/* ==========================================================================
   Prashanth Dental Centre
   Ground: bone for reading, deep clinical navy for the hospital argument.
   Accent: theatre green, chosen because green is opposite red on the wheel
   and is what an operating theatre is actually draped in.
   Display: Newsreader (institutional serif). Interface: Archivo (signage
   grotesque, variable width axis for the department directory).
   ========================================================================== */

:root {
  /* ground */
  --bone:        #F5F2EC;
  --bone-sink:   #EDE8DF;   /* recessed panel on bone */
  --navy:        #0F2B3A;
  --navy-lift:   #16384A;   /* raised panel on navy */
  /* Round 12 (chg-ddfcf124) - the sticky action bar (call/whatsapp/book/
     location/review-us) used to share --navy with the hero directly below
     it, so the two read as one block. Its own, lighter tone so it reads as
     a separate bar on every page (6.28:1 for its on-navy labels, 3.23:1 for
     the mint icon strokes - verified, not eyeballed). */
  /* 2026-09-28 (chg-efb0d56e) - she asked for the bar to be the same on
     every page as on the homepage, and lighter so it stands apart. Labels
     go white (5.16:1) and the icons a paler mint (3.49:1, graphics need
     3:1) to keep their contrast on the lighter blue. */
  --actions-bg:  #3F7390;
  --actions-ink: #FFFFFF;
  --actions-icon: #A8E0CD;

  /* ink */
  --ink:         #12222C;
  --ink-muted:   #5A6B74;   /* 4.96:1 on bone */
  --on-navy:     #F5F2EC;   /* 13.17:1 */
  --on-navy-dim: #C9D6DD;   /* 9.91:1 */

  /* accent */
  --green:       #1F6A57;   /* 5.77:1 on bone, white on it 6.45:1 */
  --green-deep:  #17503F;
  --mint:        #6FBFA5;   /* 6.78:1 on navy */

  /* lines */
  --rule:        #D8D2C7;
  --rule-strong: #BFB7A8;
  --rule-navy:   #2C4A5C;

  /* type */
  --display: "Newsreader", Georgia, "Times New Roman", serif;
  --ui:      "Archivo", system-ui, -apple-system, "Segoe UI", sans-serif;

  /* measure + rhythm */
  --measure: 34rem;
  --gutter: clamp(1.25rem, 4vw, 3.5rem);
  --shell: 78rem;
  --band: clamp(4.5rem, 9vw, 8rem);

  --dock-h: 0px;            /* raised on mobile by the action bar */

  /* Set for real by site.js once the header has laid out (masthead + the
     navy actions bar). The nav wraps to a second line in a squeeze zone just
     above the hamburger breakpoint, where no single fixed number is right,
     so this default is deliberately the conservative (tall) end - a hero
     that is briefly a little short is fine; one that pushes its own buttons
     under the fold is not. */
  --hdr-h: 200px;
}

/* -------------------------------------------------- homepage, brighter -- */
/* Round 12 (chg-ddfcf124) - "make the home page more brighter and more
   professional... you can alter the colors". Scoped to body.home (set on
   index.html only) so the other ten pages, which share these same --navy /
   --bone tokens, are untouched - she asked about the home page specifically.
   Custom properties cascade, so every .on-navy / .hero / .on-sink section
   on the homepage picks this up automatically; --actions-bg above is its
   own token, so the sticky action bar stays the same shade on every page,
   home included.
   Contrast re-verified for the new navy, not assumed: on-navy text 10.04:1,
   on-navy-dim 7.56:1, mint links/eyebrow 5.17:1, solid-button text (navy on
   mint) 5.17:1 - all comfortably clear of WCAG AA. Bone only got lighter, so
   the existing ink/ink-muted/green ratios on it can only have improved. */
body.home {
  --navy:      #183F52;
  --bone:      #FAF8F2;
  --bone-sink: #F1ECE1;
}

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

*, *::before, *::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  /* Round 5, 2026-09-23 - the action bar's marquee track is deliberately
     wider than the page (see .actions__scroll); clipped here at the
     viewport edge rather than on .actions__row itself, because clipping it
     there would ALSO clip the QR popovers, which need to escape downward
     past the row's own height. */
  overflow-x: hidden;
}

/* The action bar is sticky on desktop, so anything jumped to by an anchor
   (#appointment, #finding-us, a treatment) must clear it or it lands under
   the bar and reads as a broken link. */
[id] { scroll-margin-top: 5.5rem; }
@media (max-width: 48rem) { [id] { scroll-margin-top: 1.5rem; } }
/* 2026-10-03 (chg-8d4256d0) - the top bar with the menu stays on screen too
   now, so a jump has to clear both bars (--hdr-h, measured by site.js), and
   on a phone the top bar alone (--mast-h). */
@media (min-width: 48.0625rem) { [id] { scroll-margin-top: calc(var(--hdr-h, 9rem) + 1rem); } }
@media (max-width: 48rem) { [id] { scroll-margin-top: calc(var(--mast-h, 4rem) + 1rem); } }

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

body {
  margin: 0;
  background: var(--bone);
  color: var(--ink);
  font-family: var(--ui);
  font-size: 1.125rem;          /* 18px floor: this audience skews older */
  line-height: 1.65;
  font-variant-numeric: tabular-nums lining-nums;
  -webkit-font-smoothing: antialiased;
  padding-bottom: var(--dock-h);
}

img, svg, video { max-width: 100%; height: auto; display: block; }

a { color: inherit; }

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

.skip {
  position: absolute; left: -9999px; top: 0;
  background: var(--green); color: #fff;
  padding: 0.75rem 1.25rem; z-index: 200;
  font-weight: 600; text-decoration: none;
}
.skip:focus { left: 0; }

.sr {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* ----------------------------------------------------------- structure -- */

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

.shell--narrow { width: min(100% - (var(--gutter) * 2), 52rem); }

.band { padding-block: var(--band); }
.band--tight { padding-block: clamp(3rem, 6vw, 5rem); }

.on-navy {
  background: var(--navy);
  color: var(--on-navy);
}
.on-navy a { color: var(--mint); }
.on-navy .lede { color: var(--on-navy-dim); }

.on-sink { background: var(--bone-sink); }

/* ---------------------------------------------------------------- type -- */

h1, h2, h3, h4 {
  font-family: var(--display);
  font-weight: 500;
  font-optical-sizing: auto;
  line-height: 1.08;
  letter-spacing: -0.02em;
  text-wrap: balance;
  margin: 0;
}

h1 {
  font-size: clamp(2.5rem, 6.4vw, 4.75rem);
  letter-spacing: -0.035em;
}

h2 {
  font-size: clamp(1.95rem, 4vw, 3.1rem);
  letter-spacing: -0.028em;
}

h3 {
  font-size: clamp(1.35rem, 2.2vw, 1.75rem);
  letter-spacing: -0.02em;
  line-height: 1.2;
}

p { margin: 0 0 1.15em; max-width: var(--measure); }
p:last-child { margin-bottom: 0; }

.lede {
  font-size: clamp(1.2rem, 1.9vw, 1.45rem);
  line-height: 1.5;
  color: var(--ink-muted);
  max-width: 40rem;
}

.eyebrow {
  font-family: var(--ui);
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--green);
  margin: 0 0 1.25rem;
}
.on-navy .eyebrow { color: var(--mint); }

.display-quiet { color: var(--ink-muted); }

/* ------------------------------------------------------------- buttons -- */

.btn {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  font-family: var(--ui);
  font-size: 1rem;
  font-weight: 600;
  letter-spacing: 0.005em;
  padding: 0.95rem 1.6rem;
  border-radius: 2px;
  border: 1.5px solid transparent;
  text-decoration: none;
  cursor: pointer;
  transition: background-color 0.18s ease, color 0.18s ease, border-color 0.18s ease;
}

.btn--solid { background: var(--green); color: #fff; }
.btn--solid:hover { background: var(--green-deep); }

.btn--line {
  border-color: var(--rule-strong);
  color: var(--ink);
  background: transparent;
}
.btn--line:hover { border-color: var(--ink); }

.on-navy .btn--solid { background: var(--mint); color: var(--navy); }
.on-navy .btn--solid:hover { background: #8AD0B9; }
.on-navy .btn--line { border-color: var(--rule-navy); color: var(--on-navy); }
.on-navy .btn--line:hover { border-color: var(--on-navy); }

.btn-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.85rem;
  margin-top: 2rem;
}

/* ------------------------------------------------------ reminder modal -- */
/* Round 6, 2026-09-23 - homepage-only popup asking patients to bring their
   medical records. Native <dialog>, so ::backdrop and Escape-to-close come
   free; the click-outside-to-close listener is in site.js. */

.reminder-modal {
  border: none;
  border-radius: 4px;
  padding: 0;
  width: min(90vw, 28rem);
  background: var(--bone);
  color: var(--ink);
  box-shadow: 0 20px 60px rgba(15, 43, 58, 0.35);
}

.reminder-modal::backdrop {
  background: rgba(15, 43, 58, 0.55);
}

.reminder-modal__panel {
  position: relative;
  padding: 2.75rem 2rem 2.25rem;
  text-align: center;
}

.reminder-modal__close {
  position: absolute;
  top: 0.6rem;
  right: 0.6rem;
  width: 2.25rem;
  height: 2.25rem;
  border: none;
  background: transparent;
  color: var(--ink-muted);
  font-size: 1.6rem;
  line-height: 1;
  cursor: pointer;
  border-radius: 2px;
}
.reminder-modal__close:hover { color: var(--ink); }

.reminder-modal__title { margin-bottom: 0.85rem; }

.reminder-modal__body {
  color: var(--ink);
  font-weight: 600;
  text-wrap: balance;
  margin: 0 auto 1.75rem;
}

/* 2026-09-28 - client asked for the whole box to blink twice when it opens,
   so the reminder is noticed. Plays once per showing; the global
   prefers-reduced-motion rule collapses it to nothing for visitors who
   have asked their device for less motion. */
.reminder-modal[open] {
  animation: reminder-blink 0.5s ease-in-out 0.4s 2;
}

@keyframes reminder-blink {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.15; }
}

.reminder-modal .btn { margin-inline: auto; }

@media (max-width: 30rem) {
  .reminder-modal__panel { padding: 2.5rem 1.5rem 2rem; }
}

/* ----------------------------------------------------------- review qr -- */

.review-qr {
  display: flex;
  align-items: center;
  gap: 1.1rem;
  margin-top: 1.75rem;
}

.review-qr img {
  width: 110px;
  height: 110px;
  padding: 0.5rem;
  background: #fff;
  border: 1px solid var(--rule);
  border-radius: 2px;
}

.review-qr figcaption {
  font-size: 0.9rem;
  color: var(--ink-muted);
  max-width: 14rem;
}

@media (max-width: 30rem) {
  .review-qr { flex-direction: column; align-items: flex-start; }
}

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

.masthead {
  border-bottom: 1px solid var(--rule);
  background: var(--bone);
  position: relative;
  z-index: 60;
}

.masthead__bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
  padding-block: 1.1rem;
}

.wordmark {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  text-decoration: none;
  line-height: 1;
}

.wordmark__logo {
  height: 40px;
  width: auto;
  align-self: center;
  flex: 0 0 auto;
}

@media (max-width: 62rem) {
  .wordmark__logo { height: 32px; }
}

.wordmark__name {
  font-family: var(--display);
  font-size: 1.4rem;
  font-weight: 600;
  letter-spacing: -0.025em;
  color: var(--ink);
}

/* 2026-09-28 (chg-4e5c7f16) - she asked for "Velachery" to sit BELOW the name
   rather than beside it, so the two stack as one block beside the logo. */
.wordmark__text {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  min-width: 0;
}

.wordmark__sub {
  font-family: var(--ui);
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--ink-muted);
}

.nav {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 1.35rem;
}

.nav a {
  font-size: 0.95rem;
  font-weight: 500;
  text-decoration: none;
  color: var(--ink-muted);
  padding-block: 0.25rem;
  border-bottom: 2px solid transparent;
  transition: color 0.15s ease, border-color 0.15s ease;
  white-space: nowrap;
}
.nav a:hover { color: var(--ink); }
.nav a[aria-current="page"] { color: var(--ink); border-bottom-color: var(--green); }

.nav-toggle {
  display: none;
  font-family: var(--ui);
  font-size: 0.9rem;
  font-weight: 600;
  background: transparent;
  border: 1.5px solid var(--rule-strong);
  border-radius: 2px;
  padding: 0.6rem 1rem;
  color: var(--ink);
  cursor: pointer;
}

@media (max-width: 62rem) {
  .nav-toggle { display: inline-block; flex: 0 0 auto; }
  /* The wordmark is long. Left to itself it takes the whole 390px row and
     pushes Menu onto a second line, which doubles the header height on the
     one screen where that matters most. */
  /* 2026-09-28 (chg-4e5c7f16) - a zero basis, so the wordmark takes what is
     left beside Menu instead of claiming the row and pushing Menu onto a
     line of its own (it had been, on every phone). */
  .wordmark { flex: 1 1 0; min-width: 0; }
  .wordmark__name { font-size: 1.15rem; }
  .wordmark__sub { font-size: 0.62rem; }
  .nav {
    display: none;
    width: 100%;
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    padding-bottom: 1rem;
  }
  .nav[data-open="true"] { display: flex; }
  .nav a {
    padding: 0.85rem 0;
    border-bottom: 1px solid var(--rule);
  }
  .nav a[aria-current="page"] { border-bottom-color: var(--green); }
  .masthead__bar { flex-wrap: wrap; }
}

@media (max-width: 30rem) {
  .masthead__bar { column-gap: 0.75rem; }
  .wordmark__logo { height: 26px; }
  .wordmark__name { font-size: 1rem; }
}

/* ------------------------------------------------- action bar (sticky) -- */

.actions {
  border-top: 1px solid var(--rule-navy);
  border-bottom: 1px solid rgba(8, 24, 33, 0.28);
  background: var(--actions-bg);
  color: var(--actions-ink);
  box-shadow: 0 4px 14px rgba(8, 24, 33, 0.16);
}

.actions__row {
  display: flex;
  align-items: stretch;
  justify-content: center;
}

.action {
  flex: 1 1 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.3rem;
  padding: 0.7rem 0.4rem;
  text-decoration: none;
  color: var(--actions-ink);
  font-family: var(--ui);
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  border: 0;
  border-right: 1px solid var(--rule-navy);
  background: transparent;
  cursor: pointer;
  position: relative;
  transition: background-color 0.16s ease;
  min-height: 56px;
}
.action:last-child { border-right: 0; }
.action:hover { background: var(--navy-lift); }
.action svg { width: 20px; height: 20px; stroke: var(--actions-icon); fill: none; stroke-width: 1.6; }

/* desktop: the QR actions reveal a real code, which is what a QR is for */
/* display:none rather than visibility:hidden. A 148px panel that is merely
   invisible still sits in the layout tree, which made the 56px action bar
   measure six times its own height to anything reading the box model.
   Round 5, 2026-09-23 - opens DOWNWARD, not up: the bar this belongs to is
   sticky to the top of the page on desktop (the only place this rule is
   reachable; mobile disables the popover outright below), so opening
   upward put the panel above the visible viewport with nowhere to render -
   true for the existing Location QR as well as the new Review-us one added
   this round, not something either QR ever showed on screen. */
.action__qr {
  background: #fff;
  padding: 0.75rem;
  border-radius: 3px;
  box-shadow: 0 12px 34px rgba(8, 24, 33, 0.34);
  margin: 0;
  z-index: 90;
}
/* Fallback for a browser without the Popover API (site.js feature-detects
   and only adds [popover] when it's there): the original CSS-only hover
   reveal, escaping .action's own box via position:absolute. Untouched from
   Round 5 - this is exactly what shipped then, for exactly the browsers
   that still need it. */
.action__qr:not([popover]) {
  display: none;
  position: absolute;
  top: calc(100% + 0.6rem);
  left: 50%;
  transform: translateX(-50%);
}
.action--qr:hover .action__qr:not([popover]),
.action--qr:focus .action__qr:not([popover]),
.action--qr:focus-within .action__qr:not([popover]) { display: block; }
/* Round 6, 2026-09-23 - site.js promotes this to a native popover (top
   layer) where the API exists, so it's immune to any ancestor's overflow
   or clip-path regardless of where it sits in the DOM - which is what lets
   the scrolling bar below clip to one track's width without also clipping
   this. site.js sets top/left in viewport px (the trigger's own position,
   which the DOM nesting no longer determines once it's in the top layer);
   this just re-centers it under that point, same as the left:50% it
   replaces. Visibility is the browser's own :popover-open, not display -
   see site.js for why an unconditional display:none here would fight it. */
.action__qr[popover] {
  position: fixed;
  top: 0;
  left: 0;
  transform: translateX(-50%);
}
/* max-width here too, not just width: the global `img { max-width: 100% }`
   reset (near the top of this file) resolves against this figure's own
   shrink-to-fit width, which is indeterminate since the figure is
   position:absolute with no explicit width of its own - the two rules fight
   and the image renders squashed to a sliver. A fixed max-width ends the
   fight. Round 5, 2026-09-23 - true for the existing Location QR as well as
   the new Review-us one, and neither QR was ever legible before this. */
.action__qr img, .action__qr svg { width: 148px; height: 148px; max-width: 148px; }
/* 2026-09-29 (chg-371baae9) - she asked for the phone number to show when
   the cursor is on Call. Same popover as the QR panels (site.js opens any
   .action--qr), holding the number instead of a code. Desktop only, like
   them: on a phone the tap already dials. */
.action__qr--tel {
  font-family: var(--ui);
  font-size: 1rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  color: var(--navy);
  white-space: nowrap;
  padding: 0.6rem 0.95rem;
}
/* 2026-09-30 (chg-5a8ac823) - her ask: both numbers, the landline and
   the mobile, one per line, in the Call pop-up and the dock pill. */
.tel-line { display: block; }
.tel-line + .tel-line { margin-top: 0.2rem; }
/* 2026-09-30 (chg-5443d23d) - her ask: the two numbers aligned, mobile
   first. In the Call pop-up each is two columns, so +91 sits over 044 and
   the last digits of both numbers end in the same place. */
.action__qr--tel { font-variant-numeric: tabular-nums; }
.action__qr--tel .tel-line {
  display: grid;
  grid-template-columns: auto 1fr;
  column-gap: 0.6em;
}
.action__qr--tel .tel-line > span + span { text-align: right; }
.action__qr figcaption {
  font-size: 0.7rem;
  color: #3C4A52;
  text-align: center;
  margin-top: 0.4rem;
  letter-spacing: 0.02em;
  font-weight: 600;
}
/* 2026-09-29 (chg-269e76f3) - she asked for a direct link beside each QR:
   the whole action already is one (Location opens directions, Review us
   her Google review page), and a click on the panel is a click on it, so
   the panel says so rather than nesting a second link inside the first. */
.action__qr-link {
  display: block;
  max-width: 148px;
  margin: 0.3rem auto 0;
  color: var(--navy);
  font-weight: 700;
  line-height: 1.35;
  text-decoration: underline;
  text-underline-offset: 2px;
}

/* mobile: fixed to the bottom, and the QR panels never open */
/* On a phone the action bar is fixed at thumb level and already carries Call
   and WhatsApp, so the floating dock would be the same two affordances twice,
   on the screen where space is scarcest. The dock stays on desktop, where the
   bar sits at the top of the window instead. */
@media (max-width: 48rem) {
  /* !important: the unconditional `.dock { display: flex }` rule further down
     the file (the "dock" section) comes AFTER this media query in source
     order, so at equal specificity it was winning on mobile too - the
     WhatsApp/Call bubble has been double-showing since the original delivery,
     on top of the identical two buttons already in the bottom action bar. */
  .dock { display: none !important; }
}

@media (max-width: 48rem) {
  :root { --dock-h: 62px; }
  .actions {
    position: fixed;
    inset-inline: 0;
    bottom: 0;
    z-index: 100;
    border-top: 1px solid var(--rule-navy);
    box-shadow: 0 -6px 22px rgba(8, 24, 33, 0.22);
  }
  /* On a phone the QR must not open on tap either: the reader is holding the
     only camera they have, so the panel is a dead end and the link is the
     whole point. */
  .action__qr,
  .action--qr:hover .action__qr,
  .action--qr:focus .action__qr,
  .action--qr:focus-within .action__qr { display: none; }
  .action { font-size: 0.7rem; }
}

@media (min-width: 48.0625rem) {
  .actions { position: sticky; top: 0; z-index: 80; }
}

/* 2026-10-01 (chg-b0cd92d7) - the five actions stand still, each once, in
   five equal cells across the page (the row above does that on its own).
   Rounds 5 to 14 moved the buttons themselves, and a moving row of buttons
   always has one crossing the edge. The movement she asked for is now the
   caption line under the bar, as on aligndental.in. */
@media (min-width: 48.0625rem) {
  .action { border-right: 0; }
}

/* ------------------------------------------------------ caption ticker -- */

.ticker {
  background: var(--navy);
  color: var(--on-navy);
  border-bottom: 1px solid var(--rule-navy);
  overflow: hidden;
}
.ticker__scroll {
  display: flex;
  width: max-content;
  animation: ticker-scroll 82s linear infinite; /* 12 captions at the pace 7 had in 48s */
}
.ticker:hover .ticker__scroll { animation-play-state: paused; }
.ticker__track {
  display: flex;
  flex: 0 0 auto;
  margin: 0;
  padding: 0;
  list-style: none;
}
.ticker__track li {
  display: flex;
  align-items: center;
  padding: 0.6rem 0;
  font-family: var(--ui);
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  white-space: nowrap;
}
.ticker__track li::after {
  content: "";
  width: 6px;
  height: 6px;
  margin-inline: 1.75rem;
  border-radius: 50%;
  background: var(--mint);
}
/* 2026-10-01 (chg-f5eaef9a) - on the home page the line sits under the hero
   photographs (her ask), inside the hero, so it needs a rule above as well. */
.ticker--hero { border-top: 1px solid var(--rule-navy); }
@keyframes ticker-scroll {
  from { transform: translateX(0); }
  to { transform: translateX(-50%); }
}
@media (prefers-reduced-motion: reduce) {
  /* Nothing moves: the captions sit still, wrapped onto as many lines as they need. */
  .ticker__scroll { animation: none; width: auto; justify-content: center; }
  .ticker__track[aria-hidden] { display: none; }
  .ticker__track { flex-wrap: wrap; justify-content: center; }
}

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

/* Round 5, 2026-09-23 - restored to the delivered design. Rounds 1-3 tried a
   full-bleed photo hero (a carousel, then a full-page crop) and she asked us
   to undo it: the crops were cutting her photographs off ("half cut"), and
   she wants the homepage back to how it looked at delivery. */
.hero {
  background: var(--navy);
  color: var(--on-navy);
  position: relative;
  overflow: hidden;
}

/* Top-aligned. Bottom-aligning the caption against a three-line headline left
   it stranded 347px low with a void above it; brought up, it reads as the
   strapline to the headline, which is what it is. */
.hero__grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 20rem);
  gap: clamp(2rem, 5vw, 4.5rem);
  align-items: start;
  padding-block: clamp(4rem, 10vw, 8.5rem);
}

.hero h1 { color: var(--on-navy); }

.hero__caption {
  border-left: 2px solid var(--mint);
  padding-left: 1.5rem;
  font-size: 0.95rem;
  line-height: 1.5;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  font-weight: 600;
  color: var(--on-navy-dim);
}

.hero__caption strong {
  display: block;
  color: var(--mint);
  font-weight: 700;
  margin-bottom: 0.4rem;
}

.hero__standfirst {
  margin-top: 2rem;
  font-size: clamp(1.15rem, 1.7vw, 1.4rem);
  line-height: 1.5;
  color: var(--on-navy-dim);
  max-width: 38rem;
}
/* Her standfirst runs to two paragraphs (2026-09-23 request); keep them one block. */
.hero__standfirst + .hero__standfirst {
  margin-top: 1rem;
}

@media (max-width: 58rem) {
  .hero__grid { grid-template-columns: 1fr; align-items: start; }
  .hero__caption { order: -1; padding-left: 1.1rem; }
}

/* The hero's anchor. Not a photograph and not pretending to be one: it is the
   site's own tooth-and-heart mark drawn at architectural scale, bleeding off
   the right edge. It carries the hero while her photography is still to come,
   and it stays correct once the photographs arrive because it sits behind
   them rather than in their place. */
.hero__mark {
  position: absolute;
  right: -6%;
  top: 50%;
  transform: translateY(-50%);
  width: min(52vw, 40rem);
  height: auto;
  fill: none;
  stroke: var(--mint);
  stroke-width: 0.5;
  stroke-linejoin: round;
  opacity: 0.16;
  pointer-events: none;
}

@media (max-width: 58rem) {
  /* On a phone the mark sits directly behind the standfirst rather than beside
     it, so it drops to where it reads as texture and not as a line crossing
     the words. */
  .hero__mark { right: -26%; width: 74vw; opacity: 0.07; }
}

/* 2026-09-29 (chg-269e76f3) - her ask: the text above shows for 5 seconds,
   then her photographs come in, no text over them.
   2026-09-30 (chg-b0e958b2) - her ask: the photos ONE BY ONE, each filling
   the whole banner, "in the same manner as" aligndental.in, with the banner
   shaped so each whole image fits it precisely. Every banner is a 16:9 file
   (assets/hero/banner-*.webp) and the photo box is 16:9, so nothing is cut
   ("half cut" was rounds 1-3's complaint) and nothing is letterboxed.
   The box is a swipeable scroll-snap row, like aligndental.in's; site.js
   moves it along. Two layouts:
   - stacked (the default, and phones, no JS, reduced motion): the intro,
     then the photos under it, full width.
   - .has-reel (site.js adds it when the intro fits inside a 16:9 box, i.e.
     wide screens): the hero IS the 16:9 box, the intro and the photos share
     it, and .is-reel slides one stage out and the other in. */
.hero__intro { position: relative; }
.hero__reel { position: relative; background: var(--navy); }
.hero__slides {
  display: flex;
  aspect-ratio: 16 / 9;
  width: 100%;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  scrollbar-width: none;
}
.hero__slides::-webkit-scrollbar { display: none; }
.hero__slides:focus-visible { outline: 3px solid var(--mint); outline-offset: -3px; }
/* 2026-10-01 (chg-b0cd92d7) - every photo FILLS the banner, as on
   aligndental.in: cover, with the point to hold in view set per photo
   (--focal on the slide). The two tall photos were sitting whole over a
   blurred copy of themselves; they are now wide files (see index.html). On
   phones each slide swaps to a 4:3 file cut from her original, so nobody
   is cropped out by a narrow screen. */
.hero__slide {
  display: block;
  flex: 0 0 100%;
  width: 100%;
  height: 100%;
  scroll-snap-align: start;
}
.hero__slide img {
  display: block;
  width: 100%;
  height: 100%;
  max-width: none;
  object-fit: cover;
  object-position: var(--focal, 50% 50%);
}
@media (min-width: 48.0625rem) {
  .hero__slides { max-height: var(--hero-h, none); }
}
@media (max-width: 48rem) {
  .hero__slides { aspect-ratio: 4 / 3; }
  .hero__slide img { object-position: 50% 50%; }
}
/* Her caption, small, in the top right corner of the photographs (her words,
   22 Sep: "at top right corner like a small caption in bold letters"), over
   a soft wedge of shade so it reads on a bright photo. Only where the photos
   fill the banner; stacked, the same caption is in the text under them. */
.hero__over { display: none; }
.hero.has-reel .hero__over {
  display: block;
  position: absolute;
  top: clamp(1.5rem, 3vw, 2.75rem);
  right: var(--gutter);
  max-width: 22rem;
  margin: 0;
  padding-right: 1.1rem;
  border-right: 2px solid var(--mint);
  text-align: right;
  font-family: var(--ui);
  font-size: 0.95rem;
  line-height: 1.5;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  font-weight: 700;
  color: #fff;
  text-shadow: 0 1px 12px rgba(8, 20, 30, 0.6);
  pointer-events: none;
}
.hero__over strong { display: block; font-size: 1.15rem; color: #C8F0E2; margin-bottom: 0.3rem; }
.hero.has-reel .hero__reel::after {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(60% 55% at 100% 0%, rgba(8, 20, 30, 0.62), rgba(8, 20, 30, 0) 70%);
  pointer-events: none;
}
.hero.has-reel .hero__over,
.hero.has-reel .hero__controls { z-index: 1; }
.hero__controls { display: none; }
.hero.has-slides .hero__controls {
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 0.15rem;
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  padding: 1.5rem 1rem 0.5rem;
  background: linear-gradient(rgba(8, 20, 30, 0), rgba(8, 20, 30, 0.5));
  pointer-events: none;
}
.hero__controls button { pointer-events: auto; cursor: pointer; }
.hero__dot {
  position: relative;
  width: 2rem;
  height: 2.75rem;
  padding: 0;
  border: 0;
  background: none;
}
.hero__dot::before {
  content: "";
  position: absolute;
  left: 0.3rem;
  right: 0.3rem;
  top: 50%;
  height: 3px;
  margin-top: -1.5px;
  border-radius: 2px;
  background: rgba(255, 255, 255, 0.5);
}
.hero__dot:hover::before { background: rgba(255, 255, 255, 0.8); }
.hero__dot[aria-current="true"]::before { background: #fff; }
.hero__dot:focus-visible,
.hero__pause:focus-visible { outline: 2px solid #fff; outline-offset: 2px; }
.hero__pause {
  margin-left: 0.75rem;
  padding: 0.3rem 0.85rem;
  border: 1px solid rgba(255, 255, 255, 0.7);
  border-radius: 999px;
  background: rgba(8, 20, 30, 0.4);
  color: #fff;
  font: inherit;
  font-size: 0.8rem;
  font-weight: 600;
  letter-spacing: 0.04em;
}
.hero__pause:hover { background: rgba(8, 20, 30, 0.65); }
/* Stacked (phones): the photo is small, so the dots go under it, on the
   navy, rather than over the bottom of the picture. */
.hero.has-slides:not(.has-reel) .hero__controls {
  position: static;
  padding: 0.25rem 1rem 0.75rem;
  background: none;
}
/* 2026-10-01 (chg-b0cd92d7) - stacked, the photographs lead and the text
   follows (it was the other way round, so a phone opened on a screen of
   text). Order only: the heading is still first in the page's source. */
.hero { display: flex; flex-direction: column; }
.hero__reel { order: -1; }
/* The caption line follows the photographs, before the text. */
.hero > .ticker { order: -1; }
@media (max-width: 48rem) {
  .hero__grid { padding-block: 2.25rem 3rem; }
}
/* Where the script runs, the text is a little tighter top and bottom on a
   wide screen, so it fits the banner on an ordinary laptop. */
@media (min-width: 48.0625rem) {
  .hero.has-slides .hero__grid { padding-block: clamp(2rem, 4.5vw, 4rem); }
}

/* Two rows: the banner, --hero-h tall, and the caption line under it. */
.hero.has-reel { display: grid; grid-template-columns: minmax(0, 1fr); grid-template-rows: var(--hero-h) auto; }
.hero.has-reel > .ticker { grid-area: 2 / 1; order: 0; }
.hero.has-reel .hero__reel { order: 0; }
.hero.has-reel .hero__slides { aspect-ratio: auto; height: 100%; max-height: none; }
.hero.has-reel > .hero__intro,
.hero.has-reel > .hero__reel {
  grid-area: 1 / 1;
  transition: transform 0.9s cubic-bezier(0.7, 0, 0.2, 1);
}
.hero.has-reel > .hero__intro { display: flex; align-items: center; }
.hero.has-reel > .hero__reel { align-self: stretch; transform: translateX(100%); }
.hero.is-reel > .hero__intro { transform: translateX(-100%); }
.hero.is-reel > .hero__reel { transform: translateX(0); }
@media (prefers-reduced-motion: reduce) {
  .hero__slides { scroll-behavior: auto; }
}

/* 2026-10-08 (chg-0a72bc06) - her ask: Zainab Ali's photo and review as the
   8th slide of the home banner. The one slide that is not a photograph
   filling the frame: her collage whole at its own square shape (never
   cropped, as on the Dental tourism page), her review beside it, on the
   banner's own navy. Bottom padding keeps the words clear of the dots. */
.hero__slide--story {
  margin: 0;
  display: grid;
  grid-template-columns: auto minmax(0, 40rem);
  grid-template-rows: minmax(0, 1fr);
  align-items: center;
  justify-content: center;
  gap: clamp(1.5rem, 4vw, 4rem);
  padding: clamp(1.25rem, 3vw, 2.5rem) var(--gutter) clamp(3.25rem, 5vw, 4.25rem);
  background: radial-gradient(80% 90% at 0% 50%, #1D4A5F, var(--navy) 70%);
  color: #fff;
}
.hero__slide--story .hero__story-photo {
  display: block;
  height: 100%;
  width: auto;
  max-width: none;
  aspect-ratio: 1 / 1;
  object-fit: contain;
  border: 1px solid rgba(255, 255, 255, 0.25);
  background: #fff;
}
.hero__story-words { display: flex; flex-direction: column; gap: 1rem; max-width: 40rem; border-left: 2px solid var(--mint); padding-left: clamp(1rem, 2.5vw, 2rem); }
.hero__story-eyebrow {
  margin: 0;
  font-family: var(--ui);
  font-size: 0.8rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--mint);
}
.hero__story-words blockquote { margin: 0; }
.hero__story-words blockquote p {
  margin: 0;
  font-family: var(--display);
  font-size: clamp(1.4rem, 2.6vw, 2.35rem);
  line-height: 1.35;
  letter-spacing: -0.015em;
  color: #fff;
}
.hero__story-name {
  margin: 0;
  font-size: 0.875rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: #C8F0E2;
}
/* The corner caption and its shade step aside while the review is up. */
.hero.has-reel .hero__over,
.hero.has-reel .hero__reel::after { transition: opacity 0.4s; }
.hero.on-story .hero__over,
.hero.on-story .hero__reel::after { opacity: 0; }
@media (max-width: 48rem) {
  .hero__slide--story {
    grid-template-columns: auto minmax(0, 1fr);
    gap: 1rem;
    padding: 1rem;
  }
  .hero__slide--story .hero__story-photo { height: min(100%, 46vw); }
  .hero__story-words { gap: 0.5rem; padding-left: 0.85rem; }
  .hero__story-eyebrow { font-size: 0.68rem; }
  .hero__story-words blockquote p { font-size: clamp(0.95rem, 3.9vw, 1.2rem); line-height: 1.32; }
  .hero__story-name { font-size: 0.75rem; }
}

/* page header for inner pages */
.pagehead {
  border-bottom: 1px solid var(--rule);
  padding-block: clamp(3rem, 7vw, 5.5rem) clamp(2.5rem, 5vw, 4rem);
}
.pagehead .lede { margin-top: 1.5rem; }
/* A page head moved below the page's first section (the dental team's
   specialities, after "Our lead", chg-efb0d56e): it introduces the board
   under it, so no rule and no band gap between the two. */
.pagehead--inline { border-bottom: 0; padding-block: 0 clamp(2rem, 4vw, 3rem); }
.pagehead--inline + .band { padding-top: 0; }

/* ---------------------------------------------- the department board -- */

.board { border-top: 1px solid var(--rule-strong); }

.board__item {
  display: grid;
  grid-template-columns: minmax(0, 22rem) minmax(0, 1fr);
  gap: clamp(1rem, 4vw, 3rem);
  align-items: baseline;
  padding-block: 1.9rem;
  border-bottom: 1px solid var(--rule);
}

.board__name {
  font-family: var(--display);
  font-size: clamp(1.3rem, 2vw, 1.6rem);
  font-weight: 500;
  letter-spacing: -0.02em;
  line-height: 1.15;
  margin: 0;
}

.board__desc {
  margin: 0;
  color: var(--ink-muted);
  font-size: 1.0625rem;
  line-height: 1.6;
  max-width: 42rem;
}

.on-navy .board { border-top-color: var(--rule-navy); }
.on-navy .board__item { border-bottom-color: var(--rule-navy); }
.on-navy .board__desc { color: var(--on-navy-dim); }

@media (max-width: 48rem) {
  .board__item { grid-template-columns: 1fr; gap: 0.5rem; padding-block: 1.5rem; }
}

/* The board's two-column rhythm needs the full measure. Inside a half-width
   column it squeezes the description to ~14rem, which is how a phone number
   ended up wrapping onto three lines at 1024px. Stack it there instead. */
.board--stack .board__item {
  grid-template-columns: 1fr;
  gap: 0.3rem;
  padding-block: 1.35rem;
}

/* A phone number must never break across lines, wherever it appears. */
a[href^="tel:"], .nowrap { white-space: nowrap; }

/* ------------------------------------------------------- team gallery -- */

/* 2026-09-28 (chg-4e5c7f16) - she asked for the photos under "Our lead" to
   scroll continuously sideways. Two identical tracks, the second decorative
   (aria-hidden, empty alt), translated by exactly one track for a seamless
   loop. Every photo is shown at its own shape at one height, so nothing is
   cropped - the old 4:3 grid was cutting heads and subjects on five of the
   nine. Pauses under the pointer; reduced-motion visitors get a plain row
   they can swipe instead. */
.team-strip {
  overflow: hidden;
  margin-top: clamp(2rem, 4vw, 3rem);
}
.team-strip__scroll {
  display: flex;
  width: max-content;
  animation: team-strip-scroll 60s linear infinite;
}
.team-strip:hover .team-strip__scroll { animation-play-state: paused; }
.team-strip__track {
  display: flex;
  flex: 0 0 auto;
  gap: clamp(0.6rem, 2vw, 1.1rem);
  padding-right: clamp(0.6rem, 2vw, 1.1rem);
}
.team-strip__track img {
  height: clamp(11rem, 22vw, 15rem);
  width: auto;
  max-width: none;
  border-radius: 2px;
  background: var(--bone-sink);
}
@keyframes team-strip-scroll {
  from { transform: translateX(0); }
  to { transform: translateX(-50%); }
}
@media (prefers-reduced-motion: reduce) {
  .team-strip { overflow-x: auto; }
  .team-strip__scroll { animation: none; }
  .team-strip__track[aria-hidden] { display: none; }
}

/* His portrait, shown at its own 4:5 shape in the column the slot held. */
.portrait {
  width: 100%;
  max-width: 19rem;
  height: auto;
  border-radius: 2px;
  background: var(--bone-sink);
}
/* One column on a phone: his face first, not after the whole biography. */
@media (max-width: 52rem) {
  .prose-grid--portrait > :last-child { order: -1; }
  .portrait { max-width: 15rem; }
}

/* ------------------------------------------------------- statement band */

.statement {
  background: var(--navy);
  color: var(--on-navy);
}

.statement__text {
  font-family: var(--display);
  font-size: clamp(1.85rem, 4.2vw, 3.25rem);
  line-height: 1.16;
  letter-spacing: -0.03em;
  max-width: 24ch;
  margin: 0;
  text-wrap: balance;
}

.statement__text em {
  font-style: normal;
  color: var(--mint);
}

.statement__note {
  margin-top: 2.25rem;
  color: var(--on-navy-dim);
  max-width: 34rem;
  font-size: 1.0625rem;
}

/* --------------------------------------------------- composite marks -- */

.marks {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
  gap: 1px;
  background: var(--rule-navy);
  border: 1px solid var(--rule-navy);
  margin-top: 3.5rem;
}

.mark {
  background: var(--navy);
  padding: 2.25rem 1.75rem;
  display: flex;
  flex-direction: column;
  gap: 1.1rem;
}

.mark__art { width: 92px; height: 71px; }

.mark__art svg { width: 100%; height: 100%; overflow: visible; }

.mark__art .stroke {
  fill: none;
  stroke: var(--mint);
  stroke-width: 1.7;
  stroke-linecap: round;
  stroke-linejoin: round;
  vector-effect: non-scaling-stroke;
}

.mark__art .tooth { stroke: var(--on-navy-dim); }

/* A wire is a stroke that must NOT be part of the draw-on set: it either
   carries its own travelling dash, or it is a small detail that should be
   present the moment the outline lands. */
.mark__art .wire {
  fill: none;
  stroke: var(--mint);
  stroke-width: 1.7;
  stroke-linecap: round;
  stroke-linejoin: round;
  vector-effect: non-scaling-stroke;
  opacity: 0;
  transition: opacity 0.4s ease 0.7s;
}
.mark.is-in .mark__art .wire { opacity: 1; }
.mark__art .wire.travel { stroke-dasharray: 5 9; }

.mark__art .drip,
.mark__art .pulse[fill] { opacity: 0; }
.mark.is-in .mark__art .pulse[fill] { opacity: 1; }

.mark__name {
  font-family: var(--display);
  font-size: 1.3rem;
  font-weight: 500;
  letter-spacing: -0.02em;
  margin: 0;
}

.mark__pair {
  margin: 0;
  font-size: 0.95rem;
  line-height: 1.55;
  color: var(--on-navy-dim);
}

/* draw-on: the stroke writes itself once, when the mark scrolls in */
.mark__art .stroke {
  stroke-dasharray: var(--len, 220);
  stroke-dashoffset: var(--len, 220);
}
.mark.is-in .mark__art .stroke {
  animation: draw 1.1s cubic-bezier(0.5, 0, 0.2, 1) forwards;
}
.mark.is-in .mark__art .stroke--2 { animation-delay: 0.22s; }

@keyframes draw { to { stroke-dashoffset: 0; } }

/* each specialty's own element carries one motion that means something */
.mark.is-in .beat  { animation: beat 1.6s ease-in-out 1.1s infinite; transform-origin: center; }
.mark.is-in .drip  { animation: drip 2.4s ease-in-out 1.1s infinite; }
.mark.is-in .pulse { animation: pulse 2.2s ease-in-out 1.1s infinite; }
.mark.is-in .travel{ animation: travel 2.6s linear 1.1s infinite; }
.mark.is-in .breathe { animation: breathe 3.4s ease-in-out 1.1s infinite; transform-origin: center; }
.mark.is-in .spin  { animation: spin 9s linear 1.1s infinite; transform-origin: center; }

@keyframes beat {
  0%, 100% { transform: scale(1); }
  14% { transform: scale(1.13); }
  28% { transform: scale(1); }
  42% { transform: scale(1.08); }
}
@keyframes drip {
  0%, 62% { opacity: 0; transform: translateY(-5px); }
  70% { opacity: 1; transform: translateY(-2px); }
  100% { opacity: 0; transform: translateY(8px); }
}
@keyframes pulse {
  0%, 100% { opacity: 0.35; }
  50% { opacity: 1; }
}
@keyframes travel {
  0% { stroke-dashoffset: 30; }
  100% { stroke-dashoffset: -30; }
}
@keyframes breathe {
  0%, 100% { transform: scale(1); }
  50% { transform: scale(1.07); }
}
@keyframes spin { to { transform: rotate(360deg); } }

@media (prefers-reduced-motion: reduce) {
  .mark__art .stroke { stroke-dashoffset: 0; stroke-dasharray: none; }
  .mark.is-in .beat, .mark.is-in .drip, .mark.is-in .pulse,
  .mark.is-in .travel, .mark.is-in .breathe, .mark.is-in .spin { animation: none; }
  .mark.is-in .drip { opacity: 1; }
  .mark.is-in .pulse { opacity: 1; }
}

/* ------------------------------------------------------------ gallery -- */

.cases {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(17.5rem, 1fr));
  gap: clamp(1.5rem, 3vw, 2.5rem);
  margin-top: 3rem;
}

/* A grid that opens its band needs no gap of its own above it. */
.cases:first-child { margin-top: 0; }

.case { display: flex; flex-direction: column; gap: 1rem; }

.case__name {
  font-family: var(--display);
  font-size: 1.3rem;
  font-weight: 500;
  letter-spacing: -0.02em;
  margin: 0;
}

.case__desc {
  margin: 0;
  color: var(--ink-muted);
  font-size: 1rem;
  line-height: 1.55;
}

/* The deliberate, designed placeholder. It has to read as intentional
   structure rather than as a broken image, because it will sit on a live
   preview for days before her photographs arrive. */
/* min-height, not just aspect-ratio: if the ratio fails to resolve for any
   reason the placeholder collapses to the height of its own label, which reads
   as a broken box rather than as a reserved photograph. */
.slot {
  position: relative;
  aspect-ratio: 4 / 3;
  min-height: 13rem;
  background:
    repeating-linear-gradient(
      -45deg,
      var(--bone-sink) 0 10px,
      #E6E0D5 10px 20px
    );
  border: 1px solid var(--rule-strong);
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 1.25rem;
}

.slot__label {
  font-family: var(--ui);
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-muted);
  background: var(--bone);
  border: 1px solid var(--rule-strong);
  padding: 0.5rem 0.85rem;
  line-height: 1.4;
  max-width: 100%;
}

/* 2026-10-01 (chg-b0cd92d7) - a treatment she has not sent photos for yet
   had a striped "Before and after" placeholder, which read as an unfinished
   page beside the cards that have photos. Same box, so the grid stays even,
   but quiet: the site's tooth-and-heart mark on the recessed bone. When her
   photos for one arrive it becomes a .case--viewer card like the others. */
.slot--quiet {
  background:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 72 68' fill='none' stroke='%231F6A57' stroke-width='1' stroke-linejoin='round' opacity='0.4'%3E%3Cpath d='M10 25 C10 14 19 9 25 15 C27 17 29 17 31 15 C37 9 46 14 46 25 C46 35 43 46 41 56 C40 62 35 62 34 56 C33 49 32 45 28 45 C24 45 23 49 22 56 C21 62 16 62 15 56 C13 46 10 35 10 25 Z'/%3E%3Cpath d='M53 33 C45 26 41 20.5 41 16.5 C41 12.4 44.1 9.4 47.7 9.4 C50.2 9.4 52.1 10.8 53 12.8 C53.9 10.8 55.8 9.4 58.3 9.4 C61.9 9.4 65 12.4 65 16.5 C65 20.5 61 26 53 33 Z'/%3E%3C/svg%3E")
      center / 34% auto no-repeat,
    var(--bone-sink);
  border-color: var(--rule);
}

/* A case with her own photographs takes the whole row, so a before/after
   pair is big enough to see the teeth. Each photo keeps its own shape. */
.case--photos { grid-column: 1 / -1; }
.case--photos .case__desc { max-width: 40rem; }

/* Her words sit above her photos, and the photos are held a little under
   the full row width so the pair reads as a set rather than a wall. */
.case--photos .ba-set { max-width: 60rem; margin-top: 0.5rem; }
@media (max-width: 40rem) {
  .case--photos .ba { max-width: 19rem; }
}

.ba-set {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(17.5rem, 1fr));
  gap: clamp(1.5rem, 3vw, 2.5rem);
}

.ba { margin: 0; }

.ba__pair {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.35rem;
}

.ba__pair img {
  display: block;
  width: 100%;
  height: auto;
  background: var(--bone-sink);
  border: 1px solid var(--rule-strong);
}

.ba__cap {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.35rem;
  margin-top: 0.6rem;
  font-family: var(--ui);
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-muted);
}

/* 2026-09-29 (chg-c381e51a) - her before-and-after pairs scroll sideways
   on their own, each photo whole at its own shape (these are clinical
   close-ups; any crop cuts the face). site.js repeats the pairs until a
   track fills the width, adds a second, decorative track and starts the
   loop. Pauses under the pointer; without the script, or with reduced
   motion, it is a plain row she can swipe. 2026-09-30 (chg-5443d23d) -
   the strip now lives inside each treatment card's viewer (her ask: "when
   clicked into, scroll it and show"), not in a block of its own. */
.ba-reel {
  overflow-x: auto;
}
.ba-reel.is-running { overflow: hidden; }
.ba-reel__scroll {
  display: flex;
  width: max-content;
}
.ba-reel.is-running .ba-reel__scroll {
  animation: ba-reel-scroll var(--reel-duration, 40s) linear infinite;
}
.ba-reel:hover .ba-reel__scroll { animation-play-state: paused; }
.ba-reel__track {
  display: flex;
  flex: 0 0 auto;
  gap: clamp(1.25rem, 3vw, 2.25rem);
  padding-right: clamp(1.25rem, 3vw, 2.25rem);
}
.ba-reel .ba__pair {
  display: flex;
  gap: 0.35rem;
}
.ba-reel .ba__pair img {
  height: clamp(14rem, 26vw, 20rem);
  width: auto;
  max-width: none;
}
/* 2026-10-14 (chg-8e601619) - one rule in every viewer: a pair whose photos are a
   before and an after of the same patient (alts "Before: ..." / "After: ...") carries
   this Before / After line; any other photo carries none. */
.ba-reel .ba__cap {
  display: flex;
}
.ba-reel .ba__cap span { flex: 1 1 0; }
@keyframes ba-reel-scroll {
  from { transform: translateX(0); }
  to { transform: translateX(-50%); }
}
/* In a viewer, a collage that came stacked stays stacked, the two photos
   sharing the strip's height; a side-by-side pair keeps each photo whole. */
.ba-reel .ba__pair--stack { flex-direction: column; }
.ba-reel .ba__pair--stack img { height: calc((clamp(14rem, 26vw, 20rem) - 0.35rem) / 2); }
.ba-reel .ba__pair--flow img { flex: 0 0 auto; width: auto; }
@media (prefers-reduced-motion: reduce) {
  .ba-reel.is-running { overflow-x: auto; }
  .ba-reel.is-running .ba-reel__scroll { animation: none; }
}

/* 2026-09-29 (chg-a4128662) - she asked for her before-and-after pictures
   to sit like the other cards and open when clicked. The card is the same
   size as its neighbours: the first pair and its label fill the 4:3 box the
   placeholders use, and pressing it opens every pair large in a popover. */
.case__thumb {
  display: flex;
  flex-direction: column;
  width: 100%;
  aspect-ratio: 4 / 3;
  min-height: 13rem;
  padding: 0;
  border: 1px solid var(--rule-strong);
  background: var(--bone-sink);
  cursor: zoom-in;
  font: inherit;
  color: inherit;
  text-align: left;
}
/* 2026-09-29 (chg-d166c33b) - every pair is a slide, side by side in a
   strip clipped to the box; site.js moves the strip one slide every 3 s.
   Without the script (or with reduced motion) the first pair simply shows. */
.case__thumb-slides {
  display: flex;
  flex: 1 1 0;
  min-height: 0;
  overflow: hidden;
}
.case__thumb-pair {
  display: flex;
  justify-content: center;
  gap: 2px;
  flex: 0 0 100%;
  min-width: 0;
  height: 100%;
  overflow: hidden;
  transition: transform 0.7s ease-in-out;
}
/* Each photo whole at its own shape, never trimmed: these are clinical
   close-ups and any crop to the box cuts the face. */
.case__thumb-pair img {
  display: block;
  height: 100%;
  width: auto;
  min-width: 0;
  object-fit: contain;
}
.case__thumb-cta {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 0.6rem 0.85rem;
  background: var(--bone);
  border-top: 1px solid var(--rule-strong);
  font-family: var(--ui);
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--green);
}
.case__thumb-cta span { font-size: 1.1rem; line-height: 1; }
.case__thumb:hover .case__thumb-cta,
.case__thumb:focus-visible .case__thumb-cta { background: var(--green); color: #fff; }
.case__thumb:focus-visible { outline: 2px solid var(--green); outline-offset: 3px; }

.case-viewer {
  width: min(94vw, 62rem);
  max-height: 90vh;
  overflow: auto;
  margin: auto;
  padding: 1.25rem clamp(1rem, 3vw, 2rem) 1.75rem;
  border: none;
  border-radius: 4px;
  background: var(--bone);
  color: var(--ink);
  box-shadow: 0 20px 60px rgba(15, 43, 58, 0.35);
}
.case-viewer::backdrop { background: rgba(15, 43, 58, 0.7); }
.case-viewer__head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 1rem;
  margin-bottom: 1rem;
}
.case-viewer__title {
  margin: 0;
  font-family: var(--display);
  font-size: 1.3rem;
  font-weight: 500;
  letter-spacing: -0.02em;
}
.case-viewer__close {
  flex: none;
  width: 2.5rem;
  height: 2.5rem;
  border: none;
  background: transparent;
  color: var(--ink-muted);
  font-size: 1.8rem;
  line-height: 1;
  cursor: pointer;
  border-radius: 2px;
}
.case-viewer__close:hover { color: var(--ink); }
/* 2026-09-29 (chg-269e76f3) - her pediatric photos. Collages that came
   stacked (two wide photos one above the other) stay stacked, in the card
   and in the viewer; side-by-side pairs share one height in the viewer,
   each photo as wide as its own shape (flex-grow = its width). */
.case__thumb-pair--stack { flex-direction: column; align-items: center; }
.case__thumb-pair--stack img { height: calc(50% - 1px); }
.ba__pair--stack { grid-template-columns: 1fr; }
.ba__pair--flow { display: flex; }
.ba__pair--flow img { flex: 1 1 0; width: 0; min-width: 0; }
@media (max-width: 40rem) {
  .case-viewer .ba { max-width: 22rem; margin-inline: auto; }
}

/* 2026-10-09 (chg-adb7c134) - her ask: every treatment card stops moving,
   shows the cover photo she chose for it, and tapping it (or View photos)
   opens one still gallery of that cover plus the treatment's own photos.
   The card's cover fills the box, cropped from the centre (these covers
   are stock pictures and drawings she picked, not her clinical records).
   (The viewer's still rows from this date gave way on 2026-10-12, below.) */
.case__cover {
  display: block;
  flex: 1 1 0;
  min-height: 0;
  width: 100%;
  object-fit: cover;
  object-position: var(--focal, 50% 50%);
}
/* The Oral lesions picture she sent is tall; the card uses a copy widened at
   the sides by an image model (her picture pasted back whole over the
   middle), so all six lesions show. */
/* 2026-10-12 (chg-d3647277) - her ask, by email via Karthik: in the
   viewer "all images ... of same size", "not distort or stretch any of
   them", and the strip may scroll on its own again ("make it autoscroll
   like it was before"). Every photo in one viewer sits in one frame of the
   same size, whole (object-fit: contain on a quiet ground, never cropped
   or upscaled: these are clinical records). Each viewer sets its frame's
   shape in --frame (width over height, on the viewer in treatments.html),
   chosen to suit most of its photos, so most fill their frame. Since
   2026-10-12 (chg-83897b81, her ask "DONT SHOW THE COVER PHOTO") the cover
   is on the card only, never in the viewer. site.js runs the strip (the chg-c381e51a loop, viewers only); with
   reduced motion, or without the script, it is a row she can swipe. */
.case-viewer { --tile-h: clamp(14rem, 28vw, 21rem); }
.case-viewer .ba-reel__track { align-items: flex-start; }
.case-viewer .ba-reel__scroll { min-width: 100%; }
.case-viewer .ba-reel:not(.is-running) .ba-reel__track { margin-inline: auto; padding-right: 0; }
.case-viewer .ba { flex: 0 0 auto; max-width: none; margin-inline: 0; }
.case-viewer .ba-reel .ba__pair,
.case-viewer .ba-reel .ba__pair--stack {
  display: flex;
  flex-direction: row;
  gap: 0.35rem;
}
.case-viewer .ba-reel .ba__pair img {
  display: block;
  flex: 0 0 auto;
  width: calc(var(--tile-h) * var(--frame, 1));
  height: var(--tile-h);
  max-width: none;
  max-height: none;
  object-fit: contain;
  background: var(--bone-sink);
  border: 1px solid var(--rule-strong);
}
.case-viewer .ba-reel:focus-within .ba-reel__scroll,
.case-viewer .ba-reel.is-held .ba-reel__scroll { animation-play-state: paused; }

/* 2026-09-29 (chg-371baae9) - her equipment photographs on the facilities
   page. Most are product shots on white, so each sits whole on a white 4:3
   panel the size of the placeholder it replaced, never cropped to fit;
   --fill is for a photo that is already 4:3 edge to edge. */
.case__photo {
  aspect-ratio: 4 / 3;
  background: #fff;
  border: 1px solid var(--rule-strong);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 6%;
  overflow: hidden;
}
.case__photo img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
}
.case__photo--fill { padding: 0; }
.on-navy .case__photo { border-color: var(--rule-navy); }

.slot--split { aspect-ratio: 16 / 9; }
.slot--wide { aspect-ratio: 21 / 9; }

.on-navy .slot {
  background: repeating-linear-gradient(-45deg, var(--navy-lift) 0 10px, #1B4053 10px 20px);
  border-color: var(--rule-navy);
}
.on-navy .slot__label {
  background: var(--navy);
  border-color: var(--rule-navy);
  color: var(--on-navy-dim);
}

/* ---------------------------------------------------------- captions -- */

/* 2026-09-28 (chg-4e5c7f16) - "who this is for" as short captions, not a
   paragraph. */
.captions {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
}
.captions li {
  font-size: 0.95rem;
  font-weight: 600;
  line-height: 1.3;
  color: var(--ink);
  background: var(--bone-sink);
  border-left: 3px solid var(--green);
  padding: 0.55rem 0.85rem;
  border-radius: 2px;
}

/* --------------------------------------------------------- timeline --- */

.rail {
  margin-top: 3.5rem;
  border-left: 2px solid var(--rule-strong);
  padding-left: clamp(1.5rem, 4vw, 3rem);
  display: flex;
  flex-direction: column;
  gap: clamp(2rem, 4vw, 3rem);
}

.stop { position: relative; }

.stop::before {
  content: "";
  position: absolute;
  left: calc(clamp(1.5rem, 4vw, 3rem) * -1 - 7px);
  top: 0.55rem;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: var(--green);
  border: 3px solid var(--bone);
}

.on-navy .rail { border-left-color: var(--rule-navy); }
.on-navy .stop::before { background: var(--mint); border-color: var(--navy); }
.on-sink .stop::before { border-color: var(--bone-sink); }

.stop__when {
  font-family: var(--ui);
  font-size: 0.8125rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--green);
  margin: 0 0 0.5rem;
}
.on-navy .stop__when { color: var(--mint); }

.stop h3 { margin-bottom: 0.6rem; }
.stop p { color: var(--ink-muted); margin-bottom: 0; }
.on-navy .stop p { color: var(--on-navy-dim); }

/* 2026-09-28 (chg-4e5c7f16) - she asked for "Your visit, step by step" to be
   a short, point-wise timeline. Each step is a few short points, and on a
   wide screen the five steps run across the page on one line instead of
   down it. */
.points {
  list-style: none;
  margin: 0;
  padding: 0;
}
.points li {
  position: relative;
  padding-left: 1rem;
  font-size: 1rem;
  line-height: 1.45;
  color: var(--ink-muted);
}
.points li + li { margin-top: 0.4rem; }
.points li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.6em;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--green);
}

/* 2026-09-28 (chg-efb0d56e) - she asked for the dental team page to read as
   short points instead of paragraphs; these lists carry a section on their
   own, so a step larger than the timeline's, and they work on navy too. */
.points--lg li { font-size: 1.125rem; line-height: 1.5; }
.points--lg li + li { margin-top: 0.7rem; }
.points--lg li::before { top: 0.65em; }
.on-navy .points li { color: var(--on-navy-dim); }
.on-navy .points li::before { background: var(--mint); }
.on-navy .points a { color: var(--mint); }
@media (min-width: 62rem) {
  /* A grid with subgrid rows, so a heading that wraps to two lines pushes
     every step's points down together and they stay on one line. */
  .rail--points {
    display: grid;
    grid-template-columns: repeat(5, minmax(0, 1fr));
    grid-template-rows: auto auto 1fr;
    column-gap: 1.75rem;
    row-gap: 0;
    border-left: 0;
    border-top: 2px solid var(--rule-strong);
    padding-left: 0;
    padding-top: 2rem;
  }
  .rail--points .stop { display: grid; grid-row: span 3; grid-template-rows: subgrid; min-width: 0; }
  .rail--points .stop::before { left: 0; top: calc(-2rem - 7px); }
}

/* ------------------------------------------------------------- stats --- */

.stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
  gap: clamp(2rem, 4vw, 3.5rem);
  margin-top: 3.25rem;
}

.stat { display: flex; flex-direction: column; gap: 0.5rem; }

.stat__num {
  font-family: var(--display);
  font-size: clamp(3rem, 7vw, 4.75rem);
  font-weight: 500;
  line-height: 0.95;
  letter-spacing: -0.04em;
  color: var(--mint);
  font-variant-numeric: tabular-nums lining-nums;
}

.stat__num[data-pending="true"] {
  color: var(--on-navy-dim);
  font-size: clamp(1.5rem, 3vw, 2rem);
  line-height: 1.2;
  letter-spacing: -0.02em;
}

.stat__label {
  font-size: 0.95rem;
  color: var(--on-navy-dim);
  line-height: 1.5;
  max-width: 18rem;
}

.stat__source {
  font-size: 0.8125rem;
  color: var(--on-navy-dim);
  opacity: 0.8;
}
.stat__source a { color: inherit; }

/* 2026-10-01 (chg-f5eaef9a) - six figures standing still (her ask: the numbers
   must not move about, only rise). chg-269e76f3 had slid them sideways as a
   bar. Three across, two on a phone; each number keeps a line to itself. */
.stats--six { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.stats--six .stat__num { white-space: nowrap; }
@media (max-width: 48rem) {
  .stats--six { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 2.25rem 1.5rem; }
  .stats--six .stat__num { font-size: clamp(2.1rem, 10.5vw, 3rem); }
}

/* ----------------------------------------------------------- quotes --- */

.quotes {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(19rem, 1fr));
  gap: clamp(1.5rem, 3vw, 2.5rem);
  margin-top: 3rem;
}

.quote {
  border-top: 2px solid var(--green);
  padding-top: 1.5rem;
  display: flex;
  flex-direction: column;
  gap: 1rem;
  margin: 0;
}

.quote blockquote {
  margin: 0;
  font-family: var(--display);
  font-size: 1.2rem;
  line-height: 1.45;
  letter-spacing: -0.015em;
}

.quote figcaption {
  font-size: 0.9rem;
  color: var(--ink-muted);
}

.quote__where {
  display: block;
  font-size: 0.8125rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  font-weight: 600;
  color: var(--green);
  margin-top: 0.3rem;
}

/* A quote slot, for a review not yet published on the page. Same hatched
   language as a photograph slot so an empty state reads as one system. */
.slot--quote { aspect-ratio: 3 / 2; }

.quote--empty { border-top-color: var(--rule-strong); }

/* ------------------------------------------------- dense column list -- */

.col-list {
  list-style: none;
  margin: 2.5rem 0 0;
  padding: 0;
  columns: 3;
  column-gap: clamp(1.5rem, 4vw, 3rem);
  border-top: 1px solid var(--rule-strong);
  padding-top: 0.5rem;
}

.col-list li {
  break-inside: avoid;
  border-bottom: 1px solid var(--rule);
}

.col-list a {
  display: block;
  padding: 0.85rem 0;
  text-decoration: none;
  font-family: var(--display);
  font-size: 1.1rem;
  letter-spacing: -0.015em;
  line-height: 1.25;
  transition: color 0.15s ease;
}
.col-list a:hover { color: var(--green); }

@media (max-width: 58rem) { .col-list { columns: 2; } }
@media (max-width: 34rem) { .col-list { columns: 1; } }

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

.faq { margin-top: 3rem; border-top: 1px solid var(--rule-strong); }

.faq details {
  border-bottom: 1px solid var(--rule);
}

.faq summary {
  cursor: pointer;
  list-style: none;
  padding: 1.4rem 3rem 1.4rem 0;
  position: relative;
  font-family: var(--display);
  font-size: clamp(1.15rem, 1.8vw, 1.35rem);
  font-weight: 500;
  letter-spacing: -0.015em;
  line-height: 1.3;
}
.faq summary::-webkit-details-marker { display: none; }

.faq summary::after {
  content: "";
  position: absolute;
  right: 0.5rem;
  top: 50%;
  width: 13px;
  height: 13px;
  border-right: 2px solid var(--green);
  border-bottom: 2px solid var(--green);
  transform: translateY(-70%) rotate(45deg);
  transition: transform 0.2s ease;
}
.faq details[open] summary::after { transform: translateY(-30%) rotate(-135deg); }

.faq details > div { padding: 0 3rem 1.6rem 0; }
.faq details p { color: var(--ink-muted); }

/* ------------------------------- generated FAQ (found-ready) ----------- */
/* The found-ready generator owns this markup so the accordion and the
   FAQPage schema come from one source and cannot drift. We only style it. */

.se-faq { border-top: 1px solid var(--rule-strong); margin-top: 2rem; }

.se-faq__title {
  font-family: var(--display);
  font-size: clamp(1.95rem, 4vw, 3.1rem);
  font-weight: 500;
  letter-spacing: -0.028em;
  line-height: 1.08;
  margin: 2.25rem 0 0.5rem;
  text-wrap: balance;
}

.se-faq__item { border-bottom: 1px solid var(--rule); }

.se-faq__q {
  cursor: pointer;
  list-style: none;
  padding: 1.4rem 3rem 1.4rem 0;
  position: relative;
  font-family: var(--display);
  font-size: clamp(1.15rem, 1.8vw, 1.35rem);
  font-weight: 500;
  letter-spacing: -0.015em;
  line-height: 1.3;
}
.se-faq__q::-webkit-details-marker { display: none; }

.se-faq__q::after {
  content: "";
  position: absolute;
  right: 0.5rem;
  top: 50%;
  width: 13px;
  height: 13px;
  border-right: 2px solid var(--green);
  border-bottom: 2px solid var(--green);
  transform: translateY(-70%) rotate(45deg);
  transition: transform 0.2s ease;
}
.se-faq__item[open] .se-faq__q::after { transform: translateY(-30%) rotate(-135deg); }

.se-faq__a { padding: 0 3rem 1.6rem 0; }
.se-faq__a p { color: var(--ink-muted); margin: 0; max-width: 46rem; }
.se-faq__a p + p, .se-faq__a ul { margin-top: 0.9rem; }
.se-faq__a ul { color: var(--ink-muted); max-width: 46rem; padding-left: 1.25rem; }
.se-faq__a li { margin: 0.2rem 0; }

/* ------------------------ generated contact form ----------------------- */

.cf-form { margin: 0; }

.cf-field { margin: 0 0 1.35rem; max-width: none; }

.cf-label {
  display: block;
  font-family: var(--ui);
  font-size: 0.9rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  margin-bottom: 0.45rem;
  color: var(--ink);
}

.cf-input, .cf-textarea {
  width: 100%;
  font-family: var(--ui);
  font-size: 1.0625rem;
  line-height: 1.5;
  padding: 0.85rem 1rem;
  border: 1.5px solid var(--rule-strong);
  border-radius: 2px;
  background: var(--bone);
  color: var(--ink);
}
.cf-textarea { min-height: 8.5rem; resize: vertical; }
.cf-input:focus, .cf-textarea:focus { border-color: var(--green); outline-offset: 1px; }

.cf-submit {
  font-family: var(--ui);
  font-size: 1rem;
  font-weight: 600;
  padding: 0.95rem 2rem;
  border: 1.5px solid transparent;
  border-radius: 2px;
  background: var(--green);
  color: #fff;
  cursor: pointer;
  transition: background-color 0.18s ease;
}
.cf-submit:hover { background: var(--green-deep); }

.cf-turnstile { margin-bottom: 1.25rem; }

/* ------------------------------------------------------------- prose --- */

.prose-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: clamp(2rem, 5vw, 4.5rem);
  align-items: start;
}

/* Where one side is a pull quote, the columns are NOT equal. A two-line quote
   in a half-width column leaves a tall wall of prose beside a near-empty peer,
   and an equal column is the wrong measure for a pull quote anyway: narrow is
   what makes one read as a quote rather than as a stray large paragraph.
   Match the width to the content, on whichever side the quote sits. */
.prose-grid:has(> .pullquote:first-child) {
  grid-template-columns: minmax(0, 24rem) minmax(0, 1fr);
}
.prose-grid:has(> .pullquote:last-child) {
  grid-template-columns: minmax(0, 1fr) minmax(0, 24rem);
}

/* A portrait is a narrow, tall thing, and a half-width column beside a dense
   board is a half-width column of almost no content. */
.prose-grid--portrait { grid-template-columns: minmax(0, 1fr) minmax(0, 19rem); }
.slot--portrait { aspect-ratio: 4 / 5; }

@media (max-width: 52rem) {
  .prose-grid,
  .prose-grid:has(> .pullquote:first-child),
  .prose-grid:has(> .pullquote:last-child) { grid-template-columns: 1fr; }
}

.pullquote {
  font-family: var(--display);
  font-size: clamp(1.5rem, 2.8vw, 2.1rem);
  line-height: 1.25;
  letter-spacing: -0.025em;
  border-left: 3px solid var(--green);
  padding-left: 1.5rem;
  margin: 0;
  max-width: 30ch;
}
.on-navy .pullquote { border-left-color: var(--mint); }

.address {
  font-style: normal;
  font-family: var(--display);
  font-size: 1.2rem;
  line-height: 1.45;
  letter-spacing: -0.015em;
  margin: 0 0 1rem;
}

/* -------------------------------------------------------------- form --- */

.form-wrap {
  background: var(--bone-sink);
  border: 1px solid var(--rule);
  padding: clamp(1.75rem, 4vw, 2.75rem);
}

.field { margin-bottom: 1.35rem; }

.field label {
  display: block;
  font-size: 0.9rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  margin-bottom: 0.45rem;
}

.field input,
.field textarea,
.field select {
  width: 100%;
  font-family: var(--ui);
  font-size: 1.0625rem;
  padding: 0.85rem 1rem;
  border: 1.5px solid var(--rule-strong);
  border-radius: 2px;
  background: var(--bone);
  color: var(--ink);
}
.field textarea { min-height: 8.5rem; resize: vertical; }
.field input:focus, .field textarea:focus, .field select:focus { border-color: var(--green); }

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

.foot {
  background: var(--navy);
  color: var(--on-navy);
  padding-block: clamp(3.5rem, 7vw, 5rem) 2rem;
}

.foot__grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr));
  gap: clamp(2rem, 4vw, 3.5rem);
}

.foot h2 {
  font-size: 1.05rem;
  font-family: var(--ui);
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--mint);
  margin-bottom: 1.1rem;
}

.foot a { color: var(--on-navy-dim); text-decoration: none; }
.foot a:hover { color: var(--on-navy); text-decoration: underline; }

.foot ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0.6rem; }

.foot p { color: var(--on-navy-dim); font-size: 1rem; }

.foot__base {
  margin-top: clamp(2.5rem, 5vw, 3.5rem);
  padding-top: 1.75rem;
  border-top: 1px solid var(--rule-navy);
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
  justify-content: space-between;
  align-items: center;
  font-size: 0.875rem;
  color: var(--on-navy-dim);
}

.credit a { color: var(--on-navy-dim); text-decoration: underline; }
.credit a:hover { color: var(--mint); }

/* --------------------------------------------------------------- dock -- */

.dock {
  position: fixed;
  right: clamp(1rem, 3vw, 1.75rem);
  bottom: calc(var(--dock-h) + clamp(1rem, 3vw, 1.75rem));
  z-index: 95;
  display: flex;
  flex-direction: column;
  gap: 0.7rem;
  /* Round 12 (chg-ddfcf124) - she asked for this to pop up as you scroll
     rather than sitting on screen from the first frame. site.js toggles
     .is-visible once you've scrolled past the header; reduced-motion users
     still get the toggle, just without the animated transition (the global
     rule above collapses transition-duration to ~0). */
  opacity: 0;
  transform: translateY(12px);
  pointer-events: none;
  transition: opacity 0.25s ease, transform 0.25s ease;
}
.dock.is-visible {
  opacity: 1;
  transform: translateY(0);
  pointer-events: auto;
}

.dock a {
  width: 54px;
  height: 54px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  box-shadow: 0 6px 20px rgba(8, 24, 33, 0.28);
  text-decoration: none;
  transition: transform 0.16s ease;
}
.dock a:hover { transform: translateY(-2px); }
.dock svg { width: 26px; height: 26px; }

.dock__wa { background: #25D366; }
/* 2026-09-28 (chg-4e5c7f16) - she asked for the WhatsApp button to be bigger
   and to pop as you scroll. site.js adds .is-popping while the page is
   scrolling; each pop runs once, so a long scroll gives a steady beat and it
   rests the moment scrolling stops. Reduced motion: no pop (global rule). */
.dock a.dock__wa { width: 66px; height: 66px; }
.dock__wa svg { width: 34px; height: 34px; }
.dock__wa.is-popping { animation: wa-pop 0.9s ease-out; }
@keyframes wa-pop {
  0%   { transform: scale(1);    box-shadow: 0 6px 20px rgba(8, 24, 33, 0.28), 0 0 0 0 rgba(37, 211, 102, 0.55); }
  35%  { transform: scale(1.2);  box-shadow: 0 8px 24px rgba(8, 24, 33, 0.3), 0 0 0 10px rgba(37, 211, 102, 0.25); }
  100% { transform: scale(1);    box-shadow: 0 6px 20px rgba(8, 24, 33, 0.28), 0 0 0 18px rgba(37, 211, 102, 0); }
}
.dock__call { background: var(--green); }
/* 2026-09-29 (chg-df36b1f1) - the floating Call shows the number too, in a
   pill to its left, whenever the cursor is on it. The dock is desktop-only. */
.dock__call { position: relative; }
.dock__num {
  position: absolute;
  right: calc(100% + 0.7rem);
  top: 50%;
  transform: translate(6px, -50%);
  background: #fff;
  color: var(--navy);
  font-family: var(--ui);
  font-size: 1rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  white-space: nowrap;
  padding: 0.6rem 0.95rem;
  border-radius: 3px;
  box-shadow: 0 12px 34px rgba(8, 24, 33, 0.34);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.16s ease, transform 0.16s ease;
}
/* 2026-09-30 (chg-5a8ac823) - the pill beside the round button keeps
   both numbers on one line, split by a rule, so it stays a pill. */
.dock__num .tel-line { display: inline-block; }
.dock__num .tel-line + .tel-line {
  margin: 0 0 0 0.7rem;
  padding-left: 0.7rem;
  border-left: 1px solid var(--rule-strong);
}
.dock__call:hover .dock__num,
.dock__call:focus-visible .dock__num { opacity: 1; transform: translate(0, -50%); }

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

.reveal {
  opacity: 0;
  transform: translateY(18px);
  transition: opacity 0.6s ease, transform 0.6s cubic-bezier(0.2, 0.7, 0.2, 1);
}
.reveal.is-in { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  .reveal { opacity: 1; transform: none; transition: none; }
}

/* ---------------------------------------------------------- utilities -- */

.stack-sm > * + * { margin-top: 1rem; }
.stack > * + * { margin-top: 1.75rem; }
.stack-lg > * + * { margin-top: 3rem; }

/* Top-aligned, never bottom-aligned. Bottom-aligning a one-paragraph note
   against a three-line headline strands the note low with a void above it;
   the small margin instead drops it to meet the headline's first line. */
.split-head {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 24rem);
  gap: clamp(1.5rem, 4vw, 3.5rem);
  align-items: start;
  margin-bottom: 1rem;
}
.split-head > .note { margin-top: 0.6rem; }
@media (max-width: 58rem) {
  .split-head { grid-template-columns: 1fr; }
  .split-head > .note { margin-top: 0; }
}

.note {
  font-size: 0.95rem;
  color: var(--ink-muted);
  border-left: 2px solid var(--rule-strong);
  padding-left: 1rem;
  max-width: 34rem;
}
.on-navy .note { color: var(--on-navy-dim); border-left-color: var(--rule-navy); }

/* --------------------------------------------------------- flight --- */

/* 2026-09-29 (chg-371baae9) - she asked for an aeroplane departing one place
   and reaching another beside "Come for the dentistry" on the dental tourism
   page. A drawn route under the pull quote: the plane takes off from Home,
   the trail fills in behind it, and Chennai pulses as it lands. The motion
   is SVG's own (animateMotion), so it follows the route at any width.
   Reduced motion: the moving plane and trail go, and a still plane sits at
   the top of the arc. */
.flight { margin: clamp(1.5rem, 4vw, 2.5rem) 0 0; max-width: 24rem; }
.flight svg { display: block; width: 100%; height: auto; overflow: visible; }
.flight__route {
  fill: none;
  stroke: var(--rule-strong);
  stroke-width: 1.6;
  stroke-dasharray: 2 7;
  stroke-linecap: round;
}
.flight__trail {
  fill: none;
  stroke: var(--green);
  stroke-width: 2;
  stroke-linecap: round;
  stroke-dasharray: 1;
  stroke-dashoffset: 1;
}
.flight__pin { fill: var(--green); stroke: var(--bone); stroke-width: 3; }
.flight__halo { fill: none; stroke: var(--green); stroke-width: 1.5; opacity: 0; }
.flight__label {
  font-family: var(--ui);
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  fill: var(--ink-muted);
  text-anchor: middle;
}
.flight__plane { fill: var(--navy); }
.flight__plane--still { display: none; }
@media (prefers-reduced-motion: reduce) {
  .flight__plane--moving, .flight__trail, .flight__halo { display: none; }
  .flight__plane--still { display: inline; }
}

/* 2026-09-30 (chg-61600fbd) - she asked for people arriving from many places
   across the world, all ending at Prashanth Dental, Velachery. The same idiom
   on a dotted world map: six routes, a plane on each in turn, and the pin
   pulsing at every landing. The labels take their anchor from a class
   (the base rule centres them, and CSS outranks the attribute), the city names give way to the caption on
   narrow screens where they would be too small to read, and reduced motion
   keeps the map, the routes and the pins. */
.flight--world { max-width: 34rem; }
.flight--world .flight__label { font-size: 11px; letter-spacing: 0.08em; paint-order: stroke; stroke: var(--bone); stroke-width: 4px; stroke-linejoin: round; }
.flight__label--start { text-anchor: start; }
.flight__label--end { text-anchor: end; }
.flight--world .flight__label--to { font-size: 14px; fill: var(--navy); }
.flight__land { fill: none; stroke: var(--navy); stroke-opacity: 0.2; stroke-width: 3.4; stroke-linecap: round; }
.flight--world .flight__route { stroke-width: 1.2; stroke-dasharray: 2 5; }
.flight--world .flight__trail { stroke-width: 1.8; }
.flight__pin--from { fill: var(--navy); stroke-width: 2; }
.flight__leader { stroke: var(--green); stroke-width: 1.2; }
.flight__cap {
  margin-top: 0.75rem;
  font-family: var(--ui);
  font-size: 0.875rem;
  line-height: 1.45;
  color: var(--ink-muted);
}
@media (max-width: 40rem) {
  .flight__label--from { display: none; }
}

/* 2026-09-29 (chg-df36b1f1) - she asked for an animated picture that suits
   multidisciplinary care beside "Dentistry is not separate from the rest of
   medicine". The tooth sits at the centre of a ring of the page's own
   department marks; each spoke draws in, then a pulse runs from every
   department to the tooth in turn and the centre answers. Motion is SVG's own
   (SMIL), like .flight. Reduced motion: the pulses and halo go, and the
   drawing is simply there. */
.pagehead__split {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 22rem);
  gap: clamp(1.5rem, 4vw, 4rem);
  align-items: start;
  margin-top: 1.5rem;
}
.pagehead__split .lede { margin-top: 0; }
@media (max-width: 48rem) {
  .pagehead__split { grid-template-columns: minmax(0, 1fr); }
  .caremap { max-width: 20rem; justify-self: center; width: 100%; }
}
.caremap { margin: 0; }
.caremap svg { display: block; width: 100%; height: auto; overflow: visible; }
.caremap__ring {
  fill: none;
  stroke: var(--rule-strong);
  stroke-width: 1.4;
  stroke-dasharray: 2 7;
  stroke-linecap: round;
}
.caremap__spoke {
  fill: none;
  stroke: var(--green);
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-dasharray: 1;
  stroke-dashoffset: 1;
  animation: draw 0.6s cubic-bezier(0.5, 0, 0.2, 1) forwards;
  animation-delay: calc(0.3s + var(--i) * 0.08s);
}
.caremap__node > circle { fill: #fff; stroke: var(--rule-strong); stroke-width: 1.2; }
.caremap__icon * {
  fill: none;
  stroke: var(--green);
  stroke-width: 1.7;
  stroke-linecap: round;
  stroke-linejoin: round;
  vector-effect: non-scaling-stroke;
}
.caremap__icon .caremap__fill { fill: var(--mint); stroke: none; }
.caremap__node { animation: caremap-in 0.5s ease-out both; animation-delay: calc(var(--i) * 0.08s); }
@keyframes caremap-in { from { opacity: 0; } to { opacity: 1; } }
.caremap__hub { fill: var(--navy); }
.caremap__tooth {
  fill: none;
  stroke: var(--on-navy);
  stroke-width: 1.8;
  stroke-linejoin: round;
  vector-effect: non-scaling-stroke;
}
.caremap__halo { fill: none; stroke: var(--mint); stroke-width: 2; }
.caremap__pulse { fill: var(--green); }
@media (prefers-reduced-motion: reduce) {
  .caremap__pulse, .caremap__halo { display: none; }
  .caremap__spoke { stroke-dashoffset: 0; }
}

/* ================================================= 2026-10-03, chg-8d4256d0 */

/* ---- the top bar stays on screen, and has some colour ------------------- */
/* Her ask, pinning Menu: "I WANT THE MENU TO BE VISIBLE AT ALL THE TIME EVEN
   WHEN WE SCROLL THROUGH THE PAGE" and "THIS MENU BAR CAN BE LITTLE COLORFUL
   AND AESTHETIC". The top bar now sticks to the top of the window on every
   screen; on a wide screen the action bar sticks just under it (--mast-h is
   the top bar's measured height, set by site.js). Colour: a soft wash from
   white (behind the logo, which needs it) to a pale mint, a green-to-blue
   line along the bottom edge, and the page you are on shown as a green
   pill. */
.masthead {
  position: sticky;
  top: 0;
  z-index: 85;
  background: linear-gradient(90deg, #FFFFFF 0%, #FFFFFF 22%, #E9F6F0 62%, #D3ECE2 100%);
  border-bottom: 0;
  box-shadow: 0 2px 12px rgba(8, 24, 33, 0.08);
}
.masthead::after {
  content: "";
  display: block;
  height: 3px;
  background: linear-gradient(90deg, var(--green) 0%, var(--mint) 50%, var(--actions-bg) 100%);
}
.masthead__bar { padding-block: 0.8rem; }
.nav { gap: 0.3rem; }
.nav a {
  color: var(--ink);
  font-weight: 600;
  padding: 0.4rem 0.75rem;
  border-bottom: 0;
  border-radius: 999px;
  transition: color 0.15s ease, background-color 0.15s ease;
}
.nav a:hover { color: var(--green-deep); background: rgba(31, 106, 87, 0.12); }
.nav a[aria-current="page"] { color: #fff; background: var(--green); }
.nav-toggle {
  background: var(--green);
  border-color: var(--green);
  color: #fff;
  border-radius: 999px;
  padding: 0.55rem 1.15rem;
}
@media (min-width: 48.0625rem) {
  .actions { top: var(--mast-h, 4.5rem); }
}
/* Between a phone and a wide screen the links used to hide behind the Menu
   button (it is what she pinned). There is room for them on a line of their
   own under the name, so they are always in sight there too. */
@media (min-width: 48.0625rem) and (max-width: 62rem) {
  .nav-toggle { display: none; }
  .masthead__bar { row-gap: 0.45rem; padding-block: 0.6rem 0.5rem; }
  .nav,
  .nav[data-open="true"] {
    display: flex;
    flex-direction: row;
    flex-wrap: nowrap;
    align-items: center;
    justify-content: space-between;
    width: 100%;
    gap: 0.15rem;
    padding-bottom: 0;
  }
  .nav a { padding: 0.3rem 0.6rem; border-bottom: 0; font-size: 0.9rem; }
}
@media (max-width: 48rem) {
  .masthead__bar { padding-block: 0.65rem; }
  /* The open menu must never be taller than the window it is stuck to. */
  .nav[data-open="true"] { max-height: calc(100svh - 9.5rem); overflow-y: auto; padding-bottom: 0.5rem; }
  .nav a { border-radius: 6px; padding: 0.8rem 0.75rem; border-bottom: 0; }
  .nav a + a { margin-top: 0.15rem; }
}

/* ---- the caption line has a lighter colour of its own ------------------- */
/* Her ask, pinning "Comprehensive treatment": "MAKE THE COLOR OF THIS ENTIRE
   BAR LITTLE AESTHETIC AND MAKE IT DIFFERENTIABLE FROM THE REST BY LIGHTENING
   ITS COLOR". It was the same navy as the banner above it. Now a pale mint
   with dark lettering (11.6:1) and green dots, on every page. */
.ticker {
  background: linear-gradient(90deg, #D9F0E7 0%, #E8F6F1 50%, #D9F0E7 100%);
  color: #12384A;
  border-bottom: 1px solid #B9DDCF;
}
.ticker--hero { border-top: 1px solid #B9DDCF; }
.ticker__track li::after { background: var(--green); }

/* ---- the floating Call pops too, in turn with WhatsApp ------------------ */
/* Her ask, pinning the green Call button: "MAKE THIS ICON ALSO TO POP UP
   ALTERNATIVELY WITH THE WHATSAPP ICON". site.js gives the two buttons the
   pop in turn while the page scrolls: WhatsApp, then Call, then WhatsApp. */
.dock__call.is-popping { animation: call-pop 0.9s ease-out; }
@keyframes call-pop {
  0%   { transform: scale(1);    box-shadow: 0 6px 20px rgba(8, 24, 33, 0.28), 0 0 0 0 rgba(31, 106, 87, 0.55); }
  35%  { transform: scale(1.22); box-shadow: 0 8px 24px rgba(8, 24, 33, 0.3), 0 0 0 10px rgba(31, 106, 87, 0.25); }
  100% { transform: scale(1);    box-shadow: 0 6px 20px rgba(8, 24, 33, 0.28), 0 0 0 18px rgba(31, 106, 87, 0); }
}

/* ---- your visit, step by step: drawings and a coloured ground ----------- */
/* Her ask: "ADD SOME ANIMATED IMAGES FOR THIS STEP BY STEP ... AND ALSO GIVE
   SOME SUBTLE COLOURS TO THE BACKGROUND SINCE THE BACKGROUND LOOKS VERY
   PLAIN". Home page only (.visit / .rail--art); the timelines on the other
   pages are as they were. */
.visit {
  background:
    radial-gradient(38rem 22rem at 8% 0%, rgba(111, 191, 165, 0.26), transparent 70%),
    radial-gradient(34rem 22rem at 96% 100%, rgba(63, 115, 144, 0.18), transparent 70%),
    linear-gradient(180deg, #EEF7F3 0%, #F3F1FA 100%);
}
.rail--art { border-left-color: #A9D3C4; }
.rail--art .stop {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  column-gap: 1.25rem;
  align-content: start;
  background: #fff;
  border: 1px solid #D5E7DF;
  border-radius: 10px;
  padding: 1.25rem 1.4rem 1.35rem;
  box-shadow: 0 8px 24px rgba(15, 43, 58, 0.07);
}
.rail--art .stop > * { grid-column: 1; }
.rail--art .stop::before { top: 1.7rem; border-color: #EEF7F3; }
.rail--art .stop__art {
  grid-column: 2;
  grid-row: 1 / span 3;
  align-self: center;
  width: clamp(4.25rem, 15vw, 6.5rem);
  height: auto;
  padding: 0.9rem;
  border-radius: 50%;
  background: linear-gradient(135deg, #E2F3EC 0%, #E4EEF6 100%);
  overflow: visible;
}
.stop__art .ink {
  fill: none;
  stroke: #1D4A5F;
  stroke-width: 2.4;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.stop__art .ink.soft { stroke: #7FA6B5; }
.stop__art .ink.fill { fill: #fff; }
.stop__art .ink.accent { stroke: var(--green); stroke-width: 2.8; }
.stop__art .dot { fill: var(--green); }

.stop.is-in .art-tick { stroke-dasharray: 1; animation: art-tick 3.6s ease-in-out infinite; }
.stop.is-in .art-tick--2 { animation-delay: 0.5s; }
.stop.is-in .art-tick--3 { animation-delay: 1s; }
.stop.is-in .art-dot { animation: art-dot 1.5s ease-in-out infinite; transform-box: fill-box; transform-origin: center; }
.stop.is-in .art-dot--2 { animation-delay: 0.2s; }
.stop.is-in .art-dot--3 { animation-delay: 0.4s; }
.stop.is-in .art-scan { animation: art-scan 2.8s ease-in-out infinite; }
.stop.is-in .art-twinkle { animation: art-twinkle 2.4s ease-in-out infinite; transform-box: fill-box; transform-origin: center; }
.stop.is-in .art-twinkle--2 { animation-delay: 0.8s; }
.stop.is-in .art-twinkle--3 { animation-delay: 1.6s; }
@keyframes art-tick {
  0%, 8% { stroke-dashoffset: 1; }
  30%, 88% { stroke-dashoffset: 0; opacity: 1; }
  100% { stroke-dashoffset: 0; opacity: 0; }
}
@keyframes art-dot {
  0%, 60%, 100% { transform: translateY(0); opacity: 0.45; }
  30% { transform: translateY(-4px); opacity: 1; }
}
@keyframes art-scan {
  0%, 100% { transform: translateY(-17px); }
  50% { transform: translateY(17px); }
}
@keyframes art-twinkle {
  0%, 100% { transform: scale(0.45); opacity: 0.25; }
  50% { transform: scale(1); opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
  .stop.is-in .art-tick, .stop.is-in .art-dot, .stop.is-in .art-scan,
  .stop.is-in .art-twinkle { animation: none; }
}
@media (min-width: 62rem) {
  /* Five cards across: the drawing on top, then the step, its name, its
     points, each on a shared line (subgrid) so the cards match. */
  .rail--points.rail--art {
    grid-template-rows: auto auto auto 1fr;
    column-gap: 1.1rem;
    border-top-color: #A9D3C4;
  }
  .rail--points.rail--art .stop {
    grid-row: span 4;
    grid-template-columns: minmax(0, 1fr);
    padding: 1.4rem 1.15rem 1.5rem;
  }
  .rail--points.rail--art .stop::before { left: 1.15rem; top: calc(-2rem - 7px); }
  .rail--art .stop__art {
    grid-column: 1;
    grid-row: auto;
    align-self: start;
    width: 5.25rem;
    margin-bottom: 1.1rem;
  }
}

/* ------------------------------------------------ patients who travelled --
   2026-10-07 (chg-851a2cf1): her first travelling patient, photo and review
   as she sent them. The collage is hers, shown whole at its own square shape
   (before above, after below), never cropped. A named review, so no eye band
   (that rule is for the anonymous clinical photos on treatments.html). The
   three striped placeholders it replaces were ours. A second story is one
   more figure.traveller; they stack, alternating sides. */
.travellers { display: grid; gap: clamp(2rem, 5vw, 3.5rem); margin-top: 3rem; }
.traveller {
  margin: 0;
  display: grid;
  gap: 1.5rem;
  align-items: center;
}
.traveller__photo {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 1 / 1;
  border: 1px solid var(--rule);
  background: #fff;
}
.traveller__words { display: flex; flex-direction: column; gap: 1.1rem; border-top: 2px solid var(--green); padding-top: 1.5rem; }
.traveller__words blockquote { margin: 0; }
.traveller__words blockquote p {
  margin: 0;
  font-family: var(--display);
  font-size: clamp(1.35rem, 2.4vw, 1.9rem);
  line-height: 1.4;
  letter-spacing: -0.015em;
  color: var(--ink);
}
.traveller__name {
  margin: 0;
  font-size: 0.875rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  font-weight: 600;
  color: var(--green);
}
@media (min-width: 48.0625rem) {
  .traveller { grid-template-columns: minmax(0, 5fr) minmax(0, 6fr); gap: clamp(2rem, 5vw, 4.5rem); }
  .traveller:nth-child(even) .traveller__photo { order: 2; }
}

/* ================================================= 2026-10-10, chg-2b06aaf0 */

/* ---- the action bar: Book is gone, Align Dental Care's logo at its left,
   and the Call card ---------------------------------------------------------
   Her ask: "MAKE THIS CALL ICON AND THE PHONE NUMBERS TO APPEAR SAME LIKE
   ALIGNDENTAL.IN WHERE THE PHONE NUMBERS APPEAR VERY NEATLY", "REMOVE THIS
   PARTICULAR ICON" (Book) and "ADD THE LOGO OF ALIGN DENTAL CENTRE IN THIS
   BAR AT LEFT CORNER". The Call card follows aligndental.in's: a title, then
   one row per number with its kind on the left and the number on the right,
   each row its own link (so the card sits beside the call link, not inside
   it). The logo is on a white chip, the ground it was drawn for. Phones keep
   four buttons at thumb level and no logo: the bar there is for tapping. */
.actions__brand {
  flex: 0 0 auto;
  align-self: center;
  display: inline-flex;
  align-items: center;
  margin-right: 0.75rem;
  padding: 0.3rem 0.65rem;
  background: #fff;
  border-radius: 10px;
  box-shadow: 0 2px 8px rgba(8, 24, 33, 0.18);
  transition: transform 0.18s ease, box-shadow 0.18s ease;
}
.actions__brand img { display: block; height: 40px; width: auto; }
.actions__brand:hover { transform: translateY(-1px); box-shadow: 0 6px 14px rgba(8, 24, 33, 0.26); }
.actions__brand:focus-visible { outline: 3px solid var(--mint); outline-offset: 2px; }
@media (max-width: 48rem) {
  .actions__brand { display: none; }
}
@media (prefers-reduced-motion: reduce) {
  .actions__brand, .actions__brand:hover { transition: none; transform: none; }
}

.action--call { padding: 0; }
.action--call > .action__hit {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.3rem;
  width: 100%;
  height: 100%;
  padding: 0.7rem 0.4rem;
  color: inherit;
  text-decoration: none;
}
.action--call > .action__hit:focus-visible { outline: 3px solid var(--mint); outline-offset: -3px; }

.action__qr--tel {
  width: 16rem;
  padding: 0.9rem 0.85rem 0.85rem;
  white-space: normal;
  text-align: left;
  border: 0;
  border-radius: 10px;
  border-top: 3px solid var(--green);
}
.tel-card__title {
  margin: 0 0 0.7rem;
  text-align: center;
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  line-height: 1.5;
  text-transform: uppercase;
  color: var(--ink-muted);
}
.tel-card__list { list-style: none; margin: 0; padding: 0; }
.tel-card__list li + li { margin-top: 0.45rem; }
.tel-card__list a {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.75rem;
  padding: 0.55rem 0.75rem;
  border: 1px solid var(--rule);
  border-radius: 8px;
  background: #F4FAF7;
  color: var(--green-deep);
  text-decoration: none;
  font-size: 1rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.tel-card__list a:hover { border-color: var(--green); background: #E3F2EB; }
.tel-card__list a:focus-visible { outline: 3px solid var(--mint); outline-offset: 1px; }
.tel-card__kind {
  font-size: 0.66rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-muted);
}
.action--call:hover .action__qr:not([popover]),
.action--call:focus-within .action__qr:not([popover]) { display: block; }

/* ---- the Invisalign page (2026-10-10, chg-2b06aaf0) ----------------------
   Her ask: a section for Invisalign near Treatments, with every Invisalign
   photograph from aligndental.in. Each photograph shows whole, at its own
   shape, never cut to a slot: the three tray pictures in a row, the four
   patients in a three-column flow. A tap enlarges one, as on aligndental.in. */
.photo-grid { display: grid; gap: clamp(0.75rem, 2vw, 1.25rem); align-items: start; }
.photo-grid--wide { grid-template-columns: repeat(3, minmax(0, 1fr)); margin-bottom: clamp(2rem, 5vw, 3.5rem); }
/* a justified row: each photograph's width follows its shape (--r, width over
   height), so every one in a row stands the same height and none is cut */
.photo-grid--people { display: flex; flex-wrap: wrap; margin-top: 2rem; }
.photo-grid--people .photo-grid__item { flex: var(--r) 1 calc(var(--r) * 10rem); }
.photo-grid__item {
  display: block;
  border-radius: 6px;
  overflow: hidden;
  box-shadow: 0 6px 18px rgba(8, 24, 33, 0.14);
  cursor: zoom-in;
}
.photo-grid__item img { display: block; width: 100%; height: auto; transition: transform 0.3s ease; }
/* the three tray pictures share one height: two are 16:9 already, and the
   3:2 fitting shot loses only plain lip and chin above and below its tray */
.photo-grid--wide .photo-grid__item img { aspect-ratio: 16 / 9; object-fit: cover; }
.photo-grid__item:hover img { transform: scale(1.02); }
.photo-grid__item:focus-visible { outline: 3px solid var(--mint); outline-offset: 3px; }
@media (max-width: 48rem) {
  .photo-grid--wide { grid-template-columns: minmax(0, 1fr); }
}
@media (prefers-reduced-motion: reduce) {
  .photo-grid__item img, .photo-grid__item:hover img { transition: none; transform: none; }
}

.enlarge {
  padding: 0;
  border: 0;
  background: transparent;
  max-width: min(92vw, 1400px);
  max-height: 92vh;
  overflow: visible;
}
.enlarge::backdrop { background: rgba(8, 24, 33, 0.86); }
.enlarge img { display: block; max-width: min(92vw, 1400px); max-height: 92vh; width: auto; height: auto; border-radius: 6px; }
.enlarge form { position: absolute; top: 0.5rem; right: 0.5rem; margin: 0; }
.enlarge__close {
  width: 2.5rem; height: 2.5rem;
  border: 0; border-radius: 999px;
  background: rgba(255, 255, 255, 0.92); color: var(--ink);
  font-size: 1.5rem; line-height: 1; cursor: pointer;
}

/* "Prashanth Dental Centre" is two letters longer than the name it replaced
   (her ask, 10 Oct). On a 390px phone it no longer fitted beside Menu and
   left "Centre" alone on a second line, so the name is a touch smaller and
   Menu a touch narrower there. Below about 370px it wraps, as the old name did. */
@media (max-width: 30rem) {
  .wordmark { gap: 0.5rem; }
  .wordmark__name { font-size: 0.95rem; }
  .nav-toggle { padding-inline: 0.9rem; }
}

/* ======================================================= 2026-10-11 ===
   chg-78e48be9, eleven asks across five pages. Rules here override the
   ones above; change them here. */

/* Home: the Dental tourism world map behind the opening text (her ask: "AS
   THE BACKGROUND WHERE IT SHOULD LOOK VERY NEAT AND ELEGANT"). It sits in
   the right half, under the strapline, and fades out towards the headline
   so no word crosses a dot. Recoloured for the navy: pale dots, mint routes,
   white planes. */
.hero__intro { overflow: hidden; }
.hero__flight {
  position: absolute;
  right: max(1.25rem, calc((100vw - 80rem) / 2));
  bottom: 7%;
  width: min(44vw, 38rem);
  max-width: none;
  margin: 0;
  pointer-events: none;
  -webkit-mask-image: linear-gradient(to right, transparent 0, #000 22%);
          mask-image: linear-gradient(to right, transparent 0, #000 22%);
}
.hero__grid { position: relative; z-index: 1; }
.hero__flight .flight__land { stroke: var(--on-navy); stroke-opacity: 0.16; }
.hero__flight .flight__route { stroke: var(--mint); stroke-opacity: 0.45; }
.hero__flight .flight__trail { stroke: var(--mint); }
.hero__flight .flight__pin { fill: var(--mint); stroke: var(--navy); }
.hero__flight .flight__pin--from { fill: var(--on-navy-dim); stroke: var(--navy); }
.hero__flight .flight__halo { stroke: var(--mint); }
.hero__flight .flight__leader { stroke: var(--mint); stroke-opacity: 0.6; }
.hero__flight .flight__plane { fill: var(--on-navy); }
.hero__flight .flight__label {
  font-size: 9px;
  fill: var(--on-navy-dim);
  fill-opacity: 0.75;
  stroke: var(--navy);
}
.hero__flight .flight__label--to { font-size: 11px; fill: var(--mint); fill-opacity: 1; }
@media (max-width: 58rem) {
  /* Phones: under the words, as texture, the city names off. */
  .hero__flight { width: 120vw; right: -30vw; bottom: 0; opacity: 0.5; }
  .hero__flight .flight__label { display: none; }
}

/* Dental tourism: the map at the top of its section, full width, and easier
   to see (her ask: "BRING THIS ANIMATED IMAGE UP AND MAKE IT NICELY
   VISIBLE"). Darker dots, bolder routes, bigger pins and planes. */
.flight-lead { margin-bottom: clamp(2.5rem, 5vw, 4rem); }
.flight-lead .pullquote { max-width: none; }
.flight--big { max-width: 60rem; margin-inline: auto; margin-top: clamp(1.5rem, 3vw, 2.25rem); }
.flight--big .flight__land { stroke-opacity: 0.38; stroke-width: 3.6; }
.flight--big .flight__route { stroke: var(--green); stroke-opacity: 0.55; stroke-width: 1.4; stroke-dasharray: 2 4; }
.flight--big .flight__trail { stroke-width: 2.4; }
.flight--big .flight__pin--from { r: 4.5; }
.flight--big .flight__label { font-size: 10px; fill: var(--ink); }
.flight--big .flight__label--to { font-size: 12px; fill: var(--green-deep); }
.flight--big .flight__plane path { transform: scale(0.8); }
.flight--big .flight__cap { text-align: center; }

/* Invisalign, "The aligners": one tray photo, larger, in a rounded frame
   with a mint ring (her ask: "LITTLE BIGGER ... WITHIN SOME CURVED BORDERS
   AND HIGHLIGHT THE IMAGE"). Shown at its own shape. */
.feature-photo {
  margin: 0 auto clamp(2.5rem, 5vw, 3.5rem);
  max-width: 46rem;
  padding: 0.5rem;
  border-radius: 1.75rem;
  background: linear-gradient(135deg, var(--mint), var(--green));
  box-shadow: 0 1.25rem 3rem rgba(15, 43, 58, 0.18);
}
.feature-photo__link { display: block; border-radius: 1.35rem; overflow: hidden; cursor: zoom-in; }
.feature-photo img { display: block; width: 100%; height: auto; }

/* Invisalign, "Collecting their aligners.": the team page's strip, taller,
   each photo at its own shape with rounded corners, tap to enlarge. */
.team-strip--people .team-strip__scroll { animation-duration: 40s; }
.team-strip__link { display: block; flex: 0 0 auto; cursor: zoom-in; }
.team-strip--people .team-strip__track img { height: clamp(15rem, 28vw, 21rem); border-radius: 6px; background: var(--navy-lift); }
.team-strip--people:focus-within .team-strip__scroll { animation-play-state: paused; }

/* Multidisciplinary care: a short questionnaire pops up over each
   department on hover, keyboard focus or a tap (site.js toggles .is-open). */
.mark--ask { position: relative; cursor: pointer; outline-offset: -3px; }
.mark__hint {
  margin: auto 0 0;
  font-family: var(--ui);
  font-size: 0.8rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--mint);
}
.mark__hint::before { content: "?"; display: inline-grid; place-items: center; width: 1.3rem; height: 1.3rem; margin-right: 0.5rem; border: 1.5px solid var(--mint); border-radius: 50%; font-size: 0.75rem; }
.mark__ask {
  position: absolute;
  inset: 0.5rem;
  z-index: 3;
  padding: 1.4rem 1.4rem 1.2rem;
  border-radius: 14px;
  background: var(--on-navy);
  color: var(--ink);
  box-shadow: 0 1.25rem 2.5rem rgba(5, 18, 26, 0.45);
  overflow-y: auto;
  opacity: 0;
  visibility: hidden;
  transform: translateY(0.5rem) scale(0.97);
  transition: opacity 0.2s ease, transform 0.2s ease, visibility 0s linear 0.2s;
}
@media (hover: hover) {
  .mark--ask:hover .mark__ask { opacity: 1; visibility: visible; transform: none; transition: opacity 0.2s ease, transform 0.2s ease; }
}
.mark--ask:focus-visible .mark__ask,
.mark--ask.is-open .mark__ask {
  opacity: 1;
  visibility: visible;
  transform: none;
  transition: opacity 0.2s ease, transform 0.2s ease;
}
.mark__ask-title {
  margin: 0 0 0.75rem;
  font-family: var(--ui);
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--green);
}
.mark__ask ul { margin: 0; padding: 0; list-style: none; display: flex; flex-direction: column; gap: 0.55rem; }
.mark__ask li { position: relative; padding-left: 1.1rem; font-size: 0.95rem; line-height: 1.4; }
.mark__ask li::before { content: ""; position: absolute; left: 0; top: 0.5em; width: 0.45rem; height: 0.45rem; border-radius: 50%; background: var(--mint); }
@media (prefers-reduced-motion: reduce) {
  .mark__ask { transform: none; transition: none; }
}

/* Every footer: her landline beside the mobile, and her other branch. */
.foot__branch p { margin-bottom: 0.9rem; }

/* ---- the Diseases page (chg-23755c69) ------------------------------------ */
/* Her guide, one group per cause, each condition opening on a tap (the .faq
   accordion). A new group is one more section.disease-group. */
.disease-group__head { display: flex; gap: clamp(1rem, 2.5vw, 1.75rem); align-items: flex-start; }
.disease-group__num {
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  width: clamp(2.75rem, 5vw, 3.5rem);
  aspect-ratio: 1;
  border-radius: 50%;
  background: var(--green);
  color: #fff;
  font-family: var(--display);
  font-size: clamp(1.3rem, 2.4vw, 1.7rem);
  font-weight: 500;
  box-shadow: 0 0 0 6px rgba(111, 191, 165, 0.28);
}
.disease-group__overview { margin-top: 1rem; font-size: 1.1rem; line-height: 1.55; color: var(--ink-muted); max-width: 46rem; }
.disease-group__overview strong { color: var(--ink); font-weight: 600; }
.disease-group__label {
  margin-top: clamp(2rem, 4vw, 2.75rem);
  font-family: var(--ui);
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--green);
}
.disease-group__list { margin-top: 0.9rem; max-width: 52rem; }
.disease-group__list summary:hover { color: var(--green-deep); }
.disease-group__list details > div p { max-width: 46rem; }

/* ---- nine menu links on a wide screen (chg-23755c69) --------------------- */
/* Diseases made the menu nine links. In one row beside the name they only fit
   from about 1360px, and below that Contact fell onto a line of its own (even
   eight did, between 993 and 1180px). So the links are a little more compact
   on every wide screen, and below 85rem they take a row of their own under the
   name, as they already do on a tablet. */
@media (min-width: 62.0625rem) {
  .nav { gap: 0.15rem; flex-wrap: nowrap; }
  .nav a { padding: 0.4rem 0.6rem; font-size: 0.9rem; }
}
@media (min-width: 62.0625rem) and (max-width: 85rem) {
  .masthead__bar { flex-wrap: wrap; row-gap: 0.45rem; padding-block: 0.6rem 0.5rem; }
  .nav { width: 100%; justify-content: space-between; }
}

/* ======================================================= 2026-10-13 ===
   chg-7be91ff3, four asks. Rules here override the ones above; change them
   here. */

/* Home, the opening screen (her ask: "THE IMAGE OF THAT ANIMATED FLIGHTS
   SHOULD COME FOR WHOLE PAGE ..MAKE THAT IMAGE LARGER WITH A LIGHT
   BACKGROUND ,SO THAT THAT IS THE MAIN SPOTLIGHT"). The panel is a pale mint
   wash instead of navy, the words sit in a compact band at the top, and the
   world map fills the rest of the screen, full width, under them rather than
   beside them. The photographs that follow it keep their navy frame. */
.hero > .hero__intro {
  display: flex;
  flex-direction: column;
  background: linear-gradient(170deg, #F8FBF9 0%, #EAF5F0 55%, #DDEFE7 100%);
  color: var(--ink);
}
.hero__intro .hero__grid { order: 1; padding-block: clamp(2.25rem, 5vw, 3.5rem) 0.5rem; }
.hero__intro h1 { color: var(--ink); }
.hero__intro .hero__standfirst { color: #3B4F58; }
.hero__intro .hero__caption { color: var(--ink-muted); border-left-color: var(--green); }
.hero__intro .hero__caption strong { color: var(--green); }
.hero__intro .btn--solid { background: var(--green); color: #fff; }
.hero__intro .btn--solid:hover { background: var(--green-deep); }
.hero__intro .btn--line { border-color: var(--rule-strong); color: var(--ink); background: rgba(255, 255, 255, 0.55); }
.hero__intro .btn--line:hover { border-color: var(--ink); }

.hero__flight {
  order: 2;
  position: relative;
  inset: auto;
  width: 100%;
  max-width: 82rem;
  margin: 0 auto;
  padding: 0.5rem var(--gutter) clamp(1.25rem, 3vw, 2.5rem);
  -webkit-mask-image: none;
          mask-image: none;
  opacity: 1;
}
.hero__flight .flight__land { stroke: var(--green); stroke-opacity: 0.26; }
.hero__flight .flight__route { stroke: var(--green-deep); stroke-opacity: 0.55; stroke-width: 1.3; }
.hero__flight .flight__trail { stroke: var(--green); stroke-width: 2.2; }
.hero__flight .flight__pin { fill: var(--green); stroke: #F4FAF7; }
.hero__flight .flight__pin--from { fill: var(--navy); stroke: #F4FAF7; }
.hero__flight .flight__halo { stroke: var(--green); }
.hero__flight .flight__leader { stroke: var(--green); stroke-opacity: 0.8; }
.hero__flight .flight__plane { fill: var(--navy); }
.hero__flight .flight__label {
  display: inline;
  font-size: 9px;
  fill: var(--ink-muted);
  fill-opacity: 1;
  stroke: #EEF7F3;
}
.hero__flight .flight__label--to { font-size: 11.5px; fill: var(--green-deep); }

/* Wide screens: one screen, words on top, the map taking all the height
   left (site.js sizes the screen; the words are what it measures). */
.hero.has-reel > .hero__intro { align-items: stretch; justify-content: flex-start; }
.hero.has-reel .hero__intro .hero__grid { grid-template-columns: minmax(0, 1fr); padding-block: clamp(1.75rem, 3.5vw, 2.75rem) 0; }
/* The strapline says what the ticker under this screen already says, word
   for word, so on this screen it gives its room to the map. */
.hero.has-reel .hero__intro .hero__caption { display: none; }
.hero.has-reel .hero__intro .hero__grid > div {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  grid-template-areas: "head head" "s1 btns" "s2 btns";
  column-gap: clamp(1.5rem, 3vw, 3rem);
  align-items: center;
}
.hero.has-reel .hero__intro h1 { grid-area: head; font-size: clamp(2.3rem, 3.4vw, 4rem); }
.hero.has-reel .hero__intro .hero__standfirst { grid-area: s1; align-self: end; margin-top: 0.8rem; max-width: 40rem; font-size: clamp(1rem, 1.15vw, 1.2rem); line-height: 1.45; }
.hero.has-reel .hero__intro .hero__standfirst + .hero__standfirst { grid-area: s2; align-self: start; margin-top: 0.3rem; }
.hero.has-reel .hero__intro .btn-row { grid-area: btns; margin-top: 0.8rem; flex-wrap: nowrap; }
.hero.has-reel .hero__flight { flex: 1 1 auto; min-height: 0; max-width: none; padding-block: 0.75rem 1rem; }
.hero.has-reel .hero__flight svg { height: 100%; }

@media (max-width: 58rem) {
  /* Phones and tablets: the map right under the words, full width, the city
     names kept and set larger so they can be read. */
  .hero__flight { width: 100%; right: auto; bottom: auto; padding-inline: 0.75rem; opacity: 1; }
  .hero__flight .flight__label { display: inline; font-size: 14px; }
  .hero__flight .flight__label--to { font-size: 16px; }
}

/* Reviews (patient-stories.html, "Reviews" in the menu; her ask: "DISPLAY
   THE REVIEWS ... A FEW IMPORTANT REVIEWS, REST YOU CAN NAVIGATE"). White
   cards with a mint top edge, the Google set first, then Practo, each set
   ending in a link to read the rest where they were written. */
.reviews { margin-top: clamp(2.5rem, 5vw, 3.5rem); }
.reviews__from {
  font-family: var(--ui);
  font-size: 0.8125rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  font-weight: 700;
  color: var(--green);
}
.reviews__grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 26rem), 1fr));
  gap: clamp(1rem, 2.2vw, 1.5rem);
  margin-top: 1rem;
  align-items: stretch;
}
.review {
  margin: 0;
  padding: 1.5rem 1.5rem 1.35rem;
  background: #fff;
  border-radius: 1.1rem;
  border-top: 4px solid var(--mint);
  box-shadow: 0 0.75rem 2rem rgba(15, 43, 58, 0.08);
  display: flex;
  flex-direction: column;
  gap: 0.9rem;
}
.review__mark { display: flex; gap: 0.15rem; margin: 0; font-family: var(--ui); font-size: 0.8125rem; font-weight: 600; color: var(--green); }
.review__mark svg { width: 1.05rem; height: 1.05rem; fill: #E2A93B; }
.review__text { margin: 0; font-family: var(--display); font-size: 1.12rem; line-height: 1.5; color: var(--ink); }
/* The name sits at the foot of each card, so cards in a row end level. */
.review__text { flex: 1 1 auto; }
.review__who { font-family: var(--ui); font-size: 0.95rem; font-weight: 600; color: var(--ink); display: flex; flex-wrap: wrap; justify-content: space-between; gap: 0.25rem 1rem; }
.review__where { font-weight: 600; font-size: 0.8125rem; color: var(--green); text-decoration: none; }
.review__where:hover { text-decoration: underline; }
.reviews__more { display: inline-block; margin-top: 1.1rem; font-family: var(--ui); font-weight: 600; color: var(--green); }
.reviews__more::after { content: " \2192"; }

/* Invisalign, "The aligners" (her ask: "THERE IS A LOT OF SPACE BETWEEN THE
   TEXT AND THE IMAGE.REDUCE THE SPACE AND THE IMAGE SHOULD BE VISIBLE
   NICELY"). On wide screens the photo and its three points sit side by side,
   the photo larger, each point's name directly over its words. Phones: the
   photo, then the points straight under it. */
.aligners { display: grid; gap: clamp(1.25rem, 3vw, 2.75rem); align-items: center; }
.aligners .feature-photo { margin: 0; max-width: none; }
.aligners .board__item { grid-template-columns: minmax(0, 1fr); gap: 0.35rem; padding-block: 1.1rem; }
.aligners .board__desc { max-width: none; }
@media (min-width: 56rem) {
  .aligners { grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr); }
}

/* Diseases, "What we treat": the list of names in boxes (13 Oct) became her
   categories and clouds on 14 Oct (see "category clouds" below). */
.pagehead + .treat { padding-top: clamp(1rem, 2.5vw, 2rem); }

/* ======================================================= 2026-10-14 ===
   chg-439807a7. Rules here override the ones above; change them here. */

/* Home, the opening screen is the main banner (her ask: "IT SHOULD BE THE
   MAIN HERO BANNER AND THE REST ALL HERO BANNERS SHOULD COME AFTER THAT").
   Wide screens: it holds a minute (site.js), then the photographs. Stacked
   (phones, tablets, no script, less motion): the opening first, the map at
   its top as its picture, then the photographs, then the caption line. */
.hero__reel { order: 1; }
.hero > .ticker { order: 2; }
@media (max-width: 48rem) {
  .hero:not(.has-reel) .hero__flight { order: 0; padding-block: 1rem 0; }
  .hero:not(.has-reel) .hero__intro .hero__grid { padding-block: 1.25rem 2.25rem; }
}
.hero__to-photos { display: none; }
.hero.has-reel .hero__to-photos {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  /* At the top right of the map, under the buttons: the opening is taller
     than a short laptop's window, so the foot of the map is below the fold. */
  order: 2;
  align-self: flex-end;
  position: relative;
  z-index: 1;
  margin: 0.6rem var(--gutter) -2.6rem 0;
  padding: 0.55rem 1.05rem;
  border: 1px solid var(--rule-strong);
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.75);
  color: var(--green-deep);
  font-family: var(--ui);
  font-size: 0.9375rem;
  font-weight: 600;
  cursor: pointer;
  transition: background 0.2s, border-color 0.2s;
}
.hero.has-reel .hero__flight { order: 3; }
.hero.has-reel .hero__to-photos:hover { background: #fff; border-color: var(--green); }
.hero.has-reel .hero__to-photos:focus-visible { outline: 2px solid var(--green); outline-offset: 3px; }


/* Invisalign (her ask: "PUT THE IMAGE IMMEDIATELY BELOW THE CLEAR ALIGNERS
   HEADING"). No rule and no band gap between the page heading and the
   photo; the intro line sits beside the photo, over the three points. */
.pagehead--photo-next { border-bottom: 0; padding-bottom: clamp(1rem, 2vw, 1.5rem); }
.pagehead--photo-next + .band { padding-top: 0; }
.aligners { align-items: start; }
.aligners__lede { margin: 0 0 0.5rem; font-size: clamp(1.05rem, 1.3vw, 1.25rem); }

/* A drawing beside a page heading: Multidisciplinary care (her ask: "THIS
   IMAGE CAN COME LITTLE UP.. NEAR THE HEADING ITSELF"), Reviews and Book an
   appointment (her asks for an animated image near each heading). Wide
   screens: the drawing in its own column, level with the eyebrow and heading,
   the intro line under the heading. Phones: the drawing straight under the
   heading, then the intro line. */
.pagehead--beside { display: grid; grid-template-columns: minmax(0, 1fr); column-gap: clamp(1.5rem, 4vw, 4rem); }
.pagehead--beside .pagehead__lede .lede { margin-top: 1.5rem; }
.pagehead--beside > .pagehead__art { max-width: 17rem; width: 100%; justify-self: center; margin: 1.25rem 0 0; }
@media (min-width: 48.0625rem) {
  .pagehead--beside { grid-template-columns: minmax(0, 1fr) minmax(0, 20rem); grid-template-rows: auto auto 1fr; }
  .pagehead--beside > :not(.pagehead__art) { grid-column: 1; }
  .pagehead--beside > .pagehead__art { grid-column: 2; grid-row: 1 / 4; align-self: center; margin-top: 0; max-width: none; }
}
@media (max-width: 48rem) {
  .pagehead--beside > .pagehead__art { grid-row: 3; }
  .pagehead--beside > .lede,
  .pagehead--beside > .pagehead__lede { grid-row: 4; }
}
.art { margin: 0; }
.art svg { display: block; width: 100%; height: auto; overflow: visible; }
.art__float { animation: art-float 4s ease-in-out infinite; }
@keyframes art-float { 50% { transform: translateY(-6px); } }
.art__star { transform-box: fill-box; transform-origin: center; animation: art-star 4.5s ease-out infinite; animation-delay: calc(var(--i) * 0.3s); }
@keyframes art-star {
  0%   { opacity: 0.15; transform: scale(0.6); }
  10%  { opacity: 1; transform: scale(1.25); }
  16%  { transform: scale(1); }
  80%  { opacity: 1; }
  100% { opacity: 0.15; transform: scale(0.6); }
}
.art__ring { stroke-dasharray: 1; stroke-dashoffset: 1; animation: art-ring 4s ease-in-out infinite; }
@keyframes art-ring { 0%, 10% { stroke-dashoffset: 1; } 40%, 85% { stroke-dashoffset: 0; } 100% { stroke-dashoffset: 1; } }
.art__tick { stroke-dasharray: 1; stroke-dashoffset: 1; animation: art-tick 4s ease-out infinite; }
@keyframes art-tick { 0%, 40% { stroke-dashoffset: 1; } 55%, 85% { stroke-dashoffset: 0; } 100% { stroke-dashoffset: 1; } }
.art__minute,
.art__hour { transform-box: view-box; transform-origin: 258px 196px; animation: art-turn 6s linear infinite; }
.art__hour { animation-duration: 72s; }
@keyframes art-turn { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
  .art__star, .art__float, .art__minute, .art__hour { animation: none; }
  .art__star { opacity: 1; }
  .art__ring, .art__tick { animation: none; stroke-dashoffset: 0; }
}

/* ---- every footer: the areas near her (chg-a239e643, 2026-10-14) -------- */
/* A row of its own under the four columns; beside "Our other branch" on a
   screen wide enough for the four columns, where that row is otherwise empty. */
.foot__near { grid-column: 1 / -1; }
@media (min-width: 75rem) {
  .foot__near { grid-column: span 3; }
}
.foot__near p { margin-bottom: 0.9rem; }
/* 2026-10-15 (chg-943fd42c), her ask: "THESE AREAS NEED NOT BE VISIBLE AS SUCH.. ONLY WHEN WE CLICK ON
   THAT.. THOSE AREAS SHOULD BE VISIBLE". The "is close to" line is the button; the chips open under it.
   The names stay in the page for search engines, closed or open. */
.foot__more summary {
  display: inline-flex;
  align-items: center;
  gap: 0.7rem;
  cursor: pointer;
  list-style: none;
  padding: 0.45rem 1rem;
  border: 1px solid var(--rule-navy);
  border-radius: 999px;
  color: var(--on-navy);
  font-size: 1rem;
  transition: border-color 0.2s ease, background-color 0.2s ease;
}
.foot__more summary::-webkit-details-marker { display: none; }
.foot__more summary::after {
  content: "";
  flex: none;
  width: 8px;
  height: 8px;
  border-right: 2px solid var(--mint);
  border-bottom: 2px solid var(--mint);
  transform: translateY(-25%) rotate(45deg);
  transition: transform 0.2s ease;
}
.foot__more summary:hover { border-color: var(--mint); background: rgba(111, 191, 165, 0.08); }
.foot__more summary:focus-visible { outline: 2px solid var(--mint); outline-offset: 3px; }
.foot__more[open] summary::after { transform: translateY(25%) rotate(-135deg); }
.foot__more[open] .foot__areas { margin-top: 1rem; animation: foot-more-in 0.25s ease-out; }
@keyframes foot-more-in { from { opacity: 0; transform: translateY(-4px); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) {
  .foot__more summary::after { transition: none; }
  .foot__more[open] .foot__areas { animation: none; }
}
.foot .foot__areas {
  flex-direction: row;
  flex-wrap: wrap;
  gap: 0.5rem;
}
.foot__areas li {
  padding: 0.3rem 0.75rem;
  border: 1px solid var(--rule-navy);
  border-radius: 999px;
  font-size: 0.9rem;
  color: var(--on-navy-dim);
  white-space: nowrap;
}

/* ---- category clouds (2026-10-14, chg-e78d082f and chg-2d6ac030) ----------
   Her asks: on Diseases, "EACH CATEGORIES FROM 1 TO 21 AND WHEN CLICKED INTO
   THESE DISEASE APPEAR IN AN INTERACTIVE CLOUD DIAGRAM"; on Treatments, "BEFORE
   THE PHOTOS MAKE AN INTERACTIVE CLOUD DIAGRAM OF THESE TREATMENTS". One
   component for both: her numbered categories are the way in (the rounded
   tinted boxes she liked on 13 Oct, mint, sky and sand in turn), and the one
   pressed shows its names as a cloud of rounded boxes under the category,
   joined to it by a dotted line, on faint rings. Wide screens: categories on
   the left, the cloud beside them and staying in view. Phones: the cloud
   opens under the category pressed. Without site.js every cloud shows, one
   under another, so nothing is lost. Behaviour: site.js, "category clouds". */
.cloud-band__title { margin: 0 0 clamp(1.25rem, 3vw, 2rem); }
.cloud {
  display: grid;
  gap: clamp(1rem, 2.5vw, 2rem);
}
.cloud__cats {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 0.5rem;
}
.cloud__pick {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  width: 100%;
  margin: 0;
  padding: 0.55rem 1rem 0.55rem 0.55rem;
  border: 0;
  border-radius: 1rem;
  background: #E4F3EC;
  color: #17463A;
  font-family: var(--display);
  font-size: 1.08rem;
  line-height: 1.25;
  text-align: left;
  cursor: pointer;
  box-shadow: inset 0 0 0 1px rgba(31, 106, 87, 0.12);
  transition: background-color 0.2s ease, color 0.2s ease, box-shadow 0.2s ease;
  scroll-margin-top: calc(var(--mast-h, 4rem) + 0.75rem);
}
.cloud__cat:nth-child(3n+2) .cloud__pick { background: #E2EEF5; color: #173A4D; box-shadow: inset 0 0 0 1px rgba(23, 58, 77, 0.12); }
.cloud__cat:nth-child(3n+3) .cloud__pick { background: #F4EBDC; color: #4F3B17; box-shadow: inset 0 0 0 1px rgba(79, 59, 23, 0.12); }
.cloud__pick:hover { box-shadow: inset 0 0 0 1.5px currentColor; }
.cloud__pick:focus-visible { outline: 3px solid var(--green); outline-offset: 2px; }
.cloud__cat .cloud__pick[aria-expanded="true"] {
  background: var(--green);
  color: #FFFFFF;
  box-shadow: 0 6px 18px rgba(31, 106, 87, 0.28);
}
.cloud__num {
  flex: 0 0 auto;
  display: inline-grid;
  place-items: center;
  min-width: 2rem;
  height: 2rem;
  padding: 0 0.45rem;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.8);
  font-family: var(--ui);
  font-size: 0.88rem;
  font-weight: 600;
  line-height: 1;
}
.cloud__pick[aria-expanded="true"] .cloud__num { background: #FFFFFF; color: var(--green); }

.cloud__stage { display: grid; gap: 1rem; }
.cloud__panel {
  position: relative;
  padding: clamp(1.25rem, 3vw, 2rem) clamp(0.9rem, 2.5vw, 2rem) clamp(1.4rem, 3vw, 2.25rem);
  border-radius: 1.5rem;
  background: radial-gradient(ellipse 90% 70% at 50% 0%, #FFFFFF 0%, #F4F9F6 55%, #E9F4EE 100%);
  box-shadow: inset 0 0 0 1px rgba(31, 106, 87, 0.14);
  text-align: center;
  overflow: hidden;
}
/* the faint rings the cloud sits on */
.cloud__panel::before {
  content: "";
  position: absolute;
  inset: 0;
  background: repeating-radial-gradient(circle at 50% 2.6rem, transparent 0 54px, rgba(31, 106, 87, 0.07) 54px 55px);
  pointer-events: none;
}
.cloud__hub {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  max-width: 100%;
  margin: 0;
  padding: 0.5rem 1.2rem 0.5rem 0.5rem;
  border-radius: 999px;
  background: var(--green);
  color: #FFFFFF;
  font-family: var(--display);
  font-size: clamp(1.15rem, 2vw, 1.45rem);
  font-weight: 500;
  line-height: 1.2;
  text-align: left;
  box-shadow: 0 8px 22px rgba(31, 106, 87, 0.28);
}
.cloud__hub .cloud__num { background: #FFFFFF; color: var(--green); }
.cloud__hub::after {
  content: "";
  position: absolute;
  left: 50%;
  top: 100%;
  height: 1.15rem;
  border-left: 2px dotted rgba(31, 106, 87, 0.5);
}
.cloud__words {
  position: relative;
  list-style: none;
  margin: 1.15rem 0 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  gap: 0.5rem 0.55rem;
}
.cloud__words li {
  margin: 0;
  padding: 0.4rem 0.85rem;
  border-radius: 1.25rem;
  background: #E4F3EC;
  color: #17463A;
  font-family: var(--display);
  font-size: 1rem;
  line-height: 1.25;
  box-shadow: inset 0 0 0 1px rgba(31, 106, 87, 0.14);
}
.cloud__words li:nth-child(3n+2) { background: #E2EEF5; color: #173A4D; box-shadow: inset 0 0 0 1px rgba(23, 58, 77, 0.14); }
.cloud__words li:nth-child(3n+3) { background: #F4EBDC; color: #4F3B17; box-shadow: inset 0 0 0 1px rgba(79, 59, 23, 0.14); }
/* a cloud, not a table: the boxes come in three sizes */
.cloud__words li:nth-child(7n+1) { font-size: 1.16rem; padding: 0.48rem 1rem; }
.cloud__words li:nth-child(5n+3) { font-size: 0.92rem; padding: 0.34rem 0.75rem; }

@media (prefers-reduced-motion: no-preference) {
  .cloud.is-live .cloud__panel.is-in .cloud__hub { animation: cloud-hub 0.45s cubic-bezier(0.2, 0.8, 0.2, 1) both; }
  .cloud.is-live .cloud__panel.is-in .cloud__words li {
    animation: cloud-pop 0.5s cubic-bezier(0.2, 0.8, 0.2, 1) both;
    animation-delay: calc(var(--i, 0) * 14ms + 120ms);
  }
  .cloud__words li { transition: transform 0.2s ease; }
  .cloud__words li:hover { transform: translateY(-2px) scale(1.04); }
}
@keyframes cloud-hub { from { opacity: 0; transform: scale(0.92); } to { opacity: 1; transform: none; } }
@keyframes cloud-pop { from { opacity: 0; transform: translateY(10px) scale(0.86); } to { opacity: 1; transform: none; } }

@media (max-width: 59.99rem) {
  /* Phones and tablets: the cloud opens under the category pressed, so the
     green button just above already names it; its heading stays for
     screen readers and search only. */
  .cloud.is-live .cloud__cat .cloud__stage { margin-top: 0.5rem; }
  .cloud.is-live .cloud__cat .cloud__hub {
    position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
    overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
  }
  .cloud.is-live .cloud__cat .cloud__words { margin-top: 0; }
}
@media (max-width: 40rem) {
  .cloud__pick { font-size: 1.02rem; }
  .cloud__hub { font-size: 1.1rem; }
  .cloud__words li { font-size: 0.95rem; }
  .cloud__words li:nth-child(7n+1) { font-size: 1.05rem; }
  .cloud__words li:nth-child(5n+3) { font-size: 0.88rem; }
}
@media (min-width: 60rem) {
  .cloud { grid-template-columns: minmax(0, 24rem) minmax(0, 1fr); align-items: start; }
  /* the cloud stays beside the categories while they scroll; a long one
     scrolls inside its own frame rather than running off the screen */
  .cloud.is-live .cloud__stage {
    position: sticky;
    top: calc(var(--hdr-h, 9rem) + 1rem);
    max-height: calc(100vh - var(--hdr-h, 9rem) - 2rem);
    overflow-y: auto;
    border-radius: 1.5rem;
    scrollbar-width: thin;
  }
  /* more names below: the bottom edge fades so the cloud reads as one to scroll */
  .cloud.is-live .cloud__stage.has-more {
    -webkit-mask-image: linear-gradient(to bottom, #000 calc(100% - 3.5rem), transparent);
    mask-image: linear-gradient(to bottom, #000 calc(100% - 3.5rem), transparent);
  }
}

/* ---- Our team, "Our lead." (chg-943fd42c, then chg-40196316, 2026-10-15) --
   15 Oct, first: "THERE IS LOT OF VOID SPACES IN THE SIDE" - the section runs
   the full page width. Then, the same day: "YOU CAN REMOVE THE ANIMATED IMAGE,IT
   LOOKS VERY CHILDISH..IF U ARE ADDING, THEN ADD A VERY PROFESSIONAL IMAGE.." -
   the braces drawing that sat between the points and the portrait is gone, and
   his own photograph takes the side, larger, level with the points. Phones:
   the photograph first, then the points. */
.lead-grid { display: grid; grid-template-columns: minmax(0, 1fr); gap: clamp(1.5rem, 4vw, 4rem); align-items: start; }
@media (min-width: 52.0625rem) {
  .lead-grid { grid-template-columns: minmax(0, 1fr) minmax(0, 20rem); }
  .lead-grid .portrait { max-width: none; }
}
@media (min-width: 64rem) {
  .lead-grid { grid-template-columns: minmax(0, 1fr) minmax(0, 25rem); }
}
@media (min-width: 80rem) {
  .lead-grid { grid-template-columns: minmax(0, 1fr) minmax(0, 28rem); }
}
@media (max-width: 52rem) {
  .lead-grid__portrait { order: -1; }
}
