/* =====================================================================
   ASHES — header, navigation and inner pages.

   Layered on top of ashes.css, which holds the tokens and the homepage.
   Split in two so this half can be re-uploaded whole while iterating,
   without touching the design system underneath it.
   ===================================================================== */

/* --- header actions ---------------------------------------------------
   The site's header carries a status pill, a server-copy chip, Discord
   and the basket. All of it has to survive down to 360px, where the row
   is the only way to reach the menu — so things drop out in a deliberate
   order rather than being clipped by body{overflow-x:hidden}. */
.a-header-actions {
  order: 3;
  display: flex;
  align-items: center;
  gap: 10px;
  flex: 0 1 auto;
  min-width: 0;
  margin: 0 !important;
  position: static !important;
}

.a-sm {
  padding: 9px 16px !important;
  font-size: 13px !important;
}

.a-status {
  flex: none;
  white-space: nowrap;
}

/* Server address, click to copy. A button because it does something —
   main.js binds [data-copy] and swaps the label to "Copied!". */
.a-chip {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  max-width: 200px;
  padding: 7px 14px;
  border-radius: 999px;
  border: 1px solid var(--line);
  background: rgba(255, 255, 255, 0.03);
  color: var(--fg-2);
  font: 600 12.5px var(--font-ui);
  cursor: pointer;
  transition: border-color 0.18s var(--ease), background 0.18s var(--ease), color 0.18s var(--ease);
}
.a-chip:hover { border-color: var(--ac); background: rgba(249, 115, 22, 0.08); color: var(--fg); }
.a-chip-label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* Hover-swap on the logged-in name: the name at rest, "Log out" on hover.
   Both live in the flow so the button never changes width. */
.user-name .text-inner { position: relative; display: inline-grid; }
.user-name .text,
.user-name .text-hover { grid-area: 1 / 1; transition: opacity 0.18s var(--ease); }
.user-name .text-hover { opacity: 0; }
.user-name:hover .text { opacity: 0; }
.user-name:hover .text-hover { opacity: 1; }

/* --- navigation -------------------------------------------------------
   Section tabs and store links read as one row; the active one is lit
   rather than merely bolded, which is the only cue that survives at this
   type size on this background. */
.navigation-list > li > a[data-a-section].is-current,
.navigation-list > li > a.link-active {
  color: var(--ac);
  background: rgba(249, 115, 22, 0.10);
}

/* Anchors land below the sticky header instead of under it. */
[id] { scroll-margin-top: 92px; }

.close-navigation { display: none; }

@media (max-width: 1240px) { .a-chip { display: none; } }
@media (max-width: 1080px) {
  .a-discord { display: none; }
  /* In the drawer the list is the whole surface, so the close button
     becomes a real control rather than a decoration. */
  .close-navigation {
    display: block;
    width: 100%;
    margin-top: 8px;
    color: var(--fg-3) !important;
  }
  .navigation-list .mobile-only { display: block; }
}
@media (min-width: 1081px) { .navigation-list .mobile-only { display: none; } }
@media (max-width: 860px) { .a-status { display: none; } }
@media (max-width: 560px) {
  .user-name { display: none; }
  .a-sm { padding: 9px 14px !important; }
}

/* --- cards ------------------------------------------------------------ */
.a-card {
  background: linear-gradient(180deg, var(--surface), var(--bg-2));
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow);
  position: relative;
  overflow: hidden;
  padding: 26px 28px;
}
.a-card::before {
  content: '';
  position: absolute;
  inset: 0 0 auto 0;
  height: 1px;
  background: linear-gradient(90deg, transparent, rgba(249, 115, 22, 0.55), transparent);
}
.a-card-narrow { max-width: 520px; }

/* --- login ------------------------------------------------------------ */
.a-login-form {
  display: flex;
  gap: 10px;
  margin-top: 22px;
  flex-wrap: wrap;
}
.a-login-form input {
  flex: 1 1 220px;
  min-width: 0;
  padding: 13px 16px;
  border-radius: 999px;
  font-size: 14.5px;
}
.a-login-form input::placeholder { color: var(--fg-3); }

/* --- basket page ------------------------------------------------------ */
.page-basket .basket { padding: 0; }

.basket-second-header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
  padding: 22px 28px;
  border-bottom: 1px solid var(--line);
}
.basket-second-header .count {
  font-size: 12px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--fg-3);
}
.basket-second-header .total {
  font-family: var(--font-display);
  font-size: 22px;
  font-weight: 700;
  color: var(--gold);
  font-variant-numeric: tabular-nums;
}

.basket-items { display: block; }

.basket-item {
  display: flex;
  align-items: center;
  gap: 18px;
  flex-wrap: wrap;
  padding: 20px 28px;
  border-bottom: 1px solid var(--line);
}
.basket-item .info { flex: 1 1 260px; min-width: 0; }
.basket-item .title { font-family: var(--font-display); font-size: 17px; margin: 0; }
.basket-item .title a:hover { color: var(--ac); }
.basket-item .trial { font-size: 12px; color: var(--good); margin-top: 4px; }
.basket-item .options {
  list-style: none;
  margin: 6px 0 0;
  padding: 0;
  font-size: 12.5px;
  color: var(--fg-3);
}
.basket-item .price {
  margin-top: 8px;
  font-family: var(--font-display);
  font-size: 17px;
  font-weight: 700;
  color: var(--gold);
  font-variant-numeric: tabular-nums;
}
.basket-item .remove { flex: none; padding: 9px 16px !important; font-size: 13px !important; }

.basket-checkout {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 18px;
  flex-wrap: wrap;
  padding: 24px 28px;
}
.basket-checkout h3 {
  display: flex;
  align-items: baseline;
  gap: 10px;
  margin: 0;
  font-size: 13px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--fg-3);
}
.basket-checkout .total {
  font-family: var(--font-display);
  font-size: 26px;
  font-weight: 700;
  color: var(--gold);
  letter-spacing: 0;
  text-transform: none;
  font-variant-numeric: tabular-nums;
}
.basket-checkout .checkout { min-width: 220px; }

@media (max-width: 600px) {
  .basket-second-header, .basket-item, .basket-checkout { padding-inline: 20px; }
  .basket-checkout .checkout { width: 100%; }
}

/* --- options / variable-data page ------------------------------------- */
.page-options .store-product-options,
.page-options .store-form {
  background: linear-gradient(180deg, var(--surface), var(--bg-2));
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow);
  padding: 26px 28px;
}
.page-options label {
  display: block;
  font-size: 11.5px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ac);
  margin-bottom: 6px;
}
.page-options .field { margin-bottom: 16px; }
.page-options input,
.page-options select,
.page-options textarea {
  width: 100%;
  padding: 12px 14px;
  font-size: 14.5px;
}

/* --- sidebar modules --------------------------------------------------
   Only the checkout flow still shows these; on the homepage the sections
   replaced them. */
.store-sidebar { display: grid; gap: 16px; align-content: start; }
.store-sidebar .title,
.store-sidebar h3 {
  font-family: var(--font-display);
  font-size: 12.5px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ac);
  margin: 0 0 14px;
}


/* --- icon buttons -----------------------------------------------------
   ashes.css sets `background` (the shorthand) on .btn-tertiary and
   .btn-secondary, which also resets background-image — and that is where
   Exo keeps the glyph for .btn-icon buttons. The menu toggle came out as
   a 50px patch of nothing on every phone-width viewport.

   Rather than depend on Exo's icon assets surviving a restyle, the two
   controls that matter are drawn here: three bars for the toggle, and a
   plain readable label for the drawer's close button, which is a
   full-width row where a word beats a glyph anyway. */
.toggle-navigation {
  position: relative;
  width: 44px;
  height: 44px;
  padding: 0 !important;
  border-radius: 999px !important;
  background-color: rgba(255, 255, 255, 0.04) !important;
  color: var(--fg) !important;
}
.toggle-navigation:hover { background-color: rgba(249, 115, 22, 0.14) !important; }
.toggle-navigation::before {
  content: '' !important;
  position: absolute;
  inset: 15px 13px;
  background:
    linear-gradient(currentColor, currentColor) top / 100% 2px no-repeat,
    linear-gradient(currentColor, currentColor) center / 100% 2px no-repeat,
    linear-gradient(currentColor, currentColor) bottom / 100% 2px no-repeat;
}

.close-navigation {
  font-size: 13px !important;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  overflow: visible !important;
  text-indent: 0 !important;
}

/* --- drawer list ------------------------------------------------------
   shared.css takes .menu out of flow (position:absolute) for its own
   horizontal dropdown behaviour. Inside the drawer that collapses the
   whole panel to 25px with the links stacked invisibly behind the
   header, so the list is put back in flow for the drawer only. */
@media (max-width: 1080px) {
  .site-navigation .navigation-list {
    position: static !important;
    height: auto !important;
    max-height: none !important;
    overflow: visible !important;
    transform: none !important;
    inset: auto !important;
  }
  .site-navigation .navigation-list > li { border-bottom: 1px solid var(--line); }
  .site-navigation .navigation-list > li:last-child { border-bottom: 0; }
  .site-navigation .navigation-list > li > a { font-size: 15px; }
  /* Sub-category lists sit inline in the drawer rather than floating. */
  .site-navigation .navigation-list li ul {
    position: static !important;
    box-shadow: none;
    background: transparent;
    border: 0;
    padding-left: 14px;
  }
}

/* shared.css floats the close button into the drawer's top-right corner,
   where it landed on top of the first menu item. It belongs at the end of
   the list, in flow, like the last row of the menu it closes. */
@media (max-width: 1080px) {
  .close-navigation {
    position: static !important;
    inset: auto !important;
    transform: none !important;
    width: 100% !important;
    height: auto !important;
    margin: 10px 0 0 !important;
    padding: 14px 16px !important;
    border-radius: var(--r-sm) !important;
    background-color: rgba(255, 255, 255, 0.04) !important;
  }
  .close-navigation::before, .close-navigation::after { display: none !important; }
  .site-navigation { padding-bottom: 16px !important; }
}

/* --- icon-only buttons ------------------------------------------------
   shared.css hides these buttons' labels and paints a mask icon in the
   space instead. The base .btn-* rule in ashes.css re-showed the label
   and gave it 13px type and 24px of padding, so the basket's Remove came
   out as the word "Remove" spilling out of a 34px circle.

   Anything Exo marks as glyph-only goes back to being a square icon;
   .btn-glyph-text is excluded because that variant is meant to show its
   label, and the two controls with sizes of their own keep them. */
.btn-glyph:not(.btn-glyph-text):not(.close-navigation),
.btn-icon:not(.toggle-navigation) {
  padding: 0 !important;
  font-size: 0 !important;
  line-height: 0 !important;
  width: 36px;
  height: 36px;
  flex: none;
  display: inline-grid !important;
  place-items: center;
  border-radius: 999px !important;
}
.quantity-field .adjust { width: 30px !important; height: 30px !important; }


/* =====================================================================
   COIN BUNDLES
   The amount is the headline, not the product name — so the name is
   dropped, the number takes the gold, and the rate line underneath is
   what lets you compare five bundles without doing the arithmetic.
   ===================================================================== */
.store-products-grid .store-product.a-coin,
.store-products-list .store-product.a-coin {
  text-align: center !important;
  padding: 24px 20px 20px;
}

.a-coin .image-link { margin: 0 auto 4px !important; width: 76px !important; }
.a-coin .image,
.a-coin .image-default {
  width: 76px !important;
  height: 76px !important;
  aspect-ratio: 1 !important;
  border: 0 !important;
  border-radius: 50% !important;
  background: none !important;
  padding: 0 !important;
}

/* The card already says "1,000" in 34px gold; repeating "1000 Ash Coins"
   underneath it is the same fact twice. */
.a-coin .product-title { display: none !important; }

.a-coin-head { display: block; }
.a-coin-head b {
  display: block;
  font-family: var(--font-display);
  font-size: 34px;
  font-weight: 700;
  line-height: 1;
  color: var(--gold);
  font-variant-numeric: tabular-nums;
}
.a-coin-head span {
  display: block;
  margin-top: 4px;
  font-size: 10.5px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--fg-3);
}
.a-coin-bonus {
  display: inline-block;
  margin-top: 12px;
  padding: 4px 11px;
  border-radius: 999px;
  font-size: 11px;
  font-style: normal;
  font-weight: 700;
  letter-spacing: 0.04em;
  color: var(--good);
  background: rgba(52, 211, 153, 0.12);
  border: 1px solid rgba(52, 211, 153, 0.3);
}
/* The starter rung has no bonus to claim, and a green pill saying
   "Starter bundle" would read as one. */
.a-coin-bonus.is-base {
  color: var(--fg-3);
  background: rgba(255, 255, 255, 0.04);
  border-color: var(--line);
}

.a-coin-rate {
  font-size: 11.5px;
  color: var(--fg-3);
  margin-top: 4px;
  font-variant-numeric: tabular-nums;
}

.a-coin .product-actions { justify-content: center !important; padding-top: 12px; }
.a-coin .product-actions .price {
  margin: 0 0 12px !important;
  font-size: 23px;
  color: var(--fg) !important;
}

/* Five identical orange buttons make none of them a recommendation, so
   only the best rate gets the primary treatment. */
.a-coin .add,
.a-coin .subscribe {
  /* These were ghost buttons, following the site's btn-ghost on coin
     cards. Ghost plus the burnt ink the template now uses everywhere is
     dark text on a near-transparent dark card, which is how four of the
     five bundles ended up invisible. Filled instead — the same object as
     the best-value card, in the house orange rather than gold. */
  background: linear-gradient(180deg, var(--ac), var(--ac2)) !important;
  border-color: transparent !important;
  color: rgb(24, 13, 6) !important;
  box-shadow: 0 10px 30px -10px rgba(249, 115, 22, .7) !important;
}
.a-coin .add:hover { border-color: var(--gold) !important; background: rgba(251, 191, 36, 0.10) !important; }

.a-coin.is-best {
  border-color: rgba(251, 191, 36, 0.5);
  box-shadow: var(--shadow), 0 0 46px -18px var(--gold);
}
.a-coin.is-best::before { background: linear-gradient(90deg, transparent, var(--gold), transparent); }
.a-coin.is-best .add {
  background: linear-gradient(180deg, var(--gold), var(--gold-dim)) !important;
  border-color: transparent !important;
  color: #180d06 !important;
  /* The best-value bundle keeps gold, and now carries a gold glow to match
     so it still reads as the one being pointed at. */
  box-shadow: 0 10px 30px -10px rgba(251, 191, 36, .75) !important;
}

/* =====================================================================
   SUPPORTER TIERS
   One colour per rung, carried through the rim and the button, is what
   makes five cards read as a ladder rather than five products.
   ===================================================================== */
.store-products-grid .store-product.a-tier,
.store-products-list .store-product.a-tier {
  --tier: var(--ac);
  text-align: center !important;
  padding: 22px 18px 18px;
}

.a-tier .image-link { margin: 0 auto 10px !important; width: auto !important; }
.a-tier .image,
.a-tier .image-default {
  width: auto !important;
  height: 132px !important;
  max-width: 100%;
  aspect-ratio: auto !important;
  object-fit: contain !important;
  border: 0 !important;
  background: none !important;
  padding: 0 !important;
  filter: drop-shadow(0 10px 26px rgba(0, 0, 0, 0.7));
  transition: transform 0.4s var(--ease), filter 0.4s var(--ease);
}
.a-tier:hover .image {
  transform: translateY(-3px) scale(1.045);
  filter: drop-shadow(0 14px 30px rgba(0, 0, 0, 0.75))
          drop-shadow(0 0 22px color-mix(in srgb, var(--tier) 55%, transparent));
}

.a-tier-rank {
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--fg-3);
}
.a-tier .product-title { text-align: center !important; font-size: 18px; margin-top: 4px !important; }
.a-tier .product-actions { justify-content: center !important; padding-top: 12px; }
.a-tier .product-actions .price {
  margin: 0 0 12px !important;
  font-family: var(--font-display);
  font-size: 27px;
  color: var(--fg) !important;
}
.a-per { font-size: 12.5px; color: var(--fg-3); font-family: var(--font-ui); font-weight: 500; margin-left: 4px; }

.a-tier::before { background: linear-gradient(90deg, transparent, var(--tier), transparent); }
.a-tier:hover { border-color: color-mix(in srgb, var(--tier) 55%, transparent); }
.a-tier.is-picked {
  border-color: color-mix(in srgb, var(--tier) 45%, transparent);
  box-shadow: var(--shadow), 0 0 46px -18px var(--tier);
}
.a-tier .subscribe,
.a-tier .open-basket-cta,
.a-tier.is-picked .add {
  background: linear-gradient(180deg, var(--tier), color-mix(in srgb, var(--tier) 60%, #000)) !important;
  border-color: transparent !important;
  color: #180d06 !important;
  box-shadow: none !important;
}

/* --- corner flag ------------------------------------------------------ */
.a-flag {
  position: absolute;
  top: 0;
  right: 0;
  z-index: 3;
  padding: 5px 12px;
  border-bottom-left-radius: 12px;
  background: var(--tier, var(--ac));
  color: #180d06;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}
.a-flag.is-best { background: var(--gold); }

/* --- tiles ------------------------------------------------------------ */
.a-tile-from {
  font-size: 12.5px;
  color: var(--gold);
  font-weight: 600;
  letter-spacing: 0.04em;
  margin-top: 5px;
}
/* A tile is an invitation, not a footnote — the site gives it the same
   orange as the buy buttons it leads to. */
.a-tile-cta {
  background: linear-gradient(180deg, var(--ac), var(--ac2)) !important;
  border-color: transparent !important;
  color: #180d06 !important;
  align-self: stretch !important;
  justify-content: center;
}

/* --- card art, specificity fix ----------------------------------------
   The "card internals, forced" block above is .store-products-grid
   .store-product .image — three selectors deep with !important. The coin
   and tier rules were two deep, so they lost and both card types kept the
   generic 16:10 product plate. Same rules, matched at the same depth. */
.store-products-grid .store-product.a-coin .image-link,
.store-products-list .store-product.a-coin .image-link {
  width: 84px !important;
  margin: 0 auto 6px !important;
  flex: none !important;
}
.store-products-grid .store-product.a-coin .image,
.store-products-grid .store-product.a-coin .image-default,
.store-products-list .store-product.a-coin .image,
.store-products-list .store-product.a-coin .image-default {
  width: 84px !important;
  height: 84px !important;
  aspect-ratio: 1 !important;
  border: 0 !important;
  border-radius: 50% !important;
  background: none !important;
  padding: 0 !important;
  object-fit: contain !important;
}

/* The tier emblems are cut out with a soft alpha edge. A bordered plate
   around them crops the glow and turns five hand-painted badges into five
   UI icons, so they float on the card instead. */
.store-products-grid .store-product.a-tier .image-link,
.store-products-list .store-product.a-tier .image-link {
  width: auto !important;
  margin: 0 auto 10px !important;
  flex: none !important;
}
.store-products-grid .store-product.a-tier .image,
.store-products-list .store-product.a-tier .image {
  width: auto !important;
  height: 132px !important;
  max-width: 100% !important;
  aspect-ratio: auto !important;
  object-fit: contain !important;
  border: 0 !important;
  border-radius: 0 !important;
  background: none !important;
  padding: 0 !important;
  margin: 0 auto !important;
  filter: drop-shadow(0 10px 26px rgba(0, 0, 0, 0.7));
}

/* The badge already carries the tier name in painted lettering, so the
   product title under it is the same word twice. */
.a-tier .product-title { display: none !important; }

/* Coin bundles are narrow by nature — a number and a price — so they get
   a tighter track than the artwork cards and five fit across.
   The rate line sits inside the actions row, so it needs a full row. */
.a-coin-grid { grid-template-columns: repeat(auto-fill, minmax(198px, 1fr)) !important; }
.a-coin .a-coin-rate { width: 100%; order: 2; margin: 0 0 14px !important; }
.a-coin .product-actions .price { order: 1; margin: 0 0 2px !important; }
.a-coin .product-actions .add,
.a-coin .product-actions .subscribe,
.a-coin .product-actions .quantity-field,
.a-coin .product-actions .open-basket-cta { order: 3; }

/* --- brand mark -------------------------------------------------------
   A square mark beside the wordmark, the way the site does it. Capped
   square so a non-square upload cannot stretch the header row. */
.site-title .a-mark { height: 42px; width: 42px; object-fit: contain; }
.a-footer-brand .a-mark { height: 46px; width: 46px; object-fit: contain; }

/* A wordmark is wide, not square. Height-capped with width auto so the
   art keeps its own proportion instead of being squeezed into a box. */
.site-title .a-mark-wide { height: 38px; width: auto; max-width: 220px; }
.a-footer-brand .a-mark-wide { height: 44px; width: auto; max-width: 240px; }
@media (max-width: 700px) { .site-title .a-mark, .site-title .a-mark-wide { height: 32px; } }
@media (max-width: 420px) { .site-title .a-mark-wide { max-width: 150px; } }

/* --- trust strip ------------------------------------------------------
   Three claims in a row read as a list; a mark in front of each makes
   them read as three separate assurances. Drawn in CSS so there is no
   icon font or sprite to ship. */
.a-trust span::before {
  content: "";
  width: 16px;
  height: 16px;
  flex: none;
  border: 0;
  border-radius: 0;
  opacity: 0.78;
  background-color: var(--ac);
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  -webkit-mask-position: center; mask-position: center;
  -webkit-mask-size: contain;   mask-size: contain;
  -webkit-mask-image: var(--a-trust-icon); mask-image: var(--a-trust-icon);
  transition: opacity .25s ease, transform .25s ease;
}
.a-trust span:hover::before { opacity: 1; transform: translateY(-1px); }
.a-trust span:nth-child(1)::before { --a-trust-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.1' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3.5' y='10.5' width='17' height='11' rx='2.5'/%3E%3Cpath d='M7.5 10.5V7a4.5 4.5 0 0 1 9 0v3.5'/%3E%3C/svg%3E"); }
.a-trust span:nth-child(2)::before { --a-trust-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23000'%3E%3Cpath d='M13.6 1.8 3.9 14.2a.6.6 0 0 0 .47.98h5.2l-1.2 6.9a.6.6 0 0 0 1.07.46l9.66-12.4a.6.6 0 0 0-.47-.97h-5.2l1.2-6.9a.6.6 0 0 0-1.03-.47z'/%3E%3C/svg%3E"); }
.a-trust span:nth-child(3)::before { --a-trust-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.1' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 2.6 4.6 5.7v5.7c0 4.4 3 8.1 7.4 9.8 4.4-1.7 7.4-5.4 7.4-9.8V5.7z'/%3E%3Cpath d='m8.9 11.9 2.3 2.3 4-4.3'/%3E%3C/svg%3E"); }

/* The payment marks are a single row of small logos. shared.css lays the
   list out for its own footer and it came out stacked three deep. */
.site-footer .we-accept {
  /* shared.css pins this to the top of its own footer, where it landed on
     top of the brand blurb. Back into the flow, under everything else. */
  position: static !important;
  inset: auto !important;
  height: auto !important;
  display: flex !important;
  flex-direction: row !important;
  flex-wrap: wrap !important;
  width: 100%;
  align-items: center;
  gap: 14px;
  padding: 0;
  margin: 34px 0 0;
  list-style: none;
}
.site-footer .we-accept li { flex: none; margin: 0; }
.site-footer .we-accept img { height: 20px !important; width: auto !important; }

/* =====================================================================
   TIER PERKS
   What the ladder is actually decided on. The tick takes the tier colour,
   so the list belongs to its card rather than floating in the palette.
   ===================================================================== */
.a-perks {
  list-style: none;
  margin: 16px 0 0;
  padding: 16px 0 0;
  border-top: 1px solid var(--line);
  display: grid;
  gap: 9px;
  align-content: start;
  text-align: left;
  flex: 1;
}
.a-perks li {
  display: flex;
  gap: 10px;
  align-items: flex-start;
  font-size: 13.5px;
  color: var(--fg-2);
  line-height: 1.45;
}
/* A tick drawn from two borders — no icon font, no sprite, and it takes
   currentColor so it inherits the tier without a second variable. */
.a-perks li::before {
  content: "";
  width: 13px;
  height: 7px;
  margin-top: 5px;
  flex: none;
  border-left: 2px solid var(--tier, var(--ac));
  border-bottom: 2px solid var(--tier, var(--ac));
  transform: rotate(-45deg);
}

/* --- the free rung ---------------------------------------------------- */
.a-tier-free {
  --tier: var(--fg-3);
  opacity: 0.72;
  transition: opacity 0.28s var(--ease);
}
.a-tier-free:hover { opacity: 1; }
.a-tier-name {
  font-family: var(--font-display);
  font-size: 18px;
  margin: 4px 0 0;
  text-align: center;
}
.a-tier-free .price {
  margin: 12px 0 0 !important;
  font-family: var(--font-display);
  font-size: 27px;
  font-weight: 700;
  color: var(--fg) !important;
  text-align: center;
}
.a-tier-foot {
  margin-top: 18px;
  padding-top: 14px;
  border-top: 1px solid var(--line);
  font-size: 12px;
  color: var(--fg-3);
  text-align: center;
}

/* =====================================================================
   TRAILER
   A 16:9 frame that keeps its ratio at every width, in the same panel
   treatment as the cards so it belongs to the page.
   ===================================================================== */
.a-video {
  position: relative;
  aspect-ratio: 16 / 9;
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  overflow: hidden;
  box-shadow: var(--shadow);
  background: linear-gradient(150deg, var(--surface-2), #0d0908);
}
.a-video iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }

/* The ladder is five rungs wide, and the free one is deliberately quiet:
   grey ticks, not the accent, so it reads as the baseline rather than as
   another thing being sold. Matched at the same depth as the .a-tier rule
   above, which sets --tier on every card. */
.a-tier-grid { grid-template-columns: repeat(auto-fill, minmax(205px, 1fr)) !important; }
.store-products-grid .store-product.a-tier-free,
.store-products-list .store-product.a-tier-free { --tier: var(--fg-3); }
.a-tier-free .a-perks li { color: var(--fg-3); }
.a-tier-free .a-perks { flex: 1; }
.a-tier-free .a-tier-foot { margin-top: auto; }

@media (max-width: 1180px) { .a-tier-grid { grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)) !important; } }
@media (max-width: 560px) { .a-tier-grid, .a-coin-grid { grid-template-columns: 1fr !important; } }

/* =====================================================================
   PACKAGE MEDIA
   Tebex sizes the slider off the image, so a square badge became 1130px
   tall — half the page before you reach the price. Capped and contained,
   on the same dark plate the cards use, so the art is presented rather
   than blown up.
   ===================================================================== */
.store-product-full .media-slider {
  border-radius: var(--r);
  border: 1px solid var(--line);
  overflow: hidden;
  background: radial-gradient(closest-side, rgba(249, 115, 22, 0.10), transparent),
              linear-gradient(150deg, var(--surface-2), #0d0908);
}
.store-product-full .media-slider swiper-slide.slide,
.store-product-full .media-slider .slide {
  height: 440px !important;
  max-height: 56vh;
  display: grid;
  place-items: center;
}
.store-product-full .media-slider img.slide-image,
.store-product-full .media-slider .slide-frame {
  height: 100% !important;
  width: 100% !important;
  max-height: 440px;
  object-fit: contain !important;
  padding: 14px;
}
/* The thumbnail strip is navigation, not gallery — small and out of the
   way under the frame. */
.store-product-full .thumbs { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 14px; }
.store-product-full .thumbs .thumb {
  width: 68px;
  height: 68px;
  border-radius: var(--r-sm);
  overflow: hidden;
  border: 1px solid var(--line);
  opacity: 0.7;
  transition: opacity 0.18s var(--ease), border-color 0.18s var(--ease);
}
.store-product-full .thumbs .thumb:hover,
.store-product-full .thumbs .thumb.active { opacity: 1; border-color: var(--ac); }
.store-product-full .thumbs .thumb img { width: 100%; height: 100%; object-fit: cover; }

@media (max-width: 700px) {
  .store-product-full .media-slider swiper-slide.slide,
  .store-product-full .media-slider .slide { height: 260px !important; }
  .store-product-full .media-slider img.slide-image { max-height: 260px; }
}

/* --- header band ------------------------------------------------------
   shared.css caps .site-header at 86rem, so the sticky band stopped short of
   the viewport and floated as a short bar on wide screens. It is a band, not
   a column: the column is .site-header-inner. */
.site-header {
  width: 100% !important;
  max-width: none !important;
  margin-inline: 0 !important;
  left: 0 !important;
  right: 0 !important;
}

/* At desktop the drawer toggle is hidden, but Exo's .actions wrapper stayed
   in the flex row as a zero-width item and still ate the row's 28px gap,
   pushing the basket 28px in from the right while the brand sat flush left. */
@media (min-width: 1081px) {
  .site-header .actions { display: none !important; }
}

/* 38px left the wordmark lost in a 1240px bar. */
.site-title .a-mark-wide,
.site-header .site-title img { height: 46px !important; max-height: 46px !important; width: auto !important; max-width: 260px; }
@media (max-width: 1080px) {
  .site-title .a-mark-wide,
  .site-header .site-title img { height: 38px !important; max-height: 38px !important; max-width: 190px; }
}

/* --- header layout ----------------------------------------------------
   Measured against the site: the bar is a full-width band with a 1240
   column inside, brand left, nav centred, actions right. Exo pushed the
   nav hard right, which left a dead void beside the crest and read as an
   off-balance header. Equal flex columns either side centre it honestly. */
@media (min-width: 1081px) {
  .site-header .site-title { flex: 1 1 0; min-width: 0; }
  .site-header .site-navigation { flex: 0 0 auto; margin-left: 0 !important; margin-right: 0 !important; }
  .site-header .a-header-actions { flex: 1 1 0; justify-content: flex-end; }

  /* Exo paints a dark rounded plate behind the menu. The site's nav is
     bare type on the band, and the plate stopping mid-bar was half of why
     the header looked bolted together. Mobile keeps it: there it is the
     drawer, and the drawer needs its own surface. */
  .site-navigation .menu {
    background: none !important;
    background-color: transparent !important;
    border: 0 !important;
    box-shadow: none !important;
    padding: 0 !important;
    border-radius: 0 !important;
  }
}

/* The crest already carries the words ASHES ROLEPLAY, so the text lockup
   beside it would say the name twice. Size the crest instead. */
.site-header .a-brand-text { display: none !important; }
.site-header .site-title > a { display: inline-flex; align-items: center; gap: 12px; }
.site-header .site-title img,
.site-header .site-title .a-mark-wide {
  height: 50px !important;
  max-height: 50px !important;
  width: auto !important;
  max-width: 260px;
}
@media (max-width: 1080px) {
  .site-header .site-title img,
  .site-header .site-title .a-mark-wide { height: 38px !important; max-height: 38px !important; max-width: 190px; }
}


/* shared.css centres .site-title's text; with the title now a full flex
   column the crest floated in the middle of its own box. */
.site-header .site-title { text-align: left !important; }
.site-header .site-title > a { justify-content: flex-start; }

/* --- sticky header, for real ------------------------------------------
   shared.css puts overflow-y:auto on <body>, which makes the body its own
   scroll container. A position:sticky header inside it then sticks to a
   scrollport that never moves, so the bar scrolled away with the page.
   The page scrolls on <html>, so body only needs to clip sideways — and
   overflow-x:clip does that without creating a scroll container. */
html { overflow-x: clip !important; }
body { overflow-x: clip !important; overflow-y: visible !important; }

/* --- nav item metrics -------------------------------------------------
   The site's nav items are 9px/15px in a 40px row; Exo's were 14px/12px
   in a 56px row, which made the bar feel taller than the site's. */
@media (min-width: 1081px) {
  .site-navigation .menu > li > a,
  .site-navigation .menu a { padding: 9px 15px !important; }
}

/* --- category tiles ---------------------------------------------------
   The site deals these with auto-fit/minmax so two categories split the
   row. A fixed four-column track left a single category stranded as a
   285px stub in a 1240px row. */
.a-tiles { grid-template-columns: repeat(auto-fit, minmax(258px, 1fr)) !important; }
/* A lone category tile capped at 620 but centred floated away from the
   section heading above it, which is hard left — so nothing lined up and
   the card read as crooked. Cap it, but keep it on the left edge with the
   heading. Two or more tiles fill the row and the cap never applies. */
.a-tiles:has(> :only-child) { max-width: 620px; margin-inline: 0; }

/* The site's tile CTA is a full-width primary button, not a pill. */
.a-tile { display: flex; flex-direction: column; }
.a-tile .a-tile-cta {
  display: block;
  width: 100%;
  margin-top: auto;
  text-align: center;
  background: linear-gradient(180deg, var(--ac), var(--ac2)) !important;
  border-color: transparent !important;
  /* Burnt ink, same as the header basket — white on this orange is
     about 2.9:1 and fails contrast. */
  color: rgb(24, 13, 6) !important;
}
.a-tile-desc {
  margin: 10px 0 0;
  font-size: 13px;
  line-height: 1.6;
  color: var(--muted, #c8b9b1);
}
.a-tile-desc + .a-tile-cta { margin-top: 18px; }

/* --- section kicker icon ---------------------------------------------- */
.a-kicker svg { width: 15px; height: 15px; flex: 0 0 auto; }

/* --- live panel -------------------------------------------------------
   The site frames the featured stream in a panel with a title bar above
   the player: who you are watching, and a FEATURED flag. The frame keeps
   16:9 so the embed never letterboxes itself. */
.a-live-panel {
  border: 1px solid var(--line);
  border-radius: 18px;
  background: linear-gradient(180deg, rgba(23,17,16,.9), rgba(12,9,8,.9));
  overflow: hidden;
}
.a-live-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 14px 18px;
  border-bottom: 1px solid var(--line);
}
.a-live-who { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.a-live-who b { font-size: 14px; letter-spacing: .02em; }
.a-live-who > span {
  font-size: 12px;
  color: var(--muted, #c8b9b1);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.a-live-flag { flex: 0 0 auto; }
.a-live-frame {
  position: relative;
  aspect-ratio: 16 / 9;
  background: #000;
}
.a-live-frame iframe {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
  display: block;
}
@media (max-width: 700px) {
  .a-live-bar { flex-wrap: wrap; }
}

/* --- hero emblem ------------------------------------------------------
   The site's hero artwork is a square emblem at 400px. A store logo is
   usually a wide wordmark, so the two need different ceilings: the
   wordmark is capped by width, the emblem by both. */
.a-hero-logo-full {
  width: min(400px, 62vw);
  height: auto;
  max-height: none;
  max-width: none;
  object-fit: contain;
}
@media (max-width: 700px) {
  .a-hero-logo-full { width: min(280px, 72vw); }
}

/* --- header at tablet -------------------------------------------------
   Between the drawer breakpoint and the desktop rules the title was left
   as a block-level h1 in a flex row, so it claimed the whole 1240 and
   pushed the basket and the menu button off the right edge while the bar
   grew to 141px. The title is a lockup, not a column: it sizes to its
   contents everywhere, and only takes an equal share at desktop, where
   that is what centres the nav. */
.site-header .site-title {
  display: flex !important;
  align-items: center;
  width: auto !important;
  max-width: none !important;
  height: auto !important;
  flex: 0 0 auto;
  padding: 0 !important;
  margin: 0 !important;
}
@media (min-width: 1081px) {
  /* Equal side columns are what put the nav dead centre: both bases 0, both
     growing by the same share of what is left. */
  .site-header .site-title { flex: 1 1 0 !important; min-width: 0; }
  .site-header .a-header-actions { flex: 1 1 0 !important; }
}
.site-header .a-header-actions { flex: 1 1 auto; justify-content: flex-end; }
.site-header .actions { flex: 0 0 auto; }
.site-header-inner {
  height: 74px !important;
  min-height: 0 !important;
  max-height: 74px !important;
  flex-wrap: nowrap !important;
  /* Below the desktop breakpoint shared.css puts 110px of top padding on
     this row, leaving room for a stacked mobile header Exo builds and we
     do not. With it the bar measured 141px and the brand sat under the
     fold of its own header. */
  padding-block: 0 !important;
  padding-inline: 24px !important;
}

/* The crest is a wide wordmark, so in a 62px square tile plate it has to
   be contained rather than covered, and sat back a little so it reads as
   a mark and not as a picture. */
.a-tile-art .a-tile-art-mark {
  width: 100%;
  height: 100%;
  object-fit: contain;
  padding: 8px;
  opacity: .92;
}

/* disabled is not a real attribute on an anchor, so a dimmed buy button
   still followed its href — straight to an add-to-basket route that can
   only fail. Make the dimming mean what it looks like it means. */
a[disabled], .btn-primary[disabled], .btn-secondary[disabled], .subscribe[disabled], .add[disabled] {
  pointer-events: none !important;
  cursor: not-allowed;
}

/* shared.css absolutely positions the login link — the same trick it used
   on .site-title and .user-actions. Logged in you never see it, so it hid
   until the session dropped: Login then sat on top of Basket and hung off
   the right edge of the bar. It is a button in a row like the others. */
.site-header .log-in,
.site-header .user-name {
  position: static !important;
  inset: auto !important;
  top: auto !important;
  right: auto !important;
  bottom: auto !important;
  left: auto !important;
  margin: 0 !important;
  transform: none !important;
  float: none !important;
  /* Exo also gives .log-in order:3, which threw it past the basket, so
     logged out the primary button was not the rightmost one and the two
     states disagreed. Let the markup decide the order in both. */
  order: 0 !important;
}

/* =====================================================================
   BUTTONS
   A buy button is the one thing on the page someone is meant to press,
   and Exo drew it as a flat fill. These are lit objects instead: a bright
   top edge and dark bottom edge so the surface has a direction, an ember
   glow bedded under it, a sheen that crosses on hover, and a press that
   actually travels. Scoped to the sections built here, so Tebex's own
   basket popup and checkout keep their stock chrome.
   ===================================================================== */
.a-hero-cta .btn-primary,
.a-tile-cta,
.a-section .store-product .add,
.a-section .store-product .subscribe,
.a-section .store-product .open-basket-cta {
  position: relative;
  overflow: hidden;
  isolation: isolate;
  border: 1px solid rgba(255, 255, 255, .12);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, .30),
    inset 0 -1px 0 rgba(0, 0, 0, .32),
    0 8px 22px -10px var(--glow, rgba(249, 115, 22, .85));
  transition:
    transform .18s var(--ease),
    box-shadow .28s var(--ease),
    filter .28s var(--ease);
}

/* The tier buttons already carry their rung colour, so the glow under
   each one is that colour rather than a single house orange. */
.a-tier .subscribe,
.a-tier .open-basket-cta { --glow: var(--tier, rgba(249, 115, 22, .85)); }

/* The sheen. One pass, left to right, only while the pointer is on it. */
.a-hero-cta .btn-primary::after,
.a-tile-cta::after,
.a-section .store-product .add::after,
.a-section .store-product .subscribe::after,
.a-section .store-product .open-basket-cta::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(105deg,
    transparent 38%,
    rgba(255, 255, 255, .38) 50%,
    transparent 62%);
  transform: translateX(-130%);
  transition: transform .75s var(--ease);
  pointer-events: none;
  z-index: 1;
}

.a-hero-cta .btn-primary:hover::after,
.a-tile-cta:hover::after,
.a-section .store-product .add:hover::after,
.a-section .store-product .subscribe:hover::after,
.a-section .store-product .open-basket-cta:hover::after { transform: translateX(130%); }

.a-hero-cta .btn-primary:hover,
.a-tile-cta:hover,
.a-section .store-product .add:hover,
.a-section .store-product .subscribe:hover,
.a-section .store-product .open-basket-cta:hover {
  transform: translateY(-2px);
  filter: brightness(1.06);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, .38),
    inset 0 -1px 0 rgba(0, 0, 0, .32),
    0 14px 30px -10px var(--glow, rgba(249, 115, 22, .95));
}

.a-hero-cta .btn-primary:active,
.a-tile-cta:active,
.a-section .store-product .add:active,
.a-section .store-product .subscribe:active,
.a-section .store-product .open-basket-cta:active {
  transform: translateY(0);
  filter: brightness(.97);
  box-shadow:
    inset 0 2px 5px rgba(0, 0, 0, .45),
    0 4px 12px -8px var(--glow, rgba(249, 115, 22, .7));
}

/* Keyboard users get the same object, ringed rather than glowed. */
.a-hero-cta .btn-primary:focus-visible,
.a-tile-cta:focus-visible,
.a-section .store-product .add:focus-visible,
.a-section .store-product .subscribe:focus-visible,
.a-section .store-product .open-basket-cta:focus-visible {
  outline: 2px solid var(--glow, var(--ac));
  outline-offset: 3px;
}

@media (prefers-reduced-motion: reduce) {
  .a-hero-cta .btn-primary::after,
  .a-tile-cta::after,
  .a-section .store-product .add::after,
  .a-section .store-product .subscribe::after,
  .a-section .store-product .open-basket-cta::after { display: none; }
  .a-hero-cta .btn-primary:hover,
  .a-tile-cta:hover,
  .a-section .store-product .add:hover,
  .a-section .store-product .subscribe:hover,
  .a-section .store-product .open-basket-cta:hover { transform: none; }
}

/* Nothing is purchasable until Tebex passes the store for review, so every
   buy button carries [disabled]. Exo just dropped them to 45% opacity,
   which on this dark surface left a ghost that read as a broken button
   rather than a closed shop. Give it a real state instead: flat, outlined
   in the rung's own colour, legible, obviously not pressable. The title
   attribute says why on hover. */
.a-section .store-product .add[disabled],
.a-section .store-product .subscribe[disabled],
.a-hero-cta .btn-primary[disabled] {
  /* Filled, in the rung's own colour — the same object as the in-basket
     button, because a buy button should look like a buy button whether or
     not the shop has opened yet. Held a touch back from full strength so
     it is not claiming to be pressable; the cursor and the title say the
     rest. */
  opacity: .88 !important;
  transform: none !important;
}

/* No sheen, no lift, no glow on something you cannot press. */
.a-section .store-product .add[disabled]::after,
.a-section .store-product .subscribe[disabled]::after,
.a-hero-cta .btn-primary[disabled]::after { display: none !important; }

/* =====================================================================
   BUTTON TEXT — centring and ink

   Exo centres button labels with line-height: 46px against a fixed 46px
   height. Any padding added on top of that overflows the content box and
   drops the label — the tile CTA was sitting 14px below its own centre.
   Centre with flex instead, which does not care what the line-height is.

   The ink matches the header basket, which is the button on this site
   that already looked right: burnt near-black, not white. It is also the
   only legible choice — white on #f97316 is about 2.9:1 and fails, the
   dark ink is around 8:1.
   ===================================================================== */
.a-hero-cta .btn-primary,
.a-tile-cta,
.a-section .store-product .add,
.a-section .store-product .subscribe,
.a-section .store-product .open-basket-cta {
  display: flex !important;
  align-items: center;
  justify-content: center;
  line-height: 1.2 !important;
  text-align: center;
  color: rgb(24, 13, 6) !important;
  font-weight: 600;
}

/* At rest these are the header basket: gradient, pill, one ember glow
   bedded under it. The bevel and the sheen belong to the hover, so a
   still page reads calm and the button only performs when reached for. */
.a-hero-cta .btn-primary,
.a-tile-cta,
.a-section .store-product .add,
.a-section .store-product .subscribe,
.a-section .store-product .open-basket-cta {
  border-color: transparent;
  box-shadow: 0 10px 30px -10px var(--glow, rgba(249, 115, 22, .7));
}

/* Tebex marks the unused half of a buy control with the hidden attribute
   — subscribe when the item is already in the basket, the in-basket button
   when it is not. The display:flex above outranked [hidden]'s display:none,
   so both were rendering at once and every rung showed two buttons. */
.a-section .store-product [hidden],
.a-hero-cta [hidden],
[hidden] { display: none !important; }

/* =====================================================================
   BASKET DRAWER

   Exo paints the whole overlay solid #171110, so opening the basket
   blacked the page out and the drawer had no edge to speak of. It should
   read as a panel sliding in over the city, not a light switch: a dark
   translucent scrim with the page still faintly behind it, and the drawer
   itself lit along its left edge.

   The contents are server-rendered by Tebex — .basket-item and
   button.checkout are its class contract, and main.js binds them — so
   everything below dresses that markup without touching its structure.
   ===================================================================== */
.popup.basket-popup {
  background: rgba(6, 4, 4, .74) !important;
  backdrop-filter: blur(10px) saturate(.9);
  -webkit-backdrop-filter: blur(10px) saturate(.9);
  border: 0 !important;
  border-radius: 0 !important;
}

.basket-popup-content {
  display: flex;
  flex-direction: column;
  background: linear-gradient(180deg, #1b1413, #0d0a09) !important;
  border: 0 !important;
  border-left: 1px solid rgba(249, 115, 22, .30) !important;
  border-radius: 20px 0 0 20px !important;
  box-shadow: -30px 0 70px -20px rgba(0, 0, 0, .75), -1px 0 0 0 rgba(249, 115, 22, .12);
  padding: 0 !important;
  overflow: hidden;
}

/* A title bar the markup does not carry. The ember rule under it is the
   same one the section kickers use, so the drawer belongs to the site. */
.basket-popup-content::before {
  content: "Your basket";
  display: block;
  flex: 0 0 auto;
  padding: 22px 24px 16px;
  font-family: var(--font-display, inherit);
  font-size: 18px;
  letter-spacing: .01em;
  color: var(--fg);
  border-bottom: 1px solid var(--line);
  background: linear-gradient(180deg, rgba(249, 115, 22, .07), transparent);
}

/* The close control sat as a 20px multiplication sign in a faint grey
   ring - small, soft-edged, and easy to miss against the artwork behind
   it. Drawn as a stroked cross instead, on a solid disc that reads at any
   backdrop, and it turns under the cursor so the target is obvious. */
/* The button also carries a "Close" text node (hidden at font-size 0),
   so centring it as a flex or grid parent put the cross in a second
   slot below centre. The cross is placed against the button box
   instead, which is the only thing that centres it reliably. */
.popup-close {
  position: absolute !important;
  top: 16px;
  right: 18px;
  width: 40px;
  height: 40px;
  display: block;
  padding: 0;
  border-radius: 50%;
  border: 1px solid rgba(255, 196, 132, .6);
  /* Orange face so it reads immediately against the artwork: a lit top,
     a shaded underside and a hard lower edge give it a raised body. */
  background:
    linear-gradient(180deg, rgba(255, 255, 255, .30), rgba(255, 255, 255, 0) 56%),
    linear-gradient(180deg, #fb923c 0%, #ea580c 58%, #c2410c 100%);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, .55),
    inset 0 -4px 8px rgba(124, 45, 18, .55),
    0 4px 0 -1px #7c2d12,
    0 14px 26px -10px rgba(0, 0, 0, .95),
    0 0 26px -6px rgba(249, 115, 22, .55);
  color: #2b1206;
  font-size: 0;
  line-height: 0;
  cursor: pointer;
  z-index: 5;
  transition: border-color .18s ease, filter .18s ease,
              transform .22s ease, box-shadow .22s ease;
}

/* Exo draws its own close icon on ::before; ours replaces it. */
.popup-close::before { display: none !important; }

.popup-close::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  width: 16px;
  height: 16px;
  margin: -8px 0 0 -8px;
  background-color: currentColor;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  -webkit-mask-position: center;  mask-position: center;
  -webkit-mask-size: contain;     mask-size: contain;
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.8' stroke-linecap='round'%3E%3Cpath d='M5.8 5.8 18.2 18.2M18.2 5.8 5.8 18.2'/%3E%3C/svg%3E");
          mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.8' stroke-linecap='round'%3E%3Cpath d='M5.8 5.8 18.2 18.2M18.2 5.8 5.8 18.2'/%3E%3C/svg%3E");
}

.popup-close:hover {
  border-color: rgba(255, 224, 186, .9);
  filter: brightness(1.1);
  transform: translateY(-2px) rotate(90deg);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, .65),
    inset 0 -4px 8px rgba(124, 45, 18, .5),
    0 5px 0 -1px #7c2d12,
    0 20px 32px -10px rgba(0, 0, 0, .95),
    0 0 34px -4px rgba(249, 115, 22, .8);
}
.popup-close:active {
  transform: translateY(2px) rotate(90deg);
  box-shadow:
    inset 0 3px 7px rgba(124, 45, 18, .8),
    0 2px 8px -4px rgba(0, 0, 0, .9);
}
.popup-close:focus-visible {
  outline: 2px solid rgba(255, 224, 186, .9);
  outline-offset: 3px;
}
@media (prefers-reduced-motion: reduce) {
  .popup-close:hover { transform: none; }
}

/* --- empty state -------------------------------------------------------
   It was one grey line floating in a 520px void. Give it a mark, a voice
   and somewhere to go. */
.basket-empty {
  flex: 1 1 auto;
  display: flex !important;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 6px;
  width: auto !important;
  padding: 40px 28px 60px;
  text-align: center;
  font-size: 0;
}

.basket-empty::before {
  content: "";
  width: 64px;
  height: 64px;
  margin-bottom: 14px;
  border-radius: 18px;
  border: 1px solid var(--line);
  background:
    radial-gradient(circle at 50% 42%, rgba(249, 115, 22, .55) 0 3px, transparent 4px),
    linear-gradient(150deg, rgba(249, 115, 22, .16), transparent 70%);
}

.basket-empty::after {
  content: "Nothing in here yet. The store is through the front page.";
  display: block;
  max-width: 24ch;
  font-size: 13px;
  line-height: 1.6;
  color: var(--muted, #c8b9b1);
}

/* The words Tebex puts in the element itself, restored to a heading. */
.basket-empty {
  font-size: 0;
}
.basket-empty > * { font-size: 13px; }

/* --- items -------------------------------------------------------------- */
.basket-popup-content .basket,
.basket-popup-content .basket-items {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
}

.basket-popup-content .basket-items { padding: 8px 16px; }

.basket-item {
  display: flex;
  align-items: flex-start;
  gap: 14px;
  padding: 14px;
  border: 1px solid var(--line);
  border-radius: 14px;
  background: rgba(255, 255, 255, .022);
  margin-bottom: 10px;
  transition: border-color .18s var(--ease), background .18s var(--ease);
}

.basket-item:hover {
  border-color: rgba(249, 115, 22, .32);
  background: rgba(249, 115, 22, .05);
}

.basket-item .info { flex: 1 1 auto; min-width: 0; }

.basket-item .title {
  font-family: var(--font-display, inherit);
  font-size: 15px;
  line-height: 1.25;
  margin: 0 0 4px;
}
.basket-item .title a { color: var(--fg); }
.basket-item .title a:hover { color: var(--ac); }

.basket-item .trial {
  display: inline-block;
  margin-top: 4px;
  padding: 2px 8px;
  border-radius: 999px;
  font-size: 10.5px;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: #34d399;
  background: rgba(52, 211, 153, .12);
}

.basket-item .options { margin: 6px 0 0; padding: 0; list-style: none; }
.basket-item .options li {
  position: relative;
  padding-left: 14px;
  font-size: 11.5px;
  line-height: 1.7;
  color: var(--muted, #c8b9b1);
}
.basket-item .options li::before {
  content: "";
  position: absolute;
  left: 2px;
  top: 9px;
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: var(--ac);
  opacity: .7;
}

.basket-item .price {
  flex: 0 0 auto;
  text-align: right;
  font-variant-numeric: tabular-nums;
}
.basket-item .price strong {
  font-family: var(--font-display, inherit);
  font-size: 16px;
  color: var(--gold, #fbbf24);
}

/* Quantity and remove sit under the price, so a long package name never
   squeezes them into a column two characters wide. */
.basket-item .quantity-field {
  margin-top: 10px;
  display: inline-flex;
  align-items: center;
  border: 1px solid var(--line);
  border-radius: 999px;
  overflow: hidden;
  background: rgba(0, 0, 0, .25);
}
.basket-item .quantity-field input { width: 38px; text-align: center; }

.basket-item .remove {
  margin-top: 8px;
  border: 0;
  background: none;
  color: var(--muted, #c8b9b1);
  font-size: 11px;
  letter-spacing: .06em;
  text-transform: uppercase;
  cursor: pointer;
  opacity: .75;
  transition: color .18s var(--ease), opacity .18s var(--ease);
}
.basket-item .remove:hover { color: #ef4444; opacity: 1; }

/* --- checkout foot ------------------------------------------------------
   Pinned, so the total and the button are reachable without scrolling
   past a long basket. */
.basket-popup-content .basket-checkout {
  flex: 0 0 auto;
  padding: 18px 20px 22px;
  border-top: 1px solid var(--line);
  background: linear-gradient(180deg, rgba(0, 0, 0, .25), rgba(0, 0, 0, .5));
}

.basket-checkout .checkout {
  display: flex !important;
  align-items: center;
  justify-content: center;
  width: 100%;
  min-height: 52px;
  line-height: 1.2 !important;
  border: 1px solid transparent;
  border-radius: 999px;
  background: linear-gradient(180deg, var(--ac), var(--ac2));
  color: rgb(24, 13, 6) !important;
  font-weight: 600;
  font-size: 15px;
  cursor: pointer;
  box-shadow: 0 10px 30px -10px rgba(249, 115, 22, .7);
  transition: transform .18s var(--ease), box-shadow .28s var(--ease), filter .28s var(--ease);
}

.basket-checkout .checkout:hover {
  transform: translateY(-2px);
  filter: brightness(1.06);
  box-shadow: 0 16px 34px -10px rgba(249, 115, 22, .95);
}
.basket-checkout .checkout:active { transform: translateY(0); filter: brightness(.97); }

@media (max-width: 560px) {
  .basket-popup-content { border-radius: 20px 20px 0 0 !important; border-left: 0 !important; border-top: 1px solid rgba(249, 115, 22, .30) !important; }
  .basket-item { flex-direction: column; gap: 8px; }
  .basket-item .price { text-align: left; }
}

@media (prefers-reduced-motion: reduce) {
  .basket-checkout .checkout:hover { transform: none; }
}

/* Exo scopes its own basket rules as .basket .basket-item, one class more
   specific than the block above, so the trial badge stretched to a
   full-width orange bar and the remove link kept its button padding.
   Same specificity, loaded later, so these win on the tie. */
.basket .basket-item .trial {
  display: inline-block !important;
  width: auto !important;
  margin-top: 4px;
  padding: 2px 9px !important;
  border-radius: 999px !important;
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: #34d399 !important;
  background: rgba(52, 211, 153, .12) !important;
}

.basket .basket-item .options { margin: 6px 0 0; padding: 0; list-style: none; }
.basket .basket-item .options li {
  position: relative;
  padding: 0 0 0 14px !important;
  font-size: 11.5px;
  line-height: 1.7;
  color: var(--muted, #c8b9b1);
}
.basket .basket-item .options li::before {
  content: "";
  position: absolute;
  left: 2px;
  top: 9px;
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: var(--ac);
  opacity: .75;
}

.basket .basket-item .price strong { color: var(--gold, #fbbf24) !important; }

.basket .basket-item .remove {
  padding: 0 !important;
  margin-top: 8px;
  border: 0 !important;
  background: none !important;
  color: var(--muted, #c8b9b1) !important;
  font-size: 11px !important;
  letter-spacing: .06em;
  text-transform: uppercase;
  cursor: pointer;
  opacity: .75;
}
.basket .basket-item .remove:hover { color: #ef4444 !important; opacity: 1; }

.basket .basket-item .quantity-field { margin-top: 10px; }

/* =====================================================================
   CHECKOUT PAGE
   The full-page basket at /checkout. Same item rows as the drawer — they
   share Tebex's .basket-item contract — but the page needs the header,
   the running total and the empty state dressed, which shared.css was
   still supplying in Exo's grey.
   ===================================================================== */
.a-page .basket.a-card {
  border: 1px solid var(--line);
  border-radius: 20px;
  background: linear-gradient(180deg, rgba(23, 17, 16, .92), rgba(12, 9, 8, .92));
  overflow: hidden;
}

.a-page .basket-header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
  padding: 20px 22px;
  border-bottom: 1px solid var(--line);
  background: linear-gradient(180deg, rgba(249, 115, 22, .07), transparent);
}

.a-page .basket-title {
  font-family: var(--font-display, inherit);
  font-size: 20px;
  margin: 0;
}

.a-page .basket-second-header {
  display: flex;
  align-items: baseline;
  gap: 18px;
  font-size: 12.5px;
  color: var(--muted, #c8b9b1);
}

.a-page .basket-second-header .count { letter-spacing: .06em; text-transform: uppercase; }

.a-page .basket-second-header .total {
  font-family: var(--font-display, inherit);
  font-size: 20px;
  color: var(--gold, #fbbf24);
  font-variant-numeric: tabular-nums;
}

.a-page .basket-content { padding: 14px 16px; }
.a-page .basket-items { display: flex; flex-direction: column; }

/* The page's empty state, matched to the drawer's. */
.a-page .no-products {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 14px;
  padding: 60px 24px 66px;
  text-align: center;
  font-size: 13.5px;
  color: var(--muted, #c8b9b1);
}

.a-page .no-products::before {
  content: "";
  width: 64px;
  height: 64px;
  border-radius: 18px;
  border: 1px solid var(--line);
  background:
    radial-gradient(circle at 50% 42%, rgba(249, 115, 22, .55) 0 3px, transparent 4px),
    linear-gradient(150deg, rgba(249, 115, 22, .16), transparent 70%);
}

.a-page .basket-checkout {
  display: flex;
  justify-content: flex-end;
  padding: 18px 22px 22px;
  border-top: 1px solid var(--line);
  background: linear-gradient(180deg, rgba(0, 0, 0, .2), rgba(0, 0, 0, .4));
}

.a-page .basket-checkout .checkout { width: auto; min-width: 260px; padding-inline: 32px; }

@media (max-width: 560px) {
  .a-page .basket-header { flex-direction: column; gap: 6px; }
  .a-page .basket-checkout { justify-content: stretch; }
  .a-page .basket-checkout .checkout { width: 100%; }
}

/* =====================================================================
   LIVE — stage and roster
   Matches the site: a 22px-radius stage with a title bar and a 16:9
   frame, and a row of pill-shaped roster entries under it. The active
   entry is ringed in ember; the rest sit quiet until hovered.
   ===================================================================== */
.a-stream-stage {
  border: 1px solid var(--line);
  border-radius: 22px;
  background: linear-gradient(180deg, rgba(23, 17, 16, .92), rgba(12, 9, 8, .92));
  overflow: hidden;
}

.a-stream-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 14px 18px;
  border-bottom: 1px solid var(--line);
}

.a-stream-who { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.a-stream-who b { font-size: 14px; letter-spacing: .02em; }
.a-stream-who > span {
  font-size: 12px;
  color: var(--muted, #c8b9b1);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.a-badge-live {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 5px 11px;
  border-radius: 999px;
  border: 1px solid var(--line);
  background: rgba(255, 255, 255, .03);
  color: #fca5a5;
  font-size: 11.5px;
  letter-spacing: .08em;
  text-transform: uppercase;
}

.a-stream-frame {
  position: relative;
  aspect-ratio: 16 / 9;
  background: #000;
}
.a-stream-frame iframe {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
  display: block;
}

/* --- roster ------------------------------------------------------------- */
.a-roster {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-top: 18px;
}

.a-roster-item {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 10px 16px 10px 10px;
  border-radius: 999px;
  border: 1px solid var(--line);
  background: rgba(255, 255, 255, .025);
  color: var(--muted, #c8b9b1);
  text-align: left;
  cursor: pointer;
  transition: border-color .18s var(--ease), background .18s var(--ease), color .18s var(--ease), transform .18s var(--ease);
}

.a-roster-item:hover {
  border-color: rgba(249, 115, 22, .45);
  background: rgba(249, 115, 22, .07);
  color: var(--fg);
  transform: translateY(-1px);
}

.a-roster-item.is-active {
  border-color: var(--ac);
  background: rgba(249, 115, 22, .12);
  color: var(--fg);
}

.a-roster-av {
  flex: 0 0 auto;
  width: 32px;
  height: 32px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: linear-gradient(140deg, rgba(249, 115, 22, .85), rgba(194, 65, 12, .85));
  color: rgb(24, 13, 6);
  font-size: 13px;
  font-weight: 700;
}

.a-roster-txt { display: flex; flex-direction: column; line-height: 1.25; min-width: 0; }
.a-roster-name { font-size: 13px; color: inherit; }
.a-roster-plat {
  font-size: 10.5px;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--muted, #c8b9b1);
  opacity: .8;
}

@media (max-width: 700px) {
  .a-stream-bar { flex-wrap: wrap; }
  .a-roster { flex-wrap: nowrap; overflow-x: auto; padding-bottom: 4px; }
  .a-roster-item { flex: 0 0 auto; }
}

@media (prefers-reduced-motion: reduce) {
  .a-roster-item:hover { transform: none; }
}

/* =====================================================================
   TRAILER STAGE
   The site shows a still with a play button over it and only loads the
   video on request. Same 22px 16:9 stage as the stream, an ember ring
   around the play button, and a caption under it.
   ===================================================================== */
.a-video-screen {
  position: relative;
  aspect-ratio: 16 / 9;
  border: 1px solid var(--line);
  border-radius: 22px;
  overflow: hidden;
  background: #000;
}

.a-video-poster,
.a-video-el {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
  border: 0;
}
.a-video-poster { object-fit: cover; }
.a-video-el { object-fit: contain; background: #000; z-index: 2; }

.a-video-overlay {
  position: absolute;
  inset: 0;
  z-index: 3;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 18px;
  text-align: center;
  background: linear-gradient(180deg, rgba(10, 7, 6, .25), rgba(10, 7, 6, .72));
}

.a-video-play {
  width: 88px;
  height: 88px;
  border-radius: 50%;
  border: 1px solid rgba(249, 115, 22, .5);
  background: rgba(249, 115, 22, .14);
  color: #fed7aa;
  cursor: pointer;
  display: grid;
  place-items: center;
  font-size: 0;
  transition: transform .2s var(--ease), background .2s var(--ease), border-color .2s var(--ease), box-shadow .3s var(--ease);
}

/* A triangle, drawn rather than shipped as an icon. */
.a-video-play::before {
  content: "";
  width: 0;
  height: 0;
  margin-left: 6px;
  border-left: 22px solid currentColor;
  border-top: 14px solid transparent;
  border-bottom: 14px solid transparent;
}

.a-video-play:hover {
  transform: scale(1.06);
  background: rgba(249, 115, 22, .24);
  border-color: var(--ac);
  box-shadow: 0 0 0 10px rgba(249, 115, 22, .10), 0 18px 40px -14px rgba(249, 115, 22, .8);
}
.a-video-play:active { transform: scale(.98); }

.a-video-cap { display: flex; flex-direction: column; gap: 3px; }
.a-video-cap b {
  font-family: var(--font-display, inherit);
  font-size: 16px;
  color: var(--fg);
}
.a-video-cap span { font-size: 12.5px; color: var(--muted, #c8b9b1); }

@media (max-width: 700px) {
  .a-video-play { width: 66px; height: 66px; }
  .a-video-play::before { border-left-width: 17px; border-top-width: 11px; border-bottom-width: 11px; }
}

@media (prefers-reduced-motion: reduce) {
  .a-video-play:hover { transform: none; }
}

/* =====================================================================
   WHITELIST
   Three numbered steps and a pair of buttons. The numbers are the only
   ornament — they carry the order, so nothing else has to.
   ===================================================================== */
.a-steps {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 18px;
}

.a-step {
  position: relative;
  padding: 24px 22px 22px;
  border: 1px solid var(--line);
  border-radius: 18px;
  background: linear-gradient(180deg, rgba(23, 17, 16, .9), rgba(12, 9, 8, .9));
  transition: border-color .2s var(--ease), transform .2s var(--ease);
}

.a-step:hover { border-color: rgba(249, 115, 22, .3); transform: translateY(-2px); }

.a-step-n {
  display: grid;
  place-items: center;
  width: 34px;
  height: 34px;
  margin-bottom: 14px;
  border-radius: 50%;
  border: 1px solid rgba(249, 115, 22, .45);
  background: rgba(249, 115, 22, .12);
  color: var(--ac);
  font-family: var(--font-display, inherit);
  font-size: 14px;
}

.a-step h3 {
  font-family: var(--font-display, inherit);
  font-size: 17px;
  margin: 0 0 8px;
}

.a-step p {
  margin: 0;
  font-size: 13.5px;
  line-height: 1.7;
  color: var(--muted, #c8b9b1);
}

.a-apply-cta {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin-top: 26px;
}

@media (prefers-reduced-motion: reduce) {
  .a-step:hover { transform: none; }
}


/* ---------------------------------------------------------------
   STORE CLOSED treatment - removed.

   Tebex stamps data-not-purchasable="1" on every package until the
   visitor has signed in with FiveM, not only when the store is shut.
   The old rules here greyed the button out and replaced its label with
   "Store opening soon" via ::before, so a live store looked closed to
   everyone who had not logged in yet, which was nobody arriving cold.
   The buy links now stay enabled and the checkout route redirects to
   the FiveM login on its own.
   --------------------------------------------------------------- */

/* ---------------------------------------------------------------
   BASKET REMOVE CONTROL

   Tebex ships this as its icon-button component: a 40px box that
   paints delete.svg from --btn-icon. An earlier pass here restyled it
   as a small uppercase text button but never switched the icon off,
   so the word and the glyph rendered on top of each other inside a
   box sized for neither. It is a text button now, so the icon
   variables are cleared and the box is allowed to size to its label.
   --------------------------------------------------------------- */
.basket .basket-item .remove,
.basket-item .remove {
  --btn-icon: none;
  --btn-icon-size: 0;
  --btn-size: auto;
  display: inline-flex;
  align-items: center;
  width: auto;
  height: auto;
  min-width: 0;
  min-height: 0;
  padding: 0 !important;
  background-image: none !important;
  line-height: 1.2;
  white-space: nowrap;
  text-indent: 0;
  overflow: visible;
}

.basket .basket-item .remove::before,
.basket .basket-item .remove::after,
.basket-item .remove::before,
.basket-item .remove::after {
  content: none !important;
  background-image: none !important;
  display: none !important;
}

.basket .basket-item .remove:hover,
.basket-item .remove:hover {
  opacity: 1;
  color: #fb8a3c !important;
}

/* ---------------------------------------------------------------
   ASSETS LANDING TILES
   The category object on this page carries no reference to its
   children, so the Assets index is hand-placed in that category's
   description field. These style whatever it puts there.
   --------------------------------------------------------------- */
.a-cat-tiles {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
  gap: 14px;
  margin: 30px 0 0;
  max-width: none;
}
.a-cat-tile {
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  min-height: 136px;
  padding: 20px 22px;
  border: 1px solid var(--line);
  border-radius: 16px;
  overflow: hidden;
  text-decoration: none;
  background: linear-gradient(160deg, rgba(249,115,22,.10), transparent 58%), #100c0a;
  transition: border-color .28s var(--ease), transform .28s var(--ease);
}
.a-cat-tile::after {
  content: "";
  position: absolute;
  inset: -45% -20% auto;
  height: 160px;
  background: radial-gradient(closest-side, rgba(249,115,22,.32), transparent);
  opacity: 0;
  transition: opacity .35s var(--ease);
  pointer-events: none;
}
.a-cat-tile:hover { border-color: rgba(249,115,22,.55); transform: translateY(-3px); }
.a-cat-tile:hover::after { opacity: 1; }
.a-cat-tile b { position: relative; font-size: 19px; font-weight: 600; color: var(--fg); }
.a-cat-tile span { position: relative; margin-top: 5px; font-size: 12.5px; color: var(--fg-3); }

/* ---------------------------------------------------------------
   SHOWCASE - a category holding one or two products

   The five-across product grid is built for a full shelf. With a
   single item it left the card small and marooned in a page of
   black. Below three products the card becomes a wide split panel:
   the model lit on the left, the name, price and buy on the right.
   --------------------------------------------------------------- */
.store-products-grid.a-showcase {
  display: block;
  max-width: 980px;
}
.a-showcase .store-product {
  display: grid;
  grid-template-columns: minmax(0, 1.08fr) minmax(0, 1fr);
  padding: 0;
  overflow: hidden;
  border-radius: 22px;
}
.a-showcase .image-link {
  grid-column: 1;
  grid-row: 1 / span 3;
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 430px;
  margin: 0;
  padding: 40px;
  border-right: 1px solid var(--line);
  background:
    radial-gradient(68% 58% at 50% 44%, rgba(249,115,22,.30), transparent 72%),
    radial-gradient(120% 90% at 50% 105%, rgba(251,191,36,.12), transparent 62%),
    #0b0806;
}
.a-showcase .image-link img.image {
  max-width: 100%;
  max-height: 340px;
  width: auto;
  height: auto;
  transform: rotate(-5deg) scale(1.02);
  filter: drop-shadow(0 26px 46px rgba(0,0,0,.75)) drop-shadow(0 0 34px rgba(249,115,22,.28));
  transition: transform .55s var(--ease);
}
.a-showcase .store-product:hover .image-link img.image { transform: rotate(-1deg) scale(1.08); }
.a-showcase .product-title {
  grid-column: 2;
  grid-row: 1;
  align-self: end;
  margin: 0;
  padding: 44px 40px 0;
  font-size: 34px;
  line-height: 1.1;
  letter-spacing: -.02em;
}
.a-showcase .product-title::before {
  content: "FiveM asset";
  display: block;
  margin-bottom: 12px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: #f97316;
}
.a-showcase .actions.product-actions {
  grid-column: 2;
  grid-row: 2;
  align-content: start;
  padding: 22px 40px 44px;
}
.a-showcase .price { font-size: 30px; }
.a-showcase .price:has(del.discount)::before { font-size: 12px; padding: 4px 11px; }
.a-showcase .actions .btn-primary { margin-top: 20px; font-size: 15px; padding: 15px 26px; }

@media (max-width: 860px) {
  .store-products-grid.a-showcase { max-width: none; }
  .a-showcase .store-product { grid-template-columns: 1fr; }
  .a-showcase .image-link {
    grid-column: 1;
    grid-row: 1;
    min-height: 290px;
    padding: 26px;
    border-right: 0;
    border-bottom: 1px solid var(--line);
  }
  .a-showcase .product-title { grid-column: 1; grid-row: 2; padding: 28px 24px 0; font-size: 26px; }
  .a-showcase .actions.product-actions { grid-column: 1; grid-row: 3; padding: 18px 24px 28px; }
}

/* An index category holds tiles rather than products, so the empty-shelf
   line below it is noise. */
.a-section-head:has(.a-cat-tiles) + .no-products { display: none; }

/* The base shelf rule (.store-products-grid .store-product) matches at the
   same weight as the showcase block above and lands later in the cascade,
   so the split panel needs the extra class on the grid to win. */
.store-products-grid.a-showcase .store-product {
  display: grid;
  grid-template-columns: minmax(0, 1.08fr) minmax(0, 1fr);
  align-items: stretch;
}
.store-products-grid.a-showcase .image-link {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
}
.store-products-grid.a-showcase .actions.product-actions {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  justify-content: flex-start;
}
.store-products-grid.a-showcase .price { margin: 0; }

@media (max-width: 860px) {
  .store-products-grid.a-showcase .store-product { grid-template-columns: 1fr; }
}

/* The shelf rule carries display:flex !important, so the split panel can
   only be reached the same way. Scoped to .a-showcase, which only appears
   on a category holding fewer than three products. */
.store-products-grid.a-showcase .store-product {
  display: grid !important;
  grid-template-columns: minmax(0, 1.08fr) minmax(0, 1fr) !important;
}
.store-products-grid.a-showcase .image-link {
  display: flex !important;
  grid-column: 1 !important;
  grid-row: 1 / span 3 !important;
  width: auto !important;
  height: 100% !important;
}
.store-products-grid.a-showcase .product-title {
  grid-column: 2 !important;
  grid-row: 1 !important;
  width: auto !important;
}
.store-products-grid.a-showcase .actions.product-actions {
  grid-column: 2 !important;
  grid-row: 2 !important;
  width: auto !important;
}

@media (max-width: 860px) {
  .store-products-grid.a-showcase .store-product { grid-template-columns: 1fr !important; }
  .store-products-grid.a-showcase .image-link { grid-column: 1 !important; grid-row: 1 !important; }
  .store-products-grid.a-showcase .product-title { grid-column: 1 !important; grid-row: 2 !important; }
  .store-products-grid.a-showcase .actions.product-actions { grid-column: 1 !important; grid-row: 3 !important; }
}

/* ---------------------------------------------------------------
   SHOWCASE - artwork pass

   The listing art is no longer an isolated model on empty black; it is
   a composed square scene (banners, embers, lit ground) where the
   framing is part of the sell. So the panel shows the whole frame
   rather than cropping into the middle of it, and the painted fire
   replaces the CSS ember glow that used to stand in for it.
   --------------------------------------------------------------- */
.store-products-grid.a-showcase .image-link {
  position: relative;
  overflow: hidden;
  padding: 0 !important;
  /* The shelf card bleeds its thumbnail past the card edge (negative top
     and side margins, positive bottom). In the showcase the panel is a
     full-height column, so that bleed pushed it 22px high and left a gap
     under it. Flush to the card on every side instead. */
  margin: 0 !important;
  align-self: stretch !important;
}
.store-products-grid.a-showcase .image-link img.image {
  width: 100% !important;
  height: 100% !important;
  max-width: none !important;
  max-height: none !important;
  object-fit: cover !important;
  object-position: 50% 50% !important;
  mix-blend-mode: normal;
  -webkit-mask-image: none; mask-image: none;
  transform: scale(1.02);
  filter: contrast(1.06) saturate(1.06) brightness(1.04);
  transition: transform .7s var(--ease), filter .7s var(--ease);
}
.store-products-grid.a-showcase .store-product:hover .image-link img.image {
  transform: scale(1.07);
  filter: contrast(1.1) saturate(1.12) brightness(1.1);
}

/* The art runs to its own edges; an inset vignette settles it into the
   card instead of ending on a hard rectangle against the panel border. */
.store-products-grid.a-showcase .image-link::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  background: linear-gradient(90deg, transparent 72%, rgba(11,8,6,.55) 100%);
  box-shadow: inset 0 0 70px rgba(0,0,0,.5);
}
.store-products-grid.a-showcase .store-product {
  position: relative;
  box-shadow: 0 34px 70px -28px rgba(0,0,0,.9);
}
.store-products-grid.a-showcase .store-product::before {
  content: "";
  position: absolute;
  top: 0; left: 8%; right: 8%;
  height: 1px;
  background: linear-gradient(90deg, transparent, rgba(249,115,22,.6), transparent);
  z-index: 2;
}

/* Right column: let the type carry more weight */
.store-products-grid.a-showcase .product-title { font-size: 38px !important; }
.store-products-grid.a-showcase .price { font-size: 34px !important; }
.store-products-grid.a-showcase .actions .btn-primary {
  box-shadow: 0 14px 36px -12px rgba(249,115,22,.75);
}


/* ---------------------------------------------------------------
   EMPTY CATEGORY - authored placeholder

   A subcategory with nothing in it yet carries a written block in its
   description (a heading plus a line of copy). Where that block exists
   it IS the page, so the generic "No packages to display" state below
   it is noise, and the head should run the full content width rather
   than the narrower text column.
   --------------------------------------------------------------- */
.a-section-head:has(h3) { max-width: none; }
.a-section-head:has(h3) + .no-products { display: none; }


/* ---------------------------------------------------------------
   PACKAGE PAGE / POPUP - product page layout

   It stacked a centred image over a left-aligned price and a
   half-width button, so nothing lined up and the art floated in a
   pale frame with dead space either side.

   Now it reads as a product page: a lit plate down the left holding
   a square crop of the art, the buy column down the right. The plate
   is painted by the container, not the image, so the panel stays
   continuous when the description runs longer than the art; the art
   itself is square and sticks while that text scrolls. Square in,
   square out - so a full-bleed render fills the plate edge to edge
   and a cut-out emblem is not cropped either.
   --------------------------------------------------------------- */
.store-product-full {
  position: relative;
  padding: 0 !important;
  overflow: hidden;
}
.store-product-full::before {
  content: "";
  position: absolute;
  top: 0; left: 6%; right: 6%;
  height: 1px;
  background: linear-gradient(90deg, transparent, rgba(249,115,22,.65), transparent);
  z-index: 4;
  pointer-events: none;
}

.store-product-full > img.image {
  display: block;
  width: 100% !important;
  max-width: none !important;
  margin: 0 !important;
  border: 0 !important;
  border-radius: 0 !important;
  box-sizing: border-box;
  aspect-ratio: 1 / 1;
  object-fit: cover !important;
  object-position: 50% 50% !important;
  padding: 0 !important;
}

.store-product-full > .product-title { letter-spacing: -0.01em; }
/* The theme gives the buy button flex-basis 240px, which beats width,
   so it sat two thirds across its column. Basis, not width. */
.store-product-full > .actions.product-actions .btn-primary {
  flex: 1 1 100% !important;
  width: 100% !important;
  max-width: none !important;
  box-shadow: 0 16px 38px -14px rgba(249, 115, 22, .8);
}
.store-product-full > .descr p:first-child { font-size: 16.5px; opacity: .92; }
.store-product-full > .descr p + p { opacity: .74; }

@media (min-width: 900px) {
  .store-product-full {
    display: grid !important;
    grid-template-columns: 52% 48%;
    grid-template-rows: auto auto 1fr;
    align-items: start;
    column-gap: 0;
    /* The plate, and the hairline between the columns, are painted here
       so the left side stays one continuous panel below the artwork. */
    background-image:
      linear-gradient(90deg, transparent calc(52% - 1px), var(--line) calc(52% - 1px), var(--line) 52%, transparent 52%),
      radial-gradient(40% 26% at 26% 30%, rgba(249,115,22,.20), transparent 72%),
      radial-gradient(46% 30% at 26% 74%, rgba(249,115,22,.13), transparent 74%),
      linear-gradient(90deg, #0b0806 0 52%, transparent 52%);
  }
  .store-product-full > img.image {
    grid-column: 1;
    grid-row: 1 / span 3;
    align-self: start;
    height: auto !important;
    max-height: none !important;
  }
  .store-product-full > .product-title {
    grid-column: 2; grid-row: 1;
    margin: 0 !important;
    padding: 54px 46px 0 !important;
    font-size: 34px !important;
  }
  .store-product-full > .actions.product-actions {
    grid-column: 2; grid-row: 2;
    margin: 0 !important;
    padding: 22px 46px 30px !important;
  }
  .store-product-full > .actions.product-actions .price {
    font-size: 30px !important;
    margin: 0 0 18px !important;
  }
  .store-product-full > .descr {
    grid-column: 2; grid-row: 3;
    margin: 0 !important;
    padding: 26px 46px 52px !important;
    border-top: 1px solid var(--line);
  }
}

@media (max-width: 899px) {
  .store-product-full > .product-title { padding: 40px 26px 0 !important; margin: 0 !important; }
  .store-product-full > .actions.product-actions { padding: 20px 26px 0 !important; margin: 0 !important; }
  .store-product-full > .descr { padding: 20px 26px 38px !important; margin: 0 !important; }
}

/* ---------------------------------------------------------------
   PRODUCT IMAGE LIGHTBOX

   Clicking the art on a package page or in its popup opens it full
   screen (ashes.js). Wheel or the bar zooms, dragging pans, Escape
   closes. The close control reuses .popup-close and only needs to be
   pinned to the viewport instead of the card.
   --------------------------------------------------------------- */
.store-product-full > img.image { cursor: zoom-in; }

.a-lightbox {
  position: fixed;
  inset: 0;
  z-index: 9999;
  display: grid;
  place-items: center;
  background:
    radial-gradient(70% 60% at 50% 45%, rgba(249, 115, 22, .10), transparent 72%),
    rgba(6, 4, 3, .93);
  -webkit-backdrop-filter: blur(7px);
          backdrop-filter: blur(7px);
  opacity: 0;
  transition: opacity .2s ease;
}
.a-lightbox.is-open { opacity: 1; }

.a-lb-stage {
  display: grid;
  place-items: center;
  width: 100vw;
  height: 100vh;
  overflow: hidden;
}
.a-lb-stage img {
  max-width: 92vw;
  max-height: 84vh;
  width: auto;
  height: auto;
  border-radius: 12px;
  box-shadow: 0 50px 110px -40px rgba(0, 0, 0, .95);
  transform-origin: center center;
  transition: transform .14s ease-out;
  cursor: zoom-in;
  user-select: none;
  -webkit-user-drag: none;
}
.a-lightbox.is-zoomed .a-lb-stage img { cursor: grab; transition: none; }
.a-lightbox.is-zoomed .a-lb-stage img:active { cursor: grabbing; }

.a-lb-bar {
  position: fixed;
  left: 50%;
  bottom: 26px;
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 7px;
  border-radius: 999px;
  border: 1px solid var(--line);
  background: rgba(18, 12, 9, .88);
  box-shadow: 0 18px 34px -16px rgba(0, 0, 0, .95);
  z-index: 10000;
}
.a-lb-btn {
  min-width: 38px;
  height: 38px;
  padding: 0 14px;
  border-radius: 999px;
  border: 1px solid transparent;
  background: rgba(255, 255, 255, .05);
  color: var(--fg, #f4ece7);
  font-size: 17px;
  font-weight: 700;
  line-height: 1;
  cursor: pointer;
  transition: background .16s ease, border-color .16s ease, color .16s ease;
}
.a-lb-btn.a-lb-reset { font-size: 13px; letter-spacing: .04em; }
.a-lb-btn:hover {
  background: rgba(249, 115, 22, .18);
  border-color: rgba(249, 115, 22, .5);
  color: #fff;
}

.a-lb-close {
  position: fixed !important;
  top: 22px;
  right: 26px;
  z-index: 10001;
}

@media (max-width: 620px) {
  .a-lb-bar { bottom: 18px; }
  .a-lb-stage img { max-width: 94vw; max-height: 74vh; }
}

/* ---------------------------------------------------------------
   POPUP WIDTH AND PLATE FILL

   In the popup the card was narrower than the page, so the buy
   column ran tall while the square art stayed pinned to the top of
   the plate - leaving a large empty panel under it. Two fixes: give
   the popup the same generous width the page gets, and centre the
   art in the plate so whatever headroom is left reads as matting
   rather than a gap.
   --------------------------------------------------------------- */
.store-product-popup .popup-content.store-product-full {
  width: min(96vw, 1120px) !important;
  max-width: min(96vw, 1120px) !important;
}

@media (min-width: 900px) {
  .store-product-full > img.image { align-self: center; }
}

/* ---------------------------------------------------------------
   MULTI-IMAGE PACKAGES - slider in the plate

   Add a second image and Tebex swaps the lone img for a slider with a
   thumbnail strip. That new node had no place in the product grid, so
   it auto-flowed into the first free cell and only spanned one row,
   leaving the buy column stranded beside a tall empty panel. It takes
   the same slot the single image had, and its slides are squared to
   match the plate.
   --------------------------------------------------------------- */
.store-product-full > .media-slider {
  margin: 0 !important;
  padding: 0 !important;
  width: 100%;
  min-width: 0;
}
.store-product-full .media-slider .slider,
.store-product-full .media-slider swiper-container.slider {
  display: block;
  width: 100%;
}
.store-product-full .media-slider swiper-slide.slide,
.store-product-full .media-slider .slide {
  display: block !important;
  height: auto !important;
  /* An earlier pass capped the slide at 56vh for the old stacked layout;
     in the plate that cap is what stopped the square from squaring. */
  max-height: none !important;
  min-height: 0 !important;
  aspect-ratio: 1 / 1;
  margin: 0 !important;
  padding: 0 !important;
  border: 0 !important;
  border-radius: 0 !important;
  background: none !important;
}
/* The gallery mixes square renders with portrait in-game shots, and the
   screenshots carry a decorative frame that a crop cuts straight
   through. Fit inside the square instead: the render fills it exactly,
   a taller shot is matted by the plate rather than trimmed. */
.store-product-full .media-slider img.slide-image,
.store-product-full .media-slider .slide-frame {
  width: 100% !important;
  height: 100% !important;
  max-width: none !important;
  max-height: none !important;
  margin: 0 !important;
  border-radius: 0 !important;
  object-fit: contain !important;
  object-position: 50% 50% !important;
  cursor: zoom-in;
}
.store-product-full .media-slider .thumbs {
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
  gap: 10px;
  margin: 0 !important;
  padding: 14px 16px 16px;
}
.store-product-full .media-slider .thumb {
  width: 58px;
  height: 58px;
  border-radius: 10px;
  overflow: hidden;
  cursor: pointer;
}

/* The theme ships an expand control on the slider with no styling of
   its own, so it rendered as an invisible square over the artwork. */
.store-product-full .media-slider { position: relative; }
.store-product-full .media-slider .open-lightbox {
  position: absolute;
  top: 14px;
  right: 14px;
  z-index: 3;
  width: 38px;
  height: 38px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  border: 1px solid rgba(255, 196, 132, .45);
  background: rgba(14, 9, 6, .72);
  -webkit-backdrop-filter: blur(4px);
          backdrop-filter: blur(4px);
  color: #f6ece6;
  font-size: 0;
  cursor: pointer;
  transition: background .18s ease, border-color .18s ease, transform .18s ease;
}
.store-product-full .media-slider .open-lightbox::after {
  content: "";
  width: 17px;
  height: 17px;
  background-color: currentColor;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  -webkit-mask-position: center;  mask-position: center;
  -webkit-mask-size: contain;     mask-size: contain;
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='10.5' cy='10.5' r='6.5'/%3E%3Cpath d='M15.3 15.3 21 21M10.5 7.8v5.4M7.8 10.5h5.4'/%3E%3C/svg%3E");
          mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='10.5' cy='10.5' r='6.5'/%3E%3Cpath d='M15.3 15.3 21 21M10.5 7.8v5.4M7.8 10.5h5.4'/%3E%3C/svg%3E");
}
.store-product-full .media-slider .open-lightbox:hover {
  background: rgba(249, 115, 22, .3);
  border-color: rgba(255, 224, 186, .8);
  transform: scale(1.06);
}

@media (min-width: 900px) {
  .store-product-full > .media-slider {
    grid-column: 1;
    grid-row: 1 / span 3;
    align-self: center;
  }
}

/* --- lightbox: paging between a package's images --------------------- */
.a-lb-count {
  padding: 0 12px 0 6px;
  color: var(--muted, #c8b9b1);
  font-size: 13px;
  letter-spacing: .04em;
  white-space: nowrap;
}
.a-lightbox:not(.has-many) .a-lb-nav,
.a-lightbox:not(.has-many) .a-lb-count { display: none; }

.a-lb-nav {
  position: fixed;
  top: 50%;
  transform: translateY(-50%);
  width: 52px;
  height: 52px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  border: 1px solid var(--line);
  background: rgba(18, 12, 9, .8);
  color: #f4ece7;
  cursor: pointer;
  z-index: 10000;
  transition: background .16s ease, border-color .16s ease, transform .16s ease;
}
.a-lb-nav:hover {
  background: rgba(249, 115, 22, .22);
  border-color: rgba(249, 115, 22, .6);
}
.a-lb-prev { left: 22px; }
.a-lb-next { right: 22px; }
.a-lb-nav::after {
  content: "";
  width: 18px;
  height: 18px;
  background-color: currentColor;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  -webkit-mask-position: center;  mask-position: center;
  -webkit-mask-size: contain;     mask-size: contain;
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M15 4 7 12l8 8'/%3E%3C/svg%3E");
          mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M15 4 7 12l8 8'/%3E%3C/svg%3E");
}
.a-lb-next::after { transform: rotate(180deg); }

@media (max-width: 620px) {
  .a-lb-nav { width: 44px; height: 44px; }
  .a-lb-prev { left: 10px; }
  .a-lb-next { right: 10px; }
}
