/* RunMaxx — shared design system.

   ARCADE NIGHT (October 2026). Deep violet ground, hot pink for the game
   (XP, levels, active states), cyan for labels and links, gold for rewards.
   It replaced Night Trail (moss green on near-black), which read as a calm
   health app; this is a game between friends and should look like one.

   TYPE — three jobs, three faces.
   Chakra Petch for display (headings, names, big numbers): squared-off and a
   little arcade, one bold weight. Inter Tight for everything read in
   sentences, system mono for every number in running text. Both are
   self-hosted, so font-src stays 'self' and no page waits on a third party.

   No italic file is shipped. Secondary text is distinguished by colour and
   size. */

/* Chakra Petch ships one weight (700). The range maps every display weight
   the pages ask for (500-900) onto that file, so the browser never fakes bold. */
@font-face{
  font-family:"Chakra Petch";
  src:url("/fonts/chakrapetch-700.woff2?v=07495e4d60d0") format("woff2");
  font-weight:500 900;
  font-style:normal;
  font-display:swap;
}
@font-face{
  font-family:"Inter Tight var";
  src:url("/fonts/intertight-var.woff2?v=07495e4d60d0") format("woff2-variations"),
      url("/fonts/intertight-var.woff2?v=07495e4d60d0") format("woff2");
  font-weight:400 700;
  font-style:normal;
  font-display:swap;
}

/* Token names predate the palette: --moss is the accent (pink) and --trail
   the label/link colour (cyan). Semantic green/amber/red are reserved for
   load status: they carry information, so nothing decorative borrows them,
   and none of them is close to the pink. */
:root{
  /* Native controls (checkboxes, date pickers, selects, scrollbars) draw
     dark too, instead of bright white boxes with a near-invisible calendar. */
  color-scheme:dark;
  --paper:#0D0B1A;        /* page ground */
  --paper2:#1E1A38;       /* recessed: bar tracks, inactive chips */
  --card:#17142B;         /* raised surface */
  --ink:#F2EFFF;          /* primary text, violet-tinted white */
  --stone:#A29BCB;        /* secondary text */
  --line:#2E2952;         /* hairlines and borders */
  --line-hi:#3D3766;      /* a border on hover, and dashed "locked" outlines */
  --line-strong:#6B63A0;  /* edges of things you type into or tap: inputs, unselected options */
  --well:#100D20;         /* inset: inputs, unselected chips, link boxes */
  --on-accent:#0D0B1A;    /* text on a filled pink, gold or cyan button */
  --stage-hi:#2E2752;     /* the avatar stage: a lit centre... */
  --stage-lo:#120F24;     /* ...falling off to this */

  --trail:#3DE8FF;        /* cyan — section labels, links */
  --moss:#FF3D9A;         /* the accent (pink): XP, levels, active states */
  --moss2:#C42A78;        /* deeper accent for secondary series */

  /* SEMANTIC — load status only. --danger leans orange so it never reads as
     the pink accent. */
  --good:#22C08A;         /* load: safe band */
  --warn:#FBBF24;         /* load: ramping */
  --danger:#FF7A59;       /* load: spike */
  --cool:#4FA8FF;         /* efficiency series */
  --gold:#FFD166;
  /* Epic gear's text colour. It was #C08BFF and used nowhere, while every
     epic label wrote out #C9A2FF; the token now holds the colour in use. */
  --epic:#C9A2FF;
  --r-common:#B8B2D9;     /* common gear (rare is --cool, legendary --gold) */
  /* Two colours that were only ever written as rgba() literals — the Sweat
     blue eight times over, the boss purple twice — so neither could be changed
     in one place and both had quietly drifted from --cool and --epic. */
  --sweat:#7EC0F0;        /* Sweat: the currency, and anything that spends it */
  --boss:#B07CF0;         /* the monthly co-op boss */
  /* The arcade glow. Used on the accent only (primary buttons, the XP ring, the
     current tab), so it stays a signal rather than wallpaper. */
  --glow:0 0 18px color-mix(in oklab, var(--moss) 35%, transparent);

  --mono:"SF Mono",ui-monospace,"Cascadia Mono",Menlo,Consolas,monospace;
  --display:"Chakra Petch",system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;
  --text:"Inter Tight var",system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;
  /* Back-compat alias. Sixteen page-level <style> blocks reference --serif for
     body copy and inputs; they all mean "the reading face", so the alias points
     at --text rather than rewriting every page. Use --text in new code. */
  --serif:var(--text);

  /* One radius for raised surfaces. The review counted seven (3/4/5/6/8/12/14px);
     the player card keeps its own because it is meant to look different. */
  --radius:10px;
}
*{box-sizing:border-box;margin:0;padding:0}
/* Buttons don't inherit the page's font by default; without this a few fell back to Arial. */
button{font-family:inherit}
/* hidden means hidden, whatever display a class sets. */
[hidden]{display:none!important}
/* Whatever is focused (Tab) or linked to (#rivalry, #ch-12) lands clear of the
   sticky top bar and the fixed tab bar, not underneath them. */
html{scroll-padding-top:64px;scroll-padding-bottom:calc(70px + env(safe-area-inset-bottom))}
body{
  /* A deep violet flat fill bands visibly on 8-bit panels, and the fix is also
     the look: a tiny feTurbulence tile as a data-URI over the colour. No file,
     no request, rasterised once. It reads as film grain, which is on-brief for
     "Arcade Night" — and it is the cheapest thing on this stylesheet that makes
     the ground look deliberate rather than flat. */
  background:var(--paper) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='3'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='120' height='120' filter='url(%23n)' opacity='.035'/%3E%3C/svg%3E") repeat;
  color:var(--ink);font-family:var(--text);line-height:1.5;
  padding-bottom:36px;-webkit-font-smoothing:antialiased;
}
.wrap{max-width:820px;margin:0 auto;padding:0 16px}
a{color:var(--trail)}
svg{width:100%;height:auto;display:block;overflow:visible}

/* ---- header ---- */
header{padding:18px 0 12px;border-bottom:2px solid var(--ink)}
.eyebrow{font-family:var(--mono);font-size:11px;letter-spacing:.24em;text-transform:uppercase;
  color:var(--trail);font-weight:600;margin-bottom:6px}
/* Chakra Petch is already wide and squared-off; negative tracking cramps it,
   so display text runs at 0 throughout. */
h1{font-family:var(--display);font-size:clamp(26px,7vw,40px);font-weight:800;
  letter-spacing:0;line-height:1;text-wrap:balance}
h2{font-family:var(--display);font-size:22px;font-weight:800;letter-spacing:0;
  margin-bottom:4px;text-wrap:balance}
.sec-label{font-family:var(--mono);font-size:10px;letter-spacing:.2em;text-transform:uppercase;
  color:var(--trail);font-weight:600;margin-bottom:8px;opacity:.9}
section{padding:16px 0;border-bottom:1px solid var(--line)}
section:last-of-type{border-bottom:none}

/* ---- level chips (the player card's are restyled below) ---- */
.lvl{font-family:var(--mono);font-size:11px;font-weight:600;letter-spacing:.06em;
  text-transform:uppercase;color:var(--moss);background:color-mix(in oklab, var(--moss) 14%, transparent);
  padding:3px 7px;border-radius:3px;white-space:nowrap}
/* ============================================================
   THE PLAYER CARD

   The one element in the app allowed to be theatrical. Everything
   else stays flat and quiet; this is the screen people screenshot
   into the group chat, so it gets the frame, the glow and the ring.

   The frame TIERS with combined level. That matters more than it
   looks: a decoration everyone has from day one is wallpaper, and
   one that changes four times on the way up is a thing to chase.
   ============================================================ */
.pcard{border-radius:14px;padding:2px;background:linear-gradient(145deg,var(--stone),var(--stage-hi))}
.pcard[data-tier="2"]{background:linear-gradient(145deg,var(--moss),#8A1F5A 45%,#2A1036)}
.pcard[data-tier="3"]{background:linear-gradient(145deg,var(--cool),#1C4E7A 45%,#13243A)}
.pcard[data-tier="4"]{background:linear-gradient(145deg,var(--gold),var(--moss) 38%,#0F0C1E 62%,var(--gold))}
.pcard[data-tier="4"]{box-shadow:0 0 34px color-mix(in oklab, var(--gold) 16%, transparent)}
.pcard-in{background:radial-gradient(120% 90% at 50% 0%,#221D40,#110E22 70%);
  border-radius:12px;padding:17px 16px 15px;text-align:center}

.pcard .port{width:62px;height:62px;border-radius:50%;margin:0 auto 9px;display:grid;
  place-items:center;font-family:var(--display);font-weight:800;font-size:23px;
  letter-spacing:0;color:var(--on-accent);
  background:linear-gradient(145deg,var(--moss),var(--gold));
  box-shadow:0 0 22px color-mix(in oklab, var(--moss) 26%, transparent)}
.pcard .nm{font-family:var(--display);font-size:20px;font-weight:800;letter-spacing:0}
.pcard .rankline{font-family:var(--mono);font-size:10px;letter-spacing:.2em;
  text-transform:uppercase;color:var(--gold);font-weight:600;margin-top:3px}
.pcard .tonext{font-family:var(--mono);font-size:11px;color:var(--stone);margin-top:4px}
.pcard .tonext b{color:var(--ink);font-weight:700}
.ready-line{margin:-4px 0 12px}

.pcard .ringwrap{margin:12px auto 4px;width:112px;position:relative}
.pcard .ringwrap svg{display:block}
.pcard #pRing{transition:stroke-dashoffset 1s cubic-bezier(.22,.9,.3,1)}
.pcard .ringtxt{position:absolute;inset:0;display:grid;place-items:center;text-align:center}
.pcard .ringtxt b{display:block;font-family:var(--mono);font-size:25px;font-weight:800;line-height:1}
.pcard .ringtxt span span{font-family:var(--mono);font-size:10px;letter-spacing:.12em;
  text-transform:uppercase;color:var(--stone)}

.pcard .chips{display:flex;gap:5px;justify-content:center;flex-wrap:wrap;margin-top:11px}
.pcard .lvl{border-radius:99px;padding:4px 9px;border:1px solid color-mix(in oklab, var(--moss) 35%, transparent);
  background:color-mix(in oklab, var(--moss) 12%, transparent)}
.pcard .lvl.b{color:var(--cool);background:color-mix(in oklab, var(--cool) 12%, transparent);border-color:color-mix(in oklab, var(--cool) 35%, transparent)}
.pcard .lvl.s{color:var(--gold);background:color-mix(in oklab, var(--gold) 12%, transparent);border-color:color-mix(in oklab, var(--gold) 35%, transparent)}
.pcard .lvl.l{color:var(--trail);background:color-mix(in oklab, var(--trail) 12%, transparent);border-color:color-mix(in oklab, var(--trail) 35%, transparent)}
.pcard .xpline{font-family:var(--mono);font-size:11px;color:var(--stone);margin-top:9px}

/* Badge shelf. Earned chips carry their tier's colour; locked ones are dimmed
   and show what they take, because a case of only what you already have is a
   trophy cabinet and a trophy cabinet doesn't make anyone train. */
.shelf{display:flex;gap:5px;flex-wrap:wrap;justify-content:center;margin-top:11px}
.bdg{font-family:var(--mono);font-size:10px;letter-spacing:.08em;text-transform:uppercase;
  padding:3px 8px;border-radius:99px;border:1px solid var(--line);color:var(--stone);
  white-space:nowrap}
.bdg.bronze{color:#C08552;border-color:rgba(192,133,82,.45);background:rgba(192,133,82,.08)}
.bdg.silver{color:var(--r-common);border-color:rgba(174,182,191,.45);background:rgba(174,182,191,.08)}
.bdg.gold{color:var(--gold);border-color:color-mix(in oklab, var(--gold) 45%, transparent);background:color-mix(in oklab, var(--gold) 8%, transparent)}
.bdg.race{color:var(--moss);border-color:var(--moss);background:color-mix(in oklab, var(--moss) 10%, transparent)}
.bdg.locked{color:#9AA0A8;border-color:var(--line-hi);border-style:dashed;background:none}
.bdg.more{color:var(--stone);border-style:dashed}

/* ---- status strip ---- */
.status{display:grid;grid-template-columns:repeat(3,1fr);gap:8px;margin:10px 0 6px}
.stat{background:var(--card);border:1px solid var(--line);border-radius:var(--radius);padding:12px 13px;
  text-align:left;display:block;color:var(--ink);text-decoration:none;position:relative;min-width:0}
.stat .lbl{font-family:var(--mono);font-size:10px;letter-spacing:.06em;text-transform:uppercase;
  color:var(--stone);margin-bottom:4px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.stat .val{font-size:32px;font-weight:800;line-height:1;font-family:var(--display);letter-spacing:0;
  font-variant-numeric:tabular-nums;min-height:32px;display:flex;align-items:center}
.stat .sub{font-size:11px;color:var(--stone);margin-top:5px;line-height:1.3}
.stat.flag-good{border-color:var(--good)} .stat.flag-good .val{color:var(--good)}
.stat.flag-warn{border-color:var(--warn)} .stat.flag-warn .val{color:var(--warn)}
.stat.flag-danger{border-color:var(--danger);background:color-mix(in oklab, var(--danger) 9%, transparent)} .stat.flag-danger .val{color:var(--danger)}

.banner{border-radius:4px;padding:11px 14px;margin:8px 0 4px;font-size:14px;font-weight:600}
.banner.ok{background:rgba(74,222,128,.11);color:var(--good)}
.banner.warn{background:color-mix(in oklab, var(--warn) 11%, transparent);color:var(--warn)}
.banner.danger{background:color-mix(in oklab, var(--danger) 12%, transparent);color:var(--danger)}
.banner.quiet{background:var(--paper2);color:var(--stone);font-weight:400}

/* ---- controls ---- */
label{font-family:var(--mono);font-size:10px;letter-spacing:.06em;text-transform:uppercase;
  color:var(--stone);display:block;margin-bottom:3px}
/* Edges of things you type into are --line-strong: --line is a hairline,
   barely 1.3:1 against the card, and a box you can't see is a box you miss. */
input,select{width:100%;font-family:var(--serif);font-size:16px;padding:9px 10px;
  border:1px solid var(--line-strong);border-radius:4px;background:var(--well);color:var(--ink)}
textarea{border-color:var(--line-strong)}
input:focus,select:focus{outline:2px solid var(--moss2);outline-offset:-1px}
.btn{font-family:var(--mono);font-size:13px;letter-spacing:.04em;font-weight:600;padding:11px 16px;
  border:none;border-radius:4px;background:var(--moss);color:var(--on-accent);cursor:pointer;width:100%}
.btn:active{background:var(--moss2)}
.btn.alt{background:transparent;color:var(--moss);border:1px solid var(--moss)}
/* For the one irreversible thing a member can do to themselves (leaving):
   outlined, never the glowing pink of a normal next step. */
.btn.danger{background:transparent;color:var(--danger);border:1px solid var(--danger)}
.btn.danger:active{background:color-mix(in oklab, var(--danger) 15%, transparent)}
.btn.small{width:auto;padding:7px 12px;font-size:12px}
a.btn{display:inline-block;text-align:center;text-decoration:none}
.btnrow{display:flex;gap:8px;flex-wrap:wrap}
button:focus-visible,a:focus-visible{outline:2px solid var(--moss2);outline-offset:2px}

.entry{background:var(--card);border:1px solid var(--line);border-radius:var(--radius);padding:14px;margin-bottom:8px}
.entry .row{display:grid;grid-template-columns:1fr 1fr;gap:8px;margin-bottom:8px}
.entry .row3{display:grid;grid-template-columns:1fr 1fr 1fr;gap:8px;margin-bottom:8px}

/* ---- daily check ---- */
.footlog{display:flex;gap:8px;align-items:center;flex-wrap:wrap;background:var(--card);
  border:1px solid var(--line);border-radius:var(--radius);padding:12px 14px}
.footlog .q{font-size:14px;font-weight:600;margin-right:4px}
.fbtn{font-family:var(--mono);font-size:12px;font-weight:600;padding:9px 14px;border-radius:4px;
  border:1px solid var(--line-strong);background:var(--well);cursor:pointer}
.fbtn.quiet{color:var(--good)} .fbtn.quiet:active,.fbtn.quiet[aria-pressed=true]{background:var(--good);color:var(--on-accent)}
.fbtn.aware{color:var(--warn)} .fbtn.aware:active,.fbtn.aware[aria-pressed=true]{background:var(--warn);color:var(--on-accent)}
.fbtn.pain{color:var(--danger)} .fbtn.pain:active,.fbtn.pain[aria-pressed=true]{background:var(--danger);color:var(--on-accent)}

/* ---- the race strip: what all of this is for ---- */
.racestrip{display:flex;align-items:baseline;gap:10px;background:var(--card);
  border:1px solid var(--trail);border-radius:var(--radius);padding:11px 14px;
  margin:10px 0 4px;text-decoration:none;color:var(--ink)}
.racestrip .d{font-family:var(--mono);font-size:24px;font-weight:800;color:var(--trail);line-height:1}
.racestrip .l{font-family:var(--display);font-size:14px;font-weight:600;letter-spacing:0}
.racestrip .also{display:block;font-family:var(--text);font-size:12px;font-weight:400;color:var(--stone);margin-top:3px}

/* ---- charts ---- */
.chart-card{background:var(--card);border:1px solid var(--line);border-radius:var(--radius);padding:14px;margin-bottom:12px}
.chart-card .ct{font-family:var(--display);font-weight:700;font-size:15px;
  letter-spacing:0;margin-bottom:2px}
.chart-card .cs{font-size:12px;color:var(--stone);margin-bottom:10px}
.chart-card .scroll{overflow-x:auto}
.empty{color:var(--stone);font-size:13px;padding:14px 0;text-align:center}
.note{font-size:12px;color:var(--stone);margin-top:8px}

/* panel toggles */
.toggles{display:flex;flex-wrap:wrap;gap:6px;margin-bottom:12px}
.tg{font-family:var(--mono);font-size:11px;padding:5px 10px;border-radius:3px;cursor:pointer;min-height:36px;
  border:1px solid var(--line-strong);background:var(--well);color:var(--stone)}
/* Selected controls are TINTED, not filled. A page with six solid-green
   toggles reads as decoration; a page with six tinted ones reads as state. */
.tg[aria-pressed="true"]{background:color-mix(in oklab, var(--moss) 14%, transparent);border-color:var(--moss);
  color:var(--moss);font-weight:700}

/* Train's "Choose panels": closed by default, under the charts. On/off is a
   setting, not a choice in a game, so it's ink with a tick rather than pink. */
.panelpick{border-bottom:1px solid var(--line);padding:4px 0 12px}
.panelpick summary{min-height:44px;display:flex;align-items:center;gap:6px;cursor:pointer;
  font-family:var(--mono);font-size:12px;letter-spacing:.08em;text-transform:uppercase;color:var(--trail)}
.panelpick summary span{color:var(--stone);text-transform:none;letter-spacing:0}
.panelpick .toggles{margin-top:4px}
.panelpick .tg[aria-pressed="true"]{background:var(--paper2);border-color:var(--stone);color:var(--ink)}
.panelpick .tg[aria-pressed="true"]::before{content:'✓ ';content:'✓ ' / ''}

/* ---- tables ---- */
table{width:100%;border-collapse:collapse;font-size:13px;margin-top:4px}
th{font-family:var(--mono);font-size:10px;letter-spacing:.05em;text-transform:uppercase;
  color:var(--stone);text-align:left;padding:5px 6px;border-bottom:1.5px solid var(--ink)}
td{padding:6px;border-bottom:1px solid var(--line);vertical-align:middle}
td.mono,.mono{font-family:var(--mono)}
.del{color:#FFB4A2;cursor:pointer;font-family:var(--mono);font-size:11px;background:transparent;
  border:1px solid color-mix(in oklab, var(--danger) 40%, transparent);border-radius:6px;padding:6px 10px;min-height:30px}
/* A .del inside a table cell is a text link, not a button. */
td .del{border:none;padding:4px 6px;min-height:24px}
.foot-dot{display:inline-block;width:9px;height:9px;border-radius:50%;margin-right:2px}
.fd-quiet{background:var(--good)} .fd-aware{background:var(--warn)} .fd-pain{background:var(--danger)}
.tag{font-family:var(--mono);font-size:10px;text-transform:uppercase;letter-spacing:.05em;
  padding:2px 5px;border-radius:3px}
.tag.easy{background:color-mix(in oklab, var(--moss) 13%, transparent);color:var(--moss)}
.tag.moderate{background:color-mix(in oklab, var(--trail) 14%, transparent);color:var(--trail)}
.tag.hard{background:color-mix(in oklab, var(--danger) 14%, transparent);color:var(--danger)}
.tag.long{background:color-mix(in oklab, var(--cool) 14%, transparent);color:var(--cool)}

/* ---- xp feed ---- */
.xplist{display:flex;flex-direction:column;gap:2px}
.xprow{display:flex;justify-content:space-between;gap:10px;font-size:13px;padding:5px 0;
  border-bottom:1px solid var(--line)}
.xprow:last-child{border-bottom:none}
.xprow .p{font-family:var(--mono);font-weight:600;color:var(--moss);white-space:nowrap}

/* ---- top bar + side drawer ---- */
.topbar{position:sticky;top:0;z-index:30;display:flex;align-items:center;gap:12px;
  background:var(--paper);border-bottom:1px solid var(--line);
  padding:calc(env(safe-area-inset-top) + 10px) 16px 10px}
/* Hidden everywhere: on a phone the drawer only repeated the tab bar and the
   account menu, and the desktop has the sidebar. One way to each place. */
.topbar .burger{display:none}
.burger{width:34px;height:30px;display:flex;flex-direction:column;justify-content:center;
  gap:5px;background:none;border:none;cursor:pointer;padding:0}
.burger span{display:block;height:2px;background:var(--ink);border-radius:2px;transition:.2s}
.burger:hover span{background:var(--trail)}
.topbar-title{font-family:var(--mono);font-size:11px;letter-spacing:.2em;text-transform:uppercase;
  color:var(--stone);font-weight:600}

.drawer{position:fixed;inset:0;z-index:40;pointer-events:none}
.drawer-backdrop{position:absolute;inset:0;background:rgba(0,0,0,.62);opacity:0;transition:opacity .22s ease}
.drawer-panel{position:absolute;top:0;left:0;bottom:0;width:min(278px,82vw);background:var(--card);
  border-right:1px solid var(--line);transform:translateX(-100%);transition:transform .24s ease;
  display:flex;flex-direction:column;padding-top:env(safe-area-inset-top)}
.drawer.open{pointer-events:auto}
.drawer.open .drawer-backdrop{opacity:1}
.drawer.open .drawer-panel{transform:none}

.drawer-head{display:flex;align-items:center;justify-content:space-between;
  padding:18px 18px 14px;border-bottom:2px solid var(--ink)}
.drawer-mark{font-family:var(--mono);font-size:12px;letter-spacing:.24em;text-transform:uppercase;
  color:var(--trail);font-weight:600}
.drawer-close{background:none;border:none;font-size:26px;line-height:1;color:var(--stone);
  cursor:pointer;min-width:36px;min-height:36px;display:grid;place-items:center}
.drawer-close:hover{color:var(--ink)}

.drawer-links,.side-links{display:flex;flex-direction:column;padding:6px 0;flex:1;overflow-y:auto}

/* Rows are 36px, not 46. Fourteen sections at the old height didn't fit a phone
   without scrolling the menu itself, which defeats the point of a menu. */
.drawer-links a,.side-links a{display:flex;align-items:center;gap:11px;padding:8px 16px;
  font-size:15px;color:var(--ink);text-decoration:none;border-left:2px solid transparent}
.drawer-links a:hover,.side-links a:hover{background:var(--paper2)}
.drawer-links a[aria-current="page"],.side-links a[aria-current="page"]{
  border-left-color:var(--moss);color:var(--moss);font-weight:700;
  background:color-mix(in oklab, var(--moss) 7%, transparent)}
.drawer-links .ic,.side-links .ic{font-size:13px;width:16px;text-align:center;color:var(--stone)}
.drawer-links a[aria-current="page"] .ic,.side-links a[aria-current="page"] .ic{color:var(--moss)}

.nav-group{padding:4px 0}
.nav-group + .nav-group{margin-top:6px;border-top:1px solid var(--line);padding-top:8px}
.nav-group-label{font-family:var(--mono);font-size:10px;letter-spacing:.2em;text-transform:uppercase;
  color:var(--stone);padding:0 16px 5px}

.drawer-foot{border-top:1px solid var(--line);padding:14px 18px calc(18px + env(safe-area-inset-bottom));
  font-size:12px;color:var(--stone)}
.drawer-foot .who{font-family:var(--serif);font-size:14px;font-weight:700;color:var(--ink);margin-bottom:2px}

footer{padding:22px 0 8px;color:var(--stone);font-size:12px;text-align:center}

@media (prefers-reduced-motion: reduce){*{animation:none!important;transition:none!important}}

/* ---- pull to refresh ---- */
.ptr{height:0;overflow:hidden;display:flex;align-items:center;justify-content:center;
  background:var(--card);border-bottom:1px solid var(--line);transition:height .18s ease;
  font-family:var(--mono);font-size:11px;letter-spacing:.12em;text-transform:uppercase;
  color:var(--stone)}
.ptr.ready{color:var(--moss)}

.drawer-sync{display:block;width:100%;margin-top:10px;font-family:var(--mono);font-size:11px;
  letter-spacing:.08em;text-transform:uppercase;padding:9px;border:1px solid var(--moss);
  border-radius:4px;background:transparent;color:var(--moss);cursor:pointer;font-weight:600}
.drawer-sync:disabled{opacity:.6}
.drawer-out{display:block;margin-top:6px;font-family:var(--mono);font-size:11px;
  color:var(--stone);text-decoration:none;text-align:center;padding:8px 0}
.drawer-out:hover{color:var(--danger)}

/* ---- always-there escape hatches ----
   Back on the left, account on the right, on every screen. Nobody should ever
   have to use the browser's own chrome to get out of a page — on a home-screen
   PWA there isn't any. */
.nav-back{background:none;border:none;color:var(--stone);cursor:pointer;padding:0;
  font-size:26px;line-height:1;min-width:36px;min-height:36px;margin:0 -10px 0 -8px}
.nav-back:hover{color:var(--ink)}
.topbar-spacer{flex:1}

.acct{position:relative}
.acct-btn{width:36px;height:36px;border-radius:50%;border:1px solid var(--line);
  background:var(--card);color:var(--ink);font-family:var(--mono);font-size:11px;
  font-weight:700;cursor:pointer;letter-spacing:.02em}
.acct-btn:hover{border-color:var(--moss);color:var(--moss)}
.acct-menu{position:absolute;right:0;top:44px;min-width:174px;background:var(--card);
  border:1px solid var(--line);border-radius:6px;padding:6px;z-index:35;
  box-shadow:0 10px 26px rgba(0,0,0,.5)}
.acct-menu[hidden]{display:none}
.acct-menu .nmz{font-family:var(--serif);font-size:14px;font-weight:700;padding:6px 9px 3px}
.acct-menu .sub{font-family:var(--mono);font-size:10px;color:var(--stone);padding:0 9px 7px;
  border-bottom:1px solid var(--line);margin-bottom:5px}
.acct-menu a,.acct-menu button{display:block;width:100%;text-align:left;background:none;
  border:none;color:var(--ink);text-decoration:none;font-size:14px;padding:8px 9px;
  border-radius:4px;cursor:pointer;font-family:inherit}
.acct-menu a:hover,.acct-menu button:hover{background:var(--paper2)}
.acct-menu .out{color:var(--danger)}
.acct-signin{font-family:var(--mono);font-size:11px;letter-spacing:.08em;text-transform:uppercase;
  color:var(--moss);text-decoration:none;font-weight:600}

/* ============================================================
   DESKTOP
   The bottom tab bar is a phone pattern. Stretched across a
   laptop it was the single thing making the app look unfinished,
   so above 900px it goes away and the same section list becomes
   a permanent sidebar. No duplicate markup — one list, two
   presentations, CSS decides.
   ============================================================ */
.sidebar{display:none}

@media (min-width:900px){
  .sidebar{display:flex;flex-direction:column;position:fixed;left:0;top:0;bottom:0;width:212px;
    background:var(--card);border-right:1px solid var(--line);z-index:35}
  .side-mark{font-family:var(--mono);font-size:12px;letter-spacing:.24em;text-transform:uppercase;
    color:var(--trail);font-weight:600;text-decoration:none;padding:20px 16px 14px;
    border-bottom:1px solid var(--line)}
  .side-foot{border-top:1px solid var(--line);padding:12px 16px;font-size:12px;color:var(--stone)}
  .side-foot .who{font-family:var(--serif);font-size:14px;font-weight:700;color:var(--ink)}

  /* Everything shifts right of the sidebar. The tab bar and the burger are
     redundant here, and a back button is too when the whole map is visible. */
  body.has-nav{padding-left:212px;padding-bottom:28px}
  body.has-nav .tabs{display:none}
  body.has-nav .burger,body.has-nav .nav-back{display:none}
  body.has-nav .topbar{padding-left:26px}
  body.has-nav .toasts{left:212px}

  /* Wider column, and the things that were stacked can sit side by side.
     #charts is the training page's panel stack — nine full-width charts is a
     lot of scrolling on a screen with room for two abreast. */
  .wrap{max-width:1040px;padding:0 26px}
  /* The signed-out panel is one paragraph and one button. Left at full column
     width the Strava button stretched to 1040px, which is the first thing a
     new athlete sees on a laptop. */
  #signedOut{max-width:26rem}
  .status{grid-template-columns:repeat(3,1fr)}
  .two-up,#charts{display:grid;grid-template-columns:1fr 1fr;gap:12px;align-items:start}
  .two-up .chart-card,#charts .chart-card{margin-bottom:0}
  section{padding:18px 0}
}

/* A middle band: too narrow for a sidebar, too wide for phone spacing. */
@media (min-width:600px) and (max-width:899px){
  .wrap{max-width:720px}
  .two-up,#charts{display:grid;grid-template-columns:1fr 1fr;gap:12px;align-items:start}
  .two-up .chart-card,#charts .chart-card{margin-bottom:0}
}

/* ---- bottom tabs: the five places people actually go ---- */
.tabs{position:fixed;left:0;right:0;bottom:0;z-index:29;display:flex;
  background:var(--paper);border-top:1px solid var(--line);
  padding-bottom:env(safe-area-inset-bottom)}
.tabs a{flex:1;display:flex;flex-direction:column;align-items:center;gap:3px;
  padding:8px 2px 7px;text-decoration:none;color:var(--stone);font-size:10px;
  font-family:var(--mono);letter-spacing:.09em;text-transform:uppercase}
.tabs a .ic{font-size:16px;line-height:1}
.tabs a[aria-current="page"]{color:var(--moss)}
body{padding-bottom:calc(62px + env(safe-area-inset-bottom))}

/* ============================================================
   MOTION
   Every transition below is attached to a state change. The block
   at the very end of this file switches all of it off for anyone
   who asked their system for reduced motion — that rule is not a
   nicety, so nothing here may rely on animation to be legible.
   ============================================================ */

/* Press feedback. 60ms is under the threshold where a delay reads as lag,
   but enough that a tap on glass feels like it landed on something. */
.btn,.fbtn,.tg,.acct-btn,.drawer-sync,.kind button,.btn.small{
  transition:transform .06s ease,background .12s ease,border-color .12s ease,color .12s ease}
.btn.pressed,.fbtn.pressed,.drawer-sync.pressed,.kind button.pressed{transform:scale(.968)}
.tabs a.pressed,.drawer-links a.pressed{opacity:.6}
.btn:disabled{opacity:.5;cursor:default;transform:none!important}

/* Cards arriving. Short, small distance, capped at eight items in ui.js —
   a long stagger is a queue you make the reader stand in. */
@keyframes rise{from{opacity:0;transform:translateY(7px)}to{opacity:1;transform:none}}
.rise{animation:rise .3s cubic-bezier(.22,.9,.3,1) both}

/* XP and progress bars. Slow enough to read as filling rather than jumping.
   Bars are drawn at their final width, so the fill is a one-off scale-in on
   mount (compositor only), not a width transition that never got to run. */
@keyframes barfill{from{transform:scaleX(0)}}
.gbar i{transform-origin:left;animation:barfill .8s cubic-bezier(.22,.9,.3,1) both}

/* Status tiles reacting to a changed value. */
@keyframes pop{0%{transform:scale(1)}42%{transform:scale(1.055)}100%{transform:scale(1)}}
.stat.changed .val{animation:pop .42s ease-out}

/* The card acknowledging that XP landed. One pulse of the frame, not a loop —
   a celebration that repeats is a distraction by the third time you see it. */
@keyframes cardglow{
  0%{box-shadow:0 0 0 transparent}
  35%{box-shadow:0 0 38px color-mix(in oklab, var(--moss) 42%, transparent)}
  100%{box-shadow:0 0 0 transparent}
}
.pcard.gained{animation:cardglow 1.2s ease-out}
.pcard.gained .port{animation:pop .5s ease-out}

/* ---- toasts ---- */
.toasts{position:fixed;left:0;right:0;bottom:calc(74px + env(safe-area-inset-bottom));
  z-index:60;display:flex;flex-direction:column;align-items:center;gap:7px;
  pointer-events:none;padding:0 16px}
.toast{pointer-events:auto;max-width:26rem;width:fit-content;background:var(--card);
  border:1px solid var(--line);border-radius:5px;
  padding:11px 15px;font-size:14px;color:var(--ink);cursor:pointer;
  box-shadow:0 10px 30px rgba(0,0,0,.55);
  opacity:0;transform:translateY(10px);transition:opacity .22s ease,transform .22s ease}
.toast.in{opacity:1;transform:none}
.toast-warn{border-color:var(--warn)}
.toast-bad{border-color:var(--danger)}

/* ---- the level-up moment ---- */
.levelup{position:fixed;inset:0;z-index:70;display:grid;place-items:center;
  background:color-mix(in oklab, var(--paper) 72%, transparent);opacity:0;transition:opacity .3s ease;cursor:pointer;
  padding:24px}
.levelup.in{opacity:1}
.lu-card{background:var(--card);border:1px solid var(--moss);border-radius:10px;
  padding:30px 44px;text-align:center;transform:scale(.9);transition:transform .4s cubic-bezier(.16,1,.3,1);
  box-shadow:0 0 62px color-mix(in oklab, var(--moss) 24%, transparent)}
.levelup.in .lu-card{transform:none}
.lu-eyebrow{font-family:var(--mono);font-size:11px;letter-spacing:.24em;text-transform:uppercase;
  color:var(--moss);margin-bottom:8px}
.lu-n{font-family:var(--mono);font-size:76px;font-weight:800;line-height:1;color:var(--ink)}
.lu-sub{font-size:14px;color:var(--stone);margin-top:10px}

/* ---- skeletons ---- */
@keyframes shimmer{from{background-position:-420px 0}to{background-position:420px 0}}
.skel{border-radius:6px;margin-bottom:8px;
  background:linear-gradient(90deg,var(--card) 0%,#1B1F25 42%,var(--card) 84%);
  background-size:420px 100%;animation:shimmer 1.25s linear infinite}

/* ---- feed cards for the new event kinds ---- */

.recap-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(122px,1fr));gap:8px;
  margin-top:11px}
.recap-award{background:var(--paper2);border-radius:5px;padding:9px 11px}
.recap-award .t{font-family:var(--mono);font-size:10px;letter-spacing:.11em;
  text-transform:uppercase;color:var(--stone)}
.recap-award .w{font-family:var(--display);font-size:14px;font-weight:700;
  letter-spacing:0;margin-top:3px}
.recap-award .v{font-family:var(--mono);font-size:11px;color:var(--moss)}
.recap-tot{display:flex;gap:14px;flex-wrap:wrap;font-family:var(--mono);font-size:11px;
  color:var(--stone);margin-top:11px;padding-top:10px;border-top:1px solid var(--line)}

/* ---- empty states that point somewhere ---- */
.empty-rich{text-align:center;padding:26px 18px;background:var(--card);
  border:1px dashed var(--line);border-radius:8px}
.empty-rich .ic{font-size:26px;opacity:.5}
.empty-rich .h{font-family:var(--display);font-size:16px;font-weight:700;
  letter-spacing:0;margin:9px 0 5px}
.empty-rich .p{font-size:14px;color:var(--stone);line-height:1.55;max-width:25rem;
  margin:0 auto 13px}
.empty-rich .btn{max-width:15rem;margin:0 auto}

/* ---- notification settings ---- */
.switch{display:flex;justify-content:space-between;align-items:center;gap:12px;
  padding:11px 0;border-bottom:1px solid var(--line)}
.switch:last-of-type{border-bottom:none}
.switch .lb{font-size:14px}
.switch .lb small{display:block;color:var(--stone);font-size:12px;margin-top:2px}
.sw{flex:none;width:44px;height:25px;border-radius:13px;background:var(--paper2);
  border:1px solid var(--line);position:relative;cursor:pointer;transition:background .18s ease,border-color .18s ease}
.sw::after{content:'';position:absolute;top:2px;left:2px;width:19px;height:19px;border-radius:50%;
  background:var(--stone);transition:transform .18s cubic-bezier(.25,1,.5,1),background .18s ease}
.sw[aria-checked="true"]{background:color-mix(in oklab, var(--moss) 22%, transparent);border-color:var(--moss)}
.sw[aria-checked="true"]::after{transform:translateX(19px);background:var(--moss)}

/* ---- sharing: Settings' switch and Today's one-time question ----
   The whole row is the switch. The two answers are the same weight: this asks,
   it doesn't steer, and Off isn't coloured like a pain answer. */
.share-row{width:100%;min-height:44px;background:none;border:0;border-bottom:1px solid var(--line);
  color:inherit;font:inherit;text-align:left;cursor:pointer}
.share-row[aria-checked="true"] .sw{background:color-mix(in oklab, var(--moss) 22%, transparent);border-color:var(--moss)}
.share-row[aria-checked="true"] .sw::after{transform:translateX(19px);background:var(--moss)}
.share-ask{background:var(--paper2);border-radius:8px;padding:12px;margin:10px 0}
.share-ask p{font-size:14px;margin:0 0 10px}
.share-btns{display:flex;gap:8px}
.share-btns .btn{flex:1;min-height:44px}
.share-card{background:var(--card);border:1px solid var(--trail);border-radius:var(--radius);
  padding:13px 14px;margin:0 0 12px}
.share-card h2{font-family:var(--display);font-size:17px;margin:0 0 6px}
.share-card p{font-size:14px;color:var(--stone);margin:0 0 10px}


/* ============================================================
   THE OCTOBER REVIEW
   Home as the daily flow, the section tab strips, and the
   accessibility fixes the five reviewers asked for.
   ============================================================ */

/* Visible only to screen readers. */
.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;
  clip:rect(0,0,0,0);white-space:nowrap;border:0}

/* Skip link: off-screen until a keyboard user tabs onto it. */
.skip{position:absolute;left:12px;top:-60px;z-index:80;background:var(--moss);color:var(--on-accent);
  font-family:var(--mono);font-size:12px;font-weight:700;padding:10px 14px;border-radius:6px;
  text-decoration:none}
.skip:focus{top:calc(env(safe-area-inset-top) + 8px)}
main:focus,#main:focus{outline:none}

/* The tab strip under a section header: Run / Bike / Swim / Lift / Mobility. */
.subtabs{border-bottom:1px solid var(--line);background:var(--paper)}
.subtabs .wrap{display:flex;gap:4px;overflow-x:auto;scrollbar-width:none}
.subtabs .wrap::-webkit-scrollbar{display:none}
.subtabs.more .wrap{mask-image:linear-gradient(to right,#000 calc(100% - 40px),transparent);
  -webkit-mask-image:linear-gradient(to right,#000 calc(100% - 40px),transparent)}
.subtabs a{flex:none;font-family:var(--mono);font-size:11px;letter-spacing:.1em;text-transform:uppercase;
  color:var(--stone);text-decoration:none;padding:12px 10px 10px;min-height:40px;
  border-bottom:2px solid transparent;font-weight:600}
.subtabs a:hover{color:var(--ink)}
.subtabs a[aria-current="page"]{color:var(--moss);border-bottom-color:var(--moss)}

/* The header rule sits inside the column rather than running under the sidebar. */
header{border-bottom:none}
header .wrap{border-bottom:2px solid var(--ink);padding-bottom:12px}
header{padding-bottom:0}

/* ---- pain flag: above everything else on a day with pain logged ---- */
.painflag{display:flex;flex-direction:column;gap:3px;border-radius:var(--radius);
  padding:12px 14px;margin:12px 0 4px;font-size:14px;line-height:1.5;border:1px solid}
.painflag b{font-family:var(--display);font-weight:700;font-size:15px;letter-spacing:0}
.painflag.amber{background:color-mix(in oklab, var(--warn) 10%, transparent);border-color:var(--warn)}
.painflag.amber b{color:var(--warn)}
.painflag.red{background:color-mix(in oklab, var(--danger) 11%, transparent);border-color:var(--danger)}
.painflag.red b{color:var(--danger)}

/* ---- first-week checklist ---- */
.onboard{background:var(--card);border:1px solid var(--moss);border-radius:var(--radius);
  padding:14px 15px;margin:12px 0 4px}
.ob-head{display:flex;justify-content:space-between;align-items:baseline;gap:10px;
  font-family:var(--display);font-size:16px;font-weight:800;letter-spacing:0}
.ob-head span{font-family:var(--mono);font-size:11px;font-weight:600;color:var(--moss);letter-spacing:.06em}
.onboard ol{list-style:none;display:flex;flex-direction:column;gap:2px;margin-top:9px}
.onboard li{display:flex;align-items:center;gap:10px;font-size:14px;min-height:36px}
.onboard li.done{color:var(--stone)}
.onboard li a{color:var(--ink);text-decoration:underline;text-decoration-color:var(--moss);
  text-underline-offset:3px;display:inline-flex;align-items:center;min-height:44px}
.ob-tick{width:20px;height:20px;border-radius:50%;background:var(--moss);color:var(--on-accent);
  font-size:12px;font-weight:800;display:grid;place-items:center;flex:none}
.ob-dot{width:20px;height:20px;border-radius:50%;border:2px solid var(--line);flex:none}
.onboard .note{margin-top:10px;line-height:1.5}

/* ---- the Today card: check, rate, challenges, log ---- */
.today-card{background:var(--card);border:1px solid var(--line);border-radius:var(--radius);
  padding:14px 15px;margin:12px 0 4px;display:flex;flex-direction:column;gap:14px}
section.today-card{border-bottom:1px solid var(--line)}
/* Not the "Today" label itself: it's a .sec-label, and this used to win and set it at 18px. */
.today-card h2:not(.sec-label){font-size:18px;margin:0}
.today-card h2.sec-label{margin:0}
.today-card > div:empty{display:none}
.today-foot{display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap;
  padding-top:12px;border-top:1px solid var(--line)}
.today-foot .btn{width:auto}
.linkish{font-family:var(--mono);font-size:12px;color:var(--stone);text-decoration:none;
  padding:8px 0;min-height:36px;display:inline-flex;align-items:center}
.linkish:hover{color:var(--ink)}

/* The check widget. One row per site; Aware or Pain opens the follow-up. */
.check{display:flex;flex-direction:column;gap:10px}
.check + .check{padding-top:12px;border-top:1px solid var(--line)}
.check-top{display:flex;align-items:center;justify-content:space-between;gap:10px;flex-wrap:wrap}
.check-top .q{font-size:15px;font-weight:600;min-width:0}
.check-btns{display:flex;gap:6px}
.check-btns .fbtn{min-height:44px;min-width:64px}
.check-more{background:var(--paper2);border-radius:8px;padding:11px 12px;display:flex;
  flex-direction:column;gap:8px}
.cm-label{font-size:13px;font-weight:600}
.cm-label span{font-family:var(--mono);font-size:10px;letter-spacing:.08em;text-transform:uppercase;
  color:var(--stone);font-weight:500;margin-left:6px}
.sev-row{display:grid;grid-template-columns:repeat(11,minmax(0,1fr));gap:4px}
.sev,.tm{font-family:var(--mono);font-size:12px;font-weight:600;min-height:36px;border-radius:6px;
  border:1px solid var(--line-strong);background:var(--card);color:var(--ink);cursor:pointer;padding:0}
.sev[aria-pressed="true"]{background:var(--warn);border-color:var(--warn);color:var(--on-accent)}
.sev[data-sev="6"][aria-pressed="true"],.sev[data-sev="7"][aria-pressed="true"],
.sev[data-sev="8"][aria-pressed="true"],.sev[data-sev="9"][aria-pressed="true"],
.sev[data-sev="10"][aria-pressed="true"]{background:var(--danger);border-color:var(--danger)}
.tm-row{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:6px}
@media (min-width:520px){.tm-row{grid-template-columns:repeat(4,minmax(0,1fr))}}
/* On a phone, eleven across is 25px a button, and a slip from 5 to 6 turns the
   pain flag red (lib/body.js). Two rows, 0–5 and 6–10, at thumb size. */
@media (max-width:519px){
  .sev-row{grid-template-columns:repeat(6,minmax(0,1fr));gap:6px}
  .sev,.tm{min-height:44px}
}
.tm{padding:0 8px;font-family:var(--text);font-size:13px}
.tm[aria-pressed="true"]{background:color-mix(in oklab, var(--moss) 16%, transparent);border-color:var(--moss);color:var(--moss)}

/* Inline session rating. */
.rate-head{font-family:var(--mono);font-size:11px;letter-spacing:.12em;text-transform:uppercase;
  color:var(--trail);font-weight:600;margin-bottom:8px}
.rate-head span{color:var(--stone);letter-spacing:.04em;text-transform:none;font-weight:500;margin-left:6px}
.rate-row{display:flex;flex-direction:column;gap:7px;padding:9px 0;border-top:1px solid var(--line)}
.rate-row:first-of-type{border-top:none;padding-top:0}
.rate-what{display:flex;justify-content:space-between;gap:10px;flex-wrap:wrap;font-size:14px}
/* Activity names are typed by people; a long unbroken one must still wrap. */
.rate-what b{min-width:0;overflow-wrap:anywhere}
.rate-what span{font-family:var(--mono);font-size:11px;color:var(--stone)}
.rate-scale{display:grid;grid-template-columns:repeat(10,minmax(0,1fr));gap:4px}
.rate-scale button{font-family:var(--mono);font-size:12px;font-weight:600;min-height:36px;
  border-radius:6px;border:1px solid var(--line-strong);background:var(--paper2);color:var(--ink);cursor:pointer}
.rate-scale button:hover{border-color:var(--moss);color:var(--moss)}

/* Today's challenges. */
.tc{display:grid;grid-template-columns:1fr auto;gap:3px 12px;align-items:center;padding:10px 12px;
  background:var(--paper2);border-radius:8px;color:var(--ink);text-decoration:none;margin-top:6px}
.tc:first-of-type{margin-top:0}
.tc-t{font-family:var(--display);font-weight:700;font-size:15px;letter-spacing:0}
.tc-done{font-family:var(--mono);font-size:10px;letter-spacing:.1em;text-transform:uppercase;
  color:var(--on-accent);background:var(--moss);border-radius:99px;padding:2px 7px;margin-left:6px;
  vertical-align:2px}
.tc-b{grid-column:1;font-size:13px;color:var(--stone)}
.tc-pill{grid-row:1 / span 2;grid-column:2;font-family:var(--mono);font-size:11px;font-weight:700;
  color:var(--gold);border:1px solid color-mix(in oklab, var(--gold) 40%, transparent);border-radius:99px;padding:3px 9px;
  white-space:nowrap}
.tc-bar{grid-column:1 / -1;height:4px;background:var(--line);border-radius:2px;overflow:hidden;margin-top:5px}
.tc-bar i{display:block;height:100%;background:var(--moss);border-radius:2px;
  transform-origin:left;animation:barfill .8s cubic-bezier(.22,.9,.3,1) both}

/* ---- the stat row ---- */
.hero-stats{margin:12px 0 6px}
.hero-stats a.stat:hover{border-color:var(--line-hi)}
.stat .lbl{display:flex;align-items:center;gap:6px;overflow:visible}
.stat .lbl,.stat .sub{white-space:normal}
.small-cta{font-family:var(--text);font-size:14px;font-weight:700;color:var(--moss);letter-spacing:0}
.mini-ring{width:44px;height:44px}
.info{width:24px;height:24px;flex:none;border-radius:50%;border:1px solid var(--line);
  background:var(--paper2);color:var(--stone);font-family:var(--mono);font-size:11px;
  font-weight:700;cursor:pointer;display:inline-grid;place-items:center;padding:0;
  text-transform:none;margin:-4px 0}
.info:hover{color:var(--ink);border-color:var(--stone)}
.tip{position:absolute;z-index:20;left:-1px;right:-1px;top:calc(100% + 6px);
  min-width:220px;background:#221D40;border:1px solid var(--line);border-radius:8px;padding:10px 12px;
  font-size:13px;line-height:1.5;color:var(--ink);box-shadow:0 12px 28px rgba(0,0,0,.5)}
@media (max-width:519px){
  .hero-stats{gap:6px}
  .stat{padding:10px}
  .stat .val{font-size:26px;min-height:44px}
  .stat .lbl{font-size:10px;letter-spacing:.04em}
  .tip{left:auto;right:-60px;width:min(78vw,280px)}
}
.home-pair{margin-top:6px}

/* The countdown now carries the verdict, so it wraps on a phone. */
.racestrip{align-items:center}
.racestrip .l{line-height:1.35}

/* Footer label in the sidebar. */
.foot-k{font-family:var(--mono);font-size:10px;letter-spacing:.12em;text-transform:uppercase;
  color:var(--stone);margin-right:4px}

/* Bigger targets on the bottom tabs, and their labels clear the 10px floor. */
.tabs a{min-height:52px;justify-content:center}

/* Desktop: Home becomes two columns — the day on the left, the numbers right. */
@media (min-width:1100px){
  .home-grid{display:grid;grid-template-columns:minmax(0,1.15fr) minmax(0,1fr);gap:0 22px;
    align-items:start}
}


/* ============================================================
   AVATAR, RIVALRY, LOOT
   ============================================================ */

/* The card's portrait is the avatar now: a small stage, framed in the tier colour. */
.pcard a.port{width:104px;height:104px;border-radius:16px;margin:0 auto 9px;display:grid;place-items:center;
  background:radial-gradient(90% 80% at 50% 30%,var(--stage-hi),var(--stage-lo) 75%);box-shadow:none;
  border:2px solid rgba(255,255,255,.08);text-decoration:none;color:var(--ink);font-size:23px}
.pcard[data-tier="2"] a.port{border-color:color-mix(in oklab, var(--moss) 45%, transparent)}
.pcard[data-tier="3"] a.port{border-color:color-mix(in oklab, var(--cool) 50%, transparent)}
.pcard[data-tier="4"] a.port{border-color:color-mix(in oklab, var(--gold) 60%, transparent);box-shadow:0 0 18px color-mix(in oklab, var(--gold) 18%, transparent)}
.pcard a.port .av{width:96px;height:96px}
.pcard a.port.is3d{display:block;position:relative;overflow:hidden}
.pcard a.port.is3d canvas{display:block;border-radius:14px}
.pcard a.port:hover{border-color:var(--moss)}
.pcard a.port img.av3p{width:96px;height:96px;border-radius:12px}

/* Phones: Today is for today. The card shrinks to one block about 150px tall
   (portrait left; name, rank and the next level beside it; the ring small on
   the right; level chips under) so the check-in is on the first screen,
   one-handed after a run (PRODUCT.md). The badge shelf lives on Athletes and
   the XP total in the Locker; the header is for screen readers only. */
@media (max-width:519px){
  .home-head{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;
    clip:rect(0,0,0,0);white-space:nowrap;border:0}
  #signedIn{padding-top:12px}
  .pcard-in{display:grid;grid-template-columns:64px minmax(0,1fr) 60px;
    grid-template-areas:"port nm ring" "port rank ring" "port next ring" "chips chips chips";
    gap:2px 12px;align-items:center;text-align:left;padding:12px 12px 11px}
  .pcard a.port{grid-area:port;width:64px;height:64px;margin:0;border-radius:12px}
  .pcard a.port .av,.pcard a.port img.av3p{width:58px;height:58px}
  .pcard .nm{grid-area:nm;font-size:17px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  .pcard .rankline{grid-area:rank;margin:0}
  .pcard .tonext{grid-area:next;margin:0}
  .pcard .ringwrap{grid-area:ring;width:60px;margin:0}
  .pcard .ringwrap svg{width:60px;height:60px}
  .pcard .ringtxt b{font-size:15px}
  .pcard .ringtxt span span{display:none}
  .pcard .chips{grid-area:chips;justify-content:flex-start;margin-top:9px}
  .pcard .xpline,.pcard .shelf{display:none}
}
.av{display:block;image-rendering:pixelated;overflow:hidden}
/* Rendered 3D item icons are photos, not pixel art. */
.av.av3i{image-rendering:auto;object-fit:contain}
.av.av3p{image-rendering:auto;object-fit:cover;border-radius:inherit}

/* Weekly rivalry */
.riv{background:var(--card);border:1px solid var(--line);border-radius:var(--radius);
  padding:12px 14px;margin:10px 0 4px}
section.riv{border-bottom:1px solid var(--line)}
.riv.ahead{border-color:color-mix(in oklab, var(--moss) 50%, transparent)}
.riv.behind{border-color:color-mix(in oklab, var(--trail) 50%, transparent)}
.riv-top{display:flex;justify-content:space-between;align-items:baseline;gap:8px}
.riv-top .sec-label{margin-bottom:4px}
.riv-pts{font-family:var(--mono);font-size:11px;color:var(--gold)}
.riv-v{font-family:var(--display);font-size:18px;font-weight:800;letter-spacing:0;margin-bottom:8px}
.riv-v span{font-weight:600;color:var(--stone);font-size:15px}
.riv.ahead .riv-v{color:var(--moss)}
.riv.behind .riv-v{color:var(--trail)}
.riv-row{display:grid;grid-template-columns:62px 1fr 44px;gap:8px;align-items:center;margin-top:5px}
.riv-n{font-size:13px;font-weight:600;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.riv-p{font-family:var(--mono);font-size:12px;font-weight:700;text-align:right}
.riv-bar{position:relative;height:8px;background:var(--paper2);border-radius:4px;overflow:visible}
.riv-bar i{display:block;height:100%;border-radius:4px;background:var(--moss);
  transform-origin:left;animation:barfill .8s cubic-bezier(.22,.9,.3,1) both}
.riv-row + .riv-row .riv-bar i{background:var(--stone)}
.riv-bar b{position:absolute;top:-3px;bottom:-3px;width:2px;background:var(--ink);opacity:.55}
.riv-sub{font-size:12px;color:var(--stone);margin-top:8px;line-height:1.5}
.riv-last{font-family:var(--mono);font-size:11px;color:var(--stone);margin-top:6px}
.riv-bye{font-size:13.5px;color:var(--stone)}
/* Easing off this week (a pain flag or a recovery week): calm, never alarming. */
.riv-ease{font-size:13px;color:var(--ink);margin:6px 0 2px;padding:6px 10px;border-left:2px solid var(--moss2)}

/* Loot reveal */
/* A <dialog> arrives with a UA border, padding, background and a width cap,
   and showModal() centres it in the top layer. Strip the box, let it fill the
   viewport as before, and move the scrim to ::backdrop where it belongs —
   which is also what makes the page behind it inert. */
dialog.loot{position:fixed;inset:0;z-index:75;display:none;place-items:center;padding:20px;
  max-width:100vw;max-height:100dvh;width:100%;height:100%;border:0;background:transparent;
  color:var(--ink);overflow:auto;overscroll-behavior:contain}
dialog.loot[open]{display:grid}
dialog.loot::backdrop{background:rgba(9,7,18,.82)}
.loot-card{width:min(340px,100%);background:var(--card);border:1px solid var(--line);border-radius:16px;
  padding:22px 20px 18px;text-align:center}
.loot-card.rare{border-color:var(--cool);box-shadow:0 0 40px color-mix(in oklab, var(--cool) 18%, transparent)}
.loot-card.epic{border-color:var(--boss);box-shadow:0 0 50px color-mix(in oklab, var(--boss) 24%, transparent)}
.loot-card.legendary{border-color:var(--gold);box-shadow:0 0 70px color-mix(in oklab, var(--gold) 30%, transparent);
  background:linear-gradient(180deg,color-mix(in oklab, var(--gold) 14%, transparent),var(--card) 60%)}
.loot-k{font-family:var(--mono);font-size:11px;letter-spacing:.24em;text-transform:uppercase;color:var(--stone)}
.loot-item{width:150px;height:150px;margin:10px auto 6px;border-radius:14px;display:grid;place-items:center;
  background:radial-gradient(80% 70% at 50% 40%,var(--stage-hi),var(--stage-lo) 80%)}
.loot-item .av{width:132px;height:132px}
.loot-name{font-family:var(--display);font-size:22px;font-weight:800;letter-spacing:0}
.loot-rar{font-family:var(--mono);font-size:11px;letter-spacing:.14em;text-transform:uppercase;margin-top:3px;
  color:var(--r-common)}
.loot-card.rare .loot-rar{color:var(--cool)}
.loot-card.epic .loot-rar{color:var(--epic)}
.loot-card.legendary .loot-rar{color:var(--gold)}
.loot-why{font-size:13.5px;color:var(--stone);margin-top:8px}
.loot-count{font-family:var(--mono);font-size:11px;color:var(--stone);margin-top:4px;min-height:14px}
.loot-acts{display:flex;gap:8px;margin-top:14px}
.loot-acts .btn{flex:1}
.btn.alt.loot-all{margin-top:8px;width:100%;color:var(--ink);border-color:var(--line)}
@keyframes lootpop{0%{transform:scale(.86) rotate(-2deg);opacity:0}100%{transform:none;opacity:1}}
.loot-card.pop{animation:lootpop .45s cubic-bezier(.16,1,.3,1)}
@keyframes shine{0%,100%{filter:brightness(1)}50%{filter:brightness(1.35)}}
.loot-card.legendary.pop .loot-item{animation:shine 1.4s ease-in-out 2}

/* ---- the item card (js/item-card.js): the loot dialog, with room to read ---- */
.loot-card.icard{width:min(380px,100%);padding:18px 18px 16px}
.ic-stage{position:relative;width:min(220px,62vw);aspect-ratio:1;margin:0 auto 10px;border-radius:14px;display:grid;place-items:center;
  overflow:hidden;background:radial-gradient(80% 70% at 50% 40%,var(--stage-hi),var(--stage-lo) 80%)}
.ic-stage > .av{width:72%;height:72%}
.ic-stage.is3d > .av{visibility:hidden}
.ic-3d{position:absolute;inset:0}
.ic-3d .av3d{display:block;touch-action:none;cursor:grab}
.ic-3d .av3d:active{cursor:grabbing}
.ic-3d .av3d:focus-visible{outline:2px solid var(--moss2);outline-offset:-2px}
/* The folklore line: the campfire voice gets a gold rule, not italics (none is shipped). */
.ic-lore{margin:12px 0 2px;padding:6px 0 6px 12px;border-left:2px solid var(--gold);text-align:left;
  font-size:15px;line-height:1.45;color:var(--ink)}
.ic-lore:empty{display:none}
.ic-facts{margin:12px 0 0;text-align:left;display:grid;gap:7px}
.ic-facts div{display:grid;grid-template-columns:82px minmax(0,1fr);gap:10px;font-size:13.5px;line-height:1.4}
.ic-facts dt{font-family:var(--mono);font-size:10px;letter-spacing:.1em;text-transform:uppercase;color:var(--stone);padding-top:2px}
.ic-facts dd{margin:0;color:var(--ink);overflow-wrap:anywhere}
.ic-facts .sub{display:block;font-size:12px;color:var(--stone);margin-top:1px}
@media (max-height:700px){.ic-stage{width:min(170px,48vw)}}
/* Dyes on the card: round swatches, the price on ones you don't have yet. */
.ic-dyes{margin-top:12px;text-align:left}
.ic-dyes-h{font-family:var(--mono);font-size:10px;letter-spacing:.1em;text-transform:uppercase;color:var(--stone);margin-bottom:7px}
.ic-dyes-h span{font-family:var(--text);font-size:13px;letter-spacing:0;text-transform:none;color:var(--ink);margin-left:6px}
.ic-dye-row{display:flex;flex-wrap:wrap;gap:7px}
.dy{position:relative;width:36px;height:36px;padding:3px;border-radius:50%;border:2px solid var(--line-strong);
  background:var(--well);cursor:pointer;display:grid;place-items:center}
.dy i{display:block;width:100%;height:100%;border-radius:50%}
.dy.none i{background:repeating-linear-gradient(45deg,var(--stone) 0 2px,transparent 2px 6px)}
.dy[aria-pressed="true"]{border-color:var(--ink);box-shadow:0 0 0 2px var(--moss)}
.dy.locked i{opacity:.45}
.dy.locked span{position:absolute;right:-6px;bottom:-5px;font-family:var(--mono);font-size:10px;line-height:1.3;
  padding:0 3px;border-radius:6px;background:var(--card);color:var(--sweat);border:1px solid color-mix(in oklab, var(--sweat) 40%, transparent)}
.dy[data-armed]{border-color:var(--sweat)}
.ic-dye-note{font-size:12px;color:var(--stone);margin-top:7px}

/* Small avatars beside names */
.mini-av{flex:none;width:40px;height:40px;border-radius:10px;background:#1C2026;display:grid;place-items:center;
  border:1px solid var(--line);overflow:hidden}
.mini-av .av{width:38px;height:38px}


/* ---- season card sheet ---- */
.sc-wrap{width:min(420px,100%);display:flex;flex-direction:column;gap:10px}
.sc-wrap img{width:100%;height:auto;border-radius:14px;display:block;box-shadow:0 20px 50px rgba(0,0,0,.6)}
.sc-wrap .btn{text-align:center;text-decoration:none}

/* ---- trade note on Home ---- */
.tradenote{display:block;background:color-mix(in oklab, var(--sweat) 10%, transparent);border:1px solid color-mix(in oklab, var(--sweat) 45%, transparent);border-radius:var(--radius);
  padding:10px 12px;margin:9px 0 2px;color:var(--sweat);font-weight:600;font-size:14px;text-decoration:none}

/* ---- Sweat ---- */
/* Not `.sw`: that is the toggle switch, and its fixed width and knob leaked in. */
/* Beside the pass strip on Today, opening the Shop. It used to be a fifth
   chip among the levels, in nearly Bike's blue, though it isn't a level. */
.passrow{display:flex;gap:8px;align-items:stretch;margin:9px 0 2px}
.passrow .passstrip{flex:1;min-width:0;margin:0}
.sweatpill{flex:none;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:3px;
  min-width:68px;min-height:44px;padding:6px 10px;border-radius:var(--radius);text-decoration:none;color:var(--sweat);
  background:color-mix(in oklab, var(--sweat) 10%, transparent);border:1px solid color-mix(in oklab, var(--sweat) 40%, transparent)}
.sweatpill b{font-family:var(--display);font-size:18px;line-height:1;font-variant-numeric:tabular-nums}
.sweatpill span{font-family:var(--mono);font-size:10px;letter-spacing:.12em;text-transform:uppercase}
.sweatpill:hover{border-color:var(--sweat)}
.repair{display:flex;align-items:center;justify-content:space-between;gap:10px;flex-wrap:wrap;background:color-mix(in oklab, var(--sweat) 8%, transparent);
  border:1px solid color-mix(in oklab, var(--sweat) 40%, transparent);border-radius:var(--radius);padding:10px 12px;margin:8px 0 4px;font-size:13.5px}
.repair .btn{width:auto}
.q-swap{display:block;margin:4px 0 0 auto;font-family:var(--mono);font-size:10px;letter-spacing:.06em;text-transform:uppercase;
  color:var(--sweat);background:none;border:1px solid color-mix(in oklab, var(--sweat) 40%, transparent);border-radius:6px;padding:4px 8px;min-height:26px;cursor:pointer}

/* ---- season pass strip, quests, monthly boss ---- */
.passstrip{display:grid;grid-template-columns:auto auto 1fr;gap:4px 10px;align-items:center;
  background:var(--card);border:1px solid var(--line);border-radius:var(--radius);padding:9px 12px;
  margin:9px 0 2px;color:var(--ink);text-decoration:none}
.passstrip:hover{border-color:var(--line-hi)}
.ps-k{font-family:var(--mono);font-size:10px;letter-spacing:.14em;text-transform:uppercase;color:var(--gold);font-weight:700}
.ps-t{font-family:var(--mono);font-size:12px;color:var(--stone)}
.ps-t b{color:var(--ink);font-size:14px}
.ps-bar{height:6px;background:var(--paper2);border-radius:3px;overflow:hidden}
.ps-bar i{display:block;height:100%;background:linear-gradient(90deg,var(--gold),#FFE29A);border-radius:3px}
.ps-n{grid-column:1 / -1;font-size:12px;color:var(--stone)}

.quests{background:var(--card);border:1px solid var(--line);border-radius:var(--radius);padding:12px 14px;margin:10px 0 4px}
section.quests{border-bottom:1px solid var(--line)}
.q-top{display:flex;justify-content:space-between;align-items:baseline;gap:8px;flex-wrap:wrap}
.q-c{font-family:var(--mono);font-size:11px;color:var(--gold)}
.quest{display:grid;grid-template-columns:22px 1fr auto;gap:10px;align-items:center;padding:8px 0;border-top:1px solid var(--line)}
.quest:first-of-type{border-top:none}
.q-tick{width:20px;height:20px;border-radius:50%;border:2px solid var(--line);display:grid;place-items:center;
  font-size:12px;font-weight:800;color:var(--on-accent)}
.quest.done .q-tick{background:var(--moss);border-color:var(--moss)}
.q-body{display:flex;flex-direction:column;min-width:0}
.q-body b{font-size:14px}
.q-body span{font-size:12px;color:var(--stone)}
.quest.done .q-body b{color:var(--stone);text-decoration:line-through;text-decoration-color:var(--moss)}
.q-v{font-family:var(--mono);font-size:11px;color:var(--stone);white-space:nowrap}
.quest.done .q-v{color:var(--moss);font-weight:700}

.bossc{background:linear-gradient(180deg,color-mix(in oklab, var(--boss) 10%, transparent),var(--card) 60%);border:1px solid color-mix(in oklab, var(--boss) 45%, transparent);
  border-radius:var(--radius);padding:12px 14px;margin:10px 0 4px}
section.bossc{border-bottom:1px solid color-mix(in oklab, var(--boss) 45%, transparent)}
.bossc.beaten{border-color:var(--moss)}
.b-title{font-family:var(--display);font-size:20px;font-weight:800;letter-spacing:0}
.b-blurb{font-size:12.5px;color:var(--stone);margin-top:2px}
.b-eased{font-size:12px;color:var(--stone);margin:6px 0 0}
.b-bar{height:10px;background:var(--paper2);border-radius:5px;overflow:hidden;margin:10px 0 6px}
.b-bar i{display:block;height:100%;background:linear-gradient(90deg,#8A5CD0,var(--epic));border-radius:5px;
  transform-origin:left;animation:barfill .8s cubic-bezier(.22,.9,.3,1) both}
.bossc.beaten .b-bar i{background:var(--moss)}
.b-meta{display:flex;justify-content:space-between;font-family:var(--mono);font-size:11px;color:var(--stone)}
.b-meta b{color:var(--ink)}
.b-people{display:flex;flex-wrap:wrap;gap:6px 14px;margin-top:8px;font-size:12px;color:var(--stone)}
.b-people > span{display:inline-flex;align-items:center;gap:6px}
/* A small avatar in a list row (boss contributors, challenge standings). */
.bav{flex:none;display:inline-grid;place-items:center;border-radius:6px;overflow:hidden;background:var(--paper2);
  border:1px solid var(--line);vertical-align:middle}
.bav .av{display:block}
.b-people b{color:var(--ink);font-family:var(--mono);font-size:11px}
.b-people .you{color:var(--ink)}

/* THE OVERRIDE. Anything added above must remain fully usable once this
   strips the movement out — motion may carry emphasis, never meaning. */
@media (prefers-reduced-motion: reduce){
  *,*::before,*::after{animation:none!important;transition:none!important}
  .toast{opacity:1;transform:none}
  .lu-card{transform:none}
  .skel{background:var(--card)}
}
@media (min-width:1100px){
  .home-r .home-pair{display:block}
  .home-r .hero-stats{margin-top:13px}
}

/* ---- tap targets ----
   PRODUCT.md: "one-handed on a phone after a run". Icon controls keep their
   size and get an invisible 44px hit area; text controls simply grow. */
.acct-btn,.burger,.nav-back,.drawer-close,.info{position:relative}
.acct-btn::after,.burger::after,.nav-back::after,.drawer-close::after,.info::after{
  content:'';position:absolute;left:50%;top:50%;width:44px;height:44px;transform:translate(-50%,-50%)}
.rate-scale button{min-height:44px}
.drawer-links a,.side-links a{min-height:44px}
.drawer-sync,.drawer-out{min-height:44px;display:flex;align-items:center;justify-content:center}
.acct-signin{display:inline-flex;align-items:center;min-height:44px;padding:0 4px}
.q-swap{min-height:36px;padding:6px 10px}
.btn.small{min-height:36px}
.text-link{display:inline-flex;align-items:center;min-height:44px}
/* Secondary controls: toggles, filters, tabs, row actions. `body` lifts these
   over the page-level rules that set their padding. */
body .tg,body .filters button,body button.bdg,body .tab2,body button.more,body .gacts button,
body button.del,body #saveBio{min-height:36px}

/* ============================================================
   ARCADE NIGHT — the few places that glow.
   Glow marks the thing to press or the thing you're chasing:
   the primary button, the XP ring, the current tab, a rivalry
   you're winning. Everything else stays flat.
   ============================================================ */
.btn:not(.alt){box-shadow:var(--glow)}
.btn:not(.alt):disabled{box-shadow:none}
.pcard #pRing{filter:drop-shadow(0 0 6px color-mix(in oklab, var(--moss) 55%, transparent))}
.tabs a[aria-current="page"] .ic{text-shadow:0 0 12px color-mix(in oklab, var(--moss) 70%, transparent)}
.riv.ahead{box-shadow:0 0 22px color-mix(in oklab, var(--moss) 14%, transparent)}
/* Your rival's bar is the second colour, so the card reads as two sides. */
.riv-row.them .riv-bar i,.riv-row + .riv-row .riv-bar i{background:var(--trail)}
.riv-v{text-transform:uppercase;letter-spacing:.02em}
.riv-v span{text-transform:none;letter-spacing:0}

/* Faces on the rivalry card: a small avatar before each name. */
.riv-row.av{grid-template-columns:30px 62px minmax(0,1fr) 44px}
.riv-av{width:30px;height:30px;border-radius:8px;background:var(--paper2);border:1px solid var(--line);
  overflow:hidden;display:grid;place-items:center;flex:none}
.riv-av .av,.riv-av img{width:28px;height:28px;display:block}
.riv-av-none{display:block;width:100%;height:100%}

/* Team week: a tug bar for the two averages, then each team's people. */
.tug{display:grid;grid-template-columns:44px minmax(0,1fr) 44px;gap:8px;align-items:center;margin:4px 0 10px}
.tug-l,.tug-r{font-family:var(--mono);font-size:13px;font-weight:700}
.tug-l{color:var(--moss)}
.tug-r{color:var(--trail);text-align:right}
.tug-bar{position:relative;height:10px;border-radius:5px;background:var(--trail);overflow:hidden}
.tug-bar i{display:block;height:100%;background:var(--moss);transition:width .4s}
.tug-bar b{position:absolute;top:0;bottom:0;left:50%;width:2px;margin-left:-1px;background:var(--paper)}
.tw-teams{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:10px}
.tw-team{min-width:0}
.tw-h{display:flex;justify-content:space-between;gap:6px;font-family:var(--display);font-size:13px;font-weight:700;
  padding-bottom:4px;border-bottom:2px solid var(--moss);margin-bottom:4px}
.tw-team.theirs .tw-h{border-bottom-color:var(--trail)}
.tw-h span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.tw-h b{font-family:var(--mono);font-size:12px}
.tw-list{list-style:none}
.tw{display:grid;grid-template-columns:30px minmax(0,1fr) auto;gap:8px;align-items:center;padding:3px 0;font-size:13px}
.tw.you .tw-n{color:var(--moss);font-weight:700}
.tw-n{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.tw-n small{display:block;font-size:11px;color:var(--stone);white-space:normal}
.tw-p{font-family:var(--mono);font-size:12px;font-weight:700}
.tw.out .tw-p{color:var(--stone);font-weight:400}
@media (prefers-reduced-motion:reduce){.tug-bar i{transition:none}}

/* Today's three-line summary of the week's game. Each row opens Compete. */
.gstrip{background:var(--card);border:1px solid var(--line);border-radius:var(--radius);
  padding:12px 14px 6px;margin:10px 0 4px}
section.gstrip{border-bottom:1px solid var(--line)}
.gstrip .linkish{font-family:var(--mono);font-size:11px;color:var(--trail);text-decoration:none}
.gs-row{display:grid;grid-template-columns:62px minmax(0,1fr) auto;gap:10px;align-items:center;
  min-height:44px;padding:6px 0;border-top:1px solid var(--line);color:var(--ink);text-decoration:none}
.gs-row:first-of-type{border-top:none}
.gs-k{font-family:var(--mono);font-size:10px;letter-spacing:.12em;text-transform:uppercase;color:var(--stone)}
.gs-v{font-size:13.5px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.gs-p{font-family:var(--mono);font-size:11px;font-weight:700;color:var(--gold)}
.gs-row.ahead .gs-v{color:var(--moss)}
.gs-row.behind .gs-v{color:var(--trail)}
.week-game > div:empty{display:none}

/* Between seasons: one card at the top of Today. */
.preseason{background:linear-gradient(160deg,color-mix(in oklab, var(--trail) 12%, transparent),var(--card) 65%);
  border:1px solid color-mix(in oklab, var(--trail) 45%, transparent);border-radius:var(--radius);padding:14px 16px;margin:14px 0 4px}
section.preseason{border-bottom:1px solid color-mix(in oklab, var(--trail) 45%, transparent)}
.preseason .ps-eyebrow{font-family:var(--mono);font-size:10px;letter-spacing:.2em;text-transform:uppercase;color:var(--trail)}
.preseason h2{font-size:20px;margin:4px 0 6px}
.preseason p{font-size:13.5px;color:var(--stone);max-width:62ch}

/* ---- platform behaviour -------------------------------------------------
   Cross-document view transitions. The app is deliberately multi-page — every
   page keeps its own URL — which is exactly the case this was built for, so
   moving between tabs crossfades instead of blinking. Chromium and Safari
   honour it; Firefox ignores it and navigates instantly, which is what it does
   today, so there is nothing to fall back to. Behind a reduced-motion guard:
   under "reduce" the whole at-rule is absent and navigation is instant again.
   The tab bar is named so it stays put while the content underneath changes,
   rather than crossfading with it. */
@media (prefers-reduced-motion: no-preference) {
  @view-transition { navigation: auto }
  .tabs{view-transition-name:tabs}
  .topbar{view-transition-name:topbar}
}

/* Keep the platform's own pull-to-refresh and stop inner scrollers chaining
   into it: reaching the end of a chart's horizontal scroll or a modal body
   should do nothing, not bounce the page. On a mouse, kill the rubber-band
   entirely — it only ever looks like a bug on a desktop. */
.chart-card .scroll,.drawer,.sheet{overscroll-behavior:contain}
@media (pointer: fine) { html,body{overscroll-behavior:none} }

/* Rotating copy (voice.js picks a different line every day) sets its own line
   breaks, so balance them rather than leaving one orphan word on line two. */
.banner,.note,.empty-rich .h,.tc-t,.gs-k{text-wrap:pretty}
h1,h2,.sec-label,.empty-rich .h{text-wrap:balance}

/* ---- the words under a chart -------------------------------------------
   Every chart carries one sentence describing its trend, and the numbers
   themselves behind a closed <details>. The sentence is visible rather than
   hidden in a <desc>, because it is as useful to someone reading the chart as
   to someone who cannot see it — and one copy of the text cannot drift from
   another. The SVG points at it with aria-describedby. */
.chart-sum{font-size:12px;color:var(--stone);margin:6px 0 0;line-height:1.45;text-wrap:pretty}
.chart-data{margin-top:6px}
.chart-data summary{font-size:11px;color:var(--trail);cursor:pointer;
  font-family:var(--mono);letter-spacing:.04em;padding:4px 0;min-height:44px;
  display:flex;align-items:center}
.chart-data table{width:100%;margin-top:4px;font-size:12px}
.chart-data th,.chart-data td{padding:4px 6px;border-bottom:1px solid var(--line);text-align:left}
.chart-data thead th{font-family:var(--mono);font-size:10px;letter-spacing:.1em;
  text-transform:uppercase;color:var(--stone)}
.chart-data tbody th{font-weight:400;color:var(--stone);font-family:var(--mono)}
.chart-data td{font-family:var(--mono);color:var(--ink)}
