/* ============================================================================
   PADEL RALLY — kit.css
   Design system + app-UI mockup kit, retained from the previous experiment
   (rally.css) and pruned to what the cinematic take uses. The stage itself
   lives in take.css. No build step, no dependencies.
   ========================================================================== */
/* ── 1. TOKENS ───────────────────────────────────────────────────────────── */
:root {
  /* Colour — greens sampled directly from assets/brand/padel-rally-logo-master.png */
  --ink:        #000000;   /* page base; matches the logo artwork's own black exactly */
  --ink-02:     #080a07;
  --surface:    #0d0f0c;
  --surface-hi: #15180f;
  --line:       #23271e;
  --line-hi:    #363c2e;

  --chalk:      #ffffff;
  --chalk-mid:  rgba(255,255,255,.72);
  --chalk-low:  rgba(255,255,255,.58);
  --chalk-dim:  rgba(255,255,255,.50);   /* 5.3:1 on --ink; safe for small text */

  --volt:       #32ff28;   /* electric padel green */
  --ball:       #d4fd0d;   /* tennis-ball yellow-green */
  --volt-line:  rgba(50,255,40,.32);
  --on-volt:    #000000;

  /* Type */
  --f-display: 'Archivo', 'Helvetica Neue', Arial, sans-serif;
  --f-body:    'Archivo', 'Helvetica Neue', Arial, sans-serif;
  --f-data:    'Martian Mono', ui-monospace, 'SF Mono', Menlo, monospace;

  --t-hero:  clamp(2.9rem, 8.6vw, 7.6rem);
  --t-d1:    clamp(2.05rem, 4.6vw, 3.9rem);
  --t-d2:    clamp(1.65rem, 3.4vw, 2.6rem);
  --t-d3:    clamp(1.2rem, 2.1vw, 1.75rem);
  --t-lead:  clamp(1.0625rem, 1.35vw, 1.3rem);
  --t-body:  1.0625rem;
  --t-sm:    .9375rem;
  --t-label: .6875rem;
  --t-micro: .625rem;

  /* Space — 8px base */
  --s2: 1rem;  --s3: 1.5rem; --s4: 2rem;  --s5: 2.5rem;
  --s6: 3rem;  --s8: 4rem;   --s10: 5rem;
  --band: clamp(4.5rem, 10.5vh, 9rem);   /* section vertical rhythm */

  /* Structure. Radius is meaningful here: square = page, rounded = app UI. */
  --r-sm: 6px; --r-md: 12px; --r-lg: 18px; --r-phone: 42px;
  --wrap:  min(100% - 2.5rem, 1280px);
  --wrap-wide: min(100% - 2.5rem, 1560px);

  /* Motion */
  --head: 4.25rem;                       /* fixed masthead height; the rig pins below it */

  /* Device scale inside a pinned rig. It must be a unitless number — scale()
     rejects a length, and one invalid token voids the whole transform. Steps
     rather than a fluid calc for exactly that reason. */
  --ds: 1;

  --e-out: cubic-bezier(.16, 1, .3, 1);
  --e-soft: cubic-bezier(.4, 0, .2, 1);
  --d-micro: 180ms;
  --d-reveal: 620ms;
}

/* ── 2. RESET & BASE ─────────────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-padding-top: 5.5rem;
}

body {
  background: var(--ink);
  color: var(--chalk);
  font-family: var(--f-body);
  font-size: var(--t-body);
  font-weight: 400;
  line-height: 1.6;
  font-synthesis-weight: none;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

/* `overflow-x: hidden` here would make <body> a scroll container, which is what
   silently breaks `position: sticky` for its descendants. `clip` contains the
   same overflow without creating one, so the rig can pin. */
html { overflow-x: clip; }
@supports not (overflow: clip) { body { overflow-x: hidden; } }

img, svg, picture { display: block; max-width: 100%; }
img { height: auto; }
button, input, select { font: inherit; color: inherit; }
ul, ol { list-style: none; padding: 0; }

a { color: inherit; text-decoration: none; }
a:not([class]) {
  text-decoration: underline;
  text-underline-offset: .22em;
  text-decoration-color: var(--volt-line);
  transition: text-decoration-color var(--d-micro) var(--e-soft);
}
a:not([class]):hover { text-decoration-color: var(--volt); }

:focus-visible {
  outline: 2px solid var(--volt);
  outline-offset: 3px;
  border-radius: 2px;
}

::selection { background: var(--volt); color: var(--on-volt); }

.visually-hidden {
  position: absolute; width: 1px; height: 1px;
  margin: -1px; padding: 0; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap; border: 0;
}

.skip-link {
  position: absolute; top: 0; left: 50%;
  transform: translate(-50%, -110%);
  z-index: 200;
  background: var(--volt); color: var(--on-volt);
  padding: .7rem 1.4rem;
  font: 700 var(--t-label)/1 var(--f-data);
  letter-spacing: .1em; text-transform: uppercase;
}
.skip-link:focus-visible { transform: translate(-50%, 0); }

/* ── 3. LAYOUT PRIMITIVES ────────────────────────────────────────────────── */
.wrap        { width: var(--wrap); margin-inline: auto; }
.wrap--wide  { width: var(--wrap-wide); margin-inline: auto; }

.band { padding-block: var(--band); position: relative; }
.band--tight { padding-block: calc(var(--band) * .55); }
.band--rule  { border-top: 1px solid var(--line); }
.band--alt   { background: var(--ink-02); }

.grid { display: grid; gap: var(--s6); }
@media (min-width: 900px) {
  .grid--split   { grid-template-columns: minmax(0,1fr) minmax(0,1fr); gap: var(--s10); align-items: center; }
  .grid--7-5     { grid-template-columns: minmax(0,7fr) minmax(0,5fr); gap: var(--s10); align-items: center; }
  .grid--4-8     { grid-template-columns: minmax(0,4fr) minmax(0,8fr); gap: var(--s10); align-items: start; }
}

.stack        { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--s3); }
/* ── 4. TYPE PRIMITIVES ──────────────────────────────────────────────────── */
.eyebrow {
  display: inline-flex; align-items: center; gap: .6rem;
  font-family: var(--f-data);
  font-size: var(--t-label);
  font-weight: 600;
  font-stretch: 88%;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--chalk-low);
}
.eyebrow::before {
  content: ''; width: 6px; height: 6px; flex: none;
  background: var(--volt);
}

.display, h1, h2, h3 {
  font-family: var(--f-display);
  font-weight: 800;
  font-stretch: 118%;
  line-height: .92;
  letter-spacing: -.022em;
  text-transform: uppercase;
  text-wrap: balance;
}
/* Headings that set their own line breaks must not be re-balanced — but those
   breaks are chosen for wide viewports, so phones get balancing back. */
.brk { text-wrap: initial; }
@media (max-width: 719px) { .brk { text-wrap: balance; } }
.d-hero { font-size: var(--t-hero); font-weight: 900; letter-spacing: -.035em; }
.d1     { font-size: var(--t-d1); }
.d2     { font-size: var(--t-d2); }
.d3     { font-size: var(--t-d3); line-height: 1.04; letter-spacing: -.012em; }

/* Statement voice: sentence case, medium weight. The counterpoint to the
   uppercase display voice — used for the emotional payoff line in a section. */
.claim {
  font-size: var(--t-d3);
  font-weight: 500;
  line-height: 1.18;
  letter-spacing: -.012em;
  text-wrap: balance;
}

.lede {
  font-size: var(--t-lead);
  line-height: 1.5;
  color: var(--chalk-mid);
  max-width: 44ch;
  text-wrap: pretty;
}
.prose { color: var(--chalk-mid); max-width: 56ch; text-wrap: pretty; }
.prose strong { color: var(--chalk); font-weight: 600; }

.volt { color: var(--volt); }

.data {
  font-family: var(--f-data);
  font-size: var(--t-label);
  font-stretch: 85%;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--chalk-low);
}
/* Caption voice: the mono face at sentence-case, for asides and small print. */
.note {
  font-family: var(--f-data);
  font-size: .8125rem;
  font-stretch: 100%;
  letter-spacing: .01em;
  line-height: 1.55;
  color: var(--chalk-low);
  text-wrap: pretty;
}

.num {
  font-family: var(--f-display);
  font-weight: 800;
  font-stretch: 112%;
  font-variant-numeric: tabular-nums;
  letter-spacing: -.03em;
  line-height: .9;
}

/* Status chip. */
.tag {
  display: inline-block;
  font-family: var(--f-data);
  font-size: var(--t-micro);
  font-weight: 600;
  font-stretch: 80%;
  letter-spacing: .14em;
  text-transform: uppercase;
  padding: .28rem .5rem .24rem;
  border: 1px solid var(--line-hi);
  color: var(--chalk-low);
  line-height: 1;
  white-space: nowrap;
}
.tag--future { border-color: var(--volt-line); color: var(--volt); }

/* ── 5. MOTION / REVEAL ──────────────────────────────────────────────────── */
/* Everything below is gated on .js (set by an inline script in <head>). Without
   scripting the page renders complete rather than blank — crawlers, printing and
   any failed script load all get the finished state. */
.reveal {
  transition: opacity var(--d-reveal) var(--e-out), transform var(--d-reveal) var(--e-out);
  transition-delay: var(--delay, 0ms);
}
.js .reveal { opacity: 0; transform: translateY(18px); }
.js .reveal.is-in { opacity: 1; transform: none; }
/* ── 7. MASTHEAD ─────────────────────────────────────────────────────────── */
.masthead {
  position: fixed; inset: 0 0 auto 0; z-index: 50;
  background: color-mix(in srgb, var(--ink) 86%, transparent);
  border-bottom: 1px solid transparent;
  transition: border-color 300ms var(--e-soft), background 300ms var(--e-soft);
}
.masthead.is-stuck { border-bottom-color: var(--line); }

.masthead__inner {
  width: var(--wrap-wide); margin-inline: auto;
  display: flex; align-items: center; gap: var(--s4);
  height: 4.25rem;
}
.masthead__logo { display: flex; align-items: center; min-height: 44px; margin-right: auto; }
.masthead__logo img { width: 148px; }
@media (max-width: 560px) {
  :root { --head: 3.9rem; }
  .masthead__inner { gap: var(--s2); height: 3.9rem; }
  .masthead__logo img { width: 116px; }
  .masthead .btn--sm { padding: .55rem .85rem; font-size: .75rem; }
}

.masthead__nav { display: none; }
@media (min-width: 900px) {
  .masthead__nav { display: flex; align-items: center; gap: var(--s4); }
}
.masthead__link {
  font-family: var(--f-data);
  font-size: var(--t-label);
  font-weight: 500;
  font-stretch: 84%;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--chalk-low);
  display: inline-flex; align-items: center; min-height: 44px;
  transition: color var(--d-micro) var(--e-soft);
}
.masthead__link:hover { color: var(--chalk); }

/* ── 8. BUTTONS & FORM ───────────────────────────────────────────────────── */
.btn {
  --btn-bg: var(--volt);
  --btn-fg: var(--on-volt);
  display: inline-flex; align-items: center; justify-content: center; gap: .6rem;
  min-height: 48px;
  padding: .9rem 1.6rem;
  background: var(--btn-bg); color: var(--btn-fg);
  border: 1px solid var(--btn-bg);
  font-family: var(--f-display);
  font-size: .9rem; font-weight: 800; font-stretch: 112%;
  letter-spacing: .04em; text-transform: uppercase;
  line-height: 1;
  white-space: nowrap;
  cursor: pointer;
  transition: background var(--d-micro) var(--e-soft),
              color var(--d-micro) var(--e-soft),
              border-color var(--d-micro) var(--e-soft),
              transform var(--d-micro) var(--e-soft);
}
.btn:hover { transform: translateY(-2px); }
.btn:active { transform: translateY(0); }
.btn--ghost {
  --btn-bg: transparent; --btn-fg: var(--chalk);
  border-color: var(--line-hi);
}
.btn--ghost:hover { border-color: var(--chalk); }
.btn--sm { min-height: 44px; padding: .6rem 1.1rem; font-size: .8125rem; }
/* Buttons drawn inside a concept mockup are pictures of controls, not controls. */
.btn--static { cursor: default; }

.btn__arrow { width: 14px; height: 14px; flex: none; transition: transform var(--d-micro) var(--e-soft); }
.btn:hover .btn__arrow { transform: translateX(3px); }

/* ── 9. DEVICE + APP-UI MOCKUP KIT ───────────────────────────────────────────
   One coherent concept UI reused by every section. Phones use a fixed internal
   scale (the frame only flexes 280–292px, so px internals stay honest);
   wide panels are fully fluid.
   ------------------------------------------------------------------------- */
.device {
  width: min(292px, 100%);
  flex: none;
  background: #000;
  border: 1px solid var(--line-hi);
  border-radius: var(--r-phone);
  padding: 9px;
  box-shadow: 0 40px 90px -30px rgba(0,0,0,.9), 0 0 0 1px rgba(255,255,255,.03) inset;
  position: relative;
}
.device__screen {
  background: var(--ink);
  border-radius: calc(var(--r-phone) - 9px);
  overflow: hidden;
  position: relative;
  display: flex; flex-direction: column;
  min-height: 552px;
  font-size: 13px;
  line-height: 1.4;
}
.device__notch {
  position: absolute; top: 7px; left: 50%; transform: translateX(-50%);
  width: 78px; height: 20px; border-radius: 12px;
  background: #000; z-index: 3;
}

.ui-status {
  display: flex; align-items: center; justify-content: space-between;
  padding: 10px 18px 4px;
  font-family: var(--f-data); font-size: 9.5px; font-stretch: 80%;
  color: var(--chalk-mid); letter-spacing: .04em;
  flex: none;
}
.ui-status__icons { display: flex; gap: 4px; align-items: center; }
.ui-status__icons i {
  display: block; width: 3px; border-radius: 1px; background: var(--chalk-mid);
}
.ui-status__icons i:nth-child(1) { height: 5px; }
.ui-status__icons i:nth-child(2) { height: 7px; }
.ui-status__icons i:nth-child(3) { height: 9px; }
.ui-status__icons i:nth-child(4) { width: 16px; height: 8px; border-radius: 2px; background: var(--chalk-mid); }

.ui-body { padding: 8px 14px 14px; display: grid; gap: 10px; overflow: hidden; flex: 1 1 auto; }

.ui-head {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  padding-top: 4px;
}
.ui-title {
  font-family: var(--f-display); font-weight: 800; font-stretch: 114%;
  font-size: 17px; line-height: 1; letter-spacing: -.02em; text-transform: uppercase;
}
.ui-kicker {
  font-family: var(--f-data); font-size: 8.5px; font-stretch: 78%;
  letter-spacing: .14em; text-transform: uppercase; color: var(--chalk-low);
}

.ui-card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  padding: 12px;
}
.ui-card--volt { border-color: var(--volt-line); background: rgba(50,255,40,.05); }

.ui-avatar {
  width: 28px; height: 28px; flex: none;
  border-radius: 50%;
  display: grid; place-items: center;
  font-family: var(--f-display); font-weight: 800; font-stretch: 110%;
  font-size: 11px; line-height: 1;
  background: var(--surface-hi);
  border: 1px solid var(--line-hi);
  color: var(--chalk);
}
.ui-avatar--volt { background: var(--volt); color: var(--on-volt); border-color: var(--volt); }
.ui-avatar--lg { width: 46px; height: 46px; font-size: 17px; }
.ui-avatar--sm { width: 22px; height: 22px; font-size: 9px; }

.ui-stack-avatars { display: flex; }
.ui-stack-avatars .ui-avatar + .ui-avatar { margin-left: -8px; }

.ui-row { display: flex; align-items: center; gap: 9px; }
.ui-row--between { justify-content: space-between; }
.ui-row__main { min-width: 0; flex: 1; }

.ui-label {
  font-family: var(--f-data); font-size: 8px; font-stretch: 78%;
  letter-spacing: .13em; text-transform: uppercase; color: var(--chalk-low);
  white-space: nowrap;
}
.ui-name { font-weight: 600; font-size: 12.5px; line-height: 1.2; }
.ui-row__main > .ui-name, .ui-row__main > .ui-meta { display: block; }
.ui-meta { font-size: 11px; color: var(--chalk-low); line-height: 1.35; }

.ui-metrics { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 1px; background: var(--line); }
.ui-metrics > div { background: var(--ink); padding: 9px 8px; }
.ui-metric__n {
  font-family: var(--f-display); font-weight: 800; font-stretch: 112%;
  font-size: 19px; line-height: 1; letter-spacing: -.03em;
  font-variant-numeric: tabular-nums;
}
.ui-metric__l {
  font-family: var(--f-data); font-size: 7.5px; font-stretch: 76%;
  letter-spacing: .12em; text-transform: uppercase; color: var(--chalk-low);
  margin-top: 4px;
}

.ui-bar { height: 4px; background: var(--line); border-radius: 2px; overflow: hidden; }
.ui-bar__fill {
  height: 100%; border-radius: 2px;
  background: linear-gradient(90deg, var(--ball), var(--volt));
  width: var(--p, 50%);
}

.ui-chip {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 4px 8px; border-radius: 999px;
  border: 1px solid var(--line-hi);
  font-family: var(--f-data); font-size: 8px; font-stretch: 78%;
  letter-spacing: .1em; text-transform: uppercase; color: var(--chalk-mid);
  white-space: nowrap;
}
.ui-chip--volt { border-color: var(--volt); color: var(--volt); }
.ui-chip--fill { background: var(--volt); border-color: var(--volt); color: var(--on-volt); font-weight: 700; }

.ui-score { display: flex; gap: 5px; }
.ui-score span {
  font-family: var(--f-data); font-size: 11px; font-weight: 600; font-stretch: 82%;
  padding: 3px 6px; border: 1px solid var(--line-hi); border-radius: 4px;
  letter-spacing: .02em; color: var(--chalk);
}
.ui-score span.won { border-color: var(--volt-line); color: var(--volt); background: rgba(50,255,40,.06); }

.ui-tabbar {
  margin-top: auto; flex: none;
  display: grid; grid-template-columns: repeat(5, minmax(0, 1fr));
  padding: 9px 6px calc(9px + env(safe-area-inset-bottom, 0px));
  border-top: 1px solid var(--line);
  background: var(--ink-02);
}
/* Every slot is the same square box, centred in its equal track. `place-self: center`
   matters: a grid item with a definite width and the default `stretch` is aligned to the
   start of its track, which is what pushed the log button left of centre. The nav icons
   are drawn to a common ink box (height 16u centred on 12,12 in the sprite), so they
   also read at the same optical size. */
.ui-tabbar span {
  display: grid; place-items: center; place-self: center;
  width: 30px; height: 30px; color: var(--chalk-dim);
}
.ui-tabbar span svg { width: 17px; height: 17px; }
.ui-tabbar span.on { color: var(--volt); }
.ui-tabbar .ui-tabbar__log {
  background: var(--volt); color: var(--on-volt); border-radius: 50%;
}
.ui-tabbar .ui-tabbar__log svg { width: 15px; height: 15px; }

/* Wide app panel — fluid, used where a phone would be too small to read. */
.panel {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  overflow: hidden;
}
.panel__bar {
  display: flex; align-items: center; justify-content: space-between; gap: var(--s2);
  padding: .85rem 1.1rem;
  border-bottom: 1px solid var(--line);
  background: var(--ink-02);
}
.panel__dots { display: flex; gap: 5px; }
.panel__dots i { width: 7px; height: 7px; border-radius: 50%; background: var(--line-hi); display: block; }
.panel__dots i:first-child { background: var(--volt); }
.panel__body { padding: clamp(1.1rem, 2.4vw, 1.9rem); }

/* Icon sprite helper */
.ico { width: 1em; height: 1em; flex: none; stroke: currentColor; fill: none;
       stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.chart { width: 100%; height: auto; display: block; overflow: visible; }
.chart__grid line { stroke: var(--line); stroke-width: 1; }
.chart__bar { fill: var(--line-hi); transition: fill var(--d-micro) var(--e-soft); }
.chart__bar--now { fill: var(--volt); }
.chart__axis {
  font-family: var(--f-data); font-size: 8.5px; font-stretch: 76%;
  letter-spacing: .1em; fill: var(--chalk-dim); text-transform: uppercase;
}
/* 10.7b LIVE MATCH MODE — the watch keeps score, the phone shows it ---------- */
/* Two concept devices, one causal story. The watch is a scorekeeper, not a small
   app; the phone is a scoreboard, not a dashboard. Composed by RIG 2. */

/* ---- the watch ---- */
.watch {
  width: min(212px, 66vw); flex: none;
  aspect-ratio: 1 / 1.19;
  background: #000;
  border: 1px solid var(--line-hi);
  border-radius: 26%;
  padding: 9px;
  box-shadow: 0 24px 50px -22px rgba(0,0,0,.9);
}
.watch__screen {
  height: 100%; border-radius: 20%;
  background: var(--ink); overflow: hidden;
  display: grid; align-content: center; gap: 7px;
  padding: 10px 9px; text-align: center;
}
.watch__top {
  font-family: var(--f-data); font-size: 9px; font-stretch: 78%;
  letter-spacing: .12em; text-transform: uppercase; color: var(--chalk-low);
  display: flex; align-items: center; justify-content: center; gap: 5px;
}
.watch__live {
  color: var(--volt); display: inline-flex; align-items: center; gap: 3px;
}
.watch__live::before { content: ''; width: 5px; height: 5px; border-radius: 50%; background: var(--volt); }
.watch__score { display: flex; align-items: baseline; justify-content: center; gap: 10px; }
.watch__pt {
  font-family: var(--f-display); font-weight: 800; font-stretch: 112%;
  font-size: 36px; line-height: 1; letter-spacing: -.04em;
  font-variant-numeric: tabular-nums; color: var(--chalk-low);
}
.watch__pt--us { font-size: 50px; color: var(--volt); }
.watch__keys { display: grid; grid-template-columns: 1fr 1fr; gap: 5px; }
.watch__key {
  font-family: var(--f-data); font-size: 9px; font-weight: 600; font-stretch: 78%;
  letter-spacing: .06em; text-transform: uppercase;
  padding: 9px 2px; border-radius: 999px;
  background: var(--surface-hi); color: var(--chalk-mid);
}
.watch__key--us { background: var(--volt); color: var(--on-volt); }
.watch__undo {
  font-family: var(--f-data); font-size: 8.5px; font-stretch: 78%;
  letter-spacing: .14em; text-transform: uppercase; color: var(--chalk-low);
}

/* ---- the courtside board: landscape, because that is how a phone gets propped ---- */
.board {
  width: 100%; max-width: 36rem;
  background: #000;
  border: 1px solid var(--line-hi);
  border-radius: var(--r-lg);
  padding: 10px;
  box-shadow: 0 34px 70px -30px rgba(0,0,0,.9);
}
.board__screen {
  background: var(--ink); border-radius: calc(var(--r-lg) - 6px);
  padding: clamp(.9rem, 2.4vw, 1.5rem);
  display: grid; gap: clamp(.6rem, 1.6vw, 1rem);
}
.board__set {
  font-family: var(--f-data); font-size: var(--t-label); font-stretch: 82%;
  letter-spacing: .16em; text-transform: uppercase; color: var(--volt);
}
.board__grid { width: 100%; border-collapse: collapse; }
.board__grid thead th {
  font-family: var(--f-data); font-size: var(--t-micro); font-weight: 500; font-stretch: 78%;
  letter-spacing: .12em; text-transform: uppercase; color: var(--chalk-dim);
  text-align: right; padding: 0 0 .4rem;
}
.board__row th {
  text-align: left; font-weight: 600;
  font-size: clamp(.8rem, 1.7vw, 1.05rem); color: var(--chalk);
  padding: .5rem 0;
}
.board__row td {
  text-align: right; padding: .5rem 0 .5rem 1rem;
  font-family: var(--f-display); font-weight: 800; font-stretch: 112%;
  font-size: clamp(1.1rem, 2.6vw, 1.7rem); line-height: 1;
  letter-spacing: -.03em; font-variant-numeric: tabular-nums; color: var(--chalk-mid);
}
.board__row + .board__row th, .board__row + .board__row td { border-top: 1px solid var(--line); }
/* The point is the number you read from the far baseline. */
.board__row .board__pt { font-size: clamp(2.1rem, 7vw, 4.4rem); color: var(--chalk); }
.board__row .board__pt--live { color: var(--volt); }
.board__foot {
  font-family: var(--f-data); font-size: var(--t-micro); font-stretch: 78%;
  letter-spacing: .12em; text-transform: uppercase; color: var(--chalk-dim);
  border-top: 1px solid var(--line); padding-top: .6rem;
}
.badge__mark {
  width: 46px; height: 46px; color: var(--volt);
  fill: none; stroke: currentColor; stroke-width: 1.5;
  stroke-linecap: round; stroke-linejoin: round;
}
.badge--locked .badge__mark { color: var(--line-hi); }
/* A confirmed scoreline is worth more than a self-entered one — say so quietly. */
.verified {
  display: inline-flex; align-items: center; gap: .3rem;
  font-family: var(--f-data); font-size: var(--t-micro); font-stretch: 78%;
  letter-spacing: .12em; text-transform: uppercase; color: var(--volt);
  white-space: nowrap;
}
.verified svg { width: 11px; height: 11px; }
/* 10.20 PRE-LAUNCH ---------------------------------------------------------- */

.coming { display: grid; justify-items: center; text-align: center; gap: var(--s5); }
.coming__row { display: flex; align-items: center; justify-content: center; gap: var(--s3); flex-wrap: wrap; }

/* ── 11b RALLY ON. — the closing signature ───────────────────────────────── */
.rallyon {
  background: var(--volt); color: var(--on-volt);
  padding-block: clamp(3rem, 8vh, 5.5rem);
  overflow: hidden;
}
.rallyon__inner { position: relative; text-align: center; }
.rallyon__mark {
  font-family: var(--f-display); font-weight: 900; font-stretch: 122%;
  font-size: clamp(2.6rem, 11vw, 8rem);
  line-height: .9; letter-spacing: -.04em; text-transform: uppercase;
}
/* One ball, once, across the band — the logo's entrance, answered at the end. */
.rallyon__ball {
  position: absolute; left: 0; top: 50%;
  width: clamp(14px, 2.4vw, 22px); aspect-ratio: 1; border-radius: 50%;
  background: var(--on-volt);
  transform: translate(-50vw, -50%);
  opacity: 0;
}
@media (prefers-reduced-motion: reduce) { .rallyon__ball { display: none; } }
.js .rallyon.is-in .rallyon__ball { animation: rallyServe 1100ms var(--e-out) 160ms forwards; }
@keyframes rallyServe {
  0%   { transform: translate(-20vw, -50%) scale(.7); opacity: 0; }
  18%  { opacity: 1; }
  82%  { opacity: 1; }
  100% { transform: translate(110vw, -50%) scale(1); opacity: 0; }
}

/* ── 11. FOOTER ──────────────────────────────────────────────────────────── */
/* The footer's small copy read a notch below the rest of the page on a real
   phone: 15px body and links, 13px baseline, 11px mono labels, all alpha-white
   on pure black. Both pages carry the same footer, so the fix lives here.

   These are token overrides rather than plain font-size rules because the
   markup sets the descriptive copy with an inline style="font-size:var(--t-sm)"
   that an ordinary selector loses to — but the custom property it resolves
   against is inherited, so redefining the token on .foot reaches it. Inside
   .foot these five are consumed only by .prose, .foot__col h2, .foot__col a
   and .foot__base, so nothing outside the footer moves. The ladder is
   unchanged: the label stays the smallest thing here and the baseline strip
   the dimmest, and none of the three greys reaches full chalk. */
.foot {
  --t-sm:      1rem;                     /* 15 → 16px: body copy and nav links */
  --t-label:   .75rem;                   /* 11 → 12px: the mono column labels  */
  --chalk-mid: rgba(255,255,255,.78);    /* 10.5:1 → 12.4:1 on --ink */
  --chalk-low: rgba(255,255,255,.66);    /*  6.9:1 →  8.9:1 */
  --chalk-dim: rgba(255,255,255,.62);    /*  5.3:1 →  7.8:1 */
  border-top: 1px solid var(--line); padding-block: var(--s8) var(--s6);
}
.foot__grid { display: grid; gap: var(--s6); }
@media (min-width: 760px) { .foot__grid { grid-template-columns: minmax(0,1.4fr) minmax(0,1fr) minmax(0,1fr); gap: var(--s8); } }
.foot__logo { width: 190px; margin-bottom: var(--s3); }
.foot__col { display: grid; gap: .2rem; align-content: start; }
.foot__col > h2 { margin-bottom: .5rem; }
.foot__col > p { margin-block: .35rem; }
.foot__col h2 {
  font-family: var(--f-data); font-size: var(--t-label); font-weight: 600; font-stretch: 84%;
  letter-spacing: .14em; text-transform: uppercase; color: var(--chalk-low);
  line-height: 1.4;
}
.foot__col a {
  font-size: var(--t-sm); color: var(--chalk-mid);
  display: inline-flex; align-items: center; min-height: 44px;
  transition: color var(--d-micro) var(--e-soft);
}
.foot__col a:hover { color: var(--volt); }
.foot__base {
  margin-top: var(--s8); padding-top: var(--s4); border-top: 1px solid var(--line);
  display: flex; gap: var(--s3); flex-wrap: wrap; justify-content: space-between;
  font-size: .875rem; color: var(--chalk-dim);
}
/* A value that changes in place. Both states occupy one cell so nothing shifts.
   Nothing changes in place unless the rig pins, so the second state is removed
   outright in every static composition rather than stacked invisibly. */
.swap { display: inline-grid; }
.swap > * { grid-area: 1 / 1; }
.swap > .swap__b { display: none; opacity: 0; }

@keyframes swapOut { 0% { opacity: 1; transform: translateY(0); } 100% { opacity: 0; transform: translateY(-42%); } }
@keyframes swapIn  { 0% { opacity: 0; transform: translateY(42%); } 100% { opacity: 1; transform: translateY(0); } }
@keyframes keyTap  {
  0%   { transform: scale(1); }
  22%  { transform: scale(.94); }
  100% { transform: scale(1); }
}
@keyframes keyPulse {
  0%   { opacity: .55; transform: scale(.6); }
  100% { opacity: 0;   transform: scale(1.9); }
}
.watch__key { position: relative; overflow: hidden; }
.watch__pulse {
  position: absolute; inset: 0; margin: auto;
  width: 100%; aspect-ratio: 1; border-radius: 50%;
  background: rgba(255,255,255,.5);
  opacity: 0; pointer-events: none;
}
