/* Small, opinionated CSS. System fonts, dark-ish neutral palette. */

:root {
  --bg: #0f1115;
  --surface: #171a21;
  --surface-2: #1f232c;
  --border: #2a2f3a;
  --text: #e7e9ee;
  --text-dim: #9aa3b2;
  --accent: #4f8cff;
  --accent-hover: #6aa0ff;
  --danger: #e05a5a;
  --radius: 10px;
  --mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}

* { box-sizing: border-box; }

html, body { height: 100%; margin: 0; }

body {
  background: var(--bg);
  color: var(--text);
  font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  font-size: 15px;
  line-height: 1.5;
}

a { color: var(--accent); text-decoration: none; }
a:hover { color: var(--accent-hover); }

header {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px 24px;
  border-bottom: 1px solid var(--border);
}

.brand {
  font-weight: 600;
  font-size: 17px;
  color: var(--text);
  letter-spacing: 0.01em;
}

.role-chip {
  font-size: 12px;
  color: var(--text-dim);
  background: var(--surface-2);
  border: 1px solid var(--border);
  padding: 2px 8px;
  border-radius: 999px;
}

main {
  max-width: 900px;
  margin: 0 auto;
  padding: 32px 24px;
}

/* Landing page */
.landing main { text-align: center; }
.landing h1 { font-size: 44px; margin: 48px 0 8px; }
.landing .tagline { color: var(--text-dim); margin: 0 0 40px; }

.card-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 16px;
  text-align: left;
}
@media (max-width: 640px) {
  .card-row { grid-template-columns: 1fr; }
}

.card {
  display: block;
  background: var(--surface);
  border: 1px solid var(--border);
  padding: 24px;
  border-radius: var(--radius);
  transition: border-color 120ms, transform 120ms;
  color: var(--text);
}
.card:hover {
  border-color: var(--accent);
  transform: translateY(-1px);
  color: var(--text);
}
.card h2 { margin: 0 0 6px; font-size: 18px; }
.card p { margin: 0; color: var(--text-dim); font-size: 14px; }

footer {
  margin-top: 60px;
  color: var(--text-dim);
}

/* Version stamp in page footers. Small and unobtrusive, but visible so a
   quick glance confirms which build is actually loaded — service workers
   and HTTP caches both happily serve stale JS without warning. */
.hdr-version {
  display: block;
  margin-top: 8px;
  font-family: var(--mono);
  font-size: 11px;
  color: var(--text-dim);
  opacity: 0.55;
  letter-spacing: 0.04em;
}

/* Buttons */
button {
  font: inherit;
  background: var(--surface-2);
  color: var(--text);
  border: 1px solid var(--border);
  padding: 10px 16px;
  border-radius: 8px;
  cursor: pointer;
  transition: background 100ms, border-color 100ms;
}
button:hover:not(:disabled) { background: #262b36; }
button:disabled { opacity: 0.5; cursor: not-allowed; }
button.primary {
  background: var(--accent);
  border-color: var(--accent);
  color: white;
}
button.primary:hover:not(:disabled) { background: var(--accent-hover); border-color: var(--accent-hover); }

/* Host page */
.controls {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px;
  margin-bottom: 24px;
}
.status {
  margin: 0;
  flex: 1 1 100%;
  color: var(--text-dim);
  min-height: 1.5em;
}
.share-info {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 16px;
  margin-bottom: 24px;
}
.share-info .row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 6px 0;
}
.share-info label {
  width: 110px;
  color: var(--text-dim);
  font-size: 13px;
}
.share-info code {
  font-family: var(--mono);
  font-size: 18px;
  letter-spacing: 0.1em;
  color: var(--text);
}
.share-info .link {
  flex: 1;
  font-family: var(--mono);
  font-size: 13px;
  word-break: break-all;
}

.preview-section h3, .viewers h3 { color: var(--text-dim); font-size: 13px; font-weight: 600; letter-spacing: 0.04em; text-transform: uppercase; }

video#preview, video#remote {
  width: 100%;
  max-height: 520px;
  background: #000;
  border-radius: var(--radius);
  border: 1px solid var(--border);
}

.viewers ul { list-style: none; padding: 0; margin: 0; }
.viewers li {
  padding: 8px 0;
  border-bottom: 1px solid var(--border);
  font-family: var(--mono);
  font-size: 13px;
}
.viewers li:last-child { border-bottom: none; }

/* Viewer page */
.join-box {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 32px;
  max-width: 420px;
  margin: 48px auto;
  text-align: center;
}
.join-box h2 { margin-top: 0; }
.join-box form { display: flex; gap: 8px; margin-top: 16px; }
.join-box input {
  flex: 1;
  background: var(--bg);
  color: var(--text);
  border: 1px solid var(--border);
  padding: 10px 12px;
  border-radius: 8px;
  font: inherit;
  font-family: var(--mono);
  font-size: 16px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}
.join-box input:focus { outline: none; border-color: var(--accent); }

.player-box {
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.player-controls {
  display: flex;
  gap: 8px;
  justify-content: flex-end;
}

/* ─────────────────────────────────────────────────────────
   Mobile responsive layout.
   Breakpoint at 720px covers phones in portrait + landscape
   and small tablets. The video becomes the dominant element
   and controls grow to meet Apple HIG (44px) and Material
   (48px) minimum tap sizes.
   ───────────────────────────────────────────────────────── */
@media (max-width: 720px) {
  body { font-size: 16px; }  /* Prevent iOS Safari zoom on input focus. */

  header {
    padding: 10px 16px;
    gap: 8px;
  }
  .brand { font-size: 16px; }

  main { padding: 16px 12px; }

  /* Landing page on phones: stack, big tappable cards. */
  .landing h1 { font-size: 34px; margin: 24px 0 6px; }
  .landing .tagline { margin: 0 0 24px; }
  .card { padding: 20px; }

  /* Host: stack controls, bigger primary button. */
  .controls { gap: 8px; }
  .controls button { flex: 1 1 auto; min-height: 48px; padding: 12px 16px; }

  .share-info { padding: 12px; }
  .share-info .row {
    flex-direction: column;
    align-items: stretch;
    gap: 4px;
  }
  .share-info label { width: auto; font-size: 12px; }
  .share-info code { font-size: 22px; text-align: center; padding: 8px; background: var(--bg); border-radius: 6px; }
  .share-info .link { font-size: 12px; }

  /* Let video breathe on small screens. */
  video#preview, video#remote {
    max-height: 60vh;
  }

  /* Viewer join form: stack, big input + button. */
  .join-box { padding: 20px; margin: 16px auto; }
  .join-box form { flex-direction: column; gap: 12px; }
  .join-box input { font-size: 20px; min-height: 52px; text-align: center; }
  .join-box button { min-height: 52px; }

  /* Player controls: full-width tappable. */
  .player-controls {
    justify-content: stretch;
  }
  .player-controls button { flex: 1; min-height: 48px; }
}

/* Viewer in landscape on a phone: maximize the video, hide chrome. */
@media (max-width: 900px) and (orientation: landscape) {
  .viewer header { display: none; }
  .viewer main { padding: 0; max-width: none; }
  .viewer .player-box { gap: 0; }
  .viewer video#remote {
    width: 100vw;
    height: 100vh;
    max-height: none;
    border-radius: 0;
    border: none;
    object-fit: contain;
    background: #000;
  }
  .viewer .player-controls {
    position: fixed;
    bottom: 12px;
    right: 12px;
    z-index: 5;
  }
  .viewer .player-controls button {
    background: rgba(20, 22, 28, 0.85);
    backdrop-filter: blur(6px);
    -webkit-backdrop-filter: blur(6px);
  }
}

/* ─────────────────────────────────────────────────────────
   Tap-to-unmute / tap-to-play overlay for iOS viewers.
   iOS Safari blocks autoplay of streams with audio until the
   user taps. Even muted playback can fail on older iOS if the
   video element doesn't have explicit user gesture context.
   ───────────────────────────────────────────────────────── */
.tap-overlay {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  /* Translucent on purpose. iOS renders the first WebRTC frame as soon as
     any gesture lands on the page; the dimmed preview peeking through
     lets the viewer confirm what's being shared before they commit to
     tapping. The document-level pointerdown handler in viewer.js makes
     a tap anywhere count as "start", so users are never stuck staring
     at the preview.

     IMPORTANT: keep the hover/active/focus rules below in sync with this
     background. The generic `button:hover:not(:disabled)` rule earlier
     in this file has higher specificity (0,2,1 vs our 0,1,0) and will
     hijack the overlay to an opaque dark-gray — on iOS the :hover state
     "sticks" after a tap, so the overlay would turn solid gray until
     the user taps elsewhere. Match our background on all interaction
     states to prevent that. */
  background: rgba(0, 0, 0, 0.55);
  color: var(--text);
  font-size: 18px;
  cursor: pointer;
  z-index: 3;
  border-radius: var(--radius);
  user-select: none;
  -webkit-user-select: none;
  -webkit-tap-highlight-color: transparent;
  /* Button reset — the overlay is a <button> for iOS click reliability. */
  appearance: none;
  -webkit-appearance: none;
  border: none;
  margin: 0;
  padding: 0;
  font: inherit;
  width: 100%;
  height: 100%;
  /* Silences the ~300ms iOS double-tap zoom delay so tap feels instant. */
  touch-action: manipulation;
}
/* Pin the overlay background on every interaction state. Specificity
   0,3,0 beats `button:hover:not(:disabled)` at 0,2,1 — without this,
   iOS "sticky hover" after a tap turns the overlay opaque dark-gray
   and hides the video until the user taps somewhere else. */
.tap-overlay:hover:not(:disabled),
.tap-overlay:active:not(:disabled),
.tap-overlay:focus,
.tap-overlay:focus-visible {
  background: rgba(0, 0, 0, 0.55);
  /* And kill the focus ring — this is a full-bleed element, a ring
     around it looks like a bug. */
  outline: none;
  box-shadow: none;
}

/* The UA `[hidden] { display: none }` rule ties our `.tap-overlay
   { display: flex }` on specificity and loses on source order, so the
   `hidden` attribute alone is not enough to hide the overlay. Force it
   here explicitly. Without this, `els.tapOverlay.hidden = true` in JS
   is a no-op and the overlay stays visible forever. */
.tap-overlay[hidden] { display: none; }

/* Intentionally NO :active darken — on iOS Chrome, if the click event
   is ever suppressed, :active can stick and make the page look frozen. */
.tap-overlay .tap-inner {
  text-align: center;
  padding: 24px;
  pointer-events: none;  /* so clicks always count as "on the button" */
}
.tap-overlay .tap-icon {
  font-size: 44px;
  line-height: 1;
  margin-bottom: 12px;
  display: block;
}
.tap-overlay .tap-label { display: block; }
.player-box { position: relative; }  /* anchor for .tap-overlay */

/* ─────────────────────────────────────────────────────────
   Platform-specific messaging (iOS host unsupported, etc.)
   ───────────────────────────────────────────────────────── */
.platform-notice {
  background: var(--surface);
  border: 1px solid var(--border);
  border-left: 3px solid var(--accent);
  border-radius: var(--radius);
  padding: 16px 20px;
  margin: 16px 0;
  color: var(--text-dim);
  font-size: 14px;
  line-height: 1.5;
}
.platform-notice strong { color: var(--text); }
.platform-notice a { font-weight: 500; }
.platform-notice[hidden] { display: none; }
