/* ═══════════════════════════════════════════════════════════════════════════
   MULTIDIMENSIONAL HEALTH - DESIGN SYSTEM
   Nanaimo, BC. Osteopathy · Registered Massage Therapy · Physiotherapy
   ───────────────────────────────────────────────────────────────────────────
   DESIGN READ
     Multidisciplinary clinic site for local patients choosing a practitioner.
     Coastal-warm documentary language. Warmth comes from the PHOTOGRAPHY,
     not from a second accent colour.

   DIALS
     DESIGN_VARIANCE  7   asymmetric splits, offset trios, mixed aspect ratios
     MOTION_INTENSITY 5   fluid CSS transitions + IntersectionObserver reveals
     VISUAL_DENSITY   3   airy; generous section rhythm

   LOCKS (audited before ship)
     Colour   ONE accent, #034ea1, the clinic's real logo blue. No second
              accent anywhere. Neutrals are a single COOL family (never mixed
              warm/cool greys).
     Theme    Dual-mode via tokens. Light is primary; dark mirrors hierarchy.
              No section inverts against its page theme.
     Shape    Documented radius rule, followed everywhere:
                buttons + tags  → 999px (pill)
                media + cards   → 14px
                inputs          → 10px
                panels          → 18px
     Motion   Zero scroll event listeners. Reveals use IntersectionObserver;
              everything is gated behind prefers-reduced-motion.
     Type     Petrona (display) + Onest (body/UI), self-hosted.
              No Inter, no runtime font requests.
     Copy     Zero em-dashes and zero en-dashes. Regular hyphens only.
     Icons    Tabler Icons (MIT) path data, inlined because this project has
              no build step to install a package. Stroke width 1.75 globally.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── Fonts ───────────────────────────────────────────────────────────────── */
/* Both are true variable fonts (Google Fonts, open license), each shipped as
   ONE woff2 per style covering its whole weight axis via a range declaration
   (font-weight: min max) - the browser interpolates whatever weight a rule
   asks for, so 4 files replace what would otherwise be 6+ static cuts. */
@font-face{font-family:"Petrona";src:url("../fonts/petrona-variable.woff2") format("woff2");font-weight:400 700;font-style:normal;font-display:swap}
@font-face{font-family:"Petrona";src:url("../fonts/petrona-italic-variable.woff2") format("woff2");font-weight:400 700;font-style:italic;font-display:swap}
/* Onest ships no italic face on Google Fonts. Any <em>/italic in body copy
   is routed to Petrona's real italic instead (see the em{} rule below),
   rather than letting the browser synthesize a fake oblique of Onest. */
@font-face{font-family:"Onest";src:url("../fonts/onest-variable.woff2") format("woff2");font-weight:400 700;font-style:normal;font-display:swap}

/* ── Tokens: light (primary) ─────────────────────────────────────────────── */
:root{
  /* Surfaces. Cool neutral family. No pure #fff, no pure #000. */
  --surface:#f6f8fa;
  --surface-2:#d8e2ee;
  --surface-card:#fcfdfe;
  --surface-deep:#0d1a26;      /* ground behind the hero photo while it decodes */

  /* Ink */
  --ink:#101d29;
  --ink-2:#46586a;
  --ink-3:#3a4a5a;             /* 7.9:1 on --surface-2, 9.1:1 on white - AAA,
                                   darkened from the original #54657a (4.9:1,
                                   AA-only) so small/meta text reads easily
                                   for older clients. */

  /* The single accent. Constant hue across both themes for brand fidelity. */
  --accent:#034ea1;
  --accent-hover:#023a78;
  --accent-ink:#034ea1;        /* accent used AS text on light surfaces */
  --accent-soft:#e4eefa;
  --on-accent:#ffffff;         /* 8.6:1 on --accent. WCAG AA pass. */

  --line:#dbe3ea;
  --line-strong:#c3ceda;

  /* Radius rule */
  --r-pill:999px;
  --r-media:14px;
  --r-input:10px;
  --r-panel:18px;

  /* Rhythm. VISUAL_DENSITY 3. */
  --section-y:clamp(5rem,10vw,9rem);
  --shell:1280px;
  --gutter:clamp(1.25rem,4vw,2.5rem);

  /* Type scale */
  --fs-display:clamp(2.5rem,5.2vw,4.4rem);
  /* Sits between --fs-display and --fs-h2: for a page h1 that needs to
     read as clearly bigger than that same page's own h2 section heads
     (the ".owners" intro pattern), without going as big as the full
     photographic hero. Previously these h1s reused --fs-h2 verbatim,
     landing at the exact same size/weight/spacing as the page's h2s with
     nothing left to tell them apart. */
  --fs-h1:clamp(2.15rem,3.9vw,3.3rem);
  --fs-h2:clamp(1.95rem,3.5vw,3rem);
  --fs-h3:clamp(1.2rem,1.7vw,1.5rem);
  --fs-lead:clamp(1.04rem,1.3vw,1.2rem);
  --fs-body:1rem;
  /* Was .905rem (14.5px): this token backs actual reading copy sitewide
     (card descriptions, checklist items, bio-page sections, FAQ answers,
     review quotes) as well as small UI chrome (nav links, buttons, footer
     links) - raised to match --fs-body (16px, the common minimum for
     comfortable body text) so all that reading content is legible; the UI
     chrome that shares this token just grows slightly with it. */
  --fs-sm:1rem;
  --fs-xs:.8rem;

  /* Shadows. Tinted to the surface hue, never pure black. */
  --shadow-sm:0 2px 8px -2px rgb(16 29 41 / .10);
  --shadow-md:0 18px 40px -22px rgb(16 29 41 / .30);
  --shadow-lg:0 34px 70px -34px rgb(16 29 41 / .38);

  --ease:cubic-bezier(.16,1,.3,1);
  color-scheme:light;
}

/* ── Tokens: dark (DISABLED) ──────────────────────────────────────────────
   Decided in the 2026-09-12 design critique: DESIGN.md commits to "white is
   the dominant ground... do not introduce a third background hue," but this
   block silently inverted that for any visitor on OS-level dark mode, with
   nobody having signed off on that as in-scope. Pinned to light-only for
   every visitor per that decision. The palette below was contrast-verified
   and works; it's disabled, not deleted, in case dark mode is revisited as
   a deliberate, tested surface later.

@media (prefers-color-scheme:dark){
  :root{
    --surface:#0b141d;
    --surface-2:#111e29;
    --surface-card:#16232f;
    --surface-deep:#060d14;

    --ink:#e9eff5;
    --ink-2:#a5b5c3;
    --ink-3:#76899b;

    --accent:#034ea1;
    --accent-hover:#0a63c2;
    --accent-ink:#6fb0f0;
    --accent-soft:#0f2942;
    --on-accent:#ffffff;

    --line:#22323e;
    --line-strong:#314656;

    --shadow-sm:0 2px 8px -2px rgb(0 0 0 / .5);
    --shadow-md:0 18px 40px -22px rgb(0 0 0 / .68);
    --shadow-lg:0 34px 70px -34px rgb(0 0 0 / .75);
    color-scheme:dark;
  }
}
*/

/* ── Base ────────────────────────────────────────────────────────────────── */
*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
body{
  margin:0;
  background:var(--surface);
  color:var(--ink);
  font-family:"Onest",system-ui,-apple-system,Arial,sans-serif;
  font-size:var(--fs-body);
  line-height:1.6;
  -webkit-font-smoothing:antialiased;
  -moz-osx-font-smoothing:grayscale;
  overflow-x:hidden;
}
img,svg{display:block;max-width:100%}
img{height:auto}
a{color:inherit;text-decoration:none}
button{font:inherit;color:inherit;background:none;border:0;cursor:pointer}
h1,h2,h3,h4{margin:0;font-family:"Petrona",Georgia,"Times New Roman",serif;font-weight:700;line-height:1.06;letter-spacing:-.022em;text-wrap:balance}
/* Italic is H's defining trait, but only at true display sizes (h1/h2,
   always 24px+ on this scale): a whole page of italic h3/h4 - footer
   headers, card titles, badge numerals, all well under 24px - would trade
   away real legibility for a match to a hero moment they never appear in.
   h3/h4 stay upright; explicit normal guards against inheriting italic
   from an ancestor (e.g. a heading nested inside the em{} treatment below). */
h1,h2{font-style:italic}
h3,h4{font-style:normal}
/* Onest ships no italic face: route <em>/emphasis in body copy to
   Petrona's real italic rather than a browser-synthesized oblique of Onest. */
em{font-family:"Petrona",Georgia,"Times New Roman",serif;font-style:italic}
p{margin:0}
ul{margin:0;padding:0;list-style:none}
:focus-visible{outline:2.5px solid var(--accent-ink);outline-offset:3px;border-radius:2px}

.skip-link{position:absolute;left:-9999px;top:0;z-index:400;padding:14px 20px;background:var(--accent);color:var(--on-accent);border-radius:0 0 var(--r-input) 0;font-weight:600}
.skip-link:focus{left:0}

/* Sentinel for the sticky-header observer. Absolute so it costs no layout. */
#headerSentinel{position:absolute;top:0;left:0;width:100%;height:8px;pointer-events:none}

.shell{width:min(var(--shell),100% - var(--gutter) * 2);margin-inline:auto}

/* Section rhythm. Tint alternation stays inside one theme family. */
.section{padding-block:var(--section-y);position:relative}
.section--tight-bottom{padding-bottom:clamp(1.5rem,3vw,2.5rem)}
.section--tint{background:var(--surface-2)}

/* #services sits directly under the hero, which already has its own
   bottom padding plus the wave seam marking the handoff - the full
   --section-y on top of that read as a dead gap before "Our Core
   Services". Pull just the top padding in; bottom is untouched so the
   rhythm with #dimensions below stays the same as every other seam. */
#services{padding-top:clamp(2.25rem,4.5vw,3.75rem)}

/* ── Section seams: one long, gentle wave ────────────────────────────────
   Softens every section-to-section boundary: instead of a straight line
   where the background color cuts, the seam is a single slow wave (one
   full up-down cycle stretched across the whole width, low amplitude),
   filled solid in the section it belongs to - no new palette, same
   --surface / --surface-2 / --accent tokens the page already alternates
   between.

   Each <svg class="seam"> is the FIRST child of the section it
   introduces, absolutely positioned and pulled fully above that section's
   own top edge (so it costs no layout / can't push content) to sit over
   the boundary with the section before it. */
.seam{
  --seam-h:clamp(3rem,6vw,5rem);
  position:absolute;top:0;left:0;z-index:1;
  width:100%;height:var(--seam-h);
  transform:translateY(-100%);
  pointer-events:none;display:block;
}
.seam--cta{--seam-h:clamp(3.5rem,7vw,5.75rem)}

/* Icons: Tabler paths, one stroke width everywhere. */
.icon{width:1.15em;height:1.15em;flex:none;stroke:currentColor;stroke-width:1.75;stroke-linecap:round;stroke-linejoin:round;fill:none}

/* ── Typography helpers ──────────────────────────────────────────────────── */
.eyebrow{
  display:block;font-size:var(--fs-xs);font-weight:600;letter-spacing:.1em;
  text-transform:uppercase;color:var(--accent-ink);margin-bottom:1.1rem;
}
.h2{font-size:var(--fs-h2)}
.lead{font-size:var(--fs-lead);line-height:1.62;color:var(--ink-2);max-width:56ch;text-wrap:pretty}
.body{color:var(--ink-2);max-width:62ch}
.measure{max-width:34ch}

/* ── Buttons ─────────────────────────────────────────────────────────────── */
.btn{
  display:inline-flex;align-items:center;gap:.55rem;
  padding:.92rem 1.6rem;border-radius:var(--r-pill);
  font-family:"Onest",Arial,sans-serif;font-size:var(--fs-sm);font-weight:600;
  white-space:nowrap;                       /* CTA labels never wrap */
  border:1.5px solid transparent;
  transition:background .28s var(--ease),color .28s var(--ease),
             border-color .28s var(--ease),transform .14s var(--ease),
             box-shadow .28s var(--ease);
}
.btn:active{transform:translateY(1px) scale(.985)}
.btn .icon{width:1.05em;height:1.05em;transition:transform .28s var(--ease)}
.btn:hover .icon{transform:translateX(3px)}

.btn--primary{background:var(--accent);color:var(--on-accent);box-shadow:var(--shadow-sm)}
.btn--primary:hover{background:var(--accent-hover);box-shadow:var(--shadow-md)}

/* Small overlapping avatar stack inside a booking button, e.g. osteopathy.
   html's first CTA - puts faces to "Book with Erin or James" without
   competing with the label. */
.btn__avatars{display:inline-flex;margin-left:-.35rem;margin-right:.1rem}
.btn__avatars img{
  width:1.7rem;height:1.7rem;border-radius:50%;object-fit:cover;
  border:2px solid var(--on-accent);
}
.btn__avatars img + img{margin-left:-.65rem}

.btn--outline{border-color:var(--line-strong);color:var(--ink)}
.btn--outline:hover{border-color:var(--accent);color:var(--accent-ink);background:var(--accent-soft)}

/* On the blue CTA block: white fill / white stroke. Both clear AA on #034ea1. */
.btn--on-accent{background:var(--on-accent);color:var(--accent)}
.btn--on-accent:hover{background:var(--accent-soft);color:var(--accent-ink)}
.btn--on-accent-outline{border-color:rgb(255 255 255 / .55);color:#fff}
.btn--on-accent-outline:hover{border-color:#fff;background:rgb(255 255 255 / .14)}

/* Inline text link with a drawn underline */
.tlink{
  display:inline-flex;align-items:center;gap:.4rem;
  font-weight:600;font-size:var(--fs-sm);color:var(--accent-ink);
  padding-bottom:2px;background-image:linear-gradient(currentColor,currentColor);
  background-size:0% 1.5px;background-position:0 100%;background-repeat:no-repeat;
  transition:background-size .34s var(--ease);
}
.tlink:hover{background-size:100% 1.5px}
.tlink .icon{transition:transform .28s var(--ease)}
.tlink:hover .icon{transform:translateX(3px)}
/* On the blue block: white text clears 8.6:1 on #034ea1. */
.tlink--on-accent{color:#fff}

/* ── Header ──────────────────────────────────────────────────────────────── */
.site-header{
  position:sticky;top:0;z-index:200;
  background:color-mix(in srgb,var(--surface) 88%,transparent);
  backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px);
  border-bottom:1px solid transparent;
  transition:border-color .3s var(--ease),box-shadow .3s var(--ease);
}
.site-header.is-stuck{border-bottom-color:var(--line);box-shadow:var(--shadow-sm)}
.site-header__inner{
  display:flex;align-items:center;justify-content:space-between;gap:1.5rem;
  height:72px;                              /* nav height cap: 80px */
}
.brand{display:flex;align-items:center;gap:.7rem;font-weight:600;font-size:.98rem;letter-spacing:-.01em}
.brand picture{display:flex;flex:none}
.brand img{height:30px;width:auto}
.brand span{white-space:nowrap}

/* Header brand fade: HOME PAGE ONLY (body.page-home - set on index.html).
   There, the icon + wordmark already appear large in the hero (see
   .hero__brand), so the header starts empty and both pieces fade in
   together once the user scrolls past the hero and .is-stuck lands (same
   sentinel that drives the header's shadow) - and fade back out at the
   very top. Sized up from the original small lockup since it's only ever
   seen once revealed. Pure opacity, on purpose: their box keeps its real
   size throughout (the header never reflows the nav as this toggles), so
   what changes on screen is only ever "visible <-> invisible", which
   reads as a fade rather than a reveal or a pop.

   Every OTHER page has no hero brand to hand off from, so its header
   keeps the logo+name on screen at all times, same as it always has -
   only home suppresses it while the hero is in view. */
body.page-home .site-header .brand{font-size:1.2rem}
body.page-home .site-header .brand img{height:38px}
body.page-home .site-header .brand img,body.page-home .site-header .brand span{
  opacity:0;transition:opacity 1.1s var(--ease);
}
body.page-home .site-header.is-stuck .brand img,
body.page-home .site-header.is-stuck .brand span{opacity:1}

.site-nav{display:flex;align-items:center;gap:2rem}
.site-nav__list{display:flex;align-items:center;gap:1.6rem}
.site-nav__list a{
  font-size:var(--fs-sm);font-weight:500;color:var(--ink-2);white-space:nowrap;
  transition:color .22s var(--ease);
}
.site-nav__list a:hover,.site-nav__list a[aria-current="page"]{color:var(--accent-ink)}
.site-header .btn{padding:.68rem 1.25rem}


/* Nav dropdowns: Team / Services. A disclosure button (not a link, since it
   has no destination of its own) that reveals a small menu - floating below
   it on desktop, expanding inline (accordion-style) inside the stacked
   mobile nav. Same open/close JS drives both; only the CSS differs. */
.nav-drop{position:relative}
.nav-drop__trigger{
  display:inline-flex;align-items:center;gap:.35rem;
  font-family:inherit;font-size:var(--fs-sm);font-weight:500;color:var(--ink-2);
  padding:0;background:none;border:0;cursor:pointer;
  transition:color .22s var(--ease);
}
.nav-drop__trigger:hover,
.nav-drop__trigger[aria-expanded="true"],
.nav-drop__trigger[aria-current="page"]{color:var(--accent-ink)}
.nav-drop__trigger .icon{width:.9rem;height:.9rem;transition:transform .25s var(--ease)}
.nav-drop__trigger[aria-expanded="true"] .icon{transform:rotate(180deg)}

.nav-drop__menu{
  position:absolute;top:calc(100% + .9rem);left:50%;
  min-width:12rem;padding:.4rem;margin:0;border-radius:var(--r-input);
  background:var(--surface-card);border:1px solid var(--line);box-shadow:var(--shadow-lg);
  opacity:0;visibility:hidden;translate:-50% -4px;
  transition:opacity .2s var(--ease),translate .2s var(--ease),visibility 0s linear .2s;
  z-index:50;
}
.nav-drop__menu[data-open="true"]{
  opacity:1;visibility:visible;translate:-50% 0;
  transition:opacity .2s var(--ease),translate .2s var(--ease);
}
.nav-drop__menu a{
  display:block;padding:.6rem .85rem;border-radius:calc(var(--r-input) - 4px);
  font-size:var(--fs-sm);font-weight:500;color:var(--ink-2);white-space:nowrap;
  transition:background .18s var(--ease),color .18s var(--ease);
}
.nav-drop__menu a:hover,.nav-drop__menu a[aria-current="page"]{background:var(--accent-soft);color:var(--accent-ink)}

.nav-toggle{display:none;width:44px;height:44px;align-items:center;justify-content:center;border-radius:var(--r-pill);border:1.5px solid var(--line-strong)}
.nav-toggle .icon{width:20px;height:20px}

@media (max-width:960px){
  .nav-toggle{display:inline-flex}
  .site-nav{
    position:fixed;inset:72px 0 auto;
    flex-direction:column;align-items:stretch;gap:0;
    background:var(--surface);border-bottom:1px solid var(--line);
    padding:.5rem var(--gutter) 1.5rem;
    box-shadow:var(--shadow-md);
    transform:translateY(-8px);opacity:0;pointer-events:none;
    transition:opacity .24s var(--ease),transform .24s var(--ease);
  }
  .site-nav[data-open="true"]{transform:none;opacity:1;pointer-events:auto}
  .site-nav__list{flex-direction:column;align-items:stretch;gap:0}
  .site-nav__list a{display:block;padding:.95rem 0;font-size:1.05rem;border-bottom:1px solid var(--line)}
  .site-header .btn{margin-top:1.1rem;justify-content:center;padding:.9rem 1.5rem}

  /* Same trigger + menu, but the menu expands inline instead of floating -
     a plain accordion, matching how the rest of the stacked mobile nav
     already reads top to bottom. */
  .nav-drop__trigger{
    width:100%;justify-content:space-between;
    padding:.95rem 0;font-size:1.05rem;border-bottom:1px solid var(--line);
  }
  .nav-drop__menu{
    position:static;translate:none;margin:0;padding:0;min-width:0;
    background:none;border:0;box-shadow:none;
    max-height:0;opacity:1;visibility:visible;overflow:hidden;
    transition:max-height .3s var(--ease);
  }
  .nav-drop__menu[data-open="true"]{max-height:16rem;translate:none;transition:max-height .35s var(--ease)}
  .nav-drop__menu a{padding:.85rem 0 .85rem 1.25rem;border-bottom:1px solid var(--line);border-radius:0;font-size:1rem}
}

/* ═══ SECTION 1 · HERO - full-bleed photograph, title overlaid on top ═════ */
/* Back to the original treatment: one photograph, cover-fit edge to edge,
   with a dark gradient scrim painted over it (`.hero::after`, live CSS - not
   baked into the file, not a mask) so white title text reads directly on
   top of the photo. No separate faded file, no light-background variant:
   the photo is the plain, unedited source at full strength everywhere
   except under the scrim.
   James (the man) is the leftmost of the three, but his shoulder still sits
   at ~25% of the photo's own width - measured directly off the source file,
   not eyeballed - so the text column is kept inside that, with a margin.
   Below --hero-overlay-bp there isn't enough of that 25% left for a column
   worth reading, so the layout drops the overlay and stacks text and photo
   as two plain blocks instead (media query below). The photo never moves:
   no parallax, no Ken Burns drift. */
.hero{
  --hero-overlay-bp:80rem; /* 1280px: below this there's no longer enough
    room on either side of --hero-split for a readable column. */
  --hero-h:clamp(28rem,42vw,34rem); /* the photo's own height, held fixed -
    see hero__bg below for why this can't just be .hero's min-height.
    Sized to the text block, not the photo: measured hero__inner (title +
    lead + buttons) plus the padding-block on both sides at a representative
    width, rather than picked for how much of the photo it reveals - this
    hero is content-height-led, the photo is cropped to whatever that turns
    out to be, not the other way around. */
  --hero-split:30%; /* where the photo box starts, as a fraction of the
    whole hero. Everything left of this is bare --surface-2 (or the fade
    into the photo) - see hero__bg. */
  position:relative;isolation:isolate;overflow:hidden;
  background:var(--surface-2); /* fallback ground while the image decodes -
    the same light blue tint as #services below, not plain white - see the
    scrim comment for why */
  min-height:var(--hero-h);
  display:grid;align-items:center;
  padding-block:clamp(3.5rem,8vw,5.5rem);
}
/* height, not inset:0: this is the bug behind a real overlap a wide desktop
   screenshot once caught. min-height is a floor, not a ceiling - if the
   text column ever needs more lines than fit in --hero-h, .hero grows
   taller to fit it, and inset:0 would have stretched the photo to match
   that grown height, corrupting its crop math. Pinning the photo to a
   fixed height keeps its aspect ratio constant no matter how the text
   wraps; any rare overflow shows as plain --surface-deep below the photo
   instead of silently moving the group. */
/* Cropping can only ever remove content, never add it - there is no crop
   or object-position that moves the group rightward within the photo's own
   pixels (verified by measuring the source: trimming space off their left
   pulls them toward the new edge, not away from it). So instead the photo
   is given less of the section to occupy in the first place: its box starts
   at --hero-split, not at the hero's own left edge, and is anchored to the
   RIGHT (object-position below) so any width the box doesn't have room for
   is trimmed from the photo's own empty left margin, not from the group.
   The result: the group's position relative to the whole section is
   --hero-split (bare ground) plus their own ~25%-of-photo position scaled
   into the remaining (100% - --hero-split) width - a large, deliberate
   shift right, achieved by giving them a smaller stage, not by inventing
   new pixels or cropping people out. */
.hero__bg{
  position:absolute;top:0;right:0;left:var(--hero-split);height:var(--hero-h);
  z-index:0;
}
.hero__bg img{
  width:100%;height:100%;object-fit:cover;
  /* right, not center: if the box is narrower than the photo needs at this
     aspect, the overflow is trimmed from the photo's own left (empty
     trellis/greenery), never from the group's side - so the crop only ever
     helps push them further right, never risks clipping anyone. Vertical
     22% is the same framing knob as before. */
  object-position:right 22%;
}
/* The scrim: solid --surface-2 from the hero's own edge, fading out across
   the photo's own left portion. --surface-2, not the page's plain white
   --surface: it's the same light blue-grey tint #services (right below
   the hero) sits on, so the hero fades into ground that already matches
   the section it hands off to - one continuous tinted zone from the top
   of the page through the services grid, not a white hero sitting on top
   of a separately-tinted section with a seam between them.
   Sized to the actual text, not the column box - hero__inner's max-width
   is a ceiling the words don't always reach ("the connections." only inks
   out to ~38% of the hero at 1440px, well short of the 49%-wide box), and
   an earlier version faded all the way out to +42% on the assumption the
   box's full width needed covering. That overshot James by a wide margin
   (he sits at ~47.5%, measured as zero horizontal crop since the photo box
   is proportionally wider than the image - see hero__bg) and visibly
   washed him out for no legibility reason - the actual words were done
   needing cover 8+ points earlier. +14% clears with real margin past the
   text ink and still stops safely short of him, so he and the rest of the
   group stay at full, unfiltered photo strength. A live gradient over the
   photo (safe to tune freely, unlike a mask that has to match an exact
   background colour) rather than baked into a file - #eaeff4 is
   --surface-2 itself, spelled out because gradient stops can't reference
   a custom property's channels directly. */
.hero::after{
  content:"";position:absolute;inset:0;z-index:1;pointer-events:none;
  background:linear-gradient(to right,
    rgb(234 239 244 / 1) 0%, rgb(234 239 244 / 1) var(--hero-split),
    rgb(234 239 244 / .7) calc(var(--hero-split) + 5%),
    rgb(234 239 244 / .35) calc(var(--hero-split) + 9%),
    rgb(234 239 244 / 0) calc(var(--hero-split) + 14%));
}
.hero__grid{position:relative;z-index:2;padding-inline:var(--gutter)}
/* No longer capped short of --hero-split - the column is sized to run past
   it and overlap the photo, on purpose (see the h1 comment). The extended
   fade above is what makes that safe to read rather than the column
   avoiding the photo entirely. */
.hero__inner{max-width:clamp(20rem,46vw,46rem);text-align:left}

/* The brand mark - icon plus wordmark - large, above the headline. The
   header's own logo+name are hidden until the user scrolls past the hero
   (see .site-header .brand), so this is where the brand actually lives
   on first paint. */
.hero__brand{display:flex;align-items:center;gap:.75rem;margin-bottom:1.4rem}
.hero__mark{height:clamp(2.5rem,4.5vw,3.25rem);width:auto;display:block}
.hero__brand-name{
  font-weight:600;font-size:clamp(1.15rem,1.9vw,1.4rem);letter-spacing:-.01em;
  color:var(--ink);
}

/* Two explicit lines (see the <br> in the markup) - "Care that sees" on
   one, "the connections." on the other, the longer of the two, sized big
   enough on purpose to run out over the photo rather than stop short of
   it. Sized by measuring the real text with the real font - canvas
   measureText() against the loaded Petrona italic bold, not a guessed
   average character width - then solving the font-size and column
   vw-coefficients to reach their caps at the same viewport width (~1600px)
   with a consistent ~21% margin at every point below that, not just at
   whichever widths got screenshotted (an earlier, smaller version of this
   got that wrong exactly that way: it wrapped to three lines on a real
   desktop browser in the gap between where the two clamps hit their caps).
   Regenerate the numbers with the same method if the copy or font changes:
   ctx.font = the h1's real computed font, measure the longer line, require
   column-width-px > 1.15 * measured, at both the --hero-overlay-bp edge and
   wherever the font-size clamp maxes out. */
.hero h1{
  font-size:clamp(2.3rem,5.5vw,5.5rem);font-weight:700;color:var(--ink);
  letter-spacing:-.03em;margin-bottom:.9rem;
}
/* --accent-ink, not the on-photo blue this used when the ground was dark:
   this sits on --surface now, the same light ground every other heading's
   accent colour is tuned for (see its :root comment). */
.hero__accent{color:var(--accent-ink)}

.hero__lead{
  font-size:var(--fs-lead);line-height:1.6;
  color:var(--ink-2);max-width:42ch;
}
.hero__actions{display:flex;flex-wrap:wrap;gap:.7rem;margin-top:1.9rem}

/* Below the breakpoint there is no longer 25% of the viewport's own width
   free before his shoulder, at any column worth reading - and more scrim
   doesn't buy that space back, it just dims the photo enough to hide that
   the words would sit on top of him. So this drops the overlay entirely:
   the section becomes two honest stacked blocks in normal flow, text first
   on its own panel (--surface-2, a shade off pure white - enough to
   separate it from the photo below without a hard rule line), the full
   photo below it - nobody's face is ever behind a line of text. */
@media (max-width:79.9375rem){
  .hero{
    display:flex;flex-direction:column;align-items:stretch;min-height:0;
    padding-block:0;
  }
  .hero__bg{
    position:static;order:2;inset:auto;
    width:100%;height:clamp(16rem,60vw,28rem);
  }
  .hero__bg img{height:100%;object-position:center 30%}
  .hero::after{content:none}
  .hero__grid{
    order:1;z-index:auto;padding:clamp(2.5rem,7vw,3.5rem) var(--gutter);
    background:var(--surface-2);
  }
  .hero__inner{max-width:34rem}
  .hero h1{font-size:clamp(2.2rem,5vw,3.4rem)}
}

/* Live open/closed state. A real semantic indicator computed from real
   published hours, which is the documented exception to the no-dots rule.
   Lives in the Hours panel so the hero keeps to four text elements. */
.status{
  display:inline-flex;align-items:center;gap:.55rem;
  padding:.42rem .95rem .42rem .8rem;margin:1.1rem 0 0;
  border-radius:var(--r-pill);border:1px solid var(--line);
  background:var(--surface);
  font-size:var(--fs-xs);font-weight:500;color:var(--ink-2);
}
.status__dot{width:7px;height:7px;border-radius:50%;background:var(--ink-3);flex:none}
.status.is-open .status__dot{background:#1f9d55;box-shadow:0 0 0 3.5px rgb(31 157 85 / .2)}
.status.is-closed .status__dot{background:#b26a00;box-shadow:0 0 0 3.5px rgb(178 106 0 / .18)}

/* ═══ SECTION 4 · TEAM - round headshots, click-to-expand practitioner bios ═ */
/* Replaces the old full-bleed "leaf" media statement. Copy (name, credential
   line, clinical focus, specialties, "book with X if") is verbatim from the
   client's "Meet Your Care Team" PDF, detailed-profile pages - nothing here
   is invented. Photo, credential line and pull-quote stay visible by
   default; the longer clinical detail sits behind a per-card toggle so
   three practitioners don't turn into a wall of text. Round photo (not a
   cropped rectangle) reads as a person, not a service photo, echoing the
   .dims__dim icon treatment one section up while carrying a real face. */
.team-head{max-width:68rem;margin-bottom:clamp(2.5rem,5vw,3.5rem)}
.team-head h2{font-size:var(--fs-h2);margin-bottom:1rem}

.team-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:1.5rem}
.team-card{
  display:flex;flex-direction:column;align-items:center;text-align:center;
  background:var(--surface-card);border-radius:var(--r-media);
  box-shadow:var(--shadow-sm);
  padding:clamp(1.5rem,3vw,1.9rem) clamp(1.25rem,2.5vw,1.75rem) clamp(1.35rem,2.5vw,1.75rem);
  transition:transform .42s var(--ease),box-shadow .42s var(--ease);
}
.team-card:hover{transform:translateY(-4px);box-shadow:var(--shadow-lg)}

.team-card__photo{
  width:9rem;height:9rem;flex:none;border-radius:50%;overflow:hidden;
  margin-bottom:1rem;border:3px solid var(--surface-2);box-shadow:var(--shadow-sm);
}
.team-card__photo img{width:100%;height:100%;object-fit:cover;display:block}
.team-card__name{font-size:1.3rem;margin-bottom:.3rem}
.team-card__cred{font-size:var(--fs-sm);font-weight:600;color:var(--accent-ink);max-width:24ch;margin-bottom:.3rem}
/* Credential letters get their own quieter line below the title rather
   than living in brackets on the same line - easier to scan, and reads
   correctly however many letters a given person has. */
.team-card__letters{font-size:var(--fs-xs);font-weight:600;color:var(--ink-3);letter-spacing:.02em;max-width:24ch;margin-bottom:1.1rem}
/* Links out to the person's own bio page (see PROFILE PAGE below) rather
   than expanding in place - same outline-pill family as .btn--outline. */
.team-card__cta{
  margin-top:auto;
  display:inline-flex;align-items:center;gap:.5rem;
  padding:.7rem 1.3rem;border-radius:var(--r-pill);
  border:1.5px solid var(--line-strong);
  font-weight:600;font-size:var(--fs-sm);color:var(--ink);
  transition:border-color .25s var(--ease),color .25s var(--ease),background .25s var(--ease);
}
.team-card__cta:hover{border-color:var(--accent);color:var(--accent-ink);background:var(--accent-soft)}
.team-card__cta .icon{width:1.05rem;height:1.05rem;transition:transform .28s var(--ease)}
.team-card__cta:hover .icon{transform:translateX(3px)}

@media (max-width:1040px){
  /* Four practitioners sit 2 x 2 once four across gets tight. */
  .team-grid{grid-template-columns:1fr 1fr;gap:1.5rem}
}
@media (max-width:480px){
  .team-grid{grid-template-columns:1fr 1fr;gap:1rem}
  .team-card{padding:1.25rem .75rem 1.35rem}
  .team-card__cta{white-space:nowrap;gap:.4rem;padding:.6rem .85rem;font-size:.9rem}
  .team-card__photo{width:6.5rem;height:6.5rem}
}

/* ═══ SECTION 3 · DIMENSIONS - three distinct zones, not one long scroll ═══ */
/* A soft, oversized blurred wash behind the intro only (the two panels
   below paint their own opaque backgrounds over it) - texture, not noise,
   kept purely decorative and behind everything else in the section. */
.dims{overflow:hidden}
.dims::before{
  content:"";position:absolute;top:-18%;right:-12%;
  width:min(46vw,620px);height:min(46vw,620px);
  background:radial-gradient(circle,var(--accent-soft) 0%,transparent 72%);
  z-index:0;pointer-events:none;
}
.dims::after{
  content:"";position:absolute;bottom:-22%;left:-14%;
  width:min(34vw,460px);height:min(34vw,460px);
  background:radial-gradient(circle,var(--accent-soft) 0%,transparent 72%);
  opacity:.7;z-index:0;pointer-events:none;
}
.dims .shell{position:relative;z-index:1}

.dims__intro{max-width:44rem;margin-bottom:clamp(2.5rem,5vw,3.5rem)}
.dims__intro h2{font-size:var(--fs-h2);margin-bottom:1.1rem;line-height:1.18}
.dims__intro .lead{margin-bottom:.9rem}
.dims__intro--center{margin-inline:auto;text-align:center}
.dims__intro--center .lead,.dims__intro--center .body{margin-inline:auto}

/* Bordered pill badge, distinct from the plain uppercase .eyebrow used
   elsewhere - this section's intro is doing more visual work up top. */
.dims__pill{
  display:inline-block;margin-bottom:1.4rem;padding:.5rem 1.25rem;
  border:1.5px solid rgb(3 78 161 / .3);border-radius:var(--r-pill);
  background:var(--accent-soft);color:var(--accent-ink);
  font-size:var(--fs-xs);font-weight:700;letter-spacing:.06em;text-transform:uppercase;
}
.dims__accent{color:var(--accent)}

/* Shared pill badge (same visual language as .dims__pill), for any section
   intro that needs a small label above its heading rather than a plain
   .eyebrow - e.g. the homepage team-head. */
.pill-badge{
  display:inline-block;margin-bottom:1.4rem;padding:.5rem 1.25rem;
  border:1.5px solid rgb(3 78 161 / .3);border-radius:var(--r-pill);
  background:var(--accent-soft);color:var(--accent-ink);
  font-size:var(--fs-xs);font-weight:700;letter-spacing:.06em;text-transform:uppercase;
}
.pill-badge--below{margin-top:.4rem;margin-bottom:0}

.dims__highlights{
  display:flex;flex-wrap:wrap;justify-content:center;gap:1.5rem 2.25rem;
  margin-top:1.75rem;padding-top:1.75rem;border-top:1px solid var(--line);
}
.dims__highlight{
  display:inline-flex;align-items:center;gap:.5rem;
  font-weight:700;font-size:var(--fs-sm);color:var(--ink);
}
.dims__highlight .icon{width:1.05rem;height:1.05rem;color:var(--accent);stroke-width:1.8}

/* Zone 2: the six dimensions get their own raised, opaque panel - reads as
   a distinct module sitting on the section, not a continuation of the
   intro's plain background. */
.dims__grid{
  background:var(--surface-card);border-radius:var(--r-panel);
  box-shadow:var(--shadow-sm);
  padding:clamp(2.25rem,5vw,3.25rem) clamp(1.25rem,4vw,2.5rem);
}
.dims__head{margin-bottom:2rem;text-align:center}
.dims__head h3{font-size:var(--fs-h3)}

/* Round icon + name, no card box - the description is hidden until tapped.
   max-height (not the fancier grid-rows trick) is the transition target:
   simpler, and 200px comfortably clears every description here without
   needing to measure real content height. Hover/focus previews the same
   solid-fill state a tap commits to, plus a small lift, so the icons read
   as clickable before anyone actually clicks one. */
.dims__cards{display:grid;grid-template-columns:repeat(3,1fr);gap:1.5rem 1rem}
.dims__dim{
  display:flex;flex-direction:column;align-items:center;text-align:center;
  background:none;border:none;padding:.5rem;cursor:pointer;font-family:inherit;
  -webkit-tap-highlight-color:transparent;
}
.dims__dim-icon{
  display:flex;align-items:center;justify-content:center;
  width:4.5rem;height:4.5rem;border-radius:50%;margin-bottom:.85rem;
  background:var(--accent-soft);color:var(--accent-ink);
  transition:background .25s var(--ease),color .25s var(--ease),
             transform .25s var(--ease),box-shadow .25s var(--ease);
}
.dims__dim-icon .icon{width:2rem;height:2rem;stroke-width:1.7}
.dims__dim:hover .dims__dim-icon,
.dims__dim:focus-visible .dims__dim-icon{
  background:var(--accent);color:var(--on-accent);
  transform:translateY(-4px) scale(1.06);
  box-shadow:var(--shadow-md);
}
.dims__dim[aria-expanded="true"] .dims__dim-icon{background:var(--accent);color:var(--on-accent)}
.dims__dim-name{font-weight:700;font-size:1.05rem;color:var(--ink)}
.dims__dim-desc{
  display:block;max-width:20ch;max-height:0;opacity:0;overflow:hidden;
  font-size:var(--fs-sm);color:var(--ink-2);line-height:1.5;
  transition:max-height .35s var(--ease),opacity .3s var(--ease),margin-top .35s var(--ease);
}
.dims__dim[aria-expanded="true"] .dims__dim-desc{max-height:200px;opacity:1;margin-top:.6rem}

/* Mouse/trackpad only: reveal on hover too, and reserve the description's
   space up front (fixed height, opacity-only transition) so moving between
   cards in the grid doesn't reflow neighbouring rows. Touch devices skip
   this - there's no hover there, and permanently reserving ~9em under every
   card just for a tap target would waste huge amounts of vertical space on
   a phone, so touch keeps the plain collapse/expand-on-tap above. */
@media (hover:hover) and (pointer:fine){
  .dims__dim-desc{max-height:none;min-height:4.5em;margin-top:.6rem}
  .dims__dim:hover .dims__dim-desc,
  .dims__dim:focus-visible .dims__dim-desc{opacity:1}
}

@media (max-width:700px){
  .dims__cards{grid-template-columns:1fr 1fr;gap:1.75rem 1rem}
  .dims__dim-icon{width:4rem;height:4rem}
}

/* Zone 3: "how your care connects" gets the brand's own solid accent
   colour (same block used for the closing CTA lower on the page) instead
   of another light panel, so it doesn't just read as "zone 2, again" -
   deliberately the boldest of the three zones. */
.dims__connects{
  margin-top:clamp(2.5rem,5vw,3.5rem);
  background:var(--accent);color:#fff;
  border-radius:var(--r-panel);
  padding:clamp(2.25rem,5vw,3.25rem) clamp(1.25rem,4vw,2.5rem);
  text-align:center;
}
.dims__connects h3{font-size:var(--fs-h3);margin-bottom:1.75rem;color:#fff}
.dims__connects-grid{
  display:grid;grid-template-columns:repeat(4,1fr);gap:clamp(1.5rem,3vw,2rem);
  max-width:64rem;margin-inline:auto;text-align:left;
}
.dims__connect-icon{
  display:flex;align-items:center;justify-content:center;
  width:2.75rem;height:2.75rem;border-radius:50%;margin-bottom:1rem;
  background:rgb(255 255 255 / .16);color:#fff;
}
.dims__connect-icon .icon{width:1.3rem;height:1.3rem;stroke-width:2}
.dims__connect h4{font-size:1.05rem;font-weight:700;margin-bottom:.4rem;color:#fff}
.dims__connect p{font-size:var(--fs-sm);color:rgb(255 255 255 / .82);line-height:1.55}

@media (max-width:820px){
  .dims__connects-grid{grid-template-columns:1fr 1fr;text-align:center}
  .dims__connect-icon{margin-inline:auto}
}
@media (max-width:520px){
  .dims__connects-grid{grid-template-columns:1fr}
}

/* ═══ SECTION 2 · SERVICES - real photo + circular icon per card ══════════ */
/* Exactly 3 cells for 3 disciplines, all the same size on purpose: this
   reads as three equally-weighted choices, not a "featured" one and two
   runners-up. Photo-plus-icon-badge-plus-plain-body card (reference:
   wildewoodhealth.com's services cards), not the old photo-with-text-
   overlaid-on-top treatment - a real, separate content area reads more
   clearly as "information about a service" than type sitting on a photo. */
.svc-head{max-width:62ch;margin-bottom:clamp(2.5rem,5vw,3.5rem)}
.svc-head h2{font-size:var(--fs-h2);margin-bottom:1rem}
/* Centered variant (massage-therapy.html's Technique Architecture /
   Targeted Relief / Patient Profiles intros) - same component, just
   centered in the shell rather than left-aligned. */
.svc-head--center{margin-inline:auto;text-align:center}
.svc-head--center .lead,.svc-head--center .body{margin-inline:auto}

.svc-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:1.75rem}
.svc{
  display:flex;flex-direction:column;
  background:var(--surface-card);border-radius:var(--r-media);
  box-shadow:var(--shadow-sm);
  transition:transform .42s var(--ease),box-shadow .42s var(--ease);
}
.svc:hover{transform:translateY(-4px);box-shadow:var(--shadow-lg)}

.svc__media{position:relative}
.svc__media img{
  display:block;width:100%;aspect-ratio:4/3;object-fit:cover;
  border-radius:var(--r-media) var(--r-media) 0 0;
  transition:transform .8s var(--ease);
}
.svc:hover .svc__media img{transform:scale(1.045)}
.svc--hover-swap .svc__media{position:relative;overflow:hidden}
.svc__media .svc__img-hover{
  position:absolute;top:0;right:0;bottom:0;left:0;width:100%;height:100%;
  opacity:0;transition:opacity 1.1s ease;
}
.svc--hover-swap:hover .svc__media .svc__img-hover{opacity:1}
/* The badge straddles the photo/body seam (wildewoodhealth.com's move):
   pulled up by half its own height with a negative top + matching negative
   margin-bottom, so it pokes into the photo above without needing absolute
   positioning pinned to the photo's own (fluid, aspect-ratio-driven)
   height. A solid ring in the card's own background color separates its
   edge from the photo behind it, same idea as their teal ring on white. */
.svc__icon{
  position:relative;top:-1.75rem;margin-bottom:-1.75rem;left:1.75rem;
  display:flex;align-items:center;justify-content:center;
  width:3.5rem;height:3.5rem;border-radius:50%;
  background:var(--accent);color:var(--on-accent);
  border:4px solid var(--surface-card);
  box-shadow:var(--shadow-md);
}
.svc__icon .icon{width:1.5rem;height:1.5rem;stroke-width:1.8}

.svc__body{padding:1.5rem 1.75rem 1.75rem}
.svc h3{font-size:clamp(1.35rem,2vw,1.6rem);font-weight:700;margin-bottom:.3rem}
/* Sentence case on purpose: functional information about who you would
   see, not a decorative uppercase eyebrow. */
.svc__who{
  display:block;font-size:var(--fs-sm);font-weight:500;
  color:var(--ink-2);margin-bottom:1.1rem;
}

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

/* ═══ MEET THE OWNERS PAGE (meet-the-owners.html) ═════════════════════════ */
/* Client-supplied copy, kept word for word (one punctuation exception noted
   in the HTML). Intro: sticky-photo-beside-copy, same treatment the old
   homepage "meet the owners" section used (a real candid portrait rather
   than matched studio headshots, so no compositing needed). Below it, the
   "who we serve" paragraph becomes three scannable cards instead of a wall
   of text, and the piece closes on a quieter editorial note rather than
   another sales pitch - the quote gets room to breathe before the page
   still ends, gently, on a path to book. */
.owners{
  display:grid;grid-template-columns:minmax(260px,38%) 1fr;
  gap:clamp(2rem,5vw,4.5rem);align-items:start;
}
.owners__media{
  position:sticky;top:96px;border-radius:var(--r-media);overflow:hidden;
  box-shadow:var(--shadow-md);
}
.owners__media img{width:100%;height:auto;display:block}
.owners__content h1{font-size:var(--fs-h1);margin-bottom:1.1rem}
.owners__content .lead{margin-bottom:1.1rem;color:var(--ink);font-weight:500}
.owners__content .body{color:var(--ink-2);max-width:56ch}
.owners__content .body--dark{color:var(--ink);font-weight:500}

/* Who We Serve: same icon-circle-plus-copy language as the six dimensions
   of health further up the site's information architecture, so this reads
   as part of the same family rather than a one-off card style. */
.serve-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:1.75rem}
.serve-card{
  background:var(--surface-card);border-radius:var(--r-media);
  box-shadow:var(--shadow-sm);padding:clamp(2rem,4vw,2.5rem) clamp(1.5rem,3vw,2rem);
  transition:transform .32s var(--ease),box-shadow .32s var(--ease);
}
.serve-card:hover{transform:translateY(-4px);box-shadow:var(--shadow-lg)}
.serve-card--wide{grid-column:1 / -1}
.serve-card__icon{
  display:flex;align-items:center;justify-content:center;
  width:3.25rem;height:3.25rem;border-radius:50%;margin-bottom:1.25rem;
  background:var(--accent-soft);color:var(--accent-ink);
}
.serve-card__icon .icon{width:1.5rem;height:1.5rem;stroke-width:1.7}
.serve-card h3,.serve-card h4{font-size:1.15rem;margin-bottom:.6rem;line-height:1.3}
.serve-card p{color:var(--ink-2);font-size:var(--fs-sm);line-height:1.65;text-wrap:pretty}

/* The closing quote: an editorial pause, not another CTA block, so it gets
   a plain surface and a large decorative mark instead of the brand-blue
   treatment used elsewhere for sales moments. */
.quote-block{
  max-width:52rem;margin-inline:auto;text-align:center;
  padding-block:clamp(1rem,3vw,2rem);
}
.quote-block__mark{width:2.5rem;height:2.5rem;color:var(--accent-soft);fill:var(--accent-soft);margin-inline:auto;margin-bottom:1.25rem}
.quote-block p{
  font-family:"Petrona",Georgia,"Times New Roman",serif;
  font-size:clamp(1.2rem,2.4vw,1.6rem);font-weight:500;font-style:italic;
  color:var(--ink);line-height:1.55;
}
.quote-block--lg p{font-size:clamp(1.5rem,3.4vw,2.2rem);line-height:1.4}
.quote-block cite{
  display:block;margin-top:1.5rem;font-style:normal;
  font-size:var(--fs-sm);font-weight:600;color:var(--ink-3);
  letter-spacing:.02em;
}
.quote-block cite::before{content:"\2014  "}

.quote-block__actions{
  display:flex;flex-wrap:wrap;justify-content:center;gap:.8rem;
  margin-top:clamp(2.5rem,5vw,3.5rem);
}

/* "Meaningful Collaboration" (meet-the-owners.html, replacing the old
   "Who We Serve" grid) - built from the same pieces as the rest of the
   page (.dims__pill, .serve-grid--quad cards, .quote-block) so it reads
   as this page's own voice, not a bolted-on section. The dandelion
   metaphor in the copy gets its own card (.collab-panel) so it lands as
   a considered pause rather than just more body text sitting on the
   illustrated backdrop behind it. */
.collab-intro{max-width:46rem;margin-bottom:clamp(2.5rem,5vw,3.5rem)}
.collab-intro h2{font-size:var(--fs-h2);margin-bottom:1.1rem;line-height:1.18}

.collab-panel{
  background:var(--surface-card);border-radius:var(--r-media);
  box-shadow:var(--shadow-sm);padding:clamp(1.75rem,4vw,2.75rem);
  max-width:44rem;margin-bottom:clamp(2.5rem,5vw,3.5rem);
}
.collab-panel__icon{
  display:flex;align-items:center;justify-content:center;
  width:3rem;height:3rem;border-radius:50%;margin-bottom:1.1rem;
  background:var(--accent-soft);color:var(--accent-ink);
}
.collab-panel__icon .icon{width:1.4rem;height:1.4rem;stroke-width:1.7}
.collab-panel h3{font-size:1.25rem;margin-bottom:.9rem}
.collab-panel p{color:var(--ink-2);line-height:1.7}
.collab-panel p + p{margin-top:.9rem}

.collab-network h3{font-size:1.25rem;margin-bottom:.6rem}
.collab-network > p{color:var(--ink-2);max-width:56ch;margin-bottom:1.75rem}

/* The dandelion photo is wide (~16:9) and this section's box is tall
   (stacked intro + panel + card grid + quote push it well past a single
   viewport), so a plain object-fit:cover would scale the photo up to
   fill that height and crop away most of its width - exactly the part
   carrying the seeds trailing left. object-fit:contain instead shows the
   photo at its own aspect ratio, full composition intact (head and every
   drifting seed), pinned to the top of the section, right below the
   seam. Opacity is higher than a typical photo backdrop (.32) because
   this source is itself pale (near-white), so it needs the boost to read
   clearly rather than wash out.

   The wrapper itself is sized to the photo's own aspect ratio (not the
   full, much taller .section-photobg__media default) so it hugs the
   image exactly instead of leaving empty box below it - that's what lets
   the existing .section-photobg__media::after gradient (transparent to
   the section's tint by 88% down the box) fade out right at the photo's
   own bottom edge instead of fading across mostly-empty space further
   down the section. (.section-photobg__media.collab-bg, not just
   .collab-bg, so this beats the later, equal-specificity
   .section-photobg__media img rule in the cascade instead of quietly
   losing to it.) */
.section-photobg__media.collab-bg{
  inset:auto;top:0;left:0;right:0;height:auto;aspect-ratio:1600/893;
}
.section-photobg__media.collab-bg img{
  opacity:.6;object-fit:contain;object-position:center top;
}

@media (max-width:820px){
  .owners{grid-template-columns:1fr;gap:2rem}
  .owners__media{position:static;max-width:360px;margin-inline:auto}
  .serve-grid{grid-template-columns:1fr}
}
@media (max-width:600px){.collab-panel{padding:1.5rem}}

/* ═══ SECTION 6 · LOCATIONS - carousel card + coming-soon card ════════════ */
/* Click-driven, like the dimensions tablist: arrows and dots, no scroll
   listeners, no autoplay (autoplay fights the reveal choreography and takes
   the pace away from whoever is looking). Both cards stretch to the grid
   row's height by default, so "coming soon" carries equal visual weight
   instead of reading as an afterthought next to the real, photographed one. */
.locations-grid{display:grid;grid-template-columns:repeat(2,1fr);gap:clamp(1.25rem,3vw,2rem)}
.location-card{
  background:var(--surface-card);border:1px solid var(--line);
  border-radius:var(--r-panel);overflow:hidden;
}
.location-card__carousel{position:relative;aspect-ratio:4/3;background:var(--surface-2)}
.location-card__carousel img{
  position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
  opacity:0;transition:opacity .5s var(--ease);
}
.location-card__carousel img.is-active{opacity:1}
/* Local scrim behind the dots only, independent of how bright any one photo
   runs, so the row of dots always clears WCAG AA. */
.location-card__carousel::after{
  content:"";position:absolute;inset:auto 0 0 0;height:64px;pointer-events:none;
  background:linear-gradient(0deg,rgb(6 13 20 / .58),rgb(6 13 20 / 0));
}
.location-card__arrow{
  position:absolute;top:50%;translate:0 -50%;z-index:1;
  width:38px;height:38px;border-radius:var(--r-pill);
  display:flex;align-items:center;justify-content:center;
  background:rgb(6 13 20 / .58);color:#fff;
  backdrop-filter:blur(6px);-webkit-backdrop-filter:blur(6px);
  transition:background .22s var(--ease),transform .22s var(--ease);
}
.location-card__arrow:hover{background:rgb(6 13 20 / .72)}
.location-card__arrow:active{transform:translateY(-50%) scale(.94)}
.location-card__arrow--prev{left:.75rem}
.location-card__arrow--next{right:.75rem}
.location-card__dots{
  position:absolute;bottom:.85rem;left:50%;translate:-50% 0;z-index:1;
  display:flex;
}
/* Dots are a WCAG 2.2 target-size fix: the visible dot stays a small 7px mark
   (::before), but each button's own hit box is a full 24x24 CSS px square so
   the control is actually tappable. Boxes sit flush edge-to-edge (no gap) so
   hit areas never overlap one another. */
.location-card__dot{
  width:24px;height:24px;background:none;
  display:flex;align-items:center;justify-content:center;
}
.location-card__dot::before{
  content:"";width:7px;height:7px;border-radius:50%;
  background:rgb(255 255 255 / .75);
  transition:background .18s var(--ease);
}
.location-card__dot.is-active::before{background:#fff}

.location-card__info{padding:clamp(1.25rem,2.5vw,1.75rem)}
.location-card__info h3{font-size:var(--fs-h3);margin-bottom:.35rem}
.location-card__address{font-size:var(--fs-sm);color:var(--ink-2);margin-bottom:.7rem}
.location-card__directions{display:inline-flex;margin-bottom:1rem}
.location-card__contact{font-size:var(--fs-sm);line-height:1.7}
.location-card__hours{font-size:var(--fs-sm);color:var(--ink-2);margin-top:.7rem}
.location-card__info .status{margin-top:.6rem}

.location-card--soon{display:flex;flex-direction:column}
.location-card__photo{
  position:relative;aspect-ratio:4/3;background:var(--surface-2);overflow:hidden;
  display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center;
  padding:clamp(1.25rem,2.5vw,1.75rem);
}
.location-card__photo img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
/* Text sits centered over the photo rather than just along the bottom, so
   the darkening needs to cover the middle of the frame too, not only a
   bottom band - an even tint plus a slightly deeper vignette behind the
   text keeps it readable no matter how bright the sky/water are. */
.location-card__photo::after{
  content:"";position:absolute;inset:0;pointer-events:none;
  background:
    radial-gradient(ellipse at center, rgb(6 13 20 / .5) 0%, rgb(6 13 20 / .25) 60%, rgb(6 13 20 / .3) 100%);
}
.location-card__photo > *{position:relative;z-index:1}
.location-card__badge{
  display:inline-block;padding:.3rem .8rem;border-radius:var(--r-pill);
  background:var(--accent-soft);color:var(--accent-ink);
  font-size:var(--fs-xs);font-weight:600;letter-spacing:.04em;text-transform:uppercase;
  margin-bottom:.75rem;
}
/* On a photo, a translucent white chip alone can't guarantee contrast since
   its brightness depends on whatever's blurred behind it - a dark,
   semi-opaque chip plus a text-shadow keeps the label readable against any
   photo, not just this one. */
.location-card__photo .location-card__badge{
  background:rgb(6 13 20 / .55);color:#fff;
  backdrop-filter:blur(6px);-webkit-backdrop-filter:blur(6px);
  text-shadow:0 1px 2px rgb(0 0 0 / .35);
}
.location-card__photo h3{font-size:var(--fs-h3);color:#fff;margin:0;text-shadow:0 1px 6px rgb(0 0 0 / .5)}
.location-card--soon .location-card__info{padding:clamp(1.25rem,2.5vw,1.75rem)}
.location-card--soon .body{max-width:34ch}

/* Placeholder variant for a location with no photo yet - a flat skyline
   silhouette standing in for the real thing, with the badge/title
   enlarged and centered on it rather than pinned bottom-left. */
.location-card__photo--placeholder{
  align-items:center;justify-content:center;text-align:center;gap:.6rem;
  background:linear-gradient(160deg, var(--surface-2), var(--accent-soft));
}
.location-card__photo--placeholder::after{display:none}
.location-card__silhouette{
  position:absolute;left:0;right:0;bottom:0;width:100%;height:60%;
  color:rgb(6 13 20 / .13);z-index:0;
}
.location-card__photo--placeholder .location-card__badge{
  background:var(--surface-card);color:var(--accent-ink);
  font-size:var(--fs-sm);padding:.45rem 1.1rem;margin-bottom:0;
}
.location-card__photo--placeholder h3{color:var(--ink);font-size:clamp(1.4rem,3vw,1.9rem)}

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

/* ═══ SECTION 7 · CLOSING CTA - brand colour block ════════════════════════ */
.cta{background:var(--accent);color:#fff;text-align:center;position:relative}
.cta__inner{padding-block:clamp(4rem,8vw,6.5rem);max-width:44rem;margin-inline:auto}
.cta h2{font-size:var(--fs-h2);margin-bottom:1.1rem}
.cta p{color:rgb(255 255 255 / .88);font-size:var(--fs-lead);margin-inline:auto;max-width:46ch}
.cta__actions{display:flex;flex-wrap:wrap;gap:.8rem;justify-content:center;margin-top:2.1rem}
.cta__note{margin-top:1.5rem;font-size:var(--fs-xs);color:rgb(255 255 255 / .72)}

/* Bio pills: a lighter-weight second tier of action below the main book
   button (meet-the-owners.html's closing CTA) - a face plus a name reads
   as "get to know them first" rather than competing with "Book" as an
   equal, same-weight button would. */
.cta__bios{display:flex;flex-wrap:wrap;justify-content:center;gap:1rem;margin-top:1.75rem}
.cta__bio{
  display:inline-flex;align-items:center;gap:.7rem;
  padding:.5rem 1.35rem .5rem .5rem;border-radius:var(--r-pill);
  background:rgb(255 255 255 / .1);border:1.5px solid rgb(255 255 255 / .28);
  color:#fff;font-weight:600;font-size:var(--fs-sm);
  transition:background .25s var(--ease),border-color .25s var(--ease),transform .2s var(--ease);
}
.cta__bio:hover{background:rgb(255 255 255 / .18);border-color:rgb(255 255 255 / .5);transform:translateY(-2px)}
.cta__bio img{width:2.5rem;height:2.5rem;border-radius:50%;object-fit:cover;border:1.5px solid rgb(255 255 255 / .55)}

/* ── Footer ──────────────────────────────────────────────────────────────── */
.site-footer{background:var(--surface-2);border-top:1px solid var(--line);padding-block:clamp(3rem,6vw,4.5rem) 2rem}
.site-footer__grid{display:grid;grid-template-columns:1.5fr repeat(3,1fr);gap:clamp(1.75rem,4vw,3rem)}
.site-footer .brand{margin-bottom:1rem}
.site-footer__about{font-size:var(--fs-sm);color:var(--ink-2);max-width:30ch}
.footer-col h3{font-family:"Onest",Arial,sans-serif;font-size:var(--fs-xs);font-weight:600;letter-spacing:.1em;text-transform:uppercase;color:var(--ink-3);margin-bottom:1.1rem}
.footer-col li + li{margin-top:.7rem}
.footer-col a,.footer-col span{font-size:var(--fs-sm);color:var(--ink-2);transition:color .22s var(--ease)}
.footer-col a:hover{color:var(--accent-ink)}
.site-footer__base{
  margin-top:clamp(2.5rem,5vw,3.5rem);padding-top:1.5rem;border-top:1px solid var(--line);
  display:flex;justify-content:space-between;gap:1rem;flex-wrap:wrap;
  font-size:var(--fs-xs);color:var(--ink-3);
}
@media (max-width:760px){
  .site-footer__grid{grid-template-columns:1fr 1fr}
  .site-footer__about{max-width:none}
}
@media (max-width:480px){
  .site-footer__grid{grid-template-columns:1fr}
}

/* ═══ PROFILE PAGE - one per practitioner (erin-chaba.html etc.) ══════════ */
/* Two zones: a "snapshot" hero (photo + the same at-a-glance facts that
   used to live in the homepage card's dropdown - quote, clinical focus,
   specialties, book-with-X-if) or, below it, "Full bio" - each person's
   real bio copy, carried over word for word from their own existing site
   (multidimensionalhealth.ca for Erin/James, kaylalarsenphysiotherapy.ca
   for Kayla) and broken into readable blocks rather than one long slab. */
.profile-intro{padding-block:clamp(2.5rem,5vw,3.5rem) 0}
.profile-back{
  display:inline-flex;align-items:center;gap:.5rem;
  font-size:var(--fs-sm);font-weight:600;color:var(--ink-2);margin-bottom:1.5rem;
  transition:color .22s var(--ease);
}
.profile-back:hover{color:var(--accent-ink)}
.profile-back .icon{width:1.05rem;height:1.05rem;transition:transform .25s var(--ease)}
.profile-back:hover .icon{transform:translateX(-3px)}

.profile-hero{
  display:grid;grid-template-columns:minmax(200px,260px) 1fr;
  gap:clamp(2rem,5vw,3.5rem);align-items:start;
  padding-block:clamp(2rem,4vw,3rem) clamp(3rem,6vw,4.5rem);
}
.profile-hero__photo{
  width:100%;aspect-ratio:1;border-radius:50%;overflow:hidden;
  border:4px solid var(--surface-card);box-shadow:var(--shadow-md);
  position:sticky;top:96px;
}
.profile-hero__photo img{width:100%;height:100%;object-fit:cover;display:block}

.profile-hero__name{font-size:var(--fs-h2);margin-bottom:.35rem}
.profile-hero__cred{font-size:1.05rem;font-weight:600;color:var(--accent-ink);margin-bottom:.3rem}
/* Credential letters get their own quieter line below the title rather
   than living in brackets on the same line. */
.profile-hero__letters{font-size:var(--fs-sm);font-weight:600;color:var(--ink-3);letter-spacing:.02em;margin-bottom:1.25rem}
.profile-hero__quote{
  font-style:italic;color:var(--ink);font-size:var(--fs-lead);line-height:1.55;
  max-width:38ch;margin-bottom:1.75rem;padding-left:1.1rem;border-left:3px solid var(--accent);
}
.profile-hero__section{margin-bottom:1.75rem}
.profile-hero__section h2{font-size:.8rem;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--ink);margin-bottom:.6rem}
.profile-hero__section p{color:var(--ink-2);font-size:var(--fs-sm);line-height:1.65;max-width:56ch}

.profile-tags{display:flex;flex-wrap:wrap;gap:.5rem}
.profile-tags li{
  padding:.4rem .9rem;border-radius:var(--r-pill);
  background:var(--accent-soft);color:var(--accent-ink);
  font-size:var(--fs-xs);font-weight:600;
}

.profile-callout{padding:1.1rem 1.25rem;border-radius:var(--r-input);background:var(--surface-2);border-left:3px solid var(--accent);max-width:56ch}
.profile-callout-label{display:block;font-size:var(--fs-xs);font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--accent-ink);margin-bottom:.4rem}
.profile-callout-label--sentence{
  font-size:1.1rem;font-weight:700;letter-spacing:normal;text-transform:none;
  font-family:"Petrona",Georgia,"Times New Roman",serif;font-style:italic;
}
.profile-callout p{color:var(--ink-2);font-size:var(--fs-sm);line-height:1.55}

.profile-hero__actions{display:flex;flex-wrap:wrap;gap:.8rem;margin-top:2rem}

@media (max-width:760px){
  .profile-hero{grid-template-columns:1fr}
  .profile-hero__photo{width:9rem;height:9rem;margin-inline:auto;position:static}
  .profile-hero__name,.profile-hero__cred,.profile-hero__letters{text-align:center}
  .profile-hero__quote{margin-inline:auto;text-align:left}
  .profile-hero__actions{justify-content:center}
}

/* Zone 2: the real, word-for-word bio, visually broken up so it reads as
   distinct sections rather than a wall of text. */
.profile-bio{border-top:1px solid var(--line);padding-block:clamp(3rem,6vw,4.5rem)}
.profile-bio__head{max-width:44rem;margin-bottom:clamp(2rem,4vw,3rem)}
.profile-bio__head h2{font-size:var(--fs-h2);margin-bottom:.75rem}

/* Membership / personal-interest line from the source bio (e.g. "Osteopathy
   BC Member", "CMTBC Registered", "Nature enthusiast") - a plain fact line,
   not the clinical specialties from the snapshot above, so it gets its own
   quieter tag treatment. */
.profile-bio__meta{display:flex;flex-wrap:wrap;gap:.5rem;margin-bottom:2.5rem}
.profile-bio__meta li{
  padding:.4rem .9rem;border-radius:var(--r-pill);
  border:1px solid var(--line-strong);color:var(--ink-2);
  font-size:var(--fs-xs);font-weight:500;
}
.profile-bio__meta li a{color:var(--accent-ink);text-decoration:underline;text-underline-offset:.15em}
.profile-bio__meta li a:hover{color:var(--accent)}

.profile-bio__stack{display:flex;flex-direction:column;gap:clamp(2rem,4vw,2.75rem);max-width:64rem}
.profile-bio__block h3{font-size:var(--fs-h3);margin-bottom:.9rem}
.profile-bio__block p{color:var(--ink-2);font-size:var(--fs-body);line-height:1.75;max-width:68ch}
.profile-bio__block p + p{margin-top:1.1rem}

.profile-quote{
  max-width:44rem;margin-block:.5rem;padding:clamp(1.5rem,3vw,2rem) clamp(1.75rem,4vw,2.5rem);
  background:var(--accent-soft);border-radius:var(--r-panel);
  font-family:"Petrona",Georgia,"Times New Roman",serif;
  font-size:clamp(1.1rem,1.8vw,1.35rem);font-weight:700;color:var(--accent-ink);line-height:1.45;
}

.profile-quote__by{display:block;margin-top:.7rem;font-family:"Onest",system-ui,sans-serif;font-size:var(--fs-sm);font-weight:600;font-style:normal;color:var(--ink-3)}
.profile-bio__block p + .profile-list,.profile-bio__block .profile-list + p{margin-top:1.1rem}

.profile-list{display:flex;flex-direction:column;gap:.85rem;max-width:60ch}
.profile-list li{position:relative;padding-left:1.4rem;color:var(--ink-2);font-size:var(--fs-body);line-height:1.6}
.profile-list li::before{
  content:"";position:absolute;left:0;top:.55em;width:6px;height:6px;
  border-radius:50%;background:var(--accent);
}
.profile-list--inline{flex-direction:row;flex-wrap:wrap;gap:1.5rem}
.profile-list--inline li{padding-left:1.4rem}

/* Kayla's "fun facts" grid - short factoid cards, not full prose blocks. */
.profile-facts{display:grid;grid-template-columns:repeat(3,1fr);gap:1.25rem;max-width:64rem}
.profile-facts__card{
  background:var(--surface-card);border-radius:var(--r-media);
  box-shadow:var(--shadow-sm);padding:1.5rem 1.6rem;
}
.profile-facts__card h4{font-size:.78rem;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--accent-ink);margin-bottom:.6rem}
.profile-facts__card p{color:var(--ink-2);font-size:var(--fs-sm);line-height:1.6}

/* Kayla's education/experience timeline. */
.profile-timeline{display:flex;flex-direction:column;max-width:56rem}
.profile-timeline__row{
  display:grid;grid-template-columns:6.5rem 1fr;gap:1.5rem;
  padding-block:1.25rem;border-top:1px solid var(--line);
}
.profile-timeline__row:last-child{border-bottom:1px solid var(--line)}
.profile-timeline__year{font-weight:700;color:var(--accent-ink);font-size:var(--fs-sm)}
.profile-timeline__row h4{font-size:1.05rem;font-weight:700;margin-bottom:.3rem}
.profile-timeline__row p{color:var(--ink-2);font-size:var(--fs-sm);line-height:1.6}

/* Continuing-education year groups (erin-chaba.html, james-boyce.html):
   reuses the FAQ accordion's exact markup/JS (any .faq-item on the page
   gets the same click-to-toggle behaviour for free), just with a year +
   count as the question and a compact single-column timeline as the
   answer, instead of repeating the year on every row. */
.timeline-year-groups{display:flex;flex-direction:column;gap:.75rem;max-width:56rem}
.timeline-year-toggle__count{font-size:var(--fs-xs);font-weight:500;color:var(--ink-3)}
.timeline-year-group .faq-item__a > div{padding:0 1.4rem 1.1rem}
.profile-timeline--grouped{max-width:none}
.profile-timeline--grouped .profile-timeline__row{
  display:block;grid-template-columns:none;padding-block:.85rem;
}
.profile-timeline--grouped .profile-timeline__row:first-child{border-top:none;padding-top:0}

@media (max-width:820px){
  .profile-facts{grid-template-columns:1fr 1fr}
}
@media (max-width:600px){
  .profile-facts{grid-template-columns:1fr}
  .profile-timeline__row{grid-template-columns:1fr;gap:.35rem}
}

/* ── Motion: reveal choreography ─────────────────────────────────────────── */
/* Driven by IntersectionObserver in js/mdh.js. No scroll listeners anywhere.
   Purpose: hierarchy. Content arrives in reading order as you reach it. */
@media (prefers-reduced-motion:no-preference){
  [data-reveal]{
    opacity:0;transform:translateY(22px);
    transition:opacity .72s var(--ease),transform .72s var(--ease);
    transition-delay:calc(var(--d,0) * 90ms);
  }
  [data-reveal].is-in{opacity:1;transform:none}

  /* Hero arrives on load rather than on scroll: it is already in view. */
  .hero [data-enter]{opacity:0;transform:translateY(18px);animation:enter .78s var(--ease) forwards;animation-delay:calc(var(--d,0) * 95ms + 80ms)}
  @keyframes enter{to{opacity:1;transform:none}}

  /* Hero photo parallax: drifts a couple of percent as the hero scrolls
     past, so the photo reads as sitting slightly behind the page rather
     than pinned flat to it. Scroll-driven via animation-timeline, not a
     scroll listener - still zero of those anywhere on the site. Feature-
     detected: browsers without it (Firefox, older Safari) just keep the
     plain static photo, no broken half-state, since the enlarge-and-drift
     rule only exists inside this @supports block.
     transform only, never a change to width/height/object-position: those
     drive the crop math the whole hero's clearance is built on (see the
     hero comments above), and a transform is purely visual on top of the
     already-laid-out box, so none of that math needs to know this exists.
     scale(1.04) buys 2% of overflow on every edge - comfortably more than
     the ±1.5% the drift actually uses - so the extra is invisible padding,
     never a visible seam, and never eats into content object-position was
     placing deliberately (Erin's side, the photo's own empty margins). */
  @supports (animation-timeline: view()){
    .hero{view-timeline-name:--hero-scroll;view-timeline-axis:block}
    .hero__bg img{
      animation:hero-parallax linear both;
      animation-timeline:--hero-scroll;
      animation-range:cover 0% cover 100%;
    }
    @keyframes hero-parallax{
      from{transform:scale(1.04) translateY(-1.5%)}
      to{transform:scale(1.04) translateY(1.5%)}
    }
  }
}
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.001ms!important;animation-iteration-count:1!important;transition-duration:.001ms!important}
}

/* ═══ GLOBAL · QUICKBAR - always-on call/email/book, minimizable ══════════ */
/* Fixed bottom-right, site-wide (present on every current-system page, added
   directly into each page's markup right before the closing scripts). The
   toggle sits at the bottom of the stack, closest to the corner, acting as
   the handle: tap it to collapse the three actions away, tap again to bring
   them back. State is remembered per-visitor in localStorage - a plain
   convenience, never depended on (defaults to open if storage is
   unavailable or empty). */
.quickbar{
  position:fixed;right:1.25rem;bottom:1.25rem;z-index:150;
  display:flex;flex-direction:column;align-items:center;gap:.65rem;
}
.quickbar__btn{
  display:flex;align-items:center;justify-content:center;flex:none;
  width:3.1rem;height:3.1rem;border-radius:50%;
  background:var(--surface-card);color:var(--accent-ink);
  border:1px solid var(--line);box-shadow:var(--shadow-lg);
  transition:transform .26s var(--ease),box-shadow .26s var(--ease),
             opacity .26s var(--ease),background .22s var(--ease);
}
.quickbar__btn:hover{transform:translateY(-3px);box-shadow:var(--shadow-md);background:var(--accent-soft)}
.quickbar__btn .icon{width:1.35rem;height:1.35rem;stroke-width:1.8}
.quickbar__btn--accent{background:var(--accent);color:var(--on-accent);border-color:transparent}
.quickbar__btn--accent:hover{background:var(--accent-hover)}

.quickbar__toggle{
  display:flex;align-items:center;justify-content:center;flex:none;
  width:2.75rem;height:2.75rem;border-radius:50%;
  background:var(--ink);color:#fff;box-shadow:var(--shadow-md);
  transition:background .22s var(--ease),transform .15s var(--ease);
}
.quickbar__toggle:hover{background:var(--accent-hover)}
.quickbar__toggle:active{transform:scale(.94)}
.quickbar__toggle .icon{width:1.1rem;height:1.1rem;transition:transform .3s var(--ease)}

/* Collapsed: the three actions shrink and fade out from behind the toggle,
   and the toggle's chevron flips to point the other way (open = points
   away from the buttons, i.e. "collapse this way"; collapsed = points
   back toward them, i.e. "expand this way"). */
.quickbar[data-open="false"] .quickbar__btn{
  opacity:0;transform:scale(.5) translateY(14px);
  pointer-events:none;position:absolute;
}
.quickbar[data-open="false"] .quickbar__toggle .icon{transform:rotate(180deg)}

@media (max-width:600px){
  /* Phones start minimized. Until the script has run (data-init), keep the
     three actions folded away too, so they never flash over the page first. */
  .quickbar:not([data-init]) .quickbar__btn{opacity:0;pointer-events:none;position:absolute;transition:none}
  .quickbar{right:1rem;bottom:1rem;gap:.55rem}
  .quickbar__btn{width:2.85rem;height:2.85rem}
  .quickbar__btn .icon{width:1.2rem;height:1.2rem}
  .quickbar__toggle{width:2.5rem;height:2.5rem}
}

/* ═══ SERVICE DETAIL PAGES (osteopathy.html, massage-therapy.html) ════════ */
/* Deliberately built from pieces already established elsewhere rather than
   a one-off page style: the hero reuses .owners (meet-the-owners.html's
   sticky-photo-beside-copy intro), the philosophical quote reuses
   .quote-block, and the pillar/who-serves grids reuse .serve-grid/.serve-
   card (the same icon-circle-plus-copy language as the six dimensions of
   health). Net new below: a 2x2 variant of .serve-grid for four-up content,
   the "what to expect" checklist box, focus-area cards (icon header plus a
   checklist instead of a paragraph), and the closing credential band. */

/* Plain 2x2 four-up grid (meet-the-owners.html's collaboration network,
   and both service pages' "who we serve" client-profile cards) - ordinary
   .serve-card styling, just four instead of three. */
.serve-grid--quad{grid-template-columns:repeat(2,1fr)}
@media (max-width:600px){.serve-grid--quad{grid-template-columns:1fr}}

/* Five uniform cards (osteopathy.html's "Who Can Benefit" grid) - plain
   3-up grid so every card, including the last row's pair, is the same
   size instead of one card stretched full-width. */
.serve-grid--five{grid-template-columns:repeat(3,1fr)}
@media (max-width:900px){.serve-grid--five{grid-template-columns:repeat(2,1fr)}}
@media (max-width:600px){.serve-grid--five{grid-template-columns:1fr}}

/* Four-up "pillars" row (osteopathy.html and massage-therapy.html): four
   equal columns standing side by side under a shared beam, echoing both
   pages' own "Treatment/Technique Architecture" eyebrow rather than just
   being a generic card grid. */
.serve-grid--pillars{
  grid-template-columns:repeat(4,1fr);gap:0;
  border-top:3px solid var(--accent);border-bottom:3px solid var(--accent);
}
.serve-grid--pillars .serve-card{
  border-radius:0;box-shadow:none;background:transparent;
  border-right:1px solid var(--line);
  text-align:center;display:flex;flex-direction:column;align-items:center;
  transition:background .28s var(--ease);
}
.serve-grid--pillars .serve-card:last-child{border-right:none}
.serve-grid--pillars .serve-card:hover{transform:none;background:var(--accent-soft)}
.serve-grid--pillars .serve-card__icon{margin-inline:auto}
@media (max-width:820px){
  .serve-grid--pillars{grid-template-columns:repeat(2,1fr);border-bottom:none}
  .serve-grid--pillars .serve-card{border-bottom:1px solid var(--line)}
  .serve-grid--pillars .serve-card:nth-child(2n){border-right:none}
}
@media (max-width:600px){
  .serve-grid--pillars{grid-template-columns:1fr}
  .serve-grid--pillars .serve-card{border-right:none}
}

/* Full-bleed faded photo backdrop for an otherwise photo-less section
   (osteopathy.html's quote block and "Who We Serve" grid). The photo sits
   behind the section's own content at low opacity, then fades to the
   section's own surface color at the bottom via a gradient scrim, so it
   reads as ambient texture rather than a competing image - text contrast
   never depends on what's actually in the photo. --pb-fade defaults to
   the plain-section surface and is overridden when paired with
   .section--tint so the scrim always matches the section it's inside. */
.section-photobg{--pb-fade:var(--surface);position:relative;isolation:isolate}
.section--tint.section-photobg{--pb-fade:var(--surface-2)}
.section-photobg__media{position:absolute;inset:0;z-index:0;overflow:hidden}
.section-photobg__media img{width:100%;height:100%;object-fit:cover;object-position:center;opacity:.32}
/* Erin's face sits in the upper-left third of this source photo - shift
   the crop up so it isn't lost when the wide section crops the middle. */
.section-photobg__media--serve img{object-position:32% 18%}
.section-photobg__media::after{
  content:"";position:absolute;inset:0;
  background:linear-gradient(to bottom, transparent, var(--pb-fade) 88%);
}
.section-photobg > .shell{position:relative;z-index:1}

/* Section intro run beside a photo (osteopathy's Root-Cause block) - the
   whole heading group (eyebrow/h2/lead/body) sits in one column rather
   than just the body paragraph, so the text block's own height roughly
   matches the photo instead of one short paragraph floating against a
   much taller image (that mismatch, under align-items:center, was reading
   as a big empty gap above the paragraph - hence the merge). Top-aligned
   like .owners, not centered, so both columns start on the same line. */
.split{
  display:grid;grid-template-columns:1fr 1fr;gap:clamp(2rem,4vw,3.5rem);
  align-items:start;margin-top:clamp(2rem,4vw,2.75rem);
}
.split__content h2{font-size:var(--fs-h2);margin-bottom:1rem}
.split__content .lead{margin-bottom:1.25rem}
.split__media{border-radius:var(--r-media);overflow:hidden;box-shadow:var(--shadow-md)}
.split__media img{width:100%;height:100%;object-fit:cover;display:block}
@media (max-width:820px){.split{grid-template-columns:1fr;gap:1.5rem}}

/* "What to expect": a tinted checklist, one register quieter than the
   accent-blue CTA bands elsewhere - this is orientation, not a sales ask. */
.protocol{
  background:var(--accent-soft);border-radius:var(--r-panel);
  padding:clamp(1.75rem,4vw,2.75rem);margin-top:clamp(2rem,4vw,2.75rem);
}
.protocol__title{font-size:var(--fs-h3);margin-bottom:1.5rem;text-align:center}
.protocol__grid{display:grid;grid-template-columns:repeat(2,1fr);gap:1.5rem 2rem}
.protocol__item{display:flex;gap:1rem;align-items:flex-start}
.protocol__check{
  display:flex;align-items:center;justify-content:center;flex:none;
  width:1.75rem;height:1.75rem;border-radius:50%;margin-top:.15rem;
  background:var(--surface-card);color:var(--accent-ink);box-shadow:var(--shadow-sm);
}
.protocol__check .icon{width:1rem;height:1rem;stroke-width:2.6}
.protocol__item strong{display:block;color:var(--ink);margin-bottom:.3rem}
.protocol__item p{color:var(--ink-2);font-size:var(--fs-sm);line-height:1.6}
@media (max-width:700px){.protocol__grid{grid-template-columns:1fr}}

/* Focus-area cards: same card material as .svc/.serve-card, but the body
   is a checklist rather than a paragraph, so it gets its own small-dot
   marker rather than borrowing .focus's checkmark (reserved for "you will
   get this" promises, not a scannable symptom list). The top accent border
   is the one deliberate callback to the old stack's own focus-card style. */
.focus-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:1.5rem}
.focus-card{
  background:var(--surface-card);border-radius:var(--r-media);
  box-shadow:var(--shadow-sm);padding:clamp(1.75rem,3vw,2.25rem);
  border-top:3px solid var(--accent);
}
.focus-card__head{display:flex;align-items:center;gap:.75rem;margin-bottom:1.25rem}
.focus-card__icon{
  display:flex;align-items:center;justify-content:center;flex:none;
  width:2.5rem;height:2.5rem;border-radius:50%;
  background:var(--accent-soft);color:var(--accent-ink);
}
.focus-card__icon .icon{width:1.2rem;height:1.2rem;stroke-width:1.8}
.focus-card h3{font-size:1.05rem}
.focus-list{list-style:none;padding:0;margin:0}
.focus-list li{
  position:relative;padding-left:1.4rem;font-size:var(--fs-sm);
  color:var(--ink-2);line-height:1.8;
}
.focus-list li::before{
  content:"";position:absolute;left:.1rem;top:.72em;
  width:.4rem;height:.4rem;border-radius:50%;background:var(--accent);
}
@media (max-width:900px){.focus-grid{grid-template-columns:1fr}}

/* Closing credential band: a quiet, centered highlight naming the specific
   training behind the page, directly above the closing book-now actions -
   deliberately not the homepage's accent-blue CTA treatment, since this is
   a credibility note, not a sales ask. */
.credential-band{
  background:var(--surface-2);border-radius:var(--r-panel);
  padding:clamp(2.25rem,5vw,3.5rem);text-align:center;
  max-width:52rem;margin-inline:auto;
}
.credential-band__icon{
  display:flex;align-items:center;justify-content:center;margin-inline:auto;
  width:3rem;height:3rem;border-radius:50%;margin-bottom:1.25rem;
  background:var(--accent);color:var(--on-accent);
}
.credential-band__icon .icon{width:1.4rem;height:1.4rem;stroke-width:1.8}
.credential-band h3{font-size:1.3rem;margin-bottom:.75rem}
.credential-band p{color:var(--ink-2);max-width:44rem;margin-inline:auto;line-height:1.65}
.credential-band .btn{margin-top:1.75rem}

/* Compact legal footnote (osteopathy.html only, carried over from the
   previous build) - deliberately understated: a disclaimer, not a callout. */
.compact-note{
  max-width:56rem;margin-inline:auto;text-align:center;
  color:var(--ink-3);font-size:var(--fs-xs);line-height:1.6;
}
.profile-hero__section .aside-note{color:var(--ink-3);font-size:var(--fs-xs);font-style:italic;margin-top:.6rem}

/* Hero jot-note summary: replaces a paragraph of prose with scannable
   checkmark points (physiotherapy.html's old-stack ".physio-work-list"
   has the same job; this is the mdh-stack equivalent) - the same check
   mark already used in .protocol__check, just inline rather than badged. */
.check-list{
  list-style:none;margin:1.5rem 0 0;padding:0;
  display:flex;flex-direction:column;gap:.7rem;max-width:56ch;
}
.check-list li{display:flex;align-items:flex-start;gap:.65rem;color:var(--ink-2);font-size:var(--fs-sm);line-height:1.55}
.check-list .icon{width:1.1rem;height:1.1rem;flex:none;margin-top:.2rem;color:var(--accent-ink);stroke-width:2.4}

/* Tighter rhythm for osteopathy.html / massage-therapy.html: at the
   default VISUAL_DENSITY 3 section-y (clamp(5rem,10vw,9rem)) plus each
   component's own margin stacked on top (.svc-head, .protocol, .owners,
   .credential-band all add their own gap on top of the section's own
   padding), these two content-dense pages read airier than intended -
   closer to physiotherapy.html's denser old-stack rhythm instead. Scoped
   to a body class so the rest of the mdh-stack (home, bios, meet the
   owners) keeps the rhythm it was designed with. */
body.page-tight{--section-y:clamp(3.25rem,6vw,5.5rem)}
body.page-tight .svc-head{margin-bottom:clamp(1.5rem,3vw,2rem)}
body.page-tight .owners{gap:clamp(1.5rem,3.5vw,3rem)}
body.page-tight .split{margin-top:clamp(1.5rem,3vw,2rem);gap:clamp(1.5rem,3.5vw,3rem)}
body.page-tight .quote-block{padding-block:clamp(.25rem,1vw,.75rem)}
body.page-tight .protocol{margin-top:clamp(1.5rem,3vw,2rem);padding:clamp(1.5rem,3vw,2rem)}
body.page-tight .serve-grid{gap:1.25rem}
body.page-tight .focus-grid{gap:1.25rem}
body.page-tight .credential-band{padding:clamp(1.75rem,4vw,2.5rem)}

/* Session stats row: the mdh-stack equivalent of physiotherapy.html's old-
   stack ".physio-stats" (50 min / $185 / fully clothed), placed the same
   way - directly under the "what to expect" checklist, so price sits next
   to the session details it belongs with rather than off on its own. */
.stats-row{
  display:flex;flex-wrap:wrap;gap:2rem clamp(2rem,5vw,3.5rem);justify-content:center;
  margin-top:clamp(1.75rem,3.5vw,2.5rem);padding-top:clamp(1.75rem,3.5vw,2.5rem);
  border-top:1px solid var(--line);
}
.stats-row__item{text-align:center}
.stats-row__item strong{
  display:block;font-size:clamp(1.65rem,2.8vw,2.1rem);font-weight:700;
  color:var(--accent-ink);font-family:"Petrona",Georgia,"Times New Roman",serif;
}
.stats-row__item span{display:block;font-size:var(--fs-sm);color:var(--ink-2);margin-top:.25rem}

/* ═══ SECONDARY PAGES (contact.html, faq.html, resources.html, physio) ════ */
/* Brings the last old-stack pages onto the same system as everything else.
   Net new below is deliberately small: a plain centered intro band for
   pages with no hero photo, a generic surface-card panel, contact detail
   rows, a listener-light FAQ accordion (CSS grid-rows animation, same
   "no scroll listeners" rule as the rest of the site), a numbered step
   card for physiotherapy's five-stage session, and a plain (icon-less)
   variant of the existing focus-card for its six treatment methods.
   Everything else on these pages - .owners, .serve-grid, .focus-grid,
   .credential-band, .stats-row, .cta, .compact-note - is reused as-is. */

/* Plain intro band: eyebrow + h1 + lead, no photo. Used where a page opens
   directly with content (contact, FAQ, resources, articles) rather than a
   sticky-photo hero like the practitioner/service pages. */
.page-head{max-width:44rem;margin-inline:auto;text-align:center}
.page-head h1{font-size:var(--fs-h2);margin-bottom:1rem}
.page-head .lead{margin-inline:auto}
.page-head__byline{font-size:var(--fs-sm);font-weight:600;color:var(--ink-3);margin-top:.9rem}

/* Full-bleed photo variant of the plain .page-head band above (faq.html,
   contact.html) - a real Vancouver Island coastal photo standing in for
   the sticky-photo hero those pages otherwise don't have, with a dark
   scrim so the (now white) .page-head text stays legible over open sky
   and water rather than needing to dodge the horizon line. */
.page-hero-photo{
  position:relative;isolation:isolate;overflow:hidden;
  display:flex;align-items:center;justify-content:center;
  padding-block:clamp(2.25rem,4.5vw,3rem);
}
.page-hero-photo__media{position:absolute;inset:0;z-index:0}
.page-hero-photo__media img{width:100%;height:100%;object-fit:cover;object-position:center 65%}
.page-hero-photo::after{
  content:"";position:absolute;inset:0;z-index:1;pointer-events:none;
  background:linear-gradient(180deg, rgb(3 78 161 / .32), rgb(3 78 161 / .56));
}
.page-hero-photo > .shell{position:relative;z-index:2}
.page-hero-photo .page-head{color:#fff}
.page-hero-photo .page-head .eyebrow{color:#fff;opacity:.85}
.page-hero-photo .page-head .lead{color:rgb(255 255 255 / .9)}

/* Generic elevated panel: the one new "container" this batch of pages
   needed that nothing upstream already covered (.credential-band is
   always centered with an icon; this is plain and left-aligned, for the
   contact page's message-us fallback and the resources hub's placeholder). */
.panel-card{
  background:var(--surface-card);border-radius:var(--r-panel);
  padding:clamp(2rem,4vw,2.75rem);box-shadow:var(--shadow-sm);
}
.panel-card--center{text-align:center;max-width:40rem;margin-inline:auto}
.panel-card .eyebrow{margin-bottom:.9rem}
.panel-card h2{font-size:var(--fs-h3);margin-bottom:.85rem}
.panel-card p{color:var(--ink-2);line-height:1.65}
.panel-card .btn-row{display:flex;flex-wrap:wrap;gap:.8rem;margin-top:1.5rem}

/* Contact form (contact.html) - plain stacked fields matching the rest of
   the site's surface/line/radius tokens, posted to Netlify Forms in the
   background (see mdh.js). After a send, the whole card is replaced by a
   confirmation of the message. */
.contact-form{margin-top:1.5rem;display:flex;flex-direction:column;gap:1.1rem}
.contact-form__row{display:flex;flex-direction:column;gap:.4rem}
.contact-form__row label{font-size:var(--fs-sm);font-weight:700;color:var(--ink)}
.contact-form__row label span{font-weight:400;color:var(--ink-3)}
.contact-form__row input,
.contact-form__row textarea{
  font:inherit;font-size:var(--fs-sm);color:var(--ink);
  background:var(--surface);border:1px solid var(--line);border-radius:var(--r-input,.6rem);
  padding:.7rem .9rem;resize:vertical;
  transition:border-color .2s var(--ease);
}
.contact-form__row input:focus,
.contact-form__row textarea:focus{border-color:var(--accent);outline:2px solid var(--accent-soft);outline-offset:1px}
.contact-form button{align-self:flex-start;margin-top:.3rem}
.panel-card--center .btn-row{justify-content:center}

/* Contact details: icon-badge rows, same round-icon language as
   .serve-card__icon / .info used across the rest of the system. */
.info-rows{display:flex;flex-direction:column;gap:1.4rem}
.info-row{display:flex;gap:1rem;align-items:flex-start}
.info-row__icon{
  display:flex;align-items:center;justify-content:center;flex:none;
  width:2.75rem;height:2.75rem;border-radius:50%;
  background:var(--accent-soft);color:var(--accent-ink);
}
.info-row__icon .icon{width:1.2rem;height:1.2rem;stroke-width:1.8}
.info-row strong{display:block;font-size:var(--fs-sm);font-weight:700;color:var(--ink);margin-bottom:.15rem}
.info-row a,.info-row p span{display:block;color:var(--ink-2);font-size:var(--fs-sm)}
.info-row a:hover{color:var(--accent-ink)}
.info-row small{display:block;color:var(--ink-3);font-size:var(--fs-xs);margin-top:.25rem;line-height:1.5}

.btn-stack{display:flex;flex-direction:column;align-items:flex-start;gap:.85rem}

/* Practitioner pills (contact.html's "Choose your practitioner") - a
   face plus a first name, one per practitioner, light-surface counterpart
   to .cta__bio (that one only works on the solid-blue CTA background).
   Each links straight to that practitioner's own booking flow, same URLs
   already used on their own bio pages - Erin and James share the
   clinic's plain booking link, Kayla has her own distinct staff link. */
.practitioner-pills{display:flex;flex-wrap:wrap;gap:.85rem;margin-top:.25rem}
.practitioner-pill{
  display:inline-flex;align-items:center;gap:.7rem;
  padding:.5rem 1.4rem .5rem .5rem;border-radius:var(--r-pill);
  background:var(--surface-card);border:1.5px solid var(--line-strong);
  color:var(--ink);font-weight:600;font-size:var(--fs-sm);
  transition:background .25s var(--ease),border-color .25s var(--ease),
             transform .2s var(--ease),box-shadow .25s var(--ease);
}
.practitioner-pill:hover{
  border-color:var(--accent);background:var(--accent-soft);color:var(--accent-ink);
  transform:translateY(-2px);box-shadow:var(--shadow-sm);
}
.practitioner-pill img{width:2.5rem;height:2.5rem;border-radius:50%;object-fit:cover;flex:none}

.contact-layout{display:grid;grid-template-columns:1fr 1fr;gap:clamp(2rem,5vw,4rem);align-items:start}
.contact-layout__booking{margin-top:clamp(2rem,4vw,2.75rem)}
.contact-layout__booking .eyebrow{margin-bottom:.6rem}
.contact-layout__booking h2{font-size:var(--fs-h3);margin-bottom:1.25rem}

@media (max-width:820px){
  .contact-layout{grid-template-columns:1fr;gap:2.5rem}
}

/* FAQ accordion: a CSS grid-rows expand/collapse (0fr -> 1fr), the same
   "animate without measuring scrollHeight, no scroll or resize listener"
   approach used everywhere else on the site. JS only flips one data
   attribute per item; the transition itself is pure CSS. */
/* Four sections side by side (2 x 2), so every section's questions are on
   screen together instead of one long column. align-items:start keeps an
   opened answer from stretching its neighbour. */
.contact-form__note{margin-top:1rem;font-size:var(--fs-xs);line-height:1.6;color:var(--ink-3);max-width:44ch}
.contact-form__status{margin-top:1rem;padding:.9rem 1.1rem;border-radius:var(--r-input);font-size:var(--fs-sm);line-height:1.6;background:var(--accent-soft);color:var(--accent-ink)}
.contact-form__status[data-state="error"]{background:#fdf0ee;color:#8a2a1c}
.contact-form__status[hidden]{display:none}

/* Confirmation shown in place of the whole contact card after a message is sent. */
.panel-card.is-sent > :not(.contact-form__done){display:none}
.contact-form__done{display:flex;flex-direction:column;align-items:flex-start;gap:1rem}
.contact-form__done:focus{outline:none}
.contact-form__done-icon{display:grid;place-items:center;width:3rem;height:3rem;border-radius:50%;background:var(--accent-soft);color:var(--accent-ink)}
.contact-form__done-icon svg{width:1.5rem;height:1.5rem;fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
.panel-card .contact-form__done h2{margin:0}
.contact-form__sent{width:100%;padding:1.1rem 1.25rem;border-radius:var(--r-input);background:var(--surface);border:1px solid var(--line)}
.contact-form__sent-label{display:block;font-size:var(--fs-xs);font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--ink-3);margin-bottom:.5rem}
.panel-card .contact-form__sent p{margin:0;color:var(--ink)}
.panel-card .contact-form__sent .contact-form__sent-who{font-size:var(--fs-sm);font-weight:700;margin-bottom:.5rem;overflow-wrap:anywhere}
.panel-card .contact-form__sent .contact-form__sent-text{white-space:pre-wrap;overflow-wrap:anywhere}
@media (prefers-reduced-motion:no-preference){
  .contact-form__done{animation:contact-done-in .5s var(--ease) both}
  @keyframes contact-done-in{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:none}}
}

.faq-groups{
  display:grid;grid-template-columns:repeat(2,minmax(0,1fr));
  gap:clamp(2.25rem,4vw,3rem) clamp(1.5rem,3vw,2.5rem);align-items:start;
}
.faq-group__head{
  display:flex;align-items:center;gap:.9rem;
  margin-bottom:1.1rem;padding-bottom:1rem;border-bottom:1.5px solid var(--line-strong);
}
.faq-group__icon{
  width:2.75rem;height:2.75rem;flex:none;border-radius:50%;
  display:grid;place-items:center;background:var(--accent-soft);color:var(--accent-ink);
}
.faq-group__icon .icon{width:1.3rem;height:1.3rem}
.faq-group h2{font-size:var(--fs-h3);line-height:1.15;margin:0}
.faq-group__count{
  display:block;margin-top:.25rem;font-size:var(--fs-xs);font-weight:600;
  letter-spacing:.06em;text-transform:uppercase;color:var(--ink-3);
}
@media (max-width:900px){.faq-groups{grid-template-columns:1fr}}
.faq-list{display:flex;flex-direction:column;gap:.75rem}
.faq-item{background:var(--surface-card);border-radius:var(--r-input);box-shadow:var(--shadow-sm)}
.faq-item__q{
  width:100%;display:flex;align-items:center;justify-content:space-between;gap:1rem;
  padding:1.15rem 1.4rem;text-align:left;font-weight:600;font-size:var(--fs-sm);color:var(--ink);
}
.faq-item__q .icon{width:1.1rem;height:1.1rem;flex:none;color:var(--ink-3);transition:transform .25s var(--ease)}
.faq-item__q[aria-expanded="true"] .icon{transform:rotate(180deg)}
.faq-item__a{display:grid;grid-template-rows:minmax(0,0fr);transition:grid-template-rows .3s var(--ease)}
.faq-item__a[data-open="false"]{overflow:hidden;visibility:hidden;transition:grid-template-rows .3s var(--ease),visibility 0s linear .3s}
.faq-item__a[data-open="true"]{grid-template-rows:minmax(0,1fr);visibility:visible}
.faq-item__a > div{overflow:hidden}
.faq-item__a p{padding:0 1.4rem 1.25rem;color:var(--ink-2);font-size:var(--fs-sm);line-height:1.7}

/* Physiotherapy's six treatment methods: the same card material as
   .focus-card, minus its icon header - these are plain named methods,
   not a symptom checklist, so a bare h3 + p reads better than a list. */
.method-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:1.5rem}
.method-card{
  background:var(--surface-card);border-radius:var(--r-media);
  box-shadow:var(--shadow-sm);padding:clamp(1.75rem,3vw,2.25rem);
  border-top:3px solid var(--accent);
}
.method-card h3{font-size:1.05rem;margin-bottom:.5rem}
.method-card p{color:var(--ink-2);font-size:var(--fs-sm);line-height:1.6}
@media (max-width:900px){.method-grid{grid-template-columns:1fr 1fr}}
@media (max-width:600px){.method-grid{grid-template-columns:1fr}}

/* Physiotherapy's five-step session walkthrough: a numbered variant of
   .serve-card (same panel, same icon-circle slot, a bold number instead
   of a Tabler icon). Kept on the page's default surface/tint alternation
   rather than the old stack's inverted navy band - "no section inverts
   against its page theme" is an audited lock, not a style preference. */
.step-grid{display:grid;grid-template-columns:repeat(5,1fr);gap:1.25rem}
.step-card{
  background:var(--surface-card);border-radius:var(--r-media);
  box-shadow:var(--shadow-sm);padding:clamp(1.5rem,3vw,1.85rem) clamp(1.25rem,2.5vw,1.5rem);
}
.step-card__num{
  display:flex;align-items:center;justify-content:center;
  width:2.5rem;height:2.5rem;border-radius:50%;margin-bottom:1rem;
  background:var(--accent-soft);color:var(--accent-ink);
  font-family:"Petrona",Georgia,"Times New Roman",serif;font-weight:700;font-size:.95rem;
}
.step-card h3{font-size:1.05rem;margin-bottom:.4rem}
.step-card p{color:var(--ink-2);font-size:var(--fs-sm);line-height:1.6}
@media (max-width:960px){.step-grid{grid-template-columns:repeat(3,1fr)}}
@media (max-width:600px){.step-grid{grid-template-columns:1fr 1fr}}

/* Article template (resources-article-template.html and any post built
   from it): a full-width cover photo plus a measured copy column. */
.article-cover{border-radius:var(--r-media);overflow:hidden;box-shadow:var(--shadow-sm);margin-bottom:clamp(2rem,4vw,3rem)}
.article-cover img{width:100%;height:auto;display:block}
.article-copy{max-width:68ch;margin-inline:auto;display:flex;flex-direction:column;gap:1.15rem}
.article-copy p{color:var(--ink-2);line-height:1.75}
.article-copy + .profile-back{margin-top:2rem;margin-bottom:0}

/* ═══ HOMEPAGE SECTION HEADS - centered (client request) ══════════════════
   Scoped to index.html's own sections only. #services and #locations are
   scoped by ID rather than centering .svc-head globally, since osteopathy.
   html and massage-therapy.html reuse .svc-head for their own (left-
   aligned) section heads and shouldn't be affected. .team-head,
   .reviews__head, and .dims__connects are unique to the homepage already,
   so those are centered directly. The hero and each card's own internal
   heading (service names, team names, location names) are left as designed
   - this only touches each section's own title-plus-intro block. */
#services .svc-head,
#locations .svc-head,
.team-head{
  text-align:center;margin-inline:auto;
}
.dims__connects h3{
  text-align:center;
}
