/* ════════════════════════════════════════════════════════════════════════
   Cascadiaen — Engagements (light)
   Standalone stylesheet. Deliberately does NOT share styles.css with the
   builds page, so nothing here can affect that page.
   ════════════════════════════════════════════════════════════════════════ */

:root {
  /* Light surface */
  --paper:        #F8FAFC;
  --paper-raised: #FFFFFF;

  /* Ink */
  --ink:      #0F1C2E;
  --ink-soft: #475569;
  --ink-mute: #64748B;
  --rule:        #E2E8F0;
  --rule-strong: #CBD5E1;

  /* Brand accents (shared with the dark page) */
  --blue:    #2563EB;
  --teal:    #0D9488;   /* decorative only, 3.6:1 */
  --link:    #0F766E;   /* 5.3:1 on paper, same hue */
  --emerald: #10B981;
  /* The three strands. Dark enough to carry white text. */
  --public:    #0F766E;
  --business:  #1D4ED8;
  --finance:   #1A2E45;   /* brand navy: distinct from --public teal and --business blue */

  --ember:     #CB5A1E;  /* the one sunrise amber: centre of the C mark, and the dot on the i */
  --ember-lit: #E17E2B;  /* the same sunrise amber lifted for dark grounds */

  --gradient-primary: linear-gradient(135deg, #2563EB, #0D9488, #10B981);

  --font-sans: 'DM Sans', system-ui, sans-serif;
  --font-mono: 'DM Mono', monospace;

  --space-1: 4px;   --space-2: 8px;   --space-3: 12px;  --space-4: 16px;
  --space-5: 20px;  --space-6: 24px;  --space-8: 32px;  --space-10: 40px;
  --space-12: 48px; --space-16: 64px; --space-20: 80px; --space-24: 96px;

  /* Text measures: statements, body, long-form */
  --measure-tight: 44ch;
  --measure:       64ch;
  --measure-wide:  76ch;

  --radius-sm: 6px; --radius-md: 10px; --radius-lg: 14px;

  --ease-default: 0.18s ease;
}

* { margin: 0; padding: 0; box-sizing: border-box; }

html {
  scroll-behavior: smooth;
  overflow-x: clip;
  scroll-padding-top: 104px;
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}

body {
  font-family: var(--font-sans);
  background: var(--paper);
  color: var(--ink);
  line-height: 1.6;
  overflow-x: clip;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

.container {
  max-width: 1040px;
  margin: 0 auto;
  padding: 0 var(--space-8);
}

/* ── Top bar (continuity with the builds page) ────────────────────────── */
.top-bar {
  position: fixed;
  top: 0; left: 0; right: 0;
  height: 3px;
  background: linear-gradient(90deg, #2563EB, #0D9488, #10B981);
  z-index: 999;
}

/* ── Sidebar rules on wide screens ────────────────────────────────────── */
@media (min-width: 1300px) {
  body::before, body::after {
    content: '';
    position: fixed;
    top: 0; bottom: 0;
    width: 2px;
    background: linear-gradient(to bottom, transparent, var(--rule) 20%, var(--rule) 80%, transparent);
    pointer-events: none;
    z-index: 101;
  }
  body::before { left: calc(50% - 520px); }
  body::after  { left: calc(50% + 518px); }
}

/* ── Header ───────────────────────────────────────────────────────────── */
.header {
  /* The builds page header is matched to THIS one, in script.js
     (LOGO_FULL, PAD_TOP_FULL, PAD_BOT_FULL, MARGIN_FULL, TOGGLE_MT_FULL).
     Change both together or the engagements/builds toggle jumps. */
  padding: 40px 0 32px;
  background: var(--paper);
  position: sticky;
  top: 0;
  z-index: 100;
  transition: padding 350ms ease;
}

.header::after {
  content: '';
  position: absolute;
  bottom: 0; left: 0; right: 0;
  height: 1px;
  background: var(--rule);
}

/* Toggle: engagements | builds */
.toggle {
  display: flex;
  justify-content: center;
  align-items: center;
  gap: var(--space-4);
  margin-top: var(--space-5);
  transition: margin-top 350ms ease;
}

.toggle-item {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--ink-mute);
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-sm);
  transition: color var(--ease-default), background var(--ease-default);
}

.toggle-item:hover { color: var(--ink); background: rgba(15, 28, 46, 0.04); }

.toggle-item--active {
  color: var(--ink);
  position: relative;
}

.toggle-item--active::after {
  content: '';
  position: absolute;
  left: var(--space-3); right: var(--space-3);
  bottom: 2px;
  height: 2px;
  border-radius: 2px;
  background: var(--gradient-primary);
}

.toggle-div {
  width: 1px;
  height: 12px;
  background: var(--rule);
}

.logo-container {
  margin-bottom: 24px;
  text-align: center;
  position: relative;
  transition: margin-bottom 350ms ease;
}

.logo-container::before {
  content: '';
  position: absolute;
  top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  width: 700px; height: 200px;
  background: radial-gradient(ellipse, rgba(37,99,235,0.07) 0%, rgba(13,148,136,0.03) 35%, transparent 70%);
  pointer-events: none;
  z-index: 0;
}

.logo {
  max-width: 280px;
  width: 100%;
  height: auto;
  display: inline-block;
  position: relative;
  z-index: 1;
  transition: max-width 350ms ease;
}

.tagline {
  font-size: clamp(14px, 2vw, 20px);
  font-weight: 400;
  color: var(--ink);
  letter-spacing: -0.01em;
  line-height: 1.4;
  text-align: center;
  max-width: 1100px;
  margin: 0 auto;
  overflow: hidden;
  max-height: 4em;
  transition: opacity 350ms ease, max-height 350ms ease;
}

.tagline-mark {
  height: 1.15em;
  width: auto;
  vertical-align: middle;
  margin-right: 0.4em;
  position: relative;
  top: -0.05em;
}

.tagline-top     { color: var(--ink); font-weight: 600; font-size: 0.9em; }

/* "value" illuminates: blank to ember, not dark to ember.
   Base state is visible, so the word never disappears if the script fails.
   The pre-paint js-reveal class dims it, then JS adds .lit to bring it up. */
.illum { color: var(--ember); }

/* Dimmed rather than blank: the tagline is never an unfinished sentence. */
.js-reveal .illum { opacity: 0.28; }

.illum.lit,
.js-reveal .illum.lit {
  opacity: 1;
  text-shadow: 0 0 18px rgba(203, 90, 30, 0.34);
  transition: opacity 1100ms ease, text-shadow 1100ms ease;
}
.tagline-domains { color: var(--ink-mute); font-size: 0.9em; }
.tagline-sep     { color: var(--ember); }

/* Set by engagements.js at every width: fixed over a spacer of the full
   header's measured height, so the collapse cannot shift the page. */
.header.header--pinned { position: fixed; left: 0; right: 0; }

/* Collapsed state on scroll. The tagline closes by max-height (4em is above
   its two lines), which animates; height from auto to 0 cannot, and snapped. */
.header.collapsed { padding: 12px 0; }
.header.collapsed .toggle { margin-top: var(--space-3); }
.header.collapsed .logo-container { margin-bottom: 0; }
.header.collapsed .logo { max-width: 160px; }
.header.collapsed .tagline { opacity: 0; max-height: 0; }

/* ── Shared section furniture ─────────────────────────────────────────── */
.section { padding: 84px 0; }
.section + .section,
.hero + .section { border-top: 1px solid var(--rule); }

.section-head {
  position: relative;
  padding-top: var(--space-6);
  font-size: clamp(24px, 2.6vw, 30px);
  font-weight: 600;
  letter-spacing: -0.03em;
  line-height: 1.2;
  color: var(--ink);
  margin-bottom: var(--space-6);
}

.section-head::before {
  content: '';
  position: absolute;
  top: 0; left: 0;
  width: 80px; height: 3px;   /* was 56px grey; spectrum and longer on Jake's instruction, 2026-09-28 */
  border-radius: 2px;
  background: var(--gradient-primary);
}

/* ── Hero ─────────────────────────────────────────────────────────────── */
/* Base hero, used by about.html. */
.hero { padding: var(--space-20) 0 var(--space-16); }

.hero-statement {
  font-size: clamp(20px, 2.2vw, 28px);
  font-weight: 500;
  line-height: 1.35;
  letter-spacing: -0.02em;
  color: var(--ink);
  max-width: var(--measure-tight);
}

.hero-sub {
  margin-top: var(--space-8);
  font-size: clamp(15px, 1.3vw, 17px);
  line-height: 1.65;
  color: var(--ink-soft);
  max-width: var(--measure);
}

/* About page: headshot beside the name and intro line. */
.about-intro { display: flex; align-items: center; gap: var(--space-10); }
.about-photo {
  width: 136px;
  height: 136px;
  flex-shrink: 0;
  border-radius: 50%;
  object-fit: cover;
}

/* Engagements opening screen. Modelled on Sylvera and Pollination: the
   statement is set large in a light weight, the supporting lines sit in their
   own column offset right, and a soft sunrise amber sun rises from the bottom
   edge in the space under the statement. No bold, no highlighted phrase.
   The answer outranks the problems: problems small and grey, the cascadiaen
   sentence larger in full ink, held to two lines. */
.hero--home {
  position: relative;
  overflow: hidden;
  padding: 88px 0 104px;
}

.hero--home .container {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  column-gap: var(--space-8);
}

.hero--home .hero-statement {
  grid-column: 1 / -1;
  max-width: 24ch;
  text-wrap: balance;
  font-size: clamp(34px, 5vw, 56px);
  font-weight: 300;
  line-height: 1.1;
  letter-spacing: -0.035em;
}

.hero--home .hero-sub {
  grid-column: 5 / -1;
  grid-row: 2;
  padding-left: 56px;      /* room for the sun; any further breaks the answer to 3 lines at 1024px */
  margin-top: var(--space-12);
  font-size: 17px;
  line-height: 1.7;
  color: var(--ink-soft);
}

/* Problems as a small grey lead-in; the answer larger, light, in full ink. */
.hero--home .hero-line { display: block; text-wrap: pretty; }
.hero--home .hero-line:not(.hero-line--answer) {
  text-wrap: balance;
  font-size: 17px;
  line-height: 1.7;
  color: var(--ink-soft);
}
/* The pivot line: the reader's need, running through the brand gradient.
   Jake's instruction, 2026-09-16. Falls back to ink where background-clip
   is unsupported or forced colours are on. */
.hero--home .hero-line.hero-line--need {
  margin-top: var(--space-10);
  font-size: 19px;
  font-weight: 600;
  line-height: 1.5;
  letter-spacing: -0.01em;
  color: var(--ink);
  text-wrap: balance;
}

@supports (-webkit-background-clip: text) or (background-clip: text) {
  .hero--home .hero-line.hero-line--need {
    background: linear-gradient(95deg, #2563EB 0%, #0D9488 55%, #10B981 100%);
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
  }
}

@media (forced-colors: active) {
  .hero--home .hero-line.hero-line--need { color: CanvasText; background: none; }
}

.hero--home .hero-line--answer {
  margin-top: var(--space-4);
  font-size: 19px;
  font-weight: 300;
  line-height: 1.5;
  letter-spacing: -0.01em;
  color: var(--ink-soft);
  text-wrap: balance;
}

/* Decorative. Jake's choice, 2026-09-14. */
.hero-sun {
  grid-column: 1 / span 5;
  grid-row: 2;
  align-self: end;
  width: 320px;
  height: 160px;
  margin-bottom: -104px;   /* sits on the hero's bottom edge */
  border-radius: 320px 320px 0 0;
  background: radial-gradient(circle at 50% 100%,
    rgba(203, 90, 30, 0.45) 0%,
    rgba(225, 126, 43, 0.24) 38%,
    rgba(225, 126, 43, 0.08) 60%,
    rgba(225, 126, 43, 0) 72%);
  pointer-events: none;
}

.section-intro {
  margin-top: 0;
  margin-bottom: 56px;
  font-size: clamp(15px, 1.3vw, 17px);
  line-height: 1.65;
  color: var(--ink-soft);
  max-width: var(--measure);
}

/* The one deliberate break in the 84px section rhythm: the rising sun eats
   into the space under the hero, so the offer section takes extra room above
   to sit level with the other headings. */
#offer { padding-top: 104px; }

@media (max-width: 900px) {
  #offer { padding-top: 66px; }
}

/* ── Audiences ────────────────────────────────────────────────────────── */
/* Three distinct audiences, each its own customer and product. */
.audience-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--space-8);
  margin-top: 56px;
}

/* No cards, no fills. A thin rule and type, closer to the builds page, which
   uses borders and text rather than boxes. A small hover light-up is below. */
.audience {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  padding-top: var(--space-5);
  border-top: 3px solid var(--strand);
}

.audience--public   { --strand: var(--public); }
.audience--business { --strand: var(--business); }
.audience--finance  { --strand: var(--finance); }

.audience-name {
  font-size: clamp(18px, 1.6vw, 20px);
  font-weight: 600;
  letter-spacing: -0.03em;
  line-height: 1.1;
  color: var(--ink);
  white-space: nowrap;
}

.audience-body {
  font-size: 15px;
  line-height: 1.65;
  color: var(--ink-soft);
}

/* ── Featured service ─────────────────────────────────────────────────── */
/* The gradient tab sits on the kicker, which leads into the service name. */
.service-kicker {
  position: relative;
  padding-top: var(--space-6);
  margin-bottom: var(--space-3);
  font-size: 17px;
  line-height: 1.5;
  color: var(--ink-soft);
}

.service-kicker::before {
  content: '';
  position: absolute;
  top: 0; left: 0;
  width: 80px; height: 3px;   /* matches .section-head::before */
  border-radius: 2px;
  background: var(--gradient-primary);
}

.service-kicker + .service-name { padding-top: 0; }
.service-kicker + .service-name::before { display: none; }

.service-name {
  position: relative;
  padding-top: var(--space-6);
  font-size: clamp(24px, 2.9vw, 34px);
  font-weight: 600;
  letter-spacing: -0.03em;
  line-height: 1.15;
  color: var(--ink);
}

.service-name::before {
  content: '';
  position: absolute;
  top: 0; left: 0;
  width: 80px; height: 3px;   /* matches .section-head::before */
  border-radius: 2px;
  background: var(--gradient-primary);
}

/* Closing callback to the illuminated word in the tagline: dim until the
   paragraph scrolls in, then it comes up once, the same as "value" above. */
.service-line .illum-word {
  color: var(--ember);
  font-weight: 600;
}

.js-reveal .service-line .illum-word { opacity: 0.28; }

.js-reveal .service-line .illum-word.lit {
  opacity: 1;
  text-shadow: 0 0 18px rgba(203, 90, 30, 0.34);
  transition: opacity 3000ms linear, text-shadow 3000ms linear;   /* linear, so it looks finished when it is */
}

@media (prefers-reduced-motion: reduce) {
  .js-reveal .service-line .illum-word { opacity: 1; }
}

.service-line {
  margin-top: var(--space-6);
  font-size: clamp(15px, 1.3vw, 17px);
  line-height: 1.65;
  color: var(--ink-soft);
  max-width: var(--measure);
}

/* ── Audience states ──────────────────────────────────────────────────────
   Not greyed out. The live one keeps the dark rule; the ones still to come
   get a lighter rule and a flag, so they read as sequenced rather than
   broken or disabled.
─────────────────────────────────────────────────────────────────────────── */
.audience-flag {
  color: var(--strand);
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
}

/* Colour marks the live strand only. The two in build keep a thin grey rule
   and grey flag text, so status reads by rank rather than by fading them. */
.audience--soon { border-top-color: var(--rule-strong); border-top-width: 1px; padding-top: calc(var(--space-5) + 2px); }
.audience--soon .audience-name { color: var(--ink-soft); }
.audience--soon .audience-flag { color: var(--ink-mute); }

/* Status light on the live strand only: the sunrise amber dot of the lists,
   so amber reads as "lit up, live" (Jake, 2026-09-28). */
.audience--public .audience-flag { display: flex; align-items: center; gap: 8px; }
.audience--public .audience-flag::before {
  content: '';
  flex: none;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--ember);
}

/* A small light-up on hover (Jake, 2026-09-28): the block lifts 2px, the
   live strand's rule brightens to the lit teal and its name takes the
   strand colour; the two in build stay grey, their rule and name just
   darken a step. No fill, no card. The lift uses `translate`, not
   `transform`, because the scroll reveal owns `transform` on these blocks;
   the transition list keeps the reveal's own 0.5s opacity and transform. */
.audience-grid .audience {
  transition: opacity 0.5s ease, transform 0.5s ease, translate 240ms ease, border-color 240ms ease;
}
.audience-name { transition: color 240ms ease; }

/* Desktop: public value arrives with the scroll; business, then finance,
   follow a second apart, left to right, so the row reads in the order they
   come: live now, then in build (Jake, 2026-09-28). Delays apply to the
   reveal only, never the hover. Phones stack the blocks, each revealing as
   it is reached, so no delay there. */
@media (min-width: 901px) {
  .audience-grid .audience:nth-child(2),
  .audience-grid .audience:nth-child(3) {
    transition-duration: 1s, 1s, 240ms, 240ms;
  }
  .audience-grid .audience:nth-child(2) { transition-delay: 1s, 1s, 0s, 0s; }
  .audience-grid .audience:nth-child(3) { transition-delay: 2s, 2s, 0s, 0s; }
}

@media (hover: hover) {
  .audience:hover { translate: 0 -2px; }
  .audience--public:hover { border-top-color: var(--teal); }
  .audience--public:hover .audience-name { color: var(--public); }
  .audience--soon:hover { border-top-color: var(--ink-mute); }
  .audience--soon:hover .audience-name { color: var(--ink); }
}

/* ── The claim ────────────────────────────────────────────────────────── */
.offer-claim {
  margin-top: 28px;
  font-size: clamp(17px, 1.6vw, 20px);
  font-weight: 500;
  line-height: 1.45;
  letter-spacing: -0.015em;
  color: var(--ink);
  max-width: var(--measure-tight);
}

/* ── Many problems, one assessment ────────────────────────────────────── */
.converge { margin-top: var(--space-12); }

/* Stacked rows, not a third set of columns (Jake, 2026-09-28): the title in
   the button blue on the left, its line on the right. The three lines roll
   out left to right together, once, when "Illuminating." lights (same
   trigger, same 3s), a sideways movement used nowhere else on the page.
   Without the script, or with reduced motion, the lines are simply there. */
.converge-problems {
  max-width: var(--measure-wide);
  border-top: 1px solid var(--rule);
}

.problem-item {
  display: grid;
  grid-template-columns: 220px minmax(0, 1fr);
  gap: var(--space-8);
  align-items: baseline;
  padding: var(--space-6) 0;
  border-bottom: 1px solid var(--rule);
}

.problem-title {
  position: relative;
  padding-left: 18px;
  font-size: 17px;
  font-weight: 600;
  letter-spacing: -0.02em;
  line-height: 1.3;
  color: var(--ink);   /* blue title text tried and dropped: blue is a highlight, not a text colour */
}

/* The sunrise amber dot of the document list: these are the three things
   "Illuminating." lights up (Jake, 2026-09-28). */
.problem-title::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0.5em;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--ember);
}

.problem-body { position: relative; font-size: 15px; line-height: 1.6; color: var(--ink-soft); }

/* The reveal: a blue band sweeps left to right and the text appears behind
   it, like a wave rolling in; the band fades once it reaches the end. Band
   and wipe share one duration and curve, and the band's right edge is the
   wipe's edge (it lives inside the clipped paragraph, so it shows only where
   text is already revealed). */
.js-reveal .converge-problems .problem-body { clip-path: inset(0 100% 0 0); }
.js-reveal .converge-problems.is-rolled .problem-body {
  clip-path: inset(0 0 0 0);
  transition: clip-path 3s cubic-bezier(0.25, 0.6, 0.3, 1);
}

.js-reveal .converge-problems .problem-body::after {
  content: '';
  position: absolute;
  top: 0; bottom: 0;
  left: -56px;
  width: 56px;
  background: linear-gradient(90deg, rgba(91, 139, 236, 0) 0%, rgba(91, 139, 236, 0.28) 70%, #5B8BEC 100%);
  border-radius: 0 3px 3px 0;
  pointer-events: none;
}
.js-reveal .converge-problems.is-rolled .problem-body::after {
  left: calc(100% - 56px);
  opacity: 0;
  transition: left 3s cubic-bezier(0.25, 0.6, 0.3, 1), opacity 0.6s ease 3s;
}

/* Staggered a touch, top to bottom, so the wave rolls down the rows rather
   than all three launching at once (Jake, 2026-09-28). */
.js-reveal .converge-problems.is-rolled .problem-item:nth-child(2) .problem-body { transition-delay: 0.3s; }
.js-reveal .converge-problems.is-rolled .problem-item:nth-child(2) .problem-body::after { transition-delay: 0.3s, 3.3s; }
.js-reveal .converge-problems.is-rolled .problem-item:nth-child(3) .problem-body { transition-delay: 0.6s; }
.js-reveal .converge-problems.is-rolled .problem-item:nth-child(3) .problem-body::after { transition-delay: 0.6s, 3.6s; }


/* Governance sits under "who you're working with", below the person. */
.person + .governance { margin-top: 44px; }


/* ── Use for ──────────────────────────────────────────────────────────── */
.use-for {
  margin: 0 0 56px;   /* matches the intro-to-content gap used by the grids */
  font-size: 17px;
  font-weight: 600;
  letter-spacing: -0.02em;
  color: var(--ink);
}

/* Four cases: two by two on desktop, so none is orphaned on its own row. */
.case-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-8);
  margin-top: 56px;
}


/* ── Use case cards ───────────────────────────────────────────────────────
   Both faces share one grid cell, so the card takes the height of its taller
   face and there is no dead space. Colour is a top edge and an accent, not a
   filled slab.
─────────────────────────────────────────────────────────────────────────── */
.case {
  perspective: 1600px;
  outline: none;
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
}

.case-inner {
  display: grid;
  flex: 1;
  transform-style: preserve-3d;
  transition: transform 640ms cubic-bezier(0.16, 1, 0.3, 1);
}

.case:focus-visible .case-inner,
.case.is-flipped .case-inner { transform: rotateY(180deg); }

/* Hover flip only where hover is real. On touch, :hover sticks after a tap,
   so the card could never be tapped back to its front. */
@media (hover: hover) {
  .case:hover .case-inner { transform: rotateY(180deg); }
}

.case:focus-visible { border-radius: var(--radius-lg); box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.35); }

.case-face {
  grid-area: 1 / 1 / 2 / 2;
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  padding: var(--space-6);
  backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
  background: var(--paper-raised);
  border: 1px solid var(--rule);
  border-top: 3px solid var(--strand);
  border-radius: var(--radius-md);
}

.case-back {
  transform: rotateY(180deg);
  background: var(--paper-raised);
  background: color-mix(in srgb, var(--strand) 6%, var(--paper-raised));
}

/* The card you are on changes its top edge to the sunrise amber as it flips;
   the others keep the teal. */
.case.is-flipped .case-back,
.case:focus-visible .case-back { border-top-color: var(--ember); }

@media (hover: hover) {
  .case:hover .case-back { border-top-color: var(--ember); }
}

/* Touch has no hover, so the front face says how to reveal the result. It sits
   at the foot of the face, in the space the taller back face creates. */
.case-hint { display: none; }

@media (hover: none) {
  .case-hint {
    display: block;
    margin-top: auto;
    padding-top: var(--space-4);
    font-size: 13px;
    color: var(--ink-mute);
  }
}

@media (prefers-reduced-motion: reduce) {
  .case-hint { display: none !important; }
}

.case--public   { --strand: var(--public); }
.case--business { --strand: var(--business); }
.case--finance  { --strand: var(--finance); }

.case-name {
  font-size: 17px;
  font-weight: 600;
  letter-spacing: -0.02em;
  line-height: 1.35;
  color: var(--ink);
}

.case-who { font-size: 14px; line-height: 1.65; color: var(--ink-soft); }

/* The decision the card lands on, on the front, to draw the reader into the
   flip (Jake, 2026-09-28). Wording lifted from each card's own "So..." line.
   Same size and weight as the finding on the back, in the strand colour. */
.case-decision {
  font-size: 16px;
  font-weight: 600;
  line-height: 1.5;
  letter-spacing: -0.015em;
  color: var(--strand);
}


.case-finding {
  font-size: 16px;
  font-weight: 600;
  line-height: 1.5;
  letter-spacing: -0.015em;
  color: var(--ink);
}

/* The headline number in each finding, in sunrise amber to match the card's
   amber top edge once flipped (Jake, 2026-09-28). 4.2:1 on white. */
.case-figure { color: var(--ember); }

.case-so {
  font-size: 14px;
  line-height: 1.65;
  color: var(--ink-soft);
  margin-top: auto;
  padding-top: var(--space-4);
  border-top: 1px solid var(--rule);
}


/* Links to the proof (results, briefing notes, samples, the disclosure) are
   filled buttons, so they read as things to open rather than words in a
   paragraph. External review, 2026-09-27, approved by Jake. #5B8BEC is the
   hero's "You" blue hue at the tone of the page's green (#10B981) and
   sunrise amber (#CB5A1E): OKLCH lightness and chroma are the mean of those
   two, hue kept. Hover deepens to brand navy and lifts. */
.case-brief,
.doc-sample,
.gov-more,
.person-more {
  display: inline-block;
  align-self: flex-start;
  padding: 5px 11px;   /* plus the 1px border: 6px by 12px, snug around the words (Jake, 2026-09-28) */
  font-size: 14px;
  font-weight: 500;
  line-height: 1.3;
  color: var(--ink);
  /* Border only at rest (Jake, 2026-09-28); fills #5B8BEC on hover or flip.
     Previous rest state: solid #C1D3F6 (#5B8BEC at 35% on the paper). */
  background: transparent;
  border: 1px solid #5B8BEC;
  text-decoration: none;
  border-radius: var(--radius-md);
  transition: background var(--ease-default), color var(--ease-default), transform var(--ease-default);
}

.doc-sample:hover,
.gov-more:hover,
.person-more:hover { background: #5B8BEC; color: #FFFFFF; transform: translateY(-1px); }

/* Touch: a tap on the row or block lights its button (engagements.js,
   initTapLight), the tap version of the hover rules below. */
.doc-item.is-lit .doc-sample,
.person-text.is-lit .person-more,
.governance.is-lit .gov-more { background: #5B8BEC; color: #FFFFFF; }

/* On a case card the button fills with the flip, not on its own hover: same
   triggers, same 640ms and curve as .case-inner, so card and button move as
   one. No lift, which would be a second motion. */
.case-brief {
  transition: background 640ms cubic-bezier(0.16, 1, 0.3, 1), color 640ms cubic-bezier(0.16, 1, 0.3, 1);
}

.case.is-flipped .case-brief,
.case:focus-visible .case-brief { background: #5B8BEC; color: #FFFFFF; }

@media (hover: hover) {
  .case:hover .case-brief { background: #5B8BEC; color: #FFFFFF; }
  /* Transparent and auditable: the button lights when you are anywhere on
     its document's row, not only on the button (Jake, 2026-09-28). */
  .doc-item:hover .doc-sample { background: #5B8BEC; color: #FFFFFF; }
  /* Same for the About person block and the governance block. */
  .person-text:hover .person-more,   /* the text column, not the full-width row */
  .governance:hover .gov-more { background: #5B8BEC; color: #FFFFFF; }
}

/* ── Documents ────────────────────────────────────────────────────────────
   Set as an index rather than cards. The section is about rigour, so it
   should read like a contents page, not a brochure.
─────────────────────────────────────────────────────────────────────────── */
.doc-list {
  list-style: none;
  margin-top: 56px;
  border-top: 1px solid var(--rule);
  max-width: var(--measure-wide);
}

.doc-item {
  display: grid;
  grid-template-columns: 200px minmax(0, 1fr);
  gap: var(--space-8);
  align-items: baseline;
  padding: var(--space-6) 0;
  border-bottom: 1px solid var(--rule);
}

.doc-name {
  position: relative;
  padding-left: 18px;
  font-size: 16px;
  font-weight: 600;
  letter-spacing: -0.02em;
  color: var(--ink);
}

/* Sunrise amber dot, same as the audience list bullets, carries the page's one
   accent into the second half. */
.doc-name::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0.55em;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--ember);
}

.doc-line { font-size: 14px; line-height: 1.65; color: var(--ink-soft); }

/* Small link to the Caribbean sample of each document, one complete case set. */
.doc-sample { margin-top: var(--space-3); }

/* ── Bio page ─────────────────────────────────────────────────────────── */
.bio-body {
  margin-top: var(--space-6);
  font-size: clamp(15px, 1.3vw, 17px);
  line-height: 1.75;
  color: var(--ink-soft);
  max-width: var(--measure-wide);
}

.bio-body + .bio-body { margin-top: var(--space-5); }

.cite-list { list-style: none; margin-top: var(--space-10); }

.cite-list li {
  padding: var(--space-4) 0;
  border-bottom: 1px solid var(--rule);
  font-size: 14px;
  line-height: 1.6;
  color: var(--ink-soft);
  max-width: var(--measure-wide);
}

.cite-list li:first-child { border-top: 1px solid var(--rule); }

.cite-list em { font-style: normal; color: var(--ink); font-weight: 600; }

.cred-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-6) var(--space-10);
  margin-top: var(--space-10);
  max-width: var(--measure-wide);
}

.cred-item { display: flex; flex-direction: column; gap: var(--space-1); }

.cred-what { font-size: 15px; font-weight: 600; color: var(--ink); line-height: 1.35; }
.cred-where { font-size: 14px; color: var(--ink-mute); }

/* Shorter courses: same type scale as the degrees, but no bold and set as a
   ruled list, so they read as supporting rather than equal. */
.course-list {
  list-style: none;
  margin-top: var(--space-10);
  border-top: 1px solid var(--rule);
  max-width: var(--measure-wide);
}

.course-list li {
  display: flex;
  justify-content: space-between;
  gap: var(--space-2) var(--space-6);
  padding: var(--space-3) 0;
  border-bottom: 1px solid var(--rule);
  font-size: 14px;
  line-height: 1.5;
}

.course-what  { color: var(--ink-soft); }
.course-where { color: var(--ink-mute); text-align: right; }

/* ── Governance band ──────────────────────────────────────────────────────
   Not an engagement deliverable. A standing credibility layer over
   everything cascadiaen produces, so it sits apart from the outputs.
─────────────────────────────────────────────────────────────────────────── */
.governance {
  display: flex;
  align-items: flex-start;
  gap: var(--space-8);
  padding: var(--space-8);
  border: 1px solid var(--rule);
  border-left: 3px solid var(--teal);
  border-radius: 0 var(--radius-lg) var(--radius-lg) 0;
  background: var(--paper-raised);
}

.gov-text { display: flex; flex-direction: column; gap: var(--space-3); }

.gov-title {
  font-size: 20px;
  font-weight: 600;
  letter-spacing: -0.025em;
  color: var(--ink);
}

.gov-body { font-size: 14px; line-height: 1.65; color: var(--ink-soft); max-width: var(--measure); }

/* Link to the published disclosure, same treatment as "More about Jake". */


/* ── Who you're working with ──────────────────────────────────────────── */
.person {
  display: flex;
  align-items: center;
  gap: var(--space-8);
  margin-top: 56px;
}

/* No placeholder avatar. Add an <img class="person-photo"> once a real
   photograph exists; a stand-in circle reads worse than none. */

.person-text { display: flex; flex-direction: column; gap: var(--space-2); }
.person-name { font-size: 20px; font-weight: 600; letter-spacing: -0.025em; color: var(--ink); }
.person-line { font-size: 15px; line-height: 1.65; color: var(--ink-soft); max-width: var(--measure); }

/* Button styling is shared with the proof links, under Use cases. */
.person-more { margin-top: var(--space-2); }

/* ── Call to arms ─────────────────────────────────────────────────────── */
.arms { text-align: center; }

.arms-line {
  font-size: clamp(19px, 1.8vw, 23px);
  font-weight: 500;
  line-height: 1.4;
  letter-spacing: -0.02em;
  color: var(--ink);
  max-width: var(--measure-tight);
  margin: 0 auto;
}

.arms-cta {
  display: inline-block;
  margin-top: var(--space-10);
  font-size: 15px;
  font-weight: 500;
  color: #FFFFFF;
  background: var(--link);
  text-decoration: none;
  padding: var(--space-4) var(--space-8);
  border-radius: var(--radius-md);
  transition: background var(--ease-default), transform var(--ease-default);
}

.arms-cta:hover { background: var(--ember); transform: translateY(-1px); }

/* ── Footer ───────────────────────────────────────────────────────────── */
.footer {
  padding: 72px 0 var(--space-12);
  background: var(--paper);
  position: relative;
}

.footer::before {
  content: '';
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 1px;
  background: var(--rule);
}

.footer-links {
  display: flex;
  justify-content: center;
  gap: var(--space-6);
  margin-top: var(--space-6);
  flex-wrap: wrap;
}

.footer-link {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-mute);
  text-decoration: none;
  border-bottom: 1px solid currentColor;
  transition: color var(--ease-default), border-color var(--ease-default);
}

.footer-link:hover { color: var(--ink); border-bottom-color: var(--ink); }

.contact-text { font-size: 15px; line-height: 1.7; color: var(--ink); text-align: center; }

.contact-link {
  color: var(--link);
  text-decoration: none;
  font-weight: 500;
  border-bottom: 1px solid currentColor;
  transition: color var(--ease-default), border-color var(--ease-default);
}

.contact-link:hover { color: var(--ink); border-bottom-color: var(--ink); }

.copyright {
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--ink-mute);
  text-align: center;
  margin-top: var(--space-6);
  letter-spacing: 0.08em;
}

.footer-mark {
  display: block;
  margin: var(--space-10) auto 0;
  width: 28px;
  height: auto;
  opacity: 0.40;
}


/* ── Scroll reveal ────────────────────────────────────────────────────── */
/* Only hidden once the script confirms it can reveal them again. Without
   this guard a JS failure would leave the whole page blank. */
.js-reveal .reveal {
  opacity: 0;
  transform: translateY(14px);
}

.reveal { transition: opacity 0.5s ease, transform 0.5s ease; }

.reveal.is-visible { opacity: 1; transform: none; }

/* ── Responsive ───────────────────────────────────────────────────────── */
@media (max-width: 900px) {
  .doc-item { grid-template-columns: 1fr; gap: var(--space-2); }
  .problem-item { grid-template-columns: 1fr; gap: var(--space-2); }
  .audience-grid, .converge-problems, .case-grid, .cred-grid {
    grid-template-columns: 1fr; gap: var(--space-6);
  }
  .governance { flex-direction: column; gap: var(--space-4); }
  .person { flex-direction: column; align-items: flex-start; gap: var(--space-5); }
  .about-intro { flex-direction: column; align-items: flex-start; gap: var(--space-6); }
  .about-photo { width: 112px; height: 112px; }
  .hero-statement { max-width: none; }
  .section { padding: 56px 0; }
  .hero { padding: var(--space-12) 0; }
  /* Phones: lines take the full width; the sun sits centred below them. */
  .hero--home { padding: var(--space-16) 0 112px; }
  /* one column on phones: twelve columns' worth of gaps is wider than a phone
     screen, which pushed the statement off the right edge */
  .hero--home .container { grid-template-columns: minmax(0, 1fr); }
  .hero--home .hero-sub { grid-column: 1 / -1; padding-left: 0; margin-top: var(--space-8); font-size: 16px; position: relative; z-index: 1; }
  .hero-sun {
    position: absolute;
    left: 50%;
    bottom: 0;
    width: 240px;
    height: 104px;
    margin: 0;
    transform: translateX(-50%);
    border-radius: 240px 240px 0 0;
  }
  .header { padding: var(--space-10) 0 var(--space-8); }
  .toggle { margin-bottom: var(--space-6); }
  .header.collapsed .toggle { margin-bottom: 0; }
  .governance { padding: var(--space-5); }
  .gov-title { line-height: 1.3; }
  .logo { max-width: 260px; }
  .header.collapsed .logo { max-width: 140px; }
  .container { padding: 0 var(--space-5); }

  .course-list li { flex-direction: column; gap: 0; }
  .course-where { text-align: left; }
}

/* Phones: header parity with the builds page, whose tagline breaks its
   domains line in two here (three lines). This one holds a blank third line
   (3 x 1.4em) and drops the space under the toggle, so logo, tagline, toggle
   and rule sit in the same place on both pages. Collapsed max-height 0 wins. */
@media (max-width: 640px) {
  .tagline { height: 4.2em; max-height: 4.2em; }
  .toggle { margin-bottom: 0; }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    transition-duration: 0.01ms !important;
    animation-duration: 0.01ms !important;
  }
  .reveal { opacity: 1; transform: none; }
  .case-inner { transform: none !important; }
  .case-face { grid-area: auto; transform: none !important; min-height: 0; }
  .js-reveal .illum { opacity: 1; }
}

/* ── Forced colours ───────────────────────────────────────────────────── */
@media (forced-colors: active) {
  .case-inner { transform: none !important; }
  .case-face { grid-area: auto; transform: none !important; }
  .section-head::before, .service-name::before { forced-color-adjust: none; }
}

/* ── Print ────────────────────────────────────────────────────────────────
   Credibility pages get printed and circulated internally, so both faces of
   every case card must appear.
─────────────────────────────────────────────────────────────────────────── */
@media print {
  .top-bar, .toggle, .header-spacer, body::before, body::after { display: none; }
  .header, .header.collapsed, .header.header--pinned { position: static; padding: 0 0 16pt; }
  .header.collapsed .tagline { opacity: 1; max-height: none; }
  .header.collapsed .logo { max-width: 280px; }
  .section { padding: 16pt 0; break-inside: avoid; }
  .reveal, .js-reveal .reveal { opacity: 1 !important; transform: none !important; }
  .js-reveal .converge-problems .problem-body { clip-path: none !important; }
  .converge-problems .problem-body::after { display: none; }
  .case-inner { transform: none !important; display: block; }
  .case-face { position: static; transform: none !important; page-break-inside: avoid; }
  .case-hint { display: none !important; }
  .case-brief[href]::after { content: ' (' attr(href) ')'; font-size: 9pt; word-break: break-all; }
  a { text-decoration: underline; }
}
