/* ==========================================================================
   Alpion Cryo — shared stylesheet
   Instrumentation for cryo-electron microscopy
   --------------------------------------------------------------------------
   Contents
     1.  Design tokens (CSS custom properties)
     2.  Reset & base
     3.  Layout primitives (container, section, grid)
     4.  Typography helpers (eyebrow, lead, headings)
     5.  Buttons
     6.  Site header / navigation
     7.  Hero
     8.  Pictogram (inline SVG sprite) system
     9.  Components (cards, products, workflow, features, stats, CTA, forms)
     10. Footer
     11. Reveal-on-scroll & motion
     12. Responsive breakpoints
   ========================================================================== */

/* 1. Design tokens ========================================================= */
:root {
  /* Brand palette (from logo / CI) */
  --navy:  #020344;   /* primary dark            */
  --blue:  #00a6fb;   /* electric-blue accent    */
  --green: #56c814;   /* support — used sparingly*/
  --teal:  #70c1b3;   /* support — used sparingly*/
  --mist:  #d9e4e6;   /* light tint              */

  /* Derived navy shades */
  --navy-deep: #01012a;
  --navy-700:  #0a0c4e;   /* lifted surface on dark */
  --navy-600:  #141667;   /* card border on dark    */

  /* Functional */
  --blue-600:  #0090dd;   /* accent hover/active    */
  --ink:       #0c1230;   /* body text on light     */
  --ink-soft:  #545b73;   /* muted body text        */
  --bg:        #ffffff;
  --bg-soft:   #f3f7f9;   /* alternating section    */
  --bg-mist:   #eaf1f3;
  --line:      rgba(2, 3, 68, .10);
  --line-2:    rgba(2, 3, 68, .16);
  --line-dark: rgba(255, 255, 255, .12);
  --white:     #ffffff;

  /* Typography */
  --font-display: "Space Grotesk", "Segoe UI", system-ui, -apple-system, sans-serif;
  --font-body:    "Inter", "Segoe UI", system-ui, -apple-system, Roboto, Helvetica, Arial, sans-serif;

  /* Sizing */
  --container: 1280px;
  --gutter: clamp(1.25rem, 3.5vw, 2.5rem);
  --section-y: clamp(3.5rem, 7vw, 6.5rem);
  --radius-sm: 10px;
  --radius: 16px;
  --radius-lg: 24px;
  --radius-pill: 999px;

  /* Elevation */
  --shadow-sm: 0 1px 2px rgba(2, 3, 68, .06), 0 2px 8px rgba(2, 3, 68, .05);
  --shadow-md: 0 10px 30px -12px rgba(2, 3, 68, .22), 0 4px 12px rgba(2, 3, 68, .06);
  --shadow-lg: 0 30px 60px -22px rgba(2, 3, 68, .35);
  --shadow-blue: 0 14px 36px -10px rgba(0, 166, 251, .45);

  /* Motion */
  --ease: cubic-bezier(.22, .61, .36, 1);
  --dur: .45s;
}

/* 2. Reset & base ========================================================== */
*, *::before, *::after { box-sizing: border-box; }

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

body {
  margin: 0;
  font-family: var(--font-body);
  font-size: 1.125rem;           /* 18px — larger, less "zoomed out" */
  line-height: 1.6;
  color: var(--ink);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  overflow-x: clip;   /* `clip` (not `hidden`) so it doesn't break position: sticky */
}

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

a { color: var(--blue-600); text-decoration: none; transition: color .2s var(--ease); }
a:hover { color: var(--blue); }

h1, h2, h3 {
  font-family: var(--font-display);
  font-weight: 700;
  line-height: 1.06;
  letter-spacing: -.025em;
  color: var(--navy);
  margin: 0 0 .5em;
  text-wrap: balance;
}
h4 {
  font-family: var(--font-display);
  font-weight: 600;
  line-height: 1.1;
  letter-spacing: -.01em;
  color: var(--navy);
  margin: 0 0 .5em;
}

p { margin: 0 0 1.1rem; }
p:last-child { margin-bottom: 0; }

ul, ol { margin: 0 0 1.1rem; padding-left: 1.2rem; }

strong { font-weight: 600; color: var(--navy); }
/* on dark fields, bold text must stay legible (navy-on-navy would vanish) */
.hero strong, .section--dark strong { color: inherit; }

:focus-visible {
  outline: 3px solid var(--blue);
  outline-offset: 3px;
  border-radius: 4px;
}

.skip-link {
  position: absolute;
  left: 1rem;
  top: -4rem;
  z-index: 200;
  background: var(--navy);
  color: #fff;
  padding: .7rem 1.1rem;
  border-radius: var(--radius-sm);
  transition: top .2s var(--ease);
}
.skip-link:focus { top: 1rem; color: #fff; }

/* 3. Layout primitives ===================================================== */
.container {
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--gutter);
}
.container--narrow { max-width: 820px; }
.container--mid { max-width: 1080px; }

.section { padding-block: var(--section-y); position: relative; }
.section--soft { background: var(--bg-soft); }
.section--mist { background: linear-gradient(180deg, var(--bg-soft), var(--bg-mist)); }
.section--dark {
  background:
    radial-gradient(900px 460px at 18% 0%, rgba(0, 166, 251, .16), transparent 60%),
    radial-gradient(700px 420px at 92% 100%, rgba(112, 193, 179, .12), transparent 60%),
    linear-gradient(180deg, var(--navy) 0%, var(--navy-deep) 100%);
  color: #d7defb;
}
.section--dark h1,
.section--dark h2,
.section--dark h3 { color: #fff; }
.section--tight { padding-block: clamp(3rem, 6vw, 4.5rem); }

.section__head { max-width: 60rem; margin-bottom: clamp(2.25rem, 5vw, 3.5rem); }
/* the heading may run wide, but the lead stays at a comfortable reading measure */
.section__head .lead { max-width: 46rem; }
.section__head--center { margin-inline: auto; text-align: center; }

.grid { display: grid; gap: clamp(1.25rem, 3vw, 2rem); }
.grid--2 { grid-template-columns: repeat(2, 1fr); }
.grid--3 { grid-template-columns: repeat(3, 1fr); }
.grid--4 { grid-template-columns: repeat(4, 1fr); }

/* 4. Typography helpers ==================================================== */
/* Plain, purified section label — no decorative bar. */
.eyebrow {
  display: block;
  font-family: var(--font-display);
  font-size: .82rem;
  font-weight: 600;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--ink-soft);
  margin-bottom: .9rem;
}
.section--dark .eyebrow { color: #8f9bd0; }
.eyebrow--center { text-align: center; }

h1.display { font-size: clamp(2.75rem, 6.4vw, 4.9rem); }
h2.h2 { font-size: clamp(2.1rem, 4.2vw, 3.35rem); }
h3.h3 { font-size: clamp(1.4rem, 2.6vw, 1.75rem); }

.lead {
  font-size: clamp(1.15rem, 2vw, 1.4rem);
  line-height: 1.55;
  color: var(--ink-soft);
}
.section--dark .lead { color: #aeb8e0; }

.muted { color: var(--ink-soft); }
.section--dark .muted { color: #9aa4cf; }

/* 5. Buttons =============================================================== */
.btn {
  --btn-bg: var(--blue);
  --btn-fg: var(--navy);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .55rem;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 1rem;
  line-height: 1;
  letter-spacing: -.01em;
  padding: .95rem 1.5rem;
  border-radius: var(--radius-sm);
  border: 1.5px solid transparent;
  background: var(--btn-bg);
  color: var(--btn-fg);
  cursor: pointer;
  transition: transform .2s var(--ease), box-shadow .25s var(--ease),
              background-color .2s var(--ease), border-color .2s var(--ease), color .2s var(--ease);
  white-space: nowrap;
}
.btn:hover { transform: translateY(-2px); color: var(--btn-fg); }
.btn:active { transform: translateY(0); }

.btn--primary { box-shadow: var(--shadow-blue); }
.btn--primary:hover { background: #2bb6ff; box-shadow: 0 18px 44px -10px rgba(0, 166, 251, .6); }

/* Set by main.js while a required field is still empty. Muted, but deliberately
   still clickable and focusable, so the click reaches the browser's own
   validation and it says which field is missing. */
.btn--primary.is-incomplete,
.btn--primary.is-incomplete:hover { background: #bfe1f5; box-shadow: none; }

.btn--dark { --btn-bg: var(--navy); --btn-fg: #fff; }
.btn--dark:hover { background: var(--navy-700); }

.btn--light { --btn-bg: #fff; --btn-fg: var(--navy); box-shadow: var(--shadow-md); }
.btn--light:hover { background: #f1f5f7; }

.btn--ghost {
  background: transparent;
  border-color: var(--line-2);
  color: var(--navy);
}
.btn--ghost:hover { border-color: var(--navy); background: rgba(2, 3, 68, .03); color: var(--navy); }

.section--dark .btn--ghost,
.btn--ghost-light {
  background: rgba(2, 3, 68, .55);
  border-color: rgba(255, 255, 255, .28);
  color: #fff;
}
.section--dark .btn--ghost:hover,
.btn--ghost-light:hover { border-color: #fff; background: rgba(255, 255, 255, .08); color: #fff; }

.btn .btn__arrow { transition: transform .25s var(--ease); }
.btn:hover .btn__arrow { transform: translateX(3px); }

.btn-row { display: flex; flex-wrap: wrap; gap: .85rem; align-items: center; }

.textlink {
  display: inline-flex;
  align-items: center;
  gap: .4rem;
  font-family: var(--font-display);
  font-weight: 600;
  color: var(--blue-600);
}
.textlink .btn__arrow { transition: transform .25s var(--ease); }
.textlink:hover .btn__arrow { transform: translateX(3px); }
.section--dark .textlink { color: var(--blue); }

/* 6. Site header / navigation ============================================= */
/* Solid brand-green banner (per CI). Navy logo + navy nav read crisply on it. */
.site-header {
  position: sticky;
  top: 0;
  z-index: 100;
  background-color: var(--green);
  border-bottom: 1px solid transparent;
  transition: box-shadow .3s var(--ease);
}
.site-header.is-scrolled {
  box-shadow: 0 6px 24px -12px rgba(2, 3, 68, .55);
}
.nav {
  display: flex;
  align-items: center;
  gap: 1.5rem;
  height: 92px;            /* thicker bar so the logo reads bigger */
}
.nav__brand { display: inline-flex; align-items: center; margin-right: auto; }
.nav__brand img { height: 42px; width: auto; }
.nav__menu { display: flex; align-items: center; gap: 1.25rem; }
.nav__links {
  display: flex;
  align-items: center;
  gap: .35rem;
  list-style: none;
  margin: 0;
  padding: 0;
}
.nav__links a {
  display: inline-block;
  padding: .55rem .85rem;
  border-radius: var(--radius-sm);
  color: var(--navy);
  font-weight: 600;
  font-size: 1rem;
  transition: color .2s var(--ease), background-color .2s var(--ease);
}
.nav__links a:hover { color: var(--navy); background: rgba(2, 3, 68, .08); }
.nav__links a.is-active { color: var(--navy); }
.nav__links a.is-active::after {
  content: "";
  display: block;
  height: 2px;
  margin: .25rem .35rem 0;
  border-radius: 2px;
  background: var(--navy);
}
.nav__cta { margin-left: .5rem; }
/* CTA on the green bar: solid navy for strong contrast */
.nav__cta .btn,
.site-header .nav__cta .btn--primary {
  padding: .75rem 1.25rem;
  background: var(--navy);
  color: #fff;
  box-shadow: none;
}
.nav__cta .btn:hover,
.site-header .nav__cta .btn--primary:hover { background: var(--navy-700); color: #fff; }

.nav__toggle {
  display: none;
  width: 46px;
  height: 46px;
  border: 0;
  background: transparent;
  cursor: pointer;
  padding: 11px;
}
.nav__toggle span,
.nav__toggle span::before,
.nav__toggle span::after {
  content: "";
  display: block;
  height: 2px;
  width: 26px;
  background: var(--navy);
  border-radius: 2px;
  transition: transform .3s var(--ease), opacity .2s var(--ease);
}
.nav__toggle span { position: relative; }
.nav__toggle span::before { position: absolute; top: -7px; }
.nav__toggle span::after { position: absolute; top: 7px; }
.nav.is-open .nav__toggle span { background: transparent; }
.nav.is-open .nav__toggle span::before { transform: translateY(7px) rotate(45deg); }
.nav.is-open .nav__toggle span::after { transform: translateY(-7px) rotate(-45deg); }

/* 7. Hero ================================================================= */
/* The first view must read as a single, strong deep-blue field (#020344). */
.hero {
  position: relative;
  overflow: hidden;
  background: var(--navy);
  color: #cdd5f3;
  padding-block: clamp(4rem, 9vw, 7rem);
}
.hero::after {                 /* faint engineering dot-grid, kept very subtle */
  content: "";
  position: absolute;
  inset: 0;
  background-image: radial-gradient(rgba(255, 255, 255, .05) 1px, transparent 1px);
  background-size: 38px 38px;
  -webkit-mask-image: radial-gradient(85% 75% at 50% 25%, #000, transparent 78%);
  mask-image: radial-gradient(85% 75% at 50% 25%, #000, transparent 78%);
  pointer-events: none;
}
.hero > .container { position: relative; z-index: 1; }

.hero__inner { max-width: 880px; }
.hero h1 { color: #fff; margin-bottom: 1.1rem; }
.hero h1 .accent { color: var(--blue); }
.hero__sub {
  font-size: clamp(1.1rem, 2.1vw, 1.4rem);
  line-height: 1.55;
  color: #b9c2ec;
  max-width: 60ch;
  margin-bottom: 2rem;
}
.hero .btn-row { margin-bottom: 2.5rem; }

.badge-row { display: flex; flex-wrap: wrap; gap: .6rem 1.6rem; align-items: center; }
.badge {
  display: inline-flex;
  align-items: center;
  gap: .5rem;
  font-size: .92rem;
  color: #aab4e0;
}
.badge .dot {
  width: 8px; height: 8px; border-radius: 50%;
  background: var(--blue);
  box-shadow: 0 0 0 4px rgba(0, 166, 251, .18);
}
.badge .dot--green { background: var(--green); box-shadow: 0 0 0 4px rgba(86, 200, 20, .18); }

/* 8. Pictogram (inline SVG sprite) system ================================= */
/* Icons are inline <svg><use href="#ic-*"> referencing a hidden sprite in each
   page; they recolor via `fill: currentColor`, driven by the `color` of context. */
.picto {
  display: inline-block;
  width: var(--picto-size, 56px);
  height: var(--picto-size, 56px);
  fill: currentColor;
  flex: none;
}
/* The CryoFlash and TEM pictograms read visually smaller than their box at
   the same --picto-size as the others (detailed line art / a narrow
   instrument silhouette), wherever they appear -- scale them up in place
   without touching each container's sizing. */
.picto:has(use[href="#ic-cryoflash"]) { transform: scale(1.2); }
.picto:has(use[href="#ic-tem"]) { transform: scale(1.35); }

/* icon chip */
.icon-chip {
  display: grid;
  place-items: center;
  width: 76px;
  height: 76px;
  border-radius: 20px;
  background: linear-gradient(160deg, rgba(0, 166, 251, .14), rgba(0, 166, 251, .04));
  border: 1px solid var(--line);
  color: var(--blue-600);
  flex: none;   /* in a flex row (e.g. .contact-method) long copy must not squeeze the box */
}
.icon-chip .picto { --picto-size: 44px; }
/* The mail icon has a square viewBox, so --picto-size sets both its axes equally.
   The other (non-square) icons scale to fit, ending up ~38-44px WIDE. In a vertical
   column the eye compares widths, so size the mail up until its rendered width
   (~0.83 x picto-size for this envelope) matches them. */
.icon-chip .picto--mail { --picto-size: 48px; }
.section--dark .icon-chip {
  background: linear-gradient(160deg, rgba(0, 166, 251, .22), rgba(255, 255, 255, .02));
  border-color: var(--line-dark);
  color: var(--blue);
}

/* 9. Components =========================================================== */

/* --- Generic card --- */
.card {
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: clamp(1.5rem, 3vw, 2.1rem);
  box-shadow: var(--shadow-sm);
  transition: transform .3s var(--ease), box-shadow .3s var(--ease), border-color .3s var(--ease);
}
.card h3 { margin-bottom: .5rem; }
.card p:last-child { margin-bottom: 0; }
.card--hover:hover { transform: translateY(-4px); box-shadow: var(--shadow-md); border-color: var(--line-2); }

/* --- Product card (homepage) --- */
.product-card {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 1.25rem;
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  padding: clamp(1.75rem, 3.5vw, 2.6rem);
  box-shadow: var(--shadow-sm);
  overflow: hidden;
  transition: transform .3s var(--ease), box-shadow .3s var(--ease), border-color .3s var(--ease);
}
.product-card::before {
  content: "";
  position: absolute;
  inset: 0 0 auto 0;
  height: 4px;
  background: linear-gradient(90deg, var(--blue), var(--teal));
  opacity: .9;
}
.product-card:hover { transform: translateY(-5px); box-shadow: var(--shadow-lg); border-color: transparent; }
.product-card__tag {
  align-self: flex-start;
  font-family: var(--font-display);
  font-size: .72rem;
  font-weight: 600;
  letter-spacing: .12em;
  text-transform: uppercase;
  padding: .3rem .7rem;
  border-radius: var(--radius-pill);
  background: rgba(0, 166, 251, .1);
  color: var(--blue-600);
}
.product-card__tag--soon { background: rgba(84, 91, 115, .12); color: var(--ink-soft); }
.product-card h3 { font-size: clamp(1.6rem, 3vw, 2rem); margin: 0; }
.product-card .product-card__body { color: var(--ink-soft); flex: 1; }
.product-card .icon-chip { width: 64px; height: 64px; }
.product-card .icon-chip .picto { --picto-size: 38px; }
.product-card__links { display: flex; flex-wrap: wrap; align-items: center; gap: .4rem 1.6rem; }

/* --- Workflow strip (the cryo-EM pipeline) --- */
.flow {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: .5rem;
  align-items: stretch;
}
.flow__step {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: .85rem;
  padding: 1.5rem .75rem;
  border-radius: var(--radius);
  background: var(--white);
  border: 1px solid var(--line);
}
.flow__step .icon-chip { color: var(--ink-soft); background: var(--bg-soft); border-color: var(--line); }
.flow__step .picto { --picto-size: 42px; }
.flow__label { font-family: var(--font-display); font-weight: 600; font-size: .98rem; color: var(--navy); }
.flow__note { font-size: .82rem; color: var(--ink-soft); line-height: 1.4; }
.flow__step::after {     /* connector arrow */
  content: "";
  position: absolute;
  right: -.5rem;
  top: 3.4rem;
  width: 1rem;
  height: 2px;
  background: var(--line-2);
  z-index: 1;
}
.flow__step:last-child::after { display: none; }

.flow__step--highlight {
  background: linear-gradient(170deg, var(--navy), var(--navy-deep));
  border-color: transparent;
  box-shadow: var(--shadow-lg);
  transform: translateY(-6px);
}
.flow__step--highlight .flow__label { color: #fff; }
.flow__step--highlight .flow__note { color: #aab4e0; }
.flow__step--highlight .icon-chip {
  background: rgba(0, 166, 251, .18);
  border-color: rgba(255, 255, 255, .14);
  color: var(--blue);
}
.flow__step--highlight .flow__badge {
  position: absolute;
  top: -.7rem;
  font-family: var(--font-display);
  font-size: .66rem;
  font-weight: 600;
  letter-spacing: .1em;
  text-transform: uppercase;
  background: var(--blue);
  color: var(--navy);
  padding: .25rem .6rem;
  border-radius: var(--radius-pill);
}

/* --- Numbered step cards (workflow / software how-it-works) --- */
.steps { counter-reset: step; }
.step-card {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 1.1rem;
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  padding: clamp(1.6rem, 3vw, 2.2rem);
  box-shadow: var(--shadow-sm);
  height: 100%;
  transition: transform .3s var(--ease), box-shadow .3s var(--ease);
}
.step-card:hover { transform: translateY(-4px); box-shadow: var(--shadow-md); }
.step-card__top { display: flex; align-items: center; justify-content: space-between; }
.step-card__num {
  counter-increment: step;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1rem;
  color: var(--blue-600);
  width: 2.6rem; height: 2.6rem;
  display: grid; place-items: center;
  border-radius: 50%;
  border: 1.5px solid rgba(0, 166, 251, .35);
  background: rgba(0, 166, 251, .07);
}
.step-card__num::before { content: counter(step, decimal-leading-zero); }
.step-card h3 { font-size: 1.25rem; margin: 0; }
.step-card p { color: var(--ink-soft); margin: 0; }
.step-card .icon-chip { width: 64px; height: 64px; }

/* on dark sections */
.section--dark .step-card {
  background: rgba(255, 255, 255, .035);
  border-color: var(--line-dark);
  box-shadow: none;
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
}
.section--dark .step-card p { color: #aab4e0; }
.section--dark .step-card__num { color: var(--blue); border-color: rgba(0, 166, 251, .5); background: rgba(0, 166, 251, .12); }

/* --- Feature / value list --- */
.feature {
  display: flex;
  gap: 1.1rem;
  align-items: flex-start;
}
.feature .icon-chip { width: 58px; height: 58px; border-radius: 16px; }
.feature .icon-chip .picto { --picto-size: 32px; }
.feature h3 { font-size: 1.18rem; margin-bottom: .35rem; }
.feature p { color: var(--ink-soft); margin: 0; }
.section--dark .feature p { color: #aab4e0; }

/* check list */
.checklist { list-style: none; padding: 0; margin: 0; display: grid; gap: .85rem; }
.checklist li { position: relative; padding-left: 2rem; color: var(--ink-soft); }
.checklist li::before {
  content: "";
  position: absolute;
  left: 0; top: .18rem;
  width: 1.35rem; height: 1.35rem;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Ccircle cx='12' cy='12' r='12' fill='%2356c814'/%3E%3Cpath fill='%23ffffff' d='M9.55 17.05 4.5 12l1.4-1.4 3.65 3.6 8.15-8.15L19.1 7.5z'/%3E%3C/svg%3E") center/contain no-repeat;
}
.checklist--teal li::before {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Ccircle cx='12' cy='12' r='12' fill='%2370c1b3'/%3E%3Cpath fill='%23ffffff' d='M9.55 17.05 4.5 12l1.4-1.4 3.65 3.6 8.15-8.15L19.1 7.5z'/%3E%3C/svg%3E");
}
.section--dark .checklist li { color: #b9c2ec; }

/* --- Stats --- */
.stat__num {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(2.2rem, 5vw, 3rem);
  line-height: 1;
  color: var(--navy);
  letter-spacing: -.03em;
}
.section--dark .stat__num { color: #fff; }
.stat__num .unit { color: var(--blue); }
.stat__label { color: var(--ink-soft); font-size: .98rem; margin-top: .4rem; }
.section--dark .stat__label { color: #9aa4cf; }

/* --- Split / media row --- */
.split { display: grid; grid-template-columns: 1.05fr .95fr; gap: clamp(2rem, 5vw, 4.5rem); align-items: center; }
.split--reverse .split__media { order: -1; }
.media-frame {
  position: relative;
  border-radius: var(--radius-lg);
  border: 1px solid var(--line);
  background: linear-gradient(160deg, var(--bg-soft), var(--bg-mist));
  box-shadow: var(--shadow-md);
  overflow: hidden;
  aspect-ratio: 4 / 3;
  display: grid;
  place-items: center;
}
.media-frame .picto { --picto-size: 120px; color: var(--blue-600); opacity: .85; }
.media-frame__label {
  position: absolute;
  bottom: 1rem; left: 1rem;
  font-size: .8rem;
  color: var(--ink-soft);
  background: rgba(255, 255, 255, .8);
  padding: .3rem .7rem;
  border-radius: var(--radius-pill);
  -webkit-backdrop-filter: blur(4px);
  backdrop-filter: blur(4px);
}
.media-frame--video { aspect-ratio: 1916 / 834; }
/* photo frames take the image's own aspect ratio, so the shot is never cropped */
.media-frame--photo { aspect-ratio: 1600 / 901; margin: 0; background: var(--bg-soft); }
.media-frame img { display: block; width: 100%; height: 100%; object-fit: cover; }
.media-frame iframe { width: 100%; height: 100%; border: 0; }
.media-frame video { display: block; width: 100%; height: 100%; object-fit: cover; background: #000; }
.media-frame__caption {
  margin: .75rem 0 0; font-size: .85rem; line-height: 1.5;
  color: var(--ink-soft); text-align: center;
}

/* --- Team cards (circular portrait avatars) --- */
.team-card { text-align: center; }
.team-photo {
  width: 132px;
  height: 132px;
  border-radius: 50%;
  object-fit: cover;
  margin: 0 auto .9rem;
  display: block;
  border: 3px solid var(--bg);
  box-shadow: var(--shadow-md);
  background: var(--bg-soft);
}
.team-card h3 { margin: 0; font-size: 1.05rem; }
.team-role { margin: .15rem 0 0; color: var(--blue-600); font-weight: 600; font-size: .9rem; }

/* --- Motion showcase (looping density-map videos, white-background) --- */
.motion-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: clamp(1rem, 2.5vw, 1.75rem); }
.video-card {
  margin: 0;
  background: #fff;
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  overflow: hidden;
  box-shadow: var(--shadow-md);
}
.video-card video,
.video-card img { width: 100%; height: auto; display: block; background: #fff; }
/* keep the paired clips the same height regardless of source aspect */
.motion-grid .video-card video,
.motion-grid .video-card img { aspect-ratio: 1 / 1; height: auto; object-fit: contain; }
/* single centred clip (full natural aspect — no cropping) */
.motion-single { max-width: 440px; margin-inline: auto; }
.video-card__cap {
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  padding: .7rem 1.1rem;
  border-top: 1px solid var(--line);
  font-size: .85rem; color: var(--ink-soft);
}
.video-card__cap .tag {
  font-family: var(--font-display); font-weight: 600; font-size: .72rem;
  letter-spacing: .08em; text-transform: uppercase; color: var(--blue-600);
}
/* Motion clips (the spike GIF): sit the whole molecule inside the frame with
   margin so nothing is clipped top or bottom — smaller in the box, fully visible. */
.video-card.video-card--motion img {
  width: auto; max-width: 100%;
  max-height: clamp(320px, 44vh, 440px);
  margin: clamp(.9rem, 2.2vw, 1.5rem) auto;
  object-fit: contain;
}

/* placeholder marker (assets pending) */
.placeholder {
  border: 1.5px dashed var(--line-2);
  border-radius: var(--radius);
  padding: 1.5rem;
  text-align: center;
  color: var(--ink-soft);
  font-size: .9rem;
  background: repeating-linear-gradient(45deg, transparent, transparent 10px, rgba(2, 3, 68, .015) 10px, rgba(2, 3, 68, .015) 20px);
}

/* --- CTA band --- */
.cta-band {
  position: relative;
  overflow: hidden;
  border-radius: var(--radius-lg);
  padding: clamp(2.5rem, 6vw, 4.5rem);
  background:
    radial-gradient(700px 360px at 12% 0%, rgba(0, 166, 251, .28), transparent 60%),
    radial-gradient(600px 340px at 100% 100%, rgba(112, 193, 179, .16), transparent 55%),
    linear-gradient(160deg, var(--navy), var(--navy-deep));
  color: #cdd5f3;
  text-align: center;
}
.cta-band h2 { color: #fff; }
.cta-band .lead { color: #b9c2ec; margin-inline: auto; max-width: 56ch; }
.cta-band .btn-row { justify-content: center; margin-top: 1.8rem; }
.cta-band__mail { margin: 1.4rem 0 0; font-size: .95rem; color: #b9c2ec; }
.cta-band__mail a { color: #fff; font-weight: 600; text-decoration: underline; }

/* --- Forms --- */
.form-card {
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  padding: clamp(1.75rem, 4vw, 3rem);
  box-shadow: var(--shadow-md);
}
.form-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 1.1rem 1.25rem; }
.field { display: flex; flex-direction: column; gap: .45rem; }
.field--full { grid-column: 1 / -1; }
.field label { font-weight: 600; font-size: .92rem; color: var(--navy); }
.field label .req { color: var(--blue-600); }
.field input,
.field select,
.field textarea {
  font-family: inherit;
  font-size: 1rem;
  color: var(--ink);
  padding: .8rem .95rem;
  border: 1.5px solid var(--line-2);
  border-radius: var(--radius-sm);
  background: #fff;
  transition: border-color .2s var(--ease), box-shadow .2s var(--ease);
  width: 100%;
}
.field textarea { resize: vertical; min-height: 130px; }
.field input:focus,
.field select:focus,
.field textarea:focus {
  outline: none;
  border-color: var(--blue);
  box-shadow: 0 0 0 4px rgba(0, 166, 251, .15);
}
.field__hint { font-size: .82rem; color: var(--ink-soft); }
.form-consent { display: flex; gap: .65rem; align-items: flex-start; font-size: .9rem; color: var(--ink-soft); }
.form-consent input { width: 1.15rem; height: 1.15rem; margin-top: .2rem; flex: none; accent-color: var(--blue); }
.form-consent .req { color: var(--blue-600); font-weight: 700; }

/* contact methods */
.contact-method { display: flex; gap: 1rem; align-items: flex-start; }
.contact-method .icon-chip { width: 64px; height: 64px; border-radius: 17px; }
.contact-method h3 { font-size: 1.05rem; margin-bottom: .2rem; }
.contact-method p { margin: 0; color: var(--ink-soft); font-size: .95rem; }

/* --- Misc --- */
.pill-tags { display: flex; flex-wrap: wrap; gap: .5rem; }
.pill-tags span {
  font-size: .85rem;
  padding: .4rem .85rem;
  border-radius: var(--radius-pill);
  background: var(--bg-soft);
  border: 1px solid var(--line);
  color: var(--ink-soft);
}
.section--dark .pill-tags span { background: rgba(255, 255, 255, .05); border-color: var(--line-dark); color: #b9c2ec; }

.divider-soft { height: 1px; background: var(--line); border: 0; margin: 0; }

.prose > * + * { margin-top: 1.1rem; }
.prose h2 { margin-top: 2.4rem; font-size: clamp(1.6rem, 3vw, 2.1rem); }
.prose h3 { margin-top: 1.8rem; font-size: 1.3rem; }
.prose ul { padding-left: 1.3rem; }
.prose li { margin-bottom: .5rem; }
.prose li::marker { color: var(--blue); }

/* anchor offset for sticky header */
:target { scroll-margin-top: 110px; }

/* 10. Footer ============================================================== */
.site-footer {
  background: linear-gradient(180deg, var(--navy-deep), #000018);
  color: #9aa4cf;
  padding-block: clamp(3rem, 6vw, 4.5rem) 2rem;
}
.footer-grid {
  display: grid;
  grid-template-columns: 1.6fr 1fr 1fr 1fr;
  gap: clamp(1.75rem, 4vw, 3rem);
  padding-bottom: 2.5rem;
  border-bottom: 1px solid var(--line-dark);
}
.footer-brand img { height: 30px; margin-bottom: 1.1rem; }
.footer-brand p { color: #8a93bf; max-width: 34ch; font-size: .95rem; }
.footer-col h4 {
  font-family: var(--font-display);
  font-size: .8rem;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: #c7cdf0;
  margin: 0 0 1rem;
}
.footer-col ul { list-style: none; margin: 0; padding: 0; display: grid; gap: .65rem; }
.footer-col a { color: #9aa4cf; font-size: .95rem; }
.footer-col a:hover { color: #fff; }
.footer-bottom {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
  justify-content: space-between;
  align-items: center;
  padding-top: 1.6rem;
  font-size: .85rem;
  color: #6f78a6;
}
.footer-bottom a { color: #8a93bf; }
.footer-bottom a:hover { color: #fff; }
.footer-domains { display: flex; gap: 1rem; flex-wrap: wrap; }

/* 11. Reveal-on-scroll & motion ========================================== */
.reveal {
  opacity: 0;
  transform: translateY(22px);
  transition: opacity .7s var(--ease), transform .7s var(--ease);
  will-change: opacity, transform;
}
.reveal.is-visible { opacity: 1; transform: none; }
.reveal[data-delay="1"] { transition-delay: .08s; }
.reveal[data-delay="2"] { transition-delay: .16s; }
.reveal[data-delay="3"] { transition-delay: .24s; }
.reveal[data-delay="4"] { transition-delay: .32s; }
.reveal[data-delay="5"] { transition-delay: .40s; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .001ms !important;
    transition-duration: .001ms !important;
  }
  .reveal { opacity: 1; transform: none; }
}

/* 12. Responsive ========================================================= */
@media (max-width: 1024px) {
  .footer-grid { grid-template-columns: 1.4fr 1fr 1fr; }
  .footer-brand { grid-column: 1 / -1; }
}

@media (max-width: 900px) {
  .grid--4 { grid-template-columns: repeat(2, 1fr); }
  .flow { grid-template-columns: repeat(3, 1fr); gap: .9rem; }
  .flow__step::after { display: none; }
  .flow__step--highlight { transform: none; }
  .split { grid-template-columns: 1fr; }
  .split--reverse .split__media { order: 0; }
}

@media (max-width: 820px) {
  /* mobile navigation */
  .nav__toggle { display: block; }
  .nav__menu {
    visibility: hidden;
    position: fixed;
    left: 0; right: 0;
    top: 92px;
    flex-direction: column;
    align-items: stretch;
    gap: .9rem;
    background: var(--navy-deep);
    border-bottom: 1px solid var(--line-dark);
    box-shadow: var(--shadow-lg);
    padding: 1.1rem var(--gutter) 1.4rem;
    transform: translateY(-14px);
    opacity: 0;
    pointer-events: none;
    transition: opacity .25s var(--ease), transform .25s var(--ease);
  }
  .nav.is-open .nav__menu {
    visibility: visible;
    transform: none;
    opacity: 1;
    pointer-events: auto;
  }
  .nav__links { flex-direction: column; align-items: stretch; gap: .15rem; }
  /* .nav__links a defaults to navy for the green desktop bar; the open mobile
     menu sits on --navy-deep, so it needs its own light text or it's unreadable. */
  .nav__links a { padding: .85rem 1rem; font-size: 1.05rem; color: #fff; }
  .nav__links a:hover { color: #fff; background: rgba(255, 255, 255, .08); }
  .nav__links a.is-active::after { display: none; }
  .nav__links a.is-active { color: #fff; background: rgba(255, 255, 255, .06); }
  .nav__cta { margin-left: 0; }
  .nav__cta .btn { width: 100%; padding: .95rem 1.15rem; }
}

@media (max-width: 680px) {
  .grid--2, .grid--3, .grid--4, .motion-grid { grid-template-columns: 1fr; }
  .flow { grid-template-columns: 1fr; }
  .form-grid { grid-template-columns: 1fr; }
  .footer-grid { grid-template-columns: 1fr 1fr; }
  .footer-bottom { flex-direction: column; align-items: flex-start; }
  .btn-row .btn { width: 100%; white-space: normal; }
  .hero .btn-row .btn { width: auto; }
}

@media (max-width: 460px) {
  .footer-grid { grid-template-columns: 1fr; }
  .hero .btn-row .btn { width: 100%; }
}

/* ==========================================================================
   13. Added components — scientific figures, real-image workflow,
       scroll-driven pipeline insertion, device frame
   ========================================================================== */

/* --- Generic scientific figure ------------------------------------------- */
.figure { margin: 0; }
.figure__img {
  display: block; width: 100%; height: auto;
  border-radius: var(--radius-lg);
  border: 1px solid var(--line);
  box-shadow: var(--shadow-md);
  background: var(--bg-soft);
}
.figure__img--dark { background: #000; border-color: var(--navy-600); }
.figure--center { max-width: 1000px; margin-inline: auto; }
.figure__cap {
  margin-top: .85rem; font-size: .86rem; line-height: 1.5;
  color: var(--ink-soft); text-align: center;
}
.figure__cap strong { color: var(--ink); }
/* source / licence credit under a figure caption */
.figure__src { display: block; margin-top: .6rem; font-size: .82em; opacity: .85; }

/* --- CryoFlash operational workflow (real microscopy images) ------------- */
.wflow {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: clamp(.8rem, 1.6vw, 1.5rem);
  align-items: start;
  margin-top: clamp(2rem, 5vw, 3.25rem);
}
.wstep { display: flex; flex-direction: column; gap: .7rem; }
.wstep__media {
  position: relative;
  aspect-ratio: 4 / 3;
  border-radius: var(--radius);
  overflow: hidden;
  background: #0b0d15;
  border: 1px solid var(--line);
  box-shadow: var(--shadow-md);
}
.wstep__media img { width: 100%; height: 100%; object-fit: cover; display: block; }
.wstep__media--icon { display: grid; place-items: center;
  background: linear-gradient(165deg, var(--navy-700), var(--navy-deep)); }
.wstep__media--icon .picto { --picto-size: 68px; color: #fff; opacity: .92; }
.wstep__n {
  position: absolute; top: .6rem; left: .6rem; z-index: 2;
  width: 30px; height: 30px; border-radius: 50%;
  display: grid; place-items: center;
  font-family: var(--font-display); font-weight: 700; font-size: .92rem;
  background: var(--green); color: #fff; box-shadow: var(--shadow-sm);
}
.wstep h3 { font-size: 1.02rem; margin: .15rem 0 0; line-height: 1.25; }
.wstep p { font-size: .86rem; color: var(--ink-soft); margin: 0; }

/* --- Scroll-driven insertion: the cryo-EM pipeline + CryoFlash ----------- */
.insert-scrolly { position: relative; }
.insert-scrolly__sticky { padding-block: var(--section-y); }
.insert-scrolly.is-active { height: 180vh; }
.insert-scrolly.is-active .insert-scrolly__sticky {
  position: sticky; top: 0; min-height: 100vh;
  display: flex; flex-direction: column; justify-content: center;
  padding-block: clamp(2rem, 6vh, 4rem);
}

/* Two narrative headings stacked in one cell, crossfading from the
   "standard workflow" intro to the CryoFlash framing as you scroll. */
.insert-heads { display: grid; }
.insert-heads > .insert-head { grid-column: 1; grid-row: 1; margin-bottom: 0; }
.insert-head { transition: opacity .2s linear; }
/* default (no JS / reduced-motion): show the CryoFlash framing, hide the intro */
.insert-head--standard { opacity: 0; visibility: hidden; }
.insert-head--cryoflash { opacity: 1; }
/* while the scroll-scrub is live, both are driven by --insert (0 → 1).
   A quick swap with a slight vertical slide: the intro is fully gone before
   the CryoFlash framing arrives, so the two different headings never overlap
   into a muddy double-exposure. --o is each head's own 0→1 presence. */
.insert-scrolly.is-active .insert-head--standard {
  visibility: visible;
  --o: clamp(0, calc((0.50 - var(--insert, 0)) / 0.12), 1);
  opacity: var(--o);
  transform: translateY(calc((1 - var(--o)) * -8px));
}
.insert-scrolly.is-active .insert-head--cryoflash {
  --o: clamp(0, calc((var(--insert, 0) - 0.50) / 0.12), 1);
  opacity: var(--o);
  transform: translateY(calc((1 - var(--o)) * 8px));
}

.pipeline-status {
  display: flex; justify-content: center; margin-top: 1.4rem;
}
.pipeline-status span {
  font-family: var(--font-display); font-weight: 600; font-size: .82rem;
  letter-spacing: .04em;
  padding: .4rem .95rem; border-radius: var(--radius-pill);
  border: 1px solid var(--line-dark); color: #cfd6f5;
  background: rgba(255, 255, 255, .04);
}
.pipeline-status__a { display: none; }
.insert-scrolly.is-active .pipeline-status__a { display: inline-block; }
.insert-scrolly.is-active .pipeline-status__b { display: none; }
.insert-scrolly.is-active.is-inserted .pipeline-status__a { display: none; }
.insert-scrolly.is-active.is-inserted .pipeline-status__b { display: inline-block; }
.pipeline-status__b { color: #fff; border-color: rgba(0, 166, 251, .5);
  background: rgba(0, 166, 251, .12); }

.pipeline {
  position: relative;
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: .8rem;
  margin-top: clamp(2rem, 5vw, 3.5rem);
}
.pipeline::before {
  content: ""; position: absolute; left: 7%; right: 7%; top: 43px;
  height: 3px; border-radius: 3px;
  background: linear-gradient(90deg, var(--blue), var(--green) 42%, var(--teal));
  opacity: .5;
}
.pstep {
  position: relative; z-index: 1;
  flex: 1 1 0; min-width: 0;
  display: flex; flex-direction: column; align-items: center; text-align: center;
  gap: .55rem;
}
.pstep__chip {
  width: 88px; height: 88px; border-radius: 22px;
  display: grid; place-items: center;
  background: var(--navy-700); border: 1px solid var(--navy-600);
  box-shadow: var(--shadow-md);
}
.pstep__chip .picto { --picto-size: 46px; color: #fff; }
.pstep__label { font-family: var(--font-display); font-weight: 600; color: #fff; font-size: 1rem; }
.pstep__note { font-size: .78rem; color: #a7afda; max-width: 15ch; line-height: 1.35; }

/* The inserted CryoFlash node — larger than its neighbours and lifted onto
   the connector line, with the product name standing out above it. */
.pstep--insert { margin-top: -10px; }     /* recentre the bigger chip on the line */
.pstep__grow {
  display: flex; flex-direction: column; align-items: center; gap: .55rem;
}
.pstep--insert .pstep__badge {
  position: absolute; top: -30px; left: 50%; transform: translateX(-50%);
  z-index: 2; margin: 0; white-space: nowrap;
  font-family: var(--font-display); font-weight: 700; font-size: .82rem;
  letter-spacing: .01em; color: var(--navy);
  background: linear-gradient(120deg, #6cdb1f, var(--green));
  border-radius: var(--radius-pill); padding: .26rem .8rem;
  box-shadow: 0 10px 24px -8px rgba(86, 200, 20, .65);
}
.pstep--insert .pstep__chip {
  width: 108px; height: 108px; border-radius: 28px; position: relative;
  background: linear-gradient(155deg, #2bb6ff, var(--blue-600));
  border-color: transparent; box-shadow: var(--shadow-blue);
}
.pstep--insert .pstep__chip .picto { --picto-size: 60px; }
.pstep--insert .pstep__label { color: #eaf6ff; font-size: 1.06rem; }
/* soft halo that intensifies as the node grows in */
.pstep--insert .pstep__chip::after {
  content: ""; position: absolute; inset: -12px; border-radius: 50%;
  background: radial-gradient(closest-side, rgba(0, 166, 251, .45), transparent 72%);
  z-index: -1; opacity: var(--insert, 1); pointer-events: none;
}
@media (prefers-reduced-motion: no-preference) {
  .insert-scrolly.is-inserted .pstep--insert .pstep__chip { animation: nodePulse 2.8s var(--ease) infinite; }
}
@keyframes nodePulse {
  0%, 100% { box-shadow: var(--shadow-blue); }
  50%      { box-shadow: 0 16px 40px -10px rgba(0, 166, 251, .8), 0 0 0 10px rgba(0, 166, 251, .08); }
}

/* JS scrub: the node collapses to nothing, then grows in with --insert (0→1).
   Only the chip/label/note wrapper is clipped — the badge floats free above. */
.insert-scrolly.is-active .pstep--insert {
  flex: 0 1 auto;
  margin-inline: calc((var(--insert, 1) - 1) * .8rem);
}
.insert-scrolly.is-active .pstep--insert .pstep__grow {
  max-width: calc(var(--insert, 1) * 260px);
  opacity: clamp(0, calc(var(--insert, 1) * 1.4 - .12), 1);
  transform: translateY(calc((1 - var(--insert, 1)) * -10px))
             scale(calc(.72 + .28 * var(--insert, 1)));
  transform-origin: top center;
  overflow: hidden;
}
/* once settled, let the glow / pulse spill freely again */
.insert-scrolly.is-active.is-inserted .pstep--insert .pstep__grow { overflow: visible; }
.insert-scrolly.is-active .pstep--insert .pstep__badge {
  opacity: clamp(0, calc(var(--insert, 1) * 1.7 - .5), 1);
  transform: translateX(-50%) translateY(calc((1 - var(--insert, 1)) * 8px));
}

/* --- Device render frame (CryoShuffle tweezers) -------------------------- */
.device-frame {
  position: relative;
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: radial-gradient(125% 110% at 32% 18%, var(--navy-700), var(--navy-deep) 70%);
  border: 1px solid var(--navy-600);
  box-shadow: var(--shadow-lg);
  display: grid; place-items: center;
  padding: clamp(1.25rem, 3.5vw, 2.75rem);
  aspect-ratio: 3 / 4;
}
.device-frame--wide { aspect-ratio: 3 / 2; }
.device-frame img {
  max-height: 100%; max-width: 100%; width: auto; object-fit: contain;
  filter: drop-shadow(0 22px 44px rgba(0, 0, 0, .55));
}
.device-frame__tag {
  position: absolute; bottom: 1rem; left: 1rem;
  font-size: .78rem; color: #cfd6f5;
  background: rgba(255, 255, 255, .06);
  border: 1px solid var(--line-dark);
  padding: .3rem .7rem; border-radius: var(--radius-pill);
  -webkit-backdrop-filter: blur(4px); backdrop-filter: blur(4px);
}

/* four-up features read better stacked (icon above text) */
.grid--4 .feature { flex-direction: column; gap: .85rem; }

/* tidy ref line for patent / publication */
.ref-line { display: flex; flex-wrap: wrap; gap: 1.5rem; margin-top: 2rem;
  padding-top: 1.5rem; border-top: 1px solid var(--line); }
.ref-line div { font-size: .85rem; color: var(--ink-soft); }
.ref-line .eyebrow { margin: 0 0 .15rem; }
.ref-line a { color: var(--blue-600); font-weight: 600; }

/* --- Responsive for the added components --------------------------------- */
@media (max-width: 1024px) {
  .wflow { grid-template-columns: repeat(3, 1fr); }
}
@media (max-width: 900px) {
  /* drop the scroll-scrub on tablet/phone — show the final inserted pipeline */
  .insert-scrolly.is-active { height: auto; }
  .insert-scrolly.is-active .insert-scrolly__sticky {
    position: static; min-height: 0; padding-block: var(--section-y);
  }
  .insert-scrolly.is-active .pstep--insert { margin-inline: 0; }
  .insert-scrolly.is-active .pstep--insert .pstep__grow {
    max-width: none; opacity: 1; transform: none; overflow: visible;
  }
  /* the intro heading is a desktop scroll device — show only the CryoFlash framing */
  .insert-head--standard { display: none; }
  .insert-head--cryoflash { opacity: 1 !important; }
  .pstep--insert { margin-top: 1.4rem; }   /* room for the floating badge when steps wrap */
  .pipeline { flex-wrap: wrap; gap: 1.5rem 1rem; justify-content: center; }
  .pipeline::before { display: none; }
  .pstep { flex: 0 1 120px; }
  .pipeline-status__a { display: none !important; }
  .insert-scrolly.is-active .pipeline-status__b { display: inline-block !important; }
}
@media (max-width: 640px) {
  .wflow { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 420px) {
  .wflow { grid-template-columns: 1fr; }
  .pstep { flex-basis: 90px; }
  .pstep__chip { width: 72px; height: 72px; }
  .pstep__chip .picto { --picto-size: 38px; }
  .pstep--insert .pstep__chip { width: 88px; height: 88px; }
  .pstep--insert .pstep__chip .picto { --picto-size: 48px; }
}

/* ==========================================================================
   14. Vertical workflow ("journey") — icon left, one-line description right.
       Each row fades in on scroll; the CryoFlash step is emphasised.
   ========================================================================== */
.journey {
  max-width: 900px;
  margin-inline: auto;
  display: grid;
  gap: clamp(.9rem, 2vw, 1.4rem);
}
.journey__step {
  display: grid;
  grid-template-columns: auto 1fr;
  align-items: center;
  gap: clamp(1.25rem, 3vw, 2.25rem);
  padding: clamp(1.15rem, 2.4vw, 1.7rem) clamp(1.3rem, 2.6vw, 2rem);
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
}
.journey__icon {
  width: clamp(76px, 9vw, 104px);
  height: clamp(76px, 9vw, 104px);
  border-radius: 22px;
  display: grid; place-items: center;
  background: var(--bg-soft);
  border: 1px solid var(--line);
  color: var(--ink-soft);
  flex: none;
}
.journey__icon .picto { --picto-size: clamp(42px, 5.5vw, 58px); }
.journey__kicker {
  display: block;
  font-family: var(--font-display);
  font-size: .76rem; font-weight: 600;
  letter-spacing: .12em; text-transform: uppercase;
  color: var(--ink-soft);
  margin-bottom: .3rem;
}
.journey__step h3 { margin: 0 0 .3rem; font-size: clamp(1.3rem, 2.4vw, 1.7rem); }
.journey__step p  { margin: 0; color: var(--ink-soft); font-size: clamp(1.02rem, 1.5vw, 1.15rem); line-height: 1.5; }

/* The CryoFlash step — visually put forth: bigger, dark, with a brand-green tag */
.journey__step--highlight {
  background: linear-gradient(150deg, var(--navy), var(--navy-deep));
  border-color: transparent;
  box-shadow: var(--shadow-lg);
  padding-block: clamp(1.5rem, 3vw, 2.4rem);
}
.journey__step--highlight .journey__kicker { color: var(--green); }
.journey__step--highlight h3 { color: #fff; font-size: clamp(1.5rem, 3vw, 2.1rem); }
.journey__step--highlight p  { color: #b9c2ec; }
.journey__step--highlight .journey__icon {
  width: clamp(92px, 11vw, 132px);
  height: clamp(92px, 11vw, 132px);
  background: linear-gradient(155deg, #2bb6ff, var(--blue-600));
  border-color: transparent;
  color: #fff;
  box-shadow: var(--shadow-blue);
}
.journey__step--highlight .journey__icon .picto { --picto-size: clamp(52px, 7vw, 76px); }
.journey__tag {
  display: inline-block;
  font-family: var(--font-display);
  font-weight: 700; font-size: .72rem;
  letter-spacing: .1em; text-transform: uppercase;
  color: var(--navy);
  background: var(--green);
  padding: .3rem .75rem;
  border-radius: var(--radius-pill);
  margin-bottom: .7rem;
}

/* placeholder note for the future 3D instrument render */
.journey-render {
  max-width: 900px; margin: 0 auto clamp(1.5rem, 3vw, 2.25rem);
  border: 1.5px dashed var(--line-2);
  border-radius: var(--radius-lg);
  background: repeating-linear-gradient(45deg, transparent, transparent 12px, rgba(2,3,68,.02) 12px, rgba(2,3,68,.02) 24px);
  aspect-ratio: 16 / 7;
  display: grid; place-items: center;
  color: var(--ink-soft); font-size: .9rem; text-align: center; padding: 1rem;
}
/* Filled variant: shows the actual instrument render */
.journey-render--filled {
  border-style: solid; border-color: var(--line);
  background: linear-gradient(160deg, var(--bg-soft), var(--bg-mist));
  aspect-ratio: auto;
  display: block; text-align: center;
  padding: clamp(1rem, 3vw, 2.25rem);
}
.journey-render--filled img {
  display: block; max-width: 100%; height: auto; margin: 0 auto;
  filter: drop-shadow(0 20px 38px rgba(2, 3, 68, .18));
}
.journey-render--filled figcaption {
  margin-top: .9rem; font-size: .85rem; color: var(--ink-soft);
}

@media (max-width: 560px) {
  .journey__step { grid-template-columns: 1fr; justify-items: start; gap: 1rem; }
}

/* ==========================================================================
   14b. Dynamics reveal ("what is CryoFlash") — conventional cryo-EM (base)
        cross-fades to the CryoFlash view (transient states added) on scroll.
   ========================================================================== */
.dynfig { max-width: 960px; margin: clamp(1.75rem, 4vw, 3rem) auto 0; }
.dynfig__stage {
  position: relative;
  border-radius: var(--radius-lg);
  overflow: hidden;
  border: 1px solid var(--line);
  background: var(--white);
  box-shadow: var(--shadow-md);
}
/* base defines the box; the overlay covers exactly the same box, so the two
   scatter plots stay pixel-aligned (they share identical axes). */
.dynfig__base { display: block; width: 100%; height: auto; }
.dynfig__dyn {
  position: absolute; inset: 0;
  width: 100%; height: 100%; object-fit: fill;
  opacity: 0;
  transition: opacity 1.3s ease-in-out .15s;
}
.dynfig.is-active .dynfig__dyn { opacity: 1; }
/* Capsid movie sits in the open white space (top-right of the scatter), appearing
   only once the transient state is revealed. Sized as a plain % so it scales
   with the figure. Both the movie and the plot are white, so it blends in. */
.dynfig__spike {
  position: absolute; top: 23%; left: 74%;
  transform: translate(-50%, -50%);
  width: 23%;
  opacity: 0;
  transition: opacity 1s ease-in-out .55s;
}
.dynfig__spike img,
.dynfig__spike video { display: block; width: 100%; height: auto; }
.dynfig.is-active .dynfig__spike { opacity: 1; }
/* state pill, cross-fading gray → green as the transient states appear */
.dynfig__state {
  position: absolute; top: 1rem; left: 1rem;
  font-family: var(--font-display); font-weight: 600;
  font-size: .8rem; letter-spacing: .01em;
  padding: .35rem .8rem; border-radius: var(--radius-pill);
  -webkit-backdrop-filter: blur(4px); backdrop-filter: blur(4px);
  transition: opacity .9s ease-in-out .15s;
}
.dynfig__state--before { background: rgba(2, 3, 68, .055); color: var(--navy); border: 1px solid var(--line); }
.dynfig__state--after  { background: var(--green); color: var(--navy); opacity: 0; }
.dynfig.is-active .dynfig__state--before { opacity: 0; }
.dynfig.is-active .dynfig__state--after  { opacity: 1; }
.dynfig__sentinel { height: 1px; }
.dynfig__cap {
  margin: .9rem auto 0; max-width: 760px;
  font-size: .86rem; line-height: 1.55;
  color: var(--ink-soft); text-align: center;
}
.dynfig__cap strong { color: var(--ink); }
.dynfig__note { display: block; margin-top: .35rem; font-size: .78rem; opacity: .8; }
@media (prefers-reduced-motion: reduce) {
  /* Sitewide, reduced motion collapses all transitions to ~0 (see the global
     rule above). This particular fade reveals new information rather than
     decorating the page, so it keeps a real crossfade even then. */
  .dynfig__dyn, .dynfig__spike, .dynfig__state {
    transition-duration: 1s !important;
  }
}

/* Centred checklist: the BLOCK is centred in the column, but the items are
   stacked and share one left edge, so the ticks line up under each other
   instead of landing wherever a centred flex row happens to break. */
.checklist--inline {
  display: grid;
  justify-items: start;
  gap: .55rem;
  width: fit-content;
  max-width: 100%;
  margin: clamp(1.25rem, 3vw, 1.85rem) auto 0;
}
.checklist--inline li { padding-left: 1.7rem; }

/* ==========================================================================
   15. Proof points — patents, peer-reviewed papers, EPFL origin, partners
   ========================================================================== */
.proof-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(1rem, 2.5vw, 1.75rem);
  margin-bottom: clamp(2rem, 4vw, 3rem);
}
.proof-card {
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  padding: clamp(1.5rem, 3vw, 2.1rem);
  box-shadow: var(--shadow-sm);
}
.proof-card .proof-num {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(2rem, 4.5vw, 2.9rem);
  line-height: 1; letter-spacing: -.03em;
  color: var(--navy);
}
.proof-card .proof-num .unit { color: var(--blue-600); }
.proof-card h3 { font-size: 1.15rem; margin: .9rem 0 .35rem; }
.proof-card p { margin: 0; color: var(--ink-soft); font-size: .98rem; }

/* publication list */
.pub-list { list-style: none; margin: 0; padding: 0; display: grid; gap: .85rem; }
.pub-list li {
  position: relative;
  padding-left: 1.5rem;
  color: var(--ink-soft);
  font-size: 1rem; line-height: 1.5;
}
.pub-list li::before {
  content: ""; position: absolute; left: 0; top: .55rem;
  width: .5rem; height: .5rem; border-radius: 50%;
  background: var(--blue);
}
.pub-list .pub-authors { color: var(--navy); font-weight: 600; }
.pub-list .pub-venue { font-style: italic; }
/* each entry links out to its DOI */
.pub-list a { color: inherit; text-decoration: none; transition: color .2s var(--ease); }
.pub-list a:hover,
.pub-list a:focus-visible { color: var(--blue-600); text-decoration: underline; text-underline-offset: 3px; }
.pub-list a:hover .pub-authors,
.pub-list a:focus-visible .pub-authors { color: var(--blue-600); }

/* partners / grants logo strip */
.partner-row {
  display: flex; flex-wrap: wrap; gap: 1rem;
  align-items: stretch; justify-content: center;
}
.partner-logo {
  flex: 1 1 170px; max-width: 230px; min-height: 84px;
  display: grid; place-items: center; text-align: center;
  padding: 1rem 1.25rem;
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  color: var(--ink-soft); font-size: .85rem; line-height: 1.35;
  background: var(--white);
  box-shadow: var(--shadow-sm);
}
.partner-logo img { max-width: 100%; max-height: 60px; width: auto; height: auto; object-fit: contain; }
/* fixed layouts, so the tile count never leaves an orphan row: two-up for an
   even number of tiles, three-up for the grant + grant + test-site row */
.partner-row--2up { display: grid; grid-template-columns: repeat(2, 1fr); }
.partner-row--3up { display: grid; grid-template-columns: repeat(3, 1fr); }
.partner-row--2up .partner-logo, .partner-row--3up .partner-logo { max-width: none; }
.partner-row--3up .partner-logo { padding: 1rem .9rem; }
@media (max-width: 480px) { .partner-row--2up, .partner-row--3up { grid-template-columns: 1fr; } }
/* while the proof grid is still two columns but each column is narrow, three
   tiles across would shrink the logos to about 70px; stack them instead */
@media (min-width: 761px) and (max-width: 1000px) { .partner-row--3up { grid-template-columns: 1fr; } }

@media (max-width: 760px) {
  .proof-grid { grid-template-columns: 1fr; }
}

/* ==========================================================================
   16. Two product lines — visual split (icon left, product name as a
       light-blue bold header). Makes the two independent lines obvious.
   ========================================================================== */
.prodsplit {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: clamp(1.25rem, 3vw, 2rem);
}
.prodsplit__item {
  display: grid;
  grid-template-columns: auto 1fr;
  align-items: center;
  gap: clamp(1.1rem, 2.4vw, 1.75rem);
  padding: clamp(1.5rem, 3vw, 2.25rem);
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  color: inherit;
  transition: transform .3s var(--ease), box-shadow .3s var(--ease), border-color .3s var(--ease);
}
.prodsplit__item:hover {
  transform: translateY(-4px);
  box-shadow: var(--shadow-md);
  border-color: var(--line-2);
  color: inherit;
}
.prodsplit__icon {
  width: clamp(76px, 9vw, 104px);
  height: clamp(76px, 9vw, 104px);
  border-radius: 22px;
  display: grid; place-items: center;
  background: linear-gradient(160deg, rgba(0, 166, 251, .14), rgba(0, 166, 251, .04));
  border: 1px solid var(--line);
  color: var(--blue-600);
  flex: none;
}
.prodsplit__icon .picto { --picto-size: clamp(42px, 5.5vw, 58px); }
.prodsplit__name {
  display: block;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(1.35rem, 2.5vw, 1.8rem);
  letter-spacing: -.02em;
  color: var(--blue);              /* light-blue, bold product name */
  margin-bottom: .35rem;
}
.prodsplit__body p { margin: 0 0 .7rem; color: var(--ink-soft); font-size: 1.02rem; line-height: 1.5; }
.prodsplit__link {
  display: inline-flex; align-items: center; gap: .4rem;
  font-family: var(--font-display); font-weight: 600;
  color: var(--blue-600);
}
.prodsplit__link .btn__arrow { transition: transform .25s var(--ease); }
.prodsplit__item:hover .prodsplit__link .btn__arrow { transform: translateX(4px); }

@media (max-width: 800px) { .prodsplit { grid-template-columns: 1fr; } }
@media (max-width: 460px) { .prodsplit__item { grid-template-columns: 1fr; justify-items: start; } }

/* 3D-render placeholder at the top of the instrument cards (links to the page) */
.product-card__render {
  display: grid; place-items: center;
  aspect-ratio: 16 / 10;
  border-radius: var(--radius);
  border: 1.5px dashed var(--line-2);
  background: repeating-linear-gradient(45deg, transparent, transparent 12px, rgba(2, 3, 68, .02) 12px, rgba(2, 3, 68, .02) 24px);
  color: var(--ink-soft); font-size: .85rem; text-align: center; padding: 1rem;
  transition: border-color .25s var(--ease), color .25s var(--ease);
}
.product-card__render:hover { border-color: var(--blue); color: var(--blue-600); }
/* Filled variant: shows an actual instrument render instead of the placeholder */
.product-card__render--filled {
  border-style: solid;
  border-color: var(--line);
  background: linear-gradient(160deg, var(--bg-soft), var(--bg-mist));
  padding: clamp(.6rem, 2.2vw, 1.4rem);
  overflow: hidden;
}
.product-card__render--filled img {
  max-width: 100%; max-height: 100%; width: auto; height: auto;
  display: block;
  filter: drop-shadow(0 16px 30px rgba(2, 3, 68, .16));
  transition: transform .35s var(--ease);
}
.product-card__render--filled:hover { border-color: var(--line); }
.product-card__render--filled:hover img { transform: translateY(-2px) scale(1.015); }

/* ==========================================================================
   CCMV example — three-beat scroll story (cryoflash.html)
   One shared plot sits between beat 2 and beat 3. Reaching the beat-3 text
   swaps it in place: fig2b (an opaque copy differing only by the blue
   population) fades in over fig2a, and the grey badge crossfades to green.
   Default styles ship the FINISHED state; `.js` opts into the animation, so
   the section is complete with JavaScript disabled.
   ========================================================================== */
.ccmv {
  /* figures share exactly the text measure — never wider than the copy */
  --ccmv-measure: 44rem;
  max-width: var(--ccmv-measure);
}

.ccmv-beat + .ccmv-beat { margin-top: clamp(2rem, 4.5vw, 3rem); }
/* a little more air after the plot, so the grey "conventional" state is read
   before the beat-3 heading reaches the swap line */
.ccmv-plotfig + .ccmv-beat { margin-top: clamp(2.75rem, 6vw, 4.25rem); }
.ccmv-beat:first-child, .ccmv__title { margin-top: clamp(2.75rem, 6vw, 4.25rem); }
/* subsection heading above the worked example */
.ccmv__title {
  font-family: var(--font-display);
  font-size: clamp(.78rem, 1.5vw, .86rem);
  font-weight: 600;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--ink-soft);
  margin-bottom: 0;
  padding-bottom: .7rem;
  border-bottom: 1px solid var(--line);
}
.ccmv__title + .ccmv-beat { margin-top: clamp(1.5rem, 3.5vw, 2.1rem); }
.ccmv-beat__title {
  font-family: var(--font-display);
  font-size: clamp(1.3rem, 2.4vw, 1.6rem);
  font-weight: 600;
  color: var(--navy);
  margin-bottom: .6rem;
}
.ccmv-beat__text p { color: var(--ink-soft); margin: 0; }
.ccmv-beat__text p + p { margin-top: .7rem; }
.ccmv-beat__aside { font-size: .88rem; }

.ccmv-fig { margin: clamp(1.1rem, 2.5vw, 1.6rem) 0 0; }
.ccmv-fig__img { display: block; width: 100%; height: auto; background: var(--white); }

/* --- the shared plot: the base figure, plus the layer CryoFlash adds ---
   The overlay is not a second copy of the figure. It holds only the mid-collapse
   population, its capsid render and its label, on a transparent ground, so the
   base simply shows through everywhere else and only the blue fades up. Nothing
   exists in both layers, so nothing is drawn twice (no double-composited
   densities, no doubled anti-aliasing on the axes) and nothing is decoded twice.
   That last part matters: an earlier version stacked two complete figures, which
   made the browser hold five large rasters to paint three populations and could
   push it past its image-decode budget on a phone, silently dropping one.
   The white ground sits on the container, not on the layers, so the overlay can
   stay transparent while the plot is still guaranteed opaque.
   object-fit is `fill`, not `contain`: both layers share one viewBox, so the
   overlay has to map onto the box exactly as the base does, with no contain-fit
   rounding that could nudge the blue cloud off the axes underneath it. */
.ccmv-plotfig { margin: clamp(1.5rem, 3.5vw, 2.25rem) 0 0; }
.ccmv-plot { position: relative; background: var(--white); }
.ccmv-plot__img { display: block; width: 100%; height: auto; }
.ccmv-plot__overlay { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: fill; }
.js .ccmv-plot__overlay { opacity: 0; transition: opacity .7s var(--ease); }
.js .ccmv-plotfig.is-after .ccmv-plot__overlay { opacity: 1; }

/* --- method key: the grey badge stays, the green one joins it ---
   These used to be absolutely positioned inside the plot, where the longer
   green label collided with the in-figure "caught mid-collapse" caption once
   the figure got narrow. They now sit below the plot, so no overlap is possible
   at any width.
   The green badge is laid out from the start and only its opacity animates, so
   the row is already the right size and nothing below it shifts when the badge
   arrives — including on phones, where the pair wraps onto two lines. */
/* legend under the shared plot (what the axes and the shading mean) */
.ccmv-plotcap {
  margin: .8rem 0 0;
  font-size: .84rem;
  line-height: 1.55;
  color: var(--ink-soft);
}
.ccmv-plotcap strong { color: var(--navy); font-weight: 600; }
.ccmv-key { display: flex; flex-wrap: wrap; gap: .5rem .55rem; margin-top: .8rem; }
.ccmv-badge {
  display: flex;
  align-items: center;
  gap: .5rem;
  margin: 0;
  padding: .36rem .8rem .36rem .62rem;
  border-radius: 999px;
  font-family: var(--font-display);
  font-size: clamp(.72rem, 1.5vw, .8rem);
  font-weight: 600;
  line-height: 1.25;
  text-align: left;
}
/* colour key — sampled from the density cores in the figure itself */
.ccmv-dots { display: inline-flex; gap: .2rem; flex: none; }
.ccmv-dot {
  width: .6rem; height: .6rem;
  border-radius: 50%;
  flex: none;
  box-shadow: inset 0 0 0 1px rgba(2, 3, 68, .12);
}
.ccmv-dot--swollen { background: #d13f91; }
.ccmv-dot--compact { background: #05d17d; }
.ccmv-dot--mid     { background: #00a6fb; }
.ccmv-badge--conv {
  background: rgba(2, 3, 68, .055);
  color: var(--ink-soft);
  border: 1px solid var(--line);
}
.ccmv-badge--flash {
  background: var(--green);
  color: var(--navy);
  border: 1px solid transparent;
}
/* The grey badge is always on: a conventional experiment still resolves those
   two populations after the swap — CryoFlash adds a third one, it does not
   replace them. Only the green badge waits for the swap, and without JS the
   finished state (both badges) is what renders. */
.js .ccmv-badge--flash { opacity: 0; transition: opacity .7s var(--ease); }
.js .ccmv-plotfig.is-after .ccmv-badge--flash { opacity: 1; }

/* --- beat 3: text with the model loop beside it --- */
.ccmv-beat--split {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(200px, 280px);
  gap: clamp(1rem, 2.5vw, 1.6rem);
  align-items: start;
}
.ccmv-movie { margin: 0; }
.ccmv-movie__video {
  display: block; width: 100%; height: auto;
  border-radius: var(--radius);
  border: 1px solid var(--line);
  background: var(--white);
}
.ccmv-movie__cap {
  margin-top: .55rem;
  font-size: .74rem;
  line-height: 1.45;
  color: var(--ink-soft);
}

/* --- figure credit --- */
.ccmv-credit {
  margin-top: clamp(1.5rem, 3.5vw, 2.25rem);
  padding-top: clamp(.9rem, 2vw, 1.2rem);
  border-top: 1px solid var(--line);
  font-size: .8rem;
  line-height: 1.6;
  color: var(--ink-soft);
}
.ccmv-credit a { color: var(--blue-600); text-decoration: underline; text-underline-offset: 2px; }

@media (max-width: 640px) {
  .ccmv-beat--split { grid-template-columns: 1fr; }
  .ccmv-movie { max-width: 220px; margin-inline: auto; }
}

/* Reduced motion: no swap animation, no movie — the finished state, at once. */
@media (prefers-reduced-motion: reduce) {
  .js .ccmv-plot__overlay,
  .js .ccmv-badge--flash { opacity: 1 !important; transition: none !important; }
}


/* ==========================================================================
   17. Review-driven additions
   - .hero--live      homepage hero canvas (melt-and-freeze film) + readout
   - .reqbox          "What CryoFlash asks of you" honesty callout
   - .spec            provisional specification tables on the product pages
   - .timeline        milestones on the about page
   ========================================================================== */

/* --- homepage hero animation --- */
.hero--live::after { display: none; }   /* the dot grid gives way to the animated film */
.hero__canvas { position: absolute; inset: 0; width: 100%; height: 100%; z-index: 0; }
.hero__veil {
  position: absolute; inset: 0; z-index: 0; pointer-events: none;
  /* A wash across the copy column, clearing before the right-hand side so the
     melt is not dimmed where there is nothing to protect. It is deliberately
     flat with height: a radial blob here put a soft-edged dark shape behind the
     headline, which read as a blurred patch rather than as shading. The wash
     cannot simply be dropped: measured against the glyphs, taking it away puts
     the lead at 2.2:1 and even the headline at 2.7:1, against the 4.5:1 and
     3:1 they have to clear. */
  background:
    linear-gradient(to right, rgba(2, 3, 56, .75) 0%, rgba(2, 3, 56, .68) 34%,
                              rgba(2, 3, 56, .38) 64%, transparent 84%),
    linear-gradient(to bottom, rgba(1, 2, 36, .30), transparent 28%, rgba(1, 2, 36, .38));
}
/* The eyebrow's default ink is meant for white sections; on navy it is already
   marginal, and over the film it drops to 1.6:1. Green is what the homepage
   hero used inline, so both animated heroes now share one rule. */
.hero--live .hero__inner .eyebrow { color: var(--green); }
/* the film shows through the wash, so the copy carries a little of its own
   separation rather than asking the wash to be heavy enough for both */
.hero--live .hero__inner .eyebrow,
.hero--live .hero__inner h1,
.hero--live .hero__inner .hero__sub {
  text-shadow: 0 1px 12px rgba(1, 2, 30, .85), 0 0 3px rgba(1, 2, 30, .7);
}
/* The CryoShuffle film is one bright continuous band rather than a scatter of
   small holes, so the copy needs more help here than on the other two heroes.
   Taking it out of the wash would have hidden the left of the sample, which is
   half the picture, so the wash is only a little above the standard one and
   the lead carries the rest by being brighter. Same rule either way: flat with
   height, no shape anywhere. */
.hero--film .hero__veil {
  background:
    linear-gradient(to right, rgba(2, 3, 56, .72) 0%, rgba(2, 3, 56, .60) 34%,
                              rgba(2, 3, 56, .30) 66%, transparent 86%),
    linear-gradient(to bottom, rgba(1, 2, 36, .30), transparent 28%, rgba(1, 2, 36, .38));
}
.hero--film .hero__inner .hero__sub { color: #e9f0ff; }
/* below this width the copy runs past the point where the wash has cleared,
   so the wash keeps going instead of ending */
@media (max-width: 1000px) {
  .hero--film .hero__veil {
    background:
      linear-gradient(to right, rgba(2, 3, 56, .82) 0%, rgba(2, 3, 56, .76) 55%,
                                rgba(2, 3, 56, .64) 100%),
      linear-gradient(to bottom, rgba(1, 2, 36, .30), transparent 28%, rgba(1, 2, 36, .38));
  }
}

/* the readout describes the film, so it only appears if the film can be drawn */
.hero__readout { display: none; }
.js .hero__readout {
  display: block;
  position: absolute; right: clamp(1.25rem, 4vw, 3rem); bottom: clamp(1rem, 3vh, 2rem);
  z-index: 1; text-align: right; pointer-events: none;
  font-family: var(--font-display);
  font-size: .7rem; font-weight: 600; letter-spacing: .1em; text-transform: uppercase;
  color: rgba(255, 255, 255, .5); line-height: 1.9;
}
.hero__readout span { display: block; }
/* the phase names the step the animation is showing, so it is the part that
   has to be readable; the caption above the temperature is the quiet one */
.hero__readout #hero-phase {
  font-size: .82rem; letter-spacing: .09em;
  color: rgba(255, 255, 255, .84);
}
.hero__readout-label { color: rgba(255, 255, 255, .42); }
/* the phase and its clock share a line; the clock keeps its own casing, because
   uppercasing "22 µs" turns the micro sign into a capital Mu and it reads as
   milliseconds -- three orders of magnitude wrong, on our headline claim */
.hero__readout #hero-phase, .hero__readout #hero-clock { display: inline; }
.hero__readout #hero-clock { text-transform: none; }
.hero__readout b {
  display: block; font-size: 1.45rem; font-weight: 600; letter-spacing: 0;
  color: var(--blue); transition: color .5s var(--ease);
}
.hero__readout.is-hot b { color: #ff9a66; }
.hero__readout.is-cold b { color: #d3e9ff; }   /* the CryoShuffle film, vitrified */
.hero__readout-note {
  display: block; margin-top: .35rem;
  font-size: .66rem; font-weight: 500; letter-spacing: .08em;
  color: rgba(255, 255, 255, .5); text-transform: none;
}
/* On a phone the full readout is too much, but dropping it entirely leaves an
   abstract band of shapes with nothing naming what is happening. Keep a
   one-line chip: the phase, and the temperature beside it. */
@media (max-width: 760px) {
  .js .hero__readout {
    right: auto; left: clamp(1rem, 5vw, 1.5rem); bottom: .8rem;
    text-align: left; line-height: 1.45;
  }
  .hero__readout-label, .hero__readout-note { display: none; }
  .hero__readout b { display: inline; font-size: .92rem; margin-right: .45rem; }
  .hero__readout #hero-phase { font-size: .68rem; }
}

/* two rows of one comparison figure, read down rather than across */
.figure--stack .figure__img + .figure__img { margin-top: clamp(.75rem, 2vw, 1.25rem); }

/* --- in-page navigation on the long product pages ------------------------ */
.pagenav {
  border-bottom: 1px solid var(--line);
  background: var(--white);
  position: sticky; top: var(--header-h, 0); z-index: 20;
}
.pagenav ul {
  display: flex; flex-wrap: wrap; gap: .25rem 1.5rem;
  margin: 0; padding: .75rem 0; list-style: none;
}
.pagenav a {
  font-family: var(--font-display);
  font-size: .78rem; font-weight: 600; letter-spacing: .06em; text-transform: uppercase;
  color: var(--ink-soft); text-decoration: none;
}
.pagenav a:hover, .pagenav a:focus-visible { color: var(--blue-600); }
@media (max-width: 700px) {
  .pagenav { position: static; }
  .pagenav ul { flex-wrap: nowrap; overflow-x: auto; gap: 1.1rem; }
  .pagenav li { flex: none; }
}

/* --- pause control ------------------------------------------------------- */
.hero__pause {
  position: absolute; z-index: 2;
  left: clamp(1.25rem, 4vw, 3rem); bottom: clamp(1rem, 3vh, 2rem);
  display: grid; place-items: center;
  width: 34px; height: 34px; padding: 0;
  border: 1px solid rgba(255, 255, 255, .22); border-radius: 50%;
  background: rgba(2, 3, 56, .55); color: rgba(255, 255, 255, .68);
  cursor: pointer;
  transition: color .2s var(--ease), border-color .2s var(--ease), background .2s var(--ease);
}
.hero__pause:hover { color: #fff; border-color: rgba(255, 255, 255, .45); background: rgba(2, 3, 56, .8); }
.hero__pause[hidden] { display: none; }
@font-face { font-family: 'Space Grotesk'; src: url('assets/fonts/SpaceGrotesk.ttf') format('truetype'); font-weight: 300 700; font-style: normal; font-display: swap; }
@font-face { font-family: 'Inter'; src: url('assets/fonts/Inter.ttf') format('truetype'); font-weight: 100 900; font-style: normal; font-display: swap; }

/* September review: hierarchy, readable figures and compact utility routes. */
.site-header.is-scrolled .nav { height: 74px; }
.site-header.is-scrolled .nav__brand img { height: 36px; }
.hero:not(.hero--live) .eyebrow { color: #83db54; }
.hero--utility { padding-block: clamp(2rem, 5vw, 3.5rem); }
.hero--utility .display { font-size: clamp(2rem, 4.5vw, 3.7rem); }
.hero--utility .hero__sub { margin-bottom: 0; }
/* the hero's three-point summary, plain text rather than dotted badges */
.hero__points { font-size: .95rem; color: #aab4e0; margin: 0; }
/* utility pages are all content: start it near the fold, not a screen down */
.hero--utility + .section { padding-top: clamp(1.75rem, 3.5vw, 2.75rem); }
/* the comparison figure runs straight into the science section below it */
.section--flush-b { padding-bottom: clamp(1.25rem, 2.5vw, 2rem); }
.hero__status { max-width: 65ch; font-size: .85rem; color: #d2dcf3; margin: 1rem 0 0; }
.hero--live { padding-bottom: max(6rem, 9vw); }
.btn--quiet { --btn-fg: #fff; color: white; background: transparent; border-color: transparent; text-decoration: underline; }
.btn--quiet:hover { background: rgba(2,3,68,.5); }
.cta-band .btn--ghost, .cta-band .btn--ghost-light { background: rgba(2,3,68,.55); color: white; border-color: rgba(255,255,255,.4); }
.cta-band .eyebrow { color: #83db54; }
.product-card__body strong { display: block; margin-bottom: .4rem; }
.product-card__links a + a { font-weight: 400; }
.visualization-label,.pub-note { display: block; font-size: .8rem; color: var(--ink-soft); margin: .4rem 0; }
.pub-note { font-weight: 500; }
.team-bio { font-size: .9rem; line-height: 1.6; color: var(--ink-soft); }
.media-frame figcaption { padding: .7rem 1rem; font-size: .85rem; }
.figure__label { padding: .8rem 1rem 0; font-size: 1rem; }
.prose a, .figure__src a { overflow-wrap: anywhere; }
.split > * { min-width: 0; }
.device-frame--vertical { aspect-ratio: auto; }
.device-frame--vertical { min-height: 480px; max-width: 420px; margin-inline: auto; }
.device-frame--vertical img { height: 440px; width: 100%; object-fit: contain; }
.movie-control { font-size: .8rem; padding: .6rem .8rem; margin-top: .6rem; }
.hero__film-space { display: none; }
.figure-enlarge { display: inline-block; font: inherit; font-size: .85rem; padding: .5rem .8rem; margin: .5rem; color: var(--navy); background: white; border: 1px solid #8294a4; border-radius: 6px; cursor: zoom-in; }
.figure-dialog { width: min(96vw, 1400px); max-width: 96vw; max-height: 94vh; padding: 1rem; border: 0; border-radius: 12px; color: var(--navy); }
.figure-dialog::backdrop { background: rgba(2,3,30,.85); }
.figure-dialog__bar { display: flex; align-items: center; justify-content: space-between; gap: 1rem; position: sticky; top: -1rem; background: white; padding: .5rem; z-index: 2; }
.figure-dialog__bar p { margin: 0; font-size: .85rem; }
.figure-dialog__images { overflow: auto; }
.figure-dialog__images img { display: block; width: 100%; height: auto; }
.figure-dialog__images.is-zoomed img { width: 1400px; max-width: none; }
.figure-dialog__stack { display: grid; }
.figure-dialog__stack img { grid-area: 1 / 1; }
[id] { scroll-margin-top: calc(var(--header-h, 74px) + 65px); }
@media (max-width: 820px) {
  .site-header.is-scrolled .nav__menu { top: 74px; }
  .hero--film .hero__film-space { display: block; height: 190px; margin: .6rem 0 1.4rem; }
  .hero--film { padding-bottom: 6rem; }
  .hero--film .hero__veil { background: linear-gradient(to bottom, rgba(2,3,68,.72) 0 var(--film-top, 250px), rgba(2,3,68,.1) var(--film-top, 250px) var(--film-bottom, 440px), rgba(2,3,68,.72) var(--film-bottom, 440px) 100%); }
  .contact-layout .split__media { order: -1; }
  .js .hero__readout { max-width: calc(100% - 5rem); text-align: left; }
  .hero__status { font-size: .8rem; }
  .hero--film .badge-row { gap: .6rem 1rem; }
  .device-frame--vertical { min-height: 380px; }
  .device-frame--vertical img { height: 350px; }
}
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }
.hero__pause svg { width: 15px; height: 15px; fill: currentColor; }
.hero__pause .hero__pause-ico--play { display: none; }
.hero__pause[aria-pressed="true"] .hero__pause-ico--pause { display: none; }
.hero__pause[aria-pressed="true"] .hero__pause-ico--play { display: block; }
.btn:disabled { opacity: .6; cursor: not-allowed; box-shadow: none; }
.media-frame--photo:has(figcaption) { display: block; aspect-ratio: auto; }
@media (max-width: 760px) {
  .hero__pause { left: auto; right: clamp(1rem, 5vw, 1.5rem); bottom: .8rem; }
}

/* --- requirements callout (CryoFlash) --- */
.reqbox {
  margin-top: clamp(2rem, 4vw, 3rem);
  background: var(--white);
  border: 1px solid var(--line);
  border-left: 4px solid var(--green);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
  padding: clamp(1.25rem, 2.5vw, 1.75rem);
}
.reqbox h3 { font-size: 1.08rem; margin-bottom: .8rem; }
.reqbox ul { margin: 0; padding-left: 1.15rem; color: var(--ink-soft); }
.reqbox li { margin-bottom: .55rem; }
.reqbox li:last-child { margin-bottom: 0; }
/* closes the list in the same voice as the heading above it */
.reqbox__close {
  font-family: var(--font-display); font-weight: 700;
  font-size: 1.08rem; color: var(--navy);
  margin: .9rem 0 0;
}
.reqbox strong { color: var(--navy); }

/* --- provisional spec tables --- */
.spec { margin: clamp(1.5rem, 3.5vw, 2.25rem) 0 0; border-top: 2px solid var(--navy); }
/* the label keeps its own width and the value wraps; with the old 1fr/auto
   split a long value squeezed the label to nothing and the two overlapped */
.spec > div {
  display: grid; grid-template-columns: fit-content(15rem) minmax(0, 1fr);
  gap: .5rem 1.25rem; padding: .7rem 0;
  border-bottom: 1px solid var(--line);
}
.spec dt {
  font-family: var(--font-display); font-weight: 600;
  font-size: .78rem; letter-spacing: .08em; text-transform: uppercase;
  color: var(--ink-soft); padding-top: .15rem;
}
.spec dd { margin: 0; text-align: right; color: var(--navy); font-weight: 500; }
.spec dd.spec--tbd { color: var(--ink-soft); font-style: italic; font-weight: 400; }
@media (max-width: 560px) {
  .spec > div { grid-template-columns: 1fr; gap: .1rem; }
  .spec dd { text-align: left; }
}

/* --- milestones timeline (about) --- */
.timeline {
  margin-top: clamp(2rem, 5vw, 3rem);
  border-left: 2px solid var(--line-2);
  padding-left: clamp(1.5rem, 3vw, 2.5rem);
  display: grid; gap: clamp(1.5rem, 3vw, 2rem);
}
.timeline__item { position: relative; }
.timeline__item::before {
  content: "";
  position: absolute; top: .35rem;
  left: calc(-1 * clamp(1.5rem, 3vw, 2.5rem) - 7px);
  width: 12px; height: 12px; border-radius: 50%;
  background: var(--blue-600);
  border: 2px solid var(--white);
}
.timeline__item--now::before {
  background: var(--green);
  box-shadow: 0 0 0 4px rgba(86, 200, 20, .18);
}
/* planned, not achieved: a hollow marker so the timeline does not read as
   though 2027 and 2028 have already happened */
.timeline__item--planned::before {
  background: var(--white);
  box-shadow: inset 0 0 0 2px var(--line-2);
}
.timeline__year {
  font-family: var(--font-display); font-weight: 700;
  font-size: .8rem; letter-spacing: .1em; text-transform: uppercase;
  color: var(--ink-soft);
}
.timeline__item h3 { font-size: 1.15rem; margin: .2rem 0 .3rem; }
.timeline__item p { margin: 0; color: var(--ink-soft); max-width: 62ch; }
