/* CLINIC — plain, high-trust, no personality to get in the way
   ------------------------------------------------------------------
   Use it when: the client is a multi-practitioner clinic with no design
   opinion and the job is to look competent and load fast. Deliberately dull.
   Nobody books a physio because the website had a point of view.

   System font stack, so there is no webfont request at all and the first
   paint is immediate.
*/

:root {
  --ink: #12181f;
  --ink-2: #222b35;
  --paper: #ffffff;
  --paper-2: #f5f7f9;
  --paper-3: #e9edf1;
  --rule: #dde3ea;
  --rule-2: #c7d0da;
  --rule-dark: #26313d;
  --muted: #56606c;
  --muted-dark: #9aa5b1;
  --on-dark: #ffffff;
  --on-dark-2: rgba(255, 255, 255, .86);
  --on-dark-3: rgba(255, 255, 255, .58);

  /* 5.47:1 on white, measured. Teal reads clinical without reading corporate. */
  --accent: #0f766e;
  --accent-text: #0f766e;
  --accent-deep: #0a5551;
  --accent-wash: #edf7f5;
  --accent-light: #5eddd0;

  --accent-glow: rgba(15, 118, 110, .26);
  --accent-glow-strong: rgba(15, 118, 110, .34);

  --star: #f0b429;
  --flag: #e0a02a;
  --warn: #c2761b; --warn-wash: #fdf6ec; --warn-rule: #f0e2cb; --warn-ink: #7a4c10;
  --err: #99201d; --err-wash: #fdecec;

  --display: -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
  --body: -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
  --ui: -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;

  --wrap: 1140px;
  --gut: clamp(18px, 4.5vw, 48px);
  --r: 10px;
  --shadow: 0 1px 2px rgba(18, 24, 31, .05), 0 6px 20px rgba(18, 24, 31, .06);
  --shadow-lg: 0 2px 4px rgba(18, 24, 31, .06), 0 20px 48px rgba(18, 24, 31, .1);
  --bar: 76px;
}

h1, h2, h3 { font-weight: 700; letter-spacing: -.02em; line-height: 1.12; }
h1 { font-size: clamp(2rem, 4.6vw, 2.9rem); }
h2 { font-size: clamp(1.6rem, 3.2vw, 2.1rem); }

.btn { border-radius: 8px; }
body { font-size: 17px; }

/* KIT BASE
   ------------------------------------------------------------------
   Structure only. Every colour, font, radius and shadow comes from a CSS
   variable that a THEME sets. Do not put a brand value in this file.

   The class names here are the contract with lib/blocks.mjs. A theme restyles
   `.hero`, `.card`, `.rating`; it never renames them. That is what lets the
   same content run through a different theme.

   Variables a theme must define:
     --ink --ink-2 --paper --paper-2 --paper-3 --rule --rule-dark --muted
     --muted-dark --accent --accent-text --accent-deep --accent-wash
     --display --body --ui  --wrap --gut --r --shadow --shadow-lg --bar

   --accent-text is the accent at a ratio that clears 4.5:1 on --paper. On
   both client sites so far the brand colour failed AA at body size and was
   the colour of every link. Run scripts/contrast.mjs; it is arithmetic.
*/


/* ------------------------------------------------------------------ reset */

*, *::before, *::after { box-sizing: border-box; }
html {
  -webkit-text-size-adjust: 100%; scroll-behavior: smooth;
  /* Without this every in-page anchor lands with its heading hidden behind the
     sticky header. Header is 60-68px; 96px clears it with air to spare. */
  scroll-padding-top: 96px;
}
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  margin: 0;
  font-family: var(--body);
  font-size: 18px;
  line-height: 1.65;
  color: var(--ink);
  background: var(--paper);
  overflow-x: hidden;
  /* No padding-bottom here. On the last rebuild a body-level pad painted a
     white band under a dark footer on every phone. The sticky bar gets its
     space from a spacer element instead. */
}

/* Without height:auto the HTML height attribute wins and images render at
   intrinsic height inside a narrow column. Invisible on desktop, grotesque
   on a phone. */
img, video, svg { max-width: 100%; height: auto; display: block; }

a { color: var(--accent-text); text-decoration-thickness: 1px; text-underline-offset: 3px; }
a:hover { color: var(--accent-deep); }

h1, h2, h3, h4 { font-family: var(--display); font-weight: 400; line-height: 1.06; margin: 0 0 .5em; letter-spacing: -.015em; }
h1 { font-size: clamp(2.4rem, 6.5vw, 4.6rem); }
h2 { font-size: clamp(1.9rem, 4.2vw, 3rem); }
h3 { font-size: clamp(1.35rem, 2.6vw, 1.85rem); }
h4 { font-size: clamp(1.1rem, 2vw, 1.3rem); font-family: var(--ui); font-weight: 650; letter-spacing: -.01em; }
p { margin: 0 0 1.1em; }
ul, ol { margin: 0 0 1.1em; padding-left: 1.2em; }
li { margin-bottom: .45em; }

:focus-visible { outline: 3px solid var(--accent-text); outline-offset: 3px; border-radius: 4px; }

.wrap { max-width: var(--wrap); margin-inline: auto; padding-inline: var(--gut); }
/* .narrow is a MODIFIER on .wrap, but it kept getting used on its own, which
   silently dropped margin-inline:auto and the gutter and jammed a whole
   section against the left edge. It now stands on its own feet as well. */
.narrow { max-width: 780px; margin-inline: auto; padding-inline: var(--gut); }
.wrap.narrow { padding-inline: var(--gut); }
.eyebrow {
  font-family: var(--ui); font-size: .74rem; font-weight: 700; letter-spacing: .14em;
  text-transform: uppercase; color: var(--accent-text); margin: 0 0 1rem;
}
.eyebrow--on-dark { color: var(--accent-light); }
/* An eyebrow inside a dark band inherited the light-ground accent and failed
   AA on all three themes. Dark contexts correct it without needing the flag. */
.sec--dark .eyebrow, .bleed .eyebrow, .hero .eyebrow { color: var(--accent-light); }
.lede { font-size: clamp(1.1rem, 2vw, 1.32rem); line-height: 1.55; color: var(--muted); }
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.skip {
  position: absolute; left: -9999px; top: 0; z-index: 200; background: var(--ink); color: var(--on-dark);
  padding: 12px 20px; font-family: var(--ui);
}
.skip:focus { left: 12px; top: 12px; }

/* ----------------------------------------------------------------- header */

.topbar {
  background: var(--ink); color: var(--on-dark); font-family: var(--ui); font-size: .82rem;
  border-bottom: 1px solid var(--rule-dark);
}
.topbar__in { display: flex; align-items: center; justify-content: space-between; gap: 16px; min-height: 40px; padding-block: 6px; }
.topbar a { color: var(--on-dark); text-decoration: none; display: inline-flex; align-items: center; gap: 7px; }
.topbar a:hover { color: var(--accent-light); }
.topbar__loc { color: var(--muted-dark); display: inline-flex; align-items: center; gap: 7px; }
.topbar__right { display: flex; align-items: center; gap: 18px; }

.hdr {
  position: sticky; top: 0; z-index: 90; background: rgba(255, 255, 255, .93);
  backdrop-filter: saturate(150%) blur(14px);
  border-bottom: 1px solid var(--rule); transition: box-shadow .25s ease;
}
.hdr.is-stuck { box-shadow: 0 1px 20px rgba(0, 0, 0, .09); }
.hdr__in { display: flex; align-items: center; gap: 20px; min-height: 68px; }

.brand { font-family: var(--display); font-size: 1.5rem; letter-spacing: -.02em; text-decoration: none; color: var(--ink); white-space: nowrap; }
.brand:hover { color: var(--ink); }
.brand b { font-weight: 400; color: var(--accent-text); }

.nav { margin-left: auto; display: flex; align-items: center; gap: 4px; font-family: var(--ui); }
.nav a {
  font-size: .875rem; font-weight: 500; color: var(--ink-2); text-decoration: none;
  padding: 9px 11px; border-radius: 8px; white-space: nowrap;
}
.nav a:hover { background: var(--paper-2); color: var(--ink); }
.nav a[aria-current="page"] { color: var(--accent-text); font-weight: 650; }

/* Target the class, never the position. On the last rebuild this button was
   styled with li:last-child, a socials item was added after it, and the
   button silently lost every rule. */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  font-family: var(--ui); font-size: .9rem; font-weight: 650; line-height: 1;
  padding: 13px 22px; border-radius: 999px; border: 1.5px solid transparent;
  text-decoration: none; cursor: pointer; transition: transform .16s ease, background .16s ease, box-shadow .16s ease;
}
.btn:hover { transform: translateY(-1px); }
.btn--primary { background: var(--accent-text); color: var(--on-dark); box-shadow: 0 4px 14px var(--accent-glow); }
.btn--primary:hover { background: var(--accent-deep); color: var(--on-dark); box-shadow: 0 6px 24px var(--accent-glow-strong); }
.btn--ghost { background: transparent; color: var(--ink); border-color: var(--rule); }
.btn--ghost:hover { background: var(--paper-2); color: var(--ink); border-color: var(--rule-2); }
.btn--light { background: var(--on-dark); color: var(--ink); }
.btn--light:hover { background: var(--paper-3); color: var(--ink); }
.btn--outline-light { background: transparent; color: var(--on-dark); border-color: rgba(255, 255, 255, .45); }
.btn--outline-light:hover { background: rgba(255, 255, 255, .1); color: var(--on-dark); }
.btn--lg { padding: 16px 30px; font-size: 1rem; }
.btn--block { width: 100%; }

.nav .btn { color: var(--on-dark); }
.nav .btn--primary { padding: 11px 20px; }
.nav .btn:hover { color: var(--on-dark); }

.burger {
  margin-left: auto; display: none; width: 44px; height: 44px; border: 1px solid var(--rule);
  background: var(--on-dark); border-radius: 10px; cursor: pointer; align-items: center; justify-content: center;
  padding: 0; flex: 0 0 auto;
}
.burger span { display: block; width: 18px; height: 2px; background: var(--ink); position: relative; transition: .2s; }
.burger span::before, .burger span::after { content: ""; position: absolute; left: 0; width: 18px; height: 2px; background: var(--ink); transition: .2s; }
.burger span::before { top: -6px; } .burger span::after { top: 6px; }
.burger[aria-expanded="true"] span { background: transparent; }
.burger[aria-expanded="true"] span::before { top: 0; transform: rotate(45deg); }
.burger[aria-expanded="true"] span::after { top: 0; transform: rotate(-45deg); }

/* ------------------------------------------------------------- mobile nav */

.mnav {
  display: none; position: fixed; inset: 0; z-index: 95; background: var(--ink); color: var(--on-dark);
  padding: 84px var(--gut) 40px; overflow-y: auto; overscroll-behavior: contain;
}
.mnav.is-open { display: block; }
.mnav__close { position: absolute; top: 18px; right: var(--gut); width: 44px; height: 44px; background: transparent; border: 1px solid rgba(255,255,255,.25); border-radius: 10px; color: var(--on-dark); font-size: 1.4rem; cursor: pointer; }
.mnav__links { list-style: none; margin: 0 0 28px; padding: 0; }
.mnav__links li { margin: 0; border-bottom: 1px solid rgba(255, 255, 255, .12); }
/* display:block, so the underline can never strike through wrapped text */
.mnav__links a {
  display: block; padding: 15px 0; color: var(--on-dark); text-decoration: none;
  font-family: var(--display); font-size: 1.6rem; line-height: 1.2;
}
.mnav__links a:hover { color: var(--accent-light); }
.mnav__actions { display: grid; gap: 10px; margin-bottom: 26px; }
.mnav__actions .btn { width: 100%; }
.mnav__meta { font-family: var(--ui); font-size: .9rem; color: var(--muted-dark); }
.mnav__meta a { color: var(--on-dark); text-decoration: none; display: block; padding: 6px 0; }
/* The rating chip is an <a> inside .mnav__meta, so the block rule above beat
   it and collapsed the gap, printing "4.9128 Google reviews". */
.mnav__meta a.rating { display: inline-flex; align-items: center; gap: 7px; }
.mnav__socials { display: flex; gap: 12px; margin-top: 16px; }
.mnav__socials a { display: inline-flex; width: 42px; height: 42px; align-items: center; justify-content: center; border: 1px solid rgba(255,255,255,.25); border-radius: 10px; padding: 0; }

/* ------------------------------------------------------- rating and reviews */

/* 4.9 from 42 is the best thing this business owns and it was on no page of
   the old site. It goes where people arrive: top bar, mobile menu, hero. */
.rating { display: inline-flex; align-items: center; gap: 7px; text-decoration: none; white-space: nowrap; }
.rating__stars { display: inline-flex; gap: 1px; color: var(--star); line-height: 0; }
.rating b { font-weight: 700; }
.rating span:not(.rating__stars) { color: inherit; opacity: .78; }

.rating--bar { color: var(--on-dark); }
.rating--bar:hover { color: var(--on-dark); }
.rating--bar:hover span:not(.rating__stars) { opacity: 1; }

.rating--menu { color: var(--on-dark); padding: 10px 0 4px; }
.rating--menu:hover { color: var(--on-dark); }

.rating--block {
  color: var(--ink); background: var(--on-dark); border: 1px solid var(--rule);
  border-radius: 999px; padding: 10px 18px; font-family: var(--ui); font-size: .88rem;
  margin-bottom: 20px;
}
.rating--block:hover { color: var(--ink); border-color: var(--rule-2); }

.hero__rating { display: inline-flex; align-items: center; gap: 6px; }
.hero__rating svg { color: var(--star); }

.review {
  margin: 0; background: var(--on-dark); border: 1px solid var(--rule); border-radius: var(--r);
  padding: 26px; display: flex; flex-direction: column; gap: 12px;
}
.review__stars { display: flex; gap: 2px; color: var(--star); line-height: 0; }
.review blockquote { margin: 0; font-size: 1.02rem; line-height: 1.55; flex: 1; }
.review figcaption { font-family: var(--ui); font-size: .84rem; font-weight: 650; }
.review figcaption span { font-weight: 400; color: var(--muted); }

/* ----------------------------------------------------------------- hours */

.hours { font-family: var(--ui); font-size: .93rem; margin: 20px 0 26px; max-width: 340px; }
.hours__row { display: flex; justify-content: space-between; gap: 20px; padding: 9px 0; border-bottom: 1px solid var(--rule); }
.hours__row:last-child { border-bottom: 0; }
.hours__row b { font-weight: 650; }
.hours__row--off { color: var(--muted); }

/* --------------------------------------------------------------- sections */

.sec { padding-block: clamp(56px, 9vw, 104px); }
.sec--tight { padding-block: clamp(40px, 6vw, 68px); }
.sec--wash { background: var(--paper-2); }
.sec--accent { background: var(--accent-wash); }
.sec--dark { background: var(--ink); color: var(--on-dark); }
.sec--dark h1, .sec--dark h2, .sec--dark h3, .sec--dark h4 { color: var(--on-dark); }
.sec--dark .lede { color: var(--on-dark-2); }
.sec--dark a { color: var(--accent-light); }
/* .sec--dark a is (0,1,1) and beat .btn--primary at (0,1,0), so a primary
   button inside a dark band lost its label colour. Buttons opt out by name. */
.sec--dark a.btn--primary, .bleed a.btn--primary, .hero a.btn--primary { color: var(--on-dark); }
.sec--dark a.btn--light, .bleed a.btn--light, .hero a.btn--light { color: var(--ink); }
.sec--dark a.btn--outline-light, .bleed a.btn--outline-light, .hero a.btn--outline-light { color: var(--on-dark); }

.sec__head { max-width: 760px; margin-bottom: clamp(30px, 4vw, 52px); }
.rule { height: 1px; background: var(--rule); border: 0; margin: 0; }

/* ------------------------------------------------------------------- hero */

.hero { position: relative; background: var(--ink); color: var(--on-dark); overflow: hidden; }
.hero__media { position: absolute; inset: 0; }
.hero__media img { width: 100%; height: 100%; min-height: 100%; object-fit: cover; opacity: .5; }
.hero::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(180deg, rgba(0,0,0,.55) 0%, rgba(0,0,0,.35) 45%, rgba(0,0,0,.85) 100%);
}
.hero__in { position: relative; z-index: 2; padding-block: clamp(84px, 15vw, 168px); max-width: 760px; }
.hero h1 { color: var(--on-dark); }
.hero .lede { color: var(--on-dark-2); max-width: 56ch; }
.hero__cta { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 30px; }
.hero__trust {
  margin-top: 34px; padding-top: 22px; border-top: 1px solid rgba(255,255,255,.16);
  font-family: var(--ui); font-size: .82rem; color: var(--on-dark-3); display: flex; flex-wrap: wrap; gap: 8px 22px;
}
.hero__trust b { color: var(--on-dark); font-weight: 600; }
/* The global reset makes every svg display:block, so five inline stars stacked
   into a vertical column. Any span that mixes icons and text needs to say so. */
.hero__trust span { display: inline-flex; align-items: center; gap: 6px; }
.hero__trust svg { display: inline-block; flex: 0 0 auto; }
/* The 6px gap applied between the five individual stars, spreading the hero
   rating to 89px against 69px for the same stars in the top bar. */
.hero__trust .stars { display: inline-flex; gap: 1px; }

/* ------------------------------------------------------------------ cards */

.grid { display: grid; gap: clamp(16px, 2.4vw, 26px); }
.grid--3 { grid-template-columns: repeat(auto-fit, minmax(272px, 1fr)); }
.grid--2 { grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); }
.grid--4 { grid-template-columns: repeat(auto-fit, minmax(215px, 1fr)); }

.card {
  background: var(--on-dark); border: 1px solid var(--rule); border-radius: var(--r); overflow: hidden;
  display: flex; flex-direction: column; transition: transform .2s ease, box-shadow .2s ease, border-color .2s ease;
}
.card:hover { transform: translateY(-3px); box-shadow: var(--shadow); border-color: var(--rule-2); }
/* aspect-ratio goes on the IMG, not the wrapper.
   On the wrapper it loses: the child's height:100% resolves against a parent
   whose height is auto, so the image's intrinsic height wins and stretches the
   box. Measured on the live site: three cards whose wrappers all reported
   aspect-ratio 4/3 rendered 449px, 252px and 599px tall, exactly matching each
   photo's own ratio. Only the one photo that happened to BE 4:3 looked right.
   It is also invisible until the images finish loading, which is how it passed
   a check against unloaded images. */
.card__img { overflow: hidden; background: var(--paper-3); }
.card__img img { width: 100%; aspect-ratio: 4 / 3; height: auto; object-fit: cover; }
.card__body { padding: 24px; flex: 1; display: flex; flex-direction: column; }
.card__body h3, .card__body h4 { margin-bottom: .5rem; }
.card__body p { color: var(--muted); font-size: .98rem; margin-bottom: 1rem; }
.card__more { margin-top: auto; font-family: var(--ui); font-size: .86rem; font-weight: 650; text-decoration: none; }

/* -------------------------------------------------------------- split row */

.split { display: grid; gap: clamp(28px, 5vw, 64px); align-items: center; grid-template-columns: 1fr 1fr; }
.split--narrow-media { grid-template-columns: 1.15fr .85fr; }
.split__media img { border-radius: var(--r); width: 100%; }
.split__media--tall img { aspect-ratio: 4 / 5; height: auto; object-fit: cover; }

/* ------------------------------------------------------------- quote/wall */

.quote { border-left: 3px solid var(--accent); padding-left: clamp(20px, 3vw, 34px); }
.quote p { font-family: var(--display); font-size: clamp(1.4rem, 3vw, 2.15rem); line-height: 1.24; margin-bottom: .7rem; }
.quote cite { font-family: var(--ui); font-size: .88rem; font-style: normal; color: var(--muted); }
.sec--dark .quote cite { color: var(--muted-dark); }

.namewall { display: flex; flex-wrap: wrap; gap: 10px 12px; list-style: none; margin: 0; padding: 0; }
.namewall li {
  font-family: var(--ui); font-size: .84rem; padding: 9px 15px; border-radius: 999px;
  border: 1px solid rgba(255, 255, 255, .2); margin: 0;
}
.namewall b { font-weight: 650; }
.namewall span { color: var(--muted-dark); }

/* --------------------------------------------------------------- features */

.ticks { list-style: none; padding: 0; margin: 0; display: grid; gap: 11px; }
.ticks li { position: relative; padding-left: 30px; margin: 0; }
.ticks li::before {
  content: ""; position: absolute; left: 0; top: .52em; width: 16px; height: 9px;
  border-left: 2.5px solid var(--accent-text); border-bottom: 2.5px solid var(--accent-text);
  transform: rotate(-45deg);
}
.sec--dark .ticks li::before { border-color: var(--accent-light); }
.ticks--2 { grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); }

.steps { counter-reset: s; display: grid; gap: 14px; }
.step { display: grid; grid-template-columns: 52px minmax(0, 1fr); gap: 18px; align-items: start; padding: 22px; background: var(--paper); border: 1px solid var(--rule); border-radius: var(--r); }
/* --accent is a FILL. White on it measures 2.60:1 on signal and 3.50:1 on
   editorial, so the step numbers were barely readable. --accent-deep is the
   value that carries white text. */
.step__n {
  width: 52px; height: 52px; border-radius: 50%; background: var(--accent-deep); color: var(--on-dark);
  display: grid; place-items: center; font-family: var(--ui); font-weight: 700; font-size: 1.1rem;
}
.step h4 { margin-bottom: .25rem; }
.step p { margin: 0; color: var(--muted); font-size: .97rem; }

/* -------------------------------------------------------------- value box */

.value { border: 1px solid var(--rule); border-radius: var(--r); overflow: hidden; background: var(--on-dark); }
.value__row { display: flex; justify-content: space-between; gap: 20px; padding: 16px 22px; border-bottom: 1px solid var(--rule); }
.value__row span { flex: 1; min-width: 0; overflow-wrap: anywhere; }
.value__row b { font-family: var(--ui); font-size: .92rem; white-space: nowrap; color: var(--muted); }
.value__total { display: flex; justify-content: space-between; gap: 20px; padding: 18px 22px; background: var(--paper-2); font-family: var(--ui); font-weight: 650; }
.value__price { padding: 26px 22px; background: var(--ink); color: var(--on-dark); text-align: center; }
.value__price .n { font-family: var(--display); font-size: clamp(2.4rem, 6vw, 3.4rem); line-height: 1; display: block; }
.value__price .l { font-family: var(--ui); font-size: .8rem; letter-spacing: .12em; text-transform: uppercase; color: var(--muted-dark); }
.strike { text-decoration: line-through; opacity: .55; }

.pricecards { display: grid; gap: 16px; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); }
.pricecard { border: 1px solid var(--rule); border-radius: var(--r); padding: 26px; background: var(--on-dark); text-align: center; }
.pricecard .n { font-family: var(--display); font-size: 2.6rem; line-height: 1; display: block; margin-bottom: .3rem; }
.pricecard .l { font-family: var(--ui); font-size: .86rem; font-weight: 650; }
.pricecard .pricecard__note { font-family: var(--ui); font-size: .8rem; color: var(--muted); }

/* ------------------------------------------------------------------ notes */

.note {
  border: 1px solid var(--rule); border-left: 3px solid var(--accent); background: var(--paper-2);
  border-radius: 10px; padding: 18px 22px; font-family: var(--ui); font-size: .93rem;
}
.note--warn { border-left-color: var(--warn); background: var(--warn-wash); }
/* Only the FIRST strong is the title. Any <strong> inside the body stays
   inline: as a blanket rule this broke "the message was **not** sent" across
   three lines. */
.note > strong:first-child { display: block; margin-bottom: .3rem; }

/* --------------------------------------------------------------- FAQ/deta */

.faq { border-top: 1px solid var(--rule); }
.faq details { border-bottom: 1px solid var(--rule); }
.faq summary {
  cursor: pointer; list-style: none; padding: 22px 44px 22px 0; position: relative;
  font-family: var(--display); font-size: clamp(1.1rem, 2.2vw, 1.4rem); line-height: 1.3;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after {
  content: ""; position: absolute; right: 8px; top: 50%; width: 11px; height: 11px;
  border-right: 2px solid var(--accent-text); border-bottom: 2px solid var(--accent-text);
  transform: translateY(-70%) rotate(45deg); transition: transform .25s ease;
}
.faq details[open] summary::after { transform: translateY(-30%) rotate(-135deg); }
.faq .faq__a { padding: 0 44px 24px 0; color: var(--muted); }
.faq .faq__a p:last-child { margin-bottom: 0; }

/* Animates to intrinsic height with no JS in browsers that support it,
   and degrades to an instant open everywhere else. */
@supports (interpolate-size: allow-keywords) {
  :root { interpolate-size: allow-keywords; }
  .faq details::details-content {
    block-size: 0; overflow: hidden;
    transition: block-size .32s ease, content-visibility .32s allow-discrete;
  }
  .faq details[open]::details-content { block-size: auto; }
}
@media (prefers-reduced-motion: reduce) {
  .faq details::details-content { transition: none; }
}

/* ------------------------------------------------------------------ forms */

.formcard { background: var(--on-dark); border: 1px solid var(--rule); border-radius: var(--r); padding: clamp(22px, 3vw, 34px); }
.field { margin-bottom: 16px; }
.field label { display: block; font-family: var(--ui); font-size: .82rem; font-weight: 650; margin-bottom: 6px; }
.field input, .field textarea, .field select {
  width: 100%; padding: 13px 15px; border: 1px solid var(--rule); border-radius: 10px;
  font-family: var(--ui);
  /* 16px is not a style choice. iOS Safari force-zooms on focus below 16px
     and never zooms back, which strands people mid-form. */
  font-size: 16px;
  background: var(--on-dark); color: var(--ink);
}
/* NOT outline:none. That removed the only focus indicator on every form
   field in the kit. The ring is drawn with outline so it follows the border
   radius and survives a forced-colours mode. */
.field input:focus-visible, .field textarea:focus-visible, .field select:focus-visible {
  border-color: var(--accent-text); outline: 3px solid var(--accent-text); outline-offset: 2px;
}
.field input:focus, .field textarea:focus, .field select:focus { border-color: var(--accent-text); }
.field textarea { min-height: 130px; resize: vertical; }
.formnote { font-family: var(--ui); font-size: .82rem; color: var(--muted); margin-top: 12px; }
.formstatus { font-family: var(--ui); font-size: .9rem; margin-top: 14px; padding: 12px 16px; border-radius: 10px; display: none; }
.formstatus.is-ok { display: block; background: var(--accent-wash); color: var(--accent-deep); }
.formstatus.is-err { display: block; background: var(--err-wash); color: var(--err); }

/* ---------------------------------------------------------------- library */

.filters { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 28px; }
.filters button {
  font-family: var(--ui); font-size: .85rem; font-weight: 550; padding: 9px 16px;
  border-radius: 999px; border: 1px solid var(--rule); background: var(--on-dark); color: var(--ink-2); cursor: pointer;
}
.filters button:hover { border-color: var(--rule-2); }
.filters button[aria-pressed="true"] { background: var(--ink); color: var(--on-dark); border-color: var(--ink); }

.vidcard { display: flex; flex-direction: column; gap: 6px; padding: 20px; border: 1px solid var(--rule); border-radius: var(--r); background: var(--on-dark); text-decoration: none; color: var(--ink); }
.vidcard:hover { border-color: var(--accent-text); color: var(--ink); }
.vidcard .k { font-family: var(--ui); font-size: .7rem; font-weight: 700; letter-spacing: .1em; text-transform: uppercase; color: var(--accent-text); }
.vidcard h3 { font-size: 1.15rem; margin: 0; }
.vidcard p { font-size: .92rem; color: var(--muted); margin: 0; }

.videoframe { aspect-ratio: 16 / 9; background: var(--ink); border-radius: var(--r); overflow: hidden; display: grid; place-items: center; }
.videoframe iframe, .videoframe video { width: 100%; height: 100%; border: 0; }

/* --------------------------------------------------------------- sticky bar */

.callbar {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 88; display: none;
  background: var(--ink); border-top: 1px solid var(--rule-dark);
  padding: 9px 12px calc(9px + env(safe-area-inset-bottom));
  gap: 9px; font-family: var(--ui);
}
.callbar a { flex: 1; text-decoration: none; min-width: 0; }
/* The number has to stay readable AND stay on one line. At .88rem
   "+62 823 4048 5943" wrapped to two lines in a 375px viewport and made the
   two buttons different heights. Measured at .78rem it fits with room spare. */
/* min-height, not padding alone. The WhatsApp button carries an icon and the
   Book button does not, so padding alone left them 3px different. */
.callbar .btn { width: 100%; min-height: 44px; padding: 12px 8px; font-size: .78rem; white-space: nowrap; letter-spacing: -.01em; }
.callbar .btn svg { flex: 0 0 auto; }
.callbar .btn--outline-light { border-color: rgba(255, 255, 255, .35); }
/* Spacer, so the bar never covers the end of the footer. Two rules learned
   the hard way: it must NOT be body padding (that paints the body background
   under a dark footer and shows as a white band), and it must sit INSIDE the
   footer so it inherits the footer's colour rather than introducing a seam. */
.callbar-spacer { display: none; height: calc(var(--bar) + env(safe-area-inset-bottom)); }

/* ----------------------------------------------------------------- footer */

.ftr { background: var(--ink); color: var(--on-dark-2); font-family: var(--ui); font-size: .9rem; padding-block: clamp(44px, 6vw, 72px) 28px; }
.ftr h4 { color: var(--on-dark); font-size: .78rem; letter-spacing: .13em; text-transform: uppercase; margin-bottom: 14px; }
.ftr a { color: var(--on-dark-2); text-decoration: none; }
.ftr a:hover { color: var(--on-dark); }
.ftr__grid { display: grid; gap: 34px; grid-template-columns: 1.4fr 1fr 1fr 1fr; }
.ftr__grid ul { list-style: none; padding: 0; margin: 0; }
.ftr__grid li { margin-bottom: 9px; }
.ftr__brand { font-family: var(--display); font-size: 1.5rem; color: var(--on-dark); margin-bottom: 10px; }
.ftr__socials { display: flex; gap: 10px; margin-top: 16px; }
.ftr__socials a { width: 40px; height: 40px; border: 1px solid rgba(255, 255, 255, .2); border-radius: 10px; display: inline-flex; align-items: center; justify-content: center; }
.ftr__socials a:hover { border-color: rgba(255, 255, 255, .5); }
.ftr__base { margin-top: 40px; padding-top: 22px; border-top: 1px solid var(--rule-dark); display: flex; flex-wrap: wrap; gap: 8px 22px; justify-content: space-between; font-size: .82rem; color: var(--on-dark-3); }

/* ------------------------------------------------------------------ chat */

.chat-fab {
  position: fixed; right: 18px; bottom: 18px; z-index: 92; width: 58px; height: 58px; border-radius: 50%;
  background: var(--accent-text); color: var(--on-dark); border: 0; cursor: pointer; box-shadow: var(--shadow-lg);
  display: grid; place-items: center; transition: transform .18s ease;
}
.chat-fab:hover { transform: scale(1.06); }
.chat-fab__dot { position: absolute; top: 2px; right: 2px; width: 13px; height: 13px; border-radius: 50%; background: var(--flag); border: 2px solid var(--ink); }
.chat-panel {
  position: fixed; right: 18px; bottom: 86px; z-index: 93; width: min(384px, calc(100vw - 36px));
  height: min(560px, calc(100vh - 130px)); background: var(--on-dark); border: 1px solid var(--rule);
  border-radius: 18px; box-shadow: var(--shadow-lg); display: none; flex-direction: column; overflow: hidden;
}
.chat-panel.is-open { display: flex; }
.chat-hd { background: var(--ink); color: var(--on-dark); padding: 15px 18px; display: flex; align-items: center; gap: 11px; font-family: var(--ui); }
.chat-hd b { font-size: .95rem; }
.chat-hd small { display: block; color: var(--on-dark-3); font-size: .75rem; }
.chat-hd button { margin-left: auto; background: transparent; border: 0; color: var(--on-dark); font-size: 1.3rem; cursor: pointer; line-height: 1; padding: 4px 8px; }
.chat-demo { background: var(--warn-wash); color: var(--warn-ink); font-family: var(--ui); font-size: .76rem; padding: 8px 18px; border-bottom: 1px solid var(--warn-rule); }
.chat-log { flex: 1; overflow-y: auto; padding: 18px; display: flex; flex-direction: column; gap: 12px; font-family: var(--ui); font-size: .92rem; }
.msg { max-width: 84%; padding: 11px 15px; border-radius: 16px; line-height: 1.5; white-space: pre-wrap; overflow-wrap: anywhere; }
.msg--bot { background: var(--paper-2); border-bottom-left-radius: 5px; align-self: flex-start; }
.msg--me { background: var(--accent-text); color: var(--on-dark); border-bottom-right-radius: 5px; align-self: flex-end; }
.msg--sys { align-self: center; font-size: .78rem; color: var(--muted); text-align: center; }
.chat-ft { border-top: 1px solid var(--rule); padding: 12px; display: flex; gap: 9px; }
.chat-ft input { flex: 1; padding: 11px 14px; border: 1px solid var(--rule); border-radius: 999px; font-family: var(--ui); font-size: 16px; }
.chat-ft input:focus-visible { border-color: var(--accent-text); outline: 3px solid var(--accent-text); outline-offset: 2px; }
.chat-ft button { width: 42px; height: 42px; border-radius: 50%; border: 0; background: var(--accent-text); color: var(--on-dark); cursor: pointer; flex: 0 0 auto; display: grid; place-items: center; }
.chat-ft button:disabled { opacity: .45; cursor: default; }

/* ---------------------------------------------------------------- reveal */

.reveal { opacity: 0; transform: translateY(18px); transition: opacity .6s cubic-bezier(.2,.7,.3,1), transform .6s cubic-bezier(.2,.7,.3,1); }
.reveal.is-in { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) {
  .reveal { opacity: 1 !important; transform: none !important; transition: none; }
  .card:hover, .btn:hover, .chat-fab:hover { transform: none; }
}

/* ------------------------------------------------------------ responsive */

@media (max-width: 1180px) {
  /* Email is the least useful of the three and the longest. It goes first, so
     the rating and the number keep their space. */
  .topbar__mail { display: none; }
}

@media (max-width: 1000px) {
  .nav { display: none; }
  .burger { display: inline-flex; }
  .topbar__loc { display: none; }
}

@media (max-width: 560px) {
  /* Below this the stars stop being legible at 13px in a 40px bar. Keep the
     number and the count, drop the stars. */
  .rating--bar .rating__stars { display: none; }
  .rating--bar span:not(.rating__stars)::before { content: "★ "; color: var(--star); }
}

@media (max-width: 760px) {
  body { font-size: 17px; }
  .hdr__in { min-height: 60px; gap: 12px; }
  .brand { font-size: 1.3rem; }
  .split, .split--narrow-media { grid-template-columns: 1fr; }
  /* Only fires for hand-written markup where .split__media is a direct grid
     child. Anything built with split() uses .split--media-first above. */
  .split__media { order: -1; }
  .ftr__grid { grid-template-columns: 1fr 1fr; }
  .callbar { display: flex; }
  .callbar-spacer { display: block; }
  .chat-fab { bottom: calc(var(--bar) + 14px + env(safe-area-inset-bottom)); }
  .chat-panel { bottom: calc(var(--bar) + 78px + env(safe-area-inset-bottom)); height: min(500px, calc(100dvh - 210px)); }
  .step { grid-template-columns: 44px 1fr; gap: 14px; padding: 18px; }
  .step__n { width: 44px; height: 44px; font-size: 1rem; }
  .topbar__in { font-size: .78rem; }
}

@media (max-width: 460px) {
  .ftr__grid { grid-template-columns: 1fr; }
  .topbar__right { gap: 12px; }
}

/* ============================================================ PREMIUM BLOCKS
   The blocks that make a small business site look expensive rather than
   templated. All of them are photography-led, because on a client rebuild the
   photographs are the one asset you cannot regenerate and the one thing that
   makes the site feel like them.
*/

/* Near-edge gutters. A 1180px centred column reads as SaaS marketing; real
   editorial sites run closer to the edge. Measured on a client's own site:
   43px gutters at 1440, which is 3%. */
.wrap--wide { max-width: 1560px; margin-inline: auto; padding-inline: clamp(18px, 3vw, 44px); }
.wrap--flush { max-width: none; padding-inline: 0; }

/* Tiles. Flush images, tight gutters, no border, no radius, no shadow.
   The card chrome is what makes three photographs look like a pricing table. */
.tiles { display: grid; gap: clamp(10px, 1vw, 14px); grid-template-columns: repeat(auto-fit, minmax(min(100%, 300px), 1fr)); }
.tile { position: relative; display: block; text-decoration: none; color: inherit; }
.tile:hover { color: inherit; }
.tile__img { overflow: hidden; background: var(--paper-3); }
/* aspect-ratio on the IMG. See the note on .card__img: on the wrapper it loses
   to the image's intrinsic height and every tile ends a different size. */
.tile__img img { width: 100%; aspect-ratio: 4 / 3; height: auto; object-fit: cover; transition: transform .7s cubic-bezier(.2,.7,.3,1); }
.tile:hover .tile__img img { transform: scale(1.04); }
.tile__body { padding: 22px 2px 0; }
.tile__body h3 { margin-bottom: .4rem; }
.tile__body p { color: var(--muted); margin-bottom: .8rem; }
.tile__more { font-family: var(--ui); font-size: .84rem; font-weight: 650; color: var(--accent-text); }
.tiles--tall .tile__img img { aspect-ratio: 4 / 5; }
.tiles--square .tile__img img { aspect-ratio: 1; }

/* Centred section head. Big, quiet, lots of air either side. */
.sec__head--center { max-width: 720px; margin-inline: auto; text-align: center; }

/* Feature. Text one side, a tall photograph the other, running the full height
   of the section rather than sitting in a box. */
.feature { display: grid; grid-template-columns: 1fr 1fr; align-items: center; gap: clamp(28px, 5vw, 72px); }
.feature--flip .feature__media { order: -1; }
.feature__media img { width: 100%; aspect-ratio: 4 / 5; height: auto; object-fit: cover; border-radius: var(--r); }
.feature--edge .feature__media img { border-radius: 0; }
.feature__body { max-width: 30rem; }

/* A full-bleed photograph with words over it. The single cheapest way to make
   a page feel designed, and it uses a picture the client already owns. */
.bleed {
  position: relative; display: grid; place-items: center; text-align: center;
  min-height: clamp(360px, 46vw, 560px); padding: clamp(40px, 7vw, 90px) var(--gut);
  color: var(--on-dark); overflow: hidden; isolation: isolate;
}
.bleed__media { position: absolute; inset: 0; z-index: -2; }
.bleed__media img { width: 100%; height: 100%; object-fit: cover; }
.bleed::after {
  content: ""; position: absolute; inset: 0; z-index: -1;
  background: linear-gradient(180deg, rgba(0,0,0,.5), rgba(0,0,0,.62));
}
.bleed h2, .bleed h3, .bleed p { color: var(--on-dark); }
.bleed__in { max-width: 900px; }
.bleed blockquote { margin: 0; font-family: var(--display); font-size: clamp(1.6rem, 4vw, 3rem); line-height: 1.16; }
.bleed cite { display: block; margin-top: 1.2rem; font-family: var(--ui); font-size: .9rem; font-style: normal; opacity: .82; }

/* Numbers on dark. Only ever real, measured numbers. */
.stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: clamp(20px, 3vw, 40px); }
.stat__n { font-family: var(--display); font-size: clamp(2.4rem, 5vw, 3.6rem); line-height: 1; display: block; }
.stat__l { font-family: var(--ui); font-size: .86rem; color: var(--on-dark-3); margin-top: .5rem; display: block; }
.sec:not(.sec--dark) .stat__l { color: var(--muted); }

/* Marquee strip for logos or names. Pauses on hover and stops dead under
   prefers-reduced-motion, because a permanent loop is a real accessibility
   problem for some people. */
.marquee { overflow: hidden; -webkit-mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent); mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent); }
.marquee__track { display: flex; gap: clamp(28px, 5vw, 72px); width: max-content; animation: marquee 38s linear infinite; }
.marquee:hover .marquee__track,
.marquee:focus-within .marquee__track,
.marquee[data-paused="true"] .marquee__track { animation-play-state: paused; }
.marquee__pause {
  position: absolute; right: 8px; top: 50%; transform: translateY(-50%);
  font-family: var(--ui); font-size: .72rem; padding: 6px 12px; border-radius: 999px;
  border: 1px solid var(--rule); background: var(--paper); color: var(--ink); cursor: pointer;
}
.marquee { position: relative; }
.marquee__item { font-family: var(--ui); font-size: .95rem; font-weight: 600; white-space: nowrap; opacity: .72; }
@keyframes marquee { to { transform: translateX(-50%); } }
@media (prefers-reduced-motion: reduce) {
  .marquee__track { animation: none; flex-wrap: wrap; width: auto; justify-content: center; }
  .tile:hover .tile__img img { transform: none; }
}

@media (max-width: 860px) {
  .feature, .feature--flip { grid-template-columns: 1fr; }
  .feature--flip .feature__media { order: 0; }
  .feature__media { order: -1; }
}

/* ------------------------------------------------- ElevenLabs widget note

   The embed renders its own launcher, so the kit adds only the demo label.
   It sits above the sticky call bar on mobile and clear of the launcher, and
   it cannot be dismissed: an unlabelled assistant answering questions about
   availability on a clinic's branding is worse than no assistant at all.
*/
.chat-demo-note {
  position: fixed; z-index: 87; right: 16px; bottom: 16px;
  max-width: 210px; padding: 8px 12px;
  font-family: var(--ui); font-size: .7rem; line-height: 1.35;
  background: var(--warn-wash); color: var(--warn-ink);
  border: 1px solid var(--warn-rule); border-radius: 8px;
  box-shadow: var(--shadow); pointer-events: none;
}
/* The embed's own launcher occupies the bottom-right corner, so the note sits
   above it. Values are the widget's collapsed footprint plus a gap. */
@media (min-width: 761px) { .chat-demo-note { bottom: 92px; } }
@media (max-width: 760px) { .chat-demo-note { bottom: calc(var(--bar) + 78px); max-width: 168px; } }
@media (max-width: 420px) { .chat-demo-note { display: none; } }

/* split() wraps each side in a column div, so .split__media is a grandchild of
   the grid and `order` can never reach it. The order goes on the column. */
.split__col { min-width: 0; }
@media (max-width: 860px) {
  .split--media-first .split__col--b { order: -1; }
}


/* ---- demo only ---- */
.themebar { background: var(--ink); color: var(--on-dark); font-family: var(--ui); font-size: .8rem; }
.themebar__in { display: flex; align-items: center; gap: 18px; flex-wrap: wrap; padding-block: 10px; }
.themebar__label { color: var(--on-dark-3); text-transform: uppercase; letter-spacing: .12em; font-size: .68rem; }
.themebar__opts { display: flex; gap: 6px; }
.themebar__opts a { color: var(--on-dark-2); text-decoration: none; padding: 6px 13px; border-radius: 999px; border: 1px solid rgba(255,255,255,.2); }
.themebar__opts a:hover { color: var(--on-dark); border-color: rgba(255,255,255,.5); }
.themebar__opts a[aria-current="page"] { background: var(--on-dark); color: var(--ink); border-color: var(--on-dark); font-weight: 650; }
.themebar__note { color: var(--on-dark-3); margin-left: auto; }
@media (max-width: 760px) { .themebar__note { display: none; } }
