/* ==========================================================================
   Orkla India — base stylesheet
   Reset + base typography + layout primitives. Section-specific CSS is added
   as each section is built from Figma. Tokens come from tokens.css.
   ========================================================================== */

/* ---- Modern reset ------------------------------------------------------- */
*,
*::before,
*::after { box-sizing: border-box; }

* { margin: 0; }

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }

body {
	font-family: var(--ff-body);
	font-size: var(--fs-l2);
	font-weight: var(--fw-regular);
	line-height: var(--lh-base);
	color: var(--c-text);
	background: var(--c-white);
	-webkit-font-smoothing: antialiased;
	-moz-osx-font-smoothing: grayscale;
	text-rendering: optimizeLegibility;
	min-height: 100vh;
	/* Clip the off-canvas mobile drawer so it never adds horizontal scroll /
	   widens the full-bleed header. overflow-x only — vertical scroll stays on
	   the viewport, so the sticky header keeps working. */
	overflow-x: hidden;
}

img,
picture,
svg,
video { display: block; max-width: 100%; height: auto; }

input,
button,
textarea,
select { font: inherit; color: inherit; }

button { cursor: pointer; }

a { color: inherit; text-decoration: none; }
a:hover { text-decoration: underline; }

ul[role="list"],
ol[role="list"] { list-style: none; padding: 0; }

:where(h1, h2, h3, h4, h5, h6) {
	font-family: var(--ff-heading);
	font-weight: var(--fw-bold);
	line-height: var(--lh-heading);
	color: var(--c-text);
}

h1 { font-size: var(--fs-6xl); line-height: var(--lh-tight); letter-spacing: var(--ls-h1); }
/* 60 → 48 sitewide, client instruction 2026-09-08 (corrections item 17: section
   headings are oversized). Repointed to the H3 rung rather than lowering --fs-5xl,
   because that rung is still wanted at 60 by the two things this instruction does
   not touch: H1 (--fs-6xl, capped at 60) and the stat figures. It is why the
   page-scoped block at the foot of this file shrinks rather than disappearing —
   what is left of it is those figures and two page titles, not headings. */
h2 { font-size: var(--fs-4xl); }
h3 { font-size: var(--fs-4xl); letter-spacing: var(--ls-h3); }
h4 { font-size: var(--fs-2xl); }
h5 { font-size: var(--fs-2xl); }
h6 { font-size: var(--fs-xl); }

p { color: var(--c-text-body); }

/* Inline mailto link emitted by orkla_linkify_email() (inc/template-helpers.php)
   wherever body copy carries a bare address — first used on Career Paths (Figma
   11238:10434, talent.acquisition@orklaindia.com). Maroon semibold on the grey
   paragraph, matching the design. Global rather than section-scoped because the
   helper is shared. No resting underline (site-wide link convention), but one on
   hover/focus so the affordance is not carried by colour alone. */
.link-email {
	font-weight: var(--fw-semibold);
	color: var(--c-primary);
	text-decoration: none;
}

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

/* ---- Accessibility ------------------------------------------------------ */
:focus-visible {
	outline: 2px solid var(--c-primary);
	outline-offset: 2px;
}

.screen-reader-text {
	position: absolute !important;
	width: 1px; height: 1px;
	padding: 0; margin: -1px;
	overflow: hidden; clip: rect(0, 0, 0, 0);
	white-space: nowrap; border: 0;
}

.skip-link {
	position: absolute;
	left: -9999px;
	top: 0;
	z-index: 1000;
	padding: var(--sp-12) var(--sp-16);
	background: var(--c-primary);
	color: var(--c-white);
	border-radius: 0 0 var(--radius-lg) 0;
}
.skip-link:focus { left: 0; }

/* ---- Layout primitives -------------------------------------------------- */
.container {
	width: 100%;
	max-width: var(--container-max);
	margin-inline: auto;
	padding-inline: var(--container-pad);
}

.site-main { min-height: 40vh; }

/* Visually-hidden section placeholders during scaffold — removed as real
   sections land. Keeps early pages from looking broken. */
.scaffold-note {
	padding: var(--sp-80) var(--container-pad);
	text-align: center;
	color: var(--c-text-muted);
}
.scaffold-note h1 { color: var(--c-primary); margin-bottom: var(--sp-16); }

/* ==========================================================================
   Header — primary navigation (Figma "Navigation" 11338:5245)
   Full-width maroon bar · logo left · menu + search right · sticky on scroll.
   ========================================================================== */
/* THE ADMIN BAR, ONCE, FOR BOTH OF THE HEADER'S OFFSETS
   Two things here are placed by the viewport rather than by the document flow:
   this sticky bar, and the mobile drawer that hangs off its bottom edge
   (max-width:1279 below). Neither can see the WordPress admin bar, and core
   accounts for it by pushing <html> down with `margin-top: 32px !important`
   (46px at ≤782) — a flow offset that sticky and fixed both measure past. So a
   logged-in editor gets the bar's own height subtracted from both: the header
   slides under the toolbar on scroll, and the drawer opens that far INSIDE the
   header, which is what put the close ✕ on top of the Shop Now pill.

   --wp-admin--admin-bar--height is core's own token, declared on <html> at the
   top of wp-includes/css/admin-bar.css — a stylesheet that is only enqueued
   when the bar actually shows. So the fallback is what a visitor gets, the
   value is what an editor gets, and neither needs a body class or a media query
   to say so; core already restates it as 46px at ≤782 for the touch toolbar.
   Nothing about production rendering changes here. */
.site-header {
	position: sticky;
	top: var(--wp-admin--admin-bar--height, 0px);
	z-index: 100;
	background: var(--c-primary);
	color: var(--c-white);
	transition: box-shadow 0.25s ease;
}
.site-header.is-scrolled {
	box-shadow: 0 4px 20px rgba(0, 0, 0, 0.18);
}
/* 600 is CORE's breakpoint, not one of the theme's three — below it the admin
   bar stops being fixed and scrolls away with the page, so there is nothing left
   at the top of the viewport to clear and the offset above would strand a 46px
   band of bare page above the header on every scroll. Only the sticky header
   needs this. The drawer keeps its offset: it is fixed, so it cannot follow a
   toolbar that scrolls, and the state worth being right in is the one a menu is
   opened in — at the top of the page, toolbar showing, flush to the header. Scroll
   first and then open it and an editor sees a 46px gap above the panel; that is
   the residue of this, and it is preferred to the ✕ landing on the first row. */
@media screen and (max-width: 600px) {
	.site-header { top: 0; }
}

.site-header__inner {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--sp-32);
	min-height: var(--header-h);
	padding-inline: var(--header-pad);
}

/* ---- Brand / logo ---- */
.site-brand { flex: 0 0 auto; display: flex; align-items: center; }
.site-brand__link { display: inline-flex; align-items: center; color: var(--c-white); }
.site-brand__link:hover { text-decoration: none; }
.site-brand__link svg { height: 44px; width: auto; display: block; color: var(--c-white); }
.site-brand__text {
	font-family: var(--ff-heading);
	font-size: var(--fs-xl);
	color: var(--c-white);
	font-weight: var(--fw-bold);
}
.site-brand__text:hover { text-decoration: none; }

/* ---- Primary menu ---- */
.nav-primary__list {
	display: flex;
	align-items: center;
	/* Figma's 32 at its 1920 artboard (1.67vw = 32.06 there, so the max clamps it
	   to exactly 32), tightening as the bar narrows. Seven items plus the shop
	   button and the search icon are a tight fit at 1280, the narrowest width that
	   still shows this menu: measured, the clamp's 21.4 there leaves 83px spare
	   where a fixed 32 would leave 20. Scaling the gap buys that headroom with no
	   extra breakpoint. The 16px floor is now unreachable here — the drawer takes
	   over at ≤1279 and sets gap: 0 — but it is kept as a backstop. */
	gap: clamp(16px, 1.67vw, 32px);
	list-style: none;
	margin: 0;
	padding: 0;
}
.nav-primary .menu-item > a {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	color: var(--c-white);
	font-family: var(--ff-body);
	font-size: var(--fs-m);
	font-weight: var(--fw-regular);
	line-height: 1;
	padding-block: 10px;
	white-space: nowrap;
	transition: opacity 0.18s ease;
}
.nav-primary .menu-item > a:hover { opacity: 0.72; text-decoration: none; }

/* Dropdown caret on parents */
.nav-primary .menu-item-has-children > a::after {
	content: "";
	display: inline-block;
	width: 0.44em;
	height: 0.44em;
	border-right: 1.6px solid currentColor;
	border-bottom: 1.6px solid currentColor;
	transform: translateY(-2px) rotate(45deg);
	margin-left: 0.35em;
	transition: transform 0.2s ease;
}
.nav-primary .menu-item-has-children:hover > a::after,
.nav-primary .menu-item-has-children:focus-within > a::after {
	transform: translateY(1px) rotate(-135deg);
}

/* Dropdown panels (Figma node 11116:897 — white 240px card, triangle pointer,
   Semibold 18px rows + right chevron, divider lines). Rendered when a WP menu
   item has children. */
.nav-primary .menu-item-has-children { position: relative; }
.nav-primary .sub-menu {
	position: absolute;
	top: 100%;
	left: 0;
	width: max-content;      /* panels hug content in Figma (240–300px) */
	min-width: 240px;
	max-width: 320px;
	list-style: none;
	margin: 12px 0 0;
	padding: var(--sp-24) var(--sp-16);
	background: var(--c-white);
	color: var(--c-text);
	border-radius: var(--radius-md);
	box-shadow: 0 16px 33px -2px rgba(28, 39, 49, 0.06);
	opacity: 0;
	visibility: hidden;
	transform: translateY(6px);
	transition: opacity 0.18s ease, transform 0.18s ease, visibility 0.18s ease;
	z-index: 10;
}
/* Triangle pointer (18×9) toward the parent label */
.nav-primary .sub-menu::before {
	content: "";
	position: absolute;
	bottom: 100%;
	left: 24px;
	border-left: 9px solid transparent;
	border-right: 9px solid transparent;
	border-bottom: 9px solid var(--c-white);
}
/* Invisible hover bridge across the 12px gap so the panel stays open */
.nav-primary .sub-menu::after {
	content: "";
	position: absolute;
	bottom: 100%;
	left: 0;
	width: 100%;
	height: 12px;
}
.nav-primary .menu-item-has-children:hover > .sub-menu,
.nav-primary .menu-item-has-children:focus-within > .sub-menu {
	opacity: 1;
	visibility: visible;
	transform: translateY(0);
}
.nav-primary .sub-menu li:not(:last-child) {
	padding-bottom: var(--sp-12);
	margin-bottom: var(--sp-12);
	border-bottom: 1px solid var(--c-gray-200);
}
.nav-primary .sub-menu a {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--sp-12);
	padding: 0;
	color: var(--c-text);
	font-family: var(--ff-body);
	font-weight: var(--fw-semibold);
	font-size: var(--fs-l2);
	line-height: 1.4;
}
/* Right chevron ONLY on dropdown rows that have a nested submenu.
   A leaf row (no children) shows no arrow. This also overrides the top-level
   caret rule for nested parents (higher specificity → right chevron, not ▾). */
.nav-primary .sub-menu .menu-item-has-children > a::after {
	content: "";
	flex: 0 0 auto;
	width: 7px;
	height: 7px;
	border-top: 1.6px solid currentColor;
	border-right: 1.6px solid currentColor;
	transform: rotate(45deg);
	opacity: 0.4;
	transition: transform 0.18s ease, opacity 0.18s ease;
	margin-left: var(--sp-12);
}
.nav-primary .sub-menu a:hover {
	color: var(--c-primary);
	text-decoration: none;
}
.nav-primary .sub-menu .menu-item-has-children > a:hover::after { opacity: 0.9; transform: translateX(2px) rotate(45deg); }

/* ---- Investor Relations mega menu (Figma 11706:3630) ----------------------
   The same card as the dropdown above — same white, same 8px radius, same
   shadow, same Semibold 18/1.4 rows, same #dee1e7 dividers. All this block does
   is widen it to 944px and park a panel of that tree's sections in the right
   two thirds. Everything inherited above is deliberately left inherited.

   SELECTED BY CONTENT, NOT BY NAME. A submenu becomes a mega menu because one of
   its rows carries a .nav-mega__sections panel, and only the IR trees do (the
   panel comes from orkla_ir_sections(), see inc/nav-mega.php). So there is no
   menu-item id or class here for a client edit under Appearance → Menus to
   break, and the other four dropdowns are untouched.

   MEASURED AGAINST THE NAV, NOT THE LABEL. The other dropdowns are 240–320px and
   sit under their own item. A 944px card centred on a ~130px label would hang off
   the right of the header, so the IR item goes position:static and the card
   centres on .nav-primary instead. The nav is always narrower than the header, so
   a card this wide cannot overflow at any width that still shows the inline menu.
   The cost is that the triangle points at the middle of the card rather than at
   the label; --mega-pointer is the one value to change if that is wanted.

   DESKTOP ONLY, DECLARED AS SUCH. Everything below the panel's own display:none is
   wrapped in min-width:1280 — the exact complement of the ≤1279 drawer breakpoint.
   Not tidiness: a media query adds no specificity, and the rules that open a panel
   run to 0,5,2 because of the :not(:has()) guard, so undoing them in the drawer
   would mean restating all six of those selectors verbatim just to cancel them.
   Declaring them desktop-only instead costs no reset rules at all, and the drawer
   is left exactly as it shipped: the panel is display:none there, so the IR branch
   stays the two-level accordion that wp_nav_menu()'s depth=>2 asks for rather than
   growing a third level of twelve always-open links. */

/* Hidden until the desktop rules below turn it on, so it is inert in the drawer
   and at the 1279–1280 fractional seam, where neither breakpoint matches and the
   IR dropdown falls back to a plain card of the four tree links. */
.nav-mega__sections { display: none; }

@media (min-width: 1280px) {
	.nav-primary { position: relative; }
	.nav-primary .menu-item-has-children:has(.nav-mega__sections) { position: static; }

	.nav-primary .sub-menu:has(.nav-mega__sections) {
		--mega-left: 300px;   /* left column, Figma 11706:3634 */
		--mega-pointer: 50%;  /* triangle x within the card */
		/* The natural height of the tallest panel, which is the one thing the card
		   cannot measure for itself — the panel is absolutely positioned, so it
		   cannot push the card open. Five rows, four dividers, and the panel's own
		   padding. The value has not moved since it was written, but the panel it
		   describes has: it used to be Governance's nine sections halved into a
		   column of five, and since the 2026-09-03 dropdown change the tallest is
		   Stock Exchange Intimations, whose five sections are not split at all
		   (orkla_nav_mega_panel() only halves above five, so five is the most rows
		   any panel can have until a group reaches eleven). Written as a calc rather
		   than Figma's flat 258 because --fs-l2 is fluid: a fixed height would be
		   right at 1920 and too tall everywhere below it. Revisit only if a group's
		   section count passes ten. */
		--mega-panel-h: calc(2 * var(--sp-16) + 5 * 1.4 * var(--fs-l2) + 4 * (2 * var(--sp-12) + 1px));
		width: 944px;
		min-width: 0;
		max-width: calc(100vw - 2 * var(--header-pad));
		left: 50%;
		/* Vertical padding only: the left column's side padding belongs to its rows,
		   which keeps the panel's offsets (308 / 12) the design's own numbers rather
		   than those numbers minus a card inset. */
		padding: var(--sp-12) 0 var(--sp-24);
		transform: translateX(-50%) translateY(6px);
		/* Tall enough for that panel plus the card's own padding, +2 for sub-pixel
		   rounding so a fractional row height cannot summon a scrollbar. THIS IS NOW
		   A FLOOR THE CARD CLEARS RATHER THAN THE HEIGHT IT SETTLES AT: the left
		   column went from four rows to six on 2026-09-03, and six rows of
		   1.4 x --fs-l2 plus 12/12 padding and five 1px dividers come to ~300px
		   against this rule's ~296 at 1920 — and the gap only widens as the viewport
		   narrows, because the rows shrink more slowly than the panel does. So the
		   left column is what sets the height today. Nothing needs adjusting for
		   that: the panel is absolutely positioned with max-height 100% of the
		   content box and overflow-y auto, so a taller card simply gives it more room
		   than it needs. What the rule still guarantees is the thing it was written
		   for — the card does not resize as the visitor moves between rows, because
		   neither column's height depends on which panel is open. */
		min-height: calc(var(--sp-12) + var(--mega-panel-h) + var(--sp-24) + 2px);
	}
	.nav-primary .menu-item-has-children:hover > .sub-menu:has(.nav-mega__sections),
	.nav-primary .menu-item-has-children:focus-within > .sub-menu:has(.nav-mega__sections) {
		transform: translateX(-50%);
	}
	.nav-primary .sub-menu:has(.nav-mega__sections)::before {
		left: var(--mega-pointer);
		margin-left: -9px;
	}

	/* Left column: the six IR groups. The dropdown's own row divider
	   (.nav-primary .sub-menu li:not(:last-child), 12/1px/12 on the <li>) is turned
	   off here and re-drawn on the <a> below instead. It has to move: the divider
	   must disappear on either side of the tinted pill, and the pill IS the <a> — a
	   line drawn on the <li> would sit outside the pill's rounded corners. */
	.nav-primary .sub-menu:has(.nav-mega__sections) > li {
		width: var(--mega-left);
		padding-bottom: 0;
		margin-bottom: 0;
		border-bottom: 0;
	}
	/* Every row carries the pill's 12px padding whether or not it is the selected
	   one, so pointing at a row changes only its colours. Padding it on hover
	   instead would grow the row by 24px and shove the rest of the column down. */
	.nav-primary .sub-menu:has(.nav-mega__sections) > li > a {
		padding: var(--sp-12);
		border-radius: var(--radius-sm);
		transition: background-color 0.18s ease, color 0.18s ease;
	}
	/* Chevron on the tree rows that actually open a panel, and on no others (client,
	   2026-08-14) — overriding the frame, which draws one on all four. A chevron is
	   the promise of something to the right; Investor Contact has no sections, so on
	   that row it pointed at the empty half of the card and invited the reach the
	   hover bridge below exists to protect. The test is the same
	   :has(> .nav-mega__sections) the pill, the display and the bridge rules use, so
	   a tree that gains sections gets its chevron with them and none of these four
	   can disagree about which rows are which. Drawn in the border-box style the
	   dropdown chevron above already uses, but in its own grey rather than
	   currentColor, so it stays grey while the row's text goes maroon. */
	.nav-primary .sub-menu:has(.nav-mega__sections) > li:has(> .nav-mega__sections) > a::after {
		content: "";
		flex: 0 0 auto;
		width: 7px;
		height: 7px;
		margin-left: var(--sp-12);
		border-top: 1.5px solid var(--c-gray-400);
		border-right: 1.5px solid var(--c-gray-400);
		transform: rotate(45deg);
		transition: transform 0.18s ease;
	}
	/* The same 2px nudge the dropdown's own chevron makes on hover. These rows are
	   not .menu-item-has-children, so that rule cannot reach them, and without
	   this the transition above would have nothing to animate. Carries the same
	   :has() test as the chevron itself — a row with no chevron has nothing to nudge. */
	.nav-primary .sub-menu:has(.nav-mega__sections) > li:has(> .nav-mega__sections) > a:hover::after {
		transform: translateX(2px) rotate(45deg);
	}
	/* Dividers run between consecutive UNSELECTED rows only — never against the
	   tinted pill, never after the last row. border-top on the second of a pair is
	   what expresses that: no pair, no line. */
	.nav-primary .sub-menu:has(.nav-mega__sections) > li + li > a {
		border-top: 1px solid var(--c-gray-200);
		border-radius: 0;
	}

	/* The tinted pill, and the panel it belongs to, are always the same row — which
	   now means that pointing at a tree with no sections of its own (Investor
	   Contact) clears BOTH rather than leaving both where they were. Until
	   2026-09-03 the pill stayed put and so did the panel, on the reasoning that a
	   row with no answer should not disturb the one on screen; the client's reading
	   of it was that the card was answering the row being pointed at, which is the
	   more natural one and the reason the panel now empties. The pill has to follow
	   it or the invariant above is a sentence about nothing: a tinted Financial
	   Information beside a blank right-hand half claims a panel that isn't there.
	   That row's feedback is the inherited maroon-text hover, which is what this
	   rule has always left it. */
	.nav-primary .sub-menu:has(.nav-mega__sections) > li:has(> .nav-mega__sections):hover > a,
	.nav-primary .sub-menu:has(.nav-mega__sections) > li:has(> .nav-mega__sections):focus-within > a,
	.nav-primary .sub-menu:not(:has(> li:hover, > li:focus-within)) > li:has(> .nav-mega__sections.is-open) > a {
		background: var(--c-primary-05);
		/* Colour only — the border stays 1px wide and merely goes transparent, so the
		   row's height is identical selected or not and nothing below it moves. */
		border-top-color: transparent;
		border-radius: var(--radius-sm);
	}
	/* A pill's own top divider is suppressed above; so is the one belonging to the
	   row after it, which would otherwise sit flush against the pill's bottom edge. */
	.nav-primary .sub-menu:has(.nav-mega__sections) > li:has(> .nav-mega__sections):hover + li > a,
	.nav-primary .sub-menu:has(.nav-mega__sections) > li:has(> .nav-mega__sections):focus-within + li > a,
	.nav-primary .sub-menu:not(:has(> li:hover, > li:focus-within)) > li:has(> .nav-mega__sections.is-open) + li > a {
		border-top-color: transparent;
	}

	/* Right panel: one tinted block, absolutely positioned so that swapping trees
	   cannot resize the card under the cursor. 308 from the card's left edge and
	   12 short of its right edge are Figma's own numbers (11706:3650). */
	.nav-mega__sections {
		position: absolute;
		top: 0;
		/* 308 from the card's left edge, 12 short of its right — both derived from
		   --mega-left rather than written out, so widening the left column moves the
		   panel with it instead of overlapping it. */
		left: calc(var(--mega-left) + var(--sp-8));
		width: calc(100% - var(--mega-left) - var(--sp-8) - var(--sp-12));
		/* The card's content box: 100% of an absolutely-positioned box resolves
		   against its containing block's PADDING box, and top:0 already sits at the
		   padding edge, so both of the card's paddings come off. Equals
		   --mega-panel-h exactly for Governance, which is the point — the safety net
		   below only ever engages for a tree with more sections than that. */
		max-height: calc(100% - var(--sp-12) - var(--sp-24));
		padding: var(--sp-16);
		overflow-y: auto;
		background: var(--c-primary-05);
		border-radius: var(--radius-md);
		/* Above the hover bridge below, so the bridge cannot swallow a click aimed
		   at one of the panel's own links. */
		z-index: 1;
	}
	/* Third line is the fallback: the panel that opened with the card stays up until
	   the visitor points at a row of their own. Its test is "no row is being
	   pointed at" and NOT the narrower "no row that owns a panel is being pointed
	   at", which is what it used to ask and which made Investor Contact — the one
	   row with no sections — show the default panel on hover. Reported 2026-09-03:
	   pointing at it left Financial Information's four links sitting there, so the
	   card appeared to answer a row that has no answer.
	   Written as `> li:hover` rather than by excluding panel-less rows so that the
	   rule keeps meaning what it says. A second group without sections would
	   otherwise need adding here, and nothing would fail loudly when it wasn't. */
	.nav-primary .sub-menu:has(.nav-mega__sections) > li:hover > .nav-mega__sections,
	.nav-primary .sub-menu:has(.nav-mega__sections) > li:focus-within > .nav-mega__sections,
	.nav-primary .sub-menu:not(:has(> li:hover, > li:focus-within)) > li > .nav-mega__sections.is-open {
		display: block;
	}
	/* The hover bridge, and why the menu is unusable without it.
	   A row is --mega-left wide; its panel starts 8px further right and is pinned to
	   the CARD's top, not the row's. So the pointer travelling from "Results &
	   Presentations" (third row) to "Orkla India" (a panel that ends well above it)
	   crosses a region belonging to neither: :hover is lost, the .is-open fallback
	   above takes over, and the card swaps to whichever tree the CURRENT PAGE is in
	   — the panel is aimed at, then replaced, mid-reach.
	   This gives the hovered row a hit area covering the card's whole right-hand
	   side, so the pointer never leaves the row it started from. It is generated
	   only while that row is hovered, so it can never intercept another row's click.
	   EVERY row gets one, including the panel-less Investor Contact, which is a
	   change of 2026-09-03. It used to be confined to rows that own a panel, on the
	   reasoning that a row with nothing to reach has nothing to bridge to. But the
	   card's right-hand side is dead space while Investor Contact is pointed at, and
	   without a bridge the smallest drift into it left the row, re-satisfied the
	   fallback above and flashed the default panel back — so the fix that empties
	   the card would only have held while the pointer stayed inside 300px of it.
	   Nothing is under this one, so it intercepts nothing.
	   Absolute offsets resolve against the CARD (the li is static, the card is the
	   nearest positioned ancestor), which is the same containing block the panel
	   itself is placed in — so both read --mega-left and cannot drift apart.
	   :hover only, deliberately: focus does not travel through dead space, and a
	   bridge held open by :focus-within would sit over the card during keyboard use. */
	.nav-primary .sub-menu:has(.nav-mega__sections) > li:hover::after {
		content: "";
		position: absolute;
		top: 0;
		right: 0;
		bottom: 0;
		left: var(--mega-left);
		z-index: 0;
	}
	.nav-mega__cols {
		display: flex;
		align-items: flex-start;
		gap: var(--sp-16);
	}
	/* Two columns for a long list, one for a short one — a three-row tree split
	   2 + 1 either side of a divider reads as broken. The rule that decides is in
	   orkla_nav_mega_panel(); this only has to draw whatever it gets, so the columns
	   share the space rather than each claiming Figma's literal 280px. Two of them
	   land on 279.5 — Figma's own 280 + 16 + 1 + 16 + 280 comes to 593 inside a
	   592px panel, and a fixed pair would overflow it by that pixel. One of them
	   fills the panel, which puts its arrows on the panel's right edge exactly as
	   the left column's arrows sit on its own. */
	.nav-mega__col {
		flex: 1 1 0;
		min-width: 0;
	}
	.nav-mega__col + .nav-mega__col {
		border-left: 1px solid var(--c-gray-200);
		padding-left: var(--sp-16);
	}
	/* Rows. Every rule from here down is prefixed .nav-primary .sub-menu for one
	   reason: the dropdown's own `.nav-primary .sub-menu a` above is 0,2,1, so an
	   unprefixed .nav-mega__link rule loses to it — its `padding: 0` would flatten
	   the dividers below and its `color` would outrank .is-current. Two rows also
	   are not anchors at all (see .is-inert), and that selector cannot reach them.
	   So the shared shape is stated once here for both element types. Colour is
	   deliberately left out of it, so the state rules that follow still win. */
	.nav-primary .sub-menu .nav-mega__link {
		display: flex;
		align-items: center;
		justify-content: space-between;
		gap: var(--sp-12);
		font-family: var(--ff-body);
		font-weight: var(--fw-semibold);
		font-size: var(--fs-l2);
		line-height: 1.4;
	}
	/* 12 / 1px / 12 is the dropdown's own row spacing, which is what puts these rows
	   on Figma's 25px rhythm without restating a number. */
	.nav-primary .sub-menu .nav-mega__link:not(:last-child) {
		padding: 0 0 var(--sp-12);
		margin-bottom: var(--sp-12);
		border-bottom: 1px solid var(--c-gray-200);
	}
	.nav-primary .sub-menu .nav-mega__link.is-current { color: var(--c-primary); }
	/* A section whose page does not exist yet renders as text, not a dead link, and
	   drops the arrow with it — see orkla_nav_mega_panel(). */
	.nav-primary .sub-menu .nav-mega__link.is-inert {
		color: var(--c-gray-600);
		cursor: default;
	}
	.nav-mega__arrow {
		flex: 0 0 auto;
		display: inline-flex;
		width: 16px;
		height: 16px;
		color: var(--c-gray-500);
	}
	.nav-mega__arrow svg {
		width: 100%;
		height: 100%;
	}
	a.nav-mega__link:hover .nav-mega__arrow { color: var(--c-primary); }
}

/* Covers the two transitions the block above introduces — the tree row's tint and
   its chevron nudge. Both states still change, instantly; only the easing goes.
   Left at top level rather than nested inside min-width:1280 because the rules it
   cancels only exist there anyway, and the house style does not nest @media.
   NOTE: the nav's older transitions (the card's own fade-and-rise, and the
   dropdown chevron at the top of this file) are NOT neutralised anywhere — a
   pre-existing gap this block does not widen and did not want to silently fix. */
@media (prefers-reduced-motion: reduce) {
	.nav-primary .sub-menu:has(.nav-mega__sections) > li > a,
	.nav-primary .sub-menu:has(.nav-mega__sections) > li > a::after {
		transition: none;
	}
	.nav-primary .sub-menu:has(.nav-mega__sections) > li > a:hover::after {
		transform: rotate(45deg);
	}
}

/* Submenu disclosure button, injected by initNavAccordion(). Off here: the
   desktop menu opens its panels on hover and focus-within, so a button would be
   a second, redundant way in. It is turned on in the drawer breakpoint below. */
.nav-primary__sub-toggle { display: none; }

/* ---- Header actions (search + mobile toggle) ---- */
.site-header__actions { display: flex; align-items: center; gap: var(--sp-16); flex: 0 0 auto; }
.header-search {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 40px;
	height: 40px;
	color: var(--c-white);
	border-radius: 50%;
	transition: background-color 0.18s ease;
}
.header-search:hover { background: var(--c-white-20); text-decoration: none; }

/* ---- Shop CTA (client request after sign-off — not in Figma) ----
   Deliberately no new design language: this is the shared .btn component at its
   documented metrics (radius 12, bold 16, 8px gap, arrow-right icon) in the
   inverted .btn--shop colour way defined beside .btn--primary further down,
   because a maroon button on the maroon bar would be invisible.

   The markup prints two variants and CSS shows exactly one — the pill here in
   the bar from 1280px up, the full-width button inside the drawer below that,
   which is exactly where the hamburger takes over.

   EVERY rule below is scoped to its container (.site-header__actions /
   .nav-primary) on purpose, giving 0,2,0. The .btn base is defined much LATER in
   this file and sets both `display: inline-flex` and a `padding` shorthand; at
   the equal 0,1,0 specificity a bare `.shop-cta--drawer` would lose to it on
   source order alone, which showed BOTH variants at once and let .btn's padding
   override the bar sizing. Do not "simplify" these back to single classes
   without moving the whole block below .btn. */
.shop-cta {
	flex: 0 0 auto;      /* never squeezed by the menu beside it */
	white-space: nowrap; /* "Shop Now" must not break across two lines */
}

.site-header__actions .shop-cta--bar {
	height: 40px;                 /* matches the 40px search circle beside it */
	padding: 0 var(--sp-16);      /* shorthand, so .btn's own shorthand cannot win */
}

/* Off until the drawer breakpoint turns it on, so it cannot appear twice. */
.nav-primary .shop-cta--drawer { display: none; }

/* Hamburger — hidden on desktop */
.nav-toggle {
	display: none;
	flex-direction: column;
	justify-content: center;
	gap: 5px;
	width: 44px;
	height: 44px;
	padding: 10px;
	background: transparent;
	border: 0;
}
.nav-toggle span {
	display: block;
	height: 2px;
	width: 100%;
	background: var(--c-white);
	border-radius: 2px;
	transition: transform 0.25s ease, opacity 0.2s ease;
}
.nav-toggle[aria-expanded="true"] span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.nav-toggle[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.nav-toggle[aria-expanded="true"] span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

/* ---- Mobile / tablet: drawer nav (≤1279px) ----
   Was 1024 until the Shop Now button was added. Measured: the bar needs 1016px of
   intrinsic width without that button and 1171px with it, so 1025–1186 overflowed
   outright and 1200 was left with 11px of slack — not enough to survive a longer
   editable label or font-metric variance on another platform. 1279 is one pixel
   under the theme-wide ≤1280 laptop tier, so the widest laptop keeps its inline
   menu (83px spare there) and everything narrower gets the drawer, where the
   button always has room. Do not lower this without re-measuring. */
@media (max-width: 1279px) {
	.nav-toggle { display: inline-flex; }

	/* top: the header's height PLUS however far down the viewport the header
	   itself starts — see the admin-bar note above .site-header. --header-h alone
	   is the height, and the drawer wants the bottom edge. */
	.nav-primary {
		position: fixed;
		top: calc(var(--header-h) + var(--wp-admin--admin-bar--height, 0px));
		right: 0;
		bottom: 0;
		width: min(360px, 82vw);
		background: var(--c-primary-600);
		transform: translateX(100%);
		transition: transform 0.28s ease;
		overflow-y: auto;
		padding: var(--sp-16) var(--sp-24) var(--sp-48);
		box-shadow: -12px 0 32px rgba(0, 0, 0, 0.22);
	}
	.nav-primary.is-open { transform: translateX(0); }

	.nav-primary__list { flex-direction: column; align-items: stretch; gap: 0; }
	/* `white-space: nowrap` is right in the desktop bar, where a broken label
	   would push the row apart, and wrong here: the drawer is a vertical list
	   and a label that cannot wrap can only overflow. With the disclosure button
	   beside it the overflow does not even show as overflow — the flex line
	   cannot fit both, so the BUTTON goes to the next line and the caret appears
	   stranded under the label. "Stock Exchange Intimations" needs 216.3px
	   against 211.8px of room at 390px, missing it by four and a half pixels;
	   at 360px and below, shorter labels miss it too, so this is a width bug
	   waiting on a phone size rather than one long label.

	   Letting it wrap means a two-line row, which needs leading — line-height is
	   1 on the bar, where every label is one line by construction. --lh-base for
	   the drawer only. Single-line rows grow about 6px each as a result, which
	   is the price of the labels staying whole. */
	.nav-primary .menu-item > a {
		/* Block-level, not the bar's `inline-flex`. A row with children is a
		   flex item inside a flex <li> and fills the width whatever this says,
		   which is why every such row looked right; a row with NO children —
		   News, Contact Us — is an inline-flex box in a plain <li>, so it
		   shrank to its text and carried its border-bottom with it. Two rows
		   ended up with a divider a third of the width of the others. Same
		   objection the IR tab strip records against a hairline that stops
		   short: it reads as a rendering fault. */
		display: flex;
		justify-content: space-between;
		padding: 15px 4px;
		font-size: var(--fs-l2);
		line-height: var(--lh-base);
		white-space: normal;
		border-bottom: 1px solid var(--c-white-20);
	}

	/* Submenus expand inline (no hover) in the drawer — reset the desktop card.
	   This is the NO-JS state: everything expanded, exactly as it shipped. The
	   accordion block further down collapses it, but only once
	   initNavAccordion() has added .has-accordion and the buttons that reopen it. */
	.nav-primary .sub-menu {
		position: static;
		width: auto;
		min-width: 0;
		max-width: none;
		opacity: 1;
		visibility: visible;
		transform: none;
		margin: 0;
		background: transparent;
		box-shadow: none;
		border-radius: 0;
		padding: 0 0 var(--sp-8) var(--sp-16);
	}
	.nav-primary .sub-menu::before,
	.nav-primary .sub-menu::after { display: none; }
	.nav-primary .sub-menu li:not(:last-child) {
		border-bottom: 0;
		padding-bottom: 0;
		margin-bottom: 0;
	}
	.nav-primary .sub-menu a {
		color: var(--c-white);
		opacity: 0.85;
		padding: 10px 4px;
		font-weight: var(--fw-regular);
	}
	.nav-primary .sub-menu a:hover { background: transparent; color: var(--c-white); opacity: 1; }
	.nav-primary .sub-menu .menu-item-has-children > a:hover::after { transform: rotate(45deg); opacity: 0.85; }

	/* ---- Accordion: a branch on request, not all twenty children at once ----
	   Scoped to .has-accordion (set by initNavAccordion) so this can only ever
	   hide a submenu that has a button to bring it back. See main.js.

	   The parent row becomes a two-column flex — label, then the 44px disclosure
	   button — with the submenu wrapping onto its own full-width line beneath.
	   The label keeps its own border-bottom and the button repeats it, so the two
	   meet as one continuous divider across the row; putting the border on the
	   <li> instead would double up against the last child's divider whenever the
	   branch is open. */
	.nav-primary.has-accordion .menu-item-has-children {
		display: flex;
		flex-wrap: wrap;
		align-items: stretch;
	}
	/* `flex: 1 1 0`, not `1 1 auto`. With an `auto` basis the label's hypothetical
	   size is its UNWRAPPED width, and a flex line takes items whole: a label
	   wider than the row minus 44px does not shrink, it sends the disclosure
	   button to the next line. "Stock Exchange Intimations" did exactly that at
	   390px — 256px of label against 212px of room — and the caret appeared on
	   its own line underneath, reading as a stray mark rather than a control.
	   A zero basis makes the pair always fit, and the label wraps inside its own
	   column instead. `align-items: stretch` then keeps the button's border
	   flush with the taller label's, so the divider stays one line across.

	   min-width is deliberately left at `auto`: the floor is the longest word,
	   which keeps a label from being crushed narrower than it can render. */
	.nav-primary.has-accordion .menu-item-has-children > a { flex: 1 1 0; }

	.nav-primary.has-accordion .menu-item-has-children > .sub-menu {
		display: none;
		flex: 0 0 100%;
	}
	.nav-primary.has-accordion .menu-item-has-children.is-open > .sub-menu {
		display: block;
	}

	/* The button carries the caret now; the label's own ▾ would be a second one
	   pointing the same way, 44px to its left. */
	.nav-primary.has-accordion .menu-item-has-children > a::after { content: none; }

	/* ---- Third level: the IR mega-menu panels (inc/nav-mega.php) ----
	   Desktop parks these in a card beside the tree list, swapped on hover. The
	   drawer has neither hover nor room for a second column, so each tree becomes
	   another accordion row and its sections stack beneath it. What follows is the
	   .sub-menu block above applied one level deeper — same no-JS-expanded
	   contract, same .has-accordion gate, same 16px step of indent — restated only
	   because the panel is a <div> rather than a <ul> and none of those selectors
	   can reach it.

	   Matched by what the row CONTAINS, the same way main.js finds it: the row is
	   not .menu-item-has-children, because a panel is not a menu item and
	   WordPress does not mark it as one.

	   Most of the card's internals need no undoing: .nav-mega__cols, its
	   two-column divider and the row dividers are all declared inside
	   min-width:1280, so the panel starts from nothing here. The arrow is the one
	   exception — see below. */
	.nav-primary .nav-mega__sections {
		display: block;
		flex: 0 0 100%;
		padding: 0 0 var(--sp-8) var(--sp-16);
	}
	.nav-primary.has-accordion li:has(> .nav-mega__sections) {
		display: flex;
		flex-wrap: wrap;
		align-items: stretch;
	}
	/* Same zero basis as the level above, and the same reason — see there. */
	.nav-primary.has-accordion li:has(> .nav-mega__sections) > a { flex: 1 1 0; }
	.nav-primary.has-accordion .nav-mega__sections { display: none; }
	.nav-primary.has-accordion .is-open > .nav-mega__sections { display: block; }

	/* Linked rows are already picked up by `.nav-primary .sub-menu a` above
	   (white, 0.85, 10px 4px). This states the same box for the inert <span>,
	   which that selector cannot match at all, and drops the space-between the
	   <a> inherits from the desktop card, where it existed to push the arrow to
	   the far edge. --fs-m rather than the --fs-l2 both levels above it use: the
	   flat body rung is the right one for the deepest level, though note the two
	   tokens converge on 16px by 480, so this reads a hair smaller than its parent
	   on a tablet and identical to it on a phone. Indent and the missing dividers
	   are what actually separate the levels, not size.
	   No border-bottom: levels 1 and 2 get theirs from `.nav-primary .menu-item
	   > a`, which cannot reach these — the rows sit in a <div>, not a menu item —
	   and an undivided list is the clearer read at the deepest level anyway. */
	.nav-primary .sub-menu .nav-mega__link {
		display: block;
		padding: 10px 4px;
		font-size: var(--fs-m);
		font-weight: var(--fw-regular);
		color: var(--c-white);
	}
	/* Dimmed rather than greyed: the desktop card says "not available yet" with
	   --c-gray-600, which on this maroon would read as a colour choice instead. */
	.nav-primary .sub-menu .nav-mega__link.is-inert { opacity: 0.6; }
	/* And the current row cannot say it in --c-primary here either — that is the
	   drawer's own background. Full opacity against its siblings' 0.85, plus the
	   weight, carries it instead. */
	.nav-primary .sub-menu .nav-mega__link.is-current {
		opacity: 1;
		font-weight: var(--fw-semibold);
	}
	/* The arrow means "this leaves the card" on a hover panel. In a vertical list
	   of plain links it says nothing, sitting where the caret button already is on
	   the two rows above. Hidden rather than left alone because its 16px box is
	   declared in the desktop block: orkla_icon() ships the SVG at an intrinsic
	   width="24", so with no rule reaching it here it would render at 24px. */
	.nav-primary .sub-menu .nav-mega__arrow { display: none; }

	.nav-primary__sub-toggle {
		display: flex;
		flex: 0 0 auto;
		align-items: center;
		justify-content: center;
		width: 44px;             /* the 44px minimum touch target, on its own */
		padding: 0;
		background: transparent;
		border: 0;
		border-bottom: 1px solid var(--c-white-20);
		color: var(--c-white);
	}
	/* The global ring is `2px solid var(--c-primary)` and this drawer's
	   background is --c-primary-600, so that ring is all but invisible here —
	   the same problem the nav links solve with a white underline (see
	   "Navigation links — underline on focus" further down). White outline,
	   inset so a button on the drawer's right edge cannot clip it. */
	.nav-primary__sub-toggle:focus-visible {
		outline: 2px solid var(--c-white);
		outline-offset: -2px;
	}
	.nav-primary__sub-caret {
		width: 8px;
		height: 8px;
		border-right: 1.6px solid currentColor;
		border-bottom: 1.6px solid currentColor;
		transform: translateY(-2px) rotate(45deg);
		transition: transform 0.2s ease;
	}
	.nav-primary__sub-toggle[aria-expanded="true"] .nav-primary__sub-caret {
		transform: translateY(1px) rotate(-135deg);
	}
	/* Only the caret animates. A height transition would need a measured pixel
	   value for a list whose length changes per branch, and the drawer it lives
	   in is already sliding; the rotation is enough to show what happened. */
}

/* ---- The drawer takes the shop CTA with it (≤1279px) ----
   The swap is tied to the DRAWER, not to a phone width: whenever the hamburger
   is showing, the menu is a drawer and the shop button belongs inside it under
   Contact Us; whenever the menu is inline in the bar, the button is a pill in
   the bar beside the search circle. Swapped, never duplicated.

   This is deliberately the same 1279 the drawer itself uses above, so the two
   cannot disagree. It was written as ≤767 first, on the narrower argument that
   a pill cannot fit a 320px bar next to the logo, the search circle and the
   hamburger — true, but it left 768–1279 showing the drawer AND the bar pill at
   once, the button stranded in the header while the menu it belongs to had
   moved. Reported from a tablet width on 22 Sep. If the drawer breakpoint moves,
   move this one with it; two numbers here is the bug.

   It sits at the END of the drawer, under the last menu row — client request,
   22 Sep. That position comes from the markup order in header.php, not from
   `order` on this flex container: reordering visually would leave the button
   first in the reading and tab order, and a screen reader meeting the shop link
   before About Us is exactly the disagreement to avoid. So there is nothing
   here to move it; there is only the margin, which changed sides with it. */
@media (max-width: 1279px) {
	.site-header__actions .shop-cta--bar { display: none; }

	.nav-primary .shop-cta--drawer {
		display: flex;
		justify-content: center;
		width: 100%;
		height: auto;
		padding: var(--sp-12);
		/* Clears the LAST menu row, which carries its own 1px divider. This was
		   margin-bottom while the button sat above the menu. */
		margin-top: var(--sp-16);
	}
}

body.nav-open { overflow: hidden; }

/* ==========================================================================
   Home hero slider (Figma "Hero Slider" 11151:3251)
   Full-bleed background behind a left content column (eyebrow pill → two-tone
   H1 → description → CTA), with prev/next arrow controls and dot pagination.
   Desktop pass; responsive overrides land at the next step.
   ========================================================================== */
.hero {
	position: relative;
	width: 100%;
	min-height: 840px;
	overflow: hidden;
	isolation: isolate;
	background: var(--c-primary-900); /* base behind the slide bg */
}

/* ---- Slides (crossfade stack; only .is-active is visible) ---- */
.hero__slides { position: absolute; inset: 0; }
.hero__slide {
	position: absolute;
	inset: 0;
	opacity: 0;
	visibility: hidden;
	transition: opacity 0.6s ease, visibility 0.6s ease;
}
.hero__slide.is-active {
	opacity: 1;
	visibility: visible;
}

/* Full-bleed background image (neutral placeholder until the real per-slide
   photo is wired at the data step; the dynamic pass sets background-image
   inline per slide). */
.hero__bg {
	position: absolute;
	inset: 0;
	background: var(--c-surface) center / cover no-repeat;
	z-index: 0;
}

/* ---- Content column ---- */
.hero__inner {
	position: relative;
	z-index: 1;
	height: 100%;
	display: flex;
	/* Anchor the content column to a fixed top offset (not centered) so the
	   eyebrow + headline start at the same Y on every slide. Centering made the
	   block re-center as heading/description heights changed, so the text
	   drifted up/down between slides. */
	align-items: flex-start;
	padding: 180px 120px;
}
.hero__content {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: var(--sp-16);
	/* Sizes to its content up to the widest slide (Figma: slide 2 = 747px) on
	   large screens, but tracks the viewport (54vw) below ~1400px so the copy
	   stays inside the cream/gradient zone (baked into the slide photo) instead
	   of running onto the bright image at mid widths. */
	max-width: min(760px, 54vw);
}

/* Eyebrow pill */
.hero__eyebrow {
	display: inline-flex;
	align-items: center;
	gap: var(--sp-8);
	margin: 0;
	padding: var(--sp-8) var(--sp-12);
	border-radius: 80px;
	background: var(--c-primary-10);
	color: var(--c-primary);
	font-family: var(--ff-body);
	font-weight: var(--fw-medium);
	font-size: var(--fs-m);
	line-height: var(--lh-base);
}

/* Two-tone headline */
.hero__title {
	margin: 0;
	font-family: var(--ff-heading);
	font-weight: var(--fw-bold);
	/* Fluid size, now straight off the global H1 token (8 Aug 2026). This used to
	   be a bespoke clamp(2.125rem, 5.2vw, 3.75rem) — the hero was the only fluid
	   headline on the site, because it is the only one that can spill off the
	   cream/gradient zone onto the bright photo. Now that --fs-6xl is itself
	   fluid, the local clamp is redundant AND was the looser of the two: 5.2vw
	   reached the 60px cap by ~1154px, so the hero rendered a full 60 from 1154
	   up, while every other H1 on the site now lands at 49.2 at 1366. Deferring
	   to the token both unifies them and shrinks the hero at exactly the mid
	   widths the old clamp existed to protect — strictly safer for the spill,
	   never larger than before at any width.

	   (The old 2.125rem/34px floor was unreachable dead code: 5.2vw only falls to
	   34 at ~654px, well inside the ≤767 override below. The token's 2rem/32
	   floor is reachable and real.) */
	--hero-title-fs: var(--fs-6xl);
	font-size: var(--hero-title-fs);
	line-height: var(--lh-tight);
	letter-spacing: var(--ls-h1);
	color: var(--c-dark);
	/* Reserve two lines of height so 1- and 2-line headlines occupy the same
	   vertical space. This keeps the description + CTA (and thus the whole copy
	   block) at an identical Y on every slide — without it, shorter headlines
	   let the text below drift up/down between slides. Tracks the fluid size. */
	min-height: calc(var(--hero-title-fs) * var(--lh-tight) * 2);
}
/* The maroon half always starts its own line — client instruction, 8 Aug 2026:
   the dark lead on line one, the highlight on line two, on every slide. It is a
   block rather than a `<br>` in the markup so it holds on every environment
   without a per-slide field to set (and to get wrong): the rule is the design,
   not editorial content. The 2-line min-height above now describes every slide
   exactly rather than only the ones the designer had broken by hand. */
.hero__title-accent {
	display: block;
	color: var(--c-primary);
}

/* Description */
.hero__desc {
	margin: 0;
	/* The cream zone is baked into the photo, and the photo is `cover` — so below
	   1920 the slide is cropped from BOTH sides and the cream edge travels left
	   with it, while a viewport-proportional cap does not. That mismatch is the
	   bug this replaces: `min(499px, 40vw)` kept the 499 cap all the way down to
	   1248 (40vw only undercuts 499 below that), so at 1366 the paragraph ran to
	   619px against a cream edge sitting at 419 — 200px of text on the bright
	   photo, reported 2026-10-28.

	   Measured, not guessed: on slide 1 (1920×840, the tightest of the three)
	   the texture starts at image x=696 across the description band. With
	   `cover` at viewport < 1920 the horizontal crop is (1920 - 100vw) / 2, so
	   that edge lands on screen at 696 - (1920 - 100vw)/2 = 50vw - 264.

	   Subtract the 120px left padding to get the available column, then 32px of
	   breathing room so the last word is not flush against the gradient:

	       50vw - 264 - 120 - 32  =  50vw - 416

	   The 499px cap still governs from 1830 up, where the cream edge has moved
	   far enough right to clear it. Slides 2 and 3 are 2560 wide and their cream
	   runs further (904 and 816 at this band), so sizing to slide 1 is safe for
	   all three.

	   The 240px floor is load-bearing in one narrow band: just above 1280 the
	   gutter has already widened back to 120 (the ≤1280 query has let go) while
	   the cream edge is still well left, so 1300 is the tightest width on the
	   curve. At 240 it clears by 26px; at 260 it was 6. Below 1280 the 64px
	   gutter takes over and clearance opens up again. */
	max-width: clamp(240px, 50vw - 416px, 499px);
	font-family: var(--ff-body);
	font-weight: var(--fw-regular);
	font-size: var(--fs-l2);
	line-height: var(--lh-base);
	color: var(--c-text-muted);
}

/* CTA — sits 40px below the text group (16px gap + 24px margin) */
.hero__cta {
	display: inline-flex;
	align-items: center;
	gap: var(--sp-8);
	margin-top: var(--sp-24);
	padding: var(--sp-8) var(--sp-12);
	border-radius: var(--radius-lg);
	background: var(--c-primary);
	color: var(--c-white);
	font-family: var(--ff-body);
	font-weight: var(--fw-bold);
	font-size: var(--fs-m);
	line-height: var(--lh-base);
	transition: background-color 0.2s ease;
}
.hero__cta:hover,
.hero__cta:focus-visible { background: var(--c-primary-600); text-decoration: none; }
/* The class now lands on orkla_icon()'s wrapper span rather than on the svg
   itself (2026-08-14, when the hero stopped drawing its own arrow), so the size
   has to be set on the child — the same two-rule shape .feature-card__cta-icon
   uses. Figma's hero CTA arrow is 20px where the slider controls are 24. */
.hero__cta-arrow { flex: 0 0 auto; display: inline-flex; }
.hero__cta-arrow svg { display: block; width: 20px; height: 20px; }

/* ---- Slider controls (prev / next) ---- */
.hero__controls {
	position: absolute;
	left: 120px;
	bottom: 80px;
	z-index: 2;
	display: flex;
	gap: var(--sp-16);
}
/*
 * Shared with the news slider (2026-09-11), which is why the news rule is up
 * here in the hero block rather than down beside its own section: an arrow that
 * means "there is more that way" should be the same object wherever it appears,
 * and two copies of this would have drifted the first time one of them was
 * touched. Same grouping the theme already uses for
 * `.news-latest__grid, .news-archive__grid`.
 *
 * 48px and not tataconsumer.com's 38, which is under the 44px a finger needs.
 */
.hero__arrow,
.news-slider__arrow {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 48px;
	height: 48px;
	border-radius: 50%;
	background: var(--c-cream);
	color: var(--c-primary);
	border: 1.8px solid var(--c-primary-600);
	transition: border-color 0.2s ease, transform 0.2s ease;
}
/*
 * The pale arrow means "nowhere to go that way" — prev on slide 1, next on the
 * last slide. Until 2026-08-14 the two looks were hard-coded per button (prev
 * always pale, next always dark), so they described the button rather than the
 * position; the slider JS now moves the state with the index. It sets
 * aria-disabled rather than the disabled attribute, so this must match that and
 * not :disabled. No hover rule: an enabled arrow is already at full strength,
 * and a bounded one must not pretend otherwise.
 */
.hero__arrow[aria-disabled="true"],
.news-slider__arrow[aria-disabled="true"] { border-color: var(--c-primary-20); cursor: default; }
.hero__arrow:not([aria-disabled="true"]):active,
.news-slider__arrow:not([aria-disabled="true"]):active { transform: scale(0.94); }
.hero__arrow svg,
.news-slider__arrow svg { width: 24px; height: 24px; }

/* ---- Dot pagination ---- */
.hero__dots {
	position: absolute;
	left: 50%;
	bottom: 20px;
	transform: translateX(-50%);
	z-index: 2;
	display: flex;
	align-items: center;
	gap: var(--sp-12);
}
.hero__dot {
	position: relative;
	width: 16px;
	height: 16px;
	padding: 0;
	border: 0.8px solid var(--c-primary-20);
	border-radius: 999px;
	background: var(--c-cream);
	transition: border-color 0.25s ease;
}
/* Maroon centre dot (Figma Ø9.6px) — hidden on inactive dots, scaled in on the
   active one so the pagination reads as a filled bullseye, not a colour swap. */
.hero__dot::before {
	content: "";
	position: absolute;
	top: 50%;
	left: 50%;
	width: 9.6px;
	height: 9.6px;
	border-radius: 50%;
	background: var(--c-primary);
	transform: translate(-50%, -50%) scale(0);
	transition: transform 0.25s ease;
}
/* Invisible hit area so the 16px dot meets the 44px touch-target minimum
   without changing its painted size. */
.hero__dot::after {
	content: "";
	position: absolute;
	inset: -14px;
}
.hero__dot.is-active {
	border-color: var(--c-primary-600);
}
.hero__dot.is-active::before {
	transform: translate(-50%, -50%) scale(1);
}

/* ---- Hero responsive ---------------------------------------------------- */
/* The headline font-sizes scale via the token clamps in tokens.css
   (--fs-6xl @1280/@767/@479); here we handle padding, the fixed slide height,
   and the absolutely-positioned controls/dots. Slides are absolute so the hero
   can't grow to its content — each min-height is sized to clear the tallest
   slide (slide 2) at that width without the overflow:hidden clipping it. */

/* Tablet: ease the oversized 120px gutter + 180px vertical padding; pull the
   bottom-left controls in to match the new gutter. */
@media (max-width: 1280px) {
	.hero { min-height: 720px; }
	.hero__inner { padding: 140px 64px; }
	.hero__controls { left: 64px; bottom: 64px; }
}

/* Small tablet / large phone: tighten further; dots stay centred (room remains
   between the left controls and a centred cluster at this width). */
@media (max-width: 900px) {
	.hero { min-height: 640px; }
	.hero__inner { padding: 120px 32px 140px; }
	.hero__controls { left: 32px; bottom: 40px; }
}

/* Phone: top-align the copy and reserve bottom space for the control band.
   Controls sit bottom-left, dots bottom-right — right-aligning the dots keeps
   them from colliding with the controls on narrow viewports.
   Mobile Figma "Hero Slider" 11464:3590 — the copy moves onto the photo at this
   width, so a full-bleed cream scrim over the slide photo restores contrast
   (this is the fix for text becoming invisible on small screens). */
@media (max-width: 767px) {
	.hero { min-height: 620px; }

	/* Cream scrim between the slide photo and the text (86% cream, per design).
	   Rides inside .hero__bg (z-index:0) so it sits over the photo but under the
	   content column (.hero__inner z-index:1). Mobile-only. */
	.hero__bg::after {
		content: "";
		position: absolute;
		inset: 0;
		background: rgba(240, 218, 199, 0.86);
	}

	.hero__inner {
		align-items: flex-start;
		padding: 80px 30px 128px; /* spec 80/30; bottom reserves the control band */
	}
	/* Cream scrim covers the whole slide here, so the vw width caps are dropped
	   and the copy uses the full column width again. */
	.hero__content { gap: var(--sp-16); max-width: none; } /* 16px inner gap; CTA margin adds → 40 */
	/* Type is a touch smaller than the Figma mobile spec (48/18) so the tallest
	   slide (slide 2: long headline + 6-line paragraph) fits the fixed 620px
	   band and its CTA clears the control arrows. Shorter slides just gain a
	   little breathing room above the arrows.

	   The hardcoded 40 → 36 of 7 Aug 2026 is gone (8 Aug): the hero now reads
	   --fs-6xl like every other H1, and the token reaches 37.6 at 767 falling to
	   32 by 480 — i.e. it hand-tunes itself down through this range instead of
	   sitting at one fixed value. 37.6 is 1.6px above the old 36, which costs
	   ~4px of the 620px band across two lines and so stays inside the slack the
	   note above describes. line-height stays overridden at 1.3 (looser than
	   --lh-tight) because two long mobile lines need the leading; tracking is no
	   longer overridden at all, so it inherits --ls-h1 in em and finally scales
	   with the text instead of holding a fixed -1px at half the desktop size. */
	.hero__title {
		line-height: 1.3;
		min-height: calc(var(--fs-6xl) * 1.3 * 2); /* two lines at the mobile size */
	}
	.hero__desc {
		max-width: none;
		font-size: var(--fs-m);
		line-height: 1.4;
	}
	.hero__controls { left: 16px; bottom: 24px; }
	.hero__dots {
		left: auto;
		right: 16px;
		bottom: 40px;
		transform: none;
	}
}

/* ==========================================================================
   Home · Intro + stat cards — Figma node 11151:3252
   Lead heading + intro paragraph, then a row of three equal-height stat cards
   (big maroon number, label, faded brand icon pinned right).
   ========================================================================== */
.intro-stats {
	padding: 150px var(--sp-80);
	background: var(--c-white);
}
.intro-stats__inner {
	display: flex;
	flex-direction: column;
	gap: 60px;
	padding-inline: 40px; /* + section 80 → ~120px Figma gutter */
}

/* Text block */
.intro-stats__text {
	display: flex;
	flex-direction: column;
	gap: var(--sp-16);
}
.intro-stats__heading {
	max-width: 968px; /* Figma wrap measure; keeps the headline to ~2 lines */
	margin: 0;
	font-family: var(--ff-heading);
	font-weight: var(--fw-bold);
	font-size: var(--fs-4xl);
	line-height: var(--lh-heading);
	letter-spacing: var(--ls-h3);
	color: var(--c-dark);
}
.intro-stats__body {
	max-width: 1320px;
	margin: 0;
	font-family: var(--ff-body);
	font-weight: var(--fw-regular);
	/* 24 → 18 (Font Hirarchy.docx, client review 7 Aug 2026). At 24 this
	   paragraph read as a lead-in rather than body copy and competed with the
	   heading above it across a 1320px measure. */
	font-size: var(--fs-l2);
	line-height: var(--lh-base);
	color: var(--c-text-muted);
}

/* Stat cards row */
.intro-stats__cards {
	display: flex;
	gap: var(--sp-32);
	margin: 0;
	padding: 0;
	list-style: none;
}
.intro-stats__card {
	position: relative;
	flex: 1 1 0;
	display: flex;
	padding: var(--sp-32);
	background: var(--c-gray-05);
	border: 1px solid var(--c-gray-100);
	border-radius: var(--radius-lg);
}
.intro-stats__card-body {
	display: flex;
	flex-direction: column;
	gap: var(--sp-10);
	padding-right: 96px; /* clears the 80px icon pinned right */
}
.intro-stats__value {
	font-family: var(--ff-heading);
	font-weight: var(--fw-bold);
	/* 60 → 40 (Font Hirarchy.docx, 7 Aug 2026). --fs-3xl is the stat-figure rung
	   and already existed at exactly 40; at --fs-5xl these numbers matched the
	   page's H2s, so three stat cards read as three section headings. */
	font-size: var(--fs-3xl);
	line-height: var(--lh-base);
	color: var(--c-primary);
}
.intro-stats__label {
	font-family: var(--ff-body);
	font-weight: var(--fw-semibold);
	/* 32 → 18 (Font Hirarchy.docx, 7 Aug 2026) — the largest single cut in the
	   review. The label is the caption to the figure above it, so it should not
	   have been within one rung of it. */
	font-size: var(--fs-l2);
	line-height: var(--lh-base);
	/* --ls-h3 is -1%, calibrated for 32px display text; at 18px body size
	   negative tracking closes the counters, so this now sets none. */
	color: var(--c-dark);
}
.intro-stats__icon {
	position: absolute;
	top: 50%;
	right: var(--sp-32);
	transform: translateY(-50%);
	width: 80px;
	height: 80px;
	color: var(--c-primary); /* 0.2 opacity is baked into the SVG fill */
}
.intro-stats__icon svg {
	display: block;
	width: 80px;
	height: 80px;
}

/* Laptop: ease the tall vertical padding and inner gutter; cards stay 3-across
   (type shrinks for free via the token step-downs at this width). */
@media (max-width: 1280px) {
	.intro-stats { padding: 100px var(--sp-64); }
	.intro-stats__inner { gap: 48px; padding-inline: var(--sp-16); }
}

/* Tablet: three cards get too narrow beside the 80px icon, so wrap to 2-up
   (the third card drops to its own full-width row). */
@media (max-width: 900px) {
	.intro-stats__cards { flex-wrap: wrap; }
	.intro-stats__card { flex: 1 1 45%; }
}

/* Phone: single column; tighten section padding and gutter, and shrink the
   icon so it never crowds the number/label in a narrow card. */
@media (max-width: 767px) {
	.intro-stats { padding: 64px var(--sp-24); }
	.intro-stats__inner { gap: 40px; padding-inline: 0; }
	.intro-stats__cards { flex-direction: column; gap: var(--sp-16); }
	.intro-stats__card { flex: 1 1 auto; }
	.intro-stats__card-body { padding-right: 80px; }
	.intro-stats__icon {
		right: var(--sp-24);
		width: 64px;
		height: 64px;
	}
	.intro-stats__icon svg { width: 64px; height: 64px; }
}

/* ==========================================================================
   Home feature cards — Figma node 11151:3272
   2×2 grid of promo cards (title + desc → image → "Read more"). Sits directly
   under the intro + stat cards, so the section carries no top padding.
   ========================================================================== */
.feature-cards {
	padding: 0 var(--sp-80) 120px;
	background: var(--c-white);
}
.feature-cards__inner {
	padding-inline: 40px; /* + section 80 → ~120px Figma gutter */
}
.feature-cards__list {
	display: flex;
	flex-wrap: wrap;
	gap: var(--sp-32);
	margin: 0;
	padding: 0;
	list-style: none;
}
.feature-cards__item {
	display: flex; /* lets the card stretch to a shared row height */
	flex: 1 1 calc(50% - (var(--sp-32) / 2));
	min-width: 0; /* allow the flex item to shrink instead of overflow */
}

/* Card */
.feature-card,
.feature-card:hover,
.feature-card:focus,
.feature-card:focus-visible {
	text-decoration: none; /* section links never underline (interaction = nudge/lift only) */
}
.feature-card {
	display: flex;
	flex-direction: column;
	gap: var(--sp-16);
	width: 100%;
	padding: var(--sp-24);
	border: 1px solid var(--c-gray-200);
	border-radius: var(--radius-lg);
	background: var(--c-white);
	color: inherit;
}
.feature-card__text {
	display: flex;
	flex-direction: column;
	gap: var(--sp-8);
}
/* Font Hirarchy.docx (7 Aug 2026) changes BOTH axes of this title: Messina Sans
   32 → FK Roman 24. It is the only family change in the review, and it is
   deliberate — the four explore cards (Investors / About Us / Careers /
   Sustainability) are navigational headings, so the client wants them in the
   serif display face like every other heading, and a size down from 32 since
   the serif reads optically larger at the same measure. */
.feature-card__title {
	font-family: var(--ff-heading);
	font-weight: var(--fw-semibold);
	font-size: var(--fs-xl);
	line-height: var(--lh-base);
	/* Tracking dropped with the family: --ls-h3's -1% is tuned for Messina Sans
	   at display sizes, and FK Roman at 24 does not want negative tracking. */
	color: var(--c-text);
}
.feature-card__desc {
	font-family: var(--ff-body);
	font-weight: var(--fw-regular);
	font-size: var(--fs-m);   /* 18 → 16 (Font Hirarchy.docx, 7 Aug 2026) */
	line-height: var(--lh-base);
	color: var(--c-text-body);
}

/* Three reserved lines, so the four images sit on the same line as each other.
   The card is a column with the CTA pinned bottom (margin-top:auto), so the
   image's vertical position is decided by whatever the title + description
   happen to measure. That was invisible while all four descriptions were the
   same couple of lines of Figma copy; the client's 2026-09-03 wording ran ~230
   characters for About Us and Sustainability against ~100 for Investors and
   Careers, which dropped one image in each row a line lower than its
   neighbour's. His 2026-09-14 replacement copy is more even (86-137 characters
   across all four) but still not equal, so the reserve stays: it pads the short
   cards out to meet the long ones at any of these lengths.

   min-height, not a line-clamp: reserving space pads the short cards out to
   meet the long ones, where clamping would hide copy the client has just
   finished approving. Only from 768px up — below that the cards are a single
   column, nothing is beside anything, and the reserve would just be a gap. */
@media (min-width: 768px) {
	.feature-card__desc {
		min-height: calc(3 * var(--lh-base) * 1em); /* 3 x 22.4 = 67.2px at 16px */
	}
}
.feature-card__media {
	display: block;
	overflow: hidden; /* clips the hover zoom */
	aspect-ratio: 776 / 215; /* Figma image crop, no radius */
	line-height: 0;
}
.feature-card__img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
}
.feature-card__cta {
	display: inline-flex;
	align-items: center;
	gap: var(--sp-8);
	margin-top: auto; /* pins the CTA to the card bottom across a row */
	color: var(--c-primary);
}
.feature-card__cta-label {
	font-family: var(--ff-body);
	font-weight: var(--fw-bold);
	font-size: var(--fs-m);
	line-height: var(--lh-base);
	color: var(--c-primary);
}
.feature-card__cta-icon { display: inline-flex; }
.feature-card__cta-icon svg {
	display: block;
	width: 20px;
	height: 20px;
}

/* Laptop: match intro-stats' eased gutter; cards stay 2-up. */
@media (max-width: 1280px) {
	.feature-cards { padding: 0 var(--sp-64) 100px; }
	.feature-cards__inner { padding-inline: var(--sp-16); }
}

/* Phone: single column; tighten gutter and gaps. */
@media (max-width: 767px) {
	.feature-cards { padding: 0 var(--sp-24) 64px; }
	.feature-cards__inner { padding-inline: 0; }
	.feature-cards__list { flex-direction: column; gap: var(--sp-16); }
	.feature-cards__item { flex: 1 1 auto; }
}

/* ==========================================================================
   Home — Brands showcase — Figma node 11151:3279
   Eyebrow pill + two-tone heading + subhead, then a centred row of three brand
   logo cards on a faint maroon tint. Cards are links (lift/zoom on hover, never
   underline — see interaction block). Responsive rules follow this block.
   ========================================================================== */
.brands {
	padding: 100px var(--sp-80) 160px;
	background: var(--c-gray-05);
}
.brands__inner {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 60px;
	padding-inline: 40px; /* + section 80 → ~120px Figma gutter */
}

/* Header block — centred column */
.brands__header {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: var(--sp-16);
	text-align: center;
}
.brands__eyebrow {
	display: inline-flex;
	align-items: center;
	gap: var(--sp-8);
	margin: 0;
	padding: var(--sp-8) var(--sp-12);
	border-radius: 80px;
	background: var(--c-primary-10);
	color: var(--c-primary);
	font-family: var(--ff-body);
	font-weight: var(--fw-medium);
	font-size: var(--fs-m);
	line-height: var(--lh-base);
}
.brands__heading {
	margin: 0;
	font-family: var(--ff-heading);
	font-weight: var(--fw-bold);
	/* The font-size that used to be here is gone, and it is worth saying why
	   rather than leaving the reader to notice an absence. It set --fs-4xl for
	   the Font Hirarchy.docx of 7 Aug 2026, when this was the one H2 the client
	   had marked down from 60 — "Brands that People Trust, Every Day" is the
	   longest H2 in the theme and was the first to read oversized. On 2026-09-08
	   they asked for the same thing everywhere, so the rung moved to the h2
	   element rule at the top of this file and this override became a second way
	   of saying it. Nothing about this heading is special any more. */
	line-height: var(--lh-base); /* 1.4 */
	color: var(--c-dark);
}
.brands__heading-highlight { color: var(--c-primary); }
.brands__subhead {
	margin: 0;
	max-width: 640px;
	font-family: var(--ff-body);
	font-weight: var(--fw-regular);
	font-size: var(--fs-l2); /* 18 */
	line-height: var(--lh-base);
	color: var(--c-text-muted);
}

/* Cards row — three 480×267 logo cards, centred */
.brands__list {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	gap: var(--sp-32);
	width: 100%;
	margin: 0;
	padding: 0;
	list-style: none;
}
.brands__item {
	display: flex;
	/* Was `flex: 0 1 480px`, and that is the whole reason the three logo cards
	   dropped to two rows on a laptop (Font Hirarchy.docx item 8, 7 Aug 2026).

	   The trap: with flex-wrap:wrap the browser decides line breaks from each
	   item's HYPOTHETICAL main size — the flex-basis — and only shrinks items
	   afterwards, within the lines it already chose. flex-shrink therefore does
	   not prevent wrapping. Three 480px bases plus two 32px gaps hypothesise
	   1504px, so the row only survived while the content box was ≥1504 — i.e.
	   viewport ≥ ~1744px once the 240px of section+inner padding is taken off.
	   1920 cleared it (1680 available); every real laptop width did not. That is
	   exactly the "fine on large desktop, broken on laptop" report, and no amount
	   of font scaling could have fixed it — the cards contain images, not text.

	   `flex: 1 1 0` makes the hypothetical size 0, so wrapping is never triggered
	   by the basis; the items then grow to share the row equally and the existing
	   max-width caps them at the Figma 480. Net effect: identical 480px cards at
	   1920, one line all the way down to the ≤767 stack, nothing else changed. */
	flex: 1 1 0;
	max-width: 480px; /* Figma card width */
	min-width: 0;
}
.brand-card,
.brand-card:hover,
.brand-card:focus,
.brand-card:focus-visible {
	text-decoration: none; /* section links never underline (interaction = lift/zoom) */
}
.brand-card {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 100%;
	aspect-ratio: 480 / 267; /* Figma card proportion */
	padding: var(--sp-24);
	border: 1px solid var(--c-border);
	border-radius: var(--radius-lg);
	background: var(--c-primary-06);
}
.brand-card__logo {
	display: block;
	width: auto;
	height: auto;
	/* Logos are optically balanced within the card; per-brand fine sizing is
	   confirmed at the visual-verify step. object-contain keeps aspect ratio. */
	max-width: 70%;
	max-height: 70%;
	object-fit: contain;
}

/* ---- Responsive ------------------------------------------------------ */
/* Tablet 1280–768: tighter gutters + padding only. The cards no longer wrap 2-up
   here — that was the bug reported in Font Hirarchy.docx and is fixed on
   .brands__item above; all three now hold one line down to the ≤767 stack. */
@media (max-width: 1280px) {
	.brands { padding: 80px var(--sp-64) 120px; }
	.brands__inner { gap: var(--sp-48); padding-inline: var(--sp-16); }
	.brands__header { gap: var(--sp-12); }
}

/* Phone 767–320: single-column card stack, centred within the gutter. */
@media (max-width: 767px) {
	.brands { padding: 64px var(--sp-24) 80px; }
	.brands__inner { gap: var(--sp-32); padding-inline: 0; }
	.brands__list { gap: var(--sp-16); }
	.brands__item { flex: 1 1 100%; max-width: 420px; }
}

/* ==========================================================================
   Site footer (static) — Figma node 11151:3507
   Dark-maroon band: two-column top row (brand + cookie notice | contact card)
   above a divided bottom bar (legal links | copyright).
   ========================================================================== */
.site-footer {
	background: var(--c-primary-900);
	color: var(--c-gray-200);
}

.site-footer__inner {
	display: flex;
	flex-direction: column;
	gap: var(--sp-48);
	padding: var(--sp-80) 120px 60px;
}

/* ---- Top row --------------------------------------------------------- */
.site-footer__top {
	display: flex;
	align-items: flex-start;
	gap: var(--sp-32);
}

.site-footer__brand-col {
	flex: 1 1 auto;
	min-width: 0;
	display: flex;
	flex-direction: column;
	gap: var(--sp-24);
}

.site-footer__brand {
	display: inline-flex;
	color: var(--c-white); /* logo inherits currentColor → light on dark */
}
.site-footer__brand svg {
	display: block;
	height: 80px;
	width: auto;
}

.site-footer__cookies {
	list-style: disc;
	margin: 0;
	padding-left: var(--sp-24);
	max-width: 664px;
	display: flex;
	flex-direction: column;
	gap: var(--sp-12);
	color: var(--c-gray-200);
	font-family: var(--ff-body);
	font-size: var(--fs-m);
	font-weight: var(--fw-regular);
	line-height: var(--lh-base);
}

/* ---- Contact card ---------------------------------------------------- */
.site-footer__card {
	flex: 0 0 auto;
	width: 636px;
	max-width: 100%;
	box-sizing: border-box;
	display: flex;
	flex-direction: column;
	gap: var(--sp-12);
	padding: var(--sp-24);
	background: var(--c-gray-10); /* rgba(146,156,178,0.1) */
	border-radius: var(--radius-lg);
}

/* "Orkla India Limited" in the footer. Font Hirarchy.docx (7 Aug 2026) asks for
   32 → 24 AND centre → left. The alignment is the one non-typographic change in
   the review, and it is the right call: it was the only centred text in a footer
   whose every other column is left-aligned, so at 32px centred it read as a
   banner rather than as the head of its column. */
.site-footer__card-title {
	margin: 0;
	font-family: var(--ff-heading);
	font-weight: var(--fw-bold);
	font-size: var(--fs-xl);   /* 32 → 24 */
	line-height: var(--lh-base);
	color: var(--c-white);
	text-align: left;
}

.site-footer__contact {
	list-style: none;
	margin: 0;
	padding: 0;
	display: flex;
	flex-direction: column;
	gap: var(--sp-12);
}
.site-footer__contact-item {
	display: flex;
	align-items: flex-start;
	gap: var(--sp-8);
	color: var(--c-gray-200);
	font-family: var(--ff-body);
	font-weight: var(--fw-regular);
	font-size: var(--fs-m);   /* 18 → 16 (Font Hirarchy.docx, 7 Aug 2026) */
	line-height: var(--lh-base);
}
.site-footer__contact-item .icon {
	flex: 0 0 24px;
	width: 24px;
	height: 24px;
	color: var(--c-white);
}
.site-footer__contact-item .icon svg {
	display: block;
	width: 24px;
	height: 24px;
}
.site-footer__contact-item a {
	color: var(--c-gray-200);
	text-decoration: none;
}
.site-footer__contact-item a:hover,
.site-footer__contact-item a:focus-visible {
	color: var(--c-white);
	text-decoration: underline;
}

/* ---- Social row (2026-09-14) ----------------------------------------------
   Company profile links, centred under the address — the client's own mock.
   This is NOT the old per-page share row restyled: that row was removed from
   five templates and its CSS deleted with it. The circles are the same 48px
   outlined shape so the site keeps one vocabulary for an icon button, but the
   colours are inverted for the dark maroon band, where the old gray-600 on
   cream would have been nearly invisible.

   An unbound link (aria-disabled, awaiting the client's URLs) keeps the shape
   but drops to the muted colour and shows a default cursor, so it does not
   advertise itself as something that will go somewhere. */
.site-footer__social {
	display: flex;
	gap: var(--sp-8);
	align-items: center;
	justify-content: center;
	width: 100%;
	margin: var(--sp-24) 0 0;
	padding: 0;
	list-style: none;
}
.site-footer__social-link {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 48px;
	height: 48px;
	border: 0.75px solid rgba(255, 255, 255, 0.4);
	border-radius: 999px;
	color: var(--c-white);
	text-decoration: none;
	transition: color 0.2s ease, border-color 0.2s ease, background-color 0.2s ease, transform 0.2s ease;
}
.site-footer__social-link:hover,
.site-footer__social-link:focus-visible {
	color: var(--c-primary);
	background-color: var(--c-white);
	border-color: var(--c-white);
	transform: translateY(-2px);
}
.site-footer__social-link[aria-disabled="true"] {
	color: var(--c-gray-200);
	border-color: rgba(255, 255, 255, 0.2);
	cursor: default;
}
.site-footer__social-link[aria-disabled="true"]:hover {
	color: var(--c-gray-200);
	background-color: transparent;
	border-color: rgba(255, 255, 255, 0.2);
	transform: none;
}
.site-footer__social-icon svg {
	display: block;
	width: 22px;
	height: 22px;
}

/* ---- Bottom bar ------------------------------------------------------ */
.site-footer__bar {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--sp-24);
	flex-wrap: wrap;
	padding-top: var(--sp-32);
	border-top: 1px solid var(--c-white-20);
}
.site-footer__legal-links {
	list-style: none;
	margin: 0;
	padding: 0;
	display: flex;
	flex-wrap: wrap;
	gap: var(--sp-24);
}
.site-footer__legal-links a {
	display: inline-block;
	padding: 4px 0;
	color: var(--c-gray-100);
	font-family: var(--ff-body);
	font-weight: var(--fw-regular);
	font-size: var(--fs-m);   /* 18 → 16 (Font Hirarchy.docx, 7 Aug 2026) */
	line-height: var(--lh-base);
	text-decoration: none;
	border-bottom: 1px solid var(--c-gray-300);
}
.site-footer__legal-links a:hover,
.site-footer__legal-links a:focus-visible {
	color: var(--c-white);
	border-bottom-color: var(--c-white);
}
.site-footer__copyright {
	margin: 0;
	color: var(--c-gray-100);
	font-family: var(--ff-body);
	font-size: var(--fs-m);
	line-height: var(--lh-base);
}

/* ---- Footer responsive ----------------------------------------------- */
/* Tablet: collapse the big 120px side gutter, ease vertical padding. */
@media (max-width: 1280px) {
	.site-footer__inner {
		padding: var(--sp-64) var(--sp-32) var(--sp-48);
	}
}

/* Two columns get cramped before the phone breakpoint — stack them here. */
@media (max-width: 900px) {
	.site-footer__top {
		flex-direction: column;
		gap: var(--sp-32);
	}
	.site-footer__card {
		width: 100%;
	}
	.site-footer__cookies {
		max-width: none;
	}
}

/* Phone: tighter gutter, smaller logo, stack the bottom bar left-aligned. */
@media (max-width: 767px) {
	.site-footer__inner {
		gap: var(--sp-32);
		padding: var(--sp-48) var(--sp-16) var(--sp-32);
	}
	.site-footer__brand svg {
		height: 64px;
	}
	.site-footer__bar {
		flex-direction: column;
		align-items: flex-start;
		gap: var(--sp-16);
	}
	.site-footer__legal-links {
		gap: var(--sp-16);
	}
}

/* ==========================================================================
   Micro-interactions & polish (additive only)
   Subtle hover / focus / active states for a premium feel. No layout, colour,
   type, spacing or content changes — only transitions on opacity, transform,
   box-shadow, background-color and border-color (all GPU-friendly). Every
   effect degrades gracefully and is neutralised under prefers-reduced-motion
   (guard at the end of this block).
   ========================================================================== */

/* ---- 1. Buttons — hero CTA: lift + shadow on hover, subtle press ---- */
.hero__cta {
	transition: background-color 0.25s ease, box-shadow 0.25s ease, transform 0.2s ease;
	box-shadow: 0 2px 8px rgba(114, 4, 33, 0.18);
}
.hero__cta:hover,
.hero__cta:focus-visible {
	transform: translateY(-2px);
	box-shadow: 0 8px 20px rgba(114, 4, 33, 0.28);
}
.hero__cta:active {
	transform: translateY(0) scale(0.98);
	box-shadow: 0 2px 8px rgba(114, 4, 33, 0.18);
}

/* ---- 2. Navigation links — underline on focus + current page (NOT hover) ---- */
.nav-primary .menu-item > a { position: relative; }
.nav-primary .menu-item > a::before {
	content: "";
	position: absolute;
	left: 0;
	right: 0;
	bottom: 2px;
	height: 2px;
	background: currentColor;
	transform: scaleX(0);
	transform-origin: left center;
	transition: transform 0.25s ease;
}
/* Keyboard focus only — the hover underline was dropped by request (2026-07-30).
   The `opacity: 0.72` on :hover in the header section above is now the whole hover
   affordance, which is enough: white on maroon dims visibly.

   :focus-visible DELIBERATELY keeps the underline. The global focus ring is
   `outline: 2px solid var(--c-primary)` and this bar's background IS that same
   --c-primary (#720421), so the ring is invisible here — this white bar is the
   only visible focus indicator the primary nav has. Do not fold it into the
   hover removal, and do not "tidy" the two selectors back together. */
.nav-primary .menu-item > a:focus-visible::before {
	transform: scaleX(1);
}
/* Current page is marked by COLOUR, not an underline (user request,
   2026-07-31). The underline is left to :focus-visible alone, so the two states
   no longer look alike — previously a focused link and the current page drew
   the same white bar.

   Three surfaces, three colours, because the nav renders on three different
   backgrounds:
     - top level      white on --c-primary maroon      -> tan   (7.7:1)
     - desktop dropdown  dark on a white card          -> maroon, matching the
                                                          row's own hover
     - mobile drawer  white on --c-primary-600         -> tan (in the media
                                                          query below)
   Tan rather than cream: cream (#f2e2cf) sits too close to the white of its
   unselected siblings to read as a state change, while tan carries both a hue
   and a lightness shift, so it survives greyscale and colour-blind viewing.

   Colour is not the only signal — the anchor also carries aria-current="page",
   which is what assistive tech announces. Do not add font-weight here as a
   second visual cue: these are inline-flex items in a nowrap row, so a weight
   change reflows the whole menu as you navigate. */
.nav-primary .current-menu-item > a,
.nav-primary .current_page_item > a,
.nav-primary .current-menu-ancestor > a {
	color: var(--c-tan-200);
}
/* Dropdown rows sit on white, where tan would be unreadable (~1.6:1). Maroon
   is what the row already turns on hover, so current + hover agree. */
.nav-primary .sub-menu .current-menu-item > a,
.nav-primary .sub-menu .current_page_item > a,
.nav-primary .sub-menu .current-menu-ancestor > a {
	color: var(--c-primary);
}

/* ---- 3. Cards — intro stat cards lift with a stronger shadow + border ---- */
.intro-stats__card {
	transition: transform 0.25s ease, box-shadow 0.25s ease, border-color 0.25s ease;
}
.intro-stats__card:hover {
	transform: translateY(-5px);
	box-shadow: 0 12px 28px rgba(17, 17, 17, 0.08);
	border-color: var(--c-primary-20);
}

/* ---- 6. Icons — faded stat icon lifts gently with its card ---- */
.intro-stats__icon { transition: transform 0.25s ease; }
.intro-stats__card:hover .intro-stats__icon {
	transform: translateY(calc(-50% - 2px)); /* keeps the -50% centring */
}

/* ---- Feature cards — lift + shadow + border; image zoom; arrow nudge ---- */
.feature-card {
	transition: transform 0.25s ease, box-shadow 0.25s ease, border-color 0.25s ease;
}
.feature-card:hover,
.feature-card:focus-visible {
	transform: translateY(-5px);
	box-shadow: 0 12px 28px rgba(17, 17, 17, 0.08);
	border-color: var(--c-primary-20);
}
.feature-card:focus-visible {
	outline: 2px solid var(--c-primary);
	outline-offset: 3px;
}
.feature-card__img { transition: transform 0.4s ease; }
.feature-card:hover .feature-card__img,
.feature-card:focus-visible .feature-card__img {
	transform: scale(1.04);
}
.feature-card__cta-icon { transition: transform 0.25s ease; }
.feature-card:hover .feature-card__cta-icon,
.feature-card:focus-visible .feature-card__cta-icon {
	transform: translateX(3px);
}

/* ---- Brand cards — lift + shadow + border; logo zoom (no underline) ---- */
.brand-card {
	transition: transform 0.25s ease, box-shadow 0.25s ease, border-color 0.25s ease;
}
.brand-card:hover,
.brand-card:focus-visible {
	transform: translateY(-5px);
	box-shadow: 0 12px 28px rgba(17, 17, 17, 0.08);
	border-color: var(--c-primary-20);
}
.brand-card:focus-visible {
	outline: 2px solid var(--c-primary);
	outline-offset: 3px;
}
.brand-card__logo { transition: transform 0.4s ease; }
.brand-card:hover .brand-card__logo,
.brand-card:focus-visible .brand-card__logo {
	transform: scale(1.04);
}

/* ---- 8. (removed) Search form ----
   This held eight `.search-form*` rules written against the stock searchform.php
   — a bordered white field and a maroon submit. searchform.php now renders the
   designed row (`.search-hero`, styled with the Search takeover at the end of
   this file), so nothing emits `.search-form` any more and those rules were
   unreachable. Deleted rather than left in place: two blocks both claiming to
   style "the search form" is exactly the sort of thing that gets edited by
   mistake. Core's html5 `search-form` fallback cannot surface it either, since
   that only applies when the theme has no searchform.php. */

/* ---- Footer links — smooth colour / border transitions ---- */
.site-footer__contact-item a { transition: color 0.2s ease; }
.site-footer__legal-links a { transition: color 0.2s ease, border-color 0.2s ease; }

/* ---- Header search icon — smooth colour alongside its existing bg fade ---- */
.header-search { transition: background-color 0.18s ease, color 0.18s ease; }

/* ---- Drawer nav: no animated underline (links already have dividers) ----
   Must stay in step with the drawer breakpoint above (≤1279). */
@media (max-width: 1279px) {
	.nav-primary .menu-item > a::before { display: none; }
	/* The drawer flattens the white dropdown card onto the maroon panel, so the
	   desktop rule's maroon-on-white current colour would land maroon-on-maroon.
	   Back to tan, and clear the 0.85 idle opacity so the current row is the
	   brightest in its group.

	   This lives HERE, not in the ≤1279 block up at the drawer layout, because
	   the desktop `.nav-primary .sub-menu .current-menu-item > a` rule carries
	   the same 0,3,1 specificity and a media query adds none — placed earlier it
	   would simply lose to the desktop rule at every width. */
	.nav-primary .sub-menu .current-menu-item > a,
	.nav-primary .sub-menu .current_page_item > a,
	.nav-primary .sub-menu .current-menu-ancestor > a {
		color: var(--c-tan-200);
		opacity: 1;
	}
}

/* ==========================================================================
   Breadcrumb (interior pages) — Figma node 11281:2574
   Full-bleed maroon-tint bar; the trail is built from the live page hierarchy
   in template-parts/global/breadcrumb.php. Gutter mirrors the site sections
   (--sp-80 + 40px inner = 120px, reduced per breakpoint).
   ========================================================================== */
.breadcrumb {
	background-color: var(--c-primary-10);
	padding: var(--sp-16) var(--sp-80);
}

.breadcrumb__inner {
	padding-inline: 40px;
}

.breadcrumb__list {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 4px;
	margin: 0;
	padding: 0;
	list-style: none;
}

.breadcrumb__item {
	display: inline-flex;
	align-items: center;
	gap: 4px;
}

.breadcrumb__link,
.breadcrumb__current {
	padding: 2px 6px;
	font-family: var(--ff-body);
	font-size: var(--fs-m);
	line-height: var(--lh-base);
}

.breadcrumb__link {
	color: var(--c-gray-600);
	font-weight: var(--fw-regular);
	text-decoration: none;
	transition: color 0.18s ease;
}

.breadcrumb__link:hover,
.breadcrumb__link:focus-visible {
	color: var(--c-primary);
}

.breadcrumb__current {
	color: var(--c-text);
	font-weight: var(--fw-semibold);
}

.breadcrumb__sep {
	display: inline-flex;
	align-items: center;
	color: var(--c-gray-500);
}

.breadcrumb__sep svg {
	display: block;
	width: 18px;
	height: 18px;
}

@media (max-width: 1280px) {
	.breadcrumb { padding: var(--sp-16) var(--sp-64); }
	.breadcrumb__inner { padding-inline: var(--sp-16); }
}

@media (max-width: 767px) {
	.breadcrumb { padding: var(--sp-12) var(--sp-24); }
	.breadcrumb__inner { padding-inline: 0; }
}

/* ==========================================================================
   Page banner (artwork only) — ACF layout `page_banner`, News page
   A supplied picture with its own title painted into it, so this block draws no
   text: no scrim, no heading, nothing to clear a space for. See
   template-parts/sections/page-banner.php for why it is not a page-hero variant.

   THE CROP IS THE WHOLE DESIGN HERE. The artwork is 3 : 1, which at 1920 wide
   would stand 640px tall — most of a laptop screen, and the client asked for the
   opposite ("please don't make it look very big"). So the band is capped and the
   image fills it, which means something is always being cut off, and the only
   question is what. Two rules decide it:
     - Wide: cap the height and let the top and bottom go. The wording sits
       between roughly 25% and 62% of the artwork's height, so a centred crop
       keeps it until the band is thinner than about 5.6 : 1 — well past the cap.
     - Narrow: the band gets taller than 3 : 1 relative to its width, so the crop
       turns horizontal instead, and centring it would slice the title off the
       left edge. `object-position: left` gives the wording the side it is on and
       spends the loss on the scenery at the right, which carries nothing.
   ========================================================================== */
.page-banner {
	position: relative;
	background-color: var(--c-cream);
}

.page-banner__image {
	display: block;
	width: 100%;
	height: auto;
	max-height: clamp(240px, 26vw, 400px);
	aspect-ratio: 3 / 1;
	object-fit: cover;
	object-position: center;
}

@media (max-width: 767px) {
	.page-banner__image {
		/*
		 * 2 : 1 rather than the artwork's own 3 : 1. Held at 3 : 1 a phone gives
		 * the band about 125px, and the strapline under the title renders at
		 * roughly 6px — present, unreadable, and worse than absent because it
		 * still costs the space. The squarer box buys back half of that height.
		 */
		aspect-ratio: 2 / 1;
		max-height: none;
		object-position: left center;
	}
}

/* ==========================================================================
   Page hero (interior pages) — Figma node 11281:2576
   Full-bleed landscape photo with a cream scrim fading in from the left; the
   page title sits in the cleared left zone. Left edge aligns with the
   breadcrumb above (120 / 80 / 24 per breakpoint). ACF layout `page_hero`.
   ========================================================================== */
.page-hero {
	position: relative;
	display: flex;
	align-items: center;
	min-height: clamp(300px, 30vw, 460px);
	background-color: var(--c-cream);
	overflow: hidden;
}

/* Image layer — sits behind the scrim. */
.page-hero__media {
	position: absolute;
	inset: 0;
	background-size: cover;
	background-position: center right;
	background-repeat: no-repeat;
}

.page-hero__media--default {
	background-image: image-set(
		url("../images/sustainability-hero.webp") type("image/webp"),
		url("../images/sustainability-hero.jpg") type("image/jpeg")
	);
	/* Older engines that ignore image-set() still get the JPG. */
	background-image: url("../images/sustainability-hero.jpg");
	background-image: image-set(
		url("../images/sustainability-hero.webp") type("image/webp"),
		url("../images/sustainability-hero.jpg") type("image/jpeg")
	);
}

/* Per-page hero photo (About Us — Figma node 11247:10544, spice-market scene). */
.page-hero__media--about-us {
	background-image: url("../images/hero-about-us.jpg");
	background-image: image-set(
		url("../images/hero-about-us.webp") type("image/webp"),
		url("../images/hero-about-us.jpg") type("image/jpeg")
	);
}

/* Per-page hero photo (Careers — Figma node 11181:1507, colleagues walking the
   office floor). Standard photo treatment: the faces sit right of centre, which
   is where the shared `center right` anchor already holds them, so the cream
   scrim clears "A Home to Grow" without cropping anyone out. */
.page-hero__media--careers {
	background-image: url("../images/hero-careers.jpg");
	background-image: image-set(
		url("../images/hero-careers.webp") type("image/webp"),
		url("../images/hero-careers.jpg") type("image/jpeg")
	);
}

/* Per-page hero artwork (Our Brands — Figma node 11197:3837). A cut-out product
   collage on transparency, so PNG is the fallback rather than JPG: a JPG would
   flatten the alpha onto white and box the packs. Only meaningful together with
   .page-hero--product below, which supplies the band it sits on. */
.page-hero__media--our-brands {
	background-image: url("../images/hero-our-brands.png");
	background-image: image-set(
		url("../images/hero-our-brands.webp") type("image/webp"),
		url("../images/hero-our-brands.png") type("image/png")
	);
}

/* Cream scrim: solid at the left, transparent by mid-band. */
.page-hero::before {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 1;
	background: linear-gradient(
		90deg,
		var(--c-cream) 0%,
		var(--c-cream) 14%,
		rgba(242, 226, 207, 0.85) 26%,
		rgba(242, 226, 207, 0) 52%
	);
}

/* --------------------------------------------------------------------------
   Hero treatment: `product` (Our Brands — Figma node 11197:3837)
   No photo and no scrim. The band is a warm tan gradient and the artwork is a
   cut-out collage anchored right of centre, sized to fit so the packs are never
   cropped. Measured off the 1920×480 Figma frame:
     band      #f4e6d0 at x0 ramping linearly to #e4cca8 at x1080 (56.25%),
               flat from there to the right edge
     collage   x 765..1593 (w 829), y 39..455 (h 417)
   Both offsets are expressed as percentages of the frame width (327/1920 and
   829/1920) so the collage keeps its position at any viewport instead of
   drifting off a fixed pixel offset.
   Note: the Figma H1 sits ~40px above the band's vertical centre; that reads as
   placed-by-eye rather than intent, so this keeps the flex centring shared with
   the photo heroes.

   ORDER IS LOAD-BEARING: this block must stay below the two base rules it
   overrides. A BEM modifier is one class, so `.page-hero--product` ties with
   `.page-hero` and `.page-hero--product::before` ties with `.page-hero::before`
   — source order, not specificity, is what puts the tan band over the cream and
   switches the scrim off. Moving this above the base rules silently restores
   the cream wash over the packs.
   -------------------------------------------------------------------------- */
.page-hero--product {
	min-height: clamp(320px, 25vw, 480px);
	background: var(--c-tan-200) linear-gradient(
		90deg,
		var(--c-tan-100) 0%,
		var(--c-tan-200) 56.25%
	);
}

/* The scrim exists to clear the left zone of a photo. There is no photo here,
   and it would wash over the packs, so it is switched off. */
.page-hero--product::before {
	content: none;
}

.page-hero--product .page-hero__media {
	left: auto;                    /* inset:0 pins left; release it so right+width apply. */
	right: 17.03%;                 /* 327/1920 */
	width: 43.18%;                 /* 829/1920 */
	background-size: contain;
	background-position: center center;
}

.page-hero__inner {
	position: relative;
	z-index: 2;
	width: 100%;
	padding-block: var(--sp-64);
	padding-inline: 120px;
}

.page-hero__title {
	margin: 0;
	font-family: var(--ff-heading);
	font-weight: var(--fw-bold);
	font-size: var(--fs-6xl);
	line-height: var(--lh-tight);
	letter-spacing: var(--ls-h1);
	color: var(--c-dark);
}

@media (max-width: 1280px) {
	.page-hero__inner {
		padding-block: var(--sp-48);
		padding-inline: 80px;
	}
}

@media (max-width: 767px) {
	.page-hero {
		min-height: clamp(220px, 46vw, 320px);
	}
	.page-hero__inner {
		padding-block: var(--sp-32);
		padding-inline: var(--sp-24);
	}

	/* The desktop scrim is a HORIZONTAL gradient — opaque cream to 14%, gone by
	   52% — because the desktop H1 occupies the left third and the photo is
	   meant to show through beside it. On a phone the H1 spans the full width,
	   so from roughly the middle of its own line onward it is dark text on an
	   unscrimmed photograph. On About Us that is the spice-market scene and
	   "About Orkla India" is unreadable from the "k" rightward; reported
	   2026-10-28, and it applied to every photo hero, not just this page.

	   Same answer the home hero already uses at this breakpoint: a full-bleed
	   scrim rather than a directional one (see .hero__bg::after, ~line 1365).
	   Matching that rule's 0.86 alpha keeps the two bands looking alike where
	   they meet in a scroll. The photo stays visible underneath — this is a
	   wash, not a cover.

	   `--product` is excluded deliberately: that treatment has no photo and no
	   scrim, and at this width it stacks the heading above the collage instead
	   of overlaying it, so it has no contrast problem to fix. Both selectors
	   here are two classes to one, so they outrank the base `.page-hero::before`
	   on specificity and do not depend on source order the way the
	   `--product` block below does. */
	.page-hero:not(.page-hero--product)::before {
		background: rgba(242, 226, 207, 0.56);
	}
}

/* Product hero, tablet. The design's 17% right margin is dead space once the
   viewport narrows, so it is traded back to the collage. That widens the artwork
   and pushes its left edge outward at the same time, buying the heading room
   before it has to wrap: at 1024px the heading zone goes from 327px to 407px,
   which keeps "Our Brands" on one line at the 56px H1 this tier uses. Below
   ~900px it wraps to two lines, which the band has the height to absorb. */
@media (max-width: 1280px) {
	.page-hero--product .page-hero__media {
		right: 8%;
		width: 46%;
	}
}

/* Product hero, phone. Side by side stops working here — at 375px the heading
   would get ~148px against the ~215px "Our Brands" needs at the 40px H1, so the
   two would collide. The band therefore stacks: heading first, collage beneath
   it at full width. The media div is the first DOM child (it is the backdrop in
   the photo treatment), so it is dropped out of absolute positioning and
   reordered rather than moved in the markup — the photo heroes and this one keep
   sharing a single partial. Height is explicit because a background image gives
   an empty div nothing to size against. */
@media (max-width: 767px) {
	.page-hero--product {
		flex-direction: column;
		align-items: stretch;
		min-height: 0;             /* heading + collage define the band. */
	}
	.page-hero--product .page-hero__inner {
		order: 1;
		padding-block: var(--sp-32) var(--sp-24);
	}
	.page-hero--product .page-hero__media {
		order: 2;
		position: relative;        /* back into flow, below the heading. */
		inset: auto;               /* clears the desktop right offset. */
		width: 100%;
		height: clamp(180px, 52vw, 260px);
		margin-bottom: var(--sp-16);
	}
}

/* ==========================================================================
   Interior page heading (light) — Figma Sustainability Strategy 11290:2394.
   A large serif H1 on a plain white background (no photo hero). Same FK Roman
   Bold 60px treatment as the hero title. Gutter 120 / 80 / 24 aligns with the
   breadcrumb + hero + intro. Top padding is Figma's 120px (Life at Orkla India
   11195:3388 sits at y120 under the breadcrumb); the bottom pad is one
   --section-pad, which the following section's own top pad then stacks with —
   see the `.page-heading + …` pairings beside lead-media, value-cards, the two
   member grids and the careers bands, each of which cancels its half.
   ========================================================================== */
.page-heading {
	padding-block: clamp(var(--sp-64), 8vw, 120px) var(--section-pad);
	padding-inline: 120px;
	background: var(--c-white);
}

/* CAREERS SUB-PAGES ONLY — Career Paths, Life at Orkla India, Develop your
   skills with us, Employee Recognition. All four lead with a title and then go
   straight into body copy, with no photo, card grid or statement band to carry
   the weight, so Figma's 120px of air above the H1 reads as a gap rather than
   as breathing room — and doubly so on a phone, where it is a third of the
   screen before a word is legible. Cut to 80/48.

   Scoped by what FOLLOWS the heading rather than by page ID, so it travels with
   the markup instead of a database: `page_heading` immediately followed by
   `text_media` is those four careers pages and nothing else. Every other
   page_heading page keeps the full 120px. :has() is already load-bearing in
   this file (see .text-share:has(.text-share__card)). */
.page-heading:has(+ .text-media) {
	padding-block-start: clamp(var(--sp-48), 5vw, var(--sp-80));
}

.page-heading__inner {
	max-width: 1320px;
}

.page-heading__title {
	margin: 0;
	font-family: var(--ff-heading);
	font-weight: var(--fw-bold);
	font-size: var(--fs-6xl);
	line-height: var(--lh-tight);
	letter-spacing: var(--ls-h1);
	color: var(--c-dark);
}

/* Optional ALL-CAPS heading (Sustainability sub-pages, e.g. "NURTURING PLANET").
   CSS-only so the H1 text stays proper case in the markup. */
.page-heading__title--upper {
	text-transform: uppercase;
}

/* ---- Optional button beside the heading ---------------------------------
   NO FIGMA FRAME. Added 2026-09-10 for Grow with Us: the only link to the jobs
   board was the CTA at the foot of six sections, and the client asked for it to
   stand out. What was asked for was a blink; WCAG 2.2.2 and 2.3.1 rule that out,
   so this is the loudest thing the design system already has — .btn--primary,
   the filled accent button — moved to where the eye lands first.

   The row exists only when the button does (`--with-cta`), so the other 21
   page_heading pages keep their exact block layout and the wrapper div around the
   title is inert on them.

   Baseline is not shared: the H1 is 60px serif against a 16px button, and
   `align-items: baseline` would hang the button off the H1's first line and leave
   it stranded when the lead line pushes the text block taller. `flex-end` keeps
   it level with the BOTTOM of whatever the left column turns out to be, which is
   the same relationship whether or not there is a lead line.
   ------------------------------------------------------------------------- */
.page-heading__inner--with-cta {
	display: flex;
	flex-wrap: wrap;
	align-items: flex-end;
	justify-content: space-between;
	gap: var(--sp-24) var(--sp-32);
}

/* The title column takes the space and the button takes what it needs. Without
   this the flex base size is the H1's longest word and a two-word heading sits in
   a narrow column with a lake beside it. */
.page-heading__inner--with-cta .page-heading__text {
	flex: 1 1 420px;
}

.page-heading__cta {
	flex: 0 0 auto;
}

/* The arrow is the shared .btn__icon, and the label the shared .btn__label, so
   this button is the Shop CTA's markup with a different colour way — nothing here
   re-states a metric .btn already owns. .btn--primary widens its gap on hover, so
   the arrow nudge comes with it. */

/* Optional grey lead line under the H1 (Management, Figma 11251:4595), 16px
   below the title. Only rendered when the `lead` field is filled, so pages
   without one keep the heading's exact previous spacing. */
.page-heading__lead {
	margin: var(--sp-16) 0 0;
	font-family: var(--ff-body);
	font-weight: var(--fw-regular);
	font-size: var(--fs-l2);
	line-height: var(--lh-base);
	color: var(--c-text-muted);
}

@media (max-width: 1280px) {
	.page-heading {
		padding-inline: 80px;
	}
}

@media (max-width: 767px) {
	.page-heading {
		padding-inline: var(--sp-24);
	}
}

/* ==========================================================================
   Interior intro paragraph — Figma Sustainability 11281:2578 / 2988.
   One flowing paragraph: a maroon serif lead phrase (FK Roman Bold, 32px)
   opening the grey body-sans copy (Messina Sans, 24px). Left gutter aligns
   with the breadcrumb + hero (120 / 80 / 24).
   ========================================================================== */
.intro-text {
	padding-block: var(--section-pad);
	padding-inline: 120px;
}

/* Seven pages open with a title and then this paragraph — the CSR tree
   (Sustainability Strategy, Nurturing our Planet / Health / Communities) plus
   three more. Both pads were landing, so the gap between the H1 and the first
   line of copy was 128px. See the sanctioned-exception note beside the interior
   rhythm law below. */
@media (min-width: 901px) {
	.page-heading + .intro-text {
		padding-block-start: 0;
	}
}

.intro-text__inner {
	max-width: 1320px;
}

/* Optional section heading — Our Brands, Figma 11197:3840. Dark serif set at the
   48px H3 scale: Figma's own style for it is named "Heading/H3/Bold", so the token
   pair (--fs-4xl / --ls-h3) matches the design system rather than merely looking
   close. It renders as an <h2> because the page's <h1> lives in the hero.
   The 16px bottom margin is the measured Figma gap (heading ends y62, copy y78). */
.intro-text__heading {
	margin: 0 0 var(--sp-16);
	font-family: var(--ff-heading);
	font-weight: var(--fw-bold);
	font-size: var(--fs-4xl);       /* fluid 32 → 48 */
	line-height: var(--lh-heading); /* 1.3 */
	letter-spacing: var(--ls-h3);   /* -1px */
	color: var(--c-dark);
}

/* Photo beside the paragraph — the optional `image` (Supplier Code of Conduct,
   client's option C, 2026-10-09). The photo column is held at 464px, the same card
   width as the smaller two-across photo band, so photos read at one size across the
   Sustainability pages. Cropped to 4:3 so a panoramic source does not shrink to a
   strip beside six lines of text. Stacks under the text at tablet width. */
.intro-text--media {
	display: grid;
	grid-template-columns: minmax(0, 1fr) minmax(0, 464px);
	gap: var(--sp-64);
	align-items: center;
}
.intro-text__media {
	margin: 0;
}
.intro-text__img {
	display: block;
	width: 100%;
	height: auto;
	aspect-ratio: 4 / 3;
	object-fit: cover;
	border: 1px solid var(--c-gray-200);
	border-radius: var(--radius-lg);
}
@media (max-width: 900px) {
	.intro-text--media {
		grid-template-columns: minmax(0, 1fr);
		gap: var(--sp-32);
	}
	.intro-text__media {
		max-width: 560px;
	}
}

.intro-text__para {
	margin: 0;
	font-family: var(--ff-body);
	font-weight: var(--fw-regular);
	font-size: var(--fs-xl);
	line-height: var(--lh-base);
	color: var(--c-text-muted);
}

/* A stacked paragraph may quote a URL the reader is meant to follow (Governance
   "Key pillars": the two report.whistleb.com addresses). Those anchors are written
   by make_clickable() in the template, so they carry no class and were inheriting
   the paragraph's muted grey with no underline — indistinguishable from the prose
   around them. Brand maroon plus an underline so they read as links; the offset
   keeps the rule clear of the descenders in the URL's own glyphs. */
.intro-text__para a {
	color: var(--c-primary);
	text-decoration: underline;
	text-underline-offset: 2px;
	overflow-wrap: anywhere;   /* a bare URL has no spaces to break at on narrow screens */
}

.intro-text__para a:hover,
.intro-text__para a:focus-visible {
	color: var(--c-primary-600);
	text-decoration-thickness: 2px;
}

/* .intro-text__hl is the same treatment as the lead, applied to a phrase in the
   MIDDLE of the paragraph instead of at its start (Sustainability Strategy, client
   mail of 2026-09-16). It shares the lead's rules rather than restating them, here
   and in the --large step below, so the two can never drift apart — which would
   read on the page as one emphasis in the wrong size. */
.intro-text__lead,
.intro-text__hl {
	font-family: var(--ff-heading);
	font-weight: var(--fw-bold);
	font-size: var(--fs-2xl);
	line-height: var(--lh-base);
	color: var(--c-primary);
}

/* Larger intro variant — Sustainability Strategy pages (Figma 11290): a larger
   lead (FK Roman Bold, 40px) opening 32px body copy. Triggered two ways:
   (1) automatically when a second paragraph is present (two-paragraph intro on
   page 42, led by an inline SemiBold label "Plan Nurture :", #24272c); and
   (2) explicitly via the `.intro-text--large` modifier for single-paragraph
   pages that still want the big type (e.g. Nurturing Planet, page 43). Standard
   single-paragraph pages (Sustainability 11281) keep the 32/24 sizing above.
   Both sizes ride token stepdowns (--fs-3xl / --fs-2xl) for free at tablet + phone. */
.intro-text--large .intro-text__para,
.intro-text:has(.intro-text__para--secondary) .intro-text__para {
	font-size: var(--fs-2xl); /* 32 */
}
.intro-text--large .intro-text__lead,
.intro-text--large .intro-text__hl,
.intro-text:has(.intro-text__para--secondary) .intro-text__lead,
.intro-text:has(.intro-text__para--secondary) .intro-text__hl {
	font-size: var(--fs-3xl); /* 40 */
}
/* Figma 11290:2745 drew this as a single flowing text block — the second paragraph
   starting on a new line with normal line spacing and no paragraph gap. The client
   asked for the gap on 2026-10-21 ("a gap of approximately one line between the two
   paragraphs"), which supersedes that, so the two now read as two paragraphs.

   One line, not a fixed 32px: tied to the paragraph's own line-height so it stays
   exactly one line deep as the type rides its clamp down the breakpoints. */
.intro-text__para--secondary {
	margin-top: calc(var(--lh-base) * 1em);
}
.intro-text__label {
	font-family: var(--ff-body);
	font-weight: var(--fw-semibold);
	color: var(--c-text);
}

/* Stacked multi-paragraph intro (About Us, Figma 11247:10546): distinct
   paragraphs separated by a 32px gap, at standard 32/24 sizing (the maroon serif
   lead only opens the paragraphs that supply one). */
.intro-text--stacked .intro-text__inner {
	display: flex;
	flex-direction: column;
	gap: var(--sp-32);
}

/* In stacked mode the heading becomes a flex item, so the 32px column gap already
   separates it from the first paragraph and its own margin would stack on top of
   that. Two classes (0,2,0) beats the base (0,1,0), so this holds wherever it sits. */
.intro-text--stacked .intro-text__heading {
	margin-bottom: 0;
}

/* About Us — Vision/Mission/Values cards (Figma 11247:10550).

   Was a flex-wrap row: a fixed 308px logo card plus cards at `flex: 1 1 480px`.
   That gave row one two wide cards and row two three narrower ones, with no
   column edge shared between them — tolerable when each card held a paragraph
   and the eye had text to follow, obviously ragged once the client stripped the
   cards back to a single word (2026-09-03). It is a real 3-column grid now, so
   all six cells align vertically and the two Figma rows survive as rows 1 and 2.

   Height is one shared token rather than a per-card min-height: every tile in
   both rows is the same height, which is the thing that makes a grid read as
   designed rather than as content that happened to wrap. */
.about-cards {
	--about-card-h: 168px; /* was 214, sized for three lines of body copy. */
	padding-block: 0 100px; /* pb-100; sits directly under the intro. */
	padding-inline: 120px;
}

.about-cards__grid {
	display: grid;
	grid-template-columns: repeat(3, 1fr);
	gap: var(--sp-32);
	max-width: 1680px;
	margin-inline: auto;
}

/* Two-up, for a tile count that divides evenly into it (About Us, client
   2026-10-21: four link tiles, where three-up left one stranded on its own row).
   The base rule above stays three, so every grid that predates this is untouched;
   the 1024 and 767 steps below override both and need no variant of their own. */
.about-cards__grid--cols-2 {
	grid-template-columns: repeat(2, 1fr);
}

.about-cards__logo-card {
	display: flex;
	align-items: center;
	justify-content: center;
	min-height: var(--about-card-h);
	background: var(--c-primary-05);   /* matches the link tiles' tint (2026-10-21) */
	border-radius: var(--radius-lg);
}

.about-cards__logo {
	display: inline-flex;
	width: 178px;
}

.about-cards__logo svg {
	display: block;
	width: 100%;
	height: auto;
}

/* Title left, arrow chip right, both on the vertical centre line. A single word
   centred in an otherwise empty box reads as a layout that lost its content;
   giving the tile a second anchor at the opposite edge gives the eye somewhere
   to travel and makes the emptiness deliberate. */
/* Brand tint over the neutral grey, with a maroon bar down the leading edge
   (client 2026-10-21, "make this boxes attractive"). The tile read as an empty
   grey box at rest and only became branded on hover, which a visitor who never
   hovers — anyone on a phone — never saw.

   The bar is a ::before rather than a border-inline-start, so the hover can grow
   it without the 1px border shifting the padding box and nudging the text. It
   sits on the LOGICAL start edge so it flips with the writing direction. */
.about-cards__item {
	position: relative;
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--sp-24);
	min-height: var(--about-card-h);
	padding: var(--sp-32);
	padding-inline-start: 40px;   /* 32 + the 4px bar + 4 of air; off the token scale */
	overflow: hidden;                      /* keeps the bar inside the radius */
	background: var(--c-primary-05);
	border: 1px solid var(--c-primary-10);
	border-radius: var(--radius-lg);
	text-decoration: none;
	transition: transform 0.25s ease, box-shadow 0.25s ease, border-color 0.25s ease, background-color 0.25s ease;
}

.about-cards__item::before {
	content: "";
	position: absolute;
	inset-block: 0;
	inset-inline-start: 0;
	width: 4px;
	background: var(--c-primary);
	transition: width 0.25s ease;
}

/* The serif, as .link-cards__title does on CSR and Legal: these four tiles are
   section titles rather than UI labels, and the serif is what the site uses for
   that everywhere else. Changed with the tint above on 2026-10-21. */
.about-cards__title {
	margin: 0;
	font-family: var(--ff-heading);
	font-weight: var(--fw-semibold);
	font-size: var(--fs-2xl); /* 32 */
	line-height: 1.4;
	letter-spacing: var(--ls-h3);   /* was -0.32px = 32 x -1%; now em, so it scales */
	color: var(--c-text);
	transition: color 0.25s ease;
}

/* The "Read more" wording is gone at the client's request; the arrow is kept as
   an icon-only chip because a flat box holding one word gives a visitor nothing
   that says "this is a link". It carries no accessible name of its own — the
   title is the anchor's name, and orkla_icon() marks the glyph aria-hidden. */
.about-cards__go {
	display: inline-flex;
	flex: 0 0 auto;
	align-items: center;
	justify-content: center;
	width: 48px;
	height: 48px;
	background: var(--c-white);
	border: 1px solid var(--c-primary-20);   /* was gray-200; reads as part of the tinted tile */
	border-radius: 50%;
	color: var(--c-primary);
	transition: background-color 0.25s ease, border-color 0.25s ease, color 0.25s ease, transform 0.25s ease;
}

.about-cards__go-icon,
.about-cards__go-icon svg {
	display: block;
	width: 20px;
	height: 20px;
}

/* Hover: the tile lifts and turns maroon at its edges, and the chip inverts to
   solid maroon. One gesture, three surfaces moving together. */
.about-cards__item:hover {
	transform: translateY(-4px);
	background: var(--c-primary-10);
	border-color: var(--c-primary);
	box-shadow: 0 12px 28px rgba(36, 39, 44, 0.08);
	text-decoration: none; /* override global a:hover underline */
}

/* The bar widens into the tile — the fourth surface in the same gesture. */
.about-cards__item:hover::before,
.about-cards__item:focus-visible::before {
	width: 8px;
}

.about-cards__item:hover .about-cards__title {
	color: var(--c-primary);
	text-decoration: none;
}

.about-cards__item:hover .about-cards__go {
	background: var(--c-primary);
	border-color: var(--c-primary);
	color: var(--c-white);
	transform: translateX(4px);
}

.about-cards__item:focus-visible {
	outline: 2px solid var(--c-primary);
	outline-offset: 2px;
}

@media (max-width: 1280px) {
	.about-cards {
		padding-inline: 80px;
	}
}

/* Two columns before the titles start crowding the chip. Six cells over three
   rows, so the grid stays rectangular at every step. */
@media (max-width: 1024px) {
	.about-cards {
		--about-card-h: 148px;
	}

	.about-cards__grid {
		grid-template-columns: repeat(2, 1fr);
	}
}

@media (max-width: 767px) {
	.about-cards {
		--about-card-h: 96px;
		padding-inline: var(--sp-24);
		padding-block: 0 var(--sp-48);
	}

	.about-cards__grid {
		grid-template-columns: 1fr;
		gap: var(--sp-16);
	}

	/* Shorter, tighter chips: stacked full-width, the tiles become a list, and a
	   168px-tall row of one word each would be a lot of scrolling for five links. */
	.about-cards__item {
		padding: var(--sp-24);
		padding-inline-start: var(--sp-32);   /* shorthand above resets it; keep the text off the bar */
	}

	.about-cards__go {
		width: 40px;
		height: 40px;
	}

	.about-cards__logo-card {
		min-height: 0;
		padding-block: var(--sp-32);
	}
}

@media (max-width: 1280px) {
	.intro-text {
		padding-inline: 80px;
	}
}

@media (max-width: 767px) {
	.intro-text {
		padding-inline: var(--sp-24);
	}
	.intro-text__para {
		font-size: var(--fs-l2); /* 18 */
	}
}

/* ==========================================================================
   Text + share — plain body paragraphs. (The section is still named text_share
   in ACF; its centred social share row was removed sitewide on 2026-09-14 at
   the client's request, and the shared .*__share styling went with it.)
   Nurturing Health 11297:4343. Same gutter/rhythm as intro-text; body type
   matches .intro-text__para (grey Messina 24).
   ========================================================================== */
.text-share {
	padding-block: var(--section-pad);
	padding-inline: 120px;
}

/* Card-only layout (e.g. Nurturing Communities CTA) follows a full section
   that already supplies ~100px of bottom rhythm, so cut the section's own top
   padding right down — otherwise the two stack into an oversized gap. Scoped
   with :has() so the paragraph layout (page 44) keeps its generous top space. */
.text-share:has(.text-share__card) {
	padding-top: clamp(var(--sp-16), 2vw, 32px);
}

.text-share__inner {
	display: flex;
	flex-direction: column;
	gap: 100px; /* Figma inter-block gap (text → share), off the token scale */
}

/* Spacing inside the text block is done with sibling margins rather than a flex
   `gap`, because the two pairs differ: paragraph→paragraph is 32px, but
   heading→paragraph is only 16px (Career Paths 11238:10432 — heading ends y45,
   copy starts y61). A single `gap` cannot express both. Paragraph-only pages are
   unaffected: `p + p` reproduces the 32px they had before. */
.text-share__text {
	display: flex;
	flex-direction: column;
	max-width: 1320px; /* Figma: body text left-aligned at the gutter, capped 1320. */
}

.text-share__para {
	margin: 0;
	font-family: var(--ff-body);
	font-weight: var(--fw-regular);
	font-size: var(--fs-xl);
	line-height: var(--lh-base);
	color: var(--c-text-muted);
	/* Last-resort break only if a single word can't fit. Needed since Career Paths
	   ends on talent.acquisition@orklaindia.com — 33 unbreakable characters, which
	   at 18px overflows the 24px gutters below ~360px and would otherwise push the
	   whole document into horizontal scroll. Inert on every other page: normal
	   words always fit, so nothing already shipped re-wraps. */
	overflow-wrap: break-word;
}

.text-share__para + .text-share__para,
.text-share__para + .text-share__heading {
	margin-top: var(--sp-32);
}

/* Optional per-row heading inside the text block — Career Paths, Figma
   11238:10433 ("We want to meet you!"). Maroon serif bold at the 32px H5 scale:
   the Figma line box is 45px tall, which is 32 × 1.4 (--lh-base) to the pixel.
   Smaller and maroon rather than the dark 48px .intro-text__heading, because this
   titles a paragraph inside a block rather than opening a section. --fs-2xl
   already steps down to 24px at ≤767px, so it needs no responsive override of its
   own. It can appear mid-flow, hence the `p + h2` rule above: 32px clear of the
   paragraph before it, 16px above its own. */
.text-share__heading {
	margin: 0 0 var(--sp-16);
	font-family: var(--ff-heading);
	font-weight: var(--fw-bold);
	font-size: var(--fs-2xl);
	line-height: var(--lh-base);
	color: var(--c-primary);
}

/* Inline label running into its own paragraph — "Energy: Orkla India has made
   measurable progress…" (Sustainability, client mail of 2026-09-16). The sibling
   of .text-share__heading above, for the case where the label belongs IN the
   sentence rather than on a line of its own.

   Deliberately no font-size: it inherits .text-share__para, so it rides that
   rule's responsive steps for free and can never end up a different size from the
   sentence it opens. Maroon serif is what distinguishes it, not scale. */
.text-share__label {
	font-family: var(--ff-heading);
	font-weight: var(--fw-bold);
	color: var(--c-primary);
}

/* CTA card — highlighted link block (e.g. CSR Annual Action Plan PDF).
   Left-aligned everywhere, which is this default; centred on
   /nurturing-communities/ only — see PAGE-SCOPED OVERRIDES at the foot of this
   file before changing anything here. */
.text-share__card {
	display: flex;
	flex-direction: column;
	gap: var(--sp-16);
	max-width: 800px; /* Figma card width. */
	padding: var(--sp-24);
	background: rgba(146, 156, 178, 0.05); /* gray/opacity/05 */
	border: 1px solid var(--c-border, #dee1e7);
	border-radius: var(--radius-lg, 12px);
}

.text-share__card-text {
	margin: 0;
	font-family: var(--ff-heading);
	font-weight: var(--fw-semibold);
	font-size: var(--fs-xl); /* 24 */
	line-height: var(--lh-base);
	color: var(--c-text); /* #24272c */
}

.text-share__card-btn {
	display: inline-flex;
	align-items: center;
	gap: var(--sp-8);
	align-self: flex-start;
	font-family: var(--ff-body);
	font-weight: var(--fw-bold);
	font-size: var(--fs-m); /* 16 */
	line-height: var(--lh-base);
	color: var(--c-primary); /* #720421 */
	text-decoration: none;
	transition: gap 0.2s ease, opacity 0.2s ease;
}

.text-share__card-btn:hover,
.text-share__card-btn:focus-visible {
	gap: var(--sp-12); /* arrow nudge, no underline (section-link rule) */
}

.text-share__card-btn-icon {
	display: inline-flex;
	width: 20px;
	height: 20px;
	flex: none;
}

.text-share__card-btn-icon svg {
	width: 100%;
	height: 100%;
}

@media (max-width: 1280px) {
	.text-share {
		padding-inline: 80px;
	}
	.text-share__inner {
		gap: var(--sp-80);
	}
}

@media (max-width: 767px) {
	.text-share {
		padding-inline: var(--sp-24);
	}
	.text-share__para {
		font-size: var(--fs-l2); /* 18 */
	}
	.text-share__inner {
		gap: var(--sp-48);
	}
	.text-share__card {
		padding: var(--sp-16);
	}
	.text-share__card-text {
		font-size: var(--fs-l2); /* 18 */
	}
}

/* ==========================================================================
   Link cards — grid of equal-width link cards + centred share (CSR 11297:6270)
   A row of cards (serif title + one maroon CTA) over the shared social share row.
   Card style mirrors the text-share CTA card (light-grey border, 12px radius,
   24px padding) but on a Gray/Opacity/05 tint rather than white; the CTA reuses
   the maroon arrow-nudge treatment (no underline, per the section-link rule).
   Gutter 120/80/24 aligns with the other sections.

   TWO consumers, and they differ only in scale: CSR (11297:6270) is three cards
   with the share row on, at H6 Semibold 24; Legal (11299:8077) is two cards with
   the share row off, at 32 Bold. Legal's overrides are scoped by the
   `.page-heading + .link-cards` adjacency at the foot of this block — CSR has an
   `intro_text` between its heading and its cards, so that selector cannot reach it.
   ========================================================================== */
.link-cards {
	padding-block: var(--section-pad);
	padding-inline: 120px;
}

.link-cards__inner {
	display: flex;
	flex-direction: column;
	gap: 100px; /* Figma inter-block gap (cards → share), off the token scale */
}

.link-cards__grid {
	display: grid;
	grid-template-columns: repeat(3, 1fr);
	gap: var(--sp-32);
	margin: 0;
	padding: 0;
	list-style: none;
}

.link-cards__item {
	display: flex;
	flex-direction: column;
	justify-content: space-between; /* pin CTA to the bottom for equal-height cards */
	gap: var(--sp-24);
	padding: var(--sp-24);
	background: var(--c-gray-05); /* Figma Gray/Opacity/05 #929cb20d — a tint, not white */
	border: 1px solid var(--c-gray-200);
	border-radius: var(--radius-lg, 12px);
}

.link-cards__title {
	margin: 0;
	/* CORRECTED 2026-07-31. This block previously claimed Figma set the title in
	   Messina Semibold 32 with -0.32px tracking on a white card, and was written
	   that way. Both CSR (11297:6270) and Legal (11299:8077) in fact use the SERIF
	   at tracking 0 on the Gray/Opacity/05 tint above — verified by rendering the
	   nodes, not by reading the variable list, which reports a subtree's values
	   without saying which node consumes them. Base is CSR's own Heading/H6/
	   Semibold 24; Legal's larger 32 Bold is scoped below. */
	font-family: var(--ff-heading);
	font-weight: var(--fw-semibold);
	font-size: var(--fs-xl); /* 24 */
	line-height: var(--lh-base); /* 1.4 */
	letter-spacing: 0;
	color: var(--c-text); /* #24272c */
}

.link-cards__cta {
	display: inline-flex;
	align-items: center;
	gap: var(--sp-8);
	align-self: flex-start;
	font-family: var(--ff-body);
	font-weight: var(--fw-bold);
	font-size: var(--fs-m); /* 16 */
	line-height: var(--lh-base);
	color: var(--c-primary); /* #720421 */
	text-decoration: none;
	transition: gap 0.2s ease, opacity 0.2s ease;
}

.link-cards__cta:hover,
.link-cards__cta:focus-visible {
	gap: var(--sp-12); /* arrow nudge, no underline (section-link rule) */
}

.link-cards__cta-icon {
	display: inline-flex;
	width: 20px;
	height: 20px;
	flex: none;
}

.link-cards__cta-icon svg {
	width: 100%;
	height: 100%;
}

/* ---- Legal landing page only (Figma 11299:8077) ------------------------- *
 * Scoped by what PRECEDES the section rather than by page ID, so it travels
 * with the markup instead of a database — the same reasoning as the careers
 * page-heading overrides. `page_heading` immediately followed by `link_cards`
 * exists only on /legal/: CSR, the other consumer, has an `intro_text` between
 * the two, so it keeps the 24px base above.
 *
 * Held to >=768 because --fs-2xl itself drops to 24 at 767 (tokens.css:127), so
 * below that the bump would resolve to the base size anyway; gating it says so
 * explicitly rather than relying on two rules cancelling out. */
@media (min-width: 768px) {
	.page-heading + .link-cards .link-cards__title {
		font-size: var(--fs-2xl); /* 32 */
		font-weight: var(--fw-bold);
	}
}

@media (min-width: 901px) {
	/* Two cards, not three (824 + 32 gap + 824 = Figma's 1680 content width).
	   Driven off the child COUNT rather than a page class so the section stays
	   self-describing: a future 2-card page gets it for free, and a third card
	   added in the admin returns to thirds without a code change.

	   Must stay inside this query. `:has(> :last-child:nth-child(2))` outranks
	   the plain `.link-cards__grid` in the <=900 block below, so at the top level
	   it would defeat the mobile stack and leave two cramped columns on a phone. */
	.link-cards__grid:has(> :last-child:nth-child(2)) {
		grid-template-columns: repeat(2, 1fr);
	}

	/* The Legal page-heading sits directly above the cards, so its bottom pad and
	   the section's top pad would stack into a doubled gap. Cancel the top pad on
	   desktop, exactly as .page-heading + .value-cards / .lead-media / the two
	   member grids do. Released below the tablet stack.

	   NOTE this yields one --section-pad (64px) between title and cards, where
	   Figma draws 100px, and 64px below them where Figma draws 120px. Deliberate:
	   the theme standardised interior rhythm on --section-pad so the gap is
	   uniform across every page and retunable from one token, and every sibling
	   pairing cancels to 0 for that reason. Matching Figma here would need two
	   per-page magic numbers and would make Legal's title sit lower than the
	   identically-structured Values and Vision pages. Swap the 0 for
	   `padding-block: 36px 120px` if the exact Figma figures are wanted instead. */
	.page-heading + .link-cards {
		padding-block-start: 0;
	}
}

/* ------------------------------------------------------------------ *
 * CSR & ESG Committee — member cards + charter CTA card
 * Figma "CSR -> Composition of the Committee" body node 11298:6355.
 * ------------------------------------------------------------------ */
.committee-members {
	padding: 100px var(--sp-80) 120px;
	background: var(--c-white);
}

/* CSR & ESG Committee is the worst of the uncancelled joins — its own 100px top
   pad on top of the heading's 64 made 164px. Longhand after the shorthand above,
   which is the only order that overrides it. */
@media (min-width: 901px) {
	.page-heading + .committee-members {
		padding-block-start: 0;
	}
}

.committee-members__inner {
	max-width: 1680px;
	margin-inline: auto;
	padding-inline: 40px;
	display: flex;
	flex-direction: column;
	gap: var(--sp-48);
}

.committee-members__grid {
	display: flex;
	flex-wrap: wrap;
	gap: var(--sp-32);
	margin: 0;
	padding: 0;
	list-style: none;
}

.committee-members__item {
	flex: 1 1 320px;
	max-width: 396px;
	display: flex;
}

.committee-member {
	display: flex;
	flex-direction: column;
	width: 100%;
	background: var(--c-primary-05);
	border: 1px solid var(--c-gray-200);
	border-radius: var(--radius-lg);
	overflow: hidden;
	transition: transform 0.25s ease, box-shadow 0.25s ease, border-color 0.25s ease;
}

.committee-member:hover {
	transform: translateY(-4px);
	box-shadow: 0 16px 33px -2px rgba(28, 39, 49, 0.08);
	border-color: var(--c-primary-20);
}

.committee-member__photo {
	aspect-ratio: 396 / 327;
	/* Warm cream placeholder shown until a real member photo is uploaded. */
	background-color: #e6ccb8;
	overflow: hidden;
}

.committee-member__img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.committee-member__body {
	display: flex;
	flex-direction: column;
	gap: var(--sp-8);
	padding: 20px var(--sp-24) var(--sp-24);
	/* Grow to fill the equal-height card so the CTA can sit at the bottom. */
	flex: 1 1 auto;
}

.committee-member__name {
	margin: 0;
	font-family: var(--ff-body);
	font-weight: var(--fw-bold);
	font-size: var(--fs-xl);
	line-height: var(--lh-base);
	color: var(--c-text);
}

.committee-member__role {
	margin: 0;
	font-family: var(--ff-body);
	font-weight: var(--fw-medium);
	font-size: var(--fs-l2);
	line-height: var(--lh-base);
	color: var(--c-text-muted);
}

.committee-member__cta {
	/* Pin to the card bottom so Read More aligns across a row regardless of
	   how many lines the name/role wrap to. The body's gap keeps a min gap. */
	margin-top: auto;
	align-self: flex-start;
	display: inline-flex;
	align-items: center;
	gap: var(--sp-8);
	font-family: var(--ff-body);
	font-weight: var(--fw-bold);
	font-size: var(--fs-m);
	color: var(--c-primary);
	text-decoration: none;
	transition: color 0.2s ease;
}

.committee-member__cta:hover,
.committee-member__cta:focus-visible {
	color: var(--c-primary-600);
}

.committee-member__cta-icon {
	display: inline-flex;
	width: 20px;
	height: 20px;
	flex: none;
	transition: transform 0.25s ease;
}

.committee-member__cta-icon svg {
	width: 100%;
	height: 100%;
}

.committee-member:hover .committee-member__cta-icon {
	transform: translateX(3px);
}

.committee-members__charter {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: 20px;
	/* Fixed 600px box at the LEFT of the section (Figma node 11298:7253 = 600×124,
	   24px padding), NOT the full member-grid width. Content sits top-left: heading
	   stacked above a left-aligned maroon "Read PDF" text link (matches the member
	   cards' CTA), not a right-aligned solid button. max-width keeps it fluid below
	   600px on smaller screens. */
	align-self: flex-start;
	width: 600px;
	max-width: 100%;
	padding: var(--sp-24);
	background: var(--c-gray-05);
	border: 1px solid var(--c-gray-200);
	border-radius: var(--radius-lg);
}

.committee-members__charter-text {
	margin: 0;
	font-family: var(--ff-heading);
	font-weight: var(--fw-semibold);
	font-size: var(--fs-xl);
	line-height: var(--lh-heading);
	color: var(--c-text);
}

.committee-members__charter-btn {
	display: inline-flex;
	align-items: center;
	gap: var(--sp-8);
	font-family: var(--ff-body);
	font-weight: var(--fw-bold);
	font-size: var(--fs-m);
	color: var(--c-primary);
	text-decoration: none;
	transition: color 0.2s ease;
}

.committee-members__charter-btn:hover,
.committee-members__charter-btn:focus-visible {
	color: var(--c-primary-600);
}

.committee-members__charter-btn-icon {
	display: inline-flex;
	width: 20px;
	height: 20px;
	flex: none;
	transition: transform 0.25s ease;
}

.committee-members__charter-btn-icon svg {
	width: 100%;
	height: 100%;
}

.committee-members__charter-btn:hover .committee-members__charter-btn-icon,
.committee-members__charter-btn:focus-visible .committee-members__charter-btn-icon {
	transform: translateX(3px);
}

/* The same section, one page down an IR tree.
   ---------------------------------------------------------------------------
   This block was drawn for CSR & ESG (page 60), where it sits under a
   page_heading and owns its own gutter: 80 on the section plus 40 on the inner
   makes the 120 edge, and 100 of top padding clears the heading.

   Under .ir-header the two jobs above are already done by someone else, and
   done to different numbers. The header carries no bottom padding on purpose
   (see the .doc-cards note further down) so the section below sets the gap, and
   its tab rows sit in a 1680 box with a flat 120 gutter. Left alone, the
   committee grid would start 100px below the tabs instead of 64 and sit 40px
   inboard of them — a visible step at the left edge on a page where the tab row
   is directly above the first card.

   So: --section-pad on top, matching what .doc-cards does under the same header
   for the same reason (it stands in for Figma's 60px, the 4px approximation
   this file makes at every heading pairing), and the gutter moved wholly onto
   the section so 120 means 120. Bottom padding is untouched — that is this
   section's own trailing space, not a relationship with the header.

   Scoped to the adjacency, so page 60 is not touched. The sections are direct
   siblings: page-templates/template-content-sections.php prints each partial
   into the page with no wrapper. */
.ir-header + .committee-members {
	padding-top: var(--section-pad);
	padding-inline: 120px;
}

.ir-header + .committee-members .committee-members__inner {
	padding-inline: 0;
}

@media (max-width: 1280px) {
	.committee-members {
		padding: 80px var(--sp-64) 100px;
	}

	/* The shorthand above cannot reach a committee page: it is one class, the
	   adjacency override is two, and specificity beats source order. So the
	   gutter has to be restated here, on the same selector, walking the same
	   120 / 80 / 24 ladder as .ir-header and .doc-cards. Only the gutter —
	   padding-bottom still comes from the shorthand, and padding-top is
	   --section-pad, which is a clamp and scales without help. */
	.ir-header + .committee-members {
		padding-inline: 80px;
	}

	.committee-members__inner {
		padding-inline: var(--sp-16);
	}
}

@media (max-width: 767px) {
	.committee-members {
		padding: 64px var(--sp-24);
	}

	/* Same restatement as at 1280, bottom of the gutter ladder. */
	.ir-header + .committee-members {
		padding-inline: var(--sp-24);
	}

	.committee-members__inner {
		padding-inline: 0;
		gap: var(--sp-32);
	}

	.committee-members__grid {
		gap: var(--sp-16);
	}

	.committee-members__item {
		flex: 1 1 100%;
		max-width: none;
	}

	.committee-members__charter {
		width: 100%;
	}
}

@media (prefers-reduced-motion: reduce) {
	.committee-member,
	.committee-member__cta,
	.committee-member__cta-icon,
	.committee-members__charter-btn,
	.committee-members__charter-btn-icon {
		transition: none;
	}

	.committee-member:hover {
		transform: none;
	}

	.committee-member:hover .committee-member__cta-icon,
	.committee-members__charter-btn:hover .committee-members__charter-btn-icon,
	.committee-members__charter-btn:focus-visible .committee-members__charter-btn-icon {
		transform: none;
	}
}

/* ------------------------------------------------------------------ *
 * Member card — SHARED by the Board of Directors and Management grids
 * Figma frames 11251:4095 (board) and 11251:4558 (management), whose
 * cards are pixel-identical: a faint maroon-tint panel with a thin grey
 * border and 12px radius, a photo with a rounded top, then the name,
 * role and a maroon "Read More" link with a right arrow.
 *
 * Each page keeps its OWN section + grid wrapper (below), so page-level
 * spacing can diverge without touching the card. Deliberately does NOT
 * cover .committee-member (the CSR & ESG Committee page), which stays
 * fully isolated so that page is never affected by changes here.
 * ------------------------------------------------------------------ */
.member-card {
	display: flex;
	flex-direction: column;
	width: 100%;
	background: var(--c-primary-05);
	border: 1px solid var(--c-gray-200);
	border-radius: var(--radius-lg);
	overflow: hidden;
	transition: transform 0.25s ease, box-shadow 0.25s ease, border-color 0.25s ease;
}

.member-card:hover {
	transform: translateY(-4px);
	box-shadow: 0 16px 33px -2px rgba(28, 39, 49, 0.08);
	border-color: var(--c-primary-20);
}

.member-card__photo {
	aspect-ratio: 396 / 327;
	/* Warm cream placeholder shown until a real member photo is uploaded. */
	background-color: #e6ccb8;
	overflow: hidden;
}

.member-card__img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.member-card__body {
	display: flex;
	flex-direction: column;
	gap: var(--sp-8);
	padding: 20px var(--sp-24) var(--sp-24);
	/* Grow to fill the equal-height card so the CTA can sit at the bottom. */
	flex: 1 1 auto;
}

.member-card__name {
	margin: 0;
	font-family: var(--ff-body);
	font-weight: var(--fw-bold);
	font-size: var(--fs-xl);
	line-height: var(--lh-base);
	color: var(--c-text);
}

.member-card__role {
	margin: 0;
	font-family: var(--ff-body);
	font-weight: var(--fw-medium);
	font-size: var(--fs-l2);
	line-height: var(--lh-base);
	color: var(--c-text-muted);
}

.member-card__cta {
	/* Pin to the card bottom so Read More aligns across a row regardless of
	   how many lines the name/role wrap to. The body's gap keeps a min gap. */
	margin-top: auto;
	align-self: flex-start;
	display: inline-flex;
	align-items: center;
	gap: var(--sp-8);
	font-family: var(--ff-body);
	font-weight: var(--fw-bold);
	font-size: var(--fs-m);
	color: var(--c-primary);
	text-decoration: none;
	transition: color 0.2s ease;
}

.member-card__cta:hover,
.member-card__cta:focus-visible {
	color: var(--c-primary-600);
}

.member-card__cta-icon {
	display: inline-flex;
	width: 20px;
	height: 20px;
	flex: none;
	transition: transform 0.25s ease;
}

.member-card__cta-icon svg {
	width: 100%;
	height: 100%;
}

.member-card:hover .member-card__cta-icon {
	transform: translateX(3px);
}

/* ------------------------------------------------------------------ *
 * About Us — Board of Directors member grid (wrapper only)
 * Figma frame 11251:4095. Cards come from .member-card above; this block
 * owns the section padding, the 4-up grid and the footer note link.
 * ------------------------------------------------------------------ */
/* Gutter 120 / 80 / 24, matching .page-heading, so the first card's left edge
   lines up with the H1 above it. The gutter lives on the section (not on
   __inner) so that __inner's 1680px cap is the CONTENT width the Figma frame
   specifies — 4x396 cards + 3x32 gaps — rather than a border box the padding
   would eat 80px out of. */
.board-members {
	padding-block: 100px 120px;
	padding-inline: 120px;
	background: var(--c-white);
}

.board-members__inner {
	max-width: 1680px;
	margin-inline: auto;
	display: flex;
	flex-direction: column;
	gap: var(--sp-48);
}

/* Uniform columns. A flex-wrap grid grows a short final row's items to fill the
   line, so eight cards at 3-up rendered 352 / 352 / 396 — the last row visibly
   wider than the two above it. Grid tracks are sized once for the whole grid, so
   every card matches whether its row is full or not. The 320px floor reproduces
   the column counts the old flex-basis produced, and at the Figma content width
   (1680) auto-fit resolves to exactly 4 tracks of 396 + 3 gaps of 32. */
.board-members__grid {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
	gap: var(--sp-32);
	margin: 0;
	padding: 0;
	list-style: none;
}

.board-members__item {
	/* Flex so .member-card stretches to the tallest card in its row. */
	display: flex;
	max-width: 396px;
}

.board-members__note {
	align-self: flex-start;
	display: inline-flex;
	align-items: center;
	gap: var(--sp-8);
	font-family: var(--ff-body);
	font-weight: var(--fw-bold);
	font-size: var(--fs-m);
	color: var(--c-primary);
	text-decoration: none;
	transition: color 0.2s ease;
}

.board-members__note:hover,
.board-members__note:focus-visible {
	color: var(--c-primary-600);
}

.board-members__note-icon {
	display: inline-flex;
	width: 20px;
	height: 20px;
	flex: none;
	transition: transform 0.25s ease;
}

.board-members__note-icon svg {
	width: 100%;
	height: 100%;
}

.board-members__note:hover .board-members__note-icon,
.board-members__note:focus-visible .board-members__note-icon {
	transform: translateX(3px);
}

@media (max-width: 1280px) {
	.board-members {
		padding-block: 80px 100px;
		padding-inline: 80px;
	}
}

@media (max-width: 767px) {
	.board-members {
		padding-block: 64px;
		padding-inline: var(--sp-24);
	}

	.board-members__inner {
		gap: var(--sp-32);
	}

	.board-members__grid {
		grid-template-columns: 1fr;
		gap: var(--sp-16);
	}

	.board-members__item {
		max-width: none;
	}
}

/* ------------------------------------------------------------------ *
 * About Us — Management member grid (wrapper only)
 * Figma frame 11251:4558. Same .member-card as the board grid, in a 4-up
 * row; no footer note link in this design. Kept as its own wrapper so the
 * two pages' spacing can diverge independently.
 * ------------------------------------------------------------------ */
.management-members {
	padding-block: 100px 120px;
	padding-inline: 120px;
	background: var(--c-white);
}

.management-members__inner {
	max-width: 1680px;
	margin-inline: auto;
}

/* Both member grids sit directly under a `page_heading`, whose bottom pad would
   otherwise stack with the grid's top pad into a doubled gap. Drop the grid's
   top pad on desktop so a single --section-pad separates the title from the
   cards — the same adjacent-sibling pairing used by .page-heading + .lead-media
   and .page-heading + .value-cards. Released below the tablet stack, where the
   full rhythm returns. */
@media (min-width: 901px) {
	.page-heading + .board-members,
	.page-heading + .management-members {
		padding-block-start: 0;
	}
}

/* Uniform columns, same reasoning as .board-members__grid above. */
.management-members__grid {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
	gap: var(--sp-32);
	margin: 0;
	padding: 0;
	list-style: none;
}

.management-members__item {
	/* Flex so .member-card stretches to the tallest card in its row. */
	display: flex;
	max-width: 396px;
}

@media (max-width: 1280px) {
	.management-members {
		padding-block: 80px 100px;
		padding-inline: 80px;
	}
}

@media (max-width: 767px) {
	.management-members {
		padding-block: 64px;
		padding-inline: var(--sp-24);
	}

	.management-members__grid {
		grid-template-columns: 1fr;
		gap: var(--sp-16);
	}

	.management-members__item {
		max-width: none;
	}
}

@media (prefers-reduced-motion: reduce) {
	.member-card,
	.member-card__cta,
	.member-card__cta-icon,
	.board-members__note,
	.board-members__note-icon {
		transition: none;
	}

	.member-card:hover {
		transform: none;
	}

	.member-card:hover .member-card__cta-icon,
	.board-members__note:hover .board-members__note-icon,
	.board-members__note:focus-visible .board-members__note-icon {
		transform: none;
	}
}

@media (prefers-reduced-motion: reduce) {
	.link-cards__cta {
		transition: none;
	}
	.link-cards__cta:hover,
	.link-cards__cta:focus-visible {
		gap: var(--sp-8); /* no nudge when reduced motion is requested */
	}
}

@media (max-width: 1280px) {
	.link-cards {
		padding-inline: 80px;
	}
	.link-cards__inner {
		gap: var(--sp-80);
	}
}

@media (max-width: 900px) {
	.link-cards__grid {
		grid-template-columns: 1fr; /* stack cards once three abreast get cramped */
	}
	.link-cards__item {
		justify-content: flex-start;
	}
}

@media (max-width: 767px) {
	.link-cards {
		padding-inline: var(--sp-24);
	}
	.link-cards__inner {
		gap: var(--sp-48);
	}
	.link-cards__item {
		padding: var(--sp-16);
	}
	/* No title override here any more: the base is now --fs-xl (24), which is what
	   this breakpoint used to step down to, and Legal's 32 is gated to >=768. */
}

/* ==========================================================================
   Legal prose — Privacy Policy, Terms & Conditions (template-parts/sections/
   legal-content.php). Figma: Privacy Policy 11302:2658.

   Only two type styles run the whole page. Heading/H5/Semibold (Messina Sans
   600, 32/1.4, -1px, #24272c) sets the section headings; Heading/H6/Regular
   (Messina Sans 400, 24/1.4, #575d6a) sets the body copy AND the sub-headings,
   which the design deliberately leaves indistinguishable from body text. They
   still render as <h3> so the document keeps an outline for screen readers.

   Geometry measured off the same node: the H1 sits at the page's 120px gutter,
   while the prose column is 1320px centred in the 1920 frame — left edge 300,
   i.e. indented 180 from the H1. `margin-inline: auto` reproduces that and
   degrades on its own: below ~1560px there is no spare room left, so the column
   goes flush with the H1 exactly as it used to.

   Element selectors, not classes: the content is one WYSIWYG field, so the
   markup is whatever the editor produces and there are few hooks to hang a
   class on. Scoped under __inner so it cannot leak into the rest of the page —
   and the whole block is reachable by two pages only (Privacy Policy, Terms &
   Conditions); the Legal landing page has no legal_content row.
   ========================================================================== */
.legal-content {
	padding-block: var(--section-pad);
	padding-inline: 120px;
	background: var(--c-white);
}

.legal-content__inner {
	/* 1320 centred — see the geometry note above. */
	max-width: 1320px;
	margin-inline: auto;
	font-family: var(--ff-body);
	font-weight: var(--fw-regular);
	font-size: var(--fs-xl); /* 24 — Figma Heading/H6/Regular */
	line-height: var(--lh-base); /* 1.4 */
	color: var(--c-text-muted);
	/* Legal copy carries bare URLs and long defined terms; without this they
	   escape the measure on a phone instead of wrapping. */
	overflow-wrap: break-word;
}

.legal-content__inner > :first-child {
	margin-block-start: 0; /* no stray gap between the H1 above and the first block */
}

.legal-content__inner > :last-child {
	margin-block-end: 0; /* let the section's own padding set the closing gap */
}

/* Section heading, compact variant — Figma Heading/H5/Semibold (Privacy Policy,
   11302:3064). Sans, NOT the theme's serif heading face: that page keeps Messina
   Sans through the whole prose column and only the H1 above it is serif. 32 top /
   16 bottom are the measured frame gaps (section frames sit 32 apart; heading to
   first paragraph is 16) and hold for both variants.

   Tracking is -1% (= -0.01em), because Figma reports this style's letterSpacing
   as "-1" and that is a PERCENTAGE, resolving to -0.32px at 32px. This rule used
   to opt out of --ls-h3 and state the em value itself, because that token was a
   literal -1px and so ~3x too tight. As of 8 Aug 2026 --ls-h3 IS -0.01em — the
   token was corrected rather than worked around — so the opt-out is gone and
   this rule simply uses it. */
.legal-content__inner h2 {
	margin-block: var(--sp-32) var(--sp-16);
	font-family: var(--ff-body);
	font-weight: var(--fw-semibold);
	font-size: var(--fs-2xl); /* fluid 24 → 32 */
	line-height: var(--lh-base);
	letter-spacing: var(--ls-h3); /* Figma -1% */
	color: var(--c-text);
}

/* Section heading, display variant — Figma Heading/H4/Bold (Terms & Conditions,
   11302:3181). The two policy pages deliberately do NOT share a heading style:
   Privacy Policy plays its clause labels down in sans, while Terms numbers its
   clauses and sets them large, serif and maroon. Confirmed off the node geometry
   as well as the token — every Terms heading box is 56px tall (40 x 1.4), against
   45 (32 x 1.4) on Privacy.

   letterSpacing is a true 0 on this token, so the compact rule's -0.01em is
   explicitly cancelled rather than inherited. Size rides --fs-3xl, which already
   is fluid 32 -> 40 across the range. Opt-in per row via the layout's
   `heading_style` select, so the default stays compact for Privacy Policy and for
   any legal page added later. */
.legal-content--display .legal-content__inner h2 {
	font-family: var(--ff-heading);
	font-weight: var(--fw-bold);
	font-size: var(--fs-3xl); /* fluid 32 → 40 */
	letter-spacing: 0;
	color: var(--c-primary);
}

/* Sub-heading — Figma Heading/H6/Regular, i.e. identical to body copy. It is a
   heading element for the outline, not for a visual step; the design draws no
   distinction and neither should this. */
.legal-content__inner h3 {
	margin-block: var(--sp-16);
	font-family: var(--ff-body);
	font-weight: var(--fw-regular);
	font-size: var(--fs-xl); /* 24 */
	line-height: var(--lh-base);
	color: var(--c-text-muted);
}

.legal-content__inner p {
	margin-block: 0 var(--sp-16);
}

.legal-content__inner ul,
.legal-content__inner ol {
	margin-block: 0 var(--sp-16);
	padding-inline-start: var(--sp-24);
}

.legal-content__inner li {
	margin-block-end: var(--sp-8);
}

.legal-content__inner li:last-child {
	margin-block-end: 0;
}

/* The live copy leans on bold run-in labels ("Consent:", "Cookie policy:") to
   open a clause, so these need to read as darker than the body around them. */
.legal-content__inner strong,
.legal-content__inner b {
	font-weight: var(--fw-semibold);
	color: var(--c-text);
}

/* Underlined, unlike every other link in the theme. The no-underline rule covers
   section CTAs, which are unmistakably links from position and arrow alone; a
   link buried mid-sentence has neither, so removing the underline would leave
   colour as its only signal and fail WCAG 1.4.1. */
.legal-content__inner a {
	color: var(--c-primary);
	text-decoration: underline;
	text-underline-offset: 2px;
}

.legal-content__inner a:hover,
.legal-content__inner a:focus-visible {
	text-decoration-thickness: 2px;
}

/* Opening paragraph — Figma 11302:2696. A maroon serif run-in (FK Roman Bold,
   32px) leading grey Messina Sans at the same 32px, on a measured 58px pitch.

   It lives in the WYSIWYG body rather than in the page_heading `lead` field
   because that is where Figma puts it: indented into the prose column with the
   body, while the heading's own lead node (11302:2695) is switched off. Keeping
   it here also leaves .page-heading__lead — shared with 21 other pages —
   completely untouched. One of the two classes in this block; the editor has no
   other way to mark this paragraph as the lead. */
.legal-content__inner .legal-intro {
	margin-block: 0 var(--sp-80);
	font-size: var(--fs-2xl); /* 32 */
	line-height: 1.8; /* 58px pitch at 32px, measured off the node */
}

.legal-content__inner .legal-intro strong {
	font-family: var(--ff-heading);
	font-weight: var(--fw-bold);
	font-size: inherit;
	color: var(--c-primary);
}

/* Same page-heading pairing as the Legal landing page and the member grids — the
   heading's bottom pad would otherwise stack with this section's top pad. */
@media (min-width: 901px) {
	.page-heading + .legal-content {
		padding-block-start: 0;
	}
}

@media (max-width: 1280px) {
	.legal-content {
		padding-inline: 80px;
	}
}

@media (max-width: 767px) {
	.legal-content {
		padding-inline: var(--sp-24);
	}
	.legal-content__inner {
		font-size: var(--fs-l2); /* 18 */
	}
	/* Both h2 variants ride tokens that already collapse at this breakpoint —
	   --fs-2xl to 24 and --fs-3xl to 32 (tokens.css:126-127) — so neither needs a
	   size override here. --fs-xl does NOT collapse, so h3 and the intro both need
	   their own step — and h3 stays equal to body copy, as in Figma. */
	.legal-content__inner h3 {
		font-size: var(--fs-l2); /* 18 */
	}
	.legal-content__inner .legal-intro {
		margin-block-end: var(--sp-48);
		font-size: var(--fs-xl); /* 24 */
		line-height: 1.6;
	}
}

/* --------------------------------------------------------------------------
   Interior page rhythm.
   Section spacing is intentionally NOT done with adjacency selectors any more.
   Every section owns an equal top+bottom pad (`--section-pad`), so the gap
   between any two adjacent sections is always 2×that value — uniform on every
   page and unaffected by adding, removing, or reordering sections. To retune
   the interior rhythm, change `--section-pad` in tokens.css (one place). Do NOT
   reintroduce `.a + .b { padding }` joins here: they are global, so they leak
   the gap across every page that shares this template, and they break the
   moment a section is removed or reordered.

   ONE sanctioned exception, and it is narrow: `.page-heading + X` relaxing X's
   top pad above 901px. A page_heading is a bare title with nothing to carry its
   own weight, so the doubled pad below it reads as a hole rather than as rhythm.
   It is safe precisely because it is anchored to page-heading, which is always a
   page's FIRST section — so there is no ordering it can be broken by, and it
   degrades to the normal rhythm when the pairing does not occur. Do not
   generalise it past page-heading.

   Client cap of 10 Aug 2026: a title followed by body copy must not exceed 80px
   between them. Cancelling to 0 leaves the heading's own bottom pad as the whole
   gap — 64px at 1424px and up, 48px at 901 — so the cap holds with room over.

   Two forms, and they are not interchangeable:

     CANCEL TO 0, wrapped in `@media (min-width: 901px)` — nine pairings, and the
     default for anything new. intro-text, committee-members, news-latest,
     lead-media, value-cards, board-members, management-members, link-cards,
     legal-content. Where the section sets padding with the `padding:` shorthand
     (committee-members, news-latest) the longhand must come after it in source
     order or it does nothing.

     TOP UP TO A FIXED JOIN at top level — text-media and photo-grid only, both
     `calc(100px - var(--section-pad))`, each with its own ≤767 variant. These
     exist because those two also join to THEMSELVES down a page and the join has
     to be one specific number rather than merely smaller; see the note beside
     .text-media. Do not copy this form for a plain title-then-content page.

   Two things that look like omissions and are not: brand-detail already sets its
   own top pad to 0, so the three brand pages need no rule; and text-share is NOT
   anchored to page-heading despite an earlier version of this list saying so — it
   trims itself via `.text-share:has(.text-share__card)`, which is a different
   mechanism with a different trigger.

   Below 901px every cancel above releases and the full rhythm returns, which puts
   the tablet gap at 96px — over the client cap. That is inherited from how this
   exception has always worked, not an oversight of it: holding the cap at every
   width means dropping the media query on all nine pairings at once, which is a
   decision about tablet rhythm generally rather than about page headings. */

/* ==========================================================================
   Feature split — reusable image + text band (Sustainability 11281:2990 etc.)
   Image card one side, text column the other; side alternates via a modifier.
   Gutter 120/80/24 aligns with breadcrumb + hero + intro. Image + text share
   the row on flexible columns (image capped so it can't dominate huge screens),
   collapsing to a stacked column (image on top) on tablets down.
   ========================================================================== */
.feature-split {
	padding-block: var(--section-pad);
	padding-inline: 120px;
}

.feature-split--muted {
	background-color: var(--c-gray-05);
}

.feature-split__inner {
	display: flex;
	align-items: center;
	gap: 60px;
	max-width: 1680px;
	margin-inline: auto;
}

/* Image on the right: DOM stays media-first, visual order flips. */
.feature-split--image-right .feature-split__inner {
	flex-direction: row-reverse;
}

.feature-split__media {
	flex: 1 1 0;
	max-width: 800px;
	aspect-ratio: 800 / 560;
	overflow: hidden;
	border: 1px solid var(--c-gray-200);
	border-radius: var(--radius-lg);
	background-color: var(--c-gray-05);
}

.feature-split__img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.feature-split__content {
	flex: 1 1 0;
	display: flex;
	flex-direction: column;
	justify-content: center;
	align-items: flex-start;
	gap: var(--sp-48);
}

.feature-split__text {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: var(--sp-16);
}

.feature-split__eyebrow {
	display: inline-flex;
	align-items: center;
	padding: var(--sp-8) var(--sp-12);
	border-radius: 80px;
	background-color: var(--c-primary-10);
	color: var(--c-primary);
	font-family: var(--ff-body);
	font-weight: var(--fw-medium);
	font-size: var(--fs-m);
	line-height: var(--lh-base);
}

.feature-split__heading {
	margin: 0;
	font-family: var(--ff-heading);
	font-weight: var(--fw-bold);
	font-size: var(--fs-4xl);      /* fluid 32 → 48 */
	line-height: var(--lh-base);   /* 1.4 */
	color: var(--c-dark);
}

.feature-split__accent {
	color: var(--c-primary);
}

.feature-split__body {
	margin: 0;
	font-family: var(--ff-body);
	font-weight: var(--fw-regular);
	font-size: var(--fs-l2);       /* 18 */
	line-height: var(--lh-base);
	color: var(--c-text-muted);
	max-width: 60ch;
}

.feature-split__cta {
	display: inline-flex;
	align-items: center;
	gap: var(--sp-8);
	padding: var(--sp-8) var(--sp-12);
	border-radius: var(--radius-lg);
	background-color: var(--c-primary);
	color: var(--c-white);
	font-family: var(--ff-body);
	font-weight: var(--fw-bold);
	font-size: var(--fs-m);
	line-height: var(--lh-base);
	text-decoration: none;
	transition: background-color 0.25s ease, transform 0.25s ease, box-shadow 0.25s ease;
}

.feature-split__cta:hover,
.feature-split__cta:focus-visible {
	background-color: var(--c-primary-600);
	transform: translateY(-2px);
	box-shadow: 0 10px 22px -8px var(--c-primary-20);
	text-decoration: none;
}

.feature-split__cta:active {
	transform: translateY(0) scale(0.98);
}

.feature-split__cta-icon svg {
	display: block;
	width: 20px;
	height: 20px;
}

.feature-split__cta-icon {
	display: inline-flex;
	transition: transform 0.25s ease;
}

.feature-split__cta:hover .feature-split__cta-icon,
.feature-split__cta:focus-visible .feature-split__cta-icon {
	transform: translateX(3px);
}

@media (max-width: 1280px) {
	.feature-split {
		padding-inline: 80px;
	}
	.feature-split__inner {
		gap: var(--sp-48);
	}
}

/* Tablet down: stack (image on top for both sides). */
@media (max-width: 900px) {
	.feature-split__inner,
	.feature-split--image-right .feature-split__inner {
		flex-direction: column;
		align-items: stretch;
		gap: var(--sp-32);
	}
	.feature-split__media {
		flex: none;            /* stacked column: size by width + aspect-ratio, don't collapse to flex-basis 0 */
		max-width: none;
		width: 100%;
	}
	.feature-split__content {
		flex: none;
		align-items: flex-start;
	}
}

@media (max-width: 767px) {
	.feature-split {
		padding-inline: var(--sp-24);
	}
	.feature-split__content {
		gap: var(--sp-24);
	}
	.feature-split__text {
		gap: var(--sp-12);
	}
}

/* ==========================================================================
   Lead + media — About Us → Vision, Figma 11251:3343.
   One large statement paragraph beside a fixed 671×500 decorative graphic: a
   maroon FK Roman lead (40px) opens 32px grey body with an optional SemiBold
   dark inline emphasis. Left gutter matches the interior rhythm (120/80/24);
   the lead/body sizes ride the --fs-3xl / --fs-2xl token stepdowns at tablet +
   phone. Below 900px it stacks with the image under the statement.
   ========================================================================== */
.lead-media {
	padding-block: var(--section-pad);
	padding-inline: 120px;
}

/* Vision page: the "Vision" page-heading sits directly on top of this statement
   band, so the heading's bottom pad and this band's top pad stack into a doubled
   gap. Drop the band's top pad on desktop so a single --section-pad separates the
   title from the statement (the side-by-side layout stacks at 900px, below which
   the full rhythm returns). Scoped to the adjacent-sibling pattern, so only a
   lead-media that immediately follows a page-heading is affected. */
@media (min-width: 901px) {
	.page-heading + .lead-media {
		padding-block-start: 0;
	}
}

.lead-media__inner {
	display: flex;
	align-items: center;
	gap: var(--sp-80);
	max-width: 1680px;
	margin-inline: auto;
}

/* Image on the left: DOM stays text-first, visual order flips. */
.lead-media--image-left .lead-media__inner {
	flex-direction: row-reverse;
}

.lead-media__text {
	flex: 1 1 55%;
	min-width: 0;
}

/* Proportional column: the image shrinks with the viewport (so the statement
   keeps a readable measure at every width) but never grows past its native
   671px. At the max 1680px inner width the cap frees space that flows to the
   text — reproducing the Figma 929 / 671 split without a magic number. */
.lead-media__media {
	flex: 0 1 45%;
	max-width: 671px;
	aspect-ratio: 671 / 500;
	overflow: hidden;
}

.lead-media__img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.lead-media__para {
	margin: 0;
	font-family: var(--ff-body);
	font-weight: var(--fw-regular);
	font-size: var(--fs-2xl);      /* 32 */
	line-height: 1.8;
	color: var(--c-text-muted);
	word-break: break-word;
}

.lead-media__lead {
	font-family: var(--ff-heading);
	font-weight: var(--fw-bold);
	font-size: var(--fs-3xl);      /* 40 */
	line-height: 1.4;
	color: var(--c-primary);
}

.lead-media__em {
	font-weight: var(--fw-semibold);
	color: var(--c-text);
}

@media (max-width: 1280px) {
	.lead-media {
		padding-inline: 80px;
	}
	.lead-media__inner {
		gap: var(--sp-48);
	}
}

/* Tablet down: stack, image centred below the statement (never upscaled past
   its native 671px). */
@media (max-width: 900px) {
	.lead-media__inner,
	.lead-media--image-left .lead-media__inner {
		flex-direction: column;
		align-items: stretch;
		gap: var(--sp-32);
	}
	.lead-media__text,
	.lead-media__media {
		flex: 0 0 auto;
	}
	.lead-media__media {
		width: 100%;
		max-width: 671px;
		margin-inline: auto;
	}
}

@media (max-width: 767px) {
	.lead-media {
		padding-inline: var(--sp-24);
	}
}

/* ==========================================================================
   Value cards — About Us → Values, row of 3 (Figma 11363:7706).
   Each card is one bordered unit (1px #dee1e7, 12px radius): a 539×380 cover
   image on top over a 32px-padded body. Image and body meet on a single
   hairline (the media's bottom border), reproducing the two bordered Figma
   pieces as one card. Title is ALL-CAPS maroon FK Roman (40px / --fs-3xl); the
   description is grey Messina (20px / --fs-l, line-height 1.6). Equal flexible
   columns (Figma 538.67px is a ceiling, not a fixed width). Gutter 120px matches
   the page. No links here — these are static value statements, not navigation.
   ========================================================================== */
.value-cards {
	padding-block: var(--section-pad);
	padding-inline: 120px;
}

/* The "Values" page-heading sits directly above this grid, so its bottom pad
   and this grid's top pad would stack into a doubled gap. Drop the grid's top
   pad on desktop so a single --section-pad separates the title from the cards
   (mirrors the page-heading + lead-media pairing on the Vision page). Released
   below the tablet stack, where the full rhythm returns. */
@media (min-width: 901px) {
	.page-heading + .value-cards {
		padding-block-start: 0;
	}
}

.value-cards__grid {
	display: flex;
	gap: var(--sp-32);
	max-width: 1680px;   /* 3×538.67 + 2×32 gap */
	margin-inline: auto;
}

.value-cards__item {
	display: flex;
	flex: 1 1 0;
	flex-direction: column;
	min-width: 0;
	background: var(--c-white);
	border: 1px solid var(--c-gray-200);
	border-radius: var(--radius-lg);
	overflow: hidden;   /* clip the cover image to the rounded top corners */
}

.value-cards__media {
	aspect-ratio: 539 / 380;
	border-bottom: 1px solid var(--c-gray-200);
	overflow: hidden;
}

.value-cards__img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.value-cards__body {
	display: flex;
	flex-direction: column;
	gap: var(--sp-12);
	padding: var(--sp-32);
}

.value-cards__title {
	margin: 0;
	font-family: var(--ff-heading);
	font-weight: var(--fw-bold);
	font-size: var(--fs-3xl);   /* 40 */
	line-height: 1.4;
	text-transform: uppercase;
	color: var(--c-primary);
}

.value-cards__desc {
	margin: 0;
	font-family: var(--ff-body);
	font-weight: var(--fw-regular);
	font-size: var(--fs-l);     /* 20 */
	line-height: 1.6;
	color: var(--c-text-muted);
}

/* ---- Value cards — responsive ------------------------------------------ */
/* Tablet (≤1280): tighten the section gutter; the three cards keep one row. */
@media (max-width: 1280px) {
	.value-cards {
		padding-inline: var(--sp-64);   /* 64 */
	}
	.value-cards__body {
		padding: var(--sp-24);
	}
}

/* Small tablet (≤900): three columns get too narrow for the copy — stack into
   a single centred column, capped so cards never stretch full-bleed wide. */
@media (max-width: 900px) {
	.value-cards {
		padding-inline: var(--sp-48);   /* 48 */
	}
	.value-cards__grid {
		flex-direction: column;
		align-items: center;
		gap: var(--sp-32);
	}
	.value-cards__item {
		flex: 0 0 auto;
		width: 100%;
		max-width: 480px;
	}
}

/* Phone (≤767): page side gutter; title steps to 32px via the --fs-3xl token. */
@media (max-width: 767px) {
	.value-cards {
		padding-inline: var(--container-pad);   /* 16 */
	}
}

/* ==========================================================================
   Nurture cards — row of 3 icon cards (Sustainability Strategy 11290:2798).
   Faint maroon-tint band; each card is a white rounded link panel with a big
   grey badge circle holding a 128px maroon line icon, a serif uppercase title,
   a grey subtitle, and a "Read more" row pinned to the card foot so the CTAs
   line up across cards of unequal text length. Gutter 120px matches the rest
   of the page. Cards share the row on equal flexible columns (Figma 538px is a
   ceiling, not a fixed width). No underline — hover lifts + nudges the arrow.
   ========================================================================== */
.nurture-cards {
	padding-block: var(--section-pad);
	padding-inline: 120px;
	background-color: var(--c-primary-05);
}

.nurture-cards__inner {
	max-width: 1680px;   /* 3×538 + 2×32 gap */
	margin-inline: auto;
}

.nurture-cards__row {
	display: flex;
	gap: var(--sp-32);
	align-items: stretch;   /* equal-height cards */
	justify-content: center;
	margin: 0;
	padding: 0;
	list-style: none;
}

.nurture-cards__item {
	display: flex;              /* let the card stretch to full column height */
	flex: 1 1 0;
	max-width: 538px;
}

.nurture-card {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: var(--sp-32);
	width: 100%;
	padding: var(--sp-24);
	background-color: var(--c-white);
	border: 1px solid var(--c-gray-200);
	border-radius: var(--radius-lg);
	text-align: center;
	text-decoration: none;
	color: inherit;
	transition: transform 0.25s ease, box-shadow 0.25s ease, border-color 0.25s ease;
}

.nurture-card:hover,
.nurture-card:focus-visible {
	transform: translateY(-4px);
	box-shadow: 0 16px 32px -14px var(--c-primary-20);
	border-color: var(--c-primary-20);
	text-decoration: none;
}

.nurture-card:active {
	transform: translateY(-1px);
}

.nurture-card__badge {
	display: flex;
	align-items: center;
	justify-content: center;
	flex-shrink: 0;
	width: 250px;
	height: 250px;
	border-radius: 999px;
	background-color: var(--c-gray-10);
}

.nurture-card__icon svg {
	display: block;
	width: 128px;
	height: 128px;
	color: var(--c-primary);
}

.nurture-card__text {
	display: flex;
	flex-direction: column;
	gap: var(--sp-8);
}

.nurture-card__title {
	font-family: var(--ff-heading);
	font-weight: var(--fw-bold);
	font-size: var(--fs-2xl);   /* 32 */
	line-height: var(--lh-tight);
	color: var(--c-primary);
	text-transform: uppercase;
}

.nurture-card__subtitle {
	font-family: var(--ff-body);
	font-weight: var(--fw-regular);
	font-size: var(--fs-l2);    /* 18 */
	line-height: var(--lh-base);
	color: var(--c-text-body);
}

.nurture-card__cta {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: var(--sp-8);
	width: 100%;
	margin-top: auto;           /* pin CTA to the card foot for cross-card alignment */
	padding-left: var(--sp-16);
	font-family: var(--ff-body);
	font-weight: var(--fw-bold);
	font-size: var(--fs-m);     /* 16 */
	line-height: var(--lh-base);
	color: var(--c-primary);
}

.nurture-card__cta-label {
	white-space: nowrap;
}

.nurture-card__cta-icon {
	display: inline-flex;
	transition: transform 0.25s ease;
}

.nurture-card__cta-icon svg {
	display: block;
	width: 20px;
	height: 20px;
}

.nurture-card:hover .nurture-card__cta-icon,
.nurture-card:focus-visible .nurture-card__cta-icon {
	transform: translateX(3px);
}

/* ---- Nurture cards — responsive ---------------------------------------- */
/* Tablet (≤1280): tighten the section gutter and shrink the badge/icon so the
   three cards keep sharing one row without crowding. */
@media (max-width: 1280px) {
	.nurture-cards {
		padding-inline: var(--sp-64);   /* 64 */
	}
	.nurture-card {
		gap: var(--sp-24);
	}
	.nurture-card__badge {
		width: 200px;
		height: 200px;
	}
	.nurture-card__icon svg {
		width: 104px;
		height: 104px;
	}
}

/* Small tablet (≤900): three columns get too narrow for the badge — stack into
   a single centred column and cap the card width so it never stretches wide. */
@media (max-width: 900px) {
	.nurture-cards {
		padding-inline: var(--sp-48);   /* 48 */
	}
	.nurture-cards__row {
		flex-direction: column;
		align-items: center;
		gap: var(--sp-24);
	}
	.nurture-cards__item {
		flex: 0 0 auto;
		width: 100%;
		max-width: 480px;
	}
}

/* Phone (≤767): page side gutter + a smaller badge. The title steps down to
   24px automatically via the --fs-2xl token override at this width. */
@media (max-width: 767px) {
	.nurture-cards {
		padding-inline: var(--container-pad);   /* 16 */
	}
	.nurture-card__badge {
		width: 176px;
		height: 176px;
	}
	.nurture-card__icon svg {
		width: 92px;
		height: 92px;
	}
}

/* ---- Four pillars (2026-08-31) ------------------------------------------
   The client's Plan Nurture graphic has four pillars, not Figma's three, so
   `nurture_cards` now emits a `--cols-N` modifier and everything below is
   scoped to `--cols-4`. Three cards keep the layout above unchanged.

   Four across is a GRID, not the flex row: equal columns that cannot be pushed
   out of line by a long title ("Nurturing Governance & Ethics" is three lines
   in a narrow column), and a wrap ladder of 4 → 2 → 1 so the pairs stay even.
   Every rule here outranks the flex rules above on specificity, so the order
   of the two blocks in this file does not matter.

   The badge has to come down: at 1440px the band's content box is 1200, and
   four columns with 24px gaps leave 282 per card — 250 of badge plus 48 of card
   padding does not fit. 180 does, and grows back to the full 250 once the grid
   drops to two columns and each card is half a row wide.
   ------------------------------------------------------------------------- */
.nurture-cards--cols-4 .nurture-cards__row {
	display: grid;
	grid-template-columns: repeat(4, minmax(0, 1fr));
	gap: var(--sp-24);
	align-items: stretch;
}

.nurture-cards--cols-4 .nurture-cards__item {
	max-width: none;   /* the grid track is the width now, not the 538px Figma cap */
}

.nurture-cards--cols-4 .nurture-card__badge {
	width: 180px;
	height: 180px;
}

.nurture-cards--cols-4 .nurture-card__icon svg {
	width: 96px;
	height: 96px;
}

.nurture-cards--cols-4 .nurture-card__title {
	font-size: var(--fs-xl);   /* 20 → 24: 32px breaks "GOVERNANCE & ETHICS" badly at this width */
}

/* A card with no destination is a plain panel, not a link — kill the affordances
   the shared .nurture-card rules would otherwise give it on hover. */
.nurture-card--static {
	cursor: default;
}

.nurture-card--static:hover,
.nurture-card--static:active {
	transform: none;
	box-shadow: none;
	border-color: var(--c-gray-200);
}

/* Laptop (≤1440): pull the 120px band gutter in early. Four columns at 1281px
   with the full gutter leave 194px inside a card for a 180px badge — true, but
   with nothing to spare; 64px of gutter turns that into 222px. Below 1281 the
   shared rule already does this, so this only covers the 1281–1440 band. */
@media (max-width: 1440px) {
	.nurture-cards--cols-4 {
		padding-inline: var(--sp-64);   /* 64 */
	}
}

/* Tablet (≤1280): two columns, and the badge can go back up because each card
   is now half the band wide. */
@media (max-width: 1280px) {
	.nurture-cards--cols-4 .nurture-cards__row {
		grid-template-columns: repeat(2, minmax(0, 1fr));
		gap: var(--sp-32);
	}
	.nurture-cards--cols-4 .nurture-card__badge {
		width: 220px;
		height: 220px;
	}
	.nurture-cards--cols-4 .nurture-card__icon svg {
		width: 112px;
		height: 112px;
	}
	.nurture-cards--cols-4 .nurture-card__title {
		font-size: var(--fs-2xl);   /* room again at half-width */
	}
}

/* Small tablet (≤900): the ≤900 rule above turns the flex row into a column;
   under grid that is inert, so restate the intent as a single track and undo
   the align-items:center it also sets (which would stop cards stretching). */
@media (max-width: 900px) {
	.nurture-cards--cols-4 .nurture-cards__row {
		grid-template-columns: minmax(0, 1fr);
		justify-items: center;
		align-items: stretch;
		gap: var(--sp-24);
	}
	.nurture-cards--cols-4 .nurture-cards__item {
		width: 100%;
		max-width: 480px;
	}
}

/* Phone (≤767): inherits the single column and the 176px badge from the shared
   rules; only the title needs holding down, since --fs-2xl is 24 here anyway. */
@media (max-width: 767px) {
	.nurture-cards--cols-4 .nurture-card__badge {
		width: 176px;
		height: 176px;
	}
	.nurture-cards--cols-4 .nurture-card__icon svg {
		width: 92px;
		height: 92px;
	}
}

/* ==========================================================================
   Focus cards — Figma Nurturing Planet node 11363:9035 ("Features")
   Full-bleed landscape photo with three equal dark-translucent cards over it.
   Each card: 200px white-10% badge circle holding a 128px white line icon, a
   centred FK Roman title (32px), and a left-aligned bullet list (24px body).
   ACF layout `focus_cards`; bundled mountains photo used when no upload.
   ========================================================================== */
.focus-cards {
	position: relative;
	display: flex;
	padding-block: var(--section-pad);
	padding-inline: 120px;
	overflow: hidden;
	background-color: var(--c-primary-900);   /* base behind the photo */
}

/* Photo layer — sits behind the cards. */
.focus-cards__media {
	position: absolute;
	inset: 0;
	background-size: cover;
	background-position: center;
	background-repeat: no-repeat;
	z-index: 0;
}

.focus-cards__media--default {
	background-image: url("../images/nurturing-features.jpg");
	background-image: image-set(
		url("../images/nurturing-features.webp") type("image/webp"),
		url("../images/nurturing-features.jpg") type("image/jpeg")
	);
}

.focus-cards__inner {
	position: relative;
	z-index: 1;
	width: 100%;
	max-width: 1680px;   /* 3×538 + 2×32 gap, matches nurture-cards */
	margin-inline: auto;
}

.focus-cards__row {
	display: flex;
	gap: var(--sp-32);
	align-items: stretch;   /* equal-height cards */
	justify-content: center;
	margin: 0;
	padding: 0;
	list-style: none;
}

.focus-card {
	display: flex;
	flex: 1 1 0;
	flex-direction: column;
	align-items: center;
	gap: var(--sp-32);
	max-width: 538px;
	padding: var(--sp-32);
	background-color: rgba(29, 30, 33, 0.6);
	border-radius: var(--radius-lg);
	text-align: center;
}

.focus-card__badge {
	display: flex;
	align-items: center;
	justify-content: center;
	flex-shrink: 0;
	width: 200px;
	height: 200px;
	border-radius: 999px;
	background-color: rgba(255, 255, 255, 0.1);
}

.focus-card__icon svg {
	display: block;
	width: 128px;
	height: 128px;
	color: var(--c-white);
}

.focus-card__title {
	font-family: var(--ff-heading);
	font-weight: var(--fw-bold);
	font-size: var(--fs-2xl);   /* 32 */
	line-height: var(--lh-base);
	color: var(--c-white);
}

.focus-card__list {
	display: flex;
	flex-direction: column;
	gap: 17px;
	width: 100%;
	margin: 0;
	padding: 0;
	list-style: none;
	text-align: left;
}

.focus-card__bullet {
	position: relative;
	padding-left: var(--sp-24);
	font-family: var(--ff-body);
	font-weight: var(--fw-medium);
	font-size: var(--fs-xl);    /* 24 */
	line-height: var(--lh-base);
	color: #f8f8f8;
}

.focus-card__bullet::before {
	content: "";
	position: absolute;
	left: 0;
	top: 0.6em;
	width: 8px;
	height: 8px;
	border-radius: 999px;
	background-color: var(--c-white);
}

/* Plain lines — the `style` field (CSR infographic, client 2026-10-14: "remove
   bullet points... the first line under each image keep centre aligned, like the
   original PPT"). The dot and its inset go; the first line becomes a centred
   subtitle (the rest were left-aligned until the last follow-up below).
   Follow-up the same day, also after the PPT: title above the icon (flex `order`,
   so the markup and the bulleted bands stay as they are), first line semibold,
   the rest regular. Then every line centred, as in the PPT. */
.focus-cards--plain .focus-card__title {
	order: -1;
}
.focus-cards--plain .focus-card__list {
	text-align: center;
}
.focus-cards--plain .focus-card__bullet {
	padding-left: 0;
	font-weight: var(--fw-regular);
}
.focus-cards--plain .focus-card__bullet::before {
	content: none;
}
.focus-cards--plain .focus-card__bullet:first-child {
	font-size: calc(var(--fs-xl) + 3px);   /* 3px over the rest at every width (client) */
	font-weight: var(--fw-semibold);
}

/* ---- Focus cards — heading and compact size -------------------------------- */
/* Nurturing Planet, client 2026-10-19: "reduce the size of boxes, and in the image
   on the top, we need to write AMBITIONS FOR 2030". The heading sits over the photo
   above the row; compact narrows the cards and shrinks the badge so more of the
   photo stays visible. Both opt in, so every other band is untouched. */
/* The client came back on 2026-10-21: white-on-photo was unreadable — this band's
   photograph is a sunlit mountain valley, so the top strip the heading sits in is
   near-white sky. A colour change alone would not fix it, because the background is
   an EDITABLE image (ACF `background`) and the next upload could be dark again, so
   no single text colour can be safe. The heading therefore carries its own surface
   (see the panel on background-color below) rather than relying on the photo.
   fit-content + auto margins keep that panel hugging the words instead of ruling
   the full width; text-align:center then handles the two-line case at phone width. */
.focus-cards__heading {
	position: relative;
	width: fit-content;
	margin: 0 auto var(--sp-48);
	font-family: var(--ff-heading);
	font-weight: var(--fw-bold);
	font-size: var(--fs-3xl);   /* 40 */
	line-height: var(--lh-base);
	letter-spacing: 0.06em;   /* positive, not the headings' negative tracking: this is
	                             set in caps, where the stock fit is too tight */
	color: var(--c-white);
	text-align: center;
	/* Client 2026-10-21, third pass: shadow alone was still not readable, because
	   the top strip of this photo is near-white sky and a shadow can only ever
	   darken the pixels it covers — it cannot raise contrast the way a surface can.
	   So the heading takes the SAME dark translucent panel the three cards below
	   already use (rgba(29,30,33,0.6), 12px radius). That is the band's existing
	   material rather than a new one, so the heading reads as part of the design
	   instead of a label pasted on. A tinted panel would also have worked, but
	   matching the cards keeps the band to one surface colour. The photo is an
	   editable ACF image, so this holds whatever is uploaded next; a shadow,
	   which can only darken what is already there, would not have.

	   0.78 rather than the cards' 0.6: the cards sit low over dark hillside,
	   this sits high over near-white sky, which is the worst case in the image.
	   Measured against pure white, 0.6 gives white text only 4.41:1 — under the
	   4.5 minimum — where 0.78 gives 8.13:1. Same colour, same material, carried
	   far enough up to hold over sky. */
	background-color: rgba(29, 30, 33, 0.78);
	border-radius: var(--radius-lg);
	padding: var(--sp-16) var(--sp-48) var(--sp-24);
	/* Kept from the shadow pass: softens the panel's edge against the photo and
	   keeps the glyphs crisp where the panel is at its most transparent. */
	text-shadow: 0 2px 8px rgba(23, 1, 7, 0.6);
}

/* Short rule under the words, carrying its own shadow for the same reason the
   type does. Centred on the block rather than the text so it stays put when the
   heading wraps at phone width. Never spoken: it is a ::after. */
.focus-cards__heading::after {
	content: "";
	position: absolute;
	left: 50%;
	bottom: var(--sp-16);
	width: 64px;
	height: 2px;
	transform: translateX(-50%);
	background-color: var(--c-white);
	box-shadow: 0 1px 6px rgba(23, 1, 7, 0.8);
}

.focus-cards--compact .focus-card {
	gap: var(--sp-24);
	max-width: 420px;
	padding: var(--sp-24);
}
.focus-cards--compact .focus-card__badge {
	width: 136px;
	height: 136px;
}
.focus-cards--compact .focus-card__icon svg {
	width: 88px;
	height: 88px;
}
.focus-cards--compact .focus-card__title {
	font-size: var(--fs-xl);    /* 24 */
}
.focus-cards--compact .focus-card__bullet {
	font-size: var(--fs-l);     /* 18 → 20 */
}

@media (max-width: 1200px) {
	.focus-cards__heading {
		font-size: var(--fs-2xl);   /* 32 */
	}
}

/* ---- Focus cards — five up ------------------------------------------------ */
/* Nurturing Governance & Ethics (2026-09-17) runs five pillars where Planet and
   People run three. Five do not fit the base rule: the badge is a fixed 200px with
   flex-shrink:0 inside a 32px-padded card, so a card cannot be narrower than 264px,
   and five of those plus four 32px gaps need ≈1448px of inner width against a
   container that is `overflow: hidden`. Past that point the row does not squash —
   it is clipped.

   So the five-up band is allowed to wrap. The basis does the deciding rather than a
   hand-picked breakpoint: five fit above roughly 1770px, three below it, two below
   roughly 1265px, and at ≤900 the stack rule already in this file takes over. Rows
   stay visually even because the cap and the basis are close together, so a row of
   two is the same card width as a row of three rather than two half-width slabs.

   Scoped to min-width 901 rather than written flat, and that is deliberate: a
   `.focus-cards--cols-5 .focus-card` selector outranks the bare `.focus-card` in the
   ≤900 block, so a flat rule would quietly win the cascade and leave these five
   cards at 320px while every other band's stacked to 480px.

   Only --cols-5 has a rule. Three- and four-card bands fall through to the base flex
   row exactly as before, which is what keeps Nurturing Planet and Nurturing People
   byte-identical. No badge step-down is needed: a card here never drops below its
   280px basis, because two of them fit the narrowest inner width this block covers. */
@media (min-width: 901px) {
	.focus-cards--cols-5 .focus-cards__row {
		flex-wrap: wrap;
	}
	.focus-cards--cols-5 .focus-card {
		flex: 1 1 280px;
		max-width: 320px;
	}
}

/* ---- Focus cards — responsive -------------------------------------------- */
/* Tablet (≤1280): tighten the gutter and shrink the badge/icon so the three
   cards keep sharing one row without crowding. */
@media (max-width: 1280px) {
	.focus-cards {
		padding-inline: var(--sp-64);   /* 64 */
	}
	.focus-card {
		gap: var(--sp-24);
		padding: var(--sp-24);
	}
	.focus-card__badge {
		width: 160px;
		height: 160px;
	}
	.focus-card__icon svg {
		width: 96px;
		height: 96px;
	}
}

/* Small tablet (≤900): three columns get too narrow — stack into one centred
   column and cap the card width. */
@media (max-width: 900px) {
	.focus-cards {
		padding-inline: var(--sp-48);   /* 48 */
	}
	.focus-cards__row {
		flex-direction: column;
		align-items: center;
		gap: var(--sp-24);
	}
	.focus-card {
		flex: 0 0 auto;
		width: 100%;
		max-width: 480px;
	}
}

/* Phone (≤767): page side gutter; title steps to 24 via the --fs-2xl override. */
@media (max-width: 767px) {
	.focus-cards {
		padding-inline: var(--container-pad);   /* 16 */
	}
	.focus-card__badge {
		width: 144px;
		height: 144px;
	}
	.focus-card__icon svg {
		width: 84px;
		height: 84px;
	}
}

/* ==========================================================================
   Focus areas — "Nurturing Communities" (Figma 11363:8925)
   A full-bleed photo carrying the section headline in a translucent bar, and
   below it a rail of six icon + label pillars (maroon-tint badges, maroon icons,
   FK Roman labels on a light card) beside their panels. Distinct from focus-cards
   (3 separate cards + bullets).

   The pillars were inside the bar until 2026-09-08; the client moved them out and
   the photo shrank in the same change, then rejected the result that afternoon —
   the rail shipped dark and came back as "this change looks weired on website".
   The layout survived; its colours and its label size did not. Why is in
   template-parts/sections/focus-areas.php, and the layout rules are at "Focus
   areas — rail beside the panels" below.
   ========================================================================== */
.focus-areas {
	position: relative;
	display: flex;
	align-items: center;
	justify-content: center;
	/* 240 → 400, down from 460 → 680 on 2026-09-08: "Reduce the size of that
	   image. Its looks to be very big." The old floor was not a taste decision —
	   it was the height needed to contain six 200px badges and a headline, so the
	   photo could only shrink once the badges left. It is the same clamp shape,
	   re-aimed: still tracking the viewport rather than stepping at breakpoints. */
	min-height: clamp(240px, 22vw, 400px);
	padding-block: var(--section-pad);
	overflow: hidden;
	background-color: var(--c-primary-900);   /* base behind the photo */
}

/* Photo layer — fills the whole band, sits behind the bar. */
.focus-areas__media {
	position: absolute;
	inset: 0;
	background-size: cover;
	background-position: center;
	background-repeat: no-repeat;
	z-index: 0;
}

.focus-areas__media--default {
	background-image: url("../images/nurturing-communities-focus.jpg");
	background-image: image-set(
		url("../images/nurturing-communities-focus.webp") type("image/webp"),
		url("../images/nurturing-communities-focus.jpg") type("image/jpeg")
	);
}

/* Full-width translucent bar over the photo. It wrapped the headline AND the icon
   row until 2026-09-08; the row moved to .focus-areas__aside and the headline is
   what is left, which is why the partial now renders this element only when there
   is a headline to put in it. The tint stays here rather than moving onto the
   .focus-highlight itself so the band still reads edge to edge. */
.focus-areas__bar {
	position: relative;
	z-index: 1;
	width: 100%;
	background-color: rgba(70, 70, 70, 0.62);
}

/* The pillars' own ground. This was --c-primary-900 for one day — the same value
   already behind the photograph, chosen because it let the white label / 10%-white
   badge / white focus ring / white disc ring carry over from the bar unchanged.
   The client rejected it that afternoon ("this change looks weired on website"),
   and the saving is what caused it: a near-black slab on a cream page reads as a
   leftover admin sidebar, not as part of the section. Nothing about the DARK
   version was wrong in isolation; it was wrong beside the rest of the page.

   So the five colours the old note listed as free are re-picked below for a light
   ground, all of them maroon-tint rather than white-tint: badge --c-primary-10,
   icon --c-primary, label --c-text, hover --c-primary-05, focus ring --c-primary.
   The disc's white ring is the one that survives, because on a 5%/10% maroon tint
   an opaque white halo still separates the disc from the badge behind it.

   Light in BOTH regimes, deliberately — the alternative was light rail above 1025
   and dark band below, i.e. two schemes for one component. Below 1025 this is a
   full-bleed band under the photo, so its edges are borders rather than a radius;
   the rounded rail proper starts at 1025. */
.focus-areas__aside {
	border-block: 1px solid var(--c-primary-10);
	background-color: var(--c-primary-05);
}

.focus-areas__list {
	display: flex;
	flex-wrap: nowrap;                 /* 6 true columns in one row up to 1024 */
	align-items: flex-start;
	justify-content: center;
	gap: clamp(8px, 1.2vw, 24px);
	width: 100%;
	margin: 0;
	padding-block: var(--sp-32);
	list-style: none;
}

.focus-area {
	display: flex;
	flex: 1 1 0;                       /* equal share, ignore content basis */
	min-width: 0;                      /* allow shrink so the row never wraps */
	flex-direction: column;
	align-items: center;
	gap: var(--sp-24);
	padding: var(--sp-32) var(--sp-16);
	text-align: center;
}

/* The badge is FLUID, not stepped (client, 2026-08-31: "see responsive for icons
   you can make smaller as screen size get smaller"). It used to be a fixed 200px
   dropping to 160/132 at breakpoints, and because .focus-area is `flex: 1 1 0`
   while the badge is `flex-shrink: 0`, any width between two breakpoints gave a
   badge wider than its own column: at ~905px the column is ~118px and the badge
   was still 160px, so the circles overlapped their neighbours and the last +/-
   sign was clipped by .focus-areas' overflow. A single clamp tracks the column
   instead of lagging behind it.

   --badge is the ONE source of truth: the icon is calc()'d from it below, so
   overriding --badge alone rescales the whole pillar. Width/height
   are set as a pair rather than via aspect-ratio, for older Safari. 12vw is the
   six-across share (6 x 12 = 72% plus gaps and padding); the per-regime overrides
   in the wrap breakpoints below raise it once there are fewer per row.

   --badge also sizes the +/- sign, which is why the positioning context below
   stays here. */
.focus-area__badge {
	--badge: clamp(96px, 12vw, 200px);
	position: relative;                /* anchors the +/- sign */
	display: flex;
	align-items: center;
	justify-content: center;
	flex-shrink: 0;
	width: var(--badge);
	height: var(--badge);
	border-radius: 999px;
	background-color: var(--c-primary-10);
	transition: background-color 0.25s ease;
}

/* 0.55 is Figma's own ratio (110 of 200). Custom properties inherit, so this
   tracks --badge automatically — do not restate a px size here. */
.focus-area__icon svg {
	display: block;
	width: calc(var(--badge) * 0.55);
	height: calc(var(--badge) * 0.55);
	color: var(--c-primary);
}

.focus-area__label {
	margin: 0;
	font-family: var(--ff-heading);
	font-weight: var(--fw-bold);
	/* 14px at 900 up to 32px at 1920. The old clamp(1rem, 2.1vw, …) bottomed out
	   at 16px, which is wider than a ~118px mid-range column can set
	   "Sustenance" in — hence the mid-word breaks. Floor is 14 so the longest
	   label still fits the narrowest six-across column on one word per line. */
	font-size: clamp(0.875rem, -0.1176rem + 1.7647vw, 2rem);
	line-height: 1.15;
	color: var(--c-text);
	overflow-wrap: break-word;   /* last-resort break only if a single word can't fit */
}

/* ---- Focus areas — responsive ------------------------------------------- */
/* The badge and icon are NOT restated in these blocks — the --badge clamp above
   already scales them continuously. Each breakpoint only re-aims --badge when the
   number of items per row changes, plus the padding that goes with it. */

/* Tablet (≤1280): still six across, tighter gutters. */
@media (max-width: 1280px) {
	.focus-area {
		padding: var(--sp-24) var(--sp-12);
	}
}

/* Small tablet (≤900): six across is too tight — wrap to three per row.

   This block dropped `.focus-areas { min-height: 0 }` on 2026-09-08. Its stated
   reason was to "let the bar size to its content (no forced photo reveal)", which
   was safe only while the bar held six 200px badges and so had ample height of its
   own. The badges are in .focus-areas__aside now, .focus-areas__media is
   position: absolute and contributes no height, and the bar is one line of
   headline — so min-height: 0 would collapse the band to a text-tall sliver of
   photograph, and to nothing at all on a page whose `highlight` is empty (the bar
   is not rendered then; see the partial). The base clamp holds at every width
   instead: 22vw is under the floor below 1090px, so ≤900 gets a flat 240px band. */
@media (max-width: 900px) {
	.focus-areas__list {
		flex-wrap: wrap;               /* three per row once six-across is too tight */
	}
	.focus-area {
		flex: 1 1 33.333%;
		max-width: none;
	}
	/* Three per row, so a column is ~33vw — the six-across 12vw would look
	   stranded in it. */
	.focus-area__badge {
		--badge: clamp(120px, 22vw, 200px);
	}
	/* Columns are wide again here, so the six-across 14px floor is needlessly
	   small; go back to the 24px step. */
	.focus-area__label {
		font-size: var(--fs-2xl);
	}
}

/* Phone (≤767): two per row. */
@media (max-width: 767px) {
	.focus-area {
		flex-basis: 50%;
		gap: var(--sp-16);
		padding: var(--sp-16) var(--sp-12);
	}
	.focus-area__badge {
		--badge: clamp(104px, 28vw, 176px);
	}
	/* Two per row is a NARROWER column than three per row, so the ≤900 jump to
	   --fs-2xl (25.6px here) has to come back down — at 375px it would set
	   "Development" wider than the column and break it mid-word, which is the
	   defect this pass exists to fix. 15px at 375 up to 24px at 767. */
	.focus-area__label {
		font-size: clamp(0.9375rem, 0.3994rem + 2.2959vw, 1.5rem);
	}
	.focus-highlight {
		padding-top: var(--sp-32);
	}
}

/* ==========================================================================
   Focus areas — pillar disclosures (client note, "Nurturing Communities
   Writeup.docx", 2026-08-31: "clicking on each pillar will give information on
   that pillar"). Each pillar in the bar is a button carrying a +/- sign; its
   panel opens BELOW the photo band, never over the photograph.
   Panels render open and are collapsed by JS on load, so the no-JS page is the
   whole write-up rather than six dead icons — see focus-areas.php.
   ========================================================================== */
.focus-areas-block {
	position: relative;
}

/* The <li> stays the equal-width column; the button fills it and takes over
   the stacking, so the whole column is one hit target. */
.focus-area--toggle {
	align-items: stretch;
	padding: 0;                        /* padding moves onto the button */
}

.focus-area__toggle {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: var(--sp-24);
	width: 100%;
	margin: 0;
	/* Inline padding came down from --sp-16 to --sp-8 on 31 Aug 2026 to make room for
	   a per-pillar caption that has since been replaced by one line above the list.
	   KEPT on its own merits: at six across the column is only ~180px, and 32px of
	   that going to padding is what forces the mid-word label breaks. The vertical
	   padding is untouched — it is what separates the pillars from the bar edges. */
	padding: var(--sp-32) var(--sp-8);
	border: 0;
	border-radius: var(--radius-lg);
	background: none;
	font: inherit;
	color: inherit;
	text-align: center;
	cursor: pointer;
	-webkit-appearance: none;
	appearance: none;
	transition: background-color 0.25s ease;
}

/* --c-primary-10, not the -05 that replaced the old white 8% one-for-one: these
   tints are translucent and the rail underneath is itself --c-primary-05, so 5% on
   5% composites to about 9.75% — a real change and far too small to read as an
   affordance. 10% lands near 14.5% against the rail and is the value that actually
   matches what the white 8% did on a dark ground. The open row goes the other way,
   to opaque white, which is the conventional split: hover says pressable, the
   surfaced row says selected. */
.focus-area__toggle:hover,
.focus-area__toggle:focus-visible {
	background-color: var(--c-primary-10);
}

.focus-area__toggle:hover .focus-area__badge,
.focus-area__toggle:focus-visible .focus-area__badge,
.focus-area__toggle[aria-expanded="true"] .focus-area__badge {
	background-color: var(--c-primary-20);
}

.focus-area__toggle:focus-visible {
	outline: 2px solid var(--c-primary);
	outline-offset: 2px;
}


/* ---- The open/close sign ------------------------------------------------ */
/* A maroon disc on the badge rim: plus when shut, minus when open. The vertical
   bar rotates flat rather than being swapped out, so the state change is one
   transform and needs no second element.

   Sized off --badge (0.24 = Figma's 48 of 200) so the disc keeps its proportion
   as the circle shrinks, with a 26px floor: below that it stops reading as a
   control and is under the 24px minimum touch target once the ring is counted.

   This carries the STATE and nothing else — what the disc MEANS is spelled out
   once above the list, in .focus-areas__hint. It briefly had a captioned twin
   beside each label (994d7d0, 4ab9c37); the client replaced those six captions
   with the single line on 31 Aug 2026, so the disc is back to being the one
   per-pillar indicator it started as.

   White ring, and it outlived the dark ground it was picked for: the reason was a
   maroon disc losing its edge against the bar behind it, and on the light rail the
   badge it overlaps is --c-primary-10 — a maroon tint, so the disc still needs
   separating from it. Opaque white now rather than 0.9, since there is no dark
   ground left for the translucency to pick up. */
.focus-area__sign {
	position: absolute;
	right: 2px;
	bottom: 2px;
	display: block;
	width: max(26px, calc(var(--badge) * 0.24));
	height: max(26px, calc(var(--badge) * 0.24));
	border-radius: 999px;
	background-color: var(--c-primary);
	box-shadow: 0 0 0 3px var(--c-white);
}

/* translate(-50%, -50%) rather than the old negative margins: the stroke width is
   now computed, so there is no fixed value to halve. Every transform on these two
   pseudo-elements must therefore CARRY the translate — a bare rotate() re-anchors
   the stroke to its top-left corner and the plus falls apart.

   No width here on purpose; each modifier sets its own, just above. */
.focus-area__sign::before,
.focus-area__sign::after {
	content: "";
	position: absolute;
	top: 50%;
	left: 50%;
	width: max(10px, calc(var(--badge) * 0.09));
	height: 2px;
	border-radius: 2px;
	background-color: var(--c-white);
	transform: translate(-50%, -50%);
	transition: transform 0.25s ease;
}

.focus-area__sign::after {
	transform: translate(-50%, -50%) rotate(90deg);   /* the plus's upright stroke */
}

.focus-area__toggle[aria-expanded="true"] .focus-area__sign::after {
	transform: translate(-50%, -50%) rotate(0deg);    /* flattens onto the other bar — a minus */
}

/* ---- The FY-26 highlight, on the bar above the icons --------------------- */
/* Client, 2026-08-31: "can we set this headline into banner above icons?" — so it
   rides the translucent bar instead of sitting on the cream below it. The bar is
   the scrim; no separate text-shadow is needed.

   Symmetric padding since 2026-09-08. It had none at the bottom for as long as the
   icon row sat underneath it inside this bar, because the <ul>'s own padding-block
   supplied that gap and a second one double-spaced them. The row has moved to the
   rail below, so the missing value is now the bar's bottom edge rather than a
   double gap, and the headline would otherwise sit on it. */
.focus-highlight {
	max-width: var(--container-max);
	margin: 0 auto;
	padding: var(--sp-48) var(--container-pad);
	font-family: var(--ff-heading);
	font-weight: var(--fw-bold);
	font-size: var(--fs-4xl);
	line-height: var(--lh-heading);
	letter-spacing: var(--ls-h3);
	color: var(--c-white);
	text-align: center;
	text-wrap: balance;                /* keeps a two-line wrap even, ignored where unsupported */
}

/* Primary/100, NOT --c-primary: maroon on this bar measures about 1.3:1. The
   light tint is the same accent translated for a dark ground, and the line is
   large + bold so the 3:1 threshold is the one that applies. */
.focus-highlight__accent {
	color: var(--c-primary-100);
}

/* ---- The band's one instruction line ------------------------------------- */
/* Client, 2026-08-31: the six per-pillar "Click to explore / Click to collapse"
   captions that shipped in 994d7d0 became ONE line for the whole band, and it goes
   ABOVE the icons. Below them it would be unreadable where it matters most: at
   <=767 the pillars wrap to three rows, so "below the icons" is most of a screen
   away from the first icon someone is deciding whether to press. An instruction
   has to arrive before the control it describes.

   Padding, not margin: this is a direct child of an unpadded
   .focus-areas__aside, so a top margin would collapse through the aside's edge and
   shift the whole band down instead of insetting the text. Bottom gap to the icon
   row is the <ul>'s own padding-block — same reason .focus-highlight has no
   padding-bottom.

   The --sp-48 top opens the band. It was on a `:first-child` rule until
   2026-09-08, when the pillars moved out of the bar into .focus-areas__aside and
   this line became that element's first child unconditionally — the selector could
   no longer be false, so it was a two-state design that had only one state left.
   Folded in here rather than kept as a rule that always matches. It is genuinely
   conditional the other way round, though: when the hint does NOT render, the <ul>
   is the first child and opens the band on its own padding-block instead.

   IT STOPPED BEING PROSE ON 2026-09-15. The client replaced “Tap or click any icon
   to explore its details” with “Our CSR Pillars” — a title for the rail, not an
   instruction about it — so the three type decisions recorded here were all made for
   a sentence that no longer exists, and every one of them inverts:

     --fs-l2 (16 -> 18px) had been raised from a bespoke clamp on client request,
     with the note that “it is prose, not a label, so --fs-s is wrong here”. Three
     words set at body size above a rail of --fs-2xl labels read as a stray line
     rather than as the thing that heads them, so it takes --fs-xl and the display
     face the other band labels use.

     --c-text-body, one shade down, was chosen so “an aside about how to use the
     band should not compete with the labels”. A title is meant to sit above them,
     so it takes --c-text.

     Centred suited a line addressed to the whole band. A title belongs over the
     left edge of the list it names, which is where the >=1025 rule had already
     put it; bringing text-align: left down to the base rule makes the two agree
     at every width instead of only at desktop, and lets that override drop the
     declaration it no longer needs.

   What does NOT change is the gate in focus-areas.php: the line still only renders
   when at least one pillar has copy to open. That is now slightly odd — a title
   should not depend on the panels — but page 49 is the only user and all six of its
   pillars have copy, so relaxing it would change a template to fix nothing. */
.focus-areas__hint {
	max-width: var(--container-max);
	margin: 0 auto;
	padding: var(--sp-48) var(--container-pad) 0;
	font-family: var(--ff-heading);
	font-weight: var(--fw-bold);
	font-size: var(--fs-xl);
	line-height: 1.3;
	color: var(--c-text);
	text-align: left;
}

/* Second and later group headings inside the same box (the `group` field). A
   hairline in the rail's own border colour marks where one group ends; the type is
   the first heading's, so the two read as equal-rank titles. */
.focus-areas__hint--group {
	border-top: 1px solid var(--c-primary-10);
}

/* ---- Panels -------------------------------------------------------------- */
.focus-areas__panels {
	max-width: var(--container-max);
	margin: 0 auto;
	padding-inline: var(--container-pad);
}

.focus-panel {
	padding-block: var(--section-pad);

	/* Where an opened panel comes to rest. initFocusAreas() scrollIntoView()s the
	   panel on click and does no arithmetic of its own, so this rule alone decides
	   the landing position: the site header is sticky at top: 0, and without a
	   margin here the panel would be scrolled to y=0 and then covered by the nav.

	   Same calc() as .ir-header__subtabs, and for the same reason — --header-h is a
	   token, so this tracks the header's own 80 → 64 step at 767 with no second
	   breakpoint to keep in sync. */
	scroll-margin-block-start: calc(var(--header-h) + var(--sp-24));
}

/* Every panel but the first shut one keeps its own rule, so consecutive open
   panels (the no-JS case) stay visually separate. */
.focus-panel + .focus-panel {
	border-top: 1px solid var(--c-border);
}

.focus-panel__inner {
	display: flex;
	flex-direction: column;
	gap: var(--sp-24);
}

.focus-panel__title {
	margin: 0;
	font-family: var(--ff-heading);
	font-weight: var(--fw-bold);
	font-size: var(--fs-4xl);
	line-height: var(--lh-heading);
	letter-spacing: var(--ls-h3);
	color: var(--c-primary);
}

.focus-panel__intro {
	margin: 0;
	font-family: var(--ff-body);
	font-size: var(--fs-l);
	line-height: var(--lh-base);
	color: var(--c-text-body);
}

/* Pillar and initiative photographs (client, 2026-09-10).

   Both are capped rather than filling their column: .focus-panel__inner is the
   full container, so an uncapped 16:9 figure would be ~810px tall on a desktop
   and the copy it illustrates would be pushed off the screen. The pillar figure
   gets the larger cap because it is the panel's only picture; the initiative one
   sits inside a bordered block alongside two or three others and stays smaller.

   aspect-ratio + object-fit rather than a fixed height, so a photograph that is
   not quite 16:9 is cropped instead of letterboxed — the supplied set runs from
   4:3 to 16:9. */
.focus-panel__figure,
.focus-init__figure {
	margin: 0;
	width: 100%;
	overflow: hidden;
	border-radius: var(--radius-lg);
	aspect-ratio: 16 / 9;
	background-color: var(--c-primary-05);
}

.focus-panel__figure {
	max-width: 720px;
}

.focus-init__figure {
	max-width: 520px;
	margin-bottom: var(--sp-16);
}

.focus-panel__img,
.focus-init__img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.focus-panel__sub {
	margin: var(--sp-8) 0 0;
	font-family: var(--ff-heading);
	font-weight: var(--fw-bold);
	font-size: var(--fs-2xl);
	line-height: var(--lh-base);
	color: var(--c-text);
}

.focus-panel__inits {
	display: flex;
	flex-direction: column;
	gap: var(--sp-32);
	margin: 0;
	padding: 0;
	list-style: none;
}

/* Maroon rule down the left of each initiative — the visual that separates a
   named project from the pillar's own introduction. */
.focus-init {
	padding-left: var(--sp-24);
	border-left: 3px solid var(--c-primary-20);
}

.focus-init__heading {
	margin: 0 0 var(--sp-12);
	font-family: var(--ff-heading);
	font-weight: var(--fw-bold);
	font-size: var(--fs-xl);
	line-height: var(--lh-base);
	color: var(--c-text);
}

.focus-init__body {
	margin: 0;
	font-family: var(--ff-body);
	font-size: var(--fs-l2);
	line-height: var(--lh-base);
	color: var(--c-text-body);
}

.focus-init__body + .focus-init__body {
	margin-top: var(--sp-16);
}

/* ---- Pillar disclosures — responsive ------------------------------------ */
/* Almost nothing here is breakpoint-dependent. The +/- disc is calc()'d off
   --badge and the band's instruction line off a clamp(), so both scale
   continuously; the disc's white ring is the one exception, thinning on phones
   because 3px around a ~26px disc reads as a blob.

   Between 994d7d0 and 31 Aug 2026 each pillar also carried its own caption, and
   that made the narrowest six-across column — ~117px, just above 900px, not at the
   phone end — the binding constraint on this whole band. It no longer is: the
   instruction is one full-width line above the list. So if these columns ever look
   crowded again, the things to tune are the label font, --badge and the toggle's
   --sp-8 inline padding, in the base rules rather than here. */
@media (max-width: 1280px) {
	.focus-area--toggle {
		padding: 0;
	}
	.focus-area__toggle {
		padding: var(--sp-24) var(--sp-8);   /* inline matches the base — see the note there */
	}
}

@media (max-width: 767px) {
	.focus-area__toggle {
		gap: var(--sp-16);
		padding: var(--sp-16) var(--sp-12);
	}
	.focus-area__sign {
		box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.9);
	}
	.focus-init {
		padding-left: var(--sp-16);
	}
}

/* Motion: the sign is the only animated part, and it is decoration. */
@media (prefers-reduced-motion: reduce) {
	.focus-area__sign::before,
	.focus-area__sign::after,
	.focus-area__badge,
	.focus-area__toggle {
		transition: none;
	}
}

/* ==========================================================================
   Focus areas — rail beside the panels (client, 2026-09-08, corrections item 11)

   The one thing to know before editing this block is where it sits. Everything
   above it — the six-across row, the three-step wrap cascade at 1280/900/767, the
   badge clamp — still describes the band up to 1024px, unchanged; this is the
   desktop relayout stacked on top. It therefore has to stay AFTER the
   pillar-disclosure rules it overrides (.focus-area__toggle, .focus-area__sign,
   .focus-area__badge), which are ~350 lines up, because it beats them on source
   order and not on specificity. Move it up beside the other focus-areas layout
   rules and half of it silently stops applying, with no error anywhere.

   It is a min-width query in a file whose focus-areas rules are otherwise all
   max-width. That is not a style break — the pillars' desktop shape is now the
   exception and their stacked shape the default, which is the opposite of how the
   band was originally built, and writing it as min-width is what lets the three
   existing max-width blocks be left completely alone.

   1025 rather than 1280: below about a thousand pixels a 320px rail leaves the
   panel too narrow to set body copy in, so the band goes back to being full width
   with the pillars across it. Above it there is room for both.

   What the client asked for and what this does are slightly different shapes, and
   the difference is deliberate — see the partial's header. They asked for the
   pillars "to the left"; the complaint behind it was scrolling up and down between
   a panel and the next pillar. Left alone would not have fixed that: it is the
   panels moving up ALONGSIDE the rail, plus the rail being sticky, that keeps all
   six choices on screen while one of them is being read.
   ========================================================================== */
@media (min-width: 1025px) {

	/* The body takes over containing the section. .focus-areas__panels carries its
	   own max-width and gutter below 1025, where it is the only thing in here; that
	   is dropped just below so the two do not nest and double-indent the copy. */
	.focus-areas__body {
		display: grid;
		grid-template-columns: minmax(280px, 340px) 1fr;
		gap: clamp(32px, 3.5vw, 72px);
		/* start, NOT the stretch default — this is what makes the rail sticky.
		   A stretched grid item is as tall as the row, so it has no travel inside
		   its own grid area and position: sticky becomes a no-op. */
		align-items: start;
		max-width: var(--container-max);
		margin: 0 auto;
		padding-block: var(--section-pad);
		padding-inline: var(--container-pad);
	}

	.focus-areas__aside {
		position: sticky;
		/* Same offset as .focus-panel's scroll-margin, and it has to stay the same:
		   the sticky rail and the scrolled-to panel both come to rest just under the
		   sticky site header, so if these two drift apart the top of an opened panel
		   ends up behind the rail's top edge or floating below it. --header-h is a
		   token, so both track the header's 80 → 64 step with no extra breakpoint. */
		top: calc(var(--header-h) + var(--sp-24));
		/* A card here, a full-bleed band below 1025 — so the base rule's border-block
		   becomes a border on all four sides and the radius comes back. */
		border: 1px solid var(--c-primary-10);
		border-radius: var(--radius-lg);
		overflow: hidden;   /* clips the pillars' own hover tint to the rounded corner */
	}

	/* One column, and the pillars stop being equal-width columns: in a rail they are
	   rows, so they size to their own content and the list sizes to the rail.

	   padding-inline: 0 is not tidying. The base rule sets `padding-block` alone, so
	   the UA's own `padding-inline-start: 40px` on a <ul> was still there — the rail
	   measured 340px while every row inside it measured 300, and those 40 invisible
	   pixels came off the label, which is what put five of six labels under the +/-
	   disc. It is harmless in the six-across band below, where the row is centred
	   flex and just shifts; in a stretch column it silently narrows every child. */
	.focus-areas__list {
		flex-direction: column;
		flex-wrap: nowrap;
		align-items: stretch;
		gap: 0;
		padding-block: var(--sp-12);
		padding-inline: 0;
	}

	.focus-area {
		flex: 0 0 auto;
		flex-direction: row;
		align-items: center;
		gap: var(--sp-16);
		padding: var(--sp-12) var(--sp-24);
		text-align: left;
	}

	/* A toggle pillar gives its padding to the button, so the whole row is one hit
	   target — same trade as the base rule this repeats at a different value.

	   The padding stays on .focus-area above rather than only on the button because
	   a pillar with no copy renders as an <li> holding a badge and a <p>, with no
	   button to carry it; that row would otherwise sit flush against the rail edge
	   while its neighbours were inset. No pillar on this page is in that state today
	   — all six carry an `intro` — but it is a per-pillar data condition, so one
	   emptied ACF field is all it takes. */
	.focus-area--toggle {
		padding: 0;
	}

	.focus-area__toggle {
		/* Takes over as the positioning context for the +/- disc, which the badge
		   holds below 1025. The disc is markup-nested inside the badge, so this pair
		   of rules — relative here, static on the badge — is what moves it from the
		   badge rim out to the row's trailing edge without touching the HTML. */
		position: relative;
		flex-direction: row;
		align-items: center;
		gap: var(--sp-16);
		/* Right padding leaves room for the disc, which is out of flow and so does not
		   reserve any. Spelled out as a sum rather than rounded to the --sp-64 rung:
		   the rung was 2px short of the parts and, more to the point, a magic number
		   cannot be checked against the thing it is reserving space for. Each term is
		   the rule it comes from — the disc's own `right`, its 26px floor width from
		   .focus-area__sign, and a gap. Shrink any of them and a long label runs under
		   the +/-, which is exactly what happened on 08 Sep. */
		padding: var(--sp-12) calc(var(--sp-24) + 26px + var(--sp-12)) var(--sp-12) var(--sp-24);
		border-radius: 0;   /* full-bleed rows inside the rail; the rail is what is rounded */
		text-align: left;
	}

	.focus-area__badge {
		/* --badge is the single source of truth (see its own note), so this one line
		   rescales the circle, the icon inside it and the disc's stroke length
		   together. 44px, down from 52 on 08 Sep: six rows plus the hint were making
		   a 691px slab of a rail, and the circle is the row's height driver — at
		   --sp-12 of row padding this is what sets the uniform 68px row.

		   What does NOT limit it is the +/- disc, contrary to what this note claimed
		   until the arithmetic was checked: `max(26px, --badge * 0.24)` holds its 26px
		   floor for any --badge up to ~108px (26 / 0.24), so the control stays 26px
		   whether the circle is 52, 44 or smaller, and the touch target is in no
		   danger here. In this regime the disc is positioned on the row anyway, not on
		   the badge rim, so the two sizes are independent. The real floor is the icon:
		   calc(--badge * 0.55) is already down to 24px at 44. */
		--badge: 44px;
		position: static;
	}

	.focus-area__label {
		/* Fixed rung, not the base clamp — that clamp reaches 32px at 1920 because it
		   was sized for a sixth of the viewport, not for a ~340px rail.

		   --fs-l (18 → 20), down from --fs-2xl. At 29px "Development" alone set 193px
		   wide, so `Education & Skill Development` could not wrap narrower than that
		   however much room it was given: min-content is a floor no amount of shrink
		   gets under, and it was 49px over the space available. Five of six labels ran
		   under the disc and the two longest took three lines each. This is a
		   navigation label — it was being set at heading size, which is the actual
		   mistake; the rung below leaves every label on one or two lines with room to
		   spare. Raise it back and re-measure min-content before believing it fits.

		   min-width: 0 so the flex item may shrink past its content basis at all. */
		min-width: 0;
		font-size: var(--fs-l);
		text-align: left;
	}

	/* Out of the badge's corner, onto the row's trailing edge and vertically centred.
	   The size is left alone because it does not change here: at --badge: 44 the
	   proportional arm of `max(26px, --badge * 0.24)` is 10.56px, so the disc is a
	   flat 26px — which is exactly the 26px the toggle's right padding reserves
	   above. The two only drift apart if --badge is raised past ~108px. */
	.focus-area__sign {
		top: 50%;
		right: var(--sp-24);
		bottom: auto;
		transform: translateY(-50%);
	}

	/* The open row, and the reason the rail needs one at all: as six identical buttons
	   beside a column of copy there is nothing saying which pillar the copy belongs to
	   — the +/- carries the state, but it is 26px at the far edge of the row. A white
	   fill plus a maroon edge makes the pair read as a vertical tab strip instead of a
	   list of buttons, which is the shape the client asked for.

	   inset-inline-start on a ::before rather than a border-left: a border would move
	   the label 3px whenever a row opened. Out of flow, so it cannot. */
	.focus-area__toggle[aria-expanded="true"] {
		background-color: var(--c-white);
	}

	.focus-area__toggle[aria-expanded="true"]::before {
		content: "";
		position: absolute;
		inset-block: 0;
		inset-inline-start: 0;
		width: 3px;
		background-color: var(--c-primary);
	}

	/* Beats the shared hover/focus rule ~350 lines up on specificity, not source
	   order: hovering the row that is already open must not tint it back off white. */
	.focus-area__toggle[aria-expanded="true"]:hover,
	.focus-area__toggle[aria-expanded="true"]:focus-visible {
		background-color: var(--c-white);
	}

	/* The label is the rail's first row rather than a full-bleed line above a band, so
	   it takes the rail's own inline padding and loses the --sp-48 the band gave it.
	   Padding only since 2026-09-15: text-align: left moved to the base rule when the
	   line became a title, so restating it here would be a no-op pretending to be an
	   override. */
	/* One selector, not the pair this started as: the base rule's
	   `:first-child` twin was folded away on 08 Sep, so there is no longer a
	   higher-specificity sibling here to out-rank. */
	.focus-areas__hint {
		padding: var(--sp-24) var(--sp-24) var(--sp-12);
	}

	/* Un-contains the panels: the body above is now the container, and leaving these
	   on would indent the copy by a second gutter and cap it a second time. */
	.focus-areas__panels {
		max-width: none;
		margin: 0;
		padding-inline: 0;
	}

	/* --section-pad here would be the third stacked band of whitespace in a column
	   that already has the body's own padding-block above it and a rail beside it to
	   stay level with. The border between consecutive panels is what separates them
	   in the no-JS case, and it still does. */
	.focus-panel {
		padding-block: 0;
	}

	.focus-panel + .focus-panel {
		margin-top: var(--sp-48);
		padding-top: var(--sp-48);
	}
}

/* ==========================================================================
   Stats — "Progress You Can Measure" (Figma Nurturing Planet 11295:4138)
   Centred header, three tint cards each with a white number disc + icon badge
   + label, then a right-aligned social share row.
   ========================================================================== */
.stats-progress {
	padding-block: var(--section-pad);
	padding-inline: 120px;
	background-color: var(--c-white);
}

.stats-progress__inner {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: var(--sp-64);   /* 60 in Figma; 64 token keeps rhythm */
	width: 100%;
	max-width: 1680px;   /* 3×538 + 2×32 gap — matches focus/nurture cards */
	margin-inline: auto;
}

/* ---- Header block -------------------------------------------------------- */
.stats-progress__head {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: var(--sp-16);
	text-align: center;
	width: 100%;
}

.stats-progress__eyebrow {
	display: inline-flex;
	align-items: center;
	padding: var(--sp-8) var(--sp-12);
	border-radius: 80px;
	background-color: var(--c-primary-10);
	font-family: var(--ff-body);
	font-weight: var(--fw-medium);
	font-size: var(--fs-m);
	line-height: var(--lh-base);
	color: var(--c-primary);
}

.stats-progress__heading {
	max-width: 20ch;
	font-family: var(--ff-heading);
	font-weight: var(--fw-bold);
	font-size: var(--fs-4xl);   /* fluid 32 → 48 */
	line-height: var(--lh-base);
	color: var(--c-dark);
}

.stats-progress__subhead {
	max-width: 60ch;
	font-family: var(--ff-body);
	font-weight: var(--fw-regular);
	font-size: var(--fs-l2);    /* 18 */
	line-height: var(--lh-base);
	color: var(--c-text-muted);
}

/* ---- Cards --------------------------------------------------------------- */
.stats-progress__row {
	display: flex;
	gap: var(--sp-32);
	align-items: stretch;   /* equal-height cards */
	justify-content: center;
	width: 100%;
	margin: 0;
	padding: 0;
	list-style: none;
}

/* A band carrying ONE stat rather than three — Nurturing People has a single
   zero-accidents figure (client, 9 Sep). `flex: 1 1 0` would stretch that card
   across the whole 1680 row and strand a 250px disc in the middle of it, so a
   lone card takes the 538px it would have had as one of three. */
.stat-card:only-child {
	flex: 0 1 538px;
}

.stat-card {
	display: flex;
	flex: 1 1 0;
	flex-direction: column;
	align-items: center;
	gap: var(--sp-32);
	min-width: 0;
	padding: var(--sp-32);
	background-color: var(--c-primary-05);
	border: 1px solid var(--c-gray-100);
	border-radius: var(--radius-lg);
	text-align: center;
}

/* Decorative white disc holding the number (pure CSS, no image). */
.stat-card__disc {
	display: flex;
	align-items: center;
	justify-content: center;
	flex-shrink: 0;
	width: 250px;
	height: 250px;
	border-radius: 999px;
	background-color: var(--c-white);
	box-shadow: 0 10px 40px -12px rgba(17, 1, 7, 0.12);
}

/* Ring variant (client override — see stats-progress.php's docblock): the disc
   grows a progress arc when the stat has a `percent`. Blank percent = no
   --ring class = the plain Figma disc above, so pages that never set one are
   untouched. The ring is drawn ON the disc, not instead of it: this band's card
   is the maroon tint and the disc is the white element, so a ring on the bare
   card would sit a --c-primary-10 track on a pink panel and lose the unfilled
   arc. Stroke colours/widths are shared with .stat-donut__ring-* below rather
   than repeated — one place to change the stroke for both bands. */
.stat-card__disc--ring {
	display: grid;   /* was flex: the svg and the value share one cell */
	place-items: center;
}

.stat-card__disc--ring > * {
	grid-area: 1 / 1;   /* stack svg + value */
}

.stat-card__value {
	font-family: var(--ff-heading);
	font-weight: var(--fw-bold);
	font-size: var(--fs-5xl);   /* 60 */
	line-height: 1;
	color: var(--c-primary);
}

.stat-card__badge {
	display: flex;
	align-items: center;
	justify-content: center;
	flex-shrink: 0;
	padding: var(--sp-16);
	border-radius: 999px;
	background-color: var(--c-gray-10);
}

.stat-card__icon svg {
	display: block;
	width: 48px;
	height: 48px;
	color: var(--c-text);
}

.stat-card__label {
	font-family: var(--ff-body);
	font-weight: var(--fw-semibold);
	font-size: var(--fs-2xl);   /* 32 */
	line-height: var(--lh-base);
	letter-spacing: var(--ls-h3);   /* was -0.32px = 32 x -1%; now em, so it scales */
	color: var(--c-text);
}

/* ---- Social share row (shared: stats-progress + text-share + link-cards) - */

/* ---- Member profile (single member) — two-column per Figma 11371:9642 --- */
.member-profile {
	padding: 100px var(--sp-80) 120px;
	background: var(--c-white);
}
.member-profile__inner {
	width: 100%;
	max-width: 1680px;
	margin-inline: auto;
	padding-inline: 40px;
	display: flex;
	flex-direction: row;
	align-items: center;
	gap: var(--sp-80);
}
.member-profile__media {
	flex: 0 0 auto;
	width: 500px;
	max-width: 42%;
	margin: 0;
	aspect-ratio: 1 / 1;
	border: 2px solid var(--c-gray-200);
	border-radius: var(--radius-lg);
	overflow: hidden;
}
.member-profile__img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
}
.member-profile__text {
	flex: 1 1 0;
	min-width: 0;
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: 40px;
}
.member-profile__head {
	display: flex;
	flex-direction: column;
	gap: var(--sp-16);
	width: 100%;
}
.member-profile__name {
	font-size: var(--fs-4xl);
	line-height: 1.3;
	/* Was a literal -1px, i.e. the same Figma percent-vs-px misread as --ls-h3
	   (see tokens.css): on 48px text -1px is -0.021em, about twice the -1% the
	   design specifies. Loosens slightly as a result — that is the fix. */
	letter-spacing: var(--ls-h3);
	color: var(--c-primary);
}
.member-profile__role {
	font-size: var(--fs-l);
	font-weight: var(--fw-medium);
	line-height: 1.4;
	color: var(--c-text-muted);
}
.member-profile__bio {
	font-size: var(--fs-xl);
	line-height: 1.4;
	color: var(--c-text-muted);
}
.member-profile__bio p {
	margin: 0 0 var(--sp-16);
}
.member-profile__bio p:last-child {
	margin-bottom: 0;
}
.member-profile__bio a {
	color: var(--c-primary);
	text-decoration: underline;
}

/* ---- Member profile — responsive ---------------------------------------- */
@media (max-width: 1280px) {
	.member-profile {
		padding: 80px var(--sp-64) 100px;
	}
	.member-profile__inner {
		padding-inline: var(--sp-16);
		gap: var(--sp-48);
	}
	.member-profile__media {
		width: 420px;
	}
}
@media (max-width: 900px) {
	.member-profile__inner {
		flex-direction: column;
		align-items: flex-start;
		gap: var(--sp-32);
	}
	.member-profile__media {
		width: min(440px, 100%);
		max-width: 100%;
	}
}
@media (max-width: 767px) {
	.member-profile {
		padding: 64px var(--container-pad);
	}
	.member-profile__inner {
		padding-inline: 0;
	}
	.member-profile__media {
		width: 100%;
	}
	.member-profile__text {
		gap: var(--sp-24);
	}
}

/* ---- Stats — responsive -------------------------------------------------- */
@media (max-width: 1280px) {
	.stats-progress {
		padding-inline: var(--sp-64);   /* 64 */
	}
	.stat-card {
		gap: var(--sp-24);
		padding: var(--sp-24);
	}
	.stat-card__disc {
		width: 200px;
		height: 200px;
	}
}

/* Small tablet (≤900): three columns get too narrow (card 2 has long copy) —
   stack into one centred column and cap the card width. */
@media (max-width: 900px) {
	.stats-progress {
		padding-inline: var(--sp-48);   /* 48 */
	}
	.stats-progress__row {
		flex-direction: column;
		align-items: center;
		gap: var(--sp-24);
	}
	.stat-card {
		flex: 0 0 auto;
		width: 100%;
		max-width: 480px;
	}
	/* Re-state for the lone-card case: `.stat-card:only-child` below outranks
	   the bare class on specificity, so without this it would keep its desktop
	   538px basis all the way down. */
	.stat-card:only-child {
		flex: 0 0 auto;
	}
}

/* Phone (≤767): page side gutter; number/label step down via the --fs tokens. */
@media (max-width: 767px) {
	.stats-progress {
		padding-inline: var(--container-pad);   /* 16 */
	}
	.stat-card__disc {
		width: 180px;
		height: 180px;
	}
}

/* ==========================================================================
   Stats — donut rings ("Progress You Can Measure", Sustainability 11281:2617)
   Distinct from .stats-progress (white discs): here the BAND is the maroon-5%
   tint and the CARDS are white, and the number sits in an SVG progress ring.
   ========================================================================== */
.stats-donut {
	padding-block: var(--section-pad);
	padding-inline: 120px;
	background-color: var(--c-primary-05);   /* band is the tint (inverted vs stats-progress) */
}

.stats-donut__inner {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: var(--sp-64);   /* 60 in Figma; 64 token keeps rhythm */
	width: 100%;
	max-width: 1680px;   /* 3×538 + 2×32 gap — matches the other card rows */
	margin-inline: auto;
}

/* ---- Header block -------------------------------------------------------- */
.stats-donut__head {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: var(--sp-16);
	text-align: center;
	width: 100%;
}

.stats-donut__eyebrow {
	display: inline-flex;
	align-items: center;
	padding: var(--sp-8) var(--sp-12);
	border-radius: 80px;
	background-color: var(--c-primary-10);
	font-family: var(--ff-body);
	font-weight: var(--fw-medium);
	font-size: var(--fs-m);
	line-height: var(--lh-base);
	color: var(--c-primary);
}

.stats-donut__heading {
	max-width: 20ch;
	font-family: var(--ff-heading);
	font-weight: var(--fw-bold);
	font-size: var(--fs-4xl);   /* fluid 32 → 48 */
	line-height: var(--lh-base);
	color: var(--c-dark);
}

.stats-donut__subhead {
	max-width: 60ch;
	font-family: var(--ff-body);
	font-weight: var(--fw-regular);
	font-size: var(--fs-l2);    /* 18 */
	line-height: var(--lh-base);
	color: var(--c-text-muted);
}

/* ---- Cards --------------------------------------------------------------- */
.stats-donut__row {
	display: flex;
	gap: var(--sp-32);
	align-items: stretch;   /* equal-height cards */
	justify-content: center;
	width: 100%;
	margin: 0;
	padding: 0;
	list-style: none;
}

/* Four-up (2026-09-14): the recyclable-packaging stat moved here from Nurturing
   Planet, and a fourth card overflows the row at desktop — see the note in
   template-parts/sections/stats-donut.php. These are the same figure and padding
   the <=1280 breakpoint below already applies, deliberately.

   Bounded to >=1281 on purpose. Below that the breakpoints already size the
   figure (200px, then 180px on phones) for every row regardless of count, and
   an unbounded .stats-donut__row--4 .stat-donut__figure would outrank those
   single-class rules on specificity and pin four-card rows at 200px on phones
   where every other row steps down to 180px. */
@media (min-width: 1281px) {
	.stats-donut__row--4 .stat-donut {
		gap: var(--sp-24);
		padding: var(--sp-24);
	}
	.stats-donut__row--4 .stat-donut__figure {
		width: 200px;
		height: 200px;
	}
}

/* Four-up type, from 901px UP — everywhere the row is still a row (2026-09-15,
   on the client's "make fonts smaller for this box"). The figures were sized for
   three circles across a 1320 container; at four they sit in a box a fifth
   narrower and read as crowded.

   Deliberately NOT folded into the >=1281 block above. Between 901 and 1280 the
   cards are narrower still — 264px against 306px — so that range needs the
   smaller type MORE, not less. Below 901 the row stacks into one 480px-wide
   column and the full-size type is right again, which is where this stops.

   Specificity, because three rules compete for the same element:
     - the ring value needs (0,3,0) to clear the page-scoped 48px cap at the
       foot of this file, which is (0,2,0) but sits LATER and would otherwise
       win the tie on source order;
     - the count value needs (0,4,0) to clear its own (0,3,0) rule below.
   Both are steps DOWN, consistent with a cap whose purpose is to stop this text
   getting bigger, never to force it up. */
@media (min-width: 901px) {
	.stats-donut__row--4 .stat-donut .stat-donut__value {
		font-size: var(--fs-3xl);   /* 48 → 40 */
	}

	/* The count takes a second step: "900,000+" measures 4.94em where "59%" is
	   about 1.9em, so it has to clear the 200px disc on its own terms. The
	   <=1280 rule further down fixes the same overflow for three-card rows —
	   this is the four-up half of one bug. */
	.stats-donut__row--4 .stat-donut--count .stat-donut__figure--count .stat-donut__value {
		font-size: var(--fs-2xl);   /* 40 → 32 */
	}

	.stats-donut__row--4 .stat-donut__label {
		font-size: var(--fs-xl);    /* 32 → 24 */
	}

	.stats-donut__row--4 .stat-donut__badge {
		padding: var(--sp-12);
	}
	.stats-donut__row--4 .stat-donut__icon svg {
		width: 40px;
		height: 40px;
	}
}

.stat-donut {
	display: flex;
	flex: 1 1 0;
	flex-direction: column;
	align-items: center;
	gap: var(--sp-32);
	min-width: 0;
	padding: var(--sp-32);
	background-color: var(--c-white);   /* card is white on the tint band */
	border: 1px solid var(--c-gray-100);
	border-radius: var(--radius-lg);
	box-shadow: 0 10px 40px -18px rgba(17, 1, 7, 0.08);
	text-align: center;
}

/* Circular figure (250px) — holds either the ring or the unit graphic. */
.stat-donut__figure {
	flex-shrink: 0;
	width: 250px;
	height: 250px;
}

/* Ring variant: SVG ring + centred value overlaid in the same grid cell. */
.stat-donut__figure--ring {
	display: grid;
	place-items: center;
}

.stat-donut__figure--ring > * {
	grid-area: 1 / 1;   /* stack svg + value */
}

/* The three rules below also paint the Nurturing Planet ring
   (.stat-card__ring, added 2026-08-14). Comma-extended rather than copied: the
   two bands sit one nav click apart, and a duplicated stroke-width is exactly
   the kind of thing that gets changed in one place only. Geometry is identical
   on both sides (250 viewBox, r=116, pathLength=100), so this is safe — if the
   two ever need different strokes, split the selectors then, don't override. */
.stat-donut__ring,
.stat-card__ring {
	display: block;
	width: 100%;
	height: 100%;
	transform: rotate(-90deg);   /* start the arc at 12 o'clock */
}

.stat-donut__ring-track,
.stat-card__ring-track {
	fill: none;
	stroke: var(--c-primary-10);
	stroke-width: 18;
}

.stat-donut__ring-arc,
.stat-card__ring-arc {
	fill: none;
	stroke: var(--c-primary);
	stroke-width: 18;
	stroke-linecap: round;
	/* pathLength="100" → percent maps 1:1; arc = --pct units, gap = the rest. */
	stroke-dasharray: var(--pct, 0) 100;
	/* initStatCounters() flips --pct to 0 and back when the card scrolls in, so
	   the arc sweeps in step with the count-up. Transitioning stroke-dasharray
	   (not the custom property) keeps this working without @property. Duration
	   matches the counter's DURATION in main.js — change both together. */
	transition: stroke-dasharray 1200ms cubic-bezier(0.22, 1, 0.36, 1);
}

/* The counter bails before touching --pct under reduced motion, so the ring is
   already static there. Belt and braces in case the arc is ever driven from
   elsewhere. */
@media (prefers-reduced-motion: reduce) {
	.stat-donut__ring-arc,
	.stat-card__ring-arc {
		transition: none;
	}
}

/* Unit variant (card 3): maroon wave graphic above value + unit. */
.stat-donut__figure--unit {
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: var(--sp-16);
}

.stat-donut__wave {
	display: block;
	width: 100%;
	color: var(--c-primary);   /* rect fill = currentColor; wave lines are white */
}

.stat-donut__wave svg {
	display: block;
	width: 100%;
	height: auto;
}

.stat-donut__unitwrap {
	display: flex;
	flex-direction: column;
	align-items: center;
}

.stat-donut__value {
	font-family: var(--ff-heading);
	font-weight: var(--fw-bold);
	font-size: var(--fs-5xl);   /* 60 */
	line-height: 1.2;
	color: var(--c-primary);
}

.stat-donut__unit {
	font-family: var(--ff-heading);
	font-weight: var(--fw-bold);
	font-size: var(--fs-2xl);   /* 32 */
	line-height: 1.2;
	color: var(--c-primary);
}

/* Count variant (2026-08-31): a solid maroon disc for a figure that is a total
   rather than a share — "900,000+" lives impacted through CSR, which replaced
   the rainwater stat. Same 250px circle as the ring so the band stays three
   equal circles, but filled instead of arced: there is no denominator to draw.
   Geometry is deliberately a copy of --ring's grid stack rather than a shared
   selector, because the ring's stroke rules are already comma-shared with
   Nurturing Planet's .stat-card__ring and this variant must not inherit them. */
.stat-donut__figure--count {
	display: grid;
	place-items: center;
}

.stat-donut__figure--count > * {
	grid-area: 1 / 1;   /* stack disc + value */
}

.stat-donut__disc {
	display: block;
	width: 100%;
	height: 100%;
}

.stat-donut__disc circle {
	fill: var(--c-primary);
}

/* Reversed out of the maroon, and a step down from the ring's 60px: a grouped
   count like "900,000+" is ~8 glyphs where "59%" is 3, and at --fs-5xl it would
   overrun the 232px disc. --fs-3xl tops out at 40 and still fits at the 180px
   figure the phone breakpoint uses.

   THREE classes on purpose. The page-scoped 48px cap at the foot of this file
   (the client's "all 60px text is 48px on /sustainability/" override) matches
   .stat-donut__value at (0,2,0) and sits LATER, so a two-class selector here
   loses the tie and the count renders at 48 — which overruns the disc once the
   figure drops to 200px at ≤1280. (0,3,0) settles it by weight rather than by
   source order. Going SMALLER than that cap is consistent with it: the cap
   exists to stop this text getting bigger, never to force it up. */
.stat-donut--count .stat-donut__figure--count .stat-donut__value {
	font-size: var(--fs-3xl);   /* 32 → 40 */
	color: var(--c-white);
	padding-inline: var(--sp-16);
}

.stat-donut__badge {
	display: flex;
	align-items: center;
	justify-content: center;
	flex-shrink: 0;
	padding: var(--sp-16);
	border-radius: 999px;
	background-color: var(--c-gray-10);
}

.stat-donut__icon svg {
	display: block;
	width: 48px;
	height: 48px;
	color: var(--c-text);
}

.stat-donut__label {
	font-family: var(--ff-body);
	font-weight: var(--fw-semibold);
	font-size: var(--fs-2xl);   /* 32 */
	line-height: var(--lh-base);
	letter-spacing: var(--ls-h3);   /* was -0.32px = 32 x -1%; now em, so it scales */
	color: var(--c-text);
}

/* ---- Stats donut — responsive ------------------------------------------- */
@media (max-width: 1280px) {
	.stats-donut {
		padding-inline: var(--sp-64);   /* 64 */
	}
	.stat-donut {
		gap: var(--sp-24);
		padding: var(--sp-24);
	}
	.stat-donut__figure {
		width: 200px;
		height: 200px;
	}

	/* The count has to come down with the figure, and this is a FIX, not a
	   refinement: "900,000+" measures 4.94em in FK Roman Bold, so it needs
	   34px or less to sit inside a 200px disc and was running out past the
	   edge at --fs-3xl (36px here, 40 at the top of its clamp). The left "9"
	   and the "+" were both clipped. This has been wrong since the figure
	   first stepped down at this breakpoint — the comment on the base rule
	   predicted it and the prediction was not acted on — and it is wrong at
	   ≤767 too, where the figure is 180px; that case is covered from here,
	   since this query matches phones as well.

	   --fs-2xl tops out at 32, giving 158px of text plus 32px of padding
	   against a 200px disc, so it fits at every width in this range with
	   room to spare. Measured in the browser, not estimated. Same three
	   classes as the rule it overrides, and later in the file, so it wins on
	   source order. */
	.stat-donut--count .stat-donut__figure--count .stat-donut__value {
		font-size: var(--fs-2xl);
	}
}

/* ≤900: card 2 has long copy and three columns get too narrow — stack into
   one centred column and cap the card width. */
@media (max-width: 900px) {
	.stats-donut {
		padding-inline: var(--sp-48);   /* 48 */
	}
	.stats-donut__row {
		flex-direction: column;
		align-items: center;
		gap: var(--sp-24);
	}
	.stat-donut {
		flex: 0 0 auto;
		width: 100%;
		max-width: 480px;
	}
}

/* Phone (≤767): page side gutter; number/label step down via the --fs tokens. */
@media (max-width: 767px) {
	.stats-donut {
		padding-inline: var(--container-pad);   /* 16 */
	}
	.stat-donut__figure {
		width: 180px;
		height: 180px;
	}
}

/* ==========================================================================
   Impact initiatives — alternating text ↔ image rows with an edge stat-badge
   (Nurturing Communities 11297:4743). Each photo carries a maroon half-capsule
   that bulges past its OUTER edge; the badge always hugs the same side as the
   image, driven by one per-row image_side toggle. Gutter 120/80/24 + inner
   max 1680 align with feature-split. Rows stack (image on top) on tablets down.
   ========================================================================== */
.impact {
	padding-block: var(--section-pad);
	padding-inline: 120px;
}

.impact__inner {
	display: flex;
	flex-direction: column;
	gap: clamp(var(--sp-64), 8vw, 120px);
	max-width: 1680px;
	margin-inline: auto;
}

.impact-row {
	display: flex;
	align-items: center;
	gap: 60px;
}

/* Image on the right: DOM stays media-first, visual order flips. */
.impact-row--image-right {
	flex-direction: row-reverse;
}

/* --- Media: composite promo image (photo + baked-in maroon stat badge). --- */
.impact-row__media {
	flex: 1.05 1 0;
	min-width: 0;
}

.impact-row__img {
	display: block;
	width: 100%;
	height: auto;
	border-radius: var(--radius-lg);
}

/* --- Text column --- */
.impact-row__content {
	flex: 1 1 0;
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: var(--sp-32);
}

.impact-row__text {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: var(--sp-16);
}

.impact-row__heading {
	margin: 0;
	font-family: var(--ff-heading);
	font-weight: var(--fw-bold);
	font-size: var(--fs-3xl);      /* 40 */
	line-height: var(--lh-base);
	color: var(--c-dark);
}

.impact-row__accent {
	color: var(--c-primary);
}

.impact-row__focus {
	margin: 0;
	font-family: var(--ff-body);
	font-weight: var(--fw-regular);
	font-size: var(--fs-xl);       /* 24 */
	line-height: var(--lh-base);
	color: var(--c-text-muted);
}

.impact-row__focus-label {
	font-weight: var(--fw-semibold);
}

.impact-row__body {
	margin: 0;
	font-family: var(--ff-body);
	font-weight: var(--fw-medium);
	font-size: var(--fs-l);        /* 20 */
	line-height: 1.6;
	color: var(--c-text-muted);
}

@media (max-width: 1280px) {
	.impact {
		padding-inline: 80px;
	}
	.impact-row {
		gap: var(--sp-48);
	}
}

/* Tablet down: stack (image on top for both sides). */
@media (max-width: 900px) {
	.impact-row,
	.impact-row--image-right {
		flex-direction: column;
		align-items: stretch;
		gap: var(--sp-32);
	}
	.impact-row__media {
		flex: none;
		width: 100%;
	}
	.impact-row__content {
		flex: none;
	}
}

@media (max-width: 767px) {
	.impact {
		padding-inline: var(--container-pad);
	}
	.impact-row__content {
		gap: var(--sp-24);
	}
	.impact-row__text {
		gap: var(--sp-12);
	}
}

/* ==========================================================================
   Contact Us — registered-office card + social row (Figma node 11302:4049)
   A maroon-tint (5%) rounded card: centred head (eyebrow / serif name / note)
   over two WHITE panels — contact details left, query lines right. The tint
   shows around/between the panels; that contrast is the separation, not borders.
   ========================================================================== */
.contact-info {
	padding-block: var(--section-pad);
	background: var(--c-white);
}
.contact-info__inner {
	width: 100%;
	max-width: 1680px;
	margin-inline: auto;
	padding-inline: 40px;
}

.contact-info__card {
	max-width: 1440px;
	margin-inline: auto;
	padding: clamp(40px, 4vw, 60px) clamp(24px, 3vw, 48px);
	background: var(--c-primary-05);
	border-radius: var(--radius-lg);
}

/* ---- Head (centred) ---- */
.contact-info__head {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: var(--sp-12);
	text-align: center;
	margin-bottom: clamp(32px, 3.5vw, 48px);
}
.contact-info__eyebrow {
	margin: 0;
	font-family: var(--ff-body);
	font-weight: var(--fw-semibold);
	font-size: var(--fs-m);        /* 16 */
	line-height: var(--lh-base);
	color: var(--c-primary);
}
.contact-info__title {
	margin: 0;
	font-family: var(--ff-heading);
	font-weight: var(--fw-bold);
	font-size: var(--fs-4xl);      /* fluid 32 → 48 */
	line-height: var(--lh-heading);
	letter-spacing: var(--ls-h3);
	color: var(--c-text);
}
.contact-info__note {
	margin: 0;
	max-width: 680px;
	font-family: var(--ff-body);
	font-weight: var(--fw-regular);
	font-size: var(--fs-l2);       /* 18 */
	line-height: var(--lh-base);
	color: var(--c-gray-600);
}

/* ---- Two white panels ---- */
.contact-info__cols {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	align-items: stretch;
	gap: clamp(24px, 2.5vw, 40px);
}
.contact-info__panel {
	flex: 1 1 480px;
	max-width: 574px;
	display: flex;
	flex-direction: column;
	gap: var(--sp-16);
	padding: var(--sp-24);
	background: var(--c-white);
	border-radius: var(--radius-lg);
}
.contact-info__panel--queries {
	justify-content: center;   /* vertically centre the query lines */
}

/* ---- Left panel: icon + text rows ---- */
.contact-info__row {
	display: flex;
	align-items: flex-start;
	gap: var(--sp-8);
	margin: 0;
}
.contact-info__icon {
	flex: 0 0 auto;
	display: inline-flex;
	padding-top: 2px;              /* nudge the 24px icon to the text cap-height */
	color: var(--c-primary);
}
.contact-info__icon svg {
	display: block;
	width: 24px;
	height: 24px;
}
.contact-info__row-text {
	font-family: var(--ff-body);
	font-weight: var(--fw-regular);
	font-size: var(--fs-l);        /* 20 */
	line-height: var(--lh-base);
	color: var(--c-gray-800);
	word-break: break-word;
}

/* ---- Right panel: label : value lines ---- */
.contact-info__query {
	margin: 0;
	font-family: var(--ff-body);
	line-height: var(--lh-base);
	color: var(--c-gray-800);
	word-break: break-word;
}
.contact-info__query-label {
	font-weight: var(--fw-semibold);
	font-size: var(--fs-l2);       /* 18 */
	color: var(--c-primary);
}
.contact-info__query-value {
	font-weight: var(--fw-semibold);
	font-size: var(--fs-l);        /* 20 */
	color: var(--c-gray-800);
}

/* ---- Shared link affordance (colour shift, no underline) ---- */
.contact-info__link {
	/* No colour here: the link keeps the #3a3e47 of its paired
	   .contact-info__row-text / .contact-info__query-value class.
	   (An explicit `color: inherit` here would win on equal specificity
	   and pull a lighter inherited colour — the email-row bug.) */
	text-decoration: none;
	transition: color 0.2s ease;
}
.contact-info__link:hover,
.contact-info__link:focus-visible {
	color: var(--c-primary);
}

/* Phone: stack the two panels full-width. */
@media (max-width: 767px) {
	.contact-info__panel {
		flex-basis: 100%;
		max-width: 100%;
	}
	.contact-info__panel--queries {
		justify-content: flex-start;
	}
}

/* ==========================================================================
   Legacy Timeline — "A Legacy of Everyday Trust" (About Us, Figma 11363:8525)
   A maroon-tint band with a centred header over a vertical serpentine timeline.
   Milestones alternate left/right on a wavy maroon line (inline SVG path); the
   dots are CSS circles kept aligned to the line by an equal-row grid. Collapses
   to a single left-rail list below the alternating breakpoint.
   ========================================================================== */
.legacy-timeline {
	background: var(--c-primary-05);
	padding: clamp(var(--sp-48), 6vw, 100px) 0;
}

.legacy-timeline__inner {
	max-width: var(--container-max);
	margin-inline: auto;
	padding-inline: var(--container-pad);
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: clamp(var(--sp-32), 4vw, 60px);
}

/* ---- Header block -------------------------------------------------------- */
.legacy-timeline__head {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: var(--sp-16);
	text-align: center;
	width: 100%;
}

.legacy-timeline__eyebrow {
	display: inline-flex;
	align-items: center;
	padding: var(--sp-8) var(--sp-12);
	border-radius: 80px;
	background-color: var(--c-primary-10);
	font-family: var(--ff-body);
	font-weight: var(--fw-medium);
	font-size: var(--fs-m);
	line-height: var(--lh-base);
	color: var(--c-primary);
}

.legacy-timeline__heading {
	max-width: 22ch;
	font-family: var(--ff-heading);
	font-weight: var(--fw-bold);
	font-size: var(--fs-4xl);   /* fluid 32 → 48 */
	line-height: var(--lh-base);
	color: var(--c-dark);
}

.legacy-timeline__subhead {
	max-width: 60ch;
	font-family: var(--ff-body);
	font-weight: var(--fw-regular);
	font-size: var(--fs-l2);    /* 18 */
	line-height: var(--lh-base);
	color: var(--c-text-muted);
}

/* ---- Timeline track (alternating serpentine) ----------------------------- */
.legacy-timeline__track {
	--tl-band: clamp(90px, 12vw, 150px);  /* horizontal gap between the two dot columns */
	--tl-row: clamp(190px, 20vw, 240px);  /* equal height per milestone row */
	--tl-dot: 24px;
	list-style: none;
	margin: 0;
	padding: 0;
	position: relative;
	display: grid;
	/* Rows are a FIXED height, not minmax(...,auto), and must stay that way: the
	   wave's node i is drawn at (i*100+50) of a count*100 viewBox stretched over
	   the whole track, so it only lands on a row's centre while every row is the
	   same height. One tall milestone (2025 carries three points) overspills its
	   row by a few px rather than growing it — which is safe, because the body is
	   centred and consecutive milestones sit in OPPOSITE columns, so a spill has
	   only the far-away i±2 neighbour to clear and ~55px of slack to do it in.
	   Swapping this for auto rows unpegs every dot from the line. */
	grid-auto-rows: var(--tl-row);
	width: 100%;
	max-width: 900px;
}

/* The wavy connecting line: a single path stretched over the central band. */
.legacy-timeline__wave {
	position: absolute;
	top: 0;
	bottom: 0;
	left: 50%;
	transform: translateX(-50%);
	width: var(--tl-band);
	height: 100%;
	overflow: visible;
	pointer-events: none;
}

.legacy-timeline__wave path {
	stroke: var(--c-primary);
	stroke-width: 2;
	opacity: 0.55;
}

.legacy-timeline__event {
	display: grid;
	grid-template-columns: 1fr var(--tl-band) 1fr;
	align-items: center;
	position: relative;
}

.legacy-timeline__body {
	/* A plain vertical stack, centred in its row. The dot is NOT part of this grid
	   — it is absolutely positioned on the row's exact centre line (see below), so
	   the caption's vertical position and the dot's are decoupled and provably
	   symmetric between the two columns. */
	display: flex;
	flex-direction: column;
	gap: var(--sp-8);
	align-self: center;
}

/* Left milestones: caption in the left column, text flush to the band. */
.legacy-timeline__event[data-side="left"] .legacy-timeline__body {
	grid-column: 1;
	align-items: flex-end;
	text-align: right;
	padding-right: var(--sp-32);
}

/* Right milestones: caption in the right column, text flush to the band. */
.legacy-timeline__event[data-side="right"] .legacy-timeline__body {
	grid-column: 3;
	align-items: flex-start;
	text-align: left;
	padding-left: var(--sp-32);
}

.legacy-timeline__year {
	font-family: var(--ff-heading);
	font-weight: var(--fw-bold);
	font-size: var(--fs-5xl);   /* 60 */
	line-height: 1;
	color: var(--c-primary);
}

.legacy-timeline__desc {
	font-family: var(--ff-body);
	font-weight: var(--fw-regular);
	font-size: var(--fs-l2);    /* 18 */
	line-height: var(--lh-base);
	color: var(--c-text-body);
	max-width: 34ch;
}

/* A milestone with more than one point becomes a list (client, 9 Sep: 2024 and
   2025 "coming together like one para"). Same type and measure as __desc so a
   two-point year and a one-point year read as the same voice. */
.legacy-timeline__points {
	margin: 0;
	padding: 0;
	list-style: none;
	display: flex;
	flex-direction: column;
	gap: var(--sp-8);
	font-family: var(--ff-body);
	font-weight: var(--fw-regular);
	font-size: var(--fs-l2);    /* 18 */
	line-height: var(--lh-base);
	color: var(--c-text-body);
	max-width: 34ch;
}

/* The marker has to change sides with the caption. Left milestones are
   right-aligned, and a bullet hanging off the left of right-aligned text reads
   as a stray character rather than a list marker — so it is drawn by hand on
   the text's outer edge instead of by list-style, which cannot mirror.
   0.7em is the first line's optical centre: half of --lh-base (1.4). */
.legacy-timeline__points li {
	position: relative;
}

.legacy-timeline__points li::before {
	content: "";
	position: absolute;
	top: 0.7em;
	width: 5px;
	height: 5px;
	border-radius: 50%;
	background: var(--c-primary);
	transform: translateY(-50%);
}

.legacy-timeline__event[data-side="left"] .legacy-timeline__points li {
	padding-right: var(--sp-16);
}

.legacy-timeline__event[data-side="left"] .legacy-timeline__points li::before {
	right: 0;
}

.legacy-timeline__event[data-side="right"] .legacy-timeline__points li {
	padding-left: var(--sp-16);
}

.legacy-timeline__event[data-side="right"] .legacy-timeline__points li::before {
	left: 0;
}

/* Small print under a milestone — the asterisk the client asked for on 2026.
   It is 14 (--fs-s, the label rung) because it annotates the line above rather
   than being read as prose. The colour stays --c-text-body: --c-text-muted is
   the darker of the two despite the name, so it would emphasise the footnote
   rather than quiet it. Size alone does the work. */
.legacy-timeline__footnote {
	font-family: var(--ff-body);
	font-weight: var(--fw-regular);
	font-size: var(--fs-s);     /* 14 */
	line-height: var(--lh-base);
	color: var(--c-text-body);
	max-width: 34ch;
}

/* The dot sits on the wave. It is absolutely positioned against the event box
   (position: relative), so its centre is ALWAYS on the row's vertical centre —
   the same y the SVG wave draws its node at — independent of the caption height
   or which column it's in. Only the horizontal edge differs left vs right, so the
   two sides can never drift apart vertically again. */
.legacy-timeline__dot {
	position: absolute;
	top: 50%;
	width: var(--tl-dot);
	height: var(--tl-dot);
	border-radius: 50%;
	background: var(--c-primary);
	box-shadow: 0 0 0 6px var(--c-primary-10);
}

/* Left dot: centred on the band's left edge (= 50% − half the band width). */
.legacy-timeline__event[data-side="left"] .legacy-timeline__dot {
	left: calc(50% - var(--tl-band) / 2);
	transform: translate(-50%, -50%);
}

/* Right dot: centred on the band's right edge (= 50% + half the band width). */
.legacy-timeline__event[data-side="right"] .legacy-timeline__dot {
	left: calc(50% + var(--tl-band) / 2);
	transform: translate(-50%, -50%);
}

/* ---- Left-rail collapse (narrow viewports) ------------------------------- */
@media (max-width: 767px) {
	.legacy-timeline__track {
		display: block;
		max-width: 100%;
		position: relative;
	}

	/* Straight rail replaces the wave. */
	.legacy-timeline__wave { display: none; }

	/* Rail runs down the dot column (its centre at tl-dot/2 from the track's
	   left edge). The event boxes share that same left edge, so the dot — which
	   is positioned relative to its event — lands exactly on this line. */
	.legacy-timeline__track::before {
		content: "";
		position: absolute;
		top: 0;
		bottom: 0;
		left: calc(var(--tl-dot) / 2);
		width: 2px;
		background: var(--c-primary);
		opacity: 0.35;
	}

	/* The gutter that clears the rail lives on the EVENT (not the track) so the
	   event's left edge coincides with the track's — giving the dot and the rail
	   a shared origin. Caption content is padded past the dot column. */
	.legacy-timeline__event {
		display: block;
		position: relative;
		min-height: 0;
		padding: var(--sp-24) 0 var(--sp-24) calc(var(--tl-dot) + var(--sp-24));
	}

	/* Both sides become a plain left-aligned stack. */
	.legacy-timeline__event[data-side="left"] .legacy-timeline__body,
	.legacy-timeline__event[data-side="right"] .legacy-timeline__body {
		display: flex;
		flex-direction: column;
		align-items: flex-start;
		text-align: left;
		padding: 0;
	}

	/* Dot sits on the rail (left = tl-dot/2 from the event's left edge) and is
	   vertically centred on the year (year top = padding-top; year centre =
	   padding-top + half the year's font size). */
	.legacy-timeline__event[data-side="left"] .legacy-timeline__dot,
	.legacy-timeline__event[data-side="right"] .legacy-timeline__dot {
		top: calc(var(--sp-24) + var(--fs-5xl) / 2);
		left: calc(var(--tl-dot) / 2);
		transform: translate(-50%, -50%);
	}

	.legacy-timeline__desc,
	.legacy-timeline__points,
	.legacy-timeline__footnote { max-width: none; }

	/* Both sides are left-aligned here, so the mirrored marker has to come back
	   to the left for the left-hand milestones too — otherwise 2024 and 2025
	   would show their bullets floating off the right edge of the text. */
	.legacy-timeline__event[data-side="left"] .legacy-timeline__points li,
	.legacy-timeline__event[data-side="right"] .legacy-timeline__points li {
		padding-right: 0;
		padding-left: var(--sp-16);
	}

	.legacy-timeline__event[data-side="left"] .legacy-timeline__points li::before,
	.legacy-timeline__event[data-side="right"] .legacy-timeline__points li::before {
		right: auto;
		left: 0;
	}
}

/* ==========================================================================
   Brand grid — Our Brands logo links
   A full-bleed maroon-10 band holding a centred row of three logo cards, each
   one a link to that brand's own page (Figma 11197:3844).

   Figma drew this as an accordion — 11202:5892 was the expanded variant, where
   the open card became a white tab flanked by two inverse corner notches and a
   detail panel opened on the white beneath. The client asked on 2026-09-11 for
   the write-up to go and the logo to link straight through, so the tab states,
   the notches and every .brand-panel rule went with it; see the note in
   template-parts/sections/brand-grid.php.

   The cards mix the shared .brand-card component defined with the home brands
   section above, which already carries the 480×267 proportion, the #dfe1e7
   border, the no-underline rule and the lift/shadow/logo-zoom interaction that
   a link needs. Only what Figma differs on is restated here.
   .brand-grid__card and .brand-card are both single classes, so this is an
   equal-specificity override that works purely because this block comes later
   in the file — which is also why the whole section lives here rather than
   being spliced into the home block.
   ========================================================================== */
.brand-grid {
	padding-bottom: 100px; /* Figma: white gap between band and footer, off-scale */
}

/* The tint sits on an inner wrapper, not on the section, so the band stops where
   Figma stops it and the 100px underneath stays white. No top padding: the band
   is flush to the intro above, which supplies the gap with its own --section-pad. */
.brand-grid__band {
	padding: var(--sp-32) 120px; /* Figma list py-32; gutter matches .intro-text */
	background: var(--c-primary-10); /* #7204211a — Figma Primary/Opacity/10 */
}

.brand-grid__list {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	gap: var(--sp-32); /* Figma card gap */
	/* 3 × 480 + 2 × 32. At 1920 the band's 120px gutter leaves 1680, so this cap
	   centres the row to Figma's x208–1712 exactly; below 1744 the gutter takes
	   over and the cards line up with the intro copy above. */
	max-width: 1504px;
	margin: 0 auto;
	padding: 0;
	list-style: none;
}

/* flex-basis 0 keeps all three on one line and lets them shrink together — a
   480px basis would wrap 2-up as early as 1232 and leave a lone third card. */
.brand-grid__item {
	display: flex;
	flex: 1 1 0;
	min-width: 0;
	max-width: 480px; /* Figma card width — never larger than designed */
}

/* Figma's card on this band is white with 16px corners, where home's is
   maroon-06 with 12. Everything else — the 480×267 box, the border, the hover
   lift and the focus ring — comes from .brand-card unchanged. */
.brand-grid__card {
	margin: 0;
	padding: 0; /* Figma positions each logo absolutely, so the card has no inset */
	border-radius: var(--radius-xl); /* 16 — home's cards are 12; see report */
	background: var(--c-white);
}

/* Logo widths are percentages of the whole card, taken from Figma's own boxes
   (card 480 wide). The committed exports carry the same aspect ratios as those
   boxes, so width alone reproduces the designed height. Overrides the shared
   .brand-card__logo cap of 70%/70%, which would clip MTR. */
.brand-grid__logo {
	max-width: none;
	max-height: none;
	width: 60%; /* default for a brand with no per-brand rule below */
	height: auto;
}
.brand-grid__logo--mtr { width: 72.92%; }         /* Figma 350 / 480 */
.brand-grid__logo--eastern { width: 49.17%; }     /* Figma 236 / 480 */
.brand-grid__logo--rasoi-magic { width: 56.25%; } /* Figma 270 / 480 */

/* ---- Shared maroon button (Figma "Button" component, e.g. 11202:5947) --- */
/* Lives here because the Our Brands detail panel was the first section to need
   it. That panel is gone (see the block header above), but the brand detail
   pages reuse this verbatim for their outbound "Visit … Website" link, as does
   most of the site — do not move it on the assumption it is brand-grid's. */
.btn {
	display: inline-flex;
	align-items: center;
	gap: var(--sp-8);
	/* A transparent 1px border with the 1px taken back out of the padding, rather
	   than `border: 0`. Every filled button is the same size it always was — 8+8
	   of padding became 7+7 plus 2 of border, and the fill paints under it — but
	   --outline below now only has to set a border-COLOUR. Without this, an
	   outline button is 2px taller than the filled one it stands beside, and the
	   alternative (an inset box-shadow ring) disappears in a forced-colours mode. */
	padding: calc(var(--sp-8) - 1px) calc(var(--sp-12) - 1px);
	border: 1px solid transparent;
	border-radius: var(--radius-lg); /* 12 */
	font-family: var(--ff-body);
	font-weight: var(--fw-bold);
	font-size: var(--fs-m); /* 16 */
	line-height: var(--lh-base);
	cursor: pointer;
}

.btn,
.btn:hover,
.btn:focus,
.btn:focus-visible {
	text-decoration: none; /* section links never underline (theme rule) */
}

.btn--primary {
	background: var(--c-primary); /* #720421 */
	color: var(--c-white);
	transition: background-color 0.2s ease, gap 0.2s ease;
}

/* Darker fill + the same arrow nudge the other section CTAs use, never a rule. */
.btn--primary:hover,
.btn--primary:focus-visible {
	gap: var(--sp-12);
	background: var(--c-primary-600);
}

/* The quiet half of a pair — currently the disclaimer's "I do not confirm".
   Declining is an equal choice, not a lesser one, so it is the same button at the
   same size and weight; what separates it from the one that proceeds is fill
   versus outline, which reads in greyscale and in a forced-colours mode. Hover
   fills it in, so the two answers meet at the same colour rather than the
   declining one going somewhere the theme has no button for. */
.btn--outline {
	border-color: var(--c-primary);
	background: none;
	color: var(--c-primary);
	transition: background-color 0.2s ease, color 0.2s ease, gap 0.2s ease;
}

.btn--outline:hover,
.btn--outline:focus-visible {
	gap: var(--sp-12);
	background: var(--c-primary);
	color: var(--c-white);
}

/* --primary inverted, for a button sitting ON maroon: the header shop CTA (see
   "Shop CTA" in the header section above). Hover warms to the cream already used
   for the controls on the hero's maroon field rather than a cool grey, which
   would read as foreign next to the brand colour.

   The arrow nudges the same 4px as --primary, but by TRANSLATING the icon rather
   than growing `gap` 8 → 12. Measured: the gap shift widens the button 139.2 →
   143.2, and because .site-header__actions is pinned to the right of a flex row
   it has to grow leftward — which reflowed the whole menu 2px sideways on every
   hover. A transform is off the layout axis, so the motion is identical and
   nothing around it moves. --primary keeps the gap shift: those buttons sit in
   content flow where 4px of growth reflows nothing. */
.btn--shop {
	background: var(--c-white);
	color: var(--c-primary);
	transition: background-color 0.2s ease, color 0.2s ease;
}

.btn--shop .btn__icon {
	transition: transform 0.2s ease;
}

.btn--shop:hover,
.btn--shop:focus-visible {
	background: var(--c-cream);
	color: var(--c-primary-600);
}

.btn--shop:hover .btn__icon,
.btn--shop:focus-visible .btn__icon {
	transform: translateX(4px); /* stays inside the pill's 16px right padding */
}

.btn__icon {
	display: inline-flex;
	width: 20px; /* Figma icon box */
	height: 20px;
	flex: none;
}

.btn__icon svg {
	width: 100%;
	height: 100%;
}

/* ---- Responsive ------------------------------------------------------ */
/* Gutters track .intro-text (120 → 80 → 24) so the cards stay edge-aligned with
   the copy above. Figma has no frame below 1920, so the card counts per row are
   chosen on legibility: three cards only while each stays wide enough to read a
   logo in, then 2-up, then stacked. */
@media (max-width: 1280px) {
	.brand-grid { padding-bottom: var(--sp-80); }
	.brand-grid__band { padding-inline: 80px; }
}

/* 3-across would put each card at ~266px here, so wrap 2-up (~420px) and let
   justify-content centre the third on its own row. Basis 40% fits two per line
   and pushes the third over; they then grow to fill the line. */
@media (max-width: 1024px) {
	.brand-grid__list { gap: var(--sp-24); }
	.brand-grid__item { flex-basis: 40%; }
}

@media (max-width: 767px) {
	.brand-grid { padding-bottom: var(--sp-48); }
	.brand-grid__band { padding-inline: var(--sp-24); }
	.brand-grid__list { gap: var(--sp-16); }
	.brand-grid__item { flex-basis: 100%; max-width: 420px; } /* matches home's stack */
}

/* ==========================================================================
   Brand detail page — banner + copy + outbound link
   Figma content frames 11202:6269 (MTR), 11202:6782 (Eastern), 11202:7118
   (Rasoi Magic): one flex column on white, `gap: 60px`, `padding: 120px`,
   holding H1 → banner → copy → button. The H1 is the shared `page_heading`
   section stacked above, so this block owns items 2–4 and takes no top padding
   — page_heading's own bottom padding (--section-pad, 64) stands in for the
   design's 60px gap, the same 4px approximation every page_heading pairing in
   the theme already makes.

   Nothing is centred with `margin-inline: auto`: page_heading is left-aligned to
   the gutter, so the banner (1680) and the narrower copy column (1320) are too,
   and all three keep a common left edge past 1920 instead of drifting apart.
   ========================================================================== */
.brand-detail {
	display: flex;
	flex-direction: column;
	gap: 60px; /* Figma container gap — off-scale, no --sp-60 token */
	padding: 0 120px 120px;
	background: var(--c-white);
}

/* The tan gradient is on the frame rather than the image so both source kinds
   the design and live site use are served: a cut-out PNG composites onto this
   fill (as Figma draws it), while an opaque banner covers it. Stops are Figma's
   own — #f4e6d0 → #e4cda8 at 55.305%; the token is #e4cca8, one step off, and
   the token wins. Square corners, as designed. */
.brand-detail__banner {
	width: 100%;
	max-width: 1680px; /* Figma banner width at the 1920 frame */
	/* Designed 1680/450, but the band follows whatever shape the editor's artwork
	   actually is (the partial emits --bd-banner-ratio from the attachment), so a
	   taller banner is shown whole instead of having its feet cropped off. */
	aspect-ratio: var(--bd-banner-ratio, 3.7333);
	background: linear-gradient(
		90deg,
		var(--c-tan-100) 0%,
		var(--c-tan-200) 55.305%
	);
}

/* cover, not contain: an editor banner cropped to a different aspect fills the
   band rather than letterboxing tan bars around an opaque image. */
.brand-detail__banner-img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.brand-detail__body {
	display: flex;
	flex-direction: column;
	gap: var(--sp-32); /* Figma paragraph gap */
	max-width: 1320px; /* Figma — deliberately narrower than the banner above */
}

.brand-detail__para {
	margin: 0;
	font-family: var(--ff-body);
	font-weight: var(--fw-regular);
	font-size: var(--fs-xl);     /* 24 */
	line-height: var(--lh-base); /* 1.4 */
	color: var(--c-text-muted);
}

/* Maroon serif phrase opening a paragraph (MTR only). Set at the body's own 24px
   — intro_text's lead steps up to 32, and Figma does not do that here. */
.brand-detail__lead {
	font-family: var(--ff-heading);
	font-weight: var(--fw-bold);
	font-size: var(--fs-xl); /* 24 — same as the body it opens */
	color: var(--c-primary);
}

/* A flex item in a column stretches by default, which would smear the button
   across the full 1680. */
.brand-detail__cta {
	align-self: flex-start;
}

/* ---- Responsive ------------------------------------------------------ */
/* Gutters track page_heading and .intro-text (120 → 80 → 24) so the H1, banner
   and copy stay edge-aligned all the way down. */
@media (max-width: 1280px) {
	.brand-detail {
		gap: var(--sp-48);
		padding: 0 80px var(--sp-80);
	}
}

@media (max-width: 767px) {
	.brand-detail {
		gap: var(--sp-32);
		padding: 0 var(--sp-24) var(--sp-48);
	}
	/* The designed 3.73:1 strip is only ~88px tall inside a 375px phone, which
	   shrinks the packs past reading. Squaring up to 2.5:1 gives ~131px and costs
	   about a sixth of the width off each side — these collages carry margin
	   there, so the crop takes background rather than product. Only banners wider
	   than 5:2 are squared up: a taller one is already tall enough here and keeps
	   its own ratio rather than being cropped to a shape it never had. */
	.brand-detail__banner {
		aspect-ratio: min(var(--bd-banner-ratio, 3.7333), 2.5);
	}
	.brand-detail__para {
		font-size: var(--fs-l2); /* 18 — matches .intro-text__para on phones */
	}
}

/* ==========================================================================
   Text + media — Life at Orkla India, Figma 11195:2887 (bands 2–5).
   Maroon FK Roman H2 (48) over grey Messina body (20/1.6), with an optional
   media column of one or two photos. Four gaps inside the text column, so the
   spacing is done with sibling margins rather than a flex `gap` (same reasoning
   as .text-share__text): heading→body 16, body→body 16, body→sub-heading 20,
   sub-heading→body 8. Figma 11195:3396 y62→78, 11195:3416 y238→254,
   11195:3426 y62→82 and y0→42 respectively.

   Also Develop your skills with us, Figma 11195:3438 (bands 1–4) — same
   component, plus a maroon serif run-in opening the intro paragraph.

   Two measures, both straight from Figma: a text-only band is capped at 1320
   (11195:3396 / 11195:3426), while a band with photos spans the full 1680 inner
   width. That split is NOT fixed: Life at Orkla draws 828 + 60 + 792
   (11195:3416 / 11195:3417) and Develop your skills 810 + 60 + 810
   (11195:3459 / 11195:3788). The photo's own width arrives from PHP as
   --tm-media-w on the section, and both columns derive their basis from it, so
   the pair still sums to exactly 1680 on either page and neither needs a
   page-specific class.

   Inter-band gap is Figma's 100px everywhere — measured on 11195:2887: heading
   frame ends y206 and band 1 opens y306, then bands run 306→448, 548→980,
   1080→1415, 1515→1893. Every join is exactly 100.
   ========================================================================== */
.text-media {
	padding-block: var(--section-pad);
	padding-inline: 120px;
}

/* The 100px joins. Two --section-pads meeting would give 128 on a wide screen,
   which is the gap that was reported as too large: 28px over the design at every
   single join, four of them down one page, so the whole column reads loose.
   Topping up the preceding pad rather than setting a full one keeps the join at
   exactly 100px across the clamp's whole range instead of letting it drift
   between 96 and 128 with the viewport.

   An earlier note here rejected `.text-media + .text-media` as something that
   would "leak across every page on this template and break on reorder". It
   cannot: `text_media` is used only by the careers sub-pages (Career Paths,
   Life at Orkla India, Develop your skills with us, Employee Recognition), and
   the selector matches nothing but two adjacent bands. Career Paths' own frame
   (11238:10079) draws these joins at 80 rather than 100 — a disagreement inside
   the design, not a bug here; it is held at the house 100 pending the other
   frames. Reorder is the good case — drop another layout
   between two bands and the selector stops matching, so the full interior rhythm
   returns, which is the right answer for a join between different components. */
.page-heading + .text-media,
.text-media + .text-media {
	padding-block-start: calc(100px - var(--section-pad));
}

.text-media__inner {
	display: flex;
	align-items: flex-start; /* Figma: text and media both hang from the top. */
	gap: 60px;               /* 888 − 828 in 11195:3416, off the token scale. */
	max-width: 1680px;
	margin-inline: auto;
}

/* Media on the left: DOM stays text-first, visual order flips (lead-media idiom). */
.text-media--media-left .text-media__inner {
	flex-direction: row-reverse;
}

/* The two bases always sum to 1620 (1680 minus the 60 gap), so at full width
   nothing grows or shrinks and the Figma split is exact on both pages; below it
   the deficit is shared in proportion to the bases, which is what keeps the
   photos from collapsing before the copy does. Written as a calc against the
   media width rather than as two hard numbers so there is one source of truth —
   a basis pair that could drift apart is how a page ends up ~18px out. */
.text-media__text {
	display: flex;
	flex-direction: column;
	flex: 1 1 calc(1620px - var(--tm-media-w, 792px));
	min-width: 0;
}

/* No photos: the copy runs at the 1320 measure instead of the full 1680. */
.text-media--no-media .text-media__text {
	max-width: 1320px;
}

.text-media__heading {
	margin: 0 0 var(--sp-16);
	font-family: var(--ff-heading);
	font-weight: var(--fw-bold);
	font-size: var(--fs-4xl); /* fluid 32 → 48 */
	line-height: var(--lh-heading);
	letter-spacing: var(--ls-h3);
	color: var(--c-primary);
}

/* Dark Messina Bold label binding the paragraph under it — 8px away, which is
   what makes the pair read as one block against the 20px between blocks. */
.text-media__subheading {
	margin: 0 0 var(--sp-8);
	font-family: var(--ff-body);
	font-weight: var(--fw-bold);
	font-size: var(--fs-xl); /* 24 */
	line-height: var(--lh-base);
	color: var(--c-text);
}

.text-media__para {
	margin: 0;
	font-family: var(--ff-body);
	font-weight: var(--fw-regular);
	font-size: var(--fs-l); /* fluid 18 → 20 */
	line-height: 1.6;       /* Figma 32px line box at 20px, off the token scale */
	color: var(--c-text-muted);
	/* Same last-resort break as .text-share__para: inert for normal words, but it
	   keeps a long unbroken token (an address, a URL) from forcing the document
	   into horizontal scroll inside the 24px phone gutters. */
	overflow-wrap: break-word;
}

.text-media__para + .text-media__para {
	margin-top: var(--sp-16);
}

/* 32, over Figma's 20 (11195:3426: block 1 ends y220, block 2 starts y240). The
   client asked for the gap on 2026-09-18, and the measurement it overrides comes
   from a band whose sub-headings label consecutive paragraphs. Employee
   Recognition's two label NAMED BLOCKS instead — Galaxy of Stars carries a
   four-item list of its own, and Sales Superstar follows that list — so at 20px
   the name after the list read as though it belonged to it. That page is the only
   one with sub-headings, so nothing else moves. The scale now steps 8 inside a
   sub-heading/paragraph pair, 16 between paragraphs, 32 between blocks.

   Both selectors are needed, and a list is why: .text-media__text is a flex
   COLUMN, where margins do not collapse, so the gap belongs on one side of the
   join only — the sub-heading, where the idiom already keeps it. Without the
   second selector a name following a list sits flush against its last bullet,
   which is what was reported on the day the list shipped. */
.text-media__para + .text-media__subheading,
.text-media__bullets + .text-media__subheading {
	margin-top: var(--sp-32);
}

.text-media__bullets + .text-media__para {
	margin-top: var(--sp-16); /* as .text-media__para + .text-media__para */
}

/* Bulleted list closing a paragraph — Employee Recognition's four Galaxy of Stars
   awards (Ajit Joseph, 2026-09-18). The dot is .focus-card__bullet's idiom moved
   onto a light ground: list-style:none and an 8px round ::before at 0.6em, which
   holds the first line's baseline whatever the fluid body size does, where a
   ::marker would follow the font and drift. Maroon rather than that card's white,
   because this list sits on paper and not on a photograph.

   The label inherits its size for the reason .text-media__lead does — a separate
   tier would need a responsive rule of its own to ride the 20→18 stepdown — but it
   is the body sans in bold, not the serif of the lead: a lead runs on into its
   sentence and reads as part of it, while these labels are the NAMES of four
   awards and this list is the only place they appear. */
.text-media__bullets {
	margin: 20px 0 0; /* Figma's block gap: the list continues its own paragraph,
	                      so it stays tighter than the 32 that opens a new block. */
	padding: 0;
	list-style: none;
	display: flex;
	flex-direction: column;
	gap: var(--sp-12);
}

.text-media__bullet {
	position: relative;
	padding-left: var(--sp-24);
	font-family: var(--ff-body);
	font-weight: var(--fw-regular);
	font-size: var(--fs-l); /* fluid 18 → 20, the same as .text-media__para */
	line-height: 1.6;
	color: var(--c-text-muted);
	overflow-wrap: break-word;
}

.text-media__bullet::before {
	content: "";
	position: absolute;
	left: 0;
	top: 0.6em;
	width: 8px;
	height: 8px;
	border-radius: 999px;
	background-color: var(--c-primary);
}

.text-media__bullet-label {
	font-family: var(--ff-body);
	font-weight: var(--fw-bold);
	font-size: inherit;
	color: var(--c-text);
}

/* Maroon serif run-in opening a paragraph — Develop your skills 11195:3450 sets
   "At Orkla India," in FK Roman ahead of the Messina sentence it belongs to.
   font-size: inherit is the point: at the paragraph's own 20px it rides the
   20→18 phone stepdown with the text around it and needs no responsive rule,
   where intro_text's lead is a separate 32/40px tier that would have had to be
   maintained here too. Redeclaring the weight because <strong> only guarantees
   "bolder", which lands on the wrong FK Roman face. */
.text-media__lead {
	font-family: var(--ff-heading);
	font-weight: var(--fw-bold);
	font-size: inherit;
	color: var(--c-primary);
}

.text-media__media {
	flex: 0 1 var(--tm-media-w, 792px);
	max-width: var(--tm-media-w, 792px);
	min-width: 0;
}

.text-media__shot {
	margin: 0;
	overflow: hidden;
	border: 1px solid var(--c-gray-200);
	border-radius: var(--radius-lg); /* 12 */
}

.text-media__img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

/* One photo: fills the column and keeps its own aspect, so the layout does not
   assume the 792×335 of this particular band. */
.text-media--single .text-media__img {
	height: auto;
}

/* Two photos: a row of two equal cards with a gap between them. This was Figma's
   offset collage (11195:3415, a 792×432 box) — card 1 top-right, card 2
   bottom-left overlapping it, every offset a percentage of the box so it scaled
   with the column. The client asked the overlap out on 2026-09-18: "Keep a gap
   between both images. So that people can see the images." The overlap hid a
   third of the card behind it, which is what he is describing, and the phone rule
   below had already reached the same verdict at one width.

   flex:1 1 0 rather than the files' own 420px: two of those plus the gap want
   864px, past the 810px ceiling --tm-media-w is allowed, so each takes half of
   the 792px column (384px — a 9% downscale, still sharp) and follows it down
   every breakpoint without a second set of numbers.

   One shared aspect-ratio because the files are 420×292 and 420×263: at equal
   widths their natural heights differ by 29px, and two cards hanging from one top
   edge with a ragged bottom reads as a mistake rather than as a pair. The shorter
   photo gives up ~10% of its height to the crop — the trade photo_grid's 824:560
   and the brand-detail banner already make. */
.text-media--pair .text-media__media {
	display: flex;
	gap: var(--sp-24);
}

.text-media--pair .text-media__shot {
	flex: 1 1 0;
	min-width: 0;
	aspect-ratio: 420 / 292;
}

@media (max-width: 1280px) {
	.text-media {
		padding-inline: 80px;
	}
	.text-media__inner {
		gap: var(--sp-48);
	}
}

/* Tablet down: stack, photos below the copy (both sides), never upscaled past
   the photo's own width. The cap has to read --tm-media-w for the same reason
   the desktop bases do: hard-coded 792 would print Develop your skills' 810px
   photos 18px narrow on every tablet and phone, in a stacked column where the
   width is the only thing left distinguishing them. The fallback covers the
   two-photo collage and any band whose image has no intrinsic width. */
@media (max-width: 900px) {
	.text-media__inner,
	.text-media--media-left .text-media__inner {
		flex-direction: column;
		align-items: stretch;
		gap: var(--sp-32);
	}
	.text-media__text,
	.text-media__media {
		flex: 0 0 auto;
	}
	.text-media__media {
		width: 100%;
		max-width: var(--tm-media-w, 792px);
		margin-inline: auto;
	}
}

@media (max-width: 767px) {
	.text-media {
		padding-inline: var(--sp-24);
	}

	/* 48 (the preceding section's bottom pad) + 8 = 56px. Figma's 100 is a
	   1920-wide measurement, and held whole on a phone it puts a quarter of a
	   screen of blank white at every join — four times down Life at Orkla, where
	   the bands have already stacked to one narrow column and the gaps are the
	   tallest thing on the page. */
	.page-heading + .text-media,
	.text-media + .text-media {
		padding-block-start: var(--sp-8);
	}

	/* The pair goes one above the other. Side by side, each card is half of a
	   column that is already inside the 24px phone gutters — ~160px on a 375px
	   screen, smaller than a thumbnail. Full width in DOM order gives ~327px each
	   and keeps both photos legible; the row, like the collage it replaced, is a
	   desktop composition rather than information. Same trade as the brand-detail
	   banner squaring up on phones. The shared crop goes with it: stacked, there is
	   no common edge left to be ragged, so each photo keeps its own height. */
	.text-media--pair .text-media__media {
		flex-direction: column;
		gap: var(--sp-16);
	}
	.text-media--pair .text-media__shot {
		aspect-ratio: auto;
	}
	.text-media--pair .text-media__img {
		height: auto;
	}
}

/* ==========================================================================
   Photo grid — standalone photographs, one to three across, optional captions.
   Figma Life at Orkla India 11795:3756 (seven cards — three, three, then one),
   Develop your skills 11795:3732 and Employee Recognition 11795:3605 (one each).

   The card is a 824:560 crop in a 1px #dee1e7 hairline at 12px radius, then a
   16px gap, then a 24px Messina Medium caption in maroon (11795:3758 —
   Heading/H6/Medium, line-height 1.4, which is the 34px the caption frames
   measure). Three across at 538.67 with 32px gutters sums to 1680 exactly.

   THE CROP IS UNIFORM AND THE SOURCE FILES ARE NOT. Figma draws the seven gallery
   cards at two different heights — 366.08 and 343.86 — inside rows that are
   otherwise identical. That is a drafting slip, not a design: a row of cards
   whose images end at different heights has no reading order. aspect-ratio plus
   object-fit pins every card to the majority ratio and lets the photograph absorb
   the difference, the same call .news-card makes about its own image.

   A single photo does NOT stretch to the measure. Both one-card pages draw an
   800×560 at x0 inside the 1680 row with the right ~880px empty, and the same
   file stretches its own gallery to the full width, so the narrower single is
   intentional. The track is sized from --pg-photo-w, published by PHP from the
   photo's intrinsic width (see photo-grid.php), so it is the photo that decides —
   not a number duplicated here that would drift the first time a file changes.
   ========================================================================== */
.photo-grid {
	padding-block: var(--section-pad);
	padding-inline: 120px;
}

/* The 100px joins, topping up the preceding pad rather than adding a second full
   one — the reasoning is written out at .text-media above. Measured on all three
   pages: Life at Orkla 1648→1748, and the same 100 under the last text band on
   Develop your skills and Employee Recognition. The page_heading pairing is not
   drawn anywhere yet; it is here so a gallery placed directly under a title does
   not silently get the doubled pad the sibling layouts were fixed for. */
.page-heading + .photo-grid,
.text-media + .photo-grid {
	padding-block-start: calc(100px - var(--section-pad));
}

.photo-grid__inner {
	display: grid;
	gap: var(--sp-32); /* 32 in both axes — Figma gutter and row gap agree. */
	max-width: 1680px;
	margin-inline: auto;
}

/* minmax(0, …) on every track: without it a long unbroken caption word sets the
   track's min-content width and pushes the grid past its own max-width. */
/* min(), not minmax(): a fixed-max track keeps its growth limit when the
   container is narrower and simply overflows, so an 800px photo would run off the
   side of a 740px column. Clamping the track itself means the single-photo band
   needs no breakpoint of its own — it is 800 where there is room and fluid where
   there is not. */
.photo-grid--cols-1 .photo-grid__inner {
	grid-template-columns: min(100%, var(--pg-photo-w, 800px));
}

.photo-grid--cols-2 .photo-grid__inner {
	grid-template-columns: repeat(2, minmax(0, 1fr));
}

.photo-grid--cols-3 .photo-grid__inner {
	grid-template-columns: repeat(3, minmax(0, 1fr));
}
/* Four across (Nurturing People, 2026-10-09): one row at full measure gives
   ~276px cards at 1440. It steps to two across at 1024 and one at 560, below
   which a quarter-width photo stops reading. */
.photo-grid--cols-4 .photo-grid__inner {
	grid-template-columns: repeat(4, minmax(0, 1fr));
}
@media (max-width: 1024px) {
	.photo-grid--cols-4 .photo-grid__inner {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}
}
@media (max-width: 560px) {
	.photo-grid--cols-4 .photo-grid__inner {
		grid-template-columns: minmax(0, 1fr);
	}
}

/* Image first in a column flex, so every image in a row hangs from the top of its
   cell and the row still lines up when one caption wraps to two lines and its
   neighbour takes three. */
.photo-grid__card {
	display: flex;
	flex-direction: column;
	gap: var(--sp-16);
	margin: 0;
}

.photo-grid__img {
	display: block;
	width: 100%;
	height: auto;
	aspect-ratio: var(--pg-photo-ratio, 824 / 560); /* set only for a wide single photo, see photo-grid.php */
	object-fit: cover;
	border: 1px solid var(--c-gray-200); /* #dee1e7 */
	border-radius: var(--radius-lg);     /* 12 */
}

/* Figma hangs the single-card caption off a 1320-wide text frame while its photo
   is 800, which is just the layout's default text container showing through — the
   caption itself is one short line either way. Kept inside the figure, where a
   caption belongs, so the 3-up and 1-up cases are the same component. */
.photo-grid__caption {
	font-family: var(--ff-body);
	font-weight: var(--fw-medium);
	font-size: var(--fs-xl); /* 24 */
	line-height: var(--lh-base);
	color: var(--c-primary);
}

/* SMALLER BAND — the `size` field's "compact" (client, 2026-10-09: "keeping the
   photos slightly smaller... and not so big"). The whole band is capped at 960px and
   held against the left edge, where the intro and body text start, instead of
   filling the 1200+ measure. Only max-width changes, so the column steps below
   (3 → 2 at 1280, → 1 at 900) apply unchanged, and a wide single photo's track
   (min(100%, --pg-photo-w)) simply resolves to the 960 cap. */
.photo-grid--compact .photo-grid__inner {
	max-width: 960px;
	margin-inline: 0;
}

/* Same 960 cap, centred in the page instead of held left (the CSR drone panorama,
   2026-10-09, under a full-width grid). */
.photo-grid--centered .photo-grid__inner {
	margin-inline: auto;
}

/* Two bands in a row (CSR: the panorama, then the 3-up grid) read as one gallery:
   the gap between them is the grid's own 32px row gap, not two section pads. */
.photo-grid + .photo-grid {
	padding-block-start: 0;
	margin-block-start: calc(var(--sp-32) - var(--section-pad));
}

/* Three across stops paying at 1280: the row would hold 352px cards, and the
   caption does not step down with the viewport (--fs-xl is flat by design, same
   as .text-media__subheading), so a 24px caption in a 352px track runs to six
   lines under a 239px photo — more caption than photograph. Two across at this
   width gives 544px cards, which is within a rounding error of the 538.67 the
   design draws them at. */
@media (max-width: 1280px) {
	.photo-grid {
		padding-inline: 80px;
	}
	.photo-grid--cols-3 .photo-grid__inner {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}
}

/* Tablet down: one across, matching .text-media stacking at the same width. Two
   across here would be 288px cards by the bottom of the range, which is below the
   point where a group photograph reads at all. */
@media (max-width: 900px) {
	.photo-grid--cols-3 .photo-grid__inner,
	.photo-grid--cols-2 .photo-grid__inner {
		grid-template-columns: minmax(0, 1fr);
	}
}

@media (max-width: 767px) {
	.photo-grid {
		padding-inline: var(--sp-24);
	}

	/* 48 (the preceding section's bottom pad) + 8 = 56px, the same collapse the
	   text bands take — Figma's 100 is a 1920-wide measurement and holding it
	   whole on a phone puts a quarter-screen of white above the gallery. */
	.page-heading + .photo-grid,
	.text-media + .photo-grid {
		padding-block-start: var(--sp-8);
	}
}

/* ==========================================================================
   News card — the unit shared by Latest News and All News.
   Figma card 11363:7974 (Latest, no badge) and 11363:8029 (All News, badged).
   A 538×480 block on a 5%-grey fill inside a 1px #dee1e7 hairline, 12px radius:
   cover image on top, then a 24px gap, then the 24px-inset title + "View PDF".

   THE HEIGHT IS FIXED AND THE IMAGE ABSORBS THE DIFFERENCE. Every card in Figma
   is exactly 480 tall while its image is 292, 326 or 360 — one line of title, two
   or three. So the image is the flexible child (flex: 1) and the text block is its
   natural height, which is why row bottoms line up without anything being
   clipped or stretched. Two departures from Figma, both deliberate:
     · min-height, not height. A title longer than the three lines Figma happens to
       show would otherwise overflow a hard 480. This way the row grows instead,
       and a min-height on the media stops a runaway headline erasing the photo.
     · Figma gives the image frame a border on all four sides, which lands directly
       on the card's own border and prints as a doubled line down the sides. Only
       the bottom hairline carries information, so only that one is kept — the same
       call as .value-cards__media.
   ========================================================================== */
/* NO min-height (removed 27 Aug 2026). It used to be 480px — Figma's card height,
   and exactly 360 image + 24 gap + 72 one-line body + 24 padding — with the media
   as the flexible child soaking up the remainder. That is what made the photos
   uneven: the grid stretches every card in a row to the tallest, the body's height
   varies with the headline, and the image was whatever was left over. Height is now
   set by the image's ratio plus the body, so it is composed rather than divided. */
.news-card {
	position: relative;                   /* containing block for the stretched CTA */
	display: flex;
	flex-direction: column;
	gap: var(--sp-24);
	padding-block-end: var(--sp-24);
	background: var(--c-gray-05);         /* rgba(146,156,178,0.05) */
	border: 1px solid var(--c-gray-200);  /* #dee1e7 */
	border-radius: var(--radius-lg);      /* 12 */
	overflow: hidden;                     /* clips image + badge to the radius */
}

/* Ratio-locked, NOT flexible (27 Aug 2026, client instruction: "images have same
   height, currently image height is also odd even"). Cards in a row share a column
   width, so one ratio makes every photo the same height whatever its headline does —
   which is the only way to guarantee it, since a flexed media can always be squeezed
   by a longer title.

   538:360 is the widest card in the design and the `orkla-news-card` crop already
   registered for it (1076×720 at 2x), so nothing is resampled. This DOES override
   Figma, which draws three image heights — 360, 326, 292 — for one-, two- and
   three-line titles inside a card of constant height. That was the trade the client
   has now asked us to make the other way round: uniform photos, and the card grows.

   Still rendered with no image: an empty box with a definite width still takes its
   height from the ratio, so the tint and the hairline read as an empty panel exactly
   as before. That is what the static fallback in news-card.php relies on. */
.news-card__media {
	position: relative;
	flex: 0 0 auto;
	min-height: 0;
	aspect-ratio: 538 / 360;
	background: var(--c-gray-10);
	border-block-end: 1px solid var(--c-gray-200);
}

/* ABSOLUTE, so the photograph cannot vote on the height of the box that holds it.
   `height: 100%` alone was not enough: a percentage height resolves against a
   specified height, and an aspect-ratio is not one, so the image fell back to its
   intrinsic ratio — and a flex item's automatic minimum size then grew the media to
   fit it. The ratio was being honoured only by the images that already agreed with
   it. A 370×276 source (att. 164, "restructures its board") made its own card 401px
   tall while its neighbours sat at 360; min-height: 0 above closes the same door
   from the other side.

   Out of flow, so it contributes no content height at all, and inset: 0 sizes it
   from the ratio-sized box rather than from a percentage. The badge is also absolute
   and later in the DOM, so it still paints on top with no z-index. */
.news-card__image {
	position: absolute;
	inset: 0;
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

/* Category pill, top-left of the image (Figma 11363:8031). Notched: the top-left
   corner follows the card's radius, the bottom-right rounds away from it, the
   other two stay square. The card's overflow: hidden trims it flush to the
   border, so no negative offset is needed. */
.news-card__badge {
	position: absolute;
	top: 0;
	left: 0;
	z-index: 1;                           /* above the CTA's stretched overlay */
	padding: var(--sp-8) var(--sp-12);
	background: var(--c-primary-600);     /* #5a031a */
	border-radius: var(--radius-lg) 0 var(--radius-lg) 0;
	font-family: var(--ff-body);
	font-weight: var(--fw-bold);
	font-size: var(--fs-s);               /* 14 */
	line-height: var(--lh-base);
	color: var(--c-white);
}

.news-card__body {
	display: flex;
	flex-direction: column;
	gap: var(--sp-16);
	padding-inline: var(--sp-24);
}

/* Messina 24/1.4 at 600, not the serif: news headlines are body copy in this
   design, unlike the section heading above them.

   THREE LINES ARE RESERVED WHETHER OR NOT THEY ARE USED (client, 27 Aug 2026: "make
   3 lines default height as some have 2 line some have 3 looks odd"). Without it a
   two-line headline pulls its "View PDF" up by a whole line and the row of CTAs has
   no baseline.

   min-height, so it is a floor and not a cap: a four-line headline still grows
   rather than losing words. Truncation would drop copy from a press-release title,
   which is a content decision and not a spacing one.

   3em × the line-height, not a pixel value: `em` here is the title's own font-size,
   which is a clamp() that steps 24 → 20 across the scale, so the reserve tracks it.
   A literal was tried on this element once before and had to be removed (see the
   ≤767 note); this cannot go stale the same way. */
.news-card__title {
	margin: 0;
	min-height: calc(3em * var(--lh-base));
	font-family: var(--ff-body);
	font-weight: var(--fw-semibold);
	font-size: var(--fs-xl);              /* 24 */
	line-height: var(--lh-base);
	color: var(--c-text);                 /* #24272c */
}

/* Publish date, added 10 Sep 2026 ("For each release, we need to put a date in
   the under the heading. This will help people to search."). Not in Figma, so the
   values come from the nearest thing that is: the same 14px body-grey the badge
   and the breadcrumbs use for supporting text, so it reads as a label on the
   headline rather than a second line of it.

   Pulled up by 8px out of the body's 16px gap. Left alone the date would sit
   equidistant between the headline and the CTA and belong to neither; at 8px it
   is attached to the heading above it, which is where the client put it, and the
   CTA keeps the full 16 below. Nothing else in the card moves.

   The title reserves three lines whether or not it uses them (see above), so this
   line lands at the same height on every card in a row — the date column stays
   level even where one headline wraps and its neighbour does not. */
.news-card__date {
	display: block;
	margin-block-start: calc(var(--sp-8) - var(--sp-16));
	font-family: var(--ff-body);
	font-weight: var(--fw-regular);
	font-size: var(--fs-s);               /* 14 */
	line-height: var(--lh-base);
	color: var(--c-text-body);            /* #6f6f6f */
}

/* Same object as .link-cards__cta — 16px bold maroon with a 20px arrow that
   nudges on hover, no underline (the site-wide section-link rule). */
.news-card__cta {
	display: inline-flex;
	align-items: center;
	align-self: flex-start;
	gap: var(--sp-8);
	font-family: var(--ff-body);
	font-weight: var(--fw-bold);
	font-size: var(--fs-m);               /* 16 */
	line-height: var(--lh-base);
	color: var(--c-primary);              /* #720421 */
	text-decoration: none;
	transition: gap 0.2s ease;
}

/* THE WHOLE CARD IS THE LINK (10 Sep 2026: "Clicking on the image should open up
   the external website on another page"). One transparent overlay stretched from
   the existing CTA, not a second anchor around the image: the card stays one tab
   stop with one accessible name, and target/rel are already on this element, so
   the image inherits the new-tab behaviour for free rather than repeating it.

   ::after on the anchor rather than on the card, because the anchor is what has
   to be clicked; inset: 0 resolves against .news-card, which is why that rule now
   sets position: relative.

   TWO CONSEQUENCES. Text inside the card can no longer be selected with the mouse
   — the overlay swallows the drag — which is the accepted cost of this pattern
   and the reason it is not used on cards whose body copy someone might copy. And
   anything that must stay clickable has to be lifted above the overlay; nothing
   in this card is, but the badge gets a z-index anyway so a future link inside it
   fails visibly here rather than mysteriously at the far end of a QA pass. */
.news-card__cta::after {
	content: "";
	position: absolute;
	inset: 0;
}

/* Hover anywhere on the card now reaches the CTA through the overlay, so the
   arrow nudge doubles as the card's own hover state. */
.news-card__cta:hover,
.news-card__cta:focus-visible {
	gap: var(--sp-12);
}

.news-card__cta-icon {
	display: inline-flex;
	width: 20px;
	height: 20px;
	flex: none;
}

.news-card__cta-icon svg {
	width: 100%;
	height: 100%;
}

/* ==========================================================================
   News — Latest News row (Figma 11363:7971)
   Serif maroon 40px heading, 32px down to a row of three cards. The section
   carries the hairline that separates it from All News below (Figma 11363:7989):
   it lives on the inner wrapper so it spans the 1680 container rather than
   bleeding to the window edge, and on THIS section rather than the archive's top
   so it disappears together with the row when a filter is active.
   ========================================================================== */
/* .news-list is the stacked News page of 2026-09-11 — Press Releases in full,
   then Media Coverage below it, in place of the tabbed archive. It is the same
   thing geometrically as Latest News, a heading over a grid with a hairline
   underneath, so it shares these rules rather than restating them. The one
   difference is at the bottom of the page: see the :last-of-type rule below. */
.news-latest,
.news-list {
	padding: var(--section-pad) 120px 0;
}

/* The News landing page: title then straight into the first grid, 128px apart. */
@media (min-width: 901px) {
	.page-heading + .news-latest,
	.page-heading + .news-list {
		padding-block-start: 0;
	}
}

.news-latest__inner,
.news-list__inner {
	display: flex;
	flex-direction: column;
	gap: var(--sp-32);
	max-width: 1680px;
	margin-inline: auto;
	padding-block-end: var(--section-pad);
	border-block-end: 1px solid var(--c-gray-200);
}

/* The hairline separates one list from the next, so the last list has nothing to
   separate itself from and the page would otherwise end on a rule. */
.news-list:last-of-type .news-list__inner {
	border-block-end: 0;
}

/* ---- "Load more" (2026-09-11) -------------------------------------------- */
/* Centred as a flex item of __inner, which is already a 32-gap column, so the
   button needs no wrapper element and no margin of its own. */
.news-list__more {
	align-self: center;
	/* Base .btn is 8/12, i.e. about a 38px box. This is the one real control on
	   the page and it is reached on a phone, so it gets the 44px tap floor the
	   theme holds for the filter pills: 12 + 12 + a 22px line box = 46. */
	padding: calc(var(--sp-12) - 1px) calc(var(--sp-24) - 1px);
}

/* BOTH OF THESE RESTATE THE UA'S [hidden] AND BOTH ARE LOAD-BEARING — an author
   rule setting `display` beats [hidden] { display: none } whatever the
   specificity, and .btn sets inline-flex while .news-card sets flex. Without
   them the button prints on a page that has no use for it and, worse, every
   "hidden" card stays on screen, so the whole load-more does nothing at all
   while looking correctly wired. Same trap as .results-table__filters[hidden]
   and .doc-cards__item[hidden] further down. */
.news-list__more[hidden] {
	display: none;
}

.news-list .news-card[hidden] {
	display: none;
}

/* ---- Slider (2026-09-11) ------------------------------------------------- */
/* The other way to shorten the list, and the default one: the grid becomes a
   single row you scroll sideways, after tataconsumer.com/newsroom, which the
   client named. Every rule here hangs off .is-slider, which initNewsSlider()
   adds — NOT off the data-news-slider attribute the template prints. With
   JavaScript off nothing below applies and the section is the plain stacked
   grid with all 17 cards, rather than a hidden-scrollbar strip a mouse user
   cannot move. The class is also dropped again when the cards already fit, so
   a short list is never a slider.

   Native overflow + scroll-snap rather than slick's transforms, which is what
   the IR tab strips do (see .ir-header__tabs). Swipe, two-finger trackpad and
   the arrow keys then need no code at all. The price is that it cannot loop —
   the client chose to stop at both ends, which is what makes this possible. */
.news-list.is-slider .news-archive__grid {
	/* Mandatory, not decorative: the explicit repeat(3, …) from the base rule
	   keeps placing the first three cards in its own columns, and
	   grid-auto-flow would then only reach the fourth onwards. */
	grid-template-columns: none;
	grid-auto-flow: column;
	/* 3 cards + 2 gaps = exactly 100%, so a card edge never half-shows and the
	   last column lands flush with the container. */
	grid-auto-columns: calc((100% - 2 * var(--sp-32)) / 3);
	overflow-x: auto;
	overflow-y: hidden;
	scroll-snap-type: x mandatory;
	/* No visible scrollbar: the arrows and the bar strip below are what say
	   there is more, and a native bar under each of two lists would read as a
	   rule. Same treatment, same reason, as the IR strips. */
	scrollbar-width: none;
	-webkit-overflow-scrolling: touch;
	/* A trackpad flick past the last card would otherwise walk the browser back
	   a page, which on this list is a very easy accident to have. */
	overscroll-behavior-x: contain;
	/* overflow clips, and the global focus ring is 2px at a 2px offset, so
	   without this a card focused by keyboard would have its ring sliced off
	   top and bottom. The negative margin cancels the padding exactly — the
	   outer box, the 32px column gaps and the card edges all stay where they
	   were, and because the content box is then the full container width the
	   calc above still resolves to a true third. */
	padding: 4px;
	margin: -4px;
	/* And this is the bill for that padding. Snapping measures from the padding
	   box, so the first card lines up with the snapport only once the 4px has
	   been scrolled away — mandatory snapping duly parked the track at
	   scrollLeft 4 and the prev arrow, which tests for 0, never read as bounded.
	   Pulling the snapport in by the same 4px puts the first snap position back
	   at 0, where an untouched scroller belongs. */
	scroll-padding-inline: 4px;
}

.news-list.is-slider .news-archive__grid::-webkit-scrollbar {
	display: none;
}

.news-list.is-slider .news-card {
	scroll-snap-align: start;
}

/* Bars left, arrows right. [hidden] restated for the reason given above — this
   sets `display`, so the UA rule would lose and the controls would print on a
   list that does not scroll. */
.news-slider__controls {
	display: flex;
	align-items: center;
	gap: var(--sp-24);
}

.news-slider__controls[hidden] {
	display: none;
}

.news-slider__bars {
	display: flex;
	flex: 1 1 auto;
	min-width: 0;
	gap: var(--sp-8);
}

/* Tata's geometry — one 33×4px segment per card, across the full track width —
   in our tokens. flex 1 1 0 with a max means seventeen of them share the row
   evenly and eleven do not stretch into a different-looking strip. Marked
   aria-hidden in the template: an indicator, not a control. */
.news-slider__bar {
	flex: 1 1 0;
	max-width: 33px;
	height: 4px;
	border-radius: 2px;
	background: var(--c-primary-20);
	transition: background-color 0.2s ease;
}

/* The whole visible range lights, not one segment — see the note in
   initNewsSlider(), where Tata's single dot leaves its last two unreachable. */
.news-slider__bar.is-active {
	background: var(--c-primary);
}

.news-slider__arrows {
	display: flex;
	flex: 0 0 auto;
	gap: var(--sp-16);
}

.news-latest__heading,
.news-list__heading {
	margin: 0;
	font-family: var(--ff-heading);
	font-weight: var(--fw-bold);
	font-size: var(--fs-3xl);   /* 40 */
	line-height: var(--lh-base);
	color: var(--c-primary);
}

/* 3 × 538 + 2 × 32 = 1678, i.e. the container. Grid rather than flex so the five
   rows of the archive below share one declaration and every row self-equalises. */
.news-latest__grid,
.news-archive__grid {
	display: grid;
	grid-template-columns: repeat(3, minmax(0, 1fr));
	gap: var(--sp-32);
}

/* ==========================================================================
   News — the date list under the three featured cards (client, 2026-09-15)
   ==========================================================================
   Only rendered by the `featured` display in news-list.php, after orkla.com/media,
   which the client named: "We will keep only three images on top.. and then the rest
   of it can be just like the headline and date.. and when we click the pdf opens up."

   A LIST, NOT A SHORTER CARD. Theirs is a stack of text rows and the point is the
   contrast with the three pictures above — so nothing here borrows the card's panel,
   radius or shadow. What it does borrow is the card's destination: the row's href is
   the same one orkla_news_card_args() gave the card, so a headline and a picture can
   never lead different places.

   Rows are separated by a hairline rather than boxed, and the LAST row keeps its
   bottom border so the list reads as closed against whatever follows it; a
   heading directly below an unclosed list looks like part of it.

   THE DATE COLUMN IS A FIXED 140px, and that is the whole point of it. It was `auto`
   for one build, on the reasoning that the track should size to its own content. But
   every row is its OWN grid — the <a> is the grid container, not the <ul> — so `auto`
   resolved per row: "May 1, 2026" gave a narrow track and "February 12, 2025" a wide
   one, and the headlines started at a different x on almost every line. The client saw
   it immediately ("date and title of news is odd even"). A shared track would need the
   grid on the <ul> with `display: contents` on the rows, which costs the row its
   background, padding and hit area — so a fixed width it is. 140px clears the longest
   date this renders, "September 15, 2026", at --fs-s with room to spare; a longer
   locale would push its own row wider, which is the one case worth knowing about.

   The arrow is the third track so a two-line headline does not push it out of line —
   align-items centres all three against the row.

   The whole row is one <a>, so the hit area is the row and not just the words. */
.news-rows {
	/* No top margin: __inner is a flex column with its own 32 gap. */
	margin: 0;
	padding: 0;
	list-style: none;
	border-top: 1px solid var(--c-gray-200);
}

.news-rows__item {
	border-bottom: 1px solid var(--c-gray-200);
}

.news-rows__link {
	display: grid;
	grid-template-columns: 140px 1fr auto;
	gap: var(--sp-32);
	align-items: center;
	padding: var(--sp-24) var(--sp-8);
	text-decoration: none;
	transition: background-color 0.2s ease;
}

.news-rows__link:hover,
.news-rows__link:focus-visible {
	background-color: var(--c-primary-05);
}

.news-rows__date {
	font-family: var(--ff-body);
	font-weight: var(--fw-regular);
	font-size: var(--fs-s);
	line-height: 1.4;
	color: var(--c-text-body);
	/* Tabular so a column of dates does not shuffle sideways row to row. */
	font-variant-numeric: tabular-nums;
	white-space: nowrap;
}

.news-rows__title {
	font-family: var(--ff-heading);
	font-weight: var(--fw-bold);
	font-size: var(--fs-xl);
	line-height: var(--lh-base);
	color: var(--c-text);
}

.news-rows__link:hover .news-rows__title,
.news-rows__link:focus-visible .news-rows__title {
	color: var(--c-primary);
}

.news-rows__icon {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 24px;
	height: 24px;
	color: var(--c-primary);
	/* Sits still until the row is hovered, so a long list is not a field of arrows
	   all pointing at the reader. */
	opacity: 0;
	transform: translateX(-4px);
	transition: opacity 0.2s ease, transform 0.2s ease;
}

.news-rows__icon svg {
	width: 20px;
	height: 20px;
}

.news-rows__link:hover .news-rows__icon,
.news-rows__link:focus-visible .news-rows__icon {
	opacity: 1;
	transform: translateX(0);
}

/* The arrow is decorative and hidden from assistive tech, so revealing it on hover
   alone would leave a keyboard visitor with no hover-equivalent cue; :focus-visible
   above covers that. Motion-averse visitors get the state without the slide. */
@media (prefers-reduced-motion: reduce) {
	.news-rows__link,
	.news-rows__icon {
		transition: none;
	}

	.news-rows__icon {
		transform: none;
	}
}

/* Centred as a flex item of __inner, exactly like .news-list__more above, so it needs
   no wrapper and no margin of its own. Same 44px tap floor: this is a real control
   and it is reached on a phone. */
.news-rows__more {
	align-self: center;
	padding: calc(var(--sp-12) - 1px) calc(var(--sp-24) - 1px);
}

/* [hidden] is how the button ships and how it leaves on the last click, and .btn sets
   display: inline-flex, which would otherwise win over the UA's [hidden] rule. */
.news-rows__more[hidden] {
	display: none;
}

@media (max-width: 767px) {

	/* Date over headline, and the arrow leaves the row rather than eating a third of
	   a 390px screen: on a phone the whole row is the tap target anyway. */
	.news-rows__link {
		/* One column, so the fixed date track goes with the arrow: stacked, the date
		   sits on its own line and has nothing to align with. */
		grid-template-columns: 1fr;
		gap: var(--sp-8);
		padding-inline: 0;
	}

	.news-rows__icon {
		display: none;
	}
}
/* ==========================================================================
   News — All News: filter tabs, card grid, pager (Figma 11363:7990)
   Pills butt straight up against each other with no gutter — each is padded
   16/32, so the text spacing is the padding — and sit on a 30%-grey hairline.
   The active one is a filled 8px-radius Primary/400 pill with white text; the
   rest are plain black text.
   ========================================================================== */
.news-archive {
	padding-block: var(--section-pad);
	padding-inline: 120px;
}

.news-archive__inner {
	max-width: 1680px;
	margin-inline: auto;
}

/* Hidden in the design, so this only applies when an editor supplies one. */
.news-archive__heading {
	margin: 0 0 var(--sp-32);
	font-family: var(--ff-heading);
	font-weight: var(--fw-bold);
	font-size: var(--fs-3xl);   /* 40 */
	line-height: var(--lh-base);
	color: var(--c-primary);
}

.news-tabs {
	margin-block-end: var(--sp-48);
	border-block-end: 1px solid var(--c-gray-30);
}

/* Centred as of 2026-09-10: "Right under the banner - in the middle - let it say
   Press Releases (Tab 1) & Media Coverage (Tab 2)". Both rows, not just the type
   row — the category pills sit directly beneath and the two read as one control,
   so leaving the lower row hard left would look like a mistake rather than a
   hierarchy. The pills butt together with no gutter (see the note at the bottom
   of this file), so centring moves the block, not the spacing inside it. */
.news-tabs__list {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	margin: 0;
	padding: 0;
	list-style: none;
}

.news-tabs__link {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	padding: var(--sp-16) var(--sp-32);
	border-radius: var(--radius-md);   /* 8 */
	font-family: var(--ff-body);
	font-weight: var(--fw-semibold);
	font-size: var(--fs-l);            /* 20 */
	line-height: var(--lh-base);
	color: var(--c-black);
	text-decoration: none;
	white-space: nowrap;
	transition: background-color 0.2s ease, color 0.2s ease;
}

.news-tabs__link:hover,
.news-tabs__link:focus-visible {
	color: var(--c-primary);
}

.news-tabs__link.is-active {
	background: var(--c-primary-400);   /* #8d233f */
	color: var(--c-white);
}

/* ---- The type row (Press Releases / Media Coverage) ---------------------
   Added 2026-09-08 for the client's corrections item 18: "Right on the top we
   have to have two tabs".

   THERE IS NO FIGMA FRAME FOR THIS ROW, so it deliberately invents no new
   visual language. It is the same pill in the same family, separated from the
   category row beneath it by exactly two existing tokens: one step up the type
   scale, and the darker of the two maroons for the active fill (--c-primary
   against the category row's --c-primary-400). That is enough to say which
   control nests inside which, and it is all guesswork-free — a bespoke
   treatment here would be a design decision made by the person writing the
   CSS, which is the wrong person to make it.

   No hairline of its own: the two rows are one control, and stacking two rules
   4px of margin apart reads as a table header. The category row's hairline
   closes the group. */
.news-tabs--type {
	margin-block-end: var(--sp-16);
	border-block-end: 0;
}

/* …unless this row is on its own, which happens when the type on screen has
   posts but none of them are categorised (orkla_news_terms() only lists terms
   that have posts, so the lower row is omitted entirely). Then the group is
   just this row, and it takes the group's closing hairline and full gap back.

   DEPENDS ON THE TWO PILL ROWS BEING THE ONLY <nav> CHILDREN of
   .news-archive__inner — :last-of-type counts by element name. The pager is
   also a <nav>, but it lives inside .news-archive__results, one level deeper,
   so it does not count here. Add a third nav as a sibling and this rule stops
   firing silently; put it inside a wrapper instead. */
.news-tabs--type:last-of-type {
	margin-block-end: var(--sp-48);
	border-block-end: 1px solid var(--c-gray-30);
}

.news-tabs--type .news-tabs__link {
	font-size: var(--fs-xl);   /* 24, one rung over the category row's 20 */
}

.news-tabs--type .news-tabs__link.is-active {
	background: var(--c-primary);
}

.news-archive__empty {
	margin: 0;
	font-family: var(--ff-body);
	font-size: var(--fs-l);
	line-height: 1.6;
	color: var(--c-text-muted);
}

/* ---- Results (the AJAX swap target) -------------------------------------
   Only this node is replaced when a tab or a pager link is clicked, which is
   what keeps Latest News on screen — see inc/ajax-news.php. It is a bare
   wrapper by design: no padding, no background, nothing that would shift the
   grid relative to the server-rendered layout.

   No spinner. The response is one query returning fifteen cards and lands fast
   enough that a spinner would only flash; dimming says "working" without
   introducing a thing that appears and disappears. pointer-events guards
   against a second click landing on cards that are about to be replaced.
   ------------------------------------------------------------------------- */
.news-archive__results[aria-busy='true'] {
	opacity: 0.55;
	pointer-events: none;
}

.news-archive__results {
	transition: opacity 120ms ease-out;
}

/* Programmatic focus target only (tabindex="-1", focused after a pager click so
   keyboard users keep their place). It is never in the tab order, so there is no
   keyboard focus to indicate and a ring here would read as a stray box. */
.news-archive__results:focus {
	outline: none;
}

@media (prefers-reduced-motion: reduce) {
	.news-archive__results {
		transition: none;
	}
}

/* ---- Pager --------------------------------------------------------------
   Not in Figma: the design shows all fifteen items at once, and paging is a
   build decision (see template-parts/sections/news-archive.php). So it borrows
   the tabs' own language — 8px radius, Primary/400 for the page you are on — at
   16px instead of 20px, which reads as a control rather than a second filter
   row. Selectors target core's .page-numbers markup, which already emits the
   current page as a <span> and not a link.
   ------------------------------------------------------------------------- */
.news-pager {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: center;
	gap: var(--sp-8);
	margin-block-start: var(--sp-48);
}

.news-pager .page-numbers {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 48px;
	padding: var(--sp-12) var(--sp-16);
	border-radius: var(--radius-md);
	font-family: var(--ff-body);
	font-weight: var(--fw-semibold);
	font-size: var(--fs-m);   /* 16 */
	line-height: var(--lh-base);
	color: var(--c-black);
	text-decoration: none;
	transition: background-color 0.2s ease, color 0.2s ease;
}

.news-pager a.page-numbers:hover,
.news-pager a.page-numbers:focus-visible {
	background: var(--c-gray-10);
	color: var(--c-primary);
}

.news-pager .page-numbers.current {
	background: var(--c-primary-400);
	color: var(--c-white);
}

/* Core's ellipsis is inert text, so it drops the pill box entirely. */
.news-pager .page-numbers.dots {
	min-width: 0;
	padding-inline: var(--sp-8);
	color: var(--c-gray-600);
}

/* ---- News — responsive --------------------------------------------------
   Gutter ladder 120 → 80 → 24, the page-level one (page-hero, page-heading,
   breadcrumb, intro-text, link-cards, text-media). NOT value-cards' 64/48/16:
   these sections sit directly under the page H1, and a different ladder would
   print the card edges out of line with the heading above them at every
   viewport but the widest.

   Columns 3 → 2 → 1, and the 2-up step lands at 1024 rather than the usual 900.
   Three abreast inside the 80px tablet gutter measure (100vw − 224)/3, which is
   352px at 1280 but only 226px at 901 — too narrow for a 24px headline, and the
   card would spend most of that band cramped. Switching at 1024 keeps the
   narrowest 3-up at 267px and hands the 768–1024 band two 416px cards instead.
   1024 is also the threshold news-card.php's sizes attribute already assumed.

   The 40px section headings need no rule: --fs-3xl steps 40 → 36 → 32 on its
   own in tokens.css, and the card grid's 32px gap is deliberately held at every
   width so the rhythm between rows never changes.
   ------------------------------------------------------------------------- */

/* Tablet (≤1280): ease the gutter; three columns hold. The pills give up half
   their 32px side padding — it is pure air, and shedding it keeps the whole
   filter row on one line for several hundred pixels longer. */
@media (max-width: 1280px) {
	.news-latest,
	.news-list,
	.news-archive {
		padding-inline: 80px;
	}
	.news-tabs__link {
		padding-inline: var(--sp-24);
	}
}

/* ≤1024: two columns (see the note above on why not 900). */
@media (max-width: 1024px) {
	.news-latest__grid,
	.news-archive__grid {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}
	/* The slider steps with it: 2 cards + 1 gap. Landing on the same counts as
	   tataconsumer.com's ≤768 → 2 is why their card design needed no changes
	   here. grid-template-columns is not restated — .is-slider's `none` above
	   carries a class more and so wins on specificity, not on order. */
	.news-list.is-slider .news-archive__grid {
		grid-auto-columns: calc((100% - var(--sp-32)) / 2);
	}
}

/* Phone (≤767): page gutter, one column, and the card's interior tightens to
   match link-cards (24 → 16 inset). The title drops to 20px — set as a literal
   because --fs-l self-steps to 18 at this breakpoint, which would leave only
   2px between a card headline and its own "View PDF" link and flatten the
   hierarchy the card is built on. */
@media (max-width: 767px) {
	.news-latest,
	.news-list,
	.news-archive {
		padding-inline: var(--sp-24);
	}
	.news-latest__inner,
	.news-list__inner {
		gap: var(--sp-24);
	}
	.news-latest__grid,
	.news-archive__grid {
		grid-template-columns: minmax(0, 1fr);
	}
	/* One card, no gap to subtract. Same step as the columns above and as
	   tataconsumer.com's ≤576 → 1, reached earlier because our card is wider. */
	.news-list.is-slider .news-archive__grid {
		grid-auto-columns: 100%;
	}
	/* Seventeen segments, two 48px arrows and a 24px page gutter leave about
	   200px of strip on a 375 phone; at an 8px gap the bars themselves would be
	   thinner than the space between them. */
	.news-slider__bars {
		gap: 4px;
	}
	.news-slider__controls {
		gap: var(--sp-16);
	}
	.news-card__body {
		padding-inline: var(--sp-16);
	}
	/* .news-card__title's hardcoded 20px override is gone (8 Aug 2026): its base
	   --fs-xl is now fluid and reaches 20.8 at 767 falling to 20 at 480, so the
	   token produces this by itself. */

	/* 16px pills at 12/16: 12 + 12 + 22 line box = a 46px tap target, clear of
	   the 44px floor, in a row that now wraps to far fewer lines. */
	.news-tabs {
		margin-block-end: var(--sp-32);
	}
	.news-tabs__link {
		padding: var(--sp-12) var(--sp-16);
		font-size: var(--fs-m);   /* 16 */
	}

	/* The two rows keep their one-rung gap on a phone: --fs-l reads 18 here
	   against the category row's 16.

	   The two margins are restated rather than inherited from the base rules,
	   and they have to be. `.news-tabs` above sets margin-block-end for this
	   width and matches the type row too — same specificity, later in source —
	   so without these the type row would take the category row's 32px gap and
	   the pair would stop reading as one control. The 16 is the base value
	   again; the 32 tracks the phone gap for the row-on-its-own case. Borders
	   are not restated: nothing here touches them. */
	.news-tabs--type {
		margin-block-end: var(--sp-16);
	}
	.news-tabs--type:last-of-type {
		margin-block-end: var(--sp-32);
	}
	.news-tabs--type .news-tabs__link {
		font-size: var(--fs-l);
	}

	.news-pager {
		margin-block-start: var(--sp-32);
	}
}

/* ---- Respect reduced-motion: neutralise every transition/animation ---- */
@media (prefers-reduced-motion: reduce) {
	*,
	*::before,
	*::after {
		transition-duration: 0.01ms !important;
		animation-duration: 0.01ms !important;
		animation-iteration-count: 1 !important;
		scroll-behavior: auto !important;
	}
}

/* ==========================================================================
   Search takeover (Figma 11302:4508 empty · 11413:12454 results)
   A maroon band over a white results column. The band is 420 tall and splits
   cleanly: 100 of header bar + 120 + an 80 form row + 120. The header half
   lives in header-search.php, outside <main>, so both halves are painted
   maroon here and the seam is invisible.

   ONE COLUMN, NOT TWO. It looks like two widths — the results are 1440 (x=240
   at 1920) and the form is 1200 (x=360) — but 360 − 240 is 120, so the form is
   simply the same column with a further 120 of inset. Both are built that way:
   a 120px page gutter, a 1440 max-width, and then the band adds 120 more. They
   therefore share one outer box at every viewport instead of drifting apart,
   and the responsive ladder below only has to move two numbers.

   The 1440 is a border-box figure and has to be — `box-sizing: border-box` is
   global (top of this file), so a 1200 max-width here would subtract its own
   padding and draw the form at 960. Measured off the export: the form spans
   frame x 359.3 → 1560.7, i.e. 1200 at x=360.

   Measured off the exports rather than eyeballed — card 131 tall resolves as
   24 + 44.8 + 10 + 28 + 24, the pill fill samples #b98290 which is exactly
   50% white over #720421, and the placeholder samples #dee1e7, i.e. Gray/200
   rather than a dimmed white.
   ========================================================================== */

.search-takeover {
	background: var(--c-white);
}

/* Fills the window so the empty state's centred line has a box to centre in
   and a two-result page does not leave the band stranded at the top. */
.search-takeover .site-main {
	display: flex;
	min-height: calc(100vh - var(--header-h));
}

/* ---- Header bar ---------------------------------------------------------
   Not .site-header: the takeover has no menu, so it needs neither the sticky
   positioning nor the scrolled shadow. Two deliberate divergences from the
   site header, both measured in these frames — a 120px gutter instead of 48,
   and a 60px logo instead of 44. The search frames draw it that way, and with
   nothing between the logo and the close control there is room for it.
   ------------------------------------------------------------------------- */
.search-header {
	background: var(--c-primary);
	color: var(--c-white);
}

.search-header__inner {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--sp-32);
	min-height: var(--header-h);
	padding-inline: 120px;
}

.search-header .site-brand__link svg {
	height: 60px;
}

.search-header__close {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	flex: 0 0 auto;
	width: 48px;
	height: 48px;
	margin-inline-end: -8px;   /* optical: centres the 32px glyph on x=1784 */
	border-radius: 50%;
	color: var(--c-white);
	transition: background-color 0.18s ease;
}

.search-header__close:hover {
	background: var(--c-white-20);
	text-decoration: none;
}

.search-header__close-icon,
.search-header__close-icon svg {
	display: block;
	width: 32px;
	height: 32px;
}

/* ---- Page shell ---- */
.search-page {
	display: flex;
	flex-direction: column;
	flex: 1 1 auto;
	width: 100%;
	min-width: 0;
}

/* ---- The maroon band ----
   Outer padding is the page gutter, shared with the results column; the inner
   padding is the form's own inset inside that column. See the note above on why
   the max-width is 1440 rather than the form's own 1200. */
.search-page__band {
	flex: 0 0 auto;
	background: var(--c-primary);
	padding-block: 120px;
	padding-inline: 120px;
}

.search-page__band-inner {
	max-width: 1440px;
	margin-inline: auto;
	padding-inline: 120px;
}

/* ---- The form -----------------------------------------------------------
   An 80px row with 40px of inset either side and a hairline underneath. The
   rule is on the form and spans the full 1200 while the field and the pill sit
   inside the inset, which is why the padding is here and not on the field.
   ------------------------------------------------------------------------- */
.search-hero {
	display: flex;
	align-items: center;
	gap: var(--sp-24);
	min-height: 80px;
	padding-inline: 40px;
	border-block-end: 1px solid var(--c-white);
}

.search-hero__field {
	flex: 1 1 auto;
	min-width: 0;
	margin: 0;
	padding: 0;
	border: 0;
	background: transparent;
	font-family: var(--ff-body);
	font-weight: var(--fw-semibold);
	font-size: var(--fs-3xl);   /* 40 */
	line-height: var(--lh-base);
	color: var(--c-white);
	appearance: none;
}

/* Dimmer than the sampled #dee1e7, which sat a hair off white and read as a
   real query rather than a prompt. 62% white is 5.6:1 on the maroon — past AA
   for body text, let alone this 40px — and unmistakably not the typed value. */
.search-hero__field::placeholder {
	color: rgba(255, 255, 255, 0.62);
	opacity: 1;                 /* Firefox dims placeholders by default */
}

/* Chrome draws its own clear button inside type=search; the design has none. */
.search-hero__field::-webkit-search-cancel-button,
.search-hero__field::-webkit-search-decoration {
	appearance: none;
}

/* The global ring is maroon-on-maroon here, so the close button takes a white one. */
.search-header__close:focus-visible {
	outline: 2px solid var(--c-white);
	outline-offset: 2px;
}

/* The field does NOT, because searchform.php autofocuses it on the search page:
   a box round it is on screen the moment the page loads, which reads as a
   border on the input rather than as focus. The row already has a rule under
   it, so the indicator is that rule thickening — 1px border + a 2px shadow
   directly beneath it, which cannot shift the layout the way a wider border
   would. Transparent outline rather than none so forced-colors mode, which
   drops box-shadow, still repaints a visible ring. */
.search-hero__field:focus-visible {
	outline: 2px solid transparent;
	outline-offset: 2px;
}

.search-hero:has(.search-hero__field:focus-visible) {
	box-shadow: 0 2px 0 var(--c-white);
}

/* Without :has there is nothing to thicken, so fall back to the ring. */
@supports not selector(:has(*)) {
	.search-hero__field:focus-visible {
		outline-color: var(--c-white);
	}
}

.search-hero__submit {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: var(--sp-8);
	flex: 0 0 auto;
	min-width: 129px;
	height: 49px;
	padding-inline: var(--sp-16);
	border: 0;
	border-radius: var(--radius-md);   /* 8 */
	background: rgba(255, 255, 255, 0.5);
	font-family: var(--ff-body);
	font-weight: var(--fw-semibold);
	font-size: var(--fs-m);
	line-height: var(--lh-base);
	color: #4b1626;                    /* one-off in these frames; not a token */
	cursor: pointer;
	transition: background-color 0.18s ease;
}

.search-hero__submit:hover,
.search-hero__submit:focus-visible {
	background: rgba(255, 255, 255, 0.72);
}

.search-hero__submit:focus-visible {
	outline: 2px solid var(--c-white);
	outline-offset: 2px;
}

.search-hero__submit .icon,
.search-hero__submit .icon svg {
	display: block;
	width: 20px;
	height: 20px;
}

/* ---- Results column ---- */
.search-page__results {
	display: flex;
	flex: 1 1 auto;
	padding-block: 100px;
	padding-inline: 120px;
}

.search-page__results-inner {
	display: flex;
	flex-direction: column;
	flex: 1 1 auto;
	width: 100%;
	min-width: 0;
	max-width: 1440px;
	margin-inline: auto;
}

.search-page__count {
	margin: 0 0 var(--sp-32);
	font-family: var(--ff-body);
	font-weight: var(--fw-regular);
	font-size: var(--fs-l);   /* 20 */
	line-height: var(--lh-base);
	color: var(--c-gray-800);
}

/* `margin-block: auto` is what centres the empty and no-match states inside
   the flex column, and it is inert on the results state because no message is
   printed there. That avoids both a state class in the template and :has(). */
.search-page__message {
	margin-block: auto;
	margin-inline: 0;
	text-align: center;
	font-family: var(--ff-body);
	font-size: var(--fs-l);   /* 20 */
	line-height: var(--lh-base);
	color: var(--c-gray-800);
}

/* ---- Result cards ----
   `ul` IS LOad-BEARING. WordPress puts `search-results` on the <body> of any
   search that found something — body.search.search-results — so a bare
   `.search-results` selector matches the document body as well as this list.
   It did: every search-with-results page turned its body into a flex column
   with a 32px gap, which opened a 32px white strip between the header and
   main. It showed on the takeover, where the strip cuts the maroon in two, and
   it was invisible on a search that found NOTHING, because that body gets
   `search-no-results` instead. Qualify every unscoped rule for this list with
   the tag, or the collision comes back. */
ul.search-results {
	display: flex;
	flex-direction: column;
	gap: var(--sp-32);
	margin: 0;
	padding: 0;
	list-style: none;
}

.search-result {
	border-radius: var(--radius-lg);   /* 12 */
	background: var(--c-gray-05);      /* #f9fafb over the white column */
	transition: background-color 0.2s ease;
}

/* The anchor carries the padding, not the li, so the click target is the whole
   card rather than a text-shaped hole inside it. */
.search-result__link {
	display: block;
	padding: var(--sp-24) var(--sp-32);
	color: inherit;
	text-decoration: none;
}

.search-result__link:hover {
	text-decoration: none;
}

.search-result:hover,
.search-result:focus-within {
	background: var(--c-gray-10);
}

.search-result__title {
	margin: 0;
	font-family: var(--ff-heading);
	font-weight: var(--fw-bold);
	font-size: var(--fs-2xl);   /* 32 */
	line-height: var(--lh-base);
	color: var(--c-primary);
}

.search-result__link:hover .search-result__title {
	text-decoration: underline;
	text-underline-offset: 3px;
}

/* A URL is one unbroken token, so without this a long one widens the card past
   its container instead of wrapping. `anywhere` rather than `break-word`
   because break-word will not split a token that already has a line to itself. */
.search-result__url {
	display: block;
	margin-block-start: var(--sp-10);
	font-family: var(--ff-body);
	font-weight: var(--fw-regular);
	font-size: var(--fs-l);   /* 20 */
	line-height: var(--lh-base);
	color: var(--c-black);
	overflow-wrap: anywhere;
}

/* ---- Pager --------------------------------------------------------------
   Not in Figma — the frame stops after four cards — so it reuses the News
   pager's language rather than inventing a second one. Sits after the results
   with 48 above it, in the space the absent footer would have taken.
   ------------------------------------------------------------------------- */
.search-pagination {
	margin-block-start: var(--sp-48);
}

.search-pagination .nav-links {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: center;
	gap: var(--sp-8);
}

.search-pagination .page-numbers {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 48px;
	padding: var(--sp-12) var(--sp-16);
	border-radius: var(--radius-md);
	font-family: var(--ff-body);
	font-weight: var(--fw-semibold);
	font-size: var(--fs-m);
	line-height: var(--lh-base);
	color: var(--c-black);
	text-decoration: none;
	transition: background-color 0.2s ease, color 0.2s ease;
}

.search-pagination a.page-numbers:hover,
.search-pagination a.page-numbers:focus-visible {
	background: var(--c-gray-10);
	color: var(--c-primary);
	text-decoration: none;
}

.search-pagination .page-numbers.current {
	background: var(--c-primary-400);
	color: var(--c-white);
}

/* Core's ellipsis is inert text, so it drops the pill box entirely. Gray/700
   rather than the News pager's Gray/600: #747c8e on white measures 4.19:1 and
   misses AA for normal text, #575d6a clears it at 6.61:1. Same defect exists on
   .news-pager and is left alone here — that section is signed off, and this is
   a colour change to it, not to search. */
.search-pagination .page-numbers.dots {
	min-width: 0;
	padding-inline: var(--sp-8);
	color: var(--c-gray-700);
}

/* ---- Responsive ---------------------------------------------------------
   The gutter follows the house ladder, 120 → 80 → 24, and the form's inset
   inside the column follows it down to nothing: by phone the column is already
   as narrow as the form wants to be, so a second inset would only starve it.

   ONE MEASUREMENT DRIVES THE WHOLE FORM ROW. The placeholder "What are you
   looking for?" is 12.07em wide — measured off the export at frame x 401.8 →
   884.6 against 40px type, not estimated. It is the only thing on the page with
   a hard minimum, because a search field that cuts its own prompt in half is a
   search field nobody trusts. So each band is checked at its NARROW end, which
   is where it either holds or does not:

       field available = column − 2×(hero inset) − gap − 129 (pill)
       placeholder     = 12.07em × the field size in that band

     ≥1281  col 801 → 568 avail vs 482.8 @40   +85
     ≤1280  col 705 → 472 avail vs 434.5 @36   +37
     ≤1024  col 608 → 415 avail vs 386.2 @32   +29
     ≤767   stacked, full width: 432 vs 386.2  +46
     ≤479   stacked, full width: 272 vs 241.4  +31

   The 1024 rung exists because of that third line: at 36px the row needs 434.5
   and only has 415, so the field is pinned to 32 there rather than waiting for
   the token to step at 767. news-latest switches columns at 1024 for its own
   reasons, so the rung is already in the file.
   ------------------------------------------------------------------------- */

/* Tablet (≤1280): the house 80px gutter, top to bottom. The field needs no rule
   — --fs-3xl steps 40 → 36 on its own in tokens.css. */
@media (max-width: 1280px) {
	.search-header__inner {
		padding-inline: 80px;
	}
	.search-page__band {
		padding-block: 80px;
		padding-inline: 80px;
	}
	.search-page__band-inner {
		padding-inline: 80px;
	}
	.search-page__results {
		padding-block: 80px;
		padding-inline: 80px;
	}
}

/* ≤1024: the form gives up its inset and sits flush in the results column, the
   hero's own inset halves, and the field is pinned to 32. All three are needed
   — see the table above; at 768 the row is 29px clear, and any one of them left
   out puts it under. */
@media (max-width: 1024px) {
	.search-page__band-inner {
		padding-inline: 0;
	}
	.search-hero {
		gap: var(--sp-16);
		padding-inline: var(--sp-24);
	}
	.search-hero__field {
		/* Deliberate one-off, kept after the fluid-token move (8 Aug 2026): this
		   is an <input>, so its text cannot wrap or ellipsis — it must simply fit
		   the field, which is a layout constraint rather than a type-scale one.
		   --fs-3xl reaches ~35 here, so this still buys 3px. (The old comment
		   said "the token still says 36 at this width"; that referred to the
		   retired ≤1280 rung and no longer describes anything.) */
		font-size: 2rem;   /* 32 */
	}
}

/* Phone (≤767): the row stacks. It would in fact survive on one line to about
   627, but the whole theme goes single-column at 767 and a field-over-button
   form is what a phone expects; holding a squeezed row for another 140px of
   viewport is not worth being the one section that behaves differently.

   Stacking costs about 60px of height, which matters on a landscape phone where
   height is the scarce axis — but the band's padding drops 80 → 32 top and
   bottom at the same breakpoint, so the form is net ~100px SHORTER here than it
   was one pixel wider.

   The hairline moves from the form to the field. On one line it underlines the
   whole row and reads as the field's own rule; stacked, left on the form, it
   would underline the button instead. */
@media (max-width: 767px) {
	.search-header__inner {
		padding-inline: var(--sp-24);
	}

	/* --header-h is 64 here, so the 60px logo would fill the bar to within 4px. */
	.search-header .site-brand__link svg {
		height: 40px;
	}

	/* 44 is the tap-target floor; the glyph comes down with the box. */
	.search-header__close {
		width: 44px;
		height: 44px;
	}
	.search-header__close-icon,
	.search-header__close-icon svg {
		width: 24px;
		height: 24px;
	}

	.search-page__band {
		padding-block: var(--sp-32);
		padding-inline: var(--sp-24);
	}

	.search-hero {
		flex-wrap: wrap;
		gap: var(--sp-16);
		min-height: 0;
		padding-inline: 0;
		border-block-end: 0;
	}
	.search-hero__field {
		flex: 1 1 100%;
		padding-block-end: var(--sp-12);
		border-block-end: 1px solid var(--c-white);
	}

	/* ---- The focus indicator has to follow the rule it thickens ----
	   Above this width the form's own border-block-end IS the row's hairline,
	   so a 2px shadow on the form's bottom edge lands exactly on it and the
	   rule appears to thicken. Here the border has moved to the FIELD and the
	   form's bottom edge is below the wrapped submit — so the same shadow drew
	   a 2px white line across the whole band, level with the bottom of the
	   button and attached to nothing. searchform.php autofocuses the field on
	   this page, so it was on screen the moment the page loaded and read as a
	   second, stray underline rather than as focus.

	   Moved onto the field, where the hairline now is. Same indicator, same
	   2px, same reason it is a shadow rather than a thicker border: a border
	   would change the field's height and shift the button beneath it. */
	.search-hero:has(.search-hero__field:focus-visible) {
		box-shadow: none;
	}
	.search-hero__field:focus-visible {
		box-shadow: 0 2px 0 var(--c-white);
	}

	/* The submit needs nothing else: 49px tall already clears the 44 floor, and
	   in a wrapped row it drops to its own line at its natural width rather
	   than stretching to 719px at the top of this band. */

	.search-page__results {
		padding-block: var(--sp-48);
		padding-inline: var(--sp-24);
	}
	.search-page__count {
		margin-block-end: var(--sp-24);
	}
	/* `ul` for the same reason as the base rule — see there. */
	ul.search-results {
		gap: var(--sp-16);
	}
	.search-result__link {
		padding: var(--sp-16);
	}

	/* --fs-l steps to 18 here, but a full URL is the longest unbroken thing on
	   the card and at 18 it runs to four lines inside a 240px phone card. It is
	   supporting text, so 16 — still well past the readable floor, and black on
	   #f9fafb is 20:1 either way. */
	.search-result__url {
		font-size: var(--fs-m);   /* 16 */
	}

	.search-pagination {
		margin-block-start: var(--sp-32);
	}
}

/* Phone portrait (≤479): 32px would clip the placeholder below about 340 wide.
   Only padding-inline gives on the pager pills — the 12px block padding is what
   keeps a 16px number on a 46px tap target. */
@media (max-width: 479px) {
	.search-hero__field {
		font-size: 1.25rem;   /* 20 */
	}
	.search-pagination .page-numbers {
		min-width: 44px;
		padding-inline: var(--sp-12);
	}
}

/* 100vh is the house unit (see .site-main, top of this file) but on a phone it
   counts the collapsing browser chrome, which pushes the empty state's centred
   line below the true middle — the one state where that is the entire layout.
   Progressive, so the house default stands wherever svh is not understood. */
@supports (min-height: 100svh) {
	.search-takeover .site-main {
		min-height: calc(100svh - var(--header-h));
	}
}

@media (prefers-reduced-motion: reduce) {
	.search-header__close,
	.search-hero__submit,
	.search-result,
	.search-pagination .page-numbers {
		transition: none;
	}
}

/* ==========================================================================
   Investor Relations search                                    (not in Figma)
   ==========================================================================
   `/?s=term&ir=1`. The takeover above is unchanged — same band, same form, same
   pager — and only the results region differs, so this section styles that
   region and overrides the handful of sitewide rules that are wrong for it.
   Placed directly after the search section because several rules here are
   `.search-page__results--ir` scopings of rules defined above; moved earlier in
   the file they would lose.

   IT IS A DENSER LIST THAN THE SITEWIDE ONE, and deliberately. A sitewide
   result is a page: one title, one URL, 32px type, 32px between cards, and
   usually a handful of them. An IR result is a document, ten to a page, and the
   answer to "Q1 FY26 presentation" is a list somebody scans rather than reads.
   So the titles come down to the 24 every other IR document title uses, the
   gaps halve, and each row carries a second line of orientation the sitewide
   card has no need for.

   THE CHIPS ARE THE IR TAB PILL, SMALLER. Same 8px corner, same fill when
   active, same two-property transition — they sit two hundred pixels below a
   real .ir-header__tab row on the page the visitor just came from, and a
   second, unrelated pill vocabulary in the same section would read as a
   different site. That sentence is why the fill moved to Primary/500 here on
   2026-09-21 along with the tab row: leaving it at Primary/400 would have put
   the two reds Option B exists to remove on one page, a screen apart.

   What is added is the resting border: a tab row sits on its own hairline and
   needs no outline, whereas these float on white.
   ========================================================================== */

/* ---- The column ---------------------------------------------------------
   The count leads into the chips rather than into the results, so the 32 below
   it closes to 16 — the two are one block, and the 32 belongs under the pair.
   ------------------------------------------------------------------------- */
.search-page__results--ir .search-page__count {
	margin-block-end: var(--sp-16);
}

/* ---- Filters ------------------------------------------------------------ */
.ir-search__filters {
	display: flex;
	flex-direction: column;
	gap: var(--sp-12);
	margin-block-end: var(--sp-32);
}

.ir-search__filter {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--sp-8) var(--sp-16);
}

/* min-width, not a grid: "Area" and "Type" are 31 and 32 wide at this size, so
   the two chip rows would start one pixel out of line with each other — close
   enough to look like a mistake rather than a decision. 48 puts both rows on a
   common left edge and still leaves the 16px gap intact when a legend is
   translated into something longer. */
.ir-search__filter-legend {
	flex: none;
	min-width: 48px;
	font-family: var(--ff-body);
	font-weight: var(--fw-semibold);
	font-size: var(--fs-s);   /* 14 */
	line-height: var(--lh-base);
	color: var(--c-gray-700);
}

.ir-search__chips {
	display: flex;
	flex-wrap: wrap;
	gap: var(--sp-8);
	margin: 0;
	padding: 0;
	list-style: none;
}

.ir-search__chip {
	display: flex;
}

/* The anchor is the pill, so the whole shape is the target rather than the
   words inside it — same reason .search-result__link carries the card padding.
   The border is transparent-to-Gray/200 rather than absent-to-present so the
   pill does not resize by 2px when it becomes the active one. */
.ir-search__chip-link {
	display: inline-flex;
	align-items: center;
	gap: var(--sp-8);
	padding: var(--sp-8) var(--sp-16);
	border: 1px solid var(--c-gray-200);
	border-radius: var(--radius-md);   /* 8, as .ir-header__tab-link */
	background: var(--c-white);
	font-family: var(--ff-body);
	font-weight: var(--fw-semibold);
	font-size: var(--fs-m);   /* 16 */
	line-height: var(--lh-base);
	color: var(--c-black);
	text-decoration: none;
	transition: background-color 0.2s ease, border-color 0.2s ease, color 0.2s ease;
}

/* No underline on hover, matching the tab row above: these are navigation. */
.ir-search__chip-link:hover,
.ir-search__chip-link:focus-visible {
	border-color: var(--c-primary-100);
	color: var(--c-primary);
	text-decoration: none;
}

.ir-search__chip.is-active .ir-search__chip-link {
	border-color: var(--c-primary);
	background: var(--c-primary);   /* #720421 — follows .ir-header__tab */
	color: var(--c-white);
}

/* The tally inside the chip. Lighter than the label so the row scans as words
   first and numbers second. */
.ir-search__chip-count {
	font-weight: var(--fw-regular);
	color: var(--c-gray-700);
}

/* Not currently reachable — search-ir.php prints the counts only while nothing
   is narrowed, and a lit chip means something is. Kept as one line rather than
   left out because the day that guard is relaxed, Gray/700 on Primary/500 is
   1.8:1 and the number would simply vanish. */
.ir-search__chip.is-active .ir-search__chip-count {
	color: var(--c-white);
	opacity: 0.75;
}

/* ---- Document results ---------------------------------------------------
   The .search-result card, restated rather than extended: it is the same fill
   and the same corner, but the anchor inside it is a row instead of a block and
   every child differs, so a shared base class would have been two rules deep in
   overrides. No border, unlike .doc-card — these are on the search takeover,
   and matching the cards directly above them in the page group matters more
   here than matching the cards on the page the document lives on.
   ------------------------------------------------------------------------- */
.ir-results {
	display: flex;
	flex-direction: column;
	gap: var(--sp-16);
	margin: 0;
	padding: 0;
	list-style: none;
}

.ir-result {
	border-radius: var(--radius-lg);   /* 12 */
	background: var(--c-gray-05);
	transition: background-color 0.2s ease;
}

.ir-result:hover,
.ir-result:focus-within {
	background: var(--c-gray-10);
}

/* The kind modifiers — --pdf, --audio, --page, --file — carry no declarations
   on purpose. The difference between a PDF and a recording is already said
   twice inside the card, in the icon and in the badge text, and a third signal
   in the card's own colour would be decoration standing in for information.
   They stay in the markup as hooks: a future "audio only" affordance has
   somewhere to attach without touching the template. */

.ir-result__link {
	display: flex;
	align-items: center;
	gap: var(--sp-24);
	padding: var(--sp-24) var(--sp-32);
	color: inherit;
	text-decoration: none;
}

.ir-result__link:hover {
	text-decoration: none;
}

.ir-result__body {
	display: flex;
	flex-direction: column;
	gap: var(--sp-8);
	flex: 1 1 auto;
	min-width: 0;
}

/* 24, and the two overrides that get there are the same two .doc-card__title
   needs — the base sheet gives an h3 --fs-4xl and --ls-h3, and --ls-h3 is a
   known px/percent mix-up this opts out of rather than inherits. 24 is the
   client's 2026-08-06 instruction for the maroon document title across the
   whole IR tree, and a search result is that same title in a different place.
   Do not restore it to Figma's 32.

   overflow-wrap because these titles are long and some are a single unbroken
   reference number. */
.ir-result__title {
	margin: 0;
	font-family: var(--ff-heading);
	font-weight: var(--fw-bold);
	font-size: var(--fs-xl);   /* 24 — the IR document-title override */
	line-height: var(--lh-base);
	letter-spacing: normal;
	color: var(--c-primary);
	overflow-wrap: break-word;
}

.ir-result__link:hover .ir-result__title {
	text-decoration: underline;
	text-underline-offset: 3px;
}

/* The trail. Wraps as a flex row so a long page name breaks between the crumbs
   rather than mid-word, and so the separator stays glued to the crumb before
   it instead of starting a line. Gray/700, which clears AA on the card fill. */
.ir-result__meta {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	gap: 0 var(--sp-8);
	font-family: var(--ff-body);
	font-weight: var(--fw-regular);
	font-size: var(--fs-m);   /* 16 */
	line-height: var(--lh-base);
	color: var(--c-gray-700);
}

.ir-result__crumb {
	overflow-wrap: anywhere;
}

.ir-result__sep {
	color: var(--c-gray-400);
}

/* The type badge: a 20px glyph over a 14px word, centred, at the card's right
   edge. Same stack as .doc-card--file's CTA and the same 4px literal, one size
   down and without the underline — that one is a control, this one is a label,
   and an underline here would invite a second click inside a card that is
   already entirely a link. */
.ir-result__type {
	display: inline-flex;
	flex-direction: column;
	align-items: center;
	gap: 4px;
	flex: none;
	width: 72px;
	font-family: var(--ff-body);
	font-weight: var(--fw-regular);
	font-size: var(--fs-s);   /* 14 */
	line-height: var(--lh-base);
	color: var(--c-gray-700);
	text-align: center;
}

.ir-result__icon,
.ir-result__icon svg {
	display: block;
	width: 20px;
	height: 20px;
}

/* Fixed 72 above, so "Audio recording" wraps to two lines at a stable width
   instead of stretching the badge and pulling the title column in and out as
   the list mixes types. */
.ir-result__kind {
	display: block;
}

/* ---- The pages group ----------------------------------------------------
   Second, and visibly a different kind of answer: a rule across the column
   with 48 above it, because "no more documents" is the message and a gap alone
   does not carry it.
   ------------------------------------------------------------------------- */
.ir-search__group--pages {
	margin-block-start: var(--sp-48);
	padding-block-start: var(--sp-32);
	border-block-start: 1px solid var(--c-gray-100);
}

/* An h2, so the base sheet is offering --fs-5xl — 60px over a list of 24px
   results. Down to 24, and in Dark rather than Primary: maroon is what the
   result titles below it use, and a maroon heading would out-rank the things
   it introduces. */
.ir-search__group-heading {
	margin: 0 0 var(--sp-24);
	font-family: var(--ff-heading);
	font-weight: var(--fw-bold);
	font-size: var(--fs-xl);   /* 24 */
	line-height: var(--lh-base);
	letter-spacing: normal;
	color: var(--c-text);
}

/* The group reuses components/search-result.php as it is, which is right — a
   page result is a page result — but its sitewide sizing is not: 32px titles
   and 32px gaps under a list of 24s would make the secondary group the loudest
   thing on the page. Scoped to --ir so the sitewide search is untouched. */
.search-page__results--ir .search-results {
	gap: var(--sp-16);
}

.search-page__results--ir .search-result__title {
	font-size: var(--fs-xl);   /* 24, from 32 */
}

.search-page__results--ir .search-result__url {
	font-size: var(--fs-m);   /* 16, from 20 */
}

/* ---- Notes and the way out ---------------------------------------------- */
.ir-search__note {
	margin: var(--sp-24) 0 0;
	font-family: var(--ff-body);
	font-size: var(--fs-m);   /* 16 */
	line-height: var(--lh-base);
	color: var(--c-gray-700);
}

.ir-search__escape {
	margin: var(--sp-48) 0 0;
	font-family: var(--ff-body);
	font-size: var(--fs-m);   /* 16 */
	line-height: var(--lh-base);
	color: var(--c-gray-700);
}

.ir-search__escape-link {
	color: var(--c-primary);
	text-decoration: underline;
	text-underline-offset: 3px;
}

.ir-search__escape-link:hover,
.ir-search__escape-link:focus-visible {
	color: var(--c-primary-600);
}

/* ---- The empty state ----------------------------------------------------
   .search-page__message centres itself with `margin-block: auto`, which is
   exactly right when the message is the only thing in the column and exactly
   wrong here: an auto bottom margin absorbs the free space BELOW the message,
   so the two links that belong under it get pushed to the floor of a 700px
   column and read as page furniture rather than as the answer's continuation.

   So the auto margin moves to the last link and the group centres as one. It
   has to be conditional — the nothing-typed state prints the message and
   nothing after it, and there the original centring is correct — hence :has(),
   which the takeover already uses (see .search-hero:has(...) above).

   Both escapes are larger and centred here because in this state they are not
   an aside, they are the only thing on the page worth doing next.
   ------------------------------------------------------------------------- */
.search-page__results--ir .search-page__results-inner:has(.ir-search__escape--empty) .search-page__message {
	margin-block-end: 0;
}

.ir-search__escape--widen,
.ir-search__escape--empty {
	text-align: center;
	font-size: var(--fs-l);   /* 18 → 20 */
}

.ir-search__escape--widen {
	margin-block-start: var(--sp-24);
}

.ir-search__escape--empty {
	margin-block-start: var(--sp-24);
	margin-block-end: auto;
}

/* Widen first, then leave — the second sits close under the first because they
   are one offer in two steps, not two separate ones. */
.ir-search__escape--widen + .ir-search__escape--empty {
	margin-block-start: var(--sp-12);
}

/* Without :has the message keeps its own centring and the links settle at the
   bottom of the column. Reachable but not broken, and every browser the site
   supports has had :has since 2023. */
@supports not selector(:has(*)) {
	.ir-search__escape--empty {
		margin-block-end: 0;
	}
}

/* ---- IR search — responsive ---------------------------------------------
   TWO RUNGS, 767 and 479, and no others. The gutter ladder is already served
   by .search-page__results above — 120 → 80 → 24 — so the column arrives at
   the right width without this section saying anything, and a 1280 or 1024 rung
   here would be an empty one. The widths that matter are where the result card
   runs out of room for its title and where a five-chip filter row runs out of
   room for its widest chip:

     col = viewport − 2×gutter, capped 1440       body = col − pad − gap − 72
     1440   1200      body 1032
     1280   1120      body  952
      768    608      body  440
      767    719      body  599   (gutter drops 80 → 24 here, so it WIDENS)
      480    432      body  312
      360    312      body  192   ← the card stacks before this
      320    272                  ← the chip row must still hold at this width

   THE CHIP ROWS WRAP, THEY DO NOT SCROLL, which is a deliberate break from the
   tab strip they otherwise copy. A swipe strip in this theme is three things,
   not one: overflow-x, sticky edge fades, and initIrScrollers() toggling
   .has-more-start/.has-more-end — and the note on that block is explicit that
   without the last two "a strip that scrolls tells the user neither where they
   are nor that there is more." A filter also wants the opposite of a tab row:
   a tab you cannot see is a page you already know exists, whereas a filter you
   cannot see is an option that does not exist as far as the visitor is
   concerned. So these wrap, at the cost of some height on a phone — about four
   lines for the Area row at 375, which is the price of every option staying on
   screen.
   ------------------------------------------------------------------------- */
@media (max-width: 767px) {
	.ir-search__filters {
		margin-block-end: var(--sp-24);
	}

	/* 8px of block padding makes a 38px chip, under the 44 tap floor this file
	   holds elsewhere (.search-header__close). 12 makes it 46, which is also
	   exactly what .ir-header__tab-link steps to at this same breakpoint — the
	   two rows stay the same size as each other on the same screen. */
	.ir-search__chip-link {
		padding: var(--sp-12) var(--sp-16);
	}

	/* Matches .search-result__link, which drops to a flat 16 here. */
	.ir-result__link {
		gap: var(--sp-16);
		padding: var(--sp-16);
	}

	.ir-search__group--pages {
		margin-block-start: var(--sp-32);
		padding-block-start: var(--sp-24);
	}

	.ir-search__group-heading {
		margin-block-end: var(--sp-16);
	}

	.ir-search__note {
		margin-block-start: var(--sp-32);
	}

	/* The plain escape only. --widen and --empty are single-class selectors as
	   well, so a bare .ir-search__escape in here would not be overridden by them
	   — it would override them, on source order, and the empty state's deliberate
	   24-then-12 pairing would come apart into two 32s at exactly the width where
	   that state is most of the page. */
	.ir-search__escape:not(.ir-search__escape--widen):not(.ir-search__escape--empty) {
		margin-block-start: var(--sp-32);
	}
}

@media (max-width: 479px) {
	/* The legend takes its own line. It looks like it costs one — it buys two
	   back. Inline, the legend and its gap hold 64px hostage on every line of a
	   row that is already wrapping, and at 432 that is the difference between
	   four wrapped lines and two.

	   At 320 it stops being about tidiness. The column is 272 and "Results &
	   Presentations" measures somewhere near 220 as a chip — an estimate, not a
	   measurement, because there is no way to measure a woff2 advance from here
	   — which clears 272 and does not clear the 208 left once the legend has had
	   its share. Nothing overflows either way; the rule below is what guarantees
	   that. What the stacked legend buys is the chip not having to break its own
	   label in half to stay inside the page. */
	.ir-search__filter {
		flex-direction: column;
		align-items: stretch;
		gap: var(--sp-8);
	}

	.ir-search__chip-link {
		padding-inline: var(--sp-12);
	}

	/* No white-space: nowrap here, deliberately, and this is the other place the
	   chips part company with .ir-header__tab-link. That row nowraps because it
	   scrolls, so a long label simply extends the scrollport. These have nowhere
	   to extend to, so a label longer than the column has to be allowed to break
	   inside its own pill — ugly at a width nothing else is pretty at, and the
	   alternative is content hanging off the side of the page. */

	/* The badge comes out of the row. At 360 the card body is down to ~192px for
	   a 24px serif, which puts "Transcript of Earnings Call — Intimation" on four
	   lines beside 72px of mostly empty badge column; stacked, the same title has
	   the full 280 and the badge reads as a line of its own under the trail.
	   Kept AFTER the body rather than lifted above the title with order: -1 — an
	   eyebrow would read better, but it would put the visual order at odds with
	   the DOM order inside a single link, and the icon is already enough to stop
	   it being mistaken for another crumb. */
	.ir-result__link {
		flex-direction: column;
		align-items: flex-start;
		gap: var(--sp-12);
	}

	.ir-result__type {
		flex-direction: row;
		align-items: center;
		gap: var(--sp-8);
		width: auto;
		text-align: start;
	}
}

@media (prefers-reduced-motion: reduce) {
	.ir-search__chip-link,
	.ir-result {
		transition: none;
	}
}

/* ==========================================================================
   404 — Not Found                                    (Figma 11422:12734, ref)
   ==========================================================================
   The frame is a heading, a paragraph, and ~550px of empty white. The height
   here is proportional padding instead: the same visual breathing room on a
   laptop, without a hole on a large monitor or a scroll on a phone. Everything
   below the paragraph — the two buttons its own copy promises, the search, the
   onward links — is ours, and is drawn from parts the site already owns.
   ========================================================================== */
.error-404 {
	padding-block: clamp(var(--sp-64), 8vw, 120px);
	padding-inline: var(--container-pad);
	background: var(--c-white);
}

.error-404__inner {
	max-width: 640px;
	margin-inline: auto;
	text-align: center;
}

.error-404__title {
	margin: 0;
	font-family: var(--ff-heading);
	font-weight: var(--fw-bold);
	font-size: var(--fs-4xl);          /* 48 */
	line-height: var(--lh-tight);
	color: var(--c-text);
}

/* Narrower than the block that holds it: the paragraph wraps to three lines at
   the width Figma sets it, and the search below wants the full 640. */
.error-404__message {
	max-width: 460px;
	margin: var(--sp-16) auto 0;
	font-family: var(--ff-body);
	font-size: var(--fs-m);
	line-height: 1.6;
	color: var(--c-text-body);
}

.error-404__actions {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	gap: var(--sp-16);
	margin-block-start: var(--sp-32);
}

/* .btn is sized for a header pill; these are the page's own calls to action. */
.error-404__action {
	padding: var(--sp-12) var(--sp-24);
}

/* Inset shadow, not a border: a 1px border would make this button 2px taller
   than the primary beside it, and the pair would sit off each other's baseline. */
.error-404__action--secondary {
	background: transparent;
	color: var(--c-primary);
	box-shadow: inset 0 0 0 1px var(--c-primary-20);
	transition: background-color 0.18s ease, box-shadow 0.18s ease;
}

.error-404__action--secondary:hover,
.error-404__action--secondary:focus-visible {
	background: var(--c-primary-05);
	box-shadow: inset 0 0 0 1px var(--c-primary);
}

.error-404__search {
	margin-block-start: clamp(var(--sp-48), 5vw, var(--sp-64));
}

.error-404__search-title {
	margin: 0 0 var(--sp-16);
	font-family: var(--ff-body);
	font-weight: var(--fw-semibold);
	font-size: var(--fs-m);
	line-height: var(--lh-base);
	color: var(--c-text);
}

/* The search band is drawn for the maroon takeover: 40px white type on a white
   hairline, sized to be the whole page. Here it is one element on a white page,
   so every rule that assumed maroon behind it is re-pointed. The FORM is
   untouched — searchform.php still renders one markup, restyled, not forked. */
.error-404__search .search-hero {
	gap: var(--sp-8);
	min-height: 0;
	padding: var(--sp-8) var(--sp-8) var(--sp-8) var(--sp-24);
	border-block-end: 0;
	border-radius: var(--radius-lg);
	background: var(--c-primary-05);
	box-shadow: inset 0 0 0 1px var(--c-primary-20);
}

.error-404__search .search-hero__field {
	font-weight: var(--fw-regular);
	font-size: var(--fs-l);            /* 20 — 40 is a takeover size */
	color: var(--c-text);
}

.error-404__search .search-hero__field::placeholder {
	color: var(--c-text-muted);        /* 6:1 on the 5% tint */
}

.error-404__search .search-hero__submit {
	min-width: 0;
	height: 40px;
	background: var(--c-primary);
	color: var(--c-white);
}

.error-404__search .search-hero__submit:hover,
.error-404__search .search-hero__submit:focus-visible {
	background: var(--c-primary-400);
}

/* The takeover indicates focus by thickening the white rule under the field,
   which on a white page is nothing at all. Scoped back to a ring on the pill. */
.error-404__search .search-hero:has(.search-hero__field:focus-visible) {
	box-shadow: inset 0 0 0 2px var(--c-primary);
}

/* Below 768 the takeover moves that white 2px from the form to the FIELD,
   because its form wraps and the form's bottom edge is no longer the rule (see
   the ≤767 block). This form does not wrap into that shape and has no white
   rule to thicken, so the inherited shadow would draw a faint white line across
   the tint. Taken back here rather than scoped there, so everything this page
   does about focus stays in one place. */
.error-404__search .search-hero__field:focus-visible {
	box-shadow: none;
}

.error-404__search .search-hero__submit:focus-visible {
	outline-color: var(--c-primary);
}

@supports not selector(:has(*)) {
	.error-404__search .search-hero__field:focus-visible {
		outline-color: var(--c-primary);
	}
}

.error-404__links {
	margin-block-start: clamp(var(--sp-32), 3vw, var(--sp-48));
}

.error-404__links-list {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	gap: var(--sp-12) var(--sp-24);
	margin: 0;
	padding: 0;
	list-style: none;
}

.error-404__links-item a {
	font-family: var(--ff-body);
	font-weight: var(--fw-semibold);
	font-size: var(--fs-m);
	line-height: var(--lh-base);
	color: var(--c-primary);
}

/* Standalone links in a row, so colour is not their only signal — but they are
   still links, and the underline on hover/focus says so before the click. */
.error-404__links-item a:hover,
.error-404__links-item a:focus-visible {
	text-decoration: underline;
	text-underline-offset: 4px;
}

/* Phone. The type scales itself — tokens.css already steps --fs-4xl 48 → 40 → 32
   and --fs-l 20 → 18 — so the only work here is the search, which inherits the
   takeover's own phone rule: the row stacks and the field grows a 1px WHITE
   hairline. Invisible against the maroon that rule was written for; a pale
   scratch across this tint. Re-point it and let the button use the full width
   the stack just gave it. */
@media (max-width: 767px) {
	.error-404__search .search-hero {
		padding: var(--sp-16);
	}

	.error-404__search .search-hero__field {
		border-block-end-color: var(--c-primary-20);
	}

	.error-404__search .search-hero__submit {
		flex: 1 1 100%;
	}
}

/* Narrow phone: side by side, the two buttons wrap to a ragged pair of
   different widths. Stacked, they are two full-width targets instead. */
@media (max-width: 479px) {
	.error-404__actions {
		flex-direction: column;
		gap: var(--sp-12);
	}

	.error-404__action {
		justify-content: center;
	}
}

@media (prefers-reduced-motion: reduce) {
	.error-404__action--secondary {
		transition: none;
	}
}

/* ==========================================================================
   Investor Relations — page header shell
   Figma section 11083:178295, measured on the Governance frames 11067:175281
   and 11129:2355 (identical here, which is what makes this one partial).

   A flex column under the breadcrumb, four children with a flat 60px between
   each, exactly as Figma stacks them:

     intro  (title + standfirst | 600×56 search)   y=120  1680×127
     tabs   row 1, the four IR trees               y=307   826×60
     hero   flat banner image                      y=427  1680×450
     subtabs row 2, sections in this tree          y=937  1674×51

   Top padding is Figma's 120px, expressed with the same clamp .page-heading
   uses so the two agree on every interior page. There is NO bottom padding:
   the following section's own --section-pad (64) stands in for Figma's 60px
   gap — the 4px approximation this file already makes at every page_heading
   pairing — and padding on both sides would double it.

   Gutter 120 / inner 1680 is the site-wide interior measure. Both tab strips
   are hug-width in Figma (826 and 1674) so their hairlines stop short of the
   container; here both rules span the full 1680, matching .news-tabs, which is
   the same control shipped on the News archive. A rule that stops two-thirds
   of the way across reads as a rendering fault rather than as a decision.
   Change `.ir-header__tabs` to inline-block to go back to Figma's literal hug.

   Markup + tab resolution: template-parts/sections/ir-header.php, inc/ir-nav.php.
   Responsive is a separate pass; everything below is the 1920 desktop layout.
   ========================================================================== */
.ir-header {
	padding-block: clamp(var(--sp-64), 8vw, 120px) 0;
	padding-inline: 120px;
	background: var(--c-white);
}

.ir-header__inner {
	/* Held as a property, not a literal, because .ir-header__crumbs has to cancel
	   this gap to sit tight under the tab strip. One knob, so the two cannot
	   drift apart. */
	--ir-stack-gap: 60px;   /* Figma stack gap — off-scale, no --sp-60 token */

	/* The section tabs butt together with no gutter, so their horizontal padding
	   IS the spacing between them — which also insets the first label from the
	   container edge. The breadcrumb below has no such padding, so the two rows
	   started at different x and the trail read as slightly out of true against
	   the tab sitting directly above it.

	   Held here rather than repeated because the crumb has to match whatever the
	   tab is using, and the tab drops to 12 below 767. One knob, stepped once. */
	--ir-tab-inset: var(--sp-16);

	display: flex;
	flex-direction: column;
	gap: var(--ir-stack-gap);
	max-width: 1680px;
	margin-inline: auto;
}

/* ---- Intro: titles left, search right ----------------------------------- */
.ir-header__intro {
	display: flex;
	align-items: center;
	gap: var(--sp-32);
}

.ir-header__titles {
	display: flex;
	flex-direction: column;
	gap: var(--sp-16);
	flex: 1 1 auto;
	min-width: 0;
}

/* Same treatment as .page-heading__title — this is the same H1 in the design
   system, only with a search box beside it. */
.ir-header__title {
	margin: 0;
	font-family: var(--ff-heading);
	font-weight: var(--fw-bold);
	font-size: var(--fs-6xl);
	line-height: var(--lh-tight);
	letter-spacing: var(--ls-h1);
	color: var(--c-dark);
}

.ir-header__standfirst {
	margin: 0;
	font-family: var(--ff-body);
	font-weight: var(--fw-regular);
	font-size: var(--fs-l2);
	line-height: var(--lh-base);
	color: var(--c-text-muted);
}

/* ---- Search -------------------------------------------------------------
   600×56 at the 1920 frame, and shrinkable below it. It has to give ground:
   Figma's title column is 1048 wide, so at 1440 a pinned 600 would leave the
   60px serif H1 about 568px and wrap "Investor Relations" onto two lines at the
   commonest desktop width. Basis 600 with a 280 floor lets the two negotiate,
   and they stop sharing a row entirely at 900. (The H1 was 72px when this was
   worked out; the 7 Aug 2026 drop to 60 only widens the margin, so the
   negotiation stays as it is.)
   4px radius is Figma's and off the scale (--radius-md is 8), so it is literal.
   ------------------------------------------------------------------------- */
.ir-header__search {
	display: flex;
	align-items: center;
	gap: var(--sp-8);
	flex: 0 1 600px;
	min-width: 280px;
	height: 56px;
	padding-inline: 20px;   /* off-scale, no --sp-20 token */
	background: var(--c-gray-05);
	border: 1px solid var(--c-gray-200);
	border-radius: 4px;
}

/* The shared helper draws at 20px; the design's field wants 24. Sized here
   rather than in orkla_icon_search() so the site header keeps its own size. */
.ir-header__search .icon--search {
	flex: none;
	width: 24px;
	height: 24px;
	color: var(--c-text);
}

/* The field is the box's interior, so it carries no chrome of its own — the
   wrapper owns the border, fill and radius, and the focus ring goes on the
   wrapper too so the whole control is outlined rather than a naked input. */
.ir-header__search-input {
	flex: 1 1 auto;
	min-width: 0;
	padding: 0;
	font-family: var(--ff-body);
	font-weight: var(--fw-regular);
	font-size: var(--fs-m);
	line-height: var(--lh-base);
	color: var(--c-text);
	background: none;
	border: 0;
	appearance: none;
}

.ir-header__search-input:focus {
	outline: none;
}

.ir-header__search:focus-within {
	outline: 2px solid var(--c-primary);
	outline-offset: 2px;
}

/* Figma's empty-field state: 40% on the darker text colour. Set explicitly
   because Firefox applies its own opacity otherwise. */
.ir-header__search-input::placeholder {
	color: var(--c-text);
	opacity: 0.4;
}

/* ---- Tab row 1 — the six groups -----------------------------------------
   The .news-tabs control: pills butt together with no gutter (the 16/20 padding
   is the spacing), sitting on a 30%-grey hairline, the active one a filled 8px
   Primary/500 pill in white. Padded 16/20 here against News's 16/32.

   OPTION B, 2026-09-21 — the client picked it off the four-panel comparison sheet
   sent on 18 September, and it changes two things in this row and two in the row
   below. THE PROBLEM IT SOLVES: every unselected label used to be full black at
   the same weight as the selected one, so the marker had nothing quiet to stand
   out against — which is why more red, or darker red, was never the lever. The
   unselected labels are Gray/700 now, and nothing got darker.

   The fill also moves from Primary/400 to Primary/500, so both rows mark their
   selection in ONE red instead of two. #8d233f keeps its other jobs — News
   tabs, both pagers — and is retired from Investor Relations only. See
   `.ir-search__chip.is-active`, which is this pill smaller and follows it.

   FOUR UNTIL 2026-08-25. Figma drew this strip 826×60 for four labels, which
   measure 828px together; the Aug-25 sheet makes it six — Financial
   Information, Corporate Governance, Stock Exchange Intimations, Shareholders
   Information, Results & Presentations, Investor Contact — measuring 1557px in
   Messina SemiBold at 20px with the 20px insets. Measured off the woff2, not
   estimated. Where each version wraps, container being the viewport less 240
   above 1280 and less 160 below it, capped at 1680:

                      one line      two lines     three lines
     old four         ≥ 988         768 – 987     never
     new six          ≥ 1797        988 – 1796    768 – 987

   So this went from wrapping in a 220px tablet band to wrapping across the
   whole desktop range: 1440 splits 4 + 2, 1280 the same, 1920 still fits on one
   line with 123px to spare. Below 767 both strips become swipe strips and none
   of this applies — that already handled six as it handled four.

   Nothing overflows or clips; the row has always been allowed to wrap. What was
   missing is a gap BETWEEN lines. The pills butt together horizontally on
   purpose, so with no row-gap the second line's labels touch the first line's
   active pill — a fault that existed at 768–987 before this change and simply
   was not where anyone was looking. Hence the row-gap, which is inert on a
   single line and so changes nothing at 1920.

   Row 2 is deliberately NOT given the same gap. It is the longer row, but its
   worst case is Corporate Governance's seven at 1041px against 1120 at the
   narrowest width that wraps — it still does not wrap anywhere, and its active
   item is a 2px underline pulled 1px down to land ON the strip's hairline, so
   if it ever did wrap a gap would be the smaller of its two problems. Add
   labels to a row-2 group and measure it before assuming otherwise.

   Shrinking the type or the insets was the alternative and does not reach: six
   tabs need 1557px against 1200, and 20px → 16px insets only buys back 48.
   ------------------------------------------------------------------------- */
.ir-header__tabs {
	border-block-end: 1px solid var(--c-gray-30);
}

.ir-header__tablist {
	display: flex;
	flex-wrap: wrap;
	row-gap: var(--sp-8);
	margin: 0;
	padding: 0;
	list-style: none;
}

.ir-header__tab-link {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	padding: var(--sp-16) 20px;   /* off-scale, no --sp-20 token */
	border-radius: var(--radius-md);   /* 8 */
	font-family: var(--ff-body);
	font-weight: var(--fw-semibold);
	font-size: var(--fs-l);            /* 20 */
	line-height: var(--lh-base);
	color: var(--c-gray-700);   /* Option B: quiet neighbours, not black ones */
	text-decoration: none;
	white-space: nowrap;
	transition: background-color 0.2s ease, color 0.2s ease;
}

/* No hover underline: these are navigation, and the site reserves the underline
   for focus and current page (see the primary menu, commit 2ccd782). */
.ir-header__tab-link:hover,
.ir-header__tab-link:focus-visible {
	color: var(--c-primary);
	text-decoration: none;
}

.ir-header__tab.is-active .ir-header__tab-link {
	background: var(--c-primary);   /* #720421 — one red, both rows */
	color: var(--c-white);
}

/* ---- Hero banner --------------------------------------------------------
   A leaf frame in Figma: one flat 1680×450 image, no slides despite the layer
   name. The ratio is held by the element so a differently-cropped upload fills
   the band instead of changing the header's height under the tabs.
   ------------------------------------------------------------------------- */
.ir-header__hero-img {
	width: 100%;
	aspect-ratio: 1680 / 450;
	object-fit: cover;
}

/* ---- Tab row 2 — sections in the current tree ---------------------------
   Quieter than row 1: no pill, 19px instead of 20, and the active item is a
   maroon label over a maroon underline. 19px is a raw value in the design,
   not a scale step, so it is written literally.

   Each item reserves the rule with a transparent border so nothing shifts when
   it becomes active, and is pulled down 1px so that underline lands ON the
   strip's hairline rather than below it — which is how Figma draws them, both
   at the same y. Padding is 12 top / 10 bottom + 2px border = Figma's 51.

   OPTION B, 2026-09-21 — what the client chose, and it is where B differs from
   the A we recommended. The resting labels go Gray/700 with row 1's, the rule
   thickens 2 → 3px, and the active item picks up a PALE RED HIGHLIGHT
   (Primary/10) with the top two corners rounded. So both levels read as red and
   only one of them is dark: filled pill above, tinted tab below. The shape is
   carried as well as the colour at each level, which is what keeps the current
   page from being signalled by colour alone, and keeps the two rows saying
   different things — which SECTION you are in, and which PAGE within it.

   The extra pixel of rule is taken back out of the padding so the row does not
   grow when a tab lights. That is why the bottom padding is held in
   --ir-subtab-pb rather than written into the shorthand: the active rule
   subtracts 1px from whatever the current breakpoint set, and row 3 and the
   swipe strip both restate the property instead of fighting a more specific
   selector. Change the padding in one of those three places only.
   ------------------------------------------------------------------------- */
.ir-header__subtabs {
	border-block-end: 1px solid var(--c-gray-30);

	/* This strip is the scroll target for every tab link and every card that
	   navigates within a tree (orkla_ir_section_anchor()). The site header is
	   sticky at top: 0, so without this the browser would scroll the strip to y=0
	   and the header would then sit on top of it — the tab you just clicked
	   arriving hidden behind the nav.

	   --header-h is a token, so this tracks the header's own 80 → 64 step at 767
	   with no second breakpoint to keep in sync. The extra --sp-24 is so the strip
	   lands below the header rather than exactly against it. */
	scroll-margin-block-start: calc(var(--header-h) + var(--sp-24));
}

.ir-header__subtablist {
	display: flex;
	flex-wrap: wrap;
	margin: 0;
	padding: 0;
	list-style: none;
}

.ir-header__subtab {
	display: flex;
}

.ir-header__subtab-link {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	--ir-subtab-pb: var(--sp-10);   /* the active rule steals 1px of this */

	padding: var(--sp-12) var(--ir-tab-inset) var(--ir-subtab-pb);
	margin-block-end: -1px;
	border-block-end: 2px solid transparent;
	font-family: var(--ff-body);
	font-weight: var(--fw-semibold);
	font-size: 1.1875rem;   /* 19 — raw Figma value, off the type scale */
	line-height: var(--lh-base);
	color: var(--c-gray-700);   /* Option B, with row 1 */
	text-decoration: none;
	white-space: nowrap;
	transition: color 0.2s ease, border-color 0.2s ease;
}

.ir-header__subtab-link:hover,
.ir-header__subtab-link:focus-visible {
	color: var(--c-primary);
	text-decoration: none;
}

.ir-header__subtab.is-active .ir-header__subtab-link {
	color: var(--c-primary);

	/* The pale red half of Option B. Rounded at the top only, so it reads as a
	   tab standing on the strip's hairline rather than as a floating chip. */
	background: var(--c-primary-10);   /* #7204211a */
	border-start-start-radius: var(--radius-md);
	border-start-end-radius: var(--radius-md);

	border-block-end-color: var(--c-primary);
	border-block-end-width: 3px;
	padding-block-end: calc(var(--ir-subtab-pb) - 1px);
}

/* ---- Row 3, inside Offer Documents only ---------------------------------
   NO FIGMA FRAME — the design has two tab rows because Offer Documents was a
   row-1 tree when it was drawn. It became a Corporate Governance section on
   2026-08-25 and, until the client's 10 September correction, its own RHP /
   DRHP / Other row REPLACED row 2, which took the other six Corporate
   Governance sections off the screen. Now both are drawn; see
   orkla_ir_section_rows().

   It reuses row 2's classes rather than getting its own, so the lit state, the
   inert state, the wrap and the mobile swipe strip all keep reaching it — the
   mobile block below matches on `.ir-header__subtabs`, and initIrScrollers()
   uses querySelectorAll, so this row scrolls and shows its edge fades with
   nothing added. What this modifier changes is only what says "one level down":
   17px instead of 19, and tight under the row above instead of 60px down the
   stack.

   SIZE AND POSITION ONLY — everything else it inherits, which since Option B
   (2026-09-21) includes the grey resting label and the tinted active tab. That
   is deliberate: row 3 is row 2 one level down, and the two would stop looking
   like one control if only the outer one were restyled.

   The note this paragraph used to carry is now the other way round. Gray/700
   was rejected here because `.is-inert` already used it to mean "page does not
   exist yet"; B spends that colour on every resting tab, so it is `.is-inert`
   that had to find another signal. See the inert block below.

   No hairline of its own. Row 2's is what separates the pair from the page, and
   a second rule 30px below the first would read as an empty strip between them.
   With it gone the link's -1px pull has nothing to land on, so that goes too.
   ------------------------------------------------------------------------- */
.ir-header__subtabs--nested {
	margin-block-start: calc(var(--sp-8) - var(--ir-stack-gap));
	border-block-end: none;
}

.ir-header__subtabs--nested .ir-header__subtab-link {
	--ir-subtab-pb: var(--sp-8);

	padding-block-start: var(--sp-8);
	margin-block-end: 0;
	font-size: 1.0625rem;   /* 17 — one step under row 2's raw 19, same reason */
}

/* ---- Inert tabs ---------------------------------------------------------
   A tab whose page does not exist yet renders as text instead of a dead link.
   The design has no state for this because in the design every page exists, so
   the treatment is ours.

   IT USED TO BE THE COLOUR, and Option B took the colour away: Gray/700 read as
   unavailable next to black labels, and after 2026-09-21 every resting label is
   Gray/700. Going a step lighter was the obvious repair and is the wrong one —
   Gray/600 is #747c8e, which measures 4.19:1 on white and so misses AA for the
   17px row-3 label it would first apply to.

   So the signal moves off colour entirely: an inert tab keeps the full-contrast
   grey and drops to regular weight, which reads as unavailable beside its
   semibold neighbours and costs nothing in contrast. There are NO inert tabs
   today — no tab target is '#' anywhere in inc/ir-nav.php — so this is the
   dormant path being kept correct rather than a visible change.
   ------------------------------------------------------------------------- */
.ir-header__tab-link.is-inert,
.ir-header__subtab-link.is-inert {
	color: var(--c-gray-700);
	font-weight: var(--fw-regular);
	cursor: default;
}

@media (prefers-reduced-motion: reduce) {
	.ir-header__tab-link,
	.ir-header__subtab-link {
		transition: none;
	}
}

/* ---- "You are here" — the trail under tab row 2 -------------------------
   NO FIGMA FRAME. Added for the Offer Documents tree, where the tab row can
   only ever light the SECTION and pages go a level deeper than that (RHP ›
   RHP AV). Built from the global breadcrumb's own treatment rather than
   invented — 16px, Gray/600 links, dark semibold current — because on those
   pages BOTH trails are on screen, one at the top of the page and one here,
   and they are the same component doing the same job. Looking like two
   different things would be the only real mistake available.

   The 16px top margin has to fight .ir-header__inner's 60px stack gap, which
   is why that gap is a property: the trail belongs to the tab strip directly
   above it, not floating midway between the tabs and the page body.

   Markup: template-parts/sections/ir-header.php.
   ------------------------------------------------------------------------- */
.ir-header__crumbs {
	margin-block-start: calc(var(--sp-16) - var(--ir-stack-gap));

	/* Lines the trail's first word up with the tab label directly above it. The
	   indent is deliberately on the nav rather than the list, so the crumb's own
	   flex gaps and wrapping are untouched. */
	padding-inline-start: var(--ir-tab-inset);
}

.ir-header__crumblist {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 4px var(--sp-8);
	margin: 0;
	padding: 0;
	list-style: none;
}

.ir-header__crumb {
	display: inline-flex;
	align-items: center;
	gap: var(--sp-8);
	font-family: var(--ff-body);
	font-size: var(--fs-m);
	line-height: var(--lh-base);
}

/* The separator is drawn, not written: the <ol> already carries the order, so
   a chevron in the markup would be a third thing saying the same as the list
   and the visual sequence. The `/ ""` is CSS alt text — it keeps the character
   out of the accessibility tree where that syntax is supported, and where it is
   not, a redundant "›" is the worst that reaches a screen reader. */
.ir-header__crumb + .ir-header__crumb::before {
	content: "\203A" / "";
	color: var(--c-gray-500);
}

.ir-header__crumb-link {
	color: var(--c-gray-600);
	font-weight: var(--fw-regular);
	text-decoration: none;
	transition: color 0.18s ease;
}

.ir-header__crumb-link:hover,
.ir-header__crumb-link:focus-visible {
	color: var(--c-primary);
	text-decoration: none;
}

/* The page you are on, drawn as a pale maroon pill (client 2026-10-19: "can we
   give some reddish tint/colour to the tab or some way to differentiate it").
   It borrows the active sub-tab's own tint and maroon rather than inventing a
   second red, so the trail reads as a continuation of the strip above it. The
   pill is fully rounded, where the sub-tab is rounded at the top only: that one
   stands on the strip's hairline, this one sits on nothing. */
.ir-header__crumb-current {
	padding: 2px var(--sp-10);
	border-radius: 999px;
	background: var(--c-primary-10);   /* #7204211a */
	color: var(--c-primary);
	font-weight: var(--fw-semibold);
}

@media (prefers-reduced-motion: reduce) {
	.ir-header__crumb-link {
		transition: none;
	}
}

/* ---- IR header — responsive ---------------------------------------------
   Gutters step 120 / 80 / 24 on the theme's breakpoints, the same ladder
   .page-heading walks, so the H1 keeps a common left edge with every other
   interior page.

   The thing that actually drives this block is tab row 2. Governance has nine
   sections and they sum to 1674 of the 1680 container, so the strip fits at
   exactly one viewport — 1920 — and wraps at 1919. Wrapping is therefore the
   normal desktop state, not a mobile edge case, and it is left to happen: two
   ragged lines still show all nine, where a scroller would hide two of them
   behind a gesture nobody makes with a mouse. The -1px pull on each link is
   harmless once wrapped — the row below has no top border for it to collide
   with. Phones flip to a swipe strip instead, where nine wrapped tabs would
   otherwise cost five lines before the page content starts.
   ------------------------------------------------------------------------- */
@media (max-width: 1280px) {
	.ir-header {
		padding-inline: 80px;
	}
}

/* Below 900 the title and the search stop sharing a row: the search is already
   at its 280 floor by here, and what is left will not hold a 56px serif H1. */
@media (max-width: 900px) {
	.ir-header__intro {
		flex-direction: column;
		align-items: stretch;
		gap: var(--sp-32);
	}

	.ir-header__search {
		flex: none;
		width: 100%;
		max-width: 600px;
	}
}

@media (max-width: 767px) {
	.ir-header {
		padding-inline: var(--sp-24);
	}

	/* 60px of air between four stacked blocks is a third of a phone screen.
	   Set through the property, not `gap` directly: .ir-header__crumbs cancels
	   this value to sit tight under the tab strip, and overriding the shorthand
	   here would leave it subtracting 60 from a 32px gap — pulling the trail up
	   into the tabs at exactly the width where the tabs became a swipe strip. */
	.ir-header__inner {
		--ir-stack-gap: var(--sp-32);

		/* Steps with the section tab's own padding below, so the trail stays lined
		   up with the tab above it at every width. */
		--ir-tab-inset: var(--sp-12);
	}

	/* Both strips become swipe strips, so the row keeps its single-line shape
	   and the page body stays above the fold. No visible scrollbar: it would
	   sit on the hairline and read as a second rule. What replaces it is the
	   edge-fade block further down plus initIrScrollers(), which also scrolls
	   the active tab into view — without those two a strip that scrolls tells
	   the user neither where they are nor that there is more. */
	.ir-header__tabs,
	.ir-header__subtabs {
		/* Declared on the SCROLLER, not on the list it used to sit on, because
		   scroll-padding below needs it too and the list is the child. It still
		   reaches the fades by inheritance. */
		--ir-fade-w: 40px;

		overflow-x: auto;
		overflow-y: hidden;
		scroll-snap-type: x proximity;
		scrollbar-width: none;
		-webkit-overflow-scrolling: touch;

		/* Keep the snap positions clear of the start fade.
		
		   Without this the two features fight. initIrScrollers() centres the
		   active tab, then `proximity` snapping is free to settle the row on a
		   nearby tab edge — and `scroll-snap-align: start` means that edge is
		   the SCROLLPORT START, which is precisely where the start fade sits.
		   On Corporate Governance it landed there every time: the active tab is
		   third of six, so the row arrives scrolled, and the pill parked at
		   offset 0.34 under 40px of white-to-transparent. Over quiet text that
		   gradient reads as "more this way"; over option B's solid maroon pill
		   it read as a white smear across the tab, which is how it was
		   reported.

		   Insetting the snapport start by the fade width moves the resting
		   place to offset 40 — the gradient's transparent end — so the pill
		   arrives whole and what fades is the neighbouring tab, which is the
		   signal the fade exists to give. It applies to swiping as well as to
		   the initial centring, so the pill cannot be parked under the fade by
		   hand either.

		   Start only. `scroll-snap-align` is `start` on every tab, so the end
		   edge is never an alignment target and padding it would describe
		   nothing. At scrollLeft 0 this changes nothing: the browser cannot
		   scroll past the beginning, and no fade is shown there anyway. */
		scroll-padding-inline-start: var(--ir-fade-w);
	}

	/* overflow-x: auto forces overflow-y from visible to auto, so the 1px the
	   active underline is pulled down by would raise a 1px vertical scrollbar.
	   overflow-y: hidden settles that, and the pull is dropped rather than
	   clipped — underline and hairline simply sit adjacent here. */
	.ir-header__subtab-link {
		margin-block-end: 0;
	}

	.ir-header__tabs::-webkit-scrollbar,
	.ir-header__subtabs::-webkit-scrollbar {
		display: none;
	}

	.ir-header__tablist,
	.ir-header__subtablist {
		flex-wrap: nowrap;
		width: max-content;
		min-width: 100%;
	}

	/* ---- Edge fades: the sign that the row continues --------------------
	   Drawn as sticky pseudo-elements INSIDE the scrolling list, not as a mask
	   on the scroll container. A mask on the container would fade that
	   container's own border-block-end along with the content, and a hairline
	   that stops short of the edge reads as a rendering fault — the same
	   objection this section already records against Figma's hug width. Sitting
	   in the list, the fades cover the tabs and leave the rule alone.

	   Each one is worth --ir-fade-w and then gives the width straight back as a
	   negative margin, so it overlays the row's first or last tab instead of
	   widening the list — which would otherwise manufacture the very overflow
	   it exists to signal. Sticky pins it to the scrollport edge; without that
	   it would scroll away with the tab it is sitting on.

	   Declared only inside this query. Above 767 the lists wrap, and a
	   zero-width flex item carrying a negative margin is one more thing that
	   could take a line of its own to no purpose.

	   Which fade shows is decided in JS, because CSS cannot ask a scroll
	   container how far it has been scrolled: initIrScrollers() toggles
	   .has-more-start / .has-more-end on the nav.
	   -------------------------------------------------------------------- */
	.ir-header__tablist::before,
	.ir-header__tablist::after,
	.ir-header__subtablist::before,
	.ir-header__subtablist::after {
		content: '';
		position: sticky;
		z-index: 1;   /* over the active pill, which is not positioned */
		flex: 0 0 var(--ir-fade-w);
		opacity: 0;
		pointer-events: none;   /* the tab underneath stays tappable */
		transition: opacity 0.2s ease;
	}

	.ir-header__tablist::before,
	.ir-header__subtablist::before {
		inset-inline-start: 0;
		margin-inline-end: calc(var(--ir-fade-w) * -1);
		background: linear-gradient(to right, var(--c-white), transparent);
	}

	.ir-header__tablist::after,
	.ir-header__subtablist::after {
		inset-inline-end: 0;
		margin-inline-start: calc(var(--ir-fade-w) * -1);
		background: linear-gradient(to left, var(--c-white), transparent);
	}

	.has-more-start .ir-header__tablist::before,
	.has-more-start .ir-header__subtablist::before,
	.has-more-end .ir-header__tablist::after,
	.has-more-end .ir-header__subtablist::after {
		opacity: 1;
	}

	.ir-header__tab,
	.ir-header__subtab {
		scroll-snap-align: start;
	}

	.ir-header__tab-link {
		padding: var(--sp-12) var(--sp-16);
	}

	/* --fs-l already drops to 18 here via the tokens, so row 1 shrinks on its
	   own; row 2's 19 is a literal and has to be brought down with it, staying
	   one step quieter than the row above. */
	.ir-header__subtab-link {
		--ir-subtab-pb: var(--sp-8);

		padding-block-start: var(--sp-10);
		font-size: var(--fs-m);   /* 16 */
	}
}

/* No width bound needed: the fades are only declared inside the swipe-strip
   query above, so these selectors match nothing wider than 767. The fade still
   appears and disappears — it is the easing that goes, not the signal. */
@media (prefers-reduced-motion: reduce) {
	.ir-header__tablist::before,
	.ir-header__tablist::after,
	.ir-header__subtablist::before,
	.ir-header__subtablist::after {
		transition: none;
	}
}

/* ==========================================================================
   Investor Relations — document / link card grid
   Figma 11067:175281 (Annual Returns, 3-up, every card a PDF) and
   11129:2355 (Stock Exchange Intimations, 2-up, PDFs and page links mixed).

   Both frames place the grid at x=120 y=1048 inside the same 1680 container
   and put 32px between cards on both axes. Neither sets a card height: 131
   falls out of the content — 24 padding + 45 title + 10 + 28 subtitle + 24
   padding — so nothing here fixes one either. A card with a two-line title
   grows, and the grid grows its row-mates with it.

   The 3-up card measures 538.67 and the 2-up 824. Both are exactly 1fr once
   the 32px gutters come out, so one rule serves both and the editor's
   `columns` choice only changes the track count.

   Top padding is --section-pad (64) standing in for Figma's 60px gap under
   the header's second tab row — the same 4px approximation this file already
   makes at every page_heading pairing. .ir-header carries no bottom padding
   precisely so these two do not stack.

   Markup: template-parts/sections/doc-cards.php.
   Responsive is a separate pass; everything below is the 1920 desktop layout.
   ========================================================================== */
.doc-cards {
	padding-block: var(--section-pad);
	padding-inline: 120px;
	background: var(--c-white);
}

.doc-cards__inner {
	max-width: 1680px;
	margin-inline: auto;
}

.doc-cards__heading {
	margin: 0 0 var(--sp-32);
	font-size: var(--fs-4xl);
}

/* ---- The FY filter bar --------------------------------------------------
   Not in Figma. The client's Aug-25 structure sheet asks for a financial-year
   dropdown on eleven of these sections, and two of the eleven for a second axis
   as well — quarters on Regulation 30, AGM / EGM / Postal Ballot on General
   Meetings.

   The pills themselves are results_table's, class for class: every
   .results-table__filter* rule is a flat class selector and its enhancer in
   main.js needs only a [data-results-select] wrapper, so this is the same
   control rather than a second one that looks like it. All this block owns is
   the row they sit in.

   Its own row, unlike results_table's, where the pills share a line with the
   section intro. There is nothing to share one with here — a doc_cards block is
   a heading and a grid, and the heading is screen-reader-only on all but a
   couple of pages, so the bar is usually the first visible thing on the
   section. Left-aligned on the container edge, which is where the grid starts.
   ------------------------------------------------------------------------- */
.doc-cards__filters {
	display: flex;
	flex-wrap: wrap;
	gap: var(--sp-16);
	margin: 0 0 var(--sp-32);
}

/* An author rule setting display beats the UA's [hidden] whatever the
   specificity, so hidden has to be restated or the bar ships visible and inert
   before its script runs. Same as .results-table__filters[hidden]. */
.doc-cards__filters[hidden] {
	display: none;
}

/* ---- Nothing matched ----------------------------------------------------
   Two selects over individual cards can empty the grid, which results_table's
   year filter cannot do — picking a year there always lands on a group.

   Centred in the grid's own area rather than left-aligned under the pills. It
   is a statement about the region that just emptied, not feedback attached to
   the control, and centred is what the theme's one existing no-results line
   does (.search-page__message on search.php). Its values are copied here rather
   than its class: that one centres itself with margin-block: auto inside the
   search page's flex column, which does nothing in a static block.

   No [hidden] restatement needed, unlike the bar above — this sets no display
   of its own, so the UA rule reaches it. */
.doc-cards__empty {
	margin: 0;
	padding-block: var(--sp-32);
	text-align: center;
	font-family: var(--ff-body);
	font-size: var(--fs-l); /* 20 */
	line-height: var(--lh-base);
	color: var(--c-gray-800);
}

.doc-cards__grid {
	display: grid;
	grid-template-columns: repeat(3, 1fr);
	gap: var(--sp-32);
	margin: 0;
	padding: 0;
	list-style: none;
}

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

/* The li is only a grid cell; the card inside it has to fill that cell's full
   height or a short card would float at the top of a tall row. */
.doc-cards__item {
	display: flex;
}

/* What the filters hide. initDocFilters() narrows the grid with the `hidden`
   attribute, and the display: flex directly above beats the UA's
   [hidden] { display: none } whatever the specificity — so without this rule the
   script sets the attribute and not one card disappears.

   Unlike .results-table__cell[hidden], which has to sit at the very end of the
   file, this one has no source-order requirement and so stays next to the rule
   it is answering. The difference is a specificity tie: there, the ≤767 block
   sets display on .results-table__cell[data-label], which scores the same as
   .results-table__cell[hidden] and so is settled by order alone. Here nothing
   qualifies .doc-cards__item with an attribute or an id, so one class plus one
   attribute wins outright from anywhere. Add such a rule and this has to move
   below it. */
.doc-cards__item[hidden] {
	display: none;
}

/* ---- Folders ------------------------------------------------------------
   Not in Figma. Subsidiary Financials carries one named legal entity's audited
   accounts per group, and a flat grid of date ranges gives a shareholder no way
   to tell whose accounts they are reading — so those cards sit inside a named,
   collapsible container. The FOLDERS note in
   template-parts/sections/doc-cards.php has the rest of the reasoning.

   Only the container is new. The cards inside are the same .doc-cards__item in
   the same .doc-cards__grid, so every card rule and every column breakpoint
   further down reaches them with nothing added — and a section with no folder
   values never matches a selector in this block at all, which is what keeps this
   off the other thirty-odd doc_cards pages.

   The nesting is read the way .edoc does it one section down — a translucent
   panel behind the same Gray/100 hairline — but a rung wider at the corner (16
   against the card's 12) and a rung darker in the fill (10% against 5%), so the
   container sits behind its contents instead of looking like one more card that
   happens to be bigger.
   ------------------------------------------------------------------------- */
.doc-cards__folder {
	padding: var(--sp-24);
	background: var(--c-gray-10);
	border: 1px solid var(--c-gray-100);
	border-radius: var(--radius-xl);   /* 16 — one rung above the card's 12 */
}

/* NO display declaration above, deliberately: the UA's [hidden] { display: none }
   is then enough for initDocFilters() to hide a folder whose every card has been
   filtered out, and this needs none of the [hidden] restatement
   .doc-cards__item does. Adding a display here changes that. */

/* Blocks stack in one column, in whatever order folders and loose grids came out
   of the template. Adjacent-sibling margins rather than a gap on the parent,
   because .doc-cards__inner is a plain block that also holds the heading, the
   filter bar and the empty-state line. */
.doc-cards__folder + .doc-cards__folder,
.doc-cards__folder + .doc-cards__grid,
.doc-cards__grid + .doc-cards__folder {
	margin-block-start: var(--sp-32);
}

.doc-cards__folder-summary {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--sp-24);
	min-height: 28px;
	cursor: pointer;
	list-style: none;   /* Firefox draws its own marker on a summary without this */
}

.doc-cards__folder-summary::-webkit-details-marker {
	display: none;
}

/* The summary is the control, so it takes the focus ring — a folder is operable
   by keyboard and has to look it. */
.doc-cards__folder-summary:focus-visible {
	outline: 2px solid var(--c-primary);
	outline-offset: 4px;
}

/* .edoc__title's treatment exactly: the sans at 24/1.4 in maroon, opting out of
   the base h3's --fs-4xl and --ls-h3 — the latter a known px/% mix-up. The card
   titles below are maroon too, but serif and bold, and it is the panel and the
   hairline that separate container from contents rather than a change of colour.
   Sizing this above 24 was the alternative and is refused: 24 is the client's own
   cap on IR card titles, and a folder heading shouting past it would undo that
   decision by the side door. */
.doc-cards__folder-title {
	margin: 0;
	font-family: var(--ff-body);
	font-weight: var(--fw-semibold);
	font-size: var(--fs-xl);   /* 24 */
	line-height: var(--lh-base);
	letter-spacing: normal;
	color: var(--c-primary);
	overflow-wrap: break-word;
}

.doc-cards__folder-chevron {
	flex: 0 0 auto;
	display: inline-flex;
	color: var(--c-primary);
	transition: transform 0.2s ease;
}

.doc-cards__folder-chevron svg {
	width: 24px;
	height: 24px;
}

/* chevron-right rotated, not a second asset — earnings-docs' trick. */
.doc-cards__folder-body[open] .doc-cards__folder-chevron {
	transform: rotate(90deg);
}

/* The hairline under the title belongs to the grid and not to the summary, so it
   exists only while the folder is open. On the summary it would leave a closed
   folder with a rule ruling off nothing. */
.doc-cards__folder .doc-cards__grid {
	margin-block-start: var(--sp-24);
	padding-block-start: var(--sp-24);
	border-block-start: 1px solid var(--c-gray-30);
}

/* ---- The card -----------------------------------------------------------
   Gray/opacity/05 on Gray/100 at 12px, which the token file already carries as
   --c-gray-05 and --c-gray-100 — the Figma values match to the byte, so none
   of this is written literally.
   ------------------------------------------------------------------------- */
.doc-card {
	display: flex;
	align-items: center;
	gap: var(--sp-24);
	flex: 1 1 auto;
	min-width: 0;
	padding: var(--sp-24) var(--sp-32);
	background: var(--c-gray-05);
	border: 1px solid var(--c-gray-100);
	border-radius: var(--radius-lg);   /* 12 */
}

.doc-card__text {
	display: flex;
	flex-direction: column;
	gap: var(--sp-10);
	flex: 1 1 auto;
	min-width: 0;
}

/* The serif in Primary/500. Three overrides matter — the base sheet gives an h3
   --fs-4xl (48) and --ls-h3, and Figma's tracking here is a flat 0; --ls-h3 is
   itself a known px/percent mix-up, so this rule opts out of it rather than
   inheriting it.

   Size is 24, NOT the 32 Figma draws (H5/Bold). Client instruction, 2026-08-06:
   the maroon document-card title reads 24 across every Investor Relations tab —
   Governance and Offer Documents alike — so the whole tree is consistent and the
   longer statutory titles ("Outstanding Overdues to Material Creditors") stop
   wrapping to three lines in a card. --fs-xl rather than a literal, and it holds
   flat at every width: --fs-2xl used to step itself down to 24 at ≤767, so the
   title was 32 on desktop and 24 on phone; now it is 24 throughout. This also
   lines it up with .edoc__title, which was already 24.
   Do not "restore" this to 32 on the next pass through the design file. */
.doc-card__title {
	margin: 0;
	font-family: var(--ff-heading);
	font-weight: var(--fw-bold);
	font-size: var(--fs-xl);   /* 24 — deliberate override of Figma's 32 */
	line-height: var(--lh-base);
	letter-spacing: normal;
	color: var(--c-primary);
	overflow-wrap: break-word;
}

/* Black, not the --c-text-body grey every other p inherits: these are dates and
   reference numbers sitting under a maroon title, and Figma sets them black. */
.doc-card__subtitle {
	margin: 0;
	font-family: var(--ff-body);
	font-weight: var(--fw-regular);
	font-size: var(--fs-l);   /* 20 */
	line-height: var(--lh-base);
	color: var(--c-black);
	overflow-wrap: break-word;
}

/* ---- The two variants ---------------------------------------------------
   Same card, call to action in a different place, which is what lets one
   partial and one DOM serve both:

     file   CTA at the card's right edge, vertically centred — a 32px eye
            above a 14px underlined "View PDF"
     link   Figma has no CTA block at all. "View →" simply occupies the
            subtitle line, 10px under the title, left aligned.

   So the row IS the file layout, and --link flips to a column reusing the same
   10px the title/subtitle pair uses. A link card that also carries a subtitle
   is not a case the design covers; it stacks subtitle then View, the only
   arrangement that keeps both.
   ------------------------------------------------------------------------- */
.doc-card--link,
.doc-card--inert {
	flex-direction: column;
	align-items: stretch;
	gap: var(--sp-10);
}

.doc-card__cta {
	display: inline-flex;
	align-items: center;
	align-self: flex-start;
	gap: var(--sp-8);
	font-family: var(--ff-body);
	font-weight: var(--fw-regular);
	font-size: var(--fs-l);   /* 20 */
	line-height: var(--lh-base);
	color: var(--c-black);
	text-decoration: none;
	transition: color 0.2s ease;
}

.doc-card__cta-icon {
	display: inline-flex;
	flex: none;
}

.doc-card__cta-icon svg {
	width: 20px;
	height: 20px;
}

/* The file CTA is a 63-wide stack in Figma: icon, 4px, label. The markup puts
   the label first so the accessible name reads "View PDF <title>" in document
   order; order: -1 lifts the icon above it visually without disturbing that.
   4px is off the spacing scale, so it stays literal. 14px is NOT off the type
   scale and no longer pretends to be: this comment predated --fs-s, which was
   added to tokens.css on 13 Aug 2026 at exactly this value. The resting underline
   is Figma's and is kept — the site reserves underlines for hover elsewhere, but
   this label is small, black and set apart from its card, and the underline is
   what marks it as the control. */
.doc-card--file .doc-card__cta {
	flex-direction: column;
	align-self: center;
	flex: none;
	gap: 4px;
	font-size: var(--fs-s);   /* 14 */
	text-align: center;
	text-decoration: underline;
}

.doc-card--file .doc-card__cta-icon {
	order: -1;
}

.doc-card--file .doc-card__cta-icon svg {
	width: 32px;
	height: 32px;
}

.doc-card__cta:hover,
.doc-card__cta:focus-visible {
	color: var(--c-primary);
	text-decoration: underline;
}

/* ---- Unresolved card ----------------------------------------------------
   A card whose page is not published yet and which has no document to fall
   back on. It has no call to action at all — the partial prints none, because
   "Coming soon" would be a promise about a statutory filing. The greyed title
   is the signal, borrowed from the inert tabs above: Gray/700 reads as clearly
   unavailable and still clears AA. Transitional in exactly the same way — each
   one turns back into a live card the moment its target is published.
   ------------------------------------------------------------------------- */
.doc-card--inert .doc-card__title {
	color: var(--c-gray-700);
}

@media (prefers-reduced-motion: reduce) {
	.doc-card__cta,
	.doc-cards__folder-chevron {
		transition: none;
	}
}

/* ---- Document cards — responsive ----------------------------------------
   Gutters walk the same 120 / 80 / 24 ladder as .ir-header directly above, so
   the cards keep a common left edge with the H1 and both tab rows.

   The column count is the real work. A card is mostly a 32px serif title, and
   the design validates that title at two widths only — 538 (3-up) and 824
   (2-up). Much under 500 and the long Stock Exchange Intimations labels start
   running to four and five lines, so the ladder chases that floor rather than
   the breakpoints:

     ≥1281   as drawn — three tracks or two, whichever the editor chose
     ≤1280   three collapses to two. At 1280 each card is then 544, within a
             few pixels of the desktop 3-up card — a density already drawn.
     ≤900    one track. Two here would be 354 and falling.

   Below 1280 the editor's `columns` choice therefore stops mattering. That is
   deliberate: it is a judgement about label length at full width, and by then
   there is no width left to judge.
   ------------------------------------------------------------------------- */
@media (max-width: 1280px) {
	.doc-cards {
		padding-inline: 80px;
	}

	.doc-cards__grid--cols-3 {
		grid-template-columns: repeat(2, 1fr);
	}
}

@media (max-width: 900px) {
	.doc-cards__grid,
	.doc-cards__grid--cols-2,
	.doc-cards__grid--cols-3 {
		grid-template-columns: 1fr;
	}
}

@media (max-width: 767px) {
	.doc-cards {
		padding-inline: var(--sp-24);
	}

	/* Figma's 24/32 pulled back a step. The title needs no rule here — it is a
	   flat 24 at every width by client instruction (see .doc-card__title), so
	   only the padding changes and the card needs no height floor of its own. */
	.doc-card {
		gap: var(--sp-16);
		padding: var(--sp-16) var(--sp-24);
	}

	.doc-cards__heading {
		margin-block-end: var(--sp-24);
	}

	/* The folder steps back with the card it holds — the same 24 → 16 — and the
	   hairline's clearance goes with it. The title needs no rule here for the
	   same reason .doc-card__title needs none: flat 24 at every width, by client
	   instruction. */
	.doc-cards__folder {
		padding: var(--sp-16);
	}

	.doc-cards__folder + .doc-cards__folder,
	.doc-cards__folder + .doc-cards__grid,
	.doc-cards__grid + .doc-cards__folder {
		margin-block-start: var(--sp-24);
	}

	.doc-cards__folder .doc-cards__grid {
		margin-block-start: var(--sp-16);
		padding-block-start: var(--sp-16);
	}

	/* ---- A lone filter pill stops stretching --------------------------------
	   The pills are .results-table__filter, so that section's own rule at this
	   width reaches them: `flex: 1 1 auto; justify-content: space-between`. There
	   it is solving real crowding — its two pills used to share a line with the
	   section intro, and side by side in 340px neither label survives, so they
	   take the row and split it.

	   Nine of the eleven flagged sections here have ONE select. Stretched, that
	   pill becomes a full-viewport row with "FY :" pinned to the far left and the
	   value to the far right — a form field, not the compact control the design
	   draws. There is no crowding to solve, because there is nothing beside it.

	   So the inherited rule is narrowed rather than fought: two pills keep it and
	   split the row exactly as results_table's do, one hugs its content and sits
	   on the grid's left edge like everything else in the section. Whitespace is
	   not a child, so :only-child reads the pill count directly.

	   It wins on specificity — (0,3,0) against (0,1,0) — not on order, which
	   matters because the rule it is narrowing lives about 2,000 lines further
	   down the file, well after this one.
	   ------------------------------------------------------------------------- */
	.doc-cards__filters > .results-table__filter:only-child {
		flex: 0 1 auto;
		justify-content: flex-start;
	}
}

/* At 320 the card is 272 wide. Take off 48 of padding, the 63-wide eye stack
   and the 16 gap, and the title is left with 145px — where "Annual Secretarial
   Compliance Report" runs to six lines beside a call to action three lines
   tall. So the file card gives up its right rail here and stacks like the link
   card, with the eye and its label side by side to keep that extra row shallow.
   The icon drops to 24 to sit on the 14px label rather than tower over it. */
@media (max-width: 479px) {
	.doc-card--file {
		flex-direction: column;
		align-items: stretch;
		gap: var(--sp-10);
	}

	.doc-card--file .doc-card__cta {
		flex-direction: row;
		align-self: flex-start;
		text-align: left;
	}

	.doc-card--file .doc-card__cta-icon svg {
		width: 24px;
		height: 24px;
	}

	/* A folder's inset is paid for by the card inside it, and the note above has
	   already spent that budget: 272 at 320, of which the title gets 145. Nested,
	   the card starts 34 narrower still. So the panel keeps its vertical rhythm
	   and gives up its sides to 12, handing 8 a side back to the card. */
	.doc-cards__folder {
		padding-inline: var(--sp-12);
	}
}

/* ==========================================================================
   EARNINGS CALL UPDATES  —  Figma 11251:1738, body 11251:2195
   --------------------------------------------------------------------------
   A financial-year strip, a 300px date rail on a pink shelf that runs off the
   left of the viewport, and a column of document cards beside it.

   Every colour, radius and step here already exists in tokens.css and none of
   it is written literally — including the shelf. Figma gives it as a flat
   #f1e6e9, which is exactly Primary/500 at 10% over white, so it is
   --c-primary-10 rather than a fourteenth pink.

   ONE MEASUREMENT IS DELIBERATELY NOT FOLLOWED. Figma draws the document
   column 1180 wide inside a 1680 container, which with the 300 rail and the 80
   gutter leaves 120px of slack on the right — an asymmetric 120/240 page
   gutter that no other section in the theme has. The column fills instead, so
   this section's right edge lines up with .ir-header and .doc-cards above and
   below it. A card whose right edge sat 120px inside everything else on the
   page would read as a bug rather than as a reading measure.

   Markup: template-parts/sections/earnings-docs.php.
   Responsive is a separate pass; everything below is the 1920 desktop layout.
   ========================================================================== */
.earnings-docs {
	/* This section was the only one in the tree with no top pad, so its year
	   strip butted straight against whatever .ir-header ended with — a second
	   hairline 51px under the section strip's, and once the "you are here" trail
	   was added, a line of crumbs wedged between the two with nothing around it.
	   Figma puts 60px here (the year strip is a member of the header's own 60px
	   stack in frame 11251:1738), and --section-pad resolves to 64 at 1440 and 48
	   below ~1066. Taking the token rather than the literal 60 is deliberate: it
	   is what .doc-cards, .video-embeds and .offer-gate all use in this position,
	   so every IR section now leaves the header the same way. */
	padding-block-start: var(--section-pad);
	padding-block-end: 100px;
	padding-inline: 120px;
	background: var(--c-white);
	/* Clips the shelf's left overhang so it meets the viewport edge without
	   putting the page into horizontal scroll. */
	overflow: hidden;
}

.earnings-docs__inner {
	max-width: 1680px;
	margin-inline: auto;
}

/* ---- The financial-year strip -------------------------------------------
   Figma builds this by duplicating the section tab row from the header
   (Frame 2085667358 → Frame 2085667359, same 1680×52, same 16/12 inset), so it
   is drawn the same way: a maroon label over a 2px maroon underline when
   active, black otherwise, with the 2px reserved by a transparent border so
   nothing shifts. The type is 20 here rather than the header's raw 19.
   ------------------------------------------------------------------------- */
.earnings-docs__years {
	margin-block-end: var(--sp-32);
	border-block-end: 1px solid var(--c-gray-30);
}

.earnings-docs__yearlist {
	display: flex;
	flex-wrap: wrap;
	margin: 0;
	padding: 0;
	list-style: none;
}

.earnings-docs__year {
	display: flex;
}

.earnings-docs__year-link {
	display: inline-flex;
	align-items: center;
	padding: var(--sp-12) var(--sp-16) var(--sp-10);
	margin-block-end: -1px;
	border-block-end: 2px solid transparent;
	font-family: var(--ff-body);
	font-weight: var(--fw-semibold);
	font-size: var(--fs-l);   /* 20 */
	line-height: var(--lh-base);
	color: var(--c-black);
	text-decoration: none;
	white-space: nowrap;
	transition: color 0.2s ease, border-color 0.2s ease;
}

.earnings-docs__year-link:hover,
.earnings-docs__year-link:focus-visible {
	color: var(--c-primary);
	text-decoration: none;
}

.earnings-docs__year-link.is-active {
	color: var(--c-primary);
	border-block-end-color: var(--c-primary);
}

/* ---- Rail + panel -------------------------------------------------------- */
.earnings-docs__body {
	position: relative;
	display: flex;
	align-items: flex-start;
	gap: var(--sp-80);
}

/* The shelf. Anchored to the rail's right edge and stretched left past the
   viewport, so it bleeds correctly at 1920 and stays put on wider screens
   where the 1680 container is centred and the rail is no longer 120 from the
   edge. Its -32px top and flush bottom are Figma's 698 against the 666 body,
   expressed as an inset so it grows with the cards instead of being pinned to
   the length this one quarter happens to be. */
.earnings-docs__body::before {
	content: "";
	position: absolute;
	z-index: 0;
	inset-block: -32px 0;
	inset-inline-start: -100vw;
	width: calc(100vw + 300px);
	background: var(--c-primary-10);
	border-start-end-radius: var(--radius-xl);   /* 16 */
}

/* No rail, no shelf: the 300px it reaches past the container is the rail's own
   width, so on a page outside Earnings Call Updates — AGM 2026 is the one today
   — it would run a cream band down the left of the documents instead of sitting
   behind anything. */
.earnings-docs__body--flat::before {
	content: none;
}

.earnings-docs__rail,
.earnings-docs__panel {
	position: relative;
	z-index: 1;
}

.earnings-docs__rail {
	flex: 0 0 300px;
	width: 300px;
	border: 1px solid var(--c-gray-100);
	/* So the active row's maroon fill is cut by the frame rather than sitting
	   proud of it — Figma has this frame clipping. */
	overflow: hidden;
}

.earnings-docs__raillist {
	margin: 0;
	padding: 0;
	list-style: none;
}

/* Figma fills the inactive rows with white at 5%, which over this tint is not
   a difference anyone can see; left transparent so the shelf reads as one
   surface. */
.earnings-docs__rail-link {
	display: block;
	padding: var(--sp-16) 20px;
	border-block-end: 1px solid var(--c-gray-30);
	font-family: var(--ff-body);
	font-weight: var(--fw-semibold);
	font-size: var(--fs-l);   /* 20 */
	line-height: var(--lh-base);
	color: var(--c-black);
	text-decoration: none;
	transition: background-color 0.2s ease, color 0.2s ease;
}

.earnings-docs__railitem:last-child .earnings-docs__rail-link {
	border-block-end: 0;
}

.earnings-docs__rail-link:hover,
.earnings-docs__rail-link:focus-visible {
	color: var(--c-primary);
	text-decoration: none;
}

.earnings-docs__rail-link.is-active {
	background: var(--c-primary);
	border-block-end-color: var(--c-primary);
	color: var(--c-white);
}

.earnings-docs__panel {
	flex: 1 1 auto;
	min-width: 0;
}

.earnings-docs__list {
	display: flex;
	flex-direction: column;
	gap: var(--sp-16);
	margin: 0;
	padding: 0;
	list-style: none;
}

.earnings-docs__item {
	display: flex;
}

/* ---- The card ------------------------------------------------------------
   Gray/opacity/10 on Gray/100 at 8px — one tint lighter and one radius step
   tighter than .doc-card, which is a different card on a different surface.
   ------------------------------------------------------------------------- */
.edoc {
	flex: 1 1 auto;
	min-width: 0;
	padding: var(--sp-16) 20px;
	background: var(--c-gray-10);
	border: 1px solid var(--c-gray-100);
	border-radius: var(--radius-md);   /* 8 */
}

.edoc--single {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--sp-24);
	min-height: 60px;
}

/* Heading/H6/Medium: the sans at 24/1.4 in Primary/500 — not the serif that
   .doc-card__title uses. Both the size and the tracking are overrides: the
   base sheet gives an h3 --fs-4xl and --ls-h3, and --ls-h3 is a known px/%
   mix-up, so this opts out of it rather than inheriting it. */
.edoc__title {
	margin: 0;
	font-family: var(--ff-body);
	font-weight: var(--fw-semibold);
	font-size: var(--fs-xl);   /* 24 */
	line-height: var(--lh-base);
	letter-spacing: normal;
	color: var(--c-primary);
	overflow-wrap: break-word;
}

.edoc__cta {
	display: inline-flex;
	align-items: center;
	gap: var(--sp-8);
	flex: 0 0 auto;
	font-family: var(--ff-body);
	font-weight: var(--fw-regular);
	font-size: var(--fs-l2);   /* 18 */
	line-height: var(--lh-base);
	color: var(--c-black);
	text-decoration: none;
	white-space: nowrap;
	transition: color 0.2s ease;
}

.edoc__cta:hover,
.edoc__cta:focus-visible {
	color: var(--c-primary);
	text-decoration: underline;
}

.edoc__cta-icon svg {
	width: 20px;
	height: 20px;
}

/* ---- The group card ------------------------------------------------------
   A real <details>, open as Figma draws it, so the chevron is a disclosure
   rather than decoration and works with no JavaScript. The chevron is
   `chevron-right` turned 90°, which saves carrying a second asset for one use.
   ------------------------------------------------------------------------- */
.edoc__group {
	display: block;
}

.edoc__summary {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--sp-24);
	min-height: 28px;
	cursor: pointer;
	list-style: none;
}

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

.edoc__summary:focus-visible {
	outline: 2px solid var(--c-primary);
	outline-offset: 4px;
}

.edoc__chevron {
	flex: 0 0 auto;
	display: inline-flex;
	color: var(--c-primary);
	transition: transform 0.2s ease;
}

.edoc__chevron svg {
	width: 24px;
	height: 24px;
}

.edoc__group[open] .edoc__chevron {
	transform: rotate(90deg);
}

.edoc__items {
	margin: var(--sp-16) 0 0;
	padding: var(--sp-16) 0 0;
	border-block-start: 1px solid var(--c-gray-30);
	list-style: none;
}

.edoc__subitem {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--sp-24);
	padding-block: 4px;
}

.edoc__sublabel {
	font-family: var(--ff-body);
	font-weight: var(--fw-medium);
	font-size: var(--fs-l);   /* 20 */
	line-height: var(--lh-base);
	color: var(--c-text);
	overflow-wrap: break-word;
}

@media (prefers-reduced-motion: reduce) {
	.earnings-docs__year-link,
	.earnings-docs__rail-link,
	.edoc__cta,
	.edoc__chevron {
		transition: none;
	}
}

/* ---- Earnings Call Updates — responsive ----------------------------------
   Gutters walk the same 120 / 80 / 24 ladder as .ir-header and .doc-cards, so
   the strip, the rail and the cards keep a common left edge with the H1.

   The rail is what drives the breakpoints. It is a fixed 300 beside a fluid
   column, so it eats a larger share of the row the narrower the page gets: at
   900 it would leave the cards 500px, and a card is a title and a call to
   action on one line. So at 900 the rail stops being a rail and becomes a
   horizontal strip of dates above the panel — still the same links to the same
   pages, just laid out the way a phone can read them.

   The shelf goes with it. Its whole point is to sit behind a left-hand column
   and run off the edge of the viewport, and there is no left-hand column any
   more; rather than re-derive the bleed for a full-width strip, the tint moves
   onto the strip itself and the pseudo-element is dropped.
   ------------------------------------------------------------------------- */
@media (max-width: 1280px) {
	.earnings-docs {
		padding-inline: 80px;
	}

	.earnings-docs__body {
		gap: var(--sp-48);
	}

	.earnings-docs__rail {
		flex-basis: 260px;
		width: 260px;
	}

	.earnings-docs__body::before {
		width: calc(100vw + 260px);
	}
}

@media (max-width: 900px) {
	.earnings-docs {
		padding-block-end: var(--section-pad);
	}

	.earnings-docs__body {
		flex-direction: column;
		gap: var(--sp-24);
	}

	.earnings-docs__body::before {
		display: none;
	}

	.earnings-docs__rail {
		flex: 0 0 auto;
		width: 100%;
		background: var(--c-primary-10);
	}

	/* Dates can outnumber the width on a phone, so the strip scrolls rather
	   than wrapping into a block that pushes the documents off the fold. */
	.earnings-docs__raillist {
		display: flex;
		overflow-x: auto;
	}

	.earnings-docs__railitem {
		flex: 0 0 auto;
	}

	.earnings-docs__rail-link {
		border-block-end: 0;
		border-inline-end: 1px solid var(--c-gray-30);
		white-space: nowrap;
	}

	.earnings-docs__railitem:last-child .earnings-docs__rail-link {
		border-inline-end: 0;
	}

	.earnings-docs__panel {
		width: 100%;
	}
}

@media (max-width: 767px) {
	.earnings-docs {
		padding-inline: var(--sp-24);
	}

	.earnings-docs__years {
		margin-block-end: var(--sp-24);
	}

	/* 24 in a card barely 300 wide turns "Intimation of Board Meeting and
	   Analyst Call" into four lines. --fs-l is already down to 18 by here
	   through the tokens, so the title shrinks with the gutter. */
	.edoc__title {
		font-size: var(--fs-l);
	}

	.edoc {
		padding: var(--sp-16);
	}

	.edoc__sublabel {
		font-size: var(--fs-m);
	}
}

/* At 320 the card is 272 wide and the padding takes 32 of it. A title and its
   call to action cannot share that line, so both card shapes stack — the same
   concession .doc-card--file makes at this width. */
@media (max-width: 479px) {
	.earnings-docs__year-link,
	.earnings-docs__rail-link {
		font-size: var(--fs-m);
	}

	.edoc--single {
		flex-direction: column;
		align-items: flex-start;
		gap: var(--sp-10);
		min-height: 0;
	}

	.edoc__subitem {
		flex-direction: column;
		align-items: flex-start;
		gap: 4px;
	}
}

/* ==========================================================================
   Investor Relations — disclaimer gate
   Figma 11363:7651 (the gate body) and 11363:7662 (its two actions), inside
   frame 11158:4840. That frame is filed under Results & Presentations, not
   Offer Documents — it is the only gate drawn in the file, and the five Offer
   Documents gates reuse it. Nothing here is Offer-Documents-specific.

   The vertical rhythm is measured, not chosen:
     label            34 tall (24px x 1.4)
     +32              to the lead block
     lead             two lines 28 tall, 16 between them
     +24              to the wall
     wall             paragraphs 24 apart, 18px x 1.4
     +32              to the actions
     actions          24 between them

   Same 120px inset and 1680 container as .doc-cards, so a gate and a card grid
   sitting on the same page share a left edge.

   The measure is deliberately NOT capped at a reading width. The wall runs the
   full 1680 in Figma, and it is a legal notice reproduced verbatim: narrowing it
   would re-flow text whose line breaks the client may have approved as drawn.
   Long lines are the tradeoff the design already made.

   Markup: template-parts/sections/offer-gate.php.
   Responsive is a separate pass; everything below is the 1920 desktop layout.
   ========================================================================== */
.offer-gate {
	padding-block: var(--section-pad);
	padding-inline: 120px;
	background: var(--c-white);
}

.offer-gate__inner {
	max-width: 1680px;
	margin-inline: auto;
}

/* Sans, not the heading serif — 24px bold uppercase in Primary/500. The one
   piece of maroon on the page, and it is the warning, not a heading. */
.offer-gate__label {
	margin: 0 0 var(--sp-32);
	font-family: var(--ff-body);
	font-size: var(--fs-xl);
	font-weight: var(--fw-bold);
	line-height: var(--lh-base);
	color: var(--c-primary);
	text-transform: uppercase;
}

/* ---- The two opening lines ---------------------------------------------- */
.offer-gate__lead {
	margin-bottom: var(--sp-24);
	font-size: var(--fs-l);          /* 20 */
	font-weight: var(--fw-semibold);
	line-height: var(--lh-base);
	color: var(--c-text);
}

.offer-gate__lead > p {
	margin: 0;
}

.offer-gate__lead > p + p {
	margin-top: var(--sp-16);
}

/* ---- The wall ------------------------------------------------------------
   18px regular. Emphasis is authored, not positional: the closing "IF YOU ARE
   NOT PERMITTED..." paragraph is bold in Figma and reaches that state through a
   <strong> in the field, so no nth-child rule has to know how many paragraphs
   a given document's disclaimer happens to have. The five gates differ.
   ------------------------------------------------------------------------- */
.offer-gate__body {
	font-size: var(--fs-l2);         /* 18 */
	line-height: var(--lh-base);
	color: var(--c-text);
}

.offer-gate__body > p {
	margin: 0;
}

.offer-gate__body > p + p {
	margin-top: var(--sp-24);
}

.offer-gate__body strong {
	font-weight: var(--fw-semibold);
}

/* ---- The two answers -----------------------------------------------------
   The theme's own button, on every page and in the dialog: .btn + .btn--primary
   to proceed, .btn + .btn--outline to decline. Everything about how they look
   lives in the shared component near the top of this file, so this block only
   says what the disclaimer does differently.

   What was here before was serif, underlined, green and red. That was LIVE's
   styling, which arrived with live's copy and looked like nothing else on the new
   site; the client asked for the site's buttons instead (2026-08-13). Colour no
   longer tells the two answers apart — fill versus outline does, which survives
   greyscale, forced colours and a printout.
   ------------------------------------------------------------------------- */
.offer-gate__actions {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--sp-16);
	margin-top: var(--sp-32);
}

.offer-gate__action {
	/* Both the design and the existing site set these two in capitals. Done here
	   rather than in the field value so the accessible name stays "I Confirm" —
	   several screen readers spell all-caps text out letter by letter — and so an
	   editor who types it in ordinary case cannot quietly break the drawing. */
	text-transform: uppercase;
	/* Taller than the site's other buttons, at every width. 22.4 of line box plus
	   the shared 7+7 comes to 38, and this is the one control on the site whose
	   whole purpose is to be pressed deliberately — 12+12 takes it past the 44px
	   minimum without touching the type. The border is shared and transparent, so
	   both answers grow by exactly the same amount. */
	padding-block: var(--sp-12);
}

/* An unresolved confirm target is a <span>, not an <a>. It keeps .btn for the
   shape — so the strip does not reflow when the document lands — but never
   --primary: a grey face with muted text and no pointer says the document is not
   there yet, which is the truth. Declining stays live either way. */
.offer-gate__action--inert {
	background: var(--c-gray-100);
	color: var(--c-text-muted);
	cursor: default;
}

/* ==========================================================================
   Investor Relations — the disclaimer as a dialog

   NO FIGMA FRAME. The popup was asked for after the design was drawn, so this
   is assembled from primitives already in the file — 12px radius, 32px inset,
   the Gray/30 hairline the tab strips use — rather than invented. If a frame
   arrives later, expect to replace this block rather than tune it.

   The notice INSIDE the dialog is not restyled: the shared partial emits the
   same .offer-gate__* elements as the page, so the label, lead, wall and the
   two answers all inherit their type from the block above. Everything here
   describes only what the dialog does differently — it is a box with a fixed
   height, so the wall scrolls and the answers stay in view, which is the one
   thing the full-page version never has to solve.

   Markup: template-parts/sections/doc-cards.php +
           template-parts/offer-gate-body.php (modal context).
   Responsive is a separate pass; below is the desktop layout.
   ========================================================================== */
.offer-gate-modal {
	/* Centred in the viewport, spelled out rather than inherited.

	   A modal dialog centres itself because the UA stylesheet gives it four zero
	   insets, a fit-content height and `margin: auto` — the auto margins take up
	   the slack on both axes. This stylesheet's `* { margin: 0 }` reset (line 12)
	   reaches dialog too and takes that one declaration away, which drops the box
	   against the top edge. Restated here in full, so it does not depend on any
	   part of a UA rule the reset has already been shown to reach.

	   `height: fit-content` is load-bearing, not decoration: with a height of auto
	   between two zero block insets the box would be solved to fill the viewport
	   and the auto margins would resolve to nothing, leaving it stretched instead
	   of centred. It has to size to its content for there to be slack to centre in
	   — max-height then caps that content. */
	position: fixed;
	inset: 0;
	margin: auto;
	height: fit-content;

	/* Reset the UA dialog: it ships a border, 1em of padding and a width that
	   shrink-wraps the text. */
	width: min(880px, calc(100vw - var(--sp-48)));
	max-height: min(720px, calc(100vh - var(--sp-48)));
	padding: 0;
	border: 0;
	border-radius: var(--radius-lg);
	background: var(--c-white);
	/* Lifts the notice off the card grid behind it. The grid is still visible
	   through the backdrop on purpose — the visitor has not left the page, and
	   the dialog closing should feel like putting something down rather than
	   navigating back. */
	box-shadow: 0 24px 64px rgb(0 0 0 / 0.24);
	overflow: hidden;   /* so the radius clips the scrolling wall */
}

/* [open] and not the bare element, because a dialog's own display: none is what
   keeps it closed — setting display on .offer-gate-modal itself would leave the
   notice sitting in the page with no way to dismiss it. */
.offer-gate-modal[open] {
	display: flex;
	flex-direction: column;
}

/* Custom properties do not reach ::backdrop in every engine that supports
   dialog, so this one colour is written literally. It is the only hardcoded
   colour in the block. */
.offer-gate-modal::backdrop {
	background: rgb(0 0 0 / 0.6);
}

.offer-gate-modal__box {
	display: flex;
	flex-direction: column;
	min-height: 0;   /* lets the scroll area shrink instead of overflowing the box */
	flex: 1;
}

/* ---- Head — which document, and the way out ------------------------------ */
.offer-gate-modal__head {
	display: flex;
	align-items: flex-start;
	justify-content: space-between;
	gap: var(--sp-16);
	/* Explicitly rigid: when the box runs out of height it is the wall that gives,
	   never the title or the way out. */
	flex: 0 0 auto;
	padding: var(--sp-32) var(--sp-32) 0;
}

/* The heading serif in near-black, matching how the gate page draws its own H1
   above the maroon label (Figma 11158:4840). Not maroon: the label directly
   beneath it is the maroon, and stacking two would spend the page's one
   warning colour twice. */
.offer-gate-modal__title {
	margin: 0;
	font-family: var(--ff-heading);
	font-size: var(--fs-xl);      /* 24 — the IR card-title size, which is what was clicked */
	font-weight: var(--fw-bold);
	line-height: var(--lh-base);
	color: var(--c-text);
}

.offer-gate-modal__close {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	flex: 0 0 auto;
	width: 40px;
	height: 40px;
	margin: -8px -8px 0 0;   /* optical: pulls the 40px hit area back to the 32 inset */
	padding: 0;
	border: 0;
	border-radius: 50%;
	background: none;
	color: var(--c-gray-600);
	cursor: pointer;
	transition: color 0.18s ease, background-color 0.18s ease;
}

.offer-gate-modal__close:hover,
.offer-gate-modal__close:focus-visible {
	color: var(--c-primary);
	background-color: var(--c-gray-10);
}

/* orkla_icon() prints the SVG inside a <span class="icon …">, so the size goes
   on the svg — same shape as .doc-card__cta-icon. */
.offer-gate-modal__close-icon {
	display: inline-flex;
	flex: none;
}

.offer-gate-modal__close-icon svg {
	display: block;
	width: 24px;
	height: 24px;
}

/* ---- The wall scrolls, the answers do not --------------------------------
   Label, lead and wall scroll together as one region. Splitting them — pinning
   the lead and scrolling only the wall — would leave a phone reading the notice
   through a slot, since the lead alone runs to two paragraphs.
   ------------------------------------------------------------------------- */
.offer-gate-modal .offer-gate__scroll {
	min-height: 0;
	overflow-y: auto;
	overscroll-behavior: contain;   /* stops the page behind from scrolling at the ends */
	padding: var(--sp-24) var(--sp-32);
}

/* 32 below the label is right on a full page; inside a fixed box it is height
   the wall needs. */
.offer-gate-modal .offer-gate__label {
	margin-block-end: var(--sp-16);
}

/* The answers sit below the scroll region, always visible, separated by the
   same hairline the tab strips use. The page version's 32px top margin becomes
   padding on a bordered strip. */
.offer-gate-modal .offer-gate__actions {
	flex: 0 0 auto;
	margin-top: 0;
	padding: var(--sp-24) var(--sp-32);
	border-block-start: 1px solid var(--c-gray-30);
}

/* ---- Entry variant — a door, so no document to name ----------------------
   The entry gate (Orkla ASA Historical Results, client instruction of
   2026-08-27) guards a whole page rather than a file, so nothing has been
   clicked yet and there is no title to write. Its head holds the way out and
   nothing else, which needs two things said:

   The × has to be told to sit right. __head is space-between, which puts a lone
   child on the LEFT — it would land under the wall's left edge, reading as part
   of the notice rather than as the way out of it.

   And the 32 above the label was spacing under a title that is now gone.
   Halving it keeps the notice starting where the eye expects instead of a
   third of the way down the box. Both phone queries below already drop this to
   16 for their own reasons, so this rule is deliberately desktop-shaped and
   they need no entry-specific override.
   ------------------------------------------------------------------------- */
.offer-gate-modal__head--bare {
	justify-content: flex-end;
}

.offer-gate-modal--entry .offer-gate__scroll {
	padding-block-start: var(--sp-16);
}

/* Follows body.nav-open, the convention the mobile drawer already uses: the
   class is toggled in JS rather than derived with :has(), so the lock lands and
   lifts on exactly the same event as the dialog. */
body.gate-open {
	overflow: hidden;
}

@media (prefers-reduced-motion: reduce) {
	.offer-gate-modal__close {
		transition: none;
	}
}

/* ==========================================================================
   Investor Relations — statutory AV embeds

   NO FIGMA FRAME. The two AV pages behind the gates were never drawn, so this
   is built from the same primitives .doc-cards uses — 1680 container, 120px
   inset, 32px gutter, 12px radius — rather than invented. If a frame appears
   later, expect to replace this block rather than tune it.

   Markup: template-parts/sections/video-embeds.php.
   ========================================================================== */
.video-embeds {
	padding-block: var(--section-pad);
	padding-inline: 120px;
	background: var(--c-white);
}

.video-embeds__inner {
	max-width: 1680px;
	margin-inline: auto;
}

.video-embeds__heading {
	margin: 0 0 var(--sp-32);
	font-size: var(--fs-4xl);
}

.video-embeds__grid {
	display: grid;
	grid-template-columns: repeat(2, 1fr);
	gap: var(--sp-32);
	margin: 0;
	padding: 0;
	list-style: none;
}

.video-embeds__grid--cols-1 {
	grid-template-columns: 1fr;
	max-width: 824px;   /* the 2-up card width, so one video is not a billboard */
}

/* aspect-ratio rather than the padding-top hack: the iframe is the only child
   and every browser the project supports has had it for years. */
.video-embeds__frame {
	position: relative;
	aspect-ratio: 16 / 9;
	overflow: hidden;
	background: var(--c-gray-100);
	border-radius: var(--radius-lg);
}

.video-embeds__frame iframe {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	border: 0;
}

/* --------------------------------------------------------------------------
   The consent gate that sits over an unloaded frame.

   Printed visible and hidden by JS, never the reverse — see the template. So
   these rules describe the pre-consent state, and there is no "shown" class to
   hunt for: [hidden] is the whole mechanism.

   No YouTube poster image behind it. i.ytimg.com is another Google request, and
   a thumbnail would leak exactly what the gate exists to hold back, so the card
   is drawn from tokens. Dark rather than the grey the empty frame already has,
   because it needs to read as a deliberate surface and not as a failed load.
   -------------------------------------------------------------------------- */
.video-embeds__gate {
	position: absolute;
	inset: 0;
	display: grid;
	place-items: center;
	padding: var(--sp-24);
	background: var(--c-primary-900);
	color: var(--c-white);
	text-align: center;
}

.video-embeds__gate[hidden] {
	display: none;   /* [hidden] loses to display:grid without this. */
}

.video-embeds__gate-inner {
	max-width: 46ch;
}

.video-embeds__gate-icon {
	width: 40px;
	height: 40px;
	margin-bottom: var(--sp-12);
	color: var(--c-primary-100);
}

.video-embeds__gate-title {
	margin: 0 0 var(--sp-8);
	font-size: var(--fs-l2);
	font-weight: var(--fw-semibold);
	line-height: var(--lh-base);
}

.video-embeds__gate-body {
	margin: 0 0 var(--sp-16);
	font-size: var(--fs-m);
	line-height: var(--lh-base);
	color: var(--c-white);
	opacity: 0.82;
}

.video-embeds__gate-actions {
	display: flex;
	flex-wrap: wrap;
	gap: var(--sp-12);
	justify-content: center;
}

/* Both buttons carry the same weight on purpose. "Load this video" is filled
   only because it is the thing the visitor came to the page for — the standing
   permission is never made to look like the easier answer. */
.video-embeds__gate-btn {
	padding: 10px 20px;
	font: inherit;
	font-size: var(--fs-m);
	font-weight: var(--fw-semibold);
	color: var(--c-white);
	cursor: pointer;
	background: transparent;
	border: 1px solid var(--c-white);
	border-radius: var(--radius-sm);
}

.video-embeds__gate-btn--solid {
	color: var(--c-primary-900);
	background: var(--c-white);
}

.video-embeds__gate-btn:hover {
	background: var(--c-white-20);
}

.video-embeds__gate-btn--solid:hover {
	background: var(--c-cream);
}

.video-embeds__gate-btn:focus-visible,
.video-embeds__gate-link:focus-visible {
	outline: 2px solid var(--c-cream);
	outline-offset: 2px;
}

.video-embeds__gate-note {
	margin: var(--sp-16) 0 0;
	font-size: var(--fs-s);
	line-height: var(--lh-base);
	color: var(--c-white);
	opacity: 0.72;
}

.video-embeds__gate-link {
	padding: 0;
	font: inherit;
	color: inherit;
	text-decoration: underline;
	cursor: pointer;
	background: none;
	border: 0;
}

/* Under about 420px of card width the copy would push the buttons out of a
   16:9 box, so the explanation goes and the offer stays. The title still says
   what the card is, and the full wording is one tap away in the preferences. */
@media (max-width: 600px) {
	.video-embeds__gate-body,
	.video-embeds__gate-note {
		display: none;
	}

	.video-embeds__gate-icon {
		width: 28px;
		height: 28px;
	}
}

/* The label repeats the iframe's title deliberately — the title is only exposed
   to assistive tech, and a sighted visitor still has to be told which of two
   otherwise identical players is the Hindi one. */
.video-embeds__label {
	margin: var(--sp-16) 0 0;
	font-size: var(--fs-l2);
	font-weight: var(--fw-semibold);
	line-height: var(--lh-base);
	color: var(--c-text);
}

/* ==========================================================================
   Responsive — disclaimer gate + AV embeds
   Both walk the same 120 / 80 / 24 inset ladder as .ir-header and .doc-cards, so
   a gate, a card grid and the banner above them keep one left edge at every
   width. The type mostly scales itself: --fs-4xl and --fs-2xl are stepped down
   by the tokens at 1280 and 767, so only the sizes the tokens leave alone are
   touched here.
   ========================================================================== */
@media (max-width: 1280px) {
	.offer-gate,
	.video-embeds {
		padding-inline: 80px;
	}
}

/* Two 16:9 players side by side stop being watchable before they stop fitting:
   at 900 each is 418 wide and 235 tall, which is where a talking head with
   burnt-in Hindi subtitles starts costing you the subtitles. Same collapse
   point as .doc-cards, so a card grid and a video grid on one page break
   together rather than one after the other. */
@media (max-width: 900px) {
	.video-embeds__grid {
		grid-template-columns: 1fr;
	}
}

@media (max-width: 767px) {
	.offer-gate,
	.video-embeds {
		padding-inline: var(--sp-24);
	}

	/* --fs-xl is one of the sizes the tokens do NOT step down, so 24px bold
	   uppercase would still be here at 320 — where "DISCLAIMER – IMPORTANT"
	   takes three lines. --fs-l is already 18 by this breakpoint. */
	.offer-gate__label {
		margin-block-end: var(--sp-24);
		font-size: var(--fs-l);
	}

	/* The lead and the wall both land on 18 here, because --fs-l steps down to
	   18 and --fs-l2 never moves. The hierarchy survives on weight alone
	   (semibold against regular), which is the right thing to lose first: the
	   wall must not drop below 18 on a phone, and the lead outgrowing it would
	   make the opening lines the largest thing on the page. */

	.video-embeds__heading {
		margin-block-end: var(--sp-24);
	}

	/* No rule for .offer-gate__action any more. It used to gain padding here to
	   reach a 44px tap target, back when the two answers were bare text at 24px;
	   they are buttons now and clear it at every width, so the target no longer
	   depends on the breakpoint. */
}

/* Stacked deliberately rather than left to flex-wrap. At 375 the two buttons very
   nearly fit on one line, so wrapping would decide the layout on a few pixels of
   font rendering — and "I CONFIRM" sitting beside a wrapped "I DO NOT / CONFIRM"
   is a genuinely misleading way to draw a legal choice. They stretch to the full
   width once stacked, because two buttons of different widths left-aligned in a
   column read as a hierarchy, and these are equals. */
@media (max-width: 479px) {
	.offer-gate__actions {
		flex-direction: column;
		align-items: stretch;
	}

	.offer-gate__action {
		justify-content: center;
	}
}

/* ==========================================================================
   Responsive — the disclaimer as a dialog

   The box needs almost nothing: width and height are already min() against the
   viewport, so it fits every width down to 320 without a breakpoint, and the
   notice inside inherits the stepped-down type from the block above. What is
   left is the inset ladder, which cannot follow .offer-gate's 120 / 80 / 24 —
   the dialog is 880 wide at most, so its padding steps 32 / 24 rather than
   tracking the page gutter.

   It stays a centred box on a phone rather than becoming a bottom sheet. A sheet
   is a different pattern with different gestures, and inventing one here — for a
   layout that is not drawn anywhere — would be a bigger claim than the
   requirement makes.
   ========================================================================== */
@media (max-width: 767px) {
	.offer-gate-modal {
		/* 24 either side rather than 24 total, which is the same inset the page
		   sections drop to at this width — so the dialog's edges line up with the
		   content behind it instead of nearly lining up. */
		width: calc(100vw - var(--sp-48));
		max-height: calc(100vh - var(--sp-48));
	}

	.offer-gate-modal__head {
		padding: var(--sp-24) var(--sp-24) 0;
	}

	.offer-gate-modal .offer-gate__scroll {
		padding: var(--sp-16) var(--sp-24);
	}

	.offer-gate-modal .offer-gate__actions {
		padding: var(--sp-16) var(--sp-24);
	}

	/* 44px, matching the tap target the two answers get at this width from
	   .offer-gate__action's padding-block. Declining by closing should not be the
	   fiddliest way to decline. */
	.offer-gate-modal__close {
		width: 44px;
		height: 44px;
		margin: -10px -10px 0 0;
	}
}

/* Landscape on a phone is the one shape that genuinely squeezes this: at 375
   tall the box gets 327, and head plus a stacked actions strip can leave the
   wall under 120px. Trimming the vertical padding buys back 32 of it. The wall
   scrolls either way — this is about how much of it you can see at once. */
@media (max-height: 480px) {
	.offer-gate-modal__head {
		padding-block-start: var(--sp-16);
	}

	.offer-gate-modal .offer-gate__scroll {
		padding-block: var(--sp-16);
	}

	.offer-gate-modal .offer-gate__actions {
		padding-block: var(--sp-12);
	}
}

/* ==========================================================================
   Investor Relations — Investor Contact
   Figma 11083:177582 (person + company), 11083:178097 (registrar) and
   11083:178205 (the ODR footnote row).

   Two 1680-wide cards in Gray/opacity/05 at 12px, then a bare 28px row of text
   with no card around it. The cards are the SAME fill as .doc-card but carry no
   border: sampling the design steps straight from page white to the card fill
   with nothing between, so the hairline that section has is genuinely absent
   here rather than too faint to see. The 80px glyph top-right is Primary/500 at
   exactly 0.20 on all three channels, which is --c-primary-20 — so it is a
   colour, not an opacity, and the icons' fill="currentColor" carries it.

   Top padding is --section-pad (64) standing in for Figma's 60px gap under the
   header's tab row — the same 4px approximation this file makes at every such
   pairing, and .ir-header carries no bottom padding precisely so the two do not
   stack. Bottom is a literal 120: measured, and unlike .doc-cards' 64 this
   section ends on a footnote rather than a card, so the extra room is what keeps
   that last row reading as an aside instead of a third card.

   Four places Figma hand-spaces the same relationship two ways, normalised here
   to the 8px scale rather than reproduced: contact rows sit 16 apart in card 1
   and 12 in card 2 (-> 16); name-to-role is 4 but eyebrow-to-company is 8
   (-> 8); company-to-rows is 8 in card 1 and 20 in card 2 (-> 8); and the badge
   is 35 from the top in card 1, 21 in card 2 (-> 24, the card's own padding, so
   it sits on the head's top line). Nothing lands more than 4px off the design
   except the badge and card 2's row gap.

   Markup: template-parts/sections/investor-contact.php.
   Responsive is a separate pass; everything below is the 1920 desktop layout.
   ========================================================================== */
.investor-contact {
	padding-block: var(--section-pad) 120px;
	padding-inline: 120px;
	background: var(--c-white);
}

.investor-contact__inner {
	display: flex;
	flex-direction: column;
	/* 60 between both card pairs and again before the footnote row — the one gap
	   Figma is consistent about, so it is written as measured. */
	gap: 60px;
	max-width: 1680px;
	margin-inline: auto;
}

/* ---- The card -----------------------------------------------------------
   A flex column rather than block flow, so the one `gap` serves both shapes:
   with a person it spaces head / rule / body, and without one it spaces head /
   body directly. That is why the rule below carries no margin of its own —
   two 24s here stand in for Figma's 17-above / 19-below, and the same 24
   becomes card 2's head-to-rows gap where the design says 20.
   ------------------------------------------------------------------------- */
.investor-contact__card {
	position: relative;
	display: flex;
	flex-direction: column;
	gap: var(--sp-24);
	padding: var(--sp-24) var(--sp-48);
	background: var(--c-gray-05);
	border-radius: var(--radius-lg);
}

/* Decorative and out of flow, so it can never push the head down or wrap. The
   40px inset is measured (1680 - 1560 - 80) and has no token; pointer-events
   are off so it cannot swallow a click meant for the card's links. */
.investor-contact__badge {
	position: absolute;
	inset-block-start: var(--sp-24);
	inset-inline-end: 40px;
	display: block;
	color: var(--c-primary-20);
	pointer-events: none;
}

.investor-contact__badge svg {
	display: block;
	width: 80px;
	height: 80px;
}

/* ---- Head — whoever leads the card --------------------------------------- */
.investor-contact__head {
	display: flex;
	flex-direction: column;
	gap: var(--sp-8);
	/* Only the head can collide with the badge: 72 clears it (80 wide at a 40
	   inset, against this card's 48 gutter) and 32 more keeps a long name from
	   touching it. The body sits below the badge in both card shapes, so it is
	   deliberately not indented — an address should use the full width. */
	padding-inline-end: 104px;
}

/* Figma 62 = --fs-4xl (48) x --lh-heading (1.3). */
.investor-contact__name {
	margin: 0;
	font-family: var(--ff-heading);
	font-size: var(--fs-4xl);
	line-height: var(--lh-heading);
	color: var(--c-primary);
}

/* Figma 28 = --fs-l (20) x --lh-base (1.4) — the role, the small grey label
   above a registrar, and every contact row are all this one size. */
.investor-contact__role,
.investor-contact__eyebrow {
	margin: 0;
	font-size: var(--fs-l);
	line-height: var(--lh-base);
	color: var(--c-gray-800);
}

/* Figma 45 = --fs-2xl (32) x --lh-base (1.4). One rule for both levels: the
   company is an h2 when it leads the card and an h3 when a person does, and it
   should look identical either way — the heading level is there for the
   document outline, not for a size change. */
.investor-contact__org {
	margin: 0;
	font-family: var(--ff-heading);
	font-size: var(--fs-2xl);
	line-height: var(--lh-base);
	color: var(--c-text);
}

/* Present only when a person is, so it needs no modifier — see the template.
   Gray/100, the same hairline .doc-card uses for its border; inset to the
   content width by the card's own padding rather than by anything here. */
.investor-contact__rule {
	height: 1px;
	background: var(--c-gray-100);
}

/* ---- Body — the company and its contact rows ----------------------------- */
.investor-contact__body {
	display: flex;
	flex-direction: column;
	gap: var(--sp-8);
}

.investor-contact__rows {
	display: flex;
	flex-direction: column;
	gap: var(--sp-16);
	margin: 0;
	padding: 0;
	list-style: none;
}

/* Same icon-and-value geometry as .contact-info__row, and for the same reason:
   Figma puts a 24px glyph at x=0 and the value at x=32, so the gap is 8 and the
   icon is nudged 2px down to sit on the 28px line box. */
.investor-contact__row {
	display: flex;
	align-items: flex-start;
	gap: var(--sp-8);
}

.investor-contact__icon {
	flex: 0 0 auto;
	display: inline-flex;
	padding-top: 2px;
	color: var(--c-primary);
}

.investor-contact__icon svg {
	display: block;
	width: 24px;
	height: 24px;
}

.investor-contact__row-text {
	min-width: 0;
	font-size: var(--fs-l);
	line-height: var(--lh-base);
	color: var(--c-gray-800);
	/* A registrar's URL is one long unbreakable token; without this it widens
	   the card past its column instead of wrapping. */
	word-break: break-word;
}

/* Phones, emails and the registrar's site are links that do not announce
   themselves with an underline, unlike the footnote row below. That is not an
   oversight: each one is already labelled by its icon and is recognisable as a
   phone number, an address or a URL, so the row reads as data rather than as
   prose with links buried in it. Underlining four values per card would make
   the card look like a list of footnotes. */
.investor-contact__link {
	color: inherit;
	text-decoration: none;
	transition: color 0.2s ease;
}

.investor-contact__link:hover,
.investor-contact__link:focus-visible {
	color: var(--c-primary);
	text-decoration: underline;
	text-underline-offset: 3px;
}

/* ---- The ODR footnote row ------------------------------------------------
   Figma sets the left text at x=0 and the right at x=1256 in a 1680 box, i.e.
   pinned to both edges — space-between, not a grid. It wraps rather than
   compresses, and once wrapped the right-hand text keeps its own alignment so
   the two never look like one ragged paragraph.
   ------------------------------------------------------------------------- */
.investor-contact__odr {
	display: flex;
	flex-wrap: wrap;
	justify-content: space-between;
	gap: var(--sp-16) var(--sp-32);
}

.investor-contact__odr-doc,
.investor-contact__odr-external {
	margin: 0;
	font-size: var(--fs-l);
	line-height: var(--lh-base);
	color: var(--c-gray-800);
}

.investor-contact__odr-external {
	text-align: right;
}

/* Underlined in the design and left underlined here — these two sit in running
   text with no icon to mark them, which is exactly the case the card rows are
   not. Colour on hover only; the underline is already the affordance. */
.investor-contact__odr-link {
	color: inherit;
	text-decoration: underline;
	text-underline-offset: 3px;
	transition: color 0.2s ease;
}

.investor-contact__odr-link:hover,
.investor-contact__odr-link:focus-visible {
	color: var(--c-primary);
}

/* ---- Investor Contact — responsive ---------------------------------------
   Type needs nothing here. Every size in this section is a token that already
   steps in tokens.css — --fs-4xl 48/40/32 for the name, --fs-2xl 32/24 for the
   company, --fs-l 20/18 for the role, the label and every contact row — so the
   card re-proportions on its own and the only work left is geometry.

   Gutters walk the usual 120 / 80 / 24 ladder so the cards keep a common left
   edge with the H1 and both tab rows above them. Trailing space steps with
   them: the 120 that keeps the footnote row from crowding the footer is a
   desktop judgement, not a phone one.

   What actually needs deciding is the badge. It is decoration with
   aria-hidden, and it costs the head real width — 72px of clearance at desktop.
   So it shrinks once (80 -> 48) and then goes away entirely below 480, where a
   320-wide card leaves the head only 224px and a quarter of that is too much to
   spend on an ornament. Nothing is lost when it goes: the person's name and the
   company's name already say which kind of card this is.
   ------------------------------------------------------------------------- */
@media (max-width: 1280px) {
	.investor-contact {
		padding-inline: 80px;
		padding-block-end: 80px;
	}
}

/* The two footnote texts are drawn 468 and 424 wide in a 1680 box, so they run
   out of room together at roughly 1084 and wrap on their own between here and
   there — where the right-hand one, alone on its line, still reads as a pinned
   aside. Below 900 that stops being true: stack them explicitly and let the
   second one read left like the first, rather than leaving a right-aligned
   paragraph sitting under a left-aligned one on a narrow screen. */
@media (max-width: 900px) {
	.investor-contact__odr {
		flex-direction: column;
		gap: var(--sp-12);
	}

	.investor-contact__odr-external {
		text-align: left;
	}
}

@media (max-width: 767px) {
	.investor-contact {
		padding-inline: var(--sp-24);
		padding-block-end: var(--sp-64);
	}

	/* 60px between stacked cards is a third of a phone screen — the same call
	   .ir-header__inner makes at this width, to the same value. */
	.investor-contact__inner {
		gap: var(--sp-32);
	}

	/* Figma's 24/48 pulled back a step, matching what .doc-card does here. */
	.investor-contact__card {
		gap: var(--sp-16);
		padding: var(--sp-16) var(--sp-24);
	}

	.investor-contact__badge {
		inset-block-start: var(--sp-16);
		inset-inline-end: var(--sp-16);
	}

	.investor-contact__badge svg {
		width: 48px;
		height: 48px;
	}

	/* 40 clears the smaller glyph against the smaller gutter (48 + 16 inset,
	   less the card's 24), plus 16 of gap. */
	.investor-contact__head {
		padding-inline-end: 56px;
	}
}

@media (max-width: 479px) {
	.investor-contact__badge {
		display: none;
	}

	/* Nothing left to clear, so the head takes the full card width — which is
	   the whole reason the badge goes. */
	.investor-contact__head {
		padding-inline-end: 0;
	}
}

/* ==========================================================================
   RESULTS TABLE — Results & Presentations (IR tree 3)

   Measured on Frame 11067:176147 (Orkla India, four document columns) and
   11363:7216 (Orkla ASA, two): the year header button 11072:176909, the column
   header row 11072:176917, the two data-row states 11083:178272 (default) and
   11072:176923 (hover), the hover reveal 11129:2336, and the filter pair
   11071:176621.

   The only IR body drawn as a table rather than a grid of cards, because its
   cells are wordless 32px icons and the column header is the only thing that
   says what each one opens. Everything here hangs off a real <table>, so that
   association survives with no ARIA — see the docblock in
   template-parts/sections/results-table.php.

   Two divergences from the frames, both deliberate and both noted at the rule
   that makes them:
     · the icon columns are hand-placed in the design, not on a grid
     · the "View" reveal is 10px there, which is not a legible size
   ========================================================================== */
.results-table {
	/* Figma's own hairlines. Neither is on the token list — the border colours
	   there are opaque greys, and these are alpha rules that have to sit over
	   two different row backgrounds without banding at the joins. Declared once
	   here rather than repeated at the four rules that draw them. */
	--rt-rule: rgba(0, 0, 0, 0.08);
	--rt-rule-soft: rgba(0, 0, 0, 0.06);

	/* The title column, fixed. 313px in the frame; the four icon columns then
	   split what is left, which is where the design and this part company. */
	--rt-title-col: 313px;

	padding-block: var(--section-pad);
	padding-inline: 120px;
	background: var(--c-white);
}

.results-table__inner {
	max-width: 1680px;
	margin-inline: auto;
}

/* ---- The line above the table -------------------------------------------
   Frame 2085667361, 1680×52: the intro sits left and the two selectors right,
   on one line, 32px clear of the table. Same standfirst treatment as
   .ir-header__standfirst, so the two lines of introductory copy on this page
   read as the same voice. */
.results-table__bar {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: var(--sp-16) var(--sp-24);
	margin-block-end: var(--sp-32);
}

.results-table__intro {
	margin: 0;
	max-width: 60ch;
	font-family: var(--ff-body);
	font-weight: var(--fw-regular);
	font-size: var(--fs-l2);
	line-height: var(--lh-base);
	color: var(--c-text-muted);
}

/* ---- Filters ------------------------------------------------------------
   Two 52px pills, "Year : All" and "Type : All". They ship hidden and main.js
   unhides them, because filtering is the one thing here that does not work
   without JavaScript: with it off every row is already visible, which is the
   correct unfiltered state, and a select that narrows nothing is worse than no
   select at all. */
.results-table__filters {
	display: flex;
	flex-wrap: wrap;
	gap: var(--sp-16);
	margin: 0;
}

/* An author rule setting display beats the UA's [hidden] whatever the
   specificity, so hidden has to be restated here or the filters ship visible
   and inert. */
.results-table__filters[hidden] {
	display: none;
}

.results-table__filter {
	position: relative; /* The generated listbox hangs off this. */
	display: flex;
	align-items: center;
	gap: var(--sp-8);
	margin: 0;
	padding: var(--sp-12) var(--sp-16);
	border: 1px solid var(--c-gray-500);
	border-radius: var(--radius-md);
	background: var(--c-white);
}

.results-table__filter:focus-within,
.results-table__filter:has(> [aria-expanded='true']) {
	border-color: var(--c-primary);
}

.results-table__filter-label {
	font-family: var(--ff-body);
	font-weight: var(--fw-regular);
	font-size: var(--fs-l);
	line-height: var(--lh-base);
	color: var(--c-gray-800);
	white-space: nowrap;
}

/* The first <select> the theme styles. The pill is drawn by the wrapper above,
   so the control itself is stripped back to its text and the chevron beside it
   is a real icon in the markup — the theme has no data-URI or CSS-mask
   convention for arrows, and inventing one for two selects would be a second
   way of drawing an icon that already has a pipeline (orkla_icon). */
.results-table__select {
	appearance: none;
	margin: 0;
	padding: 0;
	border: 0;
	background: none;
	font-family: var(--ff-body);
	font-weight: var(--fw-semibold);
	font-size: var(--fs-l);
	line-height: var(--lh-base);
	color: var(--c-text);
	cursor: pointer;
}

/* Pointing down, drawn with the one chevron the theme ships and turned a
   quarter — the same thing the year disclosure below and .edoc__chevron already
   do with it, rather than a second asset that differs only in rotation. */
.results-table__filter-chevron {
	flex: 0 0 auto;
	display: inline-flex;
	color: var(--c-gray-800);
	transform: rotate(90deg);
	transition: transform 0.2s ease; /* It turns up when the list opens. */
	pointer-events: none; /* The chevron is part of the control, not a second target. */
}

.results-table__filter-chevron svg {
	width: 24px;
	height: 24px;
}

/* ---- The drawn dropdown -------------------------------------------------
   main.js hides the <select> and puts this button and list in its place. The
   reason is that a native select can be styled shut but not open: the list is
   the operating system's, so on macOS these two pills dropped a dark grey menu
   with a system tick in it — a control belonging to nothing else on the page.
   The select stays as the model; everything below is only its mirror.
   The pill itself is unchanged, which is the point: closed, this is the same
   52px box it always was, and only the open state is new. */
.results-table__select[hidden] {
	display: none;
}

.results-table__trigger {
	display: flex;
	align-items: center;
	gap: var(--sp-8);
	margin: 0;
	padding: 0;
	border: 0;
	background: none;
	font-family: var(--ff-body);
	font-weight: var(--fw-semibold);
	font-size: var(--fs-l);
	line-height: var(--lh-base);
	color: var(--c-text);
	text-align: left;
	cursor: pointer;
}

/* No focus rule here on purpose: the global :focus-visible ring (line 85) is the
   keyboard indicator, and the pill's maroon border tracks focus-within as a
   second, quieter signal. Overriding either would leave the one control on this
   page that has to be operated blind without an outline. */

/* Down when shut, up when open — the same quarter-turn the year disclosures
   make, so the two chevrons on the page never disagree about direction. */
.results-table__trigger[aria-expanded='true'] .results-table__filter-chevron {
	transform: rotate(-90deg);
}

.results-table__list {
	position: absolute;
	z-index: 20; /* Over the table's sticky-ish header cells and the year rules. */
	top: calc(100% + var(--sp-8));
	left: -1px; /* Lines the panel edge up with the pill's, border included. */
	/* Hugs its longest option — the Type list is wider than its pill, the Year
	   list narrower, and both are correct. The viewport clamp is a floor, not a
	   look: past it the labels wrap rather than being clipped, because these come
	   from ACF and a truncated column name is a lie about the data. */
	min-width: calc(100% + 2px);
	width: max-content;
	max-width: calc(100vw - var(--sp-32));
	list-style: none;
	margin: 0;
	padding: var(--sp-8) 0;
	border: 1px solid var(--c-gray-200);
	border-radius: var(--radius-md);
	background: var(--c-white);
	box-shadow: 0 16px 33px -2px rgba(28, 39, 49, 0.12);
}

.results-table__list[hidden] {
	display: none;
}

.results-table__option {
	padding: var(--sp-8) var(--sp-16);
	font-family: var(--ff-body);
	font-weight: var(--fw-regular);
	font-size: var(--fs-l);
	line-height: var(--lh-base);
	color: var(--c-text);
	cursor: pointer;
	transition: background-color 0.15s ease, color 0.15s ease;
}

/* Hover and the keyboard's active option are drawn identically on purpose: the
   arrow keys move a highlight, and a visitor who cannot see two different
   highlights has no way to tell which one Enter will take. [data-active] is set
   by main.js, which also names it through aria-activedescendant. */
.results-table__option:hover,
.results-table__option[data-active] {
	background: var(--c-primary-05);
	color: var(--c-primary);
}

/* The chosen one, which is also what the pill is showing. No tick: the theme
   ships no check icon, and adding one asset for one state is not worth it while
   aria-selected already carries this to a screen reader. */
.results-table__option[aria-selected='true'] {
	font-weight: var(--fw-semibold);
	color: var(--c-primary);
}

/* ---- The container ------------------------------------------------------
   Figma's Container is 1680 wide with its children inset by 1px on all four
   sides and clipping to an inherited radius, i.e. a 1px border and a rounded
   box. The radius value is not readable off the node, so it takes the theme's
   default 8px. */
.results-table__groups {
	border: 1px solid var(--rt-rule);
	border-radius: var(--radius-md);
	overflow: hidden;
}

/* ---- Year groups -------------------------------------------------------- */
.results-table__year-head {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--sp-12);
	/* 20 top, 21 bottom: the frame's own asymmetry, kept rather than tidied to
	   20/20, which would shorten the button by a pixel against every other
	   measurement taken off it. */
	padding: 20px 48px 21px;
	background: var(--c-gray-05);
	border-block-end: 1px solid var(--rt-rule);
	cursor: pointer;
	list-style: none;
}

.results-table__year-head::-webkit-details-marker {
	display: none;
}

.results-table__year-head:focus-visible {
	outline: 2px solid var(--c-primary);
	outline-offset: -4px; /* Inset: the summary is flush to the container's clipped edge. */
}

.results-table__year-label {
	font-family: var(--ff-heading);
	font-weight: var(--fw-bold);
	font-size: var(--fs-3xl); /* 32 → 40; the design's 40 is the top of this rung exactly. */
	line-height: var(--lh-base);
	color: var(--c-dark);
}

/* Both frames draw these groups OPEN with an arrow-up glyph, so open is the state
   the design pins down: chevron-right turned a quarter anti-clockwise. Collapsed
   then points down, which reads as "click to expand".
   .results-table__multi-chevron now follows the same convention, and for the same
   reason: since 2026-08-26 it sits BENEATH its icon rather than beside it, where a
   right-pointing glyph reads as nothing at all. It used to share the right→down
   convention with .edoc__chevron, which was correct while it was a horizontal
   sibling of the icon and stopped being correct the moment it moved under it. */
.results-table__chevron {
	flex: 0 0 auto;
	display: inline-flex;
	color: var(--c-gray-800);
	transition: transform 0.2s ease;
	transform: rotate(90deg);
}

.results-table__chevron svg {
	width: 24px;
	height: 24px;
}

.results-table__year[open] .results-table__chevron {
	transform: rotate(-90deg);
}

/* ---- The table ---------------------------------------------------------- */
.results-table__scroll {
	overflow-x: auto;
}

/* Only ever focusable while it actually scrolls — initIrScrollers() adds the
   tabindex on the same measurement that raises the fades below. */
.results-table__scroll:focus-visible {
	outline: 2px solid var(--c-primary);
	outline-offset: -2px;
}

/* ---- Edge fades: the sign that the table continues ----------------------
   The same has-more-start / has-more-end flags the tab strips use, and the same
   40px, but drawn as a mask on the scroll container rather than as sticky
   pseudo-elements inside it. The strips put theirs inside the list because
   masking their container would have faded its own hairline border-block-end,
   and a rule that stops short of the edge reads as a rendering fault. There is
   no such border to protect here: the box's border belongs to
   .results-table__groups, which is an ancestor of the element being masked, so
   the mask cannot reach it. What it does fade is the row tint and the row
   rules, which is the intended reading — the table carries on that way.

   The mask does take the focus ring with it, since the ring is drawn inside the
   masked box: a scroller that has focus AND is scrolled shows a washed-out 40px
   at that edge. Left as is — the fade is 40px of roughly 700, so the ring's long
   top and bottom runs stay fully opaque and it is not the ring's visibility that
   is in question. The alternative is a wrapper div to mask instead, which is a
   whole element for that.

   Unprefixed. <dialog> and clamp() already put this stylesheet's floor above
   the versions that needed -webkit-mask-image.
   ------------------------------------------------------------------------ */
.results-table__scroll.has-more-end {
	mask-image: linear-gradient(to left, transparent, #000 40px);
}

.results-table__scroll.has-more-start {
	mask-image: linear-gradient(to right, transparent, #000 40px);
}

.results-table__scroll.has-more-start.has-more-end {
	mask-image: linear-gradient(
		to right,
		transparent,
		#000 40px,
		#000 calc(100% - 40px),
		transparent
	);
}

/* table-layout: fixed is what makes the columns even. In the frame the four
   icons sit at 673 / 944 / 1209 / 1511, so the gaps between their centres are
   270 / 266 / 303 — hand-placed, not a grid. Four equal columns after a fixed
   title column is within a few pixels of that at 1680 and stays even at every
   other width, which the frame's spacing could not. */
.results-table__table {
	width: 100%;
	table-layout: fixed;
	border-collapse: collapse;
}

.results-table__th {
	padding: 15px var(--sp-16);
	border-block-end: 1px solid var(--rt-rule);
	font-family: var(--ff-body);
	font-weight: var(--fw-regular);
	font-size: var(--fs-s); /* 14 */
	line-height: var(--lh-base);
	letter-spacing: normal; /* Figma tracks these at 0, unlike the display rungs. */
	color: var(--c-gray-600);
	text-align: center;
	/* Drawn in caps, so the label reads the same whichever way the editor types
	   it. The frames are themselves inconsistent — "Type" in one year group,
	   "DATE" in another. */
	text-transform: uppercase;
}

.results-table__th--title {
	width: var(--rt-title-col);
	padding-inline: 18px; /* 18, not the frame's 16, so it lines up with the cell below it. */
	text-align: start;
}

.results-table__row {
	background: var(--c-primary-05);
	border-block-end: 1px solid var(--rt-rule-soft);
	transition: background-color 0.2s ease;
}

/* The white row in the frame is the hover state, not a zebra stripe: it is
   also the row carrying the maroon rail and the "View" reveal. focus-within
   comes along so that tabbing through the icons lights the same row a mouse
   would. */
.results-table__row:hover,
.results-table__row:focus-within {
	background: var(--c-white);
}

/* The 3px rail. An inset shadow on the first cell rather than a border on the
   <tr>, which border-collapse would swallow, and rather than a shadow on the
   <tr>, which is not reliably painted on a row at all. */
.results-table__row:hover .results-table__cell--title,
.results-table__row:focus-within .results-table__cell--title {
	box-shadow: inset 3px 0 0 var(--c-primary);
}

.results-table__year:last-child .results-table__row:last-child {
	border-block-end: 0; /* The container's own border closes the table. */
}

.results-table__cell {
	height: 80px;
	padding: var(--sp-16) 18px;
	text-align: center;
	vertical-align: middle;
}

.results-table__cell--title {
	width: var(--rt-title-col);
	text-align: start;
}

.results-table__title {
	display: block;
	font-family: var(--ff-body);
	font-weight: var(--fw-semibold);
	font-size: var(--fs-l); /* 18 → 20; the design's 20 is the top of this rung exactly. */
	line-height: var(--lh-base);
	letter-spacing: normal;
	color: var(--c-dark);
	overflow-wrap: break-word;
}

/* ---- One document in a cell --------------------------------------------- */
/* 64×64 in the frame, holding the icon with the reveal beneath it. The box is
   sized for both from the start, so nothing moves on hover — only the words
   appear. It is also the hit area, which at 64px clears the 44px minimum
   comfortably for a target that carries no visible label. */
.results-table__doc {
	display: inline-flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: 2px;
	width: 64px;
	min-height: 64px;
	border-radius: var(--radius-md);
	color: var(--c-primary);
	text-decoration: none;
	transition: background-color 0.2s ease;
}

.results-table__doc:hover {
	background: var(--c-primary-05);
}

.results-table__icon {
	display: inline-flex;
	flex: 0 0 auto;
}

.results-table__icon svg {
	width: 32px;
	height: 32px;
}

/* The reveal. 10px in the frame, which is below any size this site sets text
   at; --fs-s instead, which the 64px box still holds (32 + 2 + 19.6 = 53.6).
   It is decorative and aria-hidden — the accessible name on the link already
   says what it opens — so it fades rather than being unhidden, and it keeps its
   space either way. */
.results-table__doc-view {
	display: inline-flex;
	align-items: center;
	gap: 2px;
	font-family: var(--ff-body);
	font-weight: var(--fw-semibold);
	font-size: var(--fs-s);
	line-height: var(--lh-base);
	color: var(--c-primary);
	white-space: nowrap;
	opacity: 0;
	transition: opacity 0.2s ease;
}

.results-table__row:hover .results-table__doc-view,
.results-table__doc:focus-visible .results-table__doc-view {
	opacity: 1;
}

.results-table__doc-arrow {
	display: inline-flex;
}

.results-table__doc-arrow svg {
	width: 14px;
	height: 14px;
}

/* ---- Two or more documents in one cell ---------------------------------- */
/* Live puts these behind a page — two unaudited results for one quarter. Here
   the cell reveals them, because a cell that opened only the first would hide a
   statutory document behind an icon that gives no hint there is a second. */
.results-table__multi {
	display: inline-block;
	text-align: start;
}

/*
 * The same 64px box as .results-table__doc beside it, built the same way: icon on
 * top, a small affordance underneath, both centred. That is the whole fix for the
 * alignment complaint, and it is worth being precise about what the complaint was,
 * because the obvious reading of it is wrong.
 *
 * The icon was never off its column's centre line. This rule previously carried
 * padding-inline-start: calc(20px + 8px) precisely to hold it there — the cell
 * would otherwise centre the icon and the chevron together as one 60px pair and
 * drop the icon 14px to the left. Measured off the reported screenshot, the icon
 * in the two-document cell and the icon in the one-document cell above it both
 * occupied exactly the same pixels. The compensation worked.
 *
 * What did not work was the chevron. Centring the icon while a second glyph hung
 * off its right meant the cell was visibly right-heavy against a column of lone
 * icons, and a right-heavy cell reads as a misaligned one whatever a measurement
 * says. Compensating harder cannot fix that: the padding buys the icon its centre
 * line at the cost of the cell looking lopsided, which is trading one alignment
 * for another.
 *
 * Stacking removes the trade instead of re-balancing it. With the chevron beneath
 * the icon there is nothing on either side to compensate for, the box becomes the
 * same 64px square as every other cell in the row, and the icons line up because
 * the boxes do — not because a hand-tuned padding is holding one of them in place.
 * main.js positions the open panel on this box's centre, which is now the icon's
 * centre by construction rather than by arithmetic.
 */
.results-table__multi-head {
	display: inline-flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: 2px;
	width: 64px;
	min-height: 64px;
	color: var(--c-primary);
	cursor: pointer;
	list-style: none;
}

.results-table__multi-head::-webkit-details-marker {
	display: none;
}

.results-table__multi-head:focus-visible {
	outline: 2px solid var(--c-primary);
	outline-offset: 4px;
}

/* 14px to match .results-table__doc-arrow, which is the glyph occupying this exact
   slot in the one-document cell next to it. At 20px it was sized to sit beside a
   32px icon; under one it just competes with it. The stack is then 32 + 2 + 14 =
   48 inside the 64px box, so the icon keeps the vertical centre it had.

   Down when closed, up when open — the convention .results-table__chevron already
   uses on the year groups directly above this table. It pointed right when it was
   a horizontal sibling of the icon; that no longer describes where the list opens. */
.results-table__multi-chevron {
	flex: 0 0 auto;
	display: inline-flex;
	transform: rotate(90deg);
	transition: transform 0.2s ease;
}

.results-table__multi-chevron svg {
	width: 14px;
	height: 14px;
}

.results-table__multi[open] .results-table__multi-chevron {
	transform: rotate(-90deg);
}

/* ---- The multi-document panel -------------------------------------------
   Two documents used to open inside the cell, and a cell that grows takes the
   row with it: the icon jumped to the top of a 3-line row while the other four
   sat in the middle of it, so the one thing this table is — five icons on a
   line — came apart on exactly the rows that needed reading most.

   So on the table layout the list is lifted out of the flow and floated under
   the icon. Fixed, not absolute: it lives inside .results-table__scroll
   (overflow-x) and .results-table__groups (overflow: hidden), and an absolute
   panel would be clipped by both. main.js sets top/left, and reads this
   position value to decide whether to — below 768px the rows are stacked cards
   with no grid left to protect, so the list stays in flow and the JS keeps out
   of it. Nothing here has a transform, so `fixed` really is the viewport. */
.results-table__multi-list {
	position: fixed;
	z-index: 20;
	width: max-content;
	min-width: 180px;
	max-width: calc(100vw - var(--sp-32));
	margin: 0;
	padding: var(--sp-8) 0;
	border: 1px solid var(--c-gray-200);
	border-radius: var(--radius-md);
	background: var(--c-white);
	box-shadow: 0 16px 33px -2px rgba(28, 39, 49, 0.12);
	list-style: none;
}

/* A menu row, not a line of prose: the whole width is the target and the tint is
   the one the filter list uses. No underline in either state — these read as the
   options of the control that was just clicked, exactly as .results-table__option
   does two hundred lines up, and the two panels on this page are drawn the same
   way on purpose. Below 768px the same links go back to being underlined, because
   there they are text in the flow of a card with no row and no tint to stand in
   for it. */
.results-table__multi-item {
	padding: 0 var(--sp-8);
}

.results-table__multi-item .results-table__doc--text {
	display: flex;
	justify-content: flex-start; /* The base link centres itself in a 64px icon box. */
	width: 100%;
	padding: var(--sp-8) var(--sp-12);
	border-radius: var(--radius-sm);
	text-decoration: none;
	transition: background-color 0.15s ease;
}

.results-table__multi-item .results-table__doc--text:hover,
.results-table__multi-item .results-table__doc--text:focus-visible {
	background: var(--c-primary-05);
}

/* The same link, with its words showing. Inside the list the column header no
   longer tells the two apart, so the label is visible here and the icon goes. */
.results-table__doc--text {
	flex-direction: row;
	gap: var(--sp-8);
	width: auto;
	min-height: 0;
	padding: 2px 0;
	font-family: var(--ff-body);
	font-weight: var(--fw-regular);
	font-size: var(--fs-l2);
	line-height: var(--lh-base);
	text-align: start;
}

.results-table__doc--text:hover {
	background: none;
}

/* No rule for .results-table__doc-label. It used to carry the underline, and it
   renders in exactly one place — inside a multi-document panel — so the underline
   now belongs to the ≤767 rule that puts those links back in the flow, where it
   propagates into this span from the anchor. */

/* ---- Empty cells --------------------------------------------------------
   A quarter with no transcript draws nothing at all in the frame — no dash, no
   placeholder — so at this width the class styles nothing and is not given a
   rule for the sake of having one. It exists for the stacked layout below,
   where every cell prints its column label and a label with nothing behind it
   is worse than no line at all. */

/* ---- The stacked layout's column label ----------------------------------
   Printed from the cell's own data-label by the max-width: 767 block below,
   which sets `content` and nothing else. The type is up here on purpose: a
   font-size inside a media query is exactly how the stepped ladder that
   tokens.css replaced was built, and this stylesheet does not do that any
   more. Declaring it at this width costs nothing, because a ::before with no
   `content` generates no box at all. Same 14px as the column headers it stands
   in for, and the same grey — it is the same label, moved. */
.results-table__cell[data-label]::before {
	font-family: var(--ff-body);
	font-weight: var(--fw-regular);
	font-size: var(--fs-s);
	line-height: var(--lh-base);
	color: var(--c-gray-600);
	text-transform: uppercase;
}

/* ==========================================================================
   RESULTS TABLE — narrower
   The gutter follows the 120 / 80 / 24 ladder .ir-header and .doc-cards use, so
   the table's outer edge lines up with the header above it at every width.

   Where the table stops being a table was measured, not taken from the plan's
   "~900". The four icon columns need about 90px each to hold a 64px target with
   air around it, and the title column needs enough for "Orkla ASA Q4 2025
   Results (December Quarter)" on two or three lines:

     1280 – 80px gutter → 1120 content − 313 title = 807 over 4 = 201 each
      900 – 80px gutter →  740 content − 240 title = 500 over 4 = 125 each
      768 – 24px gutter →  720 content − 240 title = 480 over 4 = 120 each
      767 – 24px gutter →  719, and the title column is now half the width

   So the table does not run out of room at 900 — it runs out at the point the
   title column stops fitting a quarter's name, which is the phone breakpoint
   the rest of the theme already turns at. 900 gets a narrower title column and
   tighter cells instead of losing a layout that still works.
   ========================================================================== */

@media (max-width: 1280px) {
	.results-table {
		padding-inline: 80px;
	}
}

@media (max-width: 900px) {
	.results-table {
		--rt-title-col: 240px;
	}

	.results-table__year-head {
		padding-inline: var(--sp-32);
	}

	.results-table__th,
	.results-table__cell {
		padding-inline: var(--sp-12);
	}
}

@media (max-width: 767px) {
	.results-table {
		padding-inline: var(--sp-24);
	}

	.results-table__year-head {
		padding: var(--sp-16) var(--sp-24);
	}

	/* The intro and the selectors stop sharing a line: two pills side by side in
	   340px leave no room for either label. Full width, splitting the row
	   between them, so each keeps its "Year :" / "Type :" visible. */
	.results-table__filters {
		width: 100%;
	}

	.results-table__filter {
		flex: 1 1 auto;
		justify-content: space-between;
	}

	/* ---- Every row becomes a card ----
	   display: block takes the table semantics out of the accessibility tree,
	   and they are deliberately NOT put back with role="table" — because
	   nothing here needs them. The reason the desktop layout is a real table is
	   that its cells are wordless and the column header is the only thing naming
	   them; in this layout each link already carries the column name in its own
	   accessible name (ir-result-doc.php builds "Q1 FY27, Presentation") and the
	   visible name comes back beside it from data-label. The <thead> goes for
	   the same reason it would have to: stacked, it is four words with nothing
	   under them above the first card.

	   <tbody> is in this list because it must be. A table-row-group inside a
	   block parent gets wrapped in an anonymous table box, which restores table
	   layout to every row inside it and quietly undoes the whole block. */
	.results-table__table,
	.results-table__table tbody,
	.results-table__row,
	.results-table__cell {
		display: block;
		width: auto;
		height: auto;
	}

	.results-table__table thead {
		display: none;
	}

	.results-table__row {
		padding-block: var(--sp-8);
	}

	.results-table__cell {
		padding: var(--sp-8) var(--sp-16);
		text-align: start;
	}

	.results-table__cell--title {
		padding-block-start: var(--sp-16);
	}

	/* A column label with no document behind it is a promise of a line that
	   isn't there. The empty cell simply does not appear on the card. */
	.results-table__cell--empty {
		display: none;
	}

	/* The rail goes. Three pixels beside one line of a stacked card is a
	   fragment of a design that is not there — and the row is the whole card
	   now, so the tint alone already says which one you are in. */
	.results-table__row:hover .results-table__cell--title,
	.results-table__row:focus-within .results-table__cell--title {
		box-shadow: none;
	}

	/* Label on the left, document on the right. Keyed off the attribute rather
	   than :not(--title) so the row's <th>, which has no data-label, is left
	   alone by the same selector that prints the label. */
	.results-table__cell[data-label] {
		display: flex;
		flex-wrap: wrap;
		align-items: center;
		justify-content: space-between;
		gap: var(--sp-8) var(--sp-16);
	}

	.results-table__cell[data-label]::before {
		content: attr(data-label);
	}

	/* 44px is the tap target, not 64px of centred column: there is no column to
	   centre in. The reveal goes with it — "View" existed to name a wordless
	   icon, and the line it sits on now says the name out loud. */
	.results-table__doc {
		flex-direction: row;
		gap: var(--sp-8);
		width: auto;
		min-width: 44px;
		min-height: 44px;
		padding-inline: var(--sp-8);
	}

	.results-table__doc-view {
		display: none;
	}

	/* Two documents in one cell. The disclosure takes a flex line of its own
	   rather than sitting beside its label, because the list it reveals lives
	   INSIDE it and is therefore as wide as it is — beside the label that is
	   about 120px at 375, and "Standalone unaudited results" over four lines is
	   not a saving. Full width puts each title on two.

	   The summary stays right-aligned, so the icon is on the same edge as every
	   other cell's and the label still reads as belonging to it. */
	.results-table__multi {
		flex: 1 1 100%;
	}

	/* Back to a row down here, and explicitly: the desktop rule stacks the chevron
	   under the icon to keep an icon grid straight, and below 768px there is no
	   grid left — every row is a stacked card and this summary is right-aligned on
	   a full-width flex line. Stacking would only make the tap target tall and
	   narrow for no gain. The width goes back to auto for the same reason; 64px
	   would stop flex-end meaning anything. The chevron keeps pointing down when
	   closed, which is if anything more accurate here, since on this breakpoint
	   the list really does open directly beneath it in the flow. */
	.results-table__multi-head {
		flex-direction: row;
		justify-content: flex-end;
		gap: var(--sp-8);
		width: auto;
		min-height: 44px;
	}

	/* Back into the flow. There is no icon grid left to protect down here — every
	   row is already a stacked card — and a floating panel over a card that is
	   itself the width of the screen would only get in the way. main.js reads this
	   position value and leaves the list alone when it is not fixed, so the
	   breakpoint lives here and nowhere else. */
	.results-table__multi-list {
		position: static;
		z-index: auto;
		width: auto;
		min-width: 0;
		max-width: none;
		margin-block-end: 0;
		padding: 0;
		border: 0;
		border-radius: 0;
		background: none;
		box-shadow: none;
	}

	.results-table__multi-item {
		padding: 0;
	}

	.results-table__multi-item + .results-table__multi-item {
		margin-block-start: var(--sp-8);
	}

	/* Underlined again here, and only here: on the table layout these are rows of
	   a panel with a hover tint to mark them, but down here they are two lines of
	   text inside a card, where colour alone would leave a statutory PDF looking
	   like a caption. */
	.results-table__multi-item .results-table__doc--text {
		width: auto;
		padding: 2px 0;
		border-radius: 0;
		text-decoration: underline;
		text-decoration-thickness: 1px;
		text-underline-offset: 3px;
	}

	.results-table__multi-item .results-table__doc--text:hover,
	.results-table__multi-item .results-table__doc--text:focus-visible {
		background: none;
	}
}

@media (prefers-reduced-motion: reduce) {
	.results-table__chevron,
	.results-table__multi-chevron,
	.results-table__filter-chevron,
	.results-table__option,
	.results-table__row,
	.results-table__doc,
	.results-table__doc-view {
		transition: none;
	}
}

/* ---- What the filters hide ----------------------------------------------
   initResultsTable() narrows the table with the `hidden` attribute: a year
   group the Year select excludes, and every cell — header and body alike —
   whose column the Type select excludes.

   These have to be restated for the same reason .results-table__filters[hidden]
   above does: an author rule setting `display` beats the UA's [hidden] whatever
   the specificity, and the ≤767 block sets `display: block` on
   .results-table__cell and `display: flex` on .results-table__cell[data-label].
   That last one ties with .results-table__cell[hidden] on specificity, so this
   block must stay AFTER the media query — source order is what settles it.
   Moving it up silently breaks the Type filter on phones only. */
.results-table__year[hidden],
.results-table__th[hidden],
.results-table__cell[hidden] {
	display: none;
}

/* ==========================================================================
   PAGE-SCOPED OVERRIDES
   One page looks different from the component's default, on the client's
   instruction, and the component must stay as it is on every other page.

   Keyed to `page-slug-{slug}` from orkla_body_class_page_slug() in inc/setup.php
   — a slug, not core's `page-id-{N}`, because dev / staging / production were
   seeded separately and hold different IDs for the same page.

   Keep this block last so it wins on source order as well as specificity, keep
   every entry dated with its reason, and keep it short. A pattern that turns up
   on a second page is not a page override any more — promote it to a variant
   class or an ACF choice and take it out of here.
   ========================================================================== */

/* /sustainability/ — client instruction 10 Aug 2026: nothing on this page should
   read at 60px, drop it all to 48. Repointed to the H3 rung rather than given a
   flat 48px so it still scales with the fluid ladder (--fs-4xl is 32 → 48, hitting
   48 at 1920 exactly). Same fix, same reasoning, as .brands__heading on the home
   page — a flat px value would opt these out of the fluid scale entirely.

   Scoped because two of the four are shared: .page-hero__title also titles About
   Us, Our Brands, Careers and Contact, and .feature-split__heading also runs down
   About Us and Careers. Those keep 60. The two stats-donut selectors are unique to
   this page today and are scoped anyway, so putting that section on another page
   later inherits the default rather than this page's exception.

   Seven pieces of text in all: the H1 "Sustainability", the "Progress You Can
   Measure" heading, the four feature-split headings including "Orkla India
   Sustainability Strategy", and the figures inside the donut rings.

   The donut figure is the one that is not a heading, and it was added on a second
   pass after the client confirmed they meant it too — the instruction was the size,
   not the role. Its 32px unit beside it (.stat-donut__unit, the "%") is unchanged,
   so the pairing goes from 60/32 to 48/32; that is the visible consequence to look
   at first if this ever gets questioned. Nothing about the ring geometry is derived
   from the font-size, so only the number moves.

   The sustainability SUB-pages are untouched — their H1 is .page-heading__title,
   and their body class is page-slug-sustainability-strategy and friends, which is a
   separate class token that this selector cannot match.

   EXTENDED 2026-08-14 (client) to Nurturing Planet, Nurturing Health (retitled
   Nurturing People on 2026-08-31; the slug, and so the selector below, is unchanged)
   and Nurturing Communities. The rule is now "no 60px text on the four Sustainability-tree pages",
   which is why this is one grouped rule rather than four page entries: this block's
   own header says a pattern on a second page is not a page override any more, and
   four is well past that. It stays here rather than becoming a variant class because
   the trigger is which page you are on, not anything about the component.

   The page list is explicit and NOT ancestry-based. All four are top-level pages —
   post_parent 0, verified in the dev DB — so there is no ancestor class to hang this
   on even if we wanted one. It also keeps the sustainability sub-pages out, which is
   still the intent: they were never included and nobody has asked.

   The two selector lists are a union, not a matrix. Every page gets every selector,
   because the client's instruction is about a size and not about a section, and the
   pages have almost nothing in common structurally — Sustainability is page_hero +
   feature_split + stats_donut, the Nurturing three are page_heading + focus cards,
   and only Nurturing Planet has stats_progress. Selectors that do not appear on a
   given page simply do not match. What each page actually inherits from this today:

     sustainability          .page-hero__title, 4x .feature-split__heading,
                             .stats-donut__heading, .stat-donut__value  (7 items)
     nurturing-planet        .page-heading__title, .stats-progress__heading,
                             3x .stat-card__value                       (5 items)
     nurturing-people        .page-heading__title                       (1 item)
     nurturing-communities   .page-heading__title                       (1 item)

   Enumerated by listing every rule in this file that sets --fs-5xl or --fs-6xl and
   checking which of those classes each page renders — not by eye. Redo it that way
   if a section is ever added to one of these pages, because this lists CLASSES and
   not the rung: a new 60px heading here would need adding by hand.

   :is() keeps it to one rule. Specificity is that of its most specific argument —
   one class either side — so this matches the four-entry version it replaced, and
   the block's position at the foot of the file still settles ties. :where() is
   already used at the top of this file, so the family is not new here. */
:is(
	.page-slug-sustainability,
	.page-slug-nurturing-planet,
	.page-slug-nurturing-people,
	.page-slug-nurturing-communities
) :is(
	.page-hero__title,
	.page-heading__title,
	.stat-donut__value,
	.stat-card__value
) {
	font-size: var(--fs-4xl); /* fluid 32 → 48 */
}

/* TRIMMED 2026-09-08 from seven selectors to four, and this is a reduction in scope
   with no visible change. .feature-split__heading, .stats-donut__heading and
   .stats-progress__heading came out because they are H2s and every H2 on the site is
   now 48 — see the h2 rule at the top of this file, which is the same corrections
   sheet asking for sitewide what these four pages had locally. They would still
   compute to 48 here if this rule vanished entirely.

   The four that remain are the ones that would NOT. .page-hero__title and
   .page-heading__title are H1s at --fs-6xl, and .stat-donut__value and
   .stat-card__value are figures at --fs-5xl; both rungs are deliberately still 60
   sitewide. Delete this block and the four Sustainability-tree pages get their 60px
   titles and figures back, which is the 2026-08-07 instruction undone.

   So the per-page enumeration in the header comment above is now shorter too:
   sustainability keeps .page-hero__title + .stat-donut__value (2 of its 7),
   nurturing-planet .page-heading__title + 3x .stat-card__value (4 of 5), and the
   other two pages their .page-heading__title as before. */

/* /nurturing-communities/ — client instruction 31 Aug 2026: "this box is in center
   make for only this page not for all". The CSR Annual Action Plan card is the only
   content of its text_share section there, so left-aligned it left ~400px of dead
   space beside it under a share row that IS centred, and read as a mistake.

   Scoped, and NOT keyed to "the card is the section's only content" as this first
   shipped. That condition is true on three other pages too — Orkla Principles and
   Policy, Supplier Code of Conduct, Develop Your Skills With Us — so the data-driven
   version silently restyled all four. The client has since confirmed they want the
   default kept everywhere else, so the trigger really is which page you are on.

   align-items, not text-align alone: the button is a flex item whose
   `align-self: flex-start` would otherwise keep it pinned left inside a centred box.
   Its own align-self needs the second selector — a parent's align-items cannot
   override a child's explicit align-self. */
.page-slug-nurturing-communities .text-share__card {
	margin-inline: auto;
	align-items: center;
	text-align: center;
}

.page-slug-nurturing-communities .text-share__card-btn {
	align-self: center;
}
