/* ==========================================================================
   Components — buttons, header, nav, footer, modal, forms, action bar.
   ========================================================================== */

/* --- Buttons --------------------------------------------------------------
 * The primary is gold-on-navy, which measures 8.9:1. Gold as a *surface* with
 * dark ink on it is the only way this brand's gold is legible at button size. */

.btn {
  --btn-bg: var(--gold);
  --btn-ink: oklch(0.148 0.058 264);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.6em;
  min-height: 3rem;
  padding: 0.85rem 1.6rem;
  font-family: var(--font-text);
  font-size: var(--t-small);
  font-weight: 600;
  letter-spacing: 0.01em;
  text-decoration: none;
  color: var(--btn-ink);
  background: var(--btn-bg);
  border: 1px solid transparent;
  border-radius: var(--radius-md);
  position: relative;
  isolation: isolate;
  overflow: hidden;
  transition: transform var(--dur-fast) var(--ease-out),
              box-shadow var(--dur-mid) var(--ease-out),
              background-color var(--dur-fast) var(--ease-out),
              color var(--dur-fast) var(--ease-out),
              border-color var(--dur-fast) var(--ease-out);
}

/* Gold leaf sweeping across the face on hover — light crossing the material. */
.btn::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(105deg,
    transparent 20%,
    color-mix(in oklch, var(--gold-bright) 85%, transparent) 45%,
    transparent 70%);
  transform: translateX(-110%);
  transition: transform var(--dur-slow) var(--ease-out);
}
.btn:hover::before, .btn:focus-visible::before { transform: translateX(110%); }

.btn:hover { transform: translateY(-2px); box-shadow: var(--glow-gold); }
.btn:active { transform: translateY(0); }

.btn--ghost {
  --btn-bg: transparent;
  --btn-ink: var(--ink);
  border-color: var(--rule-strong);
}
.btn--ghost:hover {
  border-color: var(--gold);
  color: var(--gold-ink);
  box-shadow: none;
}
.btn--ghost::before { display: none; }

.btn--quiet {
  --btn-bg: transparent;
  --btn-ink: var(--ink);
  min-height: auto;
  /*
   * Horizontal padding, negatively margined back out.
   *
   * At `padding: 0.35rem 0` the hit area was the width of the glyphs and nothing else —
   * detector-confirmed on all eight instances. The quiet button is the site's tertiary
   * action and it is the one a thumb is least accurate about. The negative margin keeps it
   * optically flush with whatever it sits under, so the target grows without the alignment
   * shifting.
   */
  padding: 0.5rem 0.6rem;
  margin-inline: -0.6rem;
  border-radius: var(--radius-sm);
}
.btn--quiet::before { display: none; }
.btn--quiet:hover { transform: none; box-shadow: none; color: var(--gold-ink); }

.btn--lg { min-height: 3.5rem; padding: 1.05rem 2.1rem; font-size: var(--t-body); }
.btn--block { width: 100%; }

/* Arrow that steps forward on hover. */
.btn__arrow { transition: transform var(--dur-mid) var(--ease-out); }
.btn:hover .btn__arrow { transform: translateX(0.25rem); }

/* --- The sparkle, lifted from the wordmark ------------------------------- */

.sparkle {
  display: inline-block;
  width: 1em;
  height: 1em;
  background: currentColor;
  clip-path: polygon(50% 0, 58% 42%, 100% 50%, 58% 58%, 50% 100%, 42% 58%, 0 50%, 42% 42%);
  flex: none;
}

/* --- Header --------------------------------------------------------------- */

.header {
  position: fixed;
  inset-block-start: 0;
  inset-inline: 0;
  z-index: var(--z-nav);
  transition: transform var(--dur-mid) var(--ease-out),
              background-color var(--dur-mid) var(--ease-out),
              border-color var(--dur-mid) var(--ease-out);
  border-block-end: 1px solid transparent;
}
.header__inner {
  display: flex;
  align-items: center;
  gap: var(--s-md);
  min-height: var(--header-h);
}

/*
 * Solid once scrolled, and always solid on inner pages, so the logo never sits on top of a
 * photograph it cannot be read against.
 *
 * NAVY, always — not `var(--bg)`.
 *
 * `--bg` resolves from the <body> ground, and three templates carry `t-light`: the services
 * archive, the doctors page and the blog. On those the header painted itself near-white and
 * then sat directly on top of a `masthead--navy`, so the top of the page was a hard white
 * band butted against a dark one. It looked like a rendering fault, and it was the same
 * defect on every t-light template.
 *
 * What is underneath the header is never the body ground — it is the masthead, and every
 * masthead on this site is navy. So the chrome is navy on every page, and the header
 * restates the dark token set below rather than inheriting whichever ground the template
 * happens to use.
 */
.header.is-stuck,
body:not(.home) .header {
  background: color-mix(in oklch, oklch(0.148 0.058 264) 92%, transparent);
  backdrop-filter: blur(14px) saturate(140%);
  border-block-end-color: var(--edge-dim);
}

/*
 * The header is its own ground.
 *
 * Without this the nav links inherit `--ink` from a `t-light` body — near-black type on a
 * navy bar. Restating the set is the same rule the ground modifiers follow in tokens.css:
 * a surface that sets its own background is authoritative about its own foreground.
 */
.header {
  /*
   * The SURFACES too, not only the ink.
   *
   * Declaring white ink and stopping there broke the dropdown: `.nav__sub` paints itself
   * from `--bg-raised`, which still resolved from the <body>, so on the three t-light
   * templates the panel came out near-white with the header's white type on it — measured
   * 1.56:1, caught by the guard on services, doctors and blog. A surface that claims its
   * own foreground has to claim its own background in the same breath, which is the rule
   * the ground modifiers in tokens.css already follow.
   */
  --bg:          oklch(0.148 0.058 264);
  --bg-raised:   oklch(0.212 0.084 264);
  --bg-raised-2: oklch(0.272 0.088 263);
  --ink:         oklch(0.984 0.005 250);
  --ink-soft:    oklch(0.820 0.032 250);
  --gold-ink:    oklch(0.860 0.100 90);
  --edge-dim:    oklch(0.360 0.055 85);
  --rule:        oklch(0.360 0.070 262);
  color: var(--ink);
}
.header.is-hidden { transform: translateY(-100%); }

.header__brand {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  text-decoration: none;
  flex: none;
  margin-inline-end: auto;
}
.header__logo { width: auto; height: 2.35rem; }
@media (min-width: 64rem) { .header__logo { height: 2.7rem; } }

/* Two logotypes ship and exactly one is ever shown. The header bar is navy on every page
   now — see the note above — so it is always the white one. The navy wordmark stays in the
   theme because the footer and the print stylesheet still need it. */
.header__logo--dark { display: none; }

/* --- Primary nav ---------------------------------------------------------- */

/*
 * The desktop nav turns on at 72rem, not 64rem.
 *
 * Measured: seven nav items plus the phone plus the booking button need ~1345px of a
 * ~1200px row at 1280px wide. Nothing in the row shrinks (nav links are nowrap, the brand
 * is flex:none), so the overflow fell off the right edge of the viewport and CLIPPED the
 * "Request an appointment" button — the site's primary conversion element — on every page
 * at every common desktop width. At 1024px, 417px of the row was off-screen.
 *
 * Three changes together fix it: shorter nav labels (~190px), an icon-only phone below
 * 90rem (~153px), and this breakpoint. Even with the first two, 1024px still overflowed by
 * 78px, so below 72rem the hamburger takes over.
 */
.nav { display: none; }
@media (min-width: 72rem) { .nav { display: block; } }

.nav__list { display: flex; align-items: center; gap: clamp(0.5rem, 1.4vw, 1.5rem); }

.nav__link {
  display: inline-flex;
  align-items: center;
  gap: 0.4em;
  padding: 0.6rem 0.35rem;
  font-size: var(--t-small);
  font-weight: 500;
  text-decoration: none;
  color: var(--ink);
  position: relative;
  white-space: nowrap;
}
.nav__link::after {
  content: "";
  position: absolute;
  inset-inline: 0.35rem;
  inset-block-end: 0.15rem;
  height: 1px;
  background: var(--gold);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--dur-mid) var(--ease-out);
}
.nav__link:hover::after,
.nav__item:focus-within .nav__link::after { transform: scaleX(1); }

.nav__item--current > .nav__link { color: var(--gold-ink); }
.nav__item--current > .nav__link::after { transform: scaleX(1); }

.nav__caret { width: 0.55em; height: 0.55em; opacity: 0.6; transition: transform var(--dur-fast) var(--ease-out); }
.nav__item:hover .nav__caret { transform: rotate(180deg); }

/* Submenu. Uses position:absolute inside a non-clipping header, so it is not
   at risk of being cut off by an overflow ancestor. */
.nav__sub {
  position: absolute;
  inset-block-start: calc(100% - 0.4rem);
  inset-inline-start: -0.75rem;
  min-width: 15rem;
  padding: 0.5rem;
  background: var(--bg-raised);
  border: 1px solid var(--rule);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-deep);
  opacity: 0;
  visibility: hidden;
  transform: translateY(-0.4rem);
  transition: opacity var(--dur-mid) var(--ease-out),
              transform var(--dur-mid) var(--ease-out),
              visibility var(--dur-mid);
}
.nav__item { position: relative; }
.nav__item:hover > .nav__sub,
.nav__item:focus-within > .nav__sub {
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
}
.nav__sub a {
  display: block;
  padding: 0.6rem 0.75rem;
  font-size: var(--t-small);
  text-decoration: none;
  border-radius: var(--radius-sm);
  color: var(--ink-soft);
  transition: background-color var(--dur-fast) var(--ease-out),
              color var(--dur-fast) var(--ease-out);
}
.nav__sub a:hover { background: var(--bg-raised-2); color: var(--ink); }

.header__actions { display: none; align-items: center; gap: var(--s-sm); flex: none; }
@media (min-width: 72rem) { .header__actions { display: flex; } }

.header__phone {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.45em;
  min-width: 2.75rem;
  min-height: 2.75rem;
  font-size: var(--t-small);
  font-weight: 600;
  text-decoration: none;
  white-space: nowrap;
}

/*
 * Between 72rem and 90rem the number itself is dropped and the handset icon carries the
 * link — it is worth ~153px, which is the difference between the booking button fitting
 * and being clipped off-screen at 1152–1366px. The <a> keeps its tel: href, its 44px
 * target and an aria-label with the number, so nothing is lost to a screen reader.
 */
@media (max-width: 89.99rem) {
  .header__phone [data-partial="phone"] { display: none; }
}

/* --- Mobile menu ---------------------------------------------------------- */

.menu-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.75rem;
  height: 2.75rem;
  margin-inline-end: -0.5rem;
  border-radius: var(--radius-md);
  color: var(--ink);
}
@media (min-width: 72rem) { .menu-toggle { display: none; } }

.menu-toggle__bar {
  display: block;
  width: 1.35rem;
  height: 1.5px;
  background: currentColor;
  transition: transform var(--dur-mid) var(--ease-out),
              opacity var(--dur-fast) var(--ease-out);
}
.menu-toggle__bar + .menu-toggle__bar { margin-block-start: 0.32rem; }
[aria-expanded="true"] .menu-toggle__bar:nth-child(1) { transform: translateY(0.47rem) rotate(45deg); }
[aria-expanded="true"] .menu-toggle__bar:nth-child(2) { opacity: 0; }
[aria-expanded="true"] .menu-toggle__bar:nth-child(3) { transform: translateY(-0.47rem) rotate(-45deg); }

.mobile-menu {
  position: fixed;
  inset: 0;
  z-index: var(--z-backdrop);
  background: var(--bg);
  padding: calc(var(--header-h) + var(--s-lg)) var(--gutter) var(--s-2xl);
  overflow-y: auto;
  overscroll-behavior: contain;
  display: flex;
  flex-direction: column;
  gap: var(--s-lg);
}
.mobile-menu[hidden] { display: none; }

/*
 * The no-JavaScript floor.
 *
 * `hidden` is removed by nav.js and by nothing else, so without scripting the panel could
 * never open and the site had no navigation at all below 72rem. `:target` opens it in pure
 * CSS: the toggle is an anchor pointing here, and the close control points at #main, which
 * untargets it. Scoped to `html:not(.js)` so the scripted path keeps sole control of the
 * `hidden` attribute and a stale hash cannot fight it.
 */
html:not(.js) .mobile-menu[hidden]:target { display: flex; }
/* A leftover #da-mobile-menu hash must not open a full-screen panel on a desktop that has
   the real nav visible. */
@media (min-width: 72rem) {
  html:not(.js) .mobile-menu[hidden]:target { display: none; }
}

/*
 * The way out, placed where the hamburger is so the same spot closes what it opened.
 * The panel covers the header, so this is the only exit a touch user has.
 */
.mobile-menu__close {
  /* `fixed`, not `absolute`: the panel scrolls (`overflow-y: auto`), and an absolutely
     positioned child scrolls away with it — an exit you have to scroll back up to find is
     the same defect one step smaller. The panel's z-index makes this its own stacking
     context, so a fixed child still sits inside it and above the list. */
  position: fixed;
  inset-block-start: calc((var(--header-h) - 2.75rem) / 2);
  inset-inline-end: calc(var(--gutter) - 0.5rem);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.75rem;
  height: 2.75rem;
  border-radius: var(--radius-md);
  color: var(--ink);
  transition: color var(--dur-fast) var(--ease-out),
              background-color var(--dur-fast) var(--ease-out);
}
.mobile-menu__close:hover,
.mobile-menu__close:focus-visible {
  color: var(--gold-ink);
  background: var(--bg-raised);
}

.mobile-menu a { text-decoration: none; }

/*
 * These rules used to be written against `.mobile-menu__link` and `.mobile-menu__sub`, and
 * BOTH selectors matched zero elements. The panel calls `wp_nav_menu()` without
 * `DA_Nav_Walker`, so what actually ships is core's default markup — `li.menu-item > a` and
 * `ul.sub-menu`. The designed treatment, 1.5rem display type for a top-level destination
 * against small indented sans for its children, had never once rendered: all seventeen
 * links came out identical 16px/400 sans at zero indent, parents indistinguishable from
 * their own sub-items, which is exactly what the critique read as a flat 17-item wall.
 *
 * Written against the structure that ships. A walker would work too, but this cannot fall
 * out of sync with one.
 */
.mobile-menu__list > li > a {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-sm);
  padding: 0.9rem 0;
  font-family: var(--font-display);
  font-size: 1.5rem;
  border-block-end: 1px solid var(--rule);
}

/* A parent with children owns the group below it, so its own rule closes under the group
   rather than between the parent and its first child. */
.mobile-menu__list > li.menu-item-has-children > a { border-block-end: 0; }

.mobile-menu__list .sub-menu {
  padding-block: 0.15rem 0.7rem;
  border-block-end: 1px solid var(--rule);
}
.mobile-menu__list .sub-menu a {
  display: block;
  padding: 0.55rem 0 0.55rem 1rem;
  font-family: var(--font-text);
  font-size: var(--t-small);
  color: var(--ink-soft);
  /* The indent alone is a weak signal on a phone at arm's length; a hairline down the left
     of the group says "these belong to the line above" without another level of type. */
  border-inline-start: 1px solid var(--rule);
  margin-inline-start: 0.1rem;
}
.mobile-menu__list .sub-menu a:hover,
.mobile-menu__list .sub-menu a:focus-visible { color: var(--ink); }

/* --- Mobile action bar: the anxious patient's floor ----------------------- */

.action-bar {
  position: fixed;
  inset-inline: 0;
  inset-block-end: 0;
  z-index: var(--z-sticky);
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  height: var(--actionbar-h);
  background: color-mix(in oklch, var(--bg-raised) 96%, transparent);
  backdrop-filter: blur(16px);
  border-block-start: 1px solid var(--rule);
  padding-block-end: env(safe-area-inset-bottom);
}
@media (min-width: 48rem) { .action-bar { display: none; } }

.action-bar a {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.28rem;
  font-size: var(--t-micro);
  font-weight: 600;
  text-decoration: none;
  color: var(--ink);
  min-height: 44px;
}
.action-bar a + a { border-inline-start: 1px solid var(--rule); }
.action-bar a[data-primary] { color: var(--gold-ink); }
.action-bar svg { width: 1.15rem; height: 1.15rem; }

/* --- Footer --------------------------------------------------------------- */

/* The footer is always the navy world, whatever surface the page above it used. It is the
   base of the drench, and it keeps the NAP block reading identically on every template. */
.footer {
  background: oklch(0.148 0.058 264);
  padding-block: var(--s-2xl) var(--s-lg);

  --ink: oklch(0.984 0.005 250);
  --ink-soft: oklch(0.820 0.032 250);
  --rule: oklch(0.360 0.070 262);
  --gold-ink: oklch(0.860 0.100 90);
  color: var(--ink);
}
.footer__brand img { width: auto; max-height: 3.25rem; }
.footer__tagline {
  margin-block-start: var(--s-sm);
  font-family: var(--font-display);
  font-size: 1.15rem;
  color: var(--gold-ink);
}
.footer__address { font-style: normal; font-size: var(--t-small); color: var(--ink-soft); margin-block-end: var(--s-sm); }
.footer__hours li { display: flex; justify-content: space-between; gap: var(--s-sm); }
.footer__hours span:last-child { color: var(--ink-soft); }
.footer__legal { display: flex; flex-wrap: wrap; gap: var(--s-md); }
.footer__col--brand { display: flex; flex-direction: column; gap: var(--s-sm); align-items: flex-start; }
.footer a { text-decoration: none; color: var(--ink-soft); }
.footer a:hover { color: var(--ink); }

.footer__grid {
  display: grid;
  gap: var(--s-xl);
  grid-template-columns: repeat(auto-fit, minmax(min(15rem, 100%), 1fr));
}
.footer__title {
  font-family: var(--font-text);
  font-size: var(--t-small);
  font-weight: 600;
  color: var(--ink);
  margin-block-end: var(--s-sm);
}
.footer__list { display: flex; flex-direction: column; gap: 0.35rem; font-size: var(--t-small); }
/*
 * A footer list is navigation, not prose, so its links owe the 44px floor — and short ones
 * were failing it on width alone ("Blog" measured 31x44). `inline-flex` with vertical
 * padding and a min-height gives every entry a real target without changing the rhythm;
 * the reduced gap above pays for the padding so the column height is unchanged.
 */
.footer__list a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding-block: 0.25rem;
  /*
   * Horizontal padding pulled back out by an equal negative margin, so a short label gets a
   * real target without the column losing its left alignment. "Blog" measured 31px wide —
   * which passes WCAG 2.2 SC 2.5.8 at 24x24 and only misses the 44px AAA figure, but it is
   * a one-word link stacked among longer ones, which is the arrangement most likely to
   * catch the wrong row.
   */
  padding-inline: 0.5rem;
  margin-inline: -0.5rem;
}
/* The hours list is a table of facts, not links — it keeps the tighter setting. */
.footer__hours li { min-height: 0; }

.footer__bottom {
  margin-block-start: var(--s-xl);
  padding-block-start: var(--s-md);
  border-block-start: 1px solid var(--rule);
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-sm) var(--s-md);
  align-items: center;
  justify-content: space-between;
  font-size: var(--t-micro);
  color: var(--ink-soft);
}

.social { display: flex; gap: 0.6rem; }
.social a {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  /* 2.75rem = 44px. At 2.5rem these measured 40x44 and were two of the three tap targets
     on the site under the floor — in the footer, where a thumb is least accurate. */
  width: 2.75rem;
  height: 2.75rem;
  border: 1px solid var(--rule);
  border-radius: var(--radius-md);
  transition: border-color var(--dur-fast) var(--ease-out),
              color var(--dur-fast) var(--ease-out);
}
.social a:hover { border-color: var(--gold); color: var(--gold-ink); }
.social svg { width: 1.1rem; height: 1.1rem; }

/* --- Booking modal --------------------------------------------------------
 * Native <dialog>: escapes every stacking context, gets focus trapping and
 * Escape handling from the platform rather than from us.                    */

.booking-modal {
  /* The reset's `* { margin: 0 }` also zeroes the `margin: auto` the UA stylesheet uses to
     centre a modal dialog, which pinned this to the top-left corner with a collapsed body.
     Restoring it here is the whole fix. */
  margin: auto;

  width: min(34rem, calc(100vw - 2rem));
  max-height: min(46rem, calc(100svh - 2rem));
  padding: 0;
  border: 1px solid var(--rule);
  border-radius: var(--radius-md);
  background: var(--bg-raised);
  color: var(--ink);
  box-shadow: var(--shadow-deep);
  overflow: hidden;
  transition: width var(--dur-mid) var(--ease-out);
}
/* The form needs more room than the two-office question does. */
.booking-modal.is-form { width: min(38rem, calc(100vw - 2rem)); }

/* --- Step one: choose an office ------------------------------------------- */

.booking-step__lead {
  margin-block-end: var(--s-md);
  color: var(--ink-soft);
  font-size: var(--t-small);
}

.booking-choices { display: flex; flex-direction: column; gap: 0.6rem; }

.booking-choice {
  text-decoration: none;
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  gap: 0.25rem var(--s-sm);
  width: 100%;
  padding: var(--s-md);
  text-align: start;
  background: var(--bg-raised-2);
  border: 1px solid var(--rule);
  border-radius: var(--radius-md);
  color: var(--ink);
  transition: border-color var(--dur-fast) var(--ease-out),
              background-color var(--dur-fast) var(--ease-out),
              transform var(--dur-fast) var(--ease-out);
}
.booking-choice:hover {
  border-color: var(--gold);
  transform: translateY(-1px);
}
.booking-choice__name {
  font-family: var(--font-display);
  font-size: var(--t-h4);
  grid-column: 1;
}
.booking-choice__addr {
  grid-column: 1;
  font-size: var(--t-small);
  color: var(--ink-soft);
  line-height: 1.45;
}
.booking-choice__go {
  grid-column: 2;
  grid-row: 1 / span 2;
  color: var(--gold);
  transition: transform var(--dur-mid) var(--ease-out);
}
.booking-choice:hover .booking-choice__go { transform: translateX(0.25rem); }

.booking-step__alt {
  margin-block-start: var(--s-md);
  padding-block-start: var(--s-md);
  border-block-start: 1px solid var(--rule);
  font-size: var(--t-small);
  color: var(--ink-soft);
}
.booking-step__alt a { color: var(--gold-ink); font-weight: 600; }

/* --- Step two: the form ---------------------------------------------------- */

.booking-step__back {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--s-sm);
  margin-block-end: var(--s-sm);
  font-size: var(--t-small);
}
.booking-step__chosen { color: var(--gold-ink); font-weight: 600; }
.booking-modal::backdrop {
  background: oklch(0.10 0.05 264 / 0.72);
  backdrop-filter: blur(6px);
}
.booking-modal__head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--s-md);
  padding: var(--s-md) var(--s-md) var(--s-sm);
  border-block-end: 1px solid var(--rule);
}
.booking-modal__title { font-size: var(--t-h4); font-family: var(--font-display); }
.booking-modal__close {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.5rem;
  height: 2.5rem;
  margin: -0.4rem -0.4rem 0 0;
  border-radius: var(--radius-md);
  color: var(--ink-soft);
  flex: none;
}
.booking-modal__close:hover { color: var(--ink); background: var(--bg-raised-2); }
.booking-modal__body { padding: var(--s-sm); }
.booking-modal iframe {
  width: 100%;
  min-height: 33rem;
  border: 0;
  border-radius: var(--radius-sm);
  background: var(--bg-page);
}
.booking-modal__fallback {
  padding: var(--s-lg) var(--s-md);
  text-align: center;
  display: flex;
  flex-direction: column;
  gap: var(--s-md);
  align-items: center;
}

/* --- Accordion ------------------------------------------------------------ */

.accordion { border-block-start: 1px solid var(--rule); }
.accordion__item { border-block-end: 1px solid var(--rule); }
.accordion__trigger {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--s-md);
  width: 100%;
  padding: var(--s-md) 0;
  text-align: start;
  font-family: var(--font-display);
  font-size: var(--t-h4);
  line-height: 1.3;
  color: var(--ink);
  transition: color var(--dur-fast) var(--ease-out);
}
.accordion__trigger:hover { color: var(--gold-ink); }
.accordion__icon {
  flex: none;
  width: 1.5rem;
  height: 1.5rem;
  margin-block-start: 0.15rem;
  position: relative;
  color: var(--gold);
}
.accordion__icon::before,
.accordion__icon::after {
  content: "";
  position: absolute;
  inset-block-start: 50%;
  inset-inline-start: 50%;
  width: 0.85rem;
  height: 1.5px;
  background: currentColor;
  translate: -50% -50%;
  transition: transform var(--dur-mid) var(--ease-out), opacity var(--dur-mid) var(--ease-out);
}
.accordion__icon::after { transform: rotate(90deg); }
[aria-expanded="true"] .accordion__icon::after { transform: rotate(0deg); opacity: 0; }

.accordion__panel {
  overflow: hidden;
  color: var(--ink-soft);
}
.accordion__panel[hidden] { display: none; }
.accordion__panel > div { padding-block-end: var(--s-md); max-width: var(--measure); }

/* --- Forms ---------------------------------------------------------------- */

.field { display: flex; flex-direction: column; gap: 0.45rem; }
.field label { font-size: var(--t-small); font-weight: 600; }
.field input, .field textarea, .field select {
  width: 100%;
  padding: 0.85rem 1rem;
  background: var(--bg-raised-2);
  border: 1px solid var(--rule-strong);
  border-radius: var(--radius-md);
  color: var(--ink);
  transition: border-color var(--dur-fast) var(--ease-out),
              box-shadow var(--dur-fast) var(--ease-out);
}
.field input::placeholder, .field textarea::placeholder {
  /* Placeholders carry the same 4.5:1 obligation as body text. */
  color: var(--ink-soft);
  opacity: 1;
}
.field :is(input, textarea, select):focus-visible {
  border-color: var(--gold);
  outline-offset: 1px;
}

/* --- Badges and pills ----------------------------------------------------- */

.pill {
  display: inline-flex;
  align-items: center;
  gap: 0.45em;
  padding: 0.4rem 0.85rem;
  font-size: var(--t-micro);
  font-weight: 600;
  border: 1px solid var(--rule-strong);
  border-radius: 100px;
  color: var(--ink-soft);
  white-space: nowrap;
}
.pill--gold { border-color: color-mix(in oklch, var(--gold) 45%, transparent); color: var(--gold-ink); }
.pill .sparkle { width: 0.7em; height: 0.7em; color: var(--gold); }

/* --- Badges ---------------------------------------------------------------
 * Short factual reassurances that were previously a single muted sentence of
 * middot-separated clauses under the hero. "Se habla español" especially:
 * for a large share of this practice's patients that is the fact that decides
 * whether they call, and it was set as the tail of a line of small print.     */

.hero__badges,
.badges {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-xs);
  /* Clear air above. These sat --s-md under the buttons and read as a third row
     of controls rather than as a separate register of information. */
  margin-block-start: var(--s-lg);
}

/* --- Facet chips ----------------------------------------------------------
 * These were a bordered rectangle with a dot in it, and they looked like one.
 *
 * The old rule asked for `clip-path: var(--facet-soft)` and a 1px border
 * together, which cannot work and produced neither: `--facet-soft` is defined
 * in PERCENTAGES (3.5% / 4%), so on a 30px-tall chip the cut came out around a
 * pixel — invisible — and `clip-path` deletes a border along the diagonal
 * anyway. Two effects cancelling each other out into a plain box.
 *
 * They are now built the way `.plane` is built, at chip scale: the outer
 * element IS the gold edge, showing through a 1px padding, and the face is
 * clipped short of the same diagonal so the gold survives the corner. Same
 * construction, same cut, same brand — which is what ties them to the
 * credential plane further down the hero.
 * -------------------------------------------------------------------------- */

/*
 * --edge-lit on every chip, not --edge.
 *
 * The place badges were given the bright gold and the rest kept `--edge`, which on this
 * dark ground is oklch(0.520 …) — a mid gold. At 2px that reads on the straight sides and
 * all but vanishes along the two diagonals, where the band is the same 2px spread over a
 * 45 degree run. So two chips had visible cut corners and three appeared to have square
 * ones. The pin already separates a place from a claim; the edge does not need to.
 */
.badge {
  /*
   * 2px of frame, matching .plane, and for the same measured reason.
   *
   * At 1px these chips land at fractional positions — measured x=398.92,
   * y=617.86 — so the gold band straddles two device pixels and Chrome
   * antialiases it to roughly half strength. The edge is present in the box
   * model and absent to the eye, which is exactly what "missing edges" looks
   * like. A 2px band always covers at least one whole device pixel at any
   * ratio, so it always paints at full strength.
   */
  --chip-cut: 0.8rem;
  display: inline-flex;
  padding: 2px;
  background-color: var(--edge-lit);
  clip-path: polygon(
    0 var(--chip-cut), var(--chip-cut) 0,
    100% 0,
    100% calc(100% - var(--chip-cut)), calc(100% - var(--chip-cut)) 100%,
    0 100%);
  transition: background-color var(--dur-mid) var(--ease-out);
}

.badge__face {
  display: inline-flex;
  align-items: center;
  gap: 0.5em;
  padding: 0.5rem 0.95rem;
  font-size: var(--t-small);
  font-weight: 500;
  line-height: 1.3;
  color: var(--ink);
  /* Frosted rather than flat: the footage moves behind these, and letting a
     little of it through is what stops three chips reading as three stickers. */
  background: color-mix(in oklch, oklch(0.148 0.058 264) 76%, transparent);
  backdrop-filter: blur(10px);
  /*
   * The same `--facet-back` the cut plane uses, and for the same reason: this
   * is that construction at chip scale, so it must be that construction's
   * arithmetic. The derivation is in tokens.css.
   *
   * It was `cut − 6.85px`, which had the sign of the √2 term backwards. That
   * pushes the face 2.02px PAST the frame's own diagonal, where the frame's
   * clip-path cuts it off — so both cut corners had no gold whatsoever, while
   * all four straight sides were perfect. That is the shape the client kept
   * photographing, and it is why every previous fix aimed at the edge colour,
   * the band width and the shine missed: none of those was ever the fault.
   */
  clip-path: polygon(
    0 calc(var(--chip-cut) - var(--facet-back)), calc(var(--chip-cut) - var(--facet-back)) 0,
    100% 0,
    100% calc(100% - var(--chip-cut) + var(--facet-back)),
    calc(100% - var(--chip-cut) + var(--facet-back)) 100%,
    0 100%);
  transition: background-color var(--dur-mid) var(--ease-out);
}

/*
 * The shine.
 *
 * A narrow band of gold light travelling across the chip's own edge — not across the face,
 * which would sit over the text. It runs on the OUTER element, which is the gold layer, so
 * what moves is the edge itself catching light: the same "leaf catching the sun" idea the
 * gold rules elsewhere use, at chip scale.
 *
 * `background-size: 200%` with an animated `background-position` moves a gradient rather
 * than a box, so nothing is laid out, painted or composited beyond this element. It is the
 * cheapest way to move light there is.
 *
 * Staggered per chip so the row reads as a run of five rather than five things doing the
 * same thing at the same instant, which is the tell.
 */
.hero__badges .badge {
  background-image: linear-gradient(
    100deg,
    transparent 0%,
    transparent 38%,
    var(--gold-bright) 47%,
    oklch(1 0 0 / 0.85) 50%,
    var(--gold-bright) 53%,
    transparent 62%,
    transparent 100%);
  background-size: 220% 100%;
  background-position: 130% 0;
  animation: da-chip-shine 5.5s var(--ease-soft) infinite;
}
.hero__badges .badge:nth-child(2) { animation-delay: 0.35s; }
.hero__badges .badge:nth-child(3) { animation-delay: 0.7s; }
.hero__badges .badge:nth-child(4) { animation-delay: 1.05s; }
.hero__badges .badge:nth-child(5) { animation-delay: 1.4s; }

@keyframes da-chip-shine {
  /* Long dwell, short travel: the light crosses in half a second and then the chip is
     simply itself for five. A continuous shimmer is jewellery-shop, not dentistry. */
  0%, 82%  { background-position: 130% 0; }
  92%, 100% { background-position: -30% 0; }
}

.badge__mark {
  width: 0.7em;
  height: 0.7em;
  color: var(--gold);
  transition: transform var(--dur-slow) var(--ease-out);
}

.badge:hover { background-color: var(--gold-bright); }
.badge:hover .badge__face {
  background: color-mix(in oklch, oklch(0.212 0.084 264) 82%, transparent);
}
.badge:hover .badge__mark { transform: rotate(90deg) scale(1.2); }

/* The language chip is the one that gets the gold, because it is the one that
   decides something for the reader rather than merely informing them. Edge and
   face are both gold, so it reads as one solid cut shape. */
.badge--gold { background-color: var(--gold); }
.badge--gold .badge__face {
  background: var(--gold);
  backdrop-filter: none;
  color: oklch(0.148 0.058 264);
  font-weight: 600;
}
.badge--gold .badge__mark { color: oklch(0.148 0.058 264); }
.badge--gold:hover { background-color: var(--gold-bright); }
.badge--gold:hover .badge__face { background: var(--gold-bright); }

/*
 * A place, not a claim.
 *
 * The other three badges assert something about the practice; these two say where it is.
 * The pin is what separates the two kinds at a glance, and the gold edge is lit rather
 * than dim because "is there one near me" is the question this row answers first.
 */
.badge--place .badge__face { font-weight: 600; }
.badge__pin { flex: none; color: var(--gold); }
.badge--place:hover { background-color: var(--gold-bright); }

/* On a light ground the frosted navy fill would be a dark blot; use the
   reading surface and let the gold edge do the work. */
.section--light .badge__face,
.t-light .badge__face {
  background: var(--bg-page-2);
  backdrop-filter: none;
  color: var(--ink-dark);
}
.section--light .badge__mark,
.t-light .badge__mark { color: var(--gold-deep); }

@media (prefers-reduced-motion: reduce) {
  .badge__mark { transition: none; }
  .badge:hover .badge__mark { transform: none; }
  /* Pure decoration, so it does not run at all — and the chip keeps its solid gold edge
     because the gradient is a background IMAGE over the background COLOR, not instead. */
  .hero__badges .badge { animation: none; background-image: none; }
}
.section--light .badge--gold,
.t-light .badge--gold { background-color: var(--gold); }

@media (prefers-reduced-motion: reduce) { .badge { transition: none; } }

/* The scheduler opens in a new tab, and the modal says so in words rather than
   leaving an older visitor wondering where the page went. */
.booking-step__note {
  margin-block-start: var(--s-md);
  font-size: var(--t-small);
  line-height: 1.55;
  color: var(--ink-soft);
}


/*
 * The payer rail, optically normalised.
 *
 * Sizing every mark to the same box gives a 3.3x spread of apparent weight: measured
 * rendered widths ran Amex 38px, Mastercard 54px, Cigna 57px, Visa 93px, UnitedHealthcare
 * 96px, Principal 104px, Cherry 108px, Humana 118px, Discover 126px. A square mark is
 * bounded by its HEIGHT and a wordmark by its width, so equal boxes make the square ones
 * look like a third of the weight of the wide ones.
 *
 * So the two axes are separated: a shared height cap for the wordmarks, and a taller cap
 * for the marks that are square or nearly so, which is the correction a person makes by eye
 * when setting a logo rail by hand.
 */
.payer__logo { max-height: 1.6rem; width: auto; }
.payer__logo--american-express,
.payer__logo--mastercard,
.payer__logo--cherry { max-height: 2.15rem; }
.payer__logo--visa,
.payer__logo--discover { max-height: 1.35rem; }
