/* ═══════════════════════════════════════════════════════════════════════════
   KEELSPIN — HELM REPEATER

   The chrome is not a poster and not a menu. It is the readout of a gyro
   repeater sitting next to the tiller: bearings in degrees, arcs in degrees,
   hairlines, monospace figures, one signal colour. The game is about ANGLE
   and CLEARANCE, so every surface in the app is either a bearing, an arc, or
   a rule separating two of them.

   Laws of this sheet, no exceptions:
     · border-radius is 0. Everywhere. There is not one round corner in the
       app, and the bearing rose itself is drawn without a single circle in
       it, because an instrument that cannot print a curve prints spokes.
     · Elevation does not exist. No shadow, no lift, no gradient. Separation
       is one 1px rule, --hair, and that is the whole vocabulary.
     · Monospace carries every figure, label and row. The condensed grotesque
       carries headings and nothing else.
     · No control is filled until it is pressed. A bar is a 1px outline with
       a key on the left, a reading on the right, and a trailing glyph.
     · Motion is 80ms linear or it does not happen. Nothing slides, nothing
       scales, nothing eases.
     · 8px rhythm. Rows are 8, gaps are 8, insets are 8 or 16.
   ═══════════════════════════════════════════════════════════════════════════ */

: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:       #05090A;
  --surface:  #0A1211;
  --tint:     #0E1817;
  --tint-2:   #162320;
  --line:     #1E2E2A;
  --ink:      #DFEAE6;
  --ink-2:    #9FB0AB;
  --ink-3:    #7A8A86;
  --accent:   #34E37B;
  --accent-d: #86F5B4;
  --good:     #34E37B;
  --warn:     #FF6B4A;

  /* Saira Condensed is the only web font and it is spent on headings alone.
     Every figure, key, row and readout is system monospace, which costs no
     request and is the entire premise of the interface. */
  --f-h: "Saira Condensed", "Arial Narrow", "Helvetica Neue Condensed", system-ui, sans-serif;
  --f-m: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace;
  --f-t: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;

  --hair: 1px solid var(--line);
  --t: 80ms linear;
  --nav-h: 46px;
}

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

/* 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-m);
  font-size: 13px;
  line-height: 1.4;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
  -webkit-font-smoothing: antialiased;
}

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

/* The glyph sheet itself never renders. */
.sgs { position: absolute; width: 0; height: 0; overflow: hidden; }

/* ── glyphs ────────────────────────────────────────────────────────────────
   One family, drawn on the same grid as the rose: axis-aligned runs and 45
   degree keel strokes, butt caps, mitre joins, 1.5px, no curve anywhere. */

.sg {
  width: 20px; height: 20px; flex: none;
  fill: none; stroke: currentColor;
  stroke-width: 1.5; stroke-linecap: butt; stroke-linejoin: miter;
  vector-effect: non-scaling-stroke;
}
.sg-s { width: 15px; height: 15px; stroke-width: 1.6; }

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

.k {
  font-size: 9.5px; font-weight: 700;
  letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--ink-3);
}

/* Running prose, the only sans in the app and the only thing not on a grid. */
.txt {
  font-family: var(--f-t);
  margin: 0;
  font-size: 12.5px; line-height: 1.55;
  color: var(--ink-2);
}
.txt b { color: var(--ink); font-weight: 600; }

.fine {
  font-family: var(--f-t);
  margin: 16px 0 0;
  font-size: 10.5px; line-height: 1.5;
  color: var(--ink-3);
}

/* ── section head: the rule every block hangs from ─────────────────────── */

.hd {
  display: flex; align-items: baseline; gap: 8px;
  margin: 16px 0 0;
  padding-bottom: 5px;
  border-bottom: var(--hair);
}
.hd-k {
  font-family: var(--f-h);
  font-size: 15px; font-weight: 700;
  letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--ink);
}
.hd-v {
  margin-left: auto;
  font-size: 9.5px; font-weight: 700;
  letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--ink-3);
}
.hd-v.is-done { color: var(--good); }

/* ── the one control shape: a full width bar ───────────────────────────── */

.cmd {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  column-gap: 8px;
  width: 100%;
  margin-top: 8px;
  padding: 11px 10px;
  border: var(--hair);
  background: none;
  color: var(--ink);
  transition: background var(--t), border-color var(--t), color var(--t);
}
.cmd-k {
  font-family: var(--f-h);
  font-size: 16px; font-weight: 700;
  letter-spacing: 0.06em; text-transform: uppercase;
  line-height: 1.1;
}
.cmd-s {
  grid-column: 1;
  margin-top: 3px;
  font-size: 10.5px;
  color: var(--ink-3);
}
.cmd-s i { display: block; font-style: normal; }
.cmd-s i:empty { display: none; }
.cmd-g { grid-column: 2; grid-row: 1 / span 2; color: var(--ink-3); }
.cmd:active { background: var(--tint-2); }

/* The live bar states its colour in the border and the glyph, never a fill. */
.cmd--live { border-color: var(--accent); color: var(--accent-d); }
.cmd--live .cmd-g { color: var(--accent); }
.cmd--live .cmd-s { color: var(--ink-2); }
.cmd--live:active { background: var(--tint-2); }

/* Square control, used for back / pause / close. */
.key {
  width: 32px; height: 32px; flex: none;
  display: grid; place-items: center;
  border: var(--hair);
  color: var(--ink-2);
  transition: background var(--t), color var(--t);
}
.key:active { background: var(--tint-2); color: var(--accent-d); }

/* ── splash: a bearing stamp, not a logo reveal ────────────────────────── */

#splash {
  position: fixed; inset: 0; z-index: 90;
  display: flex; flex-direction: column; justify-content: center;
  padding: 0 24px;
  background: var(--bg);
  transition: opacity var(--t);
}
#splash.out { opacity: 0; }
.bt { border-top: var(--hair); border-bottom: var(--hair); padding: 14px 0; }
.bt-g { display: block; color: var(--accent); }
.bt-g .sg { width: 34px; height: 34px; }
.bt-n {
  font-family: var(--f-h);
  margin-top: 10px;
  font-size: 40px; font-weight: 700;
  letter-spacing: 0.1em; text-transform: uppercase;
  line-height: 1;
}
.bt-s {
  margin-top: 8px;
  font-size: 10px; font-weight: 700;
  letter-spacing: 0.18em; text-transform: uppercase;
  color: var(--ink-3);
}

/* ── 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 app level brand bar: every panel prints its own head. Each
   panel therefore carries the fullscreen top inset itself, in its own
   padding, which is the only placement that is unambiguously inside the
   scrolling box. */
.pane {
  position: absolute; inset: 0;
  display: none; flex-direction: column;
  overflow-y: auto;
  padding: 0 14px 24px;
  padding-top: max(var(--tg-safe-top), env(safe-area-inset-top, 0px));
}
[data-fullscreen="1"] .pane {
  padding-top: max(var(--tg-safe-top),
    calc(max(var(--tg-safe-top), env(safe-area-inset-top, 0px)) - 1.4vh));
}
.pane.is-active { display: flex; }

/* A scrolling flex column shrinks its children by default, so anything whose
   height comes from CSS rather than from text collapses. Pin every child at
   its natural size. Play is excluded: its well is the one element in the app
   that IS meant to take the leftover space. */
.pane:not(.pane--play) > * { flex: none; }
.pane--play { overflow: hidden; padding: 0 10px 8px; }

/* ── bottom tab bar: four bearings on the same rule ────────────────────────
   A flex-column child of #app, so it pins to the bottom of the fixed
   viewport above the scrolling content. One rule above, one rule between
   cells, and the live tab is flagged by a 2px bar across its top edge
   rather than by a fill. Pads the bottom safe-area inset. */
.tabs {
  flex: none;
  display: grid; grid-template-columns: repeat(4, 1fr);
  border-top: var(--hair);
  background: var(--bg);
  padding-bottom: max(var(--tg-safe-bottom), env(safe-area-inset-bottom, 0px));
}
.tab {
  position: relative;
  display: flex; align-items: center; justify-content: center; gap: 6px;
  height: var(--nav-h);
  color: var(--ink-3);
  font-size: 9px; font-weight: 700;
  letter-spacing: 0.14em; text-transform: uppercase;
  transition: color var(--t), background var(--t);
}
.tab + .tab { border-left: var(--hair); }
.tab:active { background: var(--tint); }
.tab.is-on { color: var(--accent-d); }
.tab.is-on::before {
  content: ""; position: absolute; left: 0; right: 0; top: -1px;
  height: 2px; background: var(--accent);
}

/* Play is the game and nothing else: the tab bar steps aside. */
[data-screen="play"] .tabs { display: none; }

/* ── home: the stamp line ──────────────────────────────────────────────── */

.stamp {
  display: flex; align-items: center; gap: 8px;
  margin-top: 10px;
  padding-bottom: 8px;
  border-bottom: 2px solid var(--line);
}
.stamp-g { color: var(--accent); display: flex; }
.stamp-n {
  font-family: var(--f-h);
  font-size: 20px; font-weight: 700;
  letter-spacing: 0.12em; text-transform: uppercase;
}
.stamp-r {
  margin-left: auto;
  display: inline-flex; align-items: center; gap: 6px;
  padding: 3px 7px;
  border: var(--hair);
  color: var(--accent-d);
  font-size: 9.5px; font-weight: 700;
  letter-spacing: 0.12em; text-transform: uppercase;
}

/* ══ the module this game earns: the BEARING ROSE ═══════════════════════════
   A rotate-fit game has neither lanes nor branches. It has four detents 45
   degrees apart and an arc of slop around whichever one you are holding, so
   the home panel prints exactly that: the keel's four headings drawn through
   one centre, the clearance shaded around the heading you start on, and the
   detent table underneath giving the bearing and the tap count for each.
   Nothing here is a decoration; every mark is a number the game uses. */

.hx { margin-top: 10px; }
.hx-face { display: grid; grid-template-columns: 1fr 150px; gap: 12px; align-items: start; }

.hx-num {
  display: block;
  font-size: 46px; font-weight: 500;
  letter-spacing: -0.02em; line-height: 0.9;
  color: var(--ink);
}
.hx-u { display: block; margin-top: 6px; }
.hx-u i {
  display: block; font-style: normal;
  margin-top: 2px;
  font-size: 9.5px; letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--ink-3);
}

.hx-spec { margin: 12px 0 0; }
.hx-spec div {
  display: flex; align-items: baseline; gap: 8px;
  padding: 4px 0;
  border-top: var(--hair);
}
.hx-spec dt {
  font-size: 9.5px; font-weight: 700;
  letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--ink-3);
}
.hx-spec dd { margin: 0 0 0 auto; font-size: 11.5px; color: var(--ink-2); }
.hx-spec dd b { color: var(--accent-d); font-weight: 500; }

/* The rose. Straight lines only: 24 rim ticks at 15 degrees, four detent
   spokes drawn as full diameters with a square stop at each end, the
   clearance printed as a flat topped wedge because a zero radius instrument
   is not allowed to draw an arc, and the keel parked on the rest heading. */
.rose { display: block; width: 150px; height: 150px; }
.rose-tick { stroke: var(--ink-3); stroke-width: 1.5; opacity: 0.45; }
.rose-spoke { stroke: var(--ink-3); stroke-width: 1; }
.rose-stop { fill: none; stroke: var(--ink-3); stroke-width: 1.5; }
.rose-rest { stroke: var(--accent); stroke-width: 1.5; }
.rose-rest-stop { fill: var(--accent); stroke: none; }
.rose-arc { fill: var(--accent); opacity: 0.13; }
.rose-edge { stroke: var(--accent); stroke-width: 1; stroke-dasharray: 3 4; opacity: 0.7; }
.rose-keel { fill: var(--accent); }

.hx-cap {
  font-family: var(--f-t);
  margin: 10px 0 0;
  font-size: 10.5px; line-height: 1.5;
  color: var(--ink-3);
}

.hx-cols {
  display: grid; grid-template-columns: 34px 1fr 58px 34px;
  gap: 8px;
  margin-top: 12px;
  padding-bottom: 4px;
  border-bottom: var(--hair);
  font-size: 9px; font-weight: 700;
  letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--ink-3);
}
.hx-cols span:nth-child(3) { text-align: right; }
.hx-cols span:nth-child(4) { text-align: center; }

.hx-det { list-style: none; margin: 0; padding: 0; }
.det {
  display: grid; grid-template-columns: 34px 1fr 58px 34px;
  gap: 8px; align-items: center;
  height: 32px;
  border-bottom: var(--hair);
  font-size: 12px;
}
.det-n { color: var(--ink-3); }
.det-b { color: var(--ink); letter-spacing: 0.04em; }
.det-t { text-align: right; color: var(--ink-2); }
.det-k { display: flex; align-items: center; justify-content: center; height: 100%; color: var(--ink-3); }
.det-k i { display: block; width: 22px; height: 2px; background: currentColor; }

/* The keel in the last column is drawn at the bearing of its own row. */
.det:nth-child(1) .det-k i { transform: rotate(90deg); }
.det:nth-child(2) .det-k i { transform: rotate(45deg); }
.det:nth-child(3) .det-k i { transform: rotate(0deg); }
.det:nth-child(4) .det-k i { transform: rotate(-45deg); }

/* The heading the run starts on. It is the only lit row in the table, and it
   is flagged with its own class: .is-active belongs to shell.js. */
.det--rest .det-n,
.det--rest .det-b,
.det--rest .det-t { color: var(--accent-d); }
.det--rest .det-k { color: var(--accent); }

/* ── target and log ────────────────────────────────────────────────────── */

.due {
  display: flex; align-items: baseline; gap: 8px;
  padding: 8px 0 6px;
  font-size: 12px;
}
.due-l { color: var(--ink-2); min-width: 0; }
.due-v { margin-left: auto; color: var(--ink); }

/* One 8px channel with a 1px border. The fill is the only solid in the app
   that is not a glyph, because a gauge with no fill is not a gauge. */
.rng { height: 8px; border: var(--hair); }
.rng > i { display: block; height: 100%; width: 0; background: var(--accent); transition: width var(--t); }
.rng > i.is-low { background: var(--warn); }

.log { display: grid; grid-template-columns: repeat(4, 1fr); margin-top: 8px; }
.log-c { padding: 8px 6px; border-top: var(--hair); border-bottom: var(--hair); }
.log-c + .log-c { border-left: var(--hair); }
.log-c b { display: block; font-size: 18px; font-weight: 500; color: var(--ink); }
.log-c span {
  display: block; margin-top: 3px;
  font-size: 8.5px; font-weight: 700;
  letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--ink-3);
}

.extra span:empty { display: none; }

/* ── play: the helm strip ──────────────────────────────────────────────── */

.helm {
  flex: none;
  display: flex; align-items: center; gap: 8px;
  padding: 8px 0;
  border-bottom: var(--hair);
}
.helm-sc { display: flex; align-items: baseline; gap: 6px; margin-right: auto; }
.helm-v { font-size: 26px; font-weight: 500; line-height: 1; color: var(--ink); }
.helm-k {
  font-style: normal;
  font-size: 9px; font-weight: 700;
  letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--ink-3);
}
.helm-x {
  padding: 3px 6px;
  border: 1px solid var(--accent);
  color: var(--accent-d);
  font-size: 11px; font-weight: 700;
  opacity: 0;
}
.helm-x:empty { display: none; }
.helm-x.is-on { opacity: 1; }
.helm-sh {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 3px 6px;
  border: var(--hair);
  color: var(--ink-2);
  font-size: 9px; font-weight: 700;
  letter-spacing: 0.1em; text-transform: uppercase;
}

.clr { flex: none; display: flex; align-items: center; gap: 8px; padding: 8px 0; }
.clr .k { flex: none; }
.clr .rng { flex: 1; }

/* The well: the water, framed by the same hairline as everything else and
   lifted by nothing at all. */
.well { flex: 1; min-height: 0; position: relative; border: var(--hair); overflow: hidden; }
#stage { display: block; width: 100%; height: 100%; touch-action: none; }

/* ── play: the helm check ──────────────────────────────────────────────── */

.check {
  position: absolute; inset: 0; z-index: 2;
  display: flex; align-items: center; justify-content: center;
  padding: 16px;
  background: rgba(5, 9, 10, 0.9);
}
.check-in { width: 100%; max-width: 320px; }

/* Three lines, keyed by the number each one changes rather than by a word.
   The whole point of the game is in the left column. */
.ln { display: grid; grid-template-columns: 68px 1fr; gap: 10px; padding: 9px 0; border-top: var(--hair); }
.ln-k {
  font-size: 12px; font-weight: 700;
  line-height: 1.35;
  color: var(--accent-d);
}
.ln-v { font-family: var(--f-t); font-size: 11.5px; line-height: 1.5; color: var(--ink-2); }
.ln-v b { color: var(--ink); font-weight: 600; }
.ln:last-of-type { border-bottom: var(--hair); }

/* ── rank ──────────────────────────────────────────────────────────────── */

.scope { display: grid; grid-template-columns: 1fr 1fr; margin-top: 8px; border: var(--hair); }
.seg-btn {
  display: flex; align-items: center; justify-content: center; gap: 6px;
  padding: 9px 4px;
  color: var(--ink-3);
  font-size: 10px; font-weight: 700;
  letter-spacing: 0.12em; text-transform: uppercase;
  transition: color var(--t), background var(--t);
}
.seg-btn + .seg-btn { border-left: var(--hair); }
.seg-btn.is-on { color: var(--accent-d); background: var(--tint); }

.ldg-h {
  display: grid; grid-template-columns: 26px 26px 1fr auto;
  gap: 8px; align-items: center;
  margin-top: 12px;
  padding-bottom: 4px;
  border-bottom: var(--hair);
  font-size: 9px; font-weight: 700;
  letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--ink-3);
}
.ldg-h span:last-child { text-align: right; }

.ldg { display: flex; flex-direction: column; }

/* shell.js writes these five class names into every generated row. */
.rw {
  display: grid; grid-template-columns: 26px 26px 1fr auto;
  gap: 8px; align-items: center;
  height: 36px;
  border-bottom: var(--hair);
}
.rw-pos { font-size: 11px; color: var(--ink-3); }
.rw-av {
  display: grid; place-items: center;
  width: 22px; height: 22px;
  border: 1px solid hsl(var(--h, 150) 22% 30%);
  color: var(--ink-2);
  font-size: 10px; font-weight: 700;
}
.rw-nm { font-size: 12.5px; color: var(--ink); min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rw-sc { font-size: 13px; color: var(--ink); }
.rw--top .rw-pos { color: var(--accent-d); }
.rw--me { background: var(--tint); }
.rw--me .rw-nm { color: var(--accent-d); }
.rw--me .rw-sc { color: var(--accent-d); }

/* ── more ──────────────────────────────────────────────────────────────── */

.entry {
  display: flex; align-items: center; gap: 10px;
  width: 100%;
  min-height: 42px;
  padding: 8px 0;
  border-bottom: var(--hair);
  color: var(--ink);
  font-size: 12.5px;
  transition: background var(--t);
}
.entry > span { flex: 1; min-width: 0; }
.entry > .sg { color: var(--ink-3); }
.entry--go:active { background: var(--tint); }
.entry-g { color: var(--ink-3); }

/* The switch: a square gate with a square shuttle in it. */
.sw {
  appearance: none; -webkit-appearance: none;
  flex: none;
  width: 40px; height: 20px;
  border: var(--hair);
  background: none;
  position: relative;
  transition: border-color var(--t);
}
.sw::after {
  content: ""; position: absolute; top: 3px; left: 3px;
  width: 12px; height: 12px;
  background: var(--ink-3);
  transition: transform var(--t), background var(--t);
}
.sw:checked { border-color: var(--accent); }
.sw:checked::after { transform: translateX(20px); background: var(--accent); }

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

.mask { position: fixed; inset: 0; z-index: 40; background: rgba(5, 9, 10, 0.86); }

/* A document, not a card: full bleed to the bottom edge, ruled at the top. */
.doc {
  position: fixed; z-index: 50;
  left: 0; right: 0; bottom: 0;
  display: flex; flex-direction: column;
  max-height: calc(100dvh - max(var(--tg-safe-top), env(safe-area-inset-top, 0px)) - 24px);
  background: var(--bg);
  border-top: 2px solid var(--line);
  /* Deliberately not animated. A sheet that slides in from below sits, for
     the length of the animation, with its own Close control under the fold. */
}
.doc-h {
  flex: none;
  display: flex; align-items: center; gap: 10px;
  padding: 12px 14px;
  border-bottom: var(--hair);
}
.doc-h b {
  flex: 1; min-width: 0;
  font-family: var(--f-h);
  font-size: 17px; font-weight: 700;
  letter-spacing: 0.08em; text-transform: uppercase;
}
.doc-b {
  flex: 1; min-height: 0;
  overflow-y: auto;
  padding: 14px 14px 4px;
  font-family: var(--f-t);
  font-size: 12.5px; line-height: 1.6;
  color: var(--ink-2);
}
.doc-b p { margin: 0 0 12px; }
.doc-b ul { margin: 0 0 12px; padding: 0; list-style: none; }
.doc-b li { position: relative; padding-left: 18px; margin-bottom: 10px; }
.doc-b li::before {
  content: ""; position: absolute; left: 0; top: 7px;
  width: 7px; height: 7px;
  border: 1px solid var(--accent);
}
.doc-b b { color: var(--ink); font-weight: 600; }
.doc-f {
  flex: none;
  padding: 8px 14px;
  padding-bottom: calc(12px + max(var(--tg-safe-bottom), env(safe-area-inset-bottom, 0px)));
  border-top: var(--hair);
}

/* Dialogs are full width bands ruled top and bottom. A floating card implies
   elevation and there is none anywhere in this app. */
.box {
  position: fixed; inset: 0; z-index: 55;
  display: flex; align-items: center;
  padding: 0;
  pointer-events: none;
}
.box-in {
  pointer-events: auto;
  width: 100%;
  padding: 16px 14px;
  padding-bottom: calc(16px + max(var(--tg-safe-bottom), env(safe-area-inset-bottom, 0px)));
  background: var(--bg);
  border-top: 2px solid var(--line);
  border-bottom: 2px solid var(--line);
}
.rep { display: flex; align-items: baseline; gap: 8px; padding: 10px 0 12px; border-bottom: var(--hair); }
.rep-n { font-size: 52px; font-weight: 500; line-height: 0.9; color: var(--accent-d); }
.rep-u {
  font-size: 9.5px; font-weight: 700;
  letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--ink-3);
}
.rep-s { margin-left: auto; font-size: 11.5px; color: var(--ink-2); }
.box-p { font-family: var(--f-t); margin: 10px 0 0; font-size: 12px; line-height: 1.5; color: var(--ink-2); }
.box-t { display: flex; align-items: center; gap: 8px; margin: 10px 0 0; font-size: 12.5px; color: var(--ink); }
.box-btns { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin-top: 8px; }
.box-btns .cmd { margin-top: 0; }

/* The revive countdown: a bare figure on the water, no ring, no card. */
.cd { position: fixed; inset: 0; z-index: 60; display: grid; place-items: center; pointer-events: none; }
.cd span {
  font-size: 96px; font-weight: 500; line-height: 1;
  color: var(--accent);
  border-top: 2px solid var(--accent);
  border-bottom: 2px solid var(--accent);
  padding: 6px 24px;
}

.tip {
  position: fixed; z-index: 70;
  left: 0; right: 0;
  bottom: calc(var(--nav-h) + max(var(--tg-safe-bottom), env(safe-area-inset-bottom, 0px)));
  padding: 11px 14px;
  background: var(--bg);
  border-top: var(--hair);
  border-bottom: var(--hair);
  font-size: 11.5px;
  color: var(--ink);
}

/* ── reduce motion: there is barely any, and this removes the rest ─────── */

[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 rose gives first, then the record figure. */
@media (max-height: 690px) {
  .hx-face { grid-template-columns: 1fr 120px; }
  .rose { width: 120px; height: 120px; }
  .hx-num { font-size: 38px; }
  .bt-n { font-size: 32px; }
  .rep-n { font-size: 42px; }
  .cd span { font-size: 76px; }
}

/* Narrow phones: the detent table keeps its columns, the rose steps under. */
@media (max-width: 340px) {
  .hx-face { grid-template-columns: 1fr; }
  .rose { margin-top: 8px; }
}
