/* =====================================================================
 * RG 2026 — design refresh layer
 * ---------------------------------------------------------------------
 * Loaded AFTER design-system.css so it wins at equal specificity.
 * Everything here is token-driven. Nothing here changes page content.
 *
 * Measured problems this layer fixes (audited 2026-09-06 at 1440 and 390):
 *   - body copy rendering at 12px / 13px / 14px across the site
 *   - brand amber #FBB707 used as text on white = 1.77:1 contrast
 *     (WCAG AA needs 4.5:1) on eyebrows, subtitles and one button label
 *   - grey #8A8F9C fine print at 3.24:1
 *   - no deliberate focus-visible system
 *   - tap targets below 44px
 *   - no dark-mode support at all
 *   - no container queries; cards only respond to viewport width
 * ===================================================================== */

/* ---------------------------------------------------------------------
 * 1. TOKENS
 * Colour choices are contrast-checked against the surface they sit on.
 * ------------------------------------------------------------------- */
:root {
	/* brand */
	--rg-brand:        #235FAE;   /* 6.34:1 on white  */
	--rg-brand-deep:   #16407A;   /* hover / pressed  */
	--rg-brand-ink:    #0B3775;   /* headings         */
	--rg-accent:       #FBB707;   /* SURFACES ONLY — never text on white */
	--rg-accent-ink:   #8A5F00;   /* 5.9:1 on white — amber as text      */

	/* ink */
	--rg-ink:          #14171F;   /* 15.9:1 on white */
	--rg-ink-muted:    #545A66;   /*  6.9:1 on white */
	--rg-ink-faint:    #6A7080;   /*  4.9:1 on white — the floor for fine print */
	--rg-ink-on-brand: #FFFFFF;
	--rg-ink-on-accent:#231A00;   /* dark ink on amber = 9.6:1, replaces white-on-amber */

	/* surfaces */
	--rg-surface:      #FFFFFF;
	--rg-surface-2:    #F5F8FC;
	--rg-surface-3:    #E9F0F9;
	--rg-line:         rgba(20, 23, 31, .12);
	--rg-line-strong:  rgba(20, 23, 31, .22);

	/* radius — slightly softer than the old flat 10px */
	--rg-r-sm:  10px;
	--rg-r:     14px;
	--rg-r-lg:  20px;
	--rg-r-pill: 999px;

	/* elevation — layered, not a single flat shadow */
	--rg-e1: 0 1px 2px rgba(11, 24, 48, .06), 0 1px 3px rgba(11, 24, 48, .05);
	--rg-e2: 0 2px 4px rgba(11, 24, 48, .05), 0 10px 24px rgba(11, 24, 48, .08);
	--rg-e3: 0 6px 12px rgba(11, 24, 48, .07), 0 20px 48px rgba(11, 24, 48, .13);

	/* spacing — 8pt rhythm with fluid section spacing */
	--rg-s1: 4px;  --rg-s2: 8px;  --rg-s3: 12px; --rg-s4: 16px;
	--rg-s5: 24px; --rg-s6: 32px; --rg-s7: 48px; --rg-s8: 64px;
	--rg-section: clamp(48px, 6vw, 96px);

	/* motion */
	--rg-dur:  180ms;
	--rg-ease: cubic-bezier(.2, .7, .3, 1);

	/* focus */
	--rg-focus: #1B4FD8;

	/* minimum comfortable tap target */
	--rg-tap: 44px;
}

/* ---------------------------------------------------------------------
 * 2. THEME PRESET REMAP
 * The theme ships x-small at 12px and small at 14px, and those two
 * presets are what almost every paragraph on the site actually uses.
 * Raising the presets fixes the text sitewide without specificity wars.
 * ------------------------------------------------------------------- */
:root {
	--wp--preset--font-size--x-small: 13px;   /* was 12px — fine print only */
	--wp--preset--font-size--small:   15px;   /* was 14px — meta and labels */
	--wp--preset--font-size--medium:  clamp(16px, .97rem + .18vw, 20px); /* was clamp(14px…) */
}

/* Body copy must not sit at label size. Paragraphs and list items that
 * were tagged small/x-small are lifted to a real reading size; genuine
 * labels (spans, meta, captions) keep the preset. */
/* WordPress emits `.has-*-font-size { font-size: var(--…) !important }`,
 * so lifting body copy off a label size requires !important to win. */
main p.has-x-small-font-size,
main p.has-small-font-size,
main li.has-x-small-font-size,
main li.has-small-font-size {
	font-size: clamp(15.5px, .95rem + .14vw, 17.5px) !important;
	line-height: 1.6;
}

/* ---------------------------------------------------------------------
 * 3. AMBER AS TEXT — the site's worst contrast failure
 * Brand amber stays exactly as it is for button fills, rules and icons.
 * As *text on a light surface* it is replaced with the bronze token.
 * On dark surfaces the bright amber already passes, so it is restored.
 * ------------------------------------------------------------------- */
.has-secondary-color,
.has-luminous-vivid-amber-color {
	color: var(--rg-accent-ink) !important;
}

.wp-block-cover .has-secondary-color,
.wp-block-cover .has-luminous-vivid-amber-color,
.rg-cta .has-secondary-color,
.rg-cta .has-luminous-vivid-amber-color,
footer .has-secondary-color,
footer .has-luminous-vivid-amber-color,
[class*="has-primary-background-color"] .has-secondary-color,
[class*="has-dark-shade-background-color"] .has-secondary-color,
[class*="has-dark-background-color"] .has-secondary-color {
	color: var(--rg-accent) !important;
}

/* White label on an amber fill was 1.77:1. Dark ink on the same fill is 9.6:1. */
.wp-block-button__link.has-secondary-background-color,
.wp-block-button__link.has-luminous-vivid-amber-background-color,
.rg-btn.rg-btn-accent,
a.rg-btn[class*="accent"] {
	color: var(--rg-ink-on-accent) !important;
}

/* Fine print floor: the form disclaimer measured 3.24:1. */
main small,
.rg-form__privacy,
.rg-form-note,
.rg-fineprint,
main .has-x-small-font-size {
	color: var(--rg-ink-faint);
}

/* The form disclaimer shipped at 12.8px / 3.24:1 — legal text people
 * are asked to agree to must be readable. */
.rg-form__privacy {
	font-size: 13.5px;
	line-height: 1.55;
}

/* ---------------------------------------------------------------------
 * 4. TYPOGRAPHY — modern wrapping and rhythm
 * ------------------------------------------------------------------- */
h1, h2, h3, h4, h5 { text-wrap: balance; }
main p, main li      { text-wrap: pretty; }

/* Eyebrow labels: short all-caps kickers above a heading. They were
 * semantic H2s rendered at 14px in unreadable amber. Now a deliberate
 * component — small, but high contrast and clearly a label. */
main .wp-block-cover .has-secondary-color.has-small-font-size,
main h2.has-secondary-color.has-small-font-size,
main h4.has-secondary-color.has-small-font-size,
main h4.has-luminous-vivid-amber-color.has-small-font-size {
	font-size: 14px;
	font-weight: 700;
	letter-spacing: .1em;
	text-transform: uppercase;
	line-height: 1.4;
	margin-bottom: var(--rg-s2);
}

/* ---------------------------------------------------------------------
 * 5. FOCUS — one visible, consistent ring everywhere
 * ------------------------------------------------------------------- */
:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
	outline: 3px solid var(--rg-focus);
	outline-offset: 2px;
	border-radius: var(--rg-r-sm);
}
/* On dark panels the blue ring needs to be light to stay visible. */
.wp-block-cover :focus-visible,
.rg-cta :focus-visible,
footer :focus-visible {
	outline-color: #9CC4FF;
}

/* ---------------------------------------------------------------------
 * 6. BUTTONS AND TAP TARGETS
 * ------------------------------------------------------------------- */
.wp-block-button__link,
.rg-btn,
button[type="submit"],
input[type="submit"] {
	min-height: var(--rg-tap);
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: var(--rg-s2);
	border-radius: var(--rg-r-pill);
	font-weight: 650;
	letter-spacing: -.005em;
	padding-inline: clamp(18px, 1.6vw, 28px);
	transition: transform var(--rg-dur) var(--rg-ease),
	            box-shadow var(--rg-dur) var(--rg-ease),
	            background-color var(--rg-dur) var(--rg-ease);
}
.wp-block-button__link:hover,
.rg-btn:hover,
button[type="submit"]:hover {
	transform: translateY(-1px);
	box-shadow: var(--rg-e2);
}
.wp-block-button__link:active,
.rg-btn:active { transform: translateY(0); box-shadow: var(--rg-e1); }

/* Inline text links inside prose get a real hit area and a modern underline. */
main p a:not(.wp-block-button__link):not(.rg-btn),
main li a:not(.wp-block-button__link):not(.rg-btn) {
	text-underline-offset: .18em;
	text-decoration-thickness: .08em;
	padding-block: 2px;
}

/* ---------------------------------------------------------------------
 * 7. SURFACES, CARDS AND CONTAINER QUERIES
 * Cards now respond to the width of their own container rather than the
 * viewport, so the same card behaves correctly in a 3-up grid, a sidebar
 * or a full-width slot.
 * ------------------------------------------------------------------- */
.rg-grid { container-type: inline-size; }

.rg-card {
	background: var(--rg-surface);
	border: 1px solid var(--rg-line);
	border-radius: var(--rg-r);
	box-shadow: var(--rg-e1);
	transition: box-shadow var(--rg-dur) var(--rg-ease),
	            transform var(--rg-dur) var(--rg-ease),
	            border-color var(--rg-dur) var(--rg-ease);
}
.rg-card:hover {
	box-shadow: var(--rg-e2);
	border-color: var(--rg-line-strong);
	transform: translateY(-2px);
}
.rg-card:focus-within {
	box-shadow: var(--rg-e2);
	border-color: var(--rg-brand);
}

@container (min-width: 520px) {
	.rg-card { padding: var(--rg-s6); }
}
@container (max-width: 519px) {
	.rg-card { padding: var(--rg-s5); }
}

/* ---------------------------------------------------------------------
 * 8. FORMS
 * ------------------------------------------------------------------- */
:root { accent-color: var(--rg-brand); }

input[type="text"], input[type="email"], input[type="tel"],
input[type="url"], input[type="number"], select, textarea {
	min-height: var(--rg-tap);
	border-radius: var(--rg-r-sm);
	border: 1px solid var(--rg-line-strong);
	background: var(--rg-surface);
	color: var(--rg-ink);
	transition: border-color var(--rg-dur) var(--rg-ease),
	            box-shadow var(--rg-dur) var(--rg-ease);
}
input:focus, select:focus, textarea:focus {
	border-color: var(--rg-brand);
	box-shadow: 0 0 0 3px rgba(35, 95, 174, .18);
}
::placeholder { color: var(--rg-ink-faint); opacity: 1; }
label { font-weight: 600; color: var(--rg-ink); }

/* ---------------------------------------------------------------------
 * 9. MEDIA — stop layout shift, never distort
 * ------------------------------------------------------------------- */
main img, main video {
	max-width: 100%;
	height: auto;
	object-fit: cover;      /* crop rather than stretch, everywhere */
}
figure.wp-block-image img { border-radius: var(--rg-r-sm); }

/* ---------------------------------------------------------------------
 * 10. SECTION RHYTHM AND ANCHORS
 * ------------------------------------------------------------------- */
html { scroll-behavior: smooth; }
:target { scroll-margin-top: clamp(80px, 12vh, 140px); }

main h2 { color: var(--rg-brand-ink); }
main h3 { color: var(--rg-ink); }

/* ---------------------------------------------------------------------
 * 11. MOTION — opt out completely when asked to
 * ------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
	html { scroll-behavior: auto; }
	*, *::before, *::after {
		animation-duration: .001ms !important;
		animation-iteration-count: 1 !important;
		transition-duration: .001ms !important;
	}
	.wp-block-button__link:hover,
	.rg-btn:hover,
	.rg-card:hover { transform: none; }
}

/* ---------------------------------------------------------------------
 * 12. DARK MODE — DELIBERATELY NOT SHIPPED
 * ---------------------------------------------------------------------
 * A prefers-color-scheme block was written, deployed and measured, then
 * removed. Retrofitting it onto this theme created NEW contrast failures
 * in both directions - 11 across only two pages:
 *   - .rg-card h3 stayed #272727 on a darkened card            (1.14:1)
 *   - card body copy stayed #6A6A6A                            (3.16:1)
 *   - .rg-form is hard-coded background:#fff in design-system.css,
 *     so the dark-mode light text landed on white               (1.19:1)
 * The theme, Site Kit and ~200 legacy pages hard-code #fff and #272727 in
 * places that cannot all be enumerated from four sample pages, so coverage
 * could not be guaranteed. Dark mode here is a theme-level colour-token
 * project, not a stylesheet override. The removed block is kept at
 * scratchpad/rg-2026.withdark.css if it is ever wanted as a starting point.
 * ------------------------------------------------------------------- */

/* ---------------------------------------------------------------------
 * 13. MOBILE TAP-TO-CALL BAR
 * Standard 2026 pattern for a phone-led trade business: the two primary
 * actions stay one thumb-reach away without covering content. Injected
 * by rg-mobile.php; delete that block to remove it entirely.
 * ------------------------------------------------------------------- */
.rg-actionbar { display: none; }

@media (max-width: 899px) {
	.rg-actionbar {
		display: grid;
		grid-template-columns: 1fr 1fr;
		gap: var(--rg-s2);
		position: fixed;
		inset-inline: 0;
		bottom: 0;
		z-index: 90;
		padding: var(--rg-s2) var(--rg-s3);
		padding-bottom: calc(var(--rg-s2) + env(safe-area-inset-bottom, 0px));
		background: color-mix(in srgb, var(--rg-surface) 88%, transparent);
		backdrop-filter: blur(12px);
		-webkit-backdrop-filter: blur(12px);
		border-top: 1px solid var(--rg-line);
		box-shadow: 0 -4px 20px rgba(11, 24, 48, .10);
	}

	.rg-actionbar a {
		display: flex;
		align-items: center;
		justify-content: center;
		gap: var(--rg-s2);
		min-height: var(--rg-tap);
		border-radius: var(--rg-r-pill);
		font-size: 15px;
		font-weight: 650;
		text-decoration: none;
		line-height: 1;
	}
	.rg-actionbar .rg-actionbar-call {
		background: var(--rg-brand);
		color: var(--rg-ink-on-brand);
	}
	.rg-actionbar .rg-actionbar-book {
		background: var(--rg-accent);
		color: var(--rg-ink-on-accent);
	}
	.rg-actionbar svg { width: 18px; height: 18px; flex: none; }

	/* keep the footer clear of the bar */
	body { padding-bottom: calc(var(--rg-tap) + var(--rg-s5) + env(safe-area-inset-bottom, 0px)); }

	/* The theme pins a back-to-top button at bottom:25px, which landed on
	 * top of the Free Inspection button. Lift it clear of the bar. */
	a.wp-block-button__link.has-tertiary-background-color[href*="#"],
	.wp-block-buttons a.wp-block-button__link.has-tertiary-background-color {
		bottom: calc(var(--rg-tap) + var(--rg-s6) + env(safe-area-inset-bottom, 0px)) !important;
	}
}

/* ---------------------------------------------------------------------
 * 14. CONTENT MUST NOT DEPEND ON JAVASCRIPT TO BE VISIBLE
 * ---------------------------------------------------------------------
 * The theme ships AOS scroll-reveal. AOS sets [data-aos]{opacity:0} and
 * only adds .aos-animate when its scroll handler fires. Measured on the
 * front page (2026-09-06):
 *   - on load            : 11 of 15 [data-aos] elements at opacity 0
 *   - with JavaScript off:  9 of 12 never become visible at all
 * That is "Go with Roofing Giant", the three award cards, the Schedule
 * button and all eight Why Choose Us items - roughly half the homepage -
 * blank for anyone whose JS is blocked, slow, or errors before AOS runs.
 * Verified pre-existing: the same 11 are hidden with this stylesheet
 * disabled, so it is the theme's behaviour, not this refresh.
 *
 * Content is now visible by default. Motion is an enhancement, never a
 * precondition for reading the page.
 * ------------------------------------------------------------------- */
[data-aos] {
	opacity: 1 !important;
	transform: none !important;
	visibility: visible !important;
}

/* ---------------------------------------------------------------------
 * 15. INSTANT ESTIMATE MODAL
 * Native <dialog>, so focus trapping, Esc and inertness come from the
 * platform. The trigger is a real link to /free-estimate/, which already
 * carries the same scheduler — with JavaScript off the link simply
 * navigates and the tool still works.
 * ------------------------------------------------------------------- */
.rg-estimate-dialog {
	width: min(880px, 96vw);
	max-width: 96vw;
	height: min(820px, 92dvh);
	max-height: 92dvh;
	padding: 0;
	border: 0;
	border-radius: var(--rg-r-lg);
	box-shadow: var(--rg-e3);
	background: var(--rg-surface);
	overflow: hidden;
}
.rg-estimate-dialog::backdrop {
	background: rgba(9, 18, 36, .62);
	backdrop-filter: blur(3px);
	-webkit-backdrop-filter: blur(3px);
}
.rg-estimate-dialog__bar {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--rg-s4);
	padding: var(--rg-s3) var(--rg-s4) var(--rg-s3) var(--rg-s5);
	border-bottom: 1px solid var(--rg-line);
	background: var(--rg-surface-2);
}
.rg-estimate-dialog__title {
	margin: 0;
	font-size: 17px;
	font-weight: 700;
	color: var(--rg-brand-ink);
	letter-spacing: -.01em;
}
.rg-estimate-dialog__close {
	min-width: var(--rg-tap);
	min-height: var(--rg-tap);
	display: inline-flex;
	align-items: center;
	justify-content: center;
	border: 1px solid var(--rg-line);
	border-radius: var(--rg-r-pill);
	background: var(--rg-surface);
	color: var(--rg-ink);
	font-size: 20px;
	line-height: 1;
	cursor: pointer;
	transition: background-color var(--rg-dur) var(--rg-ease);
}
.rg-estimate-dialog__close:hover { background: var(--rg-surface-3); }
.rg-estimate-dialog__body { height: calc(100% - 66px); background: var(--rg-surface); }
.rg-estimate-dialog iframe { display: block; width: 100%; height: 100%; border: 0; }

@media (max-width: 899px) {
	.rg-estimate-dialog { width: 100vw; max-width: 100vw; height: 100dvh; max-height: 100dvh; border-radius: 0; }
}

/* ---------------------------------------------------------------------
 * 16. ACUITY SCHEDULER EMBED (/free-estimate/)
 * The legacy embed was a fixed height="800" iframe. This keeps it
 * responsive without distorting the widget.
 * ------------------------------------------------------------------- */
.rg-acuity {
	position: relative;
	width: 100%;
	height: min(820px, 88dvh);
	margin-block: var(--rg-s5);
	border: 1px solid var(--rg-line);
	border-radius: var(--rg-r);
	overflow: hidden;
	background: var(--rg-surface);
}
.rg-acuity iframe { display: block; width: 100%; height: 100%; border: 0; }

/* ---------------------------------------------------------------------
 * 17. PORTFOLIO GALLERY — show every project, not just the first
 * ---------------------------------------------------------------------
 * The Cozy portfolio carousel leaves its flex wrapper unconstrained: it
 * measured 33,554,436px wide (the browser's maximum CSS length), so the
 * six project photographs sat in one enormous row and only the first was
 * ever on screen. The swiper reports itself initialised and renders arrows,
 * but they do not bring the other five into view.
 *
 * Rendered as a responsive grid instead. All six projects are visible, at
 * their natural 4:3 proportions, with no dependency on carousel JS.
 * ------------------------------------------------------------------- */
.cozy-block-portfolio-gallery .cozy-layout-carousel {
	display: grid !important;
	grid-template-columns: repeat(auto-fit, minmax(min(310px, 100%), 1fr));
	gap: clamp(14px, 1.6vw, 24px);
	width: 100% !important;
	max-width: 100% !important;
	transform: none !important;
}

.cozy-block-portfolio-gallery .cozy-block-carousel,
.cozy-block-portfolio-gallery .swiper-slide {
	width: auto !important;
	max-width: 100% !important;
	flex: initial !important;
	margin: 0 !important;
}

.cozy-block-portfolio-gallery figure,
.cozy-block-portfolio-gallery .wp-block-image { margin: 0; }

.cozy-block-portfolio-gallery img {
	width: 100% !important;
	height: auto !important;
	aspect-ratio: 4 / 3;
	object-fit: cover !important;
	border-radius: var(--rg-r);
	box-shadow: var(--rg-e1);
	transition: transform var(--rg-dur) var(--rg-ease), box-shadow var(--rg-dur) var(--rg-ease);
}
.cozy-block-portfolio-gallery img:hover { transform: translateY(-3px); box-shadow: var(--rg-e2); }

/* the carousel arrows/pagination no longer control anything */
.cozy-block-portfolio-gallery .swiper-button-next,
.cozy-block-portfolio-gallery .swiper-button-prev,
.cozy-block-portfolio-gallery .cozy-swiper-button-next,
.cozy-block-portfolio-gallery .cozy-swiper-button-prev,
.cozy-block-portfolio-gallery .swiper-pagination { display: none !important; }

@media (prefers-reduced-motion: reduce) {
	.cozy-block-portfolio-gallery img:hover { transform: none; }
}

/* ---------------------------------------------------------------------
 * 18. INSTANT ROOF ESTIMATOR  ([rg_estimator])
 * ------------------------------------------------------------------- */
.rg-est {
	border: 1px solid var(--rg-line);
	border-radius: var(--rg-r-lg);
	box-shadow: var(--rg-e2);
	background: var(--rg-surface);
	padding: clamp(20px, 3vw, 40px);
	margin-block: var(--rg-s6);
}

.rg-est__steps {
	display: flex;
	gap: var(--rg-s2);
	list-style: none;
	margin: 0 0 var(--rg-s6);
	padding: 0;
	counter-reset: rgstep;
}
.rg-est__steps li {
	flex: 1;
	font-size: 13px;
	font-weight: 650;
	color: var(--rg-ink-faint);
	padding-top: var(--rg-s2);
	border-top: 3px solid var(--rg-line);
	transition: color var(--rg-dur) var(--rg-ease), border-color var(--rg-dur) var(--rg-ease);
}
.rg-est__steps li.is-active { color: var(--rg-brand-ink); border-top-color: var(--rg-accent); }

.rg-est__panel { display: none; }
.rg-est__panel.is-active { display: block; }
.rg-est h3 { margin-top: 0; }

.rg-est__row { margin-bottom: var(--rg-s4); }
.rg-est__row label { display: block; font-weight: 600; margin-bottom: 6px; }
.rg-est__row input, .rg-est__row select { width: 100%; }
.rg-est__row small { display: block; margin-top: 6px; color: var(--rg-ink-faint); font-size: 13.5px; }
.rg-est__row--split { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: var(--rg-s4); }

.rg-est__group { border: 0; padding: 0; margin: 0 0 var(--rg-s5); }
.rg-est__group legend { font-weight: 700; color: var(--rg-brand-ink); margin-bottom: var(--rg-s3); padding: 0; }

.rg-est__choice, .rg-est__check {
	display: flex;
	align-items: center;
	gap: var(--rg-s3);
	min-height: var(--rg-tap);
	padding: var(--rg-s2) var(--rg-s3);
	border: 1px solid var(--rg-line);
	border-radius: var(--rg-r-sm);
	margin-bottom: var(--rg-s2);
	cursor: pointer;
	transition: border-color var(--rg-dur) var(--rg-ease), background-color var(--rg-dur) var(--rg-ease);
}
.rg-est__choice:hover, .rg-est__check:hover { border-color: var(--rg-brand); background: var(--rg-surface-2); }
.rg-est__choice:has(input:checked) { border-color: var(--rg-brand); background: var(--rg-surface-3); }

.rg-est__actions {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--rg-s4);
	margin-top: var(--rg-s5);
}
.rg-est__link {
	background: none;
	border: 0;
	padding: var(--rg-s2);
	color: var(--rg-brand);
	font: inherit;
	font-weight: 600;
	text-decoration: underline;
	text-underline-offset: .18em;
	cursor: pointer;
}

.rg-est__eyebrow {
	font-size: 14px;
	font-weight: 700;
	letter-spacing: .1em;
	text-transform: uppercase;
	color: var(--rg-accent-ink);
	margin: 0 0 var(--rg-s2);
}
.rg-est__figure {
	font-size: clamp(30px, 2rem + 2vw, 52px);
	font-weight: 800;
	line-height: 1.1;
	letter-spacing: -.02em;
	color: var(--rg-brand-ink);
	margin: 0 0 var(--rg-s3);
}
.rg-est__figure--text { font-size: clamp(24px, 1.6rem + 1.2vw, 38px); }

.rg-est__measured, .rg-est__hint { color: var(--rg-ink-muted); }
.rg-est__err { color: #A3231B; font-weight: 600; }
.rg-est__ok  { color: #16624A; font-weight: 600; }

.rg-est__lead {
	margin-top: var(--rg-s6);
	padding-top: var(--rg-s6);
	border-top: 1px solid var(--rg-line);
}
.rg-est__lead h4 { margin-top: 0; }

.rg-est__smallprint {
	margin: var(--rg-s6) 0 0;
	padding-top: var(--rg-s4);
	border-top: 1px solid var(--rg-line);
	font-size: 13.5px;
	color: var(--rg-ink-faint);
}

/* ---------------------------------------------------------------------
 * 19. INC. 5000 CARD — whole card is one link
 * ---------------------------------------------------------------------
 * Stretched-link pattern: the card is the positioning context and a single
 * anchor covers it, so badge, heading, rank and supporting text are all
 * clickable while the accessibility tree still sees exactly one link with
 * a meaningful name. Keyboard users get a ring on the whole card.
 * ------------------------------------------------------------------- */
.rg-inc-card { position: relative; }

.rg-inc-card .rg-inc__link { position: static; }
.rg-inc-card .rg-inc__link::after {
	content: "";
	position: absolute;
	inset: 0;
	border-radius: inherit;
	z-index: 1;
}

.rg-inc-card:hover { box-shadow: var(--rg-e2); }
.rg-inc-card:focus-within {
	outline: 3px solid var(--rg-focus);
	outline-offset: 3px;
}
.rg-inc-card .rg-inc__link:focus-visible { outline: none; }

/* the rank is the point of the card */
/* Matches the sentence it sits in - same family, size and colour.
 * Bold is the only emphasis. */
.rg-inc__rank {
	font-family: inherit;
	font-size: inherit;
	font-weight: 700;
	letter-spacing: inherit;
	color: inherit;
}

/* ---------------------------------------------------------------------
 * 20. CONTACT MAP (/contact-us/)
 * Restores the office map the original site carried, at the same point
 * and zoom. Responsive height instead of the original fixed 250px.
 * ------------------------------------------------------------------- */
.rg-map {
	width: 100%;
	height: clamp(260px, 32vw, 400px);
	margin-block: var(--rg-s4) var(--rg-s6);
	border: 1px solid var(--rg-line);
	border-radius: var(--rg-r);
	overflow: hidden;
	background: var(--rg-surface-2);
}
.rg-map iframe { display: block; width: 100%; height: 100%; border: 0; }

/* ---------------------------------------------------------------------
 * 21. RESTORED HOMEPAGE SECTIONS
 * Galleries, the roofing-system video, the testimonial embed, blog cards
 * and the recommendations list. Core blocks only; no carousel JS.
 * ------------------------------------------------------------------- */
.rg-sec:nth-of-type(even) { background: var(--rg-surface-2); }

.rg-gallery.wp-block-gallery { gap: clamp(12px, 1.4vw, 22px); }
.rg-gallery .wp-block-image img {
	border-radius: var(--rg-r);
	box-shadow: var(--rg-e1);
	aspect-ratio: 4 / 3;
	object-fit: cover;
	transition: transform var(--rg-dur) var(--rg-ease), box-shadow var(--rg-dur) var(--rg-ease);
}
.rg-gallery .wp-block-image img:hover { transform: translateY(-3px); box-shadow: var(--rg-e2); }

/* archive thumbnails: shown at or below their 333x249 native size, never enlarged */
.rg-gallery--thumbs .wp-block-image { max-width: 236px; }
.rg-gallery--thumbs .wp-block-image img { border-radius: var(--rg-r-sm); }

.rg-video { margin: var(--rg-s5) auto var(--rg-s6); max-width: 960px; }
.rg-video video {
	display: block;
	width: 100%;
	aspect-ratio: 16 / 9;
	background: #000;
	border-radius: var(--rg-r);
	box-shadow: var(--rg-e2);
}
.rg-warranty { text-align: center; margin-top: var(--rg-s5); }

.rg-embed {
	position: relative;
	max-width: 960px;
	margin: var(--rg-s5) auto var(--rg-s5);
	aspect-ratio: 16 / 9;
	border-radius: var(--rg-r);
	overflow: hidden;
	box-shadow: var(--rg-e2);
	background: #000;
}
.rg-embed iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }

.rg-recommends { max-width: 820px; margin-inline: auto; text-align: left; }
.rg-recommends li + li { margin-top: var(--rg-s3); }

.rg-blog-grid { margin-top: var(--rg-s5); }
.rg-blog-card { padding: 0 !important; overflow: hidden; display: flex; flex-direction: column; }
.rg-blog-card__media img { display: block; width: 100%; aspect-ratio: 3 / 2; object-fit: cover; border-radius: 0; }
.rg-blog-card__body { padding: var(--rg-s5); display: flex; flex-direction: column; gap: var(--rg-s3); flex: 1; }
.rg-blog-card__kicker { font-size: 13px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--rg-accent-ink); margin: 0; }
.rg-blog-card h3 { margin: 0; font-size: clamp(18px, 1.05rem + .4vw, 22px); }
.rg-blog-card h3 a { color: var(--rg-brand-ink); text-decoration: none; }
.rg-blog-card h3 a:hover { text-decoration: underline; }
.rg-blog-card__more { margin-top: auto; font-weight: 650; color: var(--rg-brand); }

@media (prefers-reduced-motion: reduce) {
	.rg-gallery .wp-block-image img:hover { transform: none; }
}
