/* ==========================================================================
   MCPA motion layer
   A presentation-only layer that sits on top of the existing stylesheets and
   turns the page into a continuous, motion-led experience. Everything here is
   additive: remove the file and the site still reads and works exactly as it
   did before.

   Sections
     1  Motion tokens
     2  Smooth-scroll host
     3  Page curtain (first paint)
     4  Reading progress rail
     5  Custom cursor
     6  Reveal primitives (heading masks, cards, media)
     7  Parallax + tilt + spotlight surfaces
     8  Micro-interactions (links, buttons, chips, forms)
     9  Reduced motion
   ========================================================================== */

/* ---------- 1. Motion tokens ---------- */
:root {
  --mo-dur-xs: .18s;
  --mo-dur-sm: .32s;
  --mo-dur-md: .55s;
  --mo-dur-lg: .9s;
  --mo-ease: cubic-bezier(.22, 1, .36, 1);
  --mo-ease-soft: cubic-bezier(.4, 0, .2, 1);
  --mo-ease-spring: cubic-bezier(.34, 1.42, .48, 1);
  --mo-accent: #a94736;
  --mo-accent-warm: #c8894f;
  --mo-light: #e6ebe0;
  --mo-progress: 0;
  --mo-cursor-size: 26px;
}

/* ---------- 2. Smooth-scroll host ---------- */
/* The scroller keeps the real document scroll (so ScrollTrigger, anchors and
   the scrollbar all behave natively); only the wheel delta is eased in JS. */
html.mo-smooth { scroll-behavior: auto !important; }
html.mo-smooth body { overscroll-behavior-y: none; }

/* GPU hints only while a section is actually in play. */
.mo-animating { will-change: transform, opacity; }

/* ---------- 3. Page curtain ---------- */
.mo-curtain {
  position: fixed;
  inset: 0;
  z-index: 9999;
  display: grid;
  place-items: center;
  background: #16241a;
  pointer-events: none;
}
.mo-curtain[hidden] { display: none; }

.mo-curtain-panel {
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, #16241a 0%, #22331f 100%);
  transform-origin: 50% 0;
}

.mo-curtain-mark {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 18px;
  color: var(--mo-light);
  font-family: 'IBM Plex Mono', monospace;
  font-size: 11px;
  letter-spacing: .34em;
  text-transform: uppercase;
}
.mo-curtain-mark img { width: 84px; height: auto; opacity: .92; }

.mo-curtain-bar {
  width: 172px;
  height: 2px;
  background: rgb(230 235 224 / .22);
  overflow: hidden;
}
.mo-curtain-bar i {
  display: block;
  height: 100%;
  width: 100%;
  background: var(--mo-accent);
  transform: scaleX(0);
  transform-origin: 0 50%;
}

/* ---------- 4. Reading progress rail ---------- */
.mo-rail {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  height: 3px;
  z-index: 900;
  pointer-events: none;
  background: rgb(13 23 16 / .18);
}
.mo-rail i {
  display: block;
  height: 100%;
  width: 100%;
  transform: scaleX(var(--mo-progress));
  transform-origin: 0 50%;
  background: linear-gradient(90deg, var(--mo-accent), var(--mo-accent-warm));
}

/* Chapter pips down the right edge. */
.mo-chapters {
  position: fixed;
  right: clamp(10px, 1.6vw, 26px);
  top: 50%;
  transform: translateY(-50%);
  z-index: 880;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  margin: 0;
  padding: 10px 6px;
  list-style: none;
  border-radius: 999px;
  /* A flat translucent fill rather than a backdrop-filter: this element is
     fixed, so a blur would force the compositor to re-sample the page behind
     it on every scrolled frame. */
  background: rgb(13 23 16 / .46);
}
.mo-chapters button {
  position: relative;
  display: grid;
  place-items: center;
  width: 24px;
  height: 24px;
  padding: 0;
  border: 0;
  background: none;
  color: var(--mo-light);
  cursor: pointer;
  font-family: 'IBM Plex Mono', monospace;
  font-size: 10px;
  letter-spacing: .18em;
  text-transform: uppercase;
}
/* Taken out of flow entirely. As an in-flow element at opacity 0 it still
   reserved its full width, which stretched the rail into a wide slab with the
   dots stranded against one edge. */
.mo-chapters .mo-chip-label {
  position: absolute;
  top: 50%;
  right: calc(100% + 10px);
  opacity: 0;
  transform: translate(6px, -50%);
  transition: opacity var(--mo-dur-sm) var(--mo-ease), transform var(--mo-dur-sm) var(--mo-ease);
  white-space: nowrap;
  pointer-events: none;
  text-shadow: 0 1px 6px rgb(13 23 16 / .9), 0 0 14px rgb(13 23 16 / .7);
}
.mo-chapters button:hover .mo-chip-label,
.mo-chapters button:focus-visible .mo-chip-label { opacity: 1; transform: translateX(0); }
.mo-chapters .mo-chip-dot {
  display: block;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: rgb(230 235 224 / .55);
  transition: transform var(--mo-dur-sm) var(--mo-ease-spring), background-color var(--mo-dur-sm) var(--mo-ease);
}
.mo-chapters button[aria-current='true'] .mo-chip-dot {
  background: var(--mo-accent);
  transform: scale(1.75);
}
/* Labels stay hidden until asked for, so the rail never sits on top of the
   page's own content. */
.mo-chapters:hover .mo-chip-label { opacity: .75; transform: translateX(0); }
.mo-chapters:hover button[aria-current='true'] .mo-chip-label { opacity: 1; }

@media (max-width: 1100px) { .mo-chapters { display: none; } }

/* ---------- 5. Custom cursor ---------- */
.mo-cursor,
.mo-cursor-dot {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 9500;
  pointer-events: none;
  border-radius: 50%;
  will-change: transform;
}
.mo-cursor {
  width: var(--mo-cursor-size);
  height: var(--mo-cursor-size);
  margin: calc(var(--mo-cursor-size) / -2) 0 0 calc(var(--mo-cursor-size) / -2);
  border: 1.5px solid rgb(230 235 224 / .75);
  mix-blend-mode: difference;
  display: grid;
  place-items: center;
}
.mo-cursor span {
  font-family: 'IBM Plex Mono', monospace;
  font-size: 9px;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: #16241a;
  opacity: 0;
  white-space: nowrap;
}
.mo-cursor-dot {
  width: 5px;
  height: 5px;
  margin: -2.5px 0 0 -2.5px;
  background: var(--mo-accent);
}
html.mo-cursor-on,
html.mo-cursor-on .mcpa-story-v2,
html.mo-cursor-on a,
html.mo-cursor-on button { cursor: none; }
html.mo-cursor-on input,
html.mo-cursor-on textarea,
html.mo-cursor-on select { cursor: auto; }

@media (hover: none), (pointer: coarse) {
  .mo-cursor, .mo-cursor-dot { display: none; }
  html.mo-cursor-on, html.mo-cursor-on a, html.mo-cursor-on button { cursor: auto; }
}

/* ---------- 6. Reveal primitives ---------- */
/* Headings are split into lines, each line clipped by its own mask so the
   type rises out of the page rather than fading in place. */
/* The mask clips at the line box, so a little breathing room is added back to
   stop descenders (g, y, p) being sheared off. */
.mo-line {
  display: block;
  overflow: hidden;
  padding-bottom: .14em;
  margin-bottom: -.14em;
}
/* No will-change here on purpose. There are dozens of split headings on the
   page, and promoting every line to its own compositor layer for the whole
   session costs far more than the one transition each one plays. */
.mo-line > span { display: block; }

.mo-char { display: inline-block; }

/* Elements the JS layer will animate start hidden, but only once JS has
   confirmed it is running: no-JS visitors never see a blank page. */
html.mo-ready [data-mo-fade]:not(.mo-in) { opacity: 0; }
html.mo-ready [data-mo-rise]:not(.mo-in) { opacity: 0; transform: translate3d(0, 34px, 0); }

/* Media reveals wipe open from the bottom edge. */
.mo-clip { overflow: hidden; }
html.mo-ready .mo-clip > img,
html.mo-ready .mo-clip > picture > img { will-change: transform; }

/* Section headings get an accent rule that draws itself. */
.mo-rule {
  display: block;
  height: 2px;
  width: 100%;
  max-width: 190px;
  margin-bottom: 18px;
  background: var(--mo-accent);
  transform: scaleX(0);
  transform-origin: 0 50%;
}

/* ---------- 6b. Hero ---------- */
/* The headline is split into characters that rotate up out of the baseline,
   so the mask has to allow 3D and the overflow has to stay open vertically. */
.mcpa-story-v2 .hero h1 { perspective: 900px; }
.mcpa-story-v2 .hero h1 > .w { will-change: transform; }

.mcpa-story-v2 .hero-cue {
  position: absolute;
  z-index: 3;
  left: 50%;
  bottom: clamp(14px, 2.6vh, 30px);
  transform: translateX(-50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  text-decoration: none;
  color: var(--mo-light);
  font-family: 'IBM Plex Mono', monospace;
  font-size: 10px;
  letter-spacing: .34em;
  text-transform: uppercase;
  text-shadow: 0 1px 10px rgb(4 11 7 / .9);
}
.mcpa-story-v2 .hero-cue-rail {
  display: block;
  width: 1px;
  height: 52px;
  background: rgb(230 235 224 / .3);
  overflow: hidden;
}
.mcpa-story-v2 .hero-cue-rail i {
  display: block;
  width: 100%;
  height: 100%;
  background: var(--mo-accent);
  transform: scaleY(0);
  transform-origin: 50% 0;
}
.mcpa-story-v2 .hero-cue:hover .hero-cue-text { color: #fff; }

@media (max-width: 900px) { .mcpa-story-v2 .hero-cue { display: none; } }

/* ---------- 6b2. Hand the problem route to GSAP ----------
   The legacy keyframes set `transform: scale()` on the marker groups, and a
   CSS transform replaces the SVG transform attribute outright, so the markers
   collapsed onto the SVG origin. The motion layer draws and pulses them
   instead, so the keyframes are switched off here. */
html.mo-ready .narrative-overhaul .problem-chapter.is-active .route-line,
html.mo-ready .narrative-overhaul .problem-chapter.is-active .route-diversion,
html.mo-ready .narrative-overhaul .problem-chapter.is-active .route-marker {
  animation: none;
}
html.mo-ready .narrative-overhaul .route-line,
html.mo-ready .narrative-overhaul .route-diversion { stroke-dashoffset: 0; }
html.mo-ready .route-marker { transform-box: view-box; }

/* ---------- 6c. Timeline rail ---------- */
.mcpa-story-v2 .timeline { position: relative; }
/* Sits exactly on top of the timeline's own hairline (field-atlas.css sets it
   at left: 23px) so the progress reads as that line filling in, not as a
   second rail beside it. */
.mo-timeline-rail {
  position: absolute;
  left: 23px;
  top: 42px;
  bottom: 24px;
  width: 2px;
  overflow: hidden;
  pointer-events: none;
}
.mo-timeline-rail i {
  display: block;
  width: 100%;
  height: 100%;
  background: linear-gradient(180deg, var(--mo-accent), var(--mo-accent-warm));
  transform: scaleY(0);
  transform-origin: 50% 0;
}

/* ---------- 6d. EORE as a pinned horizontal track ----------
   Applied by JS only on wide viewports, and removed again on resize, so the
   stacked layout in the base stylesheets stays the source of truth for
   narrow screens, print and no-JS. */
/* The whole section becomes one pinned screen: heading, track and progress
   all stay in view while the four phases travel past. */
.mcpa-story-v2 .eore.mo-eore-h {
  display: flex;
  flex-direction: column;
  justify-content: center;
  height: 100vh;
  padding-block: clamp(104px, 12vh, 132px) clamp(24px, 3vh, 42px);
}
/* The heading and progress bar take what they need; the track absorbs
   whatever is left, so the pinned screen always fits exactly once. */
.mcpa-story-v2 .eore.mo-eore-h .eore-head,
.mcpa-story-v2 .eore.mo-eore-h .eore-progress { flex: 0 0 auto; }
.mcpa-story-v2 .eore.mo-eore-h .eore-track-wrap { flex: 1 1 auto; min-height: 0; }
.mcpa-story-v2 .eore.mo-eore-h .eore-head {
  width: min(100% - clamp(40px, 8vw, 144px), 1440px);
  margin-inline: auto;
  margin-bottom: clamp(16px, 2.2vh, 30px);
}
.mcpa-story-v2 .eore.mo-eore-h .eore-head h2 { font-size: clamp(1.7rem, 2.5vw, 2.6rem); }
.mcpa-story-v2 .eore.mo-eore-h .eore-head .sec-head > p { font-size: .96rem; line-height: 1.5; }
.mcpa-story-v2 .eore.mo-eore-h .mo-eore-hint { letter-spacing: .2em; white-space: nowrap; }
/* Two columns keep the opener short enough that the heading, the track and
   the progress bar all fit one pinned screen. */
.mcpa-story-v2 .eore.mo-eore-h .eore-head .sec-head {
  position: static;
  max-width: none;
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr);
  column-gap: clamp(28px, 5vw, 80px);
  row-gap: 12px;
  align-items: end;
  margin-bottom: 0;
}
.mcpa-story-v2 .eore.mo-eore-h .eore-head .sec-head > .mo-rule,
.mcpa-story-v2 .eore.mo-eore-h .eore-head .sec-head > .eyebrow { grid-column: 1 / -1; }
.mcpa-story-v2 .eore.mo-eore-h .eore-head .sec-head > h2 { grid-column: 1; margin-top: 14px; }
.mcpa-story-v2 .eore.mo-eore-h .eore-head .sec-head > p,
.mcpa-story-v2 .eore.mo-eore-h .eore-head .sec-head > .mo-eore-hint { grid-column: 2; }

.mcpa-story-v2 .eore.mo-eore-h .eore-track-wrap {
  width: 100%;
  margin: 0;
  overflow: hidden;
}
.mcpa-story-v2 .eore.mo-eore-h .eore-track {
  display: flex;
  align-items: stretch;
  height: 100%;
  gap: clamp(20px, 2.4vw, 38px);
  width: max-content;
  max-width: none;
  padding: 4px max(clamp(20px, 4.5vw, 72px), calc((100vw - 1440px) / 2));
  overflow: visible;
}
.mcpa-story-v2 .eore.mo-eore-h .eore-panel {
  flex: 0 0 auto;
  display: flex;
  flex-direction: column;
  width: clamp(460px, 41vw, 620px);
  min-height: 0;
  padding: 30px 32px 34px;
  border-left: 0;
  border-top: 3px solid var(--mo-accent);
  border-radius: var(--radius-panel);
}
.mcpa-story-v2 .eore.mo-eore-h .eore-panel::before { display: none; }
/* The diagram is the flexible part of a panel: it gives up height first so
   the whole pinned screen keeps fitting. */
.mcpa-story-v2 .eore.mo-eore-h .eore-fig {
  flex: 1 1 auto;
  max-width: none;
  min-height: 0;
  overflow: hidden;
}
.mcpa-story-v2 .eore.mo-eore-h .eore-fig svg { width: 100%; height: 100%; }
/* On a short screen there is no room for a legible diagram, and a squashed
   sliver of one reads as a rendering fault. The text carries the phase. */
@media (max-height: 820px) {
  .mcpa-story-v2 .eore.mo-eore-h .eore-fig { display: none; }
}
.mcpa-story-v2 .eore.mo-eore-h .eore-panel h3 { font-size: clamp(1.25rem, 1.6vw, 1.7rem); }
.mcpa-story-v2 .eore.mo-eore-h .eore-panel p { font-size: .94rem; }

.mcpa-story-v2 .eore.mo-eore-h .eore-progress {
  width: min(100% - clamp(40px, 8vw, 144px), 1440px);
  margin: clamp(20px, 2.6vh, 38px) auto 0;
  height: 2px;
  background: rgb(230 235 224 / .2);
}

/* A hint that this section moves sideways. */
/* Only meaningful while the track actually runs sideways. */
.mo-eore-hint { display: none; }
.mo-eore-h .mo-eore-hint {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 14px;
  color: var(--mo-light);
  font-family: 'IBM Plex Mono', monospace;
  font-size: 10px;
  letter-spacing: .28em;
  text-transform: uppercase;
  opacity: .72;
}
.mo-eore-hint i {
  display: block;
  width: 34px;
  height: 1px;
  background: var(--mo-accent);
  transform-origin: 0 50%;
}

/* ---------- 7. Parallax, tilt and spotlight surfaces ---------- */
[data-mo-parallax] { will-change: transform; }

.mo-tilt {
  transform-style: preserve-3d;
  transition: box-shadow var(--mo-dur-md) var(--mo-ease);
}
.mo-tilt > * { transform: translateZ(0); }

/* A cursor-tracked highlight for card grids. */
.mo-spot { position: relative; isolation: isolate; overflow: hidden; }
.mo-spot::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 3;
  pointer-events: none;
  opacity: 0;
  transition: opacity var(--mo-dur-md) var(--mo-ease);
  background: radial-gradient(
    340px circle at var(--mo-x, 50%) var(--mo-y, 50%),
    rgb(200 137 79 / .22),
    transparent 62%
  );
}
.mo-spot:hover::after,
.mo-spot:focus-within::after { opacity: 1; }

/* Cards lift as a unit rather than nudging their contents. */
.mo-lift { transition: transform var(--mo-dur-md) var(--mo-ease), box-shadow var(--mo-dur-md) var(--mo-ease); }
.mo-lift:hover,
.mo-lift:focus-within { transform: translate3d(0, -6px, 0); }

/* ---------- 8. Micro-interactions ---------- */
/* Nav and footer links get a sweeping underline instead of a colour flip. */
.mcpa-story-v2 .nav-links a,
.mcpa-story-v2 .site-footer ul a { position: relative; }
.mcpa-story-v2 .nav-links a::after,
.mcpa-story-v2 .site-footer ul a::after {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  bottom: -4px;
  height: 1.5px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: 100% 50%;
  transition: transform var(--mo-dur-sm) var(--mo-ease);
}
.mcpa-story-v2 .nav-links a:hover::after,
.mcpa-story-v2 .nav-links a:focus-visible::after,
.mcpa-story-v2 .nav-links a[aria-current='true']::after,
.mcpa-story-v2 .site-footer ul a:hover::after,
.mcpa-story-v2 .site-footer ul a:focus-visible::after {
  transform: scaleX(1);
  transform-origin: 0 50%;
}

/* Buttons: a wash that sweeps through on hover. */
.mcpa-story-v2 .btn {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  transition: transform var(--mo-dur-sm) var(--mo-ease), color var(--mo-dur-sm) var(--mo-ease);
}
.mcpa-story-v2 .btn::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background: currentColor;
  opacity: .12;
  transform: translate3d(-101%, 0, 0);
  transition: transform var(--mo-dur-md) var(--mo-ease);
}
.mcpa-story-v2 .btn:hover::before,
.mcpa-story-v2 .btn:focus-visible::before { transform: translate3d(0, 0, 0); }

/* Magnetic elements are moved by JS; the reset is eased in CSS. */
.mo-magnet { transition: transform var(--mo-dur-md) var(--mo-ease-spring); }
.mo-magnet.is-pulling { transition: none; }

/* Form fields react as you type. */
.mcpa-story-v2 .field input,
.mcpa-story-v2 .field textarea {
  transition: border-color var(--mo-dur-sm) var(--mo-ease),
              box-shadow var(--mo-dur-sm) var(--mo-ease),
              transform var(--mo-dur-sm) var(--mo-ease);
}
.mcpa-story-v2 .field input:focus,
.mcpa-story-v2 .field textarea:focus {
  box-shadow: 0 6px 22px rgb(13 23 16 / .16);
  transform: translate3d(0, -2px, 0);
}

/* Back-to-top button gets a progress ring. */
.mcpa-story-v2 .to-top {
  transition: transform var(--mo-dur-md) var(--mo-ease-spring), opacity var(--mo-dur-md) var(--mo-ease);
}
.mcpa-story-v2 .to-top:hover { transform: translate3d(0, -4px, 0) scale(1.06); }

/* ---------- 9. Reduced motion ---------- */
@media (prefers-reduced-motion: reduce) {
  .mo-curtain,
  .mo-cursor,
  .mo-cursor-dot { display: none !important; }
  html.mo-ready [data-mo-fade],
  html.mo-ready [data-mo-rise] { opacity: 1 !important; transform: none !important; }
  .mo-rule { transform: scaleX(1); }
  .mo-line > span { transform: none !important; }
  .mo-lift:hover { transform: none; }
  .mcpa-story-v2 .btn::before { display: none; }
}
