@font-face { font-family: "Press Start 2P"; src: url("/fonts/PressStart2P.ttf") format("truetype"); font-display: swap; }
/* Body text: Pixelify Sans (SIL Open Font License, fonts/PixelifySans-OFL.txt), a readable pixel face that sits with
   Press Start 2P, bundled like it so nothing loads from another site. A Latin subset, weights 400 to 700. */
@font-face { font-family: "Pixelify Sans"; src: url("/fonts/PixelifySans.woff2") format("woff2"); font-weight: 400 700; font-display: swap; }
:root { --u: 1px; --pix: "Press Start 2P", ui-monospace, monospace; --ui: "Pixelify Sans", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif; }
* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }
html, body { margin: 0; height: 100%; overflow: hidden; background: #12052c; color: #fff; font-family: var(--ui); font-variant-ligatures: none; overscroll-behavior: none; }
body { background: #120833; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; -webkit-touch-callout: none; }
#frame { position: absolute; overflow: hidden; box-shadow: 0 0 0 1px rgba(255,255,255,.05), 0 calc(18 * var(--u)) calc(60 * var(--u)) rgba(0,0,0,.45); }
/* The stage is the 360 x 640 playfield with the Booster Dock running on below it (see client.js, layout). */
#scene { position: absolute; left: 0; top: 0; width: 100%; height: calc(640 * var(--u)); display: block; touch-action: none; }
/* Never drawn: its padding is how layout() reads the notch, rounded-corner and home-bar insets. */
#safe { position: fixed; left: 0; top: 0; width: 0; height: 0; visibility: hidden; pointer-events: none; padding: var(--safe-area-inset-top, env(safe-area-inset-top, 0px)) var(--safe-area-inset-right, env(safe-area-inset-right, 0px)) var(--safe-area-inset-bottom, env(safe-area-inset-bottom, 0px)) var(--safe-area-inset-left, env(safe-area-inset-left, 0px)); }
button { font: inherit; color: inherit; border: 0; cursor: pointer; touch-action: manipulation; }
.hidden { display: none !important; }

/* HUD: positions are in world units (360 wide) via --u */
#hud { position: absolute; inset: 0; pointer-events: none; }
#hud .top { position: absolute; left: calc(8 * var(--u)); right: calc(8 * var(--u)); top: calc(6 * var(--u)); height: calc(46 * var(--u)); display: flex; align-items: center; gap: calc(8 * var(--u)); }
#btnPause { pointer-events: auto; width: calc(38 * var(--u)); height: calc(38 * var(--u)); border-radius: calc(10 * var(--u)); background: rgba(255,255,255,0.12); font-family: var(--pix); font-size: calc(12 * var(--u)); flex: none; display: grid; place-items: center; }
#btnPause .ic { width: calc(14 * var(--u)); height: calc(14 * var(--u)); }
#hud .mid { flex: 1; text-align: center; line-height: 1.25; min-width: 0; }
#hudScore { font-family: var(--pix); font-size: calc(16 * var(--u)); text-shadow: 0 calc(2 * var(--u)) 0 #5a1a8a; }
#hudStage { font-family: var(--pix); font-size: calc(7 * var(--u)); color: #c9b6ff; margin-top: calc(4 * var(--u)); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
#hud .side { text-align: right; font-family: var(--pix); font-size: calc(9 * var(--u)); line-height: 1.7; min-width: calc(82 * var(--u)); }
#hudStars, #hudLives { display: flex; align-items: center; justify-content: flex-end; gap: calc(2.5 * var(--u)); min-height: calc(15 * var(--u)); }
#hudStars b, #hudLives b { font-weight: 400; }
#hudLives { color: #ff5d7a; }
#hudStars { color: #ffd23a; }
#progress { position: absolute; left: calc(8 * var(--u)); right: calc(8 * var(--u)); top: calc(53 * var(--u)); height: calc(2 * var(--u)); background: rgba(255,255,255,0.1); }
#progress i { display: block; height: 100%; width: 0; background: linear-gradient(90deg, #ff5e5b, #ffd23a, #4ad991); transition: width .2s; }
#combo { position: absolute; left: 0; right: 0; top: calc(64 * var(--u)); text-align: center; font-family: var(--pix); font-size: calc(10 * var(--u)); color: #ffd23a; text-shadow: 0 0 calc(8 * var(--u)) rgba(255,140,0,.8), 0 calc(2 * var(--u)) 0 #7a2a00; opacity: 0; transition: opacity .2s; }
#combo.on { opacity: 1; }
#hint { position: absolute; left: 0; right: 0; top: calc(480 * var(--u)); text-align: center; font-family: var(--pix); font-size: calc(9 * var(--u)); opacity: .85; animation: blink 1.2s infinite; }
@keyframes blink { 50% { opacity: .35; } }
#hudBalls { flex: none; min-width: calc(36 * var(--u)); display: flex; align-items: center; gap: calc(3 * var(--u)); font-family: var(--pix); font-size: calc(8 * var(--u)); color: #dcd0ff; }
#hudBalls b { font-weight: 400; }
#toast { position: absolute; left: 50%; top: calc(96 * var(--u)); transform: translateX(-50%); background: rgba(20,6,50,.92); border: calc(1.5 * var(--u)) solid #ffd23a; padding: calc(8 * var(--u)) calc(12 * var(--u)); border-radius: calc(10 * var(--u)); font-size: calc(11 * var(--u)); font-weight: 700; white-space: nowrap; transition: opacity .3s; opacity: 0; pointer-events: none; z-index: 20; }
#toast.on { opacity: 1; }
#hud.covered ~ #toast { top: calc(8 * var(--u)); } /* over a screen (the clear screen's unlocks): above its heading */

/* Screens */
.screen { position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; padding: calc(18 * var(--u)); background: rgba(14,4,36,0.82); backdrop-filter: blur(3px); -webkit-backdrop-filter: blur(3px); overflow-y: auto; z-index: 10; text-align: center; }
.screen.scroll { justify-content: flex-start; }
.screen h2 { font-family: var(--pix); margin: 0 0 calc(10 * var(--u)); line-height: 1.35; font-size: calc(15 * var(--u)); color: #ffd23a; text-shadow: 0 calc(2 * var(--u)) 0 #7a2a00; }
.screen p { font-size: calc(12.5 * var(--u)); line-height: 1.45; color: #e5dcff; margin: calc(4 * var(--u)) 0; }
.btn { display: block; width: 100%; max-width: calc(260 * var(--u)); margin: calc(5 * var(--u)) auto; padding: calc(12 * var(--u)); border-radius: calc(12 * var(--u)); background: #3b1d78; font-family: var(--pix); font-size: calc(10 * var(--u)); box-shadow: inset 0 calc(-3 * var(--u)) 0 rgba(0,0,0,.3); flex: none; }
.btn.primary { background: linear-gradient(#ff8a5b, #ef5a3a); font-size: calc(12 * var(--u)); padding: calc(15 * var(--u)); }
.btn.green { background: linear-gradient(#7fd85a, #3fa83a); }
.btn.small { font-size: calc(8 * var(--u)); padding: calc(10 * var(--u)); }
.btn:active { transform: translateY(calc(2 * var(--u))); }
.row { display: flex; gap: calc(6 * var(--u)); width: 100%; max-width: calc(260 * var(--u)); margin: 0 auto; flex: none; }
.row .btn { margin: calc(4 * var(--u)) 0; flex: 1 1 0; width: auto; min-width: 0; }
#title { background: linear-gradient(rgba(14,4,36,0) 30%, rgba(14,4,36,.92) 56%); backdrop-filter: none; -webkit-backdrop-filter: none; justify-content: flex-end; padding-bottom: calc(24 * var(--u)); }
#title .logo { font-family: var(--pix); font-size: calc(26 * var(--u)); line-height: 1.2; background: linear-gradient(#ffe066, #ff7a59 55%, #f72585); -webkit-background-clip: text; background-clip: text; color: transparent; filter: drop-shadow(0 calc(3 * var(--u)) 0 #3a0a5a); position: relative; }
/* js/logo.js swaps the text for a canvas with one pixel per font pixel (.125em), in a box the size of the text it
   replaces: --logo-w and --logo-h are the letters' width and height in em, set by logo.js from the name itself. */
#title .logo.drawn { width: calc(var(--logo-w, 5) * 1em); height: calc(var(--logo-h, 2.4) * 1em); background: none; filter: none; }
#title .logo.drawn canvas { position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); image-rendering: crisp-edges; image-rendering: pixelated; }
#title .by { font-family: var(--pix); font-size: calc(9 * var(--u)); color: #c9b6ff; margin: calc(6 * var(--u)) 0 calc(14 * var(--u)); position: relative; }
#title .best { font-family: var(--pix); font-size: calc(8 * var(--u)); color: #ffd23a; margin-top: calc(10 * var(--u)); position: relative; line-height: 1.6; }
#title .btn, #title .row { position: relative; }
#title .menu { display: contents; } /* the wide layout makes it the menu column */
.card { background: rgba(255,255,255,0.07); border-radius: calc(14 * var(--u)); padding: calc(12 * var(--u)); width: 100%; max-width: calc(310 * var(--u)); margin: calc(6 * var(--u)) auto; text-align: left; flex: none; }
.card h3 { font-family: var(--pix); font-size: calc(9 * var(--u)); margin: 0 0 calc(8 * var(--u)); color: #9be564; line-height: 1.4; }
.stats { display: grid; grid-template-columns: 1fr auto; gap: calc(6 * var(--u)) calc(12 * var(--u)); font-size: calc(12.5 * var(--u)); width: 100%; max-width: calc(260 * var(--u)); margin: calc(8 * var(--u)) auto; text-align: left; flex: none; }
.stats b { font-family: var(--pix); font-size: calc(10 * var(--u)); text-align: right; color: #ffd23a; }
.lb { width: 100%; font-size: calc(12 * var(--u)); border-collapse: collapse; }
.lb td { padding: calc(4 * var(--u)); border-bottom: 1px solid rgba(255,255,255,.07); }
.lb td:last-child { text-align: right; font-family: var(--pix); font-size: calc(8.5 * var(--u)); }
.lb tr.you td { color: #ffd23a; font-weight: 700; }
.muted { color: #a99ccc !important; font-size: calc(11 * var(--u)) !important; }
input[type=text] { width: 100%; padding: calc(10 * var(--u)); border-radius: calc(10 * var(--u)); border: calc(1.5 * var(--u)) solid #5b3aa8; background: #1d0b45; color: #fff; font-size: 16px; font-family: var(--ui); text-align: center; user-select: text; -webkit-user-select: text; -moz-user-select: text; -ms-user-select: text; }
input[type=text][readonly] { border-style: dashed; color: #c9b6ff; } /* the name comes from the player's portal account */
.toggle { display: flex; align-items: center; justify-content: space-between; gap: calc(10 * var(--u)); width: 100%; max-width: calc(290 * var(--u)); margin: calc(5 * var(--u)) auto; padding: calc(10 * var(--u)) calc(12 * var(--u)); background: rgba(255,255,255,.07); border-radius: calc(12 * var(--u)); font-size: calc(13 * var(--u)); text-align: left; flex: none; }
.toggle small { display: block; color: #a99ccc; font-size: calc(10.5 * var(--u)); }
.toggle input[type=checkbox] { width: calc(22 * var(--u)); height: calc(22 * var(--u)); accent-color: #ff7a59; flex: none; }
.toggle input[type=range] { width: calc(110 * var(--u)); accent-color: #ff7a59; }
.skins { display: grid; grid-template-columns: repeat(3, 1fr); gap: calc(8 * var(--u)); }
.skin { background: rgba(255,255,255,.07); border-radius: calc(12 * var(--u)); padding: calc(10 * var(--u)) calc(4 * var(--u)); font-size: calc(10 * var(--u)); border: calc(2 * var(--u)) solid transparent; text-align: center; }
.skin.sel { border-color: #ffd23a; }
.skin.locked { opacity: .45; }
.skin i { display: block; margin: 0 auto calc(6 * var(--u)); }
.skin small { display: block; color: #a99ccc; font-size: calc(8.5 * var(--u)); margin-top: calc(3 * var(--u)); }
/* an orb as the hints and How to play show it: the green x3 / +3 badge */
.orb { display: inline-grid; place-items: center; flex: none; width: calc(26 * var(--u)); height: calc(26 * var(--u)); border-radius: 50%; background: #8be04e; color: #fff; font-family: var(--pix); font-weight: 400; font-size: calc(9 * var(--u)); box-shadow: inset 0 calc(-2.5 * var(--u)) 0 rgba(0,0,0,.22), 0 0 0 calc(2 * var(--u)) #d8ff9e; }
/* How to play (Settings): a picture, a name and a line for each thing the game teaches while it is played */
.howto { display: flex; flex-direction: column; gap: calc(9 * var(--u)); width: 100%; max-width: calc(330 * var(--u)); margin: calc(4 * var(--u)) auto calc(6 * var(--u)); text-align: left; }
.how { display: grid; grid-template-columns: calc(46 * var(--u)) minmax(0, 1fr); column-gap: calc(10 * var(--u)); row-gap: calc(3 * var(--u)); align-items: center; }
.how-ic { grid-row: 1 / 3; display: flex; justify-content: center; align-items: center; gap: calc(1 * var(--u)); }
.how-ic .ic { width: calc(26 * var(--u)); height: calc(26 * var(--u)); }
.how-ic .ic.mouse { width: calc(21 * var(--u)); height: calc(28 * var(--u)); }
.how-ic .ic.ball { width: calc(11 * var(--u)); height: calc(11 * var(--u)); }
.how b { font-family: var(--pix); font-weight: 400; font-size: calc(9 * var(--u)); color: #ffd23a; }
.how span:last-child { font-size: calc(11.5 * var(--u)); line-height: 1.35; color: #e6dcff; }
#howtoKeys:empty { display: none; }
/* the clear screen's picture: the stage as it stood, one block per brick */
#clearPic { display: block; width: auto; height: calc(46 * var(--u)); margin: 0 auto calc(7 * var(--u)); image-rendering: pixelated; image-rendering: crisp-edges; filter: drop-shadow(0 0 calc(8 * var(--u)) rgba(255,210,58,.35)); }
/* In-play hints (js/coach.js), in field units: a bubble pointing down at what it explains, and the move-and-serve
   gesture over the paddle before a new player's first serves. Neither takes a click: the game plays on under them. */
/* --cu: the hints' unit. The field unit, but never under 0.9 stage units, so their words keep the wide layout's
   8-unit minimum (the field unit is 0.65 of a stage unit there). */
#coach, #gesture { --cu: max(var(--fu), calc(0.9 * var(--u))); }
#coach { position: absolute; z-index: 14; left: 0; top: 0; transform: translate(-50%, calc(-100% - 7 * var(--cu))); display: flex; align-items: center; gap: calc(5 * var(--cu)); padding: calc(6 * var(--cu)) calc(9 * var(--cu)); border-radius: calc(9 * var(--cu)); background: rgba(20,6,50,.8); border: calc(1.5 * var(--cu)) solid #ffd23a; color: #fff; font-family: var(--pix); font-size: max(10px, calc(9 * var(--cu))); line-height: 1.25; white-space: nowrap; pointer-events: none; opacity: 0; transition: opacity .25s; }
#coach.on { opacity: 1; }
#coach::after { content: ""; position: absolute; left: calc(50% + var(--px, 0px)); bottom: calc(-6.5 * var(--cu)); transform: translateX(-50%); border: calc(6 * var(--cu)) solid transparent; border-top-color: #ffd23a; border-bottom: 0; }
#coach.below { transform: translate(-50%, calc(7 * var(--cu))); } /* no room above, or pointing up at the HUD */
#coach.below::after { bottom: auto; top: calc(-6.5 * var(--cu)); border: calc(6 * var(--cu)) solid transparent; border-bottom-color: #ffd23a; border-top: 0; }
#coach .ic { width: max(11px, calc(11 * var(--cu))); height: max(11px, calc(11 * var(--cu))); }
#coach .orb { width: max(22px, calc(22 * var(--cu))); height: max(22px, calc(22 * var(--cu))); font-size: max(9px, calc(9 * var(--cu))); box-shadow: inset 0 calc(-2 * var(--cu)) 0 rgba(0,0,0,.22), 0 0 0 calc(1.5 * var(--cu)) #d8ff9e; }
.orb.plus3 { background: #38bdf8; } #coach .orb.plus3 { box-shadow: inset 0 calc(-2 * var(--cu)) 0 rgba(0,0,0,.22), 0 0 0 calc(1.5 * var(--cu)) #b5ecff; } /* the +3 orb is blue in play */
#gesture { position: absolute; z-index: 13; left: 0; top: 0; transform: translate(-50%, -50%); display: flex; flex-direction: column; align-items: center; gap: calc(5 * var(--cu)); color: #fff; font-family: var(--pix); font-size: max(10px, calc(10 * var(--cu))); text-shadow: 0 calc(1.5 * var(--cu)) 0 rgba(0,0,0,.65); pointer-events: none; }
#gesture .g-move { display: block; height: calc(30 * var(--cu)); animation: gslide 1.5s ease-in-out infinite alternate; }
#gesture .g-move .ic { width: calc(23 * var(--cu)); height: calc(30 * var(--cu)); }
#gesture .g-move .ic.drag { width: calc(30 * var(--cu)); }
#gesture .g-keys { display: flex; gap: calc(4 * var(--cu)); }
#gesture kbd { display: grid; place-items: center; min-width: calc(18 * var(--cu)); height: calc(18 * var(--cu)); padding: 0 calc(4 * var(--cu)); border-radius: calc(4 * var(--cu)); background: rgba(255,255,255,.14); box-shadow: inset 0 calc(-2 * var(--cu)) 0 rgba(0,0,0,.4); font: inherit; font-size: max(9px, calc(9 * var(--cu))); text-shadow: none; }
#gesture kbd .ic { width: calc(9 * var(--cu)); height: calc(9 * var(--cu)); }
@keyframes gslide { from { transform: translateX(calc(-24 * var(--cu))); } to { transform: translateX(calc(24 * var(--cu))); } }
@media (prefers-reduced-motion: reduce) { #gesture .g-move { animation: none; } }
.dots { margin: calc(10 * var(--u)) 0; display: flex; justify-content: center; gap: calc(7 * var(--u)); flex: none; }
.dots span { width: calc(6 * var(--u)); height: calc(6 * var(--u)); background: #6c5a9a; }
.dots .on { background: #ffd23a; }
.code { font-family: var(--pix); font-size: calc(18 * var(--u)); letter-spacing: calc(3 * var(--u)); color: #9be564; margin: calc(6 * var(--u)) 0; text-align: center; }

/* banners for stage intros, storms and combo tiers */
#banner { position: absolute; left: 0; right: 0; top: calc(250 * var(--u)); text-align: center; pointer-events: none; z-index: 15; opacity: 0; }
#banner.on { animation: bannerIn 1.3s ease-out forwards; }
#banner b { display: block; font-family: var(--pix); font-size: calc(20 * var(--u)); text-shadow: 0 0 calc(12 * var(--u)) currentColor, 0 calc(3 * var(--u)) 0 rgba(0,0,0,.65); }
#banner small { display: block; margin-top: calc(8 * var(--u)); font-family: var(--pix); font-size: calc(9 * var(--u)); color: #fff; opacity: .9; text-shadow: 0 calc(2 * var(--u)) 0 rgba(0,0,0,.6); }
#banner.green b { color: #b6ff7a; } #banner.gold b { color: #ffd23a; } #banner.pink b { color: #ff7ad9; } #banner.violet b { color: #d9ccff; }
@keyframes bannerIn { 0% { opacity: 0; transform: scale(1.8); } 12% { opacity: 1; transform: scale(1); } 75% { opacity: 1; transform: none; } 100% { opacity: 0; transform: translateY(calc(-20 * var(--u))) scale(.96); } }
.rating { display: flex; flex-wrap: wrap; justify-content: center; gap: calc(9 * var(--u)); margin: calc(5 * var(--u)) 0; flex: none; }
.rating .ic { width: calc(33 * var(--u)); height: calc(30 * var(--u)); opacity: .2; filter: grayscale(1); }
.rating .ic.on { opacity: 1; filter: drop-shadow(0 0 calc(7 * var(--u)) rgba(255,190,0,.75)); }
.rating em { flex-basis: 100%; }
.rating em { display: block; font-style: normal; font-family: var(--pix); font-size: calc(9 * var(--u)); color: #8be04e; letter-spacing: 0; margin-top: calc(4 * var(--u)); }

/* pixel icons: published as CSS variables by js/icons.js and scaled without smoothing */
.ic { display: inline-block; flex: none; width: calc(9 * var(--u)); height: calc(9 * var(--u)); background: center / contain no-repeat; image-rendering: crisp-edges; image-rendering: pixelated; vertical-align: middle; }
.ic.big { width: calc(66 * var(--u)); height: calc(66 * var(--u)); }
.ic.star { background-image: var(--ic-star); } .ic.heart { background-image: var(--ic-heart); } .ic.ball { background-image: var(--ic-ball); }
.ic.pause { background-image: var(--ic-pause); } .ic.lock { background-image: var(--ic-lock); } .ic.bomb { background-image: var(--ic-bomb); }
.ic.sweep { background-image: var(--ic-sweep); } .ic.long { background-image: var(--ic-long); } .ic.flame { background-image: var(--ic-flame); }
.ic.gun { background-image: var(--ic-gun); } .ic.shield { background-image: var(--ic-shield); } .ic.drag { background-image: var(--ic-drag); }
.ic.mouse { background-image: var(--ic-mouse); } .ic.arrL { background-image: var(--ic-arrL); } .ic.arrR { background-image: var(--ic-arrR); } .ic.arrD { background-image: var(--ic-arrD); }
.ic.arrU { background-image: var(--ic-arrU); } .ic.steel { background-image: var(--ic-steel); }
.skin small .ic { width: calc(8 * var(--u)); height: calc(9 * var(--u)); }

/* Top 100 */
.tabs { display: flex; gap: calc(5 * var(--u)); width: 100%; max-width: calc(310 * var(--u)); margin: calc(2 * var(--u)) auto calc(4 * var(--u)); flex: none; }
.tab { flex: 1 1 0; min-width: 0; padding: calc(10 * var(--u)) calc(2 * var(--u)); border-radius: calc(10 * var(--u)); background: rgba(255,255,255,.07); font-family: var(--pix); font-size: calc(7 * var(--u)); color: #c9b6ff; }
.tab.on { background: #3b1d78; color: #ffd23a; box-shadow: inset 0 calc(-2 * var(--u)) 0 rgba(0,0,0,.3); }
#topInfo { font-family: var(--pix); font-size: calc(6 * var(--u)) !important; line-height: 1.7; color: #9be564 !important; }
#topYou { border: calc(1.5 * var(--u)) solid #ffd23a; }
#topYou p { margin: calc(3 * var(--u)) 0 0; }
#topNote { max-width: calc(310 * var(--u)); margin-left: auto; margin-right: auto; }

/* shown by afterBreak() while an ad is being requested: blocks every click until the request settles */
/* A question on the game's own panel (js/ask.js), in builds that cannot use the browser's dialogs. */
#ask { position: fixed; inset: 0; z-index: 31; display: grid; place-items: center; padding: calc(18 * var(--u)); background: rgba(14,4,36,.74); touch-action: none; }
#ask .askbox { width: 100%; max-width: calc(280 * var(--u)); padding: calc(16 * var(--u)) calc(14 * var(--u)) calc(12 * var(--u)); border-radius: calc(14 * var(--u)); background: #24104f; border: calc(1.5 * var(--u)) solid #5b3aa8; box-shadow: 0 calc(12 * var(--u)) calc(40 * var(--u)) rgba(0,0,0,.5); text-align: center; }
#ask p { font-size: calc(12.5 * var(--u)); line-height: 1.45; color: #e5dcff; margin: 0 0 calc(12 * var(--u)); }
#ask input { margin-bottom: calc(8 * var(--u)); text-transform: uppercase; letter-spacing: .18em; }
#adwait { position: fixed; inset: 0; z-index: 30; display: grid; place-items: center; background: rgba(14,4,36,.6); touch-action: none; opacity: 0; animation: adwait .2s .25s forwards; }
#adwait i { width: calc(30 * var(--u)); height: calc(30 * var(--u)); border: calc(4 * var(--u)) solid rgba(255,255,255,.22); border-top-color: #ffd23a; border-radius: 50%; animation: spin .8s linear infinite; }
@keyframes adwait { to { opacity: 1; } }
@keyframes spin { to { transform: rotate(360deg); } }

/* ── WIDE LAYOUT ─────────────────────────────────────────────────────────────
   layout() in client.js picks it when the viewport is at least 1.25 times as wide as it is high and
   marks it with body[data-layout="wide"]. The frame is then the stage: 360 units high (--u) and 450 to
   640 wide. The field is a 9:16 box in its centre; --fu is its unit (what --u is in the tall layout) and
   --side is the room on each side of it. Every rule from here on is scoped to the wide layout, so the
   tall rules above stay as they are. A new or changed screen needs its rules in BOTH places. */
body[data-layout="wide"], body[data-layout="wide"] #frame { touch-action: none; }
body[data-layout="wide"] #frame { overflow: visible; box-shadow: none; }
body[data-layout="wide"] #scene { left: var(--side); right: auto; width: var(--fw); height: 100%; box-shadow: 0 0 0 1px rgba(255,255,255,.06), 0 0 calc(36 * var(--u)) rgba(0,0,0,.5); }

/* HUD: nothing but the launch hint, the combo, toasts and banners stays over the field */
body[data-layout="wide"] #hud { --pw: min(calc(var(--side) - 16 * var(--u)), calc(150 * var(--u))); }
body[data-layout="wide"] #hud.covered { visibility: hidden; } /* a screen is open: it uses the whole stage */
/* left of the field: pause in the corner; progress, stage, score, stars, lives and balls on one card that grows downwards when the stage label wraps */
body[data-layout="wide"] #hud .top { left: 0; right: auto; top: calc(114 * var(--u)); width: var(--side); height: auto; flex-direction: column; gap: 0; padding: calc(24 * var(--u)) calc(8 * var(--u)) 0; z-index: 0; }
body[data-layout="wide"] #hud .top::before { content: ""; position: absolute; z-index: -1; left: calc((var(--side) - var(--pw)) / 2 - 6 * var(--u)); width: calc(var(--pw) + 12 * var(--u)); top: 0; bottom: calc(-12 * var(--u)); border-radius: calc(12 * var(--u)); background: rgba(10,0,30,.5); box-shadow: inset 0 0 0 calc(1 * var(--u)) rgba(255,255,255,.09); }
body[data-layout="wide"] #btnPause { position: absolute; left: calc(8 * var(--u)); top: calc(-106 * var(--u)); width: calc(32 * var(--u)); height: calc(32 * var(--u)); }
body[data-layout="wide"] #progress { left: calc((var(--side) - var(--pw)) / 2); right: auto; width: var(--pw); top: calc(126 * var(--u)); height: calc(4 * var(--u)); border-radius: calc(2 * var(--u)); overflow: hidden; }
body[data-layout="wide"] #hud .mid { flex: none; width: 100%; display: flex; flex-direction: column-reverse; }
body[data-layout="wide"] #hudStage { font-size: calc(8 * var(--u)); line-height: 1.5; margin-top: 0; white-space: normal; overflow: visible; }
body[data-layout="wide"] #hudScore { font-size: min(calc(16 * var(--u)), calc((var(--side) - 16 * var(--u)) / 10)); margin-top: calc(4 * var(--u)); }
body[data-layout="wide"] #hud .side { flex: none; width: 100%; min-width: 0; margin-top: calc(10 * var(--u)); text-align: center; font-size: calc(10 * var(--u)); line-height: 1; }
body[data-layout="wide"] #hudStars, body[data-layout="wide"] #hudLives, body[data-layout="wide"] #hudBalls { justify-content: center; min-width: 0; min-height: 0; height: calc(16 * var(--u)); gap: calc(3 * var(--u)); }
body[data-layout="wide"] #hudBalls { order: 3; font-size: calc(10 * var(--u)); }
body[data-layout="wide"] #hud .side .ic, body[data-layout="wide"] #hudBalls .ic { width: calc(10 * var(--u)); height: calc(10 * var(--u)); }
body[data-layout="wide"] #combo { left: var(--side); right: var(--side); top: calc((64 - var(--vt)) * var(--fu)); font-size: calc(16 * var(--fu)); text-shadow: 0 0 calc(8 * var(--fu)) rgba(255,140,0,.8), 0 calc(2 * var(--fu)) 0 #7a2a00; }
body[data-layout="wide"] #hint { left: var(--side); right: var(--side); top: calc((480 - var(--vt)) * var(--fu)); font-size: calc(16 * var(--fu)); }
/* right of the field: the Booster Dock as a column. Same keys, same More tray (it opens over the three keys above it) */
body[data-layout="wide"] .dk { left: auto; right: calc((var(--side) - var(--pw)) / 2 - 6 * var(--u)); width: calc(var(--pw) + 12 * var(--u)); top: 50%; bottom: auto; height: auto; transform: translateY(-50%); padding: calc(8 * var(--u)); border-radius: calc(12 * var(--u)); box-shadow: inset 0 0 0 calc(1 * var(--u)) rgba(255,255,255,.09); }
body[data-layout="wide"] .dk-row { flex-direction: column; height: auto; }
body[data-layout="wide"] .dk-row .dk-key { flex: none; height: calc(64 * var(--u)); }
body[data-layout="wide"] .dk-tray { left: calc(8 * var(--u)); right: calc(8 * var(--u)); top: calc(8 * var(--u)); bottom: calc(78 * var(--u)); }
body[data-layout="wide"] .dk-panel { display: grid; grid-template-columns: 1fr 1fr; grid-template-rows: 1fr 1fr; }
body[data-layout="wide"] .dk-more .dk-plate, body[data-layout="wide"] .dk-key.need .dk-note .dk-plate { font-size: max(var(--dk-f2), calc(8 * var(--u))); } /* the small labels are 7 units in the tall layout */
body[data-layout="wide"] .dk-panel .dk-note { height: auto; min-height: calc(12 * var(--u)); }
body[data-layout="wide"] .dk-panel .dk-note .dk-plate { max-width: calc(100% - 4 * var(--u)); padding: calc(2 * var(--u)) calc(3 * var(--u)); white-space: normal; text-align: center; line-height: 1.3; } /* "NEED 10" wraps on a narrow tray key */
body[data-layout="wide"] #toast { top: calc((106 - var(--vt)) * var(--fu)); width: max-content; max-width: calc(340 * var(--fu)); white-space: normal; text-align: center; font-size: calc(16 * var(--fu)); padding: calc(10 * var(--fu)) calc(14 * var(--fu)); border-width: calc(2.5 * var(--fu)); border-radius: calc(14 * var(--fu)); }
body[data-layout="wide"] #banner { left: var(--side); right: var(--side); top: calc((250 - var(--vt)) * var(--fu)); }
body[data-layout="wide"] #banner.on { animation-name: bannerInWide; }
body[data-layout="wide"] #banner b { font-size: calc(20 * var(--fu)); text-shadow: 0 0 calc(12 * var(--fu)) currentColor, 0 calc(3 * var(--fu)) 0 rgba(0,0,0,.65); }
body[data-layout="wide"] #banner small { margin-top: calc(8 * var(--fu)); font-size: calc(14.5 * var(--fu)); line-height: 1.4; text-shadow: 0 calc(2 * var(--fu)) 0 rgba(0,0,0,.6); }
@keyframes bannerInWide { 0% { opacity: 0; transform: scale(1.8); } 12% { opacity: 1; transform: scale(1); } 75% { opacity: 1; transform: none; } 100% { opacity: 0; transform: translateY(calc(-20 * var(--fu))) scale(.96); } }

/* screens: laid out across the whole stage in two or three columns; the dim reaches past the stage on very wide windows */
body[data-layout="wide"] .screen { padding: calc(14 * var(--u)) calc(20 * var(--u)); box-shadow: 0 0 0 100vmax rgba(14,4,36,.82); }
body[data-layout="wide"] .btn { line-height: 1.5; padding: calc(9.5 * var(--u)) calc(10 * var(--u)); }
body[data-layout="wide"] .btn.primary { padding: calc(12 * var(--u)) calc(10 * var(--u)); }
body[data-layout="wide"] .btn.small { padding: calc(8 * var(--u)); }
body[data-layout="wide"] input[type=text] { font-size: max(16px, calc(11 * var(--u))); }
body[data-layout="wide"] .lb td:first-child { word-break: break-word; overflow-wrap: anywhere; }
body[data-layout="wide"] .lb td + td { white-space: nowrap; }

/* title: logo left, menu right, the demo plays undimmed between them */
body[data-layout="wide"] #title { display: grid; grid-template-columns: var(--side) var(--fw) var(--side); grid-template-rows: 1fr auto auto auto 1fr; justify-items: center; padding: 0; overflow: hidden; box-shadow: 0 0 0 100vmax rgba(14,4,36,.6);
  background: linear-gradient(90deg, rgba(14,4,36,.6) calc(var(--side) - 26 * var(--u)), rgba(14,4,36,0) calc(var(--side) + 6 * var(--u)), rgba(14,4,36,0) calc(100% - var(--side) - 6 * var(--u)), rgba(14,4,36,.6) calc(100% - var(--side) + 26 * var(--u))); }
body[data-layout="wide"] #title .logo { grid-area: 2 / 1; align-self: end; font-size: min(calc(32 * var(--u)), calc((var(--side) - 20 * var(--u)) / (var(--logo-w, 5) + .9))); } /* + .9: the ball and debris beside the name need their room */
body[data-layout="wide"] #title .by { grid-area: 3 / 1; margin: calc(8 * var(--u)) 0; }
body[data-layout="wide"] #title .best { grid-area: 4 / 1; align-self: start; margin-top: 0; padding: 0 calc(6 * var(--u)); }
body[data-layout="wide"] #title .menu { grid-area: 1 / 3 / 6 / 4; align-self: center; width: 100%; display: flex; flex-direction: column; align-items: center; }
body[data-layout="wide"] #title .btn, body[data-layout="wide"] #title .row { width: calc(100% - 16 * var(--u)); max-width: calc(190 * var(--u)); margin: calc(4 * var(--u)) 0; }
body[data-layout="wide"] #btnPlay { padding-left: calc(8 * var(--u)); padding-right: calc(8 * var(--u)); font-size: min(calc(12 * var(--u)), calc((var(--side) - 36 * var(--u)) / 8.2)); }
body[data-layout="wide"] #title .row { flex-wrap: wrap; gap: 0 calc(6 * var(--u)); }
body[data-layout="wide"] #title .row .btn { flex: 1 1 calc(90 * var(--u)); width: auto; max-width: none; }

/* pause, fail, stage clear: what happened on the left, what to do next on the right */
body[data-layout="wide"] #pause, body[data-layout="wide"] #fail, body[data-layout="wide"] #clear { display: grid; grid-template-columns: repeat(2, minmax(0, calc(214 * var(--u)))); column-gap: calc(24 * var(--u)); align-content: center; }
body[data-layout="wide"] #pause h2 { grid-area: 1 / 1 / 3 / 2; align-self: end; }
body[data-layout="wide"] #pauseInfo { grid-area: 3 / 1 / 5 / 2; align-self: start; }
body[data-layout="wide"] #btnResume { grid-area: 1 / 2; }
body[data-layout="wide"] #btnRetryP { grid-area: 2 / 2; }
body[data-layout="wide"] #btnSettingsP { grid-area: 3 / 2; }
body[data-layout="wide"] #btnQuit { grid-area: 4 / 2; }
body[data-layout="wide"] #fail h2 { grid-area: 1 / 1; align-self: end; }
body[data-layout="wide"] #failText { grid-area: 2 / 1 / 4 / 2; align-self: start; }
body[data-layout="wide"] #btnRetry { grid-area: 1 / 2; }
body[data-layout="wide"] #btnRelax { grid-area: 2 / 2; }
body[data-layout="wide"] #btnFailMenu { grid-area: 3 / 2; }
body[data-layout="wide"] #btnRelax.hidden + #btnFailMenu { grid-area: 2 / 2; }
body[data-layout="wide"] #clearTitle { grid-area: 1 / 1; }
body[data-layout="wide"] #clearName { grid-area: 2 / 1; }
body[data-layout="wide"] #clearRating { grid-area: 3 / 1; }
body[data-layout="wide"] #clearUnlock { grid-area: 4 / 1; }
body[data-layout="wide"] #clearStats { grid-area: 1 / 2 / 5 / 3; }
body[data-layout="wide"] #btnClearMenu { grid-area: 5 / 1; }
body[data-layout="wide"] #btnNext { grid-area: 5 / 2; }

/* How to play: two columns of pictures and lines across the stage */
body[data-layout="wide"] #howto { justify-content: center; }
body[data-layout="wide"] .howto { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: calc(22 * var(--u)); row-gap: calc(12 * var(--u)); max-width: calc(560 * var(--u)); }
body[data-layout="wide"] #btnHowtoBack { min-width: calc(160 * var(--u)); }

/* team play: the two players side by side, everything else across both */
body[data-layout="wide"] #team { display: grid; grid-template-columns: repeat(2, minmax(0, calc(200 * var(--u)))); column-gap: calc(14 * var(--u)); align-content: center; justify-content: center; }
body[data-layout="wide"] #team > * { grid-column: 1 / -1; }
body[data-layout="wide"] #team > .card { grid-column: auto; align-self: stretch; max-width: none; margin: calc(5 * var(--u)) 0; }

/* settings: two columns of switches */
body[data-layout="wide"] #settings { display: grid; grid-template-columns: repeat(2, minmax(0, calc(262 * var(--u)))); gap: calc(6 * var(--u)) calc(12 * var(--u)); align-content: center; align-items: stretch; }
body[data-layout="wide"] #settings h2 { grid-column: 1 / -1; margin-bottom: calc(4 * var(--u)); }
body[data-layout="wide"] #settings .toggle { max-width: none; margin: 0; }
body[data-layout="wide"] #settings .btn { margin: calc(4 * var(--u)) auto 0; align-self: center; }

/* locker and Stadium: BACK sits beside the heading, so it never scrolls out of reach; empty first and last rows centre the page while it fits */
body[data-layout="wide"] #locker, body[data-layout="wide"] #stadium { display: grid; grid-template-columns: repeat(6, minmax(0, 1fr)); grid-template-rows: 1fr auto auto auto 1fr; column-gap: calc(8 * var(--u)); align-items: start; }
body[data-layout="wide"] #locker .card, body[data-layout="wide"] #stadium > .card { max-width: none; margin: calc(5 * var(--u)) 0; }
body[data-layout="wide"] #btnLockerBack, body[data-layout="wide"] #btnStadiumBack { grid-area: 2 / 1 / 4 / 2; align-self: center; margin: 0; }
body[data-layout="wide"] #locker h2 { grid-area: 2 / 2 / 3 / 6; }
body[data-layout="wide"] #locker > p { grid-area: 3 / 2 / 4 / 6; margin-bottom: calc(6 * var(--u)); }
body[data-layout="wide"] #locker .card { grid-row: 4; grid-column: span 3; align-self: stretch; }

/* Stadium below 17:10: heading and name on top, the two boards side by side under them */
body[data-layout="wide"] #stadium > .card { padding: calc(9 * var(--u)); }
body[data-layout="wide"] #stadium .row .btn.primary { flex-grow: 1.3; }
body[data-layout="wide"] #stadium { padding-top: calc(10 * var(--u)); padding-bottom: calc(10 * var(--u)); }
body[data-layout="wide"] #stadium .code { margin: calc(3 * var(--u)) 0; }
body[data-layout="wide"] #stadium .row .btn { margin: calc(3 * var(--u)) 0; }
body[data-layout="wide"] #stadium .lb { font-size: calc(10.5 * var(--u)); }
body[data-layout="wide"] #stadium .lb td { padding: calc(2 * var(--u)) calc(3 * var(--u)); }
body[data-layout="wide"] #stadium .card h3 { margin-bottom: calc(6 * var(--u)); }
body[data-layout="wide"] #stadium .card > .btn { margin: calc(4 * var(--u)) auto 0; }
body[data-layout="wide"] #stadium .lb td + td { font-size: calc(8 * var(--u)); }
@media not all and (min-aspect-ratio: 17/10) {
  body[data-layout="wide"] #btnStadiumBack { grid-area: 2 / 1 / 3 / 2; }
  body[data-layout="wide"] #stadium h2 { grid-area: 2 / 2 / 3 / 5; align-self: center; font-size: calc(14 * var(--u)); margin: 0; }
  body[data-layout="wide"] #stadium > p { grid-area: 3 / 1 / 4 / 5; margin: calc(6 * var(--u)) 0 0; }
  body[data-layout="wide"] #stadium > .card:nth-of-type(1) { grid-area: 2 / 5 / 4 / 7; align-self: center; }
  body[data-layout="wide"] #stadium > .card:nth-of-type(2) { grid-area: 4 / 1 / 5 / 4; }
  body[data-layout="wide"] #stadium > .card:nth-of-type(3) { grid-area: 4 / 4 / 5 / 7; }
}
/* from 17:10 up: heading, name and BACK in a first column, one board in each of the other two.
   The boards are placed on their own and scroll inside if a board gets long, so the page itself never has to. */
@media (min-aspect-ratio: 17/10) {
  body[data-layout="wide"] #stadium { grid-template-columns: calc(132 * var(--u)); grid-template-rows: none; justify-content: start; align-content: center; padding-left: calc(16 * var(--u)); padding-right: calc(16 * var(--u)); }
  body[data-layout="wide"] #btnStadiumBack { grid-area: auto; margin-top: calc(8 * var(--u)); }
  body[data-layout="wide"] #stadium > .card:nth-of-type(n+2) { position: absolute; top: 50%; transform: translateY(-50%); width: calc(50% - 90 * var(--u)); max-height: calc(100% - 20 * var(--u)); overflow-y: auto; margin: 0; }
  body[data-layout="wide"] #stadium > .card:nth-of-type(2) { left: calc(156 * var(--u)); }
  body[data-layout="wide"] #stadium > .card:nth-of-type(3) { left: calc(50% + 74 * var(--u)); }
}

/* run over and Top 100: result, tabs and buttons left; the board right, scrolling inside when it is long */
body[data-layout="wide"] #runover, body[data-layout="wide"] #top { display: grid; grid-template-columns: minmax(0, .45fr) minmax(0, .55fr); column-gap: calc(16 * var(--u)); align-content: center; }
body[data-layout="wide"] #runover > *, body[data-layout="wide"] #top > * { grid-column: 1; }
body[data-layout="wide"] #runover > .card, body[data-layout="wide"] #top > .card:not(#topYou) { position: absolute; left: calc(36 * var(--u) + (100% - 56 * var(--u)) * .45); right: calc(20 * var(--u)); top: 50%; transform: translateY(-50%); width: auto; max-width: none; max-height: calc(100% - 28 * var(--u)); overflow-y: auto; margin: 0; }
body[data-layout="wide"] #runover .lb, body[data-layout="wide"] #top .lb { font-size: calc(10.5 * var(--u)); }
body[data-layout="wide"] #runover .lb td, body[data-layout="wide"] #top .lb td { padding: calc(3 * var(--u)); }
body[data-layout="wide"] #runover .lb td + td, body[data-layout="wide"] #top .lb td + td { font-size: calc(8 * var(--u)); }
body[data-layout="wide"] .tab { font-size: calc(8 * var(--u)); line-height: 1.5; padding: calc(8 * var(--u)) calc(2 * var(--u)); }
body[data-layout="wide"] #topInfo { font-size: calc(8 * var(--u)) !important; }
body[data-layout="wide"] #topYou { max-width: calc(310 * var(--u)); padding: calc(9 * var(--u)); }
