/* Section-styles file, loaded on every onsil template (broad gate — see inc/onsil/enqueue.php). */

/* ── page-hero — cat-lift-contour.md §1 / about.md §0 / space.md §2 / contact.md §0:
   full-bleed photo, 690px PC / 350px M, dark overlay (--c-hero-overlay), header (60px/50px M)
   sits absolutely on top so the hero itself carries the top padding. ── */

.onsil-page-hero {
	position: relative;
	isolation: isolate; /* keep video blending + warm overlay in one stable stack after reveal transform ends */
	display: flex;
	align-items: center;
	justify-content: center;
	min-height: 690px;
	padding-block: 0; /* override .onsil-section's padding-block — height comes from min-height */
	/* audit-2/3 (G4): the header is position:absolute (header.css), so it floats over the hero
	   rather than pushing it down — the old padding-top here double-counted the header height and
	   centred the text 30-34px too low. The text block centres on the full frame, same as Figma. */
	/* flat fallback when a page has no hero_image — spec's own --color-bg-hero (#6b6257) === --c-muted */
	background-color: var(--c-muted);
	background-image: var(--hero-bg, none);
	background-size: cover;
	background-position: center;
	background-blend-mode: screen; /* audit-2/3 (G4): Figma composites the photo over the base fill with SCREEN */
	color: var(--c-bg); /* audit-2 (G4): Figma text is #f3eee8 (--c-bg), not --c-on-dark #f6f1eb */
	text-align: center;
	overflow: hidden;
}

.onsil-page-hero::before {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 1;
	background-color: var(--c-hero-overlay); /* cat-lift-contour.md §1 overlay */
}

.onsil-page-hero__video {
	position: absolute;
	inset: 0;
	z-index: 0;
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
	mix-blend-mode: screen; /* match the poster's warm --c-muted screen blend throughout playback */
}

.onsil-page-hero__inner {
	position: relative;
	z-index: 2;
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 20px;
	padding-inline: 24px;
}

@media (prefers-reduced-motion: reduce) {
	.onsil-page-hero__video {
		display: none;
	}
}

.onsil-page-hero__title {
	font-family: var(--f-display), serif;
	/* cat-lift-contour.md §1: Libertinus Sans Regular 70px / lh 70px — not the 76px --t-hero
	   token (that token is the home hero-slider's own size). */
	font-size: 70px;
	line-height: 70px;
	max-width: 900px;
	text-transform: uppercase; /* audit-2/3 (G4): PC text node renders uppercase */
}

.onsil-page-hero__subtitle {
	font-family: var(--f-ui), sans-serif;
	font-weight: 600; /* Pretendard SemiBold */
	font-size: 20px;
	line-height: 26px;
}

.onsil-page-hero__body {
	font-family: var(--f-ui), var(--f-body), sans-serif;
	font-size: 16px;
	line-height: 1.6;
	max-width: 600px;
}

@media (max-width: 768px) {
	.onsil-page-hero {
		min-height: 350px; /* cat-lift-contour.md §1 mobile frame height */
	}

	.onsil-page-hero__inner {
		gap: 12px;
	}

	.onsil-page-hero__title {
		font-size: 40px; /* space.md M title: Pretendard 40px / lh 40px ("ONSIL SPACE" at 234×40) */
		line-height: 40px;
	}

	.onsil-page-hero__subtitle {
		/* fix-14 (audit MEDIUM #14): about.md's Fidelity Audit + space.md:240 both independently
		   measured Pretendard SemiBold 18px / lh 1.4 on the M hero subtitle — the previous 16/1.5
		   was a size guess, not a measured value. */
		font-size: 18px;
		line-height: 1.4;
	}

	.onsil-page-hero__body {
		font-size: 14px;
	}
}

/* ── brand-intro / intro-panel — home.md §3/§5/§6/§7/§9, cat-body.md §2, contact.md §1:
   centered column, max-width 760px. `intro-panel` is a typography variant, not a layout change. ── */

.onsil-brand-intro__inner {
	max-width: 760px;
	margin-inline: auto;
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 32px;
	text-align: center;
}

.onsil-brand-intro__logo {
	width: 100px;
	height: auto;
	margin-bottom: 8px;
}

.onsil-brand-intro__eyebrow {
	margin-bottom: 4px;
}

.onsil-brand-intro__title {
	font-family: var(--f-ui), sans-serif;
	font-weight: 500; /* cat-body.md §2: Pretendard Medium 30px */
	font-size: 30px;
	line-height: 1.4;
	color: var(--c-ink);
}

.onsil-brand-intro__subtitle {
	font-family: var(--f-ui), sans-serif;
	font-weight: 600; /* cat-lift-contour.md fonts table: Pretendard SemiBold 20px */
	font-size: 20px;
	line-height: 26px;
	color: var(--c-ink);
}

.onsil-brand-intro__body {
	font-family: var(--f-ui), var(--f-body), sans-serif;
	font-size: 16px;
	line-height: 1.6;
	color: var(--c-body);
}

.onsil-brand-intro__note {
	max-width: 760px;
	font-family: var(--f-ui), var(--f-body), sans-serif;
	font-size: 12px;
	line-height: 1.6;
	color: rgba(107, 98, 87, .55);
}

/* intro-panel variant — home.md §5: EN Libertinus h2 (reuses shared .onsil-h2), muted KR sub,
   shorter panel (~200px PC total incl. padding). */
.onsil-intro-panel {
	padding-block: 48px;
}

.onsil-brand-intro__body--panel {
	max-width: 560px;
	color: var(--c-muted);
	font-size: 16px;
}

/* wave2a (audit-5, skin-glow §3/§8 + collagen-restore §3/§5/§9): five brand-intro sections are
   text+image splits (570×710), not the centred pattern — same fixed-column recipe as intro-split
   (610 text / 570 image, justify-content:space-between fills the remaining 260px). `--left` puts
   the image on the left (`order:-1`), matching the two nodes whose image sits at x=240. */
.onsil-brand-intro--split .onsil-brand-intro__split {
	display: grid;
	grid-template-columns: 610px 570px;
	justify-content: space-between;
	align-items: center;
	text-align: left;
}

.onsil-brand-intro--left .onsil-brand-intro__media {
	order: -1;
}

.onsil-brand-intro--right .onsil-brand-intro__media {
	order: 2;
}

.onsil-brand-intro--split .onsil-brand-intro__media img {
	width: 100%;
	height: 710px;
	object-fit: cover;
}

/* Split title is Regular (not the centred variant's Medium) — audit-5. */
.onsil-brand-intro--split .onsil-brand-intro__title {
	font-weight: 400;
	line-height: 1.27; /* 38px / 30px */
}

.onsil-brand-intro--split .onsil-brand-intro__body {
	max-width: 610px;
	margin-top: 32px;
}

.onsil-brand-intro__body-group {
	display: grid;
	gap: 16px;
}

.onsil-brand-intro--split .onsil-brand-intro__body-group {
	max-width: 610px;
	margin-top: 32px;
}

.onsil-brand-intro__body-group .onsil-brand-intro__body {
	margin-top: 0;
}

.onsil-brand-intro__body-lead {
	display: block;
	margin-bottom: 8px;
	font-weight: 600;
}

/* space.md §1 / audit-3: /space/'s brand-intro is its own design — eyebrow is Libertinus 48px
   (not the shared 24px .onsil-eyebrow), and the section's "title" copy is actually the node's
   SemiBold 20px muted subtitle line, not a 30px ink heading. */
.onsil-brand-intro--space .onsil-brand-intro__eyebrow {
	font-family: var(--f-display), serif;
	font-size: 48px;
	color: var(--c-ink);
}

.onsil-brand-intro--space .onsil-brand-intro__title {
	font-family: var(--f-ui), sans-serif;
	font-weight: 600;
	font-size: 20px;
	line-height: 1.6;
	color: var(--c-muted);
}

.onsil-brand-intro--space .onsil-brand-intro__eyebrow + .onsil-brand-intro__title {
	margin-top: -20px;
}

/* Body §2: the Figma title is followed by a short vertical rule before the supporting copy. */
body.onsil-page-body .onsil-brand-intro__inner {
	gap: 24px;
}

body.onsil-page-body .onsil-brand-intro--page-lead .onsil-brand-intro__body::before,
body.onsil-page-skin-glow .onsil-brand-intro--page-lead .onsil-brand-intro__body::before,
body.onsil-page-collagen-restore .onsil-brand-intro--page-lead .onsil-brand-intro__body::before {
	content: "";
	display: block;
	width: 1px;
	height: 40px;
	margin: 0 auto 20px;
	background-color: var(--c-line);
}

@media (max-width: 768px) {
	.onsil-brand-intro__inner {
		gap: 24px;
	}

	.onsil-brand-intro__title {
		font-size: 22px;
	}

	.onsil-intro-panel {
		padding-block: 32px;
	}

	.onsil-brand-intro--split .onsil-brand-intro__split {
		grid-template-columns: 1fr;
		gap: 24px;
		text-align: center;
	}

	/* Mobile always shows the image first, regardless of desktop side (matches intro-split). */
	.onsil-brand-intro--split .onsil-brand-intro__media {
		order: -1;
	}

	.onsil-brand-intro--split .onsil-brand-intro__body {
		margin-top: 24px;
	}

	.onsil-brand-intro--split .onsil-brand-intro__body-group {
		margin-top: 24px;
	}

	.onsil-brand-intro--split .onsil-brand-intro__media img {
		height: auto;
		aspect-ratio: 570 / 710;
	}

	.onsil-brand-intro--space .onsil-brand-intro__eyebrow {
		font-size: 32px;
	}

	.onsil-brand-intro--space .onsil-brand-intro__title {
		font-size: 16px;
	}

	.onsil-brand-intro--space .onsil-brand-intro__eyebrow + .onsil-brand-intro__title {
		margin-top: -12px;
	}
}

/* ── intro-split — cat-lift-contour.md §2/§4: 2-col grid, gap 80px. Text column first in the DOM
   (default = text-left/image-right, matching the ACF `image_side` default of "right"); the
   `--left` modifier reorders the image in front via `order:-1`. Image 570×710, object-fit cover. ── */

/* audit-4 root-cause note: Figma has two shapes, not a symmetric 1fr/1fr grid — 570×710 image /
   610 text (default, image-right) and 610×430 image / 660 text (the `--left` exception, image on
   the left, landscape crop — cat-lift-contour.md §2). Fixed column widths + justify-content
   reproduce the node without guessing a single shared gap. */
.onsil-intro-split__grid {
	display: grid;
	grid-template-columns: 610px 570px;
	justify-content: space-between;
	align-items: center;
}

.onsil-intro-split--left .onsil-intro-split__media {
	order: -1;
}

.onsil-intro-split--left .onsil-intro-split__grid {
	grid-template-columns: 610px 660px;
	justify-content: start;
	gap: 107px;
}

.onsil-intro-split__title {
	margin-bottom: 24px;
}

.onsil-intro-split__text {
	color: var(--c-body);
	line-height: 1.6;
	font-size: 16px;
}

.onsil-intro-split__note {
	margin-top: 16px;
	color: var(--c-muted);
	font-size: 16px;
	line-height: 1.6;
}

.onsil-intro-split__list {
	margin: 24px 0 0;
	display: flex;
	flex-direction: column;
	gap: 16px;
}

.onsil-intro-split__list-row dt {
	font-family: var(--f-ui), sans-serif;
	font-weight: 500;
	font-size: 16px;
	color: var(--c-ink);
}

.onsil-intro-split__list-row dd {
	margin: 4px 0 0;
	color: var(--c-body);
	font-size: 16px;
	line-height: 1.6;
}

/* Checkmarked symptom list (cat-collagen-restore intro-split §4, Figma node 575:3673) — mirrors
   .onsil-concern-list__check's checkmark-glyph pattern above for visual consistency. */
.onsil-intro-split__checklist {
	list-style: none;
	margin: 24px 0 0;
	padding: 0;
}

.onsil-intro-split__checklist li {
	position: relative;
	padding-left: 28px;
	line-height: 1.6;
	font-size: 16px;
	color: var(--c-ink);
}

.onsil-intro-split__checklist li + li {
	margin-top: 12px;
}

.onsil-intro-split__checklist li::before {
	content: "\2713";
	position: absolute;
	left: 0;
	color: var(--c-accent);
}

.onsil-intro-split__link {
	margin-top: 24px;
}

.onsil-intro-split__media img {
	width: 100%;
	height: 710px; /* cat-lift-contour.md §4: image slot 570×710 */
	object-fit: cover;
}

.onsil-intro-split--left .onsil-intro-split__media img {
	height: 430px; /* cat-lift-contour.md §2: the one landscape instance, 610×430 */
}

@media (max-width: 768px) {
	.onsil-intro-split__grid,
	.onsil-intro-split--left .onsil-intro-split__grid {
		/* --left's own selector (0,2,0) otherwise outranks this plain .onsil-intro-split__grid
		   (0,1,0) rule regardless of media query, so it needs its own explicit reset here — this
		   caused a 375px horizontal-overflow regression on /lift-contour/ during verification. */
		grid-template-columns: 1fr;
		justify-content: normal;
		gap: 32px;
	}

	/* Image-left compositions keep the image first; image-right compositions follow DOM order so
	   their text leads and the image closes the section, as in the revised Lift composition. */
	.onsil-intro-split__media {
		order: 0;
	}

	.onsil-intro-split--left .onsil-intro-split__media {
		order: -1;
	}

	.onsil-intro-split__media img {
		height: auto;
		aspect-ratio: 570 / 710;
	}

	.onsil-intro-split--left .onsil-intro-split__media img {
		/* final-review minor: the desktop `--left` rule (page.css, above) sets a fixed
		   `height: 430px` at the same (0,2,1) specificity as this mobile override — since only
		   `aspect-ratio` was redeclared here, `height:430px` kept winning per-property and the
		   image never shrank below 430px tall at 375px wide. Reset `height` here too. */
		height: auto;
		aspect-ratio: 610 / 430;
	}
}

/* ── concern-list — cat-lift-contour.md §3: header row + grid of `--cols` cards, gap 30px.
   Card bg --c-card, padding 40px, min-height 220px. ── */

.onsil-concern-list__head {
	display: flex;
	flex-wrap: wrap;
	justify-content: space-between;
	align-items: flex-start;
	gap: 24px;
	margin-bottom: 48px;
}

.onsil-concern-list__title {
	max-width: 400px;
}

.onsil-concern-list__desc {
	max-width: 460px;
}

.onsil-concern-list__subtitle {
	color: var(--c-body);
	font-size: 16px;
	line-height: 1.6;
}

.onsil-concern-list__note {
	margin-top: 8px;
	color: var(--c-muted);
	font-size: 14px;
	line-height: 1.6;
}

.onsil-concern-list__grid {
	list-style: none;
	margin: 0;
	padding: 0;
	display: grid;
	grid-template-columns: repeat(var(--cols, 2), 1fr);
	gap: 30px;
}

.onsil-concern-list__item {
	background-color: var(--c-card);
	padding: 40px;
	min-height: 220px;
	display: flex;
	flex-direction: column;
	gap: 12px;
}

/* wave2a follow-up (handed over by the treatment/home/board agent): item numbers/labels
   ("CASE 01", "01", …) are Pretendard in every fetched Figma node — the shared `--f-display`
   (Libertinus Sans) has no Hangul either way, so this only affects the numerals/Latin labels. */
.onsil-concern-list__label {
	font-family: var(--f-ui), sans-serif;
	font-size: 16px;
	color: var(--c-muted);
}

.onsil-concern-list__item-title {
	font-family: var(--f-ui), sans-serif;
	font-weight: 500;
	font-size: 18px;
	color: var(--c-ink);
	line-height: 1.5;
}

body.onsil-page-skin-glow [data-sec="concern-list"] .onsil-concern-list__item-title {
	font-size: 30px;
}

body.onsil-page-skin-glow [data-sec="concern-list"] .onsil-concern-list__item {
	justify-content: center;
}

/* Collagen Restore 575:3392: center the detail-card copy and restore the 30px titles.
   Keep the later numbered-row concern list on its compact 16px treatment. */
body.onsil-page-collagen-restore .onsil-concern-list:not(.onsil-concern-list--numbered-rows) .onsil-concern-list__item {
	justify-content: center;
}

body.onsil-page-collagen-restore .onsil-concern-list:not(.onsil-concern-list--numbered-rows) .onsil-concern-list__item-title {
	font-size: 30px;
}

@media (min-width: 1200px) {
	body.onsil-page-skin-glow [data-sec="concern-list"] .onsil-concern-list__head {
		display: grid;
		grid-template-columns: 400px 640px;
		justify-content: space-between;
		column-gap: 24px;
	}

	body.onsil-page-skin-glow [data-sec="concern-list"] .onsil-concern-list__desc {
		max-width: none;
	}
}

.onsil-concern-list__item-body {
	font-family: var(--f-ui), var(--f-body), sans-serif;
	font-size: 16px;
	line-height: 1.6;
	color: var(--c-body);
}

body.onsil-page-lift-contour [data-sec="concern-list"] .onsil-concern-list__item {
	min-height: 160px;
	padding: 32px;
}

/* Collagen Restore 575:4302: 705×100 rows with a 30px circular number and inline copy. */
.onsil-concern-list--numbered-rows .onsil-concern-list__item {
	min-height: 100px;
	padding: 35px 40px;
	flex-direction: row;
	align-items: center;
	gap: 23px;
}

.onsil-concern-list--numbered-rows .onsil-concern-list__label {
	display: flex;
	align-items: center;
	justify-content: center;
	flex: 0 0 30px;
	width: 30px;
	height: 30px;
	border: 1px solid var(--c-line);
	border-radius: 50%;
	font-size: 14px;
	line-height: 1;
}

.onsil-concern-list--numbered-rows .onsil-concern-list__item-title {
	font-size: 16px;
	font-weight: 400;
	line-height: 1.6;
}

@media (max-width: 768px) {
	.onsil-concern-list__head {
		flex-direction: column;
		gap: 16px;
	}

	body.onsil-page-skin-glow [data-sec="concern-list"] .onsil-concern-list__item-title {
		font-size: 22px;
	}

	body.onsil-page-collagen-restore .onsil-concern-list:not(.onsil-concern-list--numbered-rows) .onsil-concern-list__item-title {
		font-size: 22px;
	}

	.onsil-concern-list__grid {
		grid-template-columns: 1fr;
		gap: 16px;
	}

	.onsil-concern-list__item {
		padding: 28px;
		min-height: 0;
	}

	body.onsil-page-lift-contour [data-sec="concern-list"] .onsil-concern-list__item {
		min-height: 0;
		padding: 24px;
	}

	/* Collagen Restore 628:2315: retain Figma's compact 2×2 card composition on mobile. */
	.onsil-concern-list--numbered-rows .onsil-concern-list__grid {
		grid-template-columns: repeat(2, minmax(0, 1fr));
		gap: 10px;
	}

	.onsil-concern-list--numbered-rows .onsil-concern-list__item {
		min-height: 160px;
		padding: 23px 20px;
		flex-direction: column;
		align-items: flex-start;
		gap: 5px;
	}

	.onsil-concern-list--numbered-rows .onsil-concern-list__item-title {
		font-size: 16px;
		line-height: 1.6;
	}
}

/* wave2a (audit-4, cat-body.md §4): photo-left variant — 610×480 image + a plain check-mark list
   (no grid cards). `image` is seeded (seed-v5.php `seed_cat_sections`); only this layout was
   missing. */
.onsil-concern-list--photo .onsil-concern-list__split {
	display: grid;
	grid-template-columns: 610px 1fr;
	gap: 80px;
	align-items: start;
}

.onsil-concern-list--photo .onsil-concern-list__media img {
	width: 100%;
	height: 480px;
	object-fit: cover;
}

.onsil-concern-list--photo .onsil-concern-list__title {
	margin-bottom: 24px;
	max-width: none;
}

.onsil-concern-list--photo .onsil-concern-list__note {
	margin-top: 16px;
	color: var(--c-muted);
	font-size: 16px;
	line-height: 1.6;
}

.onsil-concern-list__checks {
	list-style: none;
	margin: 0;
	padding: 0;
}

.onsil-concern-list__check {
	position: relative;
	padding-left: 28px;
	line-height: 2.5; /* cat-body.md §4: 16px text at a 40px row pitch */
	font-family: var(--f-ui), sans-serif;
	font-size: 16px;
	color: var(--c-ink);
}

.onsil-concern-list__check::before {
	content: "\2713";
	position: absolute;
	left: 0;
	color: var(--c-accent);
}

@media (max-width: 768px) {
	.onsil-concern-list--photo .onsil-concern-list__split {
		grid-template-columns: 1fr;
		gap: 24px;
	}

	.onsil-concern-list--photo .onsil-concern-list__media img {
		height: auto;
		aspect-ratio: 610 / 480;
	}
}

/* wave2a (audit-6, treatment-detail.md): compact variant on treatment detail pages — items sit
   beside the title (460×100 rows, number inline) instead of stacked below a full-width head row.
   Auto-detected (page-treatment.php calls this partial directly with no backing section post, so
   there is no `$args['variant']` to read) rather than passed in — see the PHP comment. */
.onsil-concern-list--compact .onsil-concern-list__head {
	display: flex;
	align-items: flex-start;
	gap: 48px;
	flex-wrap: wrap;
	/* band-residual review #2: the grid lives INSIDE .head in this variant (title + grid are flex
	   siblings), so the base .onsil-concern-list__head{margin-bottom:48px} rule was adding a
	   trailing 48px after the last row with nothing below it to justify the gap — Figma node
	   532:1042/617:513 have no such gap. This alone accounts for the entire desktop +48px delta. */
	margin-bottom: 0;
}

.onsil-concern-list--compact .onsil-concern-list__title {
	flex: 0 0 auto;
	max-width: 320px;
}

.onsil-concern-list--compact .onsil-concern-list__grid {
	flex: 1 1 460px;
	grid-template-columns: repeat(2, 1fr);
	gap: 30px;
}

/* fix-2 (audit HIGH #2): treatment-detail.md confirms every concern item is a shaded #e9e7e1 card
   on both PC (532:1042) and M (617:513) — this override was killing the base card look (--c-card
   bg + padding) that the non-compact variant already gets right. Keep the compact row layout,
   restore the card. */
.onsil-concern-list--compact .onsil-concern-list__item {
	min-height: 80px;
	flex-direction: row;
	align-items: center;
	gap: 16px;
	padding: 16px 24px;
	background-color: var(--c-card);
}

.onsil-concern-list--compact .onsil-concern-list__item-title {
	font-weight: 400;
}

@media (max-width: 768px) {
	.onsil-concern-list--compact .onsil-concern-list__head {
		flex-direction: column;
	}

	.onsil-concern-list--compact .onsil-concern-list__grid {
		grid-template-columns: 1fr;
		gap: 16px; /* fix-5 (audit MEDIUM #5): matches the default variant's mobile gap — the desktop
		   30px carried straight through unchanged, one contributor to the 26-84% mobile overage */
	}

	.onsil-concern-list--compact .onsil-concern-list__item {
		min-height: 56px;
		padding: 12px 14px; /* Figma M row (617:518 etc.) leaves ~47px before the title and ~16px
		   after it in a 340px card — the desktop 24px inset ate ~20px more of that budget than the
		   design allows, forcing 2-line wraps on the longer concern strings even at 14px */
		gap: 8px;
	}

	/* band-residual review #2: item-title at 18px wraps 2-deep in the ~270px pill content width
	   (Figma M node 617:518 etc.: text bbox height 20 at a 60px row => single-line ~14px, not the
	   shared 18px default variant uses). Desktop's 18px already fits single-line (verified: 460px
	   card, PC node 532:1046 text bbox height26 == font18/line-height1.5, row stays 100px as
	   spec'd) — this override is mobile-only. */
	.onsil-concern-list--compact .onsil-concern-list__item-title {
		font-size: 14px;
		line-height: 1.4;
	}
}

/* ── card-row — cat-lift-contour.md §5, cat-collagen-restore.md §13: two modes.
   (a) `.onsil-card-row--feature`: grouped `card` posts (home.md §4), fixed 3-up.
   (b) generic `$cols`-wide grid of number|title|body cards, bg --c-card. ── */

.onsil-card-row__title {
	margin-bottom: 16px;
}

.onsil-card-row__subtitle {
	margin-bottom: 48px;
	color: var(--c-body);
	font-size: 16px;
	line-height: 1.6;
}

.onsil-card-row__grid {
	list-style: none;
	/* audit-1: this class shares an element with .onsil-wrap; a `margin:0` shorthand here was
	   zeroing .onsil-wrap's margin-inline:auto too, pinning the grid flush-left with ~432px of
	   dead space on the right at 1920. Reset only the UL's own block margin. */
	margin-block: 0;
	padding: 0;
	display: grid;
	grid-template-columns: repeat(var(--cols, 3), 1fr);
	gap: 30px;
}

body.onsil-page-collagen-restore [data-sec="feature-cards-3"] .onsil-card-row__grid {
	grid-auto-rows: 1fr;
}

/* Collagen Restore 575:4369: four 340px cards span the same 1440px edges as the heading. */
body.onsil-page-collagen-restore [data-sec="feature-cards-4"] .onsil-card-row__grid {
	grid-template-columns: repeat(4, minmax(0, 340px));
	justify-content: space-between;
	gap: 0;
}

body.onsil-page-collagen-restore [data-sec="feature-cards-4"] .onsil-card-row__card {
	width: 340px;
	min-height: 590px;
	padding: 0;
	gap: 0;
}

body.onsil-page-collagen-restore [data-sec="feature-cards-4"] .onsil-card-row__card-media {
	height: 300px;
	aspect-ratio: auto;
}

body.onsil-page-collagen-restore [data-sec="feature-cards-4"] .onsil-card-row__card-content {
	flex: 0 0 290px;
	padding: 38px 30px;
	gap: 12px;
}

body.onsil-page-collagen-restore [data-sec="feature-cards-4"] .onsil-card-row__number {
	font-family: var(--f-ui), sans-serif;
	font-size: 16px;
	line-height: 1.6;
}

body.onsil-page-collagen-restore [data-sec="feature-cards-4"] .onsil-card-row__card-title {
	font-size: 28px;
	font-weight: 400;
	line-height: 1.4;
}

.onsil-card-row__card {
	background-color: var(--c-card);
	padding: 40px;
	display: flex;
	flex-direction: column;
	gap: 12px;
}

.onsil-card-row__number {
	font-family: var(--f-display), serif;
	font-size: 24px;
	color: var(--c-muted);
}

.onsil-card-row__card-title {
	font-family: var(--f-ui), sans-serif;
	font-weight: 500;
	font-size: 18px;
	color: var(--c-ink);
	line-height: 1.5;
}

[data-sec="precaution-2col"] .onsil-card-row__card-title {
	font-size: 22px;
	line-height: 1.35;
}

[data-sec="precaution-2col"] .onsil-card-row__card-content {
	text-align: center;
}

.onsil-card-row__card-body {
	font-family: var(--f-ui), var(--f-body), sans-serif;
	font-size: 16px;
	line-height: 1.6;
	color: var(--c-body);
}

/* cols=4 — cat-collagen-restore.md §13 feature-cards-4: tall narrow 340×590 cards. */
.onsil-card-row--4 .onsil-card-row__card {
	padding: 40px 28px;
	min-height: 590px;
}

/* cols=2 — cat-lift-contour.md §9 precaution-2col: wide 710px boxes, no number. */
.onsil-card-row--2 .onsil-card-row__card {
	min-height: 220px;
}

/* wave2a (audit-4/5): photo-topped cards — lift's card-row-3 (460×400 photo + panel, "01/02/03"),
   collagen's feature-cards-3/-4 (photo + panel + an optional "자세히 보기" link on some cards).
   `.onsil-card-row__card--photo` removes the flat card padding so the photo runs edge-to-edge and
   the copy lives in its own body block below it. */
.onsil-card-row__card--photo {
	padding: 0;
	gap: 0;
	background-color: transparent;
}

.onsil-card-row__card-media {
	aspect-ratio: 460 / 400;
	overflow: hidden;
	background-color: var(--c-card);
}

.onsil-card-row__card-img {
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.onsil-card-row__card--photo .onsil-card-row__card-content {
	flex: 1;
	background-color: var(--c-card);
	padding: 40px;
	display: flex;
	flex-direction: column;
	gap: 12px;
}

.onsil-card-row__card-link {
	margin-top: 4px;
	/* Inline padding + matching negative margin: room for the hover fill without moving the text. */
	padding: 4px 8px;
	margin-inline: -8px;
	font-family: var(--f-ui), var(--f-body), sans-serif;
	font-size: 14px;
	color: var(--c-muted);
	transition: background-color 200ms ease, color 200ms ease;
}

.onsil-card-row__card-link::after {
	content: " \2192"; /* → */
}

@media (hover: hover) {
	.onsil-card-row__card-link:hover {
		color: var(--c-ink);
		background-color: #e2e0db;
	}
}

/* Mode (a): feature cards (home.md §4) — image 440×440 square, EN Libertinus title, rule, KR body. */
.onsil-card-row__feature {
	display: flex;
	flex-direction: column;
}

.onsil-square {
	aspect-ratio: 1 / 1;
	overflow: hidden;
}

.onsil-square img {
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.onsil-card-row__feature-body {
	padding-block: 24px 30px;
	padding-inline: 16px; /* home.md §4: body pt24 pb30 px16 */
}

.onsil-card-row--feature .onsil-card-row__grid {
	gap: 48px; /* home.md §4: column gap 48, not the generic card-row 30 */
}

.onsil-card-row__feature-title {
	font-family: var(--f-display), serif;
	font-size: 24px;
	letter-spacing: .04em;
	color: var(--c-ink);
	white-space: nowrap;
}

.onsil-card-row__rule {
	display: block;
	width: 24px;
	height: 1px;
	background-color: var(--c-muted);
	margin-block: 12px;
}

.onsil-card-row__feature-text {
	font-family: var(--f-ui), var(--f-body), sans-serif;
	font-size: 16px;
	line-height: 1.5;
	letter-spacing: -.02em;
	color: var(--c-body);
}

/* NB: this 1024px block must precede the 768px block below — both match at ≤768px, and with
   equal selector specificity the later rule in source order wins regardless of which media query
   is "narrower", so the mobile (1-col) override has to come after this tablet (2-col) one. */
@media (max-width: 1024px) {
	.onsil-card-row__feature-title {
		white-space: normal;
		text-wrap: balance;
	}

	.onsil-card-row--4 .onsil-card-row__grid {
		grid-template-columns: repeat(2, 1fr);
	}

	body.onsil-page-collagen-restore [data-sec="feature-cards-4"] .onsil-card-row__grid {
		grid-template-columns: repeat(2, minmax(0, 340px));
		gap: 24px;
	}
}

@media (max-width: 768px) {
	.onsil-card-row__grid {
		grid-template-columns: 1fr;
	}

	.onsil-card-row--4 .onsil-card-row__grid {
		grid-template-columns: 1fr;
	}

	.onsil-card-row--4 .onsil-card-row__card {
		min-height: 0;
	}

	body.onsil-page-collagen-restore [data-sec="feature-cards-4"] .onsil-card-row__grid {
		grid-template-columns: 1fr;
		gap: 10px;
	}

	body.onsil-page-collagen-restore [data-sec="feature-cards-4"] .onsil-card-row__card {
		width: 100%;
		min-height: 500px;
	}

	body.onsil-page-collagen-restore [data-sec="feature-cards-4"] .onsil-card-row__card-media {
		height: 300px;
	}

	body.onsil-page-collagen-restore [data-sec="feature-cards-4"] .onsil-card-row__card-content {
		flex-basis: auto;
		min-height: 200px;
		padding: 32px 25px 18px;
		gap: 8px;
	}

	body.onsil-page-collagen-restore [data-sec="feature-cards-4"] .onsil-card-row__number {
		margin-bottom: 8px;
		font-size: 14px;
	}

	body.onsil-page-collagen-restore [data-sec="feature-cards-4"] .onsil-card-row__card-title {
		font-size: 22px;
		line-height: 1.3;
	}

	body.onsil-page-collagen-restore [data-sec="feature-cards-4"] .onsil-card-row__card-body {
		font-size: 14px;
		line-height: 1.8;
	}

	.onsil-card-row--feature .onsil-card-row__grid {
		grid-template-columns: 1fr;
	}
}

/* ── misc (page.php) ── */

.onsil-prose {
	padding-block: var(--section-y);
	color: var(--c-ink);
	line-height: 1.8;
}

.onsil-index-list {
	list-style: none;
	margin: 0;
	padding: 0;
}

.onsil-index-list li {
	border-bottom: 1px solid;
	border-bottom-color: var(--c-line);
	padding-block: 16px;
}

/* ── process-steps — cat-lift-contour.md §7, cat-body.md §6, cat-skin-glow.md §6/§9,
   cat-collagen-restore.md §12: two layouts chosen by whether an image is set.
   --list: STEP list left / image right (1fr 1fr, gap 80, image 570×710, matches intro-split).
   --cards: horizontal row of equal STEP cards, `--cols` set in PHP (wraps 6→2×3, 8→2×4). ── */

.onsil-process-steps__title {
	margin-bottom: 48px;
}

/* audit-4: list column 750 wide, image 570 wide, gap 120 (750+120+570=1440 exactly) — not a
   symmetric 1fr/1fr split. */
.onsil-process-steps__grid {
	display: grid;
	grid-template-columns: 750px 570px;
	justify-content: space-between;
	align-items: start;
}

.onsil-process-steps__list {
	list-style: none;
	margin: 0;
	padding: 0;
	display: flex;
	flex-direction: column;
}

.onsil-process-steps__media img {
	width: 100%;
	height: 710px;
	object-fit: cover;
}

.onsil-process-steps__cards {
	list-style: none;
	margin: 0;
	padding: 0;
	display: grid;
	grid-template-columns: repeat(var(--cols, 4), 1fr);
	gap: 30px;
}

/* wave2a (audit-4/5): list rows are a two-column layout (STEP label in its own left column, name
   +body to the right) separated by hairlines — not a vertical stack of gapped blocks. `--cards`
   step anatomy (stacked label/name/body) is unaffected. */
.onsil-process-steps--list .onsil-process-steps__step {
	display: flex;
	flex-direction: row;
	align-items: flex-start;
	gap: 24px;
	padding-block: 24px;
	border-top: 1px solid;
	border-top-color: var(--c-line);
}

.onsil-process-steps--list .onsil-process-steps__step:last-child {
	border-bottom: 1px solid;
	border-bottom-color: var(--c-line);
}

.onsil-process-steps--cards .onsil-process-steps__step {
	display: flex;
	flex-direction: column;
	gap: 8px;
}

.onsil-process-steps__content {
	display: flex;
	flex-direction: column;
	gap: 8px;
}

.onsil-process-steps__label {
	flex: 0 0 90px; /* --list: its own left column */
	font-family: var(--f-ui), sans-serif; /* audit-4/5: Pretendard, not Libertinus */
	font-size: 14px;
	color: var(--c-muted);
}

.onsil-process-steps__name {
	font-family: var(--f-ui), sans-serif;
	font-weight: 500;
	font-size: 18px;
	color: var(--c-ink);
	line-height: 1.5;
}

.onsil-process-steps__body {
	font-family: var(--f-ui), var(--f-body), sans-serif;
	font-size: 16px;
	line-height: 1.6;
	color: var(--c-body);
}

@media (max-width: 768px) {
	.onsil-process-steps__title {
		margin-bottom: 24px;
	}

	.onsil-process-steps__grid {
		grid-template-columns: 1fr;
		gap: 24px;
	}

	/* wave2a (audit-4/5): mobile keeps the DOM order (list, then media) so the photo sits BELOW
	   the step list, matching the node — the old `order:-1` here forced it above on every route. */
	.onsil-process-steps__media img {
		height: auto;
		aspect-ratio: 570 / 710;
	}

	.onsil-process-steps--list .onsil-process-steps__step {
		gap: 16px;
		padding-block: 16px;
	}

	.onsil-process-steps__label {
		flex-basis: 64px;
	}

	.onsil-process-steps__list,
	.onsil-process-steps__cards {
		grid-template-columns: 1fr;
		gap: 24px;
	}
}

/* ── panel-list — cat-lift-contour.md §8 reason-band / cat-skin-glow.md §10 bullet-list:
   one wide photo-backed band (~1440×400). wave2a (audit-4/5): Figma is a single row of centred,
   vertically-dividered captions over a photo (`--c-bg` #f3eee8 text) — not a flat 2×2 card grid or
   a plain bulleted list. `.onsil-panel-list__grid` = cols=2 (4 "제목|본문" items across one row);
   `.onsil-panel-list__bullets` = cols=1 (7 single-line items, skin-glow's timeline). `--photo` is
   added only when the section's `image` field is set (seeded — seed-v5.php `seed_cat_sections`);
   sections without a photo keep the flat --c-card fallback below. ── */

.onsil-panel-list__title {
	margin-bottom: 48px;
}

.onsil-panel-list__panel {
	position: relative;
	overflow: hidden;
	background-color: var(--c-card);
	padding: 60px;
}

/* final-review escalated minor: the panel photo (.onsil-panel-list__media) is position:absolute
   with nothing sizing its container — .onsil-panel-list__panel had no height of its own beyond
   its content, so the ~400px photo band Figma shows (cat-lift-contour.md §8 / cat-skin-glow.md
   §10) could never reproduce; it collapsed to just the caption row's own height. */
.onsil-panel-list__panel--photo {
	min-height: 400px;
	display: flex;
	align-items: center;
}

.onsil-panel-list__media {
	position: absolute;
	inset: 0;
	z-index: 0;
}

.onsil-panel-list__media img {
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.onsil-panel-list__panel--photo::before {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 0;
	/* fix-4 (audit MEDIUM #4): the reason-band photo is a light, high-key rippled-water texture —
	   .35 let bright highlights (esp. the last line) burn through the cream text; the section's
	   own overlay token (--c-hero-overlay, used identically on page-hero over similarly bright
	   photos) is .5 and is the only other darkening value this build already commits to, so reuse
	   it here rather than inventing a new opacity. */
	background-color: rgba(26, 26, 26, .5);
}

.onsil-panel-list__grid,
.onsil-panel-list__bullets {
	position: relative;
	z-index: 1;
}

.onsil-panel-list__grid {
	list-style: none;
	margin: 0;
	padding: 0;
	display: flex;
}

.onsil-panel-list__grid .onsil-panel-list__item {
	flex: 1 1 0;
	text-align: center;
	padding-inline: 24px;
	border-left: 1px solid rgba(243, 238, 232, .4);
}

.onsil-panel-list__grid .onsil-panel-list__item:first-child {
	border-left: 0;
}

.onsil-panel-list__item-title {
	font-family: var(--f-ui), sans-serif;
	font-weight: 500;
	font-size: 18px;
	color: var(--c-ink);
	line-height: 1.5;
}

.onsil-panel-list__item-body {
	margin-top: 8px;
	font-family: var(--f-ui), var(--f-body), sans-serif;
	font-size: 16px;
	line-height: 1.6;
	color: var(--c-body);
}

.onsil-panel-list__panel--photo .onsil-panel-list__item-title,
.onsil-panel-list__panel--photo .onsil-panel-list__item-body {
	color: var(--c-bg);
}

.onsil-panel-list__bullets {
	list-style: none;
	margin: 0;
	padding: 0;
	display: flex;
	flex-wrap: wrap;
}

.onsil-panel-list__bullet {
	flex: 1 1 0;
	min-width: 140px;
	text-align: center;
	padding-inline: 16px;
	border-left: 1px solid rgba(243, 238, 232, .4);
	font-family: var(--f-ui), var(--f-body), sans-serif;
	font-size: 16px;
	line-height: 1.6;
	color: var(--c-ink);
}

.onsil-panel-list__bullet:first-child {
	border-left: 0;
}

.onsil-panel-list__panel--photo .onsil-panel-list__bullet {
	color: var(--c-bg);
}

@media (max-width: 768px) {
	.onsil-panel-list__title {
		margin-bottom: 24px;
	}

	.onsil-panel-list__panel {
		padding: 32px 24px;
	}

	/* fix-4 (audit MEDIUM #4): live-measured natural content at 375px is already 519px on
	   /lift-contour/ and 413px on /body/ (both above the desktop 400px floor), so `auto` isn't
	   visibly collapsing the band on either page today — but it leaves the band's height purely
	   content-driven with no deliberate floor, the same defect class as the desktop fix addressed.
	   300px is a safety floor below both measured naturals (so it changes nothing today) that
	   guards shorter-copy routes (skin-glow/collagen-restore) from collapsing later. */
	.onsil-panel-list__panel--photo {
		min-height: 300px;
	}

	.onsil-panel-list__grid,
	.onsil-panel-list__bullets {
		flex-direction: column;
	}

	.onsil-panel-list__grid .onsil-panel-list__item,
	.onsil-panel-list__bullet {
		border-left: 0;
		border-top: 1px solid rgba(243, 238, 232, .4);
		padding-block: 16px;
		padding-inline: 0;
	}

	.onsil-panel-list__grid .onsil-panel-list__item:first-child,
	.onsil-panel-list__bullet:first-child {
		border-top: 0;
	}
}

/* ── faq — ElevenCreative disclosure motion adapted to onsil's editable section content. ── */

/* fix-12 (audit MEDIUM #12): space.md §6 confirms Figma node 569:878 (FAQ section title) is
   Pretendard Regular, not the shared `.onsil-h3` default of Medium (500) — other `.onsil-h3`
   call sites (treatment-lineup, treat-hero, card-row…) have spec lines confirming 500 is correct
   for them, so this overrides only the FAQ title rather than changing the shared class. */
.onsil-faq__title {
	align-self: start;
	font-weight: 400;
}

.onsil-faq__layout {
	display: grid;
	grid-template-columns: minmax(0, 1fr);
	gap: 65px;
}

.onsil-faq__list {
	border-top: 1px solid var(--c-line);
}

.onsil-faq__item {
	border-bottom: 1px solid var(--c-line);
}

.onsil-faq__q {
	transition: padding-bottom 300ms cubic-bezier(.4, 0, .2, 1);
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 24px;
	width: 100%;
	padding-block: 20px;
	padding-inline: 0;
	background: none;
	border: 0;
	text-align: left;
	cursor: pointer;
	font-family: var(--f-ui), sans-serif;
	font-weight: 500;
	font-size: 18px;
	line-height: 1.6;
	color: var(--c-ink);
}

.onsil-faq__icon {
	flex: 0 0 25px;
	width: 25px;
	height: 25px;
	background-image: url('../img/faq/plus.svg?v=1');
	background-repeat: no-repeat;
	background-position: center;
}

.onsil-faq__icon span {
	display: none;
}

.onsil-faq__q[aria-expanded="true"] .onsil-faq__icon {
	background-image: url('../img/faq/close.svg?v=1');
}

.onsil-faq__a {
	height: var(--faq-panel-height, auto);
	overflow: clip;
	opacity: 1;
	transform: translateY(0);
	transition: height 300ms cubic-bezier(.4, 0, .2, 1), opacity 300ms cubic-bezier(.4, 0, .2, 1), transform 300ms cubic-bezier(.4, 0, .2, 1);
	font-family: var(--f-ui), var(--f-body), sans-serif;
	font-size: 16px;
	line-height: 1.6;
	color: var(--c-muted);
}

.onsil-faq__a[aria-hidden="true"] {
	opacity: 0;
	transform: translateY(-12px);
}

.onsil-faq__q[aria-expanded="true"] {
	padding-bottom: 4px;
}

.onsil-faq__a-inner {
	padding-block: 0 20px;
}

@media (max-width: 768px) {
	.onsil-faq__layout {
		gap: 28px;
	}

	.onsil-faq__title {
		margin-bottom: 0;
	}

	.onsil-faq__q {
		padding-block: 20px;
		font-size: 16px;
	}

	.onsil-faq__a-inner {
		padding-bottom: 28px;
	}
}

@media (prefers-reduced-motion: reduce) {
	.onsil-faq__q,
	.onsil-faq__a,
	.onsil-faq__icon span {
		transition-duration: 0ms;
	}
}

/* ── image-wide — space.md §4, home.md §10: full-width photo (1440×800) + caption row
   (title/body left, optional boxed link right for the home variant). ── */

.onsil-image-wide__media img {
	width: 100%;
	height: 800px;
	object-fit: cover;
}

/* wave2a (audit-1, home.md §10): Figma is a full-width caption row (right-aligned by the home
   variant's own type override in home.css) with the CTA in its OWN centred row underneath — the
   old `justify-content:space-between` shared one row, which put the link at the caption's right
   edge instead of centred below it, and left the text only as wide as its own box (defeating
   text-align:right). This file only owns the structure; text alignment stays whatever the caller
   sets on `.onsil-image-wide__text` (home.css, home-only). */
.onsil-image-wide__caption {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 16px;
	margin-top: 45px;
}

.onsil-image-wide__text {
	width: 100%;
}

.onsil-image-wide__title {
	margin-bottom: 12px;
}

.onsil-image-wide__body {
	max-width: 560px;
	font-family: var(--f-ui), var(--f-body), sans-serif;
	font-size: 16px;
	line-height: 1.6;
	color: var(--c-muted);
}

@media (max-width: 768px) {
	.onsil-image-wide__media img {
		height: auto;
		aspect-ratio: 340 / 189;
	}

	.onsil-image-wide__caption {
		margin-top: 24px;
		align-items: flex-start;
	}

	.onsil-image-wide__link {
		align-self: center;
	}
}

/* ── doctor-profile — about.md §1, cat-lift-contour.md §10, home.md §6: photo left (570×710) /
   text right by default; `--home` flips to text left / photo right + boxed link to About. ── */

/* audit-2 (about): Media 720×712 / Body 492, justify-between in a 1440 wrap (computed gap 228) —
   not a symmetric 1fr/1fr 80px-gap split. Home variant (audit-1) is a different node: same fixed
   gap works out to 180px there, image ≤720 already renders inside tolerance.
   wave2a (item 11): audit-2 measured the About page's own node directly with get_metadata
   (720×712) and is the more authoritative source for this shared partial; audit-5's 570×710
   figure for the category-page usage explicitly defers to "the about auditor" rather than
   asserting its own number (see audit-5's doctor-profile rows). Using 720×712 everywhere this
   partial renders (About + every category page) — corrected the media height below from 710 to
   712 to match. */
.onsil-doctor-profile__grid {
	display: grid;
	grid-template-columns: 720px 492px;
	justify-content: space-between;
	align-items: start;
}

.onsil-doctor-profile__body {
	padding-top: 48px; /* about.md §1: text block top-aligns with the photo, pt 48 */
}

.onsil-doctor-profile__media img {
	width: 100%;
	height: 712px;
	object-fit: cover;
}

.onsil-doctor-profile--home .onsil-doctor-profile__media {
	order: 2;
}

.onsil-doctor-profile--home .onsil-doctor-profile__grid {
	grid-template-columns: 1fr 1fr;
	gap: 180px; /* home.md §6: measured column gap */
}

.onsil-doctor-profile--category .onsil-doctor-profile__grid {
	grid-template-columns: 570px 720px;
	gap: 150px;
	justify-content: start;
}

.onsil-doctor-profile--category .onsil-doctor-profile__media img {
	height: 710px;
}

.onsil-doctor-profile--category .onsil-doctor-profile__body {
	padding-top: 54px;
}

.onsil-doctor-profile--category .onsil-doctor-profile__name {
	max-width: 660px;
	margin-top: 0;
	line-height: 38px;
}

.onsil-doctor-profile--category .onsil-doctor-profile__quote-kr {
	max-width: 660px;
	margin-top: 21px;
}

.onsil-doctor-profile--category .onsil-doctor-profile__rule {
	margin-top: 40px;
}

.onsil-doctor-profile--category .onsil-doctor-profile__credentials {
	margin-top: 28px;
}

.onsil-doctor-profile--home .onsil-doctor-profile__body {
	padding-top: 0; /* home.md §6: body pt 0, image itself carries the offset */
}

.onsil-doctor-profile--home .onsil-doctor-profile__media {
	margin-top: 17px;
}

.onsil-doctor-profile__en-name {
	display: block;
	font-family: var(--f-display), serif;
	font-size: 16px;
	letter-spacing: .04em;
	color: var(--c-ink);
}

.onsil-doctor-profile__name {
	margin-top: 8px;
	font-family: var(--f-ui), sans-serif;
	font-weight: 500;
	font-size: 30px;
	color: var(--c-ink);
}

.onsil-doctor-profile__role {
	margin-top: 8px;
	font-family: var(--f-ui), var(--f-body), sans-serif;
	font-size: 13px;
	color: var(--c-muted);
}

.onsil-doctor-profile__quote-kr {
	margin-top: 24px;
	font-family: var(--f-ui), var(--f-body), sans-serif;
	font-size: 18px;
	line-height: 1.5;
	color: var(--c-ink);
}

.onsil-doctor-profile__quote-en {
	margin-top: 8px;
	font-family: var(--f-display), serif;
	font-size: 13px;
	line-height: 1.4;
	color: var(--c-muted);
}

.onsil-doctor-profile__credentials {
	margin-top: 32px;
	display: flex;
	flex-direction: column;
	gap: 8px;
}

.onsil-treatment-lineup__cards.is-draggable {
	cursor: grab;
	user-select: none;
}

.onsil-treatment-lineup__cards.is-dragging {
	cursor: grabbing;
	scroll-snap-type: none;
}

.onsil-doctor-profile__cred-title {
	margin-top: 16px;
	font-family: var(--f-display), serif;
	font-size: 14px;
	color: var(--c-ink);
}

.onsil-doctor-profile__cred-title:first-child {
	margin-top: 0;
}

.onsil-doctor-profile__cred-item {
	font-family: var(--f-ui), var(--f-body), sans-serif;
	font-size: 14px;
	line-height: 1.8;
	color: var(--c-muted);
}

.onsil-doctor-profile__rule {
	display: block;
	margin-top: 32px;
	height: 1px;
	background-color: var(--c-line);
}

.onsil-doctor-profile__link {
	margin-top: 32px;
}

/* Preserve the fixed Figma columns on wide screens, but let the same proportions contract before
   the single-column mobile breakpoint. Without this middle range, About's 720px + 492px columns
   overflow every viewport narrower than the 1260px wrap they require. */
@media (min-width: 769px) and (max-width: 1511px) {
	.onsil-doctor-profile__grid {
		grid-template-columns: minmax(0, 1.46fr) minmax(0, 1fr);
		gap: clamp(48px, 8vw, 120px);
		justify-content: initial;
	}

	.onsil-doctor-profile--home .onsil-doctor-profile__grid {
		grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
		gap: clamp(48px, 8vw, 120px);
	}

	.onsil-doctor-profile--category .onsil-doctor-profile__grid {
		grid-template-columns: minmax(0, 570fr) minmax(0, 720fr);
		gap: clamp(48px, 8vw, 120px);
		justify-content: initial;
	}
}

@media (max-width: 768px) {
	.onsil-doctor-profile__grid,
	.onsil-doctor-profile--home .onsil-doctor-profile__grid,
	.onsil-doctor-profile--category .onsil-doctor-profile__grid {
		/* --home's own selector (0,2,0) otherwise outranks this plain .onsil-doctor-profile__grid
		   (0,1,0) rule regardless of media query — same class of regression as intro-split above. */
		grid-template-columns: 1fr;
		gap: 24px;
	}

	.onsil-doctor-profile__media,
	.onsil-doctor-profile--home .onsil-doctor-profile__media {
		order: -1;
		margin-top: 0;
	}

	.onsil-doctor-profile__media img {
		height: auto;
		aspect-ratio: 720 / 712;
	}

	.onsil-doctor-profile__body,
	.onsil-doctor-profile--home .onsil-doctor-profile__body,
	.onsil-doctor-profile--category .onsil-doctor-profile__body {
		padding-top: 0;
	}
}

/* ── treatment-lineup — cat-lift-contour.md §6, treatment-detail.md §5: title + horizontal-scroll
   row of 440×680 cards (image 440×400, body 440×280). The rail aligns with the wrap's
   content edge, then bleeds to the viewport's right edge. Mobile cards are 280×436. ── */

.onsil-treatment-lineup__title {
	margin-bottom: 64px;
}

.onsil-treatment-lineup {
	overflow-x: clip;
}

.onsil-treatment-lineup__cards {
	width: 100%;
	max-width: none;
	gap: 30px;
	padding-bottom: 4px; /* room for the focus ring on the last card's link */
	overscroll-behavior-inline: contain;
}

.onsil-treatment-lineup__card {
	flex: 0 0 440px;
	width: 440px;
	height: 680px;
}

.onsil-treatment-lineup__link {
	display: grid;
	grid-template-rows: 400px 280px;
	height: 100%;
	color: inherit;
}

/* wave2a (audit-6): the node insets the packshot inside the tile with margins on every route
   (contain, not cover) — `cover` was cropping landscape packshots (e.g. botulinum) to ~46% of
   their height. Tile bg corrected to the node's #e2e0db (a Figma-only tint, no matching token). */
.onsil-treatment-lineup__media {
	background-color: #e2e0db;
	height: 400px;
	overflow: hidden;
	padding: 30px;
}

.onsil-treatment-lineup__media img {
	width: 100%;
	height: 100%;
	object-fit: contain;
	opacity: 1;
	transition: opacity 1s;
}

@media (hover: hover) {
	.onsil-treatment-lineup__link:hover .onsil-treatment-lineup__img,
	.onsil-treatment-lineup__link:focus-visible .onsil-treatment-lineup__img {
		opacity: .7;
		transition-duration: .5s;
	}
}

@media (prefers-reduced-motion: reduce) {
	.onsil-treatment-lineup__img {
		transition: none;
	}
}

/* Xerf and Sofwave are already art-directed on a 700×640-style tile; removing the shared
   packshot inset lets those prepared crops fill the media frame without affecting other cards. */
.onsil-treatment-lineup__link[href*="/xerf/"] .onsil-treatment-lineup__media,
.onsil-treatment-lineup__link[href*="/sofwave/"] .onsil-treatment-lineup__media {
	padding: 0;
}

.onsil-treatment-lineup__body {
	height: 280px;
	background-color: var(--c-card);
	padding: 32px 40px;
	overflow: hidden;
}

/* wave2a (audit-4/6): KR name renders FIRST, EN name second (see the PHP order-swap comment). */
.onsil-treatment-lineup__name {
	font-family: var(--f-ui), sans-serif;
	font-size: 28px;
	color: var(--c-ink);
}

.onsil-treatment-lineup__en-name {
	margin-top: 8px;
	font-family: var(--f-ui), var(--f-body), sans-serif;
	font-size: 16px;
	color: var(--c-muted);
}

.onsil-treatment-lineup__subtitle {
	margin-top: 12px;
	font-family: var(--f-ui), var(--f-body), sans-serif;
	font-size: 16px;
	line-height: 1.5;
	color: var(--c-ink);
}

.onsil-treatment-lineup__tags {
	margin: 16px 0 0;
	padding: 0;
	list-style: none;
	display: flex;
	flex-wrap: wrap;
	gap: 10px;
}

.onsil-treatment-lineup__tag {
	border: 1px solid;
	border-color: var(--c-line);
	border-radius: var(--r-pill);
	padding: 7px 20px;
	font-family: var(--f-ui), var(--f-body), sans-serif;
	font-size: 16px;
	color: var(--c-muted);
}

/* Scroll-linked rail indicator: fill position is synchronized in main.js. */
.onsil-treatment-lineup__indicator {
	display: block;
	width: 150px;
	height: 1px;
	margin: 32px auto 0;
	background-color: var(--c-line);
}

.onsil-treatment-lineup__indicator-fill {
	display: block;
	width: 50px;
	height: 1px;
	background-color: var(--c-ink);
	transform: translateX(0);
	will-change: transform;
}

@media (max-width: 768px) {
	/* band-residual review #6: base.css's [data-sec="treatment-lineup"] rule (165px/93px,
	   fix-9's own comment cites the desktop-only "Key Spacing" table figure) has no mobile
	   override at all, so it was applying full desktop padding at 375px too — Figma M node
	   617:587 (650 total): title starts at rel54 (section padding-top), cards row bottom (rel541)
	   to indicator line (rel583) is 42px, section ends 66px after the indicator (rel584→650). */
	[data-sec="treatment-lineup"] {
		padding-block: 54px 66px;
	}

	.onsil-treatment-lineup__title {
		margin-bottom: 32px;
	}

	.onsil-treatment-lineup__cards {
		width: 100%;
		gap: 20px;
	}

	/* band-residual review #6: fix-6's own comment already flagged "a genuinely 280px card ...
	   this pass has [no] spec evidence for" — raw Figma XML settles it directly: M card node
	   617:593 is 280×436 (not 300×558.7-ish), media 280×255, body 280×181. Card width drops to
	   match; body spacing below is read straight off that node's own text-box offsets. */
	.onsil-treatment-lineup__card {
		flex-basis: 280px;
		width: 280px;
		/* node 617:593 is a fixed 280×436 card regardless of per-product copy length — without a
		   cap, flex's default align-items:stretch matches every card in the row to the row's
		   tallest (whichever product has the longest subtitle), so one long subtitle inflates all
		   6 cards and the whole section. */
		height: 436px;
	}

	.onsil-treatment-lineup__link {
		grid-template-rows: 255px 181px;
	}

	.onsil-treatment-lineup__media {
		height: 255px;
		padding: 20px;
	}

	.onsil-treatment-lineup__body {
		height: 181px;
		padding: 23px 20px 30px;
		overflow: hidden;
	}

	.onsil-treatment-lineup__name {
		font-size: 22px;
		line-height: 1.3; /* was inheriting the shared 1.6 body line-height — 22×1.6=35.2 vs
		   node 617:604's own text bbox height 29 (22×1.3≈28.6) */
	}

	.onsil-treatment-lineup__en-name {
		margin-top: 0;
		line-height: 1.1; /* node 617:605: 16px text bbox height 17, not the inherited 1.6 (25.6) */
	}

	.onsil-treatment-lineup__subtitle {
		margin-top: 10px;
		font-size: 14px;
		line-height: 1.3;
		/* node 617:603 is single-line per product — with the card height now fixed at 436px, an
		   uncapped 2-line subtitle would just clip mid-glyph against `overflow:hidden` on .body */
		white-space: nowrap;
		overflow: hidden;
		text-overflow: ellipsis;
	}

	.onsil-treatment-lineup__tags {
		margin-top: 24px;
		gap: 5px;
	}

	.onsil-treatment-lineup__tag {
		padding: 8px 11px;
		font-size: 12px;
		line-height: 1.2; /* node 617:598 pill: 30px tall for 14px text bbox at 8px vertical
		   padding — the inherited 1.6 line-height was adding ~9px per pill */
	}

	.onsil-treatment-lineup__indicator {
		width: 120px;
		margin-top: 42px; /* 617:587: cards-row bottom (rel541) to the indicator line (rel583) is 42px */
	}

	.onsil-treatment-lineup__indicator-fill {
		width: 40px;
	}
}

/* ── gallery-grid — space.md §5: 2×2 grid (col-gap 80, row-gap 71), image 680×440, title = EN
   Libertinus 24px + KR 16px inline. No section post — called directly with `$args['zone']`. ── */

.onsil-gallery-grid__grid {
	list-style: none;
	margin: 0;
	padding: 0;
	display: grid;
	grid-template-columns: 1fr 1fr;
	column-gap: 80px;
	row-gap: 71px;
}

.onsil-gallery-grid__media {
	background-color: var(--c-card);
	aspect-ratio: 680 / 440;
	overflow: hidden;
}

.onsil-gallery-grid__media img {
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.onsil-gallery-grid__body {
	margin-top: 16px;
}

.onsil-gallery-grid__title {
	display: flex;
	align-items: baseline;
	gap: 8px;
	font-family: var(--f-display), serif;
}

.onsil-gallery-grid__title-en {
	font-size: 24px;
	letter-spacing: .04em;
	color: var(--c-ink);
}

.onsil-gallery-grid__title-kr {
	font-family: var(--f-ui), var(--f-body), sans-serif;
	font-size: 16px;
	color: var(--c-ink);
}

.onsil-gallery-grid__desc {
	margin-top: 8px;
	font-family: var(--f-ui), var(--f-body), sans-serif;
	font-size: 16px;
	line-height: 1.6;
	letter-spacing: -.02em;
	color: var(--c-body);
}

@media (max-width: 768px) {
	.onsil-gallery-grid__grid {
		grid-template-columns: 1fr;
		row-gap: 32px;
	}

	.onsil-gallery-grid__body {
		margin-top: 12px;
	}
}

/* ── contact-info — home.md §13, contact.md §2: map placeholder (700×700) left, info right.
   Same partial on Home and the Contact page — always reads the Contact page's own fields. ── */

/* fix-7 (audit MEDIUM #7): this flex row IS the spec's "Panel" element (contact.md §2: Panel
   padding-top 90 / padding-bottom 96) — base.css's [data-sec="contact-info"] only ever carried
   the outer section's own 20px top, so the panel's own 90px never rendered. */
.onsil-contact-info__grid {
	display: flex;
	flex-wrap: wrap;
	gap: 48px 64px;
	padding-block: 90px 96px;
}

.onsil-contact-info__map {
	position: relative;
	flex: 1 1 342px;
	min-width: 342px;
	aspect-ratio: 1 / 1;
	max-height: 700px;
	/* fix-13 (audit MEDIUM #13): contact.md §2 gives the map placeholder its own `#e2e0db` —
	   close to but distinct from --c-card (#e9e7e1), so it can't reuse that token. */
	background-color: #e2e0db;
}

.onsil-contact-info__map iframe {
	display: block;
	width: 100%;
	height: 100%;
	border: 0;
	opacity: 0;
	pointer-events: none;
}

.onsil-contact-info__map.is-loaded iframe {
	opacity: 1;
	pointer-events: auto;
}

.onsil-contact-info__map-facade {
	position: absolute;
	inset: 0;
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: 14px;
	width: 100%;
	height: 100%;
	padding: 32px;
	background-color: #e2e0db;
	color: var(--c-ink);
	text-align: center;
	text-decoration: none;
	cursor: pointer;
	transition: opacity 200ms ease, visibility 200ms ease;
}

.onsil-contact-info__map.is-loaded .onsil-contact-info__map-facade {
	opacity: 0;
	visibility: hidden;
	pointer-events: none;
}

.onsil-contact-info__map-pin {
	position: relative;
	width: 34px;
	height: 42px;
	border-width: 1px;
	border-style: solid;
	border-color: var(--c-accent);
	border-radius: 50% 50% 50% 0;
	transform: rotate(-45deg);
}

.onsil-contact-info__map-pin::after {
	content: "";
	position: absolute;
	top: 11px;
	left: 11px;
	width: 10px;
	height: 10px;
	border-width: 1px;
	border-style: solid;
	border-color: var(--c-accent);
	border-radius: 50%;
}

.onsil-contact-info__map-address {
	max-width: 320px;
	font-family: var(--f-ui), var(--f-body), sans-serif;
	font-size: 15px;
	line-height: 1.6;
}

.onsil-contact-info__map-action {
	font-family: var(--f-ui), var(--f-body), sans-serif;
	font-size: 13px;
	color: var(--c-accent);
	text-decoration: underline;
	text-underline-offset: 4px;
}

.onsil-contact-info__map-facade:focus-visible {
	outline: 2px solid var(--c-accent);
	outline-offset: -6px;
}

@media (hover: hover) {
	.onsil-contact-info__map-facade:hover .onsil-contact-info__map-action {
		text-decoration-thickness: 2px;
	}
}

@media (prefers-reduced-motion: reduce) {
	.onsil-contact-info__map-facade {
		transition: none;
	}
}

.onsil-contact-info__body {
	flex: 1 1 342px;
	min-width: 342px;
}

.onsil-contact-info__address {
	margin-top: 24px;
	font-family: var(--f-ui), var(--f-body), sans-serif;
	font-size: 18px;
	line-height: 1.5;
	color: var(--c-ink);
}

.onsil-contact-info__parking {
	margin-top: 12px;
	font-family: var(--f-ui), var(--f-body), sans-serif;
	font-size: 16px;
	color: var(--c-muted);
}

.onsil-contact-info__pills {
	list-style: none;
	margin: 20px 0 0;
	padding: 0;
	display: flex;
	flex-wrap: wrap;
	gap: 12px;
}

/* wave2a (audit-1/2): pills are Pretendard, not the inherited Noto Sans KR body font. */
.onsil-pill--ghost {
	background-color: var(--c-surface);
	color: var(--c-ink);
	border: 1px solid;
	border-color: var(--c-line);
	border-radius: 0;
	padding: 12px 24px;
	font-family: var(--f-ui), sans-serif;
	font-size: 14px;
	line-height: normal;
}

@media (hover: hover) {
	.onsil-pill--ghost:hover {
		background-color: var(--c-card);
		opacity: 1;
	}
}

/* wave2a (audit-1/2): Figma has no hairline between the tel/hours rows — drop the two extra
   `border-top`s and keep the rows separated by padding alone. */
.onsil-contact-info__row {
	display: flex;
	align-items: flex-start;
	gap: 24px;
	padding-block: 30px;
}

.onsil-contact-info__label {
	flex: 0 0 120px;
	font-family: var(--f-ui), var(--f-body), sans-serif;
	font-size: 16px;
	color: var(--c-accent);
}

.onsil-contact-info__phone {
	font-family: var(--f-display), serif;
	font-size: 30px;
	color: var(--c-ink);
}

/* wave2a (audit-1/2): a fixed-width day column + `white-space:pre-wrap` on both spans reproduces
   the node's aligned "월    화     AM 10:00 - PM 19:00" columns (see the PHP comment). */
.onsil-contact-info__hours-row {
	display: flex;
	gap: 16px;
	font-family: var(--f-ui), var(--f-body), sans-serif;
	font-size: 16px;
	line-height: 1.7;
	color: var(--c-ink);
}

.onsil-contact-info__hours-day {
	flex: 0 0 60px;
	white-space: pre-wrap;
}

.onsil-contact-info__hours-time {
	white-space: pre-wrap;
}

.onsil-contact-info__notice {
	margin-top: 16px;
}

.onsil-contact-info__notice p {
	font-family: var(--f-ui), var(--f-body), sans-serif;
	font-size: 14px;
	line-height: 1.6;
	color: var(--c-muted);
}

.onsil-contact-info__notice p:first-child {
	font-weight: 600;
}

@media (max-width: 768px) {
	.onsil-contact-info__grid {
		gap: 32px;
		padding-block: 90px 96px; /* fix-7: no separate M value in contact.md — reuses the PC panel figure */
	}

	/* Task 14: the desktop min-width:342px floor (flex:1 1 342px) doesn't fit a 375px
	   viewport minus the .onsil-wrap 24px+24px padding (327px available) — it forced a
	   6-15px horizontal overflow on every route that renders contact-info (home, /contact/).
	   min-width:0 lets flex-shrink do its job; the flex-basis still targets 342px on any
	   row wide enough to give it. */
	.onsil-contact-info__map,
	.onsil-contact-info__body {
		min-width: 0;
	}

	/* wave2a (audit-2): map is square on mobile too (340×340 in the node) — the old 300px cap
	   broke the 1:1 aspect-ratio. Order moves it after the info column (Figma: intro → info →
	   map at the bottom), and rows stay horizontal (label + value) instead of stacking. */
	.onsil-contact-info__map {
		order: 2;
	}

	.onsil-contact-info__body {
		order: 1;
	}

	.onsil-contact-info__pills {
		flex-wrap: nowrap;
		overflow-x: auto;
		scroll-snap-type: x proximity;
		scrollbar-width: none;
		overscroll-behavior-inline: contain;
	}

	.onsil-contact-info__pills::-webkit-scrollbar {
		display: none;
	}

	.onsil-contact-info__pills li {
		flex: 0 0 auto;
		scroll-snap-align: start;
	}

	.onsil-contact-info__row {
		align-items: center;
		gap: 10px;
		padding-block: 20px;
	}

	.onsil-contact-info__label {
		flex-basis: 100px;
	}
}

/* ── wave2a (item 10) — section padding overrides base.css's blanket .onsil-section 100/64.
   base.css already carries [data-sec] overrides for the sections whose audits gave one clean
   number; gallery-grid/faq/panel-list didn't ("no single number fit" — the measured node-to-node
   gaps are the SUM of one section's bottom padding and the next section's top padding, and the
   audits only measured the combined gap). These three follow the same "top absorbed by the
   preceding section, keep a measured bottom" convention as base.css's existing overrides, using
   the closest single gap each audit did report (space.md: image-wide→gallery ≈50 combined,
   gallery→faq ≈50, faq→cta-band ≈10) — an approximation, not a re-derivation of the exact split;
   flagged in the wave2a report. page.css loads after base.css, so these win regardless of order.
   This rule is genuinely space-only now (Space's `gallery-grid`/`faq` are self-consistent — see
   the override block below): `faq` used to apply the same "0 10px" figure to every page that has
   an accordion, and `panel-list` the same "0 48px" to every reason-band/bullet-list page — both
   measured on /space/ only. band-residual review #3 confirmed the identical -196px panel-list
   desktop delta on 3 unrelated pages and 200+px faq deltas on 4 more, proving those two were a
   selector bug, not content. Scoped per-page replacements are below. */
[data-sec="gallery-grid"] {
	padding-block: 0 48px;
}

[data-sec="faq"] {
	padding-block: 0 10px;
}

/* /space/: keep the gallery and FAQ as distinct groups without changing category FAQs. */
.onsil-gallery-grid + .onsil-faq {
	padding-top: 80px;
	padding-bottom: 32px;
}

body.onsil-page-space [data-sec="image-wide"] {
	padding-bottom: 96px;
}

[data-sec="panel-list"] {
	padding-block: 0 48px;
}

/* band-residual review #3 — faq/panel-list, scoped per page (page-id-N is WP's own stable
   per-post body class, so this needs no PHP change). Figures are direct offsets read from
   `design/v5/figma-page-178-2.xml`: each page's FAQ/reason-band frame top-padding (title's own y
   minus the frame's y) and bottom-padding (frame bottom minus the last content block's bottom).
   page-id-234=lift-contour, 235=body, 236=skin-glow, 237=collagen-restore (cat-*.md section
   tables / `wp_list_pages`-style constant IDs, confirmed via computed body class on each route). */
body.page-id-234 [data-sec="faq"] { padding-block: 100px 135px; } /* 532:855: title rel100, list bottom rel785 of 920 */
body.page-id-235 [data-sec="faq"] { padding-block: 100px 119px; } /* 570:2224: title rel100, list bottom rel811 of 930 */
body.page-id-236 [data-sec="faq"] { padding-block: 100px 145px; } /* 575:3116: title rel100, list bottom rel785 of 930 */
body.page-id-237 [data-sec="faq"] { padding-block: 100px 119px; } /* 575:3570: title rel100, list bottom rel811 of 930 */

body.page-id-234 [data-sec="panel-list"],
body.page-id-235 [data-sec="panel-list"],
body.page-id-236 [data-sec="panel-list"] { padding-block: 93px 156px; } /* 532:820/570:2188/575:3086: identical geometry — title rel93, panel(400px) bottom rel574 of 730 on all three */

@media (max-width: 768px) {
	[data-sec="gallery-grid"] {
		padding-bottom: 32px;
	}

	.onsil-gallery-grid + .onsil-faq {
		padding-top: 48px;
		padding-bottom: 24px;
	}

	body.onsil-page-space [data-sec="image-wide"] {
		padding-bottom: 64px;
	}

	body.page-id-234 [data-sec="faq"] { padding-block: 50px 44px; } /* 570:1892: title rel50, list bottom rel746 of 790 */
	body.page-id-235 [data-sec="faq"] { padding-block: 50px 44px; } /* 614:1101: title rel50, list bottom rel766 of 810 */
	body.page-id-236 [data-sec="faq"] { padding-block: 50px 44px; } /* 614:1422: title rel50, list bottom rel766 of 810 */
	body.page-id-237 [data-sec="faq"] { padding-block: 50px 70px; } /* 628:2604: title rel50, list bottom rel796 of 866 */

	body.page-id-234 [data-sec="panel-list"],
	body.page-id-236 [data-sec="panel-list"] { padding-block: 44px 50px; } /* 570:1854/614:1671: title rel44, panel(830px, 7 reasons) bottom rel930 of 980 */
	body.page-id-235 [data-sec="panel-list"] { padding-block: 44px 80px; } /* 614:1014: body's reason-band has only 4 reasons at M (480px panel vs the 830px 7-reason panel on lift/skin-glow) — bottom rel580 of 660, NOT the same target */

	/* skin-glow renders its real 7 bullet items (unlike lift-contour, which shows only 4 at
	   mobile — a content gap, not fixable here, already left as GENUINE CONTENT RESIDUAL) but the
	   300px safety floor (`.onsil-panel-list__panel--photo`, shared rule above) still undersizes
	   it well below the 830px band both 7-item pages target — this is the one panel-list.mobile
	   instance the review flagged as a real FAIL rather than content-driven. */
	body.page-id-236 .onsil-panel-list__panel--photo {
		min-height: 830px;
	}
}
