/* Tokens define the light palette; the two blocks below only redefine tokens. */
:root {
  --bg: #f2f6f6;
  --surface: #ffffff;
  --surface-2: #e9f0f0;
  --ink: #16212a;
  --muted: #5a6b72;
  --rule: #d2dcde;
  --accent: #0b7a75;
  --accent-ink: #065c58;
  --accent-soft: #dceeed;
  --danger: #a52a2a;
  --danger-soft: #f7e4e4;
  --warn-ink: #8a5000;
  --warn-soft: #fbf0da;
  --mine: #dceeed;
  --shadow: 0 1px 2px rgba(22, 33, 42, 0.06), 0 8px 24px rgba(22, 33, 42, 0.06);
  --mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
  --sans: system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg: #0d1416;
    --surface: #151e21;
    --surface-2: #1b262a;
    --ink: #e2eaeb;
    --muted: #8ea0a5;
    --rule: #263438;
    --accent: #4fbdb7;
    --accent-ink: #7ed3ce;
    --accent-soft: #12332f;
    --danger: #e08585;
    --danger-soft: #33191a;
    --warn-ink: #e3a84a;
    --warn-soft: #2c2412;
    --mine: #12332f;
    --shadow: 0 1px 2px rgba(0, 0, 0, 0.4), 0 8px 24px rgba(0, 0, 0, 0.3);
  }
}

:root[data-theme="dark"] {
  --bg: #0d1416;
  --surface: #151e21;
  --surface-2: #1b262a;
  --ink: #e2eaeb;
  --muted: #8ea0a5;
  --rule: #263438;
  --accent: #4fbdb7;
  --accent-ink: #7ed3ce;
  --accent-soft: #12332f;
  --danger: #e08585;
  --danger-soft: #33191a;
  --warn-ink: #e3a84a;
  --warn-soft: #2c2412;
  --mine: #12332f;
  --shadow: 0 1px 2px rgba(0, 0, 0, 0.4), 0 8px 24px rgba(0, 0, 0, 0.3);
}

* { box-sizing: border-box; }

/* An id selector such as `#screen-room { display: flex }` outranks the user
   agent's `[hidden] { display: none }`, so a hidden screen would keep
   rendering below the visible one, off the bottom of the page. Make the
   attribute authoritative instead of relying on selector order. */
[hidden] { display: none !important; }

body {
  margin: 0;
  min-height: 100vh;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 16px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

#app { display: block; }

.screen {
  max-width: 720px;
  margin: 0 auto;
  padding: 48px 20px 40px;
}

/* ---------- Home ---------- */

.brand { text-align: center; margin-bottom: 28px; }

.brand h1 {
  margin: 0 0 8px;
  font-size: 34px;
  line-height: 1.1;
  letter-spacing: -0.02em;
  font-weight: 650;
}

.tagline {
  margin: 0 auto;
  max-width: 42ch;
  color: var(--muted);
  text-wrap: balance;
}

.panel {
  display: flex;
  flex-direction: column;
  gap: 16px;
  background: var(--surface);
  border: 1px solid var(--rule);
  border-radius: 10px;
  padding: 24px;
  box-shadow: var(--shadow);
}

.field { display: flex; flex-direction: column; gap: 6px; }

.field-label {
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--muted);
}

.field-label em { font-style: normal; font-weight: 400; text-transform: none; letter-spacing: 0; }

.field-hint { font-size: 13px; color: var(--muted); }

input[type="text"], textarea {
  width: 100%;
  padding: 11px 13px;
  background: var(--bg);
  color: var(--ink);
  border: 1px solid var(--rule);
  border-radius: 7px;
  font-family: inherit;
  font-size: 16px;
  line-height: 1.4;
}

#join-code {
  font-family: var(--mono);
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

input[type="text"]:focus-visible, textarea:focus-visible, button:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

button {
  font-family: inherit;
  font-size: 15px;
  font-weight: 600;
  padding: 11px 16px;
  border-radius: 7px;
  border: 1px solid transparent;
  cursor: pointer;
}

button:disabled { opacity: 0.55; cursor: default; }

.primary { background: var(--accent); color: #fff; }
.secondary { background: var(--surface-2); color: var(--ink); border-color: var(--rule); }
.danger { background: transparent; color: var(--danger); border-color: var(--rule); }

.ghost {
  background: transparent;
  color: var(--accent-ink);
  border-color: var(--rule);
  font-size: 13px;
  padding: 6px 10px;
}

.divider {
  display: flex;
  align-items: center;
  gap: 12px;
  color: var(--muted);
  font-size: 13px;
}

.divider::before, .divider::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--rule);
}

.error {
  margin: 0;
  padding: 10px 12px;
  border-radius: 7px;
  background: var(--danger-soft);
  color: var(--danger);
  font-size: 14px;
}

.assurances {
  list-style: none;
  margin: 26px 0 0;
  padding: 0;
  display: grid;
  gap: 10px;
  font-size: 14px;
  color: var(--muted);
}

.assurances strong { color: var(--ink); }

/* ---------- Room ---------- */

#screen-room {
  display: flex;
  flex-direction: column;
  gap: 16px;
  max-width: 820px;
  /* A definite height, not a minimum. Given only `min-height` the column grows
     to fit the transcript, which leaves `overflow-y: auto` below nothing to
     scroll against: the page scrolls instead, the composer drifts thousands of
     pixels off the bottom of a long conversation, and the scroll-to-newest in
     appendEntry becomes a no-op. `dvh` keeps the height honest while a mobile
     browser slides its toolbars in and out. */
  height: 100vh;
  height: 100dvh;
  padding-top: 24px;
}

.room-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
  background: var(--surface);
  border: 1px solid var(--rule);
  border-radius: 10px;
  padding: 16px 18px;
}

.code-block { display: flex; flex-direction: column; gap: 6px; min-width: 0; }

.code {
  font-family: var(--mono);
  font-size: clamp(18px, 4vw, 24px);
  font-weight: 600;
  letter-spacing: 0.04em;
  word-break: break-all;
  color: var(--accent-ink);
}

.code-actions { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-top: 4px; }

/* The invite screen shows the code for reassurance, not for copying, so it sits
   quieter than the same value does in the room header. */
.code-sm { font-size: 16px; color: var(--muted); }

.copy-feedback { font-size: 13px; color: var(--muted); }

.qr { display: flex; flex-direction: column; gap: 8px; margin-top: 12px; }

/* The white quiet zone belongs to the SVG, so the panel keeps its own padding
   off the code and lets the symbol supply the contrast a scanner needs. */
.qr-canvas {
  width: 172px;
  max-width: 100%;
  border: 1px solid var(--rule);
  border-radius: 8px;
  overflow: hidden;
  line-height: 0;
}

.qr-canvas svg { display: block; width: 100%; height: auto; }

.qr-note { margin: 0; max-width: 46ch; font-size: 13px; color: var(--muted); }

.banner {
  padding: 10px 14px;
  border-radius: 8px;
  background: var(--warn-soft);
  color: var(--warn-ink);
  font-size: 14px;
}

.peers { display: flex; flex-direction: column; gap: 8px; }

.peer-list {
  list-style: none;
  margin: 0; padding: 0;
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}

.peer {
  display: flex;
  align-items: baseline;
  gap: 8px;
  padding: 7px 11px;
  background: var(--surface);
  border: 1px solid var(--rule);
  border-radius: 999px;
  font-size: 14px;
}

.peer.self { background: var(--accent-soft); border-color: var(--accent); }

.peer .safety {
  font-family: var(--mono);
  font-size: 12px;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}

.peer .badge { font-size: 12px; font-weight: 600; color: var(--accent-ink); }
.peer .badge.pending { color: var(--muted); }
.peer .badge.broken { color: var(--danger); }

.peer-empty { font-size: 14px; color: var(--muted); }

.transcript {
  list-style: none;
  margin: 0; padding: 14px;
  flex: 1;
  min-height: 220px;
  overflow-y: auto;
  /* The transcript drops its oldest entries once it passes its ceiling, and
     Chrome and Firefox would compensate for those removals through scroll
     anchoring while `trim()` compensates for them too, moving the view by
     twice the height that actually disappeared. Safari has no anchoring to
     turn off, so the correction in script is the one that runs everywhere and
     this leaves it unopposed. */
  overflow-anchor: none;
  display: flex;
  flex-direction: column;
  gap: 10px;
  background: var(--surface);
  border: 1px solid var(--rule);
  border-radius: 10px;
}

.entry { display: flex; flex-direction: column; gap: 3px; max-width: 78%; }
.entry.mine { align-self: flex-end; align-items: flex-end; }

.entry .meta {
  font-size: 12px;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}

.entry .bubble {
  padding: 9px 13px;
  border-radius: 12px;
  background: var(--surface-2);
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

.entry.mine .bubble { background: var(--mine); }

.entry.system, .entry.warning {
  align-self: center;
  align-items: center;
  max-width: 100%;
  text-align: center;
}

.entry.system .bubble {
  background: transparent;
  color: var(--muted);
  font-size: 13px;
  padding: 2px 0;
}

.entry.warning .bubble {
  background: var(--warn-soft);
  color: var(--warn-ink);
  font-size: 13px;
}

.composer { display: flex; gap: 10px; align-items: flex-end; }
.composer textarea { flex: 1; resize: none; max-height: 160px; }

.boot-error {
  max-width: 560px;
  margin: 80px auto;
  padding: 20px;
  background: var(--danger-soft);
  color: var(--danger);
  border-radius: 10px;
  font-size: 15px;
}

@media (max-width: 560px) {
  .screen { padding: 28px 14px; }
  .room-head { flex-direction: column; align-items: stretch; }
  .entry { max-width: 92%; }
}

@media (prefers-reduced-motion: no-preference) {
  button { transition: filter 0.12s ease; }
  button:hover:not(:disabled) { filter: brightness(1.06); }
}
