/* ==========================================================================
   Aaron Buat Kinesiology
   Single-page site. Static HTML / CSS / vanilla JS, no build step.

   Order of this file:
     1. Fonts
     2. Tokens
     3. Reset + base
     4. Layout primitives
     6. Header + nav
     7. Sections, top to bottom
     8. Forms
     9. Footer
    10. Motion + reduced motion
   ========================================================================== */

/* 1. Fonts ---------------------------------------------------------------- */
/* Two variable files, latin subset, self hosted. Archivo carries a width axis
   which is what gives the display type its athletic, slightly expanded feel. */

@font-face {
  font-family: 'Archivo';
  src: url('../fonts/archivo-var-latin.woff2') format('woff2-variations');
  font-weight: 400 700;
  font-stretch: 100% 125%;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: 'Public Sans';
  src: url('../fonts/publicsans-var-latin.woff2') format('woff2-variations');
  font-weight: 400 700;
  font-style: normal;
  font-display: swap;
}

/* 2. Tokens --------------------------------------------------------------- */

:root {
  --ink:        #0F1B2D;  /* body text, headings. Deep navy black */
  --ink-muted:  #47586F;  /* secondary text, captions. Blue grey */
  --canvas:     #F5F7FA;  /* page background. Soft off-white, faint blue cast */
  --surface:    #E6EDF6;  /* cards, alternating bands. Light blue grey */
  --line:       #CBD8E8;  /* hairlines, dividers, input borders */
  --navy:       #16325C;  /* PRIMARY. Dark band, buttons, wordmark */
  --steel:      #3E72B8;  /* SECONDARY, non-text only: icons, rules */
  --signal:     #2A6FD6;  /* ACCENT. Used on light backgrounds */

  /* Four derived values, each with one job.

     The palette is monochromatic on purpose. The accent sits inside the blue
     family rather than opposite it, so there is no second hue to fight: the
     hero underline, the focus ring and the active nav marker are all the same
     bright blue, and contrast alone separates them from the text.

     Measured ratios (sRGB, WCAG 2.x), computed rather than estimated:
       --ink        on --canvas   16.1:1
       --ink        on --surface  14.7:1
       --ink-muted  on --canvas    6.8:1
       --ink-muted  on --surface   6.2:1
       --steel-ink  on --canvas    6.7:1
       --steel-ink  on --surface   6.1:1
       --canvas     on --navy     11.9:1
       --mist       on --navy      7.2:1
       --sky        on --navy      6.1:1
       --signal     on --canvas    4.5:1
       --steel      on --canvas    4.6:1  (non-text, needs 3:1)
       --alert      on --canvas    5.6:1

     --steel measures 4.14:1 on --surface, which misses AA for body sized text,
     so anything blue carrying words uses --steel-ink. --steel keeps the
     lighter value for icons and rules, where 3:1 applies and it passes.
     --signal is the reverse case: bright enough to read as a highlight on the
     canvas, too dark to sit on --navy, so the dark band uses --sky instead. */
  --steel-ink:  #2C5892;  /* --steel, darkened to carry text */
  --sky:        #8FB7E8;  /* the accent's counterpart inside the dark band */
  --mist:       #AFC4DE;  /* secondary text inside the dark band */

  /* Form errors need a colour that reads as wrong and the palette has no red.
     Used only for invalid field text and borders. 5.6:1 on --canvas. */
  --alert:      #B03A2B;

  --font-display: 'Archivo', 'Helvetica Neue', Arial, sans-serif;
  --font-body: 'Public Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', Arial, sans-serif;

  --measure: 68ch;
  --gutter: 1.25rem;
  --radius: 4px;
  --shadow-card: 0 1px 2px rgb(15 27 45 / 0.04), 0 6px 18px -10px rgb(15 27 45 / 0.16);

  --header-h: 68px;
}

/* 3. Reset + base --------------------------------------------------------- */

*, *::before, *::after { box-sizing: border-box; }

/* Any display value in this file outranks the browser default for [hidden],
   which would otherwise leave the contact form on screen next to its own
   success message. */
[hidden] { display: none !important; }

html {
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--header-h) + 12px);
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  background: var(--canvas);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 1.0625rem;
  line-height: 1.65;
  font-synthesis-weight: none;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4 {
  font-family: var(--font-display);
  letter-spacing: -0.02em;
  line-height: 1.1;
  margin: 0 0 0.5em;
  font-weight: 700;
  font-stretch: 112%;
  text-wrap: balance;
}

p { margin: 0 0 1em; max-width: var(--measure); }
p:last-child { margin-bottom: 0; }

ul, ol { margin: 0 0 1em; padding-left: 1.25em; }
li { margin-bottom: 0.4em; max-width: var(--measure); }

a { color: var(--steel-ink); text-underline-offset: 0.18em; text-decoration-thickness: 1px; }
a:hover { color: var(--navy); }

img, svg { max-width: 100%; height: auto; display: block; }

strong { font-weight: 700; }

/* Focus. The spec asks for a --signal ring. On the warm canvas --signal alone
   sits at roughly 2:1, so it is paired with a --navy outer ring to keep the
   indicator visible on every background the site uses. */
:focus-visible {
  outline: 2px solid var(--signal);
  outline-offset: 2px;
  box-shadow: 0 0 0 4px rgb(22 50 92 / 0.45);
  border-radius: 2px;
}

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 100;
  background: var(--navy);
  color: var(--canvas);
  padding: 0.75rem 1rem;
  font-family: var(--font-display);
  font-weight: 700;
  text-decoration: none;
}
.skip-link:focus { left: 0.5rem; top: 0.5rem; }

.visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* 4. Layout primitives ---------------------------------------------------- */

.wrap {
  width: 100%;
  max-width: 1200px;
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.section { padding-block: clamp(3.25rem, 7vw, 6rem); }
.section--surface { background: var(--surface); }

.eyebrow {
  font-family: var(--font-display);
  font-size: 0.8125rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--steel-ink);
  margin: 0 0 0.9rem;
}

.section-head { max-width: 46rem; margin-bottom: clamp(1.75rem, 3vw, 2.75rem); }
.section-head h2 { font-size: clamp(1.75rem, 3.5vw, 2.75rem); }
.section-head p { color: var(--ink-muted); font-size: 1.0625rem; }
.section-head .lede { font-size: 1.125rem; }   /* .lede alone loses to the line above */

.lede { font-size: 1.125rem; }

/* Buttons ---------------------------------------------------------------- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  min-height: 48px;
  padding: 0.75rem 1.4rem;
  font-family: var(--font-display);
  font-size: 1rem;
  font-weight: 700;
  font-stretch: 108%;
  letter-spacing: -0.01em;
  text-decoration: none;
  border: 1px solid transparent;
  border-radius: var(--radius);
  cursor: pointer;
  transition: background-color 140ms ease, color 140ms ease, border-color 140ms ease;
}

.btn--primary { background: var(--navy); color: var(--canvas); }
.btn--primary:hover {
  background: #27508A;
  background: color-mix(in srgb, var(--navy) 86%, var(--canvas));
  color: var(--canvas);
}

.btn--ghost { background: transparent; color: var(--navy); border-color: var(--line); }
.btn--ghost:hover { border-color: var(--navy); background: var(--surface); color: var(--navy); }

.btn--onnavy { background: var(--canvas); color: var(--navy); }
.btn--onnavy:hover {
  background: #D5DCE6;
  background: color-mix(in srgb, var(--canvas) 88%, var(--navy));
  color: var(--navy);
}

.btn--ghost-onnavy { background: transparent; color: var(--canvas); border-color: rgb(245 247 250 / 0.35); }
.btn--ghost-onnavy:hover { border-color: var(--canvas); color: var(--canvas); }

/* Inline link that behaves like a call to action inside a card */
.arrow-link {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  min-height: 44px;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 0.9375rem;
  text-decoration: none;
  color: var(--navy);
}
.arrow-link svg { transition: transform 160ms ease; }
.arrow-link:hover svg { transform: translateX(3px); }
.arrow-link:hover { text-decoration: underline; }

/* 6. Header --------------------------------------------------------------- */

.site-header {
  position: sticky;
  top: 0;
  z-index: 50;
  background: var(--canvas);
  border-bottom: 1px solid transparent;
  transition: border-color 160ms ease;
}
.site-header.is-stuck { border-bottom-color: var(--line); }

.site-header__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  min-height: var(--header-h);
}

.wordmark {
  display: inline-flex;
  align-items: center;
  gap: 0.625rem;
  text-decoration: none;
  color: var(--ink);
  padding-block: 0.5rem;
}
.wordmark__mark { flex: none; }
.wordmark__text { display: block; line-height: 1.05; }
.wordmark__name {
  display: block;
  font-family: var(--font-display);
  font-weight: 700;
  font-stretch: 118%;
  font-size: 1.0625rem;
  letter-spacing: -0.015em;
  text-transform: uppercase;
  white-space: nowrap;
}
.wordmark__role {
  display: block;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 0.625rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--steel-ink);
  margin-top: 2px;
}

.nav-toggle {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  min-height: 44px;
  min-width: 44px;
  padding: 0 0.75rem;
  background: transparent;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 0.8125rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink);
  cursor: pointer;
}
.nav-toggle__bars { display: block; width: 16px; height: 10px; position: relative; }
.nav-toggle__bars::before,
.nav-toggle__bars::after {
  content: '';
  position: absolute;
  left: 0; right: 0;
  height: 1.5px;
  background: var(--ink);
  transition: transform 160ms ease, top 160ms ease, bottom 160ms ease;
}
.nav-toggle__bars::before { top: 0; }
.nav-toggle__bars::after { bottom: 0; }
.nav-toggle[aria-expanded='true'] .nav-toggle__bars::before { top: 4px; transform: rotate(45deg); }
.nav-toggle[aria-expanded='true'] .nav-toggle__bars::after { bottom: 4px; transform: rotate(-45deg); }

.nav {
  display: none;
  position: absolute;
  left: 0; right: 0;
  top: 100%;
  background: var(--canvas);
  border-block: 1px solid var(--line);
  padding: 0.5rem var(--gutter) 1.25rem;
}
.nav.is-open { display: block; }
.nav__list { list-style: none; margin: 0; padding: 0; }
.nav__list a {
  display: flex;
  align-items: center;
  min-height: 48px;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 1rem;
  color: var(--ink);
  text-decoration: none;
  border-bottom: 1px solid var(--line);
}
.nav__list a:hover { color: var(--steel-ink); }
.nav .btn { width: 100%; margin-top: 1rem; }

.header-cta { display: none; white-space: nowrap; }

/* 7. Sections ------------------------------------------------------------- */

/* Hero -------------------------------------------------------------------- */

.hero {
  padding-top: clamp(2.5rem, 6vw, 4.5rem);
  padding-bottom: clamp(2.5rem, 5vw, 4rem);
}

.hero__grid { display: grid; gap: clamp(2rem, 5vw, 3.5rem); align-items: center; }

/* Sized so the headline holds to two lines from 900px up. Check this if the
   wording ever changes. */
.hero h1 {
  font-size: clamp(2.25rem, 5.6vw, 4.25rem);
  margin-bottom: 0.6rem;
  max-width: 17ch;
}

/* Ochre underline on the key phrase. One of the three permitted uses. */
.mark {
  background-image: linear-gradient(var(--signal), var(--signal));
  background-repeat: no-repeat;
  background-size: 100% 0.12em;
  background-position: 0 92%;
  padding-bottom: 0.04em;
}

.hero__sub {
  font-size: clamp(1.0625rem, 1.6vw, 1.25rem);
  color: var(--ink-muted);
  max-width: 46ch;
  margin-bottom: 1.75rem;
}

/* Stacked and full width on phones so both actions read as equal weight and
   the tap targets are as large as the column allows. */
.hero__actions { display: grid; gap: 0.75rem; margin-bottom: 2rem; }

.trust {
  list-style: none;
  margin: 0;
  padding: 1.1rem 0 0;
  border-top: 1px solid var(--line);
  display: grid;
  grid-template-columns: 1fr;
  gap: 0.5rem 1.5rem;
  font-family: var(--font-display);
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  color: var(--ink-muted);
  text-transform: uppercase;
  max-width: none;
}
.trust li { display: flex; align-items: center; gap: 0.5rem; margin: 0; max-width: none; }
.trust li::before {
  content: '';
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--steel);
  flex: none;
}

/* Hero portrait. Kept dark and graded toward navy so it reads as part of the
   palette. The thin frame line is what keeps it from floating. */
.portrait {
  position: relative;
  margin: 0;
  isolation: isolate;
}
.portrait__img {
  width: 100%;
  border-radius: var(--radius);
  background: var(--navy);
  display: block;
}
.portrait--hero { max-width: 26rem; margin-inline: auto; }
/* A single hairline frame, offset down and right, sitting behind the photo.
   The only depth cue on the page apart from the card elevation. */
.portrait--hero::after {
  content: '';
  position: absolute;
  inset: 14px -14px -14px 14px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  z-index: -1;
}

/* Path fork --------------------------------------------------------------- */

.fork__grid {
  display: grid;
  gap: 1.25rem;
  grid-template-columns: 1fr;
}

.path-card {
  position: relative;
  display: flex;
  flex-direction: column;
  background: var(--canvas);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: clamp(1.5rem, 3vw, 2.25rem);
  box-shadow: var(--shadow-card);
}
.section--surface .path-card { background: var(--canvas); }
.path-card h3 { font-size: clamp(1.375rem, 2.4vw, 1.75rem); margin-bottom: 0.5rem; }
.path-card p { color: var(--ink-muted); }
.path-card__body { flex: 1; }
.path-card__meta {
  margin-top: 1rem;
  font-family: var(--font-display);
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--steel-ink);
}
.path-card .arrow-link { margin-top: 1rem; }

/* What a kinesiologist does ----------------------------------------------- */

/* Three roles, two weights. The physiotherapist and the personal trainer are
   context, so they stay hairline rules and muted text. The kinesiologist is the
   answer, so it gets the fill, the room and the closing line. Mobile stacks
   them in DOM order, context first, answer last. */

.compare { margin: 0; padding: 0; display: grid; gap: 0; }

.compare__row {
  border-top: 1px solid var(--line);
  padding: 1.15rem 0 1.35rem;
}
.compare__row dt {
  font-family: var(--font-display);
  font-weight: 700;
  font-stretch: 110%;
  font-size: 1rem;
  margin-bottom: 0.15rem;
}
.compare__row dd {
  margin: 0;
  color: var(--ink-muted);
  max-width: 60ch;
}
/* Closes the context pair off, so it reads as a bounded list rather than two
   rules trailing away. */
.compare__row:nth-child(2) { border-bottom: 1px solid var(--line); }

/* The answer */
.compare__row--mine {
  /* Stacked, the answer needs air between it and the pair above. On desktop it
     sits in its own column and the gap belongs to the grid instead. */
  margin-top: clamp(1.25rem, 4vw, 1.75rem);
  background: var(--surface);
  border-top: 2px solid var(--steel);
  border-radius: 0 0 var(--radius) var(--radius);
  padding: clamp(1.5rem, 3vw, 2.25rem);
}
.section--surface .compare__row--mine { background: var(--canvas); }
.compare__row--mine dt {
  font-size: clamp(1.25rem, 2vw, 1.5rem);
  color: var(--steel-ink);
  margin-bottom: 0.6rem;
}
.compare__row--mine dd { color: var(--ink); max-width: 54ch; }
.compare__row--mine dd p { margin: 0; max-width: none; }

.compare__punch {
  margin-top: 1.3rem !important;
  padding-top: 1.3rem;
  border-top: 1px solid var(--line);
  font-family: var(--font-display);
  font-weight: 600;
  font-stretch: 106%;
  font-size: clamp(1.0625rem, 1.5vw, 1.3125rem);
  line-height: 1.34;
  letter-spacing: -0.015em;
  color: var(--ink);
}

/* Services ---------------------------------------------------------------- */

/* Plain grid, hairline per item. No numbering: these are five things he does,
   not five steps in a sequence. */
.services__grid { display: grid; gap: 0 clamp(1.5rem, 3.5vw, 3rem); }
.service {
  border-top: 1px solid var(--line);
  padding: clamp(1.35rem, 2.5vw, 1.75rem) 0 clamp(1.5rem, 3vw, 2.25rem);
}
.service h3 { font-size: 1.25rem; font-weight: 600; margin-bottom: 0.4rem; }
.service p { color: var(--ink-muted); margin: 0; font-size: 1rem; }
.service__icon { margin-bottom: 0.9rem; }

/* About ------------------------------------------------------------------- */

.about__grid { display: grid; gap: clamp(2rem, 5vw, 3.5rem); align-items: start; }

.creds { list-style: none; margin: 1.75rem 0 0; padding: 0; display: grid; gap: 0; }
.creds li {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 0.5rem 1rem;
  align-items: baseline;
  padding: 0.85rem 0;
  border-top: 1px solid var(--line);
  margin: 0;
  max-width: none;
}
.creds li:last-child { border-bottom: 1px solid var(--line); }
.creds__label { color: var(--ink-muted); font-size: 0.9375rem; }
.creds__value {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 0.9375rem;
  text-align: right;
}

/* Reviews ----------------------------------------------------------------- */

.reviews__grid { display: grid; gap: 1.25rem; }
.review {
  background: var(--canvas);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: clamp(1.25rem, 3vw, 1.75rem);
  margin: 0;
}
.review blockquote { margin: 0 0 1rem; }
.review p { color: var(--ink); }
.review figcaption {
  font-family: var(--font-display);
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-muted);
}

/* Locations --------------------------------------------------------------- */

/* Two groups, two treatments, one shared label style so it is obvious they are
   peers answering the same question. */

.places { display: grid; gap: clamp(1.75rem, 4vw, 3rem); align-items: start; }

.places__label {
  font-family: var(--font-display);
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--steel-ink);
  margin: 0 0 0.9rem;
}

/* The gyms are places, so they sit together in one object rather than four. */
.places__gyms {
  background: var(--surface);
  border-radius: var(--radius);
  padding: clamp(1.35rem, 3vw, 1.85rem);
}
.section--surface .places__gyms { background: var(--canvas); }

.gym-list { list-style: none; margin: 0; padding: 0; }

/* Name and label share a row, address sits under both. The label is pinned to
   the row rather than stacked under the name, so a long name wrapping to two
   lines cannot knock its own label out of line with the others. */
.gym {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  column-gap: 1rem;
  align-items: center;
  padding-bottom: 0.7rem;
  margin: 0;
  max-width: none;
  border-bottom: 1px solid var(--line);
}
.gym:last-child { padding-bottom: 0; border-bottom: 0; }

.gym__name {
  grid-column: 1;
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  min-height: 44px;
  font-family: var(--font-display);
  font-weight: 700;
  font-stretch: 108%;
  font-size: 1.0625rem;
  line-height: 1.25;
  color: var(--ink);
  text-decoration: none;
}
/* The arrow is bound to the last word by .gym__tail, so it always hugs the
   name however the name wraps. */
.gym__tail { white-space: nowrap; }
.gym__ext {
  display: inline-block;
  margin-left: 0.35rem;
  vertical-align: baseline;
  color: var(--steel-ink);
}
.gym__name:hover { color: var(--steel-ink); }
.gym__name:hover .gym__label { text-decoration: underline; text-underline-offset: 0.2em; }

.gym__note {
  grid-column: 2;
  justify-self: end;
  font-family: var(--font-display);
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--steel-ink);
  white-space: nowrap;
}

.gym__address {
  grid-column: 1 / -1;
  margin: 0;
  color: var(--ink-muted);
  font-size: 0.9375rem;
  max-width: none;
}

/* The come-to-you options are ways of working, not places, so they stay plain. */
.reach-list { margin: 0; padding: 0; }
.reach-list__row {
  border-top: 1px solid var(--line);
  padding: 0.95rem 0 1.1rem;
}
.reach-list__row:last-child { border-bottom: 1px solid var(--line); }
.reach-list dt {
  font-family: var(--font-display);
  font-weight: 700;
  font-stretch: 108%;
  font-size: 1.0625rem;
  margin-bottom: 0.1rem;
}
.reach-list dd { margin: 0; color: var(--ink-muted); font-size: 0.9375rem; max-width: 52ch; }

/* Service area is a qualifier on both groups, not a third peer. */
.places__area {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.4rem 0.9rem;
  margin: clamp(1.75rem, 4vw, 2.5rem) 0 0;
  padding-top: 1.1rem;
  border-top: 1px solid var(--line);
  max-width: none;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1rem;
  color: var(--ink);
}
.places__area-label {
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-muted);
}

/* For referring practitioners --------------------------------------------- */

.referrers {
  background: var(--navy);
  color: var(--canvas);
}
.referrers .eyebrow { color: var(--sky); }
.referrers h2 { color: var(--canvas); font-size: clamp(1.75rem, 3.5vw, 2.75rem); }
.referrers p { color: var(--mist); }
/* Scoped to prose links so it does not outrank the button colours below. */
.referrers p a, .referrers li a { color: var(--canvas); }
.referrers__grid { display: grid; gap: clamp(2rem, 4vw, 3rem); }
.referrers h3 {
  color: var(--canvas);
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  margin-bottom: 0.9rem;
  padding-bottom: 0.6rem;
  border-bottom: 1px solid rgb(245 247 250 / 0.22);
}
.referrers ul { list-style: none; padding: 0; margin: 0; }
.referrers ul li {
  color: var(--mist);
  padding-left: 1.1rem;
  position: relative;
  font-size: 0.9375rem;
}
.referrers ul li::before {
  content: '';
  position: absolute;
  left: 0; top: 0.66em;
  width: 5px; height: 5px;
  border-radius: 50%;
  background: var(--sky);
}
.refer-steps { counter-reset: step; list-style: none; padding: 0; margin: 0; }
.refer-steps li {
  counter-increment: step;
  position: relative;
  padding-left: 2rem;
  color: var(--mist);
  font-size: 0.9375rem;
  margin-bottom: 0.7rem;
}
.refer-steps li::before {
  content: counter(step);
  position: absolute;
  left: 0; top: 0;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 0.8125rem;
  color: var(--sky);
  border: 1px solid rgb(143 183 232 / 0.55);
  border-radius: 50%;
  width: 1.35rem; height: 1.35rem;
  display: grid;
  place-items: center;
  line-height: 1;
}
.referrers__contact { display: flex; flex-wrap: wrap; gap: 0.75rem; margin-top: 1.75rem; }

/* Contact ----------------------------------------------------------------- */

.contact__grid { display: grid; gap: clamp(2rem, 5vw, 3.5rem); align-items: start; }

.contact-details { list-style: none; margin: 0; padding: 0; }
.contact-details li { padding: 1rem 0; border-top: 1px solid var(--line); margin: 0; max-width: none; }
.contact-details li:last-child { border-bottom: 1px solid var(--line); }
.contact-details dt,
.contact-details__label {
  font-family: var(--font-display);
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-muted);
  margin-bottom: 0.2rem;
}
.contact-details__value {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.0625rem;
}
.contact-details a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  color: var(--navy);
  text-decoration-color: var(--line);
}
.contact-details a:hover { text-decoration-color: currentColor; }

/* 8. Forms ---------------------------------------------------------------- */

.form { display: grid; gap: 1.1rem; }
.field { display: grid; gap: 0.35rem; align-content: start; }
.field label {
  font-family: var(--font-display);
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink);
}
.field .hint { font-size: 0.8125rem; color: var(--ink-muted); margin: 0; }

.field input,
.field select,
.field textarea {
  width: 100%;
  min-height: 48px;
  padding: 0.7rem 0.85rem;
  font-family: var(--font-body);
  font-size: 1rem;
  color: var(--ink);
  background: var(--canvas);
  border: 1px solid var(--line);
  border-radius: var(--radius);
}

/* Placeholders carry the message field's hint, so they have to be readable.
   --ink-muted measures 6.8:1 on --canvas rather than the browser default grey. */
.field ::placeholder { color: var(--ink-muted); opacity: 1; }

/* The platform draws its own dropdown arrow hard against the right edge and
   gives no way to space it. Drawing our own puts that back under our control. */
.field select {
  appearance: none;
  -webkit-appearance: none;
  padding-right: 2.9rem;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='13' height='8' viewBox='0 0 13 8' fill='none'%3E%3Cpath d='M1.25 1.5 6.5 6.5l5.25-5' stroke='%232C5892' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 1.1rem center;
}
.field textarea { min-height: 8.5rem; resize: vertical; line-height: 1.55; }
.field input:hover,
.field select:hover,
.field textarea:hover { border-color: var(--ink-muted); }

/* The open option list is drawn by the operating system on a classic select and
   cannot be styled at all. Chrome 135 and up expose it through
   appearance: base-select, so where that exists the list gets real padding and
   the site's own colours. Everywhere else the native control is kept, which is
   the accessible fallback rather than a compromise. */
@supports (appearance: base-select) {
  .field select {
    appearance: base-select;
    background-image: none;
    padding-right: 1.1rem;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    text-align: left;
  }
  .field select::picker-icon {
    color: var(--steel-ink);
    transition: transform 160ms ease;
  }
  .field select:open::picker-icon { transform: rotate(180deg); }

  .field select::picker(select) {
    appearance: base-select;
    margin-top: 0.3rem;
    padding: 0.35rem;
    background: var(--canvas);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    box-shadow: var(--shadow-card);
  }
  .field select option {
    padding: 0.7rem 0.85rem;
    border-radius: 2px;
    font-family: var(--font-body);
    font-size: 1rem;
    line-height: 1.4;
    color: var(--ink);
  }
  .field select option:hover { background: var(--surface); }
  .field select option:checked { color: var(--steel-ink); font-weight: 600; }
  .field select option::checkmark { color: var(--steel-ink); }
}

.field .error {
  font-size: 0.875rem;
  color: var(--alert);
  margin: 0;
  font-weight: 600;
}
.field.has-error input,
.field.has-error select,
.field.has-error textarea { border-color: var(--alert); border-width: 2px; }

.hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

.form__footer { display: flex; flex-wrap: wrap; align-items: center; gap: 1rem; }

.form-status { margin: 0; font-size: 0.9375rem; }
.form-status[data-state='error'] { color: var(--alert); font-weight: 600; }

.form-success {
  border: 1px solid var(--steel);
  border-left-width: 3px;
  border-radius: var(--radius);
  background: var(--canvas);
  padding: 1.25rem 1.35rem;
}
.form-success h3 { font-size: 1.125rem; margin-bottom: 0.35rem; }
.form-success p { color: var(--ink-muted); margin: 0; }

/* 9. Footer --------------------------------------------------------------- */

.site-footer {
  background: var(--surface);
  padding-block: clamp(2.5rem, 5vw, 3.5rem);
  border-top: 1px solid var(--line);
}
.site-footer__grid { display: grid; gap: 2rem; }
.site-footer p, .site-footer address {
  font-style: normal;
  color: var(--ink-muted);
  font-size: 0.9375rem;
  margin: 0 0 0.4rem;
}
.site-footer a { color: var(--navy); }
.site-footer address a { display: inline-flex; align-items: center; min-height: 44px; }
.site-footer h2 {
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-muted);
  margin-bottom: 0.7rem;
}
.footer-nav { list-style: none; margin: 0; padding: 0; }
.footer-nav li { margin-bottom: 0.15rem; }
.footer-nav a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  font-size: 0.9375rem;
  text-decoration: none;
}
.footer-nav a:hover { text-decoration: underline; }
.colophon {
  margin-top: 2.25rem;
  padding-top: 1.25rem;
  border-top: 1px solid var(--line);
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1.5rem;
  font-size: 0.8125rem;
  color: var(--ink-muted);
}

/* 10. Breakpoints --------------------------------------------------------- */

@media (min-width: 520px) {
  /* Four claims, always two even rows, never one orphan on a second line. */
  .trust { grid-template-columns: 1fr 1fr; }
  .hero__actions { display: flex; flex-wrap: wrap; }
}

@media (min-width: 640px) {
  :root { --gutter: 2rem; }

  .fork__grid { grid-template-columns: 1fr 1fr; }
  .services__grid { grid-template-columns: 1fr 1fr; }
  .reviews__grid { grid-template-columns: 1fr 1fr; }
  .form__row { display: grid; grid-template-columns: 1fr 1fr; gap: 1.1rem; }
  .site-footer__grid { grid-template-columns: 1.4fr 1fr 1fr; }
}

@media (min-width: 900px) {
  :root { --header-h: 76px; }

  .hero__grid { grid-template-columns: 1.22fr 0.78fr; }
  .portrait--hero { max-width: none; }

  /* Two columns. The two context roles stack on the left, the answer takes the
     wider right column and spans both rows. DOM order is untouched, so reading
     order and tab order still run context, context, answer. */
  .compare {
    grid-template-columns: 0.82fr 1.18fr;
    /* Two content sized rows for the context pair, then a third that absorbs
       whatever height the answer has left over. Without that spare row the
       spanning card stretches rows 1 and 2 and pushes the two roles apart. */
    grid-template-rows: min-content min-content 1fr;
    column-gap: clamp(2rem, 4vw, 3.5rem);
    align-items: start;
  }
  .compare__row:nth-child(1) { grid-column: 1; grid-row: 1; }
  .compare__row:nth-child(2) { grid-column: 1; grid-row: 2; }
  .compare__row--mine { grid-column: 2; grid-row: 1 / span 3; margin-top: 0; }
  .services__grid { grid-template-columns: repeat(3, 1fr); }
  .services__grid .service:nth-child(4),
  .services__grid .service:nth-child(5) { grid-column: span 1; }
  .about__grid { grid-template-columns: 0.82fr 1.18fr; }
  .places { grid-template-columns: 0.92fr 1.08fr; column-gap: clamp(2rem, 4vw, 3.5rem); }
  .referrers__grid { grid-template-columns: 1fr 1fr 1fr; }
  .contact__grid { grid-template-columns: 1.1fr 0.9fr; }
  .reviews__grid { grid-template-columns: repeat(3, 1fr); }
}

/* The nav switches later than the layout does. Six links, a wordmark and a
   button need more room than the two column grids do, and a wrapped header
   looks broken in a way a wrapped paragraph does not. */
@media (min-width: 1040px) {
  .nav-toggle { display: none; }
  .nav {
    display: block;
    position: static;
    border: 0;
    padding: 0;
  }
  .nav__list { display: flex; align-items: center; gap: clamp(0.5rem, 1.4vw, 1.25rem); }
  .nav__list a {
    min-height: 44px;
    min-width: 44px;
    justify-content: center;
    padding-inline: 0.4rem;
    border: 0;
    font-size: 0.9375rem;
    letter-spacing: 0.01em;
    white-space: nowrap;
    position: relative;
  }
  .nav__list a::after {
    content: '';
    position: absolute;
    left: 0; right: 0; bottom: 0.5rem;
    height: 2px;
    background: var(--signal);
    transform: scaleX(0);
    transform-origin: left;
    transition: transform 160ms ease;
  }
  .nav__list a:hover::after,
  .nav__list a[aria-current='true']::after { transform: scaleX(1); }
  .nav .btn { display: none; }
  .header-cta { display: inline-flex; }
}

@media (min-width: 1200px) {
  :root { --gutter: 2.5rem; }
  .hero { padding-bottom: clamp(3rem, 5vw, 5rem); }
}

/* 11. Motion -------------------------------------------------------------- */

/* Everything below is gated on .anim, which the inline script in the document
   head adds and then takes back off if no frame is ever painted. Without that
   class this whole block is inert and every element sits in its finished
   state, which is what makes the page safe in a tab that never renders.

   The vocabulary is one idea repeated: a line being drawn, and things
   arriving underneath it. The arc is the site's motif, so the arc is what
   moves. */

:root { --ease: cubic-bezier(0.22, 0.61, 0.36, 1); }

@keyframes fade-in   { from { opacity: 0; } to { opacity: 1; } }
@keyframes rise      { from { opacity: 0; transform: translateY(12px); } to { opacity: 1; transform: none; } }
@keyframes photo-in  { from { opacity: 0; transform: translateY(18px) scale(1.02); } to { opacity: 1; transform: none; } }
@keyframes frame-in  { from { opacity: 0; transform: translate(-12px, -12px); } to { opacity: 1; transform: none; } }
@keyframes underline { from { background-size: 0% 0.12em; } to { background-size: 100% 0.12em; } }

/* Hero. One orchestrated moment: the arc sweeps in, the copy arrives under it
   line by line, the portrait settles, and the ochre underline draws last. */

.anim .hero__copy > * { animation: rise 620ms var(--ease) both; }
.anim .hero__copy > *:nth-child(1) { animation-delay: 140ms; }   /* eyebrow */
.anim .hero__copy > *:nth-child(2) { animation-delay: 220ms; }   /* headline */
.anim .hero__copy > *:nth-child(3) { animation-delay: 320ms; }   /* subhead */
.anim .hero__copy > *:nth-child(4) { animation-delay: 400ms; }   /* buttons */
.anim .hero__copy > *:nth-child(5) { animation-delay: 470ms; }   /* trust strip */

.anim .portrait--hero .portrait__img { animation: photo-in 900ms var(--ease) 260ms both; }
.anim .portrait--hero::after { animation: frame-in 700ms var(--ease) 640ms both; }

/* The underline under the key phrase draws itself, same gesture as the arc.
   Two of the three permitted uses of the accent are now in motion together. */
.anim .mark {
  background-size: 0% 0.12em;
  animation: underline 620ms var(--ease) 760ms both;
}

/* Scroll reveal: 12px and a fade on section entry, children staggered by
   60ms. Needs JS to know when a section has been reached. */
.anim .reveal > * { opacity: 0; transform: translateY(12px); }
.anim .reveal.is-visible > * {
  animation: rise 560ms var(--ease) forwards;
  animation-delay: calc(var(--i, 0) * 60ms);
}

/* Hover and interaction. Small, consistent, and never on touch, where a hover
   state only ever fires as a delayed surprise after a tap. */
@media (hover: hover) and (pointer: fine) {
  .path-card {
    transition: transform 220ms var(--ease), box-shadow 220ms var(--ease),
                border-color 220ms var(--ease);
  }
  .path-card:hover {
    transform: translateY(-3px);
    border-color: var(--ink-muted);
    box-shadow: 0 2px 4px rgb(15 27 45 / 0.05), 0 14px 30px -16px rgb(15 27 45 / 0.28);
  }

  .btn { transition: background-color 140ms ease, color 140ms ease,
                     border-color 140ms ease, transform 140ms var(--ease); }
  .btn:hover { transform: translateY(-1px); }
  .btn:active { transform: translateY(0); }

  .portrait__img { transition: transform 500ms var(--ease); }
  .portrait:hover .portrait__img { transform: scale(1.012); }

  .service { transition: transform 200ms var(--ease); }
  .service:hover { transform: translateX(3px); }
}

/* Sticky header settles onto the page once you leave the top. */
.site-header { transition: box-shadow 200ms ease, border-color 200ms ease; }
.site-header.is-stuck { box-shadow: 0 1px 12px -6px rgb(15 27 45 / 0.28); }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-delay: 0ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
  /* Hand every start state its finished value directly, rather than relying
     on a 0.001ms animation to land there. */
  .anim .mark { background-size: 100% 0.12em; }
  .anim .reveal > * { opacity: 1; transform: none; }
  .portrait:hover .portrait__img,
  .path-card:hover, .btn:hover,
  .service:hover { transform: none; }
  .arrow-link:hover svg { transform: none; }
}

@media print {
  .site-header, .form { display: none; }
  body { background: #fff; color: #000; }
  /* Nothing animates on a printed page, so hand it the finished state. */
  .anim .reveal > *, .anim .hero__copy > *,
  .anim .portrait--hero .portrait__img { opacity: 1 !important; transform: none !important; }
  .anim .mark { background-size: 100% 0.12em !important; }
}
