/* == fonts: generated by `npm run fonts` (sites/tools/fonts.mjs), do not edit by hand == */
/* Self-hosted from Google Fonts. To change the faces, edit the URL below and
   re-run `npm run fonts`; it reads the URL back from here.
   source: https://fonts.googleapis.com/css2?family=Inter+Tight:wght@300..600&family=Manrope:wght@200..800&family=Qwitcher+Grypen&display=swap
*/
@font-face {
  font-family: 'Inter Tight';
  font-style: normal;
  font-weight: 300 600;
  font-display: swap;
  src: url('/assets/fonts/inter-tight-normal-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Inter Tight';
  font-style: normal;
  font-weight: 300 600;
  font-display: swap;
  src: url('/assets/fonts/inter-tight-normal-latin.woff2') format('woff2');
  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;
}
@font-face {
  font-family: 'Manrope';
  font-style: normal;
  font-weight: 200 800;
  font-display: swap;
  src: url('/assets/fonts/manrope-normal-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Manrope';
  font-style: normal;
  font-weight: 200 800;
  font-display: swap;
  src: url('/assets/fonts/manrope-normal-latin.woff2') format('woff2');
  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;
}
@font-face {
  font-family: 'Qwitcher Grypen';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/assets/fonts/qwitcher-grypen-400-normal-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Qwitcher Grypen';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/assets/fonts/qwitcher-grypen-400-normal-latin.woff2') format('woff2');
  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;
}
/* == end fonts == */

/* ===========================================================================
   Coeur Body & Aesthetx
   Built to concept 1 - Quiet Clinical Luxury, round 1.
   Mockup: design/mockup/home-866.png (866px native, built at 1440px, x1.663).

   Every value below traces to a measurement in design/SPEC.md. If a number
   here is not in SPEC.md, it is a bug - not a preference.

   HOW SIZES SCALE. Every measured size is written at its 1440 value times
   --u, which is 1px at 1440 and above and shrinks in proportion below it.
   So the 1440 anchor is exact by construction, nothing grows past the
   mockup on a wide screen, and nothing steps at a breakpoint: a size only
   ever ramps, and where it needs a floor for legibility the floor is a
   max() on the same line (PAGE.md, "Fluid by default").
   =========================================================================== */

:root {
  /* The mockups are drawn at 1440; the site renders them at 1200 and stops
     there (Jacob, 18 Sep 2026: "1200 max with no bleed"). So one unit is
     1200/1440 of a mockup pixel at 1200 and above, and shrinks below it. */
  --u: min(0.8333px, 100vw / 1440);

  /* --- Colour (SPEC.md, Colour) ----------------------------------------- */
  /* Sarah's brand palette, from the colour sheet she emailed on 14 Sep 2026
     (assets/originals/client/). Her words: "I dont use any of the purple
     colors, my primaries are the earthstone, black, and saddle bronze."
     Plum Noir (#401919) is the purple, and is not used anywhere. The
     concept's ivory, blush and blue-grey were replaced by these on 18 Sep at
     Jacob's say-so; the layout is still the concept's. */
  --porcelain: #E7E1DA;      /* Soft Porcelain */
  --ink: #1C1C19;            /* Midnight Ink: headings, buttons */
  --earthstone: #393730;     /* Earthstone: body copy, the dark bands */
  --bronze: #70431B;         /* Saddle Bronze: rules, eyebrows, the script, accents */
  --chestnut: #492716;       /* Burnished Chestnut: button hover */
  --taupe: #AD9E8D;          /* the fourth primary swatch */

  /* Roles, all from the palette above. Tints are Soft Porcelain mixed with
     white; nothing here is a colour she did not send. */
  --paper: #F3F0EC;          /* page: Soft Porcelain halfway to white */
  --gutter: #D8D1C8;         /* warm stone outside the 1200 column, so the page reads as one sheet */
  --paper-2: var(--paper);   /* header and footer */
  --ivory: #F7F4EF;          /* ivory, a step above the page */
  --blush-mute: #EFE6E0;     /* a muted blush: Soft Porcelain warmed toward pink, never purple */
  --band: #E9E1D9;           /* the values strip: lifted from #D7CFC6, which read earthy (Jacob, 18 Sep) */
  --paper-3: var(--band);    /* value row */
  --sand: var(--blush-mute); /* Meet Sarah band */
  --blush-soft: var(--blush-mute);  /* the concept's blush bands */
  --blush: var(--earthstone);       /* booking band: dark now, light type */
  --blush-ink: var(--bronze);       /* quote mark */
  --charcoal: var(--ink);    /* buttons */
  --ink-2: var(--earthstone);
  --ink-3: #5C5852;          /* small copy: Earthstone lifted toward taupe, 6.6:1 on paper */
  --rule: var(--bronze);     /* the short rules */
  --divider: #C9BFB3;        /* taupe, lightened: dividers and borders */
  --hairline: #DCD5CC;       /* between porcelain and taupe */
  --card-line: #DCD5CC;
  --bad: #9A3B2F;            /* a field or a send that failed (CONTACT-FORMS.md) */
  --good: #3F6B34;           /* a send that went */

  /* --- Faces (SPEC.md, Type) -------------------------------------------- */
  --ff-display: "Manrope", system-ui, sans-serif;   /* replaced Newsreader (Jacob, 19 Sep 2026) */
  --ff-text: "Manrope", system-ui, sans-serif;
  --fw-display: 500;                            /* medium, as the hero was set; Newsreader was drawn at 300 */
  --ls-display: -0.02em;                        /* gentle negative tracking */
  /* Every display size below (not --f-h1) is x0.92 of its Newsreader value: Manrope 500 sets 8% wider than
     Newsreader 300 across these headings (0.90-0.94, mean 0.929), so each keeps the width it was measured at. */
  --ff-sans: "Inter Tight", system-ui, sans-serif;
  --ff-script: "Qwitcher Grypen", cursive;

  /* --- Type sizes, 1440 value x --u, floored for legibility ------------- */
  --f-h1: max(32px, calc(62.4 * var(--u)));   /* 52 at 1200: sentence case in Manrope, set a little larger than the caps were (Jacob, 19 Sep) */
  --lh-h1: 1.12;   /* two lines read as one statement; the caps were 1.18 */
  --f-display: var(--f-h1);   /* every page headline is the home hero's size (Jacob, 19 Sep); the mockups drew them 91-104 */
  --f-h2: max(27px, calc(41.7 * var(--u)));   /* drawn widths want 44-47 */
  --lh-h2: 1.26;
  --f-h2-lg: max(29px, calc(47.5 * var(--u)));   /* 228mk wide */
  --lh-h2-lg: 1.18;   /* pitch 36mk = 60 */
  --f-card: max(16px, calc(23.4 * var(--u)));   /* re-solved in Manrope: "Peptides & Regenerative Care" on one line beside the ring, 263px at 1200 (it needs 283 at 25.4) */
  --f-quote: max(23px, calc(30.2 * var(--u)));   /* italic; x0.945 */
  --lh-quote: 1.35;   /* pitch 24.5mk = 41, kept */
  --f-lead: max(18px, calc(24 * var(--u)));   /* Inter Tight; x0.96 of DM Sans, same width */
  --lh-lead: 1.33;   /* pitch 19.3mk = 32, kept */
  --f-body: max(16px, calc(17 * var(--u)));
  --lh-body: 1.5;                                /* pitch 15.5mk = 26 / 17 */
  --f-nav: max(14px, calc(15.8 * var(--u)));   /* x0.96 */
  --f-label: max(11px, calc(12 * var(--u)));
  --ls-label: 0.22em;
  --f-btn: max(12px, calc(12.5 * var(--u)));   /* x0.96 */
  --ls-btn: 0.2em;
  --ls-place: 0.16em;                            /* location and services */
  --f-legal: max(10.5px, calc(11 * var(--u)));
  --ls-legal: 0.17em;
  --f-logo: max(34px, calc(51 * var(--u)));
  --f-logo-sub: max(11px, calc(15.8 * var(--u)));   /* x0.96 */
  --f-script: max(36px, calc(54 * var(--u)));   /* 58 pitch / 1.07 leading */

  /* --- Layout (SPEC.md, Container) -------------------------------------- */
  --gut: max(20px, calc(96 * var(--u)));        /* 58mk */
  --gut-wide: max(16px, calc(53 * var(--u)));   /* 32mk, the card row */
  --gut-legal: max(20px, calc(80 * var(--u)));  /* 48mk, the footer rule */
  --wrap: 1248px;                               /* 1440 - 2 x 96 */

  /* --- Components -------------------------------------------------------- */
  --header-h: max(64px, calc(81 * var(--u)));   /* 49mk */
  --btn-h: max(48px, calc(53 * var(--u)));      /* 32mk, hero button */
  --btn-pad: max(22px, calc(34 * var(--u)));    /* (303 - 234 content) / 2 */
  --btn-sm-h: max(44px, calc(45 * var(--u)));   /* 27mk, header */
  --btn-sm-pad: max(18px, calc(26 * var(--u)));
  --btn-lg-h: max(52px, calc(60 * var(--u)));   /* 36mk, booking band */
  --btn-lg-pad: max(22px, calc(22 * var(--u)));
  --icon: max(15px, calc(17 * var(--u)));       /* 10mk arrows and pins */
  --card-gap: max(16px, calc(25 * var(--u)));   /* 15mk */
  --ring: max(40px, calc(42 * var(--u)));       /* 25mk arrow circle */
}

/* A minimal reset. Everything else belongs to the design. */
/* No bleed: header, page and footer are one 1200 column, bands included. */
.site-header, main, .site-footer { max-width: 1200px; margin-inline: auto; }
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  background: var(--paper);
  color: var(--ink-2);
  font-family: var(--ff-sans);
  font-size: var(--f-body);
  line-height: var(--lh-body);
  -webkit-font-smoothing: antialiased;
  font-weight: 350;                   /* the mockup's sans is drawn light */
}
/* The page frame (ChatGPT review, 18 Sep): the gutters beside the column go a
   step darker than any band, so a band the page colour no longer floats. The
   shadow is one strip the full height of the body, behind the column, because a
   shadow on each of header, main and footer fades at every seam between them. */
main { background: var(--paper); }
@media (min-width: 1201px) {
  body { background: var(--gutter); position: relative; }
  body::before {
    content: ""; position: absolute; inset-block: 0; left: 50%; width: 1200px; z-index: -1;
    transform: translateX(-50%); pointer-events: none;
    box-shadow: 0 0 22px rgba(57, 55, 48, .14);
  }
}
img, picture, svg, video { display: block; max-width: 100%; height: auto; }
h1, h2, h3, p, figure, blockquote, ul, ol { margin: 0; }
ul, ol { padding: 0; list-style: none; }
a { color: inherit; }
h1, h2, h3 { font-weight: 400; color: var(--ink); text-wrap: balance; }

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

.skip {
  position: absolute; left: 12px; top: -60px; z-index: 50;
  padding: 10px 16px; background: var(--charcoal); color: #fff;
  font-size: 14px; text-decoration: none;
}
.skip:focus { top: 12px; }

.wrap {
  max-width: calc(var(--wrap) + 2 * var(--gut));
  margin-inline: auto;
  padding-inline: var(--gut);
}

/* ---------------------------------------------------------------------------
   Shared pieces
   --------------------------------------------------------------------------- */

.icon { width: var(--icon); height: var(--icon); flex: none; stroke-width: 1.5; }

/* The site's icons, supplied by Jacob on 18 Sep 2026 (assets/originals/icons/).
   Applied as masks so each takes the colour of the text around it: the arrow
   is light on a dark button and dark on a light one from the same file. */
.ico { display: inline-block; background-color: currentColor; -webkit-mask: var(--ico) center / contain no-repeat; mask: var(--ico) center / contain no-repeat; }
.ico--arrow { --ico: url(/assets/icons/arrow.png); }
.ico--pin { --ico: url(/assets/icons/pin.png); }
.ico--phone { --ico: url(/assets/icons/phone.png); }
.ico--mail { --ico: url(/assets/icons/mail.png); }
.ico--leaf { --ico: url(/assets/icons/leaf.png); }
.ico--heart { --ico: url(/assets/icons/heart.png); }
.ico--sun { --ico: url(/assets/icons/sun.png); }
.ico--mountain { --ico: url(/assets/icons/mountain.png); }
.ico--chev-right { --ico: url(/assets/icons/chev-right.png); }
/* About's approach: cut from its mockup, not yet supplied as files (assets/MANIFEST.md). */
.ico--listen { --ico: url(/assets/icons/approach-listen.png); }
.ico--connect { --ico: url(/assets/icons/approach-connect.png); }
.ico--personalize { --ico: url(/assets/icons/approach-personalize.png); }

/* Uppercase tracked labels: eyebrows, card tags, icon labels. 12px, 0.22em. */
.label {
  font-family: var(--ff-sans);
  font-weight: 500;
  font-size: var(--f-label);
  letter-spacing: var(--ls-label);
  line-height: 1.3;
  text-transform: uppercase;
  color: var(--ink-2);
}

/* Eyebrows over a heading carry the bronze, as the rules beside them do. */
.eyebrow-line, .eyebrow-rules, .treat__eyebrow, .approach > .label { color: var(--ink-3); }
/* Over the lake photograph bronze fell to 4.38:1 (check:derived, 1200); her darker brown holds it. */
.philo > .label { color: var(--chestnut); }
.eyebrow-rules::before, .eyebrow-rules::after { background: var(--bronze) !important; }

.h2 {
  font-family: var(--ff-display); font-weight: var(--fw-display); letter-spacing: var(--ls-display);
  font-size: var(--f-h2);
  line-height: var(--lh-h2);
}
.h2--lg { font-size: var(--f-h2-lg); line-height: var(--lh-h2-lg); }

/* The text serif the mockup draws the section paragraphs in. */
.text { font-family: var(--ff-sans); color: var(--ink-3); }   /* descriptive copy is the sans everywhere (18 Sep) */

/* A short rule under an eyebrow: 33mk = 55 long. */
.rule {
  display: block;
  width: max(40px, calc(55 * var(--u)));
  height: 1px;
  background: var(--rule);
}

.script {
  font-family: var(--ff-script);
  font-weight: 400;                   /* its only weight; the body's 350 would be synthesised */
  font-size: var(--f-script);
  line-height: 1.07;                  /* pitch 35mk = 58 at 54px */
  color: #8C7E70;                     /* taupe, deepened to read; was bronze, which felt earthy */
}

/* Buttons. One component, three heights, all measured (SPEC.md,
   Assumptions): 53 in the hero and Meet Sarah, 45 in the header, 60 in the
   booking band. Square, charcoal, a tracked label and an arrow. */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: max(12px, calc(17 * var(--u)));   /* 10mk label to arrow */
  min-height: var(--btn-h);
  padding: 0 var(--btn-pad);
  background: var(--charcoal);
  color: #fff;
  font-family: var(--ff-sans);
  font-weight: 500;
  font-size: var(--f-btn);
  letter-spacing: var(--ls-btn);
  text-transform: uppercase;
  text-decoration: none;
  white-space: nowrap;
  transition: background-color .2s ease;
}
.btn:hover { background: var(--chestnut); }
.btn--sm {
  min-height: var(--btn-sm-h);
  padding: 0 var(--btn-sm-pad);
  letter-spacing: 0.06em;             /* width 85mk, SPEC.md */
  gap: max(10px, calc(15 * var(--u)));
}
.btn--lg { min-height: var(--btn-lg-h); padding: 0 var(--btn-lg-pad); }


/* ---------------------------------------------------------------------------
   Header - 49mk tall, logo 58mk from the edge, nav centred, button right
   --------------------------------------------------------------------------- */

.site-header { background: var(--paper-2); position: relative; z-index: 20; }
.site-header__in {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: 24px;
  min-height: var(--header-h);
}
.site-header__in > .logo { justify-self: start; margin-top: max(4px, calc(9 * var(--u))); }   /* ink 12-73 in the mockup, box-centred it sat at 7 */
.site-header__in > .btn { justify-self: end; }
/* The button's right edge is 818mk, 48 from the edge, not 58. */
.site-header__in { padding-right: var(--gut-legal); }
/* Centred, less 29: the mockup's nav runs 479-903, centre 691, not 720. */
.nav { margin-right: max(6px, calc(14 * var(--u))); }   /* measured: 58 left it 22px short of x=479 */

.logo {
  display: grid;
  justify-items: start;
  gap: 0;
  color: var(--ink);
  text-decoration: none;
  line-height: 1;
}
.logo__mark {
  font-family: var(--ff-text);
  font-weight: var(--fw-display);
  font-size: var(--f-logo);
  letter-spacing: 0.058em;
  line-height: 1;
  text-transform: uppercase;
  margin-right: -0.058em;              /* tracking after the last letter */
}
/* Her logo, in the header (22 Sep 2026). At the typeset wordmark's 61 its
   AESTHETX set 7px letters, so it is 92 tall, the smallest where that line
   read in a render at 1200. The header grows to hold it, with the 9 the
   typeset wordmark sat below the top kept clear above and below. Its width
   follows its own 2.7:1. */
.logo--mark { display: block; }
.site-header__in > .logo--mark { margin-block: max(6px, calc(9 * var(--u))); }
.logo__img { display: block; height: max(52px, calc(92 * var(--u))); width: auto; }

.logo__sub {
  font-family: var(--ff-sans);
  font-size: var(--f-logo-sub);
  letter-spacing: 0.21em;
  line-height: 1;
  margin-top: calc(-3 * var(--u));   /* COEUR to sub, 12 of ink */
  text-transform: uppercase;
  white-space: nowrap;
  color: var(--ink-2);
}

.nav__list {
  display: flex;
  gap: max(22px, calc(41 * var(--u)));
  font-size: var(--f-nav);
  color: var(--ink-3);
}
.nav__list a { text-decoration: none; padding-block: 10px; }
.nav__list .nav__book { display: none; }   /* the menu's booking button, phone widths only (below) */
.nav__list a:hover,
.nav__list a[aria-current="page"] { color: var(--ink); }
/* The current page is underlined, as the About mockup draws it (6mk below
   the text). A state, so it is the same on every page. */
.nav__list a[aria-current="page"] { text-decoration: underline; text-decoration-color: var(--bronze); text-decoration-thickness: 1px; text-underline-offset: 0.65em; }

.navtoggle { display: none; }

/* ---------------------------------------------------------------------------
   Hero - 359mk tall, one photograph under the whole band, copy at x=59
   --------------------------------------------------------------------------- */

.hero {
  position: relative;
  isolation: isolate;
  min-height: max(560px, calc(660 * var(--u)));   /* 597 drawn; taller so more of the room shows (18 Sep) */
  display: flex;
  flex-direction: column;
}
.hero__media { position: absolute; inset: 0; z-index: -1; background: var(--porcelain); }   /* the mockup's pale wall, left of the photo */
/* The concept's hero, full width, supplied without its lettering (Jacob, 18 Sep):
   the pale wall on its left is where the copy sits, as the mockup draws it. */
.hero__img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: 50% 12%; }   /* her head clear of the top, as drawn */
/* The mockup's left third is a pale wash the copy sits on. */
.hero__media::after {
  content: "";
  position: absolute; inset: 0;
  background: linear-gradient(90deg, rgba(243, 240, 236, .72) 0%, rgba(243, 240, 236, .6) 46%, rgba(243, 240, 236, 0) 60%);   /* a light veil over the wall and window, so the copy holds contrast */
}
.hero__in {
  flex: 1;
  width: 100%;
  pointer-events: none;               /* a positioning box over the photograph; only its children take the pointer */
  display: flex;
  flex-direction: column;
  padding-top: max(58px, calc(130 * var(--u)));
  padding-bottom: max(23px, calc(52 * var(--u)));
}
/* Sized to its own lines, so its box (and the contrast check) never reaches the photograph. */
.hero__title {
  width: fit-content;
  font-family: var(--ff-display); font-weight: var(--fw-display); letter-spacing: var(--ls-display);
  font-size: var(--f-h1);
  line-height: var(--lh-h1);
}
.hero__lead {
  margin-top: max(14px, calc(15 * var(--u)));   /* 35 of ink under the headline at 1440; never tighter than 14 */
  max-width: max(300px, calc(560 * var(--u)));   /* line one, 300mk = 499; DM Sans sets wider at opsz 25 */
  font-size: var(--f-lead);
  line-height: var(--lh-lead);
  color: var(--ink-2);
}
.hero__cta { margin-top: max(13px, calc(29 * var(--u))); align-self: flex-start; }
.hero__in > * { pointer-events: auto; }

.hero__place {
  margin-top: auto;
  padding-top: max(23px, calc(52 * var(--u)));
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px max(7px, calc(15 * var(--u)));
  font-size: var(--f-label);
  font-weight: 500;
  letter-spacing: var(--ls-place);
  text-transform: uppercase;
  color: var(--ink);                  /* the row runs into the photograph's fade; ink-2 fell to 4.46:1 there */
}
.hero__city { display: inline-flex; align-items: center; gap: max(7px, calc(15 * var(--u))); }
.hero__line { width: max(40px, calc(98 * var(--u))); height: 1px; background: var(--ink-3); margin-inline: calc(4 * var(--u)) calc(3 * var(--u)); }
.services { display: inline-flex; flex-wrap: wrap; gap: 6px 0; }
.services li + li::before { content: "|"; padding-inline: max(8px, calc(18 * var(--u))); color: var(--ink-3); }

/* ---------------------------------------------------------------------------
   Treatments - eyebrow, a centred [heading | paragraph] row, three cards
   --------------------------------------------------------------------------- */

.treat { padding: max(20px, calc(44 * var(--u))) 0 max(20px, calc(45 * var(--u))); }
.treat__eyebrow { text-align: center; }
.treat__intro {
  margin-top: max(6px, calc(14 * var(--u)));
  display: flex;
  justify-content: center;
  align-items: center;
  gap: max(19px, calc(43 * var(--u)));
}
.treat__intro .h2 { white-space: nowrap; }
.treat__divider { flex: none; width: 1px; height: calc(40 * var(--u)); background: var(--divider); margin-right: calc(5 * var(--u)); }
.treat__intro p { max-width: max(360px, calc(480 * var(--u)));   /* two lines, as drawn: at 1200 the 16px floor made it three at 410 (Jacob, 18 Sep) */ font-size: var(--f-body); line-height: 1.47; }

.cards {
  margin: max(16px, calc(36 * var(--u))) auto 0;
  max-width: calc(3 * 429px + 2 * 25px + 2 * var(--gut-wide));
  padding-inline: var(--gut-wide);
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--card-gap);
}
.cards > li { display: flex; }   /* equal heights across the row (MOBILE.md 9) */
.card {
  flex: 1;
  position: relative;
  display: flex;
  flex-direction: column;
  background: var(--paper);
  border: 1px solid var(--card-line);
  color: inherit;
  text-decoration: none;
}
.card__img { aspect-ratio: 429 / 268; width: 100%; height: auto; object-fit: cover; }
.card__body {
  flex: 1;
  position: relative;
  padding: max(9px, calc(20 * var(--u))) max(9px, calc(21 * var(--u))) max(10px, calc(23 * var(--u))) max(12px, calc(27 * var(--u)));
}
.card__title { font-family: var(--ff-display); font-weight: var(--fw-display); letter-spacing: var(--ls-display); font-size: var(--f-card); line-height: 1.35; color: var(--ink); padding-right: calc(var(--ring) + 12px); }
.card__tag { margin-top: max(4px, calc(9 * var(--u))); }
/* At 1440 the longest tag runs under the ring, as drawn. Below 1300 the ring
   grows relative to the card (its 40px floor), so the tags keep clear of it. */
@media (max-width: 1300px) { .card__tag { padding-right: calc(var(--ring) + 4px); } }
.card__arrow {
  position: absolute;
  right: max(10px, calc(21 * var(--u)));
  top: max(9px, calc(18 * var(--u)));           /* ring centre 701mk, 2mk below the title's */
  width: var(--ring); height: var(--ring);
  color: var(--ink);
  transition: color .2s ease;
}
.card:hover .card__arrow { color: var(--bronze); }

/* ---------------------------------------------------------------------------
   Meet Sarah - photo 382mk wide, copy 37mk beyond it, a script aside
   --------------------------------------------------------------------------- */

.sarah {
  background: var(--sand);
  display: grid;
  grid-template-columns: calc(635 * var(--u)) minmax(0, 1fr);
  min-height: calc(489 * var(--u));
}
.sarah__photo { min-height: 100%; position: relative; }   /* the copy sets the band's height, not the portrait */
.sarah__img { width: 100%; height: 100%; object-fit: cover; object-position: 50% 20%; }   /* her photographs are portrait; keep the face */
.sarah .sarah__img { position: absolute; inset: 0; object-position: 50% 62%; }   /* little headroom, her hands and knees in (Jacob, 18 Sep); 80% starts to cut her head */
.asarah__photo .sarah__img { height: calc(474 * var(--u)); object-position: 50% 72%; }   /* IMG_3369: her head near the top of the frame (Jacob, 18 Sep: 55% sat too low) */
.sarah__in {
  display: grid;
  grid-template-columns: minmax(0, calc(432 * var(--u))) auto;
  justify-content: space-between;
  align-items: start;
  padding: max(27px, calc(59 * var(--u))) max(27px, calc(59 * var(--u))) max(18px, calc(40 * var(--u))) max(28px, calc(62 * var(--u)));
}
.eyebrow-line { display: flex; align-items: center; gap: max(9px, calc(20 * var(--u))); }
.eyebrow-line::after { content: ""; width: max(40px, calc(81 * var(--u))); height: 1px; background: var(--rule); }
.sarah .rule { margin-top: max(9px, calc(21 * var(--u))); }
.sarah .h2 { margin-top: max(10px, calc(22 * var(--u))); }
.sarah .text { margin-top: max(14px, calc(30 * var(--u))); }
.sarah .btn { margin-top: max(16px, calc(35 * var(--u))); }
.sarah__aside {
  align-self: center;
  margin-top: calc(-8 * var(--u));
  display: grid;
  justify-items: center;
  transform: rotate(-4deg);
}
.sarah__aside .script { text-align: center; }   /* one text run, so its lines cannot overlap each other (sweep) */
.sarah__aside .rule { width: calc(63 * var(--u)); background: var(--ink-3); margin-top: max(5px, calc(12 * var(--u))); transform: rotate(-4deg); }

/* ---------------------------------------------------------------------------
   Philosophy - centred copy over the lake at dusk
   --------------------------------------------------------------------------- */

.philo {
  position: relative;
  isolation: isolate;
  text-align: center;
  padding: max(25px, calc(56 * var(--u))) var(--gut) max(25px, calc(56 * var(--u)));
  min-height: calc(321 * var(--u));
}
.philo__img { position: absolute; inset: 0; z-index: -2; width: 100%; height: 100%; object-fit: cover; object-position: 50% 40%; }
/* A pale wash where the copy sits, so the dark trees never cross it. */
.philo::before {
  content: "";
  position: absolute; inset: 0; z-index: -1;
  background: radial-gradient(ellipse 48% 70% at 50% 45%, rgba(243, 240, 236, .8), rgba(243, 240, 236, .38) 70%, rgba(243, 240, 236, 0));
}
.philo .rule { margin: max(9px, calc(21 * var(--u))) auto 0; width: calc(53 * var(--u)); background: var(--ink-3); }
.philo .h2 { margin-top: max(8px, calc(18 * var(--u))); }
.philo p:last-child {
  margin: max(10px, calc(22 * var(--u))) auto 0;
  max-width: max(280px, calc(640 * var(--u)));   /* line two, dash included, must fit: 600 broke before the dash */
  color: var(--ink-2);
}

/* ---------------------------------------------------------------------------
   Values - four icons divided by rules
   --------------------------------------------------------------------------- */

.values { background: var(--paper-3); }
.values__list {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  max-width: calc(1300 * var(--u) + 2 * var(--gut));
  margin-inline: auto;
  padding: max(28px, calc(40 * var(--u))) var(--gut) max(24px, calc(40 * var(--u)));   /* top was 10 (drawn); Jacob wanted room above the icons, 18 Sep */
  text-align: center;
}
.values__list li {
  display: grid;
  justify-items: center;
  gap: max(9px, calc(20 * var(--u)));
  padding-inline: 8px;
}
.values__list li + li { border-left: 1px solid var(--divider); }
.values__list li:nth-child(n+2) { border-image: linear-gradient(transparent 18%, var(--divider) 18%, var(--divider) 86%, transparent 86%) 1; }
.values__list .values__ico, .values__list svg { width: max(34px, calc(42 * var(--u))); height: max(34px, calc(42 * var(--u)));   /* 35 of ink is 42 of Lucide's 24-unit box */ stroke-width: 1.1; color: var(--ink-2); }


/* ---------------------------------------------------------------------------
   Testimonial - quote | the promise. Back on 22 Sep 2026 with Sarah's real
   Google review. The mockup draws quote | photograph | promise (SPEC.md,
   Testimonial); the photograph column is not built, since a portrait beside
   a review reads as its author, so the quote takes the quote and photo
   columns (595 + 359). Upright: Manrope has no italic here.
   --------------------------------------------------------------------------- */

.voice {
  background: var(--blush-soft);
  display: grid;
  grid-template-columns: calc(954 * var(--u)) minmax(0, 1fr);
  min-height: calc(343 * var(--u));
}
.voice__quote { padding: max(14px, calc(31 * var(--u))) max(18px, calc(40 * var(--u))) max(14px, calc(30 * var(--u))) max(40px, calc(88 * var(--u))); align-self: center; }
.voice__mark {
  display: block;
  font-family: var(--ff-display); font-weight: 300;
  font-size: max(56px, calc(96 * var(--u)));
  line-height: 0.6;
  height: max(18px, calc(30 * var(--u)));
  color: var(--blush-ink);
}
.voice blockquote p {
  margin-top: max(10px, calc(22 * var(--u)));
  font-family: var(--ff-display); font-weight: 400; letter-spacing: var(--ls-display);
  font-size: var(--f-quote);
  line-height: var(--lh-quote);
  color: var(--ink-2);
  max-width: 34em;
}
.voice figcaption { margin-top: max(12px, calc(22 * var(--u))); }
/* The divider stands where the photograph did, so the two columns still read as two. */
.voice__aside { align-self: center; padding: max(33px, calc(74 * var(--u))) max(18px, calc(40 * var(--u))) max(18px, calc(40 * var(--u))) max(29px, calc(65 * var(--u))); border-left: 1px solid var(--divider); }
.voice__aside .label { line-height: 1.6; }
.voice__aside .rule { margin-top: max(12px, calc(26 * var(--u))); }
.voice__aside .text { margin-top: max(14px, calc(30 * var(--u))); line-height: 1.47; }
.voice__aside .textlink { margin-top: max(18px, calc(26 * var(--u))); }

/* ---------------------------------------------------------------------------
   Booking band
   --------------------------------------------------------------------------- */

.book { background: var(--blush); }
.book .h2, .book__copy p { color: var(--paper); }
.book .btn { background: var(--paper); color: var(--ink); }
.book .btn:hover { background: var(--porcelain); }
.book__in {
  display: flex;
  justify-content: center;
  align-items: center;
  gap: max(39px, calc(86 * var(--u)));
  min-height: calc(190 * var(--u));
  padding-left: calc(var(--gut) + 38 * var(--u));   /* the group's centre is 444mk, 19mk right of the page's */
  padding-block: max(18px, calc(40 * var(--u)));
}
.book__copy { text-align: center; }
.book__copy p { margin-top: max(4px, calc(10 * var(--u))); color: #D6CEC4; font-size: var(--f-body); }   /* light on the dark band; it was Earthstone on Earthstone */

/* ---------------------------------------------------------------------------
   Footer
   --------------------------------------------------------------------------- */

.site-footer { background: var(--paper-2); }
.site-footer__in {
  display: grid;
  grid-template-columns: calc(332 * var(--u)) calc(385 * var(--u)) calc(275 * var(--u)) minmax(0, 1fr);
  align-items: start;
  padding-top: max(17px, calc(37 * var(--u)));
  padding-bottom: max(15px, calc(33 * var(--u)));
}
.site-footer .logo { margin-top: calc(4 * var(--u)); }
.contact-list { display: grid; gap: max(7px, calc(15 * var(--u))); font-size: var(--f-label); letter-spacing: 0.2em; line-height: 1.6; text-transform: uppercase; color: var(--ink-2); }
.contact-list li { display: grid; grid-template-columns: auto 1fr; column-gap: max(10px, calc(22 * var(--u))); align-items: start; }
.contact-list .icon { margin-top: 1px; }
.contact-list a, .facts__value a { text-decoration: none; }
.contact-list a:hover, .facts__value a:hover { color: var(--bronze); }
/* The email is the one long unbroken string here; let it break on a narrow footer. */
.facts__value a[href^="mailto:"] { overflow-wrap: anywhere; }
.contact-list a[href^="mailto:"] { overflow-wrap: anywhere; text-transform: none; letter-spacing: 0.04em; }
.foot-nav { border-left: 1px solid var(--divider); padding-left: max(30px, calc(66 * var(--u))); min-height: calc(141 * var(--u)); }
.foot-nav ul { display: grid; font-size: var(--f-nav); line-height: 1.79; color: var(--ink-2); margin-top: calc(-6 * var(--u)); }
.foot-nav a { text-decoration: none; }
.foot-nav a:hover { color: var(--ink); }
.foot-script { justify-self: center; margin-top: max(10px, calc(22 * var(--u))); transform: rotate(-12deg); }
.foot-script .script { font-size: max(30px, calc(40 * var(--u))); text-align: center; }
.foot-script .rule { width: calc(35 * var(--u)); background: var(--ink-3); margin: max(8px, calc(18 * var(--u))) 0 0 max(50px, calc(110 * var(--u))); transform: rotate(8deg); }

.legal {
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 8px 24px;
  margin-inline: auto;
  max-width: calc(1280px + 2 * var(--gut-legal));
  padding: max(10px, calc(22 * var(--u))) var(--gut-legal) max(18px, calc(40 * var(--u)));
  font-size: var(--f-legal);
  letter-spacing: var(--ls-legal);
  text-transform: uppercase;
  color: var(--ink-3);
  position: relative;
}
.legal::before { content: ""; position: absolute; top: 0; left: var(--gut-legal); right: var(--gut-legal); height: 1px; background: var(--hairline); }
.legal .services li + li::before { padding-inline: max(9px, calc(20 * var(--u))); }

/* ---------------------------------------------------------------------------
   About - design/mockup/about-887.png, 887px native, x1.6234 to 1440.
   Its measurements are in design/SPEC.md, "About".
   --------------------------------------------------------------------------- */

/* The eyebrow's trailing rule is 179 here (110mk), not the home page's 81. */
.eyebrow-line--long::after { width: max(60px, calc(179 * var(--u))); }

.ahero {
  display: grid;
  grid-template-columns: minmax(0, 1fr) calc(515 * var(--u));   /* image 509-826mk */
  column-gap: max(24px, calc(60 * var(--u)));
  align-items: start;
  padding-top: max(12px, calc(16 * var(--u)));
  padding-bottom: max(40px, calc(66 * var(--u)));
}
.ahero__copy { padding-top: max(36px, calc(75 * var(--u))); }
.ahero__title {
  margin-top: max(18px, calc(20 * var(--u)));
  font-family: var(--ff-display); font-weight: var(--fw-display); letter-spacing: var(--ls-display);
  font-size: var(--f-display);
  line-height: var(--lh-h1);
}
.ahero__lead {
  margin-top: max(20px, calc(30 * var(--u)));
  font-size: max(18px, calc(22.6 * var(--u)));  /* width 408mk = 662, re-solved in Inter Tight (23.5 was DM Sans) */
  line-height: 1.3;
  color: var(--ink-2);
}
.textlink {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  margin-top: max(20px, calc(18 * var(--u)));
  padding-bottom: max(8px, calc(12 * var(--u)));
  border-bottom: 1px solid var(--ink-3);
  text-decoration: none;
}
.textlink:hover { color: var(--ink); border-color: var(--ink); }
.ahero__media img { width: 100%; height: calc(552 * var(--u)); object-fit: cover; object-position: 58% 50%; }
.ahero__media figcaption { margin-top: max(6px, calc(8 * var(--u))); }

.asarah {
  display: grid;
  grid-template-columns: calc(591 * var(--u)) minmax(0, 1fr);   /* photo 58-422mk */
  column-gap: calc(67 * var(--u));
  align-items: start;
}
.asarah__copy { padding-top: max(16px, calc(26 * var(--u))); max-width: max(320px, calc(520 * var(--u))); }   /* paragraph 463-773mk = 503 */
.h2--xl { font-size: max(30px, calc(52.4 * var(--u))); line-height: 1.28; }   /* width 302mk -> 77, cap 30mk -> 67 */
/* Her name and credential as she signs them (her email, 14 Sep). */
.sarah__who { margin-top: max(10px, calc(14 * var(--u))); font-size: 15px; letter-spacing: 0.02em; color: var(--ink-3); }
.asarah .h2 { margin-top: max(14px, calc(15 * var(--u))); }
.body-lg { font-size: max(17px, calc(19.5 * var(--u))); line-height: 1.67; color: var(--ink-2); }   /* pitch 20mk = 32.5 */
.asarah .sarah__who + .body-lg { margin-top: max(18px, calc(30 * var(--u))); }   /* was h2 + .body-lg, which the name line between them stopped matching */
.asarah .body-lg + .body-lg, .asarah .body-lg + p { margin-top: max(12px, calc(20 * var(--u))); }
.asarah { padding-bottom: max(32px, calc(54 * var(--u))); }
/* The closing line of her biography, set apart by a rule as her own PDF sets
   it. Upright: Manrope has no italic on this site, and a slanted one would be
   synthesised. The card-title size and the h2 gap, no new values. The
   element in the selector outranks the paragraph gap (.asarah .body-lg + p). */
.asarah p.asarah__pull {
  margin-top: max(18px, calc(30 * var(--u)));
  padding-top: max(18px, calc(30 * var(--u)));
  border-top: 1px solid var(--divider);
  font-family: var(--ff-display); font-weight: var(--fw-display); letter-spacing: var(--ls-display);
  font-size: var(--f-card);
  line-height: 1.35;
  color: var(--ink);
}   /* photo foot 747mk to the band 780mk = 33mk */

.approach { background: var(--band); text-align: center; padding-top: max(44px, calc(77 * var(--u))); padding-bottom: max(40px, calc(60 * var(--u))); }   /* the band's edge now shows, so the bottom matches the top's room */
.approach .h2 { margin-top: max(16px, calc(26 * var(--u))); font-size: var(--f-h2-lg); }   /* no rule under the eyebrow now, as redrawn */
/* The approach, redrawn 18 Sep (about-approach-1858.png, 1762mk = 1200px, so 1mk = 0.817u):
   three centred columns, a line icon over each title. */
.pillars { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); margin-top: max(28px, calc(64.8 * var(--u))); }
.pillars li { display: flex; flex-direction: column; align-items: center; }
.pillars__icon { width: max(64px, calc(106 * var(--u))); height: max(64px, calc(106 * var(--u))); color: var(--ink); }   /* a 130mk box per icon, so their drawn sizes hold */
.pillars h3 { margin-top: max(8px, calc(11.6 * var(--u))); font-family: var(--ff-display); font-weight: var(--fw-display); letter-spacing: var(--ls-display); font-size: max(24px, calc(38.6 * var(--u))); line-height: 1.2; }   /* solved from Listen, Connect, Personalize: 32.2 at 1200 */
.pillars p { margin-top: max(10px, calc(22.4 * var(--u))); max-width: 13.9em; font-size: var(--f-lead); line-height: var(--lh-lead); color: var(--ink-2); text-wrap: balance; }   /* 20.3 solved from the widest line; 13.9em lets "alongside your aesthetic goals." (273) fit and "experiences and" (283) not */
.steps {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  margin-top: max(8px, calc(4 * var(--u)));
  padding-left: calc(var(--gut) + 14 * var(--u));   /* col one's number sits at 68mk, 110 */
  text-align: left;
}
.steps li {
  display: grid;
  grid-template-columns: calc(97 * var(--u)) minmax(0, 1fr);   /* number 68mk, text 128mk */
}
.steps li + li { border-left: 1px solid var(--divider); padding-left: calc(52 * var(--u)); }
.steps__num {
  font-family: var(--ff-display); font-weight: var(--fw-display); letter-spacing: var(--ls-display);
  font-size: max(42px, calc(67.4 * var(--u)));    /* digits 34mk = 55 tall -> 75; width of 02 -> 96 */
  line-height: 1.11;
  color: #A3968A;                     /* soft taupe numerals on the lighter band */
}
.steps__body::before { content: ""; display: block; width: calc(80 * var(--u)); height: 1px; background: var(--rule); margin-top: calc(22 * var(--u)); }
.steps h3 { margin-top: max(10px, calc(14 * var(--u))); font-family: var(--ff-display); font-weight: var(--fw-display); letter-spacing: var(--ls-display); font-size: max(21px, calc(30.0 * var(--u))); line-height: 1.35; }
.steps p { margin-top: max(4px, calc(6 * var(--u))); font-size: max(17px, calc(19.5 * var(--u))); line-height: 1.5; color: var(--ink-3); }

/* The dark band. The mockup lays a foliage shadow over its left third; no
   file for it was supplied (assets/MANIFEST.md row 5), so the band is plain. */
.dark { background: var(--earthstone); color: var(--porcelain); }
.dark__in {
  display: grid;
  grid-template-columns: auto 1px minmax(0, calc(300 * var(--u))) 1px minmax(0, calc(300 * var(--u)));
  justify-content: center;              /* the three columns centred as one group (Jacob, 18 Sep) */
  column-gap: max(24px, calc(46 * var(--u)));
  align-items: center;
  min-height: calc(261 * var(--u));
  padding-block: max(28px, calc(47 * var(--u))) max(22px, calc(34 * var(--u)));
}
.dark .h2 { color: var(--paper); line-height: 1.38; }
.dark__rule { align-self: stretch; background: rgba(233, 228, 222, .45); }
.dark__col { padding: 0; }
.dark .label { color: var(--porcelain); }
.dark .rule { margin-top: max(12px, calc(22 * var(--u))); width: calc(66 * var(--u)); background: rgba(233, 228, 222, .6); }
.dark__col p:last-child { margin-top: max(14px, calc(22 * var(--u))); font-size: max(16px, calc(18.5 * var(--u))); line-height: 1.54; color: #D6CEC4; }

.expect {
  display: grid;
  grid-template-columns: minmax(0, 1fr) calc(556 * var(--u));   /* image 487-830mk */
  column-gap: calc(72 * var(--u));
  padding-top: max(24px, calc(36 * var(--u)));
  padding-bottom: max(24px, calc(22 * var(--u)));
}
.expect__copy { padding-top: max(10px, calc(4 * var(--u))); }
.expect .h2 { margin-top: max(12px, calc(20 * var(--u))); font-size: var(--f-h2-lg); line-height: 1.13; }   /* pitch 32mk = 52 on 60 */
.expect__grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  margin-top: max(20px, calc(30 * var(--u)));
}
.expect__grid li { padding-block: max(8px, calc(8 * var(--u))); }
.expect__grid li:nth-child(odd) { padding-right: calc(33 * var(--u)); border-right: 1px solid var(--divider); }
.expect__grid li:nth-child(even) { padding-left: calc(39 * var(--u)); }
.expect__grid li:nth-child(-n+2) { border-bottom: 1px solid var(--hairline); }
.expect__grid li:nth-child(n+3) { padding-top: max(14px, calc(24 * var(--u))); }
.expect h3 { font-family: var(--ff-display); font-weight: var(--fw-display); letter-spacing: var(--ls-display); font-size: var(--f-card); line-height: 1.35; }
.expect__grid p { margin-top: max(4px, calc(8 * var(--u))); font-size: max(16px, calc(19.5 * var(--u))); line-height: 1.5; color: var(--ink-3); }
.expect__img { width: 100%; height: calc(437 * var(--u)); object-fit: cover; }

/* The lake band, shorter here: 130mk = 211, copy only. */
.philo--short { min-height: calc(211 * var(--u)); padding-top: max(24px, calc(32 * var(--u))); padding-bottom: max(24px, calc(26 * var(--u))); }
.philo--short .h2 { margin-top: max(12px, calc(22 * var(--u))); }
.philo--short p:last-child { margin-top: max(8px, calc(12 * var(--u))); }

/* ---------------------------------------------------------------------------
   Treatments - design/mockup/treatments-956.png, 956px native, x1.506.
   Measurements in design/SPEC.md, "Treatments".
   --------------------------------------------------------------------------- */

.tintro { text-align: center; padding-top: max(40px, calc(60 * var(--u))); }
/* The eyebrow between two rules: 56 and 47mk long, 3mk clear of the text. */
.eyebrow-rules { display: inline-flex; align-items: center; gap: max(8px, calc(10 * var(--u))); }
.eyebrow-rules::before, .eyebrow-rules::after { content: ""; width: max(40px, calc(78 * var(--u))); height: 1px; background: var(--ink-3); }
.tintro__title {
  margin-top: max(16px, calc(26 * var(--u)));
  font-family: var(--ff-display); font-weight: var(--fw-display); letter-spacing: var(--ls-display);
  font-size: var(--f-display);
  line-height: var(--lh-h1);
}
.tintro__lead {
  margin-top: max(14px, calc(18 * var(--u)));
  font-family: var(--ff-text);
  font-size: var(--f-lead);             /* width 597mk -> 25.9 in Newsreader */
  color: var(--ink-2);
}

/* The filter. A row of buttons; without script every card shows and the
   buttons are hidden, so nothing on the page is a control that does nothing. */
.filter { display: none; justify-content: center; gap: max(8px, calc(40 * var(--u))); margin-top: max(24px, calc(44 * var(--u))); }
.js .filter { display: flex; flex-wrap: wrap; }
.filter button {
  min-height: 44px;
  padding: 0 max(12px, calc(22 * var(--u)));
  background: none; border: 0; border-bottom: 2px solid transparent;
  font: 400 max(16px, calc(21 * var(--u))) / 1 var(--ff-sans);   /* width 86mk -> 21.9 */
  color: var(--ink-3);
  cursor: pointer;
}
.filter button:hover { color: var(--ink); }
.filter button[aria-pressed="true"] { color: var(--ink); border-bottom-color: var(--ink); }
/* Under 520 the four tabs no longer fit one row and "Skin care" wrapped alone onto a
   second (mobile review). Two by two, equal cells, each underline its own cell. */
@media (max-width: 519px) {
  .js .filter { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 4px 12px; }
}

.tgrid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: max(18px, calc(30 * var(--u))) max(16px, calc(33 * var(--u)));
  margin: max(24px, calc(38 * var(--u))) auto 0;
  max-width: calc(1328px + 2 * var(--gut-wide));
  padding-inline: var(--gut-wide);
}
.tcard { display: flex; flex-direction: column; border: 1px solid var(--card-line); background: var(--paper); }
.tcard[hidden], .tfeature[hidden] { display: none; }
.tcard__img { width: 100%; height: calc(203 * var(--u)); min-height: 120px; object-fit: cover; }
.tcard__body {
  flex: 1;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  column-gap: 16px;
  align-items: center;
  padding: max(16px, calc(25 * var(--u))) max(14px, calc(27 * var(--u))) max(18px, calc(34 * var(--u))) max(16px, calc(32 * var(--u)));
}
.tcard .label { grid-column: 1; }
.tcard h2 {
  grid-column: 1;
  margin-top: max(8px, calc(14 * var(--u)));
  font-family: var(--ff-display); font-weight: var(--fw-display); letter-spacing: var(--ls-display);
  font-size: var(--f-h2);               /* width 307mk -> 55 */
  line-height: 1.25;
}
.tcard__go {
  grid-column: 2; grid-row: 1 / span 2;
  width: max(44px, calc(57 * var(--u))); height: max(44px, calc(57 * var(--u)));   /* 38mk */
  color: var(--ink);
}
.tcard__go:hover { color: var(--bronze); }
.tcard__desc, .tcard__more { grid-column: 1 / -1; }
.tcard__desc { margin-top: max(8px, calc(12 * var(--u))); font-size: max(16px, calc(18 * var(--u))); line-height: 1.5; color: var(--ink-3); max-width: 34em; }
.tcard__more { margin-top: max(14px, calc(20 * var(--u))); justify-self: start; }
.tcard__go::after { right: -10px; }

.tfeature {
  display: grid;
  grid-template-columns: calc(569 * var(--u)) minmax(0, 1fr);   /* image 40-418mk */
  max-width: calc(1328px + 2 * var(--gut-wide));
  margin: max(24px, calc(30 * var(--u))) auto 0;
  padding-inline: var(--gut-wide);
}
.tfeature__media { position: relative; min-height: calc(279 * var(--u)); }   /* 1145-1330mk; the panel sets the height, not the photo */
.tfeature__img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.tfeature__panel { background: var(--porcelain); padding: max(28px, calc(56 * var(--u))) max(24px, calc(60 * var(--u))) max(28px, calc(50 * var(--u))) max(24px, calc(77 * var(--u))); }
.tfeature .h2 { margin-top: max(10px, calc(16 * var(--u))); }
.tfeature .textlink { margin-top: max(20px, calc(34 * var(--u))); }

/* The treatment menu: Sarah's price list (20 Sep 2026). No mockup draws it, so
   it is built from pieces the site already has, and every value is one of
   theirs: the band padding and column gap are the detail overview's (.dover),
   a row is the consultation box's (.dbox li), the small copy is the name
   line's 15px in --ink-3. A row (.prices) is shared with the detail pages'
   consultation box. Two balanced columns of groups; one below 760. */
.menu { padding-block: max(40px, calc(56 * var(--u))) 0; text-align: center; }
.menu .h2 { margin-top: max(16px, calc(26 * var(--u))); }
.menu__lead { margin-top: max(12px, calc(18 * var(--u))); font-size: var(--f-lead); line-height: 1.33; color: var(--ink-2); }
.menu__grid {
  columns: 2;
  column-gap: max(24px, calc(120 * var(--u)));
  margin-top: max(28px, calc(56 * var(--u)));
  text-align: left;
}
.menu__group { break-inside: avoid; padding-bottom: max(28px, calc(40 * var(--u))); }
.menu__group h3 { padding-bottom: max(10px, calc(16 * var(--u))); border-bottom: 1px solid var(--ink-2); color: var(--ink); }
.menu__note { margin-top: max(8px, calc(12 * var(--u))); font-size: 15px; color: var(--ink-3); }
.prices > div {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  column-gap: 16px;
  align-items: baseline;
  padding: max(10px, calc(16 * var(--u))) 0;
  border-bottom: 1px solid var(--hairline);
}
.prices dt { font-family: var(--ff-text); color: var(--ink-2); }
.prices dt a { text-decoration: underline; text-decoration-color: var(--divider); text-underline-offset: 4px; }
.prices dt a:hover { color: var(--bronze); text-decoration-color: currentColor; }
.prices dd { margin: 0; font-family: var(--ff-text); font-weight: 600; color: var(--ink); white-space: nowrap; }
.prices dd.menu__sub { grid-column: 1 / -1; margin-top: 4px; font-family: var(--ff-sans); font-weight: 350; font-size: 15px; color: var(--ink-3); white-space: normal; }
.menu__notes li { text-wrap: balance; }
.menu__notes { max-width: 52em; margin: max(8px, calc(12 * var(--u))) auto 0; font-size: 15px; line-height: 1.6; color: var(--ink-3); }

.begin {
  display: grid;
  grid-template-columns: auto 1px minmax(0, 1fr) auto;
  align-items: center;
  column-gap: max(20px, calc(48 * var(--u)));
  max-width: calc(1328px + 2 * var(--gut-wide));
  margin: max(28px, calc(39 * var(--u))) auto 0;
  padding: max(28px, calc(46 * var(--u))) 0 max(28px, calc(40 * var(--u)));
  border-block: 1px solid var(--divider);
  width: calc(100% - 2 * var(--gut-wide));
}
.begin__rule { height: max(48px, calc(72 * var(--u))); background: var(--divider); }
.begin p { font-size: var(--f-lead); line-height: 1.3; color: var(--ink-2); max-width: 15em; }
.page-treatments .site-footer { margin-top: max(24px, calc(40 * var(--u))); }

/* ---------------------------------------------------------------------------
   Specials - design/mockup/specials-1015.png, 1015px native, x1.4187.
   Its type is drawn ~15% larger than every other page (each size / 1.15
   lands on a site token), so the type is the site's and the geometry is
   measured. design/SPEC.md, "Specials".
   --------------------------------------------------------------------------- */

.shero {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 1px calc(411 * var(--u));   /* image 664-953mk */
  column-gap: max(24px, calc(57 * var(--u)));
  align-items: start;
  padding-top: max(20px, calc(82 * var(--u)));
}
.shero__copy { padding-top: max(10px, calc(10 * var(--u))); }
.shero__rule { align-self: stretch; margin-block: calc(63 * var(--u)) calc(12 * var(--u)); background: var(--divider); }
.shero__img { width: 100%; height: calc(346 * var(--u)); object-fit: cover; object-position: 70% 50%; }
.page-title {
  margin-top: max(16px, calc(26 * var(--u)));
  font-family: var(--ff-display); font-weight: var(--fw-display); letter-spacing: var(--ls-display);
  font-size: var(--f-display);
  line-height: var(--lh-h1);
}
.page-lead { margin-top: max(14px, calc(22 * var(--u))); font-size: var(--f-lead); line-height: 1.3; color: var(--ink-2); }


/* The featured offer, back as the mockup draws it now that Sarah has one
   (20 Sep 2026): copy | photograph, the band 454 tall in the mockup's blush,
   which is her muted blush here. Geometry as first built from SPEC.md. */
.offer { background: var(--blush-mute); margin-top: max(12px, calc(14 * var(--u))); }
.offer__in {
  display: grid;
  grid-template-columns: minmax(0, 1fr) calc(571 * var(--u));   /* image 550-952mk */
  column-gap: max(24px, calc(60 * var(--u)));
  align-items: center;
  padding-block: max(28px, calc(37 * var(--u))) max(28px, calc(30 * var(--u)));
}
.offer .h2 {
  margin-top: max(12px, calc(22 * var(--u)));
  font-size: var(--f-h2-lg);            /* a section heading, below the page's h1 (Jacob, 19 Sep: it was drawn larger than the hero) */
  line-height: var(--lh-h2-lg);
}
.offer__price { font-weight: 600; color: var(--ink); }
/* Her three conditions, in the menu's small copy with the checklist's hairlines. */
.offer__terms { margin-top: max(14px, calc(22 * var(--u))); border-top: 1px solid var(--divider); max-width: 30em; }
.offer__terms li { padding: max(8px, calc(12 * var(--u))) 0; border-bottom: 1px solid var(--divider); font-size: 15px; color: var(--ink-2); }
.offer__img { width: 100%; height: calc(387 * var(--u)); object-fit: cover; object-position: 55% 40%; }
.offer__actions { display: flex; flex-wrap: wrap; align-items: center; gap: 14px max(14px, calc(30 * var(--u))); margin-top: max(20px, calc(40 * var(--u))); }
.offer__actions .textlink { margin-top: 0; }
.offer .btn { min-height: max(48px, calc(56 * var(--u))); }


.faq { background: var(--porcelain); margin-top: max(24px, calc(32 * var(--u))); }
.faq__in {
  display: grid;
  grid-template-columns: calc(402 * var(--u)) 1px minmax(0, 1fr);
  column-gap: calc(67 * var(--u));
  align-items: center;
  padding-block: max(24px, calc(30 * var(--u)));
}
.faq__rule { align-self: stretch; margin-block: calc(16 * var(--u)); background: var(--divider); }
.faq details { border-bottom: 1px solid var(--divider); }
.faq details:first-child { border-top: 1px solid var(--divider); }
.faq summary {
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  min-height: max(48px, calc(52 * var(--u)));
  padding-inline: max(8px, calc(30 * var(--u))) max(8px, calc(24 * var(--u)));
  font-size: max(16px, calc(19.5 * var(--u)));
  color: var(--ink-2);
  cursor: pointer;
  list-style: none;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after { content: "+"; font-size: 1.4em; font-weight: 300; line-height: 1; }
.faq details[open] summary::after { content: "\2212"; }
.faq details > div { padding: 0 max(8px, calc(30 * var(--u))) 18px; }

.book--dark { background: var(--earthstone); }
.book--dark .h2, .book--dark .book__copy p { color: var(--paper); }
.book--dark .btn { background: var(--paper); color: var(--ink); }
.book--dark .btn:hover { background: #fff; }

/* ---------------------------------------------------------------------------
   Contact - design/mockup/contact-992.png, 992px native, x1.4516. Its type
   is drawn ~15% large, like Specials', so the type is the site's and the
   geometry is measured. design/SPEC.md, "Contact".
   --------------------------------------------------------------------------- */

.chero {
  display: grid;
  grid-template-columns: minmax(0, 1fr) calc(536 * var(--u));   /* image 562-931mk */
  column-gap: max(24px, calc(60 * var(--u)));
  align-items: center;
  padding-block: max(24px, calc(71 * var(--u))) max(28px, calc(31 * var(--u)));
}
.chero__img { width: 100%; height: calc(372 * var(--u)); object-fit: cover; }

.cbook { background: var(--porcelain); }
.cbook__in {
  display: grid;
  grid-template-columns: minmax(0, 1fr) calc(642 * var(--u));   /* card 489-931mk */
  column-gap: max(24px, calc(60 * var(--u)));
  align-items: start;
  padding-block: max(28px, calc(37 * var(--u))) max(28px, calc(49 * var(--u)));
}
.cbook__copy { padding-top: max(10px, calc(18 * var(--u))); }
.cbook .page-lead { margin-top: max(14px, calc(26 * var(--u))); }
.cbook__note { margin-top: max(10px, calc(18 * var(--u))); color: var(--ink-3); }
.panel-card {
  background: var(--paper);
  border: 1px solid var(--divider);
  padding: max(24px, calc(50 * var(--u))) max(20px, calc(66 * var(--u))) max(24px, calc(42 * var(--u)));
}
.panel-card .h2 + p { margin-top: max(10px, calc(16 * var(--u))); font-size: max(16px, calc(19.5 * var(--u))); color: var(--ink-2); }
.btn--block { display: flex; width: 100%; margin-top: max(20px, calc(40 * var(--u))); min-height: max(52px, calc(74 * var(--u))); }
.panel-card__foot { margin-top: max(10px, calc(16 * var(--u))); text-align: center; font-size: 14px; color: var(--ink-3); }

.cmsg {
  display: grid;
  grid-template-columns: minmax(0, 1fr) calc(635 * var(--u));   /* form card 493-931mk */
  column-gap: max(24px, calc(66 * var(--u)));
  align-items: start;
  padding-block: max(32px, calc(24 * var(--u))) max(32px, calc(24 * var(--u)));
}
.cmsg__copy { padding-top: max(10px, calc(40 * var(--u))); }
.cmsg__copy > p { margin-top: max(8px, calc(14 * var(--u))); font-size: max(16px, calc(19.5 * var(--u))); color: var(--ink-2); }
.facts { margin-top: max(20px, calc(34 * var(--u))); border-top: 1px solid var(--divider); }
.facts li {
  display: grid;
  grid-template-columns: max(56px, calc(84 * var(--u))) minmax(0, 1fr);   /* circle 58mk */
  column-gap: max(18px, calc(40 * var(--u)));
  align-items: center;
  min-height: max(84px, calc(123 * var(--u)));    /* row pitch 85mk = 123 */
  border-bottom: 1px solid var(--divider);
  padding-inline: calc(8 * var(--u));
}
.facts__icon { display: grid; place-items: center; aspect-ratio: 1; border-radius: 50%; background: var(--porcelain); color: var(--ink); }
.facts__icon svg, .facts__icon .ico { width: 42%; height: 42%; stroke-width: 1.3; }
.facts .label { color: var(--ink-2); }
.facts__value { margin-top: 4px; font-size: max(17px, calc(19.5 * var(--u))); color: var(--ink); }

.form-card { background: var(--paper); border: 1px solid var(--divider); padding: max(24px, calc(34 * var(--u))) max(20px, calc(46 * var(--u))) max(24px, calc(40 * var(--u))); }
.form-card h2 { font-family: var(--ff-display); font-weight: var(--fw-display); letter-spacing: var(--ls-display); font-size: max(22px, calc(30.0 * var(--u))); line-height: 1.35; }
.form { margin-top: max(16px, calc(22 * var(--u))); }
.form__row { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: max(14px, calc(26 * var(--u))); }
.form > .form__row + .field, .form > .field + .field { margin-top: max(16px, calc(20 * var(--u))); }
.field label { display: block; margin-bottom: 8px; font-size: 15px; color: var(--ink-2); }
.field input, .field select, .field textarea {
  display: block;
  width: 100%;
  min-height: 44px;                             /* 30mk = 44 */
  padding: 10px 14px;
  border: 1px solid var(--divider);
  border-radius: 0;
  background: #fff;
  font: 400 16px/1.4 var(--ff-sans);
  color: var(--ink);
}
.field select { appearance: none; background: #fff url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23161514' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E") no-repeat right 14px center / 18px; padding-right: 44px; }
.field textarea { min-height: max(110px, calc(116 * var(--u))); resize: vertical; }   /* 80mk */
.field input::placeholder, .field textarea::placeholder { color: #8A8C94; }
.field input:focus, .field select:focus, .field textarea:focus { outline: 2px solid var(--charcoal); outline-offset: 1px; }
/* Red is never the only signal: forms.js writes the reason in .field__error. */
.field input[aria-invalid='true'], .field select[aria-invalid='true'], .field textarea[aria-invalid='true'] { border-color: var(--bad); }
.field__error { margin-top: 6px; font-size: 14px; color: var(--bad); }
.field__error:empty { display: none; }
.form__note { margin-top: max(10px, calc(14 * var(--u))); font-size: 14px; color: var(--ink-3); }
.form__send { margin-top: max(16px, calc(22 * var(--u))); }
.form__send .btn { width: 100%; border: 0; cursor: pointer; min-height: max(52px, calc(58 * var(--u))); }   /* 40mk */
.form__send .btn[disabled] { opacity: .6; cursor: default; }
.form__status { margin-top: 12px; font-size: 15px; }
.form__status:empty { display: none; }
.form__status--ok { color: var(--good); }
.form__status--bad { color: var(--bad); }

.careband { display: grid; grid-template-columns: calc(762 * var(--u)) minmax(0, 1fr); background: var(--porcelain); }
.careband__media { position: relative; min-height: calc(290 * var(--u)); }   /* 1210-1410mk */
.careband__media img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: 50% 60%; }
.careband__copy { align-self: center; padding: max(32px, calc(40 * var(--u))) var(--gut) max(32px, calc(40 * var(--u))) max(24px, calc(81 * var(--u))); }
.careband__copy > p:first-of-type { margin-top: max(8px, calc(10 * var(--u))); font-size: max(17px, calc(19.5 * var(--u))); color: var(--ink-2); }
.careband .rule { width: min(100%, calc(375 * var(--u))); margin-top: max(16px, calc(26 * var(--u))); background: var(--divider); }
.careband__copy > p:last-child { margin-top: max(16px, calc(26 * var(--u))); color: var(--ink-3); }
.careband__copy .textlink { display: flex; width: max-content; }   /* its own line at every width, as drawn; inline it ran on as "83814.GET DIRECTIONS" */

/* ---------------------------------------------------------------------------
   Treatment detail - design/mockup/treatment-870.png, 870px native, x1.655
   to the 1440 design. One template, six pages (public/treatments/). Built on
   the site's type tokens; geometry measured off the template.
   --------------------------------------------------------------------------- */

.dhero {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr);   /* image 415-870mk */
  min-height: max(420px, calc(559 * var(--u)));             /* 338mk */
  background: var(--paper);
}
.dhero__copy { padding: max(28px, calc(61 * var(--u))) max(20px, calc(40 * var(--u))) max(32px, calc(60 * var(--u))) var(--gut); }
.crumbs { font-size: 14px; color: var(--ink-3); margin-bottom: max(28px, calc(56 * var(--u))); }
.crumbs a { text-decoration: none; }
.crumbs a:hover { color: var(--ink); }
.dhero .page-title { margin-top: max(10px, calc(16 * var(--u))); }
/* A title over 34 characters (Hormone & Functional Medicine Consultation) sets smaller, so it
   holds two lines and does not stretch the hero's photograph tall. */
.dhero .page-title--long { font-size: max(29px, calc(57.0 * var(--u))); }
.dhero .page-lead { max-width: 30em; }
.dhero__actions { display: flex; flex-wrap: wrap; align-items: center; gap: 16px max(20px, calc(46 * var(--u))); margin-top: max(24px, calc(40 * var(--u))); }
.dhero__actions .textlink { margin-top: 0; font-size: 15px; }
.dhero__media { position: relative; min-height: 280px; }
.dhero__media img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: 50% 35%; }
/* The template fades the photograph into the page on its left edge. */
.dhero__media::before { content: ""; position: absolute; inset: 0 auto 0 0; width: 22%; z-index: 1; background: linear-gradient(90deg, var(--paper), rgba(243, 240, 236, 0)); }

.dnav { background: var(--band); }
.dnav ul { display: flex; justify-content: center; flex-wrap: wrap; }
.dnav li + li { border-left: 1px solid var(--divider); }
.dnav a { display: block; padding: max(14px, calc(24 * var(--u))) max(20px, calc(52 * var(--u))); text-decoration: none; font-family: var(--ff-text); font-size: max(16px, calc(19 * var(--u))); color: var(--ink-2); }
.dnav a:hover { color: var(--ink); }

.dover {
  display: grid;
  grid-template-columns: minmax(0, 1fr) calc(488 * var(--u));   /* box 529-824mk */
  column-gap: max(24px, calc(120 * var(--u)));
  align-items: start;
  padding-block: max(40px, calc(56 * var(--u)));
}
.dover .h2 { margin-top: max(10px, calc(14 * var(--u))); }
.dover .text { margin-top: max(12px, calc(18 * var(--u))); max-width: 36em; }
.dover .h2 + .text { margin-top: max(16px, calc(26 * var(--u))); }
.dbox { border: 1px solid var(--divider); background: var(--ivory); padding: max(22px, calc(36 * var(--u))); }
.dbox h3 { font-family: var(--ff-display); font-weight: var(--fw-display); letter-spacing: var(--ls-display); font-size: var(--f-card); }
.dbox .textlink { margin-top: max(18px, calc(26 * var(--u))); }
/* The box is the treatment's prices (Jacob, 22 Sep 2026: its "At your
   consultation" checklist was the same three phrases on every page, and said
   what the overview beside it already says). Rows as the menu's (.prices),
   set the checklist's old gap under the heading; the menu link on a line of
   its own so it does not run on into "Ask a question" below. */
.dbox__price .prices { margin-top: max(12px, calc(18 * var(--u))); border-top: 1px solid var(--hairline); }
.dbox__note { margin-top: max(8px, calc(12 * var(--u))); font-size: 15px; color: var(--ink-3); }
.dbox__price .textlink { display: flex; width: max-content; }

.dconsult { margin-top: 0; padding-inline: 0; max-width: none; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
.dconsult .tfeature__media { min-height: max(300px, calc(438 * var(--u))); }   /* 265mk */
.dconsult .tfeature__panel { background: var(--blush-mute); padding: max(32px, calc(66 * var(--u))) var(--gut) max(32px, calc(56 * var(--u))) max(24px, calc(72 * var(--u))); }
.dconsult .text { margin-top: max(12px, calc(20 * var(--u))); max-width: 30em; }
.dconsult .textlink { margin-top: max(18px, calc(26 * var(--u))); }

.dexpect { padding-block: max(40px, calc(54 * var(--u))) max(36px, calc(40 * var(--u))); }
.dexpect .h2 { margin-top: max(8px, calc(10 * var(--u))); }
.dexpect .steps { padding-left: calc(48 * var(--u)); margin-top: max(20px, calc(26 * var(--u))); }
/* The template sets each number above its title, not beside it. */
.dexpect .steps li { grid-template-columns: minmax(0, 1fr); }
.dexpect .steps__body::before { display: none; }
.dexpect .steps h3 { margin-top: max(6px, calc(8 * var(--u))); }

.page-detail .faq { margin-top: 0; }

.drel { padding-block: max(40px, calc(56 * var(--u))); }
.drel .h2 { margin-top: max(8px, calc(10 * var(--u))); }
.drel__grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: max(16px, calc(43 * var(--u))); margin-top: max(20px, calc(28 * var(--u))); }
.rel { display: grid; grid-template-columns: calc(245 * var(--u)) minmax(0, 1fr) auto; align-items: center; column-gap: max(16px, calc(30 * var(--u))); padding-right: max(16px, calc(36 * var(--u))); border: 1px solid var(--divider); background: var(--ivory); text-decoration: none; min-height: max(88px, calc(116 * var(--u))); }
.rel img { width: 100%; height: 100%; object-fit: cover; }
.rel__name { font-family: var(--ff-display); font-weight: var(--fw-display); letter-spacing: var(--ls-display); font-size: var(--f-card); color: var(--ink); }
.rel .icon { color: var(--ink); }
.rel:hover .rel__name, .rel:hover .icon { color: var(--bronze); }

/* The closing band, stacked and centred as the template draws it. */
.book--stack .book__in { flex-direction: column; gap: max(18px, calc(26 * var(--u))); padding-left: var(--gut); }

/* ---------------------------------------------------------------------------
   404 - no mockup. Built from the shared pieces only: the Treatments intro's
   centred eyebrow, the page headline, the lead, a button and a text link.
   --------------------------------------------------------------------------- */
.nf { text-align: center; padding: max(64px, calc(140 * var(--u))) var(--gut) max(72px, calc(160 * var(--u))); }
.nf .page-title { max-width: 14em; margin-inline: auto; }
.nf__actions { display: flex; flex-wrap: wrap; justify-content: center; align-items: center; gap: 16px max(20px, calc(34 * var(--u))); margin-top: max(28px, calc(44 * var(--u))); }
.nf__actions .textlink { margin-top: 0; }

/* ---------------------------------------------------------------------------
   Privacy - no mockup. The 404's eyebrow, headline and lead, then running
   text in the one reading measure the detail pages use (.dover .text, 36em).
   --------------------------------------------------------------------------- */
.policy { padding-block: max(56px, calc(110 * var(--u))) max(64px, calc(140 * var(--u))); }
.policy > * { max-width: 36em; }
.policy .page-title { max-width: 14em; }
.policy__date { margin-top: max(12px, calc(18 * var(--u))); font-size: var(--f-legal); letter-spacing: var(--ls-legal); text-transform: uppercase; color: var(--ink-3); }
.policy h2 { margin-top: max(32px, calc(52 * var(--u))); font-family: var(--ff-display); font-weight: var(--fw-display); letter-spacing: var(--ls-display); font-size: var(--f-card); color: var(--ink); }
.policy .text { margin-top: max(12px, calc(18 * var(--u))); }
.policy h2 + .text { margin-top: max(10px, calc(14 * var(--u))); }
.policy strong { font-weight: 600; color: var(--ink-2); }
.policy a[href^="tel:"] { white-space: nowrap; }
.legal a { text-decoration: none; }
.legal a:hover { color: var(--ink); }
/* The LocalForge credit, About only (partials/footer.html slot). It keeps
   the phrase whole, and on a phone takes its own line, right-aligned. */
.legal .credit { white-space: nowrap; }

/* ---------------------------------------------------------------------------
   Structure changes. Each breakpoint changes a layout, never a size
   (PAGE.md): the sizes above are continuous ramps either side of it.
   --------------------------------------------------------------------------- */

/* The nav collapses behind a toggle when five links, the logo and the button
   no longer share one row (measured: they touch at 984). */
@media (max-width: 1000px) {
  .site-header__in { display: flex; padding-right: var(--gut); }
  .site-header__in > .btn { margin-left: auto; }
  .navtoggle {
    display: grid; place-items: center;
    width: 44px; height: 44px;
    margin-left: 4px;
    background: none; border: 0; color: var(--ink); cursor: pointer;
  }
  .navtoggle svg { width: 24px; height: 24px; }
  .navtoggle .icon-close { display: none; }
  .nav-open .navtoggle .icon-open { display: none; }
  .nav-open .navtoggle .icon-close { display: block; }
  .nav {
    display: none;
    position: absolute; left: 0; right: 0; top: 100%;
    background: var(--paper-2);
    border-top: 1px solid var(--hairline);
    padding: 8px var(--gut) 20px;
  }
  .nav-open .nav { display: block; }
  .nav__list { flex-direction: column; gap: 0; }
  .nav__list a { display: block; padding-block: 12px; }
}

/* Treatments' begin row: below 1200 the paragraph would set ten to fourteen
   characters a line beside the headline and the button (check:layout,
   901-1101), so the headline takes a row of its own. */
@media (max-width: 1200px) {
  .begin { grid-template-columns: minmax(0, 1fr) auto; row-gap: 20px; }
  .begin .h2 { grid-column: 1 / -1; }
  .begin__rule { display: none; }
}

/* The hero's location row runs into the photograph between 761 and 1100
   (check:derived, 1.13:1 over Sarah's top at 768), so the services take a
   line of their own under the city there. Below 761 the photo moves under
   the copy and the row has the width again. */
@media (min-width: 761px) and (max-width: 1100px) {
  .hero__line { display: none; }
  .hero__place .services { flex-basis: 100%; }
}

/* The testimonial stacks below 1100, where it did when it had a photograph
   (check:layout, worst at 901): quote above, the promise under a rule. */
@media (max-width: 1100px) {
  .voice { grid-template-columns: minmax(0, 1fr); }
  .voice__quote { padding: 40px var(--gut) 32px; }
  .voice__aside { padding: 32px var(--gut) 48px; border-left: 0; border-top: 1px solid var(--divider); margin-inline: var(--gut); padding-inline: 0; }

  /* About's expectations grid would share its row with the photograph and
     set sixteen characters a line (check:layout, to 1061). */
  .expect { grid-template-columns: minmax(0, 1fr); row-gap: 32px; }
  .expect__img { height: min(62vw, 440px); }
}

/* The footer's script column is too narrow for its rotated line under 1000,
   where it runs into the nav (sweep, 901-960). */
@media (max-width: 1000px) {
  .foot-script { display: none; }
  .site-footer__in { grid-template-columns: calc(332 * var(--u)) calc(385 * var(--u)) minmax(0, 1fr); }

  /* Contact's lake band stacks here, not at 900: with "Get directions" on its own
     line the copy column grew, and at 901 the 3:1 photograph kept 61% (check:layout). */
  .careband { grid-template-columns: minmax(0, 1fr); }
  .careband__media { min-height: 0; aspect-ratio: 5 / 2; }
  .careband__copy { padding-inline: var(--gut); }
}

/* The intro row, Meet Sarah and the footer stack at 900. */
@media (max-width: 900px) {
  .treat__intro { flex-direction: column; gap: 16px; text-align: center; }
  .treat__intro .h2 { white-space: normal; }
  .treat__divider { display: none; }

  .sarah { grid-template-columns: 1fr; }
  /* Her photographs are portrait: stacked, the frame goes portrait too. */
  .sarah__photo { min-height: 0; aspect-ratio: 4 / 5; width: min(100%, 560px); justify-self: center; }
  .sarah__in { grid-template-columns: minmax(0, 1fr); padding: 48px var(--gut) 56px; }
  .sarah__aside { display: none; }


  .site-footer__in { grid-template-columns: 1fr 1fr; row-gap: 32px; padding-top: 40px; }
  .foot-nav { border-left: 0; padding-left: 0; min-height: 0; }
  /* Two columns again, so the script has a cell beside the nav instead of leaving it empty (tablet review). */
  .foot-script { display: block; justify-self: start; align-self: center; margin-top: 0; }
  /* Touch widths: every footer link a 44px row (PAGE.md), set two across so the list is not five of them tall. */
  .foot-nav ul { grid-template-columns: repeat(2, max-content); column-gap: 40px; line-height: 1.3; margin-top: 0; }
  .foot-nav a { display: inline-flex; align-items: center; min-height: 44px; }
}

/* Below 600 the lake band would be taller than it is wide, and a 3:1
   photograph behind it keeps under half of itself (check:layout). So the
   photograph becomes a strip above the copy, and the copy sits on paper. */
@media (max-width: 600px) {
  .philo { padding: 0 0 48px; min-height: 0; }
  .philo::before { display: none; }
  .philo__img { position: static; height: auto; aspect-ratio: 3 / 1; margin-bottom: 36px; }
  .philo > :not(img) { margin-inline: var(--gut); }
  .philo .rule { margin-inline: auto; }
}

/* The numbered steps (the treatment pages; About's were redrawn as .pillars)
   stack below 1060: under it each text column held about twelve characters a
   line (check:layout, 761-1061). */
@media (max-width: 1060px) {
  .steps { grid-template-columns: minmax(0, 1fr); row-gap: 28px; max-width: 640px; margin-inline: auto; padding-inline: var(--gut); }
  .steps li + li { border-left: 0; padding-left: 0; }
  .steps li { grid-template-columns: 90px minmax(0, 1fr); }

  /* The dark band's headline takes its own row; the two columns share the next. */
  .dark__in { grid-template-columns: minmax(0, 1fr) 1px minmax(0, 1fr); row-gap: 32px; }
  .dark .h2 { grid-column: 1 / -1; padding-left: 0; }
  .dark__in > .dark__rule:first-of-type { display: none; }
  .dark__col:first-of-type { padding-left: 0; }
}

/* Contact: every split stacks at 900; the name row at 760. */
@media (max-width: 900px) {
  .chero, .cbook__in, .cmsg { grid-template-columns: minmax(0, 1fr); row-gap: 28px; }
  .chero__img { height: auto; aspect-ratio: 3 / 2; }
}

/* Treatment detail: below 1100 the hero's half-width column turns tall, and
   the landscape treatment photos keep under half of themselves in it
   (check:layout, 47-62% at 901; the Hormone page's three-line title to
   1101), so the hero stacks first. */
@media (max-width: 1180px) {
  .dhero { grid-template-columns: minmax(0, 1fr); }
  .dhero__media { aspect-ratio: 16 / 9; min-height: 0; }
  .dhero__media::before { display: none; }
  .drel__grid { grid-template-columns: minmax(0, 1fr); }   /* side by side, the longest name set three words a line to 1100 */
}

/* Treatment detail: the hero, overview and consultation stack at 900. On a
   phone the hero photo's frame takes its height from its width, so it must
   not also carry the desktop min-height (that forced the page 53px wide). */
@media (max-width: 900px) {
  .dhero, .dover, .dconsult { grid-template-columns: minmax(0, 1fr); }
  .dhero__media { aspect-ratio: 4 / 3; min-height: 0; }
  .dhero__media::before { display: none; }
  .dover { row-gap: 32px; }
  .dconsult .tfeature__media { min-height: 0; aspect-ratio: 3 / 2; }
  .dconsult .tfeature__panel { padding-inline: var(--gut); }
}
@media (max-width: 760px) {
  .rel { grid-template-columns: 46% minmax(0, 1fr) auto; }
}
/* Narrow phones: the photo sits above the name, so a long name keeps its line. */
@media (max-width: 480px) {
  .rel { grid-template-columns: minmax(0, 1fr) auto; padding: 0 16px 16px 0; row-gap: 14px; }
  .rel img { grid-column: 1 / -1; aspect-ratio: 16 / 9; height: auto; }
  .rel__name { padding-left: 16px; }
  .dnav li + li { border-left: 0; }
  .dnav a { padding: 12px 14px; }
  .dexpect .steps { padding-left: 0; }
}

/* Specials: the hero, the offer and the FAQ stack at 900; the cards at 760. */
@media (max-width: 900px) {
  .shero, .offer__in, .faq__in { grid-template-columns: minmax(0, 1fr); row-gap: 28px; }
  .shero__rule, .faq__rule { display: none; }
  .shero__img, .offer__img { height: auto; aspect-ratio: 3 / 2; }
}

/* Treatments: the feature and the begin row stack at 900. */
@media (max-width: 900px) {
  .tfeature { grid-template-columns: minmax(0, 1fr); }
  .tfeature__media { min-height: 0; aspect-ratio: 3 / 2; }
  .begin { grid-template-columns: minmax(0, 1fr); }
  .begin .btn { justify-self: start; }
}

/* About: the two splits and the dark band stack at 900. */
@media (max-width: 900px) {
  .ahero, .asarah { grid-template-columns: minmax(0, 1fr); row-gap: 32px; }
  .ahero__media img { height: auto; aspect-ratio: 4 / 3; }
  .asarah__photo { width: min(100%, 560px); justify-self: center; }
  .asarah__photo .sarah__img { height: auto; aspect-ratio: 4 / 5; }
  .asarah__copy { max-width: none; padding-top: 0; }
  .dark__in { grid-template-columns: minmax(0, 1fr); row-gap: 28px; padding-block: 48px; }
  .dark .h2 { padding-left: 0; }
  .dark__rule { display: none; }
  .dark__col { padding: 0; }
}

/* One card per row; the values go two by two; the booking band stacks. */
@media (max-width: 760px) {
  .header-book { display: none; }
  /* About's approach: three columns set eight characters a line under 600 (check:layout); one per row. */
  .pillars { grid-template-columns: minmax(0, 1fr); row-gap: 36px; }
  /* The header button is gone at this width, so booking moves to the top of the open menu's foot (mobile review). */
  .nav__list .nav__book { display: block; margin-top: 12px; }
  .nav__list .nav__book a { display: flex; padding-block: 0; color: #fff; }
  .navtoggle { margin-left: auto; }   /* the button that held the right edge is gone */

  .hero { min-height: 0; }
  .hero__media { position: relative; inset: auto; order: 2; aspect-ratio: 4 / 3; }
  .hero__media::after { display: none; }
  .hero__img { width: 100%; object-position: 72% 30%; }   /* stacked: keep her and the window */
  .hero__in { padding-top: 40px; padding-bottom: 32px; }
  .hero__place { margin-top: 0; padding-top: 36px; }

  .treat { padding-top: 48px; padding-bottom: 48px; }
  .cards { grid-template-columns: minmax(0, 1fr); max-width: 520px; margin-top: 32px; }

  .values__list { grid-template-columns: repeat(2, minmax(0, 1fr)); row-gap: 32px; padding-block: 32px; }
  .values__list li:nth-child(3) { border-left: 0; }

  .book__in { flex-direction: column; gap: 24px; padding-block: 48px; }

  .tgrid { grid-template-columns: minmax(0, 1fr); }
  .menu__grid { columns: 1; }   /* one column of prices, as the cards above go one per row */
  .form__row { grid-template-columns: minmax(0, 1fr); }
  .tcard__img { height: auto; aspect-ratio: 2 / 1; }
  .expect__grid { grid-template-columns: minmax(0, 1fr); }
  .expect__grid li:nth-child(odd) { padding-right: 0; border-right: 0; }
  .expect__grid li:nth-child(even) { padding-left: 0; }
  .expect__grid li { border-bottom: 1px solid var(--hairline); padding-top: 16px; }
  .expect__grid li:last-child { border-bottom: 0; }

  .site-footer__in { grid-template-columns: 1fr; }
  .legal { flex-direction: column; }
  .legal .credit { display: block; text-align: right; }
  .legal .credit__sep { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; }
}
