/* ═══════════════════════════════════════════════
   You're Gonna Be Famous — the tape page (index.html)

   One TV fills the screen. The game's real battle backgrounds play behind
   the picture window (assets/js/tape.js) with the loading screen's tape
   faults over them, and every part of the game is a channel shown INSIDE
   the picture. The striped panel under the picture is the deck: channel
   up/down, tracking minus/plus, the wishlist REC button.

   Geometry comes from ygbf.js: it fits the 960x540 bezel to the viewport
   (contain on desktop, cover-by-height on phones) and writes the pixel
   rects of the canvas, bezel, picture window and deck as inline styles,
   plus --s, the bezel's scale, which every size in here rides.
   ═══════════════════════════════════════════════ */

@import url('https://fonts.googleapis.com/css2?family=VT323&display=swap');

body.tape{
  --ground:#05070c;
  --panel:rgba(5,7,12,.86);
  --panel-edge:rgba(92,158,184,.3);
  --ink:#d6dbe4;
  --dim:#8b95a5;
  --osd:#8fe3a0;
  --osd-dim:#3c6b47;
  --snow:#5c9eb8;
  --rec:#e0343a;
  --font-osd:'VT323','Courier New',monospace;
  --s:1;                                   /* bezel scale, set by ygbf.js */
  --t:calc(6px + 6px * var(--s));          /* body text size on the picture */
  --bg-page:var(--ground);--bg:var(--ground);--bg-alt:#0d1119;--text:var(--ink);--muted:var(--dim);
  --surface:#0d1119;--border:#1b2330;--hover:#161c27;--header-bg:#05070c;--shadow:rgba(0,0,0,.5);
  background:var(--ground);color:var(--ink);overflow-x:hidden;
}
html:has(body.tape){background:#05070c}
body.tape header#site-header{position:relative;z-index:5;backdrop-filter:none;border-bottom:1px solid #12161f}
body.tape{overflow:hidden}
/* One thin bar under the set, so the page never scrolls and the TV stays put */
body.tape footer#site-footer{position:relative;z-index:2;background:var(--ground);border-top:1px solid var(--border);padding:6px 12px}
body.tape footer .footer-inner{flex-direction:row;flex-wrap:wrap;justify-content:center;gap:6px 18px}
body.tape footer .footer-social a{width:22px;height:22px}
body.tape footer .footer-social svg{width:13px;height:13px}
body.tape footer .footer-copy{font-size:10px}
@media (max-width:767px){body.tape footer .footer-copy{display:none}}

/* ── The set ── */
.set{position:relative;width:100%;height:calc(100vh - 57px);min-height:420px;overflow:hidden;background:var(--ground)}
.set > *{position:absolute}
.tape-canvas{z-index:0;display:block;pointer-events:none;image-rendering:pixelated}
.tape-overlay{position:absolute;inset:0;width:100%;height:100%;z-index:3;display:block;pointer-events:none;image-rendering:pixelated}   /* above .channels (1), under the OSD / meter / crawl (4, 5) */
.tape-overlay[hidden],body.editing .tape-overlay{display:none}
/* Channel 04 broadcast: the snow falls on the trailer, under the card and its words (the buried channel keeps its snow over everything) */
.hole.broadcast .tape-overlay{z-index:0}
.tape-poster{z-index:0;background:#05070c url('../images/ygbf-keyart-wide.jpg') center/cover no-repeat;pointer-events:none}
.tape-poster::after{content:"";position:absolute;inset:0;background:rgba(5,7,12,.72)}
.bezel{z-index:2;background:url('../images/tv-bezel.png') 0 0 / 100% 100% no-repeat;image-rendering:pixelated;pointer-events:none}
/* The handheld: the same bezel as a nine-slice, so the screen corners and the deck panel keep their pixels and the wood stretches tall */
.bezel.nine{background:none;border-style:solid;border-color:transparent;border-image:url('../images/tv-bezel.png') 70 82 231 83 stretch;box-sizing:border-box}
.hole{z-index:1;overflow:hidden}
.plate{z-index:3}

/* ── On-screen display ── */
.osd{font-family:var(--font-osd);color:var(--osd);text-shadow:0 0 6px rgba(143,227,160,.5),2px 0 0 rgba(0,0,0,.7);letter-spacing:.04em;line-height:1;user-select:none;margin:0}
.hole-osd{position:absolute;top:calc(22px * var(--s));z-index:4;font-size:calc(26px * var(--s));pointer-events:none}
.hole-osd.left{left:calc(34px * var(--s))}
.hole-osd.right{right:calc(34px * var(--s));animation:osd-blink 1.2s steps(1) infinite}
@keyframes osd-blink{50%{opacity:0}}

/* ── The ghost: the trailer, muted, surfacing out of the static behind channel 00 ── */
.ghost{position:absolute;inset:0;z-index:0;overflow:hidden;pointer-events:none;opacity:0}
.ghost{transition:none}
.ghost iframe{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);width:max(100%,calc(100% * 16 / 9 * 299 / 855));height:max(100%,calc(100% * 855 / 16 * 9 / 299));border:0;pointer-events:none;mix-blend-mode:screen;filter:saturate(.75) contrast(1.1)}

/* ── The channel flip: snow over the picture, then the new channel rolls in ── */
/* while the tape's snow floods the window, the content drops out under it */
.hole.flipping .channels,.hole.flipping .ticker{opacity:0;transition:opacity .05s linear}
.hole.snowed .ticker,.hole.lost .ticker{opacity:0}
/* the crawl arriving: parked under the picture, then a slow slide up (classes set by the page, two seconds after boot or the buried channel) */
.ticker.below{transform:translateY(110%);opacity:0}
.ticker.rising{transition:transform 1.2s cubic-bezier(.2,.7,.2,1),opacity .9s linear}
@media (prefers-reduced-motion:reduce){.ticker.rising{transition:none}}
.channels{transition:opacity .12s linear}
.channels.rollin{animation:rollin .38s cubic-bezier(.25,.8,.3,1)}
@keyframes rollin{0%{transform:translateY(-5%) skewX(-.8deg)}40%{transform:translateY(1.2%) skewX(.3deg)}70%{transform:translateY(-.4%) skewX(0)}100%{transform:translateY(0) skewX(0)}}
/* While the tube is warming up (the shader's own boot), the set's overlays are not there yet */
.hole.booting .hole-osd,.hole.booting .ticker,.hole.booting .track-meter{opacity:0}
/* a snowed channel: its card sits under the static and only shows through once AUTO has dug it out (--reveal set by the page) */
.channel[data-snowed] > *{opacity:var(--reveal,0);transition:opacity .35s linear}
body.editing .channel[data-snowed] > *{opacity:1}
/* the crawl rolls in with the picture, but only a nudge (Ryan: the full drop bounced too much on a one-line strip) */
.ticker.rollin{animation:rollin-crawl .38s cubic-bezier(.25,.8,.3,1)}
@keyframes rollin-crawl{0%{transform:translateY(calc(-4px * var(--s))) skewX(-.3deg)}40%{transform:translateY(calc(1px * var(--s))) skewX(.1deg)}70%{transform:translateY(0) skewX(0)}100%{transform:translateY(0) skewX(0)}}
@media (prefers-reduced-motion:reduce){.channels.rollin,.ticker.rollin{animation:none}}

/* ── Channels ── */
.channels{position:absolute;inset:0;z-index:1;display:flex;flex-direction:column;overflow:hidden;touch-action:none}
.channels::-webkit-scrollbar{display:none}
.channel{position:relative;flex:0 0 100%;height:100%;display:flex;overflow:hidden;padding:calc(56px * var(--s)) calc(34px * var(--s)) calc(30px * var(--s))}
.channel[data-ch="00"]{padding-top:calc(46px * var(--s));padding-bottom:calc(8px * var(--s))}
.channel > *{margin:auto;flex:0 0 auto}
.card{position:relative;background:var(--panel);border:1px solid var(--panel-edge);padding:calc(16px * var(--s)) calc(20px * var(--s));max-width:min(100%,calc(420px * var(--s)));width:100%;box-shadow:0 0 0 1px rgba(0,0,0,.6),0 calc(10px * var(--s)) calc(30px * var(--s)) rgba(0,0,0,.5)}
/* Wide-and-short: the picture is 2.86:1, so text cards run title | body side by side */
.card.split{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.5fr);gap:calc(8px * var(--s)) calc(22px * var(--s));align-items:start;max-width:min(100%,calc(700px * var(--s)))}
.card.split .title{margin:0}
.card.split .body{max-width:none}
.card.split .body .hook{margin:.5em 0}
.card.wide{max-width:min(100%,calc(760px * var(--s)))}
.row-head{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.4fr);gap:calc(6px * var(--s)) calc(20px * var(--s));align-items:end;margin-bottom:calc(8px * var(--s))}
.row-head .title{margin:0}
.row-head .body.lead{margin:0;max-width:none}
.card.center{text-align:center}
.title{font-family:var(--font-display);font-weight:400;font-size:calc(12px + 12px * var(--s));line-height:1;margin:0 0 .5em;color:#fff;text-wrap:balance;text-shadow:3px 3px 0 rgba(0,0,0,.6)}
.body{font-size:var(--t);line-height:1.55;max-width:62ch}
.body p{margin:0 0 var(--pgap,.9em)}
.body p:last-child{margin-bottom:0}
.body strong{color:#fff}
.body .hook{font-family:var(--font-display);font-size:1.3em;line-height:1.2;color:#fff;margin:.5em 0 var(--pgap,.9em);text-shadow:2px 2px 0 rgba(0,0,0,.6)}
.body.lead{margin-bottom:calc(10px * var(--s))}
.list{list-style:none;margin:0;padding:0;display:grid;gap:var(--pgap,.5em)}
.list li{position:relative;padding-left:1.6em}
.list li::before{content:"";position:absolute;left:0;top:.45em;width:.7em;height:.7em;background:var(--snow);box-shadow:inset 0 0 0 2px var(--ground),0 0 0 1px var(--snow)}
.hint{font-size:calc(14px * var(--s));color:var(--osd-dim);margin-top:1em}
/* The buried channel's line, tuned dead on its step: the words glow brighter and brighter for the whole hold, then the cut */
.channel[data-snowed] .hint.reading,.channel[data-snowed] .errand.reading{animation:mystery-glow 4.5s ease-in forwards}
.channel[data-snowed] > .card[hidden]{display:none}   /* the buried channel keeps no card: its line stands alone */
.errand.late{font-size:calc(18px * var(--s))}   /* the buried channel's line: channel 13's placing, a touch smaller (eerier; Ryan) */
body.handheld .errand.late{font-size:calc(14px * var(--s))}
@keyframes mystery-glow{
  0%{color:var(--osd-dim);text-shadow:2px 0 0 rgba(0,0,0,.7)}
  35%{color:var(--osd);text-shadow:0 0 6px rgba(143,227,160,.5),2px 0 0 rgba(0,0,0,.7)}
  100%{color:#fff;text-shadow:0 0 8px rgba(143,227,160,.9),0 0 22px rgba(143,227,160,.8),0 0 48px rgba(143,227,160,.55),2px 0 0 rgba(0,0,0,.7)}
}
@media (prefers-reduced-motion:reduce){.channel[data-snowed] .hint.reading{animation:none;color:var(--osd)}}

/* On air */
.onair{display:flex;flex-direction:row;align-items:center;justify-content:center;text-align:center;gap:calc(26px * var(--s));background:transparent;border:0;box-shadow:none;max-width:100%;width:100%}
.onair .logo{flex:0 1 auto;width:min(63%,calc(560px * var(--s)));filter:drop-shadow(0 4px 0 rgba(0,0,0,.6)) drop-shadow(0 0 24px rgba(0,0,0,.6))}
.onair-side{display:flex;flex-direction:column;align-items:center;gap:calc(10px * var(--s));flex:0 1 auto;max-width:36%}
.onair .tag{margin:0;font-weight:700;font-size:calc(var(--t) * 1.1);color:#fff;text-shadow:2px 2px 0 rgba(0,0,0,.7)}
.onair .hint{margin-top:.3em}

/* REC button */
.btn-rec{display:inline-flex;align-items:center;gap:.6em;background:var(--rec);color:#fff;text-decoration:none;font-weight:700;font-size:calc(var(--t) * 1.05);letter-spacing:.08em;text-transform:uppercase;padding:.6em 1.15em .6em .95em;border:0;border-bottom:3px solid #8f1c22;cursor:pointer;font-family:var(--font-body);transition:transform .12s,border-bottom-width .12s;white-space:nowrap}
.btn-rec i{width:.65em;height:.65em;border-radius:50%;background:#fff;box-shadow:0 0 8px #fff;animation:osd-blink 1.2s steps(1) infinite}
@media (hover:hover){ .btn-rec:hover{transform:translateY(-1px)} }
.btn-rec:active{transform:translateY(2px);border-bottom-width:1px}
.btn-rec.big{font-size:calc(var(--t) * 1.15)}
.btn-rec:focus-visible,.deck button:focus-visible,.cassette:focus-visible,.shot:focus-visible,.slide-nav:focus-visible{outline:2px solid var(--snow);outline-offset:3px}
.cta-row{display:flex;gap:12px;justify-content:center;flex-wrap:wrap;margin-top:1em}
.btn-ghost-tape{display:inline-flex;align-items:center;font-weight:700;font-size:calc(var(--t) * .9);letter-spacing:.08em;text-transform:uppercase;padding:.7em 1.2em;border:1px solid var(--panel-edge);color:var(--ink);background:rgba(0,0,0,.3)}
@media (hover:hover){ .btn-ghost-tape:hover{border-color:var(--snow);color:#fff} }

/* ── Talents: the pocket deck ──
   The game's tape deck (scripts/ui/tape_deck.gd) at 2x: body 75x76, bay 61x41 at
   (7,7) clipping the seated 45x31 cassette at bay-local (9,6), spools at (16,18)
   and (40,18), the door plate 65x44 at (5,5), four 16px buttons at y 50. */
.deckcard{display:grid;grid-template-columns:auto minmax(0,1fr);grid-template-rows:auto auto;gap:calc(8px * var(--s)) calc(18px * var(--s));align-items:stretch;width:100%;max-width:min(100%,calc(780px * var(--s)))}
.tapedeck{position:relative;width:calc(150px * var(--s));height:calc(152px * var(--s));background:url('../images/ui/tape_deck/deck_empty.png') 0 0 / 100% 100% no-repeat;image-rendering:pixelated;flex:0 0 auto;filter:drop-shadow(0 calc(6px * var(--s)) calc(10px * var(--s)) rgba(0,0,0,.6))}
.tapedeck .bay{position:absolute;left:calc(14px * var(--s));top:calc(14px * var(--s));width:calc(122px * var(--s));height:calc(82px * var(--s));overflow:hidden}
.tapedeck .cass{position:absolute;left:calc(18px * var(--s));top:calc(12px * var(--s));width:calc(90px * var(--s));height:calc(62px * var(--s));background:url('../images/ui/tape_deck/cassette.png') 0 0 / 100% 100% no-repeat;image-rendering:pixelated;transition:top .32s cubic-bezier(.3,.7,.3,1)}
.tapedeck .cass.out{top:calc(-72px * var(--s));transition-timing-function:cubic-bezier(.5,0,.8,.4)}
.tapedeck .cass .band{position:absolute;left:14%;right:14%;top:14%;height:20%;background:var(--tape,#4a5568);opacity:.9}
.tapedeck .cass .lbl{position:absolute;left:0;right:0;top:14%;height:20%;display:flex;align-items:center;justify-content:center;font-family:var(--font-osd);font-size:calc(9px * var(--s));letter-spacing:.06em;color:#fff;text-shadow:1px 1px 0 rgba(0,0,0,.6)}
.tapedeck .wheel{position:absolute;width:calc(14px * var(--s));height:calc(14px * var(--s));top:calc(36px * var(--s));background:url('../images/ui/tape_deck/wheel_l.png') 0 0 / 100% 100% no-repeat;image-rendering:pixelated;z-index:2;visibility:hidden}   /* the spools ARE the cassette's: nothing to see with no tape in */
.tapedeck .wheel.l{left:calc(32px * var(--s))}
.tapedeck .wheel.r{left:calc(80px * var(--s));background-image:url('../images/ui/tape_deck/wheel_r.png')}
.tapedeck.playing .wheel{visibility:visible;animation:spool 1.1s linear infinite}
.tapedeck.playing .wheel.r{animation-duration:.85s}
@keyframes spool{to{transform:rotate(360deg)}}
.tapedeck .plate{position:absolute;left:calc(10px * var(--s));top:calc(10px * var(--s));width:calc(130px * var(--s));height:calc(88px * var(--s));background:url('../images/ui/tape_deck/plate.png') 0 0 / 100% 100% no-repeat;image-rendering:pixelated;pointer-events:none}
.tapedeck .dbtn{position:absolute;top:calc(100px * var(--s));width:calc(32px * var(--s));height:calc(32px * var(--s));border:0;padding:0;background:url('../images/ui/tape_deck/btn_play_sheet.png') 0 0 / 100% 400% no-repeat;image-rendering:pixelated;cursor:pointer}
/* Every state of a key lives in ONE sheet (normal, pressed, lit, lit+pressed stacked), so a state change is a background-position and never a fetch: swapping separate images blanked the key while the next one loaded, worst when clicking fast */
.tapedeck .dbtn.rew{left:calc(14px * var(--s));background-image:url('../images/ui/tape_deck/btn_rew_sheet.png')}
.tapedeck .dbtn.play{left:calc(46px * var(--s));background-image:url('../images/ui/tape_deck/btn_play_sheet.png')}
.tapedeck .dbtn.ffwd{left:calc(78px * var(--s));background-image:url('../images/ui/tape_deck/btn_ffwd_sheet.png')}
.tapedeck .dbtn.eject{left:calc(110px * var(--s));background-image:url('../images/ui/tape_deck/btn_eject_sheet.png')}
/* .down is the deck pressing its own key (the eject going down while a tape swaps), the same frame as a finger on it */
.tapedeck .dbtn:active,.tapedeck .dbtn.down{background-position:0 33.3334%}
.tapedeck.lit-rew .dbtn.rew,.tapedeck.lit-ffwd .dbtn.ffwd,.tapedeck.lit-eject .dbtn.eject{background-position:0 66.6667%}
/* play stays DOWN and lit the whole time a tape plays; the eject is down and lit while its latch holds (from a tape leaving until the next one seats) */
.tapedeck.playing .dbtn.play,.tapedeck.lit-eject .dbtn.eject.down{background-position:0 100%}
.tapedeck.lit-rew .dbtn.rew:active,.tapedeck.lit-ffwd .dbtn.ffwd:active,.tapedeck.lit-eject .dbtn.eject:active{background-position:0 100%}
.tapedeck .dbtn:focus-visible{outline:2px solid var(--snow);outline-offset:2px}
.deckread{background:var(--panel);border:1px solid var(--panel-edge);padding:calc(12px * var(--s)) calc(16px * var(--s));display:flex;flex-direction:column;justify-content:center;gap:calc(4px * var(--s));min-width:0;box-shadow:0 0 0 1px rgba(0,0,0,.6)}
.deckread .k{font-size:calc(14px * var(--s));color:var(--osd-dim);text-shadow:2px 0 0 rgba(0,0,0,.7);margin:0 0 .2em}
/* the readout line is dim with no tape in the bay and lights up, glowing like every other OSD label, once a cassette is seated and playing */
.deckcard:has(.tapedeck.playing) .deckread .k{color:var(--osd);text-shadow:0 0 6px rgba(143,227,160,.5),2px 0 0 rgba(0,0,0,.7)}
.deckread .title{margin:0;font-size:calc(10px + 11px * var(--s))}
.deckread .desc{margin:0;max-width:none}
.deckread .desc.empty{color:var(--dim)}
.tapes{grid-column:1 / -1;display:grid;grid-template-columns:repeat(10,minmax(0,1fr));gap:calc(6px * var(--s))}
.tapebtn{--tape:#4a5568;position:relative;aspect-ratio:45/31;border:0;padding:0;background:url('../images/ui/tape_deck/cassette.png') 0 0 / 100% 100% no-repeat;image-rendering:pixelated;cursor:pointer;color:#fff;filter:drop-shadow(0 calc(3px * var(--s)) 0 rgba(0,0,0,.5));transition:transform .16s cubic-bezier(.2,.9,.3,1.3),filter .16s}
.tapebtn .band{position:absolute;left:14%;right:14%;top:14%;height:20%;background:var(--tape);opacity:.9}
.tapebtn .lbl{position:absolute;left:0;right:0;top:14%;height:20%;display:flex;align-items:center;justify-content:center;font-family:var(--font-osd);font-size:calc(8px * var(--s));letter-spacing:.05em;text-shadow:1px 1px 0 rgba(0,0,0,.6)}
.tapebtn .no{position:absolute;right:10%;bottom:8%;font-family:var(--font-osd);font-size:calc(8px * var(--s));color:#2a1f14}
.tapebtn:focus-visible{transform:translateY(calc(-4px * var(--s)))}
@media (hover:hover){ .tapebtn:hover{transform:translateY(calc(-4px * var(--s)))} }
.tapebtn[aria-pressed="true"]{transform:translateY(calc(2px * var(--s))) scale(.94);filter:drop-shadow(0 0 0 rgba(0,0,0,0)) brightness(.7)}
.tapebtn:focus-visible{outline:2px solid var(--snow);outline-offset:2px}
/* a locked cassette: under snow with a question mark, until the tracking tunes it in */
.tapebtn.locked:not(.tuned){cursor:default}
.tapebtn.locked:not(.tuned):hover{transform:none}
.tapebtn.locked:not(.tuned) .band,.tapebtn.locked:not(.tuned) .lbl{visibility:hidden}
.tapebtn .snow{display:none;position:absolute;inset:0;width:100%;height:100%;image-rendering:pixelated;pointer-events:none;-webkit-mask:url('../images/ui/tape_deck/cassette.png') 0 0 / 100% 100% no-repeat;mask:url('../images/ui/tape_deck/cassette.png') 0 0 / 100% 100% no-repeat}
.tapebtn.locked:not(.tuned) .snow{display:block}
.tapebtn .q{display:none;position:absolute;inset:0;align-items:center;justify-content:center;font-size:calc(20px * var(--s));color:var(--osd);text-shadow:0 0 6px rgba(143,227,160,.5),1px 1px 0 #000;pointer-events:none}
.tapebtn.locked:not(.tuned) .q{display:flex}
/* A story card with FOUR parts in two rows (Combat, Collectibles): the divider sits between the columns only */
.card.story2.grid4 .parts{grid-template-columns:1fr 1fr;gap:calc(10px * var(--s)) calc(28px * var(--s))}
.card.story2.grid4 .part + .part{border-left:0;padding-left:0;margin-left:0}
.card.story2.grid4 .part:nth-child(even){border-left:1px solid var(--panel-edge);padding-left:calc(28px * var(--s));margin-left:calc(-14px * var(--s))}
.card.story2.grid4 .line{font-size:calc(var(--t) * 1.0)}
/* A story card that walks its topics one at a time (Combat, The World, The Entourage, Minigames, Collectibles): a tap
   anywhere turns to the next topic and wraps around. The card fits the topic showing (no padding borrowed from a taller
   one) and, being centred on the picture, grows and shrinks about that centre rather than hanging from its top edge
   (Ryan). A counter and the tap hint sit under it. */
.card.story2.slides{position:relative;display:grid;grid-template-columns:100%;grid-template-rows:auto auto;max-width:min(100%,calc(780px * var(--s)));cursor:pointer;user-select:none;-webkit-tap-highlight-color:transparent}
.card.story2.slides .slide{grid-area:1 / 1;display:none;flex-direction:column;gap:calc(10px * var(--s))}
.card.story2.slides .slide.on{display:flex}
/* keep-head (The Story): the headline stays up, in its own face, over every slide; slides sit under it */
.card.story2.slides.keep-head{grid-template-rows:auto auto auto}
.card.story2.slides.keep-head .headline{display:block;grid-area:1 / 1}
.card.story2.slides.keep-head .slide{grid-area:2 / 1}
.card.story2.slides.keep-head .dots{grid-area:3 / 1}
body.handheld .card.story2.slides.keep-head{margin:auto}   /* The Story sits in the middle of the phone's picture, not along its foot (Ryan) */
/* Socials: the four links in a row under the line */
.card.story2.socials .cta-row{display:flex;flex-wrap:wrap;justify-content:center;gap:calc(10px * var(--s));margin-top:calc(6px * var(--s))}
.card.story2.socials .mail{color:var(--osd);text-decoration:none;border-bottom:1px solid rgba(143,227,160,.4);white-space:nowrap}
body.handheld .card.story2.socials{padding:calc(10px * var(--s)) calc(12px * var(--s));gap:calc(6px * var(--s))}
body.handheld .card.story2.socials .headline{font-size:calc(8px + 6px * var(--s));padding-bottom:calc(5px * var(--s))}
body.handheld .card.story2.socials .line{font-size:calc(var(--t) * .95);line-height:1.35}
body.handheld .card.story2.socials .mail{white-space:normal;word-break:break-all}
body.handheld .card.story2.socials .cta-row{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:calc(6px * var(--s));margin-top:calc(2px * var(--s))}
body.handheld .card.story2.socials .cta-row .btn-rec{justify-content:center;font-size:calc(6px * var(--s));padding:.35em .3em;gap:.3em}
.card.story2.socials .mail:hover{color:#fff;border-bottom-color:#fff}
.card.story2.slides .slide .lbl{margin:0}
/* the premise slide (The Story) is a plain slide line like the rest: the grey ink is easier on the eyes than white (Ryan) */
.card.story2.slides .slide .line{margin:0}
.card.story2.slides .dots{grid-area:2 / 1;margin:0;text-align:center;font-size:calc(11px * var(--s));letter-spacing:.1em;color:var(--osd);opacity:.8}
.card.story2.slides:hover .dots{opacity:1}
/* small white arrows at the middle of either edge: the left half of the card goes back, the right half forward */
.card.story2.slides::before,.card.story2.slides::after{position:absolute;top:50%;transform:translateY(-50%);font-size:calc(9px * var(--s));line-height:1;color:#fff;opacity:.55;pointer-events:none;text-shadow:0 0 4px rgba(0,0,0,.8)}
.card.story2.slides::before{content:'◀';left:calc(10px * var(--s))}
.card.story2.slides::after{content:'▶';right:calc(10px * var(--s))}
body.handheld .card.story2.slides::before{left:calc(5px * var(--s))}
body.handheld .card.story2.slides::after{right:calc(5px * var(--s))}
/* room between the arrows and the words */
.card.story2.slides{padding-left:calc(36px * var(--s));padding-right:calc(36px * var(--s))}
.card.story2.slides:focus-visible{outline:2px solid var(--snow);outline-offset:3px}
/* No white headline on the slides: the green OSD label is the heading, the line sits under it (the headlines stay in the markup). */
.card.story2.slides .headline{display:none}
.card.story2.slides .slide .lbl{margin:0 0 .1em}
/* On the handheld the card is a strip along the foot of the picture, translucent, so the footage behind it is the show */
body.handheld .card.story2.slides{margin:auto 0 0;padding:calc(9px * var(--s)) calc(24px * var(--s)) calc(7px * var(--s));gap:calc(5px * var(--s));background:rgba(5,7,12,.78);max-height:none}
body.handheld .card.story2.slides .slide{gap:calc(4px * var(--s))}
/* On a phone the card keeps ONE size, its tallest topic's (Ryan): every slide is laid out in the same cell and only the one
   showing is visible, so the header stays pinned at the top, the tap hint at the bottom, and nothing jumps as you tap through. */
body.handheld .card.story2.slides .slide{display:flex;visibility:hidden;justify-content:flex-start}
body.handheld .card.story2.slides .slide.on{visibility:visible}
body.handheld .card.story2.slides .slide .lbl{font-size:calc(14px * var(--s))}
body.handheld .card.story2.slides .slide .line{font-size:calc(var(--t) * 0.95);line-height:1.38}
body.handheld .card.story2.slides .dots{font-size:calc(9px * var(--s))}
/* the secret channel */
.secret-card .hint{margin-top:.6em}
/* channel 13's errant broadcast: a line in the middle of the picture, dim and garbled off the step, glowing on it (the page sets opacity with the static) */
.errand{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);margin:0;width:88%;text-align:center;font-size:calc(24px * var(--s));letter-spacing:.14em;line-height:1.3;color:var(--osd-dim);text-shadow:2px 0 0 rgba(0,0,0,.7);opacity:0;pointer-events:none;z-index:2}
.errand.reading{animation:mystery-glow 3s ease-in forwards}
body.handheld .errand{font-size:calc(18px * var(--s))}
@media (max-width:767px){
  .deckcard{grid-template-columns:1fr}
  .tapedeck{margin:0 auto}
  .tapes{grid-template-columns:repeat(5,minmax(0,1fr))}
}

/* ── Screenshots ── */
/* ── Screenshots: a 3x2 grid of stills sized to the picture, each 16:9 ── */
.shots{display:grid;grid-template-columns:repeat(3,1fr);grid-auto-rows:1fr;gap:calc(10px * var(--s));height:100%;aspect-ratio:2.6;max-width:100%;margin:auto}
.shot{position:relative;border:0;padding:0;background:#000;cursor:zoom-in;overflow:hidden;box-shadow:0 0 0 1px var(--panel-edge),0 8px 24px rgba(0,0,0,.5);transition:transform .18s ease,box-shadow .18s ease}
@media (hover:hover){ .shot:hover{transform:translateY(-2px);box-shadow:0 0 0 1px var(--snow),0 14px 30px rgba(0,0,0,.6)} }
.shot img{display:block;width:100%;height:100%;object-fit:cover}
.shot .num{position:absolute;left:calc(6px * var(--s));top:calc(4px * var(--s));font-size:calc(14px * var(--s));pointer-events:none}
.shot.lifted{visibility:hidden}
/* the lifted still: a frame that flies from the thumbnail's slot to the middle of the screen */
.shotzoom{position:fixed;inset:0;z-index:50}
.shotzoom[hidden]{display:none}
.shotzoom .scrim{position:absolute;inset:0;background:rgba(5,7,12,.9);opacity:0;transition:opacity .4s ease}
.shotzoom.on .scrim{opacity:1}
.shotzoom .frame{position:absolute;margin:0;background:#000;transform-origin:0 0;will-change:transform;cursor:zoom-out;box-shadow:0 0 0 1px var(--panel-edge),0 30px 80px rgba(0,0,0,.7)}
.shotzoom.anim .frame{transition:transform .48s cubic-bezier(.2,.8,.2,1)}
.shotzoom .frame img{display:block;width:100%;height:100%;object-fit:cover}
.shotzoom .cap{position:absolute;left:0;right:0;bottom:0;margin:0;padding:.5em 0 .35em;text-align:center;font-size:clamp(14px,2.2vh,24px);background:linear-gradient(transparent,rgba(0,0,0,.75));opacity:0;transition:opacity .3s ease .25s}
.shotzoom.on .cap{opacity:1}
.shotzoom .slide-nav{position:absolute;top:50%;transform:translateY(-50%);z-index:1;opacity:0;transition:opacity .3s ease .25s}
.shotzoom.on .slide-nav{opacity:1}
.shotzoom .prev{left:max(8px,2vw)}
.shotzoom .next{right:max(8px,2vw)}
@media (prefers-reduced-motion: reduce){ .shotzoom .scrim,.shotzoom .frame,.shotzoom .cap,.shotzoom .slide-nav,.shot{transition:none} }
body.handheld .shotzoom .slide-nav{display:none}   /* on a phone the screenshots are swiped, not pressed */
body.handheld .shotzoom{touch-action:none}   /* the viewer takes every touch: a swipe pages, a pinch zooms, a drag pans */

/* ── Trailer ── */
.trailer{width:100%;height:100%;margin:0;display:flex;align-items:center;justify-content:center}
.trailer::after{content:"";position:absolute;inset:0;display:flex;align-items:flex-end;justify-content:center;padding-bottom:calc(20px * var(--s));font-family:var(--font-osd);font-size:calc(14px * var(--s));color:var(--osd-dim);letter-spacing:.06em;cursor:pointer}
.trailer.live::after{display:none}
.trailer{position:relative}
.trailer iframe{border:0;height:100%;aspect-ratio:16/9;max-width:100%;background:#000}

/* ── Tracking meter ── */
.track-meter{position:absolute;left:50%;bottom:calc(30px * var(--s));transform:translateX(-50%);z-index:5;font-size:calc(16px * var(--s));background:rgba(5,7,12,.7);padding:.2em .8em;white-space:nowrap;pointer-events:none}
.track-meter[hidden]{display:none}
.track-meter{transition:opacity .4s linear}   /* the deck hunting (AUTO) fades up and away */
.track-meter.fade{opacity:0}
.track-meter span{letter-spacing:.1em}

/* ── Idolex ticker ── */
.ticker{position:absolute;left:0;right:0;bottom:0;z-index:4;background:rgba(5,7,12,.85);border-top:1px solid var(--panel-edge);overflow:hidden;height:calc(16px * var(--s));display:flex;align-items:center;font-family:var(--font-osd);font-size:calc(12px * var(--s));color:var(--osd);letter-spacing:.05em;pointer-events:none}
.ticker .tag{flex:0 0 auto;background:var(--osd);color:var(--ground);padding:0 .8em;height:100%;display:flex;align-items:center;z-index:1}
.ticker .crawl{flex:1;overflow:hidden;white-space:nowrap;position:relative;height:100%}
.ticker .crawl > span{display:inline-flex;align-items:center;height:100%;padding-left:100%;white-space:nowrap;animation:crawl 55s linear infinite}
.ticker .crawl b{font-weight:400;color:var(--snow)}
.ticker .crawl em{font-style:normal;color:var(--rec)}
.ticker .crawl .sep{margin:0 1.4em;color:var(--osd-dim);font-size:.7em}
@keyframes crawl{to{transform:translateX(-100%)}}

/* ── The deck (striped panel) ── */
/* Wishlist on the left, the channel keys in the middle, Patreon on the right: the same three columns on the TV and the handheld */
.plate{display:grid;grid-template-columns:1fr auto 1fr;align-items:center;gap:calc(14px * var(--s));padding:0 calc(14px * var(--s))}
.plate .wishlist{order:-1;justify-self:start}
.plate .patreon{justify-self:end}
.plate .deck{justify-self:center}
.deck{display:flex;align-items:center;gap:calc(10px * var(--s));flex-wrap:wrap;justify-content:center;flex:0 1 auto;min-width:0}
.keys{display:flex;gap:6px}
.deck button{font-family:var(--font-body);font-weight:700;letter-spacing:.06em;background:#161c27;color:var(--ink);border:1px solid #2a3442;border-bottom-width:4px;padding:.85em 1.4em;cursor:pointer;font-size:var(--t);text-transform:uppercase;transition:transform .08s,border-bottom-width .08s;white-space:nowrap}
.deck button:active,.deck button.down{border-bottom-width:1px;transform:translateY(2px)}
.plate .btn-rec{flex:0 0 auto}
.plate.narrow{gap:calc(6px * var(--s))}

/* ── Lightbox ── */
body.tape .lightbox{position:fixed;inset:0;z-index:40;background:rgba(5,7,12,.92);display:flex;align-items:center;justify-content:center;padding:24px}
body.tape .lightbox[hidden]{display:none}
body.tape .lightbox-img{max-width:min(100%,1280px);max-height:88vh;box-shadow:0 0 0 1px var(--panel-edge),0 30px 80px rgba(0,0,0,.7)}
body.tape .lightbox-close,body.tape .lightbox-nav{position:absolute;background:#0d1119;color:var(--ink);border:1px solid #2a3442;width:44px;height:44px;font-size:26px;cursor:pointer;line-height:1}
body.tape .lightbox-close{top:16px;right:16px}
body.tape .lightbox-nav{top:50%;transform:translateY(-50%)}
body.tape .lightbox-prev{left:16px}
body.tape .lightbox-next{right:16px}

@media (prefers-reduced-motion:reduce){
  .hole-osd.right,.btn-rec i,.cassette[aria-pressed="true"] .foot::before{animation:none}
  .ticker .crawl span{animation:none;padding-left:12px}
  .cassette,.btn-rec,.deck button{transition:none}
}

/* ── Extra faces from assets/fonts, so the type panel can offer them ── */
@font-face{font-family:'Junicode';src:url('../fonts/Junicode.ttf') format('truetype');font-weight:400;font-style:normal;font-display:swap}
@font-face{font-family:'Junicode';src:url('../fonts/Junicode-Bold.ttf') format('truetype');font-weight:700;font-style:normal;font-display:swap}
@font-face{font-family:'FoulisGreek';src:url('../fonts/FoulisGreek.ttf') format('truetype');font-weight:400;font-style:normal;font-display:swap}
@font-face{font-family:'Unbounded';src:url('../fonts/Unbounded.ttf') format('truetype');font-weight:400 800;font-style:normal;font-display:swap}

/* ── Page editor: ! or ?edit ── */
/* Docked on the right, Slides-style: the page shrinks to make room (body padding), so the TV re-fits beside it. */
.editor{position:fixed;right:0;top:0;bottom:0;z-index:60;width:min(360px,100vw);overflow:auto;background:#0d1119;border-left:1px solid #2a3442;box-shadow:-12px 0 40px rgba(0,0,0,.5);font-size:13px;color:var(--ink);display:flex;flex-direction:column;gap:8px;padding:12px 14px 14px;font-family:var(--font-body)}
body.ed-open{padding-right:min(360px,100vw)}
/* Phone view in the editor: the set becomes a phone-shaped window, so the page lays out its handheld set */
body.ed-phone .set{--ph:min(calc(100vh - 57px),915px);height:var(--ph);min-height:0;width:calc(var(--ph) * 412 / 915);max-width:100%;margin:0 auto;box-shadow:0 0 0 1px #2a3442,0 0 40px rgba(0,0,0,.6)}
.ed-view{display:flex;align-items:center;gap:8px}
.ed-view .btns{flex:0 0 auto}
.ed-view .ed-help{margin:0}
.ed-channels{display:grid;grid-template-columns:1fr 1fr;gap:3px}
.ed-channels button{background:#05070c;border:1px solid #2a3442;color:var(--dim);font-family:var(--font-osd);font-size:14px;letter-spacing:.05em;padding:4px 6px;text-align:left;cursor:pointer;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.ed-channels button.on{color:var(--osd);border-color:var(--osd-dim)}
.ed-channels button:hover{color:var(--ink)}
.editor[hidden]{display:none}
.editor h3{margin:0;font-family:var(--font-osd);font-weight:400;font-size:20px;color:var(--osd);letter-spacing:.06em;display:flex;justify-content:space-between;align-items:center}
.editor h3 .hbtns{display:flex;gap:2px}
.editor h3 button{background:none;border:1px solid transparent;color:var(--dim);font-size:17px;cursor:pointer;width:26px;height:26px;line-height:1}
.editor h3 button:hover{color:var(--ink);border-color:#2a3442}
.editor label{display:grid;grid-template-columns:62px 1fr 34px;gap:8px;align-items:center;color:var(--dim);font-size:12px}
.editor label span:last-child{font-family:var(--font-osd);color:var(--osd);text-align:right;font-size:15px}
.editor label.file{grid-template-columns:62px 1fr}
.editor input[type=text],.editor select{width:100%;background:#05070c;color:var(--ink);border:1px solid #2a3442;padding:5px 7px;font:inherit;min-width:0}
.editor input[type=range]{width:100%;accent-color:var(--snow);margin:0}
.editor input[type=file]{font-size:12px;color:var(--dim)}
.editor .row{display:flex;gap:8px}
.editor .row button,.editor .btns button{background:#161c27;color:var(--ink);border:1px solid #2a3442;border-bottom-width:3px;cursor:pointer;font:inherit;font-weight:700;letter-spacing:.05em;text-transform:uppercase;font-size:12px}
.editor .row button{flex:1;padding:7px 10px}
.editor .row button:active,.editor .btns button:active{border-bottom-width:1px;transform:translateY(2px)}
.editor .btns{display:flex;gap:3px}
.editor .btns button{padding:4px 2px;flex:1;font-size:12px;line-height:1.1}
.editor .btns button.on{background:var(--snow);color:#05070c;border-color:#3d6f84}
.editor #ed-toggle[aria-pressed="true"]{background:var(--rec);border-color:#8f1c22;color:#fff}
.editor #ed-save{background:var(--osd);color:#05070c;border-color:#2f7a48}
.editor .check{display:flex;gap:4px 12px;align-items:center;color:var(--dim);flex-wrap:wrap;font-size:12px}
.editor .check.small{font-size:11px}
.editor .check label{display:inline;margin-right:4px}
.editor .ed-help{margin:0;color:var(--dim);font-size:11px;line-height:1.4}
.editor .ed-sel{margin:0;font-family:var(--font-osd);font-size:15px;color:var(--osd);background:#05070c;padding:5px 8px;border:1px solid #2a3442;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.editor .ed-pos{margin:0;display:flex;justify-content:space-between;font-size:12px;color:var(--dim)}
.editor .ed-pos span:last-child{font-family:var(--font-osd);color:var(--osd);font-size:15px}
.editor .ed-tabs{display:flex;gap:2px;border-bottom:1px solid #2a3442}
.editor .ed-tabs button{flex:1;background:none;border:0;border-bottom:2px solid transparent;color:var(--dim);font:inherit;font-weight:700;letter-spacing:.06em;text-transform:uppercase;font-size:11px;padding:6px 0;cursor:pointer}
.editor .ed-tabs button.on{color:var(--osd);border-bottom-color:var(--osd)}
.editor .ed-tab{display:flex;flex-direction:column;gap:8px}
.editor .ed-tab[hidden]{display:none}
.editor .ed-status{margin:0;font-family:var(--font-osd);font-size:14px;color:var(--osd-dim);letter-spacing:.05em}
.ed-hidden{display:none !important}
body.editing .hole-osd,body.editing .ticker,body.editing .track-meter,body.editing .shot .num,body.editing .tapedeck .plate{pointer-events:auto}
body.editing .ed-selected{outline:2px solid var(--snow) !important;outline-offset:2px;cursor:move}
body.editing .ed-editing{outline:2px dashed var(--osd) !important;outline-offset:2px;cursor:text}
body.editing .channel a,body.editing .channel button,body.editing .plate a,body.editing .plate button{cursor:move}
body.ed-grid .hole{background-image:linear-gradient(rgba(92,158,184,.18) 1px,transparent 1px),linear-gradient(90deg,rgba(92,158,184,.18) 1px,transparent 1px);background-size:calc(var(--ed-grid,8) * 1px * var(--s)) calc(var(--ed-grid,8) * 1px * var(--s));background-position:0 0}
body.ed-grid.ed-grid-fine .hole{background-image:linear-gradient(rgba(92,158,184,.09) 1px,transparent 1px),linear-gradient(90deg,rgba(92,158,184,.09) 1px,transparent 1px)}
.editor .check select{width:auto;padding:2px 4px;font-size:11px}
body.ed-pan,body.ed-pan *{cursor:grab !important}
.editor .ed-help b{color:var(--ink)}
.editor #ed-zoom{font-family:var(--font-osd);color:var(--osd);font-size:14px}
/* Frame off (editor): see and reach what is outside the picture window */
body.ed-noframe .bezel{opacity:.18}
body.ed-noframe .hole,body.ed-noframe .channels{overflow:visible}
body.ed-noframe .channel{overflow:visible}
body.ed-noframe .channel:not(.on){visibility:hidden}
body.ed-noframe .hole{outline:1px dashed var(--snow);outline-offset:-1px}
/* ...and lifted above the deck, so what spilled over the deck can be grabbed */
body.ed-noframe .hole{z-index:4}
body.ed-noframe .plate{opacity:.55}
body.ed-noframe .set{overflow:visible}
.ed-handle{position:fixed;z-index:71;width:10px;height:10px;margin:-5px 0 0 -5px;background:#fff;border:1px solid var(--snow);box-shadow:0 1px 3px rgba(0,0,0,.6)}
.ed-handle.n,.ed-handle.s{cursor:ns-resize}.ed-handle.e,.ed-handle.w{cursor:ew-resize}.ed-handle.nw,.ed-handle.se{cursor:nwse-resize}.ed-handle.ne,.ed-handle.sw{cursor:nesw-resize}
.ed-marquee{position:fixed;z-index:70;pointer-events:none;border:1px solid var(--snow);background:rgba(92,158,184,.12)}
.ed-layers{display:flex;flex-direction:column;gap:2px;max-height:190px;overflow:auto;border:1px solid #2a3442;background:#05070c;padding:3px}
.ed-layer{display:flex;align-items:center;gap:6px;padding:3px 6px;font-size:12px;color:var(--dim);cursor:pointer;border:1px solid transparent}
.ed-layer:hover{color:var(--ink)}
.ed-layer.on{color:var(--osd);border-color:var(--osd-dim);background:#0d1119}
.ed-layer.off .nm{opacity:.45;text-decoration:line-through}
.ed-layer .eye{background:none;border:0;color:var(--snow);cursor:pointer;font-size:11px;padding:0;width:14px}
.ed-layer .nm{flex:1;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.ed-layer .z{font-family:var(--font-osd);color:var(--osd-dim);font-size:13px}
.ed-guide{position:fixed;z-index:70;pointer-events:none;background:#ff5ca8;box-shadow:0 0 6px #ff5ca8}
.ed-guide.x{top:0;bottom:0;width:1px}
.ed-guide.y{left:0;right:0;height:1px}
.glow{color:var(--osd) !important;text-shadow:0 0 6px rgba(143,227,160,.5),0 0 18px rgba(143,227,160,.35),2px 0 0 rgba(0,0,0,.7) !important}
.ed-hidden{display:none !important}
body.editing .hole-osd,body.editing .ticker,body.editing .track-meter{pointer-events:auto}
body.editing .ed-selected{outline:2px solid var(--snow) !important;outline-offset:2px}
body.editing .ed-editing{outline:2px dashed var(--osd) !important;outline-offset:2px;cursor:text}
body.editing .channel a,body.editing .channel button,body.editing .plate a,body.editing .plate button{cursor:default}
.ed-grip{position:absolute;z-index:70;width:22px;height:22px;margin:-11px 0 0 -11px;background:var(--snow);color:#05070c;border:2px solid #05070c;border-radius:50%;font-size:13px;line-height:18px;text-align:center;cursor:grab;user-select:none;box-shadow:0 2px 8px rgba(0,0,0,.6);touch-action:none}
.ed-grip:active{cursor:grabbing}

/* ── Idolex crawl: a news ticker ── */
.ticker .crawl .it{display:inline-flex;align-items:center;gap:.45em;white-space:nowrap}
.ticker .crawl .it.you{color:var(--rec)}
.ticker .crawl .pos{font-weight:400;color:var(--snow)}
.ticker .crawl .mv{font-style:normal;color:var(--dim);font-size:.85em}
.ticker .crawl .mv.up{color:var(--osd)}
.ticker .crawl .mv.dn{color:var(--rec)}
.ticker .crawl .ttl{font-weight:400;color:var(--dim)}
.ticker .crawl .tag2{display:inline-block;padding:0 .45em;font-weight:400;color:var(--ground);background:var(--rec)}
.ticker .crawl .hl{color:#fff}
.ticker .crawl .tag2.loc{background:var(--snow)}
.ticker .crawl .wx{color:var(--snow)}
.ticker .crawl .wx .sub{font-style:normal;color:var(--dim);font-size:.85em}
/* ── Donor crawl ── */
.ticker .crawl .rk{display:inline-block;padding:0 .45em;margin-right:.4em;font-weight:400;color:var(--ground);background:var(--osd)}
.ticker .crawl .rk.s{background:#f5c542}.ticker .crawl .rk.a{background:#ff6db3}.ticker .crawl .rk.b{background:#6dacf8}.ticker .crawl .rk.c{background:var(--osd)}
.ticker .crawl .rk.d,.ticker .crawl .rk.e,.ticker .crawl .rk.f{background:#8b95a5}
.ticker .crawl .nm{color:var(--ink)}
.ticker .crawl .nm.s{color:#f5c542}.ticker .crawl .nm.a{color:#ff6db3}.ticker .crawl .nm.b{color:#6dacf8}.ticker .crawl .nm.c{color:var(--osd)}

/* ── Get Ranked ── */
.ranks{display:grid;grid-template-columns:repeat(7,minmax(0,1fr));gap:calc(6px * var(--s));margin:calc(6px * var(--s)) 0}
.rank{display:flex;flex-direction:column;align-items:center;text-align:center;gap:2px;background:rgba(0,0,0,.35);border:1px solid var(--panel-edge);padding:calc(6px * var(--s)) calc(6px * var(--s))}
.rank .letter{font-family:var(--font-display);font-size:calc(var(--t) * 2.2);line-height:1;color:#fff;text-shadow:3px 3px 0 rgba(0,0,0,.6)}
.rank .price{font-family:var(--font-osd);font-size:calc(var(--t) * 1.3);color:var(--osd);letter-spacing:.05em}
.rank .perk{font-size:calc(var(--t) * .8);line-height:1.3;color:var(--dim)}
.donate{max-width:min(100%,calc(860px * var(--s)))}
.donate .row-head{grid-template-columns:minmax(0,1fr) minmax(0,2fr)}
.rank.r-s .letter{color:#f5c542}.rank.r-a .letter{color:#ff6db3}.rank.r-b .letter{color:#6dacf8}.rank.r-c .letter{color:var(--osd)}
.rank.r-d .letter,.rank.r-e .letter,.rank.r-f .letter{color:#c9d1dc}
.donate .cta-row{align-items:center;margin-top:.4em}
.donate .cta-row .hint{margin:0}
@media (max-width:767px){
  .onair{flex-direction:column;gap:calc(10px * var(--s))}
  .onair .logo{width:min(96%,calc(420px * var(--s)))}
  .onair-side{max-width:100%}
}
@media (prefers-reduced-motion:reduce){.ghost{opacity:0 !important}}

/* ── The game's own buttons: battle_button.tscn's nine-patch (15px margins) in the VCR face ── */
@font-face{font-family:'Early GameBoy';src:url('../fonts/EarlyGameBoy.ttf') format('truetype');font-weight:400;font-style:normal;font-display:swap}
@font-face{font-family:'easvhs';src:url('../fonts/easvhs.ttf') format('truetype');font-weight:400;font-style:normal;font-display:swap}
body.tape .deck button,body.tape .btn-rec,body.tape .btn-ghost-tape,body.tape .slide-nav{
  --bw:round(calc(6px * var(--s)), 1px);
  font-family:'Early GameBoy','easvhs',var(--font-osd);font-weight:400;letter-spacing:.04em;text-transform:uppercase;
  color:#f3e2c4;background:#612721;background-clip:border-box;border:var(--bw) solid transparent;border-image:url('../images/ui/button_main.png') 15 fill stretch;   /* the fill colour under the nine pieces: the hairline gaps between them at fractional sizes show the button, not the wood behind it */
  image-rendering:auto;border-image-repeat:stretch;border-radius:0;box-shadow:none;text-shadow:2px 2px 0 rgba(0,0,0,.55);transition:none;transform:none;
}
body.tape .deck button{font-size:calc(12px * var(--s));padding:.4em 1.1em}
body.tape .btn-rec{font-size:calc(12px * var(--s));padding:.4em 1.1em .4em .9em;gap:.55em}
body.tape .btn-rec.big{font-size:calc(15px * var(--s))}
body.tape .btn-ghost-tape{font-size:calc(11px * var(--s));padding:.45em 1.1em}
body.tape .slide-nav{font-size:calc(14px * var(--s))}
/* The lit key is a HOVER look, so only on things that can hover: a phone's tap leaves :hover stuck on the key it touched, and the
   white frame would stay lit after the press (Ryan). On touch the key lights only while it is held (:active, below). */
@media (hover:hover){
  body.tape .deck button:hover,body.tape .btn-rec:hover,body.tape .btn-ghost-tape:hover,body.tape .slide-nav:hover{border-image-source:url('../images/ui/button_selected.png');color:#fff;transform:none}
}
body.tape .deck button:focus-visible,body.tape .btn-rec:focus-visible{border-image-source:url('../images/ui/button_selected.png');color:#fff;transform:none}
body.tape .deck button:active,body.tape .deck button.down,body.tape .btn-rec:active,body.tape .btn-ghost-tape:active,body.tape .slide-nav:active{border-image-source:url('../images/ui/button_pressed.png');transform:translateY(2px)}
body.tape .btn-rec i{width:.6em;height:.6em;background:var(--rec);box-shadow:0 0 8px var(--rec)}

@media (max-width:767px){
  .card.split,.row-head{grid-template-columns:1fr}
  .ranks{grid-template-columns:repeat(4,minmax(0,1fr))}
}

/* ── The handheld (phones): smaller keys in the deck panel, single-column channels ── */
body.handheld .plate{gap:calc(4px * var(--s));padding:0 calc(6px * var(--s))}
body.handheld .deck{gap:calc(4px * var(--s))}
body.handheld .keys{gap:3px}
body.handheld .deck button{font-size:calc(7px * var(--s));padding:.3em .55em;--bw:round(calc(4px * var(--s)), 1px)}
body.handheld .plate .btn-rec{font-size:calc(7px * var(--s));padding:.3em .6em .3em .5em;--bw:round(calc(4px * var(--s)), 1px);gap:.4em}
body.handheld .plate .btn-rec i{width:.5em;height:.5em}
body.handheld .hole-osd{font-size:calc(16px * var(--s));top:calc(12px * var(--s))}
body.handheld .hole-osd.left{left:calc(14px * var(--s))}
body.handheld .hole-osd.right{right:calc(14px * var(--s))}
body.handheld .channel{padding:calc(36px * var(--s)) calc(12px * var(--s)) calc(28px * var(--s))}
body.handheld .card,body.handheld .card.split,body.handheld .card.wide{max-width:100%}
body.handheld .card.split,body.handheld .row-head,body.handheld .deckcard{grid-template-columns:1fr}
body.handheld .onair{flex-direction:column}
body.handheld .onair .logo{width:min(96%,calc(300px * var(--s)))}
body.handheld .onair-side{max-width:100%}
body.handheld .tapes{grid-template-columns:repeat(5,minmax(0,1fr))}
body.handheld .ranks{grid-template-columns:repeat(4,minmax(0,1fr))}
.card.story2.slides.ranks-mobile{display:none}   /* the stepper is the phone's only: on a desktop the grid card stands alone */
body.handheld .card.donate{display:none}
body.handheld .card.story2.slides.ranks-mobile{display:grid;grid-template-rows:auto auto auto auto;text-align:center}
.ranks-mobile .slide{align-items:center}
.ranks-mobile .letter{font-family:var(--font-display);font-size:calc(var(--t) * 4.2);line-height:1;color:#fff;text-shadow:3px 3px 0 rgba(0,0,0,.6);margin-bottom:calc(2px * var(--s))}
.ranks-mobile .letter.r-s{color:#f5c542}.ranks-mobile .letter.r-a{color:#ff6db3}.ranks-mobile .letter.r-b{color:#6dacf8}.ranks-mobile .letter.r-c{color:var(--osd)}
.ranks-mobile .letter.r-d,.ranks-mobile .letter.r-e,.ranks-mobile .letter.r-f{color:#c9d1dc}
.ranks-mobile .line{max-width:34ch;margin:0 auto}
.ranks-mobile .cta-row{grid-area:4 / 1;display:flex;flex-direction:column;align-items:center;gap:calc(6px * var(--s));margin-top:calc(8px * var(--s))}
.ranks-mobile .cta-row .hint{margin:0}
body.handheld .tapedeck{margin:0 auto}
body.handheld .ticker{height:calc(14px * var(--s));font-size:calc(11px * var(--s))}
body.handheld .track-meter{font-size:calc(13px * var(--s));bottom:calc(22px * var(--s))}
body.handheld .ghost iframe{width:max(100%,calc(100% * 16 / 9 * 960 / 540));height:100%}
/* Broadcast (channel 04): the trailer IS the picture, so it is drawn straight, not screened into the static */
.ghost.broadcast iframe{mix-blend-mode:normal;filter:saturate(.9) contrast(1.04)}

/* Channel 01, The Story: set in LINE Seed JP (Ryan's pick) */
.channel[data-ch="01"] .title,.channel[data-ch="01"] .body,.channel[data-ch="01"] .body .hook{font-family:var(--font-body);font-weight:700}
.channel[data-ch="01"] .body p{font-weight:400}
.channel[data-ch="01"] .title{letter-spacing:-.01em;line-height:1.08}

/* ── The Story: a guide card — one headline, four labelled facts, stacked evenly ── */
.card.story{display:flex;flex-direction:column;gap:calc(10px * var(--s));max-width:min(100%,calc(720px * var(--s)));font-family:var(--font-body)}
.card.story .headline{margin:0;font-family:var(--font-body);font-weight:700;font-size:calc(10px + 9px * var(--s));line-height:1.15;color:#fff;text-wrap:balance;letter-spacing:-.01em;text-shadow:2px 2px 0 rgba(0,0,0,.6)}
.card.story .grid{display:grid;grid-template-columns:1fr 1fr;gap:calc(8px * var(--s)) calc(14px * var(--s))}
.card.story .tile{border-left:2px solid var(--osd-dim);padding:calc(2px * var(--s)) 0 calc(2px * var(--s)) calc(10px * var(--s))}
.card.story .lbl{margin:0 0 .15em;font-family:var(--font-osd);font-size:calc(13px * var(--s));letter-spacing:.08em;color:var(--osd);text-shadow:0 0 6px rgba(143,227,160,.35)}
.card.story .line{margin:0;font-size:var(--t);line-height:1.45;color:var(--ink)}
body.handheld .card.story .grid{grid-template-columns:1fr}

/* ── The Story, two parts: headline, rule, then Star Corp | Your Goal ── */
.card.story2{display:flex;flex-direction:column;gap:calc(12px * var(--s));max-width:min(100%,calc(740px * var(--s)));padding:calc(20px * var(--s)) calc(26px * var(--s));font-family:var(--font-body)}
.card.story2 .headline{margin:0;padding-bottom:calc(10px * var(--s));border-bottom:1px solid var(--panel-edge);font-family:var(--font-body);font-weight:700;font-size:calc(11px + 10px * var(--s));line-height:1.15;color:#fff;text-align:center;text-wrap:balance;letter-spacing:-.01em;text-shadow:2px 2px 0 rgba(0,0,0,.6)}
.card.story2 .two{display:grid;grid-template-columns:1fr 1fr;gap:0 calc(28px * var(--s))}
.card.story2 .part{position:relative;padding:calc(2px * var(--s)) 0}
.card.story2 .part + .part{border-left:1px solid var(--panel-edge);padding-left:calc(28px * var(--s));margin-left:calc(-14px * var(--s))}
.card.story2 .lbl{margin:0 0 .35em;font-family:var(--font-osd);font-size:calc(15px * var(--s));letter-spacing:.08em;color:var(--osd);text-shadow:0 0 6px rgba(143,227,160,.35)}
.card.story2 .line{margin:0;font-size:calc(var(--t) * 1.08);line-height:1.5;color:var(--ink)}
/* The handheld: a tighter card (smaller headline, less padding) so the whole story fits inside the picture */
body.handheld .deckread{padding:calc(10px * var(--s)) calc(12px * var(--s))}
body.handheld .deckread .title{font-size:calc(9px + 10px * var(--s))}
body.handheld .deckread .desc{font-size:calc(var(--t) * 1.12);line-height:1.42}   /* back to its first size: bigger, the shelf under it was cropped by the bezel (Ryan) */
.deckread .desc *{font-size:inherit!important}   /* pasted rich text carries a fixed px size: the readout reads one size, idle or playing (Ryan) */
body.handheld .card.story2{padding:calc(12px * var(--s)) calc(14px * var(--s));gap:calc(8px * var(--s));max-height:100%}
body.handheld .card.story2 .headline{font-size:calc(9px + 8px * var(--s));padding-bottom:calc(7px * var(--s));line-height:1.12}
body.handheld .card.story2 .lbl{font-size:calc(17px * var(--s));margin-bottom:.2em}
body.handheld .card.story2 .line{font-size:var(--t);line-height:1.42}
body.handheld .card.story2 .two{grid-template-columns:1fr;gap:calc(8px * var(--s))}
body.handheld .card.story2.grid4 .part:nth-child(even){border-left:0;padding-left:0;margin-left:0}
body.handheld .card.story2.grid4 .part + .part{border-top:1px solid var(--panel-edge);padding-top:calc(9px * var(--s))}
body.handheld .card.story2 .part + .part{border-left:0;border-top:1px solid var(--panel-edge);padding-left:0;margin-left:0;padding-top:calc(9px * var(--s))}
body.handheld .shots{grid-template-columns:1fr 1fr;height:auto;width:100%;aspect-ratio:auto;align-content:center}
body.handheld .shot{aspect-ratio:16/9}
