/* =============================================================
   Aegis 意承咨询 — design system v4
   Visual language modelled on the reference site the client gave
   us: deep clinical blue + one teal action colour, large soft
   cards, glass panels over a gradient hero, pill buttons, numbered
   gradient step badges, navy footer. Sans at heavy weights for
   display; monospace only for figures, so a price never looks
   like prose. The hero carries an abstract architectural image
   under the navy→teal overlay — no people, no facility we claim.
   ============================================================= */

:root {
  /* ---- palette v5: the named tokens are the single source of truth. The older short names
     (--blue, --navy, --teal, --ink-*, --line*, --sh-*, --r*) stay as aliases so the ~700 rules below
     keep working; a colour change is now one edit, not a search-and-replace.
     The three derived steps are marked: same hue as a named token, only lightness moved, because
     hover states and small text need a second stop that contrast rules can see. ---- */
  --color-primary: #0A2540;
  --color-accent: #00A3A1;
  --color-bg: #FFFFFF;
  --color-bg-alt: #F5F7FA;
  --color-text: #1A1A2E;
  --color-text-muted: #6B7280;
  --color-border: rgba(0, 0, 0, .06);
  --shadow-sm: 0 1px 3px rgba(0, 0, 0, .04);
  --shadow-md: 0 4px 12px rgba(0, 0, 0, .06);
  --radius: 12px;
  /* derived: darker stop of --color-accent for hover, and a stronger stop of --color-border */
  --color-accent-d: #00807E;
  --color-border-2: rgba(0, 0, 0, .14);
  --color-accent-50: #e6f7f7;
  /* two literal values from the client's spec, named rather than repeated in rules */
  --color-wall: #F4F9FF;
  --color-border-plate: #EEF2F7;

  --blue: var(--color-primary);
  --blue-d: var(--color-primary);
  --navy: var(--color-primary);
  --teal: var(--color-accent);
  --teal-d: var(--color-accent-d);
  --teal-50: var(--color-accent-50);
  --ink: var(--color-text);
  --ink-2: var(--color-text-muted);
  --ink-3: var(--color-text-muted);
  --bg: var(--color-bg-alt);
  --surface: var(--color-bg);
  --surface-2: var(--color-bg-alt);
  --line: var(--color-border);
  --line-2: var(--color-border-2);
  --ok: #0d7a5f;
  --ok-bg: #e7f6f0;
  --warn: #b5761b;
  --warn-bg: #fdf3e3;
  --stop: #a4373a;
  --stop-bg: #fdecec;
  --brass: #a8761f;
  --brass-bg: #fbf3e4;
  --r: var(--radius);
  --r-sm: 10px;
  --r-lg: var(--radius);
  --pill: 28px;
  --max: 1280px;
  --gutter: 28px;
  --sh: var(--shadow-md);
  --sh-2: var(--shadow-md);
  --sh-3: var(--shadow-sm);
  /* A CJK serif listed in the sans stack makes Chinese body text fall back to a brush face on
     Windows, so the two stacks carry their own CJK faces: YaHei for reading, Songti for display. */
  --sans: "Inter", -apple-system, "Segoe UI", "Microsoft YaHei", "PingFang SC", "Hiragino Sans GB", sans-serif;
  --serif: "Newsreader", Georgia, "Times New Roman", "Songti SC", SimSun, serif;
  --mono: "IBM Plex Mono", ui-monospace, "SFMono-Regular", Consolas, monospace;

  /* legacy aliases, still referenced by older markup */
  --brand: var(--blue); --brand-50: var(--surface-2); --brand-100: #d8e8f5;
  --brand-700: var(--blue-d); --brand-900: var(--navy); --brand-2: var(--blue); --brand-3: var(--teal);
  --brand-ghost: rgba(255, 255, 255, .08); --accent: var(--teal); --accent-bg: var(--teal-50);
  --paper: var(--bg); --paper-2: var(--surface-2); --card: var(--surface);
  --rule: var(--line); --rule-2: var(--line-2); --green: var(--ok); --amber: var(--warn);
  --amber-soft: var(--warn-bg); --brass-soft: var(--brass-bg); --brass-2: var(--brass);
  --red: var(--stop); --red-soft: var(--stop-bg); --teal-soft: var(--teal-50); --teal-2: var(--teal);
  --stop-bg: #fdecec;
}

* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; scroll-padding-top: 92px; }
body {
  margin: 0; background: var(--surface); color: var(--ink);
  font-family: var(--sans); font-weight: 400; letter-spacing: -.1px;
  /* clamp() is not accepted inside the `font:` shorthand — the whole declaration is dropped as
     invalid, which silently returned the page to the 16px UA default. Longhands only. */
  font-size: clamp(.9rem, 1.5vw, 1.05rem); line-height: 1.65;
  -webkit-font-smoothing: antialiased;
}
h1, h2, h3, h4 { margin: 0; line-height: 1.22; letter-spacing: -.6px; font-weight: 800; color: var(--navy); }
h1 { font-size: clamp(2rem, 5vw, 3.5rem); line-height: 1.1; letter-spacing: -1.4px; font-weight: 900; }
h2 { font-size: clamp(1.5rem, 3vw, 2rem); letter-spacing: -.5px; }
h3 { font-size: clamp(1rem, 1.5vw, 1.15rem); letter-spacing: -.2px; }
h4 { font-size: .96rem; }
p { margin: 0 0 1.5em; }
/* The 680px measure is applied where a paragraph can actually run the width of the page; inside cards
   and centred section heads the parent is already narrower, and a max-width there would pull a centred
   block to the left. */
@media (min-width: 769px) {
  .prose p, .faq-body p, .step-lede, .cell > p:not(.meta):not(.subhead):not(.hint) { max-width: 680px; }
  .sec-head p:not(.eyebrow) { max-width: 680px; margin-left: auto; margin-right: auto; }
}
a { color: var(--blue); text-decoration: none; }
a:hover { color: var(--teal-d); }
ul, ol { margin: 0 0 1em; padding-left: 20px; }
li { margin: 0 0 .4em; }
b, strong { font-weight: 700; color: var(--navy); }
small { font-size: .82rem; }
svg { display: block; }
:focus-visible { outline: 3px solid rgba(15, 163, 163, .5); outline-offset: 2px; border-radius: 4px; }

.wrap { max-width: var(--max); margin: 0 auto; padding: 0 var(--gutter); position: relative; }
.skip { position: absolute; left: -9999px; }
.skip:focus { position: static; left: 0; }
.mono, .num { font-family: var(--mono); font-variant-numeric: tabular-nums; }
.hint { font-size: .8rem; color: var(--ink-3); line-height: 1.55; }
.note { font-size: .84rem; color: var(--ink-3); line-height: 1.65; margin-top: 14px; }
/* The estimate caveat used to be an amber note stuck to the left edge — the least serious-looking
   surface on a page whose whole argument is seriousness. It is a white card now, on the same hairline
   and shadow every other card sits on, and it is the same tokens those cards use rather than new hex. */
.caveat { margin: 10px 0 0; padding: 24px; background: var(--color-bg); border: 1px solid var(--color-border);
  border-radius: 12px; box-shadow: 0 4px 12px rgba(10, 37, 64, .03); font-size: .87rem; color: var(--ink-2); }
.eyebrow, .kicker { font: 700 .74rem/1.4 var(--sans); letter-spacing: .14em; text-transform: uppercase; color: var(--teal-d); margin: 0 0 12px; }
.eyebrow::before { content: ""; display: inline-block; width: 22px; height: 2px; background: var(--teal); vertical-align: middle; margin-right: 10px; }
.kicker { color: rgba(255, 255, 255, .72); }
.lede { font-size: clamp(1.02rem, 1.5vw, 1.18rem); line-height: 1.62; color: var(--ink-2); max-width: 62ch; }
/* Page heads put the standfirst straight under an h1, which carries no bottom margin of its own. */
h1 + .lede { margin-top: 16px; }
.meta { font: 700 .7rem/1.4 var(--sans); letter-spacing: .1em; text-transform: uppercase; color: var(--ink-3); }
.subhead { font: 700 .74rem/1.4 var(--sans); letter-spacing: .1em; text-transform: uppercase; color: var(--blue-d); margin: 18px 0 8px; }
.detail { font-size: .88rem; color: var(--ink-2); }
.count { font: 800 .8rem/1 var(--mono); color: var(--teal-d); background: var(--teal-50); border-radius: 999px; padding: 4px 9px; }
.tag { display: inline-block; font: 800 .66rem/1 var(--sans); letter-spacing: .1em; text-transform: uppercase; color: var(--blue-d); background: var(--surface-2); border: 1px solid var(--line); border-radius: 999px; padding: 7px 11px; }
.tag.live { color: var(--ok); background: var(--ok-bg); border-color: #c6e8da; }
.band { padding: 96px 0; position: relative; }
.band.alt { background: var(--bg); }
.section { padding: 96px 0; position: relative; }
.sec-head { max-width: 74ch; margin: 0 auto 44px; text-align: center; }
.sec-head h2 { margin: 0 auto 14px; font-size: clamp(1.6rem, 3.2vw, 2.15rem); max-width: 26ch; }
.sec-head p:not(.eyebrow) { margin: 0 auto; max-width: 68ch; font-size: 1.02rem; color: var(--ink-2); }
.sec-head > .eyebrow { text-align: center; }
.sec-head > .eyebrow::before { display: none; }

/* ---------------- badges, grades, marks ---------------- */
.badge { display: inline-flex; align-items: center; gap: 6px; width: fit-content; font: 800 .68rem/1.25 var(--sans); letter-spacing: .07em; text-transform: uppercase; color: var(--ok); background: var(--ok-bg); border: 1px solid #c6e8da; border-radius: 999px; padding: 7px 12px; }
.badge.brass { color: var(--brass); background: var(--brass-bg); border-color: #ecd9b4; }
.grade { display: inline-block; font: 800 .64rem/1 var(--mono); letter-spacing: .06em; text-transform: uppercase; padding: 5px 8px; border-radius: 6px; vertical-align: middle; }
.grade.high { color: var(--ok); background: var(--ok-bg); }
.grade.medium { color: var(--blue-d); background: var(--surface-2); }
.grade.low { color: var(--brass); background: var(--brass-bg); }
.grade.gap { color: var(--ink-3); background: #eef2f6; }
.money { font-family: var(--mono); font-variant-numeric: tabular-nums; color: var(--navy); white-space: nowrap; }
.pending-quote { font: italic 400 .82rem/1.5 var(--mono); color: var(--ink-3); }
.srcline { display: block; margin-top: 6px; font: 400 .7rem/1.45 var(--mono); color: var(--ink-3); }
.srcline a { color: var(--ink-3); text-decoration: underline; }
.driver-tag { display: inline-block; margin: 0 0 10px; font: 800 .66rem/1 var(--sans); letter-spacing: .1em; text-transform: uppercase; color: var(--teal-d); background: var(--teal-50); border-radius: 999px; padding: 6px 10px; }

/* ---------------- buttons ---------------- */
.btn { display: inline-flex; align-items: center; justify-content: center; gap: 8px; background: var(--teal); color: #fff; font: 700 .95rem/1 var(--sans); letter-spacing: .2px; padding: 15px 28px; border: 0; border-radius: var(--pill); cursor: pointer; transition: .22s ease; text-align: center; }
.btn:hover { background: var(--teal-d); color: #fff; transform: translateY(-2px); box-shadow: 0 10px 26px rgba(15, 163, 163, .32); }
.btn.ghost { background: transparent; color: var(--blue-d); border: 1.5px solid var(--line-2); }
.btn.ghost:hover { background: var(--surface-2); border-color: var(--blue); color: var(--blue-d); box-shadow: none; transform: none; }
.btn.sm { padding: 11px 18px; font-size: .84rem; }
.nobg { background: none; border: 0; padding: 0; font: inherit; color: var(--blue); cursor: pointer; }
/* A real control, not a hyperlink. Clearing the case is the one thing a patient who mis-taps needs
   to find at once, so it reads as a button and sits beside the input it belongs to. */
.textbtn { display: inline-flex; align-items: center; gap: 8px; background: var(--surface); border: 1.5px solid var(--line-2); color: var(--ink-2); border-radius: var(--pill); padding: 10px 18px; font: 600 .84rem/1 var(--sans); cursor: pointer; transition: .18s; }
.textbtn:hover { border-color: var(--blue); color: var(--blue-d); background: var(--surface-2); }
.nobg:hover { color: var(--teal-d); text-decoration: underline; }
.cta-row { display: flex; flex-wrap: wrap; gap: 14px; align-items: center; }
.split-cta { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; margin-top: 34px; }
.split-cta a { display: block; background: var(--surface); border: 1px solid var(--line); border-radius: var(--r); padding: 26px 28px; box-shadow: var(--sh-3); transition: .25s; }
.split-cta a:hover { transform: translateY(-3px); box-shadow: var(--sh-2); border-color: var(--line-2); }
.split-cta h3 { margin: 0 0 8px; font-size: 1.15rem; }
.split-cta span { font-size: .9rem; color: var(--ink-2); line-height: 1.6; display: block; }
/* The closing band carries the boundary statements the homepage no longer gives its own section for. */
.start-wrap h2 { max-width: 26ch; }
.start-wrap .lede { margin: 16px 0 0; }
.fineprint { list-style: none; margin: 34px 0 0; padding: 24px 0 0; border-top: 1px solid var(--line); display: grid; gap: 9px; max-width: 92ch; }
.fineprint li { position: relative; padding-left: 15px; font-size: .8rem; line-height: 1.62; color: var(--ink-3); }
.fineprint li::before { content: ""; position: absolute; left: 0; top: .6em; width: 4px; height: 4px; border-radius: 50%; background: var(--line-2); }
.fineprint a { color: var(--blue-d); text-decoration: underline; }

/* ---------------- header ---------------- */
.top { position: sticky; top: 0; z-index: 90; background: rgba(255, 255, 255, .94); backdrop-filter: saturate(180%) blur(12px); border-bottom: 1px solid var(--line); }
.top > .wrap { display: flex; align-items: center; gap: 22px; min-height: 72px; }
.mark { display: flex; align-items: baseline; gap: 8px; font: 900 1.32rem/1 var(--serif); color: var(--navy); letter-spacing: -.4px; }
.mark .mark-en { color: var(--blue); }
.mark .mark-cn { font: 600 .82rem/1 var(--sans); letter-spacing: .12em; color: var(--ink-3); border-left: 1px solid var(--line-2); padding-left: 9px; }
.nav-links { display: flex; align-items: center; gap: 4px; margin-left: auto; }
.nav-links > a { position: relative; padding: 9px 13px; font: 600 .93rem/1 var(--sans); color: var(--ink-2); border-radius: 8px; transition: color .18s; }
.nav-links > a:hover { color: var(--blue); }
.nav-links > a[aria-current="page"] { color: var(--blue); }
.nav-links > a[aria-current="page"]::after { content: ""; position: absolute; left: 13px; right: 13px; bottom: -1px; height: 3px; border-radius: 3px; background: var(--teal); }
.nav-right { display: flex; align-items: center; gap: 12px; }
.langs { display: inline-flex; align-items: center; gap: 7px; color: var(--blue); background: var(--surface); border: 1.5px solid var(--line); border-radius: var(--pill); padding: 6px 8px 6px 12px; }
.langs svg { width: 17px; height: 17px; }
.langsel { appearance: none; width: auto; max-width: 46vw; border: 0; background: transparent; font: 600 .86rem/1 var(--sans); color: var(--blue-d); padding: 2px 4px; cursor: pointer; }
.mark-cta { background: var(--teal); color: #fff; font: 700 .9rem/1 var(--sans); padding: 12px 22px; border-radius: var(--pill); white-space: nowrap; transition: .22s; }
.mark-cta:hover { background: var(--teal-d); color: #fff; box-shadow: 0 8px 22px rgba(15, 163, 163, .3); }

/* ---------------- hero ----------------
   Every opening band on the site wears the same plate: a blue-hour campus photograph under a navy→teal
   overlay, so the page reads blue first and photographic second. The image is a rendering made for this
   site carrying our own name on the sign — it is a brand plate, not an address, so nothing may caption
   it as a facility patients can visit or a hospital we are attached to. The overlay is lighter than the
   old flat-navy one (.9 → .5 across the diagonal): the copy sits on the dark left end of the frame, and
   the building has to stay recognisable for the band to read as a place rather than a colour. */
.hero {
  position: relative; overflow: hidden; color: #fff; padding: 100px 0 92px;
  background-color: var(--navy);
  background-image:
    linear-gradient(158deg, rgba(5, 38, 63, .9) 0%, rgba(6, 45, 78, .82) 36%, rgba(10, 74, 126, .68) 68%, rgba(13, 106, 134, .5) 100%),
    radial-gradient(1100px 520px at 82% -8%, rgba(15, 163, 163, .38), transparent 62%),
    url("/assets/img/hero-aegiscares-campus.jpg");
  background-size: cover, auto, 100% auto;
  background-position: center, center, center bottom;
  background-repeat: no-repeat;
}
.hero::after { content: ""; position: absolute; inset: 0; background-image: linear-gradient(rgba(255, 255, 255, .045) 1px, transparent 1px), linear-gradient(90deg, rgba(255, 255, 255, .045) 1px, transparent 1px); background-size: 56px 56px; mask-image: radial-gradient(900px 520px at 70% 20%, #000 20%, transparent 72%); pointer-events: none; }
.hero .wrap { z-index: 1; }
.hero-inner { display: grid; grid-template-columns: 1.28fr .72fr; gap: 26px 52px; align-items: start; }
/* Named areas rather than nesting: on a phone the figures have to come straight under the headline,
   and a wrapper around the copy and the cards would make that impossible without duplicating them. */
.hero-copy { grid-column: 1; grid-row: 1; }
.hero-actions { grid-column: 1; grid-row: 2; }
.hero .proof { grid-column: 2; grid-row: 1; }
.hero h1 { color: #fff; font-size: clamp(2.2rem, 4.7vw, 3.6rem); line-height: 1.1; letter-spacing: -1.4px; max-width: 28ch; }
.hero h1 .hl { display: block; overflow-wrap: break-word; }
.hero h1 em { font: italic 400 1em/1.1 var(--serif); color: #7fe3e3; letter-spacing: -.8px; }
.hero .lede { color: rgba(255, 255, 255, .84); margin: 22px 0 0; max-width: 66ch; }
.hero .cta-row { margin: 22px 0 0; }
/* ---- the four process figures, as a 2x2 of equal tiles ----
   The figure leads and the caption follows. The markup stays `<dt>` then `<dd>` because that is what a
   definition list means to a screen reader; the order is reversed visually, which is the part a patient
   reads. Every tile is the same size, and the four numbers share a baseline because every caption
   reserves the same two lines. */
.proof { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; margin: 0; text-align: center; }
.proof > div { background: rgba(255, 255, 255, .07); border: 1px solid rgba(255, 255, 255, .2); border-radius: var(--r);
  padding: 20px 10px; display: flex; flex-direction: column; align-items: center; justify-content: center; }
.proof dt { order: 2; min-height: 2lh; margin: 8px 0 0; font: 700 12px/1.35 var(--sans); letter-spacing: .1em;
  text-transform: uppercase; color: rgba(255, 255, 255, .7); hyphens: auto; overflow-wrap: anywhere; }
.proof dd { order: 1; margin: 0; font: 700 28px/1.2 var(--mono); color: #FFFFFF; font-variant-numeric: tabular-nums; }
.proof dd span { display: block; margin-top: 5px; font: 400 .78rem/1 var(--sans); color: rgba(255, 255, 255, .62); letter-spacing: 0; }

/* the two glass cards that split the visitor by who they are, and the solid pill under them */
.role-cards { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px; }
.role-card { display: flex; flex-direction: column; align-items: flex-start; gap: 10px; background: rgba(255, 255, 255, .1); border: 1px solid rgba(255, 255, 255, .24); backdrop-filter: blur(6px); border-radius: var(--r); padding: 22px; transition: .25s ease; }
.role-card:hover { background: rgba(255, 255, 255, .16); border-color: rgba(255, 255, 255, .42); transform: translateY(-3px); }
.role-card h3 { margin: 0; color: #fff; font-size: 1.06rem; }
.role-card p { margin: 0; color: rgba(255, 255, 255, .78); font-size: .88rem; line-height: 1.58; }
.role-card .btn.glass { margin-top: auto; background: rgba(255, 255, 255, .12); color: #fff; border: 1.5px solid rgba(255, 255, 255, .42); padding: 11px 20px; font-size: .84rem; }
.role-card .btn.glass:hover { background: rgba(255, 255, 255, .24); border-color: #fff; color: #fff; box-shadow: none; transform: none; }
.btn.light { background: var(--surface); color: var(--navy); font-weight: 800; padding: 16px 32px; box-shadow: 0 12px 30px rgba(6, 45, 78, .3); }
.btn.light:hover { background: var(--teal-50); color: var(--blue-d); box-shadow: 0 16px 36px rgba(6, 45, 78, .38); }

/* the estimator left the hero: it is a full-width band with its own heading */
#estimate .panel > header { background: linear-gradient(180deg, #fff, var(--bg)); }
#estimate .panel > header h3 { font-size: 1rem; color: var(--blue-d); }

/* ---------------- panels and the estimator ---------------- */
.panel { background: var(--surface); color: var(--ink); border: 1px solid var(--line); border-radius: var(--r-lg); box-shadow: var(--sh-2); overflow: hidden; }
.hero .panel { border-color: rgba(255, 255, 255, .5); }
.panel > header { display: flex; align-items: center; justify-content: space-between; gap: 14px; padding: 20px 24px; border-bottom: 1px solid var(--line); background: linear-gradient(180deg, #fff, var(--bg)); }
.panel > header h2 { font-size: 1.12rem; letter-spacing: -.3px; }
.panel .body { padding: 22px 24px 26px; }
.fields { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 15px 16px; }
.field { display: flex; flex-direction: column; gap: 7px; min-width: 0; }
.field.wide, .field > .wide { grid-column: 1 / -1; }
.field label { font: 700 .72rem/1.3 var(--sans); letter-spacing: .09em; text-transform: uppercase; color: var(--ink-3); }
input, select, textarea { font: inherit; color: var(--ink); background: var(--surface); border: 1.5px solid var(--line); border-radius: var(--r-sm); padding: 12px 13px; width: 100%; min-width: 0; transition: border-color .18s, box-shadow .18s; }
/* A select's intrinsic width is its longest option, so every box on the path to it has to be allowed
   to shrink or the whole page inherits that width. */
.hero .wrap, .hero-inner, .hero-inner > *, .panel, .panel .body, .readout, .fields, .field { min-width: 0; }
select { appearance: none; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M2 4.5 6 8.5l4-4' fill='none' stroke='%230a4a7e' stroke-width='1.6' stroke-linecap='round'/%3E%3C/svg%3E"); background-repeat: no-repeat; background-position: right 11px center; background-size: 12px; padding-right: 32px; }
input:focus, select:focus, textarea:focus { border-color: var(--teal); box-shadow: 0 0 0 3px rgba(15, 163, 163, .16); outline: none; }
textarea { min-height: 96px; resize: vertical; }
.fields select { width: 100%; }
.readout { margin-top: 20px; }
.readout.empty { padding: 16px 18px; border: 1px dashed var(--line-2); border-radius: var(--r-sm); background: var(--bg); color: var(--ink-3); font-size: .9rem; }
.compare { display: grid; grid-template-columns: 1fr 1fr; gap: 1px; background: var(--line); border: 1px solid var(--line); border-radius: var(--r); overflow: hidden; }
.compare > div { background: var(--surface); padding: 16px 18px; }
.compare dt { font: 700 .68rem/1.35 var(--sans); letter-spacing: .1em; text-transform: uppercase; color: var(--ink-3); margin-bottom: 7px; }
.compare dd { margin: 0; }
.compare dd.big, .compare .big { font: 500 1.3rem/1.2 var(--mono); color: var(--navy); font-variant-numeric: tabular-nums; }
.compare dd.sub, .compare .sub { font-size: .8rem; color: var(--ink-3); line-height: 1.5; margin-top: 5px; }
.compare .here { background: linear-gradient(180deg, var(--teal-50), #fff); }
.compare .here dt { color: var(--teal-d); }
.compare .here dd.big, .compare .here .big { color: var(--navy); }
.savings { margin: 14px 0 0; padding: 14px 18px; background: var(--teal-50); border: 1px solid #c6ecec; border-left: 3px solid var(--teal); border-radius: 0 var(--r-sm) var(--r-sm) 0; font-size: .95rem; color: var(--ink-2); }
.savings b { color: var(--blue-d); }
.breakdown { width: 100%; border-collapse: collapse; margin-top: 16px; font-size: .88rem; }
.breakdown td { padding: 9px 0; border-bottom: 1px solid var(--line); vertical-align: top; }
.breakdown td.num { text-align: right; padding-left: 14px; white-space: nowrap; }
.breakdown tr.total td { font-weight: 800; border-bottom: 0; padding-top: 12px; color: var(--navy); }
.route { margin-top: 16px; padding: 18px 20px; background: var(--bg); border: 1px solid var(--line); border-radius: var(--r); }
.route h4 { margin: 0 0 7px; color: var(--blue-d); font-size: 1rem; }
.route p { margin: 0 0 8px; font-size: .9rem; color: var(--ink-2); }
.route ul { margin: 6px 0 0; padding-left: 18px; font-size: .86rem; color: var(--ink-2); }
.route li { margin-bottom: 4px; }
.route .docs { font-size: .84rem; line-height: 1.6; }
.route.warn { background: var(--warn-bg); border-color: #ecd9b3; }
.tl-compact { list-style: none; margin: 18px 0 0; padding: 16px 0 0; border-top: 1px solid var(--line); display: grid; gap: 6px; }
.tl-compact li { display: grid; grid-template-columns: 28px 1fr; gap: 10px; font-size: .82rem; line-height: 1.6; color: var(--ink-3); }
.tl-compact .n { font: 700 .72rem/1.9 var(--mono); color: var(--teal-d); }
.tl-compact b { font-weight: 700; color: var(--navy); }
.flags { list-style: none; margin: 14px 0 0; padding: 0; }
.flags li { margin-bottom: 7px; padding: 9px 12px; background: var(--warn-bg); border-left: 2px solid var(--warn); border-radius: 0 var(--r-sm) var(--r-sm) 0; font-size: .82rem; color: var(--ink-2); }
.readout .flags { margin-top: 16px; }
.placeholder-flag { margin-top: 14px; padding: 12px 14px; border: 1px dashed var(--line-2); border-radius: var(--r-sm); background: var(--teal-50); font-size: .8rem; color: var(--ink-2); }

/* ---------------- cards, grids, pillars ---------------- */
.cols { display: grid; gap: 20px; }
/* The three cost cards hold different amounts of copy (measured 811 / 765 / 626 px at 1280). They are
   now stretched to a common height so the row reads as one block: the owner asked for the cards to look
   the same size. What that costs is air at the bottom of the shorter two — measured 0 / 46 / 185 px.
   The alternative was tested and rejected: spreading each card's bullets to fill the height, which
   aligned the bottoms but turned the bullet rhythm into 6px in one card and 67px in another. If the air
   is unwanted, the fix is content, not CSS: the travel card's four "Not included" items are the only
   block big enough to move out of the row, and that is a decision about what the page says. */
#cost-grid { align-items: stretch; }
.cols.c2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.cols.c3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.cols.c4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.cell { position: relative; background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-lg); padding: 26px; box-shadow: var(--sh-3); transition: box-shadow .22s ease, transform .22s ease, border-color .22s ease; }
.cell::before { content: ""; position: absolute; left: 26px; top: 0; width: 34px; height: 3px; border-radius: 0 0 3px 3px; background: linear-gradient(90deg, var(--blue), var(--teal)); }
.cell:hover, .cell.is-focus { box-shadow: var(--sh-2); transform: translateY(-3px); border-color: var(--line-2); }
.cell h3 { margin: 0 0 8px; font-size: 1.08rem; }
.cell p { font-size: .93rem; color: var(--ink-2); margin: 0 0 .7em; }
.cell .meta { margin: 0 0 10px; }
.pillars { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 18px; }
.pillars.c3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.pillar { position: relative; overflow: hidden; background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-lg); padding: 24px; box-shadow: var(--sh-3); transition: transform .28s ease, box-shadow .28s ease, border-color .28s ease; }
/* Same hover vocabulary as the hospital rows and the step cards: the top rule opens to full width, the
   card lifts, and the icon tile takes the brand gradient. Three different blocks, one reaction. */
.pillar::before { content: ""; position: absolute; left: 0; top: 0; width: 34px; height: 3px;
  background: linear-gradient(90deg, var(--blue), var(--teal)); transition: width .42s cubic-bezier(.22, .61, .36, 1); }
.pillar:hover, .pillar.is-focus { transform: translateY(-3px); border-color: var(--line-2); box-shadow: var(--sh-2); }
.pillar:hover::before, .pillar.is-focus::before { width: 100%; }
.pillar:hover .icon-row, .pillar.is-focus .icon-row { background: var(--blue); border-color: var(--blue-d); color: #fff; transform: scale(1.07); }
.pillar h3 { margin: 14px 0 7px; font-size: 1rem; }
.pillar p { margin: 0; font-size: .88rem; color: var(--ink-2); line-height: 1.6; }
.icon-row { display: inline-flex; align-items: center; justify-content: center; width: 42px; height: 42px; background: var(--surface-2); border: 1px solid var(--line); border-radius: 12px; color: var(--blue); transition: background .28s ease, border-color .28s ease, color .28s ease, transform .28s ease; }
.icon-row .icon { width: 22px; height: 22px; }

/* ---------------- hospital rows ---------------- */
/* One hospital per row: the distinguishing facts (grade, department name, founding year, bed count)
   are long strings in every language, and a three-up grid would clip them. The whole row is the link. */
.hosp { position: relative; display: grid; grid-template-columns: 186px minmax(0, 1fr) auto; gap: 8px 26px;
  align-items: center; padding: 26px 28px; background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-lg); box-shadow: var(--sh-3); overflow: hidden;
  transition: transform .28s ease, box-shadow .28s ease, border-color .28s ease; }
.hosp::before { content: ""; position: absolute; left: 0; top: 0; width: 34px; height: 3px;
  background: linear-gradient(90deg, var(--blue), var(--teal)); transition: width .42s cubic-bezier(.22, .61, .36, 1); }
.hosp:hover, .hosp:focus-visible, .hosp.is-focus { transform: translateY(-3px); border-color: var(--line-2); box-shadow: var(--sh-2); color: inherit; }
.hosp:hover::before, .hosp:focus-visible::before, .hosp.is-focus::before { width: 100%; }
/* One hover treatment for every card surface on the site, written once and applied to the whole list
   of card selectors: the hairline border resolves into the brand gradient and a soft teal glow lifts
   the card. No card gets to react differently from another. The ring is drawn with a mask so it sits
   exactly on the 1px border without touching any background. */
:is(.cell, .pillar, .hosp, .journey > li, .role-card, .split-cta a) { position: relative; }
:is(.cell, .pillar, .hosp, .journey > li, .role-card, .split-cta a)::after {
  content: ""; position: absolute; inset: 0; padding: 1px; border-radius: inherit; pointer-events: none;
  background: linear-gradient(135deg, var(--blue), var(--teal) 52%, #7fe3e3);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor; mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  mask-composite: exclude; opacity: 0; transition: opacity .3s ease; }
:is(.cell, .pillar, .hosp, .journey > li, .role-card, .split-cta a):hover::after,
:is(.cell, .pillar, .hosp, .journey > li, .role-card, .split-cta a):focus-within::after,
:is(.cell, .pillar, .hosp, .journey > li, .role-card, .split-cta a).is-focus::after { opacity: 1; }
:is(.cell, .pillar, .hosp, .journey > li, .role-card, .split-cta a):hover,
:is(.cell, .pillar, .hosp, .journey > li, .role-card, .split-cta a).is-focus {
  transform: translateY(-3px); box-shadow: 0 18px 46px rgba(15, 163, 163, .22), 0 3px 12px rgba(10, 40, 72, .09); }
.hosp-mark { position: relative; display: grid; place-items: center; width: 186px; height: 92px;
  background: var(--surface-2); border: 1px solid var(--line); border-radius: var(--r); overflow: hidden; }
.hosp-mark::before { content: ""; position: absolute; inset: 0;
  background: radial-gradient(120% 90% at 18% 8%, rgba(14, 92, 156, .09), transparent 62%); }
/* The wordmark is set in the serif face and clipped to the same blue→teal as the hover ring, so the
   tile reads as drawn for this site rather than as a logo we could not be bothered to fetch. Solid
   colour first: if background-clip:text is missing the letters must still be visible. */
.hosp-mark b { position: relative; font: 600 1.3rem/1.1 var(--serif); letter-spacing: .045em;
  text-align: center; padding: 0 8px; color: var(--blue); opacity: .62;
  transition: transform .34s ease, opacity .34s ease; }
@supports (background-clip: text) or (-webkit-background-clip: text) {
  .hosp-mark b { background: linear-gradient(135deg, var(--blue), var(--teal));
    -webkit-background-clip: text; background-clip: text; color: transparent; opacity: .9; }}
/* Six-letter marks (SYSUCC) are the longest in the list; they step down so the tile never crops one. */
.hosp-mark b.wm-long { font-size: 1.02rem; letter-spacing: .01em; }
.hosp-mark img { position: absolute; inset: 12px; width: calc(100% - 24px); height: calc(100% - 24px);
  object-fit: contain; object-position: center; }
.hosp-mark:has(img) b { display: none; }
.hosp:hover .hosp-mark b, .hosp:hover .hosp-mark img, .hosp.is-focus .hosp-mark b, .hosp.is-focus .hosp-mark img { transform: scale(1.07); }
.hosp:hover .hosp-mark b, .hosp:focus-visible .hosp-mark b, .hosp.is-focus .hosp-mark b { opacity: 1; }
.hosp-body { min-width: 0 }
.hosp-body h3 { margin: 7px 0 5px; font-size: 1.16rem; line-height: 1.3; }
.hosp-body .zh { margin: 0 0 8px; font: 500 .95rem/1.4 var(--sans); color: var(--ink); }
.hosp-body p { margin: 0; font-size: .9rem; color: var(--ink-2); line-height: 1.6; }
.hosp-go { display: inline-flex; align-items: center; gap: 8px; align-self: center; white-space: nowrap;
  font: 600 .84rem/1 var(--sans); color: var(--blue); transition: color .28s ease; }
.hosp-go i { font-style: normal; transition: transform .28s ease; }
.hosp:hover .hosp-go, .hosp:focus-visible .hosp-go, .hosp.is-focus .hosp-go { color: var(--blue-d); }
.hosp:hover .hosp-go i, .hosp:focus-visible .hosp-go i, .hosp.is-focus .hosp-go i { transform: translateX(5px); }
.hosp-facts { display: flex; flex-wrap: wrap; gap: 7px; }
.hosp-facts span { font: 700 .66rem/1 var(--sans); letter-spacing: .07em; text-transform: uppercase;
  color: var(--ink-3); background: var(--surface-2); border: 1px solid var(--line); border-radius: 999px; padding: 6px 10px; }
/* The city leads, because a patient scanning the list needs to know these are two cities forty
   minutes apart before they care about grade. Filled in the same gradient as the hover ring. */
.hosp-facts .hosp-city { color: #fff; background: linear-gradient(135deg, var(--blue), var(--teal)); border-color: transparent; }

.hosp-hero { display: grid; grid-template-columns: 260px minmax(0, 1fr); gap: 30px; align-items: center; }
.h2s { margin: 0 0 20px; font-size: 1.34rem; line-height: 1.3; color: var(--navy); }
.hosp-hero .hosp-mark { width: 260px; height: 104px; }
/* The building band under the profile heading. Cropped from the centre-high so a tower keeps its
   roofline rather than its car park. */
.hosp-photo { margin: 28px 0 0; }
.hosp-photo img { display: block; width: 100%; aspect-ratio: 21 / 8; object-fit: cover; object-position: center 38%;
  border: 1px solid var(--line); border-radius: var(--r-lg); box-shadow: var(--sh-3); }
.stat-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: 18px; }
.stat { background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-lg); padding: 22px 24px; box-shadow: var(--sh-3); }
.stat .k { margin: 0 0 8px; font: 700 .68rem/1.3 var(--sans); letter-spacing: .1em; text-transform: uppercase; color: var(--ink-3); }
.stat .v { margin: 0; font: 500 1.65rem/1.1 var(--mono); color: var(--navy); font-variant-numeric: tabular-nums; }
.stat .u { margin: 6px 0 0; font-size: .82rem; color: var(--ink-2); }
.spec-list { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 12px 26px; margin: 0; padding: 0; list-style: none; }
.spec-list li { position: relative; padding-left: 22px; font-size: .93rem; color: var(--ink-2); line-height: 1.55; }
.spec-list li::before { content: ""; position: absolute; left: 0; top: .55em; width: 9px; height: 9px;
  border-radius: 3px; background: linear-gradient(135deg, var(--blue), var(--teal)); }
.icon { width: 20px; height: 20px; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
.split { display: grid; grid-template-columns: 1fr 1fr; gap: 24px; }
.split > div { background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-lg); padding: 28px; box-shadow: var(--sh-3); }
.split > div.no { background: var(--stop-bg); border-color: #f3d7d8; }
.split h3 { margin: 0 0 14px; font-size: 1.1rem; }
.split ul { padding-left: 20px; font-size: .92rem; color: var(--ink-2); }
/* The class sits on the same element as `.wrap`, so a `padding` shorthand here erased the wrap's side
   gutter and ran the contact page's opening flush against both viewport edges. Vertical rhythm comes
   from the band, horizontal rhythm from `.wrap` — this rule only lays out the two columns. */
.lead-row { display: grid; grid-template-columns: 1.1fr .9fr; gap: 44px; align-items: start; }

/* ---------------- the eight steps ---------------- */
/* One stage per card: an oversized pale numeral, then the stage and what happens in it, then the two
   things the patient gets at that point. The numeral is a CSS counter, so reordering the steps can
   never misnumber them, and the leading zero comes free. */
.journey { list-style: none; margin: 0; padding: 0; display: grid; gap: 16px; counter-reset: step; }
.journey > li { display: grid; grid-template-columns: 78px minmax(0, 1fr) minmax(0, 1.02fr); gap: 0; align-items: start;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-lg); padding: 26px 28px;
  box-shadow: var(--sh-3); transition: transform .24s ease, box-shadow .24s ease, border-color .24s ease; }
.journey > li:hover, .journey > li.is-focus { transform: translateY(-2px); border-color: var(--line-2); box-shadow: var(--sh-2); }
.journey > li::before { counter-increment: step; content: counter(step, decimal-leading-zero); grid-column: 1;
  font: 700 2.6rem/.9 var(--serif); letter-spacing: -.03em; font-variant-numeric: tabular-nums; color: rgba(14, 92, 156, .22); }
.step-icon { display: inline-flex; align-items: center; justify-content: center; width: 38px; height: 38px; border-radius: 11px; background: var(--surface-2); border: 1px solid var(--line); color: var(--blue); }
.step-icon .icon { width: 20px; height: 20px; }
.step-head { padding-right: 32px; }
.step-head h3 { margin: 12px 0 7px; font-size: 1.14rem; }
.journey .when { display: inline-block; margin: 0 0 12px; font: 800 .68rem/1 var(--sans); letter-spacing: .1em; text-transform: uppercase; color: var(--teal-d); background: var(--teal-50); border-radius: 999px; padding: 6px 11px; }
.step-lede { margin: 0; font-size: .93rem; color: var(--ink-2); line-height: 1.68; max-width: 44ch; }
/* The right column carries two points while the left carries a paragraph, so it is ruled off as its
   own block instead of floating in the leftover width. */
.step-points { list-style: none; margin: 0; padding: 2px 0 0 32px; border-left: 1px solid var(--line); align-self: stretch; display: flex; flex-direction: column; gap: 16px; }
.step-points li { display: flex; align-items: flex-start; gap: 12px; font-size: .9rem; line-height: 1.6; color: var(--ink-2); }
.step-points li::before { content: ""; flex: none; width: 18px; height: 18px; margin-top: 2px; border-radius: 50%; background: var(--teal) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23fff' stroke-width='3.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m5 13 4 4 10-10'/%3E%3C/svg%3E") center/11px no-repeat; }
/* The same eight steps, one density down. /partners.html is a referrer skimming a sequence, not a
   patient reading a stage card, so the rail returns and the two-point column goes. */
.journey.compact { position: relative; gap: 0; }
.journey.compact::before { content: ""; position: absolute; left: 19px; top: 24px; bottom: 24px; width: 2px; background: linear-gradient(180deg, var(--line), var(--line-2), var(--line)); }
.journey.compact > li { grid-template-columns: 40px minmax(0, 1fr); gap: 0 22px; padding: 0 0 30px; background: none; border: 0; border-radius: 0; box-shadow: none; overflow: visible; }
.journey.compact > li:last-child { padding-bottom: 0; }
.journey.compact > li:hover, .journey.compact > li.is-focus { transform: none; border-color: transparent; box-shadow: none; }
.journey.compact > li::before { counter-increment: step; content: counter(step); position: relative; z-index: 1;
  display: flex; align-items: center; justify-content: center; width: 40px; height: 40px; border-radius: 50%;
  background: linear-gradient(135deg, var(--blue), var(--teal)); color: #fff; font: 900 1rem/1 var(--sans);
  box-shadow: 0 0 0 6px var(--surface), 0 6px 16px rgba(14, 92, 156, .22); }
.band.alt .journey.compact > li::before { box-shadow: 0 0 0 6px var(--bg), 0 6px 16px rgba(14, 92, 156, .22); }
.journey.compact > li::after { display: none; }
/* The homepage keeps the full stage content but wears the circle-and-rail number instead of the large
   serif numeral, so the eight steps read as one path rather than eight separate panels. */
.journey.steps > li { grid-template-columns: 56px minmax(0, 1fr) minmax(0, 1.02fr); gap: 0 26px; }
.journey.steps > li::before { counter-increment: step; content: counter(step); position: relative; z-index: 1;
  display: flex; align-items: center; justify-content: center; width: 44px; height: 44px; border-radius: 50%;
  background: linear-gradient(135deg, var(--blue), var(--teal)); color: #fff; font: 900 1.05rem/1 var(--sans);
  box-shadow: 0 6px 16px rgba(14, 92, 156, .24); }
.journey.compact .step-head { padding-right: 0; }
.journey.compact .step-head h3 { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 12px; margin: 3px 0 8px; font-size: 1.02rem; }
.journey.compact .when { margin: 0; }
.journey.compact .step-lede { max-width: 78ch; }
@media (max-width: 560px) { .journey.compact > li { grid-template-columns: 34px minmax(0, 1fr); gap: 0 16px; } .journey.compact > li::before { width: 34px; height: 34px; font-size: .9rem; } .journey.compact::before { left: 16px; }}

/* The same four figures, on a light band. The markup is Layout.proofHTML() — only the surface changes. */
.standards { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: 16px; }
.standards > div { background: var(--surface); border: 1px solid var(--line); border-radius: var(--r); padding: 20px 22px; box-shadow: var(--sh-3); }
.standards dt { font: 700 .68rem/1.35 var(--sans); letter-spacing: .1em; text-transform: uppercase; color: var(--ink-3); }
.standards dd { margin: 9px 0 0; font: 500 1.72rem/1.1 var(--mono); color: var(--navy); font-variant-numeric: tabular-nums; }
.standards > div { display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center; }
.standards dt { order: 2; min-height: 2lh; margin: 8px 0 0; }
.standards dd { order: 1; }
.standards dd span { display: block; margin-top: 6px; font: 400 .78rem/1 var(--sans); color: var(--ink-3); letter-spacing: 0; }

/* ---------------- tables ---------------- */
table { width: 100%; border-collapse: collapse; font-size: .9rem; }
th { text-align: left; font: 700 .7rem/1.4 var(--sans); letter-spacing: .09em; text-transform: uppercase; color: var(--ink-3); padding: 12px 14px; border-bottom: 2px solid var(--line); }
td { padding: 13px 14px; border-bottom: 1px solid var(--line); vertical-align: top; color: var(--ink-2); }
tbody tr:hover td { background: var(--bg); }
#visa-table, #cmp-table, #route-table, #table-wrap { overflow-x: auto; border-radius: var(--r); }
.cats { font-size: .84rem; min-width: 1080px; border-collapse: separate; border-spacing: 0; }
.cats td, .cats th { padding: 12px 14px; vertical-align: top; }
.cats .money { white-space: nowrap; }
.cats th:first-child, .cats td:first-child { position: sticky; left: 0; background: var(--surface); min-width: 200px; }
.cats th:nth-child(6), .cats td:nth-child(6) { min-width: 140px; }
.cats tbody tr:hover td:first-child { background: var(--bg); }
ul.scope, ul.budget, ul.doc-list { list-style: none; margin: 0; padding: 0; font-size: .89rem; color: var(--ink-2); }
ul.scope li { position: relative; padding: 8px 0 8px 22px; border-bottom: 1px dashed var(--line); }
ul.scope li:last-child { border-bottom: 0; }
ul.scope li::before { content: ""; position: absolute; left: 2px; top: 15px; width: 8px; height: 8px; border: 2px solid var(--teal); border-radius: 50%; }
ul.budget li { display: flex; justify-content: space-between; align-items: baseline; gap: 16px; padding: 9px 0; border-bottom: 1px dashed var(--line); }
ul.budget li b { font-family: var(--mono); font-variant-numeric: tabular-nums; color: var(--blue-d); white-space: nowrap; font-weight: 500; }
.cell, .field, .route, .docs, .budget li, .scope li, .flags li, .tl-compact li { overflow-wrap: anywhere; }

/* ---------------- waiting-time chart ---------------- */
.chart { display: grid; gap: 12px; margin-top: 8px; }
.chart-pick { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 10px; margin: 0 0 26px; font: 600 .88rem/1 var(--sans); color: var(--ink-2); }
.chart-pick select { width: auto; min-width: 200px; border-radius: var(--pill); font-weight: 600; color: var(--navy); cursor: pointer; }
.bar-row { display: grid; grid-template-columns: minmax(140px, 23%) 1fr auto; gap: 16px; align-items: center; font-size: .86rem; }
.bar-row .us { color: var(--blue-d); }
.bar-row .bar { height: 12px; background: var(--surface-2); border-radius: 999px; overflow: hidden; }
.bar-row .bar > i { display: block; height: 100%; border-radius: 999px; background: linear-gradient(90deg, var(--blue), var(--blue-d)); }
.bar-row.us .bar > i { background: linear-gradient(90deg, var(--teal), #0b7f7f); }
.bar-row .val { font-family: var(--mono); font-size: .8rem; color: var(--ink-3); white-space: nowrap; }
.axis { display: flex; justify-content: space-between; font: 400 .72rem/1 var(--mono); color: var(--ink-3); border-top: 1px solid var(--line); padding-top: 8px; margin-top: 4px; }
.legend { display: flex; gap: 20px; margin: 0 0 16px; font-size: .8rem; color: var(--ink-3); }
.legend span { display: inline-flex; align-items: center; gap: 7px; }
.legend i { width: 13px; height: 13px; border-radius: 4px; display: inline-block; }
.legend .home i { background: var(--blue-d); }
.legend .china i { background: var(--teal); }
.banner { background: var(--surface-2); border: 1px solid var(--line); border-radius: var(--r); padding: 20px 22px; }

/* ---------------- prose pages, method, faq ---------------- */
.prose { max-width: 74ch; font-size: 1rem; line-height: 1.78; color: var(--ink-2); }
.prose h2 { margin: 40px 0 14px; font-size: 1.4rem; }
.prose h3 { margin: 28px 0 10px; font-size: 1.08rem; }
.prose li { margin-bottom: .5em; }
.method { background: var(--bg); border: 1px solid var(--line); border-radius: var(--r-lg); padding: 26px; margin-top: 30px; }
.method h3 { margin: 0 0 10px; }
.method ul { font-size: .9rem; color: var(--ink-2); padding-left: 20px; }
/* The money band's three cards are one component read three ways, so they are made to match: equal
   height (the shared grid is align-items:start for other bands' sake), one list rhythm, one leading. */
#costs .cols { align-items: stretch; }
#costs ul.budget li { padding: 8px 0; }
#costs .cell .hint { line-height: 1.68; }

/* ---- FAQ accordion ----
   The open/close height is animated with `grid-template-rows: 0fr -> 1fr`, never `height: auto`:
   animating a length the browser has to measure reflows on every frame and stutters, while the row
   track interpolates on the compositor and the panel keeps its own natural height in any language. */
.faq { display: grid; gap: 10px; }
.faq-card { position: relative; z-index: 1; background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r); transform-origin: center;
  transition: transform .3s cubic-bezier(.4, 0, .2, 1), box-shadow .3s cubic-bezier(.4, 0, .2, 1), border-color .3s ease; }
.faq-card:hover, .faq-card.is-focus { border-color: var(--line-2); }
.faq-h { margin: 0; }
.faq-q { display: flex; align-items: center; justify-content: space-between; gap: 18px; width: 100%;
  padding: 18px 22px; background: none; border: 0; text-align: left; cursor: pointer;
  font: 700 1.02rem/1.4 var(--sans); color: var(--navy); }
.faq-q:focus-visible { outline: 2px solid var(--blue); outline-offset: -3px; border-radius: var(--r); }
/* One glyph, two bars: the vertical one rotates out, so "+" reads as "−" without swapping content. */
.faq-sign { position: relative; flex: none; width: 18px; height: 18px; }
.faq-sign::before, .faq-sign::after { content: ""; position: absolute; border-radius: 2px; background: var(--teal);
  transition: transform .3s cubic-bezier(.4, 0, .2, 1), opacity .2s ease; }
.faq-sign::before { left: 0; top: 8px; width: 18px; height: 2px; }
.faq-sign::after { left: 8px; top: 0; width: 2px; height: 18px; }
.faq-a { display: grid; grid-template-rows: 0fr; transition: grid-template-rows .3s cubic-bezier(.4, 0, .2, 1); }
.faq-body { overflow: hidden; min-height: 0; }
.faq-body p { margin: 0 22px 20px; max-width: 84ch; font-size: .95rem; line-height: 1.6; color: var(--ink-3); }
.faq-body p + p { margin-top: 12px; }
.faq-card.is-open { transform: scale(1.02); z-index: 10; border-color: var(--line-2); box-shadow: var(--sh-2); }
.faq-card.is-open .faq-a { grid-template-rows: 1fr; }
.faq-card.is-open .faq-sign::after { transform: rotate(90deg); opacity: 0; }
.faq-card.is-open .faq-q { color: var(--blue-d); }
@media (prefers-reduced-motion: reduce) {
  .faq-card, .faq-a, .faq-sign::before, .faq-sign::after { transition: none; }
  .faq-card.is-open { transform: none; }}
.cta-band { background: linear-gradient(135deg, rgba(14, 92, 156, .95), rgba(15, 163, 163, .9)); color: #fff; border-radius: var(--r-lg); padding: 54px 38px; text-align: center; position: relative; overflow: hidden; }
.cta-band h2 { color: #fff; max-width: 24ch; margin: 0 auto 14px; }
.cta-band p { color: rgba(255, 255, 255, .86); max-width: 62ch; margin: 0 auto 26px; }
.cta-band .btn { background: #fff; color: var(--blue-d); }
.cta-band .btn:hover { background: var(--teal-50); color: var(--navy); }
.cta-band .btn.ghost { background: transparent; color: #fff; border-color: rgba(255, 255, 255, .5); }

/* ---------------- intake chat ---------------- */
.chat-shell { display: grid; grid-template-columns: minmax(0, 1fr) 348px; gap: 28px; align-items: start; padding: 44px 0 64px; }
.chat { background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-lg); box-shadow: var(--sh); overflow: hidden; }
.chat-log { height: min(58vh, 560px); overflow-y: auto; padding: 22px; display: flex; flex-direction: column; gap: 14px; background: var(--bg); }
.msg { max-width: 84%; }
.msg .who { font: 700 .66rem/1 var(--sans); letter-spacing: .1em; text-transform: uppercase; color: var(--ink-3); margin-bottom: 6px; }
.msg .mtext { background: var(--surface); border: 1px solid var(--line); border-radius: 4px 16px 16px 16px; padding: 14px 17px; font-size: .95rem; line-height: 1.62; color: var(--ink); }
.msg.you { align-self: flex-end; }
.msg.you .who { text-align: right; }
.msg.you .mtext { background: linear-gradient(135deg, var(--blue), var(--blue-d)); color: #fff; border-color: transparent; border-radius: 16px 4px 16px 16px; }
.msg .mtext pre { margin: .5em 0 0; padding: 12px 14px; background: var(--navy); color: #dceaf5; border-radius: var(--r-sm); font: 400 .76rem/1.55 var(--mono); overflow-x: auto; white-space: pre; }
.chips { display: flex; flex-wrap: wrap; gap: 9px; margin-top: 12px; }
.chip { background: var(--surface); border: 1.5px solid var(--line-2); color: var(--blue-d); border-radius: var(--pill); padding: 9px 16px; font: 600 .85rem/1.2 var(--sans); cursor: pointer; transition: .18s; }
.chip:hover { background: var(--teal-50); border-color: var(--teal); color: var(--teal-d); }
.composer { display: flex; gap: 10px; padding: 16px 18px; border-top: 1px solid var(--line); background: var(--surface); }
.composer input { flex: 1; }
.typing { margin: 0; padding: 0 22px 14px; font: italic 400 .82rem/1 var(--sans); color: var(--ink-3); background: var(--bg); }
.side { display: grid; gap: 18px; position: sticky; top: 92px; }
.casecard dl { margin: 0; display: grid; grid-template-columns: auto 1fr; gap: 7px 14px; font-size: .84rem; }
.casecard dt { color: var(--ink-3); font-weight: 600; }
.casecard dd { margin: 0; color: var(--navy); font-weight: 600; }
.score { display: flex; align-items: baseline; gap: 10px; margin-bottom: 14px; }
.score .v { font: 500 1.9rem/1 var(--mono); color: var(--blue); }
.toolbar { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 14px; }
.transcript { font-size: .8rem; color: var(--ink-3); max-height: 220px; overflow: auto; background: var(--bg); border: 1px solid var(--line); border-radius: var(--r-sm); padding: 12px 14px; }
.empty-state { padding: 26px; text-align: center; color: var(--ink-3); font-size: .9rem; border: 1px dashed var(--line-2); border-radius: var(--r); background: var(--bg); }

/* ---------------- leads board ---------------- */
.row { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; padding: 14px 0; border-bottom: 1px solid var(--line); }
.row .k-brand { font: 800 .95rem/1.2 var(--sans); color: var(--navy); }
.row .k-brass { color: var(--brass); }
.val { font-family: var(--mono); font-size: .86rem; color: var(--navy); }
.bar { height: 8px; border-radius: 999px; background: var(--surface-2); overflow: hidden; }
.bar > i { display: block; height: 100%; background: linear-gradient(90deg, var(--teal), var(--blue)); }

/* ---------------- footer ---------------- */
footer.site { position: relative; overflow: hidden; background: linear-gradient(180deg, var(--navy) 0%, var(--blue-d) 100%); color: #cdd9e3; padding: 68px 0 30px; margin-top: 0; }
footer.site::before { content: ""; position: absolute; inset: -40% 40% auto -10%; height: 420px; background: radial-gradient(closest-side, rgba(15, 163, 163, .22), transparent); pointer-events: none; }
footer.site .wrap { z-index: 1; }
footer.site h4 { color: #fff; font-size: .78rem; letter-spacing: .12em; text-transform: uppercase; margin: 0 0 14px; }
footer.site .foot-grid { display: grid; grid-template-columns: 1.6fr 1fr 1fr 1.2fr; gap: 34px; padding-bottom: 34px; border-bottom: 1px solid rgba(255, 255, 255, .16); }
/* The site-wide jump band: rendered by layout.js above every footer, minus the page you are on. */
footer.site .foot-nav { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; padding-bottom: 30px; margin-bottom: 34px; border-bottom: 1px solid rgba(255, 255, 255, .16); }
footer.site .foot-nav .eyebrow { color: #7fe3e3; margin: 0 10px 0 0; }
footer.site .foot-nav .eyebrow::before { display: none; }
footer.site .foot-nav a { border: 1px solid rgba(255, 255, 255, .26); border-radius: var(--pill); padding: 10px 17px; font: 600 .86rem/1 var(--sans); color: #dceaf5; transition: .2s; }
footer.site .foot-nav a:hover { background: rgba(255, 255, 255, .1); border-color: #7fe3e3; color: #fff; }
footer.site ul { list-style: none; margin: 0; padding: 0; font-size: .88rem; }
footer.site li { margin-bottom: 9px; }
footer.site a { color: #cdd9e3; }
footer.site a:hover { color: #7fe3e3; }
footer.site p { font-size: .88rem; line-height: 1.7; color: #a9bccb; }
footer.site .disclaim { font-size: .78rem; color: #8ba3b6; line-height: 1.65; }
footer.site .legal { grid-column: 1 / -1; border-top: 0; }
footer.site .legal p { margin: 0; }
.foot-bottom { display: flex; flex-wrap: wrap; gap: 14px; justify-content: space-between; padding-top: 22px; font-size: .78rem; color: #8ba3b6; }

/* ---------------- responsive ---------------- */
@media (max-width: 1100px) {
  .band, .section { padding: 68px 0; }
  .hero { padding: 64px 0; }
  .hero-inner { display: flex; flex-direction: column; gap: 26px; }
  /* `align-items: start` above belongs to the two-column grid. Carried into the stacked layout it
     shrinks the numbers bar to the width of its own text, so it came out a different size in every
     language — 304px in Chinese against 644px in French at a 1000px window — and stopped short of
     the entry cards above it. */
  .hero-inner { align-items: stretch; }
  .cols.c4, .pillars, .pillars.c3 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .cols.c3 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .lead-row { grid-template-columns: 1fr; gap: 32px; }
  .chat-shell { grid-template-columns: 1fr; }
  .side { position: static; grid-template-columns: 1fr 1fr; }
  footer.site .foot-grid { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 920px) {
  .top > .wrap { flex-wrap: wrap; gap: 10px 18px; padding-bottom: 0; }
  /* Below 920px the nav stops hiding behind a burger and becomes the header's second row.
     Translated labels run long — "Kosten­schätzung", "Estimation des frais" — so the row scrolls
     sideways instead of wrapping into three tiers and eating the viewport. */
  .nav-links { order: 4; flex: 0 0 100%; margin-left: 0; display: flex; align-items: stretch; gap: 2px;
    overflow-x: auto; scrollbar-width: none; -webkit-overflow-scrolling: touch; padding-bottom: 1px;
    -webkit-mask-image: linear-gradient(90deg, #000 0, #000 calc(100% - 26px), transparent);
    mask-image: linear-gradient(90deg, #000 0, #000 calc(100% - 26px), transparent); }
  .nav-links::-webkit-scrollbar { display: none; }
  .nav-links > a { padding: 12px 11px 13px; font-size: .95rem; white-space: nowrap; border-bottom: 3px solid transparent; }
  .nav-links > a:first-child { padding-left: 0; }
  .nav-links > a[aria-current="page"] { border-bottom-color: var(--teal); }
  .nav-links > a[aria-current="page"]::after { display: none; }
  .nav-right { order: 2; margin-left: auto; }
  /* Two sticky rows now, so an in-page anchor has to clear both — and the clearance is the measured
     header height, not a constant, or shrinking the header leaves every anchor landing 40px short. */
  html { scroll-padding-top: calc(var(--head-h, 138px) + 8px); }
  .split, .split-cta { grid-template-columns: 1fr; }
  .journey > li { grid-template-columns: 58px minmax(0, 1fr); gap: 4px 20px; padding: 22px 24px; }
  .journey > li::before { font-size: 1.9rem; }
  .step-head { grid-column: 2; grid-row: 1; padding-right: 0; }
  .step-points { grid-column: 2; grid-row: 2; margin-top: 18px; padding-left: 0; border-left: 0; gap: 12px; }}
@media (max-width: 768px) {
  :root { --gutter: 18px; }
  body { font-size: 16px; }
  .band, .section { padding: 52px 0; }
  .hero { padding: 46px 0; }
  .cols.c2, .cols.c3, .cols.c4, .pillars, .pillars.c3, .compare, .fields, .side, .role-cards { grid-template-columns: 1fr; }
  /* The proof strip is four short figures; stacked they turn the first screen into a list. */
  .proof { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .score .v { font-size: 1.6rem; }
  .panel > header { flex-direction: column; align-items: flex-start; gap: 10px; }
  /* The estimator's amount column is tabular and must not break mid-figure, so on a phone the
     readout scrolls sideways instead of the panel's overflow:hidden cutting a price in half. */
  .readout { overflow-x: auto; }
  .bar-row { grid-template-columns: 1fr; gap: 6px; }
  .bar-row .val { order: 3; }
  .msg { max-width: 94%; }
  /* The row keeps its mark, but the call-to-action drops under the text rather than competing with
     it for horizontal room. */
  .hosp { grid-template-columns: 128px minmax(0, 1fr); gap: 6px 18px; padding: 20px 20px; }
  .hosp-mark { width: 128px; height: 66px; }
  .hosp-mark b { font-size: 1.15rem; padding: 0 4px; }
  .hosp-mark b.wm-long { font-size: .84rem; letter-spacing: 0; }
  .hosp-go { grid-column: 2; justify-self: start; margin-top: 4px; }
  .hosp-hero { grid-template-columns: 1fr; gap: 18px; }
  .hosp-hero .hosp-mark { width: 172px; height: 84px; }
  /* At this width a 2% scale pushes the card past the gutter, so the lift is halved. */
  .faq-q { padding: 16px 18px; font-size: .98rem; }
  .faq-body p { margin: 0 18px 18px; }
  .faq-card.is-open { transform: scale(1.01); }
  .hosp-photo { margin-top: 20px; }
  .hosp-photo img { aspect-ratio: 16 / 10; }
  .cta-band { padding: 34px 22px; }
  footer.site .foot-grid { grid-template-columns: 1fr; gap: 26px; }
  .row { grid-template-columns: 1fr; }}
@media (max-width: 560px) {
  /* Row one has to hold the brand, the language pill and the consult button down to 390px, so the
     button tightens instead of disappearing — it is the page's main conversion. */
  .mark-cta { padding: 10px 15px; font-size: .84rem; }
  .langs { gap: 5px; }
  .langsel { font-size: .82rem; }
  h1 { font-size: 2.05rem; letter-spacing: -1px; }
  h2 { font-size: 1.42rem; }
  .btn { width: 100%; }
  .cta-row .btn { width: auto; flex: 1 1 auto; }
  .cell, .pillar { padding: 20px; border-radius: var(--r); }
  .panel { border-radius: var(--r); }
  .panel .body { padding: 18px 16px 22px; }
  .journey > li { grid-template-columns: 44px minmax(0, 1fr); padding: 20px 20px; gap: 4px 14px; }
  .journey > li::before { font-size: 1.55rem; }
  .tl-compact li { grid-template-columns: 24px 1fr; }}

/* =============================================================
   v5 — card system, entrance reveal, sticky header state, mobile
   ============================================================= */

/* ---- entrance reveal ----
   The resting state is wrapped in :where() so it carries no specificity: a card's own hover transform
   must still beat "resting 20px down", or the lift silently stops working. The declarations live in one
   block at the end of this file, because a transition has to be listed after every component's own
   shorthand to survive — see "v20" below. */

/* ---- the card ---- */
.card {
  background: var(--color-bg); border: 1px solid var(--color-border); border-radius: var(--radius);
  box-shadow: var(--shadow-sm); padding: 28px 24px;
  transition: transform .25s ease, box-shadow .25s ease, border-color .25s ease;
}
.card:hover { transform: translateY(-2px); box-shadow: var(--shadow-md); border-color: var(--color-border-2); }
.card-title { font: 800 1.1rem/1.3 var(--sans); color: var(--color-text); }
.card-desc { font-size: .9rem; line-height: 1.6; color: var(--color-text-muted); }

/* The money band is one component read three ways: equal height, one list rhythm. */
#costs .cols { align-items: stretch; }
/* 6px top and bottom on each row is the 12px between two items — one number, both neighbours. The
   22px left indent stays, because that is where the hollow circle bullet is drawn. */
#costs ul.scope li { padding: 6px 0 6px 22px; }
#costs ul.budget li { padding: 6px 0; }
#costs .cell .hint { line-height: 1.65; }

/* ---- hospitals: three cards across on a desktop, one column on a phone ----
   The card turns vertical at that width because the emblems are horizontal lockups: a 10:1 wordmark
   needs the full card width, not a 186px column beside the text. */
.hosp-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.hosp { display: flex; flex-direction: column; align-items: flex-start; gap: 12px; }
.hosp .hosp-mark { width: 100%; height: 92px; }
.hosp .hosp-body { width: 100% }
.hosp .hosp-go { margin-top: auto; }
/* The hero grid and the 260px plate are declared once, at their first definition.
   Re-declaring them down here, outside any media query, silently overrode the phone rule above and
   squeezed the hospital name into a 57px column — the letter-by-letter wrap he reported. */
@media (max-width: 1100px) { .hosp-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 768px) {
  .hosp-grid { grid-template-columns: minmax(0, 1fr); }
  .hosp .hosp-mark { height: 78px; }}

/* ---- sticky header: the glass is there from the start, the shadow is not ---- */
.top { transition: background .3s ease, box-shadow .3s ease, border-color .3s ease; }
.top.scrolled { background: rgba(255, 255, 255, .85); backdrop-filter: saturate(180%) blur(12px); box-shadow: var(--shadow-sm); }

/* ---- FAQ: the lift is small enough not to collide with its neighbour ---- */
.faq-card.is-open { transform: scale(1.01); }
.faq-card, .faq-a, .faq-sign::before, .faq-sign::after { transition-duration: .3s; transition-timing-function: ease; }

/* ---- phone: 20px gutters, 48px touch targets, stacked entry cards ---- */
@media (max-width: 768px) {
  :root { --gutter: 20px; }
  .band { padding: 60px 0; }
  .btn, .textbtn, .chip { min-height: 48px; }
  .btn { width: 100%; }
  .sec-head { margin-bottom: 30px; }
  .split-cta { grid-template-columns: minmax(0, 1fr); }
}

/* =============================================================
   v6 — hospital band: title row with a view-all exit, emblem wall
   as texture, and a horizontal rail of cards
   ============================================================= */

/* ---- title row ---- */
#hospitals .sec-head { display: flex; align-items: flex-end; justify-content: space-between; gap: 28px;
  max-width: none; margin: 0 0 8px; text-align: left; }
#hospitals .sec-head > div { min-width: 0; max-width: 88ch; }
#hospitals .sec-head .eyebrow { text-align: left; }
#hospitals .sec-head .eyebrow::before { display: none; }
#hospitals .sec-head h2 { margin: 0 0 12px; max-width: 34ch; }
#hospitals .sec-head p:not(.eyebrow) { margin: 0; max-width: 88ch; }
.view-all-link { flex: none; display: inline-flex; align-items: center; gap: 8px; padding: 0 0 6px;
  font: 700 .92rem/1.2 var(--sans); color: var(--color-accent); white-space: nowrap; }
.view-all-link:hover { color: var(--color-accent-d); }
.view-all-link .arrow { transition: transform .2s ease; }
.view-all-link:hover .arrow { transform: translateX(4px); }
.view-all-link:focus-visible { outline: 2px solid var(--color-primary); outline-offset: 3px; border-radius: 4px; }

/* ---- the card: emblem plate on the left, text vertically centred beside it ----
   Two grid columns, and the "view" link sits under the text rather than beside it: at rail width a
   side-by-side link left the name about 80px to wrap into, which is not a card, it is a column of
   single words. The plate spans both rows so it stays centred against the text block. */
.hosp { display: grid; grid-template-columns: 80px minmax(0, 1fr); grid-template-areas: "mark body" "mark go";
  column-gap: 18px; row-gap: 10px; align-items: center; padding: 20px 24px; }
.hosp .hosp-mark { grid-area: mark; width: 80px; height: 80px; align-self: center; flex: none;
  background: var(--color-bg); border: 1px solid var(--color-border-plate); border-radius: 8px; }
.hosp .hosp-mark::before { display: none; }
.hosp .hosp-mark img { inset: 8px; width: calc(100% - 16px); height: calc(100% - 16px); }
.hosp .hosp-body { grid-area: body; flex: 1 1 auto; min-width: 0; width: auto; }
.hosp .hosp-go { grid-area: go; justify-self: start; margin-top: 0; }
.hosp-facts { margin: 0 0 7px; }
.hosp-body h3 { margin: 0 0 5px; }

/* ---- the rail ---- */
.rail-wrap { position: relative; }
.hosp-grid.rail { display: flex; gap: 20px; overflow-x: auto; overflow-y: hidden;
  scroll-snap-type: x mandatory; scroll-behavior: smooth; padding: 20px 0 26px;
  scrollbar-width: none; -ms-overflow-style: none; }
.hosp-grid.rail::-webkit-scrollbar { display: none; }
.hosp-grid.rail > .hosp { flex: 0 0 calc((100% - 2 * 20px) / 3); scroll-snap-align: start; }

.rail-prev { left: -14px; }
.rail-next { right: -14px; }

/* ---- nav: the current page, decided from the URL ---- */
.nav-links > a.active { color: var(--color-primary); font-weight: 800; }
.nav-links > a.active::after { content: ""; position: absolute; left: 13px; right: 13px; bottom: -1px;
  height: 3px; border-radius: 3px; background: var(--color-accent); }

@media (max-width: 1100px) {
  .hosp-grid.rail > .hosp { flex-basis: calc((100% - 20px) / 2); }}
@media (max-width: 768px) {
  #hospitals .sec-head { display: block; }
  .view-all-link { padding-top: 14px; }
  .hosp { grid-template-columns: 64px minmax(0, 1fr); column-gap: 14px; row-gap: 8px; padding: 18px; }
  .hosp .hosp-mark { width: 64px; height: 64px; }
  /* one and a bit cards per screen: the sliver of the next card is the affordance that says "slide me" */
  .hosp-grid.rail > .hosp { flex-basis: calc((100% - 20px) / 1.2); }
  .hosp-grid.rail { padding-bottom: 34px; }}

/* =============================================================
   v7 — hospital band: emblem wall as true background, copy on a
   glass card, rail that pages two hospitals at a time
   ============================================================= */

/* ---- the band and its background wall ---- */
#hospitals { position: relative; }
#hospitals > .wrap { position: relative; z-index: 1; }

/* the copy sits on a glass card so it stays readable over the wall */
#hospitals .sec-head { background: rgba(255, 255, 255, .75); backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px); padding: 30px; border-radius: 16px; position: relative; z-index: 2;
  border: 1px solid var(--color-border); margin: 0 0 22px; }

/* ---- the rail: one slide per screen, two stacked cards per slide ---- */
.rail-wrap { position: relative; }
.rail { display: flex; gap: 20px; overflow-x: auto; overflow-y: hidden; scroll-snap-type: x mandatory;
  scroll-behavior: smooth; padding: 16px 0 22px; scrollbar-width: none; -ms-overflow-style: none; }
.rail::-webkit-scrollbar { display: none; }
.slide-item { flex: 0 0 100%; display: grid; gap: 20px; scroll-snap-align: start; min-width: 0; }

/* ---- the card: a wide bar, emblem plate left, text centred right ----
   The plate is 200x100 rather than 100x100 because every emblem we hold is a horizontal lockup — the
   widest is 10.7:1. In a square box, `contain` with no cropping renders those at about 12px tall,
   which is the "too small" problem again. Width is what a lockup needs; height is not. */
.hosp { display: grid; grid-template-columns: 200px minmax(0, 1fr); grid-template-areas: "mark body" "mark go";
  column-gap: 24px; row-gap: 8px; align-items: center; padding: 24px; }
.hosp .hosp-mark { grid-area: mark; width: 200px; height: 100px; align-self: center; padding: 10px;
  background: var(--color-bg); border: 1px solid var(--color-border-plate); border-radius: 12px; }
.hosp .hosp-mark img { position: static; width: 100%; height: 100%; object-fit: contain; object-position: center; }
.hosp .hosp-body { grid-area: body; }
.hosp .hosp-go { grid-area: go; justify-self: start; }

.rail-prev { left: -14px; }
.rail-next { right: -14px; }
/* The strip loops, so an arrow is never dead: at either end it wraps to the other side instead of
   switching itself off, so there is no disabled state to style. */

/* ---- the list page: two columns of the same bar ----
   Scoped to ≥761px on purpose. Written unconditionally it sat later in the file than the phone
   rule above and silently turned a 390px screen into two 180px columns, where every card wrapped
   one word per line. */
@media (min-width: 769px) { .hosp-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }

@media (max-width: 1100px) {
  .hosp { grid-template-columns: 160px minmax(0, 1fr); column-gap: 18px; }
  .hosp .hosp-mark { width: 160px; }}
@media (max-width: 768px) {
  .hospitals .sec-head, #hospitals .sec-head { padding: 20px; border-radius: var(--radius); }
  .hosp { grid-template-columns: 132px minmax(0, 1fr); column-gap: 14px; padding: 18px; }
  .hosp .hosp-mark { width: 132px; height: 72px; padding: 8px; }
  .rail { padding-left: 0; }}

/* =============================================================
   v8 — hero as one right-hand panel, headings without orphan
   lines, reveal triggered in the middle band of the screen
   ============================================================= */

/* ---- hero: 60 / 40, and the figures and the sentence are one panel ---- */
.hero-inner { grid-template-columns: 60% calc(40% - 52px); gap: 26px 52px; align-items: stretch; }
.hero-left { display: grid; grid-template-rows: auto auto; gap: 26px; min-width: 0; }
.hero-panel { display: flex; flex-direction: column; gap: 16px; padding: 22px;
  background: rgba(255, 255, 255, .08); border: 1px solid rgba(255, 255, 255, .18);
  border-radius: var(--r-lg); backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px); }
/* The panel is stretched to the height of the copy column, so its content is centred inside it:
   four compact figures and the sentence under them, with equal air above and below rather than a
   dead band at the bottom. */
.hero-panel { justify-content: center; }
.panel-note { margin: 0; font-size: .84rem; line-height: 1.6; color: rgba(255, 255, 255, .66); max-width: 46ch; }

/* ---- headings: no orphaned last line anywhere ----
   `balance` is for headings (it rewraps so the final line is not one word); `pretty` is for body
   text, where its job is killing single-word widows. They are not interchangeable, so each goes
   where it does something. */
h1, h2, h3, h4 { text-wrap: balance; }
p { text-wrap: pretty; }
.sec-head { max-width: 800px; margin: 0 auto 44px; }
.sec-head h2 { max-width: 800px; margin: 0 auto 14px; }
.hosp-body h3, .cell h3, .pillar h3, .role-card h3 { text-wrap: balance; }

/* ---- reveal lives at the end of this file (v20), in one place ---- */


/* ---- the list page keeps the square plate the client specified; the homepage rail card is
   twelve times wider and gives the lockup a 200px plate instead ---- */
.hosp-grid .hosp { grid-template-columns: 100px minmax(0, 1fr); column-gap: 20px; padding: 24px; }
.hosp-grid .hosp .hosp-mark { width: 100px; height: 100px; }

@media (max-width: 1100px) {
  /* `contents` lets the panel come straight under the headline on a phone without moving it in the DOM,
     which is what the figures are for: they answer "how fast" before anyone reads a card. */
  .hero-left { display: contents; }
  .hero-inner { display: flex; flex-direction: column; gap: 24px; }
  .hero-copy { order: 1; }
  .hero-panel { order: 2; }
  .hero-actions { order: 3; }
  .hero-panel { max-width: 680px; }}
@media (max-width: 768px) {
  /* The figures are the point of the panel, so the widest one — "$200–300" — has to stay on one
     line rather than breaking after the dash. Tighter cells plus a smaller mono size buy the room. */
  .hero-panel { padding: 16px; }
  .hero-panel .proof > div { padding: 16px 12px; }
  .hero-panel .proof dd { font-size: 1.3rem; white-space: nowrap; }
  .hosp-grid .hosp { grid-template-columns: 72px minmax(0, 1fr); column-gap: 14px; padding: 18px; }
  .hosp-grid .hosp .hosp-mark { width: 72px; height: 72px; padding: 8px; }}

/* =============================================================
   v9 — looping rail, hero panel sub-heading, FAQ line + glyph,
   home/hospitals in the nav, faster entrances
   ============================================================= */

/* ---- header sits above every band on the page ---- */
.top { z-index: 100; }

/* ---- entrances moved to the end of the file (v20): a transition declared here was being
   overwritten by every component shorthand below it ---- */

/* ---- hero panel: the figures, then what happens next ---- */
.panel-h { margin: 0; font: 700 .68rem/1.3 var(--sans); letter-spacing: .1em; text-transform: uppercase;
  color: rgba(255, 255, 255, .55); }
.hero-panel .panel-h { margin-top: 4px; }

/* ---- FAQ: a rule that draws itself across the top edge, and a glyph that inverts ---- */
.faq-card { overflow: hidden; }
.faq-card::before { content: ""; position: absolute; top: 0; left: 0; width: 0; height: 3px; z-index: 2;
  background: var(--color-accent); transition: width .4s cubic-bezier(.16, 1, .3, 1); }
.faq-card:hover::before, .faq-card.is-open::before, .faq-card.is-focus::before { width: 100%; }
.faq-q { gap: 14px; }
.faq-q > span:not(.faq-icon) { flex: 1 1 auto; }
.faq-icon { display: flex; justify-content: center; align-items: center; flex: none;
  width: 32px; height: 32px; border-radius: 8px; background: var(--color-ice); color: #0A2540;
  font: 800 1rem/1 var(--sans); transition: background .3s ease, color .3s ease; }
.faq-card:hover .faq-icon, .faq-card.is-open .faq-icon, .faq-card.is-focus .faq-icon { background: #0A2540; color: #FFFFFF; }
@media (prefers-reduced-motion: reduce) {
  .faq-card::before { transition: none; }
  .faq-icon { transition: none; }}

/* ---- the strip loops, so the arrows never go dead; a wrap is acknowledged with one blink ---- */
.rail.flash { animation: rail-blink .42s ease; }
@keyframes rail-blink { 35% { opacity: .45; }}
@media (prefers-reduced-motion: reduce) {
  .rail.flash { animation: none; }
  @keyframes rail-blink { 0%, 100% { opacity: 1; }}}

/* ---- hospital profile: the owner-supplied narrative ---- */
.hosp-brief { margin: 14px 0 0; max-width: 78ch; font-size: .96rem; line-height: 1.66; color: var(--ink-3); }
#hosp-history p, #hosp-intl-body p { max-width: 88ch; }

/* =============================================================
   v10 — the stepped intake wizard on /consult.html
   ============================================================= */

.intake { background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-lg);
  box-shadow: var(--sh-2); padding: 26px 28px 22px; max-width: 860px; margin: 0 auto; }
.intake-top { margin-bottom: 22px; }
.prog { margin: 0 0 8px; font: 600 .78rem/1 var(--mono); letter-spacing: .06em; text-transform: uppercase; color: var(--ink-3); }
.prog-bar { height: 4px; background: var(--surface-2); border-radius: 999px; overflow: hidden; }
.prog-bar > i { display: block; height: 100%; width: 0; border-radius: 999px;
  background: linear-gradient(90deg, var(--blue), var(--teal)); transition: width .3s cubic-bezier(.16, 1, .3, 1); }

/* One step leaves to the left as the next arrives from the right. Both halves are the same 0.3s so
   the pair reads as one movement rather than two waits. */
.wiz { transition: transform .3s cubic-bezier(.16, 1, .3, 1), opacity .3s cubic-bezier(.16, 1, .3, 1); min-height: 220px; }
.wiz.in { transform: translateX(24px); opacity: 0; }

.wiz-q { margin: 0 0 6px; font: 700 1.28rem/1.35 var(--sans); color: var(--navy); }
/* The two route-opening screens are a paragraph, not a question: same slot, reading weight instead of
   heading weight, and the fee figures land inline in the sentence. */
.wiz-q.wiz-guide { margin: 0 0 18px; font: 400 1.02rem/1.65 var(--sans); color: var(--ink-2); max-width: 62ch; }
.wiz-h, .fld-h { margin: 0 0 18px; font-size: .9rem; line-height: 1.6; color: var(--ink-3); max-width: 68ch; }
.fld { margin-bottom: 26px; }
.fld:last-child { margin-bottom: 6px; }
.fld-q { margin: 0 0 12px; font: 600 .98rem/1.4 var(--sans); color: var(--ink-2); }
.fld-h { margin: 10px 0 0; }
.fld-in { width: 100%; padding: 14px 16px; min-height: 48px; border: 1px solid var(--line-2); border-radius: var(--r);
  font: 400 1rem/1.4 var(--sans); color: var(--ink); background: var(--surface); }
.fld-in:focus { outline: none; border-color: var(--blue); box-shadow: 0 0 0 3px rgba(10, 37, 64, .13); }
textarea.fld-in { resize: vertical; min-height: 88px; }

.opts { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
.opts.multi { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.opt { display: flex; flex-direction: column; align-items: flex-start; gap: 4px; width: 100%; text-align: left;
  min-height: 56px; padding: 15px 18px; background: var(--surface); border: 1.5px solid var(--line-2);
  border-radius: var(--r); cursor: pointer; transition: border-color .18s ease, background .18s ease, box-shadow .18s ease; }
.opt:hover { border-color: var(--blue); box-shadow: var(--shadow-sm); }
.opt.on { border-color: var(--blue); background: var(--brand-100); box-shadow: inset 0 0 0 1px var(--blue); }
.opt-t { font: 600 .96rem/1.35 var(--sans); color: var(--navy); }
.opt-n { font-size: .8rem; color: var(--ink-3); }
.opt:focus-visible { outline: 2px solid var(--blue); outline-offset: 2px; }
.free { display: block; margin-top: 12px; }
.free .fld-in, .free input { width: 100%; padding: 12px 14px; min-height: 48px; border: 1px solid var(--line-2);
  border-radius: var(--r); font: 400 .95rem/1.4 var(--sans); }

.wiz-foot { display: flex; align-items: center; justify-content: space-between; gap: 14px; margin-top: 24px;
  padding-top: 20px; border-top: 1px solid var(--line); }
.wiz-foot .btn { min-height: 48px; }
.wiz-foot .btn[hidden] { visibility: hidden; }
.wiz-actions { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 22px; }
/* The dot between the two links belongs to the pair, not to either one: when the placeholder
   email is removed the remaining link must not be left holding a leading separator. */
.later-links > a + a::before { content: "·"; margin: 0 .5em; color: var(--ink-3); }

/* The safety line above the progress bar. It is not a step and not a button: static, small, grey, and
   deliberately quieter than the red block it replaced, so a patient reads it on the way in rather than
   being stopped on the way through. */
.safety-note { margin: 0 0 20px; padding: 12px 14px; max-width: 78ch;
  background: var(--color-ice); border: 1px solid var(--color-border); border-radius: 10px;
  font-size: .84rem; line-height: 1.6; color: var(--ink-2); }

.review { margin: 20px 0 0; display: grid; gap: 0; }
.review > div { display: grid; grid-template-columns: minmax(120px, 34%) minmax(0, 1fr); gap: 14px;
  padding: 12px 0; border-bottom: 1px solid var(--line); }
.review dt { margin: 0; font: 600 .84rem/1.4 var(--sans); color: var(--ink-3); }
.review dd { margin: 0; font-size: .95rem; line-height: 1.5; color: var(--ink); overflow-wrap: anywhere; }
.consent { margin-top: 20px; padding: 16px; background: var(--surface-2); border-radius: var(--r); }
.chk { display: flex; align-items: flex-start; gap: 12px; cursor: pointer; font-size: .92rem; line-height: 1.55; color: var(--ink-2); }
.chk input { width: 20px; height: 20px; margin: 2px 0 0; flex: none; accent-color: var(--blue); }
.done-h { margin: 6px 0 10px; font: 700 1.4rem/1.3 var(--sans); color: var(--navy); }
.done-b { margin: 0 0 16px; font-size: 1rem; line-height: 1.6; color: var(--ink-2); max-width: 62ch; }

@media (max-width: 768px) {
  .intake { padding: 20px 18px; border-radius: var(--r); }
  .opts, .opts.multi { grid-template-columns: minmax(0, 1fr); }
  .wiz-q { font-size: 1.12rem; }
  .review > div { grid-template-columns: minmax(0, 1fr); gap: 4px; }
  .wiz-foot .btn { flex: 1 1 auto; }}
@media (prefers-reduced-motion: reduce) {
  .wiz, .prog-bar > i { transition: none; }
  .wiz.in { transform: none; opacity: 1; }}

/* =============================================================
   v11 — patient-first hospital profile, honour list, wall grid,
   rail masks, always-fixed header
   ============================================================= */

/* ---- header: pinned above everything, glass and shadow from the first pixel ----
   It stays `sticky` rather than `fixed`: below 920px the nav becomes a second row, so a fixed header
   would need a padding value that changes with the viewport, and the page would slide under it. */
.top { z-index: 1000; background: rgba(255, 255, 255, .85); box-shadow: 0 1px 3px rgba(0, 0, 0, .06); }

/* ---- the strip: a narrower column of long cards, fading at both ends ---- */
/* The 900px cap lives on the wrapper, not on the scroller: padding percentages resolve against the
   containing block, so capping the rail itself made the card width chase its own padding and the
   cards collapsed to a column of one-word lines on wide screens. */
#hospitals .rail-wrap { max-width: 900px; margin: 0 auto; }
#hospitals .rail { max-width: none; }
.rail-wrap::before, .rail-wrap::after { content: ""; position: absolute; top: 0; bottom: 0; width: 60px;
  pointer-events: none; z-index: 10; }
.rail-wrap::before { left: 0; background: linear-gradient(to right, #FFFFFF 0%, transparent 100%); }
.rail-wrap::after { right: 0; background: linear-gradient(to left, #FFFFFF 0%, transparent 100%); }
.card-brief { display: -webkit-box; -webkit-line-clamp: 2; line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden; margin: 8px 0 0; font-size: .86rem; line-height: 1.5; color: var(--ink-2); }

/* ---- the profile: four facts a patient compares, before any prose ---- */
.hosp-cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: 14px; margin-top: 24px; }
.hcard { background: var(--surface); border: 1px solid var(--line); border-left: 3px solid var(--teal);
  border-radius: var(--r); padding: 16px 18px; box-shadow: var(--shadow-sm); }
.hcard-k { margin: 0; font: 700 .68rem/1.3 var(--sans); letter-spacing: .1em; text-transform: uppercase; color: var(--ink-3); }
.hcard-v { margin: 7px 0 0; font: 700 1.12rem/1.32 var(--sans); color: var(--navy); }

/* ---- strengths: the first thing a patient reads, sized like it ---- */
.str-tags { display: flex; flex-wrap: wrap; gap: 12px; margin: 0 0 16px; padding: 0; list-style: none; }
.str-tags li { padding: 14px 22px; border-radius: 999px; background: var(--brand-100);
  color: var(--navy); font: 700 1.02rem/1.2 var(--sans); }

/* ---- honours: one claim per row, so none of them can hide inside a paragraph ---- */
.honours { display: grid; gap: 12px; margin: 0 0 24px; padding: 0; list-style: none; }
.honours li { display: flex; align-items: flex-start; gap: 14px; background: var(--surface);
  border: 1px solid var(--line); border-radius: var(--r); padding: 16px 18px; box-shadow: var(--shadow-sm); }
.hon-dot { flex: none; width: 10px; height: 10px; margin-top: 7px; border-radius: 50%; background: var(--teal); }
.honours p { margin: 0; font-size: .95rem; line-height: 1.6; color: var(--ink-2); max-width: 84ch; }

/* ---- the action that follows the patient down the page ---- */
.cta-dock { position: fixed; left: 0; right: 0; bottom: 0; z-index: 900; padding: 12px 0;
  background: rgba(255, 255, 255, .92); backdrop-filter: saturate(180%) blur(12px);
  -webkit-backdrop-filter: saturate(180%) blur(12px); border-top: 1px solid var(--line); }
.cta-dock[hidden] { display: none; }
.cta-dock-in { display: flex; align-items: center; justify-content: space-between; gap: 18px; }
.cta-dock-t { margin: 0; font-size: .86rem; line-height: 1.5; color: var(--ink-3); max-width: 52ch; }
@media (max-width: 768px) {
  .cta-dock-in { flex-direction: column; align-items: stretch; gap: 10px; }
  .cta-dock .btn { min-height: 48px; text-align: center; }
  .hosp-cards { grid-template-columns: repeat(2, minmax(0, 1fr)); }}

/* =============================================================
   v12 — fixed header, 30px rise-in, hero steps, wall in flow,
   coverflow rail
   ============================================================= */

/* ---- header: out of the flow entirely, so it follows every scroll on every page ----
   `--head-h` is written by layout.js from the header's own measured height, because below 920px the
   nav drops to a second row and a hard-coded padding would either clip the page or leave a gap. */
.top { position: fixed !important; top: 0 !important; left: 0 !important; width: 100% !important;
  z-index: 9999 !important; background: rgba(255, 255, 255, .9) !important;
  backdrop-filter: saturate(180%) blur(12px) !important; -webkit-backdrop-filter: saturate(180%) blur(12px) !important;
  box-shadow: 0 1px 3px rgba(0, 0, 0, .06) !important; }
body { padding-top: var(--head-h, 74px); }
html { scroll-padding-top: calc(var(--head-h, 74px) + 16px); }
@media (max-width: 920px) { html { scroll-padding-top: calc(var(--head-h, 130px) + 12px); }}
.hero { padding-top: 40px; }

/* ---- hero panel: figures on top, the three steps under them, spread to fill ---- */
.hero-panel { justify-content: space-between; }
/* The three steps are a table of two columns, not three centred lines. Each row is a flex line as wide
   as the panel; the plate is a fixed 40px box that cannot be squeezed, and only the text takes the
   remaining width. That is what puts all three plates on one vertical line — centring each row on its
   own left its plate at a different x for every sentence length, which is what read as amateur. */
/* The three steps are a column that centres itself in the panel: `align-items: center` moves the group,
   and each row is capped at 400px so the icon and its sentence stay one unit instead of drifting to the
   panel's two edges on a wide screen. The heading above is centred, so the group lines up under it. */
.panel-steps { list-style: none; margin: 0 auto; padding: 0; width: max-content; max-width: 100%;
  display: flex; flex-direction: column; align-items: stretch; gap: 16px; }
.panel-steps li { display: grid; grid-template-columns: 40px max-content; align-items: center; gap: 0 16px; }
.ps-ic { flex: none; flex-shrink: 0; display: flex; justify-content: center; align-items: center; width: 40px; height: 40px; border-radius: 10px;
  background: rgba(255, 255, 255, .12); border: 1px solid rgba(255, 255, 255, .2); color: #fff; }
.ps-ic svg { width: 20px; height: 20px; }
.ps-t { flex: 1 1 auto; text-align: left; font-size: .84rem; line-height: 1.45; color: rgba(255, 255, 255, .72); }

/* ---- the strip: a coverflow, centre card solid, neighbours pushed back and blurred ---- */
/* The card width is one variable so the padding that centres the first and last card cannot drift
   out of step with it: without that leading and trailing space the opening card sits flush left and
   the coverflow looks broken on arrival. */
.rail { --cw: min(560px, 84vw); scroll-snap-type: x mandatory; padding-inline: calc((100% - var(--cw)) / 2); }
.rail-wrap::before, .rail-wrap::after { width: 80px; }
.rail-wrap::before { background: linear-gradient(to right, var(--color-bg) 0%, transparent 100%); }
.rail-wrap::after { background: linear-gradient(to left, var(--color-bg) 0%, transparent 100%); }
.rail > .slide-item { flex: 0 0 var(--cw); scroll-snap-align: center; }
.rail > .slide-item > .hosp { width: 100%; }
.rail .slide-item { transform: scale(.9); opacity: .4; filter: blur(2px); z-index: 5;
  transition: transform .3s cubic-bezier(.16, 1, .3, 1), opacity .3s cubic-bezier(.16, 1, .3, 1), filter .3s ease; }
.rail .slide-item.is-centre { transform: scale(1); opacity: 1; filter: blur(0); z-index: 10; }
@media (max-width: 920px) { .rail { --cw: min(560px, 84vw); }}
@media (prefers-reduced-motion: reduce) {
  .rail .slide-item { transition: none; filter: none; }
  .rail .slide-item:not(.is-centre) { opacity: .55; transform: scale(.94); }}

/* ---- emblems: fit the plate on BOTH axes ----
   Every emblem we held was a horizontal lockup, so `width:100%` plus an automatic height was enough.
   The owner's own files include square circular seals, and an automatic height let them grow past the
   plate and be clipped by overflow:hidden — which is the cropping he forbade. `max-height:100%` did
   not bind on a centred grid item, so the image now gets a definite box and `contain` letterboxes
   any aspect ratio inside it: square seals and 10:1 lockups both fit without losing a pixel. */
.hosp .hosp-mark img { position: absolute; inset: 10px; width: calc(100% - 20px); height: calc(100% - 20px);
  max-width: none; max-height: none; object-fit: contain; object-position: center; }

/* =============================================================
   v13 — panel filled, slower rise, wider cards, wall behind the words
   ============================================================= */

/* ---- hero panel: centred as one block, with a line joining the figures to the steps ---- */
.hero-panel { justify-content: center; gap: 24px; }
.panel-divider { width: 2px; height: 24px; margin: 0 auto; border-radius: 2px; background: rgba(255, 255, 255, .2); flex: none; }

/* ---- the strip: as wide as the copy above it, and the card breathes ---- */
#hospitals .rail-wrap { max-width: 1100px; }
.rail { --cw: min(720px, 88vw); }
#hospitals .rail > .slide-item > .hosp { padding: 24px 32px; }

/* ---- the heading card: flat white, lifted, and above whatever is behind the band ---- */
#hospitals .sec-head { position: relative; z-index: 2; background: #fff; backdrop-filter: none;
  -webkit-backdrop-filter: none; margin-block: 0 22px; padding: 40px; border-radius: 16px; }
@media (prefers-reduced-motion: reduce) {
  /* The neighbours are neighbours by size alone: no fade, no blur. */
  #hospitals .rail .slide-item { filter: none; opacity: 1; transform: none; }}
@media (max-width: 768px) {
  #hospitals .rail > .slide-item > .hosp { padding: 18px; }
  /* Phone: every card is solid and the arrows never disappear — on a 390px screen a card that is
     dimmed to 40% just looks like a second-class card, and the swipe affordance is not obvious. */
  #hospitals .rail .slide-item,
  #hospitals .rail .slide-item.is-centre { filter: none; opacity: 1; }
  #hospitals .rail .slide-item:not(.is-centre) { transform: scale(.94); }
  /* The white caps at either end of the strip are a fade by another name: on a phone they veil the
     neighbouring card the patient is about to swipe to, so they go. */
  .rail-wrap::before, .rail-wrap::after { display: none; }
  /* Arrows: always there, never on top of the card. A 390px screen gives the card almost the whole
     width, so a side-mounted control lands on the hospital's name — the one thing on the card that
     must not be covered. They sit under the strip instead, one at each end. */
  #hospitals .rail { padding-bottom: 62px; }
  .rail-prev { left: 0; }
  .rail-next { right: 0; }}

/* ---- hero panel: the three steps are a list the patient has to do, so they are labelled ---- */
.panel-steps-h { margin: 0; text-align: center; white-space: nowrap; font: 800 clamp(.92rem, 1.15vw, 1.02rem)/1.2 var(--sans); letter-spacing: .04em; text-transform: uppercase;
  color: rgba(255, 255, 255, .55); }
@media (max-width: 768px) {
  .hero-panel { text-align: center; }}

/* =============================================================
   v14 — phone sweep: nothing that must be read renders under 14px,
   nothing that must be tapped renders under 48px, and one word can
   no longer widen the page
   ============================================================= */
@media (max-width: 768px) {
  /* A URL, an email or a long English compound is one unbreakable token; left alone it widens the
     scroll area of whatever box holds it. `overflow-wrap: break-word` is the form that works: both
     `word-break: break-word` and `overflow-wrap: anywhere` also feed the browser's minimum-content
     maths, and measured on /comparison.html either one collapsed an auto-layout table column to a
     single letter per line. The elements that really do hold unbreakable tokens get the strong rule. */
  body { overflow-wrap: break-word; }
  .srcline, .review dd, .fld-in, .later-links a, .honours li, .spec-list li { overflow-wrap: anywhere; }
  /* The classes below are body copy, not labels: at their desktop size they render 12.8–13.4px, which
     is unreadable on a phone held at arm's length. Micro-labels (.meta, .eyebrow, .tag, .grade) keep
     their size on purpose — they are wayfinding, not text to read. */
  .hint, .note, .detail, .caveat, .opt-n, .review dt, .fineprint li, .tl-compact li, .tl-compact .n,
  .flags li, .placeholder-flag, .srcline, .compare dd.sub, .compare .sub, .count, .breakdown,
  .hosp-body p, .stat .u, .route ul, .route .docs, .cats, .ps-t, .panel-note, .split-cta span,
  .readout.empty, .wiz-h, .fld-q, .cell p, .pillar p, .spec-list li, .step-lede, .step-points li,
  .btn, .btn.sm, .textbtn, .mark-cta, .chip, .hosp-go, .done-b, .langsel, footer.site .disclaim,
  .role-card .btn.glass { font-size: .875rem; }
  /* The uppercase pills are wayfinding, not copy, so they keep their small-caps role — but at 10.6px
     on a phone they were below the point where a Chinese label stops being legible at arm's length. */
  .hosp-facts span, .journey .when, .tag, .badge, .grade, .driver-tag, .meta, .eyebrow, .kicker,
  .subhead, .proof dt, .stat .k, .standards dt, .compare dt, .field label,
  footer.site h4 { font-size: .75rem; }
  /* The nav row is the one place a 43px link was still 5px short of a thumb. */
  .nav-links > a { min-height: 48px; }
  /* Uniform rhythm: every stacked container uses the same 16px pitch so a section does not alternate
     between 8, 12, 20 and 28px gaps on the way down the page. */
  .opts, .wiz-actions, .hero-actions, .cta-row, .panel-steps, .hosp-cards, .honours, .str-tags,
  .role-cards, .faq, .budget, .scope, .wiz-foot { gap: 16px; }
  /* Tap targets. `.btn`, `.opt` and the wizard inputs are already 48px+; these are the controls whose
     height came from their text and ended up 30–40px. Static pills (.tag, .badge, .grade) are left
     alone — nothing is tapped on them, and inflating them turns a label into a false button. */
  .chip, .langsel, .view-all-link, .textbtn, .mark-cta, .later-links a {
    min-height: 48px; display: inline-flex; align-items: center; justify-content: center;
  }
  /* The header's own two controls are the one exception to that floor. They sit alone in the first row
     with nothing to align to, so two 48px pills plus the 48px nav row cost a phone a fifth of its
     viewport before the page has said anything. The site owner asked for these two smaller again
     (2026-10-16), so they are down to 32px — still above the 24px minimum, and the *text* stays at
     12.8px because shrinking the pill by taking padding is invisible while shrinking it by taking font
     size is unreadable. The height is taken by the wrapper, not the <select> inside it, or the pill's
     own padding stacks on top of the min-height. */
  .langs { min-height: 32px; padding: 0 5px 0 9px; gap: 4px; }
  .langs svg { width: 13px; height: 13px; }
  .langsel { min-height: 28px; padding: 2px; font-size: .8rem; }
  .mark-cta { min-height: 32px; padding: 0 11px; font-size: .8rem; }
  .faq-q { min-height: 48px; display: flex; align-items: center; width: 100%; }
  /* Images: a logo is contained, a photograph covers. Without this a portrait emblem in a landscape
     plate is stretched, which is the same defect he had me fix on the hospital cards. */
  .hosp-mark img, .honour-mark img { object-fit: contain; }
  .hosp-photo img, .illus img { object-fit: cover; }
  img { max-width: 100%; height: auto; }
}

/* =============================================================
   v15 — the owner's final pass: a wider gap in the hero panel,
   the emblem columns at a fixed 180px, side arrows on every
   screen, and a way back out of a hospital profile
   ============================================================= */

/* ---- hero panel: one column, centred, with real air between the three blocks ---- */
/* The panel used to be stretched to the height of the copy column, which made it a full-bleed glass
   slab down the right side — and the plate's lit "AEGIS" sign sits at the bottom right, so the slab sat
   on top of it. `align-self: start` lets the panel take its own content height instead; the band keeps
   its height because that is set by the copy column, which has not moved. */
.hero-panel { display: flex; flex-direction: column; align-self: start; justify-content: center; gap: 18px; }
/* The four figures are the tallest thing in here and they are stacked two rows deep, so the air inside
   each cell counts twice. Scoped to the panel: the same `.proof` markup on /process.html keeps its 20px. */
.hero-panel .proof > div { padding: 14px 10px; }

/* ---- emblem columns: the width is the number he set, not a share of the viewport ---- */
#hospitals { --wall-w: 180px; }

@media (max-width: 768px) {
  #hospitals .rail > .slide-item > .hosp {
    grid-template-columns: minmax(0, 1fr);
    grid-template-areas: "mark" "body" "go";
    justify-items: center; align-content: center; row-gap: 12px;
    padding: 20px 52px 18px; text-align: center;
  }
  #hospitals .rail .hosp-mark { width: 210px; height: 64px; }
  #hospitals .rail .hosp-facts { justify-content: center; }
  #hospitals .rail .hosp-go { justify-self: center; }
  #hospitals .rail { padding-bottom: 22px; }
  .rail-prev { left: 0; }
  .rail-next { right: 0; }}

/* ---- back to the hospital list: the same control at the top and the end of a profile ---- */
.back-row { margin: 18px 0 0; }
.back-row-end { margin: 28px 0 0; }
.back-to-list {
  display: inline-flex; align-items: center; gap: 8px; padding: 10px 20px;
  border: 1px solid var(--navy); border-radius: 8px; background: #fff; color: var(--navy);
  font: 600 .92rem/1.2 var(--sans); text-decoration: none;
  transition: background-color .2s ease, color .2s ease, border-color .2s ease;
}
.back-to-list:hover { background: var(--navy); color: #fff; }
.back-to-list:focus-visible { outline: 2px solid var(--blue); outline-offset: 3px; }
.back-to-list .btl-a { font-weight: 700; }
.back-row-end .back-to-list { padding: 12px 24px; }
@media (max-width: 768px) {
  /* The wrap already gives 20px at either edge; the button takes the width it needs and no more. */
  .back-to-list { max-width: 100%; }}


/* =============================================================
   v16 — one cool grey page, white cards that lift off it, hairline
   band separation, the emblem wall as a masked background layer,
   and the way back out pushed to the right
   ============================================================= */

/* The v16 grey palette and its hairline band separation were removed outright rather than overridden
   from below: two `:root` blocks arguing about the same token is how a future edit gets the wrong
   colour. The ice-blue system in v17 owns these values now. */

/* ---- the heading card on the hospital band ---- */
#hospitals > .wrap { position: relative; z-index: 2; }
#hospitals .sec-head { margin-inline: 0; background: #fff; border: 1px solid var(--color-border);
  box-shadow: var(--shadow-sm); }

/* ---- the way back out: right-aligned at both ends of the profile ---- */
.back-row { display: flex; justify-content: flex-end; }

/* ---- contrast on the new grey ----
   Measured against white and the 3% navy wash: navy headings 15.4:1 / 15.0:1, body 16.9:1,
   clear of AA. The bright accent #00A3A1 is 3.0:1, which is fine for a rule, a dot or a focus ring
   and not fine for a word to read, so the one place it carried body-size text now carries the dark
   stop instead. The primary button still paints white on #00A3A1 (3.0:1) — that is a brand decision
   left standing, not an oversight: one token, --color-accent: #00807E, fixes it everywhere. */
.view-all-link { color: var(--color-accent-d); }
.view-all-link:hover { color: var(--color-primary); }

/* =============================================================
   v17 — the ice-blue system. Every grey from v16 is gone: the page
   alternated pure white with a cold tint, and cards carry a
   navy-tinted shadow instead of a black one.
   ============================================================= */

:root {
  /* Superseded by v18, which derives the light background from the brand navy at three per cent.
     Kept here only so the ordering of the two blocks is legible: v18 wins on source order. */
  --color-page: #FFFFFF;
  --color-border: #E2E8F0;
  --color-border-2: #C6D3E3;
  /* Both shadows are built on the brand navy — rgba(10,37,64,…) — never on black or neutral grey.
     Every card already reads these two tokens for its resting and hover state, so the lift changes
     in one place. */
  --shadow-sm: 0 2px 8px rgba(10, 37, 64, .04);
  --shadow-md: 0 10px 25px -5px rgba(10, 37, 64, .12);
  --card-ease: .3s cubic-bezier(.16, 1, .3, 1);
}
body { background: var(--color-page); }
/* The boundary between bands is the cold blue itself, so the grey hairline from v16 goes away. */
.band.alt { background: var(--color-ice); }
.band + .band { border-top: 0; }
/* Anything v16 painted slate now paints ice; the pale-green callouts stay neutralised. */
.savings, .placeholder-flag, .faq-icon { background: var(--color-ice); }
.savings { border-color: var(--color-border); }
.compare .here { background: linear-gradient(180deg, var(--color-ice), #fff); }

/* ---- cards: white on the ice, navy hairline at rest, navy border and a lifted shadow on hover ----
   The hover border is the deep brand blue rather than the teal accent: against a blue-tinted shadow
   the teal competes with the small accent marks, the navy reads as one system. `.view-all-link` and
   the dots keep the teal. */
.card, .hosp, .cell, .pillar, .faq-card, .hcard, .stat, .journey > li, .split-cta a, .panel {
  background: #FFFFFF; border: 1px solid var(--color-border); box-shadow: var(--shadow-sm);
  transition: transform var(--card-ease), box-shadow var(--card-ease), border-color var(--card-ease);
}
.card:hover, .card:focus-within, .hosp:hover, .hosp:focus-visible, .cell:hover, .pillar:hover,
.faq-card:hover, .faq-card.is-open, .journey > li:hover, .split-cta a:hover,
.card.is-focus, .hosp.is-focus, .cell.is-focus, .pillar.is-focus, .faq-card.is-focus,
.journey > li.is-focus, .split-cta a.is-focus {
  border-color: #0A2540; box-shadow: var(--shadow-md); transform: translateY(-4px);
}
/* The FAQ card opens by expanding its own grid row, so it lifts without scaling: the scale from v5
   made the text reflow one letter at a time on a phone. */
.faq-card.is-open { transform: translateY(-4px); }
/* The strip's own coverflow already scales its neighbours; a card inside it must not fight that. */
#hospitals .rail .slide-item > .hosp:hover { transform: translateY(-4px); }

/* ---- the emblem wall: barely there on a white band ---- */
#hospitals { background: #FFFFFF; }
/* The strip's edge fades sit on this band, so they have to be the band's own white. */
.rail-wrap::before { background: linear-gradient(to right, #FFFFFF 0%, transparent 100%); }
.rail-wrap::after { background: linear-gradient(to left, #FFFFFF 0%, transparent 100%); }

/* ---- /hospital.html: the page is ice, every block on it is a white card ---- */
body[data-page="hospital"] { background: var(--color-ice); }
body[data-page="hospital"] .band.alt { background: transparent; }
body[data-page="hospital"] main > section + section > .wrap {
  background: #FFFFFF; border: 1px solid var(--color-border); border-radius: 16px;
  box-shadow: var(--shadow-sm); padding: 30px 34px 32px; margin-inline: var(--gutter);
  transition: box-shadow var(--card-ease), border-color var(--card-ease);
}
body[data-page="hospital"] main > section + section > .wrap:hover,
body[data-page="hospital"] main > section + section > .wrap.is-focus {
  border-color: #0A2540; box-shadow: var(--shadow-md);
}
@media (max-width: 768px) {
  body[data-page="hospital"] main > section + section > .wrap { padding: 22px 18px 24px; border-radius: var(--r); }}

/* =============================================================
   v18 — the arrows rebuilt from nothing, and the light background
   derived from the brand navy instead of chosen as a hex
   ============================================================= */

/* ---- the arrow ----
   The old control was styled by sixteen rules spread over four version blocks, and it shared a
   stacking level with the strip's own white edge-fade — which is what painted half of the right-hand
   glyph white. It is now one class with one state each. Centring uses margin, not transform, so the
   hover scale no longer has to restate a translateY every time it is written. */
.slide-arrow {
    width: 40px;
    height: 40px;
    border-radius: 50%;
    background: #FFFFFF; /* 默认白底 */
    color: #0A2540;      /* 默认深蓝文字 */
    border: 1px solid #E2E8F0;
    font-size: 18px;
    font-weight: bold;
    display: flex;
    justify-content: center;
    align-items: center;
    cursor: pointer;
    box-shadow: 0 2px 8px rgba(10, 37, 64, 0.06);
    transition: background-color 0.2s ease, color 0.2s ease, border-color 0.2s ease,
                transform 0.2s ease, opacity 0.2s ease, box-shadow 0.2s ease;
}
.slide-arrow:hover {
    background: #0A2540; /* 悬停直接切换为深蓝底 */
    color: #FFFFFF;      /* 悬停文字纯白 */
    border-color: #0A2540;
    transform: scale(1.05); /* 轻微放大 */
}
.slide-arrow:disabled {
    opacity: 0.3;
    cursor: not-allowed;
}
/* Placement only — everything the control looks like is in the block above. */
#hospitals .rail-wrap { position: relative; }
#hospitals .slide-arrow { position: absolute; top: 50%; margin-top: -20px; z-index: 12; padding: 0; line-height: 1; }
#hospitals .rail-prev { left: -14px; }
#hospitals .rail-next { right: -14px; }
/* The edge fades are the bug: a pseudo-element on the wrapper paints after its children at an equal
   stacking level, so the white wash sat on top of the arrow. They belong under the control. */
.rail-wrap::before, .rail-wrap::after { z-index: 1; }
@media (max-width: 768px) {
  #hospitals .rail-prev { left: 0; }
  #hospitals .rail-next { right: 0; }}

/* ---- light backgrounds: one source, the brand navy at three per cent ----
   No hex is picked for a band any more. rgba(10,37,64,.03) composited over white is the same hue as
   the headings by construction, so it cannot drift green or grey on a different panel, and there is
   no second colour left to keep in sync. */
:root {
  --color-ice: rgba(10, 37, 64, .03);
  --color-bg-alt: rgba(10, 37, 64, .03);
  --color-wall: rgba(10, 37, 64, .03);
  /* The card's resting shadow moves to the same source at four per cent. */
  --shadow-sm: 0 4px 12px rgba(10, 37, 64, .04);
}
.section-light { background-color: rgba(10, 37, 64, 0.03); }
.card { box-shadow: 0 4px 12px rgba(10, 37, 64, 0.04); }
/* The hospitals band stays pure white, as specified; every other light band is the navy wash. */
#hospitals { background: #FFFFFF; }
/* =============================================================
   v19 — the phone tier rebuilt, the comparison table stacked into
   cards, the FAQ made to open downwards only, and the emblem wall
   deleted outright
   ============================================================= */

/* ---- 1. one column, everywhere, on a phone ----
   Every container that lays out in columns on a desktop is flattened here. The list is explicit
   rather than a wildcard because a wildcard would also flatten the number-and-text columns that are
   meant to stay side by side. */
@media (max-width: 768px) {
  .cols, .cols.c2, .cols.c3, .pillars, .pillars.c3, .hosp-grid, .hosp-cards, .stat-row,
  .standards, .split-cta, .role-cards, .hero-inner, .compare, .svc-grid, .grid-2, .grid-3 {
    grid-template-columns: minmax(0, 1fr);
  }
  .hero-actions, .cta-row, .wiz-foot, .later-links, .head-links { flex-direction: column; }
  /* Nothing sits against the glass: one padding and one box model for every card on a phone. */
  .card, .cell, .pillar, .faq-card, .hosp, .hcard, .stat, .panel, .intake, .consent,
  .cats tbody tr, .svc, .role-card {
    box-sizing: border-box; width: 100%; max-width: 100%; padding: 16px;
  }
  .faq { gap: 12px; }
  /* A long English compound must wrap at the space, not in the middle of a word. `break-word` on the
     container and `normal` on the break mode is the pair that does that; the site has no `break-all`
     anywhere, which is what produces the letter-by-letter columns. */
  h1, h2, h3, h4, p, li, dd, dt, td, th, a, span, b, label, figcaption, caption {
    word-break: normal; overflow-wrap: break-word; white-space: normal;
  }
}

/* ---- 2. /comparison.html: the table stops being a table on a phone ----
   Nine columns at a 1080px minimum inside a horizontal scroller is the single most desktop thing on
   the site. Each row becomes its own card and each cell carries the header it belongs to, which the
   builder now emits as `data-col`. */
@media (max-width: 768px) {
  /* Only the host of the stacked table is taken out of the scroller. Every other table on the site —
     the routes table, the coordinator list on /leads.html — keeps `overflow-x: auto` and scrolls
     inside itself; releasing those is what widened the page past the viewport. */
  #cmp-table { overflow-x: visible; }
  .cats { display: block; min-width: 0; width: 100%; border-spacing: 0; }
  .cats caption, .cats thead { display: none; }
  .cats tbody, .cats tr, .cats td, .cats th { display: block; width: 100%; }
  .cats tbody tr {
    background: #FFFFFF; border: 1px solid #E2E8F0; border-radius: 8px;
    box-shadow: 0 2px 8px rgba(10, 37, 64, .06); padding: 16px; margin: 0 0 16px;
  }
  .cats td { padding: 7px 0; border: 0; font-size: .875rem; }
  .cats td + td { border-top: 1px solid #E2E8F0; }
  .cats td::before {
    content: attr(data-col); display: block; margin-bottom: 3px;
    font: 800 .68rem/1.35 var(--sans); letter-spacing: .09em; text-transform: uppercase; color: var(--ink-3);
  }
  /* The first cell is the row's title, so it gets no label and a bigger voice. The sticky column from
     the desktop table would otherwise pin a 200px block over the card. */
  .cats td:first-child { font-size: 1rem; position: static; min-width: 0; background: #FFFFFF; padding-top: 0; }
  .cats td:first-child::before { display: none; }
  .cats td:last-child { padding-bottom: 0; }
  .cats .badge, .cats .brass { display: inline-block; white-space: normal; }
}

/* ---- 3. /hospital.html: the name gets the whole row ----
   The plate and the words used to share a 260px + 1fr grid down to phone width, which left the name
   57px and wrapped it one letter at a time. On a phone the plate sits above the words. */
@media (max-width: 768px) {
  .hosp-hero { display: block; }
  .hosp-hero .hosp-mark { width: 100%; max-width: 220px; height: 64px; margin: 0 auto 16px; }
  .hosp-hero h1 { width: 100%; font-size: 1.42rem; margin: 0 0 8px; }
  .hosp-hero > div { width: 100%; display: block; max-width: none; }
  .hosp-brief { width: 100%; display: block; max-width: none; }
  .hosp-cards { display: grid; grid-template-columns: minmax(0, 1fr); gap: 12px; }
  .hosp-body h3 { font-size: 1.06rem; }
}

/* ---- 4. the FAQ opens downwards, and only downwards ----
   `is-open` used to scale the card by 1.02 and v17 lifted it four pixels. Both move the card's top
   edge, so the answer that grows below it reads as the card expanding upward. The height transition is
   `grid-template-rows: 0fr -> 1fr` on the answer row, which can only ever push content down; the card
   itself now holds completely still. */
.faq-card, .faq-card:hover, .faq-card.is-open, .faq-card:focus-within, .faq-card.is-focus { transform: none; }
.faq-card.is-open { z-index: 1; }
/* Switching from one panel to another: the closing card collapses with no transition at all, so
   site.js can measure the height it gave back and hand the scroll offset to the card that was tapped.
   Without this the collapse animates over 0.3s while the new answer grows, and the question under the
   finger drifts upward for the length of both. */
.faq-card.no-anim, .faq-card.no-anim .faq-a, .faq-card.no-anim .faq-body,
.faq-card.no-anim .faq-sign::before, .faq-card.no-anim .faq-sign::after { transition: none; }
/* On a touchscreen a hover state sticks after the tap, so the lift that reads as feedback on a laptop
   leaves a card parked four pixels high on a phone. Touch keeps the border and the shadow, loses the
   movement. */
@media (hover: none), (pointer: coarse) {
  .card, .hosp, .cell, .pillar, .faq-card, .journey > li, .split-cta a, .hcard, .stat,
  .role-card, .btn, .textbtn, .chip { transform: none; }
}

/* ---- 6. centred copy blocks ---- */
/* "Where you are treated": the heading and its standfirst are centred on the band, not pushed to the
   left gutter beside a link that no longer has anything to sit against. */
#hospitals .sec-head { display: block; text-align: center; margin-inline: auto; max-width: 950px; }
#hospitals .sec-head > div { max-width: 950px; margin-inline: auto; }
#hospitals .sec-head h2, #hospitals .sec-head p { margin-left: auto; margin-right: auto; }
#hospitals .sec-head .eyebrow { text-align: center; }
/* The standfirst used to wrap three words onto its last line because the measure was set for a
   narrower column than the band. `pretty` breaks the long paragraph without orphans, and `hyphens:
   none` keeps a medical sentence from being split mid-word for a patient reading in a second language. */
#hospitals .sec-head p:not(.eyebrow) { max-width: 950px; text-wrap: pretty; hyphens: none; }
/* The closing note under the strip carried the page's full width while the heading above it was
   capped, so its last line — the one with the two links — broke after two words. Same measure now. */
#hospitals > .wrap > .note { max-width: 950px; margin-left: auto; margin-right: auto; text-wrap: pretty; hyphens: none; }
#hospitals .view-all-link { justify-content: center; margin-top: 18px; padding-bottom: 0; }
/* The hero panel's task list is centred by its own rule further up; nothing overrides it here. */

/* The coordinator queue: its table has more columns than a phone has pixels. The wrapper is already a
   scroll container, so the fix is to stop the toolbar above it from setting the page width instead. */
@media (max-width: 768px) {
  .toolbar { flex-wrap: wrap; }
  .toolbar > * { max-width: 100%; }
  #table-wrap { max-width: 100%; }
  #f-q { width: 100% !important; }
}

/* =============================================================
   v20 — the animation, the two left-leaning pages, and the caveat cards
   ============================================================= */

/* ---- 1. the entrance animation, in one place, at the end of the file ----
   It has to be the last word: `.card` and friends declare their own `transition` shorthand earlier,
   and a reveal rule that sits above them is simply overwritten — which is why some bands looked like
   they popped into existence instead of rising.
   Two properties are named and nothing else. `all` was what made the animation expensive: it dragged
   box-shadow, border and any layout property into the same transition, and every one of those is a
   repaint or a reflow on every frame of the entrance. Layout never animates here — opacity and
   transform are the only two the compositor can move without asking the layout engine anything.
   The unit is a content block — a direct child of a band's `.wrap` (layout.js derives them from the DOM,
   so a heading, a lede, a card grid and a closing paragraph each arrive on their own).
   The three blocks inside one band arrive a breath after each other (`--unit-delay`, capped at three by
   layout.js), because a band whose heading and grid are both tall otherwise crosses the trigger line as
   one slab and the whole entrance reads as nothing.
   No `will-change` any more, and that is a load decision, not a style one: declaring it promotes every
   tagged block at parse time, which on a phone means eighteen composited layers — most of them taller
   than the screen — held for blocks the visitor has not scrolled to yet. A block that is mid-transition
   is promoted by the browser on its own, which is exactly when the layer is worth having. */
.reveal {
  opacity: 0;
  transform: translateY(44px);
}
.reveal.visible {
  opacity: 1;
  transform: translateY(0);
  /* The transition lives on the arriving state, not on the hidden one, and that ordering is the whole
     point. A transition reads its properties from the style the element is moving *to*, so hiding a
     block is instant while releasing it animates. Declared on `.reveal` instead, every block on the
     page first played a fade-out from the state the browser had already painted — the page appeared,
     dimmed away, then came back: what looked like "no entrance animation" on every page but the home.
     1.15s on an ease-out quint: at 0.8s with the old expo curve a block was finished arriving before
     the eye reached it on a normal wheel scroll, which read as snapping rather than settling. */
  transition: opacity 1.15s cubic-bezier(0.22, 1, 0.36, 1) calc(var(--unit-delay, 0) * .11s),
              transform 1.15s cubic-bezier(0.22, 1, 0.36, 1) calc(var(--unit-delay, 0) * .11s);
}
/* A block that is taller than the window — a comparison table, a cost card at a short viewport — has no
   edge the visitor is looking at while it slides, so the slide buys nothing and the block reads as
   having arrived late. It fades instead, which is visible across every row of it at once. */
.reveal.tall, .reveal.tall.visible { transform: none; }

/* ---- the first screen: CSS only, so it plays on open ----
   A load animation that waits for script has to hide the page first, and the visitor watches the
   finished page blink out and rebuild. So the opening band is animated by `animation`, which starts at
   parse time with no class to wait for, and layout.js is told to leave `.hero` and `.page-hero-dark`
   alone (REVEAL_ONLOAD). `backwards` holds the from-state through the delay, so the staggered pieces
   are genuinely absent rather than painted and then moved. */
@keyframes rise-in {
  from { opacity: 0; transform: translateY(44px); }
  to { opacity: 1; transform: translateY(0); }
}
.hero .hero-inner > *, .page-hero-dark > .wrap > * {
  animation: rise-in 1.15s cubic-bezier(0.22, 1, 0.36, 1) backwards;
}
.hero .hero-inner > :nth-child(2), .page-hero-dark > .wrap > :nth-child(2) { animation-delay: .14s; }
.hero .hero-inner > :nth-child(3), .page-hero-dark > .wrap > :nth-child(3) { animation-delay: .28s; }
.hero .hero-inner > :nth-child(n+4), .page-hero-dark > .wrap > :nth-child(n+4) { animation-delay: .42s; }
/* Inside a section, the card grids still cascade: JS puts `--delay` (0,1,2…) on each card and marks the
   grid `data-stagger`, so the cards settle in 0.07s apart while the band itself rises. The hidden state
   is scoped to `:not(.visible)`, which leaves the resting state to the card's own rules — that is what
   keeps a card's hover lift (`.card:hover`, two classes) outranking this. The shadow and border are
   repeated into the shorthand so the hover feedback does not snap. */
[data-stagger] > * {
  transition: opacity .85s cubic-bezier(0.22, 1, 0.36, 1), transform .85s cubic-bezier(0.22, 1, 0.36, 1),
              box-shadow var(--card-ease), border-color var(--card-ease);
  transition-delay: calc(var(--delay, 0) * .09s), calc(var(--delay, 0) * .09s), 0s, 0s;
}
.reveal:not(.visible) [data-stagger] > *,
.reveal[data-stagger]:not(.visible) > * { opacity: 0; transform: translateY(18px); }
@media (prefers-reduced-motion: reduce) {
  .reveal, .reveal:not(.visible), .reveal:not(.visible) [data-stagger] > *,
  .reveal[data-stagger]:not(.visible) > * { opacity: 1; transform: none; }
  .reveal, .reveal.visible, [data-stagger] > * { transition: none; }
  .hero .hero-inner > *, .page-hero-dark > .wrap > * { animation: none; }
  /* The centre band is a phone's stand-in for a cursor. With motion switched off it still says which
     card you are on — border, shadow, accent line, inverted glyph — but nothing on it moves. */
  .card.is-focus, .hosp.is-focus, .cell.is-focus, .pillar.is-focus, .role-card.is-focus,
  .journey > li.is-focus, .split-cta a.is-focus,
  .pillar.is-focus .icon-row, .hosp.is-focus .hosp-mark b, .hosp.is-focus .hosp-mark img,
  .hosp.is-focus .hosp-go i { transform: none; }
}

/* ---- 2. /process.html and /hospital.html: one measure, one rhythm ----
   Both pages ran to the site's 1280px sheet while their text stopped around two thirds of it, so the
   content read as a column pushed to the left with a blank margin on the right. They are the two
   document pages on the site, so they get the document measure: 1100px centred, and the section gap
   made 60px everywhere by giving each band exactly 30px of its own — adjacent bands meet at 60, no
   more, no less, instead of the previous mix of 96, 44, 36 and 26. */
body[data-page="process"] .band, body[data-page="hospital"] .band { padding: 30px 0; }
body[data-page="process"] .band > .wrap, body[data-page="hospital"] .band > .wrap {
  max-width: 1100px; margin: 0 auto; padding: 30px 20px; box-sizing: border-box;
}
/* The last band on a hospital profile clears the standing call-to-action bar; that gap is functional
   and stays. */
body[data-page="hospital"] .band#hosp-next { padding-bottom: 84px; }

/* ---- 3. the caveat: a card, not a warning label ----
   The estimate caveat is the most serious paragraph on the page and it was dressed as a sticky note —
   amber fill, left accent bar. It is a white card now on the site's own hairline and shadow, and the
   two that head the treatment grid span the full measure instead of being squeezed into one column of
   the card grid beside them. */
.caveat { text-align: left; }
#svc-grid > .caveat { grid-column: 1 / -1; }

/* =============================================================
   v22 — the wizard answers back, and the route is decided by one question
   ============================================================= */

/* Next is no longer greyed out, so the screen has to say what is missing when it is pressed early.
   A disabled button is the silence that reads as a broken form. */
.wiz-hint { margin: 16px 0 0; padding: 12px 14px; font-size: .9rem; line-height: 1.5; color: var(--navy);
  background: var(--color-bg); border: 1px solid var(--color-border-2); border-left-width: 3px; border-radius: 10px; }
.wiz-hint[hidden] { display: none; }
/* Under the last screen of either route: the one line that tells a patient they can reach a human
   right now instead of waiting on the form. It is quieter than the fields above it on purpose — the
   fields have to be answered, this one is an invitation. */
.contact-lead { margin: 18px 0 0; font-size: .88rem; line-height: 1.6; color: var(--ink-2); max-width: 62ch; }

/* =============================================================
   v23 — every inner page opens the way the homepage does
   ============================================================= */

/* One dark opening shared with `.hero`: the same atrium photograph under the same navy→teal wash, so an
   inner page is recognisably the same company the moment it loads. The colour is the fallback and the
   first thing painted — if the photograph is slow or missing, the band is still #0A2540 and the copy is
   still readable. */
.page-hero-dark {
  position: relative;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  justify-content: center;
  min-height: 320px;
  padding: 80px 0 60px;
  color: #FFFFFF;
  background-color: #0A2540;
  background-image:
    linear-gradient(158deg, rgba(5, 38, 63, .9) 0%, rgba(6, 45, 78, .82) 36%, rgba(10, 74, 126, .68) 68%, rgba(13, 106, 134, .5) 100%),
    radial-gradient(1100px 520px at 82% -8%, rgba(15, 163, 163, .38), transparent 62%),
    url("/assets/img/hero-aegiscares-campus.jpg");
  background-size: cover, auto, 100% auto;
  background-position: center, center, center bottom;
  background-repeat: no-repeat;
}
/* The wrap is a flex item now, and a flex item's automatic minimum size is its min-content width — on a
   page whose hero holds a form, whose selects are as wide as their longest option, that pushed the whole
   band past the viewport and clipped both edges. `min-width: 0` lets it shrink back; stretch already gives
   it the full width, so no `width` is set here. */
.page-hero-dark > .wrap { z-index: 1; min-width: 0; }
@media (max-width: 768px) { .page-hero-dark { min-height: 0; padding: 60px 0 40px; } }
/* Desktop keeps the plate at a constant scale — `100% auto` anchored to the band's bottom edge, so the
   framing is the same at 1440 and at 2500 and only the amount of blue above it changes. A phone cannot
   afford that: the band is taller than the plate is wide, so a width-locked plate would be a 150px strip
   at the foot of the screen. There it goes back to `cover`, and slides to the left quarter because cover
   crops the sides on a narrow band — centred, the lit sign landed behind the last line of the lede. */
@media (max-width: 768px) {
  .hero, .page-hero-dark, .contact-hero { background-size: cover, auto, cover; background-position: center, center, 18% 28%; }
}

/* Copy on navy. `.kicker` already arrives white (.72) from the hero rules, so it is not repeated here.
   Links keep the brand teal, except the buttons, which bring their own colours and must not be
   recoloured by a bare `a` rule. */
.page-hero-dark h1, .page-hero-dark h2 { color: #FFFFFF; }
.page-hero-dark .lede, .page-hero-dark .eyebrow, .page-hero-dark .subhead { color: rgba(255, 255, 255, .75); }
.page-hero-dark .eyebrow { color: rgba(255, 255, 255, .72); }
.page-hero-dark a:not(.btn):not(.mark):not(.view-all-link) { color: #00A3A1; }
.page-hero-dark .field label, .page-hero-dark .note, .page-hero-dark .assure { color: rgba(255, 255, 255, .68); }
/* The outlined button is dark text on a hairline border — invisible on navy. Same treatment the closing
   band gives it. */
.page-hero-dark .btn.ghost { background: transparent; color: #fff; border-color: rgba(255, 255, 255, .5); }
.page-hero-dark .btn.ghost:hover { background: rgba(255, 255, 255, .12); border-color: #fff; color: #fff; }
/* The form controls stay white cards on the dark band: a patient types into a field, not into a page.
   And a card that arrives white keeps its own dark type — the `h2` rule above is for the page's headline,
   not for the heading of a panel standing on top of the band. */
.page-hero-dark .panel { color: var(--ink); }
.page-hero-dark .panel h1, .page-hero-dark .panel h2, .page-hero-dark .panel h3 { color: var(--navy); }
.page-hero-dark .panel .note, .page-hero-dark .panel label { color: var(--ink-3); }
.page-hero-dark .hosp-brief { color: rgba(255, 255, 255, .75); }
.page-hero-dark .hosp-back, .page-hero-dark .hosp-back a { color: rgba(255, 255, 255, .72); }

/* =============================================================
   v24 — the two lists that read as left-leaning, and the tiles that lead with the figure
   ============================================================= */

/* The eight steps. The band is 1280px wide and the list filled all of it, so the rail and the numbers
   hugged the left edge while the text ran to the right margin — a column of prose with nothing on the
   right. The list is now a 900px measure, centred under its own heading. The side padding is not
   repeated here: `.wrap` already carries the gutter, and adding another 20px would only narrow the text. */
.journey.compact { max-width: 760px !important; margin-left: auto !important; margin-right: auto !important; }
/* The one call-to-action under the list sits at the end of the measure, not at its start. */
.journey-cta { display: flex; justify-content: flex-end; }

/* =============================================================
   v25 — /contact.html rebuilt as one dark two-column opening
   ============================================================= */

/* The contact page is one dark band from the header to the footer, so it wears the same plate as every
   other opening — and it has no foot fade, because what follows it is the navy footer, not a white page. */
.contact-hero {
  position: relative; overflow: hidden; color: #FFFFFF;
  background-color: #0A2540;
  background-image:
    linear-gradient(158deg, rgba(5, 38, 63, .9) 0%, rgba(6, 45, 78, .82) 36%, rgba(10, 74, 126, .68) 68%, rgba(13, 106, 134, .5) 100%),
    radial-gradient(1100px 520px at 82% -8%, rgba(15, 163, 163, .38), transparent 62%),
    url("/assets/img/hero-aegiscares-campus.jpg");
  background-size: cover, auto, 100% auto; background-position: center, center, center bottom; background-repeat: no-repeat;
}
.contact-grid {
  position: relative; z-index: 1;
  display: grid; grid-template-columns: 1fr 1fr; gap: 60px;
  max-width: 1200px; margin: 0 auto; padding: 100px 20px;
  box-sizing: border-box;
}
@media (max-width: 900px) { .contact-grid { grid-template-columns: 1fr; gap: 40px; padding: 60px 20px; } }

/* ---- the left column ---- */
.contact-left .subtitle { margin: 0 0 16px; font-size: .78rem; font-weight: 700; letter-spacing: 1px;
  text-transform: uppercase; color: #00A3A1; }
.contact-left h1 { margin: 0 0 24px; font-size: 48px; font-weight: 700; line-height: 1.08; color: #FFFFFF; }
.contact-copy { margin: 0 0 32px; font-size: 18px; line-height: 1.6; color: rgba(255, 255, 255, .8); max-width: 52ch; }
.contact-cta { display: inline-block; background: #00A3A1; color: #fff; padding: 16px 32px; border-radius: 8px;
  font-weight: 600; font-size: 16px; border: none; cursor: pointer; margin-bottom: 24px; text-decoration: none;
  transition: background .22s, transform .22s; }
.contact-cta:hover { background: var(--color-accent-d); color: #fff; transform: translateY(-2px); }
.contact-alt { margin: 0 0 18px; font-size: .92rem; }
.contact-alt a { color: #7fe3e3; }
.contact-hours { margin: 0; font-size: 14px; line-height: 1.6; color: rgba(255, 255, 255, .6); max-width: 52ch; }

/* ---- the right column: the card a patient actually fills in ---- */
.contact-right { background: #FFFFFF; padding: 40px; border-radius: 16px; color: #333; box-shadow: 0 24px 60px rgba(5, 38, 63, .28); }
.contact-head { display: flex; justify-content: space-between; align-items: center; gap: 14px; margin-bottom: 24px; }
.contact-head h2 { margin: 0; font-size: 24px; color: #0A2540; }
.contact-tag { font-size: 10px; border: 1px solid #E2E8F0; padding: 4px 8px; border-radius: 4px; color: #666;
  text-transform: uppercase; white-space: nowrap; }
.contact-row { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; margin-bottom: 16px; }
.contact-field { display: flex; flex-direction: column; min-width: 0; }
.contact-field > label, .contact-full > label { font-size: 12px; font-weight: 600; color: #555; text-transform: uppercase; letter-spacing: .04em; }
.contact-field input, .contact-field select, .contact-full textarea, .contact-full select {
  width: 100%; padding: 12px; border: 1px solid #E2E8F0; border-radius: 8px; margin-top: 4px;
  font: 400 15px/1.4 var(--sans); color: #1A1A2E; background: #fff; }
.contact-full { margin-bottom: 16px; }
.contact-full textarea { min-height: 104px; resize: vertical; }
.contact-hint, .contact-hint2 { display: block; margin-top: 6px; font-size: 12px; line-height: 1.5; color: #777; }
.contact-consent { display: flex; align-items: flex-start; gap: 8px; margin-bottom: 24px; cursor: pointer; }
.contact-consent input { margin-top: 4px; flex: none; width: 16px; height: 16px; accent-color: #00A3A1; }
.contact-consent span { font-size: 12px; color: #666; line-height: 1.4; }
.contact-send { width: 100%; background: #00A3A1; color: #fff; padding: 16px; border-radius: 8px; font-weight: 600;
  font-size: 16px; border: none; cursor: pointer; }
.contact-send:hover { background: var(--color-accent-d); }
.contact-send[disabled] { opacity: .55; cursor: default; }
.contact-state { margin: 14px 0 0; font-size: 13px; line-height: 1.5; color: #0A2540; }
@media (max-width: 560px) {
  .contact-left h1 { font-size: 34px; }
  .contact-right { padding: 26px 20px; }
  .contact-row { grid-template-columns: 1fr; gap: 12px; }
  .contact-head { flex-direction: column; align-items: flex-start; }
}

/* =============================================================
   v26 — the contact page's own breakpoints
   ============================================================= */
@media (max-width: 900px) {
    .contact-section > div { grid-template-columns: 1fr !important; gap: 40px !important; padding: 60px 20px !important; }
    .contact-left h1 { font-size: 36px !important; }
    .contact-right { padding: 24px !important; }
}
@media (max-width: 560px) {
    .contact-right form > div { grid-template-columns: 1fr !important; }
}

/* =============================================================
   v27 — what the dark page headers broke on the hospital profile
   The emblem plate and the fact chips were built for a light band, where
   --color-bg-alt is the brand navy at three per cent. Over a navy header that
   wash composites back into the header itself, so the plate, its hairline and
   the muted chip text all vanished, and a transparent emblem drawn in dark red
   or dark green had nothing left to sit on. Re-set for the dark tier only: the
   hospital list and the homepage rail keep their light treatment, and the
   emblem is never cropped or recoloured — it is given a white page to stand on.
   ============================================================= */
.page-hero-dark .hosp-mark { background: #FFFFFF; border-color: rgba(255, 255, 255, .6); }
.page-hero-dark .hosp-facts span { color: rgba(255, 255, 255, .88); background: rgba(255, 255, 255, .10);
  border-color: rgba(255, 255, 255, .32); }

/* =============================================================
   v29 — the hospital profile's vertical rhythm
   Four 102px figures were sitting inside a 260px band: 36px of band padding, a 24px margin on the
   grid itself, then another 36px on the next band. Three separate gaps around one row of cards is
   what made the page look like it had been assembled out of shelves. The paddings come out of the
   markup and into this one rule, at a little over half what they were.
   ============================================================= */
#hosp-under, #hosp-strengths, #hosp-intl, #hosp-scale, #hosp-profile { padding-top: 20px; padding-bottom: 20px; }
.hosp-cards { margin-top: 0; }

/* Self-hosted faces (2026-10-21). These used to come from fonts.googleapis.com,
   which a mainland-China visitor cannot reach: the stylesheet request stalls until
   it times out and delays first paint on all twelve pages. Files are Fontsource
   5.3.0 latin subsets of the same variable fonts, so rendering is unchanged; latin
   covers every accent in en/fr/de/es/it, and Chinese already fell back to the
   system faces listed in --sans and --serif. */
@font-face {
  font-family: "Newsreader"; font-style: normal; font-display: swap; font-weight: 300 600;
  src: url("/assets/fonts/newsreader-latin-standard-normal.woff2") format("woff2-variations");
}
@font-face {
  font-family: "Newsreader"; font-style: italic; font-display: swap; font-weight: 300 500;
  src: url("/assets/fonts/newsreader-latin-standard-italic.woff2") format("woff2-variations");
}
@font-face {
  font-family: "Inter"; font-style: normal; font-display: swap; font-weight: 400 600;
  src: url("/assets/fonts/inter-latin-wght-normal.woff2") format("woff2-variations");
}
@font-face {
  font-family: "IBM Plex Mono"; font-style: normal; font-display: swap; font-weight: 400;
  src: url("/assets/fonts/ibm-plex-mono-latin-400-normal.woff2") format("woff2");
}
@font-face {
  font-family: "IBM Plex Mono"; font-style: normal; font-display: swap; font-weight: 500;
  src: url("/assets/fonts/ibm-plex-mono-latin-500-normal.woff2") format("woff2");
}
