/* Hallmark · macrostructure: cinematic page procession · tone: editorial · anchor hue: ember
 * pre-emit critique: P5 H5 E5 S5 R5 V5 · contrast: pass · mobile: pass
 *
 * Token consolidation (Phase 1, idea2Lit UI redesign).
 * Canonical spec: docs/UI-REDESIGN-DEVELOPER-HANDOFF.md §8 (theme tokens),
 * §9 (typography tokens), §10 (header), §26 (risks).
 * Source-of-truth implementation reference: apps/server/DESIGN.md.
 *
 * The block below declares theme + typography tokens exactly once. Legacy
 *
 * `interpolate-size: allow-keywords` enables CSS to interpolate the
 * `grid-template-rows: 0fr → 1fr` transition used by the Book Options
 * reveal animation in browsers that gate that feature behind a flag.
 * It's a no-op in browsers that already interpolate size keywords freely.
 * aliases (--paper, --surface, --ink, --muted, --accent, --hairline, --focus,
 * --success, --warning, --danger, --font-mono, --header-surface, etc.) are
 * preserved as semantic shorthands so component rules further down the file
 * keep resolving. Do not redeclare font-display, font-ui, font-reading, or
 * any --color-* token below the consolidated :root.
 */

/* Montserrat Variable — single self-hosted WOFF2 file, full wght axis 100-900.
 * Source: scripts/fetch-montserrat.mjs · License: SIL OFL 1.1
 * (apps/server/public/fonts/OFL-Montserrat.txt).
 * Naming: "Montserrat Variable" is the local family name so other Montserrat
 * stacks can fall back without ambiguity. */
@font-face {
  font-family: "Montserrat Variable";
  src:
    url("/fonts/montserrat-latin-variable.woff2") format("woff2-variations"),
    url("/fonts/montserrat-latin-variable.woff2") format("woff2");
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
}

:root {
  color: var(--ink);
  background: var(--paper);
  font-family: var(--font-ui);
  font-synthesis: none;
  /* Allow interpolation of `grid-template-rows: 0fr → 1fr` and similar
   * size-keyword transitions (the Book Options reveal depends on this). */
  interpolate-size: allow-keywords;

  /* --- Typography tokens (§9). One definition each. --- */
  --font-ui:
    "Montserrat Variable", "Montserrat", "Segoe UI Variable", "Segoe UI",
    system-ui, sans-serif;
  --font-display: "Fraunces", "Georgia", "Iowan Old Style", serif;
  --font-reading: "Literata", "Georgia", "Iowan Old Style", serif;
  /* Legacy aliases — kept so component rules referencing --font-body or
   * --font-mono continue to resolve. Both resolve to --font-ui per §9
   * (no fourth monospace face). */
  --font-body: var(--font-ui);
  --font-mono: var(--font-ui);

  /* --- Theme tokens (§8) — night is the default. --- */
  --color-app: oklch(18% 0.018 252);
  --color-surface: oklch(22% 0.022 252);
  --color-surface-raised: oklch(27% 0.026 252);
  --color-page: oklch(96% 0.012 80);
  --color-ink: oklch(95% 0.014 80);
  --color-muted: oklch(72% 0.022 252);
  --color-accent: oklch(78% 0.195 65);
  --color-accent-ink: oklch(18% 0.018 252);
  --color-success: oklch(68% 0.13 145);
  --color-warning: oklch(74% 0.115 70);
  --color-danger: oklch(64% 0.18 22);
  --color-focus: oklch(78% 0.19 60);
  --color-hairline: oklch(32% 0.04 252);

  /* --- Legacy semantic aliases (kept so existing rules still resolve).
   * Values mirror the new --color-* tokens in OKLCH. --- */
  --paper: var(--color-app);
  --surface: var(--color-surface);
  --surface-raised: var(--color-surface-raised);
  --ink: var(--color-ink);
  --muted: var(--color-muted);
  --hairline: var(--color-hairline);
  --accent: var(--color-accent);
  --accent-deep: var(--color-accent);
  --accent-ink: var(--color-accent-ink);
  --success: var(--color-success);
  --danger: var(--color-danger);
  --warning: var(--color-warning);
  --focus: var(--color-focus);

  /* --- Header-specific legacy aliases. --- */
  --header-surface: color-mix(in oklch, var(--color-app) 90%, transparent);
  --header-rule: var(--color-hairline);
  --header-shadow: 0 0.55rem 1.8rem rgb(0 0 0 / 12%);

  /* --- Motion (§10, §21). --- */
  --theme-duration: 480ms;
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);

  /* --- Provider state tokens (§10). Five states, dot colors + animations. */
  --provider-dot-neutral: var(--color-muted);
  --provider-dot-checking: var(--color-accent);
  --provider-dot-ready: var(--color-success);
  --provider-dot-error: var(--color-danger);
  --provider-dot-rate: var(--color-warning);

  /* --- Misc legacy aliases (page shadow, soft signal). --- */
  --page-shadow: rgb(0 0 0 / 42%);
  --soft-signal: rgb(82 214 144 / 24%);
}

:root[data-theme="daylight"] {
  /* --- Daylight variants of the new tokens (§8). --- */
  --color-app: oklch(97% 0.008 252);
  --color-surface: oklch(94% 0.014 252);
  --color-surface-raised: oklch(90% 0.022 252);
  --color-page: oklch(96% 0.012 80);
  --color-ink: oklch(20% 0.022 252);
  --color-muted: oklch(46% 0.028 252);
  --color-accent: oklch(54% 0.185 258);
  --color-accent-ink: oklch(97% 0.008 252);
  --color-success: oklch(54% 0.13 145);
  --color-warning: oklch(58% 0.13 70);
  --color-danger: oklch(56% 0.18 22);
  --color-focus: oklch(58% 0.205 258);
  --color-hairline: oklch(80% 0.03 252);

  /* --- Lightmode ocean gradient: White to very subtle light ocean blue --- */
  --daylight-ocean-bg: linear-gradient(
    180deg,
    #ffffff 0%,
    rgba(224, 242, 254, 0.55) 45%,
    rgba(186, 230, 253, 0.38) 100%
  );

  /* --- Legacy aliases mirror daylight tokens. --- */
  --surface: var(--color-surface);
  --surface-raised: var(--color-surface-raised);
  --ink: var(--color-ink);
  --muted: var(--color-muted);
  --hairline: var(--color-hairline);
  --accent: var(--color-accent);
  --accent-deep: var(--color-accent);
  --accent-ink: var(--color-accent-ink);
  --header-surface: color-mix(in oklch, var(--color-surface) 92%, transparent);
}

/* Current workbench skin. Kept at the end so legacy component rules cannot
   reintroduce the retired beige preview palette. */
body {
  color: var(--ink);
  background: var(--paper);
  transition:
    color 240ms var(--ease-out),
    background-color 240ms var(--ease-out);
}

h1,
h2,
h3,
summary {
  font-family: var(--font-display);
}

.masthead {
  background: color-mix(in srgb, var(--paper) 88%, transparent);
  backdrop-filter: blur(18px);
}

.masthead h1 {
  display: flex;
  align-items: baseline;
  gap: 0.7rem;
  font-size: clamp(1.75rem, 3.2vw, 3.6rem);
  line-height: 1;
}

.masthead h1 small {
  color: var(--muted);
  font-family: var(--font-mono);
  font-size: clamp(0.64rem, 1vw, 0.8rem);
  font-weight: 500;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

.masthead-actions,
.prompt-actions {
  display: flex;
  align-items: center;
  gap: 0.65rem;
}

.theme-toggle {
  position: relative;
  display: grid;
  width: 2.75rem;
  min-width: 2.75rem;
  height: 2.75rem;
  padding: 0;
  overflow: hidden;
  place-items: center;
  color: var(--accent);
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: 50%;
  cursor: pointer;
  transition:
    transform 220ms var(--ease-out),
    color 220ms var(--ease-out),
    background-color 220ms var(--ease-out);
}

.theme-toggle:hover {
  color: var(--ink);
  transform: rotate(10deg) scale(1.04);
}

.theme-toggle:active {
  transform: rotate(-6deg) scale(0.92);
}

.theme-orbit,
.theme-sun,
.theme-moon {
  position: absolute;
  display: block;
  width: 1.2rem;
  height: 1.2rem;
  transition:
    transform 420ms var(--ease-in-out),
    opacity 260ms var(--ease-out);
}

.theme-orbit {
  transform: rotate(0deg);
}

.theme-sun {
  opacity: 0;
  background: currentColor;
  border-radius: 50%;
  transform: scale(0.2) rotate(-70deg);
  box-shadow:
    0 -0.78rem 0 -0.49rem currentColor,
    0 0.78rem 0 -0.49rem currentColor,
    0.78rem 0 0 -0.49rem currentColor,
    -0.78rem 0 0 -0.49rem currentColor,
    0.55rem 0.55rem 0 -0.49rem currentColor,
    -0.55rem -0.55rem 0 -0.49rem currentColor,
    0.55rem -0.55rem 0 -0.49rem currentColor,
    -0.55rem 0.55rem 0 -0.49rem currentColor;
}

.theme-moon {
  background: currentColor;
  border-radius: 50%;
  transform: scale(1) rotate(0deg);
}

.theme-moon::after {
  position: absolute;
  inset: -0.12rem -0.18rem 0.18rem 0.38rem;
  content: "";
  background: var(--surface);
  border-radius: 50%;
}

:root[data-theme="daylight"] .theme-orbit {
  transform: rotate(180deg);
}

:root[data-theme="daylight"] .theme-sun {
  opacity: 1;
  transform: scale(0.72) rotate(0deg);
}

:root[data-theme="daylight"] .theme-moon {
  opacity: 0;
  transform: scale(0.15) rotate(70deg);
}

.engine-status {
  position: relative;
  color: var(--muted);
  background: var(--surface);
  border-color: var(--hairline);
}

.engine-status.is-ready {
  color: var(--ink);
}

.engine-status.is-ready .status-dot {
  position: relative;
  background: var(--success);
}

.engine-status.is-ready .status-dot::after {
  position: absolute;
  inset: -0.38rem;
  content: "";
  background: var(--soft-signal);
  border-radius: 50%;
  animation: status-breathe 2.8s var(--ease-in-out) infinite;
}

@keyframes status-breathe {
  0%,
  100% {
    opacity: 0.35;
    transform: scale(0.72);
  }
  50% {
    opacity: 0.8;
    transform: scale(1.2);
  }
}

.editor-panel {
  padding: 0;
  overflow: clip;
  background: var(--surface);
  border: 1px solid var(--hairline);
  /* Keeps the panel summary clear of the sticky masthead when
     scrollIntoView brings the panel to the top of the viewport after
     a book completes — the user should not need to scroll a few extra
     pixels to see the "Generate another book" label. */
  scroll-margin-top: 5rem;
}

.editor-panel > summary {
  display: flex;
  min-height: 3.75rem;
  padding: 1rem 1.25rem;
  align-items: center;
  justify-content: space-between;
  color: var(--ink);
  cursor: pointer;
  list-style: none;
}

.editor-panel > summary::-webkit-details-marker {
  display: none;
}

.editor-panel > summary::after {
  content: "+";
  color: var(--accent);
  font-family: var(--font-mono);
  font-size: 1.25rem;
  transition: transform 260ms var(--ease-out);
}

.editor-panel[open] > summary::after {
  transform: rotate(45deg);
}

.editor-panel > form {
  padding: 0 1.25rem 1.25rem;
  border-top: 1px solid var(--hairline);
}

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

.idea-input::placeholder {
  color: var(--muted);
  opacity: 0.78;
  transition: opacity 320ms var(--ease-out);
}

.idea-input.is-placeholder-fading::placeholder {
  opacity: 0;
}

.idea-input.is-enhancing {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 20%, transparent);
}

#prompt-state {
  min-height: 1em;
  margin: 0 auto 0 0;
  color: var(--muted);
  font-family: var(--font-mono);
  font-size: 0.72rem;
}

input,
select,
textarea,
.book-options,
.provider-dialog,
.provider-option,
.book-workspace,
.outline-rundown,
.stream-book,
.stream-page,
.outputs-panel,
.output-card,
.manuscript-panel {
  color: var(--ink);
  background: var(--surface);
  border-color: var(--hairline);
}

.stream-page,
.output-card {
  background: var(--surface-raised);
}

.primary {
  color: var(--accent-ink);
  background: var(--accent);
  border-color: var(--accent);
}

button:disabled,
.output-card.is-disabled {
  opacity: 0.42;
  cursor: not-allowed;
  filter: saturate(0.35);
  transform: none;
}

.output-card:not(.is-disabled) {
  opacity: 1;
  filter: none;
  transition:
    transform 220ms var(--ease-out),
    border-color 220ms var(--ease-out),
    background-color 220ms var(--ease-out);
}

.output-card:not(.is-disabled):hover {
  border-color: var(--accent);
}

.output-grid {
  grid-template-columns: repeat(3, minmax(0, 1fr));
}

@media (max-width: 860px) {
  .masthead {
    align-items: flex-start;
  }

  .masthead h1 {
    flex-wrap: wrap;
  }

  .masthead-actions {
    gap: 0.4rem;
  }

  .engine-status {
    padding-inline: 0.75rem;
  }

  .output-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (max-width: 520px) {
  .masthead {
    gap: 0.75rem;
    padding-block: 1.25rem;
  }

  .masthead h1 {
    gap: 0.35rem 0.55rem;
  }

  .masthead h1 small {
    flex-basis: 100%;
  }

  .prompt-actions {
    align-items: stretch;
    flex-direction: column;
  }

  #prompt-state {
    order: -1;
  }
}

:root[data-theme="daylight"] {
  --paper: #edf2f7;
  --surface: #f9fbfd;
  --surface-raised: #ffffff;
  --ink: #111a27;
  --muted: #5d6a7b;
  --hairline: #cad4e1;
  --accent: #255fce;
  --accent-deep: #17469e;
  --accent-ink: #ffffff;
  --success: #15794b;
  --danger: #b73730;
  --focus: #255fce;
  --page-shadow: rgb(36 54 78 / 16%);
  --soft-signal: rgb(21 121 75 / 18%);
}

* {
  box-sizing: border-box;
}

html,
body {
  overflow-x: clip;
}

html {
  scroll-behavior: smooth;
}

body {
  margin: 0;
  min-height: 100vh;
}

button,
input,
select,
textarea {
  font: inherit;
}

button,
a {
  -webkit-tap-highlight-color: transparent;
}

[hidden] {
  display: none !important;
}

.masthead {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 2rem;
  padding: 2.4rem clamp(1.25rem, 5vw, 5rem);
  border-bottom: 1px solid var(--hairline);
}

h1,
h2,
h3,
p {
  margin-top: 0;
}

h1 {
  margin-bottom: 0;
  font:
    500 clamp(2rem, 4.8vw, 4.8rem) / 0.96 Georgia,
    serif;
  letter-spacing: -0.045em;
}

h2 {
  margin-bottom: 0;
  font:
    500 clamp(1.55rem, 3vw, 2.3rem) / 1.08 Georgia,
    serif;
  letter-spacing: -0.02em;
}

h3 {
  font-size: 0.9rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.step {
  margin: 0 0 0.65rem;
  color: var(--muted);
  font:
    700 0.7rem/1 ui-monospace,
    SFMono-Regular,
    Consolas,
    monospace;
  letter-spacing: 0.14em;
}

.engine-status {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  min-height: 44px;
  padding: 0.65rem 0.85rem;
  border: 1px solid #98988f;
  background: transparent;
  color: #55564e;
  cursor: pointer;
  font-size: 0.78rem;
  font-weight: 700;
}

.status-dot {
  width: 0.55rem;
  height: 0.55rem;
  border: 1px solid currentColor;
  border-radius: 50%;
  background: transparent;
}

.engine-status.is-ready {
  border-color: var(--success);
  color: var(--success);
  background: #dce8dc;
}

.engine-status.is-ready .status-dot,
.engine-status.is-streaming .status-dot {
  background: currentColor;
}

.engine-status.is-streaming {
  border-color: var(--accent-deep);
  color: var(--accent-deep);
  background: #f0dfd2;
}

main {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
}

.panel,
.book-workspace {
  padding: clamp(1.5rem, 4vw, 4rem) clamp(1.25rem, 5vw, 5rem);
  border-bottom: 1px solid var(--hairline);
}

.editor-panel {
  max-width: 78rem;
  width: 100%;
  margin-inline: auto;
}

.panel-heading,
.workspace-heading,
.dialog-heading {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: 2rem;
}

label {
  display: block;
  margin-bottom: 0.5rem;
  font-size: 0.8rem;
  font-weight: 750;
}

label span {
  color: var(--muted);
  font-size: 0.72rem;
  font-weight: 500;
}

input,
select,
textarea {
  display: block;
  width: 100%;
  border: 1px solid #9f9f95;
  border-radius: 0;
  padding: 0.8rem;
  background: var(--paper);
  color: var(--ink);
}

input[readonly] {
  color: #585950;
  background: #e5e3d9;
}

textarea {
  resize: vertical;
}

.idea-input {
  min-height: 11rem;
  font:
    1.05rem/1.55 Georgia,
    serif;
}

textarea:focus,
input:focus,
select:focus,
button:focus-visible,
a:focus-visible {
  outline: 3px solid var(--focus);
  outline-offset: 2px;
}

.field-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1.1rem;
  margin: 1.5rem 0;
}

.field-wide {
  grid-column: 1 / -1;
}

.field-label {
  display: block;
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--muted, #5a5a55);
  margin-bottom: 0.4rem;
}

/* Radio groups in dialogs and forms.
 *
 * The label is the flex container; the radio input and the descriptive text
 * are its only flex children. We use `display: flex` (block-level) rather
 * than `inline-flex` so the label stretches to the full width of its
 * parent — with `inline-flex`, the label collapses to its intrinsic width
 * which produces an unsightly gap between the radio and the text on narrow
 * screens. Inside `.radio-stack` the labels are stacked vertically and
 * each one owns a full row.
 *
 * `align-items: flex-start` aligns the radio with the first line of the
 * descriptive text; `align-items: center` would visually center the radio
 * between wrapped text lines (e.g. "Soft" / "shadow" appearing on two
 * lines because the row is narrower than the label), which looks broken.
 *
 * The radio itself is `flex-shrink: 0` so it never collapses to zero
 * width inside a tight flex container.
 */
.radio-row,
.radio-stack {
  display: flex;
  gap: 0.65rem 1.1rem;
}

.radio-row {
  flex-wrap: wrap;
}

.radio-stack {
  flex-direction: column;
  gap: 0.45rem;
}

.radio-row label,
.radio-stack label {
  display: flex;
  align-items: flex-start;
  gap: 0.5rem;
  font-size: 0.92rem;
  line-height: 1.35;
  color: inherit;
  cursor: pointer;
}

.radio-stack label {
  width: 100%;
}

.radio-row input[type="radio"],
.radio-stack input[type="radio"] {
  width: auto;
  flex: 0 0 auto;
  margin: 0.15rem 0 0;
  cursor: pointer;
}

/* Weighted Animated Slide / Fade-In / Fade-Out Drawer for Book Options */
.book-options {
  position: relative;
  margin: 1.5rem 0;
  padding: 0 1rem;
  border: 1px solid var(--hairline);
  border-radius: 0.65rem;
  background:
    linear-gradient(
      to bottom,
      color-mix(in srgb, var(--accent) 5%, transparent),
      transparent 70%
    ),
    var(--surface);
  transition:
    box-shadow 360ms cubic-bezier(0.16, 1, 0.3, 1),
    border-color 360ms cubic-bezier(0.16, 1, 0.3, 1);
  overflow: hidden;
  overflow-anchor: none;
}

.book-options[open] {
  box-shadow: 0 12px 32px -8px rgba(0, 0, 0, 0.16);
  border-color: color-mix(in srgb, var(--accent) 40%, var(--hairline));
}

.book-options .field-grid {
  display: grid;
  grid-template-rows: 0fr;
  opacity: 0;
  transform: translateY(-10px);
  margin-top: 0.4rem;
  padding-bottom: 0;
  transition:
    grid-template-rows 520ms cubic-bezier(0.16, 1, 0.3, 1),
    opacity 360ms cubic-bezier(0.16, 1, 0.3, 1),
    transform 400ms cubic-bezier(0.16, 1, 0.3, 1),
    padding-bottom 520ms cubic-bezier(0.16, 1, 0.3, 1);
}

.book-options[open] .field-grid {
  grid-template-rows: 1fr;
  opacity: 1;
  transform: translateY(0);
  padding-bottom: 1.25rem;
}

.book-options .field-grid > * {
  min-height: 0;
  overflow: hidden;
}

.book-options summary {
  transition: color 220ms cubic-bezier(0.16, 1, 0.3, 1);
}

.book-options summary:hover {
  color: var(--accent-deep);
}

.book-options summary::marker {
  transition: transform 220ms cubic-bezier(0.16, 1, 0.3, 1);
}

/* Cover Image Row & Overlay Title Toggle Styling */
.field-image-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  margin-top: 0.75rem;
  padding: 0.65rem 0.85rem;
  background: var(--surface-raised);
  border: 1px solid var(--hairline);
  border-radius: 8px;
}

.cover-action-buttons {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.cover-overlay-toggle {
  margin-top: 0.65rem;
  padding: 0.6rem 0.85rem;
  background: var(--surface-raised);
  border: 1px solid var(--hairline);
  border-radius: 8px;
  transition: border-color 150ms ease;
}

.cover-overlay-toggle:hover {
  border-color: var(--accent);
}

.toggle-control-label {
  display: flex;
  align-items: center;
  gap: 0.65rem;
  font-size: 0.82rem;
  color: var(--ink);
  cursor: pointer;
}

.toggle-checkbox {
  width: 1.1rem;
  height: 1.1rem;
  accent-color: var(--accent);
  cursor: pointer;
}

.toggle-label-text {
  font-weight: 600;
}

.toggle-badge {
  margin-left: auto;
  padding: 0.15rem 0.5rem;
  border-radius: 999px;
  background: color-mix(in srgb, var(--muted) 15%, transparent);
  color: var(--muted);
  font-size: 0.7rem;
  font-weight: 700;
}

.book-options summary:hover::before {
  border-color: var(--accent-deep);
}

.book-options summary:hover .book-options-hint {
  background: color-mix(in srgb, var(--accent) 22%, transparent);
}

button {
  border: 1px solid var(--ink);
  padding: 0.78rem 1rem;
  color: var(--ink);
  font-weight: 750;
  cursor: pointer;
}

button:disabled {
  cursor: not-allowed;
  opacity: 0.58;
}

.primary {
  width: 100%;
  min-height: 50px;
  background: var(--accent);
}

.compact-primary {
  width: auto;
}

.secondary,
.quiet-button,
.icon-button,
.text-button {
  background: transparent;
}

.quiet-button {
  font-size: 0.78rem;
}

.icon-button {
  width: 42px;
  height: 42px;
  padding: 0;
  border-color: var(--hairline);
  font-size: 1.5rem;
  line-height: 1;
}

.text-button {
  padding: 0;
  border: 0;
  text-decoration: underline;
  text-underline-offset: 0.18em;
  font-size: 0.78rem;
}

.danger {
  color: var(--danger);
}

.progress,
.stream-status,
.security-note,
.provider-note,
.dialog-intro {
  color: var(--muted);
  font-size: 0.82rem;
  line-height: 1.5;
}

.progress {
  min-height: 1.4rem;
  margin: 0.7rem 0 0;
}

.book-workspace {
  position: relative;
  background: transparent;
  padding-block: 2.5rem;
}

.stream-book {
  position: relative;
  display: grid;
  width: min(100%, 58rem);
  aspect-ratio: 1.45 / 1;
  min-height: 34rem;
  max-height: min(84vh, 50rem);
  grid-template-rows: auto minmax(0, 1fr);
  gap: 0.85rem;
  margin-inline: auto;
  overflow: hidden;
  padding: clamp(1.4rem, 3vw, 2.4rem);
  border: 1px solid #7c796d;
  border-radius: 6px 16px 16px 6px;
  background:
    radial-gradient(ellipse at center, rgba(0, 0, 0, 0.04) 0%, transparent 80%),
    linear-gradient(
      to right,
      #e2ded0 0%,
      #f5f2e6 4%,
      #faf8f2 50%,
      #f5f2e6 96%,
      #e2ded0 100%
    );
  box-shadow:
    0 22px 55px rgba(22, 20, 15, 0.22),
    inset 0 0 14px rgba(0, 0, 0, 0.07);
}

.stream-book::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  bottom: 0;
  width: 6px;
  background: linear-gradient(to right, #8a572a, #b37b42 60%, #6e421e);
  box-shadow: 2px 0 6px rgba(0, 0, 0, 0.25);
  z-index: 10;
}

.stream-book h3 {
  margin-bottom: 0;
  font:
    600 1.15em/1.1 Georgia,
    serif;
  letter-spacing: -0.01em;
  text-transform: none;
}

.stream-heading {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
}

.stream-state {
  color: var(--muted);
  font:
    700 0.68rem/1.2 ui-monospace,
    monospace;
  letter-spacing: 0.07em;
  text-align: right;
  text-transform: uppercase;
}

.stream-content {
  position: relative;
  min-width: 0;
  min-height: 0;
  overflow: hidden;
  perspective: 1400px;
  perspective-origin: center center;
}

/* 3D Open Book Spine Crease Strictly Scoped inside Stream Content Page Viewport */
.stream-content::after {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  left: 50%;
  width: 24px;
  transform: translateX(-50%);
  background: linear-gradient(
    to right,
    rgba(0, 0, 0, 0.14) 0%,
    rgba(0, 0, 0, 0.03) 42%,
    rgba(0, 0, 0, 0.03) 58%,
    rgba(0, 0, 0, 0.14) 100%
  );
  box-shadow: inset 0 0 10px rgba(0, 0, 0, 0.15);
  z-index: 10;
  pointer-events: none;
}

.stream-empty {
  display: grid;
  min-height: 100%;
  place-items: center;
  border: 1px dashed var(--hairline);
  color: var(--muted);
  font:
    0.78rem/1.5 ui-monospace,
    monospace;
  text-align: center;
}

.open-spread {
  display: grid;
  grid-template-columns: 1fr 1fr;
  width: 100%;
  height: 100%;
  min-height: 0;
}

.outline-rundown.open-spread {
  height: 100%;
  overflow: hidden;
  padding: 0;
  opacity: 0;
  transform: translateY(0.6rem);
  transition:
    opacity 480ms var(--ease-out, cubic-bezier(0.16, 1, 0.3, 1)),
    transform 480ms var(--ease-out, cubic-bezier(0.16, 1, 0.3, 1));
}

.outline-rundown.is-visible {
  opacity: 1;
  transform: translateY(0);
}

.rundown-verso,
.stream-verso {
  padding: clamp(1rem, 2.5vw, 2.2rem);
  overflow-y: auto;
  border-right: 1px solid #dcd7c8;
  box-shadow: inset -10px 0 16px -8px rgba(0, 0, 0, 0.06);
}

.rundown-recto,
.stream-recto {
  padding: clamp(1rem, 2.5vw, 2.2rem);
  overflow-y: auto;
  box-shadow: inset 10px 0 16px -8px rgba(0, 0, 0, 0.06);
}

.rundown-label,
.rundown-number {
  color: var(--muted);
  font:
    700 0.68rem/1 ui-monospace,
    monospace;
  letter-spacing: 0.12em;
}

.rundown-title {
  margin: 0.5rem 0;
  font:
    600 clamp(1.6rem, 3.5vw, 2.5rem)/1.05 Georgia,
    serif;
  letter-spacing: -0.03em;
  text-transform: none;
}

.rundown-subtitle {
  max-width: 24rem;
  color: var(--muted);
  font:
    0.92rem/1.4 Georgia,
    serif;
}

.rundown-family-badge {
  display: inline-block;
  margin-top: 1.2rem;
  padding: 0.25rem 0.65rem;
  border-radius: 4px;
  background: color-mix(in srgb, var(--accent) 15%, transparent);
  color: var(--accent-deep);
  font:
    700 0.65rem ui-monospace,
    monospace;
  letter-spacing: 0.08em;
}

.rundown-list {
  display: grid;
  max-width: 100%;
  gap: 0;
  margin: 1.2rem 0 0;
  padding: 0;
  list-style: none;
}

.rundown-item {
  display: grid;
  grid-template-columns: 2rem minmax(0, 1fr);
  gap: 0.5rem;
  padding: 0.55rem 0;
  border-top: 1px solid var(--hairline);
  opacity: 0;
  transform: translateY(0.45rem);
  transition:
    opacity 420ms var(--ease-out, cubic-bezier(0.16, 1, 0.3, 1)),
    transform 420ms var(--ease-out, cubic-bezier(0.16, 1, 0.3, 1));
}

.rundown-item.is-visible {
  opacity: 1;
  transform: translateY(0);
}

.rundown-chapter-title {
  font:
    600 clamp(0.9rem, 1.5vw, 1.1rem)/1.2 Georgia,
    serif;
}

/* Page Procession & 3D Book Page Flip Animations */
.page-procession {
  display: flex;
  width: 100%;
  height: 100%;
  gap: 0;
  transform-style: preserve-3d;
  transform: translateX(calc(var(--page-index, 0) * -100%));
  transition: transform 850ms cubic-bezier(0.22, 1, 0.36, 1);
}

.stream-page.open-spread {
  position: relative;
  display: grid;
  grid-template-columns: 1fr 1fr;
  flex: 0 0 100%;
  width: 100%;
  height: 100%;
  min-height: 0;
  gap: 0;
  overflow: hidden;
  padding: 0;
  border: 1px solid #dcd7c8;
  border-radius: 2px 8px 8px 2px;
  background: #fdfbf7;
  box-shadow:
    inset 14px 0 24px -12px rgba(0, 0, 0, 0.08),
    0 4px 16px rgba(0, 0, 0, 0.07);
  color: #2b2a26;
  transform-origin: left center;
  transform-style: preserve-3d;
  transition:
    transform 850ms cubic-bezier(0.22, 1, 0.36, 1),
    opacity 500ms ease-out,
    box-shadow 500ms ease-out;
}

.stream-verso,
.stream-recto {
  display: grid;
  grid-template-rows: auto auto minmax(0, 1fr);
  gap: 0.4rem;
  height: 100%;
  min-height: 0;
}

.stream-chapter-summary {
  font:
    italic 0.88rem/1.5 Georgia,
    serif;
  color: #5a5952;
  margin: 0.5rem 0 0.8rem;
}

.stream-key-points {
  margin: 0;
  padding-left: 1.1rem;
  font-size: 0.8rem;
  color: #626159;
  line-height: 1.55;
}

/* Real-time Inline Image Figure Styling inside Streaming Pages */
.stream-image-figure {
  margin: 0.75rem auto;
  text-align: center;
}

.stream-image-figure.frame-soft-shadow img {
  box-shadow: 0 5px 16px rgba(0, 0, 0, 0.16);
}

.stream-image-figure.frame-vignette img {
  mask-image: radial-gradient(ellipse at center, black 65%, transparent 100%);
  -webkit-mask-image: radial-gradient(
    ellipse at center,
    black 65%,
    transparent 100%
  );
}

.stream-image-caption {
  margin-top: 0.35rem;
  font:
    italic 0.8rem Georgia,
    serif;
  color: #65645b;
  text-align: center;
}

/* Cover Studio — full-screen portrait Drawing Board (self-hosted Excalidraw, MIT) */
.cover-studio-entry {
  margin-top: 0.5rem;
  padding: 0.5rem 0.65rem;
  background: var(--surface-raised);
  border: 1px solid var(--hairline);
  border-radius: 10px;
  display: flex;
  align-items: center;
  gap: 0.55rem;
  flex-wrap: wrap;
}

.cover-studio-entry-hint {
  flex: 1 1 12rem;
  font-size: 0.72rem;
  color: var(--muted);
}

.cover-studio-dialog {
  width: 100vw;
  height: 100dvh;
  max-width: 100vw;
  max-height: 100dvh;
  padding: 0;
  border: none;
  background: var(--surface);
  color: var(--ink);
}

.cover-studio-dialog::backdrop {
  background: rgb(4 8 16 / 78%);
  backdrop-filter: blur(6px);
}

.cover-studio-frame {
  display: flex;
  flex-direction: column;
  height: 100%;
}

.cover-studio-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  flex-wrap: wrap;
  padding: 0.55rem 0.9rem;
  border-bottom: 1px solid var(--hairline);
  background: var(--surface-raised);
}

.cover-studio-heading h2 {
  margin: 0;
  font-size: 1.05rem;
}

.cover-studio-subtitle {
  margin: 0.15rem 0 0;
  font-size: 0.78rem;
  color: var(--muted);
}

.cover-studio-actions {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  flex-wrap: wrap;
}

/* Portrait stage: a centered 2:3 canvas that fills the dialog */
.cover-studio-stage {
  flex: 1;
  min-height: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0.75rem;
  overflow: hidden;
  background: color-mix(in srgb, var(--surface) 82%, #000 18%);
}

#drawing-board-mount {
  /* Fill the stage: the workable canvas area is the whole dialog, not a
     small portrait box adrift in dead space. The 6" x 9" trim guide
     inside the scene provides the portrait cover boundary. */
  width: 100%;
  height: 100%;
  border-radius: 12px;
  overflow: hidden;
  position: relative;
  box-shadow: 0 1.25rem 4rem rgb(0 0 0 / 45%);
  border: 1px solid var(--hairline);
}

.cover-studio-footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
  padding: 0.4rem 0.9rem;
  border-top: 1px solid var(--hairline);
  background: var(--surface-raised);
}

/* Strip Excalidraw chrome so the studio reads as a custom interface */
#cover-studio-dialog .excalidraw .layer-ui__wrapper__footer,
#cover-studio-dialog .excalidraw .layer-ui__wrapper__footer-left,
#cover-studio-dialog .excalidraw .layer-ui__wrapper__footer-right,
#cover-studio-dialog .excalidraw .footer-center,
#cover-studio-dialog .excalidraw .HintViewer,
#cover-studio-dialog .excalidraw .main-menu-trigger {
  display: none !important;
}

.studio-attribution {
  font-size: 0.72rem;
  color: var(--muted);
}

.studio-attribution-summary {
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  list-style: none;
  user-select: none;
}

.studio-attribution-summary::-webkit-details-marker {
  display: none;
}

.studio-attribution-body {
  margin-top: 0.45rem;
  padding: 0.6rem 0.8rem;
  background: color-mix(in srgb, var(--surface) 70%, transparent);
  border: 1px solid var(--hairline);
  border-radius: 6px;
  font-size: 0.74rem;
  line-height: 1.45;
}

.studio-attribution-body p {
  margin: 0 0 0.35rem;
}

.studio-attribution-body p:last-child {
  margin-bottom: 0;
}

.studio-attribution-body a {
  color: var(--accent);
  text-decoration: underline;
  text-underline-offset: 2px;
}

.studio-attribution-body code {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  background: var(--surface-raised);
  padding: 0.05rem 0.35rem;
  border-radius: 4px;
  border: 1px solid var(--hairline);
}

.studio-attribution-meta {
  font-style: italic;
  opacity: 0.75;
}

.studio-upload-btn {
  display: inline-flex;
  align-items: center;
  cursor: pointer;
  margin: 0;
}

.studio-upload-btn input {
  display: none;
}

.studio-bg-status {
  font-size: 0.8rem;
  color: var(--muted);
  font-style: italic;
}

/* Deterministic Book Flip Style 1: 3D Page Curl */
.page-procession.anim-flip-curl .stream-page.is-turned {
  transform: rotateY(-180deg) scale(0.96);
  opacity: 0;
  box-shadow: -24px 12px 35px rgba(0, 0, 0, 0.32);
}

/* Deterministic Book Flip Style 2: Slide & Layered Stack */
.page-procession.anim-flip-slide .stream-page.is-turned {
  transform: translateX(-108%) rotateZ(-2deg);
  opacity: 0;
  box-shadow: -15px 0 25px rgba(0, 0, 0, 0.25);
}

/* Deterministic Book Flip Style 3: 3D Sheet Fold */
.page-procession.anim-flip-turn .stream-page.is-turned {
  transform: rotateY(-120deg) translateZ(-40px);
  opacity: 0;
  box-shadow: -30px 0 40px rgba(0, 0, 0, 0.35);
}

.stream-page-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.4rem;
  font:
    700 clamp(0.6rem, 0.75vw, 0.72rem) / 1 ui-monospace,
    monospace;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.stream-page-state {
  color: var(--muted);
}

.stream-chapter-title {
  min-width: 0;
  margin: 0.2rem 0 0;
  overflow: hidden;
  font:
    600 clamp(1.25rem, 2.5vw, 1.85rem) / 1.15 Georgia,
    serif;
  letter-spacing: -0.015em;
  opacity: 0;
  transform: translateY(0.7rem);
  transition:
    opacity 620ms var(--ease-out, cubic-bezier(0.16, 1, 0.3, 1)),
    transform 620ms var(--ease-out, cubic-bezier(0.16, 1, 0.3, 1));
}

.stream-chapter-body {
  min-height: 0;
  overflow: hidden;
  overflow-wrap: anywhere;
  font:
    clamp(0.92rem, 1.25vw, 1.04rem) / 1.68 "Georgia",
    "Times New Roman",
    serif;
  letter-spacing: -0.003em;
  color: #22211d;
  white-space: pre-wrap;
}

.stream-chapter-body p {
  margin: 0 0 0.5rem;
  text-indent: 1.8em;
}

.stream-page.is-waiting {
  background: #ede9dc;
  box-shadow: none;
  color: var(--muted);
}

.stream-page.is-live {
  z-index: 2;
  border-color: #8c7853;
  box-shadow:
    inset 14px 0 24px -12px rgba(0, 0, 0, 0.08),
    0 10px 30px rgba(0, 0, 0, 0.16);
}

.stream-page.is-live .stream-chapter-title {
  opacity: 1;
  transform: translateY(0);
}

.stream-page.is-live .stream-chapter-body {
  overflow-y: auto;
  padding-right: 0.25rem;
  scrollbar-color: var(--hairline) transparent;
}

.stream-page.is-diffusing .stream-chapter-body:empty::before {
  display: block;
  width: min(72%, 28rem);
  height: 100%;
  min-height: 8rem;
  margin-inline: auto;
  background:
    radial-gradient(circle at 22% 28%, currentColor 0 1px, transparent 2px),
    radial-gradient(circle at 73% 42%, currentColor 0 1px, transparent 2px),
    radial-gradient(circle at 47% 76%, currentColor 0 1px, transparent 2px);
  background-size:
    3.2rem 3.2rem,
    4.6rem 4.6rem,
    5.8rem 5.8rem;
  content: "";
  opacity: 0.16;
  animation: mercury-field-forming 1.8s ease-in-out infinite alternate;
}

.diffusion-revision {
  display: inline;
  animation: mercury-denoise 640ms cubic-bezier(0.16, 1, 0.3, 1) both;
  transform-origin: center;
}

@keyframes mercury-field-forming {
  from {
    filter: blur(0.32rem);
    opacity: 0.08;
    transform: scale(0.985);
  }

  to {
    filter: blur(0.08rem);
    opacity: 0.24;
    transform: scale(1.015);
  }
}

@keyframes mercury-denoise {
  0% {
    filter: blur(0.28em);
    letter-spacing: 0.035em;
    opacity: 0.28;
    text-shadow:
      -0.06em 0 color-mix(in srgb, var(--accent) 42%, transparent),
      0.06em 0 color-mix(in srgb, var(--ink) 28%, transparent);
  }

  52% {
    filter: blur(0.075em);
    opacity: 0.76;
  }

  100% {
    filter: blur(0);
    letter-spacing: inherit;
    opacity: 1;
    text-shadow: none;
  }
}

.stream-page.is-live .stream-page-state {
  color: var(--accent-deep);
}

.stream-page.is-complete .stream-page-state {
  color: var(--success);
}

.stream-page.is-retrying {
  border-color: var(--danger);
  color: var(--danger);
}

.stream-meter {
  width: min(100%, 78rem);
  height: 3px;
  margin: 0.85rem auto 0;
  background: #c0beb3;
}

.stream-meter span {
  display: block;
  width: 0;
  height: 100%;
  background: var(--accent-deep);
  transition: width 180ms ease;
}

.stream-summary {
  width: min(100%, 78rem);
  margin: 0.55rem auto 0;
  color: var(--muted);
  font:
    0.72rem/1.4 ui-monospace,
    monospace;
}

.outputs-panel {
  background: #22231e;
  color: #f4f1e8;
}

.outputs-panel .step {
  color: #b9b8af;
}

.output-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 1px;
  border: 1px solid #6e6e65;
  background: #6e6e65;
}

.output-card {
  display: flex;
  min-height: 6.5rem;
  flex-direction: column;
  justify-content: space-between;
  gap: 0.55rem;
  padding: 0.85rem 0.95rem;
  background: #f4f1e8;
  color: var(--ink);
  text-decoration: none;
}

.output-card:hover {
  background: #e4ddcf;
}

.output-card.is-disabled,
.output-card.is-disabled:hover {
  border: 0;
  background: #d9d6cc;
  color: #707168;
  opacity: 1;
}

.output-card.is-disabled .output-format,
.output-card.is-disabled .output-description {
  color: #77786f;
}

.output-shelf-note {
  margin: 1rem 0 0;
  color: #b9b8af;
  font-size: 0.78rem;
}

.output-format {
  color: var(--accent-deep);
  font:
    800 0.72rem/1 ui-monospace,
    monospace;
  letter-spacing: 0.12em;
}

.output-name {
  font:
    600 1.15rem/1.2 Georgia,
    serif;
}

.output-description {
  color: #5c5d55;
  font-size: 0.76rem;
  line-height: 1.4;
}

.manuscript-panel {
  background: var(--paper);
}

.manuscript-heading {
  position: sticky;
  z-index: 6;
  top: 5.4rem;
  align-items: flex-end;
  padding-block: 0.85rem;
  background: color-mix(in srgb, var(--paper) 90%, transparent);
  backdrop-filter: blur(16px);
}

#chapter-navigation {
  display: flex;
  max-width: 56rem;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: 0.45rem;
}

#chapter-navigation a {
  padding: 0.35rem 0.5rem;
  border-bottom: 1px solid var(--hairline);
  color: var(--ink);
  font-size: 0.72rem;
  text-decoration: none;
}

.manuscript {
  max-width: 46rem;
  margin-inline: auto;
  font:
    1.02rem/1.75 Georgia,
    serif;
}

.manuscript > header {
  margin: 3rem 0 5rem;
  text-align: center;
}

.manuscript > header h3 {
  margin-bottom: 0.7rem;
  font:
    600 clamp(2rem, 5vw, 4rem)/1 Georgia,
    serif;
  letter-spacing: -0.03em;
  text-transform: none;
}

.manuscript-subtitle {
  max-width: 34rem;
  margin: 0.4rem auto 0;
  color: var(--muted);
  font-size: clamp(1rem, 1.8vw, 1.2rem);
  line-height: 1.4;
  text-wrap: balance;
}

.subtitle-italic {
  font-style: italic;
}

.manuscript-byline {
  margin: 1.8rem auto 0;
  font-family: var(--font-body);
  font-size: 0.78rem;
  font-weight: 650;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}

.byline-smallcaps {
  font-variant-caps: all-small-caps;
}

.manuscript-chapter {
  scroll-margin-top: 1rem;
  margin: 0 0 7rem;
}

.chapter-label {
  display: block;
  margin-bottom: 0.35rem;
  text-align: center;
  font: 650 0.68rem/1 var(--font-body);
  letter-spacing: 0.14em;
}

.chapter-eyebrow {
  color: var(--muted);
  text-transform: uppercase;
}

.chapter-rule {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  width: 14rem;
  max-width: 80%;
  margin: 0 auto 1.3rem;
  color: #34342f;
}

.chapter-rule::before,
.chapter-rule::after {
  height: 1px;
  flex: 1;
  background: currentColor;
  content: "";
}

.chapter-rule span {
  width: 0.6rem;
  height: 0.6rem;
  border-right: 1.2px solid currentColor;
  border-bottom: 1.2px solid currentColor;
  transform: rotate(45deg) translateY(-0.18rem);
}

.chapter-rule-chapter {
  margin-bottom: 1.15rem;
}

/* Title-page variant: same motif, a touch smaller and tighter so it sits
   politely below the title and above the subtitle / byline block. */
.title-page .chapter-rule {
  width: 11rem;
  margin: 1.6rem auto 0.5rem;
}

.title-page .chapter-rule span {
  width: 0.5rem;
  height: 0.5rem;
  border-right-width: 1px;
  border-bottom-width: 1px;
  transform: rotate(45deg) translateY(-0.16rem);
}

/* Full-page-bands title page: image is full-bleed background, text bands
   are absolutely positioned on the right half of the page. Matches the
   PDF rendering in render.ts drawFullPageBandsTitlePage(). */
.title-page-bands {
  position: relative;
  min-height: 100vh;
  overflow: hidden;
}

.title-page-bg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  z-index: 0;
}

.title-page-band {
  position: absolute;
  right: 0;
  width: 45%;
  padding: 0.6rem 1.2rem;
  background: rgba(0, 0, 0, 0.3);
  color: #fff;
  z-index: 1;
}

.title-page-band-title {
  top: 32%;
}

.title-page-band-title h1 {
  margin: 0;
  font:
    600 1.6rem/1.2 Georgia,
    serif;
  letter-spacing: -0.01em;
}

.title-page-band-subtitle {
  top: 47%;
  font:
    400 0.95rem/1.35 "IBM Plex Sans",
    sans-serif;
}

.title-page-band-byline {
  top: 62%;
  font:
    500 0.75rem/1.3 "IBM Plex Sans",
    sans-serif;
  letter-spacing: 0.05em;
  text-transform: uppercase;
}

.manuscript-chapter .chapter-title {
  margin: 0 0 3rem;
  text-align: center;
  font-family: var(--font-display);
  font-size: clamp(1.65rem, 3.2vw, 2.15rem);
  font-weight: 600;
  line-height: 1.1;
  letter-spacing: -0.018em;
  text-wrap: balance;
}

.manuscript-chapter p {
  margin: 0;
  text-indent: 2em;
}

.chapter-end {
  display: flex;
  align-items: center;
  gap: 0.45rem;
  width: 5.5rem;
  margin: 2.2rem auto 0;
  color: #55554f;
}

.chapter-end::before,
.chapter-end::after {
  height: 1px;
  flex: 1;
  background: currentColor;
  content: "";
}

.chapter-end span {
  width: 0.42rem;
  height: 0.42rem;
  border-right: 1px solid currentColor;
  border-bottom: 1px solid currentColor;
  transform: rotate(45deg) translateY(-0.13rem);
}

.provider-dialog {
  width: min(42rem, calc(100vw - 2rem));
  max-height: calc(100vh - 2rem);
  overflow: auto;
  padding: 0;
  border: 1px solid #77776e;
  background: var(--paper);
  color: var(--ink);
}

.provider-dialog::backdrop {
  background: rgb(21 22 18 / 62%);
  backdrop-filter: blur(2px);
}

.provider-dialog form {
  padding: clamp(1.25rem, 4vw, 2.4rem);
}

.beginner-links {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1px;
  margin: 1.4rem 0 1.8rem;
  border: 1px solid var(--hairline);
  background: var(--hairline);
}

.beginner-links a {
  padding: 0.85rem;
  background: #e8e5da;
  color: var(--accent-deep);
  font-size: 0.8rem;
  font-weight: 700;
  text-align: center;
}

.provider-dialog label:not(.remember-row) {
  margin-top: 1rem;
}

.combobox-wrap {
  position: relative;
}

.provider-options {
  position: absolute;
  z-index: 10;
  top: calc(100% - 1px);
  right: 0;
  left: 0;
  max-height: 18rem;
  overflow: auto;
  border: 1px solid #8f8f85;
  background: var(--paper);
  box-shadow: 0 12px 24px rgb(37 35 27 / 14%);
}

.provider-option {
  display: grid;
  width: 100%;
  grid-template-columns: 1fr auto;
  gap: 0.35rem 1rem;
  padding: 0.78rem;
  border: 0;
  border-bottom: 1px solid #d0cec3;
  background: transparent;
  text-align: left;
}

.provider-option:hover,
.provider-option.is-active,
.provider-option[aria-selected="true"] {
  background: #e6e2d6;
}

.provider-option.is-active {
  outline: 2px solid var(--accent);
  outline-offset: -2px;
}

.provider-option small {
  grid-column: 1 / -1;
  color: var(--muted);
  font-weight: 500;
}

.provider-option .support-state {
  color: var(--success);
  font:
    700 0.65rem/1 ui-monospace,
    monospace;
}

.provider-option .support-state.advanced {
  color: #8a5d22;
}

.field-hint {
  max-width: 68ch;
  margin: 0.45rem 0 0;
  color: var(--muted);
  font-size: 0.78rem;
  line-height: 1.45;
}

.key-actions,
.dialog-actions {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
}

.key-actions {
  margin-top: 0.6rem;
  font-size: 0.78rem;
}

.key-actions a,
a {
  color: var(--accent-deep);
  text-underline-offset: 0.18em;
}

.remember-row {
  display: flex;
  align-items: center;
  gap: 0.65rem;
  margin-top: 1.25rem;
}

.remember-row input {
  width: auto;
}

.security-note {
  padding-left: 1.75rem;
}

.provider-note {
  min-height: 1.25rem;
  color: var(--danger);
}

.dialog-actions {
  margin-top: 1.6rem;
  padding-top: 1.2rem;
  border-top: 1px solid var(--hairline);
}

.error-panel,
.warning-panel {
  margin-top: 1.2rem;
  padding: 1rem;
  border: 1px solid var(--danger);
  background: #f4dad5;
  color: #73271f;
  font-size: 0.82rem;
}

.warning-panel {
  border-color: #9a6d36;
  background: #eee0c6;
  color: #5c3c17;
}

@media (min-width: 980px) {
  body.is-generating .book-workspace {
    position: sticky;
    z-index: 2;
    top: 0;
  }
}

@media (max-width: 860px) {
  .masthead,
  .panel-heading,
  .workspace-heading,
  .manuscript-heading {
    align-items: flex-start;
    flex-direction: column;
  }

  .field-grid,
  .output-grid,
  .beginner-links {
    grid-template-columns: 1fr;
  }

  .field-wide {
    grid-column: auto;
  }

  .stream-book {
    height: 58vh;
    min-height: 20rem;
    padding: 0.8rem;
  }

  .stream-heading {
    align-items: flex-start;
  }

  .stream-state {
    max-width: 45%;
  }

  .page-procession {
    gap: 0.75rem;
    transform: translateX(calc(var(--page-index, 0) * -94%));
  }

  .stream-page {
    min-width: 91%;
    padding: 1rem;
  }

  #chapter-navigation {
    width: 100%;
    max-width: none;
    flex-wrap: nowrap;
    justify-content: flex-start;
    gap: 0.35rem;
    overflow-x: auto;
    padding-bottom: 0.4rem;
    scroll-snap-type: x proximity;
    scrollbar-color: var(--hairline) transparent;
  }

  #chapter-navigation a {
    min-width: 2.35rem;
    flex: 0 0 auto;
    text-align: center;
    scroll-snap-align: start;
  }

  .manuscript-heading {
    top: 4.7rem;
    gap: 0.65rem;
    padding-block: 0.7rem;
  }
}

/* Keep legacy component rules bound to the active theme. */
html body {
  color: var(--ink);
  background: var(--paper);
}

:root[data-theme="daylight"] body,
:root[data-theme="daylight"] .book-workspace,
:root[data-theme="daylight"] .manuscript-panel {
  background: var(--daylight-ocean-bg) fixed !important;
  background-attachment: fixed !important;
}

body .masthead,
body .editor-panel,
body .book-workspace,
body .outline-rundown,
body .stream-book,
body .outputs-panel,
body .manuscript-panel,
body .provider-dialog,
body .provider-option,
body input,
body select,
body textarea {
  color: var(--ink);
  background: var(--surface);
  border-color: var(--hairline);
}

body .stream-page,
body .output-card {
  color: var(--ink);
  background: var(--surface-raised);
  border-color: var(--hairline);
}

body .primary {
  color: var(--accent-ink);
  background: var(--accent);
  border-color: var(--accent);
}

body .editor-panel {
  padding: 0;
  overflow: clip;
}

body .engine-status {
  color: var(--muted);
  background: var(--surface);
  border-color: var(--hairline);
}

body .engine-status.is-ready {
  color: var(--ink);
  background: var(--surface);
  border-color: var(--success);
}

body .output-grid {
  grid-template-columns: repeat(3, minmax(0, 1fr));
}

@media (max-width: 860px) {
  body .output-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

/* Borderless workbench: hierarchy comes from spacing, surface, and elevation. */
body .masthead,
body .panel,
body .book-workspace,
body .editor-panel,
body .editor-panel > form,
body .book-options,
body .outline-rundown,
body .rundown-item,
body .stream-book,
body .stream-page,
body .outputs-panel,
body .output-card,
body .manuscript-panel,
body .provider-dialog,
body .provider-option,
body .dialog-heading,
body .engine-status,
body .engine-status.is-ready,
body .theme-toggle,
body input,
body select,
body textarea,
body button,
body .error-panel,
body .warning-panel {
  border: 0;
}

body .engine-status,
body .engine-status.is-ready {
  box-shadow: none;
}

body .status-dot {
  border: 0;
}

body .output-card:not(.is-disabled):hover {
  border-color: transparent;
}

body .output-card.output-secondary {
  margin-top: 1.25rem;
}

body .output-card.output-secondary + .output-card.output-secondary {
  margin-top: 1.25rem;
}

@media (max-width: 860px) {
  body .output-grid {
    grid-template-columns: minmax(0, 1fr);
    grid-auto-rows: 1fr;
  }

  body .output-card.output-secondary + .output-card.output-secondary {
    margin-top: 0;
  }
}

/* Editorial type system. Font files are bundled with the app so local and
   hosted builds render the same hierarchy without a third-party request. */
@font-face {
  font-family: "IBM Plex Sans";
  src: url("/fonts/ibm-plex-sans-latin-400-normal.woff2") format("woff2");
  font-style: normal;
  font-weight: 400;
  font-display: swap;
}

@font-face {
  font-family: "IBM Plex Sans";
  src: url("/fonts/ibm-plex-sans-latin-500-normal.woff2") format("woff2");
  font-style: normal;
  font-weight: 500;
  font-display: swap;
}

@font-face {
  font-family: "IBM Plex Sans";
  src: url("/fonts/ibm-plex-sans-latin-600-normal.woff2") format("woff2");
  font-style: normal;
  font-weight: 600;
  font-display: swap;
}

@font-face {
  font-family: "IBM Plex Sans";
  src: url("/fonts/ibm-plex-sans-latin-700-normal.woff2") format("woff2");
  font-style: normal;
  font-weight: 700;
  font-display: swap;
}

@font-face {
  font-family: "Literata";
  src: url("/fonts/literata-latin-400-normal.woff2") format("woff2");
  font-style: normal;
  font-weight: 400;
  font-display: swap;
}

@font-face {
  font-family: "Literata";
  src: url("/fonts/literata-latin-600-normal.woff2") format("woff2");
  font-style: normal;
  font-weight: 600;
  font-display: swap;
}

/* Token consolidation (Phase 1, idea2Lit UI redesign). All font and theme
 * tokens are declared exactly once in the :root block at the top of this
 * stylesheet. Do not add additional :root blocks below this comment; if a
 * component needs a derived value, define it as a derived custom property
 * inside the component's own selector. */

body,
button,
input,
select,
textarea {
  font-family: var(--font-body);
}

h1,
h2,
.masthead h1,
.editor-panel > summary,
.stream-book h3,
.rundown-title,
.stream-chapter-title,
.output-name,
.manuscript > header h3,
.manuscript-chapter .chapter-title,
.provider-dialog h2 {
  font-family: var(--font-display);
  font-kerning: normal;
  font-optical-sizing: auto;
  text-wrap: balance;
}

.masthead h1 {
  gap: 0.8rem;
  font-size: clamp(2rem, 3.7vw, 4.15rem);
  font-weight: 700;
  line-height: 0.94;
  letter-spacing: -0.035em;
}

.masthead h1 small {
  font-family: var(--font-body);
  font-size: clamp(0.68rem, 0.75vw, 0.82rem);
  font-weight: 600;
  letter-spacing: 0.08em;
}

h2,
.workspace-heading h2,
.panel-heading h2 {
  font-size: clamp(1.7rem, 2.8vw, 2.5rem);
  font-weight: 600;
  line-height: 1.05;
  letter-spacing: -0.025em;
}

h3 {
  font-family: var(--font-body);
  font-weight: 600;
}

.editor-panel > summary {
  font-size: clamp(1.15rem, 1.4vw, 1.35rem);
  font-weight: 600;
  line-height: 1.2;
  letter-spacing: -0.012em;
}

button,
.output-description,
.progress,
.stream-status,
.security-note,
.provider-note,
.dialog-intro {
  font-weight: 500;
}

.engine-status,
.step,
.stream-state,
.rundown-label,
.rundown-number,
.stream-page-header,
.output-format,
.chapter-label,
.provider-option .support-state {
  font-family: var(--font-body);
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  letter-spacing: 0.08em;
}

.stream-book h3 {
  font-size: clamp(1.2rem, 1.8vw, 1.55rem);
  font-weight: 600;
  line-height: 1.1;
  letter-spacing: -0.018em;
}

.rundown-title {
  font-size: clamp(2.35rem, 5.3vw, 4.8rem);
  font-weight: 600;
  line-height: 0.94;
  letter-spacing: -0.035em;
}

.stream-chapter-title {
  font-size: clamp(1.55rem, 3.2vw, 2.85rem);
  font-weight: 600;
  line-height: 1.02;
  letter-spacing: -0.025em;
}

.rundown-subtitle,
.stream-chapter-body,
.manuscript {
  font-family: var(--font-reading);
  font-optical-sizing: auto;
}

.stream-chapter-body {
  font-size: clamp(0.94rem, 1.35vw, 1.06rem);
  line-height: 1.62;
}

.manuscript {
  max-width: 68ch;
  font-size: 1.03rem;
  line-height: 1.72;
}

.output-format {
  font-size: 0.7rem;
}

.output-name {
  font-size: clamp(1.15rem, 1.4vw, 1.32rem);
  font-weight: 600;
  line-height: 1.12;
  letter-spacing: -0.012em;
}

.output-description {
  font-size: 0.8rem;
  line-height: 1.5;
}

@media (max-width: 640px) {
  .masthead h1 {
    gap: 0.55rem;
    font-size: clamp(1.85rem, 10vw, 2.65rem);
  }

  .masthead h1 small {
    font-size: 0.62rem;
    letter-spacing: 0.06em;
  }
}

/* Complete theme contract: every working surface resolves through these
   tokens so daylight and night mode remain equally readable. */
:root {
  --surface-soft: #1a2940;
  --surface-strong: #22334d;
  --disabled-surface: #172338;
  --disabled-ink: #8290a4;
  --overlay: rgb(2 8 18 / 78%);
  --error-surface: #381c24;
  --error-ink: #ffbeb8;
  --warning-surface: #352916;
  --warning-ink: #f2d29b;
  --theme-duration: 560ms;
}

:root[data-theme="daylight"] {
  --surface-soft: #e7edf5;
  --surface-strong: #dbe5f0;
  --disabled-surface: #e4e8ed;
  --disabled-ink: #687383;
  --overlay: rgb(17 26 39 / 56%);
  --error-surface: #f8dfdc;
  --error-ink: #762821;
  --warning-surface: #f3e7cf;
  --warning-ink: #684315;
}

body,
.masthead,
.panel,
.book-workspace,
.editor-panel,
.editor-panel > form,
.book-options,
.stream-book,
.outline-rundown,
.stream-page,
.stream-meter,
.outputs-panel,
.output-card,
.manuscript-panel,
.provider-dialog,
.provider-dialog form,
.provider-options,
.provider-option,
.beginner-links,
.beginner-links a,
.error-panel,
.warning-panel,
button,
input,
select,
textarea,
a,
.theme-moon::after,
.status-dot::after {
  transition:
    color var(--theme-duration) var(--ease-out),
    background-color var(--theme-duration) var(--ease-out),
    border-color var(--theme-duration) var(--ease-out),
    box-shadow var(--theme-duration) var(--ease-out),
    fill var(--theme-duration) var(--ease-out),
    stroke var(--theme-duration) var(--ease-out);
}

body .masthead,
body .panel,
body .editor-panel,
body .editor-panel > form,
body .book-options,
body .book-workspace,
body .outline-rundown,
body .stream-book,
body .outputs-panel,
body .manuscript-panel {
  color: var(--ink);
  background-color: var(--paper);
}

body .editor-panel,
body .stream-book,
body .provider-dialog,
body .provider-dialog form {
  background-color: var(--surface);
}

body input,
body select,
body textarea,
body input[readonly],
body .provider-options,
body .provider-option {
  color: var(--ink);
  background-color: var(--surface-raised);
}

body input[readonly] {
  color: var(--muted);
}

body input::placeholder,
body textarea::placeholder {
  color: var(--muted);
  opacity: 0.82;
}

.idea-input::placeholder {
  transition:
    opacity 880ms var(--ease-in-out),
    color var(--theme-duration) var(--ease-out);
}

.provider-dialog {
  width: min(44rem, calc(100vw - 2rem));
  max-height: calc(100dvh - 2rem);
  border-radius: 0.75rem;
  box-shadow: 0 1.5rem 4rem rgb(0 0 0 / 36%);
}

.provider-dialog::backdrop {
  background: var(--overlay);
  backdrop-filter: blur(8px);
}

.provider-dialog .dialog-intro,
.provider-dialog .security-note,
.provider-dialog label span,
.provider-option small {
  color: var(--muted);
}

.beginner-links {
  gap: 0.75rem;
  border: 0;
  background: transparent;
}

.beginner-links a {
  min-height: 3rem;
  display: grid;
  place-items: center;
  padding: 0.8rem 1rem;
  border-radius: 0.45rem;
  color: var(--accent);
  background: var(--surface-soft);
  text-decoration: none;
}

.beginner-links a:hover,
.provider-option:hover,
.provider-option.is-active,
.provider-option[aria-selected="true"] {
  color: var(--ink);
  background: var(--surface-soft);
}

.provider-option .support-state.advanced {
  color: var(--warning);
}

.provider-note {
  color: var(--danger);
}

.error-panel {
  color: var(--error-ink);
  background: var(--error-surface);
}

.warning-panel {
  color: var(--warning-ink);
  background: var(--warning-surface);
}

.engine-status.is-streaming {
  color: var(--accent);
  background: var(--surface-soft);
}

.engine-status.is-error {
  color: var(--error-ink);
  background: var(--error-surface);
  animation: api-error-signal 720ms var(--ease-in-out) infinite;
}

.engine-status.is-error .status-dot {
  background: var(--danger);
  box-shadow: 0 0 0.8rem color-mix(in srgb, var(--danger) 64%, transparent);
}

@keyframes api-error-signal {
  0%,
  100% {
    filter: brightness(0.82);
  }
  50% {
    filter: brightness(1.28);
  }
}

/* Output dock: compact publication actions, not a wall of card-buttons. */
body .outputs-panel {
  background: var(--surface);
}

.outputs-panel .panel-heading,
.outputs-panel .output-grid,
.outputs-panel #build-notices,
.outputs-panel .output-shelf-note {
  width: min(100%, 78rem);
  margin-inline: auto;
}

body .output-grid {
  display: grid;
  grid-template-columns: repeat(6, minmax(0, 1fr));
  gap: 1rem 1.5rem;
  border: 0;
  background: transparent;
}

body .output-card,
body .output-card.is-disabled,
body .output-card.is-disabled:hover {
  position: relative;
  display: grid;
  min-width: 0;
  min-height: 4.75rem;
  grid-column: span 2;
  grid-template-columns: minmax(0, 1fr) 2.7rem;
  grid-template-rows: auto auto auto;
  gap: 0.18rem 0.8rem;
  align-content: center;
  padding: 0.85rem 0;
  color: var(--ink);
  background: transparent;
  border-radius: 0;
  text-align: left;
  opacity: 1;
  filter: none;
}

body .output-card.is-disabled {
  color: var(--disabled-ink);
  cursor: not-allowed;
}

body .output-card.is-disabled::after {
  content: "–";
  color: var(--disabled-ink);
  background: var(--disabled-surface);
}

body .output-card:not(.is-disabled):hover {
  color: var(--accent);
  transform: none;
}

body .output-card:not(.is-disabled):hover::after {
  transform: translateY(0.18rem);
}

body .output-card.output-secondary,
body .output-card.output-secondary + .output-card.output-secondary {
  min-height: 3.8rem;
  grid-column: span 3;
  margin-top: 0.75rem;
}

.output-card .output-format,
.output-card .output-name,
.output-card .output-description {
  min-width: 0;
  grid-column: 1;
}

body .output-card.is-disabled .output-format,
body .output-card.is-disabled .output-description,
.outputs-panel .step,
.output-shelf-note {
  color: var(--disabled-ink);
}

.output-description {
  max-width: 38ch;
}

/* Fluid geometry from compact portrait phones through short landscape and 4K. */
.masthead,
.panel,
.book-workspace {
  padding-right: calc(clamp(1rem, 5vw, 5rem) + env(safe-area-inset-right));
  padding-left: calc(clamp(1rem, 5vw, 5rem) + env(safe-area-inset-left));
}

.masthead {
  padding-top: calc(clamp(1.2rem, 3vw, 2.4rem) + env(safe-area-inset-top));
}

.masthead > *,
.masthead-actions,
.panel-heading > *,
.workspace-heading > *,
.dialog-heading > *,
.field-grid > *,
.stream-heading > * {
  min-width: 0;
}

.stream-book {
  height: clamp(22rem, 64dvh, 44rem);
}

button,
.output-card,
.beginner-links a,
#chapter-navigation a {
  min-height: 44px;
}

@media (max-width: 900px) {
  body .output-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  body .output-card,
  body .output-card.is-disabled,
  body .output-card.is-disabled:hover,
  body .output-card.output-secondary,
  body .output-card.output-secondary + .output-card.output-secondary {
    grid-column: span 1;
    margin-top: 0;
  }
}

@media (max-width: 640px) {
  .masthead {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: center;
  }

  .masthead h1 {
    min-width: 0;
  }

  .masthead-actions {
    justify-content: flex-end;
  }

  .engine-status {
    max-width: 9.5rem;
  }

  /* Never truncate the live provider state into ambiguity: allow the label
     to wrap onto a second line so “Cerebras · zai-glm-4.7” stays readable. */
  #provider-status-text {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    overflow: visible;
    text-align: left;
    line-height: 1.25;
  }

  .provider-status-provider,
  .provider-status-model {
    white-space: normal;
    overflow-wrap: anywhere;
  }

  .field-grid,
  .beginner-links,
  body .output-grid {
    grid-template-columns: minmax(0, 1fr);
  }

  .provider-dialog {
    width: calc(100vw - 0.75rem);
    max-height: calc(100dvh - 0.75rem);
    margin: auto;
    border-radius: 0.65rem;
  }

  .provider-dialog form {
    padding: max(1rem, env(safe-area-inset-top))
      calc(1rem + env(safe-area-inset-right))
      max(1rem, env(safe-area-inset-bottom))
      calc(1rem + env(safe-area-inset-left));
  }

  .key-actions,
  .dialog-actions {
    align-items: stretch;
    flex-direction: column;
  }

  .dialog-actions .primary,
  .dialog-actions .secondary {
    width: 100%;
  }

  .stream-heading {
    align-items: flex-start;
    flex-direction: column;
  }

  /* Full-page-bands title page: bands go full-width on narrow screens. */
  .title-page-band {
    width: 100%;
    right: 0;
  }

  .title-page-band-title h1 {
    font-size: 1.35rem;
  }

  .stream-state {
    max-width: none;
    text-align: left;
  }
}

@media (max-width: 380px) {
  .masthead {
    grid-template-columns: minmax(0, 1fr);
  }

  .masthead-actions {
    justify-content: space-between;
  }

  .engine-status {
    max-width: none;
  }

  .panel,
  .book-workspace {
    padding-top: 1.25rem;
    padding-bottom: 1.25rem;
  }
}

@media (max-height: 600px) and (orientation: landscape) {
  .provider-dialog {
    max-height: calc(100dvh - 0.5rem);
  }

  .stream-book {
    height: 72dvh;
    min-height: 18rem;
  }
}

@media (hover: none), (pointer: coarse) {
  button,
  .output-card,
  .beginner-links a,
  #chapter-navigation a {
    min-height: 48px;
  }
}

/* Brand-and-header refinement. The header stays dimensionally stable while
   provider state changes, and the supplied app mark swaps with the theme.
   (All tokens are declared in the consolidated :root block at the top.)

   Spec §10 — header uses EITHER a restrained bottom rule OR a subtle shadow
   (not both). We use the bottom rule so the surface stays quiet and the
   page procession below reads as one continuous region. */

.masthead {
  position: sticky;
  top: 0;
  z-index: 50;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: 1rem;
  min-height: 4.25rem;
  padding-top: calc(0.65rem + env(safe-area-inset-top));
  padding-bottom: 0.65rem;
  padding-inline: calc(1rem + env(safe-area-inset-left))
    calc(1rem + env(safe-area-inset-right));
  background: var(--header-surface);
  border-bottom: 1px solid var(--header-rule);
  backdrop-filter: blur(14px);
}

.brand-lockup {
  display: flex;
  min-width: 0;
  align-items: center;
  gap: 0.85rem;
}

.brand-symbol {
  position: relative;
  width: 3.25rem;
  height: 3.25rem;
  flex: 0 0 3.25rem;
  overflow: hidden;
  border-radius: 24%;
  box-shadow: 0 0.35rem 1rem rgb(0 0 0 / 22%);
}

.brand-mark {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: opacity var(--theme-duration) var(--ease-out);
}

.brand-mark-daylight {
  opacity: 0;
}

:root[data-theme="daylight"] .brand-mark-night {
  opacity: 0;
}

:root[data-theme="daylight"] .brand-mark-daylight {
  opacity: 1;
}

.masthead h1 {
  gap: 0.65rem;
  font-family: var(--font-display);
  font-size: clamp(1.65rem, 3vw, 2.8rem);
  font-weight: 700;
  line-height: 1;
  letter-spacing: -0.03em;
}

.masthead h1 small {
  color: var(--muted);
  font-family: var(--font-body);
  font-size: clamp(0.64rem, 0.78vw, 0.76rem);
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: none;
}

.masthead-actions {
  flex: 0 0 auto;
  justify-content: flex-end;
}

body .engine-status {
  width: 8.6rem;
  min-width: 8.6rem;
  justify-content: center;
  color: var(--muted);
  background: transparent;
}

body .engine-status.is-ready {
  color: var(--success);
  background: color-mix(in srgb, var(--success) 10%, transparent);
}

body .engine-status.is-ready .status-dot {
  background: var(--success);
  box-shadow: 0 0 0.85rem color-mix(in srgb, var(--success) 62%, transparent);
}

body .engine-status.is-configured {
  color: var(--accent);
  background: color-mix(in srgb, var(--accent) 8%, transparent);
}

body .engine-status.is-configured .status-dot {
  background: currentColor;
}

#provider-status-text {
  display: inline-flex;
  align-items: baseline;
  max-width: 100%;
  overflow: hidden;
}

.provider-status-provider {
  flex: 0 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.provider-status-model {
  flex: 0 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--muted);
  font-weight: 500;
}

/* Key indicator sits under the password field, aligned with the label. */
.provider-key-status {
  margin: 0.35rem 0 0;
  min-height: 1.25em;
  font-size: 0.82rem;
  line-height: 1.4;
  color: var(--muted);
}

.provider-key-saved {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  color: var(--success);
  font-weight: 600;
}

.provider-key-check {
  font-size: 1.05em;
  line-height: 1;
}

.provider-key-missing {
  color: var(--muted);
}

/* The form remains native and keyboard-operable; JavaScript animates its
   measured height so both disclosure directions are smooth. */
.editor-panel > form {
  transform-origin: top center;
  will-change: height, opacity, transform;
}

.prompt-actions {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
  align-items: center;
  gap: 0.6rem 0.8rem;
}

#enhance-prompt {
  grid-column: 2;
  justify-self: center;
}

#restore-prompt {
  grid-column: 3;
  justify-self: start;
}

#prompt-state {
  grid-column: 1 / -1;
  justify-self: center;
  text-align: center;
}

h1,
h2,
.editor-panel > summary,
.stream-book h3,
.rundown-title,
.stream-chapter-title,
.output-name,
.manuscript > header h3,
.manuscript-chapter .chapter-title,
.provider-dialog h2 {
  font-family: var(--font-display);
}

.output-name {
  font-weight: 650;
  letter-spacing: -0.015em;
}

/* Output actions stay flat and calm. Hover is a color confirmation only—no
   bounce, slide, lift, or container fill. */
body .output-card {
  transform: none;
}

body .output-card:not(.is-disabled):hover {
  color: var(--ink);
  background: transparent;
  transform: none;
}

body .output-card:not(.is-disabled):hover .output-format {
  color: var(--accent);
}

body .output-card:not(.is-disabled):hover::after {
  color: var(--accent-ink);
  background: var(--accent);
  transform: none;
}

@media (max-width: 640px) {
  .masthead {
    grid-template-columns: minmax(0, 1fr) auto;
    min-height: 4.7rem;
    padding-top: calc(0.6rem + env(safe-area-inset-top));
    padding-bottom: 0.6rem;
  }

  .brand-lockup {
    gap: 0.55rem;
  }

  .brand-symbol {
    width: 2.65rem;
    height: 2.65rem;
    flex-basis: 2.65rem;
  }

  .masthead h1 {
    gap: 0.42rem;
    font-size: clamp(1.25rem, 6.6vw, 1.9rem);
  }

  .masthead h1 small {
    font-size: 0.58rem;
  }

  body .engine-status {
    width: auto;
    max-width: 9.5rem;
    min-width: 0;
    padding-inline: 0.55rem;
  }

  .prompt-actions {
    grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
  }
}

@media (max-width: 420px) {
  .masthead {
    grid-template-columns: minmax(0, 1fr) auto;
    gap: 0.55rem;
    padding-right: calc(0.75rem + env(safe-area-inset-right));
    padding-left: calc(0.75rem + env(safe-area-inset-left));
  }

  .brand-symbol {
    width: 2.35rem;
    height: 2.35rem;
    flex-basis: 2.35rem;
  }

  .masthead h1 {
    display: block;
    font-size: 1.22rem;
  }

  .masthead h1 small {
    display: block;
    margin-top: 0.16rem;
  }

  .masthead-actions {
    justify-content: flex-end;
  }

  body .engine-status {
    width: auto;
    max-width: 8rem;
    min-width: 0;
    font-size: 0.68rem;
  }
}

/* Stable completion instrumentation and portrait-oriented reading surfaces. */
.completion-metrics {
  display: grid;
  width: min(100%, 78rem);
  min-height: 4.25rem;
  grid-template-columns: minmax(0, 1fr);
  gap: 1px;
  margin: 0.75rem auto 0;
  padding: 0;
  overflow: hidden;
  background: var(--hairline);
  opacity: 0;
  visibility: hidden;
  transition:
    opacity 460ms var(--ease-out),
    visibility 0s linear 460ms;
}

.completion-metrics.is-visible {
  opacity: 1;
  visibility: visible;
  transition-delay: 0s;
}

.completion-metrics > div {
  display: grid;
  min-width: 0;
  align-content: center;
  gap: 0.3rem;
  padding: 0.75rem 1rem;
  background: var(--surface);
}

.completion-metrics dt {
  color: var(--muted);
  font-family: var(--font-mono);
  font-size: 0.66rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.completion-metrics dd {
  margin: 0;
  overflow-wrap: anywhere;
  color: var(--ink);
  font-family: var(--font-body);
  font-size: clamp(0.8rem, 1.5vw, 1rem);
  font-variant-numeric: tabular-nums;
}

.completion-metrics.is-visible > div {
  animation: completion-metric-pop 520ms cubic-bezier(0.16, 1, 0.3, 1) both;
}

@keyframes completion-metric-pop {
  0% {
    opacity: 0;
    transform: scale(0.975);
  }
  58% {
    opacity: 1;
    transform: scale(1.018);
  }
  100% {
    opacity: 1;
    transform: scale(1);
  }
}

.book-workspace[data-generation-state="generating"] .stream-state {
  color: var(--accent);
}

.book-workspace[data-generation-state="complete"] .stream-state {
  color: var(--success);
}

.stream-book {
  height: clamp(34rem, 76dvh, 52rem);
  max-width: 70rem;
}

.stream-page {
  padding-inline: clamp(1.25rem, 6vw, 4.5rem);
}

.stream-chapter-body {
  max-width: 70ch;
  margin-inline: auto;
}

.manuscript-panel {
  overflow: visible;
}

.manuscript-heading {
  position: static;
  padding-bottom: 1.5rem;
  background: transparent;
  backdrop-filter: none;
}

.manuscript-layout {
  display: grid;
  max-width: 76rem;
  grid-template-columns: minmax(11rem, 15rem) minmax(0, 46rem);
  gap: clamp(2rem, 6vw, 6rem);
  align-items: start;
  margin-inline: auto;
}

.chapter-sidebar {
  position: sticky;
  top: 6.6rem;
  max-height: calc(100dvh - 8rem);
  overflow: auto;
}

.chapter-sidebar h3 {
  margin: 0 0 0.65rem;
  color: var(--muted);
  font-family: var(--font-mono);
  font-size: 0.68rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

#chapter-navigation {
  display: grid;
  max-width: none;
  gap: 0;
}

#chapter-navigation a {
  display: grid;
  min-width: 0;
  grid-template-columns: 2.2rem minmax(0, 1fr);
  align-items: baseline;
  gap: 0.55rem;
  padding: 0.7rem 0;
  border-bottom: 1px solid var(--hairline);
  overflow-wrap: anywhere;
}

.chapter-nav-number {
  color: var(--accent);
  font-family: var(--font-mono);
  font-size: 0.68rem;
}

.chapter-nav-title {
  font-family: var(--font-body);
  font-size: 0.8rem;
  line-height: 1.3;
}

.manuscript {
  width: 100%;
  min-width: 0;
  margin: 0;
}

.manuscript-image {
  margin: 1.75rem auto;
  break-inside: avoid;
  text-align: center;
}

.manuscript-image-60 {
  width: 60%;
}
.manuscript-image-80 {
  width: 80%;
}
.manuscript-image-100 {
  width: 100%;
}

.manuscript-image img {
  display: block;
  width: 100%;
  max-height: min(60dvh, 34rem);
  object-fit: contain;
}

.manuscript-image figcaption {
  margin-top: 0.55rem;
  color: var(--muted);
  font-family: var(--font-body);
  font-size: 0.78rem;
  line-height: 1.45;
}

/* Inline image triggers live directly under the fields they affect
   (working title for the cover image, chapter count for body images).
   They are intentionally compact: a label and a small secondary button. */
.field-image-row {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  margin-top: 0.55rem;
  font-family: var(--font-body);
  font-size: 0.78rem;
  color: var(--muted);
  flex-wrap: wrap;
}

.field-image-label {
  letter-spacing: 0.05em;
  text-transform: uppercase;
  font-weight: 600;
  color: var(--ink);
}

.field-image-row button.compact {
  padding: 0.32rem 0.7rem;
  font-size: 0.8rem;
  border-radius: 0.4rem;
}

/* The "Added images" shelf shows everything the user has staged with
   thumbnails, role/placement labels, and a per-item remove control. */
.image-shelf {
  margin-top: 1.4rem;
  padding-top: 1.2rem;
  border-top: 1px solid var(--hairline);
}

.image-shelf h4 {
  margin: 0 0 0.35rem;
  font-family: var(--font-chapter);
  font-size: 0.95rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--ink);
}

.image-shelf-help {
  margin: 0 0 0.7rem;
  color: var(--muted);
  font-size: 0.82rem;
}

.image-shelf-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
  gap: 0.55rem;
}

.image-shelf-item {
  display: grid;
  grid-template-columns: 3.2rem 1fr auto;
  align-items: center;
  gap: 0.75rem;
  padding: 0.45rem 0.6rem;
  border: 1px solid var(--hairline);
  border-radius: 0.55rem;
  background: var(--surface-raised);
}

.image-shelf-thumb {
  width: 3.2rem;
  height: 3.2rem;
  object-fit: cover;
  border-radius: 0.4rem;
  display: block;
}

.image-shelf-meta {
  display: flex;
  flex-direction: column;
  min-width: 0;
  font-family: var(--font-body);
  font-size: 0.85rem;
  color: var(--ink);
}

.image-shelf-meta strong {
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.image-shelf-sub {
  color: var(--muted);
  font-size: 0.75rem;
}

.image-shelf-remove {
  font-size: 0.75rem;
  padding: 0.28rem 0.6rem;
}

/* Header note inside the image dialog that tells the user which role the
   dialog is currently staging for, set by the button that opened it. */
.image-dialog-role-indicator {
  margin: 0.6rem 0 0;
  padding: 0.45rem 0.7rem;
  border-radius: 0.45rem;
  background: var(--surface-strong, rgba(0, 0, 0, 0.04));
  font-family: var(--font-body);
  font-size: 0.82rem;
  color: var(--ink);
}

/* Dropzone drag-over state for desktop drag-and-drop uploads. */
.image-dropzone.is-dragover {
  border-color: var(--accent);
  background: var(--surface-raised);
}

.image-dialog {
  width: min(42rem, calc(100vw - 2rem));
  max-height: calc(100dvh - 2rem);
  padding: 0;
  overflow: auto;
  color: var(--ink);
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: 0.75rem;
  box-shadow: 0 1.5rem 4rem rgb(0 0 0 / 36%);
}

.image-dialog::backdrop {
  background: rgb(4 8 16 / 72%);
}

.image-dialog form {
  display: grid;
  gap: 1rem;
  padding: clamp(1rem, 4vw, 1.75rem);
}

.image-dialog .dialog-heading p {
  margin: 0.3rem 0 0;
  color: var(--muted);
  font-size: 0.8rem;
}

.image-dropzone {
  display: grid;
  min-height: 9rem;
  place-content: center;
  gap: 0.35rem;
  padding: 1.25rem;
  background: var(--surface-raised);
  color: var(--muted);
  outline: 1px dashed var(--hairline);
  outline-offset: -1px;
  text-align: center;
  cursor: pointer;
  transition:
    background-color 220ms var(--ease-out),
    outline-color 220ms var(--ease-out);
}

.image-dropzone.is-dragging,
.image-dropzone:focus-within {
  background: color-mix(in srgb, var(--accent) 10%, var(--surface-raised));
  outline-color: var(--accent);
}

.image-dropzone input {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
}

.image-preview img {
  display: block;
  width: 100%;
  max-height: 16rem;
  object-fit: contain;
  background: var(--surface-raised);
}

body .image-dialog,
body .image-dialog input,
body .image-dialog select {
  color: var(--ink);
  background-color: var(--surface);
  border-color: var(--hairline);
}

@media (max-width: 860px) {
  .stream-book {
    height: clamp(32rem, 78dvh, 46rem);
  }

  .manuscript-layout {
    display: block;
  }

  .chapter-sidebar {
    position: sticky;
    z-index: 7;
    top: 4.7rem;
    max-height: none;
    margin: 0 -1rem 2rem;
    padding: 0.55rem 1rem;
    overflow: hidden;
    background: color-mix(in srgb, var(--paper) 94%, transparent);
    box-shadow: 0 0.45rem 1.2rem rgb(0 0 0 / 8%);
    backdrop-filter: blur(14px);
  }

  .chapter-sidebar h3 {
    margin-bottom: 0.35rem;
  }

  #chapter-navigation {
    display: flex;
    width: 100%;
    flex-wrap: nowrap;
    gap: 0.35rem;
    overflow-x: auto;
    scroll-snap-type: x proximity;
  }

  #chapter-navigation a {
    min-width: min(13rem, 74vw);
    flex: 0 0 auto;
    padding: 0.6rem 0.7rem;
    scroll-snap-align: start;
  }

  .manuscript > header {
    margin-top: 2rem;
  }
}

@media (max-width: 540px) {
  .completion-metrics > div {
    grid-template-columns: 6rem minmax(0, 1fr);
    align-items: center;
  }

  .stream-book {
    height: min(76dvh, 42rem);
    min-height: 30rem;
  }

  .stream-page {
    min-width: 94%;
    padding: 1rem 1.1rem;
  }

  .stream-chapter-body {
    font-size: clamp(0.86rem, 3.8vw, 1rem);
    line-height: 1.6;
  }

  .manuscript-image-60,
  .manuscript-image-80 {
    width: 100%;
  }

  .image-dialog {
    width: calc(100vw - 0.75rem);
    max-height: calc(100dvh - 0.75rem);
  }

  /* On narrow viewports the field-image-row stacks so the label and the
     trigger button each get their own line for legibility. */
  .field-image-row {
    flex-direction: column;
    align-items: flex-start;
  }
}

/* Provider pill resizes with its content: full provider + model names are
   always readable — the pill grows and wraps instead of ellipsizing. */
body .engine-status {
  width: auto;
  min-width: 0;
  max-width: min(100%, 24rem);
  padding-inline: 0.9rem;
  justify-content: flex-start;
}

body #provider-status-text {
  max-width: none;
  overflow: visible;
  flex-wrap: wrap;
  justify-content: center;
}

body .provider-status-provider,
body .provider-status-model {
  flex: 0 1 auto;
  min-width: 0;
  overflow: visible;
  text-overflow: clip;
  white-space: normal;
  overflow-wrap: anywhere;
}

/* The book renderer adapts to the viewport: a capped width and a dvh-based
   height so the whole workspace fits on screen instead of being sized by a
   stack of competing aspect-ratio and min/max-height rules. */
.stream-book {
  width: min(100%, 64rem);
  height: clamp(19rem, 58dvh, 44rem);
  aspect-ratio: auto;
  min-height: 0;
  max-height: none;
}

/* The output shelf only exists once a build has produced artifacts —
   hidden until then, so the waiting state can never leak through. */
.outputs-panel[hidden] {
  display: none;
}

/* Output cards: every label — format name and size alike — centers
   inside its card, at every breakpoint. */
body .output-card {
  text-align: center;
}

/* Slightly larger labels on the shelf. */
.output-card .output-format {
  font-size: 0.92rem;
}

.output-card .output-description {
  font-size: 0.8rem;
}

/* Shelf cards read as buttons again: visible surface and radius — but
   borderless, by design; elevation and the hover outline carry the
   boundary instead. The flattened "output dock" pass left them as bare
   text with no affordance, and the span-3 secondary sizing broke the
   3+3 symmetry — EVERYTHING and the KDP card ended up stranded on
   orphan rows. All six format cards span two tracks of the six-track
   grid; the KDP bundle centers on its own row beneath them. */
body .output-card,
body .output-card.is-disabled {
  grid-template-columns: minmax(0, 1fr);
  grid-column: span 2;
  min-height: 5.75rem;
  margin-top: 0;
  padding: 0.95rem 1.1rem;
  background: var(--surface-raised);
  border: 0;
  border-radius: 0.8rem;
}

body .output-card.is-disabled {
  background: var(--disabled-surface);
}

body .output-card.is-disabled::after {
  position: absolute;
  top: 0.55rem;
  right: 0.7rem;
}

/* Secondary cards keep their place in the 3+3 grid — no wider span. */
body .output-card.output-secondary,
body .output-card.output-secondary + .output-card.output-secondary {
  grid-column: span 2;
  min-height: 5.75rem;
  margin-top: 0;
}

/* The KDP publish bundle is the handoff — it sits centered on its own
   row beneath the six format cards. */
@media (min-width: 901px) {
  body .output-card.output-kdp {
    grid-column: 3 / span 2;
    text-align: center;
  }
}

@media (max-width: 900px) {
  body .output-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  body .output-card,
  body .output-card.output-secondary,
  body .output-card.output-secondary + body .output-card.output-secondary {
    grid-column: auto;
  }

  body .output-card.output-kdp {
    grid-column: 1 / -1;
    justify-self: center;
    width: min(100%, 24rem);
    text-align: center;
  }
}

@media (max-width: 640px) {
  body .output-grid {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* Hover lift: the card rises off the page and its boundary becomes
   visible (outline in the card's own ink color, no border-width change —
   no layout shift). The `body` prefix is required to outrank the older
   body-scoped hover rules above that pin `transform: none`. */
body .output-card:not(.is-disabled) {
  transition:
    transform 180ms var(--ease-out, ease),
    box-shadow 180ms var(--ease-out, ease),
    outline-color 180ms var(--ease-out, ease),
    background-color 180ms var(--ease-out, ease);
}

body .output-card:not(.is-disabled):hover,
body .output-card:not(.is-disabled):focus-visible {
  z-index: 1;
  background: var(--surface-raised);
  transform: translateY(-4px);
  outline: 2px solid currentColor;
  outline-offset: -1px;
  box-shadow: 0 14px 28px rgb(0 0 0 / 0.22);
}

/* Tap feedback for touch users, who never see :hover: a quick press-in
   that rebounds through the same transition when the tap releases. */
body .output-card:not(.is-disabled):active {
  transform: translateY(1px) scale(0.97);
  box-shadow: 0 3px 8px rgb(0 0 0 / 0.16);
  outline: 2px solid currentColor;
  outline-offset: -1px;
  transition-duration: 70ms;
}
