/* =====================================================================
 * Esselith Companion — chrome styles
 *
 * Mobile-first. Every color is var(--es-*, <suite-palette fallback>): the
 * theme READS Esselith Core's tokens and degrades to the reference palette
 * when Core is inactive. It never defines --es-* itself (that's Core's job).
 *
 * Local --esc-* aliases below exist only to keep the rest of this file
 * readable; they resolve the Core token with a fallback in one place.
 *
 * Astra hazards defended here (see suite memory):
 *   • Live Astra recolors bare <button>/<a> hover to orange — every button
 *     pins background + color + border-color !important across rest/hover/
 *     focus, and link text gets an explicit pinned color. Dev's blue Astra
 *     hides this class of bug, so it's pinned defensively.
 *   • Full-width / no-sidebar: a high-specificity backstop scoped to
 *     body.es-companion (PHP filters alone lose the race on live Astra).
 *
 * Breakpoint standard: 600 phone / 782 tablet / 1024 desktop. The desktop
 * nav switches on at 1024px.
 * ===================================================================== */

/* ---- Token aliases (read Core, fall back to the reference palette) ---- */
body {
	--esc-primary:       var(--es-brand-primary, #ED8B00);
	--esc-primary-alt:   var(--es-brand-primary-dark, #BE6F00);
	--esc-primary-dark:  var(--es-brand-primary-dark, #be6f00);
	--esc-secondary:     var(--es-brand-secondary, #004F71);
	--esc-accent:        var(--es-brand-accent, #2E3D48);
	--esc-ink:           var(--es-ink, #071120);
	--esc-text:          var(--es-text, #2E3D48);
	--esc-page-bg:       var(--es-page-bg, #F7F3EC);
	--esc-surface:       var(--es-surface, #E4E1DC);
	--esc-border:        var(--es-border, #E3E7EB);
	--esc-on-dark:       var(--es-text-on-dark, #E8ECF5);
	--esc-font-display:  var(--es-font-display, "Playfair Display", Georgia, serif);
	--esc-font-body:     var(--es-font-body, "Montserrat", system-ui, -apple-system, sans-serif);

	--esc-header-h: 64px;
	--esc-maxw: 1200px;
}

/* ==================================================================== *
 *  HEADER
 * ==================================================================== */
.es-site-header {
	position: relative;
	z-index: 100;
	background: #ffffff;
	border-bottom: 1px solid var(--esc-border);
	font-family: var(--esc-font-body);
}

.es-header-inner {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 16px;
	/* Full-bleed header bar: span the viewport with comfortable, fluid side
	   padding (logo hard-left, nav hard-right). */
	max-width: 100%;
	margin: 0 auto;
	padding: 10px clamp(20px, 3vw, 44px);
	min-height: var(--esc-header-h);
}

/* ---- Branding ---- */
.es-branding {
	display: flex;
	align-items: center;
	flex: 0 0 auto;
}
.es-branding .custom-logo-link {
	display: inline-flex;
	align-items: center;
	line-height: 0;
}
.es-branding .custom-logo {
	/* Height comes from the Customizer "Logo height" control via an inline
	   --esc-logo-h on .es-branding; falls back to the default when unset.
	   (A transparent-header logo may carry its own --esc-logo-h on its anchor.) */
	max-height: var(--esc-logo-h, 48px);
	/* Safety net for a very tall (hence wide) logo: never let the branding push
	   the menu toggle off a narrow screen. Reserves room for the toggle + the
	   header's side padding; normal-height logos stay well under it. */
	max-width: calc(100vw - 120px);
	width: auto;
	height: auto;
}
.es-wordmark {
	font-family: var(--esc-font-display);
	font-size: clamp(1.25rem, 1rem + 1.4vw, 1.6rem);
	font-weight: 700;
	line-height: 1.1;
	letter-spacing: 0.01em;
	text-decoration: none !important;
	color: var(--esc-ink) !important;
}
.es-wordmark:hover,
.es-wordmark:focus {
	color: var(--esc-secondary) !important;
}

/* ==================================================================== *
 *  NAV TOGGLE (hamburger) — mobile only
 * ==================================================================== */
.es-nav-toggle {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 44px;
	height: 44px;
	padding: 0;
	cursor: pointer;
	/* Theme-defense: pin all three against live Astra's button recolor. */
	background: transparent !important;
	color: var(--esc-ink) !important;
	border: 1px solid var(--esc-border) !important;
	border-radius: 8px;
}
.es-nav-toggle:hover,
.es-nav-toggle:focus,
.es-nav-toggle[aria-expanded="true"] {
	background: var(--esc-surface) !important;
	color: var(--esc-ink) !important;
	border-color: var(--esc-border) !important;
}
.es-nav-toggle:focus-visible {
	outline: 2px solid var(--esc-secondary);
	outline-offset: 2px;
}
.es-nav-toggle-box {
	display: inline-flex;
	flex-direction: column;
	justify-content: center;
	gap: 4px;
	width: 22px;
	height: 16px;
}
.es-nav-toggle-bar {
	display: block;
	height: 2px;
	width: 100%;
	background: currentColor;
	border-radius: 2px;
	transition: transform 0.2s ease, opacity 0.2s ease;
}
.es-nav-open .es-nav-toggle-bar:nth-child(1) { transform: translateY(6px) rotate(45deg); }
.es-nav-open .es-nav-toggle-bar:nth-child(2) { opacity: 0; }
.es-nav-open .es-nav-toggle-bar:nth-child(3) { transform: translateY(-6px) rotate(-45deg); }
.es-nav-toggle-img {
	display: block;
	width: auto;
	height: 28px;
	max-width: 32px;
	object-fit: contain;
}

/* ==================================================================== *
 *  PRIMARY NAV — mobile-first (collapsed panel), desktop inline at 1024
 * ==================================================================== */
.es-primary-nav {
	position: absolute;
	left: 0;
	right: 0;
	top: 100%;
	display: none;
	flex-direction: column;
	gap: 4px;
	padding: 8px 16px 18px;
	background: #ffffff;
	border-bottom: 1px solid var(--esc-border);
	box-shadow: 0 14px 24px -18px rgba(7, 17, 32, 0.45);
	/* A long assigned menu on a short (landscape) phone must stay reachable:
	   the panel is absolute, so cap it and let it scroll internally. */
	max-height: calc(100vh - var(--esc-header-h));
	overflow-y: auto;
	-webkit-overflow-scrolling: touch;
}
.es-nav-open .es-primary-nav {
	display: flex;
}

.es-menu {
	list-style: none;
	margin: 0;
	padding: 0;
	display: flex;
	flex-direction: column;
	gap: 2px;
}
.es-menu-item { position: relative; margin: 0; }

/* Top-level links + the disclosure button share one look on mobile. */
.es-menu > .es-menu-item > a,
.es-dropdown-toggle {
	display: flex;
	align-items: center;
	gap: 6px;
	width: 100%;
	padding: 12px 8px;
	font-size: 1rem;
	font-weight: 600;
	font-family: var(--esc-font-body);
	text-decoration: none !important;
	color: var(--esc-text) !important;
	background: transparent !important;
	border: 0 !important;
	border-radius: var(--es-radius-sm, 8px);
	cursor: pointer;
}
.es-menu > .es-menu-item > a:hover,
.es-menu > .es-menu-item > a:focus,
.es-dropdown-toggle:hover,
.es-dropdown-toggle:focus {
	/* Teal, not orange: #C97700 fails AA on white/cream at this size; teal
	   (#004F71) clears ~8:1, and reserving orange for action (CTAs) is the
	   brand rule. Pinned !important still beats Astra's hover recolor. */
	color: var(--esc-secondary) !important;
	background: var(--esc-surface) !important;
}
.es-menu a:focus-visible,
.es-dropdown-toggle:focus-visible {
	outline: 2px solid var(--esc-secondary);
	outline-offset: 1px;
}
.es-menu > .es-menu-item > a[aria-current] {
	color: var(--esc-secondary) !important;
	/* Non-color cue too (WCAG 1.4.1), since color alone marks current. */
	text-decoration: underline !important;
	text-underline-offset: 5px;
	text-decoration-thickness: 2px;
}

/* The disclosure button sits beside its parent link when both exist. */
.es-has-dropdown {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
}
.es-has-dropdown > a { flex: 1 1 auto; width: auto; }
/* The caret-only side toggle (assigned-menu path) needs a real >=44px tap
   target on mobile; the full-width --solo fallback toggle already has one. */
.es-dropdown-toggle { width: auto; flex: 0 0 auto; min-width: 44px; min-height: 44px; justify-content: center; }
.es-dropdown-toggle--solo { flex: 1 1 auto; width: 100%; min-width: 0; justify-content: flex-start; }

/* The caret is hidden in the two common cases: desktop opens on hover, and
   mobile/compact lists the submenu flat below the parent (no tap-to-expand). It
   returns only on desktop-width TOUCH devices — see the (hover: none) rule near
   the desktop nav. The fallback --solo button keeps its label, never a caret. */
.es-dropdown-toggle:not(.es-dropdown-toggle--solo) { display: none; }
.es-dropdown-toggle--solo .es-caret { display: none; }

.es-caret {
	width: 0;
	height: 0;
	border-left: 4px solid transparent;
	border-right: 4px solid transparent;
	border-top: 5px solid currentColor;
	transition: transform 0.2s ease;
}
.es-has-dropdown.es-open .es-caret { transform: rotate(180deg); }

/* Submenu — mobile/compact: a flat, always-visible indented list under the
   parent (no tap-to-expand, no caret). Desktop overrides this to a hover dropdown. */
.es-submenu {
	list-style: none;
	margin: 0;
	padding: 0 0 0 14px;
	flex-basis: 100%;
	display: block;
}
/* (es-open only matters where the submenu is collapsed — i.e. desktop hover and
   the desktop-width touch caret; harmless on the always-open mobile list.) */
.es-has-dropdown.es-open > .es-submenu { display: block; }
.es-submenu > .es-menu-item > a {
	display: block;
	padding: 10px 8px;
	font-size: 0.95rem;
	font-weight: 500;
	text-decoration: none !important;
	color: var(--esc-text) !important;
	border-radius: var(--es-radius-sm, 8px);
}
.es-submenu > .es-menu-item > a:hover,
.es-submenu > .es-menu-item > a:focus {
	color: var(--esc-secondary) !important;
	background: var(--esc-surface) !important;
}

/* ==================================================================== *
 *  HEADER CTAs (Plan a Visit / Give)
 * ==================================================================== */
.es-header-ctas {
	display: flex;
	flex-wrap: wrap;
	gap: 10px;
	margin-top: 10px;
	padding-top: 12px;
	border-top: 1px solid var(--esc-border);
}

.es-btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-height: var(--es-btn-height, 48px);
	padding: 10px 18px;
	font-family: var(--esc-font-body);
	font-size: 0.95rem;
	font-weight: 600;
	line-height: 1.2;
	text-decoration: none !important;
	border-radius: var(--es-radius-pill, 999px);
	border: 2px solid transparent !important;
	cursor: pointer;
	transition: transform 0.18s ease;
}
.es-header-ctas .es-btn { flex: 1 1 auto; }
/* 0.24.0 (arc 5) — hover is a lift only; the colours never change. Each
   button keeps its resting colours on hover and focus (pinned with them below). */
.es-btn:hover, .es-btn:focus-visible { transform: translateY(var(--es-btn-lift, -2px)); }

/* Primary (Give): solid orange, ink text. Pin every state. */
.es-btn-primary,
.es-btn-primary:link,
.es-btn-primary:visited,
.es-btn-primary:hover,
.es-btn-primary:focus {
	background: var(--esc-primary) !important;
	color: var(--esc-ink) !important;
	border-color: var(--esc-primary) !important;
}

/* Secondary: SOLID teal, white text (on LIGHT backgrounds). Pin all states.
   Moved from a teal outline to a solid fill per the suite CTA system —
   primary = solid orange, secondary = solid teal, white-on-dark below.
   Orange stays the only PRIMARY (one action per screen); teal carries
   secondary actions on light bands. */
.es-btn-secondary,
.es-btn-secondary:link,
.es-btn-secondary:visited,
.es-btn-secondary:hover,
.es-btn-secondary:focus {
	background: var(--esc-secondary) !important;
	color: #ffffff !important;
	border-color: var(--esc-secondary) !important;
}

/* White: solid white, TEAL text — the secondary treatment for DARK bands and
   over photos, where a teal fill would disappear into the ground. The teal
   lettering ties it to the secondary action. Use the .es-btn-white class
   explicitly, or let the hero /next-steps band flip its secondary
   automatically (rules below). */
.es-btn-white,
.es-btn-white:link,
.es-btn-white:visited,
.es-btn-white:hover,
.es-btn-white:focus {
	background: #ffffff !important;
	color: var(--esc-secondary) !important;
	border-color: #ffffff !important;
}
/* (The hero's over-photo secondary treatment lives with the hero section CSS
   below — search ".es-home-welcome--hero .es-btn-secondary".) */
.es-btn:focus-visible {
	outline: 2px solid var(--esc-secondary);
	outline-offset: 2px;
}

/* ==================================================================== *
 *  DESKTOP NAV — 1024px and up
 * ==================================================================== */
/* Desktop nav (1024px+). Every rule is scoped to body:not(.es-nav-compact) so
   the "Use a menu button on desktop" Customizer option (which adds
   .es-nav-compact) keeps the collapsed hamburger nav at ALL widths. */
@media (min-width: 1024px) {
	body:not(.es-nav-compact) .es-nav-toggle { display: none; }

	body:not(.es-nav-compact) .es-primary-nav {
		position: static;
		display: flex;
		flex-direction: row;
		align-items: center;
		gap: 8px;
		padding: 0;
		background: transparent;
		border: 0;
		box-shadow: none;
		max-height: none;
		overflow: visible;
	}

	body:not(.es-nav-compact) .es-menu {
		flex-direction: row;
		align-items: center;
		gap: 4px;
	}
	body:not(.es-nav-compact) .es-menu > .es-menu-item > a,
	body:not(.es-nav-compact) .es-dropdown-toggle {
		width: auto;
		padding: 8px 12px;
	}
	/* Caret toggle is compact on desktop (hover/keyboard, not a touch target). */
	body:not(.es-nav-compact) .es-dropdown-toggle { min-width: 0; min-height: 0; }
	body:not(.es-nav-compact) .es-dropdown-toggle--solo { width: auto; }

	/* Desktop dropdown: absolutely positioned, opens on hover/focus-within
	   AND on the JS .es-open toggle (touch + click). */
	body:not(.es-nav-compact) .es-has-dropdown { flex-wrap: nowrap; }
	body:not(.es-nav-compact) .es-submenu {
		position: absolute;
		top: 100%;
		left: 0;
		min-width: 220px;
		padding: 8px;
		background: #ffffff;
		border: 1px solid var(--esc-border);
		border-radius: var(--es-radius-sm, 8px);
		box-shadow: 0 18px 34px -20px rgba(7, 17, 32, 0.5);
		flex-basis: auto;
		/* Collapsed by default on the desktop hover nav (the mobile base is now
		   an always-open flat list); the hover/focus/open rules below reveal it. */
		display: none;
	}
	body:not(.es-nav-compact) .es-has-dropdown:hover > .es-submenu,
	body:not(.es-nav-compact) .es-has-dropdown:focus-within > .es-submenu,
	body:not(.es-nav-compact) .es-has-dropdown.es-open > .es-submenu {
		display: block;
	}
	/* A right-most dropdown would clip off the viewport opening leftward-to-
	   rightward; companion.js adds .es-align-right just-in-time so it anchors
	   to the trigger's right edge instead. */
	body:not(.es-nav-compact) .es-has-dropdown.es-align-right > .es-submenu {
		left: auto;
		right: 0;
	}

	body:not(.es-nav-compact) .es-header-ctas {
		margin: 0 0 0 12px;
		padding: 0 0 0 14px;
		border-top: 0;
		border-left: 1px solid var(--esc-border);
	}
	body:not(.es-nav-compact) .es-header-ctas .es-btn { flex: 0 0 auto; }
}

/* The caret is hidden everywhere by default (desktop opens on hover; mobile and
   the compact nav show a flat list). It returns ONLY on a desktop-WIDTH TOUCH
   device (no hover), where the inline desktop nav is shown but hover can't open
   the absolute dropdown — so the caret is the only tap-to-open control there. */
@media (hover: none) and (min-width: 1024px) {
	body:not(.es-nav-compact) .es-dropdown-toggle:not(.es-dropdown-toggle--solo) {
		display: inline-flex;
	}
}

/* ==================================================================== *
 *  FOOTER
 * ==================================================================== */
.es-site-footer {
	/* Darkest deep-teal: the footer stays the page's darkest surface (its anchor)
	   while joining the suite's ONE teal family — a shade below the --es-deep-b
	   band tone, tracking the Core token. Solid fallback for pre-color-mix UAs. */
	background: #03202E;
	background: color-mix(in srgb, var(--es-deep-b, #04293A) 82%, #000);
	color: var(--esc-on-dark);
	font-family: var(--esc-font-body);
	/* No top margin: the footer meets the content flush on EVERY page (the
	   former 48px showed as a page-background sliver above the dark footer on
	   non-section / non-ministry pages; the footer's own top padding is the
	   breathing room). */
	margin-top: 0;
}
.es-footer-inner {
	display: grid;
	grid-template-columns: 1fr;
	gap: 32px;
	max-width: var(--esc-maxw);
	margin: 0 auto;
	padding: 36px 20px 32px;
}
.es-footer-wordmark {
	display: block;
	font-family: var(--esc-font-display);
	font-size: 1.4rem;
	font-weight: 700;
	color: #ffffff;
}
.es-footer-logo {
	display: block;
	height: auto;
	/* Height comes from the Customizer "Footer logo height". At the default the
	   historical 220px width cap governs (byte-identical footer); raising it
	   emits --esc-footer-logo-maxw:100% so the width cap opens to the footer
	   column and a wide logo can grow past 220px. */
	max-width: min(100%, var(--esc-footer-logo-maxw, 220px));
	max-height: var(--esc-footer-logo-h, 64px);
	margin-bottom: 4px;
}
.es-footer-tagline {
	margin: 10px 0 0;
	color: var(--esc-on-dark);
	opacity: 0.85;
	max-width: 32ch;
}
.es-footer-address {
	margin: 14px 0 6px;
	font-style: normal;
	line-height: 1.6;
	opacity: 0.85;
}
.es-footer-directions,
.es-footer-links a,
.es-footer-line a {
	color: var(--esc-on-dark) !important;
	text-decoration: none !important;
}
.es-footer-directions {
	display: inline-block;
	font-weight: 600;
	border-bottom: 1px solid currentColor;
}
.es-footer-directions:hover,
.es-footer-directions:focus,
.es-footer-links a:hover,
.es-footer-links a:focus,
.es-footer-line a:hover,
.es-footer-line a:focus {
	color: var(--esc-secondary) !important;
}
.es-footer-heading {
	margin: 0 0 14px;
	font-family: var(--esc-font-body);
	font-size: var(--es-eyebrow, 0.8125rem);
	font-weight: var(--es-eyebrow-weight, 700);
	letter-spacing: var(--es-eyebrow-tracking, 0.14em);
	text-transform: uppercase;
	color: #ffffff;
	opacity: 0.7;
}
.es-footer-services {
	line-height: 1.7;
	opacity: 0.9;
}
/* 0.22.1 — office hours (Church info) sit under the service times, one line apart. */
.es-footer-hours { margin-top: 12px; }
.es-footer-line { margin: 8px 0; opacity: 0.9; }
.es-footer-links {
	list-style: none;
	margin: 0;
	padding: 0;
	line-height: 2;
}

/* ---- Social ---- */
.es-social-list {
	list-style: none;
	margin: 0;
	padding: 0;
	display: flex;
	gap: 10px;
}
.es-social-link {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 40px;
	height: 40px;
	border-radius: 999px;
	background: rgba(255, 255, 255, 0.08) !important;
	color: var(--esc-on-dark) !important;
	border: 1px solid rgba(255, 255, 255, 0.14) !important;
	text-decoration: none !important;
	transition: background-color 0.18s ease, color 0.18s ease;
}
.es-social-link:hover,
.es-social-link:focus {
	background: var(--esc-secondary) !important;
	color: #fff !important;
	border-color: var(--esc-secondary) !important;
}
.es-social-icon { display: block; }

/* ---- Bottom bar ---- */
.es-footer-bottom {
	border-top: 1px solid rgba(255, 255, 255, 0.12);
}
.es-footer-bottom > * {
	max-width: var(--esc-maxw);
	margin-left: auto;
	margin-right: auto;
}
.es-footer-bottom {
	padding: 18px 20px;
	display: flex;
	flex-wrap: wrap;
	gap: 6px 18px;
	justify-content: space-between;
	font-size: 0.85rem;
}
.es-copyright,
.es-credit { margin: 0; opacity: 0.7; }

@media (min-width: 782px) {
	/* Flex (not a fixed 4-track grid) so the row adapts to however many columns
	   are actually present — a hidden column (no service times/phone/email, no
	   footer menu, or no social links) never leaves an empty track / dead space.
	   The about column gets a little more room than the rest. */
	.es-footer-inner {
		display: flex;
		flex-wrap: wrap;
		gap: 40px;
		padding: 40px 20px 36px;
	}
	.es-footer-col {
		flex: 1 1 180px;
	}
	.es-footer-about {
		flex: 1.4 1 240px;
	}
}

/* ==================================================================== *
 *  FULL-WIDTH / NO-SIDEBAR BACKSTOP (the layer that wins the race)
 * ==================================================================== */
body.es-companion #secondary,
body.es-companion .ast-sidebar,
body.es-companion .widget-area.secondary,
body.es-companion .site-sidebar {
	display: none !important;
}
body.es-companion #primary,
body.es-companion .ast-separate-container #primary {
	width: 100% !important;
	max-width: 100% !important;
	padding-left: 0;
	padding-right: 0;
}

/* ==================================================================== *
 *  PAGE CONTENT COLUMN — WYSIWYG block alignments (es-content-page)
 *
 *  Reconciles the front end with theme.json's declared layout so the block
 *  editor and the live page match on normal content views — church-created
 *  Pages + blog posts, NOT the front page or the suite's full-bleed auto-pages
 *  (those keep their edge-to-edge sections; the es-content-page body class is
 *  withheld from them in inc/layout.php). Mirrors WordPress's constrained
 *  layout without needing the container itself to be full width:
 *     normal (un-aligned) blocks -> contentSize (720px) reading column, centered
 *     .alignwide                 -> wideSize (1200px), centered (breaks out of
 *                                   the es-container gutter; collapses to the
 *                                   content width under ~1200px)
 *     .alignfull                 -> edge-to-edge (100vw), the same breakout the
 *                                   homepage bands use
 *
 *  IMPORTANT — the reading column is a WHITELIST, not "every un-aligned child".
 *  It caps only core prose + core-block elements (raw HTML tags a church types,
 *  plus anything class*="wp-block-"). Suite/plugin shortcode output rendered
 *  straight into .entry-content — e.g. a [lumen_channel] grid (.lmn-grid) via a
 *  Shortcode block or the page-builder's Shortcode section, which has no align
 *  option and no self-breakout — is deliberately NOT matched, so it keeps its own
 *  width instead of being clamped to 720. (The page-builder's .ams-root sections
 *  and Pulpit's .ps-section already self-break-out with !important regardless.)
 *  Aligned blocks are excluded here and handled by the two rules below.
 * ==================================================================== */
body.es-content-page .entry-content
	> :is(p, h1, h2, h3, h4, h5, h6, ul, ol, dl, blockquote, pre, table, figure, hr, address, img, [class*="wp-block-"]):not(.alignwide):not(.alignfull):not(.alignleft):not(.alignright) {
	max-width: 720px;
	margin-inline: auto;
}
body.es-content-page .entry-content > .alignwide {
	--ess-wide: min(1200px, calc(100vw - 2 * clamp(20px, 5vw, 44px)));
	width: var(--ess-wide);
	max-width: none;
	margin-inline: calc((100% - var(--ess-wide)) / 2);
}
/* Full-width: WP core already sets `.wp-block-image.alignfull img{width:100%}`,
   so the image fills this once the figure breaks out. Real specificity here
   strengthens base.css's zero-specificity :where() fallback. */
body.es-content-page .entry-content > .alignfull {
	width: 100vw;
	max-width: 100vw;
	margin-inline: calc(50% - 50vw);
}

/* Pattern support: the two-column ("image & text") pattern ships an empty media
   cell. Until a photo is added, hold the proportion with a tinted rounded slot
   so the row never collapses lopsided. Once a photo lands the figure isn't empty
   and this no-ops. */
.entry-content .wp-block-media-text__media:empty {
	aspect-ratio: 4 / 3;
	background: var(--esc-surface);
	border-radius: var(--es-radius-card, 16px);
}

/* ==================================================================== *
 *  HOMEPAGE BANDS (Layer 2 — theme-owned sections)
 *  Rendered inside the page content by the [escomp_*] shortcodes. The two
 *  full-width bands use the standard alignfull breakout so the composed
 *  homepage reads edge-to-edge like the suite's own plugin sections.
 * ==================================================================== */
/* Suppress Astra's redundant page title on the front page + the suite's
   auto-created plugin pages (#3 — Events / Ministries / Our Team / What We
   Believe / the sermon pages / Live), which each render their own heading. The
   real work is done in PHP (inc/layout.php): it drives Astra's own "disable
   title" path — its title gate AND its container-padding CSS — so the title AND
   the space above the content are removed natively (a CSS-only hide left that
   space behind). This is only a backstop that drops the title header outright if
   that path is ever bypassed. (es-suppress-title is added in inc/layout.php; the
   slug set is filterable.) */
body.es-suppress-title .entry-header {
	display: none !important;
}

/* Pinned + body.es-companion-scoped, mirroring the suite plugins' own
   full-bleed (e.g. Nave's): plain unpinned breakout loses the cascade race on
   live Astra's article-container width rules (invisible on dev's blue Astra). */
body.es-companion .es-home-welcome,
body.es-companion .es-home-promo,
body.es-companion .es-home-next-steps {
	width: 100vw !important;
	max-width: 100vw !important;
	margin-left: calc(50% - 50vw) !important;
	margin-right: calc(50% - 50vw) !important;
}
.es-home-welcome,
.es-home-next-steps {
	font-family: var(--esc-font-body);
}

/* ---- Welcome band ---- */
.es-home-welcome {
	background: #ffffff;
	padding: 56px 20px;
	text-align: center;
}
.es-home-welcome-inner { max-width: 720px; margin: 0 auto; }
/* The canonical eyebrow. Block patterns carry class="es-eyebrow" so their
   drop-in output matches the hand-built bands and tracks --es-eyebrow instead
   of freezing a size into post_content. Colour stays on the block's own colour
   class (it varies by band); this rule owns only the invariant typography. */
.es-eyebrow {
	font-size: var(--es-eyebrow, 0.8125rem);
	font-weight: 700;
	letter-spacing: 0.14em;
	text-transform: uppercase;
}
/* 0.21.1 — a scripture reference's "(LSB)" link reads as part of the label. */
.es-eyebrow a { color: inherit; text-underline-offset: 3px; }
/* 0.21.1 — the translation's copyright notice under a quoted verse (LSB terms
   ask for it on any web page that quotes the text): quiet, 14px. */
.es-scripture-notice {
	margin-top: var(--wp--preset--spacing--20);
	max-width: 46em;
	line-height: 1.5;
}
.es-scripture-notice a { color: inherit; text-underline-offset: 3px; }
.has-text-align-center.es-scripture-notice { margin-left: auto; margin-right: auto; }
.es-home-eyebrow {
	margin: 0 0 10px;
	font-size: var(--es-eyebrow, 0.8125rem);
	font-weight: 700;
	letter-spacing: 0.14em; /* aligned to .es-eyebrow (was 0.12em) so both methods agree */
	text-transform: uppercase;
	color: var(--esc-secondary);
}
.es-home-welcome-title {
	margin: 0 0 14px;
	font-family: var(--esc-font-display);
	/* v0.14.1/0.14.2 — the homepage hero title steps DOWN from the suite
	   --es-h1-hero slot (40 / 55@1280 / 62px), which read too large over the
	   photo: 32px on phones → 44px from ~1050px up. Set explicitly (not via the
	   shared token) so Core's token layer, when active, can't re-inflate it;
	   --es-h1-home is a hook for a future Core/Customizer override. Pairs with
	   the 880px hero column below so a two-sentence heading with a manual
	   line break lands one sentence per line on desktop. */
	font-size: var(--es-h1-home, clamp(2rem, 1.6rem + 1.75vw, 2.75rem));
	line-height: 1.1;
	color: var(--esc-ink);
}
.es-home-welcome-text {
	margin: 0 auto 24px;
	max-width: 52ch;
	color: var(--esc-text);
	/* v0.14.3 — fluid lead: 17px on phones → the --es-lead 21px from ~1200px up.
	   A fixed 21px ran five heavy lines on a 375px screen and out-weighed the
	   32px hero title above it; desktop is unchanged (clamps at the token). */
	font-size: clamp(1.0625rem, 0.95rem + 0.5vw, var(--es-lead, 1.3125rem));
	line-height: 1.6;
}
.es-home-services {
	margin: 0 0 24px;
	color: var(--esc-text);
	font-weight: 600;
	line-height: 1.7;
}
.es-home-cta-row {
	display: flex;
	flex-wrap: wrap;
	gap: 12px;
	justify-content: center;
}

/* ---- Welcome band: media-hero variant (Layer 3) ----
   With a hero background image set in the Customizer, the welcome band renders
   full-bleed with the image behind a tuned dark scrim and the SAME welcome
   content overlaid in light type. With no image it stays the clean white band
   above (zero regression). The full-bleed breakout + Astra defenses are shared
   with .es-home-welcome; the inline style on the section supplies the image,
   --esc-hero-focal (background-position) and --esc-hero-overlay (scrim alpha). */
.es-home-welcome--hero {
	position: relative;
	/* Own stacking context so the scrim / video / content layers composite
	   together and stay in sync while the page scrolls. */
	isolation: isolate;
	display: flex;
	align-items: center;
	justify-content: center;
	/* Reserve height up front so the async background image causes no layout
	   shift. Inspiration-first (the Three I's): the media hero is sized by the
	   VIEWPORT, never by how much text it carries — the image commands the
	   first screen and the copy sits inside it. The percentage is the church's
	   choice via Customizer "Hero height (% of screen)" (--esc-hero-h, unitless,
	   default 78; 100 = the full first screen), with a 520px floor for tiny
	   windows. The plain-vh literal is the ancient-browser fallback (a var()-
	   carrying declaration can't fall back to an earlier one — it computes to
	   auto instead); the svh version in @supports below wins on modern phones
	   so nothing hides behind the browser URL bar. */
	min-height: 78vh;
	min-height: max(520px, calc(var(--esc-hero-h, 78) * 1vh));
	padding: 72px 20px;
	background-color: var(--esc-ink); /* fallback + the base the scrim tints */
	background-repeat: no-repeat;
	background-size: cover;
	background-position: var(--esc-hero-focal, center);
	overflow: hidden;
}
/* Modern phones: size against the SMALL viewport (svh) so the hero never
   overflows behind the browser URL bar. Gated in @supports because the var()
   form can't parse-time-fall-back in engines without svh (see above). */
@supports (height: 1svh) {
	.es-home-welcome--hero {
		min-height: max(520px, calc(var(--esc-hero-h, 78) * 1svh));
	}
}
/* Scrim for legibility (text-on-media must clear WCAG AA — never rely on the
   photo alone). A vertical wash, a touch stronger at the bottom where the CTAs
   sit; darkness comes from the Customizer via --esc-hero-overlay (0..1). */
.es-home-welcome--hero::before {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 1; /* above the background image / video, below the content */
	background: linear-gradient(
		to bottom,
		rgba(7, 17, 32, calc(var(--esc-hero-overlay, 0.65) * 0.85)) 0%,
		rgba(7, 17, 32, var(--esc-hero-overlay, 0.65)) 100%
	);
	pointer-events: none;
}
/* Background video (Layer 3, self-hosted): fills the hero behind the scrim and
   fades in once it actually plays (companion.js adds .is-playing). The section's
   background-image is the poster — visible on phones, on a reduced-motion
   request, and before the video loads; the video is fetched + played by
   companion.js on desktop only, so a phone never downloads it. */
.es-home-welcome-video {
	position: absolute;
	inset: 0;
	z-index: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
	border: 0;
	background: transparent;
	opacity: 0;
	transition: opacity 0.4s ease;
	pointer-events: none;
	/* Keep the video on a stable GPU compositing layer so it stays painted while
	   the page scrolls. Without this the browser can de-promote the layer once the
	   opacity fade ends, and on scroll the dark base + scrim flash THROUGH the
	   video for a frame (the "dark overlay" popping over it). */
	transform: translateZ(0);
	backface-visibility: hidden;
}
.es-home-welcome-video.is-playing {
	opacity: 1;
}
@media (prefers-reduced-motion: reduce) {
	.es-home-welcome-video { display: none !important; }
}
.es-home-welcome--hero .es-home-welcome-inner {
	position: relative; /* above the scrim + video */
	z-index: 2;
	/* v0.14.2 — a wider text column than the plain welcome band (720px): at
	   44px a ~38-character sentence needs ~830px to stay on one line. The lead
	   paragraph keeps its own 52ch cap, so only the heading uses the width.
	   max-width only — no effect below ~920px viewports. */
	max-width: 880px;
}
/* Light type over the media. The text-shadow is a photo-INDEPENDENT contrast
   floor — legibility that holds even over a bright photo at a low overlay,
   where the translucent scrim alone can't guarantee AA. */
.es-home-welcome--hero .es-home-eyebrow,
.es-home-welcome--hero .es-home-welcome-title,
.es-home-welcome--hero .es-home-welcome-text,
.es-home-welcome--hero .es-home-services {
	color: #ffffff;
	opacity: 1;
	text-shadow: 0 1px 3px rgba(7, 17, 32, 0.55), 0 1px 12px rgba(7, 17, 32, 0.35);
}

/* On a photo the secondary uses the SOLID WHITE treatment, matching the suite
   CTA system: Give reads solid white on the image (hover = lift only). */
.es-home-welcome--hero .es-btn-secondary,
.es-home-welcome--hero .es-btn-secondary:link,
.es-home-welcome--hero .es-btn-secondary:visited,
.es-home-welcome--hero .es-btn-secondary:hover,
.es-home-welcome--hero .es-btn-secondary:focus {
	background: #ffffff !important;
	color: var(--esc-secondary) !important;
	border-color: #ffffff !important;
}
/* White keyboard-focus ring on the dark hero — the default teal ring is only
   ~2:1 on the scrim, below the 3:1 focus-indicator floor (WCAG 2.4.11/2.4.13). */
.es-home-welcome--hero .es-btn:focus-visible {
	outline-color: #ffffff;
}

/* ==================================================================== *
 *  TRANSPARENT HEADER (v0.3.7) — body.es-header-transparent
 *  The header floats transparent OVER the homepage hero so the hero media
 *  starts at the very top of the viewport. Front page only, via the
 *  "Transparent header over the hero" Customizer toggle, and ONLY while the
 *  hero has media — inc/layout.php withholds the class otherwise (transparent
 *  chrome over the clean WHITE welcome band would be white-on-white). The
 *  header scrolls away with the page: transparent-at-top only, no
 *  solid-on-scroll sticky behavior (by design — no JS). Everything is scoped
 *  to the body class, so the toggle off / any other page renders today's
 *  exact white header.
 * ==================================================================== */
/* The header's containing block. Pinning #page (not the viewport) means the
   header composes below the admin bar and anything rendered before #page
   (e.g. Threshold's announcement banner) instead of underlapping them. */
body.es-header-transparent #page {
	position: relative;
}
body.es-header-transparent .es-site-header {
	/* No `top`: with only left/right set, the box keeps its static vertical
	   position — exactly where the solid header sat — while leaving the flow,
	   so the hero behind it rises to the top of the page. z-index 100 (base
	   rule) keeps it above the hero's isolated stacking context. */
	position: absolute;
	left: 0;
	right: 0;
	background: transparent;
	border-bottom: 0;
}

/* ---- Light chrome over the photo. Same AA recipe as the hero content:
   light type + a photo-independent text-shadow floor + the darker top scrim
   on the hero below. The !important pins mirror the base rules they override
   (the Astra-defense pattern carried by the toggle/wordmark). ---- */
body.es-header-transparent .es-wordmark {
	color: var(--esc-on-dark) !important;
	text-shadow: 0 1px 3px rgba(7, 17, 32, 0.55), 0 1px 12px rgba(7, 17, 32, 0.35);
}
body.es-header-transparent .es-wordmark:hover,
body.es-header-transparent .es-wordmark:focus {
	color: #ffffff !important;
}

/* Hamburger: light bars + a light border at rest. Hover/open are re-declared
   at this specificity so the button stays ink-on-surface once it gains its
   own opaque background (the base hover rule would otherwise lose the color
   war to the light rest rule above). White focus ring — the default teal is
   ~2:1 over the dark scrim. */
body.es-header-transparent .es-nav-toggle {
	color: var(--esc-on-dark) !important;
	background: transparent !important;
	border-color: rgba(255, 255, 255, 0.55) !important;
}
body.es-header-transparent .es-nav-toggle:hover,
body.es-header-transparent .es-nav-toggle:focus,
body.es-header-transparent .es-nav-toggle[aria-expanded="true"] {
	background: var(--esc-surface) !important;
	color: var(--esc-ink) !important;
	border-color: var(--esc-border) !important;
}
body.es-header-transparent .es-nav-toggle:focus-visible {
	outline-color: #ffffff;
}
/* The bars are currentColor; the drop-shadow is their text-shadow equivalent. */
body.es-header-transparent .es-nav-toggle-box {
	filter: drop-shadow(0 1px 2px rgba(7, 17, 32, 0.6));
}
/* Image-variant toggle (escomp_menu_button_image): currentColor can't recolor
   an <img>, and a church picks that icon to read on the WHITE header — so over
   the photo the button keeps a solid white plate instead (inc/chrome.php adds
   the modifier only while the transparent header is active). Hover/open still
   go ink-on-surface via the higher-specificity state rules above. */
body.es-header-transparent .es-nav-toggle--img-plate {
	background: #ffffff !important;
	border-color: #ffffff !important;
}

/* ---- Desktop inline nav (only when "Use a menu button on desktop" is OFF):
   the top-level links, caret, and CTA divider float over the photo too, so
   they get the same light treatment. Grove runs the compact menu-button nav
   and never hits these; they keep the feature correct for a church on the
   full desktop menu. The white dropdown panel and its links are untouched
   (they sit on their own white surface), and mobile/compact keep the dark
   link colors — their menu lives in the white slide-down panel. ---- */
@media (min-width: 1024px) {
	body.es-header-transparent:not(.es-nav-compact) .es-menu > .es-menu-item > a,
	body.es-header-transparent:not(.es-nav-compact) .es-dropdown-toggle {
		color: var(--esc-on-dark) !important;
		text-shadow: 0 1px 3px rgba(7, 17, 32, 0.55);
	}
	/* Hover/focus re-declared at this specificity: ink on the light surface
	   (legible on its own opaque background), shadow off. */
	body.es-header-transparent:not(.es-nav-compact) .es-menu > .es-menu-item > a:hover,
	body.es-header-transparent:not(.es-nav-compact) .es-menu > .es-menu-item > a:focus,
	body.es-header-transparent:not(.es-nav-compact) .es-dropdown-toggle:hover,
	body.es-header-transparent:not(.es-nav-compact) .es-dropdown-toggle:focus {
		color: var(--esc-ink) !important;
		background: var(--esc-surface) !important;
		text-shadow: none;
	}
	/* Current-page link: white (the underline non-color cue carries over). On
	   hover/focus it must fall back to ink-on-surface with the other links —
	   without this explicit pair, the white rest color (same specificity,
	   later in source) would win over the hover rule's ink and leave a white
	   label on the cream surface. */
	body.es-header-transparent:not(.es-nav-compact) .es-menu > .es-menu-item > a[aria-current] {
		color: #ffffff !important;
	}
	body.es-header-transparent:not(.es-nav-compact) .es-menu > .es-menu-item > a[aria-current]:hover,
	body.es-header-transparent:not(.es-nav-compact) .es-menu > .es-menu-item > a[aria-current]:focus {
		color: var(--esc-ink) !important;
	}
	/* Top-level only (like the color rules above): the submenu links live in
	   the opaque WHITE dropdown panel, where a white focus ring would vanish —
	   they keep the base teal ring. */
	body.es-header-transparent:not(.es-nav-compact) .es-menu > .es-menu-item > a:focus-visible,
	body.es-header-transparent:not(.es-nav-compact) .es-dropdown-toggle:focus-visible {
		outline-color: #ffffff;
	}
	/* The header-CTA divider hairline + the teal-outline secondary pill read
	   poorly on a photo — white outline, mirroring the hero's own secondary. */
	body.es-header-transparent:not(.es-nav-compact) .es-header-ctas {
		border-left-color: rgba(255, 255, 255, 0.35);
	}
	body.es-header-transparent:not(.es-nav-compact) .es-header-ctas .es-btn-secondary,
	body.es-header-transparent:not(.es-nav-compact) .es-header-ctas .es-btn-secondary:link,
	body.es-header-transparent:not(.es-nav-compact) .es-header-ctas .es-btn-secondary:visited,
	body.es-header-transparent:not(.es-nav-compact) .es-header-ctas .es-btn-secondary:hover,
	body.es-header-transparent:not(.es-nav-compact) .es-header-ctas .es-btn-secondary:focus {
		background: transparent !important;
		color: #ffffff !important;
		border-color: rgba(255, 255, 255, 0.7) !important;
	}
	body.es-header-transparent:not(.es-nav-compact) .es-header-ctas .es-btn:focus-visible {
		outline-color: #ffffff;
	}
}

/* The dedicated transparent-header logo's anchor (inc/chrome.php). It is
   deliberately NOT .custom-logo-link — core's Customizer selective-refresh
   partial for custom_logo targets that class (container_inclusive) and would
   swap the dedicated logo back to the normal one mid-preview — so it mirrors
   that anchor's layout here. */
body.es-header-transparent .es-branding .es-transparent-logo-link {
	display: inline-flex;
	align-items: center;
	line-height: 0;
}

/* ---- The hero under the floating header: extra top padding so the welcome
   content never slides under the chrome. --esc-header-h is 64px by default, and
   a logo taller than 80px (where this fixed clearance would be exhausted) gets
   --esc-header-h overridden inline on this section in PHP (inc/homepage.php) to
   the real logo height, so the padding keeps tracking the header. A darker wash
   at the very top of the scrim lets the light chrome clear AA over any photo:
   the top stop --esc-hero-overlay-top = max(overlay, .55) is computed in PHP
   too — never lightens a church's higher overlay setting, and avoids
   max()-in-alpha, which is invalid-at-computed-value-time in older engines (it
   would drop the scrim entirely, not fall back). ---- */
body.es-header-transparent .es-home-welcome--hero {
	padding-top: calc(var(--esc-header-h) + 72px);
}
body.es-header-transparent .es-home-welcome--hero::before {
	background: linear-gradient(
		to bottom,
		rgba(7, 17, 32, var(--esc-hero-overlay-top, 0.55)) 0,
		rgba(7, 17, 32, calc(var(--esc-hero-overlay, 0.65) * 0.85)) 180px,
		rgba(7, 17, 32, var(--esc-hero-overlay, 0.65)) 100%
	);
}
/* The same treatment for Esselith Core's Hero block when it opens the front page
   (inc/homepage.php ess_filter_hero_block adds the vars; the block's own scrim
   reads --es-hero-overlay). Scoped to the FIRST child so a later Hero is untouched. */
body.es-header-transparent .entry-content > .es-hero--media:first-child {
	padding-top: calc(var(--esc-header-h) + 72px);
}
body.es-header-transparent .entry-content > .es-hero--media:first-child::before {
	background: linear-gradient(
		to bottom,
		rgba(7, 17, 32, var(--esc-hero-overlay-top, 0.55)) 0,
		rgba(7, 17, 32, calc(var(--es-hero-overlay, 0.65) * 0.85)) 180px,
		rgba(7, 17, 32, var(--es-hero-overlay, 0.65)) 100%
	);
}

/* ---- Section heading (events / team) ---- */
.es-home-heading {
	max-width: var(--esc-maxw);
	margin: 48px auto 8px;
	padding: 0 20px;
	text-align: center;
}
.es-home-heading-title {
	margin: 4px 0 0;
	font-family: var(--esc-font-display);
	font-size: var(--es-h2, clamp(1.625rem, 1.42rem + 0.88vw, 2.375rem));
	line-height: 1.15;
	color: var(--esc-ink);
}

/* ---- Next-steps band (dark) ---- */
.es-home-next-steps {
	/* The next-steps CTA is the TOP of the footer zone, not a mid-page band — match
	   the footer's darkest deep-teal so the CTA + footer read as one continuous dark
	   anchor with no seam. Solid fallback for pre-color-mix UAs. */
	background: #03202E;
	background: color-mix(in srgb, var(--es-deep-b, #04293A) 82%, #000);
	padding: 56px 20px 32px;
	text-align: center;
}
.es-home-next-steps-inner { max-width: 720px; margin: 0 auto; }
.es-home-next-steps-title {
	margin: 0 0 22px;
	font-family: var(--esc-font-display);
	font-size: var(--es-h2, clamp(1.625rem, 1.42rem + 0.88vw, 2.375rem));
	line-height: 1.12;
	color: #ffffff;
}

/* On the dark band the secondary uses the SOLID WHITE treatment, matching the
   suite CTA system — a teal fill would vanish on ink (hover = lift only). */
.es-home-next-steps .es-btn-secondary,
.es-home-next-steps .es-btn-secondary:link,
.es-home-next-steps .es-btn-secondary:visited,
.es-home-next-steps .es-btn-secondary:hover,
.es-home-next-steps .es-btn-secondary:focus {
	background: #ffffff !important;
	color: var(--esc-secondary) !important;
	border-color: #ffffff !important;
}
/* White focus ring on the dark band (same reason as the hero — teal is too low
   contrast on ink). */
.es-home-next-steps .es-btn:focus-visible {
	outline-color: #ffffff;
}

/* ---- Promo bands (About / Ministries / What’s Happening / Meet the Team) ----
   Theme-owned text + image editorial sections (Gate #1/#10). Full-bleed (pinned
   above) with a contained inner; alternating surface tint (--alt) + image side
   for rhythm. Mobile-first: single column, image on top, centered text. */
.es-home-promo {
	padding: 56px 20px;
	background: #ffffff;
	font-family: var(--esc-font-body);
}
.es-home-promo--alt {
	background: var(--esc-surface);
}
.es-home-promo-inner {
	max-width: var(--esc-maxw);
	margin: 0 auto;
	display: flex;
	flex-direction: column;
	gap: 28px;
	align-items: center;
}
.es-home-promo-media { width: 100%; }
.es-home-promo-img {
	display: block;
	width: 100%;
	height: auto;
	border-radius: var(--es-radius-card, 16px);
}
.es-home-promo-body { width: 100%; text-align: center; }
.es-home-promo--text .es-home-promo-body { max-width: 640px; margin: 0 auto; }
.es-home-promo-title {
	margin: 6px 0 14px;
	font-family: var(--esc-font-display);
	font-size: var(--es-h2, clamp(1.625rem, 1.42rem + 0.88vw, 2.375rem));
	line-height: 1.15;
	color: var(--esc-ink);
}
.es-home-promo-text {
	margin: 0 auto 24px;
	max-width: 56ch;
	color: var(--esc-text);
	font-size: 1.05rem;
	line-height: 1.6;
}
.es-home-promo-cta {
	display: flex;
	flex-wrap: wrap;
	gap: 12px;
	justify-content: center;
}

@media (min-width: 782px) {
	.es-home-promo { padding: 88px 20px; }
	.es-home-promo--media .es-home-promo-inner {
		flex-direction: row;
		gap: 48px;
		max-width: 1300px;
	}
	/* Alternate the image side: even bands keep image-left (normal row); odd
	   bands flip to image-right. */
	.es-home-promo--media.es-home-promo--right .es-home-promo-inner {
		flex-direction: row-reverse;
	}
	/* Give the image the larger share so the photo reads big and editorial. */
	.es-home-promo--media .es-home-promo-media {
		flex: 1.55 1 0;
		min-width: 0;
	}
	.es-home-promo--media .es-home-promo-body {
		flex: 1 1 0;
		min-width: 0;
	}
	.es-home-promo--media .es-home-promo-body { text-align: left; }
	.es-home-promo--media .es-home-promo-text {
		margin-left: 0;
		margin-right: 0;
		max-width: 48ch;
	}
	.es-home-promo--media .es-home-promo-cta { justify-content: flex-start; }
}

@media (min-width: 782px) {
	.es-home-welcome,
	.es-home-next-steps { padding: 80px 20px; }
	/* The next-steps band is the TOP of the footer (same dark surface as the
	   columns below), so trim its bottom padding — otherwise the band-bottom +
	   footer-column-top padding stack into an oversized dark gap under the CTA. */
	.es-home-next-steps { padding-bottom: 40px; }
	/* Bigger hero padding on larger screens (kept after the rule above so it
	   wins the equal-specificity tie on padding). ⚠️ Deliberately NO
	   min-height here: the hero's height is governed at ALL widths by the
	   var-driven base rule (the Customizer "Hero height (% of screen)"
	   slider via --esc-hero-h). A Layer-3-era 70vh/760px cap in this block
	   used to win the cascade above 782px, silently pinning desktop heroes
	   and making the slider a no-op — do not reintroduce one. */
	.es-home-welcome--hero {
		padding: 104px 20px;
	}
	.es-home-heading { margin-top: 64px; }
}

/* ==================================================================== *
 *  A11Y + MOTION
 * ==================================================================== */
.es-site-header .screen-reader-text,
.es-site-footer .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;
}

@media (prefers-reduced-motion: reduce) {
	.es-nav-toggle-bar,
	.es-caret,
	.es-btn,
	.es-social-link {
		transition: none !important;
	}
}

/* ==================================================================== *
 *  ASTRA BRAND + FONT AUTO-SYNC  (item E)
 *
 *  Makes Astra's OWN content — plain page/post text, headings, links,
 *  buttons, Gutenberg blocks: everything outside the suite plugins — follow
 *  the church's Core-chosen brand colors + font pairing, so "set your brand
 *  once" covers the WHOLE site, not just the suite. Pure CSS, reversible
 *  (deactivate the theme -> Astra reverts). Reads --es-* with reference-
 *  palette fallbacks; never defines --es-* (Core owns that). Verified against
 *  Astra 4.13.4 — re-check on a MAJOR Astra update (see suite memory).
 *
 *  Astra 4.13.4 specifics that shape this block:
 *   - Astra funnels links, accents, outlines, form-focus AND solid-button
 *     backgrounds through ONE slot (--ast-global-color-0). The suite reserves
 *     orange for buttons/CTAs only and uses teal for accents/decoration, so we
 *     point that shared slot at the suite SECONDARY (teal — ~8.6:1 on white,
 *     AA-safe as link text) and re-brand only the SOLID buttons to the primary
 *     below. Net: links/accents = teal, buttons = brand orange.
 *   - Astra HARDCODES font-family in generated CSS (no font CSS var) and its
 *     heading rule sets weight only (headings inherit the body family). So
 *     fonts need explicit family selectors with !important, and headings are
 *     promoted to the DISPLAY family to match the suite.
 *   - companion.css already loads after Astra's inline :root (it depends on
 *     'astra-theme-css'); html:root is a defensive specificity bump.
 * ==================================================================== */

/* 1. Palette — map Astra's accent + text slots onto the suite tokens. A slot
   that references an --es-* token inherits future brand-color edits for free
   (Core re-emits :root on every Brand-screen change). Astra's neutral
   background/border slots (4/5/7) are left at the Astra defaults. */
html:root {
	--ast-global-color-0: var(--es-brand-secondary, #004F71);                                /* links / accents / outlines / focus */
	--ast-global-color-1: color-mix(in srgb, var(--es-brand-secondary, #004F71) 80%, #000);  /* accent / link hover (darker teal) */
	--ast-global-color-2: var(--es-ink, #071120);                                            /* heading text */
	--ast-global-color-3: var(--es-text, #2E3D48);                                           /* body text */
}

/* 2. Solid buttons stay the brand action color (orange) with an INK label
   (~7.5:1 on orange — AA-legible, and the suite's documented CTA standard;
   the former white label was ~2.5:1, an AA fail), pinned across rest/hover/
   focus — the suite's Astra-defense pattern (live Astra recolors bare buttons
   otherwise). Outline/ghost block buttons are excluded so they keep the teal
   accent from slot-0 above. */
.wp-block-button:not(.is-style-outline) > .wp-block-button__link,
.wp-block-button:not(.is-style-outline) > .wp-block-button__link:hover,
.wp-block-button:not(.is-style-outline) > .wp-block-button__link:focus,
.wp-block-search__button,
.wp-block-search__button:hover,
.wp-block-search__button:focus,
.ast-button,
.ast-button:hover,
.ast-button:focus,
.ast-custom-button,
.ast-custom-button:hover,
.ast-custom-button:focus,
input[type="submit"],
input[type="submit"]:hover,
input[type="submit"]:focus,
button[type="submit"],
button[type="submit"]:hover,
button[type="submit"]:focus {
	background-color: var(--es-brand-primary, #ED8B00) !important;
	border-color:     var(--es-brand-primary, #ED8B00) !important;
	color:            var(--es-ink, #071120) !important;
}

/* 3. (0.24.0, arc 5) Every block button is 48px tall and answers hover/focus
   with a 2px lift — its colours never change (the former orange-darken and
   outline-fills-teal flips are gone). Reduced-motion visitors get no lift. */
.wp-block-button > .wp-block-button__link {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-height: var(--es-btn-height, 48px);
	/* 0.24.1 — the body's 1.6 line height made block buttons 53px; at 1.2
	   they sit on the 48px floor like the theme's own buttons. */
	line-height: 1.2;
	transition: transform 0.18s ease;
}
.wp-block-button > .wp-block-button__link:hover,
.wp-block-button > .wp-block-button__link:focus-visible {
	transform: translateY(var(--es-btn-lift, -2px));
}
@media (prefers-reduced-motion: reduce) {
	.es-btn,
	.wp-block-button > .wp-block-button__link { transition: none; }
	.es-btn:hover, .es-btn:focus-visible,
	.wp-block-button > .wp-block-button__link:hover,
	.wp-block-button > .wp-block-button__link:focus-visible { transform: none; }
}
/* Secondary (outline) block buttons placed on a DARK band — the author tags
   them has-on-dark-color / has-white-color. Per the suite rule, a teal fill or
   a white outline is too low-contrast on ink, so these render as a solid WHITE
   fill with TEAL lettering, in every state. (Light-band outlines keep their
   transparent teal outline.) */
.wp-block-button.is-style-outline > .wp-block-button__link.has-on-dark-color,
.wp-block-button.is-style-outline > .wp-block-button__link.has-on-dark-color:link,
.wp-block-button.is-style-outline > .wp-block-button__link.has-on-dark-color:visited,
.wp-block-button.is-style-outline > .wp-block-button__link.has-on-dark-color:hover,
.wp-block-button.is-style-outline > .wp-block-button__link.has-on-dark-color:focus,
.wp-block-button.is-style-outline > .wp-block-button__link.has-white-color,
.wp-block-button.is-style-outline > .wp-block-button__link.has-white-color:link,
.wp-block-button.is-style-outline > .wp-block-button__link.has-white-color:visited,
.wp-block-button.is-style-outline > .wp-block-button__link.has-white-color:hover,
.wp-block-button.is-style-outline > .wp-block-button__link.has-white-color:focus {
	background-color: #ffffff !important;
	border-color:     #ffffff !important;
	color:            var(--es-brand-secondary, #004F71) !important;
}
/* (0.19.0) A light band switched to "Dark section" keeps its TEAL outline
   buttons (has-secondary-color), which nearly vanish on the dark band. Give them
   the same white-pill treatment as a dark-band outline — except inside a light
   panel (card, white or cream group) that sits within the dark band. */
.is-style-esselith-dark .wp-block-button.is-style-outline > .wp-block-button__link.has-secondary-color:not(.is-style-esselith-dark :is(.is-style-esselith-card, .has-white-background-color, .has-surface-background-color, .has-page-bg-background-color) *) {
	background-color: #ffffff !important;
	border-color:     #ffffff !important;
	color:            var(--es-brand-secondary, #004F71) !important;
}

/* 4. Eyebrow legibility on dark bands. A small brand-coloured eyebrow paragraph
   on a dark (ink) group can fall to low contrast when the church's brand primary
   /secondary is muted (e.g. the welcome-hero "WELCOME" kicker). Force a
   brand-coloured PARAGRAPH on an ink-background group to the light on-dark
   colour so it stays legible regardless of the brand colours. Scoped to <p> so
   it never touches headings, buttons, or links. (New welcome-hero insertions
   already ship a white eyebrow; this also rescues older inserted instances on a
   redeploy without re-inserting the pattern.) */
.wp-block-group.has-ink-background-color p.has-primary-color,
.wp-block-group.has-ink-background-color p.has-secondary-color,
.wp-block-group.has-ink-background-color p.has-accent-color {
	color: var(--es-text-on-dark, #E8ECF5) !important;
}

/* 3. Typography — Astra hardcodes font-family (no CSS var) and leaves headings
   inheriting the body family, so map explicitly with !important and promote
   headings to the DISPLAY family (matching the suite). */
body,
button,
input,
select,
textarea,
.ast-button,
.ast-custom-button {
	font-family: var(--es-font-body, "Montserrat", system-ui, -apple-system, sans-serif) !important;
}
h1, h2, h3, h4, h5, h6,
.entry-title, .entry-title a,
.site-title, .site-title a,
.ast-archive-title,
.widget-title {
	font-family: var(--es-font-display, "Playfair Display", Georgia, serif) !important;
}

/* ==================================================================== *
 *  HOMEPAGE EVENTS BAND (Nave) — productized from a per-page <style>.
 *  Merges the theme's home-heading into Nave's events band as one flush
 *  cream section, and flattens the band's brand washes. Applies whenever
 *  [escomp_events] renders the heading immediately before .ces-events-section.
 * ==================================================================== */
.es-home-heading:has(+ .ces-events-section) {
	background: var(--ces-section-bg);
	width: 100vw;
	max-width: 100vw;
	margin: 0 calc(50% - 50vw);
	padding: 64px 24px 4px;
	text-align: center;
}
.es-home-heading:has(+ .ces-events-section) + .ces-events-section { padding-top: 20px; }

/* (0.18.1) [escomp_events] now renders its heading INSIDE Nave's band, so the
   heading sits on whatever the band is — the rule above stays for any page that
   still places the heading before the band by hand. On the default deep-teal
   band, light type exactly like Nave's own section header; on tone="light" the
   normal ink heading. */
.ces-events-section > .es-home-heading {
	max-width: 720px;
	margin: 0 auto 40px;
	padding: 0;
}
.ces-events-section:not(.ces-events-section--light) > .es-home-heading .es-home-eyebrow {
	color: #ffffff;
}
.ces-events-section:not(.ces-events-section--light) > .es-home-heading .es-home-heading-title {
	color: var(--es-text-on-dark, #E8ECF5);
}
.ces-events-section { background-image: none !important; }

/* Aligned column groups need edge padding on phones so they don't touch the
   screen edge. */
@media (max-width: 782px) {
	.entry-content > .wp-block-group.alignwide:has(.wp-block-columns) {
		padding-left: var(--wp--preset--spacing--40, 24px);
		padding-right: var(--wp--preset--spacing--40, 24px);
	}
}
/* Nave event bento — one card per row on small phones. */
@media (max-width: 600px) {
	.ces-bento-board[class*="ces-bento-count-"] > .ces-event-card {
		grid-column: span 1 !important;
		grid-row: span 1 !important;
	}
}
