/* Reading layer: the design system (type, spacing, measure, motion timing),
   the scroll-driven atmosphere, section reveals and link/button feedback.
   Loaded after each page's own <style>, so it refines rather than replaces. */

:root {
  /* measure: 44rem column minus the 16px gutters ≈ 672px of text */
  --measure: 44rem;
  --text-size: clamp(1.125rem, 1.04rem + 0.36vw, 1.3rem);
  --leading: 1.74;
  --para-gap: 1.3em;
  --chapter-gap: clamp(5rem, 11vw, 8.5rem);

  /* motion tokens: change timing here, not in the components */
  --ease-out: cubic-bezier(.2, .7, .2, 1);
  --ease-in: cubic-bezier(.4, 0, 1, 1);
  --dur-quick: 220ms;
  --dur-reveal: 750ms;
  --dur-atmo: 60s;
  --reveal-shift: 20px;

  /* atmosphere palette: earthy at the start, neutral in the middle, open at the end */
  --atmo-earth-color: 118, 156, 112;
  --atmo-dusk-color: 74, 78, 128;
  --atmo-dawn-color: 196, 170, 255;
  --atmo-amber-color: 242, 198, 140;
  /* weights are written by metamorphosis.js from the same progress as the creature */
  --atmo-earth: 1;
  --atmo-dusk: 0;
  --atmo-dawn: 0;
}

/* ---------- typography ---------- */
body {
  font-size: var(--text-size);
  line-height: var(--leading);
  font-kerning: normal;
  font-variant-ligatures: common-ligatures;
}
.chapter { padding-top: var(--chapter-gap); }
.chapter p {
  margin: 0 0 var(--para-gap);
  text-wrap: pretty;
  hanging-punctuation: first;
  font-variant-numeric: oldstyle-nums;
}
.chapter .eyebrow { margin-bottom: 2.6rem; }
.statement { margin: 2.2rem 0 1.8rem; }
.pull { margin: 3.4rem auto; }
.lead { margin: 0 0 2rem !important; }
.question { margin-top: -1.5rem; }
.coda { margin-top: var(--chapter-gap); }
@media (max-width: 480px) {
  :root { --leading: 1.7; --para-gap: 1.2em; }
  .pull { margin: 2.6rem auto; }
}

/* ---------- atmosphere ---------- */
.atmosphere {
  position: fixed; inset: 0; z-index: -1; pointer-events: none; overflow: hidden;
}
.atmosphere span {
  position: absolute; inset: -20%;
  transition: opacity 1.2s linear;
}
.atmosphere .earth {
  opacity: var(--atmo-earth);
  background: radial-gradient(ellipse 55% 45% at 18% 78%, rgba(var(--atmo-earth-color), 0.13), transparent 70%);
  animation: atmo-drift var(--dur-atmo) ease-in-out infinite alternate;
}
.atmosphere .dusk {
  opacity: var(--atmo-dusk);
  background: radial-gradient(ellipse 70% 55% at 50% 50%, rgba(var(--atmo-dusk-color), 0.16), transparent 72%);
}
.atmosphere .dawn {
  opacity: var(--atmo-dawn);
  background:
    radial-gradient(ellipse 50% 40% at 82% 18%, rgba(var(--atmo-dawn-color), 0.10), transparent 70%),
    radial-gradient(ellipse 40% 30% at 70% 30%, rgba(var(--atmo-amber-color), 0.06), transparent 70%);
  animation: atmo-drift var(--dur-atmo) ease-in-out infinite alternate-reverse;
}
/* faint paper grain so the night is not flat */
.atmosphere::after {
  content: ""; position: absolute; inset: 0; opacity: 0.05; mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}
@keyframes atmo-drift { from { transform: translate3d(-2%, 1%, 0); } to { transform: translate3d(2%, -1.5%, 0); } }

/* ---------- section reveals ---------- */
.xp-reveal .rv {
  opacity: 0; transform: translateY(var(--reveal-shift));
  transition: opacity var(--dur-reveal) var(--ease-out), transform var(--dur-reveal) var(--ease-out);
}
.xp-reveal .rv.is-in { opacity: 1; transform: none; }
.eyebrow::after { transform-origin: left; transition: transform 1.2s var(--ease-out) 150ms; }
.xp-reveal .eyebrow.rv:not(.is-in)::after { transform: scaleX(0); }

/* the chapter III drawing traces itself when it arrives */
.metamorph g path, .metamorph g circle { stroke-dasharray: 260; stroke-dashoffset: 0; transition: stroke-dashoffset 2.4s var(--ease-out) 200ms; }
.xp-reveal .metamorph.rv:not(.is-in) g path, .xp-reveal .metamorph.rv:not(.is-in) g circle { stroke-dashoffset: 260; }

/* ---------- microinteractions ---------- */
.contents a span:last-child, footer a, .rb-toc a span:last-child {
  background: linear-gradient(currentColor, currentColor) left bottom / 0 1px no-repeat;
  transition: background-size 320ms var(--ease-out), color var(--dur-quick);
  padding-bottom: 1px;
}
.contents a:hover span:last-child, .contents a:focus-visible span:last-child,
footer a:hover, footer a:focus-visible,
.rb-toc a:hover span:last-child { background-size: 100% 1px; }
footer a { text-decoration: none; }

.xp-btn, .rb-share { transition: transform var(--dur-quick) var(--ease-out), border-color var(--dur-quick), color var(--dur-quick), background var(--dur-quick); }
.xp-btn:hover, .rb-share:hover { transform: translateY(-1px); }
.xp-btn:active, .rb-share:active { transform: translateY(0); }

/* quieter ambient motion so the transformation is the one moving thing */
.steps::after { display: none; }
.cue svg { animation: none; }

@media (prefers-reduced-motion: reduce) {
  .xp-reveal .rv { opacity: 1; transform: none; transition: none; }
  .atmosphere span { animation: none; transition: none; }
  .metamorph g path, .metamorph g circle { stroke-dashoffset: 0 !important; transition: none; }
}

/* ---------- hero: a thin line draws itself under the title, the path the butterfly will take ---------- */
.hero-line { display: block; width: min(15rem, 60vw); height: auto; margin: 1.6rem auto 0; overflow: visible; }
.hero-line path {
  fill: none; stroke: var(--teal); stroke-width: 1; stroke-linecap: round; opacity: 0.7;
  stroke-dasharray: 1; stroke-dashoffset: 0;
  animation: line-draw 2.2s var(--ease-out) 1.2s both;
}
.hero-line circle { fill: var(--star); transform-box: fill-box; transform-origin: center; animation: line-dot 0.8s ease-out 3.2s both; }
@keyframes line-draw { from { stroke-dashoffset: 1; } to { stroke-dashoffset: 0; } }
@keyframes line-dot { from { opacity: 0; transform: scale(0.2); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) { .hero-line path, .hero-line circle { animation: none; } }

/* ---------- The Bridge: ape becomes human, human becomes robot ----------
   The figures are white prints on transparent PNGs. Once the figure is in view
   it loops on its own: the ape appears, a ghost of it walks forward and dissolves
   into the human, a ghost of the human dissolves into the robot, the three hold
   together for a moment, then fade and it begins again. One cycle = --bf-cycle. */
.bridge-fig { margin: 2.4rem -16px 2.6rem; --bf-cycle: 6s; }
.bf-stage { position: relative; display: flex; }
.bf-stage img { display: block; min-width: 0; height: auto; }
.bf-fig.f1 { flex: 410 1 0; }
.bf-fig.f2 { flex: 362 1 0; }
.bf-fig.f3 { flex: 398 1 0; }
/* ghosts sit over their source figure and are only seen mid-transformation */
.bf-ghost { position: absolute; top: 0; opacity: 0; pointer-events: none; }
.bf-ghost.g1 { left: 0; width: 35.04%; --to: 94%; }
.bf-ghost.g2 { left: 35.04%; width: 30.94%; --to: 105%; }
.bf-ground {
  position: absolute; left: 6%; right: 6%; bottom: 13%; height: 1px;
  background: linear-gradient(90deg, transparent, var(--rule) 15%, var(--teal) 50%, var(--rule) 85%, transparent);
  transform-origin: left; opacity: 0.6;
}

.bridge-fig.bf-live .f1 { animation: bf-ape var(--bf-cycle) linear infinite; }
.bridge-fig.bf-live .g1 { animation: bf-ghost1 var(--bf-cycle) linear infinite; }
.bridge-fig.bf-live .f2 { animation: bf-human var(--bf-cycle) linear infinite; }
.bridge-fig.bf-live .g2 { animation: bf-ghost2 var(--bf-cycle) linear infinite; }
.bridge-fig.bf-live .f3 { animation: bf-robot var(--bf-cycle) linear infinite; }
.bridge-fig.bf-live .bf-ground { animation: bf-ground var(--bf-cycle) linear infinite; }
.bridge-fig.bf-live .bf-labels li:nth-child(1) { animation: bf-l1 var(--bf-cycle) linear infinite; }
.bridge-fig.bf-live .bf-labels li:nth-child(2) { animation: bf-l2 var(--bf-cycle) linear infinite; }
.bridge-fig.bf-live .bf-labels li:nth-child(3) { animation: bf-l3 var(--bf-cycle) linear infinite; }
/* off screen the loop holds still instead of running unseen */
.bridge-fig.bf-off * { animation-play-state: paused !important; }

/* 0-10% ape appears · 15-45% ape becomes human · 48-78% human becomes robot · hold · 88-97% all fade */
@keyframes bf-ape {
  0%       { opacity: 0; filter: blur(6px); animation-timing-function: ease-out; }
  10%, 88% { opacity: 1; filter: blur(0); animation-timing-function: ease-in; }
  97%, 100% { opacity: 0; filter: blur(4px); }
}
@keyframes bf-ghost1 {
  0%, 15%  { opacity: 0; transform: none; filter: blur(0); animation-timing-function: ease-out; }
  19%      { opacity: 0.85; transform: translateX(calc(var(--to) * 0.08)); animation-timing-function: ease-in-out; }
  45%, 100% { opacity: 0; transform: translateX(var(--to)); filter: blur(10px); }
}
@keyframes bf-human {
  0%, 20%  { opacity: 0; transform: translateX(-38%); filter: blur(12px); animation-timing-function: ease-in-out; }
  34%      { opacity: 0.7; filter: blur(4px); animation-timing-function: ease-out; }
  45%, 88% { opacity: 1; transform: none; filter: blur(0); animation-timing-function: ease-in; }
  97%, 100% { opacity: 0; transform: none; filter: blur(4px); }
}
@keyframes bf-ghost2 {
  0%, 48%  { opacity: 0; transform: none; filter: blur(0); animation-timing-function: ease-out; }
  52%      { opacity: 0.85; transform: translateX(calc(var(--to) * 0.08)); animation-timing-function: ease-in-out; }
  78%, 100% { opacity: 0; transform: translateX(var(--to)); filter: blur(10px); }
}
@keyframes bf-robot {
  0%, 53%  { opacity: 0; transform: translateX(-38%); filter: blur(12px); animation-timing-function: ease-in-out; }
  67%      { opacity: 0.7; filter: blur(4px); animation-timing-function: ease-out; }
  78%, 88% { opacity: 1; transform: none; filter: blur(0); animation-timing-function: ease-in; }
  97%, 100% { opacity: 0; transform: none; filter: blur(4px); }
}
@keyframes bf-ground {
  0%       { transform: scaleX(0); opacity: 0.6; }
  80%, 88% { transform: none; opacity: 0.6; }
  97%, 100% { transform: none; opacity: 0; }
}
@keyframes bf-l1 { 0%, 4% { opacity: 0.15; } 12%, 88% { opacity: 1; } 97%, 100% { opacity: 0.15; } }
@keyframes bf-l2 { 0%, 38% { opacity: 0.15; } 46%, 88% { opacity: 1; } 97%, 100% { opacity: 0.15; } }
@keyframes bf-l3 { 0%, 71% { opacity: 0.15; } 79%, 88% { opacity: 1; } 97%, 100% { opacity: 0.15; } }

.bf-labels { list-style: none; margin: 0.4rem 0 0; padding: 0; position: relative; height: 2.6rem; }
.bf-labels li {
  position: absolute; left: var(--x); transform: translateX(-50%);
  white-space: nowrap; text-align: center;
  font-family: var(--display); font-size: 0.66rem; letter-spacing: 0.24em; text-transform: uppercase; color: var(--ink-faint);
}
.bf-labels li.here { color: var(--teal); }
.bf-labels li.here::before {
  content: ""; display: block; width: 7px; height: 7px; margin: 0 auto 0.5rem; border-radius: 50%;
  background: var(--teal); box-shadow: 0 0 0 4px rgba(127, 227, 224, 0.15), 0 0 14px var(--teal);
}
.bf-labels li:not(.here)::before { content: ""; display: block; width: 5px; height: 5px; margin: 0.1rem auto 0.55rem; border-radius: 50%; border: 1px solid var(--ink-faint); }
@media (max-width: 560px) {
  .bf-labels { height: 3.4rem; }
  .bf-labels li { font-size: 0.56rem; letter-spacing: 0.14em; white-space: normal; width: 6.5rem; }
}
@media (prefers-reduced-motion: reduce) { .bf-stage img, .bf-ground, .bf-labels li { animation: none !important; } .bf-ghost { display: none; } }
