* { box-sizing: border-box; margin: 0; padding: 0; -webkit-tap-highlight-color: transparent; }

[hidden] { display: none !important; }

:root {
  --bg: #0b0d1a;
  --card: #161a2e;
  --border: #2a3050;
  --text: #eef0ff;
  --muted: #8b91b5;
  --accent: #38fedc;
  --primary: #1d9bf0;
  --danger: #c51111;
  --impostor: #ff3b30;
}

html, body { height: 100%; }
body {
  /* Among Us UI text: plain Arial, white, thick black outline, not bold.
     -webkit-text-stroke + paint-order are inherited, so this styles all text. */
  font-family: Arial, Helvetica, sans-serif;
  font-weight: 400;
  -webkit-text-stroke: 2.5px #000;
  paint-order: stroke fill;
  background: var(--bg);
  color: var(--text);
  overflow-x: hidden;
}
h1, h2, h3, b, strong, button { font-weight: 400; }
.logo, .meeting-title, .meeting-timer, .dead-title,
#end-title, .btn-report, .btn-kill, .btn-big {
  -webkit-text-stroke: 5px #000;
}
label, .muted, .tag, .sub, .progress-label, .error, input {
  -webkit-text-stroke: 1.5px #000;
}

.crew { flex-shrink: 0; width: auto; }
.crew-sm { height: 30px; }
.crew-md { height: 48px; }
.crew-lg { height: 84px; }
.crew-xl { height: 150px; }

#stars {
  position: fixed; inset: 0; z-index: -1;
  background:
    radial-gradient(1px 1px at 20% 30%, #fff 100%, transparent),
    radial-gradient(1px 1px at 70% 12%, #fff 100%, transparent),
    radial-gradient(2px 2px at 84% 56%, #ccd 100%, transparent),
    radial-gradient(1px 1px at 40% 78%, #fff 100%, transparent),
    radial-gradient(1px 1px at 92% 88%, #aab 100%, transparent),
    radial-gradient(2px 2px at 10% 64%, #dde 100%, transparent),
    radial-gradient(1px 1px at 55% 44%, #fff 100%, transparent),
    var(--bg);
}

/* Animated drifting starfield (js/starfield.js): pre-room page background, over
   the static #stars. Black so it reads as space; hidden in a room (static #stars
   returns). White specks (.menu-star) are appended here from JS. */
#starfield {
  position: fixed; inset: 0; z-index: -1;
  background: #000;
}
/* While the startup menu is up, hide the app screens so the shared starfield
   shows behind the transparent menu overlay. */
body.menu-active .screen { visibility: hidden; }

.screen {
  min-height: 100dvh;
  padding: 24px 16px 40px;
  display: flex;
  flex-direction: column;
  gap: 14px;
  max-width: 480px;
  margin: 0 auto;
}

.overlay {
  position: fixed; inset: 0; z-index: 20;
  background: var(--bg);
  max-width: none;
  align-items: center;
  justify-content: center;
}

.logo {
  text-align: center;
  font-size: 2rem;
  letter-spacing: 3px;
  text-shadow: 0 0 18px rgba(56, 254, 220, .35);
  margin: 12px 0 4px;
}
.logo span { color: var(--accent); }
.home-logo { display: block; width: min(80vw, 360px); height: auto; margin: 20px auto 8px; }

h2 { font-size: 1rem; margin-bottom: 10px; letter-spacing: 1px; }

.card {
  background: var(--card);
  border: 2px solid var(--border);
  border-radius: 14px;
  padding: 14px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

label { font-size: .8rem; color: var(--muted); }

input[type=text], input:not([type]) {
  width: 100%;
  padding: 12px;
  border-radius: 10px;
  border: 2px solid var(--border);
  background: #0e1122;
  color: var(--text);
  font-size: 1.05rem;
  font-family: inherit;
}
input:focus { outline: none; border-color: var(--primary); }

.code-input { text-transform: uppercase; letter-spacing: 6px; text-align: center; width: 130px; }
.row { display: flex; gap: 8px; align-items: center; }
.row input { flex: 1; }

.check { display: flex; gap: 8px; align-items: center; font-size: .9rem; color: var(--text); }
.check input { width: 20px; height: 20px; }

.btn {
  padding: 14px;
  border-radius: 12px;
  border: 2px solid var(--border);
  background: #222947;
  color: var(--text);
  font-family: inherit;
  font-size: 1rem;
  letter-spacing: 1px;
  cursor: pointer;
  touch-action: manipulation;
}
.btn:active { transform: scale(.97); }
.btn:disabled { opacity: .45; }
.btn-primary { background: var(--primary); border-color: #1478c0; }
.btn-danger { background: #5c1220; border-color: #8f1f36; }
.btn-small { padding: 8px 12px; font-size: .85rem; align-self: center; }
.btn-big { font-size: 1.25rem; padding: 18px; }

.btn-kill {
  background: var(--impostor);
  border-color: #a11;
  font-size: 1.6rem;
  padding: 20px;
}

.btn-report {
  background: var(--danger);
  border-color: #8f0d0d;
  font-size: 2.2rem;
  padding: 34px 20px;
  line-height: 1.1;
}
.btn-report span { font-size: .9rem; font-weight: normal; letter-spacing: 2px; }

.muted { color: var(--muted); font-size: .85rem; }
.center { text-align: center; }
.error { color: #ff7b7b; text-align: center; font-size: .9rem; }

.home-step { display: flex; flex-direction: column; gap: 14px; }
.menu-btns { display: flex; flex-direction: column; gap: 14px; margin-top: 10px; }
.dev-row { display: flex; gap: 10px; justify-content: center; }
.dev-row .btn-small { flex: 1; align-self: stretch; }
.btn-ghost { background: transparent; border-color: var(--border); color: var(--muted); }

.room-list { display: flex; flex-direction: column; gap: 8px; }
.room-item {
  display: flex; justify-content: space-between; align-items: center;
  background: #0e1122; border: 2px solid var(--border);
  border-radius: 10px; padding: 10px 12px;
}
.room-item .btn { padding: 8px 14px; }

.room-code { color: var(--accent); letter-spacing: 4px; font-size: 1.2rem; }

.qr-box { display: flex; justify-content: center; }
.qr-box img { image-rendering: pixelated; border-radius: 8px; background: #fff; padding: 8px; }

.player-list { display: flex; flex-direction: column; gap: 6px; }
.player-item { display: flex; align-items: center; gap: 10px; padding: 6px 4px; }
.player-item .tag { font-size: .7rem; color: var(--muted); }
.player-item.dead { opacity: .5; text-decoration: line-through; }
.player-item.imp span, .player-item.imp .tag { color: var(--impostor); }

.color-picker { display: flex; flex-wrap: wrap; gap: 8px; justify-content: center; }
.color-swatch {
  background: none; padding: 4px; border-radius: 12px;
  border: 3px solid transparent; cursor: pointer;
}
.color-swatch.taken { opacity: .25; pointer-events: none; }
.color-swatch.mine { border-color: #fff; box-shadow: 0 0 10px rgba(255,255,255,.6); }

.settings-row { display: flex; justify-content: space-between; align-items: center; gap: 8px; padding: 4px 0; }
.settings-row .set-label { font-size: .85rem; color: var(--muted); flex: 1; }
.settings-row input[type=number] {
  width: 74px; padding: 8px; border-radius: 8px;
  border: 2px solid var(--border); background: #0e1122; color: var(--text);
  font-family: inherit; font-size: 1rem; text-align: center;
}
.settings-tasks { display: flex; flex-direction: column; gap: 4px; max-height: 180px; overflow-y: auto; }

.progress-wrap { position: sticky; top: 0; z-index: 5; background: var(--bg); padding: 6px 0; }
.progress-label { font-size: .65rem; letter-spacing: 2px; color: var(--muted); margin-bottom: 4px; }
.progress-bar {
  height: 22px; border-radius: 11px; overflow: hidden;
  border: 2px solid var(--border); background: #0e1122;
}
.progress-fill {
  height: 100%; width: 0%;
  background: linear-gradient(90deg, #0f8a3d, #2ee56b);
  transition: width .4s;
}

.task-list { list-style: none; display: flex; flex-direction: column; gap: 8px; }
.task-list li {
  padding: 10px 12px; border-radius: 10px;
  background: #0e1122; border: 2px solid var(--border);
  font-size: .95rem;
}
.task-list li.done { color: #2ee56b; border-color: #14532d; text-decoration: line-through; }

.impostor-title { color: var(--impostor); text-align: center; }
.dead-title { color: var(--danger); text-align: center; font-size: 3.4rem; margin: 24px 0 8px; letter-spacing: 2px; }

.meeting-title { text-align: center; font-size: 1.5rem; margin-top: 20px; }
.meeting-timer { text-align: center; font-size: 2.4rem; color: var(--accent); }

.modal {
  position: fixed; inset: 0; z-index: 30;
  background: rgba(0, 0, 0, .8);
  display: flex; align-items: center; justify-content: center; padding: 20px;
}
.modal-box {
  background: var(--card); border: 1px solid var(--border); border-radius: 12px;
  padding: 20px; width: 100%; max-width: 420px;
  display: flex; flex-direction: column; gap: 14px;
}

.vote-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.vote-cell { position: relative; display: flex; }
.vote-cell.vote-skip { grid-column: 1 / -1; }
.vote-btn {
  flex: 1; display: flex; align-items: center; gap: 8px;
  padding: 12px; border-radius: 12px;
  background: var(--card); border: 2px solid var(--border);
  color: var(--text); font-family: inherit; font-size: .95rem;
  cursor: pointer;
}
.vote-cell.vote-skip .vote-btn { justify-content: center; }
.vote-cell.selected .vote-btn { border-color: var(--accent); }
.vote-btn:disabled { opacity: .4; }
/* Confirm controls on the selected cell: square green tick + red cross, pinned to
   the right of the row like the real game (no dark veil — the crewmate stays visible). */
.vote-confirm-bar {
  position: absolute; inset: 0; display: flex; gap: 8px;
  align-items: center; justify-content: flex-end;
  padding: 6px; pointer-events: none;
}
.vote-confirm {
  pointer-events: auto;
  width: 46px; height: 46px; aspect-ratio: 1; border-radius: 12px;
  border: 2px solid rgba(255, 255, 255, .55); padding: 0;
  display: flex; align-items: center; justify-content: center;
  cursor: pointer; color: #fff; box-shadow: 0 2px 6px rgba(0, 0, 0, .4);
}
.vote-confirm.yes { background: #2ee56b; }
.vote-confirm.no { background: var(--impostor); }
.vote-confirm:active { transform: scale(.92); }
.vote-icon { width: 24px; height: 24px; }

.results-row { display: flex; align-items: center; gap: 8px; padding: 6px 4px; font-size: .95rem; }
.results-row .votes { margin-left: auto; color: var(--accent); }

/* ---- Role reveal — exact port of the Scratch "Role reveal" sprite ----
   Rebuilt on a 480x360 virtual stage (Scratch stage). Every element is placed
   with Scratch's own mapping: left% = (240 + x - rcX)/480, top% = (180 - y -
   rcY)/360, width% = costumeWidth/480 — so positions/sizes match the original
   pixel-for-pixel. Timings mirror the blocks at 30fps. */
@font-face {
  font-family: 'VCR OSD Mono';
  src: url('../assets/fonts/vcr-osd-mono.ttf') format('truetype');
  font-display: block;
}
@font-face {
  font-family: 'OCR A Extended';
  src: url('../assets/fonts/ocr-a-extended.ttf') format('truetype');
  font-display: block;
}

.reveal { background: #000; overflow: hidden; }
.rv-stage {
  position: absolute; left: 50%; top: 50%;
  transform: translate(-50%, -50%);
  width: min(100vw, 133.333dvh);   /* fit the 4:3 stage inside the phone */
  aspect-ratio: 480 / 360;
  container-type: size;            /* cqw/cqh = stage dimensions */
}
.reveal-layer { position: absolute; inset: 0; }
.rv-stage img { position: absolute; }
.rv-title, .rv-sub { position: absolute; margin: 0; -webkit-text-stroke: 0; white-space: nowrap; }

/* Phase A — Shhh */
.rv-bg {
  left: 18.411%; top: 6.349%; width: 63.476%;
  transform-origin: 49.766% 50%;
  animation: rv-spin 17.143s linear infinite;
}
.rv-top {
  left: 28.122%; top: 18.839%; width: 43.756%;
  transform-origin: 50% 50%;
  animation: rv-pop 0.4s linear 0.4s both;
}
.rv-shhh-text {
  left: 18.155%; top: 74.167%; width: 61.012%;
  opacity: 0;
  animation: rv-appear 0.01s linear 0.4s forwards;
}
.rv-finger {
  top: 43.690%; width: 13.001%;
  left: 60.437%;
  animation: rv-finger 0.4s linear both;
}

/* Phase B — Reveal */
.rv-band {
  left: 0; top: 49.975%; width: 100%;
  opacity: 0;
  animation: rv-appear 2.667s linear both;
}
.rv-crew {                       /* Character sprite: size 50 @ (0,-79) */
  left: 42.188%; top: 58.194%; width: 15.625%;
  opacity: 0;
  animation: rv-appear 0.667s linear both, rv-drift-up 4.4s linear both;
}
.rv-title {
  left: 50%; top: 26.389%;
  transform: translate(-50%, -50%);
  font-family: 'VCR OSD Mono', monospace;
  font-size: 12cqw; letter-spacing: .02em; text-align: center;
  opacity: 0;
  animation: rv-appear 1.333s linear both, rv-drift-down 4.4s linear both;
}
.rv-title.crew { color: #27deff; }
.rv-title.impostor { color: #ff1c1c; }
.rv-sub {
  left: 50%; top: 44%;
  transform: translate(-50%, -50%);
  font-family: 'VCR OSD Mono', monospace;
  font-size: 2.88cqw; text-align: center; color: #fff;
  opacity: 0;
  animation: rv-appear 1.333s linear 0.7s both;
}

/* ---- Task Completed banner (exact port of the Scratch "Task Completed") ----
   Same 480x360 virtual stage. The banner (costume 264x74, rc≈centre) is placed
   centred and its Y is driven frame-by-frame in JS to match the Scratch script
   (spring up from y=-500, hold, then fly up +40/frame). */
.tc-overlay { position: fixed; inset: 0; z-index: 40; pointer-events: none; }
.transition-veil {
  position: fixed; inset: 0; z-index: 41;   /* in FRONT of the banner (z40) */
  background: #646464;      /* Scratch transition costume: solid #646464 */
  opacity: 0; pointer-events: none;
}
.tc-stage {
  position: absolute; left: 50%; top: 50%;
  transform: translate(-50%, -50%);
  width: min(100vw, 133.333dvh);
  aspect-ratio: 480 / 360;
  container-type: size;
}
.tc-banner {
  position: absolute; left: 50%; top: 50%;
  width: 55.012%;              /* 264.058 / 480 */
  opacity: .94;                /* ghost 6 */
  transform: translate(-50%, -50%);
}

/* ---- Meeting announcement (exact port of the Scratch "Emergecy Meeting Button"
   full-screen splash: flashing red BG + figure + title, size 120 on the same
   letterboxed 480x360 stage). Costume swaps are discrete, so placement is set
   inline from JS; no keyframes. ---- */
.ma-overlay {
  position: fixed; inset: 0; z-index: 45;
  background: #000; overflow: hidden; pointer-events: none;
}
.ma-stage {
  position: absolute; left: 50%; top: 50%;
  transform: translate(-50%, -50%);
  width: min(100vw, 133.333dvh);
  aspect-ratio: 480 / 360;
  container-type: size;
}
.ma-stage img { position: absolute; }

@keyframes rv-spin { to { transform: rotate(-360deg); } }
@keyframes rv-appear { from { opacity: 0; } to { opacity: 1; } }
/* Slow drift during the reveal (Scratch Reveal2 changeyby -0.02): title eases
   down, the crewmate eases up. `translate` composes with the centering transform. */
@keyframes rv-drift-down { from { translate: 0 0; } to { translate: 0 2.5cqh; } }
@keyframes rv-drift-up   { from { translate: 0 0; } to { translate: 0 -2.5cqh; } }
@keyframes rv-pop {                          /* size 100→115→100, once */
  0% { transform: scale(1); }
  50% { transform: scale(1.15); }
  100% { transform: scale(1); }
}
@keyframes rv-finger { from { left: 60.437%; } to { left: 43.770%; } }

#end-title { text-align: center; font-size: 2.2rem; margin-top: 30px; }
#end-title.crew { color: var(--accent); }
#end-title.impostors { color: var(--impostor); }

#screen-scan { justify-content: center; gap: 20px; }
#scan-video { width: min(92vw, 480px); border-radius: 14px; border: 2px solid var(--border); }
.scan-hint { color: var(--muted); }

.minigame-root { width: min(92vw, 420px); display: flex; flex-direction: column; gap: 16px; }

/* ---- start countdown (3…2…1 before the role reveal) ---- */
/* .overlay sets align/justify but not display, so make the countdown a flexbox
   itself, otherwise the digit falls to the top-left. Deliberately plain: no
   glow, no animation, no sound. */
.countdown { display: flex; align-items: center; justify-content: center; background: #000; }
.cd-num {
  font-family: 'VCR OSD Mono', monospace;
  font-size: 9rem; line-height: 1; color: #fff;
}

/* ---- KILL indicator (not a button — shows the impostor's kill cooldown) ---- */
.kill-indicator {
  width: 100%; box-sizing: border-box;
  border-radius: 12px; text-align: center;
  color: #fff; letter-spacing: 1px;
  cursor: default; user-select: none; -webkit-user-select: none;
}
.kill-indicator.cooling { opacity: .5; }

/* ---- corner exit button: circular red "X" in VCR OSD Mono (during play/meeting) ---- */
#btn-corner-exit {
  position: fixed; bottom: 12px; right: 12px; z-index: 15;
  width: 46px; height: 46px; border-radius: 50%; padding: 0;
  display: flex; align-items: center; justify-content: center;
  font-family: 'VCR OSD Mono', monospace; font-size: 1.6rem; line-height: 1;
  color: #ff1c1c; background: rgba(20, 24, 40, .82);
  border: 1px solid var(--border);
  backdrop-filter: blur(3px); -webkit-backdrop-filter: blur(3px);
  cursor: pointer; touch-action: manipulation;
}
#btn-corner-exit[data-armed] { background: #ff1c1c; color: #fff; } /* first tap: confirm */
#btn-corner-exit:active { transform: scale(.94); }

/* ---- fellow impostors panel ---- */
.fellow-impostors {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: center;
  gap: 8px 12px; margin-bottom: 10px;
}
.fellow-label { width: 100%; text-align: center; color: var(--muted); font-size: .8rem; letter-spacing: 1px; }
.fellow { display: inline-flex; align-items: center; gap: 5px; color: var(--impostor); font-size: .95rem; }

/* ---- host role pre-assignment modal ---- */
.assign-row {
  display: flex; align-items: center; gap: 10px; width: 100%;
  padding: 10px; border-radius: 10px; text-align: left;
  border: 2px solid var(--border); background: #222947; color: var(--text);
  cursor: pointer; font-family: inherit; font-size: 1rem;
}
.assign-name { flex: 1; }
.assign-tag { font-size: .72rem; letter-spacing: 1px; padding: 3px 8px; border-radius: 6px; }
.assign-row.auto .assign-tag { background: #333b5c; color: var(--muted); }
.assign-row.impostor { border-color: #a11; }
.assign-row.impostor .assign-tag { background: var(--impostor); color: #fff; }
.assign-row.crew { border-color: #1478c0; }
.assign-row.crew .assign-tag { background: var(--primary); color: #fff; }

/* ---- fullscreen join QR ---- */
#lobby-qr { cursor: pointer; }
.qr-full {
  position: fixed; inset: 0; z-index: 50; background: #fff;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 16px;
}
.qr-full #qr-full-code img { width: min(92vw, 92vh); height: auto; image-rendering: pixelated; }
.qr-full p { color: #222; font-family: inherit; letter-spacing: .3px; -webkit-text-stroke: 0; }

/* ---- startup menu — faithful port of the Scratch "Main menu elements" ----
   The TurboWarp stage for this project is 480×640 (portrait). Every element is
   placed with Scratch's own mapping on that stage: left% = (240 + x − rcX·s)/480,
   top% = (320 − y − rcY·s)/640, width% = costumeW·s/480 (s = size/100, origin
   centred, y up). Above every other screen (qr-full is z50). The whole overlay
   fades out on PLAY. */
.menu-overlay {
  position: fixed; inset: 0; z-index: 60;
  background: transparent; overflow: hidden;  /* the #starfield shows through */
  transition: opacity .3s ease;
}
.menu-overlay.menu-out { opacity: 0; pointer-events: none; }
.menu-stage {
  position: absolute; left: 50%; top: 50%; z-index: 1;   /* in front of the starfield */
  transform: translate(-50%, -50%);
  width: min(100vw, 75dvh);        /* fit the 480×640 (3:4) portrait stage */
  aspect-ratio: 480 / 640;
  container-type: size;            /* cqw/cqh = stage dimensions */
  overflow: hidden;               /* crop the backdrop to the stage, like Scratch */
}
/* AMONG US IRL EDITION logo: upper-centre of the stage. */
.menu-logo {
  position: absolute;
  left: 50%; top: 10%;
  transform: translateX(-50%);
  width: 72%; height: auto;
}
/* Credits subtext: full-width, pinned to the bottom of the screen (responsive).
   The full 1240×854 canvas is anchored bottom, so the credit line sits at the
   very bottom and the transparent remainder overlays harmlessly above it. */
.menu-subtext {
  position: absolute; left: 0; bottom: 0; z-index: 1;
  width: 100%; height: auto; pointer-events: none;
}
/* Star specks: tiny white dots (Scratch "costume1" star), sized/moved (px) from JS. */
.menu-star { position: absolute; background: #fff; border-radius: 50%; }
/* Intro sprite (sloth → "Tomyfak Presents"): placed frame-by-frame from JS. */
.menu-sprite { position: absolute; }
.menu-play-btn {                   /* Scratch Play button at sprite size 150% */
  position: absolute;
  left: 28.727%; top: 53.560%; width: 43.180%;
  padding: 0; border: 0; background: none;
  cursor: pointer; touch-action: manipulation; line-height: 0;
}
.menu-play-img { width: 100%; height: auto; display: block; }
.menu-play-btn.pressed .menu-play-img { filter: brightness(.6); } /* Scratch: brightness −40 */
