:root {
  --bg: #0a0a0b;
  --surface: #101013;
  --border: rgb(255 255 255 / 0.09);
  --border-strong: rgb(255 255 255 / 0.17);
  --text: #ededf0;
  --text-muted: #9a9aa2;
  --text-placeholder: #85858d;
  --accent: #2f6bff;
  --accent-hover: #4a7dff;
  --accent-active: #2257d8;
  --dot-idle: #52525b;
  --dot-searching: #eab308;
  --dot-connected: #22c55e;
  --dot-error: #ef4444;

  /* One radius scale: 6px on every panel and control. The video stage is the
     single exception at 0, since it reads as a screen rather than a card. */
  --radius: 6px;
  --control-h: 36px;
}

* {
  box-sizing: border-box;
}

/* A `display` value on a class would otherwise beat the UA rule for [hidden]. */
[hidden] {
  display: none !important;
}

body {
  margin: 0;
  font-family: system-ui, sans-serif;
  background: var(--bg);
  color: var(--text);
  height: 100dvh;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  -webkit-font-smoothing: antialiased;
}

/* ---------- header ---------- */

header {
  flex: none;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  height: 52px;
  padding: 0 16px;
  border-bottom: 1px solid var(--border);
}

header h1 {
  margin: 0;
  font-size: 0.95rem;
  font-weight: 600;
  letter-spacing: 0.01em;
}

.header-right {
  display: flex;
  align-items: center;
  gap: 16px;
  font-size: 0.8rem;
  color: var(--text-muted);
}

.online-count {
  font-variant-numeric: tabular-nums;
}

.status {
  display: flex;
  align-items: center;
  gap: 7px;
}

.status-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--dot-idle);
  transition: background-color 0.2s ease;
}

.status[data-state='searching'] .status-dot {
  background: var(--dot-searching);
  animation: pulse 1.6s ease-in-out infinite;
}

.status[data-state='connected'] .status-dot {
  background: var(--dot-connected);
}

.status[data-state='error'] .status-dot {
  background: var(--dot-error);
}

@keyframes pulse {
  0%,
  100% {
    opacity: 1;
  }
  50% {
    opacity: 0.3;
  }
}

.session {
  display: flex;
  align-items: center;
  gap: 12px;
}

.session a {
  color: var(--text-muted);
  text-decoration: none;
  transition: color 0.15s ease;
}

.session a:hover {
  color: var(--text);
}

/* ---------- app shell ---------- */

main {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 40px 24px;
  gap: 24px;
}

/* Mobile first: stage on top, controls in the middle, chat filling the rest.
   Only the chat log scrolls; the page itself never does. */
main.app {
  /* Floor for the chat so a tall stage cannot squeeze it to nothing. */
  --chat-min-h: 180px;
  /* header + vertical padding + controls row + both row gaps */
  --chrome-v: 136px;
  /* Two stacked 16:9 tiles make the stage 8/9. Take whichever bound is
     tighter so the feeds are pixel-exact 16:9 with no bars inside them. */
  --stage-w: min(
    calc(100vw - 24px),
    calc((100dvh - var(--chrome-v) - var(--chat-min-h)) * 8 / 9)
  );

  flex: 1;
  min-height: 0;
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  padding: 12px;
  gap: 12px;
}

/* ---------- video stage ---------- */

/* Always two stacked rows. Only the width calculation differs by breakpoint.
   align-self centres it horizontally in the mobile flex column, and
   vertically in the desktop grid area. */
.stage {
  flex: none;
  display: grid;
  grid-template-columns: 1fr;
  grid-template-rows: 1fr 1fr;
  width: var(--stage-w);
  height: calc(var(--stage-w) * 9 / 8);
  align-self: center;
  border: 1px solid var(--border);
  background: #000;
  overflow: hidden;
}

.video-tile {
  position: relative;
  min-width: 0;
  min-height: 0;
  background: #000;
}

/* Hairline between the two feeds instead of a gap, so they read as one stage. */
.video-tile + .video-tile {
  border-top: 1px solid var(--border);
}

video {
  display: block;
  width: 100%;
  height: 100%;
  /* contain, not cover: show the whole frame and letterbox it rather than
     cropping the edges off someone's face. */
  object-fit: contain;
  opacity: 0;
  transition: opacity 0.35s ease;
}

video.active {
  opacity: 1;
}

.video-label {
  position: absolute;
  left: 8px;
  bottom: 8px;
  padding: 2px 7px;
  border-radius: 3px;
  background: rgb(0 0 0 / 0.55);
  color: var(--text);
  font-size: 0.7rem;
  letter-spacing: 0.02em;
}

/* ---------- controls ---------- */

.controls {
  flex: none;
  display: flex;
  gap: 8px;
}

.btn {
  height: var(--control-h);
  padding: 0 18px;
  border: 1px solid transparent;
  border-radius: var(--radius);
  font-family: inherit;
  font-size: 0.875rem;
  font-weight: 500;
  line-height: 1;
  white-space: nowrap;
  cursor: pointer;
  transition: background-color 0.15s ease, border-color 0.15s ease,
    color 0.15s ease, opacity 0.15s ease;
}

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

.btn:active:not(:disabled) {
  transform: translateY(1px);
}

.btn:disabled {
  opacity: 0.38;
  cursor: not-allowed;
}

.btn-primary {
  background: var(--accent);
  color: #fff;
}

.btn-primary:hover:not(:disabled) {
  background: var(--accent-hover);
}

.btn-primary:active:not(:disabled) {
  background: var(--accent-active);
}

.btn-secondary {
  background: transparent;
  border-color: var(--border-strong);
  color: var(--text);
}

.btn-secondary:hover:not(:disabled) {
  border-color: rgb(255 255 255 / 0.3);
  background: rgb(255 255 255 / 0.05);
}

/* Least prominent of the three: no fill, no border, muted until hovered. */
.btn-ghost {
  padding: 0 12px;
  background: transparent;
  color: var(--text-muted);
}

.btn-ghost:hover:not(:disabled) {
  color: var(--text);
  background: rgb(255 255 255 / 0.05);
}

/* ---------- chat ---------- */

.chat {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
}

.chat-log {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: 12px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  font-size: 0.875rem;
  line-height: 1.5;
  scrollbar-width: thin;
  scrollbar-color: rgb(255 255 255 / 0.16) transparent;
}

.chat-log::-webkit-scrollbar {
  width: 8px;
}

.chat-log::-webkit-scrollbar-track {
  background: transparent;
}

.chat-log::-webkit-scrollbar-thumb {
  background: rgb(255 255 255 / 0.16);
  border-radius: 999px;
}

.chat-log::-webkit-scrollbar-thumb:hover {
  background: rgb(255 255 255 / 0.26);
}

.chat-log p {
  margin: 0;
}

.chat-msg {
  overflow-wrap: anywhere;
}

.chat-msg-author {
  font-weight: 600;
  margin-right: 6px;
}

.chat-msg[data-from='you'] .chat-msg-author {
  color: var(--accent-hover);
}

.chat-msg[data-from='stranger'] .chat-msg-author {
  color: var(--dot-connected);
}

.chat-msg[data-from='system'] {
  color: var(--text-muted);
  font-size: 0.82rem;
}

.chat-form {
  flex: none;
  display: flex;
  gap: 8px;
  padding: 10px;
  border-top: 1px solid var(--border);
}

.chat-input {
  flex: 1;
  min-width: 0;
  height: var(--control-h);
  padding: 0 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: rgb(255 255 255 / 0.04);
  color: var(--text);
  font-family: inherit;
  font-size: 0.875rem;
}

.chat-input::placeholder {
  color: var(--text-placeholder);
}

.chat-input:focus {
  outline: none;
  border-color: var(--accent);
}

.chat-input:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

/* ---------- desktop ---------- */

/* Two columns on wide screens, and also on short landscape ones: a landscape
   phone has no vertical room for a stacked stage plus chat, but plenty of
   width to put them side by side. */
@media (min-width: 900px), (orientation: landscape) and (max-height: 560px) {
  header {
    height: 48px;
    padding: 0 16px;
  }

  /* Stage and controls stack in the left column; chat sits beside them and
     runs the full height. The stage row takes all the leftover space.
     The video column is sized to the height the stage will actually get, so
     two stacked 16:9 feeds fill it edge to edge instead of sitting in a wide
     box with dead black either side. Everything left over goes to chat, and
     the pair is centred rather than stretched. */
  main.app {
    /* Capped in px on desktop, but proportional so a landscape phone does
       not hand almost half its width to the chat. */
    --chat-w: min(420px, 38vw);
    /* header + vertical padding + controls row + row gap */
    --chrome-v: 116px;
    /* horizontal padding + column gap + chat column */
    --chrome-h: calc(34px + var(--chat-w));

    /* Two stacked 16:9 tiles make the stage 8/9. Size it from whichever bound
       is tighter so the feeds stay pixel-exact 16:9 in any window shape, and
       any slack sits outside the stage rather than as bars inside it. */
    --stage-w: min(
      calc(100vw - var(--chrome-h)),
      calc((100dvh - var(--chrome-v)) * 8 / 9)
    );

    display: grid;
    grid-template-columns: var(--stage-w) var(--chat-w);
    grid-template-rows: minmax(0, 1fr) auto;
    grid-template-areas:
      'stage chat'
      'controls chat';
    justify-content: center;
    padding: 12px;
    gap: 10px;
  }

  .stage {
    grid-area: stage;
    max-height: 100%;
    min-height: 0;
  }

  .controls {
    grid-area: controls;
  }

  .chat {
    grid-area: chat;
  }
}

/* ---------- login ---------- */

main.centered {
  flex: 1;
  min-height: 0;
  justify-content: center;
}

.panel {
  width: 100%;
  max-width: 360px;
  padding: 24px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
}

.panel-title {
  margin: 0 0 6px;
  font-size: 1rem;
  font-weight: 600;
}

.panel-body {
  margin: 0 0 18px;
  color: var(--text-muted);
  font-size: 0.875rem;
  line-height: 1.5;
}

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

.field-label {
  font-size: 0.78rem;
  color: var(--text-muted);
}

.field-input {
  height: 38px;
  padding: 0 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: rgb(255 255 255 / 0.04);
  color: var(--text);
  font-family: inherit;
  font-size: 0.9rem;
}

.field-input::placeholder {
  color: var(--text-placeholder);
}

.field-input:focus {
  outline: none;
  border-color: var(--accent);
}

.field-message {
  margin: 0;
  font-size: 0.8rem;
  line-height: 1.4;
  color: var(--dot-error);
}

.field-message:empty {
  display: none;
}

.field-message[data-kind='info'] {
  color: var(--text-muted);
}

.btn-block {
  width: 100%;
  margin-top: 4px;
}

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

/* ---------- small screens ---------- */

@media (max-width: 640px) {
  header {
    padding: 0 12px;
  }

  .header-right {
    gap: 12px;
  }

  /* The address is recoverable from the sign-out flow; the status and the
     online count matter more once the viewport is this tight. */
  #session-email {
    display: none;
  }

  .controls {
    gap: 6px;
  }

  .btn {
    padding: 0 14px;
  }

  .controls .btn-primary,
  .controls .btn-secondary {
    flex: 1;
  }
}

@media (prefers-reduced-motion: reduce) {
  .status-dot,
  video,
  .btn {
    animation: none !important;
    transition: none !important;
  }
}
