/**
 * Concept C — verbatim demo CSS, bridged to theme.json tokens.
 *
 * SOURCE OF TRUTH for visual fidelity: website/04-design/previews/homepage.html.
 * This file is the demo's <style> block, kept VERBATIM below the bridge, so that
 * the cc-* block patterns (which output the SAME class names the demo CSS targets:
 * .hero/.imgwrap/.floatstat/.btn/.pill/.split/.band/.steps/.gallery/.ctaband ...)
 * render pixel-faithful in WordPress.
 *
 * HOW THE BRIDGE WORKS:
 *   The demo CSS is written against short variables (--cta, --bg, --card, --fh ...).
 *   The :root block below maps those onto the theme.json preset variables
 *   (--wp--preset--color--*, --wp--preset--font-family--*) so the live site's
 *   palette picker, font selection, and dark mode all drive this CSS unchanged.
 *
 * REMOVED vs the demo: the preview-only dev palette/type switcher CSS (.switchbar,
 * .swhide, .switchtoggle) — that scaffolding is not shipped.
 *
 * Dark mode: html[data-theme="dark"] re-points the WP preset color vars to the
 * Brand Blue dark token values (kept in sync with styles/dark.json).
 */

/* ---- 1. BRIDGE: demo vars -> theme.json preset tokens ---- */
:root{
	--primary:var(--wp--preset--color--primary);
	--secondary:var(--wp--preset--color--secondary);
	--cta:var(--wp--preset--color--cta);
	--ctad:var(--wp--preset--color--cta-hover);
	--accent:var(--wp--preset--color--accent);
	--bg:var(--wp--preset--color--base);
	--card:var(--wp--preset--color--card);
	--text:var(--wp--preset--color--contrast);
	--muted:var(--wp--preset--color--muted);
	--line:var(--wp--preset--color--line);
	/* In-prose LINK color — a separate token from --cta on purpose.
	   --cta is a SURFACE color (button backgrounds, where the label is #fff), so it is
	   deliberately kept from the light palette in dark mode. Used as TEXT on the dark
	   base it measured 1.80:1 — a sitewide WCAG AA failure on every in-prose link, not
	   just blog links. Light mode keeps --cta exactly (zero visual change); dark mode
	   re-points this to a light blue below. Buttons are unaffected: .btn-p/.btn-g set
	   their own color and outrank the bare `a` rule. */
	--link:var(--cta);
	--fh:var(--wp--preset--font-family--heading);
	--fb:var(--wp--preset--font-family--body);
	/* Inverted-section surface (proof band + CTA band). In LIGHT mode this is the
	   brand-dark "primary" so it tracks the palette picker. It is a SEPARATE token
	   from --primary because dark mode re-points --primary to #FFFFFF (for headings),
	   which would turn these dark sections white-on-white. Dark mode pins it dark. */
	--band-bg:var(--wp--preset--color--primary);
	/* Shared "large feature photo" shadow — same value the hero image uses, so all
	   large static photos (hero, problem-solution, institutional, audience panel)
	   carry one consistent shadow. Gallery + how-it-works images are excluded. */
	--feature-shadow:0 30px 64px -34px rgba(15,23,42,.38),0 22px 46px -26px color-mix(in srgb,var(--accent) 70%,transparent);
	/* Footer surface — derived from the brand --primary so it tracks every palette
	   (was a hardcoded navy). Text uses white-alpha so it reads on any palette's dark
	   footer. Dark mode pins an explicit near-black below (since --primary flips white). */
	--footer-bg:color-mix(in srgb,var(--primary) 86%,#000);
	--footer-text:rgba(255,255,255,.62);
	/* .55 ≈ 5.7:1 on the footer surface — clears WCAG AA (the prior .42 was 4.09:1, a fail). */
	--footer-faint:rgba(255,255,255,.55);
	--footer-line:rgba(255,255,255,.14);
}

/* ---- 2. DARK MODE: re-point WP preset color vars (mirrors styles/dark.json) ---- */
html[data-theme="dark"]{
	--wp--preset--color--base:#0E0F26;
	--wp--preset--color--card:#1B1C40;
	--wp--preset--color--contrast:#ECEDFB;
	--wp--preset--color--muted:#9B9DC8;
	--wp--preset--color--line:#2E3060;
	--wp--preset--color--primary:#FFFFFF;
	--wp--preset--color--secondary:#C7C9EA;
	/* cta + accent intentionally kept from the active light palette */
	/* Measured: 8.20:1 on --base #0E0F26, 7.15:1 on --card #1B1C40 (WCAG AA needs 4.5).
	   Replaces --cta-as-text, which measured 1.80:1 here. Fixed, not palette-derived:
	   the dev palette picker swaps --cta, and a derived link color could land back in
	   the failing range on some palette. Re-measure if this value is ever changed. */
	--link:#8AA9FF;
	/* Inverted-section surfaces in dark mode, DERIVED from the (palette-overridden)
	   dark base/card so they track whichever palette is active — the dev picker swaps
	   base/card per palette, and these follow. For the shipped Brand Blue defaults
	   above this resolves to ~#16173A (band) / ~#0B0A1E (footer), unchanged. */
	--band-bg:color-mix(in srgb,var(--wp--preset--color--card) 65%,var(--wp--preset--color--base));
	--footer-bg:color-mix(in srgb,var(--wp--preset--color--base) 80%,#000);
}

/* ---- 3. DEMO CSS (verbatim, dev switcher removed) ---- */
*{box-sizing:border-box}
body{margin:0;font-family:var(--fb),sans-serif;color:var(--text);background:var(--bg);transition:background .25s,color .25s}
.w{max-width:1320px;margin:0 auto;padding:0 28px}
h1,h2,h3,.h{font-family:var(--fh);color:var(--primary);line-height:1.12;margin:0 0 .4em}
h2{font-size:clamp(1.7rem,2.8vw,2.3rem);letter-spacing:-.4px;text-wrap:balance}
p{color:var(--muted);line-height:1.6;margin:0 0 1rem}
a{color:var(--link);text-decoration:none}
.eyebrow{color:var(--accent);font-family:var(--fh);font-weight:700;text-transform:uppercase;letter-spacing:.7px;font-size:.76rem;margin-bottom:.4rem}
/* Bug-fix #1: WordPress global-styles (theme.json core/paragraph -> muted) ties the
   single-class `.eyebrow` rule on source order and renders eyebrows gray. Raise the
   accent color to (0,2,0) specificity with a self-referential `:root .eyebrow`
   prefix (and the WP preset var) so EVERY eyebrow paragraph wins without !important.
   Patterns that intentionally recolor an eyebrow inline (cc-problem-solution=accent,
   cc-institutional=cta) still win because inline styles outrank this. */
/* Eyebrow TEXT color (council decision). Raw accent orange fails WCAG AA on light
   surfaces (~2:1). On LIGHT surfaces use the accent deepened toward black (55% accent
   + black ≈ 6.3:1 on white, still clearly the brand's warm accent). On DARK surfaces
   (dark mode + the light-mode proof band) the raw accent already passes 7-8:1, so keep
   it bright. The accent stays raw as a NON-text accent (trust dots / avatars). */
:root .eyebrow,.eyebrow.eyebrow{color:color-mix(in srgb,var(--wp--preset--color--accent,var(--accent)) 55%,#000)}
html[data-theme="dark"] .eyebrow{color:var(--wp--preset--color--accent,var(--accent))}
.center{text-align:center;max-width:680px;margin:0 auto 34px}
.btn{display:inline-flex;align-items:center;justify-content:center;gap:.45rem;font-family:var(--fh);font-weight:600;font-size:1rem;padding:.85rem 1.6rem;border-radius:999px;border:1px solid transparent;cursor:pointer;transition:.2s}
.btn-p{background:var(--cta);color:#fff;box-shadow:0 10px 26px -10px color-mix(in srgb,var(--cta) 60%,transparent)}.btn-p:hover{background:var(--ctad)}
.btn-g{background:var(--card);color:var(--primary);border:1px solid color-mix(in srgb,var(--text) 24%,transparent);box-shadow:0 1px 4px rgba(15,23,42,.08)}
.btn-g:hover{border-color:var(--cta);color:var(--cta);box-shadow:inset 0 0 0 1px var(--cta),0 1px 4px rgba(15,23,42,.08)}
.pill{display:inline-flex;gap:.4rem;align-items:center;background:var(--card);border:1px solid color-mix(in srgb,var(--text) 22%,transparent);border-radius:999px;padding:.5rem 1rem;font-size:.82rem;font-weight:600;color:var(--text);box-shadow:0 1px 4px rgba(15,23,42,.10)}
.dia{color:var(--accent)}
.row{display:flex;gap:10px;flex-wrap:wrap}
/* nav */
header{position:sticky;top:0;z-index:60;background:color-mix(in srgb,var(--bg) 86%,transparent);backdrop-filter:blur(10px);border-bottom:1px solid var(--line)}
/* Bug-fix #6: keep the header sticky and uncut.
   1. The header template-part renders <header class="wp-block-group">; pin the same
      sticky/top/z-index on that selector so a higher-specificity core rule can't
      override the bare-element rule above.
   2. Any ancestor with overflow other than visible silently kills position:sticky, so
      guarantee the scroll container (html/body and the layout wrappers) don't clip it.
   3. Admin bar: when logged in, body.admin-bar shows a 32px bar (>=783px) or a 46px bar
      (<=782px) FIXED at the top; offset the sticky header below it so it isn't cut. */
header.wp-block-group{position:sticky;top:0;z-index:60}
/* The header template-part renders inside a .wp-block-template-part wrapper that is only
   header-height tall, which CONFINES position:sticky to that box so the header scrolls
   off. display:contents removes the wrapper box so the sticky header's containing block
   becomes the full-height .wp-site-blocks. (Footer wrapper unaffected visually.) */
.wp-site-blocks > .wp-block-template-part{display:contents}
/* overflow-x:clip on the HTML element prevents horizontal scroll from full-bleed bands
   WITHOUT breaking the sticky header — putting it on BODY confines position:sticky and
   the header scrolls off. Keep it on html only. */
html{overflow-x:clip}
/* Anchor jumps (#aud/#how/#proof/#videos/#gallery) and focused targets must clear
   the sticky header (WCAG 2.4.11 Focus Not Obscured). Offset = header height. */
html{scroll-padding-top:104px}
.admin-bar{scroll-padding-top:136px}
body main.wp-block-group{overflow:visible}
.admin-bar header,.admin-bar header.wp-block-group{top:32px}
@media screen and (max-width:782px){
	.admin-bar header,.admin-bar header.wp-block-group{top:46px}
}
.nav{display:flex;align-items:center;justify-content:space-between;height:92px}
/* Banner logo (2026 SSS3) carries its own translucent card, so the .logo wrapper is
   just a sizing/centering container — no extra plate. Taller now that the wordmark
   dropped its bottom tagline line. */
.logo{display:flex;align-items:center;margin:0}.logo img{height:64px;width:auto;display:block}
.navlinks{display:flex;gap:1.2rem;align-items:center;font-family:var(--fh);font-weight:600;font-size:.9rem}.navlinks a{color:var(--secondary);cursor:pointer}.navlinks a:hover{color:var(--cta)}
.navright{display:flex;align-items:center;gap:12px}
/* native header: .nav/.navlinks/.navright are now core/group; logo is core/image
   (figure.wp-block-image.logo); links are .navlink paragraphs; CTA is core/button. */
.nav.wp-block-group{display:flex;align-items:center;justify-content:space-between;height:92px;margin:0 auto;flex-wrap:nowrap}
figure.wp-block-image.logo{display:flex;align-items:center;margin:0;flex:none}
figure.wp-block-image.logo img{height:64px;width:auto;display:block;max-width:none}
.navlinks.wp-block-group{display:flex;gap:1.2rem;align-items:center;font-family:var(--fh);font-weight:600;font-size:.9rem;margin:0}
.navlinks .navlink{margin:0}
.navlinks .navlink a{color:var(--secondary);cursor:pointer}.navlinks .navlink a:hover{color:var(--cta)}
.navright.wp-block-group{display:flex;align-items:center;gap:12px;margin:0;flex:none}
.nav-cta.wp-block-buttons{margin:0}
.nav-cta .wp-block-button.btn-p>.wp-block-button__link{padding:.6rem 1.1rem}
/* Header CTA link (wp:html header anchor). Was an inline style="padding:.6rem 1.1rem"
   that beat the mobile media query on specificity; moved here so the <=600px tier can
   shrink it. Compact vs the .btn base (.85rem 1.6rem) which is too tall for a 92px nav. */
.nav .btn.nav-cta-link{padding:.6rem 1.1rem}
.modetoggle{width:40px;height:40px;border-radius:10px;border:1px solid color-mix(in srgb,var(--text) 18%,transparent);background:var(--card);color:var(--secondary);display:flex;align-items:center;justify-content:center;cursor:pointer;transition:.2s}.modetoggle:hover{color:var(--cta);border-color:var(--cta)}
/* ---- Desktop "Solutions" dropdown (D018). Token-driven; shows at >900px where
   .navlinks shows, and is hidden inside the .mobilenav at <=900px (rules in the
   media block below). The wrapper is the hover/focus zone and the positioning
   context for the absolutely-positioned card menu. ---- */
/* Trigger styled to match .navlinks a (same color/weight/font via the parent), plus
   a chevron. Reset native button chrome so it sits inline like the sibling links. */
/* The dropdown card: same card surface / line / radius / shadow language as the
   homepage cards (.card + .aud-panel shadow). Positioned below the trigger. z-index
   above the sticky header's own stacking so it overlays page content. */
/* Invisible hover bridge: the menu sits 14px below the trigger; without this, moving the
   pointer across that gap leaves .navdrop-wrap and the menu closes before it can be used.
   The ::before is a descendant of the menu, so the pointer never leaves the wrap region. */
/* "All Solutions" hub row: emphasized + a hairline divider below it. */
/* ---- Mobile menu (hamburger). Hidden on desktop; shown <=900px when .navlinks hide.
   The bar mode-toggle moves into the menu on mobile so logo+CTA+hamburger fit. ---- */
@media(max-width:900px){
	/* "Solutions" expandable group: the expander row mirrors a .mobilenav>a row; the
	   nested submenu links are indented. Token-driven; works in light + dark. */
}
/* sections + motion */
section{padding:62px 0}
/* ---- Section surface scale: subtle alternating segmentation (council spec) ----
   Three tones, all color-mix off --primary so they track every palette AND dark
   mode automatically (dark mode re-points --primary to #fff over a dark --bg, which
   yields gently *lighter* elevated surfaces — the correct dark-UI direction). The
   rhythm across the page is intentionally irregular (0,1,0 | dark | 1,0,1,2) so it
   reads as segmentation, never stripes. Max delta between two consecutive light
   sections is 3.5% (below the banding ceiling). Driven by per-section .surf-* classes
   (NOT nth-of-type) so reordering patterns can't corrupt the scheme. */
:root{
	--surface-0:var(--bg);
	--surface-1:color-mix(in srgb,var(--primary) 3.5%,var(--bg));
	--surface-2:color-mix(in srgb,var(--primary) 6.5%,var(--bg));
}
.surf-0{background:var(--surface-0)}
.surf-1{background:var(--surface-1)}
.surf-2{background:var(--surface-2)}
/* Back-compat: existing .alt markup maps to the low tint. */
.alt{background:var(--surface-1)}
/* The audience router constrains width on its OWN element, so a plain background
   would tint only the centred 1320px and leave base-coloured gutters. Paint a
   full-bleed band behind it instead (safe: html/body already have overflow-x:clip,
   so 100vw won't add horizontal scroll). */
.sos-aud.surf-1{position:relative;z-index:0;background:transparent}
.sos-aud.surf-1::before{content:"";position:absolute;top:0;bottom:0;left:50%;margin-left:-50vw;width:100vw;background:var(--surface-1);z-index:-1}
/* Progressive enhancement: .up is only HIDDEN when <html class="js"> is set (added
   before paint by the head script). Without JS — or in the block editor, or if reveal.js
   fails — content stays visible instead of stuck invisible. reveal.js adds .reveal.in
   on scroll to animate it in. (A head-level 4s fallback reveals all if reveal.js never runs.) */
html.js .up{opacity:0;transform:translateY(24px);transition:opacity .7s ease,transform .7s cubic-bezier(.16,1,.3,1)}
.reveal.in .up{opacity:1;transform:none}
.reveal.in .up.s1{transition-delay:.08s}.reveal.in .up.s2{transition-delay:.16s}.reveal.in .up.s3{transition-delay:.24s}.reveal.in .up.s4{transition-delay:.32s}
@media(prefers-reduced-motion:reduce){.up{opacity:1!important;transform:none!important;transition:none!important}}
/* hero */
.hero{display:grid;grid-template-columns:.8fr 1.2fr;gap:44px;align-items:center;padding:46px 0 70px}
.hero h1{font-size:clamp(2.1rem,3.6vw,3rem);letter-spacing:-.6px;line-height:1.08;margin:.4em 0 .5em;text-wrap:balance}
.hero .sub{font-size:1.1rem;max-width:32rem}
/* Standard breathing room above the hero CTAs (subhead sits directly above). */
.hero .wp-block-buttons.row{margin-top:1.6rem}
.imgwrap{position:relative}
.imgwrap>img,.imgwrap>.wp-block-image{width:100%;border-radius:18px;aspect-ratio:3/2;object-fit:cover;box-shadow:0 30px 64px -34px rgba(15,23,42,.38),0 22px 46px -26px color-mix(in srgb,var(--accent) 70%,transparent);margin:0;display:block;overflow:hidden}
.imgwrap>.wp-block-image img{width:100%;height:100%;border-radius:18px;aspect-ratio:3/2;object-fit:cover;margin:0;display:block}
.floatstat{position:absolute;left:20px;right:20px;bottom:20px;background:color-mix(in srgb,var(--card) 90%,transparent);backdrop-filter:blur(8px);border:1px solid var(--line);border-radius:14px;padding:14px 10px;display:grid;grid-template-columns:repeat(3,1fr);align-items:center;text-align:center}
.floatstat b,.floatstat .fs-n{font-family:var(--fh);font-size:1.5rem;font-weight:700;color:var(--cta);display:block;margin:0;line-height:1.12;letter-spacing:0}
.floatstat .fs-n strong{font-weight:700;color:var(--cta)}
.floatstat span,.floatstat .fs-l{font-size:.72rem;color:var(--muted);margin:0;line-height:1.2}
/* Bug-fix #4: floatstat cells are core/group; WP gave them block-gap margins +
   stretch, which mis-centered the number/label and inflated the card height. Make each
   cell a tight, centered flex column and strip the injected margins so the 3 cells sit
   in one short, vertically-aligned row (matches the demo's compact bare-<div> card). */
.floatstat .fs-cell{display:flex;flex-direction:column;justify-content:center;align-items:center;gap:2px;text-align:center}
.floatstat .fs-cell.wp-block-group{margin:0}
.floatstat.wp-block-group{gap:0;margin:0}
.trust{display:flex;align-items:center;gap:.55rem;margin-top:1.3rem;color:var(--muted);font-size:.86rem}
.trust p{margin:0;color:var(--muted)}.trust b,.trust strong{color:var(--primary);font-weight:700}
.trust .dots{display:flex;align-items:center}.trust .dots i,.trust .dots .dot{width:26px;height:26px;border-radius:50%;border:2px solid var(--card);background:linear-gradient(135deg,var(--accent),color-mix(in srgb,var(--cta) 70%,var(--primary)));margin-left:-8px;display:block;flex:none}
.trust .dots.wp-block-group{gap:0}
/* Bug-fix #3: .trust + .dots are core/group (default layout). WP injects vertical
   block-gap margins between their children, which knocks the dots and the text off the
   shared center line and stacks the dots unevenly. Both rows are flex+center; strip the
   injected margins so the 4 overlapping dots sit in one centered row beside the text. */
.trust.wp-block-group{display:flex;align-items:center;gap:.55rem;flex-wrap:nowrap}
.trust.wp-block-group>*{margin-top:0;margin-bottom:0}
.trust .dots.wp-block-group>.dot{margin-top:0;margin-bottom:0}
/* audience branching (router block owns its own markup; classes kept for parity) */
.aud-tabs{display:flex;gap:8px;flex-wrap:wrap;justify-content:center;margin-bottom:26px}
.aud-tab{cursor:pointer;font-family:var(--fh);font-weight:600;font-size:.9rem;padding:.6rem 1.1rem;border-radius:999px;border:1px solid var(--line);background:var(--card);color:var(--secondary);transition:.2s}
.aud-tab:hover{border-color:var(--cta);color:var(--cta)}
.aud-tab.on{background:var(--cta);color:#fff;border-color:var(--cta)}
.aud-panel{display:grid;grid-template-columns:1.1fr .9fr;gap:36px;align-items:center;background:var(--card);border:1px solid var(--line);border-radius:18px;padding:30px;box-shadow:0 20px 50px -34px rgba(15,23,42,.4)}
.aud-panel img{width:100%;border-radius:12px;aspect-ratio:4/3;object-fit:cover}
.aud-panel h3{font-size:1.5rem;margin-bottom:.3em}
.aud-need{display:flex;flex-direction:column;gap:8px;margin:14px 0 18px}
.aud-need div{display:flex;gap:9px;align-items:flex-start;font-size:.9rem;color:var(--secondary)}
.aud-need svg{flex:none;margin-top:2px}
/* grids */
.grid{display:grid;gap:16px}.g4{grid-template-columns:repeat(4,1fr)}.g3{grid-template-columns:repeat(3,1fr)}.g6{grid-template-columns:repeat(6,1fr)}
.card{background:var(--card);border:1px solid var(--line);border-radius:12px;padding:18px;transition:.2s}
.card h3{font-size:1rem;margin-bottom:.15rem}.card p{font-size:.84rem;margin:0}
.ico{width:36px;height:36px;border-radius:9px;background:color-mix(in srgb,var(--cta) 13%,transparent);color:var(--cta);display:flex;align-items:center;justify-content:center;margin-bottom:10px}
/* split */
.split{display:grid;grid-template-columns:1fr 1fr;gap:42px;align-items:center}
.split img{width:100%;border-radius:14px;aspect-ratio:4/3;object-fit:cover}
/* Consistent feature-photo shadow on the larger static photos (problem-solution +
   institutional live in .split; audience panel image is .sos-aud__image). The hero
   (.imgwrap) already carries it. Gallery (.cc-gallery) and steps (.step) are excluded. */
.split .wp-block-image,.split>img{box-shadow:var(--feature-shadow);border-radius:14px}
.sos-aud__image{box-shadow:var(--feature-shadow)}
/* proof band + testimonials */
.band{background:var(--band-bg);color:#fff}.band h2{color:#fff}.band .center p{color:rgba(255,255,255,.7)}
/* Bug-fix #9: the proof-band eyebrow sits inside .center, so `.band .center p`
   (0,2,1) outranks the global eyebrow fix (0,2,0) and renders it white. Restore
   the accent color with a band-scoped (0,3,0) rule — the user wants this labeled. */
.band .center .eyebrow,.band .eyebrow.eyebrow{color:var(--wp--preset--color--accent,var(--accent))}
.stats{display:flex;gap:40px;justify-content:center;flex-wrap:wrap;margin-bottom:30px}
.stat b,.stat .st-n{font-family:var(--fh);font-size:2.4rem;font-weight:700;color:#fff;display:block;margin:0;line-height:1.12;letter-spacing:0}.stat .st-n strong{font-weight:700;color:#fff}.stat span,.stat .st-l{color:rgba(255,255,255,.6);font-size:.85rem;margin:0}
.quote.wp-block-quote{background:rgba(255,255,255,.05);border:1px solid rgba(255,255,255,.12);border-radius:14px;padding:20px;display:flex;flex-direction:column;gap:12px;margin:0}
.quote{background:rgba(255,255,255,.05);border:1px solid rgba(255,255,255,.12);border-radius:14px;padding:20px;display:flex;flex-direction:column;gap:12px}
.quote p,.quote.wp-block-quote p{color:rgba(255,255,255,.9);font-size:.92rem;margin:0;line-height:1.55}
.quote .who{display:flex;align-items:center;gap:10px}
.quote .av{width:38px;height:38px;border-radius:50%;background:linear-gradient(135deg,var(--accent),color-mix(in srgb,var(--cta) 70%,var(--primary)));display:flex;align-items:center;justify-content:center;font-family:var(--fh);font-weight:700;color:#fff;font-size:.9rem;flex:none}
.quote .av p{margin:0;color:#fff;font-size:.9rem}
.quote .nm{font-family:var(--fh);font-weight:700;color:#fff;font-size:.86rem;line-height:1.2}.quote .nm span,.quote .nm .nm-loc{display:block;color:rgba(255,255,255,.55);font-weight:400;font-size:.76rem}
.quote .nm p{margin:0;font-family:var(--fh);font-weight:700;color:#fff;font-size:.86rem;line-height:1.2}
/* steps */
.steps{counter-reset:s}.step{position:relative}.step img{width:100%;border-radius:10px;aspect-ratio:1/1;object-fit:cover;margin-bottom:9px}
.step .wp-block-image{margin:0 0 9px;width:100%}.step .wp-block-image img{margin:0;border-radius:10px;aspect-ratio:1/1;object-fit:cover;width:100%}
/* Bug-fix #5: step #1 image sat at a different size/top because core/image emits the
   intrinsic width/height and `img{height:auto}` lets the natural ratio override the
   square. Force EVERY step image to an identical 1:1 box (object-fit:cover) and pin the
   figure block to a uniform top so all six images align across the row regardless of the
   source file's intrinsic dimensions. */
.steps .step .wp-block-image{display:block;line-height:0}
.steps .step .wp-block-image img{height:auto;aspect-ratio:1/1;width:100%;display:block;object-fit:cover;object-position:center}
.step b,.step p{font-family:var(--fh);color:var(--primary);font-size:.86rem;margin:0;line-height:1.3}
.step::before{counter-increment:s;content:counter(s);position:absolute;top:8px;left:8px;z-index:1;background:color-mix(in srgb,var(--cta) 62%,#000);color:#fff;width:26px;height:26px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-family:var(--fh);font-weight:700;font-size:.78rem}
/* video */
.video-wrap{display:grid;grid-template-columns:1.5fr 1fr;gap:24px;align-items:start}
.vmain{position:relative;border-radius:16px;overflow:hidden;background:#000;aspect-ratio:16/9}
.vmain video{width:100%;height:100%;object-fit:cover;display:block}
.vplay{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;cursor:pointer;background:rgba(20,21,46,.28);transition:.2s}
.vplay:hover{background:rgba(20,21,46,.12)}
.vplay span{width:74px;height:74px;border-radius:50%;background:color-mix(in srgb,var(--cta) 92%,#000);display:flex;align-items:center;justify-content:center;box-shadow:0 12px 30px -8px rgba(0,0,0,.5)}
.vlist{display:flex;flex-direction:column;gap:10px}
.vthumb{display:flex;gap:12px;align-items:center;background:var(--card);border:1px solid var(--line);border-radius:11px;padding:9px;cursor:pointer;transition:.2s}
.vthumb:hover{border-color:var(--cta)}.vthumb.on{border-color:var(--cta);box-shadow:inset 0 0 0 1px var(--cta)}
.vthumb img{width:84px;height:54px;border-radius:7px;object-fit:cover;flex:none}
.vthumb .wp-block-image{margin:0;flex:none}.vthumb .wp-block-image img{width:84px;height:54px;border-radius:7px;object-fit:cover;margin:0}
.vthumb b,.vthumb .vt-title{font-family:var(--fh);font-size:.85rem;font-weight:700;color:var(--primary);display:block;margin:0;line-height:1.25;letter-spacing:0}.vthumb span,.vthumb .vt-meta{font-size:.76rem;color:var(--muted);margin:0}
.vthumb .vt-text{display:block}
.vlist.wp-block-group{display:flex;flex-direction:column;gap:10px;margin:0}
.vthumb.wp-block-group{gap:12px;margin:0}
/* gallery */
.gallery{display:grid;grid-template-columns:repeat(4,1fr);gap:12px}
.gallery a{display:block;border-radius:12px;overflow:hidden;cursor:pointer;position:relative;aspect-ratio:4/3}
.gallery img{width:100%;height:100%;object-fit:cover;transition:transform .4s}
.gallery a:hover img{transform:scale(1.06)}
.gallery a::after{content:"";position:absolute;inset:0;background:linear-gradient(transparent 60%,color-mix(in srgb,var(--primary) 55%,transparent));opacity:0;transition:.2s}
.gallery a:hover::after{opacity:1}
.gtall{grid-row:span 2;aspect-ratio:auto}
.lightbox{position:fixed;inset:0;z-index:80;background:rgba(8,9,20,.9);display:none;align-items:center;justify-content:center;padding:30px}
.lightbox.open{display:flex}.lightbox img{max-width:92%;max-height:88%;border-radius:12px;box-shadow:0 30px 80px -20px #000}
.lightbox .x{position:absolute;top:22px;right:26px;color:#fff;font-size:2rem;cursor:pointer;font-family:var(--fh)}
/* cta band + footer */
.ctaband{background:linear-gradient(120deg,var(--band-bg),color-mix(in srgb,var(--cta) 55%,var(--band-bg)));color:#fff;text-align:center;border-radius:18px;padding:54px 24px;margin:0 28px}
.ctaband h2{color:#fff}.ctaband p{color:rgba(255,255,255,.8)}
footer{background:var(--footer-bg);color:var(--footer-text);font-size:.86rem;padding:40px 0;margin-top:36px}
footer .cols{display:grid;grid-template-columns:2fr 1fr 1fr 1fr;gap:24px}
footer b,footer strong{color:#fff;font-family:var(--fh)}footer a{color:var(--footer-text);display:block;margin:.3rem 0}
/* native footer: .cols/.foot-col are now core/group; titles/links are paragraphs+list.
   Strip core block-gap so the demo's tight column spacing is preserved. */
footer .cols.wp-block-group{display:grid;grid-template-columns:2fr 1fr 1fr 1fr 1.5fr;gap:24px;margin:0;align-items:start}
footer .foot-col.wp-block-group{display:block;margin:0}
footer .foot-col>*{margin-top:0;margin-bottom:0}
footer .foot-h,footer .foot-brand{margin:0}
footer .foot-h strong,footer .foot-brand strong{color:#fff;font-family:var(--fh)}
footer .foot-brand strong{font-size:1.05rem}
footer .foot-blurb{margin:.4rem 0 0;color:var(--footer-text)}
/* social icons (core/social-links, default/colored style) — brand-colored icons on the dark footer */
footer .foot-socials{margin:.8rem 0 0;gap:8px}
footer .foot-socials .wp-block-social-link{margin:0}
footer .foot-socials .wp-block-social-link:hover{transform:translateY(-1px)}
footer .foot-links{list-style:none;margin:0;padding:0}
footer .foot-links li{margin:0}
footer .foot-links a{color:var(--footer-text);display:block;margin:.3rem 0}
/* contact block (address / phone / email) in the brand column */
footer .foot-contact{margin:.7rem 0 0;color:var(--footer-text);line-height:1.55}
footer .foot-contact a{color:var(--footer-text);display:inline;margin:0}footer .foot-contact a:hover{color:#fff}
/* BBB A+ badge */
/* Follow Us + Hours column */
footer .foot-h--hours{margin-top:1.1rem}
footer .foot-hours{margin:.3rem 0 0;color:var(--footer-text);line-height:1.5}
/* Copyright line: centered + raised tight to the columns to compress the footer. */
footer .foot-legal.wp-block-group{margin-top:14px;padding-top:14px;border-top:1px solid var(--footer-line);text-align:center}
footer .foot-copy{font-size:.78rem;color:var(--footer-faint);margin:0;text-align:center}
@media(max-width:900px){.hero,.split,.aud-panel,.video-wrap{grid-template-columns:1fr}.g4,.gallery{grid-template-columns:repeat(2,1fr)}.g6{grid-template-columns:repeat(3,1fr)}.g3{grid-template-columns:1fr}.gtall{grid-row:auto}footer .cols.wp-block-group{grid-template-columns:1fr 1fr}}

/* ============================================================================
   MOBILE TIER — small phones (<=600px). Added by the responsive audit.
   The single max-width:900px tablet rule above collapses the major grids; this
   tier handles true phone widths (375/390/414): header reflow so the nav fits,
   reduced section/horizontal padding, single-column small grids, full-width
   stacked CTAs, >=44px tap targets, and 16px body to stop iOS focus-zoom.
   All values are token-driven (no hardcoded colors). ========================= */
@media(max-width:600px){
	/* --- horizontal page padding: 28px is tight at 375 (319px content). Drop to
	   18px each side -> 339px content at 375, more usable line length. --- */
	.w{padding:0 18px}
	.cc-w{padding-inline:18px}
	.sos-aud,.sos-vg{padding-inline:18px}

	/* --- section vertical rhythm: 62px top+bottom (124px) eats a 390px screen.
	   Clamp down to ~40px on phones. --- */
	section{padding:clamp(34px,9vw,46px) 0}
	.wp-block-group.sos-section{padding:0}

	/* --- HEADER: shrink + reflow so logo + toggle + CTA fit at 375px.
	   .navlinks already hide at <=900px; here we shrink the logo, tighten the
	   navright gap, and trim the CTA button so the cluster fits 339px. --- */
	.nav,.nav.wp-block-group{height:64px}
	.logo img,figure.wp-block-image.logo img{height:44px}
	.navright,.navright.wp-block-group{gap:8px}
	.nav-cta .wp-block-button.btn-p>.wp-block-button__link,
	.nav .btn.nav-cta-link{padding:.5rem .8rem;font-size:.86rem}
	.admin-bar header,.admin-bar header.wp-block-group{top:46px}

	/* --- TAP TARGETS >=44px (WCAG 2.5.5 / Apple HIG). --- */
	.modetoggle{width:44px;height:44px;min-width:44px;flex:0 0 auto}
	.aud-tab,.sos-aud__tab{padding:.7rem 1.1rem;min-height:44px}
	.vthumb,.vthumb.wp-block-group,.sos-vg__thumb{min-height:44px}
	/* native core gallery lightbox trigger: core renders a ~20px button. Enlarge
	   its hit area to 44px without changing the icon's visual size. */
	.wp-block-gallery.cc-gallery .lightbox-trigger,
	figure.wp-block-image .lightbox-trigger{min-width:44px;min-height:44px;display:flex;align-items:center;justify-content:center;padding:0}

	/* --- HERO CTAs: full-width stacked so both buttons match (one was hug, one
	   wider). Applies to native core/buttons .row in the hero only. --- */
	.hero .row.wp-block-buttons,.w.reveal .row.up.s3{flex-direction:column;align-items:stretch;width:100%}
	.hero .row.wp-block-buttons .wp-block-button,
	.w.reveal .row.up.s3 .wp-block-button{width:100%;flex:1 1 auto}
	.hero .row.wp-block-buttons .wp-block-button__link,
	.w.reveal .row.up.s3 .wp-block-button__link{width:100%}
	.hero .wp-block-buttons.row{margin-top:1.3rem}

	/* --- HERO: tighten padding + floatstat so the overlay card doesn't dominate
	   the smaller image. --- */
	.hero{padding:24px 0 40px;gap:28px}
	.floatstat{left:12px;right:12px;bottom:12px;padding:10px 6px}
	.floatstat b,.floatstat .fs-n{font-size:1.25rem}

	/* --- SMALL GRIDS that still show 2-3 cols at 900px: collapse for phones. --- */
	.g4,.gallery,.wp-block-gallery.cc-gallery,
	.grid.g4.wp-block-group{grid-template-columns:1fr}
	.g6,.grid.g6.wp-block-group{grid-template-columns:repeat(2,1fr)}
	/* footer was 1-col on phones = far too tall. Compact 2-col with the brand band
	   (name/blurb/socials/BBB) spanning the top, then Product|Audiences, Company|Contact. */
	footer{padding:30px 0;margin-top:24px}
	footer .cols.wp-block-group{grid-template-columns:1fr 1fr;gap:20px 16px}
	footer .foot-col--brand{grid-column:1 / -1}
	footer .foot-legal.wp-block-group{margin-top:14px;padding-top:14px}

	/* --- proof-band stats: flex row wraps to a cramped 2-up; center each. --- */
	.stats,.stats.wp-block-group{gap:24px}
	.stat .st-n,.stat b{font-size:2rem}

	/* --- audience/video/split inner padding trims --- */
	.aud-panel,.sos-aud__panel{padding:20px}

	/* --- body copy >=16px on phones to avoid iOS zoom-on-focus + readability.
	   Demo base is fine, but several .sub / small paragraphs dip below; floor
	   the hero subhead and section paragraphs. --- */
	body{font-size:16px}
	.hero .sub{font-size:1.05rem}

	/* --- council refinements (visual-designer + accessibility) --- */
	/* hero headline floor + leading so the long H1 isn't oversized/tight at 375px */
	.hero h1{font-size:clamp(1.85rem,7.5vw,2.1rem);line-height:1.14;margin:.3em 0 .45em}
	.center{margin-bottom:22px}
	/* trust dots top-align with the (now 2-line) text */
	.trust.wp-block-group{align-items:flex-start;gap:.5rem}
	.trust .dots.wp-block-group{margin-top:1px}.trust p{line-height:1.4}
	/* full-width stacked CTAs on the CTA band + institutional split too (not just hero) */
	.cta-row.wp-block-buttons,.split .row.wp-block-buttons{flex-direction:column;align-items:stretch;width:100%}
	.cta-row.wp-block-buttons .wp-block-button,.split .row.wp-block-buttons .wp-block-button{width:100%;flex:1 1 auto}
	.cta-row.wp-block-buttons .wp-block-button__link,.split .row.wp-block-buttons .wp-block-button__link{width:100%}
	/* proof band: de-emphasize the long patent CREDENTIAL string (not a metric like 100+/0) */
	.band .stats .stat:nth-child(2) .st-n{font-size:1.3rem;letter-spacing:0;word-break:normal}
	/* CTA band: trim heavy padding/side margin on phones */
	.ctaband{padding:38px 20px;margin:0 20px}
	/* footer link tap targets >=44px via padding (not margin) */
	footer .foot-links a,footer .foot-contact a{padding-block:.4rem;line-height:1.3}
	/* audience tabs: left-align the wrapped pills (tidy block; all 7 options stay visible) */
	.sos-aud__tabs{justify-content:flex-start}
}

/* ---- 4. WP-NATIVE BRIDGE: neutralize core block chrome so demo classes win ---- */
/* Core wraps our markup in .wp-block-group / .wp-block-columns etc. We let the demo
   layout classes (.hero/.split/.video-wrap/.gallery/.grid) own the grid, and strip
   the default block gap/padding WP would otherwise inject on those wrappers. */
.wp-block-group.sos-section{padding:0}
.cc-w{max-width:1320px;margin-inline:auto;padding-inline:28px}
/* Native core/buttons used for the demo's .row of .btn links. core/button puts a
   custom className ONLY on the wrapper .wp-block-button (never on the <a>), so we map
   the demo button look onto the inner .wp-block-button__link from the wrapper's
   .btn/.btn-p/.btn-g classes. These rules win over the theme.json button element
   styles (.wp-element-button) because concept-c.css loads after the global inline CSS.
   The buttons wrapper carries .row for the demo's flex spacing. */
.row.wp-block-buttons{display:flex;gap:10px;flex-wrap:wrap;margin:0;align-items:center}
/* Each button is content-width and sits inline (core can otherwise make a buttons
   block without is-layout-flex render its children full-width / stacked). */
.row.wp-block-buttons .wp-block-button{margin:0;width:auto;max-width:none;flex:0 0 auto;display:inline-block}
.row.wp-block-buttons .wp-block-button .wp-block-button__link{width:auto}
/* Neutralize the core/button WRAPPER: the .btn visual (padding/border/bg) belongs
   on the inner <a> only. Without this the wrapper ALSO gets .btn padding (line ~61),
   doubling each button's width so the hero CTAs wrap instead of sitting inline. */
.wp-block-button.btn{padding:0;border:0;background:none;box-shadow:none;border-radius:0;display:inline-block}
.wp-block-button.btn>.wp-block-button__link{display:inline-flex;align-items:center;justify-content:center;gap:.45rem;font-family:var(--fh);font-weight:600;font-size:1rem;padding:.85rem 1.6rem;border-radius:999px;border:1px solid transparent;cursor:pointer;transition:.2s;text-decoration:none;line-height:1.2}
.wp-block-button.btn-p>.wp-block-button__link{background:var(--cta);color:#fff;box-shadow:0 10px 26px -10px color-mix(in srgb,var(--cta) 60%,transparent)}
.wp-block-button.btn-p>.wp-block-button__link:hover{background:var(--ctad)}
.wp-block-button.btn-g>.wp-block-button__link{background:var(--card);color:var(--primary);border:1px solid color-mix(in srgb,var(--text) 24%,transparent);box-shadow:0 1px 4px rgba(15,23,42,.08)}
.wp-block-button.btn-g>.wp-block-button__link:hover{border-color:var(--cta);color:var(--cta);box-shadow:inset 0 0 0 1px var(--cta),0 1px 4px rgba(15,23,42,.08)}
/* Bug-fix #2: the hero ghost CTA ("See how it works") rendered DOUBLE-ringed. Core's
   global button styles (theme.json elements.button + .wp-element-button defaults) give
   the link its OWN border/box-shadow ring in addition to our .btn-g 1px border, so two
   rings stack. Pin the ghost link to a single clean 1px border at rest by neutralizing
   the inherited ring (the .wp-element-button class is the global-styles target). The
   visible focus ring is preserved via :focus-visible below for accessibility. */
.wp-block-button.btn-g>.wp-block-button__link.wp-element-button{border:1px solid color-mix(in srgb,var(--text) 24%,transparent);box-shadow:0 1px 4px rgba(15,23,42,.08);outline:none}
.wp-block-button.btn-g>.wp-block-button__link.wp-element-button:focus-visible{outline:2px solid var(--cta);outline-offset:2px}
/* CTA-band ghost variant: white outline on the gradient (was an inline style in demo).
   Full `border` shorthand (not just border-color) so the ~1px rgba(255,255,255,.4)
   outline is guaranteed visible regardless of the .btn-g base border. */
.ctaband .wp-block-button.btn-ghost>.wp-block-button__link{background:transparent;color:#fff;border:1px solid rgba(255,255,255,.4)}
.ctaband .wp-block-button.btn-ghost>.wp-block-button__link:hover{background:rgba(255,255,255,.08);border-color:rgba(255,255,255,.7);color:#fff;box-shadow:none}
.cta-row.wp-block-buttons{justify-content:center;margin-top:1.2rem}
/* core/group used for floatstat cells / quote .av / .nm / .who / vthumb text: strip
   the inherited block-gap margins so spacing matches the demo's bare <div> nesting. */
.floatstat .fs-cell>*,.vthumb .vt-text>*,.quote .av>*,.quote .nm>*{margin-top:0;margin-bottom:0}
/* core/quote uses flex-column with its own gap:12px (set above); strip the block-gap
   margins core injects between the testimonial <p> and the .who row so spacing is exact. */
.quote.wp-block-quote>*{margin-top:0;margin-bottom:0}
.quote .who.wp-block-group{gap:10px;margin:0}
.stats.wp-block-group{display:flex;gap:40px;justify-content:center;flex-wrap:wrap;margin-bottom:30px}
/* Grid items STRETCH to equal height (default) so testimonial .quote cards are the
   same size with attribution pinned to the bottom (.band .quote justify-content
   below), and worry .card heights match. Top-alignment of the first item is handled
   by zeroing the WP block-gap margins on the row (next rule), NOT by align-items. */
.grid.wp-block-group{display:grid;gap:16px;margin:0}.grid.g3.wp-block-group{grid-template-columns:repeat(3,1fr)}.grid.g6.wp-block-group{grid-template-columns:repeat(6,1fr)}.grid.g4.wp-block-group{grid-template-columns:repeat(4,1fr)}
/* WP injects block-gap margin-block-start on grid items 2..n; in a grid that drops
   them one gap below item 1, so the FIRST card floats ~20px high. Zero it so every
   card in the row tops-align (same fix family as .trust/.stats/.steps). */
.grid.wp-block-group>*{margin-block-start:0;margin-block-end:0}
.step.wp-block-group>p,.step.wp-block-group>.wp-block-heading{margin-top:0;margin-bottom:0}
/* Bug-fix: WP flow layout injects margin-block-start on every row item except the
   first (.steps grid + .stats flex). That drops items 2..n by one block-gap and
   leaves item #1 floating ~20px higher than its row-mates. Zero the cross-row
   margins and top-align so all step images / all stat labels line up. */
.steps.wp-block-group{align-items:start}
.steps.wp-block-group>.step{margin-block-start:0;margin-block-end:0}
.stats.wp-block-group{align-items:flex-start}
.stats.wp-block-group>.stat{margin-block-start:0;margin-block-end:0}
@media(max-width:900px){.grid.g3.wp-block-group{grid-template-columns:1fr}.grid.g6.wp-block-group{grid-template-columns:repeat(3,1fr)}.grid.g4.wp-block-group{grid-template-columns:repeat(2,1fr)}}
/* ---- PROJECT GALLERY: demo masonry on a core/gallery ----
   The core gallery (figure.wp-block-gallery.has-nested-images.is-cropped) defaults to a
   FLEX layout that shrinks each .wp-block-image to a tiny flex-basis (the "61px scattered"
   bug). We override it to the demo's 4-col CSS grid with a tall first tile.

   SCOPING APPROACH (front end correct + editor normal):
   - FRONT END: plain, unscoped `.wp-block-gallery.cc-gallery` rules below own the layout.
     They use `display:grid` and override core's flex on the real core DOM
     (figure.wp-block-image > img). The selectors are specific enough (and use the
     gallery's own `.cc-gallery` class) to beat core's gallery flex rules; a few core
     properties (flex-basis/width on the nested images) are reset with !important because
     core sets them with comparable specificity.
   - EDITOR: the block-editor iframe <body> carries `.editor-styles-wrapper`, AND core
     prefixes ALL editor styles with `.editor-styles-wrapper`. We add an explicit
     `.editor-styles-wrapper .cc-gallery` reset that RE-NEUTRALIZES the grid back to core's
     normal flow, so the marketer sees a standard, undistorted gallery while editing.
   This is the reverse of the previous (broken) approach: front end uses the plain rule
   (always matches live), editor uses the higher-specificity `.editor-styles-wrapper` reset. */

/* FRONT END (and default): demo masonry grid */
.wp-block-gallery.cc-gallery{display:grid;grid-template-columns:repeat(4,1fr);gap:12px;margin:0}
.wp-block-gallery.cc-gallery .wp-block-image{margin:0;border-radius:12px;overflow:hidden;aspect-ratio:4/3;position:relative;width:auto!important;flex:initial!important;max-width:none}
.wp-block-gallery.cc-gallery .wp-block-image>a,.wp-block-gallery.cc-gallery .wp-block-image>figure{width:100%;height:100%;margin:0;display:block}
.wp-block-gallery.cc-gallery .wp-block-image img{width:100%;height:100%;object-fit:cover;transition:transform .4s;display:block;border-radius:0}
.wp-block-gallery.cc-gallery .wp-block-image:hover img{transform:scale(1.06)}
.wp-block-gallery.cc-gallery .wp-block-image:first-child{grid-row:auto;aspect-ratio:4/3}
.wp-block-gallery.cc-gallery .wp-block-image::after{content:"";position:absolute;inset:0;background:linear-gradient(transparent 60%,color-mix(in srgb,var(--primary) 55%,transparent));opacity:0;transition:.2s;pointer-events:none;z-index:1}
.wp-block-gallery.cc-gallery .wp-block-image:hover::after{opacity:1}
@media(max-width:900px){.wp-block-gallery.cc-gallery{grid-template-columns:repeat(2,1fr)}.wp-block-gallery.cc-gallery .wp-block-image:first-child{grid-row:auto;aspect-ratio:4/3}}

/* EDITOR ONLY: neutralize the masonry so the editing canvas shows a normal core gallery.
   Higher specificity (.editor-styles-wrapper prefix) wins over the front-end rules above,
   which core also prefixes — so inside the iframe this reset takes precedence. */
.editor-styles-wrapper .wp-block-gallery.cc-gallery{display:flex}
.editor-styles-wrapper .wp-block-gallery.cc-gallery .wp-block-image{aspect-ratio:auto;position:static;grid-row:auto;width:auto!important;flex:1 1 0%!important}
.editor-styles-wrapper .wp-block-gallery.cc-gallery .wp-block-image:first-child{grid-row:auto}
.editor-styles-wrapper .wp-block-gallery.cc-gallery .wp-block-image img{height:auto}
.editor-styles-wrapper .wp-block-gallery.cc-gallery .wp-block-image::after{content:none}

/* ============================================================================
   5. HOMEOWNERS-PAGE COMPONENTS — styled FAQ accordion + process list.
   Added for the Homeowners redesign. Both are token-driven (no hardcoded brand
   colors) so they track the palette picker and dark mode like the rest of the
   demo CSS. The .faq wraps core/details blocks; the .proc wraps core/group rows.
   ========================================================================== */

/* ---- FAQ accordion (core/details) ---- */
.faq{max-width:760px;margin-inline:auto}
.faq .wp-block-details{background:var(--card);border:1px solid var(--line);border-radius:12px;margin:0 0 12px;overflow:hidden}
.faq summary{cursor:pointer;list-style:none;padding:16px 20px;font-family:var(--fh);font-weight:600;font-size:1rem;color:var(--primary);display:flex;justify-content:space-between;align-items:center;gap:12px;min-height:44px;box-sizing:border-box}
.faq summary::-webkit-details-marker{display:none}
.faq summary::after{content:"+";font-size:1.3rem;color:var(--cta);line-height:1;transition:transform .2s}
.faq .wp-block-details[open] summary::after{content:"–"}
.faq .wp-block-details[open] summary{border-bottom:1px solid var(--line)}
.faq .wp-block-details p{margin:0;padding:16px 20px 18px;color:var(--muted);font-size:.92rem;line-height:1.6}
/* FN-1: visible keyboard focus on the accordion summary (was relying on UA default). */
.faq summary:focus-visible{outline:2px solid var(--cta);outline-offset:-3px;border-radius:12px}

/* ---- Process list (.proc / .proc-step / .proc-num) ----
   Each .proc-step is a 2-column grid: number badge gutter + text column. It MUST
   stay 2-column on mobile (the badge gutter + text), so no single-column collapse
   in the media query. The summary's 44px min-height handles FAQ tap targets. */
.proc,.proc.wp-block-group{display:grid;gap:14px;max-width:760px;margin-inline:auto}
.proc-step{display:grid;grid-template-columns:auto 1fr;gap:16px;align-items:center;background:var(--card);border:1px solid var(--line);border-radius:12px;padding:18px}
/* (0,2,0) so color:#fff beats global-styles core/paragraph color (which otherwise
   renders the number muted-gray). Badge bg is the CTA DEEPENED toward black so white
   text clears AA on every palette — raw white-on-cta fails for the warm/amber CTAs. */
.proc .proc-num{width:32px;height:32px;border-radius:50%;background:color-mix(in srgb,var(--cta) 62%,#000);color:#fff;font-family:var(--fh);font-weight:700;display:flex;align-items:center;justify-content:center;flex:none;margin:0}
.proc-step h3{margin:0 0 .15rem;font-size:1rem}
.proc-step p{margin:0;color:var(--muted);font-size:.9rem;line-height:1.5}
/* Bridge: .proc and .proc-step are core/group (default/flow layout). WP injects
   block-gap margins between flow children, which would offset the badge + text
   column and the rows. Keep the grids and zero the cross-item margins so the
   badge gutter stays aligned with the text on every step (incl. mobile — the
   2-column grid is intentionally NOT collapsed in the media query). */
.proc.wp-block-group>.proc-step{margin-block:0}
.proc-step.wp-block-group{display:grid;grid-template-columns:auto 1fr;gap:16px;align-items:center;margin:0}
.proc-step.wp-block-group>*{margin-block:0}
.proc-step .wp-block-group>*{margin-block:0}

/* ---- Testimonial equal-height: push the .who row to the card bottom so the
   3 quote cards line up regardless of quote length. ---- */
.band .quote.wp-block-quote{justify-content:space-between}

/* ---- Hero reassurance microcopy under the CTAs ---- */
.hero-note{font-size:.85rem;color:var(--muted);margin:.6rem 0 0}

/* ---- Worry-card icon spacing (the .ico base style already sizes the glyph) ---- */
.card .ico{margin-bottom:.5rem}
/* Equal-height worry cards so the 4-up row bottom-aligns regardless of copy length. */
.grid .card{height:100%}

/* ---- Verification-council fixes (homeowners redesign) ---- */
/* Single-stat floatstat variant (the 2nd "0 tiles removed" cell was an unverified
   claim and was removed): center one stat instead of leaving an empty 3rd column. */
.floatstat.fs-1{grid-template-columns:1fr;left:50%;right:auto;transform:translateX(-50%);width:max-content;max-width:calc(100% - 40px);padding:12px 26px}
/* FN-2: visible keyboard focus on the primary CTA buttons + in-content links
   (only the ghost button had one). Indigo ring offset onto the page so it shows
   against the button fill. */
.wp-block-button.btn-p>.wp-block-button__link:focus-visible{outline:2px solid var(--cta);outline-offset:3px}
main a:focus-visible{outline:2px solid var(--cta);outline-offset:2px;border-radius:3px}
/* FN-3: the native gallery "Enlarge" trigger must be >=24px (WCAG 2.5.8) at ALL
   widths, not only <=600px. Apply the 44px hit area globally. */
.wp-block-gallery.cc-gallery .lightbox-trigger,figure.wp-block-image .lightbox-trigger{min-width:44px;min-height:44px;display:flex;align-items:center;justify-content:center;padding:0}
/* Visual nit: lift the CTA-band proof line for AA on the lighter end of the gradient. */
.ctaband .cta-proof{color:rgba(255,255,255,.9)}
/* CTA-band secondary "Prefer to talk? Call …" line — white link, AA on the dark gradient. */
.ctaband .cta-alt{margin-top:14px;font-size:.95rem;color:rgba(255,255,255,.85)}
.ctaband .cta-alt a{color:#fff;text-decoration:underline;text-underline-offset:2px}
.ctaband .cta-alt a:hover{color:#fff;opacity:.85}
/* Reassurance band lead — was 16px muted (too small for the band's space). Make it a
   real statement: heading font, larger, full white. (.lead is unique to this line, so
   the testimonial band's text is untouched.) Specificity (0,3,0) beats .band .center p. */
.band .center .lead{font-family:var(--fh);font-size:clamp(1.3rem,2.8vw,1.7rem);color:#fff;font-weight:600;line-height:1.4;max-width:820px;margin:0 auto}

/* ---- DARK-MODE focus + hover contrast (systemic a11y fix) ----
   --cta (indigo) is intentionally kept from the light palette in dark mode, which is
   fine as a BUTTON BACKGROUND (white text on it passes) but fails as TEXT or a FOCUS
   OUTLINE on dark surfaces (~1.8:1). In dark mode: every focus ring goes white
   (>=14:1 on any dark surface), and hover/focus TEXT that would turn --cta goes white
   instead. !important guarantees it beats the higher-specificity light focus rules. */
html[data-theme="dark"] :focus-visible{outline-color:#fff !important}
/* Dark-mode hover. The original rule listed six selectors for the retired
   hand-built nav; when those classes were removed the list lost its declaration
   block and silently attached itself to the NEXT rule. Restated against
   core/navigation's markup, which is the only nav now. */
html[data-theme="dark"] .navlinks .wp-block-navigation-item__content.wp-block-navigation-item__content:hover,
html[data-theme="dark"] .navlinks .wp-block-navigation-item__content.wp-block-navigation-item__content:focus-visible{
	color:#fff;
}
/* Mid-page CTA after a card grid was crowding the cards — give it breathing room so
   the helper line reads as belonging to the CTA, not the row above. */
.grid.g4.wp-block-group + .center{margin-top:40px}

/* ===================== Contact form (Gravity Forms) — Concept C =====================
   Tokens (--card/--line/--primary/--muted) re-point in dark mode, so these rules work
   in both themes. !important is used where Gravity Forms' own theme CSS is stubborn. */
.contactwrap{margin-inline:auto}
.contactwrap .gform_wrapper{max-width:560px;margin:26px auto 0}
.contactwrap .gform_heading{display:none}

/* Drive Gravity Forms' Orbital theme from our tokens so it inherits dark mode.
   GF declares these on .gform-theme--framework; we match that class + .gform_wrapper
   (specificity 0,2,0) so our dark-aware tokens win regardless of stylesheet load order. */
.gform_wrapper.gform-theme--framework{
	--gf-ctrl-bg-color:var(--card);
	--gf-ctrl-color:var(--primary);
	--gf-ctrl-border-color:var(--line);
	--gf-ctrl-border-color-hover:color-mix(in srgb,var(--cta) 45%,var(--line));
	--gf-ctrl-border-color-focus:var(--cta);
	--gf-ctrl-radius:12px;
	--gf-ctrl-desc-color:var(--muted);
	--gf-ctrl-placeholder-color:var(--muted);
	--gf-color-primary:var(--cta);
	--gf-ctrl-label-color-primary:var(--primary);
	--gf-ctrl-label-color-secondary:var(--secondary);
}

.gform_wrapper .gform_fields{gap:12px}
.gform_wrapper .gfield_label{font-family:var(--fh);font-weight:600;font-size:.9rem;color:var(--primary);margin-bottom:6px}
.gform_wrapper .gfield_required{color:var(--cta);margin-left:2px}
.gform_wrapper .gfield_description{color:var(--muted);font-size:.82rem;margin-top:.35rem;padding:0}

/* Inputs — rounded, full-width, themed (fixes the stunted email + dark-mode invisibility) */
.gform_wrapper .ginput_container input[type=text],
.gform_wrapper .ginput_container input[type=email],
.gform_wrapper .ginput_container input[type=tel],
.gform_wrapper .ginput_container input[type=url],
.gform_wrapper .ginput_container input[type=number],
.gform_wrapper .ginput_container select,
.gform_wrapper .ginput_container textarea{
	width:100%;box-sizing:border-box;
	font-family:var(--fb);font-size:1rem;color:var(--primary)!important;
	background:var(--card)!important;
	border:1px solid var(--line)!important;border-radius:12px!important;
	padding:.72rem .9rem;line-height:1.4;
	transition:border-color .15s,box-shadow .15s;
}
.gform_wrapper .ginput_container textarea{min-height:120px;resize:vertical}
.gform_wrapper .ginput_container input:focus,
.gform_wrapper .ginput_container select:focus,
.gform_wrapper .ginput_container textarea:focus{
	outline:none;border-color:var(--cta)!important;
	box-shadow:0 0 0 3px color-mix(in srgb,var(--cta) 18%,transparent);
}
.gform_wrapper .ginput_container ::placeholder{color:color-mix(in srgb,var(--muted) 55%,var(--card))!important;opacity:1}

/* Radio */
.gform_wrapper .gfield_radio .gchoice{margin:.15rem 0;display:flex;align-items:center;gap:.5rem}
.gform_wrapper .gfield_radio label{font-weight:500;color:var(--secondary);margin:0}

/* Section header */
.gform_wrapper .gsection{border-bottom:1px solid var(--line);margin:.3rem 0 0;padding-bottom:.35rem}
.gform_wrapper .gsection_title{font-family:var(--fh);font-size:1.02rem;color:var(--primary)}

/* Address: street + apt line full width; city/state/zip/country two-up */
.gform_wrapper .ginput_complex.ginput_container_address{display:grid;grid-template-columns:1fr 1fr;gap:14px}
.gform_wrapper .ginput_complex.ginput_container_address > span{display:block;margin:0}
.gform_wrapper .ginput_complex.ginput_container_address .address_line_1,
.gform_wrapper .ginput_complex.ginput_container_address .address_line_2{grid-column:1 / -1}
.gform_wrapper .ginput_complex.ginput_container_address label{display:block;font-size:.76rem;color:var(--muted);font-weight:500;margin:.3rem 0 0}

/* Submit button — Concept C pill */
.gform_wrapper .gform_footer{margin-top:1.4rem;padding:0}
.gform_wrapper .gform_footer input[type=submit],
.gform_wrapper .gform_footer button[type=submit]{
	font-family:var(--fh);font-weight:600;font-size:1rem;color:#fff!important;cursor:pointer;
	background:var(--cta)!important;border:0!important;border-radius:999px!important;
	padding:.85rem 1.9rem;transition:filter .15s,transform .15s;
}
.gform_wrapper .gform_footer input[type=submit]:hover{filter:brightness(1.08);transform:translateY(-1px)}

/* Validation */
.gform_wrapper .gfield_error input,
.gform_wrapper .gfield_error textarea,
.gform_wrapper .gfield_error select,
.gform_wrapper .gfield_error .ginput_container_consent,
.gform_wrapper .gfield_error .iti{border-color:#dc2626!important;box-shadow:0 0 0 3px rgba(220,38,38,.18)!important;border-radius:12px}
.gform_wrapper .gfield_error .gfield_label,
.gform_wrapper .gfield_error legend.gfield_label{color:#dc2626!important}
.gform_wrapper .gfield_validation_message,
.gform_wrapper .validation_message{color:#dc2626;font-size:.82rem;margin-top:.3rem;background:none;border:0;padding:.2rem 0}

/* intl-tel-input v29 country dropdown — force a floating, scrollable, themed popup.
   v29 ships its positioning as NESTED CSS that did not take effect inside the GF form,
   so the whole 244-country list spilled down the page (overflow:visible, not absolute).
   Markup: .iti__country-container > .iti__country-selector (popup) >
   .iti__search-input + .iti__country-list. */
/* .iti MUST be the positioned ancestor or the popup anchors to a tall parent and
   lands at the bottom of the page. Force it (v29's input-container is position:static). */
.gform_wrapper .iti{width:100%;position:relative!important}
.iti__country-selector{
	position:absolute!important;top:100%!important;left:0!important;z-index:1000!important;
	width:320px;max-width:88vw;margin-top:4px;
	background:var(--card)!important;
	border:1px solid var(--line)!important;border-radius:12px!important;
	box-shadow:0 20px 48px rgba(15,23,42,.28)!important;overflow:hidden!important;
}
.iti__country-selector.iti__hide{display:none!important}
.iti__country-list{
	max-height:240px!important;overflow-y:auto!important;position:static!important;
	background:var(--card)!important;margin:0;padding:4px;list-style:none;
}
.iti__search-input{width:100%;box-sizing:border-box;background:var(--card)!important;color:var(--primary)!important;border:0;border-bottom:1px solid var(--line)!important;padding:.6rem .75rem}
/* Dropdown list items: name + dial code, padded, with hover. (Flag sprite isn't
   loading in this context, so flags are hidden for a clean text list — see below.) */
.iti__search-input-wrapper{padding:6px 6px 2px}
.iti__country{display:flex!important;align-items:center;gap:.55rem;padding:.5rem .7rem!important;margin:1px 3px;color:var(--primary)!important;border-radius:8px;cursor:pointer}
.iti__country .iti__country-name{flex:1 1 auto}
.iti__country .iti__dial-code{color:var(--muted)!important;flex:0 0 auto}
.iti__country:hover,.iti__country.iti__highlight{background:color-mix(in srgb,var(--cta) 12%,transparent)!important}
.iti__flag{display:none!important}            /* sprite doesn't load here — hide for a clean list */
.iti__no-results{display:none!important}      /* v29's empty-state toggle is unreliable here */
/* The "244 results found" live text is screen-reader-only; force it hidden. */
.iti__a11y-text{position:absolute!important;width:1px!important;height:1px!important;padding:0!important;margin:-1px!important;overflow:hidden!important;clip:rect(0 0 0 0)!important;white-space:nowrap!important;border:0!important}

/* ----- Phone: ONE inline rounded field (dial code left, number right). GF Orbital
   was painting the .iti__selected-country BUTTON blue, and .iti was display:block so
   the +1 stacked ABOVE the input. Rebuild .iti as a flex field. ----- */
:is(#gform_wrapper_1,#gform_wrapper_2,#gform_wrapper_3) .ginput_container_phone .iti{
	display:flex!important;align-items:stretch;width:100%;position:relative!important;
	background:var(--card)!important;border:1px solid var(--line)!important;border-radius:12px!important;
	transition:border-color .15s,box-shadow .15s;
}
:is(#gform_wrapper_1,#gform_wrapper_2,#gform_wrapper_3) .ginput_container_phone .iti:focus-within{border-color:var(--cta)!important;box-shadow:0 0 0 3px color-mix(in srgb,var(--cta) 18%,transparent)}
:is(#gform_wrapper_1,#gform_wrapper_2,#gform_wrapper_3) .iti__country-container{position:relative!important;display:flex;align-items:stretch} /* relative anchors the .sos-iti-select overlay; was static for the old custom popup, which is now disabled */
:is(#gform_wrapper_1,#gform_wrapper_2,#gform_wrapper_3) .iti__selected-country{background:transparent!important;color:var(--primary)!important;border:0!important;border-right:1px solid var(--line)!important;border-radius:0!important;box-shadow:none!important;padding:0 .55rem 0 .85rem!important;display:flex;align-items:center;gap:.4rem;font:inherit;cursor:pointer}
:is(#gform_wrapper_1,#gform_wrapper_2,#gform_wrapper_3) .iti__selected-dial-code{color:var(--primary)!important}
:is(#gform_wrapper_1,#gform_wrapper_2,#gform_wrapper_3) .iti__arrow{border-top-color:var(--muted)!important;opacity:.85}
:is(#gform_wrapper_1,#gform_wrapper_2,#gform_wrapper_3) .ginput_container_phone .iti__tel-input{
	border:0!important;background:transparent!important;border-radius:0!important;box-shadow:none!important;
	flex:1 1 auto;min-width:0;width:auto;padding:.72rem .9rem .72rem .65rem!important;
}

/* Radio: clear gap between the control and its label text. */
:is(#gform_wrapper_1,#gform_wrapper_2,#gform_wrapper_3) .gfield_radio .gchoice{display:flex;align-items:center;gap:.65rem}
:is(#gform_wrapper_1,#gform_wrapper_2,#gform_wrapper_3) .gfield_radio .gchoice input[type="radio"]{margin:0;flex:0 0 auto}
:is(#gform_wrapper_1,#gform_wrapper_2,#gform_wrapper_3) .gfield_radio .gchoice label{margin:0}

/* Address: city/state/zip/country in clean 2-up rows (like Name first/last), full width. */
:is(#gform_wrapper_1,#gform_wrapper_2,#gform_wrapper_3) .ginput_container_address{display:grid!important;grid-template-columns:1fr 1fr;gap:14px}
:is(#gform_wrapper_1,#gform_wrapper_2,#gform_wrapper_3) .ginput_container_address > span{display:block!important;width:auto!important;margin:0!important;float:none!important;padding:0!important}
:is(#gform_wrapper_1,#gform_wrapper_2,#gform_wrapper_3) .ginput_container_address .address_line_1,
:is(#gform_wrapper_1,#gform_wrapper_2,#gform_wrapper_3) .ginput_container_address .address_line_2{grid-column:1 / -1}

/* Light/dark contrast: give the form its own slightly-offset surface so the white
   fields and radios stand apart from the page background. color-mix with --primary
   darkens in light mode and lightens in dark mode automatically. */
.contactwrap .gform_wrapper{
	background:color-mix(in srgb,var(--bg) 88%,var(--primary));
	border:1px solid var(--line);
	border-radius:18px;
	padding:24px 24px 26px;
}

/* GF Orbital hardcodes label + input border colors with high-specificity rules that
   ignore the --gf-* vars, so they leaked the light theme into dark mode. Out-specify
   them: the #gform_wrapper_* id guarantees the win; the deep class chain covers any
   other GF form on the site. Values are our dark-aware tokens. */
:is(#gform_wrapper_1,#gform_wrapper_2,#gform_wrapper_3) .gfield_label,
:is(#gform_wrapper_1,#gform_wrapper_2,#gform_wrapper_3) .gsection_title,
.gform_wrapper.gform-theme--framework .gform_fields .gfield .gfield_label{color:var(--primary)!important}
:is(#gform_wrapper_1,#gform_wrapper_2,#gform_wrapper_3) .gfield_description,
:is(#gform_wrapper_1,#gform_wrapper_2,#gform_wrapper_3) .ginput_complex label{color:var(--muted)!important}
:is(#gform_wrapper_1,#gform_wrapper_2,#gform_wrapper_3) .ginput_container input,
:is(#gform_wrapper_1,#gform_wrapper_2,#gform_wrapper_3) .ginput_container select,
:is(#gform_wrapper_1,#gform_wrapper_2,#gform_wrapper_3) .ginput_container textarea,
.gform_wrapper.gform-theme--framework .gform_fields .gfield .ginput_container input,
.gform_wrapper.gform-theme--framework .gform_fields .gfield .ginput_container select,
.gform_wrapper.gform-theme--framework .gform_fields .gfield .ginput_container textarea{
	background-color:var(--card)!important;
	color:var(--primary)!important;
	border-color:var(--line)!important;
	border-radius:12px!important;
}
:is(#gform_wrapper_1,#gform_wrapper_2,#gform_wrapper_3) .ginput_container input:focus,
:is(#gform_wrapper_1,#gform_wrapper_2,#gform_wrapper_3) .ginput_container select:focus,
:is(#gform_wrapper_1,#gform_wrapper_2,#gform_wrapper_3) .ginput_container textarea:focus{border-color:var(--cta)!important}

/* ----- Contact form, feedback round 3 ----- */
/* Footer-flash fix: GF renders :is(#gform_wrapper_1,#gform_wrapper_2,#gform_wrapper_3) with inline display:none and reveals it
   via JS, collapsing the page so the footer briefly flashes mid-viewport. Force it visible
   (our CSS is render-blocking, so the form is already styled on first paint). */
:is(#gform_wrapper_1,#gform_wrapper_2,#gform_wrapper_3){display:block!important}

/* Reduce vertical spacing between fields (GF's own gap var beats the base rule). */
:is(#gform_wrapper_1,#gform_wrapper_2,#gform_wrapper_3) .gform_fields{row-gap:14px!important}
:is(#gform_wrapper_1,#gform_wrapper_2,#gform_wrapper_3) .gfield{margin-top:0!important;margin-bottom:0!important}

/* Uniform 44px field box with vertically-centered text, so every text input AND the
   country <select> align pixel-for-pixel (same height/padding/line-height). The select
   was centering its text natively (and clipping); appearance:none makes it position text
   exactly like a text input, with a custom chevron added back. */
:is(#gform_wrapper_1,#gform_wrapper_2,#gform_wrapper_3) .ginput_container input[type=text],
:is(#gform_wrapper_1,#gform_wrapper_2,#gform_wrapper_3) .ginput_container input[type=email],
:is(#gform_wrapper_1,#gform_wrapper_2,#gform_wrapper_3) .ginput_container input[type=tel],
:is(#gform_wrapper_1,#gform_wrapper_2,#gform_wrapper_3) .ginput_container input[type=url],
:is(#gform_wrapper_1,#gform_wrapper_2,#gform_wrapper_3) .ginput_container input[type=number],
:is(#gform_wrapper_1,#gform_wrapper_2,#gform_wrapper_3) .ginput_container select{
	height:44px!important;line-height:42px!important;padding:0 .9rem!important;font-size:1rem!important;box-sizing:border-box!important;
}
:is(#gform_wrapper_1,#gform_wrapper_2,#gform_wrapper_3) .ginput_container select{
	-webkit-appearance:none;-moz-appearance:none;appearance:none;
	padding-right:2.2rem!important;
	background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%239b9dc8' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
	background-repeat:no-repeat;background-position:right .9rem center;
}
/* Phone field matches the 44px box; the inner input fills it. */
:is(#gform_wrapper_1,#gform_wrapper_2,#gform_wrapper_3) .ginput_container_phone .iti{height:44px!important;box-sizing:border-box}
:is(#gform_wrapper_1,#gform_wrapper_2,#gform_wrapper_3) .ginput_container_phone .iti__tel-input{height:100%!important;line-height:42px!important;padding:0 .9rem 0 .65rem!important}
/* Phone-dropdown country names: truncate long ones cleanly instead of clipping. */
.iti__country .iti__country-name{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}

/* Footer social icons → circles. The brand color is on the <li>, which the flex row was
   stretching to 36w x 46h (vertical ellipse). Force an explicit 40x40 square (explicit
   height beats align-items:stretch) → a true circle. */
footer .foot-socials .wp-block-social-link{width:40px!important;height:40px!important;flex:0 0 40px!important;display:flex!important;align-items:center;justify-content:center;line-height:0!important;padding:0!important;border-radius:50%!important}
footer .foot-socials .wp-block-social-link > a{width:100%;height:100%;display:flex;align-items:center;justify-content:center;border-radius:50%;padding:0!important}


/* ============================================================
   SW: WARRANTY REGISTRATION + WARRANTY DOCUMENT PAGES (2026-07-10)
   Part 1: the contact form's :is(#gform_wrapper_1,#gform_wrapper_2,#gform_wrapper_3)-specific fixes, cloned for the two
   warranty-registration forms (wrappers 2 & 3) so all three forms share one look.
   Generated from the form-1 rules — keep in sync if those change.
   ============================================================ */

/* Part 1 (form-1 rule clones) REMOVED — the original form-1 rules below were refactored
   to :is(:is(#gform_wrapper_1,#gform_wrapper_2,#gform_wrapper_3),#gform_wrapper_2,#gform_wrapper_3) so all three forms share ONE
   copy of every rule (council round-1 fix: the generated clones had corrupted comments). */

/* Part 2: registration-page selector cards (real radios styled as cards). */
.sw-selector{border:0;margin:1.4rem 0;padding:0;display:grid;grid-template-columns:1fr 1fr;gap:14px}
@media (max-width:640px){.sw-selector{grid-template-columns:1fr}}
.sw-selector-legend{font-family:var(--fh);font-weight:600;font-size:1.05rem;color:var(--primary);margin-bottom:.6rem}
.sw-card{display:block;position:relative;background:var(--card);border:2px solid var(--line);border-radius:14px;padding:1rem 1.1rem;cursor:pointer;transition:border-color .15s,box-shadow .15s}
.sw-card:hover{border-color:color-mix(in srgb,var(--cta) 45%,var(--line))}
.sw-card input[type=radio]{position:absolute;opacity:0;pointer-events:none}
.sw-card:focus-within{outline:none;border-color:var(--cta);box-shadow:0 0 0 3px color-mix(in srgb,var(--cta) 20%,transparent)}
.sw-card.is-selected{border-color:var(--cta);box-shadow:0 0 0 3px color-mix(in srgb,var(--cta) 16%,transparent)}
.sw-card-title{display:block;font-family:var(--fh);font-weight:600;color:var(--primary);margin-bottom:.25rem}
.sw-card-sub{display:block;font-size:.86rem;color:var(--muted);line-height:1.45}
.sw-form[hidden]{display:none}
.sw-memory-note{background:color-mix(in srgb,var(--cta) 8%,var(--card));border:1px solid color-mix(in srgb,var(--cta) 30%,var(--line));border-radius:10px;padding:.6rem .9rem;font-size:.86rem;color:var(--secondary)}
.sw-finelinks{font-size:.82rem;color:var(--muted);margin-top:1.2rem}
.swreg .gform_wrapper{background:color-mix(in srgb,var(--bg) 88%,var(--primary));border:1px solid var(--line);border-radius:18px;padding:24px 24px 26px;margin-top:14px}
.sw-again-btn{display:inline-block;background:var(--cta);color:#fff!important;border-radius:999px;padding:.7rem 1.5rem;font-family:var(--fh);font-weight:600;text-decoration:none;margin-top:.4rem}
.sw-legal-slot{background:color-mix(in srgb,var(--cta) 7%,var(--card));border-left:3px solid var(--cta);border-radius:8px;padding:.75rem 1rem;font-size:.9rem}

/* Part 3: /warranty/ document styles — legal readability + audience badges. */
.sw-wrap .sw-intro{font-size:1.05rem;color:var(--secondary)}
.sw-cta-card{background:color-mix(in srgb,var(--cta) 8%,var(--card));border:1px solid color-mix(in srgb,var(--cta) 30%,var(--line));border-radius:16px;padding:1.2rem 1.4rem;margin:1.4rem 0}
.sw-cta-card h2{margin-top:0;font-size:1.25rem}
.sw-cta-p{color:var(--secondary);font-size:.95rem}
.sw-jump{font-size:.9rem}
.sw-doc-title{margin-top:2.2rem}
.sw-badge{border-radius:10px;padding:.65rem 1rem;font-size:.9rem;line-height:1.5}
.sw-badge-consumer{background:color-mix(in srgb,#2E7D32 10%,var(--card));border:1px solid color-mix(in srgb,#2E7D32 40%,var(--line))}
.sw-badge-commercial{background:color-mix(in srgb,#B26A00 10%,var(--card));border:1px solid color-mix(in srgb,#B26A00 40%,var(--line))}
.sw-sec{margin-top:1.6rem;font-size:1.05rem}
.sw-legal{font-size:.92rem;line-height:1.65;color:var(--secondary);margin:.55rem 0}
.sw-caps{font-size:.92rem;letter-spacing:.02em}
.sw-legal-list{padding-left:1.6rem;margin:.55rem 0}
.sw-legal-list li{font-size:.92rem;line-height:1.6;color:var(--secondary);margin:.45rem 0;padding-left:.25rem}
.sw-outro{color:var(--muted);font-size:.92rem}

/* Select clipping (Jim 2026-07-10) is solved by the uniform 44px field rule above
   (padding 0, line-height pinned to the content box) — selects must never grow taller.
   An interim height:38px override that lived here is removed; if a select ever clips
   again, fix it by reducing block padding inside the pinned height, never by adding height. */

/* Native phone country picker (Jim 2026-07-10): intl-tel-input's custom dropdown is
   disabled (countrySelectorMode OFF) and form-enhance.js lays a transparent native
   <select> over the dial-code prefix, so the phone country picker opens the exact
   OS-native menu the address Country <select> does. The first rule out-specifies the
   themed-select rules above (44px box, chevron background), which would otherwise
   paint this invisible overlay; the last adds the same chevron affordance the address
   select has, next to the dial code. */
:is(#gform_wrapper_1,#gform_wrapper_2,#gform_wrapper_3) .ginput_container select.sos-iti-select,
.sos-iti-select{
	position:absolute;inset:0;width:100%;height:100%!important;margin:0;
	padding:0!important;border:0!important;border-radius:0!important;
	opacity:0;cursor:pointer;z-index:2;
	background:none!important;background-image:none!important;
	-webkit-appearance:none;appearance:none;
}
:is(#gform_wrapper_1,#gform_wrapper_2,#gform_wrapper_3) .iti__country-container{cursor:pointer}
:is(#gform_wrapper_1,#gform_wrapper_2,#gform_wrapper_3) .iti__selected-country::after{
	content:"";width:14px;height:14px;flex:none;margin-left:.1rem;
	background:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%239b9dc8' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E") no-repeat center;
}

/* wp:table responsive scroll (product spec tables) — WP council staging R1 */
.wp-block-table{overflow-x:auto;-webkit-overflow-scrolling:touch}
.wp-block-table>table{min-width:520px}

/* Hero crossfade (Jim 2026-07-11): two 3:2 photos, photo1 on top fades to reveal photo2, then back. Both painted at t=0 (LCP-safe). */
.hero-xfade{position:relative;aspect-ratio:3/2;border-radius:18px;overflow:hidden;box-shadow:0 30px 64px -34px rgba(15,23,42,.38),0 22px 46px -26px color-mix(in srgb,var(--accent) 70%,transparent)}
.hero-xfade__img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;display:block;margin:0}
.hero-xfade .hx-top{animation:heroXfade 12s ease-in-out infinite}
@keyframes heroXfade{0%,40%{opacity:1}50%,90%{opacity:0}100%{opacity:1}}
@media(prefers-reduced-motion:reduce){.hero-xfade .hx-top{animation:none;opacity:1}}

/* ============================================================================
   PRIMARY HEADER MENU — production-matched (added 2026-07-19)
   Mirrors the live SolarOnSlate.com menu: larger bold labels, default brand
   BLUE (#3114ED), current page in brand RED (#FF004B) — exact production colors.
   The active state (.is-active + aria-current) is applied by assets/js/nav.js.
   On a Solutions child page the "Solutions" trigger AND the active dropdown item
   both turn red.
   ========================================================================== */
:root{ --nav-blue:#3114ED; --nav-red:#FF004B; }

/* larger, bold, blue top row (links + the Solutions trigger) */
.navlinks a,
.navlinks{ gap:1.3rem; }

/* hover stays blue (subtle darken) so it never reads as the red active state */
.navlinks a:hover,
.navlink-toggle:hover,

/* current page = red (top-level link, or the Solutions trigger when a child is active) */
.navlinks a.is-active,
.navlinks a.is-active:hover,
.navlink-toggle.is-active,
.navlink-toggle.is-active:hover,

/* dropdown: blue by default, red + soft highlight for the active solution page */
.navdrop a:hover,
.navdrop a.is-active,
.navdrop a.is-active:hover,
.navdrop a.is-active:focus-visible{
	color:var(--nav-red);
	background:color-mix(in srgb,var(--nav-red) 13%,transparent);
}

/* (The dark-mode nav colour list that used to sit here referenced only retired
   classes. With those gone the list had no declaration block and merged into the
   video-section rule below — which is what made the header menu vanish in dark
   mode: the links inherited overflow:hidden, line-height:0 and background:#000.
   Dark-mode nav colour is now handled once, at the end of this file.) */

/* ============================================================================
   HOMEPAGE FEATURE VIDEOS (HP1/HP2) — added 2026-07-21
   Standalone titled video sections. Revives the rounded treatment from the old
   .vmain gallery player, capped at 2/3 of the 1320px content width.
   ========================================================================== */
.vfeature{
	max-width:880px;          /* 2/3 of the 1320px .w content width */
	margin-inline:auto;
	border-radius:16px;
	overflow:hidden;
	background:#000;
	line-height:0;            /* kill the inline-video descender gap */
}
.vfeature video{
	display:block;
	width:100%;
	height:auto;
	border-radius:16px;
}

/* --- video box reservation -------------------------------------------------
   A <video preload="none"> never loads its metadata, so the browser does not
   know the clip's dimensions. It falls back to the HTML default intrinsic size
   of 300x150, and `height:auto` then resolves against THAT — collapsing the
   player to roughly 150px tall. The visible result is a black letterbox strip
   with a play bar, which is what a visitor sees until they press play.

   Declaring the ratio explicitly reserves the correct box before any metadata
   exists, so the poster frame fills it. It also removes the layout shift that
   otherwise happens when metadata finally arrives (a Core Web Vitals cost).

   Applied to every .wp-block-video, not just .vfeature: the same collapse
   affects the plain players on /slateplate/, /how-it-works/ and in blog posts.
   All current clips are 16:9 (1920x1080 and 1280x720, verified from the mp4
   headers). If a non-16:9 video is ever added, give it its own rule rather
   than removing this one. --------------------------------------------------- */
.wp-block-video video{
	display:block;
	width:100%;
	height:auto;
	aspect-ratio:16/9;
	object-fit:cover;
}

/* ============================================================================
   AUDIENCE-PAGE HERO LABEL (Round 2) — added 2026-07-22
   Promotes the hero eyebrow on the 7 audience pages to headline scale so a
   visitor immediately knows which audience page they landed on. Deliberately
   stays a <p> semantically — no second H1, heading order stays valid, and the
   value-prop H1 keeps its SEO weight.
   ========================================================================== */
.eyebrow.aud-label{
	font-size:clamp(1.15rem,2.4vw,1.6rem);  /* ~18–26px vs the 12px default */
	line-height:1.25;
	text-transform:none;      /* uppercase reads shouty at headline scale */
	letter-spacing:0;
	margin-bottom:.5rem;
}

/* ==========================================================================
   5. NEWSROOM / BLOG — "Ledger" (Style A, chosen by Jim 2026-08-01)
   --------------------------------------------------------------------------
   Bordered cards, 2-up, image-free. Deliberately reuses the same card language
   as the rest of the site (--card surface, 12px radius, --line border, hover
   ring) so the newsroom reads as part of the product site, not a bolted-on blog.

   IMAGE-FREE BY DESIGN: only 3 of 134 posts have a featured image (2.2%). A slot
   that is empty 98% of the time reads as a broken site, and 131 identical branded
   fallbacks read as wallpaper. Revisit only if real coverage exceeds ~80%.

   NO REVEAL ANIMATION ON THE GRID: reveal.js observes with threshold 0.18, so an
   element taller than (viewport / 0.18) can never satisfy the ratio and never
   fires. A 6-card list exceeds that on a phone, which would leave the entire post
   list permanently at opacity 0. The archive header may animate; the grid must not.

   These rules target the classes our templates emit. `post-template` renders a
   <ul>/<li>, NOT a .wp-block-group, which is why the existing .g3 grid rules
   (scoped to .wp-block-group) cannot be reused here.
   ========================================================================== */

/* ---- archive / hub header ---- */
.blog-head{max-width:680px;margin:0 0 34px}
.blog-head h1{font-size:clamp(1.9rem,3.4vw,2.45rem);letter-spacing:-.5px;margin:.35rem 0 .5rem}
.blog-head .dek{color:var(--secondary);font-size:1.02rem;margin:0}

/* ---- the post grid ---- */
/* list-style/padding reset is required: post-template emits a real <ul>. */
.blog-grid{display:grid;gap:16px;grid-template-columns:1fr;margin:0;padding:0;list-style:none}
/* Single mid-tier breakpoint at 680px. The sitewide .g3 collapses 3->1 at 900px
   with no tablet tier, which strands 680–900px; 2-up avoids that entirely. */
@media(min-width:680px){.blog-grid{grid-template-columns:repeat(2,1fr)}}
.blog-grid>li{margin:0;list-style:none}
.blog-grid>li::marker{content:""}

.blog-card{
	background:var(--card);
	border:1px solid color-mix(in srgb,var(--text) 16%,transparent);
	border-radius:12px;
	padding:22px;
	display:flex;flex-direction:column;height:100%;
	transition:border-color .2s,box-shadow .2s;
}
.blog-card:hover{border-color:var(--link);box-shadow:inset 0 0 0 1px var(--link)}

/* tabular-nums keeps the date column optically aligned card-to-card */
.blog-card .blog-date,
.blog-card .wp-block-post-date{
	font-size:.875rem;color:var(--muted);font-variant-numeric:tabular-nums;margin:0 0 .5rem;
}

.blog-card .wp-block-post-title{
	font-family:var(--fh);font-weight:700;font-size:1.32rem;line-height:1.2;
	letter-spacing:-.3px;margin:0 0 .55rem;
	/* Real staging titles run 27–123 chars. 3 lines holds the 123-char worst case
	   at the 2-up column width without the card growing unboundedly. */
	display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden;
}
.blog-card .wp-block-post-title a{color:var(--primary);text-decoration:none}
.blog-card:hover .wp-block-post-title a{
	color:var(--link);text-decoration:underline;text-decoration-thickness:2px;text-underline-offset:3px;
}

/* Excerpt: the visual/SEO compromise. excerptLength is set to 32 words in the
   template — deliberately ABOVE what 2 lines can show — so the 23 hand-written
   excerpts and the 111 auto-generated ones both overflow and clamp to exactly the
   same visual length. min-height reserves the 2 lines so short excerpts don't
   ragged-align the "Read article" links across a row. */
.blog-card .wp-block-post-excerpt__excerpt,
.blog-card .wp-block-post-excerpt p{
	font-size:.875rem;color:var(--muted);line-height:1.6;margin:0 0 1rem;min-height:3.2em;
	display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;
}
/* Core appends a "Read more" link inside the excerpt block; we use our own. */
.blog-card .wp-block-post-excerpt__more-text{display:none}

/* margin-top:auto pins this to the card bottom so all cards in a row align. */
.blog-card .blog-more{
	margin-top:auto;font-family:var(--fh);font-weight:600;font-size:.875rem;
	color:var(--link);text-decoration:none;
}
.blog-card:hover .blog-more{text-decoration:underline;text-underline-offset:3px}

/* ---- pagination ---- */
/* 44px min target = WCAG 2.5.8 / Apple HIG minimum. */
.blog-pager{margin-top:40px}
.blog-pager .wp-block-query-pagination-numbers,
.blog-pager.wp-block-query-pagination{display:flex;gap:.4rem;align-items:center;flex-wrap:wrap}
.blog-pager a,
.blog-pager .page-numbers{
	min-width:44px;min-height:44px;display:inline-flex;align-items:center;justify-content:center;
	border-radius:10px;border:1px solid color-mix(in srgb,var(--text) 16%,transparent);
	text-decoration:none;color:var(--secondary);font-weight:600;font-size:.9rem;padding:0 .5rem;
}
.blog-pager a:hover{border-color:var(--link);color:var(--link)}
.blog-pager .page-numbers.current{background:var(--cta);border-color:var(--cta);color:#fff}

/* ---- single post ---- */
/* The build shipped single.html at contentSize 1180px ≈ 145 characters per line.
   Comfortable reading measure is 60–80 characters; 680px lands at ~85 at this
   font size, which is the practical ceiling given the existing type scale. */
.blog-single .wp-block-post-title{font-size:clamp(1.9rem,3.6vw,2.6rem);letter-spacing:-.5px;margin-bottom:.5rem}
.blog-meta{font-size:.9rem;color:var(--muted);margin:0 0 28px}
.blog-meta a{color:var(--link)}
/* Long-form measure (option B, 2026-08-11). Column widened 680->800px AND body type
   raised 1.05rem->1.25rem together, on purpose: widening ALONE would push the line
   length past the readable range. Raising the type in step keeps characters-per-line
   at ~88 while making the glyphs 19% larger, so the page reads easier AND stops
   looking half the width of every other page. Change these two as a PAIR. */
.blog-single-content p{font-size:1.25rem;line-height:1.7}
.blog-single-content h2{font-size:clamp(1.4rem,2.4vw,1.85rem);margin-top:2em}
.blog-single-content h3{font-size:clamp(1.15rem,1.9vw,1.4rem);margin-top:1.6em}
.blog-single-content img{max-width:100%;height:auto;border-radius:10px}
.blog-single-content a{text-decoration:underline;text-underline-offset:2px}

/* Post-end CTA is a LINK, never an embedded form: functions.php gates the
   intl-tel-input + Google Maps Places stack on has_block('gravityforms/form'),
   so embedding a form here would load that third-party stack on all 133 posts. */
.blog-cta{
	margin-top:48px;padding:26px;border-radius:14px;
	background:var(--card);border:1px solid color-mix(in srgb,var(--text) 16%,transparent);
	border-left:3px solid var(--accent);
}
.blog-cta h2{font-size:1.35rem;margin:0 0 .4rem}
.blog-cta p{margin:0 0 1rem}

.blog-tags{margin-top:40px;padding-top:24px;border-top:1px solid var(--line);font-size:.875rem;color:var(--muted)}
.blog-tags a{color:var(--secondary)}
.blog-tags a:hover{color:var(--link)}

/* ============================================================================
   NATIVE NAVIGATION (2026-08-10)
   ----------------------------------------------------------------------------
   The header nav is now core/navigation instead of hand-written HTML, so the
   menu is editable at Appearance -> Editor -> Navigation and no longer has to
   be declared twice (the old markup repeated every link for the mobile menu).

   These rules restyle core's markup to match the previous design exactly.
   core/navigation renders:
       nav.wp-block-navigation.navlinks
         button.wp-block-navigation__responsive-container-open   (hamburger)
         div.wp-block-navigation__responsive-container            (overlay on mobile)
           ul.wp-block-navigation__container
             li.wp-block-navigation-item > a.wp-block-navigation-item__content
             li.has-child > button + ul.wp-block-navigation__submenu-container
   ========================================================================== */

/* --- desktop bar ----------------------------------------------------------
   DELIBERATELY MINIMAL. The existing `.navlinks a` rules above already set the
   nav's colour, size and weight (--nav-blue, 1.125rem, 700), and core/navigation
   renders its items as plain <a> inside .navlinks — so those rules apply
   unchanged. Re-declaring them here only created a conflict and got the colours
   wrong. Style only what core's markup genuinely adds. */
.navlinks.wp-block-navigation{ flex:1 1 auto; font-family:var(--fh); }
.navlinks .wp-block-navigation__container{ gap:1.2rem; align-items:center; }
/* Core ships this, with the class DOUBLED as a deliberate specificity boost:
       .wp-block-navigation .wp-block-navigation-item__content.wp-block-navigation-item__content{color:inherit}
   That is (0,3,0). A plain `.navlinks .wp-block-navigation-item__content` is (0,2,0)
   and loses, so every link renders as body text. Matching the doubled-class trick is
   the least-bad way to win without !important. Measured: without this the links
   compute to rgb(20,21,46) instead of #3114ED. */
.navlinks .wp-block-navigation-item__content.wp-block-navigation-item__content{
	color:var(--nav-blue);
	cursor:pointer;
	transition:color .2s;
}
.navlinks .wp-block-navigation-item__content.wp-block-navigation-item__content:hover{
	color:var(--nav-red);
}
/* The .btn-p utility paints a background wherever it is applied. On the core/button
   WRAPPER that draws a square block behind the already-pill-shaped link. Neutralise
   the wrapper; the link itself keeps its own background and 999px radius. */
.nav-cta .wp-block-button.btn-p{ background:none; box-shadow:none; border-radius:999px; }
.navlinks .wp-block-navigation-item__content:focus-visible{
	outline:2px solid var(--cta); outline-offset:3px; border-radius:4px;
}
/* Current page. The hand-written nav used a JS-applied .is-active class; core
   supplies .current-menu-item natively, so the highlight now works without JS. */
.navlinks .current-menu-item > .wp-block-navigation-item__content.wp-block-navigation-item__content,
.navlinks .current_page_item > .wp-block-navigation-item__content.wp-block-navigation-item__content{
	color:var(--nav-red);
}
/* The submenu toggle is a <button>, not an <a>, so the .navlinks a rules miss it.
   Match it to its siblings explicitly. */
.navlinks .wp-block-navigation-submenu__toggle{
	color:var(--nav-blue); font-size:1.125rem; font-weight:700;
	font-family:var(--fh); background:none; border:0; cursor:pointer;
}
.navlinks .wp-block-navigation-submenu__toggle:hover{ color:var(--nav-red); }

/* --- "Solutions" dropdown: inherit the old .navdrop card treatment --------- */
.navlinks .wp-block-navigation__submenu-container{
	min-width:230px;
	padding:8px;
	background:var(--card);
	border:1px solid var(--line);
	border-radius:14px;
	box-shadow:0 24px 50px -28px rgba(15,23,42,.45),0 8px 20px -14px rgba(15,23,42,.3);
	z-index:70;
}
.navlinks .wp-block-navigation__submenu-container .wp-block-navigation-item__content{
	display:block;
	padding:.55rem .8rem;
	border-radius:9px;
	font-size:.88rem;      /* dropdown items are smaller than the top-level bar */
	font-weight:600;
	color:var(--secondary);
}
.navlinks .wp-block-navigation__submenu-container .wp-block-navigation-item__content:hover{
	color:var(--cta);
}
.navlinks .wp-block-navigation__submenu-container .wp-block-navigation-item__content:hover,
.navlinks .wp-block-navigation__submenu-container .wp-block-navigation-item__content:focus-visible{
	background:color-mix(in srgb,var(--cta) 9%,transparent);
	outline:none;
}
/* Rotate the chevron when the submenu is open, as the old .navchev did. */
.navlinks .wp-block-navigation__submenu-icon{ transition:transform .2s ease; }
.navlinks .wp-block-navigation-item.is-open > .wp-block-navigation-submenu__toggle
	.wp-block-navigation__submenu-icon{ transform:rotate(180deg); }

/* --- mobile --------------------------------------------------------------- */
/* An older rule hides .navlinks entirely below 900px. That predates this block
   and would now hide the hamburger too, leaving no menu at all on a phone.
   Override it and let core's overlay do the work. */
@media(max-width:900px){
	/* Keep the block visible so its hamburger renders... */
	.navlinks.wp-block-navigation{ display:flex; flex:0 0 auto; }
	/* ...but put it AFTER the CTA, where the old hand-built hamburger sat.
	   The nav block is the second child in source order (it has to be, for the
	   desktop layout), so reorder rather than restructure. */
	.nav.wp-block-group{ gap:10px; }
	.nav.wp-block-group > .logo,
	.nav.wp-block-group > *:has(> .logo){ order:1; }
	.navright.wp-block-group{ order:2; flex:0 1 auto; min-width:0; }
	.navlinks.wp-block-navigation{ order:3; }
	/* The CTA wrapped to two lines at this width before; core's button defaults
	   to nowrap, which truncated it to "Request consu…". */
	.nav-cta .wp-block-button__link{
		white-space:normal;
		text-align:center;
		line-height:1.15;
		padding:.5rem .9rem;
	}
}
@media(max-width:600px){
	.nav-cta .wp-block-button__link{ font-size:.85rem; padding:.45rem .75rem; }
}
/* Put the hamburger beside the CTA on the right, where it was before. */
.navlinks .wp-block-navigation__responsive-container-open{
	width:44px; height:44px;
	align-items:center; justify-content:center;
	border-radius:10px;
	border:1px solid color-mix(in srgb,var(--text) 18%,transparent);
	background:var(--card);
	color:var(--primary);
	transition:.2s;
}
.navlinks .wp-block-navigation__responsive-container-open:hover{
	color:var(--cta); border-color:var(--cta);
}
/* THE MOBILE MENU IS A POPOVER, NOT A TAKEOVER (2026-08-10, owner's call).
   A full-screen sheet made everything else vanish, which felt heavier than the
   site warrants. This anchors a card under the hamburger instead, so the page
   stays visible behind it.

   Positioned against .navlinks (which is position:relative) rather than the
   viewport. Note this deliberately AVOIDS position:fixed here: the header sets
   backdrop-filter, which makes it the containing block for fixed descendants —
   the trap that collapsed the old overlay to a 64px strip. */
.navlinks .wp-block-navigation__responsive-container.is-menu-open{
	position:absolute;
	top:calc(100% + 14px);
	right:0;
	left:auto;
	/* Core sets `inset:0` on the base container, which includes bottom:0. Leaving
	   it in force alongside our `top` made the height resolve from the 44px nav
	   wrapper instead of from the content — the popover collapsed to a 22px strip
	   while its menu was 707px tall. Reset it explicitly. */
	bottom:auto;
	height:auto;
	width:min(320px, calc(100vw - 32px));
	max-height:min(70vh, 560px);
	overflow-y:auto;
	padding:10px;
	background:var(--card);
	border:1px solid var(--line);
	border-radius:14px;
	box-shadow:0 24px 50px -28px rgba(15,23,42,.45),0 8px 20px -14px rgba(15,23,42,.3);
	z-index:80;
	display:block;
}
/* Core adds this to <html> when its menu opens and it locks page scrolling —
   right for a takeover, wrong for a popover. */
html.has-modal-open{ overflow:auto !important; }

.navlinks .wp-block-navigation__responsive-container.is-menu-open
	.wp-block-navigation__responsive-dialog{ width:100%; margin:0; }
.navlinks .wp-block-navigation__responsive-container.is-menu-open
	.wp-block-navigation__responsive-container-content{ width:100%; }
.navlinks .wp-block-navigation__responsive-container.is-menu-open
	.wp-block-navigation__container{ width:100%; flex-direction:column; align-items:stretch; gap:0; }
.navlinks .wp-block-navigation__responsive-container.is-menu-open
	.wp-block-navigation-item{ width:100%; border-bottom:1px solid var(--line); }
.navlinks .wp-block-navigation__responsive-container.is-menu-open
	.wp-block-navigation-item:last-child{ border-bottom:0; }
.navlinks .wp-block-navigation__responsive-container.is-menu-open
	.wp-block-navigation-item__content{
	display:block;
	padding:.7rem .6rem;
	font-size:1rem;
	text-align:left;
	white-space:normal;
}
/* Submenu sits inline inside the popover, not as a second floating card. */
.navlinks .wp-block-navigation__responsive-container.is-menu-open
	.wp-block-navigation__submenu-container{
	position:static; background:none; border:0; box-shadow:none;
	padding:0 0 0 .8rem; min-width:0;
}

/* CLOSE BUTTON — core centres its icon by default, but the theme's button
   resets knocked the flex centring off, leaving the X sitting high-left. */
.navlinks .wp-block-navigation__responsive-container-close{
	position:absolute; top:10px; right:10px;
	width:36px; height:36px;
	display:flex; align-items:center; justify-content:center;
	padding:0; line-height:0;
	border-radius:9px;
	border:1px solid color-mix(in srgb,var(--text) 18%,transparent);
	background:var(--bg); color:var(--primary);
}
.navlinks .wp-block-navigation__responsive-container-close svg{
	display:block; margin:0;
}
/* Core pads the open container generously for a full-screen takeover
   (clamp(1rem, root-padding, 20rem)); a popover wants far less. */
.navlinks .wp-block-navigation__responsive-container.is-menu-open:not(.disable-default-overlay),
.navlinks .wp-block-navigation__responsive-container.is-menu-open{
	padding:8px 10px 10px;
}
.navlinks .wp-block-navigation__responsive-container.is-menu-open
	.wp-block-navigation__responsive-close{ padding-top:0; max-width:none; }
/* Room for the close button on the first row only. */
.navlinks .wp-block-navigation__responsive-container.is-menu-open
	.wp-block-navigation__container > li:first-child{ margin-top:30px; }

/* Core centres overlay items; a dropdown panel reads better left-aligned,
   and it matches the desktop submenu. */
.navlinks .wp-block-navigation__responsive-container.is-menu-open
	.wp-block-navigation__container,
.navlinks .wp-block-navigation__responsive-container.is-menu-open
	.wp-block-navigation__responsive-container-content{
	align-items:flex-start !important;
	justify-content:flex-start;
	text-align:left;
}
.navlinks .wp-block-navigation__responsive-container.is-menu-open
	.wp-block-navigation-item{ align-items:flex-start; }

.navlinks .wp-block-navigation__responsive-container.is-menu-open
	.wp-block-navigation__container{
	gap:0;
	align-items:stretch;
}
.navlinks .wp-block-navigation__responsive-container.is-menu-open
	.wp-block-navigation-item{
	border-bottom:1px solid var(--line);
}
.navlinks .wp-block-navigation__responsive-container.is-menu-open
	.wp-block-navigation-item__content{
	display:block;
	padding:.9rem .2rem;
	font-size:1.05rem;
	text-align:left;      /* matches the previous .mobilenav, which was left-aligned */
}
/* Inside the overlay the submenu is inline, not a floating card. */
.navlinks .wp-block-navigation__responsive-container.is-menu-open
	.wp-block-navigation__submenu-container{
	background:none; border:0; box-shadow:none; padding:0 0 0 .9rem;
}


/* ============================================================================
   HEADER FIT (2026-08-10) — decided with the council after the owner reported
   the bar breaking across a band of widths.
   ----------------------------------------------------------------------------
   THE MEASUREMENTS THAT DROVE THIS. At its working width the bar held ~1,170px
   of content in a ~1,264px space: about 95px of slack. That is why one extra
   word wrapped "How It Works" onto three lines and clipped the CTA.

   Two structural savings were taken FIRST, because they buy permanent width
   rather than borrowed width:
     · the colour-mode toggle moved to the footer   ~52px
     · the CTA shortened to "Contact Us"            ~105px
   Fluid type and gaps below recover more on top of that.

   ⚠ PRIORITY RULE, and it is deliberate: when space runs out the LINKS yield,
   never the CTA. Shrinking the CTA is what produced the vertical column of
   single letters overlapping the logo — a WCAG 2.1 Reflow failure reachable by
   anyone at 200% browser zoom on an ordinary laptop.
   ========================================================================== */

/* The CTA is load-bearing: fixed size, never wraps, never compresses. */
.navright.wp-block-group{ flex:0 0 auto; }
.nav-cta .wp-block-button__link{ white-space:nowrap; }

/* The links are the flexible element and may shrink. */
.navlinks.wp-block-navigation{ min-width:0; }

/* Never break a label across lines — "How / It / Works" was the reported fault. */
.navlinks .wp-block-navigation-item__content{ white-space:nowrap; }

/* Fluid type and gaps between ~900px and the full container. clamp() keeps a
   hard 15px floor so browser zoom still enlarges text rather than fighting it. */
@media(min-width:901px){
	.navlinks .wp-block-navigation-item__content.wp-block-navigation-item__content,
	.navlinks .wp-block-navigation-submenu__toggle{
		font-size:clamp(0.9375rem, 0.55rem + 0.68vw, 1.125rem);
	}
	.navlinks .wp-block-navigation__container{
		gap:clamp(0.55rem, -0.15rem + 1.25vw, 1.2rem);
	}
}

/* THE DEAD ZONE. Core switches its overlay on at exactly 600px; this theme's
   layout rules assumed 900px. Between the two the site rendered a full desktop
   link list under hamburger-era rules — the state that destroyed the CTA.
   Show the overlay across the whole of that band so no in-between exists. */
@media(max-width:900px){
	.navlinks .wp-block-navigation__responsive-container:not(.is-menu-open){
		display:none;
	}
	.navlinks .wp-block-navigation__responsive-container-open:not(.always-shown){
		display:flex;
	}
}

/* Footer colour-mode switch, relocated from the header. */
.foot-mode{ display:flex; align-items:center; gap:10px; margin-top:14px; }
.foot-mode__label{ font-family:var(--fh); font-weight:600; font-size:.85rem; color:var(--secondary); }


/* ============================================================================
   DARK MODE NAV + ACTIVE-PARENT HIGHLIGHT (2026-08-10)
   ----------------------------------------------------------------------------
   BUG: the header menu was effectively invisible in dark mode. --nav-blue is
   #3114ED, and the dark header background is #0E0F26 — roughly 1.5:1, far under
   the 4.5:1 minimum. The theme already diagnosed this exact problem for body
   links (see the comment above the focus-visible rules: the deep blue "fails as
   TEXT ... on dark surfaces") and solved it by re-pointing --link to #8AA9FF in
   dark. The nav tokens were simply never given the same treatment. Reuse the
   established colour rather than inventing a new one.
   ========================================================================== */
html[data-theme="dark"]{
	--nav-blue:#8AA9FF;   /* same value the theme already uses for --link in dark */
}
/* Hover/active stays the brand red, which is legible on both grounds. */
html[data-theme="dark"] .navlinks .wp-block-navigation-item__content.wp-block-navigation-item__content:hover,
html[data-theme="dark"] .navlinks .wp-block-navigation-submenu__toggle:hover{
	color:var(--nav-red);
}
/* The popover panel sits on --card in dark; keep its links on the same token. */
html[data-theme="dark"] .navlinks .wp-block-navigation__submenu-container
	.wp-block-navigation-item__content.wp-block-navigation-item__content{
	color:var(--nav-blue);
}

/* ---- Active parent -------------------------------------------------------
   When an audience page is open, its entry in the Solutions submenu already
   turns red. The PARENT ("Solutions") stayed blue, so the bar gave no clue
   which section you were in. WordPress adds .current-menu-ancestor (and
   .current-menu-parent) to the parent <li>, so no JS is needed.
   The parent is an <a> label plus a <button> toggle — both need colouring. */
.navlinks .current-menu-ancestor > .wp-block-navigation-item__content.wp-block-navigation-item__content,
.navlinks .current-menu-parent   > .wp-block-navigation-item__content.wp-block-navigation-item__content,
.navlinks .current-menu-ancestor > .wp-block-navigation-submenu__toggle,
.navlinks .current-menu-parent   > .wp-block-navigation-submenu__toggle,
.navlinks .current-menu-ancestor > .wp-block-navigation-item__content .wp-block-navigation-item__label{
	color:var(--nav-red);
}

/* ---- Newsroom archive search (2026-08-10) --------------------------------
   Native core/search, icon button inside the field. Scoped to the archive
   template only; there is deliberately no header search. */
.blog-search{ max-width:420px; margin:18px 0 0; }
/* With buttonPosition "button-inside" core draws the border on the WRAPPER,
   so the input must not draw its own or you get a box inside a box. */
.blog-search .wp-block-search__inside-wrapper{
	border:1px solid var(--line);
	border-radius:10px;
	background:var(--card);
	padding:0;
	overflow:hidden;
}
.blog-search .wp-block-search__inside-wrapper:focus-within{
	border-color:var(--cta);
	box-shadow:0 0 0 2px color-mix(in srgb,var(--cta) 25%,transparent);
}
.blog-search .wp-block-search__input{
	border:0;
	background:transparent;
	padding:.6rem .8rem;
	color:var(--text);
	font-family:var(--fb);
	font-size:.95rem;
}
.blog-search .wp-block-search__input:focus{ outline:none; }
.blog-search .wp-block-search__button{
	background:none;
	border:0;
	color:var(--secondary);
	padding:0 .6rem;
	cursor:pointer;
}
.blog-search .wp-block-search__button:hover{ color:var(--cta); }
.blog-search .wp-block-search__button svg{ fill:currentColor; width:22px; height:22px; }
html[data-theme="dark"] .blog-search .wp-block-search__button{ color:var(--nav-blue); }

/* ---- End-of-article audience router (2026-08-10) -------------------------
   Mirrors the homepage audience router. IMPORTANT: the homepage pills are NOT
   styled by this stylesheet — they come from the sos-blocks audience-router
   block (plugins/sos-blocks/blocks/audience-router/style.css), which includes a
   "Signal-Wave" section that a static-style comparison completely misses:
   a resting shadow, transform/box-shadow transitions, a hover lift with a blue
   glow, and a staggered wave animation.

   That block's CSS only loads on pages containing the block, so a blog post
   would not get its @keyframes. Everything it needs is therefore restated here
   with its own keyframe name, matching the block's values exactly. If the block
   changes, change this too — they are two copies by necessity. */
.post-router{
	margin:44px 0 8px;
	padding:26px;
	background:var(--surface-1);
	border:1px solid var(--line);
	border-radius:14px;
	text-align:center;
}
.post-router__h{ font-size:1.25rem; margin:0 0 6px; }
.post-router__dek{ margin:0 0 20px; color:var(--secondary); font-size:.95rem; }

/* == .sos-aud__tabs == */
.post-router__list{
	list-style:none; margin:0 auto; padding:0;
	max-width:800px;
	display:flex; gap:8px; flex-wrap:wrap; justify-content:center;
}
.post-router__list li{ margin:0; }

/* == .sos-aud__tab, including the resting shadow and full transition list == */
.post-router__list a{
	display:inline-block;
	cursor:pointer;
	font-family:var(--fh);
	font-weight:600;
	font-size:.9rem;
	padding:.6rem 1.1rem;
	border-radius:999px;
	border:1px solid var(--line);
	background:var(--card);
	color:var(--secondary);
	text-decoration:none;
	box-shadow:0 1px 2px rgba(20,21,46,.06);
	transition:background-color .2s ease, color .2s ease, border-color .2s ease,
		transform .18s ease, box-shadow .18s ease;
}

/* == hover: lift + blue glow == */
.post-router__list a:hover{
	transform:translateY(-4px) scale(1.03);
	box-shadow:0 12px 22px -8px color-mix(in srgb, var(--cta) 55%, transparent);
	border-color:var(--cta);
	color:var(--cta);
}
.post-router__list a:focus-visible{
	outline:2px solid var(--cta);
	outline-offset:2px;
}

/* == Signal Wave: staggered per pill via --i, released on row hover so the
      per-pill lift can show. Values identical to sos-aud-wave. == */
@media (prefers-reduced-motion: no-preference){
	.post-router__list a{
		animation:post-router-wave 5.5s ease-in-out calc(var(--i, 0) * .24s) infinite;
		will-change:transform;
	}
	.post-router__list:hover a{ animation:none; }
}
.post-router__list li:nth-child(1) a{ --i:0; }
.post-router__list li:nth-child(2) a{ --i:1; }
.post-router__list li:nth-child(3) a{ --i:2; }
.post-router__list li:nth-child(4) a{ --i:3; }
.post-router__list li:nth-child(5) a{ --i:4; }
.post-router__list li:nth-child(6) a{ --i:5; }
.post-router__list li:nth-child(7) a{ --i:6; }

@keyframes post-router-wave{
	0%   { transform:translateY(0);    box-shadow:0 1px 2px rgba(20,21,46,.06); }
	7%   { transform:translateY(-6px); box-shadow:0 12px 22px -6px color-mix(in srgb, var(--cta) 50%, transparent); }
	16%  { transform:translateY(0);    box-shadow:0 1px 2px rgba(20,21,46,.06); }
	100% { transform:translateY(0);    box-shadow:0 1px 2px rgba(20,21,46,.06); }
}

/* Same touch-target floor the homepage tabs get on small screens. */
@media(max-width:600px){
	.post-router__list a{ padding:.7rem 1.1rem; min-height:44px; }
}
}
