/*
Theme Name: Blocksy Child
Description: Child theme for Blocksy. All customisations for this site live here so the Blocksy parent theme can be updated safely.
Author: Andrew Booth
Template: blocksy
Version: 1.44.0
License: GNU General Public License v2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html
Text Domain: blocksy-child
Requires at least: 6.7
Requires PHP: 7.0
*/

/* =========================================================================
 * Blocksy variable bridge
 *
 * Blocksy drives its own styling (buttons, links, headings, containers,
 * and the Customizer-built header/footer) from --theme-* variables, and
 * those win over theme.json for anything the parent theme styles directly.
 * Rather than fight it selector by selector, point Blocksy's variables at
 * the theme.json tokens so the parent theme renders the brand natively.
 *
 * Doubled :root raises specificity above Blocksy's own :root block, which
 * WordPress prints inline in <head> after this stylesheet.
 * ====================================================================== */

:root:root {
	/* Palette — Blocksy maps 1=accent/buttons, 2=accent hover, 3=body text,
	   4=headings, 5=borders, 6/7=light surfaces, 8=white. */
	--theme-palette-color-1: #3a5dae;
	--theme-palette-color-2: #3a3a59;
	--theme-palette-color-3: #2a2a3e;
	--theme-palette-color-4: #3a3a59;
	--theme-palette-color-5: #e4e2dc;
	--theme-palette-color-6: #faf9f6;
	--theme-palette-color-7: #faf9f6;
	--theme-palette-color-8: #ffffff;

	/* Typography */
	--theme-font-stack-default: roboto, Roboto, system-ui, -apple-system, "Segoe UI", Helvetica, Arial, sans-serif;
	--theme-font-family: var(--theme-font-stack-default);
	--theme-font-size: 16px;
	--theme-line-height: 1.7;

	/* Container widths — the Figma layout is a 1200px content column inside
	   a 1440px canvas. Blocksy's theme.json points contentSize/wideSize at
	   these two, which are otherwise undefined, leaving constrained layouts
	   with no max width at all. */
	--theme-block-max-width: 1200px;
	--theme-block-wide-max-width: 1400px;
	--theme-normal-container-max-width: 1200px;
	--theme-content-width: 1200px;

	/* Buttons — 48px min height keeps the touch target above the 44px
	   floor (WCAG 2.5.5) on phones. */
	--theme-button-font-size: 14px;
	--theme-button-font-weight: 700;
	--theme-button-text-transform: uppercase;
	--theme-button-letter-spacing: 0.06em;
	--theme-button-min-height: 48px;
	--theme-button-padding: 14px 28px;
	--theme-button-border-radius: 2px;
}

/* Headings use the display face; Blocksy has no variable for this. */
:where(h1, h2, h3, h4, h5, h6),
.wp-block-heading,
.entry-title {
	font-family: var(--wp--preset--font-family--display);
	font-weight: 700;
	line-height: 1.1;
	letter-spacing: 0.01em;
}

/* Blocksy sets its own button typography; theme.json's element styles lose
   to it, so restate them here where they sit after the parent bundle. */
.wp-block-button__link,
.wp-element-button {
	font-size: var(--theme-button-font-size);
	font-weight: var(--theme-button-font-weight);
	letter-spacing: var(--theme-button-letter-spacing);
	text-transform: var(--theme-button-text-transform);
	min-height: var(--theme-button-min-height);
	display: inline-flex;
	align-items: center;
	justify-content: center;
	text-align: center;
}

/* =========================================================================
 * Multipli utilities
 *
 * Every class here is applied from the block editor's own "Additional CSS
 * class(es)" field (Block → Advanced), so pages stay 100% core blocks and
 * fully editable in Gutenberg. Design tokens come from theme.json.
 *
 * functions.php enqueues this file after Blocksy's main bundle. Blocksy
 * loads some bundles during rendering (archive cards, sidebar, comments,
 * WooCommerce) which print after this file — see the note in functions.php.
 * ====================================================================== */

/* --- Eyebrow: small tracked label with a leading dot ------------------- */
.eyebrow {
	display: flex;
	align-items: center;
	gap: 20px;
	margin-bottom: 0;
	font-family: var(--wp--preset--font-family--body);
	font-size: var(--wp--preset--font-size--eyebrow);
	font-weight: 700;
	line-height: 1.2;
	letter-spacing: 0.16em;
	text-transform: uppercase;
	color: var(--wp--preset--color--blue);
}

.eyebrow::before {
	content: "";
	flex: 0 0 auto;
	width: 8px;
	height: 8px;
	border-radius: 50%;
	background: currentColor;
}

/* On dark sections the eyebrow needs to lift off the background. */
.has-navy-background-color .eyebrow,
.has-blue-background-color .eyebrow,
.eyebrow.is-on-dark {
	color: var(--wp--preset--color--yellow);
}

/* --- Card: white panel used for testimonials, resources, product cards -- */
.card {
	height: 100%;
	border-radius: 16px;
	box-shadow: 0 12px 20px rgba(167, 167, 167, 0.1);
}

/* --- Quote mark ------------------------------------------------------- */
.quote-mark::before {
	content: "\201C";
	display: block;
	font-family: var(--wp--preset--font-family--display);
	font-size: 4rem;
	line-height: 0.8;
	color: var(--wp--preset--color--blue);
}

/* --- Decorative dot screentone --------------------------------------- */
.u-screentone {
	position: relative;
	isolation: isolate;
}

.u-screentone::after {
	content: "";
	position: absolute;
	inset: 0;
	z-index: -1;
	pointer-events: none;
	/* Measured off the Figma frames: 24px pitch, 7px dots, brand yellow at
	   30% over the ground. The pattern here was a 12px pitch of 3px dots,
	   which read as a fine mechanical screen rather than the bold dot
	   pattern the design uses — the sheet's "dot pattern is different than
	   original". Colour and opacity were already right. */
	/* The screentone, generated to match the design file.
	   CSS can only fade a dot field's opacity, but the design shrinks each
	   dot as it nears the rim, and that taper is what gives the cluster its
	   soft edge. Measuring the exported vector, the radius follows
	   r = rmax * sqrt(1 - t^2) over the cluster radius, to within 1.6%.

	   The file is generated from that rule rather than exported, because
	   the design has several screentones at different densities and the
	   only one Figma's API would hand over was the sparsest. Matching the
	   9px lattice the heroes and bands actually use meant regenerating it:
	   6,025 circles, ~28KB gzipped. See tools/screentone.py.

	   The ?v= is load-bearing: the theme version busts this stylesheet but
	   not the assets it references, and the first regeneration shipped to
	   the server while every cache kept serving the old file. Bump it
	   whenever screentone.svg is regenerated. */
	background-image: url("./assets/screentone.svg?v=4");
	background-repeat: no-repeat;
	background-position: right -168px top -231px;
	background-size: 645px 635px;
	opacity: 0.42;
}

/* --- Rounded media ---------------------------------------------------- */
.u-rounded img {
	border-radius: 16px;
}

/* --- Centred eyebrow (the base .eyebrow is a flex row, so text-align
       alone will not move it) ------------------------------------------ */
.u-eyebrow-center {
	justify-content: center;
}

/* --- Photo in a gradient frame --------------------------------------- */
.u-photo-frame img {
	display: block;
	border-radius: 2px;
}

/* --- Decorative rings around the circular photos ----------------------
       The design frames each circular photo in concentric rings. Measured
       off the Figma frames, outward from the photo edge: a white gap, one
       solid band, then two progressively paler bands. Two colourways.

       Built as percentage padding plus a radial-gradient rather than a
       box-shadow, because both padding and gradient stops are percentages —
       the rings then scale with the photo at every viewport instead of being
       pinned to the single width they were measured at. */
.u-photo-ring {
	border-radius: 50%;
	margin: 0;
}

.u-photo-ring img {
	display: block;
	width: 100%;
	height: auto;
	border-radius: 50%;
}

/* Blue: 4px gap, 8px solid, 14px mid, 18px pale, around a 346px photo. */
.u-ring-blue {
	padding: 10.1%;
	background: radial-gradient(circle closest-side,
		#ffffff 0 81.6%,
		#3a5dae 81.6% 85.3%,
		#a0b3de 85.3% 91.7%,
		#c7d2ec 91.7% 100%);
}

/* Gold: 5px gap, 15px solid, 24px mid, 29px pale, around an 823px photo. */
.u-ring-gold {
	padding: 7.5%;
	background: radial-gradient(circle closest-side,
		#ffffff 0 86%,
		#ffd067 86% 89.1%,
		#ffe6af 89.1% 94%,
		#fff4db 94% 100%);
}

/* --- Bordered list row (feature/obstacle lists) -----------------------
       The design puts a 40px navy disc with a yellow glyph at the left of
       every row. This carried no glyph at all before. */
.u-listrow {
	background: var(--wp--preset--color--white);
	position: relative;

	/* The disc sits in this padding, so the text has to clear it. The row
	   carries its own padding-left as an inline style from its block
	   attributes, and an inline style beats an ordinary rule — without
	   !important the text started at 16px and the icon landed on top of it.
	   72px matches the design, which puts the disc at 17.5px and the text
	   at 71.5px. */
	padding-left: 72px !important;
}

.u-listrow::before {
	content: "";
	position: absolute;
	left: 18px;
	top: 50%;
	transform: translateY(-50%);
	width: 40px;
	height: 40px;
	border-radius: 50%;
	background: var(--wp--preset--color--navy);
}

.u-listrow::after {
	content: "";
	position: absolute;
	left: 28px;
	top: 50%;
	margin-top: -10px;
	width: 20px;
	height: 20px;
	background: var(--wp--preset--color--yellow);
	-webkit-mask: var(--u-icon, url("./assets/icons/check.svg")) center / contain no-repeat;
	mask: var(--u-icon, url("./assets/icons/check.svg")) center / contain no-repeat;
}

@media (max-width: 781.98px) {
	.u-listrow {
		padding-left: 60px !important;
	}

	.u-listrow::before {
		left: 12px;
	}

	.u-listrow::after {
		left: 22px;
	}
}

/* --- Staggered "things you think" list (Awaken) ----------------------
       The numbers are drawn with ::before rather than typed into the
       paragraph, so the block content stays clean text that Gutenberg will
       not strip on re-save. */
.u-thought {
	position: relative;
	padding: 1.1rem 0 1.1rem 3.4rem;
	border-bottom: 1px solid var(--wp--preset--color--hairline);
}

.u-thought::before {
	position: absolute;
	left: 0.75rem;
	top: 50%;
	transform: translateY(-50%);
	font-family: var(--wp--preset--font-family--body);
	font-size: 0.75rem;
	font-weight: 700;
	color: var(--wp--preset--color--muted);
}

.u-thought-1::before { content: "01"; }
.u-thought-2::before { content: "02"; }
.u-thought-3::before { content: "03"; }
.u-thought-4::before { content: "04"; }
.u-thought-5::before { content: "05"; }
.u-thought-6::before { content: "06"; }

/* The one highlighted row gets the brand rule and full-strength text. */
.u-thought.is-highlighted {
	border-left: 3px solid var(--wp--preset--color--yellow);
	border-bottom-color: transparent;
}

/* The quotes are set in the condensed display face in the design; without
   this they fell back to the body face. */
.u-thought > p {
	font-family: var(--wp--preset--font-family--display);
	letter-spacing: 0.01em;
}

/* The staircase.

   Measured off the Figma frame at 1440: every row is the same width (859px,
   59.7%) and is simply shifted right by a different amount — 368, 290, 337,
   460, 474 and 564px from the page edge. An earlier version set left/right
   margins instead, which offset a fixed 1200px box rather than moving a
   narrower one, so the last rows ran past the section and were clipped.
   Expressing it as an explicit width plus a left offset keeps every row
   inside the container at any viewport.

   The !important is not decoration either. WordPress's constrained-layout
   rule sets `margin-left: auto !important; margin-right: auto !important` on
   every direct child of a constrained container, and each row is exactly
   that. Without matching it, all six rendered flush at identical width and
   the staircase never appeared at all.

   max-width keeps the line length sane on very wide screens, where the
   percentages alone would stretch a short quote across the monitor. */
@media (min-width: 782px) {
	.u-thought {
		width: 59.7% !important;
		max-width: 900px !important;
		margin-right: 0 !important;
	}

	.u-thought-1 { margin-left: 25.6% !important; }
	.u-thought-2 { margin-left: 20.1% !important; }
	.u-thought-3 { margin-left: 23.4% !important; }
	.u-thought-4 { margin-left: 31.9% !important; }
	.u-thought-5 { margin-left: 32.9% !important; }
	.u-thought-6 { margin-left: 39.2% !important; width: 58% !important; }
}

/* --- Tick list used inside the pricing cards -------------------------
       Disc and glyph are sized off the Figma frames: a 40px disc with a
       20px glyph, the same weight as the feature rows. They were drawn at
       28/14, which is where the handshake and the compass silted up into a
       blob — the round-one note that they were "too detailed" was really
       that they were too small for the detail they carry. */
.u-ticks {
	list-style: none;
	padding-left: 0;
	margin: 0;
}

.u-ticks li {
	position: relative;
	padding-left: 56px;
	min-height: 40px;
	margin-bottom: 0.9rem;
	font-size: 0.9375rem;
	line-height: 1.55;
}

.u-ticks li::before {
	content: "";
	position: absolute;
	left: 0;
	top: 0.05em;
	width: 40px;
	height: 40px;
	border-radius: 50%;
	background: rgba(255, 255, 255, 0.14);
}

.u-ticks li::after {
	content: "";
	position: absolute;
	left: 10px;
	top: calc(0.05em + 10px);
	width: 20px;
	height: 20px;
	background: var(--wp--preset--color--yellow);
	-webkit-mask: var(--u-icon, url("./assets/icons/check.svg")) center / contain no-repeat;
	mask: var(--u-icon, url("./assets/icons/check.svg")) center / contain no-repeat;
}

/* --- Plain list (no bullets) — used for cohort dates ----------------- */
.u-plain-list {
	list-style: none;
	padding-left: 0;
	margin: 0;
}

.u-plain-list li {
	margin-bottom: 0.35rem;
	font-size: 0.9375rem;
}

/* --- Full-width button inside a card --------------------------------- */
.u-btn-block .wp-block-button,
.u-btn-block .wp-block-button__link {
	width: 100%;
}

/* --- Pill badge -------------------------------------------------------
       The tags are paragraph blocks with a background; as block-level
       elements they would stretch the whole column, so shrink them to
       their text. Targets exactly the badge pattern (eyebrow size + a
       background colour). */
p.has-background.has-eyebrow-font-size {
	display: inline-block;
	width: auto;
}

/* --- Blog cards (Query Loop) ----------------------------------------- */
.u-blog-card {
	overflow: hidden;
}

.u-blog-card .wp-block-post-featured-image {
	margin-bottom: 0;
}

.u-blog-card .wp-block-post-featured-image img {
	border-radius: 0;
	width: 100%;
	object-fit: cover;
}

.u-blog-card .wp-block-post-title {
	margin: 0;
	line-height: 1.2;
}

.u-blog-card .wp-block-post-title a,
.u-featured-post .wp-block-post-title a {
	color: var(--wp--preset--color--navy);
	text-decoration: none;
}

.u-blog-card .wp-block-post-title a:hover,
.u-featured-post .wp-block-post-title a:hover {
	text-decoration: underline;
}

.u-blog-card .wp-block-read-more,
.u-featured-post .wp-block-read-more {
	display: inline-block;
	color: var(--wp--preset--color--blue);
}

.u-featured-post .wp-block-post-featured-image img {
	border-radius: 12px;
}

/* Post grid gap */
.u-post-grid .wp-block-post-template.is-layout-grid {
	gap: var(--wp--preset--spacing--40);
}

/* --- Scripture pull-quote inside posts ------------------------------- */
.u-scripture {
	border-radius: 0 6px 6px 0;
}

/* --- FAQ accordion (core Details block) ------------------------------ */
.u-faq {
	border-bottom: 1px solid var(--wp--preset--color--hairline);
	padding: 1.25rem 0;
}

.u-faq > summary {
	position: relative;
	list-style: none;
	cursor: pointer;
	padding-right: 2rem;
	font-weight: 700;
	color: var(--wp--preset--color--navy);
}

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

/* A plus that becomes a minus, so open/closed reads without relying on
   colour alone (WCAG 1.4.1). */
.u-faq > summary::after {
	content: "+";
	position: absolute;
	right: 0;
	top: 50%;
	transform: translateY(-50%);
	font-size: 1.5rem;
	line-height: 1;
	font-weight: 400;
	color: var(--wp--preset--color--blue);
}

.u-faq[open] > summary::after {
	content: "\2212";
}

.u-faq > summary:focus-visible {
	outline: 3px solid var(--wp--preset--color--blue);
	outline-offset: 3px;
}

.u-faq > *:not(summary) {
	margin-top: 0.75rem;
	color: var(--wp--preset--color--body-text);
}

/* --- Pull-quote panel that overlaps the section above ------------------ */
.u-overlap-card {
	border-radius: 16px;
	box-shadow: 0 12px 24px rgba(58, 58, 89, 0.12);
}

/* --- Links on dark sections -----------------------------------------
       theme.json colours links brand blue, which is 1.26:1 against the
       purple/teal gradient. On any dark surface a link takes the
       surrounding text colour and keeps its underline, so it is still
       distinguishable without relying on colour (WCAG 1.4.1). */
.has-navy-background-color a:not(.wp-block-button__link),
.has-blue-background-color a:not(.wp-block-button__link),
.has-teal-bright-background-color a:not(.wp-block-button__link),
.has-navy-blue-gradient-background a:not(.wp-block-button__link),
.has-purple-teal-gradient-background a:not(.wp-block-button__link),
.wp-block-cover a:not(.wp-block-button__link) {
	color: currentColor;
	text-decoration: underline;
}

.has-navy-background-color a:not(.wp-block-button__link):hover,
.has-blue-background-color a:not(.wp-block-button__link):hover,
.has-teal-bright-background-color a:not(.wp-block-button__link):hover,
.has-navy-blue-gradient-background a:not(.wp-block-button__link):hover,
.has-purple-teal-gradient-background a:not(.wp-block-button__link):hover,
.wp-block-cover a:not(.wp-block-button__link):hover {
	color: var(--wp--preset--color--yellow);
}

/* --- Current-page indicator ------------------------------------------
       Blocksy marks the active menu item with palette colour 2 (#3A3A59).
       That reads as 1.68:1 inside the dark offcanvas panel, and on the
       white header it is nearly the same as the body text (#2A2A3E), so
       the current page was effectively unmarked in both.

       Colour on its own is not a sufficient indicator either (WCAG 1.4.1),
       so each state also gets a bar. WordPress already sets
       aria-current="page", which covers screen readers. */

/* Header menu — an underline marks the current page. Blocksy renders the
   menu as nav#header-menu-1[data-menu]; the offcanvas rule below wins
   inside the panel on ID specificity. */
nav[data-menu] .current-menu-item > .ct-menu-link,
nav[data-menu] .current_page_item > .ct-menu-link,
nav[data-menu] .current-menu-ancestor > .ct-menu-link,
nav[data-menu] .current_page_ancestor > .ct-menu-link,
nav[data-menu] .current_page_parent > .ct-menu-link {
	/* Blocksy already colours this navy (10.88:1 on white, and what the
	   Figma header shows). The underline below is what actually marks it,
	   since navy vs the #2A2A3E siblings is not a visible difference. */
	position: relative;
}

nav[data-menu] .current-menu-item > .ct-menu-link::after,
nav[data-menu] .current_page_item > .ct-menu-link::after,
nav[data-menu] .current-menu-ancestor > .ct-menu-link::after,
nav[data-menu] .current_page_ancestor > .ct-menu-link::after,
nav[data-menu] .current_page_parent > .ct-menu-link::after {
	content: "";
	position: absolute;
	left: 0;
	right: 0;
	bottom: 0.35em;
	height: 3px;
	border-radius: 2px;
	background: currentColor;
}

/* Offcanvas hover / focus / tap state.
   Blocksy colours menu links on interaction with
   nav[class*="menu"] li:hover > .ct-menu-link { color: var(--theme-link-hover-color) },
   and that variable resolves to palette colour 2 (#3A3A59). On the dark
   panel that is 1.68:1 — on a phone the sticky :hover left the tapped item
   almost unreadable. Yellow gives 10.57:1. The #offcanvas ID outranks
   Blocksy's selector. Also covers :focus-visible for keyboard users and
   :active for the moment of the tap. */
#offcanvas li:hover > .ct-menu-link,
#offcanvas li:focus-within > .ct-menu-link,
#offcanvas .ct-menu-link:hover,
#offcanvas .ct-menu-link:focus,
#offcanvas .ct-menu-link:focus-visible,
#offcanvas .ct-menu-link:active {
	color: var(--wp--preset--color--yellow);
}

/* Keep the tap flash from painting a dark box over the label on Android. */
#offcanvas .ct-menu-link {
	-webkit-tap-highlight-color: rgba(255, 184, 28, 0.2);
}

/* Offcanvas menu — yellow text (10.57:1 on the panel) plus a left bar.
   Scoped to the panel: yellow is only 1.73:1 on the white header. */
#offcanvas .current-menu-item > .ct-menu-link,
#offcanvas .current_page_item > .ct-menu-link,
#offcanvas .current-menu-ancestor > .ct-menu-link,
#offcanvas .current_page_ancestor > .ct-menu-link,
#offcanvas .current_page_parent > .ct-menu-link {
	color: var(--wp--preset--color--yellow);
	position: relative;
}

#offcanvas .current-menu-item > .ct-menu-link::before,
#offcanvas .current_page_item > .ct-menu-link::before,
#offcanvas .current-menu-ancestor > .ct-menu-link::before,
#offcanvas .current_page_ancestor > .ct-menu-link::before,
#offcanvas .current_page_parent > .ct-menu-link::before {
	content: "";
	position: absolute;
	left: -0.75em;
	top: 50%;
	transform: translateY(-50%);
	width: 3px;
	height: 1.1em;
	border-radius: 2px;
	background: currentColor;
}

/* =========================================================================
 * Icons
 *
 * The design draws small line glyphs inside filled circles: on the bordered
 * feature rows, on the bullets inside the pricing cards, and beside the
 * footer contact lines. Those were stand-ins until now — .u-ticks painted a
 * plain yellow dot and .u-listrow had no glyph at all.
 *
 * The glyphs are Tabler Icons (MIT), self-hosted in assets/icons so nothing
 * is fetched from a CDN at runtime. The design file already uses Tabler for
 * its footer icons (those three are the exact exports from Figma). The
 * feature rows were drawn in Figma with Font Awesome 6 Pro, which is
 * licensed and cannot ship, so each of those uses the nearest Tabler glyph.
 *
 * Each glyph is applied as a mask rather than a background image, so it
 * takes its colour from CSS and works on any surface. Which glyph a row
 * shows comes from the --u-icon custom property: add one of the classes
 * below in the block sidebar under Advanced > Additional CSS class(es).
 *
 * A row with no class still gets a sensible glyph rather than a blank disc.
 * That default lives in the var() fallback on each mask, not in a rule of its
 * own — a `.u-listrow { --u-icon: … }` default sits at the same specificity
 * as the classes below and, coming later in the file, would quietly win and
 * render every row with the same icon.
 * ====================================================================== */

.u-icon-activity  { --u-icon: url("./assets/icons/activity.svg"); }
.u-icon-alert     { --u-icon: url("./assets/icons/alert-circle.svg"); }
.u-icon-book      { --u-icon: url("./assets/icons/book.svg?v=2"); }
.u-icon-calendar  { --u-icon: url("./assets/icons/calendar.svg"); }
.u-icon-check     { --u-icon: url("./assets/icons/check.svg"); }
.u-icon-clock     { --u-icon: url("./assets/icons/clock.svg"); }
.u-icon-compass   { --u-icon: url("./assets/icons/compass.svg?v=2"); }
.u-icon-dollar    { --u-icon: url("./assets/icons/currency-dollar.svg"); }
.u-icon-eye       { --u-icon: url("./assets/icons/eye.svg"); }
.u-icon-friends   { --u-icon: url("./assets/icons/friends.svg?v=3"); }
.u-icon-handshake { --u-icon: url("./assets/icons/handshake.svg?v=3"); }
.u-icon-heart     { --u-icon: url("./assets/icons/heart.svg"); }
.u-icon-mail      { --u-icon: url("./assets/icons/mail.svg"); }
.u-icon-map-pin   { --u-icon: url("./assets/icons/map-pin.svg"); }
.u-icon-message   { --u-icon: url("./assets/icons/message.svg?v=2"); }
.u-icon-phone     { --u-icon: url("./assets/icons/phone.svg"); }
.u-icon-repeat    { --u-icon: url("./assets/icons/repeat.svg"); }
.u-icon-user      { --u-icon: url("./assets/icons/user.svg"); }

/* Footer contact lines. Each line carries its own icon in the design. */
.u-footer-contact li {
	position: relative;
	padding-left: 26px;
	margin-bottom: 8px;
	list-style: none;
}

.u-footer-contact li::before {
	content: "";
	position: absolute;
	left: 0;
	top: 0.28em;
	width: 16px;
	height: 16px;
	background: currentColor;
	-webkit-mask: var(--u-icon, url("./assets/icons/check.svg")) center / contain no-repeat;
	mask: var(--u-icon, url("./assets/icons/check.svg")) center / contain no-repeat;
}

.u-footer-contact {
	padding-left: 0;
	margin: 16px 0 0;
}

/* =========================================================================
 * Section rhythm
 * ====================================================================== */

/* A full-bleed section should meet the header and the footer.

   Blocksy puts 60px of vertical space around the content area
   (--theme-content-vertical-spacing, applied via [data-vertical-spacing]).
   That is right when a page ends in ordinary text, but every page here ends
   with a full-width coloured band, and the padding left a strip of page
   background showing between that band and the footer. The same gap sits
   above the first section; it is only invisible there because that section
   happens to be white.

   Drop the padding only on the side where the outermost block is full-bleed,
   so a page that ends in plain text keeps its breathing room. */
.ct-container-full:has(> article > .entry-content > .alignfull:first-child) {
	padding-top: 0;
}

.ct-container-full:has(> article > .entry-content > .alignfull:last-child) {
	padding-bottom: 0;
}

/* Two text columns beside a photo should start together.

   Where a row holds several text columns and one image column, WordPress's
   centre alignment centres each column independently — so the shorter list
   drifts down and its heading no longer lines up with its neighbour's. The
   design has both headings on one baseline. Top-align the text columns; the
   image column is the tallest and already defines the row height, so it does
   not move.

   Scoped to rows of three or more columns. A two-column row is one text
   column beside a photo, where centring is correct and wanted. */
.wp-block-columns:has(> .wp-block-column img):has(> .wp-block-column:nth-child(3))
	> .wp-block-column:not(:has(img)) {
	align-self: flex-start;
}

/* =========================================================================
 * Video poster and lightbox
 *
 * The design keeps a chosen still frame and puts a thin white ring with a
 * solid white triangle over it. The poster stays an ordinary Image block —
 * to make one play a video, set the block's Link to the YouTube or Vimeo URL
 * in the editor. The theme notices that link and turns the image into a
 * video poster; nothing appears until a link is set, so an image never shows
 * a play button that does nothing.
 * ====================================================================== */

.u-video a {
	display: block;
	position: relative;
}

.u-video a::before {
	content: "";
	position: absolute;
	left: 50%;
	top: 50%;
	width: 72px;
	height: 72px;
	margin: -36px 0 0 -36px;
	border: 2px solid rgba(255, 255, 255, 0.92);
	border-radius: 50%;
	background: rgba(0, 0, 0, 0.08);
	transition: background-color 0.15s ease, transform 0.15s ease;
}

/* The triangle, drawn with borders so it stays crisp at any size. */
.u-video a::after {
	content: "";
	position: absolute;
	left: 50%;
	top: 50%;
	width: 0;
	height: 0;
	margin: -13px 0 0 -7px;
	border-left: 22px solid #ffffff;
	border-top: 13px solid transparent;
	border-bottom: 13px solid transparent;
}

.u-video a:hover::before,
.u-video a:focus-visible::before {
	background: rgba(255, 255, 255, 0.22);
	transform: scale(1.06);
}

/* The overlay the video opens in. */
.u-lightbox {
	position: fixed;
	inset: 0;
	z-index: 99999;
	display: flex;
	align-items: center;
	justify-content: center;
	padding: 24px;
	background: rgba(20, 20, 31, 0.92);
}

.u-lightbox__frame {
	position: relative;
	width: min(100%, 1100px);
	aspect-ratio: 16 / 9;
}

.u-lightbox__frame iframe {
	width: 100%;
	height: 100%;
	border: 0;
	border-radius: 8px;
	background: #000;
}

.u-lightbox__close {
	position: absolute;
	top: -48px;
	right: 0;
	width: 44px;
	height: 44px;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	font-size: 28px;
	line-height: 1;
	color: #ffffff;
	background: transparent;
	border: 0;
	cursor: pointer;
}

@media (prefers-reduced-motion: reduce) {
	.u-video a::before {
		transition: none;
	}

	.u-video a:hover::before,
	.u-video a:focus-visible::before {
		transform: none;
	}
}

/* =========================================================================
 * Hover states
 * ====================================================================== */

/* Buttons.
   WordPress emits its preset colour classes with !important —
   `.has-yellow-background-color { background-color: … !important }`, and the
   same for text colour. Every hover rule that changes background or colour
   is therefore outranked on any button carrying an explicit palette class,
   which is why the yellow "Register now" and "Learn more" buttons had no
   hover response at all.

   Rather than answer !important with !important on every palette class,
   animate two properties WordPress never sets: a small lift and a slight
   darkening. That reads on every button variant regardless of which palette
   classes it carries, and it cannot fight with the colour system. */
:root .wp-block-button__link:hover,
:root .wp-element-button:hover,
:root .ct-button:hover {
	filter: brightness(0.92);
	transform: translateY(-2px);
}

/* Outline buttons on dark surfaces.

   Blocksy fills an outline button with navy on hover and turns its text
   white. That disappears against a navy section or a dark photo, so those
   get a translucent white wash instead.

   Scoped deliberately. An earlier version applied the wash to every outline
   button, including the ones on white sections — and since the hover text is
   white either way, replacing the dark fill with a white wash left white
   text on a white background: the button vanished on hover. On a light
   surface Blocksy's solid navy fill is exactly right, so leave it alone.

   Dark is identified either by the button's own white text class or by one
   of the dark section wrappers. */
:root [class*="is-style-outline"] > .wp-block-button__link.has-white-color:hover,
:root .has-navy-background-color [class*="is-style-outline"] > .wp-block-button__link:hover,
:root .has-blue-background-color [class*="is-style-outline"] > .wp-block-button__link:hover,
:root .has-teal-bright-background-color [class*="is-style-outline"] > .wp-block-button__link:hover,
:root .has-navy-blue-gradient-background [class*="is-style-outline"] > .wp-block-button__link:hover,
:root .has-purple-teal-gradient-background [class*="is-style-outline"] > .wp-block-button__link:hover,
:root .wp-block-cover [class*="is-style-outline"] > .wp-block-button__link:hover {
	background-color: rgba(255, 255, 255, 0.16);
	filter: none;
}

/* Header navigation.
   Blocksy's hover colour resolves to navy #3A3A59 while these links already
   sit at #2A2A3E — two near-identical darks, so the hover was imperceptible.
   Move to the brand blue (6.2:1 on white) and add an underline, so the
   change does not depend on colour alone (WCAG 1.4.1).
   The offcanvas keeps its yellow hover: those rules are ID-scoped and so
   outrank this one. */
:root nav[data-menu] li:hover > .ct-menu-link,
:root nav[data-menu] .ct-menu-link:hover {
	color: var(--wp--preset--color--blue);
	text-decoration: underline;
	text-underline-offset: 4px;
}

/* Respect a reduced-motion preference for the button lift. */
@media (prefers-reduced-motion: reduce) {
	:root .wp-block-button__link:hover,
	:root .wp-element-button:hover,
	:root .ct-button:hover {
		transform: none;
	}
}

/* =========================================================================
 * Accessibility
 * ====================================================================== */

/* Focus indicator (WCAG 1.4.11 Non-text Contrast, 2.4.7 Focus Visible).

   An earlier version of this rule painted one blue ring and switched it to
   yellow inside a few known-dark contexts (.has-navy-background-color,
   .wp-block-cover and friends). That enumeration was incomplete: it never
   covered Blocksy's dark footer, the navy-to-blue and purple-to-teal gradient
   groups, or the offcanvas menu. Measured across the live site, 14-19 focusable
   elements per page ended up ringed between 1.34:1 and 2.23:1 — under the 3:1
   a focus indicator needs, and on the footer effectively invisible.

   No single colour clears 3:1 against white AND navy AND the yellow button, so
   stop enumerating contexts and use a two-tone ring: a yellow inner band with a
   near-black outer band. Whatever sits behind it, one of the two contrasts
   strongly — yellow carries the dark surfaces (8.2:1 on navy), near-black
   carries the light ones (18:1 on white, 10.8:1 on the yellow button).
   :focus-visible keeps it off mouse clicks. */
:root :is(a, button, input, select, textarea, summary, [tabindex]):focus-visible,
:root .wp-block-button__link:focus-visible {
	outline: 3px solid var(--wp--preset--color--yellow);
	outline-offset: 0;
	box-shadow: 0 0 0 6px #14141F;

	/* Blocksy declares `box-shadow: var(--toggle-button-shadow, none) !important`
	   on [class*="ct-toggle"], which no amount of specificity can outrank — and
	   that class is on the mobile menu trigger, the one control a phone user most
	   needs to find. Rather than answering !important with !important, feed the
	   variable its own rule reads, so the toggle paints the same outer band. */
	--toggle-button-shadow: 0 0 0 6px #14141F;
}

/* Forced-colours mode supplies its own palette; let the system win. */
@media (forced-colors: active) {
	:root :is(a, button, input, select, textarea, summary, [tabindex]):focus-visible,
	:root .wp-block-button__link:focus-visible {
		outline: 3px solid CanvasText;
		box-shadow: none;
	}
}

/* Outline buttons sitting on photography need a solid edge to stay legible. */
.wp-block-cover .wp-block-button.is-style-outline > .wp-block-button__link {
	border-width: 2px;
}

/* Header breakpoint.

   Blocksy hard-codes its desktop-to-hamburger switch at 1000px, which is
   still a laptop-sized screen — the full nav fits there with room to spare.
   Measured against the live header, the desktop row needs about 676px before
   the logo and menu actually collide, and about 760px before the gaps get
   visibly cramped. So the switch moves down to 850px: the full nav survives
   on iPad landscape (1024) and every laptop, and the hamburger takes over at
   iPad portrait (768) and below.

   Only the 850-999.98px band needs rules. Above 1000px and below 850px,
   Blocksy's own pairs already do the right thing. These selectors mirror
   those pairs from main.min.css; the `body` prefix exists purely to raise
   specificity so they win regardless of stylesheet order. */
@media (min-width: 850px) and (max-width: 999.98px) {
	body #header [data-device="desktop"],
	body #offcanvas [data-device="desktop"] {
		display: block;
	}

	body #header [data-device="mobile"],
	body #offcanvas [data-device="mobile"] {
		display: none;
	}
}

/* Touch targets. Blocksy's mobile menu trigger renders at 18x18, and the
   Query Loop pagination numbers are close to it. Both are below a
   comfortable tap target, so give them at least a 44px hit area.

   This tracks the header breakpoint set above, so the trigger is never
   left at 18x18 in a range where it is the only way to reach the menu. */
@media (max-width: 849.98px) {
	.ct-header-trigger,
	.ct-toggle,
	.wp-block-query-pagination a,
	.wp-block-query-pagination .page-numbers {
		min-width: 44px;
		min-height: 44px;
		display: inline-flex;
		align-items: center;
		justify-content: center;
	}
}

/* Respect users who ask for less motion (WCAG 2.3.3). */
@media (prefers-reduced-motion: reduce) {
	*,
	*::before,
	*::after {
		animation-duration: 0.01ms !important;
		animation-iteration-count: 1 !important;
		transition-duration: 0.01ms !important;
		scroll-behavior: auto !important;
	}
}

/* =========================================================================
 * Responsive
 * ====================================================================== */

@media (max-width: 781px) {
	/* Buttons go full-width and stack so they clear the 44px touch target. */
	.wp-block-buttons.is-stacked-on-mobile .wp-block-button {
		width: 100%;
	}

	.wp-block-buttons.is-stacked-on-mobile .wp-block-button__link {
		display: block;
		text-align: center;
	}

	/* The hero scrim is weighted to the left because the headline sits in the
	   left column on desktop. On mobile the text spans the full width, so a
	   directional gradient would leave the right-hand words on bare photo —
	   measured as low as 1.02:1. Go uniform instead.

	   0.55 is the lightest this can go: the 16px paragraph under the
	   headline needs 4.5:1 and lands at 4.53:1 here, against 3.89:1 at
	   0.50. The desktop gradient is lighter because only the large
	   headline sits over the photograph there. */
	.wp-block-cover .wp-block-cover__background.has-scrim-gradient-background,
	.wp-block-cover .wp-block-cover__gradient-background.has-scrim-gradient-background {
		background: rgba(20, 20, 35, 0.55) !important;
	}
}

/* =========================================================================
 * Footer (Blocksy footer builder + block widgets)
 *
 * The four columns are core block widgets, editable at Appearance →
 * Widgets, so the footer stays Gutenberg-editable like the pages.
 * ====================================================================== */

/* The footer background itself is set in the Customizer (Footer → Footer
   Background) so the client can change it; only the text colours that
   Blocksy does not derive from it are set here. */
.ct-footer {
	color: var(--wp--preset--color--off-white);
}

.ct-footer [data-row="middle"] {
	padding: clamp(3rem, 6vw, 4.5rem) 0 2.5rem;
}

.ct-footer [data-row="middle"] > .ct-container {
	display: grid;
	grid-template-columns: 1.6fr 1fr 1fr 1.4fr;
	gap: clamp(1.5rem, 4vw, 3.5rem);
	align-items: start;
}

.ct-footer [data-column="ghost"] {
	display: none;
}

.ct-footer p,
.ct-footer li,
.ct-footer .widget {
	color: var(--wp--preset--color--off-white);
}

.ct-footer a {
	color: var(--wp--preset--color--off-white);
	text-decoration: none;
}

.ct-footer a:hover {
	color: var(--wp--preset--color--yellow);
	text-decoration: underline;
}

.u-footer-list {
	list-style: none;
	padding-left: 0;
	margin: 0;
}

.u-footer-list li {
	margin-bottom: 12px;
	font-size: 0.875rem;
	line-height: 1.4;
}

.u-footer-logo {
	margin: 0 0 0.25rem;
}

/* The Figma footer sets the address block at 10px, which is too small to
   read comfortably; 14px keeps the same layout and is legible. */
.u-footer-contact {
	font-size: 0.875rem;
}

.ct-footer [data-row="bottom"] {
	border-top: 1px solid rgba(255, 255, 255, 0.25);
	padding: 1.25rem 0 2rem;
}

.ct-footer-copyright {
	display: flex;
	flex-wrap: wrap;
	gap: 0.5rem 2rem;
	justify-content: space-between;
	align-items: center;
	font-size: 0.75rem;
	color: var(--wp--preset--color--white);
}

.ct-footer-copyright p {
	margin: 0;
	color: var(--wp--preset--color--white);
}

@media (max-width: 899px) {
	.ct-footer [data-row="middle"] > .ct-container {
		grid-template-columns: 1fr 1fr;
	}
}

@media (max-width: 599px) {
	.ct-footer [data-row="middle"] > .ct-container {
		grid-template-columns: 1fr;
	}

	.ct-footer-copyright {
		justify-content: flex-start;
	}
}

/* =========================================================================
 * QA round one
 *
 * Fixes for the desktop and mobile QA sheets. Grouped by what they are
 * rather than by which page reported them, since nearly every item was
 * raised against several pages at once.
 * ====================================================================== */

/* --- Full-bleed sections meet each other ------------------------------
       Blocksy puts --theme-content-spacing (24px) below every child of the
       content flow, our full-width bands included. Between two coloured
       bands that gap shows the page background (#FAF9F6) through as a pale
       strip — the "grey strip that shouldn't be there" reported against the
       Home hero, the Awaken yellow band, both Give gradient sections, the
       About "Who we are" heading, the Genesis Leader hero and more.

       Closed only where one full-bleed section meets another, so a band
       sitting next to ordinary constrained text keeps its breathing room.
       The existing :has() rules further up handle the page's first and last
       section meeting the header and footer. */
.entry-content > .alignfull:has(+ .alignfull) {
	margin-block-end: 0;
}

.entry-content > .alignfull + .alignfull {
	margin-block-start: 0;
}

/* --- Logo -------------------------------------------------------------
       20% larger, as asked. Blocksy sizes the logo from --logo-max-height
       on the container; the header logo carries no Customizer value and
       falls back to the parent bundle's 50px, so setting the variable is
       enough and nothing has to fight a fixed height. */
:root [data-id="logo"] {
	--logo-max-height: 60px;
}

/* --- Menu labels in title case ----------------------------------------
       The stored labels already read "Genesis Leader"; they were being
       uppercased on the way out. Not transforming them gives exactly the
       title case the sheet asks for. */
:root nav[data-menu] .ct-menu-link {
	text-transform: none;
}

/* --- Footer links -----------------------------------------------------
       The sheet asks whether every footer link needs an underline, the
       phone number included. It does not. WCAG 1.4.1 asks for a non-colour
       cue where a link sits inside a block of text; the footer's links are
       all either in navigation lists or on their own contact line, where
       the whole line is the link and there is nothing to confuse them
       with. They keep an underline on hover and focus, and the focus ring
       is unaffected, so nothing is lost for keyboard or screen reader
       users.

       In-content links are untouched and stay underlined — see the link
       element styles in theme.json. */
.ct-footer a {
	text-decoration: none;
}

.ct-footer a:hover,
.ct-footer a:focus-visible {
	text-decoration: underline;
}

/* --- Callout with a coloured rule down one edge -----------------------
       The design rounds this callout off. It appears in two forms: as a
       panel with a background (Home, "So many are waiting…") and as a bare
       rule beside text (Churches, About), where rounding the corners is
       what curves the ends of the line.

       The border is set per block in the editor, which leaves an inline
       style but no class to hang this on. Matching the shape of that
       inline style — three sides switched off, a width on the fourth — is
       precise enough to catch both forms and nothing else. */
.entry-content [style*="border-top-style:none"][style*="border-left-width"],
.entry-content [style*="border-top-style:none"][style*="border-right-width"] {
	border-radius: 14px;
}

/* Those callouts are set in the display face in the design, not the body
   face. At body size and weight the About one ran to three lines where the
   design has two. The scripture quote that shares the same yellow bar is
   italic body text in the design, so key off the weight the callouts
   carry — it is the one thing that separates them in the markup.
   The size needs !important because it is fighting has-large-font-size,
   which WordPress emits with one. */
.entry-content [style*="border-top-style:none"][style*="border-left-width"] p[style*="font-weight:700"],
.entry-content [style*="border-top-style:none"][style*="border-right-width"] p[style*="font-weight:700"] {
	font-family: var(--wp--preset--font-family--display);
	font-size: 22px !important;
	line-height: 1.3;
}

/* --- Feature rows -----------------------------------------------------
       Three fixes the sheet raises together against the Churches "What
       gets in the way" and "Training process" rows, the Genesis Leader and
       Awaken Onsite process rows:

       1. the heavier grey rule down the left edge, which the hairline
          border alone does not read as;
       2. more room inside the box than the 10px it had;
       3. space between each row's heading and its body line, which were
          sitting flush against one another.

       The padding arrives as an inline style from the block's own
       attributes, so it needs the same !important the left padding
       already carries — see the note on .u-listrow above. */
.u-listrow {
	border-left: 4px solid #d5d2ca !important;
	padding-top: 20px !important;
	padding-bottom: 20px !important;
	padding-right: 24px !important;
}

.u-listrow > :is(h1, h2, h3, h4, h5, h6) {
	/* The block writes margin-bottom:0 inline, so this has to match it —
	   without the !important the heading and its line stayed flush. */
	margin-bottom: 0.4rem !important;
}

/* --- Programme tags ---------------------------------------------------
       The tags on the two program cards ("Spiritual conversation
       training", "9-month coaching community") are set in sentence case in
       the design. They were being uppercased by an inline style on each
       block, so this has to match it. Tracking comes back down to suit
       mixed case. */
p.has-background.has-eyebrow-font-size {
	text-transform: none !important;
	letter-spacing: 0.04em;
	line-height: 1.5;
}

/* Cards in a row should start their content on one line, so the two tags
   sit level rather than each floating at the top of a column of different
   height. */
.wp-block-columns:has(> .wp-block-column > .card) > .wp-block-column {
	display: flex;
	flex-direction: column;
}

.wp-block-columns:has(> .wp-block-column > .card) > .wp-block-column > .card {
	flex: 1;
}

/* --- Outline buttons on dark surfaces ---------------------------------
       Blocksy draws an outline button's border in the accent blue. On a
       navy section, a gradient band or a hero photo that reads as a blue
       box around white text — the sheet asks for a white outline on the
       Home hero, the Awaken Onsite and Give "Schedule a call" buttons and
       the lower Genesis Leader and Give calls to action.

       currentColor rather than a literal white, so the border always
       follows whatever colour the label is actually set in. The matching
       hover wash is already defined above. */
:root [class*="is-style-outline"] > .wp-block-button__link.has-white-color,
:root .has-navy-background-color [class*="is-style-outline"] > .wp-block-button__link,
:root .has-blue-background-color [class*="is-style-outline"] > .wp-block-button__link,
:root .has-teal-bright-background-color [class*="is-style-outline"] > .wp-block-button__link,
:root .has-navy-blue-gradient-background [class*="is-style-outline"] > .wp-block-button__link,
:root .has-purple-teal-gradient-background [class*="is-style-outline"] > .wp-block-button__link,
:root .wp-block-cover [class*="is-style-outline"] > .wp-block-button__link {
	border-color: currentColor;
}

/* --- The hero's dot screen --------------------------------------------
       The design lays the same yellow dot screen over the hero photograph
       that .u-screentone puts behind the flat sections. It was missing
       from the heroes altogether, so they read flat — called out on Home,
       and on Awaken and Genesis Leader on phones in particular.

       A cover block already stacks a photo and a scrim, both absolutely
       positioned, then its content in a relatively positioned container.
       The dots need to sit above the scrim and below the text, so the
       content container is given a layer of its own to sit on. */
.entry-content > .wp-block-cover.alignfull > .wp-block-cover__inner-container {
	z-index: 2;
}

.entry-content > .wp-block-cover.alignfull::after {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 1;
	pointer-events: none;
	/* Same asset, placed as the hero frames have it: the cluster centre
	   sits high and right, so most of it overhangs the top edge and only
	   the lower arc falls across the photograph, clear of the headline. */
	background-image: url("./assets/screentone.svg?v=4");
	background-repeat: no-repeat;

	/* Anchored into the top-right corner, matching the Home hero frame.
	   The cluster's centre sits just past the right edge and a little above
	   the top, so only its lower-left quadrant falls across the photograph
	   — that is what stops it reading as a disc over the middle. */
	background-position: right -443px top -424px;
	background-size: 830px 817px;

	/* The asset carries the design's own 0.7, which is right where Figma
	   composites it but far too strong sitting straight on a photograph.
	   0.42 on top lands at the ~30% the frames actually measure. */
	opacity: 0.42;
}

/* On a phone the headline spans the full width, so the screen moves to
   the bottom of the frame instead of the right of it, and the dots tighten
   so the pattern still reads at that size. */
@media (max-width: 781px) {
	/* Round three read the phone version as "too dense", and on Give as
	   dots sitting over a face. Two things were wrong. The tile had been
	   scaled from 830px to 480px, which shrinks the lattice with it — the
	   dots ended up ~9px apart instead of ~15px, so the field read as a
	   mechanical screen rather than the design's bold dots. And on the flat
	   bands the cluster's dense core landed at roughly (225, 86), which on
	   a 375px screen is directly behind the eyebrow and headline.

	   So: a larger tile, so the lattice keeps its spacing; offsets that put
	   the core off the top-right corner, leaving only the sparse tail on
	   screen; and the opacity turned down, which is what the sheet asked
	   for. */
	.entry-content > .wp-block-cover.alignfull::after {
		/* Offsets are from the right edge, so the cluster stays centred on
		   that edge whatever the phone's width. */
		background-position: right -330px top -360px;
		background-size: 560px 551px;
		opacity: 0.24;
	}

	.u-screentone::after {
		background-position: right -280px top -300px;
		background-size: 520px 512px;
		opacity: 0.26;
	}
}

/* --- Price ------------------------------------------------------------
       The price was the one large figure on the site still set in the body
       face, which at 60px left it looking far wider than the display type
       around it. It takes the display face like every other headline
       number, with the tracking pulled in a little at that size. */
p.has-huge-font-size,
p.has-xx-large-font-size {
	font-family: var(--wp--preset--font-family--display);
	letter-spacing: -0.01em;
}

/* --- Team and coach cards ---------------------------------------------
       The headshots are portrait crops; the design frames them in a
       shorter landscape box. Weighted above centre so the crop takes the
       head rather than the middle of the body.

       The name and its title were also sitting flush against each other,
       and the photo flush against the name — both blocks carry a zero
       margin as an inline style, so this has to answer in kind. */
.card:has(> figure.wp-block-image) > figure.wp-block-image img {
	aspect-ratio: 3 / 2;
	width: 100%;
	object-fit: cover;
	object-position: 50% 50%;
}

/* The 4:3 box weighted above centre is only right for the portrait
   headshots, which live on About. Applied to the landscape thumbnails on
   Resources it squeezed them into a taller frame than their source and
   trimmed the sides — round three's "these 2 thumbs are cropped oddly".
   Keyed to the page rather than to the markup because nothing in the
   markup distinguishes a headshot card from a link card; if coach cards
   ever appear on another page, add its id here. */
.page-id-75 .card:has(> figure.wp-block-image) > figure.wp-block-image img {
	aspect-ratio: 4 / 3;
	object-position: 50% 22%;
}

.card:has(> figure.wp-block-image) > :is(h1, h2, h3, h4, h5, h6) {
	margin-top: 1.1rem !important;
}

.card:has(> figure.wp-block-image) > :is(h1, h2, h3, h4, h5, h6) + p {
	margin-top: 0.4rem !important;
}

/* --- Lists on the gradient sections -----------------------------------
       The coach lists on About hang their bullets out in the gutter, so
       the names start 40px right of the heading above them. Bringing the
       marker inside lines the list up with the heading. */
[class*="-gradient-background"] .wp-block-list:not(.u-plain-list):not(.u-ticks) {
	padding-left: 0;
	list-style-position: inside;
}

/* --- Blog -------------------------------------------------------------
       The featured post's image is forced to 4:3 by the block, while the
       photographs themselves are 3:2 — which is what was cutting the top
       post's thumbnail off. Matching the ratio the images are actually
       shot at means nothing has to be cropped away. The cards below
       already ask for 3:2 and are left alone. */
.u-featured-post .wp-block-post-featured-image img {
	aspect-ratio: 3 / 2 !important;
}

/* Post titles belong in the display face, like every other heading on the
   site — they were the one place still setting a headline in the body
   face. This covers the featured post, the cards and the single post. */
.u-featured-post .wp-block-post-title,
.u-blog-card .wp-block-post-title,
.wp-block-post-title,
.entry-title {
	font-family: var(--wp--preset--font-family--display);
	font-weight: 700;
	line-height: 1.15;
}

/* The date and the headline it belongs to should read as one unit. The
   featured post had them nearly 58px apart; the cards had them touching. */
.u-featured-post .wp-block-post-title {
	margin-top: 0.5rem;
}

.u-blog-card .wp-block-post-title {
	margin-top: 0.6rem;
}

/* "More posts" sat straight on top of the grid it introduces. */
.eyebrow + .u-post-grid {
	margin-top: var(--wp--preset--spacing--40);
}

/* The single post's featured image picks up the same rounded corner the
   listing gives it, so a post does not change shape when you open it.

   The theme draws that hero itself, in a .ct-media-container, rather than
   through the core featured-image block — targeting only the block left
   every imported post square. The images inside the post body get the
   same corner so the page reads as one set. */
.single .ct-media-container img,
.single .wp-block-post-featured-image img,
.single .entry-content figure.wp-block-image img,
.single .entry-content figure.wp-block-media-text__media img {
	border-radius: 12px;
}

/* --- Sections that reveal as they come into view -----------------------
       The "Does this sound like you?" staircase on Awaken, the "Genesis
       Leader is for you" rows and the About page's "Sharing the Good News
       isn't someone else's job" are all meant to arrive one at a time as
       the page scrolls rather than being there from the start.

       The hidden state is applied by the script in functions.php, never in
       the markup, so a browser with no JavaScript — or one that fails
       before the observer runs — shows every row exactly as it does now.
       Anyone who has asked for less motion keeps the same static page. */
.u-thought.js-reveal {
	opacity: 0;
	transform: translateY(18px);
	transition: opacity 0.55s ease, transform 0.55s ease;
}

.u-thought.js-reveal.is-revealed {
	opacity: 1;
	transform: none;
}

/* The script already declines to add js-reveal when reduced motion is
   asked for. This is the second lock on the same door: if the class is
   ever applied some other way, the rows still simply appear. */
@media (prefers-reduced-motion: reduce) {
	.u-thought.js-reveal {
		opacity: 1;
		transform: none;
	}
}

/* --- Room at the edges on a phone -------------------------------------
       The content column ran close to the screen edge on Give; 20px either
       side is the minimum that stops text looking pinned to the bezel. */
@media (max-width: 781px) {
	.entry-content > .alignfull > .has-global-padding,
	.entry-content > .alignfull.has-global-padding {
		padding-left: max(24px, var(--wp--style--root--padding-left));
		padding-right: max(24px, var(--wp--style--root--padding-right));
	}
}

/* --- Single post ------------------------------------------------------
       The post title was the last heading still set in the body face —
       Blocksy renders it as .page-title, which the heading rule at the top
       of this file does not cover. */
.page-title,
.single .entry-header .entry-title {
	font-family: var(--wp--preset--font-family--display);
	font-weight: 700;
	line-height: 1.15;
}

/* Every post carries the same single term — "Uncategorized" before the
   blog import, "Blog" after it — so printing it under the byline adds
   nothing. Hidden rather than switched off in the Customizer, so the
   author and date, which are wanted, are untouched. */
.single .entry-meta .meta-categories {
	display: none;
}

/* --- Back to blog -----------------------------------------------------
       Printed by functions.php at the top of a single post. */
.u-back-to-blog {
	margin: 0 0 var(--wp--preset--spacing--40);
	font-size: 0.875rem;
	font-weight: 700;
	letter-spacing: 0.04em;
}

.u-back-to-blog a {
	color: var(--wp--preset--color--blue);
	text-decoration: none;
}

.u-back-to-blog a:hover,
.u-back-to-blog a:focus-visible {
	text-decoration: underline;
}

/* --- The yellow band under the hero -----------------------------------
       11px was too quiet for a band that is carrying the one-line summary
       of the whole program — raised on both Awaken and Genesis Leader.
       The tracking comes in a little to suit the larger size. */
.entry-content > .alignfull.has-yellow-background-color p.has-eyebrow-font-size {
	/* WordPress prints its preset size classes with !important, so a plain
	   font-size here loses to .has-eyebrow-font-size no matter how specific
	   the selector is. */
	font-size: 0.9375rem !important;
	letter-spacing: 0.06em;
	line-height: 1.4;
}

@media (max-width: 781px) {
	/* The band is set not to stack, so on a phone the "Online / In person"
	   column squeezes the line beside it into an awkward shape for very
	   little benefit. Drop it and give the summary the full width. */
	.entry-content > .alignfull.has-yellow-background-color
		.wp-block-columns > .wp-block-column:last-child:not(:first-child) {
		display: none;
	}

	.entry-content > .alignfull.has-yellow-background-color p.has-eyebrow-font-size {
		font-size: 1rem !important;
	}
}

/* --- Giving levels ----------------------------------------------------
       "Ignite" and its line, "Empower" and its line: heading and subhead
       were flush against each other in all three cards. Both carry a zero
       margin inline, so this has to answer in kind. */
.entry-content .wp-block-column > :is(h1, h2, h3, h4, h5, h6) + p.has-small-font-size,
.entry-content .card > :is(h1, h2, h3, h4, h5, h6) + p.has-small-font-size {
	margin-top: 0.5rem !important;
}

/* --- Room after an image caption --------------------------------------
       On Churches the line under the video still ran straight into the
       next section. A caption is the end of its figure, not the start of
       what follows. */
.entry-content figure.wp-block-image + p.has-small-font-size,
.entry-content figcaption {
	margin-bottom: var(--wp--preset--spacing--40);
}

/* --- Hero crops -------------------------------------------------------
       The Give and Awaken Onsite heroes were cropping the head off the
       person on the left. Covers default to centring the image; weighting
       it towards the top keeps faces in frame at every viewport. */
.entry-content > .wp-block-cover.alignfull > .wp-block-cover__image-background {
	/* 30% still cut the top of the left-hand head on Give. Checked against
	   the Give and Awaken Onsite frames, which both leave headroom above
	   the faces; 12% matches them and suits the Home hero too. */
	object-position: 50% 12%;
}

/* --- Stacked columns need a gap ---------------------------------------
       Once columns stack on a phone they sit flush against each other.
       Raised twice: the Churches "does any of this sound familiar" rows
       ran straight into the "We know the struggle" heading beside them,
       and on About the coach lists ran into the photo below. Both are
       sibling columns of one row, so one rule covers them.

       is-not-stacked-on-mobile rows are excluded — they stay side by side,
       so there is nothing to separate. */
@media (max-width: 781px) {
	.entry-content .wp-block-columns:not(.is-not-stacked-on-mobile)
		> .wp-block-column + .wp-block-column {
		/* An explicit value, not the preset: --wp--preset--spacing--40
		   resolves to 1rem here, which is too tight to separate a stack of
		   feature rows from the heading that follows them. */
		margin-top: 28px;
	}

	/* The coaches photo leads its row on desktop, but the sheet wants it
	   after the copy and button on a phone, just before the coach list. */
	.u-coach-photo {
		order: 2;
		margin-top: 28px;
	}
}

/* --- Pricing cards: buttons on one line -------------------------------
       The button sat directly under each card's list, so its height —
       and with it the button's position — followed however long that
       list happened to be, leaving the two calls to action at different
       heights. Pushing the button group down with an auto top margin puts
       them on the same line whatever is above.

       The width:100% matters. WordPress gives every child of a
       constrained container `margin-left/right: auto !important`, and in
       a column flex container those auto margins centre each child at its
       content width instead of filling the card — headings would
       shrink-wrap. At full width there is no free space left to centre
       with, so the layout holds.

       Scoped with :has() to cards that actually carry a button, which is
       the pricing and investment cards and nothing else. */
.wp-block-columns .card:has(> .wp-block-buttons) {
	display: flex;
	flex-direction: column;
}

.wp-block-columns .card:has(> .wp-block-buttons) > * {
	width: 100%;
}

.wp-block-columns .card:has(> .wp-block-buttons) > .wp-block-buttons {
	/* The block carries its own margin-top as an inline style, which beats
	   any selector — measured on Awaken, the buttons stayed 36px apart
	   until this matched it. padding-top keeps a gap in the case where the
	   two cards are the same height and auto resolves to zero. */
	margin-top: auto !important;
	padding-top: var(--wp--preset--spacing--30);
}

/* --- A figure that is no longer sharing a row -------------------------
       The About coaches photo moved out of its column to sit under the
       button, where the full content width would make a banner of it. */
.u-inline-figure {
	max-width: 620px;
	margin-inline: auto;
}

/* --- Statement band ---------------------------------------------------
       The full-width band that carries one sentence, used on Give twice,
       About, Churches and Genesis Leader. Measured off the Figma frames:
       the text sits in a 940px column centred in the 1440 canvas, set at
       40/48, and the band's own padding is what makes it 372px tall over
       three lines or 412px over four.

       That measure is the whole point of the sheet's "text on three lines
       like the original" — at the full 1200px content width the same
       sentence fits in one fewer line, which is why these bands were both
       too short and breaking in the wrong places. The padding is set per
       block in the editor so it stays adjustable there. */
.u-statement :is(h1, h2, h3) {
	max-width: 940px;
	margin-inline: auto;

	/* 43/52 rather than the 40/48 first tried here: the line starts in the
	   Figma frames are 52px apart, and at 40px the Genesis Leader band fell
	   a word short of the third line the sheet asks for. */
	font-size: 43px;
	line-height: 1.21;
}

@media (max-width: 781px) {
	/* The 940px measure is wider than a phone, so it simply falls away;
	   the type comes down to stay in proportion. */
	.u-statement :is(h1, h2, h3) {
		font-size: 28px;
	}
}

/* --- Icon discs on the pricing cards ----------------------------------
       The sheet asked whether the different disc colour here was an
       accessibility decision. It was not — it was a translucent white
       stand-in. The Figma frame draws a solid brand-blue disc behind the
       gold glyph, the same weight as the navy disc on the feature rows. */
.u-ticks li::before {
	background: var(--wp--preset--color--blue);
}

/* =========================================================================
 * QA round two
 * ====================================================================== */

/* --- Menu labels, 30% larger -----------------------------------------
       Blocksy sets the size as --theme-font-size on the menu links from an
       inline block printed after this file, so this has to out-specify
       that selector rather than simply set font-size. */
:root [data-header] .ct-header [data-id="menu"] > ul > li > a {
	--theme-font-size: 15.6px;
}

/* --- Inline highlights go blue, state names stay purple ---------------
       Round one moved everything mustard on a light background to purple.
       Round two walks part of that back: the highlighted phrase inside a
       heading should be the lighter blue, while the testimonial state
       lines stay purple.

       Both use the same palette token, so the two are told apart by how
       they are marked up — a highlight is an inline <mark> carrying
       has-inline-color, a state name is a whole paragraph. */
.has-inline-color.has-amber-text-color {
	/* WordPress prints its preset colour classes with !important, so this
	   has to answer in kind to repaint just the inline highlights. */
	color: var(--wp--preset--color--blue) !important;
}

/* --- Onsite pricing card ---------------------------------------------
       The two cards use different disc colours in the design: brand blue
       on the navy Online card, navy on the teal Onsite one. */
.card.has-teal-bright-background-color .u-ticks li::before {
	background: var(--wp--preset--color--navy);
}

/* --- "Let's talk" band -------------------------------------------------
       The design runs the question on one line with the button and phone
       number pushed out to the right edge. The columns were splitting
       closer to even, which wrapped the question onto two lines. */
.u-lets-talk > .wp-block-columns > .wp-block-column:first-child {
	/* The 65/35 split is set per block as an inline flex-basis, so this has
	   to match it. At 74% the question fits on one line, as the frame has
	   it, instead of wrapping onto two.

	   Scoped to a class rather than "a full-bleed row containing buttons":
	   that shape also describes the About intro and coaches rows, and
	   forcing 74/26 on those squeezed their text into a narrow column. */
	flex-basis: 74% !important;
}

.u-lets-talk > .wp-block-columns > .wp-block-column:last-child:not(:first-child) {
	flex-basis: 26% !important;
	display: flex;
	flex-direction: column;
	align-items: flex-end;
	text-align: right;
}

/* =========================================================================
 * QA round three — phone pass
 * ====================================================================== */

/* --- Bold body copy takes the purple accent --------------------------
       Three spots on the site set a run of body copy in bold — the Awaken
       "if any of these resonate with you" line, Genesis Leader's "Multipli
       can help." and the About story. The sheet asks for all of them to
       read as one treatment: still bold, in the purple accent.

       Scoped to the light sections, because the same token on the navy and
       gradient bands would be unreadable. */
.entry-content :is(.has-white-background-color, .has-off-white-background-color) :is(p, li) strong {
	color: var(--wp--preset--color--amber-text);
}

/* --- Job titles on the team cards -------------------------------------
       Same accent, so the cards match the bold copy above. The cards are
       white, so the token clears contrast even though the section behind
       them is the navy gradient. */
.card > p.has-blue-color.has-small-font-size {
	color: var(--wp--preset--color--amber-text) !important;
}

/* --- The single post's meta line --------------------------------------
       Blocksy prints a "/" after every item, including the last visible
       one once the category is hidden, which left the date trailing a
       stray slash. */
.single .entry-meta .meta-date::after {
	display: none;
}

/* "Written by" sat closer to the paragraph under it than the date sits to
   the "back to blog" line above. Matched to that.

   Keyed to a class on the block rather than to the shape of its markup.
   The selector here used to be p:has(> strong > em:only-child), which
   missed the two posts whose byline wraps the other way round or carries
   a link — every byline now carries u-byline instead. */
.single .entry-content > p.u-byline {
	margin-bottom: 2.6rem;
}

@media (max-width: 781px) {
	/* --- The numbered "things you think" rows -------------------------
	       The row's own 3.4rem left padding never applied: these are
	       has-global-padding groups, so the gutter rule wins and leaves
	       24px. The number is positioned against the row's border box, so
	       it landed on top of the first word. Give the row a left padding
	       that clears the number and drop the right one, since the section
	       already carries a gutter. */
	.u-thought {
		padding-left: 44px !important;
		padding-right: 0 !important;
	}

	.u-thought::before {
		left: 6px;
	}

	/* --- "Let's talk" ---------------------------------------------------
	       The right column is pushed to the right edge on desktop, which is
	       the design. Stacked on a phone that leaves the button and phone
	       number floating off on their own, so they go back to the left. */
	.u-lets-talk > .wp-block-columns > .wp-block-column:last-child {
		align-items: flex-start !important;
		text-align: left !important;
	}

	/* --- The Genesis Leader hero --------------------------------------
	       147px of block padding is a desktop figure; against 190px of
	       content it left more empty band than hero. */
	.entry-content > .u-screentone:first-child {
		padding-top: 88px !important;
		padding-bottom: 64px !important;
	}

	/* --- Room before "We know the struggle" ---------------------------
	       24px read as part of the block above it. */
	.u-listrow + :is(h1, h2, h3, h4, h5, h6),
	.u-listrow + p {
		margin-top: 2.6rem !important;
	}
}

/* --- The "things you think" highlight follows the scroll --------------
       One row carries is-highlighted in the markup, and the strong/muted
       text colour is set per block too, so the same sentence stayed lit
       the whole way down the section. The design moves the highlight as
       you scroll.

       All of this is behind js-thought-scroll, which the script adds only
       when it can drive the highlight and only when the reader has not
       asked for less motion. Without it the markup's own highlight is what
       shows, exactly as before. */
.js-thought-scroll .u-thought.is-highlighted {
	border-left-color: transparent;
	border-bottom-color: var(--wp--preset--color--hairline);
}

.js-thought-scroll .u-thought.is-active {
	border-left: 3px solid var(--wp--preset--color--yellow);
	border-bottom-color: transparent;
}

/* The block colours are preset classes, which WordPress prints with
   !important, so these have to answer in kind. */
.js-thought-scroll .u-thought > p {
	color: var(--wp--preset--color--muted) !important;
	transition: color 0.35s ease;
}

.js-thought-scroll .u-thought.is-active > p {
	color: var(--wp--preset--color--navy) !important;
}

/* --- The contact form --------------------------------------------------
       HubSpot renders the form inside a cross-origin iframe, so the fields,
       the labels and the submit button are styled in HubSpot's own form
       editor — no rule here can reach inside it.

       At the full content width a four-field form ran well past a thousand
       pixels, so the width goes on the iframe rather than on the frame
       around it. That distinction matters: the frame's ~20px left margin
       is WordPress's constrained layout centring it, the same margin the
       heading above gets, so overriding it only knocks the form out of
       line. Capping the iframe leaves the frame where the layout put it
       and the form sits flush under the heading. */
.hs-form-frame {
	margin-top: 28px;
}

.hs-form-frame > iframe {
	max-width: 640px;
}

@media (max-width: 781px) {
	/* The two Contact panels carry 2rem of padding so they read as panels
	   side by side. Stacked on a phone that padding compounds with the page
	   gutter and again with HubSpot's own padding inside the form iframe,
	   which pushed the fields a long way in from the edge. Scoped to the
	   page because the padding is an inline style from the block, so there
	   is nothing in the markup to key off. */
	.page-id-99 .wp-block-column {
		padding-left: 1.25rem !important;
		padding-right: 1.25rem !important;
	}
}

/* --- The heading scale inside a post ----------------------------------
       The post title takes its size from Blocksy — a flat 30px — while the
       headings inside the article take theme.json's h2, which is the
       page-section size and runs fluid up to 40px. So every subhead in a
       post outran the title above it.

       Scoped to .single, because that large h2 is right on the landing
       pages, where an h2 really is a section header. Inside an article it
       is a subhead and belongs below the title.

       At 1440 this gives 44 / 28 / 22 against 16px body; at 375, 32 / 24 /
       20. The title keeps the most room to move, since it is the one that
       has to hold a long headline on a phone. */
.single .page-title,
.single .entry-header .entry-title {
	font-size: clamp(2rem, 1.35rem + 1.9vw, 2.75rem);
}

.single .entry-content h2 {
	font-size: clamp(1.5rem, 1.25rem + 0.7vw, 1.75rem);
}

.single .entry-content h3 {
	font-size: clamp(1.25rem, 1.1rem + 0.45vw, 1.375rem);
}
