/* the store's look since 2026-10-07, at jack's ask: the refined dark one he picked out of three
   samples. the shadcn bones it had stay (the same parts, flat buttons a size down, 8px controls
   and 14px cards, and still no glows, light rays, blur-ins or hovers that change a border), with
   geist for the headings and the words alike (jack, the same day), white buttons with the purple
   left to the logo, and dark only: the light version is gone. later that day jack had everything that reads as made by ai
   taken out: glowing and purple borders and washes, the dot grid, the frosted bar, icons on tiles,
   badges, the fade-in, crushed heading spacing and soft drop shadows.
   style.css is everything every page shares; store.css is the store's own pages.

   MIT License

   Copyright (c) 2023 shadcn
   Copyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)

   Permission is hereby granted, free of charge, to any person obtaining a copy
   of this software and associated documentation files (the "Software"), to deal
   in the Software without restriction, including without limitation the rights
   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
   copies of the Software, and to permit persons to whom the Software is
   furnished to do so, subject to the following conditions:

   The above copyright notice and this permission notice shall be included in all
   copies or substantial portions of the Software.

   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
   SOFTWARE. */

:root {
  color-scheme: dark;

  /* the page and what sits on it, a step up each: cards, then raised bits (a switch's track, a
     dialog, a field), then fills for a hover or a grey button */
  --bg: #09090b;
  --surface: #111113;
  --surface-2: #18181b;
  --surface-3: #232328;
  --surface-4: #2c2c32;
  --border: rgba(255, 255, 255, 0.08);
  --border-strong: rgba(255, 255, 255, 0.13);
  --wash: rgba(255, 255, 255, 0.03);
  --wash-hover: rgba(255, 255, 255, 0.07);

  --ink: #fafafa;
  --text: #e4e4e7;
  --muted: #a1a1aa;
  /* the quietest grey that still reads at 13px on the page and on a card */
  --faint: #7f7f88;
  --icon: #a1a1aa;

  /* the logo's purple, on the mark and a plan's trial band (jack, 2026-11-03). the buttons are white with near-black words,
     a shade greyer on hover and press (jack, 2026-10-07: purple buttons read as made by ai). #7130c3 is the echo rust
     purple and goes on the dark page as it is: it was lifted to #9d6be3 to read better there until jack had it put
     back (2026-11-12) */
  --brand: #7130c3;
  --pop: #fafafa;
  --pop-hover: #e4e4e7;
  --pop-active: #d4d4d8;
  --pop-ink: #09090b;

  --success: #7ccf00;
  --success-soft: rgba(124, 207, 0, 0.12);
  --danger: #ff6467;
  --danger-text: #ff8a8c;
  --danger-soft: rgba(255, 100, 103, 0.12);
  --danger-soft-hover: rgba(255, 100, 103, 0.2);
  --warn: #f0b100;

  --r-sm: 6px;
  --r: 8px;
  --r-lg: 10px;
  --r-card: 14px;
  --r-pill: 9999px;

  --font: 'Geist', ui-sans-serif, system-ui, -apple-system, 'Segoe UI', sans-serif;
  --display: 'Geist', ui-sans-serif, system-ui, -apple-system, 'Segoe UI', sans-serif;
  --mono: 'Geist Mono', ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;

  --ease: cubic-bezier(0.16, 1, 0.3, 1);
  --std: cubic-bezier(0.4, 0, 0.2, 1);
  --motion: 0.15s var(--std);

  --band: min(1120px, calc(100% - 48px));
  --nav-h: 64px;
  --z-nav: 100;
  --z-toast: 120;
}

*, *::before, *::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  scrollbar-gutter: stable;
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--nav-h) + var(--sales-h, 0px) + 24px);
  scrollbar-color: var(--surface-4) var(--bg);
  background: var(--bg);
}

body {
  margin: 0;
  min-height: 100dvh;
  overflow-x: clip;
  color: var(--text);
  font-family: var(--font);
  font-size: 16px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  font-kerning: normal;
}

img { max-width: 100%; display: block; }
a { color: inherit; text-decoration: none; }
h1, h2, h3, h4 { margin: 0; color: var(--ink); font-weight: 600; line-height: 1.2; }
p { margin: 0; }
button { font: inherit; color: inherit; letter-spacing: inherit; }
::selection { background: var(--pop); color: var(--pop-ink); }
:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }
/* every line icon a hairline, 1px on the screen whatever size its box scales it to */
svg path, svg circle, svg rect, svg line, svg polyline { vector-effect: non-scaling-stroke; }

.skip-link {
  position: absolute; left: 12px; top: -60px; z-index: 200;
  padding: 8px 14px; border-radius: var(--r);
  background: var(--pop); color: var(--pop-ink); font-size: 14px; font-weight: 500;
  transition: top var(--motion);
}
.skip-link:focus { top: 12px; }

.num { font-family: var(--mono); font-variant-numeric: tabular-nums; }
.sr-only { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }

/* the page */
.site { position: relative; display: flex; flex-direction: column; min-height: 100dvh; padding-top: var(--nav-h); }
.site > #main { flex: 1 0 auto; display: flex; flex-direction: column; }

/* the bar (jack, 2026-10-27): the logo left, the pages in the middle, Get Premium, who is signed in
   and the cart right. equal sides keep the pages in the middle of the bar, and a side that needs more
   than its share takes it from the other rather than running into them. under 1024px the pages go
   in the menu button's list */

.nav {
  position: fixed; inset: 0 0 auto; z-index: var(--z-nav);
  height: var(--nav-h);
  display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; column-gap: 24px;
  /* percentage padding measures the viewport less the scrollbar, same as the band */
  padding: 0 calc((100% - var(--band)) / 2);
  /* frosted (jack, 2026-10-07): the page's black at 72% with a blur, so what scrolls under the bar
     shows through as soft shapes and its own words stay clear. solid where a browser cannot blur,
     since unblurred words under the bar's would fight them, and for anyone whose device asks for
     less see-through */
  background: rgba(9, 9, 11, 0.72);
  -webkit-backdrop-filter: blur(14px) saturate(150%);
  backdrop-filter: blur(14px) saturate(150%);
  border-bottom: 1px solid var(--border);
}
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .nav { background: var(--bg); }
}
@media (prefers-reduced-transparency: reduce) {
  .nav { background: var(--bg); -webkit-backdrop-filter: none; backdrop-filter: none; }
}
.nav-pill { display: contents; }
.brand { justify-self: start; display: inline-flex; align-items: center; gap: 10px; flex: none; color: var(--ink); font-family: var(--display); font-size: 17px; font-weight: 600; letter-spacing: -0.005em; line-height: 22px; }
.brand-mark { width: 13px; height: 20px; flex: none; }
.brand-mark path { fill: var(--brand); }
.nav-end { display: flex; align-items: center; justify-content: flex-end; gap: 8px; }

/* Bases, Link accounts and Join Discord, each with its line icon, in the middle of the bar and again
   in the menu's list */
.nav-links { display: flex; align-items: center; gap: 4px; }
.nav-link { display: inline-flex; align-items: center; gap: 8px; flex: none; height: 32px; padding: 0 10px; border-radius: var(--r); color: var(--muted); font-size: 14px; font-weight: 500; white-space: nowrap; transition: background-color var(--motion), color var(--motion); }
.nav-link:hover { color: var(--ink); background: var(--surface-3); }
/* the page you are on, held in the hover's fill: the ink alone was missed (jack, 2026-10-08) */
.nav-link[aria-current="page"] { color: var(--ink); background: var(--surface-3); }
.nav-link svg { width: 16px; height: 16px; flex: none; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.nav-link svg path { vector-effect: none; }
.nav-link .nav-discord { fill: currentColor; stroke: none; }

/* the menu button, only where the bar has no room for the pages, and its list hung under the bar
   like the account menu: the pages, and Get Premium on a phone, where the bar drops it */
.menu-btn { display: none; place-items: center; flex: none; width: 32px; height: 32px; padding: 0; border: 0; border-radius: var(--r); background: transparent; color: var(--ink); cursor: pointer; transition: background-color var(--motion); }
.menu-btn:hover { background: var(--surface-3); }
.menu-btn svg { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linecap: round; }
.menu-btn svg path { vector-effect: none; }
.nav-pop {
  position: fixed; inset: calc(var(--nav-h) + 8px) max(24px, calc((100vw - 1120px) / 2)) auto auto;
  width: min(260px, calc(100vw - 32px)); margin: 0; padding: 6px;
  border: 1px solid var(--border-strong); border-radius: var(--r-card);
  background: var(--surface-2); color: var(--ink);
}
.nav-pop:popover-open { display: grid; animation: alerts-in 0.16s var(--std); }
.nav-pop .nav-link { height: 36px; border-radius: var(--r-sm); color: var(--text); }
.nav-pop .nav-link:hover, .nav-pop .nav-link[aria-current="page"] { color: var(--ink); }
.nav-pop-cta { margin-top: 6px; }

.nav-cta {
  display: inline-flex; align-items: center; justify-content: center; flex: none;
  height: 32px; padding: 0 12px; border-radius: var(--r);
  background: var(--pop); color: var(--pop-ink);
  font-size: 14px; font-weight: 500; white-space: nowrap;
  transition: background-color var(--motion);
}
.nav-cta:hover { background: var(--pop-hover); }
.nav-cta:active { background: var(--pop-active); }

/* the account: Sign in, or the avatar and name, which open the account menu. a long name ends in
   dots. bar.js draws it, the same on the store and the base browser */
#account { display: inline-flex; align-items: center; justify-content: flex-end; gap: 2px; min-width: 0; max-width: 220px; }
#account .btn-sm { min-height: 32px; padding: 0 12px; font-size: 14px; }
#account .who { display: inline-flex; align-items: center; gap: 8px; min-width: 0; height: 32px; padding: 0 8px 0 4px; border: 0; border-radius: var(--r); background: transparent; color: var(--ink); font-family: inherit; font-size: 14px; font-weight: 500; cursor: pointer; transition: background-color var(--motion); }
#account .who:hover, #account .who[aria-current="page"] { background: var(--surface-3); }
#account .who img { width: 24px; height: 24px; flex: none; border-radius: 50%; box-shadow: 0 0 0 1px var(--border-strong); }
#account .who .name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.nav-auth { display: flex; align-items: center; flex: none; }
.basket-button {
  display: inline-flex; align-items: center; gap: 8px;
  height: 32px; padding: 0 6px 0 10px; border-radius: var(--r);
  color: var(--muted); font-size: 14px; font-weight: 500; white-space: nowrap;
  transition: background-color var(--motion), color var(--motion);
}
.basket-button:hover { color: var(--ink); background: var(--surface-3); }
.basket-button .count {
  min-width: 20px; height: 20px; padding: 0 6px;
  display: inline-grid; place-items: center;
  border-radius: var(--r-pill); background: var(--surface-3); color: var(--muted);
  font-size: 12px; font-weight: 600; line-height: 16px; font-variant-numeric: tabular-nums;
}
.basket-button:hover .count { background: var(--surface-4); }
.basket-button.has-items .count { background: var(--pop); color: var(--pop-ink); }
/* the base browser with no word from paynow on the cart: no number rather than a wrong one */
.basket-button .count[hidden] { display: none; }

/* the bell beside the account, only there when something on it needs looking at: its dot red for a
   payment that did not go through or a plan that ran out, amber for a plan about to (jack,
   2026-10-07). it opens the list below the bar */
.bell { position: relative; display: inline-grid; place-items: center; flex: none; width: 32px; height: 32px; padding: 0; border: 0; border-radius: var(--r); background: transparent; color: var(--ink); cursor: pointer; transition: background-color var(--motion); }
.bell[hidden] { display: none; }
.bell:hover { background: var(--surface-3); }
.bell svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 1.25; stroke-linecap: round; stroke-linejoin: round; }
.bell::after { content: ""; position: absolute; top: 6px; right: 7px; width: 8px; height: 8px; border-radius: 50%; background: var(--danger); box-shadow: 0 0 0 2px var(--bg); }
.bell[data-level="warn"]::after { background: var(--warn); }

/* the bell's list: a raised card hung under the bar at its right edge, one row an alert with what
   happened, when, and the button that sorts it */
.alerts {
  position: fixed; inset: calc(var(--nav-h) + 8px) max(24px, calc((100vw - 1120px) / 2)) auto auto;
  width: min(340px, calc(100vw - 32px)); max-height: calc(100dvh - var(--nav-h) - 24px); overflow-y: auto;
  margin: 0; padding: 6px;
  border: 1px solid var(--border-strong); border-radius: var(--r-card);
  background: var(--surface-2); color: var(--ink);
}
.alerts:popover-open { animation: alerts-in 0.16s var(--std); }
@keyframes alerts-in { from { opacity: 0; transform: translateY(-4px); } }
.alert { display: grid; grid-template-columns: 18px minmax(0, 1fr) auto; align-items: start; column-gap: 10px; padding: 10px; }
.alert + .alert { border-top: 1px solid var(--border); }
.alert-icon { width: 18px; height: 18px; margin-top: 1px; fill: none; stroke: currentColor; stroke-width: 1.25; stroke-linecap: round; stroke-linejoin: round; }
.alert.is-bad .alert-icon { color: var(--danger-text); }
.alert.is-warn .alert-icon { color: var(--warn); }
.alert-title { color: var(--ink); font-size: 13px; font-weight: 500; line-height: 18px; }
.alert-line { margin-top: 2px; color: var(--muted); font-size: 12px; line-height: 17px; }
.alert-act { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 10px; }
.alert-x { display: grid; place-items: center; width: 24px; height: 24px; margin: -3px -3px 0 0; padding: 0; border: 0; border-radius: var(--r-sm); background: none; color: var(--faint); cursor: pointer; transition: background-color var(--motion), color var(--motion); }
.alert-x:hover { background: var(--surface-3); color: var(--ink); }
.alert-x svg { width: 12px; height: 12px; fill: none; stroke: currentColor; stroke-width: 1.25; stroke-linecap: round; }

/* link accounts, its own page at /linking since 2026-10-27 (a panel off the bar until then, jack,
   2026-10-07): steam over discord in one card, each row a logo, a name, where it stands and its
   button. the ui only: the discord side is jack's bot, through the three link service settings */
/* is-narrow already pads the top, so the head does not again */
.page-head.links-head { padding-top: 0; }
.card.links-card { padding: 4px 24px; }
.links-row { display: grid; grid-template-columns: 24px minmax(0, 1fr) auto; align-items: center; column-gap: 14px; padding: 20px 0; }
.links-row + .links-row { border-top: 1px solid var(--border); }
.links-logo { width: 24px; height: 24px; fill: currentColor; }
.links-info { display: grid; min-width: 0; }
.links-info b { color: var(--ink); font-size: 15px; font-weight: 500; line-height: 22px; }
.links-info span { color: var(--muted); font-size: 14px; line-height: 20px; overflow-wrap: anywhere; }
/* steam's tick: the store knows it from the sign in */
.links-ok { width: 16px; height: 16px; margin-right: 6px; background: var(--success); -webkit-mask: 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' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6 9 17l-5-5'/%3E%3C/svg%3E") center / contain no-repeat; mask: 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' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6 9 17l-5-5'/%3E%3C/svg%3E") center / contain no-repeat; }
.links-row[data-state="guest"] .links-go, .links-row[data-state="checking"] .links-go { display: none; }
.links-row[data-state="linked"] .links-status { color: var(--success); }
.links-row[data-state="error"] .links-status { color: var(--danger-text); }
/* until the discord link url is set in the theme's settings */
.links-go[aria-disabled="true"] { opacity: 0.5; pointer-events: none; }
/* the row's buttons: Link Discord, or once linked Change and the unlink icon */
.links-act { display: flex; align-items: center; gap: 6px; }
/* held inside .links-act so it outranks .btn, which comes later and would show it again */
.links-act .links-cut { display: none; width: 32px; padding: 0; }
.links-cut svg { width: 14px; height: 14px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.links-cut svg path { vector-effect: none; }
.links-cut[aria-disabled="true"] { opacity: 0.5; pointer-events: none; }
.links-row[data-state="linked"] .links-cut { display: inline-flex; }

@media (max-width: 1023px) {
  .nav { display: flex; justify-content: space-between; gap: 16px; }
  /* a long name ends in dots here; in the three columns it takes room from the logo's side instead */
  .nav-end { min-width: 0; }
  .nav-links { display: none; }
  .menu-btn { display: inline-grid; }
}
/* held inside .nav-pop so it outranks .btn, which comes later and would show it again */
@media (min-width: 641px) {
  .nav-pop .nav-pop-cta { display: none; }
}

/* the sales on now, a strip under the bar that rides along with it as the page scrolls (jack,
   2026-10-07). main.js measures it into --sales-h, which a jump to a section and the cart's summary
   add to the bar's height; 41px, one line, until it does */
.sales { position: sticky; top: var(--nav-h); z-index: calc(var(--z-nav) - 1); border-bottom: 1px solid var(--border); background: var(--surface); }
.sales[hidden] { display: none; }
:root:has(.sales:not([hidden])) { --sales-h: 41px; }
.sale { width: var(--band); margin: 0 auto; padding: 10px 0; color: var(--muted); font-size: 13px; line-height: 20px; text-align: center; text-wrap: balance; }
.sale + .sale { border-top: 1px solid var(--border); }
.sale b { color: var(--ink); font-weight: 500; }
.sale a { margin-left: 4px; color: var(--ink); font-weight: 500; text-decoration: underline; text-decoration-color: var(--border-strong); text-underline-offset: 3px; transition: text-decoration-color var(--motion); }
.sale a:hover { text-decoration-color: currentColor; }

/* buttons: 32 tall at 8px round in 14px medium, 28 for sm and 36 for lg, since jack found 36 and
   40 big and bubbly (2026-10-05). flat fills, the hover a shade lighter; an outline button keeps
   its border on hover and only the fill moves, jack's rule */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  min-height: 32px; padding: 0 12px;
  border: 1px solid transparent; border-radius: var(--r);
  background: transparent; color: var(--ink);
  font-size: 14px; font-weight: 500; line-height: 20px; text-align: center; white-space: nowrap;
  cursor: pointer; user-select: none;
  transition: background-color var(--motion), color var(--motion);
}
.btn[disabled] { opacity: 0.5; cursor: not-allowed; }
.btn-lg { min-height: 36px; padding: 0 16px; }
.btn-sm { min-height: 28px; padding: 0 10px; gap: 4px; font-size: 13px; }
.btn-wide { width: 100%; }
/* the arrow after a button that leaves the store for steam's sign in, as the figma draws it: a
   1.46 stroke across 17.5, here at 16 with the stroke scaling along, not held to a hairline. the
   same room from the words on every button that has it, about 12px to the arrow itself (8px of gap
   and the space the arrow has round it), and it stays still on hover (jack, 2026-10-07) */
.btn:has(> .arrow-out) { gap: 8px; }
.arrow-out { width: 16px; height: 16px; flex: none; margin-right: -4px; fill: none; stroke: currentColor; stroke-width: 1.45833; stroke-linecap: round; stroke-linejoin: round; }
.arrow-out path { vector-effect: none; }
/* cta the purple, primary the outline, ghost the grey, quiet a link, danger a soft red */
.btn-cta { background: var(--pop); color: var(--pop-ink); }
.btn-cta:hover:not([disabled]) { background: var(--pop-hover); }
.btn-cta:active:not([disabled]) { background: var(--pop-active); }
.btn-primary { background: var(--wash); border-color: var(--border-strong); }
.btn-primary:hover:not([disabled]) { background: var(--wash-hover); }
.btn-ghost { background: var(--surface-3); }
.btn-ghost:hover:not([disabled]) { background: var(--surface-4); }
.btn-quiet { padding: 0 8px; color: var(--muted); text-underline-offset: 4px; }
.btn-quiet:hover { color: var(--ink); text-decoration: underline; }
.btn-danger { background: var(--danger-soft); color: var(--danger-text); }
.btn-danger:hover:not([disabled]) { background: var(--danger-soft-hover); }

/* badges: a 22px pill in 12px medium, grey unless it says something */
.badge {
  display: inline-flex; align-items: center;
  height: 22px; padding: 0 9px; border-radius: var(--r-pill);
  background: var(--surface-3); color: var(--ink);
  font-size: 12px; font-weight: 500; line-height: 16px; white-space: nowrap;
}
.badge-deal { background: var(--success-soft); color: var(--success); }

/* the copy chip: an outline button in the mono with a copy icon in front */
.chip {
  display: inline-flex; align-items: center; gap: 8px;
  height: 32px; max-width: 100%; padding: 0 12px;
  border: 1px solid var(--border-strong); border-radius: var(--r);
  background: var(--wash); color: var(--ink);
  font-size: 14px; white-space: nowrap; cursor: pointer;
  transition: background-color var(--motion);
}
.chip:hover { background: var(--wash-hover); }
.chip-copy { font-family: var(--mono); font-size: 13px; }
.chip-copy::before {
  content: ""; width: 13px; height: 13px; flex: none; background: var(--icon);
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%23000' stroke-width='1'%3E%3Crect x='5.5' y='5.5' width='8' height='8' rx='1.5'/%3E%3Cpath d='M10.5 3.5V3A1.5 1.5 0 0 0 9 1.5H4A1.5 1.5 0 0 0 2.5 3v5A1.5 1.5 0 0 0 4 9.5h.5'/%3E%3C/svg%3E") center / contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%23000' stroke-width='1'%3E%3Crect x='5.5' y='5.5' width='8' height='8' rx='1.5'/%3E%3Cpath d='M10.5 3.5V3A1.5 1.5 0 0 0 9 1.5H4A1.5 1.5 0 0 0 2.5 3v5A1.5 1.5 0 0 0 4 9.5h.5'/%3E%3C/svg%3E") center / contain no-repeat;
}

/* inner pages: the cart, the account, a policy, payment complete */

.site-content { width: var(--band); margin: 0 auto; flex: 1 0 auto; }
.site-content > main { min-width: 0; }
.site-content.is-narrow { max-width: 520px; padding-top: clamp(48px, 7vw, 88px); }
.page-head { padding: clamp(48px, 7vw, 88px) 0 32px; }
.page-title { font-family: var(--display); font-size: 48px; font-weight: 600; line-height: 1.04; letter-spacing: -0.02em; text-wrap: balance; }
.page-lead { margin-top: 12px; max-width: 580px; color: var(--muted); font-size: 16px; line-height: 24px; text-wrap: pretty; }

.card { padding: 28px; border: 1px solid var(--border); border-radius: var(--r-card); background: var(--surface); }
.card-title { font-family: var(--display); font-size: 28px; font-weight: 600; line-height: 1.1; letter-spacing: -0.015em; }
.card-lead { margin-top: 8px; color: var(--muted); font-size: 15px; line-height: 23px; }

/* a policy or any page written in the dashboard */
.prose-card { max-width: 760px; padding: clamp(24px, 4vw, 44px); border: 1px solid var(--border); border-radius: var(--r-card); background: var(--surface); }
.text-content { color: var(--text); font-size: 16px; line-height: 1.65; max-width: 66ch; text-wrap: pretty; }
.text-content > :first-child { margin-top: 0; }
.text-content h2 { margin: 40px 0 12px; color: var(--ink); font-family: var(--display); font-size: 24px; font-weight: 600; line-height: 1.25; letter-spacing: -0.01em; }
.text-content h3, .text-content h4 { margin: 32px 0 8px; color: var(--ink); font-size: 17px; font-weight: 600; }
.text-content p { margin: 0 0 16px; }
.text-content ul, .text-content ol { margin: 0 0 16px; padding-left: 20px; }
.text-content li { margin-bottom: 6px; }
.text-content li::marker { color: var(--faint); }
.text-content a { color: var(--ink); text-decoration: underline; text-decoration-color: var(--faint); text-underline-offset: 3px; transition: text-decoration-color var(--motion); }
.text-content a:hover { text-decoration-color: currentColor; }
.text-content strong, .text-content b { color: var(--ink); font-weight: 600; }
.text-content hr { margin: 32px 0; border: 0; border-top: 1px solid var(--border); }
.text-content table { width: 100%; margin: 0 0 16px; border-collapse: collapse; font-size: 14px; line-height: 20px; }
.text-content th, .text-content td { padding: 10px 12px; border-bottom: 1px solid var(--border); text-align: left; }
.text-content th { color: var(--muted); font-weight: 500; white-space: nowrap; }
.text-content img { border-radius: var(--r-lg); }
.text-content > :last-child { margin-bottom: 0; }
/* the payment complete card's words: the card's lead, set as rich text since the dashboard
   writes them */
.card-lead.text-content { color: var(--muted); font-size: 15px; line-height: 23px; }
.card-lead.text-content strong, .card-lead.text-content b { color: var(--ink); }

/* forms: the gift's Steam ID box is the only field the store draws */
.field-label { display: block; margin: 0 0 6px; color: var(--ink); font-size: 14px; font-weight: 500; }
input:not([type]), input[type=text], input[type=search], input[type=number], input[type=email], textarea {
  width: 100%; height: 38px; padding: 0 12px;
  border: 1px solid var(--border-strong); border-radius: var(--r);
  background: var(--wash); color: var(--ink);
  font-family: var(--font); font-size: 14px; line-height: 20px;
}
input[inputmode=numeric] { font-family: var(--mono); font-variant-numeric: tabular-nums; letter-spacing: 0.02em; }
textarea { height: auto; min-height: 76px; padding: 8px 12px; resize: vertical; }
input::placeholder, textarea::placeholder { color: var(--faint); }
input:focus-visible, textarea:focus-visible { outline: 2px solid var(--ink); outline-offset: 1px; }
.form-actions { display: flex; gap: 8px; margin-top: 24px; }
.form-actions > .btn-wide { flex: 1 1 0; }

/* the ticked lines under a buy button or a total */
.buybox-list { list-style: none; margin: 20px 0 0; padding: 16px 0 0; border-top: 1px solid var(--border); color: var(--muted); font-size: 14px; }
.buybox-list li { display: flex; align-items: flex-start; gap: 10px; padding: 4px 0; line-height: 21px; }
.buybox-list li::before {
  content: ""; flex: 0 0 14px; width: 14px; height: 14px; margin-top: 3.5px; background: var(--muted);
  -webkit-mask: 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' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6 9 17l-5-5'/%3E%3C/svg%3E") center / contain no-repeat;
  mask: 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' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6 9 17l-5-5'/%3E%3C/svg%3E") center / contain no-repeat;
}
.note { color: var(--muted); font-size: 14px; line-height: 1.5; }
.no-products { padding: 64px 0; color: var(--muted); text-align: center; }
/* nothing here yet: an empty cart, no orders, no subscriptions */
.basket-empty { padding: 64px 24px; border: 1px dashed var(--border-strong); border-radius: var(--r-card); background: rgba(255, 255, 255, 0.012); text-align: center; }
.basket-empty p { margin-bottom: 20px; color: var(--muted); }

/* toast: bottom right, a raised card rising into place. one box for Copied and for paynow's notices */
.toast {
  position: fixed; right: 24px; bottom: 24px; z-index: var(--z-toast);
  width: max-content; max-width: min(400px, calc(100vw - 48px));
  padding: 14px 16px;
  border: 1px solid var(--border-strong); border-radius: var(--r-lg);
  background: var(--surface-2); color: var(--ink);
  font-size: 14px; font-weight: 500; line-height: 20px;
  animation: toast-in 0.25s cubic-bezier(0, 0, 0.58, 1);
  cursor: pointer;
}
@keyframes toast-in { from { opacity: 0; transform: translateY(12px) scale(0.97); } }

/* tooltip: the colours turned over (page-colour words on the ink), with an arrow up at the control,
   open at once on hover or keyboard focus. it hangs under the control: everything carrying one sits
   in the bar along the top of the screen */
[data-tip] { position: relative; }
[data-tip]::before, [data-tip]::after {
  position: absolute; left: 50%; z-index: 300; pointer-events: none;
  opacity: 0; scale: 0.9;
  transition: opacity 0.2s cubic-bezier(0, 0, 0.2, 1), scale 0.2s cubic-bezier(0, 0, 0.2, 1);
}
[data-tip]::after {
  content: attr(data-tip);
  top: calc(100% + 10px); translate: -50% 0;
  width: max-content; max-width: 240px; padding: 6px 12px; border-radius: var(--r);
  background: var(--ink); color: var(--bg);
  font-size: 12px; font-weight: 500; line-height: 16px; text-align: left; white-space: normal;
}
[data-tip]::before {
  content: ""; top: calc(100% + 6px); width: 8px; height: 8px; margin-left: -4px; z-index: 301;
  border-radius: 2px; background: var(--ink); rotate: 45deg;
}
@media (hover: hover) {
  [data-tip]:hover::before, [data-tip]:hover::after { opacity: 1; scale: 1; }
}
[data-tip]:focus-visible::before, [data-tip]:focus-visible::after { opacity: 1; scale: 1; }

/* footer */

/* no rule along its top and no shade of its own: the square grid carries the page into it (jack,
   2026-10-07: the edge read as a hard cut off). not isolated, so the grid sits behind the page
   above it, where it thins in, rather than over it */
.footer { position: relative; flex: 0 0 auto; margin-top: clamp(96px, 12vw, 144px); padding: 64px 0 36px; }
/* the header grids' fade out (jack, 2026-10-14: a straight one still ended on a line): the canvas
   runs --tail past the shape main.js draws and the fade takes twice that, as steep as a straight
   fade at its top, then thinning out to nothing, (1 - t) squared. registered so a clamp() in it
   computes to px, which main.js reads to keep each mask's shape above the tail */
@property --tail { syntax: "<length>"; inherits: false; initial-value: 0px; }
canvas.squares {
  --fade-out: linear-gradient(to bottom, #000 calc(100% - 2 * var(--tail)),
    rgba(0, 0, 0, 0.77) calc(100% - 1.75 * var(--tail)), rgba(0, 0, 0, 0.56) calc(100% - 1.5 * var(--tail)),
    rgba(0, 0, 0, 0.39) calc(100% - 1.25 * var(--tail)), rgba(0, 0, 0, 0.25) calc(100% - var(--tail)),
    rgba(0, 0, 0, 0.14) calc(100% - 0.75 * var(--tail)), rgba(0, 0, 0, 0.06) calc(100% - 0.5 * var(--tail)),
    rgba(0, 0, 0, 0.016) calc(100% - 0.25 * var(--tail)), transparent);
}
/* the square grid across the top of the footer (jack, 2026-10-07): from the top of the gap over the
   footer to 300px into it, and three tenths of that again higher (2026-10-14), where it rises out
   of nothing; main.js draws and fades it */
.squares-footer { position: absolute; z-index: -1; top: calc(-1.3 * clamp(96px, 12vw, 144px) - 90px); left: 0; display: block; width: 100%; height: calc(1.3 * clamp(96px, 12vw, 144px) + 390px); pointer-events: none; }
.footer-inner { width: var(--band); margin: 0 auto; display: grid; grid-template-columns: minmax(240px, 340px) minmax(0, 1fr); gap: 48px; align-items: start; }
.footer-brand { display: flex; flex-direction: column; align-items: flex-start; gap: 14px; }
.footer-brand-row { display: inline-flex; align-items: center; gap: 10px; color: var(--ink); font-family: var(--display); font-size: 17px; font-weight: 600; letter-spacing: -0.005em; line-height: 22px; }
.footer-brand-row .brand-mark { width: 13px; height: 20px; flex: none; }
.footer-tag { max-width: 34ch; color: var(--muted); font-size: 14px; line-height: 21px; }
.footer-socials { display: flex; align-items: center; gap: 8px; }
.footer-socials a { display: inline-grid; place-items: center; width: 34px; height: 34px; border: 1px solid var(--border-strong); border-radius: var(--r); background: var(--wash); color: var(--muted); transition: background-color var(--motion), color var(--motion); }
.footer-socials a:hover { background: var(--wash-hover); color: var(--ink); }
.footer-socials svg { width: 16px; height: 16px; }
.footer-cols { display: grid; grid-template-columns: repeat(4, auto); justify-content: space-between; gap: 32px; }
.footer-col { display: flex; flex-direction: column; gap: 10px; }
/* the store column, when paynow had nothing to list in it */
.footer-col[hidden] { display: none; }
.footer-col-title { margin-bottom: 4px; color: var(--ink); font-size: 13px; font-weight: 500; }
.footer-col a, .footer-plain { color: var(--muted); font-size: 14px; transition: color var(--motion); }
.footer-col a:hover { color: var(--ink); }
.footer-plain { font-family: var(--mono); font-size: 13px; }
.footer-bottom { width: var(--band); margin: 48px auto 0; padding-top: 22px; border-top: 1px solid var(--border); display: flex; flex-wrap: wrap; justify-content: space-between; gap: 6px 20px; color: var(--faint); font-size: 13px; }

/* responsive */

@media (max-width: 900px) {
  .footer-inner { grid-template-columns: minmax(0, 1fr); }
  .footer-cols { grid-template-columns: repeat(2, minmax(0, 1fr)); justify-content: stretch; }
}

/* a phone has room for the logo, the account, the cart and the menu button, which holds Get Premium
   too; Sign in drops with Steam */
@media (max-width: 640px) {
  :root { --band: calc(100% - 32px); --nav-h: 60px; }
  .nav-cta, .sign-steam { display: none; }
  #account { max-width: 172px; }
  .alerts, .nav-pop { right: 16px; }
  .page-title { font-size: 36px; }
  .card { padding: 24px; }
  .toast { right: 12px; bottom: 12px; max-width: calc(100vw - 24px); }
  .footer { padding: 48px 0 32px; }
  .footer-bottom { flex-direction: column; margin-top: 40px; }
  /* under 16px a phone zooms the page in on focus */
  input:not([type]), input[type=text], input[type=search], input[type=number], input[type=email], textarea { font-size: 16px; }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { transition-duration: 1ms !important; animation-duration: 1ms !important; animation-delay: 0s !important; }
}
