/* Hallmark · redesign: in-system · macrostructure: Long Document / stream-led ·
   theme: brand-locked (paper #f9f9f9 · river greens · Caslon + Plex Mono) ·
   tone: calm, evidentiary, institutional */
/* ============================================================
   Taigris — site stylesheet
   Palette: #264640 (dark grey turquoise) / #f9f9f9 (light grey)
            #000101 (dark cyan, near-black ink)
   Type:    Libre Caslon Text (brand serif) / IBM Plex Mono (highlight)
   ============================================================ */

:root {
  --green: #264640;
  --green-deep: #1a332e;
  --green-soft: #35594f;
  --paper: #f9f9f9;
  --ink: #000101;
  --white: #ffffff;

  --serif: "Libre Caslon Text", Georgia, "Times New Roman", serif;
  --mono: "IBM Plex Mono", ui-monospace, "SF Mono", Menlo, monospace;

  --header-h: 72px;
  --radius: 8px;

  --shadow-header: 0 6px 24px rgba(0, 1, 1, 0.16), 0 1px 0 rgba(0, 1, 1, 0.08);
  --shadow-btn: 0 2px 10px rgba(38, 70, 64, 0.28);
  --shadow-btn-hover: 0 6px 22px rgba(38, 70, 64, 0.38);

  /* Animation timeline (single source of truth) */
  --t-banner: 0.25s;    /* stage 1: city + both arms fade in          */
  --d-banner: 0.9s;
  --t-stem: 1.35s;      /* stage 2: third stream flows down           */
  --d-stem: 1.2s;
  --t-header: 2.7s;     /* stage 3: header fades in                   */
  --t-text: 3.2s;       /* stage 4: substantive lines, staggered      */
  --t-text-step: 0.4s;
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--serif);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

img { display: block; }

a { color: inherit; }

:focus-visible {
  outline: 2px solid var(--green);
  outline-offset: 3px;
  border-radius: 2px;
}

/* ---------------- Header ---------------- */

.site-header {
  position: fixed;
  inset: 0 0 auto 0;
  height: var(--header-h);
  z-index: 40;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 clamp(16px, 4vw, 48px);
  background: linear-gradient(180deg, var(--green) 0%, #223f39 100%);
  box-shadow: var(--shadow-header);
}

.site-header .wordmark {
  display: inline-flex;
  align-items: center;
  text-decoration: none;
}

.site-header .wordmark img {
  height: calc(var(--header-h) - 4px);
  max-height: 100%;
  width: auto;
}

/* ---------------- Buttons ---------------- */

.btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5em;
  font-family: var(--mono);
  font-size: 0.82rem;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  text-decoration: none;
  border: none;
  border-radius: var(--radius);
  padding: 0.8em 1.6em;
  cursor: pointer;
  overflow: hidden;
  isolation: isolate;
  transition: transform 0.35s cubic-bezier(0.22, 1, 0.36, 1),
              box-shadow 0.35s ease,
              color 0.35s ease;
}

/* gradated hover layer */
.btn::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  opacity: 0;
  transition: opacity 0.4s ease;
}

.btn:hover { transform: translateY(-1px); }
.btn:hover::before { opacity: 1; }
.btn:active { transform: translateY(0); }

.btn-primary {
  color: var(--paper);
  background: linear-gradient(135deg, var(--green) 0%, var(--green-deep) 100%);
  box-shadow: var(--shadow-btn);
}
.btn-primary::before {
  background: linear-gradient(135deg, var(--green-soft) 0%, var(--green) 100%);
}
.btn-primary:hover { box-shadow: var(--shadow-btn-hover); }

.btn-light {
  color: var(--green);
  background: linear-gradient(135deg, var(--paper) 0%, #e8ecea 100%);
  box-shadow: 0 2px 10px rgba(0, 1, 1, 0.25);
}
.btn-light::before {
  background: linear-gradient(135deg, var(--white) 0%, var(--paper) 100%);
}
.btn-light:hover { box-shadow: 0 6px 20px rgba(0, 1, 1, 0.35); }

.btn-link {
  background: none;
  border: none;
  padding: 0;
  font-family: var(--mono);
  font-size: 0.82rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--paper);
  text-decoration: none;
  cursor: pointer;
  position: relative;
}
.btn-link::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: -4px;
  width: 100%;
  height: 1px;
  background: var(--paper);
  opacity: 0;
  transform: scaleX(0.4);
  transform-origin: left;
  transition: opacity 0.35s ease, transform 0.35s ease;
}
.btn-link:hover::after { opacity: 0.9; transform: scaleX(1); }

/* ---------------- Hero / banner ---------------- */

.hero {
  position: relative;
  padding-top: var(--header-h);
  background: var(--paper);
}

.banner {
  position: relative;
  aspect-ratio: 16 / 9;
  width: min(100%, calc((100svh - var(--header-h)) * 16 / 9));
  margin-left: auto; /* river hugs the right; text owns the left */
  overflow: hidden;
}

.banner img.composite {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  z-index: 1;
  opacity: 0; /* fades in as stage 1 */
}

/* animation cover — same tone as the banner ground (#f9f9f9).
   It hides the third stream while the city + both arms fade in,
   then wipes downward. Geometry calibrated against the composite:
   the arms merge and the stem begins at y ≈ 40%. */
.cover {
  position: absolute;
  background: var(--paper);
  z-index: 2;
}
.cover-stem { /* the third stream */
  top: 40%;
  left: -1%;
  width: 102%;
  height: 62%;
}

/* ---------------- Hero copy ---------------- */

.hero-copy {
  position: absolute;
  z-index: 5;
  top: 50%;
  transform: translateY(-50%);
  left: clamp(20px, 5vw, 72px);
  max-width: min(46ch, 42%);
}

.hero-copy h1 {
  font-family: var(--serif);
  font-weight: 700;
  font-size: clamp(1.7rem, 3.4vw, 3rem);
  line-height: 1.18;
  margin: 0 0 0.55em;
  color: var(--ink);
}

.hero-copy .sub {
  font-size: clamp(1rem, 1.45vw, 1.2rem);
  line-height: 1.6;
  margin: 0 0 1.6em;
  color: var(--green);
}

.hero-copy .sub .hl {
  font-family: var(--mono);
  font-size: 0.92em;
  color: var(--ink);
  background: linear-gradient(180deg, transparent 62%, rgba(38, 70, 64, 0.16) 62%);
  padding: 0 0.1em;
}

.hero-copy .alpha-tag {
  display: block;
  margin-top: 1.4em;
  font-family: var(--mono);
  font-size: 0.74rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--green-soft);
}

/* ---------------- Animation orchestration ----------------
   Nothing moves until JS confirms the banner has decoded
   (html.ready). No-JS and reduced-motion fall back to the
   finished frame. */

.site-header,
[data-line] {
  opacity: 0;
}

html.ready .banner img.composite {
  animation: fade-in var(--d-banner) ease var(--t-banner) both;
}
html.ready .cover-stem {
  animation: wipe-stem var(--d-stem) cubic-bezier(0.55, 0, 0.25, 1) var(--t-stem) both;
}
html.ready .site-header {
  animation: fade-down 0.7s ease var(--t-header) both;
}
html.ready [data-line="1"] { animation: fade-up 0.8s ease var(--t-text) both; }
html.ready [data-line="2"] { animation: fade-up 0.8s ease calc(var(--t-text) + var(--t-text-step)) both; }
html.ready [data-line="3"] { animation: fade-up 0.8s ease calc(var(--t-text) + var(--t-text-step) * 2) both; }
html.ready [data-line="4"] { animation: fade-up 0.8s ease calc(var(--t-text) + var(--t-text-step) * 3) both; }

/* The third stream flows downward from the confluence */
@keyframes wipe-stem {
  from { clip-path: inset(0 0 0 0); }
  to   { clip-path: inset(100% 0 0 0); }
}
@keyframes fade-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}
@keyframes fade-down {
  from { opacity: 0; transform: translateY(-10px); }
  to   { opacity: 1; transform: translateY(0); }
}
@keyframes fade-up {
  from { opacity: 0; transform: translateY(14px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* Reduced motion: land on the finished frame instantly */
@media (prefers-reduced-motion: reduce) {
  html.ready .cover,
  .cover { display: none; }
  .banner img.composite { opacity: 1 !important; animation: none !important; }
  .site-header,
  [data-line] { opacity: 1 !important; animation: none !important; }
}

/* ---------------- Modal ---------------- */

.modal-backdrop {
  position: fixed;
  inset: 0;
  z-index: 90;
  background: rgba(0, 1, 1, 0.5);
  backdrop-filter: blur(3px);
  display: none;
  align-items: center;
  justify-content: center;
  padding: 20px;
  opacity: 0;
  transition: opacity 0.3s ease;
}
.modal-backdrop.open { display: flex; }
.modal-backdrop.visible { opacity: 1; }

.modal {
  width: min(560px, 100%);
  max-height: min(88svh, 760px);
  overflow-y: auto;
  background: var(--paper);
  border-radius: 12px;
  box-shadow: 0 24px 80px rgba(0, 1, 1, 0.35);
  padding: clamp(24px, 4vw, 40px);
  transform: translateY(12px);
  transition: transform 0.35s cubic-bezier(0.22, 1, 0.36, 1);
}
.modal-backdrop.visible .modal { transform: translateY(0); }

.modal-head {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 16px;
  margin-bottom: 8px;
}

.modal h2 {
  font-family: var(--serif);
  font-size: 1.35rem;
  margin: 0;
  color: var(--ink);
}

.modal .lede {
  font-size: 0.95rem;
  line-height: 1.6;
  color: var(--green);
  margin: 10px 0 22px;
}

.modal-close {
  background: none;
  border: none;
  cursor: pointer;
  font-size: 1.5rem;
  line-height: 1;
  color: var(--green);
  padding: 4px 8px;
  border-radius: 6px;
  transition: background 0.3s ease;
}
.modal-close:hover { background: rgba(38, 70, 64, 0.08); }

.field-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px 16px;
}
.field-grid .full { grid-column: 1 / -1; }

.field label {
  display: block;
  font-family: var(--mono);
  font-size: 0.68rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--green);
  margin-bottom: 6px;
}

.field input,
.field select {
  width: 100%;
  font-family: var(--serif);
  font-size: 0.95rem;
  color: var(--ink);
  background: var(--white);
  border: 1px solid rgba(38, 70, 64, 0.35);
  border-radius: 6px;
  padding: 0.65em 0.8em;
  transition: border-color 0.3s ease, box-shadow 0.3s ease;
}
.field input:focus,
.field select:focus {
  outline: none;
  border-color: var(--green);
  box-shadow: 0 0 0 3px rgba(38, 70, 64, 0.14);
}

.modal .actions {
  margin-top: 24px;
  display: flex;
  align-items: center;
  gap: 16px;
}

.form-note {
  font-family: var(--mono);
  font-size: 0.72rem;
  color: var(--green-soft);
}
.form-note.error { color: #8c2f2f; }
.form-success { text-align: center; padding: 28px 8px; }
.form-success h3 { font-family: var(--serif); font-size: 1.3rem; margin: 0 0 10px; }
.form-success p { color: var(--green); line-height: 1.6; }
[hidden] { display: none !important; }

/* ---------------- Footer ---------------- */

.site-footer {
  background: linear-gradient(180deg, var(--green) 0%, var(--green-deep) 100%);
  color: var(--paper);
  padding: clamp(28px, 4vw, 48px) clamp(16px, 4vw, 48px);
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: clamp(18px, 2.5vw, 28px);
}

.footer-top {
  display: flex;
  align-items: center;
  gap: clamp(20px, 3vw, 36px);
}

.site-footer .mark img { height: 56px; width: auto; }

.footer-meta { display: flex; flex-direction: column; gap: 12px; }

.footer-meta .legal {
  font-family: var(--mono);
  font-size: 0.72rem;
  letter-spacing: 0.06em;
  color: rgba(249, 249, 249, 0.78);
}

.footer-links { display: flex; gap: 28px; align-items: center; }

/* marketing disclaimer — quiet, site-wide */
.footer-disclaimer {
  margin: 0;
  max-width: 78ch;
  font-family: var(--serif);
  font-size: 0.78rem;
  line-height: 1.55;
  color: rgba(249, 249, 249, 0.62);
}

/* footnote markers in body copy */
.fn-ref {
  font-family: var(--mono);
  font-size: 0.62em;
  font-style: normal;
  font-weight: 500;
  letter-spacing: 0.04em;
  line-height: 0;
  vertical-align: super;
  margin-left: 0.12em;
}
.fn-ref a {
  color: inherit;
  text-decoration: none;
  border-bottom: none;
}
.fn-ref a:hover { opacity: 0.7; }
.pull .fn-ref { color: inherit; }
.stat-cap .fn-ref { color: inherit; }

/* source list: bibliographic text only — no visible URL strings */
.footer-sources {
  list-style: none;
  margin: 0;
  padding: 14px 0 0;
  border-top: 1px solid rgba(249, 249, 249, 0.14);
  display: grid;
  gap: 10px;
  max-width: 78ch;
}
.footer-sources li {
  font-family: var(--serif);
  font-size: 0.74rem;
  line-height: 1.55;
  color: rgba(249, 249, 249, 0.58);
}
.footer-sources .fn-mark {
  font-family: var(--mono);
  font-size: 0.68rem;
  letter-spacing: 0.08em;
  color: rgba(249, 249, 249, 0.78);
  margin-right: 0.45em;
}
.footer-sources .fn-back {
  font-family: var(--mono);
  font-size: 0.68rem;
  color: rgba(249, 249, 249, 0.5);
  text-decoration: none;
  margin-left: 0.4em;
}
.footer-sources .fn-back:hover { color: rgba(249, 249, 249, 0.85); }

/* ---------------- Privacy page ---------------- */

.legal-page {
  max-width: 760px;
  margin: 0 auto;
  padding: calc(var(--header-h) + 48px) 24px 80px;
}
.legal-page h1 { font-size: 2rem; margin-bottom: 0.3em; }
.legal-page .updated {
  font-family: var(--mono);
  font-size: 0.75rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--green-soft);
  margin-bottom: 2.2em;
}
.legal-page h2 {
  font-size: 1.25rem;
  margin-top: 2em;
  color: var(--green);
}
.legal-page p, .legal-page li { line-height: 1.75; font-size: 0.98rem; }
.legal-page a { color: var(--green); }

/* Privacy page header/footer are static (no load choreography) */
html.static-page .site-header { opacity: 1; }

/* ---------------- Mobile ---------------- */

@media (max-width: 820px) {
  :root { --header-h: 60px; }

  .site-header .wordmark img { height: 30px; }
  .site-header .btn { font-size: 0.7rem; padding: 0.7em 1.1em; }

  .banner {
    width: 100%;
    margin-left: 0;
  }

  /* copy leaves the overlay and stacks under the banner,
     keeping the identical line-by-line reveal */
  .hero-copy {
    position: static;
    transform: none;
    max-width: none;
    padding: 28px 20px 44px;
  }
  .hero-copy h1 { font-size: clamp(1.5rem, 6.4vw, 2rem); }

  .field-grid { grid-template-columns: 1fr; }

  .site-footer { align-items: stretch; }
  .footer-top { flex-direction: column; align-items: flex-start; }
}

/* ============================================================
   Extended page — the river carries the argument
   (confluence → 3 pillars → CTA). On desktop each section is a
   pinned scene: the scroll scrubs its transition forward and
   backward, and the page only releases once the scene resolves.
   The confluence floods with the river as scene one.
   ============================================================ */

:root {
  --ease-brand: cubic-bezier(0.22, 1, 0.36, 1);
  --band-pad: clamp(96px, 14vh, 200px);
  --measure: 62ch;
  --scroll-p: 0;
}

/* [placeholder] artwork slots — intentionally empty containers
   reserved for future art (left gutter, section edges). They
   take no space until artwork is dropped in. */
.art-slot { display: none; }

/* ---------------- Global editorial polish ---------------- */

::selection { background: var(--green); color: var(--paper); }

@media (prefers-reduced-motion: no-preference) {
  html { scroll-behavior: smooth; }
}

/* film grain — fixed, pointer-inert, under the modal layer.
   Gives the paper ground a physical, printed feel. */
body::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 80;
  pointer-events: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23n)' opacity='0.55'/%3E%3C/svg%3E");
  background-size: 180px 180px;
  opacity: 0.035;
  mix-blend-mode: multiply;
}

/* the current as page progress — hairline under the fixed header */
.scroll-progress {
  position: absolute;
  left: 0;
  bottom: 0;
  width: 100%;
  height: 2px;
  background: linear-gradient(90deg, rgba(249, 249, 249, 0.9), rgba(249, 249, 249, 0.5));
  transform: scaleX(var(--scroll-p));
  transform-origin: left;
  opacity: 0.85;
  pointer-events: none;
}

/* ---------------- Scroll cue ---------------- */
.scroll-cue {
  position: absolute;
  left: 50%;
  bottom: clamp(16px, 4vh, 40px);
  transform: translateX(-50%);
  z-index: 6;
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  text-decoration: none;
  font-family: var(--mono);
  font-size: 0.66rem;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--green-soft);
  opacity: 0;
}
html.ready .scroll-cue {
  animation: fade-in 0.8s ease calc(var(--t-text) + 1.6s) both;
}
.scroll-cue-arrow {
  font-size: 1rem;
  animation: cue-bob 2.4s ease-in-out infinite;
}
@keyframes cue-bob {
  0%, 100% { transform: translateY(0); opacity: 0.55; }
  50%      { transform: translateY(5px); opacity: 1; }
}

/* ---------------- Pinned scenes ----------------
   A .pin runner is taller than the viewport; its .pin-stage
   sticks under the header while the runner scrolls past. The
   distance travelled inside the runner is the scene's progress
   (set by JS as element classes + CSS vars) — so every
   transition plays forward on scroll-down and reverses on
   scroll-up, and the page only moves on once the scene ends.
   Active only on html.pins-on (wide viewport, motion allowed,
   JS present). Everywhere else .pin is an inert wrapper. */
.pin { position: relative; }

@media (min-width: 821px) {
  html.pins-on .pin {
    height: calc(100svh + var(--pin-extra, 140vh));
  }
  html.pins-on .pin-stage {
    position: sticky;
    top: var(--header-h);
    height: calc(100svh - var(--header-h));
    padding-top: 0;
    padding-bottom: 0;
    display: flex;
    align-items: center;
    overflow: hidden;
  }
  html.pins-on .pin-stage .band-inner { width: 100%; }
  html.pins-on .flood      { display: block; }
  html.pins-on .flood-edge { display: block; }
  html.pins-on .flood-copy { display: flex; }
  html.pins-on .trail      { display: block; }
}

/* tighter rhythm when the pinned stage meets a short screen */
@media (min-width: 821px) and (max-height: 820px) {
  html.pins-on .pin-stage .band-title { font-size: clamp(1.6rem, 3vw, 2.6rem); }
  html.pins-on .pin-stage .band-lede { margin-bottom: 1.6em; }
  html.pins-on .pin-stage .step { padding: 14px 0; }
  /* the resolve card keeps its horizontal padding — without this the
     compact .step rule strips it and the copy hits the card edges */
  html.pins-on .pin-stage .step-resolve { padding: 16px 22px; }
  html.pins-on .pin-stage .steps { margin-bottom: 1.8em; }
}

/* ---------------- The flood (confluence scene) ----------------
   The river from the banner pours into the section: a green
   layer clipped to the waterline, a wave strip riding the clip
   edge, and a paper-inked duplicate of the copy clipped to the
   same line — text inverts exactly where the water passes. */
.flood,
.flood-edge,
.flood-copy { display: none; }

.band-confluence { --flood: 0%; --flood-y: 0px; }

.flood {
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  background: var(--green);
  clip-path: inset(0 0 calc(100% - var(--flood)) 0);
}
.flood-edge {
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 26px;
  z-index: 2;
  pointer-events: none;
  transform: translateY(calc(var(--flood-y) - 1px));
  overflow: hidden;
}
.flood-edge .wave {
  display: block;
  width: 200%;
  height: 100%;
  fill: var(--green);
  animation: wave-drift 7s linear infinite;
}
@keyframes wave-drift {
  to { transform: translateX(-50%); }
}
.flood-copy {
  position: absolute;
  inset: 0;
  z-index: 3;
  pointer-events: none;
  align-items: center;
  padding: 0 clamp(20px, 5vw, 72px);   /* mirrors .band's horizontal padding */
  clip-path: inset(0 0 calc(100% - var(--flood)) 0);
}
.flood-copy .band-inner { width: 100%; }
.flood-copy .eyebrow { color: rgba(249, 249, 249, 0.72); }
.flood-copy .eyebrow::before { background: rgba(249, 249, 249, 0.55); }
.flood-copy .band-title { color: var(--paper); }
.flood-copy .band-body { color: rgba(249, 249, 249, 0.88); }

/* the datalake figure inverts under the waterline too */
.flood-copy .lake-tile {
  border-color: rgba(249, 249, 249, 0.55);
  background: radial-gradient(120% 120% at 50% 40%, rgba(249, 249, 249, 0.08), rgba(249, 249, 249, 0));
}
.flood-copy .lake-tile::before { border-color: rgba(249, 249, 249, 0.25); }
.flood-copy .lake-body { fill: rgba(249, 249, 249, 0.14); stroke: var(--paper); }
.flood-copy .lake-ping { stroke: rgba(249, 249, 249, 0.8); }
.flood-copy .feed-dotted,
.flood-copy .out-dotted,
.flood-copy .out-solid,
.flood-copy .feed-solid { stroke: var(--paper); }

/* ---------------- Confluence: datalake tile ----------------
   Copy sits left; a square rounded enclosure holds the lake on
   the right. A stream feeds in from the right edge and outputs
   to the left (both continuous). A second stream is revealed by
   scroll (--merge 0→1) and aligns into the left output. */
.conf-grid {
  display: grid;
  grid-template-columns: 1.1fr 0.9fr;
  gap: clamp(32px, 5vw, 72px);
  align-items: center;
}
.conf-figure {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
}
.band-confluence { --merge: 0; }

.lake-tile {
  position: relative;
  width: min(100%, 420px);
  aspect-ratio: 1 / 1;
  border: 1px solid rgba(38, 70, 64, 0.32);
  border-radius: clamp(18px, 3vw, 28px);
  background:
    radial-gradient(120% 120% at 50% 40%, rgba(38, 70, 64, 0.05), rgba(38, 70, 64, 0));
  overflow: hidden;
}
.lake-tile::before { /* faint inner enclosure line, echoes .room */
  content: "";
  position: absolute;
  inset: 7px;
  border: 1px solid rgba(38, 70, 64, 0.12);
  border-radius: clamp(12px, 2.4vw, 22px);
  pointer-events: none;
}
.lake-svg { width: 100%; height: 100%; display: block; }

.lake-body {
  fill: rgba(38, 70, 64, 0.1);
  stroke: var(--green);
  stroke-width: 1.4;
}
.lake-ping {
  fill: none;
  stroke: var(--green-soft);
  stroke-width: 1;
  opacity: 0;
  transform-origin: 100px 100px;
  animation: lake-ping 3.6s ease-out infinite;
}
.lake-ping-2 { animation-delay: 1.8s; }
@keyframes lake-ping {
  0%   { opacity: 0.5; transform: scale(0.35); }
  70%  { opacity: 0;   transform: scale(1.15); }
  100% { opacity: 0;   transform: scale(1.15); }
}

/* streams: a dotted current enters from the left; both currents
   leave through the bottom side by side; the solid right-hand
   current only appears once the flood begins — its drawn length
   scrubs with the water level (--fill 0→1) until it matches the
   bottom outflow's length. */
.feed-dotted,
.out-dotted {
  fill: none;
  stroke: var(--green);
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-dasharray: 0.1 7;
  animation: current-flow 1.1s linear infinite;
  opacity: 0.85;
}
.out-solid {
  fill: none;
  stroke: var(--green);
  stroke-width: 1.6;
  stroke-linecap: round;
  /* only fades in once the right-hand stream has fully entered the
     square (--fill completes at 1) */
  opacity: clamp(0, calc((var(--fill, 0) - 0.95) * 12), 0.6);
}
.feed-solid {
  fill: none;
  stroke: var(--green);
  stroke-width: 1.6;
  stroke-linecap: round;
  /* a MOVING current, like section 2's streams: near-continuous
     dashes racing toward the lake. Its reach is scroll-scrubbed —
     revealed from the right edge as the water rises (--fill 0→1). */
  stroke-dasharray: 14 4;
  animation: feed-flow 0.55s linear infinite;    /* fast current */
  opacity: min(1, calc(var(--fill, 0) * 18));
  clip-path: inset(-4px 0 -4px calc((1 - var(--fill, 0)) * 100%));
}
@keyframes feed-flow {
  to { stroke-dashoffset: -18; }
}
@keyframes current-flow {
  to { stroke-dashoffset: -14.2; }
}
.band-confluence { --fill: 0; }

/* one-shot fallback (mobile / reduced motion / no-JS): end state */
html:not(.pins-on) .feed-solid { clip-path: none; opacity: 1; }
html:not(.pins-on) .out-solid { opacity: 0.6; }
html:not(.pins-on) .of-solid { opacity: 0.7; }

/* ---------------- The outfall: streams leave the box ----------------
   Both bottom streams continue out of the tile through an opening
   in the square's border and travel on toward the page edge —
   seamless continuations of the tile's own outflows (same lanes,
   matched widths and dot rhythm, overlapping the border zone). The
   solid line respects the entry rule above: it only fades in once
   the right-hand stream has fully entered the square. */
.tile-gap {
  position: absolute;
  bottom: -2px;
  left: 50%;
  transform: translateX(-50%);
  width: 15%;                  /* the opening spans both lanes */
  height: 5px;
  background: var(--paper);
  pointer-events: none;
}
.outfall {
  position: absolute;
  top: calc(100% - 2px);       /* overlaps the border zone — seamless */
  left: 50%;
  transform: translateX(-50%);
  width: min(100%, 420px);
  height: 70vh;                /* clipped by the pinned stage */
  pointer-events: none;
}
.of-dotted,
.of-solid {
  position: absolute;
  top: 0;
  bottom: 0;
}
.of-dotted {
  left: 47%;                   /* the tile's dotted lane (94/200) */
  width: 3.5px;
  margin-left: -1.75px;
  background-image: radial-gradient(circle closest-side, rgba(38, 70, 64, 0.8) 78%, transparent 100%);
  background-size: 100% 15px;  /* ≈ the tile's rendered dot rhythm */
  background-repeat: repeat-y;
  --dot-cycle: 15px;
  animation: dots-run 1.8s linear infinite;
}
.of-solid {
  left: 53%;                   /* the tile's solid lane (106/200) */
  width: 3px;
  margin-left: -1.5px;
  background: rgba(38, 70, 64, 0.65);
  opacity: clamp(0, calc((var(--fill, 0) - 0.95) * 14), 0.7);
}
.flood-copy .tile-gap { background: var(--green); }
.flood-copy .of-dotted {
  background-image: radial-gradient(circle closest-side, rgba(249, 249, 249, 0.9) 78%, transparent 100%);
}
.flood-copy .of-solid { background: rgba(249, 249, 249, 0.85); }

/* ---------------- Safety: parallel twin currents ----------------
   PARALLEL FLOW — the two currents never meet. The dotted current
   (left) descends slowly, growing slightly as it travels, and never
   reaches the bottom edge (capped at 78%). The solid current
   (right) descends fast and hits the bottom edge early. Everything
   is CSS-gradient/vector drawn — crisp at any size; growth is done
   with widths, never by scaling a raster. */
.band-safety { --trailL: 0; --trailR: 0; --zoom: 0; }
.trail {
  position: absolute;
  top: 0;
  bottom: 0;
  right: clamp(120px, 22vw, 330px);
  width: clamp(110px, 12vw, 170px);
  z-index: 0;
  pointer-events: none;
  display: none;
}
.t-line { position: absolute; top: 0; bottom: 0; }
/* the zoom: both currents enter at the tile outflows' rendered
   sizes (≈4px dots · 2px solid) AND their separation (25px — the
   12/200-unit gap of a ~420px tile), so the hand-off from the
   section above reads seamless; then they scale up and spread to
   their working lanes together (--zoom 0→1, complete by beat 01)
   before the substantive beats begin. */
.t-dotted {
  /* entry lanes sit 25px apart — the same separation as the tile's
     two outflows above (12/200 units of a ~420px tile) — then the
     zoom spreads them to their working lanes */
  left: calc(50% - 12.5px + (12.5px - 28%) * var(--zoom, 0));
  width: calc(4px + var(--zoom, 0) * 3px);
  margin-left: calc(-2px - var(--zoom, 0) * 1.5px);
  background-image: radial-gradient(circle closest-side, rgba(38, 70, 64, 0.8) 78%, transparent 100%);
  background-size: 100% calc(13px + var(--zoom, 0) * 7px);
  background-repeat: repeat-y;
  --dot-cycle: calc(13px + var(--zoom, 0) * 7px);  /* loop matches rhythm */
  clip-path: inset(0 0 calc(100% - var(--trailL, 0) * 100%) 0);
  animation: dots-run 1.8s linear infinite;        /* slow current */
}
/* the restraint lands — the corrupted current is halted */
.band-safety.halted .t-dotted { animation-play-state: paused; }
.t-solid {
  right: calc(50% - 12.5px + (12.5px - 28%) * var(--zoom, 0));
  width: calc(2px + var(--zoom, 0) * 2.4px);
  margin-right: calc(-1px - var(--zoom, 0) * 1.2px);
  background: linear-gradient(180deg, rgba(38, 70, 64, 0.55), rgba(38, 70, 64, 0.78));
  clip-path: inset(0 0 calc(100% - var(--trailR, 0) * 100%) 0);
}
@keyframes dots-run {
  to { background-position: 0 var(--dot-cycle, 13px); }
}

/* corrupted elements: two of the dotted current's own dots break
   rhythm — a rotated ink square with a low-frequency jitter. They
   appear in sequence after beat 01 and never leave the page. */
.t-mark {
  position: absolute;
  left: 22%;
  top: var(--my, 40%);
  width: 10px;
  height: 10px;
  margin: -5px 0 0 -5px;
  border: 1.5px solid var(--ink);
  background: var(--paper);
  transform: rotate(45deg);
  opacity: 0;
  transition: opacity 0.35s var(--ease-brand);
}
.t-mark.corrupt {
  opacity: 1;
  animation: mark-jitter 0.22s steps(2, end) infinite;
}
@keyframes mark-jitter {
  0%   { transform: translate(0.5px, -1.2px) rotate(37deg); }
  50%  { transform: translate(-1.5px, 1px) rotate(53deg); }
  100% { transform: translate(1.2px, 0.6px) rotate(42deg); }
}
/* restrained: the reach-across lands and the element is held in
   stasis — a high-frequency micro-glitch, frozen in place, green. */
.t-mark.restrained {
  border-color: var(--green);
  background: rgba(38, 70, 64, 0.16);
  animation: mark-stasis 0.09s steps(2, end) infinite;
}
@keyframes mark-stasis {
  0%   { transform: translate(0.4px, 0) rotate(45deg); opacity: 1; }
  100% { transform: translate(-0.4px, 0) rotate(45deg); opacity: 0.72; }
}
/* the restraining streams: reach from the solid current across to
   each corrupted element — never a merge of the two currents, a
   grip. Drawn right → left at beat 03. */
.t-link {
  position: absolute;
  right: 22%;
  left: calc(22% + 6px);
  top: var(--my, 40%);
  height: 1.6px;
  margin-top: -0.8px;
  background: var(--green);
  opacity: 0.7;
  transform: scaleX(0);
  transform-origin: right center;
  transition: transform 0.6s var(--ease-brand);
}
.t-link.on { transform: scaleX(1); }

/* ---------------- Bands (shared) ---------------- */
.band {
  position: relative;
  z-index: 1;
  padding: var(--band-pad) clamp(20px, 5vw, 72px);
  background: var(--paper);
}
.band + .band { border-top: 1px solid rgba(38, 70, 64, 0.07); }

.band-inner {
  position: relative;
  max-width: 1080px;
  margin: 0 auto;
}

.eyebrow {
  display: flex;
  align-items: center;
  gap: 12px;
  font-family: var(--mono);
  font-size: 0.72rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--green-soft);
  margin: 0 0 1.2em;
}
.eyebrow::before {
  content: "";
  width: 26px;
  height: 1px;
  background: var(--green-soft);
  opacity: 0.6;
}

.band-title {
  font-family: var(--serif);
  font-weight: 700;
  font-size: clamp(1.8rem, 3.8vw, 3.3rem);
  line-height: 1.14;
  letter-spacing: -0.005em;
  color: var(--ink);
  margin: 0 0 0.7em;
  max-width: 24ch;
}

.band-body,
.band-lede {
  max-width: var(--measure);
  color: var(--green);
}
.band-body p,
.band-lede {
  font-size: clamp(1rem, 1.35vw, 1.18rem);
  line-height: 1.72;
  margin: 0 0 1.1em;
}
.band-lede { margin-bottom: 2.6em; }

/* ---------------- Pillar 1: ledger of beats ----------------
   The three beats flow downward like the current — a vertical
   ledger. The third beat is the confluence moment and resolves
   into the brand green. */
.steps {
  list-style: none;
  margin: 0 0 2.8em;
  padding: 0;
  max-width: 680px;
  display: flex;
  flex-direction: column;
}
.step {
  display: grid;
  grid-template-columns: 56px 1fr;
  gap: clamp(16px, 2.5vw, 28px);
  align-items: start;
  padding: clamp(20px, 3vh, 30px) 0;
  border-top: 1px solid rgba(38, 70, 64, 0.16);
}
.step-n {
  display: block;
  font-family: var(--mono);
  font-size: 0.74rem;
  letter-spacing: 0.2em;
  color: var(--green-soft);
  padding-top: 5px;
}
.step p {
  margin: 0;
  font-size: clamp(1.02rem, 1.3vw, 1.16rem);
  line-height: 1.6;
  color: var(--ink);
}
.step-resolve {
  margin-top: 14px;
  border-top: none;
  background: linear-gradient(135deg, var(--green) 0%, var(--green-deep) 100%);
  border-radius: var(--radius);
  padding: clamp(22px, 3vw, 30px) clamp(20px, 3vw, 30px);
  box-shadow: var(--shadow-btn);
}
.step-resolve .step-n { color: rgba(249, 249, 249, 0.72); }
.step-resolve p { color: var(--paper); }

.pull {
  max-width: var(--measure);
  font-family: var(--serif);
  font-style: italic;
  font-size: clamp(1.15rem, 1.7vw, 1.5rem);
  line-height: 1.5;
  color: var(--green);
  border-left: 2px solid var(--green);
  padding-left: clamp(16px, 2vw, 28px);
  margin: 0;
}

/* ---------------- Pillar 2: split + editorial stat ----------------
   One number, no dashboard: an oversized serif numeral, a
   hairline rule that draws in, and a mono caption. */
.band-split {
  display: grid;
  grid-template-columns: 1.35fr 1fr;
  gap: clamp(32px, 5vw, 80px);
  align-items: center;
}
.band-split .band-title { margin-bottom: 0.6em; max-width: none; }
.band-stat { display: block; }
.stat-num {
  display: block;
  font-family: var(--serif);
  font-weight: 700;
  font-size: clamp(4.2rem, 10vw, 7.5rem);
  line-height: 0.9;
  letter-spacing: -0.01em;
  color: var(--green);
  font-variant-numeric: tabular-nums;
}
.stat-rule {
  display: block;
  width: 64px;
  height: 2px;
  background: var(--green);
  opacity: 0.4;
  margin: 20px 0 16px;
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 1s var(--ease-brand) 0.5s;
}
.reveal.in .stat-rule,
.band-stat.on .stat-rule { transform: scaleX(1); }
.stat-cap {
  display: block;
  max-width: 30ch;
  font-family: var(--mono);
  font-size: 0.8rem;
  line-height: 1.65;
  letter-spacing: 0.02em;
  color: var(--green-soft);
}

/* ---------------- Pillar 3: the sealed room ----------------
   The copy sits inside a machined double-hairline enclosure —
   the dataroom, drawn. */
.room {
  position: relative;
  max-width: 780px;
  border: 1px solid rgba(38, 70, 64, 0.32);
  border-radius: var(--radius);
  padding: clamp(26px, 4vw, 48px);
  background: linear-gradient(160deg, rgba(38, 70, 64, 0.035), rgba(38, 70, 64, 0));
}
.room::before {
  content: "";
  position: absolute;
  inset: 6px;
  border: 1px solid rgba(38, 70, 64, 0.14);
  border-radius: calc(var(--radius) - 4px);
  pointer-events: none;
}
.room-tag {
  position: absolute;
  top: -0.62em;
  left: clamp(18px, 3vw, 34px);
  padding: 0 10px;
  background: var(--paper);
  font-family: var(--mono);
  font-size: 0.64rem;
  letter-spacing: 0.26em;
  text-transform: uppercase;
  color: var(--green-soft);
}
.room .band-body { max-width: none; }
.room .band-body p:last-child { margin-bottom: 0; }

/* room-full: the enclosure fills the section; cursor-arrow agents
   bounce inside and collide with the walls, unable to cross. The
   copy sits at the bottom-left; agents own the open space. */
.room-full {
  max-width: none;
  min-height: clamp(340px, 52vh, 520px);
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  /* no overflow:hidden here — it clipped the .room-tag riding the
     top border; the agents are contained by .agents instead */
}
.room-full .room-copy { position: relative; z-index: 2; max-width: 48ch; }

.agents {
  position: absolute;
  inset: 6px;                 /* stay inside the inner hairline */
  z-index: 1;
  pointer-events: none;
  overflow: hidden;
  border-radius: calc(var(--radius) - 4px);
}
.agent {
  position: absolute;
  top: 0;
  left: 0;
  width: clamp(20px, 2.4vw, 28px);
  height: clamp(20px, 2.4vw, 28px);
  /* JS drives translate via --ax/--ay (px) + rotate via --ar (deg) */
  transform: translate(var(--ax, 40px), var(--ay, 40px)) rotate(var(--ar, 0deg));
  color: var(--green-soft);
  opacity: 0;
  transition: opacity 0.5s ease;
  will-change: transform;
}
.room-full.live .agent { opacity: 0.9; }
.agent svg { width: 100%; height: 100%; display: block; fill: currentColor; }
/* the wall-hit pulse: JS toggles .hit briefly on collision */
.agent.hit { color: var(--green); }
.agent.hit svg { filter: drop-shadow(0 0 5px rgba(38, 70, 64, 0.5)); }

/* fallback (no JS / reduced motion): agents scattered, static */
.agent:nth-child(1) { transform: translate(12%, 22%) rotate(18deg); }
.agent:nth-child(2) { transform: translate(58%, 14%) rotate(-24deg); }
.agent:nth-child(3) { transform: translate(78%, 42%) rotate(40deg); }
.agent:nth-child(4) { transform: translate(30%, 58%) rotate(-12deg); }
.agent:nth-child(5) { transform: translate(66%, 66%) rotate(28deg); }
.room-full.live .agent:nth-child(n) { transform: translate(var(--ax, 40px), var(--ay, 40px)) rotate(var(--ar, 0deg)); }

/* ---------------- CTA band: the delta ----------------
   The current arrives at the reader — one stream fanning
   into a delta above the closing claim. */
.band-cta {
  background: linear-gradient(180deg, var(--green) 0%, var(--green-deep) 100%);
  text-align: center;
  overflow: hidden;
}
.band-cta::before {
  content: "";
  position: absolute;
  inset: -20% -10%;
  background: radial-gradient(ellipse at 50% 30%, rgba(249, 249, 249, 0.07), transparent 62%);
  pointer-events: none;
}
.band-cta .band-inner { padding-left: 0; }

.delta {
  display: block;
  width: 96px;
  height: 74px;
  margin: 0 auto clamp(20px, 3vh, 32px);
  overflow: visible;
}
.delta path {
  fill: none;
  stroke: rgba(249, 249, 249, 0.55);
  stroke-width: 1.3;
  stroke-linecap: round;
  stroke-dasharray: 1;
  stroke-dashoffset: 1;
}
.reveal.in .delta path {
  transition: stroke-dashoffset 1.5s var(--ease-brand);
  stroke-dashoffset: 0;
}
/* the two arms converge together, the merged stem follows */
.reveal.in .delta path:nth-child(3) { transition-delay: 0.45s; }

.cta-title { color: var(--paper); max-width: none; }
.cta-sub {
  max-width: 48ch;
  margin: 0 auto 2.2em;
  font-size: clamp(1rem, 1.4vw, 1.2rem);
  line-height: 1.7;
  color: rgba(249, 249, 249, 0.82);
}
.cta-tag {
  display: inline-block;
  margin-top: 1.8em;
  font-family: var(--mono);
  font-size: 0.72rem;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: rgba(249, 249, 249, 0.6);
}

/* ---------------- Scroll-reveal mechanics ----------------
   Two drivers share the same hidden state:
   · .reveal.in  — one-shot reveal (mobile, CTA, fallbacks)
   · .on         — pin-scrubbed beats; the class is added AND
                   removed by scroll, so every transition plays
                   in both directions. */
[data-reveal] {
  opacity: 0;
  transform: translateY(18px);
  filter: blur(5px);
  transition: opacity 0.7s var(--ease-brand),
              transform 0.7s var(--ease-brand),
              filter 0.7s var(--ease-brand);
}
.reveal.in [data-reveal],
[data-reveal].on { opacity: 1; transform: none; filter: none; }
/* stagger children within a one-shot revealed band */
.reveal.in [data-reveal]:nth-child(1) { transition-delay: 0s; }
.reveal.in [data-reveal]:nth-child(2) { transition-delay: 0.12s; }
.reveal.in [data-reveal]:nth-child(3) { transition-delay: 0.24s; }
.reveal.in [data-reveal]:nth-child(4) { transition-delay: 0.36s; }
.reveal.in [data-reveal]:nth-child(5) { transition-delay: 0.48s; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .scroll-cue,
  .scroll-cue-arrow { animation: none !important; opacity: 1 !important; }
  .scroll-progress { display: none; }
  .delta path { stroke-dashoffset: 0 !important; transition: none !important; }
  .lake-ping, .feed-dotted, .out-dotted,
  .feed-solid, .of-dotted, .t-dotted, .t-mark { animation: none !important; }
  .feed-solid { clip-path: none !important; opacity: 1 !important; }
  .trail { display: none !important; }
  .agent { animation: none !important; }
  .stat-rule { transform: none !important; transition: none !important; }
  [data-reveal] { opacity: 1 !important; transform: none !important;
                  filter: none !important; transition: none !important; }
  /* pinned scenes collapse to plain flow */
  .pin { height: auto !important; }
  .pin-stage { position: static !important; height: auto !important; }
  .flood,
  .flood-edge,
  .flood-copy { display: none !important; }
}

/* ---------------- Extended-page mobile ---------------- */
@media (max-width: 820px) {
  :root { --band-pad: clamp(72px, 12vh, 120px); }
  .band-inner { padding-left: 0; }
  .band-title { max-width: none; }
  .steps { max-width: none; }
  .step { grid-template-columns: 44px 1fr; }
  .band-split { grid-template-columns: 1fr; gap: 44px; }
  .stat-num { font-size: clamp(3.6rem, 18vw, 5rem); }
  .conf-grid { grid-template-columns: 1fr; gap: 40px; }
  .conf-figure { order: -1; }                 /* lake sits above the copy */
  .lake-tile { width: min(78vw, 340px); margin: 0 auto; }
  .room-full { min-height: clamp(300px, 62vh, 440px); }
  .room { padding: 24px 18px; }
  .room-tag { letter-spacing: 0.2em; }
  body::after { background-size: 140px 140px; }
}
