/**
 * Reusable components: links, buttons, icons, cards, forms, and the site header.
 *
 * BEM naming. Every interactive control meets the WCAG 2.2 §2.5.8 minimum
 * target size and carries a visible focus state.
 *
 * Structural styling only — no transitions or keyframes. All motion, including
 * button hover and the card lift, lives in animations.css.
 *
 * ORDER MATTERS. Primitives (links, buttons, icons, cards, forms) come first;
 * composed components that reuse them come last. The header composes .btn, so
 * .site-header__cta must be able to override .btn at equal specificity — which
 * only works if it appears later in the file. Keep new composed components at
 * the bottom rather than raising specificity to win.
 */

/* ===============================================================
 * Links
 * =============================================================== */
a {
	color: var(--color-link);
	text-decoration: underline;
	text-decoration-thickness: 1px;
	text-underline-offset: 0.2em;
}

a:hover {
	color: var(--color-link-hover);
	text-decoration-thickness: 2px;
}

/*
 * Link that reads as plain text until interacted with. Underline returns on
 * hover and focus so the affordance is never permanently absent.
 */
.link--plain {
	text-decoration: none;
}

.link--plain:hover,
.link--plain:focus-visible {
	text-decoration: underline;
}

.link--muted {
	color: var(--color-text-light);
}

.link--muted:hover {
	color: var(--color-text);
}

/* ===============================================================
 * Buttons — LOCKED
 * Primary:   blue background, white text, pill, medium shadow
 * Secondary: white background, blue border, blue text
 * =============================================================== */
.btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: var(--space-2);
	min-height: var(--target-comfortable);
	padding: var(--space-3) var(--space-6);
	border: var(--border-width) solid transparent;
	border-radius: var(--radius-pill);
	font-family: inherit;
	font-size: var(--text-base);
	font-weight: var(--weight-semibold);
	line-height: var(--leading-tight);
	text-align: center;
	text-decoration: none;
	cursor: pointer;
}

.btn--primary {
	background-color: var(--color-primary);
	border-color: var(--color-primary);
	color: var(--color-on-primary);
	box-shadow: var(--shadow-md);
}

.btn--primary:hover {
	background-color: var(--color-primary-hover);
	border-color: var(--color-primary-hover);
	color: var(--color-on-primary);
}

.btn--secondary {
	background-color: var(--color-bg);
	border-color: var(--color-primary);
	color: var(--color-primary);
}

.btn--secondary:hover {
	background-color: var(--color-bg-alt);
	color: var(--color-primary-hover);
	border-color: var(--color-primary-hover);
}

.btn--sm {
	min-height: 36px;
	padding: var(--space-2) var(--space-4);
	font-size: var(--text-sm);
}

.btn--lg {
	padding: var(--space-4) var(--space-8);
	font-size: var(--text-lg);
}

.btn--full {
	width: 100%;
}

/*
 * Square button carrying only an icon; its accessible name comes from a .sr-only
 * span. Keeps the full comfortable target in both axes rather than inheriting the
 * text button's horizontal padding.
 */
.btn--icon {
	inline-size: var(--target-comfortable);
	padding-inline: 0;
	flex-shrink: 0;
}

.btn[disabled],
.btn[aria-disabled="true"] {
	opacity: 0.55;
	cursor: not-allowed;
	pointer-events: none;
}

/* ===============================================================
 * Icons — LOCKED: Lucide SVG at 24px
 *
 * Lucide is stroke-based, so stroke inherits the text colour and fill is
 * cleared (base.css sets fill: currentColor for decorative SVG).
 * =============================================================== */
.icon {
	inline-size: var(--icon-size);
	block-size: var(--icon-size);
	flex-shrink: 0;
	fill: none;
	stroke: currentColor;
	stroke-width: 2;
	stroke-linecap: round;
	stroke-linejoin: round;
}

.icon--sm {
	--icon-size: 20px;
}

.icon--lg {
	--icon-size: 32px;
}

/*
 * Brand-coloured icon. A modifier rather than a per-section rule, because
 * sections kept redeclaring the same colour on their own icon class.
 */
.icon--primary {
	color: var(--color-primary);
}

/* Mirror directional icons in RTL. */
[dir="rtl"] .icon--directional {
	transform: scaleX(-1);
}

/* ===============================================================
 * Cards — LOCKED: white background, 12px radius, thin border,
 * small shadow, 4px hover lift
 * =============================================================== */
.card {
	display: flex;
	flex-direction: column;
	padding: var(--space-6);
	border: var(--border-width) solid var(--color-border);
	border-radius: var(--radius-md);
	background-color: var(--color-bg);
	box-shadow: var(--shadow-sm);
}

/*
 * .card--interactive marks a card whose whole surface is actionable. The lift
 * itself is defined in animations.css.
 */

/* Hero cards use the 16px radius — LOCKED. */
.card--hero {
	border-radius: var(--radius-lg);
}

.card--flush {
	padding: 0;
}

.card__title {
	font-size: var(--text-xl);
	font-weight: var(--weight-bold);
}

.card__text {
	color: var(--color-text-light);
}

/*
 * Stretched link: makes the entire card clickable from a single anchor while
 * keeping one real link in the accessibility tree.
 */
.card__link::after {
	content: "";
	position: absolute;
	inset: 0;
}

.card:has(.card__link) {
	position: relative;
}

/*
 * When the whole card is the target, the focus ring belongs on the card rather
 * than on the few words of the title. Guarded by @supports so the anchor keeps
 * its own ring wherever :has() is unavailable — focus is never left invisible.
 */
@supports selector(:has(*)) {
	.card:has(.card__link:focus-visible) {
		outline: var(--focus-width) solid var(--color-focus);
		outline-offset: var(--focus-offset);
	}

	.card__link:focus-visible {
		outline: none;
	}
}

/* ===============================================================
 * Forms
 *
 * Control borders use --color-border-strong (4.8:1), not --color-border
 * (1.2:1), to satisfy WCAG 2.2 §1.4.11 non-text contrast.
 * =============================================================== */
.form-field {
	display: flex;
	flex-direction: column;
	gap: var(--space-2);
}

.form-label {
	font-size: var(--text-sm);
	font-weight: var(--weight-semibold);
}

/*
 * Required marker. The asterisk is decorative — the control itself carries
 * the `required` attribute, which is what assistive technology announces.
 */
.form-label__required {
	color: var(--color-danger);
}

.form-input,
.form-textarea,
.form-select {
	inline-size: 100%;
	min-block-size: var(--target-comfortable);
	padding: var(--space-3) var(--space-4);
	border: var(--border-width) solid var(--color-border-strong);
	border-radius: var(--radius-sm);
	background-color: var(--color-bg);
	color: var(--color-text);
	font-size: var(--text-base);
}

.form-input::placeholder,
.form-textarea::placeholder {
	color: var(--color-text-light);
	opacity: 1;
}

.form-input:hover,
.form-textarea:hover,
.form-select:hover {
	border-color: var(--color-text);
}

/*
 * Focus is doubled: the ring from base.css plus a border colour change, so
 * the state survives forced-colours and high-contrast modes.
 */
.form-input:focus-visible,
.form-textarea:focus-visible,
.form-select:focus-visible {
	border-color: var(--color-primary);
}

.form-textarea {
	min-block-size: 8rem;
}

.form-select {
	appearance: none;
	padding-inline-end: var(--space-10);
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%236B7280' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
	background-repeat: no-repeat;
	background-position: right var(--space-3) center;
	background-size: 20px;
	cursor: pointer;
}

[dir="rtl"] .form-select {
	background-position: left var(--space-3) center;
}

/* Invalid state is never signalled by colour alone — pair with .form-error. */
.form-input[aria-invalid="true"],
.form-textarea[aria-invalid="true"],
.form-select[aria-invalid="true"] {
	border-color: var(--color-danger);
}

.form-input[disabled],
.form-textarea[disabled],
.form-select[disabled] {
	background-color: var(--color-bg-alt);
	color: var(--color-text-light);
	cursor: not-allowed;
}

/* Checkbox and radio */
.form-check {
	display: flex;
	align-items: flex-start;
	gap: var(--space-3);
	min-block-size: var(--target-min);
}

.form-check__input {
	inline-size: var(--target-min);
	block-size: var(--target-min);
	flex-shrink: 0;
	margin: 0;
	accent-color: var(--color-primary);
	cursor: pointer;
}

.form-check__label {
	cursor: pointer;
}

.form-help {
	color: var(--color-text-light);
	font-size: var(--text-sm);
}

.form-error {
	display: flex;
	align-items: center;
	gap: var(--space-2);
	color: var(--color-danger);
	font-size: var(--text-sm);
	font-weight: var(--weight-medium);
}

/*
 * Success text uses --color-text, not --color-success: at 4.4:1 the green
 * clears AA for large text and UI boundaries but not for body copy at this
 * size. The green carries the icon and border, where the 3:1 bar applies.
 */
.form-success {
	display: flex;
	align-items: center;
	gap: var(--space-2);
	color: var(--color-text);
	font-size: var(--text-sm);
	font-weight: var(--weight-medium);
}

.form-success .icon {
	color: var(--color-success);
}

fieldset {
	padding: 0;
	border: 0;
}

legend {
	padding: 0;
	font-weight: var(--weight-semibold);
}

/* ===============================================================
 * Notices
 * =============================================================== */
.notice {
	padding: var(--space-4) var(--space-5);
	border-inline-start: 3px solid var(--color-border-strong);
	border-radius: var(--radius-sm);
	background-color: var(--color-bg-alt);
}

.notice--success {
	border-inline-start-color: var(--color-success);
}

.notice--error {
	border-inline-start-color: var(--color-danger);
}

/* ===============================================================
 * Tables — content tables produced by the editor
 * =============================================================== */
table {
	inline-size: 100%;
	border-collapse: collapse;
}

th,
td {
	padding: var(--space-3) var(--space-4);
	border-block-end: var(--border-width) solid var(--color-border);
	text-align: start;
}

th {
	font-weight: var(--weight-semibold);
}

/* ===============================================================
 * Pagination — output by the_posts_pagination() and wp_link_pages()
 * =============================================================== */
.pagination .nav-links,
.page-links {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--space-2);
}

.pagination .page-numbers,
.page-links a,
.page-links > span {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-inline-size: var(--target-comfortable);
	min-block-size: var(--target-comfortable);
	padding-inline: var(--space-3);
	border: var(--border-width) solid var(--color-border);
	border-radius: var(--radius-sm);
	text-decoration: none;
}

.pagination .page-numbers.current,
.page-links > span {
	background-color: var(--color-primary);
	border-color: var(--color-primary);
	color: var(--color-on-primary);
	font-weight: var(--weight-semibold);
}


/* ===============================================================
 * Site header — glass, sticky, three-column
 *
 * Mobile-first: navigation hidden, toggle shown. responsive.css swaps that at
 * 1024px and retunes the metric tokens per tier.
 *
 * SPACE BUDGET. The locked primary navigation has eight top-level items, four
 * of which carry a chevron. Fitting that beside the logo, language switcher
 * and CTA at 1024px is what drives --nav-font-size, --nav-gap and
 * --logo-max-width. Enlarging any of them, or adding a ninth menu item, will
 * push the navigation into a second row. Re-measure before changing them.
 * =============================================================== */

/*
 * Zero-height marker in normal flow, directly above the sticky header. When it
 * scrolls out of view the script adds --scrolled. Observing this element with
 * an IntersectionObserver avoids a scroll listener entirely.
 */
.site-header__sentinel {
	block-size: 1px;
	margin-block-end: -1px;
	pointer-events: none;
}

.site-header {
	position: relative;
	z-index: var(--z-sticky);
	background-color: var(--header-bg);
	border-block-end: var(--border-width) solid var(--header-border);
}

.site-header--sticky {
	position: sticky;
	inset-block-start: 0;
}

/*
 * Glass. Applied only where supported, so browsers without backdrop-filter
 * keep a solid legible bar rather than a washed-out one.
 */
@supports ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
	.site-header {
		-webkit-backdrop-filter: blur(var(--header-blur)) saturate(var(--header-saturate));
		backdrop-filter: blur(var(--header-blur)) saturate(var(--header-saturate));
	}
}

/* Respect a stated preference for reduced transparency. */
@media (prefers-reduced-transparency: reduce) {
	.site-header {
		background-color: var(--header-bg-opaque);
		-webkit-backdrop-filter: none;
		backdrop-filter: none;
	}
}

.site-header--scrolled {
	box-shadow: var(--header-shadow-scrolled);
}

/*
 * Three columns: brand, navigation, actions. The centre track absorbs the
 * remaining space so the navigation is optically centred regardless of how
 * wide the brand and actions become.
 */
.site-header__inner {
	display: grid;
	grid-template-columns: auto 1fr auto;
	align-items: center;
	gap: var(--space-4);
	min-block-size: var(--header-height);
}

.site-header__actions {
	display: flex;
	align-items: center;
	justify-content: flex-end;
	gap: var(--space-2);
}

/* ---------------------------------------------------------------
 * Branding
 * --------------------------------------------------------------- */
.site-branding {
	display: flex;
	align-items: center;
	min-inline-size: 0;
}

.site-branding .custom-logo-link {
	display: flex;
	align-items: center;
	text-decoration: none;
}

.site-branding .custom-logo {
	inline-size: auto;
	max-block-size: var(--logo-max-height);
	max-inline-size: var(--logo-max-width);
	object-fit: contain;
}

.site-branding__title {
	font-size: var(--text-lg);
	font-weight: var(--weight-extrabold);
	line-height: var(--leading-tight);
	letter-spacing: var(--tracking-tight);
	white-space: nowrap;
}

/* Serves both the bundled-logo link and the site-title link. */
.site-branding__link {
	display: inline-flex;
	align-items: center;
	color: var(--color-text);
}

.site-branding__link:hover {
	color: var(--color-primary);
}

/* ---------------------------------------------------------------
 * Primary navigation
 * --------------------------------------------------------------- */
.site-nav {
	display: none;
	justify-self: center;
	min-inline-size: 0;
}

.site-nav__list {
	display: flex;
	align-items: center;
	gap: var(--nav-gap);
	padding: 0;
	margin: 0;
	list-style: none;
}

/* Cancels the prose list rhythm from typography.css. */
.site-nav__list li + li {
	margin-block-start: 0;
}

/* Positioning context for the dropdown panel and the active underline. */
.site-nav__list > li {
	position: relative;
}

/*
 * NO UNDERLINE ON NAVIGATION. `a` is underlined globally at the top of this file,
 * which is right for links inside prose and wrong for a navigation bar — underlined
 * menu items read as body copy and fight the pill states below. This is the opt-out;
 * without it every top-level item was underlined, including the current one.
 *
 * The states are carried by a pill instead: surface, colour and weight, plus a ring
 * on the exact current page. Three distinguishable states, none of them relying on
 * colour alone, none of them changing the box — so opening a panel repaints a
 * background and nothing reflows.
 */
.site-nav__link {
	position: relative;
	display: inline-flex;
	align-items: center;
	gap: var(--space-1);
	min-block-size: var(--target-min);
	padding: var(--nav-link-padding-block) var(--nav-link-padding-inline);
	border-radius: var(--radius-pill);
	color: var(--color-text);
	font-size: var(--nav-font-size);
	font-weight: var(--weight-medium);
	text-decoration: none;
	white-space: nowrap;
}

/*
 * Hover and keyboard focus read the same, because they mean the same thing. The
 * surface is what moves; the label only warms towards the brand colour so a
 * pointer travelling the bar does not strobe.
 */
.site-nav__link:hover,
.site-nav__link:focus-visible {
	background-color: color-mix(in srgb, var(--color-primary) 10%, var(--color-bg));
	color: var(--color-primary);
}

/*
 * The current section — a visitor on a child page still sees which section they are
 * in. Signalled by surface, colour and weight together, never by colour alone.
 */
.site-nav__link--section,
.site-nav__item--mega > .site-nav__link[aria-expanded="true"] {
	background-color: color-mix(in srgb, var(--color-primary) 12%, var(--color-bg));
	color: var(--color-primary);
	font-weight: var(--weight-semibold);
}

/*
 * The exact current page takes the same pill plus a hairline ring. An inset shadow
 * rather than a border, so the ring costs no layout and the label never shifts by a
 * pixel between states — which is what an underline, or a border, would have done.
 */
.site-nav__link[aria-current="page"] {
	background-color: color-mix(in srgb, var(--color-primary) 12%, var(--color-bg));
	box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--color-primary) 28%, transparent);
	color: var(--color-primary);
	font-weight: var(--weight-semibold);
}

/*
 * Chevron on items with children. Decorative: the accessible name and the
 * expanded state belong to the control that owns them — the parent link on
 * desktop, the disclosure button in the drawer.
 *
 * It points downward in both writing directions, so it is deliberately not
 * mirrored under RTL; only inline-pointing icons use .icon--directional.
 */
.site-nav__chevron {
	inline-size: var(--nav-chevron-size);
	block-size: var(--nav-chevron-size);
	flex-shrink: 0;
	fill: none;
	stroke: currentColor;
	stroke-width: 2.5;
	stroke-linecap: round;
	stroke-linejoin: round;
}

/* ---------------------------------------------------------------
 * Dropdown panel
 *
 * Position and skin only. The reveal is driven by .is-open, applied by the
 * script; the transition lives in animations.css.
 * inset-inline-start flips the alignment automatically under RTL.
 * --------------------------------------------------------------- */
.site-nav__list .sub-menu {
	/*
	 * visibility, not display: display cannot be transitioned, so the reveal in
	 * animations.css would snap. visibility keeps descendants out of the tab
	 * order exactly as display:none did, and the panel is absolutely positioned
	 * so it still costs no layout.
	 */
	visibility: hidden;
	pointer-events: none;
	position: absolute;
	inset-block-start: calc(100% + var(--dropdown-offset));
	inset-inline-start: 0;
	z-index: var(--z-dropdown);
	min-inline-size: 240px;
	padding: var(--space-2);
	margin: 0;
	border: var(--border-width) solid var(--color-border);
	border-radius: var(--dropdown-radius);
	background-color: var(--dropdown-bg);
	box-shadow: var(--dropdown-shadow);
	list-style: none;
}

.site-nav__list .sub-menu li + li {
	margin-block-start: 0;
}

/*
 * ⚠ `white-space: nowrap` HERE IS FOR THE PLAIN 240px DROPDOWN, WHERE A ROW IS ONE
 * SHORT LABEL AND WRAPPING IT WOULD LOOK BROKEN. It is **not** right for a mega panel,
 * whose rows carry a title and a description — and a mega item is an `<a>` inside a
 * `.sub-menu`, so it inherits this rule. `.site-nav__list .mega-panel a` restores
 * normal wrapping further down this file; keep the two together if either changes.
 */
.site-nav__list .sub-menu a {
	display: block;
	padding: var(--space-2) var(--space-3);
	border-radius: var(--radius-sm);
	color: var(--color-text);
	font-size: var(--text-sm);
	text-decoration: none;
	white-space: nowrap;
}

.site-nav__list .sub-menu a:hover {
	background-color: var(--color-bg-alt);
	color: var(--color-primary);
}

/* ---------------------------------------------------------------
 * Language switcher (placeholder)
 * --------------------------------------------------------------- */
.lang-switcher {
	display: none;
	align-items: center;
	gap: var(--space-1);
	padding: var(--nav-link-padding-block) var(--space-2);
	border-radius: var(--radius-sm);
	color: var(--color-text-light);
	font-size: var(--text-sm);
	font-weight: var(--weight-semibold);
}

.lang-switcher__chevron {
	inline-size: var(--nav-chevron-size);
	block-size: var(--nav-chevron-size);
	flex-shrink: 0;
	fill: none;
	stroke: currentColor;
	stroke-width: 2.5;
	stroke-linecap: round;
	stroke-linejoin: round;
}

/* ---------------------------------------------------------------
 * CTA
 *
 * Overrides .btn's medium shadow: at header scale a heavy drop shadow reads
 * as clutter. The restrained brand glow appears on hover instead.
 * --------------------------------------------------------------- */
.site-header__cta {
	padding-inline: var(--space-5);
	font-size: var(--text-sm);
	white-space: nowrap;
	box-shadow: none;
}

/* ---------------------------------------------------------------
 * Mobile toggle
 *
 * Drawn in CSS rather than swapped between two icons, so the bars can morph
 * into a close mark from a single element. The transform lives in
 * animations.css and keys off aria-expanded, so the script only flips the
 * attribute.
 * --------------------------------------------------------------- */
.menu-toggle {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	inline-size: var(--target-comfortable);
	block-size: var(--target-comfortable);
	padding: 0;
	border: var(--border-width) solid var(--color-border);
	border-radius: var(--radius-sm);
	background-color: transparent;
	color: var(--color-text);
	cursor: pointer;
}

.menu-toggle:hover {
	border-color: var(--color-primary);
	color: var(--color-primary);
}

.menu-toggle__bars,
.menu-toggle__bars::before,
.menu-toggle__bars::after {
	display: block;
	inline-size: 18px;
	block-size: 2px;
	border-radius: var(--radius-pill);
	background-color: currentColor;
}

.menu-toggle__bars {
	position: relative;
}

.menu-toggle__bars::before,
.menu-toggle__bars::after {
	content: "";
	position: absolute;
	inset-inline-start: 0;
}

.menu-toggle__bars::before {
	inset-block-start: -6px;
}

.menu-toggle__bars::after {
	inset-block-start: 6px;
}

/* ---------------------------------------------------------------
 * Overlay and drawer
 *
 * One container supports both presentations, selectable without markup changes:
 *   default              slide-out drawer from the inline-end edge
 *   .site-drawer--panel  slide-down panel beneath the header
 *
 * Both are inert until 2.3 — [hidden] keeps them out of the accessibility
 * tree and the tab order.
 * --------------------------------------------------------------- */
.site-overlay {
	position: fixed;
	inset: 0;
	z-index: var(--z-overlay);
	background-color: rgba(15, 23, 42, 0.45);
	-webkit-backdrop-filter: blur(2px);
	backdrop-filter: blur(2px);
}

/*
 * A branded surface, not a white sheet. The wash is the hero visual's gradient
 * technique at panel scale — two soft brand tints over the page background — so it
 * costs no image, no request and no extra element. The links keep their own contrast
 * because the tints stay under 6%.
 *
 * The gap tightened from --space-6 to --space-4: with a logo at the top and the
 * actions at the bottom, 24px between three blocks left the drawer looking padded
 * rather than composed. The rows inside keep their own rhythm.
 */
.site-drawer {
	position: fixed;
	inset-block: 0;
	inset-inline-end: 0;
	z-index: var(--z-modal);
	inline-size: var(--drawer-width);
	padding: var(--space-5) var(--space-5) var(--space-6);
	overflow-y: auto;
	overscroll-behavior: contain;
	background-color: var(--color-bg);
	background-image:
		radial-gradient(120% 60% at 100% 0%, color-mix(in srgb, var(--color-primary) 7%, transparent) 0%, transparent 60%),
		radial-gradient(90% 50% at 0% 100%, color-mix(in srgb, var(--color-secondary) 5%, transparent) 0%, transparent 65%);
	background-repeat: no-repeat;
	background-attachment: local;
	border-start-start-radius: var(--radius-lg);
	border-end-start-radius: var(--radius-lg);
	box-shadow: var(--shadow-md);

	/* Column layout so the footer settles at the bottom of the panel. */
	display: flex;
	flex-direction: column;
	gap: var(--space-4);
}

.site-drawer--panel {
	inset-block: var(--header-height) auto;
	inset-inline: 0;
	inline-size: auto;
	max-block-size: calc(100dvh - var(--header-height));
	border-radius: 0 0 var(--radius-lg) var(--radius-lg);
}

/*
 * [hidden] must beat the layout rules above, or the containers would paint
 * while still marked hidden to assistive technology.
 */
.site-overlay[hidden],
.site-drawer[hidden] {
	display: none;
}

/* ===============================================================
 * Drawer contents
 * =============================================================== */

/*
 * Scroll lock. The reserved inline padding replaces the width the vanishing
 * scrollbar frees, so locking does not shift the page sideways. The script sets
 * --scrollbar-compensation and clears it on close.
 */
.is-menu-open {
	overflow: hidden;
	padding-inline-end: var(--scrollbar-compensation, 0);
}

/*
 * Logo and close control on one row. space-between rather than flex-end, because the
 * row now has two things in it; the divider beneath separates the brand from the
 * navigation without adding a second panel surface.
 */
.site-drawer__top {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--space-3);
	padding-block-end: var(--space-3);
	border-block-end: var(--border-width) solid var(--color-border);
}

.site-drawer__brand {
	display: inline-flex;
	align-items: center;
	min-inline-size: 0;
	text-decoration: none;
}

/*
 * Sized by height so the horizontal lockup keeps its ratio in a 320px drawer, with
 * the intrinsic width/height on the <img> reserving the box before the SVG loads —
 * no layout shift when the drawer opens.
 */
.site-drawer__logo {
	inline-size: auto;
	block-size: 28px;
	max-inline-size: 100%;
}

.site-drawer__brand--text {
	color: var(--color-text);
	font-weight: var(--weight-bold);
}

/* Mirrors .menu-toggle's box so the two controls read as a pair. */
.site-drawer__close {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	inline-size: var(--target-comfortable);
	block-size: var(--target-comfortable);
	padding: 0;
	border: var(--border-width) solid var(--color-border);
	border-radius: var(--radius-sm);
	background-color: transparent;
	color: var(--color-text);
	cursor: pointer;
}

.site-drawer__close:hover {
	border-color: var(--color-primary);
	color: var(--color-primary);
}

.site-drawer__nav {
	flex: 1;
}

.site-drawer__list {
	display: flex;
	flex-direction: column;
	gap: var(--space-1);
	padding: 0;
	margin: 0;
	list-style: none;
}

/* Cancels the prose list rhythm from typography.css. */
.site-drawer__list li + li {
	margin-block-start: 0;
}

/*
 * Full-width rows. The link keeps .site-nav__link so it inherits the colour,
 * hover and transition already defined for navigation links — space-between
 * pushes the inherited chevron to the inline-end edge, where the accordion in
 * the accordion needs it.
 */
.site-drawer__list .site-nav__link {
	display: flex;
	align-items: center;
	justify-content: space-between;
	min-block-size: var(--target-comfortable);
	padding: var(--space-3);
	border-radius: var(--radius-sm);
	font-size: var(--text-base);
	white-space: normal;

	/*
	 * Takes the remaining width so the disclosure button sits beside it rather
	 * than being pushed onto its own line.
	 */
	flex: 1 1 auto;
	min-inline-size: 0;
}

/*
 * Rows with children hold a link and a disclosure button side by side, with the
 * submenu wrapping onto the line beneath them.
 */
.site-drawer__list > li {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
}

/* ---------------------------------------------------------------
 * Drawer disclosure button
 *
 * A button, not the link: the parent items are real pages, so the link has to
 * stay navigable. The chevron is moved into this button by the script, which
 * also means the control only exists when it can actually be operated.
 * --------------------------------------------------------------- */
.site-drawer__disclosure {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	flex-shrink: 0;
	inline-size: var(--target-comfortable);
	block-size: var(--target-comfortable);
	padding: 0;
	border: 0;
	border-radius: var(--radius-sm);
	background-color: transparent;
	color: var(--color-text);
	cursor: pointer;
}

.site-drawer__disclosure:hover {
	background-color: var(--color-bg-alt);
	color: var(--color-primary);
}

/*
 * The rule that used to sit here cancelled the desktop active underline for drawer
 * rows. The underline is gone — navigation now signals state with a pill and a ring —
 * so cancelling it was dead CSS. The drawer rows inherit the ring, which reads
 * correctly against their own square-cornered surface.
 */

/* ---------------------------------------------------------------
 * Drawer accordion panel
 *
 * Collapsed with max-block-size rather than display:none so the open and close
 * can animate. The script measures scrollHeight and publishes it as
 * --mw-panel-height, so the transition runs to the panel's real height instead
 * of a guessed maximum.
 *
 * visibility keeps the collapsed links out of the tab order — overflow:hidden
 * alone would still leave them focusable and scroll the panel into view.
 * --------------------------------------------------------------- */
.site-drawer__list .sub-menu {
	flex-basis: 100%;
	overflow: hidden;
	max-block-size: 0;
	visibility: hidden;
	opacity: 0;
	padding-inline-start: var(--space-4);
	margin: 0;
	list-style: none;
}

.site-drawer__list .sub-menu.is-open {
	max-block-size: var(--mw-panel-height, 40rem);
	visibility: visible;
	opacity: 1;
}

.site-drawer__list .sub-menu a {
	display: block;
	min-block-size: var(--target-comfortable);
	padding: var(--space-3);
	border-radius: var(--radius-sm);
	color: var(--color-text);
	font-size: var(--text-sm);
	text-decoration: none;
}

.site-drawer__list .sub-menu a:hover {
	background-color: var(--color-bg-alt);
	color: var(--color-primary);
}

.site-drawer__foot {
	display: flex;
	flex-direction: column;
	gap: var(--space-4);
	padding-block-start: var(--space-4);
	border-block-start: var(--border-width) solid var(--color-border);
}

/*
 * The language switcher is hidden in the header below 1280px, so the drawer is
 * the only place it is reachable at drawer widths.
 */
.site-drawer .lang-switcher {
	display: flex;
	align-self: flex-start;
}



/* ---------------------------------------------------------------
 * Bundled logo
 *
 * block-size is deliberately definite. These logos are SVGs with a viewBox but
 * no width/height, so their only intrinsic contribution is an aspect ratio —
 * with height:auto the image sat in a shrink-to-fit chain (flex link inside
 * flex .site-branding inside an auto grid track) where its size depended on the
 * container and the container's on it, and the cycle resolved to zero. Do not
 * change this back to a max-height-only cap.
 *
 * Both logo tiers read the same --logo-max-* tokens as .custom-logo, so the
 * measured header budget holds whichever tier renders. max-inline-size clamps
 * the width to that budget; object-fit letterboxes a wide lockup rather than
 * letting it push the navigation.
 * --------------------------------------------------------------- */
.site-branding__logo {
	display: block;
	block-size: var(--logo-max-height);
	inline-size: auto;
	max-block-size: var(--logo-max-height);
	max-inline-size: var(--logo-max-width);
	object-fit: contain;
}

/* ===============================================================
 * Breadcrumbs
 *
 * A thin band between the header and the page's first section. No .section here:
 * the locked section rhythm is for content bands, and 96px of padding around one
 * line of 14px text would read as a gap rather than as orientation.
 *
 * Logical properties and a flex row, so RTL reverses it with no separate rule; the
 * chevron mirrors through .icon--directional.
 * =============================================================== */
.breadcrumbs {
	padding-block: var(--space-4);
	font-size: var(--text-sm);
}

.breadcrumbs__list {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--space-2);
}

.breadcrumbs__item {
	display: flex;
	align-items: center;
	gap: var(--space-2);
}

/*
 * Padding rather than a min-height, so the link's own box grows: at 14px the text
 * alone gives a 22px target, which clears WCAG 2.2 §2.5.8 only through the spacing
 * exception. Reaching 24px directly means the rule is satisfied outright rather than
 * by an argument about how far apart the circles are.
 */
.breadcrumbs__list a {
	padding-block: var(--space-1);
}

/*
 * A contact detail's link occupies its whole line rather than sitting inside a
 * sentence, so it takes the same treatment as the breadcrumb links: enough vertical
 * padding to clear the 24px target minimum without relying on the inline exception.
 */
.contact-details__link {
	display: inline-block;
	padding-block: var(--space-1);
}

.breadcrumbs__separator {
	color: var(--color-text-light);
}

.breadcrumbs__current {
	color: var(--color-text-light);
}

/* ===============================================================
 * Homepage hero
 *
 * Layout only. Spacing comes from .section, width from .container, rhythm from
 * .stack, the button row from .cluster and the copy from .lead — nothing here
 * restates a value the design system already owns.
 *
 * Mobile-first: one column, visual beneath the copy. responsive.css opens it
 * into two columns at the desktop breakpoint.
 * =============================================================== */
.hero__inner {
	display: grid;
	gap: var(--grid-gap);
	grid-template-columns: 1fr;
	align-items: center;
}

/*
 * Hero with no visual slot. Higher specificity than the two-column rule
 * responsive.css sets at the desktop breakpoint, so it wins at every width without
 * a media query of its own — and the copy keeps the locked reading measure instead
 * of stretching across the full 1280px container.
 */
.hero--plain .hero__inner {
	grid-template-columns: 1fr;
}

.hero--plain .hero__content {
	max-inline-size: var(--content-max);
}

/*
 * Uses the display step of the type scale, which responsive.css already
 * enlarges at each tier — including the 1280px tier, whose step had no
 * consumer until now.
 */
.hero__title {
	font-size: var(--text-5xl);
	font-weight: var(--weight-extrabold);
	letter-spacing: var(--tracking-tight);
	line-height: var(--leading-tight);
}

.hero__actions {
	gap: var(--space-3);
}

/* ---------------------------------------------------------------
 * Trust indicators
 *
 * Reassurance, not statistics — the Trust Metrics section is separate and
 * later. A list because it is a list; the marker is replaced by the icon.
 * --------------------------------------------------------------- */
.hero__trust {
	display: flex;
	flex-wrap: wrap;
	gap: var(--space-3) var(--space-6);
	padding: 0;
	margin: 0;
	list-style: none;
	color: var(--color-text-light);
	font-size: var(--text-sm);
}

.hero__trust-item {
	display: flex;
	align-items: center;
	gap: var(--space-2);
	margin-block-start: 0;
}

/*
 * --color-success, not --color-secondary: the brand green is 2.74:1 and fails
 * the 3:1 non-text bar, so it cannot carry an icon that conveys meaning.
 */
.hero__trust-icon {
	color: var(--color-success);
}

/* ---------------------------------------------------------------
 * Visual area
 *
 * A fixed ratio box so the column reserves its space before any asset loads —
 * zero layout shift whether the slot ends up holding an image, an SVG or the
 * fallback. 16px radius is the locked hero-card radius.
 * --------------------------------------------------------------- */
.hero__visual {
	position: relative;
	overflow: hidden;
	aspect-ratio: 4 / 3;
	border: var(--border-width) solid var(--color-border);
	border-radius: var(--radius-lg);
	background-color: var(--color-bg-alt);
	box-shadow: var(--shadow-md);
}

.hero__image {
	inline-size: 100%;
	block-size: 100%;
	object-fit: cover;
}

/*
 * Fallback panel: two soft brand washes over the alt surface. Pure CSS, so it
 * costs no request and cannot shift the layout. This is the one place
 * --color-secondary is correct — purely decorative, conveying nothing.
 */
.hero__visual-fallback {
	position: absolute;
	inset: 0;
	background-image:
		radial-gradient(60% 60% at 78% 22%, color-mix(in srgb, var(--color-secondary) 20%, transparent), transparent 70%),
		radial-gradient(70% 70% at 20% 80%, color-mix(in srgb, var(--color-primary) 22%, transparent), transparent 70%);
}

/* ---------------------------------------------------------------
 * Trust metrics
 *
 * Layout, spacing and card chrome all come from existing classes — .section,
 * .container, .stack, .grid--n, .card, .card__title, .card__text and
 * .list-plain. The only thing the section owns is the icon colour.
 * --------------------------------------------------------------- */
.trust-metrics__icon {
	color: var(--color-primary);
}

/* ---------------------------------------------------------------
 * Hiring process
 *
 * No timeline system: the steps are .card in .grid, exactly like trust
 * metrics. The only additions are the numbered marker and its row.
 *
 * The number comes from a CSS counter on the ordered list, so the sequence
 * lives in one place — the markup order — and no step number has to be
 * written into the content.
 * --------------------------------------------------------------- */
.hiring-process__list {
	counter-reset: mw-step;
}

.hiring-process__step {
	counter-increment: mw-step;
}

.hiring-process__marker {
	display: flex;
	align-items: center;
	gap: var(--space-3);
	color: var(--color-primary);
}

.hiring-process__marker::before {
	content: counter(mw-step);
	display: inline-flex;
	align-items: center;
	justify-content: center;
	flex-shrink: 0;
	inline-size: var(--space-8);
	block-size: var(--space-8);
	border-radius: var(--radius-pill);
	background-color: var(--color-primary);
	color: var(--color-on-primary);
	font-size: var(--text-sm);
	font-weight: var(--weight-bold);
	line-height: 1;
}

/*
 * Linked-card affordance. margin-block-start:auto pins it to the bottom of the
 * card so the affordance lines up across a row whatever the description length.
 * Colour and weight come from the .text-primary and .font-semibold utilities.
 */
.link-cards__cta {
	display: flex;
	align-items: center;
	gap: var(--space-2);
	margin-block-start: auto;
	padding-block-start: var(--space-2);
}

/*
 * Scroller track — the second layout of the one card grid, not a second grid.
 *
 * Native overflow scrolling, so it works with a swipe, a trackpad, a wheel and the
 * scrollbar before any script loads. Scroll snapping makes a manual flick land on a
 * card edge rather than mid-card, and makes the scripted advance land there too.
 *
 * Logical properties throughout: `overflow-inline` is not usable yet, but the flex
 * row, the snap axis and the padding all follow the writing direction, so RTL
 * reverses the strip with no separate rule.
 */
.link-cards__track {
	display: flex;
	gap: var(--grid-gap);
	overflow-x: auto;
	scroll-snap-type: x mandatory;
	/*
	 * Room for the card lift and its focus ring. Without it the hover transform and
	 * the outline are clipped by the scroll container's own edges.
	 */
	padding-block: var(--space-1);
	padding-inline: var(--space-1);
	margin-inline: calc(var(--space-1) * -1);
}

.link-cards__track > .card {
	/*
	 * A fixed basis rather than a fraction: the strip must show part of the next card
	 * so its scrollability is visible without a scrollbar. min() keeps a single card
	 * from exceeding a narrow viewport.
	 */
	flex: 0 0 min(300px, 78%);
	scroll-snap-align: start;
}

.scroller__controls {
	gap: var(--space-2);
}

/* ---------------------------------------------------------------
 * FAQ
 *
 * A native <details> disclosure wearing the existing card chrome — no panel
 * system, no script and no second surface.
 *
 * The summary keeps its native focus ring from base.css and its native
 * keyboard operability; nothing here is a substitute for either.
 * --------------------------------------------------------------- */

/*
 * The one thing .card must not give a <details> is its layout. A details
 * element whose display is flex lays the answer out as a flex item and keeps
 * painting it while the disclosure is closed — measured at 67px tall with
 * open=false, overlapping the content beneath. Restoring block display hands
 * layout back to the element, which is the only thing that knows how to hide
 * its own collapsed content. Everything else .card brings — border, radius,
 * padding, shadow — is inherited untouched.
 */
.faq__item {
	display: block;
}

.faq__question {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--space-4);
	min-block-size: var(--target-min);
	cursor: pointer;

	/* Retires the native triangle — both the standard and the WebKit marker. */
	list-style: none;
}

.faq__question::-webkit-details-marker {
	display: none;
}

/*
 * The chevron points downward in both writing directions, so it is deliberately
 * not mirrored under RTL; only inline-pointing icons use .icon--directional.
 * Its rotation on open lives in animations.css with the other chevron.
 */
.faq__chevron {
	color: var(--color-primary);
}

.faq__answer {
	padding-block-start: var(--space-4);
}

/* ---------------------------------------------------------------
 * Mega menu
 *
 * A richer panel inside the dropdown model the theme already had. The reveal,
 * hover intent, keyboard handling and focus management are unchanged — only the
 * panel's contents and width are new, which is why Phase 11 added no JavaScript.
 *
 * The <li> goes position:static so the panel's containing block becomes
 * .site-header, letting it span the full header width. The active underline moved
 * onto .site-nav__link for the same reason.
 * --------------------------------------------------------------- */
/*
 * Two classes, to outrank `.site-nav__list > li { position: relative }` above.
 * Going static hands the panel's containing block to .site-header, which is what
 * lets it span the full width instead of the width of one navigation item.
 */
.site-nav__list > .site-nav__item--mega {
	position: static;
}

/*
 * Same specificity as .site-nav__list .sub-menu and declared after it, so these win
 * without raising specificity — the ordering rule at the top of this file.
 */
.site-nav__list .mega-panel {
	inset-block-start: 100%;
	inset-inline: 0;
	min-inline-size: 0;
	padding: 0;
	border-inline: 0;
	border-block-start: 0;
	border-end-start-radius: var(--radius-lg);
	border-end-end-radius: var(--radius-lg);
	border-start-start-radius: 0;
	border-start-end-radius: 0;
}

/*
 * ⚠ THE ROOT CAUSE OF THE OVERLAPPING DESCRIPTIONS, AND THE ONE LINE THAT FIXES THEM.
 *
 * A mega item is an `<a>` inside a `.sub-menu`, so it inherited
 * `.site-nav__list .sub-menu a { white-space: nowrap }` — written for the plain 240px
 * dropdown, where a row is one short label. A description can therefore never wrap: the
 * *box* stays inside its 348px column, because the grid constrains it, while the *ink*
 * runs on in a single line straight over the next column and under the promotional
 * panel. Measured before this rule: France's description was 862px of text in a 348px
 * box — 514px of overflow — and all five panels were affected, worst first: Countries
 * 8 rows, Industries 6, Employers 3, Candidates 2, Resources 1.
 *
 * That is also why a box-based overlap check reported nothing wrong. Bounding boxes
 * were correct throughout; only the painted text escaped. Measure `scrollWidth` against
 * `clientWidth` to see it.
 *
 * Same specificity as the rule it overrides and declared after it, which is this file's
 * stated convention — see the note at the top. It reaches every link in every panel, so
 * it applies to menus that do not exist yet without anyone remembering to opt in.
 */
.site-nav__list .mega-panel a {
	white-space: normal;
}

.mega-panel__inner {
	display: grid;
	grid-template-columns: 1fr;
	gap: var(--space-10);
	padding-block: var(--space-8);
}

.mega-panel__groups {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: var(--space-10);
}

.mega-group__heading {
	margin-block-end: var(--space-4);
	color: var(--color-text-light);
	font-size: var(--text-sm);
	font-weight: var(--weight-bold);
	letter-spacing: 0.06em;
	text-transform: uppercase;
}

/*
 * ⚠ minmax(0, 1fr) IS LOAD-BEARING — without it the descriptions overlap the next
 * column. A grid with no explicit column gets one implicit column sized `auto`, which
 * resolves to **max-content**: the longest destination description made the column
 * 886px wide inside a 367px group, so France's text painted straight over Romania's
 * card. The items were never wrapping because they were never asked to.
 *
 * `minmax(0, 1fr)` lets the column shrink below its content and the text wraps. It is
 * the standard fix for grid blowout and it applies to every panel, not just Countries.
 */
.mega-group__list {
	display: grid;
	grid-template-columns: minmax(0, 1fr);
	gap: var(--space-2);
}

/*
 * The whole row is the target, so it carries the padding and the hover surface
 * rather than the text inside it.
 */
.mega-item {
	display: flex;
	align-items: flex-start;
	gap: var(--space-3);
	min-block-size: var(--target-comfortable);
	padding: var(--space-3) var(--space-4);
	border-radius: var(--radius-md);
	color: var(--color-text);
	text-decoration: none;
}

.mega-item:hover {
	background-color: color-mix(in srgb, var(--color-primary) 8%, var(--color-bg));
	color: var(--color-text);
}

.mega-item__figure {
	display: flex;
	align-items: center;
	justify-content: center;
	flex-shrink: 0;
	inline-size: var(--space-10);
	block-size: var(--space-10);
	border-radius: var(--radius-sm);
	background-color: var(--color-bg-alt);
	color: var(--color-primary);
}

.mega-item:hover .mega-item__figure {
	background-color: var(--color-primary);
	color: var(--color-on-primary);
}

/* Stands in for flag artwork, as on the destination cards. */
.mega-item__badge {
	font-size: var(--text-sm);
	font-weight: var(--weight-bold);
	letter-spacing: 0.02em;
}

/*
 * `min-inline-size: 0` lets this shrink below its content, which a flex item will not
 * do by default — without it the body would push the row wider than its column.
 *
 * `overflow-wrap: break-word` is the guard for the one case wrapping cannot solve on
 * its own: a single token longer than the column. Normal wrapping breaks at spaces, so
 * a German compound, a long sector name from a translation, or a URL an editor pastes
 * would still overflow. This makes the break happen inside the word instead, which is
 * the difference between an awkward line and text painted over the next card. Required
 * by the brief's "must work for translated content and future CMS content".
 *
 * `flex: 1` so the body claims the space left by the icon rather than sizing to its
 * text, which keeps every row's wrap point identical down a column.
 */
.mega-item__body {
	display: flex;
	flex-direction: column;
	gap: var(--space-1);
	flex: 1 1 auto;
	min-inline-size: 0;
	overflow-wrap: break-word;
}

.mega-item__title {
	font-weight: var(--weight-semibold);
	line-height: var(--leading-tight);
}

.mega-item:hover .mega-item__title {
	color: var(--color-primary);
}

.mega-item__text {
	color: var(--color-text-light);
	font-size: var(--text-sm);
	line-height: 1.5;
}

/*
 * The promotional panel. Brand blue in every section, including Candidates: white on
 * the brand green is roughly 3:1 and fails WCAG 1.4.3 for text at this size, so the
 * green stays a decorative accent as variables.css records.
 */
.mega-promo {
	display: flex;
	flex-direction: column;
	gap: var(--space-3);
	padding: var(--space-6);
	border-radius: var(--radius-lg);
	background-color: var(--color-primary);
	color: var(--color-on-primary);
}

.mega-promo__eyebrow {
	color: var(--color-on-primary);
	font-size: var(--text-sm);
	font-weight: var(--weight-bold);
	letter-spacing: 0.06em;
	opacity: 0.85;
	text-transform: uppercase;
}

.mega-promo__title {
	font-size: var(--text-xl);
	font-weight: var(--weight-bold);
	line-height: var(--leading-tight);
}

.mega-promo__text {
	font-size: var(--text-sm);
	line-height: var(--leading-snug);
	opacity: 0.9;
}

.mega-promo__media {
	position: relative;
	block-size: auto;
	aspect-ratio: 16 / 9;
	margin: 0;
	overflow: hidden;
	border: var(--border-width) solid color-mix(in srgb, var(--color-on-primary) 22%, transparent);
	border-radius: var(--radius-md);
	background-color: color-mix(in srgb, var(--color-on-primary) 8%, transparent);
}

.mega-promo__image,
.mega-promo__placeholder {
	display: block;
	inline-size: 100%;
	block-size: 100%;
	object-fit: cover;
}

.mega-promo__placeholder {
	background-image:
		radial-gradient(75% 100% at 10% 100%, color-mix(in srgb, var(--color-secondary) 60%, transparent), transparent 70%),
		radial-gradient(75% 100% at 100% 0%, color-mix(in srgb, var(--color-on-primary) 20%, transparent), transparent 70%);
}

/* White button on the blue panel — the reverse of .btn--primary. */
.mega-promo__cta {
	align-self: flex-start;
	margin-block-start: auto;
	background-color: var(--color-bg);
	border-color: var(--color-bg);
	color: var(--color-primary);
}

.mega-promo__cta:hover {
	background-color: var(--color-bg-alt);
	border-color: var(--color-bg-alt);
	color: var(--color-primary-hover);
}

/* ---------------------------------------------------------------
 * Language switcher
 *
 * A native <details>, so the control genuinely discloses something without a line
 * of script. .lang-switcher keeps display:block for the reason recorded in the FAQ
 * component: a <details> with a flex display does not hide its collapsed content.
 * --------------------------------------------------------------- */
.lang-switcher {
	position: relative;
	display: none;
}

.lang-switcher__toggle {
	display: flex;
	align-items: center;
	gap: var(--space-1);
	min-block-size: var(--target-comfortable);
	padding-inline: var(--space-2);
	border-radius: var(--radius-sm);
	color: var(--color-text-light);
	font-size: var(--text-sm);
	font-weight: var(--weight-semibold);
	cursor: pointer;
	list-style: none;
}

.lang-switcher__toggle::-webkit-details-marker {
	display: none;
}

.lang-switcher__toggle:hover {
	background-color: color-mix(in srgb, var(--color-primary) 8%, var(--color-bg));
	color: var(--color-primary);
}

.lang-switcher[open] .lang-switcher__toggle {
	background-color: color-mix(in srgb, var(--color-primary) 10%, var(--color-bg));
	color: var(--color-primary);
}

.lang-switcher__panel {
	position: absolute;
	inset-block-start: calc(100% + var(--dropdown-offset));
	inset-inline-end: 0;
	z-index: var(--z-dropdown);
	min-inline-size: 200px;
	padding: var(--space-2);
	border: var(--border-width) solid var(--color-border);
	border-radius: var(--dropdown-radius);
	background-color: var(--dropdown-bg);
	box-shadow: var(--dropdown-shadow);
}

.lang-switcher__option {
	display: flex;
	align-items: center;
	gap: var(--space-3);
	padding: var(--space-2) var(--space-3);
	border-radius: var(--radius-sm);
	color: var(--color-text);
	font-size: var(--text-sm);
	text-decoration: none;
}

a.lang-switcher__option:hover {
	background-color: color-mix(in srgb, var(--color-primary) 8%, var(--color-bg));
	color: var(--color-primary);
}

.lang-switcher__code {
	min-inline-size: 2em;
	color: var(--color-text-light);
	font-weight: var(--weight-bold);
}

.lang-switcher__option.is-current {
	background-color: var(--color-bg-alt);
	font-weight: var(--weight-semibold);
}

/* Not a link yet — see the note in the template. Never styled as one. */
.lang-switcher__option.is-unavailable {
	color: var(--color-text-light);
	cursor: default;
}

.lang-switcher__status {
	margin-inline-start: auto;
	color: var(--color-text-light);
	font-size: var(--text-xs);
	font-weight: var(--weight-medium);
}

/* ---------------------------------------------------------------
 * Drawer actions
 *
 * Conversion first: the CTA, contact and locale sit above the menu rather than
 * below it. The wash is the hero visual's gradient technique at a smaller scale, so
 * it costs no request and no image.
 * --------------------------------------------------------------- */
.site-drawer__actions {
	display: flex;
	flex-direction: column;
	gap: var(--space-3);
	padding: var(--space-4);
	border: var(--border-width) solid var(--color-border);
	border-radius: var(--radius-lg);
	background-image:
		radial-gradient(80% 120% at 100% 0%, color-mix(in srgb, var(--color-secondary) 14%, transparent), transparent 70%),
		radial-gradient(90% 130% at 0% 100%, color-mix(in srgb, var(--color-primary) 16%, transparent), transparent 70%);
}

/* In the drawer the switcher is always available; in the header it is width-gated. */
.site-drawer .lang-switcher {
	display: block;
}

.site-drawer .lang-switcher__toggle {
	justify-content: space-between;
	inline-size: 100%;
	border: var(--border-width) solid var(--color-border);
	background-color: var(--color-bg);
}

.site-drawer .lang-switcher__panel {
	inset-block-end: calc(100% + var(--dropdown-offset));
	inset-block-start: auto;
}

/* ===============================================================
 * Site footer
 *
 * Inverts the palette. The surface tokens are declared on the wrapper rather than
 * in variables.css — that file is locked, and these are component colours, not
 * design tokens the rest of the site consumes.
 * =============================================================== */
.site-footer {
	--footer-bg: #0a1b33;
	--footer-bg-alt: #0d2140;
	--footer-text: rgba(255, 255, 255, 0.78);
	--footer-heading: #ffffff;
	--footer-border: rgba(255, 255, 255, 0.14);

	background-color: var(--footer-bg);
	color: var(--footer-text);
}

.site-footer a {
	color: var(--footer-text);
	text-decoration: none;
}

.site-footer a:hover {
	color: var(--footer-heading);
	text-decoration: underline;
}

.site-footer__heading {
	margin-block-end: var(--space-4);
	color: var(--footer-heading);
	font-size: var(--text-sm);
	font-weight: var(--weight-bold);
	letter-spacing: 0.06em;
	text-transform: uppercase;
}

/* --- Conversion band ------------------------------------------- */
.site-footer__cta {
	background-color: var(--footer-bg-alt);
	border-block-end: var(--border-width) solid var(--footer-border);
}

.site-footer__cta-inner {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: var(--space-6);
	padding-block: var(--space-10);
}

.site-footer__cta-title {
	color: var(--footer-heading);
	font-size: var(--text-2xl);
	font-weight: var(--weight-bold);
	line-height: var(--leading-tight);
}

.site-footer__cta-text {
	color: var(--footer-text);
}

.site-footer__cta-actions {
	gap: var(--space-3);
}

/* --- Brand and columns ----------------------------------------- */
.site-footer__main {
	display: grid;
	grid-template-columns: 1fr;
	gap: var(--space-10);
	padding-block: var(--space-12);
}

.site-footer__intro {
	display: flex;
	flex-direction: column;
	gap: var(--space-4);
	max-inline-size: 34rem;
}

.site-footer__logo {
	display: block;
	inline-size: auto;
	block-size: 44px;
	max-inline-size: 180px;
	object-fit: contain;
	/* The bundled mark is dark; invert it for the dark band. */
	filter: brightness(0) invert(1);
}

.site-footer__tagline {
	color: var(--footer-text);
	font-size: var(--text-sm);
	line-height: var(--leading-relaxed);
}

.site-footer__social {
	display: flex;
	gap: var(--space-2);
}

.site-footer__social-link {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	inline-size: var(--target-comfortable);
	block-size: var(--target-comfortable);
	border: var(--border-width) solid var(--footer-border);
	border-radius: var(--radius-sm);
}

.site-footer__social-link:hover {
	background-color: var(--footer-bg-alt);
	border-color: var(--footer-heading);
}

/*
 * auto-fit, so adding a column is a registry entry and never a redesign. The floor
 * keeps a column readable; the grid wraps rather than crushing them.
 */
.site-footer__columns {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
	gap: var(--space-8);
}

.site-footer__links {
	display: grid;
	gap: var(--space-2);
	font-size: var(--text-sm);
}

/* --- SEO band --------------------------------------------------- */
.site-footer__seo {
	border-block-start: var(--border-width) solid var(--footer-border);
	background-color: var(--footer-bg-alt);
	padding-block: var(--space-10);
}

.site-footer__seo-title {
	margin-block-end: var(--space-6);
	color: var(--footer-heading);
	font-size: var(--text-lg);
	font-weight: var(--weight-bold);
}

.site-footer__seo-groups {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
	gap: var(--space-8);
}

/*
 * Wraps as inline chips rather than stacking: an SEO block is a dense list of
 * phrases, and a single column of thirty links would dominate the footer.
 */
.site-footer__seo-list {
	display: flex;
	flex-wrap: wrap;
	gap: var(--space-2);
	font-size: var(--text-sm);
}

.site-footer__seo-list a {
	display: inline-block;
	padding: var(--space-1) var(--space-3);
	border: var(--border-width) solid var(--footer-border);
	border-radius: var(--radius-pill);
}

.site-footer__seo-list a:hover {
	background-color: var(--footer-bg);
	border-color: var(--footer-heading);
	text-decoration: none;
}

/* --- Bottom bar -------------------------------------------------- */
.site-footer__bottom {
	border-block-start: var(--border-width) solid var(--footer-border);
}

.site-footer__bottom-inner {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: var(--space-3);
	padding-block: var(--space-5);
	font-size: var(--text-sm);
}

.site-footer__locales {
	color: var(--footer-text);
	letter-spacing: 0.08em;
}

/* ---------------------------------------------------------------
 * Media cards — image header, badge, meta and two actions
 *
 * The one card shape the stretched-link grid cannot express, because two real
 * buttons and a link covering the whole card are mutually exclusive. Chrome,
 * radius and border still come from .card; .card--flush removes its padding so
 * the figure can reach the card edge, and the body puts it back.
 *
 * All inset properties are logical, so the badge moves to the opposite corner
 * under RTL without a second rule.
 * --------------------------------------------------------------- */
.media-cards__item {
	overflow: hidden;
}

/*
 * Fixed ratio, so the card reserves the image's space before any asset loads —
 * zero layout shift whether the slot holds a photograph or the fallback.
 */
.media-cards__figure {
	position: relative;
	aspect-ratio: 3 / 2;
	margin: 0;
	overflow: hidden;
	background-color: var(--color-bg-alt);
	border-block-end: var(--border-width) solid var(--color-border);
}

.media-cards__image {
	inline-size: 100%;
	block-size: 100%;
	object-fit: cover;
}

/* Same two brand washes as the hero visual: no request, no bytes. */
.media-cards__placeholder {
	position: absolute;
	inset: 0;
	background-image:
		radial-gradient(60% 60% at 78% 22%, color-mix(in srgb, var(--color-secondary) 20%, transparent), transparent 70%),
		radial-gradient(70% 70% at 20% 80%, color-mix(in srgb, var(--color-primary) 22%, transparent), transparent 70%);
}

.media-cards__badge {
	position: absolute;
	inset-block-start: var(--space-3);
	inset-inline-start: var(--space-3);
	padding: var(--space-1) var(--space-3);
	border-radius: var(--radius-pill);
	background-color: var(--color-bg);
	color: var(--color-text);
	font-size: var(--text-sm);
	font-weight: var(--weight-bold);
	box-shadow: var(--shadow-sm);
}

/* flex:1 lets the actions row reach the bottom of an unevenly filled card. */
.media-cards__body {
	flex: 1;
	padding: var(--space-6);
}

.media-cards__tags {
	display: flex;
	flex-wrap: wrap;
	gap: var(--space-2);
}

.media-cards__tag {
	padding: var(--space-1) var(--space-3);
	border: var(--border-width) solid var(--color-border);
	border-radius: var(--radius-pill);
	background-color: var(--color-bg-alt);
	color: var(--color-text-light);
	font-size: var(--text-sm);
}

/* Pins the buttons to the bottom so they align across a row of cards. */
.media-cards__actions {
	margin-block-start: auto;
	padding-block-start: var(--space-2);
	gap: var(--space-2);
}
