/* CableBox — the TeleKit 25 console (an idealized Heathkit 25), a converter box on top, and what shows in the glass.
   Everything is sized in cqw (1cqw = 1% of the scene width) so the set scales as one object. */

:root { --w: min(96vw, 130vh); --w: min(96vw, 130svh); }   /* svh: the viewport with the browser's bars showing */
* { box-sizing: border-box; }
html, body { height: 100%; }
body {
  margin: 0; background: #0b0907; color: #ddd; overflow: hidden;
  font-family: system-ui, -apple-system, "Helvetica Neue", sans-serif;
}
.room {
  width: 100%; height: 100vh; height: 100svh; display: flex; align-items: center; justify-content: center;
  padding: env(safe-area-inset-top) env(safe-area-inset-right) env(safe-area-inset-bottom) env(safe-area-inset-left);
  background: radial-gradient(ellipse at 50% 20%, #1e1712 0%, #0b0907 60%);
}
:fullscreen .room, :-webkit-full-screen .room { height: 100vh; }
.scene { width: var(--w); container-type: inline-size; position: relative; }


/* ---------------- The tube ----------------
   Positioned over the photograph's glass and clipped to its traced outline. The photo's own dead tube shows through
   when the set is off; when on, it is black behind the picture. */
.glass {
  position: absolute; left: 12.573%; top: 18.652%; width: 54.788%; height: 63.708%; overflow: hidden;
  background: transparent; transition: background .35s; z-index: 1;
}
.glass.on, .glass.warming, .glass.cooling { background: #030303; }
/* The photograph's own bezel ring laid back over the picture: tube cut out, edge feathered toward black. */
.bezel { position: absolute; left: 7.687%; top: 12.921%; width: 64.625%; height: 75.281%; z-index: 2; pointer-events: none; }
.glass.warming::before { /* CRT turn-on: a line that blooms into the picture */
  content: ""; position: absolute; left: 6%; right: 6%; top: 50%; height: 0.3cqw; background: #dfe9ff;
  box-shadow: 0 0 2cqw #cfe0ff, 0 0 4cqw #9ab8ff; transform: translateY(-50%);
  animation: bloom .75s ease-out forwards;
}
@keyframes bloom {
  0% { transform: translateY(-50%) scaleX(0); opacity: 1; }
  35% { transform: translateY(-50%) scaleX(1); opacity: 1; }
  100% { transform: translateY(-50%) scaleX(1) scaleY(120); opacity: 0; }
}
.glass.cooling::before { /* CRT turn-off: the picture collapses to a line, the line to a dot, the dot fades */
  content: ""; position: absolute; left: 6%; right: 6%; top: 50%; height: 0.3cqw; background: #dfe9ff;
  box-shadow: 0 0 2cqw #cfe0ff, 0 0 4cqw #9ab8ff; transform: translateY(-50%);
  animation: collapse .95s ease-in forwards;
}
@keyframes collapse {
  0% { transform: translateY(-50%) scaleX(1) scaleY(120); opacity: .95; }
  30% { transform: translateY(-50%) scaleX(1) scaleY(1); opacity: 1; }
  70% { transform: translateY(-50%) scaleX(.03) scaleY(1); opacity: 1; }
  100% { transform: translateY(-50%) scaleX(.01) scaleY(.6); opacity: 0; }
}

/* Picture area: inset so its corners sit inside the tube's rounded corners. Never covered by anything.
   The player runs at 16:9 sized to the tube's HEIGHT and overflows the sides, like CRT overscan: a native 4:3 upload
   fills the tube exactly, a 16:9 upload with the 4:3 broadcast pillarboxed inside it also fills exactly (the black
   pillars land behind the bezel), and a true 16:9 picture loses a sliver at each edge. */
.raster { position: absolute; inset: 0; background: #000; overflow: hidden; transition: inset .65s cubic-bezier(.2,.75,.2,1); }   /* to the glass edge; the tube's radius clips the corners */
/* The squeeze: for a song's first and last seconds the picture eases toward the top right and the chyron sits in the
   black it leaves behind. Nothing is drawn over the player. */
.glass.squeeze .raster { inset: 0 0 21% 24%; }
.lower-third {
  position: absolute; left: 9%; bottom: 9%; max-width: 62%; color: #fff; opacity: 0; pointer-events: none;
  font-family: Poppins, "Helvetica Neue", Arial, sans-serif; font-weight: 700; line-height: 1.15; text-align: left;
  text-shadow: 0.14cqw 0.14cqw 0 #000, 0 0 0.7cqw rgba(0,0,0,.85); transition: opacity .35s ease .3s;
}
.glass.squeeze .lower-third { opacity: 1; }
.lt-artist { font-size: 2.2cqw; letter-spacing: 0.02cqw; }
.lt-song { font-size: 1.9cqw; font-weight: 600; font-style: italic; }
.lt-year { font-size: 1.45cqw; font-weight: 600; opacity: .9; margin-top: 0.15cqw; }
.glass.guide-mode .lower-third, .glass.guide-only .lower-third { display: none; }
#yt { pointer-events: none;   /* the picture never takes a click: television does not pause, and YouTube's pause bezel never appears */ position: absolute; top: -5.62%; left: -16.665%; height: 111.23%; width: 133.33%; display: block; border: 0; }   /* a 4:3 picture fills the tube's width; the bowed glass crops the rest. No transform: WebKit paints transformed iframes offset. */
.glass.off .raster, .glass.warming .raster, .glass.cooling .raster, .glass.snow .raster, .glass.standby .raster, .glass.offair .raster { visibility: hidden; }

.static { position: absolute; inset: 0; width: 100%; height: 100%; display: none; image-rendering: pixelated; }
.glass.snow .static { display: block; }
.scrambled { position: absolute; inset: 0; width: 100%; height: 100%; display: none; }
.glass.scramble .scrambled { display: block; }
.glass.scramble .raster { visibility: hidden; }

.standby {
  position: absolute; inset: 0; display: none; align-items: center; justify-content: center; text-align: center;
  background: radial-gradient(ellipse at 50% 50%, #274a7a, #10203a 75%);
  color: #f3e6b0; font: 700 5cqw/1.05 Cinzel, Georgia, serif; letter-spacing: 0.4cqw; text-shadow: 0 0.2cqw 0.6cqw #000;
}
.glass.standby .standby { display: flex; }

/* the text channels: the same character generator as the pledge slate */
.slate { position: absolute; inset: 0; display: none; flex-direction: column; background: #0a0aa4; color: #fff; font-family: VT323, monospace; text-transform: uppercase; }
.glass.weather .weather-slate, .glass.bulletin .board-slate { display: flex; }
.glass.weather .raster, .glass.bulletin .raster { visibility: hidden; }
.slate::after { content: ""; position: absolute; inset: 0; pointer-events: none; background: repeating-linear-gradient(to bottom, rgba(0,0,0,0) 0 .28cqw, rgba(0,0,0,.18) .28cqw .4cqw); }
.slate .sl-head { flex: 0 0 auto; margin: 3.5% 5% 0; padding: .5cqw 1.2cqw; background: #f2c81c; color: #101060; font-size: 2.2cqw; letter-spacing: .25cqw; text-align: center; }
.slate .sl-body { flex: 1; display: flex; flex-direction: column; justify-content: center; padding: 0 6%; gap: .6cqw; text-shadow: .15cqw .15cqw 0 #000; }
.slate .sl-now { display: flex; align-items: center; gap: 2cqw; margin-bottom: .6cqw; }
.slate .sl-temp { font-size: 7cqw; line-height: 1; color: #fff; }
.slate .sl-cond { font-size: 2.6cqw; line-height: 1.1; color: #f2c81c; }
.slate .sl-cond small { font-size: 1.5cqw; color: #b9c1ff; letter-spacing: .15cqw; }
.slate .sl-rows { display: flex; flex-direction: column; gap: .2cqw; border-top: .15cqw solid #4a52c8; padding-top: .6cqw; }
.slate .sl-row { display: grid; grid-template-columns: 12cqw 4.5cqw 1fr; font-size: 1.9cqw; letter-spacing: .12cqw; }
.slate .sl-row span:nth-child(2) { color: #f2c81c; text-align: right; padding-right: 1cqw; }
.slate .sl-big { font-size: 3.2cqw; text-align: center; letter-spacing: .2cqw; }
.slate .sl-sub { font-size: 2cqw; text-align: center; color: #f2c81c; letter-spacing: .25cqw; }
.slate .sl-board { gap: .9cqw; }
.slate .sl-item { font-size: 2cqw; line-height: 1.15; letter-spacing: .1cqw; padding-left: 1.6cqw; text-indent: -1.6cqw; }
.slate .sl-item::before { content: "▶ "; color: #f2c81c; }
.slate .sl-foot { flex: 0 0 auto; margin: 0 5% 1.2cqw; font-size: 1.3cqw; color: #b9c1ff; letter-spacing: .18cqw; text-align: center; white-space: nowrap; overflow: hidden; }
.slate .pl-bars { flex: 0 0 5%; background: linear-gradient(90deg, #c0c0c0 0 14.28%, #c0c000 0 28.57%, #00c0c0 0 42.85%, #00c000 0 57.14%, #c000c0 0 71.42%, #c00000 0 85.71%, #0000c0 0 100%); }
body.phone .slate .sl-head { font-size: 1.9cqw; } body.phone .slate .sl-temp { font-size: 6.2cqw; } body.phone .slate .sl-cond { font-size: 2.4cqw; } body.phone .slate .sl-cond small { font-size: 1.35cqw; }
body.phone .slate .sl-row { font-size: 1.75cqw; grid-template-columns: 11cqw 4cqw 1fr; } body.phone .slate .sl-item { font-size: 1.8cqw; } body.phone .slate .sl-foot { font-size: 1.1cqw; } body.phone .slate .sl-big { font-size: 2.8cqw; } body.phone .slate .sl-sub { font-size: 1.8cqw; }
/* the pledge slate: a cable operator's character generator, blue field, yellow bar, VT323 */
.pledge-slate { position: absolute; inset: 0; display: none; flex-direction: column; background: #0a0aa4; color: #fff; font-family: VT323, monospace; text-transform: uppercase; }
.glass.pledge .pledge-slate { display: flex; }
.glass.pledge .raster { visibility: hidden; }
.pledge-slate::after { content: ""; position: absolute; inset: 0; pointer-events: none; background: repeating-linear-gradient(to bottom, rgba(0,0,0,0) 0 .28cqw, rgba(0,0,0,.18) .28cqw .4cqw); }
.pledge-slate .pl-head { flex: 0 0 auto; margin: 5% 6% 0; padding: .6cqw 1.2cqw; background: #f2c81c; color: #101060; font-size: 2.3cqw; letter-spacing: .25cqw; text-align: center; }
.pledge-slate .pl-body { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: .4cqw; text-shadow: .15cqw .15cqw 0 #000; }
.pledge-slate .pl-line { font-size: 3.4cqw; letter-spacing: .2cqw; line-height: 1.05; }
.pledge-slate .pl-ask { margin-top: 2.2cqw; font-size: 2.2cqw; color: #f2c81c; letter-spacing: .25cqw; }
.pledge-slate .pl-phone { font-size: 3cqw; letter-spacing: .15cqw; }
.pledge-slate .pl-phone a { color: #fff; text-decoration: none; border-bottom: .25cqw solid #f2c81c; padding: 0 .3cqw; }
.pledge-slate .pl-phone a:hover { background: #f2c81c; color: #101060; }
.pledge-slate .pl-foot { margin-top: 2.6cqw; font-size: 1.6cqw; color: #b9c1ff; letter-spacing: .2cqw; }
.pledge-slate .pl-bars { flex: 0 0 5%; background: linear-gradient(90deg, #c0c0c0 0 14.28%, #c0c000 0 28.57%, #00c0c0 0 42.85%, #00c000 0 57.14%, #c000c0 0 71.42%, #c00000 0 85.71%, #0000c0 0 100%); }
/* phones: the scene is scaled up, so cqw runs large; pull the slate's type back in */
body.phone .pledge-slate .pl-head { font-size: 1.7cqw; margin-top: 3%; } body.phone .pledge-slate .pl-line { font-size: 2.5cqw; } body.phone .pledge-slate .pl-phone { font-size: 2.2cqw; } body.phone .pledge-slate .pl-ask { font-size: 1.6cqw; margin-top: 1.4cqw; } body.phone .pledge-slate .pl-foot { font-size: 1.2cqw; margin-top: 1.6cqw; }
.pledge-slate .pl-tap { display: none; } body.phone .pledge-slate .pl-tap { display: inline; } body.phone .pledge-slate .pl-key { display: none; }
.testpattern { position: absolute; inset: 0; display: none; flex-direction: column; background: #111; }
.glass.offair .testpattern { display: flex; }
.testpattern .bars { flex: 3; background: linear-gradient(90deg, #c0c0c0 0 14.28%, #c0c000 0 28.57%, #00c0c0 0 42.85%, #00c000 0 57.14%, #c000c0 0 71.42%, #c00000 0 85.71%, #0000c0 0 100%); }
.testpattern .bars2 { flex: 1; background: linear-gradient(90deg, #0000c0 0 14.28%, #131313 0 28.57%, #c000c0 0 42.85%, #131313 0 57.14%, #00c0c0 0 71.42%, #131313 0 85.71%, #c0c0c0 0 100%); }
.testpattern .signoff { flex: 1.2; display: flex; align-items: center; justify-content: center; color: #ddd; font: 2.4cqw/1 VT323, monospace; letter-spacing: 0.3cqw; background: #101010; }

/* ---------------- Guide (channel 1) ---------------- */
.glass.guide-mode { background: #0a0aa4; }
.glass.guide-mode .raster, .glass.guide-mode .static, .glass.guide-mode .standby, .glass.guide-mode .testpattern {
  inset: auto; top: 1.2cqw; left: 50%; transform: translateX(-50%);
  height: 200px; width: 267px;   /* the promo window, at YouTube's 200px floor so the grid gets the room */
}
.glass.guide-mode .standby { font-size: 2.6cqw; }
.glass.guide-mode .testpattern .signoff { font-size: 1.6cqw; }
.guide {
  position: absolute; left: 4%; right: 4%; top: calc(200px + 2cqw); bottom: 4%; display: none; flex-direction: column;
  background: #0a0aa4; color: #fff; font-family: VT323, "Courier New", monospace; font-size: 1.9cqw; line-height: 2.5cqw;
  border-top: 0.3cqw solid #0a0aa4;
}
.glass.guide-mode .guide { display: flex; }
.guide-head { display: grid; grid-template-columns: 10.5cqw repeat(4, 1fr); }
.grow { display: grid; grid-template-columns: 10.5cqw 1fr; }
.guide-head { background: #3d3de0; color: #fff; height: 2.9cqw; align-items: center; flex: none; }
.guide-head .gclock { color: #ffe600; padding-left: 0.6cqw; }
.guide-head div { padding-left: 0.5cqw; border-left: 0.15cqw solid #1c1cb8; overflow: hidden; white-space: nowrap; }
.guide-head div:first-child { border-left: 0; }
.guide-viewport { flex: 1; overflow: hidden; position: relative; --namew: 10.5cqw; --nowx: 0; }
.glass.guide-only .guide-viewport { --namew: 15cqw; }
.guide-rows { will-change: transform; }
.grow { height: 2.75cqw; align-items: stretch; border-top: 0.15cqw solid #2a2acc; }
.gtl { position: relative; overflow: hidden; background: repeating-linear-gradient(90deg, transparent 0 calc(25% - 0.15cqw), #2a2acc calc(25% - 0.15cqw) 25%); }   /* half-hour lines behind the cells */
.grow .gp { position: absolute; top: 0; bottom: 0; display: flex; align-items: center; box-sizing: border-box; }
.grow .gp.tiny { color: transparent; }
.grow .gch { color: #ffe600; padding-left: 0.6cqw; white-space: nowrap; overflow: hidden; display: flex; align-items: center; }
.grow .gch b { color: #fff; margin-right: 0.5cqw; font-weight: 400; }
.grow .gp { padding: 0 0.5cqw; border-left: 0.15cqw solid #2a2acc; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; background: #0a0aa4; }   /* opaque: a program that spans slots is one cell; the half-hour lines only show between programs */
.grow .gp.off { color: #8c8cff; }
.grow.bulletin { grid-template-columns: 1fr; background: #f2c81c; color: #14145e; height: 5.5cqw; }   /* the cable system's panel: yellow, dark text, two rows tall like the real ones */
.grow.bulletin .gbul { grid-column: 1 / -1; display: flex; align-items: center; padding: 0 1cqw; font-weight: 700; white-space: normal; line-height: 1.15; overflow: hidden; letter-spacing: 0.02cqw; }   /* spans every column, wraps to two lines */
.grow.spacer { background: #3d3de0; color: #fff; }
.grow.spacer .gch { color: #fff; grid-column: 1 / -1; text-align: center; }

/* Compact screens: the guide takes the whole tube, no promo window, larger type. */
.glass.guide-only .raster, .glass.guide-only .static, .glass.guide-only .standby, .glass.guide-only .testpattern { display: none; }
.glass.guide-only .guide { top: 4%; font-size: 3.1cqw; line-height: 3.9cqw; }
.glass.guide-only .guide-head { grid-template-columns: 15cqw repeat(4, 1fr); }
.glass.guide-only .grow { grid-template-columns: 15cqw 1fr; }
.glass.guide-only .guide-head { height: 4.2cqw; }
.glass.guide-only .grow { height: 4.5cqw; }
.glass.guide-only .grow.bulletin { height: 9cqw; }   /* the ad panel stays two rows tall on phones too */


/* ---------------- Cable box (photograph + our LED digits + hit targets) ---------------- */
.cablebox { position: relative; width: 44cqw; height: 10.918cqw; margin-left: 6cqw; margin-right: auto; margin-bottom: -2.2cqw; z-index: 2; }
.paper { /* this week's TV section, lying on the console to the right of the box (assets/paper-console-2.webp, keyed from Chris's render) */
  position: absolute; left: 63cqw; top: 2.2cqw; width: 18cqw; z-index: 3; transform: rotate(-2.5deg); transform-origin: 50% 100%; text-decoration: none;
}
.paper img { display: block; width: 100%; height: auto; filter: drop-shadow(0 .35cqw .5cqw rgba(0,0,0,.55)) drop-shadow(0 .05cqw .1cqw rgba(0,0,0,.6)); }
.paper:hover { transform: rotate(-2.2deg) translateY(-.15cqw); }
.paper:focus-visible { outline: .2cqw solid #ffd86a; }
.paper-under { display: none; }
body.phone .paper { display: none !important; }   /* the console is off-screen on phones; portrait gets the paper under the handset, landscape a tab */
body.phone.portrait.has-paper .paper-under { /* the folded section the handset is lying on: only the masthead shows (assets/paper-flat-2.webp) */
  display: block; position: fixed; left: 3%; right: 3%; bottom: 0; height: 120px; z-index: 4; transform: rotate(-1.6deg); transform-origin: 50% 100%;
  background: url(assets/paper-flat-2.webp) no-repeat center 0 / 100% auto; filter: drop-shadow(0 -2px 8px rgba(0,0,0,.45));
}
body.phone.portrait .remote { bottom: auto; z-index: 5; }   /* the handset ends at its keypad and lies on top of the paper */
.box-photo { display: block; width: 100%; height: auto; filter: drop-shadow(0 0.6cqw 1cqw rgba(0,0,0,.5)); }
.hit { position: absolute; border: 0; padding: 0; background: transparent; color: transparent; font-size: 0; cursor: pointer; border-radius: 0.3cqw; outline: 0; }
.hit:focus-visible { box-shadow: 0 0 0 0.2cqw #ffd86a; }
.hit:active { background: rgba(0,0,0,.28); }
.cb-power { left: 3.13%; top: 35.89%; width: 8.42%; height: 32.59%; }
.cb-zoom  { left: 12.98%; top: 35.89%; width: 8.01%; height: 32.59%; }
.cb-power::before { /* covers the photo's LED when the box is off; glows when it is on */
  content: ""; position: absolute; left: 50%; top: 24%; width: 13%; aspect-ratio: 1; border-radius: 50%; transform: translateX(-50%);
  background: #ff3b1f; box-shadow: 0 0 0.5cqw #ff3b1f;
}
/* Set off: the LED itself breathes gold, slowly. Nothing else on the button lights up. */
body.power-off .cb-power::before { --led-glow: 0 0 0.7cqw 0.15cqw rgba(255,200,80,.85); animation: ledpulse 3.2s ease-in-out infinite; }
@keyframes ledpulse {
  0%, 100% { background: #2a0806; box-shadow: none; }
  50% { background: #ffcf5a; box-shadow: var(--led-glow); }
}
.cb-display { position: absolute; left: 22.63%; top: 31.23%; width: 13.65%; height: 43.07%; pointer-events: none; }
.seg { position: absolute; top: 15%; height: 70%; width: 30%; }
#seg0 { left: 20%; } #seg1 { left: 59%; }
.seg polygon { fill: transparent; }                      /* the photo already has the dark unlit segments */
.seg polygon.on { fill: #ff3419; filter: drop-shadow(0 0 0.28cqw rgba(255,60,30,.9)); }
body.power-off .seg polygon.on { fill: transparent; filter: none; }
/* The readout: a 14-segment marquee in a dark window over the box's flat panel, right of the keypad */
.cb-marquee {
  position: absolute; left: 71.6%; top: 31.2%; width: 25.6%; height: 38.5%; border-radius: 0.3cqw; background: #070000;   /* bottom edge stays clear of the CB-36 mark printed on the box */
  border: 0.22cqw solid #0a0a0b; box-shadow: inset 0 0 1.2cqw #000, 0 0 0 0.12cqw #2a2a2e;
  display: flex; align-items: center; justify-content: center; gap: 0.12cqw; padding: 0 0.35cqw; pointer-events: none; overflow: hidden;
}
.mq { width: calc((100% - 11 * 0.12cqw) / 12); height: auto; flex: none; }   /* twelve cells sized to the window's width */
.mq polygon { fill: #2b0906; }
.mq polygon.on { fill: #ff3419; filter: drop-shadow(0 0 0.22cqw rgba(255,60,30,.9)); }
body.power-off .mq polygon.on { fill: #2b0906; filter: none; }
.cb-keys .hit { left: calc(39.05% + var(--c) * 7.643%); top: calc(31.82% + var(--r) * 14.665%); width: 7.08%; height: 12.34%; }

/* ---------------- The set (photograph + our overlays) ---------------- */
.set { position: relative; width: 100cqw; height: 57.981cqw; }
.set-photo { display: block; width: 100%; height: 100%; filter: drop-shadow(0 1.5cqw 2.5cqw rgba(0,0,0,.7)); }
.screen-zone { position: absolute; left: 5.5%; top: 8.98%; width: 69%; height: 81.85%; pointer-events: none; }   /* bezel and surround; what zoom shows */
.badge {
  position: absolute; left: 77.3%; top: 10.4%; width: 18.2%; height: 2.5%; display: flex; align-items: center; justify-content: center;
  color: #e6e6e6; font: 600 1.05cqw/1 Cinzel, "Copperplate", serif; letter-spacing: 0.34cqw; pointer-events: none;
  text-shadow: 0 0 0.3cqw rgba(255,255,255,.25);
}
.badge span { margin-left: 0.85cqw; font-size: 1.3cqw; letter-spacing: 0.08cqw; font-style: italic; }
.dial { position: absolute; width: 6.3%; aspect-ratio: 1; left: 79.05%; top: 16.37%; pointer-events: none; }
.dial.vhf { left: 87.25%; top: 16.27%; }
.dial svg { width: 100%; height: 100%; }
.dial .ring { fill: none; stroke: none; }
.dial text { fill: #f4f4f4; font: 700 7.6px system-ui, sans-serif; text-anchor: middle; paint-order: stroke; stroke: rgba(0,0,0,.7); stroke-width: 1.4px; }
.logo { position: absolute; left: 84.6%; top: 31.7%; width: 3.2%; display: flex; flex-direction: column; align-items: center; pointer-events: none; }
.logo svg { width: 100%; height: auto; }
.logo span { font: 700 1.2cqw/1 "Arial Black", Impact, sans-serif; color: #f7e23a; text-shadow: 0 0.08cqw 0 #6b5220; margin-top: -0.2cqw; }
.knob-label { position: absolute; left: var(--x); top: var(--y); transform: translate(-50%, -50%); font: 600 1.25cqw/1 "Dancing Script", cursive; color: #241d0c; white-space: nowrap; pointer-events: none; text-shadow: 0 0 0.2cqw rgba(255,240,200,.5); }
.knob-hit { left: 83.56%; top: 38.4%; width: 5%; height: 8.62%; border-radius: 50%; }

/* Zoom: the set is laid out larger than the window and shifted so only the picture side shows. Real pixels, not a scale. */
body.zoom { overflow: hidden; }
body.zoom .room { display: block; position: relative; overflow: hidden; }
body.zoom .scene { position: absolute; }
body.zoom .hint { display: none; }
body.zoom .cablebox, body.zoom .paper, body.zoom .knob-hit { visibility: hidden; }
body.zoom:not(.phone) .badge, body.zoom:not(.phone) .dial, body.zoom:not(.phone) .logo, body.zoom:not(.phone) .knob-label { visibility: hidden; }   /* desktop zoom crops the panel; phones show it whole, so the badge and dial labels stay */
.zoom-controls { display: none; position: fixed; right: 1rem; bottom: 1rem; gap: .4rem; z-index: 5; }
body.zoom .zoom-controls { display: flex; }
.zoom-controls button {
  min-width: 2.8rem; height: 2.2rem; padding: 0 .7rem; border: 0; border-radius: .35rem; cursor: pointer; color: #ddd;
  font: 600 .8rem/1 system-ui, sans-serif; background: rgba(40,40,44,.85); box-shadow: 0 2px 0 #0c0c0e; backdrop-filter: blur(4px);
}
.zoom-controls button:active { transform: translateY(1px); }

.hint { margin-top: 1.2cqw; text-align: center; color: #5a5048; font-size: 1.15cqw; letter-spacing: 0.04cqw; }
.hint .about { color: #8a7d6e; text-decoration: underline; text-underline-offset: .2cqw; margin-left: .6cqw; }
.hint .about:hover { color: #ffd86a; }
.hint.hidden { visibility: hidden; }

/* Small screens: let it scroll rather than crush. */
/* ---------------- Phones: the phone is the remote ----------------
   body.phone is set by script (coarse pointer and a small viewport). The tube fills the screen (landscape: by height;
   portrait: by width, with the remote below). The zoom rules do the heavy lifting; these add the remote. */
#safeProbe { position: fixed; top: 0; left: 0; width: 0; height: 0; padding-top: env(safe-area-inset-top); visibility: hidden; }
body.phone .zoom-controls, body.phone .hint { display: none; }
.remote {
  display: none; position: fixed; left: 0; right: 0; bottom: 0; z-index: 6; flex-direction: column; gap: 10px;
  padding: 12px 14px calc(12px + env(safe-area-inset-bottom)); font-family: system-ui, -apple-system, sans-serif;
  background: linear-gradient(#27272c, #121215); box-shadow: 0 -6px 18px rgba(0,0,0,.6);
}
body.phone.portrait .remote { display: flex; }
body.phone.landscape .remote.open {
  display: grid; grid-template-columns: auto 1fr; grid-template-areas: "mq mq" "top grid"; align-items: center; gap: 8px 10px;
  padding: 8px 12px calc(8px + env(safe-area-inset-bottom));
}
body.phone.landscape .rm-marquee { grid-area: mq; height: 38px; }
body.phone.landscape .rm-marquee .mq { max-height: 26px; }
body.phone.landscape .rm-top { grid-area: top; }
body.phone.landscape .rm-grid { grid-area: grid; }
.rm-top { display: grid; grid-template-columns: 1fr 1.3fr 1fr; gap: 10px; }
.rm-marquee {
  height: 46px; border-radius: 6px; background: #070000; border: 3px solid #0a0a0b; box-shadow: inset 0 0 12px #000, 0 0 0 1px #2a2a2e;
  display: flex; align-items: center; justify-content: center; gap: 2px; padding: 0 8px;
}
.rm-marquee .mq { width: calc((100% - 15 * 2px) / 16); max-height: 30px; height: auto; }
.rm-marquee .mq polygon.on { filter: drop-shadow(0 0 3px rgba(255,60,30,.9)); }
body.phone.landscape .rm-top { grid-template-columns: auto auto auto; flex: none; }
.rm-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; }
body.phone.landscape .rm-grid {
  grid-template-columns: repeat(6, 1fr); gap: 8px; flex: 1;
  grid-template-areas: "k1 k2 k3 k4 k5 up" "k6 k7 k8 k9 k0 down";   /* digits in two rows, channel up over channel down at the far right */
}
body.phone.landscape .rm-key[data-key="1"] { grid-area: k1; } body.phone.landscape .rm-key[data-key="2"] { grid-area: k2; } body.phone.landscape .rm-key[data-key="3"] { grid-area: k3; }
body.phone.landscape .rm-key[data-key="4"] { grid-area: k4; } body.phone.landscape .rm-key[data-key="5"] { grid-area: k5; } body.phone.landscape .rm-key[data-key="6"] { grid-area: k6; }
body.phone.landscape .rm-key[data-key="7"] { grid-area: k7; } body.phone.landscape .rm-key[data-key="8"] { grid-area: k8; } body.phone.landscape .rm-key[data-key="9"] { grid-area: k9; }
body.phone.landscape .rm-key[data-key="0"] { grid-area: k0; } body.phone.landscape .rm-key[data-key="up"] { grid-area: up; } body.phone.landscape .rm-key[data-key="down"] { grid-area: down; }
.rm-key {
  min-height: 54px; border: 0; border-radius: 8px; color: #eee; cursor: pointer; padding: 0 10px;
  font: 600 20px/1 system-ui, -apple-system, sans-serif; background: linear-gradient(#55555b, #2e2e33); box-shadow: 0 3px 0 #0c0c0e;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px; -webkit-tap-highlight-color: transparent;
}
body.phone.landscape .rm-key { min-height: 44px; font-size: 17px; }
.rm-key small { font-size: 10px; letter-spacing: 1px; color: #d7b45a; font-weight: 700; }
.rm-key:active { transform: translateY(2px); box-shadow: 0 1px 0 #0c0c0e; }
.rm-key.ch { background: linear-gradient(#6a5a2a, #3b3116); color: #ffe9a8; font-size: 16px; }
.rm-key.rm-power, .rm-key.rm-set { background: linear-gradient(#3a3a40, #1a1a1e); font-size: 12px; letter-spacing: 1.5px; }
.rm-key.rm-power { color: #f3d9a0; position: relative; padding-top: 10px; }
.rm-key.rm-power::before { content: ""; position: absolute; top: 7px; left: 50%; width: 8px; height: 8px; border-radius: 50%; transform: translateX(-50%); background: #ff3b1f; box-shadow: 0 0 6px #ff3b1f; }
body.power-off .rm-key.rm-power::before { --led-glow: 0 0 8px 2px rgba(255,200,80,.85); animation: ledpulse 3.2s ease-in-out infinite; }
.rm-key.rm-set { color: #cfd4e0; }
body.phone.portrait .rm-set { display: none; }                 /* portrait is always the tube; SET only exists in landscape */
.rm-key.rm-paper { display: none; text-decoration: none; text-align: center; line-height: 1.1; font-size: 11px; letter-spacing: 1.5px; color: #2a241c; background: linear-gradient(#efe8d6, #cfc6ae); box-shadow: 0 2px 0 #8c8470, inset 0 0 14px rgba(60,40,20,.22); }
body.phone.portrait .rm-paper { display: flex; align-items: center; justify-content: center; grid-column: 3; }   /* the paper takes SET's slot in portrait; landscape has the tab */
body.phone.portrait .rm-display { grid-column: 2; }
.rm-display { background: #070000; border: 3px solid #0a0a0b; border-radius: 6px; display: flex; justify-content: center; align-items: center; gap: 8px; padding: 4px 8px; box-shadow: inset 0 0 12px #000, 0 0 0 1px #2a2a2e; }
.rm-display .seg { position: static; height: 42px; width: 25px; }
body.phone.landscape .rm-display .seg { height: 34px; width: 20px; }
.rm-display .seg polygon { fill: #2b0906; }
.rm-display .seg polygon.on { fill: #ff3419; filter: drop-shadow(0 0 3px rgba(255,60,30,.9)); }
body.power-off .rm-display .seg polygon.on { fill: #2b0906; filter: none; }
.rm-toggle {
  display: none; position: fixed; right: 12px; bottom: calc(12px + env(safe-area-inset-bottom)); z-index: 6; height: 40px; padding: 0 14px; border: 0; border-radius: 8px;
  color: #ddd; font: 700 12px/1 system-ui, sans-serif; letter-spacing: 1.5px; background: rgba(40,40,44,.85); box-shadow: 0 2px 0 #0c0c0e; backdrop-filter: blur(4px);
}
body.phone.landscape .rm-toggle { display: block; }
.paper-tab { /* landscape phones: the folded section, tucked at the bottom left */
  display: none; position: fixed; left: 12px; bottom: calc(12px + env(safe-area-inset-bottom)); z-index: 6; height: 40px; padding: 0 14px; line-height: 40px; border-radius: 8px; text-decoration: none;
  color: #2a241c; font: 700 12px/40px "Roboto Condensed", "Arial Narrow", system-ui, sans-serif; letter-spacing: 1.5px; background: #e6dfcc; box-shadow: 0 2px 0 #8c8470, inset 0 0 18px rgba(60,40,20,.25); transform: rotate(-2deg);
}
body.phone.landscape .paper-tab { display: block; }
body.phone.landscape .remote.open ~ .paper-tab { display: none; }
/* the paper held up over the set */
.paperlift { position: fixed; inset: 0; z-index: 40; background: rgba(8,6,4,.62); display: flex; align-items: center; justify-content: center; }
.paperlift[hidden] { display: none; }
.paperlift-sheet { position: relative; width: min(96vw, 1300px); height: min(94vh, 1260px); animation: paperup .28s ease-out; }
.paperlift iframe { display: block; width: 100%; height: 100%; border: 0; background: #241f1b; border-radius: 3px; box-shadow: 0 24px 60px rgba(0,0,0,.7); }
.paperlift-close { position: absolute; top: 6px; right: 6px; width: 38px; height: 38px; border: 0; border-radius: 50%; background: #e6dfcc; color: #16120f; font: 700 18px/38px system-ui, sans-serif; cursor: pointer; box-shadow: 0 2px 6px rgba(0,0,0,.5); }
body.phone .paperlift-sheet { width: 100vw; height: 100vh; height: 100dvh; }
body.phone .paperlift iframe { border-radius: 0; }
@keyframes paperup { from { transform: translateY(6vh) rotate(-1.2deg); opacity: 0; } to { transform: none; opacity: 1; } }
body.phone.landscape .remote.open ~ .rm-toggle { display: none; }
@media (max-width: 700px) and (orientation: portrait) {
  body:not(.phone) { overflow: auto; }
  body:not(.phone) .room { height: auto; min-height: 100vh; min-height: 100svh; align-items: flex-start; padding-top: max(2vh, env(safe-area-inset-top)); }
}
