/* 4C Construction Systems — premium industrial/architectural design system */
/* Google Fonts are loaded via non-blocking <link> tags in each page's <head>
   (not @import here), so this stylesheet — and the deferred script tag that
   follows it — never wait on a cross-origin font request before applying. */

:root {
  --color-ink: #14181f;
  --color-graphite: #2b313c;
  --color-steel: #6b7684;
  --color-steel-light: #9aa3ae;
  --color-paper: #f7f5f1;
  --color-paper-dim: #efece5;
  --color-line: #e0dcd3;
  --color-white: #ffffff;

  /* Brand triad, sampled from the real 4C logo */
  --color-accent: #008a99;       /* teal — primary CTA / links */
  --color-accent-dark: #00666f;
  --color-accent-tint: #dcf0f2;
  --color-purple: #7b5dd6;       /* secondary accent */
  --color-purple-tint: #eae5fa;
  --color-green: #8fb222;        /* tertiary accent — used for Carbon/Sustainability */
  --color-green-tint: #ecf3da;

  --color-safe: #2f5233;
  --color-safe-tint: #e2ead9;

  --font-heading: "Sora", "Inter", sans-serif;
  --font-sans: "Inter", -apple-system, BlinkMacSystemFont, sans-serif;
  --font-mono: "Roboto Mono", monospace;

  --radius: 3px;
  --radius-lg: 6px;
  --max-width: 1180px;
  --shadow-card: 0 1px 2px rgba(20, 24, 31, 0.04), 0 8px 24px rgba(20, 24, 31, 0.06);
  --shadow-lift: 0 20px 48px rgba(20, 24, 31, 0.14);

  /* Shared motion tokens so every transition/animation across the site reads
     as one consistent, restrained language rather than ad-hoc values. */
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --ease-smooth: cubic-bezier(0.4, 0, 0.2, 1);
  --ease-hero: cubic-bezier(0.22, 1, 0.36, 1);
  --dur-micro: 180ms;
  --dur-base: 240ms;
  --dur-reveal: 550ms;
  --dur-hero: 900ms;

  /* Scroll-linked motion amounts. Kept as tokens so the whole site's
     parallax intensity can be tuned in one place, and dialled down on
     small screens further below. */
  --hero-zoom: 0.06;
  --hero-shift: -64px;
  --page-hero-zoom: 0.04;
  --page-hero-shift: -40px;
}

* { box-sizing: border-box; }

html { scroll-behavior: smooth; }

/* ---------- Motion system ---------- */
/* --reveal-y lets callers vary the travel distance without needing their own
   keyframe; the default keeps the entrance subtle. */
@keyframes ccc-fade-up {
  from { opacity: 0; transform: translateY(var(--reveal-y, 14px)); }
  to { opacity: 1; transform: translateY(0); }
}
@keyframes ccc-fade-in {
  from { opacity: 0; }
  to { opacity: 1; }
}

/* ---------- Scroll-linked reveals ----------
   main.js tags qualifying elements and drives a per-element --p (0 → 1)
   from actual scroll position on every frame, so the motion tracks the
   user's scroll continuously and reverses when they scroll back up, rather
   than firing once and stopping. --p defaults to 1 so that if JS never runs
   (or reduced motion is on) everything is simply visible — content is never
   dependent on this system. */
.scroll-reveal {
  opacity: var(--p, 1);
  transform: translateY(calc((1 - var(--p, 1)) * var(--reveal-y, 26px)));
}
.scroll-reveal-scale {
  opacity: var(--p, 1);
  transform: scale(calc(1 - (1 - var(--p, 1)) * var(--reveal-scale-amt, 0.035)));
}
/* Promoted only while actually being animated; main.js clears this once an
   element settles so we don't keep hundreds of layers alive. */
.is-animating { will-change: opacity, transform; }

/* ---------- Hero scroll response ----------
   The hero photo eases in on load (opacity only, so its transform stays free
   for scroll), then gently zooms as the user scrolls away while the hero
   copy lifts and fades — one continuous movement tied to scroll progress. */
.hero-photo-bg {
  transform: scale(calc(1 + var(--hero-p, 0) * var(--hero-zoom)));
}
.hero .wrap {
  transform: translateY(calc(var(--hero-p, 0) * var(--hero-shift)));
  opacity: calc(1 - var(--hero-p, 0) * 0.85);
}
.page-hero .hero-photo-bg {
  transform: scale(calc(1 + var(--hero-p, 0) * var(--page-hero-zoom)));
}
.page-hero .wrap {
  transform: translateY(calc(var(--hero-p, 0) * var(--page-hero-shift)));
  opacity: calc(1 - var(--hero-p, 0) * 0.8);
}

@media (max-width: 900px) {
  /* Gentler everywhere on touch screens: less zoom, less lift. */
  :root {
    --hero-zoom: 0.035;
    --hero-shift: -34px;
    --page-hero-zoom: 0.025;
    --page-hero-shift: -22px;
  }
  .scroll-reveal { --reveal-y: 18px; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
  .scroll-reveal, .scroll-reveal-scale { opacity: 1 !important; transform: none !important; }
  .hero-photo-bg, .hero .wrap, .page-hero .hero-photo-bg, .page-hero .wrap {
    transform: none !important;
    opacity: 1 !important;
  }
  /* .exploded-layer-slide is deliberately left alone here -- its transform
     is what selects which image is in the window, not decorative easing, so
     suppressing it would freeze reduced-motion visitors on the first image
     forever. Only the step marker's own decorative motion is stripped. */
  .exploded-scroll-step::before, .exploded-scroll-step h3 { transform: none !important; }
}

body {
  margin: 0;
  font-family: var(--font-sans);
  color: var(--color-graphite);
  background: var(--color-paper);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

/* height:auto keeps the aspect ratio correct now that every <img> carries its
   intrinsic width/height attributes (those reserve layout space and stop the
   page shifting as images arrive). Without it, any image whose width CSS
   constrains — .overview-grid figure img, for instance — would keep its full
   intrinsic height and render stretched. Rules that deliberately fix a height
   (.photo-gallery img, .logo-marquee-track img) use class selectors and still
   win on specificity. */
img { max-width: 100%; height: auto; display: block; }

a { color: var(--color-accent); text-decoration: none; }
a:hover { text-decoration: underline; }

h1, h2, h3, h4 {
  font-family: var(--font-heading);
  color: var(--color-ink);
  line-height: 1.15;
  margin: 0 0 16px;
  letter-spacing: -0.01em;
  /* Balances line lengths on multi-line headings instead of the browser's
     default greedy wrap, which can leave one line much longer than the
     next. Progressive enhancement -- unsupported browsers just keep the
     normal wrap, so this is safe with no fallback needed. */
  text-wrap: balance;
}

h1 { font-size: clamp(2.4rem, 4.5vw, 3.6rem); font-weight: 800; }
h2 { font-size: clamp(1.7rem, 3vw, 2.3rem); font-weight: 700; }
h3 { font-size: 1.25rem; font-weight: 700; }
h4 { font-size: 1.05rem; font-weight: 600; }

/* Available to screen readers and to the document outline, but not painted.
   Used where a section needs a heading for correct hierarchy but the design
   already makes the grouping obvious visually. */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  border: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
}

/* Lets keyboard users jump the header nav straight to the page content.
   Off-screen until focused, then it drops into the top-left corner. */
.skip-link {
  position: absolute;
  top: 0;
  left: 0;
  z-index: 200;
  transform: translateY(-120%);
  padding: 12px 20px;
  background: var(--color-ink);
  color: var(--color-white);
  font-family: var(--font-heading);
  font-size: 0.9rem;
  font-weight: 600;
  border-bottom-right-radius: var(--radius-lg);
  transition: transform var(--dur-micro) var(--ease-smooth);
}
.skip-link:focus {
  transform: translateY(0);
  text-decoration: none;
}

/* On desktop, widen this heading's container so it breaks to two balanced
   lines at full size instead of three; it wraps normally on smaller screens. */
@media (min-width: 1180px) {
  .section-head:has(.nowrap-lg) { max-width: 820px; }
  .nowrap-lg { text-wrap: balance; }
}

p { margin: 0 0 16px; color: var(--color-steel); }

.wrap {
  max-width: var(--max-width);
  margin: 0 auto;
  padding: 0 32px;
}

/* ---------- Eyebrow / kicker ---------- */
.kicker {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-family: var(--font-mono);
  font-size: 0.72rem;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--color-accent);
  margin-bottom: 14px;
}
.kicker::before {
  content: "";
  width: 22px;
  height: 2px;
  background: var(--color-accent);
  display: inline-block;
}

/* ---------- Header ---------- */
.site-header {
  position: -webkit-sticky;
  position: sticky;
  top: 0;
  z-index: 100;
  background: rgba(247, 245, 241, 0.92);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--color-line);
  transition: box-shadow var(--dur-base) var(--ease-smooth);
}
.site-header.is-scrolled { box-shadow: 0 8px 24px rgba(20, 24, 31, 0.08); }
.site-header .wrap {
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: 84px;
}
.brand {
  display: flex;
  align-items: center;
  color: var(--color-ink);
}
.brand:hover { text-decoration: none; }
.brand .mark-full {
  height: 52px;
  width: auto;
  flex-shrink: 0;
  display: block;
}

.main-nav {
  display: flex;
  align-items: center;
  gap: 30px;
}
.main-nav a {
  position: relative;
  color: var(--color-graphite);
  font-size: 0.92rem;
  font-weight: 500;
  transition: color var(--dur-micro) var(--ease-smooth);
}
.main-nav a:hover { color: var(--color-accent); text-decoration: none; }
.main-nav > a::after,
.main-nav .dropdown > a::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -8px;
  height: 2px;
  background: var(--color-accent);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--dur-base) var(--ease-out);
}
.main-nav > a:hover::after,
.main-nav .dropdown > a:hover::after,
.main-nav > a:focus-visible::after { transform: scaleX(1); }
.main-nav .dropdown { position: relative; }
.main-nav .dropdown::after {
  content: "";
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  height: 12px;
}
.main-nav .dropdown-panel {
  position: absolute;
  top: 100%;
  left: 50%;
  background: var(--color-white);
  border: 1px solid var(--color-line);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lift);
  padding: 10px;
  min-width: 220px;
  margin-top: 12px;
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transform: translate(-50%, -6px);
  transition: opacity var(--dur-base) var(--ease-out), transform var(--dur-base) var(--ease-out);
}
/* :focus-within, not just :hover, so the panel is reachable by keyboard --
   visibility flips instantly (not transitioned) so it enters/leaves the tab
   order exactly when it becomes visible, not mid-fade. */
.main-nav .dropdown:hover .dropdown-panel,
.main-nav .dropdown:focus-within .dropdown-panel {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
  transform: translate(-50%, 0);
}
.main-nav .dropdown-panel a {
  display: block;
  padding: 9px 12px;
  border-radius: var(--radius);
  font-size: 0.88rem;
  white-space: nowrap;
}
.main-nav .dropdown-panel a:hover { background: var(--color-paper-dim); text-decoration: none; }

.header-phone {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-left: 20px;
  font-family: var(--font-mono);
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--color-ink);
  white-space: nowrap;
}
.header-phone:hover { color: var(--color-accent); text-decoration: none; }
.header-phone svg { width: 16px; height: 16px; color: var(--color-accent); flex-shrink: 0; }
@media (max-width: 1024px) {
  .header-phone { display: none; }
}

.btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 13px 26px;
  border-radius: var(--radius);
  font-weight: 600;
  font-size: 0.92rem;
  font-family: var(--font-sans);
  border: 1px solid transparent;
  cursor: pointer;
  transition: transform var(--dur-base) var(--ease-out), background-color var(--dur-base) var(--ease-smooth),
    border-color var(--dur-base) var(--ease-smooth), color var(--dur-base) var(--ease-smooth), box-shadow var(--dur-base) var(--ease-smooth);
  white-space: nowrap;
}
.btn:hover { text-decoration: none; }
@media (hover: hover) and (pointer: fine) {
  .btn:hover { transform: translateY(-1px); }
}
.btn:active { transform: translateY(0) scale(0.98); }
.btn:focus-visible { outline: 2px solid var(--color-accent); outline-offset: 2px; }
.btn-primary { background: var(--color-accent); color: var(--color-white); }
.btn-primary:hover { background: var(--color-accent-dark); box-shadow: 0 8px 20px rgba(0, 138, 153, 0.25); }
.header-cta { margin-left: 16px; }
.btn-dark { background: var(--color-ink); color: var(--color-white); }
.btn-dark:hover { background: var(--color-graphite); }
.btn-outline { background: transparent; color: var(--color-ink); border-color: var(--color-ink); }
.btn-outline:hover { background: var(--color-ink); color: var(--color-white); }
.btn-outline-light { background: transparent; color: var(--color-white); border-color: rgba(255,255,255,0.4); }
.btn-outline-light:hover { background: rgba(255,255,255,0.12); }

.menu-toggle {
  display: none;
  background: none;
  border: none;
  cursor: pointer;
  color: var(--color-ink);
  width: 40px;
  height: 40px;
}
.menu-toggle svg line {
  transition: transform var(--dur-base) var(--ease-out), opacity var(--dur-micro) ease;
  transform-origin: center;
}
.menu-toggle.is-open svg line:nth-child(1) { transform: translateY(6px) rotate(45deg); }
.menu-toggle.is-open svg line:nth-child(2) { opacity: 0; }
.menu-toggle.is-open svg line:nth-child(3) { transform: translateY(-6px) rotate(-45deg); }

/* ---------- Hero ---------- */
.hero {
  position: relative;
  background: var(--color-ink);
  color: var(--color-white);
  overflow: hidden;
  padding: 100px 0 90px;
}
.hero-photo-bg {
  position: absolute;
  inset: 0;
  background-size: cover;
  background-position: center;
  opacity: 1;
  pointer-events: none;
  /* Opacity only — the transform belongs to the scroll-linked zoom above. */
  animation: ccc-fade-in 900ms var(--ease-out) both;
}
.hero-photo-bg::after {
  content: "";
  position: absolute;
  inset: 0;
  /* Darken mainly the left (behind the text) and fade toward the right so the
     photo stays legible; a soft bottom fade grounds the stats row. */
  background: linear-gradient(90deg, var(--color-ink) 0%, rgba(20,24,31,0.92) 24%, rgba(20,24,31,0.6) 46%, rgba(20,24,31,0.2) 68%, rgba(20,24,31,0) 100%),
    linear-gradient(180deg, rgba(20,24,31,0) 55%, rgba(20,24,31,0.55) 100%);
}
/* On narrow screens the text spans full width, so use a uniform scrim instead
   of the left-weighted one to keep it readable over the brighter image areas. */
@media (max-width: 900px) {
  .hero-photo-bg::after {
    background: linear-gradient(180deg, rgba(20,24,31,0.5) 0%, rgba(20,24,31,0.72) 100%);
  }
}
.hero .blueprint-bg {
  position: absolute;
  inset: 0;
  opacity: 0.16;
  pointer-events: none;
}
.hero .wrap { position: relative; z-index: 1; }
.hero-grid {
  display: block;
}
/* Locked to the hero-grid's old 800px cap so the heading keeps wrapping
   exactly as before, independent of how wide the container around it is. */
.hero h1 { color: var(--color-white); max-width: 800px; }
.hero .kicker { color: var(--color-accent); font-size: 0.85rem; letter-spacing: 0.12em; }
.hero p.lede {
  font-size: 1.15rem;
  color: rgba(255,255,255,0.72);
}
.hero-ctas { display: flex; gap: 14px; margin-top: 30px; flex-wrap: wrap; }
.hero-stats {
  display: flex;
  gap: 28px;
  margin-top: 56px;
  padding-top: 28px;
  border-top: 1px solid rgba(255,255,255,0.14);
  flex-wrap: wrap;
}
.hero-stats > div { flex: 1 1 150px; }
.hero-stats .stat-num {
  font-family: var(--font-mono);
  font-size: 2.2rem;
  font-weight: 500;
  color: var(--color-white);
  display: block;
}
.hero-stats .stat-label {
  font-size: 0.86rem;
  color: rgba(255,255,255,0.55);
  margin-top: 4px;
}

/* Hero content settles in as complete blocks (kicker + heading move as one
   unit, then the paragraph, then the CTA/stats) — never line-by-line or
   word-by-word, which reads as the page still loading. A long, slow ease
   makes the entrance feel deliberate rather than snapped-in. */
.hero .kicker, .hero h1, .hero p.lede, .hero-ctas, .hero-stats {
  animation: ccc-fade-up var(--dur-hero) var(--ease-hero) both;
}
.hero .kicker, .hero h1 { --reveal-y: 18px; animation-delay: 0ms; }
.hero p.lede { --reveal-y: 14px; animation-delay: 150ms; }
.hero-ctas { --reveal-y: 10px; animation-delay: 270ms; }
.hero-stats { --reveal-y: 10px; animation-delay: 350ms; }

/* ---------- Logo marquee (auto-scrolling partner logos, under hero) ---------- */
.logo-marquee-section { padding: 40px 0; background: var(--color-paper); overflow: hidden; }
.logo-marquee-label {
  text-align: center;
  font-family: var(--font-mono);
  font-size: 0.74rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--color-steel);
  margin: 0 0 24px;
}
.logo-marquee { width: 100%; overflow: hidden; -webkit-mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent); mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent); }
.logo-marquee-track {
  display: flex;
  align-items: center;
  gap: 72px;
  width: max-content;
  animation: logo-marquee-scroll 70s linear infinite;
  /* The track's transform isolates a compositing group, so the logos'
     mix-blend-mode: multiply needs a paper backdrop here to blend their white
     artboards against and make them disappear into the section. */
  background: var(--color-paper);
}
.logo-marquee-track img {
  height: 64px;
  width: auto;
  max-width: 220px;
  object-fit: contain;
  flex-shrink: 0;
  /* Blend the logos' white artboards into the paper background so they don't
     read as white boxes. Works for the .jpg logos too, which can't be transparent. */
  mix-blend-mode: multiply;
}
@keyframes logo-marquee-scroll {
  from { transform: translateX(0); }
  to { transform: translateX(-50%); }
}
@media (prefers-reduced-motion: reduce) {
  .logo-marquee-track { animation: none; }
}

/* ---------- Hero explainer video ---------- */
.hero-video {
  position: relative;
  width: 100%;
  aspect-ratio: 16 / 9;
  border-radius: var(--radius-lg);
  overflow: hidden;
  box-shadow: var(--shadow-lift);
  background: #000;
  cursor: pointer;
}
.hero-video video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.hero-video .hero-video-play {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(20, 24, 31, 0.18);
  border: none;
  cursor: pointer;
  padding: 0;
  transition: background 0.15s ease;
}
.hero-video .hero-video-play:hover { background: rgba(20, 24, 31, 0.32); }
.hero-video .hero-video-play .play-circle {
  width: 68px;
  height: 68px;
  border-radius: 50%;
  background: var(--color-white);
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 8px 24px rgba(0,0,0,0.35);
  transition: transform 0.15s ease;
}
.hero-video .hero-video-play:hover .play-circle { transform: scale(1.08); }
.hero-video .hero-video-play svg { width: 24px; height: 24px; color: var(--color-accent); margin-left: 3px; }
.hero-video .hero-video-play.is-hidden { display: none; }
.hero-video-caption {
  margin-top: 12px;
  font-size: 0.82rem;
  color: rgba(255,255,255,0.55);
  text-align: center;
}

/* ---------- Page hero (interior pages) ---------- */
.page-hero {
  background: var(--color-ink);
  color: var(--color-white);
  padding: 64px 0 56px;
  position: relative;
  overflow: hidden;
}
.page-hero .blueprint-bg { position: absolute; inset: 0; opacity: 0.14; }
/* Hero text runs the full header width, from the logo's left edge to the
   "Talk to Us" button's right edge, instead of a narrower centered measure. */
.page-hero .wrap { position: relative; z-index: 1; max-width: var(--max-width); }
/* Overview text column: drop the generic narrow measure and use the full
   grid column width available next to the diagram, with a touch more size. */
body[data-page="safe"] .overview-grid .section-head { max-width: none; }
body[data-page="safe"] .overview-grid .section-head p { font-size: 1.05rem; }
/* "Proven In The Field" section: match the width of the card-grid section above it. */
body[data-page="safe"] .section-head:has(.btn-outline) { max-width: none; }
body[data-page="eco"] .overview-grid .section-head { max-width: none; }
body[data-page="eco"] .overview-grid .section-head p { font-size: 1.05rem; }
body[data-page="eco"] .section-head:has(.btn-outline) { max-width: none; }
/* The stat band and the "Proven In The Field" section each sit directly above
   another full section; the default 84px top+bottom section padding stacks
   into an oversized double gap at both transitions, so tighten just those. */
body[data-page="safe"] section:has(> .wrap > .stat-band),
body[data-page="eco"] section:has(> .wrap > .stat-band),
body[data-page="safe"] section:has(.btn-outline),
body[data-page="eco"] section:has(.btn-outline) { padding-bottom: 36px; }
body[data-page="safe"] section:has(> .wrap > .stat-band) + section,
body[data-page="eco"] section:has(> .wrap > .stat-band) + section,
body[data-page="safe"] section:has(.btn-outline) + section,
body[data-page="eco"] section:has(.btn-outline) + section { padding-top: 36px; }
/* Same stacked-gap fix for a partner section feeding straight into the next
   section-head. Covers both shapes: a feature card followed by the small-card
   grid (architects page), and a feature card on its own (builders page). */
section:has(> .wrap > .partner-card-grid),
section:has(> .wrap > .partner-feature) { padding-block: 36px; }
section:has(> .wrap > .partner-card-grid) + section,
section:has(> .wrap > .partner-feature) + section { padding-top: 36px; }
/* Trims only the trailing padding of a section, for use on the one directly
   above a tightened section so the two 84px blocks don't stack into a gap.
   (A :has() rule can't reach it -- :has() cannot be nested inside :has().) */
section.tight-bottom { padding-bottom: 36px; }
/* Same stacked-84px gap into the "As seen in the news" section from
   whichever section precedes it -- #why-not-x on the homepage, the mission
   testimonial on about.html. Both selectors are inherently page-specific
   (that id and .testimonial each exist on exactly one page), so no extra
   scoping is needed. */
section:has(> .wrap > .video-grid) { padding-top: 36px; }
#why-not-x { padding-bottom: 36px; }
section:has(> .wrap > .testimonial) { padding-bottom: 36px; }
/* "Our Mission" section-head, identified by the testimonial that follows it. */
.section-head:has(+ .testimonial) { max-width: none; }
body[data-page="about"] section.on-dark .section-head { max-width: none; }
body[data-page="about"] section.on-dark .section-head h2 { font-size: 2.6rem; }
body[data-page="about"] section.on-dark .section-head p { font-size: 1.1rem; }
body[data-page="systems"] #service-options .section-head { max-width: none; }
body[data-page="partners"] #customer-types .section-head { max-width: none; }
body[data-page="partners"] #vendor-network .section-head { max-width: none; }
body[data-page="partners"] #how-it-works .section-head { max-width: none; }
body[data-page="partners"] #partner-logos .section-head { max-width: none; }
/* Manufacturing and Sustainability: intro paragraphs run the full column
   width instead of the generic 640px measure, with more generous line
   spacing to keep the longer lines easy to read, and sections sit closer
   together instead of the default 84px rhythm — matching the wider,
   tighter treatment already used on the SAFE/ECO and persona pages. */
body[data-page="manufacturing"] .section-head,
body[data-page="sustainability"] .section-head { max-width: none; }
body[data-page="manufacturing"] .section-head p,
body[data-page="sustainability"] .section-head p { line-height: 1.9; }
body[data-page="manufacturing"] section:not(.page-hero),
body[data-page="sustainability"] section:not(.page-hero) { padding: 56px 0; }
.page-hero h1 { color: var(--color-white); margin-bottom: 12px; }
.page-hero p.lede { color: rgba(255,255,255,0.72); font-size: 1.08rem; margin: 0; }
.breadcrumb-nav {
  font-size: 0.82rem;
  color: rgba(255,255,255,0.5);
  margin-bottom: 18px;
}
.breadcrumb-nav a { color: rgba(255,255,255,0.7); transition: color var(--dur-micro) var(--ease-smooth); }
.breadcrumb-nav a:hover { color: var(--color-white); }
.page-hero .breadcrumb-nav, .page-hero .kicker, .page-hero h1, .page-hero p.lede {
  animation: ccc-fade-up var(--dur-hero) var(--ease-hero) both;
}
.page-hero .breadcrumb-nav, .page-hero .kicker, .page-hero h1 { --reveal-y: 18px; animation-delay: 0ms; }
.page-hero p.lede { --reveal-y: 14px; animation-delay: 150ms; }

/* ---------- Sections ---------- */
section { padding: 84px 0; }
section.tight { padding: 56px 0; }
section.on-dark { background: var(--color-ink); color: var(--color-white); }
section.on-dark h2, section.on-dark h3 { color: var(--color-white); }
section.on-paper-dim { background: var(--color-paper-dim); }
.section-head { max-width: 640px; margin-bottom: 48px; }
/* That 48px spaces the head from the content beneath it. In a section whose
   only content IS the head, it stacks onto the section's own padding-bottom
   and makes the block sit visibly off-centre (84px above, 132px below).
   The trailing paragraph's own 16px margin lands the same way, so it's
   cleared too -- scoped to :last-child so heads that do sit above content
   keep their normal 48px + 16px separation. */
.section-head:last-child { margin-bottom: 0; }
.section-head:last-child > :last-child { margin-bottom: 0; }
.section-head.center { margin-left: auto; margin-right: auto; text-align: center; }

/* Section intros that sit directly above a full-width grid (e.g. the SAFE/ECO
   system cards) span the grid's width instead of the default narrow measure,
   so the intro copy and the grid below it read as one aligned block. */
.section-head:has(+ .system-grid) { max-width: none; }
.section-head:has(+ .system-grid) p { font-size: 1.08rem; }
.section-head:has(+ .stat-band) { max-width: none; }
.section-head:has(+ .card-grid) { max-width: none; }
.section-head:has(+ .exploded-scroll) { max-width: none; }
.section-head:has(+ .exploded-scroll) p { font-size: 1.08rem; }
.section-head:has(+ .project-grid) { max-width: none; }
.section-head:has(+ .location-grid) { max-width: none; }
.section-head:has(+ .flow-diagram) { max-width: none; }

/* "How We Work With You" intro on the three persona pages: centered, full
   header width, with extra line-height so the paragraph reads as a more
   generous, spread-out block rather than a tight default line-height. */
#work-with-you .section-head {
  max-width: none;
  margin-left: auto;
  margin-right: auto;
  text-align: center;
}
#work-with-you .section-head p { line-height: 2; }

/* ---------- Pillars (Cost, Carbon, Complexity, Compliance) ---------- */
.pillar-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 1px;
  background: var(--color-line);
  border: 1px solid var(--color-line);
  border-radius: var(--radius-lg);
  overflow: hidden;
}
.pillar {
  background: var(--color-white);
  padding: 32px 26px;
  transition: background-color var(--dur-base) var(--ease-smooth);
}
@media (hover: hover) and (pointer: fine) {
  .pillar:hover { background: var(--color-paper-dim); }
}
.pillar .pillar-letter {
  font-family: var(--font-mono);
  font-size: 0.75rem;
  color: var(--color-steel);
  letter-spacing: 0.1em;
}
/* h3 for correct hierarchy (these sit under the section's h2), sized as the
   card heading the design calls for rather than as a default h3. */
.pillar h3, .pillar h4 { font-size: 1.05rem; font-weight: 600; margin-top: 14px; margin-bottom: 8px; }
.pillar p { font-size: 0.92rem; margin: 0; }
.section-head:has(+ .pillar-grid) { max-width: none; }
#why-not-x .section-head { max-width: none; }
.section-head:has(+ .phase-flow) { max-width: none; }
#who-we-serve .section-head { max-width: none; }
#featured-work .section-head { max-width: none; }
.section-head:has(+ .video-grid) { max-width: none; }
.section-head:has(+ .article-columns) { max-width: none; }
.section-head:has(+ .callout) { max-width: none; }
.section-head:has(+ .finish-option) { max-width: none; }
.section-head:has(+ .step-list) { max-width: none; }
/* A section-head that's the sole content in its section (paired with a
   single outline CTA, no grid/list sibling to key off) -- same "text
   stops at 640px inside a much wider box" issue as the :has(+ ...) cases
   above, just with no sibling to select on. */
.section-head:has(.btn-outline) { max-width: none; }

/* ---------- Cards ---------- */
.card-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 24px; }
/* Opt-in 2x2 for grids holding four cards, which would otherwise leave one
   card orphaned on a second row under the default three columns. */
.card-grid.cols-2 { grid-template-columns: repeat(2, 1fr); }
.card {
  background: var(--color-white);
  border: 1px solid var(--color-line);
  border-radius: var(--radius-lg);
  padding: 30px 26px;
  box-shadow: var(--shadow-card);
  transition: transform var(--dur-base) var(--ease-out), box-shadow var(--dur-base) var(--ease-out);
}
@media (hover: hover) and (pointer: fine) {
  .card:hover { transform: translateY(-3px); box-shadow: var(--shadow-lift); }
  .card:hover .icon-badge { transform: translateY(-2px) scale(1.06); }
}
.card h3 { margin-bottom: 10px; }
.card p { font-size: 0.94rem; margin-bottom: 0; }
.card .icon-badge {
  width: 46px; height: 46px;
  border-radius: var(--radius);
  background: var(--color-accent-tint);
  color: var(--color-accent);
  display: flex; align-items: center; justify-content: center;
  margin-bottom: 18px;
  transition: transform var(--dur-base) var(--ease-out);
}
.card .icon-badge svg { width: 24px; height: 24px; }
/* Who-We-Serve cards with a full background image (home page). Scoped modifier
   so the shared .card used elsewhere is untouched. */
.card.serve-card {
  position: relative;
  overflow: hidden;
  border: none;
  min-height: 320px;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  color: var(--color-white);
  background-size: cover;
  background-position: center;
}
.card.serve-card::before {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(20,24,31,0.10) 0%, rgba(20,24,31,0.55) 48%, rgba(20,24,31,0.92) 100%);
}
.card.serve-card > * { position: relative; z-index: 1; }
.card.serve-card h3 { color: var(--color-white); }
.card.serve-card h3 a { color: inherit; font-weight: inherit; }
.card.serve-card p { color: rgba(255,255,255,0.85); }
.card.serve-card a { color: var(--color-white); font-weight: 600; }
.card.serve-card a:hover { color: var(--color-accent); }

/* ---------- Alternatives comparison bracket ---------- */
.compare-bracket { display: grid; grid-template-columns: 1fr 140px 1fr; align-items: stretch; gap: 0; }
/* space-between distributes the leftover height (list height matches the
   4C panel's height via grid align-items: stretch) evenly as gaps between
   the 3 cards, so the stack spans the same top-to-bottom range as the
   panel instead of floating centered with empty space above/below it. */
.compare-alt-list { display: flex; flex-direction: column; gap: 16px; justify-content: space-between; }
.compare-alt-card {
  background: var(--color-paper-dim);
  border: 1px solid var(--color-line);
  border-radius: var(--radius-lg);
  padding: 24px 26px;
  box-shadow: var(--shadow-card);
  display: flex;
  align-items: center;
  gap: 18px;
  /* Content-sized, not stretched -- the list's own height still matches the
     4C panel's height (grid align-items: stretch), but that leftover space
     becomes bigger gaps BETWEEN cards via justify-content: space-between,
     instead of taller cards with empty top/bottom padding. */
  flex: 0 0 auto;
  transition: transform var(--dur-base) var(--ease-out), box-shadow var(--dur-base) var(--ease-out);
}
@media (hover: hover) and (pointer: fine) {
  .compare-alt-card:hover { transform: translateY(-3px); box-shadow: var(--shadow-lift); }
}
.compare-alt-icon {
  width: 40px; height: 40px;
  border-radius: 50%;
  background: var(--color-accent-tint);
  color: var(--color-accent);
  display: flex; align-items: center; justify-content: center;
  flex-shrink: 0;
}
.compare-alt-icon svg { width: 20px; height: 20px; stroke-width: 1.6; }
.compare-alt-card h3 { font-size: 1.05rem; color: var(--color-accent); margin-bottom: 8px; }
.compare-alt-card p { font-size: 0.86rem; color: var(--color-ink); margin: 2px 0; }
/* The img is taken out of flow (position: absolute) so its own intrinsic
   aspect ratio can never contribute back into the grid row's auto-sizing --
   that circular dependency is what previously inflated the whole row
   height and left the 4C panel's content floating in empty space. */
.compare-bracket-media { position: relative; width: 100%; height: 100%; }
.compare-bracket-media img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; display: block; }
.compare-4c-panel {
  background: var(--color-accent);
  color: var(--color-white);
  border-radius: var(--radius-lg);
  padding: 40px;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 28px;
}
.compare-4c-panel h3 { color: var(--color-white); font-size: 1.5rem; margin: 0; }
.compare-4c-col h4 { color: var(--color-white); font-size: 1rem; margin-bottom: 12px; }
.compare-4c-col ul { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 6px; }
.compare-4c-col li { position: relative; padding-left: 20px; font-size: 0.94rem; color: rgba(255,255,255,0.92); }
.compare-4c-col li::before { content: ""; position: absolute; left: 2px; top: 0.55em; width: 5px; height: 5px; background: rgba(255,255,255,0.7); }

/* ---------- System comparison cards ---------- */
.system-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 28px; }
.system-card {
  background: var(--color-white);
  border: 1px solid var(--color-line);
  border-radius: var(--radius-lg);
  overflow: hidden;
  box-shadow: var(--shadow-card);
  transition: transform var(--dur-base) var(--ease-out), box-shadow var(--dur-base) var(--ease-out);
}
@media (hover: hover) and (pointer: fine) {
  .system-card:hover { transform: translateY(-3px); box-shadow: var(--shadow-lift); }
}
.system-card .system-card-head {
  padding: 30px 30px 24px;
  border-bottom: 1px solid var(--color-line);
}
.system-card.safe .system-card-head { background: var(--color-ink); }
.system-card.safe .system-card-head h3,
.system-card.safe .system-card-head .tag { color: var(--color-white); }
.system-card.eco .system-card-head { background: var(--color-safe-tint); }
.system-card .tag {
  display: inline-block;
  font-family: var(--font-mono);
  font-size: 0.7rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-accent);
  margin-bottom: 10px;
}
.system-card-image {
  padding: 24px 30px 0;
  text-align: center;
  background: var(--color-paper-dim);
}
.system-card-image img { max-height: 260px; width: auto; max-width: 100%; margin: 0 auto; }
.system-card-image.photo { padding: 0; }
.system-card-image.photo img {
  display: block;
  width: 100%;
  max-width: none;
  max-height: none;
  height: 240px;
  object-fit: cover;
}
.system-card-body { padding: 26px 30px 30px; }
/* Equalize the head / image / body rows across both system cards so the colored
   heads match height even when one description runs longer. Scoped to the
   image-bearing two-column layout (home + systems pages); location-page cards,
   which have no image, are left untouched. */
@supports (grid-template-rows: subgrid) {
  @media (min-width: 901px) {
    .system-grid:has(.system-card-image) { grid-template-rows: auto auto auto; }
    .system-grid:has(.system-card-image) .system-card {
      display: grid;
      grid-row: span 3;
      grid-template-rows: subgrid;
    }
  }
}
.spec-list { list-style: none; margin: 0 0 22px; padding: 0; }
.spec-list li {
  display: flex;
  justify-content: space-between;
  padding: 11px 0;
  border-bottom: 1px solid var(--color-line);
  font-size: 0.92rem;
}
.spec-list li:last-child { border-bottom: none; }
.spec-list .spec-label { color: var(--color-steel); }
.spec-list .spec-value { font-family: var(--font-mono); color: var(--color-ink); font-weight: 500; text-align: right; }
/* This list's values are full phrases, not short data points, so the
   right-aligned wrap used elsewhere reads ragged. Fix the label to a set
   width and left-align the value so long entries wrap cleanly underneath. */
#service-options .spec-list li { display: grid; grid-template-columns: 150px 1fr; gap: 4px 20px; align-items: baseline; }
#service-options .spec-list .spec-label { white-space: nowrap; }
#service-options .spec-list .spec-value { text-align: left; }

/* ---------- Stat band ---------- */
.stat-band {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 32px;
  padding: 48px 0;
  border-top: 1px solid var(--color-line);
  border-bottom: 1px solid var(--color-line);
  /* Center each stat as a block instead of ragged-left, so the row reads as
     one evenly balanced strip regardless of how wide each figure is. */
  text-align: center;
}
.stat-band .stat-num {
  font-family: var(--font-mono);
  font-size: 2.2rem;
  color: var(--color-accent);
  display: block;
}
.stat-band .stat-label { font-size: 0.85rem; color: var(--color-steel); margin-top: 6px; }
/* Three-up variant. Lives here rather than in an inline style so the mobile
   rules further down can still collapse it — an inline grid-template-columns
   outranks a media query and kept this band at three columns on phones. */
.stat-band-3 { grid-template-columns: repeat(3, 1fr); }

/* ---------- Project cards ---------- */
/* ---------- Video embed (responsive 16:9) ---------- */
/* Holds 2 videos today; auto-fit lets a 3rd slot in later without a layout change. */
.video-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 24px;
}
.video-embed {
  position: relative;
  width: 100%;
  padding-top: 56.25%;
  border-radius: var(--radius-lg);
  overflow: hidden;
  box-shadow: var(--shadow-card);
  background: var(--color-ink);
}
.video-embed iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }
/* Same 16:9 shell used as a link, for outlets whose player can't be embedded
   (CBS 8 blocks third-party embedding), so the tile still sits flush beside a
   real embed instead of leaving a ragged grid. */
/* Light card rather than the dark base the iframe siblings use: a black
   panel beside a playing video reads as a dead/failed embed, where a white
   card reads as a deliberate link. */
a.video-embed {
  position: relative;
  display: block;
  text-decoration: none;
  background: radial-gradient(120% 140% at 85% 100%, var(--color-accent-tint) 0%, var(--color-white) 55%);
  border: 1px solid var(--color-line);
  box-shadow: var(--shadow-card);
  overflow: hidden;
}
a.video-embed:hover { text-decoration: none; }
/* Thin accent bar along the bottom, revealed on hover -- the same "now
   playing" affordance the iframe tiles get for free from the video itself. */
a.video-embed::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 4px;
  background: linear-gradient(90deg, var(--color-accent), var(--color-accent-dark));
  opacity: 0;
  transform: scaleX(0.6);
  transform-origin: center;
}
@media (hover: hover) and (pointer: fine) {
  a.video-embed { transition: transform var(--dur-base) var(--ease-out), box-shadow var(--dur-base) var(--ease-out); }
  a.video-embed:hover { transform: translateY(-3px); box-shadow: var(--shadow-lift); }
  a.video-embed:hover .video-link-play { background: var(--color-accent); color: var(--color-white); box-shadow: 0 8px 20px rgba(0, 138, 153, 0.35); }
  a.video-embed:hover::after { opacity: 1; transform: scaleX(1); }
  a.video-embed::after { transition: opacity var(--dur-base) var(--ease-out), transform var(--dur-base) var(--ease-out); }
}
.video-link-body {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 12px;
  padding: 28px;
  text-align: center;
  color: var(--color-ink);
}
/* Play button and the outlet's own logo, as one centered horizontal pair. */
.video-link-brand { display: flex; align-items: center; gap: 16px; margin-bottom: 6px; }
.video-link-play {
  width: 56px;
  height: 56px;
  flex-shrink: 0;
  border-radius: 50%;
  background: var(--color-white);
  color: var(--color-accent);
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 6px 16px rgba(0, 138, 153, 0.18), inset 0 0 0 1px var(--color-accent-tint);
  transition: background-color var(--dur-base) var(--ease-smooth), color var(--dur-base) var(--ease-smooth), box-shadow var(--dur-base) var(--ease-smooth);
}
.video-link-play svg { width: 20px; height: 20px; margin-left: 3px; }
.video-link-logo { width: 50px; height: 50px; border-radius: var(--radius-lg); display: block; box-shadow: var(--shadow-card); }
.video-link-title { font-size: 0.96rem; font-weight: 600; color: var(--color-ink); max-width: 32ch; }
.video-link-cta {
  font-size: 0.86rem;
  font-weight: 600;
  color: var(--color-accent);
  padding: 8px 16px;
  border-radius: 999px;
  background: var(--color-accent-tint);
  transition: background-color var(--dur-base) var(--ease-smooth), color var(--dur-base) var(--ease-smooth);
}
@media (hover: hover) and (pointer: fine) {
  a.video-embed:hover .video-link-cta { background: var(--color-accent); color: var(--color-white); }
}

/* ---------- Build-progress photo gallery ---------- */
.photo-gallery { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; }
.photo-gallery figure { margin: 0; }
.photo-gallery img {
  width: 100%;
  height: 200px;
  object-fit: cover;
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-card);
  display: block;
  transition: transform var(--dur-base) var(--ease-out);
}
@media (hover: hover) and (pointer: fine) {
  .photo-gallery img:hover { transform: scale(1.03); }
}
.photo-gallery figcaption { margin-top: 8px; font-size: 0.82rem; color: var(--color-steel); }
@media (max-width: 900px) {
  .photo-gallery { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 640px) {
  .photo-gallery { grid-template-columns: 1fr; }
}
.photo-gallery.cols-4 { grid-template-columns: repeat(4, 1fr); }
@media (max-width: 900px) {
  .photo-gallery.cols-4 { grid-template-columns: 1fr 1fr; }
}
.finish-option-label { font-family: var(--font-mono); font-size: 0.78rem; letter-spacing: 0.05em; text-transform: uppercase; color: var(--color-accent); font-weight: 700; margin-bottom: 14px; display: block; }
.finish-option + .finish-option { margin-top: 40px; }

/* ---------- Full-bleed feature (edge-to-edge photo + content split) ---------- */
section.full-bleed-hero { padding: 0; }
.full-bleed-feature {
  display: grid;
  grid-template-columns: 1.1fr 1fr;
  min-height: 560px;
  background: var(--color-ink);
}
.full-bleed-feature-media { position: relative; overflow: hidden; }
.full-bleed-feature-media img { width: 100%; height: 100%; object-fit: cover; display: block; min-height: 320px; transition: transform var(--dur-base) var(--ease-out); }
@media (hover: hover) and (pointer: fine) {
  .full-bleed-feature-media:hover img { transform: scale(1.04); }
}
.full-bleed-feature-media .full-bleed-tag {
  position: absolute;
  left: 24px;
  bottom: 24px;
  background: rgba(20,24,31,0.75);
  color: var(--color-white);
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  padding: 8px 14px;
  border-radius: var(--radius);
}
.full-bleed-feature-body {
  padding: 64px 64px;
  color: var(--color-white);
  display: flex;
  flex-direction: column;
  justify-content: center;
}
.full-bleed-feature-body .kicker { color: var(--color-accent); }
.full-bleed-feature-body h1, .full-bleed-feature-body h2 { color: var(--color-white); margin-bottom: 16px; }
.full-bleed-feature-body p { color: rgba(255,255,255,0.85); margin-bottom: 18px; line-height: 1.7; }
.full-bleed-feature-stats {
  display: flex;
  flex-direction: column;
  gap: 16px;
  margin: 20px 0 28px;
  padding: 20px 0;
  border-top: 1px solid rgba(255,255,255,0.15);
  border-bottom: 1px solid rgba(255,255,255,0.15);
}
.full-bleed-feature-stats > div { display: flex; align-items: baseline; gap: 14px; }
.full-bleed-feature-stats .stat-num { flex: 0 0 auto; min-width: 76px; font-family: var(--font-mono); font-size: 1.5rem; font-weight: 700; color: var(--color-white); line-height: 1; }
.full-bleed-feature-stats .stat-label { flex: 1; font-size: 0.85rem; color: rgba(255,255,255,0.75); }
.full-bleed-feature-certs { display: flex; flex-direction: column; gap: 10px; margin-top: 8px; }
.full-bleed-feature-certs .badge { align-self: flex-start; }
@media (max-width: 900px) {
  .full-bleed-feature { grid-template-columns: 1fr; min-height: 0; }
  .full-bleed-feature-media img { min-height: 260px; }
  .full-bleed-feature-body { padding: 40px 28px; }
}

/* ---------- Slideshow (image carousel with fade transitions) ---------- */
.slideshow {
  position: relative;
  aspect-ratio: 16 / 9;
  border-radius: var(--radius-lg);
  overflow: hidden;
  box-shadow: var(--shadow-lift);
  background: var(--color-ink);
}
.slideshow-slide {
  position: absolute;
  inset: 0;
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.6s ease;
}
.slideshow-slide.is-active { opacity: 1; visibility: visible; }
.slideshow-slide img { width: 100%; height: 100%; object-fit: cover; display: block; }
/* Product renders (the exploded assemblies) are transparent PNG/WebP, so the
   slideshow's dark base shows through and reads as an unintended black box.
   These sit on a light ground instead, and use contain rather than cover so
   the full assembly stays visible instead of being cropped top and bottom. */
.slideshow-slide.is-product { background: var(--color-paper); }
.slideshow-slide.is-product img {
  object-fit: contain;
  padding: 40px;
  box-sizing: border-box;
}
.slideshow-caption {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  padding: 32px 88px 20px 24px;
  background: linear-gradient(180deg, transparent, rgba(20,24,31,0.85) 70%);
  color: var(--color-white);
  font-size: 0.94rem;
}
.slideshow-arrow {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  width: 40px;
  height: 40px;
  border-radius: 50%;
  border: none;
  background: rgba(20,24,31,0.5);
  color: var(--color-white);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  z-index: 2;
  transition: background 0.15s ease;
}
.slideshow-arrow:hover { background: rgba(20,24,31,0.8); }
.slideshow-arrow svg { width: 20px; height: 20px; }
.slideshow-arrow.prev { left: 16px; }
.slideshow-arrow.next { right: 16px; }
.slideshow-dots {
  position: absolute;
  right: 24px;
  bottom: 22px;
  display: flex;
  gap: 8px;
  z-index: 2;
}
.slideshow-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  border: none;
  background: rgba(255,255,255,0.45);
  cursor: pointer;
  padding: 0;
  transition: background 0.15s ease, transform 0.15s ease;
}
.slideshow-dot.is-active { background: var(--color-white); transform: scale(1.25); }
@media (max-width: 640px) {
  .slideshow { aspect-ratio: 4 / 3; }
  .slideshow-caption { padding: 24px 24px 16px; font-size: 0.86rem; }
  .slideshow-dots { right: 16px; bottom: 16px; }
}

.project-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 24px; }
.project-card {
  background: var(--color-white);
  border: 1px solid var(--color-line);
  border-radius: var(--radius-lg);
  overflow: hidden;
  box-shadow: var(--shadow-card);
  transition: transform var(--dur-base) var(--ease-out), box-shadow var(--dur-base) var(--ease-out);
}
@media (hover: hover) and (pointer: fine) {
  .project-card:hover { transform: translateY(-3px); box-shadow: var(--shadow-lift); }
}
.project-card .project-thumb {
  height: 170px;
  background: linear-gradient(135deg, var(--color-graphite), var(--color-ink));
  position: relative;
  overflow: hidden;
}
.project-card .project-thumb svg { position: absolute; inset: 0; width: 100%; height: 100%; opacity: 0.5; }
.project-card .project-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.project-card .project-thumb a { display: block; height: 100%; }
.project-card .project-thumb a img { transition: transform 0.2s ease; }
.project-card .project-thumb a:hover img { transform: scale(1.04); }
.project-card .project-body { padding: 22px 22px 26px; }
.project-card .project-tag {
  font-family: var(--font-mono);
  font-size: 0.68rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-accent);
}
.project-card h3 { font-size: 1.05rem; margin: 8px 0 4px; }
.project-card h3 a { color: inherit; text-decoration: none; }
.project-card h3 a:hover { color: var(--color-accent); text-decoration: none; }
.project-card .project-loc { font-size: 0.85rem; color: var(--color-steel); margin-bottom: 12px; }
.project-card .project-meta {
  display: flex;
  gap: 14px;
  flex-wrap: wrap;
  font-size: 0.82rem;
  color: var(--color-steel);
  border-top: 1px solid var(--color-line);
  padding-top: 12px;
}

/* ---------- Steps / process ---------- */
.step-list { list-style: none; margin: 0; padding: 0; counter-reset: step; }
.step-list li {
  counter-increment: step;
  display: grid;
  grid-template-columns: 48px 1fr;
  gap: 18px;
  padding: 22px 0;
  border-bottom: 1px solid var(--color-line);
}
.step-list li:last-child { border-bottom: none; }
.step-list li::before {
  content: counter(step, decimal-leading-zero);
  font-family: var(--font-mono);
  color: var(--color-accent);
  font-size: 1rem;
  font-weight: 500;
}
.step-list h3, .step-list h4 { font-size: 1.05rem; font-weight: 600; margin-bottom: 4px; }
.step-list p { margin: 0; font-size: 0.92rem; }

/* ---------- Flow diagram (concept-to-implementation, per audience) ---------- */
/* Mobile-first: vertical timeline with an animated "current flowing through" spine. */
.flow-diagram {
  position: relative;
  padding: 12px 4px 4px;
}
.flow-diagram .flow-track {
  position: absolute;
  top: 4px;
  bottom: 36px;
  left: 36px;
  width: 2px;
  background-image: repeating-linear-gradient(180deg, var(--color-accent) 0 8px, transparent 8px 22px);
  background-size: 2px 44px;
  animation: flow-pulse-v 1.6s linear infinite;
  opacity: 0.55;
}
@keyframes flow-pulse-v { to { background-position: 0 44px; } }
@keyframes flow-pulse-h { to { background-position: 44px 0; } }
@keyframes flow-node-glow {
  0%, 100% { box-shadow: 0 0 0 6px rgba(0, 138, 153, 0.14), 0 0 22px rgba(0, 138, 153, 0.35); }
  50% { box-shadow: 0 0 0 10px rgba(0, 138, 153, 0.22), 0 0 34px rgba(0, 138, 153, 0.6); }
}
.flow-diagram .flow-nodes {
  display: flex;
  flex-direction: column;
  gap: 30px;
  position: relative;
  z-index: 1;
}
.flow-diagram .flow-node {
  display: flex;
  align-items: flex-start;
  gap: 20px;
  text-align: left;
}
.flow-diagram .flow-node-icon {
  position: relative;
  flex-shrink: 0;
  width: 64px;
  height: 64px;
  border-radius: 50%;
  background: var(--color-ink);
  border: 2px solid var(--color-accent);
  color: var(--color-accent);
  display: flex;
  align-items: center;
  justify-content: center;
  animation: flow-node-glow 2.6s ease-in-out infinite;
}
.flow-diagram .flow-node-icon svg { width: 26px; height: 26px; }
.flow-diagram .flow-node-num {
  position: absolute;
  top: -6px;
  right: -6px;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: var(--color-accent);
  color: var(--color-ink);
  font-family: var(--font-mono);
  font-size: 0.7rem;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
}
.flow-diagram .flow-node-body { padding-top: 10px; }
.flow-diagram .flow-node h3, .flow-diagram .flow-node h4 { color: var(--color-white); font-size: 0.98rem; font-weight: 600; margin-bottom: 6px; }
.flow-diagram .flow-node p { color: rgba(255,255,255,0.62); font-size: 0.86rem; margin: 0; max-width: 46ch; }
.on-paper-dim .flow-diagram .flow-node h3, .on-paper-dim .flow-diagram .flow-node h4 { color: var(--color-ink); }
.on-paper-dim .flow-diagram .flow-node p { color: var(--color-steel); }

/* Long-form SEO copy block: split into two columns so it reads as a full-width
   article instead of a narrow strip with wasted space beside it, while each
   column keeps a comfortable line length. Heading/paragraph pairs are kept
   intact (no orphaned heading, no paragraph split mid-sentence). */
.article-columns {
  column-count: 2;
  column-gap: 56px;
}
.article-columns p { line-height: 1.7; break-inside: avoid; }
.article-columns h3 { margin-top: 32px; break-after: avoid; break-inside: avoid; }
.article-columns > :first-child { margin-top: 0; }
@media (max-width: 900px) {
  .article-columns { column-count: 1; }
}

@media (min-width: 900px) {
  .flow-diagram { padding: 40px 0 4px; }
  .flow-diagram .flow-track {
    /* 40px diagram padding-top + 32px (half the 64px icon) = the icons'
       true vertical center. The line was set to 36px on its own, landing
       35px above that center — through the number badges instead of the
       middle of the circles. */
    top: 72px;
    bottom: auto;
    left: 5%;
    right: 5%;
    width: auto;
    height: 2px;
    background-image: repeating-linear-gradient(90deg, var(--color-accent) 0 8px, transparent 8px 22px);
    background-size: 44px 2px;
    animation: flow-pulse-h 1.6s linear infinite;
  }
  .flow-diagram .flow-nodes { flex-direction: row; justify-content: space-between; gap: 12px; }
  .flow-diagram .flow-node { flex-direction: column; align-items: center; text-align: center; flex: 1; max-width: 220px; }
  .flow-diagram .flow-node-body { padding-top: 0; }
  .flow-diagram .flow-node-icon { margin-bottom: 18px; }
  .flow-diagram .flow-node p { max-width: 26ch; margin: 0 auto; }
}

/* ---------- Split ratio (custom vs. ready-to-go process breakdown) ---------- */
.split-ratio {
  position: relative;
  display: grid;
  grid-template-columns: 1fr 1fr;
  border-radius: var(--radius-lg);
  overflow: hidden;
  box-shadow: var(--shadow-lift);
}
.split-ratio-bg {
  position: absolute;
  inset: 0;
  background-size: cover;
  background-position: center;
  z-index: 0;
}
.split-ratio-panel { position: relative; z-index: 1; padding: 44px 40px; }
.split-ratio-panel.custom { background: rgba(20,24,31,0.85); color: var(--color-white); }
.split-ratio-panel.ready { background: linear-gradient(160deg, rgba(0,138,153,0.88) 0%, rgba(0,102,111,0.92) 100%); color: var(--color-white); }
.split-ratio-stat { display: flex; align-items: flex-start; gap: 14px; margin-bottom: 30px; }
.split-ratio-num { font-family: var(--font-mono); font-size: 2.6rem; font-weight: 700; line-height: 1; }
.split-ratio-label { font-size: 1.1rem; font-weight: 700; line-height: 1.3; padding-top: 6px; }

.split-ratio-cards { display: flex; flex-direction: column; }
.split-ratio-card {
  display: flex;
  gap: 14px;
  background: rgba(255,255,255,0.06);
  border: 1px solid rgba(255,255,255,0.16);
  border-radius: var(--radius);
  padding: 18px;
}
.split-ratio-card-num {
  position: relative;
  z-index: 1;
  flex-shrink: 0;
  width: 30px;
  height: 30px;
  border-radius: 50%;
  background: rgba(255,255,255,0.14);
  border: 1px solid rgba(255,255,255,0.3);
  color: var(--color-white);
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-mono);
  font-size: 0.85rem;
  font-weight: 700;
}
.split-ratio-card h4 { color: var(--color-white); margin-bottom: 4px; font-size: 0.98rem; }
.split-ratio-card p { color: rgba(255,255,255,0.66); font-size: 0.86rem; margin: 0; }
.split-ratio-foot { margin-top: 22px; font-size: 0.85rem; color: rgba(255,255,255,0.5); font-style: italic; }

.split-ratio-connector { width: 2px; height: 20px; margin: 0 0 0 32px; background: repeating-linear-gradient(180deg, rgba(255,255,255,0.5) 0 4px, transparent 4px 8px); }
.split-ratio-connector.small { height: 10px; margin-left: 26px; }

.split-ratio-stack { display: flex; flex-direction: column; }
.split-ratio-bar {
  position: relative;
  display: flex;
  align-items: center;
  gap: 12px;
  background: rgba(255,255,255,0.16);
  border: 1px solid rgba(255,255,255,0.26);
  border-radius: var(--radius);
  padding: 11px 16px;
  font-size: 0.86rem;
  font-weight: 600;
  color: var(--color-white);
}
.split-ratio-bar-num {
  flex-shrink: 0;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: rgba(255,255,255,0.24);
  border: 1px solid rgba(255,255,255,0.4);
  color: var(--color-white);
  font-family: var(--font-mono);
  font-size: 0.72rem;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
}
.split-ratio-infra {
  margin-top: 20px;
  border: 1px dashed rgba(255,255,255,0.45);
  border-radius: var(--radius);
  padding: 14px 16px;
  text-align: center;
}
.split-ratio-infra .infra-tag { font-family: var(--font-mono); font-size: 0.7rem; letter-spacing: 0.06em; font-weight: 700; }
.split-ratio-infra p { margin: 6px 0 0; font-size: 0.8rem; color: rgba(255,255,255,0.82); }

.split-ratio-arrow {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 44px;
  height: 44px;
  border-radius: 50%;
  background: var(--color-white);
  color: var(--color-ink);
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: var(--shadow-lift);
  z-index: 2;
}
.split-ratio-arrow svg { width: 20px; height: 20px; }

@media (max-width: 900px) {
  .split-ratio { grid-template-columns: 1fr; }
  .split-ratio-arrow { position: static; transform: rotate(90deg); margin: -10px auto; }
}

/* ---------- Phase flow (chevron-linked process steps) ---------- */
.phase-flow { display: flex; gap: 24px; }
.phase-flow-step {
  flex: 1;
  min-width: 0;
  background: linear-gradient(180deg, var(--color-paper) 0%, rgba(247,245,241,0) 100%);
  border-radius: var(--radius-lg);
  padding: 32px 18px 30px;
  text-align: center;
}
.phase-flow-num { display: block; font-family: var(--font-heading); font-size: 2rem; font-weight: 800; color: var(--color-ink); line-height: 1; margin-bottom: 10px; }
.phase-flow-title { display: flex; align-items: center; justify-content: center; min-height: 2.4em; font-size: 0.86rem; letter-spacing: 0.05em; text-transform: uppercase; font-weight: 700; color: var(--color-ink); margin: 0; }
.phase-flow-chevron {
  width: 56px;
  height: 46px;
  margin: 22px auto 0;
  clip-path: polygon(0 0, 62% 0, 100% 50%, 62% 100%, 0 100%, 24% 50%);
  background: linear-gradient(135deg, var(--color-accent) 0%, var(--color-accent-dark) 100%);
  position: relative;
  z-index: 1;
}
.phase-flow-desc { margin-top: 20px; font-size: 0.84rem; color: var(--color-steel); line-height: 1.5; }

@media (max-width: 900px) {
  .phase-flow { flex-wrap: wrap; }
  .phase-flow-step { flex: 1 1 calc(50% - 12px); }
}
@media (max-width: 640px) {
  .phase-flow-step { flex: 1 1 100%; }
}

/* ---------- Exploded diagram (photo + labeled component stack) ---------- */
.exploded-diagram { display: grid; grid-template-columns: 1fr 1fr; gap: 56px; align-items: center; }
.exploded-photo {
  border-radius: var(--radius-lg);
  overflow: hidden;
  box-shadow: var(--shadow-lift);
}
.exploded-photo img { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; display: block; transition: transform var(--dur-base) var(--ease-out); }
@media (hover: hover) and (pointer: fine) {
  .exploded-photo:hover img { transform: scale(1.04); }
}
.exploded-stack { display: flex; flex-direction: column; gap: 40px; }
.exploded-row { display: flex; align-items: center; gap: 16px; }
.exploded-row:nth-child(2) { margin-left: 44px; }
.exploded-row:nth-child(3) { margin-left: 88px; }
.exploded-icon {
  width: 60px; height: 60px;
  border-radius: 50%;
  background: var(--color-accent-tint);
  color: var(--color-accent);
  display: flex; align-items: center; justify-content: center;
  flex-shrink: 0;
}
.exploded-icon svg { width: 28px; height: 28px; }
.exploded-line { flex: 1; min-width: 24px; border-top: 2px dotted var(--color-line); }
.exploded-label { white-space: nowrap; font-size: 1rem; color: var(--color-ink); }
.exploded-label strong { font-weight: 800; }

@media (max-width: 900px) {
  .exploded-diagram { grid-template-columns: 1fr; }
  .exploded-row:nth-child(2) { margin-left: 24px; }
  .exploded-row:nth-child(3) { margin-left: 48px; }
}
@media (max-width: 640px) {
  .exploded-row, .exploded-row:nth-child(2), .exploded-row:nth-child(3) { margin-left: 0; }
  .exploded-label { white-space: normal; }
}

/* ---------- Exploded system scroll build-up (roof / interior / exterior
   layers stack in as the visitor scrolls past each step) ----------
   The three layers each own a horizontal band of the frame -- roof up top,
   interior partitions through the middle, exterior walls along the bottom --
   so together they read as one exploded axonometric of the building. Each
   band rises into its slot from below and *stays*, so the assembly builds up
   cumulatively as the visitor scrolls: roof, then partitions beneath it, then
   the exterior walls beneath those. cccInitExplodedScroll writes each band's
   own 0-1 progress to --lp (opacity) and --ly (the remaining rise), every
   frame, straight from scroll position -- no CSS transition, so it tracks the
   scrollbar 1:1 and reverses on the way back up. */
/* Runs tight to the sections either side of it: this one already carries a
   lot of quiet space around the drawing, so the standard 84px section padding
   -- stacked on the marquee's above and the next section's below -- read as
   holes in the page rather than as rhythm. */
#one-system { padding-top: 40px; padding-bottom: 40px; }
#one-system + section { padding-top: 56px; }
.exploded-scroll { display: grid; grid-template-columns: 0.86fr 1fr; gap: 64px; margin-top: 8px; }
.exploded-scroll-media { position: relative; align-self: stretch; }
.exploded-scroll-visual {
  position: sticky;
  top: 96px;
  /* Squarer than the other media frames on the site: the exploded stack needs
     vertical room for three bands, not a landscape crop. Deliberately given no
     card treatment -- no panel, border, or shadow. The renders are transparent
     line drawings, so letting them sit straight on the page reads as a drawing
     rather than as stock imagery dropped into a component. It also means there
     is no crop edge for a layer to be sliced against as it rises in. */
  aspect-ratio: 1 / 1;
}
.exploded-layer-track {
  position: relative;
  height: 100%;
  /* Keeps the drawing composed at every stage rather than only at the end:
     with just the roof up, the stack is nudged down and scaled up so it reads
     as centred in the frame instead of stranded at the top over empty space.
     Each layer that joins pulls the camera back toward the settled view.
     cccInitExplodedScroll interpolates both values off the layer progress. */
  transform: translateY(var(--stage-shift, 0%)) scale(var(--stage-scale, 1));
  transform-origin: 50% 50%;
  will-change: transform;
}
.exploded-layer-slide {
  position: absolute;
  left: 0;
  right: 0;
  height: 44%;
  box-sizing: border-box;
  padding: 0 26px;
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: var(--lp, 1);
  transform: translateY(var(--ly, 0px));
  will-change: opacity, transform;
}
/* Bands overlap slightly; each source render carries its own whitespace, so
   the drawn geometry still separates cleanly into roof / interior / exterior.
   The offsets are nudged up by ~2.7% from an even 0/28/56 split: the roof
   render carries more transparent margin above it than the exterior render
   does below, so shifting the whole stack lands equal breathing room at the
   top and bottom of the frame. */
.exploded-layer-slide[data-step="1"] { top: -3.3%; }
.exploded-layer-slide[data-step="2"] { top: 24.7%; }
.exploded-layer-slide[data-step="3"] { top: 52.7%; }
.exploded-layer-slide img { max-width: 100%; max-height: 100%; object-fit: contain; }
/* The gap between steps is deliberate scroll room, not decoration: it
   lengthens the column so the sticky visual stays pinned for the whole
   three-step assembly instead of letting go halfway through.
   cccInitExplodedScroll maps the layer reveals onto that pinned window. The
   top padding stays small so step 01 starts level with the top of the drawing
   rather than stranded well below it. */
.exploded-scroll-steps {
  position: relative;
  display: flex;
  flex-direction: column;
  /* No fixed gap: the column stretches to the drawing's height (the frame is
     the taller grid item) and space-between distributes the three steps across
     exactly that span, so the text block keeps covering the drawing at any
     viewport width instead of only at the size it was hand-tuned for. */
  justify-content: space-between;
  gap: 0;
  padding: 0;
}
/* Progress rail: a thin track running behind the step numbers with an
   accent fill that rises as --rail-p climbs, so the assembly reads as one
   continuous journey rather than three separate call-outs. */
.exploded-scroll-steps::before {
  content: "";
  position: absolute;
  left: 11px;
  top: 15px;
  /* Runs dot-centre to dot-centre. The last step's height depends on its copy,
     so cccInitExplodedScroll measures the span and publishes it as --rail-len;
     the fallback keeps a sensible line if that never runs. */
  height: var(--rail-len, calc(100% - 15px));
  width: 2px;
  background: var(--color-line);
}
.exploded-scroll-steps::after {
  content: "";
  position: absolute;
  left: 11px;
  top: 15px;
  width: 2px;
  height: calc(var(--rail-p, 0) * var(--rail-len, calc(100% - 15px)));
  background: var(--color-accent);
}
.exploded-scroll-step {
  position: relative;
  padding-left: 40px;
  opacity: calc(0.32 + var(--sp, 1) * 0.68);
}
.exploded-scroll-step::before {
  content: "";
  position: absolute;
  left: 3px;
  top: 6px;
  width: 18px;
  height: 18px;
  /* Explicit because the global `* { box-sizing: border-box }` doesn't match
     pseudo-elements: without it the 2px border sat outside the 18px, making
     the dot 22px wide and pushing its centre 2px off the rail. */
  box-sizing: border-box;
  border-radius: 50%;
  background: var(--color-white);
  border: 2px solid var(--color-line);
  transform: scale(calc(0.72 + var(--sp, 1) * 0.28));
}
.exploded-scroll-step.is-current::before { border-color: var(--color-accent); background: var(--color-accent); }
.exploded-step-num { display: block; font-family: var(--font-mono); font-size: 1.15rem; font-weight: 500; letter-spacing: 0.08em; color: var(--color-accent); line-height: 1; margin-bottom: 10px; }
.exploded-scroll-step h3 { margin-bottom: 8px; transform: translateX(calc((1 - var(--sp, 1)) * 10px)); }
.exploded-scroll-step p { color: var(--color-steel); margin: 0; }

@media (max-width: 900px) {
  .exploded-scroll { grid-template-columns: 1fr; gap: 32px; }
  /* No sticky frame or scroll-driven assembly on mobile -- just let all three images stack
     in normal flow, in order, above the step list. */
  .exploded-scroll-visual { position: static; aspect-ratio: auto; }
  .exploded-layer-track { height: auto; transform: none !important; }
  .exploded-layer-slide { position: static; height: auto; padding: 0; margin-bottom: 16px; transform: none !important; opacity: 1 !important; }
  .exploded-scroll-steps { gap: 28px; padding: 0; }
  .exploded-scroll-steps::before, .exploded-scroll-steps::after { display: none; }
  .exploded-scroll-step { opacity: 1; padding-left: 0; max-width: none; }
  .exploded-scroll-step::before { display: none; }
  .exploded-scroll-step h3 { transform: none; }
}

/* ---------- Value split (image + copy, per-audience value sections) ---------- */
.value-split { display: grid; grid-template-columns: 1fr 1.3fr; gap: 48px; align-items: center; }
.value-split.reverse .value-split-media { order: 2; }
.value-split + .value-split { margin-top: 64px; }
.value-split-media {
  background: var(--color-white);
  border: 1px solid var(--color-line);
  border-radius: var(--radius-lg);
  padding: 10px;
  box-shadow: var(--shadow-lift);
  overflow: hidden;
}
.value-split-media img {
  display: block;
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  border-radius: 4px;
  transition: transform var(--dur-base) var(--ease-out);
}
@media (hover: hover) and (pointer: fine) {
  .value-split-media:hover img { transform: scale(1.04); }
}
/* Technical render rather than a cropped photo. Two adjustments so it sits
   level with the copy beside it instead of towering over it:
   - its own proportions, so `contain` has nothing to letterbox (the shared
     4:3 box would otherwise add dead space above and below a 1.62:1 image);
   - even columns, since the media side is normally the wider 1.3fr. */
.value-split:has(.value-split-media.is-diagram) { grid-template-columns: 1fr 1fr; }
.value-split-media.is-diagram img {
  aspect-ratio: 1597 / 985;
  object-fit: contain;
}
.value-split-body h2, .value-split-body h3 { margin-bottom: 16px; }
.value-split-body h2 .accent, .value-split-body h3 .accent { color: var(--color-accent); }
.value-split-body .kicker { margin-bottom: 10px; }
.value-split-body p { color: var(--color-steel); margin-bottom: 14px; }
.value-split-body p:last-child { margin-bottom: 0; }

/* Step visual: stylized graphic card for process steps with no literal photo (configuration, permitting, etc.) */
.step-visual {
  position: relative;
  width: 100%;
  aspect-ratio: 4 / 3;
  border-radius: 4px;
  background: var(--color-ink);
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
}
.step-visual::before {
  content: "";
  position: absolute;
  inset: 0;
  background-image:
    linear-gradient(rgba(0, 138, 153, 0.35) 1px, transparent 1px),
    linear-gradient(90deg, rgba(0, 138, 153, 0.35) 1px, transparent 1px);
  background-size: 28px 28px;
  opacity: 0.5;
}
.step-visual svg { width: 84px; height: 84px; color: var(--color-accent); position: relative; z-index: 1; }
.step-visual-tag {
  position: absolute;
  bottom: 16px;
  left: 50%;
  transform: translateX(-50%);
  font-family: var(--font-mono);
  font-size: 0.68rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: rgba(255,255,255,0.55);
  z-index: 1;
  white-space: nowrap;
}
@media (max-width: 900px) {
  .value-split, .value-split.reverse { grid-template-columns: 1fr; gap: 24px; }
  .value-split.reverse .value-split-media { order: 0; }
}

/* ---------- Guide / lead-magnet promo ---------- */
.ebook-promo-card {
  display: grid;
  grid-template-columns: 1.3fr 1fr;
  border-radius: var(--radius-lg);
  overflow: hidden;
  box-shadow: var(--shadow-lift);
}
.ebook-promo-copy { background: var(--color-ink); color: var(--color-white); padding: 48px 44px; }
.ebook-promo-copy .kicker { color: var(--color-accent); }
.ebook-promo-copy h2 { color: var(--color-white); margin-bottom: 10px; }
.ebook-promo-copy h2 .accent { color: var(--color-accent); }
.ebook-promo-sub { color: rgba(255,255,255,0.68); font-size: 1.02rem; margin-bottom: 22px; }
.ebook-promo-copy > p { color: rgba(255,255,255,0.72); margin-bottom: 16px; }
.ebook-promo-label { font-weight: 700; color: var(--color-white); margin-bottom: 10px !important; }
.ebook-promo-list { list-style: none; margin: 0 0 20px; padding: 0; }
.ebook-promo-list li {
  position: relative;
  padding-left: 22px;
  margin-bottom: 10px;
  color: rgba(255,255,255,0.72);
  font-size: 0.92rem;
}
.ebook-promo-list li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 8px;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--color-accent);
}
/* Same bullet layout as .ebook-promo-list, but for use on light backgrounds */
.dot-list { list-style: none; margin: 0 0 20px; padding: 0; }
.dot-list li {
  position: relative;
  padding-left: 22px;
  margin-bottom: 10px;
  color: var(--color-steel);
  font-size: 0.92rem;
}
.dot-list li strong { color: var(--color-ink); }
.dot-list li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 8px;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--color-accent);
}
.ebook-promo-visual {
  background: linear-gradient(160deg, var(--color-accent) 0%, var(--color-accent-dark) 100%);
  padding: 40px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 20px;
}
.ebook-cover-stack { width: 100%; max-width: 300px; display: flex; flex-direction: column; gap: 12px; }
.ebook-cover {
  background: var(--color-white);
  color: var(--color-ink);
  border-radius: var(--radius);
  padding: 22px;
  box-shadow: var(--shadow-lift);
}
.ebook-cover-brand { display: flex; align-items: center; gap: 8px; margin-bottom: 16px; }
.ebook-cover-brand img { width: 22px; height: 22px; }
.ebook-cover-brand span { font-weight: 700; font-size: 0.82rem; }
.ebook-cover h3 { font-size: 1.05rem; margin-bottom: 8px; line-height: 1.3; }
.ebook-cover p { font-size: 0.8rem; color: var(--color-steel); margin: 0; }
.ebook-cover-tag {
  display: inline-block;
  margin-top: 16px;
  font-family: var(--font-mono);
  font-size: 0.68rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--color-steel-light);
}
.ebook-cover-photo {
  width: 100%;
  aspect-ratio: 16 / 9;
  background-size: cover;
  background-position: center;
  border-radius: var(--radius);
  box-shadow: var(--shadow-lift);
}
.ebook-promo-ctas { display: flex; flex-direction: column; gap: 10px; width: 100%; max-width: 300px; }
.ebook-promo-ctas .btn { justify-content: center; width: 100%; }
@media (max-width: 900px) {
  .ebook-promo-card { grid-template-columns: 1fr; }
  .ebook-promo-copy { padding: 40px 28px; }
  .ebook-promo-visual { padding: 32px 28px; }
}

/* ---------- Callout ---------- */
/* ---------- Overview layout with panel diagram ---------- */
.overview-grid { display: grid; grid-template-columns: 1.3fr 0.7fr; gap: 40px; align-items: start; }
.overview-grid figure { margin: 0; text-align: center; }
.overview-grid figure img { max-width: 420px; margin: 0 auto; }
.overview-grid figcaption { margin-top: 12px; font-size: 0.8rem; color: var(--color-steel); }
@media (max-width: 900px) {
  .overview-grid { grid-template-columns: 1fr; }
  .overview-grid figure { order: -1; }
  /* Grid items default to min-width:auto, so the track could never shrink
     below its widest content — the 420px diagram, and the spec table on the
     system pages. On a 375px phone that pushed the whole document 77px wider
     than the viewport and the page scrolled sideways. Letting the track
     shrink, and capping the diagram to the track rather than a fixed 420px,
     keeps everything inside the screen. */
  .overview-grid > * { min-width: 0; }
  .overview-grid figure img { max-width: 100%; }
}

.callout {
  background: var(--color-white);
  border-left: 3px solid var(--color-accent);
  border-radius: 0 var(--radius) var(--radius) 0;
  padding: 20px 24px;
  font-size: 0.94rem;
  box-shadow: var(--shadow-card);
}
.callout p:last-child { margin-bottom: 0; }
.callout.form-success { animation: ccc-fade-up var(--dur-hero) var(--ease-out) both; }
/* Shown in place when a submission can't be delivered, so the form itself
   stays on the page with the visitor's answers intact. */
.callout.form-error {
  border-left-color: #b3261e;
  background: #fdf3f2;
  box-shadow: none;
  padding: 14px 18px;
  font-size: 0.9rem;
}
.callout.on-dark { background: rgba(255,255,255,0.06); border-left-color: var(--color-accent); }
.callout.on-dark p { color: rgba(255,255,255,0.78); }

/* ---------- Testimonial / founder quote ---------- */
.testimonial {
  background: var(--color-white);
  border: 1px solid var(--color-line);
  border-radius: var(--radius-lg);
  padding: 36px 40px;
  box-shadow: var(--shadow-card);
}
.testimonial blockquote {
  margin: 0 0 24px;
  font-family: var(--font-heading);
  font-style: italic;
  font-size: 1.15rem;
  line-height: 1.5;
  color: var(--color-ink);
}
.testimonial-author { display: flex; align-items: center; gap: 14px; }
.testimonial-author img {
  width: 48px;
  height: 48px;
  border-radius: 50%;
  object-fit: cover;
  object-position: 50% 15%;
  flex-shrink: 0;
}
.testimonial-author .name { font-weight: 700; color: var(--color-ink); font-size: 0.94rem; }
.testimonial-author .title { font-size: 0.85rem; color: var(--color-steel); }

/* ---------- Certification badges ---------- */
.badge-row { display: flex; gap: 14px; flex-wrap: wrap; margin-top: 20px; }
.badge {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  background: var(--color-white);
  border: 1px solid var(--color-line);
  border-radius: var(--radius);
  padding: 10px 16px;
  font-size: 0.82rem;
  color: var(--color-graphite);
  font-family: var(--font-mono);
}
.badge svg { width: 16px; height: 16px; color: var(--color-safe); flex-shrink: 0; }

/* ---------- FAQ accordion ---------- */
.faq-list { border-top: 1px solid var(--color-line); }
.faq-item { border-bottom: 1px solid var(--color-line); padding: 4px 0; }
.faq-item summary {
  cursor: pointer;
  list-style: none;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 18px 4px;
  font-weight: 600;
  font-family: var(--font-heading);
  color: var(--color-ink);
  font-size: 1rem;
  transition: color var(--dur-micro) var(--ease-smooth);
}
.faq-item summary:hover { color: var(--color-accent); }
.faq-item summary::-webkit-details-marker { display: none; }
.faq-item summary::after {
  content: "+";
  color: var(--color-accent);
  font-size: 1.3rem;
  flex-shrink: 0;
  font-family: var(--font-sans);
  margin-left: 16px;
  display: inline-block;
  transition: transform var(--dur-base) var(--ease-smooth);
}
.faq-item[open] summary::after { transform: rotate(45deg); }
/* Height is animated from main.js (native <details> can't transition open/
   closed on its own); overflow stays clipped only while that inline height
   is set, so wrapped/reflowed content is never cut off once settled open. */
.faq-item .faq-body {
  padding: 0 4px 20px;
  color: var(--color-steel);
  overflow: hidden;
  transition: height var(--dur-base) var(--ease-smooth);
}
.faq-item .faq-body p:first-child { margin-top: 0; }
.faq-item .faq-body p:last-child { margin-bottom: 0; }

/* ---------- Partner / vendor logo grid ---------- */
.partner-grid {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: 28px;
}
.partner-logo {
  height: 110px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
}
.partner-logo img {
  max-width: 100%;
  max-height: 56px;
  width: auto;
  height: auto;
  transition: transform var(--dur-base) var(--ease-out);
  /* A few of these logos are flat JPG/WebP with a baked-in white background
     (no alpha channel possible); multiply blends that white into the
     section's paper background so it reads as transparent, same trick
     already used for the homepage's logo marquee. */
  mix-blend-mode: multiply;
}
@media (hover: hover) and (pointer: fine) {
  .partner-logo:hover img { transform: scale(1.06); }
}

/* ---------- Featured partner (single large card + a grid of smaller ones) ---------- */
.section-head:has(+ .partner-feature) { max-width: none; }
.partner-feature {
  position: relative;
  display: grid;
  grid-template-columns: 260px 1fr;
  align-items: stretch;
  background: var(--color-white);
  border: 1px solid var(--color-line);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-card);
  /* Padding lives on the two panels instead, so the logo side can carry its
     own tinted background edge-to-edge rather than floating in white space. */
  overflow: hidden;
  margin-bottom: 24px;
  transition: transform var(--dur-base) var(--ease-out), box-shadow var(--dur-base) var(--ease-out);
}
/* Accent rule down the leading edge, marking this as the featured partner
   against the plainer cards below it. */
.partner-feature::before {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  width: 3px;
  background: var(--color-accent);
}
@media (hover: hover) and (pointer: fine) {
  .partner-feature:hover { transform: translateY(-2px); box-shadow: var(--shadow-lift); }
  .partner-feature:hover .partner-feature-logo img { transform: scale(1.04); }
}
/* The 24px above spaces the feature card from the small-card grid below it;
   with no grid following, that becomes trailing dead space. */
.partner-feature:last-child { margin-bottom: 0; }
.partner-feature-logo {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 40px 32px;
  background: var(--color-paper);
  border-right: 1px solid var(--color-line);
}
.partner-feature-logo img {
  max-width: 100%;
  max-height: 88px;
  width: auto;
  height: auto;
  mix-blend-mode: multiply;
  transition: transform var(--dur-base) var(--ease-out);
}
.partner-feature-body { padding: 36px 40px; }
/* Kicker reads as a small badge here so the featured card has a clear label
   rather than another line of teal text. */
.partner-feature-body .kicker {
  margin-bottom: 12px;
  padding: 5px 11px;
  border-radius: 999px;
  background: var(--color-accent-tint);
  color: var(--color-accent-dark);
}
.partner-feature-body .kicker::before { display: none; }
@media (max-width: 900px) {
  .partner-feature-logo {
    border-right: 0;
    border-bottom: 1px solid var(--color-line);
    padding: 32px 24px;
  }
  .partner-feature-body { padding: 28px 24px; }
}
.partner-feature-body h3 { margin-bottom: 12px; }
.partner-feature-body p { color: var(--color-steel); margin-bottom: 14px; }
.partner-feature-body p:last-child { margin-bottom: 0; }

.partner-card-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 24px; }
.partner-card {
  background: var(--color-white);
  border: 1px solid var(--color-line);
  border-radius: var(--radius-lg);
  padding: 26px 22px;
  box-shadow: var(--shadow-card);
  transition: transform var(--dur-base) var(--ease-out), box-shadow var(--dur-base) var(--ease-out);
}
@media (hover: hover) and (pointer: fine) {
  .partner-card:hover { transform: translateY(-3px); box-shadow: var(--shadow-lift); }
}
.partner-card h3 { font-size: 1rem; margin-bottom: 8px; }
.partner-card p { font-size: 0.9rem; color: var(--color-steel); margin-bottom: 12px; }
.partner-card p:last-child { margin-bottom: 0; }
@media (max-width: 900px) {
  .partner-feature { grid-template-columns: 1fr; }
  .partner-card-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 640px) {
  .partner-card-grid { grid-template-columns: 1fr; }
}

.partner-category-label {
  font-family: var(--font-mono);
  font-size: 0.7rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-steel);
  margin: 28px 0 12px;
}
.partner-category-label:first-child { margin-top: 0; }
@media (max-width: 900px) {
  .partner-grid { grid-template-columns: repeat(3, 1fr); }
}
@media (max-width: 640px) {
  .partner-grid { grid-template-columns: repeat(2, 1fr); }
}

/* ---------- City / location cards ---------- */
.location-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; }
.location-card {
  background: var(--color-white);
  border: 1px solid var(--color-line);
  border-radius: var(--radius-lg);
  padding: 24px;
  transition: box-shadow 0.15s ease, transform 0.15s ease;
}
.location-card:hover { box-shadow: var(--shadow-lift); transform: translateY(-2px); text-decoration: none; }
.location-card h3 { margin-bottom: 6px; }
.location-card p { font-size: 0.88rem; margin: 0; }
.location-card .loc-tag {
  font-family: var(--font-mono);
  font-size: 0.68rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-accent);
  margin-bottom: 8px;
  display: block;
}

/* ---------- CTA band ---------- */
.cta-band {
  background: var(--color-ink);
  color: var(--color-white);
  border-radius: var(--radius-lg);
  padding: 56px 48px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 32px;
  flex-wrap: wrap;
  position: relative;
  overflow: hidden;
}
.cta-band .blueprint-bg { position: absolute; inset: 0; opacity: 0.12; }
.cta-band > * { position: relative; z-index: 1; }
.cta-band h2 { color: var(--color-white); margin-bottom: 6px; }
.cta-band p { color: rgba(255,255,255,0.7); margin: 0; }
.cta-band .cta-actions { display: flex; gap: 14px; flex-wrap: wrap; }

/* ---------- Contact form ---------- */
.contact-grid { display: grid; grid-template-columns: 1fr 1.2fr; gap: 56px; align-items: flex-start; }
.form-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 18px; }
.form-grid .full { grid-column: 1 / -1; }
/* HubSpot-embedded form (contact.html) -- the iframe HubSpot injects here is
   sized by its own script, so this only has to stop it overflowing the card.
   Field/label styling inside the iframe is controlled from the HubSpot
   portal, not from this stylesheet. */
.hs-form-frame { width: 100%; }
label { display: block; font-size: 0.85rem; font-weight: 600; color: var(--color-ink); margin-bottom: 6px; }
input, select, textarea {
  width: 100%;
  padding: 12px 14px;
  border: 1px solid var(--color-line);
  border-radius: var(--radius);
  font-family: var(--font-sans);
  font-size: 0.94rem;
  background: var(--color-white);
  color: var(--color-ink);
  transition: border-color var(--dur-micro) var(--ease-smooth), box-shadow var(--dur-micro) var(--ease-smooth);
}
textarea { resize: vertical; min-height: 110px; }
input:focus, select:focus, textarea:focus {
  outline: none;
  border-color: var(--color-accent);
  box-shadow: 0 0 0 3px var(--color-accent-tint);
}

/* ---------- Footer ---------- */
.site-footer {
  background: var(--color-ink);
  color: rgba(255,255,255,0.6);
  padding: 60px 0 28px;
}
.footer-grid {
  display: grid;
  grid-template-columns: 1.2fr 1fr 1fr 1fr 1fr;
  gap: 28px;
  padding-bottom: 40px;
  border-bottom: 1px solid rgba(255,255,255,0.12);
}
/* Footer column labels are h2 so the footer's link groups are reachable as
   real headings; the sizing below keeps them looking exactly as before. */
.footer-grid h2, .footer-grid h4 { color: var(--color-white); font-size: 0.85rem; font-weight: 600; letter-spacing: 0.04em; margin-bottom: 16px; }
.footer-grid a {
  color: rgba(255,255,255,0.62);
  display: block;
  margin-bottom: 10px;
  font-size: 0.9rem;
  transition: color var(--dur-micro) var(--ease-smooth);
}
.footer-grid a:hover { color: var(--color-white); text-decoration: none; }
.footer-brand .brand { color: var(--color-white); }
.footer-brand p { font-size: 0.88rem; margin-top: 14px; max-width: 34ch; }
.footer-bottom {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding-top: 24px;
  font-size: 0.8rem;
  flex-wrap: wrap;
  gap: 10px;
}
.footer-bottom a { color: rgba(255,255,255,0.6); transition: color var(--dur-micro) var(--ease-smooth); }
.footer-bottom a:hover { color: var(--color-white); }

/* ---------- Table (specs) ---------- */
table { width: 100%; border-collapse: collapse; margin: 0 0 20px; }
th, td { text-align: left; padding: 12px 14px; border-bottom: 1px solid var(--color-line); font-size: 0.9rem; }
th { font-family: var(--font-heading); color: var(--color-ink); font-size: 0.82rem; }
td { color: var(--color-steel); }

/* ---------- Utility ---------- */
.text-center { text-align: center; }
.mt-0 { margin-top: 0; }
.eyebrow-light { color: rgba(255,255,255,0.6); }

/* ---------- Mobile ---------- */
@media (max-width: 900px) {
  .hero-stats { gap: 24px; }
  .pillar-grid { grid-template-columns: repeat(2, 1fr); }
  .card-grid, .project-grid, .location-grid { grid-template-columns: repeat(2, 1fr); }
  .system-grid { grid-template-columns: 1fr; }
  .compare-bracket { grid-template-columns: 1fr; gap: 28px; }
  .compare-bracket-media { display: none; }
  .stat-band { grid-template-columns: repeat(2, 1fr); }
  .footer-grid { grid-template-columns: 1fr 1fr; }
  .form-grid { grid-template-columns: 1fr; }
  .contact-grid { grid-template-columns: 1fr; gap: 36px; }
}

@media (max-width: 640px) {
  .main-nav { display: none; }
  .main-nav.open-mobile {
    display: flex;
    flex-direction: column;
    position: absolute;
    top: 84px;
    left: 0;
    right: 0;
    background: var(--color-white);
    padding: 16px 32px;
    border-bottom: 1px solid var(--color-line);
    gap: 4px;
  }
  .main-nav.open-mobile > * {
    opacity: 0;
    animation: ccc-fade-up var(--dur-base) var(--ease-out) forwards;
  }
  .main-nav.open-mobile > *:nth-child(1) { animation-delay: 30ms; }
  .main-nav.open-mobile > *:nth-child(2) { animation-delay: 70ms; }
  .main-nav.open-mobile > *:nth-child(3) { animation-delay: 110ms; }
  .main-nav.open-mobile > *:nth-child(4) { animation-delay: 150ms; }
  .main-nav.open-mobile > *:nth-child(5) { animation-delay: 190ms; }
  .menu-toggle { display: flex; align-items: center; justify-content: center; }
  /* Logo + CTA + hamburger no longer fit the desktop spacing under ~420px;
     tighten the header shell so it stays on one line instead of overflowing. */
  .site-header .wrap { padding: 0 16px; }
  .header-cta { padding: 10px 16px; font-size: 0.82rem; margin-left: 8px; }
  .brand .mark-full { height: 40px; }
  .card-grid, .project-grid, .location-grid, .pillar-grid { grid-template-columns: 1fr; }
  /* Needed explicitly: .card-grid.cols-2 outranks the single-class rule above,
     so without this the 2x2 grid would stay two-across on phones. */
  .card-grid.cols-2 { grid-template-columns: 1fr; }
  .stat-band { grid-template-columns: 1fr 1fr; }
  .footer-grid { grid-template-columns: 1fr; }
  .cta-band { flex-direction: column; align-items: flex-start; }
  section { padding: 56px 0; }
  .hero { padding: 64px 0 56px; }
}

/* ---------- Accessibility controls ----------
   The launcher button and panel are injected by main.js on every page, so the
   markup lives in one place instead of being duplicated across all pages.
   Each setting is stored as a data-a11y-* attribute on <html> and persisted to
   localStorage, which is why every rule below is scoped off the root element:
   one attribute flip re-styles the whole document with no per-page work.

   These are accessibility *enhancements*. They are not a conformance claim. */

/* Text scaling. Every font-size in this stylesheet is rem-based, so changing
   the root font-size scales all typography together. Spacing stays in px on
   purpose — text grows without the layout stretching apart. */
html[data-a11y-scale] { font-size: var(--a11y-scale, 100%); }
/* At large scales long unbroken strings would otherwise push the page sideways. */
html[data-a11y-scale] body { overflow-wrap: break-word; }

/* Readable font. Verdana-first stack: high x-height, open apertures, and
   already present on essentially every OS, so this costs no extra download. */
html[data-a11y-font="readable"] {
  --font-heading: Verdana, "DejaVu Sans", "Segoe UI", Tahoma, sans-serif;
  --font-sans: Verdana, "DejaVu Sans", "Segoe UI", Tahoma, sans-serif;
  --font-mono: Consolas, "DejaVu Sans Mono", "Courier New", monospace;
}
html[data-a11y-font="readable"] body {
  line-height: 1.75;
  letter-spacing: 0.012em;
  -webkit-font-smoothing: auto;
}
html[data-a11y-font="readable"] h1,
html[data-a11y-font="readable"] h2,
html[data-a11y-font="readable"] h3,
html[data-a11y-font="readable"] h4 { letter-spacing: 0; }

/* High contrast. Re-points the palette tokens rather than restyling
   components, so dark sections (which paint from --color-ink) stay dark and
   simply get stronger, while light sections go to true black on true white. */
html[data-a11y-contrast="on"] {
  --color-ink: #000000;
  --color-graphite: #000000;
  --color-steel: #1c1c1c;
  --color-steel-light: #333333;
  --color-paper: #ffffff;
  --color-paper-dim: #ffffff;
  --color-line: #000000;
  --color-accent: #005f66;
  --color-accent-dark: #00454a;
  --color-accent-tint: #ffffff;
  --color-purple: #4b2fa8;
  --color-purple-tint: #ffffff;
  --color-green: #4a5c12;
  --color-green-tint: #ffffff;
  --shadow-card: 0 0 0 1px #000000;
  --shadow-lift: 0 0 0 2px #000000;
}
html[data-a11y-contrast="on"] body { background: #ffffff; color: #000000; }
html[data-a11y-contrast="on"] p { color: #1c1c1c; }
/* Dark sections set their own translucent white text; take it to full white. */
html[data-a11y-contrast="on"] .page-hero p.lede,
html[data-a11y-contrast="on"] .cta-band p,
html[data-a11y-contrast="on"] .site-footer,
html[data-a11y-contrast="on"] .site-footer a,
html[data-a11y-contrast="on"] .site-footer p { color: #ffffff; }
/* Photo backdrops sit behind white hero text — hold them well back so the
   text keeps a solid dark field rather than competing with the image. */
html[data-a11y-contrast="on"] .hero-photo-bg { opacity: 0.22; }
html[data-a11y-contrast="on"] .card,
html[data-a11y-contrast="on"] .project-card,
html[data-a11y-contrast="on"] .faq-item { border: 1px solid #000000; }

/* Highlight links. Underline plus a tinted band so links are distinguishable
   without relying on colour alone. */
html[data-a11y-links="on"] main a:not(.btn),
html[data-a11y-links="on"] .site-footer a:not(.btn) {
  text-decoration: underline;
  text-underline-offset: 2px;
  text-decoration-thickness: 2px;
  background: #fff3c4;
  color: #000000;
  box-shadow: 0 0 0 2px #fff3c4;
  border-radius: 2px;
}
html[data-a11y-links="on"] main a:not(.btn):hover,
html[data-a11y-links="on"] main a:not(.btn):focus-visible { background: #ffe27a; box-shadow: 0 0 0 2px #ffe27a; }
html[data-a11y-links="on"] .a11y-panel a { background: none; box-shadow: none; }

/* Reduced motion, driven by the user's choice in the panel. Mirrors the
   prefers-reduced-motion block near the top of this file so the two routes to
   "calm the page down" produce the same result. main.js also skips wiring
   most scroll-linked motion when this is on -- the exploded diagram is the one
   exception, since its --lp there decides which layers of the drawing are
   shown at all, which is content rather than decoration (see
   cccInitExplodedScroll). */
html[data-a11y-motion="reduce"] *,
html[data-a11y-motion="reduce"] *::before,
html[data-a11y-motion="reduce"] *::after {
  animation-duration: 0.001ms !important;
  animation-iteration-count: 1 !important;
  transition-duration: 0.001ms !important;
  scroll-behavior: auto !important;
}
html[data-a11y-motion="reduce"] .scroll-reveal,
html[data-a11y-motion="reduce"] .scroll-reveal-scale { opacity: 1 !important; transform: none !important; }
html[data-a11y-motion="reduce"] .hero-photo-bg,
html[data-a11y-motion="reduce"] .hero .wrap,
html[data-a11y-motion="reduce"] .page-hero .hero-photo-bg,
html[data-a11y-motion="reduce"] .page-hero .wrap { transform: none !important; opacity: 1 !important; }
html[data-a11y-motion="reduce"] .logo-marquee-track { animation: none !important; }
/* .exploded-layer-slide is left alone -- see the matching note in the
   prefers-reduced-motion media block near the top of this file. */
html[data-a11y-motion="reduce"] .exploded-scroll-step::before,
html[data-a11y-motion="reduce"] .exploded-scroll-step h3 { transform: none !important; }

/* ---------- Global focus visibility ----------
   Buttons and nav links already had focus styling; this covers everything else
   a keyboard can reach (links, inputs, selects, summary) so the focus position
   is never invisible. :focus-visible keeps it off mouse clicks. */
a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
summary:focus-visible,
[tabindex]:focus-visible {
  outline: 3px solid var(--color-accent);
  outline-offset: 2px;
  border-radius: 2px;
}
html[data-a11y-contrast="on"] :focus-visible { outline: 3px solid #000000; outline-offset: 3px; }
/* Dark backgrounds need a light ring to be visible at all. */
.page-hero a:focus-visible,
.hero a:focus-visible,
.cta-band a:focus-visible,
.site-footer a:focus-visible,
.site-header a:focus-visible,
.site-header button:focus-visible { outline-color: #ffffff; }

/* ---------- Accessibility launcher + panel ---------- */
.a11y-launcher {
  position: fixed;
  right: 20px;
  bottom: 20px;
  z-index: 150;
  width: 48px;
  height: 48px;
  display: grid;
  place-items: center;
  padding: 0;
  border: 1px solid rgba(255, 255, 255, 0.18);
  border-radius: 50%;
  background: var(--color-ink);
  color: var(--color-white);
  cursor: pointer;
  box-shadow: var(--shadow-card);
  transition: background var(--dur-micro) var(--ease-smooth), transform var(--dur-micro) var(--ease-smooth);
}
.a11y-launcher:hover { background: var(--color-accent); transform: translateY(-1px); }
.a11y-launcher svg { width: 26px; height: 26px; display: block; }

.a11y-panel {
  position: fixed;
  right: 20px;
  bottom: 78px;
  z-index: 151;
  width: 300px;
  max-width: calc(100vw - 40px);
  max-height: calc(100vh - 110px);
  overflow-y: auto;
  padding: 18px;
  background: var(--color-white);
  color: var(--color-graphite);
  border: 1px solid var(--color-line);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lift);
}
.a11y-panel[hidden] { display: none; }
.a11y-panel h2 {
  font-family: var(--font-heading);
  font-size: 0.95rem;
  margin: 0 0 4px;
  color: var(--color-ink);
}
.a11y-panel .a11y-note { font-size: 0.75rem; margin: 0 0 14px; color: var(--color-steel); }
.a11y-group { margin-bottom: 14px; }
.a11y-group > h3 {
  font-family: var(--font-heading);
  font-size: 0.72rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-steel);
  margin: 0 0 7px;
}
.a11y-size-row { display: flex; align-items: center; gap: 8px; }
.a11y-size-row button {
  flex: 1;
  min-height: 40px;
  font-family: var(--font-heading);
  font-size: 0.95rem;
  font-weight: 600;
  border: 1px solid var(--color-line);
  border-radius: var(--radius);
  background: var(--color-paper);
  color: var(--color-ink);
  cursor: pointer;
}
.a11y-size-row button:hover { border-color: var(--color-accent); color: var(--color-accent); }
.a11y-size-row output {
  min-width: 52px;
  text-align: center;
  font-family: var(--font-mono);
  font-size: 0.8rem;
  color: var(--color-steel);
}
.a11y-toggle {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  width: 100%;
  min-height: 42px;
  margin-bottom: 6px;
  padding: 8px 10px;
  text-align: left;
  font-family: var(--font-sans);
  font-size: 0.85rem;
  border: 1px solid var(--color-line);
  border-radius: var(--radius);
  background: var(--color-white);
  color: var(--color-graphite);
  cursor: pointer;
}
.a11y-toggle:hover { border-color: var(--color-accent); }
.a11y-toggle .a11y-state {
  flex: none;
  font-family: var(--font-mono);
  font-size: 0.68rem;
  letter-spacing: 0.06em;
  padding: 3px 7px;
  border-radius: 999px;
  background: var(--color-paper-dim);
  color: var(--color-steel);
}
.a11y-toggle[aria-pressed="true"] {
  border-color: var(--color-accent);
  background: var(--color-accent-tint);
  color: var(--color-ink);
}
.a11y-toggle[aria-pressed="true"] .a11y-state { background: var(--color-accent); color: var(--color-white); }
.a11y-reset {
  width: 100%;
  min-height: 42px;
  font-family: var(--font-heading);
  font-size: 0.82rem;
  font-weight: 600;
  border: 1px solid var(--color-ink);
  border-radius: var(--radius);
  background: var(--color-ink);
  color: var(--color-white);
  cursor: pointer;
}
.a11y-reset:hover { background: var(--color-accent); border-color: var(--color-accent); }

/* Screen-reader-only announcements for changes that have no visible label
   change of their own (text size stepping). */
.a11y-sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

@media (max-width: 600px) {
  .a11y-launcher { right: 14px; bottom: 14px; }
  .a11y-panel { right: 14px; left: 14px; bottom: 70px; width: auto; max-width: none; }
}

/* The launcher is a floating control; when printing it is just noise. */
@media print {
  .a11y-launcher, .a11y-panel { display: none !important; }
}
