/* SynMetabio · 3D Force-Sensing Electronic Skin — landing page styles.
   Mobile-first. Breakpoints: 768px (tablet), 1024px (desktop). */

/* ---------- Fonts (self-hosted, all from the client package 网站字体; see README section 4) ---------- */
@font-face {
  font-family: "Alternate Gothic No2";
  src: url("../fonts/alternate-gothic-no2-400.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Bison";
  src: url("../fonts/bison-700.woff2") format("woff2");
  font-weight: 700; /* the file says 300 in its OS/2 table, but it is the Bold cut */
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Barlow Semi Condensed";
  src: url("../fonts/barlow-semi-condensed-700.woff2") format("woff2");
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "HK Grotesk";
  src: url("../fonts/hk-grotesk-400.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "HK Grotesk";
  src: url("../fonts/hk-grotesk-500.woff2") format("woff2");
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "HK Grotesk";
  src: url("../fonts/hk-grotesk-600.woff2") format("woff2");
  font-weight: 600;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "HK Grotesk";
  src: url("../fonts/hk-grotesk-700.woff2") format("woff2");
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "HK Grotesk";
  src: url("../fonts/hk-grotesk-400-italic.woff2") format("woff2");
  font-weight: 400;
  font-style: italic;
  font-display: swap;
}

/* ---------- Tokens ---------- */
:root {
  --header-h: 60px; /* header once scrolled (the translucent bar); offsets below the header use this */
  --header-band: 72px; /* header over the opening film, before any scrolling */
  --gutter: 16px;
  --container: 1280px;

  --c-black: #000;
  --c-ink: #0b0d10;
  --c-graphite: #15181d;
  --c-steel-900: #1b2532;
  --c-steel-700: #33465a;
  --c-steel-500: #6b8197;
  --c-steel-300: #a7b9cb;
  --c-steel-100: #dbe6f1;
  --c-text: #f3f5f7;
  --c-text-dim: rgba(243, 245, 247, 0.76);
  --c-line: rgba(255, 255, 255, 0.5);
  --c-btn: rgba(224, 227, 230, 0.86);
  --c-btn-text: #101215;
  --c-dark-text: #0e1824;

  /* Function colours from the PDF callouts */
  --c-heat: #ff6f6f;
  --c-temp: #ffc793;
  --c-press: #fff3ca;
  /* Darker partners for use on light backgrounds */
  --c-heat-ink: #c03c3c;
  --c-temp-ink: #b5651d;
  --c-press-ink: #8f7420;

  --f-display: "Alternate Gothic No2", "Arial Narrow", sans-serif;
  --f-head: "Bison", "Arial Narrow", "Helvetica Neue", Arial, sans-serif;
  --f-ui: "Barlow Semi Condensed", "Arial Narrow", sans-serif;
  --f-body: "HK Grotesk", system-ui, -apple-system, "Segoe UI", "Helvetica Neue", Arial, "Noto Sans", sans-serif;

  --fs-body: 16px;
  /* Section type scale after synmetabio-standalone.html: headings, then reading copy. */
  --fs-title: clamp(2rem, 9.8vw, 4rem);
  --fs-lede: 0.98rem;
  --ease-out: cubic-bezier(0.2, 0.7, 0.2, 1);
}

@media (min-width: 768px) {
  :root {
    --header-h: 72px;
    --header-band: clamp(80px, calc(3.4vw + 46px), 102px); /* 46 px button + 1.7vw above and below */
    --gutter: 40px;
    --fs-body: 17px;
    --fs-title: clamp(2.3rem, 6.4vw, 8.8rem);
    --fs-lede: clamp(1rem, 1.4vw, 1.28rem);
  }
}

@media (min-width: 1024px) {
  :root {
    --header-h: 76px;
    --gutter: clamp(40px, 4.4vw, 72px);
    --fs-body: clamp(17px, 0.45vw + 11px, 19px);
  }
}

/* ---------- Base ---------- */
*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  background: var(--c-black);
  scroll-padding-top: calc(var(--header-h) + 12px);
}

body {
  margin: 0;
  background: var(--c-black);
  color: var(--c-text);
  font-family: var(--f-body);
  font-size: var(--fs-body);
  line-height: 1.6;
  overflow-x: clip;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}

img,
picture,
video,
svg {
  display: block;
  max-width: 100%;
}

p {
  margin: 0 0 1em;
}

a {
  color: inherit;
}

button,
input,
textarea {
  font: inherit;
}

:focus-visible {
  outline: 2px solid #fff;
  outline-offset: 3px;
}

[tabindex="-1"]:focus {
  outline: none;
}

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

.nowrap {
  white-space: nowrap;
}

.skip-link {
  position: fixed;
  top: 8px;
  left: 8px;
  z-index: 100;
  padding: 10px 16px;
  background: #fff;
  color: #000;
  font-weight: 600;
  text-decoration: none;
  transform: translateY(-160%);
  transition: transform 0.2s;
}

.skip-link:focus {
  transform: none;
}

.container {
  width: 100%;
  max-width: calc(var(--container) + 2 * var(--gutter));
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.section {
  position: relative;
}

/* Desktop text runs from the same gutter as the logo, as in synmetabio-standalone.html. */
@media (min-width: 1024px) {
  .container {
    max-width: none;
  }
}

/* ---------- Section typography (after synmetabio-standalone.html) ----------
   Large heading → reading copy at --fs-lede. Copy stays verbatim from the PDF. */
.section-title {
  margin: 0 0 0.5em;
  font-family: var(--f-head);
  font-weight: 700;
  font-size: var(--fs-title);
  line-height: 0.94;
  letter-spacing: 0.004em;
  text-transform: uppercase;
  text-wrap: balance;
  text-shadow: 0 8px 50px rgba(0, 0, 0, 0.25);
}

/* ---------- Background motion (P2, P3, P6, P8) ----------
   Settle: each background starts slightly enlarged and eases back over ~2 s whenever its section
   comes into view (site.js adds .settle-ready and toggles .is-inview on the section).
   Parallax: on desktop, P2 / P6 / P8 backgrounds also drift against the scroll (--parallax, set by
   site.js from data-parallax); their boxes bleed past the section so no edge ever shows. */
[data-settle] {
  overflow: hidden;
}

.settle-ready [data-settle] img,
.settle-ready [data-settle] video {
  transform: scale(1.055);
  transition: transform 1.8s var(--ease-out), opacity 0.8s ease;
}

.settle-ready .is-inview [data-settle] img,
.settle-ready .is-inview [data-settle] video {
  transform: none;
}

/* ---------- Buttons ---------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.7em;
  min-height: 44px;
  padding: 0.65em 1.15em 0.65em 1.35em;
  border: 0;
  border-radius: 0;
  font-family: var(--f-ui);
  font-weight: 700;
  font-size: 14px;
  line-height: 1;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  text-decoration: none;
  cursor: pointer;
  transition: background-color 0.2s, color 0.2s, box-shadow 0.2s;
}

.btn--light {
  background: var(--c-btn);
  color: var(--c-btn-text);
}

.btn--light:hover {
  background: #fff;
}

.btn--light:focus-visible {
  outline-color: #fff;
  box-shadow: 0 0 0 5px rgba(0, 0, 0, 0.45);
}

.btn__icon {
  width: 13px;
  height: 13px;
  fill: currentColor;
}

/* ---------- Header ----------
   One header for every screen, styled after the approved standalone build (synmetabio-standalone.html).
   Over the opening film it is transparent, with only a soft shade at the very top (keeps the white
   logo legible on bright frames) and clicks pass through the empty band. Once the page leaves the
   very top (site.js sets .is-scrolled) it settles into a slimmer, translucent black bar. */
.site-header {
  position: fixed;
  inset: 0 0 auto;
  z-index: 50;
  height: var(--header-band);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding-inline: var(--gutter);
  padding-top: env(safe-area-inset-top);
  box-sizing: content-box;
  pointer-events: none;
  transition: height 0.4s var(--ease-out), background-color 0.4s var(--ease-out), box-shadow 0.4s var(--ease-out);
}

.site-header > * {
  pointer-events: auto;
}

.site-header::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(180deg, rgba(2, 5, 8, 0.5), rgba(2, 5, 8, 0));
  pointer-events: none;
  transition: opacity 0.4s var(--ease-out);
}

.site-header.is-scrolled {
  height: var(--header-h);
  background: rgba(4, 7, 10, 0.74);
  -webkit-backdrop-filter: blur(18px) saturate(1.2);
  backdrop-filter: blur(18px) saturate(1.2);
  box-shadow: inset 0 -1px 0 rgba(255, 255, 255, 0.08);
  pointer-events: auto;
}

.site-header.is-scrolled::before {
  opacity: 0;
}

.site-header__brand {
  display: block;
  flex: none;
  border-radius: 2px;
}

.site-header__brand img {
  width: min(40vw, 160px);
  height: auto;
  filter: drop-shadow(0 2px 16px rgba(0, 0, 0, 0.35));
}

.site-header__cta {
  gap: 0.65rem;
  min-height: 40px;
  padding: 0.8rem 1.05rem;
  border-radius: 2px;
  /* Translucent fill (requested); the text stays fully dark so it reads on every screen. */
  background: rgba(217, 220, 217, 0.7);
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
  color: #080b0e;
  font-size: 0.69rem;
  letter-spacing: 0.16em;
  transition: background-color 0.35s var(--ease-out), box-shadow 0.35s var(--ease-out), opacity 0.3s, visibility 0s;
}

.site-header__cta:hover {
  background: #fff;
  box-shadow: 0 14px 34px rgba(0, 0, 0, 0.28);
}

.site-header__cta svg {
  flex: none;
  width: 14px;
  height: 14px;
  transition: transform 0.4s var(--ease-out);
}

.site-header__cta:hover svg {
  transform: translateX(3px);
}

/* Not shown on the contact screen itself (P9), as in the PDF; site.js sets .is-at-contact. */
.site-header.is-at-contact .site-header__cta {
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: background-color 0.35s, box-shadow 0.35s, opacity 0.3s, visibility 0s 0.3s;
}

@media (min-width: 768px) {
  .site-header__brand img {
    width: clamp(152px, 14.5vw, 216px);
  }

  .site-header__cta {
    min-height: 46px;
    padding: 0.92rem 1.35rem;
    font-size: 0.71rem;
  }
}

/* ---------- Reveal (only once the script has opted in) ---------- */
.reveal-ready [data-reveal] {
  opacity: 0;
  transform: translate3d(0, 26px, 0);
  transition: opacity 0.9s var(--ease-out), transform 0.9s var(--ease-out);
}

.reveal-ready [data-reveal].is-visible {
  opacity: 1;
  transform: none;
}

/* ---------- Shared media helpers ---------- */
.materials__media > picture,
.production__media > picture,
.about__media > picture,
.tile__media > picture {
  display: block;
  width: 100%;
  height: 100%;
}

.media-toggle {
  position: absolute;
  z-index: 3;
  width: 44px;
  height: 44px;
  display: grid;
  place-items: center;
  padding: 0;
  border: 1px solid rgba(255, 255, 255, 0.4);
  border-radius: 50%;
  background: rgba(0, 0, 0, 0.32);
  color: #fff;
  cursor: pointer;
  opacity: 0.72;
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
  transition: opacity 0.2s, background-color 0.2s;
}

.media-toggle:hover,
.media-toggle:focus-visible {
  opacity: 1;
  background: rgba(0, 0, 0, 0.55);
}

.media-toggle[hidden] {
  display: none;
}

.media-toggle svg {
  width: 18px;
  height: 18px;
  fill: currentColor;
}

.media-toggle__play,
.media-toggle[data-state="paused"] .media-toggle__pause {
  display: none;
}

.media-toggle[data-state="paused"] .media-toggle__play {
  display: block;
}

/* Sound button beside each play / pause button; the icon shows the current state (muted until the
   visitor's first tap, click or key press, see site.js). */
.media-sound__on,
.media-sound[data-state="on"] .media-sound__off {
  display: none;
}

.media-sound[data-state="on"] .media-sound__on {
  display: block;
}

/* Videos stay invisible until they actually play; the cover image is the fallback. */
[data-video-shell] video {
  opacity: 0;
  transition: opacity 0.8s ease;
}

[data-video-shell].has-played video {
  opacity: 1;
}

[data-video-shell].is-failed video {
  display: none;
}

/* ---------- P1 · Hero ----------
   Typography after the approved standalone build: a ruled eyebrow over a one-line title, bottom left,
   aligned with the logo. Everything sits in .hero__pin so the opening can hold the film in place. */
.hero {
  position: relative;
}

.hero__pin {
  position: relative;
  isolation: isolate;
  min-height: 100vh;
  min-height: 100svh;
  display: flex;
  align-items: flex-end;
  overflow: hidden;
  background: #1c140b;
}

.hero__media,
.hero__cover,
.hero__video,
.hero__shade {
  position: absolute;
  inset: 0;
}

.hero__media {
  z-index: -1;
}

.hero__cover img,
.hero__video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 50%;
}

/* Same as the supplied 「首页-视频上层-黑色渐变.png」 (white→black, used as multiply):
   no darkening for the top 18 %, then linear to black at the bottom edge. */
.hero__shade {
  background: linear-gradient(180deg, rgba(0, 0, 0, 0) 18%, #000 100%);
}

.hero__content {
  position: relative;
  width: 100%;
  /* clears the subtitles burnt into the bottom of the film */
  padding: calc(var(--header-band) + 32px) var(--gutter) max(80px, 12svh);
}

.hero__title {
  margin: 0;
  font-weight: 400;
}

.hero__eyebrow {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  font-family: var(--f-ui);
  font-weight: 700;
  font-size: clamp(0.72rem, 3vw, 0.82rem);
  line-height: 1;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  text-shadow: 0 2px 24px rgba(0, 0, 0, 0.35);
}

.hero__eyebrow::before {
  content: "";
  flex: none;
  width: 30px;
  height: 1px;
  background: rgba(255, 255, 255, 0.72);
}

/* Phones: two lines, "Deformation-Sensing" (about 7.5 em in Alternate Gothic No.2) kept whole on the
   first. */
.hero__main {
  display: block;
  margin-top: 0.6rem;
  font-family: var(--f-display);
  font-size: min(clamp(2.9rem, 13vw, 5.8rem), calc((100vw - 2 * var(--gutter)) / 7.6));
  line-height: 0.87;
  letter-spacing: 0.004em;
  text-transform: uppercase;
  text-wrap: balance;
  text-shadow: 0 12px 60px rgba(0, 0, 0, 0.38);
}

.hero__toggle,
.hero__sound {
  top: calc(var(--header-band) + env(safe-area-inset-top) + 8px);
  right: var(--gutter);
}

.hero__sound {
  right: calc(var(--gutter) + 52px);
}

@media (min-width: 768px) {
  .hero__content {
    padding-bottom: clamp(5.6rem, 9.5vh, 8.4rem);
  }

  .hero__eyebrow {
    gap: clamp(0.7rem, 1.2vw, 1.1rem);
    font-size: clamp(0.95rem, 1.53vw, 1.45rem);
    letter-spacing: 0.24em;
  }

  .hero__eyebrow::before {
    width: clamp(34px, 4.6vw, 68px);
  }

  /* One line, as large as the standalone build (7.7vw) but never wider than the space between the
     gutters: the title is about 13.1 em long in Alternate Gothic No.2. */
  .hero__main {
    margin-top: clamp(0.55rem, 1.1vw, 1.2rem);
    font-size: min(7.7vw, 10rem, calc((100vw - 2 * var(--gutter)) / 13.3));
    line-height: 0.84;
    white-space: nowrap;
  }

  .hero__toggle,
  .hero__sound {
    top: auto;
    bottom: clamp(1.3rem, 2.2vw, 2rem);
  }
}

/* Opening: html.hero-intro (set in <head>, kept by site.js unless reduced motion is on) turns P1 into
   a 125svh track whose first quarter screen holds the film in place. The page opens on the film
   alone; the eyebrow and title come in once the page leaves the very top (.is-revealed), then P1
   scrolls away. With desktop snapping, the extra quarter is one oversized snap area (like P4): the
   first wheel step stays in it and shows the title, the next one moves on to P2. */
.hero-intro .hero {
  height: 125vh;
  height: 125svh;
}

.hero-intro .hero__pin {
  position: sticky;
  top: 0;
}

.hero-intro .hero__eyebrow,
.hero-intro .hero__main {
  opacity: 0;
  transform: translate3d(0, 28px, 0);
  filter: blur(7px);
  transition: opacity 1.05s var(--ease-out), transform 1.05s var(--ease-out), filter 1.05s var(--ease-out);
}

.hero-intro .hero.is-revealed .hero__eyebrow,
.hero-intro .hero.is-revealed .hero__main {
  opacity: 1;
  transform: none;
  filter: none;
}

.hero-intro .hero.is-revealed .hero__main {
  transition-delay: 0.12s;
}

/* ---------- P2 · Materials ---------- */
.materials {
  isolation: isolate;
  overflow: hidden;
  /* flat where the image band fades out, so the join never shows */
  background: linear-gradient(180deg, #2e4159 0%, #2e4159 70%, #1d2a3b 100%);
}

.materials__media {
  position: relative;
  z-index: -2;
  aspect-ratio: 4 / 3.3;
}

.materials__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 76% 42%;
}

.materials__media::after {
  content: "";
  position: absolute;
  inset: auto 0 0;
  height: 46%;
  background: linear-gradient(180deg, rgba(46, 65, 89, 0) 0%, rgba(46, 65, 89, 0.86) 74%, #2e4159 100%);
}

.materials__scrim {
  display: none;
}

.materials__inner {
  position: relative;
  margin-top: -54px;
  padding-bottom: 64px;
}

.materials__copy {
  text-shadow: 0 1px 14px rgba(8, 16, 28, 0.35);
}

.materials__copy .section-title {
  max-width: 1040px;
  margin-bottom: clamp(1.4rem, 3.2vw, 3.2rem);
}

.materials__copy p {
  max-width: 46ch;
  margin-bottom: clamp(0.95rem, 1.6vw, 1.3rem);
  color: rgba(255, 255, 255, 0.84);
  font-size: var(--fs-lede);
  line-height: 1.6;
  text-wrap: pretty;
}

.materials__copy .materials__lead {
  font-size: 1.04em;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.92);
}

@media (min-width: 768px) {
  .materials__copy p {
    max-width: 660px;
  }
}

@media (min-width: 1024px) {
  .materials {
    min-height: 100svh;
    display: flex;
    align-items: center;
    padding-block: calc(var(--header-h) + min(48px, 4svh)) min(72px, 7svh);
    background: #6584a6;
  }

  /* Heading and the gap below it also follow the screen height, so P2 stays one screen on short
     wide windows (e.g. 1536 × 730, 1366 × 657). */
  .materials__copy .section-title {
    font-size: min(6.4vw, 10.5svh, 8.8rem);
    margin-bottom: clamp(1.2rem, min(3.2vw, 5svh), 3.2rem);
  }

  .materials__media {
    position: absolute;
    inset: -7% 0;
    aspect-ratio: auto;
    transform: translate3d(0, var(--parallax, 0px), 0);
    will-change: transform;
  }

  .materials__media img {
    object-position: 72% 50%;
  }

  .materials__media::after {
    display: none;
  }

  /* The scrim runs a little further right, under the wider heading. */
  .materials__scrim {
    display: block;
    position: absolute;
    inset: 0;
    z-index: -1;
    background: linear-gradient(90deg, rgba(16, 28, 44, 0.8) 0%, rgba(20, 34, 52, 0.66) 38%, rgba(26, 44, 66, 0.22) 62%, rgba(26, 44, 66, 0) 78%);
  }

  .materials__inner {
    margin-top: 0;
    padding-bottom: 0;
  }
}

/* ---------- P4 · Structure ---------- */
.structure {
  isolation: isolate;
  overflow: hidden;
  color: var(--c-dark-text);
  background: linear-gradient(180deg, #c9d9ea 0%, #dcebfa 100%);
  padding-block: 56px 64px;
}

/* Small screens: image right after the intro, so a selected layer is visible next to the list. */
.structure__grid {
  display: flex;
  flex-direction: column;
}

.structure__copy {
  display: contents;
}

.structure__copy > * {
  order: 2;
}

.structure__title,
.structure__copy > p:first-of-type {
  order: 0;
}

.structure__figure {
  order: 1;
  margin: 6px 0 4px;
}

.structure__title {
  font-size: clamp(40px, 11vw, 52px);
  line-height: 0.98;
}

.structure__copy > p {
  max-width: 560px;
  color: rgba(14, 24, 36, 0.86);
}

.structure__hint {
  margin: 1.4em 0 0.7em;
  font-size: 0.8em;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: rgba(14, 24, 36, 0.62);
}

.fn-list {
  display: grid;
  gap: 8px;
  max-width: 560px;
  margin: 0 0 1.4em;
  padding: 0;
  list-style: none;
}

.fn {
  --accent: var(--c-press);
  --accent-ink: var(--c-press-ink);
  position: relative;
  display: grid;
  grid-template-columns: 12px minmax(0, 1fr);
  column-gap: 14px;
  row-gap: 2px;
  width: 100%;
  padding: 13px 16px 14px;
  border: 1px solid rgba(14, 24, 36, 0.14);
  background: rgba(255, 255, 255, 0.3);
  color: inherit;
  text-align: left;
  cursor: pointer;
  transition: background-color 0.25s, border-color 0.25s, opacity 0.25s, box-shadow 0.25s;
}

.fn[data-fn="temperature"] {
  --accent: var(--c-temp);
  --accent-ink: var(--c-temp-ink);
}

.fn[data-fn="heating"] {
  --accent: var(--c-heat);
  --accent-ink: var(--c-heat-ink);
}

.fn:hover {
  background: rgba(255, 255, 255, 0.5);
}

.fn:focus-visible {
  outline: 2px solid var(--c-dark-text);
  outline-offset: 2px;
}

.fn__dot {
  grid-row: 1 / span 2;
  width: 12px;
  height: 12px;
  margin-top: 0.36em;
  border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 0 1px rgba(14, 24, 36, 0.4);
}

.fn__name {
  font-family: var(--f-head);
  font-weight: 700;
  font-size: 19px;
  line-height: 1.2;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.fn__text {
  grid-column: 2;
  font-size: 0.92em;
  line-height: 1.5;
  color: rgba(14, 24, 36, 0.82);
}

.fn[aria-pressed="true"] {
  background: rgba(255, 255, 255, 0.78);
  border-color: var(--accent-ink);
  box-shadow: inset 4px 0 0 var(--accent-ink);
}

.structure.has-selection .fn[aria-pressed="false"] {
  opacity: 0.58;
}

.structure.has-selection .fn[aria-pressed="false"]:hover,
.structure.has-selection .fn[aria-pressed="false"]:focus-visible {
  opacity: 0.9;
}

.structure__stage {
  position: relative;
  aspect-ratio: 3142 / 2222;
  container-type: inline-size;
}

.structure__art,
.structure__art picture,
.structure__art img,
.structure__overlay,
.structure__callouts {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}

/* Small screens: the artwork sits as a card inside the reading column. The gradient matches the
   artwork's backdrop and doubles as the placeholder while the image loads. */
.structure__art {
  overflow: hidden;
  border-radius: 10px;
  background: linear-gradient(229.5deg, #304251 0%, #758a9f 32%, #b9cde3 62%, #d4e6f8 100%);
  box-shadow: 0 18px 40px -24px rgba(14, 24, 36, 0.55);
}

.structure__overlay {
  overflow: visible;
}

.structure__defocus {
  opacity: 0;
  transition: opacity 0.45s ease;
}

.structure.has-selection .structure__defocus {
  opacity: 1;
}

.region {
  opacity: 0;
  transition: opacity 0.4s ease;
}

.region.is-active {
  opacity: 1;
}

.anchor {
  fill: none;
  stroke: var(--c-press);
  stroke-width: 10;
  opacity: 0;
  transform-box: fill-box;
  transform-origin: center;
  transition: opacity 0.3s ease;
}

.anchor[data-anchor="temperature"] {
  stroke: var(--c-temp);
}

.anchor[data-anchor="heating"] {
  stroke: var(--c-heat);
}

.anchor.is-active {
  opacity: 1;
  animation: anchor-pulse 1.8s ease-out infinite;
}

@keyframes anchor-pulse {
  0% {
    transform: scale(0.7);
    opacity: 1;
  }
  70%,
  100% {
    transform: scale(1.9);
    opacity: 0;
  }
}

/* Labels sit where the designer placed them in 「背景-p4.png」 (removed from the web image and drawn
   as live text): left edge at --x, cap-height centre at --y, size 2.1 % of the artwork width with a
   12 px floor so they stay legible on phones. */
.callout {
  --accent: var(--c-press);
  position: absolute;
  left: var(--x);
  top: var(--y);
  margin-left: -0.5em;
  padding: 0.24em 0.5em;
  border: 0;
  border-radius: 3px;
  background: transparent;
  color: var(--accent);
  font-family: var(--f-body);
  font-weight: 400;
  font-size: clamp(12px, 2.1cqw, 20px);
  line-height: 1;
  letter-spacing: 0.01em;
  white-space: nowrap;
  text-shadow: 0 2px 6px rgba(10, 18, 28, 0.45);
  transform: translateY(-50%);
  cursor: pointer;
  transition: background-color 0.25s, color 0.25s, box-shadow 0.25s, text-shadow 0.25s;
}

.callout--heating {
  --accent: var(--c-heat);
  --x: 57.77%;
  --y: 22.89%;
}

.callout--temperature {
  --accent: var(--c-temp);
  --x: 60.95%;
  --y: 42.57%;
}

.callout--pressure {
  --x: 66.2%;
  --y: 60.42%;
}

.callout:hover {
  box-shadow: inset 0 -1px 0 var(--accent);
}

.callout.is-active {
  background: var(--accent);
  color: #10161f;
  text-shadow: none;
  box-shadow: 0 6px 18px -8px rgba(10, 18, 28, 0.6);
}

/* P4 layered mode (data-mode="layers"): used once separate layer artwork exists; markup in README.md.
   Each layer image is exported on the full canvas at its exploded position; --collapse-x/-y move it
   onto the stack. Labels appear one after another once the layers have spread out. */
.layers-toggle {
  margin: 4px 0 18px;
}

.layer-stack {
  position: relative;
  aspect-ratio: var(--stage-ratio, 3142 / 2222);
}

.layer-stack .layer {
  position: absolute;
  inset: 0;
  transition: transform 0.85s var(--ease-out);
  transition-delay: calc(var(--i, 0) * 50ms);
}

.layer-stack .layer img {
  width: 100%;
  height: 100%;
  object-fit: contain;
}

.layer-stack[data-state="collapsed"] .layer {
  transform: translate(var(--collapse-x, 0%), var(--collapse-y, 0%));
}

.layer__label {
  --accent: var(--c-press);
  position: absolute;
  left: var(--label-x, 76%);
  top: var(--label-y, 50%);
  padding: 0.32em 0.6em;
  border-radius: 2px;
  background: rgba(12, 18, 27, 0.6);
  color: var(--accent);
  font-size: 14px;
  white-space: nowrap;
  transition: opacity 0.35s ease;
  transition-delay: calc(450ms + var(--i, 0) * 120ms);
}

.layer-stack[data-state="collapsed"] .layer__label {
  opacity: 0;
  transition-delay: 0ms;
}

.btn--ink {
  background: var(--c-dark-text);
  color: #fff;
}

.btn--ink:hover {
  background: #22344a;
}

.btn--ink:focus-visible {
  outline-color: var(--c-dark-text);
}

@media (min-width: 768px) {
  .structure {
    padding-block: calc(var(--header-h) + 40px) 72px;
  }

}

@media (min-width: 1024px) {
  .structure {
    min-height: 100svh;
    display: flex;
    align-items: center;
    background: #d8e8fd;
  }

  .structure__grid {
    display: grid;
    grid-template-columns: minmax(0, 5.2fr) minmax(0, 6.8fr);
    align-items: center;
    gap: clamp(24px, 3.4vw, 56px);
  }

  .structure__copy {
    display: block;
  }

  .structure__title {
    font-size: clamp(44px, 4.3vw, 64px);
  }

  .structure__figure {
    margin: 0 calc(-1 * var(--gutter)) 0 0;
  }

  /* Desktop: the artwork bleeds into the section. The section colour continues the image's own
     backdrop — a linear gradient fitted to the source pixels (mean error ≈ 4/255) — anchored to the
     figure so the join stays seamless at every viewport size. Refit if the artwork is replaced. */
  .structure__stage::before {
    content: "";
    position: absolute;
    inset: -100% 0 -100% -150%;
    z-index: -1;
    background: linear-gradient(229.5deg, #304251 10%, #4b5f72 20%, #758a9f 30%, #a2b7cd 40%, #d1e4fc 50%, #d8e8fd 60%);
    pointer-events: none;
  }

  .structure__art {
    border-radius: 0;
    background: none;
    box-shadow: none;
    -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 10%, #000 100%), linear-gradient(180deg, transparent 0, #000 9%, #000 91%, transparent 100%);
    -webkit-mask-composite: source-in;
    mask-image: linear-gradient(90deg, transparent 0, #000 10%, #000 100%), linear-gradient(180deg, transparent 0, #000 9%, #000 91%, transparent 100%);
    mask-composite: intersect;
  }

}

/* P4 · Full-screen structure. The native scroll container remains unclipped for sticky. */
.structure--scroll {
  display: block;
  overflow: visible;
  min-height: 0;
  padding: 0;
  background: #8ea5bb;
}

.structure__pin {
  position: relative;
  width: 100%;
  height: 100svh;
  overflow: clip;
  background: #8ea5bb;
}

/* Extend the original backdrop to fill portrait and ultrawide screens, while preserving
   every layer and the original labels inside the complete 16:9 animation. */
.structure__pin::before {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(112deg, #a9bfd4, #c6dff5 30%, #8fa6ba 60%, #4a6073);
}

.structure--scroll .structure__figure {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  margin: 0;
}

.structure__sequence {
  position: absolute;
  top: 50%;
  left: 18%;
  width: 90%;
  aspect-ratio: 16 / 9;
  transform: translateY(-50%);
  overflow: hidden;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 18%, #000), linear-gradient(180deg, transparent, #000 6%, #000 94%, transparent);
  -webkit-mask-composite: source-in;
  mask-image: linear-gradient(90deg, transparent, #000 18%, #000), linear-gradient(180deg, transparent, #000 6%, #000 94%, transparent);
  mask-composite: intersect;
}

.structure__poster,
.structure__poster img,
.structure__scrub-video {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
}

.structure__scrub-video {
  opacity: 0;
  pointer-events: none;
}

.is-frame-ready .structure__scrub-video {
  opacity: 1;
}

.is-frame-ready .structure__poster {
  visibility: hidden;
}

.structure__editorial {
  position: absolute;
  inset: 0;
  color: #fff;
  text-shadow: 0 2px 5px rgba(32, 51, 67, 0.58);
  pointer-events: none;
}

/* A soft shade behind the white copy on the pale backdrop (the standalone build sets this copy over a
   darkened left side; lighter here, so the screen keeps its pale look). */
.structure__editorial::before {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(90deg, rgba(22, 38, 56, 0.55) 0%, rgba(22, 38, 56, 0.34) 34%, rgba(22, 38, 56, 0) 66%);
}

.structure__headline {
  position: absolute;
  top: max(18svh, calc(var(--header-h) + env(safe-area-inset-top) + 24px));
  left: 5.6%;
  margin: 0;
  font-family: var(--f-head);
  font-size: clamp(48px, 6.4vw, 8.8rem);
  line-height: 0.94;
  font-weight: 700;
  letter-spacing: 0.004em;
  text-transform: uppercase;
  text-shadow: 0 5px 8px rgba(32, 51, 67, 0.4);
}

.structure__headline span {
  display: block;
}

.structure__description {
  position: absolute;
  left: 5.8%;
  bottom: 15%;
  /* Wider and larger than the standalone build's 590 px column (requested); also follows the
     screen height so it never reaches the heading on short windows. */
  width: min(56%, 800px);
  font-size: clamp(1.02rem, min(1.45vw, 2.6svh), 1.35rem);
  line-height: 1.6;
  letter-spacing: 0.01em;
  text-wrap: pretty;
}

.structure__description p {
  margin: 0 0 clamp(0.9rem, 1.5vw, 1.25rem);
}

.structure__description p:last-child {
  margin-bottom: 0;
}

/* The PDF's manual line breaks belong to its wider text column. */
.structure__desktop-break {
  display: none;
}

.structure--scroll.is-scroll-pinned {
  height: 300svh;
}

.is-scroll-pinned .structure__pin {
  position: sticky;
  top: 0;
}

@media (max-width: 767px) {
  .structure--scroll.is-scroll-pinned {
    height: 240svh;
  }
}

@media (max-width: 767px), (max-aspect-ratio: 1 / 1) {
  /* Portrait: heading at the top, copy along the bottom. */
  .structure__editorial::before {
    background:
      linear-gradient(180deg, rgba(22, 38, 56, 0.4) 0%, rgba(22, 38, 56, 0) 30%),
      linear-gradient(0deg, rgba(22, 38, 56, 0.62) 0%, rgba(22, 38, 56, 0.34) 30%, rgba(22, 38, 56, 0) 50%);
  }

  .structure__headline {
    top: calc(var(--header-h) + env(safe-area-inset-top) + 24px);
    left: 6%;
    font-size: clamp(2rem, 9.8vw, 4rem);
  }

  .structure__description {
    left: 6%;
    bottom: 3.5%;
    width: 88%;
    font-size: clamp(14px, 3.7vw, 18px);
    line-height: 1.5;
  }

  .structure__description p {
    margin-bottom: 0.8em;
  }

  .structure__sequence {
    left: -10%;
    top: 38%;
    width: 120%;
    -webkit-mask-image: linear-gradient(180deg, transparent, #000 12%, #000 88%, transparent);
    mask-image: linear-gradient(180deg, transparent, #000 12%, #000 88%, transparent);
  }
}

/* Short landscape windows read the complete composition in natural flow. */
@media (max-height: 600px) {
  .structure--scroll .structure__pin {
    height: 700px;
  }

}

/* ---------- P3 · Sensing ---------- */
.sensing {
  isolation: isolate;
  overflow: hidden;
  background: #1d2430;
}

/* Native frame proportions everywhere: the stretching action and the data panel are never cropped.
   Update the ratio if the final video uses a different frame size. */
.sensing__media {
  position: relative;
  aspect-ratio: 16 / 9; /* frame size of 「10月26日(1).mp4」 */
}

.sensing__cover,
.sensing__video {
  position: absolute;
  inset: 0;
}

.sensing__cover img,
.sensing__video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 50%;
}

.sensing__scrim {
  display: none;
}

.sensing__toggle,
.sensing__sound {
  right: 12px;
  bottom: 12px;
}

.sensing__sound {
  right: 64px;
}

.sensing__inner {
  padding-block: 32px 64px;
}

.sensing__copy p {
  max-width: 46ch;
  margin: 0;
  color: rgba(255, 255, 255, 0.9);
  font-size: var(--fs-lede);
  line-height: 1.6;
  text-wrap: pretty;
}

@media (min-width: 768px) {
  .sensing__inner {
    padding-block: 40px 72px;
  }

  .sensing__copy p {
    max-width: 720px;
  }
}

/* Desktop: the video fills the whole screen behind the transparent header, like P1. Screens that
   are not 16:9 crop the edges; the crop leans left and up so the ΔC data panel at the upper right
   stays in frame. The copy sits at the lower right behind a local scrim and steps aside a few
   seconds into playback (site.js initSensingCopy sets .is-copy-hidden), returning whenever the
   video pauses. */
@media (min-width: 1024px) {
  .sensing__frame {
    position: relative;
    isolation: isolate;
    height: 100svh;
  }

  .sensing__media {
    position: absolute;
    inset: 0;
    z-index: -2;
    aspect-ratio: auto;
  }

  .sensing__cover img,
  .sensing__video {
    object-position: 72% 24%;
  }

  .sensing__scrim {
    display: block;
    position: absolute;
    inset: 0;
    z-index: -1;
    pointer-events: none;
    background: radial-gradient(64% 58% at 76% 90%, rgba(8, 12, 18, 0.78) 0%, rgba(8, 12, 18, 0.5) 48%, rgba(8, 12, 18, 0) 84%);
    transition: opacity 1.05s var(--ease-out);
  }

  .sensing__inner {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: flex-end;
    justify-content: flex-end;
    padding-block: var(--header-h) clamp(40px, 8svh, 96px);
    pointer-events: none; /* full-frame layer: clicks reach the video toggle underneath */
    transition: opacity 1.05s var(--ease-out), transform 1.05s var(--ease-out), filter 1.05s var(--ease-out);
  }

  /* Lower right, in wide lines (requested). */
  .sensing__copy {
    width: min(1040px, 64vw);
    text-shadow: 0 2px 26px rgba(0, 0, 0, 0.55);
    pointer-events: auto;
  }

  .sensing__copy p {
    max-width: none;
  }

  .sensing.is-copy-hidden .sensing__inner {
    opacity: 0;
    transform: translate3d(0, 20px, 0);
    filter: blur(6px);
  }

  .sensing.is-copy-hidden .sensing__copy {
    pointer-events: none;
  }

  .sensing.is-copy-hidden .sensing__scrim {
    opacity: 0;
  }

  /* One line (requested): the heading is 10.1 em long in Bison, so its size follows the copy
     width (64vw, at most 1040 px). */
  .sensing__copy .section-title {
    margin-bottom: clamp(0.9rem, 1.6vw, 1.5rem);
    font-size: min(6.2vw, 6.25rem, 10svh);
    line-height: 0.9;
    text-shadow: 0 12px 64px rgba(0, 0, 0, 0.48);
  }

  .sensing__toggle,
  .sensing__sound {
    top: auto;
    right: auto;
    left: var(--gutter);
    bottom: clamp(24px, 3vw, 48px);
  }

  .sensing__sound {
    left: calc(var(--gutter) + 52px);
  }
}

/* ---------- P5 · Specifications ---------- */
.specs {
  background: var(--c-black);
  padding-block: 64px 56px;
}

.specs__grid {
  display: grid;
  gap: 36px;
}

.specs .section-title {
  font-size: clamp(1.9rem, 8.5vw, 3.2rem);
  margin-bottom: clamp(1.2rem, 3vw, 2.6rem);
}

.spec-list {
  margin: 0;
}

/* Open table after the standalone build: hairline rows, bright keys, dimmer values. */
.spec {
  padding: 0.75rem 0.55rem;
  border-bottom: 1px solid rgba(255, 255, 255, 0.16);
}

.spec:first-child {
  border-top: 1px solid rgba(255, 255, 255, 0.3);
}

.spec dt {
  margin-bottom: 0.25rem;
  color: rgba(255, 255, 255, 0.92);
  font-size: 0.88rem;
  font-weight: 500;
  line-height: 1.35;
}

.spec dd {
  margin: 0;
  color: rgba(255, 255, 255, 0.66);
  font-size: 0.9rem;
  line-height: 1.45;
  overflow-wrap: break-word;
}

.spec .qual {
  color: rgba(255, 255, 255, 0.5);
}

.spec__mark {
  margin-left: 1px;
  color: #fff;
  font-weight: 700;
}

/* Pointer highlight: the row under the mouse turns light and its key steps in. */
@media (hover: hover) and (pointer: fine) {
  .spec {
    transition: background-color 0.3s var(--ease-out), padding 0.3s var(--ease-out);
  }

  .spec dt,
  .spec dd,
  .spec .qual,
  .spec__mark {
    transition: color 0.3s var(--ease-out);
  }

  .spec:hover {
    padding-left: 0.8rem;
    background: #e8edf1;
  }

  .spec:hover dt,
  .spec:hover dd,
  .spec:hover .qual,
  .spec:hover .spec__mark {
    color: #070a0d;
  }
}

.specs__figure {
  order: -1;
  width: min(100%, 420px);
  margin: 0 auto;
}

/* The leader lines and dots are part of the artwork; the labels are live text at the positions the
   designer used in 「P6 右侧.png」: left edge at --x, cap-height centre at --y (scales with the image,
   12 px floor on phones). */
.specs__art {
  position: relative;
  container-type: inline-size;
}

.specs__art img {
  width: 100%;
  height: auto;
}

.layer-tag {
  --accent: var(--c-press);
  position: absolute;
  left: var(--x);
  top: var(--y);
  color: var(--accent);
  font-size: clamp(12px, 3.15cqw, 18px);
  line-height: 1;
  letter-spacing: 0.01em;
  white-space: nowrap;
  text-shadow: 0 2px 6px rgba(0, 0, 0, 0.6);
  transform: translateY(-50%);
}

.layer-tag--heating {
  --accent: var(--c-heat);
  --x: 66.28%;
  --y: 23.18%;
}

.layer-tag--temperature {
  --accent: var(--c-temp);
  --x: 66.28%;
  --y: 42.01%;
}

.layer-tag--pressure {
  --x: 73.64%;
  --y: 60.97%;
}

.specs__note {
  max-width: 840px;
  margin: 28px 0 0;
  font-size: clamp(0.72rem, 0.78vw, 0.8rem);
  line-height: 1.6;
  color: rgba(255, 255, 255, 0.56);
}

.specs__note-label {
  display: block;
  margin-bottom: 2px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--c-text);
}

@media (min-width: 768px) {
  .specs {
    padding-block: calc(var(--header-h) + 32px) 64px;
  }

  .specs .section-title {
    font-size: clamp(2rem, 4.4vw, 4.6rem);
  }

  .spec {
    display: grid;
    grid-template-columns: minmax(150px, 0.42fr) minmax(0, 1fr);
    column-gap: clamp(0.8rem, 1.4vw, 1.4rem);
    padding: 0.72rem 0.9rem;
  }

  .spec dt,
  .spec dd {
    font-size: clamp(0.82rem, 0.98vw, 1rem);
    line-height: 1.35;
  }

  .spec dt {
    margin: 0;
  }

  .specs__figure {
    width: min(100%, 520px);
  }
}

@media (min-width: 768px) and (hover: hover) and (pointer: fine) {
  .spec:hover {
    padding-left: 1.25rem;
  }
}

@media (min-width: 1024px) {
  .specs {
    /* Layer image (1806 × 2015): at most 720 px wide and half the content width (--fig-share),
       and never taller than the screen leaves room for. */
    --fig-w: min(720px, calc((100svh - var(--header-h) - 160px) * 0.896));
    --fig-share: 50%;
    min-height: 100svh;
    display: flex;
    flex-direction: column;
    justify-content: center;
    padding-block: calc(var(--header-h) + clamp(12px, 2.5vh, 32px)) clamp(20px, 3.5vh, 48px);
  }

  /* The image spans the title row as well as the table, so it can be larger while P5 still fits
     one screen; the title and the table are centred beside it as one block. */
  .specs > .container {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(240px, min(var(--fig-w), var(--fig-share)));
    grid-template-rows: 1fr auto auto 1fr auto;
    column-gap: clamp(28px, 3.4vw, 64px);
  }

  .specs__grid {
    display: contents;
  }

  .specs .section-title {
    grid-area: 2 / 1;
  }

  .spec-list {
    grid-area: 3 / 1;
  }

  /* Shifted right into the page margin (requested): the right part of the artwork beyond the
     labels is black, like the section, so the labels still end inside the content edge. */
  .specs__figure {
    grid-area: 1 / 2 / 5 / 3;
    align-self: center;
    justify-self: end;
    width: 100%;
    max-width: var(--fig-w);
    margin-right: calc(-1 * var(--gutter));
  }

  .specs__note {
    grid-area: 5 / 1 / 6 / 3;
  }
}

/* Shorter (≤ 1040 px) or narrower (1024–1279 px) desktop screens: tighter table so P5 still
   fits one screen. */
@media (min-width: 1024px) and (max-height: 1040px), (min-width: 1024px) and (max-width: 1279px) {
  .specs {
    /* The layer image may not outgrow the screen either. */
    --fig-w: min(720px, calc((100svh - var(--header-h) - 110px) * 0.896));
    padding-top: calc(var(--header-h) + 10px);
    padding-bottom: 16px;
  }

  .specs .section-title {
    margin-bottom: 0.4em;
    font-size: min(4.4vw, 7svh);
  }

  .spec {
    padding-block: 0.38rem;
  }

  /* The table text also follows the screen height here. */
  .spec dt,
  .spec dd {
    font-size: clamp(0.8rem, min(0.98vw, 1.9svh), 1rem);
  }

  .specs__note-label {
    display: inline;
  }

  .specs__note {
    margin-top: 14px;
  }
}

/* Narrower desktops (1024–1279 px): the table takes more of the width, and as more rows still
   wrap, they are tighter as well. */
@media (min-width: 1024px) and (max-width: 1279px) {
  .specs {
    --fig-share: 36%;
  }

  .spec {
    padding-block: 0.36rem;
  }

  .specs__note-label {
    display: inline;
  }
}

/* Short desktop windows (≤ 720 px inside the browser, e.g. 1366 × 657 or 1536 × 730). */
@media (min-width: 1024px) and (max-height: 720px) {
  .specs {
    --fig-w: min(720px, calc((100svh - var(--header-h) - 70px) * 0.896));
    padding-top: calc(var(--header-h) + 4px);
    padding-bottom: 12px;
  }

  .specs .section-title {
    margin-bottom: 0.3em;
  }

  .spec {
    padding-block: 0.3rem;
  }

  .spec dt,
  .spec dd {
    font-size: clamp(0.75rem, min(0.98vw, 1.9svh), 1rem);
    line-height: 1.3;
  }

  .specs__note {
    margin-top: 10px;
    font-size: 12px;
    line-height: 1.45;
  }

  .specs__note-label {
    display: inline;
  }
}

/* ---------- P6 · Production ---------- */
.production {
  isolation: isolate;
  overflow: hidden;
  background: linear-gradient(180deg, #1c2733 0%, #1c2733 70%, #12181f 100%);
}

.production__media {
  position: relative;
  z-index: -2;
  aspect-ratio: 4 / 3;
}

.production__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 62% 50%;
}

.production__media::after {
  content: "";
  position: absolute;
  inset: 0;
  background:
    linear-gradient(180deg, rgba(58, 79, 97, 0) 50%, rgba(28, 39, 51, 0.92) 92%, #1c2733 100%),
    rgba(46, 66, 86, 0.1);
}

.production__scrim {
  display: none;
}

.production__inner {
  position: relative;
  margin-top: -64px;
  padding-bottom: 64px;
}

.production__copy {
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.45), 0 2px 18px rgba(0, 0, 0, 0.5);
}

/* One long line on desktop, as the standalone build's "wide" heading. */
.production__copy .section-title {
  font-size: clamp(1.75rem, 7.6vw, 3rem);
  line-height: 0.98;
}

.production__copy p {
  max-width: 46ch;
  color: rgba(255, 255, 255, 0.82);
  font-size: var(--fs-lede);
  line-height: 1.6;
  text-wrap: pretty;
}

@media (min-width: 768px) {
  .production__copy .section-title {
    font-size: clamp(1.9rem, 3.75vw, 4.35rem);
  }

  .production__copy p {
    max-width: 1280px;
  }
}

.production__copy .btn {
  margin-top: 1.2em;
  text-shadow: none;
}

@media (min-width: 1024px) {
  /* Copy centred on the full screen (requested): equal space above and below, as the header
     overlays the top. */
  .production {
    min-height: 100svh;
    display: flex;
    align-items: center;
    padding-block: var(--header-h);
    background: #2f4152;
  }

  .production__media {
    position: absolute;
    inset: -7% 0;
    aspect-ratio: auto;
    transform: translate3d(0, var(--parallax, 0px), 0);
    will-change: transform;
  }

  .production__media img {
    object-position: 50% 50%;
  }

  .production__media::after {
    display: none;
  }

  .production__scrim {
    display: block;
    position: absolute;
    inset: 0;
    z-index: -1;
    /* Just a faint veil over the factory, a touch deeper behind the centred copy; the copy's own
       shadow does the rest. */
    background:
      radial-gradient(ellipse 58% 44% at 50% 50%, rgba(3, 8, 12, 0.28) 0%, rgba(3, 8, 12, 0) 100%),
      rgba(3, 8, 12, 0.16);
  }

  .production__inner {
    margin-top: 0;
    padding-bottom: 0;
  }

  /* The copy block is centred on the screen; its text stays left-aligned. */
  .production__copy {
    max-width: 1280px;
    margin-inline: auto;
  }
}

/* ---------- P7 · Applications ---------- */
.apps {
  background: var(--c-black);
  padding-block: 64px 72px;
}

.apps__inner {
  display: flex;
  flex-direction: column;
}

.apps__title {
  margin-bottom: 28px;
  font-size: clamp(1.35rem, 6.1vw, 2.3rem);
  line-height: 1.05;
}

.apps__deco {
  display: none;
}

.apps__tiles {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 12px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.tile figure {
  position: relative;
  height: 100%;
  margin: 0;
  overflow: hidden;
  border-radius: 14px;
  background: var(--c-graphite);
}

.tile__media {
  aspect-ratio: 1 / 1;
  overflow: hidden;
}

.tile__media picture,
.tile__media img {
  width: 100%;
  height: 100%;
}

.tile__media img {
  object-fit: cover;
  object-position: var(--focus, 50% 50%);
  transition: transform 0.3s ease;
}

.tile__label {
  position: absolute;
  inset: auto 0 0;
  padding: 28px 8px 9px;
  /* Lighter shade than before (0.62); the text shadow keeps the labels readable on pale photos. */
  background: linear-gradient(180deg, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0.45) 100%);
  color: #fff;
  font-weight: 500;
  font-size: 13px;
  line-height: 1.3;
  letter-spacing: 0.04em;
  text-align: center;
  text-shadow: 0 1px 8px rgba(0, 0, 0, 0.6);
}

.tile--pillow {
  --focus: 52% 60%;
}
.tile--torso {
  --focus: 58% 40%;
}
.tile--sleeve {
  --focus: 42% 50%;
}
.tile--mattress {
  --focus: 52% 55%;
}
.tile--patch {
  --focus: 50% 35%;
}
.tile--seat {
  --focus: 50% 40%;
}
.tile--wristband {
  --focus: 55% 45%;
}
.tile--fabric {
  --focus: 48% 35%;
}
.tile--hand {
  --focus: 50% 30%;
}

/* Hover zoom stays inside the fixed frame in the grid; tiles are not interactive.
   The desktop collage enlarges the whole tile instead (see the P7 collage block below). */
@media (hover: hover) and (pointer: fine) {
  .tile figure:hover img {
    transform: scale(1.12);
  }
}

@media (min-width: 768px) {
  .apps {
    padding-block: calc(var(--header-h) + 24px) 88px;
  }

  .apps__tiles {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 14px;
  }

  .tile__media {
    aspect-ratio: 4 / 3;
  }

  .tile__label {
    font-size: 14px;
  }

  .apps__title {
    font-size: clamp(1.45rem, 3.35vw, 4rem);
    line-height: 1;
  }
}

/* Desktop: the PDF's full-screen collage. Decoration blocks and photos sit on a 16:9 artboard
   (positions measured from the PDF, in % of the artboard) that fills the screen like the PDF page:
   on a 16:9 screen it is the screen; on other shapes it is cropped at the edges (only ever into the
   decoration) and shifted so the photos stay centred, clear of the header and the title. The title
   runs in one line along the bottom, as in the PDF. */
@media (min-width: 1024px) {
  .apps {
    /* Artboard width: covers the screen, but stays small enough that the photos (14–78 % of its
       width, 19–76 % of its height) are never cut off at the sides or run under the header (76 px)
       or into the title. */
    --art-w: min(max(100vw, 177.78svh), (100vw - 48px) * 1.57, 2.868 * 100svh - 482px, 2.493 * 100svh - 111px);
    --tile-r: calc(var(--art-w) * 0.013);
    height: 100svh;
    min-height: 0;
    padding: 0;
    overflow: hidden;
    isolation: isolate;
  }

  .apps__inner {
    max-width: none;
    margin: 0;
    padding: 0;
  }

  /* Positioned without a transform, so a tile enlarged on hover can rise above the title. The
     screen shows the part of the artboard centred on the photos (centre at 45.9 %) as far as the
     artboard reaches; an artboard narrower than the screen is simply centred. */
  .apps__mosaic {
    position: absolute;
    top: calc(50% - var(--art-w) * 0.28125);
    left: calc(50% - clamp(min(50%, var(--art-w) / 2), var(--art-w) * 0.459, max(var(--art-w) - 50%, var(--art-w) / 2)));
    width: var(--art-w);
    aspect-ratio: 16 / 9;
  }

  /* Baseline at 90.6 % of the screen height as in the PDF; size as in the standalone build (3.35vw),
     never larger than the PDF's share of the height. One line (the title is 21.4 em long in Bison). */
  .apps__title {
    position: absolute;
    inset: auto 0 calc(9.37svh - 0.11em);
    z-index: 1;
    margin: 0;
    padding-inline: var(--gutter);
    font-size: max(28px, min(3.35vw, 6.59svh, var(--art-w) * 0.0371));
    text-align: center;
  }

  .apps__deco,
  .apps__tiles {
    position: absolute;
    inset: 0;
  }

  .apps__deco {
    display: block;
  }

  .apps__tiles {
    display: block;
  }

  .deco,
  .tile {
    position: absolute;
    left: var(--x);
    top: var(--y);
    width: var(--w);
    height: var(--h);
  }

  /* Each block fades from almost black to its own brightness (--hi) towards --angle, as in the PDF. */
  .deco {
    border-radius: calc(var(--art-w) * 0.0244);
    background: linear-gradient(var(--angle, 90deg), rgba(255, 255, 255, 0.015) 0%, rgba(255, 255, 255, var(--hi, 0.3)) 100%);
  }

  .tile figure {
    border-radius: var(--tile-r);
  }

  .tile__media {
    height: 100%;
    aspect-ratio: auto;
  }

  /* Same size as the PDF's labels; "Robots Skin" just fits the narrow hand tile on one line. */
  .tile__label {
    padding: calc(var(--art-w) * 0.022) 0.1em calc(var(--art-w) * 0.0085);
    font-size: max(12px, var(--art-w) * 0.0108);
    text-wrap: balance;
  }

  /* Tile positions on the 16:9 artboard, measured from the PDF.
     --ox / --oy is the hover zoom origin, x / (100% − w) and y / (100% − h): a tile grows away
     from the nearer edges, so the enlarged tile always stays inside the artboard. */
  .tile--pillow { --x: 16.2%; --y: 24.48%; --w: 16.4%; --h: 17.79%; --ox: 19.38%; --oy: 29.78%; }
  .tile--torso { --x: 32.7%; --y: 19.01%; --w: 17.37%; --h: 23.26%; --ox: 39.57%; --oy: 24.77%; }
  .tile--sleeve { --x: 50.22%; --y: 28.04%; --w: 17.76%; --h: 17.27%; --ox: 61.07%; --oy: 33.89%; }
  .tile--mattress { --x: 31.67%; --y: 42.8%; --w: 18.4%; --h: 17.88%; --ox: 38.81%; --oy: 52.12%; }
  .tile--patch { --x: 21.38%; --y: 42.71%; --w: 10.15%; --h: 21.96%; --ox: 23.8%; --oy: 54.73%; }
  .tile--seat { --x: 50.22%; --y: 46.09%; --w: 14.1%; --h: 26.57%; --ox: 58.46%; --oy: 62.77%; }
  .tile--wristband { --x: 64.47%; --y: 46.09%; --w: 13.28%; --h: 14.59%; --ox: 74.34%; --oy: 53.96%; }
  .tile--fabric { --x: 64.52%; --y: 61.11%; --w: 12.05%; --h: 11.55%; --ox: 73.36%; --oy: 69.09%; }
  .tile--hand { --x: 14.06%; --y: 53.82%; --w: 6.78%; --h: 21.87%; --ox: 15.08%; --oy: 68.88%; }

  /* The 15 decoration blocks of the PDF, top to bottom; --1 sits behind GET IN TOUCH. */
  .deco--1 { --x: 68.72%; --y: 4.43%; --w: 18.1%; --h: 25%; --angle: 0deg; --hi: 0.45; }
  .deco--2 { --x: 19.03%; --y: 9.55%; --w: 13.23%; --h: 14.76%; --angle: 270deg; --hi: 0.53; }
  .deco--3 { --x: 50.27%; --y: 13.28%; --w: 13.61%; --h: 14.41%; --angle: 0deg; --hi: 0.45; }
  .deco--4 { --x: 8.15%; --y: 28.47%; --w: 7.91%; --h: 13.37%; --angle: 180deg; --hi: 0.43; }
  .deco--5 { --x: 88.82%; --y: 29.08%; --w: 8.25%; --h: 30.47%; --angle: 90deg; --hi: 0.4; }
  .deco--6 { --x: 68.62%; --y: 30.03%; --w: 15.23%; --h: 11.81%; --angle: 90deg; --hi: 0.45; }
  .deco--7 { --x: 6.73%; --y: 42.8%; --w: 14.3%; --h: 10.67%; --angle: 270deg; --hi: 0.38; }
  .deco--8 { --x: 78.18%; --y: 46.01%; --w: 8.01%; --h: 15.19%; --angle: 90deg; --hi: 0.34; }
  .deco--9 { --x: 1.76%; --y: 59.55%; --w: 6.1%; --h: 11.28%; --angle: 270deg; --hi: 0.26; }
  .deco--10 { --x: 76.92%; --y: 61.2%; --w: 5.56%; --h: 19.36%; --angle: 90deg; --hi: 0.23; }
  .deco--11 { --x: 28.7%; --y: 66.15%; --w: 9.61%; --h: 13.1%; --angle: 180deg; --hi: 0.18; }
  .deco--12 { --x: 38.75%; --y: 66.15%; --w: 12.54%; --h: 25.6%; --angle: 180deg; --hi: 0.17; }
  .deco--13 { --x: 84.53%; --y: 67.97%; --w: 12.54%; --h: 10.24%; --angle: 90deg; --hi: 0.21; }
  .deco--14 { --x: 21.38%; --y: 71.61%; --w: 6.88%; --h: 13.81%; --angle: 180deg; --hi: 0.14; }
  .deco--15 { --x: 57.3%; --y: 74.13%; --w: 14.3%; --h: 16.58%; --angle: 180deg; --hi: 0.16; }
}

/* Collage hover: the tile under the pointer is enlarged out of the collage while the others dim.
   It keeps its stacking order until it has shrunk back, so it never slips under a neighbour. */
@media (min-width: 1024px) and (hover: hover) and (pointer: fine) and (prefers-reduced-motion: no-preference) {
  .apps__tiles {
    --zoom: 1.15;
  }

  .tile {
    transition: z-index 0s 0.5s;
  }

  .tile:hover {
    z-index: 2;
    transition-delay: 0s;
  }

  .tile figure {
    transform-origin: var(--ox) var(--oy);
    transition:
      transform 0.5s cubic-bezier(0.2, 0.8, 0.2, 1),
      border-radius 0.5s cubic-bezier(0.2, 0.8, 0.2, 1),
      box-shadow 0.5s ease,
      opacity 0.35s ease;
  }

  .tile:hover figure {
    transform: scale(var(--zoom));
    /* Scaled with the tile, so this renders at the tile's normal corner radius. */
    border-radius: calc(var(--tile-r, 14px) / var(--zoom));
    box-shadow: 0 12px 32px rgba(0, 0, 0, 0.55);
  }

  .tile figure:hover img {
    transform: none;
  }

  .apps__tiles:has(.tile:hover) .tile:not(:hover) figure {
    opacity: 0.35;
  }
}

/* ---------- P8 · About ---------- */
.about {
  isolation: isolate;
  overflow: hidden;
  background: var(--c-black);
}

.about__media {
  position: relative;
  z-index: -2;
  aspect-ratio: 4 / 3;
}

.about__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 40%;
}

.about__media::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(0, 0, 0, 0.1) 0%, rgba(0, 0, 0, 0) 40%, rgba(0, 0, 0, 0.88) 92%, #000 100%);
}

.about__scrim {
  display: none;
}

.about__inner {
  position: relative;
  margin-top: -52px;
  padding-bottom: 64px;
}

/* Heading in Barlow Semi Condensed and in its own case, as in the standalone build. */
.about__copy .section-title {
  font-family: var(--f-ui);
  font-size: clamp(2.1rem, 9vw, 3rem);
  line-height: 1;
  letter-spacing: -0.005em;
  text-transform: none;
}

.about__copy p {
  max-width: 46ch;
  margin-bottom: 0.6em;
  color: rgba(255, 255, 255, 0.82);
  font-size: var(--fs-lede);
  line-height: 1.68;
  text-wrap: pretty;
}

@media (min-width: 768px) {
  .about__copy .section-title {
    font-size: clamp(2.1rem, 4.2vw, 4.25rem);
  }

  .about__copy p {
    max-width: 1280px;
    font-size: clamp(0.96rem, 1.28vw, 1.17rem);
  }
}

.about__copy strong {
  font-weight: 700;
}

.about__copy .btn {
  margin-top: 1em;
}

@media (min-width: 1024px) {
  .about {
    min-height: 100svh;
    display: flex;
    align-items: flex-end;
    padding-block: calc(var(--header-h) + 48px) clamp(56px, 10vh, 104px);
  }

  /* Bleeds only upwards, so the image keeps its bottom edge on the section's; the bottom of the
     image is black, like the section behind it, while the parallax lifts it on the way in. */
  .about__media {
    position: absolute;
    inset: -32px 0 0;
    aspect-ratio: auto;
    transform: translate3d(0, var(--parallax, 0px), 0);
    will-change: transform;
  }

  .about__media img {
    object-position: 50% 100%;
  }

  .about__media::after {
    display: none;
  }

  .about__scrim {
    display: block;
    position: absolute;
    inset: 0;
    z-index: -1;
    background:
      linear-gradient(0deg, rgba(0, 0, 0, 0.68) 0%, rgba(0, 0, 0, 0.4) 38%, rgba(0, 0, 0, 0) 62%),
      linear-gradient(180deg, rgba(0, 0, 0, 0.3) 0%, rgba(0, 0, 0, 0) 18%);
  }

  .about__inner {
    margin-top: 0;
    padding-bottom: 0;
  }

  .about__copy {
    text-shadow: 0 1px 12px rgba(0, 0, 0, 0.4);
  }
}

/* ---------- P9 · Contact ---------- */
.contact {
  display: grid;
  grid-template-areas:
    "info"
    "form"
    "social";
  background: var(--c-black);
}

.contact__info {
  grid-area: info;
  padding: 64px var(--gutter) 36px;
}

.contact__logo {
  display: block;
  width: clamp(154px, 14vw, 212px);
  margin: 0 0 clamp(1.8rem, 3.4vw, 3.2rem);
  filter: drop-shadow(0 2px 16px rgba(0, 0, 0, 0.5));
}

.contact__logo img {
  width: 100%;
  height: auto;
}

.contact__title {
  margin: 0 0 0.7em;
  font-family: var(--f-ui);
  font-weight: 700;
  font-size: clamp(2.2rem, 10.4vw, 3.4rem);
  line-height: 1;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  white-space: nowrap;
}

.contact__details {
  font-style: normal;
}

.contact__label {
  margin: clamp(1.6rem, 2.6vw, 2.5rem) 0 0.45rem;
  font-weight: 600;
  font-size: clamp(1.25rem, 1.65vw, 1.55rem);
  line-height: 1.2;
}

.contact__value {
  max-width: 540px;
  margin: 0;
  color: rgba(255, 255, 255, 0.72);
  font-size: clamp(1.02rem, 1.2vw, 1.18rem);
  line-height: 1.6;
  overflow-wrap: anywhere;
}

.contact__emails {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 2px;
}

.contact__emails a {
  display: inline-block;
  padding: 4px 2px;
  text-decoration: underline;
  text-decoration-color: rgba(255, 255, 255, 0.35);
  text-underline-offset: 4px;
  transition: text-decoration-color 0.2s, color 0.2s;
}

.contact__emails a:hover {
  text-decoration-color: #fff;
}

.contact__panel {
  grid-area: form;
  position: relative;
  isolation: isolate;
  padding: 44px var(--gutter) 48px;
}

.contact__bg,
.contact__bg picture {
  position: absolute;
  inset: 0;
  z-index: -1;
}

.contact__bg img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 62% 50%;
}

.contact__bg::after {
  content: "";
  position: absolute;
  inset: 0;
  background:
    linear-gradient(180deg, #000 0%, rgba(0, 0, 0, 0.5) 14%, rgba(0, 0, 0, 0.55) 86%, #000 100%),
    rgba(0, 0, 0, 0.38);
}

.contact-form {
  width: 100%;
  max-width: 540px;
  margin: 0 auto;
}

.form-mode {
  margin: 0 0 22px;
  padding: 10px 12px;
  border: 1px dashed rgba(255, 199, 147, 0.7);
  background: rgba(40, 26, 10, 0.55);
  color: #ffd7ae;
  font-size: 15px;
  line-height: 1.45;
}

.form-mode[hidden] {
  display: none;
}

.form-mode strong {
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.field {
  margin-bottom: 20px;
}

.field label {
  display: block;
  margin-bottom: 0.45rem;
  font-family: var(--f-ui);
  font-weight: 700;
  font-size: 0.9rem;
  line-height: 1.3;
  letter-spacing: 0.17em;
  text-transform: uppercase;
}

.field__req {
  color: rgba(255, 255, 255, 0.75);
}

.field input,
.field textarea {
  display: block;
  width: 100%;
  min-height: 44px;
  padding: 10px 12px;
  border: 1px solid rgba(255, 255, 255, 0.16);
  border-radius: 0;
  background: rgba(208, 215, 220, 0.24);
  color: #fff;
  font-size: 18px;
  line-height: 1.4;
  -webkit-appearance: none;
  appearance: none;
  -webkit-backdrop-filter: blur(7px);
  backdrop-filter: blur(7px);
  transition: background-color 0.3s var(--ease-out), border-color 0.3s var(--ease-out);
}

.field input {
  min-height: 50px;
}

.field textarea {
  min-height: 112px;
  resize: vertical;
}

.field input:hover,
.field textarea:hover {
  border-color: rgba(255, 255, 255, 0.36);
}

.field input:focus,
.field textarea:focus {
  outline: 2px solid #fff;
  outline-offset: 2px;
  background: rgba(255, 255, 255, 0.3);
}

.field.has-error input,
.field.has-error textarea {
  border-color: #ff9a9a;
  box-shadow: inset 3px 0 0 #ff9a9a;
}

.field__error {
  margin: 7px 0 0;
  color: #ffc2c2;
  font-size: 16px;
  line-height: 1.4;
}

.field__error:empty {
  display: none;
}

.field--trap {
  position: absolute;
  left: -10000px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.form-note {
  margin: -4px 0 18px;
  font-size: 15px;
  color: var(--c-text-dim);
}

.form-actions {
  display: flex;
  justify-content: center;
}

.form-submit {
  position: relative;
  min-width: min(220px, 100%);
  padding: 0.95rem 1.3rem;
  border-radius: 2px;
  background: #d9dcd9;
  color: #080b0e;
  font-size: 0.9rem;
  letter-spacing: 0.16em;
}

.form-submit:hover {
  background: #fff;
  box-shadow: 0 14px 34px rgba(0, 0, 0, 0.3);
}

.form-submit:disabled {
  cursor: default;
  opacity: 0.72;
}

.form-submit:disabled:hover {
  background: #d9dcd9;
  box-shadow: none;
}

.form-submit__spinner {
  display: none;
  width: 14px;
  height: 14px;
  border: 2px solid rgba(16, 18, 21, 0.25);
  border-top-color: currentColor;
  border-radius: 50%;
  animation: spin 0.8s linear infinite;
}

.form-submit[data-state="busy"] .form-submit__spinner {
  display: block;
}

@keyframes spin {
  to {
    transform: rotate(360deg);
  }
}

.form-status {
  margin-top: 18px;
  font-size: 17px;
  line-height: 1.5;
  text-align: center;
}

.form-status:empty {
  display: none;
}

.form-status > p {
  margin: 0;
  padding: 12px 14px;
  border: 1px solid rgba(255, 255, 255, 0.22);
  background: rgba(0, 0, 0, 0.55);
}

.form-status .is-success {
  border-color: rgba(150, 230, 180, 0.7);
  color: #c6f3d6;
}

.form-status .is-error {
  border-color: rgba(255, 154, 154, 0.75);
  color: #ffd0d0;
}

.form-status .is-info {
  border-color: rgba(255, 199, 147, 0.7);
  color: #ffe0c2;
}

.form-status__retry {
  margin-left: 6px;
  padding: 2px 0;
  border: 0;
  background: none;
  color: #fff;
  font-weight: 600;
  text-decoration: underline;
  text-underline-offset: 3px;
  cursor: pointer;
}

.contact__social {
  grid-area: social;
  padding: 32px var(--gutter) 56px;
}

.social-list {
  display: flex;
  justify-content: flex-start;
  gap: 16px;
  margin: 0;
  padding: 0;
  list-style: none;
}

/* The 26 px icon sits centred in a 44 px target; pull the row back so the icon meets the gutter. */
.contact__social .social-list {
  margin-left: -9px;
}

.social-link {
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  color: rgba(255, 255, 255, 0.86);
  transition: color 0.2s;
}

.social-link svg {
  width: 26px;
  height: 26px;
  fill: currentColor;
}

.social-link:hover {
  color: #fff;
}

@media (min-width: 1024px) {
  /* Contact details and social links stay together, centred beside the form. */
  .contact {
    grid-template-columns: minmax(0, 44fr) minmax(0, 56fr);
    grid-template-rows: 1fr auto auto 1fr;
    grid-template-areas:
      ". form"
      "info form"
      "social form"
      ". form";
    min-height: 100svh;
  }

  .contact__info {
    padding: calc(var(--header-h) + 32px) var(--gutter) 0;
  }

  .contact__title {
    font-size: clamp(2.4rem, 4.9vw, 4.9rem);
  }

  .contact__panel {
    display: flex;
    align-items: center;
    padding: calc(var(--header-h) + 40px) clamp(32px, 6vw, 112px) 56px;
  }

  .contact__bg img {
    object-position: 50% 50%;
  }

  .contact__bg::after {
    background:
      linear-gradient(90deg, #000 0%, rgba(0, 0, 0, 0.55) 9%, rgba(0, 0, 0, 0) 26%),
      rgba(0, 0, 0, 0.42);
  }

  .contact__social {
    padding: 28px var(--gutter) 48px;
  }
}

/* Short desktop windows (≤ 760 px): tighter spacing so the whole form fits one screen. */
@media (min-width: 1024px) and (max-height: 760px) {
  .contact__info {
    padding-top: calc(var(--header-h) + 16px);
  }

  .contact__panel {
    padding-block: calc(var(--header-h) + 12px) 20px;
  }

  .contact__social {
    padding-block: 20px 28px;
  }

  .form-mode {
    margin-bottom: 14px;
    padding-block: 8px;
  }

  .field {
    margin-bottom: 12px;
  }

  .field label {
    margin-bottom: 6px;
  }

  .field textarea {
    min-height: 84px;
  }

  .form-note {
    margin-bottom: 12px;
  }
}

/* ---------- Screen-by-screen snapping (desktop) ----------
   Kept at the end of the file so it overrides the section rules above.
   Every screen snaps to the top of the viewport. P4's pinned animation track (300svh when
   scrolling freely) is shortened to 200svh here. Phones, touch tablets, short windows and
   reduced-motion users keep free scrolling. */
@media (min-width: 1024px) and (min-height: 621px) and (hover: hover) and (pointer: fine) and (prefers-reduced-motion: no-preference) {
  html {
    scroll-snap-type: y mandatory;
    scroll-padding-top: 0;
  }

  main > section {
    scroll-snap-align: start;
  }

  /* P4 is one snap area taller than the screen. Browsers snap to its first screen on the way in
     and its last screen on the way out, and scroll freely in between, so the layer animation
     follows the wheel or trackpad instead of being pulled back to either end. */
  .structure--scroll.is-scroll-pinned {
    height: 200svh;
  }
}

/* ---------- Reduced motion ---------- */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }

  .reveal-ready [data-reveal] {
    opacity: 1;
    transform: none;
  }

  .materials__media,
  .production__media,
  .about__media {
    transform: none !important;
  }

  .structure--scroll.is-scroll-pinned {
    height: auto;
  }

  .structure--scroll .structure__pin {
    position: relative;
  }

  .structure__scrub-video {
    opacity: 0 !important;
  }

  .tile figure:hover img {
    transform: none;
  }

  .anchor.is-active {
    animation: none;
    opacity: 1;
  }
}
