/* =====================================================================
   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: 14px;
  height: 14px;
  flex: none;
  border: 1.5px solid var(--ac);
  border-radius: 50%;
  opacity: 0.8;
}
.a-trust span:nth-child(2)::before { border-radius: 3px; }
.a-trust span:nth-child(3)::before { border-radius: 50% 50% 50% 2px; transform: rotate(-45deg); }

/* 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);
}

.popup-close {
  position: absolute !important;
  top: 16px;
  right: 18px;
  width: 34px;
  height: 34px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  border: 1px solid var(--line);
  background: rgba(255, 255, 255, .04);
  color: var(--muted, #c8b9b1);
  font-size: 0;
  cursor: pointer;
  z-index: 3;
  transition: background .18s var(--ease), border-color .18s var(--ease), color .18s var(--ease);
}

/* Exo draws its close icon as bars on ::before — with our own glyph on
   ::after that left a stray dash floating above the cross. */
.popup-close::before { display: none !important; }

.popup-close::after {
  content: "\00d7";
  font-size: 20px;
  line-height: 1;
}

.popup-close:hover {
  background: rgba(249, 115, 22, .14);
  border-color: rgba(249, 115, 22, .45);
  color: var(--fg);
}

/* --- 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
   Tebex stamps data-not-purchasable="1" on .product-actions and sets
   the buttons to pointer-events:none whenever the webstore is not
   taking orders (pending review, or store paused). Without this the
   button still looks live and a click does nothing, which reads as a
   broken site. Show the real state instead. Reverts on its own the
   moment Tebex starts accepting orders.
   --------------------------------------------------------------- */
.product-actions[data-not-purchasable="1"] .add,
.product-actions[data-not-purchasable="1"] .subscribe {
  background: linear-gradient(180deg, #38281e, #271a12) !important;
  border: 1px solid rgba(255, 160, 80, .18) !important;
  box-shadow: none !important;
  cursor: not-allowed !important;
  transform: none !important;
  font-size: 0 !important;
  color: transparent !important;
}
.product-actions[data-not-purchasable="1"] .add::after,
.product-actions[data-not-purchasable="1"] .subscribe::after { display: none !important; }

.product-actions[data-not-purchasable="1"] .add::before,
.product-actions[data-not-purchasable="1"] .subscribe::before {
  content: "Store opening soon";
  font-family: inherit;
  font-size: 14px;
  font-weight: 600;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: rgba(255, 226, 200, .58);
}

.product-actions[data-not-purchasable="1"] { cursor: not-allowed; }
