/* FINAL RUSH skin: the room's arcade (GPT Astra art) over play.css. Stage = 1672x941 = scene size. */
#stage { background: #0b1526; }
#world { position: absolute; left: 0; top: 0; width: 1672px; height: 941px; transform-origin: 0 0; }
#room { position: absolute; inset: 0; background: url(assets/final-rush/scene.webp) 0 0 / 1672px 941px no-repeat; image-rendering: pixelated; }
#stage::before { content: ''; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(90deg, rgba(4, 8, 16, .62) 0%, rgba(4, 8, 16, .2) 30%, transparent 38%, transparent 62%, rgba(4, 8, 16, .2) 70%, rgba(4, 8, 16, .62) 100%); }
#floor { display: none; }
body { position: fixed; inset: 0; overflow: hidden; } /* phones: no layout-viewport zoom-out */
:root { --rainbow: linear-gradient(100deg, #ff453a 0%, #ff9f0a 18%, #ffe900 34%, #64ff00 50%, #00eadb 66%, #008cff 82%, #ff49cf 100%); } /* site rainbow, no violet stop */

/* screen hole measured on the art: x 673-998, y 147-575 (325x428). Canvas 465x660 kept at its ratio. */
#cabinet { left: 673px; top: 147px; width: 325px; height: 428px; background: #001215; filter: none; }
#glassWrap { left: 11px; right: 11px; top: 0; bottom: 0; }
#board { background: #001215; }
#scan { background: repeating-linear-gradient(transparent 0 3px, rgba(0, 0, 0, .22) 3px 4px); }
#glow, #danger { inset: -2px; }

.brand { left: 44px; top: 30px; width: 470px; mix-blend-mode: normal; display: flex; flex-direction: column; align-items: flex-start; gap: 10px; }
.brand img { display: block; image-rendering: pixelated; filter: drop-shadow(0 4px 0 rgba(0, 0, 0, .55)); }
.brand .wc { width: 250px; margin: -12px 0 0 -10px; } /* official site logo (brand kit), 60px transparent margin baked in */
.brand .fr { width: 440px; }
.tag { right: 48px; top: 40px; font-size: 14px; color: #9fb4d8; text-shadow: 0 2px 0 #000; }
/* Pixelify Sans closes the C under ~18 rendered px (SCORE read SOORE on a laptop): small caps labels use Silkscreen, the digits font */
@font-face { font-family: 'WC Caps'; src: url(assets/fonts/silkscreen.ttf) format('truetype'); font-display: block; }
.eyebrow, .sub, .tag, #hint, #coach small, #combo, .ov .score, .ov .best, .ov .keys { font-family: 'WC Caps', 'Pixelify Sans', monospace; font-weight: 400; letter-spacing: .1em; }
.sub b, .ov .score b { font-family: 'WC Digits', 'Pixelify Sans', monospace; }

/* score panel (art 822x204), sits in the clear wall below the photos */
.hud.left { left: 44px; top: 388px; width: 470px; height: 117px; padding: 16px 30px 0; gap: 0;
  background: url(assets/final-rush/score.webp) 0 0 / 100% 100% no-repeat; }
.hud.left .rule { display: none; }
.hud.left .eyebrow { color: #2ee6ff; font-size: 15px; text-shadow: 0 2px 0 #000; }
.hud.left .val { font-size: 60px; margin: 0; text-shadow: 3px 3px 0 #000; }
.hud.left .sub { position: absolute; right: 34px; top: 20px; text-align: right; font-size: 14px; color: #9fb4d8; letter-spacing: .12em; text-shadow: 0 2px 0 #000; }
.hud.left .sub b { display: block; font-size: 30px; color: #fff; letter-spacing: 0; margin-top: 2px; }
#combo { position: absolute; left: auto; right: 0; top: 124px; margin: 0; width: 190px; height: 50px; line-height: 50px; text-align: center; font-size: 18px;
  background: url(assets/final-rush/combo.webp) 0 0 / 100% 100% no-repeat; -webkit-background-clip: border-box; background-clip: border-box; color: #fff; text-shadow: 2px 2px 0 #000; }

/* next panel (art 326x299) */
.hud.right { right: 60px; top: 262px; width: 230px; align-items: center; text-align: center; gap: 4px; }
.hud.right .rule { display: none; }
.hud.right .eyebrow { color: #2ee6ff; font-size: 15px; text-shadow: 0 2px 0 #000; }
#nextBox { width: 200px; height: 184px; border: 0; background: url(assets/final-rush/next.webp) 0 0 / 100% 100% no-repeat; }
#nextBox::before { display: none; }
#nextBox img { width: 108px; height: 108px; }

/* round push buttons */
.icons { right: 56px; bottom: 40px; gap: 14px; }
.icons .cta { width: 72px; min-height: 72px; height: 72px; border: 0; font-size: 0; background: url(assets/final-rush/btn-sound.webp) 0 0 / 100% 100% no-repeat; }
.icons #pauseBtn { background-image: url(assets/final-rush/btn-pause.webp); }
.icons .cta:hover { filter: brightness(1.2); }
.icons .cta:active { transform: translateY(3px); filter: brightness(.85); }
.icons .cta:focus-visible { outline: 2px solid #fff; outline-offset: 3px; border-radius: 50%; }
#hint { left: 44px; bottom: 30px; max-width: 540px; font-size: 14px; line-height: 1.7; color: #b7c6e2; text-shadow: 0 2px 0 #000; }
.touch { display: none; }
@media (pointer: coarse) { .kb { display: none; } .touch { display: inline; } }

/* first-drop coach mark over the glass; final-rush-amb.mjs hides it after the first drop */
#coach { position: absolute; left: 0; right: 0; top: 34%; pointer-events: none; text-align: center; font-size: 26px; font-weight: 400; letter-spacing: .04em; color: #fff; text-shadow: 2px 2px 0 #000, 0 0 14px rgba(var(--neon), .7); animation: coach 1.6s ease-in-out infinite; transition: opacity .3s; }
#coach small { display: block; font-size: 14px; letter-spacing: .14em; color: #9fb4d8; margin-top: 8px; }
#coach.off { opacity: 0; animation: none; }
@keyframes coach { 50% { transform: translateY(-5px); opacity: .75; } }

/* menus: tall cat-notch panel (art 511x851, kept near its ratio) + art keys */
.ov .panel { width: 420px; min-height: 600px; padding: 108px 44px 44px; border: 0; background: url(assets/final-rush/panel.webp) 0 0 / 100% 100% no-repeat; image-rendering: pixelated; }
.ov .eyebrow { color: #2ee6ff; font-size: 13px; letter-spacing: .06em; }
.ov .score { font-size: 14px; }
.ov h1, .ov h2 { margin: 12px 0 18px; }
.ov .score b { font-size: 80px; margin: 8px 0 26px; }
.ov .keys { margin-top: 26px; font-size: 14px; letter-spacing: .06em; color: #9fb4d8; line-height: 1.8; }
.ov .best { font-size: 14px; margin-top: 22px; }
.ov .row { flex-direction: column; }
.ov .row .cta { border: 0; min-height: 62px; justify-content: center; background: url(assets/final-rush/btn-secondary.webp) 0 0 / 100% 100% no-repeat; color: #fff; }
.ov .row .cta.primary { background-image: url(assets/final-rush/btn-primary.webp); color: #0b1526; }
.ov .row .cta.primary .holo { color: #0b1526; }

/* ---------- ambient room (final-rush-amb.mjs) ---------- */
:root { --neon: 46, 230, 255; } /* palette accent, swapped per theme */
#amb { position: absolute; inset: 0; pointer-events: none; z-index: 0; }
#amb .crop { position: absolute; background: url(assets/final-rush/scene-on.webp) 0 0 / 1672px 941px no-repeat; image-rendering: pixelated; opacity: 0; }
#amb .ring.lit { opacity: 1; animation: ringBreath 5.2s steps(1) infinite; }
@keyframes ringBreath { 0%, 61%, 64%, 66%, 100% { opacity: 1; } 62%, 65% { opacity: .45; } 63% { opacity: .8; } }
#amb .ring.flash { animation: ringPop .6s ease-out; opacity: 1; filter: brightness(1.6); }
@keyframes ringPop { 0% { filter: brightness(2.2); } 100% { filter: brightness(1); } }
#amb .ring.click { transition: none; }
#amb .hit { position: absolute; pointer-events: auto; background: none; cursor: pointer; border-radius: 50%; }
#amb .hit:hover { box-shadow: 0 0 0 2px rgba(255, 255, 255, .18); }
#amb .hit:focus-visible { outline: 2px solid #fff; outline-offset: 2px; }
#amb .marquee.on { opacity: 1; }
#amb .city { transition: opacity .6s steps(3); }
#amb .city.on { opacity: 1; }
#amb .pool { position: absolute; left: 520px; top: 820px; width: 640px; height: 140px; border-radius: 50%; mix-blend-mode: screen;
  background: radial-gradient(closest-side, rgba(var(--neon), .32), rgba(var(--neon), 0)); animation: poolBreath 3.4s ease-in-out infinite; }
@keyframes poolBreath { 50% { opacity: .55; } }
#amb .pool.kick { animation: poolKick .5s ease-out, poolBreath 3.4s ease-in-out .5s infinite; }
@keyframes poolKick { 0% { opacity: 1; transform: scale(1.12); filter: brightness(1.8); } 100% { opacity: 1; transform: scale(1); } }
#amb .mote { position: absolute; width: 3px; height: 3px; background: rgba(var(--neon), .8); box-shadow: 0 0 4px rgba(var(--neon), .8); animation: mote linear infinite; opacity: 0; }
#amb .mote.big { width: 4px; height: 4px; }
@keyframes mote { 0% { transform: translate(0, 0); opacity: 0; } 15% { opacity: .9; } 85% { opacity: .6; } 100% { transform: translate(24px, -150px); opacity: 0; } }
#stage > :not(#amb) { z-index: 1; }
#stage::after { content: ''; position: absolute; inset: 0; pointer-events: none; z-index: 2; opacity: 0; transition: opacity .3s;
  box-shadow: inset 0 0 180px 40px rgba(255, 45, 58, .45); }
#stage.alarm::after { opacity: 1; animation: alarm 1.2s ease-in-out infinite; }
#danger.on { animation-duration: 1.2s; } /* glass pulse and room alarm share one beat */
@keyframes alarm { 50% { opacity: .35; } }
#stage.hype #cabinet { animation: hype .35s ease-out; }
@keyframes hype { 30% { filter: drop-shadow(0 0 22px rgba(var(--neon), .9)); } }
@media (prefers-reduced-motion: reduce) { #amb .mote { display: none; } #amb .ring.lit, #amb .pool { animation: none; } }
#amb .crop { -webkit-mask-image: radial-gradient(closest-side, #000 72%, transparent); mask-image: radial-gradient(closest-side, #000 72%, transparent); }
#amb .city { -webkit-mask-image: linear-gradient(#000 85%, transparent); mask-image: linear-gradient(#000 85%, transparent); }

/* palette proposals (lab only, ?theme=sunset|ember|rainbow). Ambient crops exist for the cyan scene; the picked palette gets its own lit scene. */
#stage[data-theme] #amb .crop, #stage[data-theme] #amb .hit { display: none; }
#stage[data-theme=sunset] #room { background-image: url(assets/final-rush/pal-sunset.webp); --neon: 255, 45, 138; }
#stage[data-theme=ember] #room { background-image: url(assets/final-rush/pal-ember.webp); --neon: 255, 163, 26; }
#stage[data-theme=rainbow] #room { background-image: url(assets/final-rush/pal-rainbow.webp); --neon: 255, 255, 255; }
#stage[data-theme] .hud .eyebrow, #stage[data-theme] .ov .eyebrow { color: rgb(var(--neon)); }
.tag i { background: rgb(var(--neon)); box-shadow: 0 0 8px rgb(var(--neon)); }

/* ---------- phone, portrait: play.mjs crops the stage to the cabinet (body[data-focus]); HUD moves onto the cabinet ---------- */
body.portrait .brand, body.portrait .tag, body.portrait #stage::before { display: none; }
body.portrait .hud.left { left: 612px; top: 712px; width: 300px; height: 80px; padding: 10px 20px 0; }
body.portrait .hud.left .eyebrow { font-size: 14px; }
body.portrait .hud.left .val { font-size: 40px; line-height: 1; margin-top: -2px; }
body.portrait .hud.left .sub { right: 22px; top: 11px; font-size: 13px; }
body.portrait .hud.left .sub b { font-size: 22px; margin-top: 0; }
body.portrait #combo { right: auto; left: 0; top: -54px; width: 170px; height: 44px; line-height: 44px; font-size: 16px; }
body.portrait .hud.right { right: auto; left: 924px; top: 694px; width: 134px; gap: 2px; }
body.portrait .hud.right .eyebrow { font-size: 14px; }
body.portrait #nextBox { width: 134px; height: 123px; }
body.portrait #nextBox img { width: 72px; height: 72px; }
body.portrait #hint { left: 0; right: 0; bottom: 8px; max-width: none; text-align: center; font-size: 14px; }
body.portrait .icons { right: auto; left: 612px; bottom: 54px; gap: 12px; }
body.portrait .icons .cta { width: 60px; height: 60px; min-height: 60px; }
body.portrait #coach { font-size: 24px; }

/* ---------- audit fixes (04/11) ---------- */
@keyframes alarm { 0%, 100% { opacity: .35; } 50% { opacity: 1; } } /* same beat and phase as #danger glass pulse */
.ov { visibility: hidden; transition: background .4s, backdrop-filter .4s, visibility 0s .4s; }
.ov.on { visibility: visible; transition: background .4s, backdrop-filter .4s; }
#hint { max-width: 640px; }
.hud.right { top: 330px; }
.brand img { image-rendering: auto; } /* logo + wordmark are downscaled: smooth beats uneven pixels */
@media (prefers-reduced-motion: reduce) { #coach, .tag i, #stage.alarm::after, #stage.hype #cabinet { animation: none; } }
body.portrait #stage::after { box-shadow: none; }
body.portrait #stage.alarm #cabinet { filter: drop-shadow(0 0 24px rgba(255, 45, 58, .85)); }
.ov .row .cta:focus-visible { outline: 2px solid #fff; outline-offset: 4px; border-radius: 10px; }
.ov .row .cta:focus:not(:focus-visible) { outline: none; }

/* ---------- ranked: start + leaderboard (final-rush-ranked.mjs) ---------- */
#startOv .panel { min-height: 640px; }
.ov .lead { font-size: 18px; line-height: 1.45; color: #dce6f8; margin: 0 0 16px; }
.ov .prizes { list-style: none; display: flex; gap: 10px; justify-content: center; margin: 0 0 20px; padding: 0; }
.ov .prizes li { font-family: 'WC Caps', monospace; font-size: 13px; letter-spacing: .08em; color: #9fb4d8; border: 2px solid #2b4a7a; padding: 8px 10px; background: #061226; }
.ov .prizes b { color: #2ee6ff; font-weight: 400; margin-right: 6px; }
.ov .row .cta[hidden] { display: none; }
.ov .ranked-note { margin-top: 14px; font-size: 15px; line-height: 1.5; color: #9fb4d8; min-height: 22px; }
.ov .panel.wide { width: 560px; min-height: 600px; padding: 104px 48px 40px; }
#boardList { list-style: none; margin: 4px 0 18px; padding: 0; max-height: 380px; overflow-y: auto; text-align: left; font-family: 'WC Digits', 'Pixelify Sans', monospace; }
#boardList li { display: grid; grid-template-columns: 46px 1fr 90px 92px; align-items: center; gap: 8px; padding: 7px 10px; font-size: 17px; border-bottom: 1px solid #13233f; }
#boardList li.me { background: rgba(46, 230, 255, .12); outline: 1px solid rgba(46, 230, 255, .5); }
#boardList li.empty { display: block; text-align: center; color: #9fb4d8; border: 0; }
#boardList .rk { color: #9fb4d8; }
#boardList .who { color: #fff; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-family: 'Pixelify Sans', monospace; }
#boardList .sc { text-align: right; color: #fff; }
#boardList .tier { font-family: 'WC Caps', monospace; font-size: 11px; letter-spacing: .08em; text-align: center; padding: 4px 0; color: #9fb4d8; border: 1px solid #2b4a7a; }
#boardList .tier.gtd { color: #061226; background: #2ee6ff; border-color: #2ee6ff; }
#boardList .tier.fcfs { color: #2ee6ff; border-color: #2ee6ff; }
#boardList .tier:empty { border: 0; }
.ov .fine { font-size: 13px; line-height: 1.5; color: #7f93b8; margin: -8px 0 16px; }
.ov .linkish { color: #2ee6ff; text-decoration: underline; font: inherit; }

/* panels keep the art's own proportions (511x851): no more stretched cat notch; the notch carries the OFFICIAL icon */
.ov .panel, .ov .panel.wide { position: relative; aspect-ratio: 511 / 851; min-height: 0; height: auto; }
.ov .panel { width: 420px; padding: 108px 44px 40px; }   /* px, not %: % padding follows the overlay's width */
#startOv .panel { width: 470px; padding: 124px 48px 40px; }
#startOv .row { gap: 10px; }
.ov .panel.wide { width: 500px; padding: 124px 56px 72px; }
.ov .panel::before { content: ''; position: absolute; left: 50%; top: .1%; width: 26.5%; aspect-ratio: 548 / 466; transform: translateX(-50%);
  background: url(assets/final-rush/wc-icon.png) center / contain no-repeat; image-rendering: pixelated; filter: drop-shadow(0 3px 0 #000); }
#boardOv .panel { display: flex; flex-direction: column; } #boardList { flex: 1; max-height: none; } #boardOv .row { margin-top: auto; }

/* ---------- audit 3 (06/11) ---------- */
#board { image-rendering: auto; }
#scan { display: none; }   /* CRT lines now drawn in device pixels inside the canvas */
#stage > #world { z-index: 0; }
#world > #cabinet { z-index: 1; }

/* match camera: the room stays as is on menus; when a run starts the camera moves in on the arcade (Netto 06/11) */
#world { transition: transform .9s cubic-bezier(.22, .9, .25, 1); }
#stage.play #world { transform: translate(-333.7px, 8.5px) scale(1.4); }
.hud, .icons, .brand, .tag, #hint { transition: left .9s cubic-bezier(.22, .9, .25, 1), right .9s cubic-bezier(.22, .9, .25, 1), top .9s cubic-bezier(.22, .9, .25, 1), opacity .4s; }
@media (prefers-reduced-motion: reduce) { #world, .hud, .icons, .brand, .tag, #hint { transition: none; } }

/* HUD regroup + rainbow glow (Fable audit 3; Netto: side menus cluttered, rainbow shadow) */
.hud.left { padding: 18px 50px 0 46px; }
.hud.left .sub { right: 52px; top: 22px; }
.hud.left .val { font-size: 54px; line-height: 1; }
#combo { width: 160px; height: 73px; line-height: 73px; top: 122px; right: 8px; }
.hud.right .eyebrow { position: absolute; left: 0; right: 0; top: 14px; z-index: 2; }
.hud.right { top: 300px; }
#nextBox { margin-top: 0; }
.tag { right: 56px; }
.hud.left, #nextBox, #combo, .icons .cta, .ov .panel, .ov .row .cta { image-rendering: auto; }
.hud.left, #nextBox, .icons .cta { isolation: isolate; }
.hud.left::before, #nextBox::before, .icons .cta::before { content: ''; display: block; position: absolute; inset: 4px; z-index: -1; border-radius: 16px;
  background: linear-gradient(90deg, #ff453a, #ff9f0a, #ffe900, #64ff00, #00eadb, #008cff, #ff2d8a, #ff453a); background-size: 300% 100%;
  filter: blur(16px); opacity: .42; animation: hudGlow 8s linear infinite; pointer-events: none; }
.icons .cta { position: relative; }
.icons .cta::before { inset: 10px; border-radius: 50%; filter: blur(12px); }
@keyframes hudGlow { to { background-position: 300% 0; } }
#stage.hype .hud.left::before, #stage.hype #nextBox::before { opacity: .9; transition: opacity .2s; }
@media (prefers-reduced-motion: reduce) { .hud.left::before, #nextBox::before, .icons .cta::before { animation: none; } }
/* during a run: one column each side, hints off (the pause panel has the keys) */
#stage.play .hud.left { left: 24px; top: 300px; }
#stage.play .hud.right { right: 40px; top: 300px; }
#stage.play .icons { right: 66px; top: 560px; bottom: auto; }
#stage.play #hint { opacity: 0; pointer-events: none; }
#stage.play .tag { opacity: .7; }
/* overlay buttons: label centred, icon pinned right */
.ov .row .cta { position: relative; }
.ov .row .cta .holo { flex: 1; text-align: center; }
.ov .row .cta > span:last-child { position: absolute; right: 30px; top: 50%; transform: translateY(-50%); }
.ov .keys, #frLeft, .ov .lead, .ov .fine { text-wrap: balance; }
.ov .keys { letter-spacing: .04em; }
/* glow only around the cards (their glass is see-through): ring masked out of the middle */
.hud.left::before, #nextBox::before { inset: -16px; padding: 16px; border-radius: 22px;
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0); -webkit-mask-composite: xor;
  mask: linear-gradient(#000 0 0) content-box exclude, linear-gradient(#000 0 0); filter: blur(10px); opacity: .55; }
.hud.right .eyebrow { top: 30px; }
#nextBox img { top: 56%; }
#stage.play .icons { left: 40px; right: auto; top: 440px; }
/* v2 glow: box-shadow is only painted OUTSIDE the box, so the see-through glass stays clean; colours step around (no hue-rotate: it crosses violet) */
.hud.left::before, #nextBox::before, .icons .cta::before { -webkit-mask: none; mask: none; background: none; filter: none; padding: 0;
  inset: 10px; height: auto; top: 10px; bottom: 10px; left: 10px; right: 10px; border-radius: 14px; opacity: .8; animation: hudGlow2 6s steps(1) infinite; }
.icons .cta::before { inset: 14px; top: 14px; bottom: 14px; left: 14px; right: 14px; border-radius: 50%; }
@keyframes hudGlow2 {
  0%   { box-shadow: -16px 0 28px rgba(255, 69, 58, .55), 16px 0 28px rgba(0, 234, 219, .55), 0 -12px 26px rgba(255, 233, 0, .4), 0 12px 26px rgba(255, 45, 138, .45); }
  33%  { box-shadow: -16px 0 28px rgba(255, 159, 10, .55), 16px 0 28px rgba(0, 140, 255, .55), 0 -12px 26px rgba(100, 255, 0, .35), 0 12px 26px rgba(255, 69, 58, .45); }
  66%  { box-shadow: -16px 0 28px rgba(255, 45, 138, .55), 16px 0 28px rgba(255, 233, 0, .5), 0 -12px 26px rgba(0, 234, 219, .4), 0 12px 26px rgba(0, 140, 255, .45); }
}
.hud.left::before, #nextBox::before, .icons .cta::before { transition: box-shadow 2s; }
/* phone portrait: no camera move (the stage is already cropped to the cabinet); keep the portrait HUD */
body.portrait #stage.play #world { transform: none; }
body.portrait #stage.play .hud.left, body.portrait .hud.left { left: 604px; top: 712px; padding: 10px 22px 0; }
body.portrait #stage.play .hud.right, body.portrait .hud.right { right: auto; left: 924px; top: 694px; }
body.portrait #stage.play .icons, body.portrait .icons { left: 612px; right: auto; top: auto; bottom: 54px; }
body.portrait .hud.right .eyebrow { top: 18px; }
body.portrait #combo { right: auto; left: 0; top: -54px; width: 150px; height: 69px; line-height: 69px; }
body.portrait .hud.left .sub { right: 30px; top: 12px; }

/* round 2 (Netto 06/11): official logo on the marquee; during a run the room goes soft (blur) and the HUD appears only then */
#marquee { position: absolute; left: 650px; top: 27px; width: 370px; height: 73px; z-index: 1; display: flex; align-items: center; justify-content: center;
  background: #03080d; box-shadow: inset 0 0 0 3px #000, inset 0 0 18px rgba(46, 230, 255, .35); animation: marquee 4.8s ease-in-out infinite; }
#marquee img { height: 58px; width: auto; display: block; image-rendering: auto; }
@keyframes marquee { 50% { box-shadow: inset 0 0 0 3px #000, inset 0 0 26px rgba(46, 230, 255, .6); } }
#room, #amb { transition: filter .9s ease; }
#stage.play #room, #stage.play #amb { filter: blur(5px) brightness(.72) saturate(.9); }
.hud, .icons { opacity: 0; pointer-events: none; transition: opacity .45s ease .55s, left .9s cubic-bezier(.22, .9, .25, 1), right .9s cubic-bezier(.22, .9, .25, 1), top .9s cubic-bezier(.22, .9, .25, 1); }
#stage.play .hud, #stage.play .icons { opacity: 1; pointer-events: auto; }
#stage:not(.play) #hint { opacity: 0; }
body.portrait #stage.play #room, body.portrait #stage.play #amb { filter: brightness(.8); }
@media (prefers-reduced-motion: reduce) { #marquee { animation: none; } }

/* the arcade itself is part of the room picture: an unblurred crop of it sits over the blurred room (soft sides) */
#cabSharp { position: absolute; left: 590px; top: 0; width: 492px; height: 941px; background: url(assets/final-rush/scene.webp) -590px 0 / 1672px 941px no-repeat;
  image-rendering: pixelated; opacity: 0; transition: opacity .9s ease; z-index: 0;
  -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 22px, #000 calc(100% - 22px), transparent 100%);
  mask-image: linear-gradient(90deg, transparent 0, #000 22px, #000 calc(100% - 22px), transparent 100%); }
#stage.play #cabSharp { opacity: 1; }
#marquee { background: #000; }
#marquee { top: 19px; height: 82px; }
#stage.play .brand .wc { opacity: 0; }
.brand .wc { transition: opacity .5s; }

/* 06/11: the marquee art itself carries the official logo now (Astra scene3), no overlay */
#marquee { display: none; }
/* 06/11: new Astra panel with the official icon in the notch (no overlay) */
.ov .panel, .ov .panel.wide { aspect-ratio: 866 / 1419; }
.ov .panel::before { display: none; }
#startOv .panel { padding-top: 132px; }
.ov .panel.wide { padding-top: 132px; }

/* ================= design pass 09/11 (audit in review/fable52/AUDIT.md) =================
   Same Astra art, no new pictures over it: final-rush-frames.mjs 9-slices the frame art into one bitmap per element,
   so panels and keys take the size of their content instead of one fixed ratio with dead space.
   The border-image rules below are only the fallback until that bitmap is set (.framed). */
#stage .framed { border-image: none !important; }

/* ---- menu panels: height follows the content; notch + corners keep their pixels ---- */
#stage .ov .panel, #stage .ov .panel.wide { --w: 440px; width: var(--w); aspect-ratio: auto; height: auto; min-height: 0; display: block;
  background: none; border: 0 solid transparent;
  border-image: url(assets/final-rush/panel.webp) 260 100 130 100 fill / calc(var(--w) * .3002) calc(var(--w) * .1155) calc(var(--w) * .1501) stretch;
  padding: calc(var(--w) * .305) calc(var(--w) * .15) calc(var(--w) * .16); }
#stage #startOv .panel { --w: 470px; }
#stage .ov .panel.wide { --w: 540px; padding-left: calc(var(--w) * .135); padding-right: calc(var(--w) * .135); }
body.portrait #stage .ov .panel.wide { --w: 472px; }
.ov.on { background: rgba(2, 6, 14, .78); }

/* ---- buttons: 9-sliced keys, caps labels, one clear state each ---- */
#stage .ov .row { gap: 10px; }
#stage .ov .row + .row { margin-top: 10px; }
#stage .ov .row.two { flex-direction: row; }
#stage .ov .row .cta { min-height: 60px; padding: 0 22px; background: none; border: 0 solid transparent; color: #fff;
  border-image: url(assets/final-rush/btn-secondary.webp) 30 44 30 44 fill / 18px 26px stretch; transition: filter .12s, transform .08s; }
#stage .ov .row .cta.primary { min-height: 62px; color: #06121f; border-image: url(assets/final-rush/btn-primary.webp) 30 44 30 96 fill / 18px 26px 18px 57px stretch; }
#stage .ov .row .cta .holo { font-size: 17px; letter-spacing: .09em; text-transform: uppercase; background-image: none; -webkit-background-clip: border-box; background-clip: border-box; color: inherit; text-shadow: none; }
#stage .ov .row.two .cta { padding: 0 8px; } #stage .ov .row.two .cta .holo { font-size: 15px; letter-spacing: .07em; }
#stage .ov .row .cta > .holo:last-child { position: static; transform: none; }
#stage .ov .row .cta:hover { filter: brightness(1.22); }
#stage .ov .row .cta:active { transform: translateY(2px); filter: brightness(.9); }
#stage .ov .row .cta:disabled { filter: saturate(.4) brightness(.7); cursor: default; }
/* keyboard focus = arcade select cursor (the white rounded box read as a glitch) */
#stage .ov .row .cta:focus-visible { outline: 0; border-radius: 0; }
#stage .ov .row .cta:focus-visible::before { content: ''; position: absolute; left: -22px; top: 50%; margin-top: -9px; border: 9px solid transparent; border-left: 13px solid #2ee6ff; border-right: 0;
  filter: drop-shadow(0 0 6px rgba(46, 230, 255, .8)); animation: selCursor .9s steps(1) infinite; }
@keyframes selCursor { 50% { opacity: .25; } }

/* ---- type scale inside panels ---- */
.ov .eyebrow { font-size: 12.5px; letter-spacing: .08em; white-space: nowrap; }
.ov h1, .ov h2 { font-size: 44px; margin: 10px 0 16px; letter-spacing: 0; }
.ov h1 { text-shadow: -2px 0 #00cfff, 2px 0 #ff414b, 0 4px 0 #000; }
.ov h2.title { margin: 8px 0 14px; } .ov h2.title img { display: block; width: 88%; margin: 0 auto 0 4%; }
.ov .lead { font-size: 17px; margin: 0 0 16px; }
.ov .keys { margin-top: 18px; font-size: 13px; color: #b7c6e2; }
.ov .fine { margin: 10px 0 0; font-size: 12.5px; color: #6f84ab; }
.ov .score b { font-size: 84px; margin: 6px 0 8px; text-shadow: 0 5px 0 #000; }
.ov .best { margin: 0 0 16px; font-size: 14px; min-height: 16px; }

/* ---- start: prize cards with the trophy / medal art ---- */
.ov .prizes { gap: 8px; margin: 0 0 18px; }
.ov .prizes li { flex: 1; display: flex; align-items: center; gap: 8px; padding: 8px 8px 8px 6px; text-align: left; border: 2px solid #1f3a66; background: #040e1e; font-size: 11px; letter-spacing: .1em; color: #2ee6ff; line-height: 1.2; }
.ov .prizes img { width: 38px; height: 38px; object-fit: contain; flex: none; }
.ov .prizes b { display: block; margin: 0 0 3px; font-family: 'WC Digits', 'WC Caps', monospace; font-size: 17px; letter-spacing: 0; color: #fff; white-space: nowrap; }
#startOv.offline .prizes, #startOv.offline .fine { display: none; }

/* ---- game over: the run in three numbers ---- */
.ov .stats { list-style: none; display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; margin: 0 0 18px; padding: 0; }
.ov .stats li { display: flex; flex-direction: column; align-items: center; justify-content: flex-end; gap: 6px; height: 74px; padding: 0 2px 9px; border: 2px solid #1f3a66; background: #040e1e;
  font-family: 'WC Caps', monospace; font-size: 10px; letter-spacing: .08em; color: #9fb4d8; white-space: nowrap; }
.ov .stats b { font-family: 'WC Digits', 'WC Caps', monospace; font-size: 26px; font-weight: 400; color: #fff; line-height: 1; }
.ov .stats img { width: 44px; height: 44px; margin-bottom: -4px; }
.ov .ranked-note { margin-top: 14px; font-size: 14px; min-height: 0; text-wrap: balance; }
.ov .ranked-note:empty { display: none; }

/* ---- leaderboard: a real high-score table ---- */
.board-head, #boardList li { display: grid; grid-template-columns: 40px 1fr 76px 92px; align-items: center; gap: 8px; padding: 0 10px; }
.board-head { margin-top: 6px; padding-bottom: 8px; border-bottom: 2px solid #1f3a66; font-family: 'WC Caps', monospace; font-size: 11px; letter-spacing: .12em; color: #6f84ab; text-align: left; }
.board-head span:nth-child(3) { text-align: right; } .board-head span:nth-child(4) { text-align: center; }
#stage #boardList { position: relative; flex: none; margin: 0; max-height: 336px; overflow-y: auto; scrollbar-width: thin; scrollbar-color: #2b4a7a transparent; }
#boardList li { height: 42px; font-size: 17px; border-bottom: 1px solid #10203a; }
#boardList li.top .who { color: #fff; } #boardList li:not(.top) .who { color: #dce6f8; }
#boardList .rk img { display: block; width: 30px; height: 30px; margin-left: -6px; }
#boardList li.me { background: rgba(46, 230, 255, .14); outline: 0; box-shadow: inset 3px 0 0 #2ee6ff; }
#boardList li.open .rk, #boardList li.open .sc { color: #3d5683; }
#boardList li.open .who { font-family: 'WC Caps', monospace; font-size: 11px; letter-spacing: .12em; color: #3d5683; }
#boardList li:not(.open) + li.open .who, #boardList li.open:first-child .who { color: #7f93b8; }
#boardList .tier { font-size: 11px; padding: 5px 0 4px; }
#boardList .tier.wait { font-size: 9px; color: #ffe900; border-color: #6b6400; }
.board-me { margin: 12px 0 14px; min-height: 14px; font-family: 'WC Caps', monospace; font-size: 12px; letter-spacing: .1em; color: #2ee6ff; text-wrap: balance; }

/* ---- in play: mode chip, NEXT and the merge chain share the right column ---- */
.tag { padding: 9px 14px 8px; background: rgba(3, 10, 22, .84); border: 2px solid #2b4a7a; color: #dce6f8; font-size: 14px; }
#stage.play .tag { right: 40px; top: 246px; opacity: 1; }
#stage.play .hud.right { right: 40px; width: 200px; }
.hud.chain { right: 40px; top: 512px; width: 424px; gap: 10px; padding: 30px 26px 20px; align-items: stretch; text-align: center;
  border: 0 solid transparent; border-image: url(assets/final-rush/score.webp) 70 70 60 70 fill / 40px 40px 34px 40px stretch; }
.hud.chain .eyebrow { color: #2ee6ff; font-size: 13px; text-shadow: 0 2px 0 #000; }
#ladder { list-style: none; display: flex; flex-wrap: wrap; justify-content: center; gap: 6px 0; margin: 0; padding: 0; }
#ladder li { position: relative; width: 16.66%; height: 54px; display: flex; align-items: center; justify-content: center; }
#ladder img { width: 54px; height: 54px; opacity: .3; filter: grayscale(1); transition: opacity .3s, filter .3s, transform .3s cubic-bezier(.2, 1.6, .4, 1); }
#ladder li.lit img { opacity: 1; filter: none; }
#ladder li.now img { transform: scale(1.22); filter: drop-shadow(0 0 8px rgba(46, 230, 255, .9)); }
#ladder li:not(:last-child)::after { content: ''; position: absolute; right: -5px; top: 50%; width: 5px; height: 5px; margin-top: -3px; border-top: 2px solid #2b4a7a; border-right: 2px solid #2b4a7a; transform: rotate(45deg); }
#ladder li:nth-child(6)::after { display: none; }
@media (prefers-reduced-motion: reduce) { #ladder img { transition: none; } #stage .ov .row .cta:focus-visible::before { animation: none; } }
/* phone: one thin row on the cabinet base, right of the round buttons */
body.portrait .hud.chain { left: 752px; right: auto; top: 826px; width: 308px; padding: 13px 12px 8px; }
body.portrait .hud.chain .eyebrow { display: none; }
body.portrait #ladder { flex-wrap: nowrap; gap: 0; }
body.portrait #ladder li { width: 9.09%; height: 30px; }
body.portrait #ladder img { width: 26px; height: 26px; } body.portrait #ladder li::after { display: none; }

/* ---- small-screen legibility + phone fixes ---- */
.ov .score { font-size: 15px; letter-spacing: .14em; }
.ov .stats li { font-size: 11px; height: 78px; }
.board-head, #boardList li { grid-template-columns: 38px 1fr 66px 84px; gap: 6px; padding: 0 6px; }
#boardList .who { font-size: 16px; }
body.portrait #stage.play .hud.right, body.portrait .hud.right { width: 134px; }
@media (pointer: coarse) { #stage .ov .row .cta:focus-visible::before { display: none; } }

/* ---- human check (Cloudflare Turnstile) sits between the buttons and the status line, only while it runs ---- */
#tsBox { margin: 14px auto 0; min-height: 65px; display: flex; justify-content: center; }
#tsBox[hidden] { display: none; }

/* 13/11 (Netto): at 1.4x the joystick and the lower buttons were cut by the bottom edge. 1.35x and a little higher:
   the whole arcade front (marquee to the control deck, scene y 12-695) fits the 941 px stage. Phone keeps no camera move. */
#stage.play #world { transform: translate(-291.9px, -12px) scale(1.35); }
body.portrait #stage.play #world { transform: none; }

/* ---- leaderboard: X profile photo before the @ (Netto 13/11) ---- */
#boardList li:not(.open) .who { display: flex; align-items: center; gap: 8px; min-width: 0; }
#boardList .who span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
#boardList .av { flex: none; width: 28px; height: 28px; object-fit: cover; background: #040e1e; border: 2px solid #2b4a7a; image-rendering: auto; }
#boardList li.top .av { border-color: #2ee6ff; }
#boardList .av.none { object-fit: contain; padding: 2px; }

/* ---- prize tiers from the server (2 or 3 cards), FREE MINT chip, review notice on the board ---- */
.ov .prizes.three { gap: 6px; }
.ov .prizes.three li { flex-direction: column; text-align: center; gap: 4px; padding: 8px 2px 7px; font-size: 10px; letter-spacing: .06em; }
.ov .prizes.three img { width: 34px; height: 34px; }
.ov .prizes.three b { font-size: 15px; margin-bottom: 2px; }
#boardList .tier.free { color: #06121f; background: #ffe900; border-color: #ffe900; font-size: 9px; }
.ov .board-note { margin: -4px 0 14px; color: #9fb4d8; }

/* ================= highlights (Netto 13/11): the site's shine + rare RGB jolt, in pixel steps =================
   Same family as room-v2/hype.css (stepped light band, cyan/pink split for a few frames), kept quiet: no rainbow rim,
   nothing loops fast. Only on what should catch the eye: the FINAL RUSH title, the main key, the Leaderboard keys,
   the prize cards and the spot chips of the board. Off with prefers-reduced-motion. */
@keyframes frJoltImg {   /* pictures: split with drop-shadows */
  0%, 89%, 100% { translate: 0 0; }
  90% { translate: -3px 0; filter: drop-shadow(-3px 0 #00eadb) drop-shadow(3px 0 #ff49cf); }
  91% { translate: 3px 0; filter: drop-shadow(3px 0 #00eadb) drop-shadow(-3px 0 #ff49cf); }
  92% { translate: -1px 0; filter: drop-shadow(-1px 0 #00eadb) drop-shadow(1px 0 #ff49cf); }
  93% { translate: 0 0; }
}
@keyframes frJoltText {  /* text: split with text-shadows */
  0%, 89%, 100% { translate: 0 0; }
  90% { translate: -2px 0; text-shadow: -2px 0 #00eadb, 2px 0 #ff49cf; }
  91% { translate: 2px 0; text-shadow: 2px 0 #00eadb, -2px 0 #ff49cf; }
  92% { translate: -1px 0; text-shadow: -1px 0 #00eadb, 1px 0 #ff49cf; }
  93% { translate: 0 0; }
}
@keyframes frShine { 0%, 58% { background-position: -170% 0; } 100% { background-position: 270% 0; } }
@keyframes frTwinkle { 0%, 84%, 100% { filter: none; } 86% { filter: brightness(1.7); } 88% { filter: none; } 90% { filter: brightness(1.4); } 92% { filter: none; } }
@keyframes frFreeGlow { 0%, 100% { box-shadow: 0 0 0 0 rgba(255, 233, 0, 0); } 50% { box-shadow: 0 0 10px 1px rgba(255, 233, 0, .7); } }

/* the title: wordmark in the start panel and in the room, text titles of the other panels */
.ov.on h2.title img { animation: frJoltImg 7s steps(1) infinite; }
.brand .fr { animation: frJoltImg 9s steps(1) 2.5s infinite; }
.ov.on h1, .ov.on h2:not(.title) { animation: frJoltText 8s steps(1) 1s infinite; }

/* the main key: a stepped light band crossing it now and then */
#stage .ov .row .cta.primary::after, .ov .prizes li::after, #boardList .tier.free::after, #boardList .tier.gtd::after, #boardList .tier.fcfs::after {
  content: ''; position: absolute; pointer-events: none;
  background: linear-gradient(105deg, transparent 0 43%, rgba(255, 255, 255, .8) 43% 47%, transparent 47% 49.5%, rgba(255, 255, 255, .4) 49.5% 51.5%, transparent 51.5%) -170% 0 / 260% 100% no-repeat;
  animation: frShine 4.8s steps(14) infinite; }
#stage .ov .row .cta.primary::after { inset: 7px 10px; }
/* Leaderboard keys: the label jolts once in a while */
#boardBtn .holo, #overBoardBtn .holo { display: inline-block; animation: frJoltText 6.5s steps(1) 3s infinite; }

/* prize cards: band + the trophy / medals twinkle, one after the other */
.ov .prizes li { position: relative; overflow: hidden; }
.ov .prizes li::after { inset: 0; opacity: .5; animation-duration: 6s; }
.ov .prizes li:nth-child(2)::after { animation-delay: .5s; } .ov .prizes li:nth-child(3)::after { animation-delay: 1s; }
.ov .prizes img { animation: frTwinkle 5s steps(1) infinite; }
.ov .prizes li:nth-child(2) img { animation-delay: .7s; } .ov .prizes li:nth-child(3) img { animation-delay: 1.4s; }

/* the board: spot chips shine row after row; FREE MINT also breathes; top-3 medals twinkle */
#boardList .tier.free, #boardList .tier.gtd, #boardList .tier.fcfs { position: relative; overflow: hidden; }
#boardList .tier.free::after, #boardList .tier.gtd::after, #boardList .tier.fcfs::after { inset: 0; animation-duration: 5.4s; }
#boardList .tier.fcfs::after { opacity: .55; }
#boardList li:nth-child(4n+2) .tier::after { animation-delay: .35s; } #boardList li:nth-child(4n+3) .tier::after { animation-delay: .7s; } #boardList li:nth-child(4n) .tier::after { animation-delay: 1.05s; }
#boardList .tier.free { animation: frFreeGlow 2.4s steps(6) infinite; }
#boardList .rk img { animation: frTwinkle 6s steps(1) infinite; }
#boardList li:nth-child(2) .rk img { animation-delay: .8s; } #boardList li:nth-child(3) .rk img { animation-delay: 1.6s; }
.ov .best.new { animation: frJoltText 5s steps(1) infinite; }

@media (prefers-reduced-motion: reduce) {
  .ov.on h2.title img, .brand .fr, .ov.on h1, .ov.on h2:not(.title), #boardBtn .holo, #overBoardBtn .holo, .ov .prizes img, #boardList .tier.free, #boardList .rk img, .ov .best.new { animation: none; }
  #stage .ov .row .cta.primary::after, .ov .prizes li::after, #boardList .tier::after { display: none; }
}

/* ---- the arcade is alive (final-rush-amb.mjs #cabFx): marquee light failing, LED trim blinking, control deck jolting ---- */
#cabFx { position: absolute; inset: 0; pointer-events: none; z-index: 0; }
#cabFx .fx { position: absolute; opacity: 0; background-size: 1672px 941px; background-repeat: no-repeat; image-rendering: pixelated; }
#cabFx .marquee { filter: brightness(.22) saturate(.5); }
#cabFx .marquee.fail { animation: fxFail .55s steps(1); }
#cabFx .marquee.fail.long { animation: fxFailLong .9s steps(1); }
@keyframes fxFail { 0% { opacity: 1; } 14% { opacity: 0; } 26% { opacity: .85; } 44% { opacity: 0; } 100% { opacity: 0; } }
@keyframes fxFailLong { 0% { opacity: 1; } 9% { opacity: 0; } 16% { opacity: .9; } 24% { opacity: .3; } 30% { opacity: 1; } 62% { opacity: 0; } 70% { opacity: .7; } 76% { opacity: 0; } 100% { opacity: 0; } }
#cabFx .led.blink { animation: fxLed .7s steps(1); }
@keyframes fxLed { 0% { opacity: .9; } 12% { opacity: 0; } 22% { opacity: .75; } 34% { opacity: 0; } 58% { opacity: .5; } 66% { opacity: 0; } 100% { opacity: 0; } }
#cabFx .deck.jolt { animation: fxJolt .42s steps(1); }
@keyframes fxJolt {
  0% { opacity: 1; translate: -3px 0; filter: drop-shadow(-3px 0 #00eadb) drop-shadow(3px 0 #ff49cf) brightness(1.25); }
  25% { opacity: 1; translate: 3px 0; filter: drop-shadow(3px 0 #00eadb) drop-shadow(-3px 0 #ff49cf) brightness(1.25); }
  50% { opacity: 1; translate: -1px 0; filter: drop-shadow(-1px 0 #00eadb) drop-shadow(1px 0 #ff49cf); }
  75% { opacity: 1; translate: 0 0; filter: brightness(1.2); }
  100% { opacity: 0; }
}
#cabFx .deck.wink { animation: fxWink .2s steps(1); }
@keyframes fxWink { 0% { opacity: 1; filter: brightness(1.45) saturate(1.2); } 60% { opacity: 1; filter: brightness(1.15); } 100% { opacity: 0; } }
@media (prefers-reduced-motion: reduce) { #cabFx { display: none; } }

/* the top of the joystick ball, pasted back over the game glass (final-rush-amb.mjs #joyTop) */
#joyTop { position: absolute; z-index: 2; pointer-events: none; image-rendering: pixelated; }

/* ================= HUD type on one grid (Netto 13/11: the texts looked thrown in) =================
   Score card: labels on one line, values on one baseline, everything clear of the rivets (the frame is 9-sliced now, so the
   card can be a little taller). Right column: mode chip, NEXT and MERGE CHAIN share one right edge; the chip is the NEXT
   box's header (same width); labels sit inside their frames with even padding. */
#stage .hud.left { display: grid; grid-template: "sl bl" auto "sv bv" 1fr / 1fr auto; justify-items: end; align-items: baseline; column-gap: 24px; row-gap: 4px;
  width: 470px; height: 138px; padding: 36px 56px 28px 54px; background: none; }
#stage .hud.left .eyebrow { grid-area: sl; justify-self: start; font-size: 13px; letter-spacing: .16em; line-height: 1; color: #2ee6ff; }
#stage .hud.left .val { grid-area: sv; justify-self: start; font-size: 50px; line-height: 1; margin: 0; }
#stage .hud.left .sub { display: contents; font-size: 13px; letter-spacing: .16em; line-height: 1; color: #9fb4d8; text-shadow: 0 2px 0 #000; }
#stage .hud.left .sub b { grid-area: bv; display: block; margin: 0; font-size: 30px; line-height: 1; letter-spacing: 0; color: #dce6f8; text-shadow: 2px 2px 0 #000; }
#stage #combo { top: 150px; right: 0; }
#stage.play .icons { top: 458px; left: 34px; }

/* right column */
#stage.play .tag { right: 40px; top: 252px; width: 216px; padding: 10px 0 9px; text-align: center; font-size: 13px; letter-spacing: .16em; }
#stage.play .hud.right { right: 40px; top: 300px; width: 216px; }
#stage #nextBox { width: 216px; height: 198px; }
#stage .hud.right .eyebrow { top: 46px; font-size: 13px; letter-spacing: .16em; line-height: 1; padding-left: .16em; }
#stage #nextBox img { width: 92px; height: 92px; top: 57%; }
#stage .hud.chain { right: 40px; top: 516px; width: 424px; gap: 14px; padding: 42px 40px 32px; }
#stage .hud.chain .eyebrow { font-size: 13px; letter-spacing: .16em; line-height: 1; padding-left: .16em; }
#stage #ladder { gap: 8px 0; }
#stage #ladder li { height: 48px; }
#stage #ladder img { width: 48px; height: 48px; }
#stage #ladder li.now img { transform: scale(1.14); }

/* phone: same grid, smaller */
body.portrait #stage .hud.left, body.portrait #stage.play .hud.left { left: 604px; top: 700px; width: 304px; height: 96px; padding: 25px 36px 18px 34px; column-gap: 12px; row-gap: 3px; }
body.portrait #stage .hud.left .eyebrow, body.portrait #stage .hud.left .sub { font-size: 12px; letter-spacing: .12em; }
body.portrait #stage .hud.left .val { font-size: 34px; }
body.portrait #stage .hud.left .sub b { font-size: 22px; }
body.portrait #stage #combo { top: -62px; left: 0; right: auto; }
body.portrait #stage .hud.right, body.portrait #stage.play .hud.right { left: 922px; right: auto; top: 690px; width: 138px; }
body.portrait #stage #nextBox { width: 138px; height: 126px; }
body.portrait #stage .hud.right .eyebrow { top: 27px; font-size: 12px; letter-spacing: .12em; }
body.portrait #stage #nextBox img { width: 60px; height: 60px; top: 60%; }
body.portrait #stage .hud.chain { left: 752px; right: auto; top: 826px; width: 308px; padding: 13px 12px 8px; gap: 0; }
body.portrait #stage #ladder { gap: 0; }
body.portrait #stage #ladder li { height: 30px; }
body.portrait #stage #ladder img { width: 26px; height: 26px; }
body.portrait #stage.play .icons, body.portrait #stage .icons { left: 612px; right: auto; top: auto; bottom: 54px; }
body.portrait #stage .hud.left, body.portrait #stage.play .hud.left { padding: 25px 46px 18px 46px; column-gap: 8px; }
body.portrait #stage .hud.left .val { font-size: 32px; }
body.portrait #stage .hud.left .sub b { font-size: 20px; }

/* during a run the top of the joystick ball goes translucent, so the cats under it stay readable (Netto 13/11) */
#joyTop { transition: opacity .5s ease; }
#stage.play #joyTop { opacity: .45; }

/* ---- lock screen (the game is on the site but not open yet) ---- */
#lockOv .lock-art { display: block; width: 104px; margin: 4px auto 14px; image-rendering: pixelated; animation: frTwinkle 4s steps(1) infinite; }
#lockOv .lead { margin-bottom: 18px; }
#lockOv a.cta { text-decoration: none; }
#lockOv .keys { color: #2ee6ff; }
@media (prefers-reduced-motion: reduce) { #lockOv .lock-art { animation: none; } }

/* phones: the page never zooms or selects (iPhone double tap zoomed the game and hid the HUD); the leaderboard list still scrolls */
html, body, #stage, #stage * { touch-action: none; -webkit-touch-callout: none; -webkit-user-select: none; user-select: none; -webkit-tap-highlight-color: transparent; }
#stage button, #stage a { touch-action: manipulation; }
#stage #boardList, #stage #boardList * { touch-action: pan-y; }
html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; overscroll-behavior: none; }

/* ---- first-run hint + "?" card (Netto 13/11) ---- */
#coach { top: 30%; font-size: 30px; letter-spacing: .06em; }
#coach small { font-size: 15px; margin-top: 10px; color: #2ee6ff; }
#coach .coach-arrow { display: block; width: 0; height: 0; margin: 0 auto 14px; border: 14px solid transparent; border-top: 18px solid #fff; border-bottom: 0;
  filter: drop-shadow(3px 3px 0 #000) drop-shadow(0 0 10px rgba(46, 230, 255, .8)); animation: coachTap 1s steps(2) infinite; }
@keyframes coachTap { 50% { transform: translateY(10px); opacity: .5; } }
body.portrait #coach { font-size: 26px; }

/* the "?" key: a plain pixel key (text on the game's dark plate), next to sound and pause */
.icons #helpBtn { width: 52px; height: 52px; align-self: center; margin-left: 4px; font-family: 'WC Caps', monospace; font-size: 24px; line-height: 1; color: #2ee6ff;
  background: #030a16; border: 3px solid #2ee6ff; box-shadow: 0 0 0 3px #000, 0 4px 0 3px #0a5f73; cursor: pointer; }
.icons #helpBtn:hover { filter: brightness(1.25); }
.icons #helpBtn:active { transform: translateY(3px); }
.icons #helpBtn:focus-visible { outline: 2px solid #fff; outline-offset: 5px; }
body.portrait .icons #helpBtn { width: 44px; height: 44px; font-size: 20px; }
/* phone: three keys now sit left of the chain strip, which starts a little further right */
body.portrait #stage .hud.chain { left: 808px; width: 252px; padding: 13px 8px 8px; }
body.portrait #stage #ladder img { width: 21px; height: 21px; }
body.portrait #stage.play .icons, body.portrait #stage .icons { gap: 8px; }

/* the card */
#stage .ov#helpOv .panel { --w: 470px; }
.ov .steps { list-style: none; margin: 4px 0 18px; padding: 0; display: grid; gap: 10px; text-align: left; }
.ov .steps li { display: grid; grid-template-columns: 132px 1fr; align-items: center; gap: 12px; padding: 10px 12px; border: 2px solid #1f3a66; background: #040e1e; font-size: 14px; line-height: 1.4; color: #dce6f8; }
.ov .steps b { display: block; margin-bottom: 4px; font-family: 'WC Caps', monospace; font-weight: 400; font-size: 13px; letter-spacing: .12em; color: #2ee6ff; }
.ov .steps .step-art { display: flex; align-items: center; justify-content: center; gap: 2px; height: 56px; position: relative; }
.ov .steps .step-art img { width: 40px; height: 40px; }
.ov .steps .step-art em { font-style: normal; font-family: 'WC Caps', monospace; font-size: 14px; color: #9fb4d8; }
.ov .steps .step-art .step-drop { position: absolute; left: 50%; top: 0; width: 0; height: 0; margin-left: -6px; border: 6px solid transparent; border-top: 8px solid #fff; border-bottom: 0; animation: coachTap 1s steps(2) infinite; }
.ov .steps li:first-child .step-art img { margin-top: 14px; width: 44px; height: 44px; }
.ov .steps .chainlet img:nth-child(1) { width: 30px; height: 30px; } .ov .steps .chainlet img:nth-child(2) { width: 40px; height: 40px; } .ov .steps .chainlet img:nth-child(3) { width: 52px; height: 52px; }
.ov .linkish.how { display: block; margin: 14px auto 0; background: none; border: 0; cursor: pointer; font-family: 'WC Caps', monospace; font-size: 12px; letter-spacing: .12em; text-decoration: none; color: #2ee6ff; }
.ov .linkish.how:hover { color: #fff; }
@media (prefers-reduced-motion: reduce) { #coach .coach-arrow, .ov .steps .step-drop { animation: none; } }

/* ---- game over: push the share (Netto 13/11). SHARE ON X = the main call, a running rainbow rim (site rainbow, no violet) and a
   pulse; SAVE CARD = a yellow rim that blinks, so the two read as different actions. ---- */
#overOv #shareXBtn::after, #overOv #saveCardBtn::after { content: ''; position: absolute; inset: -5px; padding: 4px; pointer-events: none; z-index: 2;
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0); -webkit-mask-composite: xor;
          mask: linear-gradient(#000 0 0) content-box exclude, linear-gradient(#000 0 0); }
#overOv #shareXBtn::after { background: linear-gradient(90deg, #ff453a, #ff9f0a, #ffe900, #64ff00, #00eadb, #008cff, #ff49cf, #ff453a) 0 0 / 200% 100%;
  filter: drop-shadow(0 0 6px rgba(255, 73, 207, .7)) drop-shadow(0 0 9px rgba(0, 234, 219, .6)); animation: frRim 1.5s linear infinite; }
#overOv.on #shareXBtn { animation: frPulse 1.2s steps(2) infinite; }
#overOv #shareXBtn .holo { animation: frJoltText 3.2s steps(1) infinite; }
#overOv #saveCardBtn::after { background: #ffe900; filter: drop-shadow(0 0 7px rgba(255, 233, 0, .75)); animation: frBlinkRim 1.1s steps(1) infinite; }
#overOv #saveCardBtn .holo { color: #ffe900; }
@keyframes frRim { to { background-position: 200% 0; } }
@keyframes frPulse { 50% { transform: scale(1.045); } }
@keyframes frBlinkRim { 0%, 100% { opacity: 1; } 50% { opacity: .25; } }
#stage #overOv .row.two { gap: 18px; margin-top: 16px; }
@media (prefers-reduced-motion: reduce) { #overOv #shareXBtn::after, #overOv #saveCardBtn::after, #overOv.on #shareXBtn, #overOv #shareXBtn .holo { animation: none; } }

/* the "?" key is a round key like sound and pause: the same ring art with a pixel "?" (btn-help.webp), same size and spacing */
.icons #helpBtn, body.portrait .icons #helpBtn { width: 72px; height: 72px; min-height: 72px; margin: 0; padding: 0; align-self: auto; border: 0; box-shadow: none; font-size: 0; color: transparent;
  background: url(assets/final-rush/btn-help.webp) 0 0 / 100% 100% no-repeat; }
.icons #helpBtn:focus-visible { outline: 2px solid #fff; outline-offset: 3px; border-radius: 50%; }
body.portrait .icons #helpBtn { width: 60px; height: 60px; min-height: 60px; }
body.portrait #stage .hud.chain { left: 816px; width: 244px; }
body.portrait #stage #ladder img { width: 20px; height: 20px; }

/* ---- "5 ranked runs a day" said clearly (Netto 13/11): the rule line and the player's own counter ---- */
.ov .rule5 { margin: -4px 0 16px; padding: 8px 10px 7px; border: 2px solid #ffe900; background: rgba(255, 233, 0, .08); font-family: 'WC Caps', monospace; font-size: 12px; letter-spacing: .08em; line-height: 1.5; color: #ffe900; text-wrap: balance; }
.ov .rule5 b { font-family: 'WC Digits', 'WC Caps', monospace; font-weight: 400; font-size: 15px; }
.ov .rule5[hidden] { display: none; }
.ov .rule5.in-help { margin: 0 0 16px; font-size: 11px; }
#startOv.offline .rule5 { display: none; }
.ov .keys.counter, .ov .runs-left { margin-top: 16px; font-family: 'WC Caps', monospace; font-size: 13px; letter-spacing: .08em; line-height: 1.6; color: #dce6f8; text-wrap: balance; }
.ov .keys.counter b, .ov .runs-left b { font-family: 'WC Digits', 'WC Caps', monospace; font-weight: 400; font-size: 18px; color: #2ee6ff; }
.ov .keys.counter.none-left b, .ov .runs-left.none-left b { color: #ff453a; }
.ov .runs-left { margin-top: 14px; } .ov .runs-left:empty { display: none; }

/* the runs counter, big (Netto 13/11: he had not noticed the 5/5): a plate with a running rainbow edge, the number in the
   logo's rainbow (site colours, no violet), readable on a phone */
#stage .ov .counter { position: relative; display: grid; justify-items: center; gap: 2px; margin: 18px 0 0; padding: 12px 10px 10px; background: #040e1e; letter-spacing: .1em; line-height: 1.3; color: #dce6f8; }
#stage .ov .counter::before { content: ''; position: absolute; inset: 0; padding: 3px; pointer-events: none;
  background: linear-gradient(90deg, #ff453a, #ff9f0a, #ffe900, #64ff00, #00eadb, #008cff, #ff49cf, #ff453a) 0 0 / 200% 100%; animation: frRim 3s linear infinite;
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0); -webkit-mask-composite: xor; mask: linear-gradient(#000 0 0) content-box exclude, linear-gradient(#000 0 0); }
#stage .ov .counter .cl { font-size: 12px; color: #9fb4d8; }
#stage .ov .counter .cn { font-family: 'WC Digits', 'WC Caps', monospace; font-weight: 400; font-size: 54px; line-height: 1; letter-spacing: .02em; margin: 4px 0 2px;
  background: linear-gradient(90deg, #ff453a, #ff9f0a, #ffe900, #64ff00, #00eadb, #008cff, #ff49cf, #ff453a) 0 0 / 200% 100%; -webkit-background-clip: text; background-clip: text; color: transparent;
  filter: drop-shadow(0 4px 0 #000); animation: frRim 3s linear infinite; }
#stage .ov .counter .cs { font-size: 11px; color: #9fb4d8; }
#stage .ov .counter.none-left .cn { background: none; -webkit-background-clip: border-box; background-clip: border-box; color: #ff453a; animation: none; }
#stage .ov .counter.none-left::before { background: #ff453a; animation: none; }
#stage #overOv .counter { margin-top: 14px; padding: 9px 10px 8px; } #stage #overOv .counter .cn { font-size: 40px; }
@media (prefers-reduced-motion: reduce) { #stage .ov .counter::before, #stage .ov .counter .cn { animation: none; } }

/* frames are canvases behind the content (final-rush-frames.mjs): the element is its own layer, the canvas fills it at z -1 */
#stage .framed { isolation: isolate; }
#stage .framed > canvas.frame-bg { position: absolute; left: 0; top: 0; width: 100%; height: 100%; z-index: -1; pointer-events: none; image-rendering: auto; display: block; }
/* if the frame could not be drawn at all, the filled key still reads: a plain cyan plate under dark text */
#stage .ov .row .cta.primary:not(.framed) { background: #2ee6ff; border-image: none; }
