/* console.css — the owner console's shell, on top of knocklet.css.
   Every colour here comes through a custom property from that file, so the console inherits the
   iOS colorsets by reference and there is not one pigment value to keep in step. A hex in this
   file is a colour that escaped the pin in test/design-tokens.test.js, which scans it.

   The console is not `.page`. That class is the presser button's layout and carries eleven
   data-state rules; borrowing it here would mean fighting them. What is borrowed is the
   vocabulary — .field, .btn-primary, .btn-quiet, .join-code, .room-swatch, .hint, .eyebrow,
   .wordmark, .guard — so the two surfaces are visibly one product. */

:root {
  /* Wider than --column (26rem): the presser page is one button and a sentence, a console row is
     a label, a code, a state and two controls. */
  --console-column: 40rem;
  --rail: 18rem;
}

/* knocklet.css centres the presser card in the viewport from 48rem up. The console is a shell
   with a bar above it, not a card, so the grid and its centring are undone here rather than
   guarded there — that file belongs to the button page. */
body {
  display: flex;
  flex-direction: column;
  place-items: stretch;
  min-block-size: 100svh;
  padding: 0;
}

/* ── The bar, and the rail it becomes ───────────────────────────────────── */

.topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-3);
  padding: var(--sp-3) var(--gutter);
  background: var(--surface);
  border-block-end: var(--hair) solid var(--line);
}
.wordmark--bar { font-size: var(--t-title3); text-align: start; }

.nav { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-4); }
.nav__item {
  font: 500 var(--t-subheadline) var(--face-display);
  color: var(--ink);
  text-decoration: none;
}
.nav__item:hover { text-decoration: underline; }
.nav__item:focus-visible { outline: 2px solid var(--control-accent); outline-offset: 3px; }

/* ── The column ─────────────────────────────────────────────────────────── */

.console {
  box-sizing: border-box;
  flex: 1 1 auto;
  inline-size: 100%;
  max-inline-size: var(--console-column);
  margin-inline: auto;
  padding: var(--sp-5) var(--gutter) calc(var(--sp-6) + env(safe-area-inset-bottom));
  display: flex;
  flex-direction: column;
  gap: var(--flow);
}
/* Focus is moved here by nothing; the attribute exists so a skip target is available. */
.console:focus { outline: none; }

/* Two mechanisms decide what is on screen, and the panels are the first: data-view says which
   one this route allows. The `hidden` attribute is the second and says what the data carried —
   knocklet.css marks it !important, so it always wins over the reveal below. Neither mechanism
   names the sentence at the foot of the page, which is why nothing can take it off the screen. */
[data-panel] { display: none; }
.console[data-view="signin"] [data-panel="signin"],
.console[data-view="rooms"]  [data-panel="rooms"],
.console[data-view="room"]   [data-panel="room"],
.console[data-view="edit"]   [data-panel="edit"],
.console[data-view="admin"]  [data-panel="admin"] {
  display: flex;
  flex-direction: column;
  gap: var(--flow);
}

.block { display: flex; flex-direction: column; gap: var(--sp-2); }

form { display: flex; flex-direction: column; gap: var(--sp-3); }
form .btn-primary { align-self: center; margin-block-start: var(--sp-2); }
form .btn-quiet { align-self: center; }

a.btn-primary, a.btn-quiet {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  text-decoration: none;
}
/* Small only in type and padding. The 44px target stays, because a row of these is exactly where
   a thumb lands. */
.btn-primary--small, .btn-quiet--small { padding: 8px 16px; font-size: var(--t-subheadline); }
.btn-primary--wide { align-self: center; }
.back { align-self: flex-start; }

.hint:empty, .notice:empty { display: none; }
.notice { margin: 0; font: var(--t-subheadline)/1.45 var(--face-body); color: var(--muted); }
/* A sentence the owner has to act on. Palette.emphasisRule is the one thing in this product that
   means "notice this"; there is no warning colour, here or anywhere. */
.hint--trouble {
  padding-inline-start: var(--sp-3);
  border-inline-start: 2px solid var(--emphasis-rule);
  color: var(--ink);
}

/* The sentence the whole product is bounded by, held at the floor of the column. Below the fold
   on a long list is allowed; off the page is not. */
.console > .guard { margin-block-start: auto; padding-block-start: var(--sp-6); }

/* ── Room cards ─────────────────────────────────────────────────────────── */

.cards { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--sp-3); }
.card {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-2) var(--sp-4);
  padding: var(--sp-4);
  background: var(--surface);
  border: var(--hair) solid var(--line);
  border-radius: var(--r-card);
}
.card__link {
  flex: 1 1 12rem;
  min-inline-size: 0;
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  color: var(--ink);
  text-decoration: none;
}
.card__link:focus-visible { outline: 2px solid var(--control-accent); outline-offset: 3px; }
.card__label { font: 600 var(--t-title3)/1.25 var(--face-display); overflow-wrap: anywhere; }
.card__status { flex-basis: 100%; font: var(--t-subheadline)/1.4 var(--face-body); color: var(--muted); }

/* Someone or no one, never a number. A count would turn a door into a queue, and the owner would
   start reading it as one. */
.flag { display: inline-flex; align-items: center; gap: var(--sp-2);
        font: 600 var(--t-footnote) var(--face-display); color: var(--waiting-ink); }
.flag--quiet { font-weight: 500; color: var(--muted); }
.dot { inline-size: .5rem; block-size: .5rem; border-radius: var(--r-pill); background: var(--muted); }
.dot--waiting { background: var(--waiting); }

/* ── The live room ──────────────────────────────────────────────────────── */

.room-head { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-3); }
.room-head .hero-title { flex: 1 1 10rem; }
.room-head .hint { flex-basis: 100%; margin: 0; }

.toggle {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  min-block-size: 44px;
  font: 500 var(--t-subheadline) var(--face-display);
  color: var(--ink);
  cursor: pointer;
}
.toggle input { inline-size: 1.25rem; block-size: 1.25rem; accent-color: var(--slate); }

.rows { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; }
.row {
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
  padding-block: var(--sp-3);
  border-block-start: var(--hair) solid var(--line);
}
.row__head { display: flex; align-items: baseline; justify-content: space-between; gap: var(--sp-3); }
/* The two accents the product has, one meaning each, and both of them are the text-legible ink
   rather than the graphic tone. */
.word { font: 600 var(--t-headline) var(--face-display); }
.word--waiting { color: var(--waiting-ink); }
.word--acknowledged { color: var(--acknowledged-ink); }
.row__elapsed { font-size: var(--t-subheadline); color: var(--muted); }
.row__meta { font: var(--t-subheadline)/1.4 var(--face-body); color: var(--muted); }
.row__note { font: var(--t-subheadline)/1.45 var(--face-body); color: var(--ink); overflow-wrap: anywhere; }
/* Used on a <span> in a row and on a <p> in the share block, so the paragraph's own margin comes
   off here rather than at one of the call sites. */
.row__actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2); margin: 0; }
.row__ask { font: 500 var(--t-subheadline) var(--face-display); color: var(--ink); }

.row--log { flex-direction: row; align-items: baseline; gap: var(--sp-3); }
.row__when { flex: 0 0 auto; font: var(--t-footnote) var(--face-ticker); color: var(--muted); }
.row__log { font: var(--t-subheadline)/1.4 var(--face-body); color: var(--ink); overflow-wrap: anywhere; }
.row__who { font: 600 var(--t-headline) var(--face-display); color: var(--ink); overflow-wrap: anywhere; }
/* A press that is over is history rather than a state, so it wears neither accent. */
.word--closed { color: var(--muted); }

/* ── The share block ────────────────────────────────────────────────────── */

/* The link is read off the screen and typed into a phone as often as it is copied, so it is
   type first: monospace, wrapping at any character, no ellipsis. */
.share-link {
  margin: 0;
  font: 500 var(--t-callout) var(--face-ticker);
  color: var(--ink);
  overflow-wrap: anywhere;
}

/* Big enough to read across a desk, because somebody is going to. */
.share-code { margin: 0; font-size: var(--t-title3); color: var(--ink); }

.qr-pair { display: flex; flex-wrap: wrap; gap: var(--sp-5); }
.share-qr { flex: 1 1 10rem; margin: 0; }
/* The symbol is drawn on a white ground by lib/qr/svg.js and stays on one in dark mode: a QR
   with an inverted quiet zone is a QR a camera will not read. */
.share-qr img {
  display: block;
  inline-size: min(100%, 11rem);
  block-size: auto;
  border-radius: var(--r-field);
}
.share-qr figcaption {
  margin-block-start: var(--sp-2);
  font: var(--t-footnote)/1.4 var(--face-body);
  color: var(--muted);
  max-inline-size: 22ch;
}

/* ── The form ───────────────────────────────────────────────────────────── */

fieldset { margin: 0; padding: 0; border: 0; min-inline-size: 0; }
legend { padding: 0; }
.pair { display: flex; flex-wrap: wrap; gap: var(--sp-3); }
.pair__half { flex: 1 1 12rem; display: flex; flex-direction: column; gap: var(--sp-2); }

.swatches { display: flex; flex-wrap: wrap; gap: var(--sp-3); }
/* A real radio, kept in the focus order and hidden behind the dot it controls: the label is the
   target, the check state is the browser's, and :has does the styling. */
.swatch {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--sp-1);
  min-inline-size: 3.5rem;
  min-block-size: 44px;
  padding: var(--sp-2);
  border: var(--hair) solid transparent;
  border-radius: var(--r-field);
  cursor: pointer;
}
.swatch input { position: absolute; inset-block-start: 0; inset-inline-start: 0; inline-size: 1px; block-size: 1px; opacity: 0; }
.swatch__dot { inline-size: 1.75rem; block-size: 1.75rem; border-radius: var(--r-pill); background: var(--room); }
.swatch__name { font: 500 var(--t-caption) var(--face-body); color: var(--muted); }
.swatch:has(input:checked) { border-color: var(--control-accent); }
.swatch:has(input:checked) .swatch__name { color: var(--ink); }
.swatch:has(input:focus-visible) { outline: 2px solid var(--control-accent); outline-offset: 2px; }

.swatch-block .hint { margin: 0; }
/* A number that is a setting rather than a sentence: the column is as wide as the figure needs. */
input[type="number"] { max-inline-size: 9rem; }
input[type="datetime-local"] { inline-size: 100%; }

/* ── The rail ───────────────────────────────────────────────────────────── */

/* The iPad sidebar, spelled in CSS: the bar unrolls into a column beside the content instead of
   sitting over it. One breakpoint, because there are only two shapes this console has. */
@media (min-width: 60rem) {
  body { display: grid; grid-template-columns: var(--rail) minmax(0, 1fr); }
  .topbar {
    flex-direction: column;
    align-items: flex-start;
    justify-content: flex-start;
    gap: var(--sp-5);
    padding: var(--sp-6) var(--sp-5);
    border-block-end: 0;
    border-inline-end: var(--hair) solid var(--line);
  }
  .nav { flex-direction: column; align-items: flex-start; gap: var(--sp-4); }
  .console { padding-block-start: var(--sp-7); }
}

@media (forced-colors: active) {
  .dot { forced-color-adjust: none; background: CanvasText; }
  .card { border-color: CanvasText; }
}
