/* SPDX-License-Identifier: AGPL-3.0-only */
/* zero — single stylesheet, no framework.
   Two faces, one signal: the UI follows the system colour scheme with no
   toggle and no flash — plain prefers-color-scheme, applied before first
   paint, re-evaluated live when the OS switches.
     · light  "paper"     — warm cream stock, deep green ink
     · dark   "phosphor"  — near-black tube, signal-green type, scanlines
   No inline style attributes anywhere: seat colours arrive through
   [data-star="…"] rules so the strict CSP stays untouched. */

/* ---- tokens ---------------------------------------------------------------- */

:root {
  color-scheme: light;
  --bg: hsl(150 18% 95%);
  --panel: hsl(0 0% 100%);
  --fg: hsl(160 48% 11%);
  --muted: hsl(158 20% 34%);
  --line: hsl(150 20% 86%);
  --accent: hsl(158 92% 28%);
  --accent-ink: hsl(0 0% 100%);
  --mine: hsl(152 38% 92%);
  --danger: hsl(6 78% 46%);
  --ok: hsl(154 80% 32%);
  --warn: hsl(38 95% 40%);
  --warn-bg: hsl(44 85% 92%);
  --warn-ink: hsl(33 75% 22%);
  --shadow: hsl(160 35% 15% / 0.08);
  --radius: 14px;
  --radius-sm: 9px;
}

:root[data-theme="light"] {
  color-scheme: light;
  --bg: hsl(150 18% 95%);
  --panel: hsl(0 0% 100%);
  --fg: hsl(160 48% 11%);
  --muted: hsl(158 20% 34%);
  --line: hsl(150 20% 86%);
  --accent: hsl(158 92% 28%);
  --accent-ink: hsl(0 0% 100%);
  --mine: hsl(152 38% 92%);
  --danger: hsl(6 78% 46%);
  --ok: hsl(154 80% 32%);
  --warn: hsl(38 95% 40%);
  --warn-bg: hsl(44 85% 92%);
  --warn-ink: hsl(33 75% 22%);
  --shadow: hsl(160 35% 15% / 0.08);
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;
    --bg: hsl(150 30% 3%);
    --panel: hsl(150 24% 6%);
    --fg: hsl(138 70% 68%);
    --muted: hsl(140 28% 50%);
    --line: hsl(142 40% 16%);
    --accent: hsl(122 100% 55%);
    --accent-ink: hsl(150 35% 4%);
    --mine: hsl(150 45% 10%);
    --danger: hsl(4 85% 64%);
    --ok: hsl(122 100% 55%);
    --warn: hsl(42 95% 60%);
    --warn-bg: hsl(42 30% 14%);
    --warn-ink: hsl(42 85% 72%);
    --shadow: hsl(150 60% 2% / 0.8);
  }
}

:root[data-theme="dark"] {
  color-scheme: dark;
  --bg: hsl(150 30% 3%);
  --panel: hsl(150 24% 6%);
  --fg: hsl(138 70% 68%);
  --muted: hsl(140 28% 50%);
  --line: hsl(142 40% 16%);
  --accent: hsl(122 100% 55%);
  --accent-ink: hsl(150 35% 4%);
  --mine: hsl(150 45% 10%);
  --danger: hsl(4 85% 64%);
  --ok: hsl(122 100% 55%);
  --warn: hsl(42 95% 60%);
  --warn-bg: hsl(42 30% 14%);
  --warn-ink: hsl(42 85% 72%);
  --shadow: hsl(150 60% 2% / 0.8);
}

/* ---- base ------------------------------------------------------------------ */

* { box-sizing: border-box; }

html, body {
  height: 100%;
  overflow-x: hidden;
}
html {
  font-size: 93.75%;
  scrollbar-color: var(--line) transparent;
}

body {
  margin: 0;
  font-family: ui-monospace, "Cascadia Mono", "SF Mono", Menlo, Consolas, "DejaVu Sans Mono", "Liberation Mono", monospace;
  font-size: 1rem;
  line-height: 1.55;
  background-color: var(--bg);
  background-image:
    radial-gradient(72rem 38rem at 50% -12rem, hsl(155 45% 90% / 0.7), transparent 72%),
    radial-gradient(circle at 50% 50%, hsl(152 22% 80% / 0.55) 1px, transparent 1px);
  background-size: 100% 100%, 20px 20px;
  color: var(--fg);
  -webkit-font-smoothing: antialiased;
}

::selection { background: var(--accent); color: var(--accent-ink); }

#app { height: 100%; }

/* ---- theme faces -------------------------------------------------------------
   Two distinct, rich aesthetic faces sharing identical layout metrics:
     · light "cryptographic ledger": architectural micro-dot grid, ambient daylight wash, obsidian-emerald ink
     · dark  "phosphor CRT": near-black tube, signal-green ambient halo, and faint CRT scanlines */

@media (prefers-color-scheme: dark) {
  html:not([data-theme="light"]) body {
    background-color: var(--bg);
    background-image:
      radial-gradient(72rem 38rem at 50% -14rem, hsl(140 85% 9% / 0.55), transparent 70%);
    background-size: auto;
  }

  html:not([data-theme="light"]) body::after {
    content: "";
    position: fixed;
    inset: 0;
    z-index: 999;
    pointer-events: none;
    background: repeating-linear-gradient(to bottom, hsl(150 50% 2% / 0.22) 0 1px, transparent 1px 3px);
  }
}

html[data-theme="dark"] body {
  background-color: var(--bg);
  background-image:
    radial-gradient(72rem 38rem at 50% -14rem, hsl(140 85% 9% / 0.55), transparent 70%);
  background-size: auto;
}

html[data-theme="dark"] body::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 999;
  pointer-events: none;
  background: repeating-linear-gradient(to bottom, hsl(150 50% 2% / 0.22) 0 1px, transparent 1px 3px);
}

html[data-theme="light"] body {
  background-color: var(--bg);
  background-image:
    radial-gradient(72rem 38rem at 50% -12rem, hsl(155 45% 90% / 0.7), transparent 72%),
    radial-gradient(circle at 50% 50%, hsl(152 22% 80% / 0.55) 1px, transparent 1px);
  background-size: 100% 100%, 20px 20px;
}

html[data-theme="light"] body::after {
  content: none;
}

/* ---- shared bits ------------------------------------------------------------- */

.btn {
  font: inherit;
  border: 1px solid var(--line);
  background: var(--panel);
  color: var(--fg);
  padding: 0.5rem 1rem;
  border-radius: var(--radius-sm);
  cursor: pointer;
  white-space: nowrap;
  box-shadow: 0 1px 2px hsl(160 30% 15% / 0.05);
  transition: border-color 0.15s ease, box-shadow 0.15s ease, transform 0.15s ease;
}
.btn:hover {
  border-color: var(--accent);
  box-shadow: 0 2px 6px hsl(158 92% 28% / 0.12);
}
.btn:active { transform: translateY(1px); }
.btn:disabled { opacity: 0.5; cursor: default; transform: none; box-shadow: none; }
.btn.attaching {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
}
.btn.attaching:disabled {
  opacity: 0.8;
  cursor: wait;
}
.btn.primary {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--accent-ink);
  font-weight: 600;
  box-shadow: 0 2px 6px hsl(158 92% 25% / 0.28), 0 1px 2px hsl(158 92% 25% / 0.15);
}
.btn.primary:hover:not(:disabled) {
  filter: brightness(1.05);
  box-shadow: 0 4px 14px hsl(158 92% 25% / 0.38);
}
.btn.danger-ghost { color: var(--danger); box-shadow: none; }
.btn.tiny { padding: 0.15rem 0.55rem; font-size: 0.8rem; border-radius: 7px; }

@media (prefers-color-scheme: dark) {
  html:not([data-theme="light"]) .btn { box-shadow: none; }
  html:not([data-theme="light"]) .btn:hover { box-shadow: none; }
  html:not([data-theme="light"]) .btn.danger-ghost { background: hsl(4 45% 14%); border-color: hsl(4 50% 30%); }
  html:not([data-theme="light"]) .btn.primary { box-shadow: 0 0 22px hsl(122 100% 55% / 0.28); }
}

html[data-theme="dark"] .btn { box-shadow: none; }
html[data-theme="dark"] .btn:hover { box-shadow: none; }
html[data-theme="dark"] .btn.danger-ghost { background: hsl(4 45% 14%); border-color: hsl(4 50% 30%); }
html[data-theme="dark"] .btn.primary { box-shadow: 0 0 22px hsl(122 100% 55% / 0.28); }

.input {
  font: inherit;
  color: var(--fg);
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  padding: 0.55rem 0.7rem;
  width: 100%;
}
.input:focus, .btn:focus-visible, a:focus-visible, summary:focus-visible, textarea:focus {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
  box-shadow: 0 0 0 3px hsl(158 92% 28% / 0.15);
}
@media (prefers-color-scheme: dark) {
  html:not([data-theme="light"]) .input:focus,
  html:not([data-theme="light"]) .btn:focus-visible,
  html:not([data-theme="light"]) a:focus-visible,
  html:not([data-theme="light"]) summary:focus-visible,
  html:not([data-theme="light"]) textarea:focus {
    box-shadow: 0 0 12px hsl(122 100% 55% / 0.35);
  }
}

html[data-theme="dark"] .input:focus,
html[data-theme="dark"] .btn:focus-visible,
html[data-theme="dark"] a:focus-visible,
html[data-theme="dark"] summary:focus-visible,
html[data-theme="dark"] textarea:focus {
  box-shadow: 0 0 12px hsl(122 100% 55% / 0.35);
}

/* Blinking terminal cursor that follows the wordmark (both faces). */
.cursor {
  display: inline-block;
  width: 0.56em;
  height: 1em;
  margin-left: 0.16em;
  vertical-align: -0.1em;
  background: var(--accent);
  animation: cursor-blink 1.1s steps(1) infinite;
}
@keyframes cursor-blink { 50% { opacity: 0; } }

/* ---- landing ----------------------------------------------------------------- */

.landing {
  min-height: 100%;
  display: grid;
  place-items: center;
  padding: 1.25rem 1rem;
}

.card {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 1.6rem 1.8rem;
  max-width: 32rem;
  width: 100%;
  box-shadow: 0 2px 4px hsl(160 30% 15% / 0.04), 0 16px 36px -4px hsl(160 30% 15% / 0.09);
}

@media (prefers-color-scheme: dark) {
  html:not([data-theme="light"]) .card { box-shadow: 0 10px 30px var(--shadow); }
}

html[data-theme="dark"] .card { box-shadow: 0 10px 30px var(--shadow); }

.card-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  margin-bottom: 0.35rem;
}
.card-head-brand {
  display: flex;
  align-items: center;
  gap: 0.55rem;
}
.card-head h1 {
  margin: 0;
  font-size: 1.7rem;
  letter-spacing: -0.02em;
  text-shadow: 0 1px 1px hsl(152 40% 90% / 0.9);
}

.theme-toggle {
  font-size: 0.82rem;
  padding: 0.28rem 0.65rem;
  white-space: nowrap;
}

@media (prefers-color-scheme: dark) {
  html:not([data-theme="light"]) .card h1 { text-shadow: 0 0 16px hsl(122 100% 55% / 0.45); }
}

html[data-theme="dark"] .card h1 { text-shadow: 0 0 16px hsl(122 100% 55% / 0.45); }

.tagline { margin: 0 0 1.15rem; color: var(--muted); font-size: 0.95rem; line-height: 1.45; }

.create-form { display: grid; gap: 0.75rem; }
.create-form .input { min-height: 44px; font-size: 0.95rem; }
.create-form .btn { min-height: 44px; font-size: 0.95rem; font-weight: 600; }

.form-error { margin: 0; color: var(--danger); font-size: 0.88rem; }

.card-divider {
  border: 0;
  border-top: 1px solid var(--line);
  margin: 1.35rem 0 1.15rem;
}

.how-section {
  display: flex;
  flex-direction: column;
  gap: 0.85rem;
}

.how-title {
  margin: 0;
  font-size: 1.05rem;
  font-weight: 600;
  color: var(--fg);
  letter-spacing: -0.01em;
}

.how-steps {
  margin: 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: 0.85rem;
}

.how-steps strong {
  display: block;
  color: var(--fg);
  font-weight: 600;
  margin-bottom: 0.15rem;
  font-size: 0.95rem;
}

.how-desc {
  display: block;
  color: var(--muted);
  font-size: 0.90rem;
  line-height: 1.52;
}

.tech-section {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}

.tech-title {
  margin: 0;
  font-size: 1.05rem;
  font-weight: 600;
  color: var(--fg);
  letter-spacing: -0.01em;
}

.tech-text {
  margin: 0;
  color: var(--muted);
  font-size: 0.90rem;
  line-height: 1.52;
}

/* ---- room --------------------------------------------------------------------- */

.room {
  height: 100%;
  display: flex;
  flex-direction: column;
  max-width: 46rem;
  margin: 0 auto;
  width: 100%;
  box-sizing: border-box;
  overflow-x: hidden;
}

.room-body {
  height: 100%;
  display: flex;
  flex-direction: column;
  min-height: 0;
  min-width: 0;
  width: 100%;
  max-width: 100%;
  flex: 1;
}
.room-body.hidden {
  display: none !important;
}

.conceal-screen {
  flex: 1;
  display: grid;
  place-items: center;
  padding: 2rem 1rem;
  width: 100%;
  box-sizing: border-box;
}
.conceal-screen.hidden {
  display: none !important;
}

.conceal-card {
  max-width: 28rem;
  text-align: center;
}
.conceal-card .card-head {
  justify-content: center;
}
.conceal-actions {
  display: flex;
  justify-content: center;
  margin-top: 0.5rem;
}

.room-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  padding: 0.65rem 1rem;
  border-bottom: 1px solid var(--line);
  min-width: 0;
  max-width: 100%;
  box-sizing: border-box;
}

.room-header-main {
  display: flex;
  align-items: center;
  gap: 0.65rem;
  min-width: 0;
  flex: 1;
}

.room-identity {
  display: inline-flex;
  align-items: center;
  font-family: var(--mono);
  min-width: 0;
  flex-shrink: 0;
}

.room-code {
  margin: 0;
  font-size: 0.92rem;
  font-weight: 600;
  color: var(--fg);
  font-family: var(--mono);
  font-variant-ligatures: none;
  letter-spacing: 0.01em;
  white-space: nowrap;
}

html[data-theme="dark"] .room-code {
  text-shadow: 0 0 14px hsl(122 100% 55% / 0.35);
}

.chips {
  display: flex;
  gap: 0.35rem;
  align-items: center;
  flex-wrap: wrap;
  min-width: 0;
}

.chip {
  font-size: 0.76rem;
  color: var(--muted);
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 0.12rem 0.52rem;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
  box-shadow: 0 1px 2px hsl(160 30% 15% / 0.04);
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
}

.chip-quiet { border-style: dashed; }
.chip-crypto { letter-spacing: 0.02em; }
.chip-ttl[hidden] { display: none !important; }

.dot {
  width: 0.48rem;
  height: 0.48rem;
  border-radius: 50%;
  background: var(--muted);
  flex: none;
}

.dot[data-state="ok"] {
  background: var(--ok);
  box-shadow: 0 0 0 2px hsl(154 80% 32% / 0.22), 0 0 6px hsl(154 80% 32% / 0.45);
}
.dot[data-state="connecting"] { background: var(--warn); }
.dot[data-state="down"] { background: var(--danger); }
.dot[data-state="ended"] { background: var(--muted); }
@media (prefers-color-scheme: dark) {
  html:not([data-theme="light"]) .dot[data-state="ok"] { box-shadow: 0 0 8px hsl(122 100% 55% / 0.7); }
}

html[data-theme="dark"] .dot[data-state="ok"] { box-shadow: 0 0 8px hsl(122 100% 55% / 0.7); }

.roster {
  position: relative;
  display: inline-flex;
}

.roster summary,
.roster-summary {
  cursor: pointer;
  user-select: none;
  list-style: none;
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  transition: border-color 0.15s ease, color 0.15s ease;
}

.roster summary::-webkit-details-marker,
.roster-summary::-webkit-details-marker {
  display: none;
}

.roster summary:hover,
.roster-summary:hover {
  border-color: var(--accent);
  color: var(--fg);
}

.roster summary::after,
.roster-summary::after {
  content: " ▾";
  font-size: 0.65rem;
  opacity: 0.65;
}

.roster[open] summary::after,
.roster[open] .roster-summary::after {
  content: " ▴";
}

.room-actions {
  display: flex;
  gap: 0.35rem;
  align-items: center;
  flex: none;
  flex-wrap: wrap;
}

.room-actions .btn {
  font-size: 0.78rem;
  padding: 0.22rem 0.55rem;
  min-height: 28px;
  white-space: nowrap;
}

.room-actions .pass-btn {
  font-weight: 600;
}
.roster-list {
  position: absolute;
  left: 0;
  right: auto;
  top: calc(100% + 0.35rem);
  z-index: 60;
  margin: 0;
  padding: 0.55rem 0.75rem;
  list-style: none;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  min-width: 14rem;
  max-width: calc(100vw - 2rem);
  box-shadow: 0 12px 30px var(--shadow);
  display: grid;
  gap: 0.4rem;
  box-sizing: border-box;
}
.roster-item { display: flex; align-items: center; gap: 0.6rem; font-size: 0.9rem; min-height: 28px; }
.roster-item.away { opacity: 0.55; }
.swatch { width: 0.7rem; height: 0.7rem; border-radius: 50%; flex: none; background: var(--sender, var(--muted)); }
.roster-name { flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.badge {
  font-size: 0.68rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--accent);
  border: 1px solid var(--accent);
  border-radius: 999px;
  padding: 0 0.4rem;
  flex: none;
}

.banner {
  background: var(--warn-bg);
  color: var(--warn-ink);
  padding: 0.45rem 1rem;
  font-size: 0.9rem;
  text-align: center;
}

.messages {
  flex: 1;
  overflow-y: auto;
  list-style: none;
  margin: 0;
  padding: 1rem 1rem 1.5rem;
  display: flex;
  flex-direction: column;
  gap: 0.55rem;
}

.msg { display: flex; }
.msg.mine { justify-content: flex-end; }

.bubble {
  max-width: 78%;
  background: var(--panel);
  border: 1px solid var(--line);
  border-left: 3px solid var(--sender, var(--muted));
  border-radius: var(--radius-sm);
  padding: 0.5rem 0.8rem 0.55rem;
  overflow-wrap: anywhere;
  box-shadow: 0 1px 3px hsl(160 30% 15% / 0.04);
}
.msg.mine .bubble {
  background: var(--mine);
  border-left: 1px solid var(--line);
  border-right: 3px solid var(--sender, var(--accent));
  box-shadow: 0 1px 3px hsl(158 60% 25% / 0.08);
}

@media (prefers-color-scheme: dark) {
  html:not([data-theme="light"]) .bubble { box-shadow: none; }
  html:not([data-theme="light"]) .msg.mine .bubble { box-shadow: none; }
}

html[data-theme="dark"] .bubble { box-shadow: none; }
html[data-theme="dark"] .msg.mine .bubble { box-shadow: none; }

.who {
  display: block;
  font-size: 0.72rem;
  color: var(--muted);
  margin-bottom: 0.15rem;
}

.body { white-space: pre-wrap; }

.file-transfer {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.88rem;
}
.file-label {
  word-break: break-word;
  overflow-wrap: anywhere;
}

.spinner {
  display: inline-block;
  width: 0.85rem;
  height: 0.85rem;
  border: 2px solid var(--line);
  border-top-color: var(--accent);
  border-radius: 50%;
  animation: zero-spin 0.7s linear infinite;
  vertical-align: -0.12rem;
  flex: none;
}

@keyframes zero-spin {
  to { transform: rotate(360deg); }
}

@media (prefers-reduced-motion: reduce) {
  .spinner {
    animation-duration: 2s;
  }
}

.file-img {
  display: block;
  max-width: 100%;
  max-height: 20rem;
  border-radius: 7px;
  margin-bottom: 0.35rem;
}
.file-link { color: var(--accent); text-decoration: none; }
.file-link:hover, .file-link:focus-visible { text-decoration: underline; }

.sys {
  text-align: center;
  font-size: 0.8rem;
  color: var(--muted);
  padding: 0.2rem 0;
}

.composer {
  display: grid;
  gap: 0.5rem;
  padding: 0.8rem 1rem 1rem;
  border-top: 1px solid var(--line);
}
.composer-input { resize: none; min-height: 2.7rem; }
.composer-actions { display: flex; gap: 0.5rem; justify-content: flex-end; }

/* ---- seat palette ---------------------------------------------------------------
   One rule per seat name; the same hues return brighter on the dark face.
   Unknown names fall back to --muted via the var() default. */

.swatch[data-star="Altair"], .bubble[data-star="Altair"] { --sender: hsl(197 85% 44%); }
.swatch[data-star="Antares"], .bubble[data-star="Antares"] { --sender: hsl(18 82% 48%); }
.swatch[data-star="Rigel"], .bubble[data-star="Rigel"] { --sender: hsl(238 78% 60%); }
.swatch[data-star="Capella"], .bubble[data-star="Capella"] { --sender: hsl(48 90% 44%); }
.swatch[data-star="Mira"], .bubble[data-star="Mira"] { --sender: hsl(328 74% 50%); }
.swatch[data-star="Vega"], .bubble[data-star="Vega"] { --sender: hsl(172 78% 34%); }
.swatch[data-star="Deneb"], .bubble[data-star="Deneb"] { --sender: hsl(275 64% 56%); }
.swatch[data-star="Pollux"], .bubble[data-star="Pollux"] { --sender: hsl(95 55% 36%); }

@media (prefers-color-scheme: dark) {
  html:not([data-theme="light"]) .swatch[data-star="Altair"], html:not([data-theme="light"]) .bubble[data-star="Altair"] { --sender: hsl(197 92% 62%); }
  html:not([data-theme="light"]) .swatch[data-star="Antares"], html:not([data-theme="light"]) .bubble[data-star="Antares"] { --sender: hsl(18 88% 62%); }
  html:not([data-theme="light"]) .swatch[data-star="Rigel"], html:not([data-theme="light"]) .bubble[data-star="Rigel"] { --sender: hsl(238 84% 74%); }
  html:not([data-theme="light"]) .swatch[data-star="Capella"], html:not([data-theme="light"]) .bubble[data-star="Capella"] { --sender: hsl(48 95% 60%); }
  html:not([data-theme="light"]) .swatch[data-star="Mira"], html:not([data-theme="light"]) .bubble[data-star="Mira"] { --sender: hsl(328 78% 66%); }
  html:not([data-theme="light"]) .swatch[data-star="Vega"], html:not([data-theme="light"]) .bubble[data-star="Vega"] { --sender: hsl(172 82% 50%); }
  html:not([data-theme="light"]) .swatch[data-star="Deneb"], html:not([data-theme="light"]) .bubble[data-star="Deneb"] { --sender: hsl(275 68% 70%); }
  html:not([data-theme="light"]) .swatch[data-star="Pollux"], html:not([data-theme="light"]) .bubble[data-star="Pollux"] { --sender: hsl(95 62% 56%); }
}

html[data-theme="dark"] .swatch[data-star="Altair"], html[data-theme="dark"] .bubble[data-star="Altair"] { --sender: hsl(197 92% 62%); }
html[data-theme="dark"] .swatch[data-star="Antares"], html[data-theme="dark"] .bubble[data-star="Antares"] { --sender: hsl(18 88% 62%); }
html[data-theme="dark"] .swatch[data-star="Rigel"], html[data-theme="dark"] .bubble[data-star="Rigel"] { --sender: hsl(238 84% 74%); }
html[data-theme="dark"] .swatch[data-star="Capella"], html[data-theme="dark"] .bubble[data-star="Capella"] { --sender: hsl(48 95% 60%); }
html[data-theme="dark"] .swatch[data-star="Mira"], html[data-theme="dark"] .bubble[data-star="Mira"] { --sender: hsl(328 78% 66%); }
html[data-theme="dark"] .swatch[data-star="Vega"], html[data-theme="dark"] .bubble[data-star="Vega"] { --sender: hsl(172 82% 50%); }
html[data-theme="dark"] .swatch[data-star="Deneb"], html[data-theme="dark"] .bubble[data-star="Deneb"] { --sender: hsl(275 68% 70%); }
html[data-theme="dark"] .swatch[data-star="Pollux"], html[data-theme="dark"] .bubble[data-star="Pollux"] { --sender: hsl(95 62% 56%); }

/* ---- dialog / toasts ------------------------------------------------------------- */

.dialog {
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--panel);
  color: var(--fg);
  padding: 1.4rem 1.6rem;
  max-width: 30rem;
  width: calc(100vw - 2rem);
}
.dialog::backdrop { background: var(--shadow); }
.dialog h3 { margin: 0 0 0.4rem; }
.dialog-note { color: var(--muted); font-size: 0.88rem; margin: 0 0 0.8rem; }
.dialog-actions { display: flex; gap: 0.5rem; flex-wrap: wrap; margin-top: 0.9rem; }

.toasts {
  position: fixed;
  bottom: 1rem;
  left: 50%;
  transform: translateX(-50%);
  display: grid;
  gap: 0.4rem;
  z-index: 20;
}
.toast {
  background: var(--fg);
  color: var(--bg);
  padding: 0.5rem 1rem;
  border-radius: 999px;
  font-size: 0.88rem;
  box-shadow: 0 8px 20px var(--shadow);
}

.copy-fallback {
  position: fixed;
  left: -9999px;
  top: 0;
}

/* ---- burn animation & goodbye screen -------------------------------------------- */

.room.burning .room-header,
.room.burning .banner,
.room.burning .messages,
.room.burning .bubble,
.room.burning .sys,
.room.burning .composer,
.room.burning .toasts {
  animation: burn-consume 1.4s ease-in forwards;
  pointer-events: none;
}

@keyframes burn-consume {
  0% {
    opacity: 1;
    filter: none;
    transform: translateY(0) scale(1);
  }
  30% {
    border-color: hsl(24 100% 54%);
    color: hsl(28 100% 62%);
    box-shadow: 0 0 24px hsl(18 100% 50% / 0.55);
  }
  65% {
    opacity: 0.45;
    border-color: hsl(10 85% 32%);
    color: hsl(14 60% 28%);
    filter: contrast(1.4) brightness(0.45) blur(1.5px);
    transform: translateY(-8px) scale(0.985);
  }
  100% {
    opacity: 0;
    filter: brightness(0.1) blur(6px);
    transform: translateY(-20px) scale(0.96);
  }
}

.fire-overlay {
  position: fixed;
  inset: 0;
  z-index: 900;
  display: grid;
  place-items: center;
  overflow: hidden;
  background: var(--bg);
  animation: fire-backdrop 1.5s ease-out both;
}

@keyframes fire-backdrop {
  0% { background: transparent; }
  45% { background: hsl(16 80% 8% / 0.55); }
  78% { background: hsl(12 65% 5% / 0.92); }
  100% { background: var(--bg); }
}

.fire-canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  z-index: 1;
}

.burn-goodbye {
  position: relative;
  z-index: 2;
  text-align: center;
  padding: 2rem;
  opacity: 1;
  animation: goodbye-enter 2.2s ease-out both;
}

.burn-goodbye-text {
  margin: 0;
  font-size: 2rem;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--fg);
}

.burn-countdown {
  margin: 0.55rem 0 0;
  font-size: 0.95rem;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}

@media (prefers-color-scheme: dark) {
  html:not([data-theme="light"]) .burn-goodbye-text {
    text-shadow: 0 0 18px hsl(18 90% 55% / 0.35), 0 0 14px hsl(122 100% 55% / 0.35);
  }
}

html[data-theme="dark"] .burn-goodbye-text {
  text-shadow: 0 0 18px hsl(18 90% 55% / 0.35), 0 0 14px hsl(122 100% 55% / 0.35);
}

@keyframes goodbye-enter {
  0%, 55% {
    opacity: 0;
    transform: translateY(8px) scale(0.96);
  }
  100% {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
}

/* ---- motion & small screens ------------------------------------------------------ */

@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; animation: none !important; }
}

@media (max-width: 520px) {
  .landing { padding: 0.85rem 0.65rem; }
  .card { padding: 1.4rem 1.15rem; }
  .card-head h1 { font-size: 1.55rem; }
  .tagline { margin: 0 0 1rem; font-size: 0.92rem; line-height: 1.45; }
  .card-divider { margin: 1.2rem 0 1rem; }
  .how-title { font-size: 1.02rem; }
  .how-steps { gap: 0.80rem; }
  .how-steps strong { font-size: 0.94rem; margin-bottom: 0.15rem; }
  .how-desc { font-size: 0.88rem; line-height: 1.50; }
  .tech-title { font-size: 1.02rem; }
  .tech-text { font-size: 0.88rem; line-height: 1.50; }
  .bubble { max-width: 90%; }

  /* Mobile room header: 2 purposeful, compact, non-cluttered rows */
  .room-header {
    flex-direction: column;
    align-items: stretch;
    gap: 0.4rem;
    padding: 0.55rem 0.75rem 0.45rem;
  }

  .room-header-main {
    width: 100%;
    justify-content: space-between;
    gap: 0.4rem;
  }

  .room-code {
    font-size: 0.84rem;
  }

  .room-actions {
    width: 100%;
    display: flex;
    gap: 0.3rem;
    align-items: center;
    flex-wrap: wrap;
    justify-content: flex-start;
  }

  .room-actions .btn,
  .room-actions .theme-toggle,
  .room-actions .roster summary,
  .roster-summary {
    font-size: 0.76rem;
    padding: 0.18rem 0.42rem;
    min-height: 26px;
    white-space: nowrap;
  }

  .btn-extra-text {
    display: none;
  }

  .roster-list {
    left: auto;
    right: 0;
    max-width: calc(100vw - 1.5rem);
  }
}

/* PWA install prompt banner (news.svpn.com style) */
.pwa-install-bar {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 8px 14px;
  background: var(--panel);
  border-bottom: 1px solid var(--line);
  color: var(--fg);
  font-size: 13px;
  line-height: 1.35;
  width: 100%;
  box-sizing: border-box;
  position: relative;
  z-index: 100;
  animation: pwaSlideDown 0.22s ease-out;
}

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

.pwa-install-icon {
  width: 32px;
  height: 32px;
  border-radius: 8px;
  flex: none;
  display: block;
}

.pwa-install-box {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
}

.pwa-install-title {
  font-weight: 600;
  color: var(--fg);
  font-size: 13px;
}

.pwa-install-sub {
  color: var(--muted);
  font-size: 12px;
}

.pwa-install-btn {
  flex: none;
  min-height: 32px;
  padding: 0 14px;
  border: 1px solid var(--accent);
  border-radius: 6px;
  background: var(--accent);
  color: var(--accent-ink);
  font: inherit;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  transition: opacity 0.15s ease, transform 0.15s ease, filter 0.15s ease;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .pwa-install-btn {
    box-shadow: 0 0 14px hsl(122 100% 55% / 0.35);
  }
}

:root[data-theme="dark"] .pwa-install-btn {
  box-shadow: 0 0 14px hsl(122 100% 55% / 0.35);
}

.pwa-install-btn:hover {
  filter: brightness(1.1);
}

.pwa-install-btn:active {
  transform: scale(0.97);
}

.pwa-install-dismiss {
  flex: none;
  width: 32px;
  height: 32px;
  border: 0;
  border-radius: 4px;
  background: transparent;
  color: var(--muted);
  font: inherit;
  font-size: 20px;
  line-height: 1;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: color 0.15s ease, background 0.15s ease;
}

.pwa-install-dismiss:hover {
  color: var(--fg);
  background: var(--line);
}

/* ---- manual invite fallback, banner retry, jump to latest, and file pull ---- */

.manual-invite-box {
  background: var(--panel);
  border-bottom: 1px solid var(--line);
  padding: 0.65rem 1rem;
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  font-size: 0.88rem;
  z-index: 20;
}
.manual-invite-box.hidden {
  display: none;
}
.manual-invite-label {
  font-size: 0.82rem;
  color: var(--muted);
  font-weight: 500;
}
.manual-invite-row {
  display: flex;
  gap: 0.5rem;
  align-items: center;
}
.manual-invite-input {
  flex: 1;
  min-width: 0;
  font-family: var(--mono);
  font-size: 0.82rem;
  padding: 0.35rem 0.55rem;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--bg);
  color: var(--fg);
}
.manual-invite-dismiss {
  flex: none;
  font-size: 0.82rem;
  padding: 0.35rem 0.65rem;
}

.banner-retry-btn {
  margin-left: 0.5rem;
  padding: 0.15rem 0.6rem;
  font-size: 0.8rem;
  font-family: inherit;
  border: 1px solid currentColor;
  background: transparent;
  color: inherit;
  border-radius: var(--radius-sm);
  cursor: pointer;
  vertical-align: middle;
}
.banner-retry-btn:hover {
  filter: brightness(1.15);
  background: var(--line);
}

.jump-latest {
  position: absolute;
  bottom: 4.8rem;
  left: 50%;
  transform: translateX(-50%);
  z-index: 50;
  padding: 0.35rem 0.85rem;
  font-family: var(--mono);
  font-size: 0.8rem;
  font-weight: 600;
  border-radius: 9999px;
  background: var(--panel);
  color: var(--accent);
  border: 1px solid var(--line);
  box-shadow: 0 4px 14px var(--shadow);
  cursor: pointer;
  transition: opacity 0.15s ease, transform 0.15s ease;
}
.jump-latest:hover {
  filter: brightness(1.08);
}
.jump-latest.hidden {
  display: none;
}

.file-download-btn {
  margin-left: 0.5rem;
  font-size: 0.78rem;
  padding: 0.15rem 0.55rem;
  border: 1px solid var(--accent);
  color: var(--accent);
  background: transparent;
  border-radius: var(--radius-sm);
  cursor: pointer;
}
.file-download-btn:hover {
  background: var(--accent);
  color: var(--accent-ink);
}

