/* ──────────────────────────────
   HOW IT WORKS — diagram scenes
────────────────────────────── */
/* ── homepage mount: the story fragment is injected here by JS ──
   While the fragment loads, the mount reserves a viewport so the page
   content below doesn't flash at the top. `hiw-settled` drops the
   reservation once the story collapses (or fails to load). */
.js .hiw-mount {
  min-height: 100vh;
  min-height: 100svh;
}

.js .hiw-mount.hiw-settled {
  min-height: 0;
}

/* static fallback statements (no-JS or fragment load failure) */
.hiw-fallback {
  max-width: 900px;
  margin: 0 auto;
  padding: 3rem 2rem;
}

.hiw-fallback p {
  font-weight: 600;
  font-size: clamp(1.5rem, 3.5vw, 2.5rem);
  line-height: 1.3;
  color: #0f2b46;
  text-align: center;
  mix-blend-mode: multiply;
}

.hiw-fallback p + p {
  margin-top: 2.5rem;
}

.js .hiw-fallback {
  display: none;
}

.js .hiw-mount.hiw-load-failed .hiw-fallback {
  display: block;
}

/* ── story track: static stacked scenes by default (no-JS / reduced motion) ── */
.hiw-story {
  position: relative;
}

/* Pinned, scroll-driven mode (class added by JS only when motion is allowed).
   Track height is set inline by JS in svh units (beats × per-beat length) so
   it never changes while the mobile URL bar collapses/expands; this is only
   the pre-JS fallback. */
.js .hiw-story.hiw-animate {
  height: 480vh;
  height: 480svh;
}

/* The pinned stage uses the *small* viewport height so nothing hides behind
   the URL bar / in-app browser chrome, and safe-area padding keeps centered
   content clear of notches and toolbars. */
.js .hiw-story.hiw-animate .hiw-stage {
  position: sticky;
  top: 0;
  height: 100vh;
  height: 100svh;
  overflow: hidden;
  padding-top: env(safe-area-inset-top, 0px);
  padding-bottom: env(safe-area-inset-bottom, 0px);
}

.js .hiw-story.hiw-animate .scene {
  position: absolute;
  inset: 0;
  display: flex;
  padding: 2rem;
  opacity: 0;
  transform: translateY(48px);
  will-change: opacity, transform;
  pointer-events: none;
}

/* transitions only kick in one frame after setup, so the pre-JS static
   layout can't be seen fading out on load */
.js .hiw-story.hiw-animate.hiw-ready .scene {
  transition: opacity 0.6s ease, transform 0.7s cubic-bezier(0.2, 0.7, 0.2, 1);
}

.js .hiw-story.hiw-animate .scene.is-active {
  opacity: 1;
  transform: none;
  pointer-events: auto;
}

.js .hiw-story.hiw-animate .scene.is-prev {
  opacity: 0;
  transform: translateY(-48px);
}

/* auto margins center the content when it fits, but collapse to zero when
   it's taller than the stage — so the top of the text is never clipped on
   short viewports (flex `align-items: center` would push it out of view) */
.js .hiw-story.hiw-animate .scene-inner {
  width: 100%;
  margin: auto;
}

/* keep each diagram inside one viewport */
.js .hiw-story.hiw-animate .scene-diagram svg {
  max-height: 56vh;
  max-height: 56svh;
}

/* scroll cue (base styles live in style.css) */
.hiw-story .scroll-cue {
  color: var(--blue);
  mix-blend-mode: multiply;
}

.js .hiw-story.hiw-animate .scroll-cue {
  display: flex;
}

.scene {
  padding: 3rem 2rem 3.5rem;
}

.scene-inner {
  max-width: 1000px;
  margin: 0 auto;
}

.scene-kicker {
  font-family: 'Bebas Neue', 'Thunderhouse Pro', Impact, sans-serif;
  font-size: clamp(1.9rem, 3.5vw, 2.9rem);
  letter-spacing: 0.03em;
  color: var(--navy);
  mix-blend-mode: multiply;
}

.scene-statement {
  margin-top: 0.5rem;
  font-weight: 600;
  font-size: clamp(1.05rem, 2.1vw, 1.55rem);
  line-height: 1.35;
  color: #0f2b46;
  max-width: 52ch;
  mix-blend-mode: multiply;
}

.scene-visual + .scene-statement {
  margin-top: 1.5rem;
}

.scene-inner--center {
  text-align: center;
}

.scene-inner--center .scene-statement {
  margin-left: auto;
  margin-right: auto;
}

/* ── zine-graphic scene compositions ── */
.scene-visual {
  margin-top: 1.75rem;
}

.visual-row {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: clamp(1rem, 3vw, 2.5rem);
}

.zi-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.6rem;
  margin: 0;
}

.zi {
  display: block;
  mix-blend-mode: multiply;
}

.zi-card { width: clamp(120px, 15vw, 190px); }
.zi-phone { width: clamp(58px, 7vw, 92px); }
.zi-profile { width: clamp(150px, 19vw, 250px); }

.zi-cart-group {
  position: relative;
  width: clamp(110px, 14vw, 180px);
}

.zi-cart {
  position: relative;
  width: 100%;
}

.zi-fruit {
  position: absolute;
  z-index: -1;
}

.zi-fruit-1 { width: 28%; top: -14%; left: 16%; transform: rotate(-10deg); }
.zi-fruit-2 { width: 34%; top: -22%; left: 38%; transform: rotate(12deg); }
.zi-fruit-3 { width: 26%; top: -12%; left: 64%; transform: rotate(6deg); }

.zi-label {
  font-size: clamp(0.8rem, 1.4vw, 1rem);
  font-weight: 600;
  color: var(--blue);
  text-align: center;
  max-width: 26ch;
  mix-blend-mode: multiply;
}

.zi-stream {
  width: clamp(70px, 9vw, 130px);
  overflow: visible;
  mix-blend-mode: multiply;
}

.broker-box {
  background: var(--navy);
  border-radius: 14px;
  padding: 1rem 1.4rem 1.2rem;
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  align-items: flex-start;
  min-width: clamp(140px, 16vw, 210px);
}

.broker-title {
  font-family: 'Bebas Neue', 'Thunderhouse Pro', Impact, sans-serif;
  font-size: clamp(1.2rem, 2vw, 1.7rem);
  letter-spacing: 0.05em;
  color: var(--lime);
}

.broker-rows {
  display: flex;
  flex-direction: column;
  gap: 0.45rem;
  width: 100%;
}

.broker-rows span {
  height: 8px;
  border-radius: 4px;
  background: rgba(248, 247, 242, 0.55);
}

.broker-rows span:nth-child(1) { width: 90%; }
.broker-rows span:nth-child(2) { width: 72%; }
.broker-rows span:nth-child(3) { width: 54%; }

.chip-stack,
.stamp-stack {
  display: flex;
  flex-direction: column;
  gap: 0.7rem;
  align-items: flex-start;
}

.hiw-chip {
  display: inline-block;
  border-radius: 999px;
  padding: 0.45rem 1.05rem;
  font-weight: 600;
  font-size: clamp(0.85rem, 1.5vw, 1.05rem);
  color: var(--navy);
  white-space: nowrap;
  mix-blend-mode: multiply;
}

.chip-lime { background: var(--lime); }
.chip-sky { background: var(--sky); }
.chip-pink { background: var(--pink); color: var(--cream); }
.chip-navy { background: var(--navy); color: var(--cream); }

.hiw-stamp {
  display: inline-block;
  font-family: 'Bebas Neue', 'Thunderhouse Pro', Impact, sans-serif;
  font-size: clamp(1.3rem, 2.4vw, 2rem);
  letter-spacing: 0.06em;
  color: var(--orange);
  border: 3px solid var(--orange);
  border-radius: 8px;
  padding: 0.1rem 0.7rem;
  transform: rotate(-6deg);
  mix-blend-mode: multiply;
}

.zi-register-group {
  position: relative;
  width: clamp(120px, 15vw, 190px);
}

.zi-register { width: 100%; }

.price-tag {
  position: absolute;
  border-radius: 999px;
  padding: 0.3rem 0.85rem;
  font-weight: 600;
  font-size: clamp(0.95rem, 1.7vw, 1.2rem);
}

.price-tag-a {
  top: -8%;
  left: -20%;
  background: var(--lime);
  color: var(--navy);
}

.price-tag-b {
  top: 14%;
  right: -24%;
  background: var(--pink);
  color: var(--cream);
}

.zi-pin {
  width: clamp(46px, 6vw, 70px);
  mix-blend-mode: multiply;
}

/* ── scene 2: stamp overlay + "sold as fact" flow ── */
.zi-profile-group {
  position: relative;
}

.stamp-pos {
  position: absolute;
  top: -12%;
  right: -14%;
}

.sold-group {
  display: flex;
  align-items: center;
  gap: 0.7rem;
}

.zi-stream--sold {
  width: clamp(56px, 7vw, 100px);
}

.zi-coin-text {
  fill: var(--cream);
  font-weight: 700;
  font-size: 17px;
  font-family: 'Source Sans 3', 'Avenir Next', Avenir, sans-serif;
}

/* ── scene 3: branching buyers diagram ── */
.buyers-diagram {
  flex-wrap: nowrap;
}

.zi-fan {
  width: clamp(70px, 9vw, 140px);
  flex-shrink: 0;
  overflow: visible;
  mix-blend-mode: multiply;
}

.buyer-list {
  display: flex;
  flex-direction: column;
  gap: clamp(1rem, 2.5vh, 1.75rem);
  align-items: flex-start;
}

.buyer-node {
  display: flex;
  align-items: center;
  gap: 0.9rem;
}

.buyer-node .zi-label {
  text-align: left;
}

/* insurers rate meter */
.zi-meter-group {
  position: relative;
  width: clamp(96px, 11vw, 150px);
}

.zi-meter {
  display: block;
  width: 100%;
  overflow: visible;
  mix-blend-mode: multiply;
}

.meter-seg {
  fill: none;
  stroke-width: 10;
  stroke-linecap: round;
}

.meter-txt {
  font-family: 'Bebas Neue', 'Thunderhouse Pro', Impact, sans-serif;
  font-size: 11px;
  letter-spacing: 0.06em;
}

.meter-needle {
  transform-box: view-box;
  transform-origin: 60px 64px;
  transform: rotate(64deg);
}

.js .meter-needle {
  transform: rotate(-72deg);
  transition: transform 0.9s cubic-bezier(0.34, 1.45, 0.4, 1) 0.25s;
}

.js .scene.in-view .meter-needle,
.js .scene.r2 .meter-needle,
.js .scene.r3 .meter-needle,
.js .scene.r4 .meter-needle,
.js .scene.r5 .meter-needle,
.js .scene.r6 .meter-needle,
.js .scene.r7 .meter-needle,
.js .scene.r8 .meter-needle {
  transform: rotate(64deg);
}

.rate-tag {
  position: absolute;
  top: -18%;
  right: -26%;
  border-radius: 999px;
  padding: 0.2rem 0.6rem;
  font-weight: 600;
  font-size: clamp(0.8rem, 1.3vw, 1rem);
  background: var(--pink);
  color: var(--cream);
  white-space: nowrap;
}

.zi-register-group--sm {
  width: clamp(84px, 9vw, 130px);
}

.zi-register-group--sm .price-tag {
  font-size: clamp(0.8rem, 1.3vw, 1rem);
  padding: 0.2rem 0.6rem;
}

@media (max-width: 640px) {
  .buyers-diagram {
    flex-wrap: wrap;
  }

  .zi-fan {
    display: none;
  }
}

.zi-question-group {
  position: relative;
}

.zi-question {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: 'Bebas Neue', 'Thunderhouse Pro', Impact, sans-serif;
  font-size: clamp(3.2rem, 8vw, 5.5rem);
  color: var(--orange);
  mix-blend-mode: multiply;
}

.arrow {
  fill: var(--navy);
}

/* dashed marching data stream */
.stream {
  fill: none;
  stroke: var(--navy);
  stroke-width: 3;
  stroke-linecap: round;
  stroke-dasharray: 2 12;
}

.js .stream {
  animation: stream-march 0.9s linear infinite;
}

@keyframes stream-march {
  to { stroke-dashoffset: -14; }
}

/* ── scroll-driven reveals (gated on .js so no-JS users see everything) ──
   Elements are grouped d1..d8; JS adds r1..r8 to the scene as the visitor
   scrolls, so each scroll tick reveals the next group (and hides it again
   when scrolling back). `.in-view` still means "fully revealed" and is used
   for passed scenes, the collapsed state, and fallbacks. */
.js .anim {
  opacity: 0;
  transform: translateY(16px);
  transform-box: fill-box;
  transform-origin: center;
  transition: opacity 0.35s ease, transform 0.35s ease;
}

.js .anim--pop {
  transform: scale(0.5);
}

/* text beats rise up from the bottom of the viewport as the user scrolls.
   svh keeps the entrance offset stable while the mobile URL bar animates. */
.js .anim.beat {
  transform: translateY(46vh);
  transform: translateY(40svh);
  transition-duration: 0.55s, 0.7s;
}

.js .scene.in-view .anim,
.js .scene.r1 .anim.d1,
.js .scene.r2 .anim.d2,
.js .scene.r3 .anim.d3,
.js .scene.r4 .anim.d4,
.js .scene.r5 .anim.d5,
.js .scene.r6 .anim.d6,
.js .scene.r7 .anim.d7,
.js .scene.r8 .anim.d8 {
  opacity: 1;
  transform: none;
}

/* reduced motion: show finished diagrams, no animation */
@media (prefers-reduced-motion: reduce) {
  .js .stream { animation: none; }

  .js .meter-needle {
    transform: rotate(64deg);
    transition: none;
  }

  .js .anim,
  .js .anim--pop,
  .js .anim.beat {
    opacity: 1;
    transform: none;
    transition: none;
  }

}

@media (max-width: 640px) {
  .scene { padding: 2rem 1.25rem 2.5rem; }
  .scene-visual { margin-top: 1.25rem; }
}

/* ── small / short viewports: tighten everything so a full scene (kicker +
   statements + visual) fits inside one small viewport with browser chrome
   visible, and keep the pinned stage clear of notches and toolbars ── */
@media (max-width: 640px), (max-height: 700px) {
  .js .hiw-story.hiw-animate .scene {
    /* generous top clearance so the first statement sits well below the
       mobile browser chrome / notch and is never clipped at the top edge;
       extra bottom room keeps the scroll cue clear of scene text */
    padding: calc(env(safe-area-inset-top, 0px) + 4rem) 1.25rem
      calc(env(safe-area-inset-bottom, 0px) + 4.25rem);
  }

  .js .hiw-story.hiw-animate .scene-statement {
    font-size: 1rem;
    line-height: 1.3;
  }

  .js .hiw-story.hiw-animate .scene-kicker {
    font-size: 1.6rem;
  }

  .js .hiw-story.hiw-animate .scene-visual {
    margin-top: 1rem;
  }

  .js .hiw-story.hiw-animate .scene-visual + .scene-statement {
    margin-top: 1rem;
  }

  .js .hiw-story.hiw-animate .visual-row {
    gap: 0.9rem;
  }

  .js .hiw-story.hiw-animate .zi-card { width: 96px; }
  .js .hiw-story.hiw-animate .zi-phone { width: 48px; }
  .js .hiw-story.hiw-animate .zi-profile { width: 132px; }
  .js .hiw-story.hiw-animate .zi-cart-group { width: 92px; }
  .js .hiw-story.hiw-animate .zi-stream { width: 60px; }
  .js .hiw-story.hiw-animate .zi-stream--sold { width: 52px; }
  .js .hiw-story.hiw-animate .zi-meter-group { width: 88px; }
  .js .hiw-story.hiw-animate .zi-register-group--sm { width: 78px; }
  .js .hiw-story.hiw-animate .zi-pin { width: 42px; }

  .js .hiw-story.hiw-animate .broker-box {
    min-width: 120px;
    padding: 0.7rem 1rem 0.85rem;
  }

  .js .hiw-story.hiw-animate .hiw-chip {
    font-size: 0.8rem;
    padding: 0.32rem 0.85rem;
  }

  .js .hiw-story.hiw-animate .hiw-stamp {
    font-size: 1.15rem;
  }

  .js .hiw-story.hiw-animate .zi-label {
    font-size: 0.74rem;
  }

  .js .hiw-story.hiw-animate .buyer-list {
    gap: 0.8rem;
  }

  .js .hiw-story.hiw-animate .scene-diagram svg,
  .js .hiw-story.hiw-animate .scene-visual svg {
    max-height: 32vh;
    max-height: 32svh;
  }

  /* keep the cue inside the safe area at the very bottom of the stage */
  .js .hiw-story.hiw-animate .scroll-cue {
    bottom: calc(env(safe-area-inset-bottom, 0px) + 1rem);
  }
}

/* ── very short phones (iPhone SE etc.): scene 1 (statement + graphics row +
   two more statements) is the tallest scene, so tighten it further — smaller
   graphics, smaller broker box, tighter gaps — and trim the extra top/bottom
   clearance a bit so the last statements are never cut off. ── */
@media (max-width: 640px) and (max-height: 700px) {
  .js .hiw-story.hiw-animate .scene {
    padding: calc(env(safe-area-inset-top, 0px) + 2.5rem) 1.1rem
      calc(env(safe-area-inset-bottom, 0px) + 3.25rem);
  }

  .js .hiw-story.hiw-animate .scene-statement {
    font-size: 0.92rem;
    line-height: 1.28;
  }

  .js .hiw-story.hiw-animate .scene-visual {
    margin-top: 0.7rem;
  }

  .js .hiw-story.hiw-animate .scene-visual + .scene-statement {
    margin-top: 0.7rem;
  }

  .js .hiw-story.hiw-animate .visual-row {
    gap: 0.6rem;
    row-gap: 0.4rem;
  }

  .js .hiw-story.hiw-animate .zi-item {
    gap: 0.35rem;
  }

  .js .hiw-story.hiw-animate .zi-card { width: 76px; }
  .js .hiw-story.hiw-animate .zi-phone { width: 38px; }
  .js .hiw-story.hiw-animate .zi-cart-group { width: 74px; }
  .js .hiw-story.hiw-animate .zi-stream { width: 46px; }
  .js .hiw-story.hiw-animate .zi-profile { width: 112px; }

  .js .hiw-story.hiw-animate .broker-box {
    min-width: 96px;
    padding: 0.5rem 0.75rem 0.6rem;
    gap: 0.4rem;
  }

  .js .hiw-story.hiw-animate .broker-title {
    font-size: 1rem;
  }

  .js .hiw-story.hiw-animate .broker-rows {
    gap: 0.3rem;
  }

  .js .hiw-story.hiw-animate .broker-rows span {
    height: 6px;
  }

  .js .hiw-story.hiw-animate .zi-label {
    font-size: 0.68rem;
  }
}

