/* ═══════════════════════════════════════════════════════════════════════════
   about-demo.css — the replay of one real answer on /about (#demo, in #does).

   Loaded by about.html only, after style.css and site.css. Same rules as
   site.css: no colour, shadow or type size of its own, every gap from the --s*
   scale, no inline styles. The answer, the cards, the tabs, the Saved list, the
   format picker and the ELI5 panel are the app's own components (style.css
   classes: .synth, .cx, .qline, .card-*, .badge, .save, .rail-tabs, .rail-tab,
   .saved-item, .format-tabs, .format-preview, .eli5-panel, …). This file only
   seats them in the page's window frame (site.css .shot / .shotframe /
   .shotbar) and undoes the two site.css rules that would otherwise reach
   inside them (.site-page p, .site-page a).

   Two new things. The guide strip: the tour callout's palette and left accent
   rule (TUTORIAL_ARCHITECTURE_SPEC.md §8), as the frame's header instead of
   floating over a scrim. The box: a fixed height inside the frame, so the
   page scrolls around the demo and the demo's panes scroll inside it. Nothing
   here is sticky. Two tokens, --demo-box-h and --demo-box-h-stacked
   (style.css :root, UI_MAP.md §11).
   ═══════════════════════════════════════════════════════════════════════════ */

/* Two inks step down one notch inside the demo, so every small label clears
   4.5:1 on both grounds it sits on (--page and --apparatus). --ink-soft
   (#7E8996, 3.6:1 on white) takes --ink-mid's value; --blue (#377CC5, 4.3:1)
   takes --flow-b's, the existing navy-leaning blue that "elutes" already
   uses. Re-pointing the tokens here, rather than restyling each component,
   keeps every app class untouched and means no hue is added. */
.demo {
  --ink-soft: var(--ink-mid);
  --blue: var(--flow-b);
}

/* Below the three cards in #does: the heading and intro, the frame, the
   recorded-on line under it. The heading is the second of the section, so it
   opens one --s8 below the cards. */
.demo {
  margin-top: var(--s8);
  scroll-margin-top: var(--anchor-offset);
}

.demo .shot {
  margin-top: var(--s5);
  border-radius: var(--r);
  box-shadow: var(--e2);
}

/* The figure carries the frame's shadow, so the strip and the frame read as
   one window; the strip takes the frame's top corners. */
.demo .shotframe { box-shadow: none; }
.demo .demo-guide + .shotframe {
  border-top: none;
  border-top-left-radius: 0;
  border-top-right-radius: 0;
}

/* A [hidden] element must stay hidden even where a component sets display
   (the strip's link and buttons do, at (0,2,0)). */
.about-page .demo [hidden],
.demo-live[hidden] { display: none; }

.about-page .demo-intro { margin: 0; }

.about-page .demo-label {
  font-size: var(--t-small);
  color: var(--ink-mid);
  margin: var(--s3) 0 0;
}

/* ── No-JS line: inside the frame, under the dots, so the window is never an
   empty box ── */
.about-page .demo-nojs {
  font-size: var(--t-small);
  color: var(--ink-mid);
  max-width: none;
  margin: 0;
  padding: var(--s6) var(--s5);
  text-align: center;
}

/* ── Guide strip ──────────────────────────────────────────────────────────
   The frame's header: as wide as the frame, joined to its top edge, outside
   the scroll box. It is in the page's flow and not sticky, so it never floats
   over the answer or the rest of the page, and the box scrolling under it
   cannot move it. Two rows at every width: the step count with the buttons,
   then the instruction across the whole strip. */
.demo-guide {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: var(--s1) var(--s3);
  background: var(--navy-fill);
  color: var(--on-navy);
  border-left: var(--bw-accent) solid var(--pale);
  border-radius: var(--r) var(--r) 0 0;
  padding: var(--s2) var(--s4) var(--s3);
}

.demo-guide-body {
  grid-column: 1 / -1;
  min-width: 0;
}

.demo-guide-actions { grid-column: 2; }

.about-page .demo-guide p {
  margin: 0;
  max-width: none;
}

.demo-guide-step {
  font-family: var(--data);
  font-size: var(--t-micro);
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  color: var(--pale);
}

/* 20% over --t-small (13px -> 15.6px): the instruction is the one line of the
   strip a visitor has to read, the step count and buttons stay at their size. */
.about-page .demo-guide-text {
  font-size: calc(var(--t-small) * 1.2);
  color: var(--on-navy);
}

.demo-guide-actions {
  display: flex;
  gap: var(--s2);
  grid-row: 1;
}

/* Skipped: only Restart is left, on the right. The rest is hidden with
   visibility, not removed, so the strip keeps its height and skipping moves
   nothing below it. Done: the count goes the same way, and Open Elute takes
   Skip's place beside Restart. */
.demo-guide.is-skipped .demo-guide-step,
.demo-guide.is-skipped .demo-guide-body,
.demo-guide.is-skipped .demo-skip,
.demo-guide.is-done .demo-guide-step { visibility: hidden; }

.demo-guide-btn,
.about-page .demo-guide-open {
  min-height: var(--tap-min);
  padding: 0 var(--s3);
  border: var(--hair) solid var(--pale);
  border-radius: var(--r);
  background: none;
  color: var(--on-navy);
  font-family: var(--body);
  font-size: var(--t-small);
  cursor: pointer;
  transition: background var(--dur-fast), color var(--dur-fast);
}

.demo-guide-btn:hover { background: var(--pale-fill); color: var(--on-pale); }

/* The one link at the end: the closing band's inverted CTA, at strip size. */
.about-page .demo-guide-open {
  display: inline-flex;
  align-items: center;
  background: var(--page);
  color: var(--navy);
  font-weight: 600;
  text-decoration: none;
}

/* Compact on a phone: less padding, the same 44px buttons. At the larger
   instruction size every instruction but one wraps to two lines below 901px and
   the longest ("Explain like I'm 5 ...") to three on a phone, so room for that
   many lines is reserved: the strip, and the box under it, stay put from step
   to step. Three lines up to 540px (the longest needs them to ~470px in IBM
   Plex, with margin), two from there to 900px. */
@media (max-width: 900px) {
  .demo-guide { padding: var(--s2) var(--s3); column-gap: var(--s2); }
  .about-page .demo-guide-text { min-height: 2lh; }
  .demo-guide-btn,
  .about-page .demo-guide-open { padding: 0 var(--s2); }
}

@media (max-width: 540px) {
  .about-page .demo-guide-text { min-height: 3lh; }
}

/* ── The box: a fixed height inside the frame ─────────────────────────────
   The page scrolls normally around it. Below 901px the box is ONE scroll pane
   (the answer, then the rail under it), --demo-box-h-stacked tall. From 901px
   it is two, like the app: the answer and the rail each fill the box's height
   and scroll on their own, and the rail's tabs head their pane.
   overscroll-behavior is auto on every pane, never contain: a pane at its end
   hands the scroll on to the page, so no one on a phone is trapped in it.
   scroll-padding is the margin about-demo.js keeps clear when it brings a
   target into view inside a pane. */
.demo-box {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  align-content: start;
  height: var(--demo-box-h-stacked);
  overflow-y: auto;
  overscroll-behavior: auto;
  scroll-padding: var(--s4);
}

.demo-doc {
  min-width: 0;
  padding: var(--s5);
  background: var(--page);
}

/* The app clamps the query to two lines; here it is the page's only copy of the
   question, so it shows whole. */
.demo .qline-text {
  display: block;
  -webkit-line-clamp: unset;
  line-clamp: unset;
  overflow: visible;
}

.demo-eli5-row {
  display: flex;
  margin-top: var(--s5);
  padding-top: var(--s4);
  border-top: var(--hair) solid var(--rule);
}

/* The app's panel sits centred above a sticky composer and caps its body at
   40vh; here it follows the button in the page's flow, so neither applies. */
.demo .demo-eli5 {
  margin: var(--s3) 0 0;
}

.demo .eli5-body { max-height: none; overflow: visible; }

/* The rail: the instrument surface, as in the app. */
.demo-rail {
  min-width: 0;
  display: flex;
  flex-direction: column;
  background: var(--apparatus);
  border-top: var(--hair) solid var(--rule);
}

.demo-rail-body { padding: var(--s4); }

@media (min-width: 901px) {
  .demo-box {
    grid-template-columns: minmax(0, 1fr) var(--rail-w);
    grid-template-rows: minmax(0, 1fr);
    height: var(--demo-box-h);
    overflow: hidden;
  }

  .demo-doc,
  .demo-rail-scroll {
    min-height: 0;
    overflow-y: auto;
    overscroll-behavior: auto;
    scroll-padding: var(--s4);
  }

  .demo-rail {
    min-height: 0;
    border-top: none;
    border-left: var(--hair) solid var(--rule);
  }

  /* The tabs head the pane and stay put; only the list under them scrolls. */
  .demo-rail-scroll { flex: 1; }
}

/* ── Cards (app.js renderCard markup, under .demo-card rather than .card,
   which site.css already claims for the page's own card component) ── */
.demo-card {
  display: grid;
  grid-template-columns: var(--card-num-col) minmax(0, 1fr);
  gap: 0 var(--s2);
  background: var(--surface);
  border: var(--hair) solid var(--rule);
  border-radius: var(--r);
  box-shadow: var(--e1);
  padding: var(--s3);
  margin-bottom: var(--s2);
  transition: box-shadow var(--dur) var(--ease-out), border-color var(--dur);
}

.demo-card:last-child { margin-bottom: 0; }

/* app.js jumpToCard()'s flash, the same tokens as .card.flash. */
.demo-card.flash { border-color: var(--blue); box-shadow: var(--e3), var(--flash-ring); }

.demo-card.open .card-summary { -webkit-line-clamp: unset; line-clamp: unset; }

/* .site-page p (0,1,1) would give every card line the prose measure and margin. */
.about-page .demo-card p { max-width: none; margin: 0 0 var(--s1); }
.about-page .demo-card .card-meta,
.about-page .demo-card .card-summary,
.about-page .demo-card .card-nosum { margin: 0 0 var(--s2); }

/* .site-page a would turn every title blue; the app's title is navy. */
.demo .card-title a { color: inherit; }

/* ── Tabs, Saved list, picker ── */
.demo .rail-tabs { flex: none; }

.demo .rail-empty { padding-bottom: var(--s5); }

.demo-picker {
  margin: 0 0 var(--s4);
  padding: var(--s3) var(--s4) var(--s4);
  background: var(--surface);
  border: var(--hair) solid var(--rule);
  border-radius: var(--r);
  box-shadow: var(--e2);
}

.about-page .demo-picker-title {
  margin: 0;
  font-family: var(--display);
  font-size: var(--t-title);
  font-weight: 600;
  color: var(--navy);
}

/* A DOI URL is one unbreakable word; at 375px it would run out of the box. */
.about-page .format-preview p { max-width: none; overflow-wrap: anywhere; }

/* ── The current step's target ──
   The app's own "look here" idiom (.card.flash's --flash-ring), held instead of
   flashed, plus a hairline in the accent so it reads on white and on the tint.
   Static: nothing here moves, so there is nothing to settle for reduced motion. */
.demo .is-guided {
  outline: var(--hair) solid var(--blue);
  outline-offset: var(--hair);
  box-shadow: var(--flash-ring);
  border-radius: var(--r-sm);
}

.demo .cx.is-guided { background: var(--pale-fill); color: var(--navy); }

/* A hovered marker sits on --pale-fill, where the accent ink would fall under
   4.5:1; it takes navy there instead. */
.demo .cx:hover { color: var(--navy); }

/* ── Focus ──
   style.css's :focus-visible is a soft glow (box-shadow), which several of these
   components swallow with their own shadow — the specificity trap the design
   system warns about. An outline cannot collide with any box-shadow, so every
   control in the demo shows the same ring, guided or not. */
.demo :focus-visible {
  outline: var(--bar-w) solid var(--blue);
  outline-offset: var(--bar-w);
}

.demo-guide :focus-visible { outline-color: var(--pale); }

/* The tabs touch the top of the box from 901px, which clips anything drawn
   outside them; their ring is drawn inside instead. */
.demo .rail-tab:focus-visible { outline-offset: calc(var(--bar-w) * -1); }

/* style.css's reduced-motion block shortens every transition to .01ms, which
   still starts one (and runs it for a frame). The demo's transitions are all
   hover and state feedback, so here they simply do not exist: the state lands
   at once. !important because that blanket rule is !important itself. Nothing
   in the demo animates, so there is no end frame to pin. */
@media (prefers-reduced-motion: reduce) {
  .demo *,
  .demo *::before,
  .demo *::after { transition: none !important; }
}
