/* ═══════════════════════════════════════════════════════════════════════════
   STORM LANE — FACET

   Cut stone. Nothing in this app is a plain rectangle and nothing is round:
   every surface is a chamfered polygon, and the chamfers of neighbouring
   panels open diagonal slivers of ground between them. That sliver is the
   spacing system.

   The rules this sheet keeps, without exception:

     · RADIUS IS 0. Shape comes from clip-path, so the cut is real geometry and
       the hit area is the shape you can see. Every panel carries at least one
       corner cut, --c, and 12px is the house cut.
     · ELEVATION IS FACET SHADING, not shadow. There is no box-shadow anywhere
       in this file. A panel is lifted by splitting one shape into two tones
       across a 45 degree hard stop, parallel to its own chamfer, so the light
       reads as falling on a cut face.
     · CUTS POINT. On anything you can press, the chamfer sits on the side the
       action goes: bottom right on a blade, so the arrow leaves through it.
     · TYPE IS ONE SHARP GROTESQUE, tracked in at display size and tracked out
       hard at label size. Figures are the canvas face, so a millisecond in the
       chrome is the same shape as the millisecond printed in the gate.
     · MOTION IS 160ms AND DIAGONAL. Things arrive along the cut, never fade up
       from below, and nothing loops.
   ═══════════════════════════════════════════════════════════════════════════ */

:root {
  /* Written from JS by applySafeArea(). 0 outside Telegram fullscreen, so
     every utility that reads them collapses on its own. */
  --tg-safe-top: 0px;
  --tg-safe-bottom: 0px;

  /* Duplicated from brand.js so the splash paints correctly on frame one,
     before shell.js has stamped the palette onto <html>. */
  --bg:       #0B0F14;
  --surface:  #141B23;
  --tint:     #1C2530;
  --tint-2:   #2A3745;
  --line:     #3A4B5C;
  --ink:      #E8F1F5;
  --ink-2:    #9DAFBC;
  --ink-3:    #72858F;
  --accent:   #2BC4D8;
  --accent-d: #86E4F0;
  --good:     #3ED9A0;
  --warn:     #FF5E7A;

  --f:   "Space Grotesk", "Helvetica Neue", Arial, sans-serif;
  --f-n: "Chakra Petch", "Space Grotesk", ui-monospace, sans-serif;

  --c: 12px;                        /* THE cut. Overridden per panel. */
  --t: 160ms cubic-bezier(.2, .75, .25, 1);

  /* The cuts. Each resolves --c on the element that uses it, so one token set
     covers a 26px play face and an 8px avatar without a second definition. */
  --x-tlbr: polygon(var(--c) 0, 100% 0, 100% calc(100% - var(--c)), calc(100% - var(--c)) 100%, 0 100%, 0 var(--c));
  --x-trbl: polygon(0 0, calc(100% - var(--c)) 0, 100% var(--c), 100% 100%, var(--c) 100%, 0 calc(100% - var(--c)));
  --x-tl:   polygon(var(--c) 0, 100% 0, 100% 100%, 0 100%, 0 var(--c));
  --x-br:   polygon(0 0, 100% 0, 100% calc(100% - var(--c)), calc(100% - var(--c)) 100%, 0 100%);
  --x-para: polygon(var(--c) 0, 100% 0, calc(100% - var(--c)) 100%, 0 100%);
  --x-dia:  polygon(50% 0, 100% 50%, 50% 100%, 0 50%);

  /* The two-tone faces. The hard stop runs at 45 degrees, parallel to every
     chamfer on the panel, and the lit tone is always on the cut-away side. */
  --face-1: linear-gradient(135deg, var(--tint) 0 44%, var(--surface) 44%);
  --face-2: linear-gradient(135deg, var(--tint-2) 0 44%, var(--tint) 44%);
  --face-3: linear-gradient(135deg, var(--accent) 0 44%, #21A7B8 44%);
}

*, *::before, *::after { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }

/* Overlays set their own display, which outranks the UA rule for [hidden]. */
[hidden] { display: none !important; }

html, body {
  margin: 0; padding: 0; height: 100%;
  background: var(--bg);
  overscroll-behavior: none;
  -webkit-overflow-scrolling: touch;
}

body {
  font-family: var(--f);
  font-weight: 400;
  color: var(--ink);
  font-size: 15px;
  line-height: 1.45;
  -webkit-font-smoothing: antialiased;
}

button, input { font: inherit; color: inherit; }
button { border: 0; background: none; padding: 0; cursor: pointer; }

/* ── glyphs: filled polygons, holes punched with evenodd ─────────────────── */

.pgs { position: absolute; width: 0; height: 0; overflow: hidden; }

.pg {
  display: block; flex: none;
  width: 22px; height: 22px;
  fill: currentColor;
  fill-rule: evenodd;
  stroke: none;
}
.pg-s { width: 16px; height: 16px; }

/* ── type roles ──────────────────────────────────────────────────────────── */

.kick {
  margin: 0;
  font-size: 10px; font-weight: 700;
  letter-spacing: 0.22em; text-transform: uppercase;
  color: var(--ink-3);
}

.say {
  margin: 8px 0 0;
  font-size: 13.5px; line-height: 1.5;
  color: var(--ink-2);
}
.say--lead { font-size: 14.5px; color: var(--ink-2); }
.say--fine { font-size: 12.5px; color: var(--ink-3); }

.fine {
  margin: 6px 0 4px;
  font-size: 11.5px; line-height: 1.5;
  color: var(--ink-3);
}

/* ── press: a sharp slide down the diagonal, never a scale ───────────────── */

.hit { transition: transform var(--t), background var(--t), color var(--t); }
.hit:active { transform: translate(1.5px, 1.5px); }

/* ── blades: the pressable block. The cut is bottom right, on the side the
      action leaves through, and the arrow leaves through it. ─────────────── */

.blade {
  --c: 15px;
  position: relative;
  display: flex; align-items: center; justify-content: center; gap: 9px;
  width: 100%;
  padding: 13px 17px;
  background: var(--accent);
  color: var(--bg);
  clip-path: var(--x-br);
  font-size: 14px; font-weight: 700;
  letter-spacing: -0.01em;
}
/* Hairline variant. A clipped shape cannot carry a border on its diagonals, so
   the edge is the panel itself and the fill is an inset layer under the text. */
.blade--ghost { background: var(--line); color: var(--ink); }
.blade--ghost::before {
  content: ""; position: absolute; inset: 1.5px;
  background: var(--surface);
  clip-path: var(--x-br);
}
.blade--ghost > * { position: relative; }
.blade--sm { --c: 10px; width: auto; flex: none; padding: 9px 13px; font-size: 12.5px; gap: 7px; }
.blade--ad { justify-content: flex-start; text-align: left; align-items: flex-start; margin-top: 10px; }
.blade:disabled { opacity: .5; }

.ad-t { position: relative; display: flex; flex-direction: column; gap: 3px; }
.ad-t b { font-size: 13.5px; font-weight: 700; }
.ad-t i { font-style: normal; font-size: 11.5px; font-weight: 400; color: var(--ink-2); }
.ad-t i:empty { display: none; }

/* ── knobs: the chamfered icon square, edge first, fill inset ────────────── */

.knob {
  --c: 10px;
  position: relative; flex: none;
  width: 38px; height: 38px;
  display: grid; place-items: center;
  background: var(--line);
  clip-path: var(--x-tlbr);
  color: var(--ink);
}
.knob::before {
  content: ""; position: absolute; inset: 1.5px;
  background: var(--surface);
  clip-path: var(--x-tlbr);
}
.knob .pg { position: relative; }
/* The pause control is the player's only way out of a round, so it is cut in
   the accent and never blended into the dark HUD. */
.knob--lit { background: var(--accent); color: var(--accent-d); }
.knob--lit::before { background: var(--tint-2); }

/* ── tags: chamfered, never a pill ───────────────────────────────────────── */

.tag {
  --c: 6px;
  display: inline-flex; align-items: center; gap: 5px;
  padding: 5px 11px;
  background: var(--tint-2);
  clip-path: var(--x-tlbr);
  color: var(--accent-d);
  font-size: 11px; font-weight: 700;
  letter-spacing: 0.1em; text-transform: uppercase;
  white-space: nowrap;
}
.tag--x { background: var(--accent); color: var(--bg); font-size: 14px; letter-spacing: 0; opacity: 0; transition: opacity var(--t); }
.tag--x.is-on { opacity: 1; }
.tag--warn { color: var(--warn); background: var(--tint); padding: 8px; }
.tag--warn .pg { width: 20px; height: 20px; }

/* ── gauges: a parallelogram, filled from the left ───────────────────────── */

.gauge {
  --c: 7px;
  height: 14px;
  background: var(--tint);
  clip-path: var(--x-para);
}
.gauge i {
  display: block; height: 100%; width: 0;
  background: var(--accent);
  transition: width var(--t), background var(--t);
}
.gauge i.is-low { background: var(--warn); }

/* ── splash ──────────────────────────────────────────────────────────────── */

#splash {
  position: fixed; inset: 0; z-index: 90;
  background: var(--bg);
  display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  gap: 5px;
  transition: opacity 200ms cubic-bezier(.2, .75, .25, 1);
}
#splash.out { opacity: 0; }
.sp-m {
  --c: 20px;
  width: 78px; height: 78px;
  display: grid; place-items: center;
  background: var(--face-2);
  clip-path: var(--x-tlbr);
  color: var(--accent-d);
  margin-bottom: 20px;
}
.sp-m .pg { width: 38px; height: 38px; }
.sp-n {
  font-size: 30px; font-weight: 700;
  letter-spacing: -0.035em; text-transform: uppercase;
}
.sp-s {
  font-size: 11px; font-weight: 500;
  letter-spacing: 0.24em; text-transform: uppercase;
  color: var(--ink-3);
}

/* ── frame ───────────────────────────────────────────────────────────────── */

#app {
  position: fixed; inset: 0;
  display: flex; flex-direction: column;
  background: var(--bg);
}

/* The top element carries the fullscreen top inset — the whole chrome band is
   reserved here so the rail clears Telegram's floating Close / ⋯ row. */
.rail {
  flex: none;
  padding-top: max(var(--tg-safe-top), env(safe-area-inset-top, 0px));
}
/* Fullscreen already reserves the chrome inset; trim a cosmetic sliver so the
   rail does not read as a gap, floored at the inset itself. */
[data-fullscreen="1"] .rail {
  padding-top: max(var(--tg-safe-top),
    calc(max(var(--tg-safe-top), env(safe-area-inset-top, 0px)) - 1.4vh));
}
.rail-in { display: flex; align-items: center; gap: 9px; padding: 10px 15px 8px; }
.rail-m {
  --c: 8px;
  width: 28px; height: 28px; flex: none;
  display: grid; place-items: center;
  background: var(--face-2);
  clip-path: var(--x-tlbr);
  color: var(--accent-d);
}
.rail-m .pg { width: 15px; height: 15px; }
.rail-n {
  font-size: 16px; font-weight: 700;
  letter-spacing: -0.02em; text-transform: uppercase;
}
/* shell.js writes every [data-rank-badge], so this stays in sync with the gem. */
.rail-g {
  margin-left: auto;
  display: inline-flex; align-items: center; gap: 5px;
  color: var(--accent-d);
  font-size: 11.5px; font-weight: 500;
}
.rail-g .pg { width: 12px; height: 12px; }

/* ── bottom nav: four cut blocks, standard mobile position ────────────────────
   A flex-column child of #app, so it pins to the bottom of the fixed viewport
   above the scrolling content. Pads the bottom inset. */
.nav {
  flex: none; position: relative;
  display: flex; gap: 5px;
  padding: 7px 11px;
  padding-bottom: calc(7px + max(var(--tg-safe-bottom), env(safe-area-inset-bottom, 0px)));
  background: var(--surface);
}
.nav::before {
  content: ""; position: absolute; top: 0; left: 0; right: 0; height: 1px;
  background: var(--line);
}
.navt {
  --c: 9px;
  flex: 1;
  display: flex; flex-direction: column; align-items: center; gap: 3px;
  padding: 7px 2px 6px;
  clip-path: var(--x-tlbr);
  color: var(--ink-3);
  font-size: 9.5px; font-weight: 600;
  letter-spacing: 0.14em; text-transform: uppercase;
  transition: color var(--t), background var(--t), transform var(--t);
}
.navt .pg { width: 20px; height: 20px; }
.navt.is-on { background: var(--face-2); color: var(--accent-d); }
.navt:active { transform: translate(1.5px, 1.5px); }

/* Play is the game and nothing else — the rail and the nav both step aside so
   the gate owns the screen. */
[data-screen="play"] .rail,
[data-screen="play"] .nav { display: none; }

main { flex: 1; min-height: 0; position: relative; }

.face {
  position: absolute; inset: 0;
  display: none;
  flex-direction: column;
  overflow-y: auto;
  padding: 8px 15px 24px;
}
/* Screens arrive along the cut, 160ms, and stop. */
.face.is-active { display: flex; animation: slide 160ms cubic-bezier(.2, .75, .25, 1); }
@keyframes slide { from { opacity: 0; transform: translate(-11px, -7px); } }

/* ══════════════════════════ HOME: the gem ══════════════════════════════════
   Overlapping angled facets, each carrying one figure, with Play cut as the
   largest face. The chamfers of neighbouring facets open the diagonal slivers
   that do all the spacing work here. */

.gem {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 7px;
  margin: 16px 0 26px;
}

.fc {
  --c: 13px;
  position: relative;
  min-width: 0;
  padding: 10px 11px;
  background: var(--face-1);
  clip-path: var(--x-tlbr);
}
.fc-v {
  display: block;
  font-family: var(--f-n);
  font-size: 24px; font-weight: 700; line-height: 1.05;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
}
.fc-t {
  display: block;
  font-size: 15px; font-weight: 600; line-height: 1.15;
  letter-spacing: -0.015em;
  color: var(--accent-d);
}
.fc-k {
  display: block; margin-top: 3px;
  font-size: 8.5px; font-weight: 600;
  letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--ink-3);
}

/* The play face: the biggest cut in the app, in the only accent fill on the
   screen, with the chamfer on the corner the arrow leaves through. */
.fc--go {
  --c: 28px;
  grid-column: 1 / 3; grid-row: 1 / 3;
  display: flex; flex-direction: column; justify-content: center; gap: 1px;
  padding: 16px 24px 16px 15px;
  background: var(--face-3);
  color: var(--bg);
  clip-path: var(--x-br);
  text-align: left;
}
.go-k {
  font-size: 9px; font-weight: 700;
  letter-spacing: 0.24em; text-transform: uppercase;
  opacity: .68;
}
.go-t {
  font-size: 38px; font-weight: 700; line-height: 1;
  letter-spacing: -0.045em; text-transform: uppercase;
  margin: 2px 0 5px;
}
.go-s {
  display: flex; align-items: center; gap: 6px;
  font-size: 11.5px; font-weight: 600;
  letter-spacing: -0.005em;
}
.go-a { opacity: .8; }

/* The two large read facets ride over the play face, tilted off it. */
.fc--best {
  --c: 17px;
  grid-column: 3 / 5; grid-row: 1;
  clip-path: var(--x-trbl);
  margin-left: -16px;
  transform: rotate(.8deg);
  z-index: 2;
}
.fc--best .fc-v { font-size: 30px; }
.fc--grade {
  --c: 17px;
  grid-column: 3 / 5; grid-row: 2;
  clip-path: var(--x-tlbr);
  margin-left: -16px;
  transform: rotate(-.7deg);
  z-index: 2;
}

.fc--n { grid-row: 3; padding: 9px 9px 10px; }
.fc--n:nth-child(even) { clip-path: var(--x-trbl); transform: rotate(.55deg); }
.fc--n:nth-child(odd)  { transform: rotate(-.55deg); }
.fc--n .fc-v { font-size: 21px; }

/* ── the window: the module a reaction game earns ─────────────────────────────
   Every other game in this set has a score. This one has a deadline, and the
   deadline moves. Four bars, cut as parallelograms, each the width of the time
   you are allowed to answer in at that point in a run, with the 320ms snap
   threshold scored through all four. */

.win { margin: 0 0 26px; }
.win-set { display: flex; flex-direction: column; gap: 4px; margin: 13px 0 11px; }
.win-r {
  display: grid;
  grid-template-columns: 52px 1fr 32px;
  align-items: center;
  gap: 10px;
}
.win-g {
  font-size: 9px; font-weight: 600;
  letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--ink-3);
}
.win-b {
  --c: 7px;
  position: relative;
  height: 16px;
  background: var(--tint);
  clip-path: var(--x-para);
}
.win-b i { display: block; height: 100%; background: var(--accent); }
/* Below the snap line the whole window pays triple, so it is cut in the
   lighter tone: you can see the run turn into a reflex test. */
.win-b .win-i { background: var(--accent-d); }
.win-b::before {
  content: ""; position: absolute; z-index: 1;
  left: 48%; top: 0; bottom: 0; width: 1.5px;
  background: var(--line);
  transform: skewX(-24deg);
}
.win-v {
  font-family: var(--f-n);
  font-size: 15px; font-weight: 700;
  font-variant-numeric: tabular-nums;
  text-align: right;
}

/* ── today's target ──────────────────────────────────────────────────────── */

.task { margin: 0 0 24px; }
.task-h { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
.task-s {
  font-size: 9.5px; font-weight: 700;
  letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--ink-3);
}
.task-s.is-done { color: var(--good); }
.task-g { margin: 8px 0 10px; font-size: 14px; color: var(--ink); }
.task-w { display: flex; align-items: center; gap: 11px; }
.task-b {
  --c: 6px;
  flex: 1; height: 14px;
  background: var(--tint);
  clip-path: var(--x-para);
}
.task-b i {
  display: block; height: 100%; width: 0;
  background: var(--accent);
  transition: width var(--t);
}
.task-v {
  flex: none;
  font-family: var(--f-n);
  font-size: 15px; font-weight: 700;
  font-variant-numeric: tabular-nums;
}

/* ── the optional offer ──────────────────────────────────────────────────── */

.offer { margin: 0 0 24px; }
.offer-r { display: flex; align-items: center; gap: 13px; margin-top: 9px; }
.offer-t { flex: 1; min-width: 0; font-size: 12.5px; line-height: 1.45; color: var(--ink-2); }
.offer-t i { font-style: normal; color: var(--ink-3); }
.offer-t i:empty { display: none; }

/* ══════════════════════════ PLAY ══════════════════════════════════════════ */

.face--play { overflow: hidden; padding: 0 12px 10px; }

.hud {
  flex: none;
  display: flex; align-items: center; gap: 10px;
  padding-top: calc(max(var(--tg-safe-top), env(safe-area-inset-top, 0px)) + 8px);
}
.hud-s { margin-right: auto; display: flex; flex-direction: column; line-height: 1; }
.hud-k {
  font-style: normal;
  font-size: 9px; font-weight: 700;
  letter-spacing: 0.22em; text-transform: uppercase;
  color: var(--ink-3);
}
.hud-v {
  margin-top: 4px;
  font-family: var(--f-n);
  font-size: 34px; font-weight: 700;
  letter-spacing: -0.03em;
  font-variant-numeric: tabular-nums;
}
.tag--sh { background: var(--tint); color: var(--ink-2); }

.live { flex: none; margin: 13px 0 11px; }
.live-k {
  display: block; margin-bottom: 7px;
  font-size: 9px; font-weight: 700;
  letter-spacing: 0.22em; text-transform: uppercase;
  color: var(--ink-3);
}

/* The playfield is a cut plate: a hairline of stone around it, the storm
   inside, and the same chamfer as everything else. */
.plate {
  --c: 18px;
  flex: 1; min-height: 0; position: relative;
  padding: 1.5px;
  background: var(--line);
  clip-path: var(--x-tlbr);
}
#stage {
  --c: 17px;
  display: block; width: 100%; height: 100%;
  background: var(--bg);
  clip-path: var(--x-tlbr);
  touch-action: none;
}

.brief {
  --c: 17px;
  position: absolute; inset: 1.5px;
  display: flex; align-items: center; justify-content: center;
  padding: 16px;
  overflow-y: auto;
  /* the plate ground, not a lifted card: the step facets have to read as cut
     out of the same stone, and a --surface ground would swallow their dark
     half whole */
  background: var(--bg);
  clip-path: var(--x-tlbr);
}
.brief-in { width: 100%; max-width: 330px; }
.steps { list-style: none; margin: 12px 0 16px; padding: 0; display: flex; flex-direction: column; gap: 6px; }
.st {
  --c: 14px;
  display: grid;
  grid-template-columns: 24px 1fr;
  column-gap: 11px;
  padding: 11px 13px;
  background: var(--face-1);
  clip-path: var(--x-tlbr);
}
.st:nth-child(even) { clip-path: var(--x-trbl); transform: rotate(.5deg); }
.st:nth-child(odd) { transform: rotate(-.5deg); }
.st-g { grid-row: 1 / 3; align-self: start; margin-top: 2px; color: var(--accent-d); }
.st-t { font-size: 13.5px; font-weight: 700; letter-spacing: -0.01em; }
.st-d { font-size: 12px; line-height: 1.4; color: var(--ink-2); }

/* ══════════════════════════ RANK ══════════════════════════════════════════ */

.seg { display: flex; gap: 6px; margin: 12px 0 0; }
.seg-btn {
  --c: 11px;
  flex: 1;
  padding: 10px 8px;
  background: var(--surface);
  clip-path: var(--x-tlbr);
  color: var(--ink-3);
  font-size: 12px; font-weight: 600;
  letter-spacing: 0.14em; text-transform: uppercase;
  transition: background var(--t), color var(--t), transform var(--t);
}
.seg-btn:nth-child(even) { clip-path: var(--x-trbl); }
.seg-btn:active { transform: translate(1.5px, 1.5px); }
.seg-btn.is-on { background: var(--face-2); color: var(--accent-d); }

.board { display: flex; flex-direction: column; gap: 4px; margin: 12px 0 14px; }
.rw {
  --c: 11px;
  display: flex; align-items: center; gap: 11px;
  padding: 8px 13px;
  background: var(--face-1);
  clip-path: var(--x-tlbr);
}
.rw:nth-child(even) { clip-path: var(--x-trbl); }
.rw-pos {
  min-width: 20px;
  font-family: var(--f-n);
  font-size: 13px; font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--ink-3);
  text-align: center;
}
.rw-av {
  --c: 8px;
  width: 30px; height: 30px; flex: none;
  display: grid; place-items: center;
  clip-path: var(--x-tlbr);
  /* shell.js hands each name a hue; keep it quiet so the accent stays the one
     loud colour on the screen. */
  background: hsl(var(--h) 22% 22%);
  color: hsl(var(--h) 52% 78%);
  font-size: 13px; font-weight: 700;
}
.rw-nm {
  flex: 1; min-width: 0;
  font-size: 14px; font-weight: 500;
  letter-spacing: -0.01em;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.rw-sc {
  font-family: var(--f-n);
  font-size: 17px; font-weight: 700;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
}
.rw--top .rw-pos { color: var(--accent-d); }
.rw--me { background: var(--face-2); }
.rw--me .rw-pos { color: var(--accent-d); }
.rw--me .rw-nm { font-weight: 700; }
.rw--me .rw-sc { color: var(--accent-d); }

/* ══════════════════════════ MORE ══════════════════════════════════════════ */

.set { display: flex; flex-direction: column; gap: 4px; margin: 12px 0 26px; }
.set-r {
  --c: 11px;
  display: flex; width: 100%; align-items: center; gap: 12px;
  padding: 12px 14px;
  background: var(--face-1);
  clip-path: var(--x-tlbr);
  color: var(--ink);
  font-size: 14px; font-weight: 500; text-align: left;
}
.set-r:nth-child(even) { clip-path: var(--x-trbl); }
.set-r > span { flex: 1; min-width: 0; }
.set-a { color: var(--ink-3); }
.set-b:active { background: var(--face-2); }

.sw {
  --c: 7px;
  appearance: none; -webkit-appearance: none;
  width: 48px; height: 26px; flex: none;
  margin: 0; position: relative;
  background: var(--tint-2);
  clip-path: var(--x-tlbr);
  transition: background var(--t);
}
.sw::after {
  --c: 5px;
  content: ""; position: absolute; top: 3px; left: 3px;
  width: 20px; height: 20px;
  background: var(--ink-2);
  clip-path: var(--x-tlbr);
  transition: transform var(--t), background var(--t);
}
.sw:checked { background: var(--accent); }
.sw:checked::after { background: var(--bg); transform: translateX(22px); }

/* ══════════════════════════ overlays ══════════════════════════════════════ */

.scrim { position: fixed; inset: 0; z-index: 40; background: rgba(4, 8, 11, .76); }

.sheet {
  --c: 22px;
  position: fixed; z-index: 50;
  left: 10px; right: 10px;
  bottom: calc(10px + max(var(--tg-safe-bottom), env(safe-area-inset-bottom, 0px)));
  background: var(--surface);
  clip-path: var(--x-tlbr);
  display: flex; flex-direction: column;
  max-height: calc(100dvh - max(var(--tg-safe-top), env(safe-area-inset-top, 0px)) - 24px);
  /* Deliberately NOT animated. A sheet that slides in from below sits, for the
     length of the animation, with its own Close button under the fold — and if
     a client throttles animations it stays there. The sheet just appears. */
}
.sheet-h {
  flex: none; position: relative;
  display: flex; align-items: center; gap: 12px;
  padding: 16px 16px 13px;
}
.sheet-h::after {
  content: ""; position: absolute; left: 16px; right: 16px; bottom: 0; height: 1px;
  background: var(--line);
}
.sheet-t {
  flex: 1; min-width: 0;
  font-size: 19px; font-weight: 700;
  letter-spacing: -0.025em; text-transform: uppercase;
}
.sheet-b {
  flex: 1; min-height: 0;
  overflow-y: auto;
  padding: 15px 17px 4px;
  font-size: 13.5px; line-height: 1.55;
  color: var(--ink-2);
}
.sheet-b p { margin: 0 0 12px; }
.sheet-b ul { margin: 0 0 12px; padding-left: 0; list-style: none; }
.sheet-b li { position: relative; padding-left: 19px; margin-bottom: 10px; }
/* The bullet is a cut wedge, the same shape family as everything else. */
.sheet-b li::before {
  content: ""; position: absolute; left: 1px; top: 7px;
  width: 0; height: 0;
  border-left: 8px solid var(--accent);
  border-top: 4.5px solid transparent;
  border-bottom: 4.5px solid transparent;
}
.sheet-b b { font-weight: 700; color: var(--ink); }
.sheet-f { flex: none; position: relative; padding: 13px 17px 17px; }
.sheet-f::before {
  content: ""; position: absolute; left: 17px; right: 17px; top: 0; height: 1px;
  background: var(--line);
}

.modal {
  position: fixed; inset: 0; z-index: 55;
  display: flex; align-items: center; justify-content: center;
  padding: 20px;
  pointer-events: none;
}
.slab {
  --c: 26px;
  pointer-events: auto;
  width: 100%; max-width: 332px;
  padding: 22px 20px;
  background: var(--face-1);
  clip-path: var(--x-tlbr);
  text-align: center;
  animation: slab 160ms cubic-bezier(.2, .75, .25, 1);
}
@keyframes slab { from { opacity: 0; transform: translate(-9px, -9px); } }
.slab .tag { margin-bottom: 4px; }
.slab-n {
  font-family: var(--f-n);
  font-size: 62px; font-weight: 700; line-height: 1;
  letter-spacing: -0.04em;
  font-variant-numeric: tabular-nums;
  margin: 10px 0 4px;
}
.slab-k {
  display: block;
  font-size: 9.5px; font-weight: 700;
  letter-spacing: 0.2em; text-transform: uppercase;
  color: var(--ink-3);
}
.slab-s { display: block; margin-top: 8px; font-size: 13px; color: var(--ink-2); }
.slab-t {
  display: block; margin: 12px 0 0;
  font-size: 22px; font-weight: 700;
  letter-spacing: -0.03em; text-transform: uppercase;
}
.slab-p { margin: 8px 0 0; font-size: 13.5px; line-height: 1.5; color: var(--ink-2); }
.slab-b { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin-top: 18px; }
.slab-b .blade { --c: 12px; padding: 12px 10px; font-size: 13px; gap: 7px; }
.slab .blade--ghost { margin-top: 10px; }
.slab-b .blade--ghost { margin-top: 0; }

/* The countdown before a continue: the one true gem shape in the app. */
.revive {
  position: fixed; inset: 0; z-index: 60;
  display: grid; place-items: center;
  pointer-events: none;
}
.revive span {
  display: grid; place-items: center;
  width: 134px; height: 134px;
  background: var(--face-2);
  clip-path: var(--x-dia);
  font-family: var(--f-n);
  font-size: 54px; font-weight: 700;
  color: var(--accent-d);
  animation: chip 160ms cubic-bezier(.2, .75, .25, 1);
}
@keyframes chip { from { opacity: 0; transform: translate(-10px, -10px); } }

.toast {
  --c: 12px;
  position: fixed; z-index: 70;
  left: 16px; right: 16px;
  bottom: calc(96px + max(var(--tg-safe-bottom), env(safe-area-inset-bottom, 0px)));
  padding: 13px 18px;
  background: var(--face-2);
  clip-path: var(--x-tlbr);
  font-size: 13px; font-weight: 500;
  text-align: center;
}

/* ── reduce motion: kill all of it ───────────────────────────────────────── */

[data-reduce-motion="1"] *,
[data-reduce-motion="1"] *::before,
[data-reduce-motion="1"] *::after {
  animation: none !important;
  transition: none !important;
}

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

/* Short phones: the play face and the modal figure give first. */
@media (max-height: 690px) {
  .go-t { font-size: 32px; }
  .fc--go { padding-top: 13px; padding-bottom: 13px; }
  .gem { margin: 12px 0 20px; }
  .slab-n { font-size: 50px; }
  .st { padding: 9px 11px; }
  .st-d { font-size: 11.5px; }
}
