/**
 * Dental Clinic Abroad — rules theme.json cannot express.
 *
 * Design tokens all live in theme.json and arrive here as --wp--preset--*
 * custom properties. Nothing in this file hard-codes a colour or a size that
 * theme.json already owns, so re-skinning the site stays a theme.json edit.
 */

/* ---------------------------------------------------------------------------
 * 0. Gutters the theme owns
 *
 * On the live host, WordPress grants root gutters only to containers sitting
 * directly under the page root: nested full-bleed sections carry the
 * .has-global-padding class, the padding variables resolve on them, and yet
 * no padding rule matches — measured at 0px on the cover's inner container
 * while the top-level <main> got its 36px. Rather than chase which core rule
 * scopes to direct children in this WP build, the theme declares the gutter
 * itself. Same value core would use, so where core does apply it the two
 * agree, and where core forgets, ours holds.
 * ------------------------------------------------------------------------ */

.has-global-padding {
	padding-inline:
		var(--wp--style--root--padding-left, var(--wp--preset--spacing--40))
		var(--wp--style--root--padding-right, var(--wp--preset--spacing--40));
}

/* ---------------------------------------------------------------------------
 * 0b. Tables — the price comparison's styling, previously preview-only
 *
 * The polished table look lived in the static preview's base.css, which never
 * shipped with the theme, so the live table fell back to core defaults.
 * Ported here: quiet borders, zebra striping on White over Mist, numeric
 * columns right-aligned in tabular figures so the euro amounts stack.
 * ------------------------------------------------------------------------ */

.wp-block-table table {
	width: 100%;
	border-collapse: collapse;
	font-size: var(--wp--preset--font-size--medium);
}

.wp-block-table th,
.wp-block-table td {
	text-align: left;
	padding: 1rem 1.25rem;
	border-bottom: 1px solid var(--wp--preset--color--border);
}

.wp-block-table th {
	font-weight: 600;
	font-size: var(--wp--preset--font-size--small);
	letter-spacing: 0.04em;
}

.wp-block-table.is-style-stripes tbody tr:nth-child(odd),
.wp-block-table tbody tr:nth-child(odd) {
	background-color: rgba(255, 255, 255, 0.6);
}

.wp-block-table.is-style-stripes tbody tr:nth-child(even) {
	background-color: transparent;
}

.wp-block-table td:not(:first-child),
.wp-block-table th:not(:first-child) {
	text-align: right;
	font-variant-numeric: tabular-nums;
}

.wp-block-table figcaption {
	margin-top: var(--wp--preset--spacing--30);
	color: var(--wp--preset--color--muted);
	font-size: var(--wp--preset--font-size--small);
	text-align: left;
}

/* ---------------------------------------------------------------------------
 * 1. The signature headline: sans roman + serif italic
 *
 * Editors italicise a word in any heading and the block editor emits <em>.
 * That is the whole mechanism — no shortcode, no custom block, and the
 * markup stays meaningful if the theme is ever swapped out.
 * ------------------------------------------------------------------------ */

h1 em,
h2 em,
h3 em,
h4 em,
.wp-block-post-title em,
.wp-block-site-title em,
.dca-display em {
	font-family: var(--wp--preset--font-family--display);
	font-style: italic;
	font-weight: 400;
	/* Instrument Serif runs smaller on the body than Inter at the same px. */
	font-size: 1.06em;
	/* Positive, not negative. Headings carry -0.025em, and letter-spacing
	   inherits — so an italic set tight was being squeezed twice, on a face
	   whose sidebearings are already narrower than Inter's. This overrides the
	   heading's tracking rather than adding to it. */
	letter-spacing: 0.012em;
	word-spacing: 0.06em;
	/* Italic leans right, so its last letter runs into whatever follows. */
	margin-inline-end: 0.06em;
}

/* ---------------------------------------------------------------------------
 * 2. Small utilities used by the patterns
 * ------------------------------------------------------------------------ */

.dca-eyebrow {
	font-size: var(--wp--preset--font-size--eyebrow);
	letter-spacing: 0.14em;
	text-transform: uppercase;
	color: var(--wp--preset--color--muted);
	margin: 0;
}

/* Text link with a trailing arrow that nudges on hover. */
.dca-link-arrow {
	display: inline-flex;
	align-items: center;
	gap: 0.5em;
	text-decoration: none;
	border-bottom: 1px solid currentColor;
	padding-bottom: 2px;
}

/* The label inside is a link. Without this it takes the global Adriatic link
   colour, which disappears on the dark sections these arrows mostly sit on —
   the static preview carried color:inherit inline, the patterns never did. */
.dca-link-arrow a {
	color: inherit;
	text-decoration: none;
}

.dca-link-arrow::after {
	content: "↗";
	transition: transform var(--wp--custom--transition--base);
}

.dca-link-arrow:hover::after {
	transform: translate(2px, -2px);
}

/* Any section placed on Midnight Ink flips its own text colours. */
.dca-on-dark,
.dca-on-dark h1,
.dca-on-dark h2,
.dca-on-dark h3,
.dca-on-dark h4 {
	color: var(--wp--preset--color--porcelain);
}

.dca-on-dark .dca-eyebrow,
.dca-on-dark .has-muted-color {
	color: var(--wp--preset--color--muted-invert);
}

.dca-on-dark .wp-element-button,
.dca-on-dark .wp-block-button__link {
	background-color: var(--wp--preset--color--porcelain);
	color: var(--wp--preset--color--midnight);
}

.dca-on-dark .wp-element-button:hover,
.dca-on-dark .wp-block-button__link:hover {
	background-color: var(--wp--preset--color--sea-glass);
	color: var(--wp--preset--color--midnight);
}

/* ---------------------------------------------------------------------------
 * 3. Header
 *
 * Three-column grid — links left, wordmark dead centre, actions right — so the
 * wordmark stays optically centred no matter how wide the nav gets.
 * ------------------------------------------------------------------------ */

.dca-header {
	display: grid;
	grid-template-columns: 1fr auto 1fr;
	align-items: center;
	gap: var(--wp--preset--spacing--30);
	width: 100%;
}

.dca-header__start {
	justify-self: start;
}

.dca-header__center {
	justify-self: center;
}

.dca-header__end {
	display: flex;
	align-items: center;
	gap: var(--wp--preset--spacing--30);
	justify-self: end;
}

/* The overlay header's template-part wrapper stays in the DOM at zero height,
   so the site-blocks gap rule still hands the next sibling — main — a top
   margin, painting a Porcelain strip above the hero. When the header floats,
   whatever follows starts at the very top. */
.wp-block-template-part:has(.dca-header--overlay) + * {
	margin-block-start: 0;
}

/* Over the hero the header floats on the image and inverts. */
.dca-header--overlay {
	position: absolute;
	inset-block-start: 0;
	inset-inline: 0;
	z-index: 10;
}

.dca-header--overlay,
.dca-header--overlay a {
	color: var(--wp--preset--color--porcelain);
}

/* Once the hero scrolls away the overlay header needs its own ground. */
.dca-header--overlay.is-pinned {
	position: fixed;
	background-color: var(--wp--preset--color--porcelain);
	box-shadow: var(--wp--preset--shadow--card);
}

.dca-header--overlay.is-pinned,
.dca-header--overlay.is-pinned a {
	color: var(--wp--preset--color--midnight);
}

@media (max-width: 781px) {
	.dca-header {
		grid-template-columns: auto 1fr auto;
	}

	.dca-header__start {
		order: 2;
	}

	.dca-header__center {
		order: 1;
		justify-self: start;
	}

	/* The navigation collapses to an overlay menu at this width and carries its
	   own booking link, so a second one in the bar just crowds the wordmark. */
	.dca-header__cta {
		display: none;
	}
}

/* ---------------------------------------------------------------------------
 * 4. Hero
 * ------------------------------------------------------------------------ */

/* Built on core/cover, so the client can swap the photograph from the editor
   without touching markup. Everything below only adjusts what cover leaves open. */
.dca-hero.wp-block-cover {
	min-height: min(92svh, 900px);
	align-items: flex-end;
	padding: 0;
	background:
		radial-gradient(circle at 76% 20%, rgba(117, 184, 178, 0.34), transparent 30%),
		linear-gradient(135deg, #1f5f7a 0%, #173d5a 48%, #12243a 100%);
}

.dca-hero .wp-block-cover__inner-container {
	width: 100%;
}

/* Cover's flat dim is uniform; the headline sits bottom-left and needs the
   gradient weighted there instead. */
.dca-hero .wp-block-cover__background {
	background-image:
		linear-gradient(90deg, rgba(18, 36, 58, 0.48) 0%, rgba(18, 36, 58, 0.12) 52%, rgba(18, 36, 58, 0) 82%),
		linear-gradient(to top, rgba(18, 36, 58, 0.48) 0%, rgba(18, 36, 58, 0) 58%);
	opacity: 1;
}

.dca-hero__inner {
	position: relative;
	z-index: 1;
	width: 100%;
	display: grid;
	grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.1fr);
	align-items: end;
	column-gap: var(--wp--preset--spacing--50);
	row-gap: var(--wp--preset--spacing--30);
	padding-block: var(--wp--preset--spacing--60);
}

.dca-hero__title {
	margin: 0;
	color: var(--wp--preset--color--porcelain);
	text-wrap: balance;
}

.dca-hero__aside {
	grid-column: 1;
	color: var(--wp--preset--color--mist);
	max-width: 34ch;
	justify-self: start;
	text-align: left;
}

.dca-hero__actions {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--wp--preset--spacing--40);
	margin-block-start: var(--wp--preset--spacing--40);
}

/* --- Cutout variant --------------------------------------------------------
 *
 * .dca-hero--cutout expects a subject cut out on a transparent background. The
 * subject stands ON the gradient instead of filling the frame, so the hero has
 * depth without needing a photographed backdrop.
 *
 * The trick is to size by height and let the width follow, rather than reaching
 * for object-fit. A cutout PNG carries a wide band of transparent pixels beside
 * the subject; object-fit measures that band as part of the image and shrinks
 * the subject to fit it, which is why "contain" leaves the figure stranded and
 * small. Sizing by height ignores the band entirely — it simply overflows the
 * frame, and being transparent, nothing shows.
 * ------------------------------------------------------------------------ */

.dca-hero--cutout .wp-block-cover__image-background {
	inset: auto 0 0 auto;
	width: auto;
	max-width: none;
	height: 100%;
	/* Above the scrim: the gradient darkens the headline's side of the frame,
	   and must not wash over the subject on the way. */
	z-index: 2;
	object-fit: fill;
}

/* Text sits above both the scrim and the subject. */
.dca-hero--cutout .wp-block-cover__inner-container {
	z-index: 3;
}

/* The subject occupies the right of the frame, so the scrim only has to lift
   the left. A full-width dim would grey her out for no benefit. */
.dca-hero--cutout .wp-block-cover__background {
	background-image:
		linear-gradient(90deg, rgba(18, 36, 58, 0.62) 0%, rgba(18, 36, 58, 0.28) 45%, rgba(18, 36, 58, 0) 72%),
		linear-gradient(to top, rgba(18, 36, 58, 0.55) 0%, rgba(18, 36, 58, 0) 55%);
}

@media (max-width: 781px) {
	.dca-hero__inner {
		grid-template-columns: 1fr;
		align-items: start;
	}

	.dca-hero__aside {
		justify-self: start;
		text-align: left;
	}

	/* At full height the subject is wider than a phone screen, so she scales down
	   and the layout goes vertical: headline on top, subject beneath.

	   Keeping the two apart cannot depend on a fixed hero height, because how far
	   the text runs depends on how long the copy is — a headline that wraps to a
	   third line would push it straight onto her.

	   So the hero is left to grow with its content, and both the reserved band
	   and the subject are expressed in the same unit. The subject is 44svh tall
	   and the text reserves 48svh beneath itself, which puts the gap at 4svh no
	   matter how long the copy gets. */
	.dca-hero--cutout.wp-block-cover {
		align-items: flex-start;
		min-height: 100svh;
		height: auto;
	}

	.dca-hero--cutout .wp-block-cover__image-background {
		height: 44svh;
	}

	.dca-hero--cutout .dca-hero__inner {
		/* Clear the header, which floats over the hero and reserves no space. */
		padding-block-start: 6rem;
		padding-block-end: 48svh;
	}
}

/* ---------------------------------------------------------------------------
 * 4b. Philosophy — small photographs tucked around a large centred statement
 *
 * The images are taken out of flow so they can sit against the headline the way
 * the reference does. Floats or grid cells would reserve space and open a gap
 * in the middle of the section instead.
 * ------------------------------------------------------------------------ */

.dca-philosophy {
	position: relative;
	text-align: center;
	/* Guarantees the flanking photographs have somewhere to sit. They are out of
	   flow, so without this the section would collapse to the height of the text
	   and let them spill into the treatment list below. */
	min-height: clamp(420px, 44vw, 620px);
}

/* Narrower than it looks like it needs to be. The statement has to clear the
   photographs on both sides, and at this size they take real width. */
.dca-philosophy__statement {
	max-width: 17ch;
	margin-inline: auto;
}

.dca-philosophy__lede {
	max-width: 42ch;
	margin-inline: auto;
}

.dca-philosophy__art {
	position: absolute;
	border-radius: var(--wp--custom--radius--image);
	margin: 0;
	pointer-events: none;
}

/* The class lands on the <figure>; the crop has to reach the <img>. */
.dca-philosophy__art img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
	border-radius: inherit;
}

/* Each aspect ratio matches the photograph placed in it, so nothing is cropped
   against its own composition: a portrait operatory on the left, the square
   handpiece detail on the right, the wide chairside scan closing the section. */
.dca-philosophy__art--start {
	inset-block-start: 0;
	inset-inline-start: 0;
	width: clamp(150px, 20vw, 290px);
	aspect-ratio: 2 / 3;
}

.dca-philosophy__art--end {
	inset-block-start: 38%;
	inset-inline-end: 0;
	width: clamp(130px, 16vw, 240px);
	aspect-ratio: 1;
}

/* The third stays in flow, closing the section rather than floating.
   Relative rather than static so it can carry the panel below. */
.dca-philosophy__art--center {
	position: relative;
	/* Contains the panel's negative z-index. Without a stacking context here it
	   would slide behind the section's Porcelain background and disappear. */
	isolation: isolate;
	width: clamp(260px, 42vw, 580px);
	aspect-ratio: 3 / 2;
	margin-block-start: var(--wp--preset--spacing--50);
	margin-inline: auto;
}

/* A Sea Glass panel the same shape as the photograph, offset down and to the
   left so the two read as one layered object rather than a stray rectangle. It
   fills the empty corner between the left portrait and the wide image, which
   was the slackest part of the composition, and it is the only place the
   accent colour appears in an otherwise Porcelain-and-Midnight section.

   Only an L-shaped sliver of it is ever visible, down the left edge and along
   the bottom. The mask anchors the colour at the corner where those two strips
   meet and dissolves it as they run away from it, so the panel reads as a
   shadow of the photograph rather than a slab parked behind it.

   The fade is a mask rather than a gradient to transparent: gradients
   interpolate through transparent black, which would drag a grey cast through
   the middle of the fade. A mask works on alpha alone, so the colour stays a
   single token and stays clean the whole way out. */
.dca-philosophy__art--center::before {
	content: "";
	position: absolute;
	inset: 0;
	z-index: -1;
	translate: clamp(-32px, -2.4vw, -16px) clamp(16px, 2.4vw, 32px);
	background-color: var(--wp--preset--color--mist);
	border-radius: inherit;
	/* Reaches further than it would with a stronger colour. Mist sits at 1.14:1
	   against Porcelain, so a fade tuned for Sea Glass leaves nothing visible at
	   all — the falloff holds most of its opacity and only lets go near the end. */
	-webkit-mask-image: linear-gradient(to top right, #000 0%, rgba(0, 0, 0, 0.72) 46%, transparent 88%);
	mask-image: linear-gradient(to top right, #000 0%, rgba(0, 0, 0, 0.72) 46%, transparent 88%);
}

/* Below the breakpoint the statement takes the full width, so there is no
   margin left for the flanking pair to sit in. The wide one carries the
   section on its own. */
@media (max-width: 781px) {
	.dca-philosophy {
		min-height: 0;
	}

	.dca-philosophy__art--start,
	.dca-philosophy__art--end {
		display: none;
	}

	.dca-philosophy__art--center {
		width: 100%;
	}
}

/* ---------------------------------------------------------------------------
 * 5. Treatment list — rows that fill on hover
 *
 * The hover state is a fill that wipes in from the left, with the labels at
 * either end resolving as it passes. Nothing is revealed that was not already
 * on the row, so the list keeps a steady rhythm and never reflows.
 * ------------------------------------------------------------------------ */

.dca-treatments {
	position: relative;
	border-block-start: 1px solid rgba(220, 233, 235, 0.18);
}

.dca-treatments__row {
	position: relative;
	/* Contains the fill's negative z-index so it cannot slide behind the
	   section background and disappear. */
	isolation: isolate;
	display: grid;
	grid-template-columns: 10rem 1fr 10rem;
	align-items: center;
	gap: var(--wp--preset--spacing--30);
	padding-block: clamp(1.5rem, 4vw, 2.75rem);
	border-block-end: 1px solid rgba(220, 233, 235, 0.18);
	text-decoration: none;
	transition: color var(--wp--custom--transition--base);
}

/* The fill wipes in from the left rather than cross-fading.
 *
 * A directional sweep reads as the row responding to the pointer arriving; a
 * background-colour transition reads as the page repainting underneath you.
 * It is also the cheaper of the two — transform and opacity are the only
 * properties the compositor can animate without re-running layout or paint. */
.dca-treatments__row::before {
	content: "";
	position: absolute;
	inset-block: 0;
	/* Overhang the text slightly so the fill does not crop tight to the labels. */
	inset-inline: calc(-1 * var(--wp--preset--spacing--30));
	z-index: -1;
	background-color: var(--wp--preset--color--porcelain);
	transform: scaleX(0);
	transform-origin: left center;
	transition: transform var(--wp--custom--transition--base);
}

.dca-treatments__row:hover::before,
.dca-treatments__row:focus-within::before {
	transform: scaleX(1);
}

/* Stretched link: the title anchor covers the whole row, so the entire row is
   clickable while the accessible name stays just the treatment name. No JS,
   and no nesting block-level content inside an <a>. */
.dca-treatments__row .wp-block-post-title a::after,
.dca-treatments__row .dca-treatments__name a::after {
	content: "";
	position: absolute;
	inset: 0;
}

.dca-treatments__row:hover,
.dca-treatments__row:focus-within {
	color: var(--wp--preset--color--midnight);
}

/* The category label is held back until hover, so the eye reads a clean column
   of treatment names first and picks up the grouping second. */
.dca-treatments__cat {
	font-size: var(--wp--preset--font-size--eyebrow);
	letter-spacing: 0.14em;
	text-transform: uppercase;
	opacity: 0.45;
	transition: opacity var(--wp--custom--transition--base);
}

/* On the live site the category is a Query Loop post-terms block, so the label
   is a link. The global Adriatic link colour is near-invisible on Midnight —
   inherit the row's colour instead, exactly as the static label did. */
.dca-treatments__cat a {
	color: inherit;
	text-decoration: none;
}

.dca-treatments__row:hover .dca-treatments__cat,
.dca-treatments__row:focus-within .dca-treatments__cat {
	opacity: 1;
}

.dca-treatments__name {
	margin: 0;
	font-size: var(--wp--preset--font-size--xx-large);
	text-align: center;
	transition:
		color var(--wp--custom--transition--base),
		letter-spacing var(--wp--custom--transition--base);
}

/* The colour has to be restated here, not left to inherit from the row.
   .dca-on-dark sets a colour on h1–h4 directly, so the heading never inherits
   the row's hover colour — which left Porcelain text sitting on the Porcelain
   fill, invisible.

   The tracking change is a hair of extra tightening as the fill lands: enough
   to feel like the name settles into the lit row, not enough to shift layout. */
.dca-treatments__row:hover .dca-treatments__name,
.dca-treatments__row:focus-within .dca-treatments__name,
.dca-treatments__row:hover .dca-treatments__name a,
.dca-treatments__row:focus-within .dca-treatments__name a {
	color: var(--wp--preset--color--midnight);
	letter-spacing: -0.012em;
}

.dca-treatments__name a {
	color: inherit;
	text-decoration: none;
}

/* Enters from the left so it travels with the fill rather than against it.
 *
 * Sits above the stretched link that covers the row. Without the stacking
 * context the row's own overlay would swallow the click and send the visitor
 * to the treatment page instead of the quote form. */
.dca-treatments__more {
	justify-self: end;
	position: relative;
	z-index: 1;
	margin: 0;
	white-space: nowrap;
	opacity: 0;
	transform: translateX(-12px);
	transition:
		opacity var(--wp--custom--transition--base),
		transform var(--wp--custom--transition--base);
}

.dca-treatments__more a {
	display: inline-block;
	background-color: var(--wp--preset--color--adriatic);
	color: var(--wp--preset--color--porcelain);
	border-radius: var(--wp--custom--radius--pill);
	padding: 0.7rem 1.4rem;
	font-size: var(--wp--preset--font-size--small);
	font-weight: 500;
	line-height: 1;
	text-decoration: none;
	transition: background-color var(--wp--custom--transition--base);
}

.dca-treatments__more a:hover,
.dca-treatments__more a:focus-visible {
	background-color: var(--wp--preset--color--midnight);
	color: var(--wp--preset--color--porcelain);
}

.dca-treatments__row:hover .dca-treatments__more,
.dca-treatments__row:focus-within .dca-treatments__more {
	opacity: 1;
	transform: translateX(0);
}

@media (max-width: 781px) {
	.dca-treatments__row {
		grid-template-columns: 1fr;
		gap: 0.35rem;
		text-align: start;
	}

	.dca-treatments__name {
		text-align: start;
	}

	.dca-treatments__cat {
		opacity: 1;
	}

	/* The quote link stays — it is the point of the row — but a filled pill on
	   every row stacks into a wall of colour. Quiet it to a text link. */
	.dca-treatments__more {
		justify-self: start;
		opacity: 1;
		transform: none;
		margin-block-start: 0.35rem;
	}

	.dca-treatments__more a {
		background-color: transparent;
		color: var(--wp--preset--color--sea-glass);
		padding: 0;
		border-block-end: 1px solid currentColor;
		border-radius: 0;
	}

	.dca-treatments__more a:hover,
	.dca-treatments__more a:focus-visible {
		background-color: transparent;
		color: var(--wp--preset--color--porcelain);
	}

	/* Sea Glass reads well on the Midnight section (6.9:1) but collapses to
	   2.1:1 once the Porcelain fill lands under it, which a tap triggers.
	   Adriatic Blue holds at 6.5:1 on that fill. */
	.dca-treatments__row:hover .dca-treatments__more a,
	.dca-treatments__row:focus-within .dca-treatments__more a {
		color: var(--wp--preset--color--adriatic);
	}
}

/* Touch devices never truly hover, so the row would otherwise sit in its
   unresolved state forever — the category dim and the quote link hidden.
   Both are forced visible instead.

   The fill is deliberately left switched on. Tapping a row on a touch screen
   fires a sticky :hover in most mobile browsers, and the hover state also
   darkens the text; disabling only the fill left Midnight text on the Midnight
   section with nothing lit behind it, so a tapped row went blank. Fill and
   text colour have to change together or not at all. */
@media (hover: none) {
	.dca-treatments__cat {
		opacity: 1;
	}

	.dca-treatments__more {
		opacity: 1;
		transform: none;
	}
}

/* ---------------------------------------------------------------------------
 * 6. Before / after comparison
 *
 * Driven by a range input so it is keyboard-operable and works without JS
 * beyond writing one custom property.
 * ------------------------------------------------------------------------ */

/* --- Gallery framing -------------------------------------------------------
 *
 * The comparison sits in a raised centre card with other cases falling away on
 * either side, faded and blurred. The flankers are decoration, not content:
 * they carry no caption and are hidden from assistive tech, so the section
 * still reads as one case rather than five.
 *
 * They run off both edges on purpose. A row that stops neatly inside the
 * container reads as a finished set of five; one that is cut off reads as a
 * deeper library you are seeing part of.
 * ------------------------------------------------------------------------ */

.dca-gallery {
	display: flex;
	align-items: stretch;
	justify-content: center;
	gap: clamp(8px, 1.2vw, 20px);
	/* Full-bleed so the outer cards are clipped by the viewport, not by a
	   container edge that would draw a visible boundary. */
	width: 100vw;
	max-width: 100vw;
	margin-inline: calc(50% - 50vw);
	padding-inline: clamp(8px, 1.2vw, 20px);
	overflow: clip;
}

.dca-gallery__aside {
	flex: 0 0 auto;
	/* Ceiling is not arbitrary. These inner cards are the split pair, and how
	   much of the photograph a card shows is its own aspect over the image's —
	   so the wider they get, the more the two halves overlap. Past roughly 360px
	   at this height the left and right halves start showing the same pixels and
	   the effect collapses into a duplicate. 300 keeps clear of that. */
	inline-size: clamp(90px, 17vw, 300px);
	margin: 0;
	border-radius: var(--wp--custom--radius--image);
	overflow: hidden;
	/* Softening kept deliberately light — enough to sit behind the case, not so
	   much that the work is unreadable. The remaining blur is doing real work
	   though: it is most of what stops the stock portrait reading as a patient
	   alongside a genuine before-and-after. */
	opacity: 0.68;
	filter: blur(0.6px) saturate(0.92);
}

.dca-gallery__aside img {
	inline-size: 100%;
	block-size: 100%;
	object-fit: cover;
}

/* Each flanking photograph is used twice, showing its left half on one side of
   the case and its right half on the other. The centre card then reads as
   sitting on top of a continuous image rather than between unrelated crops —
   the same trick as a figure standing in front of a backdrop. */
.dca-gallery__aside--start img {
	object-position: left center;
}

.dca-gallery__aside--end img {
	object-position: right center;
}

/* Opt out of the halving.
 *
 * Splitting works on a mouth or an instrument tray, where either half still
 * reads as itself. It does not work on a face: half a face on each side of the
 * card is the one thing the eye refuses to reassemble, and it looks wrong
 * rather than clever. Anything with a face in it stays whole on both sides.
 * Its own frame is cropped tall and narrow so a slim card still shows all of
 * the face rather than a strip down the middle of it. */
.dca-gallery__aside--whole img {
	object-position: center;
}

/* The outermost pair sits a little narrower than the split pair beside it —
   the original proportion, restored. It was cut much further at one point to
   force the halving to read on a portrait, which is no longer needed now that
   faces are shown whole. */
.dca-gallery > .dca-gallery__aside:first-child,
.dca-gallery > .dca-gallery__aside:last-child {
	inline-size: clamp(70px, 12vw, 220px);
}

/* Her frame is cropped 1:2, taller than these cards, so a wider card crops
   vertically instead of horizontally. Biased up to keep the face rather than
   centring on her collar. */
.dca-gallery__aside--whole img {
	object-position: center 22%;
}

.dca-gallery__main {
	/* Must not shrink. The flankers are fixed-width and do not, so any overflow
	   was being taken out of this card instead — the decoration squeezing the
	   one thing the section exists to show. The row is wider than the viewport
	   by design; the outer cards absorb that by being clipped. */
	flex: 0 0 clamp(300px, 52vw, 740px);
	display: flex;
	flex-direction: column;
	justify-content: center;
	gap: var(--wp--preset--spacing--40);
	padding: var(--wp--preset--spacing--40);
	background-color: var(--wp--preset--color--mist);
	border-radius: var(--wp--custom--radius--image);
	text-align: center;
}

.dca-gallery__hint {
	font-size: var(--wp--preset--font-size--small);
	color: var(--wp--preset--color--muted);
	margin: 0.4rem 0 0;
}

.dca-gallery__title {
	font-size: var(--wp--preset--font-size--x-large);
	line-height: 1.2;
	margin: 0;
}

/* Below the breakpoint the flankers would be slivers, so they go entirely and
   the case takes the full width. */
@media (max-width: 781px) {
	.dca-gallery {
		width: auto;
		max-width: none;
		margin-inline: 0;
		padding-inline: 0;
	}

	.dca-gallery__aside {
		display: none;
	}

	.dca-gallery__main {
		flex-basis: 100%;
	}
}

.dca-compare {
	position: relative;
	/* Clinical intraoral shots are framed with the arch across the top of a 4:3
	   frame and dead black below it. A letterbox crops that black away without
	   touching the files, so both images keep identical dimensions — which is
	   what keeps the two halves registered across the wipe. */
	aspect-ratio: 2.1 / 1;
	overflow: clip;
	border-radius: var(--wp--custom--radius--image);
	/* The dental midline sits at 47.95% of these frames, not at 50% — measured
	   off the interproximal gap between the central incisors. Opening the wipe
	   on the midline means the two halves meet exactly where the eye checks. */
	--dca-compare-pos: 48%;
}

.dca-compare img {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
	/* Anchored to the top, identically for both, so the midline lands in the
	   same place on each side of the wipe.
	   Not centred vertically, though the taller frame invites it: these shots
	   are cut off at the gum line, so pulling the window down would slice
	   through the gingival margin and lose the part of the result a dentist is
	   actually judged on. The arch stays whole and the dark field fills below. */
	object-position: center top;
}

.dca-compare__after {
	clip-path: inset(0 0 0 var(--dca-compare-pos));
	/* Measured registration, not eyeballing. The two shots are from the same
	   setup but not identical: the after frames the arch 0.5% narrower and its
	   midline lands 3px right of the before's, over 1024px. Scaling about the
	   midline widens it back without moving the one landmark that has to stay
	   put, then the nudge left brings the two midlines onto each other. */
	transform: translateX(-0.29%) scaleX(1.006);
	transform-origin: 48% center;
}

.dca-compare__range {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	margin: 0;
	opacity: 0;
	cursor: ew-resize;
}

.dca-compare__handle {
	position: absolute;
	inset-block: 0;
	inset-inline-start: var(--dca-compare-pos);
	width: 2px;
	background: var(--wp--preset--color--porcelain);
	pointer-events: none;
	translate: -1px 0;
}

.dca-compare__handle::after {
	content: "";
	position: absolute;
	inset-block-start: 50%;
	inset-inline-start: 50%;
	width: 26px;
	height: 52px;
	translate: -50% -50%;
	border-radius: var(--wp--custom--radius--pill);
	background: var(--wp--preset--color--porcelain);
	box-shadow: var(--wp--preset--shadow--card);
}

.dca-compare__range:focus-visible + .dca-compare__handle::after {
	outline: 3px solid var(--wp--preset--color--sea-glass);
	outline-offset: 3px;
}

/* ---------------------------------------------------------------------------
 * 7. Testimonials
 * ------------------------------------------------------------------------ */

/* Without JS only the first quote shows; once enhanced the script owns which
   slide is active. display:none also takes the inactive slides out of the
   accessibility tree, so screen readers only ever meet one quote. */
.dca-testimonials__slide {
	display: none;
}

.dca-testimonials:not(.is-enhanced) .dca-testimonials__slide:first-of-type,
.dca-testimonials.is-enhanced .dca-testimonials__slide.is-active {
	display: block;
}

.dca-testimonials__grid {
	display: grid;
	grid-template-columns: minmax(0, 0.8fr) minmax(0, 1.2fr);
	gap: var(--wp--preset--spacing--50);
	align-items: center;
}

/* The image block renders a <figure>, so the crop has to be applied to the
   <img> inside it rather than to the element carrying the class. */
.dca-testimonials__portrait {
	width: 100%;
	margin: 0;
}

.dca-testimonials__portrait img {
	width: 100%;
	aspect-ratio: 4 / 5;
	object-fit: cover;
	border-radius: var(--wp--custom--radius--medium);
}

.dca-testimonials__quote {
	font-size: var(--wp--preset--font-size--x-large);
	line-height: 1.4;
	letter-spacing: -0.02em;
	margin: 0;
	text-wrap: pretty;
}

.dca-testimonials__meta {
	display: flex;
	flex-wrap: wrap;
	gap: var(--wp--preset--spacing--30);
	align-items: baseline;
	margin-block-start: var(--wp--preset--spacing--30);
	font-size: var(--wp--preset--font-size--small);
}

.dca-testimonials__controls {
	display: flex;
	align-items: center;
	justify-content: space-between;
	margin-block-start: var(--wp--preset--spacing--50);
	font-size: var(--wp--preset--font-size--small);
}

.dca-testimonials__nav {
	display: flex;
	gap: 0.75rem;
}

.dca-testimonials__btn {
	inline-size: 44px;
	block-size: 44px;
	border-radius: var(--wp--custom--radius--pill);
	border: 1px solid currentColor;
	background: none;
	color: inherit;
	cursor: pointer;
	font-size: 1rem;
	line-height: 1;
	transition:
		background-color var(--wp--custom--transition--base),
		color var(--wp--custom--transition--base);
}

.dca-testimonials__btn:hover {
	background-color: var(--wp--preset--color--porcelain);
	color: var(--wp--preset--color--midnight);
}

@media (max-width: 781px) {
	.dca-testimonials__grid {
		grid-template-columns: 1fr;
	}
}

/* ---------------------------------------------------------------------------
 * 7b. Treatment plan — the section that stands in for testimonials
 *
 * A clinic with no patient testimonials yet still has to earn trust somewhere.
 * This shows the artefact instead of quoting people: the written plan, with the
 * material named against each tooth.
 * ------------------------------------------------------------------------ */

.dca-plan__grid {
	display: grid;
	grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
	gap: var(--wp--preset--spacing--50);
	align-items: center;
}

.dca-plan__media {
	position: relative;
	/* Contains the blend so it tints the photograph and not the section behind. */
	isolation: isolate;
	margin: 0;
	border-radius: var(--wp--custom--radius--image);
	overflow: hidden;
}

.dca-plan__media img {
	display: block;
	width: 100%;
	height: auto;
}

.dca-plan__list {
	list-style: none;
	margin: var(--wp--preset--spacing--40) 0 0;
	padding: 0;
}

.dca-plan__list li {
	display: flex;
	gap: 0.85rem;
	padding-block: 0.7rem;
	border-block-end: 1px solid rgba(220, 233, 235, 0.18);
	font-size: var(--wp--preset--font-size--small);
}

.dca-plan__list li::before {
	content: "";
	flex: none;
	inline-size: 6px;
	block-size: 6px;
	margin-block-start: 0.55em;
	border-radius: 50%;
	background-color: var(--wp--preset--color--sea-glass);
}

@media (max-width: 781px) {
	.dca-plan__grid {
		grid-template-columns: 1fr;
	}
}

/* ---------------------------------------------------------------------------
 * 8. FAQ — heading parked on the left, accordion on the right
 * ------------------------------------------------------------------------ */

.dca-faq {
	display: grid;
	grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr);
	gap: var(--wp--preset--spacing--50);
	align-items: start;
}

.dca-faq__list > * + * {
	margin-block-start: var(--wp--preset--spacing--20);
}

.dca-faq summary {
	cursor: pointer;
	font-size: var(--wp--preset--font-size--large);
	line-height: 1.35;
	list-style: none;
	display: flex;
	justify-content: space-between;
	align-items: start;
	gap: var(--wp--preset--spacing--30);
}

.dca-faq summary::-webkit-details-marker {
	display: none;
}

.dca-faq summary::after {
	content: "+";
	flex: none;
	font-size: 1.25em;
	line-height: 1;
	color: var(--wp--preset--color--adriatic);
	transition: transform var(--wp--custom--transition--base);
}

.dca-faq details[open] summary::after {
	transform: rotate(45deg);
}

.dca-faq details > *:not(summary) {
	margin-block-start: var(--wp--preset--spacing--20);
	color: var(--wp--preset--color--muted);
	font-size: var(--wp--preset--font-size--small);
	max-width: 62ch;
}

@media (max-width: 781px) {
	.dca-faq {
		grid-template-columns: 1fr;
	}
}

/* ---------------------------------------------------------------------------
 * 9. Accessibility
 * ------------------------------------------------------------------------ */

:where(a, button, input, summary):focus-visible {
	outline: 3px solid var(--wp--preset--color--sea-glass);
	outline-offset: 3px;
}

.dca-skip-link {
	position: absolute;
	inset-block-start: -100px;
	inset-inline-start: var(--wp--preset--spacing--30);
	z-index: 100;
	padding: 0.75rem 1.25rem;
	background: var(--wp--preset--color--midnight);
	color: var(--wp--preset--color--porcelain);
	border-radius: var(--wp--custom--radius--small);
}

.dca-skip-link:focus {
	inset-block-start: var(--wp--preset--spacing--20);
}
