/* ===== Fonts ===== */
/* ==========================================================================
   Self-hosted typefaces

   Files live in public/fonts/ and are served from our own origin. There is no
   request to Google Fonts or any other font service at runtime, which keeps
   the Content-Security-Policy `font-src 'self'` intact and sends no visitor
   data anywhere.

   Only the Latin subsets are shipped — 76 KB in total for all four files.
   Provenance and licences: docs/FONTS.md and docs/font-licenses/.

   `font-display: swap` means text is painted immediately in the fallback and
   swaps when the file arrives. Reading is never blocked on a font.
   ========================================================================== */

/* Headings — Manrope, variable weight 200–800 in a single 28 KB file. */
@font-face {
  font-family: "Manrope Variable";
  font-style: normal;
  font-weight: 200 800;
  font-display: swap;
  src: url("../fonts/manrope-variable-latin.woff2") format("woff2-variations");
  unicode-range:
    U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329,
    U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* Body — Source Sans 3, regular and semibold. */
@font-face {
  font-family: "Source Sans 3";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("../fonts/source-sans-3-latin-400.woff2") format("woff2");
  unicode-range:
    U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329,
    U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "Source Sans 3";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("../fonts/source-sans-3-latin-600.woff2") format("woff2");
  unicode-range:
    U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329,
    U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* Technical labels only — IBM Plex Mono, one weight. */
@font-face {
  font-family: "IBM Plex Mono";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("../fonts/ibm-plex-mono-latin-500.woff2") format("woff2");
  unicode-range:
    U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329,
    U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* ===== Global styles ===== */
/* ==========================================================================
   exRNA Therapeutics — global stylesheet

   Organisation:
     1. Design tokens
     2. Reset and base elements
     3. Typography
     4. Layout primitives
     5. Components (header, footer, cards, buttons, visuals)
     6. Motion and reveal
     7. Print

   Colour choices are checked for WCAG AA contrast. If you change a colour,
   re-check it against its background before shipping.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Design tokens
   -------------------------------------------------------------------------- */

:root {
  /* ---------------------------------------------------------------------
     Brand palette.

     Every value below was checked for WCAG contrast before use. The four
     bright accents DO NOT pass AA for small text on a light background —
     measured against Porcelain they are: Precision Teal 2.81, RNA Cyan
     1.66, Microbial Amber 2.15, Neural Violet 4.24. Neural Violet also
     fails on Midnight (3.90).

     So each accent has two forms:
       *  the bright brand colour — large text, rules, marks, SVG only
       *  an `-ink` form         — safe for small text on light
       *  an `-on-dark` form     — safe for small text on Midnight

     If you reach for a bright accent for body-size text, reach for the
     `-ink` variant instead.
     --------------------------------------------------------------------- */

  /* Midnight and Graphite */
  --ink-900: #071a2b; /* Midnight */
  --ink-800: #0e2438; /* raised dark surface */
  --ink-700: #24333e; /* Graphite */
  --ink-600: #33475a;

  /* Porcelain and Mist */
  --paper-000: #ffffff;
  --paper-100: #f6f8f7; /* Porcelain */
  --paper-200: #e5ecee; /* Mist */
  --paper-300: #d3dee2;

  /* Precision Teal / RNA Cyan */
  --teal: #15a6a1; /* Precision Teal — large text, rules, marks */
  --cyan: #48d7cc; /* RNA Cyan — dark backgrounds only */
  --accent-700: #0e7571; /* teal ink: 5.18 on Porcelain — small text, buttons */
  --accent-600: #0e7571;
  --accent-500: var(--teal);
  --accent-300: var(--cyan); /* 9.96 on Midnight */

  /* Neural Violet — the CNS section only */
  --violet: #7167d9;
  --violet-ink: #4a42a8; /* 7.47 on Porcelain */
  --violet-on-dark: #8b83e4; /* 5.42 on Midnight */

  /* Microbial Amber — the microbial section only */
  --amber: #d5a348; /* 7.69 on Midnight, so fine there */
  --amber-ink: #7a5d18; /* 5.78 on Porcelain */

  /* Semantic roles */
  --bg: var(--paper-100);
  --bg-raised: var(--paper-000);
  --bg-sunken: var(--paper-200);
  --text: var(--ink-700); /* Graphite, 12.17 on Porcelain */
  --text-muted: #51637a; /* 5.76 on Porcelain */
  --text-on-dark: var(--paper-100);
  --text-muted-on-dark: #a9bacb; /* 8.87 on Midnight */
  --rule: #d3dee2;
  --rule-strong: #a8b8bf;
  --rule-on-dark: rgba(169, 186, 203, 0.24);
  --link: var(--accent-700);
  --focus: var(--accent-700);
  --focus-on-dark: var(--accent-300);

  /*
     Typography — self-hosted, declared in fonts.css. No runtime request to
     any font service. The fallbacks are system faces so text is readable
     before the woff2 arrives.
  */
  --font-display:
    "Manrope Variable", system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue",
    "Liberation Sans", Arial, sans-serif;
  --font-sans:
    "Source Sans 3", system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue",
    "Liberation Sans", Arial, sans-serif;
  /* Small technical labels only — never body copy. */
  --font-mono:
    "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace;

  /*
     Fluid type scale, 320px → 1440px viewports. Target sizes:
       --step-4 (h1)   42px mobile  →  72px desktop
       --step-3 (h2)   32px mobile  →  50px desktop
       --step-2 (h3)   22px         →  30px
       --step-1 (lede) 18px         →  22px
       --step-0 (body) 16px mobile  →  18px desktop
     Deliberately short of the 100px+ agency headline.
  */
  --step--1: clamp(0.875rem, 0.845rem + 0.15vw, 0.95rem);
  /* Small-but-comfortable: footer copy, captions, callouts, legal metadata. */
  --step--0-5: clamp(0.95rem, 0.92rem + 0.15vw, 1.0625rem);
  /* Navigation links. */
  --nav-size: clamp(1rem, 0.97rem + 0.15vw, 1.0625rem);
  --step-0: clamp(1rem, 0.97rem + 0.15vw, 1.125rem);
  --step-1: clamp(1.125rem, 1.07rem + 0.28vw, 1.375rem);
  --step-2: clamp(1.375rem, 1.2rem + 0.75vw, 1.875rem);
  --step-3: clamp(2rem, 1.55rem + 2.25vw, 3.125rem);
  --step-4: clamp(2.625rem, 1.9rem + 3.6vw, 4.5rem);

  /* Spacing */
  --space-2xs: 0.375rem;
  --space-xs: 0.625rem;
  --space-s: 1rem;
  --space-m: 1.5rem;
  --space-l: 2.25rem;
  --space-xl: 3.5rem;
  /* Section rhythm: 72px mobile → 144px desktop. */
  --space-2xl: clamp(4.5rem, 3.4rem + 5.5vw, 9rem);

  /* Layout */
  --measure: 68ch;
  --container: 80rem; /* 1280px of content */
  --container-narrow: 52rem;
  --header-height: 4.25rem;
  --radius: 4px;
  --radius-lg: 8px;

  --transition: 200ms cubic-bezier(0.2, 0, 0.2, 1);
}

/* --------------------------------------------------------------------------
   2. Reset and base elements
   -------------------------------------------------------------------------- */

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

html {
  -webkit-text-size-adjust: 100%;
  scroll-padding-top: calc(var(--header-height) + var(--space-m));
}

body {
  margin: 0;
  background-color: var(--bg);
  color: var(--text);
  font-family: var(--font-sans);
  font-size: var(--step-0);
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-wrap: break-word;
}

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

img {
  height: auto;
}

ul,
ol {
  margin: 0;
  padding: 0;
}

figure {
  margin: 0;
}

:where(a) {
  color: var(--link);
  text-decoration-thickness: 1px;
  text-underline-offset: 0.2em;
}

:where(a:hover) {
  text-decoration-thickness: 2px;
}

/* Focus: visible, high contrast, never removed. */
:focus-visible {
  outline: 3px solid var(--focus);
  outline-offset: 3px;
  border-radius: 2px;
}

:is(.section--dark, .hero, .page-hero) :focus-visible,
.site-footer :focus-visible {
  outline-color: var(--focus-on-dark);
}

::selection {
  background-color: var(--accent-300);
  color: var(--ink-900);
}

/* Skip link — visible as soon as it receives focus. */
.skip-link {
  position: absolute;
  top: 0;
  left: 0;
  z-index: 100;
  padding: 0.75rem 1.25rem;
  background-color: var(--ink-800);
  color: var(--paper-000);
  font-weight: 600;
  text-decoration: none;
  transform: translateY(-120%);
  transition: transform var(--transition);
}

.skip-link:focus-visible {
  transform: translateY(0);
  outline-offset: -3px;
  outline-color: var(--accent-300);
}

/* --------------------------------------------------------------------------
   3. Typography
   -------------------------------------------------------------------------- */

/*
   Headings are Manrope. It is a geometric sans, so it wants a heavier weight
   and tighter tracking than a serif would at the same size.
*/
h1,
h2,
h3,
h4 {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 700;
  line-height: 1.12;
  letter-spacing: -0.022em;
  text-wrap: balance;
  color: var(--ink-900);
}

:is(.section--dark, .hero, .page-hero) :is(h1, h2, h3, h4) {
  color: var(--text-on-dark);
}

h1 {
  font-size: var(--step-4);
  letter-spacing: -0.03em;
}

h2 {
  font-size: var(--step-3);
  letter-spacing: -0.026em;
}

h3 {
  font-size: var(--step-1);
  line-height: 1.25;
}

h4 {
  font-size: var(--step-0);
  line-height: 1.35;
}

p {
  margin: 0;
  text-wrap: pretty;
}

.lede {
  font-size: var(--step-1);
  line-height: 1.55;
  color: var(--text-muted);
  max-width: 58ch;
}

:is(.section--dark, .hero, .page-hero) .lede {
  color: var(--text-muted-on-dark);
}

.prose {
  max-width: var(--measure);
  display: flex;
  flex-direction: column;
  gap: var(--space-m);
}

.prose h3 {
  margin-top: var(--space-s);
}

.prose ul {
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
  padding-left: 1.25rem;
  list-style: none;
}

.prose ul li {
  position: relative;
}

.prose ul li::before {
  content: "";
  position: absolute;
  left: -1.25rem;
  top: 0.68em;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background-color: var(--accent-600);
}

/* Small uppercase label used above section headings. */
.eyebrow {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  margin: 0 0 var(--space-s);
  font-family: var(--font-mono);
  font-size: var(--step--0-5);
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--accent-700);
}

.eyebrow::after {
  content: "";
  flex: 1 1 auto;
  height: 1px;
  max-width: 5rem;
  background-color: var(--rule-strong);
}

:is(.section--dark, .hero, .page-hero) .eyebrow {
  color: var(--accent-300);
}

:is(.section--dark, .hero, .page-hero) .eyebrow::after {
  background-color: var(--rule-on-dark);
}

/* --------------------------------------------------------------------------
   4. Layout primitives
   -------------------------------------------------------------------------- */

/*
   Page gutters: ~20px at 320, ~34px at 768, ~42px at 1024, capping at 64px.
   Above 1280 the container's own max-width supplies the rest of the margin.
*/
.container {
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: clamp(1.25rem, 0.6rem + 3.2vw, 4rem);
}

.container--narrow {
  max-width: var(--container-narrow);
}

.section {
  padding-block: var(--space-2xl);
  position: relative;
}

.section--tight {
  padding-block: var(--space-xl);
}

.section--dark {
  background-color: var(--ink-900);
  color: var(--text-on-dark);
}

.section--sunken {
  background-color: var(--bg-sunken);
}

.section--ruled {
  border-top: 1px solid var(--rule);
}

.section__head {
  max-width: 46rem;
  margin-bottom: var(--space-xl);
}

/* Trailing link under a section's content. */
.section__foot {
  margin-top: var(--space-xl);
}

/*
   Sections that carry a decorative background field: the field is absolutely
   positioned at z-index 0, so the content needs its own layer to sit on.
*/
.section > .container,
.page-hero__inner {
  position: relative;
  z-index: 1;
}

.section__head > * + * {
  margin-top: var(--space-s);
}

.grid {
  display: grid;
  gap: var(--space-m);
}

@media (min-width: 46em) {
  .grid--2 {
    grid-template-columns: repeat(2, 1fr);
  }
}

/*
   A two-column split for a body of prose beside a supporting aside. It holds
   a single column much longer than .grid--2, because splitting a reading
   column at tablet width leaves the text too narrow to read comfortably.
*/
@media (min-width: 64em) {
  .grid--split {
    grid-template-columns: minmax(0, 1.15fr) minmax(0, 0.85fr);
    gap: var(--space-2xl);
    align-items: start;
  }
}

@media (min-width: 58em) {
  .grid--3 {
    grid-template-columns: repeat(3, 1fr);
  }

  .grid--4 {
    grid-template-columns: repeat(4, 1fr);
  }
}

@media (min-width: 46em) and (max-width: 57.99em) {
  .grid--4 {
    grid-template-columns: repeat(2, 1fr);
  }
}

.stack {
  display: flex;
  flex-direction: column;
  gap: var(--space-m);
}

.stack--l {
  gap: var(--space-l);
}

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* --------------------------------------------------------------------------
   5. Components
   -------------------------------------------------------------------------- */

/* --- Buttons --- */

.button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.55rem;
  min-height: 3rem; /* comfortable touch target */
  padding: 0.75rem 1.5rem;
  border: 1px solid transparent;
  border-radius: var(--radius);
  font-family: var(--font-sans);
  font-size: var(--step-0);
  font-weight: 600;
  line-height: 1.2;
  text-decoration: none;
  cursor: pointer;
  transition:
    background-color var(--transition),
    border-color var(--transition),
    color var(--transition),
    transform var(--transition),
    box-shadow var(--transition);
}

.button--primary {
  background-color: var(--accent-700);
  color: var(--paper-000);
}

.button--primary:hover {
  background-color: #085a55;
}

.button--secondary {
  background-color: transparent;
  border-color: var(--rule-strong);
  color: var(--text);
}

.button--secondary:hover {
  border-color: var(--ink-700);
  background-color: rgba(11, 27, 43, 0.04);
}

/* Shared lift on hover, and a clear pressed state on activation. */
@media (prefers-reduced-motion: no-preference) {
  .button:hover {
    transform: translateY(-1px);
  }
}

.button--primary:hover {
  box-shadow: 0 4px 14px rgba(10, 110, 104, 0.28);
}

.button:active {
  transform: translateY(1px);
  box-shadow: none;
}

.button--primary:active {
  background-color: #074c48;
}

.button--secondary:active {
  background-color: rgba(11, 27, 43, 0.09);
  border-color: var(--ink-800);
}

:is(.section--dark, .hero, .page-hero) .button--primary {
  background-color: var(--accent-300);
  color: var(--ink-900);
}

:is(.section--dark, .hero, .page-hero) .button--primary:hover {
  background-color: #8ae2da;
}

:is(.section--dark, .hero, .page-hero) .button--secondary {
  border-color: rgba(169, 186, 203, 0.5);
  color: var(--paper-100);
}

:is(.section--dark, .hero, .page-hero) .button--secondary:hover {
  border-color: var(--paper-100);
  background-color: rgba(247, 244, 238, 0.08);
}

:is(.section--dark, .hero, .page-hero) .button--primary:hover {
  box-shadow: 0 4px 16px rgba(95, 211, 201, 0.24);
}

:is(.section--dark, .hero, .page-hero) .button--primary:active {
  background-color: #4bc3b9;
}

:is(.section--dark, .hero, .page-hero) .button--secondary:active {
  background-color: rgba(247, 244, 238, 0.16);
}

.button-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-s);
}

/* Text link with a trailing arrow. */
.arrow-link {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  min-height: 2.75rem;
  font-weight: 600;
  text-decoration: none;
  border-bottom: 1px solid currentColor;
  align-self: flex-start;
}

.arrow-link svg {
  flex: none;
  transition: transform var(--transition);
}

.arrow-link:hover svg {
  transform: translateX(3px);
}

:is(.section--dark, .hero, .page-hero) .arrow-link {
  color: var(--accent-300);
}

/* --- Header --- */

.site-header {
  position: sticky;
  top: 0;
  z-index: 50;
  background-color: rgba(247, 244, 238, 0.92);
  border-bottom: 1px solid transparent;
  transition:
    border-color var(--transition),
    box-shadow var(--transition),
    background-color var(--transition);
}

@supports (backdrop-filter: blur(8px)) {
  .site-header {
    backdrop-filter: blur(8px);
  }
}

.site-header[data-scrolled="true"] {
  border-bottom-color: var(--rule);
  box-shadow: 0 1px 12px rgba(7, 21, 35, 0.06);
}

.site-header__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-m);
  min-height: var(--header-height);
}

/*
   Brand: the official logo, held locally in public/brand/. The link carries
   an aria-label and the image an empty alt, so the company name is announced
   exactly once.
*/
.brand {
  display: inline-flex;
  align-items: center;
  text-decoration: none;
  padding-block: 0.45rem;
  padding-inline: 2px;
  border-radius: var(--radius);
  flex: none;
}

.brand__logo {
  transition: opacity var(--transition);
}

.brand:hover .brand__logo {
  opacity: 0.78;
}

/* The logo steps down on small screens so it never crowds the menu button. */
@media (max-width: 30em) {
  .brand__logo {
    --logo-height: 38px;
  }
}

@media (max-width: 24em) {
  .brand__logo {
    --logo-height: 32px;
  }
}

.site-nav__list {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: clamp(0.25rem, 0.6vw, 1rem);
  list-style: none;
}

.site-nav__link {
  display: inline-flex;
  align-items: center;
  min-height: 2.75rem;
  padding: 0.45rem 0.8rem;
  border-radius: var(--radius);
  color: var(--text);
  font-size: var(--nav-size);
  font-weight: 600;
  letter-spacing: 0.005em;
  text-decoration: none;
  transition:
    color var(--transition),
    background-color var(--transition);
}

.site-nav__link:hover {
  color: var(--accent-700);
  background-color: rgba(10, 110, 104, 0.07);
}

.site-nav__link[aria-current="page"] {
  color: var(--accent-700);
  box-shadow: inset 0 -2px 0 var(--accent-700);
  border-radius: 0;
}

.nav-toggle {
  display: none;
  align-items: center;
  gap: 0.55rem;
  min-height: 2.75rem;
  padding: 0.5rem 0.85rem;
  background-color: transparent;
  border: 1px solid var(--rule-strong);
  border-radius: var(--radius);
  color: var(--text);
  font-family: inherit;
  font-size: var(--step--1);
  font-weight: 600;
  cursor: pointer;
}

.nav-toggle__bars {
  display: grid;
  gap: 3px;
}

.nav-toggle__bars span {
  display: block;
  width: 16px;
  height: 2px;
  background-color: currentColor;
}

/*
   The mobile panel behaviour is only applied when JavaScript is available.
   Without JS the navigation stays in the flow and simply wraps, so every
   link remains reachable.
*/
@media (max-width: 47.99em) {
  html[data-js="true"] .nav-toggle {
    display: inline-flex;
  }

  html[data-js="true"] .site-header__inner {
    flex-wrap: wrap;
  }

  html[data-js="true"] .site-nav {
    flex-basis: 100%;
    display: none;
  }

  html[data-js="true"] .site-nav[data-open="true"] {
    display: block;
  }

  html[data-js="true"] .site-nav__list {
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    padding-block: var(--space-xs) var(--space-s);
    border-top: 1px solid var(--rule);
  }

  html[data-js="true"] .site-nav__link {
    min-height: 3rem;
    padding-inline: 0;
    font-size: var(--step-0);
  }

  html[data-js="true"] .site-nav__link[aria-current="page"] {
    box-shadow: inset 3px 0 0 var(--accent-700);
    padding-left: 0.75rem;
  }
}

/* --- Hero --- */

.hero {
  position: relative;
  background-color: var(--ink-900);
  color: var(--text-on-dark);
  overflow: hidden;
}

.hero__inner {
  position: relative;
  z-index: 2;
  display: grid;
  gap: var(--space-xl);
  padding-block: clamp(3.5rem, 2rem + 7vw, 7rem);
  align-items: center;
}

@media (min-width: 62em) {
  .hero__inner {
    grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr);
    gap: var(--space-2xl);
  }
}

.hero__title {
  max-width: 16ch;
}

.hero__lede {
  margin-top: var(--space-m);
  max-width: 46ch;
  font-size: var(--step-1);
  color: var(--text-muted-on-dark);
}

.hero__actions {
  margin-top: var(--space-l);
}

.hero__meta {
  margin-top: var(--space-xl);
  padding-top: var(--space-m);
  border-top: 1px solid var(--rule-on-dark);
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-s) var(--space-l);
  font-family: var(--font-mono);
  font-size: var(--step--0-5);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-muted-on-dark);
  list-style: none;
}

/*
   Page entry. A short, small rise applied to the hero's own children only.
   It runs once, immediately on load, and is skipped entirely for
   reduced-motion visitors — so it never stands between a visitor and the
   content. Nothing below the fold depends on it.
*/
@media (prefers-reduced-motion: no-preference) {
  .hero__enter > * {
    animation: enter-rise 440ms cubic-bezier(0.2, 0, 0.2, 1) both;
  }

  .hero__enter > *:nth-child(2) {
    animation-delay: 55ms;
  }

  .hero__enter > *:nth-child(3) {
    animation-delay: 100ms;
  }

  .hero__enter > *:nth-child(4) {
    animation-delay: 145ms;
  }

  .hero__enter > *:nth-child(5) {
    animation-delay: 190ms;
  }

  .hero__figure {
    animation: enter-fade 700ms cubic-bezier(0.2, 0, 0.2, 1) both;
    animation-delay: 120ms;
  }
}

@keyframes enter-rise {
  from {
    opacity: 0;
    transform: translateY(10px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

@keyframes enter-fade {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

/* --- Page hero (interior pages) --- */

.page-hero {
  background-color: var(--ink-900);
  color: var(--text-on-dark);
  position: relative;
  overflow: hidden;
}

.page-hero__inner {
  position: relative;
  z-index: 2;
  padding-block: clamp(3rem, 2rem + 5vw, 5.5rem);
  max-width: 46rem;
}

.page-hero__lede {
  margin-top: var(--space-m);
  font-size: var(--step-1);
  color: var(--text-muted-on-dark);
  max-width: 52ch;
}

.page-hero__pattern {
  position: absolute;
  inset: 0;
  z-index: 1;
  opacity: 0.5;
  pointer-events: none;
}

/* --- Cards --- */

.card {
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
  padding: var(--space-m);
  background-color: var(--bg-raised);
  border: 1px solid var(--rule);
  border-radius: var(--radius-lg);
}

.card--flush {
  background-color: transparent;
  border: 0;
  border-top: 2px solid var(--ink-800);
  border-radius: 0;
  padding: var(--space-m) 0 0;
}

:is(.section--dark, .hero, .page-hero) .card {
  background-color: rgba(247, 244, 238, 0.04);
  border-color: var(--rule-on-dark);
}

:is(.section--dark, .hero, .page-hero) .card--flush {
  background-color: transparent;
  border-top-color: var(--accent-300);
}

/*
   Card that is itself a link (the capability summaries on the homepage).
   Hover and keyboard focus share the same treatment, so a keyboard user gets
   exactly the affordance a mouse user gets.
*/
.card-link {
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
  text-decoration: none;
  color: inherit;
  transition:
    border-color var(--transition),
    box-shadow var(--transition),
    transform var(--transition),
    background-color var(--transition);
}

.card-link:hover,
.card-link:focus-visible {
  border-color: var(--accent-600);
  box-shadow: 0 6px 22px rgba(7, 21, 35, 0.09);
  background-color: var(--paper-000);
}

.card-link:focus-visible {
  outline: 3px solid var(--focus);
  outline-offset: 3px;
}

.card-link:active {
  box-shadow: 0 2px 8px rgba(7, 21, 35, 0.1);
}

@media (prefers-reduced-motion: no-preference) {
  .card-link:hover,
  .card-link:focus-visible {
    transform: translateY(-3px);
  }

  .card-link:active {
    transform: translateY(0);
  }
}

/* The arrow cue inside a linked card. */
.card-link__cue {
  margin-top: auto;
  padding-top: var(--space-s);
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  font-size: var(--step--0-5);
  font-weight: 600;
  color: var(--accent-700);
}

.card-link__cue svg {
  transition: transform var(--transition);
}

.card-link:hover .card-link__cue svg,
.card-link:focus-visible .card-link__cue svg {
  transform: translateX(4px);
}

.card__number {
  font-family: var(--font-mono);
  font-size: var(--step--0-5);
  letter-spacing: 0.12em;
  color: var(--accent-700);
}

:is(.section--dark, .hero, .page-hero) .card__number {
  color: var(--accent-300);
}

.card__body {
  color: var(--text-muted);
}

:is(.section--dark, .hero, .page-hero) .card__body {
  color: var(--text-muted-on-dark);
}

/* --- Scientific position: three pillars with deliberate weighting --- */

/*
   RNA and oligonucleotide research is the primary focus, so it gets a full
   row and larger type. The other two share the row beneath. The weighting is
   visual only — each pillar's own text still states its standing in words
   ("Primary focus", "Research area", "Supporting research"), so the hierarchy
   is never carried by size or colour alone.
*/
.pillars {
  display: grid;
  gap: var(--space-m);
}

@media (min-width: 52em) {
  .pillars {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--space-l) var(--space-m);
  }

  .pillar--primary {
    grid-column: 1 / -1;
  }
}

.pillar__head {
  display: flex;
  align-items: baseline;
  gap: var(--space-s);
  flex-wrap: wrap;
}

.pillar__rank {
  font-family: var(--font-mono);
  font-size: var(--step--1);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--text-muted);
}

:is(.section--dark, .hero, .page-hero) .pillar__rank {
  color: var(--text-muted-on-dark);
}

.pillar__title {
  font-size: var(--step-2);
}

.pillar--primary {
  border-top-width: 3px;
  border-top-color: var(--teal);
}

.pillar--primary .pillar__title {
  font-size: var(--step-3);
}

.pillar--primary .pillar__statement {
  font-size: var(--step-1);
  max-width: 54ch;
}

@media (min-width: 52em) {
  .pillar--primary {
    padding-bottom: var(--space-s);
  }

  /* The primary pillar reads as a wide feature, not a tall column. */
  .pillar--primary .pillar__detail {
    max-width: 62ch;
  }
}

/* Pillar card */

/*
   The three pillars read as one set: each sits under a muted rule, and on
   hover or keyboard focus an accent rule grows across it from the left. The
   effect is the transition between the three — no carousel, no tabs, and
   nothing that hides a pillar until it is interacted with.
*/
.pillar {
  display: flex;
  flex-direction: column;
  gap: var(--space-s);
  height: 100%;
  position: relative;
  padding-top: var(--space-m);
  border-top: 2px solid var(--rule-strong);
  transition:
    transform var(--transition),
    border-color var(--transition);
}

:is(.section--dark, .hero, .page-hero) .pillar {
  border-top-color: var(--rule-on-dark);
}

/* Each pillar's own accent rule, revealed from the left. */
.pillar::before {
  content: "";
  position: absolute;
  top: -2px;
  left: 0;
  height: 2px;
  width: 0;
  background-color: var(--accent-600);
  transition: width 420ms cubic-bezier(0.2, 0, 0.2, 1);
}

.pillar:hover::before,
.pillar:focus-within::before {
  width: 100%;
}

@media (prefers-reduced-motion: no-preference) {
  .pillar:hover,
  .pillar:focus-within {
    transform: translateY(-2px);
  }
}

@media (prefers-reduced-motion: reduce) {
  /* Keep the affordance, drop the movement. */
  .pillar::before {
    transition: none;
  }
}

.pillar__statement {
  font-family: var(--font-display);
  font-size: var(--step-1);
  line-height: 1.4;
}

.pillar__detail {
  color: var(--text-muted);
}

:is(.section--dark, .hero, .page-hero) .pillar__detail {
  color: var(--text-muted-on-dark);
}

:is(.section--dark, .hero, .page-hero) .pillar::before {
  background-color: var(--accent-300);
}

/* --- CNS section: Midnight ground, Neural Violet used sparingly --- */

/*
   Violet appears only inside this section, and only on rules, markers and the
   figure. Body text stays on the standard on-dark colours, because Neural
   Violet fails AA for small text on Midnight (3.90).
*/
.section--cns {
  background-color: var(--ink-900);
  border-top: 1px solid var(--rule-on-dark);
}

.section--cns .eyebrow {
  color: var(--violet-on-dark);
}

.section--cns .eyebrow::after {
  background-color: rgba(139, 131, 228, 0.35);
}

.section--cns .marker-list li::before {
  background-color: var(--violet-on-dark);
}

.section--cns .figure-frame {
  border-color: rgba(139, 131, 228, 0.28);
}

/* --- Microbial section: Porcelain ground, Microbial Amber used sparingly --- */

.section--microbial .eyebrow {
  color: var(--amber-ink);
}

.section--microbial .eyebrow::after {
  background-color: rgba(213, 163, 72, 0.55);
}

.focus-item {
  border-top: 2px solid rgba(213, 163, 72, 0.5);
  padding-top: var(--space-s);
}

.focus-item__title {
  font-size: var(--step-0);
  font-weight: 700;
  margin-bottom: 0.3rem;
}

/* A simple marked list, used where prose bullets would be too heavy. */
.marker-list {
  list-style: none;
  display: grid;
  gap: var(--space-xs);
  margin-top: var(--space-xs);
}

.marker-list li {
  position: relative;
  padding-left: 1.4rem;
  color: var(--text-muted);
}

.marker-list li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.62em;
  width: 8px;
  height: 2px;
  border-radius: 1px;
  background-color: var(--teal);
}

:is(.section--dark, .hero, .page-hero) .marker-list li {
  color: var(--text-muted-on-dark);
}

/* --- Closing action band --- */

.closing {
  display: grid;
  gap: var(--space-l);
  align-items: end;
}

@media (min-width: 58em) {
  .closing {
    grid-template-columns: minmax(0, 1.1fr) auto;
  }
}

.closing__heading {
  max-width: 26ch;
}

/* Capability list item */

.capability {
  display: grid;
  gap: var(--space-s);
  padding-block: var(--space-l);
  border-top: 1px solid var(--rule);
}

@media (min-width: 52em) {
  .capability {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.35fr);
    gap: var(--space-l);
  }
}

.capability__title {
  font-size: var(--step-2);
}

.capability__points {
  list-style: none;
  display: grid;
  gap: var(--space-xs);
  margin-top: var(--space-s);
}

.capability__points li {
  position: relative;
  padding-left: 1.4rem;
  color: var(--text-muted);
}

.capability__points li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.62em;
  width: 8px;
  height: 1px;
  background-color: var(--accent-600);
}

/* Principles */

.principle {
  display: flex;
  flex-direction: column;
  gap: var(--space-2xs);
  padding-left: var(--space-m);
  border-left: 2px solid var(--accent-600);
}

:is(.section--dark, .hero, .page-hero) .principle {
  border-left-color: var(--accent-300);
}

/* Key-value list (contact, company facts) */

.facts {
  list-style: none;
  display: grid;
  gap: var(--space-m);
}

.facts__key {
  font-family: var(--font-mono);
  font-size: var(--step--0-5);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--text-muted);
  margin-bottom: 0.2rem;
}

:is(.section--dark, .hero, .page-hero) .facts__key {
  color: var(--text-muted-on-dark);
}

.facts__value {
  font-size: var(--step-1);
  font-family: var(--font-display);
  line-height: 1.4;
}

.facts__value a {
  color: inherit;
  text-decoration-color: var(--accent-600);
}

:is(.section--dark, .hero, .page-hero) .facts__value a {
  text-decoration-color: var(--accent-300);
}

/* Callout */

.callout {
  padding: var(--space-m);
  background-color: var(--bg-sunken);
  border-left: 3px solid var(--accent-600);
  border-radius: 0 var(--radius) var(--radius) 0;
  color: var(--text-muted);
  font-size: var(--step--0-5);
  line-height: 1.6;
}

:is(.section--dark, .hero, .page-hero) .callout {
  background-color: rgba(247, 244, 238, 0.05);
  border-left-color: var(--accent-300);
  color: var(--text-muted-on-dark);
}

/* CTA band */

.cta {
  display: grid;
  gap: var(--space-l);
  align-items: end;
}

@media (min-width: 52em) {
  .cta {
    grid-template-columns: minmax(0, 1.2fr) auto;
  }
}

/* --- Footer --- */

.site-footer {
  background-color: var(--ink-900);
  color: var(--text-on-dark);
  padding-block: var(--space-xl) var(--space-l);
  border-top: 1px solid var(--rule-on-dark);
}

.site-footer a {
  color: var(--paper-100);
  text-decoration-color: rgba(169, 186, 203, 0.5);
}

.site-footer a:hover {
  color: var(--accent-300);
  text-decoration-color: currentColor;
}

.site-footer__top {
  display: grid;
  gap: var(--space-xl);
}

@media (min-width: 52em) {
  .site-footer__top {
    grid-template-columns: minmax(0, 1.3fr) repeat(2, minmax(0, 1fr));
  }
}

.site-footer__heading {
  font-family: var(--font-mono);
  font-size: var(--step--0-5);
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text-muted-on-dark);
  margin-bottom: var(--space-s);
}

.site-footer__list {
  list-style: none;
  display: grid;
  gap: 0.35rem;
}

.site-footer__heading--spaced {
  margin-top: var(--space-l);
}

.site-footer__list a {
  display: inline-flex;
  align-items: center;
  min-height: 2.5rem;
  font-size: var(--step-0);
}

.site-footer__brand {
  display: inline-block;
  padding: 2px;
  border-radius: var(--radius);
  margin-bottom: var(--space-m);
}

.site-footer__brand .logo {
  transition: opacity var(--transition);
}

.site-footer__brand:hover .logo {
  opacity: 0.8;
}

.site-footer__blurb {
  color: var(--text-muted-on-dark);
  max-width: 42ch;
  font-size: var(--step--0-5);
  line-height: 1.6;
}

.site-footer__address {
  color: var(--text-muted-on-dark);
  max-width: 42ch;
  font-size: var(--step--0-5);
  line-height: 1.6;
  font-style: normal;
  margin-top: var(--space-s);
}

.site-footer__bottom {
  margin-top: var(--space-xl);
  padding-top: var(--space-m);
  border-top: 1px solid var(--rule-on-dark);
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-s) var(--space-l);
  justify-content: space-between;
  align-items: baseline;
  color: var(--text-muted-on-dark);
  font-size: var(--step--0-5);
}

.site-footer__legal {
  display: flex;
  flex-wrap: wrap;
  gap: 0 var(--space-m);
  list-style: none;
}

/*
   These are standalone links, not links inside a sentence, so they get a
   comfortable hit area rather than the bare height of their text.
*/
.site-footer__legal a {
  display: inline-flex;
  align-items: center;
  min-height: 2.75rem;
}

/* Same reasoning for the key/value contact links. */
.facts__value a {
  display: inline-flex;
  align-items: center;
  min-height: 2.5rem;
}

.site-footer__note {
  margin-top: var(--space-m);
  color: var(--text-muted-on-dark);
  font-size: var(--step--0-5);
  max-width: 80ch;
  line-height: 1.6;
}

/* --- 404 --- */

.notfound {
  display: grid;
  place-items: center;
  min-height: 60vh;
  text-align: center;
}

.notfound__code {
  font-family: var(--font-mono);
  font-size: var(--step--0-5);
  letter-spacing: 0.24em;
  color: var(--accent-700);
  margin-bottom: var(--space-s);
}

/* --- Legal document pages --- */

.legal-body {
  max-width: var(--measure);
}

.legal-body h2 {
  font-size: var(--step-2);
  margin-top: var(--space-xl);
  margin-bottom: var(--space-s);
}

.legal-body h2:first-child {
  margin-top: 0;
}

.legal-body p + p {
  margin-top: var(--space-s);
}

.legal-body ul {
  list-style: none;
  display: grid;
  gap: var(--space-xs);
  margin-top: var(--space-s);
  padding-left: 1.25rem;
}

.legal-body ul li {
  position: relative;
}

.legal-body ul li::before {
  content: "";
  position: absolute;
  left: -1.25rem;
  top: 0.68em;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background-color: var(--accent-600);
}

.legal-meta {
  font-family: var(--font-mono);
  font-size: var(--step--0-5);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-muted);
}

/* --- Abstract visuals --- */

.figure-frame {
  position: relative;
  border: 1px solid var(--rule-on-dark);
  border-radius: var(--radius-lg);
  background-color: rgba(247, 244, 238, 0.03);
  padding: clamp(1rem, 0.5rem + 2vw, 1.75rem);
}

/*
   Figure captions are real sentences, so they are set in the body face. IBM
   Plex Mono is reserved for short technical labels — a multi-line caption in
   uppercase mono is markedly harder to read.
*/
.figure-frame__caption {
  margin-top: var(--space-s);
  font-family: var(--font-sans);
  font-size: var(--step--0-5);
  line-height: 1.5;
  color: var(--text-muted-on-dark);
  max-width: 44ch;
}

.section--microbial .figure-frame__caption,
.section:not(.section--dark) .figure-frame__caption {
  color: var(--text-muted);
}

/* --------------------------------------------------------------------------
   6. Motion and reveal

   Accessibility contract for every animation on this site:

     * Content is visible by default. No rule here ever sets opacity or
       visibility on a block of text as its resting state.
     * The scroll reveal is played by JavaScript with the Web Animations API,
       and only on elements still below the viewport — so nothing a visitor is
       reading can fade. If the script never runs, or throws, the page is
       simply already in its final state.
     * Animations are short (under ~700ms) and change only `transform` and
       `opacity`, so the compositor handles them and layout never shifts.
     * `prefers-reduced-motion: reduce` removes all non-essential motion.
   -------------------------------------------------------------------------- */

@media (prefers-reduced-motion: no-preference) {
  html {
    scroll-behavior: smooth;
  }
}

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

/* --------------------------------------------------------------------------
   7. Print
   -------------------------------------------------------------------------- */

@media print {
  .site-header,
  .skip-link,
  .hero-visual,
  .page-hero__pattern {
    display: none !important;
  }

  body {
    background: #fff;
    color: #000;
  }

  .hero,
  .page-hero,
  .section--dark,
  .site-footer {
    background: #fff !important;
    color: #000 !important;
  }
}

/* ===== Component: LatticePattern ===== */
.lattice {
  width: 100%;
  height: 100%;
}

/* ===== Component: Logo ===== */
/*
     The width/height attributes give the browser the 2:1 aspect ratio up
     front, so the space is reserved and nothing shifts when the file loads.
     Height is driven by the component prop; width follows the ratio.
  */
.logo {
  display: block;
  height: var(--logo-height);
  width: auto;
  max-width: 100%;
}

/* ===== Component: HeroVisual ===== */
.hero-visual {
  position: relative;
}

.hero-visual svg {
  width: 100%;
  height: auto;
  overflow: visible;
}

.hv-label {
  font-family: var(--font-mono);
  font-size: 9px;
  letter-spacing: 0.16em;
  fill: var(--cyan);
  fill-opacity: 0.75;
}

.hv-strand {
  fill: none;
  stroke-linecap: round;
  stroke-width: 1.8;
}

.hv-strand--upper {
  stroke: var(--cyan);
  stroke-opacity: 0.95;
}

.hv-strand--lower {
  stroke: var(--teal);
  stroke-opacity: 0.85;
}

.hv-rung {
  stroke: var(--cyan);
  stroke-width: 1.4;
  stroke-opacity: 0.55;
}

.hv-node {
  fill: var(--cyan);
}

.hv-tick {
  fill: var(--text-muted-on-dark);
  opacity: 0.3;
}

.hv-tick--region {
  fill: var(--cyan);
  opacity: 0.55;
}

/*
     Reduced motion is the DEFAULT state above: strands in register, rungs and
     zone visible. The animation below only adds the approach and release, so a
     reduced-motion visitor sees the finished diagram and loses no information.
  */
@media (prefers-reduced-motion: no-preference) {
  /* 16s loop: approach, pair, hold, release. */
  .hv-lower {
    animation: hv-approach 16s ease-in-out infinite;
  }

  .hv-rung {
    animation: hv-pair 16s ease-in-out infinite;
    animation-delay: var(--d, 0s);
  }

  .hv-zone {
    animation: hv-zone 16s ease-in-out infinite;
  }

  .hv-node {
    animation: hv-node 16s ease-in-out infinite;
  }

  .hv-tick--region {
    animation: hv-tick 16s ease-in-out infinite;
  }
}

/* The lower strand drifts down and back up, settling in register. */
@keyframes hv-approach {
  0% {
    transform: translateY(14px);
  }
  28%,
  72% {
    transform: translateY(0);
  }
  100% {
    transform: translateY(14px);
  }
}

@keyframes hv-pair {
  0%,
  18% {
    opacity: 0;
  }
  32%,
  68% {
    opacity: 0.55;
  }
  88%,
  100% {
    opacity: 0;
  }
}

@keyframes hv-zone {
  0%,
  14% {
    opacity: 0.35;
  }
  34%,
  66% {
    opacity: 1;
  }
  92%,
  100% {
    opacity: 0.35;
  }
}

@keyframes hv-node {
  0%,
  22% {
    opacity: 0.2;
  }
  38%,
  64% {
    opacity: 1;
  }
  86%,
  100% {
    opacity: 0.2;
  }
}

@keyframes hv-tick {
  0%,
  20% {
    opacity: 0.2;
  }
  38%,
  66% {
    opacity: 0.7;
  }
  88%,
  100% {
    opacity: 0.2;
  }
}

/* ===== Component: NeuralVisual ===== */
.neural {
  position: relative;
}

.neural svg {
  width: 100%;
  height: auto;
  overflow: visible;
}

.neural__links path {
  fill: none;
  stroke: var(--violet-on-dark);
  stroke-opacity: 0.5;
  stroke-width: 1.6;
  stroke-linecap: round;
}

.neural__branches path {
  fill: none;
  stroke: var(--violet-on-dark);
  stroke-opacity: 0.34;
  stroke-width: 1.1;
  stroke-linecap: round;
}

.neural__terminals circle {
  fill: var(--violet-on-dark);
  opacity: 0.5;
}

.neural__soma {
  fill: var(--violet-on-dark);
}

.neural__halo {
  fill: none;
  stroke: var(--violet-on-dark);
  stroke-opacity: 0.28;
  stroke-width: 1;
}

/*
     Motion: a slow, low-contrast pulse travelling between nodes. Nothing
     flashes, nothing rotates. Removed under reduced motion, which leaves the
     network fully drawn.
  */
@media (prefers-reduced-motion: no-preference) {
  .neural__halo {
    animation: neural-halo 9s ease-in-out infinite;
    animation-delay: var(--d, 0s);
    transform-box: fill-box;
    transform-origin: center;
  }

  .neural__terminals circle {
    animation: neural-dot 7s ease-in-out infinite;
    animation-delay: var(--d, 0s);
  }
}

@keyframes neural-halo {
  0%,
  100% {
    transform: scale(0.86);
    stroke-opacity: 0.14;
  }
  50% {
    transform: scale(1.1);
    stroke-opacity: 0.4;
  }
}

@keyframes neural-dot {
  0%,
  100% {
    opacity: 0.28;
  }
  50% {
    opacity: 0.72;
  }
}

/* ===== Component: MicrobialVisual ===== */
.microbial {
  position: relative;
}

.microbial svg {
  width: 100%;
  height: auto;
  max-width: 420px;
  margin-inline: auto;
}

.mb-field {
  fill: none;
  stroke: var(--amber);
  stroke-opacity: 0.32;
  stroke-width: 1.2;
}

.mb-field--inner {
  stroke-opacity: 0.16;
  stroke-dasharray: 2 6;
}

.mb-graticule line {
  stroke: var(--amber);
  stroke-opacity: 0.3;
  stroke-width: 1;
}

.mb-cross {
  stroke: var(--amber);
  stroke-opacity: 0.12;
  stroke-width: 1;
}

.mb-rod,
.mb-coccus {
  fill: var(--amber);
}

.mb-scale line {
  stroke: var(--amber);
  stroke-opacity: 0.5;
  stroke-width: 1.2;
}

/*
     Motion: a very slow drift, as if the sample were settling under the lens.
     No rotation of the whole field, nothing flashing. Removed under reduced
     motion, leaving the full field visible.
  */
@media (prefers-reduced-motion: no-preference) {
  .mb-rod,
  .mb-coccus {
    animation: mb-settle 13s ease-in-out infinite alternate;
    animation-delay: var(--d, 0s);
    transform-box: fill-box;
    transform-origin: center;
  }
}

@keyframes mb-settle {
  from {
    transform: translate3d(0, 0, 0);
  }
  to {
    transform: translate3d(2.5px, -3px, 0);
  }
}

/* ===== Component: SequenceField ===== */
.seq-field {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  overflow: hidden;
  /* Fade the field out towards the text side so copy always stays legible. */
  mask-image: linear-gradient(to bottom, transparent, #000 35%, #000 65%, transparent);
  -webkit-mask-image: linear-gradient(to bottom, transparent, #000 35%, #000 65%, transparent);
}

.seq-field svg {
  width: 100%;
  height: 100%;
}

@media (prefers-reduced-motion: no-preference) {
  .seq-field__drift {
    animation: seq-drift 60s linear infinite alternate;
  }
}

@keyframes seq-drift {
  from {
    transform: translate3d(0, 0, 0);
  }
  to {
    transform: translate3d(-24px, -14px, 0);
  }
}

/* ===== Component: WorkflowSteps ===== */
.workflow {
  list-style: none;
  display: grid;
  gap: var(--space-m);
  counter-reset: none;
}

.workflow__step {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: var(--space-s);
  position: relative;
}

/* --- Vertical sequence: the mobile and tablet default --- */

.workflow__marker {
  position: relative;
  width: 1.5rem;
  display: flex;
  justify-content: center;
}

.workflow__dot {
  width: 11px;
  height: 11px;
  border-radius: 50%;
  background-color: var(--teal);
  margin-top: 0.45rem;
  flex: none;
  position: relative;
  z-index: 1;
}

/* The connector: a line down the marker column, stopping at the last step. */
.workflow__step:not(:last-child) .workflow__marker::after {
  content: "";
  position: absolute;
  top: 1.1rem;
  bottom: calc(-1 * var(--space-m) - 0.6rem);
  left: 50%;
  width: 2px;
  transform: translateX(-50%);
  background-color: var(--rule);
}

.workflow__content {
  padding-bottom: var(--space-xs);
}

.workflow__number {
  font-family: var(--font-mono);
  font-size: var(--step--1);
  letter-spacing: 0.14em;
  color: var(--accent-700);
  margin-bottom: 0.2rem;
}

.workflow__title {
  font-size: var(--step-1);
  line-height: 1.25;
}

.workflow__body {
  margin-top: 0.4rem;
  color: var(--text-muted);
  max-width: 46ch;
}

/* --- Two rows of three from tablet width --- */

@media (min-width: 46em) and (max-width: 74.99em) {
  .workflow {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: var(--space-l) var(--space-m);
  }

  /* A vertical connector would run into the next row, so the numbered steps
       carry the order on their own here. */
  .workflow__step:not(:last-child) .workflow__marker::after {
    display: none;
  }

  .workflow__body {
    font-size: var(--step--0-5);
  }
}

/* --- One row of six only when each step has room to be read --- */

@media (min-width: 75em) {
  .workflow {
    grid-template-columns: repeat(6, minmax(0, 1fr));
    gap: var(--space-m) var(--space-s);
  }

  .workflow__step {
    grid-template-columns: minmax(0, 1fr);
    gap: var(--space-s);
    /*
         Each step is a grid item stretched to the tallest step's height. Left
         to `stretch`, the two internal rows absorb that extra space unevenly
         and the step numbers stop lining up across the row.
      */
    align-content: start;
  }

  .workflow__marker {
    width: 100%;
    justify-content: flex-start;
    padding-top: 0.35rem;
  }

  .workflow__dot {
    margin-top: 0;
  }

  /* Connector now runs horizontally, from this dot to the next. */
  .workflow__step:not(:last-child) .workflow__marker::after {
    top: 5px;
    bottom: auto;
    left: 11px;
    right: calc(-1 * var(--space-s));
    width: auto;
    height: 2px;
    transform: none;
  }

  .workflow__content {
    padding-bottom: 0;
  }

  .workflow__title {
    font-size: var(--step-0);
    font-weight: 700;
  }

  .workflow__body {
    font-size: var(--step--0-5);
    max-width: none;
  }
}

/* On dark sections the connector and dot invert. */
.section--dark .workflow__dot {
  background-color: var(--cyan);
}

.section--dark .workflow__step:not(:last-child) .workflow__marker::after {
  background-color: var(--rule-on-dark);
}

.section--dark .workflow__number {
  color: var(--cyan);
}

.section--dark .workflow__body {
  color: var(--text-muted-on-dark);
}
