/* ══════════════════════════════════════════════════════════════════════════
   Eugene Farber — Personal site
   Design: Brand | Vibe: Clinical Precision (warm-paper variant) | Layout:
   Ledger + Alternating Split | Color: Restrained, single copper accent

   Token architecture follows a two-layer model: primitives (raw values) feed
   semantic schemes (background/text/accent/border as a set). A section opts
   into a scheme by class, never by hardcoding a colour.
   ══════════════════════════════════════════════════════════════════════════ */

/* ── Layer 1: primitives ──────────────────────────────────────────────── */
:root {
  /* Warm paper — neutrals tinted toward hue 80, never pure grey */
  --paper-lightest: oklch(98.5% 0.005 80);
  --paper-lighter: oklch(96.5% 0.008 79);
  --paper-light:   oklch(94.5% 0.012 78);
  --paper:         oklch(90%   0.014 78);
  --paper-dark:    oklch(78%   0.016 78);

  /* Blue slate — structural darks, tinted, never #000 */
  --slate-darkest: oklch(15% 0.016 250);
  --slate-darker:  oklch(18% 0.018 250);
  --slate-dark:    oklch(21% 0.020 250);
  --slate:         oklch(34% 0.020 250);
  --slate-mid:     oklch(45% 0.018 250);
  --slate-light:   oklch(62% 0.016 250);
  --slate-lighter: oklch(74% 0.014 250);

  /* Copper — the single accent */
  --copper-lightest: oklch(95% 0.022 58);
  --copper-lighter:  oklch(88% 0.050 58);
  --copper-light:    oklch(74% 0.100 58);
  --copper:          oklch(56% 0.120 58);
  --copper-dark:     oklch(44% 0.105 58);
  --copper-darkest:  oklch(30% 0.075 58);

  /* Type scale — 1.25 ratio throughout. Flat scales read as uncommitted. */
  --step--2: 0.75rem;
  --step--1: 0.875rem;
  --step-0:  1rem;
  --step-1:  1.25rem;
  --step-2:  1.5625rem;
  --step-3:  1.953rem;
  --step-4:  2.441rem;
  --step-5:  3.052rem;
  --step-6:  3.815rem;
  --step-7:  4.768rem;

  /* Spacing — several values, used deliberately for rhythm */
  --space-1: 0.25rem;
  --space-2: 0.5rem;
  --space-3: 0.75rem;
  --space-4: 1rem;
  --space-5: 1.5rem;
  --space-6: 2rem;
  --space-7: 2.5rem;
  --space-8: 3.5rem;
  --space-9: 4.5rem;
  --space-10: 5.5rem;
  --space-11: 6.5rem;
  --space-12: 8rem;

  /* Motion — one curve, exponential out. No bounce, no elastic, no linear. */
  --ease: cubic-bezier(0.32, 0.72, 0, 1);
  --dur-fast: 180ms;
  --dur: 320ms;
  --dur-slow: 720ms;

  --radius-sm: 0.375rem;
  --radius: 0.625rem;
  --radius-lg: 1rem;
  --radius-pill: 999px;

  --rule: 1px;
  --shell: 74rem;
  --shell-wide: 84rem;
}

/* ── Layer 2: semantic schemes ────────────────────────────────────────── */
.scheme-paper {
  --bg: var(--paper-lightest);
  --bg-raised: oklch(99.2% 0.004 80);
  --text: oklch(19% 0.016 250);
  --text-soft: var(--slate-mid);
  --text-faint: var(--slate-light);
  --accent: var(--copper);
  --accent-text: var(--copper-dark);
  --border: oklch(19% 0.016 250 / 0.14);
  --border-strong: oklch(19% 0.016 250 / 0.28);
  --shadow: 0 1px 2px oklch(19% 0.016 250 / 0.05),
            0 12px 32px -12px oklch(19% 0.016 250 / 0.14);
}

.scheme-sand {
  --bg: var(--paper-light);
  --bg-raised: oklch(97.5% 0.007 79);
  --text: oklch(19% 0.016 250);
  --text-soft: var(--slate-mid);
  --text-faint: var(--slate-light);
  --accent: var(--copper);
  --accent-text: var(--copper-dark);
  --border: oklch(19% 0.016 250 / 0.16);
  --border-strong: oklch(19% 0.016 250 / 0.30);
  --shadow: 0 1px 2px oklch(19% 0.016 250 / 0.06),
            0 14px 36px -14px oklch(19% 0.016 250 / 0.18);
}

.scheme-slate {
  --bg: var(--slate-dark);
  --bg-raised: var(--slate-darker);
  --text: oklch(96% 0.008 80);
  --text-soft: var(--slate-lighter);
  --text-faint: var(--slate-light);
  --accent: var(--copper-light);
  --accent-text: var(--copper-light);
  --border: oklch(96% 0.008 80 / 0.16);
  --border-strong: oklch(96% 0.008 80 / 0.30);
  --shadow: none;
}

.scheme-deep {
  --bg: var(--slate-darkest);
  --bg-raised: oklch(19% 0.018 250);
  --text: oklch(96% 0.008 80);
  --text-soft: var(--slate-lighter);
  --text-faint: var(--slate-light);
  --accent: var(--copper-light);
  --accent-text: var(--copper-light);
  --border: oklch(96% 0.008 80 / 0.14);
  --border-strong: oklch(96% 0.008 80 / 0.26);
  --shadow: none;
}

/* ── Reset ────────────────────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }

body {
  margin: 0;
  background: var(--paper-lightest);
  color: oklch(19% 0.016 250);
  font-family: "Public Sans", system-ui, -apple-system, "Segoe UI", sans-serif;
  font-size: var(--step-0);
  line-height: 1.65;
  font-weight: 400;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

h1, h2, h3, h4 {
  font-family: "Archivo", system-ui, -apple-system, "Segoe UI", sans-serif;
  font-weight: 600;
  line-height: 1.12;
  letter-spacing: -0.021em;
  margin: 0;
  text-wrap: balance;
}

p { margin: 0; text-wrap: pretty; }
ul, ol, dl, dd { margin: 0; padding: 0; }
li { list-style: none; }

a { color: var(--accent-text, inherit); text-underline-offset: 0.18em; }
a:hover { text-decoration-thickness: 2px; }

img, svg { max-width: 100%; height: auto; display: block; }

:focus-visible {
  outline: 2px solid var(--copper);
  outline-offset: 3px;
  border-radius: 2px;
}

/* ── Utilities ────────────────────────────────────────────────────────── */
.visually-hidden {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}

.skip-link {
  position: absolute; left: var(--space-4); top: -100%;
  z-index: 100; padding: var(--space-3) var(--space-5);
  background: var(--slate-darkest); color: oklch(96% 0.008 80);
  border-radius: var(--radius); font-weight: 500; text-decoration: none;
  transition: top var(--dur-fast) var(--ease);
}
.skip-link:focus { top: var(--space-4); }

.shell {
  width: 100%;
  max-width: var(--shell);
  margin-inline: auto;
  padding-inline: clamp(1.25rem, 5vw, 3rem);
}
.shell--wide { max-width: var(--shell-wide); }

.section {
  background: var(--bg);
  color: var(--text);
  padding-block: var(--section-pad, var(--space-10));
}
.section + .section { border-top: var(--rule) solid var(--border); }

/* Anchor targets must clear the 4.25rem sticky header, or a nav click drops
   the heading underneath it. */
:where(#top, #engagements, #capabilities, #work, #experience, #credentials, #contact) {
  scroll-margin-top: 5.75rem;
}

.eyebrow {
  font-size: var(--step--2);
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--accent-text);
  margin-bottom: var(--space-5);
  display: flex;
  align-items: center;
  gap: var(--space-3);
}
.eyebrow::before {
  content: "";
  width: 1.75rem; height: 1px;
  background: currentColor; opacity: 0.5;
  flex: none;
}

.section__head { max-width: 46rem; margin-bottom: var(--space-9); }
.section__title { font-size: clamp(1.953rem, 1.4rem + 2.2vw, 3.052rem); }
.section__sub {
  margin-top: var(--space-5);
  font-size: var(--step-1);
  color: var(--text-soft);
  max-width: 40rem;
  line-height: 1.55;
}

/* ── Buttons ──────────────────────────────────────────────────────────── */
.btn {
  --btn-bg: transparent;
  --btn-fg: var(--text);
  display: inline-flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-3) var(--space-3) var(--space-6);
  font-family: inherit;
  font-size: var(--step-0);
  font-weight: 500;
  line-height: 1;
  background: var(--btn-bg);
  color: var(--btn-fg);
  border: var(--rule) solid transparent;
  border-radius: var(--radius-pill);
  cursor: pointer;
  text-decoration: none;
  transition: background-color var(--dur) var(--ease),
              color var(--dur) var(--ease),
              border-color var(--dur) var(--ease),
              transform var(--dur-fast) var(--ease);
}
.btn:active { transform: scale(0.985); }

.btn--primary {
  --btn-bg: var(--slate-darkest);
  --btn-fg: oklch(97% 0.008 80);
}
.scheme-slate .btn--primary,
.scheme-deep .btn--primary {
  --btn-bg: var(--copper-light);
  --btn-fg: var(--slate-darkest);
}
.btn--primary:hover { --btn-bg: var(--slate-dark); }
.scheme-slate .btn--primary:hover,
.scheme-deep .btn--primary:hover { --btn-bg: oklch(80% 0.095 58); }

.btn--ghost {
  --btn-fg: var(--text);
  border-color: var(--border-strong);
  padding-inline: var(--space-6);
}
.btn--ghost:hover { border-color: var(--text); }

.btn--sm { font-size: var(--step--1); padding: var(--space-2) var(--space-2) var(--space-2) var(--space-5); }
.btn--full { width: 100%; justify-content: space-between; }

/* Button-in-button: trailing icon nests in its own wrapper, flush with the
   button's inner padding — never sitting naked beside the label. Applied to
   primary CTAs only, so it stays a signal rather than wallpaper. */
.btn__icon {
  display: grid;
  place-items: center;
  width: 1.9em; height: 1.9em;
  flex: none;
  border-radius: 50%;
  background: color-mix(in oklab, currentColor 14%, transparent);
  transition: transform var(--dur) var(--ease);
}
.btn__icon svg { width: 0.95em; height: 0.95em; }
.btn:hover .btn__icon { transform: translateX(2px) translateY(-2px); }

/* ── Header ───────────────────────────────────────────────────────────── */
.site-header {
  position: sticky;
  top: 0;
  z-index: 50;
  /* 0.92, not 0.82: the header is sticky and passes over the dark schemes,
     where a lighter alpha composited to a cool grey band across an otherwise
     warm-paper page. The blur still supplies the depth cue. */
  background: oklch(98.5% 0.005 80 / 0.92);
  /* backdrop-blur lives ONLY here — a fixed element. Never on scrolling
     containers, where it forces continuous GPU repaint on mobile. */
  backdrop-filter: saturate(150%) blur(12px);
  border-bottom: var(--rule) solid oklch(19% 0.016 250 / 0.10);
}
@supports not (backdrop-filter: blur(12px)) {
  .site-header { background: var(--paper-lightest); }
}

.site-header.is-scrolled {
  box-shadow: 0 1px 0 oklch(19% 0.016 250 / 0.06),
              0 8px 24px -16px oklch(19% 0.016 250 / 0.35);
}

.header__inner {
  display: flex;
  align-items: center;
  gap: var(--space-6);
  min-height: 4.25rem;
}

.header__brand {
  display: flex; align-items: center; gap: var(--space-3);
  text-decoration: none; color: inherit;
  font-family: "Archivo", sans-serif;
  font-weight: 600;
  letter-spacing: -0.015em;
  flex: none;
}
.header__mark {
  display: grid; place-items: center;
  width: 2rem; height: 2rem;
  border-radius: var(--radius-sm);
  background: var(--slate-darkest);
  color: oklch(96% 0.008 80);
  font-size: var(--step--1);
  font-weight: 700;
  letter-spacing: 0.02em;
}
.header__name { font-size: var(--step-0); }

.header__nav { margin-left: auto; }
.header__list { display: flex; gap: var(--space-6); }
.header__list a {
  color: var(--slate-mid);
  text-decoration: none;
  font-size: var(--step--1);
  font-weight: 500;
  padding-block: var(--space-2);
  border-bottom: 2px solid transparent;
  transition: color var(--dur) var(--ease), border-color var(--dur) var(--ease);
}
.header__list a:hover { color: var(--slate-darkest); border-bottom-color: var(--copper); }

.header__cta { flex: none; }

.header__toggle {
  display: none;
  margin-left: auto;
  background: none; border: 0; cursor: pointer;
  padding: var(--space-3); color: var(--slate-darkest);
}
.header__bars { display: grid; gap: 5px; width: 22px; }
.header__bars i {
  display: block; height: 2px; background: currentColor; border-radius: 2px;
  transition: transform var(--dur) var(--ease), opacity var(--dur) var(--ease);
}
.header__toggle[aria-expanded="true"] .header__bars i:first-child { transform: translateY(3.5px) rotate(45deg); }
.header__toggle[aria-expanded="true"] .header__bars i:last-child  { transform: translateY(-3.5px) rotate(-45deg); }

.mobile-nav {
  position: sticky; top: 4.25rem; z-index: 45;
  background: var(--paper-lightest);
  border-bottom: var(--rule) solid oklch(19% 0.016 250 / 0.12);
  padding: var(--space-4) clamp(1.25rem, 5vw, 3rem) var(--space-6);
}
.mobile-nav__list { display: grid; gap: var(--space-1); }
.mobile-nav__list a {
  display: block;
  padding: var(--space-4) 0;
  color: var(--slate-dark);
  text-decoration: none;
  font-family: "Archivo", sans-serif;
  font-size: var(--step-1);
  font-weight: 500;
  border-bottom: var(--rule) solid oklch(19% 0.016 250 / 0.08);
}
.mobile-nav__list a:hover { color: var(--copper-dark); }

/* ── Hero ─────────────────────────────────────────────────────────────── */
.hero { --section-pad: clamp(3.5rem, 7vw, 7rem); padding-bottom: clamp(3rem, 6vw, 5.5rem); }

.hero__grid {
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr);
  gap: clamp(2.5rem, 6vw, 5rem);
  align-items: center;
}

.hero__title {
  font-size: clamp(2.441rem, 1.5rem + 4.2vw, 4.768rem);
  font-weight: 600;
  letter-spacing: -0.032em;
  line-height: 1.04;
  max-width: 15ch;
}

/* A wrapper rather than a paragraph, because the lede runs to two of them and
   the measure and type size have to be stated once. */
.hero__lede {
  margin-top: var(--space-6);
  font-size: clamp(1.0625rem, 1rem + 0.4vw, 1.25rem);
  line-height: 1.6;
  color: var(--slate-mid);
  max-width: 46ch;
}
.hero__lede p + p { margin-top: var(--space-4); }

.hero__actions {
  margin-top: var(--space-8);
  display: flex; flex-wrap: wrap; gap: var(--space-4);
  align-items: center;
}

.hero__note {
  margin-top: var(--space-7);
  padding-top: var(--space-5);
  border-top: var(--rule) solid var(--border);
  font-size: var(--step--1);
  color: var(--slate-light);
  max-width: 42ch;
}

.hero__figure { margin: 0; }
.blueprint { width: 100%; color: var(--slate); }
.blueprint--hero { max-width: 34rem; margin-inline: auto; }

/* SVG sub-parts share one ink so they re-theme with the scheme */
.bp-source rect { fill: currentColor; opacity: 0.30; }
.bp-flow path { stroke: currentColor; stroke-opacity: 0.42; stroke-width: 1.25; }
.bp-connect path { stroke: currentColor; stroke-opacity: 0.20; stroke-width: 1; }
.bp-out circle { fill: var(--copper); }
.bp-out path { stroke: currentColor; stroke-opacity: 0.35; stroke-width: 1; }
.bp-ticks path { stroke: currentColor; stroke-opacity: 0.24; stroke-width: 1; }
.bp-doc rect { fill: none; stroke: currentColor; stroke-opacity: 0.34; stroke-width: 1.25; }
.bp-doc rect:last-child { fill: currentColor; fill-opacity: 0.10; }
.bp-stack path { fill: none; stroke: currentColor; stroke-opacity: 0.40; stroke-width: 1.25; }
.bp-axis { stroke: currentColor; stroke-opacity: 0.28; stroke-width: 1; }
.bp-wave { stroke: var(--copper); stroke-width: 1.75; stroke-linecap: round; stroke-linejoin: round; }
.bp-marker circle { fill: var(--copper); }
.bp-plan path { stroke: currentColor; stroke-opacity: 0.32; stroke-width: 1.25; }
.bp-occupancy circle { fill: var(--copper); opacity: 0.55; }
.bp-occupancy circle:nth-child(2n) { opacity: 0.28; }

/* ── Outcome ledger ───────────────────────────────────────────────────── */
.ledger { --section-pad: var(--space-10); }
.ledger__heading {
  font-size: clamp(1.5625rem, 1.2rem + 1.6vw, 2.441rem);
  margin-bottom: var(--space-9);
  max-width: 22ch;
}
.ledger__list { display: grid; }
.ledger__row {
  display: grid;
  grid-template-columns: minmax(0, 17rem) minmax(0, 1fr);
  gap: clamp(1.5rem, 5vw, 4rem);
  padding-block: var(--space-7);
  border-top: var(--rule) solid var(--border);
  align-items: baseline;
}
.ledger__row:last-child { border-bottom: var(--rule) solid var(--border); }

/* Keeps a compound value like "→ 100%" from breaking apart mid-expression,
   which would strand the arrow at the end of the previous line. */
.ledger__pair { white-space: nowrap; }

.ledger__figure {
  font-family: "Archivo", sans-serif;
  font-size: clamp(1.953rem, 1.5rem + 1.9vw, 3.052rem);
  font-weight: 600;
  letter-spacing: -0.03em;
  line-height: 1;
  color: var(--text);
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0 var(--space-3);
}
.ledger__unit {
  font-family: "Public Sans", sans-serif;
  font-size: var(--step--1);
  font-weight: 500;
  letter-spacing: 0.01em;
  color: var(--accent);
  line-height: 1.2;
}
.ledger__arrow { color: var(--accent); font-weight: 400; }

.ledger__detail {
  color: var(--text-soft);
  font-size: var(--step-0);
  line-height: 1.7;
  max-width: 58ch;
}

/* ── How I work ───────────────────────────────────────────────────────────
   Two ruled groups: what I get called in for, and the three ways to engage.
   The problems use the same ruled-row grammar as `.spec`; the offers are the
   one place on the page that lifts onto a raised surface, because they are
   the only content a visitor is meant to pick from. */
.engagements { --section-pad: var(--space-11); }

.group + .group { margin-top: var(--space-11); }

/* Larger than the .problems__title / .offer__name h4s beneath it — the group
   headings are the parent level in the outline, not a label above them. */
.group__title { font-size: clamp(1.5625rem, 1.3rem + 1.2vw, 1.953rem); }

.group__sub {
  margin-top: var(--space-3);
  font-size: var(--step-1);
  line-height: 1.55;
  color: var(--text-soft);
  max-width: 40rem;
}

.problems {
  margin-top: var(--space-6);
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  column-gap: clamp(2rem, 5vw, 4.5rem);
  border-bottom: var(--rule) solid var(--border);
}
.problems__item {
  padding-block: var(--space-7);
  border-top: var(--rule) solid var(--border);
}

.problems__index {
  font-family: "Archivo", sans-serif;
  font-size: var(--step--1);
  font-weight: 600;
  letter-spacing: 0.1em;
  color: var(--accent-text);
}
.problems__title {
  margin-top: var(--space-3);
  font-size: var(--step-2);
  letter-spacing: -0.022em;
  max-width: 22ch;
}
.problems__desc {
  margin-top: var(--space-4);
  font-size: var(--step-0);
  line-height: 1.65;
  color: var(--text-soft);
  max-width: 44ch;
}

.offers {
  margin-top: var(--space-6);
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--space-5);
}
.offer {
  display: flex;
  flex-direction: column;
  padding: var(--space-6);
  background: var(--bg-raised);
  border: var(--rule) solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
}

/* The paid entry point, marked with the section's only accent rule. */
.offer--entry { border-top: 2px solid var(--accent); }
.offer__tag {
  font-size: var(--step--2);
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--accent-text);
  margin-bottom: var(--space-4);
}

.offer__name {
  font-size: var(--step-1);
  letter-spacing: -0.015em;
  text-wrap: balance;
}
.offer__lede {
  margin-top: var(--space-3);
  font-size: var(--step--1);
  line-height: 1.55;
  color: var(--text-soft);
}

.offer__list {
  margin-top: var(--space-5);
  padding-top: var(--space-5);
  border-top: var(--rule) solid var(--border);
  display: grid;
  gap: var(--space-3);
}
.offer__list li {
  position: relative;
  padding-left: var(--space-5);
  font-size: var(--step--1);
  line-height: 1.55;
  color: var(--text-soft);
}
.offer__list li::before {
  content: "";
  position: absolute;
  left: 0; top: 0.6em;
  width: 0.35rem; height: 0.35rem;
  border-radius: 50%;
  background: var(--accent);
}

/* Pinned to the card's foot so the three lists end on one line. Uses
   --text-soft, not --text-faint: this is selling copy, and faint measures
   3.4:1 on the raised card surface — under AA for 14px text. */
.offer__close {
  margin-top: auto;
  padding-top: var(--space-5);
  font-size: var(--step--1);
  line-height: 1.5;
  color: var(--text-soft);
}

/* ── Capabilities ─────────────────────────────────────────────────────── */
.capabilities { --section-pad: var(--space-11); }

.spec { display: grid; }
.spec__row {
  display: grid;
  grid-template-columns: minmax(0, 17rem) minmax(0, 1fr);
  gap: clamp(1rem, 4vw, 3.5rem);
  padding-block: var(--space-6);
  border-top: var(--rule) solid var(--border);
}
.spec__row:last-child { border-bottom: var(--rule) solid var(--border); }

.spec__key {
  font-family: "Archivo", sans-serif;
  font-size: var(--step-0);
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--text);
  padding-top: var(--space-1);
}

/* The tagline sits above the chips and is the only prose in the section: it says
   what the practice area is for, which a list of tool names cannot. Set to
   --text-soft rather than --text-faint so it clears AA at this size. */
.spec__val { display: grid; gap: var(--space-4); }
.spec__lede {
  font-size: var(--step--1);
  line-height: 1.6;
  color: var(--text-soft);
  max-width: 58ch;
}

.chips { display: flex; flex-wrap: wrap; gap: var(--space-3); }
.chips li {
  font-size: var(--step--1);
  font-weight: 500;
  color: var(--slate-dark);
  background: var(--bg-raised);
  border: var(--rule) solid var(--border);
  border-radius: var(--radius-sm);
  padding: 0.3rem 0.7rem;
  line-height: 1.5;
}

/* ── Selected work ────────────────────────────────────────────────────── */
.work { --section-pad: var(--space-10); }

.case {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 0.8fr);
  gap: clamp(2rem, 6vw, 5rem);
  align-items: center;
  padding-block: var(--space-9);
  border-top: var(--rule) solid var(--border);
}
.case:last-child { padding-bottom: 0; }
.case--flip .case__body { order: 2; }
.case--flip .case__figure { order: 1; }

.case__title {
  font-size: clamp(1.5625rem, 1.2rem + 1.5vw, 2.441rem);
  letter-spacing: -0.026em;
  max-width: 22ch;
}
.case__lede {
  margin-top: var(--space-5);
  font-size: var(--step-1);
  line-height: 1.55;
  color: var(--text-soft);
  max-width: 46ch;
}
.case__points {
  margin-top: var(--space-6);
  display: grid;
  gap: var(--space-3);
  max-width: 52ch;
}
.case__points li {
  position: relative;
  padding-left: var(--space-5);
  font-size: var(--step-0);
  line-height: 1.6;
  color: var(--text-soft);
}
.case__points li::before {
  content: "";
  position: absolute;
  left: 0; top: 0.62em;
  width: 0.4rem; height: 0.4rem;
  border-radius: 50%;
  background: var(--accent);
}
.case__tech {
  margin-top: var(--space-6);
  padding-top: var(--space-4);
  border-top: var(--rule) solid var(--border);
  font-size: var(--step--1);
  color: var(--text-faint);
  letter-spacing: 0.005em;
}

.case__figure { margin: 0; }
.blueprint--case { max-width: 25rem; margin-inline: auto; color: var(--slate); }

/* ── Experience ───────────────────────────────────────────────────────── */
.experience { --section-pad: var(--space-12); }

.timeline { display: grid; }
.timeline__item {
  display: grid;
  grid-template-columns: minmax(0, 12rem) minmax(0, 1fr);
  gap: clamp(1rem, 4vw, 3.5rem);
  padding-block: var(--space-6);
  border-top: var(--rule) solid var(--border);
}
.timeline__item:last-child { border-bottom: var(--rule) solid var(--border); }

.timeline__period {
  font-family: "Archivo", sans-serif;
  font-size: var(--step--1);
  font-weight: 500;
  color: var(--accent-text);
  letter-spacing: 0.005em;
  padding-top: 0.35rem;
}
.timeline__role {
  font-size: var(--step-1);
  font-weight: 600;
  letter-spacing: -0.014em;
}
.timeline__org {
  margin-top: var(--space-1);
  font-size: var(--step--1);
  font-weight: 500;
  color: var(--slate-mid);
}
.timeline__desc {
  margin-top: var(--space-3);
  font-size: var(--step-0);
  line-height: 1.65;
  color: var(--text-soft);
  max-width: 62ch;
}

/* ── Credentials ──────────────────────────────────────────────────────── */
.credentials { --section-pad: var(--space-10); }

.credo {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 17rem), 1fr));
  gap: clamp(2rem, 5vw, 4rem);
}
.credo__label {
  font-size: var(--step--1);
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--accent);
  padding-bottom: var(--space-4);
  border-bottom: var(--rule) solid var(--border-strong);
}
.credo__list { margin-top: var(--space-5); display: grid; gap: var(--space-5); }
.credo__list li { display: grid; gap: var(--space-2); }
.credo__badge {
  font-family: "Archivo", sans-serif;
  font-size: var(--step--1);
  font-weight: 600;
  color: var(--copper-light);
  letter-spacing: 0.02em;
}
.credo__text {
  font-size: var(--step-0);
  line-height: 1.55;
  color: var(--text-soft);
}

/* ── Contact ──────────────────────────────────────────────────────────── */
.contact { --section-pad: var(--space-11); }

.contact__grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: clamp(2.5rem, 6vw, 5rem);
  align-items: start;
}
.contact__title {
  font-size: clamp(2.441rem, 1.6rem + 3vw, 3.815rem);
  letter-spacing: -0.032em;
  max-width: 16ch;
}
.contact__lede {
  margin-top: var(--space-6);
  font-size: var(--step-1);
  line-height: 1.6;
  color: var(--text-soft);
  max-width: 44ch;
}

.contact__direct {
  margin-top: var(--space-9);
  padding-top: var(--space-6);
  border-top: var(--rule) solid var(--border-strong);
  display: grid;
  gap: var(--space-5);
}
.contact__line { display: grid; grid-template-columns: 7rem minmax(0, 1fr); gap: var(--space-4); }
.contact__line dt {
  font-size: var(--step--1);
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-faint);
  padding-top: 0.2rem;
}
.contact__line dd { font-size: var(--step-0); color: var(--text); }
.contact__line a { color: var(--accent-text); font-weight: 500; }

/* ── Form ─────────────────────────────────────────────────────────────── */
.form {
  background: var(--bg-raised);
  border: var(--rule) solid var(--border);
  border-radius: var(--radius-lg);
  padding: clamp(1.5rem, 3vw, 2.25rem);
  box-shadow: var(--shadow);
  display: grid;
  gap: var(--space-5);
}

.form__row { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-5); }

.field { display: grid; gap: var(--space-2); }
.field label {
  font-size: var(--step--1);
  font-weight: 500;
  color: var(--text);
  letter-spacing: 0.005em;
}
.field__opt { color: var(--text-faint); font-weight: 400; }

.field input,
.field select,
.field textarea {
  font-family: inherit;
  font-size: var(--step-0);
  color: var(--text);
  background: var(--bg);
  border: var(--rule) solid var(--border-strong);
  border-radius: var(--radius);
  padding: 0.7rem 0.85rem;
  width: 100%;
  transition: border-color var(--dur) var(--ease), background-color var(--dur) var(--ease);
}
.field textarea { resize: vertical; min-height: 7rem; line-height: 1.6; }
.field select { appearance: none; cursor: pointer;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M2.5 4.5 6 8l3.5-3.5' fill='none' stroke='%23666' stroke-width='1.4' stroke-linecap='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 0.85rem center; background-size: 0.85rem;
  padding-right: 2.2rem;
}
.field input:hover, .field select:hover, .field textarea:hover { border-color: var(--slate-light); }
.field input:focus, .field select:focus, .field textarea:focus {
  border-color: var(--copper);
  outline: 2px solid var(--copper);
  outline-offset: 0;
}
.field input:user-invalid, .field textarea:user-invalid { border-color: oklch(52% 0.17 25); }

.form__status {
  font-size: var(--step--1);
  line-height: 1.6;
  color: var(--copper-darkest);
  background: var(--copper-lightest);
  border-radius: var(--radius);
  padding: 0;
  min-height: 0;
}
.form__status:not(:empty) { padding: var(--space-3) var(--space-4); }
.form__status a { font-weight: 600; }
.form__status ul { display: grid; gap: var(--space-1); }

/* Heading shared by both enquiry forms. It names the three engagement types
   before the fields, so a visitor answers in the terms the practice is sold
   in rather than describing a problem and leaving the routing to me. */
.form__intro { margin-bottom: var(--space-5); }
.form__head, .chat__title {
  font-size: var(--step-2);
  letter-spacing: -0.02em;
  text-wrap: balance;
}
.form__sub {
  margin-top: var(--space-3);
  font-size: var(--step--1);
  line-height: 1.6;
  color: var(--text-soft);
  max-width: 42ch;
}

/* ── Footer ───────────────────────────────────────────────────────────── */
.site-footer {
  background: var(--slate-darkest);
  color: oklch(96% 0.008 80);
  padding-block: var(--space-8);
}
.footer__inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-4) var(--space-6);
}
.footer__name {
  font-family: "Archivo", sans-serif;
  font-weight: 600;
  letter-spacing: -0.015em;
}
.footer__links { display: flex; flex-wrap: wrap; gap: var(--space-5); margin-left: auto; }
.footer__links a {
  color: oklch(96% 0.008 80 / 0.78);
  font-size: var(--step--1);
  text-decoration: none;
  transition: color var(--dur) var(--ease);
}
.footer__links a:hover { color: var(--copper-light); }
.footer__meta {
  font-size: var(--step--1);
  color: oklch(96% 0.008 80 / 0.55);
  flex-basis: 100%;
}

/* ── Chat launcher ──────────────────────────────────────────────────────
   A floating shortcut to the enquiry the contact section already takes.
   The wrapper carries .scheme-paper in the markup, which is not decorative:
   a position:fixed element sits outside every section, so without a scheme
   class it resolves none of the layer-2 tokens and paints with nothing. */
.chat {
  position: fixed;
  right: var(--space-5);
  bottom: calc(var(--space-5) + env(safe-area-inset-bottom, 0px));
  z-index: 40;            /* under .mobile-nav (45) and .site-header (50) */
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: var(--space-3);
  /* Deliberately NO pointer-events: none on this wrapper. It buys almost
     nothing — the box shrinks to its two children, so the only dead area is
     the 12px gap between them — and WebKit hit-tests the touch against the
     wrapper first, which makes the launcher untappable on iOS. */
}

.chat__launch {
  box-shadow: var(--shadow);
  gap: var(--space-2);
  padding: 0.7rem var(--space-5);
}
.chat__launch svg { width: 1.05em; height: 1.05em; flex: none; }

.chat__panel {
  width: min(23rem, calc(100vw - 2 * var(--space-5)));
  max-height: min(46rem, calc(100vh - 9rem));
  /* dvh where supported: mobile browser chrome makes 100vh taller than the
     area actually on screen, which would push the submit button off it. */
  max-height: min(46rem, calc(100dvh - 9rem));
  overflow-y: auto;
  overscroll-behavior: contain;   /* panel scroll must not chain to the page */
  padding: var(--space-6);
  background: var(--bg-raised);
  border: var(--rule) solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow);
  transition: opacity var(--dur) var(--ease), transform var(--dur) var(--ease);
}
/* Progressive enhancement: animates the way out of display:none where the
   browser supports it, and simply appears where it does not. */
@starting-style {
  .chat__panel { opacity: 0; transform: translateY(0.5rem); }
}

.chat__head { display: flex; align-items: flex-start; gap: var(--space-4); }
.chat__title { flex: 1; }

/* The panel takes focus on touch devices so the soft keyboard does not open
   the moment the launcher is tapped. It is tabindex="-1", so no keyboard user
   ever reaches it by Tab and the ring would only ever be an artefact. */
.chat__panel:focus { outline: none; }

.chat__close {
  flex: none;
  display: grid;
  place-items: center;
  width: 2rem; height: 2rem;
  margin: -0.35rem -0.35rem 0 0;
  color: var(--text-soft);
  background: none;
  border: 0;
  border-radius: 50%;
  cursor: pointer;
  transition: color var(--dur) var(--ease), background-color var(--dur) var(--ease);
}
.chat__close:hover { color: var(--text); background: var(--border); }
.chat__close svg { width: 1rem; height: 1rem; }

/* Tighter than the contact form: the panel has a fixed maximum height, and a
   form that opens already needing a scroll reads as broken rather than full. */
.chat__form { margin-top: var(--space-5); display: grid; gap: var(--space-4); }
.chat__form textarea { min-height: 5rem; }

/* The launcher ships 41px tall, just under the 44px minimum tap target.
   Keyed to pointer type rather than viewport width: an iPad is a touch device
   at 768px and would otherwise keep the small target. */
@media (pointer: coarse) {
  .chat__launch { padding-block: 0.85rem; }
}

/* ── Scroll reveal ────────────────────────────────────────────────────── */
.reveal {
  opacity: 0;
  transform: translateY(1.25rem);
  transition: opacity var(--dur-slow) var(--ease), transform var(--dur-slow) var(--ease);
}
.reveal.is-visible { opacity: 1; transform: none; }

/* ── Responsive ───────────────────────────────────────────────────────── */
/* The offers are the one grid that changes at its own width rather than the
   page's: below ~1088px three columns drop under 320px each and the bullet
   copy breaks to two and three lines apiece. The odd card out spans the row
   instead of sitting beside an empty cell. */
@media (max-width: 68rem) {
  .offers { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .offer:last-child { grid-column: 1 / -1; }
}

/* Below this the paired columns fall under ~330px and every bullet starts
   wrapping to two lines, while the spanning card stays twice their width —
   which reads as a broken layout rather than a deliberate pair. */
@media (max-width: 48rem) {
  .offers { grid-template-columns: 1fr; }
  .offer:last-child { grid-column: auto; }
}

@media (max-width: 64rem) {
  .header__nav { display: none; }
  .header__cta { display: none; }
  .header__toggle { display: block; }
}

@media (max-width: 56rem) {
  .hero__grid,
  .contact__grid,
  .case,
  .case--flip { grid-template-columns: 1fr; }

  .hero__figure { order: -1; max-width: 26rem; margin-inline: 0; }
  .case--flip .case__body { order: 1; }
  .case--flip .case__figure { order: 2; }
  .case__figure { max-width: 20rem; margin-inline: 0; }

  .ledger__row,
  .spec__row,
  .timeline__item { grid-template-columns: 1fr; gap: var(--space-4); }

  /* Three offer columns get too narrow to scan before this breakpoint. Two,
     with the last spanning the row, beats a half-empty cell beside it. */
  .problems { grid-template-columns: 1fr; }

  .ledger__row { padding-block: var(--space-6); }
  .contact__line { grid-template-columns: 1fr; gap: var(--space-1); }
  .footer__links { margin-left: 0; }
}

@media (max-width: 34rem) {
  .form__row { grid-template-columns: 1fr; }
  .hero__actions .btn { width: 100%; justify-content: space-between; }
  .chat { right: var(--space-4); bottom: calc(var(--space-4) + env(safe-area-inset-bottom, 0px)); }
  /* Near-full-screen and tighter: at 390px the desktop spacing left the form
     ~50px too tall, so it opened already scrolled and the submit button sat
     below the fold. Gutters match at --space-4 on both sides. */
  .chat__panel {
    width: min(23rem, calc(100vw - 2 * var(--space-4)));
    max-height: calc(100vh - 5rem);
    max-height: calc(100dvh - 5rem);
    padding: var(--space-5);
  }
  .chat__form { gap: var(--space-3); }
  .chat__form textarea { min-height: 4.5rem; }

  /* Ten to fourteen bordered chips per area, one per line on a phone, is ninety
     boxes of chrome — the section reads as an accordion of pills. Falling back
     to the accent-dot list the engagement cards already use keeps every item
     individually scannable. This is a legibility change more than a height one:
     measured at 390px a list item drops from 33px to 21px, but the section only
     goes from 4799px to 4337px, because the taglines and row padding dominate
     at this width. */
  .chips { display: grid; gap: var(--space-2); }
  .chips li {
    position: relative;
    padding: 0 0 0 var(--space-5);
    background: none;
    border: 0;
    color: var(--text-soft);
    line-height: 1.5;
  }
  .chips li::before {
    content: "";
    position: absolute;
    left: 0; top: 0.55em;
    width: 0.35rem; height: 0.35rem;
    border-radius: 50%;
    background: var(--accent);
  }
}

/* ── Reduced motion ───────────────────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }

  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }

  /* State clarity is preserved with opacity and instant changes — never by
     removing feedback altogether. */
  .reveal { opacity: 1; transform: none; }
  .btn:hover .btn__icon { transform: none; }
  .btn:active { transform: none; }
}
