/* ==========================================================================
   Site styles. Logical properties only — layout flips from [dir] alone.
   No raw hex: every color comes from a role token in tokens.css.
   ========================================================================== */

/* --- Fonts. Self-hosted (SIL OFL), subset, woff2. ------------------------ */
@font-face {
  font-family: "Cormorant Garamond";
  src: url("/assets/fonts/cormorant-latin.33679a74b5.woff2") format("woff2-variations");
  font-weight: 300 700;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Cormorant Garamond";
  src: url("/assets/fonts/cormorant-italic-latin.1e36efc618.woff2") format("woff2-variations");
  font-weight: 300 700;
  font-style: italic;
  font-display: swap;
}
@font-face {
  font-family: "Montserrat";
  src: url("/assets/fonts/montserrat-latin.28f6ca0983.woff2") format("woff2-variations");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Montserrat Arabic";
  src: url("/assets/fonts/montserrat-arabic.90dbb9c696.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

/* --- Reset --------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; }
html { -webkit-text-size-adjust: 100%; }
img, svg { display: block; max-inline-size: 100%; block-size: auto; }
a { color: inherit; }

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

/* --- Base ---------------------------------------------------------------- */
body {
  background-color: var(--surface);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: var(--step-0);
  font-weight: var(--weight-body);
  line-height: var(--leading-body);
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
  min-block-size: 100svh;
  display: flex;
  flex-direction: column;
}

:where(h1, h2, h3) {
  font-family: var(--font-heading);
  font-weight: var(--weight-display);
  line-height: var(--leading-tight);
  text-wrap: balance;
}

p { text-wrap: pretty; }

/* Focus: defined for both the light ground and the dark surface. */
:focus-visible {
  outline: 2px solid var(--focus-ring);
  outline-offset: 3px;
}
.surface-invert :focus-visible { outline-color: var(--focus-ring-invert); }

.skip-link {
  position: absolute;
  inset-block-start: var(--space-2xs);
  inset-inline-start: var(--space-2xs);
  padding: var(--space-2xs) var(--space-s);
  background-color: var(--surface-invert);
  color: var(--ink-invert);
  font-size: var(--step--1);
  transform: translateY(-200%);
  transition: transform var(--transition);
  z-index: 10;
}
.skip-link:focus-visible { transform: translateY(0); }

/* --- Layout -------------------------------------------------------------- */
.shell {
  inline-size: min(100% - (var(--gutter) * 2), var(--page-max));
  margin-inline: auto;
}
.flow > * + * { margin-block-start: var(--flow-gap, var(--space-s)); }
main { flex: 1; }

/* --- The mirror rule: the brand's one graphic device ---------------------
   A hairline, a diamond, a hairline. Used as the logo's spine, as the divider
   between sections (A4), and above the voice band. Built once here so it can
   never drift between the places it appears.

   The fade-to-transparent ends are the point: rules on this site end by
   dissolving, not by stopping. --------------------------------------------- */
.mirror {
  display: flex;
  align-items: center;
  gap: 0.75em;
  color: var(--rule);
  flex: none;
}
.mirror i {
  inline-size: 4em;
  block-size: var(--hairline);
  background: linear-gradient(to right, transparent, currentColor 35%,
                              currentColor 65%, transparent);
}
.mirror b {
  inline-size: 0.32em;
  block-size: 0.32em;
  background: currentColor;
  transform: rotate(45deg);
  flex: none;
}
/* Short accent marks may stay solid — under 3em there is not enough length
   for a fade to read as anything but a smudge. */
.mirror--tight i { inline-size: 2em; background: currentColor; }

/* A4 — the divider between two sections that share the ivory ground. */
.mirror--divider {
  justify-content: center;
  margin-block: var(--space-7);
}
.hero .mirror--divider { margin-block: 0; }
.hero .mirror i { inline-size: 5em; }

/* --- The MIRROR lockup ---------------------------------------------------
   Never stretched, tilted, recoloured, reordered or given effects. Clear
   space is 4x the diamond width on every side, held by the padding below. -- */
.lockup {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  text-decoration: none;
  color: var(--ink);
  padding: 1.28em;              /* 4 x the 0.32em diamond */
  margin: -1.28em;              /* clear space without shifting the layout */
  min-inline-size: 6rem;        /* the 96px floor */
}
.lockup__latin {
  font-family: var(--family-display);
  font-weight: var(--weight-display);
  letter-spacing: 0.26em;
  padding-inline-start: 0.26em; /* balance the trailing letter-space */
  white-space: nowrap;
}
.lockup__ar {
  font-family: var(--family-arabic);
  font-weight: var(--weight-body);
  letter-spacing: 0;            /* never, under any circumstance */
  white-space: nowrap;
}
.lockup--inline { font-size: var(--size-small); flex: 0 1 auto; min-inline-size: 0; }
/* Between the tablet break and full desktop the header is tight. The Arabic
   half of the inline lockup goes first — the wordmark and the mirror still
   identify the mark, and the Arabic name is on every page below it anyway. */
@media (max-width: 68rem) {
  .lockup--inline .lockup__ar,
  .lockup--inline .mirror { display: none; }
}
.lockup--inline .lockup__ar { color: var(--ink-secondary); }

.lockup--stacked {
  flex-direction: column;
  gap: var(--space-4);
  text-align: center;
  font-size: var(--size-h3);
}
.lockup--stacked .mirror i { inline-size: 3.5em; }
.lockup__desc {
  font-family: var(--family-support);
  font-size: var(--size-kicker);
  letter-spacing: var(--tracking-descriptor);
  padding-inline-start: var(--tracking-descriptor);
  text-transform: uppercase;
  color: var(--ink-secondary);
  line-height: 1.6;
}

/* Below the 96px floor the full lockup stops being legible; swap to the
   compact mark rather than letting it shrink into a smear. */
.lockup__compact { display: none; }
@media (max-width: 22rem) {
  .lockup--inline .lockup__latin,
  .lockup--inline .mirror,
  .lockup--inline .lockup__ar { display: none; }
  .lockup--inline .lockup__compact {
    display: inline;
    font-family: var(--family-display);
    letter-spacing: 0.26em;
    padding-inline-start: 0.26em;
  }
}

/* --- A1 · Section kicker -------------------------------------------------
   Number, dash, tracked caps label, then a hairline to the container edge
   that fades out. The rule is the last flex child, so it fills whatever is
   left and mirrors automatically under [dir] without a physical property. */
.kicker {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  font-family: var(--family-support);
  font-size: var(--size-kicker);
  line-height: 1;
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  /* umber, not taupe: at 11px this is small text and needs 4.5:1 */
  color: var(--ink-secondary);
  margin-block-end: var(--space-5);
}
.kicker__n { font-variant-numeric: lining-nums tabular-nums; }
.kicker__dash { color: var(--rule); }
.kicker__label { padding-inline-start: var(--tracking-label); }
.kicker__rule {
  flex: 1;
  block-size: var(--hairline);
  background: linear-gradient(to left, transparent, var(--rule-fade));
  margin-inline-start: var(--space-2);
}
[dir="ltr"] .kicker__rule {
  background: linear-gradient(to right, transparent, var(--rule-fade));
}
:lang(ar) .kicker {
  letter-spacing: 0;
  text-transform: none;
  font-family: var(--family-arabic);
  font-size: var(--size-small);
}
:lang(ar) .kicker__label { padding-inline-start: 0; }

/* --- A3 · Watermark wordmark ---------------------------------------------
   The brand filling its own empty space, rather than decoration filling it.
   One per page, never behind body copy. */
.watermark {
  position: absolute;
  /* Anchored low and bled well off the trailing edge, so it fills the corner
     the layout leaves empty without ever sitting behind the name or a line
     of body copy. */
  inset-block-end: -8%;
  inset-inline-end: -14vw;
  font-family: var(--family-arabic);
  font-size: clamp(9rem, 22vw, 24rem);
  line-height: 1;
  white-space: nowrap;
  color: var(--ink);
  opacity: 0.03;
  pointer-events: none;
  user-select: none;
  z-index: 0;
}
.watermark--footer { color: var(--ink-invert); opacity: 0.05; }

/* --- Masthead ------------------------------------------------------------
   Sticky, 64px, ivory. The bottom hairline appears only once the page has
   scrolled, so at rest the header dissolves into the ground and the hero has
   no line across the top of it. The state comes from a 1px sentinel above
   the header rather than a scroll handler — no listener, no work per frame. */
.masthead__sentinel {
  display: block;
  block-size: var(--hairline);
}
.masthead {
  position: sticky;
  inset-block-start: 0;
  z-index: 20;
  background-color: var(--surface);
  border-block-end: var(--hairline) solid transparent;
  transition: border-color var(--transition);
}
.masthead.is-stuck { border-block-end-color: var(--rule-soft); }
.masthead__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-5);
  min-block-size: 4rem;         /* 64px */
}
.masthead__actions {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex: none;
}

.lang-switch {
  font-family: var(--family-support);   /* the switch label is always Latin */
  font-size: var(--size-kicker);
  letter-spacing: var(--tracking-button);
  text-transform: uppercase;
  text-decoration: none;
  color: var(--ink-secondary);
  /* 44px hit area without 44px of visual weight */
  display: inline-flex;
  align-items: center;
  min-block-size: 2.75rem;
  padding-inline: var(--space-2);
  border-block-end: var(--hairline) solid transparent;
  transition: color var(--transition), border-color var(--transition);
  white-space: nowrap;
}
.lang-switch:hover { color: var(--ink); border-block-end-color: var(--rule); }

/* --- A10 · The mobile booking bar ---------------------------------------
   The only filled button on the site, held at the foot of every phone
   screen. Desktop gets the header button instead. */
.wa-bar { display: none; }
@media (max-width: 52rem) {
  .wa-bar {
    position: fixed;
    inset-inline: 0;
    inset-block-end: 0;
    z-index: 30;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-3);
    min-block-size: 3.5rem;      /* 56px */
    background-color: var(--surface-invert);
    color: var(--ink-invert);
    text-decoration: none;
    font-family: var(--font-label);
    font-size: var(--size-small);
    font-weight: var(--weight-medium);
    letter-spacing: var(--tracking-button);
    padding-inline: var(--space-5);
  }
  :lang(ar) .wa-bar { letter-spacing: 0; }
  .wa-bar svg { inline-size: 1.25rem; block-size: 1.25rem; fill: currentColor; }
  /* The brief's mobile header is the logo and a menu button. The WhatsApp
     action lives in the bar at the foot of the screen, so the header copy of
     it is removed rather than shown twice. */
  .masthead .wa-btn { display: none; }

  /* Nothing at the foot of the page may sit under the bar. */
  body { padding-block-end: 3.5rem; }
  .colophon { padding-block-end: var(--space-8); }
}

/* --- Hero ---------------------------------------------------------------- */
.hero {
  padding-block: clamp(var(--space-xl), 12vh, var(--space-3xl));
  text-align: center;
}
.hero__name {
  font-size: var(--step-4);
  letter-spacing: var(--tracking-display);
  text-transform: var(--transform-display);
  /* Letterspacing adds trailing space after the last glyph; pull it back so
     the lockup stays optically centred. Zero for Arabic, where tracking is 0. */
  margin-inline-end: calc(var(--tracking-display) * -1);
}
.hero__title {
  font-family: var(--font-label);
  font-size: var(--step--1);
  font-weight: var(--weight-medium);
  letter-spacing: var(--tracking-label);
  text-transform: var(--transform-label);
  color: var(--ink-secondary);
  margin-inline-end: calc(var(--tracking-label) * -1);
}
.hero__voice {
  font-family: var(--font-heading);
  font-style: italic;
  font-size: var(--step-2);
  color: var(--ink-secondary);
}
:lang(ar) .hero__voice { font-style: normal; }  /* the Arabic face has no italic */

.hero__copy { display: flex; flex-direction: column; gap: var(--space-5); }
.hero { position: relative; overflow: hidden; }   /* the watermark bleeds */
.hero > .shell { position: relative; z-index: 1; }
.section__more { margin-block-start: var(--space-6); }
.section__heading { margin-block-end: var(--space-4); }

.hero__note {
  max-inline-size: var(--measure-narrow);
  margin-inline: auto;
  color: var(--ink-secondary);
  font-size: var(--step-0);
}

/* --- Hero with the doctor's portrait -------------------------------------
   The cut-out stands against a BONE panel. A rectangle and not an ellipse
   on purpose: --radius is 0 because the identity is square, and a circle
   here would be the one round corner on the whole site.

   This is the page's one decorative wash. Do not add another. */
.hero--portrait .shell {
  display: grid;
  gap: var(--space-l);
  justify-items: center;
}
.hero__figure {
  position: relative;
  inline-size: min(300px, 64vw);
  margin: 0;
}
.hero__figure::before {
  content: "";
  position: absolute;
  inset-block: 14% 0;
  inset-inline: 6%;
  background-color: var(--surface-alt);
}
.hero__portrait {
  position: relative;   /* lifts her above the panel without a z-index race */
  display: block;
  inline-size: 100%;
  block-size: auto;
}

@media (min-width: 52rem) {
  .hero--portrait .shell {
    /* Both columns size to their content and the pair is centred as a unit.
       Giving the copy 1fr instead pins the two to opposite edges of the
       shell and opens a dead zone down the middle of the page. */
    grid-template-columns: auto auto;
    justify-content: center;
    align-items: end;
    justify-items: start;
    text-align: start;
    gap: var(--space-2xl);
  }
  /* The flanking rules read as centred trim; start-aligned they would point
     at nothing. Drop the leading rule and let the diamond begin the line. */
  .hero--portrait .mirror { justify-content: start; }
  .hero--portrait .hero__copy { padding-block-end: var(--space-l); }
  .hero--portrait .hero__figure { inline-size: min(340px, 32vw); }
}

/* --- A photograph beside prose ------------------------------------------- */
.duo {
  display: grid;
  gap: var(--space-l);
  align-items: start;
}
@media (min-width: 52rem) {
  .duo { grid-template-columns: minmax(0, 1.7fr) minmax(0, 1fr); }
}
.duo__figure { margin: 0; }
.duo__figure img {
  display: block;
  inline-size: 100%;
  block-size: auto;
}
.duo__caption {
  margin-block-start: var(--space-2xs);
  font-size: var(--step--1);
  /* UMBER, 8.69:1. Never TAUPE — it fails AA and is exposed only as --rule. */
  color: var(--ink-secondary);
}

/* Cards and location panels answer the pointer with a hairline that darkens.
   That, plus colour and opacity at 160ms, is the entire motion budget. */
.card, .location {
  transition: background-color var(--transition), border-color var(--transition);
}

/* --- Scroll reveal -------------------------------------------------------
   Content rises a little and fades in as it enters view.

   Four rules, each of which has already been paid for once:

   1. :where() IS LOAD-BEARING. It flattens this list to zero specificity so
      `.reveal .is-in` (0,2,0) always outranks it. Without it, `.card` at
      (0,2,0) merely ties and is saved by source order, while
      `.article > p` at (0,2,1) BEATS the reveal rule — which is exactly how
      an earlier version of this shipped with every treatment page's body
      text set to opacity 0 and unable to come back. See LESSONS #27.
   2. NOTHING ABOVE THE FOLD. No selector reaches into .hero, .page-head or
      .masthead. The element painted largest and earliest is the h1 or the
      portrait, and animating the LCP element's opacity delays LCP by exactly
      the duration of the animation.
   3. Only opacity and transform — both composited, so no layout, no paint.
   4. The `.reveal` gate is set by an inline head script that refuses to run
      under prefers-reduced-motion or without IntersectionObserver. No class,
      no hiding: a reduced-motion visitor, an old browser, or one whose
      JavaScript never arrives sees an ordinary page. Content is never hidden
      on a bet that a script will run. ------------------------------------ */
.reveal :where(
  .kicker,
  .section__heading,
  .section__note,
  .section__more,
  .card,
  .video-card,
  .location,
  .duo__figure,
  .steps__col,
  .article > h2,
  .article > h3,
  .article > p,
  .article > ul,
  .article > ol,
  .table-wrap,
  .faq details,
  .byline,
  .embed-note,
  .aliases,
  .voice-band__line,
  .booking__heading,
  .booking p,
  .mirror--divider
) {
  opacity: 0;
  transform: translateY(var(--reveal-rise));
  transition:
    opacity   var(--reveal-dur) var(--reveal-ease) var(--reveal-delay, 0ms),
    transform var(--reveal-dur) var(--reveal-ease) var(--reveal-delay, 0ms);
}
.reveal .is-in {
  opacity: 1;
  transform: none;
}

/* Anything the observer will never reach must not be hidden by the rule
   above, or it is hidden forever. The JS filters out these four containers to
   protect LCP; this keeps the CSS in step with that filter.

   This is not hypothetical: the hero's mirror divider matched the list, was
   set to opacity 0, and the observer then skipped it because it sits inside
   .hero — so the divider under her name simply never appeared. Same shape of
   fault as the specificity bug, from the opposite direction.

   :is() takes the specificity of its heaviest argument (0,1,0) and :where()
   contributes nothing, so this ties with the hiding rule and wins on order.
   It deliberately does NOT use a bare `*`, which would also overwrite the
   watermark's 3% opacity. */
:is(.hero, .page-head, .masthead, .colophon) :where(
  .kicker, .section__heading, .section__note, .section__more,
  .card, .video-card, .location, .duo__figure, .steps__col,
  .table-wrap, .byline, .embed-note, .aliases,
  .voice-band__line, .booking__heading, .mirror--divider
) {
  opacity: 1;
  transform: none;
}

/* A printed page has no scroll, so nothing may be mid-reveal on paper. */
@media print {
  .reveal :where(.kicker, .card, .article > p, .article > h2, .steps__col,
                 .voice-band__line, .booking__heading, .byline) {
    opacity: 1;
    transform: none;
  }
}

/* --- Sections ------------------------------------------------------------ */
.section { padding-block: var(--space-2xl); }
.section--alt { background-color: var(--surface-alt); }
.section--invert {
  background-color: var(--surface-invert);
  color: var(--ink-invert);
}
.section--invert .section__label,
.section--invert .prose { color: var(--ink-invert-secondary); }

.section__label {
  font-family: var(--font-label);
  font-size: var(--step--1);
  font-weight: var(--weight-medium);
  letter-spacing: var(--tracking-label);
  text-transform: var(--transform-label);
  color: var(--ink-secondary);
  margin-inline-end: calc(var(--tracking-label) * -1);
}
.section__heading { font-size: var(--step-3); }
/* One line under a category heading on the treatments hub, saying what the
   group is for. Keeps the grid from reading as an undifferentiated wall. */
.section__note {
  max-inline-size: var(--measure-narrow);
  margin-block: var(--space-2xs) var(--space-m);
  color: var(--ink-secondary);
  font-size: var(--step--1);
}
/* The terms patients actually search by, listed at the foot of a service
   page. UMBER, never TAUPE — this is text. */
.aliases {
  margin-block-start: var(--space-m);
  color: var(--ink-secondary);
  font-size: var(--step--1);
}
.prose {
  max-inline-size: var(--measure);
  color: var(--ink-secondary);
}
.prose--center { margin-inline: auto; text-align: center; }

/* --- Detail list --------------------------------------------------------- */
.details {
  display: grid;
  gap: var(--space-m);
  grid-template-columns: repeat(auto-fit, minmax(min(15rem, 100%), 1fr));
  margin-block-start: var(--space-l);
  text-align: start;
}
.details__term {
  font-family: var(--font-label);
  font-size: var(--step--1);
  font-weight: var(--weight-medium);
  letter-spacing: var(--tracking-label);
  text-transform: var(--transform-label);
  color: var(--ink-secondary);
  margin-inline-end: calc(var(--tracking-label) * -1);
  margin-block-end: var(--space-3xs);
}
.details__value { font-size: var(--step-1); font-family: var(--font-heading); }

/* --- A12 · Footer, as the closing lockup --------------------------------
   Espresso ground, the stacked lockup at full clear space, then the link
   columns and the fine print. This is the last thing on every page and it
   should read as the mark signing off, not as a list of leftovers. */
.colophon {
  position: relative;
  overflow: hidden;              /* the watermark bleeds; the page must not */
  padding-block: var(--space-9) var(--space-7);
  background-color: var(--surface-invert);
  color: var(--ink-invert-secondary);   /* taupe on espresso is 6.20:1 ✓ */
  font-size: var(--size-small);
}
.colophon > * { position: relative; z-index: 1; }
.colophon__lockup {
  display: flex;
  justify-content: center;
  color: var(--ink-invert);
  padding-block-end: var(--space-8);
}
.colophon__lockup .mirror { color: var(--ink-invert-secondary); }
.colophon__lockup .lockup__desc { color: var(--ink-invert-secondary); }
.colophon__inner {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4) var(--space-5);
  align-items: center;
  justify-content: space-between;
  margin-block-start: var(--space-7);
  padding-block-start: var(--space-5);
  border-block-start: var(--hairline) solid rgba(244, 240, 233, 0.16);
  font-size: var(--size-kicker);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
}
:lang(ar) .colophon__inner { letter-spacing: 0; text-transform: none; font-size: var(--size-small); }
.colophon__cities { color: var(--ink-invert-secondary); }

/* ==========================================================================
   Article — treatment pages
   ========================================================================== */
.nav {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4);
  align-items: center;
}
.nav a {
  font-family: var(--font-label);
  font-size: var(--size-kicker);
  font-weight: var(--weight-medium);
  /* Navigation takes the button tracking, not the kicker's .26em. A kicker
     is one label with a rule after it and can afford the width; seven nav
     items at .26em overflow the header and wrap to a second line. */
  letter-spacing: var(--tracking-button);
  text-transform: var(--transform-label);
  text-decoration: none;
  color: var(--ink-secondary);
  white-space: nowrap;
  display: inline-flex;
  align-items: center;
  min-block-size: 2.75rem;          /* 44px hit area */
  border-block-end: var(--hairline) solid transparent;
  transition: color var(--transition), border-color var(--transition);
}
:lang(ar) .nav a { letter-spacing: 0; font-size: var(--size-small); }
.nav a:hover { color: var(--ink); border-block-end-color: var(--rule); }
.nav a[aria-current="page"] { color: var(--ink); border-block-end-color: var(--ink); }

.page-head {
  padding-block: var(--space-xl) var(--space-l);
  border-block-end: var(--hairline) solid var(--rule-soft);
}
.page-head__title { font-size: var(--step-4); }
.page-head__standfirst {
  font-size: var(--step-1);
  color: var(--ink-secondary);
  max-inline-size: var(--measure);
  margin-block-start: var(--space-s);
}

.article {
  max-inline-size: var(--measure);
  padding-block: var(--space-xl);
}
.article > * + * { margin-block-start: var(--space-s); }
.article h2 {
  font-size: var(--step-2);
  margin-block-start: var(--space-xl);
  padding-block-start: var(--space-s);
  border-block-start: var(--hairline) solid var(--rule-soft);
}
/* The first heading in an article needs none of the three. `.article` already
   opens with 4rem of its own padding; the margin adds a second 4rem, the
   padding a third gap, and the hairline draws a divider under the page head,
   which is already a section boundary. Together that put 128px of empty
   ground above the first substantive line on 78 pages — on a 375px phone the
   honest opening sentence fell below the fold.

   All three, not just the margin: zeroing the margin alone leaves the rule
   floating under the metadata strip, dividing nothing. */
.article > h2:first-child {
  margin-block-start: 0;
  padding-block-start: 0;
  border-block-start: 0;
}

.article h3 {
  font-size: var(--step-1);
  margin-block-start: var(--space-l);
  font-family: var(--font-body);
  font-weight: var(--weight-strong);
}
.article ul, .article ol { padding-inline-start: 1.4em; }
.article li + li { margin-block-start: var(--space-2xs); }
.article strong { font-weight: var(--weight-strong); }

/* Honest-caution block. Deliberately quiet, not alarmist — it is a clinical
   statement, not a warning banner. */
.caution {
  border-inline-start: 3px solid var(--rule);
  padding: var(--space-s) var(--space-m);
  background-color: var(--surface-alt);
  margin-block-start: var(--space-m);
}
.caution__label {
  font-family: var(--font-label);
  font-size: var(--step--1);
  font-weight: var(--weight-medium);
  letter-spacing: var(--tracking-label);
  text-transform: var(--transform-label);
  color: var(--ink-secondary);
  margin-inline-end: calc(var(--tracking-label) * -1);
  margin-block-end: var(--space-2xs);
}

.table-wrap { overflow-x: auto; margin-block-start: var(--space-m); }
table { border-collapse: collapse; inline-size: 100%; min-inline-size: 32rem; }
th, td {
  text-align: start;
  padding: var(--space-2xs) var(--space-s);
  border-block-end: var(--hairline) solid var(--rule-soft);
  vertical-align: top;
}
th {
  font-family: var(--font-label);
  font-size: var(--step--1);
  font-weight: var(--weight-medium);
  letter-spacing: var(--tracking-label);
  text-transform: var(--transform-label);
  color: var(--ink-secondary);
}

.faq { margin-block-start: var(--space-m); }
.faq details {
  border-block-end: var(--hairline) solid var(--rule-soft);
  padding-block: var(--space-s);
}
.faq summary {
  cursor: pointer;
  font-weight: var(--weight-strong);
  list-style: none;
  display: flex;
  gap: var(--space-s);
  align-items: baseline;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after {
  content: "+";
  margin-inline-start: auto;
  color: var(--ink-secondary);
  font-family: var(--family-support);
}
.faq details[open] summary::after { content: "–"; }
.faq details > *:not(summary) { margin-block-start: var(--space-2xs); color: var(--ink-secondary); }

.byline {
  margin-block-start: var(--space-xl);
  padding-block-start: var(--space-s);
  border-block-start: var(--hairline) solid var(--rule-soft);
  font-size: var(--step--1);
  color: var(--ink-secondary);
}
.byline__pending {
  display: inline-block;
  margin-block-start: var(--space-2xs);
  padding: 2px var(--space-2xs);
  border: var(--hairline) dashed var(--rule);
}

.cta {
  margin-block-start: var(--space-xl);
  padding: var(--space-l);
  background-color: var(--surface-invert);
  color: var(--ink-invert);
  text-align: center;
}
.cta p { color: var(--ink-invert-secondary); }
.cta__link {
  display: inline-block;
  margin-block-start: var(--space-s);
  font-family: var(--font-label);
  font-size: var(--step--1);
  font-weight: var(--weight-medium);
  letter-spacing: var(--tracking-label);
  text-transform: var(--transform-label);
  color: var(--ink-invert);
  text-decoration: none;
  border-block-end: var(--hairline) solid var(--ink-invert-secondary);
  padding-block-end: 3px;
}
.cta__link:hover { border-block-end-color: var(--ink-invert); }

/* --- A8 · Treatment cards ------------------------------------------------
   3-up desktop, 2-up tablet, 1-up phone. Raised ground, hairline, no radius.
   The whole card is the link target — a card whose only hit area is the
   title makes a patient aim at eight words of 14px type on a phone. */
.card-grid {
  display: grid;
  gap: var(--space-5);
  grid-template-columns: repeat(3, 1fr);
  margin-block-start: var(--space-6);
}
@media (max-width: 64rem) { .card-grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 40rem) { .card-grid { grid-template-columns: 1fr; } }

.card {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  min-block-size: 2.75rem;
  padding: var(--space-6);
  background-color: var(--surface-raised);
  border: var(--hairline) solid var(--rule-soft);
  text-decoration: none;
  color: var(--ink);
}
.card:hover {
  background-color: var(--surface);
  border-color: var(--rule);
}
.card__n {
  font-family: var(--font-label);
  font-size: var(--size-kicker);
  letter-spacing: var(--tracking-label);
  color: var(--ink-secondary);
  font-variant-numeric: lining-nums tabular-nums;
}
:lang(ar) .card__n { letter-spacing: 0; }
.card__title {
  font-family: var(--font-heading);
  font-size: var(--size-h3);
  line-height: var(--leading-h3);
  font-weight: var(--weight-display);
}
.card__desc {
  color: var(--ink-secondary);
  font-size: var(--size-small);
}
.card__more {
  margin-block-start: auto;
  padding-block-start: var(--space-4);
  font-family: var(--font-label);
  font-size: var(--size-kicker);
  letter-spacing: var(--tracking-label);
  text-transform: var(--transform-label);
  color: var(--ink-secondary);
  transition: color var(--transition);
}
:lang(ar) .card__more { letter-spacing: 0; text-transform: none; font-size: var(--size-small); }
.card:hover .card__more { color: var(--ink); }

/* --- A7 · The voice band -------------------------------------------------
   One per page. The site's single moment of saturation, and the thing that
   stops an endless ivory scroll from reading as one undifferentiated sheet. */
.voice-band {
  background: var(--band-invert);
  color: var(--ink-invert);
  padding-block: var(--space-9);
  text-align: center;
}
.voice-band .mirror { justify-content: center; color: var(--ink-invert-secondary); }
.voice-band__line {
  font-family: var(--font-heading);
  font-style: italic;
  font-size: clamp(1.5rem, 1.1rem + 1.8vw, 2.25rem);
  line-height: var(--leading-h1);
  font-weight: var(--weight-display);
  margin-block-start: var(--space-6);
  max-inline-size: 24ch;
  margin-inline: auto;
}
:lang(ar) .voice-band__line { font-style: normal; }

/* --- A2 · The margin column ----------------------------------------------
   A persistent narrow column on the trailing side holding the quiet things:
   a section number, the cities, a caption. This is what turns the empty half
   of the page into a designed margin rather than a gap. Below 1024px it
   folds away entirely — a 120px column on a phone is a stripe, not a margin. */
.with-margin { display: block; }
.margin-col { display: none; }
@media (min-width: 64rem) {
  .with-margin {
    display: grid;
    grid-template-columns: minmax(0, 1fr) var(--margin-col);
    gap: var(--space-8);
    align-items: start;
  }
  .margin-col {
    display: flex;
    flex-direction: column;
    gap: var(--space-5);
    padding-block-start: var(--space-2);
    font-family: var(--font-label);
    font-size: var(--size-kicker);
    letter-spacing: var(--tracking-label);
    text-transform: var(--transform-label);
    line-height: 1.7;
    color: var(--ink-secondary);
    border-inline-start: var(--hairline) solid var(--rule-soft);
    padding-inline-start: var(--space-5);
  }
  :lang(ar) .margin-col {
    letter-spacing: 0;
    text-transform: none;
    font-size: var(--size-small);
  }
  .margin-col__vertical {
    writing-mode: vertical-rl;
    text-orientation: mixed;
  }
}

/* --- A5 · Treatment metadata strip ---------------------------------------
   Four fields under the h1, separated by hairlines. Exactly what a patient
   wants to know before she reads anything else, and it gives the top of the
   page something to be. Values are the doctor's to supply; until she does,
   each renders a neutral em dash rather than a guess. */
.meta-strip {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  margin-block-start: var(--space-6);
  border-block: var(--hairline) solid var(--rule-soft);
}
@media (max-width: 40rem) { .meta-strip { grid-template-columns: repeat(2, 1fr); } }
.meta-strip__item {
  padding: var(--space-4) var(--space-5) var(--space-4) 0;
  border-inline-start: var(--hairline) solid var(--rule-soft);
  padding-inline-start: var(--space-5);
}
.meta-strip__item:first-child { border-inline-start: 0; padding-inline-start: 0; }
@media (max-width: 40rem) {
  .meta-strip__item:nth-child(3) { border-inline-start: 0; padding-inline-start: 0; }
}
.meta-strip__label {
  display: block;
  font-family: var(--font-label);
  font-size: var(--size-kicker);
  letter-spacing: var(--tracking-label);
  text-transform: var(--transform-label);
  color: var(--ink-secondary);
}
:lang(ar) .meta-strip__label { letter-spacing: 0; text-transform: none; font-size: var(--size-small); }
.meta-strip__value {
  display: block;
  margin-block-start: var(--space-2);
  font-family: var(--font-heading);
  font-size: var(--size-h3);
  font-weight: var(--weight-display);
  font-variant-numeric: lining-nums;
}
.meta-strip__value--pending { color: var(--ink-secondary); }

/* --- A6 · What happens at the visit --------------------------------------
   Three stages, one column each. */
.steps {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--space-7);
  margin-block-start: var(--space-6);
}
@media (max-width: 48rem) { .steps { grid-template-columns: 1fr; gap: var(--space-6); } }
.steps__n {
  font-family: var(--family-display);
  font-size: 2rem;
  line-height: 1;
  color: var(--rule);
  font-variant-numeric: lining-nums;
}
.steps__title {
  font-family: var(--font-heading);
  font-size: var(--size-h3);
  font-weight: var(--weight-display);
  margin-block-start: var(--space-3);
}
.steps__body {
  color: var(--ink-secondary);
  font-size: var(--size-small);
  margin-block-start: var(--space-2);
}

/* --- Buttons -------------------------------------------------------------
   Outlined by default. The single filled button on the site is the WhatsApp
   primary action, because there is exactly one thing a visitor is being
   asked to do and it should not compete with anything. */
.btn-outline {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  min-block-size: 2.75rem;
  padding: var(--space-3) var(--space-5);
  border: var(--hairline) solid var(--ink);
  background: transparent;
  color: var(--ink);
  text-decoration: none;
  font-family: var(--font-label);
  font-size: var(--size-small);
  font-weight: var(--weight-medium);
  letter-spacing: var(--tracking-button);
  text-transform: var(--transform-label);
  transition: background-color var(--transition), color var(--transition);
}
:lang(ar) .btn-outline { letter-spacing: 0; text-transform: none; }
.btn-outline:hover { background-color: var(--ink); color: var(--ink-invert); }

/* --- Photographs ---------------------------------------------------------
   Paper and ink: a hairline, no radius beyond a hair, no card. */
.framed {
  border: var(--hairline) solid var(--rule-hairline);
  background-color: var(--surface-alt);
}

/* ==========================================================================
   Instagram — click-to-load cards
   ========================================================================== */
.media-grid {
  display: grid;
  gap: var(--space-m);
  grid-template-columns: repeat(auto-fit, minmax(min(16rem, 100%), 1fr));
  margin-block-start: var(--space-l);
}
.embed-card {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: var(--space-m);
  min-block-size: 11rem;
  padding: var(--space-m);
  border: var(--hairline) solid var(--rule-soft);
  text-decoration: none;
  color: inherit;
  background-color: var(--surface);
  transition: border-color var(--transition);
}
.embed-card:hover { border-color: var(--rule); }
.embed-card__kind {
  font-family: var(--font-label);
  font-size: var(--step--1);
  font-weight: var(--weight-medium);
  letter-spacing: var(--tracking-label);
  text-transform: var(--transform-label);
  color: var(--ink-secondary);
  margin-inline-end: calc(var(--tracking-label) * -1);
}
.embed-card__title {
  font-family: var(--font-heading);
  font-size: var(--step-1);
  line-height: var(--leading-tight);
}
.embed-card__cue {
  font-family: var(--family-support);
  font-size: var(--step--1);
  color: var(--ink-secondary);
  display: flex;
  align-items: center;
  gap: var(--space-2xs);
}
.embed-card__cue::before {
  content: "";
  inline-size: 0.9rem;
  block-size: 0.9rem;
  flex: none;
  background-color: currentColor;
  /* play triangle */
  clip-path: polygon(15% 5%, 15% 95%, 92% 50%);
}
/* The player is sized here, not by Instagram. Their embed sizes itself by
   postMessage and silently leaves a 2px-tall iframe when that does not
   complete. A fixed frame with the iframe filling it cannot fail that way. */
.embed__frame {
  display: block;
  position: relative;
  inline-size: 100%;
  /* clamp, not min(): min() collapses to nothing wherever the viewport
     height resolves to 0, and a player that is present but invisible is the
     bug this whole block exists to prevent. */
  block-size: clamp(26rem, 78vh, 40rem);
  background-color: var(--surface-alt);
  border: var(--hairline) solid var(--rule-soft);
}
.embed__frame iframe {
  inline-size: 100%;
  block-size: 100%;
  border: 0;
  display: block;
}
.videos .embed__frame { grid-column: 1 / -1; }
.article .embed__frame { margin-block-start: var(--space-m); }
.embed-note {
  font-size: var(--step--1);
  color: var(--ink-secondary);
  margin-block-start: var(--space-s);
}

/* ==========================================================================
   Booking + locations
   ========================================================================== */
/* --- A10 · The booking block --------------------------------------------
   Repeated at the foot of every page above the footer. Espresso ground, the
   mirror rule, the heading, the one instruction about naming the city, then
   the site's only filled button. */
.booking {
  background: var(--band-invert);
  color: var(--ink-invert);
  padding-block: var(--space-9);
  text-align: center;
}
.booking .mirror { justify-content: center; color: var(--ink-invert-secondary); }
.booking__heading {
  font-size: var(--size-h1);
  line-height: var(--leading-h1);
  margin-block-start: var(--space-6);
}
.booking p {
  color: var(--ink-invert-secondary);
  max-inline-size: 46ch;
  margin-inline: auto;
  margin-block-start: var(--space-4);
}

/* A kicker inside a dark band. Taupe on espresso is 6.20:1 — it is a valid
   ink role here, and only here. */
.booking .kicker,
.voice-band .kicker,
.section--invert .kicker { color: var(--ink-invert-secondary); }
.booking .kicker__dash,
.section--invert .kicker__dash { color: var(--ink-invert-secondary); }
.booking .kicker__rule,
.section--invert .kicker__rule {
  background: linear-gradient(to left, transparent, rgba(244, 240, 233, 0.28));
}
[dir="ltr"] .booking .kicker__rule,
[dir="ltr"] .section--invert .kicker__rule {
  background: linear-gradient(to right, transparent, rgba(244, 240, 233, 0.28));
}
.booking .kicker { justify-content: center; }
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  /* Stack on narrow screens: side by side, the label and the number together
     overflow 375px and the number breaks mid-digits, which reads as a typo. */
  flex-wrap: wrap;
  gap: var(--space-3xs) var(--space-2xs);
  max-inline-size: 100%;
  margin-block-start: var(--space-m);
  padding: var(--space-xs) var(--space-l);
  font-family: var(--font-label);
  font-size: var(--step-0);
  font-weight: var(--weight-medium);
  letter-spacing: var(--tracking-label);
  text-transform: var(--transform-label);
  text-decoration: none;
  background-color: var(--ink-invert);
  color: var(--surface-invert);
  border: var(--hairline) solid var(--ink-invert);
  transition: background-color var(--transition), color var(--transition);
}
.btn:hover { background-color: transparent; color: var(--ink-invert); }
.btn--light {
  background-color: var(--ink);
  color: var(--surface);
  border-color: var(--ink);
}
.btn--light:hover { background-color: transparent; color: var(--ink); }
.btn__number {
  font-family: var(--family-support);
  letter-spacing: 0.04em;
  text-transform: none;
  direction: ltr;
  unicode-bidi: isolate;
  /* A phone number must never break across lines. */
  white-space: nowrap;
}

.locations {
  display: grid;
  gap: var(--space-l);
  grid-template-columns: repeat(auto-fit, minmax(min(20rem, 100%), 1fr));
  margin-block-start: var(--space-l);
}
.location { border: var(--hairline) solid var(--rule-soft); }
.location__body { padding: var(--space-m); }
.location__city {
  font-family: var(--font-label);
  font-size: var(--step--1);
  font-weight: var(--weight-medium);
  letter-spacing: var(--tracking-label);
  text-transform: var(--transform-label);
  color: var(--ink-secondary);
  margin-inline-end: calc(var(--tracking-label) * -1);
}
.location__name { font-family: var(--font-heading); font-size: var(--step-2); margin-block-start: var(--space-3xs); }
.location__addr { color: var(--ink-secondary); font-size: var(--step--1); margin-block-start: var(--space-2xs); }
.location__links { display: flex; flex-wrap: wrap; gap: var(--space-s); margin-block-start: var(--space-s); }
.location__links a {
  font-family: var(--font-label);
  font-size: var(--step--1);
  letter-spacing: var(--tracking-label);
  text-transform: var(--transform-label);
  color: var(--ink);
  text-decoration: none;
  border-block-end: var(--hairline) solid var(--rule);
  padding-block-end: 2px;
}
.location__links a:hover { border-block-end-color: var(--ink); }

/* The map frame. Was a click-to-load placeholder; now the live embed, at the
   owner's instruction. The aspect-ratio is what reserves the space before the
   lazy iframe arrives, so nothing below it jumps when it does. */
.map {
  display: block;
  position: relative;
  aspect-ratio: 16 / 9;
  background-color: var(--surface-alt);
  border-block-end: var(--hairline) solid var(--rule-soft);
}
.map iframe { inline-size: 100%; block-size: 100%; border: 0; display: block; }

/* ==========================================================================
   Video grid — portrait cards linking out to Instagram
   ========================================================================== */
/* ==========================================================================
   Video cards — 1:1 transplant of the drbokhary.com implementation
   (theme css/components.css §VideoCard), rebuilt from scratch 2026-08-25.
   Geometry, class names and the is-embedded release are theirs verbatim;
   only colors and the stage pattern come from Samar's tokens.
   ========================================================================== */
.videos-page__grid {
  display: grid;
  /* 330px minimum: Instagram's embed has an inline min-width of 326px, so
     anything narrower forces it to overflow and be clipped. This also gives
     the reel more room, which is what makes it render larger. */
  grid-template-columns: repeat(auto-fill, minmax(min(330px, 100%), 1fr));
  gap: var(--space-m);
  margin-block-start: var(--space-l);
}
.videos-page__foot {
  display: grid;
  gap: var(--space-m);
  border-block-start: var(--hairline) solid var(--rule-soft);
  padding-block-start: var(--space-l);
  margin-block-start: var(--space-xl);
}

.video-card {
  display: flex;
  flex-direction: column;
  gap: var(--space-s);
  padding: var(--space-s);
  background-color: var(--surface);
  border: var(--hairline) solid var(--rule-soft);
  transition: border-color var(--transition);
}
.video-card:hover { border-color: var(--rule); }

.video-card__stage {
  /* A <button> now — reset the UA styling before our own applies. */
  appearance: none;
  -webkit-appearance: none;
  padding: 0;
  font: inherit;
  color: inherit;
  cursor: pointer;
  inline-size: 100%;
  position: relative;
  aspect-ratio: 9 / 16;
  display: grid;
  place-items: center;
  overflow: hidden;
  /* Her diamond motif stands in for the reference's pale-lines SVG. */
  background:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 240 240'%3E%3Cg stroke='%23A79B8A' stroke-width='1'%3E%3Cline x1='48' y1='120' x2='96' y2='120'/%3E%3Cline x1='144' y1='120' x2='192' y2='120'/%3E%3C/g%3E%3Crect x='120' y='109' width='15.6' height='15.6' transform='rotate(45 120 109)' fill='%23211C16'/%3E%3C/svg%3E")
    no-repeat center / 42%,
    var(--surface-alt);
}
/* The reference's three declarations, plus the width handling its own
   layout does not need. Instagram writes an inline `min-width: 326px` onto
   its iframe. Our card is ~335px on a phone and carries padding, leaving
   about 303px inside — so the embed overflowed and `overflow: hidden`
   cropped its header, footer and action row. Cancelling the inline
   min-width and letting the player span the card's full width (negating the
   padding) makes it sit correctly instead of clipped. */
.video-card__stage.is-embedded {
  aspect-ratio: auto;
  background: none;
  display: block;
  overflow: visible;
  cursor: default;
  border: 0;
  margin-inline: calc(var(--space-s) * -1);
  margin-block-end: calc(var(--space-s) * -1);
}
/* Instagram letterboxes a 9:16 reel inside its own media box, which is why
   black bars appear either side. That box is cross-origin — its internals
   cannot be styled from here. What we CAN do is stop constraining the
   player: give the embed the full card width and let its natural height
   stand, so the video renders as large as Instagram will draw it.
   The bars are Instagram's own rendering; a self-hosted MP4
   (src/videos/<REEL_ID>.mp4) removes them completely — see B53. */
.video-card:has(.is-embedded) { padding: var(--space-s); }
.video-card:has(.is-embedded) .video-card__title { margin-block-start: var(--space-s); }
.video-card__stage.is-embedded iframe,
.video-card__stage.is-embedded blockquote {
  min-inline-size: 0 !important;
  inline-size: 100% !important;
  margin: 0 !important;
}

.video-card__cover {
  position: absolute;
  inset: 0;
  inline-size: 100%;
  block-size: 100%;
  object-fit: cover;
  transition: transform 0.55s cubic-bezier(0.22, 1, 0.36, 1);
}
.video-card:hover .video-card__cover { transform: scale(1.045); }

.video-card__play {
  position: relative;
  z-index: 1;
  display: grid;
  place-items: center;
  inline-size: 4rem;
  block-size: 4rem;
  border-radius: 50%;
  background: rgb(244 240 233 / 0.9);
  color: var(--ink);
}

.video-card__title {
  font-family: var(--font-body);
  font-size: var(--step-0);
  font-weight: var(--weight-strong);
  line-height: var(--leading-body);
  color: var(--ink);
}

.video-card__actions {
  margin-block-start: auto;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2xs) var(--space-s);
}
.video-card__load {
  padding: 0.6em 1.1em;
  font-family: var(--font-label);
  font-size: var(--step--1);
  font-weight: var(--weight-medium);
  letter-spacing: var(--tracking-label);
  text-transform: var(--transform-label);
  color: var(--ink);
  background: transparent;
  border: var(--hairline) solid var(--rule);
  cursor: pointer;
  transition: background-color var(--transition), color var(--transition);
}
.video-card__load:hover { background-color: var(--ink); color: var(--surface); }
.video-card__ig {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3xs);
  font-family: var(--family-support);
  font-size: var(--step--1);
  font-weight: var(--weight-medium);
  color: var(--ink-secondary);
  text-decoration: none;
}
.video-card__ig:hover { color: var(--ink); }
.video-card__ig svg { flex: none; }

.embed-note {
  font-size: var(--step--1);
  color: var(--ink-secondary);
  margin-block-start: var(--space-m);
}

/* Masthead WhatsApp button */
.masthead__actions { display: flex; align-items: center; gap: var(--space-s); }
.wa-btn {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3xs);
  padding: var(--space-3xs) var(--space-2xs);
  font-family: var(--font-label);
  font-size: var(--step--1);
  font-weight: var(--weight-medium);
  letter-spacing: var(--tracking-label);
  text-transform: var(--transform-label);
  text-decoration: none;
  color: var(--ink);
  border: var(--hairline) solid var(--rule);
  white-space: nowrap;
  transition: background-color var(--transition), color var(--transition);
}
.wa-btn:hover { background-color: var(--ink); color: var(--surface); }
.wa-btn svg { inline-size: 0.95em; block-size: 0.95em; fill: currentColor; flex: none; }
@media (max-width: 26rem) {
  .wa-btn__label { position: absolute; inline-size: 1px; block-size: 1px; overflow: hidden; clip-path: inset(50%); }
  .wa-btn { padding: var(--space-2xs); }
}

/* ==========================================================================
   Mobile navigation
   Six nav items wrapped to three rows on a phone, giving a 161px masthead
   that ate a fifth of the viewport on every page. Collapsed behind a toggle
   below the breakpoint, as the reference practice site does.
   ========================================================================== */
.masthead__toggle {
  display: none;
  align-items: center;
  justify-content: center;
  inline-size: 2.4rem;
  block-size: 2.4rem;
  padding: 0;
  background: none;
  border: var(--hairline) solid var(--rule);
  cursor: pointer;
  color: var(--ink);
}
.masthead__toggle-line {
  display: block;
  inline-size: 1rem;
  block-size: 1px;
  background-color: currentColor;
  transition: transform var(--transition), opacity var(--transition);
}
.masthead__toggle-line + .masthead__toggle-line { margin-block-start: 4px; }
.masthead__toggle[aria-expanded="true"] .masthead__toggle-line:nth-child(1) { transform: translateY(2.5px) rotate(45deg); }
.masthead__toggle[aria-expanded="true"] .masthead__toggle-line:nth-child(2) { transform: translateY(-2.5px) rotate(-45deg); }

@media (max-width: 48rem) {
  .masthead__inner { flex-wrap: wrap; }
  .masthead__toggle { display: flex; }
  .nav {
    order: 3;
    flex-basis: 100%;
    flex-direction: column;
    align-items: flex-start;
    gap: 0;
    /* Collapsed by default only when scripting is available to reopen it —
       see the .js-nav class added by embeds.js. Without JS the nav stays
       visible rather than being unreachable. */
    display: none;
  }
  .nav--open { display: flex; }
  .nav a {
    inline-size: 100%;
    padding-block: var(--space-2xs);
    border-block-end: var(--hairline) solid var(--rule-soft);
  }
  html:not(.js) .nav { display: flex; }
  html:not(.js) .masthead__toggle { display: none; }
}

/* ==========================================================================
   Appointment form
   ========================================================================== */
.form { max-inline-size: 34rem; margin-inline: auto; text-align: start; }
.form__row { margin-block-start: var(--space-m); }
.form label {
  display: block;
  font-family: var(--font-label);
  font-size: var(--step--1);
  font-weight: var(--weight-medium);
  letter-spacing: var(--tracking-label);
  text-transform: var(--transform-label);
  color: var(--ink-secondary);
  margin-inline-end: calc(var(--tracking-label) * -1);
  margin-block-end: var(--space-3xs);
}
.form input,
.form select,
.form textarea {
  inline-size: 100%;
  font: inherit;
  font-size: var(--step-0);
  color: var(--ink);
  background-color: var(--surface);
  border: var(--hairline) solid var(--rule);
  border-radius: 0;
  padding: var(--space-2xs) var(--space-xs);
  transition: border-color var(--transition);
  -webkit-appearance: none;
  appearance: none;
}
.form select {
  /* Re-add an affordance, since appearance:none removes the native arrow.
     A chevron drawn in the ink color, flipped by [dir] via the logical
     inset property. */
  background-image: linear-gradient(45deg, transparent 50%, currentColor 50%),
                    linear-gradient(135deg, currentColor 50%, transparent 50%);
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
  padding-inline-end: var(--space-l);
}
:root:dir(ltr) .form select { background-position: right 1.15rem top 55%, right 0.85rem top 55%; }
:root:dir(rtl) .form select { background-position: left 0.85rem top 55%, left 1.15rem top 55%; }
.form textarea { min-block-size: 5rem; resize: vertical; }
.form input:focus-visible,
.form select:focus-visible,
.form textarea:focus-visible { border-color: var(--ink); }
.form__hint { font-size: var(--step--1); color: var(--ink-secondary); margin-block-start: var(--space-2xs); }
.form__actions { margin-block-start: var(--space-l); }
.form__note {
  font-size: var(--step--1);
  color: var(--ink-secondary);
  margin-block-start: var(--space-m);
  padding-inline-start: var(--space-s);
  border-inline-start: 2px solid var(--rule);
}

/* ==========================================================================
   Breadcrumbs + expanded footer
   ========================================================================== */
.crumbs { padding-block: var(--space-s); font-size: var(--step--1); }
.crumbs ol { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: var(--space-2xs); }
.crumbs li { display: flex; align-items: center; gap: var(--space-2xs); color: var(--ink-secondary); }
.crumbs li + li::before { content: "/"; color: var(--rule); }
.crumbs a { color: var(--ink-secondary); text-decoration: none; border-block-end: var(--hairline) solid transparent; }
.crumbs a:hover { color: var(--ink); border-block-end-color: var(--rule); }
.crumbs [aria-current="page"] { color: var(--ink); }

.colophon__cols {
  display: grid;
  gap: var(--space-l);
  grid-template-columns: repeat(auto-fit, minmax(min(13rem, 100%), 1fr));
  padding-block-end: var(--space-l);
}
.colophon__col h2 {
  font-family: var(--font-label);
  font-size: var(--size-kicker);
  font-weight: var(--weight-medium);
  letter-spacing: var(--tracking-label);
  text-transform: var(--transform-label);
  color: var(--ink-secondary);
  margin-inline-end: calc(var(--tracking-label) * -1);
  margin-block-end: var(--space-2xs);
}
.colophon__col ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--space-3xs); }
.colophon__col a {
  color: var(--surface-alt);       /* bone on espresso — 11.4:1 ✓ */
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  min-block-size: 2.75rem;         /* 44px hit area */
  border-block-end: var(--hairline) solid transparent;
  transition: color var(--transition), border-color var(--transition);
}
.colophon__col a:hover {
  color: var(--ink-invert);
  border-block-end-color: var(--ink-invert-secondary);
}

/* MP4 variant — the reference's spec §6.6. A native player fills the stage;
   no play badge and no embed button, because the browser supplies controls.
   This path has no Instagram dependency and cannot be blocked by an embed
   permission, a login wall, or a failed postMessage handshake. */
.video-card__stage--mp4 {
  aspect-ratio: 9 / 16;
  background: var(--surface-invert);
  display: block;
}
.video-card__mp4 {
  inline-size: 100%;
  block-size: 100%;
  object-fit: cover;
  display: block;
}


/* ==========================================================================
   §4 · Print — clinic stationery
   A patient printing a treatment page should get something that looks like it
   came from the practice, not a screenshot of a website. The palette swap
   lives in tokens.css with every other colour decision; what is here is only
   what to hide and what to keep together on a page.
   ========================================================================== */
@media print {
  body { padding-block-end: 0; }
  .masthead, .nav, .wa-bar, .wa-btn, .lang-switch, .crumbs,
  .btn, .btn-outline, .cta__link, .skip-link, .watermark,
  .video-card__stage, .map, .booking p, .section__more,
  .colophon__cols { display: none !important; }

  /* The bands lose their ground but keep their words. */
  .voice-band, .booking, .colophon {
    background: none;
    border-block-start: var(--hairline) solid var(--rule);
    padding-block: var(--space-5);
  }
  a { text-decoration: none; }
  .article, .shell { max-inline-size: none; }
  .with-margin { display: block; }
  .margin-col { display: none; }
  h1, h2, h3 { break-after: avoid; }
  .meta-strip, .steps, .location, .byline { break-inside: avoid; }
  .byline { border: var(--hairline) solid var(--rule); padding: var(--space-2) var(--space-3); }
}


/* --- §4 · Hit areas ------------------------------------------------------
   Every interactive element clears 44px. These three were short: the skip
   link by a single pixel, the header WhatsApp button, and the breadcrumb
   links, which are small type and easy to miss on a phone. The padding is
   inline-block so none of them gains visual weight in exchange. */
.skip-link { min-block-size: 2.75rem; display: inline-flex; align-items: center; }
.masthead .wa-btn { min-block-size: 2.75rem; }
.crumbs a, .crumbs span {
  display: inline-flex;
  align-items: center;
  min-block-size: 2.75rem;
}
.margin-col a, .aliases a {
  display: inline-flex;
  align-items: center;
  min-block-size: 2.75rem;
}
