/* tvlogo.monster: colours leaned toward the site's palette, keeping FLOE STATE's neon-ice character (lars's original
   to ours): the mint cyan #33ffcc to the site's cyan #67e8f9, the magenta a touch warmer (#ff33ff to #ff4fd0), the gold
   warmer (#ffcc33 to #ffc14a), the warm bands' orange #ff9900 to the site's #f67508 (also --orange, the mascot's name
   on the title), the icy bands' #33ccff to the site's cyan, the shadow navy and the page's black the site's dark tones
   (#000033 to #120d1a, #000000 to #0d0b10) and the grey its muted grey (#999999 to #aaa1ab); lars's layout unchanged */
@font-face{font-family:'Whorl Arcade';src:url('./core/fonts/whorl-arcade.ttf') format('truetype');font-display:block}
/* Pixel art direction. The game renders at a low resolution and scales up with hard edges; --px is one game
   pixel in CSS pixels (set from the window size by main.js). UI type is Whorl Arcade, our 8x8 mid-80s arcade font, sized
   so its pixels sit on the same grid: --s (small, a font pixel of half a game pixel), --m (one game pixel),
   --l and --xl (two and three). Colours come from the same 6-levels-a-channel palette the renderer snaps to.
   No rounded corners, no tilted text, square borders. Type sits on a hard pixel shadow a font pixel down and right
   (--glow, .125em: a font pixel at any size), the way arcade boards did it, and the score's steps down in its own
   colour first. No soft glows or blurred halos: until October 7, 2026 type glowed in a blurred halo of its own
   colour, which read as a cheap paint-program outer glow. */
:root{color-scheme:dark;--px:4px;--fp:calc(var(--px) / 2);
  --s:calc(var(--px) * 4);--m:calc(var(--px) * 8);--l:calc(var(--px) * 16);--xl:calc(var(--px) * 24);
  --ink:#0d0b10;--white:#ffffff;--cyan:#67e8f9;--pink:#ff4fd0;--gold:#ffc14a;--red:#ff3366;--grey:#aaa1ab;--navy:#120d1a;--orange:#f67508;--bridge:#c0362c;
  --glow:.125em .125em 0 rgb(0 0 0 / .9);
  /* hard colour bands, two font pixels each, the way mid-80s arcade boards shaded their big type */
  --warm:linear-gradient(#ffff66 0 25%,#ffc14a 25% 50%,#f67508 50% 75%,#ff3300 75%);
  --icy:linear-gradient(#ffffff 0 25%,#ccffff 25% 50%,#67e8f9 50% 75%,#3366ff 75%)}
.bands{-webkit-background-clip:text;background-clip:text;color:transparent;line-height:1}
*{box-sizing:border-box}
html,body{margin:0;height:100%;background:var(--ink);color:var(--white);overflow:hidden;font-family:'Whorl Arcade',monospace;font-size:var(--s);line-height:1.5;user-select:none;-webkit-user-select:none;touch-action:none;-webkit-touch-callout:none}
#stage canvas{display:block}
/* the title's pixel night (pixeltitle.js) over the 3D scene, scaled up crisp; it fades out as a game, the story or the
   credits start. While it's up the title dims only round its words, in the middle, and leaves the edges bright */
#pixeltitle{position:fixed;inset:0;width:100%;height:100%;image-rendering:crisp-edges;image-rendering:pixelated;transition:opacity .6s ease-out}
#pixeltitle.gone{opacity:0;pointer-events:none}
body:has(#pixeltitle:not(.gone)) #title{background:radial-gradient(ellipse 62% 58% at 50% 50%, rgba(0,0,0,.6), rgba(0,0,0,.3) 62%, rgba(0,0,0,0))}
/* touch: floating stick + a couple of buttons, only on touch screens */
#touchbar{position:fixed;right:12px;bottom:calc(28px + env(safe-area-inset-bottom));display:none;gap:10px;z-index:20}
#touchbar button{font:inherit;font-size:var(--m);color:var(--cyan);background:var(--ink);border:var(--px) solid var(--cyan);border-radius:0;padding:10px 12px;box-shadow:var(--px) var(--px) 0 var(--navy)}
#touchbar button.off{color:var(--grey);border-color:var(--grey);text-decoration:line-through;text-decoration-thickness:var(--fp)}
.tc{display:none}
/* ?perf: the frame-cost readout (main.js perfFrame) */
.perf{position:fixed;left:8px;bottom:calc(8px + env(safe-area-inset-bottom, 0px));z-index:90;padding:4px 6px;background:rgba(0,0,0,.7);color:#67e8f9;font-size:var(--s);line-height:1.4;white-space:pre;pointer-events:none}
#title.sound-on .sound-off-only,#title:not(.sound-on) .sound-on-only{display:none}
@media (pointer: coarse){#touchbar{display:flex}.kb{display:none}.tc{display:inline}.hud.bottom{display:none}}
/* in play the thumbs own the bottom of the screen (whorl/input.js: one stick, wherever the thumb lands), so only the
   pause button stays, small, just under the HUD on the right (main.js keeps --hud-bottom); the effects and sound switches join it along
   the bottom on the title and the pause screen */
@media (pointer: coarse){#touchbar #tbFx,#touchbar #tbMusic,#touchbar #tbSfx{display:none}
  body:not(:has(#title.show)):not(:has(#pause.show)) #touchbar{top:var(--hud-bottom, calc(64px + env(safe-area-inset-top, 0px)));bottom:auto}
  body:not(:has(#title.show)):not(:has(#pause.show)) #touchbar button{font-size:var(--s);padding:6px 10px}
  body:has(#title.show) #touchbar button,body:has(#pause.show) #touchbar button{display:inline-block}}
/* hard pixel shadow: a font pixel down and right, in black */
.hud,#intro,.overlay,.meter-label,.luge-hint,.zone-label{text-shadow:var(--glow)}
.hud{position:fixed;left:16px;right:16px;top:calc(12px + env(safe-area-inset-top, 0px));display:flex;justify-content:space-between;align-items:flex-start;gap:12px;font-size:var(--s);pointer-events:none;color:var(--cyan)}
.hud.bottom{top:auto;bottom:calc(10px + env(safe-area-inset-bottom, 0px));justify-content:flex-end;color:var(--grey)}
/* an ultrawide screen: the HUD comes in to a band round the board rather than the far corners */
@media (min-aspect-ratio: 2/1){.hud{left:calc(50% - 88vh);right:calc(50% - 88vh)}}
#score{font-size:var(--m);line-height:1;color:var(--gold);text-shadow:.125em .125em 0 #993300,.25em .25em 0 rgb(0 0 0 / .85)}
#sub{margin-top:var(--px);color:var(--cyan)}
#arena{text-align:center}
/* the streak meter: multiplier, tier name and count, and the fuse burning down */
#streak{margin-top:var(--px);display:flex;flex-wrap:wrap;align-items:baseline;gap:0 var(--m);color:hsl(var(--sh,180) 100% 60%);transition:opacity .3s ease-out}
#streak.off{opacity:0}
#streak b{font-weight:400;font-size:var(--m);display:inline-block}
#streak .fuse{flex-basis:100%;height:calc(var(--px) * 2);margin-top:var(--px);max-width:calc(var(--px) * 40);border:var(--fp) solid currentColor}
#streak .fuse i{display:block;height:100%;width:0;background:currentColor}
#streak.t5 b,#streak.t6 b{animation:throb .5s ease-in-out infinite alternate}
#streak.t7 b,#streak.t8 b,#streak.t9 b{animation:throb .25s ease-in-out infinite alternate}
#streak.t9{color:var(--white)}
@keyframes throb{to{transform:scale(1.25)}}
@keyframes huecycle{to{filter:hue-rotate(360deg)}}
.hud-right{text-align:right}
/* a phone held upright: the score and the lives share the top row, the arena's name (and the marquee) the row under */
@media (max-width: 560px){.hud{flex-wrap:wrap;row-gap:var(--px)}.hud>:first-child{flex:1 1 0;min-width:0}#arena{order:3;flex-basis:100%}}
/* lives: a mascot icon each; they flash when one is won. The next score milestone sits under them. */
#lives{display:flex;justify-content:flex-end;align-items:center;gap:var(--fp);min-height:calc(var(--px) * 5)}
#lives .sprite{display:block}
#lives.gain{animation:gain 1.2s ease-in-out}
@keyframes gain{0%,30%,60%{filter:brightness(2.2)}15%,45%,100%{filter:none}}
#next1up{margin-top:var(--fp);color:var(--grey)}
#gold{margin-top:var(--px);color:var(--gold)}
#gold.bump{animation:goldbump .6s cubic-bezier(.2,1.35,.4,1)}
@keyframes goldbump{0%{transform:scale(2.5)}100%{transform:scale(1)}}
/* callouts: tier names, gold, a lost streak, in wavy pixel text */
/* in play, words go in a lane beside the board, wherever the margin is biggest, so they never cover the play */
@keyframes callfade{0%,80%{opacity:1}100%{opacity:0}}
#msgs{position:fixed;inset:0;pointer-events:none;overflow:hidden}

#intro{position:fixed;left:50%;top:28%;transform:translate(-50%,-50%);text-align:center;pointer-events:none;opacity:0;width:100%;padding:0 16px}
#intro.show{animation:intro 3.2s forwards}
/* a skit's card goes under the stage, clear of the jumbotron's ledger */
#intro.low{top:min(85%, calc(100% - 150px))}
#intro .num{font-size:var(--s);color:var(--cyan)}
#intro .name{font-size:var(--l);line-height:1.3;margin:var(--px) 0;color:var(--pink);text-shadow:.125em .125em 0 #660066,.25em .25em 0 rgb(0 0 0 / .85)}
#intro .tag{font-size:var(--s);color:var(--white);text-transform:uppercase}
#intro .new{margin-top:var(--m);font-size:var(--s);color:var(--gold)}
@keyframes intro{0%{opacity:0;transform:translate(-50%,-50%) scale(2)}12%{opacity:1;transform:translate(-50%,-50%) scale(1)}85%{opacity:1}100%{opacity:0}}
.overlay{position:fixed;inset:0;display:none;flex-direction:column;align-items:center;justify-content:center;text-align:center;padding:16px;gap:var(--m);background:rgba(0,0,0,.6)}
.overlay.show{display:flex}
/* phones play upright: held sideways, a phone gets this instead of a squashed board (tablets and desktops don't) */
#rotate{z-index:60;background:var(--ink)}
@media (pointer: coarse) and (orientation: landscape) and (max-height: 500px){#rotate{display:flex}}
#rotate .phone{width:calc(var(--px) * 9);height:calc(var(--px) * 15);border:var(--px) solid var(--cyan);box-shadow:var(--px) var(--px) 0 var(--navy);animation:upright 1.8s ease-in-out infinite}
#rotate .phone::after{content:'';display:block;width:calc(var(--px) * 3);height:var(--px);margin:calc(var(--px) * 11) auto 0;background:var(--cyan)}
#rotate p{margin:0;font-size:var(--m);color:var(--white)}
@keyframes upright{0%,20%{transform:rotate(-90deg)}55%,100%{transform:rotate(0deg)}}
@media (prefers-reduced-motion: reduce){#rotate .phone{animation:none}}
.overlay>*{flex-shrink:0}
/* the title has its own credit in a bottom corner, so the effects hint steps aside */
body:has(#title.show) .hud.bottom,body:has(#ribbon.show) .hud{display:none}
/* a short screen: the title fills it, so the HUD's top row (an unplayed score, the lives and the HI score, which the
   attract panels show anyway) would sit under the logo */
body:has(#title.show) .hud{display:none}
/* the title can draw on a finer pixel grid of its own, so it always fits the screen (main.js fitTitle sets its --px);
   these work its sizes out again from that */
#title{--fp:calc(var(--px) / 2);--s:calc(var(--px) * 4);--m:calc(var(--px) * 8);--l:calc(var(--px) * 16);--xl:calc(var(--px) * 24)}
#title,#over{cursor:pointer}
.logo{font-size:var(--xl);font-weight:400;margin:0;line-height:1;color:var(--pink);text-shadow:var(--glow);position:relative}
/* the title logo is drawn on a canvas on the game pixel grid: the letters full of sea with ice blocks drifting through */
.logo-art canvas{display:block;image-rendering:pixelated}
.sr{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
.tagline{font-size:var(--s);margin:0;color:var(--cyan)}
.start{font-size:var(--m);margin:var(--m) 0 0;color:var(--white);animation:blink 1s ease-in-out infinite}
/* Continue: a line on the title, and the Orbital Ribbon's panel above the beads */
.continue{margin:0;font-size:var(--s);color:var(--gold)}
.continue button{font:inherit;font-size:var(--m);color:var(--gold);background:var(--ink);border:var(--px) solid var(--gold);padding:var(--px) calc(var(--px) * 3)}
#ribbon{justify-content:flex-start;padding-top:calc(48px + env(safe-area-inset-top, 0px));background:none;pointer-events:none}
#ribbon button{pointer-events:auto;font:inherit;font-size:var(--m);color:var(--cyan);background:var(--ink);border:var(--px) solid var(--cyan);padding:var(--px) calc(var(--px) * 3)}
#ribbonInfo{display:flex;flex-direction:column;gap:var(--px);background:rgba(0,0,0,.6);padding:var(--px) calc(var(--px) * 4);border:var(--px) solid var(--pink)}
#ribbonInfo p{margin:0}.r-map{color:var(--cyan)}.r-name{font-size:var(--m)}.r-best{color:var(--gold);font-size:var(--s)}.r-best.locked{color:var(--grey)}
.ribbon-nav{display:flex;gap:var(--m)}
#ribbon .controls{margin-top:auto}
/* the pause screen's badges: all fifteen, the earned ones lit */
.badges{font-size:var(--s);max-width:min(100%, calc(var(--px) * 200));text-align:left}
.badges .b-head{text-align:center;color:var(--gold);margin:0 0 var(--px)}
.badges ul{list-style:none;margin:0;padding:0;columns:2;column-gap:var(--m)}
.badges li{color:#7a7a7a;break-inside:avoid;margin-bottom:var(--fp)}
.badges li.got{color:var(--white)}.badges li.got b{color:var(--gold)}
.badges li b{font-weight:400}.badges li span{display:none}
@media (min-width: 900px){.badges li span{display:inline;color:var(--grey)}.badges ul{columns:1}}
/* (and when they don't fit the screen with what each asks, just their names) */
.badges.tight li span{display:none}.badges.tight ul{columns:2}
/* initials for the world table, arcade style: three big letters, the one being set lit in gold */
#entry{display:flex;flex-direction:column;align-items:center;gap:var(--px);margin-top:var(--m)}
.entry-head{margin:0;font-size:var(--s);color:var(--gold)}
.entry-keys{margin:0;font-size:var(--s);color:var(--grey)}
.letters{display:flex;gap:calc(var(--px) * 3);align-items:center}
.letter{display:flex;flex-direction:column;align-items:center}
.letter b{font-weight:400;font-size:var(--xl);line-height:1;color:var(--white);padding:0 var(--px);border-bottom:var(--px) solid var(--grey)}
.letter.on b{color:var(--gold);border-color:var(--gold);animation:blink .8s steps(2) infinite}
.letters button{font:inherit;font-size:var(--l);line-height:1;color:var(--cyan);background:none;border:0;padding:var(--px) calc(var(--px) * 3);cursor:pointer;font-family:monospace}
.letters .ok{font-size:var(--m);border:var(--px) solid var(--cyan);padding:var(--px) calc(var(--px) * 3);margin-left:var(--m)}
/* the heroes screen (heroes.js) draws in the game itself: the game-over card steps aside to a strip along the foot */
#over.heroes{background:none;justify-content:flex-end;padding-bottom:calc(var(--m) * 1.5)}
#over.heroes .logo,#over.heroes #final{display:none}
#over.heroes .entry-keys{position:absolute;left:0;right:0;bottom:calc(var(--px) * 4);margin:0} /* (under the ring's front letter, not through it) */
.hero-keys{display:none;gap:var(--m);align-items:center}
@media (pointer: coarse){.hero-keys{display:flex}} /* (a touch screen's: a keyboard types the letters, and the strip would cover the ring's front) */
.hero-keys button{font:inherit;font-size:var(--l);line-height:1;color:var(--cyan);background:none;border:0;padding:var(--px) calc(var(--px) * 3);cursor:pointer;font-family:monospace}
.hero-keys .ok{font-size:var(--m);border:var(--px) solid var(--cyan)}
#title .corner-r{cursor:pointer}
body.heroes-on .hud,body.heroes-on #touchbar,body.heroes-on #camBtn{visibility:hidden}
.keys{font-size:var(--s);line-height:1.8;max-width:min(90vw,calc(var(--px) * 180));margin:0;color:var(--white)}
.warn{font-size:var(--s);line-height:1.8;color:var(--grey);max-width:min(90vw,calc(var(--px) * 150));margin:0}
.controls{font-size:var(--s);color:var(--grey);margin:0}
.stats{font-size:var(--s);line-height:1.8;color:var(--grey);max-width:min(90vw,calc(var(--px) * 150));margin:0}
.stats-btn{font:inherit;color:var(--cyan);background:none;border:0;padding:0;cursor:pointer;text-decoration:underline;text-underline-offset:.3em}
.stats-btn.off{color:var(--grey)}
/* the title cast, like Pengo's: a sprite and a name for each, sprites drawn from the game's own voxel models */
.cast{list-style:none;margin:0;padding:0;display:grid;grid-template-columns:auto auto auto auto;gap:calc(var(--px) * 2) calc(var(--px) * 3);align-items:center;justify-items:start}
@media (max-width: 600px){.cast{grid-template-columns:auto auto}}
.cast li{display:contents}
.sprite{image-rendering:pixelated;display:block;justify-self:center}
.cast span{font-size:var(--s)}
.attract dt .sprite{display:inline-block;vertical-align:middle;margin-right:var(--px)}
/* the Whorl mark, spinning in the bottom corner of the title, the way Pengo signs itself SEGA */
.corner{position:absolute;bottom:calc(12px + env(safe-area-inset-bottom, 0px));font-size:var(--s);display:flex;align-items:center;gap:var(--px)}
.corner-r{right:16px;color:var(--bridge)}
/* the bottom left corner: the volume slider, and over it the version, which opens the version history */
.corner-vol{left:16px}
/* the title's volume slider, short enough to clear the warning centred between the corners; its keys only where there's room */
#title .whorl-volume input{width:calc(var(--px) * 28)}
@media (max-width: 1279px){#title .whorl-volume .kb{display:none}}
@media (pointer: coarse){#title .whorl-volume input{width:calc(var(--px) * 56)}}
.corner-l{left:16px;font:inherit;font-size:var(--s);color:var(--grey);background:none;border:0;padding:0;cursor:pointer}
.corner-l:hover,.corner-l:focus-visible{color:var(--cyan)}
#history{background:rgba(0,0,0,.96);justify-content:flex-start;padding-top:calc(24px + env(safe-area-inset-top, 0px));z-index:5}
.hist-list{width:min(100%, calc(var(--px) * 180));flex:1 1 auto;min-height:0;overflow-y:auto;text-align:left;display:flex;flex-direction:column;gap:var(--m);padding-right:var(--px)}
.hist-list h2{font-size:var(--s);font-weight:400;margin:0 0 var(--px);color:var(--white)}
.hist-list .hv{color:var(--gold)}.hist-list .hd{color:var(--grey)}
.hist-list ul{margin:0;padding-left:calc(var(--px) * 4);color:var(--cyan);font-size:var(--s);display:flex;flex-direction:column;gap:var(--fp)}
.hist-close{font:inherit;font-size:var(--m);color:var(--cyan);background:var(--ink);border:var(--px) solid var(--cyan);padding:var(--px) calc(var(--px) * 3)}
@media (pointer: fine){.hist-close{display:none}}
#historyBtn{bottom:calc(12px + var(--px) * 8 + env(safe-area-inset-bottom, 0px))}
@media (pointer: coarse){#historyBtn{bottom:calc(84px + var(--px) * 8 + env(safe-area-inset-bottom, 0px))}}
#whorlMark{flex:none}
@media (pointer: coarse){.corner{bottom:calc(84px + env(safe-area-inset-bottom, 0px))}}
/* title attract panel: rotates through how-to, scores, snobies, pickups, high score. Every page sits in the same grid
   cell, so the box is always as tall as the tallest page and turning a page never moves the rest of the title. */
.attract{display:grid;width:min(calc(var(--px) * 170),100%);padding:calc(var(--px) * 4);border:var(--px) solid var(--cyan);background:var(--ink);box-shadow:var(--px) var(--px) 0 var(--navy)}
.attract>.page{grid-area:1/1;visibility:hidden}
.attract>.page.on{visibility:visible;animation:panel .3s ease-out both}
@keyframes panel{from{opacity:0}to{opacity:1}}
.attract h2{margin:0 0 var(--m);font-size:var(--s);font-weight:400;color:var(--pink)}
.attract dl{display:grid;grid-template-columns:auto 1fr;gap:var(--px) var(--m);margin:0;text-align:left;font-size:var(--s);align-items:baseline}
.attract dt{color:var(--c,var(--cyan));white-space:nowrap}
.attract dd{margin:0;color:var(--white);min-width:0}
.attract .hi{margin:var(--m) 0 0;font-size:var(--l);line-height:1;color:var(--gold);text-shadow:.125em .125em 0 #993300,.25em .25em 0 rgb(0 0 0 / .85)}
/* bonus stage: catapult power meter and landing-zone labels */
.meter{position:fixed;right:calc(28px + env(safe-area-inset-right, 0px));top:50%;transform:translateY(-50%);width:calc(var(--px) * 7);height:min(46vh,320px);border:var(--px) solid var(--cyan);background:var(--ink);pointer-events:none}
.meter-fill{position:absolute;left:var(--px);right:var(--px);bottom:var(--px);max-height:calc(100% - var(--px) * 2);background:repeating-linear-gradient(to top,var(--pink) 0 calc(var(--px) * 3),var(--cyan) calc(var(--px) * 3) calc(var(--px) * 4));height:0}
.meter-sweet{position:absolute;left:calc(var(--px) * -3);right:calc(var(--px) * -3);top:var(--px);height:8%;border:var(--px) solid var(--gold)}
.meter-label{position:absolute;right:calc(var(--px) * 12);top:50%;transform:translateY(-50%);white-space:nowrap;font-size:var(--s);color:var(--gold);animation:blink .7s ease-in-out infinite}
.luge-hint{position:fixed;left:50%;bottom:calc(64px + env(safe-area-inset-bottom, 0px));transform:translateX(-50%);white-space:nowrap;font-size:var(--s);color:var(--gold);pointer-events:none}
@media (pointer: coarse){.luge-hint{bottom:calc(254px + env(safe-area-inset-bottom, 0px))}} /* (over the trip globe, which sits in the corner under it) */
.globe{position:fixed;left:14px;bottom:calc(14px + env(safe-area-inset-bottom, 0px));width:208px;height:208px;image-rendering:pixelated;pointer-events:none;z-index:4}
/* on a touch screen it sits above the buttons */
@media (pointer: coarse){.globe{width:150px;height:150px;bottom:calc(88px + env(safe-area-inset-bottom, 0px))}}
.zone-label{position:fixed;left:0;top:0;transform:translate(-50%,-50%);font-size:var(--s);color:hsl(var(--h) 100% 60%);pointer-events:none}
.reticle-label{font-size:var(--m)} /* (the luge reticle's pay, where you'll come down) */
/* end-of-round score show: wavy, colour-rolling pixel text over the exploding board. Everything moves smoothly at the
   display's frame rate: the wave is a transform the compositor runs, each letter has its own colour and the whole
   word rolls through the rainbow with one hue rotation, so no letter repaints as it moves. */
.wavy{display:inline-block;white-space:nowrap;--amp:var(--px);--spd:1.1s;--hsp:1.6s;animation:huecycle var(--hsp) linear infinite}
.wavy span{display:inline-block;color:hsl(calc(var(--i) * 32 + 300) 100% 62%);will-change:transform;animation:wave var(--spd) ease-in-out infinite;animation-delay:calc(var(--i) * -.08s)}
@keyframes wave{0%,100%{transform:translateY(0)}50%{transform:translateY(calc(var(--amp) * -1))}}
@keyframes cardcycle{0%{border-color:#ff4fd0}25%{border-color:#ffc14a}50%{border-color:#33ff99}75%{border-color:#67e8f9}100%{border-color:#ff4fd0}}
@keyframes slam{0%{transform:scale(3)}100%{transform:scale(1)}}
#results{background:rgba(0,0,0,.45);cursor:pointer;transition:background .3s}
/* the rank's moment: the card steps out of the way of the voxel rank (main.js rankStage), then comes back */
#results .res-card{transition:opacity .3s,transform .3s}
#results.ranked{background:transparent}#results.ranked .res-card{opacity:0;transform:scale(.9)}
.res-card{width:min(calc(var(--px) * 140),100%);padding:calc(var(--px) * 4);border:var(--px) solid var(--pink);background:var(--ink);box-shadow:calc(var(--px) * 2) calc(var(--px) * 2) 0 var(--navy);display:flex;flex-direction:column;gap:calc(var(--px) * 2);text-align:left;animation:cardcycle 2s linear infinite}
.res-head{align-self:center;font-size:var(--m);padding-top:var(--px)}
.res-lines{display:flex;flex-direction:column;gap:calc(var(--px) * 2);min-height:3em}
.r{display:flex;justify-content:space-between;align-items:baseline;gap:var(--m);opacity:0;transform:translateX(calc(var(--px) * -4));transition:opacity .15s ease-out,transform .25s cubic-bezier(.2,1.35,.4,1)}
.r.on{opacity:1;transform:none}
.r .wavy{font-size:var(--s);--amp:var(--fp);min-width:0}
.r b{font-weight:400;font-size:var(--s);color:var(--white);white-space:nowrap}
.r.settled b{color:var(--gold)}
.res-time{border-top:var(--fp) dashed var(--grey);padding-top:calc(var(--px) * 2);align-items:center}
/* the map's grade, large beside its time, stamped in when the time row pays */
.grade{font-style:normal;font-size:var(--l);line-height:1;opacity:0;display:flex;flex-direction:column;align-items:center}
.grade small{font-size:var(--s);color:var(--gold);animation:blink .6s steps(2) infinite}
.r.settled .grade{opacity:1;animation:slam .45s cubic-bezier(.2,1.35,.4,1)}
.g-S{color:#33ffff}.g-A{color:var(--gold)}.g-B{color:#33ff66}.g-C{color:#ff9933}.g-D{color:var(--grey)}
.res-total{display:flex;justify-content:space-between;align-items:baseline;gap:var(--m);font-size:var(--s);color:var(--cyan);margin-top:var(--px)}
.res-total b{font-weight:400;font-size:var(--m);color:var(--white)}
.slammed .res-total b{animation:slam .4s cubic-bezier(.2,1.35,.4,1)}
.res-quip{align-self:center;font-size:var(--s);text-align:center;opacity:0;transition:opacity .3s .3s ease-out}
.slammed .res-quip{opacity:1}
.res-foot{font-size:var(--s);color:var(--grey);text-align:center}
.res-next{text-align:center;font-size:var(--s);color:var(--cyan)}
.res-skip{text-align:center;font-size:var(--s);color:var(--grey);animation:blink 1.2s ease-in-out infinite}
@media (prefers-reduced-motion: reduce){.wavy,.wavy span{animation:none}.res-card{animation:none}#streak b,#streak{animation:none}.logo{animation:none}}
@keyframes blink{50%{opacity:.2}}
#pause .logo{font-size:var(--l)}
#pause .quit,#pause .race{margin:0}#over .retry{margin:0}#over .retry[hidden]{display:none}#quitBtn.armed{color:var(--pink);border-color:var(--pink)}
.cam-btn{font:inherit;font-size:var(--s);color:var(--cyan);background:var(--ink);border:var(--fp) solid var(--cyan);padding:var(--px) calc(var(--px) * 3);pointer-events:auto;cursor:pointer}
/* the badges on a card of their own, so they read over a busy board */
#pause .badges{max-width:min(100%, calc(var(--px) * 216));background:var(--ink);border:var(--px) solid var(--cyan);box-shadow:var(--px) var(--px) 0 var(--navy);padding:calc(var(--px) * 3) calc(var(--px) * 4)}
/* short screens: the logo steps down a size; phones: the big shouts too */
@media (max-height: 900px){.logo{font-size:var(--l)}.overlay{gap:calc(var(--px) * 3)}}
/* a laptop window (about 720 tall, where the UI pixel is still 4): tighter gaps, so the title fits top to bottom */
@media (max-height: 780px){.overlay{gap:calc(var(--px) * 1.5);padding:8px}.start{margin-top:var(--s)}}
@media (max-width: 600px){.logo{font-size:var(--l)}}
