/* ═══════════════════════════════════════════════════════════════════════════
   RATCHET LINE — THE DETENT DIAL

   Everything on this screen is drawn from a centre. Rings, arcs, dots and
   capsules, and not one rectangle in the chrome: the only square thing in the
   product is the canvas itself, and it sits inside a bezel so it reads as a
   porthole cut into the dial face.

   The wheel it describes does not turn smoothly. It advances in sixteen
   discrete clicks, so this sheet steps too. The tooth ring on the home dial is
   driven by steps(16) and never sweeps, the pawl above it drops once a second,
   and every state change lands in 220ms with nothing in between.

   Rules held without exception:
     · Radius is 50% or 999px. If a shape has a corner it is wrong.
     · Elevation is off. Depth is concentric strokes of different weights, set
       with box-shadow rings. No drop shadow, no blur, no glass.
     · One face, Jost: geometric, circular counters, open apertures. Numerals
       are light and large and sit centred inside rings. Micro labels are 10px
       uppercase tracked to 0.22em, because a label on a dial is engraved
       around the rim, not set in a paragraph.
     · Lume green is the lit index: it marks the live thing and nothing else.
       Vermilion means exactly one thing, this can break.
     · Motion is rotation or an arc sweep, 220ms. Things orbit into place and
       press by contracting toward their own centre. Nothing slides, nothing
       bounces, nothing fades in from below.
   ═══════════════════════════════════════════════════════════════════════════ */

: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:       #070B16;
  --surface:  #0E1425;
  --tint:     #16203A;
  --tint-2:   #212E4E;
  --line:     #2E3D63;
  --ink:      #ECF1FF;
  --ink-2:    #A8B5D6;
  --ink-3:    #6F7EA4;
  --accent:   #C7EE63;
  --accent-d: #DDF79E;
  --good:     #55D8FF;
  --warn:     #FF6B4A;

  --f: "Jost", "Century Gothic", "Avenir Next", -apple-system, BlinkMacSystemFont,
       "Segoe UI", Roboto, sans-serif;

  /* One duration for the whole build. A ratchet has one beat. */
  --t: 220ms cubic-bezier(.33, .68, .3, 1);

  /* The two ring weights everything is built from. */
  --ring:  inset 0 0 0 1px var(--line);
  --ring-o: 0 0 0 1px var(--line);
}

*, *::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.55;
  -webkit-font-smoothing: antialiased;
}

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

/* The symbol library itself never renders. */
.marks { position: absolute; width: 0; height: 0; overflow: hidden; }

/* ── icons: arcs and dots ────────────────────────────────────────────────────
   No straight edge survives in here. Every stroke is round-capped, which makes
   even a two-stroke pause mark a pair of capsules, and every terminal is a
   dot. */

.orb {
  display: block; flex: none;
  width: 22px; height: 22px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.orb-s { width: 17px; height: 17px; stroke-width: 1.7; }
.orb-l { width: 34px; height: 34px; stroke-width: 1.2; }

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

/* The engraved rim label. Everything small in this build is one of these. */
.legend {
  display: block;
  font-size: 10px; font-weight: 500;
  font-style: normal;
  letter-spacing: 0.22em; text-transform: uppercase;
  color: var(--ink-3);
  line-height: 1.5;
}
.head { text-align: center; margin: 0 0 20px; }
.head .sep::before { content: "\00a0\00b7\00a0"; }
.mid { text-align: center; margin: 12px 0 0; }

.lead {
  margin: 0 0 18px;
  text-align: center;
  font-size: 15px; font-weight: 300;
  color: var(--ink-2);
}

.note {
  margin: 22px 0 0;
  text-align: center;
  font-size: 11.5px; font-weight: 400; line-height: 1.6;
  color: var(--ink-3);
}

/* ── capsules: every labelled control ────────────────────────────────────── */

.cap {
  display: inline-flex; align-items: center; justify-content: center; gap: 9px;
  width: 100%;
  border-radius: 999px;
  padding: 15px 24px;
  font-size: 14.5px; font-weight: 500;
  letter-spacing: 0.01em;
  transition: transform var(--t), background var(--t), box-shadow var(--t), color var(--t);
}
.cap--lit   { background: var(--accent); color: var(--bg); font-weight: 600; }
.cap--soft  { background: var(--tint); color: var(--accent-d); box-shadow: var(--ring); }
.cap--ghost { color: var(--ink-2); box-shadow: var(--ring); }
/* A control presses by contracting toward its own centre, never downward. */
.cap:active { transform: scale(.965); }
.cap:disabled { opacity: .45; }

/* Circular button: one action, no label, aria carries the name. */
.knob {
  width: 44px; height: 44px; flex: none;
  display: grid; place-items: center;
  border-radius: 50%;
  color: var(--ink-2);
  box-shadow: var(--ring);
  transition: transform var(--t), box-shadow var(--t), color var(--t);
}
.knob:active { transform: scale(.92); color: var(--accent); box-shadow: inset 0 0 0 1px var(--accent); }

/* A word on its own, for the quiet route out of a decision. */
.plain {
  display: inline-block;
  padding: 9px 6px;
  font-size: 13.5px; font-weight: 400;
  color: var(--ink-2);
  border-bottom: 1px solid var(--line);
  transition: color var(--t), border-color var(--t);
}
.plain:active { color: var(--accent-d); border-color: var(--accent); }

/* ── tags: a state, set in a capsule ─────────────────────────────────────── */

.tag {
  display: inline-flex; align-items: center; gap: 6px;
  border-radius: 999px;
  padding: 6px 14px;
  box-shadow: var(--ring);
  color: var(--accent-d);
  font-size: 10px; font-weight: 500;
  letter-spacing: 0.18em; text-transform: uppercase;
  white-space: nowrap;
}
.tag--lit { background: var(--accent); color: var(--bg); box-shadow: none; font-weight: 600; }
/* The chain tag holds no space until there is a chain to show, so the hold disc
   stays on the centre line of the screen. */
.tag:empty { display: none; }
.tag.is-done { color: var(--good); box-shadow: inset 0 0 0 1px var(--good); }

/* ── the disc: the only gauge shape in the build ──────────────────────────────
   shell.js drives progress by writing a width percentage, so a ring driven by
   stroke-dashoffset is not available to it. A width inside a circular clip is:
   the fill wipes across the disc and the thing empties like a moon going dark.
   Nothing in this app is a bar. */

.disc {
  width: 38px; height: 38px; flex: none;
  border-radius: 50%;
  background: var(--tint);
  box-shadow: var(--ring);
  overflow: hidden;
}
.disc i {
  display: block; height: 100%; width: 0;
  background: var(--accent);
  transition: width var(--t), background var(--t);
}
.disc i.is-low { background: var(--warn); }
.disc--lg { width: 52px; height: 52px; }

/* ── the arc rule ─────────────────────────────────────────────────────────────
   A divider on a dial is not a straight line, it is a segment of a much larger
   circle passing through. One hairline, curved. */

.sweep {
  flex: none;
  height: 15px;
  margin: 24px 0 22px;
  border-top: 1px solid var(--line);
  border-radius: 50% 50% 0 0 / 100% 100% 0 0;
  opacity: .85;
}

/* ── splash: the pawl seats, then the app opens ──────────────────────────── */

#splash {
  position: fixed; inset: 0; z-index: 90;
  background: var(--bg);
  display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  gap: 14px;
  transition: opacity var(--t);
}
#splash.out { opacity: 0; }
.boot-mark {
  width: 92px; height: 92px;
  display: grid; place-items: center;
  border-radius: 50%;
  color: var(--accent);
  box-shadow: inset 0 0 0 1px var(--accent), 0 0 0 9px var(--surface), 0 0 0 10px var(--line);
  animation: seat 380ms cubic-bezier(.33, .68, .3, 1) both;
}
.boot-mark .orb { width: 46px; height: 46px; stroke-width: 1.1; }
.boot-name {
  font-size: 21px; font-weight: 400;
  letter-spacing: 0.34em; text-transform: uppercase;
  padding-left: 0.34em;
  animation: seat 380ms cubic-bezier(.33, .68, .3, 1) 90ms both;
}
.boot-line { animation: seat 380ms cubic-bezier(.33, .68, .3, 1) 170ms both; }

/* Everything arrives by rotating onto its seat. */
@keyframes seat {
  from { transform: rotate(-9deg) scale(.94); opacity: 0; }
  to   { transform: none; opacity: 1; }
}

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

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

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

/* There is no top bar. Each face carries the fullscreen top inset itself, so
   the content leads and nothing sits above the dial competing with it. */
.face {
  position: absolute; inset: 0;
  display: none;
  flex-direction: column;
  overflow-y: auto;
  padding: calc(max(var(--tg-safe-top), env(safe-area-inset-top, 0px)) + 20px) 22px 28px;
}
.face.is-active { display: flex; }
.face > * { flex: none; }

/* The run owns the screen: no scroll, the viewport takes what is left. */
.face--run {
  overflow: hidden;
  padding: calc(max(var(--tg-safe-top), env(safe-area-inset-top, 0px)) + 8px) 10px 8px;
}

/* ── navigation: four nodes on the bottom rail ───────────────────────────── */

.orbitbar {
  flex: none;
  display: flex; justify-content: center; gap: 4px;
  padding: 9px 12px;
  padding-bottom: calc(9px + max(var(--tg-safe-bottom), env(safe-area-inset-bottom, 0px)));
  border-top: 1px solid var(--line);
}
.node {
  flex: 1; max-width: 96px;
  display: flex; flex-direction: column; align-items: center; gap: 6px;
  color: var(--ink-3);
  font-size: 9px; font-weight: 500;
  letter-spacing: 0.2em; text-transform: uppercase;
  transition: color var(--t);
}
.node .pip {
  width: 40px; height: 40px;
  display: grid; place-items: center;
  border-radius: 50%;
  transition: background var(--t), color var(--t), transform var(--t);
}
.node.is-on { color: var(--ink); }
.node.is-on .pip { background: var(--accent); color: var(--bg); }
.node:active .pip { transform: scale(.9); }

/* Play is the machine and nothing else. */
[data-screen="play"] .orbitbar { display: none; }

/* ── home: one dial, satellites around it ────────────────────────────────── */

.dial {
  position: relative;
  width: min(268px, 74vw);
  aspect-ratio: 1;
  margin: 4px auto 26px;
}
.dial-svg { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }

/* Concentric strokes of three weights. This is the whole elevation model. */
.d-rim  { fill: none; stroke: var(--line); stroke-width: .8; opacity: .55; }
.d-rim2 { fill: none; stroke: var(--line); stroke-width: 1.4; }
.d-in   { fill: none; stroke: var(--line); stroke-width: 1; opacity: .5; }

/* Sixteen teeth, exactly as many as the wheel has, advancing one per second.
   steps(16) is the point: a ratchet cannot be caught between two teeth. */
.d-teeth { fill: var(--ink-3); transform-box: view-box; transform-origin: 50% 50%; }
.d-teeth circle { opacity: .8; }
.d-teeth { animation: detent 16s steps(16, end) infinite; }
@keyframes detent { to { transform: rotate(360deg); } }

/* The pawl is fixed at the top and drops onto whichever tooth arrives. */
.d-pawl { transform-box: view-box; animation: drop 1s linear infinite; }
.d-pawl .arm  { fill: none; stroke: var(--ink-3); stroke-width: 2.4; stroke-linecap: round; }
.d-pawl .tip  { fill: var(--accent); }
.d-pawl .halo { fill: none; stroke: var(--accent); stroke-width: 1; opacity: .45; }
@keyframes drop { 0% { transform: translateY(-4px); } 12%, 100% { transform: none; } }

.dial-core {
  position: absolute; inset: 0;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 4px;
  pointer-events: none;
}
.dial-num {
  font-size: clamp(56px, 19vw, 76px);
  font-weight: 300;
  letter-spacing: -0.03em;
  line-height: 1;
  font-variant-numeric: tabular-nums;
}
.dial-core .legend { font-size: 9px; letter-spacing: 0.2em; }

/* The grade sits on the rim, cutting the ring, the way a bezel index does. */
.grade {
  position: absolute; left: 50%; bottom: -14px;
  transform: translateX(-50%);
  display: inline-flex; align-items: center; gap: 7px;
  background: var(--bg);
  box-shadow: var(--ring-o);
  border-radius: 999px;
  padding: 6px 15px;
  color: var(--accent-d);
  font-size: 10px; font-weight: 500;
  letter-spacing: 0.18em; text-transform: uppercase;
  white-space: nowrap;
}
.grade .orb { color: var(--accent); }

/* ── the figure: one tooth, opened out ────────────────────────────────────────
   The module a ratchet earns and a smooth game cannot use. It is not a chart of
   the run, it is the rule of the game drawn once: a single tooth pitch bent
   into the arc it actually travels, with the window inside it marked. */

.fig { margin: 0; }
.fig-svg { display: block; width: 100%; height: auto; overflow: visible; }
.fig-svg .track { fill: none; stroke: var(--line); stroke-width: 9; stroke-linecap: round; }
.fig-svg .live  { fill: none; stroke: var(--accent); stroke-width: 9; stroke-linecap: round; }
.fig-svg .bad   { fill: none; stroke: var(--warn); stroke-width: 9; stroke-linecap: round; opacity: .72; }
.fig-svg .grad  { fill: none; stroke: var(--ink-3); stroke-width: 1.6; stroke-linecap: round;
                  stroke-dasharray: 0.1 11; opacity: .7; }
.fig-svg .wall  { fill: none; stroke: var(--line); stroke-width: 2.4; stroke-linecap: round; }
/* The seat itself: a hole punched in the lit band, so the arm visibly drops
   INTO something rather than resting on top of it. */
.fig-svg .pin   { fill: var(--bg); }
.fig-svg .arm   { fill: none; stroke: var(--ink-3); stroke-width: 2.4; stroke-linecap: round; }
.fig-svg text {
  font-family: var(--f);
  font-size: 8.5px; font-weight: 500;
  letter-spacing: 0.2em; text-transform: uppercase;
  fill: var(--ink-3);
}
.fig-svg .t-lit { fill: var(--accent-d); }
.fig-svg .t-bad { fill: var(--warn); }
.fig-cap {
  margin: 14px 2px 0;
  font-size: 13.5px; font-weight: 300; line-height: 1.6;
  color: var(--ink-2);
  text-align: center;
}
.fig-cap b { font-weight: 500; color: var(--ink); }

/* ── satellites: four counters on a shallow orbit ────────────────────────── */

.belt {
  display: flex; justify-content: center; gap: 8px;
  padding-bottom: 14px;
}
.sat {
  width: 72px; height: 72px; flex: none;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 1px;
  border-radius: 50%;
  box-shadow: var(--ring);
}
/* The outer pair rides lower, so the four sit on an arc under the dial. */
.sat:first-child, .sat:last-child { transform: translateY(14px); }
.sat b {
  font-size: 23px; font-weight: 300; line-height: 1.1;
  font-variant-numeric: tabular-nums;
}
.sat i {
  font-style: normal;
  font-size: 8px; font-weight: 500;
  letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--ink-3);
}

/* ── today's line ────────────────────────────────────────────────────────── */

.task { display: flex; align-items: center; gap: 15px; }
.task-tx { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.task-tx b { font-size: 14px; font-weight: 400; color: var(--ink); }
.task-tx i {
  font-style: normal;
  font-size: 10px; font-weight: 500;
  letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--ink-3);
}
.task-tx i [data-daily-state].is-done { color: var(--good); }

/* ── the spare brace offer ───────────────────────────────────────────────── */

.aside .legend { text-align: center; }
.aside-tx {
  margin: 10px 0 14px;
  text-align: center;
  font-size: 13px; font-weight: 300; line-height: 1.6;
  color: var(--ink-2);
}
.aside-tx span:empty { display: none; }

/* ── the run ─────────────────────────────────────────────────────────────── */

.crown { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.count { display: flex; flex-direction: column; align-items: center; gap: 3px; }
.count b {
  font-size: 38px; font-weight: 300; line-height: 1;
  letter-spacing: -0.03em;
  font-variant-numeric: tabular-nums;
}
.count .legend { font-size: 9px; letter-spacing: 0.2em; }

.gauges {
  display: flex; align-items: center; justify-content: center; gap: 12px;
  min-height: 58px;
  margin: 6px 0 2px;
}
.hold { display: flex; flex-direction: column; align-items: center; gap: 4px; }
.hold .legend { font-size: 8px; letter-spacing: 0.18em; }
.tag--combo {
  opacity: 0;
  background: var(--accent); color: var(--bg);
  box-shadow: none;
  font-size: 12px; font-weight: 600; letter-spacing: 0.06em;
  transition: opacity var(--t), transform var(--t);
}
.tag--combo.is-on { opacity: 1; }

/* The porthole. The canvas is the one rectangle in the product, so it is set
   behind concentric rings and clipped, and it reads as an aperture. */
.viewport {
  flex: 1; min-height: 0;
  position: relative;
  margin: 8px 9px 10px;
  border-radius: 46px;
  overflow: hidden;
  background: var(--bg);
  box-shadow: var(--ring), 0 0 0 6px var(--bg), 0 0 0 7px var(--line);
}
#stage { display: block; width: 100%; height: 100%; touch-action: none; }

/* The notes, laid over the aperture until the pawl drops. The whole panel is
   the start target, so a tap anywhere begins the run. */
.brief {
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
  background: var(--surface);
  padding: 20px 22px;
  overflow-y: auto;
}
.brief-in { width: 100%; max-width: 310px; text-align: center; }
.brief-mark {
  width: 62px; height: 62px;
  display: grid; place-items: center;
  margin: 0 auto 14px;
  border-radius: 50%;
  color: var(--accent);
  box-shadow: inset 0 0 0 1px var(--line), 0 0 0 6px var(--bg);
}
.brief-h {
  margin: 0 0 20px;
  font-size: 13px; font-weight: 500;
  letter-spacing: 0.22em; text-transform: uppercase;
  color: var(--ink);
}
.cues { list-style: none; margin: 0 0 22px; padding: 0; display: flex; flex-direction: column; gap: 14px; }
.cue { display: flex; align-items: flex-start; gap: 13px; text-align: left; }
.cue-n {
  width: 26px; height: 26px; flex: none;
  display: grid; place-items: center;
  border-radius: 50%;
  box-shadow: inset 0 0 0 1px var(--accent);
  color: var(--accent);
  font-size: 11px; font-weight: 500;
}
.cue-tx { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.cue-tx b { font-size: 13.5px; font-weight: 500; }
.cue-tx i {
  font-style: normal;
  font-size: 12.5px; font-weight: 300; line-height: 1.45;
  color: var(--ink-2);
}

/* ── the register ────────────────────────────────────────────────────────── */

.scope {
  display: flex; justify-content: center; gap: 8px;
  margin: 0 auto 22px;
}
.seg-btn {
  flex: none;
  white-space: nowrap;
  border-radius: 999px;
  padding: 11px 24px;
  box-shadow: var(--ring);
  color: var(--ink-3);
  font-size: 10px; font-weight: 500;
  letter-spacing: 0.2em; text-transform: uppercase;
  transition: background var(--t), color var(--t), box-shadow var(--t);
}
.seg-btn.is-on { background: var(--accent); color: var(--bg); box-shadow: none; font-weight: 600; }

/* Rows are not ruled. The avatars are the rhythm, and the one that is yours is
   the only capsule on the board. */
.board { display: flex; flex-direction: column; gap: 2px; }
.rw {
  display: flex; align-items: center; gap: 13px;
  padding: 7px 12px;
  border-radius: 999px;
}
.rw-pos {
  width: 24px; height: 24px; flex: none;
  display: grid; place-items: center;
  border-radius: 50%;
  color: var(--ink-3);
  font-size: 11px; font-weight: 500;
  font-variant-numeric: tabular-nums;
}
.rw-av {
  width: 32px; height: 32px; flex: none;
  display: grid; place-items: center;
  border-radius: 50%;
  /* shell.js hands each name a hue; keep it quiet so the lume stays the one
     loud colour on the screen. */
  background: hsl(var(--h) 26% 17%);
  color: hsl(var(--h) 42% 72%);
  font-size: 13px; font-weight: 500;
}
.rw-nm { flex: 1; min-width: 0; font-size: 14.5px; font-weight: 400; }
.rw-sc { font-size: 15px; font-weight: 400; font-variant-numeric: tabular-nums; }
.rw--top .rw-pos { color: var(--accent); box-shadow: inset 0 0 0 1px var(--accent); }
.rw--me {
  background: var(--tint);
  box-shadow: var(--ring);
  margin: 4px 0;
}
.rw--me .rw-nm { font-weight: 500; }
.rw--me .rw-sc { color: var(--accent-d); }

/* ── settings and papers ─────────────────────────────────────────────────── */

.opts { display: flex; flex-direction: column; gap: 4px; }
.opt {
  display: flex; align-items: center; gap: 13px;
  padding: 11px 4px;
  font-size: 14.5px; font-weight: 400;
}
.opt::before {
  content: ""; flex: none;
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--line);
}
.opt > span { flex: 1; min-width: 0; }

/* The switch is the one control that was already the right shape. */
.sw {
  appearance: none; -webkit-appearance: none;
  width: 48px; height: 28px; flex: none;
  margin: 0; position: relative;
  border-radius: 999px;
  background: var(--tint-2);
  box-shadow: var(--ring);
  transition: background var(--t), box-shadow var(--t);
}
.sw::after {
  content: ""; position: absolute; top: 3px; left: 3px;
  width: 22px; height: 22px;
  border-radius: 50%;
  background: var(--ink-3);
  transition: transform var(--t), background var(--t);
}
.sw:checked { background: rgba(199, 238, 99, .14); box-shadow: inset 0 0 0 1px var(--accent); }
.sw:checked::after { transform: translateX(20px); background: var(--accent); }

.links { display: flex; flex-direction: column; gap: 4px; }
.lk {
  display: flex; align-items: center; gap: 13px;
  width: 100%;
  padding: 12px 16px;
  border-radius: 999px;
  text-align: left;
  font-size: 14.5px; font-weight: 400;
  color: var(--ink);
  transition: background var(--t), color var(--t);
}
.lk > span { flex: 1; min-width: 0; }
.lk .orb { color: var(--ink-3); }
.lk:active { background: var(--tint); }

/* ── overlays ────────────────────────────────────────────────────────────── */

/* Decisions carry no card, so this is the only thing separating them from the
   face underneath. It is nearly opaque on purpose. */
.eclipse { position: fixed; inset: 0; z-index: 40; background: rgba(5, 7, 16, .96); }

/* The paper panel. Its top edge is a single wide arc, so even the one surface
   that has to hold running text arrives as a dome and not a card. */
.dome {
  position: fixed; z-index: 50;
  left: 10px; right: 10px;
  bottom: calc(10px + max(var(--tg-safe-bottom), env(safe-area-inset-bottom, 0px)));
  display: flex; flex-direction: column;
  max-height: calc(100dvh - max(var(--tg-safe-top), env(safe-area-inset-top, 0px)) - 26px);
  overflow: hidden;
  background: var(--surface);
  box-shadow: var(--ring);
  border-radius: 50% 50% 40px 40px / 52px 52px 40px 40px;
  /* Deliberately NOT animated. A panel that slides in from below sits, for the
     length of the animation, with its own Close control under the fold. */
}
.dome-hd { flex: none; padding: 40px 26px 14px; text-align: center; }
.dome-ti {
  margin: 6px 0 0;
  font-size: 14px; font-weight: 500;
  letter-spacing: 0.2em; text-transform: uppercase;
}
.dome-bd {
  flex: 1; min-height: 0;
  overflow-y: auto;
  padding: 4px 26px;
  font-size: 13.5px; font-weight: 300; line-height: 1.65;
  color: var(--ink-2);
}
.dome-bd p { margin: 0 0 13px; }
.dome-bd ul { margin: 0 0 13px; padding-left: 0; list-style: none; }
.dome-bd li { position: relative; padding-left: 20px; margin-bottom: 11px; }
.dome-bd li::before {
  content: ""; position: absolute; left: 2px; top: 8px;
  width: 7px; height: 7px;
  border-radius: 50%;
  background: var(--accent);
}
.dome-bd b { font-weight: 500; color: var(--ink); }
.dome-ft { flex: none; padding: 12px 26px 22px; }

/* Decisions have no card. They sit on the eclipse, centred, and they orbit in. */
.halo {
  position: fixed; inset: 0; z-index: 55;
  display: flex; align-items: center; justify-content: center;
  padding: 28px;
  pointer-events: none;
}
.halo-in {
  pointer-events: auto;
  width: 100%; max-width: 312px;
  display: flex; flex-direction: column; align-items: center; gap: 12px;
  text-align: center;
  animation: seat var(--t) both;
}
.halo-in .cap { margin-top: 4px; }

/* The result, centred in a ring, with a second ring outside it for depth. */
.score-ring {
  width: 176px; height: 176px;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 2px;
  border-radius: 50%;
  box-shadow: inset 0 0 0 1px var(--line), 0 0 0 7px var(--bg), 0 0 0 8px var(--tint-2);
}
.score-ring b {
  font-size: 58px; font-weight: 300; line-height: 1;
  letter-spacing: -0.03em;
  font-variant-numeric: tabular-nums;
}
.halo-h {
  margin: 0;
  font-size: 15px; font-weight: 500;
  letter-spacing: 0.14em; text-transform: uppercase;
}
.halo-s {
  margin: 0;
  font-size: 13.5px; font-weight: 300; line-height: 1.6;
  color: var(--ink-2);
}

/* The one surface in the app that leaves it, so it says what it costs first. */
.offer-cap {
  display: flex; flex-direction: column; align-items: center; gap: 4px;
  width: 100%;
  padding: 14px 20px;
  border-radius: 26px;
  box-shadow: var(--ring);
  color: var(--accent-d);
  transition: transform var(--t);
}
.offer-cap:active { transform: scale(.97); }
.offer-cap b { font-size: 13.5px; font-weight: 500; }
.offer-cap i {
  font-style: normal;
  font-size: 11.5px; font-weight: 300; line-height: 1.5;
  color: var(--ink-3);
}
.offer-cap i:empty { display: none; }
.offer-cap:disabled { opacity: .45; }

.countdown {
  position: fixed; inset: 0; z-index: 60;
  display: grid; place-items: center;
  pointer-events: none;
}
.countdown span {
  display: grid; place-items: center;
  width: 136px; height: 136px;
  border-radius: 50%;
  background: var(--surface);
  box-shadow: inset 0 0 0 1px var(--accent), 0 0 0 8px var(--bg), 0 0 0 9px var(--line);
  color: var(--accent);
  font-size: 62px; font-weight: 300;
  font-variant-numeric: tabular-nums;
  animation: seat var(--t) both;
}

.blip {
  position: fixed; z-index: 70;
  left: 50%; transform: translateX(-50%);
  bottom: calc(104px + max(var(--tg-safe-bottom), env(safe-area-inset-bottom, 0px)));
  max-width: calc(100% - 36px);
  background: var(--surface);
  box-shadow: var(--ring-o);
  border-radius: 999px;
  padding: 12px 22px;
  font-size: 10.5px; font-weight: 500;
  letter-spacing: 0.18em; text-transform: uppercase;
  text-align: center;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* ── reduce motion: the ring stops stepping, everything else lands ───────── */

[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; animation-iteration-count: 1 !important;
      transition-duration: 0.01ms !important; }
}

/* ── short phones: the dial gives, the aperture never does ───────────────── */

@media (max-height: 700px) {
  .dial { width: min(210px, 60vw); margin-bottom: 22px; }
  .dial-num { font-size: 52px; }
  .sat { width: 64px; height: 64px; }
  .sat b { font-size: 20px; }
  .sweep { margin: 18px 0 16px; }
  .count b { font-size: 32px; }
  .score-ring { width: 150px; height: 150px; }
  .score-ring b { font-size: 50px; }
  .cues { gap: 11px; }
}
