/* v1's hero story, lifted verbatim for v2.
 *
 * Oliver: "add the v one three d model, the exact same thing, copy and
 * paste it over into v two at the very top in the header."
 *
 * So this is styles.css lines 184-371 unchanged, in its own file rather
 * than pulled in wholesale - loading styles.css on v2 would restyle the
 * body, the nav and every heading and undo the page.
 *
 * It IS a scroll hijack: .story is 820vh with a sticky viewport inside.
 * That was flagged before building it; it is what was asked for.
 */

/* ----------------------------------------------------------- story */
/* The whole hero inherits the on-image role rather than the page one.
   Elements inside it that want a dimmer grey still say so explicitly;
   what this fixes is everything that inherited from body and therefore
   went near-black over the sky the moment the page went light. */
.story { height: 820vh; position: relative; color: var(--on-image); }
/* The nav is its own white surface now, so it is NOT on-image any more
   and its links go back to page ink. Only the hero text below it still
   sits directly on the photograph. */
.story .nav { color: var(--text); }
.story-sticky { position: sticky; top: 0; height: 100vh; overflow: hidden; }
.story #story-canvas { position: absolute; inset: 0; width: 100%; height: 100%; }

/* technical coordinates, always present, barely there */
.story #coords {
  position: absolute; z-index: 3; top: 5.2rem; left: 2.4rem;
  font-family: var(--mono); font-size: .66rem; letter-spacing: .08em;
  color: var(--dim-2); user-select: none;
}
.story #coords span { display: block; margin-top: .2rem; }

/* screen 1: the promise, centred over open sky */
.story .s1 {
  position: absolute; z-index: 3; inset: 0;
  display: grid; place-items: center; align-content: center;
  text-align: center;
  pointer-events: none; padding: 16vh 1.5rem 0;
}
.story .s1 h1 {
  font-size: clamp(2.8rem, 6.4vw, 5.4rem); font-weight: 600;
  line-height: 1.04; letter-spacing: -.025em; text-transform: uppercase;
  text-shadow: 0 2px 40px rgba(6, 20, 34, .45);
}
.story .s1 h1 span { display: block; }
/* The family has a Regular and a Bold and no medium, so 500 would round
   up to Bold and the ghost line would stop being a ghost. */
.story .s1 h1 .ghost { color: #c3d2dd; font-weight: 400; }
.story .s1 .sub {
  margin: 1.6rem auto 0; color: #dbe6ee; font-size: 1.05rem;
  max-width: 34rem; text-shadow: 0 1px 24px rgba(6, 20, 34, .5);
}
.story .s1 .cta-row {
  display: flex; gap: 1rem; margin-top: 2.4rem;
  justify-content: center; pointer-events: auto;
}

/* step captions: glass cards, bottom centre, actually readable */
.story .s2 {
  position: absolute; z-index: 3; left: 50%; bottom: 8vh;
  translate: -50% 0; width: min(38rem, calc(100% - 3rem));
  pointer-events: none;
  background: rgba(6, 11, 15, .84);
  border: 1px solid var(--line-2); border-radius: 12px;
  padding: 1.15rem 1.5rem 1.25rem;
  backdrop-filter: blur(14px);
  box-shadow: 0 24px 70px -24px rgba(0, 0, 0, .85);
}
.story .s2 p.k {
  font-family: var(--mono); font-size: .64rem; letter-spacing: .24em;
  text-transform: uppercase; color: var(--cyan); margin-bottom: .55rem;
}
.story .s2 p.t { color: #cfdae3; font-size: .98rem; line-height: 1.65; }
.story .s2 p.t b { color: var(--on-image); font-weight: 600; }

/* screen 4: the business */
.story .s4 {
  position: absolute; z-index: 3; inset: 0;
  display: grid; place-items: center; text-align: center;
  pointer-events: none;
}
.story .s4 h2 {
  font-size: clamp(2.2rem, 6vw, 5rem); font-weight: 600;
  line-height: 1.02; letter-spacing: -.025em; text-transform: uppercase;
}
.story .s4 h2 span { display: block; }
/* this block closes on bright sky, not on the dark ground the rest of
 * the story sits on, so it carries its own contrast */
.story .s4 h2 { text-shadow: 0 2px 26px rgba(4, 16, 34, .45); }
.story .s4 p {
  color: #f2f7fb; margin-top: 1.2rem;
  font-size: 1.06rem; font-weight: 400;
  text-shadow: 0 1px 14px rgba(4, 16, 34, .75),
               0 0 3px rgba(4, 16, 34, .5);
}
.story .s4 .cta-row {
  display: flex; gap: 1rem; margin-top: 2.2rem;
  justify-content: center; pointer-events: auto;
}
.story .s4-legend {
  display: flex; gap: 1.6rem; justify-content: center;
  margin-top: 1.3rem; font-family: var(--mono); font-size: .7rem;
  letter-spacing: .1em; text-transform: uppercase; color: #f2f7fb;
  text-shadow: 0 1px 12px rgba(4, 16, 34, .8);
}
.story .s4-legend span { display: flex; align-items: center; gap: .5rem; }
.story .s4-legend i {
  width: .85rem; height: .85rem; border-radius: 2px;
  box-shadow: 0 0 0 1px rgba(255, 255, 255, .35);
}
.story .lg-hot { background: #b8451c; }
.story .lg-wet { background: #2c6e94; }
.story .lg-quiet { background: #3a4450; }

/* instrument annotations, not cards */
.story #annos { position: absolute; inset: 0; z-index: 2; pointer-events: none; }
.story .anno {
  position: absolute; translate: 0 -50%;
  padding: .45rem .65rem .5rem .8rem;
  background: var(--panel);
  border-left: 1px solid var(--line-2);
  backdrop-filter: blur(6px);
  opacity: 0; transition: opacity .4s;
  min-width: 10rem;
}
.story .anno.on { opacity: 1; }
.story .anno .v {
  font-family: var(--mono); font-size: 1.05rem; color: var(--on-image);
  letter-spacing: .02em;
}
.story .anno .k {
  font-family: var(--mono); font-size: .56rem; letter-spacing: .18em;
  text-transform: uppercase; color: var(--dim); margin-top: .15rem;
}
.story .anno.risk .v { color: var(--risk); }
.story .anno::before {
  content: ""; position: absolute; left: -2.4rem; top: 50%;
  width: 2.4rem; height: 1px;
  background: linear-gradient(90deg, transparent, var(--line-2));
}
.story .anno::after {
  content: ""; position: absolute; left: -2.6rem; top: 50%;
  translate: 0 -50%; width: 3px; height: 3px; border-radius: 50%;
  background: var(--cyan);
}

/* legibility scrim: a quiet centre vignette for the centred copy */
.story #scrim {
  position: absolute; inset: 0; z-index: 2; pointer-events: none;
  background: radial-gradient(ellipse 58% 50% at 50% 45%,
    rgba(4, 14, 34, .50) 0%, rgba(4, 14, 34, .26) 55%, transparent 76%);
}

/* per-wall grade chips: the survey, wall by wall */
.story .wtag {
  position: absolute; translate: -50% -50%;
  font-family: var(--mono); font-size: .62rem; letter-spacing: .05em;
  padding: .16rem .42rem; border-radius: 3px;
  background: rgba(6, 11, 15, .85); border: 1px solid var(--line-2);
  opacity: 0; transition: opacity .3s; white-space: nowrap;
}
.story .wtag.on { opacity: 1; }
.story .wtag.bad { color: #ff8a5e; border-color: rgba(224, 96, 58, .6); }
.story .wtag.weak { color: #e8c477; border-color: rgba(217, 161, 63, .5); }
.story .wtag.ok { color: #7fd8c4; border-color: rgba(47, 143, 122, .5); }

/* the satellite HUD: tiny, technical, top right */
.story #sathud {
  position: absolute; z-index: 3; top: 5.2rem; right: 2.4rem;
  text-align: right; font-family: var(--mono); font-size: .66rem;
  letter-spacing: .18em; color: #dfe9f2; text-transform: uppercase;
  text-shadow: 0 1px 14px rgba(6, 20, 34, .6);
}
.story #sathud p { opacity: 0; transition: opacity .35s; margin-top: .45rem; }
.story #sathud #sh-2 { color: var(--cyan); }
.story #sathud #sh-3 span { color: #93a7b8; font-size: .6rem; letter-spacing: .12em; }

/* passing through the cloud deck */
.story #cloudpass {
  position: absolute; inset: 0; z-index: 2; pointer-events: none;
  background: radial-gradient(ellipse at 50% 60%,
    rgba(255, 255, 255, 1) 0%, rgba(244, 248, 252, .96) 55%,
    rgba(230, 238, 246, .9) 100%);
  opacity: 0;
}

/* the phase caption: the analysis narrating itself */
.story #phase {
  position: absolute; z-index: 3; top: 5.2rem; left: 50%;
  translate: -50% 0;
  font-family: var(--mono); font-size: .66rem; letter-spacing: .28em;
  color: #dfe9f2; text-transform: uppercase;
  transition: opacity .3s; white-space: nowrap;
  background: rgba(6, 11, 15, .78);
  border: 1px solid var(--line-2); border-radius: 999px;
  padding: .55rem 1.2rem;
  backdrop-filter: blur(10px);
}



/* =====================================================================
   THE REST OF THE STORY'S CSS - the half my first port missed.

   I extracted styles.css lines 184-371 and called it "the story block".
   It is not. Eighteen more story rules live elsewhere in that file, and
   the ones that matter most sit at lines 1330-1360, where styles.css
   does its LIGHT-THEME conversion for .s1 h1, .s1 .sub, #phase and
   #sathud. Without them v2.css's near-black h1 colour won on a blue sky
   - which is exactly the "SEE WATER" screenshot - and every .layer panel
   was unstyled, spilling off the left edge as raw text.

   Lesson: a section's styles are wherever they ended up, not where the
   banner comment says the section starts.
   ===================================================================== */

/* ------------------------------------------------------------- biz
 * The two flat text columns that used to live here are gone; see
 * "THE PAGE BELOW THE HERO" at the foot of this file for what replaced
 * them. .biz-actions and .biz-price survive down there too.
 */

/* the pain-point layers: analyses stacking up at the corner */
/* THE COLUMN IS POSITIONED, THE CARDS ARE NOT. Each card used to be
   absolute with left and width but no top or bottom, so all three
   resolved to the same static position and drew on top of one another -
   Ground Truth under Topography under Water. They accumulate on screen
   together (main.js: "the three layers accumulate"), so they need a
   column to accumulate down. */
.story .layers {
  position: absolute; z-index: 3; left: 2.4rem;
  top: 50%; translate: 0 -50%;
  width: min(28rem, 44vw);
  display: flex; flex-direction: column; gap: .75rem;
  /* The cards are the only thing here; the map behind them stays
     clickable everywhere they are not. */
  pointer-events: none;
}
.story .layer {
  position: relative; z-index: 3;
  width: 100%;
  padding: 1.3rem 1.5rem 1.4rem 1.7rem;
  background: rgba(6, 11, 15, .88);
  border-left: 3px solid var(--cyan);
  box-shadow: 0 18px 60px -18px rgba(0, 0, 0, .9),
    0 0 34px -12px rgba(56, 189, 242, .35);
  backdrop-filter: blur(10px);
  opacity: 0;
}

.story .layer .n {
  font-family: var(--mono); font-size: .64rem; letter-spacing: .3em;
  color: var(--cyan); text-transform: uppercase;
}

.story .layer .t {
  font-size: 1.7rem; font-weight: 600; letter-spacing: -.01em;
  text-transform: uppercase; margin-top: .3rem;
}

.story .layer .v {
  font-family: var(--mono); font-size: 2.4rem; color: var(--cyan);
  margin-top: .45rem; font-variant-numeric: tabular-nums;
}

.story .layer .d { color: var(--dim); font-size: .92rem; margin-top: .35rem; }

.story .layer.risk { border-left-color: var(--risk);
  box-shadow: 0 18px 60px -18px rgba(0, 0, 0, .9),
    0 0 34px -12px rgba(224, 96, 58, .4); }

.story .layer.risk .n, .story .layer.risk .v { color: var(--risk); }

/* ---------------------------------------------------- first-paint state
 * The story timeline sets these opacities on its first scroll frame,
 * which does not run until the module has loaded and scrolled once.
 * Without an initial state here they paint at full strength for a beat
 * on load - the closing "500,000 properties" headline lands on top of
 * the hero, and the step cards flash. Inline styles from the timeline
 * outrank these the moment it takes over. */
.story .s2, .story .s4, .story #phase, .story #sathud { opacity: 0; }

/* And the canvas is empty until the first WebGL frame, showing the
 * near-black page ground. Sit the opening sky behind it so the gap
 * reads as sky rather than as a broken page. */
.story-sticky {
  background: linear-gradient(180deg,
    #2b5b92 0%, #4a7eb4 46%, #83abd2 100%);
}

/* --- the hero, inside a box that clips ------------------------ */
  /* 9vw crosses 2.8rem at exactly 640px, so the heading is the same
     size on both sides of this breakpoint and only shrinks below it. */
.story .s1 { padding: 14vh 1.1rem 0; }

.story .s1 .cta-row, .story .s4 .cta-row {
    flex-wrap: wrap; width: 100%; max-width: min(24rem, 100%);
    margin-inline: auto;
  }

.story .s1 .cta-row .btn-lg, .story .s4 .cta-row .btn-lg {
    flex: 1 1 100%; justify-content: center;
  }

/* .s4 has no padding of its own and sits edge to edge */
.story .s4 { padding-inline: 1.1rem; }

/* the HUD chrome, which is absolutely positioned against edges */
.story #phase {
    white-space: normal; text-align: center; line-height: 1.5;
    max-width: calc(100% - 2rem); padding: .45rem .9rem;
  }


/* ---------------------------------------------------------------------
   AND PIN IT AGAINST v2.css.

   v2.css sets h1/h2 and body colour for a light page. The story sits on
   a photograph and needs the on-image role, and source order alone is
   too fragile a thing to rest that on - v2.css loads first today and
   might not tomorrow. These say it outright, scoped to .story so nothing
   below the fold is touched.
   --------------------------------------------------------------------- */
.story, .story h1, .story h2, .story p, .story .sub { color: var(--on-image, #f2f7fb); }
.story .s1 h1 { color: #fff; text-shadow: 0 2px 40px rgba(6,20,34,.45); }
.story .layer { color: var(--on-image, #f2f7fb); }
/* The layer panels were spilling off the left edge unstyled. They are
   absolutely positioned in v1; make sure they cannot escape the stage. */
.story .layers, .story #annos, .story .s1, .story .s2 { max-width: 100%; }
.story-sticky { overflow: hidden; }


/* ---------------------------------------------------------------------
   THE STORY'S BUTTONS - the neon, which I under-copied again.

   "See it on your address" was rendering as a raw browser link, purple
   and underlined, because .btn-solid/.btn-ghost/.btn-lg live at
   styles.css 166-181 and I only brought across the .s1/.s4 .cta-row
   rules that POSITION them. Oliver: "this button should be the old
   neon." It is --lime, #c9f542, and it was never here to apply.

   --lime is defined in styles.css's token block, which v2 does not
   load, so it is declared locally rather than inherited from nothing.
   --------------------------------------------------------------------- */
.story { --lime: #c9f542; }

.story .btn-solid, .story .btn-ghost {
  display: inline-flex; align-items: center; gap: .55rem;
  /* 600, not 700: DejaVu's bold was doing most of the clunking. */
  font: 600 .875rem/1 var(--ui);
  letter-spacing: .004em;
  padding: .72rem 1.35rem; border-radius: 999px;
  text-decoration: none; white-space: nowrap;
  transition: transform .18s, background .18s, border-color .18s, color .18s;
}
.story .btn-solid { background: var(--lime); color: #131a04; font-weight: 600; }
.story .btn-solid:hover { background: #b8e62e; transform: translateY(-1px); }
/* NOT `color: var(--text)`. That is v1's token and v2 does not define
   it, so the declaration is invalid at computed-value time and `color`
   falls back to INHERITED - which inside .story is the on-image
   near-white I pin a few rules up. Result: white text on a white pill,
   which is what Oliver photographed. An undefined custom property does
   not fail loudly; it quietly hands the property to inheritance.
   Ghost is the secondary button: white fill, navy ink, 13.1:1. */
.story .btn-ghost { color: #16324e; background: #fff;
  border: 1px solid rgba(22, 50, 78, .18); }
.story .btn-ghost:hover { border-color: rgba(22, 50, 78, .38); }
.story .btn-lg { padding: .98rem 1.75rem; font-size: .94rem; }
.story .arr { font-size: .85em; translate: 0 -1px; }


/* v2.css owns `a` colour for a light page; the story's buttons are not
   links in that sense and must not take it. */
.story .btn-solid { color: #131a04; text-decoration: none; }
.story .btn-ghost { text-decoration: none; color: #16324e; background: #fff; }


/* ---------------------------------------------------------------------
   "Scroll" AND THE SCENE NOTE - the third thing I under-copied.

   Oliver: "when I reload, top right it says scroll illustrative property
   etc". Both are position:absolute inside the story in v1 - the hint
   bottom-centre, the note bottom-right. Without their rules they fall
   back to static flow and stack as plain paragraphs at the top of the
   page, which is exactly what he saw on reload before the reveal hid
   anything.
   --------------------------------------------------------------------- */
.story .hint {
  position: absolute; z-index: 3; left: 50%; bottom: 1.4rem;
  translate: -50% 0;
  font-family: var(--mono); font-size: .62rem; letter-spacing: .3em;
  text-transform: uppercase; color: var(--dim-2);
}

/* the fine print riding the scene */
.story .scene-note {
  position: absolute; z-index: 3; right: 2.4rem; bottom: 1.4rem;
  font-family: var(--mono); font-size: .62rem; color: var(--dim-2);
  max-width: 22rem; text-align: right; line-height: 1.7;
}



/* ---------------------------------------------------------------------
   THE TOKENS THE PORTED CSS EXPECTS.

   The ghost button taught this the hard way: it said `color: var(--text)`,
   v2 does not define --text, and an undefined custom property is not a
   no-op - the declaration becomes invalid at computed-value time and the
   property falls back to INHERITED. Inside .story that inherit is the
   on-image near-white, so the rule painted white text on a white pill
   with no error anywhere.

   Audited the rest rather than waiting to be shown the next one: nine
   tokens are referenced by the ported rules and defined nowhere. Each is
   given the value it had in v1, or the v2 palette equivalent.
   --------------------------------------------------------------------- */
.story {
  --text:     #f2f7fb;   /* on the photograph, so light */
  --on-image: #f2f7fb;
  --dim:      #cfdae3;
  --dim-2:    #a8b8c6;
  --line-2:   rgba(255, 255, 255, .22);
  --panel:    rgba(10, 18, 26, .55);
  --risk:     #ff8a5e;
  --mono:     ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  --ui:       var(--geo);
}


/* ------------------------------------------------- mobile: no hijack
   .story is 820vh with a sticky viewport inside - a deliberate effect
   with a wheel, and 8.2 screen-heights of thumb-work on a phone with
   nothing underneath reachable. Below 760px the hero becomes one
   screen and the page scrolls normally. The canvas still paints; it
   just is not scroll-driven, which is the same thing reduce-motion
   users have always seen. */
@media (max-width: 760px) {
  .story { height: 100svh; height: 100vh; }
  .story-sticky { position: relative; height: 100svh; height: 100vh; }
}
