/* ============================================================================
   onion/styles.css

   Used in a kitchen: one hand, wet fingers, a phone propped against the
   backsplash. So the steppers are big, the plan is readable at arm's length,
   and two of the site's rules carry most of the weight:

     ZERO LAYOUT SHIFT. The drawings redraw on every tap at a height that
     depends only on the onion's proportions, and the prediction lands in a
     slot with a fixed min-height — so a result arriving never moves the
     button under a thumb.

     COLOUR IS NEVER THE ONLY SIGNAL. Every chart has a legend or a title that
     names its one series, and a table of the same numbers.

   The glass tokens come from /site.css.
   ========================================================================== */

:root {
  --bg: #0e1116;
  --ink: #e8edf2;
  --muted: #93a1b0;
  --line: #2a323d;
  --gold: #f0c419;
  --accent: #4aa8ff;
  --shadow: 0 6px 24px rgba(0, 0, 0, .35);
  --mono: ui-monospace, "JetBrains Mono", "SF Mono", Menlo, Consolas, monospace;

  /* chart series: the validated dark-surface categorical steps, in order */
  --s1: #3987e5;
  --s2: #d95926;
  --s3: #199e70;
  --ctx: rgba(232, 237, 242, .20);

  /* the onion itself */
  --flesh: rgba(244, 228, 196, .10);
  --flesh-line: rgba(244, 228, 196, .30);
  --skin: rgba(244, 228, 196, .75);
}

* { box-sizing: border-box; }
html, body { margin: 0; }
body {
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  background: var(--g-bg, var(--bg));
  color: var(--ink);
  line-height: 1.5;
  padding-bottom: 40px;
}
h1, h2, h3, h4 { margin: 0 0 .4em; font-weight: 650; }
a { color: var(--accent); }
.muted { color: var(--muted); }
.small { font-size: .84rem; }
button { font: inherit; cursor: pointer; -webkit-tap-highlight-color: transparent; touch-action: manipulation; }
code { font-family: var(--mono); font-size: .88em; }

/* ---------- top bar ---------- */
.topbar {
  text-align: center;
  padding: 22px 16px 14px;
  background: linear-gradient(180deg, rgba(11, 107, 58, .62), rgba(8, 74, 40, .38));
  border-bottom: 2px solid rgba(240, 196, 25, .45);
  box-shadow: var(--g-hi), var(--shadow);
  -webkit-backdrop-filter: var(--g-blur); backdrop-filter: var(--g-blur);
}
.brand { display: flex; gap: .5rem; align-items: center; justify-content: center; }
.brand h1 { font-size: 1.6rem; letter-spacing: .3px; margin: 0; }
.bulb { font-size: 1.5rem; }
.tagline { margin: 6px 0 0; color: #d8efe0; font-size: .9rem; }

/* ---------- layout ---------- */
main { max-width: 980px; margin: 16px auto; padding: 0 16px; display: flex; flex-direction: column; gap: 16px; }
.panel {
  background: var(--g-sheen), var(--g-base);
  border: 1px solid var(--g-line);
  border-radius: var(--g-r-lg, 16px);
  padding: 16px 18px;
  box-shadow: var(--g-hi), var(--g-lo), var(--shadow);
  -webkit-backdrop-filter: var(--g-blur); backdrop-filter: var(--g-blur);
}
.panel > h2 { font-size: 1.08rem; color: var(--gold); }
.placeholder { color: var(--muted); text-align: center; padding: 18px 8px; margin: 0; }

/* ---------- the short version ---------- */
.short summary { cursor: pointer; list-style: none; display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.short summary::-webkit-details-marker { display: none; }
.short summary::before { content: '▸'; color: var(--gold); transition: transform .15s ease; }
.short[open] summary::before { transform: rotate(90deg); }
.short-h { color: var(--gold); font-weight: 650; font-size: 1.02rem; }
.short ol { margin: 10px 0 6px; padding-left: 1.3em; display: flex; flex-direction: column; gap: 6px; color: #c3cdd8; font-size: .94rem; }
.short ol b { color: var(--ink); }
.short ol a { font-size: .82rem; margin-left: 4px; }
.short p { margin: 4px 0 0; }

/* ---------- inputs ---------- */
.inputs { display: flex; flex-wrap: wrap; gap: 12px 18px; align-items: flex-end; }
.field { display: flex; flex-direction: column; gap: 5px; }
.field label, .field .lbl { font-size: .8rem; color: var(--muted); font-weight: 600; }
.stepper {
  display: inline-flex; align-items: center;
  border: 1px solid var(--g-line); border-radius: 12px; background: var(--g-well); overflow: hidden;
}
.stepper button {
  width: 44px; height: 44px; border: none; background: var(--g-in-fill); color: var(--ink);
  font-size: 1.3rem; font-weight: 600; line-height: 1;
}
.stepper button:active { background: var(--g-in-fill-hover); }
.stepper input {
  width: 58px; height: 44px; border: none; background: transparent; color: var(--ink);
  font: 650 1.15rem var(--mono); text-align: center; -moz-appearance: textfield; appearance: textfield;
}
.stepper input::-webkit-outer-spin-button, .stepper input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }

.segmented { display: inline-flex; border: 1px solid var(--g-line); border-radius: 12px; overflow: hidden; background: var(--g-well); }
.segmented button {
  min-height: 44px; padding: 5px 13px; border: none; border-right: 1px solid var(--g-line);
  background: transparent; color: var(--muted); display: flex; flex-direction: column; align-items: center; justify-content: center;
  font-size: .86rem; font-weight: 650; line-height: 1.15;
}
.segmented button:last-child { border-right: none; }
.segmented button .sub { font-size: .7rem; font-weight: 500; opacity: .8; }
.segmented button.active { background: linear-gradient(180deg, #ffd955, var(--gold)); color: #241c02; }
.hint { margin: 10px 0 0; }

/* ---------- the drawings ---------- */
.views { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; margin-top: 14px; }
.view { margin: 0; min-width: 0; }
.view figcaption { font-size: .8rem; color: var(--muted); font-weight: 600; margin-bottom: 4px; }
.guide { width: 100%; }
.guide svg { display: block; margin: 0 auto; touch-action: manipulation; }
.cutinfo { min-height: 2.6em; margin: 4px 0 0; color: #c3cdd8; }

.g-board { fill: rgba(255, 255, 255, .025); }
.g-boardline { stroke: rgba(255, 255, 255, .35); stroke-width: 1.5; }
.g-flesh { fill: var(--flesh); stroke: none; }
.g-layer { fill: none; stroke: var(--flesh-line); stroke-width: 1; }
.g-skin { fill: none; stroke: var(--skin); stroke-width: 1.5; }
.g-cut { stroke: var(--gold); stroke-width: 1.6; stroke-linecap: round; fill: none; }
.g-cut.thin { stroke-width: 1.2; opacity: .9; }
.g-cut.on { stroke: #fff; stroke-width: 3; }
.g-hit { stroke: transparent; stroke-width: 18; cursor: pointer; }
.g-aimray { stroke: rgba(240, 196, 25, .28); stroke-width: 1; }
.g-aim { fill: var(--gold); stroke: var(--g-bg, #0a0d13); stroke-width: 2; }
.g-cross { stroke: rgba(232, 237, 242, .65); stroke-width: 1.2; }
.g-trimcut { stroke: rgba(232, 237, 242, .35); stroke-width: 1.2; }
.g-trim { fill: rgba(0, 0, 0, .35); }
.g-stub { fill: rgba(240, 196, 25, .12); }
.g-lbl { fill: #c3cdd8; font-size: 11.5px; font-weight: 600; }
.g-lbl.dim { fill: var(--muted); }
.g-lbl.gold { fill: var(--gold); }

/* ---------- the explode view ---------- */
/* Seven size bins, log-symmetric about the typical piece: warm for small
   (they scorch), cool for large, a neutral grey between. Brightness and
   saturation rise away from the middle, so the extremes are what you see. */
.pc-0 { --pc: #f07a6e; }
.pc-1 { --pc: #cf5b4c; }
.pc-2 { --pc: #9c6a5f; }
.pc-3 { --pc: #77746c; }
.pc-4 { --pc: #5f7fa6; }
.pc-5 { --pc: #3f82d6; }
.pc-6 { --pc: #74aef0; }
.xp-pc {
  fill: transparent; stroke: none; cursor: pointer;
  transform-origin: 0 0;
  transition: transform .45s cubic-bezier(.3, .7, .2, 1), fill .3s ease;
}
svg.exploded .xp-pc { fill: var(--pc); stroke: var(--g-bg, #0a0d13); stroke-width: .8; vector-effect: non-scaling-stroke; }
svg.exploded .xp-pc.on { stroke: #fff; stroke-width: 2; }
.g-plan { transition: opacity .3s ease; }
svg.exploded .g-plan { opacity: 0; pointer-events: none; }
.guide.stale .xp { opacity: .45; }
@media (prefers-reduced-motion: reduce) { .xp-pc, .g-plan { transition: none; } }

/* The 3D view lies over the end view in the same box, and the two cross-fade:
   its first frame is the drawing, square on to the stem end at the same
   scale. Sideways drags turn it; vertical ones are left to scroll the page. */
.xp-stage { position: relative; }
.xp-stage .guide svg { transition: opacity .35s ease; }
.xp-stage.gl .guide svg { opacity: 0; pointer-events: none; }
.xp3d {
  position: absolute; inset: 0; width: 100%; height: 100%; display: block;
  opacity: 0; pointer-events: none; transition: opacity .35s ease;
  touch-action: pan-y; cursor: grab; -webkit-tap-highlight-color: transparent;
}
.xp-stage.gl .xp3d { opacity: 1; pointer-events: auto; }
.xp3d.drag { cursor: grabbing; }
@media (prefers-reduced-motion: reduce) { .xp3d, .xp-stage .guide svg { transition: none; } }

.xp-bar { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-top: 8px; }
.xp-toggle {
  min-height: 40px; padding: 0 16px; border-radius: 999px; font-weight: 650; font-size: .88rem;
  color: var(--ink); background: var(--g-in-fill); border: 1px solid var(--g-line);
}
.xp-toggle[aria-pressed="true"] { background: linear-gradient(180deg, #ffd955, var(--gold)); color: #241c02; border-color: rgba(255, 230, 140, .7); }
.xp-slice { display: inline-flex; align-items: center; gap: 8px; font-size: .8rem; color: var(--muted); font-weight: 600; flex: 1 1 160px; }
.xp-slice input { flex: 1 1 auto; min-width: 90px; accent-color: var(--gold); }
.xp-slice input:disabled { opacity: .35; }
.xp-slice output { font: 600 .8rem var(--mono); min-width: 3.6em; text-align: right; color: #c3cdd8; }
/* the key keeps its line whether or not the view is exploded */
.xp-legend { display: flex; flex-direction: column; gap: 3px; margin-top: 8px; visibility: hidden; }
.xp-legend.shown { visibility: visible; }
.xp-swatches { display: flex; gap: 2px; }
.xp-sw { flex: 1 1 0; height: 18px; border-radius: 4px; background: var(--pc); display: flex; align-items: center; justify-content: center; }
.xp-sw span { font-size: .66rem; font-weight: 700; color: #0b0e13; white-space: nowrap; }
.xp-sw.pc-3 span, .xp-sw.pc-2 span, .xp-sw.pc-4 span { color: #eef2f6; }
/* two lines held for the caption whichever colouring it describes, so
   switching Size and Cooking moves nothing below it */
.xp-cap { font-size: .72rem; color: var(--muted); min-height: 3em; }

/* ---------- the article's model, live ---------- */
.aw { margin-top: 12px; display: flex; flex-direction: column; gap: 10px; }
.aw-presets { display: flex; gap: 6px; flex-wrap: wrap; }
.aw-presets button {
  min-height: 36px; padding: 0 12px; border-radius: 999px; font-size: .8rem; font-weight: 650;
  color: #c3cdd8; background: var(--g-in-fill); border: 1px solid var(--g-line);
}
.aw-presets button.active { color: #241c02; background: linear-gradient(180deg, #ffd955, var(--gold)); border-color: rgba(255, 230, 140, .7); }
.aw-inputs { gap: 10px 14px; }
.aw-inputs .stepper button { width: 38px; height: 38px; }
.aw-inputs .stepper input { width: 40px; height: 38px; font-size: 1rem; }
.aw-inputs .segmented button { min-height: 38px; }
.aw-depth { flex: 1 1 220px; }
.aw-range { display: flex; align-items: center; gap: 10px; min-height: 38px; }
.aw-range input { flex: 1 1 auto; accent-color: var(--gold); }
.aw-range input:disabled { opacity: .35; }
.aw-range output { font: 650 .95rem var(--mono); min-width: 3.4em; text-align: right; }
.aw-fig { width: 100%; }
.aw-fig svg { display: block; margin: 0 auto; }
.aw-read { margin: 0; min-height: 3em; font-size: .9rem; color: #c3cdd8; }
.aw-read b { color: var(--ink); font-family: var(--mono); }

/* ---------- the colour toggle ---------- */
.xp-colour button { min-height: 40px; padding: 4px 12px; }

/* ---------- onion drawings (draw.js) ---------- */
.g-root { fill: rgba(120, 96, 60, .55); }
.g-slice { stroke: rgba(240, 196, 25, .7); stroke-width: 1.2; }
.g-lbl.strong { fill: var(--ink); }
.iso-host { margin-top: 6px; }
.iso-top { fill: rgba(244, 228, 196, .55); stroke: var(--g-bg, #0a0d13); stroke-width: 1; }
.iso-l { fill: rgba(244, 228, 196, .32); stroke: var(--g-bg, #0a0d13); stroke-width: 1; }
.iso-r { fill: rgba(244, 228, 196, .20); stroke: var(--g-bg, #0a0d13); stroke-width: 1; }
.shape-fig { margin-top: 10px; }
.shape-pair { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; margin-top: 10px; }
.shape-trio { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; margin-top: 10px; }
.shape-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px; margin-top: 10px; }
.shape-cell { margin: 0; min-width: 0; }
.shape-cell figcaption { font-size: .8rem; color: #c3cdd8; margin-bottom: 4px; }
.shape-cell svg { display: block; }
.shape-facts { margin: 4px 0 0; font-size: .76rem; color: var(--muted); line-height: 1.45; }
.ch-rowlbl.strong { fill: var(--gold); font-weight: 650; }
@media (max-width: 760px) {
  .shape-pair, .shape-trio { grid-template-columns: 1fr; }
  .shape-grid { grid-template-columns: 1fr 1fr; }
}

.steps { margin: 14px 0 0; padding-left: 1.4em; display: flex; flex-direction: column; gap: 8px; font-size: .97rem; }
.steps b { color: var(--gold); font-weight: 700; }
.more { margin-top: 14px; }
.more summary { cursor: pointer; color: var(--muted); font-weight: 650; font-size: .88rem; }
.more .inputs { margin-top: 10px; }

/* ---------- the prediction ---------- */
.predictor .inputs { margin-top: 6px; }
.go {
  margin-top: 14px; min-height: 46px; padding: 0 26px; border-radius: 999px; font-weight: 700; color: #04121f;
  background: linear-gradient(180deg, #7cc0ff, var(--accent)); border: 1px solid rgba(190, 224, 255, .6);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .45), 0 6px 16px rgba(74, 168, 255, .28);
}
.go:disabled { opacity: .55; cursor: progress; }
/* The table is drawn with dashes before the first run, so empty, working and
   full are the same shape; the min-height only covers font-loading jitter. */
.pred-slot { min-height: 262px; margin-top: 12px; transition: opacity .15s ease; }
.pred-slot.stale table, .pred-slot.stale .pred-note, .pred-slot.busy table { opacity: .45; }
.pred-status { min-height: 1.4em; margin: 6px 0 0; color: var(--gold); font-size: .86rem; }
.pred-table { width: 100%; border-collapse: collapse; font-size: .92rem; }
.pred-table th, .pred-table td { padding: 6px 8px; border-bottom: 1px solid var(--g-in-line); text-align: right; vertical-align: top; }
.pred-table thead th { color: var(--muted); font-size: .78rem; font-weight: 650; }
.pred-table tbody th { text-align: left; font-weight: 650; }
.pred-table td { font: 650 1rem var(--mono); }
.pred-table .help { display: block; font-size: .72rem; font-weight: 400; color: var(--muted); }
/* three lines reserved: the note grows from the one-line prompt to the result */
.pred-note { margin: 10px 0 0; font-size: .88rem; color: #c3cdd8; min-height: 4.5em; }
@media (min-width: 761px) { .pred-note { min-height: 3em; } }
.pred-note b { color: var(--gold); }

/* ---------- tabs ---------- */
/* The tabs are the site's tier-2 .mode-tabs (site.css). A tab is a column of
   panels; [hidden] has to beat .findings' display:flex, so it is explicit. */
.tab { display: flex; flex-direction: column; gap: 16px; }
.tab[hidden] { display: none !important; }
.fgroup { display: flex; flex-direction: column; gap: 16px; }
.mode-tabs { max-width: 980px; }

/* ---------- findings ---------- */
.findings { display: flex; flex-direction: column; gap: 16px; }
.intro p { color: #c3cdd8; }
.finding h3 { font-size: 1.02rem; color: var(--ink); display: flex; gap: 8px; align-items: baseline; }
.fnum {
  flex: 0 0 auto; display: inline-flex; align-items: center; justify-content: center;
  width: 24px; height: 24px; border-radius: 50%; background: rgba(240, 196, 25, .14); color: var(--gold);
  font-size: .8rem; font-weight: 800;
}
.finding p { color: #c3cdd8; margin: .5em 0; }
.finding b { color: var(--ink); }
.caveats ul { margin: 6px 0 0; padding-left: 1.2em; color: #c3cdd8; font-size: .92rem; }
.caveats li { margin: 4px 0; }

.tiles { display: flex; gap: 12px; flex-wrap: wrap; margin: 10px 0; }
.tile { flex: 1 1 140px; padding: 12px 14px; border-radius: 12px; background: var(--g-in-fill); border: 1px solid var(--g-in-line); }
.tile-v { font-size: 1.9rem; font-weight: 650; line-height: 1.1; }
.tile-l { color: var(--muted); font-size: .82rem; }

/* ---------- charts ---------- */
.ch-cap { margin: 14px 0 2px !important; font-size: .82rem; font-weight: 650; color: var(--muted) !important; }
.chart { position: relative; }
.ch-box { position: relative; width: 100%; }
.ch-box svg { display: block; overflow: visible; }
.ch-box svg:focus { outline: none; }
.ch-box svg:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 4px; }
.ch-legend { display: flex; flex-wrap: wrap; gap: 4px 14px; margin: 4px 0 6px; font-size: .78rem; color: #c3cdd8; }
.ch-key { display: inline-flex; align-items: center; gap: 6px; }
.ch-key.dim { color: var(--muted); }
.ch-line { display: inline-block; width: 16px; height: 2px; border-radius: 1px; flex: 0 0 auto; }
.ch-grid { stroke: rgba(255, 255, 255, .07); stroke-width: 1; }
.ch-axis { stroke: rgba(255, 255, 255, .22); stroke-width: 1; }
.ch-tick { fill: var(--muted); font-size: 11px; font-variant-numeric: tabular-nums; }
.ch-axlbl { fill: var(--muted); font-size: 11px; }
.ch-rowlbl { fill: #c3cdd8; font-size: 11.5px; }
.ch-ctx { fill: none; stroke-linejoin: round; stroke-linecap: round; }
.ch-line-s { fill: none; stroke-linejoin: round; stroke-linecap: round; }
.ch-dot { stroke: var(--g-bg, #0a0d13); stroke-width: 2; }
.ch-ref { stroke: rgba(232, 237, 242, .45); stroke-width: 1; }
.ch-ref.strong { stroke: var(--gold); stroke-width: 1.5; }
.ch-reflbl { fill: #c3cdd8; font-size: 11px; font-weight: 600; }
.ch-band { fill: rgba(57, 135, 229, .10); }
.ch-bandlbl { fill: var(--muted); font-size: 10.5px; }
.ch-mklbl { fill: var(--ink); font-size: 11px; font-weight: 650; }
.ch-range { opacity: .85; }
.ch-hair { stroke: rgba(232, 237, 242, .4); stroke-width: 1; }
.ch-tip {
  position: absolute; pointer-events: none; z-index: 3; min-width: 150px; max-width: 250px;
  padding: 8px 10px; border-radius: 10px; font-size: .78rem;
  background: rgba(12, 15, 21, .94); border: 1px solid var(--g-line-strong); box-shadow: var(--g-drop);
}
.ch-tiphd { color: var(--muted); margin-bottom: 3px; }
.ch-tiprow { display: flex; align-items: center; gap: 6px; color: #c3cdd8; white-space: nowrap; }
.ch-tiprow b { color: var(--ink); font-variant-numeric: tabular-nums; }
.ch-table { margin-top: 8px; }
.ch-table summary { cursor: pointer; color: var(--muted); font-size: .8rem; font-weight: 650; }
.table-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.ch-table table, table.data { border-collapse: collapse; margin-top: 6px; font-size: .82rem; min-width: 100%; }
.ch-table th, .ch-table td, table.data th, table.data td { padding: 5px 8px; border-bottom: 1px solid var(--g-in-line); text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums; }
.ch-table th:first-child, table.data th:first-child { text-align: left; }
.ch-table thead th, table.data thead th { color: var(--muted); font-weight: 650; }
table.data tr.pick th, table.data tr.pick td { color: var(--gold); }

/* ---------- footer ---------- */
footer { max-width: 980px; margin: 20px auto 0; padding: 0 16px; font-size: .86rem; }
footer summary { cursor: pointer; color: var(--gold); font-weight: 650; }
.foot-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; margin-top: 12px; }
.foot-grid h4 { color: var(--gold); font-size: .9rem; }
.foot-grid p { margin: .5em 0; color: #c3cdd8; }

@media (max-width: 760px) {
  .views { grid-template-columns: 1fr; }
  .foot-grid { grid-template-columns: 1fr; }
}
@media (max-width: 480px) {
  main { padding: 0 10px; gap: 12px; }
  .panel { padding: 14px 13px; }
  .inputs { gap: 10px 12px; }
  .field.wide { width: 100%; }
  .field.wide .segmented { display: flex; }
  .field.wide .segmented button { flex: 1 1 0; padding: 5px 6px; }
  .stepper input { width: 50px; }
  .brand h1 { font-size: 1.4rem; }
}

/* ---------- the game (play.js, game3d.js) ----------
   A phone held in one hand, a thumb doing the cutting. The stage is a fixed
   height at every width and the canvas captures the touch while cutting
   (a swipe must not scroll the page); once the pieces are out, vertical drags
   go back to the page and sideways ones turn the board. Every line around the
   stage holds its height empty, in play and scored. */
/* The game card is controls, not prose. Some of its text could be selected
   (the HUD's chips, the readout, a disabled Undo). On iOS, a dock tap held a
   beat too long, two quick taps, or a thumb in a gap between buttons then
   selected from the stage to the Undo, and the next taps dragged the
   selection's handles instead of the knife. So nothing on the card selects,
   calls up the copy menu or zooms on a double tap. A name field asked for
   under a result is still a field. */
.panel.game { -webkit-user-select: none; user-select: none; -webkit-touch-callout: none; touch-action: manipulation; }
.panel.game input { -webkit-user-select: text; user-select: text; -webkit-touch-callout: default; }
.gm-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; flex-wrap: wrap; }
.gm-head h2 { margin: 0; font-size: 1.08rem; color: var(--gold); }
.gm-mode button { min-height: 38px; padding: 4px 16px; }
.gm-range button { min-height: 34px; padding: 3px 12px; font-size: .8rem; }
.gm-board .gm-head { margin-bottom: 4px; }
.gm-brief { margin: 10px 0 10px; min-height: 3.1em; font-size: .9rem; color: #c3cdd8; line-height: 1.45; }
.gm-brief b { color: var(--ink); }
.gm-brief .muted { display: block; font-size: .8rem; }
/* how rare the onion is: grey, green, blue, the colours games have taught
   everyone; a rare one shimmers, so turning one up is noticed */
.gm-rar {
  display: inline-block; padding: 0 7px; border-radius: 999px; font-size: .72rem; font-weight: 750; letter-spacing: .03em;
  text-transform: uppercase; vertical-align: 1px; color: #c9d1da; border: 1px solid rgba(201, 209, 218, .4);
}
.gm-rar.uncommon { color: #7ee08a; border-color: rgba(126, 224, 138, .5); }
.gm-rar.rare {
  color: #0b1830; border-color: rgba(140, 190, 255, .9);
  background: linear-gradient(110deg, #7fb6ff 0%, #b9d8ff 40%, #ffffff 50%, #b9d8ff 60%, #7fb6ff 100%);
  background-size: 250% 100%; animation: gm-shimmer 2.4s linear infinite;
}
@keyframes gm-shimmer { from { background-position: 100% 0; } to { background-position: -150% 0; } }
@media (prefers-reduced-motion: reduce) { .gm-rar.rare { animation: none; background-position: 50% 0; } }
.gm-var { font-size: .72rem; font-weight: 650; color: #93a1b0; }
.gm-var.uncommon { color: #7ee08a; }
.gm-var.rare { color: #8fc0ff; }
/* the stage's own colours are only seen before the first frame (or with no
   WebGL2): the kitchen the game draws, a warm wall over a pale counter */
.gm-stage {
  position: relative; height: clamp(330px, 96vw, 540px); border-radius: 14px; overflow: hidden;
  background: linear-gradient(180deg, #f6efe4 0%, #ead9c2 52%, #e4ddd2 54%, #d9d0c3 100%);
  border: 1px solid var(--g-line); box-shadow: inset 0 0 24px rgba(60, 40, 20, .18);
}
.gm-gl, .gm-trail { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
.gm-hud, .gm-read, .gm-nogl { z-index: 2; }
.gm-gl { touch-action: pan-y; cursor: grab; outline: none; -webkit-tap-highlight-color: transparent; }
.gm-gl.cutting { touch-action: none; cursor: crosshair; }
.gm-gl:focus-visible { box-shadow: inset 0 0 0 2px var(--accent); }
.gm-trail { pointer-events: none; overflow: visible; }
.gm-hud {
  position: absolute; top: 10px; left: 10px; right: 10px; display: flex; justify-content: space-between; align-items: flex-start; gap: 8px;
  pointer-events: none; font-size: .78rem; font-weight: 700;
}
.gm-chips { display: flex; flex-wrap: wrap; gap: 6px; min-width: 0; }
/* the slots the extras fill (coins.css, tears.css, duel.css style what goes
   in them): the HUD's left column, the head's right, the overlays on the
   stage and the receipt line on the result card. Each keeps its box empty
   or full, so nothing around it moves. */
.gm-hud-l { display: flex; flex-direction: column; align-items: flex-start; gap: 6px; min-width: 0; }
.gm-head-r { display: flex; align-items: center; gap: 8px; }
.gm-tears { position: absolute; inset: 0; z-index: 1; pointer-events: none; }
.gm-toast { position: absolute; left: 10px; right: 10px; top: 50px; z-index: 4; pointer-events: none; text-align: center; }
.gm-earn { margin: 8px 0 0; min-height: 1.4em; font-size: .84rem; }
/* how you cut: a setting, so small, and on the stage where it acts */
.gm-ctl {
  pointer-events: auto; flex: 0 0 auto; display: inline-flex; border-radius: 999px; overflow: hidden;
  background: rgba(10, 12, 16, .62); border: 1px solid rgba(255, 255, 255, .14);
  -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px);
}
.gm-ctl button {
  min-height: 32px; padding: 0 12px; border: none; background: transparent; color: #c3cdd8;
  font: inherit; font-weight: 700; -webkit-tap-highlight-color: transparent;
}
.gm-ctl button.active { background: linear-gradient(180deg, #ffd955, var(--gold)); color: #241c02; }
.gm-ctl[hidden] { display: none; }
.gm-hud-r { display: flex; flex-direction: column; align-items: flex-end; gap: 6px; flex: 0 0 auto; }
/* the clock: fixed-width digits so a tenth ticking over never moves it;
   muted until the first touch, white while it runs, gold once it stops */
.gm-hud .gm-clock { font-variant-numeric: tabular-nums; min-width: 5.4em; text-align: center; }
.gm-hud .gm-clock::before { content: "⏱ "; }
.gm-hud .gm-clock.idle { color: var(--muted); }
.gm-hud .gm-clock.done { color: var(--gold); }
.gm-clock[hidden] { display: none; }
.gm-clock b { font-weight: inherit; }
/* Play's speed bonus, in the clock's own chip so the HUD's right column is no
   taller and no wider: the share of it left burns down as an amber fuse
   behind the digits, and the percent follows them, grey once it has run out.
   The fuse is as dark as the chip, or the digits wash out against the wall;
   and the fuse stands in for the ⏱, whose width the percent takes, since a
   chip wider than the Swipe / Knife toggle wraps the step's chips at 360 px. */
.gm-spd { margin-left: 5px; color: var(--gold); }
.gm-spd[hidden] { display: none; }
.gm-hud .gm-clock.fuse {
  background: linear-gradient(90deg, rgba(104, 74, 4, .86) calc(var(--fuse, 1) * 100%), rgba(10, 12, 16, .62) calc(var(--fuse, 1) * 100%));
}
.gm-hud .gm-clock.fuse::before { content: none; }
/* a duel's clock counts down what is left of the onion's (play.js), the same
   fuse; for its last fifteen seconds the fuse and the digits go red, and the
   chip beats, so the end is felt before the knife comes down */
.gm-hud .gm-clock.race .gm-spd { color: #c3cdd8; }
.gm-hud .gm-clock.race.hurry {
  color: #ffd0c4;
  background: linear-gradient(90deg, rgba(150, 28, 18, .9) calc(var(--fuse, 1) * 100%), rgba(10, 12, 16, .62) calc(var(--fuse, 1) * 100%));
  border-color: rgba(255, 120, 90, .6); animation: gm-hurry 1s ease-in-out infinite;
}
.gm-hud .gm-clock.race.hurry .gm-spd { color: #ffd0c4; }
@keyframes gm-hurry { 50% { transform: scale(1.06); } }
@media (prefers-reduced-motion: reduce) { .gm-hud .gm-clock.race.hurry { animation: none; } }
.gm-clock.spent .gm-spd { color: var(--muted); }
.gm-hud span {
  padding: 4px 10px; border-radius: 999px; background: rgba(10, 12, 16, .62); border: 1px solid rgba(255, 255, 255, .12);
  -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px); color: #e8edf2;
}
.gm-hud .gm-step { color: var(--gold); }
.gm-count:empty { visibility: hidden; }
/* the readout sits on the stage, two lines held, so a swipe's words never
   push anything */
.gm-read {
  position: absolute; left: 10px; right: 10px; bottom: 8px; margin: 0; min-height: 2.7em;
  display: flex; align-items: flex-end; pointer-events: none;
  font-size: .82rem; line-height: 1.35; color: #f2efe6; text-shadow: 0 1px 3px rgba(0, 0, 0, .9), 0 0 12px rgba(0, 0, 0, .7);
}
.gm-nogl { position: absolute; inset: 0; margin: 0; display: flex; align-items: center; justify-content: center; text-align: center; padding: 24px; color: #5b4a38; }
.gm-nogl[hidden] { display: none; }
/* the knife's dock: five thumb-sized buttons over the foot of the stage, the
   readout lifted over them. Held, the arrows keep going (play.js); the tilt
   pair keep their places hidden on the slices, so Cut never moves. */
.gm-kdock {
  position: absolute; left: 10px; right: 10px; bottom: 10px; z-index: 3; max-width: 440px; margin: 0 auto;
  display: grid; grid-template-columns: 1fr 1fr 1.7fr 1fr 1fr; gap: 8px;
}
.gm-kdock[hidden] { display: none; }
.gm-kb {
  height: 50px; min-width: 0; padding: 0; border-radius: 14px; border: 1px solid rgba(255, 255, 255, .16);
  background: rgba(10, 12, 16, .66); -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px);
  color: #eef2f6; display: flex; align-items: center; justify-content: center;
  touch-action: none; user-select: none; -webkit-user-select: none; -webkit-touch-callout: none; -webkit-tap-highlight-color: transparent;
}
.gm-kb svg { width: 24px; height: 24px; fill: none; stroke: currentColor; stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round; }
.gm-kb.held { background: rgba(240, 196, 25, .24); border-color: rgba(240, 196, 25, .62); color: #ffe9a3; }
.gm-kb.cut {
  font-weight: 800; font-size: 1rem; letter-spacing: .02em; color: #241c02;
  background: linear-gradient(180deg, #ffd955, var(--gold)); border-color: rgba(255, 230, 140, .7);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .45), 0 6px 16px rgba(240, 196, 25, .2);
}
.gm-kb.cut:active, .gm-kb.cut.down { transform: translateY(1px); }
.gm-kb.off { visibility: hidden; }
.gm-stage.knife .gm-read { bottom: 68px; }
.gm-actions { display: grid; grid-template-columns: 1fr 1fr 1.4fr; gap: 8px; margin-top: 10px; }
.gm-btn {
  min-height: 46px; border-radius: 12px; font-weight: 700; font-size: .92rem;
  color: var(--ink); background: var(--g-in-fill); border: 1px solid var(--g-line);
}
.gm-btn:disabled { opacity: .4; cursor: default; }
.gm-btn.go {
  margin: 0; border-radius: 12px; padding: 0 12px; color: #241c02;
  background: linear-gradient(180deg, #ffd955, var(--gold)); border-color: rgba(255, 230, 140, .7);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .45), 0 6px 16px rgba(240, 196, 25, .2);
}
.gm-actions .gm-btn:not(:disabled):active { transform: translateY(1px); }

/* the result: drawn with dashes before the first score, so empty, dicing
   and scored are the same shape */
.gm-result { margin-top: 12px; min-height: 236px; }
.gm-score { display: flex; align-items: center; gap: 6px 16px; flex-wrap: wrap; }
.gm-big { display: flex; align-items: baseline; gap: 4px; }
.gm-num { font: 750 2.6rem/1 var(--mono); color: var(--gold); min-width: 3.2ch; }
.gm-score.empty .gm-num { color: var(--muted); }
.gm-of { color: var(--muted); font-weight: 600; }
.gm-tier { display: flex; flex-direction: column; font-weight: 700; color: var(--ink); line-height: 1.25; }
.gm-stars { color: var(--gold); letter-spacing: 2px; font-size: 1rem; }
.gm-par { flex: 1 1 100%; color: var(--muted); font-size: .82rem; min-height: 1.3em; }
.gm-par .gm-time { color: var(--ink); font-variant-numeric: tabular-nums; }
.gm-stats { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; margin: 10px 0 0; }
.gm-stats div { padding: 8px 10px; border-radius: 10px; background: var(--g-in-fill); border: 1px solid var(--g-in-line); }
.gm-stats dt { font-size: .72rem; color: var(--muted); font-weight: 650; }
.gm-stats dd { margin: 2px 0 0; font: 650 .95rem var(--mono); color: var(--ink); white-space: nowrap; }
.gm-stats .gm-plus { color: var(--gold); }
.gm-note { margin: 10px 0 6px; font-size: .86rem; color: #c3cdd8; min-height: 2.7em; }
.gm-note b { color: var(--gold); }
.gm-key { margin-top: 4px; }
.gm-res-actions { display: flex; gap: 8px; margin-top: 8px; }
.gm-small {
  min-height: 36px; padding: 0 14px; border-radius: 999px; font-size: .8rem; font-weight: 650;
  color: #c3cdd8; background: var(--g-in-fill); border: 1px solid var(--g-line);
}
.gm-small[aria-pressed="true"] { color: #241c02; background: linear-gradient(180deg, #ffd955, var(--gold)); border-color: rgba(255, 230, 140, .7); }
.gm-small:disabled { opacity: .4; }
@media (max-width: 560px) {
  .gm-stats { grid-template-columns: repeat(2, 1fr); }
  .gm-result { min-height: 300px; }
  /* the step, the count and the toggle in one row on a phone */
  .gm-hud span { padding: 4px 8px; }
  .gm-chips { gap: 4px; }
  .gm-ctl button { padding: 0 9px; }
  /* the brief holds the height of the longest one, Zen's or a duel's (its
     note wraps to a second line on a phone), so switching between the modes
     never moves the stage under it: measured 79 px against Play's 60 at 375 */
  .gm-brief { min-height: 5.5em; }
}
/* a narrow phone: the step and the count on one row, so the wipe button that
   comes under them sits clear of the onion's shoulder rather than on it */
@media (max-width: 400px) {
  .gm-hud { gap: 4px; font-size: .74rem; }
  .gm-hud span { padding: 4px 6px; }
  .gm-chips { gap: 3px; }
  .gm-ctl button { padding: 0 8px; }
}

/* the board */
.gm-rows { list-style: none; margin: 8px 0 12px; padding: 0; display: flex; flex-direction: column; gap: 4px; min-height: 2.4em; }
.gm-rows li {
  display: grid; grid-template-columns: 2.2em 1fr auto auto; align-items: center; gap: 10px;
  padding: 6px 8px 6px 10px; border-radius: 10px; background: var(--g-in-fill); border: 1px solid var(--g-in-line);
}
.gm-rows li.me { border-color: rgba(240, 196, 25, .55); }
.gm-rows li.gm-off { display: block; background: none; border: none; color: var(--muted); font-size: .86rem; padding: 4px 0; }
.gm-rank { color: var(--muted); font: 650 .86rem var(--mono); }
.gm-who { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 650; }
.gm-pts { font: 700 1rem var(--mono); color: var(--gold); white-space: nowrap; }
.gm-pts .gm-ms { font: 600 .72rem var(--mono); color: var(--muted); }
.gm-watch {
  min-height: 32px; padding: 0 10px; border-radius: 999px; font-size: .76rem; font-weight: 650;
  color: #c3cdd8; background: transparent; border: 1px solid var(--g-line);
}
.gm-post { display: flex; gap: 8px; }
.gm-post.off { display: none; }
.gm-post input {
  flex: 1 1 auto; min-width: 0; min-height: 44px; padding: 0 12px; border-radius: 12px; font: inherit;
  color: var(--ink); background: var(--g-well); border: 1px solid var(--g-line);
}
.gm-who.anon { color: var(--muted); font-style: italic; font-weight: 600; }
.gm-status { min-height: 1.4em; margin: 6px 0 0; color: var(--gold); }
/* the account (account/): the chip (account.css, one fixed size) and a line
   beside it held at two lines on a phone, three on the narrowest, whatever it
   says. Signed in, the name field gives way to the handle in its own box,
   read-only (play.js): the field's text goes clear and a line over it reads
   "Posting as Kevin ✓", so signing in or out moves nothing. A ✓ by a name
   on the board is a row posted under an account. */
.gm-acct { display: flex; align-items: center; gap: 10px; margin: 6px 0 2px; }
.gm-acct-chip { flex: 0 0 auto; display: inline-flex; }
.gm-acct-say { flex: 1 1 auto; min-width: 0; min-height: 2.7em; display: flex; align-items: center; font-size: .8rem; line-height: 1.35; color: var(--muted); }
@media (max-width: 359px) { .gm-acct-say { min-height: 4.05em; } }
.gm-post { position: relative; }
.gm-as { display: none; }
.gm-post.acct .gm-as {
  position: absolute; inset: 0; display: flex; align-items: center; gap: 5px; padding: 0 13px; pointer-events: none;
  white-space: nowrap; overflow: hidden; font-size: .92rem; color: var(--muted);
}
.gm-as b { min-width: 0; overflow: hidden; text-overflow: ellipsis; color: var(--ink); }
.gm-post.acct input { color: transparent; caret-color: transparent; cursor: pointer; background: var(--g-in-fill); }
.gm-ok { color: var(--accent); font-weight: 800; font-style: normal; }
.gm-how summary { cursor: pointer; color: var(--gold); font-weight: 650; }
.gm-how p { color: #c3cdd8; font-size: .9rem; }
.gm-how b { color: var(--ink); }
.tab.practice .gm-board { opacity: .55; }
