/* demo.css — the two-up demonstration, on top of knocklet.css, presser.css and console.css.
   Layout only. Every screen element on this page belongs to one of those two stylesheets and is
   drawn by their rules; what is here is the frame around them — the column, the two sides, and
   the handful of declarations that undo a rule written for a document that is the whole window.

   Both product stylesheets are written as if their screen were the page: presser.css sizes its
   column to the viewport, console.css makes the body a shell. Neither is true here, so the two
   blocks marked "undone" below are the price of drawing the real thing rather than a copy of it.
   Nothing else in this file may reach into either screen. */

/* console.css's body is the console's shell: a column of bar, strip, screen and foot that becomes
   a two-track grid at 60rem, with the bar as a rail down the side. This document has no bar and no
   rail, so the shell is restated here rather than inherited — display included, because the grid
   is set inside a media query and a rule that only renamed the alignment would leave the two
   frames sharing one 15rem track. Last stylesheet in, so this wins on order at equal weight. */
body { display: flex; flex-direction: column; align-items: center; }

.sides {
  box-sizing: border-box;
  flex: 1 1 auto;
  inline-size: 100%;
  max-inline-size: 74rem;
  margin-inline: auto;
  padding: var(--sp-6) var(--gutter) calc(var(--sp-7) + env(safe-area-inset-bottom));
  display: flex;
  flex-direction: column;
  gap: var(--sp-5);
}
.sides:focus { outline: none; }

.sides__head { display: flex; flex-direction: column; align-items: center; gap: var(--sp-2);
               text-align: center; }
.sides__head .hint { margin: 0; max-inline-size: 52ch; }

/* The way between the two frames, and the way back to the start. Both on one row, because they
   are the only two controls on the page that are not part of a screen. */
.sides__bar {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: center;
  gap: var(--sp-3);
}

.sides__pair { display: grid; gap: var(--sp-6); align-items: start; }

/* A frame, and a caption saying whose screen it is: without them the two halves read as one page
   with a doubled state. The caption is the landing's, in the same size and tracking, so a reader
   arriving from there recognises the pair. */
.side { display: flex; flex-direction: column; gap: var(--sp-3); min-inline-size: 0; }
.side__cap {
  margin: 0;
  font: 500 var(--t-caption)/1.3 var(--face); letter-spacing: .08em; text-transform: uppercase;
  color: var(--ink3);
}

/* ── Undone: the presser column ─────────────────────────────────────────── */

/* .page is written to be the document — a window's height with a spacer holding its floor, and a
   card only once the window is wide. In a frame it is neither, so the height claim comes off and
   the card comes on at every width. */
.side--visitor .page {
  min-height: 0;
  max-width: none;
  padding-block: var(--sp-7);
  background: var(--surface);
  border: var(--hair) solid var(--line);
  border-radius: var(--r-card);
}

/* ── Undone: the console shell ──────────────────────────────────────────── */

/* The console's Now tab and its trail, with no bar, no rail and no tabs above them. The panel is
   the same card the presser column is in, so the two frames weigh the same. */
.owner {
  box-sizing: border-box;
  display: flex; flex-direction: column; gap: var(--sp-5);
}
.deck {
  box-sizing: border-box;
  display: flex; flex-direction: column; gap: var(--sp-4);
  padding: var(--sp-5);
  background: var(--surface);
  border: var(--hair) solid var(--line);
  border-radius: var(--r-card);
}
/* The room's title is a screen title on a console 90rem wide; in a frame half that, it is a
   heading over a card. */
.deck .screen-title { font-size: var(--t-title2); }
/* The first press has the tab's own rule above it, which in the console separates it from the
   tab strip. There is no strip here. */
.deck .presses .press:first-child, .deck .idle { border-block-start: 0; }
.deck .idle { padding-block: 0; }
.deck .idle__head { font-size: var(--t-title3); }

.trail { gap: var(--sp-3); }

/* ── The push ───────────────────────────────────────────────────────────── */

/* The lock screen the press lands on, at the width the landing draws it. Centred over the card
   rather than inside it: it arrives before the console is opened, which is the order the loop
   actually happens in. */
.lock { inline-size: 18rem; max-inline-size: 100%; align-self: center; }

/* ── Somebody is waiting ────────────────────────────────────────────────── */

/* The room's dot takes the waiting accent while a press is open, which is the console's own
   vocabulary (.dot--waiting) applied from the state rather than from a class the page swaps. */
.owner[data-state="waiting"] .room-dot { background: var(--accent); }
.owner[data-state="acked"]   .room-dot { background: var(--ack); }

/* The pulse the switch turns off. Opacity only, on a mark 10px across, at the ripple's own tempo:
   a page that blinks is an alerting device, and this is a dot breathing under a sentence that
   already says the same thing in words. Off entirely where the reader's machine has asked for
   less motion — the switch is a preference, that is a requirement. */
@media (prefers-reduced-motion: no-preference) {
  .owner[data-pulse="on"][data-state="waiting"] .room-dot { animation: waiting-pulse 2.5s ease-in-out infinite; }
}
@keyframes waiting-pulse {
  0%, 100% { opacity: 1; }
  50%      { opacity: .35; }
}

/* ── The two widths ─────────────────────────────────────────────────────── */

/* One frame at a time on a phone, and the pills choose which. Both sides stay in the document —
   the hidden one is display:none rather than removed — so the state a reader built on one side
   is still there when they come back to it. */
@media (max-width: 61.99rem) {
  .sides[data-show="visitor"] .side--owner { display: none; }
  .sides[data-show="owner"] .side--visitor { display: none; }
  /* One frame gets a column rather than the window: these are two hand-held screens, and a
     tablet's whole width spent on one of them makes the phone in the picture the size of the
     tablet. The cap is the presser page's own, which is where the number comes from. */
  .sides__pair { max-inline-size: 34rem; margin-inline: auto; inline-size: 100%; }
}

/* Both frames at once, which is when the loop is legible: the press on the left and the answer
   on the right, and the reader watching one land on the other. Nothing left to choose, so the
   pills go. */
@media (min-width: 62rem) {
  .sides__pair { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); column-gap: var(--sp-7); }
  .sides__bar .pills { display: none; }
  .sides__bar { justify-content: flex-end; }
}
