/* THE ROLE SCREEN'S LOOK (IND-1512). The first thing every stand device shows, so it is dressed as
   the same product as the instructor's controller and the debrief screen.

   THE CONTROLLER'S OWN TOKENS, NOT NEW ONES. Dark is the default, and it is the controller's layout
   A, the theatre console (`packages/controller/app/globals.css`, `:root`), which DESIGN.md calls the
   debrief screen's own palette: a device on the stand reads as one product with the two screens a
   visitor sees. A device set to light gets the controller's own light palette, layout B, the
   anaesthetic record (`[data-layout="record"]`), with the console's rounder corners kept so the
   shapes do not change with the colours, and TWO VALUES DARKER THAN LAYOUT B'S: `--muted` (#7b7566
   there, #6e685b here) and `--warn` (#a3620e there, #965a0d here). Layout B's pair falls short of
   the 4.5:1 WCAG AA asks of small text on this page's light surfaces (muted 3.75:1 on --panel-2,
   warn 3.98:1); these are the least darkening, same hue, that reaches 4.5:1 on every surface each
   sits on: muted 4.91 on --paper, 5.30 on --panel, 4.53 on --panel-2, 4.77 on --accent-soft; warn
   4.94 on --paper, 5.34 on --panel, 4.56 on --panel-2, 5.06 on --warn-soft. Dark is the
   controller's exactly. Same names as the controller's tokens, so a change there is
   a copy here. ONE ACCENT, AND COLOUR MEANS ONE THING, as there: green is joined and chosen, amber is
   waiting or a notice, red is refused.

   FACES. The controller self-hosts Inter and Source Serif 4 at build time. This page fetches nothing
   but its own files and the hub's doors, so it names those faces first, for a device that has
   them installed, and falls back to the system's own: New York (`ui-serif`) and San Francisco on an
   iPad or a Mac, Segoe UI on Windows, Roboto and Noto Serif on Android.

   TARGETS. Every control is at least the controller's 56 px, well over the 44 px minimum. */

:root {
  --paper: #16171a;
  --panel: #1d1f23;
  --panel-2: #24272c;
  --ink: #f0efeb;
  --ink-2: #cfcdc6;
  --muted: #97948c;
  --line: #2e3238;
  --line-2: #3b4048;
  --accent: #7fc0ad;
  --accent-soft: #1d2b28;
  --accent-ink: #bfe6d8;
  --warn: #e0b45a;
  --warn-soft: #2d2718;
  --stop: #e07a7a;
  --stop-soft: #2d1c1c;
  --radius: 12px;
  --radius-sm: 8px;
  --touch: 56px;
  --shadow: 0 1px 0 rgba(255, 255, 255, 0.03) inset, 0 10px 30px rgba(0, 0, 0, 0.25);
  --font-display: 'Source Serif 4', 'Source Serif Pro', ui-serif, 'New York', Georgia, 'Noto Serif', serif;
  --font-ui: 'Inter', system-ui, -apple-system, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
  color-scheme: dark;
}

@media (prefers-color-scheme: light) {
  :root {
    --paper: #f4f1ea;
    --panel: #fbfaf6;
    --panel-2: #ece8df;
    --ink: #1e1c17;
    --ink-2: #4a463d;
    --muted: #6e685b;
    --line: #d9d3c6;
    --line-2: #c4bdad;
    --accent: #2f5d50;
    --accent-soft: #e8f0ec;
    --accent-ink: #24493f;
    --warn: #965a0d;
    --warn-soft: #fbf3e4;
    --stop: #8c2f2f;
    --stop-soft: #fcf1f0;
    --shadow: 0 1px 2px rgba(30, 28, 23, 0.06), 0 8px 24px rgba(30, 28, 23, 0.06);
    color-scheme: light;
  }
}

* { box-sizing: border-box; }

html {
  background: var(--paper);
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}

body {
  margin: 0;
  min-height: 100vh;
  min-height: 100dvh;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-ui);
  font-size: 17px;
  line-height: 1.45;
  -webkit-tap-highlight-color: transparent;
  overscroll-behavior: none;
  padding:
    env(safe-area-inset-top, 0px)
    env(safe-area-inset-right, 0px)
    env(safe-area-inset-bottom, 0px)
    env(safe-area-inset-left, 0px);
}

main {
  max-width: 76rem;
  margin: 0 auto;
  padding: 1.25rem clamp(1rem, 3.5vw, 2.5rem) 3rem;
}

h1, h2 { font-family: var(--font-display); font-weight: 500; margin: 0; }
h1 { font-size: clamp(2.1rem, 4.2vw, 2.9rem); line-height: 1.1; letter-spacing: -0.01em; }
h1:focus { outline: none; }
h2 { font-size: 1.35rem; line-height: 1.2; }

a { color: var(--accent); }

code {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 0.92em;
  overflow-wrap: anywhere;
  color: var(--ink-2);
}

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

/* ---- buttons, as the controller's ------------------------------------------------------------ */

button, select { font: inherit; color: inherit; }

button {
  min-height: var(--touch);
  padding: 0 20px;
  border: 1px solid var(--line-2);
  border-radius: var(--radius-sm);
  background: var(--panel-2);
  color: var(--ink);
  font-weight: 600;
  cursor: pointer;
  touch-action: manipulation;
  user-select: none;
  -webkit-user-select: none;
  transition: transform 90ms ease, filter 90ms ease, background-color 120ms ease, border-color 120ms ease;
}
/* Every press answers: the button sinks and brightens while the finger is down, as on the controller. */
button:not(:disabled):active { transform: scale(0.97); filter: brightness(1.15); }
button:focus-visible, select:focus-visible, a:focus-visible { outline: 3px solid var(--accent); outline-offset: 3px; }
button.primary { background: var(--accent-soft); border-color: var(--accent); color: var(--accent-ink); }
button.stop { background: var(--stop-soft); border-color: var(--stop); color: var(--stop); }
button:disabled { cursor: default; opacity: 0.5; }
@media (prefers-reduced-motion: reduce) {
  button { transition: none; }
  button:not(:disabled):active { transform: none; }
}

/* ---- the top bar ----------------------------------------------------------------------------- */

.topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  min-height: 3.5rem;
  margin-bottom: clamp(1.5rem, 4vh, 2.75rem);
  padding-bottom: 1rem;
  border-bottom: 1px solid var(--line);
}

.brand { display: flex; align-items: center; gap: 0.6rem; min-width: 0; }
.mark { color: var(--accent); fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; flex: none; }
.mark .mark-dot { fill: currentColor; stroke: none; }
.brand-name { font-family: var(--font-display); font-size: 1.6rem; font-weight: 500; letter-spacing: -0.01em; }
.brand-place {
  padding-left: 0.7rem;
  margin-left: 0.1rem;
  border-left: 1px solid var(--line-2);
  color: var(--muted);
  font-size: 0.8rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.joined {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  margin: 0;
  padding: 0.4rem 0.85rem;
  border: 1px solid var(--line-2);
  border-radius: 999px;
  color: var(--ink-2);
  font-size: 0.9rem;
  font-weight: 600;
  white-space: nowrap;
}
.joined[hidden] { display: none; }
.dot { width: 0.6rem; height: 0.6rem; border-radius: 50%; background: var(--muted); flex: none; }
.joined.is-joined { border-color: var(--accent); color: var(--accent-ink); }
.joined.is-joined .dot { background: var(--accent); }
.joined.is-not { border-color: var(--warn); color: var(--warn); }
.joined.is-not .dot { background: var(--warn); }

/* ---- the roles view -------------------------------------------------------------------------- */

.layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  grid-template-areas: "intro" "side" "main";
  gap: 0 2rem;
}
.intro { grid-area: intro; margin-bottom: 1.75rem; }
.side { grid-area: side; }
.main { grid-area: main; min-width: 0; }
.side.has-approvals { margin-bottom: 1.75rem; }

/* Wide enough, the devices waiting sit beside the roles rather than above them. */
@media (min-width: 1100px) {
  .layout:has(.side.has-approvals) {
    grid-template-columns: minmax(0, 1fr) 24rem;
    grid-template-areas: "intro intro" "main side";
  }
  .side.has-approvals { margin-bottom: 0; position: sticky; top: 1rem; align-self: start; }
}

.eyebrow {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin: 0 0 0.6rem;
  color: var(--accent);
  font-size: 0.85rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}
.eyebrow-icon { display: inline-flex; }

.lede { margin: 0.6rem 0 0; color: var(--ink-2); font-size: 1.15rem; max-width: 46rem; }

.notices:empty { display: none; }
.notice {
  margin: 0 0 1.25rem;
  padding: 0.9rem 1.1rem;
  background: var(--warn-soft);
  border: 1px solid var(--warn);
  border-radius: var(--radius);
  color: var(--ink);
}
.notice strong { color: var(--warn); }

.current {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: center;
  gap: 0.9rem 1.1rem;
  margin: 0 0 1.5rem;
  padding: 1rem 1.25rem;
  background: var(--accent-soft);
  border: 1px solid var(--accent);
  border-radius: var(--radius);
}
.current-icon, .tile-icon, .opening-icon {
  display: grid;
  place-items: center;
  color: var(--accent-ink);
  background: var(--accent-soft);
  border: 1px solid var(--line-2);
  border-radius: var(--radius-sm);
}
.current-icon { width: 3.25rem; height: 3.25rem; background: var(--panel); border-color: var(--accent); }
.current-words { margin: 0; display: grid; gap: 0.1rem; }
.current-eyebrow { color: var(--ink-2); font-size: 0.95rem; }
.current-words strong { font-family: var(--font-display); font-size: 1.5rem; font-weight: 500; }
.current-actions { grid-column: 1 / -1; display: flex; flex-wrap: wrap; gap: 0.75rem; }
@media (min-width: 700px) {
  .current { grid-template-columns: auto minmax(0, 1fr) auto; }
  .current-actions { grid-column: auto; }
}

.icon { fill: none; stroke: currentColor; stroke-width: 1.75; stroke-linecap: round; stroke-linejoin: round; }

.tiles {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 17.5rem), 1fr));
  gap: 0.9rem;
}
.tiles-two { grid-template-columns: repeat(auto-fill, minmax(min(100%, 20rem), 1fr)); }
/* Each tile fills its grid cell, so a row of tiles is one height whichever of them wraps. */
.tiles > li { display: flex; }

.tile {
  position: relative;
  width: 100%;
  min-height: 8.25rem;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.9rem;
  padding: 1.1rem 1.2rem 1.2rem;
  background: var(--panel);
  border: 1px solid var(--line-2);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  text-align: left;
  font-weight: 400;
}
.tile:hover:not(:disabled) { border-color: var(--accent); }
.tile-icon { width: 3rem; height: 3rem; }
.tile-text { display: grid; gap: 0.25rem; }
.tile-label { font-size: 1.3rem; font-weight: 600; line-height: 1.2; color: var(--ink); }
.tile-what { font-size: 0.98rem; color: var(--muted); line-height: 1.35; }

.tile.is-current { border-color: var(--accent); background: var(--accent-soft); box-shadow: 0 0 0 1px var(--accent) inset, var(--shadow); }
.tile.is-current .tile-icon { background: var(--panel); border-color: var(--accent); }

.tile:disabled { opacity: 1; background: transparent; border-style: dashed; box-shadow: none; }
.tile:disabled .tile-icon { color: var(--muted); background: transparent; }
.tile:disabled .tile-label, .tile:disabled .tile-what { color: var(--muted); }

.badge {
  position: absolute;
  top: 1rem;
  right: 1rem;
  padding: 0.2rem 0.65rem;
  border: 1px solid currentColor;
  border-radius: 999px;
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}
.badge-current { color: var(--accent); background: var(--panel); }
.badge-later { color: var(--muted); }

.back { margin: 1.5rem 0 0; }

footer {
  margin-top: 2.25rem;
  padding-top: 1rem;
  border-top: 1px solid var(--line);
  color: var(--muted);
  font-size: 0.95rem;
}
footer p { margin: 0; }

/* ---- the cloud runners (IND-1558) ------------------------------------------------------------ */

/* The Runner tile is a link drawn as a tile: it is not a role, so it carries no button. */
a.tile-link { color: inherit; text-decoration: none; }
a.tile-link:hover { border-color: var(--accent); }

/* On the front door: how many sessions are running against the cap. Words only, no action. */
.sessions { margin: 0.9rem 0 0; color: var(--ink-2); font-size: 1rem; }
.sessions.is-full { color: var(--warn); font-weight: 600; }

/* The words beside Leave this runner, when a leave does not land. */
.runner-outcome { margin: 0; font-weight: 600; color: var(--accent-ink); }
/* A live region, so never display:none: empty, it is taken out of the flow and takes no space. */
.runner-outcome:empty { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }
.runner-outcome.is-warn { color: var(--warn); }

/* On a runner: which one, and the way back to the front door. */
.runner-leave { display: flex; flex-wrap: wrap; align-items: center; gap: 0.6rem 1rem; margin: 2rem 0 0; color: var(--ink-2); }

/* ---- the devices waiting to join ------------------------------------------------------------- */

.approvals {
  padding: 1.1rem 1.1rem 1.2rem;
  background: var(--panel);
  border: 1px solid var(--line-2);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
}
.approvals-head { display: grid; gap: 0.3rem; margin-bottom: 0.75rem; }
.approvals-how { margin: 0; color: var(--muted); font-size: 0.95rem; }
.approvals-state { margin: 0; color: var(--ink-2); font-size: 0.95rem; }
/* A live region, so never display:none: empty, it is taken out of the flow and takes no space. */
.approvals-state:empty { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }
.approvals-state.is-warn { color: var(--warn); }

.waiting { list-style: none; margin: 0.75rem 0 0; padding: 0; display: grid; gap: 0.75rem; }
.waiting:empty { display: none; }
.waiting-row {
  position: relative;
  display: grid;
  gap: 0.6rem;
  padding: 0.9rem 1rem 1rem;
  background: var(--panel-2);
  border: 1px solid var(--warn);
  border-radius: var(--radius-sm);
}
.waiting-top { display: flex; align-items: center; gap: 0.75rem; flex-wrap: wrap; }
.waiting-code {
  font-size: 2.1rem;
  font-weight: 700;
  letter-spacing: 0.18em;
  line-height: 1;
  font-variant-numeric: tabular-nums;
  color: var(--ink);
}
.waiting-icon { display: inline-flex; color: var(--ink-2); }
.waiting-role { font-weight: 600; color: var(--ink); }
.waiting-hint { color: var(--muted); font-size: 0.92rem; }
.waiting-change { display: grid; gap: 0.35rem; color: var(--ink-2); font-size: 0.9rem; font-weight: 600; }
.waiting-change select {
  min-height: var(--touch);
  width: 100%;
  padding: 0 0.85rem;
  border: 1px solid var(--line-2);
  border-radius: var(--radius-sm);
  background: var(--paper);
  color: var(--ink);
  font-weight: 400;
}
.waiting-actions { display: grid; grid-template-columns: 1fr 1fr; gap: 0.6rem; }
.waiting-outcome { margin: 0; font-weight: 600; color: var(--accent-ink); }
/* Empty until there is something to say, and never display:none, so a live region is in the tree
   before its words arrive; empty, it is taken out of the row's flow and takes no space. */
.waiting-outcome:empty { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }
.waiting-outcome.is-warn { color: var(--warn); }
.waiting-row.is-approved { border-color: var(--accent); background: var(--accent-soft); }
.waiting-row.is-refused { border-color: var(--stop); background: var(--stop-soft); }
.waiting-row.is-refused .waiting-outcome { color: var(--stop); }
.waiting-row.is-gone { border-color: var(--line-2); }

/* ---- the pairing view ------------------------------------------------------------------------ */

.pair {
  max-width: 48rem;
  min-height: 70vh;
  min-height: 70dvh;
  margin: 0 auto;
  display: grid;
  align-content: center;
  justify-items: center;
  text-align: center;
  gap: 1.1rem;
}
.pair-role {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  margin: 0;
  padding: 0.45rem 0.95rem;
  border: 1px solid var(--line-2);
  border-radius: 999px;
  color: var(--ink-2);
}
.pair-role-icon { display: inline-flex; color: var(--accent); }
.pair-role strong { color: var(--ink); }
.pair h1 { font-size: clamp(1.9rem, 4vw, 2.6rem); }

.code {
  display: flex;
  justify-content: center;
  gap: clamp(0.5rem, 2vw, 0.9rem);
  margin: 0.6rem 0 0.3rem;
  min-height: clamp(6.5rem, 16vw, 9rem);
  align-items: center;
}
.digit {
  display: grid;
  place-items: center;
  width: clamp(4.6rem, 14vw, 6.6rem);
  height: clamp(6.5rem, 18vw, 9rem);
  background: var(--panel);
  border: 1px solid var(--line-2);
  border-bottom: 3px solid var(--accent);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  font-size: clamp(3.75rem, 11vw, 5.75rem);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  line-height: 1;
  color: var(--ink);
}
.code.is-spent .digit { color: var(--muted); border-bottom-color: var(--line-2); text-decoration: line-through; text-decoration-thickness: 3px; }
.code-wait { color: var(--muted); font-size: 1.15rem; }

.pair-how { margin: 0; max-width: 36rem; color: var(--ink-2); font-size: 1.08rem; }
.pair-how strong { color: var(--ink); }

.pair-status {
  display: inline-flex;
  align-items: center;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.55rem;
  margin: 0.25rem 0 0;
  padding: 0.55rem 1rem;
  border-radius: 999px;
  border: 1px solid var(--line-2);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.pair-status:empty { display: none; }
.pair-status .sep { width: 1px; height: 1.1em; background: var(--line-2); }
.pair-status.is-waiting { border-color: var(--warn); color: var(--warn); }
.pair-status.is-waiting .dot { background: var(--warn); animation: pulse 1.6s ease-in-out infinite; }
.pair-status.is-warn { border-color: var(--warn); color: var(--warn); background: var(--warn-soft); }
/* A warning can run to two lines: a box rather than a pill, the dot beside the words. */
.pair-status.is-warn { max-width: 36rem; flex-wrap: nowrap; text-align: left; border-radius: var(--radius); }
.pair-status.is-warn .dot { background: var(--warn); }
.pair-status.is-stop { border-color: var(--stop); color: var(--stop); background: var(--stop-soft); }
.pair-status.is-stop .dot { background: var(--stop); }
@keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.25; } }
@media (prefers-reduced-motion: reduce) { .pair-status.is-waiting .dot { animation: none; } }

.pair-actions { display: flex; flex-wrap: wrap; justify-content: center; gap: 0.75rem; margin-top: 0.5rem; }

/* ---- the instructor code --------------------------------------------------------------------- */

/* One box for six digits on the device's own number keypad, hidden as dots until the eye beside it
   shows them, with Open beside the two on a wide screen and under them on a narrow one. The dots are
   `-webkit-text-security` on a text box, so no browser offers to save the code as a password; Safari
   and Chrome draw it. A browser that does not (Firefox) shows the digits, and the eye, which would
   toggle nothing there, is hidden. The digits stay readable to accessibility software while they are
   dots, declared in the README. */
.entry-form {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: stretch;
  gap: 0.75rem;
  width: 100%;
  margin: 0.4rem 0 0;
}
.entry-box {
  display: flex;
  gap: 0.5rem;
  width: min(100%, 25rem);
}
.entry-code {
  flex: 1 1 auto;
  min-width: 0;
  width: 100%;
  min-height: calc(var(--touch) + 1.5rem);
  padding: 0 1rem;
  background: var(--panel);
  color: var(--ink);
  border: 1px solid var(--line-2);
  border-bottom: 3px solid var(--accent);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  font-family: var(--font-ui);
  font-size: clamp(2.2rem, 7vw, 3rem);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.35em;
  text-align: center;
  text-indent: 0.35em;
  -webkit-text-security: disc;
}
.entry-code.is-shown { -webkit-text-security: none; }
.entry-show {
  flex: 0 0 auto;
  width: calc(var(--touch) + 1.5rem);
  min-width: var(--touch);
  min-height: calc(var(--touch) + 1.5rem);
  padding: 0;
  display: grid;
  place-items: center;
}
.entry-show[aria-pressed="true"] { border-color: var(--accent); color: var(--accent-ink); background: var(--accent-soft); }
@supports not (-webkit-text-security: disc) {
  .entry-show { display: none; }
}
.entry-code:focus-visible { outline: 3px solid var(--accent); outline-offset: 3px; }
.entry-form button[type="submit"] { min-height: calc(var(--touch) + 1.5rem); min-width: 14rem; font-size: 1.1rem; }

/* ---- opening a screen ------------------------------------------------------------------------ */

.opening {
  min-height: 55vh;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  gap: 1rem;
  text-align: center;
}
.opening-icon { width: 5rem; height: 5rem; border-color: var(--accent); }
.opening-name { margin: 0; font-family: var(--font-display); font-size: clamp(1.8rem, 3.6vw, 2.4rem); }
.opening-link { margin: 0; }
.opening-link a { display: inline-flex; align-items: center; min-height: var(--touch); padding: 0 0.5rem; }
