/* ============================================================================
   PARTS — the certificate plate, the disclosure panels, reviews, the media
   links, the Instagram wall, the popup player, and the sub-page furniture.

   Re-grounded for the light herbal system (spec 2026-08-17 §2/§4/§5). The
   brass-and-enamel signboard, the four rivets and the 9:16 video posters are
   gone: the plate is a printed certificate now, and the videos are a row of
   quiet link-cards.

   Colour policy in this sheet matches components.css / sections.css:
   · semantic token NAMES first (tokens.css revalues them, the names are stable)
   · the --lh-* aliases declared at the top of sections.css for the spec §2
     literals that have no semantic token. Custom properties resolve per
     element, not per sheet, so they read fine even though this file loads
     first.
   · saffron is NEVER text or fill on cream — only on forest (11.52:1)
   · amber #D4791E is a MARK colour (stars, dots), never text: 3.09:1
   ========================================================================== */

/* ---------------------------------------------------------------------------
   THE SIGNBOARD — now a certificate plate

   The nameplate in the studio photograph reads "Santosh Kumar — Homeopathic
   Physician": no "Dr.", no surname. Rather than overlay a patch on the photo
   (which drifts out of register at other screen sizes), the photo is cropped
   above it and this real, typeset plate takes its place.

   It used to be brass and black enamel — an awards-gala object. It is now the
   same certificate double-rule the cred card and the rating tile carry: near-
   white stock, a 2px forest rule with a 1px sage rule set one breath inside
   it. The credential idiom of the whole redesign, at its largest.
   --------------------------------------------------------------------------- */

.signboard {
  position: relative;
  display: grid;
  gap: var(--space-2xs);
  justify-items: center;
  text-align: center;
  padding: clamp(var(--space-md), 3.5vw, var(--space-lg)) clamp(var(--space-md), 5vw, var(--space-xl));
  background-color: var(--lh-mat);
  border: var(--frame-outer);
  border-radius: var(--radius-sm);
  /* A card, not the seal: the quiet lift only (spec §4.6). */
  box-shadow: var(--shadow-lift);
}

/* The inner sage rule. This pseudo used to be one of the four brass rivets;
   reusing it is what guarantees the rivet cannot come back. */
.signboard::before {
  content: "";
  position: absolute;
  inset: 6px;
  border: var(--frame-inner);
  border-radius: 2px;
  pointer-events: none;
}

.signboard__seal {
  inline-size: clamp(2.75rem, 7vw, 3.5rem);
  margin-block-end: var(--space-3xs);
}
.signboard__seal img { inline-size: 100%; }

/* Forest in the display face — 13.69:1 on the plate. The engraved text-shadow
   is gone with the enamel it was cut into. */
.signboard__name {
  font-family: var(--font-display);
  font-weight: var(--display-weight);
  font-size: clamp(1.5rem, 1rem + 2.2vw, 2.4rem);
  line-height: 1.1;
  text-wrap: balance;
  letter-spacing: var(--display-tracking);
  color: var(--lh-forest);
}
html[lang="hi"] .signboard__name { line-height: 1.28; }

.signboard__rule {
  inline-size: min(100%, 15rem);
  block-size: 1px;
  border: 0;
  margin-block: var(--space-2xs);
  background-color: var(--lh-sage);
}

/* Moss label — 9.99:1 on the plate. */
.signboard__role {
  font-family: var(--font-ui);
  font-size: clamp(var(--step--1), 0.8rem + 0.5vw, var(--step-0));
  font-weight: 600;
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--lh-moss);
  max-inline-size: none;
}
html[lang="hi"] .signboard__role {
  text-transform: none;
  letter-spacing: 0.04em;
  font-weight: 700;
}

/* Ink, small — 14.35:1. Was a dim warm grey on enamel. */
.signboard__cred {
  font-family: var(--font-ui);
  font-size: var(--step--2);
  letter-spacing: 0.08em;
  color: var(--text-body);
  max-inline-size: none;
}

/* Hairline pill with the availability dot. Sage rather than the fainter
   #DDE3D2: on the near-white plate that hairline would measure 1.27:1 and
   simply not be there. */
.signboard__hours {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  margin-block-start: var(--space-3xs);
  padding: 0.3rem 0.8rem;
  border: 1px solid var(--lh-sage);
  border-radius: var(--radius-pill);
  font-family: var(--font-ui);
  font-size: var(--step--2);
  letter-spacing: 0.06em;
  color: var(--text-body);
}
html[lang="hi"] .signboard__hours { letter-spacing: 0; }
.signboard__hours::before {
  content: "";
  inline-size: 0.45rem;
  block-size: 0.45rem;
  border-radius: 50%;
  background-color: var(--lh-tulsi);
}

/* ---------------------------------------------------------------------------
   DISCLOSURE — the services open on press

   The mechanism below is load-bearing and unchanged: the 0fr → 1fr row
   transition, the [hidden] override, the overflow contract on the panel inner,
   and the aria-expanded sign states are exactly what disclose.js drives.
   Only the colours moved.
   --------------------------------------------------------------------------- */

.service { display: block; padding-block: 0; }

/* The heading wraps the button — the correct accordion structure. A heading
   cannot live inside a <button>, since a button only takes phrasing content. */
.service__h { margin: 0; font: inherit; letter-spacing: normal; }

.service__trigger {
  inline-size: 100%;
  display: grid;
  grid-template-columns: 3.25rem 1fr auto;
  align-items: center;
  gap: var(--space-sm);
  padding-block: var(--space-md);
  text-align: start;
  cursor: pointer;
  color: inherit;
  background-color: transparent;
  transition: background-color var(--dur-base) var(--ease-out-quart);
}

/* Vermilion — 5.37:1 on cream, 5.29:1 on a leaf band. */
.service__num {
  font-family: var(--font-ui);
  font-size: var(--step-0);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--text-accent);
  letter-spacing: 0.04em;
  align-self: start;
  padding-block-start: 0.2em;
}

.service__heading { display: grid; gap: 3px; justify-items: start; }
.service__title {
  font-family: var(--font-display);
  font-size: var(--step-2);
  font-weight: var(--display-weight);
  line-height: var(--leading-tight);
  letter-spacing: var(--display-tracking);
  color: var(--lh-forest);
  text-wrap: balance;
  transition: transform var(--dur-base) var(--ease-out-quart);
}
html[lang="hi"] .service__title { line-height: 1.26; }
.service__summary {
  font-family: var(--font-ui);
  font-size: var(--step--1);
  color: var(--text-muted);
  max-inline-size: 44ch;
}

/* A drawn plus that becomes a minus. Two rules, one rotates away.

   The circle IS the state indicator here — nothing else on the row says
   open or closed — so its boundary takes the deeper sage (3.37:1) rather
   than the decorative #A8B79A hairline (2.05:1). */
.service__sign {
  position: relative;
  inline-size: 1.6rem;
  block-size: 1.6rem;
  flex: none;
  border: 1px solid var(--ink-400);
  border-radius: 50%;
  align-self: start;
  margin-block-start: 0.25em;
  transition: border-color var(--dur-base) var(--ease-out-quart),
              background-color var(--dur-base) var(--ease-out-quart);
}
.service__sign::before,
.service__sign::after {
  content: "";
  position: absolute;
  inset-block-start: 50%;
  inset-inline-start: 50%;
  inline-size: 0.7rem;
  block-size: 1.5px;
  background-color: var(--text-body);
  translate: -50% -50%;
  transition: transform var(--dur-base) var(--ease-out-quart),
              background-color var(--dur-base) var(--ease-out-quart);
}
.service__sign::after { transform: rotate(90deg); }

/* Open: the vermilion fill survives the retune — it is the one hot mark on
   the section, and white on #D62B0A measures 4.99:1. */
.service__trigger[aria-expanded="true"] .service__sign {
  background-color: var(--vermilion-600);
  border-color: var(--vermilion-600);
}
.service__trigger[aria-expanded="true"] .service__sign::before,
.service__trigger[aria-expanded="true"] .service__sign::after {
  background-color: #FFFFFF;
}
.service__trigger[aria-expanded="true"] .service__sign::after { transform: rotate(0deg); }

/* grid-template-rows 0fr → 1fr is the only way to transition to auto height
   without measuring anything in JavaScript. */
.service__panel {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows var(--dur-slow) var(--ease-out-quart);
}
.service__panel > * { overflow: hidden; }
.service.is-open .service__panel { grid-template-rows: 1fr; }

/* `display: grid` above is author-origin and would otherwise beat the user
   agent's `[hidden] { display: none }`, leaving a collapsed panel as a dead
   strip whose text is still focusable and still read aloud. */
.service__panel[hidden] { display: none; }

.service__panelinner {
  padding-inline-start: calc(3.25rem + var(--space-sm));
  /* No bottom padding here. This element is the overflow container for the
     0fr → 1fr collapse, and padding on it survives the collapse as a dead
     strip. A margin on the last child sits inside the clip and goes to zero. */
  min-block-size: 0;
}
.service__panelinner > *:last-child { margin-block-end: var(--space-md); }
.service__panelinner p {
  max-inline-size: 60ch;
  color: var(--text-body);
}
@media (max-width: 40rem) {
  .service__trigger { grid-template-columns: 2.25rem 1fr auto; gap: var(--space-2xs); }
  .service__panelinner { padding-inline-start: calc(2.25rem + var(--space-2xs)); }
}

/* Leaf tint, one step deeper than --surface-sunken, so the hover still reads
   if the services section is ever moved onto a leaf band. */
@media (hover: hover) {
  .service__trigger:hover { background-color: var(--lh-leaf); }
  .service__trigger:hover .service__title { transform: translateX(var(--space-3xs)); }
  .service__trigger:hover .service__sign { border-color: var(--lh-forest); }
}

/* ---------------------------------------------------------------------------
   FOOTER PAGE LINKS

   The footer is the one forest ground left on the site, and .footer__nav
   exists nowhere else — which is the only reason saffron is allowed here.
   Cream 9.56:1 → saffron 11.52:1, both on #06321C.
   --------------------------------------------------------------------------- */

.footer__nav {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--space-sm) var(--space-md);
  margin-block-start: var(--space-2xs);
  font-family: var(--font-ui);
  font-size: var(--step--1);
}
.footer__nav a {
  color: var(--lh-cream-muted);
  text-decoration: none;
  padding-block-end: 2px;
  border-block-end: 1px solid transparent;
  transition: color var(--dur-fast) var(--ease-out-quart),
              border-color var(--dur-fast) var(--ease-out-quart);
}
.footer__nav a:hover {
  color: var(--saffron-500);
  border-color: rgb(253 235 1 / 0.6);
}

/* Cross-page nav state — set from body[data-page] rather than per-page markup.
   These are masthead links on cream, so the current colour is forest, the same
   value components.css gives `.is-current`. */
body[data-page="about"] .nav-about,
body[data-page="videos"] .nav-videos { color: var(--lh-forest); }
body[data-page="about"] .nav-about::after,
body[data-page="videos"] .nav-videos::after { transform: scaleX(1); }

/* ---------------------------------------------------------------------------
   REVIEWS
   --------------------------------------------------------------------------- */

/* The rating is a credential, so it takes the certificate frame rather than
   the plain card the individual reviews use. */
.rating {
  position: relative;
  display: grid;
  gap: var(--space-2xs);
  justify-items: center;
  text-align: center;
  padding: var(--space-lg);
  background-color: var(--surface-raised);
  border: var(--frame-outer);
  border-radius: var(--radius-sm);
}
.rating::before {
  content: "";
  position: absolute;
  inset: 6px;
  border: var(--frame-inner);
  border-radius: 2px;
  pointer-events: none;
}
.rating__score {
  font-family: var(--font-display);
  font-weight: var(--display-weight);
  font-size: var(--step-4);
  line-height: 1;
  color: var(--lh-forest);
}
/* Amber, not saffron: a star is a mark, and #D4791E is the one warm value
   that reads on cream at all (3.09:1 — the non-text floor, and these carry a
   role="img" label, so the colour is never the information). */
.rating__stars { display: flex; gap: 3px; color: var(--lh-amber); }
.rating__stars svg { inline-size: 1.15rem; block-size: 1.15rem; }
.rating__count {
  font-family: var(--font-ui);
  font-size: var(--step--1);
  color: var(--text-muted);
  max-inline-size: none;
}
.rating__src {
  font-family: var(--font-ui);
  font-size: var(--step--2);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--text-muted);
}
html[lang="hi"] .rating__src { text-transform: none; letter-spacing: 0.04em; }

.reviews__grid {
  display: grid;
  gap: var(--space-md);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 17rem), 1fr));
}

.review {
  display: grid;
  gap: var(--space-2xs);
  align-content: start;
  padding: var(--space-md);
  background-color: var(--lh-mat);
  border: 1px solid var(--lh-sage);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow-lift);
}
.review__stars { display: flex; gap: 2px; color: var(--lh-amber); }
.review__stars svg { inline-size: 0.95rem; block-size: 0.95rem; }
.review__text { color: var(--text-body); max-inline-size: none; }
.review__who {
  font-family: var(--font-ui);
  font-size: var(--step--1);
  font-weight: 600;
  color: var(--text-strong);
  margin-block-start: var(--space-3xs);
}

/* Shown only while no real review text has been supplied. */
.reviews__pending {
  grid-column: 1 / -1;
  padding: var(--space-lg);
  border: 1px dashed var(--lh-sage);
  border-radius: var(--radius-sm);
  text-align: center;
  color: var(--text-muted);
}

/* ---------------------------------------------------------------------------
   MEDIA LINKS — what the four 9:16 video posters became

   The posters were the single most out-of-proportion thing on the page: four
   phone-shaped slabs of dark chrome carrying nothing but a brand watermark.
   Each entry is now a horizontal row you can read in one pass — brand mark,
   platform, title, and the affordance on the right. The YouTube and Instagram
   rows are <button data-play>; the Facebook rows are plain <a>, because a
   /share/r/ link cannot be framed by anyone. Both element types wear the same
   class and must therefore look identical.
   --------------------------------------------------------------------------- */

.medialinks {
  display: grid;
  gap: var(--space-sm);
  /* min() rather than the bare 15rem: below ~240px of column the bare floor
     would push the grid wider than its container and pan the page sideways. */
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 15rem), 1fr));
}

.medialink {
  --brand: var(--lh-moss);
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: var(--space-sm);
  /* 72px is the floor, not the height: a long Hindi title is allowed to grow
     the row rather than be clipped out of the page. Rows in the same grid
     line stretch to match, so a wrapped title never makes the row ragged. */
  min-block-size: 4.5rem;
  /* 0.75rem, not 1rem: the min-height already gives a single-line row all the
     air it needs, and the tighter block padding is what keeps a two-line
     Devanagari title inside the 96px ceiling instead of 8px over it. */
  padding: var(--space-xs) var(--space-md);
  background-color: var(--lh-mat);
  border: 1px solid var(--lh-sage);
  border-radius: var(--radius-sm);
  /* <button> normalisation — it defaults to centred text and its own font. */
  inline-size: 100%;
  font: inherit;
  text-align: start;
  color: var(--text-body);
  text-decoration: none;
  cursor: pointer;
  /* `translate` and not `transform`: motion.css parks every revealed element
     at `transform: none` with a higher specificity than :hover, so a hover
     written as a transform would simply never arrive. */
  transition: border-color var(--dur-fast) var(--ease-out-quart),
              box-shadow var(--dur-fast) var(--ease-out-quart),
              translate var(--dur-fast) var(--ease-out-quart);
}

.medialink--yt { --brand: #FF0000; }   /* 3.86:1 on the card */
.medialink--ig { --brand: #E4405F; }   /* 3.90:1 */
.medialink--fb { --brand: #0866FF; }   /* 4.65:1 */

.medialink__icon {
  display: grid;
  place-items: center;
  inline-size: 1.5rem;
  block-size: 1.5rem;
  flex: none;
  color: var(--brand);
}
.medialink__icon svg { inline-size: 100%; block-size: 100%; }

/* min-inline-size:0 — without it a long unbroken title sets the column's
   min-content width and blows the grid past its container. */
.medialink__meta { display: grid; gap: 2px; min-inline-size: 0; }

/* Moss caps, 9.99:1. No html[lang="hi"] override here on purpose: the value is
   always a Latin brand name ("YouTube", "Instagram", "Facebook"), so the caps
   and the tracking are correct in both languages. */
.medialink__src {
  font-family: var(--font-ui);
  font-size: var(--step--2);
  font-weight: 600;
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  /* One line of Latin caps has no matras to clear, so it does not need the
     1.78 Devanagari body leading it would otherwise inherit in `hi` — that
     alone was pushing the tallest row 6px past the 96px ceiling. */
  line-height: 1.3;
  color: var(--lh-moss);
}

.medialink__title {
  font-family: var(--font-ui);
  font-size: var(--step--1);
  font-weight: 600;
  line-height: 1.35;
  color: var(--text-body);
  overflow-wrap: anywhere;
}
html[lang="hi"] .medialink__title { font-weight: 700; line-height: 1.55; }
/* This title is Devanagari in BOTH page languages (span lang=\"hi\"), so the
   matra-clearance boost keys on the CONTENT language, not the page toggle. */
.medialink__title :lang(hi) {
  line-height: 1.55;
  font-weight: 700;
}
/* The YouTube title is authored `lang="hi"` and stays Hindi in both language
   modes. base.css swaps the stack on html[lang], so in English this span would
   otherwise be handed Mona Sans and fall back to a system Devanagari face. */
.medialink__title [lang="hi"] { font-family: "Mukta", system-ui, sans-serif; }

/* Chevron or play mark — 5.52:1, and aria-hidden, so it is decoration
   reinforcing the title rather than the label itself. */
.medialink__go {
  display: grid;
  place-items: center;
  inline-size: 1.15rem;
  block-size: 1.15rem;
  flex: none;
  color: var(--text-accent);
  transition: translate var(--dur-fast) var(--ease-out-quart);
}
.medialink__go svg { inline-size: 100%; block-size: 100%; }

@media (hover: hover) {
  .medialink:hover {
    border-color: var(--ink-400);
    box-shadow: var(--shadow-lift);
    translate: 0 -2px;
  }
  .medialink:hover .medialink__go { translate: 3px 0; }
}

/* The base ring is offset 3px, which floats it away from a card this wide.
   Pulled in, and given the hover's own affordances so the keyboard sees what
   the mouse sees. */
.medialink:focus-visible {
  outline: 2px solid var(--focus-ring);
  outline-offset: 2px;
  border-color: var(--ink-400);
  box-shadow: var(--shadow-lift);
}

/* ---------------------------------------------------------------------------
   INSTAGRAM WALL

   Instagram serves no public thumbnail — og:image is stripped, /media/ returns
   405 and oEmbed is retired — so the cover frame can only come from Instagram's
   own embed. Each tile is that embed, lazily loaded so five third-party players
   are not fetched until the section is actually scrolled to.
   --------------------------------------------------------------------------- */

.igwall {
  display: grid;
  gap: var(--space-lg);
  /* Instagram's embed breaks below 326px, so 326px is the floor the tiles have
     to clear. The old 19rem (304px) did not: auto-fit lays columns out at the
     minimum and only then stretches them, so a container that fits N columns
     exactly hands each one 304px. 20.5rem is 328px — the first round figure
     over the line. (Under ~328px of container there is one full-width column;
     below 326px of viewport the embed is clipped by the frame rather than
     allowed to widen the page.) */
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 20.5rem), 1fr));
  justify-content: center;
}

.igreel { display: grid; gap: var(--space-2xs); align-content: start; }

/* A white mat with a sage hairline — the same framing the portrait and the
   gallery prints use, so the embeds' own white chrome now blends into it
   instead of glaring off an ink plate. */
.igreel__frame {
  position: relative;
  /* Instagram's embed adds its own header and action bar above and below the
     video, so the tile is taller than the 9:16 of the reel itself. */
  aspect-ratio: 10 / 17;
  background-color: var(--lh-mat);
  border: 1px solid var(--lh-sage);
  border-radius: var(--radius-sm);
  overflow: hidden;
  transition: border-color var(--dur-base) var(--ease-out-quart),
              box-shadow var(--dur-base) var(--ease-out-quart);
}
.igreel:hover .igreel__frame {
  border-color: var(--ink-400);
  box-shadow: var(--shadow-lift);
}

.igreel__frame iframe {
  position: absolute;
  inset: 0;
  inline-size: 100%;
  block-size: 100%;
  border: 0;
  /* The embed paints on white; matching the mat keeps the seam invisible
     while it loads. */
  background-color: var(--lh-mat);
}

.igreel__foot {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-sm);
}
.igreel__num {
  font-family: var(--font-ui);
  font-size: var(--step--2);
  font-weight: 700;
  letter-spacing: var(--tracking-label);
  color: var(--lh-moss);
}
html[lang="hi"] .igreel__num { letter-spacing: 0.04em; }
.igreel__out {
  font-family: var(--font-ui);
  font-size: var(--step--1);
  color: var(--text-body);
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  border-block-end: 1px solid var(--lh-sage);
  padding-block-end: 1px;
  transition: color var(--dur-fast) var(--ease-out-quart),
              border-color var(--dur-fast) var(--ease-out-quart);
}
.igreel__out svg { inline-size: 0.9rem; block-size: 0.9rem; }
.igreel__out:hover { color: var(--text-accent); border-color: var(--text-accent); }

/* ---------------------------------------------------------------------------
   THE POPUP PLAYER

   The scrim may stay dark (spec §5) — it is what lets a video read. Everything
   inside it is paper: the panel is a white card, so the caption and the escape
   link are ink and vermilion rather than cream floating on a scrim whose
   luminance depends on whatever happens to be scrolled behind it.
   --------------------------------------------------------------------------- */

.player {
  padding: 0;
  border: 0;
  background: transparent;
  max-inline-size: none;
  max-block-size: none;
  inline-size: 100%;
  block-size: 100%;
  overflow: visible;
}
.player::backdrop { background-color: rgb(18 36 26 / 0.72); }

.player__panel {
  position: absolute;
  inset-block-start: 50%;
  inset-inline-start: 50%;
  /* Nudged down half the close button's height. The button hangs ABOVE the
     card, and on a true vertical centre it was the first thing to leave the
     screen — measured at -10px on a 694px viewport, and worse on a phone. */
  translate: -50% calc(-50% + 1.75rem);
  inline-size: min(94vw, 25rem);
  display: grid;
  gap: var(--space-2xs);
  padding: var(--space-2xs);
  background-color: var(--lh-mat);
  border: 1px solid var(--lh-sage);
  border-radius: var(--radius-sm);
  box-shadow: 0 2px 6px rgb(18 36 26 / 0.24), 0 18px 46px rgb(18 36 26 / 0.30);
}

.player__frame {
  position: relative;
  aspect-ratio: 9 / 16;
  /* Trimmed from 78svh to leave room for the card's own padding and caption.
     The second term is what makes it survive a landscape phone: 13rem is the
     close button, the card's padding and gap, and a wrapped Devanagari caption
     added up, so the reel gives way rather than pushing the dismiss control
     off the top of the screen. */
  max-block-size: min(74svh, 100svh - 13rem);
  border-radius: var(--radius-xs);
  overflow: hidden;
  background-color: var(--lh-mat);
  border: 1px solid var(--lh-sage);
}
.player__frame iframe {
  position: absolute;
  inset: 0;
  inline-size: 100%;
  block-size: 100%;
  border: 0;
}

/* Sits above the card, on the scrim, so it is a cream chip in its own right —
   the same object as .lightbox__close, at the same 44px touch size. */
.player__close {
  position: absolute;
  inset-block-start: -3.25rem;
  inset-inline-end: 0;
  display: grid;
  place-items: center;
  inline-size: 2.75rem;
  block-size: 2.75rem;
  background-color: var(--surface-raised);
  color: var(--text-strong);
  border: 1px solid var(--ink-400);
  border-radius: var(--radius-sm);
  cursor: pointer;
  transition: background-color var(--dur-fast) var(--ease-out-quart),
              border-color var(--dur-fast) var(--ease-out-quart);
}
.player__close:hover {
  background-color: var(--lh-leaf);
  border-color: var(--lh-forest);
}
.player__close svg { inline-size: 1.2rem; block-size: 1.2rem; }

.player__meta {
  display: grid;
  gap: var(--space-3xs);
  justify-items: center;
  text-align: center;
  padding: var(--space-3xs) var(--space-2xs) var(--space-2xs);
}
.player__title {
  font-family: var(--font-body);
  font-size: var(--step--1);
  color: var(--text-body);
  max-inline-size: 40ch;
}
.player__title:empty { display: none; }
.player__out {
  font-family: var(--font-ui);
  font-size: var(--step--1);
  color: var(--text-accent);
  text-decoration: none;
  border-block-end: 1px solid rgb(185 58 14 / 0.4);
}
.player__out:hover { border-color: var(--text-accent); }
/* player.js sets .hidden on this link when a reel has no external permalink.
   The UA rule already handles it; this is here so that giving the link a
   display value later cannot silently un-hide it. */
.player__out[hidden] { display: none; }

/* ---- Brand row ------------------------------------------------------------
   It used to sit on an ink plate; it sits on cream and leaf-tint bands now,
   so the chips are white with a sage edge and ink labels. */

.brandrow {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--space-sm);
  margin-block-start: var(--space-xl);
  padding-block-start: var(--space-lg);
  border-block-start: 1px solid var(--lh-sage);
}

.brandlink {
  --brand: var(--lh-moss);
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  padding: 0.6rem 1.1rem;
  min-block-size: 2.75rem;           /* spec §1 touch floor */
  background-color: var(--lh-mat);
  border: 1px solid var(--lh-sage);
  border-radius: var(--radius-pill);
  font-family: var(--font-ui);
  font-size: var(--step--1);
  font-weight: 600;
  color: var(--text-body);           /* 14.35:1 on the chip */
  text-decoration: none;
  transition: border-color var(--dur-fast) var(--ease-out-quart),
              background-color var(--dur-fast) var(--ease-out-quart),
              color var(--dur-fast) var(--ease-out-quart),
              translate var(--dur-fast) var(--ease-out-quart);
}
.brandlink svg { inline-size: 1.25rem; block-size: 1.25rem; color: var(--brand); flex: none; }

/* WhatsApp's own #25D366 measures 1.91:1 as a glyph on the chip and simply
   disappears; --whatsapp is the site's already-darkened register (3.06:1) and
   keeps the button and the chip speaking with one green. */
.brandlink--wa { --brand: var(--whatsapp); }
.brandlink--yt { --brand: #FF0000; }
.brandlink--ig { --brand: #E4405F; }
.brandlink--fb { --brand: #0866FF; }

.brandlink:hover {
  border-color: var(--lh-forest);
  background-color: var(--lh-leaf);
  color: var(--lh-forest);           /* 12.45:1 on the leaf tint */
  translate: 0 -2px;
}

/* ---------------------------------------------------------------------------
   THE CLINIC FILM

   The one object on a light page allowed to stay deep — video chrome is dark
   whatever the page does, and a cream frame around a dark film only draws a
   halo. It is built as a frame rather than a plate: a forest-black mat with a
   sage hairline and the quiet lift, the same construction as the white-matted
   photographs, in the dark register.
   --------------------------------------------------------------------------- */

.clinicfilm {
  position: relative;
  padding: 6px;
  background-color: var(--ink-950);   /* #0A1F14 */
  border: 1px solid var(--lh-sage);   /* 8.13:1 against the mat */
  border-radius: var(--radius-sm);
  overflow: hidden;
  box-shadow: var(--shadow-lift);
}
.clinicfilm video {
  inline-size: 100%;
  block-size: auto;
  max-block-size: 78svh;
  display: block;
  margin-inline: auto;
  border-radius: var(--radius-xs);
}

/* ---------------------------------------------------------------------------
   BOTANICAL ORNAMENT — engraved sprigs pressed into the paper

   Moss line art at printing-ink weight: light enough to be paper texture,
   present enough to be seen. A shade stronger on the leaf bands, which are
   themselves closer to the stroke colour.
   --------------------------------------------------------------------------- */

.sprig {
  position: absolute;
  color: var(--lh-moss);
  opacity: 0.10;
  pointer-events: none;
  z-index: 0;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.1;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.section--sunken .sprig,
.section:has(.gallery) .sprig { opacity: 0.13; }

/* The footer is the only forest ground left, so there the strokes invert. */
.plate .sprig { color: var(--lh-cream); opacity: 0.12; }

.sprig--tl { inset-block-start: -1.5rem; inset-inline-start: -2.5rem; inline-size: clamp(7rem, 16vw, 13rem); rotate: -14deg; }
.sprig--br { inset-block-end: -2rem; inset-inline-end: -2rem; inline-size: clamp(8rem, 18vw, 15rem); rotate: 168deg; }
.sprig--tr { inset-block-start: -1rem; inset-inline-end: -3rem; inline-size: clamp(6rem, 13vw, 11rem); rotate: 24deg; }

@media (max-width: 48rem) {
  .sprig--br, .sprig--tr { display: none; }
  /* The leaf-band boost above is (0,2,0) and a media query adds no specificity
     of its own, so the second selector is what lets this land on a leaf band
     rather than only on cream. */
  .sprig--tl,
  .section--sunken .sprig--tl,
  .section:has(.gallery) .sprig--tl { opacity: 0.08; }
}

/* ---------------------------------------------------------------------------
   SUB-PAGE FURNITURE
   --------------------------------------------------------------------------- */

/* No dark plate here any more: the pagehead is the page's own cream, with the
   sprig and the ambient canvases doing the work the ink used to do.
   `isolation` is what keeps those canvases (z-index -1/-2, positioned by
   sections.css) inside this box rather than escaping to the root stacking
   context and sliding under the paper texture — the same reasoning the hero
   carries now that it too is de-plated. */
.pagehead {
  position: relative;
  isolation: isolate;
  padding-block: clamp(3rem, 8vw, 5.5rem) clamp(2rem, 5vw, 3.5rem);
  overflow: hidden;
}
.pagehead h1 {
  font-size: var(--step-4);
  margin-block-start: var(--space-sm);
  color: var(--lh-forest);
}
/* Muted ink, 7.82:1 — the old value was on-plate cream and would be invisible
   on this ground. */
.pagehead__lede {
  margin-block-start: var(--space-md);
  font-size: var(--step-1);
  line-height: 1.55;
  color: var(--text-muted);
  max-inline-size: 52ch;
}
html[lang="hi"] .pagehead__lede { line-height: 1.75; }

.crumbs {
  font-family: var(--font-ui);
  font-size: var(--step--1);
  color: var(--lh-moss);             /* 9.73:1 */
}
.crumbs a { color: var(--text-accent); text-decoration: none; }
.crumbs a:hover { text-decoration: underline; }

/* Numbered consultation steps — an ordered register, not a card grid.

   The numerals are forest rather than amber. Amber is the mark colour of this
   system (stars, dots, buds) and is explicitly not a text colour: at 3.01:1 on
   cream it would sit on the large-text floor with nothing under it, while the
   display numerals everywhere else on the site — the hours, the telephone, the
   facts — are forest at 13.33:1. This register joins them. */
.steps { display: grid; gap: 0; counter-reset: step; }
.step {
  display: grid;
  grid-template-columns: 3.5rem 1fr;
  gap: var(--space-sm);
  padding-block: var(--space-md);
  border-block-start: var(--rule-hair);
}
.step:last-child { border-block-end: var(--rule-hair); }
.step__num {
  font-family: var(--font-display);
  font-weight: var(--display-weight);
  font-size: var(--step-2);
  line-height: 1;
  color: var(--lh-forest);
}
.step h3 { font-size: var(--step-1); margin-block-end: var(--space-3xs); }

/* A quiet closing call to action for sub-pages. Deeper cream stock inside the
   certificate frame — the same object as the cred card, doing a different job. */
.endcap {
  position: relative;
  display: grid;
  gap: var(--space-sm);
  justify-items: center;
  text-align: center;
  padding: clamp(var(--space-lg), 5vw, var(--space-2xl));
  background-color: var(--surface-aged);
  border: var(--frame-outer);
  border-radius: var(--radius-sm);
}
.endcap::before {
  content: "";
  position: absolute;
  inset: 6px;
  border: var(--frame-inner);
  border-radius: 2px;
  pointer-events: none;
}
.endcap h2 { font-size: var(--step-2); color: var(--lh-forest); }
.endcap p { max-inline-size: 46ch; color: var(--text-body); }
