/* =========================================================================
   Beauty by Kocer — "Pop-up" (design 15)
   A pop-up book. The baseline below is the complete static page: seven
   paper panels in a column (no JS, reduced motion, motion off, short
   screens). popup.js adds html.book-live (+ .book-spread for two-page
   spreads or .book-single for one page at a time) and only then does the
   pinned 3D book take over — every pre-animation state lives under those
   classes, so nothing is ever hidden without scripting.
   ========================================================================= */

/* ---------- Tokens ---------- */
:root {
  /* Palette (brief). Coral and teal are decoration and large type only;
     their -ink partners carry text: 5.5:1 and 5.6:1 on cream. */
  --cream: #FFF6E9;
  --kraft: #D9B98B;
  --coral: #F2665A;
  --coral-ink: #B23A2E;
  --teal: #1FA39A;
  --teal-ink: #0E6F68;
  --ink: #2A2A35;
  --butter: #FFD36E;
  /* Paper shadows and washes: the palette's own ink and inks at low alpha. */
  --shadow-edge: rgba(42, 42, 53, .22);
  --shadow-soft: rgba(42, 42, 53, .14);
  --shadow-deep: rgba(42, 42, 53, .3);
  --kraft-wash: rgba(217, 185, 139, .34);
  --coral-wash: rgba(242, 102, 90, .16);
  --teal-wash: rgba(31, 163, 154, .18);
  --butter-wash: rgba(255, 211, 110, .5);
  --cream-glare: rgba(255, 246, 233, .5);
  --ink-scrim: rgba(42, 42, 53, .78);
  /* Ink ring: 13:1 on cream, 7.6:1 on kraft, 4.6:1 on coral and teal. */
  --focus: var(--ink);
  --paper-shadow: 0 1px 0 var(--shadow-edge), 0 10px 18px -10px var(--shadow-soft), 0 26px 44px -26px var(--shadow-deep);
  --grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23g)' opacity='.5'/%3E%3C/svg%3E");

  /* Type: Young Serif for display, Work Sans for text. */
  --font-display: 'Young Serif', Georgia, 'Times New Roman', serif;
  --font-text: 'Work Sans', 'Segoe UI', Arial, sans-serif;
  --fs-12: 12px;
  --fs-14: 14px;
  --fs-16: 16px;
  --fs-18: 18px;
  --fs-22: 22px;
  --fs-28: 28px;
  --fs-36: 36px;
  --fs-hero: clamp(36px, 4.2vw, 64px);
  --lh-body: 1.55;
  --lh-tight: 1.12;

  /* Spacing: one 4px scale. */
  --sp-4: 4px;
  --sp-8: 8px;
  --sp-12: 12px;
  --sp-16: 16px;
  --sp-24: 24px;
  --sp-32: 32px;
  --sp-48: 48px;
  --sp-64: 64px;

  /* Radii: paper corners are nearly square; pills for buttons. */
  --r-2: 2px;
  --r-6: 6px;
  --r-pill: 999px;

  /* Easing and timing: every transition names one of these. */
  --ease-paper: cubic-bezier(.22, 1, .36, 1);
  --ease-roll: cubic-bezier(.76, 0, .24, 1);
  --ease-spring: cubic-bezier(.34, 1.56, .64, 1);
  --ease-out: cubic-bezier(.33, 1, .68, 1);
  --t-micro: 150ms;
  --t-ui: 300ms;
  --t-enter: 600ms;

  --head-h: 64px;
}

/* ---------- Reset & base ---------- */
*, *::before, *::after { box-sizing: border-box; }
html {
  -webkit-text-size-adjust: 100%;
  /* clip, never hidden: hidden on body/html breaks ScrollTrigger's pin. */
  overflow-x: clip;
}
body {
  margin: 0;
  color: var(--ink);
  font-family: var(--font-text);
  font-size: var(--fs-16);
  line-height: var(--lh-body);
  /* The "table" the book lies on: kraft-washed cream with paper grain. */
  background-color: var(--cream);
  background-image: var(--grain), linear-gradient(var(--kraft-wash), var(--kraft-wash));
}
h1, h2, p, figure, ol, ul { margin: 0; }
ol, ul { padding: 0; list-style: none; }
h1, h2 { font-family: var(--font-display); font-weight: 400; line-height: var(--lh-tight); text-wrap: balance; }
img { display: block; max-width: 100%; height: auto; }
video { display: block; }
a { color: inherit; }
button { font: inherit; color: inherit; background: none; border: 0; padding: 0; cursor: pointer; }
[hidden] { display: none !important; }
:focus-visible { outline: 3px solid var(--focus); outline-offset: 3px; border-radius: var(--r-2); }
main:focus { outline: none; }

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}
.skip-link {
  position: fixed;
  left: var(--sp-16);
  top: var(--sp-12);
  z-index: 80;
  transform: translateY(-160%);
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  padding: 0 var(--sp-16);
  background: var(--ink);
  color: var(--cream);
  border-radius: var(--r-pill);
  transition: transform var(--t-ui) var(--ease-paper);
}
.skip-link:focus-visible { transform: none; outline-color: var(--butter); }

/* ---------- Header: a perforated paper strip ---------- */
.topbar {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: 50;
  height: var(--head-h);
  display: flex;
  align-items: center;
  gap: var(--sp-16);
  padding: 0 var(--sp-24);
  background: var(--cream);
  border-bottom: 2px dashed var(--kraft);
}
.wordmark {
  display: inline-flex;
  align-items: baseline;
  gap: var(--sp-8);
  min-height: 44px;
  padding-top: var(--sp-8);
  font-family: var(--font-display);
  font-size: var(--fs-22);
  text-decoration: none;
  white-space: nowrap;
}
.wordmark-small {
  font-family: var(--font-text);
  font-size: var(--fs-12);
  font-weight: 600;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--teal-ink);
}
.contents { margin-left: auto; }
.contents ol { display: flex; gap: var(--sp-4); }
.contents a {
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  border-radius: var(--r-2);
  font-size: var(--fs-14);
  font-weight: 600;
  text-decoration: none;
  background: var(--cream);
  box-shadow: 0 0 0 1px var(--kraft);
  transition: transform var(--t-micro) var(--ease-out);
}
.contents a:hover { background: var(--butter); transform: translateY(-2px); }
.contents a[aria-current="true"] { background: var(--coral); box-shadow: 0 0 0 1px var(--coral-ink); }
.counter {
  font-size: var(--fs-14);
  font-weight: 500;
  white-space: nowrap;
}
.counter-num { font-weight: 600; color: var(--coral-ink); }
/* A static "Spread 1 of 7" would be wrong the moment a no-JS visitor
   scrolls; each panel carries its own count instead. */
html:not(.js) .counter,
html:not(.js) .motion-toggle { display: none; }
.motion-toggle {
  min-height: 44px;
  padding: 0 var(--sp-16);
  border-radius: var(--r-pill);
  background: var(--ink);
  color: var(--cream);
  font-size: var(--fs-14);
  font-weight: 500;
  white-space: nowrap;
}
.motion-toggle:hover { background: var(--teal-ink); }
.motion-toggle:disabled { cursor: not-allowed; opacity: .72; }
.motion-state { color: var(--butter); margin-left: var(--sp-4); }

/* =========================================================================
   Baseline — the stacked paper panels. This is the whole page with no JS,
   under reduced motion, with Motion off, and on screens too short for the
   pinned book.
   ========================================================================= */
main { display: block; padding-top: calc(var(--head-h) + var(--sp-32)); }
.book-stage { position: relative; padding: 0 var(--sp-16); }
.book-scene { display: none; }
.cue { display: none; }

.spread {
  position: relative;
  max-width: 1180px;
  margin: 0 auto var(--sp-48);
  padding: var(--sp-32) var(--sp-24) var(--sp-48);
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--sp-32);
  background-color: var(--cream);
  background-image: var(--grain);
  border-radius: var(--r-2);
  box-shadow: var(--paper-shadow);
  scroll-margin-top: calc(var(--head-h) + var(--sp-16));
}
/* Pinking-shears top edge: small kraft triangles cut into the panel. */
.spread::before {
  content: "";
  position: absolute;
  inset: 0 0 auto 0;
  height: 8px;
  background: linear-gradient(135deg, var(--kraft-wash) 25%, transparent 25%) 0 0 / 12px 8px repeat-x,
    linear-gradient(225deg, var(--kraft-wash) 25%, transparent 25%) 0 0 / 12px 8px repeat-x;
  pointer-events: none;
}
.spread-1 { background-color: var(--coral); }

.caption { display: flex; flex-direction: column; align-items: flex-start; gap: var(--sp-12); max-width: 46ch; }
.eyebrow {
  font-size: var(--fs-12);
  font-weight: 600;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--teal-ink);
}
.caption h2 { font-size: var(--fs-36); }
.title-hero { font-size: var(--fs-hero); }
.title-main { display: block; }
.title-sub { display: block; margin-top: var(--sp-8); font-family: var(--font-text); font-size: var(--fs-18); font-weight: 500; letter-spacing: .02em; }
.lede { font-size: var(--fs-18); }
.spread-1 .eyebrow, .spread-1 .title-hero, .spread-1 .lede { color: var(--ink); }
.actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-12) var(--sp-16); }

.link {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-4);
  min-height: 44px;
  font-weight: 500;
  color: var(--coral-ink);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 4px;
}
.link:hover { color: var(--ink); }
.spread-1 .link { color: var(--ink); }
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-8);
  min-height: 44px;
  padding: 0 var(--sp-16);
  border-radius: var(--r-pill);
  font-weight: 500;
  white-space: nowrap;
  transition: transform var(--t-micro) var(--ease-out);
}
.btn:hover { transform: translateY(-2px); }
.btn-solid { background: var(--ink); color: var(--cream); }
.btn-solid:hover { background: var(--teal-ink); }
.btn-paper { background: var(--cream); color: var(--ink); box-shadow: 0 0 0 1px var(--kraft), 0 6px 12px -8px var(--shadow-deep); }
.btn-paper:hover { background: var(--butter); }

/* ---------- Stage in the baseline: a flat open book ---------- */
.stage { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--sp-32); }
.page { display: flex; flex-wrap: wrap; justify-content: center; align-items: flex-start; gap: var(--sp-24); }
.stand { position: relative; flex: 1 1 260px; display: flex; flex-direction: column; align-items: center; min-width: 0; max-width: 100%; }
/* Definite widths all the way down, so every min(100%, …) below resolves
   against a real box instead of a shrink-to-fit (cyclic) one. */
.stand-card { position: relative; display: flex; flex-direction: column; align-items: center; width: 100%; }
.stand-shadow, .stand-deco { display: none; }

/* Films: framed as paper screens. */
.screen {
  display: flex;
  flex-direction: column;
  gap: var(--sp-8);
  width: min(100%, calc(var(--film-w, 54svh) + var(--sp-16)));
  padding: var(--sp-8) var(--sp-8) var(--sp-12);
  background: var(--teal-ink);
  border-radius: var(--r-6);
  box-shadow: var(--paper-shadow);
}
.screen-media { position: relative; overflow: hidden; border-radius: var(--r-2); background: var(--ink); }
/* A film fills its clipped frame, so its own outline would be cut away;
   the ring goes on the unclipped wrapper instead: butter on the teal-ink
   screen, 4.2:1, inside the screen's own padding. (Without :has, the
   film keeps its own ring.) */
@supports selector(:has(a)) {
  .screen-media video:focus-visible { outline: none; }
  .screen-media:has(video:focus-visible) { outline: 3px solid var(--butter); outline-offset: 1px; }
}
.screen-media video { width: 100%; height: 100%; object-fit: cover; }
.ratio-34 { width: 100%; aspect-ratio: 3 / 4; }
.ratio-916 { width: 100%; aspect-ratio: 9 / 16; }
.screen figcaption { color: var(--cream); font-size: var(--fs-14); line-height: 1.35; padding: 0 var(--sp-4); }
.media-error {
  position: absolute;
  inset: auto var(--sp-8) var(--sp-8);
  padding: var(--sp-8) var(--sp-12);
  border-radius: var(--r-6);
  background: var(--ink-scrim);
  color: var(--cream);
  font-size: var(--fs-14);
}
.media-error a { display: inline-flex; align-items: center; min-height: 44px; color: var(--butter); }
.flap-film { --film-w: 45svh; }

/* Two clients: complete squares in cream mats. */
.print { display: flex; flex-direction: column; gap: var(--sp-12); width: min(100%, 460px); }
.print-frame {
  display: block;
  padding: var(--sp-12);
  background: var(--cream);
  border: 2px solid var(--coral);
  border-radius: var(--r-2);
  box-shadow: var(--paper-shadow);
}
.print-frame img { width: 100%; aspect-ratio: 1; object-fit: cover; }
.strip {
  order: 2;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0;
  padding: var(--sp-12) var(--sp-16) var(--sp-4);
  background: var(--butter);
  border-radius: var(--r-2);
  font-size: var(--fs-14);
  font-weight: 500;
  box-shadow: 0 6px 12px -8px var(--shadow-deep);
}
.strip .link { color: var(--ink); }
.pull-tab { display: none; }

/* Client three: the flap is shown open, the accordion laid flat. */
.flap { position: relative; display: flex; justify-content: center; width: 100%; }
.flap-cover, .flap-btn { display: none; }
.accordion { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--sp-8); width: min(100%, 520px); }
.fold figure { display: flex; flex-direction: column; gap: var(--sp-8); padding: var(--sp-8); background: var(--cream); border-radius: var(--r-2); box-shadow: var(--paper-shadow); }
.fold img { width: 100%; aspect-ratio: 3 / 4; object-fit: cover; }
.fold figcaption, .cutout figcaption, .easel figcaption, .portrait figcaption { font-size: var(--fs-14); line-height: 1.35; }

/* The artist at work: deckle-edged cut-outs and a certificate on a stand. */
.cutout { display: flex; flex-direction: column; gap: var(--sp-8); width: min(100%, 340px); filter: drop-shadow(0 12px 14px var(--shadow-soft)); }
.cutout-frame { display: block; padding: var(--sp-8); background: var(--cream); }
.cutout-a .cutout-frame { clip-path: polygon(2% 1%, 26% 0, 51% 2%, 77% 0, 99% 2%, 100% 27%, 98% 52%, 100% 78%, 98% 99%, 73% 100%, 49% 98%, 24% 100%, 1% 98%, 0 73%, 2% 49%, 0 24%); }
.cutout-b .cutout-frame { clip-path: polygon(0 2%, 24% 0, 50% 1%, 76% 0, 100% 1%, 99% 26%, 100% 50%, 98% 74%, 100% 99%, 76% 98%, 51% 100%, 25% 98%, 2% 100%, 0 76%, 1% 50%, 0 26%); }
.cutout img, .easel img, .portrait img, .look-photo img { width: 100%; aspect-ratio: 3 / 4; object-fit: cover; }
.easel { display: flex; flex-direction: column; gap: var(--sp-8); width: min(100%, 360px); }
.easel-frame { display: block; padding: var(--sp-12); background: var(--kraft); border-radius: var(--r-2); box-shadow: var(--paper-shadow); }
.easel-leg { display: none; }

/* Her own looks: the wheel's four portraits laid out as a grid. */
.wheel-clip { position: relative; display: flex; justify-content: center; width: 100%; }
.disc, .wheel-window, .wheel-btn { display: none; }
.rotor { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--sp-16); width: min(100%, 560px); }
.look a {
  display: flex;
  flex-direction: column;
  gap: var(--sp-8);
  padding: var(--sp-8) var(--sp-8) var(--sp-4);
  background: var(--cream);
  border-radius: var(--r-2);
  box-shadow: var(--paper-shadow);
  text-decoration: none;
}
.look-photo { display: block; overflow: hidden; }
.look-name { display: flex; align-items: center; min-height: 44px; font-family: var(--font-display); font-size: var(--fs-18); }

/* Her own transformation: both 9:16 portraits whole, side by side. */
.s6-before, .s6-after { flex: 1 1 0; max-width: 220px; }
.portrait { display: flex; flex-direction: column; gap: var(--sp-8); width: 100%; }
.portrait-frame { display: block; padding: var(--sp-8); background: var(--butter); border-radius: var(--r-2); box-shadow: var(--paper-shadow); }
.portrait img { aspect-ratio: 9 / 16; }
.s6-film { --film-w: 40svh; }

/* Back cover: the contact tag. */
.tag-hook { display: none; }
.tag {
  position: relative;
  display: flex;
  flex-direction: column;
  width: min(100%, 360px);
  color: var(--ink);
  text-decoration: none;
  -webkit-touch-callout: none;
}
.tag-top {
  display: grid;
  place-items: center;
  height: 64px;
  background: var(--kraft);
  clip-path: polygon(22% 0, 78% 0, 100% 100%, 0 100%);
}
.tag-hole { width: 18px; height: 18px; border-radius: 50%; background: var(--cream); box-shadow: inset 0 2px 3px var(--shadow-deep); }
.tag-body {
  display: flex;
  flex-direction: column;
  gap: var(--sp-8);
  padding: var(--sp-24) var(--sp-24) var(--sp-32);
  background: var(--kraft);
  border-top: 2px dashed var(--ink);
  border-radius: 0 0 var(--r-6) var(--r-6);
  box-shadow: var(--paper-shadow);
}
.tag-kicker { font-size: var(--fs-12); font-weight: 600; letter-spacing: .14em; text-transform: uppercase; }
.tag-title { font-family: var(--font-display); font-size: var(--fs-36); line-height: var(--lh-tight); }
.tag-handle { font-weight: 600; overflow-wrap: anywhere; }
.tag-hint { font-size: var(--fs-14); text-decoration: underline; text-underline-offset: 4px; }
.tag-meter { display: none; }
.tag:hover .tag-hint { text-decoration-thickness: 2px; }

/* ---------- Baseline on wider screens: caption beside a flat open book ---------- */
@media (min-width: 900px) {
  .spread {
    grid-template-columns: minmax(0, 1fr) minmax(0, 2fr);
    align-items: start;
    padding: var(--sp-48);
  }
  .caption { position: sticky; top: calc(var(--head-h) + var(--sp-32)); }
  .stage { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 0; }
  .page { padding: 0 var(--sp-24); }
  .page-l { border-right: 1px solid var(--shadow-edge); }
  .page-c { grid-column: 1 / -1; }
  .rotor { grid-template-columns: repeat(4, minmax(0, 1fr)); width: 100%; }
  /* The film spreads (the hero, client three, her transformation) put the
     caption above a full-width stage and give every page its own row, so
     each film keeps its full width: 72svh tall for the 3:4 films, 60svh
     for the detail film, at any desktop width. */
  .spread-1, .spread-3, .spread-6 { grid-template-columns: minmax(0, 1fr); }
  .spread-1 .caption, .spread-3 .caption, .spread-6 .caption { position: static; }
  .spread-3 .page, .spread-6 .page { grid-column: 1 / -1; border-right: 0; }
  .spread-1 .page, .spread-3 .page, .spread-6 .page { padding: 0; }
}

/* ---------- Footer: the kraft endpaper under the book ---------- */
.site-footer {
  position: relative;
  z-index: 2;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--sp-16);
  padding: var(--sp-48) var(--sp-24) var(--sp-64);
  text-align: center;
  background: var(--kraft);
  border-top: 2px dashed var(--ink);
}
.footer-note { max-width: 62ch; font-size: var(--fs-14); }
.footer-nav { display: flex; flex-wrap: wrap; justify-content: center; gap: var(--sp-8) var(--sp-24); }
.footer-nav a {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-8);
  min-height: 44px;
  font-weight: 600;
  text-underline-offset: 4px;
}

/* ---------- Film dialog: native <dialog>, a paper card on an ink scrim ---------- */
.film-dialog {
  width: min(92vw, 520px);
  max-height: 92dvh;
  padding: 0;
  border: 0;
  border-radius: var(--r-6);
  background: var(--cream);
  color: var(--ink);
  box-shadow: var(--paper-shadow);
  overflow: auto;
}
.film-dialog::backdrop { background: var(--ink-scrim); }
.film-dialog[open] { animation: dialog-in var(--t-ui) var(--ease-paper); }
@keyframes dialog-in {
  from { opacity: 0; transform: translateY(16px) scale(.98); }
  to { opacity: 1; transform: none; }
}
.dialog-bar { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-12); padding: var(--sp-8) var(--sp-8) var(--sp-8) var(--sp-24); }
.dialog-bar h2 { font-size: var(--fs-22); }
.dialog-close { display: grid; place-items: center; width: 44px; height: 44px; border-radius: 50%; font-size: var(--fs-18); }
.dialog-close:hover { background: var(--butter-wash); }
.dialog-video { width: 100%; max-height: 70dvh; aspect-ratio: 3 / 4; object-fit: contain; background: var(--ink); }
/* The dialog clips its edges, so this ring sits just inside the film. */
.dialog-video:focus-visible { outline-color: var(--butter); outline-offset: -3px; }
.dialog-note { padding: var(--sp-8) var(--sp-24) var(--sp-16); font-size: var(--fs-14); }
.dialog-note a { display: inline-flex; align-items: center; min-height: 44px; color: var(--coral-ink); text-underline-offset: 4px; }
.film-dialog .media-error { position: static; margin: 0 var(--sp-24) var(--sp-24); }

/* =========================================================================
   Book mode. popup.js writes the geometry as px custom properties on
   <html> (--area-x/-y/-w/-h: the book's box under the header; --book-w,
   --page-w, --page-h: the unprojected book; --front: the front edge above
   the box bottom; --depth: the page's projected depth on screen; --persp;
   --cap-w and --band-h for the captions), so the CSS and the projection
   maths in JS can never disagree.
   ========================================================================= */
html.book-pending main,
html.book-pending .site-footer { visibility: hidden; }

html.book-live main { padding-top: 0; }
html.book-live .book-stage {
  height: 100svh;
  padding: 0;
  overflow: hidden;
  /* A warm lamp over the table, brightest behind the book. */
  background: radial-gradient(ellipse 70% 60% at 62% 40%, var(--cream-glare), transparent 70%);
}
html.book-live .book-scene {
  display: block;
  position: absolute;
  left: var(--area-x);
  top: var(--area-y);
  width: var(--area-w);
  height: var(--area-h);
  perspective: var(--persp);
  perspective-origin: 50% 0;
  pointer-events: none;
}
.book-shift {
  position: absolute;
  left: 50%;
  bottom: var(--front);
  width: var(--book-w);
  height: var(--page-h);
  margin-left: calc(var(--book-w) / -2);
  transform-style: preserve-3d;
  transform-origin: 50% 100%;
}
.book { position: absolute; inset: 0; transform-style: preserve-3d; transform-origin: 50% 100%; }
/* The book's soft shadow on the table, a hair under the boards. It has no
   children, so its blur never flattens any of the 3D above it. */
.book::before {
  content: "";
  position: absolute;
  inset: 3% -3% -4%;
  border-radius: var(--r-6);
  background: var(--shadow-soft);
  filter: blur(16px);
  transform: translateZ(-2px);
}
/* The two halves carry #84, the sticky split: each hinges at the spine and
   lifts its outer edge while a leaf is in the air, then settles flat. */
.half { position: absolute; top: 0; bottom: 0; width: 50%; transform-style: preserve-3d; }
.half-l { left: 0; transform-origin: 100% 50%; }
.half-r { right: 0; transform-origin: 0 50%; }
html.book-single .half-l { display: none; }
/* Page-block thickness: a thin face folded down along the front edge. */
.edge {
  position: absolute;
  left: 0;
  right: 0;
  top: 100%;
  height: 10px;
  transform-origin: 50% 0;
  transform: rotateX(-90deg);
  background: repeating-linear-gradient(180deg, var(--cream) 0 2px, var(--shadow-soft) 2px 3px);
}
.half-l .edge { left: 8px; }
.half-r .edge { right: 8px; }
.leaf {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 50%;
  width: 50%;
  transform-origin: 0 50%;
  transform-style: preserve-3d;
}
/* Pages sit 8px inside the boards so the cloth rim always shows. */
.leaf.is-page { top: 8px; bottom: 8px; width: calc(50% - 8px); }
.face {
  position: absolute;
  inset: 0;
  overflow: hidden;
  backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
}
.face-back { transform: rotateY(180deg); }

/* ---------- Printed page art (decorative) ---------- */
.art {
  background-color: var(--cream);
  background-image: var(--grain), linear-gradient(90deg, var(--shadow-soft), transparent 16%);
}
/* Once a leaf is turned, its back face has the spine on its right edge. */
.face-back.art { background-image: var(--grain), linear-gradient(270deg, var(--shadow-soft), transparent 16%); }
.art-dots {
  background-image: var(--grain), linear-gradient(90deg, var(--shadow-soft), transparent 16%), radial-gradient(circle, var(--teal-wash) 22%, transparent 24%);
  background-size: auto, auto, 22px 22px;
}
.face-back.art-dots { background-image: var(--grain), linear-gradient(270deg, var(--shadow-soft), transparent 16%), radial-gradient(circle, var(--teal-wash) 22%, transparent 24%); }
/* The running line: section name and page number along the page's front
   margin. popup.js keeps every stand-up's base (and its shadow) behind
   this band, so nothing that pops up can ever stand on the print. The
   page number sits at the outer edge of each page. */
.art-run {
  position: absolute;
  left: 7%;
  right: 7%;
  bottom: 1%;
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 4%;
  font-size: clamp(var(--fs-12), calc(var(--page-w) * .028), var(--fs-14));
  line-height: 1.2;
  letter-spacing: .1em;
  text-transform: uppercase;
  white-space: nowrap;
  color: var(--teal-ink);
}
.art-head { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.art-folio { flex: none; font-weight: 600; }
.face-front .art-folio { margin-left: auto; }
.face-back .art-folio { order: -1; }
/* Spread one only: the book's title across the left page, printed below
   where the film and its paper props stand. */
.art-mark {
  position: absolute;
  left: 8%;
  right: 8%;
  bottom: calc(7% + 8px);
  font-family: var(--font-display);
  font-size: calc(var(--page-w) * .1);
  line-height: 1.05;
  text-align: center;
  white-space: nowrap;
}
.art-fold { position: absolute; left: 18%; right: 18%; top: 46%; border-top: 2px dashed var(--kraft); }
.art-board { background-color: var(--teal); background-image: var(--grain), repeating-linear-gradient(45deg, var(--teal-wash) 0 5px, transparent 5px 10px); }
.art-cover {
  display: grid;
  place-items: center;
  background-color: var(--coral);
  background-image: var(--grain), repeating-linear-gradient(45deg, var(--coral-wash) 0 6px, transparent 6px 12px);
}
.cover-label {
  width: 74%;
  padding: 7% 6%;
  text-align: center;
  background: var(--butter);
  border: 2px solid var(--ink);
  border-radius: var(--r-2);
  box-shadow: 6px 6px 0 var(--ink);
}
.cover-kicker { display: block; font-size: max(var(--fs-12), calc(var(--page-w) * .032)); font-weight: 600; letter-spacing: .16em; text-transform: uppercase; }
.cover-title { display: block; margin: 4% 0; font-family: var(--font-display); font-size: calc(var(--page-w) * .1); line-height: 1.05; }
.cover-sub { display: block; font-size: calc(var(--page-w) * .04); }
/* A board's inner face is the endpaper inside a teal cloth rim; the pages
   lying on it are 8px smaller, so the rim frames every spread. Its print
   moves up by the rim so it lines up with the pages' print. */
.leaf:not(.is-page) > .art { box-shadow: inset 0 0 0 8px var(--teal); }
.leaf:not(.is-page) .art-run { bottom: calc(1% + 8px); }

/* ---------- Book mode: spreads become layers over the pinned book ---------- */
html.book-live .spread {
  position: absolute;
  inset: 0;
  display: block;
  max-width: none;
  margin: 0;
  padding: 0;
  background: none;
  border-radius: 0;
  box-shadow: none;
  pointer-events: none;
}
html.book-live .spread::before { display: none; }
html.book-live .eyebrow-count { display: none; }

/* #126 sticky scroll reveal: every caption sits in one column beside the
   pinned book and popup.js slides the column with the scroll, so the text
   travels while the book stays put; the current caption is opaque. */
html.book-live .caption {
  position: absolute;
  top: 0;
  max-width: none;
  gap: var(--sp-8);
  pointer-events: auto;
}
html.book-spread .caption { left: var(--sp-32); width: var(--cap-w); }
html.book-single .caption { left: var(--sp-16); right: var(--sp-16); max-width: 640px; margin: 0 auto; }
/* A focused section (Tab walking the book) is a container, not a control:
   no ring round the whole stage, its heading is underlined in the focus
   colour instead, and the next Tab lands on a control with its own ring. */
.spread:focus { outline: none; }
.spread:focus-visible .caption :is(h1, h2) {
  text-decoration-line: underline;
  text-decoration-thickness: 3px;
  text-decoration-color: var(--focus);
  text-underline-offset: 6px;
}
html.book-live .caption h2 { font-size: var(--fs-28); }
html.book-live .spread-1 .eyebrow { color: var(--teal-ink); }
html.book-live .spread-1 .link { color: var(--coral-ink); }
html.book-single .caption h2 { font-size: var(--fs-22); }
html.book-single .title-hero { font-size: var(--fs-28); }
html.book-single .title-sub { margin-top: var(--sp-4); font-size: var(--fs-16); }
html.book-single .lede { font-size: var(--fs-16); }
html.book-single .caption .eyebrow { display: none; }
html.book-single .actions { gap: var(--sp-8); }
html.book-single .actions .btn,
html.book-single .actions .link { font-size: var(--fs-14); }
html.book-single .actions .btn { padding: 0 var(--sp-12); }

html.book-live .stage {
  position: absolute;
  left: var(--area-x);
  top: var(--area-y);
  width: var(--area-w);
  height: var(--area-h);
  display: block;
  pointer-events: none;
}
html.book-live .page {
  position: absolute;
  top: 0;
  bottom: 0;
  display: block;
  padding: 0;
  border: 0;
  visibility: hidden;
}
html.book-live .page.is-on { visibility: visible; }
/* Pages more than one step from the reader are not rendered, so their
   lazy images wait until the page is next (all pages share one box in the
   pinned stage, where every image would otherwise count as in view). */
html.book-live .page:not(.is-near) { display: none; }
html.book-spread .page-l { left: calc(50% - var(--page-w)); width: var(--page-w); }
html.book-spread .page-r { left: 50%; width: var(--page-w); }
html.book-spread .page-c { left: calc(50% - var(--book-w) / 2); width: var(--book-w); }
/* One page at a time: pieces are placed on the paper itself, from 4px
   off the spine to 16px inside the cloth rim. */
html.book-single .page { left: calc(50% - var(--page-w) / 2 + 4px); width: calc(var(--page-w) - 20px); }

/* A stand-up: its box sits on the page at depth --k (0 = front edge,
   1 = far edge of the projected page); popup.js hinges .stand-card on its
   bottom edge. Positioning containers never take pointer events. */
html.book-live .stand {
  position: absolute;
  left: var(--x, 50%);
  bottom: calc(var(--front) + var(--depth) * var(--k, .3));
  display: block;
  max-width: none;
  transform: translateX(-50%);
  pointer-events: none;
}
html.book-live .stand-card { display: block; width: auto; pointer-events: auto; transform-origin: 50% 100%; }
html.book-live .stand-deco { display: block; }
html.book-live .stand-deco .stand-card { pointer-events: none; }
html.book-live .stand-shadow {
  display: block;
  position: absolute;
  left: -6%;
  right: -6%;
  bottom: -4px;
  height: 16px;
  border-radius: 50%;
  background: radial-gradient(closest-side, var(--shadow-deep), transparent);
  pointer-events: none;
}
/* The glued V-fold foot under each large stand-up (two-page book only;
   phone pages keep that strip for the print). */
html.book-spread .stand-film .stand-card::after,
html.book-spread .stand-flap .stand-card::after,
html.book-spread .stand-print .stand-card::after,
html.book-spread .stand-easel .stand-card::after,
html.book-spread .stand-portrait .stand-card::after {
  content: "";
  position: absolute;
  left: 18%;
  right: 18%;
  top: 100%;
  height: 8px;
  background: var(--kraft);
  clip-path: polygon(0 0, 100% 0, 90% 100%, 10% 100%);
}
/* Captions under media take the frame width and never widen it. */
html.book-live .stand figcaption:not(.strip) { width: 0; min-width: 100%; font-size: var(--fs-12); line-height: 1.3; }

/* Film screens: height-led, sized per stand with --media-h. */
html.book-live .screen { width: auto; gap: var(--sp-4); padding: var(--sp-8); }
html.book-live .ratio-34 { width: calc(var(--media-h) * .75); height: var(--media-h); aspect-ratio: auto; }
html.book-live .ratio-916 { width: calc(var(--media-h) * .5625); height: var(--media-h); aspect-ratio: auto; }

/* Decorative paper props (aria-hidden), each on its own stand. */
.paper { display: block; }
.paper-flat {
  width: 9svh;
  height: 40svh;
  background-color: var(--teal);
  background-image: var(--grain), linear-gradient(90deg, transparent 70%, var(--teal-wash) 70%);
  border-radius: 50% 50% var(--r-2) var(--r-2) / 18% 18% var(--r-2) var(--r-2);
  box-shadow: var(--paper-shadow);
}
.paper-sun {
  width: 22svh;
  aspect-ratio: 1;
  border-radius: 50%;
  background: radial-gradient(circle, var(--butter) 0 42%, transparent 43%), repeating-conic-gradient(var(--coral) 0 9deg, var(--butter-wash) 9deg 18deg);
}
.paper-fern {
  width: 10svh;
  height: 16svh;
  background: var(--teal-ink);
  clip-path: polygon(50% 0, 62% 18%, 90% 14%, 70% 36%, 100% 42%, 70% 58%, 96% 70%, 62% 76%, 56% 100%, 44% 100%, 38% 76%, 4% 70%, 30% 58%, 0 42%, 30% 36%, 10% 14%, 38% 18%);
}
.paper-star {
  width: 9svh;
  aspect-ratio: 1;
  background: var(--butter);
  clip-path: polygon(50% 0, 61% 35%, 98% 35%, 68% 57%, 79% 91%, 50% 70%, 21% 91%, 32% 57%, 2% 35%, 39% 35%);
}
/* Suns and stars stand on thin kraft stalks painted under them. */
html.book-live .s1-sun .stand-card,
html.book-live .s7-star-l .stand-card,
html.book-live .s7-star-r .stand-card {
  padding-bottom: 10svh;
  background: linear-gradient(var(--kraft), var(--kraft)) 50% 100% / 4px 10svh no-repeat;
}

/* ---------- Two-page spreads (3:2 or wider, >= 1024x640): positions -------
   Budget at 1366x768: header 64, front edge 48px above the bottom, the
   page projects about 256px deep. Every base (with its shadow and foot)
   stays behind the printed running line, spread one's film and ferns stand
   behind the wordmark, and every top stays below the header; the numbers
   for each are in the status file. */
html.book-spread .s1-film { --k: .45; --media-h: 60svh; }
html.book-spread .s1-flat-l { --x: calc(50% - var(--book-w) / 2 + 6svh); --k: .56; }
html.book-spread .s1-flat-r { --x: calc(50% + var(--book-w) / 2 - 6svh); --k: .56; }
html.book-spread .s1-sun { --x: calc(50% - 25svh); --k: .84; }
html.book-spread .s1-fern-l { --x: calc(50% - 30svh); --k: .45; }
html.book-spread .s1-fern-r { --x: calc(50% + 30svh); --k: .45; }

html.book-spread .s2-print { --k: .45; }
html.book-spread .s2-print .print { width: min(40svh, var(--page-w) * .72); }

html.book-spread .s3-film { --x: 56%; --k: .3; --media-h: 60svh; }
html.book-spread .s3-flap { --x: 44%; --k: .85; --media-h: 45svh; }
html.book-spread .s3-accordion { --k: .22; }

html.book-spread .s4-mirror { --x: 42%; --k: .62; }
html.book-spread .s4-mirror .cutout { width: min(30svh, var(--page-w) * .5); }
html.book-spread .s4-work { --x: 74%; --k: .22; }
html.book-spread .s4-work .cutout { width: min(25svh, var(--page-w) * .44); }
html.book-spread .s4-cert { --k: .34; }
html.book-spread .s4-cert .easel { width: min(36svh, var(--page-w) * .66); }

html.book-spread .s5-wheel { --k: .22; --look-w: min(30svh, (var(--book-w) * .86 - 24px) * 3 / 11); }

html.book-spread .s6-before { --x: 31%; --k: .36; }
html.book-spread .s6-after { --x: 75%; --k: .36; }
html.book-spread .s6-before .portrait,
html.book-spread .s6-after .portrait { width: min(22svh, (var(--page-w) - 120px) / 2); }
html.book-spread .s6-film { --k: .28; --media-h: min(60svh, (var(--page-w) - 40px) * 16 / 9); }

html.book-spread .s7-tag { --k: .3; }
html.book-spread .s7-tag .tag { width: min(36svh, var(--book-w) * .4); }
html.book-spread .s7-star-l { --x: calc(50% - 32svh); --k: .5; }
html.book-spread .s7-star-r { --x: calc(50% + 32svh); --k: .72; }

/* ---------- One page at a time: phones (down to 640px of visible height),
   4:3 screens and portrait tablets. Budget at 375x640: header 56, caption
   band 174px, front edge 12px above it; every film stays at 52svh, every
   base clears the printed line, every top clears the header. */
html.book-single .stand-deco { display: none; }
html.book-single .s1-film,
html.book-single .s3-film,
html.book-single .s3-flap { --k: .2; --media-h: min(52svh, (100vw - 48px) * 4 / 3); }
html.book-single .s2-print { --k: .24; }
html.book-single .s2-print .print { width: min(36svh, var(--page-w) * .92); }
html.book-single .s3-accordion { --k: .2; }
html.book-single .s4-mirror { --x: 32%; --k: .72; }
html.book-single .s4-mirror .cutout { width: min(26svh, var(--page-w) * .44); }
html.book-single .s4-work { --x: 72%; --k: .2; }
html.book-single .s4-work .cutout { width: min(22svh, var(--page-w) * .36); }
html.book-single .s4-cert { --k: .24; }
html.book-single .s4-cert .easel { width: min(32svh, var(--page-w) * .8); }
html.book-single .s5-wheel { --k: .2; --look-w: min(34svh, 62vw); }
html.book-single .s6-before { --x: 27%; --k: .3; }
html.book-single .s6-after { --x: 73%; --k: .3; }
html.book-single .s6-before .portrait,
html.book-single .s6-after .portrait { width: min(22svh, (var(--page-w) - 64px) / 2); }
html.book-single .s6-film { --k: .2; --media-h: min(52svh, (100vw - 48px) * 16 / 9); }
html.book-single .s7-tag { --k: .28; }
html.book-single .s7-tag .tag { width: min(36svh, var(--page-w) * .76); }
html.book-single .tag-hook { left: -6%; right: -6%; }
html.book-single .screen { padding: var(--sp-4); }
/* On phone pages the shadow stays behind and beside each piece, never on
   the printed line in front of it. */
html.book-single .stand-shadow { bottom: 0; }

/* ---------- Book mode: the pieces inside the stand-ups ---------- */
html.book-live .stand-card { isolation: isolate; }

/* Two clients: the caption strip hides behind the print and rises above
   it when the tab is pulled (or when scrolling passes the spread middle). */
html.book-spread .print { display: block; position: relative; }
html.book-spread .print-frame { position: relative; z-index: 1; padding: var(--sp-8); }
html.book-spread .strip {
  position: absolute;
  left: 6%;
  right: 6%;
  top: var(--sp-12);
  z-index: 0;
  visibility: hidden;
  transform: translateY(0);
  transition: transform var(--t-enter) var(--ease-spring), visibility 0s var(--ease-out) var(--t-enter);
}
html.book-spread .print.is-open .strip {
  visibility: visible;
  transform: translateY(calc(-100% - var(--sp-4)));
  transition: transform var(--t-enter) var(--ease-spring), visibility 0s;
}
html.book-spread .pull-tab {
  position: absolute;
  left: 50%;
  top: 100%;
  z-index: 2;
  display: inline-flex;
  align-items: center;
  gap: var(--sp-8);
  min-height: 44px;
  padding: var(--sp-8) var(--sp-16);
  background: var(--coral);
  color: var(--ink);
  font-size: var(--fs-14);
  font-weight: 600;
  letter-spacing: .06em;
  text-transform: uppercase;
  border-radius: 0 0 var(--r-6) var(--r-6);
  box-shadow: 0 10px 14px -10px var(--shadow-deep);
  transform: translate(-50%, -4px);
  transition: transform var(--t-ui) var(--ease-spring);
}
html.book-spread .print.is-open + .pull-tab { transform: translate(-50%, 8px); }
/* #130 letter swap and 3D rolling flip: each letter is a two-faced cube
   (built by popup.js) that rolls a quarter turn, 25ms after its neighbour. */
.roll { display: inline-flex; white-space: nowrap; perspective: 240px; }
.roll-char {
  position: relative;
  display: inline-block;
  height: 1.3em;
  line-height: 1.3;
  transform-style: preserve-3d;
  transition: transform 400ms var(--ease-roll);
  transition-delay: calc(var(--i, 0) * 25ms);
}
.roll-face { display: block; height: 1.3em; backface-visibility: hidden; -webkit-backface-visibility: hidden; transform: translateZ(.65em); }
.roll-face + .roll-face { position: absolute; left: 0; top: 0; transform: rotateX(-90deg) translateZ(.65em); }
.pull-tab:focus-visible .roll-char,
.pull-tab.is-rolled .roll-char { transform: rotateX(90deg); }
@media (hover: hover) and (pointer: fine) {
  .pull-tab:hover .roll-char { transform: rotateX(90deg); }
}

/* Client three: the flap is a two-faced paper door over the detail film;
   popup.js writes its angle. The film under it never rotates. */
html.book-live .flap { display: block; width: auto; }
/* Hinged on its left edge, the flap swings back and away from the reader,
   so it never grows toward the header or over the film it uncovers.
   Clicking the flap itself opens and closes it, like the button. */
html.book-live .flap-cover {
  display: block;
  position: absolute;
  inset: 0;
  z-index: 2;
  transform-origin: 0 50%;
  transform-style: preserve-3d;
  cursor: pointer;
}
.flap-cover::before,
.flap-cover::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: var(--r-6);
  backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
}
.flap-cover::before {
  background-color: var(--kraft);
  background-image: var(--grain), repeating-linear-gradient(90deg, var(--kraft-wash) 0 2px, transparent 2px 10px);
  box-shadow: var(--paper-shadow);
}
.flap-cover::after { background: var(--cream); box-shadow: inset 0 0 0 2px var(--kraft); transform: rotateY(180deg); }
.flap-print {
  position: absolute;
  left: 50%;
  top: 58%;
  z-index: 1;
  display: grid;
  place-items: center;
  width: 44%;
  aspect-ratio: 1;
  border-radius: 50%;
  background: var(--butter);
  font-family: var(--font-display);
  font-size: var(--fs-16);
  backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
  transform: translate(-50%, -50%) translateZ(1px);
}
html.book-live .flap-btn { display: inline-flex; }

/* The accordion strip: three panels folded zig-zag; popup.js unfolds them. */
html.book-live .accordion { display: flex; gap: 0; width: auto; perspective: 800px; }
html.book-live .fold { flex: none; width: var(--fold-w); }
html.book-live .fold figure { gap: var(--sp-4); padding: var(--sp-4); box-shadow: 0 8px 14px -10px var(--shadow-deep); }
html.book-live .fold figcaption { line-height: 1.25; }

/* The artist at work: cut-outs and the certificate on an easel. */
html.book-live .cutout { gap: var(--sp-4); }
html.book-live .easel-frame { padding: var(--sp-8); }
html.book-live .easel-leg {
  display: block;
  position: absolute;
  right: -8%;
  bottom: 0;
  z-index: -1;
  width: 34%;
  height: 64%;
  background: var(--teal-ink);
  clip-path: polygon(0 0, 26% 0, 100% 100%, 74% 100%);
  pointer-events: none;
}

/* Her own looks: a volvelle. The disc rises out of a slit in the page;
   four portraits sit on it a quarter turn apart and only the one at the
   top clears the slit, framed by the fixed window. With the portrait width
   w, the disc radius is 11w/6 and its centre sits w/2 below the slit, so
   the neighbours at ±90° stay under the page. */
html.book-live .wheel-clip {
  position: relative;
  display: block;
  overflow: hidden;
  width: calc(var(--look-w) * 11 / 3 + 24px);
  height: calc(var(--look-w) * 4 / 3 + 12px);
}
html.book-live .disc {
  display: block;
  position: absolute;
  left: 0;
  top: 0;
  width: calc(var(--look-w) * 11 / 3 + 24px);
  aspect-ratio: 1;
  border-radius: 50%;
  background: radial-gradient(circle, transparent 0 58%, var(--teal-wash) 58% 60%, transparent 60%),
    repeating-conic-gradient(var(--cream) 0 7.5deg, var(--butter-wash) 7.5deg 15deg);
  box-shadow: inset 0 0 0 12px var(--teal), inset 0 0 0 16px var(--cream), 0 18px 30px -18px var(--shadow-deep);
}
html.book-live .rotor {
  display: block;
  position: absolute;
  left: 50%;
  top: calc(var(--look-w) * 11 / 6 + 12px);
  width: 0;
  height: 0;
}
html.book-live .look {
  position: absolute;
  left: calc(var(--look-w) / -2);
  top: calc(var(--look-w) * -11 / 6);
  width: var(--look-w);
  transform-origin: 50% calc(var(--look-w) * 11 / 6);
  transform: rotate(calc(var(--i, 0) * 90deg));
}
html.book-live .look:nth-child(2) { --i: 1; }
html.book-live .look:nth-child(3) { --i: 2; }
html.book-live .look:nth-child(4) { --i: 3; }
html.book-live .look a { gap: 0; padding: 0; box-shadow: 0 6px 10px -6px var(--shadow-deep); }
/* The portrait link sits under the window frame, which would hide its own
   ring; the frame itself turns ink (13:1 on the cream disc) instead. */
@supports selector(:has(a)) {
  html.book-live .look a:focus-visible { outline: none; }
  html.book-live .wheel-clip:has(a:focus-visible) + .wheel-window { border-color: var(--ink); }
}
html.book-live .look-name {
  position: absolute;
  width: 1px;
  height: 1px;
  min-height: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}
html.book-live .wheel-window {
  display: block;
  position: absolute;
  left: 50%;
  bottom: 0;
  width: calc(var(--look-w) + 16px);
  height: calc(var(--look-w) * 4 / 3 + 8px);
  transform: translateX(-50%);
  border: 10px solid var(--coral);
  border-bottom: 0;
  border-radius: var(--r-6) var(--r-6) 0 0;
  box-shadow: var(--paper-shadow);
  pointer-events: none;
}
.wheel-window-label {
  position: absolute;
  left: 50%;
  bottom: 100%;
  padding: var(--sp-4) var(--sp-12);
  transform: translate(-50%, calc(-1 * var(--sp-8)));
  background: var(--butter);
  border-radius: var(--r-2);
  font-size: var(--fs-12);
  font-weight: 600;
  letter-spacing: .1em;
  text-transform: uppercase;
  white-space: nowrap;
  box-shadow: 0 6px 10px -8px var(--shadow-deep);
}
html.book-live .wheel-btn {
  display: inline-flex;
  position: absolute;
  left: calc(50% + var(--look-w) / 2 + var(--sp-24));
  bottom: var(--sp-12);
  z-index: 2;
}
html.book-single .wheel-btn { left: calc(50% + var(--look-w) / 2 + var(--sp-8)); width: 44px; padding: 0; }
html.book-single .wheel-btn-text {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* Back cover: the tag hangs from a paper arch; #98 fills the perforation
   while it is held (popup.js writes --hold) and tears the tag when full. */
html.book-live .tag-hook {
  display: block;
  position: absolute;
  left: -10%;
  right: -10%;
  top: -56px;
  bottom: 0;
  z-index: -1;
  border: 4px solid var(--teal-ink);
  border-bottom: 0;
  border-radius: 50% 50% 0 0 / 30% 30% 0 0;
  pointer-events: none;
}
html.book-live .tag-hook::after {
  content: "";
  position: absolute;
  left: 50%;
  top: -4px;
  width: 2px;
  height: 88px;
  background: var(--ink);
}
html.book-spread .tag-title { font-size: var(--fs-hero); }
html.book-live .tag-meter {
  display: block;
  position: absolute;
  left: 0;
  right: 0;
  top: 62px;
  height: 4px;
  background: var(--coral-ink);
  transform-origin: 0 50%;
  transform: scaleX(var(--hold, 0));
  pointer-events: none;
}
.tag-body { transition: transform var(--t-enter) var(--ease-spring); }
.tag.is-holding .tag-body { transition: none; }
.tag.is-torn .tag-body { transform: translate(6px, 28px) rotate(-6deg); }

/* ---------- Scroll cue, band and column rules ---------- */
html.book-live .cue {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-8);
  position: absolute;
  z-index: 5;
  padding: var(--sp-4) var(--sp-12);
  border-radius: var(--r-pill);
  background: var(--cream);
  box-shadow: 0 0 0 1px var(--kraft);
  font-size: var(--fs-12);
  font-weight: 600;
  letter-spacing: .08em;
  text-transform: uppercase;
  pointer-events: none;
}
html.book-live .cue { transition: opacity var(--t-ui) var(--ease-out); }
html.book-live .cue.is-done { opacity: 0; }
html.book-spread .cue { left: var(--sp-32); bottom: var(--sp-24); }
html.book-single .cue { right: var(--sp-16); bottom: calc(var(--band-h) - 30px); }
html.book-single .cue-long { display: none; }
.cue-arrow { display: inline-block; }
/* Three bobs on arrival, then still: nothing loops while the page idles. */
html.book-live:not(.motion-off) .cue-arrow { animation: cue-bob 900ms var(--ease-out) 3 both; }
@keyframes cue-bob {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(4px); }
}
/* A perforated rule between the caption column and the book. */
html.book-spread .book-stage::before {
  content: "";
  position: absolute;
  top: calc(var(--head-h) + var(--sp-24));
  bottom: var(--sp-24);
  left: calc(var(--cap-w) + var(--sp-48));
  border-left: 2px dashed var(--kraft);
  pointer-events: none;
}
/* The caption band on phones: a cream strip with a perforated top. */
html.book-single .book-stage::before {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: var(--band-h);
  background: var(--cream);
  border-top: 2px dashed var(--kraft);
  pointer-events: none;
}

/* ---------- Header on narrower screens ---------- */
@media (max-width: 1023.98px) {
  .contents { display: none; }
  .counter { margin-left: auto; }
}
@media (max-width: 599.98px) {
  :root { --head-h: 56px; }
  .topbar { gap: var(--sp-12); padding: 0 var(--sp-16); }
  .wordmark { flex-direction: column; align-items: flex-start; justify-content: center; gap: 0; padding-top: 0; line-height: 1; }
  /* Slim margins keep the stacked films at 52svh or more on phones. */
  .book-stage { padding: 0 var(--sp-8); }
  .spread { padding: var(--sp-24) var(--sp-12) var(--sp-32); }
  .screen { padding: var(--sp-4) var(--sp-4) var(--sp-8); }
  .caption h2 { font-size: var(--fs-28); }
}

/* =========================================================================
   Reduced motion. CSS half of the guard: popup.js never builds the book
   under this preference, so the stacked panels above are the whole page;
   this only stills the few hover and dialog transitions.
   ========================================================================= */
/* Off on purpose: motion is always on, whatever the device's reduced-motion setting (owner's call, 2026-09-23). */
@media not all {
  *, *::before, *::after {
    animation-duration: 1ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 1ms !important;
    scroll-behavior: auto !important;
  }
  .btn:hover, .contents a:hover { transform: none; }
}
/* The Motion toggle, switched off, gives the same still page. */
html.motion-off *,
html.motion-off *::before,
html.motion-off *::after { animation: none !important; transition: none !important; }
html.motion-off .btn:hover, html.motion-off .contents a:hover { transform: none; }

/* ---------- #96 glare: lamp light on the paper, following the pointer ---------- */
.glare {
  position: absolute;
  left: 20%;
  top: 0;
  width: 60%;
  aspect-ratio: 1;
  opacity: 0;
  border-radius: 50%;
  background: radial-gradient(closest-side, var(--cream-glare), transparent);
  transform: translateZ(10px);
  pointer-events: none;
}

/* ---------- Tag meter: drains back smoothly when a hold is let go ---------- */
html.book-live .tag-meter { transition: transform var(--t-ui) var(--ease-out); }
html.book-live .tag.is-holding .tag-meter { transition: none; }

/* ---------- Motion on, but no book (short screens): panels rise in once ----------
   Only under html.panels-live, which popup.js adds; with no JS every panel
   is simply there. The same 24px for every panel, however tall, so anchor
   jumps land where they aim. */
html.panels-live .spread {
  opacity: 0;
  transform: translateY(24px);
  transition: opacity var(--t-enter) var(--ease-paper), transform var(--t-enter) var(--ease-spring);
}
html.panels-live .spread.is-in { opacity: 1; transform: none; }
