/* styles.css — Page-turn technical spike (Phase 1, corrected)
   Uses the site's existing brand tokens (bronze/green/ink/cream, Cormorant
   Garamond + Inter). No new fonts, no framework, no build step.

   The book is one persistent object at a fixed footprint. Desktop shows it
   as two stationary pages either side of a center spine; only ONE half
   (or, for the cover, the whole book) ever animates — the rest of the
   object never moves. */

*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

:root {
  --bronze:      #B5864A;
  --bronze-dark: #8C6535;
  --green:       #253027;
  --ink:         #141612;
  --cream:       #EFE6D4;
  --text-dark:   #1A1F1C;
  --text-light:  #EAE1CE;
  --paper:       #FBF8F2;
  --font-logo:   'Cormorant Garamond', Georgia, serif;
  --font-ui:     'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
  --ease-expo:   cubic-bezier(0.16, 1, 0.3, 1);
  --spine-w:     14px;
}

html, body { height: 100%; }

body {
  background:
    radial-gradient(700px 500px at 85% -10%, rgba(181,134,74,0.12), transparent 70%),
    radial-gradient(600px 500px at 10% 110%, rgba(37,48,39,0.08), transparent 70%),
    var(--cream);
  color: var(--text-dark);
  font-family: var(--font-ui);
  line-height: 1.6;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 32px 16px 64px;
}

a { color: inherit; }
:focus-visible { outline: 3px solid var(--bronze); outline-offset: 2px; }

/* === Reader-facing progress bar — real production UI, always visible === */
.workbook-progress-bar {
  width: 100%;
  max-width: 960px;
  margin-bottom: 8px;
  font-size: 13px;
}
#progress-indicator { font-variant-numeric: tabular-nums; color: #666; }

/* === QA-only controls (Phase 6 correction): populated by app.js's
   isQaEnvironment() gate ONLY on localhost/127.0.0.1 or a Netlify
   deploy-preview host with ?qa=1 — never on tylerjlewis.com. The
   [hidden] override matters here for the same reason it did for
   .status-banner and .deep-fields elsewhere in this file: without it,
   this rule's own `display: flex` would outrank the browser's native
   [hidden] rule by source order and show an empty bar even when app.js
   never populates it. === */
.qa-bar[hidden] { display: none; }
.qa-bar {
  width: 100%;
  max-width: 960px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 10px;
  background: rgba(37,48,39,0.06);
  border: 1px solid rgba(37,48,39,0.12);
  border-radius: 10px;
  padding: 12px 16px;
  margin-bottom: 24px;
  font-size: 13px;
}
.qa-bar strong { color: var(--green); }
.qa-toggle-label { display: flex; align-items: center; gap: 8px; cursor: pointer; }
.toggle-state { color: #666; }

/* === Book stage === */
.book-outer {
  position: relative; /* shared anchor for #book and the three leaf siblings */
  width: 100%;
  max-width: 920px;
  perspective: 2400px;
}

/* Phase 3: real manuscript content varies hugely in length page to page.
   #book's height is measured and applied explicitly in JS (app.js:
   syncBookHeight) from the tallest of the two absolutely-positioned
   halves' natural content height, since absolutely-positioned children
   can't auto-size their container. min-height is only the pre-JS/no-JS
   fallback. */
.book {
  position: relative;
  width: 100%;
  min-height: 420px;
  border-radius: 16px;
  box-shadow: 0 2px 4px rgba(20,22,18,0.04), 0 30px 70px rgba(37,48,39,0.16);
}

.single-page-wrap { max-width: 560px; margin: 0 auto; }

/* === Stationary halves (desktop spread) === */
.book-half {
  position: absolute;
  top: 0;
  min-height: 100%;
  width: calc(50% - (var(--spine-w) / 2));
  background: var(--paper);
  overflow: hidden;
}
.book-half--left { left: 0; border-radius: 16px 0 0 16px; }
.book-half--right { right: 0; border-radius: 0 16px 16px 0; }
.book-half--left .page { border-right: 1px solid rgba(37,48,39,0.08); }

.book-spine-line {
  position: absolute;
  top: 0;
  left: calc(50% - (var(--spine-w) / 2));
  width: var(--spine-w);
  height: 100%;
  background: linear-gradient(90deg, rgba(37,48,39,0.06), rgba(37,48,39,0.16), rgba(37,48,39,0.06));
  pointer-events: none;
}

/* === Solo pages (cover + end) — same footprint as the open spread, so
   opening the cover reads as the same object, not a smaller floating
   card. === */
.book-solo {
  position: absolute;
  top: 0; left: 0; right: 0;
  min-height: 100%;
  border-radius: 16px;
  background: var(--paper);
  overflow: hidden;
}
.book-solo--cover { background: var(--ink); }

/* === Shared page contents === */
.page {
  /* Deliberately NOT a percentage of its (absolutely-positioned, possibly
     stale-height) ancestor: app.js measures this element's own natural
     offsetHeight directly to size #book, and a percentage height here
     would make that measurement circular. */
  min-height: 420px;
  padding: 40px 36px;
  display: flex;
  flex-direction: column;
  gap: 14px;
  position: relative;
}
.single-page-wrap .page,
.book-solo .page {
  box-shadow: 0 1px 2px rgba(20,22,18,0.05), 0 20px 44px rgba(37,48,39,0.14);
  border: 1px solid rgba(37,48,39,0.1);
  border-radius: 16px;
  min-height: 440px;
}
.single-page-wrap .page { background: var(--paper); }
/* On mobile, the cover is rendered inside .single-page-wrap (there's no
   separate .book-solo--cover wrapper to carry the dark background there),
   so without this override the cover's light, dark-background-only text
   colors would land on the default light paper background — a real
   contrast failure, not just a visual mismatch. */
.single-page-wrap .page--cover { background: var(--ink); border-color: rgba(234,225,206,0.12); }

.page-tab {
  position: absolute; top: 20px; right: 20px;
  font-size: 10px; font-weight: 700; letter-spacing: 1.5px; color: var(--bronze-dark);
  background: rgba(181,134,74,0.1); border-radius: 999px; padding: 4px 10px;
}
.page-eyebrow { font-size: 11px; font-weight: 700; letter-spacing: 2px; text-transform: uppercase; color: var(--bronze-dark); }
.page-title { font-family: var(--font-logo); font-size: 34px; font-weight: 600; color: var(--text-light); }
.page-subtitle { font-size: 15px; color: rgba(234,225,206,0.75); }
.page-headline { font-family: var(--font-ui); font-size: 22px; font-weight: 700; line-height: 1.3; color: var(--text-dark); }
.page--cover .page-headline, .page--cover .page-title { color: var(--text-light); }
.page-instruction { font-size: 14px; color: #555; }
.page-body p { font-size: 15px; color: #444; line-height: 1.75; margin-bottom: 10px; }
.page-callout {
  font-size: 14px; font-style: italic; color: var(--bronze-dark);
  border-left: 3px solid var(--bronze); padding-left: 14px; margin-top: auto;
}

.field-label { font-size: 12px; font-weight: 600; color: var(--text-dark); margin-top: 6px; }
.field-input {
  width: 100%; min-height: 100px;
  border: 1.5px solid rgba(37,48,39,0.16); border-radius: 10px;
  padding: 12px 14px; font-family: var(--font-ui); font-size: 15px; background: #fff;
}
.field-input:focus { border-color: var(--bronze); }
/* Auto-growing textareas (app.js: autoGrowTextarea) size themselves to
   their content on every keystroke, on load, and on breakpoint/width
   change — resize:none and overflow:hidden keep the browser's own resize
   handle and internal scrollbar from fighting that, which would otherwise
   produce exactly the nested, unusable scroll area the PRD prohibits. */
textarea.field-input { resize: none; overflow: hidden; }
.field-required { color: var(--bronze-dark); }
.field-error {
  font-size: 12.5px; color: #8a3b1f; min-height: 0; margin-top: 2px;
}
.field-error:empty { display: none; }
[aria-invalid="true"] { border-color: #b1502b; }
.save-indicator { font-size: 12px; color: var(--bronze-dark); min-height: 16px; }

.page-nav-row { display: flex; justify-content: space-between; gap: 12px; margin-top: auto; padding-top: 12px; }

/* === Buttons === */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  font-family: var(--font-ui); font-weight: 600; font-size: 14px;
  border: none; border-radius: 10px; padding: 13px 26px; cursor: pointer; min-height: 44px;
  transition: transform 0.3s var(--ease-expo), box-shadow 0.3s var(--ease-expo), background 0.2s ease;
}
.btn:hover { transform: translateY(-2px); }
.btn-primary { background: var(--bronze); color: #fff; box-shadow: 0 10px 24px rgba(181,134,74,0.3); }
.btn-primary:hover { background: var(--bronze-dark); }
.btn-outline { background: transparent; border: 1.5px solid rgba(37,48,39,0.22); color: var(--text-dark); }
.btn-outline:hover { border-color: var(--green); }
.btn-text { background: none; border: none; color: var(--bronze-dark); text-decoration: underline; text-underline-offset: 3px; font-size: 13px; }

/* === Leaves: the ONLY things that ever animate. Each is sized and hinged
   to match exactly one physical part of the stationary book. === */
.leaf {
  display: none;
  position: absolute;
  top: 0;
  height: 100%;
  z-index: 5;
  transform-style: preserve-3d;
  pointer-events: none;
}
.leaf-face { position: absolute; inset: 0; backface-visibility: hidden; overflow: hidden; }
.leaf-front { background: var(--paper); }
/* rotateY(180deg) here is what makes the back face read correctly once the
   leaf has turned: it's the actual reverse side of the same physical page,
   not a separate rotated copy, so its content must be pre-mirrored to
   appear right-reading once the leaf settles. */
.leaf-back { background: var(--paper); transform: rotateY(180deg); box-shadow: inset 0 0 60px rgba(37,48,39,0.08); }
.leaf-front .page, .leaf-back .page { height: 100%; }

/* Cover backside — a deliberate content surface, not blank paper. Distinct
   from the ordinary page treatment so it visibly reads as "this is a real
   surface with something on it," ready for the approved Inside Cover
   manuscript content later. */
.page--inside-cover {
  background: var(--paper);
  border: 1.5px dashed rgba(181,134,74,0.4);
  align-items: flex-start;
  justify-content: center;
}
.page--inside-cover .page-eyebrow { color: var(--bronze-dark); }
.page--inside-cover .page-headline { font-family: var(--font-logo); font-size: 26px; }
.page--inside-cover .page-instruction { color: #666; max-width: 380px; }

/* Right-page leaf: same slot as .book-half--right, hinged at the spine
   (its own left edge). Forward turns only. */
.leaf--right {
  right: 0;
  width: calc(50% - (var(--spine-w) / 2));
  transform-origin: left center;
  border-radius: 0 16px 16px 0;
}
.leaf--right .leaf-face { border-radius: 0 16px 16px 0; }

/* Left-page leaf: same slot as .book-half--left, hinged at the spine
   (its own right edge). Backward turns only. */
.leaf--left {
  left: 0;
  width: calc(50% - (var(--spine-w) / 2));
  transform-origin: right center;
  border-radius: 16px 0 0 16px;
}
.leaf--left .leaf-face { border-radius: 16px 0 0 16px; }

/* Cover leaf: the full book footprint, hinged at the book's own left
   edge (the spine) — used only for the cover-opening moment. */
.leaf--cover {
  left: 0;
  width: 100%;
  transform-origin: left center;
  border-radius: 16px;
}
.leaf--cover .leaf-face { border-radius: 16px; }
.leaf--cover .leaf-front { background: var(--ink); }

.leaf--turning-fwd { transform: rotateY(-176deg); transition: transform 550ms var(--ease-expo); }
.leaf--turning-back { transform: rotateY(176deg); transition: transform 550ms var(--ease-expo); }

.leaf::after {
  content: ''; position: absolute; inset: 0; border-radius: inherit;
  background: linear-gradient(90deg, rgba(0,0,0,0.18), transparent 40%);
  opacity: 0; transition: opacity 550ms var(--ease-expo);
}
.leaf--turning-fwd::after, .leaf--turning-back::after { opacity: 1; }

/* === Accessibility: reduced motion === */
@media (prefers-reduced-motion: reduce) {
  .leaf--turning-fwd, .leaf--turning-back { transition-duration: 0.001ms !important; }
}

.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0;
}

/* === Reader-facing progress bar (renamed off "qa-" in the Phase 6
   correction — this is real production UI, always visible, not internal
   tooling; see .workbook-progress-bar above) === */
.progress-track { width: 100%; max-width: 960px; height: 4px; border-radius: 2px; background: rgba(37,48,39,0.1); margin-bottom: 20px; overflow: hidden; }
.progress-fill { height: 100%; background: linear-gradient(90deg, var(--bronze-dark), var(--bronze)); border-radius: 2px; width: 0%; transition: width 0.4s var(--ease-expo); }
@media (prefers-reduced-motion: reduce) { .progress-fill { transition: none; } }

/* === Cover === */
.page-cover-body { font-size: 15px; color: rgba(234,225,206,0.65); line-height: 1.7; max-width: 420px; }
.page-cover-meta { font-size: 12.5px; color: rgba(234,225,206,0.4); margin-top: auto; }
.page--cover .btn { align-self: flex-start; margin-top: 8px; }

/* === Text/paragraph content shared by left pages and others === */
.page-list { padding-left: 22px; }
.page-list li { font-size: 15px; color: #444; line-height: 1.7; margin-bottom: 8px; }
.page-list--bullet { list-style: none; padding-left: 0; }
.page-list--bullet li { position: relative; padding-left: 20px; }
.page-list--bullet li::before { content: ''; position: absolute; left: 0; top: 9px; width: 6px; height: 6px; border-radius: 50%; background: var(--bronze); }
.page-example-path li strong { color: var(--text-dark); }
.page-quote { font-size: 16px; font-style: italic; color: var(--text-dark); border-left: 3px solid rgba(181,134,74,0.4); padding-left: 16px; }
.page-formula { font-size: 15.5px; font-weight: 600; color: var(--bronze-dark); background: rgba(181,134,74,0.07); border-radius: 10px; padding: 14px 16px; }
.page-definition { font-size: 15px; color: var(--text-dark); background: var(--cream); border-radius: 10px; padding: 14px 16px; }
.page-model { font-size: 17px; font-weight: 700; color: var(--text-dark); text-align: center; padding: 8px 0; }
.page-guardrail, .page-supporting-note { font-size: 13.5px; color: #777; font-style: italic; }
.page-small-print { font-size: 12px; color: #888; margin-top: auto; }
.page-personal-invitation { font-size: 14.5px; color: #555; line-height: 1.7; font-style: italic; }

.control-distinction { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.control-col-label { font-size: 11px; font-weight: 700; letter-spacing: 0.5px; text-transform: uppercase; color: var(--bronze-dark); margin-bottom: 6px; }
.test-options p { font-size: 14.5px; color: #444; margin-bottom: 10px; }
.example-progression p { font-size: 14.5px; color: #444; margin-bottom: 8px; }
.example-progression-label { font-weight: 700; color: var(--text-dark); }

/* === Fields === */
.field-note { font-size: 12.5px; color: #888; margin-top: -4px; margin-bottom: 4px; }
.field-note--validation { text-align: center; color: #999; }
.field-starter { font-size: 12.5px; color: #999; margin-top: -4px; }
.field-input--text { min-height: 44px; }
.field-block { display: flex; flex-direction: column; gap: 4px; }

/* === Choice / agreement rows === */
.choice-group { display: flex; flex-direction: column; gap: 8px; }
.choice-row, .agreement-row {
  display: flex; align-items: center; gap: 12px;
  border: 1.5px solid rgba(37,48,39,0.14); border-radius: 10px; padding: 12px 14px; cursor: pointer;
  transition: border-color 0.15s ease, background 0.15s ease;
}
.choice-row:hover, .agreement-row:hover { border-color: rgba(181,134,74,0.4); }
.choice-row input, .agreement-row input { position: absolute; opacity: 0; width: 1px; height: 1px; }
.choice-visual { width: 18px; height: 18px; border-radius: 50%; border: 2px solid rgba(37,48,39,0.3); flex-shrink: 0; display: flex; align-items: center; justify-content: center; }
.choice-visual::after { content: ''; width: 9px; height: 9px; border-radius: 50%; background: var(--bronze); transform: scale(0); transition: transform 0.15s var(--ease-expo); }
.choice-visual--square { border-radius: 5px; }
.choice-visual--square::after { border-radius: 2px; width: 10px; height: 10px; }
.choice-row.selected, .agreement-row.selected { border-color: var(--bronze); background: rgba(181,134,74,0.06); }
.choice-row.selected .choice-visual, .agreement-row.selected .choice-visual { border-color: var(--bronze); }
.choice-row.selected .choice-visual::after, .agreement-row.selected .choice-visual::after { transform: scale(1); }
.choice-label, .agreement-label { font-size: 14.5px; color: var(--text-dark); }

/* === Deep prompts ("Help Me Think This Through") === */
.deep-prompts { border-top: 1px solid rgba(37,48,39,0.08); padding-top: 12px; margin-top: 4px; }
.deep-toggle {
  background: none; border: 1.5px dashed rgba(181,134,74,0.4); border-radius: 8px;
  color: var(--bronze-dark); font-weight: 600; font-size: 13px; padding: 9px 14px; cursor: pointer;
}
.deep-toggle:hover { border-color: var(--bronze); }
.deep-hint { font-size: 12px; color: #999; margin-top: 6px; }
.deep-fields[hidden] { display: none; }
.deep-fields { display: flex; flex-direction: column; gap: 14px; margin-top: 12px; padding-left: 14px; border-left: 2px solid rgba(181,134,74,0.15); }

/* === Example reveal === */
.example-box { margin-top: 4px; }
.example-toggle { background: none; border: none; color: var(--bronze-dark); font-weight: 600; font-size: 13px; text-decoration: underline; text-underline-offset: 3px; cursor: pointer; padding: 4px 0; }
.example-body { background: var(--cream); border-radius: 10px; padding: 14px 16px; margin-top: 8px; }
.example-body p { font-size: 14px; color: #444; line-height: 1.7; font-style: italic; }

.section-completion-line { font-size: 14.5px; color: var(--text-dark); background: rgba(181,134,74,0.08); border-radius: 10px; padding: 12px 14px; }

/* === Incomplete-page validation message === */
.incomplete-message { background: rgba(196,98,45,0.08); border: 1px solid rgba(196,98,45,0.25); border-radius: 10px; padding: 14px 16px; }
.incomplete-message p { font-size: 13.5px; color: #6b3a1f; margin-bottom: 10px; }
.incomplete-actions { display: flex; gap: 10px; flex-wrap: wrap; }

/* === Decision 6 stage repeater === */
.stage-repeater { display: flex; flex-direction: column; gap: 12px; }
.stage-block { border: 1.5px solid rgba(37,48,39,0.12); border-radius: 10px; padding: 14px; }
.stage-block-header { display: flex; align-items: center; gap: 10px; margin-bottom: 8px; }
.stage-number {
  width: 24px; height: 24px; border-radius: 50%; background: var(--bronze); color: #fff;
  font-size: 12px; font-weight: 700; display: flex; align-items: center; justify-content: center; flex-shrink: 0;
}
.stage-name-input { flex: 1; min-height: 40px; font-weight: 600; }
.stage-remove { flex-shrink: 0; font-size: 12px; }
.stage-sub-fields { display: flex; flex-direction: column; gap: 8px; margin-top: 8px; }
.stage-sub-fields .field-label { margin-top: 0; }
.stage-sub-field { min-height: 56px; font-size: 13.5px; }

/* === Offer Integrity scorer === */
.integrity-scorer { display: flex; flex-direction: column; gap: 16px; }
.integrity-row { border-bottom: 1px solid rgba(37,48,39,0.08); padding-bottom: 14px; }
.integrity-row-label { font-size: 13px; font-weight: 700; letter-spacing: 0.5px; text-transform: uppercase; color: var(--bronze-dark); }
.integrity-row-prompt { font-size: 14px; color: #444; margin: 4px 0 10px; }
.score-btn-row { display: flex; gap: 8px; }
.score-btn {
  flex: 1; border: 1.5px solid rgba(37,48,39,0.16); border-radius: 8px; background: #fff;
  padding: 10px 6px; cursor: pointer; font-weight: 700; font-size: 14px; color: var(--text-dark);
  display: flex; flex-direction: column; align-items: center; gap: 2px;
}
.score-btn-label { font-size: 9.5px; font-weight: 500; text-transform: none; letter-spacing: 0; color: #888; }
.score-btn:hover { border-color: rgba(181,134,74,0.5); }
.score-btn.selected { border-color: var(--bronze); background: rgba(181,134,74,0.1); color: var(--bronze-dark); }
.integrity-result { background: var(--cream); border-radius: 10px; padding: 16px; }
.integrity-total, .integrity-next-q { font-size: 14.5px; color: var(--text-dark); margin-bottom: 6px; }
.integrity-tie-note, .integrity-interp { font-size: 13px; color: #666; }

/* === Lead capture (PRD §21: first/last/email required, consent optional
   and unchecked by default, wide-screen name pairing / mobile stacking) === */
.lead-capture-box { display: flex; flex-direction: column; gap: 14px; background: var(--cream); border-radius: 12px; padding: 18px; }
.field-pair-row { display: flex; gap: 14px; }
.field-pair-row .field-block { flex: 1; min-width: 0; }
.agreement-row--consent { align-items: flex-start; }
.agreement-row--consent .choice-visual { margin-top: 2px; }
.page-small-print--transactional { color: #777; line-height: 1.6; }

/* === Offer Map (PRD §22: directly editable in place) === */
.page--map { gap: 10px; }
.map-meta { font-size: 13px; color: #888; }
.map-status { font-style: italic; }
.map-block { border-bottom: 1px solid rgba(37,48,39,0.08); padding-bottom: 10px; }
.map-block-label { font-size: 11px; font-weight: 700; letter-spacing: 1px; text-transform: uppercase; color: var(--bronze-dark); margin-bottom: 4px; }
.map-block-value { font-size: 14.5px; color: var(--text-dark); line-height: 1.6; white-space: pre-wrap; }
.map-block-value--empty { color: #aaa; font-style: italic; }
.map-hypothesis-note { font-size: 13px; color: #888; font-style: italic; }
.map-footer { font-size: 13px; color: #777; line-height: 1.6; margin-top: 8px; }
.map-brand-line { font-size: 11px; color: #aaa; letter-spacing: 0.3px; }
.map-edit-jump { margin-top: 4px; }
.map-block[data-map-block="final-offer-sentence"] .map-edit-field { font-size: 16px; font-weight: 600; }

/* Editable map fields read as text first, editable second: a faint dashed
   border and transparent background at rest, a normal field look on
   hover/focus. white-space:pre-wrap (native to <textarea>) plus no
   resize/scroll (auto-grown by app.js) keeps line breaks the reader typed
   without ever clipping or scrolling internally. */
.map-edit-field {
  min-height: 0; background: transparent; border: 1.5px dashed rgba(181,134,74,0.35);
  padding: 8px 10px; font-size: 14.5px; color: var(--text-dark); line-height: 1.6;
}
.map-edit-field:hover { border-color: rgba(181,134,74,0.6); background: #fff; }
.map-edit-field:focus { border-style: solid; border-color: var(--bronze); background: #fff; }
.map-edit-field--empty { color: #aaa; font-style: italic; }
/* Print-only mirror of each editable field's current value (correction
   pass: a real print engine showed the textarea's own on-screen
   auto-grown height governing its printed box — sometimes clipping
   wrapped text, sometimes leaving a large empty area, since a form
   control's print box is its own height/rows, not how much of its value
   actually reflows). Hidden on screen; see @media print below for where
   this swaps places with the textarea. */
.map-print-mirror { display: none; white-space: pre-wrap; }
.map-edit-field--over { border-color: #b1502b; }
.map-length-warning { font-size: 12.5px; color: #8a3b1f; margin-top: 4px; }
.map-actions { flex-wrap: wrap; }
.map-print-hint { font-size: 12px; color: #888; margin-top: -6px; }
/* Phase 5: "Email My Copy" send status — a dedicated, page-local live
   region right next to the buttons that triggered it (see app.js's
   setEmailStatus()), separate from the shared #workbook-status-banner. */
.map-email-status { font-size: 13.5px; margin-top: -6px; min-height: 0; }
.map-email-status:empty { display: none; }
.map-email-status--sending { color: #777; font-style: italic; }
.map-email-status--success { color: var(--green); }
.map-email-status--error { color: #8a3b1f; }

/* === Completion spread === */
.completion-action { border-left: 3px solid var(--bronze); padding-left: 14px; }
.completion-action strong { display: block; font-size: 11px; letter-spacing: 1px; text-transform: uppercase; color: var(--bronze-dark); margin-bottom: 4px; }
.completion-action p { font-size: 14.5px; color: var(--text-dark); margin-bottom: 2px; }
.completion-action-body { color: #666 !important; font-size: 13.5px !important; }
.secondary-resource { background: var(--cream); border-radius: 10px; padding: 16px; margin-top: 8px; }
.secondary-resource p { font-size: 14px; color: #444; margin-bottom: 10px; }

/* === Persistence lifecycle banner (resume / expired / schema-mismatch /
   corrupt / storage-unavailable / start-over confirm) — app chrome, lives
   outside #book. === */
.status-banner[hidden] { display: none; }
.status-banner {
  width: 100%; max-width: 960px; background: #fff;
  border: 1.5px solid rgba(181,134,74,0.35); border-radius: 12px;
  padding: 16px 18px; margin-bottom: 20px;
  display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 12px;
}
.status-banner-text { flex: 1; min-width: 220px; display: flex; flex-direction: column; gap: 4px; }
.status-banner-message { font-size: 14px; color: var(--text-dark); line-height: 1.6; flex: 1; min-width: 220px; }
.status-banner-message--secondary { font-size: 13px; color: #666; }
.status-banner-actions { display: flex; gap: 10px; flex-wrap: wrap; }
.status-banner--warning { border-color: rgba(196,98,45,0.4); background: rgba(196,98,45,0.06); }
.status-banner--warning .status-banner-message { color: #6b3a1f; }

/* === Persistent workbook toolbar: Table of Contents / autosave status /
   Start Over — always reachable, not just from the transient resume
   banner === */
.workbook-toolbar {
  width: 100%; max-width: 960px; display: flex; align-items: center; gap: 14px;
  margin-bottom: 16px; flex-wrap: wrap;
}
.btn-small { padding: 9px 16px; font-size: 13px; min-height: 36px; }
.save-status {
  font-size: 12.5px; color: #999; flex: 1; min-width: 140px;
  transition: color 0.2s ease;
}
.save-status[data-save-status="saved"] { color: var(--bronze-dark); }
.save-status[data-save-status="failed"] { color: #8a3b1f; font-weight: 600; }
.save-status:empty { visibility: hidden; }

/* === Table of Contents overlay === */
.toc-panel[hidden] { display: none; }
.toc-panel {
  position: fixed; inset: 0; z-index: 50;
  background: rgba(20,22,18,0.55);
  display: flex; align-items: center; justify-content: center; padding: 24px;
}
.toc-panel-inner {
  width: 100%; max-width: 480px; max-height: 84vh; overflow-y: auto;
  background: var(--paper); border-radius: 16px; padding: 28px 26px;
  box-shadow: 0 30px 70px rgba(20,22,18,0.35);
  display: flex; flex-direction: column; gap: 14px;
}
.toc-heading { font-family: var(--font-logo); font-size: 24px; color: var(--text-dark); }
.toc-heading:focus-visible { outline: 3px solid var(--bronze); outline-offset: 3px; }
.toc-review-label { font-size: 11px; font-weight: 700; letter-spacing: 1px; text-transform: uppercase; color: var(--bronze-dark); margin-top: -8px; }
.toc-list { list-style: none; display: flex; flex-direction: column; gap: 6px; }
.toc-item-btn {
  width: 100%; display: flex; align-items: center; justify-content: space-between; gap: 10px;
  border: 1.5px solid rgba(37,48,39,0.14); border-radius: 10px; padding: 12px 14px;
  background: #fff; cursor: pointer; font-family: var(--font-ui); font-size: 14.5px; color: var(--text-dark);
  text-align: left;
}
.toc-item-btn:hover { border-color: rgba(181,134,74,0.5); }
.toc-item--current .toc-item-btn { border-color: var(--bronze); background: rgba(181,134,74,0.06); }
.toc-item-tag {
  font-size: 10.5px; font-weight: 700; letter-spacing: 0.5px; text-transform: uppercase;
  border-radius: 999px; padding: 3px 9px; flex-shrink: 0;
}
.toc-item-tag--current { background: var(--bronze); color: #fff; }
.toc-item-tag--completed { background: rgba(37,48,39,0.1); color: var(--green); }
.toc-return-btn { align-self: stretch; }

/* === "Use This Structure" (copies only the blank field starter, never
   the substantive example answer) === */
.example-use-structure { margin-top: 8px; display: block; }

/* === Mobile: single page at a time, no spread, no spine leaves === */
@media (max-width: 760px) {
  .page { padding: 28px 22px; }
  .single-page-wrap .page, .book-solo .page { min-height: 380px; }
  .page-title { font-size: 26px; }
  .page-headline { font-size: 19px; }
  .book { min-height: 400px; }
  .workbook-progress-bar { font-size: 12px; }
  .qa-bar { font-size: 12px; }
  .control-distinction { grid-template-columns: 1fr; }
  .score-btn-row { flex-wrap: wrap; }
  .score-btn { min-width: 70px; }
  .stage-block-header { flex-wrap: wrap; }
  .field-pair-row { flex-direction: column; gap: 0; }
  .status-banner { flex-direction: column; align-items: stretch; }
  .workbook-toolbar { flex-direction: column; align-items: stretch; }
  .toc-panel-inner { max-width: none; max-height: 90vh; }
}

/* ========================================================================
   Print / Save as PDF (PRD: Offer Map only, US Letter with an A4-safe
   fallback, selectable text, restrained branding, no QA bar / navigation
   / page-turn leaves / unrelated pages, one page when answers stay within
   the guidance limits above). Never rasterized — this is the same live
   HTML/CSS the screen shows, just re-laid-out for a printed sheet.
   ======================================================================== */
@page {
  size: letter;
  margin: 0.6in;
}
@media print {
  /* US Letter is the primary target; browsers fall back to the printer's
     configured page size (commonly A4) automatically when Letter isn't
     available, and every measurement below is relative (%, em, auto flow)
     rather than a fixed Letter-only pixel size, so that fallback still
     lays out safely instead of overflowing or clipping. */
  html, body { background: #fff; height: auto; }
  body { padding: 0; display: block; }

  .workbook-progress-bar, .progress-track, .qa-bar, #page-announcer, .status-banner,
  .leaf, [data-print-hide] { display: none !important; }

  .book-outer, .book, .book-half, .book-solo, .single-page-wrap {
    all: unset;
    display: block;
  }

  /* Only the Offer Map page prints — every other page/spread (including
     the currently-open spread's OTHER half, if any) is hidden outright. */
  .page:not([data-print-target]) { display: none !important; }

  .page--map {
    display: block; box-shadow: none; border: none; padding: 0; min-height: 0;
    color: #000; gap: 0;
  }
  /* .single-page-wrap .page / .book-solo .page (styles.css, screen rules)
     is a two-class selector — more specific than .page--map alone — so
     it was still winning here and leaving the screen card's shadow,
     border, rounded corners, and cream background on the printed page.
     Same specificity-order pitfall as the earlier `[hidden]` bug; matched
     with an equal-or-greater-specificity override instead of relying on
     source order. Found via the real-Chrome print screenshot in this
     correction pass. */
  .single-page-wrap .page--map, .book-solo .page--map {
    box-shadow: none !important; border: none !important; border-radius: 0 !important;
    background: #fff !important; min-height: 0 !important;
  }
  /* Typography floor (final correction pass, after a real Chrome print
     engine found both clipping AND large empty gaps — see below and the
     Final Print Report): body values >= 9pt (12px), labels/metadata
     >= 8pt (10.7px, rounded up to 11px here), title and one-sentence
     offer larger still. Never applied to the on-screen editing
     experience. Point sizes are computed at 96 CSS px/in (1pt = 1.333px):
     12px = 9pt, 11px = 8.25pt, 18px = 13.5pt, 15px = 11.25pt.
   */
  .page--map .page-eyebrow { color: #333; font-size: 11px; }
  .page--map .page-headline {
    font-family: var(--font-logo); font-size: 18px; color: #000;
    border-bottom: 1.5px solid #000; padding-bottom: 3px; margin-bottom: 2px;
  }
  .page--map .map-meta { font-size: 11px; margin: 0; line-height: 1.25; }
  .page--map .map-block { border-bottom: 1px solid #ccc; padding-bottom: 0; margin-bottom: 0; page-break-inside: avoid; }
  .page--map .map-block-label { color: #555; font-size: 11px; margin-bottom: 0; line-height: 1.15; }
  .page--map .map-block-value {
    color: #000; -webkit-text-fill-color: #000; /* selectable, real text, not an image */
    font-size: 12px; line-height: 1.25; margin: 0;
  }
  /* The textarea itself never prints (see below, and PHASE-3-FINAL-PRINT-
     REPORT.md): a real print engine showed its printed box governed by
     its own on-screen auto-grown height/rows, not by how much of its
     value actually reflowed onto the printed page — producing both
     mid-word clipping and large empty gaps in the same document,
     depending on the field. .map-print-mirror (a plain <p>, always kept
     in sync — see app.js's refreshMapPrintMirror()) replaces it here: it
     has no intrinsic height of its own, so it paginates exactly like the
     rest of the page's text. */
  .map-edit-field { display: none !important; }
  .map-print-mirror {
    display: block; color: #000; -webkit-text-fill-color: #000;
    font-size: 12px; line-height: 1.25; margin: 0;
  }
  .map-print-mirror--empty { color: #666; font-style: italic; }
  .map-block[data-map-block="final-offer-sentence"] .map-print-mirror { font-size: 15px; font-weight: 600; }
  .map-length-warning, .map-edit-jump { display: none !important; }
  .map-hypothesis-note { font-size: 11px; margin: 3px 0; }
  .map-footer, .map-brand-line { color: #555; font-size: 11px; margin: 3px 0 0; }
  .map-actions, .map-print-hint { display: none !important; }

  /* Layout redesign (correction pass §4, part 2): the three exchange
     terms and the two test parameters are each short, single-line values
     (their guidance limits are 60-100 characters) but were still printing
     as five full-width stacked blocks, each paying a label + border
     overhead that a value this short doesn't need. Laying each trio/pair
     out as one compact row — still five independently editable fields on
     screen, this only changes print layout — was the highest-leverage fix
     once the type-size floor above was reached; see the report for the
     measured before/after.
   */
  .map-block[data-map-block="exchange-delivery-model"],
  .map-block[data-map-block="exchange-duration"],
  .map-block[data-map-block="exchange-price"] {
    display: inline-block; vertical-align: top; box-sizing: border-box;
    width: 33.33%; padding-right: 8px; border-bottom: none; margin-bottom: 0;
  }
  .map-block[data-map-block="exchange-price"] { border-bottom: 1px solid #ccc; padding-bottom: 1px; margin-bottom: 1px; width: 33.34%; }
  .map-block[data-map-block="test-size"],
  .map-block[data-map-block="test-review-date"] {
    display: inline-block; vertical-align: top; box-sizing: border-box;
    width: 50%; padding-right: 8px; border-bottom: none; margin-bottom: 0;
  }
  .map-block[data-map-block="test-review-date"] { border-bottom: 1px solid #ccc; padding-bottom: 1px; margin-bottom: 1px; }

  /* Four of these blocks paired two-to-a-row, chosen from pairs that are
     genuinely ADJACENT in the DOM (renderOfferMap()'s fixed block order —
     see app.js): person+desire, constraint+result, path-summary+trust-
     statement, trust-next-proof+exchange-included. Each is still two
     independently editable fields, just laid out side by side instead of
     stacked. difference-statement has no adjacent text-block partner (the
     structured path block follows it) and stays full width. Ordinary
     inline-block wrapping puts each real pair on one row; every other
     block here stays block-level, which forces a fresh line right after
     each pair — so this only works because these four pairs are each
     other's actual next sibling. If renderOfferMap()'s block order ever
     changes, this must be re-verified (see the manual QA procedure in the
     correction-pass report). */
  .map-block[data-map-block="person-statement"],
  .map-block[data-map-block="constraint-statement"],
  .map-block[data-map-block="path-summary"],
  .map-block[data-map-block="trust-next-proof"] {
    display: inline-block; vertical-align: top; box-sizing: border-box;
    width: 48%; margin-right: 4%; border-bottom: none; margin-bottom: 0;
  }
  .map-block[data-map-block="desire-statement"],
  .map-block[data-map-block="result-statement"],
  .map-block[data-map-block="trust-statement"],
  .map-block[data-map-block="exchange-included"] {
    display: inline-block; vertical-align: top; box-sizing: border-box;
    width: 48%; border-bottom: 1px solid #ccc; padding-bottom: 1px; margin-bottom: 1px;
  }
}
