/*
Theme Name:   Nearby (Blocksy Child)
Theme URI:    https://github.com/comnio/nearby-core
Description:  Child theme for every Nearby directory — the vertical is read from Nearby_Verticals, so one theme serves septic, plumbing and electrical (state-agnostic; Texas live). Owns all template customization (T1–T10) per scoping doc Appendix C.4 — no page builders. v0.10: geo-language pass — general pages national (cache-safe), geo pages state-scoped; visitor-state hook; coverage rollup.
Author:       Ross Clurman
Template:     blocksy
Version:      0.42.9
Requires PHP: 8.2
Text Domain:  nearby-septic
*/

/* ==================================================================
   Shared base tokens — Nearby family, all verticals
   Source of truth: "Nearby Family System" brand kit, decided 2026-09-07.
   Neutrals and --verify never vary by vertical; --v-primary/--v-accent
   and their derived shades are set per install by the [data-vertical]
   block below (data-vertical is emitted on <html> from
   Nearby_Verticals::current()). --ns-forest and --ns-moss stay as aliases
   so the existing call sites across theme + plugin keep working unchanged.
   ================================================================== */
:root {
	--ns-bg: #FFFFFF;
	--ns-wash: #F7F5EF;
	--ns-tone: #EFEDE5;
	--ns-bone: #DCD7C9;
	--ns-ink: #1A1A19;
	--ns-mut: #726E60;
	--ns-faint: #767260;  /* was Stone #8F8A76 = 3.46:1 on white, 3.29:1 on Paper — below AA for the 11–12.5px kickers and footnotes it colors (QA W3, 2026-09-15, measured from rendered pixels on / and /texas/dallas/). #767260 reads 4.83:1 / 4.59:1. The brand sheet keeps Stone for the descriptor line and OG-card labels, which are images, not this text. */
	--ns-hair: #DCD7C9;
	--ns-hair-warm: #CFDCC0;   /* generic warm hairline (filter bar, search, pager, chips) — unchanged value, split off --ns-verify-hair 2026-09-07 so retinting verify doesn't recolor unrelated UI */

	/* Vertical brand pair — values set per install by [data-vertical] below.
	   Fallback here matches Septic (Nearby_Verticals::FALLBACK) so nothing
	   renders unstyled if the attribute is ever missing. */
	--v-primary: #31511E;      --v-primary-on: #FFFFFF;
	--v-primary-dk: #243D14;   --v-primary-wash: #F0F3E7;  --v-primary-tint: #D9E3C8;
	--v-accent: #859F3D;       --v-accent-on: #1A1A19;     --v-accent-deep: #5F7429;
	--v-blob-rgb: 133,159,61;  /* the hero blob's radial wash = --v-accent as an rgb triple, because rgba() cannot take a hex var. Was an inline literal in six templates, so plumbing rendered septic's olive (QA W6, 2026-09-15) */

	--ns-forest: var(--v-primary);
	--ns-forest-dk: var(--v-primary-dk);
	--ns-forest-wash: var(--v-primary-wash);
	--ns-forest-tint: var(--v-primary-tint);
	--ns-moss: var(--v-accent);
	--ns-moss-deep: var(--v-accent-deep);

	--ns-gold: #FFCA4E;
	--ns-gold-dk: #E9AE27;

	/* portable trust signal — belongs to no vertical (brand kit §07, decided
	   2026-09-07): Verify Green #276B3C, replacing the old #31511E (Septic's
	   own forest) so the badge reads as a signal, not as brand chrome. Tints
	   below are re-derived from #276B3C at the same mix ratios the old
	   forest-based tints used — a judgment call (the brand kit specs only
	   the solid --verify/--verify-on pair, not these tints). */
	--verify: #276B3C;
	--verify-on: #FFFFFF;
	--ns-verify: var(--verify);
	--ns-verify-dk: #1C4D2B;
	--ns-verify-tint: #D5E2D9;
	--ns-verify-bg: #EDF3EF;
	--ns-verify-hair: #CCDCD1;

	--ns-warn-bg: #FBF3DC;
	--ns-warn-ink: #765B13;   /* 4.68:1 on --ns-wheat-border (was #7A5E14, 4.46:1 — QA 2026-09-25) */
	--ns-char: #1A1A19;
	/* One family sitewide (standalone mockup spec): Archivo 400–800.
	   --ns-disp kept as an alias so every display-font usage follows. */
	--ns-sans: "Archivo", -apple-system, "Segoe UI", Roboto, sans-serif;
	--ns-disp: "Archivo", -apple-system, "Segoe UI", Roboto, sans-serif;

	/* Table-refresh system (approved mockups: Table Refresh Mockups 1a–1d).
	   Text tones extend the ink family; wheat = the single highlight tint. */
	--ns-body: #3E4234;
	--ns-hairline: #E7E5D8;
	--ns-hairline-soft: #E0DED0;
	--ns-wheat: #F9F6E7;
	--ns-wheat-border: #EBDCA8;
	--ns-row-hover: #FAF9F2;

	/* Back-compat aliases (0.2 scaffold classes still in plugin output) */
	--ns-verified: var(--ns-verify);
	--ns-verified-bg: var(--ns-verify-bg);
	--ns-unverified: var(--ns-warn-ink);
	--ns-unverified-bg: var(--ns-warn-bg);
	--ns-card-border: var(--ns-hair);
}

/* ---- vertical brand pair — exactly one block matches per install, via
   <html data-vertical="…"> (header.php, from Nearby_Verticals::current()).
   Values and contrast ratios: "Nearby Family System" brand kit, decided
   2026-09-07. Selector values are Nearby_Verticals::all() codes, NOT the
   brand kit's own cosmetic slugs (its board calls this vertical "plumber";
   the registry's live code is "plumbing" — this file follows the registry). ---- */

[data-vertical="septic"] {
	--v-primary: #31511E;      --v-primary-on: #FFFFFF;   /* 9.03:1 */
	--v-primary-dk: #243D14;   --v-primary-wash: #F0F3E7;  --v-primary-tint: #D9E3C8;
	--v-accent: #859F3D;       --v-accent-on: #1A1A19;     --v-accent-deep: #5F7429;  /* 5.83:1 */
	--v-btn-rest-a: #3A5F23;   --v-btn-rest-b: #2A4517;    --v-btn-hover-b: #223A10;  /* CTA gradient stops - exact values the live Septic button already ships, unchanged */
	--v-sec-a: #35571F; --v-sec-b: #2A4517; --v-sec-text: #DDE7D2; --v-sec-meta: #C2D0B2; --v-sec-icon: #A6BC6B;  /* .ns-sec--forest band - exact values already shipped, unchanged */
}

[data-vertical="plumbing"] {
	--v-primary: #1D3F63;      --v-primary-on: #FFFFFF;   /* 10.81:1 */
	--v-primary-dk: #152D47;   --v-primary-wash: #ECEFF2;  --v-primary-tint: #D3D9E0;
	--v-accent: #66A0CE;       --v-accent-on: #1A1A19;     --v-accent-deep: #487191;  /* 6.21:1 */
	--v-blob-rgb: 102,160,206;
	--v-btn-rest-a: #28486B;   --v-btn-rest-b: #183452;    --v-btn-hover-b: #132940;  /* CTA gradient stops - proportional analog of Septic, not brand-kit spec-d */
	--v-sec-a: #214366; --v-sec-b: #183452; --v-sec-text: #D9DFE5; --v-sec-meta: #BBC5D0; --v-sec-icon: #90A1B2;  /* .ns-sec--forest band - proportional analog, not brand-kit spec-d */
}

/* Electrical: registered in Nearby_Verticals as 'electrical' on 2026-09-24
   (staged, no live state), and the selector was renamed from the brand kit's
   "electric" to match, exactly as the note that used to sit here said to do.
   Values are the brand kit's forward-declared Electric colorway, unchanged. */
[data-vertical="electrical"] {
	/* Brand board v1 (2026-09-20) Copper/Amber, adopted 2026-09-25 (EX-E016),
	   replacing the kit's #7A3B12/#D98324. Primary, accent and on-colors are the
	   board's; the rest are derived from the primary (scale or white mix), each
	   contrast measured. */
	--v-primary: #A85A12;      --v-primary-on: #FFFFFF;   /* 5.08:1 */
	--v-primary-dk: #79410D;   --v-primary-wash: #FBF7F3;  --v-primary-tint: #EEDED0;
	--v-accent: #D9922B;       --v-accent-on: #1A1A19;     --v-accent-deep: #9E6B1F;  /* on 6.72:1, deep 4.59:1 on white */
	--v-blob-rgb: 217,146,43;
	--v-btn-rest-a: #A85A12;   --v-btn-rest-b: #8B4B0F;    --v-btn-hover-b: #6F3B0C;  /* white 5.08 / 6.75 / 9.10 */
	--v-sec-a: #A05611; --v-sec-b: #8B4B0F; --v-sec-text: #F5EBE3; --v-sec-meta: #EAD7C6; --v-sec-icon: #DCBDA0;  /* on sec-b: 5.75 / 4.83 / 3.80 */
}

/* Pest control: registered in Nearby_Verticals as 'pest' on 2026-10-08
   (staged, no live state). The fifth vertical — "a fifth vertical is a fifth
   block, not a fork" (family system §08). PROVISIONAL color pair, pending the
   pest brand board (Sprint 1 item 2): Deep Teal / Sea Glass, chosen inside the
   family's rules — same value band as the other primaries, a hue family none
   of them uses (184°), accents never carry white type. Primary, accent and
   on-colors are the registry's email_ink / email_accent; the rest are derived
   (scale or white mix), each contrast measured 2026-10-08. */
[data-vertical="pest"] {
	--v-primary: #0E5E63;      --v-primary-on: #FFFFFF;   /* 7.50:1 */
	--v-primary-dk: #0A4447;   --v-primary-wash: #F3F7F7;  --v-primary-tint: #CFDFE0;
	--v-accent: #5DBDB8;       --v-accent-on: #1A1A19;     --v-accent-deep: #3A7773;  /* on 7.83:1, deep 5.16:1 on white */
	--v-blob-rgb: 93,189,184;
	--v-btn-rest-a: #0E5E63;   --v-btn-rest-b: #0B4D51;    --v-btn-hover-b: #0A4043;  /* white 7.50 / 9.57 / 11.49 */
	--v-sec-a: #0D595E; --v-sec-b: #0B4D51; --v-sec-text: #E7EFEF; --v-sec-meta: #CADCDD; --v-sec-icon: #9FBFC1;  /* on sec-b: 8.20 / 6.74 / 4.87 */
}

/* Forward-declared from the brand kit — HVAC has no Nearby_Verticals entry
   yet, so this selector is unused today and its attribute value may need
   renaming once the vertical is registered (confirm the registered code
   first; don't assume it matches the brand kit's slug). */
[data-vertical="hvac"] {
	--v-primary: #4A2C56;      --v-primary-on: #FFFFFF;   /* 11.76:1 */
	--v-primary-dk: #35203E;   --v-primary-wash: #F0EEF1;  --v-primary-tint: #DBD6DE;
	--v-accent: #B683C4;       --v-accent-on: #1A1A19;     --v-accent-deep: #805C8A;  /* 5.83:1 */
	--v-blob-rgb: 182,131,196;
	--v-btn-rest-a: #53365E;   --v-btn-rest-b: #3D2447;    --v-btn-hover-b: #301D38;  /* CTA gradient stops - proportional analog, unused until this vertical is registered */
	--v-sec-a: #4E3059; --v-sec-b: #3D2447; --v-sec-text: #E1DCE3; --v-sec-meta: #C8BFCC; --v-sec-icon: #A697AC;  /* .ns-sec--forest band - proportional analog, unused until registered */
}

/* --v-accent-on is always --ink (#1A1A19). White on any accent measures
   2.6-3.0:1 and fails AA at every size, so no accent ever carries white
   type — brand kit §06. */


html { scroll-behavior: smooth; }
.ns-skip { position: absolute; left: -9999px; top: 0; z-index: 100; background: #fff; color: var(--ns-ink); padding: 10px 16px; font-weight: 600; border-radius: 0 0 8px 0; }
.ns-skip:focus { left: 0; }

/* ==================================================================
   Scope: everything the child theme renders sits inside .ns
   ================================================================== */
.ns { font-family: var(--ns-sans); color: var(--ns-ink); font-size: 16px; line-height: 1.55; background: var(--ns-bg); overflow-x: clip; }
.ns * { box-sizing: border-box; }
.ns a { color: var(--ns-ink); text-decoration: none; }
.ns a:hover { color: var(--ns-forest); }
.ns h1, .ns h2 { font-family: var(--ns-disp); font-weight: 700; margin: 0; color: var(--ns-ink); text-wrap: pretty; }
.ns h1 { font-size: clamp(30px, 4vw, 44px); line-height: 1.06; letter-spacing: -.025em; }
.ns h2 { font-size: clamp(22px, 2.6vw, 28px); line-height: 1.12; letter-spacing: -.02em; }
.ns h3 { font-size: 16px; font-weight: 700; letter-spacing: -.01em; margin: 0; }
.ns .dim { color: var(--ns-faint); }
.ns-wrap { max-width: 1180px; margin: 0 auto; padding: 0 24px; }
.ns-sec { padding: 56px 0; }
/* Heroes don't clip their gradient blobs (they fade out naturally over
   the following section); .ns's overflow-x:clip prevents sideways
   scroll from off-canvas blob edges instead. */
.ns-sec--hero { padding: 64px 0 48px; position: relative; overflow: visible; }
.ns-sec--hero .ns-blob { z-index: 0; }
.ns-sec--hero .ns-wrap { position: relative; z-index: 1; }
.ns-sec--wash { background: var(--ns-wash); }
.ns-sec--band { background: var(--ns-forest-wash); }
.ns-sec--forest { background: linear-gradient(180deg, var(--v-sec-a), var(--v-sec-b)); color: var(--v-sec-text); }
.ns-sec--forest h2 { color: #fff; }
.ns-sec--forest .ns-meta { color: var(--v-sec-meta); font-size: 14px; }
.ns-sec--forest .ns-ic { color: var(--v-sec-icon); }
.ns-sec--tight { padding: 36px 0; }
.ns-rule { height: 1px; background: linear-gradient(90deg, rgba(217,213,204,0), #D9D5CC 50%, rgba(217,213,204,0)); }
.ns-kicker { font-size: 11px; letter-spacing: .16em; text-transform: uppercase; font-weight: 700; color: var(--ns-faint); margin-bottom: 12px; }
.ns-dek { color: var(--ns-body); font-size: 17px; line-height: 1.6; margin: 14px 0 0; max-width: 680px; }
.ns-fn { font-size: 12.5px; color: var(--ns-faint); margin-top: 10px; }
.ns-meta { font-size: 13px; color: var(--ns-mut); line-height: 1.55; }
.ns-crumbs { font-size: 12.5px; color: var(--ns-faint); }
.ns-crumbs a { color: var(--ns-faint); }
.ns-crumbs a:hover { color: var(--ns-forest); }
.ns-num { font-weight: 600; font-variant-numeric: tabular-nums; white-space: nowrap; }
.ns-narrow { max-width: 760px; }

/* Long-form prose (page.php, guides) — the typographic rhythm raw
   the_content() lacks. */
.ns-prose { max-width: 760px; font-size: 16px; line-height: 1.7; }
.ns-prose p { margin: 0 0 16px; }
.ns-prose h2 { font-size: clamp(22px, 2.6vw, 28px); margin: 44px 0 14px; letter-spacing: -.02em; }
.ns-prose h3 { font-size: 20px; font-weight: 700; letter-spacing: -.01em; margin: 30px 0 10px; }
.ns-prose h2:first-child { margin-top: 0; }
.ns-prose ul, .ns-prose ol { margin: 0 0 16px; padding-left: 22px; }
.ns-prose li { margin: 7px 0; }
.ns-prose a { color: var(--ns-forest); font-weight: 500; text-decoration: underline; text-decoration-color: var(--ns-forest-tint); text-underline-offset: 3px; }
.ns-prose a:hover { text-decoration-color: var(--ns-forest); }
.ns-prose table { margin: 20px 0 24px; }
.ns-prose blockquote { border-left: 3px solid var(--ns-forest-tint); margin: 20px 0; padding: 4px 0 4px 18px; color: var(--ns-mut); }
.ns-prose strong, .ns-prose b { color: var(--ns-ink); }
.ns-prose em:last-child { color: var(--ns-mut); }
.ns-prose img { max-width: 100%; height: auto; border-radius: 12px; }
.ns-prose hr { border: 0; border-top: 1px solid var(--ns-hair); margin: 32px 0; }

/* Icons */
.ns-ic { width: 18px; height: 18px; stroke: currentColor; fill: none; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; vertical-align: -3px; flex: 0 0 auto; }
.ns-ic--lg { width: 24px; height: 24px; color: var(--ns-forest); }

/* Washes */
.ns-blob { position: absolute; border-radius: 50%; pointer-events: none; }

/* ==================================================================
   Header / nav
   ================================================================== */
.ns-nav { background: rgba(255,255,255,.94); backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px); position: sticky; top: 0; z-index: 40; border-bottom: 1px solid var(--ns-hair); }
body.admin-bar .ns-nav { top: 32px; }
/* 601–782px ONLY. At ≤600px WordPress makes the admin bar
   position:absolute — it scrolls away with the page — so pinning our nav
   46px down there left a 46px strip of content sliding above the pinned
   header after any scroll. Logged-in users only, but that's exactly who
   reviews the site on a phone. Below 601px the bar scrolls off and the
   nav belongs at 0. */
@media (min-width: 601px) and (max-width: 782px) { body.admin-bar .ns-nav { top: 46px; } }
@media (max-width: 600px) { body.admin-bar .ns-nav { top: 0; } }
.ns-nav-links ul, .ns-mobilenav ul { list-style: none; margin: 0; padding: 0; }
.ns-nav-links ul { display: flex; gap: 22px; }
.ns-mobilenav ul li a { display: block; padding: 10px 0; font-weight: 500; border-bottom: 1px solid var(--ns-wash); }
.ns-nav .ns-wrap { display: flex; align-items: center; gap: 26px; height: 64px; }
.ns-logo { display: flex; align-items: center; gap: 9px; white-space: nowrap; color: var(--ns-ink); }
.ns-logo .ns-wm { font-family: var(--ns-sans); font-size: 15px; font-weight: 800; letter-spacing: 0; word-spacing: normal; }
.ns-logo .ns-wm b { color: var(--ns-forest); font-weight: 800; }
.ns-nav-links { display: flex; gap: 24px; font-size: 14px; font-weight: 600; }
.ns-nav-links a { color: var(--ns-body); border-bottom: 2px solid transparent; padding-bottom: 2px; }
.ns-nav-links a:hover { color: var(--ns-ink); border-bottom-color: var(--ns-gold-dk); }
.ns-nav-links .current-menu-item > a, .ns-nav-links .current-menu-ancestor > a, .ns-nav-links .current_page_item > a { color: var(--ns-ink); border-bottom-color: var(--ns-gold-dk); }
.ns-nav-cta { margin-left: auto; display: flex; gap: 20px; align-items: center; font-size: 13.5px; font-weight: 600; }
.ns-nav-cta > a:first-child { color: var(--ns-body); }
.ns-nav-cta > a:first-child:hover { color: var(--ns-ink); }
.ns-burger { display: none; margin-left: auto; font-size: 19px; background: none; border: 1px solid var(--ns-hair); border-radius: 8px; padding: 2px 10px; cursor: pointer; color: var(--ns-ink); }
/* Burger ↔ close. Fixed 1em box and centered glyph so the button does not
   change width when the character swaps — ✕ is narrower than ☰, and a
   nav control that resizes as you tap it reads as a layout bug. */
.ns-burger-ico { display: inline-block; width: 1em; text-align: center; line-height: 1.35; }
.ns-burger-ico::before { content: "\2630"; }
.ns-burger[aria-expanded="true"] .ns-burger-ico::before { content: "\2715"; font-size: .88em; }
.ns-burger[aria-expanded="true"] { border-color: var(--ns-ink); }
.ns-mobilenav { display: none; border-top: 1px solid var(--ns-hair); background: var(--ns-bg); padding: 12px 24px 18px; }
.ns-mobilenav.open { display: block; }
/* :not(.ns-btn) matters — this generic rule was flattening the "Get quotes"
   button into a plain bordered link in the mobile menu. */
.ns-mobilenav a:not(.ns-btn) { display: block; padding: 10px 0; font-weight: 500; border-bottom: 1px solid var(--ns-wash); }
.ns-mobilenav .ns-btn { display: block; width: 100%; text-align: center; border-bottom: 0; }

/* ==================================================================
   Buttons — primary forest / action gold / ghost / arrow
   ================================================================== */
.ns-btn { display: inline-flex; align-items: center; justify-content: center; gap: 7px; border-radius: 8px; padding: 11px 20px; font-size: 14px; font-weight: 600; cursor: pointer; border: 1px solid transparent; font-family: var(--ns-sans); white-space: nowrap; color: #fff; background: linear-gradient(180deg, var(--v-btn-rest-a), var(--v-btn-rest-b)); text-decoration: none; }
.ns-btn:hover { background: linear-gradient(180deg, var(--v-primary), var(--v-btn-hover-b)); color: #fff; }
.ns-btn:focus-visible, .ns a:focus-visible { outline: 2px solid var(--ns-moss); outline-offset: 2px; }
.ns-btn--gold { background: linear-gradient(180deg, #FFD26B, #F8BE3E); color: var(--ns-ink); }
.ns-btn--gold:hover { background: linear-gradient(180deg, #FFCA4E, #EFB230); color: var(--ns-ink); }
.ns-btn--ghost { background: #fff; border-color: #CBC5B4; color: var(--ns-ink); }
/* background MUST be declared here: .ns-btn:hover (same specificity, earlier
   in the file) sets the dark forest gradient, and without an override it
   showed through on ghost buttons — ink text on near-black, unreadable.
   The subtle wash is the intended hover darkening. */
.ns-btn--ghost:hover { background: var(--ns-wash); border-color: var(--ns-ink); color: var(--ns-ink); }
.ns-btn--sm { padding: 7px 14px; font-size: 13px; }
/* Phone width: the county-card phone and "View profile" buttons measured 150×36px at 390 (QA W4, 2026-09-15). 44px is the floor. */
@media (max-width: 480px) { .ns-btn--sm { min-height: 44px; } }
/* Anchor buttons: `.ns a` (0,1,1) outranks `.ns-btn` (0,1,0) — re-assert button text colors for <a> buttons. */
.ns a.ns-btn, .ns a.ns-btn:hover { color: #fff; }
.ns a.ns-btn--gold, .ns a.ns-btn--gold:hover { color: var(--ns-ink); }
.ns a.ns-btn--ghost, .ns a.ns-btn--ghost:hover { color: var(--ns-ink); }
.ns a.ns-chip--on, .ns a.ns-chip--on:hover { color: #fff; }
.ns-alink { font-size: 14px; font-weight: 500; }
.ns-alink:after { content: " \2192"; }

/* ==================================================================
   Chips + badges
   ================================================================== */
.ns-chip, .ns a.ns-chip { display: inline-flex; align-items: center; gap: 5px; background: #fff; border: 1px solid var(--ns-hairline-soft); border-radius: 999px; padding: 7px 15px; font-size: 12.5px; font-weight: 600; color: var(--ns-body); }
.ns a.ns-chip:hover { border-color: var(--ns-forest); color: var(--ns-forest); }
.ns-chip--on, .ns-chip--on:hover { background: var(--ns-ink); border-color: var(--ns-ink); color: #fff; }
/* Badge fills are one step darker than the wash panels they sit on
   (--ns-wash legend card, --ns-row-hover list rows). The old pale tints
   were ~1.03:1 against the legend and read as a single field of cream.
   Text stays AA: 7.4:1 verified, 4.6:1 unmatched. */
.ns-badge { display: inline-flex; align-items: center; gap: 5px; font-size: 11.5px; font-weight: 600; padding: 3px 10px; border-radius: 999px; vertical-align: middle; background: var(--ns-tone); color: var(--ns-ink); }
.ns-badge--verified { color: var(--ns-verify-dk); background: var(--ns-verify-tint); }
.ns-badge--unverified { color: var(--ns-warn-ink); background: var(--ns-wheat-border); }
.ns-feat-tag { font-size: 10.5px; font-weight: 600; letter-spacing: .05em; text-transform: uppercase; color: var(--ns-moss-deep); }

/* ==================================================================
   Grids & tiles (borderless)
   ================================================================== */
.ns-cols2 { display: grid; grid-template-columns: 1fr 1fr; gap: 36px; }
.ns-cols3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 32px; }
.ns-cols4 { display: grid; grid-template-columns: repeat(4, 1fr); gap: 28px; }
.ns-tile { display: block; color: var(--ns-ink); }
.ns-tile .ns-emo { margin-bottom: 12px; }
.ns-tile .ns-symptom-icon { display: block; width: 44px; height: 44px; }
.ns-tile h3 { margin-bottom: 4px; }
.ns-tile:hover h3 { color: var(--ns-forest); }

/* Cards that stay cards */
.ns-card { background: var(--ns-bg); border: 1px solid var(--ns-hair); border-radius: 14px; padding: 22px; }

/* ==================================================================
   Provider card
   ================================================================== */
.ns-provider-card { display: flex; gap: 16px; align-items: flex-start; border: 1px solid var(--ns-hair); border-radius: 14px; padding: 20px 22px; margin-bottom: 12px; background: var(--ns-bg); }
/* An explicit display value beats the UA's [hidden]{display:none}, so
   setting .hidden from JS silently does nothing on any of these. Every
   element the county and A–Z filters hide needs to be on this list:
   provider cards and the method note (provider filter), county cards,
   grids and letter headings (A–Z filter — without these, filtering left
   empty letter headings and their grid gaps behind). */
.ns-provider-card[hidden],
.ns-method-note[hidden],
.ns-county-grid[hidden],
.ns-letter[hidden] { display: none; }

/* County provider service filter.
   Three visually distinct states, in order of emphasis:
   rest    — white, soft hairline;
   hover   — wash fill + forest border/text (clearly "press me");
   active  — solid ink, white text (clearly "pressed").
   Hovering the active pill lightens it slightly so it still responds
   without ever being mistakable for an inactive one. */
.ns-svcfilter { display: flex; gap: 7px; flex-wrap: wrap; margin: 24px 0 10px; }
.ns-svcfilter .ns-chip { cursor: pointer; transition: background .12s, border-color .12s, color .12s; }
.ns .ns-svcfilter a.ns-chip:hover { background: var(--ns-forest-wash); border-color: var(--ns-forest); color: var(--ns-forest); }
.ns .ns-svcfilter a.ns-chip--on { background: var(--ns-ink); border-color: var(--ns-ink); color: #fff; }
.ns .ns-svcfilter a.ns-chip--on:hover { background: #33332F; border-color: #33332F; color: #fff; }
.ns-chip-n { font-weight: 700; font-size: 11px; opacity: .55; font-variant-numeric: tabular-nums; }
.ns-chip--on .ns-chip-n { opacity: .7; }
.ns-svcfilter-count { margin: 0 0 14px; min-height: 1em; }
.ns-svcfilter-count:empty { margin-bottom: 8px; }
.ns-provider-card--unv { border-style: dashed; }
.ns-provider-card .ns-pc-body { flex: 1; min-width: 0; }
.ns-pc-name { font-size: 16.5px; font-weight: 700; letter-spacing: -.01em; display: flex; gap: 9px; align-items: center; flex-wrap: wrap; }
.ns-pc-name a:hover { color: var(--ns-forest); }
.ns-lic-line { font-size: 12.5px; color: var(--ns-mut); margin-top: 5px; font-variant-numeric: tabular-nums; }
.ns-lic-line b { color: var(--ns-verify); font-weight: 600; }
.ns-pc-chips { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 10px; }
.ns-pc-acts { display: flex; flex-direction: column; gap: 8px; flex: 0 0 auto; }
.ns-avatar { flex: 0 0 44px; width: 44px; height: 44px; border-radius: 10px; background: var(--ns-tone); display: flex; align-items: center; justify-content: center; font-family: var(--ns-disp); font-weight: 600; color: var(--ns-forest); font-size: 15px; }

/* ==================================================================
   Tables — editorial system (Table Refresh Mockups 1a–1d).
   No cell borders: strong ink rule under the header, hairlines
   between rows, tabular semibold figures, one highlight row max.
   ================================================================== */
.ns table { width: 100%; border-collapse: collapse; border: none; font-size: 15px; line-height: 1.5; }
.ns th { text-align: left; padding: 0 24px 12px 0; font-weight: 700; font-size: 11px; letter-spacing: .12em; text-transform: uppercase; color: var(--ns-faint); background: none; border: none; border-bottom: 2px solid var(--ns-ink); }
.ns td { padding: 16px 24px 16px 0; border: none; border-bottom: 1px solid var(--ns-hairline); color: var(--ns-body); vertical-align: top; font-variant-numeric: tabular-nums; }
.ns th:last-child, .ns td:last-child { padding-right: 0; }
.ns td:first-child { font-weight: 600; color: var(--ns-ink); }
.ns td strong, .ns td b { font-weight: 600; color: var(--ns-ink); white-space: nowrap; }
.ns td em { font-style: normal; font-size: 14px; color: var(--ns-mut); }
.ns tbody tr:last-child td { border-bottom: none; }
.ns-prose tbody tr:hover td, .wp-block-table tbody tr:hover td { background: var(--ns-row-hover); }
.ns-prose figure.wp-block-table { margin: 2rem 0; }
.ns-prose .wp-block-table figcaption, .ns-prose table + figcaption { text-align: left; margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--ns-hairline); font-size: 12px; color: var(--ns-faint); }

/* Figures — the content lane's `figure.ns-figure` blocks and the theme-rendered
   set-2 figures (0.35.17) share this one rule, inside .ns-prose or not. */
.ns-figure { margin: 24px 0; }
.ns-figure img { display: block; width: 100%; height: auto; border-radius: 12px; border: 1px solid var(--ns-hairline); }
.ns-figure .wp-element-caption { text-align: left; font-size: 12px; color: var(--ns-faint); margin-top: 8px; }
.ns-figure--w800 { max-width: 800px; }
.ns .wp-block-table.is-style-stripes { border-bottom: none; }
.ns .wp-block-table.is-style-stripes tbody tr:nth-child(odd) { background: transparent; }

/* Utility: center every column but the first (frequency matrices) */
.ns-center-data td:not(:first-child), .ns-center-data th:not(:first-child) { text-align: center; padding-right: 0; }

/* Highlight row — cream tint + gold "most common" tag (one per table max) */
.ns tr.ns-highlight td { background: var(--ns-wheat); }
.ns tr.ns-highlight td:first-child { border-radius: 8px 0 0 8px; padding-left: 16px; }
.ns tr.ns-highlight td:last-child { border-radius: 0 8px 8px 0; padding-right: 16px; }
.ns-tag { display: inline-block; font-size: 10px; line-height: 1; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; background: var(--ns-gold-dk); color: var(--ns-ink); padding: 4px 8px; border-radius: 999px; }
.ns td .ns-tag { display: block; width: max-content; margin-top: 6px; }

/* Inline average bar (region tables — only where a sourced average exists) */
.ns-bar-wrap { display: flex; align-items: center; gap: 14px; }
.ns-bar-wrap > strong { width: 44px; font-weight: 600; color: var(--ns-ink); }
.ns-bar { width: 130px; height: 6px; border-radius: 3px; background: var(--ns-tone); }
.ns-bar > span { display: block; height: 6px; border-radius: 3px; background: var(--ns-forest); }

/* Stat band — replaces "at a glance" tables on cost guides */
.ns-statband { background: var(--ns-wash); border-radius: 12px; padding: 28px 30px; display: grid; grid-template-columns: repeat(4, 1fr); margin: 2rem 0; }
.ns-stat { padding: 0 24px; border-left: 1px solid var(--ns-hairline-soft); }
.ns-stat:first-child { padding-left: 0; border-left: none; }
.ns-stat:last-child { padding-right: 0; }
.ns-stat b { display: block; font-family: var(--ns-disp); font-size: 26px; font-weight: 700; letter-spacing: 0; color: var(--ns-ink); font-variant-numeric: tabular-nums; }
.ns-stat span { display: block; margin-top: 5px; font-size: 12px; color: var(--ns-mut); }

/* County "at a glance" band + tier key (0.36.10).
   Replaces the 360px fact card, the county locator PNG and the tier-strip
   PNG that stacked above the provider list. One band whose stats wrap to
   the screen, then a one-line tier key under the Providers heading that
   wraps rather than scales. Text and CSS only, so it is sharp at any
   density and never needs redrawing when a count moves. */
.ns-sec--glance { padding: 0 0 36px; }
.ns-sec--glance + .ns-rule + .ns-sec { padding-top: 40px; }
/* Desktop: the title and its link are one narrow column, the stats flow to
   its right at their natural width — a county with one fact is one short
   row, not a wide empty box. Below 760px the two stack. */
.ns-glance { display: grid; grid-template-columns: minmax(190px, 240px) minmax(0, 1fr); gap: 16px 36px; align-items: center; background: var(--ns-wash); border: 1px solid var(--ns-hairline); border-radius: 12px; padding: 20px 26px; }
.ns-glance-head { display: flex; flex-direction: column; align-items: flex-start; gap: 10px; }
.ns-glance-title { align-self: stretch; padding-bottom: 10px; border-bottom: 2px solid var(--ns-ink); font-size: 11px; font-weight: 700; letter-spacing: .14em; line-height: 1.4; text-transform: uppercase; color: var(--ns-faint); }
.ns .ns-glance-link { font-size: 13.5px; font-weight: 600; color: var(--ns-forest); }
.ns .ns-glance-link:hover { text-decoration: underline; text-underline-offset: 3px; }
.ns-glance-stats { display: flex; flex-wrap: wrap; gap: 16px 32px; margin: 0; }
.ns-glance-stat { flex: 0 1 auto; min-width: 130px; max-width: 280px; padding-left: 14px; border-left: 2px solid var(--ns-hairline-soft); }
.ns-glance-stat dt { margin: 0; font-size: 12px; font-weight: 400; line-height: 1.35; color: var(--ns-mut); }
.ns-glance-stat dd { margin: 4px 0 0; font-size: 16px; font-weight: 700; line-height: 1.3; color: var(--ns-ink); overflow-wrap: anywhere; }
.ns-glance-stat dd.ns-glance-n { font-family: var(--ns-disp); font-size: 28px; line-height: 1.05; letter-spacing: -.01em; font-variant-numeric: tabular-nums; }
.ns-glance-prose { margin-top: 32px; max-width: 72ch; }
.ns-tierkey { display: flex; flex-wrap: wrap; align-items: center; gap: 10px 14px; margin-top: 18px; font-size: 12.5px; color: var(--ns-mut); }
.ns-tierkey-h { font-weight: 600; }
.ns-tierkey-list { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin: 0; padding: 0; list-style: none; }
.ns-tierkey-list li { display: flex; align-items: center; gap: 6px; margin: 0; }
.ns-tierkey .ns-badge { font-size: 12px; padding: 4px 11px; }
.ns-tierkey-note { color: var(--ns-warn-ink); font-size: 12px; }
.ns .ns-tierkey-link { font-weight: 600; color: var(--ns-forest); }
.ns .ns-tierkey-link:hover { text-decoration: underline; text-underline-offset: 3px; }
@media (max-width: 760px) {
	.ns-glance { grid-template-columns: 1fr; padding: 16px 18px 18px; }
	.ns-glance-head { flex-direction: row; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 6px 16px; padding-bottom: 10px; border-bottom: 2px solid var(--ns-ink); }
	.ns-glance-title { align-self: auto; padding-bottom: 0; border-bottom: none; }
	.ns-glance-stats { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 130px), 1fr)); gap: 14px 16px; }
	.ns-glance-stat { min-width: 0; max-width: none; padding-left: 10px; }
	.ns-glance-stat dd.ns-glance-n { font-size: 24px; }
}

/* Methodology note — icon + text, vertically centered (mockup 1c fix) */
.ns-method-note { display: flex; align-items: center; gap: 7px; margin-top: 14px; font-size: 12px; color: var(--ns-faint); }
.ns-method-note .ns-i { display: inline-flex; width: 14px; height: 14px; border: 1px solid #C9C7B8; border-radius: 999px; align-items: center; justify-content: center; font-size: 9px; font-style: italic; font-weight: 700; flex: 0 0 auto; }
.ns-method-note a { font-weight: 600; color: var(--ns-forest); }

/* County editorial slots — fixed slots, not prose (NS_Editorial).
   Two card treatments, because the two states are genuinely different
   claims: a FILLED slot says something is true here (white card, like the
   permit authority cards it sits under), a NO-VARIATION slot says the state
   norm applies unchanged (wash card, the same recessive tone the fact panel
   uses). Unresearched slots have no treatment because they have no card.
   The source line is ruled off rather than merely small: it is the thing
   that makes the slot checkable, not a footnote to it. */
.ns-edslot { display: flex; flex-direction: column; }
.ns-edslot--norm { background: var(--ns-wash); border-color: var(--ns-hairline); }
.ns-edslot h3 { display: flex; align-items: center; gap: 8px; }
.ns-edslot .ns-ic { color: var(--ns-forest); }
.ns-edslot-body { margin-top: 10px; line-height: 1.75; }
.ns-edslot-body p { margin: 0 0 10px; }
.ns-edslot-body p:last-child { margin-bottom: 0; }
.ns-edslot-body b { color: var(--ns-ink); font-weight: 600; }
.ns-edslot-src { margin-top: auto; padding-top: 12px; border-top: 1px solid var(--ns-hairline); }
.ns-edslot-src a { color: var(--ns-mut); text-decoration: underline; text-decoration-color: var(--ns-hairline-soft); text-underline-offset: 3px; }
.ns-edslot-src a:hover { color: var(--ns-forest); }

/* Mobile: content tables collapse to stacked cards (mockup 1d) */
@media (max-width: 640px) {
	.ns-prose thead, .wp-block-table thead { display: none; }
	.ns-prose table, .ns-prose tbody, .wp-block-table table, .wp-block-table tbody { display: block; }
	.ns-prose tbody tr, .wp-block-table tbody tr { display: block; border: 1px solid var(--ns-hairline); border-radius: 12px; padding: 14px 16px; margin-bottom: 10px; background: #fff; }
	.ns-prose tbody td, .wp-block-table tbody td { display: block; border: none; padding: 2px 0; }
	.ns-prose tbody td:first-child, .wp-block-table tbody td:first-child { font-size: 13px; font-weight: 700; padding-bottom: 4px; }
	/* The column name the hidden <thead> would have given each cell (0.39.1).
	   data-label is written at render time by ns_child_table_labels(); a cell
	   without one (no thead, section row) prints nothing extra. */
	.ns-prose tbody td[data-label], .wp-block-table tbody td[data-label] { padding: 5px 0; }
	.ns-prose tbody td[data-label]::before, .wp-block-table tbody td[data-label]::before { content: attr(data-label); display: block; font-size: 10.5px; line-height: 1.3; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--ns-mut); margin-bottom: 2px; }
	.ns-prose td strong, .ns-prose td b, .wp-block-table td strong, .wp-block-table td b { font-size: 21px; }
	.ns-prose tbody tr:hover td, .wp-block-table tbody tr:hover td { background: transparent; }
	.ns-prose tr.ns-highlight, .wp-block-table tr.ns-highlight { background: var(--ns-wheat); border-color: var(--ns-wheat-border); }
	.ns-prose tr.ns-highlight td, .wp-block-table tr.ns-highlight td { background: transparent; padding-left: 0; padding-right: 0; border-radius: 0; }
	.ns-bar { width: 100%; }
	.ns-bar-wrap { flex-wrap: wrap; }
	.ns-statband { grid-template-columns: 1fr 1fr; gap: 18px 20px; padding: 20px; }
	.ns-stat { padding: 0; border-left: none; }
	.ns-stat b { font-size: 21px; }
}

/* Stats */
.ns-stats { display: grid; grid-template-columns: repeat(4, 1fr); gap: 28px; }
.ns-stats .n { font-family: var(--ns-disp); font-size: clamp(28px, 3.4vw, 38px); font-weight: 700; letter-spacing: -.02em; line-height: 1; font-variant-numeric: tabular-nums; }
.ns-stats .l { font-size: 13px; color: var(--ns-mut); margin-top: 8px; }
/* /how-we-verify/ live stat band (0.35.19): the band inside prose, boxed like a figure. */
.ns-stats--figure { margin: 24px 0 8px; padding: 22px 24px; border: 1px solid var(--ns-hairline); border-radius: 12px; background: var(--ns-wash, #F7F7F2); }
@media (max-width: 700px) { .ns-stats--figure { grid-template-columns: repeat(2, 1fr); gap: 18px; } }

/* FAQ */
.ns details { border-bottom: 1px solid var(--ns-hair); padding: 14px 2px; }
.ns details:first-of-type { border-top: 1px solid var(--ns-hair); }
.ns summary { font-weight: 600; font-size: 15.5px; cursor: pointer; }
.ns summary:hover { color: var(--ns-forest); }
.ns details p { margin: 8px 0 0; font-size: 14.5px; color: #4a463e; max-width: 700px; line-height: 1.6; }

/* License box */
.ns-license-block { background: var(--ns-verify-bg); border: 1px solid var(--ns-verify-hair); border-left-width: 1px; border-radius: 14px; padding: 24px; margin: 0; }
.ns-license-block h3 { display: flex; align-items: center; gap: 8px; color: var(--ns-verify); }
.ns-license-block th { border-color: #A8BC8E; color: #4A6532; }
.ns-license-block td { border-color: var(--ns-verify-hair); }
.ns-licfoot { display: flex; gap: 14px; flex-wrap: wrap; margin-top: 12px; font-size: 12.5px; color: #3A5426; }
/* Unverified: neutral card, not a hazard panel. The block addresses the
   homeowner (what to ask before hiring) and the unclaimed provider we want
   to convert in the same breath — a yellow alert served neither. Status is
   carried by the small amber chip; the card itself stays calm. */
.ns-license-block--unverified { background: var(--ns-bg); border-color: var(--ns-hairline-soft); }
.ns-license-block--unverified h3 { color: var(--ns-ink); }
.ns-license-block--unverified th { border-color: var(--ns-hairline); color: var(--ns-mut); }
.ns-license-block--unverified td { border-color: var(--ns-hairline); }
.ns-license-block--unverified .ns-licfoot { color: var(--ns-body); }
.ns-license-block--unverified .ns-licfoot a { color: var(--ns-forest); }
.ns-license-block--unverified .ns-licfoot a b { color: inherit; }
.ns-vchip { display: inline-flex; align-items: center; margin-left: 8px; padding: 3px 10px; border-radius: 999px; background: var(--ns-warn-bg); border: 1px solid #E8D9A8; color: var(--ns-warn-ink); font-size: 11px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; vertical-align: 2px; }

/* Quiet claim link under the provider hero actions — the moment an owner
   googling their own company decides whether to claim. */
.ns-claim-hint { font-size: 12.5px; color: var(--ns-mut); text-align: center; }
.ns-claim-hint b { color: var(--ns-forest); }
.ns-claim-hint:hover b { text-decoration: underline; text-underline-offset: 3px; }

/* Steps */
.ns-steps { counter-reset: s; }
.ns-step { display: flex; gap: 14px; align-items: flex-start; padding: 14px 0; border-bottom: 1px solid var(--ns-hair); font-size: 14.5px; line-height: 1.6; }
.ns-step::before { counter-increment: s; content: counter(s); flex: 0 0 24px; height: 24px; border-radius: 999px; border: 1px solid var(--ns-ink); display: flex; align-items: center; justify-content: center; font-weight: 600; font-size: 12px; }

/* Search + forms */
/* Search: the input has to hold "City, county, or ZIP — e.g. New Braunfels
   or 78130" without clipping, so it gets the lion's share of the row and the
   whole bar is wider. 20ch floor keeps the placeholder legible as the row
   shrinks (the e.g. tail may truncate on narrow phones — the label half
   survives, which is the half that instructs).
   --ns-search-h is the one number the three controls agree on: the theme
   sets an explicit height on inputs/selects, which beats flex stretch, so
   they used to sit ~6px shorter than the button no matter what the flex
   container did. Declaring the height on all three (button included) makes
   the row exact instead of coincidental.
   The select carries appearance:none from the parent theme, meaning no
   native arrow is drawn and no room is reserved for one — we draw the
   chevron and reserve the padding ourselves. Vertical centering is by
   line-height = height with zero vertical padding, because a select's
   text box does not honor flex alignment; the old 11px padding + 22.5px
   line-height needed 44.5px inside a 38px content box, which is what was
   clipping the option text top and bottom. */
.ns-search { --ns-search-h: 46px; display: flex; align-items: stretch; gap: 10px; background: var(--ns-bg); border: 1px solid var(--ns-hair); border-radius: 12px; padding: 8px; box-shadow: 0 1px 2px rgba(20,18,14,.04); max-width: 860px; }
.ns-search input,
.ns-search select,
.ns-search .ns-btn,
.ns-search button[type="submit"] { height: var(--ns-search-h); min-height: var(--ns-search-h); box-sizing: border-box; }
.ns-search input { flex: 1.75 1 0; min-width: 20ch; border: 0; padding: 0 14px; line-height: var(--ns-search-h); }
/* The generic `.ns select` / `.ns input[type=...]` rule below sets
   padding: 11px 13px and lands LATER in this file at equal specificity
   (0,1,1), so it silently won here: an 11px vertical padding inside a
   46px border-box leaves a 24px content box, while line-height is the
   full 46px — so the option text overflowed and clipped. Same class of
   bug as `.ns a` beating `.ns-btn` (LEARNINGS L-004). Re-assert with
   `.ns` prefixed (0,2,1) rather than reordering the file. */
.ns .ns-search input,
.ns .ns-search select { padding-top: 0; padding-bottom: 0; }
.ns .ns-search input { padding-left: 14px; padding-right: 14px; }
.ns .ns-search select { padding-left: 13px; padding-right: 34px; }
.ns-search select {
	flex: 1.25 1 0; min-width: 0; border: 0;
	background: var(--ns-wash);
	border-radius: 8px;
	/* Room for the chevron on the right; text ellipses rather than clips
	   if a service name ever outgrows the column. */
	padding: 0 34px 0 13px;
	line-height: var(--ns-search-h);
	text-overflow: ellipsis;
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5 6 6.5l5-5' fill='none' stroke='%236B6558' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
	background-repeat: no-repeat;
	background-position: right 13px center;
}
.ns-search .ns-btn, .ns-search button[type="submit"] { display: inline-flex; align-items: center; justify-content: center; white-space: nowrap; padding-top: 0; padding-bottom: 0; }
/* Small inline units that must never break across lines ("How we verify →"). */
.ns-nowrap { white-space: nowrap; }

/* ------------------------------------------------------------------
   Hero search typeahead.
   The native <datalist> stays in the markup for no-JS visitors, but its
   rendering is what we're replacing: Chrome draws a dropdown arrow inside
   the field and a bare UA flyout on click, neither of which matches the
   brand or can be styled. ns.js detaches the list attribute at boot and
   drives this panel instead. The datalist's own arrow is hidden for the
   no-JS case too — the field still autocompletes, just without chrome.
   ------------------------------------------------------------------ */
.ns-search input::-webkit-calendar-picker-indicator { display: none !important; opacity: 0; }
.ns-search { position: relative; }
.ns-suggest { position: absolute; top: calc(100% + 6px); z-index: 45; background: var(--ns-bg); border: 1px solid var(--ns-hair); border-radius: 10px; box-shadow: 0 8px 28px rgba(20,18,14,.12); max-height: 292px; overflow-y: auto; padding: 6px; margin: 0; list-style: none; }
.ns-suggest[hidden] { display: none; }
.ns-suggest li { padding: 9px 12px; border-radius: 7px; font-size: 14.5px; color: var(--ns-ink); cursor: pointer; }
.ns-suggest li b { color: var(--ns-forest); font-weight: 700; }
.ns-suggest li:hover, .ns-suggest li[aria-selected="true"] { background: var(--ns-forest-wash); color: var(--ns-forest); }
.ns-suggest .ns-suggest-note { padding: 8px 12px; font-size: 12px; color: var(--ns-faint); cursor: default; }
.ns-suggest .ns-suggest-note:hover { background: none; color: var(--ns-faint); }

/* Inline validation for an unrecognised county / malformed ZIP. */
.ns-search.is-invalid input { box-shadow: inset 0 0 0 1px var(--ns-danger, #B4453A); }
.ns-search-msg { margin: 8px 0 0; font-size: 12.5px; color: var(--ns-danger, #B4453A); font-weight: 500; }
.ns-search-msg:empty { display: none; }

/* "Use my location" — injected by ns.js after the search bar, only when
   geolocation can actually work. Styled as a quiet affordance, not a third
   button: the typed search stays the primary path. */
.ns-uselocate { display: inline-flex; align-items: center; gap: 6px; margin-top: 10px; padding: 0; border: 0; background: none; font-family: var(--ns-sans); font-size: 13px; font-weight: 600; color: var(--ns-forest); cursor: pointer; }
.ns-uselocate .ns-ic { width: 15px; height: 15px; }
.ns-uselocate:hover span { text-decoration: underline; }
.ns-uselocate[disabled] { color: var(--ns-mut); cursor: default; }
.ns-uselocate[disabled] span { text-decoration: none; }

/* Marker underline — a hand-drawn gold arc under a phrase in the hero H1.
   Inline SVG stroke rather than border-bottom so it keeps the sketched
   curve and imperfect ends. Sits behind the text, scales with the phrase,
   and works on the geo-variable headline where the wording changes. */
.ns-mark { position: relative; display: inline; color: var(--ns-forest); }
.ns-mark svg { position: absolute; left: 0; bottom: -.22em; width: 100%; height: .34em; overflow: visible; pointer-events: none; z-index: -1; }
.ns-mark path { fill: none; stroke: var(--ns-gold); stroke-width: 9; stroke-linecap: round; }
@media (prefers-reduced-motion: no-preference) {
	.ns-mark path { stroke-dasharray: 320; stroke-dashoffset: 320; animation: ns-mark-draw .75s cubic-bezier(.65,0,.35,1) .25s forwards; }
}
@keyframes ns-mark-draw { to { stroke-dashoffset: 0; } }
.ns input[type="text"], .ns input[type="email"], .ns input[type="tel"], .ns select, .ns textarea { border: 1px solid var(--ns-hair); border-radius: 8px; padding: 11px 13px; font-size: 14.5px; font-family: var(--ns-sans); color: var(--ns-ink); background: var(--ns-bg); width: 100%; }
.ns-qgrid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin-top: 22px; max-width: 760px; }
.ns-qgrid textarea { grid-column: 1 / -1; min-height: 64px; resize: vertical; }
.ns-visually-hidden { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }

/* Marquee — pauses on hover and on keyboard focus, so a county can
   actually be read and clicked instead of chased across the screen. */
.ns-marq { overflow: hidden; white-space: nowrap; padding: 14px 0; border-top: 1px solid var(--ns-hair); border-bottom: 1px solid var(--ns-hair); }
.ns-marq .in { display: inline-block; animation: ns-marq 40s linear infinite; font-size: 13px; color: var(--ns-mut); }
.ns-marq:hover .in, .ns-marq:focus-within .in { animation-play-state: paused; }
.ns-marq a { color: var(--ns-mut); padding: 4px 2px; border-radius: 5px; }
.ns-marq a b { color: var(--ns-ink); font-weight: 600; }
.ns-marq a:hover { color: var(--ns-forest); }
.ns-marq a:hover b { color: var(--ns-forest); text-decoration: underline; text-underline-offset: 3px; }
.ns-marq a:focus-visible { outline: 2px solid var(--ns-gold-dk); outline-offset: 1px; }
.ns-marq-sep { padding: 0 14px; color: var(--ns-faint); }
@keyframes ns-marq { from { transform: translateX(0); } to { transform: translateX(-50%); } }
@media (prefers-reduced-motion: reduce) { .ns-marq .in { animation: none; } }

/* Bands */
.ns-bandrow { display: flex; align-items: center; gap: 20px; flex-wrap: wrap; }
.ns-bandrow > div:first-child { flex: 1; min-width: 260px; }
/* Full-bleed dark band: breathe — inset the row so copy doesn't hug the
   page grid's left rail, and open up the text/CTA gap. */
.ns-sec--forest .ns-bandrow { padding: 10px clamp(8px, 4vw, 64px); gap: 48px; }

/* Feature line under the band headline. Was two &nbsp;s between items and
   baseline-aligned icons, which read as cramped and slightly off. Now a
   flex list: doubled horizontal spacing, and align-items:center so the
   glyph sits on the text's optical center rather than its baseline. */
.ns-featline { list-style: none; margin: 14px 0 0; padding: 0; display: flex; flex-wrap: wrap; align-items: center; gap: 10px 32px; font-size: 14px; color: var(--ns-meta-on-dark, #C7D6B4); }
.ns-featline li { display: flex; align-items: center; gap: 8px; line-height: 1; }
.ns-featline svg, .ns-featline .ns-ic { flex: none; display: block; }

/* ==================================================================
   Footer
   ================================================================== */
.ns-footer { background: var(--ns-char); color: #B3ADA3; font-size: 13.5px; padding: 56px 0 30px; }
.ns-footer h4 { color: #fff; font-size: 11px; letter-spacing: .08em; text-transform: uppercase; margin: 0 0 12px; }
.ns-footer a { color: #B3ADA3; display: block; padding: 3px 0; }
.ns-footer a:hover { color: #fff; }
.ns-flogo { color: #fff; display: flex; align-items: center; gap: 9px; }
.ns-flogo .ns-wm { font-family: var(--ns-sans); font-size: 15px; font-weight: 800; letter-spacing: 0; word-spacing: normal; }
.ns-flogo .ns-wm b { color: var(--v-sec-icon); font-weight: 800; }
/* Trademark notice on the wordmark lockup. U+2122 is already a raised glyph,
   so no <sup> and no vertical-align — either double-raises it and grows the
   line box. Under 1em, so it cannot change the lockup's line height. Selector
   is lockup-generic, not footer-scoped: if the header lockup ever carries the
   mark too it inherits this rather than rendering at full weight and size.

   Dropped so the mark's foot lands on the bottom of SEPTIC's C rather than
   floating at cap height. .30em is derived from Archivo's own outlines, not
   eyeballed: U+2122 has ymin .2822em at wght 700 and C bottoms at -.012em
   (round-letter overshoot), so at .66em the mark sits .2822 × .66 + .012 =
   .198em of the lockup too high — .30em of the mark's own font-size, which
   is what `top` resolves against. Verified by pixel-sampling a render with
   the Google-served Archivo woff2 embedded: C and mark bottom on the same
   row at 60px and at 120px. If you re-measure this, load the real font
   first — a fallback serif needs ~.38em and will send you to the wrong
   number. `position: relative` and not `vertical-align`, because a relative
   offset moves the glyph without touching the line box the comment above is
   protecting. */
.ns-wm .ns-tm { font-size: .66em; font-weight: 700; letter-spacing: 0; margin-left: 1px; position: relative; top: .30em; }
.ns-fcred { font-size: 12.5px; line-height: 1.7; margin-top: 12px; max-width: 460px; }
.ns-fsoc { display: flex; gap: 8px; margin-top: 16px; }
.ns-fsoc a { width: 30px; height: 30px; border: 1px solid #453F37; border-radius: 8px; display: flex; align-items: center; justify-content: center; padding: 0; font-size: 12px; font-weight: 700; }

/* Brand block owns its own row above the link columns — it was previously
   the first grid cell, which pinched the Counties column beside it. */
.ns-fbrand { padding-bottom: 30px; margin-bottom: 32px; border-bottom: 1px solid #3A352C; }

/* Section headings link to their parent hub. Keep the uppercase label
   styling; only the hover color signals the link. */
.ns-footer h4 a { color: inherit; display: inline; padding: 0; font: inherit; letter-spacing: inherit; }
.ns-footer h4 a:hover { color: var(--v-sec-icon); }
.ns-fgrid b { color: #DCD7C9; font-weight: 600; }

/* Columns are equal height and the "All … →" link sits on the floor of
   each, so those read as one row across the footer no matter how many
   links the content pipeline has shipped above them. */
.ns-fgrid > div { display: flex; flex-direction: column; }
.ns-fall { margin-top: auto; padding-top: 14px; }
/* The bold child was overriding the inherited link hover, so these were
   the only footer links with no hover state at all. */
.ns-footer a:hover b { color: #fff; }
.ns-fall:hover b { text-decoration: underline; text-underline-offset: 3px; }
@media (max-width: 760px) {
	/* Stacked columns have no shared floor to align to. */
	.ns-fall { margin-top: 0; padding-top: 3px; }
}

/* Columns are equal height (grid stretch) and each becomes a flex column,
   so the "All … →" link can be pushed to the bottom with margin-top:auto.
   That lines those links up as a row across the footer no matter how many
   links sit above them — which matters here because the columns are
   content-driven and their lengths change as the pipeline ships. */
.ns-fgrid > div { display: flex; flex-direction: column; align-items: flex-start; }
.ns-fall { margin-top: auto; padding-top: 14px; }
/* The <b> inside carried a fixed color, so these were the one set of
   footer links with no hover response at all. */
.ns-footer a:hover b { color: #fff; }
.ns-fall b { transition: color .12s; }
.ns-fall:hover b { text-decoration: underline; text-underline-offset: 3px; }
@media (prefers-reduced-motion: reduce) { .ns-fall b { transition: none; } }
@media (max-width: 760px) {
	/* Stacked columns have no shared baseline to align to. */
	.ns-fall { margin-top: 0; padding-top: 6px; }
}

.ns-flegal { border-top: 1px solid #3A352C; margin-top: 30px; padding-top: 18px; font-size: 11.5px; color: #898378; line-height: 1.65; } /* 4.63:1 on #1A1A19 (was #847E73, 4.32:1 — QA 2026-09-25) */
.ns-flegal p { margin: 0; }
.ns-flegal a { display: inline; padding: 0; color: #A8A296; text-decoration: none; }
.ns-flegal a:hover { color: #DCD7C9; }
/* Legal links sit on their own line, always — on a phone they were
   wrapping into the copyright and reading as one crowded run-on. */
.ns-flegal-row { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 10px 20px; margin-top: 12px; }
.ns-flegal-links { display: flex; flex-wrap: wrap; gap: 8px 18px; }

/* Cost calculator (T9) */
.ns-calcrow { margin-top: 16px; }
.ns-calcrow label { display: block; font-size: 13px; font-weight: 600; margin-bottom: 6px; color: var(--ns-ink); }
.ns-calcrow select { width: 100%; padding: 11px 12px; border: 1px solid var(--ns-hair); border-radius: 10px; font: inherit; font-size: 14.5px; background: #fff; color: var(--ns-ink); }
.ns-calcout { margin-top: 20px; }
.ns-calcres { background: var(--ns-wash); border: 1px solid var(--ns-hair); border-radius: 12px; padding: 20px; }
.ns-calcres--none b { color: var(--ns-forest); }
.ns-calcnum { font-family: var(--ns-disp); font-size: 32px; font-weight: 700; color: var(--ns-forest); letter-spacing: -.02em; font-variant-numeric: tabular-nums; }
.ns-calcsrc { font-size: 12.5px; color: var(--ns-mut); margin-top: 8px; line-height: 1.6; }
.ns-calcnote { font-size: 12.5px; color: var(--ns-mut); margin-top: 8px; line-height: 1.6; }
.ns-calcres .ns-btn, .ns-calcres a.ns-btn { margin-top: 14px; }

/* Free tools (0.32.0): checklist builder + pump-out reminder. Both lean on
   the calculator's form vocabulary (.ns-calcrow/.ns-calcres); below is only
   what those don't cover. */
.ns-cklq { border: 0; padding: 0; margin-top: 16px; }
.ns-cklq legend { font-size: 13px; font-weight: 600; margin-bottom: 6px; color: var(--ns-ink); padding: 0; }
.ns-cklopt { display: flex; gap: 9px; align-items: baseline; font-size: 14.5px; padding: 5px 0; cursor: pointer; }
.ns-cklopt input { accent-color: var(--ns-forest); flex: none; }
.ns-cklout h4 { font-size: 14px; margin: 18px 0 4px; color: var(--ns-forest); }
.ns-cklout ul { list-style: none; padding: 0; margin: 0; }
.ns-cklout li { padding: 0; margin: 0; }
.ns-cklcheck { display: flex; gap: 10px; align-items: baseline; padding: 7px 0; font-size: 14.5px; line-height: 1.6; border-bottom: 1px solid var(--ns-hair); cursor: pointer; }
.ns-cklcheck input { accent-color: var(--ns-forest); flex: none; }
.ns-cklcheck input:checked + span { color: var(--ns-mut); text-decoration: line-through; }
.ns-cklactions { margin-top: 14px; }
.ns-cklmail { margin-top: 18px; border-top: 1px solid var(--ns-hair); padding-top: 14px; }
.ns-cklmail label { font-size: 13.5px; display: block; margin-bottom: 8px; }
.ns-cklmailrow { display: flex; gap: 8px; }
.ns-cklmailrow input[type='email'] { flex: 1; min-width: 0; padding: 11px 12px; border: 1px solid var(--ns-hair); border-radius: 10px; font: inherit; font-size: 14.5px; }
.ns-remrow2 { display: grid; grid-template-columns: 1.4fr 1fr; gap: 8px; }
#ns-rem input[type='email'] { width: 100%; padding: 11px 12px; border: 1px solid var(--ns-hair); border-radius: 10px; font: inherit; font-size: 14.5px; }
@media (max-width: 560px) { .ns-cklmailrow { flex-direction: column; } }

/* Sizing calculator (T9, LA-09). Shares the calculator form vocabulary above;
   below is only what that does not cover.

   THE RESERVED OUTPUT BOX IS LOAD-BEARING, NOT DECORATION. The box carries a
   min-height AND a server-rendered placeholder of roughly the same shape, so
   the first answer replaces something the same size instead of appearing out
   of nothing. Inputs a state's rule does not read are dimmed and disabled in
   place rather than removed, for the same reason: the form never changes
   height when the state changes. NOT YET MEASURED AGAINST PIXELS — the
   reserve is sized by eye and wants one CLS reading in the QA pass.

   Provenance is carried in words, never in color alone: .ns-sizetag prints
   "our arithmetic" or "printed in the rule" as text, and the left rule is a
   second cue on top of the sentence, not the meaning. */
.ns-calcrow input[type='number'] { width: 100%; padding: 11px 12px; border: 1px solid var(--ns-hair); border-radius: 10px; font: inherit; font-size: 14.5px; background: #fff; color: var(--ns-ink); }
.ns-calcrow input[type='number']:disabled { background: var(--ns-wash); color: var(--ns-mut); }
/* WCAG 2.2 AA 2.5.8, target size. RE-MEASURED 2026-09-24 in a browser at
   375x812 on production, not carried from the 2026-09-10 note: the label
   box was 293 x 20.15 CSS px and the checkbox 13 x 13, both under the
   24 x 24 minimum. min-height lifts the clickable box to 293 x 24 and moves
   nothing else -- measured with the rule injected on the live page: checkbox
   still 13 x 13 at the same top, label top unchanged, row +3.86px, card
   +3.86px, document scrollWidth still 375 (no overflow), and a synthetic
   click 22px down the box -- outside the old 20.15px box -- toggled the
   input and fired exactly one change event. Sizing the input to 24 x 24 was
   the alternative and was not taken: it nearly doubles the visible checkbox.

   RECORDED WHILE MEASURING, not fixed here. `display`, `gap`, `font-size`
   and `margin-bottom` below have never applied. `.ns-calcrow label` above
   (0,1,1) outranks `.ns-sizecheck` (0,1,0) and wins with display:block,
   13px and margin-bottom:6px -- read off the live page, computed display
   "block" and font-size 13px against a rule that says flex and 14.5px. So
   the flex row this rule describes has never existed, and align-items is
   inert either way (set to center so it is right if flex is ever restored).
   Switching flex on re-flows the row -- 10px gap instead of a word space,
   14.5px text, no bottom margin -- and that is a design change, not an
   accessibility fix, so it is a separate decision with a separate look. */
.ns-sizecheck { display: flex; gap: 10px; align-items: center; min-height: 24px; font-size: 14.5px; font-weight: 600; color: var(--ns-ink); margin-bottom: 0; cursor: pointer; }
.ns-sizecheck input { accent-color: var(--ns-forest); flex: none; }
.ns-sizecheckrow { margin-top: 18px; }
/* The sizing calculator used to sit in the left half of a .ns-cols2 with
   three prose cards beside it. Those cards were verbatim copies of
   LA-09's post_content and now render from the body, so the card is
   centered at the width the old left column gave it (1180 wrap - 48
   padding - 36 gap, halved) instead of being stranded against an empty
   right-hand half. */
.ns-toolcol { max-width: 548px; margin: 0 auto; }
.ns-sizerow--off { opacity: .55; }
.ns-sizerow--off label { cursor: default; }
.ns-calcout--size { min-height: 380px; }
.ns-sizeunit { font-size: 13.5px; color: var(--ns-ink); margin-top: 6px; line-height: 1.6; }
.ns-sizeheadline { font-size: 15px; color: var(--ns-ink); line-height: 1.6; }
.ns-sizetag { font-size: 12.5px; color: var(--ns-mut); line-height: 1.6; margin-top: 12px; padding-left: 12px; border-left: 3px solid var(--ns-hair); }
.ns-sizework { margin: 12px 0 0; padding-left: 20px; font-size: 13px; color: var(--ns-body); line-height: 1.7; }
.ns-sizework li { margin-top: 6px; }
.ns-sizecite { display: inline-block; font-size: 11.5px; color: var(--ns-faint); font-variant-numeric: tabular-nums; }
.ns-sizeplaceholder { font-size: 13.5px; color: var(--ns-mut); line-height: 1.7; }
.ns-sizetablewrap { margin-top: 22px; overflow-x: auto; }
.ns-sizetable { min-width: 620px; }
.ns-sizetable th[scope='row'] { border-bottom: 1px solid var(--ns-hairline); font-size: 15px; letter-spacing: 0; text-transform: none; color: var(--ns-ink); padding: 16px 24px 16px 0; vertical-align: top; }
.ns-fgrid { display: grid; grid-template-columns: repeat(5, 1fr); gap: 28px; }
/* Four-column variant (2026-08 restructure): Services · Costs & permits ·
   Tools & resources · States + Company stacked. */
.ns-fgrid--4 { grid-template-columns: repeat(4, 1fr); }
/* Stacked groups inside the shared last column. The first group ends where
   the second begins; the column's .ns-fall floor logic is unaffected. */
.ns-fstack + .ns-fstack { margin-top: 26px; }
.ns-fgrid > div > .ns-fstack { display: flex; flex-direction: column; align-items: flex-start; }

/* State hub — A–Z county cards + letter nav */
/* County A–Z index — letter-grouped link columns (mockup 1b) */
.ns-az-bar { display: flex; flex-wrap: wrap; justify-content: center; gap: 6px; margin: 20px 0 4px; }
.ns-az-bar a { width: 30px; height: 30px; display: flex; align-items: center; justify-content: center; border: 1px solid var(--ns-hairline-soft); background: #fff; color: var(--ns-body); border-radius: 6px; font-size: 12.5px; font-weight: 700; }
.ns-az-bar a:hover { border-color: var(--ns-ink); color: var(--ns-ink); }

/* Sticky A–Z index on the state hub.
   The letter jump bar IS the secondary nav on a 254-row page — a section
   nav would only ever say "counties". Because it sticks inside the county
   section rather than the page, it pins while the list is in view and
   releases on its own at the end of it; no JS decides when it leaves.
   It lives inside .ns-wrap, so it breaks out to full width and pads back
   to the grid, otherwise content scrolls through a 1180px-wide bar. */
.ns-subnav--az {
	margin: 20px calc(50% - 50vw) 0;
	/* Was 4px top / 6px bottom plus an 8px margin on the bar inside it —
	   12px of space above the letter tiles and 15px below, which is the
	   asymmetry that read as bottom-heavy. Now symmetric, matching how
	   .ns-subnav-in pads the section-nav variant (9px 0, likewise treating
	   the 1px bottom border as a rule rather than as padding). */
	padding: 10px calc(50vw - 50%);
	background: rgba(253,252,249,.94);
	backdrop-filter: saturate(140%) blur(8px);
	-webkit-backdrop-filter: saturate(140%) blur(8px);
}
/* The bar's own margin would reintroduce the asymmetry it inherits from
   the non-sticky .ns-az-bar (20px 0 4px); the wrapper owns the spacing. */
.ns-subnav--az .ns-az-bar { margin: 0; }
@media (max-width: 900px) {
	/* Keep it sticky on phones — but as one scrollable row, since 26
	   wrapped letters would take a third of the screen. */
	.ns-subnav--az { position: sticky; }
	/* justify-content returns to flex-start here on purpose: centered flex
	   content that overflows a scroll container gets clipped at the start
	   edge and cannot be scrolled back to, so "A" would be unreachable. */
	.ns-subnav--az .ns-az-bar { flex-wrap: nowrap; justify-content: flex-start; overflow-x: auto; scrollbar-width: none; }
	.ns-subnav--az .ns-az-bar::-webkit-scrollbar { display: none; }
	.ns-subnav--az .ns-az-bar a { flex: none; }
}

/* Clears the main nav (60px) + the stuck A–Z bar, so a letter heading
   isn't hidden underneath after a jump. */
.ns-letter { display: flex; align-items: center; gap: 18px; margin-top: 34px; scroll-margin-top: 128px; }
.ns-letter b { font-family: var(--ns-disp); font-size: 25px; font-weight: 700; color: var(--ns-ink); line-height: 1; }
.ns-letter i { flex: 1; height: 1px; background: var(--ns-hairline); }
.ns-letter span { font-size: 12px; color: var(--ns-faint); white-space: nowrap; }
.ns-county-grid { margin-top: 12px; display: grid; grid-template-columns: repeat(4, 1fr); gap: 4px 36px; }
.ns-county-grid > div { padding: 8px 0; }
.ns-county-grid a { font-size: 15px; font-weight: 600; color: var(--ns-ink); }
.ns-county-grid a:hover { color: var(--ns-forest); text-decoration: underline; text-underline-offset: 3px; }
.ns-county-grid .ns-verified { font-size: 12.5px; font-weight: 600; color: var(--ns-forest); }
@media (max-width: 900px) { .ns-county-grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 480px) { .ns-county-grid { grid-template-columns: 1fr; } }
#ns-county-filter { max-width: 380px; }

/* "Near you" module on service pages — client-rendered, so its absence
   (JS off, out-of-coverage visitor, fetch failure) leaves no scar. */
.ns-near { margin-top: 34px; padding: 22px 24px; background: var(--ns-forest-wash); border: 1px solid var(--ns-forest-tint); border-radius: 14px; }
.ns-near[hidden] { display: none; }
.ns-near-head { display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; }
.ns-near-head h3 { margin: 0; }
.ns-near-switch { font-size: 12.5px; color: var(--ns-mut); }
.ns-near-switch a { color: var(--ns-forest); font-weight: 600; }
.ns-near-switch a:hover { text-decoration: underline; text-underline-offset: 3px; }
.ns-near-list { list-style: none; margin: 14px 0 0; padding: 0; }
.ns-near-list li { padding: 8px 0; border-bottom: 1px solid var(--ns-forest-tint); font-size: 14.5px; }
.ns-near-list li:last-child { border-bottom: 0; }
.ns-near-list a { font-weight: 600; }
.ns-near-serves { font-size: 12.5px; color: var(--ns-mut); }
.ns-near-more { margin: 10px 0 0; font-size: 13.5px; }
.ns-near-more a { color: var(--ns-forest); font-weight: 600; }
.ns-near-guides { margin: 12px 0 0; font-size: 13px; color: var(--ns-mut); }
.ns-near-guides a { color: var(--ns-forest); font-weight: 500; }

/* Coverage page — waitlist capture */
.ns-wlform { margin-top: 14px; }
.ns-wlform input[type="text"], .ns-wlform input[type="email"] { margin-bottom: 8px; }
.ns-wlrow { display: flex; gap: 8px; align-items: stretch; flex-wrap: wrap; }
.ns-wlrow input { flex: 1 1 200px; min-width: 0; margin-bottom: 0; }
.ns-wlrow .ns-btn { flex: 0 0 auto; white-space: nowrap; }
/* Honeypot: out of sight and out of the accessibility tree, but NOT
   display:none — some bots skip hidden fields, and some browsers skip
   validating them. Kept in the layout at zero size instead. */
.ns-hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }
@media (max-width: 480px) { .ns-wlrow .ns-btn { flex: 1 1 100%; } }

/* Fluent Forms embed — inherit the brand form language */
.ns-ffwrap { max-width: 760px; margin-top: 22px; } /* gap under the "Tell us once" dek — parity with .ns-qgrid */
.ns-ffwrap .ff-el-form-control { border: 1px solid var(--ns-hair) !important; border-radius: 8px !important; padding: 11px 13px !important; font-size: 14.5px !important; font-family: var(--ns-sans) !important; color: var(--ns-ink) !important; background: var(--ns-bg) !important; }
.ns-ffwrap .ff-el-input--label label { font-size: 12.5px; font-weight: 600; color: var(--ns-mut); }
.ns-ffwrap .ff-btn-submit { border-radius: 8px !important; padding: 11px 20px !important; font-size: 14px !important; font-weight: 600 !important; color: #fff !important; background: linear-gradient(180deg, var(--v-btn-rest-a), var(--v-btn-rest-b)) !important; border: 0 !important; font-family: var(--ns-sans) !important; }
.ns-ffwrap .ff-btn-submit:hover { background: linear-gradient(180deg, var(--v-primary), var(--v-btn-hover-b)) !important; }
.ns-ffwrap .ff-message-success { background: var(--ns-verify-bg); border: 1px solid var(--ns-verify-hair); border-radius: 12px; padding: 18px; color: #3A5426; }

/* Form height (0.39.28). Measured on the electrical quote form at 1156px
   before: 874px tall, every field 90px (25 label + 5 gap + 40 input + 20
   margin). After: 501px. Labels stay above the inputs — placeholder-only
   fields lose their name the moment someone types, and left-hand labels
   cost more scanning and break at phone width. The height comes out of the
   rhythm instead: tighter label gap and field margin, a shorter textarea,
   and at desktop width the two natural pairs (email + phone, services +
   county) share a row and the three timeline radios sit on one line. The
   pairing is name-based because septic's phone field is type=text; it is
   scoped to the quote form (data-ns-quote-county) so the contractor intake
   forms keep a single column. Below 640px nothing is paired and radios stay
   stacked at their 44px targets (the 860px block below). */
.ns-ffwrap .ff-el-group { margin-bottom: 14px !important; }
.ns-ffwrap .ff-el-input--label { margin-bottom: 4px !important; line-height: 1.2; }
.ns-ffwrap .ff-el-input--label label { line-height: 1.2; }
.ns-ffwrap textarea.ff-el-form-control { height: 104px !important; min-height: 104px !important; }
.ns-ffwrap .ff_submit_btn_wrapper { margin-top: 6px; margin-bottom: 0 !important; }
@media (min-width: 641px) {
	.ns-ffwrap .ff-el-form-check:has(> label > input[type="radio"]) { display: inline-block; margin: 0 22px 0 0 !important; }
	.ns-ffwrap .ff-el-form-check:has(> label > input[type="radio"]) .ff-el-form-check-label { margin: 0; min-height: 0; }
	.ns-ffwrap[data-ns-quote-county] .frm-fluent-form > fieldset { display: grid; grid-template-columns: 1fr 1fr; column-gap: 16px; }
	.ns-ffwrap[data-ns-quote-county] .frm-fluent-form > fieldset > * { grid-column: 1 / -1; }
	.ns-ffwrap[data-ns-quote-county] .frm-fluent-form > fieldset > .ff-el-group:has(input[name="email"]),
	.ns-ffwrap[data-ns-quote-county] .frm-fluent-form > fieldset > .ff-el-group:has(select[name="dropdown[]"]) { grid-column: 1; }
	.ns-ffwrap[data-ns-quote-county] .frm-fluent-form > fieldset > .ff-el-group:has(input[name="phone"]),
	.ns-ffwrap[data-ns-quote-county] .frm-fluent-form > fieldset > .ff-el-group:has(select[name="county"]) { grid-column: 2; }
}

/* SMS consent (2026-09-19 checkbox + 2026-09-20 restyle). Fine print, read as
   ONE unit: a hairline above sets it apart from the fields, the box sits on the
   first line of the sentence, and the Terms · Privacy line hangs under the
   sentence at the same indent. The links are a separate custom_html field on
   purpose (docs/fluent-forms.md — HTML in the option label leaks into
   aria-label), so the two groups are joined here by spacing, not by markup.
   Text: 13.5px muted. It is a disclosure, not a field. */
.ns-ffwrap .ns-sms-consent-box { margin: 26px 0 0; padding: 18px 0 0; border-top: 1px solid var(--ns-hair); }
.ns-ffwrap .ns-sms-consent-box .ff-el-form-check { margin: 0; }
.ns-ffwrap .ns-sms-consent-box .ff-el-form-check-label {
	display: flex; align-items: flex-start; gap: 12px; margin: 0; min-height: 0;
	font-family: var(--ns-sans); font-size: 13.5px; line-height: 1.55; font-weight: 400; color: var(--ns-mut); cursor: pointer;
}
.ns-ffwrap .ns-sms-consent-box .ff-el-form-check-input { flex: 0 0 auto; width: 18px; height: 18px; margin: 3px 0 0; accent-color: var(--v-primary); }
.ns-ffwrap .ff-custom_html:has(> .ns-sms-consent-links) { margin: 6px 0 24px; }
.ns-ffwrap .ns-sms-consent-links { margin: 0 !important; /* a broader p rule gives it 26px left */ padding-left: 28px; font-family: var(--ns-sans); font-size: 13px; line-height: 1.5; color: var(--ns-faint); }
.ns-ffwrap .ns-sms-consent-links a { color: var(--v-primary); text-decoration: underline; text-underline-offset: 2px; }
.ns-ffwrap .ns-sms-consent-links a:hover { text-decoration-thickness: 2px; }

/* Sticky mobile CTA bar */
.ns-msticky { display: none; }

/* Legacy call CTA (plugin output) */
.ns-call-cta { display: inline-block; font-weight: 700; }
.ns-call-plain { font-weight: 600; }

/* ==================================================================
   Responsive
   ================================================================== */
@media (max-width: 960px) {
	.ns-cols4 { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 760px) {
	.ns-nav-links, .ns-nav-cta { display: none; }
	.ns-burger { display: block; }
	.ns-cols2, .ns-cols3, .ns-stats, .ns-qgrid, .ns-fgrid { grid-template-columns: 1fr 1fr; }
	.ns-search { flex-direction: column; padding: 10px; }
	.ns-search input, .ns-search select { border: 1px solid var(--ns-hair); }
	.ns-provider-card { flex-direction: column; }
	.ns-pc-acts { flex-direction: row; width: 100%; }
	.ns-pc-acts .ns-btn { flex: 1; }
	.ns-sec { padding: 40px 0; }
	.ns-sec--hero { padding: 48px 0 36px; }
	.ns-msticky { display: flex; position: sticky; bottom: 0; z-index: 30; background: #fff; border-top: 1px solid var(--ns-hair); padding: 10px 12px; gap: 10px; box-shadow: 0 -4px 16px rgba(20,18,14,.08); }
	.ns-msticky .ns-btn { flex: 1; }
	.ns-call-cta { display: block; text-align: center; padding: .85em 1em; border-radius: 8px; background: linear-gradient(180deg, #FFD26B, #F8BE3E); color: var(--ns-ink); }
}
@media (max-width: 480px) {
	.ns-cols3, .ns-cols4, .ns-qgrid { grid-template-columns: 1fr; }
	.ns-stats, .ns-fgrid { grid-template-columns: 1fr 1fr; }
	/* Phone portrait (iPhone Pro ≈ 402pt): nothing sits in a half-width
	   column. The calculator and its two explainer panels each take the
	   full measure — at ~190px a two-up panel wraps every few words. */
	.ns-cols2 { grid-template-columns: 1fr; }
	.ns-calcres, .ns-panel, .ns-fact-panel { width: 100%; }
	.ns-wrap { padding: 0 18px; }
}

/* ==================================================================
   Sticky section nav + back-to-top (directory & long-form pages)
   ================================================================== */
/* Sits directly under the main nav, which is 60px tall and already
   sticky — top is expressed against that so the two never overlap.
   Below 900px it un-sticks: two stacked bars eat a third of a phone
   screen, so the floating back-to-top button covers mobile instead. */
.ns-subnav { position: sticky; top: 60px; z-index: 28; background: rgba(253,252,249,.94); backdrop-filter: saturate(140%) blur(8px); border-bottom: 1px solid var(--ns-hair); margin-bottom: 28px; }
body.admin-bar .ns-subnav { top: 92px; }
.ns-subnav-in { display: flex; gap: 4px; overflow-x: auto; scrollbar-width: none; padding: 9px 0; }
.ns-subnav-in::-webkit-scrollbar { display: none; }
.ns-subnav a { white-space: nowrap; font-size: 13.5px; font-weight: 600; color: var(--ns-body); padding: 6px 12px; border-radius: 999px; }
.ns-subnav a:hover { color: var(--ns-ink); background: var(--ns-wash); }
.ns-subnav a.is-on { color: var(--ns-ink); background: var(--ns-forest-wash); }
/* Retracts once the reader is past the content it indexes (see ns.js).
   Transform rather than display so it slides out instead of blinking,
   and pointer-events:none keeps it untabbable while hidden. */
.ns-subnav { transition: transform .22s ease, opacity .22s ease; }
.ns-subnav.is-gone { transform: translateY(-100%); opacity: 0; pointer-events: none; }
@media (max-width: 900px) {
	.ns-subnav { position: static; margin-bottom: 20px; transition: none; }
	.ns-subnav.is-gone { transform: none; opacity: 1; pointer-events: auto; }
}
@media (prefers-reduced-motion: reduce) {
	.ns-subnav { transition: none; }
}

.ns-totop { position: fixed; right: 16px; bottom: 16px; z-index: 40; display: flex; align-items: center; gap: 6px; font: inherit; font-size: 13px; font-weight: 600; color: var(--ns-ink); background: var(--ns-bg); border: 1px solid var(--ns-hair); border-radius: 999px; padding: 9px 15px; cursor: pointer; box-shadow: 0 3px 14px rgba(20,18,14,.13); opacity: 0; visibility: hidden; transform: translateY(8px); transition: opacity .18s, transform .18s, visibility .18s; }
.ns-totop.is-on { opacity: 1; visibility: visible; transform: none; }
.ns-totop:hover { border-color: var(--ns-ink); }
@media (max-width: 760px) {
	/* Default to the normal inset. The 74px lift exists only to clear the
	   sticky mobile CTA bar, and that bar is on county/county-service/
	   provider pages only — everywhere else the button was floating 74px
	   off the floor for no reason. ns.js sets .ns-has-msticky on <body>
	   when the bar is actually present. */
	.ns-totop { bottom: 16px; right: 12px; }
	body.ns-has-msticky .ns-totop { bottom: 74px; }
	/* Once the CTA bar retracts, the button drops back down with it. */
	body.ns-has-msticky .ns-msticky.is-gone ~ .ns-totop,
	body.ns-has-msticky.ns-msticky-gone .ns-totop { bottom: 16px; }
}

/* The mobile CTA bar leaves at the same point the back-to-top button does:
   it is pinned to the bottom of the screen, so past the quote band it is
   sitting on the form it is trying to send people to. */
.ns-msticky { transition: transform .22s ease, opacity .22s ease; }
.ns-msticky.is-gone { transform: translateY(110%); opacity: 0; pointer-events: none; }
@media (prefers-reduced-motion: reduce) { .ns-msticky { transition: none; } }
@media (prefers-reduced-motion: reduce) {
	.ns-totop { transition: none; }
}

/* ==================================================================
   County map — server-rendered SVG, one <a> per county
   ================================================================== */
.ns-map { margin-top: 26px; }
.ns-map svg { width: 100%; height: auto; display: block; }
.ns-map-c { stroke: var(--ns-bg); stroke-width: 1; fill: var(--ns-wash); transition: fill .12s; }
.ns-map-c--0 { fill: #EFEDE6; }
.ns-map-c--1 { fill: #CBD9AE; }
.ns-map-c--2 { fill: #9DB86F; }
.ns-map-c--3 { fill: var(--ns-forest); }
.ns-map-c--off { fill: #F4F2EC; }
.ns-map a:hover .ns-map-c { fill: var(--ns-gold); }
.ns-map a:focus-visible { outline: none; }
.ns-map a:focus-visible .ns-map-c { fill: var(--ns-gold); stroke: var(--ns-ink); stroke-width: 2; }
.ns-map-key { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px; margin-top: 14px; font-size: 12.5px; color: var(--ns-mut); }
.ns-map-sw { width: 14px; height: 14px; border-radius: 3px; display: inline-block; }
.ns-map-sw--0 { background: #EFEDE6; }
.ns-map-sw--1 { background: #CBD9AE; }
.ns-map-sw--2 { background: #9DB86F; }
.ns-map-sw--3 { background: var(--ns-forest); }
@media (prefers-reduced-motion: reduce) { .ns-map-c { transition: none; } }

/* Form trust cue — rural visitors are handing over a phone number to a
   site they just met; say plainly what happens to it. */
.ns-formtrust { display: flex; align-items: flex-start; gap: 8px; margin-top: 14px; font-size: 12.5px; line-height: 1.6; color: var(--ns-mut); }
.ns-formtrust svg, .ns-formtrust .ns-ic { flex: none; width: 15px; height: 15px; margin-top: 1px; color: var(--ns-forest); }
.ns-formtrust b { color: var(--ns-body); font-weight: 600; }

/* ==================================================================
   Empty states (404, zero-provider counties, empty sections)
   ================================================================== */
.ns-empty { text-align: center; border: 1px dashed #CBC5B4; border-radius: 14px; padding: 40px 28px; }
.ns-empty .ns-ic { width: 30px; height: 30px; color: var(--ns-moss-deep); }
.ns-empty h3 { margin-top: 12px; font-size: 18px; }
.ns-empty p { margin: 8px auto 0; max-width: 460px; }
.ns-empty .ns-btn { margin-top: 18px; }
.ns-404-code { font-family: var(--ns-disp); font-weight: 600; font-size: 15px; letter-spacing: .12em; color: var(--ns-moss-deep); }

/* ==================================================================
   Print — permit guides & printable resources
   ================================================================== */
.ns-printhead { display: none; }
@media print {
	@page { margin: 1.6cm; }
	body { background: #fff !important; }
	#wpadminbar, .ns-nav, .ns-footer, .ns-msticky, .ns-marq, .ns-blob, .ns-skip,
	.ns-search, .ns-qgrid, form, .ns-btn, button,
	.ns-sec--band, .ns-sec [data-qform], #quote { display: none !important; }
	.ns { font-size: 11.5pt; color: #000; background: #fff; }
	.ns-printhead { display: block; font-family: var(--ns-sans); font-size: 9.5pt; color: #333; border-bottom: 1pt solid #000; padding: 0 0 6pt; margin-bottom: 14pt; }
	.ns-sec, .ns-sec--hero, .ns-sec--wash { padding: 10pt 0 !important; background: #fff !important; }
	.ns-wrap { max-width: none; padding: 0; }
	h1 { font-size: 22pt; } h2 { font-size: 15pt; }
	.ns a { color: #000; text-decoration: none; }
	.ns-sec a[href^="http"]:not(.ns-btn):after { content: " (" attr(href) ")"; font-size: 8.5pt; color: #444; word-break: break-all; }
	.ns a[href^="tel:"]:after { content: none; }
	.ns th { color: #000; border-bottom: 1.5pt solid #000; }
	.ns td { border-bottom: .5pt solid #999; }
	.ns details { border: none; padding: 6pt 0; }
	.ns details > * { display: block; }
	.ns summary { list-style: none; }
	.ns summary::-webkit-details-marker { display: none; }
	.ns-card, .ns-license-block { border: 1pt solid #000; border-radius: 0; break-inside: avoid; }
	.ns-step, .ns-provider-card, .ns details, table { break-inside: avoid; }
	/* Checklist builder: print only the built checklist, with its boxes. */
	#ns-ckl, .ns-cklmail, .ns-cklactions, #ns-ckl-intro { display: none !important; }
	.ns-cklcheck { border-bottom: .5pt solid #999; }
	.ns-cklcheck input { -webkit-appearance: none; appearance: none; width: 10pt; height: 10pt; border: 1pt solid #000; border-radius: 2pt; }
	.ns-cols2, .ns-cols3 { display: block; }
	.ns-cols2 > div, .ns-cols3 > div { margin-bottom: 10pt; }
}

/* ==========================================================================
   Provider directory + profile — v4 mock parity
   Source: "Nearby Septic - Provider Pages.html" (Ross, 2026-08-13).
   Palette is mapped onto the existing --ns-* tokens rather than the mock's
   raw hex, so the brand system stays the single source of color truth.
   ========================================================================== */

/* --- Global: reclaim the dead band between nav and breadcrumbs -----------
   The hero opened with 64px of top padding on every template. On an
   interior page the first thing under the nav is a breadcrumb, so that
   band read as wasted space. The homepage is the one place the air is
   doing work, and it keeps it via --hero-tall. */
.ns-sec--hero { padding: 24px 0 34px; }
.ns-sec--hero-tall { padding: 64px 0 48px; }

/* H1 at display weight. Was 700; the mock sets 800 with tighter tracking,
   which is what gives a provider name its presence at the top of a page. */
.ns h1 { font-weight: 800; letter-spacing: -.028em; line-height: 1.05; }

/* --- Badge legend (directory hero, right rail) --------------------------- */
.ns-legend { border: 1px solid var(--ns-hairline); border-radius: 16px; padding: 22px 24px 20px; background: var(--ns-wash); }
.ns-legend-h { font-size: 11.5px; font-weight: 700; letter-spacing: .13em; text-transform: uppercase; color: var(--ns-mut); margin-bottom: 16px; }
h2.ns-legend-h { margin-top: 0; line-height: 1.3; font-family: inherit; }
.ns-legend-row { display: flex; gap: 12px; align-items: flex-start; margin-bottom: 15px; }
.ns-legend-row:last-of-type { margin-bottom: 0; }
.ns-legend-row p { margin: 0; font-size: 13.5px; line-height: 1.45; color: var(--ns-body); }
.ns-legend-foot { margin: 17px 0 0; padding-top: 15px; border-top: 1px solid var(--ns-hairline); font-size: 12.5px; line-height: 1.45; color: var(--ns-mut); }

/* "How we verify" — arrow slides, rule darkens. */

.ns-dirhero { display: grid; grid-template-columns: minmax(0,1fr) 352px; gap: 44px; align-items: start; }

/* --- Sticky filter bar ---------------------------------------------------
   State cards are the primary choice at rest; once the page scrolls past
   them they collapse into a compact select so the bar stays one row deep.
   The swap is CSS-only (a data-stuck flag toggled by a tiny scroll
   listener), so it degrades to the full bar with JS off.

   .ns-stickyzone is the containing block that bounds how far the bar
   follows. It wraps the bar and the results section (pager included), and a
   sticky element stops sticking at its containing block's bottom edge — so
   the bar scrolls out of view past the pagination instead of riding over the
   prefooter and footer. No overflow or transform may be set on this wrapper:
   either one would make it a new containing block for the fixed/sticky
   descendant and kill the stick entirely. */
.ns-stickyzone { position: relative; }
.ns-filterbar { position: sticky; top: 60px; z-index: 29; background: var(--ns-forest-wash); border-top: 1px solid var(--ns-hair-warm); border-bottom: 1px solid var(--ns-hair-warm); }
/* Filter and letter links carry #providers so a reload lands on the results.
   Without a scroll offset the sticky header + filter bar sit on top of the
   first row, so the visitor arrives looking at a covered heading. Matches the
   128px .ns-letter already uses for the state-hub A–Z jumps. */
#providers { scroll-margin-top: 128px; }
.ns-filterbar .ns-wrap { padding-top: 0; padding-bottom: 0; }
.ns-staterow { display: flex; gap: 10px; padding: 18px 0 0; flex-wrap: wrap; }
.ns-filterbar[data-stuck="true"] .ns-staterow { display: none; }
.ns-filterbar[data-stuck="true"] .ns-statesel { display: block; }
.ns-statesel { display: none; flex: none; height: 46px; padding: 0 12px; background: var(--ns-forest-dk); border: 1px solid var(--ns-forest-dk); border-radius: 10px; font-size: 14.5px; font-weight: 600; color: #fff; cursor: pointer; }
.ns-statecard { flex: 1 1 200px; display: flex; flex-direction: column; gap: 3px; align-items: flex-start; padding: 13px 18px; border-radius: 12px; border: 1px solid var(--ns-hair-warm); background: #FBFCF8; cursor: pointer; text-align: left; text-decoration: none; transition: transform .15s ease, box-shadow .15s ease, border-color .15s ease, background .15s ease; }
.ns-statecard:hover { transform: translateY(-2px); box-shadow: 0 8px 20px rgba(23,26,21,.08); border-color: var(--ns-moss); background: #fff; text-decoration: none; }
.ns-statecard b { font-size: 15.5px; font-weight: 700; color: var(--ns-ink); }
/* The abbreviation exists in the markup on every card and is shown only
   in the phone pill row. Hidden here rather than absent, so one template
   serves both and the swap is a media query. */
.ns-statecard .ns-sc-abbr { display: none; }
.ns-statecard span { font-size: 12.5px; color: var(--ns-mut); }
.ns-statecard[aria-current="true"] { background: var(--ns-forest-dk); border-color: var(--ns-forest-dk); }
.ns-statecard[aria-current="true"] b, .ns-statecard[aria-current="true"] span { color: #fff; }

.ns-filterrow { display: flex; gap: 10px; align-items: center; padding: 16px 0; flex-wrap: wrap; }
.ns-fsearch { flex: 2 1 300px; display: flex; align-items: center; gap: 9px; height: 46px; padding: 0 14px; background: #fff; border: 1px solid var(--ns-hair-warm); border-radius: 10px; transition: border-color .15s ease; }
.ns-fsearch:focus-within, .ns-fsearch:hover { border-color: var(--ns-moss); }
.ns-fsearch input { flex: 1; border: 0; outline: 0; background: transparent; font-size: 15px; color: var(--ns-ink); min-width: 0; }
.ns-fsel { flex: 1 1 190px; height: 46px; padding: 0 12px; background: #fff; border: 1px solid var(--ns-hair-warm); border-radius: 10px; font-size: 15px; color: var(--ns-ink); cursor: pointer; }
.ns-fsel:hover { border-color: var(--ns-moss); }
/* Was an inline `style="flex:1 1 160px"` on the city field. Inline beats
   every stylesheet, and on a phone — where the row is a column and
   flex-basis therefore sizes HEIGHT — it made that one input 160px tall.
   Same desktop result, now overridable. */
.ns-fsel--city { flex: 1 1 160px; }
.ns-ftoggle { flex: none; display: inline-flex; align-items: center; gap: 9px; height: 46px; padding: 0 16px; border-radius: 10px; border: 1px solid var(--ns-hair-warm); background: #fff; cursor: pointer; font-size: 14.5px; font-weight: 600; color: var(--ns-ink); transition: border-color .15s ease, background .15s ease; }
.ns-ftoggle:hover { border-color: var(--ns-moss); background: #F7FAF1; }
.ns-ftoggle i { width: 34px; height: 20px; border-radius: 999px; background: #DFE4D2; position: relative; display: inline-block; transition: background .18s ease; font-style: normal; }
.ns-ftoggle i b { position: absolute; top: 2px; left: 2px; width: 16px; height: 16px; border-radius: 50%; background: #fff; box-shadow: 0 1px 2px rgba(0,0,0,.2); transition: transform .18s ease; display: block; }
.ns-ftoggle[aria-pressed="true"] { border-color: var(--ns-moss); background: #F3F8EA; }
.ns-ftoggle[aria-pressed="true"] i { background: var(--ns-forest); }
.ns-ftoggle[aria-pressed="true"] i b { transform: translateX(14px); }

/* Alphabet rail — shared with the /state/ page banner (.ns-subnav--az). */

.ns-chiprow { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; padding: 0 0 14px; }
.ns-fchip { display: inline-flex; align-items: center; gap: 7px; height: 30px; padding: 0 11px; border-radius: 999px; border: 1px solid var(--ns-hair-warm); background: #fff; font-size: 13px; color: var(--ns-body); text-decoration: none; }
.ns-fchip:hover { border-color: var(--ns-moss); text-decoration: none; }
.ns-fchip b { font-weight: 600; }
.ns-clearall { border: 0; background: transparent; padding: 0; cursor: pointer; font-size: 13px; color: var(--ns-mut); text-decoration: underline; text-underline-offset: 3px; font-family: inherit; }
.ns-clearall:hover { color: var(--ns-ink); }

/* --- Provider cards ------------------------------------------------------ */
.ns-pgrid { display: grid; grid-template-columns: repeat(auto-fill, minmax(352px, 1fr)); gap: 16px; }
.ns-pcard { display: flex; flex-direction: column; padding: 20px 22px 16px; background: #fff; border: 1px solid var(--ns-hairline); border-radius: 14px; min-height: 238px; transition: transform .16s ease, box-shadow .16s ease, border-color .16s ease; position: relative; }
.ns-pcard:hover { transform: translateY(-3px); box-shadow: 0 14px 30px rgba(23,26,21,.10); border-color: #B9C9A6; }
.ns-pcard-top { display: flex; align-items: center; gap: 10px; margin-bottom: 12px; }
.ns-pcard-checked { margin-left: auto; font-size: 11px; color: var(--ns-faint); white-space: nowrap; font-variant-numeric: tabular-nums; }
.ns-pcard h3 { margin: 0 0 7px; font-size: 19px; line-height: 1.22; letter-spacing: -.012em; font-weight: 700; }
.ns-pcard h3 a { color: var(--ns-ink); text-decoration: none; }
/* Whole-card target without nesting interactive elements inside a link. */
.ns-pcard h3 a::after { content: ""; position: absolute; inset: 0; }
.ns-pcard h3 a:hover { color: var(--ns-forest); text-decoration: none; }
.ns-pcard-geo { display: flex; align-items: center; gap: 7px; font-size: 13.5px; color: var(--ns-body); margin-bottom: 14px; flex-wrap: wrap; }
.ns-pcard-geo .ns-cty { color: var(--ns-forest); font-weight: 600; }
.ns-pcard-lic { display: flex; align-items: baseline; gap: 8px; padding: 9px 11px; background: #FAFAF5; border: 1px solid #EDEEE5; border-radius: 8px; margin-bottom: 12px; font-size: 12px; color: var(--ns-mut); }
.ns-pcard-lic b { margin-left: auto; font-weight: 400; color: var(--ns-body); font-variant-numeric: tabular-nums; }
.ns-pcard-chips { display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 16px; }
.ns-pcard-chips span { padding: 4px 9px; border: 1px solid var(--ns-hairline); border-radius: 999px; font-size: 12px; color: var(--ns-body); background: #fff; }
.ns-pcard-foot { margin-top: auto; padding-top: 14px; border-top: 1px solid #EFF0E8; display: flex; align-items: center; gap: 10px; }
.ns-pcard-foot a.ns-tel { font-size: 14.5px; font-weight: 600; color: var(--ns-ink); text-decoration: none; letter-spacing: -.01em; position: relative; z-index: 1; }
.ns-pcard-foot a.ns-tel:hover { color: var(--ns-forest); }

.ns-emptybox { padding: 64px 24px; text-align: center; border: 1px dashed var(--ns-hair-warm); border-radius: 16px; background: var(--ns-wash); }

/* --- Pagination ---------------------------------------------------------- */
.ns-pager { display: flex; align-items: center; gap: 24px; padding-top: 20px; margin-top: 26px; border-top: 1px solid var(--ns-hairline); flex-wrap: wrap; }
.ns-pager-range { margin: 0; font-size: 13.5px; color: var(--ns-mut); flex: 0 0 auto; min-width: 150px; }
.ns-pager-nums { display: flex; align-items: center; gap: 6px; margin: 0 auto; flex-wrap: wrap; justify-content: center; }
.ns-pager-nums a, .ns-pager-nums span { min-width: 44px; height: 44px; padding: 0 12px; display: inline-flex; align-items: center; justify-content: center; border-radius: 10px; border: 1px solid var(--ns-hairline); background: #fff; font-size: 14.5px; font-weight: 600; color: var(--ns-body); text-decoration: none; transition: background .15s ease, color .15s ease, border-color .15s ease; }
.ns-pager-nums a:hover { background: var(--ns-forest-wash); border-color: var(--ns-moss); color: var(--ns-ink); text-decoration: none; }
.ns-pager-nums .current { background: var(--ns-forest-dk); border-color: var(--ns-forest-dk); color: #fff; }
.ns-pager-nums .dots { border-color: transparent; background: transparent; min-width: 24px; }
.ns-pager-nums .prev, .ns-pager-nums .next { padding: 0 18px; border-color: var(--ns-hair-warm); color: var(--ns-ink); }
.ns-pager-jump { display: flex; align-items: center; gap: 9px; font-size: 13.5px; color: var(--ns-mut); flex: 0 0 auto; }
.ns-pager-jump input { width: 68px; height: 40px; padding: 0 10px; border: 1px solid var(--ns-hair-warm); border-radius: 9px; font-size: 14.5px; background: #fff; }
.ns-pager-jump input:focus { border-color: var(--ns-forest); outline: 0; }
.ns-pager-jump button { height: 40px; padding: 0 14px; border-radius: 9px; border: 1px solid var(--ns-hair-warm); background: #fff; cursor: pointer; font-size: 14px; font-weight: 600; color: var(--ns-ink); font-family: inherit; }
.ns-pager-jump button:hover { background: var(--ns-forest-wash); border-color: var(--ns-moss); }

/* --- Profile ------------------------------------------------------------- */
.ns-prof { display: grid; grid-template-columns: minmax(420px,1fr) 336px; gap: 44px; align-items: start; }
.ns-prof-aside { display: flex; flex-direction: column; gap: 16px; position: sticky; top: 88px; }
.ns-statstrip { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px,1fr)); border: 1px solid var(--ns-hairline); border-radius: 14px; overflow: hidden; margin-bottom: 30px; }
.ns-statstrip > div { padding: 15px 18px; border-right: 1px solid #EFF0E8; }
.ns-statstrip > div:last-child { border-right: 0; }
.ns-statstrip dt { font-size: 11px; font-weight: 700; letter-spacing: .11em; color: var(--ns-faint); margin-bottom: 6px; text-transform: uppercase; }
.ns-statstrip dd { margin: 0; font-size: 14.5px; font-weight: 600; color: var(--ns-ink); }
.ns-licblock { border: 1px solid var(--ns-verify-hair); background: var(--ns-forest-wash); border-radius: 16px; padding: 24px 26px; margin-bottom: 34px; }
.ns-licblock h2 { font-size: 17px; font-weight: 700; color: var(--ns-forest-dk); margin: 0; }
.ns-lictable { width: 100%; border-collapse: collapse; }
.ns-lictable th { font-size: 11px; font-weight: 700; letter-spacing: .11em; text-transform: uppercase; color: var(--ns-mut); text-align: left; padding: 0 12px 10px 0; border-bottom: 1px solid #D2DBBE; background: none; }
.ns-lictable td { padding: 15px 12px 18px 0; border-bottom: 1px solid #D2DBBE; font-size: 14.5px; vertical-align: middle; }
.ns-lictable td.ns-num { font-variant-numeric: tabular-nums; }
.ns-lictable td b { font-size: 15px; font-weight: 700; color: var(--ns-ink); }
.ns-covers { padding-top: 18px; }
.ns-covers-h { font-size: 11px; font-weight: 700; letter-spacing: .11em; text-transform: uppercase; color: var(--ns-mut); margin-bottom: 10px; }
.ns-twoup { display: grid; grid-template-columns: 1fr 1fr; gap: 1px; background: var(--ns-hairline); border: 1px solid var(--ns-hairline); border-radius: 14px; overflow: hidden; margin-bottom: 34px; }
.ns-twoup > div { background: #fff; padding: 20px 22px; }
.ns-twoup h3 { font-size: 11.5px; font-weight: 700; letter-spacing: .12em; text-transform: uppercase; margin-bottom: 11px; }
.ns-twoup ul { margin: 0; padding-left: 17px; font-size: 14px; line-height: 1.6; color: var(--ns-body); }
.ns-relgrid { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; margin-bottom: 34px; }
.ns-relcard { border: 1px solid var(--ns-hairline); border-radius: 14px; padding: 20px 22px; background: var(--ns-wash); }
.ns-relcard h3 { font-size: 11.5px; font-weight: 700; letter-spacing: .12em; text-transform: uppercase; color: var(--ns-mut); margin-bottom: 10px; }
.ns-ctacard { border: 1px solid var(--ns-hairline); border-radius: 16px; padding: 22px; background: #fff; box-shadow: 0 8px 24px rgba(23,26,21,.05); }
.ns-sidecard { border: 1px solid var(--ns-hairline); border-radius: 16px; padding: 20px 22px; background: #fff; }
.ns-sidecard h3 { font-size: 11.5px; font-weight: 700; letter-spacing: .12em; text-transform: uppercase; color: var(--ns-mut); margin-bottom: 14px; }
.ns-nearby a { display: flex; flex-direction: column; gap: 4px; padding: 12px; margin: 0 -12px; border-radius: 10px; text-decoration: none; transition: background .14s ease; }
.ns-nearby a:hover { background: #F4F6EE; text-decoration: none; }
.ns-nearby b { font-size: 14.5px; font-weight: 600; color: var(--ns-ink); line-height: 1.3; }
.ns-nearby span { font-size: 12.5px; color: var(--ns-mut); }
/* The claim button was low-contrast ghost styling on a tinted card and
   read as disabled. Gold, like every other primary action on the site. */
.ns-claimcard { border: 1px solid var(--ns-hairline); border-radius: 16px; padding: 20px 22px; background: var(--ns-wash); }

@media (max-width: 1080px) {
	.ns-dirhero, .ns-prof { grid-template-columns: 1fr; gap: 28px; }
	.ns-prof-aside { position: static; }
}
@media (max-width: 860px) {
	.ns-sec--hero { padding: 18px 0 26px; }
	.ns-sec--hero-tall { padding: 40px 0 32px; }
	.ns-pgrid { grid-template-columns: 1fr; }
	.ns-twoup, .ns-relgrid { grid-template-columns: 1fr; }
	.ns-pager { gap: 14px; justify-content: center; }
	.ns-pager-range, .ns-pager-jump { flex: 1 1 100%; justify-content: center; }
	.ns-filterbar { top: 56px; }
	#providers { scroll-margin-top: 112px; }
}
.ns-sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }

/* --- State-hub A–Z banner, restyled to match the provider filter rail ----
   Same visual language as .ns-rail so the two sticky banners on the site
   read as one component: tinted band rather than translucent white, taller
   tiles, forest-dark active state. Structure and stickiness are unchanged —
   only the skin. */
/* Padding is mirrored top and bottom. The old rule paid 10px above and
   10px below but the bar inside it still carried `margin: 20px 0 4px` from
   its non-sticky form, so the band measured 30px above the tiles and 14px
   below — visibly top-heavy. The wrapper owns the spacing; the bar owns
   none, in both contexts. */
.ns-subnav--az { background: var(--ns-forest-wash); border-top: 1px solid var(--ns-hair-warm); border-bottom: 1px solid var(--ns-hair-warm); backdrop-filter: none; -webkit-backdrop-filter: none; padding: 14px calc(50vw - 50%); }
.ns-subnav--az .ns-az-bar { margin: 0; }
.ns-az-bar { gap: 3px; margin: 14px 0; }
.ns-az-bar a { width: 34px; height: 32px; border-radius: 8px; border-color: transparent; background: transparent; font-size: 13px; font-weight: 600; transition: background .12s ease, color .12s ease, border-color .12s ease; }
.ns-az-bar a:hover { background: #fff; border-color: var(--ns-moss); color: var(--ns-ink); }
.ns-az-bar a[aria-current="true"], .ns-az-bar a.is-on { background: var(--ns-forest-dk); border-color: var(--ns-forest-dk); color: #fff; }
/* Letters with no providers. They are anchors without href, so they already
   inherit the tile box above; this only mutes them and kills the hover. */
.ns-az-bar a:not([href]) { color: var(--ns-faint); cursor: default; pointer-events: none; }
.ns-az-bar a:not([href]):hover { background: transparent; border-color: transparent; color: var(--ns-faint); }

/* --- Filter row: one height for every control ---------------------------
   Borrowed wholesale from .ns-search, which already solved this. The city
   field was a bare <input type=text>, so `.ns input[type="text"]` (0,2,1)
   beat `.ns-fsel` (0,1,0) and gave it 11px padding and width:100% — taller
   than its neighbors and stretched. Specificity here has to clear that
   rule, which is why every selector is scoped to .ns. */
.ns .ns-filterrow { --ns-fh: 46px; }
.ns .ns-filterrow input[type="text"],
.ns .ns-filterrow input[type="search"],
.ns .ns-filterrow select,
.ns .ns-filterrow .ns-btn,
.ns .ns-filterrow button[type="submit"],
.ns .ns-filterrow .ns-fsearch,
.ns .ns-filterrow .ns-ftoggle {
	height: var(--ns-fh); min-height: var(--ns-fh); box-sizing: border-box;
	padding-top: 0; padding-bottom: 0; line-height: normal;
}
.ns .ns-filterrow input[type="text"], .ns .ns-filterrow select { width: auto; padding-left: 12px; padding-right: 12px; }
.ns .ns-filterrow .ns-fsearch input { height: auto; min-height: 0; border: 0; padding: 0; }
.ns .ns-filterrow .ns-btn { padding-left: 20px; padding-right: 20px; }

/* Buttons on these pages are the site's .ns-btn system. The bespoke set
   that shipped first lost to `.ns a:hover` (0,2,1) on hover — forest text
   on a forest fill, i.e. an unreadable "Request a quote". .ns-btn already
   pins its own hover color, so reuse beats reinvention. */
.ns-btn--wide { width: 100%; height: 50px; font-size: 15.5px; }
.ns .ns-pcard-cta { margin-left: auto; position: relative; z-index: 1; }
.ns .ns-seeall { margin-top: 14px; width: 100%; }

/* Letter rail reuses .ns-az-bar from the state hub. Only the grid wrapper
   is new — the tiles, hover and active state are the shared component. */
.ns-railwrap { display: flex; align-items: center; gap: 14px; padding: 0 0 14px; flex-wrap: wrap; }
.ns-raillabel { flex: none; font-size: 11.5px; font-weight: 700; letter-spacing: .13em; color: var(--ns-mut); }

/* --- Provider profile: spacing corrections (2026-08-13) ------------------ */

/* .ns-license-block is the shared component and carries no bottom margin of
   its own, so the badge means/doesn't-mean pair sat flush against it. */
.ns-prof .ns-license-block { margin-bottom: 30px; }
.ns .ns-licblock-h { font-size: 21px; line-height: 1.2; letter-spacing: -.015em; font-weight: 700; color: var(--ns-forest-dk); margin: 0 0 22px; }

/* Two stacked full-width CTAs need a gap; the bespoke button that owned
   that margin was removed when these moved onto .ns-btn. */
.ns .ns-ctacard-h { font-size: 18px; line-height: 1.2; letter-spacing: -.015em; font-weight: 700; margin: 0 0 18px; color: var(--ns-ink); }
.ns-ctacard .ns-btn--wide + .ns-btn--wide { margin-top: 10px; }

/* --- Filter row: the search field is a <label> wrapper, not a control ----
   It has to match the height of its siblings while its inner <input> fills
   it rather than being sized itself — otherwise the input's own box lands
   off-center inside the label and the field reads misaligned. */
.ns .ns-filterrow .ns-fsearch {
	height: var(--ns-fh); min-height: var(--ns-fh); box-sizing: border-box;
	display: flex; align-items: center; gap: 9px; padding: 0 14px; margin: 0;
}
.ns .ns-filterrow .ns-fsearch input[type="search"] {
	height: 100%; min-height: 0; border: 0; background: transparent;
	padding: 0; margin: 0; width: 100%; line-height: normal;
}
.ns .ns-filterrow .ns-fsearch svg { flex: none; }

/* Claim button matches the rail's other buttons. It is --sm (40px) rather
   than --wide (50px) because it is a secondary action, but full width like
   everything else in the sidebar. */
.ns-claimcard .ns-btn { width: 100%; }

/* Legend badge column: fixed width so "Phone verified" and the longer
   badges stay on one line instead of wrapping mid-word. */
.ns-legend-row { align-items: flex-start; }
.ns-legend-row .ns-badge { flex: 0 0 132px; justify-content: flex-start; white-space: nowrap; }

/* ==================================================================
   Mobile pass — 2026-09-01
   ==================================================================
   Measured on the live providers archive at 390x844 before any of this:

     filter bar, at rest ......... 972px  (115% of the screen)
     filter bar, state cards
       collapsed ................. 514px  (61%, + 56px header = 68%)
     #providers scroll offset .... 112px  against 570px of occlusion
     first provider card ......... 1,976px down the document

   The site had already decided this question once, for .ns-subnav:
   "Below 900px it un-sticks: two stacked bars eat a third of a phone
   screen." The provider filter bar was the same shape and had never had
   the rule applied to it. What follows applies it — the bar stays sticky
   (filters have to be reachable while a visitor scrolls 1,600 records)
   but is folded down to one 40px pill row plus a 44px disclosure.
   ================================================================== */

/* The anchor offset is the real height of what is pinned above the
   results, written by the template's script as --ns-anchor. The literals
   here are the JS-off fallback and are unchanged from what shipped. */
#providers { scroll-margin-top: var(--ns-anchor, 128px); }
/* The claim and sign-up forms on /for-providers/ are reached by anchor from
   every "Claim this free listing" button and from the postcard's /claim/<code>
   link. Without this the sticky header covered the section heading: measured
   2026-10-19, "Claim your listing" landed 163px above the viewport at 390px
   wide and flush under the header at 1440px. */
#claim, #join { scroll-margin-top: var(--ns-anchor, 128px); }

/* Desktop: the disclosure does not exist. The summary is hidden, the
   element stays open, and the bar renders exactly as it did before. */
.ns-fdrawer > summary { display: none; }
/* `.ns details` (0,1,1) is this theme's FAQ accordion — a hairline top and
   bottom rule and 14px of vertical padding — and it outranked `.ns-fdrawer`
   (0,1,0), which is why the closed drawer measured 84px instead of 54px.
   `.ns details:first-of-type` (0,2,1) adds the top rule too, so the reset
   has to match that weight — hence `details.ns-fdrawer` rather than a
   second class — and sits later in the file to win the tie. */
.ns details.ns-fdrawer { margin: 0; padding: 0; border: 0; background: none; }

@media (max-width: 860px) {

	#providers { scroll-margin-top: var(--ns-anchor, 112px); }
	#claim, #join { scroll-margin-top: var(--ns-anchor, 112px); }

	/* --- State pills -------------------------------------------------
	   Six 80px cards stacked = 514px. The same six as a single scrolling
	   line of pills = 40px, and no information is lost: name and count
	   both stay on the pill. It bleeds to the screen edges so the row
	   visibly runs off the side rather than looking like the whole list. */
	.ns-filterbar .ns-wrap { --ns-gut: 24px; }
	.ns-staterow {
		flex-wrap: nowrap; overflow-x: auto; overscroll-behavior-x: contain;
		-webkit-overflow-scrolling: touch; scrollbar-width: none;
		gap: 8px; padding: 10px var(--ns-gut);
		margin-left: calc(var(--ns-gut) * -1); margin-right: calc(var(--ns-gut) * -1);
	}
	.ns-staterow::-webkit-scrollbar { display: none; }
	.ns-statecard {
		flex: 0 0 auto; flex-direction: row; align-items: baseline; gap: 7px;
		height: 40px; padding: 0 15px; border-radius: 999px; white-space: nowrap;
	}
	.ns-statecard b { font-size: 14px; }
	.ns-statecard span { font-size: 12px; }
	/* Abbreviation in, full name and count out. The name is clipped rather
	   than display:none so the link's accessible name is still "Ohio" and
	   not "OH"; the abbreviation carries aria-hidden in the markup so it is
	   not read twice. The count goes from both trees -- on a pill it is
	   noise, and it is on the state hub for anyone who wants it. */
	.ns-statecard .ns-sc-abbr { display: inline; }
	.ns-statecard .ns-sc-n { display: none; }
	.ns-statecard .ns-sc-name {
		position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
		overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
	}
	/* baseline is what the two-line desktop card wants. With one short line
	   left, a baseline in a 40px box sits high; center is what center means. */
	.ns-statecard { align-items: center; }
	/* Lift-on-hover is a pointer affordance and reads as a stuck :hover
	   after a tap on touch. */
	.ns-statecard:hover { transform: none; box-shadow: none; }

	/* The desktop cards-to-select swap answers a desktop problem. Here the
	   pills are already one line, and a native select would drop the
	   counts, so the swap is off. */
	.ns-filterbar[data-stuck="true"] .ns-staterow { display: flex; }
	.ns-filterbar[data-stuck="true"] .ns-statesel { display: none; }

	/* --- The disclosure ---------------------------------------------- */
	.ns-fdrawer > summary {
		display: flex; align-items: center; gap: 9px;
		min-height: 44px; margin: 0 0 10px; padding: 0 14px;
		border: 1px solid var(--ns-hair-warm); border-radius: 10px;
		background: #fff; font-size: 14.5px; font-weight: 600; color: var(--ns-ink);
		cursor: pointer; list-style: none;
	}
	.ns-fdrawer > summary::-webkit-details-marker { display: none; }
	.ns-fdrawer > summary::after {
		content: ""; margin-left: auto; width: 7px; height: 7px;
		border-right: 2px solid var(--ns-mut); border-bottom: 2px solid var(--ns-mut);
		transform: rotate(45deg) translateY(-2px);
	}
	.ns-fdrawer[open] > summary { border-color: var(--ns-moss); background: #F7FAF1; }
	.ns-fdrawer[open] > summary::after { transform: rotate(-135deg) translateY(-2px); }
	.ns-fdrawer > summary:focus-visible { outline: 2px solid var(--ns-moss); outline-offset: 2px; }
	.ns-fdrawer-n {
		display: inline-flex; align-items: center; justify-content: center;
		min-width: 20px; height: 20px; padding: 0 6px; border-radius: 999px;
		background: var(--ns-forest-dk); color: #fff;
		font-size: 11.5px; font-weight: 700; font-variant-numeric: tabular-nums;
	}
	/* Capped so an open drawer can never be taller than the screen it is
	   pinned to — the failure the whole bar had. */
	.ns-fdrawer-body { max-height: 60vh; overflow-y: auto; }

	/* --- Controls, stacked and thumb-sized --------------------------- */
	.ns .ns-filterrow {
		--ns-fh: 48px;
		flex-direction: column; align-items: stretch; gap: 8px; padding: 0 0 12px;
	}
	/* flex-basis resolves against the MAIN axis, and the main axis is now
	   vertical. Left alone, `.ns-fsearch { flex: 2 1 300px }` becomes a
	   300px-TALL search field and the stack measured 790px. Basis is reset
	   to auto so the shared --ns-fh height rule is what sizes them. */
	.ns .ns-filterrow > * { flex: 0 0 auto; width: 100%; }
	.ns .ns-filterrow input[type="text"], .ns .ns-filterrow select { width: 100%; }
	/* 16px is the threshold under which iOS Safari zooms the page on focus
	   and does not zoom back. Measured at 14.5px before this. */
	.ns .ns-filterrow input, .ns .ns-filterrow select { font-size: 16px; }
	.ns-ftoggle { justify-content: flex-start; }

	/* --- A–Z rail ----------------------------------------------------
	   27 tiles wrapped to three rows = 176px. One scrolling line = 40px,
	   and the tiles go from 34x32 to 40x40. */
	.ns-railwrap { flex-direction: column; align-items: stretch; gap: 8px; padding: 0 0 4px; }
	.ns-railwrap .ns-az-bar {
		flex-wrap: nowrap; justify-content: flex-start; overflow-x: auto;
		gap: 4px; margin: 0; scrollbar-width: none; -webkit-overflow-scrolling: touch;
	}
	.ns-railwrap .ns-az-bar::-webkit-scrollbar { display: none; }
	.ns-railwrap .ns-az-bar a { flex: 0 0 auto; width: 40px; height: 40px; }

	/* --- Applied filters --------------------------------------------
	   Deliberately NOT inside the disclosure: these are the only thing on
	   screen that explains why a list is twelve rows long. */
	.ns-chiprow {
		flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none;
		gap: 8px; padding: 0 var(--ns-gut) 12px;
		margin-left: calc(var(--ns-gut) * -1); margin-right: calc(var(--ns-gut) * -1);
	}
	.ns-chiprow::-webkit-scrollbar { display: none; }
	.ns-fchip { flex: 0 0 auto; height: 34px; }
	.ns-clearall { flex: 0 0 auto; display: inline-flex; align-items: center; height: 34px; }

	/* --- Quote form --------------------------------------------------
	   Same 16px rule. This is the site's only conversion path, and a
	   visitor whose page zooms on the first field has to pinch back out
	   to read the second one. */
	.ns-ffwrap .ff-el-form-control { font-size: 16px !important; padding: 13px !important; }
	.ns-ffwrap .choices__inner, .ns-ffwrap .choices__input { font-size: 16px !important; }
	.ns-ffwrap .ff-btn-submit { width: 100%; padding: 14px 20px !important; font-size: 16px !important; }
	/* Radios and checkboxes rendered at 13x13. The label wraps the input,
	   so the whole row becomes the target rather than the dot. */
	.ns-ffwrap .ff-el-form-check-input { width: 20px; height: 20px; }
	.ns-ffwrap .ff-el-form-check-label {
		display: flex; align-items: center; gap: 10px;
		min-height: 44px; font-size: 15px; line-height: 1.35;
	}
	/* Consent stays top-aligned fine print; the whole paragraph is the target, well past 44px. */
	.ns-ffwrap .ns-sms-consent-box .ff-el-form-check-label { align-items: flex-start; min-height: 0; font-size: 14px; line-height: 1.5; }
	.ns-ffwrap .ns-sms-consent-box .ff-el-form-check-input { width: 18px; height: 18px; margin-top: 3px; }
	.ns-ffwrap .ns-sms-consent-links { padding-left: 28px; }
}

@media (max-width: 760px) {
	/* 41x35. It is the only way to reach the menu on a phone. */
	.ns-burger {
		display: inline-flex; align-items: center; justify-content: center;
		width: 44px; height: 44px; padding: 0;
	}
	/* 116x20, and it is the fastest route to a local result on a phone —
	   the one control on the page that uses the device's own advantage. */
	.ns-uselocate { min-height: 44px; margin-top: 4px; }
	/* Menu rows were 10px 0 on a 15px line: about 38px. */
	.ns-mobilenav a:not(.ns-btn) { padding: 13px 0; }
	.ns-mobilenav .ns-btn { min-height: 48px; }
}

@media (max-width: 480px) {
	.ns-filterbar .ns-wrap { --ns-gut: 18px; }
}
