/* ==========================================================================
   Design tokens and base. Two grounds — foyer (lights up) and house (down).
   Deliberately single-theme: this is a cinema, it commits to the dark.
   ========================================================================== */

:root {
  /* Foyer — theater carpet and brass. Before the film, and on pause. */
  --foyer:        #2A1620;
  --foyer-raised: #3A2029;
  --brass:        #C9A227;

  /* House — warm near-black, never #000. Projection bulbs are warm. */
  --ink:          #0B0908;
  --ink-raised:   #16120F;

  --screen:       #F2EDE4;
  --dim:          #CFC3B8;
  --muted:        #8A7D74;
  --faint:        #6E625B;
  --lamp:         #E8A33D;
  --fault:        #C4564A;
  --rule:         #241D19;

  --display: "Bricolage Grotesque", "Arial Black", system-ui, sans-serif;
  --body: "Instrument Sans", "Helvetica Neue", Arial, sans-serif;
  --mono: "DM Mono", ui-monospace, "SF Mono", Menlo, monospace;

  --ease: cubic-bezier(.4, 0, .2, 1);

  /* One layout margin for the whole app. Grows with the viewport so a wide
     monitor gets breathing room at the edges without the content being
     parked in a column down the middle. Safe-area insets are added rather
     than replaced, so a notched phone in landscape keeps text clear of the
     cutout. The larger of the two side insets, because the same gutter pads
     both edges and the notch lands on whichever side the phone was turned
     towards. */
  --gutter: calc(clamp(18px, 4vw, 72px) + max(env(safe-area-inset-left, 0px), env(safe-area-inset-right, 0px)));

  color-scheme: dark;
}

* { box-sizing: border-box; }

/* Author rules beat the UA stylesheet, so a bare `label { display: block }`
   silently defeats the `hidden` attribute. Restate it with force once. */
[hidden] { display: none !important; }

html, body { min-height: 100%; }

/* Nothing should ever scroll sideways. This is the guard, not the fix — the
   causes are handled where they arise, with min-width:0 on grid and flex
   children and a measure on anything holding prose. */
html { overflow-x: hidden; }

body {
  margin: 0;
  background: var(--ink);
  color: var(--screen);
  font-family: var(--body);
  font-size: 16px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

/* ---------------------------------------------------------------- type */

h1, h2, h3 {
  font-family: var(--display);
  font-weight: 700;
  margin: 0;
  text-wrap: balance;
  letter-spacing: -0.025em;
  line-height: 1.02;
}

p { margin: 0; }

/* A pasted URL, a room code, a long unbroken filename: none of them may push
   a container wider than its column. */
p, h1, h2, h3, li, dd, .mono { overflow-wrap: anywhere; }

.eyebrow {
  font-family: var(--mono);
  font-size: 0.6875rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--muted);
}

.mono { font-family: var(--mono); }
.muted { color: var(--muted); }
.faint { color: var(--faint); }

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

button {
  font-family: var(--body);
  font-size: 0.9375rem;
  font-weight: 600;
  border: 0;
  border-radius: 3px;
  padding: 13px 22px;
  min-height: 44px;
  cursor: pointer;
  background: var(--brass);
  color: #1A0E13;
  transition: filter 160ms var(--ease), transform 120ms var(--ease);
  /* No double-tap-to-zoom wait before a tap registers, and no grey flash
     painted behind whatever was tapped. */
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
}
button:active:not(:disabled) { transform: translateY(1px); }
button:disabled { opacity: 0.4; cursor: not-allowed; }

button.ghost {
  background: transparent;
  color: var(--screen);
  border: 1px solid var(--rule);
  font-weight: 500;
}

button.bare {
  background: transparent;
  color: var(--dim);
  border: 0;
  padding: 10px 12px;
  font-weight: 500;
}

input, select {
  font-family: var(--body);
  font-size: 0.9375rem;
  background: var(--ink-raised);
  color: var(--screen);
  border: 1px solid var(--rule);
  border-radius: 3px;
  padding: 12px 14px;
  min-height: 44px;
  width: 100%;
}
input::placeholder { color: var(--faint); }

/* iOS zooms the whole page into any field whose text is under 16px the
   moment it is focused, and does not zoom back out — which is how tapping
   the chat box left the room magnified and sliding sideways. Touch screens
   get 16px everywhere; the look on a mouse is unchanged. */
@media (pointer: coarse) {
  input:not([type="range"]):not([type="checkbox"]):not([type="radio"]),
  select,
  textarea {
    font-size: 16px !important;
  }
}

/* Room codes are read aloud over the phone — always mono, always spaced. */
input.code {
  font-family: var(--mono);
  letter-spacing: 0.3em;
  text-transform: uppercase;
}

label {
  display: block;
  font-size: 0.8125rem;
  color: var(--muted);
  margin-bottom: 6px;
}

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

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

/* Hover only where there is a pointer that can hover. On a touch screen iOS
   applies :hover on tap and keeps it until the next tap somewhere else — so
   Full screen stayed lit amber after pressing it, and Join voice looked
   switched on when it was not. */
@media (hover: hover) {
  button:hover:not(:disabled) { filter: brightness(1.1); }
  button.ghost:hover:not(:disabled) { border-color: var(--lamp); color: var(--lamp); filter: none; }
  button.bare:hover:not(:disabled) { color: var(--lamp); filter: none; }
  a:hover { text-decoration: underline; }
}

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

/* The join gate is the one place a narrow measured column is right: a single
   short form, nothing to lay out around it. */
.shell {
  width: 100%;
  max-width: 460px;
  margin-inline: auto;
  /* Clear of the status bar in the installed app, and of the home bar. */
  padding:
    calc(clamp(56px, 14vh, 130px) + env(safe-area-inset-top, 0px))
    var(--gutter)
    max(60px, env(safe-area-inset-bottom, 0px));
}

.field { display: flex; flex-direction: column; }
.row { display: flex; gap: 10px; align-items: flex-end; flex-wrap: wrap; }
.row > .field { flex: 1 1 200px; }

.notice {
  font-size: 0.875rem;
  padding: 11px 14px;
  border-radius: 3px;
  border: 1px solid transparent;
}
.notice.err { color: var(--fault); border-color: rgba(196, 86, 74, .35); background: rgba(196, 86, 74, .08); }
.notice.info { color: var(--dim); border-color: var(--rule); background: var(--ink-raised); }
.notice[hidden] { display: none !important; }

.spin {
  display: inline-block; width: 12px; height: 12px;
  border: 2px solid rgba(232, 163, 61, .25);
  border-top-color: var(--lamp);
  border-radius: 50%;
  animation: spin 700ms linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 120ms !important;
  }
  .spin { animation: none !important; border-top-color: var(--lamp); }
}
