/**
 * CVC Towing — design layer on top of Blocksy (Concept A "Dispatch").
 *
 * Colours, fonts, sizes and spacing come from theme.json presets
 * (var(--wp--preset--*)). Blocksy's colour defaults are supplied by
 * inc/blocksy-defaults.php. Mobile-first; desktop rules in min-width queries.
 * No !important: Blocksy's dynamic CSS is beaten by order or specificity.
 */

/* ---------- Tokens ---------- */

:root {
	--cvc-ease: var(--wp--custom--ease);
	--cvc-radius: var(--wp--custom--radius--md);

	/* Blocksy reads its root font from this stack (see docs/blocksy-variables.md). */
	--theme-font-stack-default: var(--wp--preset--font-family--body);
}

/* ---------- Font fallbacks ---------- */

/*
 * Barlow Condensed is far narrower than system faces, so a heading that fits two lines in Barlow takes four in
 * the fallback and the page jumps when the font arrives (CLS). These faces scale a local bold sans to Barlow's
 * widths (size-adjust) and borrow its vertical metrics, so the swap changes letter shapes only. Values are tuned
 * in Chrome to minimise line-count changes against Barlow on 12 pages at phone widths
 * (plan 2026-10-16-theme-1-11-3). Liberation Sans is metric-compatible with Arial; Roboto (Android) has its
 * own values. No listed face: the stack falls through.
 */
@font-face {
	font-family: "Barlow Condensed Fallback";
	src: local("Arial Bold"), local("Arial-BoldMT"), local("Liberation Sans Bold"), local("LiberationSans-Bold");
	font-weight: 600 700;
	size-adjust: 76%;
	ascent-override: 131.6%;
	descent-override: 26.3%;
	line-gap-override: 0%;
}

@font-face {
	font-family: "Barlow Condensed Fallback";
	src: local("Arial Bold"), local("Arial-BoldMT"), local("Liberation Sans Bold"), local("LiberationSans-Bold");
	font-weight: 800 900;
	size-adjust: 77%;
	ascent-override: 129.9%;
	descent-override: 26%;
	line-gap-override: 0%;
}

@font-face {
	font-family: "Barlow Condensed Fallback Roboto";
	src: local("Roboto Bold"), local("Roboto-Bold");
	font-weight: 600 700;
	size-adjust: 81%;
	ascent-override: 123.5%;
	descent-override: 24.7%;
	line-gap-override: 0%;
}

@font-face {
	font-family: "Barlow Condensed Fallback Roboto";
	src: local("Roboto Bold"), local("Roboto-Bold");
	font-weight: 800 900;
	size-adjust: 82%;
	ascent-override: 122%;
	descent-override: 24.4%;
	line-gap-override: 0%;
}

/* ---------- Base ---------- */

body {
	-webkit-font-smoothing: antialiased;
}

/* Two-element selectors beat Blocksy's single-element heading rules printed later. */
body :is(h1, h2, h3, h4) {
	--theme-font-family: var(--wp--preset--font-family--display);
	--theme-text-transform: none;
	--theme-letter-spacing: 0;
	--theme-line-height: 0.95;
	--theme-font-weight: 800;
}

body h1 {
	--theme-font-size: var(--wp--preset--font-size--cvc-display);
}

body h2 {
	--theme-font-size: var(--wp--preset--font-size--cvc-xxl);
}

body h3 {
	--theme-font-size: var(--wp--preset--font-size--cvc-xl);
	--theme-font-weight: 700;
}

body h4 {
	--theme-font-size: var(--wp--preset--font-size--cvc-l);
	--theme-font-weight: 700;
	--theme-line-height: 1.2;
}

.cvc-mono,
.cvc-mono a {
	font-family: var(--wp--preset--font-family--mono);
	font-weight: 500;
}

/*
 * Two rings (surface inside, ink outside) so focus shows on light, dark and red; dark sections remap both slugs.
 * Blocksy's `a:focus-visible, button:focus-visible` (outline in the accent colour) has specificity 0,1,1 and
 * `:where()` adds none, so `:root` lifts this rule to 0,2,0: it wins on the cascade, not on file order.
 * Core's lightbox gives its "Enlarge" button `.wp-lightbox-container button:focus-visible` (0,2,1, browser ring
 * colour), so that button is listed on its own at 0,3,0 (work gallery, plan 2026-10-30).
 * Blocksy's `*, *::before, *::after { outline: none; }` removes the browser ring from the job-log and reviews
 * scrollers, which Chrome and Firefox make keyboard-focusable while they overflow. They carry no `[tabindex]` for
 * `:where()` to match, so they are listed at 0,2,0 (plan 2026-10-30-job-log-scroller-focus-ring).
 * tests/unit/FocusRingTest.php pins this.
 */
:root :where(a, button, input, select, textarea, summary, [tabindex]):focus-visible,
.wp-lightbox-container .lightbox-trigger:focus-visible,
.cvc-jobs--scroller:focus-visible,
.cvc-reviews__list:focus-visible {
	outline: 2px solid var(--wp--preset--color--ink);
	outline-offset: 2px;
	box-shadow: 0 0 0 2px var(--wp--preset--color--surface);
}

/* ---------- Buttons ---------- */

.cvc-btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 0.625rem;
	min-height: 44px;
	padding: 0.75rem 1.25rem;
	border-radius: var(--cvc-radius-btn);
	font-weight: 600;
	text-decoration: none;
	transition: transform 0.25s var(--cvc-ease), background-color 0.25s var(--cvc-ease);
}

.cvc-btn:active {
	transform: scale(0.97);
}

.cvc-btn--solid {
	background-color: var(--wp--preset--color--red);
	color: var(--wp--preset--color--white);
}

.cvc-btn--solid:hover,
.cvc-btn--solid:focus-visible {
	background-color: var(--wp--preset--color--red-press);
	color: var(--wp--preset--color--white);
}

.cvc-btn--outline {
	border: 1px solid var(--wp--preset--color--line-strong);
	color: var(--wp--preset--color--ink);
}

.cvc-btn--outline:hover {
	border-color: var(--wp--preset--color--ink);
	color: var(--wp--preset--color--ink);
}

.cvc-btn--big {
	gap: 1rem;
	padding: 1.125rem 1.625rem;
	border-radius: var(--wp--custom--radius--lg);
}

.cvc-btn__number {
	font-family: var(--wp--preset--font-family--display);
	font-size: var(--wp--preset--font-size--cvc-xl);
	font-weight: 700;
	letter-spacing: 0.02em;
	line-height: 1;
}

.cvc-btn__icon {
	flex: none;
	width: 1.125rem;
	height: 1.125rem;
}

/*
 * Header call button (cvc_render_call_link( 'header', 'compact' )): a 44 px circle with the phone icon on
 * phones, icon and number from 560 px. The number is always in the link, so its accessible name is the number
 * (WCAG 2.5.3); below 560 px it is clipped with the same declarations as core's .screen-reader-text. That
 * helper class cannot switch off at a breakpoint, which is why the rule lives here. Never display: none.
 */
.cvc-btn--compact {
	position: relative;
	min-width: 44px;
	padding: 0.625rem;
	border-radius: var(--wp--custom--radius--pill);
}

.cvc-btn--compact .cvc-btn__icon {
	width: 1.25rem;
	height: 1.25rem;
}

.cvc-btn--compact .cvc-btn__number {
	position: absolute;
	width: 1px;
	height: 1px;
	overflow: hidden;
	clip-path: inset(50%);
	white-space: nowrap;
}

@media (min-width: 560px) {
	.cvc-btn--compact {
		padding: 0.625rem 1.125rem;
	}

	.cvc-btn--compact .cvc-btn__icon {
		width: 1.125rem;
		height: 1.125rem;
	}

	.cvc-btn--compact .cvc-btn__number {
		position: static;
		width: auto;
		height: auto;
		overflow: visible;
		clip-path: none;
		font-size: var(--wp--preset--font-size--cvc-l);
	}
}

/* ---------- Eyebrow and live dot ---------- */

.cvc-eyebrow {
	display: flex;
	align-items: center;
	gap: 0.625rem;
	font-family: var(--wp--preset--font-family--mono);
	font-size: var(--wp--preset--font-size--cvc-xs);
	font-weight: 500;
	letter-spacing: 0.14em;
	text-transform: uppercase;
	color: var(--wp--preset--color--mute);
}

.cvc-eyebrow--live::before {
	content: "";
	flex: none;
	width: 8px;
	height: 8px;
	border-radius: 50%;
	background-color: var(--wp--preset--color--ok);
	animation: cvc-pulse 2s infinite;
}

@keyframes cvc-pulse {
	0% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--wp--preset--color--ok) 60%, transparent); }
	70%, 100% { box-shadow: 0 0 0 10px color-mix(in srgb, var(--wp--preset--color--ok) 0%, transparent); }
}

/* ---------- Header (Blocksy) ---------- */

#header {
	position: sticky;
	top: 0;
	z-index: 40;
	border-bottom: 1px solid var(--wp--preset--color--line);
}

/*
 * Row height and logo size. Blocksy prints --height on the row (120 px desktop, 70 px mobile) and
 * --logo-max-height only when it is not 50, and the image is 4.2 times wider than high: at 50 px high it was
 * 209 px wide and the call button covered it on phones. The #header selector beats Blocksy's generated rule.
 */
#header [data-row*="middle"] {
	--height: 64px;
}

#header .site-logo-container {
	--logo-max-height: 34px;
}

/* The logo link is 34 to 40 px high; this reaches 5 px above and below it so the touch area is at least 44 px without moving anything. */
#header .site-logo-container::after {
	position: absolute;
	inset: -5px 0;
	content: "";
}

@media (min-width: 560px) {
	#header .site-logo-container {
		--logo-max-height: 38px;
	}
}

@media (min-width: 1000px) {
	#header [data-row*="middle"] {
		--height: 72px;
	}

	/*
	 * Blocksy lays the row out as 1fr auto 1fr, so the menu column (the middle one) can be no wider than the row minus
	 * twice the widest side column. The call button and hours made that about 395 px at 1366 px and Blocksy's own
	 * "More" overflow hid About and Contact. The side columns now take only their content, the menu column the rest.
	 */
	#header [data-row*="middle"][data-column-set="3"] > .ct-container {
		grid-template-columns: auto 1fr auto;
	}

	#header .site-logo-container {
		--logo-max-height: 40px;
	}
}

/* The logo may never be wider than its column (a safety net next to the grid rule in "Mobile header"). */
#header .site-logo-container img {
	max-width: 100%;
}

/*
 * Menu links: Blocksy sets 12 px uppercase bold through variables on the link. A plain reading size, sentence case and
 * a wider hit area read as navigation rather than labels. Blocksy's own 2 px red hover bar stays.
 */
#header [data-id="menu"] .ct-menu-link {
	--theme-font-size: 0.9375rem;
	--theme-font-weight: 500;
	--theme-text-transform: none;
	--menu-item-padding: 0 0.875rem;
}

/*
 * Services dropdown. Blocksy's default is a dark box with 25 px rows; this is a light card (surface, border, the
 * shared shadow) with 44 px rows and a width that keeps "Sea cans and containers" on one line.
 */
#header [data-id="menu"] .sub-menu {
	min-width: 16rem;
	border: 1px solid var(--wp--preset--color--line-strong);
	border-radius: 0 0 var(--wp--custom--radius--md) var(--wp--custom--radius--md);
	background-color: var(--wp--preset--color--surface);
	box-shadow: var(--cvc-shadow-lift);
}

#header [data-id="menu"] .sub-menu .ct-menu-link {
	--theme-link-initial-color: var(--wp--preset--color--ink);
	--theme-link-hover-color: var(--wp--preset--color--red-text);
	display: flex;
	align-items: center;
	min-height: 2.75rem;
	padding-inline: 1rem;
	white-space: nowrap;
}

/* Call button and hours (parts/header-call.php). Blocksy's flow margins are reset so the row stays 44 px high. */
#header .ct-header-cta {
	display: flex;
	align-items: center;
	gap: 1rem;
}

#header .ct-header-cta > * {
	margin: 0;
}

.cvc-header-hours {
	display: none;
	color: var(--wp--preset--color--mute);
	font-family: var(--wp--preset--font-family--mono);
	font-size: var(--wp--preset--font-size--cvc-xs);
	white-space: nowrap;
}

@media (min-width: 1200px) {
	.cvc-header-hours {
		display: block;
	}
}

/* The mobile menu button is an 18 px icon in Blocksy's own CSS (main.min.css 2.1.58, .ct-header-trigger has no size rule): give it a 44 px touch target, outlined to sit beside the round call button. */
.ct-header-trigger {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 44px;
	min-height: 44px;
	border: 1px solid var(--wp--preset--color--line-strong);
	border-radius: var(--wp--custom--radius--pill);
}

/* Core Search block button (the Blog page): 38 px by default, under the 44 px target size. */
.wp-block-search__button {
	min-width: 44px;
	min-height: 44px;
}

/* ---------- Reveal ---------- */

/* Hidden only once cvc.js has added .cvc-js, so content never disappears without JavaScript. */
.cvc-js .cvc-reveal {
	opacity: 0;
	transform: translateY(24px);
	transition: opacity 0.9s var(--cvc-ease), transform 0.9s var(--cvc-ease);
}

.cvc-js .cvc-reveal.is-in {
	opacity: 1;
	transform: none;
}

@media (prefers-reduced-motion: reduce) {
	.cvc-js .cvc-reveal,
	.cvc-js .cvc-reveal.is-in {
		opacity: 1;
		transform: none;
		transition: none;
	}

	.cvc-eyebrow--live::before {
		animation: none;
	}

	.cvc-btn {
		transition: none;
	}
}

/* ---------- Final call band (printed before the footer) ---------- */

.cvc-final {
	padding: var(--wp--preset--spacing--60) var(--theme-content-edge-spacing, 1rem);
}

.cvc-final__inner {
	display: grid;
	gap: var(--wp--preset--spacing--40);
	max-width: var(--theme-normal-container-max-width, 1290px);
	margin-inline: auto;
	padding: var(--wp--preset--spacing--50) var(--wp--preset--spacing--40);
	border-radius: var(--cvc-radius-card);
	background-color: var(--wp--preset--color--red);
	color: var(--wp--preset--color--white);
}

body .cvc-final__title {
	--theme-font-size: var(--wp--preset--font-size--cvc-xxl);
	margin: 0;
	color: var(--wp--preset--color--white);
}

.cvc-final__number {
	display: block;
	/* 44 px touch target (measured 41 px at 375 px on the live site). */
	padding-block: 0.25rem;
	font-family: var(--wp--preset--font-family--display);
	font-size: clamp(2.25rem, 6vw, 3.5rem);
	font-weight: 800;
	line-height: 1;
	color: var(--wp--preset--color--white);
	text-decoration: none;
}

.cvc-final__number:hover,
.cvc-final__number:focus-visible {
	color: var(--wp--preset--color--white);
	text-decoration: underline;
}

.cvc-final__note {
	margin: 0.5rem 0 0;
	color: var(--wp--preset--color--white);
}

@media (min-width: 900px) {
	.cvc-final__inner {
		grid-template-columns: 1.4fr 1fr;
		align-items: center;
		padding: var(--wp--preset--spacing--70);
	}

	.cvc-final__call {
		text-align: end;
	}
}

/* ---------- Footer (Blocksy widget areas, filled by CVC Setup) ---------- */

/* Approved logo 09, dark lockup (plan Part I). Width and height attributes come from inc/images.php. */
#footer .cvc-footer__logo {
	margin: 0 0 var(--wp--preset--spacing--30);
}

#footer .cvc-footer__logo img {
	width: 240px;
	max-width: 100%;
	height: auto;
}

/* Business facts: label above the value, one per line. */
#footer .cvc-fact {
	display: flex;
	flex-direction: column-reverse;
	gap: 0.125rem;
	margin-top: 1rem;
}

#footer .cvc-fact__label {
	font-family: var(--wp--preset--font-family--mono);
	font-size: var(--wp--preset--font-size--cvc-xs);
	letter-spacing: 0.14em;
	text-transform: uppercase;
	color: var(--wp--preset--color--mute);
}

#footer .cvc-fact__value a {
	display: inline-flex;
	align-items: center;
	min-height: 44px;
	color: var(--wp--preset--color--ink);
}

#footer .widget-title {
	font-family: var(--wp--preset--font-family--mono);
	letter-spacing: 0.14em;
	text-transform: uppercase;
}

#footer .widget_nav_menu ul {
	margin: 0;
	padding: 0;
	list-style: none;
}

/* 44 px tap targets on phones; tighter rows once there is a pointer. */
#footer .widget_nav_menu a {
	display: inline-flex;
	align-items: center;
	min-height: 44px;
	color: var(--wp--preset--color--ink-soft);
	text-decoration: none;
}

#footer .widget_nav_menu a:hover,
#footer .widget_nav_menu [aria-current="page"] {
	color: var(--wp--preset--color--night-red-text);
	text-decoration: underline;
}

@media (min-width: 900px) and (pointer: fine) {
	#footer .widget_nav_menu a {
		min-height: 32px;
	}
}

/* ---------- Mobile call bar ---------- */

.cvc-callbar {
	position: fixed;
	inset-inline: 0.75rem;
	bottom: 0.75rem;
	z-index: 50;
	display: grid;
	grid-template-columns: 1fr auto;
	gap: 0.5rem;
	padding: 0.5rem;
	border: 1px solid var(--wp--preset--color--night-line);
	border-radius: var(--cvc-radius-card);
	background-color: var(--wp--preset--color--night);
	box-shadow: var(--cvc-shadow-lift);
}

.cvc-callbar .cvc-btn {
	min-height: 52px;
	border-radius: var(--cvc-radius-btn);
	font-size: var(--wp--preset--font-size--cvc-l);
}

.cvc-callbar__sms {
	aspect-ratio: 1;
	padding: 0;
	border-color: var(--wp--preset--color--night-line-strong);
	background-color: var(--wp--preset--color--night-surface);
	color: var(--wp--preset--color--night-ink);
}

/* Keep the footer's last line above the bar; the space takes the footer's dark background. */
#footer {
	padding-bottom: 5.5rem;
}

@media (min-width: 900px) {
	.cvc-callbar {
		display: none;
	}

	#footer {
		padding-bottom: 0;
	}
}

/* ---------- Mobile header ---------- */

/*
 * Blocksy's mobile middle row is a two-column grid of equal tracks, and the end column (call button + menu
 * button) is wider than its track. Let the logo column shrink and the end column take its own width.
 * Selectors confirmed in Blocksy 2.1.58 markup (docs/blocksy-variables.md).
 */
#header [data-device="mobile"] [data-row="middle"] > .ct-container {
	grid-template-columns: minmax(0, 1fr) auto;
}

#header [data-device="mobile"] .site-branding[data-id="logo"] {
	min-width: 0;
}

/* ---------- Mobile menu (Blocksy offcanvas) ---------- */

/*
 * Blocksy's panel is a dark slab (rgba(18, 21, 25, 0.98)) with small 20 px links. #offcanvas is in the dark
 * list of sections.css, so presets here resolve to their night twins. The dispatch card
 * (parts/menu-dispatch.php) is printed by the theme through blocksy:header:offcanvas:mobile:bottom.
 */
/* Blocksy's rule is [data-header*="type-1"] #offcanvas .ct-panel-inner and is printed after this stylesheet; the extra attribute selector wins the tie. */
#offcanvas.ct-panel[data-behaviour*="side"] .ct-panel-inner {
	max-width: min(100%, 420px);
	background-color: var(--wp--preset--color--night);
}

#offcanvas .ct-toggle-close {
	min-width: 44px;
	min-height: 44px;
}

#offcanvas .ct-panel-content-inner {
	display: flex;
	flex-direction: column;
	gap: var(--wp--preset--spacing--40);
	min-height: 100%;
	padding-bottom: calc(1.25rem + env(safe-area-inset-bottom, 0px));
}

#offcanvas .mobile-menu li {
	border-bottom: 1px solid var(--wp--preset--color--line);
}

/* Submenu rows (Services): the same rows one step smaller, and a 44 px toggle button. */
#offcanvas .mobile-menu .sub-menu .ct-menu-link {
	--theme-font-size: 1.5rem;
	min-height: 3rem;
	padding-inline-start: 1rem;
}

#offcanvas .mobile-menu .ct-toggle-dropdown-mobile {
	min-width: 44px;
	min-height: 44px;
}

#offcanvas .mobile-menu .ct-menu-link {
	--theme-font-family: var(--wp--preset--font-family--display);
	--theme-font-size: 2rem;
	--theme-font-weight: 700;
	--theme-text-transform: none;
	--theme-line-height: 1;
	display: flex;
	align-items: center;
	width: 100%;
	min-height: 3.5rem;
	color: var(--wp--preset--color--ink);
}

#offcanvas .mobile-menu .ct-menu-link:hover,
#offcanvas .mobile-menu .ct-menu-link:focus-visible,
#offcanvas .mobile-menu li[class*="current-menu-"] > .ct-menu-link {
	color: var(--wp--preset--color--red-text);
}

.cvc-menu-dispatch {
	display: grid;
	gap: 0.875rem;
	width: 100%;
	padding: 1.25rem;
	border: 1px solid var(--wp--preset--color--line-strong);
	border-radius: var(--cvc-radius-card);
	background-color: var(--wp--preset--color--surface);
}

.cvc-menu-dispatch > * {
	margin: 0;
}

/* Pinned to the bottom of the panel. Blocksy gives every child of .ct-panel-content-inner a 20 px bottom margin through an ID selector, so this one needs an ID too. */
#offcanvas .ct-panel-content-inner > .cvc-menu-dispatch {
	margin-top: auto;
}

.cvc-menu-dispatch .cvc-btn {
	width: 100%;
	min-height: 3.5rem;
	border-radius: var(--wp--custom--radius--lg);
}

.cvc-menu-dispatch__hours {
	color: var(--wp--preset--color--mute);
	font-family: var(--wp--preset--font-family--mono);
	font-size: var(--wp--preset--font-size--cvc-xs);
}

/* ---------- Footer columns ---------- */

/* Blocksy footer rows read --grid-template-columns and --columns-gap (docs/blocksy-variables.md). */
@media (min-width: 900px) {
	#footer [data-row="middle"] > .ct-container {
		--grid-template-columns: 1.45fr repeat(3, 1fr);
		--columns-gap: var(--wp--preset--spacing--50);
	}
}
