/* Room overlay tokens (docs/landing-design.md §7.5, direction A) — shared
   with web/static/landing.css and join.js/join.html. Only the pre-game
   overlay and its states are restyled to this direction (§7.2 M3); the
   in-game toolbar/HUD keep their existing look. */
@font-face {
  font-family: 'Barlow Condensed';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('/static/fonts/barlow-condensed-600-latin.woff2') format('woff2');
}
@font-face {
  font-family: 'Barlow Condensed';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('/static/fonts/barlow-condensed-700-latin.woff2') format('woff2');
}
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-weight: 400 600;
  font-display: swap;
  src: url('/static/fonts/ibm-plex-sans-var-latin.woff2') format('woff2');
}

:root {
  color-scheme: dark;
  --bg: #0e1218;
  --bg2: #151b25;
  --line: #242c39;
  --text: #e8ecf1;
  --muted: #8b95a5;
  --accent: #5aa8ff;
  --accent-ink: #061020;
  --radius: 4px;
  --p1: #e5484d;
  --p2: #3b82f6;
  --p3: #f5c518;
  --p4: #3fb950;
  --font-display: 'Barlow Condensed', 'Arial Narrow', sans-serif;
  --font-body: 'IBM Plex Sans', system-ui, sans-serif;
}

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

body {
  background: #111;
  color: #eee;
  font-family: sans-serif;
  height: 100vh;
  height: 100svh;
  display: flex;
  flex-direction: column;
  align-items: center;
  overflow: hidden;
  overscroll-behavior: none;
}

/* Game canvas — fills remaining space above the in-flow toolbar.
   flex:1 means the game gets all the height the toolbar doesn't need,
   regardless of how many rows the toolbar wraps to on small screens.
   max-aspect-ratio: EJS sets the canvas buffer to the element size, so
   the div must stay ≤4:3 to avoid black bars below the game content.
   On wide screens (landscape) it fills the height and narrows the width;
   on tall screens (portrait) it fills the width and limits the height. */
#game {
  width: 100vw;
  max-width: 100vw;
  flex: 1 1 0;
  min-height: 0;
  margin: auto 0; /* vertical center when max-height caps the flex growth */
  order: 1;
}

#stream-overlay {
  width: 100vw;
  max-width: 100vw;
  max-height: calc(100vw * 3 / 4);
  aspect-ratio: 4 / 3;
  flex: 1 1 0;
  min-height: 0;
  margin: auto 0;
  order: 1;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* Desktop (no touch): cap game area to 4:3 so the canvas buffer matches
   the N64 aspect ratio and the game is centered vertically. */
@media (hover: hover) and (pointer: fine) {
  #game,
  #stream-overlay {
    max-height: calc(100vw * 3 / 4);
  }
}

/* Mobile: when physical gamepad connected and virtual gamepad hidden,
   constrain game to 4:3 so margin:auto can vertically center it. */
#game.gamepad-connected {
  max-height: calc(100vw * 3 / 4);
}

/* Gamepad connected indicator (mobile, during gameplay) —
   in-flow flex child just above the toolbar */
#gamepad-indicator {
  order: 9; /* just before toolbar (order:10) */
  flex-shrink: 0;
  align-self: center;
  background: rgba(0, 0, 0, 0.6);
  color: #999;
  font-size: 12px;
  padding: 4px 14px;
  border-radius: 12px;
  pointer-events: none;
  margin-bottom: 4px;
}
#gamepad-indicator.hidden {
  display: none;
}

/* Tap-to-unmute banner (streaming guests, mobile) */
#unmute-banner {
  position: fixed;
  top: 12px;
  left: 50%;
  transform: translateX(-50%);
  background: rgba(0, 0, 0, 0.75);
  color: #fff;
  font-size: 14px;
  padding: 8px 20px;
  border-radius: 20px;
  z-index: 60;
  cursor: pointer;
}
#unmute-banner.hidden {
  display: none;
}

/* During lockstep, force-hide all EJS overlays (cheats, netplay, toolbar menus).
   Only the canvas matters — our lockstep engine handles all UI.
   CSS !important overrides EJS inline styles regardless of EJS internal state. */
#game.kn-playing > div > *:not(canvas) {
  display: none !important;
  pointer-events: none !important;
}

#game canvas,
#game video {
  max-width: 100%;
  width: 100%;
  height: 100%;
  object-fit: contain;
  display: block;
}

#stream-overlay video {
  width: 100%;
  height: 100%;
  max-width: 100%;
  max-height: 100%;
  object-fit: cover;
  display: block;
}

/* Streaming video: force 4:3 so iOS doesn't stretch WebRTC srcObject.
   Not applied to canvas — EJS manages canvas sizing directly. */
#game video {
  height: auto;
  max-height: 100%;
  aspect-ratio: 4 / 3;
  margin: auto;
}

/* Pre-game overlay */
#overlay {
  position: fixed;
  inset: 0;
  background: radial-gradient(70% 50% at 50% 0%, #121a26, var(--bg) 70%);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 100;
  font-family: var(--font-body);
  color: var(--text);
}

#overlay.hidden {
  display: none;
}

.overlay-card {
  background: var(--bg2);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 1.25rem;
  max-width: 480px;
  width: 90vw;
  max-height: 90vh;
  overflow-y: auto;
}

.card-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px 14px;
  flex-wrap: wrap;
  margin-bottom: 0.75rem;
  padding-bottom: 0.75rem;
  border-bottom: 1px solid var(--line);
}

.overlay-card h2 {
  margin: 0;
  font-family: var(--font-label, var(--font-display));
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-size: 0.85rem;
  font-weight: 600;
}

#room-display {
  font-size: 1.1rem;
  letter-spacing: 0.12em;
  color: var(--accent);
}

.name-section {
  display: flex;
  align-items: center;
  gap: 8px;
}

.name-label {
  font-size: 13px;
  color: var(--muted);
  white-space: nowrap;
}

.name-input {
  flex: 1;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  color: var(--text);
  padding: 10px;
  font-size: 14px;
  font-family: inherit;
  min-height: 44px;
}

.name-input:focus {
  border-color: var(--accent);
  outline: 2px solid var(--accent);
  outline-offset: -2px;
}

.name-hint {
  font-size: 12px;
  color: var(--muted);
  margin: -4px 0 8px;
  padding: 0 2px;
}

.copy-btn {
  padding: 8px 14px !important;
  font-size: 14px !important;
  min-height: 44px !important;
  background: var(--line) !important;
  color: var(--text) !important;
  white-space: nowrap;
}
.copy-btn:hover {
  background: #2f3a4d !important;
}

.card-section {
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 10px;
  margin-bottom: 8px;
}

@media (max-width: 600px) {
  .overlay-card {
    padding: 0.75rem;
  }

  .card-section {
    padding: 6px 8px;
    margin-bottom: 6px;
  }

  .overlay-card h2 {
    font-size: 0.95rem;
  }

  /* 44px minimum tap targets on phones (§7.6) */
  .claim-slot-btn {
    min-height: 44px !important;
  }
}

/* Player list — W4 layout (docs/landing-design.md §4 W4) */
.player-slot {
  display: flex;
  align-items: center;
  padding: 6px 10px;
  background: var(--bg2);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  margin-bottom: 3px;
  font-size: 14px;
}

.player-slot .slot-num {
  color: var(--muted);
  margin-right: 8px;
  font-size: 11px;
  font-weight: bold;
  min-width: 20px;
}

.player-slot .name {
  flex: 1;
}

.player-slot .name.empty {
  color: var(--muted);
  font-style: italic;
  font-size: 13px;
}

.player-slot .rom-status {
  font-size: 11px;
  font-weight: 600;
  line-height: 14px;
  margin-left: auto;
  text-transform: uppercase;
  letter-spacing: 0.5px;
}

.player-slot .rom-status.ready {
  color: var(--p4);
}

.player-slot .rom-status.not-ready {
  color: var(--p3);
}

.claim-slot-btn {
  margin-left: auto;
  padding: 6px 10px !important;
  font-size: 12px !important;
  min-height: 32px !important;
  background: var(--accent) !important;
  color: var(--accent-ink) !important;
  font-weight: 600;
}
.claim-slot-btn:hover {
  filter: brightness(1.08);
}
.claim-slot-btn[hidden] {
  display: none !important;
}

.player-slot .gamepad {
  font-size: 14px;
  color: var(--muted);
  margin-left: 6px;
  pointer-events: none;
  cursor: default;
}

.player-slot .device {
  font-size: 14px;
  color: var(--muted);
  margin-left: 6px;
}

.gamepad-detected {
  color: var(--p4) !important;
}

#spectator-list {
  font-size: 11px;
  color: var(--muted);
  margin-top: 6px;
  padding: 0 2px;
}

/* Host controls */
#host-controls {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.host-options-row[hidden] {
  display: none;
}

.host-options-row {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 14px;
  color: #ccc;
}

.mode-label {
  font-size: 14px;
  color: #888;
  white-space: nowrap;
}

#mode-select {
  background: #0d0d1a;
  border: 1px solid #333;
  border-radius: 5px;
  color: #eee;
  padding: 6px 8px;
  font-size: 14px;
  flex: 1;
}

#rollback-options,
#lockstep-options {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.advanced-options {
  margin-top: 8px;
}

.advanced-options summary {
  color: #cbd5e1;
  cursor: pointer;
  font-size: 13px;
  list-style: none;
  padding: 6px 0;
}

.advanced-options summary::-webkit-details-marker {
  display: none;
}

.advanced-options summary::before {
  color: #888;
  content: '▸';
  display: inline-block;
  margin-right: 6px;
  transition: transform 0.15s ease;
}

.advanced-options[open] > summary::before {
  transform: rotate(90deg);
}

.advanced-options .summary-status {
  color: #8a8a8a;
  font-size: 12px;
  margin-left: 8px;
}

#rollback-options label,
#lockstep-options label {
  display: flex;
  align-items: center;
  gap: 6px;
  cursor: pointer;
  min-height: 44px;
}
#rollback-options input[type='checkbox'],
#lockstep-options input[type='checkbox'],
.overlay-card input[type='checkbox'] {
  accent-color: #7c5cff;
  width: 18px;
  height: 18px;
  flex-shrink: 0;
}
.opt-hint {
  color: #8a8a8a;
  font-size: 12px;
}

#start-btn {
  width: 100%;
  font-size: 15px;
  font-weight: 600;
  background: var(--accent);
  color: var(--accent-ink);
  margin-top: 4px;
}

#start-btn:hover:not(:disabled) {
  filter: brightness(1.08);
}
#start-btn:disabled {
  background: var(--line);
  color: var(--muted);
  cursor: default;
}

#guest-status {
  text-align: center;
  color: var(--muted);
  margin-top: 8px;
  font-size: 14px;
}

#gamepad-area {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}

#gamepad-status,
#switch2-status {
  font-size: 12px;
  color: #8a8a8a;
}

#gamepad-status {
  flex: 1;
}

#switch2-status {
  flex-basis: 100%;
}

#gamepad-controls {
  display: flex;
  gap: 4px;
}

#engine-status {
  text-align: center;
  font-size: 11px;
  color: #8a8a8a;
  margin-top: 4px;
  min-height: 14px;
}

/* Buttons */
button {
  padding: 12px 20px;
  border: none;
  border-radius: var(--radius);
  background: #3a5a8a;
  color: #fff;
  font-size: 15px;
  cursor: pointer;
  min-height: 44px;
}

button:hover {
  background: #4a6fa5;
}

.overlay-card button,
#unsupported-browser button {
  border-radius: var(--radius);
  font-family: inherit;
}

.small-btn {
  padding: 8px 12px !important;
  font-size: 14px !important;
  min-height: 44px !important;
  background: var(--line) !important;
  color: var(--text) !important;
}
.small-btn:hover {
  background: #2f3a4d !important;
}

#remap-wizard {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  margin-top: 6px;
  font-size: 13px;
}
#remap-prompt {
  color: #6af;
  flex: 1;
}
#remap-progress {
  color: #8a8a8a;
  font-size: 11px;
}

#leave-btn {
  display: block;
  width: 100%;
  margin-top: 8px;
  background: var(--line);
  color: var(--text);
  font-size: 14px;
  padding: 10px;
  min-height: 44px;
}

#leave-btn:hover {
  background: color-mix(in srgb, var(--p1) 25%, var(--line));
}

/* Footer links */
.overlay-footer {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  margin-top: 10px;
  padding: 4px 0;
}
.footer-link {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  min-height: 44px;
  color: #8a8a8a;
  text-decoration: none;
  font-size: 11px;
  transition: color 0.2s;
}
.footer-link:hover {
  color: #aaa;
}
.footer-dot {
  color: #333;
  font-size: 11px;
}
.footer-icon {
  width: 13px;
  height: 13px;
}

/* In-game toolbar — in-flow bar below the game area.
   Part of the body flex column so it naturally takes only
   the height it needs, and the game gets the rest.
   order:10 pushes it to the bottom regardless of HTML order. */
#toolbar {
  width: 100%;
  flex-shrink: 0;
  order: 10;
  display: flex;
  flex-wrap: nowrap;
  gap: 6px;
  padding: 6px 8px;
  background: rgba(17, 17, 17, 0.95);
  z-index: 50;
  align-items: center;
}

#toolbar.hidden {
  display: none;
}

#toolbar-room {
  font-size: 13px;
  color: #888;
  letter-spacing: 0.05em;
  white-space: nowrap;
}

#toolbar-status {
  font-size: 13px;
  color: #6af;
  margin-left: 4px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
  flex-shrink: 1;
}

.toolbar-spacer {
  flex: 1;
  min-width: 0;
}

#toolbar button {
  padding: 6px 10px;
  font-size: 13px;
  min-height: 44px;
  white-space: nowrap;
  flex-shrink: 0;
}

.toolbar-toggle {
  background: #333;
  font-size: 13px !important;
  padding: 6px 10px !important;
  min-height: 44px !important;
}
.toolbar-toggle.active {
  background: #4a6;
}
#toolbar-end {
  background: #8a3a3a;
}
#toolbar-end:hover {
  background: #a44a4a;
}

/* Invite submenu inside more dropdown */
.more-submenu {
  border-bottom: 1px solid #2a2a40;
  padding-bottom: 4px;
  margin-bottom: 4px;
}
.more-submenu-label {
  padding: 6px 14px 2px;
  font-size: 10px;
  color: #64748b;
  text-transform: uppercase;
  letter-spacing: 0.5px;
}

/* More (overflow) dropdown */
#more-wrapper {
  position: relative;
  flex-shrink: 0;
  z-index: 70;
}
#toolbar-more {
  min-width: 44px;
  text-align: center;
  font-size: 18px !important;
  letter-spacing: 2px;
}
.more-dropdown {
  position: absolute;
  bottom: 100%;
  right: 0;
  margin-bottom: 6px;
  background: #1a1a2e;
  border: 1px solid #2a2a40;
  border-radius: 8px;
  padding: 4px;
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 140px;
  z-index: 55;
}
.more-dropdown.floating {
  position: fixed;
  right: auto;
  bottom: auto;
  margin: 0;
  z-index: 2147483647;
}
.more-dropdown[popover] {
  inset: auto;
  color: #eee;
}
.more-dropdown:popover-open {
  display: flex;
}
.more-dropdown.hidden {
  display: none;
}
.more-option {
  padding: 10px 14px !important;
  font-size: 14px !important;
  min-height: 44px !important;
  background: transparent !important;
  text-align: left;
  border-radius: 6px;
  white-space: nowrap;
}
.more-option:hover {
  background: #2a2a40 !important;
}
.more-end {
  color: #e66 !important;
}

/* Room-full banner */
.room-full-banner {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 250;
  background: rgba(42, 42, 64, 0.95);
  color: #ccc;
  font-size: 13px;
  padding: 10px 16px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  animation: bannerSlideIn 0.3s ease;
}
.room-full-banner .banner-close {
  background: transparent !important;
  border: none;
  color: #888;
  min-width: 44px !important;
  min-height: 44px !important;
  font-size: 16px;
  cursor: pointer;
  padding: 0 4px !important;
  min-height: auto !important;
  line-height: 1;
}
.room-full-banner .banner-close:hover {
  color: #eee;
}
@keyframes bannerSlideIn {
  from {
    transform: translateY(-100%);
  }
  to {
    transform: translateY(0);
  }
}

/* In-game info overlay */
#info-overlay {
  position: fixed;
  top: 8px;
  left: 8px;
  z-index: 60;
  display: flex;
  flex-direction: column;
  gap: 2px;
  font-family: 'Menlo', 'Consolas', monospace;
  font-size: 11px;
  color: rgba(255, 255, 255, 0.8);
  background: rgba(0, 0, 0, 0.6);
  padding: 6px 10px;
  border-radius: 6px;
  pointer-events: none;
  line-height: 1.4;
}
#info-overlay.hidden {
  display: none;
}
#info-header {
  font-weight: bold;
  font-size: 12px;
  color: rgba(255, 255, 255, 0.95);
}
#info-peers {
  font-size: 10px;
  color: rgba(255, 255, 255, 0.55);
}

/* Mobile: info overlay stays fixed so it never enters flex flow and resizes #game */
@media (hover: none) and (pointer: coarse) {
  #info-overlay {
    position: fixed;
    top: 8px;
    left: 8px;
    right: 8px;
    z-index: 60;
    padding: 4px 8px;
    font-size: 10px;
    pointer-events: auto;
    flex-direction: row;
    flex-wrap: wrap;
    gap: 0 8px;
    max-height: none;
    overflow: visible;
  }
  #info-overlay.expanded {
    /* no longer needed — info is fully visible */
  }
  #info-header {
    font-size: 10px;
    white-space: nowrap;
  }
  #info-stats {
    white-space: nowrap;
  }
  #info-peers {
    width: 100%;
    font-size: 9px;
  }
  #info-overlay #dump-logs-btn {
    font-size: 9px;
    padding: 2px 6px;
    margin-top: 4px;
  }
}

/* Reconnecting banner */
#reconnecting-banner {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  padding: 8px 16px;
  background: rgba(30, 30, 50, 0.95);
  color: #ccc;
  text-align: center;
  font-size: 0.85rem;
  z-index: 250;
  animation: fadeIn 0.3s ease;
}
#reconnecting-banner.hidden {
  display: none;
}
#reconnecting-banner .spinner {
  display: inline-block;
  width: 12px;
  height: 12px;
  border: 2px solid #555;
  border-top-color: #aaf;
  border-radius: 50%;
  animation: spin 0.8s linear infinite;
  vertical-align: middle;
  margin-right: 6px;
}
@keyframes spin {
  to {
    transform: rotate(360deg);
  }
}
@keyframes fadeIn {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

/* Toast notifications */
#toast-container {
  position: fixed;
  top: 50px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 200;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  pointer-events: none;
}

#menu-wait-overlay {
  position: fixed;
  top: calc(env(safe-area-inset-top, 0px) + 64px);
  left: 50%;
  transform: translateX(-50%);
  z-index: 180;
  max-width: min(420px, calc(100vw - 24px));
  padding: 10px 14px;
  border: 1px solid rgba(115, 170, 255, 0.42);
  border-radius: 8px;
  background: rgba(8, 11, 18, 0.9);
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.42);
  color: #f4f7fb;
  text-align: center;
  pointer-events: none;
}

#menu-wait-overlay.hidden {
  display: none;
}

#menu-wait-title {
  font-size: 14px;
  font-weight: 700;
  line-height: 1.25;
  overflow-wrap: anywhere;
}

#menu-wait-detail {
  margin-top: 3px;
  color: #bcc8d8;
  font-size: 12px;
  line-height: 1.35;
}

.toast {
  background: rgba(0, 0, 0, 0.8);
  color: #eee;
  padding: 8px 16px;
  border-radius: 6px;
  font-size: 13px;
  animation: toastIn 0.3s ease;
}

.toast.fade-out {
  animation: toastOut 0.3s ease forwards;
}

@keyframes toastIn {
  from {
    opacity: 0;
    transform: translateY(-10px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

@keyframes toastOut {
  from {
    opacity: 1;
  }
  to {
    opacity: 0;
  }
}

/* In-game remap overlay */
#ingame-remap {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.8);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 150;
}
#ingame-remap.hidden {
  display: none;
}

.ingame-remap-card {
  background: #1a1a2e;
  border: 1px solid #2a2a40;
  border-radius: 12px;
  padding: 1.25rem;
  max-width: 360px;
  width: 85vw;
  text-align: center;
}

#ingame-remap-prompt {
  font-size: 15px;
  margin-bottom: 6px;
}

#ingame-remap-progress {
  font-size: 12px;
  color: #888;
  margin-bottom: 14px;
}

.ingame-remap-buttons {
  display: flex;
  gap: 8px;
  justify-content: center;
}

/* Error overlay */
#error-msg {
  position: fixed;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(0, 0, 0, 0.9);
  z-index: 300;
}

#error-msg.hidden {
  display: none;
}

.error-card {
  background: #2a1a1a;
  border: 1px solid #5a3a3a;
  border-radius: 12px;
  padding: 2rem;
  text-align: center;
  max-width: 400px;
  width: 90vw;
}

.error-card h3 {
  margin-bottom: 1rem;
  color: #f88;
}
.error-card a {
  color: #6af;
}
.error-back {
  display: inline-block;
  margin-top: 1rem;
  padding: 10px 24px;
  background: #3a5a8a;
  color: #fff;
  text-decoration: none;
  border-radius: 6px;
  font-size: 14px;
}
.error-back:hover {
  background: #4a6fa5;
}

/* ROM drop zone (W4 §4) */
.rom-drop {
  border: 1px dashed var(--muted);
  border-radius: var(--radius);
  padding: 1rem;
  text-align: center;
  cursor: pointer;
  background: var(--bg2);
  transition:
    border-color 0.2s,
    background 0.2s;
}

.rom-drop p {
  font-family: var(--font-display);
  font-size: 15px;
  font-weight: 700;
}
.rom-drop .rom-hint {
  font-family: var(--font-body);
  font-weight: 400;
}

.rom-drop.dragover {
  border-color: var(--accent);
  background: rgba(90, 168, 255, 0.06);
}

.rom-drop.loaded {
  border-color: var(--p4);
  background: rgba(63, 185, 80, 0.06);
}

.rom-hint {
  font-size: 12px;
  color: var(--muted);
  margin-top: 4px;
}

.rom-status.rom-unsupported {
  color: var(--p3);
}

/* Wrong-ROM banner (W4 variant) — names both games, persists until fixed */
.rom-mismatch {
  margin-top: 12px;
  padding: 10px 12px;
  border-radius: var(--radius);
  border: 1px solid var(--p1);
  background: color-mix(in srgb, var(--p1) 12%, var(--bg2));
  color: var(--text);
  font-size: 13px;
  text-align: left;
  display: flex;
  flex-wrap: wrap;
  gap: 8px 12px;
  align-items: center;
  justify-content: space-between;
}
.rom-mismatch[hidden] {
  display: none;
}

/* "Watch instead" — the no-ROM path that stays in the room (§7.2 M3 #1) */
.watch-instead-row {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 10px;
  align-items: center;
  color: var(--text);
  font-size: 13px;
  margin-top: 8px;
}
.watch-instead-row[hidden] {
  display: none;
}
.watch-instead-hint {
  color: var(--muted);
  font-size: 12px;
}

.host-rom-info {
  border: 1px solid var(--line);
  border-radius: var(--radius);
  margin-bottom: 8px;
  padding: 8px 10px;
  font-size: 12px;
  line-height: 1.35;
  color: var(--text);
  background: rgba(90, 168, 255, 0.06);
  overflow-wrap: anywhere;
}

.host-rom-info.pending {
  color: var(--muted);
  background: rgba(255, 255, 255, 0.03);
}

.host-rom-info.ready {
  border-color: var(--accent);
}

/* ROM Library — also shown to guests, matched entries marked (§7.2 M3 #1) */
.rom-library {
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
  margin-top: 8px;
}

.rom-library-header {
  padding: 6px 10px;
  background: var(--bg2);
  color: var(--muted);
  font-size: 11px;
  font-family: var(--font-display);
  text-transform: uppercase;
  letter-spacing: 0.1em;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.rom-library-header .rom-count {
  color: var(--muted);
  font-size: 10px;
}

.rom-library-list {
  max-height: 160px;
  overflow-y: auto;
  scrollbar-width: thin;
  scrollbar-color: var(--line) transparent;
}

.rom-library-item {
  padding: 8px 10px;
  display: flex;
  align-items: center;
  gap: 8px;
  cursor: pointer;
  border-top: 1px solid var(--line);
  transition: background 0.15s;
}

.rom-library-item:first-child {
  border-top: none;
}

.rom-library-item:hover {
  background: rgba(255, 255, 255, 0.03);
}

.rom-library-item.active {
  background: rgba(63, 185, 80, 0.08);
  border-left: 3px solid var(--p4);
  padding-left: 7px;
}

.rom-library-item.matches-host:not(.active) {
  background: rgba(90, 168, 255, 0.06);
  border-left: 3px solid var(--accent);
  padding-left: 7px;
}

.rom-library-item .rom-check {
  color: transparent;
  font-size: 14px;
  width: 18px;
  text-align: center;
  flex-shrink: 0;
}

.rom-library-item.active .rom-check {
  color: var(--p4);
}

.rom-library-item .rom-info {
  flex: 1;
  min-width: 0;
}

.rom-library-item .rom-name {
  color: var(--text);
  font-size: 13px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.rom-library-item.active .rom-name {
  color: var(--text);
}

.rom-library-item .rom-meta {
  color: var(--muted);
  font-size: 10px;
  display: flex;
  gap: 8px;
}

.rom-library-item .rom-meta .verified {
  color: var(--p4);
}

.rom-library-item.matches-host .rom-meta .verified {
  color: var(--accent);
}

.rom-library-item .rom-meta .unverified {
  color: var(--muted);
}

.rom-library-item .rom-use {
  flex-shrink: 0;
}

.rom-library-item .rom-delete {
  background: none;
  border: 1px solid var(--line);
  color: var(--muted);
  border-radius: 4px;
  padding: 2px 6px;
  font-size: 11px;
  cursor: pointer;
  flex-shrink: 0;
  transition:
    border-color 0.15s,
    color 0.15s;
}

.rom-library-item .rom-delete:hover {
  border-color: var(--p1);
  color: var(--p1);
}

.rom-status {
  font-size: 12px;
  color: var(--accent);
  margin-top: 8px;
}

/* ROM sharing */
.rom-sharing-disclaimer {
  font-size: 11px;
  color: #a88;
  margin: 2px 0 4px 0;
  line-height: 1.3;
}

#rom-sharing-prompt {
  text-align: center;
  padding: 1rem;
}

.rom-sharing-prompt-text {
  font-size: 14px;
  color: #999;
  margin-bottom: 6px;
}

.rom-sharing-prompt-legal {
  display: block;
  font-size: 12px;
  color: #999;
  line-height: 1.3;
  margin-top: 2px;
}

.rom-sharing-prompt-buttons {
  display: flex;
  gap: 8px;
  justify-content: center;
  flex-wrap: wrap;
}

.rom-progress-bar-container {
  background: #2a2a40;
  border-radius: 4px;
  height: 8px;
  overflow: hidden;
  margin-bottom: 8px;
}

.rom-progress-bar {
  background: #6af;
  height: 100%;
  width: 0%;
  transition: width 0.2s;
  border-radius: 4px;
}

#rom-transfer-progress {
  text-align: center;
  padding: 1rem;
}

/* Game loading overlay.
 * Opaque (not 0.8) so the EmulatorJS canvas stays fully hidden during boot
 * and late-join state transfer — otherwise the N64 boot logo / first
 * pre-state-load frames bleed through and confuse joiners. */
#game-loading {
  position: fixed;
  inset: 0;
  background: #000;
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 90;
  transition: opacity 0.4s;
  pointer-events: none;
}

#game-loading.hidden {
  display: none;
}

#game-loading.fade-out {
  opacity: 0;
  pointer-events: none;
}

.game-loading-content {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 16px;
}

/* Match start (docs/landing-design.md §5.7f #2, §7.11) — driven by real
   per-slot state from play.js (updateBootPorts), not a fixed timer. Ports
   fill via CSS transition as JS toggles .is-ready; .all-ready plays one
   bounce once every occupied port is ready; .collapsing plays as the game
   boots (dismissGameLoading). Still frame under reduced motion. */
.ms-boot {
  width: 64px;
  height: 43px;
  display: block;
}
.ms-boot rect {
  transform-box: fill-box;
  transform-origin: bottom center;
}
.ms-boot .outline {
  fill: none;
  stroke: var(--line);
  stroke-width: 1.2;
}
.ms-boot .fill {
  transform: scaleY(0);
  transition: transform 0.5s ease-out;
}
.ms-boot .fill.is-open {
  display: none;
}
.ms-boot .fill.is-ready {
  transform: scaleY(1);
}
.ms-boot .f1.is-ready {
  fill: var(--p1);
}
.ms-boot .f2.is-ready {
  fill: var(--p2);
}
.ms-boot .f3.is-ready {
  fill: var(--p3);
}
.ms-boot .f4.is-ready {
  fill: var(--p4);
}
.ms-boot.all-ready .fill.is-ready {
  animation: ms-boot-bounce 0.5s ease-out;
}
.ms-boot.collapsing .fill,
.ms-boot.collapsing .outline {
  transition:
    height 0.4s ease-in,
    transform 0.4s ease-in;
  transform: scaleY(1) !important;
  height: 5px;
  transform-box: fill-box;
}
@keyframes ms-boot-bounce {
  0%,
  100% {
    transform: scaleY(1) translateY(0);
  }
  50% {
    transform: scaleY(1) translateY(-3px);
  }
}
@media (prefers-reduced-motion: reduce) {
  .ms-boot .fill {
    transition: none;
  }
  .ms-boot.all-ready .fill.is-ready {
    animation: none;
  }
  .ms-boot.collapsing .fill,
  .ms-boot.collapsing .outline {
    transition: none;
  }
}

#game-loading-text {
  font-size: 14px;
  color: #aaa;
}

/* ── Unsupported-browser screen (docs/landing-design.md §7.2 M3 #2) ────── */
#unsupported-browser {
  position: fixed;
  inset: 0;
  background: radial-gradient(70% 50% at 50% 0%, #121a26, var(--bg) 70%);
  color: var(--text);
  font-family: var(--font-body);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 200;
  padding: 20px;
}
#unsupported-browser.hidden {
  display: none;
}
.ub-card {
  max-width: 440px;
  width: 100%;
  background: var(--bg2);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 24px 20px;
  text-align: center;
}
.ub-card h1 {
  font-family: var(--font-display);
  font-size: 22px;
  font-weight: 700;
  margin-bottom: 12px;
}
.ub-card p {
  color: var(--muted);
  font-size: 14px;
  line-height: 1.5;
  margin-bottom: 8px;
}
.ub-card .ub-hint {
  color: var(--text);
}
.ub-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  justify-content: center;
  margin-top: 16px;
}
#unsupported-copy {
  background: var(--accent);
  color: var(--accent-ink);
  font-weight: 600;
}
#unsupported-watch[hidden] {
  display: none;
}

/* Gesture prompt overlay — above everything including EmulatorJS */
#gesture-prompt {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.85);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 10000;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

#gesture-prompt.hidden {
  display: none;
}

.gesture-prompt-content {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 16px;
  user-select: none;
}

.gesture-prompt-icon {
  width: 0;
  height: 0;
  border-style: solid;
  border-width: 30px 0 30px 52px;
  border-color: transparent transparent transparent #6af;
  filter: drop-shadow(0 0 16px rgba(102, 170, 255, 0.4));
}

.gesture-prompt-text {
  font-size: 18px;
  color: #ccc;
  letter-spacing: 0.5px;
}

/* Diagnostic image preference stays available to every player, not just hosts. */
.capture-options label {
  display: flex;
  align-items: flex-start;
  gap: 8px;
}
.capture-options .opt-hint {
  margin-top: 8px;
  line-height: 1.5;
}
.capture-options a {
  color: inherit;
  text-decoration: underline;
}
a.more-option {
  color: inherit;
  display: block;
  text-decoration: none;
}

/* Crew room (play.html?auto=1, set by play.js): five friends who all open the
   same link. The room is always Rollback with default settings, the link is
   the site itself, and nobody needs the front page, feedback or about links.
   Everything a player uses stays: name, slots, spectators, Watch instead,
   ROM drop and library, controller settings, Start, Leave. */
body.kn-crew .room-label,
body.kn-crew #mode-row,
body.kn-crew #listed-row,
body.kn-crew #host-controls .advanced-options,
body.kn-crew #player-controls,
body.kn-crew .capture-options,
body.kn-crew .overlay-footer,
body.kn-crew #share-watch,
body.kn-crew #switch2-connect-btn,
body.kn-crew #host-rom-info,
body.kn-crew .kn-feedback-fab,
body.kn-crew .kn-feedback-toolbar-item,
body.kn-crew .kn-feedback-session-prompt,
body.kn-crew.kn-watching #rom-section {
  display: none !important;
}

/* Now playing (crew room): what the host's ROM is, and where you stand. */
.now-playing {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: baseline;
  column-gap: 12px;
  row-gap: 2px;
}
.now-playing[hidden] {
  display: none;
}
.now-playing-label {
  grid-column: 1 / -1;
  font-family: var(--font-display);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
}
.now-playing-title {
  font-family: var(--font-display);
  font-size: 22px;
  font-weight: 700;
  letter-spacing: 0.02em;
  line-height: 1.15;
  text-transform: uppercase;
  overflow-wrap: anywhere;
}
.now-playing-detail {
  font-size: 13px;
  color: var(--muted);
  white-space: nowrap;
}
.now-playing-status {
  grid-column: 1 / -1;
  font-size: 13px;
  color: var(--muted);
}
.now-playing-status:empty {
  display: none;
}
.now-playing[data-tone='ok'] .now-playing-status {
  color: var(--p4);
}
.now-playing[data-tone='ok'] .now-playing-status::before {
  content: '\2713  ';
}

/* The crew room's mark beside its title: the same turning controller as the
   gate's loader (front/gate/controller.svg), smaller. */
.crew-mark {
  display: none;
}
/* The drawing fills about two thirds of its box (room for every pose), so
   the negative margins keep the header its usual height. */
body.kn-crew .crew-mark {
  display: block;
  width: 88px;
  height: 86px;
  margin: -22px -14px -22px -16px;
}
body.kn-crew .card-header h2 {
  margin-right: auto;
}

/* Voice chat (static/voice.js). The lobby row sits under the player list;
   .voice-ind marks each name: in voice, talking, or muted. Space for the
   marks is kept only while someone in the room is in voice. */
:root {
  --icon-mic: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 14c1.66 0 3-1.34 3-3V5c0-1.66-1.34-3-3-3S9 3.34 9 5v6c0 1.66 1.34 3 3 3zm5.3-3c0 3-2.54 5.1-5.3 5.1S6.7 14 6.7 11H5c0 3.41 2.72 6.23 6 6.72V21h2v-3.28c3.28-.48 6-3.3 6-6.72h-1.7z'/%3E%3C/svg%3E");
  --icon-mic-off: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M19 11h-1.7c0 .74-.16 1.43-.43 2.05l1.23 1.23c.56-.98.9-2.09.9-3.28zm-4.02.17c0-.06.02-.11.02-.17V5c0-1.66-1.34-3-3-3S9 3.34 9 5v.18l5.98 5.99zM4.27 3 3 4.27l6.01 6.01V11c0 1.66 1.33 3 2.99 3 .22 0 .44-.03.65-.08l1.66 1.66c-.71.33-1.5.52-2.31.52-2.76 0-5.3-2.1-5.3-5.1H5c0 3.41 2.72 6.23 6 6.72V21h2v-3.28c.91-.13 1.77-.45 2.54-.9L19.73 21 21 19.73 4.27 3z'/%3E%3C/svg%3E");
}

.voice-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 8px;
  margin-top: 8px;
  padding-top: 8px;
  border-top: 1px solid var(--line);
}
.voice-row-label {
  font-family: var(--font-display);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
  min-width: 42px;
}
.voice-row .small-btn[hidden] {
  display: none !important;
}
#voice-mute.muted {
  background: color-mix(in srgb, var(--p1) 30%, var(--line)) !important;
}
.voice-note {
  font-size: 12px;
  color: var(--muted);
}
.voice-note.warn {
  color: var(--p3);
}

.voice-ind {
  display: none;
  flex-shrink: 0;
  align-items: center;
  justify-content: center;
  width: 18px;
  height: 18px;
  margin-right: 6px;
  border-radius: 50%;
  color: var(--muted);
  vertical-align: middle;
  transition:
    background-color 0.12s,
    color 0.12s;
}
.voice-ind::before {
  content: '';
  width: 12px;
  height: 12px;
  background: currentColor;
  -webkit-mask: var(--icon-mic) center / contain no-repeat;
  mask: var(--icon-mic) center / contain no-repeat;
}
body.kn-voice-any .voice-ind {
  display: inline-flex;
  visibility: hidden;
}
body.kn-voice-any .voice-ind[data-voice] {
  visibility: visible;
}
.voice-ind[data-voice='speaking'] {
  color: var(--p4);
  background: color-mix(in srgb, var(--p4) 22%, transparent);
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--p4) 55%, transparent);
}
.voice-ind[data-voice='muted'] {
  color: var(--p1);
}
.voice-ind[data-voice='muted']::before {
  -webkit-mask-image: var(--icon-mic-off);
  mask-image: var(--icon-mic-off);
}
#spectator-list .voice-ind {
  width: 14px;
  height: 14px;
  margin-right: 3px;
}
#spectator-list .voice-ind::before {
  width: 10px;
  height: 10px;
}

/* In-game toolbar: who's talking, and your mic. */
/* Who's talking outranks the status text when the bar runs out of room. */
.toolbar-voice {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  flex-shrink: 0;
  max-width: 30vw;
  font-size: 13px;
  color: var(--p4);
  white-space: nowrap;
}
.toolbar-voice[hidden] {
  display: none;
}
.toolbar-voice::before {
  content: '';
  flex-shrink: 0;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: currentColor;
}
.toolbar-voice.warn {
  color: var(--p3);
}
#toolbar-voice-names {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
}
#toolbar-mic {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 44px;
  background: #333;
}
#toolbar-mic[hidden] {
  display: none;
}
#toolbar-mic::before {
  content: '';
  width: 18px;
  height: 18px;
  background: currentColor;
  -webkit-mask: var(--icon-mic) center / contain no-repeat;
  mask: var(--icon-mic) center / contain no-repeat;
}
#toolbar-mic.speaking {
  box-shadow: inset 0 0 0 2px var(--p4);
}
#toolbar-mic.muted {
  background: #8a3a3a;
}
#toolbar-mic.muted::before {
  -webkit-mask-image: var(--icon-mic-off);
  mask-image: var(--icon-mic-off);
}

@media (prefers-reduced-motion: reduce) {
  .voice-ind {
    transition: none;
  }
}

/* Faces (static/faces.js): each player's camera, small. In game, tiles float
   over the picture and can be dragged and resized; in the lobby, a tiny one
   leads each occupied slot. Seat colors match the slots: P1 red to P4 green. */
:root {
  --icon-cam: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M17 10.5V7c0-.55-.45-1-1-1H4c-.55 0-1 .45-1 1v10c0 .55.45 1 1 1h12c.55 0 1-.45 1-1v-3.5l4 4v-11l-4 4z'/%3E%3C/svg%3E");
  --icon-cam-off: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M21 6.5l-4 4V7c0-.55-.45-1-1-1H9.82L21 17.18V6.5zM3.27 2 2 3.27 4.73 6H4c-.55 0-1 .45-1 1v10c0 .55.45 1 1 1h12c.21 0 .39-.08.54-.18L19.73 21 21 19.73 3.27 2z'/%3E%3C/svg%3E");
}

#faces {
  position: fixed;
  inset: 0;
  z-index: 45; /* over the game, under the toolbar's menus */
  pointer-events: none;
}
.face {
  --seat: var(--muted);
  position: absolute;
  top: 0;
  left: 0;
  overflow: hidden;
  border-radius: 6px;
  background: #000;
  box-shadow:
    0 0 0 2px var(--seat),
    0 4px 14px rgba(0, 0, 0, 0.5);
  pointer-events: auto;
  cursor: grab;
  touch-action: none;
  user-select: none;
  transition:
    box-shadow 0.12s,
    opacity 0.12s;
}
/* Over the game: a little see-through, so the game shows through the face.
   Beside the picture there's nothing under it to see. */
.face.over {
  opacity: 0.8;
}
.face.over:hover,
.face.dragging {
  opacity: 1;
}
.face[hidden] {
  display: none;
}
.face[data-seat='0'] {
  --seat: var(--p1);
}
.face[data-seat='1'] {
  --seat: var(--p2);
}
.face[data-seat='2'] {
  --seat: var(--p3);
}
.face[data-seat='3'] {
  --seat: var(--p4);
}
.face.dragging {
  cursor: grabbing;
}
.face.talking {
  box-shadow:
    0 0 0 2px var(--seat),
    0 0 0 4px #fff,
    0 4px 14px rgba(0, 0, 0, 0.5);
}
.face video {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  pointer-events: none;
}
.face.self video,
.face-mini.self {
  transform: scaleX(-1); /* your own face as a mirror, like every video call */
}
.face-label {
  position: absolute;
  left: 0;
  top: 0;
  padding: 1px 5px 2px;
  border-bottom-right-radius: 6px;
  background: var(--seat);
  color: #0e1218;
  font: 700 11px/1.1 var(--font-display);
  letter-spacing: 0.04em;
  pointer-events: none;
}
.face-grip {
  position: absolute;
  right: 0;
  bottom: 0;
  width: 16px;
  height: 16px;
  cursor: nwse-resize;
  opacity: 0;
  background: linear-gradient(135deg, transparent 50%, rgba(255, 255, 255, 0.85) 50%);
  transition: opacity 0.12s;
}
.face:hover .face-grip,
.face.dragging .face-grip {
  opacity: 1;
}

.face-mini {
  flex-shrink: 0;
  width: 48px;
  height: 36px;
  margin: -3px 8px -3px 0;
  border-radius: 4px;
  object-fit: cover;
  background: #000;
}
.face-mini[hidden] {
  display: none;
}
.face-mini.talking {
  box-shadow: 0 0 0 2px var(--p4);
}

#voice-cam[hidden] {
  display: none !important;
}
#voice-cam[aria-pressed='true'] {
  background: color-mix(in srgb, var(--p4) 28%, var(--line)) !important;
}

#toolbar-cam {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 44px;
  background: #333;
}
#toolbar-cam[hidden] {
  display: none;
}
#toolbar-cam::before {
  content: '';
  width: 18px;
  height: 18px;
  background: currentColor;
  -webkit-mask: var(--icon-cam) center / contain no-repeat;
  mask: var(--icon-cam) center / contain no-repeat;
}
#toolbar-cam.off {
  color: var(--muted);
}
#toolbar-cam.off::before {
  -webkit-mask-image: var(--icon-cam-off);
  mask-image: var(--icon-cam-off);
}

@media (prefers-reduced-motion: reduce) {
  .face,
  .face-grip {
    transition: none;
  }
}

/* Clips (static/clips.js): "Clip that" in the toolbar, a small note that this
   browser is keeping the last seconds, and the lobby's in/out toggle. */
#clips-me[aria-pressed='true'] {
  background: color-mix(in srgb, var(--p4) 28%, var(--line)) !important;
}
.toolbar-clips {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  flex-shrink: 0;
  font-size: 12px;
  letter-spacing: 0.04em;
  color: var(--muted);
  white-space: nowrap;
}
.toolbar-clips[hidden] {
  display: none;
}
.toolbar-clips::before {
  content: '';
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--p1);
  opacity: 0.85;
}
#toolbar-clip {
  background: #333;
  font-weight: 600;
}
#toolbar-clip[hidden] {
  display: none;
}
#toolbar-clip:not(:disabled):hover {
  background: #444;
}
#toolbar-clip:disabled {
  opacity: 0.6;
  cursor: default;
}
