/* 00-tokens.css */
/* =========================================================================
   Tokens — alextacho.com. Light theme only.
   Scale mapped from linear.app measurements (refs/ANALYSIS.md), adapted for
   a light, warm, copy-led page: body 18px instead of 15px, same display
   ratios (64/48 = 1.33, 48/24 = 2.0), same -0.022em display tracking.
   ========================================================================= */

/* Hanken Grotesk Variable (OFL 1.1), latin subset, weights 100–900 */
@font-face {
  font-family: "Hanken Grotesk";
  src: url("/fonts/hanken-grotesk-latin-wght-normal.woff2") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* Metric-matched fallback so the swap causes minimal layout shift.
   Measured in Chromium canvas: Hanken advance width = 1.005x Arial; ascent 1.00em, descent 0.30em. */
@font-face {
  font-family: "Hanken Grotesk Fallback";
  src: local("Arial"), local("Helvetica Neue"), local("Helvetica");
  size-adjust: 100.5%;
  ascent-override: 99.5%;
  descent-override: 29.9%;
  line-gap-override: 0%;
}

:root {
  /* ---- Font ---------------------------------------------------------- */
  --font-sans: "Hanken Grotesk", "Hanken Grotesk Fallback", system-ui, -apple-system, "Segoe UI", Arial, sans-serif;

  /* ---- Weights (3 only) ---------------------------------------------- */
  --weight-regular: 400;  /* body, ledes */
  --weight-medium: 540;   /* display, h2 — tight via tracking, never bold (Hanken 500 read thin) */
  --weight-semibold: 600; /* h3, buttons, eyebrow, nav emphasis */

  /* ---- Type scale (7 sizes) ------------------------------------------
     role        desktop  mobile(390)  line-height  tracking
     display     64       40           1.04         -0.022em
     h2          48       30           1.08         -0.022em
     lede        24       20           1.4          -0.012em
     h3          20       20           1.35         -0.012em
     body        18       18           1.6          -0.006em
     small       15       15           1.5          -0.003em  (nav, footer, meta)
     eyebrow     13       13           1.4          +0.08em uppercase
     Fluid sizes interpolate 390px -> 1440px. Body/small never shrink.   */
  --text-display: clamp(2.5rem, 1.6643rem + 3.4286vw, 4rem);   /* 40 -> 64 */
  --text-h2: clamp(1.875rem, 1.2482rem + 2.5714vw, 3rem);      /* 30 -> 48 */
  --text-lede: clamp(1.25rem, 1.1107rem + 0.5714vw, 1.5rem);   /* 20 -> 24 */
  --text-h3: 1.25rem;    /* 20 */
  --text-body: 1.125rem; /* 18 */
  --text-small: 0.9375rem; /* 15 */
  --text-eyebrow: 0.8125rem; /* 13 */

  --leading-display: 1.04;
  --leading-h2: 1.08;
  --leading-lede: 1.4;
  --leading-h3: 1.35;
  --leading-body: 1.6;
  --leading-small: 1.5;

  --tracking-display: -0.022em;
  --tracking-title: -0.012em;
  --tracking-body: -0.006em;
  --tracking-eyebrow: 0.08em;

  /* ---- Color: surfaces ------------------------------------------------ */
  --color-bg: #FFFDF8;        /* warm paper white — page background */
  --color-bg-alt: #FAF6EC;    /* alternate section band (use sparingly) */

  /* ---- Color: text, 4 tiers (ratios vs --color-bg / --color-bg-alt) --- */
  --color-ink: #1C1A16;       /* 17.09:1 / 16.10:1 — headlines, primary text, button text */
  --color-ink-2: #46423A;     /*  9.83:1 /  9.26:1 — body copy */
  --color-ink-3: #6B665C;     /*  5.61:1 /  5.29:1 — ledes' second tone, meta, nav, captions */
  --color-ink-4: #A8A294;     /*  2.50:1 — DECORATIVE ONLY (dividers glyphs, disabled icons). NEVER text. */

  /* ---- Color: border (the ONE border style) --------------------------- */
  --color-border: #E8E2D4;    /* 1.27:1 — hairline separators, not a UI boundary cue */
  --border: 1px solid var(--color-border);

  /* ---- Color: yellow accent family ------------------------------------
     Fill / highlight / underline only. NEVER as text color on light bg.
     #F6BE00 on #FFFDF8 = 1.68:1 (fails text), ink on #F6BE00 = 10.16:1.  */
  --color-accent: #F6BE00;       /* button fill, markers. ink text on it 10.16:1 */
  --color-accent-strong: #E0AC00;/* hover fill. ink on it 8.33:1 */
  --color-accent-soft: #FFE58A;  /* highlighter band, ::selection. ink on it 13.92:1, ink-2 8.01:1 */
  --color-accent-wash: #FFF3C4;  /* faint tint backgrounds. ink on it 15.61:1 */
  --color-accent-deep: #8A6A00;  /* link underline (4.99:1 on bg) — gold, passes 3:1 non-text */

  /* ---- Focus ---------------------------------------------------------- */
  --focus-ring: 2px solid var(--color-ink); /* 17:1 on bg, 10:1 on yellow */
  --focus-offset: 3px;

  /* ---- Spacing (4/8 base) --------------------------------------------- */
  --space-1: 0.25rem;  /*   4 */
  --space-2: 0.5rem;   /*   8 */
  --space-3: 0.75rem;  /*  12 */
  --space-4: 1rem;     /*  16 */
  --space-5: 1.5rem;   /*  24 — heading -> body, paragraph gap */
  --space-6: 2rem;     /*  32 — h1 -> lede */
  --space-7: 2.5rem;   /*  40 — headline -> CTA */
  --space-8: 3rem;     /*  48 */
  --space-9: 4rem;     /*  64 — section header -> content */
  --space-10: 5rem;    /*  80 */
  --space-11: 7.5rem;  /* 120 */
  --space-12: 10rem;   /* 160 */

  /* Section padding: 64px @390 -> 120px @1440 (the ONE section rhythm) */
  --section-pad: clamp(4rem, 2.7rem + 5.333vw, 7.5rem);
  /* Air above the hero h1 (≥150px @1440) */
  --hero-pad-top: clamp(4.5rem, 2.64rem + 7.62vw, 9.5rem);

  /* ---- Layout --------------------------------------------------------- */
  --container-max: 1280px;                   /* content width, excluding gutters */
  --gutter: clamp(1.25rem, 5vw, 5rem);       /* 20px @390, 72px @1440, 80px max */
  /* One two-column grid for every split section (services, about, contact):
     40/60, 80px gutter, so the right column starts on the same line from
     top to bottom. */
  --split-columns: minmax(0, 2fr) minmax(0, 3fr);
  --split-gap: var(--space-10);
  --measure: 38rem;                          /* 608px prose max (≤620) */
  --measure-narrow: 32rem;                   /* 512px hero lede */

  /* ---- Chrome --------------------------------------------------------- */
  --nav-height: 4.5rem;                      /* 72px; nav piece should match */
  --radius-sm: 6px;
  --radius-pill: 9999px;
  --control-height: 2.75rem;                 /* 44px buttons / tap targets */

  --ease: cubic-bezier(0.2, 0, 0, 1);
  --duration: 160ms;
}

/* 01-base.css */
/* =========================================================================
   Base — reset, typography, primitives.

   API for section builders (use these; don't redefine them):
   .container        centered max-width wrapper with responsive gutters
   .section          THE section recipe: vertical padding var(--section-pad)
   .section--alt     same, on the warm alt band (--color-bg-alt)
   .section__header  heading block; children spaced 24px; max 48rem wide
   .eyebrow          13px uppercase label above a heading (ink-3)
   .display          64/40px hero or closing headline (use on the one h1)
   .h2 / .h3         apply heading styles to non-heading elements
   .lede             24/20px intro paragraph, ink-3, measure-limited
   .prose            flow container: paragraphs spaced 24px, ≤608px wide
   .muted            ink-3 text tone (e.g. second half of a two-tone h2)
   .mark             yellow highlighter band behind a phrase
   .btn              primary: yellow fill, ink text, pill, 44px tall
   .btn--ghost       text-style action: ink text, gold underline, 44px target
   .skip-link        hidden until focused; first element in <body>
   .visually-hidden  screen-reader-only text
   Tokens: see 00-tokens.css (--space-*, --text-*, --color-*, --gutter...).
   Rules: one filled .btn per viewport; yellow is never text color;
   borders only via var(--border); no shadows or gradients.
   ========================================================================= */

/* ---- Reset ------------------------------------------------------------ */
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; }
html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  scroll-padding-top: calc(var(--nav-height) + var(--space-4));
  color-scheme: light;
}
@media (prefers-reduced-motion: no-preference) {
  html { scroll-behavior: smooth; }
}
body {
  min-height: 100vh;
  background: var(--color-bg);
  color: var(--color-ink-2);
  font-family: var(--font-sans);
  font-size: var(--text-body);
  line-height: var(--leading-body);
  letter-spacing: var(--tracking-body);
  font-weight: var(--weight-regular);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  font-kerning: normal;
  overflow-x: clip;
}
img, picture, svg, video { display: block; max-width: 100%; height: auto; }
input, button, textarea, select { font: inherit; color: inherit; }
button { cursor: pointer; }
ul[role="list"], ol[role="list"] { list-style: none; padding: 0; }
p, li, h1, h2, h3, h4 { overflow-wrap: break-word; }
[hidden] { display: none !important; }

/* ---- Headings --------------------------------------------------------- */
h1, h2, h3, h4, .display, .h2, .h3 {
  color: var(--color-ink);
  text-wrap: balance;
}
h1, .display {
  font-size: var(--text-display);
  line-height: var(--leading-display);
  letter-spacing: var(--tracking-display);
  font-weight: var(--weight-medium);
}
h2, .h2 {
  font-size: var(--text-h2);
  line-height: var(--leading-h2);
  letter-spacing: var(--tracking-display);
  font-weight: var(--weight-medium);
}
h3, h4, .h3 {
  font-size: var(--text-h3);
  line-height: var(--leading-h3);
  letter-spacing: var(--tracking-title);
  font-weight: var(--weight-semibold);
}

p { text-wrap: pretty; }
strong, b { font-weight: var(--weight-semibold); color: var(--color-ink); }
small { font-size: var(--text-small); line-height: var(--leading-small); }

/* ---- Links ------------------------------------------------------------
   Gold underline (#8A6A00, 4.99:1) = non-color cue ≥3:1. Hover adds the
   yellow highlighter band; text stays ink.                                */
a {
  color: var(--color-ink);
  text-decoration-line: underline;
  text-decoration-color: var(--color-accent-deep);
  text-decoration-thickness: 0.1em;
  text-underline-offset: 0.22em;
  text-decoration-skip-ink: auto;
  border-radius: 2px;
  transition: background-color var(--duration) var(--ease), text-decoration-color var(--duration) var(--ease);
}
a:hover {
  background-color: var(--color-accent-soft);
  text-decoration-color: var(--color-ink);
}

/* ---- Focus ------------------------------------------------------------ */
:focus-visible {
  outline: var(--focus-ring);
  outline-offset: var(--focus-offset);
}
:focus:not(:focus-visible) { outline: none; }

::selection { background: var(--color-accent-soft); color: var(--color-ink); }

/* ---- Skip link -------------------------------------------------------- */
.skip-link {
  position: absolute;
  top: var(--space-3);
  left: var(--space-3);
  z-index: 1000;
  padding: var(--space-2) var(--space-4);
  background: var(--color-ink);
  color: var(--color-bg);
  font-size: var(--text-small);
  font-weight: var(--weight-semibold);
  text-decoration: none;
  border-radius: var(--radius-sm);
  transform: translateY(-200%);
}
.skip-link:focus, .skip-link:focus-visible {
  transform: none;
  outline: 2px solid var(--color-ink);
  outline-offset: 2px;
}
.skip-link:hover { background: var(--color-ink); }

/* ---- Layout primitives ----------------------------------------------- */
.container {
  width: 100%;
  max-width: calc(var(--container-max) + 2 * var(--gutter));
  margin-inline: auto;
  padding-inline: var(--gutter);
}
.section { padding-block: var(--section-pad); }
.section--alt { background: var(--color-bg-alt); }
.section__header {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
  max-width: 48rem;
  margin-bottom: var(--space-9);
}
.section__header > .eyebrow + * { margin-top: calc(-1 * var(--space-2)); }

/* ---- Text primitives -------------------------------------------------- */
.eyebrow {
  display: block;
  font-size: var(--text-eyebrow);
  line-height: 1.4;
  letter-spacing: var(--tracking-eyebrow);
  text-transform: uppercase;
  font-weight: var(--weight-semibold);
  color: var(--color-ink-3);
}
.lede {
  font-size: var(--text-lede);
  line-height: var(--leading-lede);
  letter-spacing: var(--tracking-title);
  color: var(--color-ink-3);
  max-width: var(--measure);
}
.prose { max-width: var(--measure); }
.prose > * + * { margin-top: var(--space-5); }
.muted { color: var(--color-ink-3); }
.mark {
  background: linear-gradient(transparent 40%, var(--color-accent-soft) 40%, var(--color-accent-soft) 94%, transparent 94%);
  color: inherit;
  padding-inline: 0.08em;
  -webkit-box-decoration-break: clone;
  box-decoration-break: clone;
}

/* ---- Buttons ---------------------------------------------------------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  min-height: var(--control-height);
  padding: 0 var(--space-5);
  border: 0;
  border-radius: var(--radius-pill);
  background: var(--color-accent);
  color: var(--color-ink);
  font-size: var(--text-body);
  font-weight: var(--weight-semibold);
  line-height: 1;
  letter-spacing: 0;
  text-decoration: none;
  white-space: nowrap;
  transition: background-color var(--duration) var(--ease);
}
.btn:hover { background: var(--color-accent-strong); color: var(--color-ink); }
.btn:active { transform: translateY(1px); }

.btn--ghost {
  background: transparent;
  padding-inline: 0;
  border-radius: 2px;
  text-decoration-line: underline;
  text-decoration-color: var(--color-accent-deep);
  text-decoration-thickness: 0.1em;
  text-underline-offset: 0.3em;
}
.btn--ghost:hover { background: transparent; text-decoration-color: var(--color-ink); }

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

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

/* Inline arrow: the self-hosted subset has no U+2192 glyph, so a text arrow
   would fall back to a system face. */
.arrow {
  width: 1em;
  height: 1em;
  vertical-align: -0.125em;
  flex: none;
}

/* 10-nav.css */
/* =========================================================================
   Nav — sticky 72px bar, hairline bottom, 18px name, 15px links, and a
   quiet text CTA (ink + gold underline + arrow) so the hero keeps the only
   yellow button. Fits without JS by tightening: below 400px the CTA drops the
   arrow and reads as the single whole word "Book" (accessible name still
   starts with it: "Book a call on Calendly"); below 360px About drops
   (Contact stays). No hamburger, no JS.
   ========================================================================= */
.nav {
  position: sticky;
  top: 0;
  z-index: 100;
  background: var(--color-bg);
  border-bottom: var(--border);
}
@supports ((-webkit-backdrop-filter: blur(1px)) or (backdrop-filter: blur(1px))) {
  .nav {
    background: color-mix(in srgb, var(--color-bg) 93%, transparent);
    -webkit-backdrop-filter: saturate(1.4) blur(16px);
    backdrop-filter: saturate(1.4) blur(16px);
  }
}

.nav__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  height: calc(var(--nav-height) - 1px); /* + 1px hairline = 72px */
}

.nav a { text-decoration: none; }

.nav__name {
  display: inline-flex;
  align-items: center;
  min-height: var(--control-height);
  font-size: var(--text-body);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-title);
  color: var(--color-ink);
  white-space: nowrap;
}
.nav__name:hover { background: transparent; color: var(--color-ink-2); }

.nav__menu {
  display: flex;
  align-items: center;
  gap: var(--space-5);
}

.nav__links {
  display: flex;
  align-items: center;
  gap: var(--space-1);
}

.nav__link {
  display: inline-flex;
  align-items: center;
  min-height: var(--control-height);
  padding-inline: var(--space-3);
  border-radius: var(--radius-pill);
  font-size: var(--text-small);
  line-height: var(--leading-small);
  color: var(--color-ink-3);
  white-space: nowrap;
}
.nav__link:hover { background: var(--color-bg-alt); color: var(--color-ink); }

/* Quiet action: ink semibold text, gold underline (4.99:1 on bg), arrow. */
.nav .nav__cta {
  display: inline-flex;
  align-items: center;
  gap: 0.3em;
  min-height: var(--control-height);
  border-radius: 2px;
  color: var(--color-ink);
  font-size: var(--text-small);
  font-weight: var(--weight-semibold);
  line-height: var(--leading-small);
  white-space: nowrap;
}
.nav__cta-label {
  text-decoration-line: underline;
  text-decoration-color: var(--color-accent-deep);
  text-decoration-thickness: 0.1em;
  text-underline-offset: 0.3em;
}
.nav__cta-arrow {
  display: inline-block;
  text-decoration: none;
  transition: transform var(--duration) var(--ease);
}
.nav .nav__cta:hover { background: transparent; }
.nav__cta:hover .nav__cta-label { text-decoration-color: var(--color-ink); }
.nav__cta:hover .nav__cta-arrow { transform: translateX(2px); }

@media (max-width: 40rem) {
  .nav__inner { gap: var(--space-2); }
  .nav__menu { gap: var(--space-2); }
  .nav__links { gap: 0; }
  .nav__link { padding-inline: var(--space-2); }
}
@media (max-width: 27rem) {
  /* "Book a call →" no longer fits beside the wordmark: show the whole word
     "Book" and drop the arrow, so nothing reads clipped and the name keeps air. */
  .nav__cta-arrow { display: none; }
  /* " a call" leaves the layout but stays in the accessible name, which
     therefore still reads "Book a call on Calendly" and starts with "Book". */
  .nav__cta-rest {
    position: absolute;
    width: 1px; height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }
  .nav .nav__cta { gap: 0; }
  .nav__menu { gap: var(--space-3); } /* separate the links group from "Book" */
  .nav__link { padding-inline: 0.25rem; }
}
@media (max-width: 22.49rem) {
  .nav__item--about { display: none; }
}

/* Pills already carry their own padding; keep the ring snug to them. */
.nav__link:focus-visible, .nav__cta:focus-visible { outline-offset: 0; }

/* 20-hero.css */
/* Hero — centered, content held to 80% of the container: eyebrow, h1, the
   promise, then a sign-off block centered as one unit: portrait +
   credential, the services link centered under it.
   (Book a call lives in the nav, Services and Contact.) */
.hero {
  padding-top: var(--space-9);
  /* Hero and Services share the page background, so a full section pad on
     both sides of the seam read as a dead band. 64px here + Services' top pad. */
  padding-bottom: var(--space-9);
  text-align: center;
}
@media (min-width: 56rem) {
  .hero { padding-top: var(--space-11); }
  .hero .hero__inner > * {
    max-width: calc(var(--container-max) * 0.8);
    margin-inline: auto;
  }
}

/* Let the eyebrow wrap naturally and balance its lines at every width, so a
   phone never gets a stub first line ending on a dangling separator. */
.hero__eyebrow { text-wrap: balance; }
.hero__title { margin-top: var(--space-4); }
.hero__line { display: block; text-wrap: balance; }

.hero .hero__receipt {
  max-width: 34rem;
  margin: var(--space-6) auto 0;   /* h1 -> promise 32px */
  font-size: var(--text-lede);
  line-height: var(--leading-lede);
  color: var(--color-ink-2);
  text-wrap: balance;
}
.hero__cred {
  font-size: var(--text-small);
  line-height: var(--leading-small);
  color: var(--color-ink-3);
}

/* Sign-off: one left-aligned block, centered in the hero */
.hero .hero__signoff {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-6);
  width: fit-content;
  max-width: 100%;
  margin: var(--space-8) auto 0;
  text-align: left;
}
.hero .hero__person {
  display: flex;
  align-items: center;
  gap: var(--space-5);
}
.hero__photo {
  flex: none;
  width: 112px;
  height: 112px;
  border-radius: 50%;
}
.hero__cred { max-width: 30rem; text-wrap: balance; }
.hero__name {
  color: var(--color-ink-2);
  font-weight: var(--weight-semibold);
}

.hero .hero__more { align-self: center; }
.hero__more a {
  display: inline-flex;
  align-items: center;
  gap: 0.4em;
  min-height: 24px;   /* A10: 24px minimum hit box for an inline text link */
  font-weight: var(--weight-semibold);
}

/* Phones: a smaller portrait keeps the section compact */
@media (max-width: 55.9375rem) {
  .hero .hero__signoff { margin-top: var(--space-7); }
  .hero .hero__person { gap: var(--space-4); }
  .hero__photo { width: 80px; height: 80px; }
}

/* 30-services.css */
/* Services — three offers stacked as rows, one under the other, separated by
   the site's single hairline. At >=60rem each row splits: the label, name and
   summary on the left, the details and next step on the right, so the offer
   name stays the scan anchor and the reader meets one offer at a time.
   Below 60rem everything stacks. One border style, no cards. */
.services .services__header { margin-bottom: var(--space-5); }
/* One section recipe: eyebrow -> h2 is 16px here, in the hero and in About. */
.services .services__title > * + * { margin-top: var(--space-4); }
@media (min-width: 60rem) {
  /* h2 left, lede right, on the page's split grid: the lede starts on the
     same line as the offers' detail column below it. */
  .services .services__header {
    display: grid;
    grid-template-columns: var(--split-columns);
    column-gap: var(--split-gap);
    align-items: end;
    max-width: none;
  }
}

.services__list {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
}

.services .offer {
  display: grid;
  grid-template-columns: minmax(0, var(--measure));
  align-content: start;
  padding-block: var(--space-5) var(--space-7);
  border-top: var(--border);
}
.services .offer:last-child { padding-bottom: 0; }

@media (min-width: 60rem) {
  /* One row per offer: identity left, detail right. The rule between rows is
     the only separator; the columns inside a row share one baseline. */
  .services .offer {
    grid-template-columns: var(--split-columns);
    /* status + name rows hug their content; the detail column's extra height
       lands in the summary row, so every name sits the same 8px under its chip */
    grid-template-rows: auto auto 1fr;
    column-gap: var(--split-gap);
    align-items: start;
  }
  .services .offer__status,
  .services .offer__name,
  .services .offer__summary { grid-column: 1; }
  .services .offer__facts--lead,
  .services .offer__tail {
    grid-column: 2;
    grid-row: span 3;
  }
  .services .offer__facts--lead { grid-row: 1 / span 3; margin-top: 0; }
  .services .offer__tail { grid-row: 4; }
  /* Detail columns read as two stacked groups, not a wall of text. */
  .services .offer__facts--lead > div:first-child { padding-top: 0; }
}

/* Availability: sentence case; the words carry the meaning, fill reinforces. */
.services .offer__status {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-1) var(--space-3);
  font-size: var(--text-small);
  line-height: var(--leading-small);
}
.services .offer__badge {
  padding: 0 var(--space-2);
  border: var(--border);
  border-radius: var(--radius-sm);
  font-weight: var(--weight-semibold);
  color: var(--color-ink-2);
}
.services .offer__badge--open {
  background: var(--color-accent-soft);
  border-color: transparent;
  color: var(--color-ink);
}
.services .offer__hint { color: var(--color-ink-3); }

/* The offer name is the scan anchor. Flat 24px, not the lede clamp: at 390
   the clamp fell to 20px and the name collapsed into the 18px summary
   (1.11). Flat 1.5rem holds name:summary = 24/18 = 1.33 at every width,
   and is byte-identical to the lede at 1440, so desktop is unchanged.
   The chip sits 8px above it: chip + name read as one landmark. */
.services .offer__name {
  margin-top: var(--space-2);
  font-size: 1.5rem;
  line-height: var(--leading-h3);
  letter-spacing: var(--tracking-title);
  font-weight: var(--weight-semibold);
}
.services .offer__summary {
  margin-top: var(--space-2);
  color: var(--color-ink-3);
}

/* Details: small, tight, labelled. The three fact groups keep one constant
   16px gap; the summary -> facts boundary is the bigger tier change, so it
   opens wider at 24px. */
.services .offer__facts {
  display: grid;
  font-size: var(--text-small);
  line-height: var(--leading-small);
}
.services .offer__facts--lead { margin-top: var(--space-5); }
/* Row layout: the detail column starts on the badge line. Declared after the
   base rule above, or the 24px stacked gap wins and the columns misalign. */
@media (min-width: 60rem) {
  .services .offer__facts--lead { margin-top: 0; }
}
.services .offer__facts > div { padding-top: var(--space-4); }
.services .offer__facts--lead > div:first-child { padding-top: 0; }
.services .offer__facts dt {
  font-weight: var(--weight-semibold);
  color: var(--color-ink);
}
.services .offer__facts dd { margin: var(--space-1) 0 0; }

.services .offer__bullets > li {
  position: relative;
  padding-left: var(--space-4);
}
.services .offer__bullets > li + li { margin-top: 0; }
.services .offer__bullets > li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.7em;
  width: 6px;
  height: 1px;
  background: var(--color-ink-3);
}

.services .offer__action {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-1) var(--space-4);
  margin-top: var(--space-4);
}
.services .offer__link {
  display: inline-flex;
  align-items: center;
  min-height: var(--control-height);
  font-weight: var(--weight-semibold);
}
.services .offer__note {
  font-size: var(--text-small);
  line-height: var(--leading-small);
  color: var(--color-ink-3);
}

/* Stacked, the label rides in on the same line as its fact: three fewer
   label lines per offer brings the whole first offer — including its next
   step — inside the 390x844 fold. At >=60rem the labels go back to their
   own line so the For / Not for / You get rows can align across columns. */
@media (max-width: 59.999rem) {
  .services .offer__facts dt,
  .services .offer__facts dd { display: inline; }
  .services .offer__facts dd { margin: 0; }
  .services .offer__facts dd:has(.offer__bullets) {
    display: block;
    margin-top: var(--space-1);
  }
}

/* 40-about.css */
/* About — two columns with aligned tops: the point of view (h2) left,
   the story that earns it right. */
.about .about__eyebrow { margin-bottom: var(--space-4); }

.about__grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-7);
}
.about__col {
  display: flex;
  flex-direction: column;
  align-items: start;
  gap: var(--space-6);
}
/* Story is load-bearing credibility copy: body tier. */
.about__story { color: var(--color-ink-2); }
.about__punch { color: var(--color-ink); font-weight: var(--weight-semibold); }

@media (min-width: 60rem) {
  .about__grid {
    grid-template-columns: var(--split-columns);
    column-gap: var(--split-gap);
    align-items: start;
  }
  /* optical top alignment: the story's first line sits on the h2 cap line */
  .about__col--story { padding-top: var(--space-1); }
}

/* 50-contact.css */
/* Contact — closing note. Reading order is the same at every width:
   h2 -> letter -> signature -> Book a call -> availability -> waitlists.
   At >=60rem the h2 and the letter share a row and the availability +
   waitlists close the section as a full-width band under the button, so the
   two reasons a reader may not be able to hire Alex never precede the ask. */

.contact__grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  grid-template-areas: "title" "note" "actions" "aside";
  row-gap: var(--space-5);
}
.contact__title { grid-area: title; max-width: var(--measure); }

.contact__note {
  grid-area: note;
  max-width: var(--measure);
  color: var(--color-ink-2);
}
.contact__note > * + * { margin-top: var(--space-4); }
.contact__sign {
  font-weight: var(--weight-semibold);
  color: var(--color-ink);
}
/* standalone text links: full 44px target (WCAG 2.5.8), no inline-link exception */
.contact__sign a,
.contact__link {
  display: inline-flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0 0.35em;
  min-height: var(--control-height);
}
/* same action, same weight as the Services waitlist links (.offer__link) */
.contact__link { font-weight: var(--weight-semibold); }
.contact__note > .contact__sign { margin-top: var(--space-5); }

.contact__aside {
  grid-area: aside;
  align-self: start;
  max-width: var(--measure);
}
.contact__availability { color: var(--color-ink-2); }
.contact__waitlists {
  list-style: none;
  margin: var(--space-5) 0 0;
  padding: 0;
  display: grid;
  justify-items: start;
}
.contact__waitlists li {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-1) var(--space-4);
}
/* same helper treatment as Services: its own muted small line */
.contact__opens,
.contact__helper {
  font-size: var(--text-small);
  line-height: var(--leading-small);
  color: var(--color-ink-3);
}

.contact__actions {
  grid-area: actions;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-4) var(--space-5);
}

@media (min-width: 60rem) {
  .contact__grid {
    grid-template-columns: var(--split-columns);
    grid-template-areas: "title note" ". actions" "aside aside";
    column-gap: var(--split-gap);
    row-gap: var(--space-6);
    align-items: start;
  }
  .contact__actions { margin-top: var(--space-2); }

  /* closing band: availability left, both waitlists right, one row */
  .contact__aside {
    max-width: none;
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    align-items: baseline;
    gap: var(--space-4) var(--space-10);
    margin-top: var(--space-4);
    padding-top: var(--space-6);
    border-top: var(--border);
  }
  .contact__availability { max-width: var(--measure); }
  .contact__waitlists {
    margin: 0;
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: var(--space-4) var(--space-8);
  }
}

/* 80-legal.css */
/* Legal pages: /privacy/ and 404. Tokens + base classes only. */

.legal__header {
  display: flex;
  flex-direction: column;
  gap: var(--space-6);
  max-width: var(--measure);
  padding-top: calc(var(--hero-pad-top) - var(--section-pad));
}
.legal__header > .eyebrow + .legal__title { margin-top: calc(-1 * var(--space-4)); }

.legal__meta {
  font-size: var(--text-small);
  line-height: var(--leading-small);
  color: var(--color-ink-3);
}

/* Section headings: h3 scale. A legal doc with 48px h2s shouts. */
.legal h2 {
  font-size: var(--text-h3);
  line-height: var(--leading-h3);
  letter-spacing: var(--tracking-title);
  font-weight: var(--weight-semibold);
}

/* The short version */
.legal__summary {
  max-width: var(--measure);
  margin-top: var(--space-9);
  padding: var(--space-6);
  background: var(--color-accent-wash);
  border-radius: var(--radius-sm);
}
.legal__summary h2 { margin-bottom: var(--space-4); }

.legal ul { padding-left: 1.25em; }
.legal li + li { margin-top: var(--space-2); }
.legal li::marker { color: var(--color-ink-3); }

/* Details */
.legal__body { margin-top: var(--space-9); }
.legal__body > h2 { margin-top: var(--space-8); }
.legal__body > h2:first-child { margin-top: 0; }
.legal__body > h2 + * { margin-top: var(--space-3); }
.legal__body > p + ul,
.legal__body > ul + p { margin-top: var(--space-4); }

/* 404 */
.legal--404 { min-height: calc(100vh - var(--nav-height) - 12rem); }
.legal__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-5) var(--space-6);
  margin-top: var(--space-7);
}
.legal--404 .legal__meta { margin-top: var(--space-8); max-width: var(--measure); }

@media (max-width: 30em) {
  .legal__summary { padding: var(--space-5); margin-inline: calc(-1 * var(--space-2)); }
}

/* Privacy: the reading column sits centered on the page; text stays left-aligned. */
.legal:not(.legal--404) .legal__header,
.legal:not(.legal--404) .legal__summary,
.legal:not(.legal--404) .legal__body {
  max-width: var(--measure);
  margin-inline: auto;
}
@media (max-width: 30em) {
  .legal:not(.legal--404) .legal__summary { margin-inline: calc(-1 * var(--space-2)); }
}

/* 90-footer.css */
/* Footer — shared on every page. */
.site-footer {
  border-top: var(--border);
  padding-block: var(--space-9);
  font-size: var(--text-small);
  line-height: var(--leading-small);
  color: var(--color-ink-3);
}
.site-footer__inner {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-5);
}
.site-footer__name { color: var(--color-ink); font-weight: var(--weight-semibold); }
.site-footer__links {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-1) var(--space-5);
}
.site-footer__links a {
  display: inline-flex;
  align-items: center;
  min-height: var(--control-height);
  color: var(--color-ink-2);
}
.site-footer__links a:hover { color: var(--color-ink); }
@media (min-width: 60rem) {
  .site-footer__inner {
    grid-template-columns: auto 1fr auto;
    align-items: center;
    gap: var(--space-8);
  }
  .site-footer__links { justify-content: center; }
}
