/* ---------- B: the name in three frames ---------- */
/* no words tell anyone to scroll: what comes next is already on screen, out of focus,
   and the next frame's ground waits along the bottom edge */
/* 180vh of scroll per frame (414vh for 03, SPAN in chapters.js): its lines come into focus, it holds,
   then the next frame rises */
.chapters {
  position: relative;
  height: 874vh;
}
.ch-stage {
  position: sticky;
  top: 0;
  height: 100svh;
  overflow: hidden;
  color: var(--ink);
  background-color: transparent;
}
.ch-stage[data-ground="light"] {
  background-color: var(--asphodel);
  color: var(--night);
}

/* ---------- the label and progress ticks along the bottom ---------- */
.ch-meta {
  position: absolute;
  z-index: 3;
  left: max(16px, calc((100% - 1200px) / 2));
  right: max(16px, calc((100% - 1200px) / 2));
  bottom: calc(var(--peek, 0px) + 18px);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  font: 500 12px/1 var(--mono);
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--ink);
}
.ch-label { color: var(--lead); }
.ch-stage[data-meta="light"] .ch-meta { color: var(--night); }
.ch-stage[data-meta="light"] .ch-label { color: var(--night-2); }

.ch-ticks {
  display: flex;
  gap: 6px;
}
.ch-ticks i {
  display: block;
  width: 28px;
  height: 2px;
  background: var(--line);
  position: relative;
  overflow: hidden;
}
.ch-stage[data-meta="light"] .ch-ticks i { background: rgba(18, 17, 25, .14); }
.ch-ticks i::after {
  content: "";
  position: absolute;
  inset: 0;
  background: currentColor;
  transform: scaleX(var(--f, 0));
  transform-origin: left;
}

/* ---------- one frame ---------- */
.chap {
  position: absolute;
  inset: 0;
  isolation: isolate;
  display: grid;
  place-content: center;
  justify-items: center;
  text-align: center;
  gap: clamp(14px, 2.4vw, 28px);
  padding: 80px 16px calc(var(--peek, 0px) + 56px);
  visibility: hidden;
}
.chap.on { visibility: visible; }

/* the scroll is the focus ring: a line sharpens as the page moves, and waits as a soft ghost until then */
.chap > .el:not(.step) {
  opacity: calc(1 - var(--out, 0));
  filter: blur(calc(var(--out, 0) * 12px));
}
.chap .step {
  opacity: calc((.3 + .7 * var(--f, 0)) * (1 - var(--out, 0)));
  filter: blur(calc((1 - var(--f, 0)) * 14px + var(--out, 0) * 12px));
  transform: translateY(calc((1 - var(--f, 0)) * 12px));
  transition: opacity 240ms linear, filter 240ms linear, transform 240ms var(--ease);
}
.chap .say-big .stress i.step {
  opacity: 1;
  filter: none;
  transform: scaleX(var(--f, 0));
}

/* left alone, the next ghost hunts for focus once, like a lens */
@keyframes hunt {
  0%, 100% {
    filter: blur(calc((1 - var(--f, 0)) * 14px));
    opacity: calc(.3 + .7 * var(--f, 0));
  }
  32% {
    filter: blur(2px);
    opacity: .8;
  }
  52% {
    filter: blur(8px);
    opacity: .5;
  }
  70% {
    filter: blur(3.5px);
    opacity: .68;
  }
}
.chap .step.hunt { animation: hunt 1600ms var(--ease) 1; }

.ch-stage.snap,
.ch-stage.snap * { transition: none !important; }

/* ---------- one graphic device per frame (guide 6.2): frosted glass, the drafting grid, the lean ---------- */
.ch-bg {
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  overflow: hidden;
}

/* 01: the key visual's frosted glass, the mark seen through it; the scroll pulls the focus a little, never all the way */
.frost svg {
  position: absolute;
  top: 50%;
  right: -12vw;
  height: min(76svh, 740px);
  width: auto;
  transform: translateY(-48%) rotate(-4deg);
}
.frost .far {
  filter: blur(90px);
  opacity: calc(.3 - .12 * var(--m, 0));
}
.frost .near {
  filter: blur(36px);
  opacity: calc(.2 * var(--m, 0));
}

/* 02: the drafting grid, 8 mm hairlines with a cross every 32 mm, one step off the ground, kept clear of the words */
.grid {
  --hair: #E2E0EA;
  background-image:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='121' height='121'%3E%3Cpath d='M15.5 10v11M10 15.5h11' stroke='%23C9C6D6' stroke-width='1'/%3E%3C/svg%3E"),
    linear-gradient(var(--hair) 1px, transparent 1px),
    linear-gradient(90deg, var(--hair) 1px, transparent 1px);
  background-size: 121px 121px, 30.25px 30.25px, 30.25px 30.25px;
  background-position: center;
  -webkit-mask-image: radial-gradient(ellipse 50% 34% at 50% 50%, transparent 35%, #000 80%);
          mask-image: radial-gradient(ellipse 50% 34% at 50% 50%, transparent 35%, #000 80%);
}

/* 03: the lean, a Laurel field with one edge at the mark's 6 degrees; it waits outside the stage on the right
   and sweeps in from there as the frame hands over to the last one */
.lean {
  --a: calc(-10.5svh - 2px);
  --d: 10.5svh;
  background: var(--laurel-ground);
  clip-path: polygon(calc(100% - var(--a)) 0, 100% 0, 100% 100%, calc(100% - var(--a) - var(--d)) 100%);
}

@media (max-width: 640px) {
  .frost svg {
    right: -34vw;
    height: 38svh;
    top: 80%;
  }
  .frost .far { filter: blur(60px); }
  .frost .near { filter: blur(26px); }
}

/* ---------- the next frame, waiting under the bottom edge; scrolling on lifts it over the stage ---------- */
.ch-peek {
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  clip-path: inset(calc(100% - var(--h, 0px)) 0 0 0);
}
.ch-peek[data-ground="light"] {
  background: var(--asphodel);
  color: var(--night);
}
.ch-peek[data-ground="ink"] {
  color: var(--ink);
  background:
    radial-gradient(60% 50% at 50% 38%, var(--glow) 0%, transparent 70%),
    radial-gradient(120% 90% at 50% 50%, transparent 55%, var(--ground-deep) 100%),
    var(--ground);
}
.ch-peek > .chap { transform: translateY(var(--y, 0px)); }

@keyframes band {
  0%, 100% { clip-path: inset(calc(100% - var(--h, 0px)) 0 0 0); }
  45% { clip-path: inset(calc(100% - var(--h, 0px) - 22px) 0 0 0); }
}
@keyframes lift {
  0%, 100% { transform: translateY(var(--y, 0px)); }
  45% { transform: translateY(calc(var(--y, 0px) - 22px)); }
}
.ch-peek.nudge { animation: band 1300ms var(--ease) 1; }
.ch-peek.nudge > .chap { animation: lift 1300ms var(--ease) 1; }

/* ---------- 01: the sum comes first, small, with the prefix in Latin letters (guide 1.1); "Very easy." follows, big ---------- */
.very {
  margin: 0;
  font: 700 clamp(56px, 11vw, 168px)/1 var(--display);
  letter-spacing: -.025em;
}
.sum {
  margin: 0;
  font: 400 clamp(20px, 2.2vw, 28px)/1.2 var(--ui);
  color: var(--ink-2);
}
.sum .op {
  color: var(--lead);
  margin: 0 .35em;
}
.eri {
  font-family: var(--serif);
  font-style: italic;
  color: var(--gold);
  font-size: 1.12em;
}
.cap {
  margin: 8px 0 0;
  max-width: 40ch;
  color: var(--ink-2);
  font-size: clamp(16px, 1.4vw, 19px);
}
[data-ground="light"] .cap { color: var(--night-2); }

/* ---------- 02: how to say it ---------- */
.say-big {
  margin: 0;
  font: 500 clamp(64px, 17vw, 240px)/1 var(--mono);
  letter-spacing: -.02em;
  color: var(--night);
  white-space: nowrap;
}
.say-big .soft { color: #6E6B80; }
.say-big .stress {
  position: relative;
  display: inline-block;
}
.say-big .stress i {
  position: absolute;
  left: 4%;
  right: 4%;
  bottom: -.12em;
  height: .045em;
  min-height: 3px;
  background: var(--gold-deep);
  transform-origin: left;
}

/* ---------- 03: the "E for" key visual, driven by the scroll ---------- */
/* chapters.js sets --a per word, --g as E and "for" step back, --t for the tail.
   Without those values it rests on "E for everything.", the plain stacked version */
.ef {
  position: relative;
  display: grid;
  justify-items: center;
  transform: translateY(calc(var(--g, 0) * var(--lift, 0px) * -1));
}
.ef-head {
  display: grid;
  justify-items: center;
  opacity: calc(1 - var(--g, 0));
  filter: blur(calc(var(--g, 0) * 14px));
}
.ef-mark {
  width: clamp(52px, 6vw, 76px);
  height: auto;
  display: block;
}
.ef-for {
  margin-top: clamp(22px, 3vw, 36px);
  font: 400 clamp(22px, 2.6vw, 34px)/1 var(--ui);
  color: var(--lead);
}
.ef-word,
.ef-tail {
  font: 700 clamp(56px, 11vw, 168px)/1.1 var(--display);
  letter-spacing: -.02em;
  white-space: nowrap;
}
.ef-word {
  display: grid;
  margin-top: clamp(4px, 1vw, 12px);
}
/* the blur does the hand-over: a word stays visible while it goes soft, and fades only at the end */
.ef-word .w {
  grid-area: 1 / 1;
  justify-self: center;
  opacity: min(1, var(--a, 0) * 2);
  filter: blur(calc((1 - var(--a, 0)) * 18px));
}
.ef-word .w:nth-child(3) { --a: 1; }
.ef-tail {
  position: absolute;
  top: 100%;
  left: 50%;
  margin: 0;
  transform: translateX(-50%);
  color: var(--lead);
  opacity: var(--t, 0);
  filter: blur(calc((1 - var(--t, 0)) * 16px));
}

/* ---------- .static (set by chapters.js): the three frames simply stack, nothing moves ---------- */
.chapters.static { height: auto; }
.chapters.static .ch-stage {
  position: static;
  height: auto;
  display: block;
  background: none;
}
.chapters.static .ch-meta,
.chapters.static .ch-peek { display: none; }
.chapters.static .chap {
  position: relative;
  overflow: hidden;
  padding: 96px 16px;
  visibility: visible;
}
.chapters.static .chap[data-ground="light"] {
  background: var(--asphodel);
  color: var(--night);
}
.chapters.static .el,
.chapters.static .step {
  opacity: 1 !important;
  filter: none !important;
  transform: none !important;
}
.chapters.static .lean { display: none; }
