/* ==========================================================
   world.css — Custodians of the Stone Circle, homepage
   Replaces cinematic.css entirely.

   Principles, after the design review:
   1. The commissioned art is the star. Never dim it globally —
      darken only locally, behind type.
   2. Depth comes from layered planes and foreground occlusion,
      not from scroll length.
   3. One pinned moment, inside the first screen, as a reward.
   4. Everything readable with no JS and with motion off.
   ========================================================== */

/* ----------------------------------------------------------
   0. Palette + type, taken properly from the cover this time
   ---------------------------------------------------------- */
:root{
  --cyan:      #4FD8E8;   /* the ley-lines, cover panels 1 & 3 */
  --cyan-deep: #1E7F92;
  --ember:     #E8813A;   /* the cover's sunset valley */
  --violet:    #A879BE;   /* the cover's far panel */
  --paper-warm:#EDE3CC;   /* warm parchment, not clinical off-white */
  --paper-line-2: #D8CBAA;

  --font-carved: 'Cinzel', 'Playfair Display', Georgia, serif;
  --plate-ratio: 2.3887;  /* 2200 / 921 — the hero painting */
}

/* ----------------------------------------------------------
   1. Nav — floats over the artwork, condenses on scroll
   ---------------------------------------------------------- */
body[data-world] .site-nav{
  position: fixed; left: 0; right: 0; top: 0;
  background: transparent;
  -webkit-backdrop-filter: none; backdrop-filter: none;
  border-bottom-color: transparent;
}
body[data-world] .site-nav::before{
  content: ""; position: absolute; inset: 0; z-index: -1;
  background: linear-gradient(180deg, rgba(6,9,16,.78), transparent);
  transition: opacity .35s ease;
}
body[data-world] .site-nav.is-condensed{
  background: rgba(6,9,16,.94);
  -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
  border-bottom-color: rgba(201,162,75,.22);
}
body[data-world] .site-nav.is-condensed::before{ opacity: 0; }

/* ----------------------------------------------------------
   2. Grain — the difference between "black" and "darkness".
   Static tile, no animation: cheap, and it survives reduced motion.
   ---------------------------------------------------------- */
.grain{
  position: absolute; inset: 0; z-index: 9;
  pointer-events: none;
  background-image: url("../assets/grain.png");
  background-size: 128px 128px;
  opacity: .16;
  mix-blend-mode: overlay;
}
.grain-warm{ opacity: .17; mix-blend-mode: multiply; }

/* ==========================================================
   3. THE THRESHOLD
   Class is .portal, not .threshold — main.css already defines
   `.threshold svg { width:26px }` for an unrelated divider, and
   that selector was quietly shrinking the ley-line overlay.
   ========================================================== */

.portal{
  display: block;            /* <header> picks up a flex rule elsewhere */
  position: relative;
  height: 100svh;
  min-height: 620px;
  isolation: isolate;      /* contain the blend modes */
  overflow: hidden;
  background: #070A11;
}
/* the pinned beat adds a short runway *below* the hero */
.js .portal{ height: 100svh; }

/* --- the plate: art + ley-lines locked in one coordinate space ---
   Sized to cover the viewport while keeping the painting's aspect,
   so the SVG overlay registers exactly against the painted glow.
   Nudged right of centre so the stone circle sits on the right
   third and the quiet hillside stays free for type.              */
.plate{
  position: absolute;
  top: 50%;
  left: var(--plate-x, 50%);
  transform: translate(-50%, -50%);
  width: max(100%, calc(100svh * var(--plate-ratio)));
  aspect-ratio: 2200 / 921;
  z-index: 0;
  will-change: transform;
}
.plate-art{
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: fill;         /* the box already has the right ratio */
}
.plate-ley{
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  overflow: visible;
  pointer-events: none;
}
/* the painted ley-lines, traced and given a bloom */
.plate-ley .ley{
  fill: none;
  stroke: #7FF0FA;
  stroke-width: 3.2;
  stroke-linecap: round;
  filter: url(#leyBloom);
  opacity: .72;
}
.plate-ley .ley-core{
  fill: none;
  stroke: #E8FEFF;
  stroke-width: 1.4;
  stroke-linecap: round;
  opacity: .62;
}
/* with JS on, the lines arrive rather than simply being there */
.js .plate-ley .ley,
.js .plate-ley .ley-core{
  stroke-dasharray: var(--len, 400);
  stroke-dashoffset: var(--len, 400);
}
/* a slow breath, so the light reads as alive rather than as a PNG */
@media (prefers-reduced-motion: no-preference){
  .plate-ley.is-lit .ley{ animation: ley-breathe 5.5s ease-in-out infinite; }
}
@keyframes ley-breathe{
  0%, 100%{ opacity: .62; }
  50%     { opacity: 1; }
}

/* --- mist: a photographed fog plate on black, screen-blended so only
   the fog carries through. Sits over the middle distance, drifting. --- */
.th-mist{
  position: absolute; left: -14%; right: -14%; top: 44%; height: 34%;
  z-index: 1; pointer-events: none;
  background: url("../assets/mist.jpg") center/cover no-repeat;
  mix-blend-mode: screen;
  opacity: .40;
  -webkit-mask-image: linear-gradient(180deg, transparent, #000 30%, #000 66%, transparent);
  mask-image: linear-gradient(180deg, transparent, #000 30%, #000 66%, transparent);
  will-change: transform;
}
/* the fog's drift is driven from world.js — a keyframe here would
   override the inline transform the parallax needs */

/* --- the pool of light the circle stands in. Sits INSIDE .plate, so it
   is pinned to the painting's own coordinates and moves with it. Kept
   low and blurred: it should read as glow off the ground, never as a
   graphic laid on top of the painting. --- */
.ley-pool{
  position: absolute;
  /* the painted ley-lines run x 51–86%, y 70.5–75% of the painting.
     A 26%-tall ellipse read as a ring hovering in the air; the real
     one is almost flat, because the camera is low. */
  left: 48%; top: 66%; width: 40%; height: 13.5%;
  z-index: 1; pointer-events: none;
  background: url("../assets/ley-pool.jpg") center/100% 100% no-repeat;
  mix-blend-mode: screen;
  opacity: .34;
  filter: blur(1.4px);
  -webkit-mask-image: radial-gradient(ellipse 60% 82% at 50% 54%, #000 26%, transparent 80%);
  mask-image: radial-gradient(ellipse 60% 82% at 50% 54%, #000 26%, transparent 80%);
}
@media (prefers-reduced-motion: no-preference){
  .ley-pool{ animation: pool-breathe 6.5s ease-in-out infinite; }
}
@keyframes pool-breathe{ 0%,100%{ opacity: .22; } 50%{ opacity: .44; } }

/* --- the legibility plate: left-anchored only. The right of the
   frame, where the stones and the glow live, stays untouched. --- */
.th-scrim{
  position: absolute; inset: 0; z-index: 2; pointer-events: none;
  background:
    linear-gradient(94deg, rgba(6,9,16,.90) 0%, rgba(6,9,16,.74) 30%, rgba(6,9,16,.30) 52%, transparent 68%),
    linear-gradient(180deg, rgba(6,9,16,.55) 0%, transparent 26%, transparent 66%, rgba(6,9,16,.42) 100%);
}

/* --- foreground occlusion: a real moorland ridge with boulders, heather
   and grass, cut to alpha, sitting between the reader and the circle.
   That overlap is what puts the reader inside the frame. My earlier attempt
   at this was a generated path with no interior shape; this one has one.
   It occludes the painting and the pool of light, but passes behind the
   copy so it can never clip a button. */
.th-ridge{
  position: absolute; left: -6%; right: -6%; bottom: -1px;
  height: 24%;
  /* below the copy, not above it: at z-index 6 a boulder clipped the
     corner of the primary CTA, and no depth cue is worth that */
  z-index: 4; pointer-events: none;
  /* 100% 100% not cover: the ridge is a shape, and cover would crop the
     boulders out of it */
  background: url("../assets/fore-ridge.png") bottom center/100% 100% no-repeat;
  will-change: transform;
}
@media (max-width: 860px){ .th-ridge{ height: 14%; } }

/* --- the copy column --- */
.th-copy{
  position: relative; z-index: 5;
  width: 100%;
  height: 100%;
  max-width: var(--container);
  margin: 0 auto;
  padding: 0 28px;
  display: flex; flex-direction: column; justify-content: center;
  align-items: flex-start;
  text-align: left;
}
/* narrow enough to stay clear of the stone circle on the right */
.th-inner{ max-width: 27rem; padding-bottom: 4vh; }

.th-cover{
  display: block;
  width: 86px;
  height: auto;
  margin-bottom: 22px;
  border-radius: 2px;
  box-shadow: 0 18px 34px -14px rgba(0,0,0,.9), 0 0 0 1px rgba(232,205,134,.22);
}
.th-eyebrow{
  display: block;
  font-family: var(--font-carved);
  font-size: .74rem; font-weight: 600;
  letter-spacing: .22em; text-transform: uppercase;
  color: var(--gold-soft);
  margin-bottom: 16px;
}
.th-title{
  font-family: var(--font-carved);
  font-weight: 700;
  font-size: clamp(2.05rem, 3.8vw, 3.2rem);
  line-height: 1.02;
  letter-spacing: .005em;
  color: var(--parchment);
  margin: 0 0 16px;
}
.th-title .of{
  display: block;
  font-size: .47em;
  letter-spacing: .17em;
  color: var(--gold-soft);
  margin: .28em 0 .18em;
}
.th-hook{
  font-family: var(--font-serif);
  font-style: italic;
  font-size: clamp(1.05rem, 1.5vw, 1.32rem);
  line-height: 1.45;
  color: #DCD5C4;
  margin: 0 0 18px;
  max-width: 26ch;
  /* stops single-word orphan lines ("...of its / own", "...that / back.")
     without hand-tuning every measure; ignored by browsers that lack it */
  text-wrap: balance;
}
.th-meta{
  font-family: var(--font-ui);
  font-size: .88rem;
  color: var(--parchment-dim);
  margin: 0 0 26px;
}
.th-meta strong{ color: var(--parchment); font-weight: 600; }
.th-ctas{ display: flex; gap: 12px; flex-wrap: wrap; }

/* scroll cue, sitting over the foreground plane */
.th-cue{
  position: absolute; left: 50%; bottom: 26px; z-index: 7;
  transform: translateX(-50%);
  display: flex; flex-direction: column; align-items: center; gap: 9px;
  font-family: var(--font-carved);
  font-size: .68rem; font-weight: 600;
  letter-spacing: .24em; text-transform: uppercase;
  color: var(--parchment-dim);
  text-decoration: none;
}
.th-cue:hover{ color: var(--gold-soft); }
.th-cue .rail{
  width: 1px; height: 40px; position: relative; overflow: hidden;
  background: linear-gradient(180deg, rgba(232,205,134,.6), transparent);
}
.th-cue .rail::after{
  content: ""; position: absolute; left: 0; top: -40px;
  width: 1px; height: 40px;
  background: linear-gradient(180deg, transparent, var(--gold-soft));
}
@media (prefers-reduced-motion: no-preference){
  .th-cue .rail::after{ animation: cue-fall 2.6s cubic-bezier(.5,0,.5,1) infinite; }
}
@keyframes cue-fall{ to{ top: 40px; } }

@media (max-width: 860px){
  .th-scrim{
    background:
      linear-gradient(180deg, rgba(6,9,16,.90) 0%, rgba(6,9,16,.58) 40%, rgba(6,9,16,.34) 62%, rgba(6,9,16,.88) 100%);
  }
  /* on a phone only ~19% of the painting is in frame, so aim it at
     the circle itself rather than the empty hillside */
  /* aim at the stone circle (68% across the painting) but never let
     the painting's edge come into view, whatever the aspect ratio */
  .plate{
    --pw: max(calc(100% + 60px), calc(100svh * var(--plate-ratio)));
    width: var(--pw);
    left: clamp(calc(100% + 30px - var(--pw) / 2), calc(55% - var(--pw) * 0.18), calc(var(--pw) / 2 - 30px));
  }
  .th-inner{ max-width: 100%; padding-bottom: 8vh; }
  .th-cover{ width: 68px; }
}

/* ==========================================================
   4. Shared section furniture

   Two rules that were being broken, and were the whole reason
   the page read as unsettled:

   a) ONE left rail. Every section's label and heading starts at
      the container's left edge. Previously the story, world and
      author headings lived inside the right column of a two-column
      grid, so as you scrolled the section labels jumped between
      four different x positions (158 / 649 / 859 / 400 at 1440px).
      Now the head sits above the grid and the columns start below it.

   b) ONE heading size. The h2s were 40 / 45 / 38 / 38 / 38 / 32px —
      close enough to look like a mistake rather than a hierarchy.
      There are now exactly two display sizes on the page: the hero
      title, and every section heading.
   ========================================================== */

/* main.js gives every #main h2 its own clip-path mask-reveal. On this
   page the headings already sit inside a [data-rise] block that fades
   in, so the two transitions were stacking on the same element and
   muddying each other. One reveal per thing. */
body[data-world] #main h2.rm{ clip-path: none; opacity: 1; }

body[data-world] #main h2{
  font-size: clamp(1.85rem, 2.8vw, 2.4rem);
  line-height: 1.14;
  letter-spacing: -.004em;
  margin: 0;
  /* the measure belongs on the heading itself: `ch` here is 38px-sized,
     so 26ch is a real 26-character line. On the wrapper it resolved
     against the 17px body size and came out less than half as wide. */
  max-width: 26ch;
  /* stops single-word orphan lines ("...of its / own", "...that / back.")
     without hand-tuning every measure; ignored by browsers that lack it */
  text-wrap: balance;
}
.band-head{ margin-bottom: clamp(30px, 3.4vw, 46px); }
.band-head .lede{ margin: 14px 0 0; max-width: 52ch; }
.band{ position: relative; isolation: isolate; padding-block: 78px; }
/* consecutive bands share one gap instead of stacking two */
.band + .band:not(.band-paper){ padding-block-start: 0; }
@media (max-width: 760px){ .band{ padding-block: 56px; } }
.band-dark{ background: linear-gradient(180deg, #070A11, var(--panel) 60%, #070A11); }
.band-paper{
  /* a warm wash over the real paper: the scan darkens toward its edges,
     and body copy has to clear 4.5:1 everywhere on the band, not just in
     the middle of the sheet */
  background:
    linear-gradient(rgba(250,244,230,.52), rgba(250,244,230,.52)),
    url("../assets/paper.jpg") center/cover no-repeat,
    var(--paper-warm);
  color: var(--paper-ink);
  border-top: 1px solid var(--paper-line-2);
  border-bottom: 1px solid var(--paper-line-2);
}
.band-paper h2, .band-paper h3{ color: #23201A; }
.band-paper .eyebrow{ color: #6A5A2E; }

.kicker{
  display: block;
  font-family: var(--font-carved);
  font-size: .72rem; font-weight: 600;
  letter-spacing: .22em; text-transform: uppercase;
  color: var(--gold-soft);
  margin-bottom: 14px;
}
.band-paper .kicker{ color: #6A5418; }

/* ==========================================================
   5. THE STORY — synopsis beside the cover, shown properly
   ========================================================== */
.story-grid{
  display: grid;
  grid-template-columns: minmax(240px, 0.9fr) 1.4fr;
  gap: clamp(36px, 6vw, 84px);
  align-items: start;
}
@media (max-width: 900px){ .story-grid{ grid-template-columns: 1fr; gap: 34px; } }

/* the cover: large, flat, front-on, undamaged. No fake page block,
   no sheen wedge across the artwork, no tilt. */
.cover-plate{ position: relative; }
.cover-plate img{
  width: 100%;
  max-width: 380px;
  margin: 0 auto;
  border-radius: 3px;
  box-shadow:
    0 2px 0 rgba(255,255,255,.06),
    0 40px 70px -34px rgba(0,0,0,.95),
    0 0 0 1px rgba(232,205,134,.14);
}
/* a warm contact glow beneath, instead of a fake 3D pose */
.cover-plate::after{
  content: ""; position: absolute; left: 50%; bottom: -26px;
  width: min(78%, 300px); height: 42px;
  transform: translateX(-50%);
  background: radial-gradient(ellipse at center, rgba(201,162,75,.30), transparent 70%);
  filter: blur(10px);
  pointer-events: none;
}
.story-copy h2{ font-size: clamp(1.8rem, 3vw, 2.5rem); margin-bottom: 20px; }
.story-copy p{ font-size: 1.06rem; }
.story-copy p:last-of-type{ margin-bottom: 26px; }

/* ==========================================================
   6. THE FIVE — full-colour portraits, name set on the image
   ========================================================== */
.five-grid{
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 14px;
  margin-top: 40px;
}
@media (max-width: 1040px){ .five-grid{ grid-template-columns: repeat(3, 1fr); } }
@media (max-width: 640px){ .five-grid{ grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 380px){ .five-grid{ grid-template-columns: 1fr; } }

.child{
  position: relative;
  overflow: hidden;
  border-radius: 3px;
  background: var(--panel);
  border: 1px solid rgba(255,255,255,.06);
  transition: transform .4s var(--ease-cine), box-shadow .4s ease;
}
.child:hover{ transform: translateY(-5px); box-shadow: 0 30px 56px -30px rgba(0,0,0,.9); }
.child-img{ position: relative; aspect-ratio: 3 / 4; }
/* the portraits keep their own colour and their own light. */
.child-img img{
  width: 100%; height: 100%;
  object-fit: cover; object-position: center 22%;
  transition: transform .7s var(--ease-cine);
}
.child:hover .child-img img{ transform: scale(1.04); }
/* the gradient sits low, so it darkens the caption area only */
.child-img::after{
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(180deg, transparent 42%, rgba(7,10,17,.62) 68%, rgba(7,10,17,.97) 100%);
}
.child-cap{
  position: absolute; left: 0; right: 0; bottom: 0; z-index: 2;
  padding: 0 16px 16px;
}
.child-name{
  font-family: var(--font-carved);
  font-weight: 700;
  font-size: 1.16rem;
  color: var(--parchment);
  line-height: 1.1;
}
.child-place{
  display: block;
  font-family: var(--font-ui);
  font-size: .66rem; font-weight: 600;
  letter-spacing: .12em; text-transform: uppercase;
  color: var(--accent, #8FE3DC);
  margin-top: 3px;
}
.child-trait{
  padding: 14px 16px 18px;
  margin: 0;
  font-size: .9rem;
  line-height: 1.5;
  color: var(--parchment-dim);
}

/* ==========================================================
   7. THE WORLD — the map presented as an object, not wallpaper
   ========================================================== */
.map-grid{
  display: grid;
  grid-template-columns: 1.5fr 1fr;
  gap: clamp(32px, 5vw, 66px);
  align-items: start;
}
@media (max-width: 940px){ .map-grid{ grid-template-columns: 1fr; } }

.map-object{
  position: relative;
  transition: transform .8s var(--ease-cine);
}
.map-object img{
  width: 100%;
  display: block;
  border-radius: 2px;
  box-shadow: 0 50px 90px -40px rgba(0,0,0,1);
}
/* the corridor network already painted on the map, given a lift */
.map-object::after{
  content: ""; position: absolute; inset: 0;
  border-radius: 2px;
  background: radial-gradient(ellipse 34% 40% at 50% 50%, rgba(232,205,134,.22), transparent 62%);
  mix-blend-mode: screen;
  opacity: .55;
  pointer-events: none;
  transition: opacity .9s ease;
}
.map-object:hover::after{ opacity: 1; }
@media (prefers-reduced-motion: no-preference){
  .map-object::after{ animation: map-breathe 7s ease-in-out infinite; }
}
@keyframes map-breathe{ 0%,100%{ opacity: .42; } 50%{ opacity: .92; } }

.places{
  list-style: none;
  margin: 22px 0 0;
  padding: 0;
  border-top: 1px solid var(--line);
}
.places li{
  display: flex; align-items: baseline; gap: 12px;
  padding: 11px 0;
  border-bottom: 1px solid var(--line);
  font-family: var(--font-ui);
  font-size: .9rem;
  color: var(--parchment-dim);
}
.places .pl{
  font-family: var(--font-carved);
  font-size: .95rem;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--gold-soft);
  min-width: 8.5rem;
}

/* ==========================================================
   8. FOR GROWN-UPS — the reassurance block, on warm paper
   ========================================================== */
.assure-grid{
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 34px;
  margin-bottom: 46px;
}
@media (max-width: 860px){ .assure-grid{ grid-template-columns: 1fr; gap: 26px; } }
.assure-card{ border-left: 2px solid #A98C3E; padding-left: 20px; }
.assure-card h3{ font-family: var(--font-serif); font-weight: 600; font-size: 1.28rem; margin-bottom: 8px; }
.assure-card p{ color: #55503F; font-size: .97rem; margin: 0; }

.safety{
  background: rgba(255,251,240,.66);
  border: 1px solid var(--paper-line-2);
  border-left: 3px solid #A98C3E;
  padding: 28px 32px;
  margin-bottom: 44px;
}
.safety p{ margin: 0; color: #3A3628; font-size: 1.02rem; line-height: 1.66; }
.safety .kicker{ color: #6A5418; }

.facts{
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 1px;
  background: var(--paper-line-2);
  border: 1px solid var(--paper-line-2);
}
@media (max-width: 860px){ .facts{ grid-template-columns: repeat(2, 1fr); } }
.fact{ background: var(--paper-warm); padding: 20px 18px; text-align: center; }
.fact .k{
  display: block;
  font-family: var(--font-ui);
  font-size: .66rem; font-weight: 600;
  letter-spacing: .1em; text-transform: uppercase;
  color: #6A5418;
  margin-bottom: 7px;
}
.fact .v{ font-family: var(--font-serif); font-weight: 600; font-size: 1.06rem; color: #23201A; }

/* ==========================================================
   9. GET THE BOOK — readers | schools, side by side
   ========================================================== */
.get-grid{
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0;
  border: 1px solid var(--line);
}
@media (max-width: 860px){ .get-grid{ grid-template-columns: 1fr; } }
.get-col{ padding: clamp(28px, 4vw, 46px); }
.get-col + .get-col{ border-left: 1px solid var(--line); }
@media (max-width: 860px){ .get-col + .get-col{ border-left: 0; border-top: 1px solid var(--line); } }
.get-col.readers{ background: linear-gradient(160deg, rgba(201,162,75,.09), transparent 70%); }
.get-col.schools{ background: linear-gradient(160deg, rgba(79,216,232,.07), transparent 70%); }
.get-col h3{ font-family: var(--font-serif); font-weight: 600; font-size: 1.5rem; margin-bottom: 10px; }
.get-col p{ color: var(--parchment-dim); font-size: .97rem; }
.get-actions{ display: flex; flex-wrap: wrap; gap: 10px; margin-top: 22px; align-items: center; }
.get-note{ margin-top: 20px; font-size: .82rem; color: var(--parchment-dim); }

/* ==========================================================
   10. THE AUTHOR
   ========================================================== */
.author-strip{
  display: grid;
  grid-template-columns: 1fr minmax(160px, 220px);
  gap: clamp(28px, 4vw, 52px);
  align-items: start;
}
@media (max-width: 760px){
  .author-strip{ grid-template-columns: 1fr; gap: 24px; }
  .author-strip picture{ order: 2; }
}
.author-strip .portrait{
  width: 100%; max-width: 220px;
  aspect-ratio: 1/1;
  object-fit: cover; object-position: center 25%;
  filter: grayscale(100%) contrast(1.04);
  border: 1px solid var(--line);
  border-radius: 2px;
}
.author-role{
  font-family: var(--font-ui); font-size: .84rem;
  color: var(--cyan); margin: 0 0 14px;
}
.author-strip p{ color: var(--parchment-dim); font-size: 1rem; max-width: 62ch; }

/* ==========================================================
   11. Reveals — in-view, once, no pinning
   ========================================================== */
.js [data-rise]{ opacity: 0; transform: translateY(18px); }
.js [data-rise].is-in{
  opacity: 1; transform: none;
  transition: opacity .8s var(--ease-cine), transform .8s var(--ease-cine);
}
@media (prefers-reduced-motion: reduce){
  .js [data-rise]{ opacity: 1 !important; transform: none !important; }
}

/* ==========================================================
   12. Reduced motion / no-JS safety net
   ========================================================== */
@media (prefers-reduced-motion: reduce){
  .plate{ transform: translate(-50%, -50%) !important; }
  .th-ridge{ transform: none !important; }
  .plate-ley .ley, .plate-ley .ley-core{ stroke-dashoffset: 0 !important; }
}
.no-js .plate-ley .ley,
.no-js .plate-ley .ley-core{ stroke-dashoffset: 0; }

/* on phones the retailer buttons stack full-width — ragged widths read as unfinished */
@media (max-width: 560px){
  .get-actions .btn{ flex: 1 1 100%; text-align: center; }
}

/* ==========================================================
   12. PHASE 0 POLISH
   Small, deliberate motion. Everything here is transform or
   opacity only, and all of it switches off under reduced motion.
   ========================================================== */

/* --- hero: a larger, carved title, and an entrance that settles
       in the same order the eye reads it --- */
.th-title{ font-size: clamp(2.3rem, 4.4vw, 3.9rem); text-shadow: 0 2px 30px rgba(0,0,0,.55); }
.th-title .of{
  background: var(--foil); background-size: 220% 100%;
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
@media (max-width: 860px){ .th-title{ font-size: clamp(2.35rem, 10.4vw, 3rem); } }

@media (prefers-reduced-motion: no-preference){
  .js .th-inner > *{ animation: th-in 1.1s var(--ease-cine) both; }
  .js .th-inner > :nth-child(1){ animation-delay: .15s; }
  .js .th-inner > :nth-child(2){ animation-delay: .30s; }
  .js .th-inner > :nth-child(3){ animation-delay: .42s; }
  .js .th-inner > :nth-child(4){ animation-delay: .62s; }
  .js .th-inner > :nth-child(5){ animation-delay: .74s; }
  .js .th-inner > :nth-child(6){ animation-delay: .88s; }
  /* the gold "of the" catches the light once, after the title lands */
  .js .th-title .of{ animation: foil-sweep 2.4s ease-out 1.3s both; }
}
@keyframes th-in{ from{ opacity: 0; transform: translateY(16px); filter: blur(4px); } to{ opacity: 1; transform: none; filter: none; } }
@keyframes foil-sweep{ from{ background-position: 100% 0; } to{ background-position: 0 0; } }

/* --- buttons: a light that passes across, an arrow that leans --- */
.btn{ position: relative; overflow: hidden; isolation: isolate; }
.btn-solid::after{
  content: ""; position: absolute; inset: 0; z-index: -1;
  background: linear-gradient(105deg, transparent 30%, rgba(255,255,255,.55) 50%, transparent 70%);
  transform: translateX(-120%);
}
@media (prefers-reduced-motion: no-preference){
  .btn-solid:hover::after{ transform: translateX(120%); transition: transform .9s var(--ease-cine); }
}
.btn-arrow span{ display: inline-block; transition: transform .35s var(--ease-cine); }
.btn-arrow:hover span{ transform: translateX(4px); }

/* --- section kickers: a ley-line that draws itself in --- */
.band-head .kicker, .kicker-sub{ display: flex; align-items: center; gap: 12px; }
.band-head .kicker::before, .kicker-sub::before{
  content: ""; flex: none; width: 26px; height: 1px;
  background: linear-gradient(90deg, var(--teal), rgba(95,208,198,0));
  box-shadow: 0 0 8px rgba(95,208,198,.7);
  transform-origin: left center;
}
.band-paper .band-head .kicker::before{ background: linear-gradient(90deg, #8A6D22, rgba(138,109,34,0)); box-shadow: none; }
@media (prefers-reduced-motion: no-preference){
  .js .band-head[data-rise] .kicker::before{ transform: scaleX(0); transition: transform 1.1s var(--ease-cine) .25s; }
  .js .band-head[data-rise].is-in .kicker::before{ transform: scaleX(1); }
}

/* --- the story: a lead line, the cover that tilts toward you --- */
.story-copy .story-lead{
  font-family: var(--font-serif); font-style: italic;
  font-size: clamp(1.2rem, 1.7vw, 1.42rem); line-height: 1.5;
  color: var(--parchment); margin-bottom: 22px;
}
.story-foot{ display: flex; flex-wrap: wrap; align-items: center; gap: 18px 26px; margin-top: 8px; }
.story-copy .story-foot p{ margin: 0; }
.next-up{ font-size: .86rem !important; line-height: 1.5; color: var(--parchment-dim); display: flex; align-items: baseline; gap: 10px; }
.next-up .next-dot{ transform: translateY(-1px); }
.next-up em{ color: var(--parchment); }
.next-dot{ width: 7px; height: 7px; border-radius: 50%; background: var(--teal); box-shadow: 0 0 0 0 rgba(95,208,198,.6); flex: none; }
@media (prefers-reduced-motion: no-preference){ .next-dot{ animation: dot-pulse 2.6s ease-out infinite; } }
@keyframes dot-pulse{ 0%{ box-shadow: 0 0 0 0 rgba(95,208,198,.55); } 70%,100%{ box-shadow: 0 0 0 10px rgba(95,208,198,0); } }

.cover-plate{ perspective: 1100px; }
.cover-plate picture{ display: block; transform-style: preserve-3d; transition: transform .6s var(--ease-cine); will-change: transform; }
.cover-plate .glare{
  position: absolute; inset: 0; pointer-events: none; z-index: 2; border-radius: 2px;
  background: radial-gradient(circle at var(--gx,50%) var(--gy,30%), rgba(255,244,214,.20), transparent 46%);
  opacity: 0; transition: opacity .5s ease; mix-blend-mode: screen;
}
.cover-plate.is-tilting .glare{ opacity: 1; }
@media (max-width: 900px){ .cover-plate{ max-width: 340px; margin-inline: auto; } }

/* --- the five: each card lights in its own colour --- */
.child{ transition: transform .5s var(--ease-cine), box-shadow .5s ease, border-color .5s ease; }
.child:hover, .child:focus-within{
  border-color: color-mix(in srgb, var(--accent) 55%, transparent);
  box-shadow: 0 30px 56px -30px rgba(0,0,0,.9), 0 0 0 1px color-mix(in srgb, var(--accent) 30%, transparent), 0 18px 60px -24px color-mix(in srgb, var(--accent) 45%, transparent);
}
.child-trait{ font-family: var(--font-serif); font-style: italic; font-size: .98rem; line-height: 1.5; }

/* phones: a swipeable row instead of a tall two-column stack */
@media (max-width: 640px){
  .five-grid{
    display: flex; gap: 12px;
    overflow-x: auto; overscroll-behavior-x: contain;
    scroll-snap-type: x mandatory; scroll-padding-inline: 20px;
    margin-inline: -20px; padding: 4px 20px 18px;
    scrollbar-width: none;
  }
  .five-grid::-webkit-scrollbar{ display: none; }
  .five-grid > .child{ flex: 0 0 72%; scroll-snap-align: start; }
  .js .five-grid [data-rise]{ opacity: 1; transform: none; }
  #five .band-head .lede::after{
    content: "Swipe to meet all five \2192"; display: block; margin-top: 10px;
    font-family: var(--font-ui); font-style: normal; font-size: .72rem; font-weight: 600;
    letter-spacing: .14em; text-transform: uppercase; color: var(--teal);
  }
}

/* --- the way through: stops along a single glowing line --- */
.map-intro{ font-size: 1.04rem; }
.kicker-sub{ margin-top: 26px; margin-bottom: 6px; }
.journey{ list-style: none; margin: 10px 0 0; padding: 0; position: relative; counter-reset: stop; }
.journey::before{
  content: ""; position: absolute; left: 11px; top: 16px; bottom: 16px; width: 1px;
  background: linear-gradient(180deg, rgba(95,208,198,.0), rgba(95,208,198,.75) 12%, rgba(95,208,198,.75) 88%, rgba(95,208,198,0));
  box-shadow: 0 0 10px rgba(95,208,198,.5);
  transform-origin: top;
}
.journey li{ position: relative; padding: 12px 0 12px 42px; counter-increment: stop; }
.journey li::before{
  content: counter(stop); position: absolute; left: 0; top: 13px;
  width: 23px; height: 23px; border-radius: 50%;
  display: grid; place-items: center;
  font-family: var(--font-ui); font-size: .66rem; font-weight: 700; color: #06131A;
  background: radial-gradient(circle at 40% 35%, #BDF6F0, var(--teal) 60%, var(--teal-deep));
  box-shadow: 0 0 0 4px rgba(7,10,17,1), 0 0 16px rgba(95,208,198,.65);
}
.journey .pl{
  display: block; font-family: var(--font-carved); font-weight: 600;
  font-size: 1rem; letter-spacing: .06em; color: var(--gold-soft);
}
.journey .pd{ display: block; font-size: .9rem; color: var(--parchment-dim); margin-top: 2px; line-height: 1.5; }
@media (prefers-reduced-motion: no-preference){
  .js [data-rise] .journey::before{ transform: scaleY(0); transition: transform 1.6s var(--ease-cine) .3s; }
  .js [data-rise].is-in .journey::before{ transform: scaleY(1); }
  .js [data-rise] .journey li{ opacity: 0; transform: translateX(-8px); transition: opacity .7s ease, transform .7s var(--ease-cine); }
  .js [data-rise].is-in .journey li{ opacity: 1; transform: none; }
  .js [data-rise].is-in .journey li:nth-child(1){ transition-delay: .35s; }
  .js [data-rise].is-in .journey li:nth-child(2){ transition-delay: .55s; }
  .js [data-rise].is-in .journey li:nth-child(3){ transition-delay: .75s; }
  .js [data-rise].is-in .journey li:nth-child(4){ transition-delay: .95s; }
  .js [data-rise].is-in .journey li:nth-child(5){ transition-delay: 1.15s; }
}

/* --- facts: eight cells, never a half-empty row --- */
.facts{ grid-template-columns: repeat(4, 1fr); }
@media (max-width: 860px){ .facts{ grid-template-columns: repeat(2, 1fr); } }
.fact{ transition: background .4s ease; }
.fact:hover{ background: #F3E7C9; }
.nowrap{ white-space: nowrap; }
@media (max-width: 380px){ .fact .v.nowrap{ font-size: .92rem; } }

/* --- the note to families: it reads like a letter --- */
.safety{ position: relative; box-shadow: 0 24px 50px -36px rgba(60,40,10,.45); }
.safety p + p{ margin-top: 12px; }

/* --- buy panel: each column answers the pointer --- */
.get-col{ transition: background-color .5s ease; }
.get-col.readers:hover{ background-color: rgba(201,162,75,.045); }
.get-col.schools:hover{ background-color: rgba(79,216,232,.035); }

/* --- author --- */
.author-say{ font-size: .84rem; color: var(--parchment-dim); margin: -4px 0 12px; letter-spacing: .01em; }
.author-say em{ color: var(--parchment); }
.author-strip .portrait{ transition: filter .8s ease, transform .8s var(--ease-cine); }
.author-strip picture:hover .portrait{ transform: scale(1.015); }

/* --- keyboard focus, always visible and on-brand --- */
body[data-world] :focus-visible{ outline: 2px solid var(--gold-soft); outline-offset: 3px; border-radius: 2px; }
.five-grid:focus-visible{ outline-offset: 6px; }
.th-title .nw{ white-space: nowrap; }
@media (min-width: 861px){ .th-inner{ max-width: 34rem; } .th-hook{ max-width: 30ch; } }

/* hero never crops its own copy: on short screens (iPhone SE, landscape
   tablets) it grows instead of overlapping the nav and the scroll cue */
.portal, .js .portal{ height: auto; min-height: max(620px, 100svh); }
.th-copy{ height: auto; min-height: max(620px, 100svh); padding-top: 92px; padding-bottom: 108px; }
@media (max-height: 720px) and (max-width: 860px){
  .th-cover{ width: 56px; margin-bottom: 14px; }
  .th-eyebrow{ margin-bottom: 10px; }
}
.get-note a{ color: var(--gold-soft); text-decoration: underline; text-underline-offset: 3px; text-decoration-color: rgba(232,205,134,.45); }
.get-note a:hover{ text-decoration-color: var(--gold-soft); }
#schools{ scroll-margin-top: 90px; }
@media (min-width: 861px){ .readers .get-actions .btn{ flex: 1 1 calc(50% - 5px); } }
.get-actions .btn{ justify-content: center; text-align: center; }
