/* ── Elevate shared stylesheet ─────────────────────────────────────────────
   Tokens, reset, and all reusable components for Elevate hub + event pages.
   Version the file (not inline styles) when changing the design system.
   ────────────────────────────────────────────────────────────────────────── */

/* ── Reset ─────────────────────────────────────────────────────────────── */
*, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }
img, video { display: block; max-width: 100%; }
ul { list-style: none; }
button { font: inherit; cursor: pointer; border: none; background: none; }
a { color: inherit; }

/* ── Design tokens ──────────────────────────────────────────────────────── */
:root {
  --denim:          oklch(0.24 0.045 240);
  --denim-mid:      oklch(0.30 0.042 240);
  --denim-raised:   oklch(0.36 0.040 240);
  --denim-deep:     oklch(0.18 0.035 240);

  --orange:         oklch(0.64 0.175 58);
  --orange-light:   oklch(0.70 0.160 60);
  --orange-dim:     oklch(0.55 0.130 58);

  --text-1:         oklch(0.96 0.006 240);
  --text-2:         oklch(0.72 0.020 240);
  --text-3:         oklch(0.52 0.018 240);

  --border:         oklch(0.33 0.030 240);
  --border-light:   oklch(0.40 0.025 240);

  --f-display: 'Figtree', system-ui, sans-serif;
  --f-body:    'Figtree', system-ui, sans-serif;
}

/* ── Base ───────────────────────────────────────────────────────────────── */
html { scroll-behavior: smooth; font-size: 16px; }

body {
  font-family: var(--f-body);
  font-size: 1rem;
  line-height: 1.65;
  color: var(--text-1);
  background: var(--denim);
}

p { max-width: 65ch; }

/* ── Utility classes ────────────────────────────────────────────────────── */
.eyebrow {
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--orange);
  margin-bottom: 0.75rem;
  display: block;
}

.wrap {
  max-width: 1200px;
  margin-inline: auto;
  padding-inline: clamp(1.5rem, 5vw, 4rem);
}

.pad { padding-block: clamp(4rem, 9vh, 6.5rem); }

/* ── Navigation ─────────────────────────────────────────────────────────── */
.site-nav {
  position: fixed;
  inset: 0 0 auto;
  z-index: 200;
  padding-inline: clamp(1.5rem, 5vw, 4rem);
  transition: background 0.3s, border-color 0.3s;
  border-bottom: 1px solid transparent;
}

.site-nav.scrolled {
  background: oklch(0.18 0.035 240 / 0.94);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border-bottom-color: var(--border);
}

.nav-inner {
  display: flex;
  align-items: center;
  height: 68px;
  gap: 2rem;
}

.nav-logo { flex-shrink: 0; text-decoration: none; display: flex; align-items: center; }
.nav-logo img { height: 26px; width: auto; }
.brand-elevate {
  font-family: var(--f-display);
  font-weight: 800;
  font-size: 1.4rem;
  letter-spacing: -0.02em;
  line-height: 1;
  color: var(--text-1);
}
.brand-elevate .brand-dot { color: var(--orange); }
.brand-by {
  font-size: 0.62rem;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--text-3);
}
@media (max-width: 420px) { .brand-by { display: none; } }

.nav-links {
  display: flex;
  align-items: center;
  gap: clamp(1rem, 2.5vw, 2rem);
  margin-left: auto;
}

.nav-links a {
  text-decoration: none;
  font-size: 0.875rem;
  font-weight: 500;
  color: var(--text-2);
  transition: color 0.2s;
}

.nav-links a:hover,
.nav-links a[aria-current="page"] { color: var(--text-1); }

.nav-cta {
  display: inline-flex;
  align-items: center;
  padding: 0.5rem 1.2rem;
  background: var(--orange);
  color: var(--denim-deep);
  font-size: 0.85rem;
  font-weight: 700;
  text-decoration: none;
  border-radius: 3px;
  transition: background 0.2s;
  white-space: nowrap;
  flex-shrink: 0;
}

.nav-cta:hover { background: var(--orange-light); }

@media (max-width: 700px) { .nav-links { display: none; } }

/* ── Buttons ─────────────────────────────────────────────────────────────── */
.btn {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  padding: 0.8rem 1.65rem;
  font-family: var(--f-body);
  font-size: 0.95rem;
  font-weight: 600;
  text-decoration: none;
  border-radius: 3px;
  border: 2px solid transparent;
  transition: background 0.2s, color 0.2s, border-color 0.2s;
  cursor: pointer;
  line-height: 1;
}

.btn-primary  { background: var(--orange); color: var(--denim-deep); border-color: var(--orange); }
.btn-primary:hover { background: var(--orange-light); border-color: var(--orange-light); }

.btn-ghost    { background: transparent; color: var(--text-1); border-color: var(--border-light); }
.btn-ghost:hover { border-color: var(--text-1); }

.btn-outline-orange {
  background: transparent;
  color: var(--orange);
  border-color: oklch(0.64 0.175 58 / 0.45);
}
.btn-outline-orange:hover {
  background: oklch(0.64 0.175 58 / 0.1);
  border-color: var(--orange);
}

.btn-dark { background: var(--denim-deep); color: var(--orange); border-color: var(--denim-deep); }
.btn-dark:hover { background: var(--denim); border-color: var(--denim); }

.btn-sm { font-size: 0.85rem; padding: 0.6rem 1.2rem; }

/* ── Hero (program hub variant) ─────────────────────────────────────────── */
.hero {
  position: relative;
  min-height: 100svh;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  padding: clamp(5rem, 12vh, 9rem) clamp(1.5rem, 5vw, 4rem) clamp(4rem, 9vh, 6rem);
  overflow: hidden;
}

.hero-photo {
  position: absolute;
  inset: 0;
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
  opacity: 1;
}

/* Photo runs at full opacity (crisp, full colour). The scrim is kept light so
   subjects read everywhere - text legibility comes mostly from a text-shadow on
   the hero copy, not from crushing the image:
     1) top band  - just enough to keep the nav readable
     2) left wash - gentle, so left-of-frame subjects still show through
     3) bottom    - blends into the next section
   The photo stays clear toward the centre/right. */
.hero-grad {
  position: absolute;
  inset: 0;
  background:
    linear-gradient(180deg,
      oklch(0.12 0.03 240 / 0.72) 0%,
      oklch(0.13 0.03 240 / 0.25) 12%,
      transparent 22%),
    linear-gradient(90deg,
      oklch(0.13 0.035 240 / 0.90) 0%,
      oklch(0.14 0.035 240 / 0.78) 32%,
      oklch(0.15 0.035 240 / 0.50) 52%,
      oklch(0.16 0.035 240 / 0.18) 76%,
      oklch(0.16 0.035 240 / 0.06) 100%),
    linear-gradient(180deg,
      transparent 50%,
      oklch(0.17 0.035 240 / 0.55) 80%,
      var(--denim) 100%);
}

/* The 90deg wash above is a DESKTOP device: it darkens the left third, where the
   copy sits, and lets the photo run clear to the right. At phone widths the copy is
   full-bleed, so its right-hand end lands on the 0.06-0.18 tail of that wash - which
   is why measured contrast on the live site fell to 2.2:1 against white over the
   brightest tenth of the headline's area, on 41 of 84 hero text regions.
   The three hero variants also sit at different heights (.hero and .event-hero are
   bottom-aligned, .page-hero is top-padded), so no single directional gradient covers
   them. Below 720px the wash is therefore replaced by an even veil, keeping the nav
   band and the bottom blend. The photo reads as a backdrop here rather than a
   subject, which is the right trade when the alternative is unreadable copy. */
@media (max-width: 720px) {
  .hero-grad {
    background:
      linear-gradient(180deg,
        oklch(0.12 0.03 240 / 0.80) 0%,
        oklch(0.13 0.03 240 / 0.42) 16%,
        transparent 30%),
      linear-gradient(180deg,
        transparent 55%,
        oklch(0.15 0.035 240 / 0.45) 80%,
        var(--denim) 100%),
      linear-gradient(0deg,
        oklch(0.13 0.03 240 / 0.62),
        oklch(0.13 0.03 240 / 0.62));
  }
}

/* Legibility insurance for hero copy over photography (tight shadow + soft glow) */
.hero-content, .page-hero-content {
  text-shadow: 0 1px 2px oklch(0.10 0.03 240 / 0.7), 0 2px 30px oklch(0.10 0.03 240 / 0.6);
}
.hero-content .btn, .page-hero-content .btn { text-shadow: none; }

.hero-content { position: relative; z-index: 1; max-width: 1200px; }

.hero-badge {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  padding: 0.3rem 0.85rem;
  border: 1px solid oklch(0.64 0.175 58 / 0.4);
  border-radius: 100px;
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--orange);
  margin-bottom: 1.75rem;
}

.hero-badge::before {
  content: '';
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--orange);
  flex-shrink: 0;
}

.hero-h1 {
  font-family: var(--f-display);
  font-size: clamp(3rem, 7.5vw, 6.25rem);
  font-weight: 800;
  line-height: 1.0;
  letter-spacing: -0.025em;
  color: var(--text-1);
  max-width: 14ch;
  margin-bottom: 1.5rem;
}

.hero-h1 em { font-style: italic; color: var(--orange); }

.hero-sub {
  font-size: clamp(1rem, 1.8vw, 1.2rem);
  color: var(--text-2);
  line-height: 1.65;
  max-width: 52ch;
  margin-bottom: 2.5rem;
}

.hero-ctas { display: flex; flex-wrap: wrap; gap: 0.85rem; }

/* Hero (event page variant - shorter, more focused) */
.event-hero {
  position: relative;
  min-height: 70svh;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  padding: clamp(5rem, 12vh, 9rem) clamp(1.5rem, 5vw, 4rem) clamp(3rem, 7vh, 5rem);
  overflow: hidden;
}

.event-hero-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.85rem;
  margin-bottom: 1.5rem;
}

.event-hero-date {
  font-family: var(--f-display);
  font-size: 0.82rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--orange);
}

.event-hero-sep {
  width: 3px;
  height: 3px;
  border-radius: 50%;
  background: var(--border-light);
}

.event-hero-venue {
  font-size: 0.82rem;
  color: var(--text-2);
  letter-spacing: 0.04em;
}

.event-hero .hero-h1 { font-size: clamp(2.4rem, 5.5vw, 4.5rem); }

/* Past-event pill in the event hero */
.event-hero-past {
  display: inline-flex;
  align-items: center;
  padding: 0.25rem 0.7rem;
  border: 1px solid var(--border-light);
  border-radius: 100px;
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text-3);
  background: oklch(1 0 0 / 0.06);
}

/* ── Intro band ─────────────────────────────────────────────────────────── */
.intro-band {
  background: var(--denim-mid);
  border-top: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
}

.intro-text {
  font-family: var(--f-display);
  /* Up one step in the hierarchy (~15% on every stop of the clamp) so the statement
     reads as the section's voice rather than an oversized paragraph. */
  font-size: clamp(1.725rem, 3.1vw, 2.53rem);
  font-weight: 500;
  /* Was 1.4. At display size across a 46ch measure the lines were stacking too
     tightly to breathe. */
  line-height: 1.55;
  color: var(--text-1);
  max-width: 46ch;
}

.intro-text strong { font-weight: 700; color: var(--orange); }

/* Second tier beneath the statement: lighter weight, smaller, and set in the body
   face rather than the display face, so the statement above stays the loud one.
   Its own max-width is wider than .intro-text because body copy reads badly at the
   short measure a display line wants. */
.intro-support {
  /* Scales with the statement so the gap between the two tiers holds. */
  margin-top: clamp(1.15rem, 2.1vw, 1.75rem);
  font-size: clamp(1.09rem, 1.32vw, 1.24rem);
  font-weight: 400;
  line-height: 1.8;
  color: var(--text-2);
  max-width: 58ch;
}

.intro-support > :first-child { margin-top: 0; }
.intro-support > :last-child { margin-bottom: 0; }
.intro-support p + p { margin-top: 1.15rem; }
.intro-grid .intro-support { max-width: 48ch; }

/* Statement with host logos: text left, logos stacked on the right. */
.intro-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: clamp(2rem, 6vw, 5rem);
  align-items: start;
}
.intro-grid .intro-text { max-width: 40ch; }
/* Statement with a video: copy left, player right.

   This variant runs a wider measure than the rest of the site. At the standard
   1200px wrap a fixed-width player leaves the statement only ~470px, which breaks
   a display-size heading into a ragged four lines. The extra width goes to the
   copy, not the player. */
.intro-band-video .wrap { max-width: 1440px; }
.intro-grid-video {
  grid-template-columns: minmax(0, 1fr) minmax(0, 560px);
  align-items: center;
  gap: clamp(2rem, 4vw, 3.5rem);
}
.intro-grid-video .intro-text { max-width: 38ch; }

/* headingAcross: the statement runs the full width above the row. It keeps the
   default 46ch measure - a display line set across the whole 1440px band would be
   an unreadably long measure - and the copy below starts at the top of its column
   rather than centring against the player. */
.intro-text-across { margin-bottom: clamp(1.75rem, 3vw, 2.75rem); }
.intro-grid-across { align-items: start; }

/* Tablet: the player would squeeze the copy below its comfortable measure before
   the single-column breakpoint arrives, so cap it earlier. */
@media (max-width: 1100px) {
  .intro-grid-video { grid-template-columns: minmax(0, 1fr) minmax(0, 46%); }
}

/* Stacked: copy first, player beneath at full width. aspect-ratio on .video-frame
   keeps the 16/9 box, so nothing letterboxes or collapses. */
@media (max-width: 860px) {
  .intro-band-video .wrap { max-width: 1200px; }
  .intro-grid-video { grid-template-columns: minmax(0, 1fr); gap: clamp(1.75rem, 5vw, 2.5rem); }
  .intro-grid-video .intro-text { max-width: none; }
}

.intro-hosts { display: flex; flex-direction: column; gap: 1.4rem; padding-top: 0.5rem; }
.intro-hosts-stack {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 1.9rem;
}
/* Explicit height (not max-height) so the EPUT SVG - which has no intrinsic size -
   scales up instead of rendering tiny. Heights set for even optical presence:
   the compact block sits a touch taller than the long wordmark. */
.intro-hosts-stack img { display: block; width: auto; }
.intro-hosts-stack img[src*="mid-south-essex"] { height: 81px; }
.intro-hosts-stack img[src*="eput"] { height: 66px; }
@media (max-width: 820px) {
  .intro-grid { grid-template-columns: 1fr; gap: 2.25rem; }
}
@media (max-width: 520px) {
  .intro-hosts-stack img[src*="mid-south-essex"] { max-height: 54px; max-width: 108px; }
  .intro-hosts-stack img[src*="eput"] { max-width: 140px; max-height: 42px; }
}

/* ── Dual audience panels ────────────────────────────────────────────────── */
.dual-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 2px;
  background: var(--border);
}

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

.audience-panel { padding: clamp(2.5rem, 5vw, 4rem); }
.audience-panel:first-child { background: var(--denim); }
.audience-panel:last-child  { background: var(--denim-mid); }

.audience-panel h3 {
  font-family: var(--f-display);
  font-size: clamp(1.4rem, 2.3vw, 1.9rem);
  font-weight: 700;
  line-height: 1.2;
  margin-bottom: 1.75rem;
}

/* ── Benefit list ───────────────────────────────────────────────────────── */
.benefit-list { margin-bottom: 2.5rem; }

.benefit-list li {
  display: grid;
  grid-template-columns: 1.2rem 1fr;
  gap: 0.65rem;
  padding-block: 0.7rem;
  border-bottom: 1px solid var(--border);
  font-size: 0.95rem;
  color: var(--text-2);
  line-height: 1.5;
  align-items: start;
}

.benefit-list li::before {
  content: '\2192';
  color: var(--orange);
  font-weight: 700;
  margin-top: 0.05em;
}

/* ── Section heading ────────────────────────────────────────────────────── */
.section-h2 {
  font-family: var(--f-display);
  font-size: clamp(1.7rem, 2.8vw, 2.3rem);
  font-weight: 700;
  line-height: 1.2;
}

/* ── Case study ─────────────────────────────────────────────────────────── */
.case-band { background: var(--denim-mid); }

.case-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(2.5rem, 5vw, 5rem);
  align-items: center;
}

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

.case-h2 {
  font-family: var(--f-display);
  font-size: clamp(1.6rem, 2.8vw, 2.4rem);
  font-weight: 700;
  line-height: 1.15;
  margin-bottom: 1rem;
}

.case-body {
  font-size: 1rem;
  color: var(--text-2);
  line-height: 1.7;
  margin-bottom: 2rem;
}

.outcomes { display: flex; flex-direction: column; gap: 1.25rem; }

.outcome {
  display: grid;
  grid-template-columns: 2rem 1fr;
  gap: 0.75rem;
  align-items: start;
}

.outcome-num {
  font-family: var(--f-display);
  font-size: 0.75rem;
  font-weight: 800;
  color: var(--orange);
  padding-top: 0.15em;
  letter-spacing: 0.05em;
}

.outcome-body strong {
  display: block;
  font-size: 0.95rem;
  font-weight: 600;
  color: var(--text-1);
  margin-bottom: 0.2rem;
}

.outcome-body span {
  font-size: 0.875rem;
  color: var(--text-2);
  line-height: 1.5;
}

.case-img {
  width: 100%;
  aspect-ratio: 4/3;
  object-fit: cover;
  border-radius: 4px;
}

/* ── Testimonials / quotes ───────────────────────────────────────────────── */
.quotes-header { margin-bottom: clamp(2rem, 4vw, 3rem); }

.quotes-header h2 {
  font-family: var(--f-display);
  font-size: clamp(1.7rem, 2.8vw, 2.3rem);
  font-weight: 700;
  line-height: 1.2;
  max-width: 22ch;
}

.quotes-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  /* Matches the carousel: no divider rules, no outer border. Cards stay separable
     through the alternating .raised tint rather than hairlines. */
  gap: 0;
}

.quote-card {
  background: var(--denim);
  padding: clamp(1.75rem, 3vw, 2.5rem);
  display: flex;
  flex-direction: column;
  gap: 1.25rem;
}

.quote-card.raised { background: var(--denim-mid); }

/* Quotation mark anchored top-right, sitting behind the text as a graphic device
   rather than a stray character. Sized to fit WITHIN the card: bled off the corner it
   cropped down to two disconnected blobs that read as a rendering artefact, so the
   whole glyph now shows and the opacity carries the weight instead of the scale.
   The CLOSING mark, not the opening one: it sits at the end of the card's top edge,
   where an opening mark would read as introducing something above it.
   Set in a serif: the display face's " is a pair of geometric ticks, which at small
   size looked like an unclosed typo. A serif open-quote has the familiar comma form
   that reads unmistakably as quotation.
   It sits BEHIND the text (z-index 0, siblings raised to 1) and is aria-hidden, so it
   is decoration to both the eye and a screen reader. */
.quote-mark {
  position: absolute;
  /* One inset value for both edges, applied raw. An earlier -0.24em compensation for
     the glyph's top bearing over-corrected: it lifted the ink until the commas clipped
     on the card's top edge. The bearing is left in, so the visible gap above the mark
     is a little larger than the gap to its right, which is what the design wants. */
  --qm-inset: clamp(1rem, 3cqw, 2.25rem);
  top: var(--qm-inset);
  right: var(--qm-inset);
  z-index: 0;
  pointer-events: none;
  user-select: none;
  font-family: Georgia, 'Times New Roman', 'Iowan Old Style', serif;
  /* Sized against the CARD, not the viewport: at three columns a viewport-relative
     mark looked right, but the same value in a full-width carousel card was tiny
     against all that area. cqw ties it to the card's own width so one rule holds for
     every column count. The vw line above is the fallback for engines without
     container query units. */
  font-size: clamp(5rem, 9vw, 7.5rem);
  font-size: clamp(4.5rem, 30cqw, 16rem);
  font-weight: 700;
  line-height: 0.8;
  color: var(--orange);
  opacity: 0.32;
}

/* A carousel card owns the full band, so the mark scales with it. Opacity eases off
   as it grows - the same 0.2 over that much more area reads far heavier. */
/* Larger area, so the same opacity would read heavier - ease it back a touch. Size
   is handled by the shared cqw rule and needs no carousel override. */
/* In the carousel the mark is a child of the WRAP, not of a card: it holds still
   while the quotes slide past it. Inset matches the card padding so it sits where a
   per-card mark used to. */
.quotes-carousel-wrap > .quote-mark {
  right: clamp(2rem, 4.5vw, 4rem);
  top: clamp(2rem, 4.5vw, 4rem);
  font-size: clamp(7rem, 22cqw, 16rem);
  opacity: 0.28;
}

/* Clip the bleed to the card, and lift the content above the mark. */
/* inline-size container so .quote-mark can size against the card. Safe here: the
   card's width comes from its grid track or flex basis, never from its contents. */
.quote-card { position: relative; overflow: hidden; container-type: inline-size; }
.quote-card > *:not(.quote-mark) { position: relative; z-index: 1; }

.quote-text {
  font-size: clamp(0.9rem, 1.25vw, 1.05rem);
  line-height: 1.7;
  color: var(--text-2);
  flex: 1;
  max-width: none;
}

.quote-attr {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding-top: 0.5rem;
  border-top: 1px solid var(--border);
}

.quote-initials {
  width: 38px;
  height: 38px;
  border-radius: 50%;
  background: var(--denim-raised);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 0.78rem;
  font-weight: 700;
  color: var(--text-3);
  flex-shrink: 0;
  font-family: var(--f-display);
}

.attr-name  { font-size: 0.875rem; font-weight: 600; color: var(--text-1); display: block; line-height: 1.3; }
.attr-role  { font-size: 0.775rem; color: var(--text-2); display: block; line-height: 1.4; }

/* Photo alternative to the initials disc. Same footprint so a mixed set (some with
   photos, some without) keeps its attribution rows on one baseline. */
.quote-photo {
  width: 38px;
  height: 38px;
  border-radius: 50%;
  object-fit: cover;
  flex-shrink: 0;
  display: block;
}

/* Tier one: the short quotable line. Display face, so it carries the card and the
   supporting copy beneath reads as context rather than competing with it. */
.quote-headline {
  font-family: var(--f-display);
  font-size: clamp(1.15rem, 1.7vw, 1.45rem);
  font-weight: 600;
  line-height: 1.35;
  color: var(--text-1);
  margin: 0;
  max-width: 34ch;
}

.quote-card figcaption { margin: 0; }
.quote-card { margin: 0; }

/* ── Testimonials carousel ────────────────────────────────────────────────
   Scroll-snap rather than JS: the editor preview loads no site scripts, so a
   scripted carousel would render as a broken stack for the author while working
   on the live page. A plain scroll region also stays keyboard-navigable and is
   announced sensibly, with no behaviour to reimplement. */
.quotes-carousel {
  display: flex;
  /* No gap, no background, no border. The 1px gap over a --border background was a
     divider trick that read as an inner edge inside the card, and the outer border
     boxed in a band that sits better flush. */
  gap: 0;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  overscroll-behavior-x: contain;
  scrollbar-width: none;
  /* It is a grid item now; keep its automatic minimum size from being its content. */
  min-width: 0;
}

.quotes-carousel::-webkit-scrollbar { display: none; }

.quotes-carousel:focus-visible { outline: 2px solid var(--orange); outline-offset: 2px; }

/* One quote at a time. */
.quotes-carousel > .quote-card {
  flex: 0 0 100%;
  scroll-snap-align: start;
  /* No bottom reserve for the attribution. It used to sit out of flow under an
     absolute layer, and the card padded a fixed 5.5rem strip for it to land in. The
     attribution's height is not fixed - it grows with the length of the job title,
     and again below 640px where the footer stacks - so anything longer than the
     reserve rode up over the quote instead of pushing the band taller. The footer is
     now a grid row of its own (see .quotes-carousel-wrap), so the band measures it. */
  padding: var(--qc-pad);
  justify-content: center;
  min-height: clamp(18rem, 26vw, 24rem);
  overflow: visible;
}

/* Attribution layer: one cell, every attribution stacked in it, only the current one
   visible. Crossfading here rather than sliding with the card is the whole point -
   the copy travels, the person fades. */
/* The attribution and the controls share one row rather than overlapping. A long
   role (and a dot per quote) makes any fixed reserve wrong sooner or later, so the
   layout engine keeps them apart instead of a magic padding value. */
/* In flow as the band's second grid row, not an absolute layer over the card. That is
   what makes the promise in the comment above true: the band's height is now the
   carousel's height PLUS whatever the tallest attribution needs, so no length of job
   title and no number of dots can collide with the quote. position:relative only so
   z-index still applies over the quote mark. */
.quotes-footer {
  position: relative;
  z-index: 2;
  padding: 0 var(--qc-pad) var(--qc-pad);
  display: flex;
  align-items: center;
  gap: clamp(1rem, 3vw, 2.5rem);
  pointer-events: none;
}

.quotes-attrs {
  flex: 1 1 auto;
  min-width: 0;
  display: grid;
  pointer-events: none;
}

.quotes-attrs > .quote-attr {
  grid-area: 1 / 1;
  opacity: 0;
  transition: opacity 0.45s ease;
  border-top: 0;
  padding-top: 0;
}

.quotes-attrs > .quote-attr.is-current { opacity: 1; }

@media (prefers-reduced-motion: reduce) {
  .quotes-attrs > .quote-attr { transition: none; }
}

/* The carousel gives a single quote the whole band, so it can afford a much
   louder headline than the same quote gets in a grid cell. */
.quotes-carousel .quote-headline {
  font-size: clamp(1.5rem, 3vw, 2.4rem);
  font-weight: 700;
  max-width: 24ch;
}

.quotes-carousel .quote-text { max-width: 62ch; }

/* The attribution scales with the card. At grid size it is a footnote; given the
   whole band it should read as a named person, so the name, role and avatar all
   step up rather than sitting at footnote size in a 24rem-tall card. */
.quotes-carousel-wrap .quote-attr { gap: 1rem; }

@media (max-width: 640px) {
  /* Not enough width to sit them side by side - stack instead. */
  .quotes-footer { flex-direction: column; align-items: flex-start; gap: 1.1rem; }
}
.quotes-carousel-wrap .attr-name { font-size: 1.0625rem; line-height: 1.35; }
.quotes-carousel-wrap .attr-role { font-size: 0.9rem; line-height: 1.45; }

.quotes-carousel-wrap .quote-photo,
.quotes-carousel-wrap .quote-initials {
  width: 75px;
  height: 75px;
}

/* Proportional to the 75px disc, matching the ratio the 38px grid variant uses
   (0.78rem at 38px). At 1rem the initials read as a small label inside a large
   circle rather than a stand-in for a face. */
.quotes-carousel-wrap .quote-initials { font-size: 1.5rem; }

@media (prefers-reduced-motion: reduce) {
  .quotes-carousel { scroll-behavior: auto; }
}

/* Positioning context for the inset controls. There was an edge-fade gradient here
   as a scroll hint, from before the carousel had any controls. With dots and arrows
   inside the card it was redundant, and a dark gradient running down the card's right
   edge read as an unwanted inner shadow, so it is gone. */
/* Container context so the fixed mark can size against the band, plus the
   positioning context the mark, attributions and controls all anchor to.
   The card background moves UP here: .quote-card is positioned and comes after the
   mark in the DOM, so its opaque background painted straight over the mark and hid
   it entirely. With the fill on the wrap and the cards transparent, the mark sits on
   the band and the sliding copy passes over it. */
.quotes-carousel-wrap {
  position: relative;
  container-type: inline-size;
  background: var(--denim);
  overflow: hidden;
  /* Two rows: the scroll track, then the attribution band. The quote mark is absolute
     and so creates no row of its own. --qc-pad lives here rather than on the card
     because the card and the footer must share one optical margin. */
  --qc-pad: clamp(2rem, 4.5vw, 4rem);
  display: grid;
  grid-template-rows: auto auto;
}

.quotes-carousel > .quote-card { background: transparent; }

/* Inside the card, bottom-right. Sitting below the track they added a band of dead
   space under the band and read as a detached toolbar; inset they belong to the quote
   they control. The attribution reserves room on its right so a long role cannot run
   underneath them. */
/* Sits on the attribution row, right-aligned. Offsets are derived from the card's
   own padding so the controls share the content's optical margin, and the +13px
   centres the 34px control cluster on the 60px avatar beside it rather than having
   it hang low. */
/* A dot per quote means the row's width is set by the content, not the design. With
   eight quotes it measured 278px inside a 264px card at 320px, and the wrap's
   overflow:hidden clipped the forward arrow off the page entirely - so the only
   control a 320px visitor could see went backwards. Bounded and wrapping, the row
   folds instead of being cut, and the band grows to fit it. */
.quotes-controls {
  /* Still never yields to the attribution beside it - a long role shrinks itself
     (min-width:0 on .quotes-attrs), exactly as before. max-width only binds when the
     row has the whole width to itself and STILL cannot fit, which is the stacked
     layout below 640px. That is where the dots fold, and nowhere else. */
  flex: none;
  max-width: 100%;
  display: flex;
  align-items: center;
  gap: 0.35rem;
  pointer-events: auto;
}

.quotes-arrow {
  /* Never absorb the shrink - a squashed arrow is a worse target than a folded dot
     row. The dots give instead. */
  flex: none;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  border: 1px solid var(--border);
  background: transparent;
  color: var(--text-2);
  font-size: 1rem;
  line-height: 1;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: color .2s, border-color .2s, background .2s;
}

.quotes-arrow:hover { color: var(--text-1); border-color: var(--text-3); background: var(--denim-mid); }
.quotes-arrow:focus-visible { outline: 2px solid var(--orange); outline-offset: 2px; }

/* The dots, not the arrows, are the part that grows with the quote count, so the dots
   are the part that gives. Shrinkable and wrapping, a long run folds to a second row
   between the two arrows instead of pushing the forward arrow off the band. */
.quotes-dots {
  display: flex;
  flex: 0 1 auto;
  min-width: 0;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 0.1rem;
  margin: 0 0.35rem;
}

/* 44px hit area around a small visual dot: the target stays accessible without a
   row of oversized circles dominating the band. */
.quotes-dot {
  width: 22px;
  height: 34px;
  padding: 0;
  border: 0;
  background: transparent;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
}

.quotes-dot::before {
  content: '';
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--text-3);
  opacity: .5;
  transition: opacity .2s, background .2s, transform .2s;
}

.quotes-dot:hover::before { opacity: .8; }
.quotes-dot.is-current::before { background: var(--orange); opacity: 1; transform: scale(1.4); }
.quotes-dot:focus-visible { outline: 2px solid var(--orange); outline-offset: -6px; border-radius: 50%; }

/* ── Solution / technology categories grid ──────────────────────────────── */
.categories-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 1px;
  background: var(--border);
  border: 1px solid var(--border);
}

.category-card {
  background: var(--denim-mid);
  padding: 1.5rem;
  display: flex;
  flex-direction: column;
  gap: 0.65rem;
  transition: background 0.2s;
}

.category-card:hover { background: var(--denim-raised); }

.category-icon {
  width: 36px;
  height: 36px;
  color: var(--orange);
}

.category-name {
  font-family: var(--f-display);
  font-size: 0.95rem;
  font-weight: 700;
  color: var(--text-1);
  line-height: 1.3;
}

.category-desc {
  font-size: 0.82rem;
  color: var(--text-3);
  line-height: 1.5;
  max-width: none;
}

/* ── Logo strip ─────────────────────────────────────────────────────────── */
.logos-band {
  background: var(--denim-mid);
  border-top: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
}

.logos-label {
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text-3);
  margin-bottom: 1.5rem;
  display: block;
}

.logos-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: clamp(1.5rem, 3vw, 3rem);
}

.logos-row img,
.logos-row svg {
  height: 64px;
  width: auto;
  max-width: 240px;
  opacity: 0.6;
  filter: brightness(0) invert(1);
  transition: opacity 0.2s;
}

.logos-row img:hover,
.logos-row svg:hover { opacity: 0.9; }

/* EPUT supplies a wide horizontal lockup rather than the stacked NHS format the
   other trusts use; scale it down so its visual weight reads as a peer, not a
   headline, in the logo row. */
.logos-row img[src*="eput"] { height: 46px; max-width: 200px; }

/* ── Logo strip with intro (logosIntro) ──────────────────────────────────────
   Pipeline strip: the band and label are shared with .logos-band above; these
   rules add the intro line and the per-entry sub-line. Entries become columns
   so a caption can sit under its mark, so the row aligns on the top edge
   rather than the centre used by the plain strip. */
/* The label + intro use the shared .section-head / .eyebrow / .lead treatment so
   this band reads as house style rather than a one-off. Only the band's own
   spacing is set here. */
.logos-band .section-head .lead { margin: 0; }

.logos-row-captioned { align-items: flex-start; }

/* Fixed column count. --logos-cols is set inline by the renderer; the row falls
   back to the wrapping flex layout above when Columns is left on 'auto'. */
/* Column count is authored per breakpoint; the renderer sets all three custom
   properties inline. Each tier falls back to the tier above it, so leaving tablet
   or mobile unset just inherits the wider setting rather than snapping to a
   hardcoded number. */
.logos-row-grid {
  display: grid;
  grid-template-columns: repeat(var(--logos-cols, 3), minmax(0, 1fr));
  align-items: start;
  justify-items: stretch;
}

@media (max-width: 900px) {
  .logos-row-grid {
    grid-template-columns: repeat(var(--logos-cols-tablet, var(--logos-cols, 3)), minmax(0, 1fr));
  }
}

@media (max-width: 600px) {
  .logos-row-grid {
    grid-template-columns: repeat(var(--logos-cols-mobile, var(--logos-cols-tablet, 2)), minmax(0, 1fr));
  }
}

/* No max-width: the mark should be free to use the full column, otherwise a wide
   grid leaves each logo stranded in a narrow strip at the left of a wide cell. */
.logos-item {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  /* Tight enough that the caption belongs to the mark above it. At 0.85rem the gap
     inside a figure matched the gap between figures, so the sites line read as a
     stray item in the grid rather than as that logo's caption. */
  gap: 0.4rem;
  margin: 0;
  width: 100%;
}

/* The shared .logos-row rule sizes any direct img/svg; inside a figure the mark
   needs the same treatment re-stated, since it is no longer a direct child. */
/* Height is set, not auto. These logos are SVGs carrying only a viewBox and no
   intrinsic width/height, so `height: auto` collapses them to the browser's default
   replaced-element size instead of filling anything. A set height also normalises
   marks whose aspect ratios vary enormously (1.64:1 to 3.9:1 across the current
   set) - sizing them by width instead would make the squarest logo tower over the
   widest. max-width keeps a very wide mark inside its column. */
.logos-item img {
  height: clamp(52px, 5.5vw, 76px);
  width: auto;
  max-width: 100%;
  object-fit: contain;
  object-position: left top;
  align-self: flex-start;
  /* Full white, not the 0.6 the plain strip uses. brightness(0) invert(1) already
     flattens the mark to white; the opacity on top was what made it read grey. */
  opacity: 1;
  filter: brightness(0) invert(1);
}

/* A caption naming the sites an ICB covers, not a section label. Set as a label -
   uppercase, tracked, 600, full white - it read as loud as the logo above it and
   wrapped to two lines in a grid cell ("SALISBURY | SWINDON | BATH"), which detached
   it from the mark it belongs to. Sentence case at the muted text colour fits on one
   line and reads as an annotation. Nudged up from 0.68rem because 10.88px was under
   the mobile reading floor; it still reads smaller, because the weight and the
   tracking were doing the shouting, not the size. */
.logos-sites {
  font-size: 0.75rem;
  font-weight: 500;
  letter-spacing: 0.01em;
  color: var(--text-2);
  line-height: 1.45;
}

@media (max-width: 520px) {
  .logos-item img { height: 48px; }
}

/* ── Events list ─────────────────────────────────────────────────────────── */
.events-band { border-top: 1px solid var(--border); }

.events-list { margin-top: 2.5rem; }

.event-row {
  display: grid;
  grid-template-columns: 180px 1fr auto;
  gap: 2rem;
  align-items: center;
  padding-block: 1.5rem;
  border-bottom: 1px solid var(--border);
}

.event-row:first-child { border-top: 1px solid var(--border); }

.event-date {
  font-family: var(--f-display);
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--orange);
  line-height: 1.4;
}

.event-name {
  font-family: var(--f-display);
  font-size: 1.05rem;
  font-weight: 700;
  color: var(--text-1);
  margin-bottom: 0.15rem;
}

.event-trust {
  font-size: 0.85rem;
  color: var(--text-3);
  max-width: none;
}

/* Nested instances for a multi-date SERIES card (API mode): each venue+date sits
   under the series name as a quiet sub-list. */
.event-instances {
  margin-top: 0.5rem;
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
  list-style: none;
  padding: 0;
}
.event-instances li {
  font-size: 0.82rem;
  color: var(--text-2);
  padding-left: 0.85rem;
  position: relative;
}
.event-instances li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.55em;
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: var(--orange);
}

/* Null-logo host in the trust strip (API mode): rendered as text, sized to peer
   with the logos beside it. */
.logos-textname {
  font-family: var(--f-display);
  font-weight: 700;
  font-size: 1rem;
  color: #fff;
  opacity: 0.6;
  max-width: 220px;
  line-height: 1.25;
}

@media (max-width: 640px) {
  .event-row { grid-template-columns: 1fr; gap: 0.5rem; }
}

/* Past events read as a compact archive, deliberately unlike the live event
   cards/rows above: a quiet, single-line list, not bookable hardware. */
.past-events {
  margin-top: 3.5rem;
  padding-top: 2rem;
  border-top: 1px solid var(--border);
}
.past-events .eyebrow { color: var(--text-3); }
.past-list {
  list-style: none;
  margin: 1rem 0 0;
  padding: 0;
  /* One shared grid for the whole list so every column aligns across rows.
     Each row (the <a>) spans all tracks and re-uses them via subgrid. */
  display: grid;
  grid-template-columns: max-content minmax(0, 1fr) max-content max-content;
  column-gap: 1.5rem;
}
.past-list li { display: contents; }
.past-item {
  display: grid;
  grid-column: 1 / -1;
  grid-template-columns: subgrid;
  align-items: baseline;
  row-gap: 0.35rem;
  padding: 0.85rem 0.25rem;
  border-top: 1px solid var(--border);
  text-decoration: none;
  color: var(--text-2);
  transition: color 0.15s ease, background 0.15s ease;
}
.past-list li:last-child .past-item { border-bottom: 1px solid var(--border); }
.past-item:hover { color: var(--text-1); background: rgba(255, 255, 255, 0.02); }
/* Static (non-linked) past entries: no clickable affordance. */
.past-item--static { cursor: default; }
.past-item--static:hover { color: var(--text-2); background: none; }
.past-item-meta {
  display: flex;
  align-items: center;
  gap: 0.6rem;
}
.past-item-tag {
  font-size: 0.6rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--text-3);
  border: 1px solid var(--border-light);
  border-radius: 999px;
  padding: 0.15rem 0.5rem;
  white-space: nowrap;
}
.past-item-date {
  font-size: 0.82rem;
  color: var(--text-3);
  white-space: nowrap;
}
.past-item-name { font-weight: 600; }
.past-item-trust {
  font-size: 0.88rem;
  color: var(--text-3);
}
.past-item-cta {
  font-size: 0.82rem;
  color: var(--text-3);
  white-space: nowrap;
}
.past-item:hover .past-item-cta { color: var(--orange-light); }
@media (max-width: 640px) {
  .past-list { grid-template-columns: 1fr; }
  .past-item {
    grid-template-columns: 1fr;
    gap: 0.15rem;
    padding: 1rem 0.25rem;
  }
  .past-item-cta { margin-top: 0.35rem; }
}

/* ── How it works steps ─────────────────────────────────────────────────── */
.steps-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 1px;
  background: var(--border);
  border: 1px solid var(--border);
  margin-top: 2.5rem;
}

.step-card {
  background: var(--denim);
  padding: clamp(1.75rem, 3vw, 2.5rem);
  display: flex;
  flex-direction: column;
  gap: 0.85rem;
}

.step-card:nth-child(even) { background: var(--denim-mid); }

.step-num {
  font-family: var(--f-display);
  font-size: 2.5rem;
  font-weight: 800;
  color: oklch(0.64 0.175 58 / 0.25);
  line-height: 1;
}

.step-title {
  font-family: var(--f-display);
  font-size: 1.05rem;
  font-weight: 700;
  color: var(--text-1);
  line-height: 1.3;
}

.step-body {
  font-size: 0.875rem;
  color: var(--text-2);
  line-height: 1.6;
  max-width: none;
}

/* ── CTA band ────────────────────────────────────────────────────────────── */
.cta-band { background: var(--orange); }

.cta-inner {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 3rem;
  align-items: center;
}

.cta-inner h2 {
  font-family: var(--f-display);
  font-size: clamp(1.35rem, 2.3vw, 1.9rem);
  font-weight: 700;
  color: var(--denim-deep);
  line-height: 1.25;
  margin-bottom: 0.5rem;
}

.cta-inner p {
  font-size: 0.95rem;
  color: oklch(0.25 0.04 240);
  max-width: 55ch;
}

/* The CTA band is the one place an inline quote lands on ORANGE rather than the
   dark denim ground. Everything the default treatment relies on breaks here: the
   orange rule disappears into the background, and --text-1/--text-2 are tuned for
   a dark ground so they wash out. The band is already dark-on-orange - its heading
   is --denim-deep - so the quote joins that, rather than importing the dark-ground
   palette onto a light one. */
.cta-band .inline-quote {
  border-left-color: var(--denim-deep);
  max-width: 54ch;
  margin-top: 1.25rem;
}
.cta-band .inline-quote blockquote {
  color: var(--denim-deep);
  font-size: clamp(0.98rem, 1.3vw, 1.1rem);
}
.cta-band .inline-quote .attr-name { color: var(--denim-deep); }
.cta-band .inline-quote .attr-role { color: oklch(0.32 0.04 240); }
/* Initials fallback: a light disc with dark type, the inverse of the dark-ground
   version, so a quote without a photo still reads here. */
.cta-band .inline-quote .quote-initials {
  background: oklch(0.92 0.03 60);
  color: var(--denim-deep);
}

/* A quote makes the left column much taller than the button, and a vertically
   centred button then floats mid-band with nothing beside it. Sit it with the
   heading instead. */
.cta-inner:has(.inline-quote) { align-items: start; }

@media (max-width: 640px) { .cta-inner { grid-template-columns: 1fr; gap: 1.5rem; } }

/* ── Pricing block ──────────────────────────────────────────────────────── */
.pricing-band { background: var(--denim-mid); border-top: 1px solid var(--border); }

/* Heading: centred over a single offer, left-aligned above a comparison grid. */
.pricing-head { margin-bottom: 2.5rem; }
.pricing-head .section-h2 { margin-top: 0.5rem; }
.pricing-lead { color: var(--text-2); margin-top: 0.75rem; max-width: 62ch; }
.pricing-head--center { text-align: center; max-width: 46rem; margin-inline: auto; }
.pricing-head--center .pricing-lead { margin-inline: auto; }

/* ── Comparison grid (2+ packages) ──────────────────────────────────────── */
.pricing-grid {
  display: grid;
  grid-template-columns: repeat(var(--cols, 2), minmax(0, 1fr));
  gap: 1px;
  background: var(--border);
  border: 1px solid var(--border);
}
@media (max-width: 720px) { .pricing-grid { grid-template-columns: 1fr; } }

.pricing-card {
  background: var(--denim);
  padding: clamp(2rem, 4vw, 3rem);
  border-top: 3px solid transparent;   /* reserve the top-rule space so the featured card stays aligned */
}
.pricing-card--featured { background: var(--denim-raised); border-top-color: var(--orange); }

/* ── Single offer: package + add-on unified in one card ─────────────────── */
.pricing-solo { max-width: 46rem; margin-inline: auto; }
.offer-card {
  background: var(--denim);
  border: 1px solid var(--border);
  border-top: 3px solid var(--orange);   /* signature accent rule */
}
.offer-body { padding: clamp(2rem, 4.5vw, 3rem); }
.offer-headline { margin-bottom: 1.75rem; }
.offer-headline .pricing-desc { margin-bottom: 0; }

.pricing-amount {
  font-family: var(--f-display);
  font-size: clamp(2.2rem, 4vw, 3.2rem);
  font-weight: 800;
  color: var(--text-1);
  line-height: 1;
  margin-bottom: 0.25rem;
}
.pricing-amount--lg { font-size: clamp(2.9rem, 6vw, 4rem); }
.pricing-amount span { font-size: 1rem; font-weight: 400; color: var(--text-3); }

.pricing-desc {
  font-size: 0.875rem;
  color: var(--text-2);
  margin-bottom: 1.75rem;
  max-width: none;
}

/* Includes in two columns inside the solo card; arrow bullets + spacing carry the
   rhythm, so no per-row dividers here. */
.benefit-list--cols {
  display: grid;
  grid-template-columns: 1fr 1fr;
  column-gap: clamp(1.5rem, 4vw, 3.5rem);
}
.benefit-list--cols li { border-bottom: none; padding-block: 0.5rem; }
@media (max-width: 560px) { .benefit-list--cols { grid-template-columns: 1fr; } }

/* Add-on as a divided lower section of the same card */
.offer-addon {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 1.25rem;
  padding: clamp(1.5rem, 4vw, 2rem) clamp(2rem, 4.5vw, 3rem);
  border-top: 1px solid var(--border);
  background: var(--denim-deep);
}
.offer-addon-info { flex: 1 1 20rem; min-width: 0; }
.offer-addon-title { font-family: var(--f-display); font-size: 1.05rem; font-weight: 700; color: var(--text-1); }
.offer-addon-desc { font-size: 0.85rem; color: var(--text-2); margin-top: 0.25rem; max-width: 46ch; }

.offer-cta { text-align: center; margin-top: 2rem; }

/* Larger CTA for the focused single-offer */
.btn-lg { padding: 0.95rem 2rem; font-size: 1rem; }

/* ── Contact strip ──────────────────────────────────────────────────────── */
.contact-strip {
  background: var(--denim-mid);
  border-top: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
}

.contact-person {
  display: flex;
  align-items: center;
  gap: 0.9rem;
  margin-top: 2rem;
  padding-bottom: 1.5rem;
  border-bottom: 1px solid var(--border);
}
.contact-person .ch-label {
  display: block;
  font-size: 0.78rem; font-weight: 700; letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--text-3); margin-bottom: 0.35rem;
}

.contact-avatar {
  width: 54px;
  height: 54px;
  border-radius: 50%;
  object-fit: cover;
  flex-shrink: 0;
  background: var(--denim-raised);
}

.contact-name {
  font-family: var(--f-display);
  font-size: 1rem;
  font-weight: 700;
  color: var(--text-1);
  margin-bottom: 0.1rem;
}

.contact-role { font-size: 0.82rem; color: var(--text-3); }

.contact-links {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  margin-top: 0.75rem;
}

.contact-links a {
  font-size: 0.85rem;
  color: var(--orange);
  text-decoration: none;
  transition: opacity 0.2s;
}

.contact-links a:hover { opacity: 0.75; }

/* ── Related events strip ───────────────────────────────────────────────── */
.related-events {
  border-top: 1px solid var(--border);
}

.related-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: 1px;
  background: var(--border);
  border: 1px solid var(--border);
  margin-top: 2rem;
}

.related-card {
  background: var(--denim-mid);
  padding: clamp(1.5rem, 3vw, 2rem);
  text-decoration: none;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  transition: background 0.2s;
}

.related-card:hover { background: var(--denim-raised); }

.related-date {
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--orange);
}

.related-name {
  font-family: var(--f-display);
  font-size: 1.1rem;
  font-weight: 700;
  color: var(--text-1);
  line-height: 1.2;
}

.related-trust { font-size: 0.82rem; color: var(--text-3); }

/* ── Venue / hospital cards ─────────────────────────────────────────────── */
.venues-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 14px;
  margin-top: 2.5rem;
}
@media (max-width: 920px) { .venues-grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 540px) { .venues-grid { grid-template-columns: 1fr; } }

.venue-card {
  display: flex;
  flex-direction: column;
  background: var(--denim-mid);
  border: 1px solid var(--border);
  border-radius: 10px;
  overflow: hidden;
  transition: background 0.2s, border-color 0.2s, transform 0.28s var(--ease-out-quart), box-shadow 0.28s;
}
.venue-card:hover { background: var(--denim-raised); border-color: var(--border-light); }

.venue-img {
  aspect-ratio: 16 / 9;
  background: var(--denim-deep);
  border-bottom: 4px solid var(--vc, var(--orange));
  overflow: hidden;
}
.venue-img img { width: 100%; height: 100%; object-fit: cover; display: block; }

.venue-img-logo {
  display: flex;
  align-items: center;
  justify-content: center;
  background: #005eb8;
  padding: 18px 24px;
}
.venue-img-logo img { width: auto; max-width: 80%; max-height: 64%; object-fit: contain; }

.venue-body { display: flex; flex-direction: column; flex: 1; padding: 16px 18px 18px; }

.venue-date {
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--vc, var(--orange));
  margin-bottom: 6px;
}
.venue-date-tbc { color: var(--text-3); }

.venue-name {
  font-family: var(--f-display);
  font-size: 1.05rem;
  font-weight: 700;
  color: var(--text-1);
  line-height: 1.2;
  margin: 0 0 3px;
}
.venue-trust { font-size: 0.74rem; color: var(--text-3); margin-bottom: 10px; line-height: 1.4; }
.venue-desc { font-size: 0.84rem; line-height: 1.6; color: var(--text-2); margin: 0; }

/* ── Footer ─────────────────────────────────────────────────────────────── */
.site-footer {
  background: var(--denim-deep);
  border-top: 1px solid var(--border);
}

.footer-grid {
  display: grid;
  grid-template-columns: 1.4fr 1fr 1fr;
  gap: clamp(2rem, 5vw, 4rem);
}

@media (max-width: 700px) { .footer-grid { grid-template-columns: 1fr; gap: 2rem; } }

.footer-logo     { height: 26px; margin-bottom: 1rem; }
/* Footer copy sat on --text-3 (oklch .52) against --denim-deep (oklch .18). That is
   thin contrast for body text, and the muted tone read as washed out rather than
   deliberately quiet. Lifted a tier to --text-2; the base line keeps a slightly
   quieter tone but is no longer the dimmest token available. */
.footer-tagline  { font-size: 0.85rem; color: var(--text-2); line-height: 1.6; margin-bottom: 0.75rem; }
/* The tagline is two paragraphs, one per audience. A paragraph gap of the full
   1.25rem reads as a blank line at this size, so only the last one keeps the
   larger gap that separates the block from the social row. */
.footer-tagline:last-of-type { margin-bottom: 1.25rem; }

.footer-social   { display: flex; gap: 0.5rem; flex-wrap: wrap; }
.footer-social a { font-size: 0.8rem; color: var(--text-2); text-decoration: none; transition: color 0.2s; }
.footer-social a:hover { color: var(--text-1); }
.footer-social span { color: var(--border); }

.footer-nav-label {
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--text-3);
  margin-bottom: 1rem;
  display: block;
}

.footer-nav-list { display: flex; flex-direction: column; gap: 0.5rem; }
.footer-nav-list a { font-size: 0.875rem; color: var(--text-2); text-decoration: none; transition: color 0.2s; }
.footer-nav-list a:hover { color: var(--text-1); }

.footer-base {
  margin-top: 3.5rem;
  padding-top: 1.5rem;
  border-top: 1px solid var(--border);
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 0.75rem;
}

.footer-base p   { font-size: 0.775rem; color: var(--text-2); max-width: none; }
.footer-base a   { color: var(--text-2); text-decoration: none; }
.footer-base a:hover { color: var(--text-1); }

/* ── Motion tokens ──────────────────────────────────────────────────────── */
:root {
  --ease-out-quart: cubic-bezier(0.25, 1, 0.5, 1);
  --ease-out-quint: cubic-bezier(0.22, 1, 0.36, 1);
  --ease-out-expo:  cubic-bezier(0.16, 1, 0.3, 1);
}

/* ── Scroll reveal ──────────────────────────────────────────────────────── */
@media (prefers-reduced-motion: no-preference) {
  .reveal {
    opacity: 0;
    transform: translateY(20px);
    transition: opacity 0.6s var(--ease-out-quint), transform 0.6s var(--ease-out-quint);
  }
  .reveal.in { opacity: 1; transform: none; }
  .reveal-d1 { transition-delay: 0.08s; }
  .reveal-d2 { transition-delay: 0.16s; }
  .reveal-d3 { transition-delay: 0.24s; }
}

/* ── Motion layer (shared across all pages) ─────────────────────────────────
   Purposeful enhancements layered on the existing reveal system. Everything
   that moves an element is gated behind prefers-reduced-motion: no-preference;
   colour/border feedback stays for everyone. */

/* Hero entrance choreography - the signature on-load moment. Hero copy rises in
   sequence (crumbs/eyebrow -> heading -> sub -> CTAs) the first time the page
   paints. Above the fold, so it plays on load rather than on scroll. */
@media (prefers-reduced-motion: no-preference) {
  @keyframes hero-rise {
    from { opacity: 0; transform: translateY(24px); }
    to   { opacity: 1; transform: none; }
  }
  .hero-content > *,
  .page-hero-content > * {
    animation: hero-rise 0.7s var(--ease-out-quint) both;
  }
  .hero-content > *:nth-child(1), .page-hero-content > *:nth-child(1) { animation-delay: 0.05s; }
  .hero-content > *:nth-child(2), .page-hero-content > *:nth-child(2) { animation-delay: 0.15s; }
  .hero-content > *:nth-child(3), .page-hero-content > *:nth-child(3) { animation-delay: 0.25s; }
  .hero-content > *:nth-child(4), .page-hero-content > *:nth-child(4) { animation-delay: 0.35s; }
  .hero-content > *:nth-child(5), .page-hero-content > *:nth-child(5) { animation-delay: 0.45s; }
  .hero-content > *:nth-child(6), .page-hero-content > *:nth-child(6) { animation-delay: 0.55s; }

  /* Hero photo is slightly oversized so the JS parallax has headroom to travel
     without ever exposing an edge (see assets/js/elevate.js). */
  .hero-photo {
    transform: scale(1.14);
    transform-origin: center;
    will-change: transform;
  }
}

/* Button feedback - lift on hover, press down on click. */
.btn { transition: background 0.2s, color 0.2s, border-color 0.2s, transform 0.16s var(--ease-out-quart), box-shadow 0.2s; }
@media (prefers-reduced-motion: no-preference) {
  .btn-primary:hover,
  .btn-ghost:hover,
  .btn-outline-orange:hover,
  .btn-dark:hover { transform: translateY(-2px); }
  .btn-primary:hover { box-shadow: 0 8px 22px oklch(0.64 0.175 58 / 0.32); }
  .btn:active { transform: translateY(0) scale(0.97); transition-duration: 0.06s; }
}

/* Card lift - related/event cards read as liftable surfaces. */
.related-card { transition: background 0.2s, border-color 0.2s, transform 0.28s var(--ease-out-quart), box-shadow 0.28s; }
@media (prefers-reduced-motion: no-preference) {
  .related-card:hover { transform: translateY(-4px); box-shadow: 0 14px 34px oklch(0.10 0.03 240 / 0.45); }
}

/* Nav links - underline wipes in from the left on hover / current page. */
.nav-links a { position: relative; }
@media (prefers-reduced-motion: no-preference) {
  .nav-links a::after {
    content: '';
    position: absolute;
    left: 0; right: 0; bottom: -5px;
    height: 2px;
    background: var(--orange);
    transform: scaleX(0);
    transform-origin: left center;
    transition: transform 0.28s var(--ease-out-quart);
  }
  .nav-links a:hover::after,
  .nav-links a[aria-current="page"]::after { transform: scaleX(1); }
}

/* Feature media - gentle zoom when the row is hovered. */
.feature-media { overflow: hidden; }
@media (prefers-reduced-motion: no-preference) {
  .feature-media img { transition: transform 0.6s var(--ease-out-quart); }
  .feature-row:hover .feature-media img { transform: scale(1.045); }
}

/* ════════════════════════════════════════════════════════════════════════
   ADDITIONS FOR MULTI-PAGE ELEVATE SITE
   Mobile nav, sub-page hero, section heads, process timeline, FAQ,
   stats band, contact form, thank-you. All built on the tokens above.
   ════════════════════════════════════════════════════════════════════════ */

/* ── Mobile nav ─────────────────────────────────────────────────────────── */
.nav-toggle {
  display: none;
  margin-left: auto;
  width: 44px;
  height: 44px;
  align-items: center;
  justify-content: center;
  color: var(--text-1);
  flex-shrink: 0;
}

.nav-toggle svg { width: 24px; height: 24px; }
.nav-toggle .icon-close { display: none; }
.nav-toggle[aria-expanded="true"] .icon-open { display: none; }
.nav-toggle[aria-expanded="true"] .icon-close { display: block; }

.mobile-nav {
  position: fixed;
  inset: 68px 0 auto;
  z-index: 190;
  background: oklch(0.18 0.035 240 / 0.98);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border-bottom: 1px solid var(--border);
  padding: 1.25rem clamp(1.5rem, 5vw, 4rem) 2rem;
  transform: translateY(-12px);
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.25s, transform 0.25s, visibility 0.25s;
}

.mobile-nav.open { transform: none; opacity: 1; visibility: visible; }

.mobile-nav ul { display: flex; flex-direction: column; }

.mobile-nav a {
  display: block;
  padding: 0.9rem 0;
  font-family: var(--f-display);
  font-size: 1.15rem;
  font-weight: 600;
  color: var(--text-2);
  text-decoration: none;
  border-bottom: 1px solid var(--border);
  transition: color 0.2s;
}

.mobile-nav a:hover,
.mobile-nav a[aria-current="page"] { color: var(--text-1); }
/* The mobile CTA is a .btn, but it is also an <a> inside .mobile-nav, and
   `.mobile-nav a` (0,1,1) outranks `.btn` / `.btn-primary` (0,1,0). Without
   this it inherits display:block, flush-left padding, the muted link colour and
   the hairline underline, so justify-content never applies and it renders as a
   flat orange bar with left-aligned text. Restore the button box. */
.mobile-nav .btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  margin-top: 1.5rem;
  padding: 0.9rem 1.65rem;
  color: var(--denim-deep);
  border: 2px solid var(--orange);
  border-radius: 3px;
}

@media (max-width: 860px) {
  .nav-links { display: none; }
  .nav-cta { display: none; }
  .nav-toggle { display: flex; }
}

/* Above the breakpoint the desktop nav is back, so the mobile panel must never
   render - even if it was left open when the window was resized. The JS also
   closes it (restoring aria-expanded and body scroll); this is the guarantee that
   it cannot be seen regardless. */
@media (min-width: 861px) {
  .mobile-nav,
  .mobile-nav.open { display: none; }
}

/* ── Sub-page hero (shorter than program hub hero) ──────────────────────── */
.page-hero {
  position: relative;
  padding: clamp(8rem, 18vh, 11rem) clamp(1.5rem, 5vw, 4rem) clamp(3rem, 7vh, 5rem);
  overflow: hidden;
  border-bottom: 1px solid var(--border);
}

.page-hero-content { position: relative; z-index: 1; max-width: 1200px; margin-inline: auto; }

.page-hero h1 {
  font-family: var(--f-display);
  font-size: clamp(2.4rem, 5.5vw, 4rem);
  font-weight: 800;
  line-height: 1.04;
  letter-spacing: -0.025em;
  color: var(--text-1);
  max-width: 16ch;
  margin-bottom: 1.25rem;
}

.page-hero h1 em { font-style: italic; color: var(--orange); }

.page-hero-sub {
  font-size: clamp(1rem, 1.7vw, 1.2rem);
  color: var(--text-2);
  line-height: 1.6;
  max-width: 56ch;
  margin-bottom: 2.5rem;
}

.page-hero .hero-ctas { display: flex; flex-wrap: wrap; gap: 0.85rem; }

/* ── Breadcrumb ─────────────────────────────────────────────────────────── */
.crumbs {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.78rem;
  color: var(--text-2);
  margin-bottom: 1.5rem;
}
.crumbs a { color: var(--text-2); text-decoration: none; transition: color 0.2s; }
.crumbs a:hover { color: var(--text-1); }
.crumbs span[aria-hidden] { color: var(--border-light); }

/* ── Section head helper ────────────────────────────────────────────────── */
.section-head { max-width: 720px; margin-bottom: clamp(2rem, 4vw, 3rem); }
.section-head .section-h2 { margin-bottom: 0.85rem; }
.section-head .lead { font-size: 1.05rem; color: var(--text-2); line-height: 1.7; }

/* ── Alternating feature rows ───────────────────────────────────────────── */
/* ─── Inline quote ────────────────────────────────────────────────────────────
   A quote set beside the claim it evidences - inside a feature row, or under a
   stats band - rather than gathered into a block people scroll past.

   Deliberately NOT a card: a second card inside a feature row would compete with
   the row for weight. An orange rule down the left carries it instead, which is
   the same accent the section heads already use, and the attribution reuses the
   quote-card markup so a face here matches a face there. */
.inline-quote {
  margin: 1.5rem 0 0;
  padding: 0 0 0 1.15rem;
  border-left: 2px solid var(--orange);
}
.inline-quote blockquote {
  margin: 0 0 0.85rem;
  font-family: var(--f-display);
  font-size: clamp(1.02rem, 1.5vw, 1.2rem);
  font-weight: 500;
  line-height: 1.45;
  color: var(--text-1);
  text-wrap: pretty;
}
.inline-quote blockquote::before { content: '\201C'; }
.inline-quote blockquote::after  { content: '\201D'; }
.inline-quote .quote-attr { border-top: none; padding-top: 0; gap: 0.7rem; }

/* On the stats band the quote sits under a full-width grid, so it needs a measure
   of its own or it runs the width of the viewport. */
.stats-band .inline-quote {
  margin-top: clamp(1.75rem, 3vw, 2.5rem);
  max-width: 62ch;
}

@media (max-width: 720px) {
  .inline-quote { margin-top: 1.25rem; padding-left: 0.9rem; }
}


.feature-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(2rem, 5vw, 4.5rem);
  align-items: center;
  padding-block: clamp(2.5rem, 5vw, 4rem);
  border-bottom: 1px solid var(--border);
}
.feature-row:last-child { border-bottom: none; }
.feature-row.flip .feature-media { order: -1; }

.feature-row h3 {
  font-family: var(--f-display);
  font-size: clamp(1.5rem, 2.6vw, 2.1rem);
  font-weight: 700;
  line-height: 1.15;
  margin-bottom: 1rem;
}
.feature-row p { color: var(--text-2); line-height: 1.7; }

.feature-media {
  background: var(--denim-mid);
  border: 1px solid var(--border);
  border-radius: 6px;
  aspect-ratio: 4 / 3;
  overflow: hidden;
}
.feature-media img { width: 100%; height: 100%; object-fit: cover; }

@media (max-width: 800px) {
  .feature-row { grid-template-columns: 1fr; gap: 1.75rem; }
  .feature-row.flip .feature-media { order: 0; }
}

/* ── Process timeline (vertical numbered) ───────────────────────────────── */
.timeline {
  display: flex;
  flex-direction: column;
  margin-top: 2.5rem;
  counter-reset: step;
}

.timeline-step {
  display: grid;
  grid-template-columns: 4rem 1fr;
  gap: 1.5rem;
  padding-bottom: 2.25rem;
  position: relative;
}

.timeline-step::before {
  counter-increment: step;
  content: counter(step, decimal-leading-zero);
  font-family: var(--f-display);
  font-size: 1.05rem;
  font-weight: 800;
  color: var(--orange);
  width: 4rem;
  height: 4rem;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--border-light);
  border-radius: 50%;
  background: var(--denim);
  flex-shrink: 0;
  z-index: 1;
}

.timeline-step:not(:last-child)::after {
  content: '';
  position: absolute;
  left: 2rem;
  top: 4rem;
  bottom: 0;
  width: 1px;
  background: var(--border);
}

.timeline-step h3 {
  font-family: var(--f-display);
  font-size: 1.15rem;
  font-weight: 700;
  color: var(--text-1);
  margin-bottom: 0.4rem;
  padding-top: 1.1rem;
  grid-column: 2;
}
.timeline-step p { color: var(--text-2); line-height: 1.65; font-size: 0.95rem; grid-column: 2; }

@media (max-width: 560px) {
  .timeline-step { grid-template-columns: 3rem 1fr; gap: 1rem; }
  .timeline-step::before { width: 3rem; height: 3rem; font-size: 0.9rem; }
  .timeline-step:not(:last-child)::after { left: 1.5rem; top: 3rem; }
  .timeline-step h3 { padding-top: 0.65rem; }
}

/* ── Stats band (big numbers) ───────────────────────────────────────────── */
.stats-band { background: var(--denim-deep); border-block: 1px solid var(--border); }
.stats-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 1px;
  background: var(--border);
  border: 1px solid var(--border);
}
.stat { background: var(--denim-deep); padding: clamp(1.5rem, 3vw, 2.4rem); min-width: 0; }
.stat-num {
  font-family: var(--f-display);
  font-size: clamp(2rem, 3.2vw, 3rem);
  font-weight: 800;
  line-height: 1;
  color: var(--orange);
  letter-spacing: -0.03em;
  margin-bottom: 0.6rem;
  font-variant-numeric: tabular-nums;
  overflow-wrap: break-word;
}
.stat-label { font-size: 0.9rem; color: var(--text-2); line-height: 1.5; max-width: 28ch; }

/* ── Pricing extras ─────────────────────────────────────────────────────── */
.price-label {
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--orange);
  margin-bottom: 1rem;
}
.pricing-amount .vat { font-size: 1rem; font-weight: 400; color: var(--text-3); }

.addon-band {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
  margin-top: 1px;
  padding: clamp(1.5rem, 3vw, 2rem);
  background: var(--denim);
  border: 1px solid var(--border);
  border-top: none;
}
.addon-tag {
  display: inline-block;
  font-size: 0.62rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--text-3);
  border: 1px solid var(--border-light);
  border-radius: 100px;
  padding: 0.2rem 0.65rem;
  margin-bottom: 0.6rem;
}
.addon-band h3 { font-family: var(--f-display); font-size: 1.1rem; font-weight: 700; color: var(--text-1); margin-bottom: 0.3rem; }
.addon-band p { font-size: 0.9rem; color: var(--text-2); max-width: 48ch; }
.addon-price { font-family: var(--f-display); font-size: 1.9rem; font-weight: 800; color: var(--text-1); white-space: nowrap; }
.addon-price .vat { display: block; font-size: 0.7rem; font-weight: 400; color: var(--text-3); text-align: right; }

/* ── FAQ accordion ──────────────────────────────────────────────────────── */
.faq-list { border-top: 1px solid var(--border); margin-top: 2rem; }
.faq-item { border-bottom: 1px solid var(--border); }

.faq-q {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
  padding: 1.4rem 0;
  text-align: left;
  font-family: var(--f-display);
  font-size: clamp(1rem, 1.8vw, 1.2rem);
  font-weight: 600;
  color: var(--text-1);
  background: none;
  border: none;
}
.faq-q:hover { color: var(--orange); }

.faq-icon {
  flex-shrink: 0;
  width: 22px;
  height: 22px;
  position: relative;
  transition: transform 0.25s;
}
.faq-icon::before,
.faq-icon::after {
  content: '';
  position: absolute;
  background: var(--orange);
  border-radius: 2px;
  inset: 0;
  margin: auto;
}
.faq-icon::before { width: 100%; height: 2px; }
.faq-icon::after { width: 2px; height: 100%; transition: transform 0.25s; }
.faq-q[aria-expanded="true"] .faq-icon::after { transform: scaleY(0); }

.faq-a {
  max-height: 0;
  overflow: hidden;
  transition: max-height 0.3s ease;
}
.faq-a-inner { padding: 0 0 1.5rem; color: var(--text-2); line-height: 1.7; max-width: 70ch; }
.faq-a-inner p + p { margin-top: 0.85rem; }
.faq-a-inner a { color: var(--orange); text-decoration: underline; text-underline-offset: 2px; }

/* ── Contact / form ─────────────────────────────────────────────────────── */
.contact-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(2.5rem, 5vw, 5rem);
  align-items: start;
}
@media (max-width: 800px) { .contact-grid { grid-template-columns: 1fr; gap: 2.5rem; } }

.contact-channels { display: flex; flex-direction: column; gap: 1.5rem; margin-top: 2rem; }
/* The last channel's rule used to close the group and orphan whatever followed. */
.contact-channel:last-child { border-bottom: 0; padding-bottom: 0; }
.contact-channel {
  display: flex;
  gap: 1rem;
  align-items: flex-start;
  padding-bottom: 1.5rem;
  border-bottom: 1px solid var(--border);
}
.contact-channel svg { width: 22px; height: 22px; color: var(--orange); flex-shrink: 0; margin-top: 0.2rem; }
.contact-channel .ch-label { font-size: 0.78rem; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; color: var(--text-3); margin-bottom: 0.25rem; }
.contact-channel a { color: var(--text-1); text-decoration: none; font-size: 1.05rem; }
.contact-channel a:hover { color: var(--orange); }

.form-grid { display: flex; flex-direction: column; gap: 1.1rem; }
.form-row { display: grid; grid-template-columns: 1fr 1fr; gap: 1.1rem; }
@media (max-width: 540px) { .form-row { grid-template-columns: 1fr; } }

.field { display: flex; flex-direction: column; gap: 0.4rem; }
.field label { font-size: 0.82rem; font-weight: 600; color: var(--text-2); }
.field input,
.field select,
.field textarea {
  font-family: var(--f-body);
  font-size: 1rem;
  color: var(--text-1);
  background: var(--denim-deep);
  border: 1px solid var(--border-light);
  border-radius: 4px;
  padding: 0.75rem 0.9rem;
  appearance: none;
  -webkit-appearance: none;
  box-shadow: none;
  transition: border-color 0.2s;
  width: 100%;
}
.field textarea { resize: vertical; min-height: 120px; }
.field input::placeholder,
.field textarea::placeholder { color: var(--text-3); }
.field input:focus,
.field select:focus,
.field textarea:focus { outline: none; border-color: var(--orange); }
.field select { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23ED8B00' stroke-width='2'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E"); background-repeat: no-repeat; background-position: right 0.75rem center; background-size: 18px; padding-right: 2.5rem; }
.form-note { font-size: 0.78rem; color: var(--text-3); }

/* ── Confirmation / thank-you ───────────────────────────────────────────── */
.confirm {
  min-height: 80svh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: clamp(7rem, 16vh, 10rem) clamp(1.5rem, 5vw, 4rem) clamp(4rem, 8vh, 6rem);
}
.confirm-check {
  width: 72px;
  height: 72px;
  border-radius: 50%;
  border: 2px solid var(--orange);
  display: flex;
  align-items: center;
  justify-content: center;
  margin-bottom: 2rem;
  color: var(--orange);
}
.confirm-check svg { width: 34px; height: 34px; }
.confirm h1 {
  font-family: var(--f-display);
  font-size: clamp(2rem, 4.5vw, 3rem);
  font-weight: 800;
  line-height: 1.1;
  letter-spacing: -0.02em;
  margin-bottom: 1rem;
  max-width: 18ch;
}
.confirm p { color: var(--text-2); line-height: 1.7; max-width: 52ch; margin-bottom: 2rem; }
.confirm .hero-ctas { display: flex; flex-wrap: wrap; gap: 0.85rem; justify-content: center; }

/* ── Inline CTA helper (centered band) ──────────────────────────────────── */
.cta-center { text-align: center; max-width: 640px; margin-inline: auto; }
.cta-center h2 {
  font-family: var(--f-display);
  font-size: clamp(1.8rem, 3.5vw, 2.6rem);
  font-weight: 800;
  line-height: 1.15;
  letter-spacing: -0.02em;
  margin-bottom: 1rem;
}
.cta-center p { color: var(--text-2); line-height: 1.7; margin: 0 auto 2rem; }
.cta-center .hero-ctas { justify-content: center; display: flex; flex-wrap: wrap; gap: 0.85rem; }

/* ── Technology x location matrix (techMatrix block) ────────────────────────── */
.tm-wrap { overflow-x: auto; margin-top: 2.5rem; border: 1px solid var(--border); border-radius: 6px; }
.tm { width: 100%; border-collapse: collapse; min-width: 640px; }
.tm th, .tm td { padding: 0.85rem 1rem; text-align: center; border-bottom: 1px solid var(--border); border-right: 1px solid var(--border); }
.tm thead th { background: var(--denim-deep); vertical-align: bottom; }
.tm-ev { display: block; font-family: var(--f-display); font-weight: 700; font-size: 0.95rem; color: var(--text-1); line-height: 1.2; }
.tm-evsub { display: block; font-size: 0.72rem; color: var(--text-3); margin-top: 0.15rem; }
.tm-rowhead { text-align: left; font-weight: 600; color: var(--text-1); font-size: 0.92rem; background: var(--denim); position: sticky; left: 0; z-index: 1; min-width: 200px; }
.tm tbody tr:nth-child(even) th.tm-rowhead { background: var(--denim-mid); }
.tm tbody tr:nth-child(even) td { background: oklch(0.30 0.042 240 / 0.35); }
.tm th:last-child, .tm td:last-child { border-right: none; }
.tm tbody tr:last-child th, .tm tbody tr:last-child td { border-bottom: none; }
.tm-yes { display: inline-block; width: 15px; height: 15px; border-radius: 50%; background: var(--orange); }
.tm-no { display: inline-block; width: 14px; height: 4px; border-radius: 3px; background: var(--border-light); opacity: 0.55; }

/* Host lockup (two trust logos, e.g. Essex = MSE + EPUT). Logos differ wildly in
   aspect ratio (a compact stacked mark vs a long wordmark), so balance by a shared
   bounding box - cap BOTH height and width - to even their optical size. */
.host-lockup { display: flex; flex-wrap: wrap; align-items: center; gap: clamp(2rem, 5vw, 3.5rem); margin-top: 1.25rem; }
.host-lockup img { height: auto; width: auto; max-height: 76px; max-width: 200px; }
@media (max-width: 520px) { .host-lockup img { max-height: 56px; max-width: 150px; } }

/* ── Partner band (e.g. Collaborating with Insight) ─────────────────────────── */
.partner-band { background: var(--denim-mid); border-top: 1px solid var(--border); }
.partner-grid { display: grid; grid-template-columns: 300px 1fr; gap: clamp(2rem, 5vw, 4rem); align-items: start; margin-top: 1rem; }
.partner-logo {
  display: flex;
  align-items: center;
  justify-content: flex-start;
}
.partner-logo img { max-height: 88px; max-width: 100%; width: auto; }
.partner-name { font-family: var(--f-display); font-weight: 800; font-size: 2.2rem; color: var(--text-1); letter-spacing: -0.02em; }
.partner-body { color: var(--text-2); line-height: 1.75; font-size: 1.02rem; max-width: 60ch; }
@media (max-width: 760px) { .partner-grid { grid-template-columns: 1fr; } .partner-logo { min-height: 100px; } }

/* ── Rich text prose (richtext block body) ──────────────────────────────── */
.rich-body { color: var(--text-2); line-height: 1.75; max-width: 68ch; font-size: 1.02rem; }
.rich-body > * + * { margin-top: 1.15rem; }
.rich-body p { max-width: none; }
.rich-body strong { color: var(--text-1); font-weight: 700; }
.rich-body a { color: var(--orange-light); text-decoration: underline; text-underline-offset: 2px; }
.rich-body h3 { font-family: var(--f-display); font-weight: 700; color: var(--text-1); font-size: 1.2rem; margin-top: 1.75rem; }
.rich-body ul { list-style: none; display: flex; flex-direction: column; gap: 0.7rem; }
.rich-body ul li { position: relative; padding-left: 1.5rem; }
.rich-body ul li::before {
  content: ""; position: absolute; left: 0; top: 0.62em;
  width: 0.5rem; height: 0.5rem; border-radius: 50%;
  background: var(--orange); transform: translateY(-50%);
}

/* ── Video block (square leadership / proof clip) ───────────────────────── */
.video-grid {
  display: grid;
  grid-template-columns: minmax(0, 440px) 1fr;
  gap: clamp(1.5rem, 4vw, 3rem);
  align-items: center;
  margin-top: 1.5rem;
}
.video-frame {
  position: relative;
  width: 100%;
  border-radius: 10px;
  overflow: hidden;
  background: var(--denim-deep);
  border: 1px solid var(--border);
}
.video-el { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; border: 0; display: block; }
.video-placeholder {
  position: absolute; inset: 0;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 0.7rem;
  color: var(--text-3);
  background: radial-gradient(circle at 50% 42%, var(--denim-raised), var(--denim-deep));
}
.video-placeholder svg { width: 52px; height: 52px; color: var(--orange); }
.video-placeholder span { font-size: 0.72rem; font-weight: 700; letter-spacing: 0.1em; text-transform: uppercase; }
.video-copy .rich-body { max-width: 48ch; }
.video-attr { margin-top: 1.5rem; display: flex; flex-direction: column; gap: 0.4rem; }
.video-attr span { display: flex; flex-direction: column; }
.video-attr strong { color: var(--text-1); font-weight: 700; }
.video-role { color: var(--text-3); font-size: 0.88rem; }
@media (max-width: 760px) {
  .video-grid { grid-template-columns: 1fr; }
  .video-frame { max-width: 440px; }
}

/* Small-print disclaimer (e.g. AI-generated / E&OE note). */
.rich-body .disclaimer {
  font-size: 0.78rem; line-height: 1.6; color: var(--text-3); max-width: 80ch;
  border-top: 1px solid var(--border); padding-top: 1.1rem; margin: 0;
}

/* ── Trust-intelligence brief: meta strip ───────────────────────────────── */
.intel-meta { display: flex; flex-wrap: wrap; gap: 0.5rem 0.75rem; margin-top: 1.1rem; }
.intel-chip {
  display: inline-flex; align-items: center; gap: 0.45rem;
  font-size: 0.78rem; font-weight: 600; color: var(--text-2);
  padding: 0.3rem 0.7rem; border: 1px solid var(--border); border-radius: 100px;
  background: oklch(0.24 0.045 240 / 0.6);
}
.intel-chip strong { color: var(--text-1); font-weight: 700; }
.intel-chip.is-flag { border-color: var(--orange-dim); color: var(--orange-light); }

/* Teaser page: centre the gate card over a soft, parallaxing backdrop. The
   backdrop is purely decorative (no gated content lives in the teaser). */
.gate-teaser { position: relative; overflow: hidden; isolation: isolate; }
.gate-teaser .wrap { display: flex; justify-content: center; position: relative; z-index: 1; }
.gate-teaser .gate-card { width: min(560px, 100%); }
.gate-teaser-fx {
  position: absolute; inset: -25% -10%; z-index: 0; pointer-events: none;
  background:
    radial-gradient(38% 48% at 30% 32%, oklch(0.64 0.175 58 / 0.32), transparent 70%),
    radial-gradient(42% 52% at 72% 70%, oklch(0.40 0.05 240 / 0.55), transparent 72%);
  filter: blur(60px);
  opacity: 0.6;
}
@media (prefers-reduced-motion: no-preference) {
  .gate-teaser-fx, .gate-teaser .gate-card { will-change: transform; }
}

/* ── Lead gate ──────────────────────────────────────────────────────────── */
/* The gate is one .intel-lock unit: blurred gated content + an overlay card.
   Locked by default in the build; the JS controller removes .is-locked to
   reveal. Fails closed (stays locked) if JS never runs. */
.intel-lock { position: relative; }

.intel-lock.is-locked .intel-gated {
  max-height: 420px;
  overflow: hidden;
  filter: blur(7px);
  opacity: 0.5;
  pointer-events: none;
  user-select: none;
  -webkit-user-select: none;
}
.intel-lock.is-locked .intel-gated > * { animation: none !important; }

/* Overlay: gradient that fades the blurred peek into the page, with the card
   centred over the seam so it reads as "unlock to keep reading". */
.intel-gate-overlay {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: clamp(1.5rem, 5vw, 4rem);
  background: linear-gradient(to bottom,
    oklch(0.24 0.045 240 / 0) 0%,
    oklch(0.24 0.045 240 / 0.65) 22%,
    var(--denim) 60%);
}

/* Unlocked: drop the blur/cap, fade the overlay out, let content breathe. The
   overlay fades (not display:none) so the unlock reads as a reveal, not a snap. */
.intel-lock:not(.is-locked) .intel-gated {
  max-height: none; overflow: visible; filter: none; opacity: 1;
  pointer-events: auto; user-select: auto; -webkit-user-select: auto;
}
.intel-lock:not(.is-locked) .intel-gate-overlay { opacity: 0; visibility: hidden; pointer-events: none; }

.gate-card {
  width: min(560px, 100%);
  background: var(--denim-raised);
  border: 1px solid var(--border-light);
  border-radius: 8px;
  padding: clamp(1.75rem, 4vw, 2.75rem);
  box-shadow: 0 24px 60px oklch(0.12 0.03 240 / 0.55);
  text-align: left;
}
.gate-title { font-family: var(--f-display); font-weight: 800; font-size: clamp(1.5rem, 3.2vw, 2rem); line-height: 1.1; letter-spacing: -0.02em; color: var(--text-1); }
.gate-body { color: var(--text-2); margin-top: 0.75rem; max-width: none; }
.gate-points { display: flex; flex-direction: column; gap: 0.65rem; margin: 1.25rem 0 0; }
.gate-points li { position: relative; padding-left: 1.6rem; color: var(--text-3); font-size: 0.95rem; }
.gate-points strong { color: var(--text-1); font-weight: 700; }
.gate-points li::before {
  content: ""; position: absolute; left: 0; top: 0.45rem;
  width: 0.7rem; height: 0.7rem; border-radius: 50%;
  background: var(--orange); box-shadow: 0 0 0 3px oklch(0.64 0.175 58 / 0.18);
}
.gate-form { margin-top: 1.5rem; display: flex; flex-direction: column; gap: 1rem; }
.gate-fields { display: grid; gap: 0.9rem; }
.gate-submit { align-self: stretch; justify-content: center; text-align: center; }
.gate-note { font-size: 0.78rem; color: var(--text-3); max-width: none; margin: 0; }
.gate-error { font-size: 0.85rem; color: var(--orange-light); font-weight: 600; margin: 0; }

/* Editor: show the gate inline (not as a blurring overlay) so it's editable. */
.gate-editor-divider {
  display: flex; align-items: center; gap: 1rem;
  margin: 2rem clamp(1.5rem, 5vw, 4rem); color: var(--text-3);
  font-size: 0.78rem; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase;
}
.gate-editor-divider::before, .gate-editor-divider::after {
  content: ""; flex: 1; height: 1px; background: var(--orange-dim); opacity: 0.5;
}

/* Dev-bypass ribbon - shown only when the gate is skipped for local testing. */
.intel-dev-ribbon {
  position: fixed; bottom: 1rem; left: 1rem; z-index: 500;
  display: inline-flex; align-items: center; gap: 0.5rem;
  font-size: 0.72rem; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--denim-deep); background: var(--orange);
  padding: 0.4rem 0.75rem; border-radius: 100px;
  box-shadow: 0 6px 18px oklch(0.12 0.03 240 / 0.5);
}
.intel-dev-ribbon button { color: var(--denim-deep); text-decoration: underline; font-weight: 700; }

/* ── Trust-intelligence brief: motion layer ─────────────────────────────────
   Page-specific motion, following the shared pattern: anything that moves is
   gated behind prefers-reduced-motion: no-preference; colour/border feedback
   stays for everyone. The signature moment is the unlock - the blurred content
   un-blurs and the overlay fades as the gate opens (height eased in JS). */
@media (prefers-reduced-motion: no-preference) {
  .intel-gated { transition: filter 0.7s var(--ease-out-quart), opacity 0.7s var(--ease-out-quart); }
  .intel-gate-overlay { transition: opacity 0.45s var(--ease-out-quart), visibility 0.45s linear; }

  /* Chips read as tags - a 1px lift + brighten acknowledges the pointer. */
  .intel-chip { transition: border-color 0.2s, color 0.2s, transform 0.2s var(--ease-out-quart); }
  .intel-chip:hover { transform: translateY(-1px); }

  /* Step cards are liftable surfaces, like related cards. */
  .step-card { transition: border-color 0.2s, transform 0.28s var(--ease-out-quart), box-shadow 0.28s; }
  .step-card:hover { transform: translateY(-4px); box-shadow: 0 14px 34px oklch(0.10 0.03 240 / 0.45); }

  /* Gate form: focus glow + a short shake when validation fails. */
  .gate-form .field input { transition: border-color 0.2s, box-shadow 0.25s var(--ease-out-quart); }
  @keyframes gate-shake {
    10%, 90% { transform: translateX(-1px); }
    20%, 80% { transform: translateX(2px); }
    30%, 50%, 70% { transform: translateX(-4px); }
    40%, 60% { transform: translateX(4px); }
  }
  .gate-form.shake { animation: gate-shake 0.4s var(--ease-out-quart); }
}
.intel-chip:hover { border-color: var(--border-light); color: var(--text-1); }
.gate-form .field input:focus { box-shadow: 0 0 0 3px oklch(0.64 0.175 58 / 0.18); }

/* Submit loading state while the lead is posted. */
.gate-submit[disabled] { opacity: 0.72; cursor: progress; }

/* ── Estate accordion (filterable deep-dive) ────────────────────────────── */
.estate-band { background: var(--denim-mid); border-top: 1px solid var(--border); }

.estate-filters { display: flex; flex-wrap: wrap; gap: 0.5rem; margin: 1.5rem 0 1.75rem; }
.estate-filter {
  display: inline-flex; align-items: center; gap: 0.4rem;
  font-size: 0.82rem; font-weight: 600; color: var(--text-2);
  padding: 0.4rem 0.85rem; border: 1px solid var(--border); border-radius: 100px;
  background: transparent; transition: color 0.2s, border-color 0.2s, background 0.2s;
}
.estate-filter:hover { color: var(--text-1); border-color: var(--border-light); }
.estate-filter.is-active { background: var(--orange); border-color: var(--orange); color: var(--denim-deep); }
.estate-count { font-size: 0.74rem; font-weight: 700; opacity: 0.75; }

.estate-list { display: flex; flex-direction: column; gap: 0.6rem; }
.estate-item {
  border: 1px solid var(--border); border-radius: 8px; background: var(--denim);
  overflow: hidden; transition: border-color 0.2s;
}
.estate-item[open] { border-color: var(--border-light); }
.estate-item:hover { border-color: var(--border-light); }

.estate-summary {
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  padding: 1.1rem 1.25rem; cursor: pointer; list-style: none; user-select: none;
}
.estate-summary::-webkit-details-marker { display: none; }
.estate-sum-main { display: flex; align-items: baseline; gap: 0.85rem; min-width: 0; }
.estate-num { font-family: var(--f-display); font-weight: 800; color: var(--orange); font-size: 0.95rem; flex-shrink: 0; }
.estate-title { font-weight: 600; color: var(--text-1); font-size: 1.02rem; line-height: 1.3; }
.estate-cat { display: block; font-size: 0.78rem; font-weight: 500; color: var(--text-3); margin-top: 0.15rem; }
.estate-sum-meta { display: flex; align-items: center; gap: 0.6rem; flex-shrink: 0; }

.estate-stage { font-size: 0.7rem; font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase; padding: 0.25rem 0.6rem; border-radius: 100px; border: 1px solid currentColor; white-space: nowrap; }
.estate-stage.stage-live { color: oklch(0.78 0.13 165); }
.estate-stage.stage-procurement { color: var(--orange-light); }
.estate-stage.stage-planned { color: oklch(0.74 0.10 245); }
.estate-stage.stage-mixed { color: var(--text-3); }
.estate-vendor { font-size: 0.78rem; color: var(--text-3); max-width: 22ch; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
@media (max-width: 680px) { .estate-vendor, .estate-cat { display: none; } }

.estate-chevron { width: 10px; height: 10px; border-right: 2px solid var(--text-2); border-bottom: 2px solid var(--text-2); transform: rotate(45deg); transition: transform 0.25s var(--ease-out-quart); flex-shrink: 0; }
.estate-item[open] .estate-chevron { transform: rotate(-135deg); }

.estate-detail { padding: 0 1.25rem 1.5rem; border-top: 1px solid var(--border); padding-top: 1.25rem; }
.estate-sec + .estate-sec { margin-top: 1.4rem; padding-top: 1.4rem; border-top: 1px solid var(--border); }
.estate-sec-label {
  font-size: 0.72rem; font-weight: 700; letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--orange); margin-bottom: 0.5rem;
}
.estate-detail .rich-body { font-size: 0.96rem; max-width: 76ch; }
.estate-detail .rich-body a { word-break: break-word; }

/* Numbered list (parsed "(1)..(2).." enumerations) - orange numeral badges. */
.rich-body ol { list-style: none; counter-reset: ol; display: flex; flex-direction: column; gap: 0.55rem; padding-left: 0; }
.rich-body ol li { position: relative; padding-left: 2.1rem; }
.rich-body ol li::before {
  counter-increment: ol; content: counter(ol);
  position: absolute; left: 0; top: 0.05em;
  width: 1.45rem; height: 1.45rem; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  font-size: 0.72rem; font-weight: 700; color: var(--denim-deep); background: var(--orange);
}

/* Timeline list (parsed "Timeline:" date runs) - dated rows on a rail. */
.estate-timeline { list-style: none; display: flex; flex-direction: column; gap: 0.6rem; margin: 0; padding-left: 1.1rem; border-left: 2px solid var(--border-light); }
.estate-timeline li { position: relative; padding-left: 0.25rem; }
.estate-timeline li::before { content: ""; position: absolute; left: calc(-1.1rem - 1px); top: 0.55em; width: 7px; height: 7px; border-radius: 50%; background: var(--orange); transform: translateX(-50%); }
.estate-timeline li strong { color: var(--orange-light); font-weight: 700; }

@media (prefers-reduced-motion: no-preference) {
  .estate-item[open] .estate-detail { animation: estate-open 0.3s var(--ease-out-quart); }
  @keyframes estate-open { from { opacity: 0; transform: translateY(-4px); } to { opacity: 1; transform: none; } }
}

/* Honeypot: off-screen rather than display:none, and never announced. A real
   person cannot reach it (tabindex -1, aria-hidden); a bot filling it is rejected
   server-side. */
.hp-field { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

/* Contact form status line: one element for sending / sent / failed. */
.form-status { font-size: .9rem; color: var(--text-2); margin: .25rem 0 0; }
.form-status.is-error { color: var(--orange-light); }
