/* The way in as a book's front matter (the literary page, 2026-10-26; a wizard since 2026-10-10).
   On a wide screen it is the spread play becomes: the city's plate (#start) the left page, the
   wizard (one modal dialog, every step's logic its own) the right page, the gutter's soft shadow
   between them. Under 900px the spread folds: the plate a band on top, the dialog the page under
   it. The step's top holds still on every step (2026-10-18: centred, it moved 113-403px between
   steps on a phone): its content starts at the same height on every step, growing downward, and
   the page scrolls inside the dialog. Begin's labels share one size, and the waking line keeps its
   space from the start. */

/* The plate: the city filling the left page, in fog while the world wakes, clear once it is warm,
   fading into the sky at the gutter. #cobalt (index.html) maps the drawing's greys onto the
   world's blues. The gutter's left half lies over its edge; its right half is the dialog's. */
.way-in {
  position: relative; isolation: isolate; overflow: hidden; min-height: 100svh;
  background: var(--sky); color: var(--ink);
}
.way-in .plate { position: absolute; inset: 0 50% 0 0; pointer-events: none; transition: opacity 2.2s ease-out, filter 2.2s ease-out; }
.way-in .plate::after { content: ''; position: absolute; inset: 0; background: linear-gradient(90deg, transparent 70%, var(--sky)); }
.way-in[data-city="fog"] .plate { opacity: .3; filter: blur(2px); }
.way-in .plate img { display: block; width: 100%; height: 100%; object-fit: cover; object-position: 38% 100%; filter: url(#cobalt); }
.way-in::after {
  content: ''; position: absolute; top: 0; bottom: 0; right: 50%; width: 40px; pointer-events: none;
  background: linear-gradient(90deg, transparent, #0000002e 38px, #ffffff08);
}

/* The right page: the dialog on its own sky, no shadow, no corner, the backdrop clear. Back is an
   underlined link at its top left, in a row of its own height whether it shows or not, so nothing
   moves. Each step a column 70px in from the gutter, at most 560px wide, starting `--top` down:
   about where a centred Welcome sat (22% of the window, at most 240px), never so low that the
   Microphone Check answered (about 620px) would leave a laptop's window, never into Back's row. */
#wizard {
  --top: max(76px, min(22svh, 240px, 100svh - 620px));
  --in: 70px; --out: max(56px, calc(100% - var(--in) - 560px));
  position: fixed; inset: 0; width: 50%; max-width: none; height: 100svh; max-height: none;
  margin: 0 0 0 50%; padding: 0; border: 0; border-radius: 0; box-shadow: none;
  overflow: hidden auto; overscroll-behavior: contain; scrollbar-width: thin;
  background: linear-gradient(90deg, #ffffff08, #0000002e 2px, transparent 40px) left / 40px 100% no-repeat, var(--sky);
  color: var(--ink);
}
/* Its column direction holds while it is closed too: the crossing's fade draws it closed. */
#wizard { flex-direction: column; }
#wizard[open] { display: flex; }
#wizard::backdrop { background: transparent; }
.wizard-top { position: absolute; top: 24px; left: var(--in); right: 32px; display: flex; align-items: center; gap: 12px; min-height: 40px; }
.wizard-top .link { font-size: 15px; }
#wizard-resume { min-height: 40px; margin-left: auto; padding: 0 16px; font-size: 14px; }
#wizard .step { flex: 1 0 auto; display: flex; flex-direction: column; padding: var(--top) var(--out) 30px var(--in); }
#wizard h1, #wizard h2 { margin: 0 0 20px; font-weight: 400; font-style: italic; font-size: 30px; line-height: 1.15; letter-spacing: 0; text-wrap: balance; }
#wizard h1:focus, #wizard h2:focus { outline: none; }
#wizard .lede { margin: 0; font-size: 21px; line-height: 1.5; text-wrap: pretty; }
/* The buttons' row, under the step's words. Primaries are play.css's: filled in the ink with the
   sky's words, waiting an outline in the soft ink at the same size. */
#wizard .step-actions { display: flex; flex-wrap: wrap; gap: 12px; min-height: 68px; margin-top: 28px; }
/* The Microphone Check's row holds Try again alone, which comes with the refusal's own line: until
   then it takes no room, so Or type instead sits under the words. */
#step-ask .step-actions:not(:has(> :not([hidden]))) { min-height: 0; margin-top: 0; }
/* The steps' small lines share one small size, in the soft ink. */
#wizard .small { margin: 14px 0 0; font-size: 16px; line-height: 1.5; color: var(--soft); }
/* An error's sentence from the visit before, for a moment, under the title. */
#wizard .notice { margin: 0 0 18px; font-size: 17px; line-height: 1.45; font-style: italic; color: var(--you); }

/* The Welcome, the title page: *Vesper* large, a small ✦, the lede, Begin; the consent at the
   page's foot, like a book's imprint, and the world still waking (a cold first crossing waits
   about half a minute) under it, in space kept for it, so its showing moves nothing. */
#wizard #step-threshold h1 { margin: 0 0 6px; font-size: 64px; line-height: 1; letter-spacing: -.01em; }
#wizard .ornament { margin: 18px 0 22px; font-size: 13px; line-height: 1; color: var(--soft); }
#wizard #step-threshold .step-actions { margin-top: 30px; }
#wizard .consent { margin: auto 0 0; padding-top: 24px; font-size: 14px; line-height: 1.45; color: var(--soft); }
#wizard .waking { margin: 4px 0 0; font-size: 14px; line-height: 1.45; font-style: italic; color: var(--soft); visibility: hidden; }
#wizard .waking.shown { visibility: visible; }
/* Begin's headphones show only beside "Begin" (app.ts's `drawBegin`). */
#begin:not([data-label="begin"]) .phones { display: none; }

/* The trace (the wizard upgrade, 2026-10-11): one fine line across the page's text, in the soft
   ink on both checks (the literary page, 2026-10-26; wave.ts draws it at the device's pixels). */
#wizard .wave { display: block; flex-shrink: 0; width: 100%; height: 72px; margin: 18px 0 0; }
#step-ask .wave { height: 56px; }

/* The steps' text links (Skip audio; "Or type instead", "Type instead" after a refusal): italic,
   underlined, in the soft ink, under their buttons. */
#wizard .alt { align-self: flex-start; margin-top: 16px; font-size: 16px; font-style: italic; }

/* The Microphone Check (2026-10-18): the narrator's prompt as plain ink text, as it will read in
   the transcript; the soft line under it while it asks for the mic, the hint, text alone, taking
   its place at its size when it comes, so its showing moves nothing (app.ts hides the one as the
   other shows; on a phone both keep two lines' room). */
#wizard .quote { margin: 0; font-size: 21px; line-height: 1.5; color: var(--ink); }
#wizard :is(#ask-ask, #ask-hint) { margin: 8px 0 0; font-size: 15px; line-height: 1.5; color: var(--soft); }
/* The mic allowed, the soft line has nothing left to ask: unseen, its room kept for the hint. */
#wizard #ask-ask.granted { visibility: hidden; }
/* Refused, or with no key: its line under the prompt. */
#step-ask .lede { margin-top: 14px; }
/* What Vesper hears: the player's words as in play, italic gold, flush; before any, a quiet
   "Listening…" in their place, smaller, in a line of the words' height, so the first words move
   nothing. Before the mic opens (the narrator's prompt still playing), it keeps its room unseen. */
#wizard .heard { --heard: 21px; margin: 18px 0 0; font-size: var(--heard); line-height: 1.5; font-style: italic; color: var(--you); overflow-wrap: anywhere; }
#wizard .heard.waiting { color: var(--soft); font-size: 16px; line-height: calc(var(--heard) * 1.5); }
#wizard .heard.unopened { visibility: hidden; }
#step-ask .heard, #step-briefing .heard { margin-top: 14px; }
/* The acknowledgement, shown as it begins: the narrator's, plain ink. */
#wizard .reply { margin: 14px 0 0; font-size: 21px; line-height: 1.5; }
/* Recognition failing after the grant: a line, and Type instead beside it. */
#wizard .trouble { margin: 14px 0 0; font-size: 16px; line-height: 1.5; }
#wizard .trouble .link { margin-left: .4em; font-size: 16px; }
/* Typed: play's writing line, a faint rule over the box and Send, the line sent quoted under it
   (the markup's order). */
.ask-form { display: flex; align-items: center; gap: 14px; margin-top: 22px; padding-top: 10px; border-top: 1px solid var(--faint); }
.ask-form input { flex: 1; min-width: 0; min-height: 48px; padding: 0; border: 0; background: none; font-size: 19px; }
.ask-form input::placeholder { color: var(--soft); font-style: italic; opacity: 1; }
.ask-form input:focus-visible { outline: none; }
.ask-form input:disabled { opacity: .5; }
.ask-form button { min-height: 48px; padding: 0 4px; box-shadow: none; color: var(--you); font-size: 16px; }
.ask-form button:disabled { box-shadow: none; }

/* The Briefing, the preface: its label the heading, the story opening with a drop cap (the only
   one outside play), later paragraphs indented; Make the Crossing under it, held at the page's
   foot while a long story scrolls away under it. */
#briefing-body { font-size: 21px; line-height: 1.55; }
#briefing-body p { margin: 0 0 .7em; text-indent: 1.4em; text-wrap: pretty; }
#briefing-body > p:first-of-type { text-indent: 0; }
#briefing-body > p:first-of-type::first-letter { float: left; font-size: 3.2em; line-height: .86; padding: 6px 8px 0 0; }
#briefing-body > :last-child { margin-bottom: 0; }
/* The assignment's bold run is a line of its own, the paragraph's opening. */
#briefing-body .assignment strong { display: block; font-weight: 500; text-indent: 0; }
#briefing-body h3 { margin: 1em 0 .4em; font-weight: 400; font-style: italic; font-size: 22px; line-height: 1.3; }
/* A list of lines to say: a script's examples before its `---`: quoted, faint rules between,
   never buttons. */
#wizard .examples { list-style: none; margin: 0 0 .7em; padding: 0; border-top: 1px solid var(--faint); }
#wizard .examples li { padding: 10px 0; border-bottom: 1px solid var(--faint); line-height: 1.35; }
#wizard .examples li::before { content: '“'; }
#wizard .examples li::after { content: '”'; }
#step-briefing .acts { position: sticky; bottom: 0; margin-top: 4px; padding: 18px 0 0; background: linear-gradient(transparent, var(--sky) 18px); }
/* The Crossing by voice (2026-10-17): the narrator's ready line under the story, and what the mic
   heard under it, as on the Microphone Check. Without the mic, the line that says to press the
   button (2026-10-20). */
#wizard #cross-ready { margin-top: .7em; }
#wizard #cross-click { margin-top: .7em; }

/* The crossing (the literary page, 2026-10-26): the one orchestrated motion, on #play's
   `crossing` (page.ts's `show`, on the answer to this tab's own crossing alone: a reload into play
   shows it at once). As play shows, the dialog fades out (held in the top layer and drawn until its
   fade ends), the plate fades out over play, lifted above it, and play's two pages fade in, about
   1.2 s; page.ts hides #start once the fade has played. With motion reduced (play.css) there is no
   transition: all at once. */
#wizard:has(~ .play.crossing) { transition: opacity 1.2s var(--settle), overlay 1.2s allow-discrete, display 1.2s allow-discrete; }
#wizard:not([open]) { opacity: 0; pointer-events: none; }
.way-in:has(~ .play.crossing:not([hidden])) { z-index: 1; opacity: 0; pointer-events: none; transition: opacity 1.2s var(--settle); }
.play.crossing > .leaf { transition: opacity 1.2s var(--settle); }
@starting-style { .play.crossing > .leaf { opacity: 0; } }

/* The fold (under 900px: a phone, a tablet held upright): the plate a band on top (at most 250px),
   fading down into the sky; the dialog the page under it, the window's width, Back's row on top,
   the step's column at most 600px, centred. */
@media (max-width: 899px) {
  .way-in { --plate: min(30svh, 250px); }
  .way-in .plate { inset: 0 0 auto 0; height: var(--plate); }
  .way-in .plate::after { background: linear-gradient(180deg, transparent 55%, var(--sky)); }
  .way-in .plate img { object-position: 30% 100%; }
  .way-in::after { display: none; }
  #wizard {
    --plate: min(30svh, 250px); --in: max(20px, calc((100% - 600px) / 2)); --out: var(--in);
    width: 100%; height: calc(100svh - var(--plate)); margin: var(--plate) 0 0; background: var(--sky);
  }
  .wizard-top { position: static; flex: none; padding: 4px var(--in) 0; }
  #wizard .step { padding: 8px var(--out) 20px var(--in); }
}
/* A phone (680px and narrower): smaller type, body text 18px; the soft line and the hint each take
   two lines' room, so the hint (two lines here) moves nothing. */
@media (max-width: 680px) {
  #wizard #step-threshold h1 { font-size: 48px; }
  #wizard h1, #wizard h2 { font-size: 26px; margin-bottom: 16px; }
  #wizard :is(.lede, .quote, .heard, .reply), #briefing-body { font-size: 19px; }
  #wizard .heard { --heard: 19px; }
  #wizard :is(#ask-ask, #ask-hint) { min-height: 3em; }
  #wizard .ornament { margin: 14px 0 18px; }
  #wizard .step-actions > button { min-width: 0; flex: 1 1 auto; max-width: 340px; }
}
