/* Play layer (owner "play": src/run/topic/calc.js, play-fx.js): the formula bar grows to 4 numbers + 3 signs and must fit a
   360 px phone and short landscape without scrolling, so tiles shrink with the slot count (data-n on #expr).
   Loaded after game.css and look.css. */

.exprbar[data-n="5"]{--s:min(46px, calc((100vw - 150px) / 4.8))}
.exprbar[data-n="6"],.exprbar[data-n="7"]{--s:min(42px, calc((100vw - 150px) / 6.6)); gap:6px; padding-left:8px; padding-right:6px}
.exprbar[data-n="5"] .slots,.exprbar[data-n="6"] .slots,.exprbar[data-n="7"] .slots{gap:clamp(2px, .9vw, 6px)}
.exprbar[data-n="5"] .slot,.exprbar[data-n="6"] .slot,.exprbar[data-n="7"] .slot{min-width:var(--s); height:var(--s); padding:0 3px; border-radius:calc(var(--s) * .26); font-size:calc(var(--s) * .5)}
.exprbar[data-n="5"] .slot.op,.exprbar[data-n="6"] .slot.op,.exprbar[data-n="7"] .slot.op{width:calc(var(--s) * .8); min-width:calc(var(--s) * .8); height:calc(var(--s) * .8); padding:0; border-radius:50%}
.exprbar[data-n="5"] .slot.long,.exprbar[data-n="6"] .slot.long,.exprbar[data-n="7"] .slot.long{font-size:calc(var(--s) * .38)}
.exprbar[data-n="5"] .slot.xlong,.exprbar[data-n="6"] .slot.xlong,.exprbar[data-n="7"] .slot.xlong{font-size:calc(var(--s) * .3)}
.exprbar[data-n="5"] .slot.op.word,.exprbar[data-n="6"] .slot.op.word,.exprbar[data-n="7"] .slot.op.word{font-size:calc(var(--s) * .28)}
.exprbar[data-n="5"] .eqv,.exprbar[data-n="6"] .eqv,.exprbar[data-n="7"] .eqv{font-size:clamp(16px, 5vw, 22px)}
.exprbar[data-n="6"] .clr,.exprbar[data-n="7"] .clr{width:24px; height:24px}

/* After a last-part win: the numbers before it fade back; the part that counted stays bright (green rim from game.css) */
.slot.spent{border:2px solid var(--card-edge); background:var(--card); color:var(--ball-ink); opacity:.32}
.slot.op.spent{background:var(--op); border-color:var(--op-edge); color:var(--on-op)}
.exprbar.ok .slot.full{animation:pl-lift .3s cubic-bezier(.3,1.7,.5,1)}
@keyframes pl-lift{40%{transform:translateY(-4px) scale(1.08)}}

/* The bar grows: a small neutral pulse (no colour, so it never hints right or wrong) */
.exprbar.pl-grow{animation:pl-grow .32s ease-out}
@keyframes pl-grow{40%{transform:scale(1.04)}}

/* Cheer chip over the bar for 3-/4-number formulas and last-part wins */
.pl-chip{position:fixed; transform:translate(-50%,-100%); padding:4px 12px; border-radius:999px; background:var(--panel); border:2px solid var(--good);
  color:var(--good); font:700 17px/1.1 var(--font-display); white-space:nowrap; pointer-events:none; animation:pl-chip 1.4s ease forwards; box-shadow:0 4px 12px rgba(0,0,0,.15)}
.pl-chip.gold{border-color:var(--gold); color:var(--ink); background:color-mix(in srgb, var(--gold) 30%, var(--panel))}
@keyframes pl-chip{0%{opacity:0; transform:translate(-50%,-70%) scale(.8)}12%{opacity:1; transform:translate(-50%,-100%) scale(1)}80%{opacity:1}100%{opacity:0; transform:translate(-50%,-112%)}}

@media (prefers-reduced-motion: reduce){ .exprbar.ok .slot.full,.exprbar.pl-grow,.pl-chip{animation:none!important} .pl-chip{opacity:1} }

/* ===== Review fixes (docs/math-racing/archive/review/ux.md) ===== */
/* #2 Toasts wrap to 2–3 lines instead of "…" */
.toast{white-space:normal; text-overflow:clip; overflow:visible; text-align:center; border-radius:16px; max-width:min(440px, calc(100vw - 32px)); width:max-content; box-sizing:border-box; line-height:1.3;
  bottom:calc(max(10px, env(safe-area-inset-bottom, 0px)) + 172px)}   /* above the bar, the next-row strip and its chips */
@media (min-aspect-ratio: 5/4){ .toast{bottom:auto; top:calc(max(8px, env(safe-area-inset-top, 0px)) + 58px); left:50%; max-width:min(440px, 46vw)} }

/* #3 Mixed numbers: the whole number and a small stacked fraction, never "11/6"; no squeezed letter-spacing */
.ball.long span,.ball.xlong span,.ball.xxlong span{letter-spacing:0}
.slot.xlong{letter-spacing:0}
.mx-f{display:inline-flex!important; flex-direction:column; align-items:center; vertical-align:middle; font-size:.56em; line-height:1; margin-left:.14em}
.mx-f span{display:block!important; padding:0 .06em}
.mx-f span:first-child{border-bottom:.09em solid currentColor}
.ball span.mx-w,.slot .mx-w,.nr-cell .mx-w{display:inline!important}
.ball span[data-num]{display:flex; align-items:center; justify-content:center}
/* Fractions are stacked with a horizontal bar, never a slash (src/run/hud/frac-text.js): a fraction on its own is big, the
   fraction of a mixed number small. In the ball only the outer span takes the ball's size classes. */
.mx-f.fr{font-size:.74em; margin:0 .05em}
.mx-f span:first-child{border-bottom-width:.1em}
#goal span[data-num] span{font-size:1em; letter-spacing:0}
#goal span[data-num] .mx-f{font-size:.56em}
#goal span[data-num] .mx-f.fr{font-size:.74em}
.fly .mx-f,.toast .mx-f,.trap-chip .mx-f,.trap-formula .mx-f{display:inline-flex!important}

/* Ball pictures (src/run/hud/ball-pic.js): K–2 topics on Normal / Hard show the ball's number as a picture (ten-frame,
   blocks, coins) on the ball itself, where it can be counted calmly; the road only ever shows numerals. Fraction and
   angle topics get a small pie or wedge badge on the ball's rim. */
#goal.pic > span{display:none}
#goal .gpic{position:relative; z-index:1; display:flex; align-items:center; justify-content:center; gap:4px; pointer-events:none}
#goal .gpic svg{display:block; width:calc(var(--B) * .62); height:calc(var(--B) * .5)}
#goal.formula .gpic svg{width:calc(var(--B) * .8); height:calc(var(--B) * .54)}
/* Base-ten blocks and coins need room to be counted (play test 2026-11-12: 77 in blocks was 36 px wide in landscape):
   the ball becomes a wide ball with a white face, like an answer run's, and the picture is at least 46 px tall (a unit
   cube about 4 px, a rod's ten marks apart). */
#goal.pic.picwide{width:auto; min-width:var(--B); border-radius:999px; padding:0 10px; box-sizing:border-box;
  background:linear-gradient(var(--ball-face), var(--ball-face)) padding-box, var(--rc) border-box; border:5px solid transparent}
#goal.pic.picwide .gpic svg{height:max(46px, calc(var(--B) * .62)); width:auto; max-width:none}
#goal.pic.picwide.formula{height:auto; min-height:calc(var(--B) * .78); padding:3px 8px}
#goal.pic.picwide.formula .gpic svg{height:max(42px, calc(var(--B) * .56))}
#goal .gpic b{font:700 calc(var(--B) * .3)/1 var(--font-display); color:var(--ball-ink)}
#goal .gbadge{position:absolute; left:calc(100% - 14px); bottom:-6px; z-index:2; min-width:calc(var(--B) * .42); height:calc(var(--B) * .42); padding:0 3px; box-sizing:border-box;
  border-radius:999px; background:#fff; box-shadow:0 1px 4px rgba(0,0,0,.35); display:flex; align-items:center; justify-content:center; pointer-events:none}
#goal .gbadge svg{height:82%; width:auto; display:block}
.gpic .tf-box{fill:#fff; stroke:#7f8db0; stroke-width:2} .gpic .tf-line{fill:none; stroke:#c3cde0; stroke-width:1.5}
.gpic .tf-dot{fill:#2f5bff} .gpic .tf-dot.b{fill:#13a39b}   /* never red on the HUD: red only means a wrong formula */
.gpic .b10{fill:#69b8ff; stroke:#1d5ea8; stroke-width:.14} .gpic .b10.u{fill:#ffc83d; stroke:#a87400} .gpic .b10-grid{fill:none; stroke:#1d5ea8; stroke-width:.07}
.gpic .coin circle{fill:#dfe4ec; stroke:#7d889c; stroke-width:1.1} .gpic .coin.cu circle{fill:#e7a26b; stroke:#9b5a28} .gpic .coin .rim{fill:none; stroke-width:.7}
.gpic .coin text{font-family:Fredoka, Trebuchet MS, sans-serif; font-weight:700; fill:#2c3446}

/* #4 Equation tiles: the value in the slot, the tile as a small caption above it */
.slot{position:relative}
.slot .cap{position:absolute; left:50%; bottom:calc(100% + 3px); transform:translateX(-50%); padding:1px 6px; border-radius:7px; background:var(--panel); border:1px solid var(--panel-line);
  font:700 12px/1.2 var(--font-body); color:var(--muted); white-space:nowrap; pointer-events:none}
/* A chain is written as a path: 8 → 75 % of → 6 → ÷2 → 3 */
.exprbar.path .slots{gap:15px}
.exprbar.path .slot:not(:first-child)::before{content:'→'; position:absolute; left:-13px; top:50%; transform:translateY(-50%); font:700 13px/1 var(--font-body); color:var(--muted)}
.exprbar.path .slot.op{width:auto; min-width:0; padding:0 8px; border-radius:999px}

/* bugs.md #6: no red in the HUD except a wrong formula (the speed bar used to end in --r0 coral red) */
.speedo i{background:linear-gradient(90deg, var(--r5), var(--r2), var(--gold))}

/* #9 No label smaller than 12 px */
.place span,.stat .lab,.goallab,.diffs .lab,.ex-kicker{font-size:12px}
.rulebar.plain{font-size:12px}

/* #10 Every button at least 44 × 44 */
.iconchip{width:44px; height:44px}
.diff,.calm{min-height:44px}
#endOv .btns .btn,#menuOv .btns .btn{min-height:44px}   /* (2026-11-12: the compact cards had made them 39–42 px) */
.rulebar{min-height:44px}
.rulebar.qonly{min-width:44px; justify-content:center; padding:3px 0} .rulebar.qonly .rt{display:none}   /* game.js: "Example" does not fit whole */
.rulebar.qfade .rt{opacity:0; transition:opacity .4s}   /* game.js pillLate: a long pill's words fade before it folds to its "?" */
.ex-close{width:44px; height:44px}
.how summary{min-height:44px; display:flex; align-items:center; justify-content:center; gap:6px}
.how .more summary{min-height:44px}
@media (min-aspect-ratio: 5/4) and (max-height:500px){ .iconchip{width:44px; height:44px} }
/* The Race button stays in view: the topic list scrolls inside the card (game.css); only when How to play is open does
   the card itself scroll, and then Race sticks to its bottom edge. */
.card.start .btns{position:sticky; bottom:-1px; z-index:2; background:var(--tile); padding:6px 0 4px; margin:-6px 0 -4px}
@media (max-height:700px) and (max-aspect-ratio: 5/4){
  .card.start{gap:9px; padding:16px 16px} .card.start .demo{display:none} .card.start h1{font-size:30px}
  .strand{min-height:44px} .topic{padding:7px 9px} .modehint{font-size:13.5px; padding:6px 9px}
}
/* Landscape and desktop (2026-11-12, menu-review.md Option 1 sketch): two columns. Left: title, strand tabs,
   Difficulty, Race, Calm motion and How to play; right: the strand's name, its topics and the hint. The right column
   takes the left column's height (contain:size) and its topic list scrolls, so nothing is covered (the old one-column
   grid let the sticky Race bar cover Easy / Normal / Hard at 844 × 390). */
@media (min-aspect-ratio: 5/4) and (min-width:600px){
  .card.start{max-width:min(920px, 100%); display:grid; grid-template-columns:minmax(250px, 300px) minmax(0, 1fr); column-gap:20px; row-gap:10px; align-content:start;
    grid-template-areas:"demo pick" "h1 pick" "strands pick" "diffs pick" "btns pick" "foot pick"}
  .card.start .demo{grid-area:demo} .card.start h1{grid-area:h1} .card.start .strands{grid-area:strands} .card.start .diffs{grid-area:diffs}
  .card.start .btns{grid-area:btns; position:static; margin:0; padding:0} .card.start .start-foot{grid-area:foot}
  .card.start .pick{grid-area:pick; contain:size; min-height:0}
  .card.start .topics{flex:1 1 0}
  .card.start .diffs .lab{margin-right:0}
}
@media (min-aspect-ratio: 5/4) and (min-width:600px) and (min-height:601px){ .card.start .topics{grid-template-columns:repeat(auto-fill, minmax(160px, 1fr))} }
@media (min-aspect-ratio: 5/4) and (min-width:600px) and (max-height:600px){
  .card.start{padding:14px 16px; row-gap:8px} .card.start .demo{display:none} .card.start h1{font-size:28px}
  .strand{min-height:44px; font-size:18px} .start-foot{gap:4px 8px} .calm{padding:6px 10px}
  .topic{padding:6px 9px} .topic b{font-size:15px} .modehint{font-size:13.5px; padding:6px 9px; line-height:1.35}
}

/* How to play: a few picture lines for K–2, the full rules behind "More" */
.how .steps{margin:0; padding:0; list-style:none; display:flex; flex-direction:column; gap:8px}
.how .steps li{display:grid; grid-template-columns:44px 1fr; align-items:center; gap:10px; font:600 17px/1.25 var(--font-display); color:var(--ink)}
.how .steps .ic{width:44px; height:44px; border-radius:12px; display:grid; place-items:center; background:var(--given); font:700 22px/1 var(--font-display)}
.how .more summary{font-size:14px; color:var(--muted); font-weight:800; cursor:pointer; justify-content:flex-start}

/* #1 The next row, in lane order, just above the formula bar (src/run/hud/next-row.js). Tiles only, never colour by answer. */
.exprwrap{display:flex; flex-direction:column; align-items:center; gap:6px}
@media (min-aspect-ratio: 5/4){ .exprwrap{align-items:flex-start} }
.nextrow{display:flex; gap:4px; justify-content:center; max-width:calc(100vw - 24px); padding:4px 6px; border-radius:14px; background:color-mix(in srgb, var(--panel) 82%, transparent);
  border:1px solid var(--panel-line); opacity:0; transition:opacity .2s; pointer-events:none}
.nextrow.on{opacity:1; pointer-events:auto}
.nr-cell{position:relative; flex:0 1 auto; box-sizing:border-box; min-width:30px; height:34px; padding:0 4px; border-radius:9px; display:grid; place-items:center; overflow:hidden;
  font:600 20px/1 var(--font-display); color:var(--muted); border:1.5px dashed color-mix(in srgb, var(--ink) 18%, transparent); white-space:nowrap; font-variant-numeric:tabular-nums; cursor:pointer}
.nr-cell.num{background:var(--card); color:var(--ball-ink); border:2px solid var(--card-edge); border-bottom-width:3px}
.nr-cell.op{width:34px; border-radius:50%; background:var(--op); color:var(--on-op); border:0; border-bottom:3px solid var(--op-edge)}
.nr-cell.door{background:#ffffff; color:#0f1a2e; border:2px solid #3a4660}
.nr-cell.step{background:var(--op); color:var(--on-op); border:0; border-bottom:3px solid var(--op-edge); border-radius:999px; padding:0 8px}
.nextrow[data-n="8"]{width:min(560px, calc(100vw - 24px)); box-sizing:border-box}
.nextrow[data-n="8"] .nr-cell{flex:1 1 0; min-width:0; padding:0 2px}   /* equal slots: each cell sits where its lane is */
.nextrow[data-n="8"] .nr-cell.op{width:auto; border-radius:999px}
.nextrow[data-n="8"] .nr-cell:not(:is(.num,.op,.door,.step)){opacity:.55}
.nextrow[data-n="8"]{justify-content:space-between}
@media (min-aspect-ratio: 5/4){ .nextrow[data-n="8"]{width:min(400px, 36vw)} }   /* landscape: keep the near track clear */
.nr-cell.long{font-size:14px; letter-spacing:-.01em}
.nr-cell.xlong{font-size:12px; white-space:normal; line-height:1; text-align:center; word-break:break-word; height:38px}
.nr-cell.op.long,.nr-cell.op.xlong{width:auto; border-radius:999px}
.nr-cell.me{box-shadow:0 0 0 3px var(--you)}
.nr-cell.me::after{content:''; position:absolute; left:50%; bottom:1px; width:6px; height:3px; margin-left:-3px; border-radius:2px; background:var(--you)}
@media (max-height:500px){ .nr-cell{height:28px; min-width:26px; font-size:17px} .nr-cell.op{width:28px} .nr-cell.long{font-size:12px} }
html.calm .nextrow{transition:none}

/* Large screens (2026-11-12, coordinator: the start, pause and results cards were phone-sized islands with small type
   on tablets and desktops): the three cards scale up as a whole (type, controls, width) with CSS zoom, so their
   layouts stay exactly as designed. The start card's height cap is divided by the same factor so it still fits. */
@media (min-width:700px) and (min-height:760px){
  #startOv > .card, #menuOv > .card, #endOv > .card{zoom:1.15}
  .card.start{max-height:calc((100dvh - max(16px, env(safe-area-inset-top, 0px)) - max(16px, env(safe-area-inset-bottom, 0px))) / 1.15)}
}
@media (min-width:740px) and (min-height:960px){
  #startOv > .card, #menuOv > .card, #endOv > .card{zoom:1.25}
  .card.start{max-height:calc((100dvh - max(16px, env(safe-area-inset-top, 0px)) - max(16px, env(safe-area-inset-bottom, 0px))) / 1.25)}
}
/* Laptop and tablet landscape (taller than 560, up to 900 high; the card is one column and zoomed 1.15 from 760 high):
   the results card tightens and its tally goes two columns, with or without the record strip (2026-11-12: without the
   strip it ran 31 px past the bottom at 1280 × 800, 63 px at 1366 × 768 and 1024 × 768, 8 px at 1280 × 720) */
@media (min-aspect-ratio: 5/4) and (min-height:561px) and (max-height:900px){
  #endOv .card .tally{display:grid; grid-template-columns:1fr 1fr; gap:2px 16px}
  #endOv .card .tally div:last-child{grid-column:1 / -1}
  #endOv .card{gap:9px; padding:16px 18px} #endOv .card .medal{width:48px; height:48px; font-size:20px} #endOv .card h2{font-size:26px}
  #endOv .card .tally div{padding:3px 0; font-size:14px} #endOv .card .tally b{font-size:17px}
  #endOv .card .btns{gap:8px} #endOv .card .btn{padding:10px 14px; font-size:18px} #endOv .card .btn.ghost{font-size:16px}
}
@media (min-aspect-ratio: 5/4) and (min-height:561px) and (max-height:800px){
  #endOv .card{gap:6px; padding-block:12px} #endOv .card .tally div{padding:2px 0}
}
/* Very short landscape phones (667 × 375): the pause and results cards fit without scrolling (they ran 6–10 px over) */
@media (min-aspect-ratio: 5/4) and (max-height:400px){
  #menuOv .card{gap:8px; padding:12px 18px} #menuOv h2{font-size:24px} #menuOv .btns{gap:8px} #menuOv .btn{padding:9px 14px}
  #endOv .card{padding-block:10px; row-gap:6px}
  #menuOv, #endOv{padding-block:max(8px, env(safe-area-inset-top, 0px)) max(8px, env(safe-area-inset-bottom, 0px))}
}
