/* ============================================================
   LurexBio — site stylesheet
   Single source of truth for all 8 pages. A token change here is
   one edit, not eight.

   Load order in <head>:
     1. Google Fonts preconnect + Montserrat variable axis
     2. this file
     3. page-specific <style> block, if any
   ============================================================ */

/* ============================================================
   TOKENS — every hex from handoff §4. Nothing invented.
   Retired from this page: #6B4FE0 #02086A #20325C #2E3192
   ============================================================ */
:root{
  --teal:#2A9689;
  --teal-glow:#3FF3D9;
  --violet-glow:#9B7FFF;      /* figure only — encodes "immune cell" */
  --navy-black:#050914;
  --light-grey:#E4E3E3;
  --cool-grey:#B9B9B9;

  --surface-light:#FFFFFF;
  --surface-dark:var(--navy-black);
  --text-on-light:var(--navy-black);
  --text-muted-on-light:rgba(5,9,20,.70);   /* 7.7:1 on white */
  --text-on-dark:#FFFFFF;
  --text-muted-on-dark:var(--cool-grey);    /* 10.1:1 on navy  */
  --rule:var(--light-grey);
  --rule-on-dark:rgba(255,255,255,.16);

  --font-display:"Montserrat",system-ui,-apple-system,"Segoe UI",sans-serif;
  --font-body:Arial,Helvetica,sans-serif;

  --step--1:.875rem; --step-0:1rem; --step-1:1.125rem;
  --step-2:clamp(1.375rem,2.2vw,1.75rem);
  --step-3:clamp(1.75rem,3.2vw,2.5rem);
  --step-4:clamp(2.25rem,5vw,3.75rem);
  --step-5:clamp(2rem,4vw,2.625rem);   /* display stat numerals */
  --step-hero:clamp(2.5rem,5.2vw,4rem);/* h1 only, one step above --step-4 */

  --space-0:4px;  --space-1:8px; --space-2:16px; --space-3:24px; --space-4:32px;
  --space-5:48px; --space-6:64px; --space-7:96px; --space-8:128px;

  --section-y:clamp(48px,8vw,96px);
  --wrap:1200px; --wrap-pad:32px;
  --radius:14px;
  --radius-btn:8px;
  /* figures break the text grid; prose doesn't. Formula can never exceed the
     actual side space, so no horizontal overflow at any width. */
  --fig-bleed:clamp(0px, calc((100vw - 1136px) / 2 - 24px), 64px);
  --nav-h:72px;
  /* nav is chrome, not content: it aligns to the viewport, not the 1200px wrap */
  --nav-pad:clamp(var(--space-4),4vw,var(--space-6));
  --measure:64ch;
}

/* ---------- base ---------- */
*,*::before,*::after{box-sizing:border-box;}
html{-webkit-text-size-adjust:100%; scroll-behavior:smooth;}
body{
  margin:0; background:var(--surface-light); color:var(--text-on-light);
  font-family:var(--font-body); font-size:var(--step-0); line-height:1.6;
}
h1,h2,h3,h4,.eyebrow,.btn,label,th,nav a{font-family:var(--font-display);}
h1,h2,h3{margin:0; line-height:1.15; letter-spacing:-.015em; text-wrap:balance;}
h1{font-size:var(--step-4); font-weight:800;}
h2{font-size:var(--step-3); font-weight:800;}
h3{font-size:var(--step-2); font-weight:700;}
p{margin:0; max-width:var(--measure);}
a{color:inherit; text-decoration:none;}
::selection{background:var(--teal-glow); color:var(--navy-black);}
:focus-visible{outline:2px solid var(--teal); outline-offset:3px;}
.section--dark :focus-visible,.nav :focus-visible{outline-color:var(--teal-glow);}

/* ---------- rhythm: vertical padding lives HERE and nowhere else ---------- */
.section{padding-block:var(--section-y);}
.section--dark{background:var(--surface-dark); color:var(--text-on-dark);}
/* full-bleed page division. Content-level hairlines stay at wrap width; this one
   runs edge to edge so the two never read as the same kind of rule. */
.section--ruled{border-block-start:1px solid var(--rule);}
.wrap{max-width:var(--wrap); margin-inline:auto; padding-inline:var(--wrap-pad);}
/* site chrome aligns to the viewport, not to the text column */
.wrap--full{max-width:none; padding-inline:var(--nav-pad);}
.section > .wrap > * + *{margin-block-start:var(--space-6);}

.eyebrow{
  display:block; margin:0 0 var(--space-3);
  font-size:var(--step--1); font-weight:700; letter-spacing:.14em;
  text-transform:uppercase; color:var(--teal);
}
.section--dark .eyebrow{color:var(--teal-glow);}
.lead{font-size:var(--step-1); line-height:1.55; color:var(--text-muted-on-light);}
/* deck sits under the headline at a matched measure, both sharing a left edge */
.deck{margin-block-start:var(--space-3); max-width:60ch;
  font-size:var(--step-1); line-height:1.55; color:var(--text-muted-on-light);}
.section--dark .deck{color:var(--text-muted-on-dark);}

/* ---------- dark-surface overrides ----------
   Any component hardcoding a light-surface colour goes blind on navy. .deck
   shipped without one and rendered near-black on navy. Declared as a set so the
   next dark section can't reintroduce it. */
.section--dark .caption,
.section--dark .row__body,
.section--dark .strip__body,
.section--dark .band__label,
.section--dark .band__source{color:var(--text-muted-on-dark);}
.section--dark .arrow-link{color:var(--text-on-dark);}
.section--dark .rows,
.section--dark .row,
.section--dark .strip,
.section--dark .strip__item + .strip__item,
.section--dark .statement{border-color:var(--rule-on-dark);}
.section--dark .row__label,
.section--dark .strip__label,
.section--dark .statement strong{color:var(--teal-glow);}
.section--dark .rows--numbered::before{background:var(--rule-on-dark);}
.section--dark .lead{color:var(--text-muted-on-dark);}

/* ---------- buttons ---------- */
.btn{
  display:inline-flex; align-items:center; justify-content:center;
  min-height:44px; padding-inline:var(--space-3);
  border:1px solid transparent; border-radius:var(--radius-btn);
  font-family:var(--font-display); font-size:var(--step-0); font-weight:700;
  cursor:pointer;
  transition:background-color 180ms ease,color 180ms ease,border-color 180ms ease;
}
/* teal-glow fill is 1.4:1 against white, so it only works on dark */
.btn--primary{background:var(--teal-glow); color:var(--navy-black);}
.btn--primary:hover{background:var(--surface-light);}
.btn--secondary{background:transparent; color:var(--text-on-dark); border-color:var(--rule-on-dark);}
.btn--secondary:hover{border-color:var(--teal-glow); color:var(--teal-glow);}
.btn--on-light{background:var(--navy-black); color:var(--surface-light);}
.btn--on-light:hover{background:var(--teal); color:var(--navy-black);}  /* 5.51:1 */

/* ---------- nav ---------- */
.nav{position:fixed; inset:0 0 auto; z-index:100; background:var(--navy-black);
  border-bottom:1px solid var(--rule-on-dark); color:var(--text-on-dark);}
.nav .wrap{display:flex; align-items:center; justify-content:space-between;
  height:var(--nav-h); gap:var(--space-4);}
.nav__logo{display:inline-flex; align-items:center; gap:10px;
  font-family:var(--font-display); font-weight:800; font-size:var(--step-1); letter-spacing:-.01em;}
.mark{width:28px; height:28px; flex:0 0 auto;}
/* Helix artwork from assets/favicon.svg with its background rect removed and
   the #3FF3D9→#6B4FE0 gradient flattened to approved tokens. */
.mark .s-strand{stroke:var(--teal-glow); stroke-width:5.2;}
.mark .s-back{stroke:var(--teal-glow); stroke-width:5.2; opacity:.5;}
.mark .s-r1{stroke:var(--teal-glow);}
.mark .s-r2{stroke:var(--cool-grey);}
.mark .s-r3{stroke:var(--teal);}
.mark line{stroke-width:3;}
.nav__logo em{font-style:normal; color:var(--teal-glow);}
.nav__links{display:flex; gap:var(--space-4); list-style:none; margin:0; padding:0; font-size:var(--step--1); font-weight:600;}
.nav__links a{color:var(--cool-grey); transition:color 180ms ease;}
.nav__links a:hover{color:var(--teal-glow);}
.nav__cta{min-height:36px; padding-inline:var(--space-2); font-size:var(--step--1);}
.nav__burger{display:none; min-width:44px; min-height:44px; align-items:center; justify-content:center;
  background:none; border:1px solid var(--rule-on-dark); border-radius:var(--radius-btn);
  color:var(--text-on-dark); cursor:pointer;}
.nav__burger svg{width:18px; height:18px;}
@media (max-width:880px){
  .nav__burger{display:inline-flex;}
  .nav__cta{display:none;}
  .nav__links{position:absolute; inset:var(--nav-h) 0 auto; flex-direction:column; gap:0;
    background:var(--navy-black); border-bottom:1px solid var(--rule-on-dark);
    padding:var(--space-2) var(--nav-pad) var(--space-4);}
  .nav__links[hidden]{display:none;}
  .nav__links a{display:block; padding-block:var(--space-2); font-size:var(--step-0);}
}

/* ---------- hero ---------- */
.hero{
  display:flex; flex-direction:column; justify-content:center;
  min-height:100vh;    /* fallback */
  min-height:100svh;   /* svh, not vh — avoids the mobile URL-bar jump */
  padding-block:calc(var(--nav-h) + var(--space-7)) var(--space-7);
}
.hero h1{font-size:var(--step-hero);}
/* figure column slightly wider: the diagram is an SVG, so column width is its size */
.hero__grid{display:grid; grid-template-columns:1fr 1.12fr; gap:var(--space-6); align-items:center;}
.hero h1 .accent{color:var(--teal-glow);}
.hero .lead{margin-block-start:var(--space-3);}
.hero__cta{display:flex; gap:var(--space-2); flex-wrap:wrap; margin-block-start:var(--space-5);}
@media (max-width:900px){.hero__grid{grid-template-columns:1fr; gap:var(--space-6);}}

/* ---------- figure ---------- */
.figure{margin:0; padding:var(--space-4); border:1px solid var(--rule-on-dark); border-radius:var(--radius);}
.figure__head{display:flex; align-items:baseline; justify-content:space-between; gap:var(--space-3);
  flex-wrap:wrap; padding-block-end:var(--space-3); border-bottom:1px solid var(--rule-on-dark);}
.figure__title{margin:0; font-family:var(--font-display); font-size:var(--step-0); font-weight:600;}
/* "Figure N." reads inline with its own title, the way a journal caption does */
.fig-label{color:var(--teal); font-weight:700;}
/* reference marker. Explicit .45em + line-height:0 so it scales with whatever
   it is attached to and never affects the line box of its heading. */
.fig-ref{font-size:.45em; font-weight:800; vertical-align:super; line-height:0;
  margin-inline-start:.08em; color:var(--teal);}
.section--dark .fig-label,
.section--dark .fig-ref{color:var(--teal-glow);}

.seg{display:inline-flex; border:1px solid var(--rule-on-dark); border-radius:var(--radius-btn); overflow:hidden;}
.seg button{min-height:44px; padding-inline:var(--space-3);
  font-family:var(--font-display); font-size:var(--step--1); font-weight:700;
  background:none; border:0; color:var(--cool-grey); cursor:pointer;
  transition:background-color 180ms ease,color 180ms ease;}
.seg button + button{border-left:1px solid var(--rule-on-dark);}
.seg button:hover{color:var(--text-on-dark);}
.seg button[aria-checked="true"]{background:var(--teal-glow); color:var(--navy-black);}

.legend{display:flex; gap:var(--space-4); flex-wrap:wrap; margin-block-start:var(--space-3);
  font-family:var(--font-display); font-size:var(--step--1); font-weight:600; color:var(--text-muted-on-dark);}
.legend span{display:inline-flex; align-items:center; gap:var(--space-1);}
.legend i{width:10px; height:10px; border-radius:50%; flex:0 0 auto;}
.legend .k-signal{background:var(--teal-glow);}
.legend .k-cell{background:var(--violet-glow);}

.diagram{display:block; width:100%; height:auto; margin-block-start:var(--space-3);}
.d-mass{fill:none; stroke:rgba(255,255,255,.34); stroke-width:1.5;}
.d-cell{fill:none; stroke:var(--cool-grey); stroke-width:1.5;
  transition:transform 260ms ease, fill 260ms ease, stroke 260ms ease;}
.d-tag{opacity:0; transition:opacity 200ms ease 120ms;}
.d-tag line{stroke:var(--teal-glow); stroke-width:1.5; stroke-linecap:round;}
.d-tag circle{fill:var(--teal-glow);}
.is-tagged .d-cell{fill:var(--violet-glow); stroke:var(--violet-glow);}
.is-tagged .d-tag{opacity:1;}
.is-tagged .c1{transform:translate(14px,14px);}
.is-tagged .c2{transform:translate(-14px,14px);}
.is-tagged .c3{transform:translate(16px,-4px);}
.is-tagged .c4{transform:translate(-16px,-6px);}
.is-tagged .c5{transform:translate(-6px,-16px);}
.is-tagged .c6{transform:translate(10px,-16px);}

.figure figcaption{margin-block-start:var(--space-3); padding-block-start:var(--space-3);
  border-top:1px solid var(--rule-on-dark);
  font-size:var(--step--1); line-height:1.5; color:var(--text-muted-on-dark); max-width:56ch;}
.figure figcaption strong{color:var(--text-on-dark);}
.figure__source{margin-block-start:var(--space-2); font-size:var(--step--1); line-height:1.5;
  color:var(--text-muted-on-dark); opacity:.8;}

/* ---------- stat band ---------- */
/* light data strip. Was navy; flipped so the dark run ends at the fold
   instead of continuing ~250px past it. */
.band{border-block:1px solid var(--rule); padding-block:var(--space-6);}
.band .wrap{display:grid; grid-template-columns:minmax(0,1fr) auto; gap:var(--space-6); align-items:center;}
.band__line{font-family:var(--font-display); font-size:var(--step-2); font-weight:700;
  line-height:1.3; letter-spacing:-.01em; max-width:36ch;}
/* teal-glow measures 1.4:1 on white, so the accent drops to teal (3.6:1),
   valid because both the accent and the numerals are large bold text. */
.band__line .accent{color:var(--teal);}
.band__stats{display:flex; gap:var(--space-7); flex-wrap:wrap;}
.band__num{font-family:var(--font-display); font-weight:800; font-size:var(--step-5);
  line-height:1; color:var(--teal);}
.band__label{margin-block-start:var(--space-1); font-size:var(--step--1); line-height:1.5;
  color:var(--text-muted-on-light); max-width:24ch;}
.band__source{margin-block-start:var(--space-5); font-size:var(--step--1); line-height:1.5;
  color:var(--text-muted-on-light); max-width:none;}
@media (max-width:900px){
  .band .wrap{grid-template-columns:1fr; gap:var(--space-5);}
  .band__stats{gap:var(--space-5);}
}

/* ---------- rows: replaces every card grid ---------- */
.rows{border-block-start:1px solid var(--rule);}
.row{display:grid; grid-template-columns:minmax(0,12rem) minmax(0,1fr) minmax(0,1.45fr);
  gap:var(--space-2) var(--space-5); padding-block:var(--space-5);
  align-items:baseline; border-block-end:1px solid var(--rule);}
.row__label{font-family:var(--font-display); font-size:var(--step--1); font-weight:700;
  letter-spacing:.08em; text-transform:uppercase; color:var(--teal);}
.row__title{margin:0; font-size:var(--step-2);}
.row__body{max-width:none; color:var(--text-muted-on-light);}
.row__title sup{font-size:.5em; vertical-align:super; font-weight:700;}

/* numbered variant: large numerals against one continuous vertical rule.
   Both encode real structure — these four steps are a causal chain. */
.rows--numbered .row{grid-template-columns:minmax(0,4.5rem) minmax(0,1fr) minmax(0,1.45fr);}
.rows--numbered{counter-reset:step; position:relative;}
.rows--numbered::before{
  content:''; position:absolute; top:0; bottom:0;
  left:calc(4.5rem + var(--space-5) / 2); width:1px; background:var(--rule);
}
.rows--numbered .row__label{
  font-size:var(--step-3); font-weight:800; line-height:1;
  letter-spacing:-.02em; text-transform:none; color:var(--teal);
}
.rows--numbered .row__label::before{content:counter(step,decimal-leading-zero); counter-increment:step;}

@media (max-width:900px){
  .rows--numbered::before{display:none;}
  .row{grid-template-columns:minmax(0,12rem) minmax(0,1fr); align-items:start;}
  .rows--numbered .row{grid-template-columns:minmax(0,4.5rem) minmax(0,1fr);}
  .row__body{grid-column:2;}
}
@media (max-width:640px){
  /* .rows--numbered .row (0,2,0) outranks .row (0,1,0), so the numbered variant
     has to be named explicitly here or it keeps the two-column grid from the
     900px block. When that happened, .row__body{grid-column:auto} dropped the
     paragraph into the 4.5rem number column and the text rendered roughly one
     character per line. */
  .row,
  .rows--numbered .row{grid-template-columns:1fr; gap:var(--space-2); padding-block:var(--space-4);}
  .row__body{grid-column:auto;}
}

/* closing statement — prominence comes from type size, not a fill.
   Keeps this stretch of the page to a single navy panel. */
/* no top rule: the last row's bottom border already separates this */
.statement{padding-block-start:0;}
.statement p{margin:0; max-width:34ch;
  font-family:var(--font-display); font-weight:800; font-size:var(--step-3);
  line-height:1.2; letter-spacing:-.015em;}
/* teal is 3.6:1 on white — valid here because step-3 bold is large text (3:1),
   but NOT valid for the 16px link below, which stays navy. */
.statement strong{color:var(--teal); font-weight:800;}
.arrow-link{display:inline-flex; align-items:center; gap:var(--space-1);
  min-height:44px;
  font-family:var(--font-display); font-weight:700; font-size:var(--step-0);
  color:var(--text-on-light);}
.arrow-link:hover{text-decoration:underline; text-underline-offset:3px;}
.arrow-link svg{width:15px; height:15px; color:var(--teal); flex:0 0 auto;}
.statement .arrow-link{margin-block-start:var(--space-2);}

/* ---------- horizontal strip: the 4-up alternative to stacked rows ---------- */
.strip{display:grid; grid-template-columns:repeat(4,minmax(0,1fr));
  border-block:1px solid var(--rule);}
.strip__item{padding:var(--space-5) var(--space-4);}
.strip__item:first-child{padding-inline-start:0;}
.strip__item:last-child{padding-inline-end:0;}
.strip__item + .strip__item{border-inline-start:1px solid var(--rule);}
.strip__label{display:block; font-family:var(--font-display); font-size:var(--step--1);
  font-weight:700; letter-spacing:.08em; text-transform:uppercase; color:var(--teal);}
.strip__name{margin:var(--space-2) 0 var(--space-2); font-size:var(--step-2);}
.strip__name sup{font-size:.5em; vertical-align:super; font-weight:700;}
/* Coverage names link to the article when a URL exists. Same treatment as
   .footer__bottom a: inherits colour, underline, teal on hover. No new token. */
.strip__name a{color:inherit; text-decoration:underline; text-underline-offset:3px;}
.strip__name a:hover{color:var(--teal-glow);}
.strip__body{max-width:none; font-size:var(--step--1); line-height:1.5;
  color:var(--text-muted-on-light);}

@media (max-width:900px){
  .strip{grid-template-columns:repeat(2,minmax(0,1fr));}
  .strip__item{padding-inline:var(--space-4);}
  .strip__item:nth-child(odd){padding-inline-start:0; border-inline-start:0;}
  .strip__item:nth-child(even){padding-inline-end:0;}
  .strip__item:nth-child(n+3){border-block-start:1px solid var(--rule);}
}
@media (max-width:600px){
  .strip{grid-template-columns:1fr;}
  .strip__item{padding-inline:0; border-inline-start:0;}
  .strip__item + .strip__item{border-block-start:1px solid var(--rule);}
}
/* 2-up and 3-up variants, same hairline treatment */
.strip--2{grid-template-columns:repeat(2,minmax(0,1fr));}
.strip--3{grid-template-columns:repeat(3,minmax(0,1fr));}
@media (max-width:640px){.strip--3{grid-template-columns:1fr;}}
/* publication names set as type, not logos: naming a publication factually is
   safe, reproducing its logo implies endorsement and needs permission */
.strip--3 .strip__name{margin:0; font-size:var(--step-2); line-height:1.2;}
.strip--2 .strip__body{font-size:var(--step-0); max-width:44ch;}
.strip--2 .btn{margin-block-start:var(--space-4);}
@media (max-width:760px){
  .strip--2{grid-template-columns:1fr;}
  .strip--2 .strip__item{padding-inline:0; border-inline-start:0;}
  .strip--2 .strip__item + .strip__item{border-block-start:1px solid var(--rule);}
}

/* ---------- footer ---------- */
/* Constrained to the 1200px wrap, not full-bleed like the nav. A 72px bar can
   span the viewport and read deliberate; a ~570px block of text cannot. */
.footer{background:var(--surface-dark); color:var(--text-on-dark);
  border-block-start:1px solid var(--rule-on-dark);
  padding-block:var(--space-4); text-align:center;}
.footer__brand{display:inline-flex; align-items:center; gap:10px;
  margin-block-end:var(--space-4);
  font-family:var(--font-display); font-weight:800; font-size:var(--step-1);
  letter-spacing:-.01em;}
.footer__brand em{font-style:normal; color:var(--teal-glow);}
/* 8-column grid rather than a centred flex row: distributes edge to edge
   instead of clustering in the middle */
.footer__nav{display:grid; grid-template-columns:repeat(8,minmax(0,1fr));
  gap:0 var(--space-2); list-style:none; margin:0 0 var(--space-3); padding:0;
  font-family:var(--font-display); font-size:var(--step--1); font-weight:600;}
@media (max-width:900px){.footer__nav{grid-template-columns:repeat(4,minmax(0,1fr));}}
@media (max-width:520px){.footer__nav{grid-template-columns:repeat(2,minmax(0,1fr));}}
/* ~37px tall: clears the 24px WCAG 2.5.8 pointer-target floor. The 44px rule
   is held for buttons; applying it to eight footer links would add ~150px. */
.footer__nav a{display:inline-block; padding-block:var(--space-1);
  color:var(--cool-grey); transition:color 180ms ease;}
.footer__nav a:hover{color:var(--teal-glow);}
/* was 11.5px / 100ch. 14px clears the 12px floor; 76ch keeps it a block, not a band. */
/* One continuous paragraph. max-width:none puts this at ~138ch, which is wide
   by normal standards; 118ch is available if it reads too long. */
.footer__legal{max-width:none; text-align:start;
  padding-block-start:var(--space-3); border-block-start:1px solid var(--rule-on-dark);
  font-size:var(--step--1); line-height:1.5; color:var(--text-muted-on-dark);}
@media (max-width:760px){.footer__legal{columns:1;}}
.footer__legal strong{color:var(--text-on-dark); font-weight:700;
  font-family:var(--font-display);}
.footer__bottom{display:flex; flex-wrap:wrap; justify-content:space-between;
  gap:var(--space-1) var(--space-3);
  margin-block-start:var(--space-3); padding-block-start:var(--space-3);
  border-block-start:1px solid var(--rule-on-dark);
  font-size:var(--step--1); color:var(--text-muted-on-dark);}
.footer__bottom a{color:inherit; text-decoration:underline; text-underline-offset:2px;}
.footer__bottom a:hover{color:var(--teal-glow);}
@media (max-width:520px){.footer__bottom{justify-content:center;}}

/* ---------- Figure 2: process axis. Same figure language as Figure 1. ---------- */
.fig{
  margin-block-start:var(--space-7);
  margin-inline:calc(-1 * var(--fig-bleed));
  width:calc(100% + 2 * var(--fig-bleed));
}
.fig__head{margin-block-end:var(--space-6);}
.fig__title{margin:0; max-width:none; font-family:var(--font-display);
  font-size:var(--step-2); font-weight:600; line-height:1.25;}
.fig__caption{position:relative; margin-block-start:var(--space-4);
  padding-inline-start:var(--space-3); max-width:60ch;
  font-size:var(--step--1); line-height:1.5; color:var(--text-muted-on-dark);}
.fig__caption::before{content:'*'; position:absolute; inset-inline-start:0;
  color:var(--teal-glow); font-weight:700;}

/* no box: the axis carries the structure, so a border around it was doing nothing
   except doubling up with the axis rule itself */
.flow{list-style:none; margin:0; padding:0; position:relative;
  display:grid; grid-template-columns:1.15fr 1fr 1fr;}
.flow__stage{position:relative; padding:var(--space-5) var(--space-5) 0 0;
  border-block-start:1px solid var(--rule-on-dark);}
/* the axis is colour-coded: LurexBio's segment is teal-glow, the rest is neutral.
   Adjacent grid items with no gap, so the borders read as one line that changes colour. */
.flow__stage--lurex{border-block-start-color:var(--teal-glow);}
/* tick, not a dot — a tick reads as a measured position, a dot reads as a flowchart node */
.flow__stage::before{content:''; position:absolute; inset-block-start:0; inset-inline-start:0;
  width:1px; height:16px; background:var(--cool-grey);}
.flow__stage--lurex::before{width:2px; height:30px; background:var(--teal-glow);}
/* direction indicator: two borders rotated, no glyph */
.flow::after{content:''; position:absolute; inset-block-start:-4px; inset-inline-end:0;
  width:7px; height:7px; transform:rotate(45deg);
  border-block-start:1px solid var(--rule-on-dark);
  border-inline-end:1px solid var(--rule-on-dark);}
.flow__label{display:block; font-family:var(--font-display); font-size:var(--step--1);
  font-weight:700; letter-spacing:.08em; text-transform:uppercase;
  color:var(--text-muted-on-dark);}
.flow__stage--lurex .flow__label{color:var(--teal-glow);}
/* --step-2, one level below the section h2 at --step-3: a label inside a figure
   should not compete with the headline the figure sits under */
.flow__name{margin:var(--space-2) 0 var(--space-3); font-size:var(--step-2);
  line-height:1.2;}
.flow__body{max-width:none; font-size:var(--step-0); line-height:1.55;
  color:var(--text-muted-on-dark);}
@media (max-width:820px){
  .flow{grid-template-columns:1fr; gap:var(--space-5);}
  .flow__stage{padding-inline-end:0;}
  .flow::after{display:none;}
}

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


/* ---------- breadcrumb ---------- */
.crumb{margin-block-end:var(--space-3);
  font-family:var(--font-display); font-size:var(--step--1); font-weight:600;
  color:var(--text-muted-on-dark);}
/* teal is 3.61:1 — fails 4.5:1 at 14px, so crumb links carry an underline instead */
.crumb a{color:var(--text-on-dark); text-decoration:underline; text-underline-offset:2px;}
.crumb a:hover{color:var(--teal-glow);}

/* ---------- interior page header ---------- */
.pagehead{padding-block:calc(var(--nav-h) + var(--space-6)) var(--section-y);}
.pagehead .deck{margin-block-start:var(--space-3);}

/* ---------- two-column page split ---------- */
.split{display:grid; grid-template-columns:minmax(0,1.1fr) minmax(0,.9fr);
  gap:var(--space-7);}
@media (max-width:900px){.split{grid-template-columns:1fr; gap:var(--space-6);}}

/* stacked variant of .strip, for sidebars */
.strip--stack{grid-template-columns:1fr; border-block:0;}
.strip--stack .strip__item{padding-inline:0;
  border-inline-start:0; border-block-start:1px solid var(--rule);}
.strip--stack .strip__item:first-child{padding-block-start:0; border-block-start:0;}
.strip--stack .btn{margin-block-start:var(--space-3);}

/* ---------- forms ---------- */
.form{display:grid; gap:var(--space-3); max-width:54ch;
  margin-block-start:var(--space-4);}
.field{display:grid; gap:var(--space-1);}
.field label{font-family:var(--font-display); font-size:var(--step--1); font-weight:700;
  letter-spacing:.06em; text-transform:uppercase; color:var(--text-muted-on-light);}
.field input,.field textarea{
  width:100%; min-height:44px; padding:11px var(--space-2);
  font-family:var(--font-body); font-size:var(--step-0); line-height:1.5;
  color:var(--text-on-light); background:var(--surface-light);
  border:1px solid var(--rule); border-radius:var(--radius-btn);
  transition:border-color 180ms ease;}
.field textarea{min-height:150px; resize:vertical;}
/* .55 alpha = 4.6:1 on white. Placeholder text is not exempt from contrast. */
.field input::placeholder,.field textarea::placeholder{color:rgba(5,9,20,.55);}
.field input:focus-visible,.field textarea:focus-visible{border-color:var(--teal);}
.field :user-invalid{border-color:var(--teal);}
.form__note{max-width:54ch; font-size:var(--step--1); line-height:1.5;
  color:var(--text-muted-on-light);}
.form .btn{justify-self:start;}

/* ---------- plain contact details ---------- */
.detail{display:grid; gap:var(--space-1); margin-block-start:var(--space-5);
  font-size:var(--step-0); line-height:1.6;}
.detail a{text-decoration:underline; text-underline-offset:2px;}
.detail a:hover{color:var(--teal);}
/* .detail was written to sit below the form with clear separation. Inside a
   strip item it follows a heading instead, so the large top margin reads as a
   gap rather than a break. */
.strip__item .detail{margin-block-start:var(--space-2);}

/* LinkedIn is a plain text link in .footer__bottom, not an icon. A filled
   badge carries far more visual weight than 14px type at the same pixel size,
   and the footer has no other icons for it to sit alongside. */

/* ---------- form status ---------- */
.form__status{margin:0; max-width:54ch;
  font-size:var(--step--1); line-height:1.5; font-weight:700;
  font-family:var(--font-display); color:var(--text-on-light);}
.form__status:empty{display:none;}

/* ============ CONTACT FORM 7 ============
   CF7 renders its own markup and ships its own stylesheet: 2px coloured boxes,
   its own spacing, its own type. This maps that output onto the site's existing
   form component so a submission looks like the rest of the site.

   Two structural facts about CF7 that this has to account for:
     1. It renders <form class="wpcf7-form">, NOT .form, so the grid layout has
        to be declared again here.
     2. It wraps every control in <span class="wpcf7-form-control-wrap">, which
        would otherwise break the .field grid.

   No !important anywhere. functions.php makes this stylesheet depend on the
   contact-form-7 handle when CF7 is active, so this always loads afterwards. If
   CF7's own styling ever wins, that dependency is the thing to check.

   Existing tokens only. No new colours. */

.wpcf7-form{display:grid; gap:var(--space-3); max-width:54ch;
  margin-block-start:var(--space-4);}
.wpcf7-form .btn{justify-self:start;}
.wpcf7-form-control-wrap{display:block;}

/* Response summary. CF7's default is a bordered box in its own green or red.
   Replaced with the .form__status treatment: Montserrat, small, and a rule on
   the inline start instead of a box. */
.wpcf7 .wpcf7-response-output{
  margin:0; max-width:54ch;
  padding-block:var(--space-2); padding-inline:var(--space-3) 0;
  border:0; border-inline-start:2px solid var(--rule);
  font-family:var(--font-display); font-size:var(--step--1); font-weight:700;
  line-height:1.5; color:var(--text-on-light);
}
.wpcf7 form.sent .wpcf7-response-output{
  border-inline-start-color:var(--teal); color:var(--teal);
}
/* The palette has no error colour, and the site already uses teal for
   :user-invalid. Rather than introduce a red, failure states are distinguished
   by weight and darkness, and the message text carries the meaning. */
.wpcf7 form.invalid .wpcf7-response-output,
.wpcf7 form.unaccepted .wpcf7-response-output,
.wpcf7 form.spam .wpcf7-response-output,
.wpcf7 form.failed .wpcf7-response-output,
.wpcf7 form.aborted .wpcf7-response-output{
  border-inline-start-color:var(--navy-black); border-inline-start-width:3px;
  color:var(--text-on-light);
}

/* Per-field validation, consistent with .field :user-invalid above. */
.wpcf7-not-valid-tip{
  margin-block-start:var(--space-1);
  font-family:var(--font-display); font-size:var(--step--1); font-weight:700;
  letter-spacing:.02em; color:var(--teal);
}
.field input.wpcf7-not-valid,
.field textarea.wpcf7-not-valid{border-color:var(--teal);}

/* CF7's spinner is a small animated disc. Kept - it is feedback, not
   decoration - but aligned to the button rather than floating. */
.wpcf7-spinner{margin-inline-start:var(--space-2); vertical-align:middle;}


/* ---------- stat list (definition pairs) ---------- */
.stats{display:grid; margin:0;}
/* column-reverse puts the value above its label while keeping dt before dd
   in source order, which is what the HTML spec wants inside each div */
.stats > div{display:flex; flex-direction:column-reverse; gap:var(--space-0);
  padding-block:var(--space-3); border-block-start:1px solid var(--rule);}
.stats > div:first-child{padding-block-start:0; border-block-start:0;}
.stats dt{font-size:var(--step--1); line-height:1.5; color:var(--text-muted-on-light);}
/* teal at --step-2 bold is large text, so 3.61:1 clears the 3:1 bar */
.stats dd{margin:0; font-family:var(--font-display); font-weight:800;
  font-size:var(--step-2); line-height:1.1; color:var(--teal);}
.section--dark .stats > div{border-color:var(--rule-on-dark);}
.section--dark .stats dt{color:var(--text-muted-on-dark);}
.section--dark .stats dd{color:var(--teal-glow);}

/* ---------- article prose ---------- */
.prose{max-width:var(--measure);}
.prose > * + *{margin-block-start:var(--space-3);}

/* ============ LEGAL PAGES ============
   Long-form legal copy: terms of use, privacy policy. Numbered sections,
   no decoration, generous measure. Existing tokens only - no new colours,
   no new radii, nothing added to the palette. */
.legal{max-width:var(--measure);}
.legal > * + *{margin-block-start:var(--space-3);}
.legal__date{font-size:var(--step--1); font-weight:600; letter-spacing:.02em;
  color:var(--text-muted-on-light);}
.legal h2{margin-block-start:var(--space-6); font-size:var(--step-1);}
.legal h3{margin-block-start:var(--space-4); font-size:var(--step-0); font-weight:700;}
.legal p{color:var(--text-muted-on-light);}
.legal ul{margin-block-start:var(--space-2); padding-inline-start:var(--space-3);
  color:var(--text-muted-on-light);}
.legal li + li{margin-block-start:var(--space-1);}
/* Statutory all-caps blocks (warranty disclaimer, liability limit). Set at
   small size with a rule so a wall of capitals does not dominate the page. */
.legal__caps{font-size:var(--step--1); line-height:1.65;
  color:var(--text-muted-on-light);
  border-inline-start:2px solid var(--rule); padding-inline-start:var(--space-3);}
.legal address{font-style:normal; color:var(--text-muted-on-light);}
/* Unfilled placeholder markers - deliberately loud so they cannot ship unnoticed. */
.legal__todo{font-weight:700; color:var(--navy-black);
  border-block-end:2px solid var(--teal);}


/* ---------- emphasised strip item ---------- */
.strip__item--focus .strip__label{color:var(--navy-black);}
.strip__note{margin-block-start:var(--space-2); padding-inline-start:var(--space-2);
  border-inline-start:2px solid var(--teal);
  font-size:var(--step--1); line-height:1.5; color:var(--text-on-light);}

/* bigger stat numerals on dark, where teal-glow runs at 14.2:1 */
.section--dark .stats dd{font-size:var(--step-3); line-height:1;}

/* ---------- referenced footnote on light surfaces ---------- */
.note{position:relative; margin-block-start:var(--space-4);
  padding-inline-start:var(--space-3); max-width:62ch;
  font-size:var(--step--1); line-height:1.5; color:var(--text-muted-on-light);}
.note::before{content:'*'; position:absolute; inset-inline-start:0;
  color:var(--teal); font-weight:700;}
.section--dark .note{color:var(--text-muted-on-dark);}
.section--dark .note::before{color:var(--teal-glow);}

/* ---------- bordered panel ---------- */
.panel{padding:var(--space-5); border:1px solid var(--rule);
  border-radius:var(--radius);}
.section--dark .panel{border-color:var(--rule-on-dark);}
.panel h3{margin:0 0 var(--space-1);}
.panel .caption{margin:0 0 var(--space-4);}

/* lead stat inside a panel */
.stats .stat--lead{padding-block-start:0;}
.stats .stat--lead dd{font-size:var(--step-4); letter-spacing:-.02em;}

/* ---------- data table ---------- */
.table-scroll{overflow-x:auto; margin-block-start:var(--space-5);}
.table{width:100%; min-width:44rem; border-collapse:collapse;
  font-size:var(--step-0);}
.table th,.table td{padding:var(--space-4) var(--space-4) var(--space-4) 0;
  text-align:start; vertical-align:top;
  border-block-end:1px solid var(--rule);}
.table thead th{padding-block:0 var(--space-2);
  font-family:var(--font-display); font-size:var(--step--1); font-weight:700;
  letter-spacing:.08em; text-transform:uppercase;
  /* navy not teal: teal at 14px is 3.61:1, below the 4.5:1 needed for small text */
  color:var(--text-on-light);
  border-block-end:2px solid var(--teal);}
.table tbody th{width:15rem;
  font-family:var(--font-display); font-size:var(--step-1); font-weight:700;
  line-height:1.25; color:var(--text-on-light);}
.table td{line-height:1.55; color:var(--text-muted-on-light);}
/* the last column carries the punchline: same gap, four different modalities.
   A vertical rule sets it apart so the repetition is visible at a glance. */
.table td:last-child{padding-inline-start:var(--space-4);
  border-inline-start:1px solid var(--rule);
  font-family:var(--font-display); font-weight:600;
  color:var(--text-on-light);}
.table tbody tr:last-child th,
.table tbody tr:last-child td{border-block-end:0;}

/* ---------- unit chart: one square = one patient in 100 ---------- */
.units{display:grid; grid-template-columns:repeat(3,minmax(0,1fr));
  gap:var(--space-6); margin-block-start:var(--space-6);}
.unit__name{font-family:var(--font-display); font-size:var(--step-0);
  font-weight:700; line-height:1.3;}
.unit__name small{display:block; margin-block-start:var(--space-0);
  font-family:var(--font-body); font-weight:400; font-size:var(--step--1);
  color:var(--text-muted-on-dark);}
.unit__value{margin-block-start:var(--space-3);
  font-family:var(--font-display); font-size:var(--step-3); font-weight:800;
  line-height:1; color:var(--teal-glow);}
.unit__grid{display:grid; grid-template-columns:repeat(10,1fr);
  gap:2px;   /* chart gutter, not layout spacing */
  margin-block-start:var(--space-3); max-width:15rem;}
.unit__grid i{aspect-ratio:1; background:rgba(255,255,255,.13);}
.unit--45 i:nth-child(-n+45),
.unit--5  i:nth-child(-n+5),
.unit--3  i:nth-child(-n+3){background:var(--teal-glow);}
@media (max-width:820px){
  .units{grid-template-columns:1fr; gap:var(--space-5);}
  .unit__grid{max-width:13rem;}
}

/* ---------- contents index ---------- */
.toc__band{margin-block-start:var(--space-6);
  border-block:1px solid var(--rule-on-dark);}
.toc__band ol{display:grid; grid-template-columns:repeat(4,minmax(0,1fr));
  gap:0; list-style:none; margin:0; padding:0; counter-reset:toc;}
.toc__band li{counter-increment:toc;}
.toc__band li + li{border-inline-start:1px solid var(--rule-on-dark);}
.toc__band a{display:block; height:100%;
  padding:var(--space-4) var(--space-4) var(--space-5);
  font-family:var(--font-display); font-size:var(--step-0); font-weight:600;
  line-height:1.3; color:var(--text-on-dark);
  transition:color 180ms ease;}
.toc__band li:first-child a{padding-inline-start:0;}
.toc__band a::before{content:counter(toc,decimal-leading-zero); display:block;
  margin-block-end:var(--space-2);
  font-size:var(--step-2); font-weight:800; line-height:1;
  color:var(--teal-glow); transition:color 180ms ease;}
.toc__band a:hover{color:var(--teal-glow);}
.toc__band a:hover::before{color:var(--surface-light);}
@media (max-width:820px){
  .toc__band ol{grid-template-columns:repeat(2,minmax(0,1fr));}
  .toc__band li:nth-child(odd){border-inline-start:0;}
  .toc__band li:nth-child(odd) a{padding-inline-start:0;}
  .toc__band li:nth-child(n+3){border-block-start:1px solid var(--rule-on-dark);}
}
@media (max-width:520px){
  .toc__band ol{grid-template-columns:1fr;}
  .toc__band li{border-inline-start:0 !important;}
  .toc__band li a{padding-inline-start:0;}
  .toc__band li + li{border-block-start:1px solid var(--rule-on-dark);}
}

/* ---------- component spec: problem / response opposition ----------
   Distinct from .rows and .strip because the content is an opposition,
   not a list: what is wrong, then what the platform does about it. The
   response column carries a teal rule so the two are not read as equals. */
.spec{padding-block:var(--space-6); border-block-start:1px solid var(--rule);}
.spec:last-child{border-block-end:1px solid var(--rule);}
.spec__head{display:flex; align-items:baseline; gap:var(--space-3);
  flex-wrap:wrap; margin-block-end:var(--space-5);}
.spec__num{font-family:var(--font-display); font-size:var(--step-3); font-weight:800;
  line-height:1; letter-spacing:-.02em; color:var(--teal);}
.spec__name{margin:0; font-size:var(--step-3);}
.spec__name sup{font-size:.45em; vertical-align:super; font-weight:700;}
.spec__meta{font-family:var(--font-display); font-size:var(--step--1); font-weight:700;
  letter-spacing:.08em; text-transform:uppercase; color:var(--text-muted-on-light);}
.spec__body{display:grid; grid-template-columns:minmax(0,1fr) minmax(0,1.25fr);
  gap:var(--space-6);}
.spec__label{display:block; margin-block-end:var(--space-2);
  font-family:var(--font-display); font-size:var(--step--1); font-weight:700;
  letter-spacing:.08em; text-transform:uppercase;}
.spec__col p{max-width:none; line-height:1.6;}
.spec__col--problem .spec__label{color:var(--text-muted-on-light);}
.spec__col--problem p{color:var(--text-muted-on-light);}
.spec__col--response{padding-inline-start:var(--space-4);
  border-inline-start:2px solid var(--teal);}
.spec__col--response .spec__label{color:var(--teal);}
@media (max-width:820px){
  .spec__body{grid-template-columns:1fr; gap:var(--space-4);}
  .spec__col--response{padding-inline-start:var(--space-3);}
}

/* ---------- vertical progress track ----------
   Deliberately vertical, and dots rather than ticks, so it is not mistaken
   for the positional axis in Figure 2. Filled dot = where we are, hollow =
   ahead of us. Sequence only; the handoff keeps dates off the public site. */
.track{list-style:none; margin:var(--space-6) 0 0; padding:0;}
.track__stage{position:relative;
  padding:0 0 var(--space-6) var(--space-5);
  border-inline-start:1px solid var(--rule);}
.track__stage:last-child{padding-block-end:0; border-inline-start-color:transparent;}
.track__stage::before{content:''; position:absolute;
  inset-block-start:6px; inset-inline-start:-6px;
  width:11px; height:11px; border-radius:50%;
  background:var(--surface-light); border:1px solid var(--cool-grey);}
.track__stage--now::before{background:var(--teal); border-color:var(--teal);}
.track__head{display:flex; align-items:center; gap:var(--space-2);
  flex-wrap:wrap; margin-block-end:var(--space-2);}
.track__title{margin:0; font-size:var(--step-2);}
.track__now{padding:var(--space-0) var(--space-1);
  border:1px solid var(--teal); border-radius:var(--radius-btn);
  font-family:var(--font-display); font-size:var(--step--1); font-weight:700;
  letter-spacing:.08em; text-transform:uppercase; color:var(--teal);}
.track__body{max-width:62ch; line-height:1.6; color:var(--text-muted-on-light);}
.section--dark .track__stage{border-inline-start-color:var(--rule-on-dark);}
.section--dark .track__stage::before{background:var(--surface-dark);}
.section--dark .track__stage--now::before{background:var(--teal-glow); border-color:var(--teal-glow);}
.section--dark .track__now{border-color:var(--teal-glow); color:var(--teal-glow);}
.section--dark .track__body{color:var(--text-muted-on-dark);}

/* ---------- research questions ----------
   Two questions side by side, split by a vertical hairline and framed top
   and bottom. Display-size question, method beneath, gate marker on the
   second. Stacks below 820px, where the divider becomes horizontal. */
.ask{display:grid; grid-template-columns:repeat(2,minmax(0,1fr));
  margin-block-start:var(--space-6);
  border-block:1px solid var(--rule);}
.ask__item{padding:var(--space-6) var(--space-5);}
.ask__item:first-child{padding-inline-start:0;}
.ask__item:last-child{padding-inline-end:0;}
.ask__item + .ask__item{border-inline-start:1px solid var(--rule);}
.ask__meta{display:block; margin-block-end:var(--space-3);
  font-family:var(--font-display); font-size:var(--step--1); font-weight:700;
  letter-spacing:.1em; text-transform:uppercase; color:var(--teal);}
.ask__q{margin:0; max-width:22ch;
  font-family:var(--font-display); font-size:var(--step-3); font-weight:800;
  line-height:1.15; letter-spacing:-.02em;}
.ask__how{margin-block-start:var(--space-4); max-width:44ch;
  line-height:1.6; color:var(--text-muted-on-light);}
.ask__gate{display:block; margin-block-start:var(--space-4);
  padding-inline-start:var(--space-2); border-inline-start:2px solid var(--teal);
  font-family:var(--font-display); font-size:var(--step--1); font-weight:700;
  letter-spacing:.06em; text-transform:uppercase; color:var(--teal);}
.section--dark .ask{border-color:var(--rule-on-dark);}
.section--dark .ask__item + .ask__item{border-inline-start-color:var(--rule-on-dark);}
.section--dark .ask__meta,
.section--dark .ask__gate{color:var(--teal-glow);}
.section--dark .ask__gate{border-color:var(--teal-glow);}
.section--dark .ask__how{color:var(--text-muted-on-dark);}
@media (max-width:820px){
  .ask{grid-template-columns:1fr;}
  .ask__item{padding-inline:0;}
  .ask__item + .ask__item{border-inline-start:0; border-block-start:1px solid var(--rule);}
  .section--dark .ask__item + .ask__item{border-block-start-color:var(--rule-on-dark);}
}

/* ---------- pull quote ---------- */
/* max-width lives on the <p>, not the <blockquote>. The ch unit resolves
   against the element's own font-size: on the blockquote that is inherited body
   Arial (~16px), giving about 410px, while the text inside renders at --step-2
   Montserrat Bold (22-28px). The quote was being squeezed to roughly 20
   characters per line instead of 46. Same value, correct element. */
.quote{margin:0;}
.quote p{margin:0; max-width:46ch; font-family:var(--font-display); font-size:var(--step-2);
  font-weight:700; line-height:1.35; letter-spacing:-.01em;}
.quote footer{margin-block-start:var(--space-3);
  font-family:var(--font-display); font-size:var(--step--1); font-weight:700;
  letter-spacing:.08em; text-transform:uppercase; color:var(--teal);}
.quote cite{font-style:normal;}
.section--dark .quote footer{color:var(--teal-glow);}

/* ---------- people roster ----------
   Monogram + name + role + note in a 3-up directory. No boxes: the monograms
   carry the rhythm. Swap .roster__mono for an <img> when headshots exist. */
.roster{display:grid; grid-template-columns:repeat(3,minmax(0,1fr));
  gap:var(--space-6) var(--space-5); margin-block-start:var(--space-6);
  list-style:none; padding:0;}
.roster__person{display:grid; gap:var(--space-2); align-content:start;}
.roster__mono{display:grid; place-items:center;
  width:56px; height:56px; border-radius:50%;
  background:var(--navy-black); color:var(--surface-light);
  font-family:var(--font-display); font-size:var(--step-0); font-weight:800;
  letter-spacing:.02em;}
.roster__name{margin:0; font-size:var(--step-1); line-height:1.3;}
.roster__role{font-family:var(--font-display); font-size:var(--step--1);
  font-weight:700; letter-spacing:.04em; color:var(--teal);}
.roster__note{max-width:none; font-size:var(--step--1); line-height:1.55;
  color:var(--text-muted-on-light);}
.section--dark .roster__mono{background:var(--teal-glow); color:var(--navy-black);}
.section--dark .roster__role{color:var(--teal-glow);}
.section--dark .roster__note{color:var(--text-muted-on-dark);}
@media (max-width:900px){.roster{grid-template-columns:repeat(2,minmax(0,1fr));}}
@media (max-width:560px){.roster{grid-template-columns:1fr;}}

/* narrower table variant for two-column lists */
.table--slim{min-width:28rem;}
.table--slim tbody th{width:auto;}

/* ---------- independent panels ----------
   Gapped rather than divided: these four IP domains are protected separately,
   so the design says "separate" by leaving space between them, where .strip
   and .rows both say "connected" by sharing rules. */
.panels{display:grid; grid-template-columns:repeat(2,minmax(0,1fr));
  gap:var(--space-4); margin-block-start:var(--space-6);}
.panels .panel{display:flex; flex-direction:column;}
.panel__tag{display:block; margin-block-end:var(--space-3);
  font-family:var(--font-display); font-size:var(--step--1); font-weight:700;
  letter-spacing:.08em; text-transform:uppercase; color:var(--teal);}
.panel__name{margin:0 0 var(--space-2); font-size:var(--step-2);}
.panel__name sup{font-size:.45em; vertical-align:super; font-weight:700;}
.section--dark .panel__tag{color:var(--teal-glow);}
@media (max-width:760px){.panels{grid-template-columns:1fr;}}

/* ---------- closing call to action ----------
   Bridge sections were a stacked stub: eyebrow, h2, deck, button. As a
   horizontal band framed top and bottom it fills the width and reads as a
   deliberate close rather than leftover space. */
.cta{display:grid; grid-template-columns:minmax(0,1fr) auto;
  gap:var(--space-6); align-items:center;
  padding-block:var(--space-6);
  border-block:1px solid var(--rule);}
.cta__body > * + *{margin-block-start:var(--space-2);}
.cta h2{font-size:var(--step-2);}
.cta .deck{margin-block-start:var(--space-2); font-size:var(--step-0); max-width:52ch;}
.section--dark .cta{border-color:var(--rule-on-dark);}
@media (max-width:760px){
  .cta{grid-template-columns:1fr; gap:var(--space-4); align-items:start;}
}

/* ---------- news feed ----------
   The whole row is the link, which is what a listing wants and is why this
   is not .rows: those are content blocks, these are navigation. Hover is a
   colour change only, consistent with the rest of the site. */
.feed{border-block-start:1px solid var(--rule);}
.feed__item{display:grid; grid-template-columns:minmax(0,1fr) auto;
  gap:var(--space-3) var(--space-4); align-items:center;
  padding-block:var(--space-5);
  border-block-end:1px solid var(--rule);
  color:inherit; text-decoration:none;}
.feed__kicker{display:block; margin-block-end:var(--space-2);
  font-family:var(--font-display); font-size:var(--step--1); font-weight:700;
  letter-spacing:.08em; text-transform:uppercase; color:var(--teal);}
.feed__meta{display:flex; flex-wrap:wrap; gap:var(--space-0) var(--space-2);
  align-items:baseline; margin:0 0 var(--space-2);}
.feed__meta .feed__kicker{margin-block-end:0;}
.feed__date{font-family:var(--font-display); font-size:var(--step--1);
  font-weight:600; color:var(--text-muted-on-light);
  font-variant-numeric:tabular-nums;}
.section--dark .feed__date{color:var(--text-muted-on-dark);}
.feed__title{margin:0; max-width:52ch; font-size:var(--step-2); line-height:1.25;
  transition:color 180ms ease;}
.feed__item svg{width:18px; height:18px; color:var(--teal); flex:0 0 auto;}
.feed__item:hover .feed__title{color:var(--teal);}
.section--dark .feed,
.section--dark .feed__item{border-color:var(--rule-on-dark);}
.section--dark .feed__kicker,
.section--dark .feed__item svg{color:var(--teal-glow);}
.section--dark .feed__item:hover .feed__title{color:var(--teal-glow);}

/* ---------- press release body ---------- */
.release{max-width:68ch;}
.release > * + *{margin-block-start:var(--space-3);}
.release h2{margin-block-start:var(--space-6); font-size:var(--step-2);}
.release__dateline{font-family:var(--font-display); font-size:var(--step--1);
  font-weight:700; letter-spacing:.06em; text-transform:uppercase; color:var(--teal);}
.release__boiler{margin-block-start:var(--space-7); padding-block-start:var(--space-4);
  border-block-start:1px solid var(--rule); max-width:68ch;}
.release__boiler h2{margin-block-start:0;}

/* Equal-height columns with bottom-aligned buttons. Grid already stretches the
   items; making each a flex column lets the button take margin-block-start:auto
   and sit at the bottom regardless of how the body copy wraps. Without this the
   buttons drift apart whenever the two descriptions wrap to different heights. */
.strip--2 .strip__item{display:flex; flex-direction:column; align-items:flex-start;}
.strip--2 .strip__body{margin-block-end:var(--space-4);}
.strip--2 .btn{margin-block-start:auto;}