:root {
  --ink: #f4f6ff;
  --panel: rgba(8, 12, 26, .68);
  --line: rgba(255, 255, 255, .14);
  --hero: #7ec8f4;
  --red: #d82630;
  --gold: #f7d31e;
  --good: #3ee08a;
  --bad: #ff4d6a;
  --sl: env(safe-area-inset-left, 0px);
  --sr: env(safe-area-inset-right, 0px);
  --st: env(safe-area-inset-top, 0px);
  --sb: env(safe-area-inset-bottom, 0px);
}
* { box-sizing: border-box; margin: 0; padding: 0; }
html, body {
  height: 100%; overflow: hidden; background: #05070d; color: var(--ink);
  font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  touch-action: none; -webkit-user-select: none; user-select: none;
  -webkit-touch-callout: none; -webkit-tap-highlight-color: transparent;
  overscroll-behavior: none;
}
button { font: inherit; color: inherit; cursor: pointer; }
#game { position: fixed; inset: 0; overflow: hidden; }
#c2d, #three-host, #three-host canvas { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
#three-host { display: none; }
body.three #three-host { display: block; }
/* Full-screen cutscene (cutscene.js) */
#cutscene { position: absolute; inset: 0; z-index: 58; background: #000; display: none; cursor: pointer; }
#cutscene.on { display: block; animation: fade .4s; }
#cutscene video, #cutscene img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; }
#cutscene:not(.still) img, #cutscene.still video, #cutscene.bare video, #cutscene.bare img { display: none; }
#cutscene .cs-cap { position: absolute; left: 50%; bottom: calc(40px + var(--sb)); transform: translateX(-50%); width: min(720px, 90vw); text-align: center; font: 400 26px/1.25 "Bangers", Impact, sans-serif; letter-spacing: .04em; color: #fff; text-shadow: 0 2px 8px #000; }
#cutscene.bare .cs-cap { bottom: 50%; transform: translate(-50%, 50%); font-size: 34px; }
#cutscene .cs-skip { position: absolute; right: calc(16px + var(--sr)); bottom: calc(12px + var(--sb)); font-size: 11px; opacity: .5; }
#cutscene canvas.cs-screen { position: absolute; inset: 0; width: 100%; height: 100%; z-index: 1; }
#cutscene.screen .cs-cap, #cutscene.screen .cs-skip { z-index: 2; }
/* the clip stays rendered (invisibly): iOS won't decode frames of a display:none video */
#cutscene.screen video { display: block !important; opacity: 0; }
#cutscene.screen .cs-cap { bottom: calc(24px + var(--sb)); top: auto; transform: translateX(-50%); font-size: 22px; }
#cutscene.screen .cs-skip { opacity: .8; font: 400 15px "Bangers", Impact, sans-serif; letter-spacing: .06em; }
#club-loading { position: absolute; left: 50%; top: 58%; transform: translateX(-50%); width: min(320px, 70vw); display: none; z-index: 5; text-align: center; font-weight: 700; letter-spacing: .04em; color: #fff; text-shadow: 0 2px 6px #000a; }
#club-loading.on { display: block; }
#club-loading .lbl { font-size: 13px; margin-bottom: 6px; }
#club-loading .bar { height: 8px; border-radius: 4px; background: #ffffff26; overflow: hidden; }
#club-loading .bar i { display: block; height: 100%; width: 0; background: linear-gradient(90deg, #3fa9ff, #ff3f6c); transition: width .25s; }
body.three #c2d { display: none; }
#xray-tint, #intox-tint { position: absolute; inset: 0; pointer-events: none; opacity: 0; transition: opacity .25s; }
#xray-tint { background: radial-gradient(ellipse at center, rgba(40, 200, 255, .10), rgba(0, 60, 140, .45)); mix-blend-mode: screen; }
#xray-tint.on { opacity: 1; }
#intox-tint { background: radial-gradient(ellipse at center, rgba(255, 80, 180, 0) 35%, rgba(255, 60, 170, .55)); }

/* ---------- HUD ---------- */
#hud { position: absolute; inset: 0; pointer-events: none; }
body.title-on #hud, body.title-on #btns, body.title-on #touch { display: none !important; }
.panel { background: rgba(10, 10, 20, .74); border: 2px solid #050508; border-radius: 7px; box-shadow: 3px 3px 0 rgba(0, 0, 0, .55), inset 0 0 0 1px rgba(255, 255, 255, .09); }
#hud-left { position: absolute; left: calc(10px + var(--sl)); top: calc(10px + var(--st)); padding: 8px 11px 9px; width: 178px; }
.me { display: flex; align-items: center; gap: 8px; }
/* her face (herophotos.js): the expression follows her rep and the drink, the costume the act */
#hud-face { flex: none; width: 42px; height: 42px; border-radius: 50%; object-fit: cover; background: radial-gradient(circle at 50% 35%, #3f7ee0, #142a66); border: 2px solid var(--gold); box-shadow: 0 0 0 2px #050508; }
#hud-face:not([src]) { display: none; }
#hud-face.pop { animation: face-pop .35s cubic-bezier(.2, 1.7, .5, 1); }
@keyframes face-pop { from { transform: scale(.6) rotate(-8deg); } }
.rep { font: 400 24px/1 "Bangers", Impact, sans-serif; letter-spacing: .05em; }
.rep small { font-size: 11px; margin-left: 5px; opacity: .7; font-weight: 700; }
.rank { font-size: 10px; opacity: .85; text-transform: uppercase; letter-spacing: .12em; margin-top: 3px; color: var(--gold); }
.barlabel { font-size: 10px; opacity: .8; margin-top: 6px; display: flex; justify-content: space-between; text-transform: uppercase; letter-spacing: .06em; }
.bar { height: 7px; background: rgba(255, 255, 255, .12); border-radius: 4px; overflow: hidden; margin-top: 3px; }
.bar > i { display: block; height: 100%; width: 0; transition: width .15s linear; border-radius: 4px; }
.b-intox { background: linear-gradient(90deg, #ff9ad0, #ff3f9e); }
.b-vice { background: linear-gradient(90deg, #b88cff, #8b3dff); }
.b-hp { background: linear-gradient(90deg, #ff6a6a, #3ee08a); }
.b-en { background: linear-gradient(90deg, #4ac8ff, #a8ecff); }
.b-alert { background: linear-gradient(90deg, #ffd23f, #ff3030); }
.b-boss { background: linear-gradient(90deg, #ff3030, #ff9a3a); }
.bar.warn > i { animation: pulse .6s infinite alternate; }
@keyframes pulse { from { opacity: 1; } to { opacity: .45; } }
.barlabel.nil, .bar.nil { display: none; }
#lockouts { margin-top: 6px; font-size: 11px; color: #ffb3c6; }
#lockouts div { margin-top: 2px; }
#hud-top { position: absolute; left: 50%; top: calc(10px + var(--st)); transform: translateX(-50%); text-align: center; padding: 6px 14px; min-width: 150px; max-width: 46vw; }
#hud-title { font: 400 16px/1.1 "Bangers", Impact, sans-serif; letter-spacing: .06em; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
#hud-sub { font-size: 11px; opacity: .8; margin-top: 1px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
#hud-right { position: absolute; right: calc(10px + var(--sr)); top: calc(10px + var(--st)); display: flex; gap: 8px; align-items: flex-start; pointer-events: auto; }
/* Minimap corner; grows into a 16:9 video panel while a city-feed clip plays (cityfeed.js),
   with the map shrunk to an inset in its corner. */
#mapbox { position: relative; width: 128px; height: 128px; transition: width .35s ease, height .35s ease; }
#minimap { position: absolute; right: 0; top: 0; width: 100%; height: 100%; border-radius: 12px; border: 1px solid rgba(255, 255, 255, .3); background: #0a1020; cursor: pointer; z-index: 2; transition: width .35s ease, height .35s ease, top .35s ease, right .35s ease; }
body:not([data-mode="overworld"]):not([data-mode="club3"]) #mapbox, body[data-mode="club3"] #mapbox:not(.feed-on) { display: none; }
body[data-mode="club3"] #minimap { display: none; } /* (in the club the corner is only the LIVE feed, while she's high) */
body[data-mode="club3"] { --feedH: calc(min(340px, 34vw) * 9 / 16); }
body[data-mode="club3"]:has(#mapbox.feed-on) #objectives { top: calc(18px + var(--st) + var(--feedH)); }
body[data-mode="club3"]:has(#mapbox.feed-on) #c3-tip { top: calc(82px + var(--st) + var(--feedH)); }
#feed { position: absolute; inset: 0; border-radius: 12px; overflow: hidden; background: #000; border: 1px solid rgba(255, 255, 255, .35); box-shadow: 0 8px 30px rgba(0, 0, 0, .5); opacity: 0; pointer-events: none; transition: opacity .3s ease; cursor: pointer; }
#feed video, #feed img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
#feed:not(.still) img, #feed.still video { display: none; }
#feed.still img { animation: feedZoom 7s linear forwards; }
@keyframes feedZoom { from { transform: scale(1); } to { transform: scale(1.12); } }
#feed .feed-cap { position: absolute; left: 0; right: 0; bottom: 0; padding: 14px 8px 5px; font-size: 11px; font-weight: 800; letter-spacing: .04em; background: linear-gradient(to top, rgba(0, 0, 0, .75), rgba(0, 0, 0, 0)); display: flex; gap: 6px; align-items: baseline; }
#feed .feed-live { color: #ff4d6a; }
#feed.hot .feed-live { color: #ff5fd0; }
#feed .feed-x { position: absolute; top: 5px; right: 7px; font-size: 12px; opacity: .7; text-shadow: 0 1px 3px #000; }
#mapbox.feed-on { width: min(340px, 34vw); height: calc(min(340px, 34vw) * 9 / 16); }
#mapbox.feed-on #feed { opacity: 1; pointer-events: auto; }
#mapbox.feed-on #minimap { width: 58px; height: 58px; top: calc(100% + 6px); right: 0; opacity: .92; }
.iconbtn { width: 42px; height: 42px; border-radius: 12px; border: 1px solid var(--line); background: var(--panel); font-size: 13px; font-weight: 900; }
#objectives { position: absolute; right: calc(10px + var(--sr)); top: calc(62px + var(--st)); padding: 8px 11px; font-size: 12px; max-width: 250px; display: none; pointer-events: auto; cursor: pointer; }
#objectives.on { display: block; }
#objectives div { margin: 2px 0; opacity: .75; }
#objectives div.cur { opacity: 1; color: var(--gold); font-weight: 700; }
#objectives div.done { text-decoration: line-through; opacity: .45; }
#prompt { position: absolute; left: 50%; bottom: calc(22px + var(--sb)); transform: translateX(-50%); padding: 9px 16px; font-size: 13px; text-align: center; display: none; max-width: min(520px, 60vw); }
#prompt.on { display: block; }
#prompt b { color: var(--gold); }
#prompt .risk { display: inline-block; margin-left: 6px; padding: 1px 6px; border-radius: 6px; font-size: 10px; font-weight: 800; letter-spacing: .06em; }
#marker { position: absolute; left: 0; top: 0; width: 26px; height: 26px; margin: -13px 0 0 -13px; display: none; }
#marker.on { display: block; }
#marker::before { content: ""; position: absolute; inset: 3px; background: var(--gold); transform: rotate(45deg); border: 2px solid #fff; border-radius: 3px; box-shadow: 0 0 12px var(--gold); animation: pulse .7s infinite alternate; }
#marker span { position: absolute; top: 26px; left: 50%; transform: translateX(-50%); font-size: 10px; font-weight: 800; text-shadow: 0 1px 3px #000; white-space: nowrap; }

/* ---------- Touch controls ---------- */
#touch { position: absolute; inset: 0; pointer-events: none; display: none; }
body.touch #touch { display: block; }
#stick-zone { position: absolute; left: 0; bottom: 0; width: 46%; height: 62%; pointer-events: auto; touch-action: none; }
#stick-zone.off { display: none; }
/* Floating joystick: visible at its rest spot, jumps to the thumb, follows past the rim. */
#stick-base { position: absolute; left: calc(92px + var(--sl)); top: calc(100% - 100px - var(--sb)); width: 128px; height: 128px; transform: translate(-50%, -50%); border-radius: 50%; background: radial-gradient(circle, rgba(255, 255, 255, .04), rgba(255, 255, 255, .12)); border: 2px solid rgba(255, 255, 255, .3); opacity: .55; transition: opacity .15s; pointer-events: none; }
#stick-base::before { content: ""; position: absolute; inset: 10px; border-radius: 50%; border: 1px dashed rgba(255, 255, 255, .2); }
#stick-knob { position: absolute; left: 50%; top: 50%; width: 58px; height: 58px; transform: translate(-50%, -50%); border-radius: 50%; background: radial-gradient(circle at 35% 30%, rgba(190, 230, 255, .95), rgba(80, 160, 220, .75)); border: 2px solid rgba(255, 255, 255, .85); box-shadow: 0 4px 12px rgba(0, 0, 0, .4); }
#stick-zone.active #stick-base { opacity: 1; }
#fs-btn { display: none; }
body.touch #fs-btn { display: block; }
#btns { position: absolute; right: calc(14px + var(--sr)); bottom: calc(14px + var(--sb)); width: 290px; height: 220px; pointer-events: none; }
.tbtn { position: absolute; pointer-events: auto; touch-action: none; width: 70px; height: 70px; border-radius: 50%; border: 2px solid rgba(255, 255, 255, .45); background: rgba(10, 16, 34, .55); backdrop-filter: blur(4px); -webkit-backdrop-filter: blur(4px); display: flex; flex-direction: column; align-items: center; justify-content: center; font-weight: 900; font-size: 12px; letter-spacing: .04em; line-height: 1.05; text-align: center; }
.tbtn span { pointer-events: none; }
.tbtn kbd { display: none; font: 700 9px system-ui; opacity: .6; margin-top: 2px; pointer-events: none; }
body:not(.touch) .tbtn kbd { display: block; }
.tbtn.on, .tbtn:active { background: rgba(126, 200, 244, .6); transform: scale(.94); }
.tbtn.lit { border-color: var(--gold); box-shadow: 0 0 14px rgba(247, 211, 30, .7); }
.tbtn.toggled { background: rgba(60, 200, 255, .55); border-color: #bff; }
.tbtn.dim { opacity: .35; }
.tbtn.big { width: 86px; height: 86px; font-size: 14px; }
.tbtn.red { border-color: #ff8a8a; }
.slot0 { right: 6px; bottom: 16px; }
.slot1 { right: 104px; bottom: 6px; }
.slot2 { right: 16px; bottom: 116px; }
.slot3 { right: 100px; bottom: 96px; }
.slot4 { right: 190px; bottom: 6px; }
.slot5 { right: 184px; bottom: 92px; }
.big.slot0 { right: 0; bottom: 8px; }
body:not(.touch) #btns { transform: scale(.8); transform-origin: bottom right; }

/* ---------- Toasts, banners ---------- */
#toasts { position: absolute; left: 50%; top: calc(64px + var(--st)); transform: translateX(-50%); display: flex; flex-direction: column; align-items: center; gap: 6px; pointer-events: none; width: min(92vw, 520px); }
.toast { background: rgba(10, 10, 20, .96); border: 2px solid #050508; box-shadow: 3px 3px 0 rgba(0, 0, 0, .5); padding: 6px 12px; border-radius: 10px; font-size: 13px; font-weight: 600; animation: tin .25s ease-out; transition: opacity .4s, transform .4s; text-align: center; }
.toast.good { border-color: rgba(62, 224, 138, .6); color: #b9ffd9; }
.toast.bad { border-color: rgba(255, 77, 106, .6); color: #ffc2cc; }
.toast.out { opacity: 0; transform: translateY(-8px); }
@keyframes tin { from { opacity: 0; transform: translateY(-8px); } }
#banner { position: absolute; left: 0; right: 0; top: 34%; text-align: center; pointer-events: none; opacity: 0; font-weight: 900; font-size: clamp(26px, 6vw, 54px); letter-spacing: .04em; text-shadow: 0 4px 0 rgba(0, 0, 0, .5), 0 0 30px rgba(0, 0, 0, .6); }
#banner small { display: block; font-size: clamp(12px, 2.2vw, 18px); font-weight: 700; opacity: .9; margin-top: 4px; letter-spacing: .1em; }
#banner.show { animation: ban 2.2s ease-out forwards; }
@keyframes ban { 0% { opacity: 0; transform: scale(1.4); } 12% { opacity: 1; transform: scale(1); } 78% { opacity: 1; } 100% { opacity: 0; transform: translateY(-20px); } }
#flash { position: absolute; inset: 0; pointer-events: none; opacity: 0; background: #fff; }
#flash.go { animation: fl .6s ease-out; }
@keyframes fl { 0% { opacity: .95; } 100% { opacity: 0; } }

/* ---------- Modals & dialogs ---------- */
/* Dialogs must sit above everything, including the title screen. */
#modal-root { position: absolute; inset: 0; pointer-events: none; z-index: 60; }
#toasts, #banner { z-index: 55; }
#title { z-index: 40; }
.modal-back { position: absolute; inset: 0; background: rgba(2, 4, 12, .55); display: flex; align-items: center; justify-content: center; pointer-events: auto; padding: calc(12px + var(--st)) calc(12px + var(--sr)) calc(12px + var(--sb)) calc(12px + var(--sl)); animation: fade .2s; }
@keyframes fade { from { opacity: 0; } }
.modal { background: linear-gradient(180deg, #121a33, #0b1022); border: 1px solid rgba(126, 200, 244, .35); border-radius: 16px; padding: 18px 18px 14px; width: min(560px, 100%); max-height: 100%; overflow: auto; box-shadow: 0 20px 60px rgba(0, 0, 0, .6); touch-action: pan-y; }
.dlg.danger .modal { border-color: rgba(255, 77, 106, .6); background: linear-gradient(180deg, #2a0f1c, #120812); }
.dlg.villain .modal { border-color: rgba(57, 255, 106, .5); background: linear-gradient(180deg, #0f2416, #07120b); }
.modal h2 { font-size: 18px; letter-spacing: .04em; margin-bottom: 6px; color: var(--gold); }
.speaker { font-size: 12px; font-weight: 800; text-transform: uppercase; letter-spacing: .12em; color: var(--hero); margin-bottom: 6px; }
.dtext { font-size: 15px; line-height: 1.45; margin-bottom: 12px; }
.dtext em { color: #ffd6e8; }
.dtext .hint { display: block; margin-top: 8px; font-size: 13px; opacity: .8; font-style: italic; }
.opts { display: flex; flex-direction: column; gap: 7px; }
.opt { display: flex; align-items: center; gap: 10px; text-align: left; padding: 10px 12px; border-radius: 10px; border: 1px solid rgba(255, 255, 255, .16); background: rgba(255, 255, 255, .06); font-size: 14px; font-weight: 600; min-height: 44px; }
.opt:hover:not(:disabled) { background: rgba(126, 200, 244, .2); border-color: rgba(126, 200, 244, .6); }
.opt:disabled { opacity: .4; cursor: default; }
.opt .k { flex: none; width: 22px; height: 22px; border-radius: 6px; background: rgba(255, 255, 255, .12); display: grid; place-items: center; font-size: 11px; font-weight: 800; }
.opt small { display: block; font-size: 11px; opacity: .7; font-weight: 500; margin-top: 2px; }
.opt.risky { border-color: rgba(255, 95, 162, .5); }
.opt.bad { border-color: rgba(255, 77, 106, .6); }
.opt.good { border-color: rgba(62, 224, 138, .55); }
.portrait { float: right; margin: 0 0 6px 10px; }

/* Capture scene: dialogs become a compact caption bar along the bottom, so the room (and her)
   stay visible. The dim fades up from the bottom instead of covering the screen; the scene pans
   up a little while one is open (captured.js). Options sit side by side to keep it short. */
body[data-mode="captured"] .modal-back.dlg { align-items: flex-end; background: linear-gradient(to top, rgba(2, 4, 12, .85) 0%, rgba(2, 4, 12, .45) 28%, rgba(2, 4, 12, 0) 55%); }
body[data-mode="captured"] .dlg .modal { width: min(860px, 100%); max-height: 46%; padding: 12px 16px 12px; border-radius: 14px; background: rgba(9, 13, 26, .9); border: 1px solid rgba(255, 255, 255, .14); box-shadow: inset 4px 0 0 var(--gold), 0 -10px 40px rgba(0, 0, 0, .45); animation: capIn .22s ease-out; }
body[data-mode="captured"] .dlg.villain .modal { background: rgba(6, 22, 12, .9); box-shadow: inset 4px 0 0 #39ff6a, 0 -10px 40px rgba(0, 0, 0, .45); }
body[data-mode="captured"] .dlg.danger .modal { background: rgba(34, 8, 18, .92); box-shadow: inset 4px 0 0 #ff4d6a, 0 -10px 40px rgba(0, 0, 0, .45); }
body[data-mode="captured"] .dlg .modal h2 { display: inline-block; font-size: 15px; margin: 0 0 4px; }
body[data-mode="captured"] .dlg .speaker { display: inline-block; padding: 2px 9px; border-radius: 999px; background: rgba(255, 255, 255, .1); margin-bottom: 6px; }
body[data-mode="captured"] .dlg.villain .speaker { background: rgba(57, 255, 106, .16); color: #9dffb8; }
body[data-mode="captured"] .dlg .dtext { font-size: 14px; line-height: 1.4; margin-bottom: 9px; }
body[data-mode="captured"] .dlg .dtext .hint { font-size: 12px; margin-top: 5px; }
body[data-mode="captured"] .dlg .opts { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: 6px; }
body[data-mode="captured"] .dlg .opt { min-height: 40px; padding: 7px 10px; font-size: 13px; }
@keyframes capIn { from { transform: translateY(28px); opacity: 0; } }
@media (max-height: 460px) {
  body[data-mode="captured"] .dlg .modal { max-height: 60%; padding: 9px 12px 9px; }
  body[data-mode="captured"] .dlg .dtext { font-size: 13px; margin-bottom: 7px; }
  body[data-mode="captured"] .dlg .opt { min-height: 36px; padding: 5px 9px; }
}
.portrait canvas { width: 84px; height: 110px; border-radius: 10px; background: #0005; border: 1px solid var(--line); }
.portrait img.hero-face { display: block; width: 96px; height: 96px; border-radius: 50%; object-fit: cover; background: radial-gradient(circle at 50% 35%, #3f7ee0, #142a66); border: 3px solid var(--gold); box-shadow: 3px 3px 0 rgba(0, 0, 0, .5); }
.list { font-size: 13px; line-height: 1.5; margin-bottom: 12px; }
.list .item { padding: 8px 10px; background: rgba(255, 255, 255, .05); border-radius: 8px; margin-bottom: 6px; }
.list .item b { color: var(--gold); }
.chip { display: inline-block; font-size: 11px; padding: 1px 7px; border-radius: 10px; margin: 2px 3px 0 0; background: rgba(255, 255, 255, .1); }
.chip.match { background: rgba(62, 224, 138, .3); color: #cfffe3; }
.chip.miss { background: rgba(255, 77, 106, .25); color: #ffd0d8; text-decoration: line-through; }

/* keypad */
.keypad { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; max-width: 260px; margin: 0 auto; }
.keypad button { height: 54px; border-radius: 10px; border: 1px solid var(--line); background: rgba(255, 255, 255, .08); font-size: 20px; font-weight: 800; }
.keypad button:active { background: rgba(126, 200, 244, .4); }
.kp-screen { font: 800 30px ui-monospace, Consolas, monospace; letter-spacing: .4em; text-align: center; padding: 10px; margin: 0 auto 12px; max-width: 260px; border-radius: 10px; background: #041408; color: #39ff6a; border: 1px solid #1e5a2a; }
.qte-btn { display: block; width: 100%; height: 110px; border-radius: 16px; border: 2px solid #fff; background: linear-gradient(180deg, #ff4d6a, #b3122e); font-size: 28px; font-weight: 900; letter-spacing: .08em; margin-top: 10px; touch-action: manipulation; }
.qte-btn:active { transform: scale(.97); }

/* map */
.mapwrap { position: relative; }
.mapwrap canvas { width: 100%; height: auto; border-radius: 10px; display: block; image-rendering: pixelated; cursor: crosshair; }
.legend { display: flex; flex-wrap: wrap; gap: 4px 10px; font-size: 11px; margin-top: 10px; }
.legend span { display: inline-flex; align-items: center; gap: 4px; }
.legend i { width: 10px; height: 10px; border-radius: 3px; display: inline-block; }

/* ---------- Newspaper ---------- */
.paper-back { background: rgba(0, 0, 0, .7); }
.paper-back .modal { background: none; border: none; box-shadow: none; padding: 0; width: min(640px, 100%); overflow: visible; }
.paper { background: #f1ead8; color: #1a1712; border-radius: 3px; padding: 14px 18px 16px; box-shadow: 0 30px 80px rgba(0, 0, 0, .8); font-family: Georgia, "Times New Roman", serif; animation: spin 1s cubic-bezier(.2, .8, .3, 1.1); position: relative; background-image: repeating-linear-gradient(0deg, rgba(0, 0, 0, .025) 0 1px, transparent 1px 3px); }
@keyframes spin { 0% { transform: rotate(-900deg) scale(.05); opacity: 0; } 60% { opacity: 1; } 100% { transform: rotate(0) scale(1); } }
.paper .mast { display: flex; align-items: flex-end; justify-content: space-between; border-bottom: 3px double #1a1712; padding-bottom: 5px; gap: 8px; }
.paper .mast h1 { font-size: clamp(20px, 5vw, 38px); font-weight: 900; letter-spacing: .02em; text-align: center; flex: 1; font-family: "Old English Text MT", "UnifrakturMaguntia", Georgia, serif; }
.paper .ed { font-size: 10px; font-family: system-ui, sans-serif; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; width: 90px; }
.paper .ed:last-child { text-align: right; }
.paper .hl { font-size: clamp(24px, 6.2vw, 46px); font-weight: 900; line-height: 1; margin: 10px 0 6px; text-align: center; text-transform: uppercase; letter-spacing: -.01em; font-family: Impact, "Arial Black", Georgia, serif; }
.paper .sub { font-size: clamp(13px, 2.6vw, 17px); font-style: italic; text-align: center; margin-bottom: 8px; border-bottom: 1px solid #1a171255; padding-bottom: 7px; }
.paper .cols { display: flex; gap: 12px; align-items: flex-start; }
.paper .photo { width: 56%; height: auto; border: 1px solid #1a1712; flex: none; }
.paper .txt { font-size: 12px; line-height: 1.4; text-align: justify; column-count: 1; }
.paper .txt p { margin-bottom: 6px; }
.paper .txt p:first-child::first-letter { font-size: 2.3em; float: left; line-height: .9; margin-right: 3px; font-weight: 900; }
.paper .repd { position: absolute; right: -8px; top: -12px; transform: rotate(8deg); font: 900 14px system-ui, sans-serif; padding: 6px 10px; border-radius: 6px; color: #fff; box-shadow: 0 6px 16px rgba(0, 0, 0, .4); }
.paper .repd.good { background: #1f9d55; }
.paper .repd.bad { background: #c21f3a; }
.paper .tap { text-align: center; font: 700 11px system-ui, sans-serif; margin-top: 8px; opacity: .55; letter-spacing: .1em; text-transform: uppercase; }
.paper.tabloid { background: #fff7f2; }
.paper.tabloid .mast { border-bottom: 4px solid #d8122e; }
.paper.tabloid .mast h1 { color: #fff; background: #d8122e; font-family: Impact, "Arial Black", sans-serif; letter-spacing: .06em; padding: 2px 8px; }
.paper.tabloid .hl { color: #d8122e; }
@media (max-width: 520px) { .paper .cols { flex-direction: column; } .paper .photo { width: 100%; } }
.paper-back .modal { max-height: 100%; overflow: auto; padding: 16px 12px 4px 4px; }
@media (max-height: 460px) {
  .paper { padding: 8px 12px 10px; }
  .paper .mast h1 { font-size: 24px; }
  .paper .hl { font-size: 24px; margin: 6px 0 4px; }
  .paper .sub { font-size: 12px; margin-bottom: 5px; padding-bottom: 4px; }
  .paper .cols { flex-direction: row; }
  .paper .photo { width: 40%; }
  .paper .txt { font-size: 11px; max-height: 120px; overflow: hidden; }
  .paper .tap { margin-top: 4px; }
}

/* ---------- Title ---------- */
#title { position: absolute; inset: 0; display: none; align-items: center; justify-content: center; background: radial-gradient(ellipse at center, rgba(5, 8, 20, .35), rgba(5, 8, 20, .85)); padding: 16px; overflow: auto; }
body.title-on #title { display: flex; }
/* her photo beside the title card (a full-body green-screen cutout, herophotos.js); landscape only */
#title-hero { order: 2; flex: none; height: min(86vh, 640px); max-width: 38vw; object-fit: contain; margin-left: 2vw; filter: drop-shadow(0 0 28px rgba(126, 200, 244, .45)) drop-shadow(6px 6px 0 rgba(0, 0, 0, .45)); animation: rv-hero .6s cubic-bezier(.2, 1.2, .4, 1) both; }
#title-hero:not([src]) { display: none; }
@media (max-aspect-ratio: 1/1) { #title-hero { display: none; } }
.title-card { text-align: center; max-width: 520px; }
.logo { display: flex; justify-content: center; margin-bottom: 4px; }
.shield { width: 74px; height: 64px; background: var(--gold); color: var(--red); font: 900 44px Georgia, serif; display: grid; place-items: center; clip-path: polygon(0 0, 100% 0, 100% 38%, 50% 100%, 0 38%); border: none; filter: drop-shadow(0 0 16px rgba(247, 211, 30, .6)); padding-bottom: 12px; }
#title h1 { font-size: clamp(38px, 9vw, 76px); font-weight: 900; letter-spacing: .06em; color: #fff; text-shadow: 0 4px 0 var(--red), 0 0 40px rgba(126, 200, 244, .7); line-height: 1; font-family: Impact, "Arial Black", sans-serif; }
#title h2 { font-size: clamp(16px, 3.5vw, 26px); letter-spacing: .4em; color: var(--hero); margin: 4px 0 8px; text-transform: uppercase; }
.tag { opacity: .85; margin-bottom: 16px; font-size: 14px; }
.title-btns { display: flex; flex-direction: column; gap: 9px; align-items: center; }
.title-btns button { min-width: 230px; padding: 12px 18px; border-radius: 12px; border: 1px solid rgba(255, 255, 255, .25); background: rgba(10, 16, 34, .7); font-weight: 800; letter-spacing: .06em; font-size: 15px; }
.title-btns button.big { background: linear-gradient(180deg, #2f8fd0, #1b5d93); border-color: #9fd8ff; }
.title-btns button:hover { filter: brightness(1.15); }
.seed { display: inline-flex; gap: 8px; align-items: center; margin-top: 12px; font-size: 12px; opacity: .8; }
.seed input { width: 110px; padding: 5px 8px; border-radius: 8px; border: 1px solid var(--line); background: rgba(0, 0, 0, .4); color: #fff; font: 700 13px ui-monospace, monospace; user-select: text; -webkit-user-select: text; }
.hint { font-size: 11px; opacity: .6; margin-top: 10px; }
.howto { font-size: 13px; line-height: 1.5; }
.howto h3 { font-size: 13px; color: var(--gold); margin: 10px 0 3px; text-transform: uppercase; letter-spacing: .08em; }
.howto kbd { background: rgba(255, 255, 255, .12); border-radius: 4px; padding: 0 5px; font: 700 11px ui-monospace, monospace; }

/* ---------- Small screens ---------- */
@media (max-height: 480px), (max-width: 560px) {
  #hud-left { width: 146px; padding: 6px 9px 7px; }
  .rep { font-size: 18px; }
  #hud-face { width: 32px; height: 32px; }
  .me { gap: 6px; }
  #mapbox { width: 92px; height: 92px; }
  #mapbox.feed-on { width: min(250px, 40vw); height: calc(min(250px, 40vw) * 9 / 16); }
  #mapbox.feed-on #minimap { width: 46px; height: 46px; }
  body[data-mode="club3"] { --feedH: calc(min(250px, 40vw) * 9 / 16); }
  .iconbtn { width: 36px; height: 36px; }
  #hud-top { padding: 4px 10px; min-width: 110px; }
  #hud-title { font-size: 12px; }
  #objectives { top: calc(54px + var(--st)); font-size: 11px; max-width: 190px; }
  /* one line: the current step (first one only); tap the panel for the full list */
  #objectives:not(.open):has(.cur) div:not(.cur), #objectives:not(.open) div.cur ~ div.cur { display: none; }
  #objectives:not(.open):has(.cur)::after { content: "▾ tap for all"; display: block; font-size: 9px; opacity: .45; margin-top: 2px; letter-spacing: .05em; }
  #hud-left { width: 128px; padding: 5px 8px 6px; }
  .rank { font-size: 9px; margin-top: 1px; }
  .barlabel { font-size: 9px; margin-top: 4px; }
  .bar { height: 5px; margin-top: 2px; }
  #hud-sub { font-size: 10px; }
  #toasts { width: min(40vw, 380px); top: calc(50px + var(--st)); }
  .toast { font-size: 11px; padding: 5px 10px; }
  .tbtn { width: 60px; height: 60px; font-size: 11px; }
  .tbtn.big { width: 74px; height: 74px; }
  .slot1 { right: 90px; } .slot2 { bottom: 100px; } .slot3 { right: 86px; bottom: 82px; } .slot4 { right: 164px; } .slot5 { right: 160px; bottom: 80px; }
}
@media (max-width: 560px) and (orientation: portrait) {
  #hud-top { top: calc(10px + var(--st)); left: auto; right: calc(56px + var(--sr)); transform: none; max-width: 38vw; }
  body[data-mode="overworld"] #hud-top { right: calc(150px + var(--sr)); }
  #objectives { top: calc(120px + var(--st)); }
}

/* ================================================================
   Comic-book overlay (src/comic.js) - campy 60s/80s TV-comic style
   ================================================================ */
@font-face { font-family: "Bangers"; src: url("assets/fonts/bangers.woff2") format("woff2"); font-display: swap; }
#comic-layer { position: absolute; inset: 0; pointer-events: none; z-index: 50; overflow: hidden; font-family: "Bangers", Impact, "Arial Black", sans-serif; }
body.title-on #comic-layer { display: none; }
#comic-layer .out { opacity: 0 !important; transition: opacity .3s, transform .3s; }

/* POW! bursts */
.pow { position: absolute; display: grid; place-items: center; transform: rotate(var(--rot)); animation: pow-in .42s cubic-bezier(.2, 1.9, .5, 1) both, pow-wobble .5s .42s ease-in-out 2 alternate; filter: drop-shadow(4px 5px 0 rgba(0, 0, 0, .55)); }
.pow svg { position: absolute; inset: 0; width: 100%; height: 100%; }
.pow span { position: relative; letter-spacing: .03em; line-height: 1; -webkit-text-stroke: 3px #111; paint-order: stroke fill; text-shadow: 3px 3px 0 #111; transform: rotate(calc(var(--rot) * -.4)); }
.pow.out { transform: rotate(var(--rot)) scale(1.35); }
@keyframes pow-in { 0% { transform: rotate(calc(var(--rot) - 25deg)) scale(0); } 70% { transform: rotate(var(--rot)) scale(1.18); } 100% { transform: rotate(var(--rot)) scale(1); } }
@keyframes pow-wobble { from { transform: rotate(var(--rot)) scale(1); } to { transform: rotate(calc(var(--rot) + 5deg)) scale(1.06); } }

/* Speech / shout / thought bubbles */
.bubble { position: absolute; max-width: min(280px, 60vw); padding: 9px 14px 8px; background: #fff; color: #111; border: 3px solid #111; border-radius: 22px; font-size: clamp(15px, 2.1vw, 21px); letter-spacing: .04em; line-height: 1.1; text-align: center; box-shadow: 4px 4px 0 rgba(0, 0, 0, .45); animation: bub-in .32s cubic-bezier(.2, 1.7, .5, 1) both; --tail: 50%; }
/* her own lines (thoughts, and anything she says) carry her face on the corner (herophotos.js) */
.bubble .bub-face { position: absolute; left: -22px; top: -24px; width: 44px; height: 44px; border-radius: 50%; object-fit: cover; background: radial-gradient(circle at 50% 35%, #3f7ee0, #142a66); border: 3px solid #111; box-shadow: 2px 2px 0 rgba(0, 0, 0, .45); }
.bubble .bub-face:not([src]) { display: none; }
.bubble b { display: block; font-size: .7em; color: #d8122e; letter-spacing: .1em; margin-bottom: 1px; }
.bubble::after, .bubble::before { content: ""; position: absolute; left: var(--tail); top: 100%; transform: translateX(-50%); border-style: solid; }
.bubble::before { border-width: 20px 11px 0 11px; border-color: #111 transparent transparent transparent; }
.bubble::after { border-width: 15px 7px 0 7px; border-color: #fff transparent transparent transparent; margin-top: -1px; }
.bubble.below::before { top: auto; bottom: 100%; border-width: 0 11px 20px 11px; border-color: transparent transparent #111 transparent; }
.bubble.below::after { top: auto; bottom: 100%; border-width: 0 7px 15px 7px; border-color: transparent transparent #fff transparent; margin-bottom: -1px; }
.bubble.shout { background: #fff36b; border-width: 4px; border-radius: 6px; font-size: clamp(17px, 2.5vw, 25px); animation: bub-in .3s cubic-bezier(.2, 1.7, .5, 1) both, shake .09s .3s linear 6; }
.bubble.shout::after { border-top-color: #fff36b; }
.bubble.shout.below::after { border-bottom-color: #fff36b; border-top-color: transparent; }
.bubble.thought { border-radius: 50%; padding: 14px 20px; font-style: italic; }
.bubble.thought::before, .bubble.thought::after { border: 3px solid #111; background: #fff; border-radius: 50%; }
.bubble.thought::before { width: 14px; height: 14px; margin-top: 4px; }
.bubble.thought::after { width: 8px; height: 8px; margin-top: 22px; margin-left: -6px; }
.bubble.thought.below::before { margin-bottom: 4px; }
.bubble.thought.below::after { margin-bottom: 22px; }
.bubble.out { transform: scale(.6); }
@keyframes bub-in { from { transform: scale(0) rotate(-6deg); } to { transform: scale(1) rotate(0); } }
@keyframes shake { 0% { translate: 0 0; } 50% { translate: 2px -1px; } 100% { translate: -2px 1px; } }

/* Narrator captions */
/* Lower left, just above the joystick; slides in from the left edge like a comic panel. */
.caption { position: absolute; left: calc(14px + var(--sl)); bottom: calc(180px + var(--sb)); max-width: min(440px, 44vw); padding: 7px 16px 6px; background: #ffe24a; color: #111; border: 3px solid #111; box-shadow: 5px 5px 0 rgba(0, 0, 0, .5); font-size: clamp(15px, 2vw, 22px); letter-spacing: .06em; text-transform: uppercase; text-align: left; transform: skew(-6deg); transform-origin: left bottom; animation: cap-in .5s cubic-bezier(.2, 1.3, .5, 1) both; }
.caption.out { animation: cap-out .32s ease-in both; }
@keyframes cap-in { from { transform: skew(-6deg) translateX(calc(-100% - 40px)); } to { transform: skew(-6deg); } }
@keyframes cap-out { to { transform: skew(-6deg) translateX(calc(-100% - 40px)); } }
@media (max-height: 460px) { .caption, .newsflash { bottom: calc(160px + var(--sb)); max-width: 40vw; font-size: 14px; } }
/* in flight she's at screen centre: keep the caption in the left third so it never covers her */
@media (max-height: 480px), (max-width: 560px) { body[data-mode="overworld"] .caption, body[data-mode="overworld"] .newsflash { max-width: 34vw; font-size: 13px; } }

/* EXTRA! news flashes */
.newsflash { position: absolute; left: calc(14px + var(--sl)); bottom: calc(180px + var(--sb)); transform: rotate(-2deg); transform-origin: left bottom; display: flex; align-items: center; gap: 10px; max-width: min(480px, 46vw); padding: 8px 16px 7px 10px; background: #f3ecd8; color: #111; border: 3px solid #111; box-shadow: 6px 6px 0 rgba(0, 0, 0, .5); font-size: clamp(16px, 2.4vw, 25px); letter-spacing: .03em; animation: news-in .6s cubic-bezier(.2, 1.3, .5, 1) both; }
.newsflash i { font-style: normal; background: #d8122e; color: #fff; padding: 3px 8px 2px; font-size: .78em; letter-spacing: .08em; white-space: nowrap; transform: rotate(-4deg); }
.newsflash span { line-height: 1.05; }
.newsflash em { font-style: normal; font-size: 1.1em; }
.newsflash.good { background: linear-gradient(135deg, #fff6c8, #ffd84d); border-color: #7a5a00; animation: news-in .6s cubic-bezier(.2, 1.3, .5, 1) both, glow 1.2s .6s ease-in-out infinite alternate; }
.newsflash.good i { background: #1f9d55; }
.newsflash.good em { color: #fff; text-shadow: 0 0 8px #fff, 0 0 16px #ffd84d; animation: twinkle .5s infinite alternate; }
.newsflash.bad { background: #cfcac0; clip-path: polygon(0 4%, 6% 0, 14% 5%, 25% 0, 38% 4%, 52% 0, 66% 5%, 80% 0, 92% 4%, 100% 0, 100% 96%, 90% 100%, 78% 95%, 64% 100%, 50% 96%, 36% 100%, 22% 95%, 10% 100%, 0 96%); animation: news-in .6s cubic-bezier(.2, 1.3, .5, 1) both, sway 1.4s .6s ease-in-out infinite alternate; }
.newsflash.bad span { text-decoration: underline wavy #d8122e 2px; text-underline-offset: 4px; }
.newsflash.bad em { color: #fff; background: #d8122e; border: 2px solid #111; padding: 2px 7px 1px; transform: rotate(10deg); }
.newsflash.out { animation: news-out .32s ease-in both; }
/* slides in from the left edge into the story slot, like the narrator caption */
@keyframes news-in { from { transform: translateX(calc(-100% - 40px)) rotate(-2deg); } to { transform: rotate(-2deg); } }
@keyframes news-out { to { transform: translateX(calc(-100% - 40px)) rotate(-2deg); } }
@keyframes glow { from { box-shadow: 6px 6px 0 rgba(0, 0, 0, .5), 0 0 0 rgba(255, 216, 77, 0); } to { box-shadow: 6px 6px 0 rgba(0, 0, 0, .5), 0 0 32px rgba(255, 216, 77, .95); } }
@keyframes twinkle { from { opacity: .5; } to { opacity: 1; } }
@keyframes sway { from { transform: rotate(2.5deg); } to { transform: rotate(-1deg); } }

/* Spinning-emblem scene transition */
.spinner { position: absolute; inset: 0; display: grid; place-items: center; animation: spin-fade 1.45s ease-in-out both; }
.spinner .rays { position: absolute; left: 50%; top: 50%; width: 220vmax; height: 220vmax; margin: -110vmax 0 0 -110vmax; background: repeating-conic-gradient(#1e3cff 0 10deg, #d8122e 10deg 20deg, #ffe600 20deg 30deg); animation: rays-spin 1.45s linear both; }
.spinner .shield { position: relative; flex: none; width: min(46vmin, 300px); height: calc(min(46vmin, 300px) * .87); background: #111; clip-path: polygon(0 0, 100% 0, 100% 38%, 50% 100%, 0 38%); display: grid; place-items: center; animation: shield-spin 1.45s cubic-bezier(.45, .05, .55, .95) both; }
.spinner .shield::before { content: ""; position: absolute; inset: 4%; background: #ffe600; clip-path: polygon(0 0, 100% 0, 100% 38%, 50% 100%, 0 38%); }
.spinner .shield span { position: relative; font-family: Georgia, serif; font-weight: 900; font-size: min(26vmin, 170px); color: #d8122e; margin-top: -16%; -webkit-text-stroke: 3px #111; paint-order: stroke fill; }
.spinner .spin-label { position: absolute; bottom: 14%; font-size: clamp(22px, 5vw, 48px); color: #fff; -webkit-text-stroke: 3px #111; paint-order: stroke fill; letter-spacing: .06em; animation: label-in .4s .45s cubic-bezier(.2, 1.9, .5, 1) both; }
@keyframes label-in { from { transform: scale(0) rotate(-20deg); } to { transform: scale(1) rotate(-3deg); } }
@keyframes rays-spin { from { transform: rotate(0) scale(.2); } 50% { transform: rotate(360deg) scale(1); } to { transform: rotate(900deg) scale(1.2); } }
@keyframes shield-spin { 0% { transform: rotate(0) scale(.05); } 45% { transform: rotate(900deg) scale(1.1); } 70% { transform: rotate(1080deg) scale(1); } 100% { transform: rotate(1440deg) scale(6); opacity: 0; } }
@keyframes spin-fade { 0% { opacity: 0; } 8% { opacity: 1; } 80% { opacity: 1; } 100% { opacity: 0; } }
@media (prefers-reduced-motion: reduce) { .spinner, .spinner * { animation-duration: .01s !important; } }

/* === investigation === */
/* Evidence card: the "CLUE FOUND" moment as an inked comic panel on cream stock. */
.dlg.evidence { background: radial-gradient(ellipse at center, rgba(10, 4, 20, .25), rgba(4, 2, 10, .7)); }
.dlg.evidence .modal { width: min(600px, 100%); background: #f6eed8; color: #16111c; border: 4px solid #120a16; border-radius: 4px; box-shadow: 8px 8px 0 #120a16, 0 24px 60px rgba(0, 0, 0, .6); padding: 0 16px 12px; transform: rotate(-1.2deg); animation: ev-pop .42s cubic-bezier(.2, 1.6, .4, 1); background-image: radial-gradient(rgba(0, 0, 0, .07) 1px, transparent 1.4px); background-size: 6px 6px; position: relative; overflow: visible; }
.dlg.evidence .modal h2 { display: inline-block; margin: -16px 0 8px -24px; padding: 4px 16px 2px; background: #ffd21a; color: #120a16; border: 3px solid #120a16; box-shadow: 4px 4px 0 #120a16; font: 30px/1 "Bangers", Impact, sans-serif; letter-spacing: .06em; transform: rotate(-3deg); }
.dlg.evidence .speaker { color: #b3122e; font-size: 12px; letter-spacing: .16em; margin-bottom: 4px; }
.dlg.evidence .dtext { font-size: 15px; margin-bottom: 10px; }
.ev { display: flex; gap: 16px; align-items: center; }
.ev-art { flex: none; width: min(220px, 42vh); aspect-ratio: 1; background: #fffaf0; border: 4px solid #120a16; box-shadow: 5px 5px 0 #120a16; transform: rotate(2.5deg); display: grid; place-items: center; background-image: radial-gradient(circle at 50% 45%, #fffdf6 30%, #f0e6c8 100%), radial-gradient(rgba(0, 0, 0, .09) 1px, transparent 1.4px); background-size: 100% 100%, 5px 5px; background-blend-mode: multiply; }
.ev-glyph { width: 92%; height: 92%; animation: ev-glyph .5s .15s cubic-bezier(.2, 1.8, .4, 1) both; filter: drop-shadow(3px 4px 0 rgba(18, 10, 22, .25)); }
.ev-glyph.fly { animation: ev-fly .6s cubic-bezier(.25, .9, .3, 1.15) both; }
@keyframes ev-fly { from { transform: translate(var(--fx), var(--fy)) scale(.15) rotate(-60deg); opacity: .4; } 70% { opacity: 1; } to { transform: none; } }
.ev-txt { min-width: 0; }
.ev-txt .hint { display: block; margin-top: 8px; font-size: 12.5px; font-style: italic; color: #4a3a2a; }
.ev-txt i { display: block; font-size: 12.5px; opacity: .75; margin-bottom: 4px; }
.ev-txt p { font-size: 18px; line-height: 1.35; font-weight: 700; }
.ev-txt b, .dlg.evidence .dtext b { color: #b3122e; background: linear-gradient(transparent 58%, rgba(255, 210, 26, .7) 58%); padding: 0 2px; }
.dlg.evidence .dtext .hint { color: #4a3a2a; opacity: .85; }
.dlg.evidence .opt { background: #120a16; color: #fff; border: 2px solid #120a16; font: 20px/1 "Bangers", Impact, sans-serif; letter-spacing: .08em; justify-content: center; min-height: 42px; }
.dlg.evidence .opt .k { display: none; }
.dlg.evidence .opt:hover:not(:disabled) { background: #b3122e; border-color: #120a16; }
@keyframes ev-pop { 0% { transform: scale(.4) rotate(-9deg); opacity: 0; } 100% { transform: scale(1) rotate(-1.2deg); opacity: 1; } }
@keyframes ev-glyph { from { transform: scale(0) rotate(-40deg); } to { transform: scale(1) rotate(3deg); } }

/* Case board: evidence pinned to cork, suspects' mugshots, red string between them. */
.caseboard .modal { width: min(820px, 100%); padding: 0; background: #1a1210; border: 4px solid #120a16; border-radius: 6px; box-shadow: 0 20px 60px rgba(0, 0, 0, .7); overflow: hidden; animation: cb-pop .32s cubic-bezier(.2, 1.4, .4, 1); }
@keyframes cb-pop { from { transform: scale(.6) rotate(-3deg); opacity: 0; } }
.cb { position: relative; padding: 8px 12px 8px; max-height: calc(100vh - 36px); overflow: auto; background: #a8764a; background-image: radial-gradient(rgba(60, 30, 10, .35) 1px, transparent 1.6px), radial-gradient(rgba(255, 220, 170, .18) 1px, transparent 1.8px), linear-gradient(180deg, #b8845a, #976640); background-size: 7px 7px, 11px 11px, 100% 100%; background-position: 0 0, 3px 5px, 0 0; box-shadow: inset 0 0 40px rgba(40, 20, 5, .6); color: #16111c; }
.cb-head { display: flex; align-items: baseline; gap: 12px; margin-bottom: 6px; }
.cb-head b { font: 26px/1 "Bangers", Impact, sans-serif; letter-spacing: .06em; color: #fff; background: #120a16; padding: 3px 12px 1px; transform: rotate(-2deg); box-shadow: 3px 3px 0 #b3122e; }
.cb-head span { font: 700 12px system-ui; color: #2a1608; text-transform: uppercase; letter-spacing: .1em; opacity: .8; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cb-ev { display: flex; gap: 10px; justify-content: center; margin-bottom: 22px; position: relative; z-index: 2; }
.cb-card { position: relative; width: 112px; min-height: 76px; padding: 5px 5px 4px; background: #fbf7ea; border: 2px solid #120a16; box-shadow: 3px 3px 0 rgba(18, 10, 22, .8); transform: rotate(var(--r, 0deg)); text-align: center; display: flex; flex-direction: column; align-items: center; }
.cb-card img { width: 40px; height: 40px; }
.cb-card b { font: 16px/1 "Bangers", Impact, sans-serif; letter-spacing: .05em; color: #b3122e; margin-top: 1px; }
.cb-card small { font-size: 10.5px; font-weight: 700; line-height: 1.1; }
.cb-card.polaroid { padding: 5px 5px 4px; width: 118px; }
.cb-card img.cb-snap { width: 104px; height: 78px; object-fit: cover; border: 1px solid #120a16; margin-bottom: 2px; }
@media (max-height: 460px) { .cb-card.polaroid { width: 110px; } .cb-card img.cb-snap { width: 96px; height: 58px; } }
.cb-card.unk { background: rgba(30, 20, 14, .55); border-style: dashed; border-color: rgba(255, 240, 220, .5); box-shadow: none; color: #f2e6d0; }
.cb-card.unk b { color: #f2e6d0; }
.cb-q { font: 34px/40px "Bangers", Impact, sans-serif; color: rgba(255, 240, 220, .7); }
.cb-pin { position: absolute; top: -6px; left: 50%; width: 12px; height: 12px; margin-left: -6px; border-radius: 50%; background: radial-gradient(circle at 35% 35%, #ff8a8a, #c01020 60%, #600); box-shadow: 1px 2px 2px rgba(0, 0, 0, .5); }
.cb-no { position: absolute; top: -8px; left: -8px; width: 22px; height: 22px; background: #ffd21a; border: 2px solid #120a16; font: 15px/19px "Bangers", Impact, sans-serif; text-align: center; transform: rotate(-8deg); }
.cb-ph { position: absolute; top: -9px; right: -10px; font: normal 11px/1 "Bangers", Impact, sans-serif; letter-spacing: .08em; background: #3ee08a; color: #120a16; border: 2px solid #120a16; padding: 2px 4px 1px; transform: rotate(8deg); }
.cb-sus { display: flex; gap: 10px; position: relative; }
.cb-mug { position: relative; flex: 1 1 0; min-width: 0; display: flex; gap: 8px; align-items: flex-start; flex-wrap: wrap; padding: 6px; background: #f3ecdc; border: 2px solid #120a16; box-shadow: 4px 5px 0 rgba(18, 10, 22, .8), 0 8px 14px rgba(30, 14, 4, .45); transform: rotate(var(--r, 0deg)); }
.cb-mug.out { z-index: 4; }
.cb-mug.out .cb-acc { background: #8a827c; box-shadow: none; }
.cb-mug .cb-pin { top: -7px; }
.cb-photo { flex: none; width: 60px; height: 76px; overflow: hidden; border: 2px solid #120a16; background: #6a7480; background-image: repeating-linear-gradient(180deg, transparent 0 11px, rgba(255, 255, 255, .35) 11px 12px); }
.cb-photo canvas { width: 120px; height: 157px; display: block; margin: -2px 0 0 -30px; }
.cb-info { flex: 1; min-width: 0; }
.cb-info b { display: block; font: 17px/1.05 "Bangers", Impact, sans-serif; letter-spacing: .04em; }
.cb-info small { display: block; font-size: 11px; font-weight: 600; opacity: .7; margin-bottom: 2px; }
.cb-chips .chip { font-size: 10.5px; font-weight: 700; background: rgba(18, 10, 22, .1); color: #16111c; border: 1px solid rgba(18, 10, 22, .25); padding: 0 5px; margin: 2px 2px 0 0; border-radius: 3px; }
.cb-chips .chip.match { background: #ffd21a; border-color: #b3122e; color: #120a16; box-shadow: 0 0 0 1px #b3122e; }
.cb-chips .chip.miss { background: transparent; color: rgba(18, 10, 22, .45); text-decoration: line-through; }
.cb-acc { flex: 1 0 100%; min-height: 36px; margin-top: 2px; background: #b3122e; color: #fff; border: 2px solid #120a16; box-shadow: 2px 2px 0 #120a16; font: 19px/1 "Bangers", Impact, sans-serif; letter-spacing: .1em; cursor: pointer; }
.cb-acc:disabled { background: #7a6a60; opacity: .6; cursor: default; }
.cb-acc:not(:disabled):hover { background: #d8122e; }
.cb-mug.out .cb-photo, .cb-mug.out .cb-info { opacity: .55; filter: grayscale(.8); }
.cb-stamp { position: absolute; left: 50%; top: 34%; transform: translate(-50%, -50%) rotate(-14deg); font: 24px/1 "Bangers", Impact, sans-serif; letter-spacing: .08em; color: rgba(179, 18, 46, .85); border: 3px solid rgba(179, 18, 46, .85); padding: 2px 8px 0; pointer-events: none; white-space: nowrap; mix-blend-mode: multiply; }
.cb-strings { position: absolute; left: 0; top: 0; width: 100%; height: 100%; pointer-events: none; z-index: 3; overflow: visible; }
.cb-strings path { fill: none; stroke: #c8102e; stroke-width: 2.4; stroke-linecap: round; filter: drop-shadow(1px 2px 1px rgba(0, 0, 0, .45)); }
.cb-strings circle { fill: #d8182e; stroke: #500; stroke-width: 1; }
.cb-strings circle.hl { fill: #ffb0b0; stroke: none; }
.cb-foot { display: flex; align-items: center; gap: 10px; margin-top: 8px; position: relative; z-index: 2; }
.cb-foot span { flex: 1; font-size: 12.5px; font-weight: 700; color: #1a0e06; background: rgba(251, 247, 234, .85); padding: 5px 9px; border: 2px solid #120a16; }
.cb-close { min-height: 38px; padding: 0 14px; background: #120a16; color: #fff; border: 2px solid #120a16; font: 18px/1 "Bangers", Impact, sans-serif; letter-spacing: .08em; display: flex; align-items: center; gap: 8px; cursor: pointer; }
@media (max-height: 460px) {
  .cb-ev { margin-bottom: 16px; }
  .cb-card { width: 104px; min-height: 68px; }
  .cb-card img { width: 34px; height: 34px; }
}

/* Accusation splash: tilted panel over a radial burst, the hero steps in, the verdict lands with a
   flash and a shake, then a three-panel recap of the evidence. Timings match caseboard.js REVEAL. */
.reveal { background: #0c0610; padding: 0; }
.reveal .modal { width: 100%; height: 100%; max-height: none; padding: 0; background: none; border: 0; border-radius: 0; box-shadow: none; overflow: hidden; }
.rv2 { position: relative; width: 100%; height: 100%; overflow: hidden; }
.rv2.hit { animation: rv-shake .38s linear; }
.rv-burst { position: absolute; inset: -40%; background: repeating-conic-gradient(from 0deg at 42% 50%, #ffd21a 0 5deg, #ff8a1a 5deg 10deg); animation: rv-spin 12s linear infinite; }
.rv2.bad .rv-burst { background: repeating-conic-gradient(from 0deg at 42% 50%, #3a3f4a 0 5deg, #262a33 5deg 10deg); }
.rv-burst::after { content: ""; position: absolute; inset: 0; background: radial-gradient(circle at 42% 50%, transparent 18%, rgba(12, 6, 16, .55) 70%); }
.rv-panel { position: absolute; left: 6%; top: 7%; width: 34%; height: 66%; background: #6a7480; background-image: repeating-linear-gradient(180deg, transparent 0 22px, rgba(255, 255, 255, .3) 22px 23px); border: 6px solid #120a16; box-shadow: 10px 10px 0 #120a16; transform: rotate(-4deg); overflow: hidden; animation: rv-slam .34s cubic-bezier(.2, 1.5, .4, 1) both; }
.rv2.bad .rv-panel { filter: grayscale(.7); }
.rv-mug { position: absolute; inset: 0 0 20% 0; display: grid; place-items: end center; overflow: hidden; }
.rv-mug canvas { height: 100%; width: auto; }
.rv-cap { position: absolute; left: 0; right: 0; bottom: 0; padding: 6px 10px 5px; background: #120a16; color: #fff; font: clamp(18px, 5vh, 30px)/1 "Bangers", Impact, sans-serif; letter-spacing: .05em; }
.rv-cap small { display: block; font: 700 11px system-ui; letter-spacing: .14em; text-transform: uppercase; opacity: .75; margin-top: 2px; }
.rv-hero { position: absolute; right: 1%; bottom: -2%; width: 28%; height: 100%; display: grid; place-items: end center; animation: rv-hero .45s .32s cubic-bezier(.2, 1.2, .4, 1) both; filter: drop-shadow(6px 6px 0 #120a16); }
.rv-hero canvas { height: 100%; width: auto; }
.rv-hero img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; object-position: center bottom; }
.rv-word { position: absolute; left: 41%; top: 7%; font: clamp(44px, 16vh, 96px)/1 "Bangers", Impact, sans-serif; letter-spacing: .04em; color: #ffe600; -webkit-text-stroke: 3px #120a16; paint-order: stroke fill; text-shadow: 6px 6px 0 #d8122e, 10px 10px 0 #120a16; transform: rotate(-6deg); animation: rv-word .3s .7s cubic-bezier(.3, 1.8, .5, 1) both; }
.rv2.bad .rv-word { color: #cfd4dc; text-shadow: 6px 6px 0 #4a4f5a, 10px 10px 0 #120a16; }
.rv-stamp { position: absolute; left: 40%; top: 44%; font: clamp(30px, 11vh, 64px)/1 "Bangers", Impact, sans-serif; letter-spacing: .08em; padding: 6px 16px 0; border: 6px solid currentColor; color: #ff2d4a; background: rgba(255, 255, 255, .12); transform: translate(-50%, -50%) rotate(-14deg); white-space: nowrap; animation: rv-stamp .3s .7s cubic-bezier(.3, 1.6, .5, 1) both; }
.rv2.bad .rv-stamp { color: #aab0ba; }
.rv-recap { position: absolute; left: 36%; bottom: 5%; display: flex; gap: 10px; }
.rv-rc { position: relative; width: clamp(88px, 13vw, 120px); padding: 5px 5px 6px; background: #fbf7ea; border: 3px solid #120a16; box-shadow: 4px 4px 0 #120a16; text-align: center; animation: rv-in .3s var(--d) both; }
.rv-rc:nth-child(2) { transform: rotate(2deg); }
.rv-rc:nth-child(3) { transform: rotate(-2deg); }
.rv-rc img { width: 100%; height: clamp(44px, 12vh, 72px); object-fit: contain; }
.rv-rc b { display: block; font: 16px/1 "Bangers", Impact, sans-serif; letter-spacing: .05em; color: #b3122e; }
.rv-rc small { display: block; font: 700 10.5px/1.1 system-ui; color: #16111c; }
.rv-rc i { position: absolute; top: -12px; right: -10px; width: 26px; height: 26px; border-radius: 50%; border: 2px solid #120a16; font: normal 900 15px/22px system-ui; color: #120a16; background: #3ee08a; }
.rv-rc.no i { background: #ff4d6a; color: #fff; }
.rv-flash { position: absolute; inset: 0; background: #fff; opacity: 0; pointer-events: none; }
.rv2.hit .rv-flash { animation: rv-flash .4s ease-out; }
@keyframes rv-spin { to { transform: rotate(360deg); } }
@keyframes rv-slam { from { transform: rotate(-16deg) scale(1.6); opacity: 0; } }
@keyframes rv-hero { from { transform: translateX(70%); opacity: 0; } }
@keyframes rv-word { from { transform: rotate(-6deg) scale(3); opacity: 0; } }
@keyframes rv-flash { 0% { opacity: .95; } 100% { opacity: 0; } }
@keyframes rv-shake { 0%, 100% { transform: none; } 20% { transform: translate(-8px, 4px); } 40% { transform: translate(7px, -5px); } 60% { transform: translate(-5px, -3px); } 80% { transform: translate(4px, 3px); } }
@keyframes rv-in { from { opacity: 0; transform: translateY(24px) scale(.8); } }
@keyframes rv-stamp { from { opacity: 0; transform: translate(-50%, -50%) rotate(-30deg) scale(3); } to { opacity: 1; transform: translate(-50%, -50%) rotate(-14deg) scale(1); } }

/* Camera: the snapped frame pops out as a polaroid and slides off toward the case notes. */
.snap-polaroid { position: absolute; width: 132px; margin: -60px 0 0 -66px; padding: 6px 6px 18px; background: #fbfaf5; border: 2px solid #120a16; box-shadow: 5px 6px 0 rgba(18, 10, 22, .85); animation: snap-fly 2.4s cubic-bezier(.3, .8, .4, 1) forwards; z-index: 5; }
.snap-polaroid canvas { display: block; width: 100%; height: auto; border: 1px solid #120a16; animation: snap-dev 1s ease-out both; }
.snap-polaroid span { position: absolute; left: 0; right: 0; bottom: 2px; text-align: center; font: 14px/1 "Bangers", Impact, sans-serif; letter-spacing: .08em; color: #b3122e; }
@keyframes snap-fly {
  0% { transform: scale(.3) rotate(0); opacity: 0; }
  12% { transform: scale(1.12) rotate(var(--rot)); opacity: 1; }
  20%, 62% { transform: scale(1) rotate(var(--rot)); opacity: 1; }
  100% { transform: translate(38vw, 30vh) scale(.25) rotate(20deg); opacity: 0; }
}
@keyframes snap-dev { from { filter: brightness(3) saturate(0); } to { filter: none; } }

/* === flying (3D flight slice, ?flight=3d) === */
/* the 3D view under a transparent 2D canvas that keeps the comic overlay (icons, markers, speed lines) */
body.fly3d #three-host { display: block; z-index: 0; }
body.fly3d #c2d { z-index: 1; pointer-events: none; }

/* flight buttons over the 3D view: smaller, grouped round the right thumb; DIVE/PERCH appear when they apply */
body.fly3d .tbtn.f3 { width: 58px; height: 58px; font-size: 11px; }
body.fly3d .tbtn.gone { display: none; }
body.fly3d .tbtn.f3-boost { right: 4px; bottom: 6px; width: 74px; height: 74px; font-size: 13px; }
body.fly3d .tbtn.f3-dive { right: 2px; bottom: 92px; width: 74px; height: 74px; font-size: 14px; }
body.fly3d .tbtn.f3-up, body.fly3d .tbtn.f3-down { right: 90px; width: 50px; height: 46px; font-size: 16px; }
body.fly3d .tbtn.f3-up { bottom: 54px; border-radius: 25px 25px 8px 8px; }
body.fly3d .tbtn.f3-down { bottom: 6px; border-radius: 8px 8px 25px 25px; }
body.fly3d .tbtn.f3-perch { right: 150px; bottom: 6px; }
body.fly3d .tbtn.f3-map { right: 92px; bottom: 112px; width: 46px; height: 46px; font-size: 10px; }
/* DIVE / PERCH: contextual, but loud when they apply (pop in, gold, pulsing) */
@keyframes f3pop { from { transform: scale(.3); opacity: 0; } to { transform: scale(1); opacity: 1; } }
@keyframes f3pulse { 0%, 100% { box-shadow: 0 0 0 0 rgba(255, 214, 40, .8), 0 0 12px rgba(255, 214, 40, .6); } 50% { box-shadow: 0 0 0 12px rgba(255, 214, 40, 0), 0 0 24px rgba(255, 214, 40, .95); } }
body.fly3d .tbtn.f3-dive:not(.gone), body.fly3d .tbtn.f3-perch.lit:not(.gone) {
  background: linear-gradient(#ffe24a, #f0a000); color: #160c1c; border: 3px solid #0b0b16; text-shadow: none;
  animation: f3pop .22s ease-out, f3pulse 1.1s ease-in-out .22s infinite;
}
body.fly3d .tbtn.f3-perch { font-size: 10px; }

/* === stability === */
/* "RESTORING GRAPHICS…" / "LOADING…": a comic caption card mid-screen, under the HUD, the LIVE feed
   and the captions (z 6, like the club loader) so the story layer stays on top */
#gfx-panel { position: absolute; left: 50%; top: 46%; transform: translate(-50%, -50%) skew(-6deg); z-index: 6; display: none; pointer-events: none;
  padding: 10px 22px 8px; background: #ffe24a; color: #111; border: 3px solid #111; box-shadow: 6px 6px 0 rgba(0, 0, 0, .55);
  font: 400 clamp(20px, 3.2vw, 30px)/1.1 "Bangers", Impact, "Arial Black", sans-serif; letter-spacing: .08em; text-align: center; white-space: nowrap; }
#gfx-panel.on { display: block; }
#gfx-panel s { display: block; overflow: hidden; height: 5px; margin: 6px auto 0; width: 60%; }
/* (a transform animation keeps running on the compositor while a load blocks the main thread) */
#gfx-panel i { display: block; height: 100%; width: calc(100% + 32px); background: repeating-linear-gradient(90deg, #111 0 10px, transparent 10px 16px); animation: gfx-dash .6s linear infinite; will-change: transform; }
@keyframes gfx-dash { from { transform: translateX(-32px); } to { transform: translateX(0); } }

/* === dive === */
/* The dive's comic landing beat (divefx.js): over the game view and the LOADING cards (z 7), under
   the HUD, the LIVE feed, the touch controls (lifted to z 8 while it runs) and the captions (z 50).
   Everything after the impact moves by transform/opacity, so it keeps playing through a zone's load. */
#dive-fx { position: absolute; inset: 0; z-index: 7; pointer-events: none; overflow: hidden; font-family: "Bangers", Impact, "Arial Black", sans-serif; }
body.divefx #hud, body.divefx #btns, body.divefx #touch { z-index: 8; }
/* the zone's own HUD (title, side panel, objectives) takes over under the panel: keep it out of sight
   until the wipe, then bring it in with it (the LIVE feed and the minimap corner never hide) */
body.divefx-landed #hud-left, body.divefx-landed #hud-top, body.divefx-landed #objectives, body.divefx-landed #prompt, body.divefx-landed #marker { opacity: 0; }
body.divefx-landed.divefx-out #hud-left, body.divefx-landed.divefx-out #hud-top, body.divefx-landed.divefx-out #objectives, body.divefx-landed.divefx-out #prompt, body.divefx-landed.divefx-out #marker { opacity: 1; transition: opacity .3s .1s; }
/* a zone's title banner waits (held on its first, invisible keyframe) and plays once the panel is gone */
body.divefx-hold #banner.show { animation-play-state: paused; }
#dive-fx canvas { position: absolute; inset: 0; width: 100%; height: 100%; }
#dive-fx.hit canvas { filter: contrast(1.12) saturate(1.3); animation: df-push 1.6s linear both, df-shake var(--shake) var(--stop) linear both; }
@keyframes df-push { from { scale: var(--s0); } to { scale: var(--s1); } }
@keyframes df-shake {
  0% { translate: 0 0; } 8% { translate: calc(var(--a) * -1px) calc(var(--a) * .75px); } 18% { translate: calc(var(--a) * .85px) calc(var(--a) * -.6px); }
  30% { translate: calc(var(--a) * -.55px) calc(var(--a) * -.45px); } 44% { translate: calc(var(--a) * .38px) calc(var(--a) * .32px); }
  60% { translate: calc(var(--a) * -.2px) calc(var(--a) * .15px); } 78% { translate: calc(var(--a) * .08px) calc(var(--a) * -.06px); } 100% { translate: 0 0; } }
/* hit-stop flash: white-hot round the impact, a yellow wash out to the frame, gone in ~0.3 s */
.df-flash { position: absolute; inset: 0; background: radial-gradient(circle at var(--x) var(--y), #fff 0, #fff 22%, rgba(255, 246, 190, .9) 48%, rgba(255, 214, 40, .55) 100%); animation: df-flash .32s linear both; }
@keyframes df-flash { 0% { opacity: 1; } 22% { opacity: .92; } 30% { opacity: .55; } 100% { opacity: 0; } }
.df-ring { position: absolute; left: var(--x); top: var(--y); width: 0; height: 0; animation: df-ring .42s var(--stop) cubic-bezier(.12, .75, .3, 1) both; }
.df-ring.late { animation-delay: calc(var(--stop) + 90ms); animation-duration: .5s; }
.df-ring svg { position: absolute; left: 0; top: 0; overflow: visible; }
@keyframes df-ring { 0% { transform: scale(.12); opacity: 1; } 45% { opacity: 1; } 100% { transform: scale(3.2); opacity: 0; } }
.df-puff { position: absolute; left: var(--x); top: var(--y); animation: df-puff 1.5s calc(var(--stop) + var(--d)) cubic-bezier(.1, .8, .3, 1) both; } /* (long: still drifting through the hold) */
.df-puff svg { width: 100%; height: 100%; overflow: visible; transform: scaleX(var(--f)); }
@keyframes df-puff { 0% { transform: translate(0, 0) scale(.2); opacity: 1; } 40% { transform: translate(calc(var(--dx) * .78), calc(var(--dy) * .78)) scale(1.05); opacity: 1; } 100% { transform: translate(var(--dx), calc(var(--dy) - 14px)) scale(1.35); opacity: 0; } }
/* the onomatopoeia: burst balloon + hand-lettered word, popped in past full size, then a slow swell */
.df-word { position: absolute; display: grid; place-items: center; transform: rotate(var(--rot)); filter: drop-shadow(5px 6px 0 rgba(0, 0, 0, .55));
  animation: df-word-in .36s var(--stop) cubic-bezier(.2, 1.7, .45, 1) both, df-word-hold 1.6s calc(var(--stop) + 360ms) ease-out forwards; } /* (forwards: a backwards fill would hide the pop-in) */
.df-word svg { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
.df-word span { position: relative; line-height: 1; letter-spacing: .02em; white-space: nowrap; -webkit-text-stroke: 4px #111; paint-order: stroke fill; text-shadow: .045em .055em 0 var(--sh), .085em .1em 0 #111; }
.df-word i { display: inline-block; font-style: normal; transform: translateY(var(--y)) rotate(var(--r)); }
@keyframes df-word-in { 0% { transform: rotate(calc(var(--rot) - 26deg)) scale(0); } 62% { transform: rotate(calc(var(--rot) + 3deg)) scale(1.3); } 82% { transform: rotate(var(--rot)) scale(.95); } 100% { transform: rotate(var(--rot)) scale(1); } }
@keyframes df-word-hold { 0% { transform: rotate(var(--rot)) scale(1); } 22% { transform: rotate(calc(var(--rot) - 1deg)) scale(1.09); } 45% { transform: rotate(calc(var(--rot) - 1deg)) scale(1.02); } 70% { transform: rotate(calc(var(--rot) - 2deg)) scale(1.08); } 100% { transform: rotate(calc(var(--rot) - 2deg)) scale(1.05); } } /* (a throb: the panel is alive while the zone loads) */
/* the zone's name, as a caption tag; it grows the LOADING dashes if the zone is slow */
.df-tag { position: absolute; padding: 4px 13px 3px; background: #ffe24a; color: #111; border: 3px solid #111; box-shadow: 4px 4px 0 rgba(0, 0, 0, .55); font-size: clamp(15px, 2.4vw, 22px); letter-spacing: .07em; white-space: nowrap; transform: skew(-6deg); animation: df-tag-in .26s calc(var(--stop) + 220ms) cubic-bezier(.2, 1.5, .5, 1) both; }
.df-tag s { display: none; overflow: hidden; height: 4px; margin: 4px 0 1px; }
.df-tag.loading s { display: block; }
.df-tag i { display: block; height: 100%; width: calc(100% + 32px); background: repeating-linear-gradient(90deg, #111 0 10px, transparent 10px 16px); animation: gfx-dash .6s linear infinite; }
@keyframes df-tag-in { from { transform: skew(-6deg) translateX(-40px); opacity: 0; } to { transform: skew(-6deg); opacity: 1; } }
/* out: a comic panel wipe, a diagonal gutter sweeping left to right to the zone behind it */
#dive-fx.out { animation: df-wipe var(--wipe) cubic-bezier(.55, 0, .45, 1) both; }
@keyframes df-wipe {
  from { -webkit-clip-path: polygon(0 0, 100% 0, 100% 100%, -18% 100%); clip-path: polygon(0 0, 100% 0, 100% 100%, -18% 100%); }
  to { -webkit-clip-path: polygon(118% 0, 118% 0, 100% 100%, 100% 100%); clip-path: polygon(118% 0, 118% 0, 100% 100%, 100% 100%); } }
/* the gutter riding the wipe's edge: white on the zone's side, ink on the panel's */
.df-gutter { position: absolute; left: 0; top: 50%; z-index: 7; width: 16px; height: var(--gh); margin-top: calc(var(--gh) / -2); background: #111; border-left: 5px solid #fff; pointer-events: none;
  transform: translateX(var(--g0)) rotate(var(--gr)); animation: df-gutter var(--wipe) cubic-bezier(.55, 0, .45, 1) both; }
@keyframes df-gutter { from { transform: translateX(var(--g0)) rotate(var(--gr)); } to { transform: translateX(var(--g1)) rotate(var(--gr)); } }
#dive-fx.lite.out { animation: df-fade .26s ease-in both; }
@keyframes df-fade { to { opacity: 0; } }
/* prefers-reduced-motion: no flash, no shake, no swing; the word just appears */
#dive-fx.lite .df-flash { display: none; }
#dive-fx.lite.hit canvas { animation: none; }
#dive-fx.lite .df-word { animation: df-lite-in .2s both; }
#dive-fx.lite .df-puff { animation-duration: .4s; }
@keyframes df-lite-in { from { opacity: 0; } }

/* === feed sound === */
#feed .feed-snd { margin-left: auto; color: #fff; opacity: .85; font-size: 10px; letter-spacing: .03em; }

/* === 3D infiltration club (src/club3d/) === */
/* close-ups and the VIP dance are drawn flat on the 2D canvas, over the waiting 3D view.
   That canvas covers the screen, so the action buttons (BACK, CASE, CAMERA) have to sit above it. */
body.three.c3-flat #c2d { display: block; position: absolute; z-index: 1; }
body.c3-flat #btns, body.closeup-on #btns { z-index: 3; }
/* investigation close-up: the picture fills the screen; the buttons stand in one column down the right edge,
   which closeupFrame (src/nightclub/scenes.js, CLOSEUP_RAIL) keeps every tappable spot clear of */
body.closeup-on #btns { left: auto; right: calc(10px + var(--sr)); top: calc(44px + var(--st)); bottom: calc(10px + var(--sb)); width: 76px; height: auto; display: flex; flex-direction: column; justify-content: center; align-items: center; gap: 10px; }
body.closeup-on #btns .tbtn, body.closeup-on #btns .tbtn.big { position: static; width: 68px; height: 68px; flex: none; }
body.c3-flat #objectives, body.c3-flat #marker, body.c3-flat #prompt, body.c3-flat #c3-talk, body.c3-flat #c3-chat { display: none; }
/* a Talker's two bars over their heads: evidence (gold) and their suspicion (red) */
#c3-talk { position: absolute; left: 0; top: 0; width: 132px; margin: -46px 0 0 -66px; padding: 4px 7px 6px; background: rgba(10, 6, 18, .78); border: 2px solid #111; border-radius: 8px; display: none; font: 400 13px "Bangers", Impact, sans-serif; letter-spacing: .06em; color: #ffd84d; text-align: center; }
#c3-talk.on { display: block; }
#c3-talk .bar { height: 7px; margin-top: 3px; }
#c3-talk .ev { background: #ffd84d; }
#c3-talk .su { background: #ff3a5a; }
/* bubbles in the crowd you can tap: rumours (noted), whispers (super-hearing), offers (accept) */
#c3-chat { position: absolute; inset: 0; pointer-events: none; z-index: 51; overflow: hidden; font-family: "Bangers", Impact, "Arial Black", sans-serif; }
#c3-chat .c3b { position: absolute; left: 0; top: 0; max-width: min(260px, 58vw); padding: 8px 13px 7px; pointer-events: auto; cursor: pointer; background: #fff; color: #111; border: 3px solid #111; border-radius: 20px; font: inherit; font-size: clamp(14px, 2vw, 19px); letter-spacing: .03em; line-height: 1.1; text-align: center; box-shadow: 4px 4px 0 rgba(0, 0, 0, .45); animation: c3b-in .32s cubic-bezier(.2, 1.7, .5, 1) both; transition: opacity .25s; }
/* (pops in with scale/rotate, not transform: bub-in's held transform overrode the inline translate and pinned every tap bubble over the HUD, top left) */
@keyframes c3b-in { from { scale: 0; rotate: -6deg; } to { scale: 1; rotate: 0deg; } }
#c3-chat .c3b small { display: block; margin-top: 4px; font-size: .62em; letter-spacing: .12em; color: #b8860b; }
#c3-chat .c3b b { display: block; font-size: .62em; letter-spacing: .14em; color: #7a3ad8; margin-bottom: 2px; }
#c3-chat .c3b.rumour { border-color: #b8860b; box-shadow: 4px 4px 0 rgba(0, 0, 0, .45), 0 0 0 3px #ffd84d inset; }
#c3-chat .c3b.whisper { font-style: italic; background: #efe4ff; border-color: #5a2ab0; }
#c3-chat .c3b.offer { background: #fff0f8; border-color: #c0106a; }
#c3-chat .c3b.offer small { color: #c0106a; }
#c3-chat .c3b.out { opacity: 0; }
/* quick prompts (quick.js): a small choice at the foot of the screen; the club keeps going and walking off is a no */
#c3-quick { position: absolute; left: 0; right: 0; margin: 0 auto; bottom: calc(18px + var(--sb)); z-index: 52; width: min(500px, calc(100vw - 380px)); min-width: 270px; padding: 9px 12px 10px; display: none; pointer-events: auto; background: rgba(10, 6, 18, .9); border: 2px solid #111; border-radius: 12px; box-shadow: 4px 4px 0 rgba(0, 0, 0, .5), inset 0 0 0 1px rgba(255, 63, 184, .45); color: #fff; font-size: 13px; animation: bub-in .25s cubic-bezier(.2, 1.5, .5, 1) both; }
#c3-quick.on { display: block; }
#c3-quick .who { display: block; font: 400 15px "Bangers", Impact, sans-serif; letter-spacing: .06em; color: #ff3fb8; }
#c3-quick .txt { margin: 2px 0 8px; line-height: 1.35; }
#c3-quick .txt small { display: block; margin-top: 4px; color: #9dff9a; font-size: 11.5px; }
#c3-quick .opts { display: flex; flex-direction: row; flex-wrap: wrap; gap: 6px; margin: 0; }
#c3-quick .q { flex: 1 1 auto; min-width: 128px; max-width: 100%; height: auto; display: flex; flex-direction: row; align-items: flex-start; gap: 7px; min-height: 38px; padding: 6px 9px; text-align: left; color: #fff; background: rgba(255, 255, 255, .08); border: 1px solid rgba(255, 255, 255, .22); border-radius: 8px; font: 700 13px system-ui, sans-serif; cursor: pointer; }
#c3-quick .q .k { flex: none; width: 18px; height: 18px; border-radius: 4px; background: rgba(255, 255, 255, .16); font-size: 11px; display: grid; place-items: center; }
#c3-quick .q small { display: block; font-weight: 500; font-size: 11px; opacity: .7; margin-top: 1px; }
#c3-quick .q.risky { border-color: #ff9a3d; } #c3-quick .q.good { border-color: #3ee08a; } #c3-quick .q.bad { border-color: #ff3a5a; }
body.touch #c3-quick .q .k { display: none; }
body.c3-flat #c3-quick { display: none; }
/* first-visit tips (feel.js): a card under the objectives, once each (the narrator's captions take the left) */
#c3-tip { position: absolute; right: calc(10px + var(--sr)); top: calc(122px + var(--st)); z-index: 52; width: min(250px, 34vw); padding: 7px 10px 8px; display: none; pointer-events: none; background: rgba(10, 6, 18, .88); border: 2px solid #111; border-radius: 9px; box-shadow: 3px 3px 0 rgba(0, 0, 0, .5), inset 3px 0 0 #ffd84d; color: #fff; font-size: 12px; line-height: 1.35; }
#c3-tip.on { display: block; animation: bub-in .25s cubic-bezier(.2, 1.5, .5, 1) both; }
#c3-tip b { display: block; font: 400 14px "Bangers", Impact, sans-serif; letter-spacing: .1em; color: #ffd84d; }
body.c3-flat #c3-tip { display: none; }
/* the shot-off's timing bar, and the countdown bars on the host's and the owner's questions */
.c3-timing { position: relative; height: 26px; margin: 12px 0 4px; background: #24183a; border: 2px solid #111; border-radius: 6px; overflow: hidden; }
.c3-timing .zone { position: absolute; top: 0; bottom: 0; background: #3ee08a; }
.c3-timing .needle { position: absolute; top: -2px; bottom: -2px; width: 5px; margin-left: -2px; background: #fff; box-shadow: 0 0 6px #fff; }
.c3-clock { height: 8px; margin: 8px 0 2px; }
/* the polaroid the owner slides across the desk */
.c3-pol { display: block; width: min(44%, 170px); margin: 4px auto 8px; transform: rotate(-4deg); box-shadow: 0 6px 18px #000a; }
/* the struggle (club3d/struggle.js): a clip of her held, full screen; turn the stick to break free */
.c3-struggle { position: absolute; inset: 0; z-index: 59; background: #000; touch-action: none; user-select: none; -webkit-user-select: none; overflow: hidden; }
.c3-struggle video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.c3-struggle .st-tint { position: absolute; inset: 0; background: radial-gradient(ellipse at center, transparent 45%, rgba(0, 0, 0, .65)); pointer-events: none; }
.c3-struggle.stall video { animation: st-shake .09s linear infinite; filter: saturate(.4) brightness(.75) sepia(.3) hue-rotate(-30deg); }
.c3-struggle.stall .st-tint { background: radial-gradient(ellipse at center, rgba(255, 0, 40, .08) 35%, rgba(120, 0, 20, .7)); }
.c3-struggle.won .st-tint { background: rgba(62, 224, 138, .25); }
.c3-struggle.lost .st-tint { background: rgba(160, 0, 30, .45); }
@keyframes st-shake { 0% { transform: translate(0, 0) scale(1.04); } 25% { transform: translate(-7px, 4px) scale(1.04) rotate(-.5deg); } 50% { transform: translate(6px, -5px) scale(1.04); } 75% { transform: translate(-4px, -3px) scale(1.04) rotate(.5deg); } 100% { transform: translate(5px, 5px) scale(1.04); } }
.c3-struggle .st-top { position: absolute; left: 50%; top: calc(10px + var(--st)); transform: translateX(-50%); width: min(560px, 92vw); text-align: center; pointer-events: none; }
.c3-struggle h2 { margin: 0; font: 400 34px/1 "Bangers", Impact, sans-serif; letter-spacing: .06em; color: #ffd84d; text-shadow: 3px 3px 0 #000, 0 0 12px #000; }
.c3-struggle .st-text { margin-top: 4px; color: #fff; font-size: 14px; text-shadow: 0 1px 4px #000; }
.c3-struggle .st-time { height: 8px; margin: 8px auto 0; width: 70%; background: rgba(0, 0, 0, .6); border: 2px solid #111; border-radius: 5px; overflow: hidden; }
.c3-struggle .st-time i { display: block; height: 100%; width: 100%; background: linear-gradient(90deg, #ff3a3a, #ffd84d); }
.c3-struggle .st-pad { position: absolute; right: calc(24px + var(--sr)); bottom: calc(24px + var(--sb)); width: 120px; height: 120px; pointer-events: none; }
.c3-struggle .st-pad svg { width: 100%; height: 100%; transform: rotate(-90deg); }
.c3-struggle .st-track { fill: rgba(0, 0, 0, .55); stroke: rgba(255, 255, 255, .25); stroke-width: 10; }
.c3-struggle .st-prog { fill: none; stroke: #3ee08a; stroke-width: 10; stroke-linecap: round; transition: stroke-dashoffset .08s linear; }
.c3-struggle.stall .st-prog { stroke: #ff3a3a; }
.c3-struggle .st-knob { position: absolute; left: 50%; top: 50%; width: 22px; height: 22px; margin: -11px 0 0 -11px; border-radius: 50%; background: #fff; box-shadow: 0 0 10px #fff; }
.c3-struggle .st-count { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; font: 400 22px "Bangers", Impact, sans-serif; color: #fff; text-shadow: 2px 2px 0 #000; }
.c3-struggle .st-hint { position: absolute; left: 50%; bottom: calc(28px + var(--sb)); transform: translateX(-50%); font: 400 26px "Bangers", Impact, sans-serif; letter-spacing: .08em; color: #fff; text-shadow: 3px 3px 0 #000; pointer-events: none; white-space: nowrap; }
.c3-struggle.stall .st-hint { color: #ff5a6a; animation: st-shake .12s linear infinite; }
/* the Hive's high meter: the band below the mark is "sober" (nothing opens up) */
.c3-high { position: relative; }
.c3-high u { position: absolute; top: -3px; bottom: -3px; width: 3px; margin-left: -1px; background: #fff; box-shadow: 0 0 4px #000; }

/* === the act (src/act/): Supergirl or Impostor?, the UNMASKED panel, the act board === */
.spotcall { background: radial-gradient(ellipse at center, rgba(20, 6, 30, .55), rgba(4, 2, 10, .88)); }
.spotcall .modal { width: min(520px, 100%); padding: 0; background: transparent; border: 0; box-shadow: none; overflow: visible; }
.spot { display: flex; flex-direction: column; align-items: center; gap: 8px; }
.spot-head { text-align: center; }
.spot-head b { display: inline-block; padding: 4px 16px 2px; background: #ffd21a; color: #120a16; border: 3px solid #120a16; box-shadow: 4px 4px 0 #120a16; font: 30px/1 "Bangers", Impact, sans-serif; letter-spacing: .06em; transform: rotate(-2deg); }
.spot-head span { display: block; margin-top: 6px; font-size: 13px; color: #f2e6d0; opacity: .85; }
.spot-pic { position: relative; transform: rotate(1.5deg); }
.spot-pic img { display: block; width: auto; height: min(52vh, 340px); max-width: 86vw; box-shadow: 0 10px 30px #000c; }
.spot-stamp { position: absolute; left: 50%; top: 42%; transform: translate(-50%, -50%) rotate(-14deg) scale(2.4); opacity: 0; font: 64px/1 "Bangers", Impact, sans-serif; letter-spacing: .08em; padding: 2px 16px 0; border: 6px solid currentColor; border-radius: 8px; pointer-events: none; }
.spot-stamp.on { opacity: .92; transform: translate(-50%, -50%) rotate(-14deg) scale(1); transition: transform .22s cubic-bezier(.2, 1.6, .4, 1), opacity .12s; }
.spot-stamp.real { color: #2fd06a; }
.spot-stamp.fake { color: #ff2a4a; }
.spot-mock { display: none; max-width: min(460px, 92vw); padding: 7px 16px 6px; background: #ffe24a; color: #111; border: 3px solid #111; box-shadow: 5px 5px 0 rgba(0, 0, 0, .5); font: 20px/1.15 "Bangers", Impact, sans-serif; letter-spacing: .05em; text-transform: uppercase; transform: skew(-6deg); }
.spot-mock.on { display: block; animation: cap-in .45s cubic-bezier(.2, 1.3, .5, 1) both; }
.spot-mock.right { background: #c8f7d4; }
.spot-btns { display: flex; gap: 12px; }
.spot-b { min-width: 150px; min-height: 52px; padding: 0 18px; border: 3px solid #120a16; box-shadow: 4px 4px 0 #120a16; font: 26px/1 "Bangers", Impact, sans-serif; letter-spacing: .07em; color: #fff; cursor: pointer; }
.spot-b.real { background: #2459d8; }
.spot-b.fake { background: #c8102e; }
.spot-b.next { background: #120a16; }
.spot-b:active { transform: translate(2px, 2px); box-shadow: 2px 2px 0 #120a16; }
.spot-score { min-height: 1em; font-size: 12.5px; font-weight: 700; color: #f2e6d0; opacity: .85; text-align: center; max-width: 92vw; }
@media (max-height: 460px) { .spot-pic img { height: 44vh; } .spot-head b { font-size: 22px; } .spot-b { min-height: 42px; font-size: 21px; min-width: 120px; } .spot-mock { font-size: 16px; } }

.unmask { background: radial-gradient(ellipse at center, rgba(40, 6, 20, .5), rgba(4, 2, 10, .9)); }
.unmask .modal { width: min(620px, 100%); padding: 0; background: transparent; border: 0; box-shadow: none; overflow: visible; }
.um { position: relative; display: grid; grid-template-columns: auto 1fr; gap: 6px 16px; align-items: center; padding: 18px 18px 14px; background: #f6eed8; color: #16111c; border: 4px solid #120a16; box-shadow: 8px 8px 0 #120a16; transform: rotate(-1deg); animation: ev-pop .42s cubic-bezier(.2, 1.6, .4, 1); background-image: radial-gradient(rgba(0, 0, 0, .07) 1px, transparent 1.4px); background-size: 6px 6px; }
.um-burst { position: absolute; left: -12px; top: -12px; width: 190px; height: 190px; background: repeating-conic-gradient(#ffd21a 0 10deg, transparent 10deg 20deg); border-radius: 50%; opacity: .55; animation: um-spin 9s linear infinite; pointer-events: none; }
@keyframes um-spin { to { transform: rotate(360deg); } }
.um-pic { position: relative; grid-row: span 2; width: 120px; height: 157px; overflow: hidden; border: 3px solid #120a16; background: #6a7480; }
.um-pic canvas { width: 120px; height: 157px; display: block; }
.um-stamp { position: absolute; left: 6px; top: 118px; font: 32px/1 "Bangers", Impact, sans-serif; letter-spacing: .08em; color: #c8102e; border: 5px solid #c8102e; padding: 2px 10px 0; transform: rotate(-16deg); background: rgba(246, 238, 216, .8); animation: um-stamp .5s .25s cubic-bezier(.2, 1.6, .4, 1) both; }
@keyframes um-stamp { from { transform: rotate(-16deg) scale(3); opacity: 0; } }
.um-txt > b { display: block; font: 30px/1 "Bangers", Impact, sans-serif; letter-spacing: .05em; }
.um-txt > small { display: block; font-size: 12px; font-weight: 700; color: #b3122e; text-transform: uppercase; letter-spacing: .06em; margin-bottom: 6px; }
.um-line { font: italic 15px/1.35 Georgia, serif; margin: 4px 0 8px; }
.um-fact { font-size: 14px; line-height: 1.35; padding: 6px 8px; background: #fff7d0; border: 2px dashed #120a16; }
.um-fact b { display: inline; font: 700 14px system-ui; color: #b3122e; }
.um-key { margin-top: 8px; font: 18px/1 "Bangers", Impact, sans-serif; letter-spacing: .06em; color: #2a5a1a; }
.um-go { grid-column: 1 / -1; justify-self: end; min-height: 40px; padding: 0 16px; background: #120a16; color: #fff; border: 2px solid #120a16; font: 20px/1 "Bangers", Impact, sans-serif; letter-spacing: .08em; cursor: pointer; }
@media (max-height: 460px) { .um { padding: 10px 12px; } .um-pic { width: 90px; height: 118px; } .um-pic canvas { width: 90px; height: 118px; } .um-txt > b { font-size: 22px; } .um-line { font-size: 13px; margin: 2px 0 4px; } .um-fact { font-size: 12.5px; } .um-fact b { font-size: 12.5px; } .um-stamp { top: 96px; left: 0; font-size: 19px; border-width: 3px; padding: 2px 6px 0; } }

.actboard .modal { width: min(900px, 100%); }
.ab-grid { display: grid; grid-template-columns: 1fr 300px; gap: 12px; }
.ab-lts { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px 10px; padding-top: 6px; }
.ab-lt { position: relative; padding: 6px 6px 8px; background: rgba(30, 20, 14, .55); border: 2px dashed rgba(255, 240, 220, .5); color: #f2e6d0; transform: rotate(var(--r, 0deg)); text-align: center; overflow: hidden; }
.ab-lt.on { background: #fbf7ea; border: 2px solid #120a16; box-shadow: 3px 3px 0 rgba(18, 10, 22, .8); color: #16111c; }
.ab-ph { width: 60px; height: 76px; margin: 0 auto 4px; overflow: hidden; border: 2px solid #120a16; background: #3a3036; }
.ab-lt:not(.on) .ab-ph canvas { filter: brightness(0) opacity(.75); }
.ab-ph canvas { width: 120px; height: 157px; display: block; margin: -2px 0 0 -30px; }
.ab-lt > b { display: block; font: 18px/1 "Bangers", Impact, sans-serif; letter-spacing: .04em; color: inherit; }
.ab-lt.on > b { color: #b3122e; }
.ab-lt small { display: block; font-size: 10.5px; font-weight: 700; opacity: .8; }
.ab-lt p { font-size: 11px; line-height: 1.25; margin-top: 4px; }
.ab-lt p b { font: 700 11px system-ui; color: #b3122e; }
.ab-lt p.dim { opacity: .75; font-style: italic; }
.ab-stamp { position: absolute; right: -6px; top: 26px; font: 15px/1 "Bangers", Impact, sans-serif; letter-spacing: .08em; color: #c8102e; border: 3px solid #c8102e; padding: 2px 5px 0; transform: rotate(18deg); background: rgba(251, 247, 234, .85); }
.ab-side { display: flex; flex-direction: column; gap: 8px; }
.ab-boss { position: relative; text-align: center; padding: 6px; background: #120a16; color: #39ff6a; border: 2px solid #39ff6a; box-shadow: 3px 3px 0 rgba(18, 10, 22, .8); }
.ab-q { font: 46px/1 "Bangers", Impact, sans-serif; text-shadow: 0 0 14px #39ff6a; }
.ab-boss b { display: block; font: 20px/1 "Bangers", Impact, sans-serif; letter-spacing: .06em; color: #eafff0; }
.ab-boss small { font-size: 11px; opacity: .8; }
.ab-jig { background: #fbf7ea; border: 2px solid #120a16; padding: 4px; text-align: center; }
.ab-jig canvas { width: 100%; height: auto; display: block; border: 1px solid #120a16; }
.ab-jig small { font-size: 11px; font-weight: 700; }
.ab-gates { background: rgba(251, 247, 234, .92); border: 2px solid #120a16; padding: 4px 8px; }
.ab-gate { display: flex; justify-content: space-between; gap: 8px; font-size: 12px; font-weight: 700; padding: 2px 0; border-bottom: 1px dotted rgba(18, 10, 22, .25); }
.ab-gate b { font-variant-numeric: tabular-nums; }
.ab-gate.ok { color: #1f7a3a; }
@media (max-height: 460px) {
  .ab-grid { grid-template-columns: 1fr 236px; gap: 8px; }
  .ab-lts { gap: 8px 6px; padding-top: 4px; }
  .ab-lt { padding: 3px 4px 4px; }
  .ab-ph { width: 40px; height: 50px; margin-bottom: 2px; }
  .ab-ph canvas { width: 80px; height: 105px; margin: -2px 0 0 -20px; }
  .ab-lt > b { font-size: 14px; }
  .ab-lt small { font-size: 9.5px; }
  .ab-lt p { font-size: 9.5px; margin-top: 2px; }
  .ab-lt p b { font-size: 9.5px; }
  .ab-stamp { font-size: 11px; top: 14px; border-width: 2px; }
  .ab-boss { padding: 2px 4px; } .ab-q { font-size: 26px; } .ab-boss b { font-size: 15px; }
  .ab-jig canvas { height: 64px; object-fit: cover; }
  .ab-gate { font-size: 10.5px; padding: 1px 0; }
}
@media (max-width: 560px) { .ab-grid { grid-template-columns: 1fr; } .ab-lts { grid-template-columns: repeat(2, 1fr); } }

/* === r11 L (the club loop: the bouncers' read, tension, the struggle, skips) === */
#c3-threat { position: absolute; inset: 0; pointer-events: none; z-index: 49; overflow: hidden; }
.c3-sus, .c3-edge { position: absolute; left: 0; top: 0; width: 34px; height: 34px; margin: -17px 0 0 -17px; display: none; --p: 0; --c: #ffe040; }
.c3-sus.on, .c3-edge.on { display: block; }
.c3-sus .ring { position: absolute; inset: 0; border-radius: 50%; background: conic-gradient(var(--c) calc(var(--p) * 1%), rgba(22, 14, 32, .9) 0); border: 3px solid #111; box-shadow: 2px 2px 0 rgba(0, 0, 0, .55); }
.c3-sus .ring::after { content: ""; position: absolute; inset: 4px; border-radius: 50%; background: #16101f; }
.c3-sus b, .c3-edge b { position: absolute; inset: 0; z-index: 1; display: grid; place-items: center; font: 400 22px/1 "Bangers", Impact, sans-serif; color: #fff; text-shadow: 1px 1px 0 #000; }
.c3-sus .star { position: absolute; inset: -10px; display: none; background: #111; clip-path: var(--star); }
.c3-sus .star::after { content: ""; position: absolute; inset: 3px; background: #ffe040; clip-path: var(--star); }
.c3-sus.s-calm b { color: #fff; }
.c3-sus.s-sus { --c: #ffa020; } .c3-sus.s-sus b { color: #ffd84d; animation: c3-bob .5s ease-in-out infinite alternate; }
.c3-sus.s-search { --c: #ff7a1a; } .c3-sus.s-search b { color: #ffb070; } .c3-sus.s-search .ring { animation: c3-ping 1s ease-out infinite; }
.c3-sus.s-alert .ring { display: none; } .c3-sus.s-alert .star { display: block; animation: c3-bang .4s cubic-bezier(.2, 1.8, .5, 1) both; }
.c3-sus.s-alert b { color: #ff1a2a; font-size: 30px; text-shadow: 2px 2px 0 #111, -1px -1px 0 #111; }
@keyframes c3-bob { from { transform: translateY(1px); } to { transform: translateY(-3px); } }
@keyframes c3-ping { 0% { box-shadow: 0 0 0 0 rgba(255, 122, 26, .7), 2px 2px 0 rgba(0, 0, 0, .55); } 100% { box-shadow: 0 0 0 12px rgba(255, 122, 26, 0), 2px 2px 0 rgba(0, 0, 0, .55); } }
@keyframes c3-bang { from { transform: scale(.2) rotate(-30deg); } to { transform: none; } }
.c3-edge { width: 30px; height: 30px; margin: -15px 0 0 -15px; border-radius: 50%; background: #16101f; border: 3px solid var(--c); box-shadow: 2px 2px 0 rgba(0, 0, 0, .6); }
.c3-edge .arr { position: absolute; inset: 0; }
.c3-edge .arr::before { content: ""; position: absolute; right: -15px; top: 50%; margin-top: -8px; border: 8px solid transparent; border-left: 12px solid var(--c); }
.c3-edge b { font-size: 18px; color: var(--c); }
.c3-edge.s-sus { --c: #ffa020; } .c3-edge.s-search { --c: #ff7a1a; } .c3-edge.s-alert { --c: #ff2a3a; animation: c3-throb .5s ease-in-out infinite alternate; }
@keyframes c3-throb { to { box-shadow: 0 0 0 5px rgba(255, 42, 58, .35), 2px 2px 0 rgba(0, 0, 0, .6); } }
.c3-xtag { position: absolute; left: 0; top: 0; width: 92px; margin-left: -46px; display: none; padding: 2px 0 1px; text-align: center; font: 800 10px/1.2 system-ui, sans-serif; letter-spacing: .14em; color: #06121c; background: #3ad8ff; border: 2px solid #0a0a12; border-radius: 4px; box-shadow: 0 0 10px rgba(58, 216, 255, .55); }
.c3-xtag.on { display: block; }
.c3-xtag.s-sus { background: #ffb020; box-shadow: 0 0 10px rgba(255, 176, 32, .55); }
.c3-xtag.s-search { background: #ff8a2a; box-shadow: 0 0 10px rgba(255, 138, 42, .55); }
.c3-xtag.s-alert { background: #ff2a3a; color: #fff; box-shadow: 0 0 12px rgba(255, 42, 58, .7); }
.c3-xtag.s-ko { background: #7a8a9a; color: #111; box-shadow: none; }
#c3-vig { position: absolute; inset: 0; pointer-events: none; }
#c3-vig i { position: absolute; inset: 0; opacity: 0; }
#c3-vig .r { background: radial-gradient(ellipse 78% 74% at 50% 54%, transparent 52%, rgba(170, 0, 34, .5) 80%, rgba(90, 0, 18, .92) 100%); }
#c3-vig .c { background: radial-gradient(ellipse 82% 78% at 50% 50%, transparent 48%, rgba(60, 220, 255, .5) 100%); }
#c3-vig .c.go { animation: c3-relief 1.2s ease-out; }
@keyframes c3-relief { 0% { opacity: .95; } 100% { opacity: 0; } }
body:not([data-mode="club3"]) #c3-vig, body:not([data-mode="club3"]) #c3-threat { display: none; }
/* X-ray as a detective read: a scan sweeps down as it comes on, the club goes dark blue round the glowing bouncers */
body.c3-xray #xray-tint { background: radial-gradient(ellipse at center, rgba(30, 140, 220, .16), rgba(0, 30, 90, .55)); }
body.c3-xray #xray-tint::after { content: ""; position: absolute; left: 0; right: 0; top: -30%; height: 30%; background: linear-gradient(transparent, rgba(120, 230, 255, .4) 85%, rgba(200, 250, 255, .7)); animation: c3-xsweep .75s ease-out forwards; }
@keyframes c3-xsweep { to { top: 100%; } }
/* the struggle: a thumb circling (until she gets going, and whenever she stops), a jolt each quarter turn */
.c3-struggle .st-gest { position: absolute; left: 50%; top: 60%; width: 116px; height: 116px; margin: -58px 0 0 -58px; border: 3px dashed rgba(255, 255, 255, .6); border-radius: 50%; opacity: 0; transition: opacity .3s; pointer-events: none; }
.c3-struggle.gesture .st-gest { opacity: 1; }
.c3-struggle .st-gest i { position: absolute; left: 50%; top: 50%; width: 30px; height: 30px; margin: -15px 0 0 -15px; border-radius: 50%; background: rgba(255, 255, 255, .92); box-shadow: 0 0 16px #fff; animation: c3-orbit 1s linear infinite; }
@keyframes c3-orbit { from { transform: rotate(0deg) translateX(58px); } to { transform: rotate(360deg) translateX(58px); } }
.c3-struggle.jolt:not(.stall) video { animation: c3-jolt .18s ease-out; }
@keyframes c3-jolt { 0% { transform: scale(1.035) translate(-5px, 3px); } 100% { transform: none; } }
.c3-struggle .st-text b { color: #ffd84d; }
/* clips: the way out is always on screen, top right, and says how many taps it takes */
#cutscene .cs-skip, #cutscene.screen .cs-skip { right: calc(12px + var(--sr)); top: calc(10px + var(--st)); bottom: auto; z-index: 3; opacity: 1; padding: 8px 14px 7px; color: #fff; background: rgba(10, 6, 18, .85); border: 2px solid #fff; border-radius: 999px; box-shadow: 3px 3px 0 rgba(0, 0, 0, .55); font: 400 16px/1 "Bangers", Impact, sans-serif; letter-spacing: .07em; white-space: nowrap; }
#cutscene .cs-skip b { margin-left: 5px; color: #ffd84d; }
#cutscene .cs-skip i { margin-left: 8px; font-style: normal; letter-spacing: .12em; color: #ffd84d; }
#cutscene .cs-skip.nudge { animation: c3-nudge 1.1s ease-in-out infinite; }
@keyframes c3-nudge { 50% { transform: scale(1.08); box-shadow: 0 0 0 5px rgba(255, 216, 77, .45), 3px 3px 0 rgba(0, 0, 0, .55); } }

/* === r11 D === */
/* D1 the S-shield struggle: the shield in the old ring's spot (pentagon ≈ the ring's disc: ~7.8k px²) */
.c3-struggle .st-shield { position: absolute; right: calc(24px + var(--sr)); bottom: calc(24px + var(--sb)); width: 156px; height: 107px; pointer-events: none; }
.c3-struggle .st-shield img { position: absolute; inset: 0; width: 100%; height: 100%; clip-path: polygon(16.5% 9.4%, 84.2% 8.8%, 93.4% 28.1%, 88.2% 32.5%, 79.5% 40.0%, 72.6% 47.5%, 64.5% 58.8%, 55.8% 73.8%, 46.8% 88.8%, 43.8% 91.6%, 40.4% 88.8%, 31.8% 77.5%, 21.8% 62.5%, 13.0% 47.5%, 6.2% 36.2%, 4.5% 30.6%, 7.1% 25.0%, 13.9% 13.8%); filter: contrast(1.12) saturate(1.15); }
.c3-struggle .st-shield svg { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
.c3-struggle .sg-rim { fill: none; stroke: #0b0b12; stroke-width: 9; stroke-linejoin: round; }
.c3-struggle .sg-lane { fill: none; stroke: rgba(0, 0, 0, .22); stroke-width: 66; stroke-linecap: round; stroke-linejoin: round; }
.c3-struggle .sg-ink { fill: none; stroke: #0b0b12; stroke-width: 15; stroke-linecap: round; stroke-linejoin: round; }
.c3-struggle .sg-guide { fill: none; stroke: #fff6c8; stroke-width: 5; stroke-dasharray: 14 12; stroke-linecap: round; stroke-linejoin: round; }
.c3-struggle .sg-glow { fill: none; stroke: rgba(255, 216, 77, .6); stroke-width: 34; stroke-linecap: round; stroke-linejoin: round; }
.c3-struggle .sg-trail { fill: none; stroke: #fff; stroke-width: 13; stroke-linecap: round; stroke-linejoin: round; }
.c3-struggle .sg-end { fill: #fff; stroke: #0b0b12; stroke-width: 5; opacity: .45; }
.c3-struggle .st-shield.fresh .sg-end { opacity: 1; fill: #ffd84d; animation: sg-pulse .7s ease-in-out infinite alternate; }
@keyframes sg-pulse { from { stroke-width: 5; } to { stroke-width: 14; stroke: rgba(255, 255, 255, .85); } }
.c3-struggle .sg-cur { fill: #fff; stroke: #ffd84d; stroke-width: 8; }
.c3-struggle .sg-count { font: 400 52px "Bangers", Impact, sans-serif; fill: #fff; stroke: #0b0b12; stroke-width: 9; paint-order: stroke; text-anchor: middle; }
.c3-struggle.stall .sg-trail { stroke: #ff5a6a; }
.c3-struggle.stall .sg-glow { stroke: rgba(255, 40, 60, .5); }
.c3-struggle .st-shield.flash { animation: sg-flash .45s ease-out; }
@keyframes sg-flash { 0% { transform: scale(1.18); filter: drop-shadow(0 0 14px #ffd84d) brightness(1.5); } 100% { transform: none; filter: none; } }
.c3-struggle .st-shield.miss { animation: sg-miss .3s linear; }
@keyframes sg-miss { 0%, 100% { transform: none; } 25% { transform: translateX(-7px) rotate(-3deg); filter: sepia(1) hue-rotate(-50deg) saturate(3); } 75% { transform: translateX(6px) rotate(2deg); } }
/* the ghost: a dot tracing a thumb-sized S (2.4x the pad's), where the old orbiting dot was */
.c3-struggle .st-gest.sg { width: 264px; height: 120px; margin: -60px 0 0 -132px; border: 0; border-radius: 0; }
.c3-struggle .st-gest.sg svg { width: 100%; height: 100%; overflow: visible; }
.c3-struggle .sg-ghost { fill: none; stroke: rgba(255, 255, 255, .6); stroke-width: 5; stroke-dasharray: 12 12; stroke-linecap: round; stroke-linejoin: round; }
.c3-struggle .sg-gdot { fill: rgba(255, 255, 255, .92); }
/* her line: a comic bubble over the shield */
.c3-struggle .st-say { position: absolute; right: calc(16px + var(--sr)); bottom: calc(142px + var(--sb)); max-width: min(300px, 46vw); padding: 7px 12px 6px; background: #fff; color: #111; border: 3px solid #0b0b12; border-radius: 16px; box-shadow: 3px 3px 0 rgba(0, 0, 0, .5); font: 400 21px/1.1 "Bangers", Impact, sans-serif; letter-spacing: .04em; text-align: center; pointer-events: none; opacity: 0; transform: scale(.6); transform-origin: 80% 100%; transition: opacity .12s, transform .12s; }
.c3-struggle .st-say::after { content: ""; position: absolute; right: 52px; bottom: -14px; border: 7px solid transparent; border-top: 9px solid #0b0b12; border-bottom: 0; }
.c3-struggle .st-say.on { opacity: 1; transform: none; }
.c3-struggle .st-say.win { background: #ffd84d; font-size: 26px; }
.c3-struggle .st-say.miss { background: #f3e9ee; color: #7a0618; font-size: 18px; font-style: italic; }

/* === r11 F === */
/* the LIVE clip over the 3D flight: Chromium culled the WebGL canvas in a box the clip's size, mirrored
   below it (the "black box" in the harness frames: the page background showing through). A no-op filter
   draws the clip through its own surface, which avoids it; the panel itself is unchanged. */
#feed video { filter: contrast(1.001); }
/* the air events' verdict panel (src/moments/verdict.js): left of centre, clear of the LIVE panel and the controls */
#mo-verdict { position: absolute; left: calc(16px + var(--sl, 0px)); top: 30%; width: min(480px, calc(100vw - 330px)); min-width: 240px; padding: 8px 18px 9px; z-index: 54; pointer-events: none; text-align: center; border: 4px solid #0b0b12; box-shadow: 6px 6px 0 rgba(0, 0, 0, .55); transform: rotate(-2deg) scale(.3); opacity: 0; transition: opacity .12s, transform .16s cubic-bezier(.2, 1.6, .4, 1); background-image: radial-gradient(rgba(0, 0, 0, .16) 1.2px, transparent 1.4px); background-size: 7px 7px; }
#mo-verdict.won { background-color: #ffd84d; color: #12081c; }
#mo-verdict.lost { background-color: #e8323f; color: #fff; }
#mo-verdict.on { opacity: 1; transform: rotate(-2deg) scale(1); }
#mo-verdict b { display: block; font: 400 54px/1 "Bangers", Impact, sans-serif; letter-spacing: .05em; -webkit-text-stroke: 2px #0b0b12; text-shadow: 3px 3px 0 #0b0b12; }
#mo-verdict.won b { color: #fff; }
#mo-verdict small { display: block; margin-top: 2px; font: 800 13px/1.2 system-ui, sans-serif; letter-spacing: .03em; text-transform: uppercase; }
@media (max-height: 480px) { #mo-verdict b { font-size: 44px; } #mo-verdict small { font-size: 11px; } }
/* === r11 F2b === */
/* one message lane while a flight moment runs: toasts drop below the moment's banner (never on it) */
body.mo-on #toasts { top: calc(124px + var(--st)); left: 38%; } /* (left of the LIVE panel) */
@media (max-height: 480px) { body.mo-on #toasts { top: calc(112px + var(--st)); } }
/* captions in flight: clear of the joystick's rest spot and of the left edge (the skew pushed them off it) */
@media (max-height: 480px) { body[data-mode="overworld"] .caption, body[data-mode="overworld"] .newsflash { bottom: calc(176px + var(--sb)); left: calc(22px + var(--sl)); } }
/* the impostor unmasked: a comic panel instead of the Continue box (auto-dismisses) */
#mo-unmask { position: absolute; left: calc(16px + var(--sl, 0px)); top: 22%; width: min(500px, calc(100vw - 330px)); min-width: 250px; z-index: 54; pointer-events: none; padding: 10px 18px 12px; border: 4px solid #0b0b12; box-shadow: 7px 7px 0 rgba(0, 0, 0, .55); background-color: #3fa0ff; color: #fff; background-image: radial-gradient(rgba(0, 0, 0, .18) 1.2px, transparent 1.4px); background-size: 7px 7px; transform: rotate(-3deg) scale(.3); opacity: 0; transition: opacity .12s, transform .18s cubic-bezier(.2, 1.6, .4, 1); text-align: center; }
#mo-unmask.on { opacity: 1; transform: rotate(-3deg) scale(1); }
#mo-unmask b { display: block; font: 400 60px/1 "Bangers", Impact, sans-serif; letter-spacing: .05em; color: #ffe23a; -webkit-text-stroke: 2px #0b0b12; text-shadow: 4px 4px 0 #0b0b12; }
#mo-unmask small { display: block; margin-top: 4px; font: 800 13px/1.25 system-ui, sans-serif; letter-spacing: .03em; text-transform: uppercase; text-shadow: 1px 1px 0 #0b0b12; }
#mo-unmask i { position: absolute; right: -14px; top: -18px; font: 400 26px/1 "Bangers", Impact, sans-serif; font-style: normal; background: #ffe23a; color: #0b0b12; border: 3px solid #0b0b12; padding: 3px 8px; transform: rotate(10deg); }
@media (max-height: 480px) { #mo-unmask b { font-size: 48px; } #mo-unmask small { font-size: 11px; } }

/* === r11 L2b (the feel: spotted / lost them stamps, the spot edge, slim club stats, X-ray chips, the clue beacon) === */
#c3-vig .s { background: radial-gradient(ellipse 70% 66% at 50% 52%, transparent 40%, rgba(220, 0, 40, .55) 72%, rgba(150, 0, 20, .97) 100%); box-shadow: inset 0 0 0 10px rgba(200, 0, 30, .9); }
#c3-stamp { position: absolute; left: 50%; top: calc(64px + var(--st)); z-index: 53; pointer-events: none; display: none; padding: 2px 16px 0; font: 400 40px/1.05 "Bangers", Impact, sans-serif; letter-spacing: .06em; color: #fff; border: 4px solid #111; border-radius: 6px; box-shadow: 4px 4px 0 rgba(0, 0, 0, .6); -webkit-text-stroke: 1.5px #111; text-shadow: 3px 3px 0 #111; white-space: nowrap; }
#c3-stamp.on { display: block; animation: c3-stamp .4s cubic-bezier(.2, 1.6, .4, 1) both; }
#c3-stamp.on.out { animation: c3-stamp-out .3s ease-in both; }
#c3-stamp.s-spot { background: #e0142e; transform: translateX(-50%) rotate(-4deg); }
#c3-stamp.s-lost { background: #18b8e8; transform: translateX(-50%) rotate(3deg); }
@keyframes c3-stamp { 0% { opacity: 0; scale: 2.2; } 60% { opacity: 1; scale: .94; } 100% { opacity: 1; scale: 1; } }
@keyframes c3-stamp-out { from { opacity: 1; } to { opacity: 0; scale: 1.06; } }
@media (max-height: 480px) { #c3-stamp { font-size: 30px; top: calc(52px + var(--st)); } }
/* slim stats in the club: thin bars, small labels; the panel fades back while nothing's happening */
body[data-mode="club3"] #hud-left { width: 124px; padding: 4px 8px 5px; transition: opacity .4s; }
body[data-mode="club3"] #hud-left .rank, body[data-mode="club3"] #hud-left .barlabel { font-size: 8.5px; margin-top: 2px; }
body[data-mode="club3"] #hud-left .rep { font-size: 17px; }
body[data-mode="club3"] #hud-left .bar { height: 4px; margin-top: 1px; }
body[data-mode="club3"] #hud-left.c3-calm { opacity: .5; }
/* X-ray tags: a glyph in a coloured chip, not a word */
.c3-xtag.r11b { width: auto; min-width: 24px; margin-left: 0; translate: -50% 0; padding: 1px 6px 0; font: 400 15px/1.15 "Bangers", Impact, sans-serif; letter-spacing: .04em; }
#c3-beacon { position: absolute; left: 0; top: 0; pointer-events: none; display: none; width: 30px; height: 30px; margin: -15px 0 0 -15px; }
#c3-beacon.on { display: block; }
#c3-beacon i { position: absolute; inset: 5px; background: #ffd84d; border: 3px solid #111; rotate: 45deg; box-shadow: 0 0 14px 5px rgba(255, 216, 77, .8); animation: c3-beac .7s ease-in-out infinite alternate; }
#c3-beacon b { position: absolute; left: 50%; top: 31px; translate: -50% 0; font: 400 13px "Bangers", Impact, sans-serif; letter-spacing: .08em; color: #ffd84d; text-shadow: 1px 1px 0 #000, -1px -1px 0 #000; white-space: nowrap; }
@keyframes c3-beac { from { scale: .8; } to { scale: 1.2; } }
/* === r11 F2c === */
/* the verdict panel shares the frame with the payoff in her hands (car overhead, kitten held up): smaller, up in the top-left corner, clear of her */
#mo-verdict { top: 18%; width: min(310px, calc(100vw - 420px)); min-width: 220px; padding: 6px 14px 7px; }
#mo-verdict b { font-size: 46px; }
@media (max-height: 480px) { #mo-verdict { top: 16%; } #mo-verdict b { font-size: 38px; } #mo-verdict small { font-size: 10px; } }
