:root {
  --bg: #fff9ef;
  --bg-soft: #fff1d8;
  --bg-strong: #ffe1b3;
  --surface: rgba(255, 255, 255, 0.9);
  --surface-strong: #fffdf9;
  --surface-tint: rgba(255, 244, 222, 0.72);
  --text: #2d2050;
  --muted: #65597d;
  --line: rgba(108, 87, 145, 0.14);
  --accent: #ff7a59;
  --accent-strong: #ef5f3f;
  --accent-soft: #ffd1b8;
  --sky: #dff4ff;
  --sky-strong: #bde8ff;
  --mint: #d8f4d8;
  --sun: #ffd766;
  /* v2 "crayon / sticker-book" tokens — shared by the header/footer (global)
     and the migrated marketing pages. Additive: no collision with the palette
     above. North star: docs/prototypes/crayonbloom-design-v2.html */
  --paper: #fcf7ec;
  --page: #ffffff;
  --ink: #3a2e25; /* warm espresso ink — softer than the old near-black #241d17 */
  --ink-soft: #776657;
  /* ============================================================
     BRAND COLOR — single source of truth (Direction A, "warmer coral").
     Change this ONE value to reskin the whole brand accent: every CTA,
     squiggle, sticker dot, link, and badge derives from --brand.
     --coral and --coral-deep both flow from it (see @supports below).
     ============================================================ */
  --brand: #e8654e;
  --coral: var(--brand);
  --coral-deep: #c44e3a; /* darker brand shade for text-on-light; AA on white. Derived from --brand where supported (see @supports below). */
  /* Error copy sits on a warm tinted band (--t-blush / the peach alert wash), where
     --coral-deep lands at 3.8:1 and --accent-strong at 2.8:1 — both under AA. This
     is one step deeper so an error message is readable on the band it lives on
     (5.2:1 on the peach, 5.1:1 on --t-blush). Errors are the copy AA matters most for. */
  --error-ink: #a83f2d;
  --marigold: #f7b24a;
  --grass: #2a9466;
  --grass-deep: #157a4b; /* AA-safe grass for text on white (4.5:1) */
  --cornflower: #3f6fe5;
  --grape: #8a63d6;
  --t-butter: #fff1cf;
  --t-mint: #e3f5ea;
  --t-sky: #e7edff;
  --t-blush: #fce3e6;
  --t-coral: #fdeee8; /* soft coral wash for the brand-accent section band (--cb-band--coral); kept light so --ink / --ink-soft body copy stays AA, matching the mint/butter bands. */
  --bw: 2.6px;
  --r-card: 20px;
  --r-card-lg: 30px;
  --shadow-sticker: 6px 7px 0 rgba(36, 29, 23, 0.14);
  --shadow-sticker-lg: 9px 10px 0 rgba(36, 29, 23, 0.16);
  /* The warm "hand-made" drop — a soft brown glow over a faint solid offset.
     This is the DEFINITION; `.cb-page` / `.studio-surface` re-point
     --shadow-sticker at it rather than restating the literal, so the warm
     shadow has one home. (Both used to carry their own near-identical copy;
     the -lg alphas had already drifted apart. These are the shipped
     `.cb-page` values — nothing renders differently.) */
  --shadow-warm: 6px 9px 20px -7px rgba(150, 96, 40, 0.30), 3px 4px 0 rgba(36, 29, 23, 0.08);
  --shadow-warm-lg: 10px 15px 30px -8px rgba(150, 96, 40, 0.32), 4px 6px 0 rgba(36, 29, 23, 0.08);
  --page-gutter: clamp(1rem, 3vw, 2rem);
  /* The shape of a drawing. Every box that shows a coloring page — marketing
     sample, style sample, a parent's own preview — takes this rather than
     writing a ratio of its own, so the site and the printer agree about what a
     page looks like. It mirrors OpenAi::Client::LINE_ART_ASPECT (2560x3072 =
     5:6 since T-12824); ArtAspectTest fails if the two drift, because CSS
     cannot read the constant and a stale ratio here is invisible.
     Boxes pair it with object-fit: contain — the art we drew before this is
     2:3, and letterboxing white line art on a white card costs nothing while
     cropping a child's drawing costs the drawing. */
  --art-aspect: 5 / 6;
  /* Radius scale (4-step) — the small ad-hoc radii consolidate onto these.
     --r-card / --r-card-lg stay the semantic container tokens (re-pointed
     warmer inside .cb-page / .studio-surface); pill 999px + circle 50% keep
     their shape keywords. */
  --r-sm: 4px;
  --r-md: 8px;
  --r-lg: 12px;
  --r-xl: 16px;
  /* Elevation shadow scale (4-step, soft purple ambient) — the card/panel
     drop. --shadow-md is the default card elevation (formerly --shadow). The
     hard sticker offsets (--shadow-sticker) and colored accent glows are a
     separate language and keep their own tokens/values. */
  --shadow-sm: 0 12px 30px rgba(78, 54, 117, 0.07);
  --shadow-md: 0 18px 44px rgba(78, 54, 117, 0.1);
  --shadow-lg: 0 26px 60px rgba(78, 54, 117, 0.15);
  --shadow-xl: 0 30px 80px rgba(78, 54, 117, 0.16);
  /* UI text colors on tinted surfaces + service-status hues */
  --sage: #6b8a6f;
  --mint-ink: #2f5a37;
  --mint-ink-strong: #176b41;
  --sky-ink: #355774;
  --status-ok: #2f8f5b;
  --status-warn: #b8860b;
  --status-down: #c0392b;
  font-family: "Nunito", "Avenir Next", "Trebuchet MS", sans-serif;
}

/* Derive the darker brand shade from --brand so a single colour change reskins
   everything, including coral-deep. The literal above is the fallback for the
   rare browser without CSS relative-colour support. */
@supports (color: oklch(from white l c h)) {
  :root {
    --coral-deep: oklch(from var(--brand) calc(l - 0.09) c h);
  }
}

* {
  box-sizing: border-box;
}

html {
  scroll-behavior: smooth;
}

/* `.site-header` is sticky, so a fragment jump parks its destination at the very
   top of the viewport — behind the header. Arriving at #try-free that way hid the
   composer's promise line ("Try a free page first…") under 78px of header, which is
   the sentence the visitor clicked the CTA for. Every anchored destination clears
   the header instead. Block axis only, so the horizontally snapping activity reel
   is untouched. */
[id] {
  scroll-margin-top: 6.5rem;
}

body {
  margin: 0;
  min-height: 100vh;
  color: var(--text);
  font-family: "Nunito", "Avenir Next", "Trebuchet MS", sans-serif;
  background: linear-gradient(180deg, #fffefb 0%, var(--bg) 42%, #fff4df 100%);
}

a {
  color: inherit;
}

img {
  max-width: 100%;
  height: auto;
}

.page-shell {
  width: min(1180px, calc(100% - (var(--page-gutter) * 2)));
  margin: 0 auto;
}

/* The shared site header/footer wear the v2 "crayon / storybook" look on every
   page, and every public marketing surface (home, pricing, faq, the four legal
   pages, coloring-pages) now renders on the shared `.cb-page` system below it. */
/* Global storybook header chrome (promoted from the old home-only override):
   soft warm wash, borderless, a hairline shadow instead of the heavy ink rule.
   Keyed on `.site-header` so EVERY controller's pages share it (home, pricing,
   legal, coloring-pages, auth/studio). */
.site-header {
  position: sticky;
  top: 0;
  z-index: 30;
  backdrop-filter: blur(8px);
  background: rgba(251, 244, 228, 0.82);
  box-shadow: 0 1px 0 rgba(36, 29, 23, 0.05);
}

.site-header__inner,
.site-footer__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.85rem 0;
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: 0.7rem;
  text-decoration: none;
}

.brand__mark {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.7rem;
  height: 2.7rem;
  border-radius: var(--r-lg);
  background: var(--accent-soft);
  border: var(--bw) solid var(--ink);
  box-shadow: 4px 5px 0 rgba(36, 29, 23, 0.14);
  overflow: hidden;
}

.brand__mark img {
  display: block;
  width: 100%;
  height: 100%;
}

.brand__lockup {
  display: grid;
  gap: 0.1rem;
}

h1,
h2,
h3,
.button,
button,
input[type="submit"] {
  font-family: "Fredoka", "Nunito", sans-serif;
}

/* Storybook wordmark — all-coral Fredoka, global (header + footer). */
.brand__lockup strong {
  font-family: "Fredoka", system-ui, sans-serif;
  font-weight: 600;
  font-size: 1.5rem;
  line-height: 1;
  letter-spacing: -0.01em;
  color: var(--coral);
}

.brand__lockup strong b {
  color: var(--coral);
  font-weight: 700;
}

/* The header carries the bigger, borderless storybook lockup (the as-shipped
   home reference, now global); the footer keeps the base smaller mark/size. */
.site-header .brand__mark {
  width: 3.2rem;
  height: 3.2rem;
  border: 0;
  border-radius: var(--r-xl);
  background: transparent;
  box-shadow: none;
  overflow: visible;
}

.site-header .brand__lockup strong {
  font-size: 1.85rem;
}

.brand__lockup small {
  color: var(--muted);
  font-size: 0.8rem;
  line-height: 1.1;
}

/* The nav lives inside a native <details> so it can collapse to a hamburger on
   mobile with no JS. On desktop the disclosure is invisible: the summary is
   hidden and the nav is always shown (override the closed-details content
   hiding via ::details-content). */
.site-menu {
  display: block;
}

.site-menu__toggle {
  display: none;
}

/* Desktop: the disclosure is always "open" visually — override the UA's
   closed-details content hiding so the inline nav shows regardless of state.
   On mobile this rule drops away and native open/closed behavior takes over. */
@media (min-width: 721px) {
  .site-menu::details-content {
    content-visibility: visible;
  }
}

.site-nav {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  justify-content: flex-end;
  /* Wide enough that a two-word item ("Coloring pages") reads as one item and
     not as a run-on with its neighbour. The stacked mobile menu sets its own. */
  gap: 0.9rem;
}

.site-nav a {
  text-decoration: none;
}

/* Sticker nav links + buttons, scoped to the header so un-migrated page bodies
   keep their existing button styling. */
.site-header .site-nav > a {
  position: relative;
  font-family: "Nunito", sans-serif;
  font-weight: 600;
  color: var(--ink);
}

.site-header .site-nav > a:hover,
.site-header .site-nav > a:focus-visible {
  color: var(--coral-deep);
}

/* Current-page indicator: a subtle coral underline accent + color shift — NOT a
   button. The underline is an absolutely-positioned ::after, and the text weight
   is unchanged, so the active link occupies the exact same box width as when it's
   inactive. That keeps the nav from reflowing/jumping as you move between pages. */
.site-header .site-nav > a[aria-current="page"] {
  color: var(--coral-deep);
}

.site-header .site-nav > a[aria-current="page"]::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -0.4rem;
  height: 3px;
  border-radius: 999px;
  background: var(--coral);
}

/* Header buttons use the storybook button system (Fredoka + sticker shadow), so
   the chrome CTAs match the in-page `.cb-page .button` look on every page. They
   live outside `.cb-page`, so the rules are restated here. Plain `.button` is the
   coral primary ("Start creating"); `--secondary` is the white sign-in. */
.site-header .button,
.site-header button {
  font-family: "Fredoka", "Nunito", sans-serif;
  /* Normal-weight Fredoka — matches the in-page `.cb-page .button` (Fredoka's
     heavier weights read bloated at this small chrome-CTA size). */
  font-weight: normal;
  font-size: 0.95rem;
  min-height: 0;
  padding: 0.58em 1.15em;
  border: var(--bw) solid var(--ink);
  border-radius: 999px;
  background: var(--coral);
  color: #fff;
  box-shadow: var(--shadow-sticker);
}

.site-header .button:hover,
.site-header button:hover {
  transform: translate(-2px, -2px);
  box-shadow: var(--shadow-sticker-lg);
}

.site-header .button:active,
.site-header button:active {
  transform: translate(3px, 4px);
  box-shadow: 2px 2px 0 rgba(36, 29, 23, 0.16);
}

.site-header .button--secondary {
  background: var(--page);
  color: var(--ink);
}

.site-header .button:focus-visible,
.site-header button:focus-visible {
  outline: 3px solid var(--cornflower);
  outline-offset: 2px;
}

form.button_to {
  margin: 0;
}

.button,
button,
input[type="submit"] {
  appearance: none;
  border: 0;
  cursor: pointer;
  font: inherit;
  font-family: "Fredoka", "Nunito", sans-serif;
  font-size: 1rem;
  border-radius: 999px;
  padding: 0.92rem 1.35rem;
  background: linear-gradient(180deg, var(--accent) 0%, var(--accent-strong) 100%);
  color: white;
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.4rem;
  max-width: 100%;
  min-height: 2.85rem;
  text-align: center;
  line-height: 1.15;
  transition:
    transform 0.2s ease,
    box-shadow 0.2s ease,
    background 0.2s ease;
  box-shadow: 0 18px 34px rgba(255, 122, 89, 0.25);
}

.button:hover,
button:hover,
input[type="submit"]:hover {
  transform: translateY(-2px);
  box-shadow: 0 22px 38px rgba(255, 122, 89, 0.3);
}

.button--secondary {
  background: rgba(255, 255, 255, 0.78);
  color: var(--text);
  border: 1px solid rgba(108, 87, 145, 0.14);
  box-shadow: none;
}

.button--secondary:hover {
  background: rgba(255, 255, 255, 0.92);
  box-shadow: none;
}

.button--ghost {
  background: transparent;
  color: var(--muted);
  box-shadow: none;
  padding-inline: 0;
}

.button:disabled,
button:disabled,
input[type="submit"]:disabled {
  cursor: not-allowed;
  opacity: 0.6;
  transform: none;
  box-shadow: none;
}

.button:focus-visible,
button:focus-visible,
input[type="submit"]:focus-visible,
.field input:focus-visible,
.field textarea:focus-visible,
.field select:focus-visible {
  outline: 3px solid var(--accent);
  outline-offset: 2px;
}

.hero {
  position: relative;
  overflow: clip;
  padding: clamp(1.5rem, 4vw, 3rem) 0 clamp(2.5rem, 5vw, 4.5rem);
}

.hero__inner,
.feature-grid,
.pricing-grid,
.dashboard-grid,
.book-grid,
.studio-grid,
.stats-grid,
.story-grid,
.admin-grid,
.journey,
.idea-grid,
.mini-pricing,
.faq-list {
  display: grid;
  gap: 1.5rem;
}

.hero__inner {
  grid-template-columns: minmax(0, 0.98fr) minmax(320px, 0.9fr);
  align-items: center;
  gap: clamp(1.5rem, 4vw, 3.25rem);
  min-height: min(46rem, calc(100svh - 6rem));
}

.hero__copy {
  position: relative;
  z-index: 1;
  animation: rise-in 0.7s ease both;
}

.hero__tagline {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.5rem 0.85rem;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.8);
  border: 1px solid rgba(108, 87, 145, 0.12);
  color: var(--muted);
  font-weight: 700;
}

.hero__tagline::before {
  content: "";
  width: 0.7rem;
  height: 0.7rem;
  border-radius: 50%;
  background: linear-gradient(180deg, var(--sun) 0%, #ffb63d 100%);
}

h1,
h2,
h3 {
  margin-top: 0;
  line-height: 0.95;
  letter-spacing: 0;
}

h1 {
  margin-bottom: 1rem;
  font-size: 4.35rem;
}

h2 {
  margin-bottom: 0.8rem;
  font-size: 2.45rem;
}

h3 {
  margin-bottom: 0.5rem;
  font-size: 1.45rem;
}

.hero__copy h1 {
  max-width: 9.8ch;
}

.hero__lede {
  max-width: 34rem;
  margin-bottom: 1.5rem;
  font-size: 1.13rem;
  line-height: 1.65;
  color: var(--muted);
}

.hero__proof {
  grid-template-columns: repeat(3, minmax(0, 1fr));
  margin-top: 1.75rem;
  gap: 1rem;
}

.proof-pill {
  padding: 0.8rem 0;
  border-top: 1px solid rgba(108, 87, 145, 0.14);
}

.proof-pill strong,
.price-tag {
  display: block;
  margin-bottom: 0.15rem;
  font-family: "Fredoka", "Nunito", sans-serif;
  font-size: 1.2rem;
}

.proof-pill span {
  color: var(--muted);
  font-size: 0.92rem;
}

/* Hero email capture (launch-mode waitlist as the primary CTA) */
.hero__capture {
  margin-top: 0.5rem;
}

.waitlist-inline {
  display: grid;
  gap: 0.5rem;
}

.waitlist-inline__row {
  display: flex;
  flex-wrap: wrap;
  align-items: stretch;
  gap: 0.6rem;
}

.waitlist-inline__row .field {
  flex: 1 1 16rem;
  min-width: 0;
}

.waitlist-inline__row input[type="email"] {
  height: 100%;
  font-size: 1rem;
}

.waitlist-inline__row .button {
  flex: 0 0 auto;
  white-space: nowrap;
}

.waitlist-inline__note {
  margin: 0;
  font-size: 0.88rem;
}

.hero__secondary {
  margin: 1rem 0 0;
  color: var(--muted);
  font-size: 0.98rem;
}

.link-arrow {
  font-weight: 700;
  color: var(--accent-strong);
  text-decoration: none;
  border-bottom: 2px solid transparent;
}

.link-arrow::after {
  content: " \2192";
}

.link-arrow:hover,
.link-arrow:focus-visible {
  border-bottom-color: currentColor;
}

.trust-strip {
  display: flex;
  flex-wrap: wrap;
  gap: 0.55rem 1.1rem;
  margin: 1.75rem 0 0;
  padding: 0;
  list-style: none;
  color: var(--muted);
  font-size: 0.92rem;
  font-weight: 700;
}

.trust-strip li {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
}

.trust-strip li::before {
  content: "";
  width: 0.5rem;
  height: 0.5rem;
  border-radius: 50%;
  background: var(--accent);
}

.waitlist-panel {
  max-width: 560px;
  margin: 0 auto;
}

.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;
}

.hero-visual {
  position: relative;
  animation: rise-in 0.9s ease both;
}

.story-stage {
  position: relative;
  min-height: 34rem;
  border-radius: var(--r-md);
  overflow: hidden;
  background:
    linear-gradient(180deg, #dcf4ff 0%, #e9f9ff 36%, #fff2d6 100%);
  border: 1px solid rgba(108, 87, 145, 0.08);
  box-shadow: var(--shadow-md);
}

.story-stage__sun {
  position: absolute;
  top: 2.5rem;
  right: 3rem;
  width: 7.2rem;
  height: 7.2rem;
  border-radius: 50%;
  background: radial-gradient(circle at 35% 35%, #fff8d8 0%, #ffe789 42%, #ffc95d 100%);
  box-shadow: 0 0 0 16px rgba(255, 215, 102, 0.16);
}

.story-stage__cloud,
.story-stage__cloud::before,
.story-stage__cloud::after {
  position: absolute;
  background: rgba(255, 255, 255, 0.92);
  border-radius: 999px;
}

.story-stage__cloud {
  height: 1.7rem;
}

.story-stage__cloud::before,
.story-stage__cloud::after {
  content: "";
}

.story-stage__cloud::before {
  width: 2rem;
  height: 2rem;
  top: -0.65rem;
  left: 0.35rem;
}

.story-stage__cloud::after {
  width: 2.4rem;
  height: 2.4rem;
  top: -1rem;
  right: 0.5rem;
}

.story-stage__cloud--one {
  top: 4.5rem;
  left: 3rem;
  width: 5.5rem;
  animation: drift 8s ease-in-out infinite;
}

.story-stage__cloud--two {
  top: 8rem;
  right: 10rem;
  width: 4.8rem;
  animation: drift 9.5s ease-in-out infinite reverse;
}

.story-stage__hill {
  position: absolute;
  left: -12%;
  right: -12%;
  bottom: -2rem;
  height: 12rem;
  border-radius: 50% 50% 0 0;
  background: linear-gradient(180deg, #ccefbf 0%, #9edb93 100%);
}

.story-stage__hill::after {
  content: "";
  position: absolute;
  inset: auto 8% 2.3rem auto;
  width: 10rem;
  height: 4rem;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.24);
  filter: blur(16px);
}

.story-sheet {
  --sheet-x: 0;
  --sheet-tilt: 0deg;
  position: absolute;
  margin: 0;
  width: 14.5rem;
  padding: 0.7rem 0.7rem 0.55rem;
  border-radius: var(--r-md);
  background: rgba(255, 255, 255, 0.96);
  border: 1px solid rgba(108, 87, 145, 0.1);
  box-shadow: var(--shadow-md);
  transform: translate(var(--sheet-x), 0) rotate(var(--sheet-tilt));
}

.story-sheet img {
  display: block;
  width: 100%;
  aspect-ratio: var(--art-aspect);
  object-fit: contain;
  border-radius: var(--r-sm);
  background: #fff;
  border: 1px solid rgba(108, 87, 145, 0.08);
}

.story-sheet figcaption {
  margin-top: 0.5rem;
  text-align: center;
  font-family: "Fredoka", "Nunito", sans-serif;
  font-size: 0.98rem;
  color: var(--text);
}

.story-sheet--one {
  --sheet-tilt: -8deg;
  top: 6.5rem;
  left: 2.4rem;
  animation: float-sheet 5.5s ease-in-out infinite;
}

.story-sheet--two {
  --sheet-tilt: 9deg;
  top: 12rem;
  right: 2.5rem;
  animation: float-sheet 6.3s ease-in-out infinite reverse;
}

.story-sheet--three {
  --sheet-x: -50%;
  --sheet-tilt: -2deg;
  bottom: 5rem;
  left: 50%;
  width: 16rem;
  animation: float-sheet 5.9s ease-in-out infinite;
}

.story-stage__badge {
  position: absolute;
  left: 2.3rem;
  bottom: 3.2rem;
  display: inline-flex;
  align-items: center;
  gap: 0.65rem;
  padding: 0.8rem 1rem;
  border-radius: var(--r-md);
  background: rgba(77, 53, 117, 0.9);
  color: white;
  box-shadow: 0 18px 32px rgba(77, 53, 117, 0.18);
}

.story-stage__badge strong {
  font-family: "Fredoka", "Nunito", sans-serif;
  font-size: 1rem;
}

.story-stage__badge span {
  font-size: 0.92rem;
  color: rgba(255, 255, 255, 0.82);
}

.sample-gallery {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1.5rem;
  margin-top: 2.5rem;
}

.sample-card {
  margin: 0;
  display: flex;
  flex-direction: column;
  padding: 0.9rem;
  min-width: 0;
  border-radius: var(--r-md);
  background: var(--surface-strong);
  border: 1px solid var(--line);
  box-shadow: var(--shadow-md);
  transition: transform 0.2s ease, box-shadow 0.2s ease;
}

.sample-card:hover {
  transform: translateY(-4px);
  box-shadow: var(--shadow-xl);
}

.sample-card__art {
  border-radius: var(--r-sm);
  overflow: hidden;
  background: #fff;
  border: 1px solid var(--line);
}

.sample-card__art img {
  display: block;
  width: 100%;
  aspect-ratio: var(--art-aspect);
  object-fit: contain;
}

.sample-card figcaption {
  margin-top: 0.85rem;
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
}

.sample-card figcaption strong {
  overflow-wrap: anywhere;
  font-family: "Fredoka", "Nunito", sans-serif;
  font-size: 1.1rem;
}

.sample-card figcaption span {
  font-size: 0.92rem;
  line-height: 1.4;
}

.eyebrow {
  margin-bottom: 0.7rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  font-size: 0.78rem;
  color: var(--sage);
  font-weight: 800;
}

p,
li,
label,
input,
textarea,
select {
  line-height: 1.6;
}

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

.stack,
.pill-row,
.spark-list {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
}

.stack--column {
  flex-direction: column;
  flex-wrap: nowrap;
  align-items: stretch;
}

.pill {
  display: inline-flex;
  align-items: center;
  border: 1px solid rgba(108, 87, 145, 0.12);
  padding: 0.45rem 0.8rem;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.72);
  color: var(--muted);
  font-size: 0.92rem;
}

.section {
  padding: clamp(1.5rem, 4vw, 2.5rem) 0 clamp(2rem, 5vw, 3.5rem);
}

.section-heading {
  max-width: 42rem;
  margin-bottom: 1.5rem;
}

.marketing-band,
.cta-banner,
.page-intro,
.legal-wrap {
  position: relative;
}

.marketing-band {
  padding: clamp(0.5rem, 2vw, 1rem) 0;
}

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

.path-card,
.hero-card,
.panel,
.feature-card,
.pricing-card,
.dashboard-card,
.book-card,
.studio-card,
.stat-card,
.admin-card,
.legal-card {
  border-radius: var(--r-md);
  background: var(--surface);
  border: 1px solid rgba(108, 87, 145, 0.1);
  box-shadow: var(--shadow-md);
}

.path-card,
.panel,
.feature-card,
.pricing-card,
.dashboard-card,
.book-card,
.studio-card,
.admin-card,
.legal-card {
  padding: clamp(1.1rem, 2.5vw, 1.5rem);
  min-width: 0;
}

.path-card {
  background:
    linear-gradient(180deg, rgba(255, 255, 255, 0.9) 0%, rgba(255, 247, 234, 0.95) 100%);
}

.path-card__step {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.6rem;
  height: 2.6rem;
  margin-bottom: 1rem;
  border-radius: 999px;
  font-family: "Fredoka", "Nunito", sans-serif;
  font-size: 1.1rem;
  background: linear-gradient(180deg, #ffe39f 0%, #ffc374 100%);
  box-shadow: 0 12px 20px rgba(255, 199, 90, 0.25);
}

.idea-grid {
  grid-template-columns: minmax(0, 0.95fr) minmax(300px, 0.85fr);
  align-items: center;
  gap: 2rem;
}

.spark-chip {
  padding: 0.65rem 0.9rem;
  border-radius: 999px;
  background: rgba(223, 244, 255, 0.8);
  color: var(--sky-ink);
  font-weight: 700;
}

.panel--playful {
  background:
    radial-gradient(circle at top left, rgba(255, 255, 255, 0.8), transparent 30%),
    linear-gradient(180deg, rgba(255, 241, 216, 0.9) 0%, rgba(223, 244, 255, 0.78) 100%);
}

.mode-list {
  display: grid;
  gap: 1rem;
}

.mode-item {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 1rem;
  align-items: start;
}

.mode-item__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 3rem;
  height: 3rem;
  border-radius: var(--r-md);
  background: rgba(255, 255, 255, 0.72);
  font-family: "Fredoka", "Nunito", sans-serif;
  font-size: 1rem;
  font-weight: 700;
  color: var(--ink);
}

.feature-grid,
.pricing-grid,
.dashboard-grid,
.book-grid,
.admin-grid {
  grid-template-columns: repeat(3, minmax(0, 1fr));
}

.mini-pricing {
  grid-template-columns: repeat(4, minmax(0, 1fr));
  margin-top: 1.5rem;
}

.stat-card {
  padding: 1rem;
  min-width: 0;
  background: rgba(255, 255, 255, 0.72);
}

.mini-pricing .stat-card strong {
  display: block;
  margin-bottom: 0.35rem;
  font-family: "Fredoka", "Nunito", sans-serif;
  font-size: 1.2rem;
}

.story-note {
  max-width: 38rem;
}

.cta-banner {
  overflow: hidden;
  padding: clamp(1.3rem, 3vw, 2.2rem);
  border-radius: var(--r-md);
  border: 1px solid rgba(108, 87, 145, 0.08);
  background: linear-gradient(135deg, #ffe5bd 0%, #ffd3cb 48%, #e3f6ff 100%);
}

.cta-banner__content {
  position: relative;
  z-index: 1;
  display: flex;
  align-items: end;
  justify-content: space-between;
  gap: 1.5rem;
}

.page-intro,
.legal-wrap {
  padding: clamp(1.3rem, 3vw, 2.2rem);
  border-radius: var(--r-md);
  border: 1px solid rgba(108, 87, 145, 0.08);
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.92) 0%, rgba(255, 249, 238, 0.92) 100%);
}

.page-intro {
  margin-bottom: 1.5rem;
}

.page-intro p:last-child,
.legal-wrap p:last-child {
  max-width: 42rem;
}

.legal-prose h2 {
  margin-top: 1.8rem;
  margin-bottom: 0.5rem;
  font-size: 1.15rem;
}

.legal-prose p,
.legal-prose ul {
  max-width: 44rem;
}

.legal-prose ul {
  margin: 0.5rem 0 0.5rem 1.1rem;
  padding-left: 0.4rem;
  list-style: disc;
}

.legal-prose li {
  margin-bottom: 0.35rem;
}

.pricing-card {
  display: grid;
  gap: 1rem;
}

.pricing-card--featured {
  background:
    linear-gradient(180deg, rgba(255, 241, 216, 0.95) 0%, rgba(255, 255, 255, 0.95) 100%);
}

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

.pricing-bullets li::before {
  content: "";
  display: inline-block;
  width: 0.55rem;
  height: 0.55rem;
  margin-right: 0.65rem;
  border-radius: 50%;
  background: var(--accent);
  vertical-align: middle;
}

.pricing-example {
  margin-top: 1.5rem;
  padding: 1.25rem 1.4rem;
  border-radius: var(--r-lg);
  background: var(--surface-tint);
  border: 1px solid var(--line);
  max-width: 46rem;
}

.pricing-example p:last-child {
  margin-bottom: 0;
  font-size: 1.08rem;
  line-height: 1.6;
}

.pricing-note {
  margin-top: 1.25rem;
  padding: 1rem 1.1rem;
  border-radius: var(--r-md);
  background: rgba(223, 244, 255, 0.72);
  color: var(--sky-ink);
}

.faq-list {
  gap: 1rem;
}

.faq-row {
  padding: 1.2rem 1.3rem;
  border-radius: var(--r-md);
  background: rgba(255, 255, 255, 0.74);
  border: 1px solid rgba(108, 87, 145, 0.1);
}

.faq-row strong {
  display: block;
  margin-bottom: 0.35rem;
  font-family: "Fredoka", "Nunito", sans-serif;
  font-size: 1.08rem;
}

.form-stack {
  display: grid;
  gap: 1rem;
}

.field {
  display: grid;
  gap: 0.4rem;
}

.field input,
.field textarea,
.field select {
  width: 100%;
  border-radius: var(--r-md);
  border: 1px solid rgba(108, 87, 145, 0.16);
  padding: 0.9rem 1rem;
  background: rgba(255, 255, 255, 0.92);
}

.field textarea {
  min-height: 10rem;
  resize: vertical;
}

.field__hint {
  margin: 0;
  font-size: 0.9rem;
  line-height: 1.45;
}

/* Required 18-or-older attestation: checkbox beside a short, linked statement. */
.assent-check {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 0.6rem;
  align-items: start;
  font-size: 0.85rem;
  line-height: 1.45;
  color: var(--ink-soft, #6c5791);
}

.assent-check input[type="checkbox"] {
  width: 1.1rem;
  height: 1.1rem;
  margin-top: 0.1rem;
  accent-color: var(--coral);
}

.assent-check a {
  color: var(--coral-deep);
  text-decoration: underline;
  font-weight: 600;
}

.notice,
.alert {
  margin: 1rem auto;
  width: min(1180px, calc(100% - (var(--page-gutter) * 2)));
  border-radius: var(--r-md);
  padding: 0.95rem 1rem;
}

.notice {
  border: 1px solid rgba(107, 143, 113, 0.35);
  background: rgba(216, 244, 216, 0.8);
}

.alert {
  border: 1px solid rgba(255, 122, 89, 0.22);
  background: rgba(255, 209, 184, 0.5);
}

.site-footer {
  margin-top: 0;
  border-top: 2.6px solid var(--ink);
  background: var(--paper);
}

.site-footer__grid {
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 2rem;
  padding-block: 2.75rem 1.5rem;
}

.site-footer__brand {
  max-width: 24rem;
}

.site-footer__brand .brand {
  margin-bottom: 0.85rem;
}

.site-footer__brand .muted {
  color: var(--ink-soft);
  font-weight: 500;
}

.site-footer__cols {
  display: flex;
  flex-wrap: wrap;
  gap: 2.5rem;
}

.site-footer__col h4 {
  margin: 0 0 0.7rem;
  font-family: "Nunito", sans-serif;
  font-weight: 800;
  font-size: 0.78rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--ink);
}

.site-footer__col a,
.site-footer__manage {
  display: block;
  margin-bottom: 0.55rem;
  font-weight: 600;
  font-size: 0.95rem;
  color: var(--ink-soft);
  text-decoration: none;
}

/* The "Privacy choices" control is a button (it re-opens the consent banner),
   styled to sit in the footer link list. */
.site-footer__manage {
  appearance: none;
  background: none;
  border: 0;
  padding: 0;
  min-height: 0;
  box-shadow: none;
  font-family: inherit;
  text-align: left;
  cursor: pointer;
}

.site-footer__col a:hover,
.site-footer__col a:focus-visible,
.site-footer__manage:hover,
.site-footer__manage:focus-visible {
  color: var(--coral-deep);
}

.site-footer__legal {
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 0.6rem;
  padding: 1.1rem 0 2rem;
  border-top: 2px dashed rgba(36, 29, 23, 0.18);
  color: var(--ink-soft);
  font-weight: 600;
  font-size: 0.88rem;
}

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

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

.value-split {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1rem;
  margin: 1.25rem 0 0.5rem;
}

.value-split__item {
  display: grid;
  gap: 0.4rem;
  align-content: start;
  padding: 1.1rem 1.2rem;
  border-radius: var(--r-md);
  background: rgba(255, 255, 255, 0.74);
  border: 1px solid rgba(108, 87, 145, 0.12);
}

.value-split__item strong {
  font-family: "Fredoka", "Nunito", sans-serif;
  font-size: 1.1rem;
}

.value-split__tag {
  justify-self: start;
  padding: 0.2rem 0.7rem;
  border-radius: 999px;
  font-family: "Fredoka", "Nunito", sans-serif;
  font-size: 0.82rem;
  /* small tag: Fredoka's heavier weights read bloated here, so use regular. */
  font-weight: normal;
  letter-spacing: 0.01em;
}

.value-split__tag--free {
  background: var(--mint);
  color: var(--mint-ink);
}

.value-split__tag--paid {
  background: var(--accent-soft);
  color: var(--accent-strong);
}

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

.preview-card {
  padding: 1rem;
  border-radius: var(--r-md);
  background: rgba(255, 255, 255, 0.72);
  border: 1px solid rgba(108, 87, 145, 0.1);
}

.two-column {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 340px;
  gap: 1.5rem;
}

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

/* ---- Book studio ---- */
.studio-card__lede {
  max-width: 44rem;
  color: var(--muted);
  font-size: 1.05rem;
  line-height: 1.6;
}

.studio-progress {
  margin: 1.25rem 0 0.5rem;
  padding: 1.1rem 1.2rem;
  border-radius: var(--r-lg);
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.92) 0%, var(--surface-tint) 100%);
  border: 1px solid var(--line);
}

.studio-progress__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.75rem;
  margin-bottom: 0.7rem;
}

.studio-progress__head strong {
  font-family: "Fredoka", "Nunito", sans-serif;
  font-size: 1.05rem;
}

.studio-progress__count {
  font-weight: 800;
  color: var(--accent-strong);
  white-space: nowrap;
}

.studio-progress__bar {
  position: relative;
  height: 0.7rem;
  border-radius: 999px;
  background: rgba(108, 87, 145, 0.12);
  overflow: hidden;
}

.studio-progress__fill {
  position: relative;
  display: block;
  height: 100%;
  min-width: 0.7rem;
  border-radius: 999px;
  background: linear-gradient(90deg, var(--accent) 0%, var(--sun) 100%);
  transition: width 0.6s ease;
}

.studio-progress__fill.is-animating::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(
    90deg,
    transparent 0%,
    rgba(255, 255, 255, 0.55) 50%,
    transparent 100%
  );
  transform: translateX(-100%);
  animation: studio-shimmer 1.4s ease-in-out infinite;
}

@keyframes studio-shimmer {
  to {
    transform: translateX(100%);
  }
}

.studio-progress__note {
  margin: 0.6rem 0 0;
  font-size: 0.95rem;
}

.studio-message {
  margin: 1rem 0 0;
  padding: 0.85rem 1rem;
  border-radius: var(--r-md);
  font-size: 0.98rem;
}

.studio-message--info {
  border: 1px solid rgba(107, 143, 113, 0.32);
  background: rgba(216, 244, 216, 0.7);
  color: var(--mint-ink);
}

.studio-message--error {
  border: 1px solid rgba(239, 95, 63, 0.32);
  background: rgba(255, 209, 184, 0.5);
  color: var(--error-ink);
}

.studio-choice {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  padding: 1.3rem;
  border-radius: var(--r-lg);
  border: 1px solid var(--line);
  background: rgba(255, 255, 255, 0.6);
}

.studio-choice .value-split__tag {
  margin-bottom: 0.5rem;
}

.studio-choice h2 {
  font-size: 1.5rem;
  margin-bottom: 0.35rem;
}

.studio-choice .form-stack {
  margin-top: auto;
  padding-top: 0.85rem;
}

.studio-choice--print {
  background: linear-gradient(180deg, rgba(255, 247, 234, 0.7) 0%, rgba(255, 255, 255, 0.6) 100%);
}

.print-option {
  display: grid;
  gap: 0.55rem;
  padding: 0.85rem 0.95rem;
  border-radius: var(--r-md);
  background: rgba(255, 255, 255, 0.75);
  border: 1px solid var(--line);
}

.print-option__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.6rem;
}

.print-option__head strong {
  font-family: "Fredoka", "Nunito", sans-serif;
  font-size: 1.05rem;
}

.print-option button {
  width: 100%;
}

/* Clickwrap assent line directly under the buy button. */
.print-option__assent {
  margin: 0;
  font-size: 0.78rem;
  line-height: 1.4;
}

.studio-preview__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.75rem;
  flex-wrap: wrap;
}

.studio-preview__intro {
  margin-top: -0.4rem;
  max-width: 38rem;
}

.preview-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1.2rem;
  margin-top: 0.5rem;
}

.preview-grid .preview-card {
  margin: 0;
  display: flex;
  flex-direction: column;
  padding: 0.85rem;
  border-radius: var(--r-md);
  background: var(--surface-strong);
  border: 1px solid var(--line);
  box-shadow: var(--shadow-sm);
  transition: transform 0.2s ease, box-shadow 0.2s ease;
}

.preview-grid .preview-card--art:hover,
.preview-grid .preview-card--art:focus-within {
  transform: translateY(-4px);
  box-shadow: var(--shadow-lg);
}

.preview-card__art {
  border-radius: var(--r-md);
  overflow: hidden;
  background: #fff;
  border: 1px solid var(--line);
}

.preview-card__art img {
  display: block;
  width: 100%;
  aspect-ratio: var(--art-aspect);
  object-fit: contain;
}

.preview-card__art--placeholder {
  display: grid;
  place-items: center;
  aspect-ratio: var(--art-aspect);
  background:
    repeating-linear-gradient(
      135deg,
      rgba(108, 87, 145, 0.04) 0,
      rgba(108, 87, 145, 0.04) 10px,
      rgba(108, 87, 145, 0.07) 10px,
      rgba(108, 87, 145, 0.07) 20px
    );
}

.preview-card--generating .preview-card__art--placeholder {
  background: linear-gradient(110deg, var(--bg-soft) 8%, #fff 18%, var(--bg-soft) 33%);
  background-size: 220% 100%;
  animation: studio-skeleton 1.4s ease-in-out infinite;
}

@keyframes studio-skeleton {
  to {
    background-position: -220% 0;
  }
}

.preview-card--error .preview-card__art--placeholder {
  background: rgba(255, 209, 184, 0.35);
}

.preview-card__icon {
  font-size: 1.6rem;
  opacity: 0.6;
}

.preview-card--error .preview-card__icon {
  color: var(--accent-strong);
  opacity: 0.85;
}

.preview-card__spinner {
  width: 1.7rem;
  height: 1.7rem;
  border-radius: 50%;
  border: 3px solid rgba(255, 122, 89, 0.25);
  border-top-color: var(--accent);
  animation: studio-spin 0.8s linear infinite;
}

@keyframes studio-spin {
  to {
    transform: rotate(360deg);
  }
}

.preview-card figcaption {
  margin-top: 0.7rem;
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  min-width: 0;
}

.preview-card__num {
  font-size: 0.78rem;
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
}

.preview-card figcaption strong {
  overflow-wrap: anywhere;
  font-family: "Fredoka", "Nunito", sans-serif;
  font-size: 1rem;
}

.preview-card__story {
  margin: 0;
  overflow-wrap: anywhere;
  font-size: 0.9rem;
  line-height: 1.45;
  color: var(--muted);
}

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

@media (max-width: 420px) {
  .preview-grid {
    grid-template-columns: 1fr;
  }
}

/* Free page-1 "vibe" preview: the drawn first page beside its draw/adjust
   controls. Reuses the .preview-card art styling; this just lays the two out. */
.vibe-preview {
  border: 1px solid var(--line);
  border-radius: var(--r-xl);
  padding: 1.4rem;
  background: var(--surface-strong);
}

.vibe-preview__body {
  display: grid;
  grid-template-columns: minmax(0, 220px) minmax(0, 1fr);
  gap: 1.4rem;
  align-items: start;
  margin-top: 0.6rem;
}

.vibe-preview .preview-card {
  margin: 0;
}

.vibe-preview__controls {
  display: flex;
  flex-direction: column;
  gap: 0.85rem;
  align-items: flex-start;
}

.vibe-preview__edit,
.vibe-preview__actions {
  width: 100%;
}

.vibe-preview__edit textarea {
  width: 100%;
  min-height: 5rem;
}

.vibe-preview__cta {
  margin: 0.2rem 0 0;
}

@media (max-width: 620px) {
  .vibe-preview__body {
    grid-template-columns: 1fr;
  }
}

.book-status-panel .key-value {
  margin-bottom: 0.75rem;
}

.book-status-panel .key-value strong {
  font-family: "Fredoka", "Nunito", sans-serif;
}

.book-status-panel__detail {
  margin: 0.25rem 0 0;
}

.book-status-panel__progress {
  margin: 0.35rem 0 0;
  font-weight: 700;
  font-size: 0.92rem;
}

.book-status-panel__sub {
  margin-top: 1.5rem;
}

.book-outline {
  margin: 0;
  padding: 0.9rem 1rem;
  border-radius: var(--r-md);
  background: var(--surface-tint);
  border: 1px solid var(--line);
  font-family: "Nunito", sans-serif;
  font-size: 0.92rem;
  line-height: 1.55;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  max-height: 22rem;
  overflow-y: auto;
}

.empty-state {
  padding: 2rem;
  text-align: center;
}

.key-value {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: 0.35rem 0.9rem;
}

.table-shell {
  overflow-x: auto;
}

table {
  width: 100%;
  border-collapse: collapse;
}

th,
td {
  text-align: left;
  padding: 0.85rem 0.65rem;
  border-bottom: 1px solid rgba(108, 87, 145, 0.12);
}

@keyframes rise-in {
  from {
    opacity: 0;
    transform: translateY(18px);
  }

  to {
    opacity: 1;
    transform: translateY(0);
  }
}

@keyframes float-sheet {
  0%,
  100% {
    transform: translate(var(--sheet-x), 0) rotate(var(--sheet-tilt));
  }

  50% {
    transform: translate(var(--sheet-x), -12px) rotate(var(--sheet-tilt));
  }
}

@keyframes drift {
  0%,
  100% {
    transform: translateX(0);
  }

  50% {
    transform: translateX(12px);
  }
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation: none !important;
    transition: none !important;
    scroll-behavior: auto !important;
  }
}

@media (max-width: 960px) {
  .hero__inner,
  .two-column,
  .feature-grid,
  .pricing-grid,
  .dashboard-grid,
  .book-grid,
  .stats-grid,
  .story-grid,
  .studio-grid,
  .admin-grid,
  .journey,
  .idea-grid,
  .mini-pricing,
  .hero__proof {
    grid-template-columns: 1fr;
  }

  .sample-gallery {
    grid-template-columns: repeat(2, 1fr);
  }

  .site-header__inner,
  .site-footer__inner,
  .cta-banner__content {
    flex-direction: column;
    align-items: flex-start;
  }

  .hero__inner {
    min-height: auto;
    padding-top: 1rem;
  }

  .hero__copy h1,
  .hero__lede {
    max-width: 42rem;
  }

  .story-stage {
    min-height: 30rem;
  }

  .story-stage__sun {
    right: 2rem;
  }

  .story-sheet--one {
    left: 2rem;
  }

  .story-sheet--two {
    right: 2rem;
  }
}

@media (max-width: 720px) {
  .page-shell {
    width: min(100% - 1.25rem, 1180px);
  }

  /* Compact, single-row header on mobile: brand + a hamburger that opens the
     nav as an overlay panel, so the sticky bar reclaims the fold. */
  .site-header__inner {
    flex-direction: row;
    align-items: center;
    padding: 0.45rem 0;
    gap: 0.75rem;
  }

  .brand {
    gap: 0.6rem;
    min-height: 44px;
  }

  .brand__mark {
    width: 2.4rem;
    height: 2.4rem;
    box-shadow: 0 10px 22px rgba(255, 122, 89, 0.2);
  }

  .brand__lockup strong {
    font-size: 1.05rem;
  }

  /* Header keeps the bigger borderless storybook lockup on mobile too. */
  .site-header .brand__mark {
    width: 2.7rem;
    height: 2.7rem;
  }

  .site-header .brand__lockup strong {
    font-size: 1.55rem;
  }

  .brand__lockup small {
    display: none;
  }

  .site-menu {
    position: relative;
  }

  .site-menu__toggle {
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
    min-height: 44px;
    padding: 0 0.85rem;
    border-radius: 999px;
    background: var(--page);
    border: var(--bw) solid var(--ink);
    color: var(--ink);
    font-family: "Nunito", sans-serif;
    font-weight: 700;
    font-size: 0.95rem;
    cursor: pointer;
    list-style: none;
    box-shadow: 4px 5px 0 rgba(36, 29, 23, 0.13);
    -webkit-tap-highlight-color: transparent;
  }

  .site-menu__toggle::-webkit-details-marker {
    display: none;
  }

  .site-menu__toggle:focus-visible {
    outline: 3px solid var(--cornflower);
    outline-offset: 2px;
  }

  .site-menu__bars,
  .site-menu__bars::before,
  .site-menu__bars::after {
    content: "";
    display: block;
    width: 18px;
    height: 2.4px;
    border-radius: var(--r-sm);
    background: var(--ink);
  }

  .site-menu__bars {
    position: relative;
  }

  .site-menu__bars::before {
    position: absolute;
    top: -6px;
  }

  .site-menu__bars::after {
    position: absolute;
    top: 6px;
  }

  .site-menu[open] .site-menu__bars {
    background: transparent;
  }

  .site-menu[open] .site-menu__bars::before {
    top: 0;
    transform: rotate(45deg);
  }

  .site-menu[open] .site-menu__bars::after {
    top: 0;
    transform: rotate(-45deg);
  }

  .site-menu[open] .site-nav {
    position: absolute;
    top: calc(100% + 0.6rem);
    right: 0;
    flex-direction: column;
    align-items: stretch;
    flex-wrap: nowrap;
    gap: 0.25rem;
    min-width: 13.5rem;
    padding: 0.5rem;
    background: var(--page);
    border: var(--bw) solid var(--ink);
    border-radius: var(--r-lg);
    box-shadow: var(--shadow-sticker);
    z-index: 40;
  }

  .site-menu[open] .site-nav > * {
    width: 100%;
  }

  .site-menu[open] .site-nav a,
  .site-menu[open] .site-nav .button {
    display: flex;
    justify-content: flex-start;
    align-items: center;
    width: 100%;
    /* Reset the row-layout flex basis (1 1 9rem) so the vertical menu sizes
       items by content height (~44px), not a 9rem-tall flex basis. */
    flex: 0 0 auto;
    min-height: 44px;
    padding: 0.65rem 0.8rem;
    border-radius: var(--r-md);
    box-shadow: none;
  }

  .site-menu[open] .site-nav > a {
    color: var(--ink);
  }

  .site-menu[open] .site-nav > a:hover,
  .site-menu[open] .site-nav > a[aria-current="page"] {
    background: var(--t-butter);
  }

  /* The desktop underline accent would float oddly across a full-width vertical
     row, so the stacked menu uses the butter fill above as its current cue. */
  .site-menu[open] .site-nav > a[aria-current="page"]::after {
    display: none;
  }

  .hero {
    padding-top: 1.2rem;
  }

  h1 {
    font-size: 2.55rem;
    line-height: 1;
  }

  h2 {
    font-size: 1.8rem;
    line-height: 1.05;
  }

  .marketing-band,
  .cta-banner,
  .page-intro,
  .legal-wrap {
    padding: 1.15rem;
    border-radius: var(--r-md);
  }

  .path-card,
  .panel,
  .feature-card,
  .pricing-card,
  .dashboard-card,
  .book-card,
  .studio-card,
  .admin-card,
  .legal-card {
    border-radius: var(--r-md);
  }

  .sample-gallery {
    grid-template-columns: 1fr;
    gap: 1rem;
    margin-top: 1.5rem;
  }

  .story-stage {
    min-height: 28rem;
    border-radius: var(--r-md);
  }

  .story-stage__sun {
    width: 5.5rem;
    height: 5.5rem;
  }

  .story-sheet {
    width: 10.5rem;
    padding: 0.8rem;
  }

  .story-sheet--one {
    top: 7rem;
    left: 1.2rem;
  }

  .story-sheet--two {
    top: 12rem;
    right: 1rem;
  }

  .story-sheet--three {
    bottom: 5.2rem;
    width: 12rem;
  }

  .story-stage__badge {
    left: 1rem;
    right: 1rem;
    bottom: 1.2rem;
    display: grid;
    justify-content: stretch;
    gap: 0.2rem;
  }

  .site-nav {
    width: 100%;
    justify-content: flex-start;
    gap: 0.5rem;
  }

  .site-nav .button,
  .site-nav button {
    flex: 1 1 9rem;
  }

  .cta-banner__content .stack,
  .hero__copy .stack {
    width: 100%;
  }

  .cta-banner__content .button,
  .hero__copy .button {
    flex: 1 1 10rem;
  }
}

.status-badge {
  font-weight: 600;
  white-space: nowrap;
}

.status-ok {
  color: var(--status-ok);
}

.status-degraded {
  color: var(--status-warn);
}

.status-down {
  color: var(--status-down);
}

/* Free single-page funnel: email gate + result */
.free-page-gate {
  max-width: 640px;
}

.free-page-gate__note {
  margin-top: 0.5rem;
  font-size: 0.9rem;
}

.free-page-result {
  text-align: center;
}

.free-page-result__art {
  margin: 2rem auto;
  max-width: 560px;
}

.free-page-result__art img {
  width: 100%;
  border-radius: var(--r-xl);
  background: #fff;
  box-shadow: var(--shadow-md);
}

.free-page-result__actions {
  justify-content: center;
}

/* A quiet aside under the download buttons: the printable's blank "Colored by"
   line is the kid's to fill in, so it's a note, not an action. */
.free-page-result__sign {
  margin: 0.9rem auto 0;
  max-width: 34ch;
  text-align: center;
  font-size: 0.9rem;
  line-height: 1.45;
}

/* Just a modest reminder of what's being drawn — the prompt is a quiet caption,
   never the headline. Clamp long ideas to two lines so a paragraph-length prompt
   can't take over the wait screen. */
.free-page-result__prompt {
  margin: 0.75rem auto 0;
  max-width: 34ch;
  font-size: 1rem;
  font-style: italic;
  overflow-wrap: anywhere;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  overflow: hidden;
}

/* The words are the point — a small bouncing-crayon-dot indicator just keeps
   the wait feeling alive. Reduced-motion is handled by the global reset above. */
.free-page-result__step {
  margin-top: 1.5rem;
  font-size: 1.15rem;
  font-weight: 600;
  color: var(--accent);
  min-height: 1.5em;
}

.free-page-result__dots {
  display: flex;
  justify-content: center;
  gap: 0.5rem;
  margin-top: 0.85rem;
}

.free-page-result__dots span {
  width: 11px;
  height: 11px;
  border-radius: 50%;
  background: var(--accent);
  animation: free-page-bounce 1.1s ease-in-out infinite;
}

.free-page-result__dots span:nth-child(2) {
  animation-delay: 0.15s;
}

.free-page-result__dots span:nth-child(3) {
  animation-delay: 0.3s;
}

.free-page-result__hint {
  margin-top: 1rem;
  font-size: 0.9rem;
}

@keyframes free-page-bounce {
  0%, 80%, 100% {
    transform: translateY(0);
    opacity: 0.5;
  }
  40% {
    transform: translateY(-7px);
    opacity: 1;
  }
}

/* ---- result-page chrome on the v2 storybook brand ----
   The whole `<main>` opts into `.cb-page` (the scoped pattern from
   DESIGN_SYSTEM.md §6), so the eyebrow/heading/download buttons inherit the
   storybook system and read consistent with the keepsake + share cards below
   — no more legacy-purple heading or gradient buttons. These rules re-point the
   few legacy bits the `.free-page-result__*` primitives hard-coded (the cool
   `--accent` purple on the pending step + dots, the cool drop-shadow) to the
   warm brand, and recenter the heading so it lines up with the centered artwork
   and action row. */
.cb-page .free-page-result .section-heading {
  margin-inline: auto;
}

.cb-page .free-page-result__art img {
  box-shadow: var(--shadow-sticker);
}

.cb-page .free-page-result__step {
  color: var(--coral-deep);
}

.cb-page .free-page-result__dots span {
  background: var(--coral);
}

/* ---- result-page conversion surface (keepsake-book tease + share loop) ----
   Shown only in the ready state, below the download buttons. Wrapped in
   `.cb-page` so it inherits the storybook sticker system on a view that is
   otherwise legacy chrome. */
.cb-page.fp-next {
  margin: 3rem auto 0;
  max-width: 640px;
  padding: 0;
  background: none;
  text-align: left;
}

.cb-page .fp-keepsake {
  border: var(--bw) solid var(--ink);
  border-radius: var(--r-card);
  padding: 1.6rem 1.7rem;
  background:
    radial-gradient(34rem 18rem at 110% -20%, rgba(255, 178, 46, 0.22), transparent 62%),
    var(--page);
  box-shadow: var(--shadow-sticker);
}

.cb-page .fp-keepsake__title {
  margin: 0.7rem 0 0;
  font-size: 1.75rem;
  line-height: 1.12;
}

.cb-page .fp-keepsake__lede {
  margin: 0.6rem 0 1.2rem;
  color: var(--ink-soft);
  font-weight: 500;
  line-height: 1.55;
  max-width: 48ch;
}

.cb-page .fp-arc {
  list-style: none;
  margin: 1rem 0 1.2rem;
  padding: 0;
  display: grid;
  gap: 0.55rem;
}

.cb-page .fp-arc__beat {
  display: grid;
  grid-template-columns: auto 1fr;
  align-items: baseline;
  gap: 0.7rem;
  padding: 0.7rem 0.85rem;
  border: var(--bw) dashed var(--ink);
  border-radius: var(--r-card);
  background: var(--page);
}

.cb-page .fp-arc__page {
  font-weight: 700;
  font-size: 0.78rem;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: var(--ink-soft);
  white-space: nowrap;
}

.cb-page .fp-arc__line {
  color: var(--ink);
  font-weight: 500;
  line-height: 1.5;
}

.cb-page .fp-keepsake__cta {
  display: inline-flex;
}

.cb-page .fp-keepsake__fine {
  margin: 0.85rem 0.1rem 0;
  color: var(--ink-soft);
  font-weight: 600;
  font-size: 0.84rem;
  max-width: 46ch;
}

.cb-page .fp-keepsake__confirm {
  margin: 0.4rem 0 0;
  font-weight: 700;
  font-size: 1.05rem;
  color: var(--ink);
}

.cb-page .fp-share {
  margin-top: 1.4rem;
  padding: 1.2rem 1.4rem;
  border: var(--bw) dashed var(--ink);
  border-radius: var(--r-card);
  background: var(--page);
}

.cb-page .fp-share__line {
  margin: 0 0 0.9rem;
  color: var(--ink-soft);
  font-weight: 500;
  line-height: 1.5;
  max-width: 50ch;
}

.cb-page .fp-share__line strong {
  color: var(--ink);
}

.cb-page .fp-share__actions {
  flex-flow: row wrap;
  gap: 0.7rem;
}

@media (max-width: 520px) {
  .cb-page .fp-keepsake__cta,
  .cb-page .fp-share__actions .button {
    width: 100%;
  }
}

/* "Browse while you wait" gallery on the free-page result screen. A warm
   storybook band (.cb-page brings the crayon tokens + soft shadow) below the
   loader; it only renders while generating and vanishes on the full-page
   reload when the visitor's own art is ready, so there's no hide-on-ready JS
   and no layout shift. A wall of mini-cards — line art + the kid's idea. */
.cb-page.fp-wall {
  margin: 3.25rem auto 0;
  max-width: 1000px;
  padding: 2.5rem clamp(1.1rem, 4vw, 2.5rem) 2.75rem;
  border: var(--bw) solid var(--ink);
  border-radius: var(--r-card-lg);
  box-shadow: var(--shadow-sticker-lg);
  text-align: center;
}

.cb-page .fp-wall__head {
  max-width: 46ch;
  margin: 0 auto;
}

.cb-page .fp-wall__title {
  font-size: clamp(1.5rem, 3.4vw, 2.1rem);
  line-height: 1.12;
  margin: 0.55rem 0 0.3rem;
}

.cb-page .fp-wall__lede {
  font-size: 1.05rem;
  margin: 0;
}

.cb-page .fp-wall__grid {
  list-style: none;
  margin: 1.85rem 0 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
  gap: 1rem;
}

.cb-page .fp-wall__card {
  margin: 0;
  height: 100%;
  display: flex;
  flex-direction: column;
  gap: 0.45rem;
  background: var(--page);
  border: var(--bw) solid var(--ink);
  border-radius: var(--r-xl);
  padding: 0.5rem;
  box-shadow: var(--shadow-sticker);
  transition: transform 0.14s ease;
}

/* Sticker-wall charm: a gentle alternating tilt (rotate is its own property,
   so the hover translate and the bloom-pop transform stay independent). */
.cb-page .fp-wall__item:nth-child(odd) .fp-wall__card {
  rotate: -1.1deg;
}

.cb-page .fp-wall__item:nth-child(even) .fp-wall__card {
  rotate: 1.2deg;
}

.cb-page .fp-wall__card:hover {
  transform: translate(-2px, -3px);
}

.cb-page .fp-wall__art {
  aspect-ratio: 1;
  border-radius: var(--r-lg);
  overflow: hidden;
  background: #fff;
  border: 2px solid rgba(36, 29, 23, 0.1);
}

.cb-page .fp-wall__art img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.cb-page .fp-wall__cap {
  padding: 0 0.15rem 0.1rem;
  font-size: 0.8rem;
  line-height: 1.32;
  font-style: italic;
  color: var(--ink-soft);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* Staggered entrance: cards default visible, so without JS (or with reduced
   motion, which the global reset neutralizes) nothing is ever hidden. The
   reveal only runs once JS arms the wall with .is-live. */
.cb-page.fp-wall.is-live .fp-wall__item {
  animation: fp-wall-in 0.5s cubic-bezier(0.2, 0.7, 0.3, 1) both;
  animation-delay: calc(var(--i) * 45ms);
}

@keyframes fp-wall-in {
  from {
    opacity: 0;
    transform: translateY(12px) scale(0.96);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

/* A brief bloom-pop on one random card keeps the wall feeling alive during
   the wait (JS-driven, skipped under reduced motion). */
.cb-page .fp-wall__item.is-bloom .fp-wall__card {
  animation: fp-wall-bloom 0.9s ease;
}

@keyframes fp-wall-bloom {
  0%, 100% {
    transform: none;
    box-shadow: var(--shadow-sticker);
  }
  40% {
    transform: translateY(-7px) scale(1.045);
    box-shadow: var(--shadow-sticker-lg);
  }
}

@media (max-width: 560px) {
  .cb-page .fp-wall__grid {
    grid-template-columns: repeat(auto-fill, minmax(125px, 1fr));
    gap: 0.7rem;
  }
}

/* =====================================================================
   v2 DESIGN SYSTEM — the shared, reusable "crayon / storybook" system.
   ---------------------------------------------------------------------
   This is the FOUNDATION for the whole site, and there is ONE layer: put
   `.cb-page` on a page's <main> (or top wrapper) and you get the warm
   storybook system unconditionally — the crayon palette (from :root), the
   rounder radii + soft "hand-made" shadow, Nunito body + Fredoka display
   type, and every component primitive below: buttons, sticker eyebrows/
   kickers, cards, bands, the page-card, the spark composer, checklists.
   Nothing here is scoped to a single page; it is the system. (Genuinely
   additive storybook-only flourishes — hero doodles, the wave divider, the
   keepsake/ladder compositions — live in the "STORYBOOK FLOURISHES" block
   further down; they have no base equivalent to override.)

   Specificity note for new pages: override a component heading/numeral with
   a CLASS (`.cb-page .foo__title`) — never a bare `.foo h3`, which ties at
   (0,1,1) with `.cb-page h3` and then resolves by source order. See
   docs/DESIGN_SYSTEM.md §5. Build a new page by composing these classes.
   North star: docs/design/redesign-options/a-storybook-v2.html
   ===================================================================== */
.cb-page {
  /* The crayon-box palette + base form tokens (--bw, hard --shadow-sticker, etc.)
     come from :root and are inherited here. `.cb-page` only OVERRIDES the tokens
     the warm storybook treatment changes — rounder radii + the soft "hand-made"
     shadow — then sets the paper wash and the Nunito/Fredoka type. */
  --r-card: 26px;
  --r-card-lg: 38px;
  /* a soft, warm "hand-made" drop: a glow plus a faint sticker offset */
  --shadow-sticker: var(--shadow-warm);
  --shadow-sticker-lg: var(--shadow-warm-lg);

  /* warm cream "paper" with the faintest sun-washed blooms */
  background:
    radial-gradient(58rem 40rem at 88% -6%, rgba(255, 178, 46, 0.16), transparent 60%),
    radial-gradient(48rem 36rem at -8% 8%, rgba(242, 74, 92, 0.09), transparent 58%),
    radial-gradient(60rem 50rem at 50% 118%, rgba(63, 111, 229, 0.07), transparent 60%),
    #fbf4e4;
  color: var(--ink);
  font-family: "Nunito", ui-sans-serif, system-ui, sans-serif;
  font-size: 1.0625rem;
  overflow-x: clip;
}

.cb-page ::selection {
  background: var(--marigold);
  color: var(--ink);
}

.cb-page h1,
.cb-page h2,
.cb-page h3 {
  font-family: "Fredoka", system-ui, sans-serif;
  font-weight: 600;
  color: var(--ink);
  letter-spacing: 0;
}

.cb-page h1 {
  font-size: clamp(2.9rem, 7.4vw, 5.4rem);
  line-height: 1.04;
  margin: 0.3em 0 0.34em;
}

.cb-page h2 {
  font-size: clamp(2.15rem, 4.6vw, 3.4rem);
  line-height: 1.1;
  margin: 0.2em 0 0.32em;
}

.cb-page h3 {
  font-size: 1.4rem;
  margin: 0.1em 0 0.35em;
}

.cb-page .muted {
  color: var(--ink-soft);
  font-weight: 500;
}

.cb-page .section-heading {
  max-width: 52ch;
}

.cb-page .section-heading .muted {
  font-size: 1.2rem;
  line-height: 1.62;
}

/* ---- sticker eyebrow + kicker ---- */
.cb-page .eyebrow,
.cb-page .cb-kicker {
  display: inline-flex;
  align-items: center;
  gap: 0.5em;
  margin: 0 0 0.2em;
  font-family: "Nunito", sans-serif;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  font-size: 0.82rem;
  color: var(--ink);
  background: var(--marigold);
  border: var(--bw) solid var(--ink);
  border-radius: 999px;
  padding: 0.46em 1em;
  box-shadow: var(--shadow-sticker);
  rotate: -2deg;
}

.cb-page .cb-kicker {
  color: var(--coral-deep);
  background: var(--t-butter);
}

.cb-page .cb-kicker--sun {
  color: var(--ink);
  background: var(--marigold);
  rotate: 2deg;
}

.cb-page .eyebrow__dot {
  width: 0.5em;
  height: 0.5em;
  border-radius: 50%;
  background: var(--coral);
}

/* ---- squiggle-underlined word ---- */
.cb-page .cb-squig {
  position: relative;
  white-space: nowrap;
  color: var(--coral);
}

.cb-page .cb-squig__line {
  position: absolute;
  left: -2%;
  width: 104%;
  bottom: -0.22em;
  height: 0.46em;
  overflow: visible;
}

/* The squiggle stroke and the push-pin head are brand-coral. Driving them from
   the token here (a CSS property beats the inline SVG presentation attribute)
   keeps them on the single --brand knob — change --brand and these reskin too.
   Un-scoped so it covers every page, migrated or not. */
.cb-squig__line path {
  stroke: var(--coral);
}

.cb-pagecard__pin circle {
  fill: var(--coral);
}

/* ---- buttons (sticker treatment, scoped) ---- */
.cb-page .button {
  font-family: "Fredoka", system-ui, sans-serif;
  /* Fredoka is a display face — at button sizes its heavier weights read
     bloated, so buttons use its regular (normal, 400) weight. */
  font-weight: normal;
  font-size: 1.02rem;
  border: var(--bw) solid var(--ink);
  border-radius: 999px;
  padding: 0.82em 1.4em;
  background: var(--page);
  color: var(--ink);
  box-shadow: var(--shadow-sticker);
  transition: transform 0.12s ease, box-shadow 0.12s ease, background 0.15s ease;
  min-height: 0;
}

.cb-page .button:hover {
  transform: translate(-2px, -2px);
  box-shadow: var(--shadow-sticker-lg);
}

.cb-page .button:active {
  transform: translate(3px, 4px);
  box-shadow: 2px 2px 0 rgba(36, 29, 23, 0.16);
}

.cb-page .button--primary {
  background: var(--coral);
  color: #fff;
  /* the ink sticker offset PLUS a soft coral halo, so the one primary action
     reads as a confident, lit-up accent rather than a flat fill. */
  box-shadow: var(--shadow-sticker), 0 14px 26px -12px var(--coral);
}

.cb-page .button--primary:hover {
  box-shadow: var(--shadow-sticker-lg), 0 18px 30px -12px var(--coral);
}

.cb-page .button--sun {
  background: var(--marigold);
  color: var(--ink);
}

.cb-page .button:focus-visible,
.cb-page input:focus-visible {
  outline: 4px solid var(--cornflower);
  outline-offset: 3px;
}

/* Universal visible-focus for every interactive element under .cb-page: the
   standard 4px cornflower ring. Links carry their own color/underline styles;
   this only guarantees the ring is present and consistent (chips, theme cards,
   in-content links, the bloom tile, buttons all match). */
.cb-page a:focus-visible {
  outline: 4px solid var(--cornflower);
  outline-offset: 2px;
  border-radius: var(--r-sm);
}

/* ---- form fields on .cb-page (the free-page claim form + any marketing form) ----
   The system's sticker treatment for native form controls — ink-bordered,
   rounded, page-white, Nunito body face — matching the `.studio-surface`
   controls so a form reads the same on marketing and app surfaces. Submit
   buttons carry an explicit `.button` class (see the button rules above); this
   completes the field/label half the system was missing. */
.cb-page .field label {
  font-weight: 700;
  color: var(--ink);
  font-size: 0.95rem;
}

.cb-page .field input,
.cb-page .field select,
.cb-page .field textarea {
  background: var(--page);
  border: var(--bw) solid var(--ink);
  border-radius: var(--r-lg);
  color: var(--ink);
  font-family: "Nunito", ui-sans-serif, system-ui, sans-serif;
  font-size: 1rem;
  padding: 0.8rem 0.95rem;
}

.cb-page .field input::placeholder,
.cb-page .field textarea::placeholder {
  color: var(--ink-soft);
  opacity: 0.85;
}

.cb-page .field select:focus-visible,
.cb-page .field textarea:focus-visible {
  outline: 4px solid var(--cornflower);
  outline-offset: 3px;
}

/* The claim form on the result page (`.free-page-result` is centered): keep it a
   tidy, readable column with left-aligned labels rather than full-bleed. */
.cb-page .free-page-claim {
  max-width: 30rem;
  margin: 2rem auto 0;
  text-align: left;
}

/* ---- hero (position:relative anchors the absolutely-placed doodles) ---- */
.cb-page .hero {
  position: relative;
  padding: clamp(2rem, 5vw, 3.75rem) 0 clamp(1.5rem, 3vw, 2rem);
  overflow: visible;
}

.cb-page .hero__inner {
  position: relative;
  z-index: 1;
  grid-template-columns: minmax(0, 1.04fr) minmax(0, 0.96fr);
  gap: clamp(2rem, 5vw, 3.4rem);
  align-items: center;
}

/* Headline: two short sentences, each its own line. The phrase wrapper +
   text-wrap:balance and the &nbsp; glue in the markup keep "it up." from
   orphaning onto a line of its own while still wrapping gracefully when narrow. */
.cb-page .hero__copy h1.hero__headline {
  max-width: 13ch;
  text-wrap: balance;
}

.cb-page .hero__headline-line {
  display: block;
}

.cb-page .hero__lede {
  font-size: 1.2rem;
  line-height: 1.62;
  color: var(--ink-soft);
  font-weight: 500;
  max-width: 40ch;
}

/* primary book CTA + demoted free-page link */
.cb-page .hero__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.55rem 1.2rem;
  margin-top: 1.5rem;
}

.cb-page .button--hero {
  font-size: 1.08rem;
  padding: 0.92em 1.55em;
}

.cb-page .hero__try-link {
  font-weight: 700;
  font-size: 0.98rem;
  color: var(--coral-deep);
  text-decoration: none;
  text-underline-offset: 3px;
  white-space: nowrap;
}

.cb-page .hero__try-link:hover,
.cb-page .hero__try-link:focus-visible {
  text-decoration: underline;
}

/* spark composer — the hero's primary, prompt-first create surface */
.cb-page .hero__capture {
  margin-top: 1.6rem;
  max-width: 600px;
}

.cb-page .hero__capture--free {
  margin-top: 2rem;
  padding-top: 1.5rem;
  border-top: 2px dashed var(--hairline, rgba(36, 29, 23, 0.18));
}

.cb-page .hero__free-note {
  margin: 0 0 1rem;
  font-size: 0.98rem;
  font-weight: 500;
  color: var(--ink-soft);
  max-width: 46ch;
}

.cb-page .hero__free-note strong {
  color: var(--ink);
}

.cb-page .cb-composer__box {
  background: var(--page);
  border: var(--bw) solid var(--ink);
  border-radius: var(--r-card);
  box-shadow: var(--shadow-sticker);
  padding: 0.7rem 0.8rem 0.7rem 0.9rem;
  /* prompt-composer layout: a full-width textarea on top (so a whole example
     prompt fits), the submit button on its own row below */
  display: flex;
  flex-direction: column;
  gap: 0.55rem;
}

.cb-page .cb-composer__field {
  display: flex;
  align-items: flex-start;
  gap: 0.6rem;
}

.cb-page .cb-composer__foot {
  display: flex;
  justify-content: flex-end;
}

.cb-page .cb-composer__box:focus-within {
  /* cornflower is the brand visible-focus signal; marigold-on-cream was faint */
  outline: 4px solid var(--cornflower);
  outline-offset: 2px;
}

.cb-page .cb-composer__icon {
  display: inline-flex;
  color: var(--ink);
  flex: none;
  /* keep the pencil beside the first line as the textarea grows */
  padding-top: 0.5rem;
}

.cb-page .cb-composer input[type="text"],
.cb-page .cb-composer textarea {
  flex: 1;
  border: 0;
  background: transparent;
  font-family: inherit;
  font-size: 1.02rem;
  font-weight: 500;
  color: var(--ink);
  min-width: 0;
  padding: 0.4rem 0;
}

.cb-page .cb-composer textarea {
  resize: none;
  line-height: 1.4;
  /* tall enough for the longest example prompt to show in full (3 lines at
     narrow mobile widths) without truncation; JS auto-grows beyond this */
  min-height: 4.3em;
  max-height: 10em;
  overflow-y: auto;
}

.cb-page .cb-composer input[type="text"]::placeholder,
.cb-page .cb-composer textarea::placeholder {
  color: #a99c8e;
}

.cb-page .cb-composer input[type="text"]:focus,
.cb-page .cb-composer textarea:focus {
  outline: none;
}

.cb-page .cb-composer .button {
  flex: none;
  padding: 0.7em 1.05em;
  font-size: 0.98rem;
}

.cb-page .cb-sparks {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
  margin-top: 0.9rem;
}

.cb-page .cb-sparks__lead {
  font-weight: 700;
  font-size: 0.9rem;
  color: var(--ink-soft);
}

.cb-page .cb-chip {
  font-weight: 700;
  font-size: 0.9rem;
  text-decoration: none;
  border: var(--bw) solid var(--ink);
  background: var(--page);
  color: var(--ink);
  border-radius: 999px;
  padding: 0.46em 0.95em;
  line-height: 1.1;
  box-shadow: 4px 5px 0 rgba(36, 29, 23, 0.13);
  transition: transform 0.12s ease, box-shadow 0.12s ease;
}

.cb-page .cb-sparks .cb-chip:nth-of-type(odd) {
  rotate: -2.5deg;
}

.cb-page .cb-sparks .cb-chip:nth-of-type(even) {
  rotate: 2deg;
}

.cb-page .cb-chip:hover {
  transform: translate(-2px, -2px);
  box-shadow: 6px 7px 0 rgba(36, 29, 23, 0.15);
}

.cb-page .cb-chip[aria-current="true"] {
  background: var(--marigold);
  box-shadow: 2px 2px 0 rgba(36, 29, 23, 0.16);
}

.cb-page .cb-chip[aria-current="true"]::before {
  content: "";
  width: 0.62em;
  height: 0.62em;
  margin-right: 0.1em;
  display: inline-block;
  vertical-align: middle;
  border-radius: 999px;
  background: var(--coral-deep, #d93a4b);
  border: 1.5px solid var(--ink);
}

/* the waitlist promo is deliberately quiet — the prompt composer is the star */
.cb-page .hero__secondary {
  margin-top: 1.4rem;
  color: var(--ink-soft);
  font-weight: 500;
  font-size: 0.85rem;
  opacity: 0.9;
}

.cb-page .hero__secondary .link-arrow {
  font-size: 0.85rem;
}

.cb-page .link-arrow {
  color: var(--coral-deep);
  font-weight: 700;
}

/* trust strip */
.cb-page .trust-strip {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1.25rem;
  margin: 1.4rem 0 0;
  padding: 0;
  list-style: none;
  font-weight: 600;
  font-size: 0.95rem;
}

.cb-page .trust-strip li {
  display: inline-flex;
  align-items: center;
  gap: 0.45em;
}

.cb-page .trust-strip li::before {
  content: "";
  width: 1.05em;
  height: 1.05em;
  flex: none;
  background: no-repeat center / contain
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%231fa868' stroke-width='2.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6 9 17l-5-5'/%3E%3C/svg%3E");
}

/* hero page-card (fridge-art vibe) */
.cb-page .hero-visual {
  display: flex;
  justify-content: center;
}

.cb-page .cb-pagecard {
  position: relative;
  background: var(--page);
  border: var(--bw) solid var(--ink);
  border-radius: var(--r-card-lg);
  box-shadow: var(--shadow-sticker);
  padding: 1.1rem 1.1rem 0.9rem;
  transform: rotate(-1.8deg);
  max-width: 380px;
  width: 100%;
}

.cb-page .cb-pagecard::before {
  content: "";
  position: absolute;
  inset: 0.6rem;
  border: 2px dashed rgba(36, 29, 23, 0.16);
  border-radius: 20px;
  pointer-events: none;
  z-index: 1;
}

.cb-page .cb-pagecard__tape {
  position: absolute;
  top: -14px;
  left: 50%;
  transform: translateX(-50%) rotate(-3deg);
  width: 120px;
  height: 26px;
  background: rgba(255, 178, 46, 0.62);
  border: 2px solid rgba(36, 29, 23, 0.4);
  border-radius: var(--r-sm);
  z-index: 2;
}

.cb-page .cb-pagecard__page {
  position: static;
  width: 100%;
  margin: 0;
  padding: 0;
  transform: none;
  border: 2px solid rgba(36, 29, 23, 0.1);
  border-radius: var(--r-xl);
  overflow: hidden;
  background: #fff;
  box-shadow: none;
  animation: none;
}

.cb-page .cb-pagecard__page img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: auto;
  object-fit: contain;
  border: 0;
  border-radius: 0;
  transition: opacity 0.22s ease;
}

.cb-page .cb-pagecard__page img.is-swapping {
  opacity: 0;
}

.cb-page .cb-pagecard__cap {
  display: flex;
  align-items: flex-start;
  gap: 0.55rem;
  margin-top: 0.6rem;
  padding: 0 0.2rem;
}

.cb-page .cb-pagecard__pin {
  flex: none;
  margin-top: 0.2rem;
}

.cb-page .cb-pagecard__cap p {
  flex: 1;
  min-width: 0;
  margin: 0;
  font-style: italic;
  color: var(--ink-soft);
  font-weight: 500;
  font-size: 0.92rem;
  line-height: 1.35;
}

/* ---- section bands ---- */
/* soft warm hairline rules (cozier than the bold sticker border) */
.cb-page .cb-band {
  border-top: 2px solid rgba(36, 29, 23, 0.1);
  border-bottom: 2px solid rgba(36, 29, 23, 0.1);
  margin-top: clamp(1.5rem, 4vw, 2.5rem);
}

.cb-page .cb-band--mint {
  background: #e8f6ee;
}

/* the dark CTA band keeps the bold ink rule */
.cb-page .cb-band--ink {
  background: var(--ink);
  color: var(--paper);
  border-color: var(--ink);
}

.cb-page .cb-band--butter {
  background: #fff3d6;
}

/* the brand-accent band — a soft coral wash under a confident coral top rule, so
   the accent finally carries a large surface (not just the CTAs). The wash stays
   light for AA body copy; the boldness lives in the 3px coral rule + the coral
   heading marks/CTAs that sit on it. Used on each page's key section. */
.cb-page .cb-band--coral {
  background: var(--t-coral);
  border-top: 3px solid var(--coral);
}

.cb-page .cb-band--ink h2 {
  color: var(--paper);
}

/* ---- how it works ---- */
.cb-page .journey {
  gap: 1.4rem;
  margin-top: 1.5rem;
}

.cb-page .path-card {
  background: var(--page);
  border: var(--bw) solid var(--ink);
  border-radius: var(--r-card);
  padding: 1.6rem 1.5rem 1.75rem;
  box-shadow: var(--shadow-sticker);
}

.cb-page .path-card__step {
  /* numerals use the system display face (Fredoka 600), matching the headings
     and the keepsake price — never the legacy Comic Neue. */
  font-family: "Fredoka", sans-serif;
  font-weight: 600;
  font-size: 3.2rem;
  line-height: 0.8;
  display: block;
  margin-bottom: 0.6rem;
  color: var(--coral);
}

.cb-page .journey .path-card:nth-child(2) .path-card__step {
  color: var(--cornflower);
}

.cb-page .journey .path-card:nth-child(3) .path-card__step {
  color: var(--grass);
}

.cb-page .path-card h3 {
  /* Match the system's storybook h3 weight (600). Was 700 when this lived
     under the higher-specificity `.marketing-home.storybook h3` rule; keep the
     card titles on the lyrical Fredoka 600 the live home ships. */
  font-weight: 600;
}

.cb-page .path-card p {
  margin: 0;
  font-weight: 500;
}

/* ---- samples gallery ---- */
.cb-page .sample-gallery {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1.25rem;
  margin-top: 1.5rem;
}

.cb-page .sample-card {
  background: var(--page);
  border: var(--bw) solid var(--ink);
  border-radius: var(--r-card);
  padding: 0.85rem;
  box-shadow: var(--shadow-sticker);
  transition: transform 0.14s ease;
}

.cb-page .sample-card:hover {
  transform: translate(-2px, -3px);
}

.cb-page .sample-card__art {
  border-radius: var(--r-lg);
  overflow: hidden;
  background: #fff;
  border: 2px solid rgba(36, 29, 23, 0.1);
}

.cb-page .sample-card__art img {
  display: block;
  width: 100%;
  height: auto;
}

.cb-page .sample-card figcaption {
  display: grid;
  gap: 0.15rem;
  margin-top: 0.7rem;
}

.cb-page .sample-card figcaption strong {
  font-weight: 800;
  font-size: 1rem;
}

.cb-page .sample-card figcaption .muted {
  font-size: 0.9rem;
  font-style: italic;
  line-height: 1.35;
}

/* ---- hover-to-colorize crossfade ---- */
.cb-page .sample-card--colorize .sample-card__art {
  position: relative;
}

.cb-page .sample-card--colorize .sample-card__art:focus-visible {
  outline: 4px solid var(--cornflower);
  outline-offset: 3px;
}

.cb-page .sample-card__line,
.cb-page .sample-card__color {
  display: block;
  width: 100%;
  height: auto;
}

/* Colored layer stacks over the line art and crossfades in on reveal. */
.cb-page .sample-card__color {
  position: absolute;
  inset: 0;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  transition: opacity 0.5s ease;
  pointer-events: none;
}

/* Mouse: reveal while hovering the card (hover-capable devices only, so the
   colored layer never sticks after a tap on touch screens). */
@media (hover: hover) {
  .cb-page .sample-card--colorize:hover .sample-card__color {
    opacity: 1;
  }
}

/* Keyboard + touch: focusing the tile (Tab, or a tap on mobile) reveals it. */
.cb-page .sample-card--colorize .sample-card__art:focus .sample-card__color,
.cb-page .sample-card--colorize .sample-card__art:focus-within .sample-card__color {
  opacity: 1;
}

/* Discoverability hint — a small sticker badge on hover-capable devices.
   Sits idle on the tile and fades out as the color blooms in. */
.cb-page .sample-card__hint {
  position: absolute;
  right: 0.5rem;
  bottom: 0.5rem;
  z-index: 1;
  padding: 0.2rem 0.55rem;
  border: 2px solid var(--ink);
  border-radius: 999px;
  background: var(--sun, #ffd766);
  color: var(--ink);
  font-family: "Fredoka", sans-serif;
  font-weight: 600;
  font-size: 0.74rem;
  line-height: 1;
  box-shadow: 0 2px 0 rgba(36, 29, 23, 0.25);
  opacity: 0;
  transition: opacity 0.2s ease;
}

@media (hover: hover) {
  .cb-page .sample-card--colorize:not(:hover) .sample-card__hint {
    opacity: 0.92;
  }
}

/* Reduced motion: reveal instantly, no crossfade or hint animation. */
@media (prefers-reduced-motion: reduce) {
  .cb-page .sample-card__color,
  .cb-page .sample-card__hint {
    transition: none;
  }
}

/* ---- colored-in showcase ---- */
.cb-page .cb-colored {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 1.3rem;
  margin-top: 1.75rem;
}

.cb-page .cb-colored__card {
  position: relative;
  margin: 0;
  background: var(--page);
  border: var(--bw) solid var(--ink);
  border-radius: var(--r-card);
  padding: 0.7rem 0.7rem 0.85rem;
  box-shadow: var(--shadow-sticker);
  transition: transform 0.14s ease, box-shadow 0.14s ease, rotate 0.14s ease;
}

.cb-page .cb-colored__card:nth-child(odd) {
  rotate: -1.4deg;
}

.cb-page .cb-colored__card:nth-child(even) {
  rotate: 1.4deg;
}

.cb-page .cb-colored__card:hover {
  transform: translate(-2px, -3px);
  box-shadow: var(--shadow-sticker-lg);
  rotate: 0deg;
}

.cb-page .cb-colored__tape {
  position: absolute;
  top: -12px;
  left: 50%;
  transform: translateX(-50%) rotate(-3deg);
  width: 92px;
  height: 24px;
  background: rgba(255, 178, 46, 0.62);
  border: 2px solid rgba(36, 29, 23, 0.4);
  border-radius: var(--r-sm);
  z-index: 2;
}

.cb-page .cb-colored__art {
  border-radius: var(--r-lg);
  overflow: hidden;
  background: #fff;
  border: 2px solid rgba(36, 29, 23, 0.1);
}

.cb-page .cb-colored__art img {
  display: block;
  width: 100%;
  height: auto;
}

.cb-page .cb-colored__card figcaption {
  margin-top: 0.65rem;
  text-align: center;
  font-weight: 800;
  font-size: 0.94rem;
  color: var(--ink);
}

.cb-page .cb-colored__note {
  margin: 1.6rem auto 0;
  max-width: 52ch;
  text-align: center;
  font-weight: 600;
}

/* ---- modes (free vs printed book) ---- */
.cb-page .cb-modes {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1.5rem;
  margin-top: 1.5rem;
}

/* FAQ Q&A grid — two-up, but a lone trailing card spans the full width so an
   odd-count section never leaves an orphaned half-width card. (Don't borrow
   `.cb-modes`, which is a fixed two-up built for the free-vs-printed pair.) */
.cb-page .cb-faq-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1.5rem;
  margin-top: 1.5rem;
}

.cb-page .cb-faq-grid > .path-card:last-child:nth-child(odd) {
  grid-column: 1 / -1;
}

.cb-page .cb-mode {
  border: var(--bw) solid var(--ink);
  border-radius: var(--r-card-lg);
  padding: 1.9rem 1.9rem 2rem;
  box-shadow: var(--shadow-sticker);
}

.cb-page .cb-mode--free {
  background: var(--t-blush);
}

.cb-page .cb-mode--paid {
  background: var(--t-sky);
}

.cb-page .cb-mode__tag {
  display: inline-block;
  font-weight: 800;
  font-size: 0.78rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: #fff;
  border: var(--bw) solid var(--ink);
  border-radius: 999px;
  padding: 0.36em 0.9em;
  box-shadow: var(--shadow-sticker);
  rotate: -2.5deg;
}

.cb-page .cb-mode__tag--free {
  background: var(--coral-deep);
}

.cb-page .cb-mode__tag--paid {
  background: var(--cornflower);
}

.cb-page .cb-mode h3 {
  font-size: 1.7rem;
  margin: 0.55em 0 0.2em;
}

.cb-page .cb-mode > p {
  margin: 0 0 1.1rem;
  color: var(--ink-soft);
  font-weight: 500;
}

/* shared ink-check list */
.cb-page .cb-checklist {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.55rem;
}

.cb-page .cb-checklist li {
  position: relative;
  padding-left: 1.7rem;
  font-weight: 600;
  font-size: 0.98rem;
}

.cb-page .cb-checklist li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.12em;
  width: 1.15em;
  height: 1.15em;
  background: no-repeat center / contain
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%233a2e25' stroke-width='2.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6 9 17l-5-5'/%3E%3C/svg%3E");
}

/* ---- pricing ---- */
.cb-page .cb-prices {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1.4rem;
  margin-top: 1.5rem;
  align-items: stretch;
}

.cb-page .cb-price {
  background: var(--page);
  border: var(--bw) solid var(--ink);
  border-radius: var(--r-card);
  padding: 1.75rem 1.6rem 1.9rem;
  box-shadow: var(--shadow-sticker);
  display: flex;
  flex-direction: column;
}

.cb-page .cb-price--free {
  background: var(--marigold);
}

.cb-page .cb-price__name {
  font-weight: 800;
  font-size: 1.05rem;
}

.cb-page .cb-price__amt {
  /* system display face (Fredoka 600) — consistent with the keepsake price and
     the headings; not the legacy Comic Neue. */
  font-family: "Fredoka", sans-serif;
  font-weight: 600;
  font-size: 2.7rem;
  line-height: 1;
  margin: 0.18em 0 0.1em;
}

.cb-page .cb-price__amt small {
  font-family: "Nunito", sans-serif;
  font-size: 0.9rem;
  font-weight: 700;
  color: var(--ink-soft);
}

.cb-page .cb-price .cb-checklist {
  margin: 0.9rem 0 1.4rem;
}

.cb-page .cb-price .button {
  margin-top: auto;
}

.cb-page .cb-price__note {
  margin-top: 1.1rem;
  text-align: center;
  font-weight: 600;
}

/* ---- launch list band ---- */
.cb-page .cb-launch {
  display: grid;
  grid-template-columns: 1.1fr 0.9fr;
  gap: clamp(1.75rem, 4vw, 3rem);
  align-items: center;
}

.cb-page .cb-launch__lede {
  color: #d9cfc4;
  font-weight: 500;
  font-size: 1.1rem;
  max-width: 46ch;
}

.cb-page .cb-signup {
  background: var(--page);
  border: var(--bw) solid var(--ink);
  border-radius: var(--r-card);
  padding: 1rem;
  box-shadow: var(--shadow-sticker);
}

.cb-page .cb-signup__row {
  display: flex;
  gap: 0.6rem;
}

.cb-page .cb-signup input[type="email"] {
  flex: 1;
  border: 2.4px solid var(--ink);
  border-radius: var(--r-xl);
  padding: 0.8em 1em;
  font-family: inherit;
  font-size: 1rem;
  font-weight: 500;
  color: var(--ink);
  background: #fff;
  min-width: 0;
}

.cb-page .cb-signup .button {
  flex: none;
}

.cb-page .cb-signup__fine {
  color: var(--ink-soft);
  font-weight: 600;
  font-size: 0.86rem;
  margin: 0.7rem 0.2rem 0;
}

/* ---- final cta ---- */
.cb-page .cb-finalcta {
  text-align: center;
}

.cb-page .cb-finalcta .section-heading,
.cb-page .cb-finalcta .muted {
  max-width: 46ch;
  margin-left: auto;
  margin-right: auto;
}

.cb-page .cb-finalcta__row {
  justify-content: center;
  margin-top: 1.2rem;
}

/* ---- responsive ---- */
@media (max-width: 940px) {
  .cb-page .hero__inner {
    grid-template-columns: minmax(0, 1fr);
  }
  .cb-page .cb-pagecard {
    transform: none;
    margin: 0 auto;
  }
  .cb-page .cb-modes,
  .cb-page .cb-faq-grid,
  .cb-page .cb-launch {
    grid-template-columns: 1fr;
  }
  .cb-page .sample-gallery,
  .cb-page .cb-colored,
  .cb-page .cb-prices {
    grid-template-columns: 1fr 1fr;
  }
}

@media (max-width: 600px) {
  .cb-page .journey,
  .cb-page .sample-gallery,
  .cb-page .cb-prices {
    grid-template-columns: 1fr;
  }
  .cb-page .cb-colored {
    grid-template-columns: 1fr 1fr;
    gap: 0.9rem;
  }
  .cb-page .cb-composer__foot .button {
    width: 100%;
  }
  .cb-page .cb-signup__row {
    flex-direction: column;
  }
  .cb-page .cb-signup .button {
    width: 100%;
  }
}

@media (prefers-reduced-motion: reduce) {
  .cb-page .button,
  .cb-page .cb-chip,
  .cb-page .sample-card,
  .cb-page .cb-colored__card,
  .cb-page .cb-pagecard__page img {
    transition: none;
  }
}

/* =====================================================================
   v2 DESIGN SYSTEM — STORYBOOK FLOURISHES.
   ---------------------------------------------------------------------
   Additive `.cb-page` rules with no equivalent in the system block above:
   the hand-drawn hero doodles + torn-paper wave, the generous section
   rhythm, the home header lockup, and the keepsake / pricing-ladder
   compositions. The tokens, type, shadow, bands, and component primitives
   all live in the SINGLE `.cb-page` system block above — there is no
   separate "bold base" layer to override, and `.cb-page` is unconditionally
   the warm storybook system.
   ===================================================================== */

/* CTAs use the Fredoka display face via `.cb-page .button` (above). This rule
   also re-faces BARE native controls (`button`, `input[type="submit"]`) inside
   a `.cb-page` — fine for marketing pages, but the studio/app must opt in with a
   scoped wrapper, not a blanket `.cb-page` (see DESIGN_SYSTEM.md §6). */
.cb-page button,
.cb-page input[type="submit"] {
  font-family: "Fredoka", system-ui, sans-serif;
}

/* generous, gentle section rhythm */
.cb-page .sb-section {
  padding-block: clamp(3rem, 7vw, 5.5rem);
}

.cb-page .section-heading.sb-heading {
  max-width: 56ch;
  margin-inline: auto;
  text-align: center;
}

.cb-page .cb-launch .section-heading,
.cb-page .cb-launch.sb-heading {
  text-align: left;
}

/* center the kicker stickers above centered headings */
.cb-page .sb-heading .cb-kicker {
  margin-inline: auto;
}

/* Coral crayon-stroke mark under the section headline — a short, thick, rounded
   accent that threads the brand color through every section header (home,
   pricing, faq) instead of leaving each h2 unaccented ink. Decorative only. */
.cb-page .sb-heading h2::after,
.cb-page .cb-finalcta h2::after {
  content: "";
  display: block;
  width: 3.4rem;
  height: 6px;
  margin: 0.85rem auto 0;
  border-radius: 999px;
  background: var(--coral);
}

/* on the dark ink CTA band the mark would clash with the sun kicker — the band
   carries its own accent, so suppress the coral rule there. */
.cb-page .cb-band--ink .sb-heading h2::after {
  display: none;
}

/* ---- hand-drawn hero doodles (absolutely placed inside the relative .hero) ---- */
.cb-page .sb-doodles {
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 0;
}

.cb-page .sb-doodle {
  position: absolute;
  filter: drop-shadow(2px 3px 0 rgba(36, 29, 23, 0.06));
}

.cb-page .sb-doodle--spark-a {
  width: 2.6rem;
  top: 6%;
  left: 3%;
  rotate: -8deg;
  animation: sb-float 7s ease-in-out infinite;
}

.cb-page .sb-doodle--swirl {
  width: 4.2rem;
  top: 2%;
  right: 6%;
  rotate: 6deg;
  animation: sb-float 9s ease-in-out infinite 0.6s;
}

.cb-page .sb-doodle--spark-b {
  width: 1.8rem;
  top: 46%;
  right: 2%;
  animation: sb-float 6s ease-in-out infinite 1.2s;
}

.cb-page .sb-doodle--loop {
  width: 4.6rem;
  bottom: 9%;
  left: 1%;
  rotate: -4deg;
  animation: sb-float 8s ease-in-out infinite 0.3s;
}

.cb-page .sb-doodle--dots {
  width: 3rem;
  bottom: 16%;
  right: 8%;
  rotate: -10deg;
  animation: sb-float 7.5s ease-in-out infinite 0.9s;
}

@keyframes sb-float {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-7px); }
}

/* ---- torn-paper wave divider under the hero ---- */
.cb-page .sb-wave {
  line-height: 0;
  margin-top: clamp(0.5rem, 2vw, 1.5rem);
}

.cb-page .sb-wave svg {
  display: block;
  width: 100%;
  height: clamp(22px, 3vw, 36px);
}

@media (max-width: 600px) {
  .cb-page .sb-doodle--swirl,
  .cb-page .sb-doodle--loop {
    display: none;
  }
}

@media (prefers-reduced-motion: reduce) {
  .cb-page .sb-doodle {
    animation: none;
  }
}

/* The storybook header lockup is now the GLOBAL default (see `.site-header`
   chrome + `.brand__lockup strong` near the top of this file). The old
   `body.marketing--home`-scoped override has been removed so there is one
   source of truth for the header on every page. */

/* lead-in line above the spark composer (owner refinement) */
.cb-page .hero__sample-lead {
  margin: 1.5rem 0 0.55rem;
  font-weight: 700;
  font-size: 0.95rem;
  color: var(--ink-soft);
}

/* mobile hero: smaller coloring-page image ON TOP, offer visible at once */
@media (max-width: 760px) {
  .cb-page .hero__inner {
    display: flex;
    flex-direction: column;
    /* reset the desktop grid's align-items:center — in a flex column it sizes
       children to max-content (not the container), so the copy shrink-wrapped to
       the un-wrapped H1 line and bled off both edges. Stretch keeps it contained. */
    align-items: stretch;
  }
  .cb-page .hero-visual {
    order: -1;
  }
  .cb-page .cb-pagecard {
    max-width: 228px;
    margin: 0 auto 0.25rem;
    transform: rotate(-1.8deg);
  }
  .cb-page .hero__actions {
    margin-top: 1.1rem;
  }
}

/* printed keepsake — three overlapping colored pages framing the book */
.cb-page .cb-keepsake__inner {
  display: grid;
  grid-template-columns: minmax(0, 0.95fr) minmax(0, 1.05fr);
  gap: clamp(2rem, 6vw, 4.5rem);
  align-items: center;
}

.cb-page .cb-keepsake__media {
  position: relative;
  min-height: 23rem;
  display: flex;
  justify-content: center;
  align-items: center;
}

.cb-page .cb-keepsake__page {
  margin: 0;
  background: var(--page);
  border: var(--bw) solid var(--ink);
  border-radius: var(--r-xl);
  overflow: hidden;
  box-shadow: var(--shadow-sticker);
}

.cb-page .cb-keepsake__page img {
  display: block;
  width: 100%;
  height: auto;
}

.cb-page .cb-keepsake__page--front {
  position: relative;
  z-index: 3;
  width: min(58%, 15.5rem);
  rotate: -2deg;
  box-shadow: var(--shadow-sticker-lg);
}

.cb-page .cb-keepsake__page--back-l {
  position: absolute;
  z-index: 1;
  width: min(48%, 12.5rem);
  left: 2%;
  top: 13%;
  rotate: -9deg;
}

.cb-page .cb-keepsake__page--back-r {
  position: absolute;
  z-index: 2;
  width: min(50%, 13rem);
  right: 1%;
  top: 5%;
  rotate: 8deg;
}

.cb-page .cb-keepsake__copy h2 {
  max-width: 20ch;
}

.cb-page .cb-keepsake__copy > .muted {
  margin: 0 0 1.6rem;
}

.cb-page .cb-quality {
  list-style: none;
  margin: 0 0 2rem;
  padding: 0;
  display: grid;
  gap: 0.9rem;
}

.cb-page .cb-quality li {
  position: relative;
  padding-left: 1.95rem;
  font-weight: 500;
  font-size: 1rem;
  color: var(--ink-soft);
  line-height: 1.5;
}

.cb-page .cb-quality li strong {
  color: var(--ink);
  font-weight: 800;
}

.cb-page .cb-quality li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.05em;
  width: 1.3em;
  height: 1.3em;
  background: no-repeat center / contain url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23e8654e' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'/%3E%3Cpath d='M8 12.5l2.5 2.5L16 9'/%3E%3C/svg%3E");
}

.cb-page .cb-keepsake__foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 1.1rem 1.6rem;
}

.cb-page .cb-keepsake__price {
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
}

.cb-page .cb-keepsake__price-label {
  font-size: 0.8rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--ink-soft);
}

.cb-page .cb-keepsake__price-amt {
  font-family: "Fredoka", sans-serif;
  font-weight: 600;
  font-size: 2rem;
  line-height: 1;
  color: var(--ink);
}

/* printed-book product shot — a clean cut-out of the real open book,
   floating on the cream band (no frame, no props) with a soft contact shadow
   and a slight tilt so it reads as the tilted keepsake hero. */
.cb-page .cb-bookshot {
  position: relative;
  margin: 0;
  width: 100%;
  max-width: 34rem;
  rotate: -2deg;
}

.cb-page .cb-bookshot img {
  display: block;
  width: 100%;
  height: auto;
  filter: drop-shadow(8px 12px 16px rgba(150, 96, 40, 0.22));
}

@media (max-width: 820px) {
  .cb-page .cb-keepsake__inner {
    grid-template-columns: 1fr;
  }
  .cb-page .cb-keepsake__media {
    min-height: 19rem;
    margin-bottom: 0.5rem;
  }
  .cb-page .cb-bookshot {
    max-width: 28rem;
  }
}

/* pricing ladder — B-bold aesthetic: thick borders, tilt, burst flag */
.cb-page .cb-prices--ladder {
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 1.1rem;
  align-items: stretch;
}

.cb-page .cb-prices--ladder .cb-price {
  border-width: 3px;
  position: relative;
}

.cb-page .cb-price--sample {
  background: var(--marigold);
  rotate: -1.2deg;
}

.cb-page .cb-price__sub {
  margin: 0.15rem 0 0.25rem;
  font-weight: 700;
  font-size: 0.85rem;
  color: var(--ink-soft);
}

/* the free card sits on marigold — ink-soft fails AA there, use full ink */
.cb-page .cb-price--sample .cb-price__sub {
  color: var(--ink);
}

.cb-page .cb-price--featured {
  background: #fff3d6;
  rotate: 1.4deg;
  border-color: var(--coral);
  box-shadow: var(--shadow-sticker-lg);
}

/* the recommended tier's price in the brand accent — ties the number to the
   coral border + flag and pulls the eye to the pick. --coral-deep on the butter
   card is ~4.2:1, clearing AA for this large (2.7rem) numeral. */
.cb-page .cb-price--featured .cb-price__amt {
  color: var(--coral-deep);
}

.cb-page .cb-price__flag {
  position: absolute;
  top: -1.05rem;
  right: -0.6rem;
  z-index: 3;
  background: var(--coral);
  /* ink-on-coral clears AA at this small pill size; white-on-coral did not */
  color: var(--ink);
  font-family: "Fredoka", sans-serif;
  font-weight: 600;
  font-size: 0.8rem;
  padding: 0.3em 0.85em;
  border: 2.5px solid var(--ink);
  border-radius: 999px;
  rotate: 6deg;
}

.cb-page .cb-prices--ladder .cb-checklist {
  font-size: 0.92rem;
}

@media (max-width: 940px) {
  .cb-page .cb-prices--ladder {
    grid-template-columns: 1fr 1fr;
  }
}

@media (max-width: 560px) {
  .cb-page .cb-prices--ladder {
    grid-template-columns: 1fr;
  }
}

/* ---- .cb-texthero — the interior text hero (a SYSTEM component) ----
   The one treatment every copy-only interior hero shares: /pricing, /faq,
   /coloring-pages (index + theme), /blog. It anchors the storybook doodles
   inside the hero (heading above them) and sizes the long descriptive SEO
   headline a notch down from the home's punchy 5.4rem display hero, so it
   settles into two or three balanced lines instead of ballooning to five.
   The headline wraps freely (no &nbsp; glue) with an overflow-wrap guard so
   it can never clip off a narrow phone.

   Add `cb-texthero` to the hero <section>; keep the page's own hook class
   (`pricing-hero`, `cp-hero`, …) for structure + tests. The treatment is
   deliberately NOT keyed to those hooks: it used to be a hand-maintained
   selector list, and /blog shipped without joining it — its h1 rendered at
   the home's 86px inside a 52ch measure, five lines deep. One class, one
   place to join. */
.cb-page .cb-texthero {
  position: relative;
  overflow: visible;
}

.cb-page .cb-texthero > .section-heading {
  position: relative;
  z-index: 1;
  max-width: 44rem;
}

.cb-page .cb-texthero h1 {
  font-size: clamp(2.15rem, 5vw, 3.6rem);
  max-width: 22ch;
  margin-inline: auto;
  text-wrap: balance;
  overflow-wrap: anywhere;
}

.cb-page .cb-texthero .section-heading > .muted {
  max-width: 46ch;
  margin-inline: auto;
}

/* =====================================================================
   v2 COLORING-PAGES SEO SURFACE — /coloring-pages (index + theme pages).
   ---------------------------------------------------------------------
   These pages compose the shared `.cb-page` primitives (sample-gallery,
   sample-card, cb-chip, section bands, section_heading). The remaining
   `cp-*` classes (cp-make, cp-grid, cp-theme-grid, cp-related, cp-card,
   cp-upsell, …) are intentional STRUCTURAL / test hooks — they mark regions
   for the integration tests and carry no bespoke styling on purpose.
   (`cp-hero` is the exception: it shares the interior-text-hero treatment
   above with `.pricing-hero`/`.faq-hero` — doodle anchor + sized headline.)
   The rules below are the only `cp-*` that need real CSS: the theme card is a
   card-wrapping anchor (reset the link chrome), the breadcrumb wants a little
   breathing room above the eyebrow, and the sourced facts list wants a reading
   measure plus a citation quieter than the prose link it inherits.
   ===================================================================== */
.cb-page .cp-theme-card {
  display: block;
  color: inherit;
  text-decoration: none;
  border-radius: var(--r-card);
}

.cb-page .cp-crumb {
  margin: 0 0 0.9rem;
  font-weight: 700;
}

/* The sourced facts list sits under a centered section heading but reads as
   prose, so it wants the article's measure rather than the shell's full width —
   `.cb-prose` styles the list itself and carries no width of its own. The
   index's "what comes out of the printer" list is the same shape on the hub
   page, so it shares the measure rather than restating it. */
.cb-page .cp-facts__body,
.cb-page .cp-print__body {
  width: min(44rem, 100%);
  margin-inline: auto;
  text-align: left;
}

/* A citation is provenance, not a call to action. It inherits the bold coral
   `.cb-prose a`, which six of them in a row would shout with — so it keeps the
   underline (still obviously a link) and drops the weight and the color. The
   selector carries `.cb-prose a` so it can out-specify what it is overriding. */
.cb-page .cb-prose a.cp-facts__source {
  font-size: 0.86em;
  font-weight: 600;
  color: var(--ink-soft);
  text-decoration-color: var(--ink-soft);
  text-decoration-thickness: 1px;
}

.cb-page .cb-prose a.cp-facts__source:hover {
  color: var(--ink);
  text-decoration-color: currentColor;
}

/* The theme-card caption carries a Download sticker chip (not the home's
   italic caption), so the chip wants more air under the title than the
   shared 0.15rem figcaption gap gives. Scoped to cp-card; span-targeted to
   stay tie-free with the shared `.sample-card figcaption` rule. */
.cb-page .cp-card figcaption span {
  margin-top: 0.35rem;
}

/* =====================================================================
   v2 LEGAL PAGES — privacy / terms / refunds / acceptable-use.
   A CALM .cb-page reading-card composition: the shared storybook system
   (paper wash, Fredoka headings, Nunito body, marigold sticker eyebrow)
   but deliberately quiet — one sticker eyebrow, then long-form policy
   prose on a clean, ink-outlined white page constrained to a comfortable
   reading measure. Less sticker chaos than the marketing pages by design:
   these are policies, so legibility leads. Everything here composes the
   .cb-page system; the only page-scoped pieces are the reading card and a
   calmer heading rhythm than the marketing hero/section scale.
   ===================================================================== */
.cb-page .cb-legal {
  width: min(54rem, calc(100% - (var(--page-gutter) * 2)));
  margin: 0 auto;
  background: var(--page);
  border: var(--bw) solid var(--ink);
  border-radius: var(--r-card-lg);
  box-shadow: var(--shadow-sticker-lg);
  padding: clamp(1.5rem, 4vw, 3.25rem);
}

/* Calmer heading rhythm than the marketing hero/section scale. */
.cb-page .cb-legal h1 {
  font-size: clamp(2rem, 4.6vw, 2.9rem);
  line-height: 1.06;
  margin: 0.3em 0 0.3em;
}

.cb-page .cb-legal h2 {
  font-size: clamp(1.3rem, 2.6vw, 1.6rem);
  line-height: 1.2;
  margin: 2.1rem 0 0.5rem;
}

.cb-page .cb-legal h3 {
  font-size: 1.18rem;
  line-height: 1.25;
  margin: 1.4rem 0 0.4rem;
}

/* "Last updated" line */
.cb-page .cb-legal__updated {
  margin: 0.4em 0 1.6rem;
  font-weight: 600;
  color: var(--ink-soft);
}

/* readable long-form prose */
.cb-page .cb-legal p,
.cb-page .cb-legal ul {
  max-width: 44rem;
}

.cb-page .cb-legal p,
.cb-page .cb-legal li {
  line-height: 1.72;
}

.cb-page .cb-legal strong {
  font-weight: 800;
}

.cb-page .cb-legal ul {
  margin: 0.6rem 0 0.6rem 1.2rem;
  padding-left: 0.4rem;
  list-style: disc;
}

.cb-page .cb-legal li {
  margin-bottom: 0.4rem;
}

.cb-page .cb-legal li::marker {
  color: var(--coral);
}

/* on-brand links */
.cb-page .cb-legal a {
  color: var(--coral-deep);
  font-weight: 700;
  text-decoration: underline;
  text-underline-offset: 2px;
  text-decoration-thickness: 2px;
  text-decoration-color: var(--t-blush);
  border-radius: var(--r-sm);
}

.cb-page .cb-legal a:hover {
  color: var(--ink);
  text-decoration-color: currentColor;
}

.cb-page .cb-legal a:focus-visible {
  outline: 4px solid var(--cornflower);
  outline-offset: 2px;
  text-decoration: none;
}

@media (max-width: 600px) {
  .cb-page .cb-legal p,
  .cb-page .cb-legal li {
    line-height: 1.65;
  }
}

/* =====================================================================
   v2 BLOG — /blog (index) + /blog/:slug (article).
   The organic-SEO content surface. Composes the shared .cb-page system
   (paper wash, Fredoka headings, Nunito body, sticker eyebrow/kicker,
   section bands). Two bespoke pieces: the index post-card grid, and the
   `.cb-prose` reading block that renders ANY markdown post body well.
   ===================================================================== */

/* --- Index: post-card grid --- */
.cb-page .cb-blog {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(20rem, 1fr));
  gap: clamp(1.25rem, 3vw, 2rem);
}

.cb-page .cb-blog__card {
  display: flex;
  flex-direction: column;
  color: inherit;
  text-decoration: none;
  background: var(--page);
  border: var(--bw) solid var(--ink);
  border-radius: var(--r-card);
  box-shadow: var(--shadow-sticker);
  overflow: hidden;
  transition: transform 0.15s ease, box-shadow 0.15s ease;
}

.cb-page .cb-blog__card:hover {
  transform: translate(-2px, -2px);
  box-shadow: var(--shadow-sticker-lg);
}

.cb-page .cb-blog__card:focus-visible {
  outline: 4px solid var(--cornflower);
  outline-offset: 3px;
}

.cb-page .cb-blog__art {
  aspect-ratio: 16 / 9;
  border-bottom: var(--bw) solid var(--ink);
  background: var(--t-butter);
}

.cb-page .cb-blog__art img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.cb-page .cb-blog__body {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  padding: clamp(1.1rem, 2.5vw, 1.5rem);
}

.cb-page .cb-blog__meta {
  margin: 0;
  font-size: 0.82rem;
  font-weight: 700;
  color: var(--ink-soft);
}

.cb-page .cb-blog__title {
  font-size: 1.4rem;
  line-height: 1.2;
  margin: 0;
}

.cb-page .cb-blog__desc {
  margin: 0;
  line-height: 1.55;
}

.cb-page .cb-blog__card .link-arrow {
  margin-top: 0.25rem;
}

/* --- Article: reading card + prose --- */
.cb-page .cb-article .page-shell {
  width: min(48rem, calc(100% - (var(--page-gutter) * 2)));
}

.cb-page .cb-article__crumb {
  margin: 0 0 1rem;
  font-weight: 700;
}

.cb-page .cb-article__head h1 {
  font-size: clamp(2.2rem, 5vw, 3.2rem);
  line-height: 1.05;
  margin: 0.4em 0 0.3em;
}

.cb-page .cb-article__meta {
  margin: 0;
  font-weight: 600;
  color: var(--ink-soft);
}

.cb-page .cb-article__cover {
  margin: 1.6rem 0;
}

.cb-page .cb-article__cover img {
  width: 100%;
  height: auto;
  display: block;
  border: var(--bw) solid var(--ink);
  border-radius: var(--r-card-lg);
  box-shadow: var(--shadow-sticker);
}

/* The prose block renders any post body — generic element styling only. */
.cb-page .cb-prose {
  margin-top: 1.6rem;
  font-size: 1.08rem;
  line-height: 1.75;
}

.cb-page .cb-prose h2 {
  font-size: clamp(1.5rem, 3vw, 2rem);
  line-height: 1.15;
  margin: 2rem 0 0.6rem;
}

.cb-page .cb-prose h3 {
  font-size: 1.35rem;
  line-height: 1.2;
  margin: 1.7rem 0 0.5rem;
}

.cb-page .cb-prose h4 {
  font-size: 1.12rem;
  line-height: 1.25;
  margin: 1.4rem 0 0.4rem;
}

.cb-page .cb-prose p,
.cb-page .cb-prose ul,
.cb-page .cb-prose ol {
  margin: 0 0 1.1rem;
}

.cb-page .cb-prose ul,
.cb-page .cb-prose ol {
  padding-left: 1.4rem;
}

.cb-page .cb-prose li {
  margin-bottom: 0.4rem;
}

.cb-page .cb-prose li::marker {
  color: var(--coral);
}

.cb-page .cb-prose strong {
  font-weight: 800;
}

.cb-page .cb-prose a {
  color: var(--coral-deep);
  font-weight: 700;
  text-decoration: underline;
  text-underline-offset: 2px;
  text-decoration-thickness: 2px;
  text-decoration-color: var(--t-blush);
  border-radius: var(--r-sm);
}

.cb-page .cb-prose a:hover {
  color: var(--ink);
  text-decoration-color: currentColor;
}

.cb-page .cb-prose a:focus-visible {
  outline: 4px solid var(--cornflower);
  outline-offset: 2px;
  text-decoration: none;
}

.cb-page .cb-prose img {
  max-width: 100%;
  height: auto;
  display: block;
  margin: 1.4rem auto;
  border: var(--bw) solid var(--ink);
  border-radius: var(--r-card);
  box-shadow: var(--shadow-sticker);
}

.cb-page .cb-prose blockquote {
  margin: 1.4rem 0;
  padding: 0.9rem 1.3rem;
  background: var(--t-butter);
  border: var(--bw) solid var(--ink);
  border-radius: var(--r-card);
  font-style: italic;
}

.cb-page .cb-prose blockquote p:last-child {
  margin-bottom: 0;
}

.cb-page .cb-prose code {
  font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace;
  font-size: 0.92em;
  background: var(--t-sky);
  padding: 0.1em 0.35em;
  border-radius: var(--r-md);
}

.cb-page .cb-prose pre {
  margin: 1.4rem 0;
  padding: 1rem 1.2rem;
  overflow-x: auto;
  background: var(--ink);
  color: var(--paper);
  border-radius: var(--r-card);
}

.cb-page .cb-prose pre code {
  background: none;
  padding: 0;
  color: inherit;
}

/* ---- consent / cookie banner -------------------------------------------- */
/* Lives outside .cb-page, so it restates the crayon-box look: warm paper card,
   thick ink outline, soft hand-made shadow, one coral primary action. Shown by
   consent.js only when there's no stored choice (and no Do Not Track signal).
   Anchored to the bottom-LEFT corner as a compact card (not a wide bottom-center
   bar) so it never sits over a centered hero headline on first paint. On a phone
   it spans the width as a slim bottom bar. */
.cb-consent {
  position: fixed;
  z-index: 60;
  left: clamp(0.75rem, 2.5vw, 1.5rem);
  right: auto;
  bottom: clamp(0.75rem, 2.5vw, 1.5rem);
  width: min(25rem, calc(100% - 1.5rem));
  background: var(--paper);
  border: var(--bw) solid var(--ink);
  border-radius: var(--r-card);
  box-shadow:
    6px 9px 20px -7px rgba(150, 96, 40, 0.32),
    3px 4px 0 rgba(36, 29, 23, 0.1);
  font-family: "Nunito", sans-serif;
}

.cb-consent[hidden] {
  display: none;
}

.cb-consent__inner {
  display: flex;
  align-items: center;
  gap: 1.1rem 1.4rem;
  flex-wrap: wrap;
  padding: 1rem 1.25rem;
}

.cb-consent__copy {
  flex: 1 1 18rem;
  min-width: 0;
}

.cb-consent__title {
  margin: 0 0 0.2rem;
  font-family: "Fredoka", sans-serif;
  font-weight: 600;
  font-size: 1.05rem;
  color: var(--ink);
}

.cb-consent__text {
  margin: 0;
  font-size: 0.92rem;
  line-height: 1.5;
  color: var(--ink-soft);
}

.cb-consent__link {
  color: var(--coral-deep);
  font-weight: 700;
  text-decoration: underline;
  text-underline-offset: 2px;
}

.cb-consent__link:hover,
.cb-consent__link:focus-visible {
  color: var(--coral);
}

.cb-consent__actions {
  display: flex;
  gap: 0.6rem;
  flex: 0 0 auto;
}

.cb-consent__btn {
  appearance: none;
  cursor: pointer;
  font-family: "Fredoka", "Nunito", sans-serif;
  font-weight: normal;
  font-size: 0.95rem;
  line-height: 1.1;
  padding: 0.6em 1.1em;
  border: var(--bw) solid var(--ink);
  border-radius: 999px;
  min-height: 0;
  box-shadow: 3px 3px 0 rgba(36, 29, 23, 0.12);
  transition:
    transform 0.12s ease,
    box-shadow 0.12s ease,
    background 0.15s ease;
}

.cb-consent__btn:hover {
  transform: translate(-2px, -2px);
  box-shadow: 5px 5px 0 rgba(36, 29, 23, 0.14);
}

.cb-consent__btn:active {
  transform: translate(2px, 2px);
  box-shadow: 1px 1px 0 rgba(36, 29, 23, 0.14);
}

.cb-consent__btn--accept {
  background: var(--coral);
  color: #fff;
}

.cb-consent__btn--decline {
  background: var(--page);
  color: var(--ink);
}

.cb-consent__btn:focus-visible {
  outline: 4px solid var(--cornflower);
  outline-offset: 2px;
}

@media (max-width: 33rem) {
  .cb-consent__actions {
    width: 100%;
  }

  .cb-consent__btn {
    flex: 1 1 0;
  }
}

@media (prefers-reduced-motion: reduce) {
  .cb-consent__btn {
    transition: none;
  }

  .cb-consent__btn:hover,
  .cb-consent__btn:active {
    transform: none;
  }
}

/* ============================================================
   studio — v2 storybook brand (SCOPED opt-in)
   ------------------------------------------------------------
   Brings the authenticated books + orders surfaces onto the
   crayon palette (warm paper, ink, coral, Fredoka/Nunito,
   sticker shadows) WITHOUT the `.cb-page` bare-control reface
   (see docs/DESIGN_SYSTEM.md §6). Every rule is scoped under
   `.studio-surface` so the shared component classes (`.panel`,
   `.book-card`, `.field`, `.preview-card`, …) keep their legacy
   look on dashboard / admin / auth / free-page surfaces that
   reuse the same class names. Native controls are restyled here
   DELIBERATELY via explicit `.studio-surface` selectors — not
   inherited — so focus rings + behavior stay intact.
   ============================================================ */

/* The cream "paper" wash, matched to `.cb-page`, applied to the
   books + orders + dashboard controllers and the form-heavy public
   surfaces (free-page generator, sign-in, support) — body class =
   controller name. All opt in to the brand via `.studio-surface` on
   their `<main>` rather than `.cb-page` (see docs/DESIGN_SYSTEM.md §6). */
body.books,
body.book-assemblies,
body.orders,
body.dashboard,
body.free-pages,
body.sessions,
body.support-requests {
  background:
    radial-gradient(58rem 40rem at 88% -6%, rgba(255, 178, 46, 0.16), transparent 60%),
    radial-gradient(48rem 36rem at -8% 8%, rgba(242, 74, 92, 0.09), transparent 58%),
    radial-gradient(60rem 50rem at 50% 118%, rgba(63, 111, 229, 0.07), transparent 60%),
    #fbf4e4;
}

.studio-surface {
  /* the warm storybook token overrides (rounder radii + soft shadow) */
  --r-card: 24px;
  --r-card-lg: 34px;
  /* the flat cream under the body's radial washes above — the one value anything
     fading out to the page background (the activity reel's edges) fades to. */
  --studio-paper: #fbf4e4;
  --shadow-sticker: var(--shadow-warm);
  --shadow-sticker-lg: var(--shadow-warm-lg);
  color: var(--ink);
  font-family: "Nunito", ui-sans-serif, system-ui, sans-serif;
}

.studio-surface ::selection {
  background: var(--marigold);
  color: var(--ink);
}

/* Keep the header row's button sized to its content — the shared `.stack`
   defaults to `align-items: stretch`, which would stretch a pill button to
   the row's full height (a giant circle). Column stacks keep their stretch. */
.studio-surface .stack:not(.stack--column) {
  align-items: center;
}

/* ---- type ---- */
.studio-surface h1,
.studio-surface h2,
.studio-surface h3 {
  font-family: "Fredoka", "Nunito", sans-serif;
  font-weight: 600;
  color: var(--ink);
  letter-spacing: 0;
}

.studio-surface h1 {
  font-size: clamp(2.1rem, 4.4vw, 3rem);
  line-height: 1.06;
}

.studio-surface h2 {
  font-size: clamp(1.5rem, 2.6vw, 1.95rem);
  line-height: 1.16;
}

.studio-surface h3 {
  font-size: 1.2rem;
}

.studio-surface .book-card h2 {
  font-size: 1.25rem;
  line-height: 1.2;
  margin: 0.1em 0 0.3em;
}

.studio-surface .muted {
  color: var(--ink-soft);
  font-weight: 500;
}

.studio-surface .muted a {
  color: var(--coral-deep);
  font-weight: 700;
  text-decoration: none;
}

.studio-surface .muted a:hover,
.studio-surface .muted a:focus-visible {
  text-decoration: underline;
}

.studio-surface .studio-card__lede {
  color: var(--ink-soft);
}

/* ---- sticker eyebrow ---- */
.studio-surface .eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 0.5em;
  margin: 0 0 0.7rem;
  font-family: "Nunito", sans-serif;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  font-size: 0.74rem;
  color: var(--ink);
  background: var(--marigold);
  border: var(--bw) solid var(--ink);
  border-radius: 999px;
  padding: 0.38em 0.9em;
  box-shadow: var(--shadow-sticker);
  rotate: -2deg;
}

.studio-surface .eyebrow::before {
  content: "";
  width: 0.5em;
  height: 0.5em;
  border-radius: 50%;
  background: var(--coral);
}

/* ---- cards / panels ---- */
.studio-surface .panel,
.studio-surface .book-card,
.studio-surface .studio-card {
  background: var(--page);
  border: var(--bw) solid var(--ink);
  border-radius: var(--r-card);
  box-shadow: var(--shadow-sticker);
}

.studio-surface .book-card {
  transition: transform 0.18s ease, box-shadow 0.18s ease;
}

.studio-surface .book-card:hover,
.studio-surface .book-card:focus-within {
  transform: translate(-2px, -2px);
  box-shadow: var(--shadow-sticker-lg);
}

.studio-surface .book-card h2 a {
  color: var(--ink);
  text-decoration: none;
}

.studio-surface .book-card h2 a:hover,
.studio-surface .book-card h2 a:focus-visible {
  color: var(--coral-deep);
}

.studio-surface .empty-state {
  background: var(--page);
}

.studio-surface .key-value strong,
.studio-surface .book-status-panel .key-value strong {
  font-family: "Fredoka", "Nunito", sans-serif;
  color: var(--ink);
}

/* ---- form fields (deliberate v2 control treatment, explicit selectors) ---- */
.studio-surface .field label {
  font-weight: 700;
  color: var(--ink);
  font-size: 0.95rem;
}

.studio-surface .field input,
.studio-surface .field textarea,
.studio-surface .field select {
  background: var(--page);
  border: 2px solid var(--ink);
  border-radius: var(--r-lg);
  color: var(--ink);
  /* Nunito body face on every control (textareas otherwise default to the UA
     monospace) — the brand's input face, NOT the Fredoka display reface. */
  font-family: "Nunito", ui-sans-serif, system-ui, sans-serif;
  font-size: 1rem;
  padding: 0.8rem 0.95rem;
}

.studio-surface .field input::placeholder,
.studio-surface .field textarea::placeholder {
  color: var(--ink-soft);
  opacity: 0.85;
}

.studio-surface .field input:focus-visible,
.studio-surface .field textarea:focus-visible,
.studio-surface .field select:focus-visible {
  outline: 3px solid var(--cornflower);
  outline-offset: 2px;
  border-color: var(--ink);
}

/* Optional guided-detail chips on the free-page gate: a bare grouping of .field
   controls, so the fieldset itself carries no chrome — just the legend heading
   and hint, then the shared control treatment above does the rest. */
.studio-surface .guided-details {
  border: 0;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 0.75rem;
}

.studio-surface .guided-details legend {
  padding: 0;
  font-family: "Fredoka", "Nunito", sans-serif;
  font-weight: 600;
  font-size: 1.05rem;
  color: var(--ink);
}

.studio-surface .guided-details .field__hint {
  color: var(--ink-soft);
}

/* ---- buttons: v2 sticker pills (explicit, not the .cb-page reface) ----
   Default = coral primary; `.button--secondary` = white. Covers the
   `link_to … class:"button"`, the `form.submit`, and the React island's
   bare `<button>` (primary checkout) + `.button--secondary` (quote). */
.studio-surface .button,
.studio-surface button,
.studio-surface input[type="submit"] {
  font-family: "Fredoka", "Nunito", sans-serif;
  font-weight: normal;
  font-size: 1rem;
  border: var(--bw) solid var(--ink);
  border-radius: 999px;
  background: var(--coral);
  color: #fff;
  box-shadow: var(--shadow-sticker);
  transition: transform 0.18s ease, box-shadow 0.18s ease;
}

.studio-surface .button:hover,
.studio-surface button:hover,
.studio-surface input[type="submit"]:hover {
  transform: translate(-2px, -2px);
  box-shadow: var(--shadow-sticker-lg);
}

.studio-surface .button:active,
.studio-surface button:active,
.studio-surface input[type="submit"]:active {
  transform: translate(3px, 4px);
  box-shadow: 2px 2px 0 rgba(36, 29, 23, 0.16);
}

.studio-surface .button:disabled,
.studio-surface button:disabled,
.studio-surface input[type="submit"]:disabled {
  opacity: 0.55;
  transform: none;
  box-shadow: var(--shadow-sticker);
  cursor: not-allowed;
}

.studio-surface .button--secondary,
.studio-surface button.button--secondary {
  background: var(--page);
  color: var(--ink);
}

.studio-surface .button:focus-visible,
.studio-surface button:focus-visible,
.studio-surface input[type="submit"]:focus-visible {
  outline: 3px solid var(--cornflower);
  outline-offset: 2px;
}

/* ---- value split (free / paid) ---- */
.studio-surface .value-split__item {
  background: var(--paper);
  border: 2px solid var(--ink);
  border-radius: var(--r-xl);
  box-shadow: none;
}

.studio-surface .value-split__item strong {
  font-family: "Fredoka", "Nunito", sans-serif;
  color: var(--ink);
}

.studio-surface .value-split__tag {
  font-family: "Fredoka", "Nunito", sans-serif;
  font-weight: normal;
}

.studio-surface .value-split__tag--free {
  background: var(--t-mint);
  color: var(--mint-ink-strong);
}

.studio-surface .value-split__tag--paid {
  background: var(--t-sky);
  color: #2f57c2;
}

/* ---- progress bar ---- */
.studio-surface .studio-progress {
  background: var(--t-butter);
  border: 2px solid var(--ink);
  border-radius: var(--r-xl);
}

.studio-surface .studio-progress__head strong {
  font-family: "Fredoka", "Nunito", sans-serif;
  color: var(--ink);
}

.studio-surface .studio-progress__count {
  color: var(--coral-deep);
}

.studio-surface .studio-progress__bar {
  background: rgba(36, 29, 23, 0.12);
}

.studio-surface .studio-progress__fill {
  background: linear-gradient(90deg, var(--coral) 0%, var(--marigold) 100%);
}

/* ---- inline messages ---- */
.studio-surface .studio-message--info {
  border: 1px solid rgba(31, 168, 104, 0.4);
  background: var(--t-mint);
  color: var(--mint-ink-strong);
}

.studio-surface .studio-message--error {
  border: 1px solid rgba(207, 58, 75, 0.4);
  background: var(--t-blush);
  color: var(--error-ink);
}

/* ---- print choice + options ---- */
.studio-surface .studio-choice,
.studio-surface .studio-choice--print {
  background: var(--t-sky);
  border: 2px solid var(--ink);
  border-radius: var(--r-xl);
}

.studio-surface .studio-choice h2 {
  font-size: 1.4rem;
}

.studio-surface .print-option {
  background: var(--page);
  border: 2px solid var(--ink);
  border-radius: var(--r-xl);
}

.studio-surface .print-option__head strong {
  font-family: "Fredoka", "Nunito", sans-serif;
  color: var(--ink);
}

/* ---- story-outline preview grid ---- */
.studio-surface .preview-grid .preview-card {
  background: var(--page);
  border: 2px solid var(--ink);
  border-radius: var(--r-xl);
  box-shadow: var(--shadow-sticker);
}

.studio-surface .preview-grid .preview-card--art:hover,
.studio-surface .preview-grid .preview-card--art:focus-within {
  transform: translate(-2px, -2px);
  box-shadow: var(--shadow-sticker-lg);
}

.studio-surface .preview-card__art {
  border: 2px solid var(--ink);
  border-radius: var(--r-lg);
}

.studio-surface .preview-card__num {
  color: var(--coral-deep);
  letter-spacing: 0.06em;
}

.studio-surface .preview-card figcaption strong {
  font-family: "Fredoka", "Nunito", sans-serif;
  color: var(--ink);
}

.studio-surface .preview-card__story {
  color: var(--ink-soft);
}

/* ---- vibe (page-1) preview: full v2 card + branded loading state ----
   The base `.vibe-preview` / `.preview-card` / spinner rules still carry the
   pre-redesign neutral tokens (`--line`, `--surface-strong`, `--accent`), which
   otherwise show through as a thin purple hairline and an orange spinner inside
   the otherwise-warm studio. Re-point them to the crayon palette here so the
   "See page 1" card reads as a real storybook card (ink outline + sticker
   shadow) and the draw states use coral, matching every sibling surface. */
.studio-surface .vibe-preview {
  background: var(--page);
  border: var(--bw) solid var(--ink);
  border-radius: var(--r-card);
  box-shadow: var(--shadow-sticker);
}

/* the figure inside is just a layout wrapper — drop its own border so we don't
   nest three ink outlines (vibe card > figure > art frame). */
.studio-surface .vibe-preview .preview-card {
  padding: 0;
  border: 0;
  background: transparent;
  box-shadow: none;
}

.studio-surface .preview-card__spinner {
  border-color: var(--t-butter);
  border-top-color: var(--coral);
}

.studio-surface .preview-card--generating .preview-card__art--placeholder {
  background-image: linear-gradient(110deg, var(--t-butter) 8%, #fff 18%, var(--t-butter) 33%);
}

.studio-surface .preview-card--error .preview-card__art--placeholder {
  background: var(--t-blush);
}

.studio-surface .preview-card--error .preview-card__icon {
  color: var(--coral-deep);
}

/* the vibe preview's primary CTA ("Draw page 1 free") sits a step up in size. */
.studio-surface .button--lg {
  padding: 0.85rem 1.5rem;
  font-size: 1.1rem;
}

/* a real ghost button in the studio: a quiet text button, not the coral pill
   the base `.studio-surface .button` would otherwise give it (used for the
   preview's "Adjust and redraw"). Placed after that rule so the tie resolves
   in the ghost's favor. */
.studio-surface .button--ghost {
  background: transparent;
  color: var(--coral-deep);
  border-color: transparent;
  box-shadow: none;
}

.studio-surface .button--ghost:hover {
  background: rgba(232, 101, 78, 0.09);
  transform: none;
  box-shadow: none;
}

/* ============================================================
   Book studio (books/show) — the rebuilt information architecture.
   Four regions in the order a parent asks: orient -> prove it
   (the page-1 preview) -> the story page by page -> order. The
   printed-copy order card is a persistent sticky right-hand rail.
   One status truth, one outline, one primary action.
   ============================================================ */

/* the two-column shell: narrative on the left, sticky order rail on the right */
.studio-surface .studio-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 340px;
  gap: clamp(1.5rem, 3vw, 2.4rem);
  align-items: start;
}

/* No order rail while the book is in review — the pages get the whole width,
   which is what makes them big enough to judge. */
.studio-surface .studio-layout--review {
  grid-template-columns: minmax(0, 1fr);
}

.studio-surface .studio-main {
  display: flex;
  flex-direction: column;
  gap: clamp(1.6rem, 3.4vw, 2.8rem);
  min-width: 0;
}

/* ---- region 1: orient (title + one honest status) ---- */
.studio-surface .studio-orient h1 {
  margin: 0.1em 0 0;
}

.studio-surface .studio-orient__meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.6rem 0.9rem;
  margin-top: 0.9rem;
}

.studio-surface .studio-orient__jump {
  font-weight: 700;
  color: var(--coral-deep);
}

.studio-surface .studio-orient .studio-card__lede {
  margin: 1rem 0 0;
  max-width: 52ch;
}

/* the header order anchor is a mobile convenience — the sticky rail already
   holds the CTA on desktop, so hide the jump link where the rail is visible. */
@media (min-width: 861px) {
  .studio-surface .studio-orient__jump {
    display: none;
  }
}

/* ---- one sticker-chip vocabulary (status + free/paid + page type) ---- */
.studio-surface .studio-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.4em;
  align-self: flex-start;
  font-family: "Nunito", sans-serif;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  font-size: 0.7rem;
  border: 2px solid var(--ink);
  border-radius: 999px;
  padding: 0.28rem 0.7rem;
  box-shadow: var(--shadow-sticker);
}

.studio-surface .studio-chip--status {
  background: var(--t-mint);
  color: var(--mint-ink-strong);
}

/* the one status the orient chip reports that is bad news, so it re-points to the
   same blush/error pair `.studio-message--error` uses rather than announcing a
   stopped draw in the mint every other status wears. */
.studio-surface .studio-chip--stopped {
  background: var(--t-blush);
  color: var(--error-ink);
}

.studio-surface .studio-chip--free {
  background: var(--t-blush);
  color: var(--coral-deep);
  rotate: 2deg;
}

.studio-surface .studio-chip--paid {
  background: var(--t-sky);
  color: #2f57c2;
  rotate: -2deg;
}

/* the in-card page-type chips sit flat (no sticker lift) so they read as a
   label inside the outline card, not a second floating sticker. */
.studio-surface .studio-chip--coloring,
.studio-surface .studio-chip--activity {
  box-shadow: none;
  font-size: 0.64rem;
}

.studio-surface .studio-chip--coloring {
  background: var(--t-butter);
  color: var(--coral-deep);
}

.studio-surface .studio-chip--activity {
  background: var(--t-sky);
  color: #2f57c2;
}

/* ---- region 2: the page-1 preview hero (intro line) ---- */
.studio-surface .vibe-preview__intro {
  margin: 0.1rem 0 0.2rem;
  max-width: 42ch;
}

/* ---- region 3: the story, page by page (outline as one flat-card grid) ---- */
.studio-surface .studio-story__head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 0.8rem 1.2rem;
  flex-wrap: wrap;
  margin-bottom: 1.1rem;
}

.studio-surface .studio-story__head h2 {
  margin: 0;
}

.studio-surface .studio-story__head > div {
  display: flex;
  align-items: baseline;
  gap: 0.7rem;
  flex-wrap: wrap;
}

.studio-surface .outline-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
  gap: 1rem;
}

.studio-surface .outline-card {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  padding: 1.1rem 1.15rem;
  background: var(--page);
  border: var(--bw) solid var(--ink);
  border-radius: var(--r-card);
  box-shadow: var(--shadow-sticker);
}

.studio-surface .outline-card__top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.6rem;
}

.studio-surface .outline-card__num {
  font-family: "Nunito", sans-serif;
  font-weight: 800;
  font-size: 0.66rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--ink-soft);
}

.studio-surface .outline-card__title {
  font-family: "Fredoka", "Nunito", sans-serif;
  font-weight: 600;
  font-size: 1.08rem;
  line-height: 1.2;
  color: var(--ink);
  overflow-wrap: anywhere;
}

.studio-surface .outline-card__story {
  margin: 0;
  font-size: 0.95rem;
  line-height: 1.5;
  color: var(--ink-soft);
}

.studio-surface .outline-card__scene {
  margin: 0.15rem 0 0;
  font-size: 0.82rem;
  line-height: 1.45;
  color: var(--ink-soft);
}

.studio-surface .outline-card__scene-label {
  display: block;
  font-weight: 800;
  font-size: 0.62rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--coral-deep);
  margin-bottom: 0.1rem;
}

/* ---- region 2b: the puzzle pages, already made ----
   Inline and scrollable, never a modal: these are the one finished thing on the
   page before a parent pays, so nothing goes between him and them. The reel
   scrolls sideways with the pages sized so a 16-column word-search grid (the
   13+ band) still reads on a phone. Three things say there are more pages: the
   next page peeking past the edge, the fade it slides under, and — for a mouse,
   which has nothing to swipe — a pair of arrows in the heading row. */
.studio-surface .activity-preview {
  display: flex;
  flex-direction: column;
  gap: 1.1rem;
}

.studio-surface .activity-preview__head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 0.8rem 1.2rem;
  flex-wrap: wrap;
}

.studio-surface .activity-preview__say {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  align-items: flex-start;
}

.studio-surface .activity-preview__head h2 {
  margin: 0;
}

.studio-surface .activity-preview__intro {
  margin: 0;
  max-width: 52ch;
  /* keeps "this." off a line of its own where the copy happens to break */
  text-wrap: pretty;
}

/* the arrows are the mouse's affordance. A real touch screen — one that reports
   both no hover AND a coarse pointer — swipes the reel and would only lose card
   to them, so it alone drops them; anything we can't identify keeps the control. */
.studio-surface .activity-preview__nav {
  display: flex;
  gap: 0.5rem;
  padding-bottom: 0.2rem;
  /* stays on the reel's right edge even when it wraps under the copy */
  margin-inline-start: auto;
}

@media (hover: none) and (pointer: coarse) {
  .studio-surface .activity-preview__nav {
    display: none;
  }
}

.studio-surface .activity-preview__arrow {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.6rem;
  height: 2.6rem;
  padding: 0;
  border: var(--bw) solid var(--ink);
  border-radius: 50%;
  background: var(--page);
  color: var(--ink);
  box-shadow: var(--shadow-sticker);
  cursor: pointer;
  transition: transform 0.15s ease, box-shadow 0.15s ease, opacity 0.15s ease;
}

.studio-surface .activity-preview__arrow:hover:not(:disabled) {
  transform: translate(-2px, -2px);
  box-shadow: var(--shadow-sticker-lg);
}

.studio-surface .activity-preview__arrow:active:not(:disabled) {
  transform: translate(1px, 1px);
  box-shadow: var(--shadow-sticker);
}

.studio-surface .activity-preview__arrow:disabled {
  opacity: 0.35;
  cursor: default;
  box-shadow: none;
}

/* the fades live on the viewport, which reaches past the text column by the
   room the sticker shadows need, so a fade always meets the reel's real edge. */
.studio-surface .activity-preview__viewport {
  position: relative;
  margin-inline: -9px;
}

.studio-surface .activity-preview__viewport::before,
.studio-surface .activity-preview__viewport::after {
  content: "";
  position: absolute;
  /* full height, captions included — a fade that stopped short of them would
     leave a caption hard-clipped at the edge it is meant to soften */
  top: 0;
  bottom: 0;
  width: 3.5rem;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.18s ease;
}

/* the far stop is --studio-paper at zero alpha spelled out, not `transparent`,
   so no browser fades the edge through gray on its way to nothing. */
.studio-surface .activity-preview__viewport::before {
  left: 0;
  background: linear-gradient(to right, var(--studio-paper), rgba(251, 244, 228, 0));
}

.studio-surface .activity-preview__viewport::after {
  right: 0;
  background: linear-gradient(to left, var(--studio-paper), rgba(251, 244, 228, 0));
}

.studio-surface .activity-preview__viewport--back::before,
.studio-surface .activity-preview__viewport--more::after {
  opacity: 1;
}

.studio-surface .activity-preview__reel {
  display: flex;
  gap: 1rem;
  overflow-x: auto;
  scroll-snap-type: x proximity;
  /* the sticker shadows would otherwise be clipped by the scroll box */
  padding: 4px 9px 1rem;
  scroll-padding-inline-start: 9px;
  scrollbar-width: thin;
  scrollbar-color: var(--ink-soft) rgba(58, 46, 37, 0.12);
}

.studio-surface .activity-preview__reel:focus-visible {
  outline: 3px solid var(--coral);
  outline-offset: -1px;
  border-radius: var(--r-card);
}

.studio-surface .activity-page {
  flex: 0 0 auto;
  width: min(420px, 84vw);
  margin: 0;
  scroll-snap-align: start;
}

/* Crops the printed page's dead margin so the puzzle itself fills the card —
   the connect-the-dots pages in particular read sparse at thumbnail size, and
   nothing but white is lost. The print geometry is untouched: the page is 630x810
   pt with a 45 pt content margin (Pdfs::InteriorBuilder), and this trims 30 of
   those 45 pt off every edge, leaving a hair of white inside the outline. So the
   frame is (630-60):(810-60), the image is 630/570 = 110.526% of it, and the 30 pt
   offset is 30/630 x 110.526% = 5.263% of the frame's width — which is what a
   percentage margin resolves against on every edge, top included. */
.studio-surface .activity-page__frame {
  aspect-ratio: 570 / 750;
  overflow: hidden;
  background: #fff;
  border: var(--bw) solid var(--ink);
  border-radius: var(--r-card);
  box-shadow: var(--shadow-sticker);
}

.studio-surface .activity-page__frame img {
  display: block;
  width: 110.526%;
  height: auto;
  margin: -5.263% 0 0 -5.263%;
}

.studio-surface .activity-page figcaption {
  margin-top: 0.55rem;
  font-family: "Nunito", sans-serif;
  font-weight: 800;
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--ink-soft);
}

/* ---- region 3b: the pre-print review ----
   The paid book, drawn, page by page, at a size worth judging — the last look
   before it costs a print run. Reuses the outline grid's flat-card language so
   nothing here is a new visual idea; the page image is what's different. */
.studio-surface .review {
  display: flex;
  flex-direction: column;
  gap: 1.2rem;
}

.studio-surface .review__head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 1rem 1.5rem;
  flex-wrap: wrap;
}

.studio-surface .review__head h2 {
  margin: 0 0 0.3rem;
}

.studio-surface .review__lede {
  margin: 0;
  max-width: 52ch;
  color: var(--ink-soft);
}

.studio-surface .review__go {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.4rem;
}

.studio-surface .review__deadline {
  margin: 0;
  font-size: 0.85rem;
}

.studio-surface .review__grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: 1.2rem;
}

.studio-surface .review-page {
  display: flex;
  flex-direction: column;
  gap: 0.45rem;
  padding: 1rem 1.05rem 1.1rem;
  background: var(--page);
  border: var(--bw) solid var(--ink);
  border-radius: var(--r-card);
  box-shadow: var(--shadow-sticker);
}

/* Same crop as the pre-purchase puzzle card, for the same reason: the printed
   page's dead margin is nothing but white, and cropping it lets the drawing
   fill the card. See .activity-page__frame for the arithmetic. */
.studio-surface .review-page__frame {
  aspect-ratio: 570 / 750;
  display: grid;
  place-items: center;
  overflow: hidden;
  background: #fff;
  border: var(--bw) solid var(--ink);
  border-radius: var(--r-card);
}

.studio-surface .review-page__frame img {
  display: block;
  width: 110.526%;
  height: auto;
  margin: -5.263% 0 0 -5.263%;
}

.studio-surface .review-page__drawing {
  margin: 0;
  padding: 1rem;
  text-align: center;
  color: var(--ink-soft);
  font-size: 0.9rem;
}

.studio-surface .review-page__top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.6rem;
  margin-top: 0.35rem;
}

.studio-surface .review-page__num {
  font-family: "Nunito", sans-serif;
  font-weight: 800;
  font-size: 0.66rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--ink-soft);
}

.studio-surface .review-page__title {
  font-family: "Fredoka", "Nunito", sans-serif;
  font-weight: 600;
  font-size: 1.02rem;
  line-height: 1.2;
  color: var(--ink);
  overflow-wrap: anywhere;
}

.studio-surface .review-page__note-label {
  font-family: "Nunito", sans-serif;
  font-weight: 800;
  font-size: 0.62rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--coral-deep);
}

.studio-surface .review-page__note {
  width: 100%;
  resize: vertical;
  font: inherit;
  font-size: 0.9rem;
  padding: 0.5rem 0.6rem;
  border: var(--bw) solid var(--ink);
  border-radius: calc(var(--r-card) / 2);
  background: var(--page);
  color: var(--ink);
}

.studio-surface .review-page__actions {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  flex-wrap: wrap;
  margin-top: 0.2rem;
}

.studio-surface .review-page__note-only {
  border: 0;
  background: none;
  padding: 0;
  font: inherit;
  font-size: 0.85rem;
  color: var(--ink-soft);
  text-decoration: underline;
  cursor: pointer;
}

.studio-surface .review-page__spent,
.studio-surface .review-page__sent {
  margin: 0;
  font-size: 0.82rem;
  line-height: 1.45;
}

/* ---- region 4: the sticky order rail (one flat card, never nested) ---- */
.studio-surface .studio-rail {
  position: sticky;
  top: 1.5rem;
  align-self: start;
}

.studio-surface .studio-order {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  padding: clamp(1.3rem, 2vw, 1.6rem);
  background: var(--t-sky);
  border: var(--bw) solid var(--ink);
  border-radius: var(--r-card-lg);
  box-shadow: var(--shadow-sticker);
}

.studio-surface .studio-order h2 {
  margin: 0;
  font-size: 1.5rem;
  line-height: 1.14;
}

.studio-surface .studio-order__from {
  margin: 0;
  font-family: "Fredoka", "Nunito", sans-serif;
  font-size: 1.25rem;
  color: var(--ink);
}

.studio-surface .studio-order__from b {
  color: var(--coral-deep);
}

.studio-surface .studio-order__perks {
  list-style: none;
  margin: 0.2rem 0;
  padding: 0;
  display: grid;
  gap: 0.5rem;
}

.studio-surface .studio-order__perks li {
  position: relative;
  padding-left: 1.7rem;
  font-size: 0.92rem;
  line-height: 1.4;
  font-weight: 500;
}

.studio-surface .studio-order__perks li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.05rem;
  width: 1.2rem;
  height: 1.2rem;
  border-radius: 999px;
  background: var(--grass);
  -webkit-mask: no-repeat center / 0.7rem url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='none' stroke='white' stroke-width='3.5' stroke-linecap='round' stroke-linejoin='round' d='M4 12l5 5L20 6'/%3E%3C/svg%3E");
  mask: no-repeat center / 0.7rem url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='none' stroke='white' stroke-width='3.5' stroke-linecap='round' stroke-linejoin='round' d='M4 12l5 5L20 6'/%3E%3C/svg%3E");
}

.studio-surface .studio-order__zip {
  margin-top: 0.2rem;
}

.studio-surface .studio-order__zip .field input,
.studio-surface .studio-order__zip input {
  width: 100%;
}

.studio-surface .studio-order__hint {
  margin: 0.4rem 0 0;
  font-size: 0.8rem;
}

/* "When will it come?" — the last unanswered question before the buy button.
   Deliberately not a perk: no check bullet, no ink-black body weight, so it
   reassures without competing with the button under it. It takes the rail's own
   gap off the ZIP hint, so the two logistics lines read as one group, and sits a
   notch above that hint (0.86rem over 0.8rem, medium over regular) because fine
   print is the wrong register for the thing a parent buying a gift asks last.
   --muted on the rail's --t-sky is 5.5:1. */
.studio-surface .studio-order__arrival {
  margin: 0;
  color: var(--muted);
  font-size: 0.86rem;
  font-weight: 500;
  line-height: 1.45;
}

.studio-surface .studio-order__tiers {
  display: grid;
  gap: 0.85rem;
}

/* flat rows, separated by a hairline — deliberately NOT cards, so the order
   card is never a card inside a card. */
.studio-surface .studio-order__tier {
  display: grid;
  gap: 0.5rem;
  padding-top: 0.85rem;
  border-top: 2px dashed rgba(58, 46, 37, 0.16);
}

.studio-surface .studio-order__tier-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.6rem;
}

.studio-surface .studio-order__tier-head strong {
  font-family: "Fredoka", "Nunito", sans-serif;
  font-weight: 600;
  font-size: 1.02rem;
  color: var(--ink);
}

.studio-surface .studio-order__tier-price {
  font-family: "Fredoka", "Nunito", sans-serif;
  font-weight: 600;
  color: var(--coral-deep);
  white-space: nowrap;
}

.studio-surface .studio-order__tier--featured .studio-order__tier-head strong::after {
  content: "Most loved";
  margin-left: 0.5rem;
  font-family: "Nunito", sans-serif;
  font-weight: 800;
  font-size: 0.58rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--coral-deep);
  vertical-align: middle;
}

.studio-surface .studio-order__tier-sub {
  margin: 0;
  font-size: 0.85rem;
}

.studio-surface .studio-order__tier button {
  width: 100%;
}

.studio-surface .studio-order__assent {
  margin: 0;
  font-size: 0.76rem;
  line-height: 1.4;
}

/* ---- "email me when printed books open" — the lead capture that stands in
   for the buy button while ordering is closed. Same rail, same rhythm as the
   ZIP + buy stack it replaces. ---- */
.studio-surface .studio-order__notify {
  margin-top: 1.1rem;
}

.studio-surface .studio-order__notify .button {
  width: 100%;
  margin-top: 0.7rem;
}

.studio-surface .studio-order__note {
  margin: 0.7rem 0 0;
  font-weight: 600;
  line-height: 1.45;
}

.studio-surface .studio-order__note.is-error {
  color: var(--coral);
}

.studio-surface .studio-order__fine {
  margin: 0.6rem 0 0;
  font-size: 0.76rem;
  line-height: 1.4;
  color: var(--ink-soft);
}

/* ---- the sign-in step an anonymous builder meets at the buy button. Sits
   where the ZIP + quote stack sits for an account, so the rail keeps one
   primary action either way. ---- */
.studio-surface .studio-order__account {
  margin-top: 1.1rem;
}

.studio-surface .studio-order__account .button {
  width: 100%;
}

/* stack the rail under the narrative below the two-column breakpoint */
@media (max-width: 860px) {
  .studio-surface .studio-layout {
    grid-template-columns: 1fr;
  }

  .studio-surface .studio-rail {
    position: static;
  }
}

/* ---- community gallery consent (books/show; the gate is enforced in the
   model — this only restyles the opt-in, never the logic) ---- */
.studio-surface .studio-gallery {
  margin-top: clamp(1.6rem, 3.4vw, 2.8rem);
  padding: clamp(1.2rem, 2.4vw, 1.6rem);
}

.studio-surface .studio-gallery__head {
  margin: 0 0 0.6rem;
  font-size: 1.2rem;
}

/* ---- community-gallery consent (books/show aside; the gate itself is
   enforced in the model — this only restyles the opt-in, never the logic) ---- */
.studio-surface .book-status-panel__gallery {
  margin-top: 1.5rem;
  padding-top: 1.3rem;
  border-top: 2px dashed rgba(58, 46, 37, 0.18);
}

/* ---- shared community-gallery opt-in control (studio aside + free-page
   claim). A plain, legible checkbox row + fine-print terms; the coral accent
   ties the native checkbox to the brand. Global (not `.studio-surface`-scoped)
   so it reads the same on every submission surface. The consent LOGIC lives in
   the model gate + controllers — this is presentation only. */
.gallery-grant {
  display: flex;
  align-items: flex-start;
  gap: 0.6rem;
  cursor: pointer;
  font-weight: 600;
  color: var(--ink);
}

.gallery-grant__box {
  flex: 0 0 auto;
  width: 1.15rem;
  height: 1.15rem;
  margin-top: 0.15rem;
  accent-color: var(--coral);
}

.gallery-grant__label {
  line-height: 1.45;
}

.gallery-grant__terms {
  margin: 0.6rem 0 0;
  font-size: 0.85rem;
  line-height: 1.55;
}

/* ---- book status outline ---- */
.studio-surface .book-outline {
  background: var(--paper);
  border: 2px solid var(--ink);
  border-radius: var(--r-lg);
}

/* ---- order confirmation / receipt ----
   The post-checkout "here's your order" page: an eyebrow + title, a key-value
   facts block, then tracking / PDF / shipping sections on an even rhythm — all
   design-system primitives, no inline styles. */
.studio-surface .order-receipt__title {
  margin: 0.2rem 0 0;
}

.studio-surface .order-receipt__facts {
  margin-top: 1.4rem;
}

.studio-surface .order-receipt__block {
  margin-top: 1.7rem;
}

.studio-surface .order-receipt__heading {
  margin: 0 0 0.55rem;
  font-size: 1.15rem;
}

.studio-surface .order-receipt__note {
  margin: 0.5rem 0 0;
}

.studio-surface .order-receipt__ship {
  margin: 0;
  font-style: normal;
  color: var(--ink-soft);
  line-height: 1.6;
}

.studio-surface .order-receipt__back {
  margin-top: 1.9rem;
}

.studio-surface .order-receipt__back a {
  color: var(--coral-deep);
  font-weight: 700;
  text-decoration: none;
}

.studio-surface .order-receipt__back a:hover,
.studio-surface .order-receipt__back a:focus-visible {
  text-decoration: underline;
}

@media (prefers-reduced-motion: reduce) {
  .studio-surface .button,
  .studio-surface button,
  .studio-surface input[type="submit"],
  .studio-surface .book-card,
  .studio-surface .preview-grid .preview-card {
    transition: none;
  }

  .studio-surface .button:hover,
  .studio-surface button:hover,
  .studio-surface input[type="submit"]:hover,
  .studio-surface .book-card:hover,
  .studio-surface .preview-grid .preview-card--art:hover {
    transform: none;
  }
}

/* ---- consolidated dashboard (scoped under .studio-surface) ----
   The one home for a customer's books: new-book composer, the "pick up where
   you left off" hero, then every book as a status-badged card (ordered books
   carry their fulfillment inline). Reuses the shared shell + .book-card /
   .eyebrow / .button primitives branded above; these add the pieces unique to
   the dashboard. Mirrors the owner-approved dashboard mockup. */
.studio-surface .dash-intro {
  margin-bottom: 2rem;
}

.studio-surface .dash-intro__lede {
  max-width: 48ch;
  margin: 0.6rem 0 0;
  font-size: 1.08rem;
}

/* new-book composer */
.studio-surface .dash-composer {
  background: var(--t-butter);
  border: var(--bw) solid var(--ink);
  border-radius: var(--r-card);
  box-shadow: var(--shadow-sticker);
  padding: 1.4rem clamp(1.2rem, 3vw, 1.8rem);
  margin-bottom: 2.4rem;
}

.studio-surface .dash-composer__head {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  margin-bottom: 1rem;
}

.studio-surface .dash-composer__head h2 {
  font-size: 1.45rem;
}

.studio-surface .dash-composer__spark {
  width: 2.5rem;
  height: 2.5rem;
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  font-size: 1.2rem;
  background: var(--coral);
  border: var(--bw) solid var(--ink);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-sticker);
}

.studio-surface .dash-composer__row {
  display: flex;
  gap: 0.75rem;
  flex-wrap: wrap;
  margin: 0;
}

.studio-surface .dash-composer__input {
  flex: 1 1 22rem;
  display: flex;
  align-items: center;
  background: var(--page);
  border: var(--bw) solid var(--ink);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-sticker);
  padding: 0 0.4rem 0 1rem;
}

.studio-surface .dash-composer__input input {
  flex: 1;
  border: 0;
  outline: 0;
  background: transparent;
  font-family: "Nunito", sans-serif;
  font-size: 1.02rem;
  color: var(--ink);
  padding: 0.75rem 0;
}

.studio-surface .dash-composer__input input::placeholder {
  color: var(--ink-soft);
  opacity: 0.85;
}

.studio-surface .dash-composer__input:focus-within {
  outline: 3px solid var(--cornflower);
  outline-offset: 2px;
}

.studio-surface .dash-composer__chips {
  display: flex;
  gap: 0.5rem;
  flex-wrap: wrap;
  margin-top: 0.85rem;
}

.studio-surface .dash-chip {
  font-family: "Nunito", sans-serif;
  font-weight: 700;
  font-size: 0.82rem;
  color: var(--ink);
  background: var(--page);
  border: 2px solid var(--ink);
  border-radius: 999px;
  padding: 0.3rem 0.85rem;
  text-decoration: none;
}

.studio-surface .dash-chip:hover,
.studio-surface .dash-chip:focus-visible {
  background: var(--t-sky);
  text-decoration: none;
}

.studio-surface .dash-composer__hint {
  margin: 0.8rem 0 0;
  font-size: 0.9rem;
  color: var(--ink-soft);
}

/* "pick up where you left off" hero */
.studio-surface .dash-resume {
  display: flex;
  flex-wrap: wrap;
  gap: 1.6rem;
  align-items: center;
  background: var(--page);
  border: var(--bw) solid var(--ink);
  border-radius: var(--r-card);
  box-shadow: var(--shadow-sticker-lg);
  padding: 1.5rem;
  margin-bottom: 2.8rem;
}

.studio-surface .dash-resume__thumb {
  flex: 0 0 10.5rem;
  width: 10.5rem;
  height: 12.5rem;
  overflow: hidden;
  border: var(--bw) solid var(--ink);
  border-radius: var(--r-lg);
  background: var(--page);
  box-shadow: var(--shadow-sticker);
}

.studio-surface .dash-resume__body {
  flex: 1 1 20rem;
  min-width: 17rem;
}

.studio-surface .dash-resume__body h2 {
  margin: 0.6rem 0 0.3rem;
}

.studio-surface .dash-resume__meta {
  color: var(--ink-soft);
  font-size: 0.95rem;
  margin: 0 0 1.1rem;
}

.studio-surface .dash-resume__cta {
  display: flex;
  gap: 0.85rem;
  flex-wrap: wrap;
  align-items: center;
}

/* library section head */
.studio-surface .dash-libhead {
  margin: 0 0 1.3rem;
}

.studio-surface .dash-libhead h2 {
  font-size: 1.6rem;
}

/* book cards — extra structure on top of the shared .book-card.
   Make the dashboard grid cards flex columns so footers bottom-pin
   (`.book-card__foot` / `.order-strip` margin-top:auto) and the new-book
   pseudo-card centers. Scoped to the grid so the shared .book-card stays put. */
.studio-surface .book-grid .book-card {
  display: flex;
  flex-direction: column;
}

.studio-surface .book-card__top {
  display: flex;
  gap: 0.85rem;
  margin-bottom: 0.85rem;
}

.studio-surface .book-card__thumb {
  flex: 0 0 3.4rem;
  width: 3.4rem;
  height: 4rem;
  overflow: hidden;
  background: var(--page);
  border: var(--bw) solid var(--ink);
  border-radius: var(--r-md);
}

/* Shared cover framing for the resume hero + grid cards: the child's first-page
   line art fills the tile (its own aspect cropped to fit), and the branded
   crayon-bloom mark stands in on a butter wash while that page is still drawing. */
.studio-surface .book-thumb__art {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.studio-surface .book-thumb__mark {
  display: grid;
  place-items: center;
  width: 100%;
  height: 100%;
  background: var(--t-butter);
}

.studio-surface .book-thumb__mark svg {
  width: 58%;
  height: 58%;
}

.studio-surface .book-card__title {
  font-size: 1.2rem;
  line-height: 1.15;
  margin: 0 0 0.25rem;
}

.studio-surface .book-card__title a {
  color: var(--ink);
  text-decoration: none;
}

.studio-surface .book-card__title a:hover,
.studio-surface .book-card__title a:focus-visible {
  color: var(--coral-deep);
}

.studio-surface .book-card__sub {
  color: var(--ink-soft);
  font-size: 0.9rem;
  margin: 0;
}

.studio-surface .book-card__prompt {
  color: var(--ink-soft);
  font-size: 0.92rem;
  margin: 0 0 1rem;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.studio-surface .book-card__foot {
  margin-top: auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
}

.studio-surface .book-card__badgerow {
  margin-bottom: 0.85rem;
}

.studio-surface .button--sm {
  padding: 0.5rem 0.9rem;
  font-size: 0.9rem;
}

/* start-a-new-book pseudo-card (first in the grid per owner's tweak) */
.studio-surface .book-card--new {
  border-style: dashed;
  background: transparent;
  box-shadow: none;
  align-items: center;
  justify-content: center;
  text-align: center;
  gap: 0.6rem;
  min-height: 12rem;
  text-decoration: none;
}

.studio-surface .book-card--new:hover,
.studio-surface .book-card--new:focus-visible {
  background: var(--page);
  border-style: solid;
  text-decoration: none;
}

.studio-surface .book-card--new .book-card__plus {
  width: 3rem;
  height: 3rem;
  display: grid;
  place-items: center;
  font-family: "Fredoka", "Nunito", sans-serif;
  font-size: 1.6rem;
  color: #fff;
  background: var(--coral);
  border: var(--bw) solid var(--ink);
  border-radius: 50%;
}

.studio-surface .book-card--new .book-card__sub {
  text-align: center;
}

.studio-surface .book-card--empty {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 0.4rem;
}

/* status badges (the lifecycle dot pills) */
.studio-surface .book-badge {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  font-family: "Nunito", sans-serif;
  font-weight: 800;
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--ink);
  border: 2px solid var(--ink);
  border-radius: 999px;
  padding: 0.25rem 0.7rem;
  box-shadow: 3px 4px 0 rgba(36, 29, 23, 0.1);
}

.studio-surface .book-badge .dot {
  width: 0.5rem;
  height: 0.5rem;
  border-radius: 50%;
  border: 1.5px solid var(--ink);
}

.studio-surface .book-badge--draft {
  background: var(--t-blush);
}
.studio-surface .book-badge--draft .dot {
  background: var(--coral);
}
.studio-surface .book-badge--preview {
  background: var(--t-butter);
}
.studio-surface .book-badge--preview .dot {
  background: var(--marigold);
}
.studio-surface .book-badge--ordered {
  background: var(--t-sky);
}
.studio-surface .book-badge--ordered .dot {
  background: var(--cornflower);
}
.studio-surface .book-badge--printing {
  background: var(--t-grape, #efe7fb);
}
.studio-surface .book-badge--printing .dot {
  background: var(--grape);
}
.studio-surface .book-badge--shipped {
  background: var(--t-mint);
}
.studio-surface .book-badge--shipped .dot {
  background: var(--grass);
}
/* A book we declined wears the paper itself, not the alarm peach `--failed`
   wears: nothing went wrong here and nothing is waiting on the parent, so the
   card should read as set aside rather than as a problem on his shelf. */
.studio-surface .book-badge--declined {
  background: var(--paper);
}
.studio-surface .book-badge--declined .dot {
  background: var(--ink-soft);
}
.studio-surface .book-badge--failed {
  background: #fbe2d4;
}
.studio-surface .book-badge--failed .dot {
  background: var(--coral-deep);
}

/* inline order/fulfillment strip on ordered+ cards */
.studio-surface .order-strip {
  margin-top: auto;
  padding-top: 0.85rem;
  border-top: 2px dashed rgba(36, 29, 23, 0.22);
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.studio-surface .order-row {
  display: flex;
  justify-content: space-between;
  gap: 0.75rem;
  font-size: 0.9rem;
}

.studio-surface .order-row .k {
  color: var(--ink-soft);
}

.studio-surface .order-row .v {
  font-weight: 700;
  text-align: right;
}

.studio-surface .track {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  font-weight: 800;
  color: var(--grass-deep);
  text-decoration: underline;
  text-underline-offset: 2px;
}

.studio-surface .track:hover,
.studio-surface .track:focus-visible {
  color: var(--coral-deep);
}

/* Comfortable touch targets on phones: the spark chips, the card CTAs, and the
   inline tracking link all clear the 44px minimum where taps land. */
@media (max-width: 640px) {
  .studio-surface .dash-chip {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
    padding: 0.4rem 1rem;
  }

  .studio-surface .book-card .button--sm {
    min-height: 44px;
    padding: 0.65rem 1.1rem;
  }

  .studio-surface .track {
    min-height: 44px;
  }
}

/* ============================================================
   The note on a book we declined (books/declined) — the whole page.
   One card, one column, one thing to do. It borrows the studio's card
   skin so it still reads as this parent's shelf, and re-points nothing
   red: the peach band belongs to the failures that are ours.
   ============================================================ */
.studio-surface .studio-note {
  background: var(--page);
  border: var(--bw) solid var(--ink);
  border-radius: var(--r-card);
  box-shadow: var(--shadow-sticker);
  padding: clamp(1.6rem, 4vw, 2.6rem);
  /* Narrow on purpose: the card is the whole page, and its own width is what
     holds every line near the ~60-character measure a parent reads comfortably —
     out loud, quite possibly, with the kid leaning on his arm. */
  max-width: 36rem;
}

/* balance keeps the headline off a one-word second line — it is the sentence
   that delivers the news, and "one" stranded under it reads like a stumble. */
.studio-surface .studio-note__head {
  margin: 0;
  text-wrap: balance;
}

.studio-surface .studio-note__lede {
  margin: 0.9rem 0 0;
  font-size: 1.05rem;
  text-wrap: pretty;
}

.studio-surface .studio-note__action {
  margin: 1.6rem 0 0;
}

.studio-surface .studio-note__aside {
  margin: 1.6rem 0 0;
  font-size: 0.95rem;
}

/* The way to a person, underlined at rest rather than on hover like the shelf's
   other quiet links: this is the one line that matters to a parent we refused by
   mistake, and colour alone is not a link he can find. */
.studio-surface .studio-note__aside a {
  text-decoration: underline;
}

.studio-surface .studio-note__back {
  margin: 1.8rem 0 0;
}

.studio-surface .studio-note__back a {
  color: var(--coral-deep);
  font-weight: 700;
}

/* ---- free-page / auth / support helpers (scoped under .studio-surface) ----
   The shared `.panel`, `.field`, `.eyebrow`, `.button`, `.muted` primitives
   are already branded above; these cover the few links the free-page gate +
   sign-in + support forms add, so the legacy `--accent-strong`/`--muted`
   tokens don't leak through. */
.studio-surface .hero__secondary {
  margin-top: 1.4rem;
  color: var(--ink-soft);
  font-weight: 500;
  font-size: 0.9rem;
}

.studio-surface .link-arrow {
  color: var(--coral-deep);
  font-weight: 700;
  border-bottom: 2px solid transparent;
}

.studio-surface .link-arrow:hover,
.studio-surface .link-arrow:focus-visible {
  border-bottom-color: currentColor;
}

/* ============================================================
   Assemble a book from loose pages (book_assemblies#new picker)
   Reuses the studio tokens; a checkbox turns each page-card into a
   selectable sticker that lifts + rings coral when picked.
   ============================================================ */
.studio-surface .assembly-empty {
  background: var(--page);
  border: var(--bw) solid var(--ink);
  border-radius: var(--r-card);
  box-shadow: var(--shadow-sticker);
  padding: 2rem;
  text-align: center;
}

.studio-surface .assembly-empty h2 {
  margin: 0 0 0.5rem;
}

.studio-surface .assembly-empty .button {
  margin-top: 1.2rem;
}

.studio-surface .assembly-pick {
  border: 0;
  margin: 0;
  padding: 0;
}

.studio-surface .assembly-pick__legend {
  font-weight: 700;
  margin-bottom: 1.1rem;
  color: var(--ink-soft);
}

.studio-surface .assembly-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(11rem, 1fr));
  gap: 1.1rem;
}

.studio-surface .pick-card {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  background: var(--page);
  border: var(--bw) solid var(--ink);
  border-radius: var(--r-card);
  box-shadow: var(--shadow-sticker);
  padding: 0.8rem;
  cursor: pointer;
  transition: transform 0.12s ease, box-shadow 0.12s ease;
}

.studio-surface .pick-card:hover {
  transform: translateY(-2px);
  box-shadow: var(--shadow-sticker-lg);
}

.studio-surface .pick-card__check {
  position: absolute;
  top: 0.85rem;
  left: 0.85rem;
  width: 1.4rem;
  height: 1.4rem;
  accent-color: var(--coral);
}

.studio-surface .pick-card:has(.pick-card__check:checked) {
  outline: 3px solid var(--coral);
  outline-offset: 2px;
}

.studio-surface .pick-card:has(.pick-card__check:focus-visible) {
  outline: 3px solid var(--cornflower);
  outline-offset: 2px;
}

.studio-surface .pick-card__art {
  display: block;
  aspect-ratio: var(--art-aspect);
  overflow: hidden;
  border-radius: var(--r-lg);
  background: var(--paper);
  border: 2px solid var(--ink);
}

.studio-surface .pick-card__art img {
  width: 100%;
  height: 100%;
  object-fit: contain;
}

.studio-surface .pick-card__prompt {
  font-size: 0.9rem;
  color: var(--ink-soft);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.studio-surface .assembly-form__foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 1rem;
  margin-top: 1.8rem;
}

.studio-surface .assembly-form__hint {
  margin: 0;
  font-size: 0.9rem;
  color: var(--ink-soft);
}

/* ============================================================
   Book-builder wizard (books#new / books#edit React island, BookWizardApp)
   ------------------------------------------------------------
   Migrated onto the shipped studio design system (T-6926). The island
   now renders inside `.studio-surface` (see books/new + books/edit), so
   it inherits the shared primitives — `.eyebrow`, `.field`, `.button`,
   `.studio-chip`, `.studio-message`, `.studio-card`, headings, `.muted`,
   `.studio-card__lede` — exactly like the book page. These rules add only
   what's unique to the wizard: the narrow column, the composer, the
   editable page list, and the dark "next step" bar. No new visual
   language — same tokens, same sticker recipe.
   ============================================================ */
.book-wizard-surface {
  padding-bottom: 4rem;
}

/* single narrow reading column inside the page-shell */
.studio-surface .book-wizard {
  width: min(760px, 100%);
  margin: 0 auto;
  display: flex;
  flex-direction: column;
  gap: clamp(1.5rem, 3.4vw, 2.6rem);
}

/* ---- shared header (both steps) ---- */
.studio-surface .wiz-head h1 {
  margin: 0;
}

.studio-surface .wiz-head__row {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 0.9rem 1.2rem;
  flex-wrap: wrap;
}

.studio-surface .wiz-head .studio-card__lede {
  margin: 0.9rem 0 0;
  max-width: 54ch;
}

.studio-surface .wiz-back {
  flex: 0 0 auto;
  font-size: 0.9rem;
  padding: 0.55rem 1rem;
  min-height: 0;
  white-space: nowrap;
}

/* ---- step 1: start ---- */
.studio-surface .wiz-start {
  display: flex;
  flex-direction: column;
  gap: clamp(1.5rem, 3.4vw, 2.4rem);
}

.studio-surface .wiz-head--center {
  text-align: center;
}

.studio-surface .wiz-head--center .wiz-lede {
  margin-left: auto;
  margin-right: auto;
  max-width: 46ch;
}

/* the prompt composer — a white studio card holding the labelled fields */
.studio-surface .wiz-composer {
  display: flex;
  flex-direction: column;
  gap: 1.2rem;
  padding: clamp(1.3rem, 3.4vw, 2rem);
}

.studio-surface .wiz-composer .field {
  display: grid;
  gap: 0.45rem;
}

.studio-surface .wiz-composer .field input,
.studio-surface .wiz-composer .field textarea,
.studio-surface .wiz-composer .field select {
  width: 100%;
}

.studio-surface .wiz-composer__prompt {
  min-height: 132px;
  resize: vertical;
  line-height: 1.5;
  font-size: 1.05rem;
}

/* inline "the more you tell us…" hint next to a field label */
.studio-surface .wiz-optional {
  font-family: "Nunito", sans-serif;
  font-weight: 600;
  font-size: 0.82rem;
  color: var(--ink-soft);
  text-transform: none;
  letter-spacing: 0;
}

/* example sparks — pickable prompt chips (mirrors the dashboard composer's
   .dash-chip; aria-current marks the one that filled the prompt) */
.studio-surface .wiz-sparks {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem 0.7rem;
}

.studio-surface .wiz-sparks__label {
  font-family: "Nunito", sans-serif;
  font-weight: 800;
  font-size: 0.78rem;
  color: var(--ink-soft);
}

.studio-surface .wiz-sparks__chips {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}

.studio-surface .wiz-chip {
  font-family: "Nunito", sans-serif;
  font-weight: 700;
  font-size: 0.84rem;
  color: var(--ink);
  background: var(--page);
  border: 2px solid var(--ink);
  border-radius: 999px;
  padding: 0.36rem 0.85rem;
  min-height: 0;
  box-shadow: 2px 3px 0 rgba(36, 29, 23, 0.1);
  transition: transform 0.14s ease, box-shadow 0.14s ease, background 0.15s ease;
}

.studio-surface .wiz-chip:hover {
  transform: translate(-1px, -1px);
  background: var(--t-sky);
  box-shadow: 3px 4px 0 rgba(36, 29, 23, 0.12);
}

.studio-surface .wiz-chip[aria-current="true"] {
  background: var(--marigold);
}

.studio-surface .wiz-style {
  margin: 0;
}

/* hint + primary CTA row */
.studio-surface .wiz-composer__foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
}

.studio-surface .wiz-composer__hint {
  margin: 0;
  max-width: 38ch;
  font-size: 0.92rem;
}

.studio-surface .wiz-assent {
  margin: 0;
  font-size: 0.82rem;
  line-height: 1.5;
}

.studio-surface .wiz-assent a {
  color: var(--coral-deep);
  font-weight: 700;
}

/* free-to-review reassurances — a small grass-checked row */
.studio-surface .wiz-reassure {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.7rem 1.6rem;
  list-style: none;
  margin: 0;
  padding: 0;
}

.studio-surface .wiz-reassure li {
  position: relative;
  padding-left: 1.7rem;
  font-weight: 600;
  font-size: 0.92rem;
  color: var(--ink-soft);
}

.studio-surface .wiz-reassure li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.05rem;
  width: 1.2rem;
  height: 1.2rem;
  border-radius: 999px;
  background: var(--grass);
  -webkit-mask: no-repeat center / 0.7rem url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='none' stroke='white' stroke-width='3.5' stroke-linecap='round' stroke-linejoin='round' d='M4 12l5 5L20 6'/%3E%3C/svg%3E");
  mask: no-repeat center / 0.7rem url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='none' stroke='white' stroke-width='3.5' stroke-linecap='round' stroke-linejoin='round' d='M4 12l5 5L20 6'/%3E%3C/svg%3E");
}

/* ---- step 1: building (loading) state ---- */
.studio-surface .wiz-building {
  text-align: center;
  padding: clamp(2rem, 5vw, 3.2rem);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.5rem;
}

.studio-surface .wiz-building h1 {
  margin: 0;
}

.studio-surface .wiz-building__spinner {
  width: 2.6rem;
  height: 2.6rem;
  margin-bottom: 0.4rem;
  border: 4px solid var(--t-butter);
  border-top-color: var(--coral);
  border-radius: 50%;
  animation: wiz-spin 0.9s linear infinite;
}

@keyframes wiz-spin {
  to { transform: rotate(360deg); }
}

.studio-surface .wiz-building__step {
  font-family: "Fredoka", "Nunito", sans-serif;
  font-weight: 500;
  font-size: 1.2rem;
  color: var(--ink);
  margin: 0.5rem 0 0;
}

/* ---- step 2: book meta ---- */
.studio-surface .wiz-meta {
  padding: clamp(1.3rem, 3.4vw, 2rem);
}

.studio-surface .wiz-meta__grid {
  display: grid;
  grid-template-columns: 2fr 1.4fr 1fr;
  gap: 1rem;
}

.studio-surface .wiz-meta .field {
  display: grid;
  gap: 0.45rem;
  margin: 0;
}

.studio-surface .wiz-meta__note {
  margin: 1rem 0 0;
  font-size: 0.9rem;
}

@media (max-width: 680px) {
  .studio-surface .wiz-meta__grid {
    grid-template-columns: 1fr;
  }
}

/* the small "our guess" tag on AI-suggested fields */
.studio-surface .wiz-tag {
  display: inline-flex;
  align-items: center;
  font-family: "Nunito", sans-serif;
  font-weight: 800;
  font-size: 0.62rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--grape);
  background: #f1ebfb;
  border: 1.8px solid var(--grape);
  border-radius: 999px;
  padding: 0.16em 0.5em;
  margin-left: 0.35rem;
  vertical-align: middle;
}

/* ---- step 2: the editable page list ---- */
.studio-surface .wiz-outline__head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 0.4rem 1.2rem;
  flex-wrap: wrap;
  margin-bottom: 0.4rem;
}

.studio-surface .wiz-outline__head h2 {
  margin: 0;
}

.studio-surface .wiz-outline__count {
  margin: 0.3rem 0 0;
  font-size: 0.92rem;
}

.studio-surface .wiz-outline__legend {
  margin: 0;
  font-size: 0.8rem;
  font-weight: 700;
}

.studio-surface .wiz-outline__hint {
  margin: 0 0 1rem;
  font-size: 0.9rem;
  max-width: 60ch;
}

.studio-surface .wiz-pages {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 0.85rem;
}

.studio-surface .wiz-page {
  display: grid;
  grid-template-columns: auto auto 1fr auto;
  gap: 0.9rem;
  align-items: start;
  background: var(--page);
  border: var(--bw) solid var(--ink);
  border-radius: var(--r-card);
  box-shadow: var(--shadow-sticker);
  padding: 0.9rem 1rem;
}

.studio-surface .wiz-page:hover {
  box-shadow: var(--shadow-sticker-lg);
}

.studio-surface .wiz-page--editing {
  box-shadow: var(--shadow-sticker-lg);
}

.studio-surface .wiz-page__drag {
  cursor: grab;
  color: var(--ink-soft);
  align-self: center;
  font-size: 1.1rem;
  line-height: 0.7;
  letter-spacing: 1px;
  user-select: none;
}

.studio-surface .wiz-page__drag:active {
  cursor: grabbing;
}

.studio-surface .wiz-page__num {
  width: 1.9rem;
  height: 1.9rem;
  display: grid;
  place-items: center;
  align-self: center;
  font-family: "Fredoka", "Nunito", sans-serif;
  font-weight: 600;
  font-size: 0.95rem;
  color: var(--ink);
  background: var(--t-butter);
  border: var(--bw) solid var(--ink);
  border-radius: var(--r-md);
}

.studio-surface .wiz-page__body {
  min-width: 0;
}

.studio-surface .wiz-page__top {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  flex-wrap: wrap;
  margin-bottom: 0.35rem;
}

.studio-surface .wiz-page__title {
  font-family: "Fredoka", "Nunito", sans-serif;
  font-weight: 600;
  font-size: 1.02rem;
  color: var(--ink);
  overflow-wrap: anywhere;
}

.studio-surface .wiz-page__story {
  color: var(--ink-soft);
  font-size: 0.92rem;
  font-weight: 500;
  line-height: 1.5;
  margin: 0;
}

.studio-surface .wiz-page__actions {
  display: flex;
  flex-direction: column;
  gap: 0.85rem;
  align-self: center;
}

.studio-surface .wiz-page__group {
  display: flex;
  gap: 0.5rem;
}

/* square icon buttons — deliberately NOT the coral pill the studio-surface
   `button` default would give them, so they read as quiet controls */
.studio-surface .wiz-iconbtn {
  width: 2.75rem;
  height: 2.75rem;
  min-height: 0;
  padding: 0;
  display: grid;
  place-items: center;
  background: var(--page);
  border: var(--bw) solid var(--ink);
  border-radius: var(--r-lg);
  box-shadow: 2px 3px 0 rgba(36, 29, 23, 0.12);
  font-size: 1.1rem;
  line-height: 1;
  color: var(--ink);
}

.studio-surface .wiz-iconbtn:hover:not(:disabled) {
  transform: translate(-1px, -1px);
  box-shadow: 3px 4px 0 rgba(36, 29, 23, 0.14);
}

.studio-surface .wiz-iconbtn:disabled {
  opacity: 0.4;
  cursor: not-allowed;
  transform: none;
  box-shadow: 2px 3px 0 rgba(36, 29, 23, 0.12);
}

.studio-surface .wiz-iconbtn--danger {
  color: var(--coral-deep);
  background: var(--t-blush);
}

/* the inline edit / re-prompt panel that opens under a page */
.studio-surface .wiz-reprompt {
  margin-top: 0.8rem;
  display: grid;
  gap: 0.75rem;
}

.studio-surface .wiz-reprompt .field {
  display: grid;
  gap: 0.35rem;
}

.studio-surface .wiz-reprompt .field label {
  font-size: 0.82rem;
}

.studio-surface .wiz-reprompt textarea {
  min-height: 62px;
  resize: vertical;
  line-height: 1.5;
  font-size: 0.95rem;
}

.studio-surface .wiz-reprompt__foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.7rem;
  flex-wrap: wrap;
}

.studio-surface .wiz-typeselect {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  font-weight: 700;
  font-size: 0.85rem;
  color: var(--ink-soft);
}

.studio-surface .wiz-typeselect label {
  font-weight: 700;
}

.studio-surface .wiz-typeselect select {
  width: auto;
  padding: 0.45rem 2rem 0.45rem 0.7rem;
  font-size: 0.85rem;
  background: var(--page);
  border: 2px solid var(--ink);
  border-radius: var(--r-lg);
  color: var(--ink);
  font-family: "Nunito", ui-sans-serif, system-ui, sans-serif;
}

.studio-surface .wiz-reprompt__done {
  font-size: 0.9rem;
  padding: 0.5rem 1.1rem;
  min-height: 0;
}

.studio-surface .wiz-addrow {
  display: flex;
  gap: 0.7rem;
  flex-wrap: wrap;
  margin-top: 1rem;
}

/* ---- step 2: the dark "next step" bar ---- */
.studio-surface .wiz-cta {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.2rem;
  flex-wrap: wrap;
  background: var(--ink);
  border: var(--bw) solid var(--ink);
  border-radius: var(--r-card-lg);
  padding: 1.3rem 1.6rem;
  box-shadow: var(--shadow-sticker);
}

.studio-surface .wiz-cta__copy {
  color: var(--paper);
}

.studio-surface .wiz-cta__copy strong {
  font-family: "Fredoka", "Nunito", sans-serif;
  font-weight: 600;
  font-size: 1.15rem;
  display: block;
}

.studio-surface .wiz-cta__copy span {
  color: #d9cfc4;
  font-weight: 600;
  font-size: 0.9rem;
}

/* the go button rides the marigold sun fill for pop on the dark bar */
.studio-surface .book-wizard .wiz-cta__go {
  flex: 0 0 auto;
  background: var(--marigold);
  color: var(--ink);
}

@media (prefers-reduced-motion: reduce) {
  .studio-surface .wiz-building__spinner {
    animation: none;
  }
  .studio-surface .wiz-chip,
  .studio-surface .wiz-iconbtn,
  .studio-surface .wiz-page {
    transition: none;
  }
  .studio-surface .wiz-chip:hover,
  .studio-surface .wiz-iconbtn:hover:not(:disabled) {
    transform: none;
  }
}
