/*
 * Marketing site — the whole stylesheet.
 *
 * One file, no build step, no framework. It is deployed by copying it to
 * nginx, so everything it needs is either here or in tokens.css.
 *
 * Two rules govern every line below:
 *
 *  1. No raw colour, size, radius or duration. Every value is a token from
 *     tokens.css. The only literals in this file are the two breakpoints
 *     (a media query cannot read a custom property) and structural constants
 *     with no design meaning — 0, 1fr, 100%, 50%.
 *
 *     The one exception is game art, which arrives from web/art/ carrying its
 *     own colour. That is the only place on the site that is not the palette.
 *
 *  2. Mobile first. Every rule is written for a 390px phone; the two
 *     min-width blocks add what a larger viewport can afford. The audience
 *     arrives on the phone they are about to install on, often on 3G, so the
 *     phone layout is the default path and the desktop layout is the
 *     exception.
 *
 * ---------------------------------------------------------------------------
 * WHAT THIS LOOKS LIKE, AND WHY IT CHANGED
 *
 * The first version of this page was a printed spec sheet: hairlines, muted
 * surfaces, one small accent, no artwork. It was honest and it was
 * disciplined and it read as a company rather than as a casino. Nobody wants
 * to install a spec sheet.
 *
 * The register is KISMAT HOUSE — Midnight Volt (ADR-061) warmed to match the
 * client's redress, and the entire repaint was an edit to css/tokens.css:
 *
 *   - The ground is a warm four-step espresso ladder (--stage = #17110d, the
 *     chrome #0d0906), lit by two off-centre pools of gold and ember. Depth is
 *     real again: --elev-*, --glow-* and --inset-top carry values, so the rules
 *     in this file that ask for them stopped resolving to nothing.
 *   - ONE accent: the electric volt (#edff00), still spent only on things you
 *     press. GOLD is the ornament — hairlines, the bead rule under the header,
 *     the section ribbons, the marquee bulbs on the download band, and the word
 *     "money" in the headline. Gold is never a button; volt is never decoration.
 *   - The type scale keeps its top end: --text-mega for the live
 *     multiplier, --text-hero for the headline — in Inter 900 now.
 *   - Game art carries the catalogue. A tile is a picture with a name under
 *     it, not a paragraph in a box.
 *   - This is the open web, so it HAS gradients, box-shadows and keyframes and
 *     it uses all three. The Unity client cannot (docs/06-DESIGN-SYSTEM.md,
 *     "What USS actually supports"), which is why the two surfaces agree on
 *     colour and ornament and not on technique.
 *
 * What did NOT change is the arithmetic. Every house edge is still printed on
 * the tile it belongs to, the expected-loss table on Responsible play is still
 * plain, and no figure anywhere is dressed up. The page got louder about the
 * product; it did not get quieter about the odds.
 */

/* ========================================================== reset & base */

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

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  background: var(--stage);
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }
}

/* The two ambient washes are fixed to the viewport rather than painted on the
 * page, so a 6000px document does not stretch one radial gradient over its
 * whole height and lose it. They are off-centre pools of light on a dark room.
 * Deliberately not a linear two-hue gradient: that is the one gesture that
 * makes a page look machine-made. */
body {
  margin: 0;
  min-height: 100vh;
  background-color: var(--stage);
  background-image: var(--wash-accent), var(--wash-gold);
  background-repeat: no-repeat;
  background-attachment: fixed;
  background-size: 100% 720px, 100% 560px;
  color: var(--text-primary);
  font-family: var(--font-body);
  font-size: var(--text-body);
  line-height: var(--leading-normal);
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

h1,
h2,
h3,
h4 {
  font-family: var(--font-display);
  font-weight: var(--weight-display);
  line-height: var(--leading-tight);
  letter-spacing: var(--tracking-display);
  margin: 0;
  text-wrap: balance;
}

h3,
h4 {
  font-weight: var(--weight-display-sub);
}

p {
  margin: 0;
}

ul,
ol {
  margin: 0;
  padding: 0;
}

a {
  color: var(--accent);
  text-decoration-color: var(--accent-border);
  text-underline-offset: var(--space-1);
}

a:hover {
  color: var(--accent-hover);
  text-decoration-color: var(--accent-hover);
}

img,
svg {
  display: block;
  max-width: 100%;
}

/* Focus is the accent and nothing else — identical on every focusable thing
 * on the site, exactly as --focus-ring is identical across all 38 games. */
:focus-visible {
  outline: var(--border-thick) solid var(--focus-ring);
  outline-offset: var(--space-1);
  border-radius: var(--radius-sm);
}

::selection {
  background: var(--accent-subtle);
  color: var(--text-primary);
}

/* Skip link. Present on every page; the site is a distribution channel and
 * has to be operable without a mouse. */
.skip {
  position: absolute;
  left: var(--space-3);
  top: calc(var(--space-3) * -1 - var(--tap-min));
  z-index: 4;
  padding: var(--space-3) var(--space-4);
  background: var(--accent);
  color: var(--text-on-accent);
  border-radius: var(--radius-md);
  font-weight: 600;
  text-decoration: none;
  transition: top var(--dur-fast) var(--ease-out);
}

.skip:focus {
  top: var(--space-3);
}

/* ================================================================== type */

/* THE RIBBON, and it is the site's one piece of ornament.
 *
 * Every section on every page opens with an eyebrow — forty-odd of them — so
 * the eyebrow is the one element that can carry a house style across the whole
 * site from a single rule. It was volt uppercase text: correct, and identical
 * to the section label on any dark SaaS page written this year.
 *
 * It is a banner now: a shallow gold plate, a hairline top and bottom, a solid
 * gold fold at the leading edge and a swallowtail cut out of the trailing one.
 * The tail is `clip-path`, which is the whole reason this treatment lives on
 * the web side and not in the client — USS has no clip-path and no
 * pseudo-elements, so in Unity a ribbon is four elements and here it is one
 * declaration.
 *
 * GOLD, NOT VOLT. Volt is the colour of things you press; an eyebrow is not
 * pressable and never was. Moving it to gold takes the accent back to meaning
 * one thing, which is the rule the whole palette rests on. */
.eyebrow {
  display: inline-flex;
  align-items: center;
  min-height: var(--space-6);
  padding: var(--space-1) var(--space-6) var(--space-1) var(--space-4);
  font-size: var(--text-label);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--gold-pale);
  background-image: var(--ribbon-face);
  border-top: var(--border-hairline) solid var(--gold-border);
  border-bottom: var(--border-hairline) solid var(--gold-border);
  border-left: var(--border-thick) solid var(--gold);
  font-weight: 600;
  margin: 0;
  /* The swallowtail. The notch is cut INTO the trailing edge, so the plate
   * reads as a length of ribbon rather than as a pennant pointing somewhere. */
  clip-path: polygon(
    0 0,
    100% 0,
    calc(100% - var(--ribbon-notch)) 50%,
    100% 100%,
    0 100%
  );
}

/* The quieter eyebrow, for a section that is information rather than an
 * invitation — the legal pages, the tables, and the "before you deposit"
 * warning, which is the one place on this site where ornament would be in bad
 * taste. It drops the whole ribbon rather than only its colour: a gold plate
 * with grey type on it reads as a broken ribbon, not as a quiet one. */
.eyebrow--muted {
  color: var(--text-secondary);
  background-image: none;
  border-top-color: var(--transparent);
  border-bottom-color: var(--transparent);
  border-left-color: var(--border-strong);
  clip-path: none;
}

.lead {
  font-size: var(--text-lead);
  color: var(--text-secondary);
  max-width: var(--measure-tight);
}

.prose {
  max-width: var(--measure);
  color: var(--text-secondary);
}

.prose > * + * {
  margin-top: var(--space-4);
}

.prose h2 {
  font-size: var(--text-subhead);
  color: var(--text-primary);
  margin-top: var(--space-7);
}

.prose h3 {
  font-size: var(--text-heading);
  color: var(--text-primary);
  margin-top: var(--space-6);
}

.prose strong {
  color: var(--text-primary);
  font-weight: 600;
}

.prose ul,
.prose ol {
  padding-left: var(--space-5);
}

.prose li + li {
  margin-top: var(--space-2);
}

.prose code {
  font-family: var(--font-numeric);
  font-size: var(--text-label);
  background: var(--stage-deep);
  border: var(--border-hairline) solid var(--border-subtle);
  border-radius: var(--radius-sm);
  padding: 0 var(--space-1);
  color: var(--text-primary);
  word-break: break-all;
}

/* Present for a screen reader, absent for everyone else. Used on table
 * captions, where the heading above already says it out loud. */
.visually-hidden {
  position: absolute;
  width: var(--rule);
  height: var(--rule);
  padding: 0;
  margin: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

.num {
  font-family: var(--font-numeric);
  font-variant-numeric: var(--numeric);
}

/* An unfilled fact. Deliberately loud: nothing on this site should quietly
 * read as true when nobody has confirmed it.
 *
 * It wraps. Several of these are whole sentences describing what a policy has
 * to say, and a nowrap pill containing a sentence pushed the page 800px wider
 * than a 390px phone — invisible on a desktop, and on a phone it silently
 * shoved the entire layout sideways. */
.todo {
  font-family: var(--font-numeric);
  font-size: var(--text-caption);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  font-weight: 600;
  color: var(--pending);
  background: var(--pending-subtle);
  border: var(--border-hairline) solid var(--pending);
  border-radius: var(--radius-sm);
  padding: 0 var(--space-2);
  display: inline;
  max-width: 100%;
  overflow-wrap: anywhere;
  /* Each wrapped line gets its own border and padding rather than one box
   * torn across two lines. */
  -webkit-box-decoration-break: clone;
  box-decoration-break: clone;
}

.note {
  border-top: var(--border-thick) solid var(--pending);
  background: var(--panel);
  padding: var(--space-4);
  border-radius: 0 0 var(--radius-md) var(--radius-md);
  color: var(--text-secondary);
  font-size: var(--text-body);
  box-shadow: var(--shadow-card);
}

.note--info {
  border-top-color: var(--info);
}

.note > * + * {
  margin-top: var(--space-3);
}

.note strong {
  color: var(--text-primary);
}

/* A small honesty label. Used on anything on this page that LOOKS like live
 * data and is not — the wins ticker and the hero round. It is not decoration
 * and it does not get to be subtle: a visitor must never be able to mistake an
 * illustration for a feed of real players' money. */
.tag {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  padding: 0 var(--space-2);
  min-height: var(--space-5);
  border-radius: var(--radius-sm);
  font-family: var(--font-numeric);
  font-size: var(--text-caption);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  font-weight: 600;
  color: var(--text-secondary);
  background: var(--surface-wash);
  border: var(--border-hairline) solid var(--border-default);
  white-space: nowrap;
}

/* ================================================================ layout */

.wrap {
  width: 100%;
  max-width: var(--site-max);
  margin: 0 auto;
  padding-left: var(--site-gutter);
  padding-right: var(--site-gutter);
}

.section {
  padding-top: var(--space-7);
  padding-bottom: var(--space-7);
  border-top: var(--rule) solid var(--border-subtle);
  position: relative;
}

.section--flush {
  border-top: 0;
}

/* A band rather than a section — the ticker brings its own rules top and
 * bottom and does not need the full section rhythm around it as well. */
.section--band {
  padding-top: var(--space-5);
  padding-bottom: var(--space-5);
}

.section--sunken {
  background: var(--stage-deep);
  border-top-color: var(--border-default);
}

.stack > * + * {
  margin-top: var(--space-4);
}

.stack-lg > * + * {
  margin-top: var(--space-6);
}

/* The section head: a tracked label, a hairline, then the heading. This is the
 * spec-sheet motif that the whole first version was built on. It survives —
 * it is genuinely good structure — but the rule is now lit at its left end,
 * so it reads as part of a room with the lights on rather than a page in a
 * ring binder. */
.head {
  margin-bottom: var(--space-5);
}

/* GOLD, NOT VOLT. The rule sits directly under the eyebrow, which is a gold
 * ribbon now — a volt bar under a gold plate reads as two identities arguing.
 * Volt is for things you press; this is a rule. */
.head__rule {
  height: var(--border-thick);
  background: linear-gradient(
    to right,
    var(--gold) 0,
    var(--border-default) var(--space-8),
    var(--transparent) 100%
  );
  border-radius: var(--radius-pill);
  margin: var(--space-3) 0 var(--space-4);
}

.head h2,
.head h1 {
  font-size: var(--text-section);
}

.head p {
  margin-top: var(--space-3);
  color: var(--text-secondary);
  max-width: var(--measure);
}

/* ================================================================ header */

/* The reference chrome: a solid BLACK bar, flat, one hairline under it. */
.site-header {
  position: sticky;
  top: 0;
  z-index: 3;
  background: var(--surface-sunken);
  border-bottom: var(--rule) solid var(--border-subtle);
}

/* The dotted bazaar divider: dashes of lantern light with alternating gold
 * and rani beads, riding just under the header. */
.site-header::after {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  top: 100%;
  height: var(--divider-h);
  background-image: var(--bazaar-divider);
  background-size: var(--divider-sizes);
  background-position: var(--divider-pos);
  background-repeat: repeat-x;
  pointer-events: none;
}

/* One flex row that is allowed to wrap. The brand and the toggle sit on the
 * first line; the nav is the wrapped third child, full width, hidden until the
 * toggle opens it. At 1000px it stops wrapping and becomes a normal row — the
 * same DOM, no duplicate markup, no overlay to get trapped behind. */
.site-header__bar {
  min-height: var(--header-height);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
}

/* The wordmark: plain text, heavy caps, the accent — no drawn logo
 * (ADR-061). The markup still carries "Kismat" as plain text so the
 * accessible name reads naturally. */
.brand {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  color: var(--accent);
  text-decoration: none;
  font-family: var(--font-display);
  font-weight: var(--weight-display);
  font-size: var(--text-heading);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  line-height: var(--leading-tight);
}

/* The diya glyph is retired with the lantern identity; the markup keeps it
 * for now and this rule keeps it off every page at once. */
.brand__diya {
  display: none;
}

/* Nav collapses to a disclosure on the phone. One button, no overlay, no
 * scroll lock — it pushes the page down, which costs nothing and cannot trap
 * anyone behind a broken close button on a slow connection. */
.nav-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  min-height: var(--tap-min);
  min-width: var(--tap-min);
  padding: 0 var(--space-3);
  background: var(--surface-wash);
  color: var(--text-primary);
  border: var(--border-hairline) solid var(--border-default);
  border-radius: var(--radius-md);
  font: inherit;
  font-size: var(--text-label);
  font-weight: 600;
  cursor: pointer;
}

.nav-toggle:hover {
  background: var(--surface-wash-strong);
  border-color: var(--border-strong);
}

.nav-toggle svg {
  width: var(--icon-lg);
  height: var(--icon-lg);
}

.nav-toggle .nav-toggle__close,
.nav-toggle[aria-expanded='true'] .nav-toggle__open {
  display: none;
}

.nav-toggle[aria-expanded='true'] .nav-toggle__close {
  display: block;
}

.site-nav {
  display: none;
  flex-basis: 100%;
  padding-bottom: var(--space-4);
  border-top: var(--rule) solid var(--border-subtle);
}

.site-nav.is-open {
  display: block;
}

.site-nav ul {
  list-style: none;
  display: flex;
  flex-direction: column;
}

/* The plain nav links carry their own class rather than being selected as
 * `.site-nav a`. The download CTA is also an anchor inside this nav, and a
 * descendant selector would out-specify .btn and strip its padding — which is
 * exactly what it did before this class existed. */
.site-nav__link {
  display: flex;
  align-items: center;
  min-height: var(--tap-min);
  padding: var(--space-2) 0;
  color: var(--text-secondary);
  text-decoration: none;
  font-weight: 500;
  border-bottom: var(--rule) solid var(--border-subtle);
}

.site-nav__link:hover {
  color: var(--text-primary);
}

.site-nav__link[aria-current='page'] {
  color: var(--accent);
}

.site-nav .site-nav__cta {
  margin-top: var(--space-4);
  border-bottom: 0;
  /* The auth pair: the grey Log in beside the volt Sign up. */
  display: flex;
  gap: var(--space-2);
}

.site-nav .site-nav__cta .btn {
  flex: 1;
  white-space: nowrap;
}

/* ================================================================ button */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  /* Was `--tap-bet` — a token this file referenced and tokens.css never
   * defined, so the declaration was invalid at computed-value time and every
   * button on the site had no minimum height whatsoever. Nothing errored and
   * nothing looked obviously broken. HANDOFF §5.3, on the web side. */
  min-height: var(--tap-cta);
  padding: var(--space-3) var(--space-5);
  border-radius: var(--radius-md);
  border: var(--border-hairline) solid var(--transparent);
  font-family: var(--font-body-medium);
  font-size: var(--text-body);
  font-weight: 600;
  text-decoration: none;
  cursor: pointer;
  /* Geometry springs over --dur-spring; colour and shadow SETTLE. --ease-spring
   * on a background-color overshoots the value, not the position — the tint
   * leaves gamut for a frame and flickers. Same split as components.uss §1b and
   * the same two easings by the same names. */
  transition: transform var(--dur-spring) var(--ease-spring),
    box-shadow var(--dur-normal) var(--ease-settle),
    background-color var(--dur-fast) var(--ease-settle),
    border-color var(--dur-fast) var(--ease-settle);
}

.btn svg {
  width: var(--icon-lg);
  height: var(--icon-lg);
  flex: none;
}

.btn:active {
  transform: scale(var(--press-scale));
  opacity: var(--opacity-pressed);
}

/* Disabled reacts to nothing. Stated once here rather than per variant, which
 * is the same shape the client's press block takes (components.uss §1b). */
.btn:disabled,
.btn[aria-disabled='true'] {
  transform: none;
  opacity: var(--opacity-disabled);
  cursor: default;
}

/* THE ONE BUTTON THAT MATTERS, GIVEN ITS WEIGHT BACK.
 *
 * Three shadows, and each is doing a different job: the bloom says the button
 * is lit, the drop says it is standing off the page, and the inset lights its
 * top edge so the ramp underneath reads as a curved face rather than a
 * gradient. A flat yellow rectangle is a swatch; this is a control. */
.btn--primary {
  background: var(--cta-grad);
  color: var(--text-on-accent);
  box-shadow: var(--glow-accent), var(--elev-2), var(--inset-top-strong);
}

.btn--primary:hover {
  background: var(--cta-grad-hover);
  color: var(--text-on-accent);
  box-shadow: var(--glow-accent-lg), var(--elev-3), var(--inset-top-strong);
}

/* Pressed is FLAT and unlit: the face loses its ramp and the button loses the
 * drop it was standing on, so it reads as pushed into the page rather than as
 * a slightly different yellow. */
.btn--primary:active {
  background: var(--accent-pressed);
  box-shadow: var(--inset-top);
}

/* The quiet control beside the loud volt one (Log in, Download for Android in
 * the hero). It is NOT a flat grey plate any more — it carries the gold
 * hairline the rest of the page is drawn with and a real contact shadow, which
 * is the difference between "the other option" and "a disabled button". */
.btn--secondary {
  background: var(--control-secondary);
  color: var(--text-primary);
  border-color: var(--gold-border);
  box-shadow: var(--elev-1), var(--inset-top);
}

.btn--secondary:hover {
  background: var(--surface-hover);
  color: var(--text-primary);
  border-color: var(--gold);
  box-shadow: var(--elev-2), var(--inset-top-strong);
}

.btn--block {
  width: 100%;
}

/* The one unmissable button. Used once per page, on the download. It is
 * bigger than a normal button, it glows, and the second line under the label
 * answers the question a first-time visitor actually has — how big, and from
 * where — so the button does not need a paragraph next to it.
 *
 * AND IT BREATHES. One --dur-breathe cycle between the two glow tokens: the
 * only looping animation on the site, spent on the only action the site exists
 * for. USS has no @keyframes, which is why the client does this from C# and
 * this file does it in one declaration.
 *
 * `prefers-reduced-motion` is honoured explicitly below. Re-pointing the
 * duration tokens (which tokens.css does) flattens transitions but CANNOT stop
 * a keyframe animation — a loop not named in a media query keeps running.
 *
 * ONE RULE, not two. A second `.btn--cta { animation: … }` block below this one
 * would have equal specificity and be decided silently by source order, which
 * is the defect that turned Dog Racing's runner into a grey box. */
.btn--cta {
  min-height: var(--space-8);
  padding: var(--space-4) var(--space-6);
  font-size: var(--text-subhead);
  /* Buttons stay in Mukta — Rozha One is display only, never a control. */
  font-family: var(--font-body);
  font-weight: 700;
  letter-spacing: var(--tracking-display);
  border-radius: var(--radius-lg);
  gap: var(--space-3);
  animation: cta-breathe var(--dur-breathe) var(--ease-settle) infinite;
}

@media (prefers-reduced-motion: reduce) {
  .btn--cta {
    animation: none;
  }
}

.btn--cta svg {
  width: var(--icon-xl);
  height: var(--icon-xl);
}

.btn__sub {
  display: block;
  font-family: var(--font-body);
  font-size: var(--text-caption);
  font-weight: 500;
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  opacity: var(--opacity-pressed);
}

/* A quiet secondary route. Deliberately NOT a second button — the download is
 * the only call to action on this site and a competing button would dilute it. */
.textlink {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  min-height: var(--tap-min);
  font-weight: 600;
  text-decoration: none;
  border-bottom: var(--border-hairline) solid var(--accent-border);
  align-self: flex-start;
}

.textlink svg {
  width: var(--icon-md);
  height: var(--icon-md);
  transition: transform var(--dur-fast) var(--ease-out);
}

.textlink:hover svg {
  transform: translateX(var(--space-1));
}

/* ================================================================== hero */

.hero {
  padding-top: var(--space-6);
  padding-bottom: var(--space-7);
  position: relative;
}

.hero h1 {
  font-size: var(--text-hero);
  max-width: var(--measure-tight);
  letter-spacing: var(--tracking-mega);
}

.hero .lead {
  margin-top: var(--space-4);
}

.hero .eyebrow {
  margin-bottom: var(--space-3);
}

.hero__actions {
  margin-top: var(--space-6);
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: var(--space-4);
}

/* --text-secondary, not --text-muted: muted clears 4.5:1 on this surface by
 * 0.01, which is not a margin worth having on a line that tells someone their
 * phone is about to show them a security warning. */
.hero__meta {
  margin-top: var(--space-4);
  color: var(--text-secondary);
  font-size: var(--text-label);
  max-width: var(--measure-tight);
}

/* The home hero. Tighter than the others: the headline, the live round and the
 * button have to be inside the first screenful of a 390px phone, so the lead
 * paragraph is one sentence and everything else waits. */
.hero--home {
  padding-top: var(--space-5);
  padding-bottom: var(--space-6);
}

/* Everything above the live panel is compressed on purpose. On a 700px-tall
 * phone the headline, the button and the first artwork all have to be inside
 * the first screenful, and the only way to buy that room is to stop the lead
 * paragraph and the action block from breathing as much as they do elsewhere. */
.hero--home .lead {
  margin-top: var(--space-3);
}

.hero--home .hero__actions {
  margin-top: var(--space-5);
  gap: var(--space-3);
}

.hero--home .strip {
  margin-top: var(--space-4);
}

/* The meta paragraph is the last thing in the hero and the ticker band that
 * follows brings its own rule, so the hero does not also need a full section's
 * worth of air under it. */
.hero--home .hero__meta {
  margin-top: var(--space-4);
  margin-bottom: calc(var(--space-4) * -1);
}

.hero--home h1 {
  max-width: none;
}

/* The money phrase in the headline — "Real money." — in the money colour,
 * glowing. This is the only place on the site where display type is coloured,
 * and it is the one non-figure phrase gold is allowed on because it literally
 * names money. */
.hero em {
  font-style: normal;
  color: var(--gold);
  text-shadow: var(--glow-ink-gold);
}

/* ========================================================== live round == */

/* The showpiece. A Crash round that actually runs: the multiplier climbs, the
 * curve draws under it, and at a point fixed before the animation started it
 * stops and goes red. It is the product's central mechanic, shown rather than
 * described, and it is the reason a visitor understands this page in two
 * seconds instead of reading four paragraphs.
 *
 * It is labelled ILLUSTRATIVE, twice, because it is not a feed. */
.live {
  margin-top: var(--space-5);
  position: relative;
  overflow: hidden;
  border: var(--border-hairline) solid var(--accent-border);
  border-radius: var(--radius-lg);
  background-color: var(--felt);
  background-image: var(--wash-tile), var(--wash-felt);
  box-shadow: var(--shadow-panel), var(--inset-top);
  padding: var(--space-4) var(--space-4) 0;
}

.live__head {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex-wrap: wrap;
}

.live__label {
  font-size: var(--text-caption);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  font-weight: 600;
  color: var(--text-on-felt);
  margin-right: auto;
}

/* The pulse. Small, and the only thing on the page that moves on its own
 * without being asked to. */
.live__dot {
  width: var(--space-2);
  height: var(--space-2);
  border-radius: var(--radius-pill);
  background: var(--live);
  box-shadow: 0 0 0 0 var(--win-subtle);
  flex: none;
  animation: pulse var(--dur-live) var(--ease-out) infinite;
}

@keyframes pulse {
  0% {
    box-shadow: 0 0 0 0 var(--win-subtle);
  }
  70% {
    box-shadow: 0 0 0 var(--space-3) var(--transparent);
  }
  100% {
    box-shadow: 0 0 0 0 var(--transparent);
  }
}

/* The number. This is --text-mega and nothing else on the site uses it. */
.live__mult {
  font-family: var(--font-numeric);
  font-variant-numeric: var(--numeric);
  font-size: var(--text-mega);
  font-weight: 600;
  line-height: 1;
  letter-spacing: var(--tracking-mega);
  color: var(--accent);
  text-shadow: var(--glow-ink-accent);
  margin: var(--space-2) 0 0;
  transition: color var(--dur-fast) var(--ease-out);
}

.live__mult .live__x {
  font-size: 0.44em;
  letter-spacing: 0;
  opacity: var(--opacity-pressed);
}

/* The crash. The number turns to the loss colour and the caption underneath
 * swaps — the same two-state treatment the game screen uses. */
.live.is-bust .live__mult {
  color: var(--loss);
  text-shadow: none;
}

.live.is-bust .live__curve {
  stroke: var(--loss);
}

.live.is-bust .live__area {
  fill: var(--loss-subtle);
}

.live.is-bust .live__dot {
  background: var(--loss);
  animation: none;
}

.live__state {
  margin-top: var(--space-1);
  font-size: var(--text-label);
  font-weight: 600;
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--text-on-felt-dim);
  min-height: var(--space-5);
}

.live.is-bust .live__state {
  color: var(--loss);
}

.live__plot {
  width: 100%;
  height: var(--hero-plot-h);
  margin-top: var(--space-3);
  display: block;
}

.live__grid {
  stroke: var(--border-subtle);
  stroke-width: var(--border-hairline);
  fill: none;
}

.live__curve {
  fill: none;
  stroke: var(--accent);
  stroke-width: var(--border-thick);
  stroke-linecap: round;
  stroke-linejoin: round;
}

.live__area {
  fill: var(--accent-subtle);
  stroke: none;
}

.live__nose {
  fill: var(--accent);
}

.live.is-bust .live__nose {
  fill: var(--loss);
}

.live__foot {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: var(--space-2);
  padding: var(--space-3) 0;
  margin-top: var(--space-1);
  border-top: var(--rule) solid var(--border-subtle);
  font-size: var(--text-caption);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--text-on-felt-dim);
}

/* ============================================================ art strip = */

/* A row of game art that runs off the right edge of the phone. The overflow is
 * the point: it says "there are more of these" without a word, and it puts
 * artwork on screen inside the first viewport, which is the single thing the
 * old page never did.
 *
 * It is full-bleed on the phone — negative margins to the gutter — so the
 * first tile lines up with the text and the last one is cut by the screen edge
 * rather than by a container. */
.strip {
  margin-top: var(--space-5);
}

.strip__label {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-3);
  font-size: var(--text-caption);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  font-weight: 600;
  color: var(--text-secondary);
  margin-bottom: var(--space-3);
}

.strip__rail {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: var(--art-hero-min);
  gap: var(--space-3);
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x proximity;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  margin-left: calc(var(--site-gutter) * -1);
  margin-right: calc(var(--site-gutter) * -1);
  padding: var(--space-1) var(--site-gutter);
}

.strip__rail::-webkit-scrollbar {
  display: none;
}

.strip__rail > * {
  scroll-snap-align: start;
}

/* ============================================================== fact row */

.facts {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(var(--fact-min), 1fr));
  gap: var(--space-5);
}

.fact dt {
  font-size: var(--text-label);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--text-secondary);
  font-weight: 600;
}

/* The figures are gold, because gold is the money colour on this page and
 * every one of these is a number about money, a count or an age. */
.fact dd {
  margin: var(--space-2) 0 0;
  font-family: var(--font-numeric);
  font-variant-numeric: var(--numeric);
  font-size: var(--text-numeral);
  font-weight: 600;
  line-height: var(--leading-tight);
  color: var(--gold);
  letter-spacing: var(--tracking-mega);
}

.fact p {
  margin-top: var(--space-2);
  color: var(--text-secondary);
  font-size: var(--text-label);
}

/* ================================================================== card */

.card {
  background-color: var(--panel);
  background-image: var(--wash-tile);
  border: var(--border-hairline) solid var(--border-subtle);
  border-radius: var(--radius-lg);
  padding: var(--space-5);
  box-shadow: var(--shadow-card), var(--inset-top);
}

.card > * + * {
  margin-top: var(--space-3);
}

.card h3 {
  font-size: var(--text-heading);
}

.card p {
  color: var(--text-secondary);
}

.grid {
  display: grid;
  gap: var(--space-4);
  grid-template-columns: repeat(auto-fit, minmax(min(var(--tile-min), 100%), 1fr));
}

.grid--steps {
  grid-template-columns: repeat(auto-fit, minmax(min(var(--step-min), 100%), 1fr));
}

/* ============================================================= game tile */

/* THE CATALOGUE IS THE MARKETING.
 *
 * A tile is a picture with a name under it. The picture is the whole top of
 * the tile at a fixed 4:3, it is the largest thing in the component, and it
 * comes from web/art/ — the one part of this page whose colour the design
 * system does not own.
 *
 * The art is loaded as <img src="/art/games/<slug>.svg">, not as a <use> into
 * the sprite, for three reasons that all matter to the actual audience:
 *   - nginx sends `default-src 'none'; img-src 'self' data:`. An <img> is
 *     unambiguously allowed by img-src. An external <use> reference is not
 *     covered by any directive and its handling is not consistent.
 *   - a per-file <img> can be loading="lazy", so a 390px phone on 3G fetches
 *     the four tiles it can see and not the other sixteen.
 *   - each file caches and revalidates on its own; one sprite invalidates
 *     every tile whenever any single game's art is redrawn.
 * The sprite at web/art/games.svg remains the right choice for anything that
 * needs to recolour the art with currentColor. This page does not.
 *
 * If the art has not landed yet the <img> resolves to nothing and the frame it
 * sits in still reads as a deliberate panel rather than a hole, because the
 * frame carries its own ground and inner light. */
.tile {
  display: flex;
  flex-direction: column;
  position: relative;
  background-color: var(--felt);
  background-image: var(--wash-tile);
  border: var(--border-hairline) solid var(--border-default);
  border-radius: var(--radius-lg);
  overflow: hidden;
  text-decoration: none;
  color: inherit;
  box-shadow: var(--shadow-card), var(--inset-top);
  transition: transform var(--dur-normal) var(--ease-spring),
    box-shadow var(--dur-normal) var(--ease-out),
    border-color var(--dur-fast) var(--ease-out);
}

a.tile:hover,
a.tile:focus-visible {
  color: inherit;
  transform: translateY(var(--lift-tile));
  border-color: var(--accent-border);
  box-shadow: var(--shadow-card-hover), var(--glow-accent), var(--inset-top-strong);
}

.tile__art {
  display: block;
  position: relative;
  aspect-ratio: var(--art-ratio);
  background-color: var(--felt-deep);
  background-image: radial-gradient(
    80% 70% at 50% 28%,
    var(--felt-raised) 0%,
    var(--felt-deep) 78%
  );
  border-bottom: var(--rule) solid var(--border-subtle);
  overflow: hidden;
}

.tile__art img,
.tile__art svg {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform var(--dur-slow) var(--ease-out);
}

a.tile:hover .tile__art img,
a.tile:hover .tile__art svg {
  transform: scale(1.04);
}

/* A catalogue game whose key art has not been drawn yet.
 *
 * This is the SAME designed ground the live lobby already gives an art-less
 * game (lobby.css `.g-tile__art--fallback`), down to the hue: lobby.js hashes
 * the slug into 0-359, and because this page is static the resulting number is
 * written into the markup rather than computed. Deliberately not a stand-in
 * illustration borrowed from another game -- a tile that shows you a roulette
 * wheel for a game that is not roulette is a small lie, and this page's whole
 * argument is that it does not tell them. */
.tile__art--letter {
  display: grid;
  place-items: center;
  background-color: hsl(var(--tile-hue, 0) var(--fallback-sat) var(--fallback-l-lo));
  background-image: radial-gradient(
    120% 120% at 50% 0%,
    hsl(var(--tile-hue, 0) var(--fallback-sat) var(--fallback-l-hi)) 0%,
    hsl(var(--tile-hue, 0) var(--fallback-sat) var(--fallback-l-mid)) 55%,
    hsl(var(--tile-hue, 0) var(--fallback-sat) var(--fallback-l-lo)) 100%
  );
}

.tile__letter {
  font-family: var(--font-display);
  font-size: var(--text-numeral);
  font-weight: var(--weight-display);
  line-height: 1;
  color: hsl(var(--tile-hue, 0) var(--fallback-ink-sat) var(--fallback-ink-l));
  opacity: var(--letter-alpha);
}

/* The kind badge rides on the art rather than taking a line of its own —
 * eighteen tiles on a phone cannot each afford a third line. */
.tile__kind {
  position: absolute;
  left: var(--space-2);
  top: var(--space-2);
  padding: 0 var(--space-2);
  border-radius: var(--radius-sm);
  background: var(--surface-scrim);
  backdrop-filter: blur(var(--blur-header));
  -webkit-backdrop-filter: blur(var(--blur-header));
  border: var(--border-hairline) solid var(--border-subtle);
  font-size: var(--text-caption);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  font-weight: 600;
  color: var(--text-secondary);
  line-height: var(--space-5);
}

.tile__body {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  padding: var(--space-3);
  flex: 1;
}

.tile__name {
  font-family: var(--font-display);
  font-weight: var(--weight-display-sub);
  font-size: var(--text-body);
  line-height: var(--leading-tight);
  letter-spacing: var(--tracking-display);
  color: var(--text-primary);
}

/* A game's house edge is a fact about it, so it is printed on the tile rather
 * than buried in a footnote. It stayed when everything else got louder. */
.tile__edge {
  font-family: var(--font-numeric);
  font-variant-numeric: var(--numeric);
  font-size: var(--text-caption);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  font-weight: 600;
  color: var(--text-on-felt-dim);
  margin-top: auto;
}

.tile__edge b {
  color: var(--gold);
  font-weight: 600;
}

/* The catalogue tile on games.html, which has room for the sentence that says
 * what the game actually is. */
.tile--detail .tile__body {
  gap: var(--space-2);
  padding: var(--space-4);
}

.tile--detail .tile__name {
  font-size: var(--text-heading);
}

.tile__desc {
  color: var(--text-on-felt);
  font-size: var(--text-label);
  margin: 0;
}

.tile--detail .tile__edge {
  padding-top: var(--space-3);
  border-top: var(--rule) solid var(--border-subtle);
}

/* The art grid. Two columns on the smallest phone we support, and it grows by
 * itself — no rule anywhere in this file names a column count. */
.grid--art {
  display: grid;
  gap: var(--space-3);
  grid-template-columns: repeat(auto-fill, minmax(min(var(--art-min), 100%), 1fr));
}

.grid--catalogue {
  display: grid;
  gap: var(--space-4);
  grid-template-columns: repeat(auto-fill, minmax(min(var(--tile-min), 100%), 1fr));
}

/* =============================================================== ticker = */

/* The wins ticker.
 *
 * READ THIS BEFORE CHANGING IT. These rows are WRITTEN INTO THE HTML as fixed
 * example values and they are labelled, in visible text, as illustrative. They
 * are not a feed, they are not sampled from the ledger, and no number here is
 * presented as a real person's money. A casino page that fakes a live win feed
 * is lying to the exact people this product is asking to trust its RNG, and
 * this one does not.
 *
 * What it IS: an honest demonstration of the shape of a result — game, stake,
 * multiplier, return — so a visitor can see what winning looks like here
 * before installing anything. */
.ticker {
  position: relative;
  overflow: hidden;
  border-top: var(--rule) solid var(--border-subtle);
  border-bottom: var(--rule) solid var(--border-subtle);
  background: var(--stage-deep);
  padding: var(--space-3) 0;
  /* Both edges fade out, so the row reads as a band passing through the page
   * rather than a list that has been cut off. */
  -webkit-mask-image: linear-gradient(
    to right,
    var(--transparent),
    var(--text-primary) var(--space-8),
    var(--text-primary) calc(100% - var(--space-8)),
    var(--transparent)
  );
  mask-image: linear-gradient(
    to right,
    var(--transparent),
    var(--text-primary) var(--space-8),
    var(--text-primary) calc(100% - var(--space-8)),
    var(--transparent)
  );
}

.ticker__rail {
  display: flex;
  width: max-content;
  gap: var(--space-3);
  animation: marquee var(--dur-marquee) linear infinite;
}

.ticker:hover .ticker__rail {
  animation-play-state: paused;
}

/* Two identical copies sit in the rail and it translates by exactly half its
 * own width, so the seam never appears. The second copy is aria-hidden in the
 * markup — a screen reader reads the list once. */
@keyframes marquee {
  from {
    transform: translateX(0);
  }
  to {
    transform: translateX(-50%);
  }
}

.win {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex: none;
  padding: var(--space-2) var(--space-4);
  border-radius: var(--radius-pill);
  background: var(--panel);
  border: var(--border-hairline) dashed var(--border-default);
  white-space: nowrap;
  font-size: var(--text-label);
}

.win__who {
  color: var(--text-secondary);
  font-weight: 500;
}

.win__game {
  color: var(--text-muted);
}

.win__mult {
  font-family: var(--font-numeric);
  font-variant-numeric: var(--numeric);
  font-weight: 600;
  color: var(--accent);
}

.win__amt {
  font-family: var(--font-numeric);
  font-variant-numeric: var(--numeric);
  font-weight: 600;
  color: var(--gold);
}

/* A big multiplier gets the hot colour. Same ramp as the client's multiplier
 * heat, used here for the same reason: magnitude should read before value. */
.win--big .win__mult {
  color: var(--gold);
}

.win--huge .win__mult {
  color: var(--ember);
}

.ticker__note {
  margin-top: var(--space-3);
  font-size: var(--text-caption);
  color: var(--text-muted);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex-wrap: wrap;
}

@media (prefers-reduced-motion: reduce) {
  .ticker__rail {
    animation: none;
  }

  .ticker {
    overflow-x: auto;
  }

  .live__dot {
    animation: none;
  }
}

/* A trailing link under a grid or a list. Named rather than set with an
 * inline style attribute: nginx sends `style-src 'self'` with no
 * 'unsafe-inline', so a style="" attribute on this site is not applied at all
 * in production while looking perfectly fine on a local file:// preview. */
.more {
  margin-top: var(--space-5);
}

/* =============================================================== ordered */

.steps {
  list-style: none;
  counter-reset: step;
}

.steps > li {
  counter-increment: step;
  padding: var(--space-5) 0;
  border-top: var(--rule) solid var(--border-default);
  display: grid;
  gap: var(--space-3);
}

.steps > li::before {
  content: counter(step, decimal-leading-zero);
  font-family: var(--font-numeric);
  font-variant-numeric: var(--numeric);
  font-size: var(--text-figure);
  font-weight: 600;
  color: var(--accent);
  text-shadow: var(--glow-ink-accent);
  letter-spacing: var(--tracking-mega);
  line-height: 1;
}

/* The text column of a step. The <li> grid gaps the number away from the
 * text; this gaps the heading away from its first paragraph, which otherwise
 * sat flush against it because the two are siblings inside one child. */
.steps > li > div {
  display: grid;
  gap: var(--space-3);
  align-content: start;
}

.steps h3 {
  font-size: var(--text-subhead);
}

.steps p {
  color: var(--text-secondary);
  max-width: var(--measure);
}

.steps p + p {
  margin-top: var(--space-3);
}

/* ================================================================= table */

.table-wrap {
  overflow-x: auto;
  border: var(--border-hairline) solid var(--border-subtle);
  border-radius: var(--radius-md);
  background: var(--panel);
  box-shadow: var(--shadow-card);
}

table {
  border-collapse: collapse;
  width: 100%;
  font-size: var(--text-label);
}

/* Tight horizontal padding by default so a four-column table fits inside a
 * 390px phone without scrolling. It grows at 720px, where there is room. */
th,
td {
  text-align: left;
  padding: var(--space-3) var(--space-2);
  border-bottom: var(--rule) solid var(--border-subtle);
  white-space: nowrap;
  vertical-align: top;
}

/* Headers wrap, cells do not. The headers are the widest thing in every table
 * on this site ("Expected loss per hour"), and letting them wrap is what keeps
 * the column that actually matters on screen instead of behind a scroll. */
th {
  font-size: var(--text-caption);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--text-secondary);
  font-weight: 600;
  white-space: normal;
}

td {
  color: var(--text-primary);
}

td.is-num {
  font-family: var(--font-numeric);
  font-variant-numeric: var(--numeric);
}

tr:last-child td {
  border-bottom: 0;
}

/* ============================================================== release */

/* The download facts. A checksum is only useful if it can be read and copied
 * without error, so it gets its own well, wraps on any character, and carries
 * a copy button that falls back to plain selectable text without JS. */
.release {
  background-color: var(--panel);
  background-image: var(--wash-tile);
  border: var(--border-hairline) solid var(--border-default);
  border-radius: var(--radius-lg);
  padding: var(--space-5);
  box-shadow: var(--shadow-card), var(--inset-top);
}

.release dl {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-4);
  margin: 0;
}

.release dt {
  font-size: var(--text-caption);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--text-secondary);
  font-weight: 600;
}

.release dd {
  margin: var(--space-1) 0 0;
  font-family: var(--font-numeric);
  font-variant-numeric: var(--numeric);
  font-size: var(--text-heading);
  color: var(--text-primary);
}

/* The secondary half of a release fact — the versionCode beside the version,
 * the exact byte count beside the human size. Both are the number a machine
 * checks, so they are printed rather than rounded away, but they are not the
 * number a reader scans for. */
.release__vc {
  font-size: var(--text-label);
  color: var(--text-secondary);
  font-weight: 400;
}

/* The download URL under the button, so it can be read before it is clicked
 * and typed on a second device. */
.hero__url {
  font-family: var(--font-numeric);
  font-size: var(--text-label);
  color: var(--text-secondary);
  word-break: break-all;
}

.checksum {
  margin-top: var(--space-5);
}

.checksum__value {
  display: block;
  margin-top: var(--space-2);
  padding: var(--space-3);
  background: var(--stage-deep);
  border: var(--border-hairline) solid var(--border-subtle);
  border-radius: var(--radius-md);
  font-family: var(--font-numeric);
  font-variant-numeric: var(--numeric);
  font-size: var(--text-label);
  color: var(--text-primary);
  word-break: break-all;
  line-height: var(--leading-normal);
}

.copy {
  margin-top: var(--space-3);
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  min-height: var(--tap-min);
  padding: 0 var(--space-4);
  background: var(--surface-wash);
  color: var(--text-primary);
  border: var(--border-hairline) solid var(--border-default);
  border-radius: var(--radius-md);
  font: inherit;
  font-size: var(--text-label);
  font-weight: 600;
  cursor: pointer;
}

.copy:hover {
  background: var(--surface-wash-strong);
  border-color: var(--border-strong);
}

.copy svg {
  width: var(--icon-md);
  height: var(--icon-md);
}

.copy[data-copied='true'] {
  color: var(--accent);
  border-color: var(--accent-border);
}

pre.cmd {
  margin: var(--space-3) 0 0;
  padding: var(--space-3) var(--space-4);
  background: var(--stage-deep);
  border: var(--border-hairline) solid var(--border-subtle);
  border-radius: var(--radius-md);
  overflow-x: auto;
  font-family: var(--font-numeric);
  font-size: var(--text-label);
  color: var(--text-primary);
}

/* ============================================================== closer == */

/* The last block on every page: one line, one button. A visitor who has read
 * to the bottom should not have to scroll back up to find the download. */
/* THE DOWNLOAD BAND, WITH A LIT RAIL ALONG THE TOP OF IT.
 *
 * --bulb-strip is a run of gold bulbs on a repeat, and it has been in
 * tokens.css painting nothing since the flat repaint. It belongs here: this is
 * the last thing on the page and the only card whose whole job is one button,
 * so it is the one surface allowed to be theatrical. `position: relative` for
 * the rail; `overflow: hidden` so the rail follows the card's own radius
 * instead of squaring its top corners. */
.closer {
  position: relative;
  overflow: hidden;
  text-align: center;
  background-color: var(--panel);
  background-image: var(--wash-tile);
  border: var(--border-hairline) solid var(--gold-border);
  border-radius: var(--radius-xl);
  padding: var(--space-6) var(--space-5);
  box-shadow: var(--shadow-panel), var(--inset-top), var(--glow-gold);
  display: grid;
  justify-items: center;
  gap: var(--space-4);
}

.closer::before {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  height: var(--bulb-h);
  background-image: var(--bulb-strip);
  background-size: var(--bulb-tile) var(--bulb-h);
  background-repeat: repeat-x;
  pointer-events: none;
}

.closer h2 {
  font-size: var(--text-section);
  max-width: var(--measure-tight);
}

.closer p {
  color: var(--text-secondary);
  max-width: var(--measure-tight);
}

/* ================================================================ footer */

/* The footer takes the SAME bead rule the header carries, on its top edge —
 * so the page is bracketed by the ornament rather than wearing it once and
 * forgetting. One token (--bazaar-divider), two ends, no duplicated values. */
.site-footer {
  border-top: var(--rule) solid var(--border-default);
  background: var(--stage-deep);
  padding-top: var(--space-7);
  padding-bottom: var(--space-7);
  margin-top: var(--space-7);
  position: relative;
}

.site-footer::before {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  bottom: 100%;
  height: var(--divider-h);
  background-image: var(--bazaar-divider);
  background-size: var(--divider-sizes);
  background-position: var(--divider-pos);
  background-repeat: repeat-x;
  pointer-events: none;
}

/* The trust band across the top of every footer: the 18+ mark, the
 * provably-fair line, and the drawn payment chips (never third-party
 * logos). Same shape as the lobby footer's strip. */
.site-footer__trust {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-3) var(--space-4);
  padding-bottom: var(--space-5);
  margin-bottom: var(--space-6);
  border-bottom: var(--rule) solid var(--border-subtle);
  color: var(--text-secondary);
  font-size: var(--text-label);
}

.site-footer__trust strong {
  color: var(--text-primary);
}

.site-footer__marks {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  margin-left: auto;
}

.paychip {
  display: inline-flex;
  align-items: center;
  padding: var(--space-1) var(--space-2);
  border: var(--rule) solid var(--border-default);
  border-radius: var(--radius-sm);
  font-size: var(--text-caption);
  font-weight: 700;
  letter-spacing: var(--tracking-label);
  color: var(--text-secondary);
}

.site-footer__cols {
  display: grid;
  gap: var(--space-6);
  grid-template-columns: repeat(auto-fit, minmax(min(var(--fact-min), 100%), 1fr));
}

.site-footer h2 {
  font-family: var(--font-body-medium);
  font-size: var(--text-caption);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--text-secondary);
  font-weight: 600;
  margin-bottom: var(--space-3);
}

.site-footer ul {
  list-style: none;
}

.site-footer li + li {
  margin-top: var(--space-1);
}

/* Only the column links get the 44px target treatment. Scoped to `li a`
 * rather than `.site-footer a`, because the legal paragraph below also
 * contains links, and turning an inline link inside a sentence into a 44px
 * flex box tears a hole in the line it sits in. */
.site-footer li a {
  display: inline-flex;
  align-items: center;
  min-height: var(--tap-min);
  color: var(--text-secondary);
  text-decoration: none;
}

.site-footer li a:hover {
  color: var(--text-primary);
}

.site-footer__legal {
  margin-top: var(--space-6);
  padding-top: var(--space-5);
  border-top: var(--rule) solid var(--border-subtle);
  color: var(--text-muted);
  font-size: var(--text-label);
  display: grid;
  gap: var(--space-3);
}

/* The 18+ mark. Not decoration — it is the one thing on this page that has to
 * be visible on every single view. */
.age {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: var(--tap-min);
  min-height: var(--tap-min);
  border: var(--border-thick) solid var(--loss);
  color: var(--loss);
  border-radius: var(--radius-pill);
  font-family: var(--font-numeric);
  font-variant-numeric: var(--numeric);
  font-weight: 600;
  font-size: var(--text-label);
  flex: none;
}

/* Two flex children and no bare text nodes: the badge, and one span holding
 * the whole sentence. A bare text node beside an inline link would become two
 * separate anonymous flex items and the sentence would lay out in columns. */
.age-line {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  color: var(--text-secondary);
}

/* ============================================================ 720px + == */

@media (min-width: 720px) {
  .section {
    padding-top: var(--space-8);
    padding-bottom: var(--space-8);
  }

  .hero__actions {
    flex-direction: row;
    align-items: center;
    flex-wrap: wrap;
  }

  .btn--block {
    width: auto;
  }

  .release dl {
    grid-template-columns: repeat(auto-fit, minmax(min(var(--fact-min), 100%), 1fr));
  }

  th,
  td {
    padding: var(--space-3) var(--space-4);
  }

  .steps > li {
    grid-template-columns: auto 1fr;
    column-gap: var(--space-5);
  }

  .live {
    padding: var(--space-5) var(--space-5) 0;
  }

  .closer {
    padding: var(--space-8) var(--space-6);
  }
}

/* =========================================================== 1000px + == */

@media (min-width: 1000px) {
  /* The nav stops collapsing. The toggle is removed from the accessibility
   * tree as well as from view, so a keyboard user is never sent to a control
   * that does nothing. */
  .nav-toggle {
    display: none;
  }

  .site-nav {
    display: block;
    flex-basis: auto;
    margin-left: auto;
    border-top: 0;
    padding-bottom: 0;
  }

  .site-nav ul {
    flex-direction: row;
    align-items: center;
    gap: var(--space-5);
  }

  .site-nav__link {
    min-height: var(--header-height);
    border-bottom: 0;
    font-size: var(--text-label);
  }

  .site-nav .site-nav__cta {
    margin-top: 0;
  }

  /* In the header the CTA drops to the standard 44px target. --tap-cta is
   * sized for the one button the whole site is pointing at; a nav button is
   * pressed once, and at 56px it fills the entire 58px bar. */
  .site-nav__cta .btn {
    min-height: var(--tap-min);
    padding: var(--space-2) var(--space-4);
    font-size: var(--text-label);
  }

  .site-header__bar {
    gap: var(--space-6);
  }

  /* The hero splits: copy left, the live round right, sharing one baseline. */
  .hero__split {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--space-7);
    align-items: center;
  }

  .live {
    margin-top: 0;
  }

  /* The strip stops being a scroller and becomes a row, because at this width
   * the whole row fits and a horizontal scrollbar on a desktop is a nuisance
   * rather than an affordance. */
  .strip__rail {
    grid-auto-flow: unset;
    grid-template-columns: repeat(auto-fit, minmax(min(var(--art-hero-min), 100%), 1fr));
    overflow-x: visible;
    margin-left: 0;
    margin-right: 0;
    padding-left: 0;
    padding-right: 0;
  }
}
