/*
Theme Name: Windrose Relocation Africa
Theme URI: https://windroserelocation.africa/
Author: Imarisher Ventures Ltd
Author URI: https://imarisher.com/
Description: Custom WordPress theme for Windrose Relocation Africa, a Nairobi-based global mobility, destination and market access company. Phase 1 is a single scrolling page with a paid consultation booking flow integrated directly with PesaPal — no WooCommerce and no e-commerce plugin. Page content is authored as PHP partials in /content/ and pulled into near-empty WordPress Pages via the [windrose_content page="slug"] shortcode.
Version: 1.2.0
Requires at least: 6.0
Tested up to: 6.7
Requires PHP: 7.4
License: GNU General Public License v2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
Text Domain: windrose
Tags: business, custom-menu, custom-logo, featured-images, one-page
*/

/* ==========================================================================
   WINDROSE RELOCATION AFRICA — DESIGN SYSTEM
   --------------------------------------------------------------------------
   Palette sampled from the supplied logo artwork (Logo/300ppi/windrose
   logo.png): the navy of the wordmark and the gold of "RELOCATION" are the
   two brand colours, read straight out of the file rather than guessed.

       Navy .............. #0D1B2A
       Gold .............. #C29D5C

   Typography follows the brand direction in the proposal — "a serif for
   headlines with a clean sans-serif for body text". DM Serif Display is the
   heading face; Inter is the body face.

   DM Serif Display ships ONE weight (400) plus an italic. Nothing may set a
   serif heading bolder than 400 — the browser would synthesise the weight by
   smearing the outline, which on a high-contrast Didone reads as a printing
   fault. It is already dark enough on the page that it does not need it.

   The layout language comes from the supplied inspiration: a split hero, the
   headline / body editorial rhythm, tinted cards, and
   full-bleed dark bands.

   NO MOBILE COMPOSITION WAS SUPPLIED. Everything below 1100px is derived, not
   given: display type is set in clamp() so it scales smoothly, and the fixed
   grids collapse in a stated order. Section 12 collects all of it in one place
   so it can be reviewed as a unit — and it is worth checking on a real phone
   before sign-off, since it was not part of what anyone approved.

   Contents
     1.  Tokens
     2.  Reset and base
     3.  Layout primitives
     4.  Typography
     5.  Header, nav and drawer
     6.  Buttons and pills
     7.  Sections and editorial blocks
     8.  Home page components
     9.  Booking page and forms
     10. Bands: promise, CTA, connect
     11. Footer
     12. Archive, single and editor content
     13. Responsive
     14. Touch
   ========================================================================== */


/* --------------------------------------------------------------------------
   1. Tokens
   -------------------------------------------------------------------------- */

:root {
	/* Brand ---------------------------------------------------------- */
	--wr-navy: #0D1B2A;          /* Wordmark navy — headings, dark panels    */
	--wr-navy-deep: #081420;     /* Footer, the deepest ground               */
	--wr-navy-soft: #16293C;     /* Hover on navy, card borders on navy      */
	--wr-gold: #C29D5C;          /* Logo gold — rules, eyebrows, numerals    */
	--wr-gold-light: #DCBE8B;    /* Gold on dark, where the base is too dim  */
	--wr-gold-deep: #A6803F;     /* Gold button hover                        */

	/* Grounds -------------------------------------------------------- */
	--wr-bg: #FBFAF7;            /* Page background — warm off-white         */
	--wr-sand: #F4F0E9;          /* Tinted sections and cards                */
	--wr-stone: #EAE4DA;         /* Image well before an image is set        */

	/* Text ----------------------------------------------------------- */
	--wr-ink: #16212E;           /* Default body text                        */
	--wr-body: #3D4A58;          /* Paragraphs                               */
	--wr-muted: #66727E;         /* Secondary copy, inactive nav             */

	/* Lines and washes ----------------------------------------------- */
	--wr-rule: rgba(13, 27, 42, 0.12);
	--wr-rule-strong: rgba(13, 27, 42, 0.22);
	--wr-rule-light: rgba(255, 255, 255, 0.16);
	--wr-gold-wash: rgba(194, 157, 92, 0.14);

	/* On-dark text --------------------------------------------------- */
	--wr-on-dark: #FBFAF7;
	--wr-on-dark-80: rgba(255, 255, 255, 0.80);
	--wr-on-dark-64: rgba(255, 255, 255, 0.64);
	--wr-on-dark-46: rgba(255, 255, 255, 0.46);

	/* Type ----------------------------------------------------------- */
	--wr-serif: 'DM Serif Display', Georgia, 'Times New Roman', serif;
	--wr-sans: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;

	/*
	 * Fluid display sizes. The upper bound of each is the desktop value the
	 * layout was composed at; the lower bound is the derived mobile size.
	 */
	--wr-h1-hero: clamp(36px, 4.4vw, 68px);
	--wr-h1: clamp(34px, 4.6vw, 58px);
	--wr-h2: clamp(28px, 3.6vw, 46px);
	--wr-h2-sm: clamp(25px, 3vw, 38px);
	--wr-h3: clamp(19px, 1.5vw, 22px);
	--wr-promise: clamp(30px, 4.4vw, 58px);

	/* Layout --------------------------------------------------------- */

	/*
	 * FULL WIDTH. There is no max-width on the container: sections run edge to
	 * edge and the gutter alone holds the content off the sides. The gutter is
	 * fluid so the margin grows with the screen instead of leaving the content
	 * pinned against the glass on a large monitor.
	 *
	 * A full-bleed layout still needs a reading measure, or paragraphs stretch
	 * to 200 characters on a wide screen and become genuinely hard to read.
	 * That cap lives on the text blocks (--wr-measure), not on the container,
	 * so panels, grids and bands stay full width while prose does not.
	 */
	--wr-gutter: clamp(20px, 4vw, 88px);
	--wr-measure: 68ch;
	--wr-section-y: clamp(64px, 8vw, 128px);

	/*
	 * The header has two states: tall at the top of the page, condensed once it
	 * scrolls. main.js adds .is-stuck past the threshold — see section 5. All
	 * four values are tokens so the condensed header can be retuned here rather
	 * than in the script.
	 */
	--wr-header-h: 88px;
	--wr-header-h-stuck: 66px;
	--wr-mark-h: 44px;
	--wr-mark-h-stuck: 34px;

	--wr-radius: 4px;
	--wr-ease: cubic-bezier(0.22, 0.61, 0.36, 1);
}


/* --------------------------------------------------------------------------
   2. Reset and base
   -------------------------------------------------------------------------- */

*,
*::before,
*::after {
	box-sizing: border-box;
}

html {
	-webkit-text-size-adjust: 100%;
	scroll-behavior: smooth;
}

/*
 * Anchored jumps must clear the fixed header rather than landing underneath it.
 * Measured against the CONDENSED height: any in-page jump happens mid-scroll,
 * where the header is already stuck and therefore short.
 */
:target,
[id] {
	scroll-margin-top: calc(var(--wr-header-h-stuck) + 20px);
}

@media (prefers-reduced-motion: reduce) {
	html {
		scroll-behavior: auto;
	}

	*,
	*::before,
	*::after {
		animation-duration: 0.01ms !important;
		animation-iteration-count: 1 !important;
		transition-duration: 0.01ms !important;
	}
}

body {
	margin: 0;
	background: var(--wr-bg);
	color: var(--wr-body);
	font-family: var(--wr-sans);
	font-size: 16px;
	font-weight: 400;
	line-height: 1.65;
	-webkit-font-smoothing: antialiased;
	-moz-osx-font-smoothing: grayscale;
}

/* Set by main.js while the drawer is open, so the page behind cannot scroll. */
body.wr-noscroll {
	overflow: hidden;
}

h1, h2, h3, h4, h5, h6 {
	margin: 0;
	font-family: var(--wr-serif);
	font-weight: 400;
	color: var(--wr-navy);
	line-height: 1.12;
	letter-spacing: -0.01em;
}

p {
	margin: 0 0 1.15em;
}

p:last-child {
	margin-bottom: 0;
}

a {
	color: var(--wr-navy);
	text-decoration-color: var(--wr-gold);
	text-underline-offset: 3px;
	transition: color 0.2s var(--wr-ease);
}

a:hover {
	color: var(--wr-gold-deep);
}

img {
	max-width: 100%;
	height: auto;
	display: block;
}

ul, ol, dl, dd {
	margin: 0;
	padding: 0;
}

ul, ol {
	list-style: none;
}

/* Visible focus everywhere. Never remove this without replacing it. */
a:focus-visible,
button:focus-visible,
summary:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
[tabindex]:focus-visible {
	outline: 2px solid var(--wr-gold);
	outline-offset: 3px;
	border-radius: 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: 100;
	padding: 12px 20px;
	background: var(--wr-navy);
	color: var(--wr-on-dark);
	text-decoration: none;
}

.skip-link:focus {
	left: 8px;
	top: 8px;
	color: var(--wr-on-dark);
}

/*
 * The honeypot. Positioned off-screen rather than display:none — some bots skip
 * display:none inputs, which would defeat the trap entirely.
 */
.wr-honeypot {
	position: absolute !important;
	left: -9999px;
	width: 1px;
	height: 1px;
	overflow: hidden;
}

/* Editor-only notices from windrose_content_admin_notice(). */
.wr-notice {
	margin: 12px 0 0;
	padding: 10px 14px;
	background: var(--wr-gold-wash);
	border-left: 3px solid var(--wr-gold);
	font-size: 13px;
	color: var(--wr-ink);
}


/* --------------------------------------------------------------------------
   3. Layout primitives
   -------------------------------------------------------------------------- */

.wr-container {
	width: 100%;
	margin: 0 auto;
	padding: 0 var(--wr-gutter);
}

.wr-measure {
	max-width: var(--wr-measure);
}

.wr-main {
	/*
	 * The header is fixed, so it is out of flow and the first section would
	 * otherwise start underneath it. The hero overrides this to sit under the
	 * header deliberately (section 8).
	 */
	padding-top: var(--wr-header-h);
}

/*
 * The one-pager's hero pads itself past the fixed header, so the wrapper must
 * not pad it a second time. Every other page needs the wrapper padding, or its
 * first section starts underneath the header.
 */
body.home .wr-main {
	padding-top: 0;
}

.wr-section {
	padding: var(--wr-section-y) 0;
}

.wr-section--flush {
	padding-top: 0;
}

.wr-section--tint {
	background: var(--wr-sand);
}

/*
 * The tint, faded out to white down the section.
 *
 * A separate modifier rather than a change to --tint, because --tint is also on
 * Who We Serve, which sits between two light sections and needs to stay a flat
 * block of colour to read as its own band at all.
 */
.wr-section--fade {
	background: linear-gradient(to bottom, var(--wr-sand) 0%, #fff 100%);
}

.wr-section--navy {
	background: var(--wr-navy);
	color: var(--wr-on-dark-80);
}

.wr-section--navy h1,
.wr-section--navy h2,
.wr-section--navy h3 {
	color: var(--wr-on-dark);
}

/* Image wells ------------------------------------------------------------ */

.wr-imagewell {
	position: relative;
	background: var(--wr-stone);
	overflow: hidden;
}

.wr-imagewell img {
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.wr-imagewell--fill {
	width: 100%;
	height: 100%;
	min-height: 320px;
}

.wr-imagewell--band {
	aspect-ratio: 21 / 9;
}

/* The art-direction note, shown to logged-in editors only. */
.wr-imagewell__hint {
	position: absolute;
	inset: 0;
	display: flex;
	align-items: center;
	justify-content: center;
	padding: 24px;
	text-align: center;
	font-size: 12px;
	line-height: 1.5;
	letter-spacing: 0.04em;
	text-transform: uppercase;
	color: var(--wr-muted);
}


/* --------------------------------------------------------------------------
   4. Typography
   -------------------------------------------------------------------------- */

.wr-h1 {
	font-size: var(--wr-h1);
}

.wr-h1--page {
	margin-bottom: 0.4em;
}

.wr-h2 {
	font-size: var(--wr-h2);
}

.wr-h2--sm {
	font-size: var(--wr-h2-sm);
}

.wr-h3 {
	font-size: var(--wr-h3);
}

/*
 * The eyebrow. Letterspaced uppercase Inter rather than the monospace of the
 * layout reference — it reads the same at this size and keeps the font payload
 * to two families.
 */
.wr-eyebrow {
	margin: 0 0 20px;

	/*
	 * font-family and line-height are set explicitly because this class is worn
	 * by <h2> and <h3> elements as well as <p> — see .wr-statement and
	 * .wr-feecard. Without them a heading would inherit the serif face and the
	 * 1.12 display leading from the h1–h6 rule and look nothing like the eyebrow
	 * beside it.
	 */
	font-family: var(--wr-sans);
	line-height: 1.4;
	font-size: 11px;
	font-weight: 500;
	letter-spacing: 0.16em;
	text-transform: uppercase;
	color: var(--wr-muted);
}

.wr-eyebrow--tight {
	margin-bottom: 10px;
}

.wr-eyebrow--light {
	color: var(--wr-gold-light);
}

.wr-lead {
	font-size: clamp(17px, 1.4vw, 19px);
	line-height: 1.6;
	color: var(--wr-ink);
}

.wr-note {
	font-size: 14px;
	color: var(--wr-muted);
}

.wr-prose > * + * {
	margin-top: 1.1em;
}


/* --------------------------------------------------------------------------
   5. Header, nav and drawer
   -------------------------------------------------------------------------- */

/*
 * STACKING ORDER: scrim 60 -> drawer 62 -> header 63.
 *
 * All three matter and all three are easy to break by accident.
 *
 * THE HEADER IS ON TOP, and that is the whole point: the toggle IS the close
 * button — there is no ✕ inside the panel — so if anything paints over it the
 * drawer becomes a modal with no way out on a touch screen, where there is no
 * Escape key. The header used to sit at 61, UNDER the drawer at 62, which put
 * the panel's own background over the toggle in exactly that way.
 *
 * Nothing is lost by the swap now that the drawer is white: the header's
 * translucent near-white band over a white panel is invisible, and the panel
 * pads its content past the header height anyway (.wr-nav-mobile__inner), so
 * the logo and links start below the bar rather than under it.
 */
.wr-header {
	position: fixed;
	top: 0;
	left: 0;
	right: 0;
	z-index: 63;
	height: var(--wr-header-h);
	background: rgba(251, 250, 247, 0.86);
	backdrop-filter: saturate(150%) blur(12px);
	-webkit-backdrop-filter: saturate(150%) blur(12px);
	border-bottom: 1px solid transparent;
	transition: height 0.3s var(--wr-ease), background 0.3s var(--wr-ease), border-color 0.3s var(--wr-ease);
}

.wr-header.is-stuck {
	height: var(--wr-header-h-stuck);
	border-bottom-color: var(--wr-rule);
	box-shadow: 0 1px 24px rgba(13, 27, 42, 0.06);
}

.wr-header__inner {
	display: grid;
	grid-template-columns: auto 1fr auto;
	align-items: center;
	gap: 32px;
	height: 100%;
}

.wr-header__brand {
	grid-column: 1;
}

.wr-header__nav {
	grid-column: 2;
	justify-self: center;
}

.wr-header__actions {
	grid-column: 3;
	display: flex;
	align-items: center;
	gap: 12px;
}

/* The logo lockup: compass mark plus the wordmark set in type. */
.wr-logo {
	display: inline-flex;
	align-items: center;
	gap: 12px;
	text-decoration: none;
	color: var(--wr-navy);
}

.wr-logo__mark {
	width: auto;
	height: var(--wr-mark-h);
	transition: height 0.3s var(--wr-ease);
}

.is-stuck .wr-logo__mark {
	height: var(--wr-mark-h-stuck);
}

.wr-logo__words {
	display: flex;
	flex-direction: column;
	line-height: 1;
}

.wr-logo__name {
	font-family: var(--wr-serif);
	font-size: 21px;
	/* 400 because DM Serif Display has no other weight — see section 1. */
	font-weight: 400;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	color: var(--wr-navy);
}

.wr-logo__sub {
	margin-top: 4px;
	font-size: 8.5px;
	font-weight: 500;
	letter-spacing: 0.22em;
	text-transform: uppercase;
	color: var(--wr-gold);
}

.wr-logo--light .wr-logo__name {
	color: var(--wr-on-dark);
}

.wr-logo--light .wr-logo__sub {
	color: var(--wr-gold-light);
}

/* WordPress's own custom-logo classes, for an uploaded Site Identity logo. */
.custom-logo-link {
	display: inline-block;
}

.custom-logo {
	height: var(--wr-mark-h);
	width: auto;
	transition: height 0.3s var(--wr-ease);
}

.is-stuck .custom-logo {
	height: var(--wr-mark-h-stuck);
}

/* Nav --------------------------------------------------------------------- */

.wr-nav__list {
	display: flex;
	align-items: center;
	gap: 28px;
}

.wr-nav__list a {
	position: relative;
	font-size: 14px;
	font-weight: 400;
	color: var(--wr-muted);
	text-decoration: none;
	padding: 4px 0;
}

.wr-nav__list a::after {
	content: '';
	position: absolute;
	left: 0;
	right: 0;
	bottom: 0;
	height: 1px;
	background: var(--wr-gold);
	transform: scaleX(0);
	transform-origin: left;
	transition: transform 0.25s var(--wr-ease);
}

.wr-nav__list a:hover,
/*
 * ONE selector for the active state, whichever way the nav was built: PHP sets
 * aria-current on a real wp_nav_menu, and main.js sets the same attribute from
 * scroll position on the one-page anchor nav.
 */
.wr-nav__list a[aria-current="page"] {
	color: var(--wr-navy);
}

.wr-nav__list a:hover::after,
.wr-nav__list a[aria-current="page"]::after {
	transform: scaleX(1);
}

.wr-header__cta {
	display: inline-flex;
	align-items: center;
	padding: 11px 22px;
	border: 1px solid var(--wr-navy);
	border-radius: 99px;
	background: var(--wr-navy);
	color: var(--wr-on-dark);
	font-size: 13px;
	font-weight: 500;
	letter-spacing: 0.01em;
	text-decoration: none;
	white-space: nowrap;
	transition: background 0.2s var(--wr-ease), border-color 0.2s var(--wr-ease), color 0.2s var(--wr-ease);
}

.wr-header__cta:hover {
	background: var(--wr-gold);
	border-color: var(--wr-gold);
	color: var(--wr-navy);
}

/* Toggle ------------------------------------------------------------------ */

.wr-nav-toggle {
	display: none;
	align-items: center;
	gap: 10px;
	padding: 8px 4px;
	background: none;
	border: 0;
	cursor: pointer;
	font-family: inherit;
	font-size: 11px;
	font-weight: 500;
	letter-spacing: 0.14em;
	text-transform: uppercase;
	color: var(--wr-navy);
}

/*
 * Three bars from one element: the middle is the element's own background, the
 * outer two are pseudo-elements. On open they become an ✕ — the middle fades
 * out and the other two rotate onto each other.
 */
.wr-nav-toggle__bars,
.wr-nav-toggle__bars::before,
.wr-nav-toggle__bars::after {
	display: block;
	width: 22px;
	height: 1.5px;
	background: currentColor;
	transition: transform 0.3s var(--wr-ease), opacity 0.2s var(--wr-ease);
}

.wr-nav-toggle__bars {
	position: relative;
}

.wr-nav-toggle__bars::before,
.wr-nav-toggle__bars::after {
	content: '';
	position: absolute;
	left: 0;
}

.wr-nav-toggle__bars::before {
	top: -7px;
}

.wr-nav-toggle__bars::after {
	top: 7px;
}

.wr-nav-toggle.is-active .wr-nav-toggle__bars {
	background: transparent;
}

.wr-nav-toggle.is-active .wr-nav-toggle__bars::before {
	transform: translateY(7px) rotate(45deg);
}

.wr-nav-toggle.is-active .wr-nav-toggle__bars::after {
	transform: translateY(-7px) rotate(-45deg);
}

/* Scrim and drawer -------------------------------------------------------- */

.wr-nav-scrim {
	position: fixed;
	inset: 0;
	z-index: 60;
	background: rgba(13, 27, 42, 0.5);
	opacity: 0;
	visibility: hidden;
	transition: opacity 0.3s var(--wr-ease), visibility 0s linear 0.3s;
}

.wr-nav-scrim.is-open {
	opacity: 1;
	visibility: visible;
	transition: opacity 0.3s var(--wr-ease), visibility 0s;
}

.wr-nav-mobile {
	position: fixed;
	top: 0;
	right: 0;
	bottom: 0;
	z-index: 62;
	width: min(86vw, 400px);

	/*
	 * WHITE, NOT NAVY. The panel used to be navy — which put a navy
	 * .wr-button--primary "Book a consultation" on a navy ground, so the site's
	 * primary call to action was a rectangle of the same colour as the panel
	 * behind it and effectively invisible. On white it reads as a button.
	 */
	background: #fff;
	color: var(--wr-body);
	box-shadow: -18px 0 48px -24px rgba(13, 27, 42, 0.45);
	transform: translateX(100%);
	visibility: hidden;
	overflow-y: auto;
	overscroll-behavior: contain;

	/*
	 * VISIBILITY IS SWITCHED BY TRANSITION *DELAY*, NOT DURATION, and the two
	 * directions differ on purpose.
	 *
	 * Opening is immediate: main.js calls .focus() on the panel on the same
	 * tick, and .focus() on a visibility:hidden element is a silent no-op.
	 * Closing is delayed by the length of the slide, so the panel stays on
	 * screen until it has finished leaving.
	 */
	transition: transform 0.34s var(--wr-ease), visibility 0s linear 0.34s;
}

.wr-nav-mobile.is-open {
	transform: translateX(0);
	visibility: visible;
	transition: transform 0.34s var(--wr-ease), visibility 0s;
}

.wr-nav-mobile__inner {
	display: flex;
	flex-direction: column;
	min-height: 100%;
	/*
	 * The top padding clears the fixed header, which sits ABOVE this panel in
	 * the stacking order so that the Menu toggle stays clickable — it is the
	 * only way to close the drawer. See the stacking note at the top of this
	 * section.
	 */
	padding: calc(var(--wr-header-h) + 20px) 28px 32px;
}

.wr-nav__list--mobile {
	flex-direction: column;
	align-items: stretch;
	gap: 0;
}

/*
 * The links inherit the body's 1.65 line-height unless told otherwise, which at
 * 20px put every row at 64px and the nine of them at 576px — over two-thirds of
 * a phone screen for a nine-item menu. Display leading and slightly tighter
 * padding bring a row to 50px, still comfortably over the 44px tap minimum.
 */
.wr-nav__list--mobile a {
	display: block;
	padding: 13px 0;
	border-bottom: 1px solid var(--wr-rule);
	font-family: var(--wr-serif);
	font-size: 19px;
	line-height: 1.25;
	color: var(--wr-navy);
}

.wr-nav__list--mobile a::after {
	display: none;
}

.wr-nav__list--mobile a:hover,
.wr-nav__list--mobile a[aria-current="page"] {
	color: var(--wr-gold-deep);
}

/*
 * THE CTA IS PINNED TO THE BOTTOM OF THE PANEL.
 *
 * It keeps its place in the document directly under the last menu item — the
 * reading order is still browse-then-book — but it stops scrolling out of
 * sight. A nine-item menu plus the logo is taller than a phone screen, so as an
 * ordinary block the site's primary call to action opened BELOW the fold of the
 * drawer: present, but only for someone who thought to scroll a menu.
 *
 * sticky rather than fixed, so it is bounded by the panel rather than the
 * viewport and cannot escape the drawer when it is closed. The panel is the
 * scrolling ancestor (overflow-y: auto above), which is what sticky resolves
 * against.
 *
 * The background is opaque and the rule sits on top, because the contact block
 * below scrolls underneath this rather than beside it.
 */
.wr-nav-mobile__cta {
	position: sticky;
	bottom: 0;
	z-index: 2;
	margin: 22px 0 0;
	padding: 14px 0 4px;
	background: #fff;
	box-shadow: 0 -12px 16px -8px rgba(255, 255, 255, 0.95);
}

.wr-nav-mobile__cta .wr-button {
	width: 100%;
	justify-content: center;
}

/*
 * margin-top:auto pins the contacts to the bottom. The gap it opens falls
 * between the CTA and the contacts, so the button stays with the menu it
 * follows and the contacts stay against the bottom edge whatever the drawer's
 * height. Once the menu is long enough to scroll, the gap closes and everything
 * simply flows.
 *
 * The bottom padding is clearance for the sticky CTA above, which the last
 * contact row would otherwise scroll underneath and never fully clear.
 */
.wr-nav-mobile__foot {
	margin-top: auto;
	padding-top: 32px;
	padding-bottom: 72px;
}

.wr-nav-mobile__heading {
	margin: 0 0 14px;
	font-family: var(--wr-sans);
	font-size: 11px;
	font-weight: 500;
	letter-spacing: 0.16em;
	text-transform: uppercase;
	color: var(--wr-muted);
}

.wr-nav-mobile__contacts {
	display: flex;
	flex-direction: column;
	gap: 12px;
	font-size: 14px;
}

/*
 * ICON AND DETAIL, ALIGNED.
 *
 * A grid rather than a flex row, so the icon has a column of its own and every
 * line of a wrapped address starts at the same x — under flex, the second line
 * of a wrapping value used to slide under the icon.
 *
 * The rows are centred, which is right for the single-line values (phone,
 * email) and, on a touch screen, keeps the icon against the middle of the 44px
 * tap target rather than floating at the top of it. Multi-line values override
 * this — see --block below.
 */
.wr-nav-mobile__contact {
	display: grid;
	grid-template-columns: 17px minmax(0, 1fr);
	align-items: center;
	gap: 0 12px;
	color: var(--wr-body);
}

/*
 * The address and the opening hours run to several lines, where a centred icon
 * would sit against the middle of the block and label nothing. These align to
 * the first line instead: the icon is 17px against a ~21px line, so 2px of top
 * margin puts it on the cap height.
 */
.wr-nav-mobile__contact--block {
	align-items: start;
}

.wr-nav-mobile__contact--block .wr-icon {
	margin-top: 2px;
}

.wr-nav-mobile__contact a {
	color: var(--wr-navy);
	text-decoration: none;
}

.wr-nav-mobile__contact a:hover {
	color: var(--wr-gold-deep);
}

.wr-nav-mobile__address,
.wr-nav-mobile__hours {
	font-style: normal;
	line-height: 1.5;
}

.wr-nav-mobile__hours {
	color: var(--wr-muted);
}

/* Icons ------------------------------------------------------------------- */

.wr-icon {
	flex: 0 0 auto;
	width: 17px;
	height: 17px;
	color: var(--wr-gold);
}


/* --------------------------------------------------------------------------
   6. Buttons and pills
   -------------------------------------------------------------------------- */

.wr-button {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 8px;
	padding: 13px 28px;
	border: 1px solid transparent;
	border-radius: 99px;
	font-family: var(--wr-sans);
	font-size: 14px;
	font-weight: 500;
	line-height: 1.2;
	text-decoration: none;
	cursor: pointer;
	transition: background 0.2s var(--wr-ease), color 0.2s var(--wr-ease), border-color 0.2s var(--wr-ease);
}

.wr-button--lg {
	padding: 16px 34px;
	font-size: 15px;
}

.wr-button--primary {
	background: var(--wr-navy);
	border-color: var(--wr-navy);
	color: var(--wr-on-dark);
}

.wr-button--primary:hover {
	background: var(--wr-navy-soft);
	border-color: var(--wr-navy-soft);
	color: var(--wr-on-dark);
}

.wr-button--secondary {
	background: transparent;
	border-color: var(--wr-rule-strong);
	color: var(--wr-navy);
}

.wr-button--secondary:hover {
	border-color: var(--wr-navy);
	background: var(--wr-navy);
	color: var(--wr-on-dark);
}

.wr-button--gold {
	background: var(--wr-gold);
	border-color: var(--wr-gold);
	color: var(--wr-navy);
}

.wr-button--gold:hover {
	background: var(--wr-gold-deep);
	border-color: var(--wr-gold-deep);
	color: var(--wr-on-dark);
}

/* On a dark ground: outlined until hovered. */
.wr-button--ghost {
	background: transparent;
	border-color: var(--wr-on-dark-46);
	color: var(--wr-on-dark);
}

.wr-button--ghost:hover {
	background: var(--wr-on-dark);
	border-color: var(--wr-on-dark);
	color: var(--wr-navy);
}

.wr-button[disabled],
.wr-button.is-busy {
	opacity: 0.6;
	cursor: progress;
}

.wr-button-row {
	display: flex;
	flex-wrap: wrap;
	gap: 12px;
	margin: 28px 0 0;
}

/* The small outlined label from the reference's hero. */
.wr-pill {
	display: inline-block;
	margin: 0 0 26px;
	padding: 7px 16px;
	border: 1px solid var(--wr-on-dark-46);
	border-radius: 99px;
	font-size: 10.5px;
	font-weight: 500;
	letter-spacing: 0.14em;
	text-transform: uppercase;
	color: var(--wr-on-dark-80);
}


/* --------------------------------------------------------------------------
   7. Sections and editorial blocks
   -------------------------------------------------------------------------- */

.wr-sectionhead {
	margin-bottom: clamp(36px, 4vw, 56px);
	max-width: 720px;
}

.wr-sectionhead--split {
	display: flex;
	flex-wrap: wrap;
	align-items: flex-end;
	justify-content: space-between;
	gap: 28px;
	max-width: none;
}

.wr-sectionhead__aside {
	max-width: 380px;
	margin: 0;
	font-size: 15px;
	color: var(--wr-muted);
}

.wr-sectionhead--light .wr-sectionhead__aside {
	color: var(--wr-on-dark-64);
}

/*
 * The editorial rhythm: headline left, body copy right.
 *
 * The reference this was taken from carried a third, narrow column to the LEFT
 * of the headline holding a small label ("Who we are", "Our network"). It is
 * gone: a label set beside a heading rather than above it reads as a stray
 * fragment — you get to it after the headline, not before, so it labels nothing.
 * Sections that still carry a label are the ones where it sits directly above
 * its heading and works as an introduction to it.
 */
.wr-editorial {
	display: grid;
	grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
	gap: 32px 48px;
	align-items: start;
}

.wr-editorial__body {
	/*
	 * The editorial grid's columns are fractions of a full-width container, so
	 * on a wide monitor this column would otherwise run to 1,000px and 180
	 * characters a line. Capping it here keeps the column a column.
	 */
	max-width: 56ch;
}

.wr-editorial__body > * + * {
	margin-top: 1.1em;
}

/* Vision and mission, side by side. */
.wr-statements {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: 32px;
	margin-top: clamp(48px, 6vw, 80px);
	padding-top: clamp(40px, 5vw, 64px);
	border-top: 1px solid var(--wr-rule);
}

.wr-statement__text {
	max-width: 46ch;
	font-family: var(--wr-serif);
	font-size: clamp(19px, 1.7vw, 24px);
	line-height: 1.42;
	color: var(--wr-navy);
}


/* --------------------------------------------------------------------------
   8. Home page components
   -------------------------------------------------------------------------- */

/* Hero -------------------------------------------------------------------- */

/*
 * Two columns, edge to edge — no container. The dark panel pads itself to the
 * container's left edge with a calc so the words still line up with every
 * section below, while the panel's background runs to the viewport edge.
 */
/*
 * The 1.2fr / 1fr split is not arbitrary. The panel's left padding grows with
 * the viewport (it lines the words up with every section below), so a narrower
 * column would leave the headline with LESS room as the screen gets wider, not
 * more — and "Connecting Futures." would wrap mid-phrase against the <br /> in
 * the markup.
 */
.wr-hero {
	display: grid;
	grid-template-columns: minmax(0, 1.2fr) minmax(0, 1fr);
	min-height: min(92vh, 860px);
	background: var(--wr-navy);
}

.wr-hero__panel {
	display: flex;
	align-items: center;
	background: var(--wr-navy);
	color: var(--wr-on-dark-80);
	/*
	 * The left padding is the plain gutter now that the container is full
	 * width. It used to be a max() against the old 1280px cap, to keep the
	 * hero words lined up with the centred content below; with nothing centred
	 * any more, the gutter does that on its own.
	 */
	padding: calc(var(--wr-header-h) + 48px) 40px 56px var(--wr-gutter);
}

/*
 * 780px, checked against the headline rather than picked by eye. "Connecting
 * Futures." sets at ~606px in DM Serif Display at the 68px cap, and the panel's
 * column leaves at least 688px from 1440px upward — so the line never wraps
 * against the <br /> in the markup. Raise --wr-h1-hero or narrow this and
 * re-measure before assuming it still holds.
 */
.wr-hero__panelinner {
	width: 100%;
	max-width: 780px;
}

.wr-hero__title {
	color: var(--wr-on-dark);
	font-size: var(--wr-h1-hero);
	margin-bottom: 26px;
}

.wr-hero__text {
	max-width: 52ch;
	font-size: clamp(16px, 1.2vw, 17.5px);
	color: var(--wr-on-dark-64);
}

.wr-hero__media {
	position: relative;
	min-height: 320px;
}

.wr-hero__media .wr-imagewell {
	position: absolute;
	inset: 0;
	background: var(--wr-navy-soft);
}

.wr-scrollcue {
	display: flex;
	align-items: center;
	gap: 12px;
	margin: 56px 0 0;
	font-size: 10.5px;
	font-weight: 500;
	letter-spacing: 0.18em;
	text-transform: uppercase;
	color: var(--wr-on-dark-46);
}

.wr-scrollcue__dot {
	position: relative;
	display: block;
	width: 28px;
	height: 1px;
	background: var(--wr-on-dark-46);
	overflow: hidden;
}

.wr-scrollcue__dot::after {
	content: '';
	position: absolute;
	inset: 0;
	background: var(--wr-gold);
	transform: translateX(-100%);
	animation: wr-cue 2.4s var(--wr-ease) infinite;
}

@keyframes wr-cue {
	0%   { transform: translateX(-100%); }
	55%  { transform: translateX(0); }
	100% { transform: translateX(100%); }
}

/* Values ------------------------------------------------------------------ */

.wr-valuegrid {
	display: grid;
	grid-template-columns: repeat(3, minmax(0, 1fr));
	gap: 1px;
	background: var(--wr-rule);
	border: 1px solid var(--wr-rule);
}

.wr-value {
	padding: 30px 28px;
	background: var(--wr-sand);
}

.wr-value__name {
	margin-bottom: 8px;
	font-family: var(--wr-serif);
	font-size: 20px;
	color: var(--wr-navy);
}

.wr-value__text {
	font-size: 14.5px;
	color: var(--wr-muted);
}

/* Programmes: a sticky panel and a column of expanding cards -------------- */

/*
 * HOW THIS SECTION WORKS
 *
 * Two columns. The left one is position:sticky, so the photograph and the
 * heading stay fixed in view while the right column scrolls its cards past
 * them. That is the whole effect — no scroll listeners, no IntersectionObserver,
 * no library, which is why it stays smooth on a mid-range Android phone and
 * costs nothing on the main thread.
 *
 * ONE THING BREAKS IT, SILENTLY: overflow:hidden (or auto/scroll/clip) on ANY
 * ancestor. Sticky positions against the nearest scrolling ancestor, and a
 * clipping one takes that job and pins the panel inside a box that is scrolling
 * away with it. Nothing errors; the panel simply behaves as if it were static.
 *
 * The cards themselves are ORDINARY FLOW. They used to be sticky too — each one
 * pinning a few pixels below the last so the deck gathered into a stack — and
 * that is gone deliberately: a card now opens to a full programme spread from
 * the capability statement, which is far taller than the viewport, and a sticky
 * element taller than the viewport has its own bottom cut off with no way to
 * reach it. Do not put it back without solving that first.
 *
 * The cards must still be tall enough, together, to out-scroll the panel — with
 * nine of them that is not a concern, but it is why this pattern is wrong for a
 * section with two or three items.
 */

.wr-programmes-section {
	display: grid;
	grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
	align-items: start;

	/*
	 * A hard split down the middle rather than one flat colour, because the
	 * panel is shorter than the column of cards beside it: it unsticks and
	 * scrolls away while the last cards are still going past — and an opened
	 * card leaves it behind sooner still. With a single light ground that read
	 * as the image falling through a hole. With the left half already navy, the
	 * panel simply slides off its own colour and the hand-off to the next
	 * section looks deliberate.
	 */
	background: linear-gradient(to right, var(--wr-navy) 0 50%, var(--wr-sand) 50% 100%);
}

/* The panel ---------------------------------------------------------------- */

.wr-programmes__panel {
	position: sticky;
	top: var(--wr-header-h-stuck);

	/*
	 * svh, not vh. On mobile browsers vh is the height with the address bar
	 * hidden, so a 100vh sticky panel is taller than what you can actually see
	 * and its bottom — where the heading sits — stays cropped off until the bar
	 * retracts. svh is the SMALL viewport height: the bar-visible one, which is
	 * the state the panel has to look right in. The vh line before it is the
	 * fallback for browsers that do not know svh.
	 */
	height: calc(100vh - var(--wr-header-h-stuck));
	height: calc(100svh - var(--wr-header-h-stuck));

	display: flex;
	align-items: flex-end;
	overflow: hidden; /* Safe HERE: it clips the panel's own image, not the sticky ancestors. */
	background: var(--wr-navy);
}

.wr-programmes__panel .wr-imagewell {
	position: absolute;
	inset: 0;
	background: var(--wr-navy);
}

/*
 * The scrim. It is on the panel rather than baked into the photograph, so the
 * heading stays legible over whatever image the client uploads — nobody
 * choosing a picture in wp-admin should have to think about text contrast.
 */
.wr-programmes__panel::after {
	content: '';
	position: absolute;
	inset: 0;
	background: linear-gradient(to top, rgba(13, 27, 42, 0.94) 0%, rgba(13, 27, 42, 0.72) 42%, rgba(13, 27, 42, 0.34) 100%);
}

.wr-programmes__panelinner {
	position: relative; /* Above the scrim. */
	z-index: 1;
	padding: var(--wr-gutter);
	padding-bottom: clamp(40px, 5vw, 72px);
	max-width: 620px;
}

.wr-programmes__title {
	color: var(--wr-on-dark);
	margin-bottom: 18px;
}

.wr-programmes__intro {
	max-width: 46ch;
	font-size: clamp(15.5px, 1.2vw, 17px);
	color: var(--wr-on-dark-64);
}

/* The cards ---------------------------------------------------------------- */

.wr-programmes__list {
	padding: clamp(48px, 6vw, 96px) var(--wr-gutter);
}

.wr-programmes {
	display: flex;
	flex-direction: column;
	gap: 22px;
}

.wr-programme {
	background: #fff;
	border-top: 2px solid var(--wr-gold);
	box-shadow: 0 -1px 0 var(--wr-rule), 0 18px 40px -24px rgba(13, 27, 42, 0.35);
}

/* The head: number, name, summary, and the plus ---------------------------- */

/*
 * Two columns: everything readable on the left, the plus on the right. The
 * number spans both so its rule still runs the full width of the card.
 *
 * The children are placed rather than wrapped because <summary> may only hold
 * phrasing content and a heading — a <div> around the left column would be
 * invalid markup, so grid does the grouping that nesting normally would.
 */
.wr-programme__summary {
	display: grid;
	grid-template-columns: minmax(0, 1fr) auto;
	column-gap: clamp(20px, 2.5vw, 36px);
	align-items: start;
	padding: clamp(28px, 3vw, 40px);
	cursor: pointer;

	/*
	 * Both lines are needed to drop the browser's own disclosure triangle:
	 * Firefox and Chromium honour list-style, Safari only the ::marker
	 * pseudo-element below.
	 */
	list-style: none;
}

.wr-programme__summary::-webkit-details-marker {
	display: none;
}

/*
 * The outline goes on the summary, not the card, because the summary is what
 * actually takes focus. Inset rather than offset: an outline drawn outside the
 * summary would be clipped by the card edge it sits flush against.
 */
.wr-programme__summary:focus-visible {
	outline: 2px solid var(--wr-gold);
	outline-offset: -4px;
}

.wr-programme__step {
	display: block;
	grid-column: 1 / -1;
	margin: 0 0 14px;
	padding-bottom: 12px;
	border-bottom: 1px solid var(--wr-rule);
	font-size: 11px;
	font-weight: 500;
	letter-spacing: 0.16em;
	text-transform: uppercase;
	color: var(--wr-gold-deep);
}

.wr-programme__title {
	grid-column: 1;
	margin-bottom: 10px;
	font-size: clamp(21px, 1.9vw, 27px);
	transition: color 0.2s ease;
}

.wr-programme__text {
	display: block;
	grid-column: 1;
	max-width: 52ch;
	font-size: 15px;
	color: var(--wr-muted);
}

/*
 * The plus. It sits in the second column and spans the title and summary rows,
 * centred against them, so it holds the same optical position whether the card
 * front runs to one line of summary or three.
 */
.wr-programme__toggle {
	display: flex;
	align-items: center;
	justify-content: center;
	grid-column: 2;
	grid-row: 2 / span 2;
	align-self: center;
	width: 40px;
	height: 40px;
	border: 1px solid var(--wr-rule-strong);
	border-radius: 50%;
	color: var(--wr-navy);
	transition: background-color 0.2s ease, border-color 0.2s ease, color 0.2s ease;
}

.wr-programme__toggle .wr-icon {
	width: 18px;
	height: 18px;
	color: inherit;
}

/*
 * Plus to minus, by collapsing the upright stroke rather than swapping in a
 * second icon — so the change animates, and there is only ever one drawing to
 * keep in step with the brand.
 *
 * transform-box: fill-box makes the stroke rotate about its own centre; without
 * it the origin is the SVG viewport's, and the stroke swings away instead of
 * closing in place.
 */
.wr-icon__upright {
	transform-box: fill-box;
	transform-origin: center;
	transition: transform 0.25s ease;
}

.wr-programme__disclosure[open] .wr-icon__upright {
	transform: scaleY(0);
}

.wr-programme__summary:hover .wr-programme__toggle,
.wr-programme__disclosure[open] .wr-programme__toggle {
	border-color: var(--wr-gold);
	background: var(--wr-gold);
	color: var(--wr-on-dark);
}

.wr-programme__summary:hover .wr-programme__title {
	color: var(--wr-gold-deep);
}

/* Motion is a courtesy, never a requirement. */
@media (prefers-reduced-motion: reduce) {

	.wr-icon__upright {
		transition: none;
	}
}

/* The overview ------------------------------------------------------------- */

/*
 * What is behind the plus: two or three paragraphs of the capability
 * statement's own prose, and nothing else. It is separated from the head by a
 * rule rather than by a gap, which would read as a second card.
 *
 * There is deliberately no list styling here. The programmes' itemised service
 * lists are not on the card — see the note at the top of inc/programmes.php
 * before adding them back.
 */
.wr-programme__detail {
	padding: clamp(24px, 2.4vw, 32px) clamp(28px, 3vw, 40px) clamp(28px, 3vw, 40px);
	border-top: 1px solid var(--wr-rule);
}

.wr-programme__lead {
	max-width: 62ch;
	font-size: 15px;
	color: var(--wr-body);
}

.wr-programme__lead + .wr-programme__lead {
	margin-top: 14px;
}

/* Audiences --------------------------------------------------------------- */

.wr-audiences {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: 2px 48px;
	margin-top: clamp(40px, 5vw, 64px);
}

/*
 * Each row is a tick, a name and the line the document gives that audience.
 * align-items: flex-start, not center — the row is now two lines deep and a
 * centred tick would float between them instead of marking the name.
 */
.wr-audience {
	display: flex;
	align-items: flex-start;
	gap: 12px;
	padding: 15px 0;
	border-bottom: 1px solid var(--wr-rule);
	font-size: 15.5px;
	color: var(--wr-ink);
}

/* Optical alignment: the tick sits with the name's cap height, not its box. */
.wr-audience .wr-icon {
	margin-top: 3px;
}

.wr-audience__body {
	display: flex;
	flex-direction: column;
	gap: 3px;
}

.wr-audience__name {
	font-weight: 500;
}

.wr-audience__text {
	font-size: 14px;
	color: var(--wr-muted);
}

/* Pillars ----------------------------------------------------------------- */

.wr-pillars {
	display: grid;
	grid-template-columns: repeat(3, minmax(0, 1fr));
	gap: 40px 48px;
}

.wr-pillar .wr-icon {
	width: 26px;
	height: 26px;
	margin-bottom: 16px;
}

.wr-pillar__name {
	margin-bottom: 8px;
	font-size: var(--wr-h3);
}

.wr-pillar__text {
	font-size: 14.5px;
	color: var(--wr-muted);
}

/* Journey ----------------------------------------------------------------- */

/*
 * Eight stages across four columns. The connecting hairline is a pseudo-element
 * on each step rather than a border on the grid, so it stops at the last item
 * in each row instead of running off the edge.
 */
.wr-journey {
	display: grid;
	grid-template-columns: repeat(4, minmax(0, 1fr));
	gap: 40px 32px;
}

.wr-journey__step {
	position: relative;
	padding-top: 26px;
	border-top: 1px solid var(--wr-rule-light);
}

.wr-journey__step::before {
	content: '';
	position: absolute;
	top: -3px;
	left: 0;
	width: 5px;
	height: 5px;
	border-radius: 50%;
	background: var(--wr-gold);
}

.wr-journey__num {
	display: block;
	margin-bottom: 10px;
	font-size: 11px;
	font-weight: 500;
	letter-spacing: 0.14em;
	color: var(--wr-gold-light);
}

.wr-journey__name {
	margin-bottom: 8px;
	font-size: var(--wr-h3);
	color: var(--wr-on-dark);
}

.wr-journey__text {
	font-size: 14px;
	color: var(--wr-on-dark-64);
}

/* Why Windrose ------------------------------------------------------------ */

.wr-why {
	display: grid;
	grid-template-columns: minmax(0, 0.85fr) minmax(0, 1.15fr);
	gap: 48px 64px;
	align-items: start;
}

.wr-why__intro {
	margin-top: 22px;
	font-size: 15.5px;
	color: var(--wr-muted);
}

.wr-reasons {
	display: flex;
	flex-direction: column;
}

.wr-reason {
	display: flex;
	gap: 22px;
	padding: 24px 0;
	border-bottom: 1px solid var(--wr-rule);
}

.wr-reason:first-child {
	padding-top: 0;
}

.wr-reason:last-child {
	border-bottom: 0;
	padding-bottom: 0;
}

.wr-reason__num {
	flex: 0 0 auto;
	font-family: var(--wr-serif);
	font-size: 17px;
	line-height: 1.4;
	color: var(--wr-gold);
}

.wr-reason__name {
	margin-bottom: 6px;
	font-family: var(--wr-sans);
	font-size: 16px;
	font-weight: 600;
	color: var(--wr-navy);
	letter-spacing: 0;
}

.wr-reason__text {
	font-size: 14.5px;
	color: var(--wr-muted);
}

/* Partner network tags ---------------------------------------------------- */

.wr-tags {
	display: flex;
	flex-wrap: wrap;
	gap: 10px;
	margin-top: clamp(36px, 4vw, 56px);
}

.wr-tag {
	padding: 9px 18px;
	border: 1px solid var(--wr-rule-strong);
	border-radius: 99px;
	font-size: 13.5px;
	color: var(--wr-ink);
}

/* The line under the tags that says what the network is for. */
.wr-network__note {
	max-width: 68ch;
	margin-top: clamp(28px, 3vw, 40px);
	font-size: 15px;
	color: var(--wr-muted);
}


/* --------------------------------------------------------------------------
   9. Booking page and forms
   -------------------------------------------------------------------------- */

.wr-pagehead {
	padding-bottom: clamp(40px, 4vw, 64px);
}

/*
 * The one place on the site that is NOT full width. Everything else gains from
 * running edge to edge; a form does not — without a cap this grid reaches
 * ~1300px on a wide monitor and every text input with it, which is unpleasant
 * to fill in and reads as broken rather than generous.
 *
 * margin-inline:0 rather than the .wr-container default of auto, so the capped
 * block still starts on the gutter and lines up with the page heading above it
 * instead of floating in the middle of the viewport.
 */
.wr-booking {
	display: grid;
	grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr);
	gap: 48px 64px;
	align-items: start;
	max-width: 1400px;
	margin-inline: 0;
}

.wr-form__grid {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: 22px;
}

.wr-field {
	display: flex;
	flex-direction: column;
	gap: 7px;
}

.wr-field--full {
	grid-column: 1 / -1;
}

.wr-label {
	font-size: 12.5px;
	font-weight: 500;
	letter-spacing: 0.05em;
	text-transform: uppercase;
	color: var(--wr-muted);
}

.wr-req {
	color: var(--wr-gold-deep);
}

.wr-hint {
	font-size: 12.5px;
	color: var(--wr-muted);
}

.wr-input,
.wr-select,
.wr-textarea {
	width: 100%;
	padding: 13px 15px;
	background: #fff;
	border: 1px solid var(--wr-rule-strong);
	border-radius: var(--wr-radius);
	font-family: inherit;
	font-size: 15px;
	color: var(--wr-ink);
	transition: border-color 0.2s var(--wr-ease), box-shadow 0.2s var(--wr-ease);
}

.wr-textarea {
	resize: vertical;
	min-height: 130px;
}

.wr-input:focus,
.wr-select:focus,
.wr-textarea:focus {
	outline: none;
	border-color: var(--wr-gold);
	box-shadow: 0 0 0 3px var(--wr-gold-wash);
}

.wr-input[aria-invalid="true"],
.wr-textarea[aria-invalid="true"] {
	border-color: #B4382F;
}

.wr-error {
	font-size: 13px;
	color: #B4382F;
}

.wr-form__submit {
	margin-top: 30px;
}

.wr-form__note {
	margin: 14px 0 0;
	max-width: 60ch;
	font-size: 13.5px;
	color: var(--wr-muted);
}

/* Status banners ---------------------------------------------------------- */

.wr-status {
	margin-bottom: 28px;
	padding: 20px 24px;
	border-left: 3px solid var(--wr-gold);
	background: var(--wr-sand);
}

.wr-status--error {
	border-left-color: #B4382F;
	background: #FBEDEC;
}

.wr-status--warning {
	border-left-color: var(--wr-gold);
	background: var(--wr-gold-wash);
}

.wr-status__title {
	margin: 0 0 6px;
	font-family: var(--wr-serif);
	font-size: 19px;
	color: var(--wr-navy);
}

.wr-status__text {
	margin: 0;
	font-size: 14.5px;
}

/* Booking aside ----------------------------------------------------------- */

.wr-booking__aside > * + * {
	margin-top: 32px;
}

.wr-feecard {
	padding: 28px;
	background: var(--wr-navy);
	color: var(--wr-on-dark-80);
}

.wr-feecard .wr-eyebrow {
	color: var(--wr-gold-light);
}

.wr-feecard__amount {
	margin: 0 0 12px;
	font-family: var(--wr-serif);
	font-size: clamp(30px, 3vw, 40px);
	line-height: 1;
	color: var(--wr-on-dark);
}

.wr-feecard__text {
	font-size: 14.5px;
	color: var(--wr-on-dark-80);
}

.wr-feecard__methods {
	margin: 16px 0 0;
	padding-top: 16px;
	border-top: 1px solid var(--wr-rule-light);
	font-size: 13px;
	color: var(--wr-on-dark-64);
}

.wr-steps__title,
.wr-asidecontact__title {
	margin-bottom: 16px;
	font-family: var(--wr-sans);
	font-size: 12px;
	font-weight: 500;
	letter-spacing: 0.16em;
	text-transform: uppercase;
	color: var(--wr-muted);
}

.wr-steps__list {
	display: flex;
	flex-direction: column;
}

.wr-steps__item {
	display: flex;
	gap: 16px;
	padding: 14px 0;
	border-bottom: 1px solid var(--wr-rule);
	font-size: 14.5px;
	color: var(--wr-ink);
}

.wr-steps__item:last-child {
	border-bottom: 0;
}

.wr-steps__num {
	flex: 0 0 auto;
	font-family: var(--wr-serif);
	color: var(--wr-gold);
}

.wr-asidecontact__list {
	display: flex;
	flex-direction: column;
	gap: 10px;
	font-size: 14.5px;
}

.wr-asidecontact__list li {
	display: flex;
	align-items: center;
	gap: 10px;
}

/* Receipt ----------------------------------------------------------------- */

.wr-receipt {
	margin: 32px 0 20px;
	border-top: 1px solid var(--wr-rule);
}

.wr-receipt__row {
	display: flex;
	flex-wrap: wrap;
	gap: 8px 24px;
	padding: 13px 0;
	border-bottom: 1px solid var(--wr-rule);
	font-size: 14.5px;
}

.wr-receipt__row dt {
	flex: 0 0 200px;
	color: var(--wr-muted);
}

.wr-receipt__row dd {
	margin: 0;
	color: var(--wr-ink);
	font-weight: 500;
}


/* --------------------------------------------------------------------------
   10. Bands: promise, CTA, connect
   -------------------------------------------------------------------------- */

/*
 * The promise band. The photograph sits behind the words, so the scrim is put
 * here in CSS rather than relying on whatever gets uploaded being dark enough —
 * a bright image would otherwise make the headline unreadable, and nobody
 * choosing a photograph in wp-admin should have to think about that.
 */
.wr-promise {
	position: relative;
	padding: clamp(80px, 10vw, 152px) 0;
	background: var(--wr-navy);
	color: var(--wr-on-dark-80);
	overflow: hidden;
}

.wr-promise__media {
	position: absolute;
	inset: 0;
}

.wr-promise__media .wr-imagewell {
	height: 100%;
	background: var(--wr-navy);
}

.wr-promise__media::after {
	content: '';
	position: absolute;
	inset: 0;
	background: linear-gradient(100deg, rgba(13, 27, 42, 0.93) 0%, rgba(13, 27, 42, 0.82) 48%, rgba(13, 27, 42, 0.55) 100%);
}

/*
 * margin-inline:0 matters. This element is also a .wr-container, which centres
 * itself — harmless when the container was capped at 1280px and the band was
 * only a little wider than its text, but at full width a 900px block centred in
 * a 1920px viewport sits ~500px in from the edge, out of line with every other
 * section on the page. Pinning it to the gutter puts it back in the same
 * left-hand rhythm.
 */
.wr-promise__inner {
	position: relative;
	max-width: 900px;
	margin-inline: 0;
}

.wr-promise__title {
	margin-bottom: 22px;
	font-size: var(--wr-promise);
	color: var(--wr-on-dark);
}

.wr-promise__text {
	max-width: 62ch;
	font-size: clamp(15.5px, 1.2vw, 17px);
	color: var(--wr-on-dark-64);
}

/* CTA band ---------------------------------------------------------------- */

.wr-cta {
	padding: clamp(64px, 8vw, 120px) 0;
	background: var(--wr-navy-deep);
	color: var(--wr-on-dark-80);
	text-align: center;
}

.wr-cta__inner {
	max-width: 760px;
}

.wr-cta__title {
	margin-bottom: 18px;
	font-size: var(--wr-h2);
	color: var(--wr-on-dark);
}

.wr-cta__text {
	max-width: 56ch;
	margin-inline: auto;
	color: var(--wr-on-dark-64);
}

.wr-cta__actions {
	display: flex;
	justify-content: center;
	margin: 32px 0 0;
}

/* Connect strip ----------------------------------------------------------- */

.wr-connect {
	padding: 30px 0;
	background: var(--wr-navy);
	border-top: 1px solid var(--wr-rule-light);
	color: var(--wr-on-dark-80);
}

.wr-connect__inner {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: 20px 40px;
}

.wr-connect__title {
	margin: 0;
	font-size: clamp(20px, 2vw, 26px);
	color: var(--wr-on-dark);
}

.wr-connect__list {
	display: flex;
	flex-wrap: wrap;
	gap: 14px 32px;
	font-size: 14.5px;
}

.wr-connect__item {
	display: flex;
	align-items: center;
	gap: 10px;
}

.wr-connect__item a,
.wr-connect__item span {
	color: var(--wr-on-dark-80);
	text-decoration: none;
}

.wr-connect__item a:hover {
	color: var(--wr-gold-light);
}


/* --------------------------------------------------------------------------
   11. Footer
   -------------------------------------------------------------------------- */

.wr-footer {
	padding: clamp(56px, 6vw, 88px) 0 0;
	background: var(--wr-navy-deep);
	color: var(--wr-on-dark-64);
	font-size: 14.5px;
}

.wr-footer__inner {
	display: grid;
	grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr) minmax(0, 1.2fr);
	gap: 40px 56px;
	padding-bottom: clamp(40px, 5vw, 64px);
}

/*
 * The footer mark. Portrait or square, uploaded in the Customizer — it replaced
 * the horizontal lockup, the tagline and the descriptive paragraph that used to
 * fill this column.
 *
 * The size is capped in both directions because the file is the client's to
 * choose: a tall portrait crop is held by max-height so it cannot push the
 * column past the two beside it, and a wide one by max-width so it cannot run
 * into them.
 */
.wr-footer__logo {
	display: inline-block;
}

.wr-footer__logo img {
	width: auto;
	max-width: min(260px, 100%);
	max-height: 190px;
	object-fit: contain;
	object-position: left top;
}

/*
 * The shipped white lockup is a wide horizontal file, so it is held to the
 * header mark's proportions rather than blown up to the portrait cap that an
 * uploaded square logo is allowed to fill.
 */
.wr-footer__logo--fallback img {
	max-width: min(210px, 100%);
	max-height: 64px;
}

.wr-footer__heading {
	margin: 0 0 18px;
	font-family: var(--wr-sans);
	font-size: 11px;
	font-weight: 500;
	letter-spacing: 0.16em;
	text-transform: uppercase;
	color: var(--wr-gold-light);
}

.wr-nav__list--footer {
	flex-direction: column;
	align-items: flex-start;
	gap: 10px;
}

.wr-nav__list--footer a {
	color: var(--wr-on-dark-64);
	font-size: 14.5px;
}

.wr-nav__list--footer a:hover,
.wr-nav__list--footer a[aria-current="page"] {
	color: var(--wr-on-dark);
}

.wr-footer__contacts {
	display: flex;
	flex-direction: column;
	gap: 9px;
}

.wr-footer__contacts a,
.wr-footer__contacts span {
	color: var(--wr-on-dark-64);
	text-decoration: none;
}

.wr-footer__contacts a:hover {
	color: var(--wr-gold-light);
}

.wr-footer__address {
	font-style: normal;
}

.wr-footer__hours {
	color: var(--wr-on-dark-46);
}

.wr-footer__social {
	display: flex;
	gap: 18px;
	margin-top: 20px;
	font-size: 12px;
	letter-spacing: 0.08em;
	text-transform: uppercase;
}

.wr-footer__social a {
	color: var(--wr-on-dark-64);
	text-decoration: none;
}

.wr-footer__social a:hover {
	color: var(--wr-gold-light);
}

.wr-footer__legal {
	display: flex;
	flex-wrap: wrap;
	justify-content: space-between;
	gap: 10px 32px;
	padding-top: 22px;
	padding-bottom: 26px;
	border-top: 1px solid var(--wr-rule-light);
	font-size: 12.5px;
	color: var(--wr-on-dark-46);
}

.wr-footer__legal p {
	margin: 0;
}

/*
 * The build credit. Underlined rather than left to colour alone, because at
 * 12.5px on a dark ground a colour shift is not a reliable signal that
 * something is a link.
 */
.wr-footer__credit {
	color: var(--wr-on-dark-64);
	text-decoration: underline;
	text-decoration-color: var(--wr-gold);
	text-underline-offset: 3px;
}

.wr-footer__credit:hover,
.wr-footer__credit:focus-visible {
	color: var(--wr-gold-light);
}


/* --------------------------------------------------------------------------
   12. Archive, single and editor content
   --------------------------------------------------------------------------
   index.php, single.php and comments.php were written to match the rest of the
   site but the classes they use were never given rules, so a Posts page or a
   single post rendered as unstyled browser defaults. Nothing links here in
   Phase 1; it is styled now so the Learning Centre arrives on-brand rather than
   bare, and so a stray /?p=1 does not look broken.

   THE CONTENT RULES BELOW MATTER ON MOBILE. the_content() emits whatever the
   editor put in — a pasted table, a YouTube embed, a code block, a long URL —
   and none of it is width-aware. Each one is the classic cause of a page that
   scrolls sideways on a phone, so each is contained here rather than left to
   chance.
   -------------------------------------------------------------------------- */

.wr-cardgrid {
	display: grid;
	grid-template-columns: repeat(3, minmax(0, 1fr));
	gap: 1px;
	background: var(--wr-rule);
	border: 1px solid var(--wr-rule);
}

.wr-card {
	padding: 30px 28px;
	background: var(--wr-sand);
}

.wr-card__title {
	margin-bottom: 8px;
	font-size: 20px;
}

.wr-card__title a {
	text-decoration: none;
}

.wr-card__meta {
	margin-bottom: 10px;
	font-size: 11px;
	font-weight: 500;
	letter-spacing: 0.16em;
	text-transform: uppercase;
	color: var(--wr-muted);
}

.wr-card__text {
	font-size: 14.5px;
	color: var(--wr-muted);
}

/* Pagination — WordPress's own markup from the_posts_pagination(). */
.wr-section .navigation.pagination {
	margin-top: clamp(36px, 4vw, 56px);
}

.wr-section .nav-links {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 10px;
}

.wr-section .page-numbers {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 44px;
	min-height: 44px;
	padding: 0 14px;
	border: 1px solid var(--wr-rule-strong);
	border-radius: 99px;
	font-size: 14px;
	text-decoration: none;
	color: var(--wr-navy);
}

.wr-section a.page-numbers:hover {
	border-color: var(--wr-navy);
	background: var(--wr-navy);
	color: var(--wr-on-dark);
}

.wr-section .page-numbers.current {
	border-color: var(--wr-gold);
	background: var(--wr-gold);
	color: var(--wr-navy);
}

.wr-section .page-numbers.dots {
	border-color: transparent;
	min-width: 0;
	padding: 0 4px;
}

/* Comments ---------------------------------------------------------------- */

.wr-comments {
	margin-top: clamp(48px, 6vw, 80px);
	padding-top: clamp(32px, 4vw, 48px);
	border-top: 1px solid var(--wr-rule);
}

.wr-comments__list {
	display: flex;
	flex-direction: column;
	gap: 24px;
	margin-top: 24px;
}

.wr-comments__list li {
	padding-bottom: 24px;
	border-bottom: 1px solid var(--wr-rule);
}

.wr-comments__list li:last-child {
	border-bottom: 0;
	padding-bottom: 0;
}

/* Editor content ---------------------------------------------------------- */

/*
 * A pasted table is the one piece of editor content that cannot simply be told
 * to shrink — its columns have a minimum width and it will push the page wider
 * than the phone. It scrolls inside its own box instead, which keeps the table
 * whole and the page still.
 */
.wr-prose table {
	display: block;
	width: 100%;
	overflow-x: auto;
	border-collapse: collapse;
	font-size: 14.5px;
}

.wr-prose th,
.wr-prose td {
	padding: 10px 14px;
	border: 1px solid var(--wr-rule);
	text-align: left;
}

.wr-prose th {
	background: var(--wr-sand);
	font-weight: 600;
	color: var(--wr-navy);
}

/*
 * Embeds. WordPress wraps oEmbeds in .wp-block-embed__wrapper; a bare <iframe>
 * pasted into the editor gets the same treatment. aspect-ratio keeps the frame
 * in proportion once the width is capped.
 */
.wr-prose iframe,
.wr-prose embed,
.wr-prose object,
.wr-prose video {
	display: block;
	max-width: 100%;
	width: 100%;
	aspect-ratio: 16 / 9;
	height: auto;
	border: 0;
}

.wr-prose figure {
	margin: 1.6em 0;
}

.wr-prose figcaption {
	margin-top: 10px;
	font-size: 13px;
	color: var(--wr-muted);
}

.wr-prose blockquote {
	margin: 1.6em 0;
	padding: 4px 0 4px 22px;
	border-left: 2px solid var(--wr-gold);
	font-family: var(--wr-serif);
	font-size: clamp(18px, 1.6vw, 22px);
	line-height: 1.45;
	color: var(--wr-navy);
}

.wr-prose pre {
	overflow-x: auto;
	padding: 18px 20px;
	background: var(--wr-navy);
	color: var(--wr-on-dark-80);
	font-size: 13.5px;
	line-height: 1.6;
}

.wr-prose code {
	font-size: 0.92em;
}

.wr-prose :not(pre) > code {
	padding: 2px 6px;
	background: var(--wr-sand);
	border-radius: 3px;
}

/*
 * Lists inside editor content. The global reset strips markers from every ul
 * and ol on the site because every list in the layout is a styled component;
 * prose is the one place a plain bulleted list is meant to look like one.
 */
.wr-prose ul,
.wr-prose ol {
	margin: 1.1em 0;
	padding-left: 1.4em;
	list-style: revert;
}

.wr-prose li + li {
	margin-top: 0.4em;
}

/*
 * A long unbroken string — a URL, a file path, an email in running text — is
 * the last thing that can force a phone to scroll sideways. Breaking it is
 * always better than breaking the page.
 */
.wr-prose {
	overflow-wrap: break-word;
}


/* --------------------------------------------------------------------------
   13. Responsive
   --------------------------------------------------------------------------
   NO MOBILE COMPOSITION WAS SUPPLIED, so everything here is derived. The grids
   collapse in a stated order:

     1100px — three-across becomes two; the nav becomes a toggle opening the
               drawer (see the note on that block — it is NOT 900px, and why)
      900px — the hero stacks; the editorial pattern becomes one column
      640px — single column throughout

   Reviewed as a unit here rather than scattered through the file, so a change
   at one width can be checked against the others.

   TAP TARGET AND INPUT SIZING IS NOT HERE — it is in section 14, keyed to the
   pointer rather than the width, for the reason given there.
   -------------------------------------------------------------------------- */

@media (max-width: 1100px) {

	/*
	 * THE NAV COLLAPSES AT 1100px, NOT 900px.
	 *
	 * It used to be 900. The primary nav carries nine items and will not shrink
	 * or wrap: at its narrowest it needs ~692px, and beside the logo and the
	 * "Book a consultation" button that does not fit until about 1100px. The
	 * header's grid is `auto 1fr auto`, so the overflow had nowhere to go and
	 * pushed the CTA clean off the right-hand edge — 186px off at 901px, still
	 * 68px off at 1024px, which is an iPad in landscape and the most common
	 * tablet width there is.
	 *
	 * It never showed up as a sideways scroll, and that is why it survived: the
	 * header is position:fixed, so an overflowing child does not extend the
	 * document. The page looked fine and the primary conversion button was
	 * simply not on screen.
	 *
	 * If the nav ever loses items, this can come back down — measure the nav's
	 * min-content width against the viewport before moving it.
	 *
	 * main.js closes the drawer on resize past this same width. THE TWO MUST
	 * MATCH: see the matchMedia call in initDrawer().
	 */
	.wr-header__nav,
	.wr-header__cta {
		display: none;
	}

	.wr-nav-toggle {
		display: inline-flex;
	}

	/*
	 * Two columns now, and each item names its own grid-column deliberately: a
	 * display:none grid item is removed from the grid rather than leaving its
	 * cell empty, so under automatic placement hiding the nav would pull the
	 * actions back into column 2 and strand the layout mid-header.
	 */
	.wr-header__inner {
		grid-template-columns: auto auto;
		justify-content: space-between;
	}

	.wr-header__brand {
		grid-column: 1;
	}

	.wr-header__actions {
		grid-column: 2;
	}

	.wr-valuegrid,
	.wr-pillars,
	.wr-cardgrid {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}

	.wr-journey {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}

	.wr-why {
		grid-template-columns: minmax(0, 1fr);
	}

	.wr-booking {
		grid-template-columns: minmax(0, 1fr);
	}

	.wr-footer__inner {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}

	.wr-footer__brand {
		grid-column: 1 / -1;
	}
}

@media (max-width: 900px) {

	:root {
		--wr-header-h: 72px;
		--wr-header-h-stuck: 62px;
	}

	/*
	 * The editorial pattern goes to one column here rather than at 640px.
	 * Headline beside body copy needs both columns to hold a reading measure,
	 * and below this width each is under 400px — a column of prose about six
	 * words wide, which reads as a newspaper column squeezed onto a tablet.
	 * It stacks at the same width the hero does, so the whole page changes
	 * shape once rather than twice.
	 */
	.wr-editorial {
		grid-template-columns: minmax(0, 1fr);
	}

	/*
	 * THE HERO STACKS: words above, photograph below.
	 *
	 * The proportions are set so the FIRST SCREENFUL is the words plus the top
	 * of the photograph, rather than a full screen of navy with the image
	 * pushed entirely below the fold. Before this the panel alone ran to 605px
	 * on a 375x812 phone for 445px of content — 160px of padding around a
	 * headline — and the picture began below the fold.
	 *
	 * The panel is now bounded rather than free: it takes the height its
	 * content needs and no more, and the photograph is given a fixed slice of
	 * the viewport underneath it. svh, not vh — vh on a phone is the height
	 * with the address bar hidden, which is not the state the page loads in.
	 */
	.wr-hero {
		grid-template-columns: minmax(0, 1fr);
		min-height: 0;
	}

	.wr-hero__panel {
		padding: calc(var(--wr-header-h) + 28px) var(--wr-gutter) 36px;
	}

	.wr-hero__title {
		margin-bottom: 18px;
	}

	.wr-pill {
		margin-bottom: 18px;
	}

	.wr-hero__text {
		font-size: 15.5px;
	}

	.wr-button-row {
		margin-top: 22px;
	}

	.wr-hero__media {
		min-height: 34svh;
	}

	/*
	 * LIGHTEN THE PROGRAMMES SCRIM.
	 *
	 * The desktop gradient is built for a full-height panel where the heading
	 * sits at the bottom and the top of the frame is left open. Collapsed to a
	 * short band on a phone, that same gradient put its 0.94 end across most of
	 * the panel and the photograph disappeared into it — the image was there,
	 * just under a near-opaque navy wash.
	 *
	 * This keeps enough darkness under the text to hold contrast and lets the
	 * top two-thirds of the picture through.
	 */
	.wr-programmes__panel::after {
		background: linear-gradient(to top, rgba(13, 27, 42, 0.88) 0%, rgba(13, 27, 42, 0.55) 55%, rgba(13, 27, 42, 0.18) 100%);
	}

	.wr-scrollcue {
		display: none;
	}

	.wr-statements {
		grid-template-columns: minmax(0, 1fr);
	}

	/*
	 * THE PROGRAMMES PANEL STOPS BEING STICKY BELOW 900px.
	 *
	 * Not a simplification for its own sake. Once the two columns become one,
	 * a full-height image that never moves means the reader scrolls a long way
	 * through the cards with half the screen frozen — and an opened card, which
	 * runs to a full programme spread, would scroll behind it for screens on
	 * end.
	 *
	 * So on narrow screens the panel becomes an ordinary band at the top of the
	 * section. Same content, same order, no cleverness.
	 */
	.wr-programmes-section {
		grid-template-columns: minmax(0, 1fr);
		/* One column now, so the vertical split would cut across the content. */
		background: var(--wr-sand);
	}

	/*
	 * RELATIVE, NOT STATIC. This one word was breaking two sections at once.
	 *
	 * The panel holds two absolutely-positioned children — the image well and
	 * the ::after scrim, both `inset: 0`. They size themselves against the
	 * nearest POSITIONED ancestor. With the panel static, and the section, main
	 * and body static above it, there was no positioned ancestor at all, so
	 * both resolved against the initial containing block — the viewport.
	 *
	 * The result on every phone: the programmes photograph was pinned to the
	 * top of the document instead of sitting in its own section 3,000px down,
	 * and the panel's dark scrim was painted across the first screenful of the
	 * page — directly over the hero, hiding the headline, the copy and both
	 * buttons behind a near-opaque navy wash.
	 *
	 * The sticky version above 900px never showed it, because position:sticky
	 * is itself a positioned value and was doing this job silently.
	 */
	.wr-programmes__panel {
		position: relative;
		height: auto;
		/* Tall enough that there is a photograph to see behind the heading. */
		min-height: 52vh;
		min-height: 62svh;

		/*
		 * `top` HAS TO BE CLEARED WITH THE SWITCH TO position: relative.
		 *
		 * The base rule sets `top: var(--wr-header-h-stuck)` to hold the sticky
		 * panel clear of the fixed header. Under position:sticky that is an
		 * anchor — it only takes effect once the panel reaches the top of the
		 * viewport. Under position:relative it is an unconditional offset: the
		 * panel is painted 62px lower than where it is laid out, and nothing
		 * else moves with it.
		 *
		 * That left a 62px band of bare section background above the panel and
		 * ran its bottom edge 62px over the first programme card.
		 */
		top: auto;
	}

	.wr-audiences {
		grid-template-columns: minmax(0, 1fr);
	}

	.wr-connect__inner {
		flex-direction: column;
		align-items: flex-start;
	}

	/*
	 * Contact details are the longest unbreakable strings on the site — a
	 * two-word domain in an email address has no space to wrap at. Allow the
	 * break rather than let it push the page sideways.
	 */
	.wr-connect__item,
	.wr-footer__contacts,
	.wr-nav-mobile__contacts,
	.wr-asidecontact__list {
		overflow-wrap: anywhere;
	}
}

@media (max-width: 640px) {

	/* .wr-editorial is already one column from 900px — see the block above. */
	.wr-valuegrid,
	.wr-pillars,
	.wr-journey,
	.wr-cardgrid,
	.wr-form__grid,
	.wr-footer__inner {
		grid-template-columns: minmax(0, 1fr);
	}

	/*
	 * The wordmark drops away below 640px and the compass carries the brand on
	 * its own — at this width the type would either crowd the toggle or shrink
	 * to the point of being illegible.
	 */
	.wr-logo__words {
		display: none;
	}

	.wr-nav-toggle__label {
		display: none;
	}

	.wr-button-row .wr-button,
	.wr-cta__actions .wr-button {
		width: 100%;
	}

	.wr-receipt__row dt {
		flex: 0 0 100%;
	}

	.wr-value {
		padding: 26px 22px;
	}

	/*
	 * The card has no padding of its own — the head and the detail pad
	 * themselves, so that the rule between them can run edge to edge.
	 */
	.wr-programme__summary {
		padding: 26px 22px;
	}

	.wr-programme__detail {
		padding: 22px 22px 26px;
	}

	/*
	 * A smaller plus at this width. The card head is two columns whatever the
	 * screen, so every pixel the circle gives up goes to the summary beside it —
	 * which is where the reader is actually looking.
	 */
	.wr-programme__toggle {
		width: 34px;
		height: 34px;
	}

	/*
	 * CONDENSING THE FOOTER
	 *
	 * Stacked into one column and with every link grown to a 44px tap target,
	 * the footer ran to about 1,140px on a 375px phone — roughly a screen and a
	 * half of scrolling after the reader has already reached the end of the
	 * page. Everything below buys that height back WITHOUT dropping any content:
	 * the links, contacts, social and legal lines are all still there.
	 *
	 * The nav is the whole problem — nine items at 44px each is 396px on its
	 * own, more than a third of the footer. Two columns halves it to five rows
	 * and costs nothing, because the labels are short: the longest ("Who We
	 * Serve") sets at ~101px against a 129px column at the 320px worst case.
	 */
	.wr-nav__list--footer {
		display: grid;
		grid-template-columns: repeat(2, minmax(0, 1fr));
		column-gap: 22px;
		align-items: start;
	}

	/*
	 * The rest is vertical rhythm. These are the desktop values scaled back for
	 * a screen where whitespace is measured in thumb-swipes rather than in
	 * elegance — the footer is the one place on the page that can afford to be
	 * tighter than the sections above it.
	 */
	.wr-footer {
		padding-top: 40px;
	}

	.wr-footer__inner {
		gap: 28px;
		padding-bottom: 28px;
	}

	.wr-footer__legal {
		padding-top: 18px;
		padding-bottom: 20px;
	}

	.wr-footer__social {
		margin-top: 12px;
	}
}


/* --------------------------------------------------------------------------
   14. Touch
   --------------------------------------------------------------------------
   Keyed to the POINTER, not to the viewport width.

   Width is the wrong test for these two problems. An iPad in landscape is
   1024px wide and is still operated with a fingertip; a desktop browser dragged
   narrow is 375px wide and still has a mouse. Sizing tap targets by width gets
   both backwards — it leaves the tablet with 15px links and gives the mouse
   user 44px ones.

   `pointer: coarse` asks the question that actually matters: is the primary
   input device imprecise? Everything here follows from a yes.
   -------------------------------------------------------------------------- */

@media (pointer: coarse) {

	/*
	 * FORM FIELDS GO TO 16px.
	 *
	 * Not a type-scale decision. iOS Safari zooms the page in when a field
	 * smaller than 16px takes focus, and it does not zoom back out — so the
	 * visitor is left part-way through the booking form on a page suddenly
	 * wider than the screen, pinching their way back. The design size is 15px;
	 * the one pixel is worth far less than the bug.
	 */
	.wr-input,
	.wr-select,
	.wr-textarea {
		font-size: 16px;
	}

	/*
	 * TAP TARGETS.
	 *
	 * All of these were sized for a pointer and sit under the 44px a fingertip
	 * needs (WCAG 2.5.5). They are given height with padding rather than
	 * font-size, so nothing about the type changes — only the area that
	 * responds to a tap.
	 */
	.wr-nav-toggle {
		/*
		 * The worst offender: with the label hidden below 640px this button's
		 * box measured 30x18, and it is the only way to reach the menu.
		 */
		min-width: 44px;
		min-height: 44px;
		justify-content: flex-end;
		padding: 8px 0;
	}

	.wr-nav__list--footer a,
	.wr-footer__contacts a,
	.wr-footer__social a,
	.wr-footer__credit,
	.wr-connect__item a,
	.wr-asidecontact__list a,
	.wr-nav-mobile__contact a {
		display: inline-flex;
		align-items: center;
		min-height: 44px;
	}

	/*
	 * The ROW gaps come off the lists whose links are now padded, or every row
	 * gains its own 44px on top of a gap meant for 17px text and the footer
	 * grows a screen taller.
	 *
	 * row-gap, not gap: the column gap is still doing real work — it separates
	 * the two columns of the footer nav below 640px and the social links from
	 * each other — and zeroing it would run them together.
	 */
	.wr-nav__list--footer,
	.wr-footer__contacts,
	.wr-footer__social,
	.wr-nav-mobile__contacts {
		row-gap: 0;
	}

	/*
	 * The programme cards' plus is decorative — the whole card head is the
	 * target — but the card head must itself be comfortably tappable, and it
	 * is, at 100+px tall. Nothing to do here; noted so the next reader does not
	 * go looking.
	 */
}
