/**
 * LD4T CMS — front-end section styles.
 * Styled for the ld4t-frontend theme: uses --ld4t-* tokens with fallbacks and
 * the theme's .ld4t-container / .ld4t-card / .button utility classes.
 */

.ld4t-cms-sections {
	--cms-orange: var( --ld4t-orange, #f97316 );
	--cms-blue: var( --ld4t-blue, #1e3a8a );
	--cms-blue-bright: var( --ld4t-blue-bright, #2563eb );
	--cms-ink: var( --ld4t-ink, #0f172a );
	--cms-muted: var( --ld4t-muted, #64748b );
	--cms-border: var( --ld4t-border, #e2e8f0 );
	--cms-surface: var( --ld4t-surface, #f8fafc );
	--cms-blue-light: var( --ld4t-blue-light, #dbeafe );
	--cms-radius: var( --ld4t-radius, 14px );

	/* Inherited, so this guards every heading, badge, list item and label in
	   every section template — not just .ld4t-cms-rich — against a long
	   unbroken string (URL, German compound word, huge number) blowing out
	   the layout on narrow viewports. */
	overflow-wrap: break-word;
	word-wrap: break-word;
}

.ld4t-cms-section {
	padding: clamp( 48px, 7vw, 88px ) 0;
}

/* Chained with .ld4t-cms-section for higher specificity than the mobile
   .ld4t-cms-section override below, so the spacing choice survives at any width. */
.ld4t-cms-section.ld4t-cms-spacing-compact {
	padding: clamp( 24px, 3.5vw, 44px ) 0;
}

.ld4t-cms-section.ld4t-cms-spacing-roomy {
	padding: clamp( 72px, 10vw, 132px ) 0;
}

/* ---- Page header ---- */
.ld4t-cms-pageheader {
	text-align: center;
}

.ld4t-cms-pageheader-inner {
	max-width: 760px;
	margin: 0 auto;
}

.ld4t-cms-pageheader-title {
	margin: 0 0 .4em;
	font-family: var( --ld4t-font-heading, inherit );
	font-size: clamp( 32px, 5vw, 56px );
	line-height: 1.1;
	color: var( --cms-blue );
}

.ld4t-cms-pageheader-lead {
	margin: 0;
	font-size: clamp( 16px, 2vw, 19px );
	line-height: 1.75;
	color: var( --cms-muted );
}

/* Background variants */
.ld4t-cms-bg-hero {
	background: linear-gradient( 135deg, var( --ld4t-blue-light, #dbeafe ) 0%, var( --cms-surface ) 100% );
}

.ld4t-cms-bg-hero .ld4t-cms-pageheader-title {
	color: var( --cms-blue );
}

/* The lead's default --cms-muted gray sits at 3.9:1 on this background's
   lighter (blue-light) stop — under WCAG AA's 4.5:1. Reusing --cms-blue
   (7.15:1+ on both gradient stops) instead of minting a new tint: the
   32-56px/16-19px size gap already carries the heading/lead hierarchy, so
   color doesn't have to. */
.ld4t-cms-bg-hero .ld4t-cms-pageheader-lead {
	color: var( --cms-blue );
}

/* Deep navy variant — same gradient as the theme's .ld4t-row-hero, for the
   one bold "page header" moment on a high-stakes page (e.g. Contact) that
   wants the full committed treatment rather than the paler .bg-hero tint. */
.ld4t-cms-bg-navy {
	background: linear-gradient( 135deg, var( --ld4t-blue-dark, #172554 ) 0%, var( --cms-blue ) 55%, var( --cms-blue-bright ) 100% );
}

.ld4t-cms-bg-navy .ld4t-cms-pageheader-title,
.ld4t-cms-bg-navy .ld4t-cms-pageheader-lead {
	color: #fff;
}

.ld4t-cms-bg-orange {
	background: linear-gradient( 135deg, var( --cms-orange ) 0%, var( --ld4t-orange-dark, #ea580c ) 100% );
}

.ld4t-cms-bg-orange .ld4t-cms-pageheader-title,
.ld4t-cms-bg-orange .ld4t-cms-pageheader-lead {
	color: #fff;
}

.ld4t-cms-bg-surface {
	background: var( --cms-surface );
}

.ld4t-cms-bg-plain {
	background: #fff;
}

/* ---- Contact ---- */
.ld4t-cms-contact-grid {
	display: grid;
	grid-template-columns: minmax( 260px, 380px ) 1fr;
	gap: clamp( 24px, 4vw, 48px );
	align-items: start;
}

@media ( max-width: 782px ) {
	.ld4t-cms-contact-grid {
		grid-template-columns: 1fr;
	}
}

.ld4t-cms-contact-trust {
	display: flex;
	flex-direction: column;
	gap: 24px;
}

.ld4t-cms-contact-photo {
	margin: 0;
	border-radius: var( --cms-radius, 14px );
	overflow: hidden;
	box-shadow: 0 2px 10px -3px rgba( 15, 23, 42, .12 );
}

.ld4t-cms-contact-photo img {
	display: block;
	width: 100%;
	height: auto;
	aspect-ratio: 4 / 5;
	object-fit: cover;
}

.ld4t-cms-contact-photo figcaption {
	padding: 12px 16px;
	background: var( --cms-surface );
	font-family: var( --ld4t-font-heading, inherit );
	font-weight: 600;
	color: var( --cms-ink );
}

.ld4t-cms-contact-confidence {
	margin: 0;
	padding: 20px 24px;
	border-radius: var( --cms-radius, 14px );
	background: var( --ld4t-blue-light, #dbeafe );
	color: var( --cms-blue );
	font-family: var( --ld4t-font-heading, inherit );
	font-weight: 500;
	font-size: 1.05em;
	line-height: 1.6;
}

.ld4t-cms-contact-form-card h2,
.ld4t-cms-contact-info-card h2 {
	margin-top: 0;
}

.ld4t-cms-muted {
	color: var( --cms-muted );
}

/* Honeypot — visually hidden but present for bots. */
.ld4t-cms-hp {
	position: absolute !important;
	left: -9999px !important;
	width: 1px;
	height: 1px;
	overflow: hidden;
}

.ld4t-cms-form .ld4t-cms-field {
	margin: 0 0 1em;
}

.ld4t-cms-form label {
	display: block;
	margin-bottom: .35em;
	font-weight: 600;
	font-size: .95em;
	color: var( --cms-ink );
}

.ld4t-cms-req {
	color: var( --cms-orange );
}

.ld4t-cms-form input[type="text"],
.ld4t-cms-form input[type="tel"],
.ld4t-cms-form input[type="email"],
.ld4t-cms-form textarea {
	width: 100%;
	padding: .7em .9em;
	border: 1px solid var( --cms-border );
	border-radius: var( --ld4t-radius-sm, 8px );
	background: #fff;
	font: inherit;
	color: var( --cms-ink );
}

.ld4t-cms-form input:focus,
.ld4t-cms-form textarea:focus {
	outline: none;
	border-color: var( --cms-blue-bright );
	box-shadow: 0 0 0 3px var( --cms-blue-light );
}

.ld4t-cms-form textarea {
	resize: vertical;
}

.ld4t-cms-notice {
	padding: .9em 1.1em;
	border-radius: var( --ld4t-radius-sm, 8px );
	margin: 0 0 1em;
}

.ld4t-cms-notice-success {
	background: #dcfce7;
	border: 1px solid #86efac;
	color: #166534;
}

.ld4t-cms-notice-error {
	background: #fee2e2;
	border: 1px solid #fca5a5;
	color: #991b1b;
}

/* ---- Shared: centered section heading ---- */
.ld4t-cms-head {
	max-width: 720px;
	margin: 0 auto 2.5rem;
	text-align: center;
}

.ld4t-cms-head h2 {
	margin: 0 0 .4em;
}

.ld4t-cms-head p {
	margin: 0;
	color: var( --cms-muted );
}

/* ---- Hero ---- */
.ld4t-cms-hero.ld4t-cms-hero-has-image {
	position: relative;
	isolation: isolate;
}

/* Full-bleed cover image — a real <img> (see hero.php) instead of a CSS
   background so the browser's preload scanner can find and prioritize it as
   the LCP element, instead of only discovering it after CSSOM/style is built.
   Selector needs two classes' worth of specificity (not one) to beat the
   "Responsive safety" .ld4t-cms-sections img { height: auto } rule further
   down this file — that rule was clobbering height:100% here regardless of
   source order, which let the <img> fall back to sizing itself by its own
   intrinsic aspect ratio and overflow past the section into the content below. */
.ld4t-cms-hero-has-image .ld4t-cms-hero-bg {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
	z-index: 0;
}

.ld4t-cms-hero-has-image::before {
	content: '';
	position: absolute;
	inset: 0;
	background: linear-gradient( to bottom, rgba( 15, 23, 42, .55 ), rgba( 15, 23, 42, .72 ) );
	z-index: 1;
}

.ld4t-cms-hero-has-image .ld4t-cms-hero-inner {
	position: relative;
	z-index: 2;
}

.ld4t-cms-hero-has-image .ld4t-cms-hero-title,
.ld4t-cms-hero-has-image .ld4t-cms-hero-lead {
	color: #fff;
}

.ld4t-cms-hero-inner {
	text-align: center;
	max-width: 820px;
}

.ld4t-cms-hero-title {
	margin: 0 0 .4em;
	font-size: clamp( 34px, 5.5vw, 64px );
	line-height: 1.08;
}

.ld4t-cms-hero-lead {
	font-size: clamp( 16px, 2vw, 20px );
	line-height: 1.75;
	margin: 0 auto 1.6em;
	max-width: 640px;
}

.ld4t-cms-hero-actions {
	display: flex;
	flex-wrap: wrap;
	gap: 12px;
	justify-content: center;
	margin: 0;
}

.ld4t-cms-cta-inner {
	text-align: center;
	max-width: 760px;
}

.ld4t-cms-cta.ld4t-cms-cta-has-image {
	position: relative;
	isolation: isolate;
}

/* Full-bleed cover image — a real <img loading="lazy"> (see cta.php) instead
   of a CSS background, so this well-below-the-fold band's image is deferred
   instead of competing with above-the-fold resources on initial load.
   Two-class selector for the same specificity reason as .ld4t-cms-hero-bg above. */
.ld4t-cms-cta-has-image .ld4t-cms-cta-bg {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
	z-index: 0;
}

.ld4t-cms-cta-has-image::before {
	content: '';
	position: absolute;
	inset: 0;
	background: linear-gradient( to bottom, rgba( 15, 23, 42, .55 ), rgba( 15, 23, 42, .72 ) );
	z-index: 1;
}

.ld4t-cms-cta-has-image .ld4t-cms-cta-inner {
	position: relative;
	z-index: 2;
}

.ld4t-cms-cta-has-image h2,
.ld4t-cms-cta-has-image p {
	color: #fff;
}

/* ---- Cards grid ---- */
.ld4t-cms-grid {
	display: grid;
	gap: 32px;
}

.ld4t-cms-cols-2 {
	grid-template-columns: repeat( 2, 1fr );
}

.ld4t-cms-cols-3 {
	grid-template-columns: repeat( 3, 1fr );
}

.ld4t-cms-cols-4 {
	grid-template-columns: repeat( 4, 1fr );
}

@media ( max-width: 900px ) {
	.ld4t-cms-cols-3,
	.ld4t-cms-cols-4 {
		grid-template-columns: repeat( 2, 1fr );
	}
}

/* Scoped to 601-900px (not the plain max-width:900px above) — below 600px the
   grid collapses to a single column (see next query), so the 50%-width cap
   here must not apply there too, or the 3rd/orphaned card would get stranded
   at half the viewport width instead of filling it like its siblings. */
@media ( min-width: 601px ) and ( max-width: 900px ) {
	/* A 3-card grid at 2 columns strands its 3rd card alone on the left of a
	   near-empty row (e.g. pricing tiers on tablet) — center it at the same
	   width as its siblings instead of leaving it stranded. Doesn't apply to
	   4-card grids: an orphaned 4th card there is a much smaller gap, and
	   spanning it full-width would look like an unrelated banner. */
	.ld4t-cms-cols-3 > :last-child:nth-child( odd ) {
		grid-column: 1 / -1;
		max-width: calc( 50% - 16px );
		margin: 0 auto;
	}
}

@media ( max-width: 600px ) {
	.ld4t-cms-grid {
		grid-template-columns: 1fr;
	}
}

.ld4t-cms-stat-title {
	display: block;
	color: var( --cms-ink );
}

.ld4t-cms-price {
	font-size: 1.1em;
	font-weight: 600;
	color: var( --cms-blue-bright );
	margin: 0 0 .5em;
}

/* ---- Courses grid (coursesGrid — cards built live from `course` posts) ---- */
/* .ld4t-card.ld4t-cms-course-card (two classes chained), not just
   .ld4t-cms-course-card alone — same specificity as plain .ld4t-card
   otherwise, so this would lose the cascade to the theme's own
   `.ld4t-card { padding: 32px }` whenever style.css happens to load after
   this file, silently leaving the image inset instead of edge-to-edge. */
.ld4t-card.ld4t-cms-course-card {
	/* The image (when present) bleeds to the card's own edges; everything
	   else lives in .ld4t-cms-course-body, which carries the card's normal
	   padding either way — so a course with no featured image still gets
	   correctly-padded text, no :has()/conditional-margin trick needed. */
	padding: 0;
	overflow: hidden;
	/* Anchors .ld4t-cms-course-flag, which overlays the top-right corner of
	   the card (over the image, like a ribbon) rather than sitting inline
	   above the title. */
	position: relative;
}

/* Two-class selector (matches the .ld4t-cms-hero-bg fix above) so this beats
   the "Responsive safety" .ld4t-cms-sections img { height: auto } rule further
   down the file — same specificity otherwise, so source order let that rule
   win and portrait photos (e.g. the teacher's photo on Full A1 Course) render
   at their own tall aspect ratio instead of the intended 200px crop. */
.ld4t-card.ld4t-cms-course-card .ld4t-cms-course-image img {
	display: block;
	width: 100%;
	height: 200px;
	object-fit: cover;
	transition: transform .4s cubic-bezier( .4, 0, .2, 1 );
}

/* The card itself already lifts on hover (style.css); let the photo drift in
   the same gesture instead of sitting static while everything around it moves. */
.ld4t-cms-course-card:hover .ld4t-cms-course-image img {
	transform: scale( 1.04 );
}

@media ( prefers-reduced-motion: reduce ) {
	.ld4t-cms-course-image img {
		transition: none;
	}
	.ld4t-cms-course-card:hover .ld4t-cms-course-image img {
		transform: none;
	}
}

.ld4t-cms-course-body {
	display: flex;
	flex-direction: column;
	flex: 1;
	padding: 32px;
}

.ld4t-cms-course-flag {
	position: absolute;
	top: 16px;
	right: 16px;
	z-index: 1;
	padding: .3em .9em;
	border-radius: 999px;
	background: var( --cms-orange );
	color: #fff;
	font-family: var( --ld4t-font-heading, inherit );
	font-size: .78em;
	font-weight: 600;
	letter-spacing: .01em;
	box-shadow: 0 2px 6px -1px rgba( 15, 23, 42, .3 );
}

.ld4t-cms-course-pill {
	display: inline-block;
	margin: 0 .4em .4em 0;
	padding: .25em .8em;
	border-radius: 999px;
	background: var( --cms-surface );
	border: 1px solid var( --cms-border );
	color: var( --cms-muted );
	font-size: .85em;
}

/* Clamped to a fixed line count (not a character-count truncate) so cards
   with a short vs. long course summary still end up the same height —
   the button beneath it is pinned to the bottom by the .button rule below
   regardless of how many lines this actually uses. */
.ld4t-cms-course-detail {
	display: -webkit-box;
	-webkit-line-clamp: 3;
	-webkit-box-orient: vertical;
	overflow: hidden;
	margin: 0 0 20px;
	color: var( --ld4t-text, #334155 );
}

/* .ld4t-card's own bottom-pinned-button rule only targets its *direct*
   children (see style.css) — the image wrapper breaks that here, so this
   restates it one level down. */
.ld4t-cms-course-body > .button {
	margin-top: auto;
	align-self: flex-start;
}

.ld4t-cms-course-meta {
	color: var( --cms-muted );
	font-size: .95em;
}

/* Courses beyond the first 6 stay in the markup (SEO/no-JS friendly) but are
   hidden until the "show more" button reveals them — see courses-grid.js.
   Two-class selector (matches the fix above for .ld4t-cms-course-image img) —
   same specificity as the theme's .ld4t-card { display: flex }, and style.css
   loads after this file, so a single class here would silently lose and the
   "extra" cards would stay visible even before the button is clicked. */
.ld4t-card.ld4t-cms-course-card-extra {
	display: none;
}

.ld4t-cms-course-more-wrap {
	margin: 32px 0 0;
	text-align: center;
}

/* ---- Row / column layout ---- */
.ld4t-cms-row-grid {
	display: grid;
	gap: clamp( 24px, 4vw, 48px );
	align-items: start;
}

.ld4t-cms-row-1col       { grid-template-columns: 1fr; }
.ld4t-cms-row-2col-equal { grid-template-columns: 1fr 1fr; }
.ld4t-cms-row-3col-equal { grid-template-columns: 1fr 1fr 1fr; }
.ld4t-cms-row-2col-1-2   { grid-template-columns: 1fr 2fr; }
.ld4t-cms-row-2col-2-1   { grid-template-columns: 2fr 1fr; }

@media ( max-width: 900px ) {
	.ld4t-cms-row-3col-equal {
		grid-template-columns: 1fr 1fr;
	}
}

@media ( max-width: 600px ) {
	.ld4t-cms-row-grid {
		grid-template-columns: 1fr !important;
	}
}

.ld4t-cms-column {
	min-width: 0; /* prevent grid blowout from wide media/text */
	display: flex;
	flex-direction: column;
	gap: 20px;
}

/* Full-bleed container variant (edge-to-edge, ignores --ld4t-container clamp). */
.ld4t-cms-container-full {
	max-width: none;
	width: 100%;
	padding-left: 0;
	padding-right: 0;
}

/* ---- Widgets ---- */
.ld4t-cms-widget-spacer-small  { height: clamp( 16px, 2vw, 24px ); }
.ld4t-cms-widget-spacer-medium { height: clamp( 32px, 4vw, 56px ); }
.ld4t-cms-widget-spacer-large  { height: clamp( 56px, 8vw, 96px ); }

.ld4t-cms-widget-divider {
	border: 0;
	border-top: 1px solid var( --cms-border );
	margin: 0;
}

.ld4t-cms-widget-image img {
	border-radius: var( --cms-radius );
	display: block;
	width: 100%;
	height: auto;
}

.ld4t-cms-widget-heading {
	margin: 0 0 .4em;
}

.ld4t-cms-widget-heading.ld4t-cms-align-center {
	text-align: center;
}

/* ---- Split content ---- */
.ld4t-cms-split-grid {
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: clamp( 28px, 5vw, 64px );
	align-items: center;
}

@media ( max-width: 860px ) {
	.ld4t-cms-split-grid {
		grid-template-columns: 1fr;
	}
}

/* Short lead-in line above a splitContent title — body type, not a
   tracked-uppercase kicker (see the theme's No-Eyebrow Rule in DESIGN.md).
   Trust Navy, not Signal Orange: orange is reserved for actions/CTAs, and
   at this weight/size orange only hits ~2.8:1 on white (fails WCAG AA). */
.ld4t-cms-eyebrow {
	display: block;
	margin-bottom: .4em;
	font-family: var( --ld4t-font-heading, inherit );
	font-size: 1.05em;
	font-weight: 600;
	color: var( --cms-blue );
}

.ld4t-cms-list {
	list-style: none;
	padding: 0;
	margin: 1em 0;
}

.ld4t-cms-list li {
	position: relative;
	padding: .35em 0 .35em 1.6em;
}

.ld4t-cms-list li::before {
	content: "✓";
	position: absolute;
	left: 0;
	color: var( --cms-blue-bright );
	font-weight: 700;
}

.ld4t-cms-split-cta {
	margin-top: 1.5em;
}

/* .ld4t-card has height:100%, so when this card ends up shorter than the
   text column beside it, the card stretches to match — leaving slack below
   its own content. Give the button a guaranteed minimum gap from the text
   above (this rich block normally has its trailing margin trimmed to 0) AND
   let margin-top: auto soak up any leftover slack, pinning the button to the
   card's bottom edge instead of leaving it stranded high up with dead space
   underneath. When the card is exactly content-height (e.g. stacked mobile),
   auto resolves to 0 and the rich block's own margin is the only gap. */
.ld4t-cms-split-card .ld4t-cms-rich > :last-child {
	margin-bottom: 1.5em;
}

.ld4t-cms-split-card > .button {
	margin-top: auto;
}

.ld4t-cms-split-image {
	width: 100%;
	height: auto;
	border-radius: var( --cms-radius );
	display: block;
}

.ld4t-cms-rich > :first-child {
	margin-top: 0;
}

.ld4t-cms-rich > :last-child {
	margin-bottom: 0;
}

/* richText section width */
.ld4t-cms-rich-normal {
	max-width: 760px;
	margin-left: auto;
	margin-right: auto;
}

.ld4t-cms-rich-wide {
	max-width: 100%;
}

/* ---- Responsive safety ---- */

/* Media never overflows its column (prose/richText images, iframes). */
.ld4t-cms-sections img,
.ld4t-cms-sections video {
	max-width: 100%;
	height: auto;
}

.ld4t-cms-sections iframe {
	max-width: 100%;
}

/* Long words / URLs / code wrap instead of forcing horizontal scroll. */
.ld4t-cms-rich {
	overflow-wrap: break-word;
	word-wrap: break-word;
}

@media ( max-width: 600px ) {
	.ld4t-cms-section {
		padding: 44px 0;
	}

	.ld4t-cms-grid {
		gap: 20px;
	}

	.ld4t-cms-head {
		margin-bottom: 1.75rem;
	}

	/* Full-width, easy-to-tap hero/CTA buttons. */
	.ld4t-cms-hero-actions {
		flex-direction: column;
		align-items: stretch;
	}

	.ld4t-cms-hero-actions .button {
		width: 100%;
		justify-content: center;
		text-align: center;
	}

	.ld4t-cms-contact-grid {
		gap: 20px;
	}
}

/* ---- Design group (colour / alignment / spacing) --------------------------
   Set per block by the shared Design fields (inc/design.php). Colours arrive
   as the custom properties --ld4t-b-text / --ld4t-b-bg on the block wrapper,
   so the cascade below decides what actually inherits them instead of every
   template repeating it. A section's own wrapper sits *outside* its
   <section>, hence the child selectors. */
.ld4t-cms-has-color.ld4t-cms-widget,
.ld4t-cms-has-color > .ld4t-cms-section {
	color: var( --ld4t-b-text );
}

.ld4t-cms-has-color.ld4t-cms-widget :where( h1, h2, h3, h4, h5, h6, p, li, strong, em, span ),
.ld4t-cms-has-color > .ld4t-cms-section :where( h1, h2, h3, h4, h5, h6, p, li, strong, em, span ) {
	color: inherit;
}

.ld4t-cms-has-bg.ld4t-cms-widget,
.ld4t-cms-has-bg > .ld4t-cms-section {
	background: var( --ld4t-b-bg );
}

/* A widget given its own background needs breathing room, or the colour hugs
   the text. Sections already carry their own vertical padding. */
.ld4t-cms-has-bg.ld4t-cms-widget {
	padding: clamp( 16px, 2.5vw, 28px );
	border-radius: var( --cms-radius );
}

.ld4t-cms-block.ld4t-cms-align-left,
.ld4t-cms-widget.ld4t-cms-align-left   { text-align: left; }
.ld4t-cms-block.ld4t-cms-align-center,
.ld4t-cms-widget.ld4t-cms-align-center { text-align: center; }
.ld4t-cms-block.ld4t-cms-align-right,
.ld4t-cms-widget.ld4t-cms-align-right  { text-align: right; }

/* Centring a block should centre its button row and grids too, not only the
   text runs. */
.ld4t-cms-align-center .ld4t-cms-buttons { justify-content: center; }
.ld4t-cms-align-right  .ld4t-cms-buttons { justify-content: flex-end; }

.ld4t-cms-mt-none { margin-top: 0 !important; }
.ld4t-cms-mt-sm   { margin-top: clamp( 12px, 1.5vw, 20px ); }
.ld4t-cms-mt-md   { margin-top: clamp( 24px, 3vw, 40px ); }
.ld4t-cms-mt-lg   { margin-top: clamp( 40px, 5vw, 72px ); }
.ld4t-cms-mb-none { margin-bottom: 0 !important; }
.ld4t-cms-mb-sm   { margin-bottom: clamp( 12px, 1.5vw, 20px ); }
.ld4t-cms-mb-md   { margin-bottom: clamp( 24px, 3vw, 40px ); }
.ld4t-cms-mb-lg   { margin-bottom: clamp( 40px, 5vw, 72px ); }

/* ---- Button groups ----
   Any number of buttons per block (the `buttons` repeater), wrapping on
   narrow viewports instead of overflowing. */
/* Deliberately NOT a flex container. These groups sit in centred bands (CTA,
   cards, price card) and in left-aligned columns (split content) alike, and the
   only thing that knows which is the `text-align` they inherit. A flex wrapper
   ignores text-align, so making one pinned every button on the site to the left
   of its section regardless of the heading above it. Inline-flex buttons flow
   like text instead, so each group lines up with the words around it for free.

   Zero-specificity, so the per-section rules above (.ld4t-cms-hero-actions and
   friends) keep overriding this where they already did. */
:where( .ld4t-cms-buttons ) {
	margin: 24px 0 0;
}

/* Symmetric side margins stand in for flex `gap`; asymmetric ones would throw
   a centred group off-centre by half the gap. */
:where( .ld4t-cms-buttons ) > .button {
	margin: 6px 5px 0;
}

/* Sections that do make the group a real flex row bring their own `gap`, so
   drop the inline-flow margins there rather than adding to it. */
.ld4t-cms-hero-actions > .button {
	margin: 0;
}

/* The theme makes price-card buttons full-width blocks. A side margin on a
   100%-wide button pushes it past its own container, so keep the vertical
   rhythm and drop the horizontal half. */
.ld4t-price-card .ld4t-cms-buttons > .button {
	margin-left: 0;
	margin-right: 0;
}

.ld4t-cms-buttons .button {
	display: inline-flex;
	align-items: center;
	gap: .5em;
}

.ld4t-cms-btn-icon {
	display: inline-flex;
	line-height: 1;
}

/* "Text only" button variant — the link-styled member of the button family. */
.ld4t-cms-buttons .button-ghost {
	background: transparent;
	border-color: transparent;
	color: var( --cms-blue-bright );
	box-shadow: none;
	padding-left: 0;
	padding-right: 0;
}

.ld4t-cms-buttons .button-ghost:hover,
.ld4t-cms-buttons .button-ghost:focus {
	color: var( --cms-orange );
	background: transparent;
}

/* Icons inside lists/cards keep the size the old inline SVGs had. */
.ld4t-cms-icon-slot .fa-solid,
.ld4t-cms-icon-slot .fa-regular,
.ld4t-cms-icon-slot .fa-brands {
	font-size: 1em;
	line-height: 1;
}

/* A list item that chose its own icon drops the CSS bullet — the icon is the
   marker now. */
.ld4t-cms-sections li.ld4t-cms-has-icon {
	list-style: none;
	display: flex;
	align-items: flex-start;
	gap: .6em;
}

.ld4t-cms-sections li.ld4t-cms-has-icon .ld4t-cms-icon-slot {
	flex: 0 0 auto;
	margin-top: .15em;
	color: var( --cms-orange );
}

.ld4t-price-card-meta .ld4t-cms-icon-slot {
	margin-right: .5em;
}

/* Card icon: a large accent glyph above the card's own content. */
.ld4t-cms-card-icon {
	display: block;
	font-size: 1.9em;
	line-height: 1;
	margin-bottom: .4em;
	color: var( --cms-orange );
}

/* A plain card's badge: a short scannable value (a duration, a count) sitting
   above the title, not competing with it. */
.ld4t-cms-card-badge {
	margin: 0 0 .35em;
	font-size: 12px;
	font-weight: 700;
	letter-spacing: .03em;
	text-transform: uppercase;
	color: var( --cms-orange );
}

/* ---- Cards grid: "Group into one card box" ----
   The section's heading and its whole grid share a single bordered panel, so a
   subject made of parts (an exam set and its papers) reads as one thing. The
   inner cards therefore give up their own frame: a bordered card inside a
   bordered card is two boxes saying the same thing, and the nesting is what
   the reader ends up looking at instead of the content. */
.ld4t-cms-cardbox {
	background: var( --ld4t-white, #fff );
	border: 1px solid var( --cms-border );
	border-radius: var( --cms-radius );
	box-shadow: var( --ld4t-shadow-sm, 0 1px 2px rgba( 15, 23, 42, .06 ) );
	padding: clamp( 24px, 3.5vw, 40px );
}

/* Left-aligned and full width inside the box: the centered, 720px-capped
   section heading is sized for a page-wide band, and reads as floating loose
   when it sits inside a panel with its own edges. */
.ld4t-cms-cardbox .ld4t-cms-head {
	max-width: none;
	margin: 0 0 clamp( 20px, 2.5vw, 32px );
	text-align: left;
}

.ld4t-cms-cardbox .ld4t-cms-head h2 {
	font-size: clamp( 22px, 3vw, 30px );
}

/* An accent rule under the box's heading, marking where the shared title ends
   and the individual parts begin. */
.ld4t-cms-cardbox .ld4t-cms-head::after {
	content: "";
	display: block;
	width: 56px;
	height: 3px;
	margin-top: clamp( 16px, 2vw, 24px );
	border-radius: 2px;
	background: var( --cms-orange );
}

.ld4t-cms-cards-boxed .ld4t-cms-grid {
	gap: clamp( 16px, 2vw, 24px );
}

/* Inner parts: flat items on the panel, not a second card. A tile that keeps
   its own background/border/shadow inside .ld4t-cms-cardbox is a card nested
   in a card — the outer box is the one thing being grouped, so it's the one
   that gets to look like a container; these give that up entirely and rely
   on the grid's gap (and, stacked on mobile, a hairline) for separation.
   Chained with .ld4t-cms-cards-boxed for higher specificity than the theme's
   own .ld4t-card, whose border and shadow are what's being undone. */
.ld4t-cms-cards-boxed .ld4t-cms-grid > .ld4t-card,
.ld4t-cms-cards-boxed .ld4t-cms-grid > .ld4t-trust-item,
.ld4t-cms-cards-boxed .ld4t-cms-grid > .ld4t-process-step {
	background: transparent;
	border: 0;
	border-radius: 0;
	box-shadow: none;
	padding: 0;
}

.ld4t-cms-cards-boxed .ld4t-cms-grid > .ld4t-card:hover {
	transform: none;
}

/* Below 900px the grid itself still holds multiple columns (or wraps to two),
   so the gap keeps doing the separating job. Only once it collapses to one
   column (600px, see .ld4t-cms-grid above) do stacked items need their own
   cue — a single neutral hairline, not another box. */
@media ( max-width: 600px ) {
	.ld4t-cms-cards-boxed .ld4t-cms-grid > .ld4t-card:not( :first-child ),
	.ld4t-cms-cards-boxed .ld4t-cms-grid > .ld4t-trust-item:not( :first-child ),
	.ld4t-cms-cards-boxed .ld4t-cms-grid > .ld4t-process-step:not( :first-child ) {
		padding-top: 20px;
		border-top: 1px solid var( --cms-border );
	}
}

.ld4t-cms-cards-boxed .ld4t-cms-grid > .ld4t-card h3 {
	font-size: clamp( 16px, 1.6vw, 18px );
}

.ld4t-cms-cards-boxed .ld4t-cms-card-icon {
	font-size: 1.5em;
}

/* The "plain" background is the page's own white, against which a white panel
   has only its 1px border to show for itself — tint the band so the box reads
   as a box. Matched by absence: ld4t_cms_row_class() emits no class at all for
   plain, so there is nothing positive to hook onto. */
.ld4t-cms-cards-boxed:not( .ld4t-row-hero ):not( .ld4t-row-orange ):not( .ld4t-row-surface ) {
	background: var( --cms-surface );
}

@media ( max-width: 600px ) {
	.ld4t-cms-cardbox {
		padding: 22px 18px;
	}
}

/* ---- Cards grid: "plain" variant — pill badge, centered body, arrow button ----
   Adapted from a reference blog-card pattern (small pill tag above the title,
   centered copy, a rounded button with a trailing arrow). Scoped to the
   `plain` variant only — the other variants (feature/step/stat/pricing) keep
   their left-aligned, badge-as-plain-label look. */
.ld4t-cms-variant-plain .ld4t-card {
	text-align: center;
}

.ld4t-cms-variant-plain .ld4t-card .ld4t-cms-card-badge {
	align-self: center;
	display: inline-flex;
	align-items: center;
	margin: 0 0 .6em;
	padding: .2em .7em;
	background: var( --cms-blue-light );
	border: 1px solid var( --cms-blue-bright );
	border-radius: 999px;
	color: var( --cms-blue );
	font-size: 12px;
	font-weight: 600;
	letter-spacing: normal;
	text-transform: none;
}

/* .ld4t-card > .button already pins to the bottom-left with border-radius:999px
   (see theme style.css); centering it here and adding the arrow is additive,
   not a rebuild — three extra declarations, no new markup. */
.ld4t-cms-variant-plain .ld4t-card > .button {
	align-self: center;
	display: inline-flex;
	align-items: center;
	gap: .4em;
	/* A 3-4 column grid leaves each button too narrow for the full-size
	   pill's padding plus a multi-word label — it was wrapping to two lines
	   at both the em-dash break and, on some labels, again after it. Sized
	   down for this context specifically (not the button in general) and
	   pinned to one line; the label itself was also shortened to remove the
	   forced break at the dash. */
	padding: .6em 1.15em;
	font-size: .9em;
	white-space: nowrap;
}

.ld4t-cms-variant-plain .ld4t-card > .button::after {
	content: "\2192";
	transition: transform var( --ld4t-transition );
}

.ld4t-cms-variant-plain .ld4t-card > .button:hover::after {
	transform: translateX( 3px );
}

/* ---- In-page jump targets ----
   Any section given an anchor ID (see cardsGrid's optional "Anchor ID" field)
   needs room to clear the sticky site header when scrolled to — otherwise the
   target's heading lands directly under it. 100px matches the offset already
   used for the sticky sidebar elsewhere in the theme (masthead is ~85px). */
.ld4t-cms-section[id] {
	scroll-margin-top: 100px;
}

/* ---- Jump nav: "which one is you" ----
   A short lead line plus a row of pill links that jump straight to the
   matching exam-set box, so a reader who already knows their level doesn't
   have to scroll past the ones that aren't theirs to find out. */
.ld4t-cms-jumpnav {
	max-width: 760px;
	margin: 0 auto;
	text-align: center;
}

.ld4t-cms-jumpnav-lead {
	margin: 0 0 .9em;
	color: var( --cms-muted );
	font-size: 14px;
}

.ld4t-cms-jumpnav-pills {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	gap: 12px;
}

.ld4t-cms-jumpnav-pill {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: .15em;
	min-width: 108px;
	padding: .55em 1.1em;
	background: var( --ld4t-white, #fff );
	border: 1.5px solid var( --cms-blue-bright );
	border-radius: 999px;
	color: var( --cms-blue );
	text-decoration: none;
	transition: background var( --ld4t-transition ), color var( --ld4t-transition ), transform var( --ld4t-transition );
}

.ld4t-cms-jumpnav-pill strong {
	font-family: var( --ld4t-font-heading, inherit );
	font-size: 15px;
	font-weight: 700;
}

.ld4t-cms-jumpnav-pill span {
	font-size: 11.5px;
	opacity: .85;
}

.ld4t-cms-jumpnav-pill:hover,
.ld4t-cms-jumpnav-pill:focus-visible {
	background: var( --cms-blue-bright );
	color: var( --ld4t-white, #fff );
	transform: translateY( -2px );
}

@media ( max-width: 480px ) {
	.ld4t-cms-jumpnav-pill {
		min-width: 0;
		flex: 1 1 30%;
	}
}
