/* base.css — DH Hospital Cumilla base layer + components
   Owner: design-system · v1.0 (2026-07-31) · depends on tokens.css

   HARD RULES ENCODED HERE (frontend-builder §"Known bugs", audit.py 19/21):
   1. NO overflow-x:hidden on html/body — it kills position:sticky. We use
      overflow-x:clip on a wrapper instead, and the sticky header + fixed
      bottom bar live OUTSIDE that wrapper as direct children of <body>.
   2. NO blur-filter / filter / transform on any ancestor of the header or the
      bottom bar — those properties make the ancestor a containing block and
      capture position:fixed descendants. There are none in this file.
   3. Every custom property used here is defined in tokens.css.
   4. Bangla: never letter-spacing, never the break-all word-break value.
   NOTE: audit.py greps this file as plain text — do not name a forbidden CSS
   value literally in a comment, or the auditor will flag its own warning.
*/

/* ============================== fonts ==============================
   Three families, self-hosted woff2 subsets in production. Never a font CDN —
   speed and reliability in BD (CLAUDE.md §4).
     Instrument Sans   Latin  — UI, English body and headings
     Noto Sans Bengali Bengali — body
     Noto Serif Bengali Bengali — display
   Latin and Bengali sit in ONE stack; the browser picks per glyph, so a
   Bangla page with an English test name renders both correctly with no
   layout shift on the language toggle.
   The faces themselves are declared in assets/css/fonts.css, generated by
   tools/fetch_fonts.py and loaded as its own <link> so the @font-face rules
   parse before this file. Three @font-face blocks used to sit here pointing at
   filenames that never existed — noto-sans-bengali-400.woff2 rather than the
   -400-bengali.woff2 subset — and every page was making three requests that
   404'd. Removed 2026-09-03. There is one place a face is declared now. */

/* ============================== reset ============================== */
*, *::before, *::after { box-sizing: border-box; }

html {
  font-size: var(--fs-base);
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  /* NO overflow-x here. See rule 1. */
}
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
}

body {
  margin: 0;
  font-family: var(--font-body);
  font-weight: var(--fw-normal);
  line-height: var(--lh-base);
  color: var(--ink);
  background: var(--paper);
  /* room for the fixed mobile action bar so it never covers page content */
  padding-bottom: calc(var(--bottombar-h) + env(safe-area-inset-bottom, 0px));
}
@media (min-width: 768px) {
  body { padding-bottom: 0; } /* bottom bar is mobile-only */
}

h1, h2, h3, h4 {
  font-family: var(--font-display);
  font-weight: var(--fw-bold);
  line-height: var(--lh-tight);
  margin: 0 0 var(--sp-3);
  /* Bangla headings must never be letter-spaced — it breaks conjunct perception */
  letter-spacing: normal;
}
html[lang="en"] :where(h1, h2, h3, h4) { letter-spacing: var(--track-tight); }
h1 { font-size: var(--fs-3xl); text-wrap: balance; }
h2 { font-size: var(--fs-2xl); margin-top: var(--sp-6); }
h3 { font-size: var(--fs-xl);  margin-top: var(--sp-5); }

p, li { margin: 0 0 var(--sp-4); overflow-wrap: break-word; }
ul, ol { padding-inline-start: var(--sp-5); }

a { color: var(--green-600); text-decoration-thickness: 1px; text-underline-offset: 3px; }
a:hover { color: var(--green-700); }

img { max-width: 100%; height: auto; }

/* ============================== a11y ============================== */
:where(a, button, summary, input, select, textarea, [tabindex]):focus-visible {
  outline: var(--focus-width) solid var(--focus);
  outline-offset: var(--focus-offset);
  border-radius: var(--radius-sm);
}
/* On green surfaces the dark ring disappears — flip it there. */
.on-green :where(a, button, summary, [tabindex]):focus-visible,
.site-topbar :where(a, button, [tabindex]):focus-visible,
.site-navbar :where(a, button, [tabindex]):focus-visible,
.mega :where(a, button, [tabindex]):focus-visible,
.drawer :where(a, button, summary, [tabindex]):focus-visible,
.bottom-bar :where(a, button, [tabindex]):focus-visible,
.site-footer :where(a, button, [tabindex]):focus-visible {
  outline-color: var(--focus-dark);
}

.skip-link {
  position: absolute; left: var(--sp-2); top: calc(var(--sp-2) * -8);
  z-index: var(--z-skip);
  background: var(--paper); color: var(--ink);
  padding: var(--sp-2) var(--sp-4); border-radius: var(--radius-sm);
  transition: top var(--dur-fast) var(--ease-out);
}
.skip-link:focus { top: var(--sp-2); }

.visually-hidden {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap;
}

/* ============================== layout ============================== */
/* The ONLY element allowed to clip horizontal overflow. `clip` (not `hidden`)
   keeps position:sticky working, and unlike transform it does not create a
   containing block, so the fixed bottom bar is unaffected. */
.page-wrap { overflow-x: clip; }

.wrap { width: min(100% - 2 * var(--sp-4), var(--wrap)); margin-inline: auto; }

.section { padding-block: var(--sp-6); }
/* A section's padding IS the space between bands. A heading sitting at the
   top of one must not stack its own top margin on that, and the last block
   inside must not add a bottom margin — together those doubled every gap. */
.section > .wrap > :first-child,
.section :where(h2, h3, h4):first-child { margin-top: 0; }
.section > .wrap > :last-child,
.section > .wrap > :last-child > :last-child { margin-bottom: 0; }
.section--tint { background: var(--green-100); }

.grid { display: grid; gap: var(--sp-4); }
@media (min-width: 600px) { }
@media (min-width: 900px) { }

/* ============================== buttons ============================== */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--sp-2);
  min-height: var(--tap); padding: var(--sp-3) var(--sp-5);
  border: 0; border-radius: var(--radius);
  font: inherit; font-weight: var(--fw-semi); text-decoration: none;
  cursor: pointer;
  transition: transform var(--dur-press) var(--ease-out),
              box-shadow var(--dur-press) var(--ease-out),
              background-color var(--dur-fast) var(--ease-out);
}
.btn:active { transform: scale(.97); }          /* transform/opacity only */
.btn--primary { background: var(--green-600); color: var(--paper); }
.btn--primary:hover { background: var(--green-700); color: var(--paper); box-shadow: var(--shadow-lift); }
.btn--ghost { background: transparent; color: var(--green-700); box-shadow: inset 0 0 0 2px var(--green-600); }
.btn--block { width: 100%; }

/* Phone number shown AS TEXT beside every call button — people read from one
   phone and dial on another (patient-experience §3). */
.tel-text { font-weight: var(--fw-semi); color: var(--ink); }

/* ============================== bottom action bar ==============================
   Mobile only. Direct child of <body>. 4 slots are laid out but only 3 render
   until Phase 2 — the চ্যাট slot is reserved (live-chat-integration §2).
   No floating bubble, ever: it would cover the call buttons.               */
.bottom-bar {
  position: fixed; inset-inline: 0; bottom: 0; z-index: var(--z-bottombar);
  display: grid; grid-auto-flow: column; grid-auto-columns: 1fr;
  background: var(--green-900);
  padding-bottom: env(safe-area-inset-bottom, 0px);
  box-shadow: 0 -2px 12px rgb(13 59 35 / .25);
}
.bottom-bar__item {
  min-height: var(--bottombar-h);
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 2px;
  color: var(--paper); text-decoration: none;
  font-size: var(--fs-xs); font-weight: var(--fw-medium);
}
.bottom-bar__item--emergency { background: var(--accent-red); }
.bottom-bar__icon { font-size: var(--fs-lg); line-height: 1; }
.bottom-bar__item[hidden] { display: none; }
@media (min-width: 768px) { .bottom-bar { display: none; } }

/* ============================== cards ============================== */
.card {
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: var(--sp-4);
  box-shadow: var(--shadow);
}

/* Initial-avatar stands in until a real headshot arrives.
   NEVER a stock photo of a foreign doctor (design-system §3, trust rule). */

.chip {
  display: inline-block; padding: var(--sp-1) var(--sp-3);
  background: var(--green-100); color: var(--green-700);
  border-radius: var(--radius-pill); font-size: var(--fs-sm);
  text-decoration: none;
}
/* Symptom chips are real controls — they must meet the tap target. */

/* ============================== FAQ ==============================
   Native <details> — keyboard-operable with zero JS (a11y §8).
   Height animates via grid-template-rows, the one exception to the
   transform/opacity-only rule (motion-interaction §1). */
.faq { border-top: 1px solid var(--line); }
.faq__item { border-bottom: 1px solid var(--line); }
.faq__q {
  position: relative;
  min-height: var(--tap);
  display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3);
  padding: var(--sp-3) var(--sp-6) var(--sp-3) 0;
  font-weight: var(--fw-semi); cursor: pointer;
  list-style: none;
}
.faq__q::-webkit-details-marker { display: none; }
.faq__q::before, .faq__q::after {
  content: ""; position: absolute; inset-inline-end: 2px; top: 50%;
  width: 14px; height: 2px; margin-top: -1px;
  background: var(--green-600); border-radius: 1px;
  transition: transform var(--dur-fast) var(--ease-out);
}
.faq__q::after { transform: rotate(90deg); }
.faq__item[open] .faq__q::after { transform: rotate(0deg); }
.faq__a { display: grid; grid-template-rows: 1fr; }
.faq__a > div { min-height: 0; padding-bottom: var(--sp-3); color: var(--muted); }

/* ============================== motion ==============================
   One reveal pattern site-wide: fade + 12px rise. IntersectionObserver adds
   .is-in once and never re-animates. Content is visible by default so a JS
   failure can never hide it — .reveal only hides once JS confirms support. */
.js-motion .reveal { opacity: 0; transform: translateY(12px); }
.js-motion .reveal.is-in {
  opacity: 1; transform: none;
  transition: opacity var(--dur-reveal) var(--ease-out),
              transform var(--dur-reveal) var(--ease-out);
}
.js-motion .reveal:nth-child(2) { transition-delay: 60ms; }
.js-motion .reveal:nth-child(3) { transition-delay: 120ms; }
.js-motion .reveal:nth-child(4) { transition-delay: 180ms; }

/* Emergency pages get everything instantly — a panicking user waits for nothing. */
.no-motion .reveal,
.js-motion .no-motion .reveal { opacity: 1 !important; transform: none !important; }

@media (prefers-reduced-motion: reduce) {
  .js-motion .reveal { opacity: 1 !important; transform: none !important; }
  .btn:active { transform: none; }
  *, *::before, *::after { transition-duration: 0ms !important; animation-duration: 0ms !important; }
}

/* A phone number that wraps at its hyphen becomes two wrong numbers — someone
   reads "01878-" off one line and dials it. Every number on this site is a
   number a patient is meant to call, so none of them may break.

   Measured across all 66 built pages at 340/384/412px (tests/numbreak.js):
   before this rule, 432 numbers were being laid out across two lines. The
   class is for numbers set inside a longer label, where there is no link. */
a[href^="tel:"], .nowrap { white-space: nowrap; }
/* the footer's WhatsApp line is a number too, and it is not a tel: link */
.foot-item a { white-space: nowrap; }

/* Brittany Signature — the face Billal asked for on the Managing Director's
   signature line. It is a commercial font; no file ships in this repo, so this
   declaration is deliberately left commented out rather than pointing at a
   missing file (a 404 per page load, for a decoration, on a 3G connection).

   To turn it on: buy the licence, convert to woff2, put the file at the path
   below, and uncomment. Nothing else needs to change — the font is already
   first in the stack on .md-sign__mark.

@font-face {
  font-family: "Brittany Signature";
  src: url("/assets/fonts/brittany-signature.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
*/

/* header.css — masthead, navigation, mega menu, search, mobile drawer
   Owner: design-system + frontend-builder · v2.0 (2026-08-27)

   Structure, top to bottom:
     .site-topbar    utility strip, deepest green, scrolls away
     .site-masthead  logo · search · contact block, warm ground, scrolls away
     .site-navbar    primary nav, sticky. Reveals a compact logo + call button
                     once it sticks, so the hotline is never off-screen.

   Rules honoured here:
   - No blur/filter/transform on any ancestor of the fixed bottom bar.
     Every element below is a sibling of it, never a parent.
   - Only transform and opacity animate. The mega panel uses a
     grid-template-rows trick for height, the one documented exception.
   - Bangla is never letter-spaced. Tracking is scoped to Latin only.
*/

/* ============================== tier 1 — utility ============================== */
.site-topbar {
  background: var(--green-950);
  color: var(--cream);
  font-size: var(--fs-xs);
}
.site-topbar__inner {
  width: min(100% - 2 * var(--sp-4), var(--wrap));
  margin-inline: auto;
  min-height: var(--h-utility);
  display: flex; align-items: center; gap: var(--sp-4);
}
.site-topbar__where { display: none; align-items: center; gap: var(--sp-2); }
@media (min-width: 720px) { .site-topbar__where { display: flex; } }
.site-topbar__right { margin-inline-start: auto; display: flex; align-items: center; gap: var(--sp-3); }

/* Ambulance lives here, not in the masthead. Two phone numbers side by side
   made the masthead compete with itself, and the louder of the two was the
   rarer action. Up here it is always visible, always first in the DOM, and
   it stops shouting over the everyday hotline. */
.topbar-amb {
  min-height: 24px;
  display: none; align-items: center; gap: var(--sp-2);
  color: var(--cream); text-decoration: none;
  font-weight: var(--fw-semi); font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
/* The red signal lives in the icon, not the words. Salmon text sat outside the
   green / gold / cream palette and read as a mistake rather than an alert. */
.topbar-amb svg { color: var(--accent-red-on-dark); flex: none; }

.topbar-call {
  display: none; align-items: center; gap: var(--sp-2);
  color: var(--cream); text-decoration: none;
  font-weight: var(--fw-semi); font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
@media (min-width: 620px) { .topbar-call { display: inline-flex; } }
.topbar-call svg { color: var(--gold-soft); flex: none; }
.topbar-call:hover, .topbar-amb:hover { color: var(--paper); }
@media (min-width: 480px) { .topbar-amb { display: inline-flex; } }
.topbar-amb:hover { color: var(--paper); }
.topbar-amb__label { display: none; }
@media (min-width: 900px) { .topbar-amb__label { display: inline; } }
@media (max-width: 560px) { .site-topbar .open-now { display: none; } }
.site-topbar .open-now { display: inline-flex; align-items: center; gap: var(--sp-2); }
.site-topbar .open-now {
  position: relative; padding-inline-start: 18px;
}
.site-topbar .open-now::before,
.site-topbar .open-now::after {
  content: ""; position: absolute; inset-inline-start: 0; top: 50%;
  width: 8px; height: 8px; margin-top: -4px; border-radius: 50%;
  background: var(--green-500);
}
/* the ring: scale + fade only, so it never touches layout */
.site-topbar .open-now::after {
  animation: livepulse 2.4s var(--ease-out) infinite;
}
@keyframes livepulse {
  0%   { transform: scale(1);   opacity: .75; }
  70%  { transform: scale(3.2); opacity: 0; }
  100% { transform: scale(3.2); opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
  .site-topbar .open-now::after { animation: none; opacity: 0; }
}
.site-topbar__rule { width: 1px; height: 14px; background: var(--gold); opacity: .55; }

.lang-toggle { display: inline-flex; align-items: center; gap: 2px; }
.lang-toggle a, .lang-toggle span {
  display: inline-flex; align-items: center;
  padding: var(--sp-1) var(--sp-2); border-radius: var(--radius-sm);
  color: var(--cream); text-decoration: none;
  font-weight: var(--fw-medium); font-size: var(--fs-xs);
}
.lang-toggle a:hover { color: var(--gold-soft); }
.lang-toggle [aria-current="true"] { background: rgb(242 237 226 / .14); color: var(--paper); }

/* ============================== tier 2 — masthead ============================== */
.site-masthead { background: var(--bone); border-bottom: 1px solid var(--line); }
.site-masthead__inner {
  width: min(100% - 2 * var(--sp-4), var(--wrap));
  margin-inline: auto;
  min-height: var(--h-main);
  display: flex; align-items: center; gap: var(--sp-4);
}
/* Equal side columns put the search field on the true centre line, whatever
   the logo and contact block happen to measure. */
@media (min-width: 980px) {
  /* The centre column is declared, not inferred: equal 1fr sides keep the
     field on the true centre line, and the cap lets it take everything the
     logo and button are not using. */
  .site-masthead__inner {
    display: grid;
    /* Both side columns are floored at the logo width, so they always resolve
       equal and the search field lands on the true centre. With a plain 1fr
       the wider side (the logo) overflowed its share and pushed the field
       right — which is exactly what went wrong when the wordmark grew. */
    grid-template-columns:
      minmax(var(--logo-col), 1fr)
      minmax(0, 600px)
      minmax(var(--logo-col), 1fr);
    gap: var(--sp-4);
  }
  .site-masthead__inner > .logo { justify-self: start; }
  .site-masthead__inner > .search { width: 100%; }
  .site-masthead__inner > .masthead-contact { justify-self: end; }
}

/* logo lockup */
.logo { display: inline-flex; align-items: center; gap: var(--sp-3); text-decoration: none; flex: none; }
@media (min-width: 768px) { .logo { width: var(--logo-col); } }
.logo__mark { display: block; flex: none; width: 48px; height: 48px; }
@media (min-width: 768px) { .logo__mark { width: 64px; height: 64px; } }
.navbar-compact .logo__mark { width: 30px; height: 30px; }
.drawer__head .logo__mark { width: 40px; height: 40px; }
.logo__text { display: block; line-height: 1.15; }
.logo__name {
  font-family: var(--font-ui); font-weight: var(--fw-bold);
  font-size: var(--fs-md); color: var(--green-900);
  letter-spacing: var(--track-tight); white-space: nowrap;
}
@media (min-width: 768px) { .logo__name { font-size: var(--fs-lg); } }
/* One wordmark, one line: "DH Hospital Cumilla". The place name keeps a
   lighter weight so the eye still reads brand-then-location, but it is part
   of the same string rather than a second line. */
.logo__place {
  font-weight: var(--fw-medium);
  color: var(--green-600);
  letter-spacing: var(--track-tight);
}
/* the separator sits back so the two names stay the loudest parts */
.logo__dash { color: var(--muted); font-weight: var(--fw-normal); }
/* --muted is for the light masthead; in the drawer the lockup sits on dark
   green and the dash all but vanished. Same treatment the footer already uses. */
.drawer .logo__dash { color: rgb(242 237 226 / .62); }

/* search */
.search { flex: 1 1 auto; min-width: 0; position: relative; display: none; }
@media (min-width: 980px) { .search { flex: none; } }
@media (min-width: 980px) { .search { display: block; } }
.search__field {
  display: flex; align-items: center; gap: var(--sp-2);
  background: var(--paper);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-pill);
  padding-inline: var(--sp-4);
  min-height: var(--tap);
  transition: border-color var(--dur-fast) var(--ease-out), box-shadow var(--dur-fast) var(--ease-out);
}
.search__field:focus-within { border-color: var(--green-600); box-shadow: 0 0 0 4px rgb(26 125 71 / .14); }
.search__icon { color: var(--green-600); flex: none; }
.search input {
  flex: 1 1 auto; min-width: 0;
  border: 0; outline: 0; background: none;
  font: inherit; font-size: var(--fs-sm); color: var(--ink);
  padding-block: var(--sp-2);
}
.search input::placeholder { color: var(--muted); opacity: 1; transition: opacity var(--dur-fast) var(--ease-out); }
.search input.is-swapping::placeholder { opacity: 0; }
.search__hint {
  flex: none; font-size: var(--fs-xs); color: var(--muted);
  border: 1px solid var(--line); border-radius: var(--radius-sm);
  padding: 1px var(--sp-2);
}
@media (max-width: 1100px) { .search__hint { display: none; } }

.search__results {
  position: absolute; inset-inline: 0; top: calc(100% + var(--sp-2));
  z-index: var(--z-menu);
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-panel);
  padding: var(--sp-2);
  max-height: 60vh; overflow-y: auto;
}
.search__results[hidden] { display: none; }
.search__results li { list-style: none; margin: 0; }
.search__results ul { margin: 0; padding: 0; }
.search__results a {
  display: flex; align-items: baseline; gap: var(--sp-3);
  padding: var(--sp-2) var(--sp-3); border-radius: var(--radius-sm);
  text-decoration: none; color: var(--ink);
}
.search__results a:hover, .search__results a:focus-visible, .search__results a[data-active] {
  background: var(--green-100); color: var(--green-900);
}
.search__results .kind {
  margin-inline-start: auto; flex: none;
  font-size: var(--fs-xs); color: var(--muted);
  letter-spacing: var(--track-label); text-transform: uppercase;
}
.search__empty { padding: var(--sp-3); color: var(--muted); font-size: var(--fs-sm); }

/* contact block */
.masthead-contact { margin-inline-start: auto; display: flex; align-items: center; gap: var(--sp-2); flex: none; }
@media (min-width: 560px) { }

.icon-btn {
  min-width: var(--tap); min-height: var(--tap);
  display: inline-grid; place-items: center;
  background: none; border: 0; cursor: pointer;
  color: var(--green-900); border-radius: var(--radius-sm);
}
.icon-btn:hover { background: var(--green-100); }
@media (min-width: 980px) { .icon-btn--search { display: none; } }
@media (min-width: 1024px) { .icon-btn--menu { display: none; } }

/* ============================== tier 3 — nav ============================== */
.site-navbar {
  position: sticky; top: 0; z-index: var(--z-header);
  background: var(--green-900);
  border-bottom: 1px solid rgb(200 164 92 / .28);
  transition: background-color var(--dur-base) var(--ease-out),
              box-shadow var(--dur-base) var(--ease-out);
}
.site-navbar.is-stuck {
  background: var(--green-950);
  box-shadow: 0 10px 30px rgb(4 24 15 / .35);
}

/* Scroll progress. Scroll-driven CSS animation where supported, so there is
   no scroll listener eating the INP budget; elsewhere it simply never shows. */
.nav-progress {
  position: absolute; inset-inline-start: 0; bottom: -1px;
  height: 2px; width: 100%;
  background: var(--gold);
  transform: scaleX(0); transform-origin: 0 50%;
  opacity: 0;
}
@supports (animation-timeline: scroll()) {
  .is-stuck .nav-progress {
    opacity: 1;
    animation: navprogress linear both;
    animation-timeline: scroll(root block);
  }
  @keyframes navprogress { to { transform: scaleX(1); } }
}
@media (prefers-reduced-motion: reduce) { .nav-progress { display: none; } }
.site-navbar__inner {
  position: relative;
  width: min(100% - 2 * var(--sp-4), var(--wrap));
  margin-inline: auto;
  min-height: var(--h-nav);
  display: flex; align-items: center; gap: var(--sp-3);
}
@media (min-width: 1024px) {
  .site-navbar__inner {
    display: grid; grid-template-columns: 1fr auto 1fr; gap: var(--sp-3);
  }
  .site-navbar__inner > .navbar-compact { grid-column: 1; justify-self: start; }
  .site-navbar__inner > .navlist        { grid-column: 2; justify-self: center; }
  .site-navbar__inner > .navbar-right   { grid-column: 3; justify-self: end; }
}

/* compact logo + call, revealed only once the bar sticks */
.navbar-compact {
  display: flex; align-items: center; gap: var(--sp-2);
  flex: none;
}
@media (min-width: 1024px) {
  .navbar-compact {
    opacity: 0; transform: translateX(-6px); pointer-events: none;
    transition: opacity var(--dur-base) var(--ease-out), transform var(--dur-base) var(--ease-out);
  }
  .is-stuck .navbar-compact { opacity: 1; transform: none; pointer-events: auto; }
  .navbar-compact__name { display: none; }
}

.navbar-right { display: flex; align-items: center; gap: var(--sp-3); }
/* The masthead carries the button; this one takes over once that row is gone,
   so the main action is never off-screen. */
.site-navbar .nav-cta { display: none; }
@media (min-width: 1024px) {
  .is-stuck .site-navbar .nav-cta {
    display: inline-flex;
    animation: fadein var(--dur-base) var(--ease-out) both;
  }
}
.mega .nav-cta { display: inline-flex; }
@keyframes fadein { from { opacity: 0; transform: translateX(6px); } to { opacity: 1; transform: none; } }
.navbar-compact__name {
  font-family: var(--font-ui); font-weight: var(--fw-bold); font-size: var(--fs-sm);
  color: var(--paper); letter-spacing: var(--track-tight); text-decoration: none;
  white-space: nowrap;
}


.navlist {
  list-style: none; margin: 0; padding: 0;
  display: none; align-items: stretch; gap: 0;
  position: relative; min-width: 0;
}
@media (min-width: 1024px) { .navlist { display: flex; } }

.navlist > li { display: flex; }
.navlist > .nav-indicator { display: block; }
.navlink {
  display: inline-flex; align-items: center; gap: var(--sp-2);
  padding-inline: clamp(var(--sp-2), 0.9vw, var(--sp-4)); min-height: var(--h-nav);
  color: var(--cream); text-decoration: none;
  font-family: var(--font-ui); font-weight: var(--fw-semi); font-size: var(--fs-sm);
  letter-spacing: var(--track-tight);
  background: none; border: 0; cursor: pointer;
  white-space: nowrap;
}
.navlink:hover, .navlink[aria-expanded="true"] { color: var(--paper); }
.navlink__caret { transition: transform var(--dur-fast) var(--ease-out); }
.navlink[aria-expanded="true"] .navlink__caret { transform: rotate(180deg); }

/* the sliding indicator — position and width are set by site.js */
.nav-indicator {
  position: absolute; bottom: 0; inset-inline-start: 0;
  height: 3px; width: 0;
  background: var(--paper);   /* white on green-900 = 14.34:1 */
  border-radius: 3px 3px 0 0;
  opacity: 0;
  transform: translateX(0);
  transition: transform var(--dur-base) var(--ease-out),
              width var(--dur-base) var(--ease-out),
              opacity var(--dur-fast) var(--ease-out);
  pointer-events: none;
}

.nav-cta {
  position: relative; overflow: hidden;
  display: inline-flex; align-items: center; gap: var(--sp-2);
  min-height: 44px; padding-inline: var(--sp-5);
  background: var(--green-700); color: var(--paper);
  border-radius: var(--radius-btn);
  text-decoration: none;
  font-family: var(--font-ui); font-weight: var(--fw-bold); font-size: var(--fs-sm);
  letter-spacing: var(--track-tight); white-space: nowrap; flex: none;
  transition: transform var(--dur-press) var(--ease-out),
              background-color var(--dur-fast) var(--ease-out),
              box-shadow var(--dur-fast) var(--ease-out);
  /* pointer position, written by site.js. Defaults live here so the button
     still renders correctly with JS off (and so audit.py check 18 passes). */
  --mx: 50%;
  --my: 50%;
  box-shadow: inset 0 1px 0 rgb(255 255 255 / .24),
              inset 0 -1px 0 rgb(4 24 15 / .26);
}
.nav-cta > * { position: relative; z-index: 2; }

/* Bilingual buttons must measure the same. "Book appointment" is a good deal
   wider than "সিরিয়াল নিন", and with the search field fixed at the same width in
   both editions, that difference showed up as a gap beside the Bangla field —
   which read as a narrower search box even though it is identical.
   A shared minimum makes the two headers line up pixel for pixel. */
.masthead-cta, .site-navbar .nav-cta {
  min-width: 13.2rem;
  justify-content: center;
}

/* ---- crystal ----
   Three layers, and none of them is allowed to wash out the label:
     bevel   a fixed 1px facet on the top and bottom edges
     glare   a soft highlight that follows the pointer across the face
     beam    a bright line running along the top edge only

   The glare is capped at .14 alpha. Measured: white-on-green survives a white
   overlay up to .18 (4.61:1) and fails at .22 (4.21:1), so .14 keeps the
   hover state at 5.10:1 with room to spare. The beam is brighter but rides
   the 2px top edge, where no glyph ever sits. */
.nav-cta::before {
  content: ""; position: absolute; inset: 0; z-index: 0;
  border-radius: inherit;
  background: radial-gradient(130px circle at var(--mx) var(--my),
              rgb(255 255 255 / .14), transparent 62%);
  opacity: 0;
  transition: opacity var(--dur-fast) var(--ease-out);
}
.nav-cta:hover::before, .nav-cta:focus-visible::before { opacity: 1; }

.nav-cta::after {
  content: ""; position: absolute; z-index: 1;
  inset-block-start: 0; inset-inline-start: 0;
  height: 2px; width: 100%;
  background: linear-gradient(90deg, transparent 0%, transparent 34%,
              rgb(255 255 255 / .95) 47%, rgb(255 255 255 / .35) 53%,
              transparent 66%, transparent 100%);
  transform: translateX(-100%);
  transition: transform 760ms var(--ease-out);
}
.nav-cta:hover::after, .nav-cta:focus-visible::after { transform: translateX(100%); }
.nav-cta:hover {
  background: var(--green-600); color: var(--paper);
  box-shadow: inset 0 1px 0 rgb(255 255 255 / .3),
              inset 0 -1px 0 rgb(4 24 15 / .26),
              var(--shadow-lift);
}

/* A button belongs to the surface it sits on. Deep green reads as the action
   on the light masthead; on the dark bar and the mega panel the same green
   would disappear, so it flips to cream.
   (Gold measured 2.22:1 against the bone masthead — below the 3:1 floor for
   non-text contrast. It stays a hairline and label accent, not a button.) */
.site-navbar .nav-cta,
.mega .nav-cta {
  background: var(--cream); color: var(--green-950);
}
.site-navbar .nav-cta:hover,
.mega .nav-cta:hover {
  background: var(--paper); color: var(--green-950);
}
.site-navbar .nav-cta,
.mega .nav-cta {
  box-shadow: inset 0 1px 0 rgb(255 255 255 / .7),
              inset 0 -1px 0 rgb(4 24 15 / .18);
}
.site-navbar .nav-cta::before,
.mega .nav-cta::before {
  background: radial-gradient(130px circle at var(--mx) var(--my),
              rgb(4 24 15 / .2), transparent 62%);
}
.site-navbar .nav-cta::after,
.mega .nav-cta::after {
  background: linear-gradient(90deg, transparent 34%,
              rgb(4 24 15 / .55) 47%, rgb(4 24 15 / .2) 53%, transparent 66%);
}
.nav-cta:active { transform: scale(.98); }
.nav-cta__arrow { transition: transform var(--dur-fast) var(--ease-out); }
.nav-cta:hover .nav-cta__arrow { transform: translateX(3px); }
@media (prefers-reduced-motion: reduce) {
  .nav-cta::before, .nav-cta::after { display: none; }
  .nav-cta__arrow { transition: none; }
}


/* ============================== mega menu ============================== */
.mega {
  position: absolute; inset-inline: 0; top: 100%;
  z-index: var(--z-menu);
  background: var(--green-900);
  border-top: 1px solid rgb(200 164 92 / .3);
  box-shadow: var(--shadow-panel);
  display: grid; grid-template-rows: 0fr;
  transition: grid-template-rows var(--dur-base) var(--ease-out),
              opacity var(--dur-fast) var(--ease-out);
  opacity: 0;
  overflow: hidden;
}
.mega[data-open="true"] { grid-template-rows: 1fr; opacity: 1; }
.mega__clip { min-height: 0; overflow: hidden; }
.mega__inner {
  width: min(100% - 2 * var(--sp-4), var(--wrap));
  margin-inline: auto;
  padding-block: var(--sp-4);
  display: grid; gap: var(--sp-4);
  /* Two rows of five plus the strip fit any laptop. The cap is a safety valve
     for very short windows, not the normal state — nobody should have to
     scroll a menu to reach the last department. */
  max-height: calc(100vh - var(--h-utility) - var(--h-nav) - var(--sp-4));
  overflow-y: auto;
}

.mega__grid { display: grid; gap: var(--sp-2); }
@media (min-width: 620px)  { .mega__grid { grid-template-columns: repeat(3, 1fr); } }
@media (min-width: 1024px) { .mega__grid { grid-template-columns: repeat(4, 1fr); } }
@media (min-width: 1180px) { .mega__grid { grid-template-columns: repeat(5, 1fr); } }
/* a three-item panel should not stretch to five columns */
@media (min-width: 620px)  { .mega__grid--3 { grid-template-columns: repeat(3, 1fr); } }
@media (min-width: 1024px) { .mega--compact .mega__inner { max-width: 940px; } }

.mega__item {
  display: block; padding: var(--sp-3);
  position: relative;
  opacity: 0; transform: translateY(6px);
  border-radius: var(--radius); text-decoration: none;
  border: 1px solid transparent;
  transition: background-color var(--dur-fast) var(--ease-out),
              border-color var(--dur-fast) var(--ease-out),
              opacity var(--dur-base) var(--ease-out),
              transform var(--dur-base) var(--ease-out);
}
.mega__item:nth-child(1) { transition-delay: 15ms; }
.mega__item:nth-child(2) { transition-delay: 33ms; }
.mega__item:nth-child(3) { transition-delay: 51ms; }
.mega__item:nth-child(4) { transition-delay: 69ms; }
.mega__item:nth-child(5) { transition-delay: 87ms; }
.mega__item:nth-child(6) { transition-delay: 105ms; }
.mega__item:nth-child(7) { transition-delay: 123ms; }
.mega__item:nth-child(8) { transition-delay: 141ms; }
.mega__item:nth-child(9) { transition-delay: 159ms; }
.mega__item:nth-child(10) { transition-delay: 177ms; }
.mega__item[data-live] { background: rgb(242 237 226 / .1); border-color: rgb(200 164 92 / .5); }
.mega[data-open="true"] .mega__item { opacity: 1; transform: none; }
.mega__item:hover, .mega__item:focus-visible {
  background: rgb(242 237 226 / .07);
  border-color: rgb(200 164 92 / .35);
  transform: translateY(-1px);
}
.mega__name {
  display: block; color: var(--paper);
  font-weight: var(--fw-semi); font-size: var(--fs-sm);
  line-height: 1.35; margin-bottom: 2px;
}
.mega__gloss {
  display: block; color: rgb(242 237 226 / .62); font-size: var(--fs-xs);
  line-height: 1.4;
}

.mega__aside {
  border: 1px solid rgb(200 164 92 / .35);
  border-radius: var(--radius-lg);
  padding: var(--sp-3) var(--sp-4);
  background: rgb(4 24 15 / .5);
  display: grid; gap: var(--sp-1) var(--sp-4); align-items: center;
}
@media (min-width: 900px) {
  .mega__aside { grid-template-columns: auto 1fr auto; }
  .mega__aside .mega__eyebrow { grid-row: 1; }
  .mega__aside h3 { grid-row: 1; }
  .mega__aside p:not(.mega__eyebrow) { grid-column: 1 / -2; grid-row: 2; }
  .mega__aside .nav-cta { grid-column: 3; grid-row: 1 / span 2; }
}
.mega__eyebrow {
  color: var(--gold-soft); font-size: var(--fs-xs); font-weight: var(--fw-bold);
  letter-spacing: var(--track-label); text-transform: uppercase;
  margin: 0; white-space: nowrap;
}
.mega__aside h3 { color: var(--paper); font-size: var(--fs-md); margin: 0; }
.mega__aside > * { transition: opacity var(--dur-fast) var(--ease-out); }
.mega__aside.is-swapping > * { opacity: 0; }
.mega__aside p { color: rgb(242 237 226 / .78); font-size: var(--fs-sm); margin: 0; }

/* ============================== mobile drawer ============================== */
.drawer-backdrop {
  position: fixed; inset: 0; z-index: var(--z-drawer);
  background: rgb(4 24 15 / .55);
  opacity: 0; transition: opacity var(--dur-base) var(--ease-out);
}
.drawer-backdrop[hidden] { display: none; }
.drawer-backdrop[data-open="true"] { opacity: 1; }

.drawer {
  position: fixed; inset-block: 0; inset-inline-end: 0; z-index: var(--z-drawer);
  width: min(88vw, 380px);
  background: var(--green-900); color: var(--cream);
  display: flex; flex-direction: column;
  transform: translateX(100%);
  transition: transform var(--dur-base) var(--ease-out);
  overflow-y: auto;
}
.drawer[data-open="true"] { transform: none; }
.drawer[hidden] { display: none; }

.drawer__head {
  display: flex; align-items: center; gap: var(--sp-3);
  padding: var(--sp-4); border-bottom: 1px solid rgb(242 237 226 / .16);
}
.drawer__head .logo__name { color: var(--paper); }
.drawer__head .logo__place { color: rgb(242 237 226 / .7); }
.drawer__close {
  margin-inline-start: auto;
  min-width: var(--tap); min-height: var(--tap);
  display: grid; place-items: center;
  background: none; border: 0; color: var(--cream); cursor: pointer;
  border-radius: var(--radius-sm); font-size: var(--fs-xl);
}
.drawer__close:hover { background: rgb(242 237 226 / .12); }

.drawer__body { padding: var(--sp-3) var(--sp-4) var(--sp-6); }
.drawer__list { list-style: none; margin: 0; padding: 0; }
.drawer__list > li { border-bottom: 1px solid rgb(242 237 226 / .12); }
.drawer__list a, .drawer__list summary {
  display: flex; align-items: center; gap: var(--sp-2);
  min-height: var(--tap); padding-block: var(--sp-2);
  color: var(--cream); text-decoration: none;
  font-weight: var(--fw-semi); font-size: var(--fs-md);
}
.drawer__list a:hover, .drawer__list summary:hover { color: var(--paper); }
.drawer details > summary { cursor: pointer; list-style: none; }
.drawer details > summary::-webkit-details-marker { display: none; }
.drawer details > summary::after {
  content: "\203a"; margin-inline-start: auto;
  transition: transform var(--dur-fast) var(--ease-out);
  font-size: var(--fs-xl); line-height: 1;
}
.drawer details[open] > summary::after { transform: rotate(90deg); }
.drawer__sub { list-style: none; margin: 0 0 var(--sp-2); padding-inline-start: var(--sp-3); }
/* Name on its own line, plain-language gloss under it.
   Inline, the two ran together into one long string that wrapped mid-phrase --
   "নবজাতক ও শিশু" broke across two lines and pushed its gloss out of line with
   every other row. Stacked, each row is scannable and the column edge is
   straight. The .drawer__list rule sets display:flex, so this overrides it. */
.drawer__sub a {
  display: block; padding-block: var(--sp-2);
  font-weight: var(--fw-normal); font-size: var(--fs-sm); min-height: 42px;
  line-height: 1.45;
}
.drawer__sub .gloss {
  display: block; margin-top: 1px;
  color: rgb(242 237 226 / .62); font-size: var(--fs-xs); line-height: 1.4;
}

.drawer__cta { display: grid; gap: var(--sp-2); margin-top: var(--sp-5); }
.drawer__cta a {
  display: flex; align-items: center; justify-content: center; gap: var(--sp-2);
  min-height: var(--tap); border-radius: var(--radius-pill);
  text-decoration: none; font-weight: var(--fw-bold);
}
.drawer__cta .is-call { background: var(--gold); color: var(--green-950); }
.drawer__cta .is-amb  { background: var(--accent-red); color: var(--paper); }

/* mobile search panel (revealed by the search icon under 980px) */
.msearch { background: var(--bone); border-bottom: 1px solid var(--line); }
.msearch[hidden] { display: none; }
.msearch .search { display: block; max-width: none; }
.msearch__inner { width: min(100% - 2 * var(--sp-4), var(--wrap)); margin-inline: auto; padding-block: var(--sp-3); }

/* ============================== reduced motion ============================== */
@media (prefers-reduced-motion: reduce) {
  .mega, .drawer, .drawer-backdrop, .nav-indicator, .navbar-compact { transition: none; }
  .mega__item { opacity: 1; transform: none; transition: none; }
  .amb-pill:active, .nav-cta:active, .mega__item:hover { transform: none; }
}

/* ============================== phones ==============================
   Everything above this point was written for the desktop lockup, and on a
   360px screen it forced the document to 596px — the whole page scrolled
   sideways. Below 1024px the header is a different object:

     masthead  logo, then the search and menu buttons. The masthead CTA goes:
               the sticky bar under it carries one, and the fixed bottom bar
               carries "serial" as well. Three booking buttons on one screen
               is not three times the conversion.
     navbar    stays sticky, but only the mark and a compact CTA. The wordmark
               beside it is already on screen in the masthead.

   Nothing here is allowed to be flex: none — that is what stopped the row
   shrinking in the first place. */
@media (max-width: 1023px) {
  .site-masthead__inner { gap: var(--sp-3); }

  /* the logo takes what is left and truncates rather than pushing the row */
  .logo { flex: 0 1 auto; min-width: 0; }
  .logo__text { min-width: 0; }
  .logo__name {
    display: block; min-width: 0;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  }

  .masthead-contact { gap: 0; flex: none; }
  .masthead-cta { display: none; }

  /* The whole nav tier goes. Its two contents are already hidden at this
     width — the link list needs 1024px, and the CTA only appears once the
     bar sticks on a desktop — so all that was left was a green strip with a
     second copy of the logo sitting under the first. Nothing is lost: the
     drawer carries the navigation, the masthead carries menu and search, and
     the fixed bottom bar carries hotline, ambulance and serial the whole way
     down the page. */
  .site-navbar { display: none; }
}

@media (max-width: 560px) {
  .logo__mark { width: 40px; height: 40px; }
  .logo { gap: var(--sp-2); }
  .logo__name { font-size: var(--fs-sm); }
  /* the tap target stays 44px; only the box around the glyph tightens */
  .icon-btn { min-width: 42px; }
}

/* "All departments" — the hub itself, listed with the ten it lists. Marked out
   so it does not read as an eleventh department. */
.mega__item--all {
  display: flex; align-items: center; justify-content: center;
  box-shadow: inset 0 0 0 1px rgb(242 237 226 / .28);
}
.mega__item--all .mega__name { color: var(--cream); }
/* was --green-800 -- a dark green on the drawer's dark green ground, which is
   all but invisible. Gold is the drawer's accent and reads at 7.9:1 here. */
.drawer__sub .is-all { font-weight: var(--fw-bold); color: var(--gold-soft); }

/* home.css — homepage + header/footer components
   Owner: frontend-builder · appended to base.css to produce site.css
   Every custom property used here is defined in tokens.css.
*/

/* ============================== hero ==============================
   Full-bleed photograph with the copy over it.

   The desktop gradient is baked INTO the artwork — its left half is solid
   #031a06, measured at 18.19:1 against white text. So the CSS scrim here is
   only a light safety floor; running the full wash again would darken the
   right-hand side of the photo for no reason.

   Mobile is different: object-fit crops a 2.78:1 image to the centre, which is
   the bright half, so the bottom-up scrim there stays at full strength. */
.hero { position: relative; background: var(--green-900); isolation: isolate; }

.hero__media { position: absolute; inset: 0; z-index: 0; overflow: hidden; }
.hero__media img, .hero__media picture {
  width: 100%; height: 100%; object-fit: cover; display: block;
  /* Bias up so the tower keeps its roofline, and let the crop eat the left —
     that half of the frame is flat colour, so nothing is lost there, while
     cropping from the right would cut into the building. */
  object-position: 55% 22%;
}
@media (min-width: 1400px) { .hero__media img { object-position: 50% 25%; } }
/* A phone crops a 2.78:1 frame to roughly 0.8:1, and at 55% that lands on the
   flat green half — the building ends up a sliver at the edge. Measured on the
   file, the hospital sits right of centre, so the phone crop goes there. */
@media (max-width: 899px) { .hero__media img { object-position: 80% 30%; } }

.hero::after {
  content: ""; position: absolute; inset: 0; z-index: 1;
  background: linear-gradient(to top,
              rgb(2 26 6 / .90) 0%, rgb(2 26 6 / .80) 46%,
              rgb(2 26 6 / .70) 72%, rgb(2 26 6 / .30) 100%);
}
@media (min-width: 900px) {
  .hero::after {
    background:
      /* 1. vertical falloff — light lands on a scene, it does not wipe across
            it. Without this the horizontal ramp reads as a mechanical wipe. */
      linear-gradient(to bottom,
        rgb(2 26 6 / .34) 0%, rgb(2 26 6 / .06) 24%,
        rgb(2 26 6 / 0) 58%, rgb(2 26 6 / .30) 100%),
      /* 2. eased horizontal ramp. The artwork already carries its own, which
            climbs 115 luminance in 19% of the width — a visible seam. These
            stops stretch that climb and cut the steepest step from +29.6 to
            +22.9, measured on the actual file. */
      linear-gradient(to right,
        rgb(2 26 6 / .46) 0%,
        rgb(2 26 6 / .44) 34%,
        rgb(2 26 6 / .36) 46%,
        rgb(2 26 6 / .28) 54%,
        rgb(2 26 6 / .20) 62%,
        rgb(2 26 6 / .12) 70%,
        rgb(2 26 6 / .05) 79%,
        rgb(2 26 6 / 0) 90%);
  }
}

.hero__inner { position: relative; z-index: 2; }
.hero__body {
  width: min(100% - 2 * var(--sp-4), var(--wrap));
  margin-inline: auto;
  padding-block: var(--sp-6);
  display: flex; flex-direction: column; justify-content: center;
  /* Fit the screen rather than dictate to it: the header above is ~174px, so
     the hero takes what is left, floors at 340px and never grows past 500px.
     svh (not vh) so the mobile address bar does not push the buttons off. */
  min-height: clamp(340px, calc(100vh - 210px), 500px);
  min-height: clamp(340px, calc(100svh - 210px), 500px);
}
/* The copy now measures about 300px on a phone, so the cap comes down with it
   — the hero was holding 500px for content that had stopped needing it. */
@media (max-width: 560px) {
  .hero__body {
    min-height: clamp(320px, calc(100vh - 200px), 430px);
    min-height: clamp(320px, calc(100svh - 200px), 430px);
  }
}
@media (min-width: 900px) {
  .hero__body {
    padding-block: var(--sp-7);
    min-height: clamp(380px, calc(100vh - 220px), 520px);
    min-height: clamp(380px, calc(100svh - 220px), 520px);
  }
}

.hero h1 {
  margin: 0 0 var(--sp-4);
  color: var(--paper);
  font-size: clamp(1.8rem, 3.6vw, 2.7rem);
  line-height: 1.16;
  /* Was 26ch. `ch` is the width of the font's "0", so the box itself resized
     while the display face was still loading and the headline rewrapped — the
     jump Billal reported. em depends only on font-size, which does not move.
     The two editions get different values because 26ch genuinely resolved
     differently in each: Noto Serif Bengali's zero is narrower than Instrument
     Sans's. Both numbers are the measured settled width, so neither edition's
     layout changes. */
  max-width: var(--hero-measure);
}
/* The break is placed by hand rather than left to text-wrap, so the headline
   reads the same on every screen wide enough to hold it. Below that it wraps
   naturally — a forced break on a narrow phone would look worse than none. */
.hero__break { display: none; }
@media (min-width: 620px) { .hero__break { display: inline; } }
.hero__lead {
  margin: 0 0 var(--sp-5);
  color: var(--cream);
  font-size: var(--fs-lg);
  max-width: 34.632em;          /* one line at the display size */
}
.hero__actions { display: flex; flex-wrap: wrap; gap: var(--sp-3); }
/* One row on a phone. At the desktop size the pair measures ~393px against
   the ~380px a 412px screen offers — barely over, so they stacked and cost
   the hero an extra 68px of height. Trimming the padding and dropping to
   --fs-sm brings them to ~345px and the section gets shorter twice over. */
@media (max-width: 560px) {
  .hero__actions { flex-wrap: nowrap; gap: var(--sp-2); }
  .hero__actions .btn {
    padding-inline: var(--sp-4); font-size: var(--fs-sm);
    white-space: nowrap; flex: 0 1 auto; min-width: 0;
  }
}

/* the outline button needs light edges on a dark ground */
.hero .btn--ghost {
  color: var(--paper);
  box-shadow: inset 0 0 0 2px rgb(255 255 255 / .55);
  background: rgb(255 255 255 / .06);
}
.hero .btn--ghost:hover { color: var(--green-950); background: var(--paper); }

/* ============================== emergency ==============================
   Brand green, not a red slab. Red stays the signal — the pulse, the numerals,
   the rail along the top — because a red that means "urgent" only works while
   it is rare.

   That is also the accessible answer, not just the tasteful one: --accent-red
   measures 1.21:1 against --green-700, 2.20:1 against --green-900 and 2.79:1
   against --green-950, and WCAG 1.4.11 wants 3:1 for a control. There is no
   shade of our green a red button can legally sit on. A white slab with red
   numerals clears it easily and shouts louder anyway.

   The accent is the gold from the wordmark's "Cumilla", not red. Note what
   that forces: gold on a white button face measures 2.35:1, so the white slab
   had to become the gold slab, with near-black green numerals on it. That is
   the higher-contrast pairing anyway.

   Verified on --green-900 (#03320b):
     white                 12.3:1   heading
     --cream at 82%         ~8.5:1  body copy
     --gold-soft            7.88:1  status label, hotline numerals
     --gold (button face)   6.09:1  ambulance slab
     --green-950 on gold    7.74:1  the ambulance numerals themselves
     --accent-red-on-dark   5.00:1  kept for the one failure message        */
.emergency-band {
  position: relative;
  background-color: var(--green-900);
  /* a slow wash off to one side so the band is not a flat rectangle; it sits
     away from the text column, so nothing measured above changes */
  background-image: radial-gradient(90% 130% at 88% 0%, rgb(35 158 56 / .20), transparent 62%);
  color: var(--cream);
}
/* a gold hairline across the top, the same gold as "Cumilla" in the wordmark */
.emergency-band::before {
  content: ""; position: absolute; inset-inline: 0; top: 0; height: 3px;
  background: var(--gold);
}

.eg { display: grid; gap: var(--sp-5); }
@media (min-width: 900px) {
  .eg { grid-template-columns: minmax(0, 1.1fr) minmax(0, .9fr); gap: var(--sp-8); align-items: center; }
}

/* ---- left: the call ---- */
.eg__status {
  display: inline-flex; align-items: center; gap: var(--sp-2);
  margin: 0 0 var(--sp-3);
  font-size: var(--fs-xs); font-weight: var(--fw-bold);
  letter-spacing: var(--track-label); text-transform: uppercase;
  color: var(--gold-soft);
}
html[lang="bn"] .eg__status { text-transform: none; letter-spacing: normal; }
.eg__dot {
  position: relative; width: 9px; height: 9px; flex: none;
  border-radius: 50%; background: var(--gold-soft);
}
.eg__dot::after {
  content: ""; position: absolute; inset: 0; border-radius: 50%;
  background: var(--gold-soft);
  animation: livepulse 2.4s var(--ease-out) infinite;
}
@media (prefers-reduced-motion: reduce) { .eg__dot::after { animation: none; opacity: 0; } }

.emergency-band h2 { margin: 0; color: var(--paper); font-size: var(--fs-2xl); }
.eg__lead {
  margin: var(--sp-3) 0 var(--sp-5);
  max-width: 27.972em; color: rgb(242 237 226 / .82);
}

.eg__calls { display: flex; flex-wrap: wrap; gap: var(--sp-3); }
.eg__num, .eg__alt {
  display: inline-flex; align-items: center; gap: var(--sp-3);
  min-height: 68px; padding-inline: var(--sp-5);
  border-radius: var(--radius); text-decoration: none;
  transition: transform var(--dur-press) var(--ease-out),
              box-shadow var(--dur-press) var(--ease-out),
              background-color var(--dur-fast) var(--ease-out);
}
.eg__num {
  background: var(--gold); color: var(--green-950);
  box-shadow: 0 12px 30px rgb(2 26 6 / .42);
}
.eg__num:hover {
  color: var(--green-950); background: var(--gold-soft);
  transform: translateY(-2px);
  box-shadow: 0 18px 38px rgb(2 26 6 / .48);
}
.eg__num:active { transform: translateY(0); }
.eg__alt {
  color: var(--gold-soft);
  box-shadow: inset 0 0 0 1px rgb(200 164 92 / .45);
}
.eg__alt:hover { color: var(--gold-soft); background: rgb(200 164 92 / .1); box-shadow: inset 0 0 0 1px var(--gold); }

.eg__num-text {
  display: grid; font-family: var(--font-ui); font-weight: var(--fw-bold);
  font-size: var(--fs-xl); line-height: 1.15; font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.eg__alt .eg__num-text { font-size: var(--fs-lg); }
.eg__num-text small {
  font-size: var(--fs-xs); font-weight: var(--fw-semi);
  letter-spacing: var(--track-label); text-transform: uppercase;
}
/* set outright rather than by opacity — a faded label on gold drops under 4.5 */
.eg__num .eg__num-text small { color: rgb(2 26 6 / .78); }
.eg__alt .eg__num-text small { color: rgb(200 164 92 / .92); }
html[lang="bn"] .eg__num-text small { text-transform: none; letter-spacing: normal; }

.eg__ico { display: inline-flex; flex: none; }
.eg__ico svg { width: 18px; height: 18px; display: block; }
.eg__ico--lg svg { width: 30px; height: 30px; }

/* ---- right: what the dispatcher will ask for ----
   Not decoration. The hardest part of getting an ambulance here is saying
   where you are, so this column is the three questions, then a shortcut that
   answers the first one for you. */
.eg__aside {
  border-radius: var(--radius-lg); padding: var(--sp-5);
  background: rgb(242 237 226 / .055);
  box-shadow: inset 0 0 0 1px rgb(200 164 92 / .22);
}
.eg__aside h3 { margin: 0 0 var(--sp-4); color: var(--paper); font-size: var(--fs-md); }

.eg__steps { counter-reset: eg; list-style: none; margin: 0; padding: 0; display: grid; gap: var(--sp-3); }
.eg__steps li {
  position: relative; margin: 0; padding-inline-start: var(--sp-6);
  font-size: var(--fs-sm); color: rgb(242 237 226 / .84);
}
.eg__steps li::before {
  counter-increment: eg; content: counter(eg);
  position: absolute; inset-inline-start: 0; top: 0;
  width: 22px; height: 22px; border-radius: 50%;
  display: grid; place-items: center;
  background: rgb(200 164 92 / .18); color: var(--gold-soft);
  font-size: 11px; font-weight: var(--fw-bold); font-variant-numeric: tabular-nums;
}
html[lang="bn"] .eg__steps li::before { content: counter(eg, bengali); }

.eg__geo-wrap { margin-top: var(--sp-5); }
.eg__geo-wrap[hidden] { display: none; }
.eg__geo {
  display: inline-flex; align-items: center; gap: var(--sp-2);
  min-height: var(--tap); padding-inline: var(--sp-4);
  border: 0; border-radius: var(--radius);
  background: rgb(242 237 226 / .1); color: var(--cream);
  box-shadow: inset 0 0 0 1px rgb(242 237 226 / .3);
  font: inherit; font-size: var(--fs-sm); font-weight: var(--fw-semi);
  cursor: pointer; text-align: start;
  transition: background-color var(--dur-fast) var(--ease-out);
}
.eg__geo:hover { background: rgb(242 237 226 / .18); }
.eg__geo[disabled] { cursor: progress; opacity: .7; }
.eg__note { margin: var(--sp-2) 0 0; font-size: var(--fs-xs); color: rgb(242 237 226 / .58); }
.eg__note.is-warn { color: var(--accent-red-on-dark); }

/* ============================== symptom router ==============================
   Type a problem, or pick one — get the department and the doctors who sit in
   it, without leaving the page. The chips are real links to the hubs, so with
   JS off this degrades to what it used to be: a set of symptom links.

   Everything animated is transform/opacity. The result panel is revealed, not
   built, so nothing reflows the page below except its own height.            */
.sx__lead { max-width: 43.956em; color: var(--muted); margin: 0 0 var(--sp-5); }

/* ---- search ---- */
.sx__search { position: relative; max-width: 560px; }
.sx__ico { display: inline-flex; }
.sx__ico svg { width: 18px; height: 18px; display: block; }
.sx__search > .sx__ico {
  position: absolute; inset-inline-start: var(--sp-4); top: 50%; margin-top: -9px;
  color: var(--muted); pointer-events: none;
}
.sx__input {
  width: 100%; min-height: 52px;
  padding-inline: calc(var(--sp-4) * 2 + 18px) var(--sp-8);
  border: 1px solid var(--line-strong); border-radius: var(--radius);
  background: var(--paper); color: var(--ink);
  font: inherit; font-size: var(--fs-md);
  transition: border-color var(--dur-fast) var(--ease-out),
              box-shadow var(--dur-fast) var(--ease-out);
}
.sx__input::placeholder { color: var(--muted); }
.sx__input:focus {
  outline: none;
  border-color: var(--green-600);
  box-shadow: 0 0 0 3px rgb(16 125 34 / .18);
}
.sx__input::-webkit-search-cancel-button { display: none; }
.sx__clear {
  position: absolute; inset-inline-end: var(--sp-2); top: 50%;
  transform: translateY(-50%);
  min-width: 36px; min-height: 36px;
  border: 0; border-radius: var(--radius-sm);
  background: none; color: var(--muted);
  font-size: var(--fs-xl); line-height: 1; cursor: pointer;
}
.sx__clear:hover { color: var(--ink); background: var(--green-100); }
.sx__clear[hidden] { display: none; }

/* type-ahead */
.sx__list {
  position: absolute; inset-inline: 0; top: calc(100% + 4px); z-index: var(--z-menu);
  margin: 0; padding: var(--sp-2); list-style: none;
  max-height: 320px; overflow-y: auto;
  background: var(--paper);
  border: 1px solid var(--line); border-radius: var(--radius);
  box-shadow: var(--shadow-panel);
}
.sx__list[hidden] { display: none; }
.sx__opt {
  display: flex; align-items: baseline; justify-content: space-between; gap: var(--sp-3);
  margin: 0; padding: var(--sp-3); border-radius: var(--radius-sm);
  cursor: pointer; font-size: var(--fs-sm);
}
.sx__opt:hover, .sx__opt.is-on { background: var(--green-100); }
.sx__opt em { font-style: normal; color: var(--muted); font-size: var(--fs-xs); white-space: nowrap; }
.sx__opt mark { background: none; color: var(--green-700); font-weight: var(--fw-bold); }

/* ---- chips ---- */
.sx__chips { display: flex; flex-wrap: wrap; gap: var(--sp-2); margin-top: var(--sp-4); }
.sx__chip {
  display: inline-flex; align-items: center;
  min-height: var(--tap); padding-inline: var(--sp-4);
  border: 1px solid var(--line); border-radius: var(--radius-pill);
  background: var(--paper); color: var(--ink);
  font-size: var(--fs-sm); font-weight: var(--fw-semi); text-decoration: none;
  transition: background-color var(--dur-fast) var(--ease-out),
              border-color var(--dur-fast) var(--ease-out),
              color var(--dur-fast) var(--ease-out),
              transform var(--dur-press) var(--ease-out);
}
.sx__chip:hover { border-color: var(--green-600); color: var(--green-700); transform: translateY(-1px); }
.sx__chip.is-on { background: var(--green-700); border-color: var(--green-700); color: var(--paper); }
.sx__chip[hidden] { display: none; }
/* the extra chips are hidden only once JS can offer a way to reveal them */
.sx.is-collapsed .sx__chip--extra { display: none; }

.sx__more {
  margin-top: var(--sp-3);
  min-height: 40px; padding-inline: var(--sp-4);
  border: 0; border-radius: var(--radius-pill);
  background: none; color: var(--green-700);
  font: inherit; font-size: var(--fs-sm); font-weight: var(--fw-semi);
  text-decoration: underline; text-underline-offset: 3px; cursor: pointer;
}
.sx__more[hidden] { display: none; }
.sx__none { margin-top: var(--sp-4); color: var(--muted); font-size: var(--fs-sm); }
.sx__none[hidden] { display: none; }

/* ---- result ---- */
.sx__result { margin-top: var(--sp-5); }
.sx__result[hidden] { display: none; }
.js-motion .sx__result.is-in { animation: sx-in var(--dur-base) var(--ease-out) both; }
@keyframes sx-in {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: none; }
}

/* A red flag jumps the queue. Sending someone with crushing chest pain to a
   Tuesday-evening serial is the worst thing this section could do, so the
   ambulance sits above the chamber list and the list is framed as "later". */
.sx__urgent {
  margin-bottom: var(--sp-4); padding: var(--sp-4);
  border-radius: var(--radius);
  background: var(--accent-red); color: var(--paper);
}
.sx__urgent[hidden] { display: none; }
.sx__urgent p { margin: 0 0 var(--sp-3); }
.sx__urgent-h {
  display: flex; align-items: center; gap: var(--sp-2);
  font-family: var(--font-display); font-weight: var(--fw-bold); font-size: var(--fs-lg);
}
.sx__urgent .btn { background: var(--paper); color: var(--accent-red); font-weight: var(--fw-bold); }
.sx__urgent .btn:hover { background: var(--cream); color: var(--accent-red); }

.sx__for { margin: 0 0 var(--sp-3); font-size: var(--fs-sm); color: var(--muted); }
.sx__for strong { color: var(--green-700); }

.sx__panel {
  background: var(--paper);
  border: 1px solid var(--line); border-radius: var(--radius-lg);
  padding: var(--sp-5);
}
.sx__panel[hidden] { display: none; }
.sx__panel h3 { margin: 0; font-size: var(--fs-xl); color: var(--green-900); }

.sx__docs-h {
  margin: var(--sp-4) 0 var(--sp-2);
  font-size: var(--fs-xs); font-weight: var(--fw-bold); color: var(--muted);
  letter-spacing: var(--track-label); text-transform: uppercase;
}
html[lang="bn"] .sx__docs-h { text-transform: none; letter-spacing: normal; }
.sx__docs { list-style: none; margin: 0; padding: 0; display: grid; }
.sx__docs li {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--sp-2) var(--sp-3);
  margin: 0; padding: var(--sp-3) 0;
  border-bottom: 1px solid var(--line);
}
.sx__docs li:last-child { border-bottom: 0; }
.sx__docs a { font-weight: var(--fw-semi); text-decoration: none; }
.sx__docs a:hover { text-decoration: underline; }
/* she is a GP, not a specialist — doctors-data.md #8 requires the distinction */
.sx__role {
  font-style: normal; font-size: var(--fs-xs); color: var(--muted);
  padding-inline: var(--sp-2); border-radius: var(--radius-pill);
  background: var(--green-100);
}
.sx__when { margin-inline-start: auto; font-size: var(--fs-sm); color: var(--green-700); font-weight: var(--fw-semi); }
/* eleven of fifteen have no confirmed hours yet (Iron Rule 2) — say so quietly */
.sx__when.is-soft { color: var(--muted); font-weight: var(--fw-normal); }

.sx__acts { margin-top: var(--sp-5); display: flex; flex-wrap: wrap; gap: var(--sp-3); }

@media (prefers-reduced-motion: reduce) {
  .sx__chip { transition: none; }
  .js-motion .sx__result.is-in { animation: none; }
}

/* ============================== departments ==============================
   A brand-green band, and ten wide cards in two columns.

   The surface is exactly the ambulance band's: --green-900 with one soft wash
   off the top-right corner. Same treatment, so the two green bands on the page
   read as one system rather than two ideas.

   Verified on --green-900 (#03320b):
     white                12.3:1   department names
     --cream at 78%       ~8.0:1   scope lines
     --gold-soft           7.9:1   doctor counts, the Explore arrow           */
.departments {
  position: relative;
  color: var(--cream);
  background-color: var(--green-900);
  background-image: radial-gradient(90% 130% at 88% 0%, rgb(35 158 56 / .20), transparent 62%);
}
.departments h2 { color: var(--paper); }
.dept-lead { max-width: 39.96em; color: rgb(242 237 226 / .8); margin: 0 0 var(--sp-5); }

/* Ten departments, two rows of five on a desktop. That makes each one a tile
   rather than a card, so above 720px the layout turns and centres: icon over
   name over scope. Below that a phone gets the horizontal form, which reads
   far better in a narrow column than a centred stack does. */
.dept-grid { display: grid; gap: var(--sp-3); }
@media (min-width: 560px)  { .dept-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 900px)  { .dept-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (min-width: 1140px) { .dept-grid { grid-template-columns: repeat(5, minmax(0, 1fr)); } }

.dept {
  /* declared here so the pair is always defined, with or without JS */
  --mx: 50%; --my: 0%;
  position: relative; overflow: hidden; isolation: isolate;
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  grid-template-areas:
    "ico title go"
    "ico scope go"
    "ico meta  go";
  column-gap: var(--sp-4); row-gap: 2px;
  align-items: center;
  padding: var(--sp-4) var(--sp-5);
  border: 0; border-radius: var(--radius-lg);
  background: rgb(242 237 226 / .055);
  box-shadow: inset 0 0 0 1px rgb(242 237 226 / .13);
  color: var(--cream); text-decoration: none;
  transition: transform var(--dur-base) var(--ease-out),
              background-color var(--dur-fast) var(--ease-out),
              box-shadow var(--dur-base) var(--ease-out);
}
.dept::before {
  content: ""; position: absolute; inset: 0; z-index: -1; opacity: 0;
  background: radial-gradient(320px circle at var(--mx) var(--my),
                              rgb(35 158 56 / .30), transparent 62%);
  transition: opacity var(--dur-base) var(--ease-out);
}
.dept:hover, .dept:focus-visible {
  transform: translateY(-3px);
  background: rgb(242 237 226 / .085);
  box-shadow: inset 0 0 0 1px rgb(200 164 92 / .5), 0 14px 34px rgb(2 26 6 / .45);
}
.dept:hover::before { opacity: 1; }

.dept__ico {
  grid-area: ico; align-self: center;
  display: grid; place-items: center;
  width: 50px; height: 50px; border-radius: var(--radius);
  background: rgb(242 237 226 / .1); color: var(--gold-soft);
  box-shadow: inset 0 0 0 1px rgb(200 164 92 / .3);
  transition: background-color var(--dur-fast) var(--ease-out),
              color var(--dur-fast) var(--ease-out),
              transform var(--dur-base) var(--ease-out);
}
.dept__ico svg { width: 26px; height: 26px; display: block; }
.dept:hover .dept__ico {
  background: var(--gold); color: var(--green-950);
  box-shadow: none;
  transform: rotate(-6deg) scale(1.06);
}

.dept h3 { grid-area: title; margin: 0; font-size: var(--fs-lg); color: var(--paper); }
.dept__scope { grid-area: scope; margin: 0; font-size: var(--fs-sm); color: rgb(242 237 226 / .78); }
/* the count comes from the same list the symptom router routes to */
.dept__meta {
  grid-area: meta; margin-top: 2px;
  font-size: var(--fs-xs); font-weight: var(--fw-semi); color: var(--gold-soft);
}

.dept__go {
  grid-area: go; align-self: center;
  display: inline-flex; align-items: center; gap: var(--sp-2);
  font-size: var(--fs-sm); font-weight: var(--fw-semi); color: var(--gold-soft);
  white-space: nowrap;
}
.dept__go svg {
  width: 16px; height: 16px; display: block;
  transition: transform var(--dur-base) var(--ease-out);
}
.dept:hover .dept__go svg { transform: translateX(5px); }

/* ---- tile form: two rows of five ---- */
@media (min-width: 560px) {
  .dept {
    grid-template-columns: minmax(0, 1fr);
    grid-template-areas: "ico" "title" "scope" "meta" "go";
    justify-items: center; text-align: center;
    row-gap: var(--sp-2); column-gap: 0;
    padding: var(--sp-5) var(--sp-4);
  }
  .dept__ico { margin-bottom: var(--sp-1); }
  /* one line each: the strings are written to fit, and the ellipsis is a
     visible signal if anyone ever makes one longer than the tile */
  .dept h3, .dept__scope {
    max-width: 100%; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  }
  .dept h3 { font-size: var(--fs-md); }
  .dept__scope { font-size: var(--fs-xs); }
  .dept__meta { margin-top: var(--sp-1); }
  /* the scope is the elastic row; letting it take the slack keeps the icon,
     the name and the arrow on the same line across all ten tiles */
  .dept__scope { align-self: start; }
  .dept__go { margin-top: var(--sp-2); align-self: end; }
  .dept:hover .dept__go svg { transform: translateX(3px); }
}
/* five across leaves no room for a word beside the arrow */
@media (min-width: 1140px) { .dept__go-t { display: none; } }

/* ten cards, so the reveal ladder has to reach ten rather than four */
.js-motion .dept-grid .reveal:nth-child(1) { transition-delay: 0ms; }
.js-motion .dept-grid .reveal:nth-child(2) { transition-delay: 50ms; }
.js-motion .dept-grid .reveal:nth-child(3) { transition-delay: 100ms; }
.js-motion .dept-grid .reveal:nth-child(4) { transition-delay: 150ms; }
.js-motion .dept-grid .reveal:nth-child(5) { transition-delay: 200ms; }
.js-motion .dept-grid .reveal:nth-child(6) { transition-delay: 250ms; }
.js-motion .dept-grid .reveal:nth-child(7) { transition-delay: 300ms; }
.js-motion .dept-grid .reveal:nth-child(8) { transition-delay: 350ms; }
.js-motion .dept-grid .reveal:nth-child(9) { transition-delay: 400ms; }
.js-motion .dept-grid .reveal:nth-child(10) { transition-delay: 450ms; }

@media (prefers-reduced-motion: reduce) {
  .dept, .dept__ico, .dept__go svg, .dept::before { transition: none; }
  .dept:hover, .dept:focus-visible { transform: none; }
  .dept:hover .dept__ico { transform: none; }
  .dept:hover .dept__go svg { transform: none; }
}

/* ============================== featured doctor ==============================
   The E-E-A-T anchor: the hospital's main face, his degree line, and the thing
   that actually converts — when he sits, worked out for you rather than left
   as a table of four days to reason about.                                   */
.featured-band { background: var(--bone); }
.ftd { display: grid; gap: var(--sp-5); align-items: center; }
@media (min-width: 900px) {
  .ftd { grid-template-columns: minmax(0, 1.05fr) minmax(0, .95fr); gap: var(--sp-7); }
}

/* ---- video facade ----
   No YouTube frame, script or cookie until someone presses play. That keeps
   ~1.3MB of third-party JavaScript off a page most visitors will never watch,
   and keeps Google's cookies off the site for the ones who don't. */
.yt {
  position: relative; overflow: hidden;
  border-radius: var(--radius-lg);
  background: var(--green-950);
  box-shadow: var(--shadow-lift);
  aspect-ratio: 16 / 9;
}
.yt__poster {
  display: block; width: 100%; height: 100%;
  object-fit: cover;
  transition: transform var(--dur-base) var(--ease-out),
              filter var(--dur-base) var(--ease-out);
}
.yt:hover .yt__poster { transform: scale(1.03); filter: brightness(.9); }

/* a scrim only along the bottom, so the title stays legible over any frame */
.yt::after {
  content: ""; position: absolute; inset-inline: 0; bottom: 0; height: 45%;
  background: linear-gradient(to top, rgb(2 26 6 / .82), transparent);
  pointer-events: none;
}
.yt__title {
  position: absolute; inset-inline: var(--sp-4); bottom: var(--sp-4); z-index: 2;
  margin: 0; color: var(--paper);
  font-family: var(--font-display); font-weight: var(--fw-bold); font-size: var(--fs-md);
  text-shadow: 0 1px 12px rgb(2 26 6 / .6);
  pointer-events: none;
}

.yt__play {
  position: absolute; inset: 0; z-index: 3;
  display: grid; place-items: center;
  width: 100%; height: 100%;
  border: 0; background: none; cursor: pointer;
}
.yt__play-ico {
  display: grid; place-items: center;
  width: 72px; height: 72px; border-radius: 50%;
  background: var(--accent-red); color: var(--paper);
  box-shadow: 0 10px 30px rgb(2 26 6 / .45);
  transition: transform var(--dur-base) var(--ease-out),
              background-color var(--dur-fast) var(--ease-out);
}
.yt__play-ico svg { width: 34px; height: 34px; margin-inline-start: 3px; display: block; }
.yt__play:hover .yt__play-ico { transform: scale(1.08); }
.yt__play:active .yt__play-ico { transform: scale(.98); }

/* a slow halo, so the eye finds the play control without it shouting */
.yt__play-ico::before {
  content: ""; position: absolute; width: 72px; height: 72px; border-radius: 50%;
  background: var(--accent-red); opacity: .45;
  animation: yt-halo 2.8s var(--ease-out) infinite;
}
@keyframes yt-halo {
  0%   { transform: scale(1);   opacity: .45; }
  70%  { transform: scale(1.7); opacity: 0; }
  100% { transform: scale(1.7); opacity: 0; }
}
.yt[data-yt-on] { aspect-ratio: 16 / 9; }
.yt[data-yt-on]::after { display: none; }
.yt iframe { display: block; width: 100%; height: 100%; border: 0; }

/* ---- the panel that stands in until there is a video ---- */

/* ---- the doctor ---- */
/* the section heading matches every other band; the doctor is the h3 under it */
.featured-band h2 { color: var(--green-900); }
.ftd__name { margin: 0; font-size: var(--fs-xl); color: var(--green-900); }
.ftd__role { margin: var(--sp-2) 0 0; color: var(--muted); font-weight: var(--fw-semi); }

/* One line. Five pills at 16px plus padding and gaps ran to two rows in the
   right-hand column; the same words as a dotted run are about half as wide and
   read the way a degree line is actually written. green-800 on bone = 9.9:1. */
.ftd__degrees {
  display: flex; flex-wrap: wrap; align-items: baseline;
  margin: var(--sp-4) 0 0; padding: 0; list-style: none;
  font-size: var(--fs-sm); font-weight: var(--fw-semi); color: var(--green-800);
}
.ftd__degrees li { margin: 0; white-space: nowrap; }
.ftd__degrees li + li::before {
  content: "·"; margin-inline: var(--sp-2);
  color: var(--line-strong); font-weight: var(--fw-normal);
}
.ftd__affil {
  margin: var(--sp-4) 0 0;
  padding: var(--sp-3) var(--sp-4);
  border-inline-start: 3px solid var(--gold);
  border-radius: 0 var(--radius) var(--radius) 0;
  background: var(--paper);
  color: var(--green-900); font-size: var(--fs-sm); font-weight: var(--fw-semi);
  line-height: 1.5;
}

/* ---- the schedule ----
   Four day pills, with today lit. What it never says is "in chamber now":
   hours are a schedule, presence is not something a static page can know. */
.ftd__sched {
  margin-top: var(--sp-5); padding-top: var(--sp-4);
  border-top: 1px solid var(--line);
}
.ftd__sched-h {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--sp-2);
  margin: 0 0 var(--sp-3);
  font-size: var(--fs-sm); font-weight: var(--fw-semi); color: var(--ink);
}
.ftd__live {
  display: inline-flex; align-items: baseline; gap: 4px;
  color: var(--green-700); font-weight: var(--fw-semi);
}
.ftd__live[hidden] { display: none; }
.ftd__live::before {
  content: ""; align-self: center;
  width: 8px; height: 8px; flex: none; margin-inline-end: 4px;
  border-radius: 50%; background: var(--green-500);
  animation: livepulse 2.4s var(--ease-out) infinite;
}
@media (prefers-reduced-motion: reduce) { .ftd__live::before { animation: none; } }

.ftd__days { display: flex; flex-wrap: wrap; gap: var(--sp-2); margin: 0; padding: 0; list-style: none; }
.ftd__day {
  margin: 0; padding: var(--sp-2) var(--sp-3);
  min-width: 92px; text-align: center;
  border: 1px solid var(--line); border-radius: var(--radius);
  background: var(--paper);
  transition: border-color var(--dur-fast) var(--ease-out),
              background-color var(--dur-fast) var(--ease-out);
}
.ftd__day b { display: block; font-size: var(--fs-sm); color: var(--ink); }
.ftd__day span { display: block; font-size: var(--fs-xs); color: var(--muted); }
.ftd__day.is-today {
  background: var(--green-700); border-color: var(--green-700);
}
.ftd__day.is-today b { color: var(--paper); }
/* white, not the green tint: at --fs-xs on the solid pill the tint sat too
   close to the background to read. White on --green-700 is 7.91:1. */
.ftd__day.is-today span { color: var(--paper); font-weight: var(--fw-semi); }
.ftd__day.is-next { border-color: var(--green-600); }

.ftd__acts { margin-top: var(--sp-5); display: flex; flex-wrap: wrap; gap: var(--sp-3); }
/* "সিরিয়ালের জন্য কল করুন" + "পুরো প্রোফাইল দেখুন" measure ~417px at the
   desktop size against the ~380px a phone offers. --fs-xs and tighter padding
   bring the pair to ~363px, which fits down to 360px wide. */
@media (max-width: 560px) {
  .ftd__acts { flex-wrap: nowrap; gap: var(--sp-2); }
  .ftd__acts .btn {
    padding-inline: var(--sp-3); font-size: var(--fs-xs);
    white-space: nowrap; flex: 0 1 auto; min-width: 0;
  }
}

/* Four fixed 92px pills need 392px and a phone offers about 380, so they
   broke to two rows. Below 560px they share the row equally instead: the
   week reads as one strip, which is the whole point of showing four days. */
@media (max-width: 560px) {
  .ftd__days { flex-wrap: nowrap; gap: 6px; }
  .ftd__day {
    flex: 1 1 0; min-width: 0;
    padding: var(--sp-2) 4px;
  }
  .ftd__day b { font-size: var(--fs-xs); }
  /* 11px, not --fs-xs: the hours have to clear the pill at a quarter of the
     screen, and Bengali conjuncts stop resolving much below this. */
  .ftd__day span { font-size: 11px; line-height: 1.35; }
}

@media (prefers-reduced-motion: reduce) {
  .yt__poster, .yt__play-ico, .ftd__day { transition: none; }
  .yt__play-ico::before { animation: none; opacity: 0; }
}

/* ============================== packages ==============================
   A rail and a stage, not a grid of ten cards. Ten cards side by side is a
   wall — the tenth never gets read, and the overlap between packages (CBC,
   HbA1c and Lipid Profile recur in most of them) stays invisible.

   Here the names and prices sit in one scannable column, one package is open
   at a time, and switching marks what the new one adds over the last. The
   comparison tray takes it further: up to three, side by side.

   Every animated property is transform, opacity or width on a 6px bar —
   nothing that forces layout on a low-end Android (motion-spec §1). */
/* The break after the dash is deliberate — the sentence has two halves.
   It is suppressed on a narrow screen, where the text wraps on its own
   and a forced break would strand a word. */
/* A surface for the card to sit on. Plain white between two green bands left
   the stage with no edge at all — the section read as a spreadsheet. */
.packages {
  padding-bottom: var(--sp-5);
  background-color: var(--bone);
  background-image: radial-gradient(90% 60% at 12% 0%, var(--green-100), transparent 58%);
}
.packages__lead { max-width: 47.952em; color: var(--muted); margin: 0 0 var(--sp-5); }
.packages__lead br { display: none; }
@media (min-width: 760px) { .packages__lead br { display: inline; } }

/* ---- filter chips ---- */
/* Each chip carries its own count, so you know a filter is worth tapping
   before you tap it. */
.pkg-chips { display: flex; flex-wrap: wrap; gap: var(--sp-2); margin-bottom: var(--sp-5); }
.pkg-chip {
  display: inline-flex; align-items: center; gap: var(--sp-2);
  min-height: 40px; padding-inline: var(--sp-4);
  border: 1px solid var(--line); border-radius: var(--radius-pill);
  background: var(--paper); color: var(--ink);
  font: inherit; font-size: var(--fs-sm); font-weight: var(--fw-semi);
  cursor: pointer;
  transition: background-color var(--dur-fast) var(--ease-out),
              border-color var(--dur-fast) var(--ease-out),
              box-shadow var(--dur-base) var(--ease-out),
              transform var(--dur-press) var(--ease-out),
              color var(--dur-fast) var(--ease-out);
}
.pkg-chip:hover { border-color: var(--green-600); transform: translateY(-1px); }
.pkg-chip:active { transform: translateY(0); }
.pkg-chip.is-on { box-shadow: 0 6px 18px rgb(6 95 21 / .28); }
.pkg-chip.is-on { background: var(--green-700); border-color: var(--green-700); color: var(--paper); }

/* ---- the explorer ---- */
.pkgx { display: grid; gap: var(--sp-4); align-items: start; }
@media (min-width: 900px) {
  .pkgx { grid-template-columns: 364px minmax(0, 1fr); gap: var(--sp-5); }
}

/* ---- rail ---- */
.pkgx__rail { position: relative; display: grid; gap: 2px; }

/* The marker is one element that slides between rows — ten hover/active
   backgrounds cross-fading would look like ten separate things happening. */
.pkgx__marker {
  position: absolute; inset-inline: 0; top: 0; height: 0;
  background: var(--green-100);
  border-radius: var(--radius);
  box-shadow: inset 3px 0 0 var(--green-700);
  pointer-events: none;
  transition: transform var(--dur-base) var(--ease-out),
              height var(--dur-base) var(--ease-out);
}

.pkgx__item {
  position: relative; z-index: 1;
  display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3);
  min-height: 54px; padding: var(--sp-2) var(--sp-3) var(--sp-2) var(--sp-4);
  border: 0; border-radius: var(--radius);
  background: none; color: var(--ink);
  font: inherit; text-align: start; cursor: pointer;
  transition: background-color var(--dur-fast) var(--ease-out),
              color var(--dur-fast) var(--ease-out);
}
.pkgx__item:hover { background: var(--paper); }
.pkgx__item.is-on { background: none; color: var(--green-900); }
.pkgx__item.is-on .pkgx__rname { font-weight: var(--fw-bold); }
.pkgx__item[hidden] { display: none; }
/* queued for comparison — visible from the rail, so you never lose track */
.pkgx__item.is-picked { box-shadow: inset 0 0 0 1px var(--green-600); }

/* One line per row. The rail is sized so none of the ten names truncates;
   the ellipsis is a safety net, not a design. */
.pkgx__rname {
  flex: 1 1 auto; min-width: 0;
  font-size: var(--fs-sm); font-weight: var(--fw-semi);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.pkgx__rprice {
  flex: 0 0 auto;
  font-family: var(--font-ui); font-weight: var(--fw-bold); color: var(--green-700);
  font-variant-numeric: tabular-nums; white-space: nowrap; text-align: end;
}
/* inline, not stacked: every rail row is then exactly the same height */
.pkgx__rprice small {
  font-size: var(--fs-xs); font-weight: var(--fw-medium);
  color: var(--muted); letter-spacing: normal;
}

/* Below 900px the rail becomes a snap-scrolling strip above the stage. */
@media (max-width: 899px) {
  .pkgx__rail {
    grid-auto-flow: column; grid-auto-columns: minmax(210px, 1fr);
    gap: var(--sp-2); overflow-x: auto; padding-bottom: var(--sp-2);
    scroll-snap-type: x proximity;
  }
  .pkgx__marker { display: none; }
  .pkgx__item {
    scroll-snap-align: start;
    flex-direction: column; align-items: flex-start; justify-content: center; gap: 2px;
    border: 1px solid var(--line);
  }
  .pkgx__item.is-on { background: var(--green-100); border-color: var(--green-700); }
  .pkgx__rprice { text-align: start; }
  .pkgx__rname { white-space: normal; }
}

/* ---- stage ---- */
/* The card is its own height. Stretching it to match the rail padded every
   short package with a slab of empty white below the call button; capping it
   to the tallest package did the same thing with a different number. Whatever
   is in the package sets the height, and the page below moves — which is what
   a person expects when they deliberately pick a bigger package. */
.pkgx__stage { position: relative; }
.pkgx__card {
  border: 1px solid var(--line); border-radius: var(--radius-lg);
  border-inline-start: 3px solid var(--gold);
  padding: var(--sp-5);
  background-color: var(--paper);
  /* depth without another image request */
  background-image: radial-gradient(120% 90% at 100% 0%, var(--green-100), transparent 62%);
  box-shadow: 0 18px 44px rgb(2 26 6 / .09);
}
.pkgx__card[hidden] { display: none; }
.js-motion .pkgx__card.is-in { animation: pkgx-in var(--dur-base) var(--ease-out) both; }
@keyframes pkgx-in {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: none; }
}

.pkgx__tag {
  margin: 0; font-size: var(--fs-xs); font-weight: var(--fw-semi); color: var(--green-600);
  text-transform: uppercase; letter-spacing: var(--track-label);
}
/* Bangla is never upper-cased or letter-spaced */
html[lang="bn"] .pkgx__tag { text-transform: none; letter-spacing: normal; }

.pkgx__title { margin: var(--sp-2) 0 0; font-size: var(--fs-xl); color: var(--green-900); }
.pkgx__amount {
  margin: var(--sp-3) 0 0;
  font-family: var(--font-ui); font-size: var(--fs-3xl); font-weight: var(--fw-bold);
  color: var(--green-700); line-height: 1.05; font-variant-numeric: tabular-nums;
}
.pkgx__amount small {
  font-size: var(--fs-xs); font-weight: var(--fw-medium); color: var(--muted);
  margin-inline-start: var(--sp-2);
}

/* How much is in this package, against the fullest one. A number alone does
   not land; a bar that grows when you switch does. */
.pkgx__meter { margin: var(--sp-4) 0 0; display: grid; gap: var(--sp-2); }
.pkgx__meter-label { font-size: var(--fs-sm); color: var(--muted); }
.pkgx__meter-track {
  height: 6px; border-radius: var(--radius-pill);
  background: var(--green-100); overflow: hidden;
}
.pkgx__meter-fill {
  display: block; height: 100%; width: 0; border-radius: var(--radius-pill);
  background: linear-gradient(90deg, var(--green-700), var(--green-500));
  transition: width 620ms var(--ease-out);
}

.pkgx__vary { margin: var(--sp-4) 0 0; font-size: var(--fs-sm); color: var(--muted); }

/* "vs the one you were just looking at" — the whole point of the section */
.pkgx__delta {
  margin: var(--sp-4) 0 0; padding: var(--sp-2) var(--sp-3);
  border-radius: var(--radius); background: var(--green-100); color: var(--green-900);
  font-size: var(--fs-sm); font-weight: var(--fw-semi);
}
.pkgx__delta[hidden] { display: none; }

/* One column while the stage is narrow; two once there is room, so the
   fourteen-row package does not tower over the ten-row rail beside it. */
.pkgx__tests { list-style: none; margin: var(--sp-4) 0 0; padding: 0; display: grid; }
@media (min-width: 760px) {
  .pkgx__tests { grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: var(--sp-5); }
}
.pkgx__tests li {
  position: relative; margin: 0;
  padding: var(--sp-2) 0 var(--sp-2) var(--sp-5);
  border-bottom: 1px solid var(--line);
  font-size: var(--fs-sm);
}
.pkgx__tests li::before {
  content: "\2713"; position: absolute; inset-inline-start: 0; top: var(--sp-2);
  color: var(--green-600); font-weight: var(--fw-bold);
}
.pkgx__tests li.is-added { background-image: linear-gradient(90deg, var(--green-100), transparent 70%); }
.pkgx__new {
  margin-inline-start: var(--sp-2); padding: 1px var(--sp-2);
  border-radius: var(--radius-pill);
  background: var(--green-600); color: var(--paper);
  font-size: 10px; font-weight: var(--fw-bold); vertical-align: middle;
}

/* rows arrive in sequence, but fast — 9 rows land inside 320ms */
.js-motion .pkgx__card.is-in .pkgx__tests li { animation: pkgx-row var(--dur-base) var(--ease-out) both; }
@keyframes pkgx-row {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: none; }
}
.js-motion .pkgx__card.is-in .pkgx__tests li:nth-child(1) { animation-delay: 40ms; }
.js-motion .pkgx__card.is-in .pkgx__tests li:nth-child(2) { animation-delay: 66ms; }
.js-motion .pkgx__card.is-in .pkgx__tests li:nth-child(3) { animation-delay: 92ms; }
.js-motion .pkgx__card.is-in .pkgx__tests li:nth-child(4) { animation-delay: 118ms; }
.js-motion .pkgx__card.is-in .pkgx__tests li:nth-child(5) { animation-delay: 144ms; }
.js-motion .pkgx__card.is-in .pkgx__tests li:nth-child(6) { animation-delay: 170ms; }
.js-motion .pkgx__card.is-in .pkgx__tests li:nth-child(7) { animation-delay: 196ms; }
.js-motion .pkgx__card.is-in .pkgx__tests li:nth-child(8) { animation-delay: 222ms; }
.js-motion .pkgx__card.is-in .pkgx__tests li:nth-child(9) { animation-delay: 248ms; }
.js-motion .pkgx__card.is-in .pkgx__tests li:nth-child(10) { animation-delay: 274ms; }
.js-motion .pkgx__card.is-in .pkgx__tests li:nth-child(11) { animation-delay: 300ms; }
.js-motion .pkgx__card.is-in .pkgx__tests li:nth-child(12) { animation-delay: 326ms; }
.js-motion .pkgx__card.is-in .pkgx__tests li:nth-child(13) { animation-delay: 352ms; }
.js-motion .pkgx__card.is-in .pkgx__tests li:nth-child(14) { animation-delay: 378ms; }

.pkgx__actions {
  margin-top: var(--sp-5);
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-4);
}
.pkgx__cmp {
  display: inline-flex; align-items: center; gap: var(--sp-2); min-height: var(--tap);
  font-size: var(--fs-sm); font-weight: var(--fw-semi); color: var(--green-700);
  cursor: pointer;
}
.pkgx__cmp input { width: 24px; height: 24px; accent-color: var(--green-600); }
.pkgx__cmp:has(input:disabled) { color: var(--muted); cursor: not-allowed; }

.pkg-empty { color: var(--muted); margin-top: var(--sp-4); }
.pkg-empty[hidden] { display: none; }

/* ---- comparison tray ---- */
.cmp-bar {
  position: fixed; inset-inline: 0; z-index: var(--z-menu);
  bottom: calc(var(--bottombar-h) + env(safe-area-inset-bottom, 0px) + var(--sp-3));
  padding-inline: var(--sp-4);
  transform: translateY(140%);
  transition: transform var(--dur-base) var(--ease-out);
}
@media (min-width: 768px) { .cmp-bar { bottom: var(--sp-5); } }
.cmp-bar[hidden] { display: none; }
.cmp-bar[data-open="true"] { transform: none; }

/* A dock, not a bar: it floats clear of the window edge with a gold hairline,
   so it reads as a tool you picked up rather than a strip bolted to the
   bottom of the screen. No blur behind it: at 93% opacity it would barely
   show, it costs real compositing time on a budget Android, and it would
   leave a standing warning on a rule that exists to catch a genuine bug. */
.cmp-bar__inner {
  width: min(100%, 980px); margin-inline: auto;
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: var(--sp-3); padding: var(--sp-3) var(--sp-4);
  border-radius: var(--radius-lg);
  background: rgb(2 26 6 / .96);
  box-shadow: inset 0 0 0 1px rgb(200 164 92 / .34), 0 18px 44px rgb(2 26 6 / .5);
  color: var(--cream);
}
.cmp-bar__count { margin: 0; font-size: var(--fs-sm); white-space: nowrap; }
.cmp-bar__count strong {
  display: inline-block; min-width: 1.2em; text-align: center;
  font-size: var(--fs-lg); color: var(--gold-soft);
}
/* the number kicks when it changes, so a pick registers even while your eye
   is still on the card you just ticked */
.cmp-bar__count strong.is-bump { animation: cmp-bump 320ms var(--ease-out); }
@keyframes cmp-bump {
  0%   { transform: scale(1); }
  45%  { transform: scale(1.38); }
  100% { transform: scale(1); }
}
.cmp-bar__count span { color: rgb(242 237 226 / .6); }
.cmp-bar__actions { display: flex; gap: var(--sp-2); }
.cmp-bar .btn { min-height: 40px; }
.cmp-bar .btn--ghost { color: var(--cream); box-shadow: inset 0 0 0 1px rgb(242 237 226 / .4); }
.cmp-bar .btn[disabled] { opacity: .45; cursor: not-allowed; }

/* Named, removable chips: you can drop a package without hunting back up the
   rail for its checkbox. 36px tall — above the 24px WCAG 2.2 target minimum,
   short enough that the tray stays one line on a phone. */
.cmp-bar__pills { display: flex; flex-wrap: wrap; gap: var(--sp-2); flex: 1 1 auto; }
.cmp-pill {
  display: inline-flex; align-items: center; gap: var(--sp-2);
  min-height: 36px; padding-inline: var(--sp-3);
  border: 1px solid rgb(242 237 226 / .38); border-radius: var(--radius-pill);
  background: transparent; color: var(--cream);
  font: inherit; font-size: var(--fs-xs); font-weight: var(--fw-semi);
  cursor: pointer;
  transition: background-color var(--dur-fast) var(--ease-out),
              border-color var(--dur-fast) var(--ease-out);
}
.cmp-pill:hover { background: rgb(242 237 226 / .12); border-color: var(--cream); }
.cmp-pill span { font-size: var(--fs-md); line-height: 1; opacity: .75; }
.cmp-pill { animation: cmp-pop 260ms var(--ease-out) both; }
@keyframes cmp-pop {
  from { opacity: 0; transform: translateY(6px) scale(.92); }
  to   { opacity: 1; transform: none; }
}

/* ---- comparison panel ---- */
.cmp-panel {
  position: fixed; inset: 0; z-index: var(--z-drawer);
  background: var(--paper);
  overflow-y: auto;
  opacity: 0;
  transition: opacity var(--dur-base) var(--ease-out);
}
.cmp-panel[hidden] { display: none; }
.cmp-panel[data-open="true"] { opacity: 1; }
.cmp-panel > * { transform: translateY(14px); transition: transform var(--dur-base) var(--ease-out); }
.cmp-panel[data-open="true"] > * { transform: none; }
.cmp-panel__head {
  position: sticky; top: 0; z-index: 2;
  background: var(--green-900); color: var(--paper);
}
.cmp-panel__head-inner {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: var(--sp-3); padding-block: var(--sp-3);
}

/* Everything / Only differences. Three packages make an eighteen-row table
   and most of those rows are shared; the toggle is the shortest path to the
   two or three that actually decide it. */
.cmp-seg {
  display: inline-flex; padding: 3px; border-radius: var(--radius-pill);
  background: rgb(2 26 6 / .45);
  box-shadow: inset 0 0 0 1px rgb(242 237 226 / .16);
}
.cmp-seg__btn {
  min-height: 34px; padding-inline: var(--sp-4);
  border: 0; border-radius: var(--radius-pill);
  background: none; color: rgb(242 237 226 / .72);
  font: inherit; font-size: var(--fs-xs); font-weight: var(--fw-semi); cursor: pointer;
  transition: background-color var(--dur-fast) var(--ease-out),
              color var(--dur-fast) var(--ease-out);
}
.cmp-seg__btn:hover { color: var(--paper); }
.cmp-seg__btn.is-on { background: var(--gold); color: var(--green-950); }

/* One card per package: price, size, and what it adds over the cheapest of
   the ones picked. The table answers that row by row; this answers it once,
   at the top, before anyone starts reading ticks. */
.cmp-cards { display: grid; gap: var(--sp-3); margin-bottom: var(--sp-5); }
@media (min-width: 700px) { .cmp-cards { grid-auto-flow: column; grid-auto-columns: 1fr; } }
.cmp-card {
  padding: var(--sp-4);
  border-radius: var(--radius-lg);
  background: var(--bone);
  box-shadow: inset 0 0 0 1px var(--line);
  animation: cmp-rise 380ms var(--ease-out) both;
}
.cmp-card:nth-child(2) { animation-delay: 70ms; }
.cmp-card:nth-child(3) { animation-delay: 140ms; }
@keyframes cmp-rise {
  from { opacity: 0; transform: translateY(12px); }
  to   { opacity: 1; transform: none; }
}
.cmp-card.is-base { background: var(--green-100); box-shadow: inset 0 0 0 1px var(--green-600); }
.cmp-card__name { margin: 0; font-size: var(--fs-sm); font-weight: var(--fw-semi); color: var(--green-900); }
.cmp-card__price {
  display: block; margin-top: var(--sp-1);
  font-family: var(--font-ui); font-size: var(--fs-2xl); font-weight: var(--fw-bold);
  color: var(--green-700); line-height: 1.05; font-variant-numeric: tabular-nums;
}
.cmp-card__n { display: block; margin-top: var(--sp-2); font-size: var(--fs-xs); color: var(--muted); }
.cmp-card__delta {
  display: inline-block; margin-top: var(--sp-2);
  padding: 2px var(--sp-3); border-radius: var(--radius-pill);
  background: var(--green-700); color: var(--paper);
  font-size: var(--fs-xs); font-weight: var(--fw-semi);
}
.cmp-card.is-base .cmp-card__delta { background: var(--green-600); }
.cmp-panel__head h3 { margin: 0; color: var(--paper); font-size: var(--fs-lg); }
.cmp-panel__close {
  min-width: var(--tap); min-height: var(--tap);
  background: none; border: 0; color: var(--paper);
  font-size: var(--fs-2xl); line-height: 1; cursor: pointer; border-radius: var(--radius-sm);
}
.cmp-panel__close:hover { background: rgb(255 255 255 / .12); }
.cmp-panel__body { padding-block: var(--sp-5) var(--sp-8); overflow-x: auto; }
.cmp-note { margin: 0 0 var(--sp-4); color: var(--muted); font-size: var(--fs-sm); }

.cmp-table { width: 100%; border-collapse: collapse; min-width: 520px; }
.cmp-table th, .cmp-table td {
  padding: var(--sp-3); text-align: start;
  border-bottom: 1px solid var(--line); font-size: var(--fs-sm);
}
.cmp-table thead th {
  position: sticky; top: 0; z-index: 2;
  background: var(--paper);
  color: var(--green-900); font-size: var(--fs-md); vertical-align: bottom;
}
.cmp-table tbody tr { animation: cmp-row 300ms var(--ease-out) both; }
@keyframes cmp-row { from { opacity: 0; } to { opacity: 1; } }
.cmp-table tbody tr:nth-child(1) { animation-delay: 20ms; }
.cmp-table tbody tr:nth-child(2) { animation-delay: 45ms; }
.cmp-table tbody tr:nth-child(3) { animation-delay: 70ms; }
.cmp-table tbody tr:nth-child(4) { animation-delay: 95ms; }
.cmp-table tbody tr:nth-child(5) { animation-delay: 120ms; }
.cmp-table tbody tr:nth-child(6) { animation-delay: 145ms; }
.cmp-table tbody tr:nth-child(7) { animation-delay: 170ms; }
.cmp-table tbody tr:nth-child(n+8) { animation-delay: 195ms; }
.cmp-table .cmp-price {
  display: block; font-family: var(--font-ui); font-size: var(--fs-xl);
  font-weight: var(--fw-bold); color: var(--green-700);
  font-variant-numeric: tabular-nums;
}
.cmp-table tbody th { font-weight: var(--fw-normal); color: var(--ink); }
.cmp-table td { text-align: center; }
.cmp-yes { color: var(--green-600); font-weight: var(--fw-bold); }
.cmp-no { color: var(--line-strong); }
.cmp-table tr.is-diff th { font-weight: var(--fw-semi); }
.cmp-table tr.is-diff { background: var(--green-100); }

/* On a phone the table scrolls sideways; the test name has to stay put or the
   tick marks lose their meaning halfway across. */
.cmp-table th:first-child,
.cmp-table td:first-child {
  position: sticky; inset-inline-start: 0; z-index: 1;
  background: var(--paper);
}
.cmp-table tr.is-diff th:first-child { background: var(--green-100); }
.cmp-table tfoot td { border-bottom: 0; padding-top: var(--sp-4); }
.cmp-table tfoot .btn { width: 100%; min-height: 40px; font-size: var(--fs-sm); }

@media (prefers-reduced-motion: reduce) {
  .cmp-bar, .cmp-panel, .cmp-panel > *, .pkgx__marker, .pkgx__meter-fill,
  .pkgx__item { transition: none; }
  .cmp-pill, .cmp-card, .cmp-table tbody tr, .cmp-bar__count strong.is-bump { animation: none; }
  .js-motion .pkgx__card.is-in,
  .js-motion .pkgx__card.is-in .pkgx__tests li { animation: none; }
}

/* ============================== steps ============================== */
.steps { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--sp-4); counter-reset: step; }
@media (min-width: 800px) { .steps { grid-template-columns: repeat(3, 1fr); } }
.steps li { counter-increment: step; padding-inline-start: 52px; position: relative; }
.steps li::before {
  content: counter(step); position: absolute; inset-inline-start: 0; top: 0;
  width: 38px; height: 38px; border-radius: 50%;
  background: var(--green-600); color: var(--paper);
  display: grid; place-items: center;
  font-family: var(--font-display); font-weight: var(--fw-bold);
}

/* ============================== reasons ============================== */

/* ============================== footer ==============================
   Three bands: brand + address, the numbers side by side, then a hairline and
   the legal line. Two type sizes in the whole thing, one accent colour, one
   rule. What reads as premium is the space, not the ornament. */
.site-footer {
  background: var(--green-950);
  color: var(--cream);
  padding-block: var(--sp-5) var(--sp-4);
  margin-top: var(--sp-6);
  font-size: var(--fs-sm);
}
.site-footer a { color: var(--cream); text-decoration: none; }
.site-footer a:hover { color: var(--paper); text-decoration: underline; text-underline-offset: 3px; }

/* ---- band 1: brand and address ---- */
.foot-top { display: flex; }
.foot-top .logo { width: auto; }
.foot-top .logo__name { color: var(--paper); font-size: var(--fs-lg); }
.foot-top .logo__place { color: var(--gold-soft); }
.foot-top .logo__dash { color: rgb(242 237 226 / .5); }
/* Address and hours sit under the numbers, left aligned with everything else.
   They are reference detail, not a headline — so they read quieter than the
   numbers above them. */
/* One line: address then hours, separated by a hairline pip. They wrap to two
   lines on a narrow screen rather than squeezing. */
.foot-where {
  margin: var(--sp-5) 0 0;
  display: flex; flex-wrap: wrap; align-items: center;
  gap: var(--sp-2) var(--sp-4);
  line-height: 1.6;
}
.foot-address {
  display: inline-flex; align-items: center; gap: var(--sp-2);
  color: rgb(242 237 226 / .8);
}
.foot-hours {
  position: relative; padding-inline-start: var(--sp-4);
  color: var(--gold-soft); font-weight: var(--fw-semi); font-size: var(--fs-xs);
}
.foot-hours::before {
  content: ""; position: absolute; inset-inline-start: 0; top: 50%;
  width: 1px; height: 12px; margin-top: -6px;
  background: rgb(242 237 226 / .28);
}
@media (max-width: 560px) {
  .foot-hours { padding-inline-start: 0; }
  .foot-hours::before { display: none; }
}

/* ---- band 2: the numbers, side by side ---- */
.foot-contact {
  display: grid; gap: var(--sp-4) var(--sp-5);
  grid-template-columns: repeat(auto-fit, minmax(158px, 1fr));
  margin-top: var(--sp-4);
  padding-top: var(--sp-4);
  border-top: 1px solid rgb(242 237 226 / .09);
}
.foot-item { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.foot-item__label {
  display: flex; align-items: center; gap: var(--sp-2);
  font-family: var(--font-ui); font-size: var(--fs-xs); font-weight: var(--fw-bold);
  letter-spacing: var(--track-label); text-transform: uppercase;
  color: rgb(242 237 226 / .55);
}
.foot-item a {
  font-size: var(--fs-md); font-weight: var(--fw-semi);
  font-variant-numeric: tabular-nums; letter-spacing: var(--track-tight);
}
.foot-item.is-mail a { font-size: var(--fs-sm); overflow-wrap: anywhere; }
.foot-item.is-urgent .foot-ico { color: var(--accent-red-on-dark); }
.foot-item.is-urgent a { color: var(--paper); }

.foot-ico { display: inline-flex; flex: none; color: var(--gold-soft); }
.foot-ico svg { width: 14px; height: 14px; display: block; }

/* ---- band 3: legal ---- */
.foot-base {
  margin-top: var(--sp-4); padding-top: var(--sp-3);
  border-top: 1px solid rgb(242 237 226 / .09);
  display: flex; flex-wrap: wrap; gap: var(--sp-2) var(--sp-5);
  align-items: center; justify-content: space-between;
}
.foot-base p { margin: 0; color: rgb(242 237 226 / .5); font-size: var(--fs-xs); }
/* Legal links and the agency credit share the last line, divided by hairline
   pips. Padding rather than gap, so each pip sits exactly halfway between. */
.foot-meta {
  display: flex; flex-wrap: wrap; align-items: center; row-gap: var(--sp-2);
  font-size: var(--fs-xs);
}
.foot-meta > * { padding-inline: var(--sp-4); }
.foot-meta > *:first-child { padding-inline-start: 0; }
.foot-meta > *:last-child { padding-inline-end: 0; }
.foot-meta > * + * { position: relative; }
.foot-meta > * + *::before {
  content: ""; position: absolute; inset-inline-start: 0; top: 50%;
  width: 1px; height: 12px; margin-top: -6px;
  background: rgb(242 237 226 / .28);
}
.foot-meta, .foot-meta a { color: rgb(242 237 226 / .7); text-decoration: none; }
/* 24px tall so a thumb can land on them. The legal pair sits in a row rather
   than inside a sentence, so the 2.5.8 inline exception does not cover it. */
.foot-meta a { display: inline-flex; align-items: center; min-height: 24px; }
.foot-meta a:hover { color: var(--gold-soft); text-decoration: underline; }
.foot-credit { color: rgb(242 237 226 / .5); }

/* ---- phones ----
   The address and the copyright each ran to two lines on a 380px screen.
   What comes off is the landmark and the formal suffix — the authoritative
   copies of both live in the JSON-LD (PostalAddress and the Hospital name),
   which is what Google reads for NAP, so the local signal is untouched.
   The email row goes too: it is the one contact nobody taps on a phone, and
   it was the widest cell in the grid. */
@media (max-width: 560px) {
  .foot-near, .foot-copy-tail { display: none; }
  .foot-address, .foot-base p { white-space: nowrap; }
  .foot-item.is-mail { display: none; }
  .foot-contact { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  /* the pips divide items on ONE line; once the row wraps, the credit
     inherits one as a dangling mark at the start of its own line */
  .foot-meta { gap: var(--sp-2) var(--sp-5); }
  .foot-meta > * { padding-inline: 0; }
  .foot-meta > * + *::before { display: none; }
  .foot-credit { flex-basis: 100%; }
}

/* ============================== videos ==============================
   Three long, four shorts. Every tile is a click-to-load facade over a local
   WebP poster: seven live embeds would be several megabytes of third-party
   JavaScript and seven sets of Google cookies before anyone pressed anything.
   Nothing is fetched from YouTube until a play button is clicked, and then
   exactly one player is built — inside the lightbox.                        */
.videos { background: var(--bone); padding-block: var(--sp-5); }
.vid-lead { max-width: 41.292em; color: var(--muted); margin: 0 0 var(--sp-4); }

/* the type switch and the channel action share one row: one is what you are
   looking at, the other is where to get more of it */
.vid-bar {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: var(--sp-3); margin-bottom: var(--sp-4);
}

/* #cc0000, not the brand #FF0000: white on true YouTube red is 4.00:1 and
   fails AA for button text; one shade down is 5.89:1 and still unmistakable.
   Written literally rather than as a token — it is somebody else's brand, not
   part of this design system, and a token that fails to resolve would take the
   whole background declaration with it and leave an invisible button. */
.btn--yt {
  background: #cc0000; color: var(--paper);
  border-radius: var(--radius-btn);
  box-shadow: none;
  /* well under a primary CTA: this is a secondary, off-site action and must
     not compete with "call for a serial". 32px still clears the 24px WCAG 2.2
     target minimum. */
  min-height: 32px; padding: 0 var(--sp-3);
  gap: 6px; font-size: var(--fs-xs);
}
.btn--yt:hover { background: #a80000; color: var(--paper); box-shadow: none; }
.yt-mark { width: 16px; height: 16px; display: block; flex: none; }
/* Long form and shorts are different things to sit down to, so they get a
   switch rather than a stack — and the page carries one row of tiles at a
   time instead of seven. */
.vid-seg {
  display: inline-flex; padding: 3px;
  border-radius: var(--radius-pill);
  background: var(--paper); box-shadow: inset 0 0 0 1px var(--line);
}
.vid-seg__btn {
  min-height: 38px; padding-inline: var(--sp-5);
  border: 0; border-radius: var(--radius-pill);
  background: none; color: var(--muted);
  font: inherit; font-size: var(--fs-sm); font-weight: var(--fw-semi); cursor: pointer;
  transition: background-color var(--dur-fast) var(--ease-out),
              color var(--dur-fast) var(--ease-out);
}
.vid-seg__btn:hover { color: var(--ink); }
.vid-seg__btn.is-on { background: var(--green-700); color: var(--paper); }
.vid-row[hidden] { display: none; }
.js-motion .vid-row.is-in { animation: vid-in var(--dur-base) var(--ease-out) both; }
@keyframes vid-in {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: none; }
}

.vid-row { display: grid; gap: var(--sp-4); }
@media (min-width: 700px)  { .vid-row--long { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
.vid-row--short { grid-auto-flow: column; grid-auto-columns: minmax(180px, 1fr);
                  overflow-x: auto; padding-bottom: var(--sp-2); }
@media (min-width: 700px)  { .vid-row--short { grid-auto-flow: row; grid-template-columns: repeat(4, minmax(0, 1fr)); overflow: visible; } }

.vid {
  position: relative; display: block; width: 100%; padding: 0;
  border: 0; border-radius: var(--radius-lg); overflow: hidden;
  background: var(--green-950); cursor: pointer;
  box-shadow: var(--shadow);
  transition: transform var(--dur-base) var(--ease-out),
              box-shadow var(--dur-base) var(--ease-out);
}
.vid:hover { transform: translateY(-4px); box-shadow: var(--shadow-lift); }
.vid:active { transform: translateY(-1px); }
.vid--long { aspect-ratio: 16 / 9; }
.vid--short { aspect-ratio: 9 / 16; }

.vid__poster {
  display: block; width: 100%; height: 100%; object-fit: cover;
  transition: transform var(--dur-base) var(--ease-out),
              filter var(--dur-base) var(--ease-out);
}
.vid:hover .vid__poster { transform: scale(1.05); filter: brightness(.82); }

/* the scrim only exists to keep the caption legible over any frame */
.vid::after {
  content: ""; position: absolute; inset-inline: 0; bottom: 0; height: 55%;
  background: linear-gradient(to top, rgb(2 26 6 / .9), transparent);
  pointer-events: none;
}
.vid__title {
  position: absolute; inset-inline: var(--sp-3); bottom: var(--sp-3); z-index: 2;
  color: var(--paper); text-align: start;
  font-size: var(--fs-xs); font-weight: var(--fw-semi); line-height: 1.4;
  text-shadow: 0 1px 10px rgb(2 26 6 / .7);
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}

.vid__play {
  position: absolute; inset: 0; z-index: 3;
  display: grid; place-items: center;
  color: var(--paper);
}
.vid__play svg {
  width: 26px; height: 26px; display: block; margin-inline-start: 3px;
  position: relative; z-index: 1;
}
.vid__play::before {
  content: ""; position: absolute;
  width: 58px; height: 58px; border-radius: 50%;
  background: var(--accent-red);
  box-shadow: 0 8px 24px rgb(2 26 6 / .5);
  transition: transform var(--dur-base) var(--ease-out);
}
.vid:hover .vid__play::before { transform: scale(1.12); }
/* the first long video carries a slow halo, so the row reads as playable */
.vid-row--long .vid:first-child .vid__play::after {
  content: ""; position: absolute; width: 58px; height: 58px; border-radius: 50%;
  background: var(--accent-red); opacity: .4;
  animation: yt-halo 2.8s var(--ease-out) infinite;
}

/* ---- lightbox ----
   One player for the whole page. It is built on the click that asks for it
   and destroyed on close, so a closed lightbox costs nothing. */
.vlight {
  position: fixed; inset: 0; z-index: var(--z-drawer);
  display: grid; grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center; gap: var(--sp-3);
  padding: var(--sp-5) var(--sp-4);
  background: rgb(2 26 6 / .93);
  opacity: 0;
  transition: opacity var(--dur-base) var(--ease-out);
}
.vlight[hidden] { display: none; }
.vlight[data-open="true"] { opacity: 1; }

.vlight__frame {
  justify-self: center;
  width: min(100%, 960px);
  border-radius: var(--radius-lg); overflow: hidden;
  background: #000;
  box-shadow: 0 30px 80px rgb(0 0 0 / .6);
  transform: scale(.96);
  transition: transform var(--dur-base) var(--ease-out);
}
.vlight[data-open="true"] .vlight__frame { transform: none; }
.vlight__frame iframe { display: block; width: 100%; height: 100%; border: 0; }
.vlight__frame[data-kind="long"] { aspect-ratio: 16 / 9; }
/* a short is portrait; a 16:9 box would letterbox it into a stripe */
.vlight__frame[data-kind="short"] { width: min(100%, 420px); aspect-ratio: 9 / 16; }

.vlight__nav, .vlight__close {
  display: grid; place-items: center;
  width: 46px; height: 46px; border: 0; border-radius: 50%;
  background: rgb(242 237 226 / .12); color: var(--paper);
  font-size: var(--fs-2xl); line-height: 1; cursor: pointer;
  transition: background-color var(--dur-fast) var(--ease-out);
}
.vlight__nav:hover, .vlight__close:hover { background: rgb(242 237 226 / .24); }
.vlight__close {
  position: absolute; top: var(--sp-4); inset-inline-end: var(--sp-4); z-index: 2;
}
.vlight__caption {
  grid-column: 1 / -1; justify-self: center; margin: 0;
  max-width: 39.96em; text-align: center;
  color: rgb(242 237 226 / .82); font-size: var(--fs-sm);
}
@media (max-width: 620px) {
  .vlight { grid-template-columns: minmax(0, 1fr); }
  .vlight__nav { position: absolute; bottom: var(--sp-5); z-index: 2; }
  .vlight__nav--prev { inset-inline-start: var(--sp-4); }
  .vlight__nav--next { inset-inline-end: var(--sp-4); }
}

@media (prefers-reduced-motion: reduce) {
  .vid, .vid__poster, .vid__play::before, .vlight, .vlight__frame,
  .vid-seg__btn { transition: none; }
  .js-motion .vid-row.is-in { animation: none; }
  .vid-row--long .vid:first-child .vid__play::after { animation: none; opacity: 0; }
}

/* ============================== visit band ==============================
   Questions on the right, a way to reach a person on the left. The address is
   NOT repeated here — the map sits directly below it and the footer carries it
   again; a third copy would be noise where a phone number is useful. */
.visit { background: var(--bone); padding-block: var(--sp-5); }
.visit__grid { display: grid; gap: var(--sp-6); }
@media (min-width: 900px) {
  .visit__grid { grid-template-columns: 0.9fr 1.1fr; gap: var(--sp-7); align-items: start; }
}
.visit h2 { margin: 0 0 var(--sp-3); font-size: var(--fs-xl); color: var(--green-900); }

/* ---- left: live status + the two fastest routes to a human ---- */
.visit__help {
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  padding: var(--sp-5);
  box-shadow: var(--shadow);
}
.live-now {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2);
  margin: 0 0 var(--sp-4);
  font-size: var(--fs-xs);
}
.live-now__dot {
  position: relative; width: 9px; height: 9px; flex: none;
  border-radius: 50%; background: var(--green-500);
}
.live-now__dot::after {
  content: ""; position: absolute; inset: 0; border-radius: 50%;
  background: var(--green-500);
  animation: livepulse 2.4s var(--ease-out) infinite;
}
@media (prefers-reduced-motion: reduce) { .live-now__dot::after { animation: none; opacity: 0; } }
.live-now__text {
  font-weight: var(--fw-bold); color: var(--green-700);
  letter-spacing: var(--track-label); text-transform: uppercase;
}
.live-now__time {
  font-weight: var(--fw-bold); color: var(--ink);
  font-variant-numeric: tabular-nums;
}

.visit__help-body { margin: 0 0 var(--sp-4); color: var(--muted); }
/* the live pill already spaces this heading; its own top margin doubled it */
.visit__help h2 { margin-top: 0; }
.visit__help-actions { display: grid; gap: var(--sp-2); }
.visit__help-actions .btn { width: 100%; }
.visit__ico { display: inline-flex; flex: none; }
.visit__ico svg { width: 16px; height: 16px; display: block; }
.visit__fee {
  margin: var(--sp-4) 0 0; padding-top: var(--sp-3);
  border-top: 1px solid var(--line);
  color: var(--muted); font-size: var(--fs-xs); line-height: 1.6;
}

/* ---- right: the questions ---- */
.visit .faq { border-top: 1px solid var(--line); }
.visit .faq__q { font-size: var(--fs-md); color: var(--green-900); }
.visit .faq__item[open] .faq__q { color: var(--green-600); }

/* ============================== location map ==============================
   Full-bleed, lazy, and last. A Maps embed costs well over half a megabyte,
   so it must never load for someone who does not scroll this far. */
.map-section { padding-top: var(--sp-6); background: var(--bone); }
.map-section h2 { margin: 0 0 var(--sp-2); font-size: var(--fs-xl); color: var(--green-900); }
.map-section__address { margin: 0 0 var(--sp-5); color: var(--muted); font-size: var(--fs-sm); }
.map-section__address a {
  display: inline-block; padding-block: 4px;
  color: var(--green-600); font-weight: var(--fw-semi); white-space: nowrap;
}

.map-section__frame {
  line-height: 0;                 /* kills the inline-frame descender gap */
  background: var(--green-100);
}
.map-section__frame iframe {
  display: block; width: 100%;
  height: 220px; border: 0;
  /* Maps renders its own greyscale-ish palette; a slight lift keeps it from
     fighting the warm ground above it without distorting the map itself. */
  filter: saturate(.92);
}
@media (min-width: 700px) { .map-section__frame iframe { height: 320px; } }

/* The footer follows immediately. base.css puts a 3rem top margin on it for
   the rest of the page; here the map has to meet the footer edge to edge. */
.map-section + .site-footer { margin-top: 0; }

/* ============================================================================
   Symptom router on a phone.

   The chips were a plain flex-wrap, which packs them from the left and leaves
   whatever is left over as a ragged gap on the right. Measured at 390px the
   rows used 267, 299, 198, 297 and 302 of about 350 — so one row sat with
   152px of nothing beside it and the section read as unfinished.

   A fixed two-column grid was tried first and rejected by tests/sxfit.js: the
   English labels are far longer than the Bangla ones ("Fainting or
   unconsciousness", "Child growth and nutrition") and thirteen of them wrapped
   to two lines inside their column. A column width that suits one language
   cannot suit both.

   So the rows stay flexible and the chips grow to fill them. Each row is
   packed by content as before, then every chip in it expands to take up the
   slack — the right edge is straight, no width is imposed on any label, and it
   works the same in both languages whatever the labels say.
   ========================================================================= */
@media (max-width: 560px) {
  .sx__chips {
    gap: var(--sp-2);
    margin-top: var(--sp-3);
  }

  .sx__chip {
    /* grow into the leftover space, never shrink below the label */
    flex: 1 1 auto;
    justify-content: center;
    text-align: center;
    padding-inline: var(--sp-3);
  }

  /* the intro was sitting a long way from the thing it introduces */
  .symptoms .section__lead,
  .sx__intro { margin-bottom: var(--sp-4); }
}

/* pages.css — breadcrumbs and the interior-page layers
   Owner: frontend-builder · depends on tokens.css + base.css

   Everything the homepage does not need. Loaded in the same bundle because a
   second request costs more than the two kilobytes it saves — the audience is
   on mobile data in Cumilla, and round trips are the expensive part.        */

/* ============================== breadcrumbs ==============================
   Small, quiet, and above the h1. Screen readers get the landmark; the
   BreadcrumbList in the JSON-LD is what Google reads.                       */
.crumbs {
  background: var(--bone);
  border-bottom: 1px solid var(--line);
  font-size: var(--fs-xs);
}
.crumbs .wrap { display: flex; flex-wrap: wrap; align-items: center; padding-block: var(--sp-3); }
/* inline-flex at 24px: as a plain inline link "Home" measured 23px tall,
   a pixel under the WCAG 2.2 target minimum */
.crumbs a, .crumbs span {
  display: inline-flex; align-items: center; min-height: 24px;
  color: var(--muted); text-decoration: none;
}
.crumbs a:hover { color: var(--green-700); text-decoration: underline; }
.crumbs [aria-current] { color: var(--ink); font-weight: var(--fw-semi); }
/* the separator is decoration, so it is drawn rather than typed — a literal
   character here would be read aloud between every step */
.crumbs > .wrap > * + *::before {
  content: ""; display: inline-block;
  width: 5px; height: 5px; margin-inline: var(--sp-3);
  border-top: 1px solid var(--line-strong);
  border-right: 1px solid var(--line-strong);
  transform: rotate(45deg) translateY(-1px);
}

/* ============================== packages page ============================== */
/* the same band rhythm the homepage settled on */
@media (max-width: 560px) {
  .pkgp-head, .pkgp-camp, .pkgp-all, .pkgp-how, .pkgp-cta { padding-block: var(--sp-5); }
  .pkgp-head { padding-bottom: var(--sp-3); }
}
.pkgp-head { padding-bottom: var(--sp-4); }
.pkgp-lead { max-width: 45.288em; color: var(--muted); margin: 0 0 var(--sp-4); }
.price-note {
  margin: var(--sp-4) 0 0;
  font-size: var(--fs-xs); color: var(--muted);
}

/* ---- the campaign block ----
   keyword-map §14.5: the offer swaps, the URL never does. Styled to read as a
   promotion without pretending to be one — no countdown, no fake scarcity on a
   hospital page. */
.pkgp-camp {
  background-color: var(--green-900);
  background-image: radial-gradient(90% 130% at 88% 0%, rgb(35 158 56 / .20), transparent 62%);
  color: var(--cream);
}
.pkgp-camp__inner { display: grid; gap: var(--sp-5); align-items: center; }
@media (min-width: 900px) {
  .pkgp-camp__inner { grid-template-columns: minmax(0, 1fr) minmax(0, 420px); gap: var(--sp-7); }
}
.pkgp-camp__eyebrow {
  margin: 0 0 var(--sp-2);
  font-size: var(--fs-xs); font-weight: var(--fw-bold); color: var(--gold-soft);
  letter-spacing: var(--track-label); text-transform: uppercase;
}
html[lang="bn"] .pkgp-camp__eyebrow { text-transform: none; letter-spacing: normal; }
.pkgp-camp h2 { margin: 0 0 var(--sp-3); color: var(--paper); font-size: var(--fs-2xl); }
.pkgp-camp__copy p { margin: 0; color: rgb(242 237 226 / .82); max-width: 30.636em; }

/* ---- controls ----
   The same chip component as the homepage (.pkg-chip, home.css) so the two
   pages filter with one vocabulary. Sorting is a native <select>: on a phone
   that opens the OS picker, which beats anything custom. */
.pkgp-bar {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: var(--sp-3); margin-bottom: var(--sp-3);
}
.pkgp-sort { display: inline-flex; align-items: center; gap: var(--sp-2); font-size: var(--fs-sm); }
.pkgp-sort > span { color: var(--muted); }
.pkgp-sort select {
  min-height: 40px; padding: 0 var(--sp-3);
  border: 1px solid var(--line-strong); border-radius: var(--radius);
  background: var(--paper); color: var(--ink);
  font: inherit; font-size: var(--fs-sm); cursor: pointer;
}
.pkgp-sort select:focus-visible { outline: var(--focus-width) solid var(--focus); outline-offset: 2px; }
.pkgp-count { margin: 0 0 var(--sp-4); font-size: var(--fs-sm); color: var(--muted); }
.pkgp-empty { margin: var(--sp-5) 0 0; color: var(--muted); }
.pkgp-empty[hidden] { display: none; }

/* ---- the cards ---- */
.pkgp-all { background: var(--bone); }
.pkgp-grid { display: grid; gap: var(--sp-4); }
@media (min-width: 640px)  { .pkgp-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 1040px) { .pkgp-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }

.pkgp {
  display: flex; flex-direction: column;
  padding: var(--sp-5);
  background: var(--paper);
  border: 1px solid var(--line);
  border-inline-start: 3px solid var(--gold);
  border-radius: var(--radius-lg);
  box-shadow: 0 14px 34px rgb(2 26 6 / .07);
}
/* the campaign card sits on the green band, so it inverts */
.pkgp.is-featured {
  background: rgb(242 237 226 / .06);
  border: 0; box-shadow: inset 0 0 0 1px rgb(200 164 92 / .45);
  color: var(--cream);
}
.pkgp__tag {
  margin: 0 0 var(--sp-2);
  font-size: var(--fs-xs); font-weight: var(--fw-semi); color: var(--green-600);
}
.pkgp.is-featured .pkgp__tag { color: var(--gold-soft); }
/* These two components appear at two heading depths, so their selectors must
   not name a tag. `.dpd` (the doctor card) is h2 on /doctors/, where the grid
   is the page, and h3 on a department or doctor page, where it sits under a
   section h2. `.ab-story__list` is h2 on /about/history/. A selector written
   for one level silently unstyles the other, which is how a heading ends up
   rendering at browser-default size on one page only. */
.pkgp :is(h2, h3) { margin: 0; font-size: var(--fs-lg); color: var(--green-900); }
.pkgp.is-featured :is(h2, h3) { color: var(--paper); }
.pkgp__price {
  margin: var(--sp-2) 0 0;
  font-family: var(--font-ui); font-size: var(--fs-2xl); font-weight: var(--fw-bold);
  color: var(--green-700); line-height: 1.05;
  font-variant-numeric: tabular-nums; letter-spacing: var(--track-tight);
}
.pkgp.is-featured .pkgp__price { color: var(--gold); }
.pkgp__price small {
  font-size: var(--fs-xs); font-weight: var(--fw-medium);
  color: var(--muted); letter-spacing: normal;
}
.pkgp.is-featured .pkgp__price small { color: rgb(242 237 226 / .7); }
.pkgp__count {
  margin: var(--sp-2) 0 var(--sp-3);
  font-size: var(--fs-xs); color: var(--muted);
}
.pkgp.is-featured .pkgp__count { color: rgb(242 237 226 / .7); }

.pkgp__tests {
  list-style: none; margin: 0 0 var(--sp-5); padding: 0;
  display: grid; gap: 6px;
  font-size: var(--fs-sm);
}
.pkgp__tests li { margin: 0; padding-inline-start: var(--sp-5); position: relative; }
.pkgp__tests li::before {
  content: "\2713"; position: absolute; inset-inline-start: 0;
  color: var(--green-600); font-weight: var(--fw-bold);
}
.pkgp.is-featured .pkgp__tests li::before { color: var(--gold-soft); }
/* Fourteen items on Premium against four on Corporate dragged every card in
   the row to the tallest, so anything past six folds away. */
.pkgp__tests.is-clamped li:nth-child(n+7) { display: none; }
/* On a phone the nine cards stack into one very long column, so the fold is
   tighter there: four items, not six. The JS reads the same breakpoint so the
   "+N more" count always matches what is actually hidden. */
@media (max-width: 700px) {
  .pkgp__tests.is-clamped li:nth-child(n+5) { display: none; }
}
.pkgp__more {
  align-self: start; margin: calc(var(--sp-5) * -1) 0 var(--sp-5);
  min-height: 32px; padding: 0;
  border: 0; background: none; color: var(--green-600);
  font: inherit; font-size: var(--fs-sm); font-weight: var(--fw-semi);
  text-decoration: underline; text-underline-offset: 3px; cursor: pointer;
}
.pkgp__more[hidden] { display: none; }
.pkgp__more:hover { color: var(--green-700); }

.pkgp[hidden] { display: none; }
.pkgp {
  transition: transform var(--dur-base) var(--ease-out),
              box-shadow var(--dur-base) var(--ease-out);
}
.pkgp:hover { transform: translateY(-3px); box-shadow: 0 20px 44px rgb(2 26 6 / .12); }
.pkgp.is-featured:hover { transform: none; }

/* nine cards, so the reveal ladder has to reach nine */
.js-motion .pkgp-grid .reveal:nth-child(1) { transition-delay: 0ms; }
.js-motion .pkgp-grid .reveal:nth-child(2) { transition-delay: 50ms; }
.js-motion .pkgp-grid .reveal:nth-child(3) { transition-delay: 100ms; }
.js-motion .pkgp-grid .reveal:nth-child(4) { transition-delay: 150ms; }
.js-motion .pkgp-grid .reveal:nth-child(5) { transition-delay: 200ms; }
.js-motion .pkgp-grid .reveal:nth-child(6) { transition-delay: 250ms; }
.js-motion .pkgp-grid .reveal:nth-child(7) { transition-delay: 300ms; }
.js-motion .pkgp-grid .reveal:nth-child(8) { transition-delay: 350ms; }
.js-motion .pkgp-grid .reveal:nth-child(9) { transition-delay: 400ms; }

@media (prefers-reduced-motion: reduce) {
  .pkgp { transition: none; }
  .pkgp:hover { transform: none; }
}

.pkgp .btn { margin-top: auto; }
.pkgp.is-featured .btn--primary { background: var(--gold); color: var(--green-950); }
.pkgp.is-featured .btn--primary:hover { background: var(--gold-soft); color: var(--green-950); }

/* ---- how it works ----
   A connected run rather than three loose paragraphs: a rail joins the steps
   and fills as they come into view, so the section reads as a sequence you are
   moving through. The rail is decoration — the <ol> carries the real order. */
.pkgp-flow { position: relative; }
/* No single absolute rail: one spanning the whole block overshot past the last
   step and hung in space. Each step draws the segment to the one after it, so
   the line self-sizes and simply stops at the last disc. Each segment turns
   green as its own step arrives, which is the progressive fill. */
.pkgp-flow__rail { display: none; }

.pkgp-steps {
  position: relative; z-index: 1;
  list-style: none; margin: 0; padding: 0;
  counter-reset: step; display: grid; gap: var(--sp-5);
}
@media (min-width: 800px) { .pkgp-steps { grid-template-columns: repeat(3, 1fr); gap: var(--sp-5); } }

.pkgp-step { position: relative; margin: 0; padding-inline-start: 56px; }
.pkgp-step:not(:last-child)::before {
  content: ""; position: absolute; z-index: 0;
  inset-inline-start: 19px; top: 40px;
  bottom: calc(var(--sp-5) * -1); width: 2px;
  background: var(--line); border-radius: 2px;
  transition: background-color 600ms var(--ease-out);
}
.js-motion .pkgp-step.is-in:not(:last-child)::before { background: var(--green-600); }

@media (min-width: 800px) {
  .pkgp-step { padding-inline-start: 0; padding-top: 56px; text-align: center; }
  .pkgp-step:not(:last-child)::before {
    inset-inline-start: calc(50% + 20px);
    inset-inline-end: calc(-50% - 20px);
    top: 19px; bottom: auto; height: 2px; width: auto;
  }
}
/* the number and the icon share one disc: the number is the sequence, the icon
   is what the step actually is */
.pkgp-step__ico {
  position: absolute; top: 0; inset-inline-start: 0; z-index: 1;
  width: 40px; height: 40px; border-radius: 50%;
  display: grid; place-items: center;
  background: var(--paper); color: var(--green-600);
  box-shadow: inset 0 0 0 2px var(--line);
  transition: background-color var(--dur-base) var(--ease-out),
              color var(--dur-base) var(--ease-out),
              transform var(--dur-base) var(--ease-out),
              box-shadow var(--dur-base) var(--ease-out);
}
@media (min-width: 800px) { .pkgp-step__ico { inset-inline-start: calc(50% - 20px); } }
.pkgp-step__ico svg { width: 20px; height: 20px; display: block; }
.js-motion .pkgp-step.is-in .pkgp-step__ico {
  background: var(--green-700); color: var(--paper); box-shadow: inset 0 0 0 2px var(--green-700);
}
.pkgp-step:hover .pkgp-step__ico { transform: scale(1.06); }

/* The number sits above the title as a quiet label rather than as a badge
   crowding the icon. The rail already carries the sequence; this just names it. */
.pkgp-step strong { display: block; margin-bottom: 4px; color: var(--green-900); }
.pkgp-step strong::before {
  counter-increment: step; content: counter(step, decimal-leading-zero);
  display: block; margin-bottom: 2px;
  font-family: var(--font-ui); font-size: var(--fs-xs); font-weight: var(--fw-bold);
  color: var(--green-600); letter-spacing: var(--track-label);
}
html[lang="bn"] .pkgp-step strong::before {
  content: counter(step, bengali); letter-spacing: normal;
}
.pkgp-step__body {
  display: block; color: var(--muted); font-size: var(--fs-sm);
  text-wrap: balance;
}

/* Honest because the hotline really is 24 hours — it is a fact restated live,
   not a claim invented by the clock. */
.pkgp-step__live {
  display: inline-flex; align-items: center; gap: var(--sp-2);
  margin-top: var(--sp-3);
  font-size: var(--fs-xs); font-weight: var(--fw-semi); color: var(--green-700);
}
.pkgp-step__live[hidden] { display: none; }
.pkgp-step__dot {
  position: relative;
  width: 8px; height: 8px; flex: none; border-radius: 50%;
  background: var(--green-500);
}
.pkgp-step__dot::after {
  content: ""; position: absolute; inset: 0; border-radius: 50%;
  background: var(--green-500);
  animation: livepulse 2.4s var(--ease-out) infinite;
}
@media (prefers-reduced-motion: reduce) {
  .pkgp-step::before, .pkgp-step__ico { transition: none; }
  .pkgp-step:hover .pkgp-step__ico { transform: none; }
  .pkgp-step__dot::after { animation: none; opacity: 0; }
}

/* ---- closing call ---- */
.pkgp-cta__inner {
  display: grid; gap: var(--sp-4); align-items: center;
  padding: var(--sp-5);
  background: var(--green-100);
  border-radius: var(--radius-lg);
}
@media (min-width: 900px) {
  .pkgp-cta__inner { grid-template-columns: minmax(0, 1fr) auto; gap: var(--sp-6); }
}
.pkgp-cta h2 { margin: 0 0 var(--sp-2); font-size: var(--fs-xl); color: var(--green-900); }
.pkgp-cta p { margin: 0; color: var(--muted); max-width: 37.296em; }
.pkgp-cta__acts { display: flex; flex-wrap: wrap; gap: var(--sp-3); }

/* One row on a phone. The full labels cannot both fit at 360px at any readable
   size — which is why this used to be allowed to wrap — so the short forms are
   what make the row possible. The call button takes the larger share because a
   phone number has no slack in it; "সব বিভাগ" does. */
@media (max-width: 560px) {
  .pkgp-cta__acts { flex-wrap: nowrap; gap: var(--sp-2); }
  .pkgp-cta__acts .btn {
    flex: 1 1 auto; min-width: 0;
    padding-inline: var(--sp-2); font-size: var(--fs-xs);
    white-space: nowrap;
  }
  .pkgp-cta__acts .btn:first-child { flex-grow: 1.6; }
  .pkgp-cta__acts .btn__full { display: none; }
  .pkgp-cta__acts .btn__short { display: inline; }
}

/* ---- the help card, one row on a phone ----
   Scoped to .visit--compact so the homepage band keeps its stacked pair. The
   two full labels measure ~366px against the ~332px inside the card, so the
   short forms are what make one line possible — the number stays on the call
   button because that is the whole point of it. */
.btn__short { display: none; }
@media (max-width: 560px) {
  .visit--compact .visit__help-actions { display: flex; flex-wrap: nowrap; gap: var(--sp-2); }
  .visit--compact .visit__help-actions .btn {
    flex: 1 1 auto; min-width: 0; width: auto;
    padding-inline: var(--sp-2); gap: var(--sp-2);
    font-size: var(--fs-xs); white-space: nowrap;
  }
  /* an equal split clipped the number at 360px: "WhatsApp" has slack the
     phone number does not, so the row is divided by what each label needs */
  .visit--compact .visit__help-actions .btn:first-child { flex-grow: 1.6; }
  .visit--compact .visit__help-actions .btn__full { display: none; }
  .visit--compact .visit__help-actions .btn__short { display: inline; }
}

/* Below ~340px a phone number plus a second label genuinely will not share a
   row inside a card this narrow. Stacking there is the honest answer; the only
   thing that must never happen is a clipped phone number. No current phone is
   this narrow — this is the floor, not the target. */
/* Measured, not guessed: the two buttons need ~278px and the card gives
   (viewport - 32 wrap - 48 padding), so one row needs about 358px of viewport.
   Below that they stack. The earlier floor of 339 let the card itself grow
   wider than its grid column at 340 — the page did not scroll, because
   .page-wrap clips, but the card was over-wide all the same. */
@media (max-width: 359px) {
  .visit--compact .visit__help-actions,
  .pkgp-cta__acts { flex-wrap: wrap; }
  .visit--compact .visit__help-actions .btn,
  .pkgp-cta__acts .btn { flex-basis: 100%; }
}
/* and a grid item may not refuse to shrink below its content */
.visit__grid > * { min-width: 0; }

/* ============================== contact page ==============================
   Built around WhatsApp rather than a form. On this stack a contact form is a
   PHP mail script that lands in spam as often as not and has nobody watching
   it at 2am; 01820-113365 is a line this hospital already answers.          */
.ct-head { padding-bottom: var(--sp-4); }
/* the same band rhythm the homepage and the packages page settled on */
@media (max-width: 560px) {
  .ct-head, .ct-wa, .ct-nums, .ct-where { padding-block: var(--sp-5); }
  .ct-head { padding-bottom: var(--sp-3); }
}
.ct-head .live-now { margin-bottom: var(--sp-3); }
.ct-intro { max-width: 43.956em; color: var(--muted); margin: 0; }
.ct-lead { max-width: 41.292em; color: var(--muted); margin: 0 0 var(--sp-5); }
.ct-note { margin: var(--sp-4) 0 0; font-size: var(--fs-xs); color: var(--muted); }

/* ---- the composer ---- */
.ct-wa {
  background-color: var(--green-900);
  background-image: radial-gradient(90% 130% at 88% 0%, rgb(35 158 56 / .20), transparent 62%);
  color: var(--cream);
}
.ct-wa__grid { display: grid; gap: var(--sp-5); align-items: start; }
@media (min-width: 900px) {
  .ct-wa__grid { grid-template-columns: minmax(0, 1fr) minmax(0, 380px); gap: var(--sp-7); }
}
.ct-wa h2 { margin: 0 0 var(--sp-2); color: var(--paper); font-size: var(--fs-2xl); }
/* no max-width cap here: the column is the measure, and the cap was forcing
   a second line the sentence does not need */
.ct-wa__lead { margin: 0 0 var(--sp-5); color: rgb(242 237 226 / .82); }
.ct-step {
  margin: 0 0 var(--sp-3);
  font-size: var(--fs-xs); font-weight: var(--fw-bold); color: var(--gold-soft);
}

/* one row on a desktop; on a phone six of these cannot share a line at any
   readable size, so they wrap there */
.wa-chips { display: flex; flex-wrap: wrap; gap: var(--sp-2); margin-bottom: var(--sp-5); }
/* 1200px, not 900: at 900 the two-column grid leaves the left side about
   564px and the six chips need ~600, so nowrap there just pushed them out
   of their own column. Below this they wrap, which is correct. */
@media (min-width: 1200px) { .wa-chips { flex-wrap: nowrap; } }
.wa-chip {
  min-height: 40px; padding-inline: var(--sp-4);
  border: 0; border-radius: var(--radius-pill);
  background: rgb(242 237 226 / .08); color: var(--cream);
  box-shadow: inset 0 0 0 1px rgb(242 237 226 / .22);
  font: inherit; font-size: var(--fs-sm); font-weight: var(--fw-semi); cursor: pointer;
  transition: background-color var(--dur-fast) var(--ease-out),
              box-shadow var(--dur-fast) var(--ease-out),
              transform var(--dur-press) var(--ease-out);
}
.wa-chip:hover { background: rgb(242 237 226 / .16); }
.wa-chip:active { transform: scale(.97); }
.wa-chip.is-on { background: var(--gold); color: var(--green-950); box-shadow: none; }

.ct-fields { display: grid; gap: var(--sp-4); }
@media (min-width: 620px) { .ct-fields { grid-template-columns: 1fr 1fr; } }
.ct-field { display: grid; gap: var(--sp-2); }
.ct-field > span { font-size: var(--fs-xs); font-weight: var(--fw-bold); color: var(--gold-soft); }
.ct-field input, .ct-field select {
  min-height: 46px; padding-inline: var(--sp-3);
  border: 0; border-radius: var(--radius);
  background: rgb(242 237 226 / .1); color: var(--paper);
  box-shadow: inset 0 0 0 1px rgb(242 237 226 / .3);
  font: inherit; font-size: var(--fs-sm);
}
.ct-field input::placeholder { color: rgb(242 237 226 / .5); }
.ct-field input:focus-visible, .ct-field select:focus-visible {
  outline: var(--focus-width) solid var(--focus-dark); outline-offset: 2px;
}
.ct-field select option { color: var(--ink); }

/* ---- the preview ----
   A chat bubble, because that is exactly what the reader is about to send.
   Tail and read-ticks included: recognising the shape is the reassurance. */
.wa-preview[hidden], .wa-urgent[hidden] { display: none; }
.wa-preview__h {
  margin: 0 0 var(--sp-3);
  font-size: var(--fs-xs); font-weight: var(--fw-bold); color: var(--gold-soft);
}
.wa-bubble {
  position: relative;
  padding: var(--sp-4) var(--sp-4) var(--sp-2);
  border-radius: var(--radius-lg) var(--radius-lg) var(--radius-lg) 4px;
  background: #075e54; color: var(--paper);
  box-shadow: 0 12px 30px rgb(2 26 6 / .35);
}
.wa-bubble p { margin: 0; font-size: var(--fs-sm); line-height: 1.55; }
.wa-bubble__meta {
  display: flex; align-items: center; justify-content: flex-end; gap: 4px;
  margin-top: var(--sp-2);
  font-size: 11px; color: rgb(255 255 255 / .72);
  font-variant-numeric: tabular-nums;
}
.wa-bubble__meta svg { width: 15px; height: 10px; display: block; color: #7ad0ff; }

/* White on WhatsApp green is 2.87:1 — a well-known failure, and it was ours
   too. Dark text on the brighter brand green measures 9.19:1 and looks MORE
   like WhatsApp, not less: their own light-mode buttons read this way. */
.btn--wa {
  margin-top: var(--sp-4);
  background: #25d366; color: var(--green-950); font-weight: var(--fw-bold);
}
.btn--wa:hover { background: #1fbe5b; color: var(--green-950); }
.wa-copy {
  display: block; width: 100%; min-height: 34px; margin-top: var(--sp-2);
  border: 0; background: none; color: var(--gold-soft);
  font: inherit; font-size: var(--fs-sm); font-weight: var(--fw-semi);
  text-decoration: underline; text-underline-offset: 3px; cursor: pointer;
}

/* an emergency is not a chat */
.wa-urgent {
  padding: var(--sp-4); border-radius: var(--radius-lg);
  background: var(--accent-red); color: var(--paper);
}
.wa-urgent p { margin: 0 0 var(--sp-3); font-size: var(--fs-sm); }
.wa-urgent__h { font-family: var(--font-display); font-weight: var(--fw-bold); font-size: var(--fs-lg); }
.wa-urgent .btn { background: var(--paper); color: var(--accent-red); width: 100%; font-weight: var(--fw-bold); }
.wa-urgent .btn:hover { background: var(--cream); color: var(--accent-red); }

/* ---- numbers ---- */
.ct-nums { background: var(--bone); }
.num-grid { display: grid; gap: var(--sp-3); }
@media (min-width: 620px)  { .num-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 1000px) { .num-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
.num {
  display: grid; grid-template-columns: auto 1fr; gap: 2px var(--sp-3);
  align-items: center;
  padding: var(--sp-4) var(--sp-5);
  background: var(--paper); border: 1px solid var(--line); border-radius: var(--radius-lg);
  text-decoration: none; color: var(--ink);
  transition: transform var(--dur-base) var(--ease-out),
              border-color var(--dur-fast) var(--ease-out),
              box-shadow var(--dur-base) var(--ease-out);
}
.num:hover { transform: translateY(-3px); border-color: var(--green-600); box-shadow: var(--shadow-lift); }
.num__ico { display: inline-flex; grid-row: span 2; color: var(--green-600); }
.num__ico svg { width: 20px; height: 20px; display: block; }
.num__label { font-size: var(--fs-xs); color: var(--muted); }
.num__value {
  font-family: var(--font-ui); font-size: var(--fs-md); font-weight: var(--fw-bold);
  color: var(--green-700); font-variant-numeric: tabular-nums; letter-spacing: var(--track-tight);
}
.num.is-urgent .num__ico, .num.is-urgent .num__value { color: var(--accent-red); }
.num.is-mail .num__value { font-size: var(--fs-sm); overflow-wrap: anywhere; letter-spacing: normal; }

/* ---- address and map ---- */
.ct-where__grid { display: grid; gap: var(--sp-5); align-items: start; }
/* a grid item defaults to min-width:auto, so a nowrap button inside it can
   force the whole column wider than the page — this is what let the English
   "Directions from where I am" push the section 12px past 360px */
.ct-where__grid > * { min-width: 0; }
@media (min-width: 900px) {
  .ct-where__grid { grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr); gap: var(--sp-6); }
}
/* Two facts, each an icon beside a stacked label and value. The previous
   version put the icon, the name and the address line into one grid as three
   separate items, so the address dropped underneath the icon into column one
   and the name was squeezed into a narrow column beside it. Wrapping the text
   in a single element is what keeps the grid to the two items it describes. */
.ct-facts {
  list-style: none; margin: 0 0 var(--sp-5); padding: 0;
  display: grid; gap: var(--sp-4);
}
.ct-fact {
  display: grid; grid-template-columns: auto minmax(0, 1fr);
  gap: var(--sp-3); align-items: start; margin: 0;
  padding-bottom: var(--sp-4); border-bottom: 1px solid var(--line);
}
.ct-fact:last-child { padding-bottom: 0; border-bottom: 0; }
.ct-fact__ico {
  display: grid; place-items: center;
  width: 38px; height: 38px; border-radius: 50%;
  background: var(--green-100); color: var(--green-700);
}
.ct-fact__ico svg { width: 18px; height: 18px; display: block; }
.ct-fact__body { display: grid; gap: 3px; min-width: 0; }
.ct-fact__body strong { color: var(--ink); line-height: 1.4; }
.ct-fact__body > span { color: var(--muted); font-size: var(--fs-sm); line-height: 1.55; }
.ct-fact__live {
  display: inline-flex; align-items: center; gap: var(--sp-2);
  margin-top: 2px;
  font-size: var(--fs-xs); font-weight: var(--fw-semi);
}
.ct-fact__live, .ct-fact__body .ct-fact__live { color: var(--green-700); }
.ct-fact__live time { font-variant-numeric: tabular-nums; }
.ct-where__acts { display: flex; flex-wrap: wrap; gap: var(--sp-3); }
.ct-map {
  border-radius: var(--radius-lg); overflow: hidden;
  border: 1px solid var(--line); line-height: 0;
  box-shadow: var(--shadow);
}
.ct-map iframe { display: block; width: 100%; height: 340px; border: 0; }


@media (max-width: 560px) {
  .ct-where__acts { flex-wrap: nowrap; }
  .ct-where__acts .btn {
    flex: 1 1 auto; min-width: 0;
    padding-inline: var(--sp-2); font-size: var(--fs-xs); white-space: nowrap;
  }
  .ct-where__acts .btn__full { display: none; }
  .ct-where__acts .btn__short { display: inline; }
  .ct-map iframe { height: 260px; }
}
@media (prefers-reduced-motion: reduce) { .wa-chip, .num { transition: none; } }

/* ============================== legal pages ==============================
   Long text with a contents list beside it. Restraint is the design here — a
   privacy policy that performs is a privacy policy nobody trusts. The only
   moving part is the contents highlighting whichever section you are reading,
   which is the one thing that genuinely helps on a page this long.          */
.lg-head { padding-bottom: var(--sp-4); background: var(--bone); }
.lg-head h1 { margin: 0 0 var(--sp-2); }
.lg-updated {
  margin: 0 0 var(--sp-3);
  font-size: var(--fs-sm); color: var(--muted);
}
.lg-updated time { font-weight: var(--fw-semi); color: var(--ink); }
.lg-lead { max-width: 45.288em; color: var(--muted); margin: 0; }

.lg-grid { display: grid; gap: var(--sp-5); align-items: start; }
.lg-grid > * { min-width: 0; }
@media (min-width: 900px) {
  .lg-grid { grid-template-columns: minmax(0, 250px) minmax(0, 1fr); gap: var(--sp-7); }
}

/* ---- contents ---- */
.lg-toc__h {
  margin: 0 0 var(--sp-3);
  font-size: var(--fs-xs); font-weight: var(--fw-bold); color: var(--muted);
  letter-spacing: var(--track-label); text-transform: uppercase;
}
html[lang="bn"] .lg-toc__h { text-transform: none; letter-spacing: normal; }
.lg-toc__list { list-style: none; margin: 0; padding: 0; counter-reset: sec; }
.lg-toc__list li { margin: 0; }
.lg-toc__list a {
  display: block; padding: var(--sp-2) 0 var(--sp-2) var(--sp-4);
  border-inline-start: 2px solid var(--line);
  color: var(--muted); font-size: var(--fs-sm); text-decoration: none;
  transition: color var(--dur-fast) var(--ease-out),
              border-color var(--dur-fast) var(--ease-out);
}
.lg-toc__list a::before {
  counter-increment: sec; content: counter(sec) ". ";
  font-variant-numeric: tabular-nums;
}
html[lang="bn"] .lg-toc__list a::before { content: counter(sec, bengali) ". "; }
.lg-toc__list a:hover { color: var(--green-700); border-color: var(--green-500); }
.lg-toc__list a.is-here {
  color: var(--green-800); font-weight: var(--fw-semi);
  border-color: var(--green-700);
}
@media (min-width: 900px) {
  .lg-toc { position: sticky; top: calc(var(--h-nav) + var(--sp-4)); }
}

/* ---- the document ---- */
.lg-gist {
  padding: var(--sp-5);
  border-radius: var(--radius-lg);
  background: var(--green-100);
  margin-bottom: var(--sp-6);
}
.lg-gist__h {
  margin: 0 0 var(--sp-3);
  font-family: var(--font-display); font-weight: var(--fw-bold);
  font-size: var(--fs-md); color: var(--green-900);
}
.lg-gist ul { margin: 0; padding: 0; list-style: none; display: grid; gap: var(--sp-2); }
.lg-gist li {
  position: relative; margin: 0; padding-inline-start: var(--sp-5);
  color: var(--green-900); font-size: var(--fs-sm); line-height: 1.6;
}
.lg-gist li::before {
  content: "\2713"; position: absolute; inset-inline-start: 0;
  color: var(--green-600); font-weight: var(--fw-bold);
}

.lg-sec { scroll-margin-top: calc(var(--h-nav) + var(--sp-5)); }
@media (max-width: 899px) { .lg-sec { scroll-margin-top: 78px; } }
.lg-sec + .lg-sec { margin-top: var(--sp-6); }
.lg-sec h2 {
  counter-increment: lgsec; margin: 0 0 var(--sp-3);
  font-size: var(--fs-xl); color: var(--green-900);
}
.lg-doc { counter-reset: lgsec; }
.lg-sec h2::before {
  content: counter(lgsec) ". ";
  color: var(--green-600); font-variant-numeric: tabular-nums;
}
html[lang="bn"] .lg-sec h2::before { content: counter(lgsec, bengali) ". "; }
.lg-sec p { margin: 0 0 var(--sp-3); max-width: 46.62em; line-height: 1.7; color: var(--ink); }
.lg-sec p:last-child { margin-bottom: 0; }

.lg-ask {
  margin-top: var(--sp-7); padding: var(--sp-5);
  border-radius: var(--radius-lg);
  background: var(--bone); border: 1px solid var(--line);
}
.lg-ask h2 { margin: 0 0 var(--sp-2); font-size: var(--fs-lg); color: var(--green-900); }
.lg-ask h2::before { content: none; }
.lg-ask p { margin: 0 0 var(--sp-4); color: var(--muted); font-size: var(--fs-sm); }

/* On a phone the eight-item list pushed the document a full screen down, so
   below the two-column breakpoint the contents becomes a sticky rail of chips:
   one line instead of three hundred pixels, and it stays reachable while you
   read. Nothing is sticky on a phone except this and the bottom bar, so top: 0
   is free. */
@media (max-width: 899px) {
  .lg-toc {
    position: sticky; top: 0; z-index: 2;
    margin-inline: calc(var(--sp-4) * -1);
    padding: var(--sp-3) var(--sp-4);
    background: var(--paper);
    border-bottom: 1px solid var(--line);
  }
  .lg-toc__h { display: none; }
  .lg-toc__list {
    display: flex; gap: var(--sp-2);
    overflow-x: auto; scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
  }
  .lg-toc__list::-webkit-scrollbar { display: none; }
  .lg-toc__list a {
    padding: 6px var(--sp-3); white-space: nowrap;
    border: 1px solid var(--line); border-radius: var(--radius-pill);
    /* the desktop rule sets only the inline-start border; reset it here */
    border-inline-start-width: 1px;
    font-size: var(--fs-xs);
  }
  .lg-toc__list a.is-here {
    background: var(--green-700); border-color: var(--green-700); color: var(--paper);
  }
}
@media (max-width: 560px) {
  .lg-head, .lg-body { padding-block: var(--sp-5); }
}
@media (prefers-reduced-motion: reduce) { .lg-toc__list a { transition: none; } }

/* ============================== appointment ==============================
   The conversion page. Three routes at the top for people who already know
   what they want, then a composer for people who do not.                    */
.ap-head { padding-bottom: var(--sp-4); }
.ap-head .live-now { margin-bottom: var(--sp-3); }
.ap-intro { max-width: 50.616em; color: var(--muted); margin: 0; }

/* ---- three ways ---- */
.ap-ways { background: var(--bone); }
.ap-way-grid { display: grid; gap: var(--sp-3); }
@media (min-width: 760px) { .ap-way-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
.ap-way {
  display: grid; grid-template-columns: auto minmax(0, 1fr); gap: var(--sp-3);
  align-items: start;
  padding: var(--sp-4) var(--sp-5);
  background: var(--paper); border: 1px solid var(--line); border-radius: var(--radius-lg);
  text-decoration: none; color: var(--ink);
  transition: transform var(--dur-base) var(--ease-out),
              border-color var(--dur-fast) var(--ease-out),
              box-shadow var(--dur-base) var(--ease-out);
}
.ap-way:hover { transform: translateY(-3px); border-color: var(--green-600); box-shadow: var(--shadow-lift); }
.ap-way__ico {
  display: grid; place-items: center;
  width: 38px; height: 38px; border-radius: 50%;
  background: var(--green-100); color: var(--green-700);
}
.ap-way__ico svg { width: 18px; height: 18px; display: block; }
.ap-way__body { display: grid; gap: 2px; min-width: 0; }
.ap-way__body strong { color: var(--green-900); }
.ap-way__why { font-size: var(--fs-xs); color: var(--muted); }
.ap-way__val {
  font-family: var(--font-ui); font-weight: var(--fw-bold); font-size: var(--fs-sm);
  color: var(--green-700); font-variant-numeric: tabular-nums;
  overflow-wrap: anywhere;
}
/* the fastest route reads first */
.ap-way:first-child { border-inline-start: 3px solid var(--gold); }

/* ---- composer ---- */
.ap-form {
  background-color: var(--green-900);
  background-image: radial-gradient(90% 130% at 88% 0%, rgb(35 158 56 / .20), transparent 62%);
  color: var(--cream);
}
.ap-form__grid { display: grid; gap: var(--sp-5); align-items: start; }
.ap-form__grid > * { min-width: 0; }
@media (min-width: 900px) {
  .ap-form__grid { grid-template-columns: minmax(0, 1fr) minmax(0, 380px); gap: var(--sp-7); }
}
.ap-form h2 { margin: 0 0 var(--sp-2); color: var(--paper); font-size: var(--fs-2xl); }
.ap-form__lead { margin: 0 0 var(--sp-5); color: rgb(242 237 226 / .82); }

.ap-fields { display: grid; gap: var(--sp-4); }
@media (min-width: 620px) { .ap-fields { grid-template-columns: 1fr 1fr; } }
.ap-who__row { display: grid; grid-template-columns: minmax(0, 2fr) minmax(0, 1fr); gap: var(--sp-2); }
.ap-who__row input {
  min-height: 46px; padding-inline: var(--sp-3);
  border: 0; border-radius: var(--radius);
  background: rgb(242 237 226 / .1); color: var(--paper);
  box-shadow: inset 0 0 0 1px rgb(242 237 226 / .3);
  font: inherit; font-size: var(--fs-sm);
}
.ap-who__row input::placeholder { color: rgb(242 237 226 / .5); }
.ap-who__row input:focus-visible {
  outline: var(--focus-width) solid var(--focus-dark); outline-offset: 2px;
}

/* the live answer: whose chamber is next, or a plain instruction to call */
.ap-sitting {
  display: inline-flex; align-items: center; gap: var(--sp-2);
  margin: var(--sp-4) 0 0; padding: var(--sp-2) var(--sp-4);
  border-radius: var(--radius-pill);
  background: rgb(200 164 92 / .16); color: var(--gold-soft);
  font-size: var(--fs-sm); font-weight: var(--fw-semi);
}
.ap-sitting[hidden] { display: none; }
/* eleven of fifteen have no confirmed hours; that reads differently on purpose */
.ap-sitting.is-soft {
  background: rgb(242 237 226 / .08); color: rgb(242 237 226 / .78); font-weight: var(--fw-normal);
}
/* no measure cap: the sentence is short enough for one line in this column,
   and 56ch was breaking it in two for no reason */
.ap-unsure {
  margin: var(--sp-3) 0 0; font-size: var(--fs-sm); color: rgb(242 237 226 / .7);
}
.ap-unsure[hidden] { display: none; }
/* .btn--ghost is drawn for light surfaces: --green-700 text on this dark band
   measures 1.81:1, which is close to invisible. On the composer it takes the
   light treatment instead — --cream on --green-900 is about 9.7:1. */
.ap-form .btn--ghost, .ct-wa .btn--ghost {
  color: var(--cream);
  box-shadow: inset 0 0 0 1px rgb(242 237 226 / .42);
}
.ap-form .btn--ghost:hover, .ct-wa .btn--ghost:hover {
  color: var(--paper); background: rgb(242 237 226 / .1);
  box-shadow: inset 0 0 0 1px var(--cream);
}
.ap-call { margin-top: var(--sp-2); }

/* ---- notes ---- */
.ap-notes__grid { display: grid; gap: var(--sp-4); }
@media (min-width: 860px) { .ap-notes__grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
.ap-note {
  padding: var(--sp-5);
  background: var(--paper); border: 1px solid var(--line); border-radius: var(--radius-lg);
}
.ap-note h2 { margin: 0 0 var(--sp-3); font-size: var(--fs-lg); color: var(--green-900); }
.ap-list { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--sp-2); }
.ap-list li {
  position: relative; margin: 0; padding-inline-start: var(--sp-5);
  color: var(--muted); font-size: var(--fs-sm); line-height: 1.6;
}
.ap-list li::before {
  content: "\2713"; position: absolute; inset-inline-start: 0;
  color: var(--green-600); font-weight: var(--fw-bold);
}
.ap-note--urgent { background: var(--accent-red); border-color: var(--accent-red); color: var(--paper); }
.ap-note--urgent h2 { color: var(--paper); }
.ap-note--urgent p { margin: 0 0 var(--sp-4); font-size: var(--fs-sm); }
.ap-note--urgent .btn { background: var(--paper); color: var(--accent-red); width: 100%; font-weight: var(--fw-bold); }
.ap-note--urgent .btn:hover { background: var(--cream); color: var(--accent-red); }

@media (max-width: 560px) {
  .ap-head, .ap-ways, .ap-form, .ap-notes { padding-block: var(--sp-5); }
  .ap-head { padding-bottom: var(--sp-3); }
}
@media (prefers-reduced-motion: reduce) { .ap-way { transition: none; } }

/* ========================= departments hub =========================
   The silo head. Every card carries its doctors and the complaints that
   belong to it, so this one page links to all ten department hubs and all
   fifteen doctor pages in context — which is the whole point of it.

   That is a lot of text for a page whose job is "pick one", so the card
   leads with the three things that decide the pick (name, plain gloss, how
   many doctors) and lets the detail sit underneath in a quieter weight.  */
.dh-head { background: var(--bone); padding-bottom: var(--sp-5); }
.dh-head h1 { margin: 0 0 var(--sp-3); }
.dh-intro { max-width: 41.292em; color: var(--muted); margin: 0 0 var(--sp-5); }

/* ---- search ---- */
.dh-search .sx__ico {
  display: grid; place-items: center; width: 44px; height: 46px;
  color: var(--muted); flex: none;
}
.dh-search .sx__ico svg { width: 17px; height: 17px; }
.sx__input {
  flex: 1 1 auto; min-width: 0; min-height: 46px;
  border: 0; background: none; font: inherit; font-size: var(--fs-sm); color: var(--ink);
  padding-inline-end: var(--sp-3);
}
.sx__input:focus { outline: none; }
.sx__input::placeholder { color: var(--muted); }
.sx__input::-webkit-search-cancel-button { display: none; }
.sx__clear {
  flex: none; width: 32px; height: 32px; margin-inline-end: 7px;
  display: grid; place-items: center;
  border: 0; border-radius: 50%; cursor: pointer;
  background: var(--bone); color: var(--ink);
  font-size: 20px; line-height: 1;
}
.sx__clear:hover { background: var(--green-100); color: var(--green-800); }
.sx__clear[hidden] { display: none; }

/* ---- the grid: five across, two rows ---- */
.dh-list { padding-top: var(--sp-5); }
.dh-grid { display: grid; gap: var(--sp-3); }
.dh-grid > * { min-width: 0; }
/* same breakpoints as the homepage band, so the two read as one system */
@media (min-width: 560px)  { .dh-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 900px)  { .dh-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (min-width: 1140px) { .dh-grid { grid-template-columns: repeat(5, minmax(0, 1fr)); } }

/* The whole tile is the anchor: one target, no nested links, and the entire
   surface is tappable rather than a small "read more" at the bottom. */
.dh-tile {
  display: grid; align-content: start; gap: var(--sp-2);
  padding: var(--sp-4);
  background: var(--paper); border: 1px solid var(--line);
  border-radius: var(--radius-lg); text-decoration: none;
  transition: transform var(--dur-base) var(--ease-out),
              border-color var(--dur-fast) var(--ease-out),
              box-shadow var(--dur-base) var(--ease-out);
}
.dh-tile:hover { transform: translateY(-3px); border-color: var(--green-600); box-shadow: var(--shadow-lift); }
.dh-tile[hidden] { display: none; }

.dh-tile__ico {
  display: grid; place-items: center;
  width: 40px; height: 40px; border-radius: var(--radius);
  background: var(--green-100); color: var(--green-700);
  transition: background-color var(--dur-fast) var(--ease-out);
}
.dh-tile__ico svg { width: 21px; height: 21px; display: block; }
.dh-tile:hover .dh-tile__ico { background: var(--green-500); color: var(--paper); }

.dh-tile__name {
  margin: var(--sp-2) 0 0; font-size: var(--fs-md); line-height: 1.3;
  color: var(--green-900);
}
.dh-tile__gloss { font-size: var(--fs-sm); line-height: 1.5; color: var(--muted); }
.dh-tile__meta {
  justify-self: start; margin-top: var(--sp-2);
  padding: 2px var(--sp-3); border-radius: var(--radius-pill);
  background: var(--green-100); color: var(--green-800);
  font-size: var(--fs-xs); font-weight: var(--fw-semi);
}
.dh-tile__go { margin-top: var(--sp-2); color: var(--green-600); }
.dh-tile__go svg {
  width: 16px; height: 16px; display: block;
  transition: transform var(--dur-fast) var(--ease-out);
}
.dh-tile:hover .dh-tile__go svg { transform: translateX(4px); }

@media (max-width: 560px) {
  .dh-head, .dh-list { padding-block: var(--sp-5); }
  .dh-head { padding-bottom: var(--sp-4); }
  /* one column on a phone would be ten full-height tiles to scroll past, so
     they pair up and the icon moves beside the text */
  .dh-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--sp-2); }
  .dh-tile { padding: var(--sp-3); }
  .dh-tile__name { font-size: var(--fs-sm); }
  .dh-tile__gloss { font-size: var(--fs-xs); }
  /* the pill's own side padding is what tips the longest badge onto a second
     line in a 125px tile at 340px; the text itself fits */
  .dh-tile__meta { padding-inline: var(--sp-2); }
  .dh-tile__go { display: none; }
}
/* ---- the grid, on the brand band ----
   Same surface as the homepage departments band and the ambulance band:
   --green-900 with one soft wash off the top-right. Reusing it rather than
   inventing a second green means the hub and the homepage read as one system.

   Verified on --green-900 (#03320b):
     --paper              12.3:1   department names
     --cream at 82%       ~8.4:1   scope lines
     --gold-soft           7.9:1   doctor counts and the arrow                */
.dh-list {
  position: relative;
  color: var(--cream);
  background-color: var(--green-900);
  background-image: radial-gradient(90% 130% at 88% 0%, rgb(35 158 56 / .20), transparent 62%);
}

.dh-tile {
  background: rgb(242 237 226 / .055);
  border: 0;
  box-shadow: inset 0 0 0 1px rgb(242 237 226 / .13);
  color: var(--cream);
}
.dh-tile:hover {
  transform: translateY(-3px);
  background: rgb(242 237 226 / .085);
  border: 0;
  box-shadow: inset 0 0 0 1px rgb(200 164 92 / .5), 0 14px 34px rgb(2 26 6 / .45);
}

.dh-tile__ico {
  background: rgb(242 237 226 / .1);
  color: var(--gold-soft);
  box-shadow: inset 0 0 0 1px rgb(200 164 92 / .3);
  transition: background-color var(--dur-fast) var(--ease-out),
              color var(--dur-fast) var(--ease-out),
              transform var(--dur-base) var(--ease-out);
}
.dh-tile:hover .dh-tile__ico {
  background: var(--gold); color: var(--green-950);
  box-shadow: none;
  transform: rotate(-6deg) scale(1.06);
}

.dh-tile__name { color: var(--paper); }
.dh-tile__gloss { color: rgb(242 237 226 / .82); }
.dh-tile__meta {
  background: rgb(242 237 226 / .1);
  color: var(--gold-soft);
  box-shadow: inset 0 0 0 1px rgb(200 164 92 / .28);
}
.dh-tile__go { color: var(--gold-soft); }


@media (prefers-reduced-motion: reduce) {
  .dh-tile, .dh-tile__go svg, .dh-tile__ico { transition: none; }
}

/* ========================= department pages =========================
   Ten pages off one template. The order follows the questions a patient
   actually asks: what is this, when should I come, who will I see, what
   can be done here, how do I book.                                     */
.dp-head { background: var(--bone); padding-bottom: var(--sp-5); }
.dp-head .live-now { margin-bottom: var(--sp-3); }
.dp-head__row { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: var(--sp-4); align-items: start; }
.dp-head__ico {
  display: grid; place-items: center; flex: none;
  width: 52px; height: 52px; border-radius: var(--radius);
  background: var(--green-100); color: var(--green-700);
}
.dp-head__ico svg { width: 27px; height: 27px; display: block; }
.dp-head h1 { margin: 0 0 var(--sp-3); }
/* 84ch, not 68: at ~28 words the narrower measure ran to three lines. Wider
   here is fine because the heading above sets the reading rhythm and this is
   one short paragraph, not body copy. */
.dp-intro { max-width: 55.944em; color: var(--muted); margin: 0; }
.dp-head__acts { display: flex; flex-wrap: wrap; gap: var(--sp-3); margin-top: var(--sp-5); }

/* ---- when to see ---- */
.dp-when h2, .dp-ops h2, .dp-docs h2, .dp-services h2 {
  margin: 0 0 var(--sp-4); font-size: var(--fs-xl); color: var(--green-900);
}
/* 88ch: this is a single short paragraph introducing the list below, not body
   copy, so a wider measure keeps it to two lines without hurting reading. */
.dp-lead { max-width: 58.608em; color: var(--ink); line-height: 1.7; margin: 0 0 var(--sp-4); }
.dp-note { max-width: 46.62em; margin: var(--sp-4) 0 0; color: var(--muted); font-size: var(--fs-sm); line-height: 1.7; }

/* ---- first aid, where the copy carries one ---- */
.dp-alert { padding-block: 0; }
.dp-alert__box { padding: var(--sp-5); border-radius: var(--radius-lg); background: var(--accent-red); color: var(--paper); }
.dp-alert__box h2 { margin: 0 0 var(--sp-2); font-size: var(--fs-lg); color: var(--paper); }
.dp-alert__box p { margin: 0 0 var(--sp-4); font-size: var(--fs-sm); line-height: 1.7; }
.btn--amb { background: var(--paper); color: var(--accent-red); font-weight: var(--fw-bold); }
.btn--amb:hover { background: var(--cream); color: var(--accent-red); }

/* ---- operations and linked services ---- */
.dp-ops__list { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: var(--sp-2); }
.dp-ops__list li { margin: 0; }
.dp-ops__list a {
  display: inline-block; padding: var(--sp-2) var(--sp-4);
  border-radius: var(--radius-pill);
  background: var(--paper); box-shadow: inset 0 0 0 1px var(--line);
  color: var(--ink); font-size: var(--fs-sm); text-decoration: none;
  transition: box-shadow var(--dur-fast) var(--ease-out), color var(--dur-fast) var(--ease-out);
}
.dp-ops__list a:hover { color: var(--green-800); box-shadow: inset 0 0 0 1px var(--green-600); }

/* ---- diagnostics service list ---- */
.dsv-grid { display: grid; gap: var(--sp-3); }
.dsv-grid > * { min-width: 0; }
/* Ten services, so the column count has to divide ten or one card is left
   stranded on a row of its own: 2 - 5 - 5 - 2, never 3. Five across on a wide
   screen is the shape Billal asked for and it is also the only one that fills
   both rows exactly. */
@media (min-width: 560px)  { .dsv-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
/* 1040px, not 900: five across in a 900px window leaves each card 166px, and
   "আল্ট্রাসনোগ্রাম (৪ডি)" then takes three lines. Two columns holds until there
   is room for five — and two also divides ten. */
@media (min-width: 1040px) { .dsv-grid { grid-template-columns: repeat(5, minmax(0, 1fr)); } }
.dsv {
  display: grid; gap: 3px; padding: var(--sp-4);
  background: var(--paper); border: 1px solid var(--line); border-radius: var(--radius-lg);
  text-decoration: none;
  transition: transform var(--dur-base) var(--ease-out), border-color var(--dur-fast) var(--ease-out);
}
.dsv:hover { transform: translateY(-2px); border-color: var(--green-600); }
.dsv__name { font-weight: var(--fw-semi); color: var(--green-900); font-size: var(--fs-sm); }
.dsv__why { font-size: var(--fs-xs); color: var(--muted); }

/* ---- tests strip ---- */
.dp-tests { padding-block: 0; }
.dp-tests__box { padding: var(--sp-5); border-radius: var(--radius-lg); background: var(--green-100); }
.dp-tests__box h2 { margin: 0 0 var(--sp-2); font-size: var(--fs-lg); color: var(--green-900); }
.dp-tests__box p { margin: 0 0 var(--sp-3); max-width: 46.62em; color: var(--green-950); line-height: 1.7; }
.dp-tests__go {
  display: inline-flex; align-items: center; gap: 6px;
  color: var(--green-800); font-weight: var(--fw-semi); font-size: var(--fs-sm); text-decoration: none;
}
.dp-tests__go svg { width: 15px; height: 15px; }
.dp-tests__go:hover { color: var(--green-950); }


@media (max-width: 560px) {
  .dp-head, .dp-when, .dp-docs, .dp-ops, .dp-services { padding-block: var(--sp-5); }
  .dp-head__row { grid-template-columns: 1fr; gap: var(--sp-3); }
  .dp-head__ico { width: 44px; height: 44px; }
  .dp-head__ico svg { width: 23px; height: 23px; }
  .dp-head__acts .btn { flex: 1 1 0; min-width: 0; justify-content: center; }
  .dpd { padding: var(--sp-4); }
}
@media (prefers-reduced-motion: reduce) { .dpd, .dsv, .dpd__go svg { transition: none; } }

/* ========================= doctors hub =========================
   The page targets "best doctor in Cumilla" and never claims it — the query
   is answered by an H2 phrased as a question, and the body says specialist.
   The confirmed-hours table carries only the four the client has confirmed;
   that is a feature, not a gap, so it is labelled rather than padded.      */
.dr-head { background: var(--bone); padding-bottom: var(--sp-5); }
.dr-head .live-now { margin-bottom: var(--sp-3); }
.dr-head h1 { margin: 0 0 var(--sp-3); }
.dr-intro { max-width: 45.288em; color: var(--muted); margin: 0; }

/* ---- find by problem ---- */
.dr-find h2, .dr-confirmed h2, .dr-all h2 {
  margin: 0 0 var(--sp-3); font-size: var(--fs-xl); color: var(--green-900);
}


/* ========================= doctor pages =========================
   The E-E-A-T engine: name, credentials, what to come for, when, how to
   book. Four of the fifteen have confirmed hours and show them; the other
   eleven show the hotline instead, never a guessed day.                 */
.dx-head { background: var(--bone); padding-bottom: var(--sp-6); }
.dx-head__grid { display: grid; gap: var(--sp-5); align-items: start; }
.dx-head__grid > * { min-width: 0; }
@media (min-width: 760px) { .dx-head__grid { grid-template-columns: 132px minmax(0, 1fr); gap: var(--sp-6); } }
.dx-head .live-now { margin-bottom: var(--sp-3); }
.dx-head h1 { margin: 0 0 var(--sp-2); font-size: clamp(1.5rem, 3.4vw, 2.1rem); }
.dx-role { margin: 0 0 var(--sp-3); font-size: var(--fs-md); font-weight: var(--fw-semi); color: var(--green-700); }
.dx-intro { max-width: 46.62em; color: var(--muted); line-height: 1.8; margin: 0; }
.dx-head__acts { display: flex; flex-wrap: wrap; gap: var(--sp-3); margin-top: var(--sp-5); }

/* A monogram until the photographs arrive. Fifteen identical grey
   silhouettes would say the hospital could not be bothered; the doctor's
   own initial at least belongs to them. */
.dx-portrait {
  display: grid; place-items: center;
  width: 96px; height: 96px; border-radius: var(--radius-lg);
  background: var(--green-800);
  background-image: radial-gradient(120% 120% at 30% 0%, var(--green-700), transparent 70%);
  box-shadow: inset 0 0 0 1px rgb(242 237 226 / .16);
}
@media (min-width: 760px) { .dx-portrait { width: 132px; height: 132px; } }
.dx-portrait span {
  font-family: var(--font-display); font-weight: var(--fw-bold);
  font-size: 2.6rem; line-height: 1; color: var(--cream);
}
@media (min-width: 760px) { .dx-portrait span { font-size: 3.4rem; } }

/* ---- credentials ---- */
.dx-cred__grid { display: grid; gap: var(--sp-5); align-items: start; }
.dx-cred__grid > * { min-width: 0; }
@media (min-width: 860px) { .dx-cred__grid { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: var(--sp-7); } }
.dx-cred h2 { margin: 0 0 var(--sp-3); font-size: var(--fs-lg); color: var(--green-900); }
.dx-degs { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--sp-2); }
.dx-degs li {
  position: relative; margin: 0; padding-inline-start: var(--sp-5);
  color: var(--ink); line-height: 1.6; font-size: var(--fs-sm);
}
.dx-degs li::before {
  content: ""; position: absolute; inset-inline-start: 0; top: .6em;
  width: 6px; height: 6px; border-radius: 50%; background: var(--green-500);
}
.dx-facts { margin: 0; display: grid; gap: var(--sp-3); }
.dx-facts > div { display: grid; gap: 2px; }
.dx-facts dt {
  font-size: var(--fs-xs); font-weight: var(--fw-bold); color: var(--muted);
  letter-spacing: var(--track-label); text-transform: uppercase;
}
html[lang="bn"] .dx-facts dt { text-transform: none; letter-spacing: normal; }
.dx-facts dd { margin: 0; font-size: var(--fs-sm); color: var(--ink); line-height: 1.6; }
.dx-facts dd a { color: var(--green-700); font-weight: var(--fw-semi); text-decoration: none; }
.dx-facts dd a:hover { text-decoration: underline; }

/* ---- what to see them for ---- */
.dx-treats { background: var(--bone); }
.dx-treats h2 { margin: 0 0 var(--sp-4); font-size: var(--fs-xl); color: var(--green-900); }
/* eleven of fifteen have no treats: line on file, so they carry a one-line
   department scope instead of an invented condition list */

/* ---- booking ---- */
.dx-book__grid { display: grid; gap: var(--sp-5); align-items: start; }
.dx-book__grid > * { min-width: 0; }
@media (min-width: 860px) { .dx-book__grid { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: var(--sp-7); } }
.dx-book h2 { margin: 0 0 var(--sp-3); font-size: var(--fs-lg); color: var(--green-900); }
.dx-hours {
  margin: 0 0 var(--sp-3); padding: var(--sp-3) var(--sp-4);
  border-radius: var(--radius); background: var(--green-100);
  color: var(--green-950); font-weight: var(--fw-semi); line-height: 1.7;
}
.dx-tel { color: var(--green-800); font-family: var(--font-ui); font-variant-numeric: tabular-nums; }
.dx-addr, .dx-amb { margin: 0 0 var(--sp-2); font-size: var(--fs-sm); color: var(--muted); line-height: 1.7; }
.dx-addr b { color: var(--ink); }
.dx-amb a { color: var(--accent-red); font-weight: var(--fw-semi); }
.dx-steps { margin: 0; padding: 0; list-style: none; counter-reset: dxstep; display: grid; gap: var(--sp-3); }
.dx-steps li {
  position: relative; margin: 0; padding-inline-start: calc(var(--sp-5) + 12px);
  color: var(--ink); line-height: 1.7; font-size: var(--fs-sm);
}
.dx-steps li::before {
  counter-increment: dxstep; content: counter(dxstep);
  position: absolute; inset-inline-start: 0; top: 0;
  display: grid; place-items: center;
  width: 24px; height: 24px; border-radius: 50%;
  background: var(--green-700); color: var(--paper);
  font-family: var(--font-ui); font-size: var(--fs-xs); font-weight: var(--fw-bold);
}
html[lang="bn"] .dx-steps li::before { content: counter(dxstep, bengali); }

/* ---- related ---- */
@media (min-width: 760px) { }

@media (max-width: 560px) {
  .dx-head, .dx-cred, .dx-treats, .dx-book, .dx-rel { padding-block: var(--sp-5); }
  .dx-head { padding-bottom: var(--sp-5); }
  .dx-head__grid { grid-template-columns: auto minmax(0, 1fr); gap: var(--sp-4); align-items: center; }
  /* the monogram shrinks and sits beside the name rather than above it */
  .dx-portrait { width: 64px; height: 64px; }
  .dx-portrait span { font-size: 1.8rem; }
  .dx-head__body { grid-column: 1 / -1; }
  .dx-head__acts .btn { flex: 1 1 0; min-width: 0; justify-content: center; }
}

/* Inline links that a thumb has to hit.
   WCAG 2.2 2.5.8 exempts a link inline in a sentence, but the exemption does
   not make a 19px phone number easier to tap on a bus — and these are the
   links people reach for in a hurry. inline-block plus vertical padding takes
   each to 25px without changing where the text sits on the line. */
.dp-amb a, .dx-amb a, .dx-hours .dx-tel,
.dx-facts dd a, .dp-alldocs a, .dr-card__dept a, .dr-confirmed__note,
/* the ambulance number written into the first-aid sentence on the oxygen and
   fracture pages — the one link on those pages somebody taps in a hurry */
.dp-alert__box a {
  display: inline-block; padding-block: 3px;
}
/* the department list on a doctor page separates with a middot, so the
   padding must not close the gap between two adjacent names */
.dx-facts dd a { margin-inline-end: 1px; }

/* ===================== department pages, v2 =====================
   Three changes on 2026-09-01: a shorter intro, a selectable symptom list,
   and the doctors moved onto the brand band as one row of photo cards.   */

/* ---- when to see: selectable ---- */
.dp-syms {
  list-style: none; margin: 0; padding: 0;
  display: grid; gap: var(--sp-2);
}
@media (min-width: 700px)  { .dp-syms { grid-template-columns: 1fr 1fr; gap: var(--sp-2) var(--sp-3); } }
@media (min-width: 1100px) { .dp-syms { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
.dp-syms li { margin: 0; min-width: 0; }

.dp-sym {
  width: 100%; display: grid;
  grid-template-columns: auto minmax(0, 1fr); align-items: center; gap: var(--sp-3);
  padding: var(--sp-3) var(--sp-4);
  text-align: start; cursor: pointer;
  background: var(--paper);
  border: 0; border-radius: var(--radius-lg);
  box-shadow: inset 0 0 0 1px var(--line);
  color: var(--ink); font: inherit; font-size: var(--fs-sm); line-height: 1.5;
  transition: box-shadow var(--dur-fast) var(--ease-out),
              background-color var(--dur-fast) var(--ease-out),
              transform var(--dur-base) var(--ease-out);
}
.dp-sym:hover { transform: translateY(-2px); box-shadow: inset 0 0 0 1px var(--green-500), var(--shadow-lift); }
.dp-sym__tick {
  display: grid; place-items: center; flex: none;
  width: 24px; height: 24px; border-radius: 50%;
  background: var(--bone); color: transparent;
  box-shadow: inset 0 0 0 1px var(--line);
  transition: background-color var(--dur-fast) var(--ease-out),
              color var(--dur-fast) var(--ease-out),
              box-shadow var(--dur-fast) var(--ease-out);
}
.dp-sym__tick svg { width: 14px; height: 14px; display: block; }
.dp-sym[aria-pressed="true"] {
  background: var(--green-100);
  box-shadow: inset 0 0 0 1.5px var(--green-600);
}
.dp-sym[aria-pressed="true"] .dp-sym__tick {
  background: var(--green-600); color: var(--paper); box-shadow: none;
}
.dp-sym[aria-pressed="true"] .dp-sym__t { color: var(--green-950); font-weight: var(--fw-semi); }

/* the bar that appears once something is selected */
.dp-pick {
  display: grid; gap: var(--sp-3); align-items: center;
  margin-top: var(--sp-5); padding: var(--sp-4) var(--sp-5);
  border-radius: var(--radius-lg);
  background: var(--green-900);
  background-image: radial-gradient(90% 130% at 88% 0%, rgb(35 158 56 / .22), transparent 62%);
  color: var(--cream);
}
@media (min-width: 720px) { .dp-pick { grid-template-columns: minmax(0, 1fr) auto; } }
.dp-pick[hidden] { display: none; }
.dp-pick__t { margin: 0; font-size: var(--fs-sm); }
.dp-pick__t b {
  display: inline-block; min-width: 26px; padding: 1px 8px; margin-inline-end: 4px;
  border-radius: var(--radius-pill);
  background: var(--gold); color: var(--green-950);
  font-family: var(--font-ui); font-weight: var(--fw-bold);
}
.dp-pick__acts { display: flex; flex-wrap: wrap; gap: var(--sp-2); }
/* .btn--ghost is drawn for light surfaces; on this band it needs the light treatment */
.dp-pick .btn--ghost { color: var(--cream); box-shadow: inset 0 0 0 1px rgb(242 237 226 / .42); }
.dp-pick .btn--ghost:hover { background: rgb(242 237 226 / .1); color: var(--paper); }

/* ---- doctors, on the brand band ----
   Same surface as the departments hub and the ambulance band.
   Verified on --green-900 (#03320b): --paper 12.3:1, cream at 82% ~8.4:1,
   --gold-soft 7.9:1. */
.dp-docs {
  background-color: var(--green-900);
  background-image: radial-gradient(90% 130% at 88% 0%, rgb(35 158 56 / .20), transparent 62%);
  color: var(--cream);
}
.dp-docs h2 { color: var(--paper); }

/* One row. No department has more than three doctors, so data-n sets the
   column count directly rather than letting them wrap unevenly. */
.dpd-grid { display: grid; gap: var(--sp-4); }
.dpd-grid > * { min-width: 0; }
@media (min-width: 760px) {
  .dpd-grid[data-n="2"] { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .dpd-grid[data-n="3"] { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}


.dpd {
  display: flex; flex-direction: column; overflow: hidden;
  padding: 0;
  background: rgb(242 237 226 / .055);
  border: 0; border-radius: var(--radius-lg);
  box-shadow: inset 0 0 0 1px rgb(242 237 226 / .13);
  color: var(--cream);
  transition: transform var(--dur-base) var(--ease-out),
              background-color var(--dur-fast) var(--ease-out),
              box-shadow var(--dur-base) var(--ease-out);
}
.dpd:hover {
  transform: translateY(-3px);
  background: rgb(242 237 226 / .085);
  box-shadow: inset 0 0 0 1px rgb(200 164 92 / .5), 0 14px 34px rgb(2 26 6 / .45);
}

/* The photograph slot. Portraits are still PENDING, so it carries the
   doctor's initial — a flat rectangle would read as a broken image. When the
   photographs arrive an <img> replaces the <span> and nothing else changes. */
.dpd__photo {
  display: grid; place-items: center;
  /* fixed, not an aspect ratio: at 631px wide, 4/3 made a 473px-tall slot.
     object-fit crops the real photograph into this strip when it arrives. */
  height: 132px;
  background: var(--green-800);
  background-image: radial-gradient(120% 120% at 30% 0%, var(--green-700), transparent 70%);
  border-bottom: 1px solid rgb(242 237 226 / .12);
  text-decoration: none;
}
.dpd__photo span {
  font-family: var(--font-display); font-weight: var(--fw-bold);
  font-size: 2.5rem; line-height: 1; color: rgb(242 237 226 / .5);
  transition: color var(--dur-fast) var(--ease-out);
}
.dpd:hover .dpd__photo span { color: var(--gold-soft); }
.dpd__photo img { width: 100%; height: 100%; object-fit: cover; display: block; }

.dpd__body { display: flex; flex-direction: column; flex: 1 1 auto; padding: var(--sp-4) var(--sp-4) var(--sp-4); }
.dpd :is(h2, h3) { margin: 0 0 6px; font-size: var(--fs-lg); line-height: 1.25; }
.dpd :is(h2, h3) a { color: var(--paper); text-decoration: none; }
.dpd :is(h2, h3) a:hover { color: var(--gold-soft); }
.dpd__role { margin: 0; font-size: var(--fs-sm); font-weight: var(--fw-semi); color: var(--gold-soft); }

/* The general practitioner's classification, on her own card.
   It used to be a sub-heading above a second grid, which is what pushed her
   onto a second row. doctors-data.md requires she is never presented as a
   specialist; this label travels with the card, so it cannot be separated
   from her name by scrolling. build_dept_pages.assert_gp_isolated fails the
   build if a specialist word ever appears inside this card. */
.dp-alldocs { margin: var(--sp-5) 0 0; }
.dp-alldocs a { color: var(--gold-soft); font-weight: var(--fw-semi); font-size: var(--fs-sm); }

/* ---- tighter rhythm: the help block lost three lines, so the band that
   holds it no longer needs the taller padding ---- */
.dp-docs + .dp-ops, .dp-docs + .dp-tests { padding-top: var(--sp-6); }
.visit--compact .visit__help { align-self: start; }

@media (max-width: 760px) {
  .dpd__photo { height: 124px; }
  .dpd__photo span { font-size: 2.4rem; }
  .dpd__body { padding: var(--sp-4); }
}
@media (max-width: 560px) {
  .dp-sym { padding: var(--sp-3); }
  .dp-pick { padding: var(--sp-4); }
  .dp-pick__acts .btn { flex: 1 1 0; min-width: 0; justify-content: center; }
}
@media (prefers-reduced-motion: reduce) {
  .dp-sym, .dpd, .dpd__go svg, .dpd__photo span { transition: none; }
}

/* ---- doctor card, restructured ----
   Name, title, degrees, workplace and hours were five stacked paragraphs in
   near-identical grey: one block of text with no shape, and every card a
   different height depending on how many of the five a doctor had on file.

   Now each fact says what it is. Degrees and workplace sit in a labelled list
   with an icon; the chamber line — the one actionable fact — gets its own
   strip; and three actions sit at the foot of every card, so a visitor can
   ring or message about that specific doctor without leaving the page.        */


.dpd__ico { display: inline-grid; place-items: center; flex: none; width: 15px; height: 15px; }
.dpd__ico svg { width: 100%; height: 100%; display: block; }

/* the chamber strip: pushed to the foot of the body so every card in a row
   lines its hours up, whatever else the doctor has on file */
.dpd__when {
  display: flex; align-items: center; gap: var(--sp-2);
  /* margin-top:auto pushes this to the foot of the body so every card in the
     row lines its hours up. A later margin-top would cancel the auto — the
     minimum gap above comes from .dpd__meta's margin-bottom instead. */
  margin: auto 0 0; padding: var(--sp-2) var(--sp-3);
  border-radius: var(--radius);
  background: rgb(200 164 92 / .12);
  box-shadow: inset 0 0 0 1px rgb(200 164 92 / .22);
  font-size: var(--fs-sm); line-height: 1.45; color: var(--cream);
}
.dpd__when .dpd__ico { color: var(--gold-soft); }
.dpd__when b { color: var(--gold-soft); font-weight: var(--fw-semi); }
/* eleven of fifteen have no confirmed hours; that line is an instruction, and
   it should not wear the gold that means "here is a confirmed time" */
.dpd__when.is-soft {
  background: rgb(242 237 226 / .06);
  box-shadow: inset 0 0 0 1px rgb(242 237 226 / .14);
  color: rgb(242 237 226 / .78); font-style: italic;
}
.dpd__when.is-soft .dpd__ico { color: rgb(242 237 226 / .6); }

/* ---- the three actions ---- */
.dpd__acts {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2);
  margin-top: var(--sp-3); padding-top: var(--sp-3);
  border-top: 1px solid rgb(242 237 226 / .14);
}
.dpd__go {
  display: inline-flex; align-items: center; gap: 6px;
  margin: 0; padding: 4px 0; border: 0;
  margin-inline-end: auto;
  color: var(--gold-soft); font-size: var(--fs-sm); font-weight: var(--fw-semi);
  text-decoration: none;
}
.dpd__go svg { width: 15px; height: 15px; transition: transform var(--dur-fast) var(--ease-out); }
.dpd:hover .dpd__go svg { transform: translateX(3px); }
.dpd__act {
  display: inline-flex; align-items: center; gap: 6px;
  min-height: 34px; padding: 0 var(--sp-3);
  border-radius: var(--radius-pill);
  background: rgb(242 237 226 / .1);
  box-shadow: inset 0 0 0 1px rgb(242 237 226 / .2);
  color: var(--cream); font-size: var(--fs-xs); font-weight: var(--fw-semi);
  text-decoration: none;
  transition: background-color var(--dur-fast) var(--ease-out),
              box-shadow var(--dur-fast) var(--ease-out),
              color var(--dur-fast) var(--ease-out);
}
.dpd__act:hover {
  background: var(--gold); color: var(--green-950);
  box-shadow: none;
}
.dpd__act .dpd__ico { width: 13px; height: 13px; }

/* ---- the photo reacts, so the card feels alive without moving text ---- */
.dpd__photo { overflow: hidden; }
.dpd__photo span {
  transition: color var(--dur-base) var(--ease-out), transform var(--dur-base) var(--ease-out);
}
.dpd:hover .dpd__photo span { transform: scale(1.08); }
.dpd:hover .dpd__photo img { transform: scale(1.04); }
.dpd__photo img { transition: transform var(--dur-base) var(--ease-out); }

/* the general practitioner badge sits above her name */

@media (max-width: 560px) {
  .dpd__acts { gap: 6px; }
  .dpd__go { margin-inline-end: auto; }
}
@media (prefers-reduced-motion: reduce) {
  .dpd__photo span, .dpd__photo img, .dpd__act { transition: none; }
  .dpd:hover .dpd__photo span, .dpd:hover .dpd__photo img { transform: none; }
}

/* ---- section heading with the "all doctors" link beside it ----
   It used to sit under the grid, where it read as a fourth card's worth of
   dead space. Beside the heading it is a destination, not an afterthought. */
.dp-docs__head {
  display: flex; flex-wrap: wrap; align-items: baseline;
  justify-content: space-between; gap: var(--sp-3);
  margin-bottom: var(--sp-4);
}
.dp-docs__head h2 { margin: 0; }
.dp-alldocs {
  display: inline-flex; align-items: center; gap: 6px;
  margin: 0; padding: var(--sp-2) var(--sp-4);
  border-radius: var(--radius-pill);
  background: rgb(242 237 226 / .1);
  box-shadow: inset 0 0 0 1px rgb(200 164 92 / .34);
  color: var(--gold-soft); font-size: var(--fs-sm); font-weight: var(--fw-semi);
  text-decoration: none; white-space: nowrap;
  transition: background-color var(--dur-fast) var(--ease-out),
              color var(--dur-fast) var(--ease-out);
}
.dp-alldocs svg { width: 15px; height: 15px; }
.dp-alldocs:hover { background: var(--gold); color: var(--green-950); }

/* The hours have to hold one line: "রবি, মঙ্গল ও বৃহস্পতি ৫টা–৮টা · শুক্রবার ২টা–৬টা"
   is the longest string on any card. Dropping the "Chamber:" label bought most
   of the room; the rest comes from a slightly smaller size here. */
.dpd__when { font-size: var(--fs-xs); }
.dpd__when > span:last-child { min-width: 0; }

/* ---- a department with one doctor ----
   Four departments (surgery, cardiology, ENT, neurosurgery) have a single
   doctor. Left as one card in a three-column grid it sat in the corner with
   two-thirds of the band empty. Wide, it becomes a spotlight: portrait beside
   the name, credentials in one column, hours and actions in the other — and
   where the doctor has a treats: line on file, their conditions fill the rest.

   Nothing here is new information. The conditions are the same list their own
   profile page carries. */
.dpd-grid[data-n="1"] { grid-template-columns: minmax(0, 1fr); max-width: none; }

@media (min-width: 860px) {
  .dpd--wide { display: grid; grid-template-columns: 290px minmax(0, 1fr); }
  .dpd--wide .dpd__photo { height: 100%; min-height: 300px; border-bottom: 0; }
  .dpd--wide .dpd__photo span { font-size: 4rem; }
  .dpd--wide .dpd__body {
    display: grid; align-content: start;
    grid-template-columns: minmax(0, 1fr) minmax(0, 290px);
    grid-template-areas:
      "name   when"
      "role   when"
      "meta   acts"
      "subh   acts"
      "treats acts";
    column-gap: var(--sp-7);
    padding: var(--sp-5) var(--sp-6) var(--sp-5);
  }
  .dpd--wide :is(h2, h3) { grid-area: name; }
  .dpd--wide .dpd__role { grid-area: role; }
  .dpd--wide .dpd__meta { grid-area: meta; }
  .dpd--wide .dpd__sub { grid-area: subh; }
  .dpd--wide .dpd__treats { grid-area: treats; }
  /* the hours sit top-right, where the eye lands after the name */
  .dpd--wide .dpd__when { grid-area: when; margin: 0; align-self: start; }
  .dpd--wide .dpd__acts {
    grid-area: acts; align-self: end;
    margin-top: var(--sp-5); border-top: 0;
  }
}

.dpd__sub {
  margin: var(--sp-4) 0 var(--sp-2);
  font-size: var(--fs-xs); font-weight: var(--fw-semi);
  color: rgb(242 237 226 / .62);
  letter-spacing: var(--track-label); text-transform: uppercase;
}
html[lang="bn"] .dpd__sub { text-transform: none; letter-spacing: normal; }
.dpd__treats {
  list-style: none; margin: 0; padding: 0;
  display: flex; flex-wrap: wrap; gap: 6px;
}
.dpd__treats li {
  margin: 0; padding: 3px var(--sp-3);
  border-radius: var(--radius-pill);
  background: rgb(242 237 226 / .08);
  box-shadow: inset 0 0 0 1px rgb(242 237 226 / .14);
  font-size: var(--fs-xs); color: rgb(242 237 226 / .88);
}

/* An author-placed line break in a lead paragraph. Suppressed below 1100px,
   where the natural wrap reads better than a break chosen for a wide screen.
   The space before it in the source is what keeps the words apart when it is
   hidden -- see CLAUDE.md section 8. */
.dp-br { display: none; }
@media (min-width: 1100px) { .dp-br { display: inline; } }

/* ========================= doctors hub, v2 =========================
   The roster now uses the same card the department pages use, imported
   rather than copied. What is local to this page is the filter bar.      */
.dr-head { background: var(--bone); padding-bottom: var(--sp-5); }
.dr-head__acts { display: flex; flex-wrap: wrap; gap: var(--sp-3); margin-top: var(--sp-5); }

/* the roster sits on the brand band, like the department pages */
.dr-all {
  background-color: var(--green-900);
  background-image: radial-gradient(90% 130% at 88% 0%, rgb(35 158 56 / .20), transparent 62%);
  color: var(--cream);
}
.dr-grid { grid-template-columns: minmax(0, 1fr); }
@media (min-width: 760px)  { .dr-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 1140px) { .dr-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
.dr-all .pkgp-empty { color: rgb(242 237 226 / .82); }
.dr-all .pkgp-empty .tel-text { color: var(--gold-soft); }

@media (max-width: 560px) {
  /* .dr-head was left in this selector list when the filter bar was removed;
     it is a section, not a flex item, so the declarations did nothing to it. */
  .dr-head__acts .btn { flex: 1 1 0; min-width: 0; justify-content: center; }
}
@media (prefers-reduced-motion: reduce) { }


/* ---- cards in a row share their row heights ----
   Name, role, DEGREES, ALSO WORKS AT, hours and buttons used to start wherever
   the text above them happened to end, so no two cards in a row lined up. CSS
   subgrid makes every card use the SAME rows as the grid it sits in, which
   aligns all six landmarks across the row no matter how long each doctor's
   degree line is.

   Nine rows: portrait, name, role, degrees label, degrees value, workplace
   label, workplace value, hours, buttons. The builder always emits both
   label/value pairs — empty where a doctor has no workplace on file — so every
   card fills the same nine.

   Where subgrid is unsupported the declaration is ignored and the cards fall
   back to the previous stacked layout: unaligned, but never broken.          */
@supports (grid-template-rows: subgrid) {
  @media (min-width: 760px) {
    .dpd-grid:not(.dpd-grid--solo) { grid-template-rows: repeat(9, auto); }
    /* row-gap: 0 matters. A subgrid inherits the parent's gap, so the grid's
       row gap — which is there to separate one row of CARDS from the next —
       was also being applied to all eight row boundaries INSIDE every card.
       That was 216px of pure gap per card. Spacing inside comes from the
       elements' own margins. */
    .dpd-grid:not(.dpd-grid--solo) > .dpd:not(.dpd--wide) {
      grid-row: span 9; display: grid; grid-template-rows: subgrid; row-gap: 0;
    }
    .dpd-grid:not(.dpd-grid--solo) > .dpd:not(.dpd--wide) > .dpd__body {
      grid-row: span 8; display: grid; grid-template-rows: subgrid; row-gap: 0;
    }
  }
}

/* the two facts, now flat children of the body */
.dpd__lbl {
  display: flex; align-items: center; gap: 6px;
  margin: var(--sp-3) 0 2px;
  font-size: var(--fs-xs); font-weight: var(--fw-semi);
  color: rgb(242 237 226 / .62);
  letter-spacing: var(--track-label); text-transform: uppercase;
}
html[lang="bn"] .dpd__lbl { text-transform: none; letter-spacing: normal; }
.dpd__val {
  margin: 0; font-size: var(--fs-xs); line-height: 1.6;
  color: rgb(242 237 226 / .88);
}
/* The placeholder pair holds its row open and says nothing. It keeps the SAME
   margins as a real label: subgrid aligns the rows, but a placeholder with no
   top margin let the text inside the next real label sit 18px higher than its
   neighbours, so the rows matched while the words did not. */
.dpd__lbl.is-empty, .dpd__val.is-empty { min-height: 0; }

/* ---- doctor cards on a phone ----
   Portrait on top, everything under it. I briefly turned the card sideways to
   save scroll height; it read badly — a narrow strip of green with a small
   letter in it, and the buttons wrapping oddly underneath. Height is worth
   less than a card that looks like a card.                                   */
@media (max-width: 759px) {
  .dpd:not(.dpd--wide) .dpd__photo { height: 152px; }
  .dpd:not(.dpd--wide) .dpd__photo span { font-size: 2.6rem; }
  .dpd:not(.dpd--wide) .dpd__body { padding: var(--sp-4); }

  /* Profile on its own line, then Call and WhatsApp sharing the next one.
     In a single flex row the third button dropped on its own and left the
     row looking broken. */
  .dpd__acts {
    display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-2);
    align-items: stretch;
  }
  .dpd__go { grid-column: 1 / -1; margin: 0 0 2px; }
  .dpd__act { justify-content: center; min-height: 40px; }
}
@media (max-width: 400px) {
  .dpd:not(.dpd--wide) .dpd__photo { height: 132px; }
  .dpd:not(.dpd--wide) .dpd__body { padding: var(--sp-3); }
}

/* ===================== doctor page, v2 =====================
   These pages were built before the department pages settled the design
   language, so they read as a different site: no brand band, a small
   monogram, plain lists. This brings them onto the same system.          */

/* ---- hero ---- */
.dx-head {
  background-color: var(--green-900);
  background-image: radial-gradient(90% 130% at 88% 0%, rgb(35 158 56 / .20), transparent 62%);
  color: var(--cream);
  padding-bottom: var(--sp-7);
}
.dx-head__grid { gap: var(--sp-6); }
@media (min-width: 760px) { .dx-head__grid { grid-template-columns: 200px minmax(0, 1fr); } }
.dx-head h1 { color: var(--paper); }
.dx-role { color: var(--gold-soft); }
.dx-intro { color: rgb(242 237 226 / .86); }
.dx-head .live-now { color: var(--cream); }
.dx-head .live-now__text { color: rgb(242 237 226 / .82); }
.dx-head .live-now__time { color: var(--gold-soft); }

/* the portrait slot: an <img> drops straight in when the photographs arrive */
.dx-portrait {
  width: 100%; max-width: 200px; height: 200px;
  border-radius: var(--radius-lg);
  background: var(--green-800);
  background-image: radial-gradient(120% 120% at 30% 0%, var(--green-700), transparent 70%);
  box-shadow: inset 0 0 0 1px rgb(200 164 92 / .28);
  overflow: hidden;
}
.dx-portrait span { color: rgb(242 237 226 / .55); }
.dx-portrait img { width: 100%; height: 100%; object-fit: cover; display: block; }
.dx-head__acts .btn--ghost {
  color: var(--cream); box-shadow: inset 0 0 0 1px rgb(242 237 226 / .42);
}
.dx-head__acts .btn--ghost:hover { background: rgb(242 237 226 / .1); color: var(--paper); }

/* ---- the week strip ---- */
.dxw { padding-block: var(--sp-6); background: var(--bone); }
.dxw__head {
  display: flex; flex-wrap: wrap; align-items: baseline;
  justify-content: space-between; gap: var(--sp-3);
  margin-bottom: var(--sp-4);
}
.dxw__head h2 { margin: 0; font-size: var(--fs-xl); color: var(--green-900); }
/* the live line: written by JS, because a static page cannot know what day
   the visitor is reading on */
.dxw__live {
  margin: 0; padding: var(--sp-2) var(--sp-4);
  border-radius: var(--radius-pill);
  background: var(--green-100); color: var(--green-800);
  font-size: var(--fs-sm); font-weight: var(--fw-semi);
}
.dxw__live.is-in { background: var(--green-700); color: var(--paper); }
.dxw__live[hidden] { display: none; }

.dxw__days {
  list-style: none; margin: 0; padding: 0;
  display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 6px;
}
.dxw__day {
  margin: 0; position: relative;
  border-radius: var(--radius); text-align: center;
  background: var(--paper); box-shadow: inset 0 0 0 1px var(--line);
  color: var(--muted);
}
.dxw__day b, .dxw__day span {
  display: block; padding-inline: 4px;
}
.dxw__day b { font-size: var(--fs-sm); color: var(--ink); padding-top: var(--sp-3); }
.dxw__day span { font-size: 11px; line-height: 1.35; padding-bottom: var(--sp-3); }
.dxw__day a {
  display: block; text-decoration: none; color: inherit; border-radius: var(--radius);
}
/* a day the doctor sits: tapping it writes the WhatsApp message */
.dxw__day.is-on {
  background: var(--green-100); box-shadow: inset 0 0 0 1px var(--green-500);
}
.dxw__day.is-on b { color: var(--green-900); }
.dxw__day.is-on span { color: var(--green-800); font-weight: var(--fw-semi); }
.dxw__day.is-on:hover { box-shadow: inset 0 0 0 1.5px var(--green-700); }
.dxw__day.is-today { box-shadow: inset 0 0 0 2px var(--gold); }
.dxw__now {
  position: absolute; inset-inline-start: 50%; top: -9px; transform: translateX(-50%);
  padding: 1px 8px; border-radius: var(--radius-pill);
  background: var(--gold); color: var(--green-950);
  font-size: 10px; font-weight: var(--fw-bold); font-style: normal;
  white-space: nowrap;
}

/* ---- conditions: the same picker the department pages use ---- */
.dx-treats { background: var(--paper); }
.dx-treats h2 { color: var(--green-900); }

@media (max-width: 760px) {
  .dx-head { padding-bottom: var(--sp-6); }
  .dx-portrait { max-width: 132px; height: 132px; }
  /* seven columns will not fit a phone; two rows of four and three do */
  .dxw__days { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .dxw__day b { font-size: var(--fs-xs); }
}
@media (max-width: 400px) {
  .dxw__days { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

/* ===================== doctor page, v3 ===================== */

/* ---- hero: bigger portrait, tighter text ----
   The portrait was small next to five lines of prose, so the buttons fell
   below the fold. The picture is the thing a patient looks for first. */
@media (min-width: 760px) {
  .dx-head__grid { grid-template-columns: 260px minmax(0, 1fr); gap: var(--sp-7); }
}
.dx-portrait { max-width: 260px; height: 260px; }
.dx-portrait span { font-size: 4.4rem; }
.dx-head h1 { font-size: clamp(1.45rem, 2.6vw, 2rem); }
/* narrower measure and a smaller size: this is a standfirst, not body copy */
.dx-intro { max-width: 37.296em; font-size: var(--fs-sm); line-height: 1.75; }

/* ---- credentials: each qualification is a card ----
   A bulleted list of five degrees beside a definition list was accurate and
   completely flat. These ARE the credibility signal on the page. */
.dx-cred { background: var(--bone); }
.dx-degs { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--sp-2); }
@media (min-width: 620px) {
  .dx-degs[data-n="4"], .dx-degs[data-n="5"], .dx-degs[data-n="6"] {
    grid-template-columns: 1fr 1fr;
  }
}
.dx-degs li {
  display: grid; grid-template-columns: auto minmax(0, 1fr); gap: var(--sp-3);
  align-items: center; margin: 0;
  padding: var(--sp-3) var(--sp-4);
  background: var(--paper); border-radius: var(--radius);
  box-shadow: inset 0 0 0 1px var(--line);
  transition: transform var(--dur-fast) var(--ease-out),
              box-shadow var(--dur-fast) var(--ease-out);
}
.dx-degs li:hover { transform: translateY(-2px); box-shadow: inset 0 0 0 1px var(--green-500); }
.dx-degs li::before { content: none; }
.dx-deg__ico {
  display: grid; place-items: center; width: 30px; height: 30px;
  border-radius: 50%; background: var(--green-100); color: var(--green-700);
}
.dx-deg__ico svg { width: 16px; height: 16px; }
.dx-deg__t { font-weight: var(--fw-semi); color: var(--green-900); font-size: var(--fs-sm); }

.dx-facts > div { padding: var(--sp-3) 0; }
.dx-facts > div + div { border-top: 1px solid var(--line); }
.dx-facts dt { display: flex; align-items: center; gap: 6px; }
.dx-fact__ico { display: inline-grid; place-items: center; width: 15px; height: 15px; color: var(--green-600); }
.dx-fact__ico svg { width: 100%; height: 100%; }

/* ---- week strip: alive ---- */
.dxw__live { display: inline-flex; align-items: center; gap: 8px; }
.dxw__live::before {
  content: ""; width: 8px; height: 8px; border-radius: 50%;
  background: currentColor; flex: none;
}
/* a slow pulse only while the doctor is actually in — a badge that always
   pulses stops meaning anything */
.dxw__live.is-in::before { background: var(--paper); animation: dxwPulse 2.4s ease-in-out infinite; }
@keyframes dxwPulse {
  0%, 100% { opacity: 1; transform: scale(1); }
  50% { opacity: .45; transform: scale(.72); }
}
.dxw__day { transition: transform var(--dur-fast) var(--ease-out), box-shadow var(--dur-fast) var(--ease-out); }
.dxw__day.is-on:hover { transform: translateY(-2px); }
.dxw__day.is-today { box-shadow: inset 0 0 0 2px var(--gold), 0 6px 18px rgb(2 26 6 / .1); }

/* ---- the conditions grid divides evenly ----
   Ten chips in three columns left one stranded on a fourth row. The count
   comes from the builder, so the column count can be chosen to fill. */
/* Same reasoning for the condition chips: the widest of them needs 355px, so
   the fixed column counts below only apply once every column is at least that
   wide. The `min()` keeps the track from exceeding the container on a phone. */
/* Same rule for the chips, and for the same reason: each step up in column
   count waits until the columns are wide enough for the labels that go in
   them. The department pages' chips are one or two words and were fine at
   1100; the service pages' are short phrases and were not. */
@media (min-width: 1100px) {
  .dp-syms[data-n="9"], .dp-syms[data-n="6"], .dp-syms[data-n="3"] { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
@media (min-width: 1200px) {
  .dp-syms[data-n="8"], .dp-syms[data-n="4"], .dp-syms[data-n="7"] { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}
@media (min-width: 1320px) {
  .dp-syms[data-n="10"], .dp-syms[data-n="5"] { grid-template-columns: repeat(5, minmax(0, 1fr)); }
}


/* ---- booking: premium ---- */
.dx-book { background: var(--bone); }
.dx-book__grid { gap: var(--sp-6); }
.dx-hours {
  background: var(--green-900);
  background-image: radial-gradient(90% 130% at 88% 0%, rgb(35 158 56 / .22), transparent 62%);
  color: var(--cream);
  padding: var(--sp-4) var(--sp-5); border-radius: var(--radius-lg);
  font-size: var(--fs-md);
}
.dx-tel { color: var(--gold-soft); }
.dx-map {
  display: inline-flex; align-items: center; gap: 6px;
  margin-top: var(--sp-3);
  color: var(--green-700); font-size: var(--fs-sm); font-weight: var(--fw-semi);
}
.dx-map svg { width: 15px; height: 15px; }
/* the three steps, joined by a line so they read as a sequence */
.dx-steps { position: relative; }
.dx-steps li { padding-block: var(--sp-2); }
.dx-steps li::after {
  content: ""; position: absolute; inset-inline-start: 11px;
  width: 2px; background: var(--green-100); z-index: 0;
}
.dx-steps li:not(:last-child)::after { top: 26px; height: calc(100% - 26px); }
.dx-steps li::before { z-index: 1; }

/* ---- colleagues, as cards ---- */
.dx-also {
  background-color: var(--green-900);
  background-image: radial-gradient(90% 130% at 88% 0%, rgb(35 158 56 / .20), transparent 62%);
  color: var(--cream);
}
.dx-also h2 { margin: 0 0 var(--sp-4); font-size: var(--fs-xl); color: var(--paper); }

@media (max-width: 760px) {
  .dx-portrait { max-width: 152px; height: 152px; }
  .dx-portrait span { font-size: 2.8rem; }
  .dx-hours { font-size: var(--fs-sm); }
}
@media (prefers-reduced-motion: reduce) {
  .dx-degs li, .dxw__day { transition: none; }
  .dxw__live.is-in::before { animation: none; }
}

/* ===================== doctor page, v4 ===================== */

/* The standfirst had a narrow measure and a wide empty column beside it.
   Widening it turns four lines into two and uses the space that was there. */
.dx-intro { max-width: 51.948em; }

/* Label and value on one line. Stacked, three facts cost six rows and pushed
   the section taller than the degree cards beside it. */
.dx-facts > div {
  display: grid; grid-template-columns: minmax(0, auto) minmax(0, 1fr);
  gap: var(--sp-3); align-items: baseline;
}
.dx-facts dt { white-space: nowrap; }

/* ---- the colleague cards take a SQUARE portrait ----
   The photographs will be square, like the box in the hero, and a wide band
   would crop a square portrait through the middle of the face.
   
   A square must be a FIXED size, not an aspect ratio: `aspect-ratio: 1/1` on a
   630px-wide card produced a 630px-tall photograph. This is a 168px portrait
   sitting inside the card, so the same square asset drops in unchanged and the
   card stays the height of a card.

   Only from 900px up, where the portrait sits BESIDE the name. Below that the
   card is the same stacked card as everywhere else on the site — photograph
   across the top — so a colleague card and a card on /doctors/ look identical
   on a phone. */
@media (min-width: 900px) {
  .dx-also .dpd:not(.dpd--wide) .dpd__photo {
    width: 168px; height: 168px; aspect-ratio: auto;
    margin: var(--sp-5) var(--sp-5) 0;
    border-radius: var(--radius-lg); border-bottom: 0;
    box-shadow: inset 0 0 0 1px rgb(200 164 92 / .25);
  }
  .dx-also .dpd:not(.dpd--wide) .dpd__photo span { font-size: 3rem; }
}

/* ===================== doctor page, v4 ===================== */

/* ---- the hero portrait runs the full height of the column ----
   It was a fixed 260px square with the text column beside it running past it
   to the buttons, so a wedge of empty green sat under the picture. The slot
   now ends level with the bottom of the action buttons; a portrait photograph
   is taller than it is wide anyway, so this is the shape the real picture
   wants. min-height keeps it sane if a doctor's intro is unusually short. */
@media (min-width: 760px) {
  .dx-head__grid { align-items: stretch; }
  /* max-width too: an earlier max-width:760 rule caps it at 152px, and at
     exactly 760 both queries match — which left a narrow strip inside a
     260px column. */
  .dx-portrait { height: auto; min-height: 240px; max-width: 260px; align-self: stretch; }
}

/* On a phone the portrait is a small square beside the name. It was coming out
   28px wide — the width of the letter — because `width: 100%` inside an `auto`
   grid track has nothing to be a percentage of, and that declaration sits later
   in the file than the 64px one it was meant to replace. */
@media (max-width: 560px) {
  .dx-portrait { width: 64px; min-width: 64px; max-width: none; height: 64px; }
}

/* ---- colleague cards: portrait beside the name, not above it ----
   Stacked, the 168px square pushed every line down and left the whole right
   half of the card empty. Beside the name it fills that gap and the card comes
   down by about a third. The photograph spans the six rows the text needs, so
   the top block reads as one unit and the hours strip and buttons stay full
   width underneath. Phones keep the stacked card — a narrow sideways strip
   read badly there, which is why it was changed back once already. */
@supports (grid-template-rows: subgrid) {
  /* 900px, not 760px. Two cards share the row, so at 760 each is only 355px
     wide and a 168px portrait leaves the text about 150px to live in. Below
     this the stacked card stays. */
  @media (min-width: 900px) {
    /* eight rows, not nine: the portrait no longer owns one of its own */
    .dx-also .dpd-grid:not(.dpd-grid--solo) { grid-template-rows: repeat(8, auto); }
    .dx-also .dpd-grid:not(.dpd-grid--solo) > .dpd:not(.dpd--wide) {
      grid-row: span 8;
      grid-template-columns: 168px minmax(0, 1fr);
      column-gap: var(--sp-5); padding: var(--sp-5);
    }
    /* the body stops being a box so its children join the card's own grid and
       can sit in either column; its padding moves to the card above */
    .dx-also .dpd-grid:not(.dpd-grid--solo) > .dpd:not(.dpd--wide) > .dpd__body {
      display: contents;
    }
    .dx-also .dpd:not(.dpd--wide) .dpd__photo {
      grid-column: 1; grid-row: 1 / 7;
      align-self: start; margin: 0;
    }
    .dx-also .dpd :is(h2, h3), .dx-also .dpd__role,
    .dx-also .dpd__lbl, .dx-also .dpd__val { grid-column: 2; }
    .dx-also .dpd__when, .dx-also .dpd__acts { grid-column: 1 / -1; }
  }
  /* a smaller portrait while the card itself is narrow */
  @media (min-width: 900px) and (max-width: 1199px) {
    .dx-also .dpd-grid:not(.dpd-grid--solo) > .dpd:not(.dpd--wide) {
      grid-template-columns: 124px minmax(0, 1fr); column-gap: var(--sp-4);
    }
    .dx-also .dpd:not(.dpd--wide) .dpd__photo { width: 124px; height: 124px; }
    .dx-also .dpd:not(.dpd--wide) .dpd__photo span { font-size: 2.4rem; }
  }
}


/* ===================== phones, v5 =====================
   Measured on a 412px viewport against the real built pages, not guessed.  */

/* ---- hero ----
   The portrait was a 64px square alone on the first row with the whole right
   half of the row empty beside it, because the body below it spans both
   columns. One column and a portrait worth looking at reads better, and it is
   the box a real photograph has to fit. */
@media (max-width: 560px) {
  /* row-gap: 0 — with display: contents below, every paragraph becomes a grid
     item and the hero's 27px row gap was landing between all of them on top of
     their own margins. Spacing comes from the margins, as before. */
  .dx-head__grid { grid-template-columns: 148px minmax(0, 1fr); align-items: start;
                   column-gap: var(--sp-4); row-gap: 0; }
  /* the body's children join the hero's own grid, so the one short line on the
     page — open now, and the time — can sit in the space beside the portrait
     instead of leaving it blank. Everything else runs full width underneath. */
  .dx-head__body { display: contents; }
  .dx-portrait { width: 148px; min-width: 0; max-width: none; height: 148px;
                 grid-column: 1; grid-row: 1; }
  .dx-portrait span { font-size: 3.2rem; }
  .dx-head .live-now { grid-column: 2; grid-row: 1;
                       align-self: center; justify-self: start; margin: 0; }
  .dx-head h1, .dx-head .dx-role, .dx-head .dx-intro,
  .dx-head__acts { grid-column: 1 / -1; }
  .dx-head h1 { margin: var(--sp-5) 0 var(--sp-2); }
  .dx-head .dx-intro { margin: var(--sp-3) 0 0; }
  .dx-head__acts { margin-top: var(--sp-5); }
}

/* ---- hero buttons, every page ----
   "কল করুন +88 01841-513365" does not fit in half a phone: the button was
   83px tall with the number broken onto a second line. Measured across all 66
   built pages — it happened on both doctor hubs and all twenty department
   pages. One button per row, one line each. */
@media (max-width: 560px) {
  .dx-head__acts, .dr-head__acts, .dp-head__acts, .dp-pick__acts {
    display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--sp-3);
  }
  .dx-head__acts .btn, .dr-head__acts .btn, .dp-head__acts .btn,
  .dp-pick__acts .btn,
  /* the call button in the "no surgeon named" block on two operation pages —
     it was 268px inside a 378px card while every other primary call button on
     a phone runs the full width */
  .op-nodoc .btn {
    width: 100%; flex: none;
  }
}

/* The picker bar's buttons are the same case, and were worse: side by side they
   were 132px wide at 340px, and since a tel: link may not wrap (a broken number
   reads as a wrong number) the label spilled 42px out of the button on both
   sides. Full width, the same label fits at every phone size.

   This one hid from the responsive sweep because the bar only exists after a
   condition is selected — the sweep measures the page as it loads. tests/
   pickfit.js selects one first. */
@media (max-width: 560px) {
  .dp-pick__acts .btn { min-width: 0; justify-content: center; }
}

/* ---- a phone number must never break across two lines ----
   Step 1 of "how to take a serial" was ending a line inside 01639-801019.
   Someone reading it aloud to a relative reads a wrong number. */
.dx-steps a, .dx-steps b, .dx-hours a { white-space: nowrap; }

/* ---- the conditions, two to a row ----
   Ten chips one per row is 580px of mostly empty pill. Two columns halves the
   scroll and the longest label still fits on one line at 412px. */
@media (min-width: 380px) and (max-width: 900px) {
  .dp-syms { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* ---- doctor cards ----
   Fifteen of these make /doctors/ 9,581px long on a phone. The photograph
   stays on top — a sideways card was tried and read badly — but the band comes
   down, and the three buttons go back on one row where they fit. */
@media (max-width: 560px) {
  .dpd:not(.dpd--wide) .dpd__photo { height: 128px; }
  .dpd:not(.dpd--wide) .dpd__photo span { font-size: 2.4rem; }
  .dpd__lbl { margin-top: var(--sp-2); }
}
@media (min-width: 380px) and (max-width: 560px) {
  /* back to the desktop row: profile left, call and WhatsApp right. Measured
     at 412px — the three together come to 344px inside 378px of card. */
  .dpd__acts { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2); }
  .dpd__go { grid-column: auto; margin: 0 auto 0 0; }
  .dpd__act { min-height: 36px; }
}

/* ===================== service pages =====================
   These reuse the department page's hero, selectable list, alert box and visit
   band. Only two things are their own: a calm variant of the alert box, and the
   "why have it here" grid.                                                   */

/* The alert box is red because on a department page it carries first aid. Here
   the same component often carries an explanation — what an ultrasound is —
   which is not an emergency and must not look like one. The red is kept for the
   two pages where the words really are a warning: the cancer-marker caveat and
   the first-aid line on the oxygen page. */
.dp-alert__box--calm {
  background: var(--bone); color: var(--ink);
  box-shadow: inset 0 0 0 1px var(--line);
}
.dp-alert__box--calm h2 { color: var(--green-900); }
.dp-alert__box--calm p { color: var(--muted); }
.dp-alert__box p:last-child { margin-bottom: 0; }

.sv-why {
  background-color: var(--green-900);
  background-image: radial-gradient(90% 130% at 88% 0%, rgb(35 158 56 / .20), transparent 62%);
  color: var(--cream);
}
.sv-why h2 { margin: 0 0 var(--sp-4); font-size: var(--fs-xl); color: var(--paper); }
/* Four across on a wide screen, and the LABELS are kept short enough to fit —
   Billal's call: shorten the words rather than widen the column. The budget is
   243px of text at 1280px, which is what a quarter of the wrap leaves after the
   tick, the gap and the padding. tests/svcfit.js measures it. */
.sv-why__list { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--sp-3); }
@media (min-width: 700px) {
  .sv-why__list { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .sv-why__list[data-n="3"] { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
/* 1300px, not 1000px. Four across only once each column can actually hold the
   longest label on one line: the widest needs 236px of text, so 300px of card,
   so 1251px of container. In a 1000px window four columns give 165px and every
   other label breaks — which is exactly what was happening. Below this it is
   two columns, and four items make a tidy 2x2. */
@media (min-width: 1300px) {
  .sv-why__list[data-n="4"] { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}
/* The tick is a grid column, not an absolutely positioned pseudo-element with
   a hand-tuned `top`. It was sitting about 10px above the text's first line —
   measured: tick centre 22.6px, text centre 33px — because translateY(-50%)
   after a rotate moves the box along the ROTATED axis, diagonally. As a grid
   item it lines up on its own, at any font size, and stays on the first line
   when the label wraps. */
.sv-why__list li {
  margin: 0; padding: var(--sp-4);
  display: grid; grid-template-columns: 11px minmax(0, 1fr);
  align-items: start; gap: var(--sp-3);
  border-radius: var(--radius); background: rgb(242 237 226 / .07);
  box-shadow: inset 0 0 0 1px rgb(242 237 226 / .16);
  font-size: var(--fs-sm); line-height: 1.6;
  transition: box-shadow var(--dur-fast) var(--ease-out),
              transform var(--dur-fast) var(--ease-out);
}
.sv-why__list li:hover {
  transform: translateY(-2px); box-shadow: inset 0 0 0 1px var(--gold);
}
/* the tick is drawn, not a character, so it keeps its weight at any size.
   The margin puts its middle on the middle of the first line. */
.sv-why__list li::before {
  content: ""; width: 9px; height: 5px; border: 2px solid var(--gold);
  border-block-start: 0; border-inline-end: 0;
  margin-top: .62em; transform: rotate(-45deg);
}
.sv-why__note {
  margin: var(--sp-5) 0 0; font-size: var(--fs-xs);
  color: rgb(242 237 226 / .72);
}
@media (prefers-reduced-motion: reduce) { .sv-why__list li { transition: none; } }

/* ===================== operations =====================
   The hub is a grid of twelve; each page reuses the department components plus
   three of its own: the signs list, the surgeon row, and the cost box.        */

.op-all { background: var(--bone); }
.op-all h2 { margin: 0 0 var(--sp-4); font-size: var(--fs-xl); color: var(--green-900); }
.op-grid { display: grid; gap: var(--sp-3); grid-template-columns: minmax(0, 1fr); }
@media (min-width: 620px)  { .op-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 1000px) { .op-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
.op-card {
  display: grid; grid-template-columns: 40px minmax(0, 1fr) 20px;
  align-items: center; gap: var(--sp-3);
  padding: var(--sp-4); text-decoration: none;
  background: var(--paper); border-radius: var(--radius);
  box-shadow: inset 0 0 0 1px var(--line);
  transition: transform var(--dur-fast) var(--ease-out),
              box-shadow var(--dur-fast) var(--ease-out);
}
.op-card:hover {
  transform: translateY(-2px);
  box-shadow: inset 0 0 0 1px var(--green-600), 0 8px 22px rgb(2 26 6 / .08);
}
.op-card__ico {
  grid-row: span 2; display: grid; place-items: center;
  width: 40px; height: 40px; border-radius: 50%;
  background: var(--green-100); color: var(--green-700);
}
.op-card__ico svg { width: 21px; height: 21px; }
.op-card__t { font-weight: var(--fw-semi); color: var(--green-900); line-height: 1.3; }
.op-card__w { grid-column: 2; font-size: var(--fs-xs); color: var(--muted); line-height: 1.4; }
.op-card__go { grid-row: span 2; color: var(--green-600); display: grid; place-items: center; }
.op-card__go svg { width: 18px; height: 18px; transition: transform var(--dur-fast) var(--ease-out); }
.op-card:hover .op-card__go svg { transform: translateX(3px); }

/* signs: a plain list, deliberately. These are things to act on, not chips to
   tap — see the note in build_operations.py. */
.op-signs h2 { margin: 0 0 var(--sp-4); font-size: var(--fs-xl); color: var(--green-900); }
.op-signs__list { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--sp-2); }
@media (min-width: 760px) { .op-signs__list { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.op-signs__list li {
  margin: 0; position: relative;
  padding: var(--sp-3) var(--sp-4) var(--sp-3) var(--sp-6);
  background: var(--bone); border-radius: var(--radius);
  box-shadow: inset 0 0 0 1px var(--line);
  font-size: var(--fs-sm); line-height: 1.6; color: var(--ink);
}
.op-signs__list li::before {
  content: ""; position: absolute; inset-inline-start: var(--sp-4); top: 1.45em;
  width: 7px; height: 7px; border-radius: 50%; background: var(--green-600);
}

.op-docs { background: var(--bone); }
.op-docs h2 { margin: 0 0 var(--sp-4); font-size: var(--fs-xl); color: var(--green-900); }
.op-doc-grid { display: grid; gap: var(--sp-3); grid-template-columns: minmax(0, 1fr); }
@media (min-width: 760px) {
  .op-doc-grid[data-n="2"] { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .op-doc-grid[data-n="3"] { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
.op-doc {
  display: flex; flex-wrap: wrap; align-items: baseline;
  justify-content: space-between; gap: var(--sp-2);
  padding: var(--sp-4); text-decoration: none;
  background: var(--paper); border-radius: var(--radius);
  box-shadow: inset 0 0 0 1px var(--line);
  transition: box-shadow var(--dur-fast) var(--ease-out);
}
.op-doc:hover { box-shadow: inset 0 0 0 1px var(--green-600); }
.op-doc__n { font-weight: var(--fw-semi); color: var(--green-900); }
.op-doc__go {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: var(--fs-xs); color: var(--green-700);
}
.op-doc__go svg { width: 14px; height: 14px; }

/* the honest absence: two operations have no surgeon named in doctors-data.md */
.op-nodoc {
  padding: var(--sp-5); border-radius: var(--radius-lg);
  background: var(--paper); box-shadow: inset 0 0 0 1px var(--line);
}
.op-nodoc h2 { margin: 0 0 var(--sp-2); font-size: var(--fs-lg); color: var(--green-900); }
.op-nodoc p { margin: 0 0 var(--sp-4); color: var(--muted); font-size: var(--fs-sm); }

/* The cost box answers the question the keyword raises. It is deliberately a
   box and not a footnote: "কত খরচ" is why most of these pages get opened, and
   the honest answer deserves to be the thing you cannot miss. */
.op-cost { padding-block: 0; }
.op-cost__box {
  padding: var(--sp-5); border-radius: var(--radius-lg);
  background-color: var(--green-900);
  background-image: radial-gradient(90% 130% at 88% 0%, rgb(35 158 56 / .22), transparent 62%);
  color: var(--cream);
}
.op-cost__box h2 { margin: 0 0 var(--sp-2); font-size: var(--fs-lg); color: var(--paper); }
.op-cost__box p { margin: 0; font-size: var(--fs-sm); line-height: 1.75; }
@media (prefers-reduced-motion: reduce) {
  .op-card, .op-card__go svg, .op-doc { transition: none; }
}

/* ===================== about =====================
   The hub reuses the operations grid for "what you will find here". Its own
   parts are the stat strip, the leadership cards, the history steps and the
   vision box.                                                                */

.ab-stats { padding-block: var(--sp-6); }
.ab-stats__list {
  list-style: none; margin: 0; padding: 0;
  display: grid; gap: var(--sp-3);
  grid-template-columns: repeat(2, minmax(0, 1fr));
}
@media (min-width: 700px) { .ab-stats__list { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
.ab-stats__list li {
  margin: 0; padding: var(--sp-4); text-align: center;
  background: var(--bone); border-radius: var(--radius);
  box-shadow: inset 0 0 0 1px var(--line);
}
.ab-stats__list b {
  display: block; font-size: var(--fs-2xl); line-height: 1.1;
  color: var(--green-800); font-weight: var(--fw-bold);
}
.ab-stats__list span {
  display: block; margin-top: 4px;
  font-size: var(--fs-xs); color: var(--muted);
}

.ab-people {
  background-color: var(--green-900);
  background-image: radial-gradient(90% 130% at 88% 0%, rgb(35 158 56 / .20), transparent 62%);
  color: var(--cream);
}
.ab-people h2 { margin: 0 0 var(--sp-4); font-size: var(--fs-xl); color: var(--paper); }
.ab-people__grid { display: grid; gap: var(--sp-3); grid-template-columns: minmax(0, 1fr); }
@media (min-width: 760px) { .ab-people__grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
.ab-person {
  display: grid; grid-template-columns: minmax(0, 1fr) 18px;
  align-items: center; gap: var(--sp-2);
  padding: var(--sp-4) var(--sp-5); text-decoration: none;
  border-radius: var(--radius); background: rgb(242 237 226 / .07);
  box-shadow: inset 0 0 0 1px rgb(242 237 226 / .16);
  transition: transform var(--dur-fast) var(--ease-out),
              box-shadow var(--dur-fast) var(--ease-out);
}
.ab-person:hover { transform: translateY(-2px); box-shadow: inset 0 0 0 1px var(--gold); }
.ab-person__r {
  font-size: var(--fs-xs); color: var(--gold-soft);
  letter-spacing: var(--track-label); text-transform: uppercase;
}
html[lang="bn"] .ab-person__r { text-transform: none; letter-spacing: normal; }
.ab-person__n {
  grid-column: 1; font-weight: var(--fw-semi); color: var(--paper); line-height: 1.35;
}
.ab-person__go { grid-row: span 2; color: var(--gold-soft); }
.ab-person__go svg { width: 18px; height: 18px; }

/* ---- the history: three steps on the brand band ----
   Each step is a card with a numbered marker, joined by a rail. The rail
   between one step and the next lights only once that step has scrolled into
   view (site.js §17 adds .is-in, the same observer the packages page uses), so
   the timeline draws itself as you read down it. Without JS every step is
   already visible and every connector already lit — the animation is the only
   thing that is lost. */
.ab-story {
  background-color: var(--green-900);
  background-image: radial-gradient(90% 130% at 88% 0%, rgb(35 158 56 / .20), transparent 62%);
  color: var(--cream);
}
.ab-story__list { list-style: none; margin: 0; padding: 0; counter-reset: ab; }
.ab-story__list li {
  position: relative; isolation: isolate; margin: 0 0 var(--sp-3);
  padding: var(--sp-5) var(--sp-5) var(--sp-5) calc(var(--sp-7) + var(--sp-3));
  counter-increment: ab; overflow: hidden;
  border-radius: var(--radius-lg);
  background: rgb(242 237 226 / .07);
  box-shadow: inset 0 0 0 1px rgb(242 237 226 / .16);
  transition: transform var(--dur-fast) var(--ease-out),
              box-shadow var(--dur-fast) var(--ease-out);
}
.ab-story__list li:last-child { margin-bottom: 0; }
/* the light under the pointer, the same one the diagnostics cards use */
.ab-story__list li::before {
  content: ""; position: absolute; inset: 0; z-index: -1; opacity: 0;
  background: radial-gradient(240px circle at var(--mx, 50%) var(--my, 50%),
              rgb(200 164 92 / .26), transparent 70%);
  transition: opacity var(--dur-base) var(--ease-out);
}
.ab-story__list li:hover { transform: translateY(-2px); box-shadow: inset 0 0 0 1px var(--gold); }
.ab-story__list li:hover::before { opacity: 1; }

.ab-story__list :is(h2, h3) {
  position: relative; margin: 0 0 var(--sp-2);
  font-size: var(--fs-lg); color: var(--paper);
}
/* the numbered marker sits in the card's left gutter */
.ab-story__list :is(h2, h3)::before {
  content: counter(ab);
  position: absolute; inset-inline-start: calc(-1 * (var(--sp-7) + 2px)); top: -2px;
  display: grid; place-items: center; width: 34px; height: 34px;
  border-radius: 50%; background: rgb(242 237 226 / .1); color: var(--gold-soft);
  box-shadow: inset 0 0 0 1px rgb(200 164 92 / .34);
  font-size: var(--fs-sm); font-weight: var(--fw-bold);
  transition: background-color var(--dur-base) var(--ease-out),
              color var(--dur-base) var(--ease-out);
}
/* Bangla digits on the Bangla page, the way every other numbered list on the
   site does it — a "2" in a Bangla sentence reads as a typo to this audience */
html[lang="bn"] .ab-story__list :is(h2, h3)::before { content: counter(ab, bengali); }
/* filled once the step has arrived */
.ab-story__list li.is-in :is(h2, h3)::before { background: var(--gold); color: var(--green-950); }
/* the rail to the next step, drawn from the marker down */
.ab-story__list li:not(:last-child)::after {
  content: ""; position: absolute;
  inset-inline-start: calc(var(--sp-5) + 3px);
  top: calc(var(--sp-5) + 34px); bottom: calc(-1 * var(--sp-3));
  width: 2px; background: rgb(242 237 226 / .16);
  transform-origin: top; transform: scaleY(0);
  /* --dur-reveal, the same 300ms the fade-ins use: the rail and the card it
     leads to should finish together */
  transition: transform var(--dur-reveal) var(--ease-out);
}
.ab-story__list li.is-in:not(:last-child)::after { transform: scaleY(1); background: var(--gold-soft); }
.ab-story__list p { margin: 0; color: rgb(242 237 226 / .84); line-height: 1.8; }

@media (max-width: 560px) {
  .ab-story__list li {
    padding: var(--sp-5) var(--sp-4) var(--sp-4) calc(var(--sp-6) + var(--sp-3));
  }
  .ab-story__list :is(h2, h3)::before {
    inset-inline-start: calc(-1 * (var(--sp-6) + 2px)); width: 30px; height: 30px;
  }
  .ab-story__list li:not(:last-child)::after {
    inset-inline-start: calc(var(--sp-4) + 3px); top: calc(var(--sp-5) + 30px);
  }
}
@media (prefers-reduced-motion: reduce) {
  .ab-story__list li, .ab-story__list li::before, .ab-story__list :is(h2, h3)::before { transition: none; }
  .ab-story__list li:hover { transform: none; }
  .ab-story__list li:not(:last-child)::after { transition: none; transform: scaleY(1); }
}

.ab-prio h2 { margin: 0 0 var(--sp-4); font-size: var(--fs-xl); color: var(--green-900); }
/* the priorities reuse the service page's tick list, but on paper rather than
   on the brand band, so the ticks and text need the light-surface colours */
.ab-prio .sv-why__list li {
  background: var(--bone); color: var(--ink);
  box-shadow: inset 0 0 0 1px var(--line);
}
.ab-prio .sv-why__list li:hover { box-shadow: inset 0 0 0 1px var(--green-600); }
.ab-prio .sv-why__list li::before { border-color: var(--green-600); }

.ab-vision { padding-block: 0; }
.ab-vision__box {
  padding: var(--sp-6); border-radius: var(--radius-lg);
  background-color: var(--green-900);
  background-image: radial-gradient(90% 130% at 88% 0%, rgb(35 158 56 / .22), transparent 62%);
  color: var(--cream);
}
.ab-vision__box h2 { margin: 0 0 var(--sp-3); font-size: var(--fs-lg); color: var(--paper); }
.ab-quote, .ab-vision__t {
  /* --font-display, not a serif of its own: on Bangla pages it is Noto Serif
     Bengali and on English pages it falls back to the sans, which is the
     behaviour the tokens file already decided for headings. */
  margin: 0; font-family: var(--font-display);
  font-size: var(--fs-lg); line-height: 1.75; color: var(--paper);
}
.ab-quote { padding-inline-start: var(--sp-4); border-inline-start: 3px solid var(--gold); }
.ab-vision__by {
  margin: var(--sp-4) 0 0; font-size: var(--fs-sm);
  font-weight: var(--fw-semi); color: var(--gold-soft);
}
/* the line that keeps an aspiration an aspiration. build_about.py fails the
   build if it is ever missing. */
.ab-vision__note {
  margin: var(--sp-2) 0 0; font-size: var(--fs-xs); color: rgb(242 237 226 / .72);
}
@media (prefers-reduced-motion: reduce) { .ab-person { transition: none; } }

/* The ambulance number inside the red alert box was inheriting .tel-text's
   green, which is a colour chosen for a light surface: 2.64:1 on the red, well
   under AA, on the one line somebody reads in an emergency. On the red box a
   link is paper with an underline; the calm variant keeps the green. */
.dp-alert__box:not(.dp-alert__box--calm) a,
.dp-alert__box:not(.dp-alert__box--calm) .tel-text {
  color: var(--paper); text-decoration: underline; text-underline-offset: 3px;
  text-decoration-thickness: 1.5px;
}
.dp-alert__box:not(.dp-alert__box--calm) a:hover { text-decoration-thickness: 2.5px; }

/* ---- about: the four kinds of care ----
   The panels ship visible and the tab strip is inert until the script upgrades
   it, so `.is-tabbed` is what switches this from four stacked lists into tabs.
   Without JS the reader loses nothing. */
.ab-care { background: var(--bone); }
.ab-care h2 { margin: 0 0 var(--sp-2); font-size: var(--fs-xl); color: var(--green-900); }
.ab-care .dp-lead { margin: 0 0 var(--sp-5); }
.ab-tabs { display: none; }
.is-tabbed .ab-tabs {
  display: grid; gap: var(--sp-2); margin-bottom: var(--sp-4);
  grid-template-columns: repeat(2, minmax(0, 1fr));
}
@media (min-width: 760px) {
  .ab-care.is-tabbed .ab-tabs { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  /* the Managing Director's page has three aims, not four */
  .md-pillars.is-tabbed .ab-tabs { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
.ab-tab {
  display: grid; gap: 2px; text-align: start;
  padding: var(--sp-3) var(--sp-4);
  background: var(--paper); border: 0; border-radius: var(--radius);
  box-shadow: inset 0 0 0 1px var(--line);
  cursor: pointer; font: inherit; min-height: 44px;
  transition: box-shadow var(--dur-fast) var(--ease-out),
              transform var(--dur-fast) var(--ease-out);
}
.ab-tab:hover { transform: translateY(-1px); box-shadow: inset 0 0 0 1px var(--green-500); }
.ab-tab__t { font-weight: var(--fw-semi); color: var(--green-900); line-height: 1.3; }
.ab-tab__w { font-size: var(--fs-xs); color: var(--muted); }
.ab-tab.is-on {
  background: var(--green-800);
  box-shadow: inset 0 0 0 1px var(--green-800), 0 6px 18px rgb(2 26 6 / .12);
}
.ab-tab.is-on .ab-tab__t { color: var(--paper); }
.ab-tab.is-on .ab-tab__w { color: rgb(242 237 226 / .78); }

.ab-panels { display: grid; gap: var(--sp-3); }
.ab-panel {
  padding: var(--sp-5); background: var(--paper);
  border-radius: var(--radius-lg); box-shadow: inset 0 0 0 1px var(--line);
}
.ab-panel[hidden] { display: none; }
/* the panel heading repeats the tab label, which a sighted reader does not need
   twice — but with no JS it is the only label the list has */
.ab-care.is-tabbed .ab-panel h3 { display: none; }
.ab-panel h3 { margin: 0 0 var(--sp-3); font-size: var(--fs-lg); color: var(--green-900); }
.ab-panel ul {
  list-style: none; margin: 0; padding: 0;
  display: grid; gap: var(--sp-2);
}
@media (min-width: 700px) { .ab-panel ul { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.ab-panel li {
  margin: 0; position: relative; padding-inline-start: var(--sp-5);
  color: var(--ink); line-height: 1.7;
}
.ab-panel li::before {
  content: ""; position: absolute; inset-inline-start: 0; top: .72em;
  width: 8px; height: 8px; border-radius: 50%; background: var(--green-600);
}

/* ---- about: the ten departments ---- */

/* ---- about: the diagnostic catalogue ---- */
@media (min-width: 620px)  { }
@media (min-width: 1000px) { }

/* CT and MRI on site is the one thing on this page a competitor in Cumilla
   probably cannot say, so it gets its own strip rather than a bullet. */

@media (prefers-reduced-motion: reduce) { .ab-tab { transition: none; } }

/* The "see all" pill was designed for the brand band, where gold on dark green
   reads well. On the About page it sits on paper, and gold on paper measured
   1.82:1 — a link nobody with less than perfect sight would find. On a light
   surface it takes the green. */
.ab-depts .dp-alldocs {
  color: var(--green-800);
  background: var(--green-100);
  box-shadow: inset 0 0 0 1px var(--green-500);
}
.ab-depts .dp-alldocs:hover { background: var(--green-800); color: var(--paper); }

/* ---- diagnostics: why have your tests here ----
   Four bullets on paper became four cards on the brand band, each of which
   goes somewhere: the discount card dials the hotline, the others link into
   the site. The pointer light is the same idea as the department grid on the
   home page — it follows the cursor across the card rather than lighting a
   fixed corner, so the block feels alive under the hand without any of it
   moving. Everything degrades: no JS, no light; no hover, no lift. */
.dp-whyband {
  background-color: var(--green-900);
  background-image: radial-gradient(90% 130% at 88% 0%, rgb(35 158 56 / .20), transparent 62%);
  color: var(--cream);
}
.dp-whyband h2 { margin: 0 0 var(--sp-4); font-size: var(--fs-xl); color: var(--paper); }
.dwy-grid { display: grid; gap: var(--sp-3); grid-template-columns: minmax(0, 1fr); }
@media (min-width: 620px)  { .dwy-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 1040px) { .dwy-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); } }

/* Stacked, not side by side. Four across, each card is about 245px wide — not
   enough for an icon column, two lines of text and an arrow on one row, and the
   icon ended up floating in the middle of the left edge with a gap above and
   below it. Icon on top, then the title, then the subtext with the arrow beside
   it: nothing floats, and the card works at any column count. */
.dwy {
  position: relative; isolation: isolate;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-content: start; gap: var(--sp-2) var(--sp-3);
  padding: var(--sp-5);
  border-radius: var(--radius-lg); text-decoration: none;
  background: rgb(242 237 226 / .07);
  box-shadow: inset 0 0 0 1px rgb(242 237 226 / .16);
  overflow: hidden;
  transition: transform var(--dur-fast) var(--ease-out),
              box-shadow var(--dur-fast) var(--ease-out);
}
/* the light: a soft disc that sits where the pointer is, written by site.js
   into --mx / --my. With no script both stay at 50% and the disc is invisible
   because its opacity is 0 until :hover. */
.dwy::before {
  content: ""; position: absolute; inset: 0; z-index: -1; opacity: 0;
  background: radial-gradient(200px circle at var(--mx, 50%) var(--my, 50%),
              rgb(200 164 92 / .3), transparent 70%);
  transition: opacity var(--dur-base) var(--ease-out);
}
.dwy:hover, .dwy:focus-visible {
  transform: translateY(-3px);
  box-shadow: inset 0 0 0 1px var(--gold), 0 12px 28px rgb(2 26 6 / .28);
}
.dwy:hover::before, .dwy:focus-visible::before { opacity: 1; }

.dwy__ico {
  grid-column: 1 / -1; margin-bottom: var(--sp-2);
  display: grid; place-items: center;
  width: 40px; height: 40px; border-radius: 50%;
  background: rgb(242 237 226 / .1); color: var(--gold-soft);
  box-shadow: inset 0 0 0 1px rgb(200 164 92 / .3);
  transition: background-color var(--dur-fast) var(--ease-out),
              color var(--dur-fast) var(--ease-out);
}
.dwy__ico svg { width: 20px; height: 20px; }
.dwy:hover .dwy__ico { background: var(--gold); color: var(--green-950); }
.dwy__t { grid-column: 1 / -1; font-weight: var(--fw-semi); color: var(--paper); line-height: 1.35; }
/* The forced two-line title height is gone. It existed because one of the four
   titles wrapped; that title has been shortened, so every card is now one line
   of title over one line of subtext — and the reserved second line was showing
   as a gap between the icon and the words. */

.dwy__w { grid-column: 1; font-size: var(--fs-xs); color: rgb(242 237 226 / .78); line-height: 1.5; }
/* the arrow sits with the last line of the subtext, not floating beside the lot */
.dwy__go { grid-column: 2; align-self: end; color: var(--gold-soft); }
.dwy__go svg { width: 18px; height: 18px; transition: transform var(--dur-fast) var(--ease-out); }
.dwy:hover .dwy__go svg { transform: translateX(3px); }

/* a phone has no pointer to follow and less room, so: no light, tighter box */
@media (max-width: 560px) {
  .dwy { padding: var(--sp-4); }
  .dwy::before { content: none; }
  .dwy__t { font-size: var(--fs-sm); }
  .dwy__ico { margin-bottom: 2px; }
}
@media (prefers-reduced-motion: reduce) {
  .dwy, .dwy::before, .dwy__ico, .dwy__go svg { transition: none; }
  .dwy:hover { transform: none; }
}

/* ---- credentials: the workplace line on one line ----
   "অধ্যাপক, মেডিসিন বিভাগ — শহীদ সোহরাওয়ার্দী মেডিকেল কলেজ ও হাসপাতাল, ঢাকা"
   needs 541px. In a half-width column it had 429–537px, so it wrapped. Two
   changes, both measured:

   * the facts column takes the larger share of the row (0.85 / 1.15), because
     the degrees beside it are short cards and the facts are sentences;
   * and the row only splits into two columns from 1200px, where that share
     comes to 575px. Below 1200 the facts sit under the degrees at full width,
     which is far more than the line needs.                                   */
@media (min-width: 860px) and (max-width: 1199.98px) {
  .dx-cred__grid { grid-template-columns: minmax(0, 1fr); gap: var(--sp-6); }
  /* the degree cards are two or three words each; across a full-width row the
     two-column grid stretched "এমবিবিএস" to 980px. auto-fit packs as many
     200px cards as fit, whatever number of degrees a doctor has. */
  .dx-degs, .dx-degs[data-n="4"], .dx-degs[data-n="5"], .dx-degs[data-n="6"] {
    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  }
}
@media (min-width: 1200px) {
  .dx-cred__grid { grid-template-columns: minmax(0, 0.85fr) minmax(0, 1.15fr); }
}

/* ---- credentials: the three fact rows read as one set ----
   The department value was the only one at weight 600 in link green, which
   made it look a size larger than পদবি and কর্মস্থল above it. Same size
   (16.2px) all along — it was the weight and the colour doing it. It stays a
   link, so it keeps the green and gains an underline rather than the extra
   weight: still obviously clickable, no longer shouting. */
.dx-facts dd a {
  font-weight: var(--fw-normal);
  text-decoration: underline;
  text-decoration-color: rgb(6 95 21 / .35);
  text-underline-offset: 4px;
}
.dx-facts dd a:hover { text-decoration-color: currentColor; }
/* and a rule under the last row, so the set closes the way it opens */
.dx-facts > div:last-child { border-bottom: 1px solid var(--line); }

/* ---- condition chips: every box the same size ----
   The <li> stretched to the row height but the button inside it did not, so in
   a row where one label wrapped to two lines the other chip sat 21px shorter
   with a gap under it. Measured at 412px: li heights [71, 71], button heights
   [71, 50].

   The button now fills its cell, and on the two-column phone layout every row
   takes the height of the tallest chip, so the block reads as a grid rather
   than as ten boxes of assorted sizes. */
.dp-syms li { display: grid; }
.dp-sym { height: 100%; }
@media (min-width: 380px) and (max-width: 900px) {
  .dp-syms { grid-auto-rows: 1fr; }
}

/* ---- fact rows on a phone: the value drops below the label when it has to ----
   "ALSO WORKS AT" is a wide label. Beside it on a 412px screen the workplace
   had 188px to live in and came out five lines tall against a 190px label —
   a thin column of text next to a lot of nothing.

   Every row stacks, not only the long one. Mixing the two — some values beside
   their label, some under it — left the column with a ragged left edge; with
   all three under their labels the values line up on one margin and each gets
   the full width. */
@media (max-width: 700px) {
  .dx-facts > div {
    display: flex; flex-wrap: wrap; align-items: baseline;
    column-gap: var(--sp-3); row-gap: 4px;
  }
  .dx-facts dd { flex: 1 1 100%; }
}

/* "What you will find here" moves onto the brand band. It is the six doors out
   of this page, so it should read as the page's own strip rather than as more
   paper. The cards inside were built for a light surface, so they take the
   band's colours here. */
.op-all.op-all--brand {
  background-color: var(--green-900);
  background-image: radial-gradient(90% 130% at 88% 0%, rgb(35 158 56 / .20), transparent 62%);
}
.op-all--brand h2 { color: var(--paper); }
.op-all--brand .op-card {
  background: rgb(242 237 226 / .07);
  box-shadow: inset 0 0 0 1px rgb(242 237 226 / .16);
}
.op-all--brand .op-card:hover {
  box-shadow: inset 0 0 0 1px var(--gold), 0 10px 26px rgb(2 26 6 / .26);
}
.op-all--brand .op-card__ico {
  background: rgb(242 237 226 / .1); color: var(--gold-soft);
  box-shadow: inset 0 0 0 1px rgb(200 164 92 / .3);
}
.op-all--brand .op-card:hover .op-card__ico { background: var(--gold); color: var(--green-950); }
.op-all--brand .op-card__t { color: var(--paper); }
.op-all--brand .op-card__w { color: rgb(242 237 226 / .78); }
.op-all--brand .op-card__go { color: var(--gold-soft); }

/* Two brand bands now sit one under the other — the doors strip and the people
   strip. Without a seam they read as one very tall green block, so the lower
   one takes a hairline across its top. */
.op-all--brand + .ab-people { box-shadow: inset 0 1px 0 rgb(242 237 226 / .14); }

/* ---- the map meets the footer, wherever the map sits ----
   home.css has `.map-section + .site-footer { margin-top: 0 }`, which works on
   the home page because there the map is the footer's own previous sibling. On
   /about/ the map is the last section INSIDE <main>, so the footer's previous
   sibling is the page wrapper and the rule never matched — leaving the
   footer's 36px top margin as a white band under the map.

   Cancelling it from the map's side works in every browser the audience has;
   :has() on the wrapper would have been tidier but is not safe on the older
   Android WebViews this site is built for. */
main > .map-section:last-child { margin-bottom: calc(-1 * var(--sp-6)); }

/* ---- the leadership strip goes back to paper ----
   Two brand bands stacked read as one block, and this one is a set of three
   quiet links rather than a call to action. The cards keep their shape and
   take the light-surface colours. */
.ab-people {
  background-color: var(--bone);
  background-image: none;
  color: var(--ink);
  box-shadow: none;
}
.ab-people h2 { color: var(--green-900); }
.ab-person {
  background: var(--paper);
  box-shadow: inset 0 0 0 1px var(--line);
}
.ab-person:hover {
  box-shadow: inset 0 0 0 1px var(--green-600), 0 8px 22px rgb(2 26 6 / .08);
}
.ab-person__r { color: var(--green-700); }
.ab-person__n { color: var(--green-900); }
.ab-person__go { color: var(--green-600); }

/* ---- the leaders' priorities ----
   Five statements, so there is nowhere for them to link to — the interaction
   here is presentational and honest about that: no arrow, no pointer cursor.
   Each card carries its own icon, fades in on its own beat as the list scrolls
   past, and lights under the pointer like the diagnostics cards. */
.ab-prio__list {
  list-style: none; margin: 0; padding: 0;
  display: grid; gap: var(--sp-3); grid-template-columns: minmax(0, 1fr);
}
@media (min-width: 700px) {
  .ab-prio__list { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  /* an odd count leaves the last card alone on its row; let it span so the
     block ends on a full line instead of a stub */
  .ab-prio__list[data-n="5"] > li:last-child,
  .ab-prio__list[data-n="3"] > li:last-child { grid-column: 1 / -1; }
}
.ab-prio__i {
  position: relative; isolation: isolate; overflow: hidden;
  display: grid; grid-template-columns: 38px minmax(0, 1fr);
  align-items: center; gap: var(--sp-3);
  margin: 0; padding: var(--sp-4);
  border-radius: var(--radius-lg); background: var(--bone);
  box-shadow: inset 0 0 0 1px var(--line);
  transition: transform var(--dur-fast) var(--ease-out),
              box-shadow var(--dur-fast) var(--ease-out);
}
.ab-prio__i::before {
  content: ""; position: absolute; inset: 0; z-index: -1; opacity: 0;
  background: radial-gradient(220px circle at var(--mx, 50%) var(--my, 50%),
              rgb(35 158 56 / .14), transparent 70%);
  transition: opacity var(--dur-base) var(--ease-out);
}
.ab-prio__i:hover { transform: translateY(-2px); box-shadow: inset 0 0 0 1px var(--green-500); }
.ab-prio__i:hover::before { opacity: 1; }
.ab-prio__ico {
  display: grid; place-items: center; width: 38px; height: 38px;
  border-radius: 50%; background: var(--green-100); color: var(--green-700);
  transition: background-color var(--dur-fast) var(--ease-out),
              color var(--dur-fast) var(--ease-out);
}
.ab-prio__ico svg { width: 20px; height: 20px; }
.ab-prio__i:hover .ab-prio__ico { background: var(--green-700); color: var(--paper); }
.ab-prio__t { color: var(--ink); line-height: 1.5; }
@media (prefers-reduced-motion: reduce) {
  .ab-prio__i, .ab-prio__i::before, .ab-prio__ico { transition: none; }
  .ab-prio__i:hover { transform: none; }
}

/* The vision is set large because it is a pull-quote. On a 340px screen that
   size gives about four words a line and the box ran to 436px in English, so
   it steps down — still clearly the biggest thing in the section, just not
   fighting the screen for it. */
@media (max-width: 560px) {
  .ab-vision__box { padding: var(--sp-5) var(--sp-4); }
  .ab-quote, .ab-vision__t { font-size: var(--fs-md); line-height: 1.7; }
  .ab-quote { padding-inline-start: var(--sp-3); }
}

/* ===================== the Managing Director's letter =====================
   He sent a full message in his own words, so this page is set as a letter
   rather than as the generic card blocks: a narrow measure for the prose, his
   three aims as cards, and a signed close. The framing words he wrote — "we
   aim to build", "is working towards building", "our goal is to establish" —
   stay attached to their lists; build_about.py refuses to build without them. */
.md-letter { background: var(--bone); }

.md-letter h2 { margin: 0 0 var(--sp-4); font-size: var(--fs-xl); color: var(--green-900); }
.md-letter__salut {
  margin: 0 0 var(--sp-3); font-family: var(--font-display);
  font-size: var(--fs-lg); color: var(--green-800);
}
/* order matters: the reset first, the spacing after it, or the later rule
   wins and the paragraphs run together */
.md-letter__wrap > p:not(.md-letter__salut) {
  margin: 0; color: var(--ink); line-height: 1.85;
}
/* the :not() above counts for specificity, so the spacing rule has to carry
   it too or it loses regardless of order */
.md-letter__wrap > p + p:not(.md-letter__salut) { margin-top: var(--sp-4); }

.md-pillars h2 { margin: 0 0 var(--sp-4); font-size: var(--fs-xl); color: var(--green-900); }
/* the old three-across card block was replaced by the tab strip above;
   its rules are gone rather than left behind to rot. */
.md-commit { padding-block: 0 var(--sp-7); }
.md-commit__box {
  padding: var(--sp-6); border-radius: var(--radius-lg);
  background-color: var(--green-900);
  background-image: radial-gradient(90% 130% at 88% 0%, rgb(35 158 56 / .22), transparent 62%);
  color: var(--cream);
}
.md-commit__box h2 { margin: 0 0 var(--sp-3); font-size: var(--fs-lg); color: var(--paper); }
/* Set as a quotation, because that is what it is — his words, lifted out of
   the letter. Body font at regular weight, not the display face: on a Bangla
   page --font-display is Noto Serif Bengali and the only weight self-hosted for
   it is 700, so asking it for this paragraph is asking for bold. */
.md-commit__t {
  margin: 0; padding-inline-start: var(--sp-4);
  border-inline-start: 3px solid var(--gold);
  font-family: var(--font-body); font-weight: var(--fw-normal);
  font-size: var(--fs-lg); line-height: 1.8; color: var(--paper);
}
.md-commit__thanks { margin: var(--sp-4) 0 0; font-size: var(--fs-sm); color: rgb(242 237 226 / .84); }

@media (max-width: 560px) {
  .md-commit__box { padding: var(--sp-5) var(--sp-4); }
  .md-commit__t { font-size: var(--fs-md); line-height: 1.75; padding-inline-start: var(--sp-3); }
}
@media (prefers-reduced-motion: reduce) {
}

/* ---- the letter, left aligned ----
   .wrap centres its content; a letter should start where every other section
   on the page starts, so the narrow measure is kept but the centring is not. */
/* The wrapper is a normal centred .wrap, so the letter starts on the same left
   edge as every other section, and the prose runs the full width of it. The
   70ch measure was leaving a third of the row empty and making the section
   taller than it needed to be; Billal asked for the width back, and at this
   size the letter is three short paragraphs rather than an essay. */

/* the sign-off. There is no script font on this site — only Instrument Sans and
   the two Noto Bengali faces are self-hosted, and CLAUDE.md rules out loading
   one from a CDN. So the signature is the display serif, italic and larger,
   which reads as a hand-set sign-off in both scripts. A real scanned signature
   would be better and can drop in here as an <img> when the client sends one. */
/* Signature, then the rule, then the printed name — the order a signed letter
   uses: you sign ABOVE the line and your name is printed under it. */
.md-sign { display: grid; gap: 2px; margin: var(--sp-7) 0 0; }
/* The hand: how he would sign, above the printed name — the way a letter is
   signed. It is aria-hidden, so the printed name below is what a screen reader
   announces and nothing is lost on a device without the face.

   "Brittany Signature" is first in the stack, as asked. It is a commercial font
   and no file for it is in this repo, so until one is licensed and dropped into
   assets/fonts/ (see the @font-face stub in base.css) the browser falls through
   to whatever handwriting face the device has, and then to generic cursive. The
   line therefore looks right today and looks exactly right the moment the font
   lands — nothing else has to change. */
.md-sign__mark {
  margin: 0 0 2px;
  font-family: "Brittany Signature", "Segoe Script", "Bradley Hand",
               "Brush Script MT", "Snell Roundhand", cursive;
  font-size: clamp(1.35rem, 3.4vw, 2.05rem); line-height: 1.15;
  color: var(--green-700);
  /* a signature is one stroke, not two lines — it only wraps if a very narrow
     phone leaves it no choice */
  white-space: nowrap;
}
@media (max-width: 400px) { .md-sign__mark { white-space: normal; } }
.md-sign__name {
  /* the rule is this element's own top border, so it is exactly as wide as the
     printed name — fit-content stops a grid item from filling the row */
  width: fit-content; max-width: 100%;
  margin: 0; padding-top: var(--sp-2);
  /* --line is the hairline used for card edges and is nearly invisible on its
     own; a signature rule is meant to be seen. This is the green at a low
     alpha, so it reads as part of the brand rather than as a grey divider. */
  border-top: 1.5px solid rgb(6 95 21 / .38);
  font-weight: var(--fw-bold); font-size: var(--fs-md);
  color: var(--green-900);
}
.md-sign__role { margin: 2px 0 0; font-size: var(--fs-xs); color: var(--muted); }

/* ---- the three aims, as tabs ---- */
.md-pillars { background: var(--bone); }
.md-pillars h2 { margin: 0 0 var(--sp-4); font-size: var(--fs-xl); color: var(--green-900); }
/* the tab strip gets its icon column here; the /about/ tabs have no icons */
.md-pillars .ab-tab { grid-template-columns: 34px minmax(0, 1fr); align-items: center; }
.ab-tab__ico {
  grid-row: span 2; display: grid; place-items: center;
  width: 34px; height: 34px; border-radius: 50%;
  background: var(--green-100); color: var(--green-700);
  transition: background-color var(--dur-fast) var(--ease-out),
              color var(--dur-fast) var(--ease-out);
}
.ab-tab__ico svg { width: 18px; height: 18px; }
.md-pillars .ab-tab__t, .md-pillars .ab-tab__w { grid-column: 2; }
.md-pillars .ab-tab.is-on .ab-tab__ico { background: var(--gold); color: var(--green-950); }

/* the open panel has room to breathe — that was the whole complaint */
.md-panel { padding: var(--sp-6); }
.md-panel h3 { display: block; margin: 0 0 var(--sp-2); font-size: var(--fs-xl); color: var(--green-900); }
.md-pillars.is-tabbed .md-panel h3 { display: block; }
.md-panel__lead {
  margin: 0 0 var(--sp-5); max-width: 41.292em;
  color: var(--muted); font-size: var(--fs-md); line-height: 1.7;
}
.md-panel ul { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--sp-3); }
@media (min-width: 760px) { .md-panel ul { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.md-panel li {
  margin: 0; position: relative; padding: var(--sp-3) var(--sp-4) var(--sp-3) var(--sp-6);
  border-radius: var(--radius); background: var(--bone);
  box-shadow: inset 0 0 0 1px var(--line);
  color: var(--ink); line-height: 1.55;
}
.md-panel li::before {
  content: ""; position: absolute; inset-inline-start: var(--sp-4); top: 1.35em;
  width: 9px; height: 5px; border: 2px solid var(--green-600);
  border-block-start: 0; border-inline-end: 0;
  transform: rotate(-45deg) translateY(-50%);
}
@media (max-width: 560px) {
  .md-panel { padding: var(--sp-4); }
  .md-panel h3 { font-size: var(--fs-lg); }
  .md-panel__lead { font-size: var(--fs-sm); margin-bottom: var(--sp-4); }
}

/* ---- the three aims on a phone ----
   Three tabs in a two-column strip left one stranded on a row of its own, and
   the odd one out sized differently from the pair above it (measured: 95px
   beside 140px). One column stacks them evenly, keeps the blurb, and gives
   each a full-width target. */
@media (max-width: 620px) {
  .md-pillars.is-tabbed .ab-tabs { grid-template-columns: minmax(0, 1fr); }
  .md-pillars .ab-tab { min-height: 56px; padding: var(--sp-3) var(--sp-4); }
}
/* where two or more do sit side by side, they take the tallest one's height */
.is-tabbed .ab-tabs { grid-auto-rows: 1fr; }

/* ============================================================================
   404 — the page Apache serves for any URL that does not exist.

   It gets the real header, bottom bar and footer, so all this layer has to do
   is the panel in the middle. Everything here is a token; nothing is a new
   colour, because a 404 that looks like a different site reads as an error in
   the site rather than an error in the link.
   ========================================================================= */
.nf {
  padding-block: clamp(var(--sp-7), 9vw, var(--sp-8));
  display: grid;
  gap: var(--sp-7);
}

.nf__inner { max-width: 41.292em; }

.nf__code {
  font-family: var(--font-display);
  font-size: clamp(3.4rem, 13vw, 6rem);
  font-weight: var(--fw-bold);
  line-height: 1;
  letter-spacing: -.02em;
  /* Wanted as a watermark, but --green-100 measured 1.12:1 on white and a
     visible text run has to clear 3:1 even when it is decorative — the numeral
     is the one thing on the page a hurried reader looks for. --green-500 is
     3.49:1 and is exactly what that token is documented for: large display
     text and rules, never body copy. At 3.4rem+ this is large text. */
  color: var(--green-500);
  margin: 0 0 var(--sp-2);
}

.nf__h1 {
  font-size: clamp(var(--fs-xl), 5.2vw, var(--fs-2xl));
  margin: 0 0 var(--sp-3);
}

.nf__lede {
  font-size: var(--fs-md);
  line-height: 1.75;
  color: var(--muted);
  margin: 0 0 var(--sp-5);
}

.nf__acts {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-3);
  margin-bottom: var(--sp-4);
}

.nf__amb {
  margin: 0;
  font-size: var(--fs-sm);
  color: var(--muted);
}

.nf__amb a {
  font-weight: var(--fw-bold);
  color: var(--green-700);
  /* the inline-link tap target rule elsewhere gives this its 24px box */
}

.nf__grid {
  display: grid;
  /* six cards, so 3 x 2 on a desktop rather than a thin single row — auto-fit
     put five in a row at 1440 and left one stranded underneath */
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--sp-4);
  max-width: var(--wrap-narrow);
}

@media (max-width: 900px) { .nf__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 560px) { .nf__grid { grid-template-columns: minmax(0, 1fr); } }

.nf__card {
  display: grid;
  align-content: start;
  gap: 4px;
  padding: var(--sp-4) var(--sp-5);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background: var(--paper);
  text-decoration: none;
  color: inherit;
  transition: border-color var(--dur-fast) var(--ease-out),
              transform var(--dur-fast) var(--ease-out);
}

.nf__card:hover,
.nf__card:focus-visible {
  border-color: var(--green-700);
  transform: translateY(-2px);
}

.nf__card-t {
  font-weight: var(--fw-bold);
  font-size: var(--fs-md);
  color: var(--green-700);
}

.nf__card-s {
  font-size: var(--fs-sm);
  color: var(--muted);
  line-height: 1.55;
}

@media (max-width: 560px) {
  /* same rule the hero and picker bars follow: on a phone a call button that
     is not full width is a call button somebody misses */
  .nf__acts { display: grid; grid-template-columns: minmax(0, 1fr); }
  .nf__acts .btn { width: 100%; }
}

@media (prefers-reduced-motion: reduce) {
  .nf__card { transition: none; }
  .nf__card:hover, .nf__card:focus-visible { transform: none; }
}
