/*
Theme Name: WellCareChina
Theme URI: https://wellcarechina.com/
Author: wellcarechina
Author URI: https://wellcarechina.com/
Description: WellCareChina (Chinese name: 入境医疗网) portal theme - informational portal for international patients looking up medical information in China. Visibility layer: design tokens, self-hosted icon set, homepage, credibility pages (methodology / corrections / editorial standards) and the services page. No third-party dependencies, no CDN.
Version: 0.43.0
Requires at least: 6.0
Requires PHP: 8.0
Tested up to: 7.1
License: GNU General Public License v2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html
Text Domain: wellcarechina
Tags: custom-menu, custom-logo, translation-ready
*/

/* Component styles only. Colour / spacing / radius / type values come from
   assets/css/tokens.css; fonts are declared in assets/css/fonts.css. Both are
   enqueued before this file (see wellcarechina_enqueue_assets()). */

/* ---------------------------------------------------------------- Base --- */

*,
*::before,
*::after {
	box-sizing: border-box;
}

body {
	margin: 0;
	color: var(--kl-ink);
	background: var(--kl-paper);
	font-family: var(--kl-font-sans);
	font-size: var(--kl-text-base);
	line-height: var(--kl-leading-body);
	-webkit-text-size-adjust: 100%;
}

a {
	color: var(--kl-accent);
	text-decoration-thickness: 1px;
	text-underline-offset: 2px;
}

a:hover,
a:focus {
	color: var(--kl-accent-hover);
}

:focus-visible {
	outline: 2px solid var(--kl-accent);
	outline-offset: 2px;
}

h1,
h2,
h3,
h4 {
	margin: 0 0 var(--kl-space-3);
	line-height: var(--kl-leading-tight);
	font-weight: var(--kl-weight-semibold);
	letter-spacing: -0.01em;
}

h1 {
	font-size: var(--kl-text-3xl);
}

h2 {
	font-size: var(--kl-text-xl);
}

h3 {
	font-size: var(--kl-text-lg);
}

img {
	max-width: 100%;
	height: auto;
	display: block;
}

hr {
	border: 0;
	border-top: 1px solid var(--kl-border);
	margin: var(--kl-space-6) 0;
}

/* --------------------------------------------------------- Primitives --- */

.kl-container {
	width: 100%;
	max-width: var(--kl-container);
	margin: 0 auto;
	padding: 0 var(--kl-space-5);
}

.kl-skip-link {
	position: absolute;
	left: -9999px;
	top: 0;
}

.kl-skip-link:focus {
	left: var(--kl-space-3);
	top: var(--kl-space-3);
	z-index: 100;
	padding: var(--kl-space-2) var(--kl-space-4);
	background: var(--kl-paper);
	border: 1px solid var(--kl-accent);
	border-radius: var(--kl-radius-input);
}

/* Icons are decoration; the label next to them carries the meaning. */
.kl-icon {
	width: 20px;
	height: 20px;
	flex: 0 0 auto;
	vertical-align: -3px;
}

.kl-icon--lg {
	width: 24px;
	height: 24px;
}

.kl-visually-hidden {
	position: absolute;
	width: 1px;
	height: 1px;
	margin: -1px;
	padding: 0;
	overflow: hidden;
	clip: rect(0 0 0 0);
	white-space: nowrap;
	border: 0;
}

/* -------------------------------------------------------------- Header ---
   fix-007 T7 (ledger ui-008): one row on desktop, so the search box no longer
   wraps to a line of its own - the non-front header used to stand 196px tall
   (343px on mobile). */

.kl-header {
	border-bottom: 1px solid var(--kl-border);
	background: var(--kl-paper);
}

.kl-header__inner {
	display: flex;
	flex-wrap: nowrap;
	align-items: center;
	gap: var(--kl-space-5);
	padding-top: var(--kl-space-2);
	padding-bottom: var(--kl-space-2);
}

.kl-branding {
	flex: 0 0 auto;
}

/* Site mark (dev-012): decorative, sits inline before the text brand. */
.kl-branding__mark {
	display: inline-block;
	width: 36px;
	height: 36px;
	margin-right: var(--kl-space-2);
	vertical-align: middle;
}

.kl-branding__title {
	margin: 0;
	font-size: var(--kl-text-lg);
	font-weight: var(--kl-weight-semibold);
}

.kl-branding__title a {
	display: inline-flex;
	align-items: center;
	min-height: 44px;
	color: inherit;
	text-decoration: none;
}

.kl-branding__tagline {
	margin: var(--kl-space-1) 0 0;
	color: var(--kl-slate);
	font-size: var(--kl-text-sm);
}

/* The menu is a plain row on desktop; the mobile disclosure is not rendered. */
.kl-nav {
	flex: 1 1 auto;
}

.kl-nav__details {
	display: none;
}

.kl-nav__list {
	display: flex;
	flex-wrap: wrap;
	/* dev-032: the English menu gained its eighth item (`Rankings`). At the
	   1200px container the row fits eight labels on two lines with a 16px
	   column gap; at the 24px gap it needed a third line and the non-front
	   header grew past the 120px the dev-024 contract allows. The row gap is
	   unchanged, and the <=900px mobile panel sets its own `gap: 0`.
	   dev-034: the menu gained its ninth item (`Insurance in China`) and the
	   column gap went 16px -> 4px, which is what keeps the nine labels inside
	   the dev-024 budget once the header's own gap is 4px on desktop
	   (see .kl-header__inner above). */
	gap: var(--kl-space-2) var(--kl-space-1);
	margin: 0;
	padding: 0;
	list-style: none;
	font-size: var(--kl-text-md);
}

.kl-nav__list a {
	display: inline-flex;
	align-items: center;
	min-height: 44px;
	color: var(--kl-ink);
	text-decoration: none;
}

/* ---------------------------------------------------- Language selector ---
   fix-007 T2: one conventional selector. The summary shows the current
   language's own name; the panel lists every configured language. It is a
   native `<details>`, so it opens with no JavaScript. */

.kl-lang {
	flex: 0 0 auto;
	color: var(--kl-slate);
	font-size: var(--kl-text-sm);
}

.kl-lang__details {
	position: relative;
}

.kl-lang__toggle {
	display: inline-flex;
	align-items: center;
	gap: var(--kl-space-2);
	min-height: 44px;
	padding: 0 var(--kl-space-3);
	border: 1px solid var(--kl-border-strong);
	border-radius: var(--kl-radius-pill);
	background: var(--kl-paper);
	color: var(--kl-slate);
	cursor: pointer;
	list-style: none;
}

/* Hide the native disclosure marker; the caret below replaces it. */
.kl-lang__toggle::-webkit-details-marker {
	display: none;
}

.kl-lang__toggle:hover,
.kl-lang__toggle:focus {
	color: var(--kl-ink);
}

.kl-lang__caret {
	width: 7px;
	height: 7px;
	margin-left: var(--kl-space-1);
	border-right: 1.5px solid currentColor;
	border-bottom: 1.5px solid currentColor;
	transform: rotate(45deg);
	transition: transform var(--kl-dur-fast) var(--kl-ease);
}

.kl-lang__details[open] .kl-lang__caret {
	transform: rotate(225deg);
}

.kl-lang__list {
	position: absolute;
	right: 0;
	top: calc(100% + var(--kl-space-1));
	z-index: 20;
	min-width: 200px;
	margin: 0;
	padding: var(--kl-space-2) 0;
	list-style: none;
	border: 1px solid var(--kl-border-strong);
	border-radius: var(--kl-radius-card);
	background: var(--kl-paper);
	box-shadow: var(--kl-shadow-2);
}

.kl-lang__link {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--kl-space-4);
	min-height: 44px;
	padding: 0 var(--kl-space-4);
	color: var(--kl-ink);
	text-decoration: none;
}

.kl-lang__link:hover,
.kl-lang__link:focus {
	background: var(--kl-accent-soft);
	color: var(--kl-accent-hover);
}

.kl-lang__link[aria-current="true"] {
	font-weight: var(--kl-weight-semibold);
}

.kl-lang__code {
	color: var(--kl-slate);
	font-family: var(--kl-font-mono);
	font-size: var(--kl-text-xs);
	text-transform: uppercase;
}

/* --------------------------------------------------- Chinese front page --- */

/* The Chinese landing page is text-only, so its hero uses one column instead
   of the English two-column (copy | photograph) grid. */
.kl-hero--zh .kl-hero__inner {
	grid-template-columns: minmax(0, 1fr);
}

.kl-hero--zh .kl-hero__text {
	max-width: var(--kl-measure);
}

.kl-chips--entries {
	gap: var(--kl-space-3);
}

.kl-zh-contact {
	margin-top: var(--kl-space-6);
}

/* ------------------------------------------------------------- Buttons --- */

.kl-btn {
	display: inline-flex;
	align-items: center;
	gap: var(--kl-space-2);
	padding: var(--kl-space-3) var(--kl-space-5);
	border: 1px solid var(--kl-accent);
	border-radius: var(--kl-radius-pill);
	background: var(--kl-accent);
	color: var(--kl-paper);
	font-family: inherit;
	font-size: var(--kl-text-md);
	font-weight: var(--kl-weight-semibold);
	line-height: 1.2;
	text-decoration: none;
	cursor: pointer;
	transition: background-color var(--kl-dur-fast) var(--kl-ease), border-color var(--kl-dur-fast) var(--kl-ease);
}

.kl-btn:hover,
.kl-btn:focus {
	background: var(--kl-accent-hover);
	border-color: var(--kl-accent-hover);
	color: var(--kl-paper);
}

.kl-btn--ghost {
	background: transparent;
	border-color: var(--kl-border-strong);
	color: var(--kl-ink);
}

.kl-btn--ghost:hover,
.kl-btn--ghost:focus {
	background: var(--kl-accent-soft);
	border-color: var(--kl-accent);
	color: var(--kl-accent-hover);
}

/* A disabled button must still be readable and must not look clickable. */
.kl-btn[disabled],
.kl-btn[aria-disabled="true"] {
	background: var(--kl-disabled-bg);
	border-color: var(--kl-disabled-bg);
	color: var(--kl-disabled-ink);
	cursor: not-allowed;
}

.kl-btn[aria-disabled="true"]:hover {
	background: var(--kl-disabled-bg);
	border-color: var(--kl-disabled-bg);
	color: var(--kl-disabled-ink);
}

.kl-btn-note {
	display: block;
	margin: var(--kl-space-2) 0 0;
	color: var(--kl-slate);
	font-size: var(--kl-text-sm);
}

/* --------------------------------------------------------- Search form --- */

.kl-search-form {
	margin: 0;
}

.kl-search-form__label {
	display: block;
	margin-bottom: var(--kl-space-2);
	color: var(--kl-slate);
	font-size: var(--kl-text-sm);
}

.kl-search-form__row {
	display: flex;
	gap: var(--kl-space-2);
}

.kl-search-form__input {
	flex: 1 1 auto;
	min-width: 0;
	min-height: 44px;
	padding: var(--kl-space-3);
	border: 1px solid var(--kl-border-strong);
	border-radius: var(--kl-radius-input);
	background: var(--kl-paper);
	color: var(--kl-ink);
	font-family: inherit;
	font-size: var(--kl-text-md);
}

.kl-search-form__input:focus {
	border-color: var(--kl-accent);
	box-shadow: 0 0 0 3px var(--kl-accent-ring);
	outline: none;
}

.kl-search-form__submit {
	flex: 0 0 auto;
	min-height: 44px;
	padding: var(--kl-space-3) var(--kl-space-5);
	border: 1px solid var(--kl-accent);
	border-radius: var(--kl-radius-pill);
	background: var(--kl-accent);
	color: var(--kl-paper);
	font-family: inherit;
	font-size: var(--kl-text-md);
	font-weight: var(--kl-weight-semibold);
	cursor: pointer;
}

.kl-search-form__submit:hover,
.kl-search-form__submit:focus {
	background: var(--kl-accent-hover);
	border-color: var(--kl-accent-hover);
}

.kl-search-form--hero .kl-search-form__input,
.kl-search-form--hero .kl-search-form__submit {
	padding-top: var(--kl-space-4);
	padding-bottom: var(--kl-space-4);
}

/* ---------------------------------------------------------------- Hero --- */

.kl-hero {
	padding: var(--kl-space-8) 0 var(--kl-space-7);
	background: var(--kl-navy);
	color: var(--kl-on-navy);
}

.kl-hero__inner {
	display: grid;
	grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr);
	gap: var(--kl-space-7);
	align-items: center;
}

.kl-hero__eyebrow {
	margin: 0 0 var(--kl-space-3);
	color: var(--kl-on-navy-muted);
	font-size: var(--kl-text-sm);
	letter-spacing: var(--kl-tracking-caps);
	text-transform: uppercase;
}

.kl-hero__title {
	margin: 0 0 var(--kl-space-3);
	color: var(--kl-on-navy);
	font-size: var(--kl-text-4xl);
	letter-spacing: -0.02em;
}

.kl-hero__lede {
	max-width: 46ch;
	margin: 0 0 var(--kl-space-5);
	color: var(--kl-on-navy-muted);
	font-size: var(--kl-text-lg);
}

.kl-hero .kl-search-form {
	max-width: 560px;
}

/* dev-052 (ledger ui-034): the hero already caps its search row at 560px.
   The two in-page variants did not, so on /hospitals/ and the 404 page the
   field stretched to the full 1152px content box - the label sat at the left
   edge and the button about a thousand pixels away from it, and the row read
   as a full-width banner rather than a search control. Both now share the
   hero's cap. */
.kl-search-form--landing,
.kl-search-form--default {
	max-width: 560px;
}

.kl-hero .kl-search-form__label {
	color: var(--kl-on-navy-muted);
}

.kl-hero__chips {
	margin-top: var(--kl-space-4);
}

.kl-hero__chips-label {
	margin: 0 0 var(--kl-space-2);
	color: var(--kl-on-navy-muted);
	font-size: var(--kl-text-sm);
}

.kl-hero__media {
	margin: 0;
}

/* The frame carries the photograph only (fix-007 T1). It is a plain block, so
   the credit rendered below it can never become a flex sibling of the image -
   that flex row is what squeezed the credit into a 61px column beside the
   photograph (ledger ui-002). */
.kl-hero__media-frame {
	display: block;
}

/* Hero photograph: fills the right column, cropped to a stable 16:9 frame. */
.kl-hero__media-frame img {
	display: block;
	width: 100%;
	height: auto;
	aspect-ratio: 16 / 9;
	object-fit: cover;
	border-radius: var(--kl-radius-card);
	box-shadow: var(--kl-shadow-2);
}

/* Credit sits under the image and takes the container's width - no hard ch
   limit. 13px keeps it legible; the muted-on-navy pair stays well above the
   4.5:1 contrast floor. */
.kl-hero__media-credit {
	margin: var(--kl-space-2) 0 0;
	color: var(--kl-on-navy-muted);
	font-size: var(--kl-text-sm);
}

@media (max-width: 900px) {
	.kl-hero__media-frame img {
		aspect-ratio: 4 / 3;
	}
}

.kl-hero .kl-chip {
	border-color: rgba(255, 255, 255, 0.24);
	color: var(--kl-on-navy);
}

.kl-hero .kl-chip:hover,
.kl-hero .kl-chip:focus {
	background: rgba(255, 255, 255, 0.08);
	color: var(--kl-on-navy);
}

/* --------------------------------------------------------------- Chips --- */

.kl-chips {
	display: flex;
	flex-wrap: wrap;
	gap: var(--kl-space-2);
	margin: 0;
	padding: 0;
	list-style: none;
}

.kl-chips--nowrap {
	flex-wrap: nowrap;
	overflow: hidden;
}

/* Chip row with a clamped list plus an always-visible overflow counter. */
.kl-chip-row {
	display: flex;
	align-items: center;
	gap: var(--kl-space-2);
	min-width: 0;
}

.kl-chip-row > .kl-chips--nowrap {
	flex: 1 1 auto;
	min-width: 0;
}

.kl-card .kl-chip-row {
	margin: 0 0 var(--kl-space-3);
}

.kl-chip {
	display: inline-flex;
	align-items: center;
	min-height: 44px;
	padding: 0 var(--kl-space-3);
	border: 1px solid var(--kl-border-strong);
	border-radius: var(--kl-radius-pill);
	color: var(--kl-slate);
	font-size: var(--kl-text-sm);
	line-height: 1;
	text-decoration: none;
	white-space: nowrap;
}

.kl-chip:hover,
.kl-chip:focus {
	background: var(--kl-accent-soft);
	border-color: var(--kl-accent);
	color: var(--kl-accent-hover);
}

.kl-chip--more {
	color: var(--kl-slate);
	background: var(--kl-paper-alt);
	border-style: dashed;
}

.kl-chip--selected {
	background: var(--kl-accent);
	border-color: var(--kl-accent);
	color: var(--kl-paper);
}

/*
 * test-001 (B7): a wrapping chip list can carry one label longer than the
 * column - a hospital's full English alias ("Tongji Hospital, Tongji Medical
 * College, Huazhong University of Science and Technology") measured 533px in a
 * 342px row at 390 and pushed the document 167px sideways. A chip inside a
 * wrapping list now caps at its column and its own label wraps; the clamped
 * card rows (`.kl-chips--nowrap`, where the `+N` counter lives outside the
 * clip per known-issues #9) are untouched and keep their one-line chips, which
 * is what the dev-048 card rhythm relies on.
 */
.kl-chips:not(.kl-chips--nowrap) > li {
	max-width: 100%;
}

.kl-chips:not(.kl-chips--nowrap) > li > .kl-chip {
	max-width: 100%;
	padding-block: var(--kl-space-1);
	line-height: 1.35;
	text-align: left;
	white-space: normal;
	overflow-wrap: anywhere;
}

/* ------------------------------------------------------------- Sections --- */

.kl-section {
	padding: var(--kl-space-8) 0;
}

.kl-section--alt {
	background: var(--kl-paper-alt);
}

.kl-section--tight {
	padding: var(--kl-space-7) 0;
}

.kl-section__head {
	max-width: 68ch;
	margin-bottom: var(--kl-space-6);
}

.kl-section__title {
	margin: 0 0 var(--kl-space-2);
	font-size: var(--kl-text-2xl);
}

.kl-section__intro {
	margin: 0;
	color: var(--kl-slate);
}

/* The homepage line about admission timing (dev-035 T1). It sits in the
   services section head, under the intro, and reuses the page's own type
   tokens - the wording is elastic (no figure) and the hospital-confirms clause
   is part of the same sentence. */
.kl-section__note {
	margin: var(--kl-space-2) 0 0;
	color: var(--kl-slate);
}

/* The one-line travel-partner mention under the homepage services teaser
   (dev-011 T1); it links to /services/ rather than to the partner. */
.kl-section__foot-note {
	margin: var(--kl-space-2) 0 0;
	color: var(--kl-slate);
	font-size: var(--kl-text-sm);
}

/* ----------------------------------------------------------- Trust bar --- */

.kl-trust {
	border-bottom: 1px solid var(--kl-border);
	background: var(--kl-paper-alt);
}

.kl-trust__list {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--kl-space-5);
	margin: 0;
	padding: var(--kl-space-5) 0;
	list-style: none;
}

.kl-trust__item {
	display: flex;
	flex-direction: column;
	gap: var(--kl-space-1);
}

.kl-trust__value {
	color: var(--kl-ink);
	font-family: var(--kl-font-mono);
	font-size: var(--kl-text-xl);
	font-variant-numeric: tabular-nums;
	line-height: 1.1;
}

.kl-trust__label {
	color: var(--kl-slate);
	font-size: var(--kl-text-sm);
}

.kl-trust__sep {
	align-self: stretch;
	width: 1px;
	background: var(--kl-border-strong);
}

/* -------------------------------------------------------- Module cards --- */

.kl-modules {
	display: grid;
	grid-template-columns: repeat(5, minmax(0, 1fr));
	gap: var(--kl-space-4);
	margin: 0;
	padding: 0;
	list-style: none;
}

.kl-module {
	display: flex;
	flex-direction: column;
	height: 100%;
	padding: var(--kl-space-5);
	border: 1px solid var(--kl-border);
	border-radius: var(--kl-radius-card);
	background: var(--kl-paper);
}

.kl-module__icon {
	margin-bottom: var(--kl-space-3);
	color: var(--kl-accent);
}

.kl-module__title {
	margin: 0 0 var(--kl-space-2);
	font-size: var(--kl-text-lg);
}

.kl-module__title a {
	color: inherit;
	text-decoration: none;
}

.kl-module__title a:hover,
.kl-module__title a:focus {
	color: var(--kl-accent-hover);
}

.kl-module__desc {
	margin: 0 0 var(--kl-space-4);
	color: var(--kl-slate);
	font-size: var(--kl-text-base);
}

.kl-module__foot {
	margin-top: auto;
	color: var(--kl-slate);
	font-family: var(--kl-font-mono);
	font-size: var(--kl-text-sm);
	font-variant-numeric: tabular-nums;
}

/* ------------------------------------------------------- Two columns --- */

.kl-columns {
	display: grid;
	grid-template-columns: minmax(0, 2fr) minmax(0, 1fr);
	gap: var(--kl-space-7);
}

.kl-columns__title {
	margin: 0 0 var(--kl-space-4);
	font-size: var(--kl-text-xl);
}

.kl-news-list {
	margin: 0;
	padding: 0;
	list-style: none;
}

.kl-news-list__item {
	padding: var(--kl-space-4) 0;
	border-bottom: 1px solid var(--kl-border);
}

.kl-news-list__item:first-child {
	padding-top: 0;
}

.kl-news-list__item a {
	font-weight: var(--kl-weight-semibold);
	text-decoration: none;
}

.kl-news-list__meta {
	display: flex;
	flex-wrap: wrap;
	gap: var(--kl-space-2);
	margin: var(--kl-space-1) 0 0;
	color: var(--kl-slate);
	font-size: var(--kl-text-sm);
}

.kl-panel {
	padding: var(--kl-space-5);
	border: 1px solid var(--kl-border);
	border-radius: var(--kl-radius-card);
	background: var(--kl-paper);
}

.kl-panel + .kl-panel {
	margin-top: var(--kl-space-4);
}

.kl-panel__title {
	margin: 0 0 var(--kl-space-4);
	font-size: var(--kl-text-lg);
}

/* ------------------------------------------------------- Evidence key --- */

.kl-levels {
	margin: 0;
}

.kl-level {
	display: flex;
	gap: var(--kl-space-3);
	padding: var(--kl-space-3) 0;
	border-bottom: 1px solid var(--kl-border);
}

.kl-level:last-child {
	border-bottom: 0;
	padding-bottom: 0;
}

.kl-level__icon {
	color: var(--kl-slate);
}

.kl-level--a .kl-level__icon {
	color: var(--kl-level-a);
}

.kl-level--b .kl-level__icon {
	color: var(--kl-level-b);
}

.kl-level--c .kl-level__icon {
	color: var(--kl-level-c);
}

.kl-level__body {
	margin: 0;
}

.kl-level__name {
	display: block;
	font-weight: var(--kl-weight-semibold);
}

.kl-level__desc {
	display: block;
	color: var(--kl-slate);
	font-size: var(--kl-text-sm);
}

/* ------------------------------------------------------- Service cards --- */

.kl-services {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: var(--kl-space-4);
	margin: 0;
	padding: 0;
	list-style: none;
}

.kl-service {
	display: flex;
	flex-direction: column;
	padding: var(--kl-space-5);
	border: 1px solid var(--kl-border);
	border-radius: var(--kl-radius-card);
	background: var(--kl-paper);
}

.kl-service__head {
	display: flex;
	align-items: flex-start;
	gap: var(--kl-space-3);
	margin-bottom: var(--kl-space-4);
}

.kl-service__icon {
	color: var(--kl-accent);
}

.kl-service__title {
	margin: 0;
	font-size: var(--kl-text-lg);
}

.kl-service__desc {
	margin: 0 0 var(--kl-space-4);
	color: var(--kl-slate);
}

.kl-service__spec {
	margin: 0 0 var(--kl-space-4);
}

.kl-service__spec dt {
	color: var(--kl-slate);
	font-size: var(--kl-text-sm);
	font-weight: var(--kl-weight-semibold);
}

.kl-service__spec dd {
	margin: 0 0 var(--kl-space-3);
	font-size: var(--kl-text-base);
}

.kl-service__spec dd:last-child {
	margin-bottom: 0;
}

.kl-service__foot {
	margin-top: auto;
	padding-top: var(--kl-space-4);
	border-top: 1px solid var(--kl-border);
}

.kl-service__contact {
	display: flex;
	flex-wrap: wrap;
	gap: var(--kl-space-2) var(--kl-space-4);
	margin: var(--kl-space-3) 0 0;
	padding: 0;
	list-style: none;
	font-size: var(--kl-text-base);
}

.kl-service__contact a {
	display: inline-flex;
	align-items: center;
	gap: var(--kl-space-2);
}

/* --------------------------------------------------------------- Cards --- */

.kl-card-list {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
	gap: var(--kl-space-4);
	margin: 0;
	padding: 0;
	list-style: none;
}

.kl-card {
	display: flex;
	flex-direction: column;
	padding: var(--kl-space-5);
	border: 1px solid var(--kl-border);
	border-radius: var(--kl-radius-card);
	background: var(--kl-paper);
}

.kl-card__badge {
	align-self: flex-start;
	margin: 0 0 var(--kl-space-3);
	padding: var(--kl-space-1) var(--kl-space-3);
	border-radius: var(--kl-radius-pill);
	background: var(--kl-accent-soft);
	color: var(--kl-accent-hover);
	font-size: var(--kl-text-xs);
	letter-spacing: var(--kl-tracking-caps);
	text-transform: uppercase;
}

.kl-card__title {
	margin: 0 0 var(--kl-space-2);
	font-size: var(--kl-text-lg);
}

.kl-card__title a {
	color: inherit;
	text-decoration: none;
}

.kl-card__title a:hover,
.kl-card__title a:focus {
	color: var(--kl-accent-hover);
}

.kl-card__meta {
	margin: 0 0 var(--kl-space-3);
	color: var(--kl-slate);
	font-size: var(--kl-text-sm);
}

.kl-card__chips {
	margin: 0 0 var(--kl-space-3);
}

.kl-card__excerpt {
	margin-top: auto;
	color: var(--kl-slate);
	font-size: var(--kl-text-base);
}

.kl-card__excerpt p {
	margin: 0;
}

.kl-card__foot {
	margin: var(--kl-space-3) 0 0;
	padding-top: var(--kl-space-3);
	border-top: 1px solid var(--kl-border);
	color: var(--kl-slate);
	font-size: var(--kl-text-sm);
}

/* -------------------------------------------------------- Single entry --- */

.kl-main {
	display: block;
}

.kl-single,
.kl-archive,
.kl-search-results {
	padding-top: var(--kl-space-7);
	padding-bottom: var(--kl-space-8);
}

.kl-entry {
	max-width: 820px;
}

.kl-entry__badge {
	display: inline-block;
	margin: 0 0 var(--kl-space-3);
	padding: var(--kl-space-1) var(--kl-space-3);
	border-radius: var(--kl-radius-pill);
	background: var(--kl-accent-soft);
	color: var(--kl-accent-hover);
	font-size: var(--kl-text-xs);
	letter-spacing: var(--kl-tracking-caps);
	text-transform: uppercase;
}

.kl-entry__title {
	margin-bottom: var(--kl-space-3);
	font-size: var(--kl-text-3xl);
}

/* ------------------------------------------- English-first name (fix-003) ---
   The English name is a field, so it is rendered next to the Chinese title it
   belongs to: it leads on its own line, the Chinese original follows on a quiet
   second line. Both cards and single pages use the same two spans, so the pair
   cannot drift apart. Since fix-004 T3 each slot names its own language, so a
   record without an English name renders the Chinese name once, as the only
   child of the title - and that lone line stays at title size (the demotion
   below is for a quiet SECOND line). */

.kl-name-en {
	display: block;
}

.kl-name-zh {
	display: block;
	margin-top: var(--kl-space-1);
	color: var(--kl-slate);
	font-size: var(--kl-text-sm);
	font-weight: var(--kl-weight-regular);
	letter-spacing: normal;
}

.kl-name-zh:only-child {
	margin-top: 0;
	color: inherit;
	font-size: inherit;
	font-weight: inherit;
}

.kl-entry__icd {
	margin: var(--kl-space-6) 0 0;
	padding-top: var(--kl-space-3);
	border-top: 1px solid var(--kl-border);
	color: var(--kl-slate);
	font-size: var(--kl-text-sm);
}

/* dev-041: the procedure / project-code anchor line, printed directly under the
   ICD-10 line for a treatment line that carries no ICD-10 category of its own.
   It is a continuation of that line, so it takes no border and no top padding
   of its own. */
.kl-entry__procedure {
	margin: var(--kl-space-2) 0 0;
	color: var(--kl-slate);
	font-size: var(--kl-text-sm);
}

.kl-entry__meta {
	display: flex;
	flex-wrap: wrap;
	gap: var(--kl-space-2) var(--kl-space-5);
	margin: 0 0 var(--kl-space-5);
	color: var(--kl-slate);
	font-size: var(--kl-text-base);
}

.kl-entry__content {
	max-width: var(--kl-measure);
}

.kl-archive__header,
.kl-search-results__header {
	max-width: 68ch;
	margin-bottom: var(--kl-space-6);
}

.kl-archive__desc {
	color: var(--kl-slate);
}

.kl-search-results__scope {
	margin: 0;
	color: var(--kl-slate);
	font-size: var(--kl-text-base);
}

/* ------------------------------------------------------- Source block --- */

.kl-source {
	max-width: 820px;
	margin-top: var(--kl-space-7);
	padding: var(--kl-space-5);
	border: 1px solid var(--kl-border);
	border-left: 4px solid var(--kl-slate);
	border-radius: var(--kl-radius-card);
	background: var(--kl-paper-alt);
}

.kl-source--level-a {
	border-left-color: var(--kl-level-a);
}

.kl-source--level-b {
	border-left-color: var(--kl-level-b);
}

.kl-source--level-c {
	border-left-color: var(--kl-level-c);
}

.kl-source__title {
	display: flex;
	align-items: center;
	gap: var(--kl-space-2);
	margin: 0 0 var(--kl-space-4);
	font-size: var(--kl-text-lg);
}

.kl-source--level-a .kl-source__title {
	color: var(--kl-level-a);
}

.kl-source--level-b .kl-source__title {
	color: var(--kl-level-b);
}

.kl-source--level-c .kl-source__title {
	color: var(--kl-level-c);
}

.kl-source__list {
	display: grid;
	grid-template-columns: max-content minmax(0, 1fr);
	gap: var(--kl-space-2) var(--kl-space-4);
	margin: 0;
	font-size: var(--kl-text-base);
}

.kl-source__list dt {
	color: var(--kl-slate);
}

.kl-source__list dd {
	margin: 0;
	overflow-wrap: anywhere;
}

.kl-source__list dd:has(a) {
	font-family: var(--kl-font-mono);
	font-size: var(--kl-text-sm);
}

.kl-source__note {
	margin: var(--kl-space-4) 0 0;
	padding: var(--kl-space-3) var(--kl-space-4);
	border-radius: var(--kl-radius-input);
	background: var(--kl-note-bg);
	color: var(--kl-level-c);
	font-size: var(--kl-text-base);
}

/* ------------------------------------------------------- Field groups --- */

.kl-fields {
	max-width: 820px;
	margin-top: var(--kl-space-6);
}

.kl-fields__title {
	font-size: var(--kl-text-lg);
}

.kl-fields__list {
	display: grid;
	grid-template-columns: max-content minmax(0, 1fr);
	gap: var(--kl-space-2) var(--kl-space-4);
	margin: 0 0 var(--kl-space-4);
	font-size: var(--kl-text-base);
}

.kl-fields__list dt {
	color: var(--kl-slate);
}

.kl-fields__list dd {
	margin: 0;
	overflow-wrap: anywhere;
}

.kl-fields__note {
	margin: var(--kl-space-3) 0 0;
	color: var(--kl-slate);
	font-size: var(--kl-text-sm);
}

/* Link out of a field group to the full dataset (disease page blocks). */
.kl-fields__more {
	margin: var(--kl-space-4) 0 0;
	font-size: var(--kl-text-sm);
}

/* Lede sentence above the hospital-record table on a condition page (dev-005),
   and the specialty archive links below it. */
.kl-fields__lede {
	margin: var(--kl-space-3) 0 var(--kl-space-4);
	max-width: 68ch;
	color: var(--kl-ink);
}

.kl-fields__links {
	display: flex;
	flex-wrap: wrap;
	gap: var(--kl-space-2) var(--kl-space-5);
	margin: var(--kl-space-3) 0 0;
	padding: 0;
	list-style: none;
	font-size: var(--kl-text-sm);
}

/* Level marker for dense contexts (tables, lists): a dot plus text, never a
   pill stack. */
.kl-level-tag {
	display: inline-flex;
	align-items: center;
	gap: var(--kl-space-2);
	white-space: nowrap;
}

.kl-level-tag::before {
	content: "";
	width: 8px;
	height: 8px;
	flex: 0 0 auto;
	border-radius: 50%;
	background: var(--kl-slate);
}

.kl-level-tag--a::before {
	background: var(--kl-level-a);
}

.kl-level-tag--b::before {
	background: var(--kl-level-b);
}

.kl-level-tag--c::before {
	background: var(--kl-level-c);
}

.kl-source-cell {
	font-family: var(--kl-font-mono);
	font-size: var(--kl-text-sm);
	overflow-wrap: anywhere;
}

/* -------------------------------------------------------------- Tables --- */

.kl-table-wrap {
	margin: 0;
	border: 1px solid var(--kl-border);
	border-radius: var(--kl-radius-card);
	overflow-x: auto;
}

.kl-table {
	width: 100%;
	min-width: 560px;
	border-collapse: collapse;
	font-size: var(--kl-text-base);
}

.kl-table th,
.kl-table td {
	padding: var(--kl-space-3) var(--kl-space-4);
	text-align: left;
	vertical-align: top;
	border-bottom: 1px solid var(--kl-border);
}

.kl-table th {
	color: var(--kl-slate);
	font-size: var(--kl-text-sm);
	font-weight: var(--kl-weight-semibold);
	letter-spacing: var(--kl-tracking-caps);
	text-transform: uppercase;
	white-space: nowrap;
}

.kl-table tr:last-child td {
	border-bottom: 0;
}

.kl-table td.kl-num {
	font-family: var(--kl-font-mono);
	font-variant-numeric: tabular-nums;
	white-space: nowrap;
}

/* --------------------------------------------------------- Policy pages --- */

.kl-policy {
	display: grid;
	grid-template-columns: minmax(0, 1fr) 280px;
	gap: var(--kl-space-7);
	padding-top: var(--kl-space-7);
	padding-bottom: var(--kl-space-8);
	align-items: start;
}

.kl-policy__toc {
	position: sticky;
	top: var(--kl-space-5);
	padding: var(--kl-space-5);
	border: 1px solid var(--kl-border);
	border-radius: var(--kl-radius-card);
	background: var(--kl-paper-alt);
	font-size: var(--kl-text-base);
}

.kl-policy__toc-title {
	margin: 0 0 var(--kl-space-3);
	font-size: var(--kl-text-base);
	letter-spacing: var(--kl-tracking-caps);
	text-transform: uppercase;
	color: var(--kl-slate);
}

.kl-policy__toc ol {
	margin: 0;
	padding-left: var(--kl-space-5);
}

.kl-policy__toc li + li {
	margin-top: var(--kl-space-2);
}

/* dev-055 T1: `/insurance/` joins the two-column skeleton. Its scope / partner
   / direct-billing block is a direct child of the `.kl-policy` grid (it stays
   outside `.kl-prose`, so its own card styling is untouched), so it has to be
   pinned to the prose column - the grid's auto-placement would otherwise drop
   the first sibling into the 280px directory column. The column sizes it. */
.kl-policy > .kl-insurance__scope {
	grid-column: 1;
}

.kl-page-header {
	max-width: 68ch;
	padding-bottom: var(--kl-space-5);
	margin-bottom: var(--kl-space-5);
	border-bottom: 1px solid var(--kl-border);
}

.kl-page-header__lede {
	margin: var(--kl-space-3) 0 0;
	color: var(--kl-slate);
	font-size: var(--kl-text-lg);
}

.kl-page-header__stamp {
	display: flex;
	flex-wrap: wrap;
	gap: var(--kl-space-2) var(--kl-space-4);
	margin: var(--kl-space-4) 0 0;
	padding: 0;
	list-style: none;
	color: var(--kl-slate);
	font-family: var(--kl-font-mono);
	font-size: var(--kl-text-sm);
}

/* dev-055 T2: on a prose page the header must read on the paragraph measure.
   The cap used to be 68ch, resolved against this block's inherited 15px
   (612px), while `.kl-prose p` resolves 72ch against its own 16px (691.2px) -
   one token, two pixel readings, and the lede and its rule were the narrow
   ones. Pinning the block's type size to the paragraph size makes
   `--kl-measure` resolve to one value here. Scoped to `.kl-prose` (the content
   pages), so a header outside the prose keeps the 68ch cap it was designed
   with (`/services/`, `/contact/`). */
.kl-prose > .kl-page-header {
	max-width: var(--kl-measure);
	font-size: var(--kl-text-md);
}

/* Privacy / Cookie pages (dev-012): the "last updated" line closes the prose. */
.kl-legal__updated {
	margin-top: var(--kl-space-6);
	padding-top: var(--kl-space-4);
	border-top: 1px solid var(--kl-border);
	color: var(--kl-slate);
	font-family: var(--kl-font-mono);
	font-size: var(--kl-text-sm);
}

/* ---------------------------------------------------------------- Prose --- */

/* The reading measure applies to text, not to tables: a five-column log table
   squeezed into 72ch becomes a column of two-word lines. */
.kl-prose {
	max-width: none;
}

.kl-prose p,
.kl-prose li,
.kl-prose h2,
.kl-prose h3,
.kl-prose .kl-callout,
.kl-prose .kl-signature {
	max-width: var(--kl-measure);
}

.kl-prose h2 {
	margin-top: var(--kl-space-7);
	padding-top: var(--kl-space-2);
	font-size: var(--kl-text-2xl);
}

.kl-prose h3 {
	margin-top: var(--kl-space-5);
	font-size: var(--kl-text-lg);
}

.kl-prose p,
.kl-prose li {
	font-size: var(--kl-text-md);
}

.kl-prose p {
	margin: 0 0 var(--kl-space-4);
}

.kl-prose ul,
.kl-prose ol {
	margin: 0 0 var(--kl-space-4);
	padding-left: var(--kl-space-5);
}

.kl-prose li + li {
	margin-top: var(--kl-space-2);
}

.kl-prose code {
	font-family: var(--kl-font-mono);
	font-size: 0.9em;
}

.kl-prose .kl-table-wrap {
	margin: 0 0 var(--kl-space-5);
}

.kl-callout {
	margin: var(--kl-space-5) 0;
	padding: var(--kl-space-4) var(--kl-space-5);
	border: 1px solid var(--kl-border);
	border-left: 4px solid var(--kl-level-b);
	border-radius: var(--kl-radius-card);
	background: var(--kl-paper-alt);
}

.kl-callout__title {
	display: flex;
	align-items: center;
	gap: var(--kl-space-2);
	margin: 0 0 var(--kl-space-2);
	font-size: var(--kl-text-base);
	font-weight: var(--kl-weight-semibold);
	color: var(--kl-level-b);
}

.kl-callout p:last-child {
	margin-bottom: 0;
}

.kl-signature {
	margin: var(--kl-space-6) 0 0;
	padding: var(--kl-space-5);
	border: 1px solid var(--kl-border);
	border-radius: var(--kl-radius-card);
	background: var(--kl-paper-alt);
}

.kl-signature dl {
	display: grid;
	grid-template-columns: max-content minmax(0, 1fr);
	gap: var(--kl-space-2) var(--kl-space-4);
	margin: 0;
	font-size: var(--kl-text-base);
}

.kl-signature dt {
	color: var(--kl-slate);
}

.kl-signature dd {
	margin: 0;
}

/* ------------------------------------------------------------ Services --- */

/* The admission-timing block (dev-035 T1). It sits directly under the services
   page header and states the range and the expedited case once; the condition
   and the boundary stay ordinary paragraphs under it, so the qualifiers read as
   part of the statement rather than as fine print. The accent rule on the
   leading edge marks it as the page's answer to "how long does this take".
   Row width sits on the paragraphs, not on the box (known-issues #8). */

.kl-admission {
	margin: 0 0 var(--kl-space-6);
	padding: var(--kl-space-5);
	border: 1px solid var(--kl-border);
	border-left: 3px solid var(--kl-accent);
	border-radius: var(--kl-radius-card);
	background: var(--kl-accent-soft);
}

.kl-admission__title {
	margin: 0 0 var(--kl-space-3);
	font-size: var(--kl-text-lg);
}

.kl-admission__headline {
	margin: 0;
	max-width: var(--kl-measure);
	color: var(--kl-ink);
	font-size: var(--kl-text-md);
}

.kl-admission__condition,
.kl-admission__boundary {
	margin: var(--kl-space-3) 0 0;
	max-width: var(--kl-measure);
	color: var(--kl-slate);
}

.kl-partner {
	margin-top: var(--kl-space-5);
	padding: var(--kl-space-5);
	border: 1px solid var(--kl-border);
	border-radius: var(--kl-radius-card);
	background: var(--kl-paper-alt);
}

.kl-partner__head {
	display: flex;
	align-items: flex-start;
	gap: var(--kl-space-3);
	margin-bottom: var(--kl-space-3);
}

.kl-partner__title {
	margin: 0;
	font-size: var(--kl-text-lg);
}

.kl-partner__by {
	margin: var(--kl-space-1) 0 0;
	color: var(--kl-slate);
	font-size: var(--kl-text-sm);
}

/* The partner logo is the user-supplied file (no hotlink, no recolouring). It
   is shown on a white plate so the file's own white background reads as
   deliberate against the off-white card, and it carries the partner name as
   its alt text. */
.kl-partner__logo {
	margin: var(--kl-space-3) 0 0;
}

.kl-partner__logo img {
	display: block;
	width: 255px;
	height: auto;
	max-width: 100%;
	padding: var(--kl-space-2);
	border: 1px solid var(--kl-border);
	border-radius: var(--kl-radius-input);
	background: var(--kl-paper);
	/* fix-008 T5 (ui-019): the logo used to stretch to the row's height, which
	   distorted it by ~11%. Contain keeps the artwork's own ratio on every row. */
	object-fit: contain;
	align-self: center;
}

/* --------------------------------------------------------- News coming soon --- */
/* fix-008 T4 (ui-015): the section is announced, not faked - the page names the
   six checks an item must pass before it can appear. */

.kl-news-coming {
	max-width: var(--kl-measure);
	margin: var(--kl-space-6) 0;
}

.kl-news-coming__lede {
	margin: 0 0 var(--kl-space-5);
	font-size: var(--kl-text-lg);
	color: var(--kl-slate);
}

.kl-news-coming__title {
	margin: 0 0 var(--kl-space-3);
	font-size: var(--kl-text-xl);
}

.kl-news-coming__list {
	margin: 0 0 var(--kl-space-5);
	padding-left: var(--kl-space-5);
}

.kl-news-coming__list li {
	margin-bottom: var(--kl-space-2);
}

.kl-news-coming__note {
	margin: 0 0 var(--kl-space-4);
	color: var(--kl-slate);
}

.kl-news-coming__links {
	margin: 0;
}

/* --------------------------------------------------------- News section ---
   dev-016: the news list and single pages. A card states the AI-assisted
   label, the date and the source name; the single page repeats them and adds
   the original-article button and the copyright block. Copy is verbatim from
   docs/文案-资讯栏目_v0.md. */

.kl-news-card__badge {
	align-self: flex-start;
	margin: 0 0 var(--kl-space-3);
	padding: var(--kl-space-1) var(--kl-space-3);
	border-radius: var(--kl-radius-pill);
	background: var(--kl-accent-soft);
	color: var(--kl-accent-hover);
	font-size: var(--kl-text-xs);
	letter-spacing: var(--kl-tracking-caps);
	text-transform: uppercase;
}

.kl-news-card__meta,
.kl-news-entry__meta {
	display: flex;
	flex-wrap: wrap;
	gap: var(--kl-space-1) var(--kl-space-4);
}

.kl-news-entry__ai {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--kl-space-2) var(--kl-space-3);
	margin: var(--kl-space-4) 0 0;
}

.kl-news-entry__badge {
	display: inline-block;
	margin: 0;
	padding: var(--kl-space-1) var(--kl-space-3);
	border-radius: var(--kl-radius-pill);
	background: var(--kl-accent-soft);
	color: var(--kl-accent-hover);
	font-size: var(--kl-text-xs);
	letter-spacing: var(--kl-tracking-caps);
	text-transform: uppercase;
}

.kl-news-entry__ai-note,
.kl-news-entry__rights {
	color: var(--kl-slate);
	font-size: var(--kl-text-sm);
}

.kl-news-entry__original {
	margin: var(--kl-space-6) 0 0;
}

/* The original-article button is a primary action: it keeps a 44px touch
   height on every viewport (master §T2.4 / WCAG 2.5.8). */
.kl-news-entry__original-link {
	min-height: 44px;
}

.kl-news-entry__copyright {
	max-width: var(--kl-measure);
	margin: var(--kl-space-7) 0 0;
	padding: var(--kl-space-5);
	border: 1px solid var(--kl-border);
	border-left: 4px solid var(--kl-slate);
	border-radius: var(--kl-radius-card);
	background: var(--kl-paper-alt);
}

.kl-news-entry__copyright-title {
	margin: 0 0 var(--kl-space-3);
	font-size: var(--kl-text-lg);
}

.kl-news-entry__copyright p {
	margin: 0 0 var(--kl-space-3);
}

.kl-news-entry__copyright p:last-child {
	margin-bottom: 0;
}

.kl-news-entry__links {
	margin: var(--kl-space-6) 0 0;
}

.kl-partner__link {
	margin: var(--kl-space-3) 0 0;
}

/* "How to reach us" (dev-011 T2). Email is the live channel; the WhatsApp
   placeholder is shown, labelled and never linked. */
.kl-contact {
	margin-top: var(--kl-space-6);
	padding: var(--kl-space-5);
	border: 1px solid var(--kl-border);
	border-radius: var(--kl-radius-card);
	background: var(--kl-paper);
}

.kl-contact__title {
	margin: 0 0 var(--kl-space-3);
	font-size: var(--kl-text-lg);
}

.kl-contact__body p {
	margin: 0;
}

.kl-contact__body p + p {
	margin-top: var(--kl-space-2);
}

.kl-contact__qr {
	margin: var(--kl-space-4) 0 0;
}

.kl-contact__qr-label {
	margin: 0 0 var(--kl-space-2);
	color: var(--kl-slate);
	font-size: var(--kl-text-sm);
	font-weight: var(--kl-weight-semibold);
}

.kl-contact__qr img {
	display: block;
	width: 160px;
	height: auto;
	max-width: 100%;
}

.kl-declaration {
	margin-top: var(--kl-space-6);
	padding: var(--kl-space-5);
	border: 1px solid var(--kl-border);
	border-radius: var(--kl-radius-card);
	background: var(--kl-paper-alt);
	color: var(--kl-slate);
	font-size: var(--kl-text-base);
}

.kl-declaration p {
	margin: 0;
}

.kl-declaration p + p {
	margin-top: var(--kl-space-2);
}

/* -------------------------------------------------- Insurance guide (dev-034) ---
   The seventh block of /insurance/ (scope statement + partner + the
   direct-billing slot). It reuses the existing declaration, partner and
   empty-state shapes; only the outer spacing and the slot heading are new. */

.kl-insurance__scope {
	margin-top: var(--kl-space-6);
}

.kl-insurance__scope-title {
	margin: 0 0 var(--kl-space-3);
	font-size: var(--kl-text-2xl);
}

.kl-insurance__scope .kl-declaration,
.kl-insurance__direct > p {
	max-width: var(--kl-measure);
}

.kl-insurance__direct {
	margin-top: var(--kl-space-5);
}

.kl-insurance__direct h3 {
	margin: 0 0 var(--kl-space-2);
	font-size: var(--kl-text-lg);
}

/* The direct-billing list (dev-037). Each record is a card, so a long hospital
   name and its source line stay legible at 390px without a horizontal scroll;
   "inpatient only" is a pill because it is a restriction the entry carries, not
   a feature of it. Only new selectors here - the slot's existing rules and the
   shared tokens are untouched. */

.kl-insurance__direct-list {
	display: grid;
	gap: var(--kl-space-4);
	margin: var(--kl-space-4) 0 0;
	padding: 0;
	list-style: none;
}

.kl-insurance__record {
	margin: 0;
	padding: var(--kl-space-5);
	border: 1px solid var(--kl-border);
	border-radius: var(--kl-radius-card);
	background: var(--kl-paper);
}

.kl-insurance__record-name {
	margin: 0;
	font-size: var(--kl-text-md);
	font-weight: var(--kl-weight-semibold);
	line-height: var(--kl-leading-snug);
	overflow-wrap: anywhere;
}

.kl-insurance__record-meta {
	margin: var(--kl-space-2) 0 0;
	color: var(--kl-slate);
	font-size: var(--kl-text-sm);
}

.kl-insurance__insurers {
	margin: var(--kl-space-3) 0 0;
	font-size: var(--kl-text-sm);
	overflow-wrap: anywhere;
}

.kl-insurance__inpatient {
	display: inline-block;
	margin: var(--kl-space-3) 0 0;
	padding: var(--kl-space-1) var(--kl-space-3);
	border: 1px solid var(--kl-border-strong);
	border-radius: var(--kl-radius-pill);
	background: var(--kl-note-bg);
	color: var(--kl-ink);
	font-size: var(--kl-text-xs);
	font-weight: var(--kl-weight-semibold);
	letter-spacing: var(--kl-tracking-caps);
	text-transform: uppercase;
}

.kl-insurance__record-source {
	margin: var(--kl-space-3) 0 0;
	font-size: var(--kl-text-sm);
	overflow-wrap: anywhere;
}

.kl-insurance__direct-footer {
	margin: var(--kl-space-5) 0 0;
	color: var(--kl-slate);
	font-size: var(--kl-text-sm);
}

/* ------------------------------------------------------------- Utility --- */

.kl-empty {
	max-width: 68ch;
	margin: 0 0 var(--kl-space-4);
	padding: var(--kl-space-5);
	border: 1px dashed var(--kl-border-strong);
	border-radius: var(--kl-radius-card);
	background: var(--kl-paper-alt);
	color: var(--kl-slate);
}

.kl-empty--scoped {
	direction: ltr;
}

.kl-no-results {
	max-width: 68ch;
}

.kl-pagination,
.pagination {
	margin-top: var(--kl-space-6);
}

.kl-pagination .page-numbers,
.pagination .page-numbers {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 44px;
	min-height: 44px;
	margin-right: var(--kl-space-2);
	padding: 0 var(--kl-space-2);
	border: 1px solid var(--kl-border-strong);
	border-radius: var(--kl-radius-pill);
	color: var(--kl-ink);
	text-decoration: none;
}

.kl-pagination .page-numbers.current,
.pagination .page-numbers.current {
	background: var(--kl-accent);
	border-color: var(--kl-accent);
	color: var(--kl-paper);
}

.kl-post-nav {
	margin-top: var(--kl-space-6);
	padding-top: var(--kl-space-4);
	border-top: 1px solid var(--kl-border);
	font-size: var(--kl-text-base);
}

/* -------------------------------------------------------------- Footer --- */

.kl-footer {
	margin-top: var(--kl-space-8);
	padding: var(--kl-space-7) 0 var(--kl-space-6);
	background: var(--kl-navy);
	color: var(--kl-on-navy-muted);
	font-size: var(--kl-text-base);
}

.kl-footer a {
	color: var(--kl-on-navy);
}

.kl-footer__top {
	display: flex;
	flex-wrap: wrap;
	gap: var(--kl-space-6);
	justify-content: space-between;
	padding-bottom: var(--kl-space-5);
	border-bottom: 1px solid rgba(255, 255, 255, 0.14);
}

.kl-footer__brand {
	max-width: 40ch;
}

.kl-footer__brand-title {
	margin: 0;
	color: var(--kl-on-navy);
	font-size: var(--kl-text-lg);
	font-weight: var(--kl-weight-semibold);
}

.kl-footer__brand-note {
	margin: var(--kl-space-2) 0 0;
}

.kl-footer__nav-title {
	margin: 0 0 var(--kl-space-3);
	color: var(--kl-on-navy);
	font-size: var(--kl-text-sm);
	letter-spacing: var(--kl-tracking-caps);
	text-transform: uppercase;
}

.kl-footer__list {
	display: flex;
	flex-wrap: wrap;
	gap: var(--kl-space-3) var(--kl-space-5);
	margin: 0;
	padding: 0;
	list-style: none;
}

.kl-footer__disclaimer,
.kl-footer__note {
	max-width: 80ch;
	margin: var(--kl-space-4) 0 0;
}

.kl-footer__copy {
	margin: var(--kl-space-4) 0 0;
	font-size: var(--kl-text-sm);
}

/* -------------------------------------------------------------- Facets ---
   The directory filter bar (dev-010). Every facet value is an anchor, so the
   whole directory filters without JavaScript; the selected value keeps the
   shared chip's solid state and stays clickable to clear itself. */

.kl-facets {
	margin: 0 0 var(--kl-space-6);
	padding: var(--kl-space-5);
	border: 1px solid var(--kl-border);
	border-radius: var(--kl-radius-card);
	background: var(--kl-paper-alt);
}

.kl-facets__group + .kl-facets__group {
	margin-top: var(--kl-space-4);
}

.kl-facets__title {
	margin: 0 0 var(--kl-space-2);
	color: var(--kl-slate);
	font-size: var(--kl-text-xs);
	font-weight: var(--kl-weight-semibold);
	letter-spacing: var(--kl-tracking-caps);
	text-transform: uppercase;
}

.kl-chip--facet {
	gap: var(--kl-space-2);
}

.kl-chip__count {
	color: var(--kl-slate);
	font-size: var(--kl-text-xs);
	font-variant-numeric: tabular-nums;
}

.kl-chip--selected .kl-chip__count {
	color: var(--kl-on-navy-muted);
}

.kl-facets__clear {
	margin: var(--kl-space-4) 0 0;
	padding-top: var(--kl-space-3);
	border-top: 1px solid var(--kl-border);
	font-size: var(--kl-text-sm);
}

.kl-facets__clear-link {
	color: var(--kl-accent-hover);
}

/* The grade block's one sentence: the published band is an administrative
   designation, not a quality judgement (dev-013). */
.kl-facets__note {
	margin: var(--kl-space-2) 0 0;
	color: var(--kl-slate);
	font-size: var(--kl-text-xs);
}

.kl-archive__count {
	margin: 0 0 var(--kl-space-4);
	color: var(--kl-slate);
	font-size: var(--kl-text-sm);
}

/* -------------------------------------------------------- Touch targets ---
   fix-007 T7 (ledger ui-009): every element a visitor can tap is at least 44px
   tall. Block components take a min-height; inline links in prose grow their
   hit box with vertical padding, which does not change the line box. The only
   exceptions are the visually hidden elements (`.kl-skip-link`,
   `.kl-visually-hidden`), which are keyboard-only. */

.kl-btn,
.kl-nav__list a,
.kl-module__title a,
.kl-card__title a,
.kl-news-list__item a,
.kl-footer__list a,
.kl-panel a,
.kl-service__contact a,
.kl-branding__title a,
.kl-lang__toggle,
.kl-lang__link,
.kl-pagination .page-numbers {
	display: inline-flex;
	align-items: center;
	min-height: 44px;
}

/* A card/module title stacks the English name over the Chinese one.
   dev-052 (ledger ui-033): the 44px hit-area group above hands this link
   `align-items: center`, so the stacked title was centred inside a
   full-width box. A short title landed in the middle of the card while every
   other line (meta, chips, excerpt, footer) stayed on the card's left edge,
   and a long title filled the box and read as left-aligned - one card grid
   could show both. `justify-content: center` had the same effect vertically:
   inside the 72px title box a one-line title sat lower than a two-line one,
   so titles on one row did not share a baseline. The box is now top-left
   aligned; `min-height: 72px` below still keeps the excerpt starting at the
   same y on every card in a row. */
.kl-module__title a,
.kl-card__title a {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	justify-content: flex-start;
	text-align: left;
}

.kl-main p > a,
.kl-main li > a {
	padding-top: var(--kl-space-4);
	padding-bottom: var(--kl-space-4);
}

/* ------------------------------------------------- City landing (dev-015) ---
   The L1 entrance of /hospitals/ (ledger ui-003 / ui-023). dev-015 T1 splits
   the page: the facet wall and the 730-row listing moved to /hospitals/all/,
   so the landing is the search box, the 12 curated city cards, ONE "Browse by
   province" fold and the "All hospitals" entry. Everything is a link or a
   native `<details>`, so the page needs no JavaScript at all. */

.kl-landing {
	margin: 0 0 var(--kl-space-7);
}

.kl-landing__title {
	margin: 0 0 var(--kl-space-2);
	font-size: var(--kl-text-xl);
}

.kl-landing__lede {
	max-width: 68ch;
	margin: 0 0 var(--kl-space-4);
	color: var(--kl-slate);
	font-size: var(--kl-text-base);
}

/* The city cards: an equal-height grid (T4.1) whose columns step from four
   (desktop) to three to two, so the row height is the tallest card's height and
   a sparse record never leaves a short card beside a tall one. */
.kl-city-cards {
	display: grid;
	grid-template-columns: repeat(4, minmax(0, 1fr));
	grid-auto-rows: 1fr;
	gap: var(--kl-space-4);
	margin: 0;
	padding: 0;
	list-style: none;
}

@media (max-width: 1199px) {
	.kl-city-cards {
		grid-template-columns: repeat(3, minmax(0, 1fr));
	}
}

@media (max-width: 899px) {
	.kl-city-cards {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}
}

@media (max-width: 599px) {
	.kl-city-cards {
		grid-template-columns: repeat(2, minmax(0, 1fr));
		gap: var(--kl-space-3);
	}
}

.kl-city-card {
	display: flex;
}

.kl-city-cards .kl-city-card__link {
	display: flex;
	flex-direction: column;
	width: 100%;
	height: 100%;
	min-height: 44px;
	padding: 0;
	overflow: hidden;
	border: 1px solid var(--kl-border);
	border-radius: var(--kl-radius-card);
	background: var(--kl-paper);
	color: inherit;
	text-decoration: none;
}

.kl-city-card__link:hover,
.kl-city-card__link:focus {
	border-color: var(--kl-border-strong);
}

.kl-city-card__img {
	display: block;
	width: 100%;
	height: auto;
	aspect-ratio: 16 / 10;
	object-fit: cover;
	background: var(--kl-paper-alt);
}

/* The no-image fallback (T4.3): the card keeps a 16:10 band with a map pin, so
   a missing asset leaves no empty frame and the grid stays even. */
.kl-city-card__icon {
	display: flex;
	align-items: center;
	justify-content: center;
	aspect-ratio: 16 / 10;
	background: var(--kl-paper-alt);
	color: var(--kl-slate);
}

.kl-city-card__icon .kl-icon {
	width: 40px;
	height: 40px;
}

.kl-city-card__body {
	display: flex;
	flex: 1 1 auto;
	flex-direction: column;
	gap: var(--kl-space-1);
	padding: var(--kl-space-4);
}

.kl-city-card__name {
	font-size: var(--kl-text-lg);
	font-weight: var(--kl-weight-semibold);
}

.kl-city-card__link:hover .kl-city-card__name,
.kl-city-card__link:focus .kl-city-card__name {
	color: var(--kl-accent-hover);
}

.kl-city-card__zh,
.kl-city-card__count {
	color: var(--kl-slate);
	font-size: var(--kl-text-sm);
}

/* Push the count to the foot of the card so the three lines line up across a
   row of equal-height cards. */
.kl-city-card__body .kl-city-card__count {
	margin-top: auto;
}

/* One "Browse by province" fold (dev-015 T1): a single <details> whose summary
   is the section heading, opening a compact 3-column list of province links. */
.kl-provinces {
	display: block;
}

.kl-province {
	border: 1px solid var(--kl-border);
	border-radius: var(--kl-radius-input);
	background: var(--kl-paper);
}

.kl-province__summary {
	display: flex;
	align-items: center;
	gap: var(--kl-space-2);
	min-height: 44px;
	padding: var(--kl-space-2) var(--kl-space-3);
	cursor: pointer;
	list-style: none;
	font-size: var(--kl-text-md);
}

.kl-province--single .kl-province__summary {
	padding: var(--kl-space-3) var(--kl-space-4);
	font-size: var(--kl-text-xl);
}

.kl-province__summary::-webkit-details-marker {
	display: none;
}

.kl-province__summary::after {
	content: "";
	flex: 0 0 auto;
	width: 8px;
	height: 8px;
	margin-left: var(--kl-space-2);
	border-right: 2px solid var(--kl-slate);
	border-bottom: 2px solid var(--kl-slate);
	transform: rotate(45deg);
	transition: transform var(--kl-dur-fast) var(--kl-ease);
}

.kl-province[open] .kl-province__summary::after {
	transform: rotate(-135deg);
}

.kl-province__name {
	font-weight: var(--kl-weight-semibold);
}

.kl-province__summary .kl-province__count {
	margin-left: auto;
}

.kl-province__zh,
.kl-province__count {
	color: var(--kl-slate);
	font-size: var(--kl-text-sm);
	font-variant-numeric: tabular-nums;
}

.kl-province__list {
	margin: 0;
	padding: 0 0 var(--kl-space-2);
	list-style: none;
	border-top: 1px solid var(--kl-border);
}

.kl-province__list li {
	margin: 0;
}

.kl-provinces .kl-province__list a {
	display: flex;
	align-items: center;
	gap: var(--kl-space-2);
	min-height: 44px;
	padding: var(--kl-space-2) var(--kl-space-3);
	color: inherit;
	text-decoration: none;
	font-size: var(--kl-text-base);
}

.kl-province__list a:hover,
.kl-province__list a:focus {
	color: var(--kl-accent-hover);
	background: var(--kl-paper-alt);
}

.kl-province__list .kl-province__count {
	margin-left: auto;
}

/* The compact 3-column province list (T1.1); it steps to two columns, then
   one, as the viewport narrows. */
.kl-province__list--grid {
	display: grid;
	grid-template-columns: repeat(3, minmax(0, 1fr));
	gap: 0 var(--kl-space-4);
}

@media (max-width: 899px) {
	.kl-province__list--grid {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}
}

@media (max-width: 599px) {
	.kl-province__list--grid {
		grid-template-columns: 1fr;
	}
}

.kl-landing__all {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--kl-space-3);
	max-width: none;
	margin: var(--kl-space-6) 0 0;
}

.kl-landing__all-link {
	display: inline-flex;
	align-items: center;
	min-height: 44px;
	padding: 0 var(--kl-space-5);
	border: 1px solid var(--kl-border-strong);
	border-radius: var(--kl-radius-pill);
	background: var(--kl-paper);
	font-weight: var(--kl-weight-semibold);
}

.kl-landing__all-note {
	color: var(--kl-slate);
	font-size: var(--kl-text-sm);
}

.kl-all-hospitals__title {
	margin: 0 0 var(--kl-space-4);
	font-size: var(--kl-text-xl);
}

.kl-all-hospitals--preceded {
	margin-top: var(--kl-space-6);
	padding-top: var(--kl-space-6);
	border-top: 1px solid var(--kl-border);
}

.kl-all-hospitals {
	scroll-margin-top: var(--kl-space-6);
}

.kl-archive__sort-note {
	margin: calc(-1 * var(--kl-space-3)) 0 var(--kl-space-5);
	color: var(--kl-slate);
	font-size: var(--kl-text-xs);
}

/* The header line of a simplified result view (dev-015 T3): the filter in
   effect, the way back to the landing and one "Clear filter". */
.kl-archive__filter {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--kl-space-1) var(--kl-space-3);
	margin: 0 0 var(--kl-space-4);
	color: var(--kl-slate);
	font-size: var(--kl-text-sm);
}

.kl-archive__filter-value {
	color: var(--kl-ink);
}

.kl-archive__filter .kl-archive__filter-change,
.kl-archive__filter .kl-facets__clear-link {
	display: inline-flex;
	align-items: center;
	min-height: 44px;
}

.kl-archive__filter .kl-facets__clear-link {
	margin-left: auto;
}

/* Equal-height hospital cards (ledger ui-013): every row takes the height of
   its tallest card, so a sparse record no longer leaves a one-line card beside
   a full one. Scoped to the hospital listing; the other archives are a later
   batch. */
.kl-archive--hospitals .kl-card-list {
	grid-auto-rows: 1fr;
	align-items: stretch;
}

/* --------------------------------------------- Hospital detail (dev-014) ---
   T3 puts the record in a wide main column with the key-facts / enquiry panel
   beside it, so the page no longer reads as one 544px strip (ledger ui-012),
   adds the breadcrumb, and grows the inline links a finger has to hit to 44px
   (ledger ui-013 / e2e-003). */

.kl-single--hospital .kl-entry {
	max-width: none;
}

.kl-breadcrumb {
	margin: 0 0 var(--kl-space-4);
}

.kl-breadcrumb__list {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 0 var(--kl-space-1);
	margin: 0;
	padding: 0;
	list-style: none;
	color: var(--kl-slate);
	font-size: var(--kl-text-sm);
}

.kl-breadcrumb__item + .kl-breadcrumb__item::before {
	content: "›";
	color: var(--kl-slate);
}

.kl-breadcrumb__item a,
.kl-breadcrumb__item [aria-current] {
	display: inline-flex;
	align-items: center;
	min-height: 44px;
}

.kl-breadcrumb__item a {
	color: var(--kl-slate);
}

.kl-breadcrumb__item a:hover,
.kl-breadcrumb__item a:focus {
	color: var(--kl-accent-hover);
}

.kl-breadcrumb__item [aria-current] {
	color: var(--kl-ink);
}

.kl-entry__body {
	display: grid;
	grid-template-columns: minmax(0, 1fr) 320px;
	gap: var(--kl-space-6) var(--kl-space-7);
	align-items: start;
	margin-top: var(--kl-space-5);
}

.kl-entry__main {
	min-width: 0;
}

.kl-entry__aside {
	display: flex;
	flex-direction: column;
	gap: var(--kl-space-5);
}

.kl-facts {
	padding: var(--kl-space-5);
	border: 1px solid var(--kl-border);
	border-radius: var(--kl-radius-card);
	background: var(--kl-paper-alt);
}

.kl-facts__title,
.kl-cta__title {
	margin: 0 0 var(--kl-space-3);
	font-size: var(--kl-text-lg);
}

.kl-facts__list {
	margin: 0;
}

.kl-facts__row + .kl-facts__row {
	margin-top: var(--kl-space-3);
	padding-top: var(--kl-space-3);
	border-top: 1px solid var(--kl-border);
}

.kl-facts__label {
	margin: 0 0 var(--kl-space-1);
	color: var(--kl-slate);
	font-size: var(--kl-text-xs);
	font-weight: var(--kl-weight-semibold);
	letter-spacing: var(--kl-tracking-caps);
	text-transform: uppercase;
}

.kl-facts__value {
	margin: 0;
	overflow-wrap: anywhere;
}

/* A link inside the panel (the hospital's own site) is a finger target too. */
.kl-facts__value a {
	display: inline-flex;
	align-items: center;
	min-height: 44px;
}

.kl-fact__source {
	display: block;
	margin-top: var(--kl-space-1);
	color: var(--kl-slate);
	font-size: var(--kl-text-sm);
}

.kl-cta {
	padding: var(--kl-space-5);
	border: 1px solid var(--kl-border);
	border-radius: var(--kl-radius-card);
	background: var(--kl-paper);
}

.kl-cta__lede {
	margin: 0 0 var(--kl-space-3);
	color: var(--kl-slate);
	font-size: var(--kl-text-sm);
}

.kl-cta .kl-btn-note {
	display: block;
	margin-top: var(--kl-space-2);
	color: var(--kl-slate);
	font-size: var(--kl-text-sm);
}

/* The layer line under the CTA (dev-020): the pilot-award evidence line on an
   A1 / A2 page, the "we have not verified" note on a B / C page. */
.kl-cta__evidence,
.kl-cta__note {
	margin: var(--kl-space-2) 0 0;
	color: var(--kl-slate);
	font-size: var(--kl-text-sm);
}

.kl-cta__evidence a {
	overflow-wrap: anywhere;
}

/* Previous / next hospital: a finger target, not a sentence. */
.kl-single .post-navigation a {
	display: inline-flex;
	align-items: center;
	min-height: 44px;
}

/* The record's own links (the official site row, a row's source URL) sit in a
   `<dd>`, which the shared inline-link padding rule does not cover, so they get
   the 44px box here. Scoped to the hospital page: this batch does not touch the
   other single templates. */
.kl-single--hospital .kl-fields__list dd a,
.kl-single--hospital .kl-source__list a {
	display: inline-flex;
	align-items: center;
	min-height: 44px;
}

@media (max-width: 900px) {
	.kl-entry__body {
		grid-template-columns: minmax(0, 1fr);
	}

	/* A source link inside a table row is tapped, not read: give it a 44px box
	   on small screens only (the desktop inline-link size is exempt). */
	.kl-table .kl-source-cell a {
		display: inline-flex;
		align-items: center;
		min-height: 44px;
		padding-block: var(--kl-space-2);
	}
}

/* ------------------------------------------------------- Breakpoints --- */

@media (max-width: 900px) {
	/* Mobile header (fix-007 T7): at most two compact rows - the brand and the
	   menu button on the first, the language selector and the search on the
	   second. The menu itself overlays the page, so opening it never makes the
	   header taller. */
	.kl-header__inner {
		position: relative;
		flex-wrap: wrap;
		gap: var(--kl-space-2);
		padding-top: var(--kl-space-2);
		padding-bottom: var(--kl-space-2);
	}

	.kl-branding {
		order: 1;
		flex: 1 1 200px;
		min-width: 0;
	}

	/* The tagline is dropped on small screens so the brand and the menu button
	   share one row (the header height budget does not allow three rows). */
	.kl-branding__tagline {
		display: none;
	}

	.kl-nav__details {
		display: block;
		order: 2;
		flex: 0 0 auto;
	}

	.kl-lang {
		order: 3;
	}

	.kl-nav__toggle {
		display: inline-flex;
		align-items: center;
		gap: var(--kl-space-2);
		min-height: 44px;
		padding: 0 var(--kl-space-4);
		border: 1px solid var(--kl-border-strong);
		border-radius: var(--kl-radius-pill);
		background: var(--kl-paper);
		color: var(--kl-ink);
		cursor: pointer;
		list-style: none;
	}

	.kl-nav__toggle::-webkit-details-marker {
		display: none;
	}

	/* The menu row ships hidden on mobile and is revealed by the opened
	   disclosure; it overlays the page so the header keeps its height. */
	.kl-nav {
		display: none;
	}

	.kl-nav__details[open] ~ .kl-nav {
		display: block;
		position: absolute;
		left: 0;
		right: 0;
		top: 100%;
		z-index: 30;
		padding: var(--kl-space-3) var(--kl-space-5) var(--kl-space-4);
		background: var(--kl-paper);
		border-top: 1px solid var(--kl-border);
		box-shadow: var(--kl-shadow-2);
	}

	.kl-nav__list {
		flex-direction: column;
		gap: 0;
	}

	.kl-nav__list a {
		width: 100%;
	}
}

@media (max-width: 1024px) {
	.kl-modules {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}

	.kl-policy {
		grid-template-columns: minmax(0, 1fr);
	}

	.kl-policy__toc {
		position: static;
	}
}

@media (max-width: 860px) {
	.kl-hero {
		padding: var(--kl-space-7) 0 var(--kl-space-6);
	}

	.kl-hero__inner {
		grid-template-columns: minmax(0, 1fr);
		gap: var(--kl-space-6);
	}

	.kl-hero__title {
		font-size: var(--kl-text-3xl);
	}

	.kl-columns {
		grid-template-columns: minmax(0, 1fr);
		gap: var(--kl-space-6);
	}

	.kl-services {
		grid-template-columns: minmax(0, 1fr);
	}
}

@media (max-width: 700px) {
	.kl-section {
		padding: var(--kl-space-6) 0;
	}

	.kl-section--tight {
		padding: var(--kl-space-5) 0;
	}

	.kl-section__title {
		font-size: var(--kl-text-xl);
	}

	.kl-entry__title {
		font-size: var(--kl-text-2xl);
	}

	.kl-hero__title {
		font-size: var(--kl-text-2xl);
	}

	.kl-hero__lede {
		font-size: var(--kl-text-md);
	}

	.kl-trust__sep {
		display: none;
	}

	.kl-trust__list {
		gap: var(--kl-space-4) var(--kl-space-5);
	}

	.kl-source__list,
	.kl-fields__list,
	.kl-signature dl {
		grid-template-columns: minmax(0, 1fr);
		gap: var(--kl-space-1);
	}

	.kl-source__list dt,
	.kl-fields__list dt {
		margin-top: var(--kl-space-2);
	}

	.kl-footer__top {
		gap: var(--kl-space-5);
	}
}

@media (max-width: 520px) {
	.kl-modules {
		grid-template-columns: minmax(0, 1fr);
	}
}

@media (prefers-reduced-motion: reduce) {
	*,
	*::before,
	*::after,
	/* dev-025: `::backdrop` is a pseudo-element of the element, not of `*` or
	   `::before` / `::after`, so the selector list has to name it or the
	   selector sheet's backdrop fade would survive a reduced-motion request. */
	*::backdrop {
		animation-duration: 0.001ms !important;
		animation-iteration-count: 1 !important;
		transition-duration: 0.001ms !important;
		scroll-behavior: auto !important;
	}
}

/* -------------------------------------------------- Why China (dev-017) --- */
/* The advantage pages (treatment volume / technology access / visas and
   entry). Charts are inline SVG drawn by inc/advantages.php: no JavaScript,
   no third-party resource, no new font. */

.kl-adv {
	padding-top: var(--kl-space-7);
}

.kl-adv__title {
	font-size: var(--kl-text-3xl);
}

.kl-adv__banner {
	margin: 0 0 var(--kl-space-7);
	padding: var(--kl-space-3) var(--kl-space-4);
	border: 1px solid var(--kl-border);
	border-left: 4px solid var(--kl-accent);
	border-radius: var(--kl-radius-input);
	background: var(--kl-accent-soft);
	color: var(--kl-slate);
	font-size: var(--kl-text-sm);
}

.kl-adv__block {
	margin: 0 0 var(--kl-space-8);
}

.kl-adv__block-title {
	margin-bottom: var(--kl-space-4);
	padding-bottom: var(--kl-space-2);
	border-bottom: 1px solid var(--kl-border);
}

.kl-adv__block-note {
	margin: 0 0 var(--kl-space-4);
	color: var(--kl-slate);
	font-size: var(--kl-text-sm);
}

/* Charts: a fixed 720-unit drawing keeps the labels at their designed size;
   a narrower screen scrolls the chart instead of shrinking the type. */

.kl-adv__figure {
	margin: 0 0 var(--kl-space-5);
}

.kl-adv__chart-wrap {
	overflow-x: auto;
	padding-bottom: var(--kl-space-1);
}

.kl-adv__chart {
	display: block;
	width: 720px;
	max-width: none;
	height: auto;
}

.kl-adv__chart text {
	fill: var(--kl-ink);
	font-family: var(--kl-font-sans);
	font-size: 14px;
}

.kl-adv__bar-label {
	fill: var(--kl-slate);
}

.kl-adv__chart-value {
	font-weight: var(--kl-weight-semibold);
	font-variant-numeric: tabular-nums;
}

.kl-adv__bar {
	fill: var(--kl-accent);
}

.kl-adv__caption {
	margin-top: var(--kl-space-3);
	color: var(--kl-slate);
	font-size: var(--kl-text-sm);
}

/* Data table: the metric and caliber columns carry the text, the value and
   as-of columns stay in the mono face so figures line up down the column. */

.kl-adv__table .kl-adv__metric,
.kl-adv__table .kl-adv__caliber {
	min-width: 180px;
}

/* dev-056: the `white-space: nowrap` that used to sit here was a defect, not a
   style. On `/why-china-visa-and-entry/` it made the browser size `Year or
   as-of` to 401px and squeeze `Caliber` into 182px, so every row of that page's
   longest table grew to ~280px and the page to 14,390px. The two short columns
   are free to wrap now; the mono face and the tabular figures stay, so a column
   still reads down. GLOBAL on purpose (裁定 01): the same tables on
   `/why-china-treatment-volume/` and `/why-china-technology-access/` carry the
   same defect and their typography improves with it - this is the batch's one
   global release, everything else is scoped to `.kl-adv--visa` below. */
.kl-adv__table .kl-adv__value,
.kl-adv__table .kl-adv__asof {
	font-family: var(--kl-font-mono);
	font-variant-numeric: tabular-nums;
}

/* Sources */

.kl-adv__sources {
	margin: 0 0 var(--kl-space-8);
}

.kl-adv__source-list {
	margin: 0;
	padding: 0;
	list-style: none;
}

.kl-adv__source {
	padding: var(--kl-space-4) 0;
	border-bottom: 1px solid var(--kl-border);
}

.kl-adv__source-head {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--kl-space-3);
	margin: 0 0 var(--kl-space-2);
}

.kl-adv__source-label {
	font-weight: var(--kl-weight-semibold);
}

.kl-adv__source-url {
	margin: 0;
	font-family: var(--kl-font-mono);
	font-size: var(--kl-text-sm);
	overflow-wrap: anywhere;
}

.kl-adv__source-url a {
	display: inline-block;
	min-height: 44px;
	padding: var(--kl-space-2) 0;
}

.kl-adv__source-meta {
	margin: var(--kl-space-1) 0 0;
	color: var(--kl-slate);
	font-size: var(--kl-text-sm);
}

/* What we cannot tell you */

.kl-adv__limits {
	padding: var(--kl-space-5);
	border: 1px solid var(--kl-border);
	border-left: 4px solid var(--kl-level-c);
	border-radius: var(--kl-radius-card);
	background: var(--kl-paper-alt);
}

.kl-adv__limit-list {
	margin: 0;
	padding-left: var(--kl-space-5);
}

.kl-adv__limit + .kl-adv__limit {
	margin-top: var(--kl-space-3);
}

/* Cross-links to the other two pages */

.kl-adv__chips {
	margin-top: var(--kl-space-7);
	padding-top: var(--kl-space-5);
	border-top: 1px solid var(--kl-border);
}

@media (max-width: 900px) {
	.kl-adv__title {
		font-size: var(--kl-text-2xl);
	}

	.kl-adv__limits {
		padding: var(--kl-space-4);
	}
}

/* ------------------------------------ Advantage long page (dev-056) ---
   `/why-china-visa-and-entry/` measured 14,390px at 1440 across four
   six-column data tables whose rows averaged ~280px. The copy was not the
   cause: `white-space: nowrap` on `.kl-adv__asof` / `.kl-adv__value` made the
   browser size `Year or as-of` to 401px and squeeze `Caliber` to 182px, wrapping
   every long sentence into a narrow cell. That one declaration is released
   GLOBALLY at its own rule above (裁定 01); here the six shares are fixed, so a
   row follows its text instead of its longest single cell.

   Everything below is scoped to `.kl-adv--visa` - the class the visa branch of
   `wellcarechina_render_advantages_page()` prints - so the two sibling
   advantage pages keep the dev-017 rendering byte for byte.

   The tables keep `.kl-table-wrap`'s sideways scroll on a narrow screen rather
   than taking the `.kl-table--stack` card layout: the same rows become ~340px
   cards under that layout (390px page measured 25,831 against 12,263 with the
   scroll), which would break the batch's own 390 line. Measured before/after
   for both choices: docs/testing/dev-056/. */

.kl-adv--visa .kl-adv__table {
	table-layout: fixed;
	/* At least the content column wide, so the six shares below resolve to the
	   same widths at every viewport and a narrow screen scrolls the wrapper
	   instead of squeezing the caliber column (known-issues #8). */
	min-width: calc(var(--kl-container) - 2 * var(--kl-space-5));
}

.kl-adv--visa .kl-adv__table th:nth-child(1) { width: 16%; }
.kl-adv--visa .kl-adv__table th:nth-child(2) { width: 8%; }
.kl-adv--visa .kl-adv__table th:nth-child(3) { width: 9%; }
.kl-adv--visa .kl-adv__table th:nth-child(4) { width: 47%; }
.kl-adv--visa .kl-adv__table th:nth-child(5) { width: 7%; }
.kl-adv--visa .kl-adv__table th:nth-child(6) { width: 13%; }

.kl-adv--visa .kl-adv__table th,
.kl-adv--visa .kl-adv__table td {
	padding: var(--kl-space-2) var(--kl-space-3);
	line-height: 1.4;
}

/* The base header rule is `nowrap`, which is right for a wide column and wrong
   for a 9%-wide one: "YEAR OR AS-OF" is wider than its column and runs into
   "CALIBER". Let the header wrap to its column like the cells do. */
.kl-adv--visa .kl-adv__table th {
	white-space: normal;
}

/* The chart's caption is its `<h3>` (dev-056 T1): it sits above the drawing as
   a sub-heading, and the "On this page" list deliberately still carries `h2`
   only. */
.kl-adv--visa .kl-adv__subhead {
	margin: var(--kl-space-5) 0 var(--kl-space-2);
	font-size: var(--kl-text-lg);
}

.kl-adv--visa .kl-adv__block {
	margin-bottom: var(--kl-space-7);
}

.kl-adv--visa .kl-adv__block-title {
	margin-bottom: var(--kl-space-3);
}

.kl-adv--visa .kl-adv__figure {
	margin: 0 0 var(--kl-space-3);
}

.kl-adv--visa .kl-adv__caption {
	margin-top: var(--kl-space-1);
}

/* The prose measure, on the text elements only - the tables keep the grid
   width (known-issues #8). */
.kl-adv--visa .kl-page-header__lede,
.kl-adv--visa .kl-adv__banner,
.kl-adv--visa .kl-adv__block-note,
.kl-adv--visa .kl-adv__limit {
	max-width: var(--kl-measure);
}

/* The block's own explanatory sentence, and each rule / exception sentence in
   "What we cannot tell you", wear the site's callout (dev-056 T2). The limits
   box itself steps aside - its five sentences are the boxes now. */
.kl-adv--visa .kl-callout--note {
	border-left-color: var(--kl-accent);
}

.kl-adv--visa .kl-adv__limits {
	padding: 0;
	border: 0;
	background: none;
}

.kl-adv--visa .kl-adv__limit-list {
	padding-left: 0;
	list-style: none;
}

.kl-adv--visa .kl-adv__limits .kl-adv__limit.kl-callout {
	margin: 0;
	padding: var(--kl-space-3) var(--kl-space-4);
	border-left-color: var(--kl-level-c);
}

.kl-adv--visa .kl-adv__limits .kl-adv__limit + .kl-adv__limit {
	margin-top: var(--kl-space-3);
}

/* Sources: the entries are a dense reference list - the reference rhythm, not
   the card rhythm. */
.kl-adv--visa .kl-adv__source {
	padding: var(--kl-space-3) 0;
}

.kl-adv--visa .kl-adv__source-head {
	margin-bottom: var(--kl-space-1);
}

.kl-adv--visa .kl-adv__source-url {
	margin-bottom: 0;
}

/* The 44px hit box stays (ui-009); only the wrapper's own 8px padding goes, so
   a twenty-entry reference list loses 16px an entry. */
.kl-adv--visa .kl-adv__source-url a {
	padding: 0;
}

.kl-adv--visa .kl-adv__source-meta {
	margin-top: var(--kl-space-1);
}

/* dev-056 T3 (裁定 02-A): the source list's tail folds behind the site's own
   `.kl-fold` disclosure - the same `Show all N <noun>` summary sentence the hub
   and the condition pages print, with the count inside the label, and the same
   44px touch floor - so the page's largest single block stops being a 2,539px
   wall without dropping a citation. */
.kl-adv--visa .kl-adv__sources-more {
	margin-top: var(--kl-space-4);
}

.kl-adv--visa .kl-adv__sources-more .kl-fold__summary {
	display: flex;
	align-items: center;
	gap: var(--kl-space-3);
	min-height: 44px;
	cursor: pointer;
}

.kl-adv--visa .kl-adv__sources-more .kl-fold__label {
	font-weight: var(--kl-weight-semibold);
}

.kl-adv--visa .kl-adv__sources-more .kl-fold__body {
	margin-top: var(--kl-space-2);
}

/* ------------------------------ Advantage long page, technology (dev-057) ---
   `/why-china-technology-access/` measured 16,663px at 1440 and 32,261px at 390
   across four six-column tables (68 rows in all; the first table alone carries
   51) and a 20-entry source list. Two of the three blocks were layout, not
   content:

   - the tables had no fixed columns, so at 390 the browser collapsed them to
     their minimum width and the `Caliber` cell wrapped into a 180px column
     (its `min-width` floor) - the tallest row measured 571px, and the page grew
     to twice its desktop height. With the six shares fixed here the table keeps
     the content column's width at every viewport and the wrapper scrolls
     sideways instead (known-issues #8), so a row is the same height at 390 as at
     1440;
   - the source list is a dense reference block, the same case dev-056 folded on
     the visa page.

   The six shares are tuned for this page's own columns (institution names, the
   device-type string, the long policy caliber and the very long trial query
   URLs). Everything here is scoped to `.kl-adv--tech`, the class the technology
   branch of `wellcarechina_render_advantages_page()` prints, so the two sibling
   advantage pages keep the dev-017 rendering byte for byte. Measured shares and
   heights, before and after, with both the fold and the table choices:
   docs/testing/dev-057/. */

.kl-adv--tech .kl-adv__table {
	table-layout: fixed;
	/* At least the content column wide, so the shares resolve to the same widths
	   at every viewport and a narrow screen scrolls the wrapper instead of
	   squeezing the caliber column (known-issues #8). */
	min-width: calc(var(--kl-container) - 2 * var(--kl-space-5));
}

.kl-adv--tech .kl-adv__table th:nth-child(1) { width: 26%; }
.kl-adv--tech .kl-adv__table th:nth-child(2) { width: 16%; }
.kl-adv--tech .kl-adv__table th:nth-child(3) { width: 9%; }
.kl-adv--tech .kl-adv__table th:nth-child(4) { width: 25%; }
.kl-adv--tech .kl-adv__table th:nth-child(5) { width: 9%; }
.kl-adv--tech .kl-adv__table th:nth-child(6) { width: 15%; }

.kl-adv--tech .kl-adv__table th,
.kl-adv--tech .kl-adv__table td {
	padding: var(--kl-space-1) var(--kl-space-3);
	line-height: 1.35;
}

/* Same reason as the visa page: the base header rule is `nowrap`, which is wrong
   for a 9%-wide column - "YEAR OR AS-OF" would run into "CALIBER". */
.kl-adv--tech .kl-adv__table th {
	white-space: normal;
}

/* The chart's caption is its `<h3>` (dev-057 T1), the same shape as the visa
   page; "On this page" deliberately still lists only the `h2` entries. */
.kl-adv--tech .kl-adv__subhead {
	margin: var(--kl-space-5) 0 var(--kl-space-2);
	font-size: var(--kl-text-lg);
}

.kl-adv--tech .kl-adv__block {
	margin-bottom: var(--kl-space-7);
}

.kl-adv--tech .kl-adv__block-title {
	margin-bottom: var(--kl-space-3);
}

.kl-adv--tech .kl-adv__figure {
	margin: 0 0 var(--kl-space-3);
}

/* The prose measure applies to the text elements only - the tables keep the
   grid width (known-issues #8). */
.kl-adv--tech .kl-page-header__lede,
.kl-adv--tech .kl-adv__banner,
.kl-adv--tech .kl-adv__block-note,
.kl-adv--tech .kl-adv__limit {
	max-width: var(--kl-measure);
}

/* What we cannot tell you (dev-057 T2): the five rule / exception sentences wear
   the site's callout, so the licence scope, the provincial-management gap, the
   CAR-T gap and the trial-count caliber read as rules; the missing-row records
   stay plain list items and keep the limits box's own left rule. */
.kl-adv--tech .kl-adv__limits {
	padding: 0;
	border: 0;
	background: none;
}

.kl-adv--tech .kl-adv__limit-list {
	padding-left: 0;
	list-style: none;
}

.kl-adv--tech .kl-adv__limits .kl-adv__limit.kl-callout {
	margin: 0;
	padding: var(--kl-space-3) var(--kl-space-4);
	border-left-color: var(--kl-level-c);
}

.kl-adv--tech .kl-adv__limits .kl-adv__limit.kl-callout + .kl-adv__limit.kl-callout {
	margin-top: var(--kl-space-3);
}

.kl-adv--tech .kl-adv__limits .kl-adv__limit--missing {
	margin-top: var(--kl-space-3);
	padding-left: var(--kl-space-4);
	border-left: 4px solid var(--kl-level-c);
}

/* The first block's exhaustive centre list folds behind the same disclosure the
   sources use (dev-057 T3): the policy rows and the licence batches stay in
   view, the forty-two centres stay in the DOM, and the summary prints the
   table's own row count. */
.kl-adv--tech .kl-adv__table-more {
	margin-top: var(--kl-space-4);
}

.kl-adv--tech .kl-adv__table-more .kl-fold__summary {
	display: flex;
	align-items: center;
	gap: var(--kl-space-3);
	min-height: 44px;
	cursor: pointer;
}

.kl-adv--tech .kl-adv__table-more .kl-fold__label {
	font-weight: var(--kl-weight-semibold);
}

.kl-adv--tech .kl-adv__table-more .kl-fold__body {
	margin-top: var(--kl-space-2);
}

/* Sources: the same reference rhythm and fold the visa page uses (dev-056). */
.kl-adv--tech .kl-adv__source {
	padding: var(--kl-space-3) 0;
}

.kl-adv--tech .kl-adv__source-head {
	margin-bottom: var(--kl-space-1);
}

.kl-adv--tech .kl-adv__source-url {
	margin-bottom: 0;
}

.kl-adv--tech .kl-adv__source-url a {
	padding: 0;
}

.kl-adv--tech .kl-adv__source-meta {
	margin-top: var(--kl-space-1);
}

.kl-adv--tech .kl-adv__sources-more {
	margin-top: var(--kl-space-4);
}

.kl-adv--tech .kl-adv__sources-more .kl-fold__summary {
	display: flex;
	align-items: center;
	gap: var(--kl-space-3);
	min-height: 44px;
	cursor: pointer;
}

.kl-adv--tech .kl-adv__sources-more .kl-fold__label {
	font-weight: var(--kl-weight-semibold);
}

.kl-adv--tech .kl-adv__sources-more .kl-fold__body {
	margin-top: var(--kl-space-2);
}

/* ------------------------------------------- Content images (dev-018) --- */
/* The delivered cover images, shared by four surfaces (homepage module cards,
   service cards, news covers, policy page headers). The wrapper reserves the
   display ratio and the image is cropped into it; the intrinsic width/height
   on the <img> keeps the reserved box correct even before this sheet loads. */

.kl-module__media,
.kl-service__media,
.kl-news-card__media,
.kl-news-entry__media,
.kl-page__media {
	margin: 0 0 var(--kl-space-4);
	overflow: hidden;
	border-radius: var(--kl-radius-card);
	background: var(--kl-paper-alt);
}

.kl-module__media img,
.kl-service__media img,
.kl-news-card__media img,
.kl-news-entry__media img,
.kl-page__media img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.kl-module__media,
.kl-service__media {
	aspect-ratio: 16 / 10;
}

.kl-news-card__media,
.kl-news-entry__media {
	aspect-ratio: 16 / 9;
}

.kl-page__media {
	aspect-ratio: 21 / 9;
}

/* --------------------------------- Mobile interaction (dev-024) ---
   Ledger ui-024 (a 390px header search squeezed until its placeholder read
   "Disease n") and ui-025 (legal pages with no verifiable reading
   confirmation and no status feedback anywhere).
   Scope: prompts/dev/dev-024-mobile-interaction-master.md §四 - two new
   durations live in assets/css/tokens.css, and exactly four motions are added
   here: the card/list hover lift, the chip focus lift, the reading-gate
   progress bar and the header search reveal. Everything below is neutralised
   by the existing `prefers-reduced-motion: reduce` block (style.css, above). */

/* 1 - card / list row hover lift: the design system's "lift 2px", implemented.
   The hover media query keeps a stuck hover off touch devices. */

.kl-card {
	transition: transform var(--kl-dur-fast) var(--kl-ease);
}

@media (hover: hover) {
	.kl-card:hover {
		transform: translateY(-2px);
	}
}

/* 2 - a chip lifts 2px when it takes keyboard focus. */

.kl-chip {
	transition: transform var(--kl-dur-fast) var(--kl-ease);
}

.kl-chip:focus-visible {
	transform: translateY(-2px);
}

/* 3 - the reading confirmation gate (ledger ui-025). Front-end only: no
   request, no cookie, no storage. It sits at the end of the prose in normal
   flow - never a fixed overlay over the text. */

.kl-reading-gate {
	margin-top: var(--kl-space-6);
	padding: var(--kl-space-5);
	border: 1px solid var(--kl-border);
	border-radius: var(--kl-radius-card);
	background: var(--kl-paper-alt);
}

.kl-reading-gate__note {
	margin: 0;
	color: var(--kl-ink);
}

.kl-reading-gate__caption {
	margin: var(--kl-space-3) 0 0;
	color: var(--kl-slate);
	font-size: var(--kl-text-sm);
}

/* The progress row only exists once the script is running: a browser without
   JavaScript never shows a "0%" it cannot update (the button below it stays
   enabled there, which is the progressive-enhancement contract). */

.kl-reading-gate__progress {
	display: none;
	margin-top: var(--kl-space-3);
}

.kl-reading-gate--active .kl-reading-gate__progress {
	display: block;
}

.kl-reading-gate__track {
	display: block;
	height: 6px;
	border-radius: var(--kl-radius-pill);
	background: var(--kl-disabled-bg);
	overflow: hidden;
}

.kl-reading-gate__fill {
	display: block;
	width: 0;
	height: 100%;
	background: var(--kl-accent);
	transition: width var(--kl-dur-base) linear;
}

.kl-reading-gate__value {
	margin: var(--kl-space-2) 0 0;
	color: var(--kl-slate);
	font-size: var(--kl-text-sm);
	font-variant-numeric: tabular-nums;
}

.kl-reading-gate__confirm {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-height: 44px;
	margin-top: var(--kl-space-4);
	padding: 0 var(--kl-space-5);
	border: 1px solid var(--kl-accent);
	border-radius: var(--kl-radius-pill);
	background: var(--kl-accent);
	color: var(--kl-paper);
	font-family: inherit;
	font-size: var(--kl-text-md);
	font-weight: var(--kl-weight-semibold);
	cursor: pointer;
	transition: background-color var(--kl-dur-slow) var(--kl-ease), border-color var(--kl-dur-slow) var(--kl-ease), color var(--kl-dur-slow) var(--kl-ease);
}

.kl-reading-gate__confirm:disabled {
	border-color: var(--kl-border-strong);
	background: var(--kl-disabled-bg);
	color: var(--kl-disabled-ink);
	cursor: not-allowed;
}

.kl-reading-gate__confirm.is-confirmed {
	border-color: var(--kl-accent);
	background: var(--kl-paper);
	color: var(--kl-accent-hover);
}

/* --------------------------------------- Condition evidence (dev-022) ---
   The shortlist, its evidence card and the clinical-study list on a condition
   page, plus the same card on a hospital page (spec
   docs/design/疾病页医院短名单与临床试验_v1_20260928.md §3 / §4.2).

   Two rules the whole component follows:
   1. everything a visitor can tap keeps the 44px touch height (fix-007 T7):
      block links take a min-height, inline links in a sentence grow their hit
      box with vertical padding, which does not change the line box;
   2. a quoted source URL wraps anywhere (`overflow-wrap: anywhere`), so a long
      registry or ministry URL can never push the page sideways at 390px.
   No transition is added here, so the prefers-reduced-motion contract that
   covers the rest of the site is untouched. */

.kl-evidence__disclosure {
	display: inline-flex;
	align-items: center;
	margin: var(--kl-space-3) 0 0;
	padding: var(--kl-space-1) var(--kl-space-3);
	border: 1px solid var(--kl-border-strong);
	border-radius: var(--kl-radius-pill);
	background: var(--kl-paper-alt);
	color: var(--kl-ink);
	font-size: var(--kl-text-sm);
	font-weight: var(--kl-weight-semibold);
}

.kl-evidence__method {
	margin-top: var(--kl-space-4);
}

.kl-evidence__method-summary,
.kl-evidence__extended-summary,
.kl-trials__more .kl-fold__summary {
	display: flex;
	align-items: center;
	gap: var(--kl-space-3);
	min-height: 44px;
	cursor: pointer;
}

.kl-evidence__method-summary .kl-fold__label,
.kl-trials__more .kl-fold__label {
	font-weight: var(--kl-weight-semibold);
}

.kl-evidence__extended-summary .kl-fold__count {
	margin-left: auto;
	color: var(--kl-slate);
}

.kl-evidence__rule {
	max-width: 68ch;
	margin: 0 0 var(--kl-space-3);
	color: var(--kl-slate);
	font-size: var(--kl-text-sm);
}

.kl-evidence__state {
	margin: var(--kl-space-4) 0 0;
	font-weight: var(--kl-weight-semibold);
}

.kl-evidence__list {
	display: grid;
	gap: var(--kl-space-4);
	margin: var(--kl-space-4) 0 0;
	padding: 0;
	list-style: none;
}

.kl-evidence-card {
	padding: var(--kl-space-4) var(--kl-space-5);
	border: 1px solid var(--kl-border);
	border-radius: var(--kl-radius-card);
	background: var(--kl-paper);
}

.kl-evidence-card__disease {
	margin: 0 0 var(--kl-space-2);
	color: var(--kl-accent-hover);
	font-size: var(--kl-text-xs);
	font-weight: var(--kl-weight-semibold);
	letter-spacing: var(--kl-tracking-caps);
	text-transform: uppercase;
}

.kl-evidence-card__name {
	margin: 0;
	font-size: var(--kl-text-lg);
}

.kl-evidence-card__name a {
	display: flex;
	flex-direction: column;
	justify-content: center;
	min-height: 44px;
}

.kl-evidence-card__meta {
	margin: var(--kl-space-2) 0 0;
	color: var(--kl-slate);
	font-size: var(--kl-text-sm);
}

.kl-evidence-card__badge {
	display: inline-flex;
	align-items: center;
	padding: 0 var(--kl-space-2);
	border: 1px solid var(--kl-border-strong);
	border-radius: var(--kl-radius-pill);
	background: var(--kl-accent-soft);
	color: var(--kl-accent-hover);
	font-size: var(--kl-text-xs);
}

.kl-evidence-card__group {
	margin-top: var(--kl-space-4);
}

.kl-evidence-card__label {
	margin: 0 0 var(--kl-space-2);
	color: var(--kl-slate);
	font-size: var(--kl-text-xs);
	font-weight: var(--kl-weight-semibold);
	letter-spacing: var(--kl-tracking-caps);
	text-transform: uppercase;
}

.kl-evidence-card__items {
	display: grid;
	gap: var(--kl-space-2);
	margin: 0;
	padding: 0;
	list-style: none;
}

.kl-evidence-card__rank,
.kl-evidence-card__claim,
.kl-evidence-card__platform,
.kl-evidence-card__paper {
	display: grid;
	gap: var(--kl-space-1);
	font-size: var(--kl-text-base);
}

.kl-evidence-card__item a {
	padding: var(--kl-space-3) 0;
	color: var(--kl-accent-hover);
}

.kl-evidence-card__journal {
	color: var(--kl-slate);
}

.kl-evidence-card__more,
.kl-evidence-card__note,
.kl-evidence-card__secondary {
	margin: var(--kl-space-2) 0 0;
	color: var(--kl-slate);
	font-size: var(--kl-text-sm);
}

.kl-evidence__source {
	display: block;
	min-width: 0;
	font-family: var(--kl-font-mono);
	font-size: var(--kl-text-xs);
	overflow-wrap: anywhere;
}

.kl-evidence__source a {
	display: inline-block;
	min-height: 44px;
	padding: var(--kl-space-2) 0;
	color: var(--kl-accent-hover);
}

/* The clinical-study list (§4.2). */

.kl-trials__list {
	display: grid;
	gap: var(--kl-space-4);
	margin: var(--kl-space-4) 0 0;
	padding: 0;
	list-style: none;
}

.kl-trials__item {
	padding: var(--kl-space-4) var(--kl-space-5);
	border: 1px solid var(--kl-border);
	border-radius: var(--kl-radius-card);
	background: var(--kl-paper);
}

.kl-trials__study {
	display: grid;
	gap: var(--kl-space-1);
	margin: 0;
}

.kl-trials__field {
	color: var(--kl-slate);
	font-size: var(--kl-text-xs);
	font-weight: var(--kl-weight-semibold);
	letter-spacing: var(--kl-tracking-caps);
	text-transform: uppercase;
}

.kl-trials__fields {
	display: grid;
	grid-template-columns: max-content minmax(0, 1fr);
	gap: var(--kl-space-2) var(--kl-space-4);
	margin: var(--kl-space-3) 0 0;
	font-size: var(--kl-text-base);
}

.kl-trials__fields dt {
	color: var(--kl-slate);
}

.kl-trials__fields dd {
	margin: 0;
	overflow-wrap: anywhere;
}

.kl-trials__fields dd a {
	display: inline-block;
	min-height: 44px;
	padding: var(--kl-space-2) 0;
	font-family: var(--kl-font-mono);
	font-size: var(--kl-text-sm);
	color: var(--kl-accent-hover);
}

@media (max-width: 480px) {
	.kl-trials__fields {
		grid-template-columns: minmax(0, 1fr);
		gap: 0;
	}

	.kl-trials__fields dt {
		margin-top: var(--kl-space-3);
	}
}

/* ----------------------------- Mobile selector + standing bar (dev-025) ---
   Three pieces, one scope (prompts/dev/dev-025-mobile-selector-master.md §四):

   1. the bottom selector - the mobile shell of the EXISTING city / specialty
      facets on /hospitals/all/ and the specialty archive. It produces the URL
      the chips already produce (see wellcarechina_render_hospital_facet_sheets()
      in inc/hospital-directory.php), and it exists only from 900px down, so the
      desktop directory form is byte-for-byte the one it was;
   2. the standing contact bar on /services/, 900px down, pure CSS;
   3. the card layout the `.kl-table--stack` marker has been waiting for
      (ledger ui-020: a condition-page table that scrolled sideways on a phone).

   Two motions only, both on the dev-024 durations and the one easing curve, and
   the existing `prefers-reduced-motion: reduce` block above collapses them. */

/* 1 - the bottom selector. The triggers are hidden until the script has run
   (`html.kl-sheet-ready`, added by assets/js/filter-sheet.js), and hidden again
   from 901px up: without the script there is no pressable control with nothing
   behind it, and on a desktop there is no extra control at all. */

.kl-sheet-triggers,
.kl-sheet-open {
	display: none;
}

@media (max-width: 900px) {
	.kl-sheet-ready .kl-sheet-triggers {
		display: flex;
		flex-wrap: wrap;
		gap: var(--kl-space-2);
		margin: 0 0 var(--kl-space-4);
	}

	.kl-sheet-ready .kl-sheet-open:not([hidden]) {
		display: inline-flex;
		align-items: center;
		justify-content: center;
		min-height: 44px;
		padding: 0 var(--kl-space-5);
		border: 1px solid var(--kl-border-strong);
		border-radius: var(--kl-radius-pill);
		background: var(--kl-paper);
		color: var(--kl-ink);
		font-family: inherit;
		font-size: var(--kl-text-md);
		font-weight: var(--kl-weight-semibold);
		cursor: pointer;
	}

	.kl-sheet-ready .kl-sheet-open:not([hidden]):hover,
	.kl-sheet-ready .kl-sheet-open:not([hidden]):focus {
		border-color: var(--kl-accent);
		background: var(--kl-accent-soft);
		color: var(--kl-accent-hover);
	}

	/* The sheet itself is the native modal <dialog>: the backdrop, the Escape
	   key, the focus trap and the focus return are the browser's, not a rebuilt
	   overlay. It only grows its own look while it is open. */

	.kl-sheet[open] {
		display: block;
		position: fixed;
		inset: auto 0 0 0;
		width: 100%;
		max-width: none;
		max-height: 80vh;
		margin: 0;
		padding: 0;
		border: 0;
		border-radius: var(--kl-radius-card) var(--kl-radius-card) 0 0;
		background: var(--kl-paper);
		box-shadow: var(--kl-shadow-2);
		animation: kl-sheet-in var(--kl-dur-base) var(--kl-ease) both;
	}

	.kl-sheet::backdrop {
		background: var(--kl-scrim);
		animation: kl-sheet-backdrop var(--kl-dur-fast) linear both;
	}

	.kl-sheet__head {
		display: flex;
		align-items: center;
		gap: var(--kl-space-2);
		padding: var(--kl-space-3) var(--kl-space-4);
		border-bottom: 1px solid var(--kl-border);
	}

	.kl-sheet__title {
		flex: 1 1 auto;
		min-width: 0;
		margin: 0;
		font-size: var(--kl-text-md);
		text-align: center;
	}

	.kl-sheet__cancel,
	.kl-sheet__confirm {
		flex: 0 0 auto;
		min-height: 44px;
		padding: 0 var(--kl-space-4);
		border: 1px solid var(--kl-border-strong);
		border-radius: var(--kl-radius-pill);
		background: var(--kl-paper);
		color: var(--kl-ink);
		font-family: inherit;
		font-size: var(--kl-text-md);
		cursor: pointer;
	}

	.kl-sheet__confirm {
		border-color: var(--kl-accent);
		background: var(--kl-accent);
		color: var(--kl-paper);
		font-weight: var(--kl-weight-semibold);
	}

	/* Nothing is chosen yet: the Confirm control says so instead of looking
	   ready and doing nothing. */
	.kl-sheet__confirm:disabled {
		border-color: var(--kl-border-strong);
		background: var(--kl-disabled-bg);
		color: var(--kl-disabled-ink);
		cursor: not-allowed;
	}

	.kl-sheet__body {
		max-height: calc(80vh - 72px);
		overflow-y: auto;
		padding: var(--kl-space-3) var(--kl-space-4) var(--kl-space-5);
	}

	.kl-sheet__search {
		width: 100%;
		min-height: 44px;
		margin: 0 0 var(--kl-space-2);
		padding: 0 var(--kl-space-3);
		border: 1px solid var(--kl-border-strong);
		border-radius: var(--kl-radius-input);
		background: var(--kl-paper);
		color: var(--kl-ink);
		font-family: inherit;
		font-size: var(--kl-text-md);
	}

	.kl-sheet__list {
		margin: 0;
		padding: 0;
		list-style: none;
	}

	.kl-sheet__item {
		display: flex;
		align-items: center;
		justify-content: space-between;
		gap: var(--kl-space-3);
		min-height: 44px;
		padding: var(--kl-space-2) var(--kl-space-1);
		border-bottom: 1px solid var(--kl-border);
		color: inherit;
		text-decoration: none;
	}

	.kl-sheet__item:hover,
	.kl-sheet__item:focus {
		color: var(--kl-accent-hover);
	}

	.kl-sheet__item.is-selected {
		background: var(--kl-accent-soft);
		color: var(--kl-accent-hover);
		font-weight: var(--kl-weight-semibold);
	}

	.kl-sheet__count {
		color: var(--kl-slate);
		font-variant-numeric: tabular-nums;
	}

	/* No `display` here on purpose: the script hides this line with the
	   `hidden` attribute, and an author `display` would override it. */
	.kl-sheet__empty {
		margin: var(--kl-space-3) 0 0;
		color: var(--kl-slate);
	}

	@keyframes kl-sheet-in {
		from {
			transform: translateY(8px);
			opacity: 0;
		}

		to {
			transform: translateY(0);
			opacity: 1;
		}
	}

	@keyframes kl-sheet-backdrop {
		from {
			opacity: 0;
		}

		to {
			opacity: 1;
		}
	}
}

/* 2 - the standing action bar on /services/. It is fixed to the bottom of the
   window, and the footer reserves its height, so the last lines of the page
   (and every footer link) stay reachable. The bar carries one action: the
   address the page and the footer already use. */

.kl-action-bar {
	display: none;
}

@media (max-width: 900px) {
	.kl-action-bar {
		position: fixed;
		right: 0;
		bottom: 0;
		left: 0;
		z-index: 20;
		display: flex;
		align-items: center;
		gap: var(--kl-space-3);
		min-height: var(--kl-space-8);
		padding: var(--kl-space-2) var(--kl-space-4);
		padding-bottom: calc(var(--kl-space-2) + env(safe-area-inset-bottom, 0px));
		border-top: 1px solid var(--kl-border-strong);
		background: var(--kl-paper);
		box-shadow: var(--kl-shadow-2);
		animation: kl-action-bar-in var(--kl-dur-base) var(--kl-ease) both;
	}

	.kl-action-bar__summary {
		flex: 1 1 auto;
		min-width: 0;
		margin: 0;
		overflow: hidden;
		color: var(--kl-slate);
		font-size: var(--kl-text-sm);
		text-overflow: ellipsis;
		white-space: nowrap;
	}

	.kl-action-bar__cta {
		flex: 0 0 auto;
		display: inline-flex;
		align-items: center;
		min-height: 44px;
		padding: 0 var(--kl-space-5);
		border: 1px solid var(--kl-accent);
		border-radius: var(--kl-radius-pill);
		background: var(--kl-accent);
		color: var(--kl-paper);
		font-weight: var(--kl-weight-semibold);
		text-decoration: none;
	}

	.kl-action-bar__cta:hover,
	.kl-action-bar__cta:focus {
		border-color: var(--kl-accent-hover);
		background: var(--kl-accent-hover);
		color: var(--kl-paper);
	}

	/* The reserved space: bar height (--kl-space-8) plus the page's own foot
	   padding. Scoped with :has() to the page that renders the bar, so no other
	   template pays for it. */
	body:has(.kl-action-bar) .kl-footer {
		padding-bottom: calc(var(--kl-space-8) + var(--kl-space-4) + env(safe-area-inset-bottom, 0px));
	}

	@keyframes kl-action-bar-in {
		from {
			transform: translateY(8px);
			opacity: 0;
		}

		to {
			transform: translateY(0);
			opacity: 1;
		}
	}
}

/* 3 - ui-020: the card layout for `.kl-table--stack` on a narrow screen. The
   marker (the class plus one `data-label` per cell) has been in the three
   condition-page tables since fix-008 but had no stylesheet rule, so the table
   kept its 560px floor and scrolled sideways inside its wrapper (measured at
   390x844: 587 / 629 / 560 against a 340px wrapper). Each row becomes a block
   and each cell prints its own column name, so the wrapper no longer scrolls.

   The header row is visually hidden rather than removed: the table keeps its
   headers for assistive technology, and nothing about the desktop form
   changes - every rule here lives inside the 640px query. */

@media (max-width: 640px) {
	.kl-table--stack {
		display: block;
		min-width: 0;
	}

	.kl-table--stack thead {
		position: absolute;
		width: 1px;
		height: 1px;
		margin: -1px;
		padding: 0;
		overflow: hidden;
		clip-path: inset(50%);
		white-space: nowrap;
		border: 0;
	}

	.kl-table--stack tbody,
	.kl-table--stack tr,
	.kl-table--stack td {
		display: block;
		width: auto;
	}

	.kl-table--stack tr {
		padding: var(--kl-space-3) 0;
		border-bottom: 1px solid var(--kl-border);
	}

	.kl-table--stack tr:last-child {
		padding-bottom: 0;
		border-bottom: 0;
	}

	.kl-table--stack td {
		padding: var(--kl-space-1) var(--kl-space-4);
		border-bottom: 0;
	}

	.kl-table--stack td::before {
		content: attr(data-label);
		display: block;
		margin-bottom: var(--kl-space-1);
		color: var(--kl-slate);
		font-size: var(--kl-text-xs);
		font-weight: var(--kl-weight-semibold);
		letter-spacing: var(--kl-tracking-caps);
		text-transform: uppercase;
	}

	/* dev-059 T1: the listings' own card labels. The hub tables no longer carry
	   a `data-label` on every cell (the key-specialty board alone had 6,522 of
	   them); the column name comes from the custom properties the region prints
	   once (`--kl-stack-*`, inc/rankings-hub.php) and the cell's own column, so
	   the text is written once and cannot drift from the table's `<th>`. The
	   visible label text is unchanged - P31 / dev-059-report.md carry the
	   before-and-after read of `getComputedStyle(td, '::before').content`. */
	#fudan-general .kl-hub__table td:nth-child(1)::before { content: var(--kl-stack-general-0, ""); }
	#fudan-general .kl-hub__table td:nth-child(2)::before { content: var(--kl-stack-general-1, ""); }

	#fudan-specialty .kl-hub__table td:nth-child(1)::before { content: var(--kl-stack-specialty-0, ""); }
	#fudan-specialty .kl-hub__table td:nth-child(2)::before { content: var(--kl-stack-specialty-1, ""); }
	#fudan-specialty .kl-hub__table td:nth-child(3)::before { content: var(--kl-stack-specialty-2, ""); }
	#fudan-specialty .kl-hub__table td:nth-child(4)::before { content: var(--kl-stack-specialty-3, ""); }

	#national-key-specialties .kl-hub__table td:nth-child(1)::before { content: var(--kl-stack-key-0, ""); }
	#national-key-specialties .kl-hub__table td:nth-child(2)::before { content: var(--kl-stack-key-1, ""); }
	#national-key-specialties .kl-hub__table td:nth-child(3)::before { content: var(--kl-stack-key-2, ""); }

	/* The "grouped by specialty" view lists the hospital first, so its first
	   column is named Hospital, not Specialty (the other two columns match).
	   It is keyed off `.kl-hub__alt` rather than a board id because dev-059 T2
	   moved that view into its own section on /key-specialties/. */
	.kl-hub__alt .kl-hub__table td:nth-child(1)::before { content: var(--kl-stack-key_specialty-0, ""); }
	.kl-hub__alt .kl-hub__table td:nth-child(2)::before { content: var(--kl-stack-key_specialty-1, ""); }
	.kl-hub__alt .kl-hub__table td:nth-child(3)::before { content: var(--kl-stack-key_specialty-2, ""); }

	#research-platforms .kl-hub__table td:nth-child(1)::before { content: var(--kl-stack-platform-0, ""); }
	#research-platforms .kl-hub__table td:nth-child(2)::before { content: var(--kl-stack-platform-1, ""); }
	#research-platforms .kl-hub__table td:nth-child(3)::before { content: var(--kl-stack-platform-2, ""); }
	#research-platforms .kl-hub__table td:nth-child(4)::before { content: var(--kl-stack-platform-3, ""); }

	/* In a card the value wraps: the desktop `nowrap` on a numeric cell exists
	   to keep a column aligned, which no longer applies. */
	.kl-table--stack td.kl-num {
		white-space: normal;
	}

	/* A link in a card is a finger target, the same as everywhere else on the
	   site (fix-007 T7). The card gives a hospital name the full cell width, so
	   the name sits on one line and the anchor's own box is only a line tall;
	   the hit box is therefore grown here. Scoped to the card layout, so the
	   desktop table keeps its inline link size. */
	.kl-table--stack td a {
		display: inline-flex;
		align-items: center;
		min-height: 44px;
	}
}

/* ------------------------------- Condition page data display (dev-027) ---
   Three pieces, one scope (prompts/dev/dev-027-condition-data-master.md §四):

   1. `.kl-facts` - the key-figure band under the identity. Four published
      figures, each tile a link into the section that carries its source. The
      figures are read from the same records those sections read, so a tile
      cannot state a number the section below contradicts;
   2. `.kl-range` - the interval bar inside the cost table's range cell. Every
      priced row of the condition is drawn on one scale, and the bar is a
      second reading of the figures printed above it (it is `aria-hidden`);
   3. `.kl-figure` - the five-year survival card. The page's one big number,
      with the confidence interval under it and the qualifiers below.

   The chart language is the one inc/advantages.php already uses: bars in the
   single accent, labels in slate, figures in IBM Plex Mono with tabular
   numerals, a caption under the graphic. Composition rules follow the site's
   own checklist (docs/design/设计方向_v0.md §10.5): tokens only, one accent,
   three radii, border instead of shadow, hover limited to colour plus the 2px
   lift, and no new motion - the site-wide `prefers-reduced-motion` block above
   already collapses these transitions. */

.kl-facts {
	margin: var(--kl-space-6) 0;
	padding: var(--kl-space-5);
	border: 1px solid var(--kl-border);
	border-radius: var(--kl-radius-card);
	background: var(--kl-paper-alt);
}

.kl-facts__head {
	max-width: 68ch;
	margin-bottom: var(--kl-space-5);
}

.kl-facts__title {
	margin: 0;
	font-size: var(--kl-text-lg);
}

.kl-facts__lede {
	margin: var(--kl-space-2) 0 0;
	color: var(--kl-slate);
	font-size: var(--kl-text-sm);
}

.kl-facts__list {
	display: grid;
	grid-template-columns: repeat(4, minmax(0, 1fr));
	gap: var(--kl-space-3);
	margin: 0;
	padding: 0;
	list-style: none;
}

/* One tile is one link, so the finger target is the whole tile (44px floor). */
.kl-fact__link {
	display: flex;
	flex-direction: column;
	gap: var(--kl-space-2);
	box-sizing: border-box;
	width: 100%;
	height: 100%;
	min-height: 44px;
	padding: var(--kl-space-4);
	border: 1px solid var(--kl-border);
	border-radius: var(--kl-radius-input);
	background: var(--kl-paper);
	color: var(--kl-ink);
	text-decoration: none;
	transition: border-color var(--kl-dur-fast) var(--kl-ease), transform var(--kl-dur-fast) var(--kl-ease);
}

.kl-fact__link:hover,
.kl-fact__link:focus {
	border-color: var(--kl-accent-ring);
	transform: translateY(-2px);
}

.kl-fact__label {
	color: var(--kl-slate);
	font-size: var(--kl-text-xs);
	font-weight: var(--kl-weight-semibold);
	letter-spacing: var(--kl-tracking-caps);
	text-transform: uppercase;
}

/* The figure is the tile's focal point and the accent is the site's link
   colour - the two jobs meet here, and the value is the link. */
.kl-fact__value {
	color: var(--kl-accent-hover);
	font-family: var(--kl-font-mono);
	font-size: var(--kl-text-3xl);
	font-variant-numeric: tabular-nums;
	font-weight: var(--kl-weight-semibold);
	line-height: var(--kl-leading-tight);
}

.kl-fact__note {
	margin-top: auto;
	color: var(--kl-slate);
	font-size: var(--kl-text-sm);
	line-height: var(--kl-leading-snug);
}

/* The cost cell: the published figures first, the bar as their second reading. */
.kl-cost__figure {
	display: block;
	font-size: var(--kl-text-md);
	font-weight: var(--kl-weight-semibold);
}

.kl-range {
	display: block;
	position: relative;
	width: 100%;
	height: 6px;
	margin-top: var(--kl-space-2);
	border-radius: var(--kl-radius-pill);
	background: var(--kl-border);
	overflow: hidden;
}

/* Geometry (left / width) is written inline by the renderer, because it is
   data, not styling: it comes from the two published figures of the row. The
   floor keeps an interval whose ends are equal visible; the figures above the
   bar remain the measurement. */
.kl-range__bar {
	position: absolute;
	top: 0;
	bottom: 0;
	min-width: 6px;
	border-radius: var(--kl-radius-pill);
	background: var(--kl-accent);
}

.kl-cost__scale {
	max-width: 68ch;
}

/* The one billing basis every range shares (dev-027 T6): it used to be a
   column that repeated the same words on every row. */
.kl-cost__caliber {
	max-width: 68ch;
}

/* The survival card. */
.kl-figure__card {
	padding: var(--kl-space-5);
	border: 1px solid var(--kl-border);
	border-radius: var(--kl-radius-card);
	background: var(--kl-paper);
}

.kl-figure__head {
	display: flex;
	flex-direction: column;
	gap: var(--kl-space-1);
	margin: 0;
	padding-bottom: var(--kl-space-4);
	border-bottom: 1px solid var(--kl-border);
}

.kl-figure__label {
	color: var(--kl-slate);
	font-size: var(--kl-text-xs);
	font-weight: var(--kl-weight-semibold);
	letter-spacing: var(--kl-tracking-caps);
	text-transform: uppercase;
}

.kl-figure__value {
	color: var(--kl-accent-hover);
	font-family: var(--kl-font-mono);
	font-size: var(--kl-text-4xl);
	font-variant-numeric: tabular-nums;
	font-weight: var(--kl-weight-semibold);
	line-height: var(--kl-leading-tight);
}

/* A record whose source published no percentage keeps the shared empty-state
   word, at a size that reads as a statement and not as a measurement. */
.kl-figure__value--gap {
	color: var(--kl-slate);
	font-family: var(--kl-font-sans);
	font-size: var(--kl-text-xl);
}

.kl-figure__ci {
	color: var(--kl-slate);
	font-family: var(--kl-font-mono);
	font-size: var(--kl-text-sm);
}

.kl-figure__list {
	display: grid;
	grid-template-columns: max-content minmax(0, 1fr);
	gap: var(--kl-space-2) var(--kl-space-4);
	margin: var(--kl-space-4) 0 0;
	font-size: var(--kl-text-base);
}

.kl-figure__list dt {
	color: var(--kl-slate);
}

.kl-figure__list dd {
	margin: 0;
	overflow-wrap: anywhere;
}

@media (max-width: 900px) {
	.kl-facts__list {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}
}

/* Narrow screens get the tiles as rows rather than a shrunken grid: the label
   and the figure on one line, the qualifier underneath, so four figures fit
   above the fold without a 4-column squeeze. */
@media (max-width: 640px) {
	.kl-facts {
		padding: var(--kl-space-4);
	}

	.kl-facts__list {
		grid-template-columns: minmax(0, 1fr);
		gap: var(--kl-space-2);
	}

	.kl-fact__link {
		display: grid;
		grid-template-columns: minmax(0, 1fr) auto;
		gap: var(--kl-space-1) var(--kl-space-4);
		align-items: baseline;
		padding: var(--kl-space-3) var(--kl-space-4);
	}

	.kl-fact__value {
		font-size: var(--kl-text-2xl);
		justify-self: end;
	}

	.kl-fact__note {
		margin-top: 0;
		grid-column: 1 / -1;
	}

	.kl-figure__value {
		font-size: var(--kl-text-3xl);
	}

	.kl-figure__list {
		grid-template-columns: minmax(0, 1fr);
		gap: 0;
	}

	.kl-figure__list dt {
		margin-top: var(--kl-space-3);
	}
}

/* --------------------------------------------------------- Lead form ---
   The /contact/ form (dev-019 T2). Native controls only, because the page has
   to work with JavaScript off: every affordance here is an element the browser
   already knows how to submit. Styling follows the checklist the rest of the
   sheet follows (docs/design/设计方向_v0.md §10.5): tokens only, no new colour,
   border instead of shadow, one accent.

   The result of a submission is a sentence, never a colour on its own: the
   three states share one box and differ by background and border weight, and
   the idle state renders nothing at all. */

.kl-lead {
	margin: 0 0 var(--kl-space-6);
}

/* The honeypot (inc/lead-form.php). Off screen for a visitor, present for a
   script that fills every field it can find. `display: none` is deliberately
   avoided - that is the one thing the scripts this catches do skip. */
.kl-lead__trap {
	position: absolute;
	left: -9999px;
	width: 1px;
	height: 1px;
	margin: 0;
	overflow: hidden;
}

.kl-lead__field {
	max-width: var(--kl-measure);
	margin: 0 0 var(--kl-space-4);
}

.kl-lead__label {
	display: block;
	margin-bottom: var(--kl-space-2);
	color: var(--kl-slate);
	font-size: var(--kl-text-sm);
}

.kl-lead__required {
	margin-left: var(--kl-space-2);
	color: var(--kl-ink);
	font-size: var(--kl-text-xs);
	letter-spacing: var(--kl-tracking-caps);
	text-transform: uppercase;
}

.kl-lead__input {
	box-sizing: border-box;
	width: 100%;
	min-height: 44px;
	padding: var(--kl-space-3);
	border: 1px solid var(--kl-border-strong);
	border-radius: var(--kl-radius-input);
	background: var(--kl-paper);
	color: var(--kl-ink);
	font-family: inherit;
	font-size: var(--kl-text-md);
}

.kl-lead__input:focus {
	border-color: var(--kl-accent);
	box-shadow: 0 0 0 3px var(--kl-accent-ring);
	outline: none;
}

.kl-lead__textarea {
	min-height: calc(var(--kl-space-8) * 2);
	resize: vertical;
}

/* The consent sentence is long, so the box sits beside it rather than above it:
   the reader sees the whole statement and the control it belongs to at once. */
.kl-lead__consent {
	display: flex;
	gap: var(--kl-space-3);
	align-items: flex-start;
	max-width: var(--kl-measure);
	font-size: var(--kl-text-md);
	line-height: var(--kl-leading-body);
}

.kl-lead__consent input {
	flex: 0 0 auto;
	width: 24px;
	height: 24px;
	margin: var(--kl-space-1) 0 0;
	accent-color: var(--kl-accent);
}

.kl-lead__actions {
	max-width: var(--kl-measure);
	margin: var(--kl-space-5) 0 0;
}

.kl-lead__status {
	max-width: var(--kl-measure);
	margin: 0 0 var(--kl-space-5);
	padding: 0;
	border-left: 4px solid transparent;
}

/* No submission yet: the box exists for assistive technology but prints
   nothing, so the form starts with no status line at all. */
.kl-lead__status--idle {
	display: none;
}

.kl-lead__status--ok,
.kl-lead__status--note,
.kl-lead__status--error {
	padding: var(--kl-space-3) var(--kl-space-4);
	border-radius: var(--kl-radius-input);
	background: var(--kl-paper-alt);
	border-left-color: var(--kl-ink);
}

.kl-lead__status--ok {
	background: var(--kl-accent-soft);
	border-left-color: var(--kl-accent);
}

.kl-lead__status--note {
	background: var(--kl-note-bg);
}

.kl-lead__status--error {
	font-weight: var(--kl-weight-semibold);
}

/* The voluntary-records notice, shown after a submission was accepted. */
.kl-lead__records {
	max-width: var(--kl-measure);
	margin: var(--kl-space-4) 0 0;
	padding: var(--kl-space-4);
	border: 1px solid var(--kl-border);
	border-radius: var(--kl-radius-card);
	background: var(--kl-paper-alt);
	font-size: var(--kl-text-md);
}

/* The form entry on the disease, hospital and services pages. A link, sized as
   a finger target on narrow screens like every other in-page link. */
.kl-lead-entry {
	max-width: var(--kl-measure);
	margin: var(--kl-space-3) 0 0;
}

@media (max-width: 640px) {
	.kl-lead-entry a {
		display: inline-flex;
		align-items: center;
		min-height: 44px;
	}
}

/* -------------------------------------------- 4 - the hospital page (dev-031) ---
   The re-ordered hospital detail page (docs/design/医院详情页重设计_v1_20260929.md
   §3). Everything here reuses the tokens and the tile language the condition
   page's key-figure band already established - one accent, 8pt spacing, borders
   instead of shadows, tabular figures - so the two detail pages read as one
   site. No colour, no font and no icon is introduced. */

/* The at-a-glance tile states a figure rather than opening a section, so it
   keeps the tile's look and drops the link's affordances. */
.kl-fact__link--static {
	cursor: default;
}

.kl-fact__link--static:hover,
.kl-fact__link--static:focus {
	border-color: var(--kl-border);
	transform: none;
}

/* A label that rests on something (the hospital's own published name) carries
   the ground it rests on, quieter than the label itself. */
.kl-entry__meta-note {
	color: var(--kl-slate);
	font-size: var(--kl-text-sm);
}

/* One card per published listing, each with its own heading and its own table. */
.kl-rankings__block + .kl-rankings__block {
	margin-top: var(--kl-space-6);
}

.kl-rankings__title {
	margin: 0 0 var(--kl-space-3);
	font-size: var(--kl-text-md);
}

/* The hospital's key-facts panel is a vertical list. The condition page's
   key-figure band shares the class name and lays its tiles out on a grid, and
   that rule reaches the panel too - measured at 1280px: the panel's `dl` came
   out as four 58.5px columns, so "Shanghai 上海市" was cut into three lines.
   The panel restates the layout it was built with; the band is untouched. */
.kl-single--hospital .kl-entry__aside .kl-facts__list {
	display: block;
}

.kl-single--hospital .kl-entry__aside .kl-facts__title {
	margin: 0 0 var(--kl-space-3);
}

/* -------------------------- Hospitals hub + rankings (dev-046) ---
   `dev-032`'s `/rankings/` page is retired: its four published lists are now the
   `Rankings & accreditation` region of the `/hospitals/` hub, and a hospital
   page gained a city banner, an action row and a same-city card row. The old
   page shell (`.kl-rankings-hub`, `.kl-hub__section`, `.kl-hub__subtitle`) is
   gone; the pieces the region still uses are kept below, and the boards, the
   distribution bars and the folded rows are new. Every rule reuses the existing
   tokens and the `.kl-table--stack` language, so a wide row turns into a card at
   390 instead of scrolling sideways. */

.kl-hub__hero {
	padding: var(--kl-space-6) 0 var(--kl-space-5);
}

.kl-hub__hero-lede {
	max-width: var(--kl-measure);
	margin: 0 0 var(--kl-space-5);
	color: var(--kl-slate);
	font-size: var(--kl-text-lg);
}

.kl-hub__stats {
	display: flex;
	flex-wrap: wrap;
	gap: var(--kl-space-2) var(--kl-space-3);
	margin: var(--kl-space-5) 0 0;
	padding-top: var(--kl-space-3);
	border-top: 1px solid var(--kl-border);
	color: var(--kl-slate);
	font-size: var(--kl-text-sm);
}

.kl-hub__toc {
	margin: var(--kl-space-5) 0 var(--kl-space-6);
	padding-top: var(--kl-space-4);
	border-top: 1px solid var(--kl-border);
}

.kl-hub__toc-title {
	margin: 0 0 var(--kl-space-2);
	color: var(--kl-slate);
	font-size: var(--kl-text-xs);
	font-weight: var(--kl-weight-semibold);
	letter-spacing: var(--kl-tracking-caps);
	text-transform: uppercase;
}

.kl-hub__caliber {
	margin: 0 0 var(--kl-space-4);
}

.kl-hub__count {
	color: var(--kl-slate);
	font-size: var(--kl-text-sm);
	font-weight: var(--kl-weight-regular);
}

.kl-hub__browse {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--kl-space-3) var(--kl-space-5);
	margin: var(--kl-space-5) 0 0;
}

.kl-hospitals__rankings {
	margin-top: var(--kl-space-8);
	padding-top: var(--kl-space-6);
	border-top: 1px solid var(--kl-border);
}

.kl-hospitals__rankings-title {
	margin: 0 0 var(--kl-space-4);
	font-size: var(--kl-text-2xl);
}

.kl-hub__boundary {
	margin-bottom: var(--kl-space-5);
}

.kl-hub__kpi {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
	gap: var(--kl-space-4);
	margin: 0 0 var(--kl-space-6);
	padding: 0;
	list-style: none;
}

.kl-hub__kpi-item {
	display: flex;
	flex-direction: column;
	gap: var(--kl-space-1);
	padding: var(--kl-space-5);
	border: 1px solid var(--kl-border);
	border-radius: var(--kl-radius-card);
	background: var(--kl-paper-alt);
}

.kl-hub__kpi-value {
	font-size: var(--kl-text-2xl);
	font-weight: var(--kl-weight-semibold);
	letter-spacing: -0.01em;
}

.kl-hub__kpi-label {
	color: var(--kl-slate);
	font-size: var(--kl-text-sm);
}

.kl-hub__board {
	margin-top: var(--kl-space-7);
	padding: var(--kl-space-6) var(--kl-space-5);
	border: 1px solid var(--kl-border);
	border-radius: var(--kl-radius-card);
	background: var(--kl-paper-alt);
}

.kl-hub__board-title {
	margin: 0 0 var(--kl-space-3);
	font-size: var(--kl-text-xl);
}

.kl-hub__board-lede {
	max-width: var(--kl-measure);
	margin: 0 0 var(--kl-space-4);
	color: var(--kl-slate);
}

.kl-hub__bars {
	display: grid;
	gap: var(--kl-space-1);
	margin: 0 0 var(--kl-space-6);
	padding: 0;
	list-style: none;
}

.kl-hub__bar {
	display: grid;
	grid-template-columns: minmax(110px, 220px) minmax(0, 1fr) 56px;
	align-items: center;
	gap: var(--kl-space-3);
	font-size: var(--kl-text-sm);
}

.kl-hub__bar-label {
	overflow: hidden;
	color: var(--kl-slate);
	text-overflow: ellipsis;
	white-space: nowrap;
}

.kl-hub__bar-track {
	display: block;
	height: 8px;
	border-radius: var(--kl-radius-pill);
	background: var(--kl-paper);
}

.kl-hub__bar-fill {
	display: block;
	height: 100%;
	border-radius: var(--kl-radius-pill);
	background: var(--kl-accent);
}

.kl-hub__bar-value {
	text-align: right;
}

.kl-hub__group + .kl-hub__group {
	margin-top: var(--kl-space-6);
	padding-top: var(--kl-space-5);
	border-top: 1px solid var(--kl-border);
}

.kl-hub__group-title {
	display: flex;
	align-items: baseline;
	flex-wrap: wrap;
	gap: var(--kl-space-2) var(--kl-space-3);
	margin: 0 0 var(--kl-space-3);
}

/* A grouped listing's heading is a link to the record it names, so it is a
   control rather than an inline link and holds the 44px floor. */
.kl-hub__group-title a {
	display: inline-flex;
	align-items: center;
	min-height: 44px;
}

.kl-hub__source {
	white-space: nowrap;
}

/* The two controls in the region that are not inline links inside a table cell
   still hold the 44px touch floor the rest of the site keeps (ui-009): the
   source link of a board's caliber list, and every `Show all N` fold. The fold
   rule mirrors the one the condition page's study fold already carries
   (`.kl-trials__more .kl-fold__summary`). */
.kl-hub__caliber a {
	display: inline-flex;
	align-items: center;
	min-height: 44px;
}

.kl-hospitals__rankings .kl-fold__summary {
	display: flex;
	align-items: center;
	gap: var(--kl-space-3);
	min-height: 44px;
	cursor: pointer;
}

/* dev-046 裁定 01 (step 2): on a phone the published lists stack into cards
   (`.kl-table--stack`, dev-025's layout), and every link inside a stacked cell
   holds the 44px floor - the same rule the condition-page tables carry
   (dev-025-01). The desktop keeps its dense rows and exempts these links in the
   touch-target assertion instead. */
@media (max-width: 640px) {
	.kl-hub__rows td a,
	.kl-hub__rows td .kl-hub__source {
		display: inline-flex;
		align-items: center;
		min-height: 44px;
	}
}

.kl-hub__more {
	margin-top: var(--kl-space-3);
}

/* dev-048 T1: the board's own group fold and its distribution fold. Both sit
   under the content that stays visible and reuse the region's `.kl-fold`
   summary (which already carries the 44px touch floor, line 4603). */
.kl-hub__board-more {
	margin-top: var(--kl-space-6);
}

.kl-hub__bars-more {
	margin-top: var(--kl-space-3);
}

.kl-hub__alt {
	margin-top: var(--kl-space-6);
}

.kl-hub__how {
	margin-top: var(--kl-space-8);
	padding-top: var(--kl-space-6);
	border-top: 1px solid var(--kl-border);
}

.kl-hub__how p {
	max-width: var(--kl-measure);
}

/* The hospital page's three new blocks (dev-046). */

.kl-hosp-banner {
	position: relative;
	margin: 0 0 var(--kl-space-5);
	overflow: hidden;
	border-radius: var(--kl-radius-card);
	background: var(--kl-paper-alt);
}

.kl-hosp-banner__img {
	display: block;
	width: 100%;
	height: 150px;
	object-fit: cover;
}

.kl-hosp-banner__label {
	position: absolute;
	left: var(--kl-space-4);
	bottom: var(--kl-space-4);
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	gap: var(--kl-space-1) var(--kl-space-3);
	min-height: 44px;
	padding: var(--kl-space-2) var(--kl-space-4);
	border-radius: var(--kl-radius-pill);
	background: rgba(0, 0, 0, 0.62);
	color: #fff;
	text-decoration: none;
}

.kl-hosp-banner__city {
	font-weight: var(--kl-weight-semibold);
}

.kl-hosp-banner__count {
	font-size: var(--kl-text-sm);
}

.kl-hosp-actions {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--kl-space-3) var(--kl-space-4);
	margin: 0 0 var(--kl-space-5);
}

.kl-hosp-actions .kl-btn {
	min-height: 44px;
}

.kl-hosp-actions__city {
	display: inline-flex;
	align-items: center;
	min-height: 44px;
	color: var(--kl-accent);
	font-weight: var(--kl-weight-semibold);
}

.kl-hosp-nearby__list {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
	gap: var(--kl-space-4);
	margin: 0 0 var(--kl-space-4);
	padding: 0;
	list-style: none;
}

.kl-hosp-nearby__link {
	display: flex;
	flex-direction: column;
	min-height: 44px;
	overflow: hidden;
	border: 1px solid var(--kl-border);
	border-radius: var(--kl-radius-card);
	color: inherit;
	text-decoration: none;
}

.kl-hosp-nearby__img {
	display: block;
	width: 100%;
	height: 96px;
	object-fit: cover;
}

.kl-hosp-nearby__body {
	display: flex;
	flex-direction: column;
	gap: var(--kl-space-1);
	padding: var(--kl-space-4);
}

.kl-hosp-nearby__name {
	font-weight: var(--kl-weight-semibold);
}

.kl-hosp-nearby__grade {
	color: var(--kl-slate);
	font-size: var(--kl-text-sm);
}

.kl-entry__meta--chips {
	gap: var(--kl-space-2);
}

/* One chip is a long label plus the ground it rests on ("University-affiliated
   (from the hospital's own published name)"), and the shared `.kl-chip`
   `white-space: nowrap` kept it from shrinking: at 390px the chip measured
   383px inside a 342px row and pushed the whole document 17px sideways
   (dev-046 B7). The chip now caps at its column and wraps inside it; the 44px
   touch height (`ui-009`) is unchanged. */
.kl-entry__meta-item.kl-chip {
	max-width: 100%;
	white-space: normal;
}

/* The ground gets its own line on a narrow screen, so the label keeps the
   chip's first line to itself. */
@media (max-width: 640px) {
	.kl-entry__meta-note {
		display: block;
	}
}

/* The rail sticks to the top while the record scrolls past it (dev-046): the
   left column used to sit beside a much taller rail, which left a block of
   white space under a thin record's two lines. */
.kl-single--hospital .kl-entry__aside {
	position: sticky;
	top: var(--kl-space-6);
	align-self: start;
	max-height: calc(100vh - var(--kl-space-8));
	overflow-y: auto;
}

/* ------------------------------------------- Guides (dev-033) --- */
/* The explainer section: the homepage teaser (between the hero and the
   category cards) plus the /guides/ archive and detail pages. The figure rules
   mirror the dev-018 content-image block so the new surfaces crop the same
   way; no new design token is introduced. */

.kl-guides__inner {
	display: grid;
	gap: var(--kl-space-6);
	align-items: center;
}

@media (min-width: 900px) {
	.kl-guides__inner {
		grid-template-columns: minmax(0, 1fr) minmax(0, 420px);
	}
}

.kl-guides__lede {
	font-size: var(--kl-text-lg);
	color: var(--kl-slate);
}

.kl-guides__note {
	color: var(--kl-slate);
}

.kl-guides__more {
	margin-bottom: 0;
}

.kl-guides__media {
	margin: 0;
	overflow: hidden;
	border-radius: var(--kl-radius-card);
	background: var(--kl-paper-alt);
	aspect-ratio: 16 / 10;
}

.kl-guide-card__media {
	margin: 0 0 var(--kl-space-4);
	overflow: hidden;
	border-radius: var(--kl-radius-card);
	background: var(--kl-paper-alt);
	aspect-ratio: 16 / 9;
}

.kl-guide-entry__media {
	margin: 0 0 var(--kl-space-5);
	overflow: hidden;
	border-radius: var(--kl-radius-card);
	background: var(--kl-paper-alt);
	aspect-ratio: 16 / 9;
}

.kl-guides__media img,
.kl-guide-card__media img,
.kl-guide-entry__media img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.kl-guide-entry__boundary {
	margin-top: var(--kl-space-6);
	padding-top: var(--kl-space-3);
	border-top: 1px solid var(--kl-border);
	color: var(--kl-slate);
	font-size: var(--kl-text-sm);
}

.kl-guide-entry__note {
	color: var(--kl-slate);
	font-size: var(--kl-text-sm);
}

.kl-archive__foot {
	margin-top: var(--kl-space-6);
}

/* The "Outcomes and care quality" card (dev-039). It carries the same card
   language as the survival figure so a reader meets one shape; only new
   selectors are added. */
.kl-outcomes__card {
	padding: var(--kl-space-5);
	border: 1px solid var(--kl-border);
	border-radius: var(--kl-radius-card);
	background: var(--kl-paper);
}

.kl-outcomes__value {
	margin: 0;
	padding-bottom: var(--kl-space-4);
	border-bottom: 1px solid var(--kl-border);
	color: var(--kl-accent-hover);
	font-family: var(--kl-font-mono);
	font-size: var(--kl-text-2xl);
	font-variant-numeric: tabular-nums;
	font-weight: var(--kl-weight-semibold);
	line-height: var(--kl-leading-tight);
	overflow-wrap: anywhere;
}

.kl-outcomes__target {
	margin: var(--kl-space-4) 0 0;
	color: var(--kl-ink);
	font-size: var(--kl-text-base);
}

.kl-outcomes__sources {
	margin: var(--kl-space-4) 0 0;
	padding: 0;
	list-style: none;
	font-size: var(--kl-text-sm);
}

.kl-outcomes__source + .kl-outcomes__source {
	margin-top: var(--kl-space-1);
}

.kl-outcomes__note {
	margin: var(--kl-space-3) 0 0;
	color: var(--kl-slate);
	font-size: var(--kl-text-sm);
}

/* --------------------------------------------- Grouped header (dev-045) ---
   The English primary menu is five top-level controls: `Home` plus four groups
   (Find treatment / Plan your trip / Why China / About). A group is a native
   `<details>`; its `<summary>` is the toggle and the panel is the next sibling.
   On desktop the panel is revealed by `:hover` / `:focus-within`, so the whole
   navigation works with JavaScript switched off. At <= 900px the same
   `<details>` is the mobile accordion inside `.kl-nav__details`.

   Header budget (master §三 T5): <= 88px on every desktop step. Three rules buy
   it - the brand tagline leaves the row below 1280px, the search collapses to
   the 44x44 toggle dev-024 gave phones across 901-1279px, and the row keeps its
   4px gap (already set at > 900px for the nine-item menu this batch replaces).
   Everything below is additive: no existing selector is changed or removed. */

.kl-nav__item {
	display: flex;
	align-items: center;
}

.kl-nav__group-toggle {
	display: inline-flex;
	align-items: center;
	min-height: 44px;
	color: var(--kl-ink);
	cursor: pointer;
	list-style: none;
}

/* The native marker is replaced by `.kl-nav__caret` (same caret as the
   language selector). */
.kl-nav__group-toggle::-webkit-details-marker {
	display: none;
}

.kl-nav__group-toggle:hover,
.kl-nav__group:focus-within > .kl-nav__group-toggle {
	color: var(--kl-accent-hover);
}

.kl-nav__caret {
	flex: 0 0 auto;
	width: 7px;
	height: 7px;
	margin-left: var(--kl-space-2);
	border-right: 1.5px solid currentColor;
	border-bottom: 1.5px solid currentColor;
	transform: rotate(45deg);
	transition: transform var(--kl-dur-fast) var(--kl-ease);
}

.kl-nav__group:hover .kl-nav__caret,
.kl-nav__group:focus-within .kl-nav__caret {
	transform: rotate(225deg);
}

/* `.kl-nav__list a` (the touch-target rule) also matches these links and sets
   `display: inline-flex; align-items: center`, which turned every panel title
   and description into a centred, shrink-to-fit box. The two-part selector
   outranks it so the column stretches instead. */
.kl-nav__list .kl-nav__panel-link {
	display: flex;
	flex-direction: column;
	align-items: stretch;
	justify-content: center;
	min-height: 44px;
	padding: var(--kl-space-2) var(--kl-space-3);
	border-radius: var(--kl-radius-input);
	color: var(--kl-ink);
	text-decoration: none;
}

.kl-nav__panel-link:hover,
.kl-nav__panel-link:focus {
	background: var(--kl-accent-soft);
	color: var(--kl-accent-hover);
}

.kl-nav__panel-title {
	font-weight: var(--kl-weight-semibold);
}

.kl-nav__panel-desc {
	color: var(--kl-slate);
	font-size: var(--kl-text-sm);
	line-height: var(--kl-leading-snug);
}

/* The header action that replaces the old `Contact` menu entry. Its address
   comes from wellcarechina_lead_form_page_url(), the same helper the footer and
   the standing bar use. */
.kl-header__cta {
	min-height: 44px;
	padding: var(--kl-space-2) var(--kl-space-4);
}

/* Desktop: the row is a flex line - the menu takes what is left after the CTA -
   and a group panel is a flyout anchored to the row itself (not to the group),
   so it can never run past the viewport on a narrow desktop. */
@media (min-width: 901px) {
	.kl-nav {
		position: relative;
		display: flex;
		align-items: center;
		gap: var(--kl-space-2);
		min-width: 0;
	}

	.kl-nav__list {
		flex: 1 1 auto;
		min-width: 0;
	}

	.kl-header__cta {
		flex: 0 0 auto;
	}

	/* Chrome 131+ wraps the non-summary content of a `<details>` in a
	   `::details-content` box and gives it `content-visibility: hidden`, which
	   also creates a containing block (`contain: layout`). A closed group must
	   not clip its flyout to the group's own 60-120px box, so the content stays
	   visible and `.kl-nav__panel`'s own `display` decides what shows. */
	.kl-nav__group::details-content {
		content-visibility: visible;
	}

	.kl-nav__group {
		position: static;
	}

	.kl-nav__panel {
		position: absolute;
		left: 0;
		right: 0;
		top: 100%;
		z-index: 25;
		display: none;
		grid-template-columns: minmax(0, 1fr);
		gap: var(--kl-space-1);
		padding: var(--kl-space-2);
		border: 1px solid var(--kl-border-strong);
		border-top: 0;
		border-radius: 0 0 var(--kl-radius-card) var(--kl-radius-card);
		background: var(--kl-paper);
		box-shadow: var(--kl-shadow-2);
	}

	.kl-nav__group:hover > .kl-nav__panel,
	.kl-nav__group:focus-within > .kl-nav__panel {
		display: grid;
	}
}

/* Two columns once the row is wide enough for readable entries. */
@media (min-width: 1024px) {
	.kl-nav__panel {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}
}

/* 901-1279px used to be the band where the row could not hold the brand, five
   menu controls, the header action, the language switcher and the search box,
   so it swapped the search for the 44px toggle. dev-053 withdraws that control,
   and the band now only needs the two economies that still buy real room: the
   smaller menu type and the decorative site mark. */
@media (min-width: 901px) and (max-width: 1279px) {
	.kl-header__inner {
		position: relative;
	}

	.kl-nav__list {
		font-size: var(--kl-text-base);
	}

	/* The decorative site mark (alt="", aria-hidden) costs 44px; the text brand
	   stays, so nothing is lost and the row fits with room to spare. */
	.kl-branding__mark {
		display: none;
	}

	.kl-header__cta {
		padding-left: var(--kl-space-2);
		padding-right: var(--kl-space-2);
	}
}

/* ------------------------------------------------- Header row rhythm (dev-053) ---
 *
 * The header search control is withdrawn (user ruling 2026-10-02): the box was
 * the last thing that kept the row at its dev-034 width, and the two utility
 * pill and the menu label were all sharing a 4px gutter. Without it the row has
 * the whole 1200px axis, so the arrangement is re-cut from measured slack:
 *
 *   >=1024px    content 1152/976px - brand 172/124 - language 115 - gutters 48
 *               leaves the menu 817/689px. The five labels need 425/402px, so
 *               the row can afford a 32px label gutter and a 32px gutter before
 *               the Contact action, and still leave >130px of air.
 *   901-1023px  content 853px leaves the menu 582px; a 16px label gutter and a
 *               16px action gutter fit with 24px to spare.
 *
 * The spacing lives on the labels (not in the list's row gap), so each item is
 * also a real hover/focus pill. The group toggle is a `<summary>` inside
 * `<details class="kl-nav__group">`, not a direct child of the `<li>`, which is
 * why the group selectors below walk the full path.
 */
@media (min-width: 901px) {
	.kl-header__inner {
		gap: var(--kl-space-5);
	}

	.kl-nav {
		padding: 0;
		gap: var(--kl-space-6);
	}

	.kl-nav__list {
		gap: 0;
	}

	.kl-nav__list > .kl-nav__item > a,
	.kl-nav__list > .kl-nav__item--group > .kl-nav__group > .kl-nav__group-toggle {
		padding: 0 var(--kl-space-4);
		border-radius: var(--kl-radius-input);
	}

	.kl-nav__list > .kl-nav__item > a:hover,
	.kl-nav__list > .kl-nav__item > a:focus-visible,
	.kl-nav__list > .kl-nav__item--group > .kl-nav__group > .kl-nav__group-toggle:hover,
	.kl-nav__list > .kl-nav__item--group > .kl-nav__group > .kl-nav__group-toggle:focus-visible {
		background: var(--kl-accent-soft);
		color: var(--kl-accent-hover);
	}
}

@media (min-width: 901px) and (max-width: 1023px) {
	.kl-header__inner {
		gap: var(--kl-space-4);
	}

	.kl-nav {
		gap: var(--kl-space-4);
	}

	.kl-nav__list > .kl-nav__item > a,
	.kl-nav__list > .kl-nav__item--group > .kl-nav__group > .kl-nav__group-toggle {
		padding: 0 var(--kl-space-2);
	}
}

/* The brand tagline is 343px wide. On the fixed 1200px content axis there is no
   width at which it fits beside the brand, five menu controls, the header
   action, the language switcher and the search box - and a tagline that wrapped
   would push the row past the 88px budget this batch holds. It is already
   dropped at <= 900px, so it leaves the header everywhere (measured: with it,
   /hospitals/ still wrapped to two rows at 1440px). */
.kl-branding__tagline {
	display: none;
}

/* <= 900px: the row is the mobile accordion, so the panel goes back to being a
   plain block and the native `<details>` decides what shows - no hover, no
   position:absolute, no shadow. */
@media (max-width: 900px) {
	.kl-nav__item {
		display: block;
	}

	.kl-nav__group-toggle {
		width: 100%;
	}

	.kl-nav__panel {
		position: static;
		padding: 0 0 0 var(--kl-space-4);
		border: 0;
		border-radius: 0;
		background: transparent;
		box-shadow: none;
	}

	.kl-header__cta {
		margin-top: var(--kl-space-3);
	}
}

/* ------------------------------------------ Contact page layout (dev-047) ---
   ui-028: `/contact/` was a single ~640px column on the far left with ~700px
   empty to its right, because `.kl-prose { max-width: none }` cancelled
   `.kl-container`'s 1200px cap while every field stayed at `--kl-measure`. The
   page now sits on the shared main axis and, from 1024px up, is a two-column
   grid: the form on the left, the notice-at-collection and the privacy entry on
   the right. Only new rules are added here - the `.kl-lead*` block elsewhere is
   untouched, and the field measure is lifted inside this page alone. */

.kl-contact-page {
	padding-bottom: var(--kl-space-8);
}

.kl-contact-layout {
	display: grid;
	grid-template-columns: minmax(0, 2fr) minmax(0, 1fr);
	align-items: start;
	gap: var(--kl-space-7);
}

.kl-contact-layout__main {
	min-width: 0;
}

.kl-lead-section__title {
	margin: 0 0 var(--kl-space-5);
	font-size: var(--kl-text-2xl);
}

/* The fields fill their column instead of the 72ch reading measure they carry
   elsewhere: on a two-column desktop the measure would leave the column half
   empty again. Scoped to this page so no other form is affected. */
.kl-contact-layout__main .kl-lead__field,
.kl-contact-layout__main .kl-lead__actions,
.kl-contact-layout__main .kl-lead__status,
.kl-contact-layout__main .kl-lead__records,
.kl-contact-layout__main .kl-lead__consent {
	max-width: none;
}

/* dev-047 T1.3: the three field groups. The heading is a real h3 (the form's
   own h2 sits above it), so the outline reads page -> form -> group. */
.kl-lead__group {
	margin: 0 0 var(--kl-space-6);
}

.kl-lead__group-title {
	margin: 0 0 var(--kl-space-4);
	padding-bottom: var(--kl-space-2);
	border-bottom: 1px solid var(--kl-border);
	color: var(--kl-ink);
	font-size: var(--kl-text-lg);
}

/* The notice-at-collection card: the page's own compliance copy, on the site's
   card language (border, radius, alt paper - no shadow, no new colour). */
.kl-contact-side {
	padding: var(--kl-space-5);
	border: 1px solid var(--kl-border);
	border-radius: var(--kl-radius-card);
	background: var(--kl-paper-alt);
}

.kl-contact-side__title {
	margin: 0 0 var(--kl-space-4);
	font-size: var(--kl-text-xl);
}

.kl-contact-side__list {
	margin: 0;
	padding-left: var(--kl-space-5);
}

.kl-contact-side__list li + li {
	margin-top: var(--kl-space-2);
}

.kl-contact-side__privacy {
	margin: var(--kl-space-5) 0 0;
	padding-top: var(--kl-space-4);
	border-top: 1px solid var(--kl-border);
}

.kl-contact-side__privacy a {
	display: inline-flex;
	align-items: center;
	min-height: 44px;
}

/* Under the two-column breakpoint the page is one column, like the rest of the
   site (skeleton v1 §6). */
@media (max-width: 1023px) {
	.kl-contact-layout {
		grid-template-columns: minmax(0, 1fr);
		gap: var(--kl-space-6);
	}
}

/* ---------------------------------------------- dev-048 card walls (T3) ---
   The condition / guide / news card walls give every card in a row the same
   description start. The block above the description carries a fixed floor, so
   a one-line and a two-line title (or a one-row and a two-row chip cloud) end on
   the same line; the description then grows to fill the rest of the card, which
   keeps the foot at the bottom exactly as `margin-top:auto` did (skeleton v1
   §4) while its own first line lands on the shared axis. The chip cloud is
   capped at two rows (the `+N` counter already sits outside the clipped row,
   per known-issues #9) - the cap is inert while the records stay under it. */

.kl-card-list > .kl-card .kl-card__title a {
	min-height: 72px;
}

.kl-archive--news .kl-card__meta {
	min-height: 70px;
}

.kl-card-list > .kl-card .kl-chip-row {
	min-height: 96px;
}

.kl-card-list > .kl-card .kl-chip-row > .kl-chips {
	max-height: 96px;
	overflow: hidden;
}

.kl-card-list > .kl-card .kl-card__excerpt {
	flex: 1 1 auto;
	margin-top: 0;
}


