/* ==========================================================================
   蜻之舞 — 设计系统与样式表
   蓝白叙事风格 · 零依赖 · 无外部字体请求 · 支持浅色/深色
   ========================================================================== */

/* --------------------------------------------------------------- 1. tokens */
:root {
  /* --- neutral: cool greys with a blue cast, so they sit inside the palette
         instead of fighting it ------------------------------------------- */
  --c-bg:        #F5F8FC;
  --c-surface:   #FFFFFF;
  --c-surface-2: #EDF3FA;
  --c-line:      #DCE5F0;
  --c-line-soft: #E9F0F8;
  --c-ink:       #0C1622;
  --c-ink-soft:  #3B4B60;
  --c-ink-mute:  #6C7F96;
  --c-ink-faint: #9AAABC;

  /* --- blue: the brand ramp. Azure leads, deep sea anchors -------------- */
  --c-blue:      #1266F1;
  --c-blue-600:  #0F55CC;
  --c-blue-400:  #4C8DF7;
  --c-blue-200:  #A9C8FB;
  --c-blue-050:  #E8F0FE;
  --c-deep:      #0A2A5E;
  --c-deep-2:    #071C40;

  --c-brand:     #0C1622;
  --c-accent:    var(--c-blue);
  --c-mist:      #6BA8FF;

  --c-invert-bg: #071C40;
  --c-invert-fg: #F2F7FF;
  --c-invert-mute: #93AACB;

  /* glass panels over the mist */
  --c-glass:        rgba(255, 255, 255, 0.72);
  --c-glass-strong: rgba(255, 255, 255, 0.9);
  --c-glass-line:   rgba(18, 102, 241, 0.14);
  --c-grid:         rgba(18, 102, 241, 0.055);

  /* --- type ------------------------------------------------------------- */
  --font-sans: -apple-system, BlinkMacSystemFont, "Segoe UI Variable Display",
               "Segoe UI", "PingFang SC", "Hiragino Sans GB",
               "Microsoft YaHei UI", "Microsoft YaHei", "Source Han Sans SC",
               "Noto Sans CJK SC", system-ui, sans-serif;
  --font-serif: "Songti SC", "Source Han Serif SC", "Noto Serif CJK SC",
                "STSong", "SimSun", Georgia, serif;
  --font-mono: "SF Mono", "Cascadia Mono", "JetBrains Mono", Consolas,
               "Liberation Mono", monospace;

  --t-hero:  clamp(3rem, 1.5rem + 6.4vw, 7.5rem);
  --t-act:   clamp(1.9rem, 1.1rem + 3.2vw, 4rem);
  --t-h3:    clamp(1.125rem, 1.02rem + 0.5vw, 1.45rem);
  --t-lede:  clamp(1rem, 0.95rem + 0.4vw, 1.22rem);
  --t-body:  1rem;
  --t-sm:    0.875rem;
  --t-xs:    0.75rem;
  --t-stat:  clamp(1.9rem, 1.3rem + 2.2vw, 3.1rem);

  /* --- rhythm ----------------------------------------------------------- */
  --shell:      1280px;
  --gutter:     clamp(1.25rem, 4vw, 3.5rem);
  --radius-sm:  8px;
  --radius:     14px;
  --radius-lg:  22px;
  --radius-xl:  30px;

  /* --- motion: one easing family across the whole site ------------------ */
  --ease-out:  cubic-bezier(0.22, 1, 0.36, 1);
  --ease-io:   cubic-bezier(0.65, 0, 0.35, 1);
  --dur-fast:  0.24s;
  --dur:       0.6s;
  --dur-slow:  1.1s;

  --shadow-sm: 0 1px 2px rgba(12, 22, 34, 0.05);
  --shadow:    0 14px 38px -16px rgba(10, 42, 94, 0.22),
               0 2px 8px -3px rgba(10, 42, 94, 0.08);
  --shadow-lg: 0 40px 80px -34px rgba(10, 42, 94, 0.34),
               0 6px 18px -8px rgba(10, 42, 94, 0.1);
  --glow-blue: 0 0 0 1px rgba(18, 102, 241, 0.22),
               0 8px 40px -8px rgba(18, 102, 241, 0.4);

  --header-h: 72px;
  --act-pad:  clamp(5.5rem, 8vh, 8rem);
}

@media (prefers-color-scheme: dark) {
  :root {
    --c-bg:        #0A1018;
    --c-surface:   #101927;
    --c-surface-2: #16202F;
    --c-line:      #22303F;
    --c-line-soft: #1B2534;
    --c-ink:       #EAF1FA;
    --c-ink-soft:  #B3C2D4;
    --c-ink-mute:  #7C8EA3;
    --c-ink-faint: #566779;

    --c-blue:      #4C8DF7;
    --c-blue-600:  #6BA8FF;
    --c-blue-400:  #7FB4FF;
    --c-blue-200:  #1E3557;
    --c-blue-050:  #12213A;
    --c-deep:      #0D2547;
    --c-deep-2:    #071C40;

    --c-brand:     #EAF1FA;
    --c-accent:    #4C8DF7;
    --c-mist:      #3E6FA8;

    --c-invert-bg: #071C40;
    --c-invert-fg: #F2F7FF;
    --c-invert-mute: #93AACB;

    --c-glass:        rgba(16, 25, 39, 0.66);
    --c-glass-strong: rgba(16, 25, 39, 0.86);
    --c-glass-line:   rgba(76, 141, 247, 0.2);
    --c-grid:         rgba(76, 141, 247, 0.07);

    --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.5);
    --shadow:    0 14px 38px -16px rgba(0, 0, 0, 0.7),
                 0 2px 8px -3px rgba(0, 0, 0, 0.4);
    --shadow-lg: 0 40px 80px -34px rgba(0, 0, 0, 0.85),
                 0 6px 18px -8px rgba(0, 0, 0, 0.5);
  }
}

/* ---------------------------------------------------------------- 2. reset */
*, *::before, *::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
}

body {
  margin: 0;
  background: var(--c-bg);
  color: var(--c-ink);
  font-family: var(--font-sans);
  font-size: var(--t-body);
  line-height: 1.68;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
}

/* A blueprint grid under the whole page: the site is drawn on graph paper.
   Masked to fade at the edges so it reads as depth, not as a table. */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background-image:
    linear-gradient(to right, var(--c-grid) 1px, transparent 1px),
    linear-gradient(to bottom, var(--c-grid) 1px, transparent 1px);
  background-size: 72px 72px;
  -webkit-mask-image: radial-gradient(120% 100% at 50% 0%, #000 12%, transparent 78%);
  mask-image: radial-gradient(120% 100% at 50% 0%, #000 12%, transparent 78%);
}
main, .site-footer { position: relative; z-index: 1; }

h1, h2, h3, p, dl, dd, figure, blockquote { margin: 0; }
ul, ol { margin: 0; padding: 0; list-style: none; }
img, svg { display: block; max-width: 100%; }
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; }

:focus-visible {
  outline: 2px solid var(--c-blue);
  outline-offset: 3px;
  border-radius: 4px;
}
::selection { background: var(--c-blue); color: #fff; }

.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

.skip-link {
  position: fixed; top: 8px; left: 8px; z-index: 999;
  padding: 10px 18px; border-radius: var(--radius-sm);
  background: var(--c-ink); color: var(--c-bg);
  font-size: var(--t-sm); font-weight: 600;
  transform: translateY(-160%);
  transition: transform var(--dur-fast) var(--ease-out);
}
.skip-link:focus { transform: translateY(0); }

/* ----------------------------------------------------- 3. narrative shell */
:root { --act-span: 1.6; }

.act {
  position: relative;
  min-height: 100vh;
  min-height: 100svh;
}
/* Sticky acts get extra scroll length so the pinned content has room to
   progress. --act-span is set per act from the narrative script. */
.act[data-act] { min-height: calc(100vh * var(--act-span)); }

.act-sticky {
  position: sticky;
  top: 0;
  min-height: 100vh;
  min-height: 100svh;
  display: flex;
  align-items: center;
  padding-block: var(--act-pad);
  overflow: hidden;
}

.act-inner {
  position: relative;
  width: 100%;
}

/* The hero's sticky box must STRETCH its flex item, not centre it: with
   `align-items: center` the .act-inner item shrink-to-fits its content and is
   then centred, which shifted the whole hero sideways (x=300 with width 1124
   inside a 1424 box). The .shell inside already does the horizontal centring.
   Declared here, after the base .act-sticky rule, so it wins on order as well
   as on specificity. */
.act--hero .act-sticky {
  align-items: stretch;
}

.shell {
  width: 100%;
  max-width: var(--shell);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

/* --- act header ---------------------------------------------------------- */
.act-eyebrow {
  display: flex;
  align-items: center;
  gap: 0.85rem;
  font-size: var(--t-xs);
  font-weight: 600;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--c-blue);
  margin-bottom: 1.15rem;
}
.act-eyebrow-no {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  padding: 0.2rem 0.5rem;
  border: 1px solid var(--c-glass-line);
  border-radius: 999px;
  background: var(--c-blue-050);
  letter-spacing: 0.08em;
}
.act-eyebrow--invert { color: var(--c-blue-200); }
.act-eyebrow--invert .act-eyebrow-no {
  background: rgba(255, 255, 255, 0.08);
  border-color: rgba(255, 255, 255, 0.18);
  color: var(--c-invert-fg);
}

/* --- a geometric accent system ------------------------------------------
   Each act carries three decorative shapes: a dashed ring, a dot cluster and
   a corner bracket. They are the "drawn on graph paper" motif made literal,
   and they are the difference between a sparse page and a composed one. */
.act-accent {
  position: absolute;
  pointer-events: none;
  z-index: 0;
  color: var(--c-blue);
}
.act-accent--ring {
  border-radius: 50%;
  border: 1px dashed currentColor;
  opacity: 0.2;
  animation: orbit-spin 70s linear infinite;
}
.act-accent--dots {
  background-image: radial-gradient(currentColor 1.4px, transparent 1.5px);
  background-size: 15px 15px;
  opacity: 0.3;
  -webkit-mask-image: radial-gradient(closest-side, #000, transparent);
  mask-image: radial-gradient(closest-side, #000, transparent);
}
.act-accent--cross {
  width: 46px; height: 46px;
  opacity: 0.35;
}
.act-accent--cross::before,
.act-accent--cross::after {
  content: "";
  position: absolute;
  background: currentColor;
}
.act-accent--cross::before { top: 50%; left: 0; width: 100%; height: 1px; }
.act-accent--cross::after { left: 50%; top: 0; width: 1px; height: 100%; }

/* placement is per act, so the shapes never look stamped from a template */
.act--about .act-accent--ring   { width: 30vw; height: 30vw; right: -9vw; top: 6%; }
.act--about .act-accent--dots   { width: 190px; height: 190px; left: -3rem; bottom: 8%; }
.act--about .act-accent--cross  { right: 8%; bottom: 14%; }

.act--belief .act-accent--ring  { width: 22vw; height: 22vw; left: -7vw; top: 12%; animation-direction: reverse; }
.act--belief .act-accent--dots  { width: 220px; height: 220px; right: -2rem; bottom: 4%; }
.act--belief .act-accent--cross { left: 12%; top: 10%; }

.act--scope .act-accent--ring   { width: 26vw; height: 26vw; right: -8vw; bottom: -6%; }
.act--scope .act-accent--dots   { width: 200px; height: 200px; left: -3rem; top: 8%; }
.act--scope .act-accent--cross  { right: 10%; top: 12%; }

.act--product .act-accent--ring { width: 24vw; height: 24vw; left: -8vw; bottom: 2%; }
.act--product .act-accent--dots { width: 180px; height: 180px; right: -2rem; top: 10%; }

.act--formula .act-accent--ring { width: 28vw; height: 28vw; right: -9vw; top: 20%; }
.act--formula .act-accent--dots { width: 170px; height: 170px; left: 2%; bottom: 6%; }

.act--scenes .act-accent--ring  { width: 20vw; height: 20vw; left: -6vw; top: 6%; }
.act--scenes .act-accent--dots  { width: 200px; height: 200px; right: 4%; bottom: -2rem; }

/* --- giant ghost act number --------------------------------------------- */
.act-ghost {
  position: absolute;
  right: clamp(0.5rem, 3vw, 3rem);
  top: clamp(3rem, 9vh, 7rem);
  z-index: 0;
  font-family: var(--font-mono);
  font-size: clamp(6rem, 20vw, 20rem);
  font-weight: 600;
  line-height: 0.72;
  letter-spacing: -0.06em;
  color: var(--c-blue);
  opacity: 0.055;
  pointer-events: none;
  user-select: none;
  font-variant-numeric: tabular-nums;
}
@media (prefers-color-scheme: dark) {
  .act-ghost { opacity: 0.08; }
}

/* the act's own shell must sit above the accents */
.act-shell, .plan-body { position: relative; z-index: 1; }

.act-title {
  font-size: var(--t-act);
  line-height: 1.1;
  letter-spacing: -0.028em;
  font-weight: 650;
  text-wrap: balance;
}

.act-lede {
  margin-top: 1.2rem;
  font-size: var(--t-lede);
  line-height: 1.74;
  color: var(--c-ink-soft);
  max-width: 54ch;
  text-wrap: pretty;
}
.act-lede--side { margin-top: 0.4rem; max-width: 34ch; }

.act-head { margin-bottom: clamp(1.8rem, 3vh, 3rem); }
.act-head--tight { margin-bottom: 1.6rem; }
.act-head--row {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: 1.5rem 3rem;
}

/* ------------------------------------------------------------- 4. buttons */
.btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.6rem;
  padding: 0.92rem 1.7rem;
  border-radius: 999px;
  font-size: var(--t-sm);
  font-weight: 560;
  letter-spacing: 0.01em;
  white-space: nowrap;
  border: 1px solid transparent;
  transition: background-color var(--dur-fast) var(--ease-out),
              border-color var(--dur-fast) var(--ease-out),
              color var(--dur-fast) var(--ease-out),
              box-shadow var(--dur) var(--ease-out);
  will-change: transform;
}
.btn-sm { padding: 0.62rem 1.2rem; }
.btn-lg { padding: 1.05rem 2rem; font-size: 0.95rem; }

.btn-arrow {
  position: relative;
  width: 14px; height: 1px;
  background: currentColor;
  transition: width var(--dur) var(--ease-out);
}
.btn-arrow::after {
  content: "";
  position: absolute;
  right: 0; top: 50%;
  width: 6px; height: 6px;
  border-top: 1px solid currentColor;
  border-right: 1px solid currentColor;
  transform: translateY(-50%) rotate(45deg);
}
.btn:hover .btn-arrow { width: 22px; }

.btn-primary {
  background: var(--c-blue);
  color: #fff;
  box-shadow: 0 10px 30px -12px rgba(18, 102, 241, 0.6);
}
.btn-primary:hover {
  background: var(--c-blue-600);
  box-shadow: 0 16px 40px -12px rgba(18, 102, 241, 0.7);
}

.btn-ghost {
  border-color: var(--c-line);
  color: var(--c-ink-soft);
  background: var(--c-glass);
  backdrop-filter: blur(8px);
}
.btn-ghost:hover {
  border-color: var(--c-blue-200);
  color: var(--c-blue);
  background: var(--c-surface);
}

.btn-invert {
  background: var(--c-invert-fg);
  color: var(--c-invert-bg);
}
.btn-invert:hover { background: #fff; }

/* ------------------------------------------------------------- 5. header */
.site-header {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: 100;
  border-bottom: 1px solid transparent;
  transition: background-color var(--dur-fast) linear,
              border-color var(--dur-fast) linear;
}
.site-header.is-stuck {
  background: var(--c-glass-strong);
  border-bottom-color: var(--c-line);
  backdrop-filter: saturate(1.8) blur(16px);
  -webkit-backdrop-filter: saturate(1.8) blur(16px);
}

.header-inner {
  display: flex;
  align-items: center;
  gap: 1.5rem;
  height: var(--header-h);
  transition: height var(--dur-fast) var(--ease-out);
}
.site-header.is-stuck .header-inner { height: 60px; }

.brand { display: flex; align-items: center; flex: none; }
.logo-lockup {
  height: 30px;
  width: auto;
  color: var(--c-brand);
  transition: height var(--dur-fast) var(--ease-out);
}
.site-header.is-stuck .logo-lockup { height: 26px; }

.nav { margin-inline: auto; }
.nav-list { display: flex; gap: clamp(1.1rem, 2.4vw, 2.3rem); }
.nav-list a {
  position: relative;
  font-size: var(--t-sm);
  color: var(--c-ink-soft);
  padding-block: 6px;
  transition: color var(--dur-fast) var(--ease-out);
}
.nav-list a::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 1px;
  background: var(--c-blue);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--dur) var(--ease-out);
}
.nav-list a:hover { color: var(--c-blue); }
.nav-list a:hover::after { transform: scaleX(1); }

.header-actions { display: flex; align-items: center; gap: 0.75rem; flex: none; }

.menu-toggle {
  display: none;
  width: 40px; height: 40px;
  border: 1px solid var(--c-line);
  border-radius: var(--radius-sm);
  place-items: center;
  background: var(--c-glass);
}
.menu-toggle-bars { display: grid; gap: 5px; }
.menu-toggle-bars i {
  display: block; width: 16px; height: 1.5px;
  background: var(--c-ink);
  transition: transform var(--dur-fast) var(--ease-out);
}
.menu-toggle[aria-expanded="true"] .menu-toggle-bars i:first-child {
  transform: translateY(3.25px) rotate(45deg);
}
.menu-toggle[aria-expanded="true"] .menu-toggle-bars i:last-child {
  transform: translateY(-3.25px) rotate(-45deg);
}

.mobile-nav {
  background: var(--c-glass-strong);
  backdrop-filter: blur(16px);
  border-bottom: 1px solid var(--c-line);
  padding: 0.5rem var(--gutter) 1.6rem;
}
.mobile-nav[hidden] { display: none; }
.mobile-nav li + li { border-top: 1px solid var(--c-line-soft); }
.mobile-nav a { display: block; padding: 0.95rem 0; font-size: 1.02rem; }
.mobile-nav-cta { color: var(--c-blue); font-weight: 600; }

/* ---------------------------------------------- 6. progress rail + act nav */
.progress-rail {
  position: fixed;
  inset: 0 0 auto 0;
  height: 2px;
  z-index: 120;
  background: transparent;
  pointer-events: none;
}
.progress-bar {
  display: block;
  height: 100%;
  width: 100%;
  transform: scaleX(0);
  transform-origin: left;
  background: linear-gradient(90deg, var(--c-blue-400), var(--c-blue), var(--c-deep));
  will-change: transform;
}

.act-nav {
  position: fixed;
  right: clamp(0.75rem, 2vw, 1.6rem);
  top: 50%;
  transform: translateY(-50%);
  z-index: 110;
}
.act-nav-list { display: grid; gap: 0.35rem; }
.act-dot {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 0.6rem;
  padding: 0.28rem 0;
  color: var(--c-ink-mute);
}
.act-dot-mark {
  order: 2;
  width: 8px; height: 8px;
  border-radius: 50%;
  border: 1px solid var(--c-ink-faint);
  background: transparent;
  transition: background-color var(--dur) var(--ease-out),
              border-color var(--dur) var(--ease-out),
              transform var(--dur) var(--ease-out),
              box-shadow var(--dur) var(--ease-out);
}
.act-dot-meta {
  order: 1;
  display: flex;
  align-items: baseline;
  gap: 0.4rem;
  font-size: var(--t-xs);
  white-space: nowrap;
  opacity: 0;
  transform: translateX(6px);
  transition: opacity var(--dur) var(--ease-out), transform var(--dur) var(--ease-out);
}
.act-dot-no { font-family: var(--font-mono); color: var(--c-ink-faint); }
.act-dot-label { font-weight: 500; }
.act-dot:hover { color: var(--c-blue); }
.act-dot:hover .act-dot-meta,
.act-dot.is-active .act-dot-meta { opacity: 1; transform: none; }
.act-dot:hover .act-dot-mark { border-color: var(--c-blue); }
.act-dot.is-active .act-dot-mark {
  background: var(--c-blue);
  border-color: var(--c-blue);
  transform: scale(1.5);
  box-shadow: 0 0 0 4px rgba(18, 102, 241, 0.16);
}
.act-dot.is-active { color: var(--c-blue); }

/* ------------------------------------------------- 7. hero (act 01) */
/* A single sentence, staged as two worlds.
   The viewport is split down the middle: warm earth on the left (the old
   craft), cold blue-white on the right (the new technology). A thick live
   cable is clamped across the join and the brand name is its connector.
   There is deliberately almost no body copy: the split is the argument. */

:root {
  --hero-old-bg-1:  #FDF3E0;
  --hero-old-bg-2:  #F6E3C4;
  --hero-old-ink:   #7A4A16;
  --hero-old-line:  rgba(138, 90, 43, 0.22);
  --hero-new-bg-1:  #F2F8FF;
  --hero-new-bg-2:  #DCEBFF;
  --hero-new-ink:   #0B3FA8;
  --hero-new-line:  rgba(18, 102, 241, 0.2);
  --hero-split:     50%;
}
@media (prefers-color-scheme: dark) {
  :root {
    --hero-old-bg-1: #2A1F12;
    --hero-old-bg-2: #1A1209;
    --hero-old-ink:  #F0C07A;
    --hero-old-line: rgba(240, 192, 122, 0.2);
    --hero-new-bg-1: #0A1626;
    --hero-new-bg-2: #061020;
    --hero-new-ink:  #9FD0FF;
    --hero-new-line: rgba(76, 141, 247, 0.22);
  }
}

.act--hero {
  min-height: 100vh;
  min-height: 100svh;
  /* the split bleeds past the shell so the seam reads as a division of the
     whole viewport, not of a content column */
  isolation: isolate;
}
/* the containing block for the absolutely positioned split, field and cable,
   and the block padding that keeps the type clear of the fixed header.
   This arrangement is the one that was verified to render correctly. Several
   attempts to change how the stage centres (block layout, column flex, dropping
   the shell class) each produced a worse layout, so it is deliberately kept. */
.act--hero .act-sticky {
  position: sticky;
  align-items: stretch;
  padding-block: calc(var(--header-h) + clamp(1rem, 3.5vh, 3rem)) clamp(2.5rem, 6vh, 4rem);
  overflow: hidden;
}

/* --- the two worlds ------------------------------------------------------ */
/* .split and .field are direct children of .act-sticky, which is a flex
   container. Taking them out of flow is mandatory: as flex items they claimed
   layout width and pushed the text column off-centre. */
.split {
  position: absolute;
  inset: 0;
  z-index: 0;
  display: grid;
  grid-template-columns: 1fr 1fr;
}
.split-half { position: relative; overflow: hidden; }
.split-half--old {
  background:
    radial-gradient(120% 90% at 30% 14%, var(--hero-old-bg-1), var(--hero-old-bg-2) 72%),
    var(--hero-old-bg-2);
}
.split-half--new {
  background:
    radial-gradient(120% 90% at 70% 14%, var(--hero-new-bg-1), var(--hero-new-bg-2) 72%),
    var(--hero-new-bg-2);
}

/* the old world gets a wide low sun and a coarse diagonal weave */
.split-sun {
  position: absolute;
  width: 60vw; height: 60vw;
  left: -22vw; top: -18vw;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(224, 145, 58, 0.34), transparent 66%);
  filter: blur(40px);
}
.split-grain {
  position: absolute;
  inset: 0;
  background-image: repeating-linear-gradient(
    58deg,
    var(--hero-old-line) 0 1px,
    transparent 1px 13px
  );
  opacity: 0.75;
  -webkit-mask-image: radial-gradient(90% 80% at 30% 70%, #000, transparent 78%);
  mask-image: radial-gradient(90% 80% at 30% 70%, #000, transparent 78%);
}

/* the new world gets a cold bloom and a fine technical grid */
.split-glow {
  position: absolute;
  width: 58vw; height: 58vw;
  right: -20vw; top: -14vw;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(46, 134, 255, 0.34), transparent 66%);
  filter: blur(44px);
}
.split-lines {
  position: absolute;
  inset: 0;
  background-image:
    linear-gradient(to right, var(--hero-new-line) 1px, transparent 1px),
    linear-gradient(to bottom, var(--hero-new-line) 1px, transparent 1px);
  background-size: 52px 52px;
  -webkit-mask-image: radial-gradient(90% 80% at 70% 70%, #000, transparent 76%);
  mask-image: radial-gradient(90% 80% at 70% 70%, #000, transparent 76%);
}

/* the seam itself: a hot filament where the two worlds are welded */
/* a slow warm haze rising on the earth side */
.split-heat {
  position: absolute;
  inset: 40% -10% -20% -10%;
  background: radial-gradient(60% 70% at 35% 80%, rgba(224, 145, 58, 0.3), transparent 70%);
  filter: blur(50px);
  animation: heat-drift 16s var(--ease-io) infinite alternate;
}
@keyframes heat-drift {
  from { transform: translate3d(-2%, 2%, 0) scale(1); }
  to   { transform: translate3d(3%, -3%, 0) scale(1.12); }
}

/* a cold scanline sweeping the technology side */
.split-scan {
  position: absolute;
  left: 0; right: 0;
  height: 26%;
  top: -30%;
  background: linear-gradient(
    180deg,
    transparent,
    rgba(159, 208, 255, 0.22) 45%,
    rgba(255, 255, 255, 0.32) 50%,
    rgba(159, 208, 255, 0.22) 55%,
    transparent
  );
  filter: blur(6px);
  animation: scan-sweep 9s linear infinite;
}
@keyframes scan-sweep {
  0%   { top: -30%; opacity: 0; }
  12%  { opacity: 1; }
  88%  { opacity: 1; }
  100% { top: 105%; opacity: 0; }
}

/* a dark edge at the outside of each half, so the pair reads as one solid
   object lit from the seam outward */
.split-vignette {
  position: absolute;
  inset: 0;
  background: linear-gradient(90deg, rgba(20, 12, 4, 0.12), transparent 55%);
  pointer-events: none;
}
.split-half--new .split-vignette {
  background: linear-gradient(270deg, rgba(8, 24, 52, 0.16), transparent 55%);
}

.split-seam {  position: absolute;
  left: var(--hero-split);
  top: 0; bottom: 0;
  width: 2px;
  transform: translateX(-1px);
  background: linear-gradient(
    180deg,
    transparent,
    rgba(242, 193, 78, 0.9) 22%,
    #FFFFFF 50%,
    rgba(159, 208, 255, 0.9) 78%,
    transparent
  );
  box-shadow:
    -28px 0 60px rgba(224, 145, 58, 0.4),
    28px 0 60px rgba(46, 134, 255, 0.4);
}

/* --- the particle net sits above the split, tinted per half --------------
   position:absolute is MANDATORY. `.act-sticky` is a flex row, so as an in-flow
   flex item this canvas claimed 300px of the row (its intrinsic width), which
   left the stage only 1124px of 1424 and pushed it 300px right. That single
   missing declaration was what put the slogan 150px off the viewport centre and
   made the two poles look asymmetric. */
.act--hero .field {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 1;
  opacity: 0.9;
  pointer-events: none;
}

/* --- the cable ----------------------------------------------------------- */
/* The loudest object in the act: a 46-unit armoured conductor in a 1600x260 box
   drawn 240px tall, so the stroke widths in the markup are the true rendered
   thickness. Everything here exists to make it read as live metal carrying
   current rather than as a decorative line. */
.cable {
  position: absolute;
  left: 0;
  right: 0;
  bottom: clamp(2.5rem, 9vh, 5rem);
  width: 100%;
  height: clamp(190px, 28vh, 250px);
  z-index: 2;
  pointer-events: none;
  overflow: visible;
}
/* darkens the underside so the conductor reads as a tube */
.cbl-rim { mix-blend-mode: multiply; }
.cbl-sheen { mix-blend-mode: overlay; }

/* The brand seal on the joint. Kept in HTML, NOT inside .cable: the svg is
   stretched with preserveAspectRatio="none", so any circle drawn in its user
   space turns into an ellipse on narrow screens and the three characters inside
   get squeezed. As an HTML layer it stays round and readable at every width. */
.cable-seal {
  position: absolute;
  left: 50%;
  bottom: calc(clamp(2.5rem, 9vh, 5rem) + clamp(190px, 28vh, 250px) / 2);
  transform: translate(-50%, 50%);
  z-index: 3;
  width: clamp(88px, 8.5vw, 116px);
  aspect-ratio: 1;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: #fff;
  color: var(--c-blue);
  font-size: clamp(0.82rem, 2.2vw, 1.05rem);
  font-weight: 800;
  letter-spacing: 0.04em;
  pointer-events: none;
  box-shadow:
    0 0 0 1px rgba(18, 102, 241, 0.08),
    0 18px 44px rgba(18, 102, 241, 0.28);
}
.cable-seal::before {
  content: "";
  position: absolute;
  inset: -11px;
  border-radius: 50%;
  border: 2px dashed rgba(18, 102, 241, 0.5);
}

.cbl-armour {
  stroke: rgba(255, 255, 255, 0.5);
  stroke-width: 30;
  /* pathLength=1600 is on the element: these are CSS px along a 1600px run */
  stroke-dasharray: 4 18;
  stroke-linecap: butt;
  animation: armour-crawl 2.4s linear infinite;
}
@keyframes armour-crawl {
  from { stroke-dashoffset: 0; }
  to   { stroke-dashoffset: -44; }
}

.cbl-current {
  stroke: #FFFFFF;
  stroke-width: 13;
  stroke-dasharray: 7 63;
  stroke-linecap: round;
  filter: drop-shadow(0 0 10px #FFF3C4) drop-shadow(0 0 24px rgba(255, 233, 168, 0.7));
  animation: current-run 2.1s linear infinite;
}
/* a second stream, offset, so the flow never looks like one blinking dash */
.cbl-current--b {
  stroke-width: 7;
  stroke-dasharray: 4 46;
  opacity: 0.75;
  animation-duration: 1.35s;
  animation-delay: -0.6s;
  filter: drop-shadow(0 0 8px rgba(207, 230, 255, 0.9));
}
@keyframes current-run {
  from { stroke-dashoffset: 100; }
  to   { stroke-dashoffset: 0; }
}

/* the discharge: a fork that fires in bursts where the two worlds meet */
.cbl-arc path {
  fill: none;
  stroke: #FFFFFF;
  stroke-linejoin: miter;
  stroke-linecap: round;
  filter: url(#cblArcGlow)
          drop-shadow(0 0 12px #FFE9A8)
          drop-shadow(0 0 28px rgba(46, 134, 255, 0.85));
}
.cbl-arc-main { stroke-width: 7; animation: arc-flicker 1.1s steps(3, end) infinite; }
.cbl-arc-fork { stroke-width: 4; animation: arc-flicker 1.1s steps(3, end) infinite; }
.cbl-arc-sub  { stroke-width: 3; animation: arc-flicker 1.1s steps(3, end) infinite 0.4s; }
@keyframes arc-flicker {
  0%, 100% { opacity: 0; }
  7%       { opacity: 1; }
  13%      { opacity: 0.15; }
  20%      { opacity: 1; }
  28%      { opacity: 0.1; }
  34%      { opacity: 0.9; }
  44%      { opacity: 0; }
  71%      { opacity: 0.8; }
  80%      { opacity: 0; }
}

/* sparks thrown off along the run */
.cbl-spark {
  fill: #FFFFFF;
  filter: drop-shadow(0 0 12px #FFE9A8) drop-shadow(0 0 26px rgba(46, 134, 255, 0.6));
  animation: spark-pop 1.9s var(--ease-out) infinite;
}
.cbl-spark--2 { animation-delay: 0.35s; }
.cbl-spark--3 { animation-delay: 0.9s; }
.cbl-spark--4 { animation-delay: 1.35s; }
.cbl-spark--5 { animation-delay: 0.65s; }
@keyframes spark-pop {
  0%, 100% { transform: scale(0.35); opacity: 0; }
  26%      { transform: scale(1); opacity: 1; }
  52%      { transform: scale(0.6); opacity: 0.35; }
  70%      { transform: scale(0.4); opacity: 0; }
}

/* --- the joint: the brand name is what holds the two halves together ---- */
.cbl-joint-ring {
  fill: none;
  stroke: var(--c-blue);
  stroke-width: 2.4;
  stroke-dasharray: 8 10;
  transform-origin: 800px 130px;
  animation: orbit-spin 22s linear infinite;
}
.cbl-joint-ring--2 {
  stroke: #E0913A;
  stroke-dasharray: 5 13;
  animation-duration: 14s;
  animation-direction: reverse;
}
.cbl-joint-disc {
  fill: var(--c-surface);
  stroke: var(--c-glass-line);
  stroke-width: 2;
  filter: drop-shadow(0 0 26px rgba(255, 246, 216, 0.75))
          drop-shadow(0 0 60px rgba(46, 134, 255, 0.4));
}
.cbl-joint-text {
  font-family: var(--font-sans);
  font-size: 42px;
  font-weight: 900;
  letter-spacing: -0.02em;
  stroke: none;
  fill: var(--c-blue);
}

/* short viewports: shrink uniformly so the stroke weight stays honest */
@media (max-height: 760px) {
  .cable { height: 170px; }
}
@media (max-height: 620px) {
  .cable { height: 140px; }
}

/* --- the words ----------------------------------------------------------- */
/* One centred column. The stage is the shell element, sized by the flex parent;
   the poles sit at the two ends of its content box so each lands inside its own
   half of the split, with the cable's joint on the seam. */
.hero-stage {
  position: relative;
  z-index: 3;
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  text-align: center;
  gap: clamp(0.8rem, 2.4vh, 2rem);
  /* reserves the band the cable runs through, plus clearance for its bloom */
  padding-bottom: clamp(10rem, 22vh, 13rem);
}

/* the two poles: each owns one half of the split.
   A two-column grid, NOT flex+space-between: flex let the two words collide on
   narrow screens because the row shrink-to-fit, while a 1fr/1fr grid always
   holds the intended geometry. */
.poles {
  width: 100%;
  display: grid;
  grid-template-columns: 1fr 1fr;
  align-items: baseline;
  gap: 1rem;
}
.pole--old { justify-self: start; }
.pole--new { justify-self: end; }
.pole {
  font-size: clamp(3.4rem, 13.5vw, 12rem);
  line-height: 0.82;
  letter-spacing: -0.06em;
  font-weight: 900;
}
/* the old world: stamped and warm, with a chiselled highlight above it */
.pole--old {
  color: var(--hero-old-ink);
  text-shadow:
    0 1px 0 rgba(255, 255, 255, 0.55),
    0 -1px 0 rgba(88, 52, 12, 0.35),
    0 18px 44px rgba(138, 90, 43, 0.28);
}
/* the new world: a bright gradient with a cold bloom behind it */
.pole--new {
  background-image: linear-gradient(
    100deg,
    #6FB3FF 0%,
    var(--c-blue) 38%,
    #0A3AA8 76%,
    #12408F 100%
  );
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
  filter:
    drop-shadow(0 0 24px rgba(76, 141, 247, 0.55))
    drop-shadow(0 10px 40px rgba(18, 102, 241, 0.35));
}

/* the sentence, once and quietly: the poles are the shout */
.hero-cta { display: none; }

.hero-line {
  margin: 0;
  font-size: clamp(1rem, 0.8rem + 0.9vw, 1.5rem);
  font-weight: 560;
  letter-spacing: 0.42em;
  /* letter-spacing adds space after the last glyph; pull it back to stay centred */
  text-indent: 0.42em;
  color: var(--c-ink-soft);
  text-wrap: balance;
}
.hero-line::before,
.hero-line::after {
  content: "";
  display: inline-block;
  width: clamp(18px, 4vw, 54px);
  height: 1px;
  vertical-align: middle;
  background: currentColor;
  opacity: 0.35;
}
.hero-line::before { margin-right: 0.5em; }
.hero-line::after { margin-left: 0.5em; }

@media (prefers-reduced-motion: reduce) {
  .cbl-armour, .cbl-current, .cbl-spark, .cbl-arc path,
  .cbl-joint-ring { animation: none; }
  .cbl-arc path { opacity: 1; }
}


/* ===== restored: cursor + scroll hint (lost in the hero rewrite) ========= */
.cursor,
.cursor-dot {
  position: fixed;
  top: 0; left: 0;
  z-index: 200;
  pointer-events: none;
  border-radius: 50%;
  opacity: 0;
  transition: opacity 0.3s linear;
}
.cursor {
  width: 34px; height: 34px;
  margin: -17px 0 0 -17px;
  border: 1px solid var(--c-blue);
  transition: opacity 0.3s linear,
              width 0.35s var(--ease-out),
              height 0.35s var(--ease-out),
              margin 0.35s var(--ease-out),
              background-color 0.35s var(--ease-out),
              border-color 0.35s var(--ease-out);
}
.cursor-dot {
  width: 5px; height: 5px;
  margin: -2.5px 0 0 -2.5px;
  background: var(--c-blue);
}
.cursor.is-on,
.cursor-dot.is-on { opacity: 1; }
.cursor.is-active {
  width: 62px; height: 62px;
  margin: -31px 0 0 -31px;
  background: rgba(18, 102, 241, 0.1);
  border-color: var(--c-blue-400);
}
.cursor.is-press { width: 24px; height: 24px; margin: -12px 0 0 -12px; }
.cursor.is-link { width: 48px; height: 48px; margin: -24px 0 0 -24px; }
@media (hover: none), (pointer: coarse) {
  .cursor, .cursor-dot { display: none; }
}

.scroll-hint {
  /* Absolute, not fixed: it is a hero affordance and must scroll away with the
     hero. As `fixed` it stayed pinned and reappeared at the bottom of the page.
     Anchored bottom-RIGHT because the cable now owns the bottom centre. */
  position: absolute;
  right: var(--gutter);
  bottom: clamp(1rem, 3vh, 2rem);
  z-index: 4;
  display: flex;
  align-items: center;
  gap: 0.7rem;
  font-size: var(--t-xs);
  letter-spacing: 0.18em;
  color: var(--c-ink-mute);
  transition: color var(--dur-fast) var(--ease-out);
}
.scroll-hint:hover { color: var(--c-blue); }
.scroll-hint-text { font-weight: 500; }
.scroll-hint-line {
  width: 38px;
  height: 1px;
  background: linear-gradient(to right, transparent, var(--c-blue));
  animation: hint-pulse 2.2s var(--ease-io) infinite;
  transform-origin: left;
}
@keyframes hint-pulse {
  0%, 100% { transform: scaleX(0.35); opacity: 0.4; }
  50%      { transform: scaleX(1);    opacity: 1; }
}

/* ------------------------------------------------ 8. about (act 02) */
.act--about .act-sticky {
  align-items: center;
  background:
    radial-gradient(60% 50% at 18% 22%, rgba(76, 141, 247, 0.08), transparent 68%);
}
.act-shell { display: grid; }

.pillars {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1px;
  background: var(--c-line);
  border: 1px solid var(--c-line);
  border-radius: var(--radius-lg);
  overflow: hidden;
}
.pillar {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  padding: clamp(1.4rem, 2vw, 2rem);
  background: var(--c-surface);
  transition: background-color var(--dur) var(--ease-out);
}
.pillar::before {
  content: "";
  position: absolute;
  inset: 0 0 auto 0;
  height: 2px;
  background: linear-gradient(90deg, var(--c-blue-400), var(--c-blue));
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--dur-slow) var(--ease-out);
}
.pillar:hover::before { transform: scaleX(1); }
.pillar:hover { background: var(--c-bg); }
.pillar-tag {
  align-self: flex-start;
  font-size: var(--t-xs);
  letter-spacing: 0.14em;
  color: var(--c-blue);
  padding: 0.22rem 0.6rem;
  border-radius: 999px;
  background: var(--c-blue-050);
  border: 1px solid var(--c-glass-line);
}
.pillar-title {
  font-size: clamp(1.05rem, 0.95rem + 0.4vw, 1.3rem);
  font-weight: 620;
  letter-spacing: -0.014em;
}
.pillar-desc {
  font-size: var(--t-sm);
  line-height: 1.76;
  color: var(--c-ink-soft);
  text-wrap: pretty;
}

.facts {
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: 1rem;
  margin-top: clamp(1.4rem, 3vh, 2.2rem);
  padding-top: 1.4rem;
  border-top: 1px solid var(--c-line);
}
.fact-k {
  font-size: var(--t-xs);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--c-ink-mute);
}
.fact-v {
  margin-top: 0.3rem;
  font-size: clamp(0.98rem, 0.9rem + 0.35vw, 1.15rem);
  font-weight: 560;
  letter-spacing: -0.01em;
  color: var(--c-ink);
}

/* ------------------------------------------------ 9. belief (act 03) */
.act--belief .act-sticky {
  background:
    linear-gradient(180deg, transparent, var(--c-surface-2) 28%, var(--c-surface-2) 72%, transparent);
}
.act-head--center {
  text-align: center;
  max-width: 46rem;
  margin-inline: auto;
}
.act-eyebrow--center { justify-content: center; }
.act-lede--center { margin-inline: auto; }

.contrast {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr) 1px minmax(0, 1fr);
  gap: clamp(1.2rem, 3vw, 3rem);
  align-items: start;
}
.contrast-side {
  display: grid;
  gap: 1rem;
  padding: clamp(1.2rem, 2vw, 1.7rem);
  border-radius: var(--radius-lg);
  border: 1px solid transparent;
  transition: border-color var(--dur) var(--ease-out),
              background-color var(--dur) var(--ease-out),
              box-shadow var(--dur) var(--ease-out);
}
.contrast-side--before { color: var(--c-ink-mute); }
.contrast-side--before:hover {
  border-color: var(--c-line);
  background: var(--c-glass);
}
.contrast-side--after { color: var(--c-ink); }
.contrast-side--after:hover {
  border-color: var(--c-glass-line);
  background: var(--c-glass);
  box-shadow: var(--shadow);
}
.contrast-head { display: flex; align-items: center; gap: 0.6rem; }
.contrast-dot {
  width: 8px; height: 8px;
  border-radius: 50%;
  flex: none;
  background: var(--c-ink-faint);
}
.contrast-side--after .contrast-dot {
  background: var(--c-blue);
  box-shadow: 0 0 0 4px rgba(18, 102, 241, 0.16);
}
.contrast-label {
  font-size: var(--t-sm);
  font-weight: 600;
  letter-spacing: 0.06em;
  color: inherit;
}
.contrast-list { display: grid; gap: 0.7rem; }
.contrast-item {
  display: flex;
  gap: 0.7rem;
  font-size: var(--t-sm);
  line-height: 1.7;
  color: var(--c-ink-soft);
}
.contrast-mark {
  flex: none;
  width: 14px; height: 1px;
  margin-top: 0.72rem;
  background: currentColor;
  opacity: 0.5;
}
.contrast-side--after .contrast-item { color: var(--c-ink); }
.contrast-side--after .contrast-mark {
  background: var(--c-blue);
  opacity: 1;
}

.contrast-divider {
  position: relative;
  align-self: stretch;
  background: var(--c-line);
  overflow: hidden;
}
/* a bar of blue that sweeps down the divider as the act progresses */
.contrast-sweep {
  position: absolute;
  inset: 0 0 auto 0;
  height: 100%;
  transform: scaleY(0);
  transform-origin: top;
  background: linear-gradient(180deg, var(--c-blue-400), var(--c-blue));
}

.belief-statement {
  position: relative;
  margin-top: clamp(1.6rem, 4vh, 2.6rem);
  padding-left: clamp(1.2rem, 3vw, 2.4rem);
  font-size: clamp(1.05rem, 0.9rem + 1vw, 1.7rem);
  line-height: 1.55;
  letter-spacing: -0.018em;
  color: var(--c-ink);
  max-width: 46ch;
  text-wrap: pretty;
}
.belief-quote {
  position: absolute;
  left: 0; top: 0.1em;
  width: 3px;
  height: 1.4em;
  border-radius: 2px;
  background: linear-gradient(180deg, var(--c-blue-400), var(--c-blue));
}

/* ------------------------------------------------- 10. scope (act 04) */
.act--scope .act-sticky {
  align-items: center;
  background:
    radial-gradient(70% 60% at 82% 18%, rgba(18, 102, 241, 0.09), transparent 66%);
}
.scope-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(0.8rem, 1.4vw, 1.2rem);
}
.scope-item {
  position: relative;
  padding: clamp(1.1rem, 1.8vw, 1.6rem);
  border-radius: var(--radius-lg);
  border: 1px solid var(--c-line);
  background: var(--c-surface);
  opacity: 0.5;
  transition: opacity 0.6s var(--ease-out),
              border-color 0.6s var(--ease-out),
              box-shadow 0.6s var(--ease-out),
              transform 0.6s var(--ease-out),
              background-color 0.6s var(--ease-out);
}
.scope-item.is-live {
  opacity: 1;
  border-color: var(--c-glass-line);
  background: var(--c-surface);
  box-shadow: var(--shadow-sm);
}
.scope-item:hover {
  transform: translateY(-3px);
  box-shadow: var(--shadow);
  border-color: var(--c-glass-line);
}
.scope-item-no {
  display: block;
  width: 22px; height: 2px;
  border-radius: 2px;
  background: var(--c-blue-200);
  margin-bottom: 0.9rem;
  transition: background-color var(--dur) var(--ease-out), width var(--dur) var(--ease-out);
}
.scope-item.is-live .scope-item-no { background: var(--c-blue); width: 34px; }
.scope-item-title {
  font-size: clamp(0.98rem, 0.9rem + 0.35vw, 1.15rem);
  font-weight: 600;
  letter-spacing: -0.012em;
  margin-bottom: 0.35rem;
}
.scope-item-desc {
  font-size: var(--t-sm);
  line-height: 1.7;
  color: var(--c-ink-soft);
}
.scope-note {
  margin-top: clamp(1rem, 2.5vh, 1.6rem);
  font-size: var(--t-xs);
  color: var(--c-ink-faint);
}

/* ----------------------------------------------- 11. product (act 05) */
/* The plan IS the explanation. The four steps are the four physical parts of
   the system and each one is a numbered marker on the drawing, so the act needs
   only one row of content. That is what makes it fit the viewport — the old
   second row of step cards is what overflowed by 143px. */
.act--product .act-sticky { align-items: center; }

.plan-head { margin-bottom: clamp(0.8rem, 2.2vh, 1.6rem); }
.plan-head .act-title { font-size: clamp(1.7rem, 1rem + 2.6vw, 3.2rem); }
.plan-head .act-lede { margin-top: 0.8rem; max-width: 64ch; }

.plan-body {
  display: grid;
  grid-template-columns: minmax(0, 0.86fr) minmax(0, 1fr);
  gap: clamp(1.4rem, 3vw, 3rem);
  align-items: center;
}

/* --- the four steps, collapsed except the active one -------------------- */
.plan-steps { display: grid; gap: 2px; }
.plan-step {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: 0.85rem;
  padding: 0.7rem 0.9rem;
  border-radius: var(--radius);
  transition: background-color var(--dur) var(--ease-out),
              box-shadow var(--dur) var(--ease-out);
}
.plan-step-no {
  display: grid;
  place-items: center;
  width: 30px; height: 30px;
  flex: none;
  border-radius: 50%;
  font-family: var(--font-mono);
  font-size: var(--t-xs);
  color: var(--c-ink-mute);
  border: 1px solid var(--c-line);
  background: var(--c-surface);
  transition: color var(--dur) var(--ease-out),
              background-color var(--dur) var(--ease-out),
              border-color var(--dur) var(--ease-out);
}
/* min-width:0 is required: a grid child defaults to min-content width, which
   would let a long description push the column past its track */
.plan-step-main { min-width: 0; }
.plan-step-title {
  font-size: clamp(1rem, 0.92rem + 0.35vw, 1.2rem);
  font-weight: 600;
  letter-spacing: -0.012em;
  color: var(--c-ink-mute);
  transition: color var(--dur) var(--ease-out);
}
/* grid-template-rows 0fr -> 1fr is the reliable way to animate to auto height */
.plan-step-more {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows 0.5s var(--ease-out);
}
.plan-step-more-in { overflow: hidden; }
.plan-step-desc {
  margin-top: 0.4rem;
  font-size: var(--t-sm);
  line-height: 1.7;
  color: var(--c-ink-soft);
}
.plan-step .chips { margin-top: 0.6rem; }

.plan-step.is-active { background: var(--c-surface); box-shadow: var(--shadow-sm); }
.plan-step.is-active .plan-step-no {
  background: var(--c-blue);
  border-color: var(--c-blue);
  color: #fff;
}
.plan-step.is-active .plan-step-title { color: var(--c-ink); }
.plan-step.is-active .plan-step-more { grid-template-rows: 1fr; }

/* --- the drawing --------------------------------------------------------- */
.plan-figure { position: relative; display: grid; place-items: center; }
.plan {
  width: 100%;
  height: auto;
  /* Capped so head + drawing fit one viewport. Measured: at 56vh the sticky box
     came to 828px in an 805px viewport, so its bottom 23px was unreachable. */
  max-height: min(48vh, 400px);
  overflow: visible;
  color: var(--c-blue);
}

.plan-ground { fill: var(--c-surface); stroke: var(--c-line); stroke-width: 1.5; }
.plan-lawn { color: var(--c-blue); }

.plan-house rect { fill: var(--c-surface-2); stroke: var(--c-line); stroke-width: 1.6; }
.plan-house path { fill: none; stroke: var(--c-line); stroke-width: 1.2; }
.plan-door { fill: var(--c-surface); }

.plan-patio { fill: none; stroke: var(--c-line); stroke-width: 1.2; stroke-dasharray: 5 4; }
.plan-pond { stroke: var(--c-blue-200); stroke-width: 1.2; }

/* the walkway and gate give the plot a readable entrance */
.plan-path {
  fill: none;
  stroke: var(--c-line-soft);
  stroke-width: 14;
  stroke-linecap: round;
}
.plan-gate path { stroke: var(--c-blue-200); stroke-width: 1.6; fill: none; }
.plan-hedge {
  stroke: color-mix(in srgb, var(--c-blue) 16%, transparent);
  stroke-width: 10;
  stroke-linecap: round;
  fill: none;
}

.plan-tree circle {
  fill: color-mix(in srgb, var(--c-blue) 9%, transparent);
  stroke: var(--c-blue-200);
  stroke-width: 1.2;
}
.plan-tree path { stroke: var(--c-line); stroke-width: 2; }

.plan-host rect:first-child {
  fill: var(--c-surface);
  stroke: var(--c-blue);
  stroke-width: 1.8;
}
.plan-host-band { fill: var(--c-blue-200); stroke: none; }
.plan-host-led {
  fill: var(--c-blue);
  stroke: none;
  animation: host-blink 2.4s steps(2, end) infinite;
}
@keyframes host-blink {
  0%, 60%   { opacity: 1; }
  61%, 100% { opacity: 0.25; }
}

/* the pipe loop around the perimeter */
.plan-pipe-halo {
  fill: none;
  stroke: var(--c-blue);
  stroke-width: 9;
  opacity: 0.12;
  filter: blur(3px);
}
.plan-pipe-line {
  fill: none;
  stroke: var(--c-blue);
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-dasharray: 100;
  stroke-dashoffset: 100;
}
.plan-pipe-spur {
  fill: none;
  stroke: var(--c-blue);
  stroke-width: 2;
  stroke-dasharray: 4 4;
  opacity: 0.55;
}

/* nozzles and coverage */
.nozzle-ring { fill: none; stroke: var(--c-blue); stroke-width: 1.2; opacity: 0.5; }
.nozzle-dot { fill: var(--c-surface); stroke: var(--c-blue); stroke-width: 2; }
.nozzle-pulse { fill: var(--c-blue); opacity: 0; }
/* the cones are the one thing that says "this covers the yard", so they are
   deliberately strong enough to read at a glance */
.plan-mist { opacity: 0.9; }
/* the script scales this one node to breathe the whole coverage */
.mist { transform-origin: 360px 280px; }

.plan-iot rect:first-child {
  fill: var(--c-surface);
  stroke: var(--c-blue);
  stroke-width: 1.6;
}
.plan-iot-screen { fill: var(--c-blue-050); stroke: none; }
.plan-iot-row { fill: none; stroke: var(--c-blue-200); stroke-width: 2; }
.plan-iot-home { fill: var(--c-blue-200); stroke: none; }

/* callout markers — dimmed when inactive, but never below "readable", because
   they are the whole point of the drawing */
.plan-mark { opacity: 0.55; transition: opacity 0.5s var(--ease-out); }
.plan-mark-disc {
  fill: var(--c-surface);
  stroke: var(--c-blue);
  stroke-width: 2;
}
.plan-mark-no {
  font-family: var(--font-mono);
  font-size: 15px;
  font-weight: 700;
  fill: var(--c-blue);
  stroke: none;
}
.plan-mark.is-active { opacity: 1; }
.plan-mark.is-active .plan-mark-disc {
  fill: var(--c-blue);
  stroke: var(--c-blue);
  filter: drop-shadow(0 0 6px rgba(18, 102, 241, 0.55));
}
.plan-mark.is-active .plan-mark-no { fill: #fff; }

/* --- the resident dragonfly --------------------------------------------- */
.dragonfly { color: var(--c-deep); }
.dragonfly-body { stroke: currentColor; stroke-width: 2.4; stroke-linecap: round; }
.dragonfly-eye { fill: currentColor; }
.dragonfly-wing ellipse {
  fill: color-mix(in srgb, var(--c-blue) 22%, transparent);
  stroke: currentColor;
  stroke-width: 1;
  transform-box: fill-box;
  transform-origin: right center;
  animation: wing-beat-hind 0.34s var(--ease-io) infinite alternate;
}
.dragonfly-wing--fore ellipse {
  transform-origin: left center;
  animation-name: wing-beat-fore;
  animation-duration: 0.34s;
}
.dragonfly-wing--hind ellipse:nth-child(2) { animation-delay: 0.06s; }
.dragonfly-wing--fore ellipse:nth-child(2) { animation-delay: 0.06s; }
@keyframes wing-beat-fore {
  from { transform: rotate(-3deg) scaleY(1); }
  to   { transform: rotate(-13deg) scaleY(0.62); }
}
@keyframes wing-beat-hind {
  from { transform: rotate(3deg) scaleY(1); }
  to   { transform: rotate(13deg) scaleY(0.62); }
}

/* --- chips, shared with the plan steps ---------------------------------- */
.chips { display: flex; flex-wrap: wrap; gap: 0.4rem; }
.chip {
  font-size: var(--t-xs);
  letter-spacing: 0.05em;
  color: var(--c-ink-mute);
  padding: 0.26rem 0.64rem;
  border: 1px solid var(--c-line);
  border-radius: 999px;
  background: var(--c-surface-2);
}

/* ------------------------------------------------- 13. formula */
.act--formula .act-sticky {
  background:
    linear-gradient(180deg, transparent, var(--c-surface-2) 30%, var(--c-surface-2) 70%, transparent);
}
.formula-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.35fr) minmax(0, 0.65fr);
  gap: clamp(2rem, 4vw, 4rem);
  align-items: start;
}
.ingredients {
  border-top: 1px solid var(--c-line);
}
.ingredient {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: 1.1rem;
  padding: clamp(0.9rem, 1.8vh, 1.35rem) 0;
  border-bottom: 1px solid var(--c-line);
  transition: padding-inline var(--dur) var(--ease-out),
              background-color var(--dur) var(--ease-out);
}
.ingredient:hover {
  padding-inline: 0.8rem;
  background: var(--c-glass);
  border-radius: var(--radius);
}
.ingredient-marker {
  width: 9px; height: 9px;
  border-radius: 50%;
  border: 2px solid var(--c-blue-200);
  transition: border-color var(--dur) var(--ease-out),
              box-shadow var(--dur) var(--ease-out);
}
.ingredient:hover .ingredient-marker {
  border-color: var(--c-blue);
  box-shadow: 0 0 0 4px rgba(18, 102, 241, 0.14);
}
.ingredient-name {
  display: block;
  font-size: clamp(1.05rem, 0.9rem + 0.5vw, 1.35rem);
  font-weight: 580;
  letter-spacing: -0.014em;
}
.ingredient-latin {
  display: block;
  margin-top: 0.18rem;
  font-family: var(--font-serif);
  font-style: italic;
  font-size: var(--t-sm);
  color: var(--c-ink-mute);
}
.ingredient-note {
  font-size: var(--t-xs);
  letter-spacing: 0.08em;
  color: var(--c-blue);
  white-space: nowrap;
}

.formula-aside { display: grid; gap: 1.4rem; }
.formula-badge {
  display: grid;
  gap: 0.5rem;
  padding: 1.7rem;
  border-radius: var(--radius-lg);
  border: 1px solid var(--c-glass-line);
  background: var(--c-glass);
  backdrop-filter: blur(10px);
  box-shadow: var(--shadow);
}
.formula-badge-label {
  font-size: var(--t-xs);
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--c-ink-mute);
}
.formula-badge-value {
  font-family: var(--font-serif);
  font-size: clamp(1.5rem, 1.1rem + 1.6vw, 2.2rem);
  color: var(--c-blue);
  letter-spacing: -0.01em;
}
.formula-note {
  font-size: var(--t-xs);
  line-height: 1.7;
  color: var(--c-ink-faint);
  padding-left: 1rem;
  border-left: 2px solid var(--c-line);
}

/* ---------------------------------------------------- 14. scenes */
/* Four plots at ONE scale. A square's side is proportional to the square root
   of its area, so the visible size difference IS the area difference — the
   drawing carries the claim instead of a caption asserting it. */
.act--scenes .act-sticky {
  background: linear-gradient(180deg, transparent, rgba(76, 141, 247, 0.06) 42%, transparent);
}
.scale-row {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  /* bottom-align: every label sits on one ground line and the plots grow up */
  align-items: end;
  gap: clamp(1rem, 2.2vw, 2.2rem);
  margin-top: clamp(1.2rem, 3vh, 2.4rem);
}
.scale-item {
  display: grid;
  gap: 0.85rem;
  justify-items: start;
}
.scale-plot {
  position: relative;
  width: var(--side, 200px);
  height: var(--side, 200px);
  max-width: 100%;
  display: grid;
  place-items: center;
  border: 1.5px solid var(--c-blue-200);
  border-radius: 6px;
  background: color-mix(in srgb, var(--c-blue) 5%, transparent);
  transition: border-color 0.5s var(--ease-out),
              background-color 0.5s var(--ease-out),
              box-shadow 0.5s var(--ease-out);
}
/* the dashed inset reads as the pipe perimeter drawn inside each plot */
.scale-plot-pipe {
  position: absolute;
  inset: 7px;
  border: 1px dashed var(--c-blue-200);
  border-radius: 4px;
  opacity: 0.75;
}
.scale-plot-area {
  position: relative;
  font-family: var(--font-mono);
  font-size: clamp(0.85rem, 1.3vw, 1.3rem);
  font-weight: 600;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
  color: var(--c-blue);
}
.scale-plot-area i {
  font-style: normal;
  font-size: 0.62em;
  margin-left: 0.15em;
  opacity: 0.7;
}
.scale-item.is-live .scale-plot {
  border-color: var(--c-blue);
  background: var(--c-blue-050);
  box-shadow: 0 0 0 4px rgba(18, 102, 241, 0.1);
}
.scale-meta { display: grid; gap: 0.15rem; }
.scale-tag {
  font-size: var(--t-xs);
  letter-spacing: 0.1em;
  color: var(--c-blue);
}
.scale-title {
  font-size: clamp(0.95rem, 0.88rem + 0.3vw, 1.15rem);
  font-weight: 620;
  letter-spacing: -0.012em;
}
.scale-desc {
  font-size: var(--t-xs);
  line-height: 1.6;
  color: var(--c-ink-soft);
}

/* --------------------------------------------------- 15. closing */
/* the page resolves from light into deep blue */
.act--closing .act-sticky {
  background:
    linear-gradient(180deg, transparent 0%, rgba(76, 141, 247, 0.07) 55%, rgba(10, 42, 94, 0.1) 100%);
  /* the default act padding made this sticky box 831px in an 805px viewport, so
     its bottom 26px was never reachable. The card supplies its own inset, so
     the outer padding can be tighter here. */
  padding-block: clamp(2rem, 4.5vh, 3.5rem);
}
/* the closing card is deep blue, so the accents must flip to stay visible */
.act--closing { color: var(--c-blue-200); }
.act--closing .act-ghost { opacity: 0.07; color: var(--c-blue-200); }
.act--closing .act-accent { color: var(--c-blue-200); }
.act--closing .act-accent--ring { opacity: 0.16; }
.act--closing .act-accent--dots { opacity: 0.12; }
.act--closing .act-accent--cross { opacity: 0.2; }
.closing-card {
  position: relative;
  overflow: hidden;
  border-radius: var(--radius-xl);
  background:
    radial-gradient(120% 90% at 78% 12%, rgba(18, 102, 241, 0.42), transparent 62%),
    linear-gradient(155deg, var(--c-deep) 0%, var(--c-invert-bg) 55%, var(--c-deep-2) 100%);
  color: var(--c-invert-fg);
  padding: clamp(2.2rem, 1.4rem + 5vw, 5.5rem);
  isolation: isolate;
  box-shadow: var(--shadow-lg);
}
.closing-atmos { position: absolute; inset: 0; z-index: -1; }
.closing-halo {
  position: absolute;
  border-radius: 50%;
  filter: blur(70px);
}
.closing-halo--a {
  width: 40vw; height: 40vw;
  top: -30%; right: -8%;
  background: radial-gradient(circle, rgba(76, 141, 247, 0.5), transparent 68%);
}
.closing-halo--b {
  width: 30vw; height: 30vw;
  bottom: -34%; left: 6%;
  background: radial-gradient(circle, rgba(169, 200, 251, 0.24), transparent 70%);
}
.closing-body { position: relative; z-index: 1; }
.closing-title {
  font-size: var(--t-act);
  line-height: 1.08;
  letter-spacing: -0.03em;
  font-weight: 650;
  max-width: 22ch;
}
.closing-lede {
  margin-top: 1.2rem;
  font-size: var(--t-lede);
  line-height: 1.76;
  color: var(--c-invert-mute);
  max-width: 48ch;
  text-wrap: pretty;
}
/* the contacts, repeated in the closing act where the decision happens.
   Styled for the deep-blue card, so the tokens are the invert set. */
.close-contacts {
  display: flex;
  flex-wrap: wrap;
  gap: clamp(0.9rem, 2vw, 2.2rem);
  margin-top: clamp(1.4rem, 3vh, 2.2rem);
}
.close-contact { display: grid; gap: 0.15rem; }
.close-contact a {
  display: flex;
  align-items: baseline;
  gap: 0.65rem;
  flex-wrap: wrap;
  transition: color var(--dur-fast) var(--ease-out);
}
.close-contact-name {
  font-size: var(--t-sm);
  font-weight: 600;
  color: var(--c-invert-fg);
}
.close-contact-tel {
  font-family: var(--font-mono);
  font-size: clamp(1.05rem, 0.9rem + 0.5vw, 1.4rem);
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.01em;
  color: var(--c-blue-200);
  transition: color var(--dur-fast) var(--ease-out);
}
.close-contact a:hover .close-contact-tel {
  color: #fff;
  text-decoration: underline;
  text-underline-offset: 4px;
}
.close-contact-note {
  font-size: var(--t-xs);
  color: var(--c-invert-mute);
}

.closing-actions { margin-top: 2.1rem; }
.closing-support {
  margin-top: 1rem;
  font-size: var(--t-xs);
  letter-spacing: 0.1em;
  color: var(--c-invert-mute);
}
.closing-mark {
  position: absolute;
  right: clamp(-4rem, -2rem - 6vw, -1rem);
  bottom: clamp(-4rem, -2rem - 6vw, -1rem);
  width: clamp(220px, 30vw, 430px);
  color: var(--c-blue-200);
  opacity: 0.14;
  z-index: 0;
  pointer-events: none;
}
.closing-mark .logo-mark { width: 100%; height: auto; }

/* ---------------------------------------------------- 16. footer */
.site-footer {
  position: relative;
  border-top: 1px solid var(--c-line);
  padding-block: clamp(2.5rem, 2rem + 3vw, 4.5rem);
  background: var(--c-bg);
}
.footer-inner {
  display: grid;
  grid-template-columns: minmax(0, 1.25fr) minmax(0, 0.8fr) minmax(0, 1.1fr);
  gap: clamp(1.8rem, 3vw, 3rem);
  align-items: start;
}
.footer-brand .logo-lockup { height: 32px; color: var(--c-brand); }
.footer-company {
  margin-top: 1rem;
  font-size: var(--t-sm);
  color: var(--c-ink-mute);
  max-width: 26ch;
}
.footer-nav ul { display: grid; gap: 0.6rem; }
.footer-nav a {
  font-size: var(--t-sm);
  color: var(--c-ink-soft);
  transition: color var(--dur-fast) var(--ease-out);
}
.footer-nav a:hover { color: var(--c-blue); }
.footer-contact-block { display: grid; gap: 0.85rem; align-content: start; }
.footer-contact-label {
  font-size: var(--t-xs);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--c-ink-mute);
}
.footer-contacts { display: grid; gap: 0.7rem; }
.contact { display: grid; gap: 0.1rem; }
.contact-tel {
  display: flex;
  align-items: baseline;
  gap: 0.6rem;
  flex-wrap: wrap;
  transition: color var(--dur-fast) var(--ease-out);
}
.contact-name {
  font-size: var(--t-sm);
  font-weight: 600;
  color: var(--c-ink);
}
.contact-number {
  font-family: var(--font-mono);
  font-size: 1.05rem;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.01em;
  color: var(--c-blue);
  transition: color var(--dur-fast) var(--ease-out);
}
.contact-tel:hover .contact-number { color: var(--c-blue-600); }
/* underline the number on hover, so it reads as tappable */
.contact-tel:hover .contact-number { text-decoration: underline; text-underline-offset: 3px; }
.contact-note {
  font-size: var(--t-xs);
  color: var(--c-ink-faint);
}

.footer-copy {
  grid-column: 1 / -1;
  margin-top: clamp(1.2rem, 2.5vh, 2rem);
  padding-top: 1.2rem;
  border-top: 1px solid var(--c-line);
  font-size: var(--t-xs);
  color: var(--c-ink-mute);
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1.25rem;
  align-items: baseline;
}

.footer-icp {
  color: inherit;
  text-decoration: none;
}

.footer-icp:hover,
.footer-icp:focus-visible {
  color: var(--c-blue);
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* ---------------------------------------------------- 17. reveal */
.js [data-reveal] {
  opacity: 0;
  transform: translateY(20px);
  transition: opacity 0.8s var(--ease-out), transform 0.8s var(--ease-out);
  transition-delay: var(--reveal-delay, 0ms);
}
.js [data-reveal].is-in { opacity: 1; transform: none; }

/* elements that the narrative script drives get their own transform channel */
.js [data-parallax] { will-change: transform; }

/* -------------------------------------------------- 18. responsive */
/* Rewritten for the current markup only. Rules for deleted features were
   removed rather than left behind, so behaviour at every breakpoint is
   traceable to something that still exists. */

@media (max-width: 1200px) {
  .plan-body { grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr); }
  .plan { max-height: min(46vh, 380px); }
  .scale-row { gap: clamp(0.8rem, 1.6vw, 1.6rem); }
}

@media (max-width: 1024px) {
  .act-nav { display: none; }
  .formula-grid { grid-template-columns: 1fr; }
  .contrast { grid-template-columns: 1fr; }
  .contrast-divider { height: 1px; }
  .scope-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .pillars { grid-template-columns: 1fr; }
  .facts { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .footer-inner { grid-template-columns: 1fr 1fr; }

  /* the plan and the steps stack: drawing first, then the four parts */
  .plan-body { grid-template-columns: 1fr; gap: clamp(1rem, 2.5vh, 1.8rem); }
  .plan-figure { order: -1; }
  .plan { max-height: min(38vh, 320px); }
}

@media (max-width: 900px) {
  .nav { display: none; }
  .menu-toggle { display: grid; }
  .header-actions .btn { display: none; }
  .scope-item { opacity: 1; }
  .chips { gap: 0.3rem; }
  .chip { font-size: 0.7rem; padding: 0.2rem 0.5rem; }
  /* two plots per row, still bottom-aligned on one ground line */
  .scale-row { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 700px) {
  :root { --header-h: 62px; --act-pad: 5.5rem; --act-span: 1.25; }
  /* phone: the split turns horizontal (earth above, blue below) */
  .split { grid-template-columns: 1fr; grid-template-rows: 1fr 1fr; }

  /* pinned storytelling is a desktop affordance. On phones each act is sized by
     its own content: forcing 100svh left a screen of empty space after every
     short act, which is what made the mobile page feel broken. */
  .act,
  .act[data-act] { min-height: 0; }
  .act-sticky { position: static; min-height: 0; padding-block: 6rem 4.5rem; }
  /* the hero is the one act that still owns exactly one screen */
  .act--hero { min-height: 100svh; }
  .act--hero .act-sticky {
    position: relative;
    display: block;
    min-height: 100svh;
    padding-block: 0;
  }

  /* A vertical seam leaves two unusable slivers on a phone, so the split turns
     HORIZONTAL: earth above, blue below, and the cable becomes the seam itself.
     These rules belong here and were lost once when this block was rewritten —
     the check suite now asserts their presence. */
  .split { grid-template-columns: 1fr; grid-template-rows: 1fr 1fr; }
  .split-half--old {
    background: linear-gradient(180deg, var(--hero-old-bg-1), var(--hero-old-bg-2));
  }
  .split-half--new {
    background: linear-gradient(180deg, var(--hero-new-bg-1), var(--hero-new-bg-2));
  }
  .split-seam {
    left: 0; right: 0; top: var(--hero-split);
    width: auto; height: 2px;
    transform: translateY(-1px);
    background: linear-gradient(
      90deg,
      transparent,
      rgba(242, 193, 78, 0.9) 24%,
      #FFFFFF 50%,
      rgba(159, 208, 255, 0.9) 76%,
      transparent
    );
    box-shadow:
      0 -24px 52px rgba(224, 145, 58, 0.36),
      0 24px 52px rgba(46, 134, 255, 0.36);
  }
  /* the cable straddles the horizontal seam, its joint pinned to it */
  .cable {
    top: 50%;
    bottom: auto;
    height: 150px;
    transform: translateY(-50%);
  }
  .cable-seal {
    top: 50%;
    bottom: auto;
    transform: translate(-50%, -50%);
    width: 82px;
    font-size: 0.92rem;
  }
  /* The split is TOP/BOTTOM on phones. The two words are pinned to fixed bands
     of the viewport instead of being stacked by grid gaps: with the gaps the
     composition stretched to whatever the content height happened to be, and
     传统 / 未来 drifted apart. 传统 sits in the warm half, 未来 in the cool half,
     the cable and the 好自然 seal stay the seam between them. */
  .hero-stage {
    position: absolute;
    inset: 0;
    padding: 0;
    display: block;
  }
  .poles { display: block; }
  .pole {
    position: absolute;
    left: 50%;
    transform: translateX(-50%);
    white-space: nowrap;
    font-size: clamp(3.2rem, 22vw, 5.6rem);
  }
  .pole--old { top: 27%; }
  .pole--new { top: 59.5%; }
  .hero-line {
    position: absolute;
    top: 71%;
    left: 50%;
    transform: translateX(-50%);
    white-space: nowrap;
    font-size: 0.84rem;
    letter-spacing: 0.18em;
    text-indent: 0.18em;
  }
  /* first-screen action: bottom-anchored so the lower band is not dead space */
  .hero-cta {
    display: inline-flex;
    position: absolute;
    left: 50%;
    bottom: 7.5%;
    transform: translateX(-50%);
    padding: 0.8rem 1.7rem;
    border-radius: 999px;
    background: var(--c-blue);
    color: #fff;
    font-size: 0.95rem;
    font-weight: 600;
    letter-spacing: 0.04em;
    text-decoration: none;
    box-shadow: 0 10px 28px rgba(18, 102, 241, 0.32);
  }

  .scope-grid { grid-template-columns: 1fr; }
  .facts { grid-template-columns: 1fr 1fr; }
  .footer-inner { grid-template-columns: 1fr; }
  .ingredient { grid-template-columns: auto 1fr; }
  .ingredient-note { grid-column: 2; white-space: normal; }
  .act-head--row { flex-direction: column; align-items: flex-start; }
  .scroll-hint { display: none; }

  /* the plan: keep the drawing but let it run nearly edge to edge */
  .plan { max-height: none; }
  .plan-figure { margin-inline: calc(var(--gutter) * -0.4); }

  /* the four plots stack, and each one keeps its true relative size, so the
     size difference still reads even in a single column */
  .scale-row { grid-template-columns: 1fr; gap: 1.4rem; }
  .scale-item { justify-items: start; }
}

@media (max-height: 620px) and (min-width: 901px) {
  /* short landscape viewports: let sticky acts scroll instead of clipping */
  .act-sticky { align-items: flex-start; }
}

/* ------------------------------------------------ 19. reduced motion */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    transition-delay: 0ms !important;
  }
  .js [data-reveal] { opacity: 1; transform: none; }
  .dragonfly-wing ellipse { animation: none; }
  .act[data-act] { min-height: 100vh; }
  .scope-item { opacity: 1; }
}

@media print {
  .site-header, .plan-figure, .act-nav, .progress-rail, .scroll-hint,
  body { background: #fff; }
  .act-sticky { position: static; min-height: 0; }
  .act[data-act] { min-height: 0; }
  .scope-item { opacity: 1; }
}
