/*
Theme Name: Spencer (Bricks child)
Template: bricks
Version: 0.1.0
Description: Child theme for the Spencer Home Services Bricks build. Holds no templates; all design lives in Bricks.
*/

/* Keyboard focus: one visible ring on every interactive element, site-wide by nature, so it lives here rather than on
   any one class. Two tones (Task 4): a 2px navy band filling the offset gap, then the 3px orange ring. The brand orange
   alone is 2.43:1 on white (under the 3:1 a focus indicator needs); the navy band is 14.8:1 on white and the orange
   ring 6.1:1 on the navy grounds, so the indicator reaches 3:1 against whatever ground it sits on. */
:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
	outline: 3px solid var(--color-accent);
	outline-offset: 2px;
	box-shadow: 0 0 0 2px var(--primary-950);
}

/* ---------------------------------------------------------------------------------------------------------------------
   Design fix wave 1 (2026-10-28, audits A/B/C). Site-wide rules that belong to no one Bricks class: the header element
   (#brx-header is the template wrapper, not an element), vendor markup (Trustindex, the shs-gf-integration mu-plugin's
   forms, the ServiceTitan Text2Chat launcher lives in tracking.php next to its guard) and element defaults.
   --------------------------------------------------------------------------------------------------------------------- */

/* C-1 (supersedes A-12): one real sticky header at every width. The old sticky menu row was trapped inside the 177px
   #brx-header and never stuck. The header itself sticks; from 768px the 40px brand bar scrolls away (top:-40px), so what
   stays is the logo row with Call and Book (and, from 992px, the menu row): 64px under 768px, 72px at 768-991, 120px
   from 992px. FX-22 (Spacing Task 9, Scott's Q4): brand bar 40, logo row 72 (64 on phones), menu row 48, all on the 8-grid; was 38 / 57 (76, 68) / 46
   and a 104px stuck header. --sticky-nav-h (every pinned column's top offset) follows that height; scroll-padding-top is it plus 16. */
#brx-header {
	position: sticky;
	top: 0;
	z-index: 999;
}
body { --sticky-nav-h: 64px; }
html { scroll-padding-top: 80px; }
@media (min-width: 768px) {
	#brx-header { top: -40px; }
	body { --sticky-nav-h: 72px; }
	html { scroll-padding-top: 88px; }
}
@media (min-width: 992px) {
	body { --sticky-nav-h: 120px; }
	html { scroll-padding-top: 136px; }
}

/* A-12 / skill rule 19: the phone call bar (class dock: 64px + the 6px blue band, under 768px) never covers the page's
   last line: the page itself is padded by its height (the footer legal strip no longer carries its own clearance). */
@media (max-width: 767px) {
	body { padding-bottom: calc(70px + env(safe-area-inset-bottom)); }
	/* wave 2: the sticky header keeps its Call on screen, so the bar stays parked; a parked bar reserves no space */
	body:has(.dock.dock--parked) { padding-bottom: 0; }
}

/* A-16: balanced section headings and no single-word last lines in body copy (H1s balance in their own classes).
   C-8: a heading only breaks inside a word when the word alone is wider than the line (never "anywhere"). */
:where(h2, h3) { text-wrap: balance; }
:where(p, li, blockquote, figcaption) { text-wrap: pretty; }
:where(h1, h2, h3, h4) { overflow-wrap: break-word; }

/* C-7: Bricks' base stylesheet sets blockquotes in Georgia; quotes are set in the body face like the rest of the copy. */
blockquote { font-family: var(--font-body); }

/* A-10, B-21: the Trustindex reviews widget restyled on-system inside the site's slot (class ti-slot): the body and display
   faces instead of Poppins (no element uses the vendor face, so its font files are never fetched), square cards on a 1px
   line with no shadow, 44px tap targets for Read more, Write a review and Load more. The vendor sheet uses long attribute
   selectors with !important, so these rules carry one id-weight (:is(#shs-ti, ...) never matches an id) and !important.
   F1 (review M10): the same skin wherever the widget renders in the page (main#brx-content), not only inside .ti-slot. */
:is(.ti-slot, #brx-content) :is(#shs-ti, .ti-widget),
:is(.ti-slot, #brx-content) :is(#shs-ti, .ti-widget) *:not(svg):not(svg *) {
	font-family: var(--font-body) !important;
}
:is(.ti-slot, #brx-content) :is(#shs-ti, .ti-widget) :is(.ti-name, .ti-rating-text, .ti-header-rating-reviews, .ti-header-write-btn, .ti-load-more-reviews-button, .ti-read-more, .ti-read-more *) {
	font-family: var(--font-display) !important;
	letter-spacing: .02em !important;
}
:is(.ti-slot, #brx-content) :is(#shs-ti, .ti-widget) .ti-name { font-weight: 700 !important; color: var(--color-ink) !important; }
:is(.ti-slot, #brx-content) :is(#shs-ti, .ti-widget) :is(.ti-inner, .ti-widget-header, .ti-header-write-btn, .ti-load-more-reviews-button, .ti-review-image, .ti-review-image img, .ti-more-image-count, .ti-review-text-container) {
	border-radius: 0 !important;
	box-shadow: none !important;
}
:is(.ti-slot, #brx-content) :is(#shs-ti, .ti-widget) :is(.ti-review-item > .ti-inner, .ti-widget-header) {
	border: 1px solid var(--color-line) !important;
	background: #fff !important;
}
:is(.ti-slot, #brx-content) :is(#shs-ti, .ti-widget) .ti-read-more {
	display: inline-flex !important;
	align-items: center !important;
	min-height: 44px !important;
	color: var(--color-primary) !important;
	text-decoration: underline;
	text-underline-offset: 3px;
}
:is(.ti-slot, #brx-content) :is(#shs-ti, .ti-widget) :is(.ti-header-write-btn, .ti-load-more-reviews-button) {
	display: inline-flex !important;
	align-items: center !important;
	justify-content: center !important;
	min-height: 44px !important;
	padding: 0 18px !important;
	border: 2px solid var(--color-primary) !important;
	background: transparent !important;
	color: var(--color-primary) !important;
	font-weight: 700 !important;
}
:is(.ti-slot, #brx-content) :is(#shs-ti, .ti-widget) :is(.ti-header-write-btn, .ti-load-more-reviews-button):hover {
	background: var(--color-primary) !important;
	color: #fff !important;
}

/* B-5, C-9, A-6: the shs-gf-integration mu-plugin's forms (contact, reviews, membership, financing, careers, the service
   request band) take the site's faces, colours and square corners. Its own custom properties are pointed at the tokens;
   its literal radii, pill submit and faint orange focus carry !important, so the overrides carry one id-weight too. Fields:
   white with a 1px border at 3:1 (--field-line); focus: the site's 3px deep-blue ring (13:1) and a deep-blue border. */
:root {
	--shs-font-body: var(--font-body);
	--shs-font-display: var(--font-display);
}
:is(#shs-gf, .shs-gfsi-general, .shs-gfsi-careers, .shs-gfsi-ppc) {
	--shs-gfsi-navy: var(--color-ink);
	--shs-gfsi-blue: var(--color-primary);
	--shs-gfsi-orange: var(--color-accent);
	--shs-gfsi-orange-hover: var(--accent-500);
	--shs-gfsi-border: var(--field-line);
	--shs-gfsi-error: var(--color-error);
}
:is(#shs-gf, .shs-gfsi-general, .shs-gfsi-careers, .shs-gfsi-ppc) :is(input:not([type=checkbox]):not([type=radio]):not([type=submit]):not([type=hidden]), select, textarea, .gform_validation_errors, .gform_confirmation_message) {
	border-radius: 0 !important;
}
:is(#shs-gf, .shs-gfsi-general, .shs-gfsi-careers, .shs-gfsi-ppc) :is(input:not([type=checkbox]):not([type=radio]):not([type=submit]):not([type=hidden]), select, textarea):focus {
	border-color: var(--color-deep) !important;
	outline: 3px solid var(--color-deep) !important;
	outline-offset: 0 !important;
}
:is(#shs-gf, .shs-gfsi-general, .shs-gfsi-careers, .shs-gfsi-ppc) :is(.gform_button, input[type=submit]) {
	border-radius: 0 !important;
	min-height: 48px !important;
	font: 700 var(--fs-small)/1 var(--font-display) !important;
	letter-spacing: var(--tracking-btn) !important;
	transform: none !important;
}
:is(#shs-gf, .shs-gfsi-general, .shs-gfsi-careers, .shs-gfsi-ppc) :is(.gform_button, input[type=submit]):focus-visible {
	outline: 2px solid var(--color-deep) !important;
	outline-offset: 2px !important;
	box-shadow: none !important;
}
:is(#shs-gf, .shs-gfsi-general, .shs-gfsi-careers, .shs-gfsi-ppc) input[type=checkbox] {
	width: 24px !important;
	height: 24px !important;
	accent-color: var(--color-primary) !important;
}
:is(#shs-gf, .shs-gfsi-general, .shs-gfsi-careers, .shs-gfsi-ppc) :is(.gchoice, .ginput_container_consent) {
	min-height: 44px;
	align-items: center;
}

/* A-13: the footer's "Measurement choices" control (printed by the mu-plugin) in the legal strip's own link style. */
#shs-measurement-choices {
	min-height: 44px !important;
	padding-block: 0 !important;   /* R4 T2: the inline padding is the legal row's tick spacing (classes.py ftr-legal) */
	border: 0 !important;
	border-radius: 0 !important;
	background: none !important;
	color: inherit !important;
	font: inherit !important;
	letter-spacing: inherit !important;
	text-transform: inherit !important;
	text-decoration: underline !important;
	text-underline-offset: 3px !important;
	cursor: pointer;
}

/* C-20: print the page's content only (no sticky header rows, call bar, chat launcher or button rows). */
@media print {
	#brx-header { position: static; }
	.brand-bar, .hdr-menu, .nav-m, .dock, .btn-pair, .numband, .ti-slot, #brx-footer nav,
	div:has(> iframe[src^="https://text2chat-widget.servicetitan.com"]) { display: none !important; }
	body { padding-bottom: 0; }
}

/* A-15 / R5 T1: the separator for middle-dot label lines (span.tsep, written by the bridge's includes/separators.php around the
   dot, which stays in the markup): the dot itself in the text colour at 50% (orange means call, so no orange tick). Inside an
   eyebrow (an inline-flex row) the row's own gap spaces it; under 768px an eyebrow breaks at the separator (two lines, no dot at a
   line end, A-15 WHR eyebrow). */
.tsep {
	display: inline;
	opacity: .5;
	white-space: pre;
	user-select: none;
}
.eyebrow > .tsep { margin: 0; align-self: center; }
@media (max-width: 767px) {
	.eyebrow:has(> .tsep) { flex-wrap: wrap; row-gap: 2px; }
	.eyebrow > .tsep { flex-basis: 100%; width: 0; height: 0; font-size: 0; overflow: hidden; }
}
/* A-21: breadcrumb links are 44px tap targets (they were ~22-25px tall): the padding grows the target, the equal negative
   margin keeps the crumb line where it was. */
.brxe-breadcrumbs a {
	display: inline-block;
	padding-block: 12px;
	margin-block: -12px;
}

/* C-6: under 360px the Cloudflare Turnstile box (a fixed 300px iframe) is scaled to the 280px form column. */
@media (max-width: 359px) {
	.gform_wrapper iframe[src*="challenges.cloudflare.com"] {
		transform: scale(.92);
		transform-origin: 0 0;
	}
}

/* Operator 2026-10-29: the official multicolour Google "G" before every "Google rating" label (self-hosted SVG, Google's own four
   colours; a decorative pseudo-element, so screen readers read the label alone). */
.g-rate::before {
	content: "";
	display: inline-block;
	width: 1em;
	height: 1em;
	margin-right: .32em;
	vertical-align: -.14em;
	background: url("assets/brand/google-g.svg") no-repeat center / contain;
}
.g-rate { white-space: nowrap; }

/* Operator 2026-10-29 (wide screens): the page never scrolls sideways. Vendor widgets (the Trustindex slider's off-screen cards)
   and the hero bleeds sized from 100vw (which includes a classic scrollbar's width) could make the document a few pixels to
   several hundred pixels wider than the window; a sideways scroll then left every band ending short of the right edge with its
   left side cut off. clip (not hidden) keeps the sticky header working. */
body { overflow-x: clip; }
.ti-slot { max-width: 100%; overflow: clip; }

/* Design wave 1 #6 (2026-10-29): Form 9's one-line address. With scripting on, from first paint (no shift when the script runs), the
   apartment, city, state and ZIP inputs and the separate ZIP field (4) are out of view; they stay in the form and Google Places fills
   them (assets/js/form9-address.js). The script brings them back (shs-addr-open): no Places within 4s, no place picked, a part
   missing, or "Enter the address by hand" (drawn in the 40px kept under the street line). A field in error is never hidden; with
   scripting off the form shows as printed. */
@media (scripting: enabled) {
	#gform_9 .gfield--type-address:not(.shs-addr-open):not(.gfield_error) :is(.address_line_2, .address_city, .address_state, .address_zip),
	#gform_9 #field_9_4:not(.shs-addr-open):not(.gfield_error) {
		display: none !important;
	}
	#gform_9 .gfield--type-address:not(.shs-addr-open):not(.gfield_error) .address_line_1 > label {
		position: absolute !important; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
	}
	#gform_9 .gfield--type-address:not(.shs-addr-open):not(.gfield_error) .address_line_1 { display: block; position: relative; padding-bottom: 40px; }
}
.shs-addr-manual {
	/* in flow at the street input's left edge, a full row of its own, drawn over the 40px kept under the input (net height 0) */
	width: max-content; max-width: 100%;
	display: flex; align-items: center; min-height: 44px; margin: -2px 0 -42px; padding: 0; border: 0; background: none;
	font: 400 var(--fs-small)/1.3 var(--font-body); color: var(--color-primary); text-decoration: underline; text-underline-offset: 3px; cursor: pointer;
}
.shs-addr-manual:focus-visible { outline: 2px solid var(--color-deep); outline-offset: 2px; }
/* the text-updates consent on one line; its description (exact text) inside a closed "Details" disclosure */
.shs-consent-more { margin: -6px 0 -8px 34px; font-size: var(--fs-small); line-height: 1.45; color: var(--color-muted); }
.shs-consent-more > summary {
	display: inline-flex; align-items: center; gap: 6px; min-height: 44px; cursor: pointer; color: var(--color-primary); list-style: none;
	font: 700 var(--fs-small)/1 var(--font-display); letter-spacing: .02em;
}
.shs-consent-more > summary::-webkit-details-marker { display: none; }
.shs-consent-more > summary::after { content: ""; width: 7px; height: 7px; border: solid currentColor; border-width: 0 2px 2px 0; transform: translateY(-2px) rotate(45deg); }
.shs-consent-more[open] > summary::after { transform: translateY(2px) rotate(-135deg); }
.shs-consent-more > .gfield_description { padding: 0 0 4px; margin: 0; }
/* the disclosures under the submit (the measurement notice the mu-plugin prints with an inline 12px, and the card's response note):
   16px, the card's full measure, two lines at most from 1024px */
.form-card .gform_footer .shs-ad-disclosure { flex-basis: 100%; margin: 12px 0 0 !important; font-size: var(--fs-small) !important; line-height: 1.45 !important; color: var(--color-muted) !important; }
.form-card > .meta { font-size: var(--fs-small); line-height: 1.45; }
