/* JUNBAO landing — v13 (2026-09-24).
   One stylesheet, one definition per component. Sections:
   1 tokens & base · 2 header · 3 loader · 4 film stage & media · 5 grain & light fx
   6 grid · 7 opening (intro card) · 8 chapters · 9 film marks · 10 meta & status
   11 collection · 12 responsive · 13 reduced motion
   Previous layered versions are archived in maintenance/before_redesign_20260924/. */

/* ============ 1. Tokens & base ============ */
@font-face{font-family:Manrope;src:url('./fonts/manrope-latin-variable.woff2') format('woff2');font-style:normal;font-weight:200 800;font-display:swap}
@property --spot-r{syntax:'<percentage>';inherits:true;initial-value:60%}
@property --spot-x{syntax:'<percentage>';inherits:true;initial-value:50%}
@property --spot-y{syntax:'<percentage>';inherits:true;initial-value:46%}
:root{
  color-scheme:dark;
  --ink:#050605;--green:#379d40;
  --ease:cubic-bezier(.4,0,.2,1);--ease-out:cubic-bezier(.22,1,.36,1);
  --font-sans:Manrope,'Noto Sans TC','PingFang TC',Arial,sans-serif;
  --font-mono:'IBM Plex Mono',ui-monospace,'SF Mono',Menlo,monospace;
  --font-zh:'Noto Sans TC','PingFang TC',sans-serif;
  --gutter:clamp(16px,2.4vw,44px);--intro-gutter:clamp(16px,2.4vw,44px);--grid-gap:clamp(16px,1.7vw,32px);
  --chapter-size:clamp(40px,4.4vw,88px);
  --small-type:clamp(13px,.85vw,16px);--body-type:clamp(15px,1.05vw,20px);--mono-type:clamp(11px,.72vw,13px);
  --header-bar:68px;--meta-reserve:72px;--grid-cell:clamp(26px,2.9vw,56px);
}
*{box-sizing:border-box}
html{background:var(--ink);scroll-behavior:smooth;scroll-padding-top:100px}
html.lenis,html.lenis body{height:auto}
.lenis.lenis-smooth{scroll-behavior:auto!important}
html.is-loading,html.is-loading body{overflow:hidden}
body{margin:0;background:var(--ink);color:#fff;font-family:var(--font-sans);-webkit-font-smoothing:antialiased}
a{color:inherit;text-decoration:none;touch-action:manipulation}
button{font:inherit;color:inherit;cursor:pointer}
a,button{-webkit-tap-highlight-color:transparent}
::selection{background:#fff;color:var(--ink)}
:focus-visible{outline:2px solid #fff;outline-offset:6px}
button:focus-visible{outline-offset:3px}
[hidden]{display:none!important}
.visually-hidden{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip-path:inset(50%);white-space:nowrap;border:0}
.skip-link{position:fixed;z-index:110;top:8px;left:16px;padding:14px;background:#fff;color:#111;transform:translateY(-160%)}
.skip-link:focus{transform:none}
.noscript-note{padding:20px var(--gutter);font-size:14px}
/* Shared green lead-in rule used by eyebrows and the collection label. */
.eyebrow-rule{display:block;flex:none;width:clamp(28px,3vw,56px);height:1px;background:var(--green);transform-origin:left center}

/* ============ 2. Header ============ */
.site-header{position:fixed;z-index:30;top:6px;left:var(--intro-gutter);right:var(--intro-gutter);height:56px;padding:0;display:flex;align-items:center;gap:28px;opacity:1;transition:opacity .9s var(--ease) .2s}
html.is-loading .site-header{opacity:0;transition:none}
/* Full-bleed glass bar, shown once collection content scrolls beneath (landing.js toggles .is-solid). */
.site-header::before{content:'';position:fixed;inset:0 0 auto;height:var(--header-bar);z-index:-1;pointer-events:none;background:#050605d9;backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px);border-bottom:1px solid #ffffff12;opacity:0;transition:opacity .35s var(--ease)}
.site-header.is-solid::before{opacity:1}
.brand-lockup{display:flex;align-items:center;flex-shrink:0;min-height:44px}
.brand-lockup img{display:block;width:48px;height:auto}
.brand-lockup,.nav-toggle{position:relative;z-index:2}
/* SpaceX-style bar: the main links run left to right after the logo; the menu button sits far right. */
.site-nav{display:flex;align-items:center;gap:clamp(20px,2.2vw,36px);margin-left:clamp(28px,3.4vw,56px)}
.site-nav a{position:relative;padding:13px 0;font-family:var(--font-zh);font-size:15px;letter-spacing:.14em;white-space:nowrap;color:#ffffffe6;transition:color .3s var(--ease)}
.site-nav a::after{content:'';position:absolute;left:0;width:18px;bottom:4px;height:1px;background:var(--green);transform:scaleX(0);transform-origin:left;transition:transform .35s var(--ease)}
.site-nav a[aria-current=location]::after,.site-nav a:hover::after{transform:scaleX(1)}
.site-nav a:hover{color:#fff}
.nav-toggle{display:grid;place-items:center;width:44px;height:44px;margin-left:auto;margin-right:-10px;padding:0;border:0;background:none}
.nav-toggle-bars,.nav-toggle-bars::before,.nav-toggle-bars::after{display:block;width:22px;height:1.5px;background:#fff;transition:transform .35s var(--ease),opacity .2s var(--ease)}
.nav-toggle-bars{position:relative}
.nav-toggle-bars::before,.nav-toggle-bars::after{content:'';position:absolute;left:0}
.nav-toggle-bars::before{top:-7px}
.nav-toggle-bars::after{top:7px}
.is-menu-open .nav-toggle-bars{background:transparent}
.is-menu-open .nav-toggle-bars::before{transform:translateY(7px) rotate(45deg)}
.is-menu-open .nav-toggle-bars::after{transform:translateY(-7px) rotate(-45deg)}
/* Full-screen menu: black sheet, wide-tracked items, expandable groups, a news block at the foot. */
.site-drawer{position:fixed;inset:0;z-index:0;overflow-y:auto;overscroll-behavior:contain;background:var(--ink);opacity:0;visibility:hidden;transition:opacity .35s var(--ease),visibility 0s linear .35s}
.is-menu-open .site-drawer{opacity:1;visibility:visible;transition:opacity .35s var(--ease)}
.site-header.is-menu-open .site-nav{visibility:hidden}
/* While the menu is open the bar turns solid, so menu items scrolling up pass under it rather than under the logo. */
.site-header.is-menu-open::before{z-index:1;opacity:1;background:var(--ink);backdrop-filter:none;-webkit-backdrop-filter:none}
.drawer-nav{display:flex;flex-direction:column;gap:clamp(28px,5svh,56px);min-height:100%;padding:calc(var(--header-bar) + 4svh) var(--intro-gutter) 40px}
.drawer-list,.drawer-sub{margin:0;padding:0;list-style:none}
.drawer-list>li{border-bottom:1px solid #ffffff14}
.drawer-list>li>a,.drawer-list summary{display:flex;align-items:center;gap:10px;padding:14px 0;font-family:var(--font-zh);font-size:clamp(20px,1.7vw,26px);letter-spacing:.16em;cursor:pointer;list-style:none}
.drawer-list summary::-webkit-details-marker{display:none}
.drawer-list summary::after{content:'';width:7px;height:7px;margin-top:-4px;border:solid #ffffffb0;border-width:0 1.5px 1.5px 0;transform:rotate(45deg);transition:transform .3s var(--ease)}
.drawer-list details[open] summary::after{margin-top:4px;transform:rotate(-135deg)}
.drawer-sub{display:flex;flex-wrap:wrap;gap:4px 28px;padding:0 0 16px}
.drawer-sub a{display:block;padding:8px 0;font-family:var(--font-zh);font-size:15px;letter-spacing:.14em;color:#ffffffb0}
.drawer-list a:hover,.drawer-list summary:hover,.drawer-sub a:hover{color:var(--green)}
.drawer-heading{margin:0 0 6px;font-family:var(--font-zh);font-size:13px;font-weight:400;letter-spacing:.2em;color:#ffffff80}
.drawer-news-item{display:flex;justify-content:space-between;gap:20px;padding:14px 0;border-top:1px solid #ffffff14;font-family:var(--font-zh);font-size:15px;letter-spacing:.06em}
.drawer-news-item time{font-family:var(--font-mono);font-size:var(--mono-type);letter-spacing:.12em;color:#ffffff80}
.drawer-note{margin:auto 0 0;font-family:var(--font-zh);font-size:12px;letter-spacing:.1em;color:#ffffff59}
html.is-menu-open,html.is-menu-open body{overflow:hidden}
@media(min-width:961px){
  /* Wide screens: list and news side by side, like a two-column directory. */
  .drawer-nav{display:grid;grid-template-columns:minmax(0,1.4fr) minmax(0,1fr);grid-template-rows:auto 1fr;column-gap:clamp(48px,8vw,160px);align-content:start}
  .drawer-news{grid-column:2;grid-row:1}
  .drawer-note{grid-column:1/-1}
}
/* Six links no longer fit: below 961px the bar keeps only the logo and the menu button. */
@media(max-width:960px){
  .site-nav{display:none}
}

/* ============ 3. Loader ============ */
.page-loader{position:fixed;inset:0;z-index:100;display:grid;place-items:center;background:var(--ink);transition:opacity .9s var(--ease)}
.page-loader.is-leaving{opacity:0;pointer-events:none}
.loader-lockup{display:flex;flex-direction:column;align-items:center;gap:22px}
.loader-caption{font-family:var(--font-mono);font-size:12px;letter-spacing:.22em}
.loader-track{width:142px;height:1px;background:#ffffff25;overflow:hidden}
.loader-track i{display:block;width:42%;height:100%;background:var(--green);animation:loading-travel 2.4s var(--ease) infinite}
.loader-edition{position:absolute;bottom:40px;font-family:var(--font-mono);font-size:11px;letter-spacing:.15em;color:#ffffff8c}
@keyframes loading-travel{from{transform:translateX(-110%)}to{transform:translateX(350%)}}

/* ============ 4a. Hero still (first screen) ============ */
/* PD SERIES key visual (3840×2160 master served at 1920/2880/3840; 16:9, near-black ground, units filling the frame; the baked-in "PD SERIES / JUNBAO TECH"
   title sits at 18–82% across, 16–35% down and must never be cropped). It is the only content of the first screen.
   The bottom of the picture is never cropped: the hero is at least one large viewport tall and at least as tall as the
   16:9 picture at full width (56.25vw). Screens wider than 16:9 therefore show the picture whole and let it run past
   the fold (scrolling reveals the rest); taller screens are covered by height and lose only the sides.
   Upright screens use the block below (there 56.25vw is always under 100lvh). */
/* Large-viewport height: on phones the first screen reaches under Safari's translucent bottom bar (100svh stopped at
   the bar's top edge). vh is the fallback. */
.hero{position:relative;z-index:1;height:max(100vh,56.25vw);height:max(100lvh,56.25vw);overflow:hidden;background:#000;color:#fff}
.hero-media{position:absolute;inset:0;transition:opacity 1.6s var(--ease)}
.hero-media img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;object-position:50% 50%}
/* Black tail between the key visual and the film: a block of its own (nothing is laid over the film), starting at the
   key visual's bottom-edge grey (#171717) and settling into the page black. On phones it is solid black. */
/* Hidden for now on every screen (2026-10-21): the film follows the key visual directly; remove display:none to bring
   the marquee band back. */
.hero-tail{position:relative;z-index:1;display:none;height:clamp(64px,12vh,160px);overflow:hidden;background:linear-gradient(#171717,#0b0b0b)}
/* LED marquee: a canvas of dot-matrix "pixels" (see landing.js); the grain above it matches the key visual's noisy black
   so the band no longer reads as a flat block. */
.led-marquee{position:absolute;inset:0;display:block;width:100%;height:100%}
.hero-tail-grain{position:absolute;inset:0;pointer-events:none;background:url('./film-grain-cinema-a.svg') 0 0/128px 128px;mix-blend-mode:soft-light;opacity:.22}
/* Upright screens: the dot size is capped by the width (landing.js: width/68), so the band is exactly 11 of those rows
   tall (7 lit rows, 2 dark above and below), like the desktop band; +1px keeps the row count at 11 after rounding. */
@media(max-aspect-ratio:4/5){
  .hero-tail{height:calc(100vw * 11 / 68 + 1px);background:#0b0b0b}
}
/* Mouse parallax (landing.js sets each layer's `translate`; `transform` stays free for the upright layout).
   The units layer is cut by the frame's left and right edges, so the whole stack is scaled 5% to keep
   those edges off screen at full drift (1.5% of the width across, 0.9% down); the tightest case, the units layer
   on 16:9, keeps ≈9px to spare (≈4px at 4%). Touch screens and reduced motion keep the original framing. */
@media(hover:hover) and (pointer:fine) and (prefers-reduced-motion:no-preference){
  .hero-media{scale:1.05}
  .hero-layer{will-change:translate}
}
/* Bottom-left copy: small mono model name, two-line headline, underlined link below (the foot row ≈ 38px). */
.hero-copy{position:absolute;z-index:2;left:var(--intro-gutter);bottom:calc(max(20px,4svh) + 38px + clamp(10px,2svh,20px))}
.hero-model{margin:0 0 clamp(8px,1.4svh,14px);font-family:var(--font-mono);font-size:13px;font-weight:500;line-height:1.4;letter-spacing:.12em;color:#ffffffb3}
.hero-title{margin:0;font-family:var(--font-zh);font-size:clamp(20px,min(2.2vw,4svh),40px);font-weight:500;line-height:1.4;letter-spacing:.06em}
.hero-title>span{display:block;white-space:nowrap}
.hero-title>span+span{font-weight:300;color:#ffffffc7}
.hero-foot{position:absolute;z-index:2;left:var(--intro-gutter);bottom:max(20px,4svh);display:flex;align-items:center}
.hero-cta{display:inline-flex;align-items:center;gap:10px;padding:10px 0 6px;border-bottom:1px solid #ffffff80;font-family:var(--font-zh);font-size:14px;letter-spacing:.12em;white-space:nowrap;transition:color .3s var(--ease),border-color .3s var(--ease)}
.hero-cta:hover,.hero-cta:focus-visible{border-color:#fff}
/* Fades in as the (short) loader dissolves. */
:is(.hero-copy,.hero-foot){transition:opacity 1.2s var(--ease) .5s}
html.is-loading .hero-media,html.is-loading :is(.hero-copy,.hero-foot){opacity:0;transition:none}

/* ============ 4b. Product film (between the key visual and the in-ground light) ============ */
/* PD-400 film (16:9). Wide screens: one full screen with cover; the close-ups fill the frame, so trimming its edges on
   other ratios loses nothing. Upright screens: the dedicated 4:5 cut, the whole frame at full width. */
.film-reel{position:relative;z-index:1;height:100svh;overflow:hidden;background:#0b0b0b}
.film-reel-media{display:block;width:100%;height:100%;object-fit:cover}
@media(max-aspect-ratio:4/5){
  .film-reel{height:auto}
  .film-reel-media{height:auto;aspect-ratio:4/5}
}
/* Film grain over the clean render so it sits between the grainy key visual and the still: the three cinema plates
   (fixed in place, never translated) swap every 125ms while the film plays and hold still when it is paused.
   Soft-light keeps the film's tones. Plates at 128px (finer than the old film's 192px, closer to the 4K key visual's
   grain) at opacity .28; tune the opacity by eye against the key visual. Reduced motion stops the swap (section 13). */
.film-reel-grain{position:absolute;inset:0;z-index:1;pointer-events:none;background:url('./film-grain-cinema-a.svg') 0 0/128px 128px;mix-blend-mode:soft-light;opacity:.28}
.film-reel-grain::before,.film-reel-grain::after{content:'';position:absolute;inset:0;background-size:128px 128px;opacity:0;animation:.375s steps(1,end) infinite paused}
.film-reel-grain::before{background-image:url('./film-grain-cinema-b.svg');animation-name:grain-plate-b}
.film-reel-grain::after{background-image:url('./film-grain-cinema-c.svg');animation-name:grain-plate-c}
.film-reel.is-playing .film-reel-grain::before,.film-reel.is-playing .film-reel-grain::after{animation-play-state:running}

/* ============ 4c. In-ground light still ============ */
/* Wide screens: the 16:9 RG400 render on pure black with the lens lit green, one full screen with cover. The product and
   its floor reflection sit at 25–77% across and 30–93% down, so the crop is anchored low (50% 75%): on 21:9 the visible
   band is 19–94% and nothing is lost; 16:10 and narrower trim only the black sides. Upright screens show the matching
   9:16 green render uncropped at full width. The tag reuses .chapter-tag. */
.still-story{position:relative;z-index:1;height:100svh;overflow:hidden;background:#0a0a0a}
.still-media{display:block;width:100%;height:100%;object-fit:cover;object-position:50% 75%}
/* Wide screens: no caption over the render for now; the heading stays for screen readers. */
@media not all and (max-aspect-ratio:4/5){
  .still-story .chapter-tag{width:1px;height:1px;margin:-1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}
}
@media(max-aspect-ratio:4/5){
  .still-story{height:auto}
  .still-media{height:auto;aspect-ratio:2696/4792}
}

/* ============ 4. Film stage & media ============ */
.film-story{position:relative;height:100svh}
.film-story.is-ready{height:645svh}
.film-story.is-autoplay,.film-story.is-autoplay.is-ready{height:100svh}
.film-story.is-autoplay .film-exit-space{display:none}
.film-stage{position:sticky;top:0;height:100svh;overflow:hidden;isolation:isolate;background:#000;--fx:1;--handoff:0;--pointer-x:50%;--pointer-y:50%;--intro-presence:1}
.film-media{position:absolute;inset:0;z-index:0;background:#000;opacity:1;transition:opacity 1.8s var(--ease) .1s}
.film-stage.awaiting-reveal .film-media{opacity:0;transition:none}
.film-media img,.film-media video{position:absolute;inset:0;width:100%;height:100%;object-fit:contain;object-position:center;filter:saturate(.95)}
.film-poster{transition:opacity .4s var(--ease)}
.film-media video{opacity:0;transition:opacity .4s var(--ease)}
.film-stage.has-frame video{opacity:1}
.film-stage.has-frame .film-poster{opacity:0}
/* Screens narrower than 16:9: size the film to its real box and feather top/bottom. */
@media(min-width:761px) and (max-aspect-ratio:16/9){
  .film-media img,.film-media video{top:50%;bottom:auto;height:auto;aspect-ratio:16/9;transform:translateY(-50%);mask-image:linear-gradient(transparent,#000 3%,#000 97%,transparent)}
}
/* Ultra-wide screens: the film is pillarboxed instead, so feather left/right. */
@media(min-width:761px) and (min-aspect-ratio:1601/900){
  .film-media img,.film-media video{left:50%;right:auto;width:auto;height:100%;aspect-ratio:16/9;transform:translateX(-50%);mask-image:linear-gradient(90deg,transparent,#000 8%,#000 92%,transparent)}
}
.film-exit-space{position:absolute;bottom:0;left:0;width:1px;height:85svh;pointer-events:none}
.film-story:not(.is-ready) .film-exit-space{display:none}
.film-exit-veil{position:absolute;inset:0;z-index:12;background:var(--ink);opacity:var(--outro,0);pointer-events:none}

/* ============ 5. Grain & light fx ============ */
.film-shade{position:absolute;inset:0;z-index:1;pointer-events:none;background:linear-gradient(180deg,#0009,transparent 22%,transparent 82%,#000a)}
.film-fx{position:absolute;inset:0;pointer-events:none}
.film-dots{z-index:2;background-image:radial-gradient(circle,#0008 .45px,transparent .9px);background-size:3px 3px;opacity:calc(.34 * var(--fx));mask-image:radial-gradient(ellipse at 68% 50%,#000 10%,#0009 37%,transparent 78%);transition:opacity .4s var(--ease)}
.film-stage[data-chapter=ground] .film-dots{mask-image:radial-gradient(ellipse at 32% 48%,#000 10%,#0009 37%,transparent 78%)}
.film-scan{z-index:3;opacity:calc(.08 * var(--fx));background:repeating-linear-gradient(0deg,transparent 0 3px,#0009 3px 4px)}
.film-vignette{z-index:3;opacity:calc(.30 * var(--fx));background:radial-gradient(ellipse at 55% 47%,transparent 35%,#000a 100%)}
.film-shutter{position:absolute;inset:0;z-index:4;background:#000;opacity:calc(var(--handoff) * .45);pointer-events:none}
.film-stage::after{content:'';position:absolute;inset:0;z-index:3;pointer-events:none;background:radial-gradient(ellipse at var(--pointer-x) var(--pointer-y),#a4c38605,transparent 45%);opacity:var(--fx)}
.fx-disabled .film-stage{--fx:0}
/* Three independently seeded grain plates alternate in place; the texture never translates. */
.film-grain{z-index:4;background:url('./film-grain-cinema-a.svg') 0 0/192px 192px;opacity:calc(.60 * var(--fx));mix-blend-mode:soft-light}
.film-grain::before,.film-grain::after{content:'';position:absolute;inset:0;background-size:192px 192px;opacity:0;animation-duration:.375s;animation-timing-function:steps(1,end);animation-iteration-count:infinite;animation-play-state:paused}
.film-grain::before{background-image:url('./film-grain-cinema-b.svg');animation-name:grain-plate-b}
.film-grain::after{background-image:url('./film-grain-cinema-c.svg');animation-name:grain-plate-c}
.is-grain-running .film-grain::before,.is-grain-running .film-grain::after{animation-play-state:running}
@keyframes grain-plate-b{0%{opacity:0}33.333%{opacity:1}66.666%,100%{opacity:0}}
@keyframes grain-plate-c{0%,33.333%{opacity:0}66.666%{opacity:1}100%{opacity:0}}

/* ============ 6. Grid ============ */
/* Corner grid drawn in CSS so cells stay square at every aspect ratio (the old SVG was stretched). */
.film-grid{position:absolute;inset:0;z-index:4;pointer-events:none;opacity:calc(.5 * var(--fx))}
.grid-field{position:absolute;inset:-40px 0;background-image:linear-gradient(#deefe02d 1px,transparent 1px),linear-gradient(90deg,#deefe02d 1px,transparent 1px);background-size:var(--grid-cell) var(--grid-cell);transform:translateY(calc(var(--grid-shift,0) * 1px));
  -webkit-mask:radial-gradient(22% 21% at 80% 18%,#000 0,#000b 42%,transparent 100%),radial-gradient(17% 26% at 7% 86%,#000 0,#000b 42%,transparent 100%);
  mask:radial-gradient(22% 21% at 80% 18%,#000 0,#000b 42%,transparent 100%),radial-gradient(17% 26% at 7% 86%,#000 0,#000b 42%,transparent 100%)}

/* ============ 7. Opening (intro card) ============ */
.film-panel{position:absolute;inset:0;z-index:5;pointer-events:none;will-change:opacity,transform}
.film-panel:not(.panel-intro){opacity:0;visibility:hidden}
.panel-intro{padding:0}
/* Spotlight veil: a light pool that drifts slowly; fades with the intro on scroll. */
.intro-spot{position:absolute;inset:0;z-index:1;pointer-events:none;opacity:var(--intro-presence);
  background:radial-gradient(ellipse 62% 70% at var(--spot-x) var(--spot-y),#00000033 0,#00000059 calc(var(--spot-r) * .45),#000000de var(--spot-r),#000 calc(var(--spot-r) * 1.6))}
/* Diagonal composition: first line top-left under the header, second line bottom-right, the product framed between.
   --l1-top / --l2-bottom / --foot-bottom are retuned per screen shape below. */
.panel-intro{--foot-bottom:max(24px,5svh);--l1-top:calc(var(--header-bar) + 4px);--l2-bottom:calc(var(--foot-bottom) + 44px)}
.intro-copy{position:absolute;inset:0;z-index:2}
.intro-kicker{position:absolute;left:var(--intro-gutter);bottom:calc(var(--foot-bottom) + 34px);display:flex;align-items:center;gap:14px;margin:0;font-family:var(--font-mono);font-size:var(--mono-type);font-weight:500;line-height:1.5;letter-spacing:.22em;color:#ffffffc0}
/* Sized by width and height so short laptops and sideways phones keep the headline in proportion. */
.intro-title{position:absolute;inset:0;margin:0;font-family:var(--font-zh);font-size:clamp(32px,min(5.4vw,7.8svh),104px);font-weight:500;line-height:1.2;letter-spacing:.06em}
.intro-title>span{position:absolute;white-space:nowrap}
.intro-title>span:first-child{left:var(--intro-gutter);top:var(--l1-top)}
.intro-title>span+span{right:var(--intro-gutter);bottom:var(--l2-bottom);font-weight:300;color:#ffffffde}
.intro-sub{position:absolute;left:var(--intro-gutter);bottom:var(--foot-bottom);margin:0;font-family:var(--font-zh);font-size:var(--body-type);font-weight:300;line-height:1.6;letter-spacing:.1em;color:#ffffffa8}
.intro-scroll{position:absolute;z-index:2;right:var(--intro-gutter);bottom:var(--foot-bottom);display:flex;align-items:center;gap:12px;font-family:var(--font-zh);font-size:13px;letter-spacing:.14em;line-height:1;white-space:nowrap;color:#ffffffc0}
.intro-scroll svg{height:30px;fill:none;stroke:currentColor;stroke-width:1;stroke-linecap:round;stroke-linejoin:round}
/* Keeps the headline legible over the film; fades out with the intro panel. */
.panel-intro::before{content:'';position:absolute;inset:0;pointer-events:none;background:linear-gradient(180deg,#0009 0,transparent 30%,transparent 70%,#000a 100%)}
/* While the page loader is on screen: intro hidden, spotlight dark. */
.film-stage.opening-pending .intro-spot{--spot-r:0%}
.film-stage.opening-pending :is(.intro-copy,.intro-scroll){visibility:hidden}
/* Entrance timeline (t = 0 when the loader starts to dissolve). opening.js finishes these on scroll. */
.is-opening .intro-spot{animation:op-ignite 2.2s var(--ease-out) backwards}
.is-opening .intro-title>span:first-child{animation:op-fade 1.2s ease .6s backwards}
.is-opening .intro-title>span+span{animation:op-fade 1.2s ease 1s backwards}
.is-opening :is(.intro-kicker,.intro-sub){animation:op-fade 1.2s ease 1.4s backwards}
.is-opening .intro-scroll{animation:op-fade 1.2s ease 1.6s backwards}
@keyframes op-ignite{from{--spot-r:0%}}
@keyframes op-fade{from{opacity:0}}
/* Idle life once the loader is gone; paused outside the intro chapter. */
.film-stage:not(.opening-pending) .film-media{animation:op-drift 22s ease-in-out 2.2s infinite}
.film-stage:not(.opening-pending) .intro-scroll svg{animation:op-cue 2.2s ease-in-out infinite}
.film-stage:not([data-chapter=intro]) :is(.film-media,.intro-scroll svg){animation-play-state:paused}
@keyframes op-drift{0%,100%{--spot-x:50%;--spot-y:46%}25%{--spot-x:47%;--spot-y:45%}75%{--spot-x:53%;--spot-y:48%}}
@keyframes op-cue{0%,100%{translate:0 0}50%{translate:0 6px}}

/* ============ 8. Chapters (editorial index) ============ */
/* Chapters now carry only a small exhibit-style tag in the corner; the film does the talking. */
.chapter-tag{position:absolute;left:var(--intro-gutter);bottom:max(20px,4svh);display:flex;flex-wrap:wrap;align-items:baseline;gap:6px clamp(16px,1.8vw,28px)}
.chapter-tag h2{margin:0;font-family:var(--font-zh);font-size:clamp(15px,1.15vw,19px);font-weight:400;letter-spacing:.16em}
.chapter-tag p{margin:0;font-family:var(--font-mono);font-size:var(--mono-type);letter-spacing:.12em;color:#ffffff99}
@media(max-aspect-ratio:4/5){
  .chapter-tag{bottom:calc(20px + env(safe-area-inset-bottom,0px))}
}
.film-panel:not(.panel-intro){display:grid;grid-template-columns:repeat(12,minmax(0,1fr));gap:var(--grid-gap);padding:0 var(--gutter)}
.chapter-copy{grid-column:1/6;align-self:start;min-width:0;margin-top:26svh}
/* Head (eyebrow + title) and foot (caption + spec) only matter on phones, where they hug the film frame. */
.copy-head,.copy-foot{display:contents}
.panel-bridge .chapter-copy,.panel-ground .chapter-copy{grid-column:9/13;margin-top:24svh;text-align:right}
.eyebrow{display:flex;align-items:center;gap:14px;margin:0 0 2.4svh;font-family:var(--font-mono);font-size:var(--mono-type);font-weight:500;line-height:1.5;letter-spacing:.14em;color:#ffffffc0;text-transform:uppercase}
/* --ci (0→1) comes from the film timeline, so the rule draws in with the headline. */
.eyebrow .eyebrow-rule{transform:scaleX(var(--ci,1))}
.panel-bridge .eyebrow,.panel-ground .eyebrow{justify-content:flex-end}
.chapter-title{margin:0;font-family:var(--font-zh);font-size:var(--chapter-size);font-weight:500;line-height:1.28;letter-spacing:.04em}
.chapter-title>.reveal-line{display:block;width:max-content;max-width:100%;white-space:nowrap}
.chapter-title>.reveal-line+.reveal-line{font-weight:300;color:#ffffffd0}
.panel-bridge .chapter-title>.reveal-line,.panel-ground .chapter-title>.reveal-line{margin-left:auto}
.reveal-word{display:block;transform-origin:left bottom;will-change:transform,opacity;backface-visibility:hidden}
.panel-caption{display:flex;flex-direction:column;gap:6px;margin:3.4svh 0 0;font-size:var(--body-type);line-height:1.7}
.panel-ground .panel-caption{align-items:flex-end;text-align:right}
.caption-zh{font-family:var(--font-zh);font-weight:400;letter-spacing:.08em;color:#ffffffe0}
.caption-en{font-size:var(--small-type);letter-spacing:.01em;color:#ffffff8c}
.pixel-spec{display:flex;gap:3vw;width:max-content;margin:4svh 0 0;padding-top:1.6svh;border-top:1px solid #ffffff26}
.pixel-spec div{display:flex;flex-direction:column;gap:.8svh}
.pixel-spec dt{font-family:var(--font-zh);font-size:var(--small-type);letter-spacing:.14em;color:#ffffff80}
.pixel-spec dd{margin:0;font-size:clamp(22px,1.9vw,38px);font-weight:400;letter-spacing:-.02em;line-height:1.1}
/* Closer look: bottom-left, clear of the product above. */
.panel-detail .chapter-copy{grid-column:1/9;align-self:end;margin:0 0 12svh}

/* ============ 9. Film marks ============ */
.film-marks{position:absolute;inset:0;z-index:4;pointer-events:none;opacity:calc(.9 * var(--fx));transition:opacity .5s var(--ease)}
.is-scroll-active .film-marks{opacity:calc(.12 * var(--fx))}
.mark{position:absolute;line-height:1;white-space:nowrap;color:#fff}
.mark span,.mark-frame{font-family:var(--font-mono)}
.mark-label{display:flex;align-items:center;gap:.7em;font-size:11px;letter-spacing:.14em;color:#ffffffd0}
.mark-label i{display:block;width:1.4em;height:1px;background:var(--green)}
.mark-cross{width:26px;height:26px}
.mark-cross::before,.mark-cross::after{content:'';position:absolute;background:#fff}
.mark-cross::before{left:50%;top:0;bottom:0;width:1px}
.mark-cross::after{top:50%;left:0;right:0;height:1px}
.mark-cross span{position:absolute;left:calc(100% + 7px);top:calc(100% + 3px);font-size:10px;letter-spacing:.08em;color:#ffffffa8}
.mark-box b{position:absolute;width:13px;height:13px;border:0 solid #ffffffc0}
.mark-box b:nth-child(1){left:0;top:0;border-width:1px 0 0 1px}
.mark-box b:nth-child(2){right:0;top:0;border-width:1px 1px 0 0}
.mark-box b:nth-child(3){left:0;bottom:0;border-width:0 0 1px 1px}
.mark-box b:nth-child(4){right:0;bottom:0;border-width:0 1px 1px 0}
.mark-box span{position:absolute;left:0;top:calc(100% + 6px);font-size:9.5px;letter-spacing:.1em;color:#ffffffa8}
.mark-ruler{width:100px;height:13px;border-bottom:1px solid #ffffff90;background:repeating-linear-gradient(90deg,#ffffff90 0 1px,transparent 1px 10%) bottom/100% 45% no-repeat;transform-origin:left center}
.mark-ruler::after{content:'';position:absolute;left:0;bottom:0;width:1px;height:100%;background:#fff}
.mark-ruler span{position:absolute;left:0;top:calc(100% + 6px);font-size:9px;letter-spacing:.1em;color:#ffffffa8}
.mark-frame{font-size:10px;letter-spacing:.12em;color:#ffffffc0}
.mark-frame em{font-style:normal;color:var(--green)}

/* ============ 10. Meta row & status ============ */
.film-meta{position:absolute;z-index:9;bottom:28px;left:var(--gutter);right:var(--gutter);display:flex;align-items:center;gap:24px;font-family:var(--font-mono);font-size:var(--mono-type);font-weight:500;letter-spacing:.1em;pointer-events:none;opacity:calc(.9 * var(--meta-presence,0))}
.meta-product{display:none}
.meta-type{margin-right:auto}
.scroll-note{white-space:nowrap}
.scroll-note span{margin-left:10px;font-family:var(--font-sans);font-size:18px}
.film-status{position:absolute;z-index:10;right:var(--gutter);top:123px;max-width:280px;padding:12px 16px;border:1px solid #ffffff24;border-radius:2px;background:#111b;backdrop-filter:blur(12px);font-size:14px;line-height:1.6}
.film-status[data-error=true]{top:auto;bottom:60px}

/* ============ 11. Collection ============ */
.collection{position:relative;z-index:12;overflow:hidden;background:var(--ink);padding:clamp(110px,17svh,180px) var(--gutter) 26px}
.collection-rule{display:flex;flex-wrap:wrap;justify-content:space-between;gap:8px 24px;padding-top:20px;border-top:1px solid #379d405c;font-family:var(--font-mono);font-size:var(--mono-type);letter-spacing:.14em}
.collection-rule>span{display:flex;align-items:center;gap:14px;white-space:nowrap}
.collection-hero{display:grid;grid-template-columns:repeat(12,minmax(0,1fr));gap:var(--grid-gap);align-items:end;margin:80px 0 clamp(64px,9svh,110px)}
.collection h2{grid-column:1/9;margin:0;font-family:var(--font-zh);font-size:clamp(40px,5.6vw,112px);font-weight:500;line-height:1.3;letter-spacing:.04em}
.collection h2>span{display:block;white-space:nowrap}
.collection .connect-word{font-weight:300;color:#ffffffd0}
.collection-aside{grid-column:9/13;display:flex;flex-direction:column;gap:40px;padding-bottom:.4em}
.collection-aside p{margin:0;font-family:var(--font-zh);font-size:var(--body-type);letter-spacing:.06em;line-height:1.8}
.collection-aside .phrase{display:inline-block}
.collection-aside p span[lang]{display:block;margin-top:4px;font-family:var(--font-sans);font-size:var(--small-type);letter-spacing:.01em;color:#ffffff8c}
.collection-link{display:flex;align-items:center;justify-content:space-between;gap:24px;padding-bottom:12px;border-bottom:1px solid #ffffff50;font-family:var(--font-zh);font-size:var(--small-type);letter-spacing:.12em}
.collection-link>span{font-family:var(--font-sans);font-size:28px;transition:transform .4s var(--ease)}
.collection-link:hover>span{transform:translate(4px,-4px)}
.product-index{border-top:1px solid #ffffff1f}
.product-index a{position:relative;isolation:isolate;display:grid;grid-template-columns:clamp(40px,4vw,72px) minmax(0,1fr) 44px;align-items:center;column-gap:clamp(16px,2vw,32px);padding:26px 0;border-bottom:1px solid #ffffff1f}
/* Hover wash bleeds slightly past the rules without moving them. */
.product-index a::before{content:'';position:absolute;z-index:-1;inset:0 -12px;background:#ffffff0a;opacity:0;transition:opacity .4s var(--ease)}
.pi-num{font-family:var(--font-mono);font-size:var(--mono-type);letter-spacing:.1em;transition:color .4s var(--ease)}
.pi-name{font-family:var(--font-zh);font-size:clamp(22px,2vw,36px);font-weight:400;letter-spacing:.06em}
.pi-en{font-size:var(--small-type);letter-spacing:.01em;color:#ffffff8c}
.pi-arrow{display:grid;place-items:center;width:44px;height:44px;border:1px solid #ffffff40;border-radius:50%;font-size:17px;transition:transform .4s var(--ease),border-color .4s var(--ease)}
.product-index a:hover::before,.product-index a:focus-visible::before{opacity:1}
.product-index a:hover .pi-num,.product-index a:focus-visible .pi-num{color:var(--green)}
.product-index a:hover .pi-arrow,.product-index a:focus-visible .pi-arrow{transform:translate(4px,-4px);border-color:#fff}
footer{display:flex;justify-content:space-between;align-items:center;gap:14px;padding-top:45px;font-family:var(--font-mono);font-size:var(--mono-type);letter-spacing:.12em}
.fx-toggle{display:flex;align-items:center;gap:6px;padding:7px 11px;border:1px solid #ffffff24;border-radius:30px;background:#1315106b;backdrop-filter:blur(12px);font-family:var(--font-mono);font-size:var(--mono-type);letter-spacing:.08em}
.fx-toggle i{width:4px;height:4px;border-radius:50%;background:#fff}
.fx-toggle[aria-pressed=false] i{background:#777}
.collection.motion-enabled h2>span{transform:translateY(calc((1 - var(--reveal,0)) * 70px));opacity:calc(.18 + var(--reveal,0) * .82)}
.collection.motion-enabled .connect-word{transform:translate(calc((1 - var(--reveal,0)) * 5%),calc((1 - var(--reveal,0)) * 80px))}
.collection.motion-enabled .collection-rule{opacity:var(--reveal,0);transform:translateY(calc((1 - var(--reveal,0)) * 24px))}

/* ============ 12. Responsive ============ */
@media(min-width:1800px){
  .film-meta{font-size:12px}
}
@media(max-width:1150px){
  .brand-lockup img{width:46px}
  .panel-pixel .chapter-copy{grid-column:1/7}
  .panel-bridge .chapter-copy,.panel-ground .chapter-copy{grid-column:8/13}
  /* Side columns get too narrow for the bilingual caption pair: stack it. */
}
@media(max-width:1000px){
  .collection-hero{grid-template-columns:1fr;row-gap:clamp(36px,5svh,56px)}
  .collection h2,.collection-aside{grid-column:1/-1}
  .collection-aside{flex-direction:row;align-items:center;justify-content:space-between;gap:30px}
  .collection-link{min-width:300px}
}
/* Short desktop windows. */
@media(max-height:650px) and (min-width:761px){
  :root{--chapter-size:clamp(32px,3.6vw,54px);--header-bar:60px}
  .site-header{top:4px;height:52px;padding:0}
  .brand-lockup img{width:42px}
  .intro-scroll svg{height:22px}
  .chapter-copy,.panel-bridge .chapter-copy,.panel-ground .chapter-copy{margin-top:22svh}
  .eyebrow{margin-bottom:14px}
  .panel-caption{margin-top:18px}
  .pixel-spec{margin-top:18px;padding-top:10px}
  .panel-detail .chapter-copy{margin-bottom:15svh}
  .film-meta{bottom:18px}
}
/* Phones held sideways. */
@media(max-height:500px) and (min-aspect-ratio:1/1){
  .panel-intro{--foot-bottom:max(14px,4svh);--l1-top:calc(var(--header-bar) + 4px);--l2-bottom:var(--foot-bottom)}
  .intro-kicker,.intro-scroll{display:none}
  .chapter-copy,.panel-bridge .chapter-copy,.panel-ground .chapter-copy{margin-top:max(76px,21svh)}
  .panel-detail .chapter-copy{margin:0 0 56px}
  .eyebrow{margin-bottom:8px}
  .panel-caption{margin-top:10px}
  .pixel-spec{margin-top:10px;padding-top:8px}
  .film-meta{bottom:12px}
}
/* Phones and portrait tablets: the film is a fixed widescreen frame and the copy hugs it —
   eyebrow + title just above, caption + spec just below — so the three read as one composition.
   Sideways phones (wider than tall) keep the landscape composition instead, whatever their width. */
@media(max-width:760px) and (max-aspect-ratio:1/1),(min-width:761px) and (max-aspect-ratio:4/5){
  :root{--band-scale:1;--band-y:55svh;--band-gap:28px;--band-h:calc(100vw * 9 / 16 * var(--band-scale))}
  /* Never panned or moved while scrolling; a slight fixed zoom on phones keeps the product present. */
  .film-media img,.film-media video{left:50%;right:auto;width:calc(100% * var(--band-scale));height:auto;aspect-ratio:16/9;top:var(--band-y);bottom:auto;transform:translate(-50%,-50%);object-fit:contain;mask-image:none}
  /* The light pool stays put on narrow screens; drifting reads as camera shake there. */
  .film-stage:not(.opening-pending) .film-media{animation:none}
  .film-media{--spot-y:55%}
  .intro-spot{background:radial-gradient(ellipse 95% 48% at var(--spot-x) var(--spot-y),#00000033 0,#00000059 calc(var(--spot-r) * .45),#000000de var(--spot-r),#000 calc(var(--spot-r) * 1.6))}
  .film-panel:not(.panel-intro){display:block;padding:0}
  .chapter-copy,.panel-detail .chapter-copy,.panel-bridge .chapter-copy,.panel-ground .chapter-copy{position:absolute;top:0;bottom:0;left:var(--gutter);right:var(--gutter);display:block;width:auto;margin:0;align-self:stretch;text-align:left}
  .copy-head{position:absolute;left:0;right:0;bottom:calc(100svh - var(--band-y) + var(--band-h) / 2 + var(--band-gap));display:block}
  .copy-foot{position:absolute;left:0;right:0;top:calc(var(--band-y) + var(--band-h) / 2 + var(--band-gap));display:flex;flex-direction:column;gap:14px}
  .eyebrow,.panel-bridge .eyebrow,.panel-ground .eyebrow{justify-content:flex-start;margin:0 0 14px}
  .panel-bridge .chapter-title>.reveal-line,.panel-ground .chapter-title>.reveal-line{margin-left:-.03em}
  .panel-caption,.panel-ground .panel-caption{gap:4px;align-items:flex-start;margin:0;text-align:left}
  .pixel-spec{margin:0;padding-top:0}
}
@media(min-width:761px) and (max-aspect-ratio:4/5){
  :root{--chapter-size:clamp(48px,7vw,80px);--meta-reserve:80px}
  /* Portrait tablets: width-led sizing would leave the headline phone-sized. */
  .intro-title{font-size:clamp(40px,6.4vw,64px)}
}
@media(max-width:760px){
  :root{--gutter:16px;--grid-gap:16px;--chapter-size:clamp(34px,10vw,56px);--small-type:12px;--body-type:16px;--mono-type:11px;--header-bar:60px;--meta-reserve:28px;--grid-cell:27px}
  .site-header{top:4px;height:52px;padding:0;gap:20px}
  .brand-lockup img{width:42px}
  /* Phones keep only the film and the copy; the frame is zoomed 112% (fixed) to fill more of the screen. */
  :root{--band-scale:1.12}
  .film-grid,.film-meta{display:none}
  .pixel-spec{gap:0;align-items:baseline;padding-top:0;border:0;font-family:var(--font-mono);line-height:1.5}
  .pixel-spec div{flex-direction:row;align-items:baseline;gap:.6em}
  .pixel-spec div+div::before{content:'·';margin:0 .7em;color:#ffffff80}
  .pixel-spec dd{font-family:var(--font-mono);font-size:var(--mono-type);letter-spacing:.08em;line-height:1.5}
  .grid-field{-webkit-mask:radial-gradient(40% 15% at 84% 14%,#000 0,#000b 42%,transparent 100%),radial-gradient(34% 14% at 8% 88%,#000 0,#000b 42%,transparent 100%);mask:radial-gradient(40% 15% at 84% 14%,#000 0,#000b 42%,transparent 100%),radial-gradient(34% 14% at 8% 88%,#000 0,#000b 42%,transparent 100%)}
  .intro-title{font-size:clamp(28px,10vw,46px)}
  .intro-sub{font-size:13px;letter-spacing:.06em}
  /* Swiping is second nature on phones: keep only the arrow so it never crowds the sub line. */
  .intro-scroll span{display:none}
  .intro-scroll svg{height:22px}
  .film-meta{bottom:24px;gap:20px}
  .meta-type{display:none}
  .meta-product{display:block;margin-right:auto}
  .scroll-note span{margin-left:5px}
  .film-status{top:94px}
  .loader-edition{bottom:28px}
  .collection-aside{flex-direction:column;align-items:flex-start;gap:32px}
  .collection-link{width:100%;min-width:0}
  .collection h2{font-size:clamp(30px,9.2vw,52px)}
  .collection-rule{line-height:1.7}
  .product-index a{grid-template-columns:36px minmax(0,1fr) 40px;row-gap:6px;padding:22px 0}
  .pi-num{grid-row:1/3;align-self:start;padding-top:.5em}
  .pi-name{font-size:20px}
  .pi-en{grid-column:2;grid-row:2}
  .pi-arrow{grid-column:3;grid-row:1/3;width:40px;height:40px}
  footer{flex-wrap:wrap}
}
@media(max-width:760px) and (max-height:700px){
  :root{--chapter-size:clamp(32px,9vw,50px)}
  /* Short phones (e.g. an SE under Safari's bars): drop the English kicker so line 1 sits right under the header. */
  .intro-kicker{display:none}
}
/* Portrait screens (phones held upright, portrait tablets): the dedicated 9:16 film runs full-bleed.
   Its product always sits in the middle band, so the copy takes the dark areas above and below. */
@media(max-aspect-ratio:4/5){
  .film-media img,.film-media video{left:0;top:0;width:100%;height:100%;aspect-ratio:auto;transform:none;object-fit:cover;mask-image:none}
  .film-media{--spot-y:52%}
  .intro-spot{background:radial-gradient(ellipse 110% 40% at var(--spot-x) var(--spot-y),#00000033 0,#00000059 calc(var(--spot-r) * .45),#000000de var(--spot-r),#000 calc(var(--spot-r) * 1.6))}
  .film-shade{background:linear-gradient(180deg,#000b 0,#0000 30%,#0000 70%,#000c 100%)}
  .panel-intro::before{background:linear-gradient(180deg,#000b 0,transparent 28%,transparent 68%,#000d 100%)}
  /* The 9:16 film keeps its product at roughly 40–68% of the height, so the two lines hug that band. */
  .panel-intro{--foot-bottom:calc(28px + env(safe-area-inset-bottom,0px));--l1-top:max(calc(var(--header-bar) + 34px),calc(39svh - 88px));--l2-bottom:max(calc(var(--foot-bottom) + 38px),calc(32svh - 88px))}
  .intro-kicker{top:calc(var(--l1-top) - 30px);bottom:auto}
  .copy-head{top:calc(var(--header-bar) + 3svh);bottom:auto}
  .copy-foot{top:auto;bottom:calc(32px + env(safe-area-inset-bottom,0px))}
  .film-grid,.film-meta{display:none}
}
@media(max-width:600px){
  .film-story.is-ready{height:595svh}
  .film-dots{opacity:calc(.26 * var(--fx))}
  .film-grain{opacity:calc(.50 * var(--fx))}
}
@media(max-width:360px){
  :root{--gutter:14px;--intro-gutter:14px;--chapter-size:30px;--body-type:15px}
  .brand-lockup img{width:38px}
}

/* Sideways phones narrower than 761px: phone type tokens are sized for upright screens, so scale chapters to the short height. */
@media(max-width:760px) and (min-aspect-ratio:1/1){
  :root{--chapter-size:clamp(26px,8.4svh,40px)}
  /* The opening headline drops lower and smaller so it stays clear of the product. */
  .intro-title{font-size:clamp(22px,8.4svh,34px)}
}

/* Portrait tablets (after the portrait block so these win): wider than phones, so the cropped 9:16 film
   shows its product taller (≈36–75%) and both headline lines need more clearance. */
@media(min-width:761px) and (max-aspect-ratio:4/5){
  .panel-intro{--l1-top:calc(36svh - 92px);--l2-bottom:calc(25svh - 100px)}
}

/* Hero on upright screens: the dedicated 9:16 key visual (title at 32–70% across, 22–38% down) fills the screen with
   cover, centred: phones trim ~9–12% from each side, portrait tablets ~12% from top and bottom, never the title.
   It comes in three aligned 9:16 layers (background, title, units) for the scroll depth below.
   Headline above it, link at the foot. */
@media(max-aspect-ratio:4/5){
  /* Taller header bar; the key visual starts below it and keeps its full 100lvh, so the hero grows by the bar's height
     and what follows is pushed past the first screen. The bar area is the hero's own black, the same pure #000 as the key visual. */
  :root{--header-bar:84px}
  .site-header{top:16px;height:52px}
  .hero{height:calc(100vh + var(--header-bar));height:calc(100lvh + var(--header-bar))}
  .hero-media{top:var(--header-bar)}
  .hero-media img{object-position:50% 50%}
  /* Scroll depth: landing.js sets --hero-p from 0 to 1 over the hero's height. The background barely moves, the units
     push in hard about the centre unit (53.8% 77.4% of the frame on phones; x1.45 at the end, x1.15 a third of the way),
     and the title rises and fades out first. */
  .hero-layer-bg{transform:scale(calc(1 + .08 * var(--hero-p,0)));will-change:transform}
  .hero-layer-pd{transform-origin:54% 77%;transform:scale(calc(1 + .45 * var(--hero-p,0)));will-change:transform}
  .hero-layer-text{transform:translateY(calc(-20svh * var(--hero-p,0)));opacity:calc(1 - 1.8 * var(--hero-p,0));will-change:transform,opacity}
  /* The cut-off centre unit sinks into the black ground over the last 18%, then the film follows. */
  .hero::after{content:'';position:absolute;inset:auto 0 0;z-index:1;height:18%;pointer-events:none;background:linear-gradient(#0000,#000)}
  .hero-copy{top:calc(var(--header-bar) + 3svh);bottom:auto}
  .hero-foot{bottom:calc(20px + env(safe-area-inset-bottom,0px))}
  .hero-title{font-size:clamp(24px,4vw,36px)}
}
@media(max-width:760px) and (max-aspect-ratio:4/5){
  .hero-title{font-size:clamp(20px,6.2vw,28px)}
}
/* Sideways phones: tighter bottom spacing. */
@media(max-height:500px) and (min-aspect-ratio:1/1){
  .hero-copy{bottom:calc(max(14px,4svh) + 38px + 8px)}
  .hero-foot{bottom:max(14px,4svh)}
}

/* ============ 13. Reduced motion ============ */
@media(prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  *,*::before,*::after{animation:none!important;transition:none!important}
  .film-fx,.film-shutter,.film-marks,.loader-track{display:none}
  .film-stage.awaiting-reveal .film-media{opacity:1}
  .reveal-word{transform:none!important;filter:none!important;opacity:1!important}
  .collection.motion-enabled h2>span,.collection.motion-enabled .collection-rule{transform:none;opacity:1}
}
