:root {
  --ink: #142221;
  --ink-soft: #31423f;
  --paper: #f4f1e9;
  --paper-bright: #fffdf7;
  --teal: #0b6660;
  --teal-dark: #073f3c;
  --lime: #cce66a;
  --line: rgba(20, 34, 33, 0.18);
  --max: 1180px;
  --radius: 22px;
}

* { box-sizing: border-box; }
html { scroll-behavior: smooth; }
body { margin: 0; background: var(--paper); color: var(--ink); font-family: Inter, ui-sans-serif, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; line-height: 1.6; }
a { color: inherit; }
.skip-link { position: fixed; top: 10px; left: 10px; z-index: 100; padding: .7rem 1rem; background: var(--ink); color: white; transform: translateY(-160%); }
.skip-link:focus { transform: translateY(0); }
/* Focus ring: lime measured 1.23:1 against the paper ground, which is invisible.
   Dark ring on light sections (14.5:1), lime only where the ground is dark (11.8:1). */
a:focus-visible, button:focus-visible, [tabindex]:focus-visible { outline: 3px solid var(--ink); outline-offset: 3px; border-radius: 3px; }
.section-dark a:focus-visible, .cta-band a:focus-visible, .signal-card a:focus-visible,
.credential-card a:focus-visible, .quality-bar a:focus-visible, .contact-card a:focus-visible { outline-color: var(--lime); }

.site-header { width: min(var(--max), calc(100% - 40px)); margin: 0 auto; min-height: 96px; display: flex; align-items: center; justify-content: space-between; gap: 24px; border-bottom: 1px solid var(--line); }
.brand { display: inline-flex; align-items: center; gap: 12px; max-width: 340px; font-size: .91rem; font-weight: 750; line-height: 1.2; text-decoration: none; letter-spacing: -.01em; }
.brand-mark { display: grid; place-items: center; width: 2.875rem; height: 2.875rem; flex: 0 0 2.875rem; border-radius: 50%; background: var(--ink); color: var(--lime); font-size: 0.84rem; letter-spacing: .08em; }
nav { display: flex; align-items: center; gap: 26px; }
nav a { padding: .3rem 0; color: var(--ink-soft); font-size: .92rem; font-weight: 680; text-decoration: none; border-bottom: 2px solid transparent; }
nav a:hover, nav a[aria-current="page"] { color: var(--ink); border-color: var(--teal); }

.hero, .contact-hero { width: min(var(--max), calc(100% - 40px)); margin: 0 auto; display: grid; grid-template-columns: minmax(0, 1.25fr) minmax(320px, .75fr); gap: clamp(40px, 7vw, 96px); align-items: center; padding: clamp(72px, 10vw, 138px) 0; }
.hero-copy { max-width: 760px; }
.eyebrow, .card-label { margin: 0 0 18px; color: var(--teal); font-size: 0.84rem; font-weight: 800; letter-spacing: .16em; text-transform: uppercase; }
h1, h2, h3 { margin-top: 0; line-height: 1.08; letter-spacing: -.035em; }
h1 { max-width: 900px; margin-bottom: 30px; font-family: Georgia, "Times New Roman", serif; font-size: var(--fs-1); font-weight: 500; }
h2 { margin-bottom: 24px; font-family: Georgia, "Times New Roman", serif; font-size: var(--fs-2); font-weight: 500; }
h3 { margin-bottom: 16px; font-size: 1.22rem; }
p { margin-top: 0; }
.lede { max-width: 760px; margin-bottom: 34px; color: var(--ink-soft); font-size: var(--fs-3); line-height: 1.65; }
.button-row { display: flex; flex-wrap: wrap; gap: 12px; }
.button { display: inline-flex; min-height: 48px; align-items: center; justify-content: center; padding: .8rem 1.15rem; border: 1px solid var(--ink); border-radius: 999px; font-size: .92rem; font-weight: 760; text-decoration: none; }
.button-primary { background: var(--ink); color: white; }
.button-primary:hover { background: var(--teal-dark); }
.button-secondary:hover { background: var(--paper-bright); }
.button-light { border-color: white; background: white; color: var(--ink); }
.button-light:hover { background: var(--lime); border-color: var(--lime); }

.signal-card, .contact-card { padding: clamp(28px, 4vw, 48px); border-radius: var(--radius); background: var(--teal-dark); color: white; box-shadow: 18px 18px 0 var(--lime); }
.signal-card .card-label, .contact-card .card-label { color: var(--lime); }
.principle-list { margin: 0; padding: 0; list-style: none; }
.principle-list li { display: grid; grid-template-columns: 48px 1fr; gap: 10px; padding: 18px 0; border-top: 1px solid rgba(255,255,255,.2); font-weight: 680; }
.principle-list span { color: var(--lime); font-size: 0.84rem; letter-spacing: .1em; }

.section { padding: clamp(76px, 10vw, 132px) max(20px, calc((100% - var(--max)) / 2)); }
.section-dark { background: var(--ink); color: white; }
.section-dark .eyebrow, .section-dark .card-number { color: var(--lime); }
.section-heading { display: grid; grid-template-columns: minmax(180px, .42fr) minmax(0, 1fr); gap: 48px; align-items: start; margin-bottom: 56px; }
.section-heading h2 { max-width: 850px; }
.card-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 18px; }
.service-card, .plain-card { min-height: 280px; padding: 30px; border: 1px solid var(--line); border-radius: var(--radius); }
.service-card p:last-child, .plain-card p:last-child { color: var(--ink-soft); }
/* These two are dark-ground components by origin: their border and their closing
   paragraph were hardcoded white, so putting one on paper produced 1.13:1. The white
   values now belong to the dark ground rather than to the component, which is the same
   correction already applied to .estimate-note and .method-map. */
.section-dark .service-card, .section-dark .plain-card { border-color: rgba(255,255,255,.19); }
.section-dark .service-card p:last-child, .section-dark .plain-card p:last-child { color: rgba(255,255,255,.72); }
.card-number { margin-bottom: 76px; color: var(--teal); font-size: 0.84rem; font-weight: 800; letter-spacing: .16em; }
.plain-card { min-height: 210px; }

.split-section { display: grid; grid-template-columns: minmax(250px, .75fr) minmax(0, 1fr); gap: clamp(50px, 9vw, 130px); }
.prose-stack { max-width: 720px; color: var(--ink-soft); font-size: 1.12rem; }
.prose-stack p { margin-bottom: 22px; }
.text-link { display: inline-block; min-height: 26.7px; margin-top: 14px; color: var(--teal-dark); font-weight: 800; text-decoration-thickness: 2px; text-underline-offset: 5px; }
.cta-band { width: min(var(--max), calc(100% - 40px)); margin: 30px auto 80px; padding: clamp(36px, 6vw, 70px); display: flex; align-items: center; justify-content: space-between; gap: 30px; border-radius: var(--radius); background: var(--teal); color: white; }
.cta-band .eyebrow { color: var(--lime); }
.cta-band h2 { max-width: 720px; margin: 0; font-size: var(--fs-17); }

.page-hero { width: min(var(--max), calc(100% - 40px)); margin: 0 auto; padding: clamp(72px, 10vw, 128px) 0 clamp(58px, 8vw, 100px); }
.page-hero h1 { max-width: 22ch; font-size: var(--fs-5); line-height: 1.06; text-wrap: balance; }
.service-list { padding-top: 20px; }
.service-row { display: grid; grid-template-columns: 110px 1fr; gap: 28px; padding: 44px 0; border-top: 1px solid var(--line); }
.service-row:last-child { border-bottom: 1px solid var(--line); }
.service-row .card-number { margin: 6px 0 0; }
.service-row h2 { font-size: var(--fs-6); }
.service-row div > p { max-width: 74ch; }
.service-row p:last-child { max-width: 74ch; color: var(--ink-soft); font-size: 1.08rem; }
.contact-hero h1 { max-width: 22ch; font-size: var(--fs-7); line-height: 1.06; text-wrap: balance; }
.contact-email { display: inline-block; margin-bottom: 26px; color: var(--lime); font-size: var(--fs-8); font-weight: 800; text-underline-offset: 5px; }
.contact-card p:last-child { color: rgba(255,255,255,.75); }

.site-footer { width: min(var(--max), calc(100% - 40px)); margin: 0 auto; min-height: 100px; display: flex; justify-content: space-between; align-items: center; gap: 24px; border-top: 1px solid var(--line); color: var(--ink-soft); font-size: 0.84rem; }
.site-footer p { margin: 0; }

@media (max-width: 820px) {
  .site-header { align-items: flex-start; padding: 22px 0; }
  .brand { max-width: 220px; }
  nav { flex-wrap: wrap; justify-content: flex-end; gap: 10px 18px; }
  .hero, .contact-hero, .split-section { grid-template-columns: 1fr; }
  .signal-card, .contact-card { max-width: 620px; }
  .section-heading { grid-template-columns: 1fr; gap: 12px; }
  .card-grid { grid-template-columns: 1fr; }
  .service-card { min-height: 220px; }
  .card-number { margin-bottom: 42px; }
  .cta-band { align-items: flex-start; flex-direction: column; }
}

@media (max-width: 560px) {
  .site-header { display: block; }
  .brand { max-width: none; }
  nav { margin-top: 22px; justify-content: flex-start; }
  .hero, .contact-hero, .page-hero { width: min(100% - 28px, var(--max)); }
  .hero, .contact-hero { padding-top: 62px; }
  h1 { font-size: 4.4rem; }
  .service-row { grid-template-columns: 1fr; gap: 8px; }
  .site-footer { padding: 26px 0; align-items: flex-start; flex-direction: column; }
}

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

/* --- Expansion additions (systems flow, capability tags, system blocks) --- */

.flow-strip { margin: 0; padding: 0; list-style: none; display: grid; grid-template-columns: repeat(5, 1fr); gap: 18px; }
.flow-step { padding: 26px 24px; border: 1px solid var(--line); border-radius: var(--radius); background: var(--paper-bright); }
.flow-num { margin: 0 0 30px; color: var(--teal); font-size: 0.84rem; font-weight: 800; letter-spacing: .16em; }
.flow-step h3 { margin-bottom: 10px; font-size: 1.05rem; }
.flow-step p:last-child { margin: 0; color: var(--ink-soft); font-size: .95rem; line-height: 1.55; }

.card-grid-five { grid-template-columns: repeat(5, 1fr); }
.card-grid-five .plain-card { min-height: 190px; padding: 26px; }

.tag-row { display: flex; flex-wrap: wrap; gap: 10px; margin: 34px 0 0; padding: 0; list-style: none; }
.tag { display: inline-block; padding: .34rem .85rem; border: 1px solid transparent; border-radius: 999px; background: rgba(20, 34, 33, .06); color: var(--teal-dark); font-size: 0.84rem; font-weight: 800; letter-spacing: .12em; text-transform: uppercase; }
/* A bordered pill sitting under two real buttons reads as a button. Labels lost the
   outline and took a fill; only the pills that actually navigate keep the outline, and
   they gain a hover so the affordance is earned rather than implied. */
.tag-link { border-color: var(--line); background: transparent; text-decoration: none; transition: background .12s ease, color .12s ease, border-color .12s ease; }
.tag-link:hover { border-color: var(--ink); background: var(--ink); color: var(--paper-bright); }

.system-block h2 { margin-bottom: 26px; }
.system-block .mini-label { margin: 26px 0 8px; color: var(--teal); font-size: 0.84rem; font-weight: 800; letter-spacing: .15em; text-transform: uppercase; }
.system-block .mini-label:first-of-type { margin-top: 0; }
.system-block div p { max-width: 760px; color: var(--ink-soft); font-size: 1.05rem; }
.system-block div p.outcome-line { color: var(--ink); font-family: Georgia, "Times New Roman", serif; font-size: 1.24rem; line-height: 1.45; }
.system-block div p.continuity-note { max-width: 74ch; margin-top: 28px; padding: 16px 20px; border-left: 3px solid var(--teal); border-radius: 0 12px 12px 0; background: var(--paper-bright); font-size: .98rem; }
.continuity-note strong { color: var(--teal-dark); }

.prose-on-dark { color: rgba(255, 255, 255, .78); }
.section-footnote { margin: 44px 0 0; }
.text-link-light { color: var(--lime); }

@media (max-width: 1100px) {
  .flow-strip { grid-template-columns: 1fr; }
  .card-grid-five { grid-template-columns: repeat(2, 1fr); }
}

@media (max-width: 820px) {
  .card-grid-five { grid-template-columns: 1fr; }
  .card-grid-five .plain-card { min-height: 0; }
  .system-block .mini-label:first-of-type { margin-top: 4px; }
}

/* --- Rebalance additions (cross-sector sections, proof blocks, six-step flows) --- */

.section-lede { max-width: 780px; margin: -26px 0 48px; color: var(--ink-soft); font-size: 1.12rem; line-height: 1.65; }
.flow-strip.flow-six { grid-template-columns: repeat(6, 1fr); }
.card-grid-two { grid-template-columns: repeat(2, 1fr); }
.proof-card { min-height: 0; }
.proof-card h3 { margin-bottom: 18px; }
.proof-card p { margin-bottom: 12px; font-size: .96rem; line-height: 1.6; color: rgba(255, 255, 255, .82); }
.proof-card p:last-child { margin-bottom: 0; color: rgba(255, 255, 255, .82); }
.proof-card strong { color: var(--lime); font-weight: 750; }
.system-block .block-title { margin-bottom: 26px; font-family: Georgia, "Times New Roman", serif; font-size: var(--fs-9); font-weight: 500; letter-spacing: -.035em; line-height: 1.08; }
.service-row p.continuity-note { margin-top: 18px; max-width: 74ch; padding: 16px 20px; border-left: 3px solid var(--teal); border-radius: 0 12px 12px 0; background: var(--paper-bright); color: var(--ink-soft); font-size: .98rem; }
.service-row p.continuity-note strong { color: var(--teal-dark); }
.hero-copy .tag-row { margin-top: 40px; }

@media (max-width: 1100px) {
  .flow-strip.flow-six { grid-template-columns: 1fr; }
}

@media (max-width: 820px) {
  .card-grid-two { grid-template-columns: 1fr; }
}

/* Evidence and proof additions */
.stat-band { width: min(var(--max), calc(100% - 40px)); margin: 0 auto; padding: 0 0 clamp(48px, 6vw, 72px); }
.stat-band ul { margin: 0; padding: 0; list-style: none; display: grid; grid-template-columns: repeat(4, 1fr); gap: 18px; border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); }
.stat-band li { padding: 26px 0; }
.stat-band .stat-figure { display: block; margin: 0 0 6px; font-family: Georgia, "Times New Roman", serif; font-size: var(--fs-10); font-weight: 500; letter-spacing: -.03em; line-height: 1; }
.stat-band .stat-label { display: block; color: var(--ink-soft); font-size: 0.84rem; font-weight: 700; letter-spacing: .1em; text-transform: uppercase; }
.case-study { padding: clamp(56px, 7vw, 88px) 0; border-top: 1px solid var(--line); }
.case-study:first-of-type { border-top: 0; }
.case-study .case-kicker { margin: 0 0 14px; color: var(--teal); font-size: 0.84rem; font-weight: 800; letter-spacing: .16em; text-transform: uppercase; }
.case-study h2 { max-width: 20ch; margin: 0 0 26px; font-family: Georgia, "Times New Roman", serif; font-size: var(--fs-11); font-weight: 500; letter-spacing: -.035em; line-height: 1.06; }
.case-study p, .case-study li { max-width: 760px; color: var(--ink-soft); font-size: 1.08rem; }
.case-study .case-lede { color: var(--ink); font-family: Georgia, "Times New Roman", serif; font-size: var(--fs-12); line-height: 1.45; }
.method-map { margin: 30px 0 0; padding: 24px 26px; border-left: 3px solid var(--teal); border-radius: 0 12px 12px 0; background: var(--paper-bright); }
.method-map p.mini-label { margin: 0 0 12px; color: var(--teal); font-size: 0.84rem; font-weight: 800; letter-spacing: .15em; text-transform: uppercase; }
.method-map ol { margin: 0; padding-left: 1.2rem; }
.method-map li { max-width: 74ch; margin-bottom: 8px; font-size: .99rem; }
.method-map li:last-child { margin-bottom: 0; }
/* "Mapped to the method" beside its prose (2026-11-04): prose left, card right, top-aligned, full container width.
   .method-aside stacks the section plate above the card when the section also has a plate. Stacks under 900px. */
.method-split { display: grid; grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr); gap: clamp(32px, 5vw, 72px); align-items: center; }
.method-split > :first-child > :last-child { margin-bottom: 0; }
.method-split .method-map { margin: 0; }
.method-split .method-aside > .side-plate { position: static; max-width: none; width: 100%; margin-bottom: 24px; }
@media (max-width: 900px) {
  .method-split { grid-template-columns: 1fr; }
  .method-split .method-aside > .side-plate { max-width: 420px; }
}
.evidence-table { width: 100%; margin: 30px 0 0; border-collapse: collapse; font-size: .95rem; }
.evidence-table caption { margin-bottom: 12px; color: var(--ink-soft); font-size: .9rem; text-align: left; }
.evidence-table th, .evidence-table td { padding: 12px 14px 12px 0; border-bottom: 1px solid var(--line); text-align: left; vertical-align: top; }
.evidence-table th { color: var(--teal-dark); font-size: 0.84rem; font-weight: 800; letter-spacing: .1em; text-transform: uppercase; }
.evidence-table td { color: var(--ink-soft); }
.estimate-note { margin-top: 26px; padding: 14px 18px; border: 1px dashed var(--line); border-radius: 12px; background: var(--paper-bright); font-size: .95rem; }
.estimate-note strong { color: var(--teal-dark); }
.credential-card { padding: clamp(28px, 4vw, 48px); border-radius: var(--radius); background: var(--teal-dark); color: white; box-shadow: 18px 18px 0 var(--lime); }
.credential-card h2 { margin: 0 0 8px; font-family: Georgia, "Times New Roman", serif; font-size: var(--fs-13); font-weight: 500; letter-spacing: -.03em; }
.credential-card .credential-role { margin: 0 0 24px; color: var(--lime); font-size: 0.84rem; font-weight: 800; letter-spacing: .14em; text-transform: uppercase; }
.credential-card p { max-width: 640px; color: rgba(255, 255, 255, .84); font-size: 1.03rem; }
.credential-card .credential-contact { margin-bottom: 0; padding-top: 20px; border-top: 1px solid rgba(255, 255, 255, .22); font-size: .95rem; }
.credential-card a { color: var(--lime); }
.quality-bar { margin: 0; padding: 26px 30px; border-left: 3px solid var(--lime); background: var(--ink); color: white; border-radius: 0 16px 16px 0; }
.quality-bar .bar-words { margin: 0 0 18px; font-family: Georgia, "Times New Roman", serif; font-size: var(--fs-14); line-height: 1.4; color: white; }
.quality-bar p { color: rgba(255, 255, 255, .82); font-size: 1rem; }
.quality-bar p:last-child { margin-bottom: 0; }
.commitment-list { margin: 0; padding: 0; list-style: none; }
.commitment-list li { max-width: 74ch; padding: 18px 0; border-top: 1px solid var(--line); font-size: 1.04rem; color: var(--ink-soft); }
.commitment-list li:last-child { border-bottom: 1px solid var(--line); }
.commitment-list strong { display: block; margin-bottom: 4px; color: var(--ink); font-size: 0.84rem; font-weight: 800; letter-spacing: .1em; text-transform: uppercase; }

@media (max-width: 1100px) {
  .stat-band ul { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 560px) {
  .stat-band ul { grid-template-columns: 1fr; }
  .stat-band li { padding: 18px 0; border-top: 1px solid var(--line); }
  .stat-band li:first-child { border-top: 0; }
  .evidence-table th, .evidence-table td { padding-right: 8px; font-size: .88rem; }
}

/* Two practices, one method: paired presentation */
.practice-band { width: min(var(--max), calc(100% - 40px)); margin: 0 auto; padding: 0 0 clamp(48px, 6vw, 80px); }
.practice-spine { max-width: 40ch; margin: 0 0 40px; font-family: Georgia, "Times New Roman", serif; font-size: var(--fs-15); font-weight: 500; letter-spacing: -.03em; line-height: 1.2; color: var(--ink); }
.practice-spine span { color: var(--teal); }
.practice-cols { --practice-gap: clamp(28px, 5vw, 64px); display: grid; grid-template-columns: 1fr 1fr; gap: var(--practice-gap); border-top: 1px solid var(--line); }
.practice-col { padding-top: 28px; }
.practice-col + .practice-col { padding-left: clamp(28px, 5vw, 64px); border-left: 1px solid var(--line); }
.practice-label { margin: 0 0 6px; color: var(--teal); font-size: 0.84rem; font-weight: 800; letter-spacing: .14em; text-transform: uppercase; }
.practice-years { margin: 0 0 26px; color: var(--ink-soft); font-size: .92rem; }
.practice-col ul { margin: 0; padding: 0; list-style: none; display: grid; grid-template-columns: 1fr 1fr; gap: 20px; }
.practice-col li { min-width: 0; }
.practice-col .stat-figure { display: block; margin: 0 0 6px; font-family: Georgia, "Times New Roman", serif; font-size: var(--fs-16); font-weight: 500; letter-spacing: -.03em; line-height: 1; }
.practice-col .stat-label { display: block; color: var(--ink-soft); font-size: .88rem; line-height: 1.4; }

/* The convergence. Both practice columns resolve onto one statement, so the
   spine sits BELOW the columns as their conclusion rather than above them as a
   heading. Everything here is the RESTING layout: with no JavaScript, under
   prefers-reduced-motion, or in a print context this reads as two bodies of
   work above the one sentence they share, which is the argument. Motion only
   adds the arriving. */
.practice-merge { --practice-gap: clamp(28px, 5vw, 64px); position: relative; height: clamp(44px, 5vw, 72px); }
/* Drawn as pseudo-elements, not borders. .practice-col already swaps
   border-left for border-top at 820px and a bordered connector would collide
   with that rule. */
.practice-merge::before {
  content: ""; position: absolute; top: 0; height: 50%;
  left: calc(25% - var(--practice-gap) / 4);
  right: calc(25% - var(--practice-gap) / 4);
  border-left: 1px solid var(--line); border-right: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
}
.practice-merge::after {
  content: ""; position: absolute; top: 50%; left: 50%; margin-left: -.5px;
  width: 1px; height: 50%; background: var(--line);
}
.practice-vertex { max-width: 46ch; margin: 0 auto; text-align: center; }
.practice-vertex .practice-spine { max-width: none; margin: 0; }

@media (max-width: 820px) {
  /* Stacked, there is no left and right to converge from, so the bracket
     becomes a single stem and the columns arrive in reading order instead.
     Same argument, delivered as sequence rather than as geometry. */
  .practice-merge { height: clamp(32px, 6vw, 48px); }
  .practice-merge::before { left: 50%; right: 50%; border-right: 0; border-bottom: 0; }
  /* stacked: the legs would have nothing to point at */
  .practice-merge::after { display: none; }
}
.proof-group { margin-top: clamp(40px, 5vw, 64px); }
.proof-group:first-of-type { margin-top: 0; }
.proof-group-label { display: flex; align-items: baseline; gap: 14px; margin: 0 0 8px; }
.proof-group-label .pg-tag { color: var(--lime); font-size: 0.84rem; font-weight: 800; letter-spacing: .14em; text-transform: uppercase; }
.proof-group-label .pg-rule { flex: 1; height: 1px; background: rgba(255, 255, 255, .22); }
.proof-group h3.pg-title { margin: 0 0 26px; font-family: Georgia, "Times New Roman", serif; font-size: var(--fs-17); font-weight: 500; letter-spacing: -.03em; color: white; }

@media (max-width: 820px) {
  .practice-cols { grid-template-columns: 1fr; }
  .practice-col + .practice-col { padding-left: 0; border-left: 0; border-top: 1px solid var(--line); }
}
@media (max-width: 480px) {
  .practice-col ul { grid-template-columns: 1fr; gap: 16px; }
}

/* The through-line: brief / saw / result */
.insight-list { margin: 0; padding: 0; list-style: none; }
.insight-list li { padding: 34px 0; border-top: 1px solid var(--line); display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.35fr); gap: clamp(20px, 4vw, 56px); align-items: start; }
.insight-list li:last-child { border-bottom: 1px solid var(--line); }
.insight-brief { margin: 0; }
.insight-brief .insight-tag { display: block; margin-bottom: 10px; color: var(--teal); font-size: 0.84rem; font-weight: 800; letter-spacing: .14em; text-transform: uppercase; }
.insight-brief .insight-said { margin: 0; color: var(--ink-soft); font-size: 1.02rem; line-height: 1.55; }
.insight-body { margin: 0; }
.insight-saw { margin: 0 0 14px; color: var(--ink); font-family: Georgia, "Times New Roman", serif; font-size: var(--fs-18); line-height: 1.42; }
.insight-result { margin: 0; color: var(--ink-soft); font-size: 1.02rem; line-height: 1.55; }
.insight-result strong { color: var(--teal-dark); font-weight: 750; }

@media (max-width: 820px) {
  .insight-list li { grid-template-columns: 1fr; gap: 14px; padding: 26px 0; }
}

/* Hero headline: two sentences need a tighter scale and character-based wrapping,
   otherwise a wider viewport produces MORE lines, not fewer. */
.hero h1 { max-width: 24ch; font-size: var(--fs-19); line-height: 1.06; text-wrap: balance; }

/* Mobile header: seven nav items were consuming a quarter of a phone viewport.
   Tighter type and spacing keeps the whole nav to two compact rows. */
@media (max-width: 820px) {
  .site-header { min-height: 0; padding: 18px 0; }
  nav { gap: 8px 16px; }
  nav a { font-size: .86rem; }
}
@media (max-width: 560px) {
  .brand { font-size: .84rem; }
  .brand-mark { width: 2.375rem; height: 2.375rem; flex: 0 0 2.375rem; }
  nav { margin-top: 16px; gap: 6px 14px; }
  nav a { font-size: 0.84rem; }
}

/* Provenance note under the figures */
.band-note { margin: 20px 0 0; color: var(--ink-soft); font-size: .9rem; font-style: italic; }


/* ---------------------------------------------------------------------------
   Accessibility pass, 2026-08-26. Measured, not eyeballed.

   A ground owns its ink. Three elements measured between 1.02:1 and 1.55:1
   because a paper-ground class was reused on a dark ground and kept its dark
   ink: a section lede on systems, and two case-study links. Fixing the ground
   once beats fixing each element and remembering to next time.
   --------------------------------------------------------------------------- */
.section-dark .section-lede,
.section-dark .lede,
.section-dark .band-note { color: rgba(255, 255, 255, .82); }
.section-dark .text-link,
.section-dark .mini-label,
.section-dark .tag { color: var(--lime); }
.section-dark .tag { background: rgba(255, 255, 255, .1); border-color: transparent; }
.section-dark .tag-link { background: transparent; border-color: rgba(255, 255, 255, .3); }
.section-dark .tag-link:hover { background: var(--lime); border-color: var(--lime); color: var(--ink); }

/* A light island inside a dark ground states its own ink rather than inheriting
   white onto cream, which is how a whole note measured 1.02:1. Twice: the estimate
   note, then the method map, when one was first placed on a dark section. Any future
   component that paints its own light fill belongs in this list on the day it is
   written, not on the day it is measured. */
.estimate-note { color: var(--ink); }
.estimate-note a { color: var(--teal-dark); }
.method-map { color: var(--ink); }
.method-map li, .method-map strong { color: var(--ink); }
.method-map a { color: var(--teal-dark); }

/* Tap targets. Nav links measured 33px and the brand 38px against the 44pt
   mobile minimum, on every page. The min-height creates the height, and the row
   gap comes down so the header does not grow. */
@media (max-width: 820px) {
  nav { gap: 2px 18px; }
  nav a { min-height: 44px; display: inline-flex; align-items: center; padding: 0; }
  .brand { min-height: 44px; }
  /* Standalone call-to-action links measured 24 to 29px. Links sitting inside a
     sentence are exempt: enlarging those would break the line box around them. */
  .text-link, .contact-email { min-height: 44px; display: inline-flex; align-items: center; }
}


/* Two named practices, one vocabulary. The services page ran as six undifferentiated
   rows, so a land client and a software client had to sort the list themselves.
   Same device as the proof page's Part one / Part two, on a paper ground. */
.lane-group + .lane-group { margin-top: clamp(56px, 7vw, 88px); }
.lane-heading { display: flex; align-items: baseline; gap: 14px; margin: 0 0 10px; }
.lane-tag { color: var(--teal); font-size: 0.84rem; font-weight: 800; letter-spacing: .14em;
  text-transform: uppercase; white-space: nowrap; }
.lane-rule { flex: 1; height: 1px; background: var(--line); }
.lane-title { margin: 0 0 14px; font-family: Georgia, "Times New Roman", serif;
  font-size: var(--fs-20); font-weight: 500; letter-spacing: -.03em; }
.lane-note { max-width: 74ch; margin: 0 0 10px; color: var(--ink-soft); font-size: 1.04rem; }
.lane-both { max-width: 78ch; margin: clamp(48px, 6vw, 72px) 0 0; padding: 20px 24px; border-left: 3px solid var(--teal);
  border-radius: 0 14px 14px 0; background: var(--paper-bright); }


/* The career record. The site had no roles, no dates and no education anywhere, which
   is the first thing an employer looks for and the thing that lets them reconcile this
   site against a resume. Dates in the left rail, same rhythm as the service rows. */
.record-list { margin: 0; padding: 0; list-style: none; }
.record-list li { display: grid; grid-template-columns: 150px 1fr; gap: 28px;
  padding: 34px 0; border-top: 1px solid var(--line); }
.record-list li:last-child { border-bottom: 1px solid var(--line); }
.record-when { margin: 6px 0 0; color: var(--teal); font-size: 0.84rem; font-weight: 800;
  letter-spacing: .12em; text-transform: uppercase; }
.record-list h3 { margin: 0 0 8px; font-family: Georgia, "Times New Roman", serif;
  font-size: var(--fs-21); font-weight: 500; letter-spacing: -.02em; }
.record-list p:not(.record-when) { max-width: 74ch; margin: 0; color: var(--ink-soft); font-size: 1.02rem; }
@media (max-width: 820px) {
  .record-list li { grid-template-columns: 1fr; gap: 8px; padding: 26px 0; }
  .record-when { margin: 0; }
}


/* The domain pills are navigation on a phone as much as on a desktop. */
@media (max-width: 820px) {
  .tag-link { min-height: 44px; display: inline-flex; align-items: center; }
}

/* --- Motion -----------------------------------------------------------
   Every rule below is scoped to .js-motion, which motion.js puts on <html>
   only after it has found something to animate and confirmed the reader has
   not asked for less of it. Without that class this whole block is inert and
   the page renders as it always has. Content is never hidden by CSS alone. */

.js-motion [data-r] {
  opacity: 0;
  transform: translateY(14px);
  transition: opacity .62s cubic-bezier(.22, .68, .36, 1),
              transform .62s cubic-bezier(.22, .68, .36, 1);
}
.js-motion [data-r].is-in { opacity: 1; transform: none; }

/* A revealed element must never sit behind a focus ring or a sticky header
   in a half-transformed state, so focus inside one settles it immediately. */
.js-motion [data-r]:focus-within { opacity: 1; transform: none; transition-delay: 0ms; }

/* The four-step method reads as a sequence, so its rail draws down as the
   block arrives rather than being there before the steps are. */
.js-motion .method-map { position: relative; border-left-color: transparent; }
.js-motion .method-map::before {
  content: ""; position: absolute; left: -3px; top: 0; width: 3px; height: 100%;
  background: var(--teal); transform: scaleY(0); transform-origin: top;
  transition: transform .7s cubic-bezier(.22, .68, .36, 1) .1s;
}
.js-motion .method-map.is-in::before { transform: scaleY(1); }

/* The two practices arrive inward, and the connector draws after them.
   `translate`, NOT `transform`. These columns are also reveal targets, and
   `.js-motion [data-r].is-in` sets `transform: none` at higher specificity,
   so a convergence written as transform: translateX() would silently do
   nothing. That is KIE-208, and this is exactly the shape of feature that
   hits it. The standalone property composes with the reveal instead of
   fighting it. */
.js-motion .practice-cols > .practice-col {
  translate: -20px 0;
  transition: translate .72s cubic-bezier(.22, .68, .36, 1);
}
.js-motion .practice-cols > .practice-col + .practice-col { translate: 20px 0; }
.js-motion .practice-cols > .practice-col.is-in { translate: 0 0; }

.js-motion .practice-merge::before,
.js-motion .practice-merge::after {
  transform: scaleY(0); transform-origin: top;
  transition: transform .5s cubic-bezier(.22, .68, .36, 1);
}
.js-motion .practice-merge::before { transition-delay: .18s; }
.js-motion .practice-merge::after { transition-delay: .42s; }
.js-motion .practice-merge.is-in::before,
.js-motion .practice-merge.is-in::after { transform: scaleY(1); }

@media (max-width: 820px) {
  /* Stacked: the arrival is vertical, which the reveal already does. */
  .js-motion .practice-cols > .practice-col,
  .js-motion .practice-cols > .practice-col + .practice-col { translate: 0 0; }
}

/* Reading position. Two pixels, brand teal, and it is decorative: it carries
   aria-hidden and no information that is not already in the scrollbar. */
.read-rail {
  position: fixed; top: 0; left: 0; z-index: 90;
  width: 100%; height: 2px; background: var(--teal);
  transform: scaleX(0); transform-origin: left;
  will-change: transform; pointer-events: none;
}

/* The header is a centred column, so making it sticky left the page scrolling
   visibly past it on both sides. This paints the bar full-bleed behind the
   header's own content without touching the markup on fourteen pages. It is
   present at rest too, where paper on paper is invisible, so there is no
   uncovered moment between scroll position 0 and the scrolled state. */
/* Sticky only where the header stays one compact row. Measured: it is 96px at
   900px and above, 127px from 640px, and 187px at 390px, where the nav has
   wrapped to two lines. Pinning 187px to the top of an 844px phone spends 22%
   of the screen on navigation for the whole scroll, which is a bad trade for a
   site people are here to read. */
.site-header { z-index: 80; }
@media (min-width: 900px) { .site-header { position: sticky; top: 0; } }
.site-header::before {
  content: ""; position: absolute; z-index: -1;
  top: 0; bottom: -1px; left: 50%; transform: translateX(-50%);
  width: 100vw; background: var(--paper);
  transition: box-shadow .3s ease;
}
.site-header.is-scrolled::before { box-shadow: 0 10px 24px -20px rgba(20, 34, 33, .55); }

/* Collapsing menu, after the VEM header (same breakpoint logic: the full nav
   is used only where it fits). Measured: brand 280px + nav 727px + 24px gap +
   40px page margins = 1071px, so the full nav runs from 1080px up and below
   that it collapses behind a Menu button. nav.js must use the same 1079px.
   Without JavaScript the button never appears (it is display:none here and
   shown only under .nav-enhanced, which nav.js adds once armed), so the nav
   stays visible and wraps as it always has. */
.nav-toggle { display: none; }
@keyframes nav-panel-in { from { opacity: .2; transform: translateY(-6px); } to { opacity: 1; transform: none; } }
@media (max-width: 1079px) {
  .site-header:not(.nav-enhanced) { flex-wrap: wrap; }
  .site-header.nav-enhanced { position: sticky; top: 0; display: flex; align-items: center; justify-content: space-between; gap: 16px; min-height: 72px; padding: 14px 0; }
  .nav-enhanced .nav-toggle {
    display: inline-flex; align-items: center; justify-content: center; flex: 0 0 auto;
    min-width: 44px; min-height: 44px; padding: 0 18px; border: 1px solid var(--ink); border-radius: 999px;
    background: transparent; color: var(--ink); font: inherit; font-size: .84rem; font-weight: 760;
    letter-spacing: .14em; text-transform: uppercase; cursor: pointer;
  }
  .nav-enhanced .nav-toggle:hover, .nav-enhanced .nav-toggle[aria-expanded="true"] { background: var(--ink); color: var(--paper-bright); }
  .nav-enhanced .nav-toggle:focus-visible { outline-offset: 3px; }
  /* The panel is as wide as the viewport: the header is the viewport minus
     20px a side up to 1220px, and this is only used below 1080px. */
  .site-header.nav-enhanced nav {
    display: none; position: absolute; top: 100%; left: -20px; right: -20px; margin: 0;
    flex-direction: column; align-items: stretch; gap: 0; padding: 4px 20px 20px;
    max-height: calc(100vh - 72px); max-height: calc(100dvh - 72px); overflow-y: auto; overscroll-behavior: contain;
    background: var(--paper-bright); border-bottom: 1px solid var(--line);
    box-shadow: 0 22px 32px -24px rgba(20, 34, 33, .55);
  }
  .site-header.nav-enhanced nav.is-open { display: flex; animation: nav-panel-in .22s cubic-bezier(.22, .68, .36, 1); }
  .site-header.nav-enhanced nav a {
    display: flex; align-items: center; min-height: 48px; padding: 0 4px; font-size: 1rem;
    border-bottom: 1px solid var(--line);
  }
  .site-header.nav-enhanced nav a:last-child { border-bottom-color: transparent; }
  .site-header.nav-enhanced nav a:hover { border-bottom-color: var(--line); }
  .site-header.nav-enhanced nav a[aria-current="page"] { padding-left: 14px; box-shadow: inset 3px 0 0 var(--teal); }
  .site-header.nav-enhanced nav a[aria-current="page"]:last-child { border-bottom-color: transparent; }
  .site-header.nav-enhanced .brand { max-width: calc(100% - 100px); }
}
@media (max-width: 899px) { :target, #main { scroll-margin-top: 96px; } }
@media (prefers-reduced-motion: reduce) {
  .site-header.nav-enhanced { position: relative; }
  .site-header.nav-enhanced nav.is-open { animation: none; }
}

/* An anchor jump must not land under the sticky bar. */
:target, #main { scroll-margin-top: 24px; }
@media (min-width: 900px) { :target, #main { scroll-margin-top: 112px; } }

/* Hover: a lift small enough to read as responsiveness rather than as a card
   that moves. Guarded to pointers that actually hover, so a touch device does
   not get a stuck hover state after a tap. */
/* These lifts use `translate`, not `transform`, and that is deliberate. Most of
   these cards are also reveal targets, and `.js-motion [data-r].is-in` sets
   `transform: none` at a higher specificity than `.flow-step:hover`, so a hover
   written as `transform: translateY(-2px)` silently lost every time. The shadow
   appeared and the card did not move. `translate` is its own property, so the
   two compose instead of competing and no specificity race is needed. */
@media (hover: hover) {
  .service-card, .plain-card, .flow-step, .signal-card, .credential-card, .system-block {
    transition: translate .28s cubic-bezier(.22, .68, .36, 1), box-shadow .28s ease, border-color .28s ease;
  }
  .service-card:hover, .plain-card:hover, .flow-step:hover,
  .signal-card:hover, .credential-card:hover, .system-block:hover {
    translate: 0 -2px;
    box-shadow: 0 18px 34px -26px rgba(20, 34, 33, .55);
  }
  .text-link span[aria-hidden] { display: inline-block; transition: translate .26s cubic-bezier(.22, .68, .36, 1); }
  .text-link:hover span[aria-hidden] { translate: 4px 0; }
  .button { transition: translate .2s cubic-bezier(.22, .68, .36, 1), box-shadow .2s ease, background .2s ease, color .2s ease; }
  .button:hover { translate: 0 -1px; }
  nav a { transition: color .2s ease, border-color .2s ease; }
}

/* The global reduce block above neutralises durations. This removes the
   mechanisms outright, so nothing is left mid-transform at 0.01ms. */
@media (prefers-reduced-motion: reduce) {
  .js-motion [data-r] { opacity: 1 !important; transform: none !important; }
  /* `translate` is a separate property from `transform` and the reset above
     does not reach it. Without this line a reader who asked for less motion
     would be left holding the columns 20px off their resting position. */
  .js-motion .practice-cols > .practice-col,
  .js-motion .practice-cols > .practice-col + .practice-col { translate: none !important; }
  .js-motion .practice-merge::before,
  .js-motion .practice-merge::after { transform: none !important; transition: none !important; }
  .js-motion .method-map { border-left-color: var(--teal); }
  .js-motion .method-map::before { display: none; }
  .read-rail { display: none; }
  .site-header { position: static; }
}

/* Uppercase kickers carry .16em of tracking, which reads well across a desktop
   column and turns into three stacked lines on a 390px screen. Measured: the
   home page kicker is 3 lines at 390px and drops to 2 at .09em, at the same
   type size. Tracking is the thing to spend here, not size -- size is pinned by
   the accessible floor. */
@media (max-width: 640px) {
  .eyebrow, .card-label, .mini-label, .practice-label, .case-kicker, .lane-tag,
  .proof-group-label { letter-spacing: .09em; }
}

/* Delivered-work rows: put the link on its own line, always.
   `.text-link` carries `margin-top: 14px`, which is right for a link that
   already sits on its own line and wrong when it lands inline at the end of a
   sentence -- there it adds leading to that one line and nothing else, so rows
   sat unevenly depending only on where the sentence happened to wrap. Four of
   the six looked broken and two looked fine, for no reason a reader could see.
   Block display makes the wrap point irrelevant. */
.commitment-list .text-link { display: block; width: fit-content; }

/* --- Type scale, rem only ---------------------------------------------
   Every heading used to be clamp(MINrem, calc(Arem + Bvw), MAXrem). A `vw`
   term is an ABSOLUTE length, so it cannot respond to the root font size:
   when a reader doubles their browser's default text size the fluid middle
   term does not move and the value scales by less than two. Measured before
   this change, at 1440px: h1 reached 1.37x and .lede 1.76x, against the 2x
   the accessibility guidance asks for.

   Smooth viewport fluidity and exact 2x text scaling cannot both hold, so
   the fluidity is what gives. These are the sizes the old curve produced,
   sampled at the MIDPOINT of each range below and pinned there. Fitting the
   top of each range instead put the largest error at a breakpoint edge, so
   midpoints it is. Type steps between these widths rather than sliding, and
   every value is rem, so all of it doubles with the reader's setting. */
:root {
  --fs-1: 3.492rem;
  --fs-2: 2.25rem;
  --fs-3: 1.1rem;
  --fs-4: 2rem;
  --fs-5: 2.5rem;
  --fs-6: 2rem;
  --fs-7: 2.5rem;
  --fs-8: 1.05rem;
  --fs-9: 1.9rem;
  --fs-10: 2.1rem;
  --fs-11: 2.134rem;
  --fs-12: 1.24rem;
  --fs-13: 1.9rem;
  --fs-14: 1.3rem;
  --fs-15: 1.5rem;
  --fs-16: 1.9rem;
  --fs-17: 1.5rem;
  --fs-18: 1.14rem;
  --fs-19: 2.5rem;
  --fs-20: 1.7rem;
  --fs-21: 1.25rem;
}
@media (min-width: 560px) {
  :root {
    --fs-1: 4.005rem;
    --fs-2: 2.447rem;
    --fs-3: 1.113rem;
    --fs-4: 2.225rem;
    --fs-5: 2.781rem;
    --fs-6: 2.225rem;
    --fs-7: 2.781rem;
    --fs-8: 1.113rem;
    --fs-9: 2.002rem;
    --fs-10: 2.225rem;
    --fs-11: 2.447rem;
    --fs-12: 1.24rem;
    --fs-13: 1.9rem;
    --fs-14: 1.446rem;
    --fs-15: 1.669rem;
    --fs-16: 1.9rem;
    --fs-17: 1.557rem;
    --fs-18: 1.14rem;
    --fs-19: 2.559rem;
    --fs-20: 1.768rem;
    --fs-21: 1.294rem;
  }
}
@media (min-width: 700px) {
  :root {
    --fs-1: 4.383rem;
    --fs-2: 2.679rem;
    --fs-3: 1.218rem;
    --fs-4: 2.435rem;
    --fs-5: 3.044rem;
    --fs-6: 2.435rem;
    --fs-7: 3.044rem;
    --fs-8: 1.218rem;
    --fs-9: 2.192rem;
    --fs-10: 2.435rem;
    --fs-11: 2.679rem;
    --fs-12: 1.339rem;
    --fs-13: 2.07rem;
    --fs-14: 1.583rem;
    --fs-15: 1.826rem;
    --fs-16: 1.948rem;
    --fs-17: 1.704rem;
    --fs-18: 1.157rem;
    --fs-19: 2.8rem;
    --fs-20: 1.934rem;
    --fs-21: 1.381rem;
  }
}
@media (min-width: 840px) {
  :root {
    --fs-1: 4.761rem;
    --fs-2: 2.909rem;
    --fs-3: 1.323rem;
    --fs-4: 2.645rem;
    --fs-5: 3.306rem;
    --fs-6: 2.645rem;
    --fs-7: 3.306rem;
    --fs-8: 1.3rem;
    --fs-9: 2.381rem;
    --fs-10: 2.645rem;
    --fs-11: 2.909rem;
    --fs-12: 1.455rem;
    --fs-13: 2.248rem;
    --fs-14: 1.719rem;
    --fs-15: 1.984rem;
    --fs-16: 2.116rem;
    --fs-17: 1.852rem;
    --fs-18: 1.256rem;
    --fs-19: 3.042rem;
    --fs-20: 2.101rem;
    --fs-21: 1.469rem;
  }
}
@media (min-width: 980px) {
  :root {
    --fs-1: 5.139rem;
    --fs-2: 3.14rem;
    --fs-3: 1.34rem;
    --fs-4: 2.855rem;
    --fs-5: 3.569rem;
    --fs-6: 2.855rem;
    --fs-7: 3.569rem;
    --fs-8: 1.3rem;
    --fs-9: 2.569rem;
    --fs-10: 2.855rem;
    --fs-11: 3.14rem;
    --fs-12: 1.57rem;
    --fs-13: 2.427rem;
    --fs-14: 1.856rem;
    --fs-15: 2.141rem;
    --fs-16: 2.284rem;
    --fs-17: 1.998rem;
    --fs-18: 1.356rem;
    --fs-19: 3.283rem;
    --fs-20: 2.267rem;
    --fs-21: 1.556rem;
  }
}
@media (min-width: 1120px) {
  :root {
    --fs-1: 5.517rem;
    --fs-2: 3.372rem;
    --fs-3: 1.34rem;
    --fs-4: 3.065rem;
    --fs-5: 3.831rem;
    --fs-6: 3.065rem;
    --fs-7: 3.831rem;
    --fs-8: 1.3rem;
    --fs-9: 2.758rem;
    --fs-10: 3.065rem;
    --fs-11: 3.372rem;
    --fs-12: 1.6rem;
    --fs-13: 2.605rem;
    --fs-14: 1.9rem;
    --fs-15: 2.299rem;
    --fs-16: 2.452rem;
    --fs-17: 2.145rem;
    --fs-18: 1.42rem;
    --fs-19: 3.525rem;
    --fs-20: 2.433rem;
    --fs-21: 1.6rem;
  }
}
@media (min-width: 1260px) {
  :root {
    --fs-1: 5.895rem;
    --fs-2: 3.603rem;
    --fs-3: 1.34rem;
    --fs-4: 3.275rem;
    --fs-5: 4.094rem;
    --fs-6: 3.275rem;
    --fs-7: 4.094rem;
    --fs-8: 1.3rem;
    --fs-9: 2.947rem;
    --fs-10: 3.1rem;
    --fs-11: 3.6rem;
    --fs-12: 1.6rem;
    --fs-13: 2.7rem;
    --fs-14: 1.9rem;
    --fs-15: 2.3rem;
    --fs-16: 2.62rem;
    --fs-17: 2.2rem;
    --fs-18: 1.42rem;
    --fs-19: 3.766rem;
    --fs-20: 2.599rem;
    --fs-21: 1.6rem;
  }
}
@media (min-width: 1400px) {
  :root {
    --fs-1: 6.3rem;
    --fs-2: 3.85rem;
    --fs-3: 1.34rem;
    --fs-4: 3.5rem;
    --fs-5: 4.375rem;
    --fs-6: 3.4rem;
    --fs-7: 4.375rem;
    --fs-8: 1.3rem;
    --fs-9: 3.1rem;
    --fs-10: 3.1rem;
    --fs-11: 3.6rem;
    --fs-12: 1.6rem;
    --fs-13: 2.7rem;
    --fs-14: 1.9rem;
    --fs-15: 2.3rem;
    --fs-16: 2.7rem;
    --fs-17: 2.2rem;
    --fs-18: 1.42rem;
    --fs-19: 3.9rem;
    --fs-20: 2.6rem;
    --fs-21: 1.6rem;
  }
}
@media (min-width: 1560px) {
  :root {
    --fs-1: 6.732rem;
    --fs-2: 4.114rem;
    --fs-3: 1.34rem;
    --fs-4: 3.7rem;
    --fs-5: 4.4rem;
    --fs-6: 3.4rem;
    --fs-7: 4.4rem;
    --fs-8: 1.3rem;
    --fs-9: 3.1rem;
    --fs-10: 3.1rem;
    --fs-11: 3.6rem;
    --fs-12: 1.6rem;
    --fs-13: 2.7rem;
    --fs-14: 1.9rem;
    --fs-15: 2.3rem;
    --fs-16: 2.7rem;
    --fs-17: 2.2rem;
    --fs-18: 1.42rem;
    --fs-19: 3.9rem;
    --fs-20: 2.6rem;
    --fs-21: 1.6rem;
  }
}
@media (min-width: 1720px) {
  :root {
    --fs-1: 6.8rem;
    --fs-2: 4.4rem;
    --fs-3: 1.34rem;
    --fs-4: 3.7rem;
    --fs-5: 4.4rem;
    --fs-6: 3.4rem;
    --fs-7: 4.4rem;
    --fs-8: 1.3rem;
    --fs-9: 3.1rem;
    --fs-10: 3.1rem;
    --fs-11: 3.6rem;
    --fs-12: 1.6rem;
    --fs-13: 2.7rem;
    --fs-14: 1.9rem;
    --fs-15: 2.3rem;
    --fs-16: 2.7rem;
    --fs-17: 2.2rem;
    --fs-18: 1.42rem;
    --fs-19: 3.9rem;
    --fs-20: 2.6rem;
    --fs-21: 1.6rem;
  }
}

/* --- Holding together at 2x text --------------------------------------
   Found by setting the root font size to 32px and walking every page. The
   type scale above now genuinely doubles, which is the point, and doubling
   it exposed four places that could not take it. None of these are new
   faults; they were simply never reachable while headings only grew 1.37x. */

/* 1. Long words. "straightforward", "recommendations" and "automation" all
      exceed their column at 2x. Headings are the only place this bites,
      because body copy has short enough words and a wider measure -- except
      inside the narrow cards, where a five-column grid at 2x leaves a 132px
      column and "documentation" is wider than that on its own. Set on body
      and inherited, since it only breaks a word that would otherwise spill. */
body { overflow-wrap: break-word; }

/* 2. Grid and flex children default to min-width:auto, which refuses to
      shrink below their content. The five-column flow strip pushed the page
      67px sideways at 2x because of it. */
.flow-strip > *, .card-grid > *, .practice-cols > *, .record-list li > *,
.stat-band li, .split-section > * { min-width: 0; }

/* 3. The email button holds one long unbreakable address. At 2x it left the
      viewport, so it is allowed to wrap and to break the address. */
.contact-email, .button-light { overflow-wrap: anywhere; max-width: 100%; }

/* 4. The SSU monogram overflowed its own disc at 2x, because the disc was a
      fixed 46px and the glyph inside it was rem. Pinning the glyph in px
      fixed the overflow and left a tiny mark beside a doubled wordmark, so
      the disc is rem now too and the whole lockup scales as one object. The
      glyph stays at the 0.84rem floor, which fits because the disc scales
      with it -- the type-floor gate caught the 0.8rem I tried first. */


/* --- Home hero background motion ------------------------------------------
   The still and the video sit BEHIND the hero, faded in from the right with a
   mask so the headline always rests on plain page paper; the clip's own left
   half is empty paper too. No opacity or translate at rest: the still is
   visible from this stylesheet alone, and hero-media.js only swaps the video
   in once it is actually playing (it removes `hidden`). Nothing here depends
   on .js-motion, because the still must work where motion.js stands down.

   The clip's background is a slightly lighter paper than the page's, which
   showed as a hard rectangle around the media. So the layer is painted in the
   page's own --paper and the media is blended with `darken`: wherever the clip
   is lighter than the page it takes the page's colour, and only the objects and
   the lime line, which are darker, show through. No seam can remain.

   The control sits at the top of the hero, where it is on screen when motion
   starts; at the bottom of a hero taller than the viewport it was not.

   Below 820px the hero is one column and the headline would sit over the
   objects, so the media becomes a band across the top of the section that
   fades out before the copy, instead of a layer under the words. */
.hero-with-media { position: relative; isolation: isolate; }
.hero-media { position: absolute; inset: 0; z-index: -1; overflow: hidden; pointer-events: none; background: var(--paper);
  -webkit-mask-image: linear-gradient(90deg, transparent 40%, #000 72%, #000 94%, transparent 100%),
                      linear-gradient(180deg, transparent 0%, #000 14%, #000 86%, transparent 100%);
  -webkit-mask-composite: source-in;
          mask-image: linear-gradient(90deg, transparent 40%, #000 72%, #000 94%, transparent 100%),
                      linear-gradient(180deg, transparent 0%, #000 14%, #000 86%, transparent 100%);
          mask-composite: intersect; }
.hero-media-still, .hero-media-motion { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: 100% 50%; mix-blend-mode: darken; }
.hero-media-motion[hidden] { display: none; }
/* Under `darken` two stacked images both show wherever they differ, which
   doubled every object while the clip moved. The still is the fallback, so it
   steps out only while the video is actually on screen; the video comes first
   in the markup so this can be a sibling selector. */
.hero-media-motion:not([hidden]) + .hero-media-still { display: none; }
.hero-media-control { position: absolute; top: 24px; right: 0; min-height: 44px; padding: .55rem 1rem; background: var(--paper-bright); color: var(--ink); font-family: inherit; cursor: pointer; }
.hero-media-control[hidden] { display: none; }

@media (max-width: 820px) {
  .hero-with-media { padding-top: 260px; }
  .hero-media { bottom: auto; height: 320px;
    -webkit-mask-image: linear-gradient(90deg, transparent 0%, #000 6%, #000 94%, transparent 100%),
                        linear-gradient(180deg, transparent 0%, #000 12%, #000 55%, transparent 100%);
    -webkit-mask-composite: source-in;
            mask-image: linear-gradient(90deg, transparent 0%, #000 6%, #000 94%, transparent 100%),
                        linear-gradient(180deg, transparent 0%, #000 12%, #000 55%, transparent 100%);
            mask-composite: intersect; }
  .hero-media-still, .hero-media-motion { object-position: 78% 50%; }
  .hero-media-control { top: 16px; }
}

/* Apps page cards */
.plain-card > img.app-icon { display: block; width: 64px; height: 64px; margin: 0 0 18px; border-radius: 22.5%; box-shadow: 0 0 0 1px rgba(20, 34, 33, 0.08), 0 6px 16px rgba(20, 34, 33, 0.18); }
.plain-card > .tag-row { margin: 0 0 20px; }
.plain-card > ul:not(.tag-row) { margin: 0 0 6px; padding-left: 1.1rem; color: var(--ink-soft); font-size: .96rem; }
.section-dark .plain-card > ul:not(.tag-row) { color: rgba(255, 255, 255, .82); }

/* Case study hero art */
.case-hero { width: min(var(--max), calc(100% - 40px)); margin: 28px auto 0; }
.case-hero img { display: block; width: 100%; height: auto; border-radius: var(--radius); border: 1px solid var(--line); }
.case-hero + .page-hero { padding-top: clamp(40px, 6vw, 72px); }
/* Vertical rhythm between blocks on the same background. Each block used to carry
   its full padding on both sides, so two plain blocks in a row stacked to 200-290px
   of empty paper. Now the block above sets one gap and the block below adds none. */
:root { --flow-gap: var(--bc-gap); } /* site-wide compact rhythm (see the block at the end of this file) */
.page-hero + .section:not(.section-dark), .stat-band + .section:not(.section-dark), .practice-band + .section:not(.section-dark) { padding-top: 0; }
.section:not(.section-dark) + .section:not(.section-dark),
.section-dark + .section-dark { padding-top: 0; }
.section:not(.section-dark):has(+ .section:not(.section-dark)),
.section-dark:has(+ .section-dark) { padding-bottom: var(--flow-gap); }
/* Text over a full-bleed image, after the VEM site's hero. The dark variant is for
   photographs: an ink scrim from the left and the bottom carries white type. */
.image-hero { position: relative; display: flex; align-items: flex-end; min-height: min(72vh, 620px); overflow: hidden; background: var(--ink); }
.image-hero-img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.image-hero::after { content: ""; position: absolute; inset: 0; pointer-events: none; }
.image-hero-dark::after { background: linear-gradient(to right, rgba(20, 34, 33, .82) 0%, rgba(20, 34, 33, .5) 42%, rgba(20, 34, 33, 0) 72%), linear-gradient(to top, rgba(20, 34, 33, .55) 0%, rgba(20, 34, 33, 0) 50%); }
.image-hero-in { position: relative; z-index: 1; width: min(var(--max), calc(100% - 40px)); margin: 0 auto; padding: clamp(140px, 18vw, 220px) 0 clamp(48px, 7vw, 88px); }
.image-hero h1 { max-width: 20ch; font-size: var(--fs-5); line-height: 1.06; text-wrap: balance; }
.image-hero .lede { max-width: 640px; }
.image-hero-dark h1 { color: white; }
.image-hero-dark .eyebrow { color: var(--lime); }
.image-hero-dark .lede { color: rgba(255, 255, 255, .9); }
.image-hero-dark .button-primary { border-color: white; background: white; color: var(--ink); }
.image-hero-dark .button-primary:hover { border-color: var(--lime); background: var(--lime); }
.image-hero-dark .button-secondary { border-color: rgba(255, 255, 255, .6); color: white; }
.image-hero-dark .button-secondary:hover { background: rgba(255, 255, 255, .12); }
.image-hero + .stat-band { padding-top: clamp(40px, 6vw, 72px); }
@media (max-width: 700px) {
  .image-hero { min-height: 0; }
  .image-hero-in { width: min(100% - 28px, var(--max)); }
  .image-hero-dark::after { background: rgba(20, 34, 33, .64); }
}
/* The light variant is for paper drawings composed with the art on the right: a
   paper wash from the left keeps ink type readable wherever the art reaches. */
.image-hero-light { background: var(--paper); border-bottom: 1px solid var(--line); }
.image-hero-light::after { background: linear-gradient(to right, rgba(244, 241, 233, .96) 0%, rgba(244, 241, 233, .78) 38%, rgba(244, 241, 233, 0) 64%); }
@media (max-width: 700px) {
  .image-hero-light::after { background: rgba(244, 241, 233, .86); }
}
/* Infrastructure: the tower is the subject, so anchor the frame left and the
   tower clears the headline on wide screens. */
.image-hero-img.focus-right { object-position: 0% 50%; }
/* Cards of very different lengths: flow them in balanced columns instead of rows,
   so a long card does not leave a hole beside it. */
.card-grid.card-columns { display: block; column-count: 2; column-gap: 18px; }
.card-grid.card-columns > * { break-inside: avoid; margin-bottom: 18px; }
@media (max-width: 820px) { .card-grid.card-columns { column-count: 1; } }
/* Section plates: line drawings set beside long prose, in the column the prose
   leaves empty. They stay in view while the text beside them scrolls. */
.plate-row { display: grid; grid-template-columns: minmax(0, 720px) minmax(0, 1fr); gap: clamp(32px, 5vw, 72px); align-items: start; }
.plate-row > .prose-stack, .plate-row > p { margin-bottom: 0; }
.side-plate { position: sticky; top: 96px; margin: 0; }
.side-plate img { display: block; width: 100%; height: auto; border: 1px solid var(--line); border-radius: var(--radius); }
.section-dark .side-plate img { border-color: transparent; }
.side-plate.plate-left { position: static; max-width: 420px; margin-top: clamp(28px, 4vw, 44px); }
.service-row.with-plate { grid-template-columns: 110px minmax(0, 1fr) minmax(220px, .5fr); }
@media (max-width: 820px) {
  .plate-row, .service-row.with-plate { grid-template-columns: 1fr; }
  .side-plate { position: static; max-width: 520px; }
}
.service-row.with-plate > .side-plate { align-self: start; }
.side-plate.plate-tile { position: static; break-inside: avoid; margin-bottom: 18px; }
/* Text-over-image heroes carry their own art, so they need less empty paper above the type. */
.image-hero-in { padding-top: clamp(96px, 11vw, 150px); }
/* Light heroes: only the drawing is placed, in the right half at its own shape,
   so a tall block of type can never push the art under itself or crop it away. */
.image-hero-light .image-hero-img { left: auto; right: max(20px, calc((100% - var(--max)) / 2)); top: 10%; height: 80%; width: 46%; object-fit: contain; object-position: 100% 50%; }
.image-hero-light::after { display: none; }
.image-hero-light h1 { max-width: 15ch; }
.image-hero-light .lede { max-width: 540px; }
@media (max-width: 820px) {
  .image-hero-light .image-hero-img { position: static; display: block; width: 100%; height: auto; max-height: 260px; order: -1; }
  .image-hero-light { flex-direction: column; align-items: stretch; }
  .image-hero-light .image-hero-in { padding-top: 24px; }
}
/* The drawings sit on a faint grid; fade its edges so the crop never shows a line. */
.image-hero-light .image-hero-img { -webkit-mask-image: radial-gradient(ellipse at center, #000 66%, transparent 100%); mask-image: radial-gradient(ellipse at center, #000 66%, transparent 100%); }
/* App features on the apps page: what the app does, most distinctive first. */
.plain-card > ul.feature-list { margin: 4px 0 18px; padding-left: 1.1rem; }
.plain-card > ul.feature-list li { margin-bottom: 8px; line-height: 1.5; }
.plain-card > ul.feature-list li::marker { color: var(--teal); }
/* Apps/Beta polish: 44px tap targets on touch devices of any width, tags that
   wrap without turning into lopsided pills, and a gap between side-by-side links. */
@media (pointer: coarse) {
  .plain-card .text-link { min-height: 44px; display: inline-flex; align-items: center; }
}
.plain-card .text-link + .text-link { margin-left: 18px; }
.plain-card .tag { border-radius: 14px; line-height: 1.35; }
@media (max-width: 820px) { .plain-card .text-link + .text-link { margin-left: 0; margin-right: 18px; } }

/* Beta signup form */
.signup-form { display: grid; gap: 18px; max-width: 640px; }
.signup-form .field { margin: 0; padding: 0; border: 0; display: grid; gap: 6px; }
.signup-form .field-row { display: grid; gap: 18px; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); }
.signup-form label, .signup-form legend { font-weight: 700; font-size: .95rem; }
.signup-form input[type=text], .signup-form input[type=email] { width: 100%; min-height: 48px; padding: .6rem .8rem; border: 1px solid var(--ink); border-radius: 10px; background: white; color: var(--ink); font: inherit; }
.signup-form .check { display: flex; align-items: center; gap: 10px; min-height: 40px; font-weight: 500; }
.signup-form .check input { width: 20px; height: 20px; }
.signup-form .field-hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }
.form-note { max-width: 640px; font-size: .92rem; }
.form-status { font-weight: 700; }
.cf-turnstile { min-height: 65px; }

/* Beta signup form: one card, grouped choices, readable measure. */
.signup-form { max-width: 760px; padding: clamp(22px, 3.5vw, 40px); border: 1px solid var(--line); border-radius: var(--radius); background: var(--paper-bright); gap: 22px; }
.signup-form .field { gap: 8px; }
.signup-form label, .signup-form legend { font-size: 1rem; color: var(--ink); }
.signup-form legend { padding: 0; margin-bottom: 6px; }
.signup-form input[type=text], .signup-form input[type=email] { min-height: 52px; padding: .7rem .95rem; border: 1px solid rgba(20, 34, 33, .35); border-radius: 12px; background: #fff; font: inherit; color: var(--ink); }
.signup-form input[type=text]:focus, .signup-form input[type=email]:focus { outline: 3px solid var(--teal); outline-offset: 2px; border-color: var(--teal); }
.signup-form fieldset.field { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: 10px; }
.signup-form fieldset.field > legend { grid-column: 1 / -1; float: left; width: 100%; }
.signup-form fieldset .check { padding: .55rem .85rem; border: 1px solid var(--line); border-radius: 12px; background: #fff; min-height: 48px; cursor: pointer; }
.signup-form fieldset .check:has(input:checked) { border-color: var(--teal); background: rgba(11, 102, 96, .08); }
.signup-form .check input { accent-color: var(--teal); flex: 0 0 auto; }
.signup-form .button { min-width: 220px; }
.form-note { max-width: 760px; color: var(--ink-soft); line-height: 1.55; }
.form-status { max-width: 760px; padding: 14px 18px; border-radius: 12px; background: rgba(11, 102, 96, .1); font-weight: 600; }
.form-note .text-link { display: inline; }

/* Beta page: form fills the container, choices sit side by side. */
#signup .section-heading { grid-template-columns: 1fr; gap: 12px; margin-bottom: 32px; }
#signup .signup-form { max-width: none; grid-template-columns: 1fr 1fr; column-gap: 32px; }
#signup .signup-form > * { grid-column: 1 / -1; }
#signup .signup-form > fieldset.field { grid-column: auto; align-content: start; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); }
#signup .form-note { max-width: 760px; font-size: 1rem; margin-top: 18px; }
#signup .signup-form .form-note { margin: 0; }
@media (max-width: 760px) { #signup .signup-form > fieldset.field { grid-column: 1 / -1; } }

/* Beta page integration: shared headings, paper cards and quiet form controls.
   Scoped to Beta; the existing contact hero and other pages stay untouched. */
.beta-page #signup .section-heading { grid-template-columns: minmax(180px, .42fr) minmax(0, 1fr); gap: 48px; margin-bottom: 56px; }
.beta-page #signup .signup-form { padding: 30px; background: transparent; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 30px; translate: none; box-shadow: none; }
.beta-page .signup-form input[type=text], .beta-page .signup-form input[type=email] { border-color: var(--line); border-radius: calc(var(--radius) / 2); background: var(--paper-bright); }
.beta-page #signup .signup-form > fieldset.field { grid-template-columns: repeat(auto-fit, minmax(min(100%, 190px), 1fr)); gap: 8px 18px; padding-top: 22px; border-top: 1px solid var(--line); }
.beta-page .signup-form fieldset .check { min-height: 44px; padding: 0; border: 0; border-radius: 0; background: transparent; }
.beta-page .signup-form fieldset .check:has(input:checked) { background: transparent; }
.beta-page .signup-form .check { align-items: flex-start; }
.beta-page .signup-form .check input { margin: .2em 0 0; }
.beta-page .signup-form fieldset .check { align-items: center; }
.beta-page .signup-form fieldset .check input { margin: 0; }
.beta-page .signup-form .check:has(input:focus-visible) { outline: 3px solid var(--teal); outline-offset: 3px; border-radius: 3px; }
.beta-page .signup-form > p:has(> .button) { margin-bottom: 0; }
.beta-page .form-status { margin: 18px 0 0; background: var(--paper-bright); border: 1px solid var(--line); }
@media (max-width: 820px) {
  .beta-page #signup .section-heading { grid-template-columns: 1fr; gap: 12px; }
}
@media (max-width: 560px) {
  .beta-page #signup .signup-form { padding: 20px; gap: 24px; }
  .beta-page .signup-form .field-row { grid-template-columns: minmax(0, 1fr); }
  .beta-page .signup-form .button { width: 100%; min-width: 0; }
}
/* End Beta page integration. */
/* Hero centering (one rule for every hero): the text block and the art are two grid items of the same
   row, align-items:center, so their optical centers match whichever is taller. The first and last child
   of each text block carry no outer margin, so the box that is centered is the visible text. */
.hero-copy > :first-child, .contact-hero > div > :first-child, .image-hero-in > :first-child { margin-top: 0; }
.hero-copy > :last-child, .contact-hero > div > :last-child, .image-hero-in > :last-child { margin-bottom: 0; }
/* Light image heroes (Systems, Apps, Proof, Services, About): text left, drawing right, centered with each
   other. Below 821px the drawing stacks above the text (rule above). */
@media (min-width: 821px) {
  .image-hero-light.image-hero-right { display: grid; grid-template-columns: minmax(0, 1fr) clamp(280px, calc(100% - 624px), 46%); column-gap: 24px; align-items: center;
    padding: clamp(96px, 11vw, 150px) max(20px, calc((100% - var(--max)) / 2)) clamp(48px, 7vw, 88px); }
  .image-hero-right .image-hero-img { position: static; grid-column: 2; grid-row: 1; width: 100%; height: auto; }
  .image-hero-right .image-hero-in { grid-column: 1; grid-row: 1; width: auto; margin: 0; padding: 0; }
}

/* Beta: section headings stack, left-aligned, like the form beneath them. */
.beta-page .section-heading { grid-template-columns: 1fr; gap: 12px; margin-bottom: 32px; }
.beta-page #signup .section-heading { grid-template-columns: 1fr; gap: 12px; margin-bottom: 32px; }

/* Text-only page heroes (Beta, Lucid, Support, Contact): one vertical rhythm, content-driven.
   Top reuses the tight hero offset already used under a case-study image and after an image hero
   (clamp(40px, 6vw, 72px)); bottom is the block-to-block gap (--flow-gap), so hero to first section
   equals section to section. The first section adds no top padding of its own (same rule as
   .page-hero + .section), and the hero sets no min-height. Image heroes (/apps, /about) are unchanged. */
.hero-tight { min-height: 0; padding-top: clamp(40px, 6vw, 72px); padding-bottom: var(--flow-gap); }
.hero-tight + .section:not(.section-dark) { padding-top: 0; }

/* Beta page: compact vertical rhythm (2026-11-04). Scoped to .beta-page; no other page changes.
   The token set (--bc-gap, --bc-head, --bc-tight, --bc-field) is declared on :root with the same
   values so the shared .split-block layout below can reuse it. At 1440: 56 / 24 / 8 / 16; at 390:
   32 / 16 / 8 / 12. Hero look is unchanged; only its offsets shrink. */
:root {
  --bc-gap: clamp(32px, 4.5vw, 56px); /* block to block */
  --bc-head: clamp(16px, 1.7vw, 24px); /* heading to its content */
  --bc-tight: 8px; /* eyebrow to heading */
  --bc-field: clamp(12px, 1.2vw, 16px); /* rows inside a block */
}
.beta-page {
  --flow-gap: var(--bc-gap); /* the site's section-to-section rule now resolves to the compact gap here */
}
.beta-page .hero-tight { padding-top: clamp(32px, 4vw, 56px); padding-bottom: var(--bc-gap); }
.beta-page .section { padding-bottom: var(--bc-gap); }
.beta-page .section-heading, .beta-page #signup .section-heading { gap: var(--bc-tight); margin-bottom: var(--bc-head); }
.beta-page .section-heading .eyebrow { margin-bottom: 0; }
.beta-page .section-heading h2 { margin: 0; }
.beta-page .prose-stack p { margin-bottom: 12px; }
.beta-page .prose-stack ol { margin: 0; }
.beta-page .prose-stack li { margin-bottom: 6px; }
.beta-page .form-note, .beta-page #signup .form-note { margin-top: 12px; margin-bottom: 0; }
.beta-page .site-footer, .beta-page + .site-footer { min-height: 72px; }

/* How it works + Feedback: two equal columns from 900px, stacked below (How it works first).
   Gaps reuse --bc-gap (block to block) and --bc-head/--bc-tight; titles use --fs-17 (the proof-group title step). */
.beta-page .beta-duo { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--bc-gap); align-items: start; }
@media (min-width: 900px) { .beta-page .beta-duo { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.beta-page .beta-col { min-width: 0; }
.beta-page .beta-col .section-heading h2 { max-width: none; font-size: var(--fs-17); }
.beta-page .beta-col .prose-stack { max-width: none; }
/* Inline links inside beta prose must not inflate the line box (.text-link carries margin-top and min-height). */
.beta-page .prose-stack { line-height: 1.6; }
.beta-page .prose-stack .text-link { display: inline; min-height: 0; margin-top: 0; }
/* The "Prefer email?" note under the form runs the full container width; it wraps only when the screen is narrow. */
.beta-page #signup > .form-note { max-width: none; }

/* Beta cards: equal-height flex columns; the invite link row is pinned to the bottom so the links
   share one baseline across a row. Chips stay on one line (short labels; no breaks inside). */
.beta-page .card-grid .plain-card { display: flex; flex-direction: column; }
.beta-page .card-grid .plain-card > p:last-child { margin-top: auto; padding-top: 10px; }
.beta-page .plain-card .tag { white-space: nowrap; }

/* Card grid: auto-fit columns fill the container, whatever the count. */
.beta-page .card-grid { grid-template-columns: repeat(auto-fit, minmax(min(100%, 300px), 1fr)); gap: var(--bc-field); }
.beta-page .card-grid .plain-card { min-height: 0; padding: 20px 22px; }
.beta-page .plain-card > img.app-icon { margin-bottom: 10px; }
.beta-page .plain-card > .tag-row { margin-bottom: 10px; }
.beta-page .plain-card .lane-title { margin-bottom: 6px; }
.beta-page .plain-card p { margin-top: 0; margin-bottom: 10px; }
.beta-page .plain-card p:last-child { margin-bottom: 0; }
.beta-page .plain-card .text-link { min-height: 0; }

/* Form: two columns on desktop (names; devices beside apps), one column at phone width. */
.beta-page #signup .signup-form { padding: 22px; gap: var(--bc-field) 28px; }
.beta-page .signup-form .field, .beta-page #signup .signup-form .field { gap: 4px; margin: 0; }
.beta-page .signup-form .field-row { gap: var(--bc-field); align-items: end; }
.beta-page .signup-form input[type=text], .beta-page .signup-form input[type=email] { min-height: 44px; padding: .45rem .8rem; }
.beta-page .form-split { grid-column: 1 / -1; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--bc-field) 28px; align-items: start; }
.beta-page .form-col { display: grid; gap: var(--bc-field); min-width: 0; }
.beta-page .form-col > fieldset.field { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 150px), 1fr)); gap: 0 14px; padding: 0; border: 0; }
.beta-page .form-col > fieldset.field > legend { margin-bottom: 4px; }
.beta-page .signup-form fieldset .check { min-height: 38px; }
.beta-page .signup-form .cf-turnstile { min-height: 0; }
.beta-page .signup-form > p:has(> .button) { margin-top: 4px; }
@media (max-width: 760px) {
  .beta-page .form-split { grid-template-columns: 1fr; }
  .beta-page #signup .signup-form { padding: 16px; gap: 12px; }
  .beta-page .signup-form fieldset .check { min-height: 44px; }
}

/* Text-only case studies (Proof: contested outcomes; Hearing record: the three denials): kicker, title and
   lede span the full container; the two body paragraphs sit side by side; any link runs across the bottom.
   One column below 821px. */
.case-study.case-study-cols { display: block; column-count: 2; column-gap: clamp(32px, 5vw, 72px); }
.case-study.case-study-cols > .case-kicker, .case-study.case-study-cols > h2, .case-study.case-study-cols > .case-lede, .case-study.case-study-cols > .section-footnote,
.case-study.case-study-cols > .tag-row, .case-study.case-study-cols > .estimate-note { column-span: all; }
.case-study.case-study-cols h2, .case-study.case-study-cols p { max-width: none; }
.case-study.case-study-cols > p:not(.case-kicker):not(.case-lede):not(.section-footnote):not(.estimate-note) { break-inside: avoid; margin: 0 0 1.1em; }
.case-study.case-study-cols > p:not(.case-kicker):not(.case-lede):not(.section-footnote):not(.estimate-note) ~ .case-lede { margin-top: 16px; }
.case-study.case-study-cols:has(> .method-split) { column-count: 1; }
.case-study.case-study-cols > .method-split { column-span: all; }
@media (max-width: 820px) {
  .case-study.case-study-cols { column-count: 1; }
}

/* PART sections (Proof: Part one, Part two): the eyebrow and title are centered over the block below them,
   and the intro runs the full container width. Colors, bands and the blocks below are unchanged. */
.section-part > .section-heading { grid-template-columns: 1fr; justify-items: center; gap: 12px; text-align: center; }
.section-part > .section-heading .eyebrow { margin-bottom: 0; }
.section-part > .section-heading h2 { max-width: none; }
.section-part > .section-lede, .section-part > .prose-stack { max-width: none; }

/* ITEM 1, title lockup (2026-11-04): a section heading is the eyebrow at the far left with the title UNDER it,
   running the full container width on one line at tablet widths and up (it wraps below 821px, as before).
   Sizes are rem steps (the type-scale rule above: no viewport units in type); each step is the largest size at which
   the longest title on the site (72 characters) still fits one line at the container width of that range.
   Excluded: Proof's PART sections (centered, .section-part) and /beta (already stacked, compact). */
.section:not(.section-part) > .section-heading { grid-template-columns: minmax(0, 1fr); gap: 12px; }
.section:not(.section-part) > .section-heading .eyebrow { margin-bottom: 0; }
.section:not(.section-part) > .section-heading h2 { max-width: none; }
.beta-page .section > .section-heading h2 { font-size: var(--fs-2); }
@media (min-width: 821px) {
  .section:not(.section-part) > .section-heading h2, .split-section > div:first-child h2, .case-study h2, .split-head h2, .service-row h2, .system-block .block-title { font-size: 1.4rem; }
}
@media (min-width: 900px) { .section:not(.section-part) > .section-heading h2, .split-section > div:first-child h2, .case-study h2, .split-head h2, .service-row h2, .system-block .block-title { font-size: 1.55rem; } }
@media (min-width: 1000px) { .section:not(.section-part) > .section-heading h2, .split-section > div:first-child h2, .case-study h2, .split-head h2, .service-row h2, .system-block .block-title { font-size: 1.75rem; } }
@media (min-width: 1100px) { .section:not(.section-part) > .section-heading h2, .split-section > div:first-child h2, .case-study h2, .split-head h2, .service-row h2, .system-block .block-title { font-size: 1.9rem; } }
@media (min-width: 1240px) { .section:not(.section-part) > .section-heading h2, .split-section > div:first-child h2, .case-study h2, .split-head h2, .service-row h2, .system-block .block-title { font-size: 2.15rem; } }
@media (min-width: 821px) {
  .beta-page .section > .section-heading h2 { font-size: var(--fs-2); }
}

/* ITEM 2, case-study template (2026-11-04). Compact scale = the one /beta uses (--bc-gap, 56 / 32 px).
   1. Title to first paragraph: the heading no longer adds its 56px margin and the article no longer adds its own
      88px top padding when it sits directly under a section heading (was ~170px, now the 24px under the title).
   2. The article runs the full container: .case-study-cols (kicker / title / lede / chips / notes full width, body
      paragraphs in two balanced columns) is now used by the Family Care Hub study too.
   3. Chips are smaller: the type stays at the 0.84rem floor; padding, tracking and gaps shrink so they fit one row.
   4. "What is not claimed" (.section-claims, all nine case-study pages): compact padding, and the gap before the
      contact band is the same compact value. */
:root { --compact-gap: clamp(32px, 4.5vw, 56px); }
.section > .section-heading:has(+ .case-study) { margin-bottom: 0; }
.section-heading + .case-study { padding-top: 0; }
.section-heading + .case-study:last-child { padding-bottom: 0; }
.case-study .tag-row { gap: 6px 8px; margin: 0 0 24px; }
.case-study .tag { max-width: none; padding: .12rem .5rem; font-size: .84rem; letter-spacing: .05em; color: var(--teal-dark); }
.section.section-claims { padding-top: var(--compact-gap); padding-bottom: var(--compact-gap); }
.section:not(.section-dark) + .section.section-claims { padding-top: var(--compact-gap); }
.section:not(.section-dark):has(+ .section.section-claims) { padding-bottom: 0; }
.section-claims + .cta-band { margin-top: 0; }

/* ITEM 3, adjacent surfaces (2026-11-04): two neighbouring sections never share a surface. One rule, in the shared
   section component, alternating the surfaces the site already has:
     light run:  paper (the page ground) / --paper-tint (paper, one step darker) / paper / tint ...
     dark run:   ink / --teal-dark (the signal-card green) / ink
   A run starts at the first light (or dark) section after something else, so every existing paper/dark alternation
   is untouched; only pairs that used to share a surface change. Heroes and the stat / practice bands are page
   headers and keep running into the first section on paper, as before. Surfaces that meet get the band padding
   (--band-pad) instead of the collapsed same-surface gap. Contrast: ink 13.3:1, ink-soft 8.6:1, teal 5.5:1 on the
   tint; white 11.8:1 and lime 8.5:1 on teal-dark. */
:root { --paper-tint: #ece7da; --band-pad: calc(var(--flow-gap) * .55); }
.section:not(.section-dark):has(+ .section:not(.section-dark)) { padding-bottom: var(--band-pad); }
.section:not(.section-dark) + .section:not(.section-dark) { padding-top: var(--band-pad); padding-bottom: var(--band-pad); background: var(--paper-tint); }
.section:not(.section-dark) + .section:not(.section-dark) + .section:not(.section-dark) { padding-top: var(--band-pad); padding-bottom: var(--band-pad); background: transparent; }
.section:not(.section-dark) + .section:not(.section-dark) + .section:not(.section-dark) + .section:not(.section-dark) { padding-top: var(--band-pad); padding-bottom: var(--band-pad); background: var(--paper-tint); }
.section:not(.section-dark) + .section:not(.section-dark) + .section:not(.section-dark) + .section:not(.section-dark) + .section:not(.section-dark) { padding-top: var(--band-pad); padding-bottom: var(--band-pad); background: transparent; }
.section:not(.section-dark) + .section:not(.section-dark) + .section:not(.section-dark) + .section:not(.section-dark) + .section:not(.section-dark) + .section:not(.section-dark) { padding-top: var(--band-pad); padding-bottom: var(--band-pad); background: var(--paper-tint); }
.section-dark + .section-dark { padding-top: var(--band-pad); background: var(--teal-dark); }
.section-dark + .section-dark + .section-dark { background: var(--ink); }
.section-dark:has(+ .section-dark) { padding-bottom: var(--band-pad); }
.section-claims + .cta-band { margin-top: 16px; }

/* ITEM 4, CTA band (2026-11-04): the headline gets the whole row (the old 720px cap wrapped every one at the
   56px display size, two or three lines at 1440 beside a pill that sat far to the right), the pill keeps its size
   on the right and is centered on the headline row (the eyebrow sits above that row). One line from 1100px up for every headline up to about
   60 characters; the longer apps sentence and the 821-1099px range may wrap (balanced); the band stacks below 821px
   as before. Sizes are rem steps, one step below the old display size, per the type-scale rule. */
.cta-band > div { flex: 1 1 auto; min-width: 0; }
.cta-band h2 { max-width: none; text-wrap: balance; }
.cta-band .button { flex: none; white-space: nowrap; }
@media (min-width: 821px) {
  .cta-band { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; gap: 0 30px; padding-inline: clamp(28px, 4.5vw, 56px); }
  .cta-band > div { display: contents; }
  .cta-band .eyebrow { grid-area: 1 / 1; }
  .cta-band h2 { grid-area: 2 / 1; font-size: 1.45rem; }
  .cta-band .button { grid-area: 2 / 2; }
}
@media (min-width: 1100px) { .cta-band h2 { font-size: 1.55rem; } }
@media (min-width: 1240px) { .cta-band h2 { font-size: 1.8rem; } }
/* Shared section layout (2026-11-04): .split-block. Opt-in, used on /about only for now; the older
   .split-section is untouched. Eyebrow and title (.split-head) span the full width on top; below,
   a 50/50 row holds the image (.split-media) and the prose (.split-body), top-aligned.
   .split-block--reverse puts the image on the right. DOM order is head, image, prose, so a stacked
   layout reads title, image, prose. With no image the prose takes one column at a reading measure.
   Spacing reuses the compact tokens on :root. Each block also takes one surface so neighbours read
   as separate sections: .surface-paper (the page ground), .surface-grid (paper with a 28px
   dark-green grid at 8%), .surface-deep (--teal-dark, white type). */
.split-block { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); grid-auto-flow: row dense; column-gap: clamp(32px, 5vw, 72px); row-gap: var(--bc-head); align-items: start; padding: var(--bc-gap) max(20px, calc((100% - var(--max)) / 2)); border-top: 1px solid var(--line); }
.section:not(.section-dark):has(+ .split-block) { padding-bottom: var(--bc-gap); }
.split-block > * { grid-column: 1 / -1; min-width: 0; }
.split-block > .split-head { margin: 0; }
.split-head .eyebrow { margin: 0 0 var(--bc-tight); }
.split-head h2 { margin: 0; text-wrap: balance; }
.split-block > .split-media { grid-column: 1; position: static; max-width: 460px; margin: 0; }
.split-block > .split-body { grid-column: 2; max-width: 68ch; margin: 0; }
.split-block > .split-media, .split-block > .split-body { align-self: center; }
.split-block--reverse > .split-media { grid-column: 2; justify-self: end; }
.split-block--reverse > .split-body { grid-column: 1; }
.split-block:not(:has(> .split-media)) > .split-body { grid-column: 1; max-width: 70ch; }
.split-body > p { margin-bottom: 12px; }
.split-body > :last-child { margin-bottom: 0; }
.surface-paper { background: var(--paper); }
.surface-grid { background-color: var(--paper); background-image: repeating-linear-gradient(0deg, rgba(7, 63, 60, .08) 0 1px, transparent 1px 28px), repeating-linear-gradient(90deg, rgba(7, 63, 60, .08) 0 1px, transparent 1px 28px); }
.surface-deep { background: var(--teal-dark); color: #fff; border-top-color: rgba(255, 255, 255, .2); }
.surface-deep .eyebrow { color: var(--lime); }
.surface-deep .prose-stack { color: rgba(255, 255, 255, .88); }
.surface-deep a { color: var(--lime); }
.surface-deep a:focus-visible { outline-color: var(--lime); }
@media (max-width: 720px) {
  .split-block { grid-template-columns: minmax(0, 1fr); }
  .split-block > .split-media, .split-block--reverse > .split-media { grid-column: 1; position: static; max-width: 520px; justify-self: start; }
  .split-block > .split-body, .split-block--reverse > .split-body { grid-column: 1; max-width: none; }
}

/* Audit fixes (a11y A01, A07).
   A01: .signup-form sets display:grid, which beats the UA [hidden] rule, so a
   hidden form stayed visible. The status line lives after the form and stays
   mounted; when empty it takes no space. */
.signup-form[hidden] { display: none; }
#beta-status:empty { padding: 0; margin: 0; border: 0; background: none; }

/* A07: standalone links and nav reach a 44 x 44 target at every width.
   Links inside a sentence stay inline (.form-note and unclassed prose links). */
nav a, .text-link, .contact-email, .tag-link, .site-footer a { min-height: 44px; min-width: 44px; display: inline-flex; align-items: center; }
.form-note .text-link { display: inline; min-height: 0; min-width: 0; }
.site-footer p:has(> a) { display: flex; flex-wrap: wrap; align-items: center; gap: 0 10px; }

/* SITE-WIDE COMPACT RHYTHM (2026-11-04). The approved /beta scale, promoted to every page. Spacing only: type, colour,
   textures, section variety, image sizes and layouts are untouched. Tokens live on :root (declared in the /beta block):
   --bc-gap block to block / section padding (56 at 1440, 32 at 390), --bc-head heading to content (24 / 16),
   --bc-tight eyebrow to heading (8), --bc-field grid gaps (16 / 12); --band-pad (derived, ~31 / 18) where two
   different surfaces meet; --flow-gap = --bc-gap. This block is last so it wins over the older, looser values above. */

/* Section frame, eyebrow > title > lede > content */
.section { padding-top: var(--bc-gap); padding-bottom: var(--bc-gap); }
.eyebrow, .card-label { margin-bottom: var(--bc-tight); }
h2 { margin-bottom: var(--bc-head); }
.section-heading, .section-part > .section-heading, .section:not(.section-part) > .section-heading { gap: var(--bc-tight); margin-bottom: var(--bc-head); }
.section-heading h2 { margin: 0; }
.section-heading:has(+ .section-lede) { margin-bottom: 12px; }
.section-lede { margin: 0 0 var(--bc-head); }
.section-footnote { margin-top: var(--bc-head); }
.prose-stack p { margin-bottom: 12px; }
.prose-stack > :last-child { margin-bottom: 0; }
.text-link { margin-top: 12px; }
.band-note { margin-top: 12px; }

/* Heroes: nav to eyebrow, and the bottom, on the same scale as the /beta hero */
.hero, .contact-hero { padding-top: clamp(32px, 4vw, 56px); padding-bottom: var(--bc-gap); }
.page-hero { padding-top: clamp(32px, 4vw, 56px); padding-bottom: var(--bc-gap); }
.case-hero + .page-hero { padding-top: clamp(32px, 4vw, 56px); }
.case-hero { margin-top: var(--bc-head); }
.hero-tight { padding-top: clamp(32px, 4vw, 56px); padding-bottom: var(--bc-gap); }
.image-hero { min-height: 0; }
.image-hero-in { padding-top: clamp(40px, 5vw, 64px); padding-bottom: var(--bc-gap); }
h1 { margin-bottom: var(--bc-head); }
.lede { margin-bottom: var(--bc-head); }
.hero-copy .tag-row { margin-top: var(--bc-head); }
.tag-row { margin-top: var(--bc-head); }
.image-hero + .stat-band { padding-top: var(--bc-gap); }
@media (min-width: 821px) {
  .image-hero-light.image-hero-right { padding-top: clamp(32px, 4vw, 56px); padding-bottom: var(--bc-gap); }
}
@media (max-width: 560px) {
  .hero, .contact-hero { padding-top: clamp(32px, 4vw, 56px); }
}

/* Bands, stats, practice columns */
.stat-band { padding-bottom: var(--bc-gap); }
.stat-band li { padding: var(--bc-field) 0; }
.practice-band { padding-bottom: var(--bc-gap); }
.practice-spine { margin-bottom: var(--bc-head); }
.practice-col { padding-top: var(--bc-head); }
.practice-years { margin-bottom: var(--bc-head); }
.practice-merge { height: var(--bc-gap); }
@media (max-width: 820px) { .practice-merge { height: var(--bc-gap); } }
.proof-group { margin-top: var(--bc-gap); }
.proof-group h3.pg-title { margin-bottom: var(--bc-head); }
.lane-group + .lane-group { margin-top: var(--bc-gap); }
.lane-both { margin-top: var(--bc-gap); }
.flow-num { margin-bottom: var(--bc-field); }
.flow-strip { gap: var(--bc-field); }

/* Cards and grids */
.card-grid { gap: var(--bc-field); }
.service-card, .plain-card { min-height: 0; padding: 20px 22px; }
.card-grid-five .plain-card { min-height: 0; padding: 20px 22px; }
.card-number { margin-bottom: var(--bc-head); }
@media (max-width: 820px) { .service-card { min-height: 0; } .card-number { margin-bottom: var(--bc-head); } }
.plain-card > img.app-icon { margin-bottom: 10px; }
.plain-card > .tag-row { margin-bottom: 10px; }
.proof-card h3 { margin-bottom: 12px; }
.section.service-list { padding-top: var(--bc-gap); }
.service-row { padding: var(--bc-head) 0; }
.insight-list li, .record-list li { padding-top: var(--bc-head); padding-bottom: var(--bc-head); }
@media (max-width: 820px) { .insight-list li, .record-list li { padding-top: var(--bc-head); padding-bottom: var(--bc-head); } }
.system-block h2, .system-block .block-title { margin-bottom: var(--bc-head); }
.system-block .mini-label { margin-top: var(--bc-head); }
.system-block div p.continuity-note { margin-top: var(--bc-head); }
.service-row p.continuity-note { margin-top: var(--bc-field); }
.method-map, .evidence-table { margin-top: var(--bc-head); }
.estimate-note { margin-top: var(--bc-head); }

/* Case studies (proof and case-study pages) */
.case-study { padding-top: var(--band-pad); padding-bottom: var(--band-pad); }
.case-study .case-kicker { margin-bottom: var(--bc-tight); }
.case-study h2 { margin-bottom: var(--bc-head); }
.case-study .tag-row { margin-bottom: var(--bc-head); }
.section-heading + .case-study { padding-top: 0; }
.case-study.case-study-cols > p:not(.case-kicker):not(.case-lede):not(.section-footnote):not(.estimate-note) { margin-bottom: 12px; }
.case-study h2 { max-width: none; }
.case-study.case-study-cols > .method-map, .case-study.case-study-cols > .evidence-table, .case-study.case-study-cols > .plate-row { column-span: all; }
.plate-row { gap: clamp(32px, 5vw, 72px); }
.plate-row .case-lede { margin-bottom: 12px; }

/* Closing band and footer */
.cta-band { margin: var(--bc-head) auto var(--bc-gap); padding-top: var(--bc-gap); padding-bottom: var(--bc-gap); }
.section-claims + .cta-band { margin-top: var(--bc-head); }
.site-footer { min-height: 72px; }

/* Title above, content below: the left-cell-title + right-cell-prose pattern (.split-section) now uses the same
   lockup as .section-heading and .split-block. Eyebrow and title run the full container (one line at tablet and up,
   same fluid sizes as every other title); prose follows beneath, in two balanced columns when there are two or more
   paragraphs, otherwise at one reading measure. */
.split-section { grid-template-columns: minmax(0, 1fr); gap: 0; }
.split-section > div:first-child { display: contents; }
.split-section > * { grid-column: 1; }
.split-section > div:first-child > .eyebrow { margin: 0 0 var(--bc-tight); }
.split-section > div:first-child > h2 { margin: 0 0 var(--bc-head); max-width: none; }
.split-section > .prose-stack { max-width: 78ch; }
.split-section > .section-footnote { margin-top: var(--bc-head); }
@media (min-width: 821px) {
  .split-section > .prose-stack:has(> p:nth-of-type(2)) { max-width: none; column-count: 2; column-gap: clamp(32px, 5vw, 72px); }
  .split-section > .prose-stack blockquote, .split-section > .prose-stack .estimate-note, .split-section > .prose-stack .section-footnote { break-inside: avoid; }
  .prose-stack > p, .prose-stack > ul, .prose-stack > ol { break-inside: avoid; }
  .split-block:not(:has(> .split-media)) > .split-body:has(> p:nth-of-type(2)) { grid-column: 1 / -1; max-width: none; column-count: 2; column-gap: clamp(32px, 5vw, 72px); }
  .split-block > .split-body > blockquote, .split-block > .split-body > .estimate-note { break-inside: avoid; }
}
.split-block:not(:has(> .split-media)) > .split-body { grid-column: 1 / -1; max-width: 78ch; }
.split-block > .split-media img { display: block; width: 100%; height: auto; }

/* Full-width measure (2026-11-04): a title that now runs across the container is followed by prose that runs across it
   too, in two balanced columns, instead of a 720px column with the right half of the page empty. Applies from 821px; one
   column below. Single-paragraph prose keeps its reading measure. */
@media (min-width: 821px) {
  .section > .prose-stack:has(> p:nth-of-type(2)) { max-width: none; column-count: 2; column-gap: clamp(32px, 5vw, 72px); }
  .section > .prose-stack > h3, .section > .prose-stack > blockquote, .section > .prose-stack > .estimate-note, .section > .prose-stack > ul, .section > .prose-stack > ol, .section > .prose-stack > table { break-inside: avoid; }
  .section > .prose-stack > .estimate-note { column-span: all; }
}
/* Service rows without a plate (Services, Systems): number, then the content using the full row. */
@media (min-width: 1000px) {
  .service-row:not(.with-plate):not(.system-block) > div { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); column-gap: clamp(32px, 5vw, 72px); align-items: start; }
  .service-row:not(.with-plate):not(.system-block) > div > h2 { grid-column: 1 / -1; }
  .service-row:not(.with-plate):not(.system-block) > div > p { max-width: none; }
  .service-row:not(.with-plate):not(.system-block) > div > p.continuity-note { margin-top: 0; }
  .service-row.system-block:not(.with-plate) > div { column-count: 2; column-gap: clamp(32px, 5vw, 72px); }
  .service-row.system-block:not(.with-plate) > div > .block-title { column-span: all; }
  .service-row.system-block:not(.with-plate) > div > .mini-label { break-after: avoid; }
  .service-row.system-block:not(.with-plate) > div > p { max-width: none; }
  .service-row.system-block:not(.with-plate) > div > p.continuity-note { column-span: all; max-width: none; margin-top: var(--bc-head); }
}

/* Image heroes with the drawing beside the text (About, Services, Systems, Apps, Proof): the title shares a column with
   the art, so it takes one step down on the fluid scale (3.4rem cap) and runs at most three lines. Same type family,
   colour and weight. */
@media (min-width: 821px) {
  .image-hero-right h1 { max-width: none; font-size: min(var(--fs-5), 3.4rem); }
}
@media (max-width: 820px) {
  .hero, .contact-hero { row-gap: var(--bc-gap); }
}
.section > .prose-stack:not(:last-child), .section > .section-lede:not(:last-child) { margin-bottom: var(--bc-head); }
.section:not(.split-section) > .prose-stack:not(:first-child), .section > .section-footnote:not(:first-child) { margin-top: var(--bc-head); }
.method-map + .prose-stack, .card-grid + .prose-stack, .plate-row + .prose-stack, .method-map + .case-lede { margin-top: var(--bc-head); }
.flow-strip + .service-row { margin-top: var(--bc-head); }
.quality-bar { margin-bottom: 12px; }
.split-section .quality-bar:last-child, .split-body .quality-bar:last-child { margin-bottom: 0; }

/* Estimate notes run the full container width, wherever they sit (Josh 2026-11-04). */
.estimate-note, .case-study > .estimate-note, .prose-stack > .estimate-note, .split-body > .estimate-note { max-width: none; width: 100%; box-sizing: border-box; }

/* Mapped-to-the-method rows (Josh 2026-11-04): prose left and plate right, vertically centred with each
   other; the white 'Mapped to the method' box runs full width across the bottom of the band. */
@media (min-width: 901px) {
  .method-split > .method-aside { display: contents; }
  .method-split > :first-child { grid-column: 1; grid-row: 1; align-self: center; }
  .method-split .side-plate, .method-split .method-aside > .side-plate { grid-column: 2; grid-row: 1; align-self: center; max-width: none; width: 100%; margin: 0; }
  .method-split > .method-map, .method-split .method-aside > .method-map { grid-column: 1 / -1; grid-row: 2; width: 100%; box-sizing: border-box; }
  .method-split:not(:has(.side-plate)) > :first-child { grid-column: 1 / -1; }
}

/* Services: the "both practices" callout spans the full container (Josh 2026-11-04). */
.lane-both { max-width: none; width: 100%; box-sizing: border-box; }

/* Links inside running text stay plain inline links so they never open a gap in their line. */
.text-link.text-link-inline { display: inline; min-height: 0; margin-top: 0; }

/* Numbered step tiles (Services "A useful engagement"): a lime number sits beside each tile title (Josh 2026-11-04). */
.step-cards { counter-reset: step; }
.step-cards > .plain-card { counter-increment: step; }
.step-cards > .plain-card > h3 { display: flex; align-items: baseline; gap: .55em; }
.step-cards > .plain-card > h3::before { content: counter(step); color: var(--lime); font-weight: 800; font-variant-numeric: tabular-nums; }

/* Flow-step tiles: the step number sits in line with the tile title (Josh 2026-11-04). */
.flow-step { display: grid; grid-template-columns: auto minmax(0, 1fr); column-gap: .6em; align-items: baseline; align-content: start; }
.flow-step > .flow-num { grid-column: 1; grid-row: 1; margin: 0; }
.flow-step > h3 { grid-column: 2; grid-row: 1; margin: 0; }
.flow-step > :not(.flow-num):not(h3) { grid-column: 1 / -1; }
.flow-step > h3 + * { margin-top: var(--bc-field, 12px); }

/* Flow-step tiles, redesigned (Josh 2026-11-04: titles broke awkwardly in six narrow columns).
   Six steps now sit in a 3 x 2 grid so each tile is wide enough for its title on one line; the step number
   is a small rounded badge beside the title; titles balance and descriptions avoid one-word last lines. */
@media (min-width: 821px) {
  .flow-strip.flow-six { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
@media (min-width: 821px) and (max-width: 1000px) {
  .flow-strip.flow-six { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
.flow-step { column-gap: 12px; padding: 20px 22px 22px; }
.flow-step > .flow-num { display: inline-grid; place-items: center; min-width: 34px; height: 28px; padding: 0 8px; border-radius: 999px; background: rgba(11, 102, 96, .12); color: var(--teal-dark); font-size: .84rem; letter-spacing: .08em; }
.flow-step > h3 { text-wrap: balance; line-height: 1.2; }
.flow-step > h3 + p { text-wrap: pretty; }
.section-dark .flow-step > .flow-num { background: rgba(204, 230, 106, .16); color: var(--lime); }

/* .surface-grid must beat the adjacent-sibling tint rule (.section:not(.section-dark) + .section:not(.section-dark))
   on ordinary .section elements; it lost to it before (Systems 02 and Contact). */
.section:not(.section-dark).surface-grid,
.section:not(.section-dark) + .section:not(.section-dark).surface-grid {
  background-color: var(--paper);
  background-image: repeating-linear-gradient(0deg, rgba(7, 63, 60, .08) 0 1px, transparent 1px 28px), repeating-linear-gradient(90deg, rgba(7, 63, 60, .08) 0 1px, transparent 1px 28px);
}

/* Apps page, dark "In development" band (Josh 2026-11-04): readable category labels on the dark ground,
   and each app card's link row pinned to the bottom so the links line up across a row of cards. */
.section-dark .plain-card .card-label { color: var(--lime); opacity: .9; }
.plain-card:has(> .app-icon) { display: flex; flex-direction: column; }
.plain-card:has(> .app-icon) > p:last-child { margin-top: auto; padding-top: 14px; }

/* Graph-paper band for a case study that sits inside the page container (Proof "Influence", Josh 2026-11-04):
   the grid is drawn on a full-viewport-width layer behind the article so it reads as a full-bleed band. */
.case-study.band-grid { position: relative; isolation: isolate; border-top-color: transparent; }
.case-study.band-grid::before { content: ""; position: absolute; z-index: -1; top: 0; bottom: 0; left: 50%; width: 100vw; transform: translateX(-50%); background-color: var(--paper); background-image: repeating-linear-gradient(0deg, rgba(7, 63, 60, .08) 0 1px, transparent 1px 28px), repeating-linear-gradient(90deg, rgba(7, 63, 60, .08) 0 1px, transparent 1px 28px); }
main { overflow-x: clip; }

/* Dark green band for a case study that sits inside the page container (Proof "317 packages", Josh 2026-11-04):
   full-viewport dark layer behind the article, light type on it; the white cards inside keep their own look. */
.case-study.band-deep { position: relative; isolation: isolate; border-top-color: transparent; color: rgba(255, 255, 255, .9); }
.case-study.band-deep::before { content: ""; position: absolute; z-index: -1; top: 0; bottom: 0; left: 50%; width: 100vw; transform: translateX(-50%); background: var(--ink); }
.case-study.band-deep .case-kicker { color: var(--lime); }
.case-study.band-deep h2, .case-study.band-deep .case-lede, .case-study.band-deep strong { color: #fff; }
.case-study.band-deep .text-link { color: var(--lime); }
.case-study.band-deep .evidence-table, .case-study.band-deep .evidence-table th, .case-study.band-deep .evidence-table td { color: rgba(255, 255, 255, .9); border-color: rgba(255, 255, 255, .22); }
.case-study.band-deep .evidence-table th { color: var(--lime); }
.case-study.band-deep .estimate-note, .case-study.band-deep .method-map { color: var(--ink); }
.case-study.band-deep .estimate-note strong, .case-study.band-deep .method-map strong { color: var(--ink); }
.case-study.band-deep .estimate-note strong { color: var(--teal-dark); }
.case-study.band-deep :is(p, li, td, caption, figcaption, span) { color: rgba(255, 255, 255, .92); }
.case-study.band-deep :is(.method-map, .estimate-note, .side-plate) :is(p, li, span, strong, figcaption) { color: var(--ink); }
.case-study.band-deep .estimate-note strong, .case-study.band-deep .method-map .mini-label { color: var(--teal-dark); }
.case-study.band-deep .case-kicker { color: var(--lime); }
.case-study.band-deep .evidence-table th { color: var(--lime); }
.case-study.band-deep p > strong { color: var(--lime); }
.case-study.band-deep :is(.method-map, .estimate-note, .side-plate) p > strong, .case-study.band-deep .method-map li > strong { color: var(--ink); }
.case-study.band-deep .estimate-note strong { color: var(--teal-dark); }

/* Home "two areas of work" band on dark green, full width (Josh 2026-11-04). */
.practice-band.band-ink { position: relative; isolation: isolate; padding-top: clamp(40px, 5vw, 64px); color: rgba(255, 255, 255, .9); }
.practice-band.band-ink::before { content: ""; position: absolute; z-index: -1; top: 0; bottom: 0; left: 50%; width: 100vw; transform: translateX(-50%); background: var(--ink); }
.band-ink .practice-spine, .band-ink .practice-col .stat-figure { color: #fff; }
.band-ink .practice-spine span, .band-ink .practice-label { color: var(--lime); }
.band-ink .practice-years, .band-ink .practice-col .stat-label, .band-ink .band-note { color: rgba(255, 255, 255, .84); }
.band-ink .text-link { color: var(--lime); }
.band-ink .practice-cols, .band-ink .practice-col + .practice-col { border-color: rgba(255, 255, 255, .24); }
.band-ink .practice-merge::before { border-color: rgba(255, 255, 255, .24); }
.band-ink .practice-merge::after { background: rgba(255, 255, 255, .24); }
.band-ink .lane-both { color: var(--ink); }
.band-ink .lane-both .text-link { color: var(--teal-dark); }
@media (max-width: 820px) { .band-ink .practice-col + .practice-col { border-top-color: rgba(255, 255, 255, .24); } }

/* Home stat grid: the closing cell is a plain link, level with the label row of its neighbour (Josh 2026-11-04). */
.practice-col li.practice-link { align-self: end; }
.practice-col li.practice-link .text-link { margin-top: 0; }

/* Two balanced prose columns (Home "Context first. Tools second."): explicit columns instead of CSS column flow,
   so the two halves are close in height; the link sits below, spanning both. */
.split-section > .prose-stack.prose-duo { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); column-count: auto; column-gap: clamp(32px, 5vw, 72px); row-gap: var(--bc-head, 16px); max-width: none; }
.prose-duo > div > p { margin: 0 0 12px; }
.prose-duo > div > p:last-child { margin-bottom: 0; }
.prose-duo > .section-footnote { grid-column: 1 / -1; margin: 0; }
@media (max-width: 820px) { .split-section > .prose-stack.prose-duo { grid-template-columns: minmax(0, 1fr); } }

/* WriteNudge product page (Josh 2026-11-04: "boring, not polished"): a larger hero with the icon and an
   illustrated tracked change, then the numbered dark band, graph-paper privacy and the join section. */
.wn-hero { width: min(var(--max), calc(100% - 40px)); margin: 0 auto; display: grid; grid-template-columns: minmax(0, 1.1fr) minmax(0, .9fr); gap: clamp(32px, 6vw, 88px); align-items: center; padding-top: clamp(40px, 6vw, 72px); padding-bottom: clamp(40px, 5vw, 64px); }
.wn-hero h1 { font-size: var(--fs-5); letter-spacing: -.03em; line-height: 1; margin: 0 0 18px; }
.wn-hero .lede { max-width: 34ch; }
.wn-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 12px 22px; margin-top: 22px; }
.wn-stage { position: relative; padding-top: 52px; }
.wn-icon { position: absolute; top: 0; left: 24px; width: 104px; height: 104px; border-radius: 23%; box-shadow: 0 14px 32px rgba(20, 34, 33, .22), 0 0 0 1px rgba(20, 34, 33, .08); z-index: 2; }
.wn-demo { margin: 0; padding: 72px 28px 24px; background: var(--paper-bright); border: 1px solid var(--line); border-radius: var(--radius); box-shadow: 0 18px 44px rgba(20, 34, 33, .1); }
.wn-sentence { margin: 0 0 18px; font-family: Georgia, "Times New Roman", serif; font-size: var(--fs-20); line-height: 1.5; color: var(--ink); }
.wn-sentence del { color: #b3563a; text-decoration-thickness: 2px; }
.wn-sentence ins { background: rgba(204, 230, 106, .55); color: var(--teal-dark); text-decoration: none; padding: 0 .18em; border-radius: 4px; }
.wn-choice { display: flex; gap: 10px; margin: 0 0 14px; }
.wn-pill { display: inline-flex; align-items: center; min-height: 36px; padding: 0 16px; border-radius: 999px; font-size: .9rem; font-weight: 800; }
.wn-accept { background: var(--teal-dark); color: #fff; }
.wn-reject { border: 1.5px solid var(--line); color: var(--ink-soft); }
.wn-demo figcaption { color: var(--ink-soft); font-size: .86rem; }
.wn-points { display: flex; flex-wrap: wrap; gap: 10px; margin: 18px 0; padding: 0; list-style: none; }
.wn-points li { padding: 9px 16px; border: 1px solid var(--line); border-radius: 999px; background: var(--paper-bright); font-weight: 700; font-size: .95rem; }
@media (max-width: 860px) { .wn-hero { grid-template-columns: minmax(0, 1fr); } .wn-stage { max-width: 520px; } }
.wn-hero-copy { min-width: 0; }
.wn-bubble { margin: 0 0 14px; padding: 14px 18px; border-radius: 18px; font-size: var(--fs-18); line-height: 1.45; max-width: 88%; }
.wn-ask { background: rgba(11, 102, 96, .1); color: var(--teal-dark); font-weight: 800; }
.wn-answer { margin-left: auto; background: var(--ink); color: #fff; border-bottom-right-radius: 6px; }
.wn-answer strong { color: var(--lime); }

/* Contact hero: the inquiry-area tags are tighter so the column ends level with the contact card (Josh 2026-11-04). */
.contact-hero .tag-row { gap: 8px; }
.contact-hero .tag-row .tag { padding: .18rem .6rem; letter-spacing: .04em; }
@media (min-width: 861px) { .contact-hero > .contact-card { align-self: end; margin-bottom: 18px; } }

/* QA fixes (2026-11-05 audit): focus visible on the dark bands, list markers on dark cards, resting input borders. */
.band-ink a:focus-visible, .band-ink button:focus-visible, .band-deep a:focus-visible, .band-deep button:focus-visible { outline-color: var(--lime); }
.band-ink .lane-both a:focus-visible, .band-deep .method-map a:focus-visible, .band-deep .estimate-note a:focus-visible { outline-color: var(--ink); }
.section-dark .plain-card > ul.feature-list li::marker { color: var(--lime); }
.signup-form input[type=text], .signup-form input[type=email] { border-color: var(--teal); }


/* S11: finish the full-container intros on case-study and long-form pages.
   Long bodies already use the shared split-section / prose column rules, with
   break-inside: avoid on paragraphs; Proof titles reuse case-study-cols.
   Only opted-in prose loses its remaining single-paragraph reading cap. */
.prose-stack.prose-full, .section-lede.prose-full { max-width: none; }
/* The existing inline rule resets display, height and top margin; clear the
   standalone link width floor too, including when a link wraps. */
.text-link.text-link-inline { min-width: 0; }
