/*
Theme Name: DeviceTech
Theme URI: https://www.devicetech.co.uk/
Author: Lily Paw Digital
Author URI: https://www.lilypawdigital.xyz/
Description: A custom WordPress theme for DeviceTech Systems Ltd — CCTV & alarm systems, Starlink broadband, home entertainment, and custom PC builds, based in Blaydon-on-Tyne, serving the Scottish Borders to North Yorkshire. Colours and type are grounded in DeviceTech's own brand mark. Built by Lily Paw Digital.
Version: 3.17.0
Requires at least: 6.0
Requires PHP: 7.4
License: GNU General Public License v2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html
Text Domain: devicetech
*/

/* ==========================================================================
   0. Self-hosted fonts (no third-party font CDN — see assets/fonts/LICENSE.txt)
   ========================================================================== */
@font-face {
	font-family: 'Anton';
	src: url('assets/fonts/anton-latin-400-normal.woff2') format('woff2');
	font-weight: 400;
	font-style: normal;
	font-display: swap;
}
@font-face {
	font-family: 'Inter';
	src: url('assets/fonts/inter-latin-400-normal.woff2') format('woff2');
	font-weight: 400;
	font-style: normal;
	font-display: swap;
}
@font-face {
	font-family: 'Inter';
	src: url('assets/fonts/inter-latin-500-normal.woff2') format('woff2');
	font-weight: 500;
	font-style: normal;
	font-display: swap;
}
@font-face {
	font-family: 'Inter';
	src: url('assets/fonts/inter-latin-600-normal.woff2') format('woff2');
	font-weight: 600;
	font-style: normal;
	font-display: swap;
}
@font-face {
	font-family: 'Inter';
	src: url('assets/fonts/inter-latin-700-normal.woff2') format('woff2');
	font-weight: 700;
	font-style: normal;
	font-display: swap;
}
/* ==========================================================================
   1. Design tokens — colours grounded in DeviceTech's real logo/site
      (#007cc4 / #0099da / #97bfe6 / #40a3fb / #000 / #222 / #4e4e4e sampled
      directly from the current devicetech.co.uk logo and homepage)
   ========================================================================== */
:root {
	--dt-black: #000000;
	--dt-charcoal: #1c1f24;
	--dt-charcoal-soft: #2a2e35;
	--dt-slate: #4e4e4e;
	--dt-blue: #007cc4;
	--dt-blue-bright: #0099da;
	--dt-blue-vivid: #40a3fb;
	--dt-blue-tint: #97bfe6;
	--dt-blue-tint-10: #eaf3fc;
	--dt-white: #ffffff;
	--dt-ink: #171b21;
	--dt-ink-soft: #4a5261;
	--dt-muted: #78808f;
	--dt-line: #e1e6ed;
	--dt-bg: #ffffff;
	--dt-bg-alt: #f4f7fb;
	--dt-success: #1a8f52;
	--dt-danger: #c9372c;

	--dt-radius: 14px;
	--dt-radius-sm: 8px;
	--dt-shadow: 0 24px 48px -24px rgba(0, 20, 40, 0.28);
	--dt-shadow-sm: 0 10px 24px -14px rgba(0, 20, 40, 0.3);

	/* Anton is a single-weight (400) display face — bold, tall, condensed
	   letterforms for headlines and big numbers. Every rule below that sets
	   --dt-font-display alongside a font-weight uses 400, since Anton has
	   no lighter/heavier cut to fall back on (the browser would otherwise
	   synthesize a faux-bold, which looks rough on a face this heavy
	   already). */
	--dt-font-display: 'Anton', 'Impact', sans-serif;
	--dt-font-body: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
	/* Small tracked-out labels (eyebrows, footer headings) used to run in a
	   monospace face — dropped in favour of the body face with letter-
	   spacing, since a code-editor typeface was part of what made the site
	   read as "robotic" rather than warm. */
	--dt-font-label: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
	--dt-container: 1200px;

	--ease-enter: cubic-bezier(0.16, 1, 0.3, 1);
	--ease-interact: cubic-bezier(0.22, 1, 0.36, 1);

	/* Powers the block editor's "Inner blocks use content width" layout on
	   Group blocks (add_theme_support('align-wide') without a theme.json
	   still needs these defined manually for classic themes). */
	--wp--style--global--content-size: 1200px;
	--wp--style--global--wide-size: 1400px;
}

.is-layout-constrained > :where(:not(.alignwide):not(.alignfull)),
.is-layout-flow > :where(:not(.alignwide):not(.alignfull)) {
	max-width: var(--wp--style--global--content-size);
	margin-left: auto;
	margin-right: auto;
	padding-left: 24px;
	padding-right: 24px;
}
.is-layout-constrained > .alignwide { max-width: var(--wp--style--global--wide-size); }
.wp-block-group.alignfull { padding-left: 0; padding-right: 0; }

/* Neutralise WordPress's automatic block-gap spacing (the default ~2em
   margin core injects between a Group block's direct children) inside our
   structural section/card wrappers — those already have exact, intentional
   spacing defined per component below, so the two shouldn't stack. */
.dt-hero, .dt-hero__inner,
.dt-services, .dt-service-grid, .dt-card,
.dt-coverage, .dt-coverage__grid,
.dt-why-us, .dt-why-us__inner,
.dt-process, .dt-process-grid, .dt-process-step,
.dt-testimonials,
.dt-cta-banner, .dt-cta-banner__inner,
.dt-section-heading {
	--wp--style--block-gap: 0px;
}

/* ==========================================================================
   2. Reset & base
   ========================================================================== */
*, *::before, *::after { box-sizing: border-box; }
html { scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) {
	html { scroll-behavior: auto; }
}
body {
	margin: 0;
	font-family: var(--dt-font-body);
	color: var(--dt-ink);
	background: var(--dt-bg);
	font-size: 16px;
	line-height: 1.65;
	-webkit-font-smoothing: antialiased;
}
img { max-width: 100%; height: auto; display: block; }
a { color: var(--dt-blue); text-decoration: none !important; transition: color .18s var(--ease-interact); }
a:hover { color: var(--dt-blue-bright); }
/* Restore underlines only for plain inline links inside prose, where they
   help readers spot a link within a paragraph of body text. */
.page-content p a, .entry-content p a, .dt-contact-info p a {
	text-decoration: underline !important;
	text-underline-offset: 2px;
}
ul { padding: 0; margin: 0; list-style: none; }
h1, h2, h3, h4, h5 {
	font-family: var(--dt-font-display);
	color: var(--dt-black);
	line-height: 1.15;
	margin: 0 0 .5em;
	font-weight: 400;
	letter-spacing: 0;
}
h1 { font-size: clamp(2.2rem, 4.4vw, 3.4rem); }
h2 { font-size: clamp(1.7rem, 3.2vw, 2.4rem); }
h3 { font-family: var(--dt-font-body); font-weight: 700; font-size: 1.2rem; letter-spacing: 0; }
p { margin: 0 0 1em; color: var(--dt-ink-soft); }
.wp-block-list, .page-content ul { list-style: disc; padding-left: 1.4em; margin-bottom: 1em; }
.wp-block-list li, .page-content ul li { color: var(--dt-ink-soft); margin-bottom: .45em; }
.container {
	max-width: var(--dt-container);
	margin: 0 auto;
	padding: 0 24px;
}
.screen-reader-text {
	position: absolute !important;
	clip: rect(1px,1px,1px,1px);
	width: 1px; height: 1px; overflow: hidden;
}
.skip-link { position: fixed; top: -60px; left: 0; background: var(--dt-black); color: #fff; padding: 12px 20px; z-index: 10000; transition: top .2s var(--ease-interact); }
.skip-link:focus { top: 0; }

/* Icons (self-hosted inline SVGs, see assets/icons) */
.dt-icon { display: inline-block; width: 1em; height: 1em; fill: currentColor; vertical-align: -0.125em; }

/* Buttons — min 44px touch target */
.btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 8px;
	min-height: 48px;
	padding: 12px 28px;
	border-radius: 999px;
	font-weight: 700;
	font-size: .95rem;
	border: 2px solid transparent;
	cursor: pointer;
	transition: transform .18s var(--ease-interact), box-shadow .18s var(--ease-interact), background .18s var(--ease-interact), color .18s var(--ease-interact), border-color .18s var(--ease-interact);
	white-space: nowrap;
}
.btn:hover { transform: translateY(-2px); }
.btn:focus-visible { outline: 3px solid var(--dt-blue-vivid); outline-offset: 2px; }
.btn--primary { background: var(--dt-blue); color: #fff; box-shadow: var(--dt-shadow-sm); }
.btn--primary:hover { background: var(--dt-blue-bright); color: #fff; }
.btn--ghost { background: transparent; color: var(--dt-black); border-color: var(--dt-line); }
.btn--ghost:hover { border-color: var(--dt-blue); color: var(--dt-blue); }
.btn--ghost-light { background: transparent; color: #fff; border-color: rgba(255,255,255,.4); }
.btn--ghost-light:hover { border-color: #fff; color: #fff; }
.btn--outline { background: transparent; color: var(--dt-black); border-color: var(--dt-black); }
.btn--outline:hover { background: var(--dt-black); color: #fff; }
.btn--light { background: #fff; color: var(--dt-black); }
.btn--outline-light { background: transparent; color: #fff; border-color: rgba(255,255,255,.55); }
.btn--outline-light:hover { background: rgba(255,255,255,.12); color: #fff; }
.btn--lg { padding: 15px 32px; font-size: 1rem; }
.btn--full { width: 100%; }

/* Native block-editor buttons (Buttons block) — styled to match the theme's
   pill buttons so the client can just use core blocks + our colour palette
   rather than remembering custom classes. Fill = default; Outline = core's
   built-in "Outline" style; colours come from the block's own colour picker
   using the DeviceTech swatches registered in functions.php. */
.wp-block-buttons { gap: 14px; }
.wp-block-button__link {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-height: 48px;
	padding: 12px 28px !important;
	border-radius: 999px !important;
	font-weight: 700;
	font-size: .95rem;
	transition: transform .18s var(--ease-interact), box-shadow .18s var(--ease-interact);
}
.wp-block-button:not(.is-style-outline) .wp-block-button__link:not([style*="background-color"]) {
	background-color: var(--dt-blue);
	color: #fff;
	box-shadow: var(--dt-shadow-sm);
}
.is-style-outline .wp-block-button__link {
	border: 2px solid currentColor;
}
.wp-block-button__link:hover { transform: translateY(-2px); }
.wp-block-button__link:focus-visible { outline: 3px solid var(--dt-blue-vivid); outline-offset: 2px; }

.eyebrow {
	display: inline-flex;
	align-items: flex-start;
	gap: 8px;
	font-family: var(--dt-font-label);
	font-size: .8rem;
	font-weight: 700;
	line-height: 1.5;
	letter-spacing: .06em;
	text-transform: uppercase;
	color: var(--dt-blue);
	margin-bottom: 14px;
}
/* align-items: flex-start (not center) plus a small fixed margin-top keeps
   the little bar pinned beside the first line's cap-height — with center
   alignment, a longer eyebrow that wraps to two lines (e.g. the homepage
   hero's) drags the bar down into the gap between the lines, where it reads
   as a stray underscore rather than a leading mark. */
.eyebrow::before { content: ""; flex-shrink: 0; width: 18px; height: 2px; margin-top: 8px; background: var(--dt-blue-vivid); border-radius: 2px; }

/* ==========================================================================
   4. Top bar & header
   ========================================================================== */
.top-bar { background: var(--dt-black); color: rgba(255,255,255,.85); font-size: .85rem; }
.top-bar__inner { display: flex; align-items: center; justify-content: space-between; padding: 8px 24px; gap: 16px; flex-wrap: wrap; }
.top-bar__info { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.top-bar__info a { color: #fff; font-weight: 600; display: inline-flex; align-items: center; gap: 6px; min-height: 32px; }
.top-bar__divider { opacity: .4; }
.top-bar__social { display: flex; gap: 6px; }
.top-bar__social a { color: rgba(255,255,255,.75); width: 32px; height: 32px; display: inline-flex; align-items: center; justify-content: center; border-radius: 50%; font-size: .85rem; }
.top-bar__social a:hover { color: #fff; background: rgba(255,255,255,.12); }

.site-header {
	position: sticky;
	top: 0;
	z-index: 999;
	background: rgba(255,255,255,.94);
	border-bottom: 1px solid var(--dt-line);
}
/* The frosted-glass blur lives on this pseudo-element rather than directly
   on .site-header. A `backdrop-filter` (like `transform` or `filter`)
   makes the element it's on the containing block for any position:fixed
   descendant — which was silently trapping the mobile nav drawer and its
   dimmed backdrop inside the header's own ~80px-tall box instead of the
   full viewport, so the backdrop never visibly dimmed the page and the
   drawer's height came out wrong. Keeping the blur on a decorative
   ::before instead means .site-header itself stays filter-free, so its
   fixed-position descendants size against the real viewport again. */
.site-header::before {
	content: "";
	position: absolute;
	inset: 0;
	backdrop-filter: blur(10px);
	-webkit-backdrop-filter: blur(10px);
	pointer-events: none;
}
.site-header__inner {
	position: relative;
	z-index: 1;
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 16px;
	padding: 12px 24px;
	/* Wider than the standard .container cap — with the logo, all 6 nav
	   links, and the CTA button, the header needs more room than
	   var(--dt-container) (1200px) gives it, or the nav wraps onto a
	   second line well before the hamburger breakpoint kicks in. */
	max-width: 1320px;
}
.site-logo { display: inline-flex; align-items: center; }
.site-logo img { height: 52px; width: auto; display: block; }
.site-logo--footer { display: inline-flex; margin-bottom: 16px; }
.site-logo--footer img { height: 48px; width: auto; }
.custom-logo-link img { height: 52px; width: auto; }

.main-navigation { flex: 1; display: flex; justify-content: center; }
/* The close button and CTA/phone footer only belong to the mobile drawer —
   without this they render as extra inline items in the desktop nav row,
   forcing it to wrap and duplicating the "Get a Free Quote" button. */
.nav-close, .main-navigation__footer { display: none; }
.primary-menu { display: flex; gap: 2px; flex-wrap: wrap; align-items: center; }
.primary-menu > .menu-item { position: relative; }
.primary-menu .menu-link {
	display: inline-flex;
	align-items: center;
	min-height: 44px;
	padding: 10px 10px;
	color: var(--dt-ink);
	font-weight: 600;
	font-size: .95rem;
	border-radius: 8px;
}
.primary-menu .menu-link:hover { color: var(--dt-blue); background: var(--dt-bg-alt); }
.primary-menu .sub-menu {
	position: absolute;
	top: 100%; left: 0;
	background: #fff;
	border: 1px solid var(--dt-line);
	border-radius: var(--dt-radius-sm);
	box-shadow: var(--dt-shadow);
	min-width: 220px;
	padding: 8px;
	opacity: 0;
	visibility: hidden;
	transform: translateY(6px);
	transition: opacity .2s var(--ease-interact), transform .2s var(--ease-interact), visibility .2s;
}
.primary-menu > .menu-item:hover > .sub-menu,
.primary-menu > .menu-item:focus-within > .sub-menu { opacity: 1; visibility: visible; transform: translateY(0); }
.submenu-toggle { display: none; }

.site-header__cta { display: flex; align-items: center; }
.menu-toggle {
	display: none;
	flex-direction: column;
	gap: 5px;
	background: none;
	border: none;
	cursor: pointer;
	width: 44px; height: 44px;
	align-items: center;
	justify-content: center;
}
.menu-toggle__bar { width: 22px; height: 2px; background: var(--dt-black); border-radius: 2px; }

/* ==========================================================================
   5. Editor content wrapper — the_content() output, styled to match design
   ========================================================================== */
.entry-content, .page-content { padding: 0; }
.page-content > .wp-block-group:first-child,
.entry-content > *:first-child { margin-top: 0; }

/* Generic section rhythm for top-level blocks dropped straight into a Page */
.page-content > .wp-block-group,
.page-content > .wp-block-columns,
.page-content > .wp-block-cover { margin-bottom: 0; }

/* ==========================================================================
   6. Hero — class "dt-hero" on the outer full-width Group (section chrome).
      A real-photo slideshow: several of DeviceTech's own install/repair
      photos crossfade behind the copy, with dot and arrow controls so a
      visitor can jump to a specific one rather than only watching it
      cycle. A constant scrim sits above every slide as one unchanging
      layer, so the vignette never has to be redefined per photo. This
      leads with the actual work rather than a generic text/image split.
   ========================================================================== */
.dt-hero {
	position: relative;
	display: flex;
	align-items: center;
	min-height: 560px;
	padding: 72px 0 64px;
	overflow: hidden;
	background-color: var(--dt-black);
}
/* Note: this hero box is always much wider than it is tall, and far wider
   than any of the slide photos' own aspect ratios, so object-fit: cover is
   always width-bound here — each image's rendered width already equals
   the box width with no horizontal slack, which makes object-position's
   X value mostly a no-op. Only the Y value reliably does anything above
   the 781px breakpoint below. */
/* max-width/margin resets on .dt-hero__slides and .dt-hero__scrim below:
   both are direct children of the Group block's own inner container, which
   WordPress's core "constrained layout" CSS auto-centers with a max-width
   and left/right margins (the same mechanism documented below for
   .dt-hero__inner, applied here to elements that are NOT supposed to be
   width-constrained). Since both are already position: absolute; inset: 0,
   that margin doesn't just fail to center them — it shrinks the box inward
   from both edges, leaving a bright, un-darkened sliver of the raw photo
   visible down each side. Resetting them here is what makes inset: 0 actually
   mean "full width of .dt-hero", not "full width minus WordPress's own
   auto-margins". */
.dt-hero__slides {
	max-width: none;
	margin-left: 0;
	margin-right: 0;
}
.dt-hero__slide {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
	object-position: 50% 40%;
	opacity: 0;
	transition: opacity 1.4s var(--ease-enter);
	z-index: 0;
}
.dt-hero__slide.is-active { opacity: 1; }
/* A flat wash across the whole photo, not just a vignette at the edges —
   several very different photos (a dark wood beam, a bright white repair
   desk) cycle behind this, and a bright, unobscured middle reads fine on
   the dark ones but leaves the copy and stats sitting on raw, low-contrast
   photo on the bright ones. One consistent tint over the full image keeps
   every photo readable without needing per-photo tuning. */
.dt-hero__scrim {
	position: absolute;
	inset: 0;
	z-index: 1;
	max-width: none;
	margin-left: 0;
	margin-right: 0;
	background: rgba(6, 14, 26, .62);
}
.dt-hero__inner { max-width: 560px; position: relative; z-index: 2; }
/* The header above already carries the logo on every page — this repeats
   it, much larger, as a real second element of the hero's composition:
   text on the left, the brand mark on the right, both sitting over the
   same full-image tint (see .dt-hero__scrim above). Positioned as a
   percentage of the full hero width (not
   inside the same 1200px column as the copy) so it stays clear of the
   subject at any viewport width. logo-dark.png (not the header's
   logo-light.png) is the variant with a light wordmark, built for a dark
   background rather than the header's white one. Mobile drops this
   entirely instead of shrinking it further — see the 781px breakpoint. */
.dt-hero__logo {
	position: absolute;
	top: 50%;
	right: 10%;
	transform: translateY(-50%);
	z-index: 2;
	height: 220px;
	width: auto;
	filter: drop-shadow(0 8px 20px rgba(0, 0, 0, .45));
	/* Also a direct child of the Group block's constrained inner container
	   (see .dt-hero__scrim above) - resetting these keeps its position
	   anchored purely to "right: 10%" rather than WordPress's own
	   auto-margin centering, even if a future core update changes how that
	   centering resolves for a partially-positioned element like this one. */
	max-width: none;
	margin-left: 0;
	margin-right: 0;
}
/* Overrides for the base .eyebrow/h1/p rules, scoped to the hero: white
   text reads over the darkened photo where the site's default ink colours
   (tuned for a white background) would not. */
.dt-hero .eyebrow { color: #bcd8f5; }
.dt-hero .eyebrow::before { background: var(--dt-blue-vivid); }
.dt-hero__inner h1 { color: #fff; margin-bottom: .45em; }
.dt-hero__inner p { color: rgba(255, 255, 255, .88); font-size: 1.1rem; max-width: 46ch; margin-bottom: 28px; }
.dt-hero__actions {
	display: flex;
	align-items: center;
	flex-wrap: wrap;
	gap: 30px;
	margin: 0 0 30px;
}
/* The phone number is a real alternative action, not a second button of
   equal weight next to "Get a Free Quote" — a plain text link keeps the
   visual hierarchy honest (see design rule 9: don't make every button
   equally dominant). */
.dt-hero__phone { display: flex; flex-direction: column; line-height: 1.25; }
.dt-hero__phone-label { font-family: var(--dt-font-label); font-size: .78rem; font-weight: 600; text-transform: uppercase; letter-spacing: .04em; color: rgba(255, 255, 255, .65); }
.dt-hero__phone-number { font-size: 1.05rem; font-weight: 700; color: #fff; }
.dt-hero__phone:hover .dt-hero__phone-number,
.dt-hero__phone:focus-visible .dt-hero__phone-number { color: var(--dt-blue-vivid); }

.dt-hero__stats {
	display: flex;
	flex-wrap: wrap;
	gap: 28px;
	border-top: 1px solid rgba(255, 255, 255, .25);
	padding-top: 18px;
}
.dt-hero__stats div { font-size: .82rem; font-weight: 600; color: rgba(255, 255, 255, .85); }
.dt-hero__stats strong { display: block; font-family: var(--dt-font-display); font-size: 1.3rem; font-weight: 400; color: #fff; line-height: 1.3; }

/* Slideshow controls — dots to jump straight to a specific photo. Sits in
   the same layer as the copy (z-index 2, above the scrim), clear of the
   text column and, on desktop, the logo. */
.dt-hero__dots {
	position: absolute;
	left: 50%;
	bottom: 22px;
	transform: translateX(-50%);
	z-index: 2;
	display: flex;
	gap: 10px;
	/* Same constrained-layout reset as .dt-hero__scrim above. */
	max-width: none;
	margin-left: 0;
	margin-right: 0;
}
.dt-hero__dot {
	width: 10px;
	height: 10px;
	border-radius: 50%;
	background: rgba(255, 255, 255, .4);
	border: none;
	padding: 0;
	cursor: pointer;
	transition: background .18s var(--ease-interact), transform .18s var(--ease-interact);
}
.dt-hero__dot:hover { background: rgba(255, 255, 255, .7); }
.dt-hero__dot.is-active { background: var(--dt-blue-vivid); transform: scale(1.25); }

@media (prefers-reduced-motion: reduce) {
	.dt-hero__slide { transition: none; }
}

@media (max-width: 992px) {
	/* Below this width the copy column takes up relatively more of the
	   frame (the container itself is narrower, but the text measure isn't),
	   so the scrim needs to stay opaque for longer before fading, or the
	   later lines of the paragraph end up sitting on unobscured, brighter
	   photo with weak contrast. */
	.dt-hero { min-height: 480px; }
	.dt-hero__slide { object-position: 55% 42%; }
	.dt-hero__logo { height: 130px; }
}
@media (max-width: 781px) {
	.dt-hero {
		min-height: 0;
		padding: 48px 0 40px;
	}
	.dt-hero__slide { object-position: 70% 50%; }
	.dt-hero__inner { max-width: none; }
	.dt-hero__inner p { max-width: none; }
	.dt-hero__stats { gap: 20px 26px; }
	/* The header above already carries the DeviceTech logo — repeating it a
	   second time as a small corner badge just clutters the hero on a
	   phone screen, where every pixel of the headline matters more. Rather
	   than shrink it further, drop it entirely below this width. */
	.dt-hero__logo { display: none; }
	.dt-hero__dots { bottom: 14px; }
}

/* ==========================================================================
   7. Section heading helper
   ========================================================================== */
/* margin-left/right: 0 keeps this left-aligned by default — without it, the
   same auto-centering that WordPress's core layout rule applies to any flow
   child narrower than its column (see the .dt-hero p comment above) pulls
   an un-centred section heading like "What we do" into the middle instead
   of leaving it flush with the content below it. */
.dt-section-heading { max-width: 640px; margin-bottom: 44px; margin-left: 0; margin-right: 0; }
.dt-section-heading--center { margin-left: auto; margin-right: auto; text-align: center; }

/* ==========================================================================
   8. Service grid (class: dt-service-grid on a Columns/Group block wrapper)
   ========================================================================== */
.dt-services { padding: 88px 0; }

/* Trusted-by client strip. The logo files shipped here
   (assets/images/logos/land-rover.png, specsavers.png, john-deere.png) are
   the real brand marks. Trademark permission for these must still be
   confirmed before the site goes live with this section shown publicly. */
.dt-trusted-by { padding: 40px 0; border-top: 1px solid var(--dt-line); border-bottom: 1px solid var(--dt-line); background: var(--dt-bg-alt); }
.dt-trusted-by__label { text-align: center; font-family: var(--dt-font-label); font-size: .8rem; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--dt-muted); margin: 0 0 20px; }
.dt-trusted-by__logos { display: flex; align-items: center; justify-content: center; gap: 56px; flex-wrap: wrap; }
.dt-trusted-by__logos img { height: 40px; width: auto; opacity: .8; transition: opacity .2s var(--ease-interact); }
.dt-trusted-by__logos img:hover { opacity: 1; }
.dt-service-grid {
	display: grid !important;
	/* min(280px, 100%) instead of a bare 280px: on a narrow phone (320px
	   viewport minus the 24px+24px container padding = 272px available)
	   a hard 280px floor would force the track wider than the viewport and
	   cause horizontal scrolling. This lets the column shrink to 100% of
	   the available width instead of overflowing it. */
	grid-template-columns: repeat(auto-fit, minmax(min(280px, 100%), 1fr));
	gap: 24px;
}
.dt-card {
	display: block;
	background: #fff;
	border: 1px solid var(--dt-line);
	border-radius: var(--dt-radius);
	padding: 30px;
	transition: transform .2s var(--ease-interact), box-shadow .2s var(--ease-interact), border-color .2s var(--ease-interact);
	position: relative;
}
.dt-card:hover { transform: translateY(-4px); box-shadow: var(--dt-shadow); border-color: transparent; }
.dt-card h3 { margin-bottom: 10px; }
.dt-card p { font-size: .95rem; margin-bottom: 14px; }
.dt-card p:last-child, .dt-process-step p:last-child { margin-bottom: 0; }
/* .dt-card__link is a nested <a> on the homepage (the card itself is a
   plain div) but a plain <span> on service pages, where .dt-card is
   already the whole clickable <a> — style both the same way regardless
   of which tag it lands on. */
.dt-card .dt-card__link { position: relative; z-index: 1; font-weight: 700; color: var(--dt-blue); font-size: .9rem; display: inline-flex; align-items: center; gap: 6px; min-height: 44px; }
/* Whole card is clickable (not just the link text) — a larger, easier
   tap/click target without needing JS or a custom link block. Only
   applies where .dt-card__link is itself a nested <a> (homepage); where
   .dt-card is already the whole <a> (service pages) this selector simply
   never matches, which is correct — nothing to stretch further. */
.dt-card a.dt-card__link::after { content: ""; position: absolute; inset: 0; z-index: 0; }
.dt-card:focus-within { box-shadow: var(--dt-shadow); border-color: transparent; }
.dt-card__accent {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 8px; height: 28px;
	border-radius: 4px;
	margin-bottom: 18px;
	background: linear-gradient(180deg, var(--dt-blue), var(--dt-blue-vivid));
}
/* Service icon badge — one mark per card, not a decoration on every line
   of copy (see design rule: don't overuse icons). A uniform square badge
   rather than a bare masked icon at natural size: the five source icons
   (camera, satellite dish, TV, lightbulb, PC tower) have quite different
   proportions, and without a fixed badge a narrow icon like the lightbulb
   would read visibly smaller than a wide one like the TV even at the same
   bounding box. See "icon-in-mask pattern" for the technique. */
.dt-card__icon {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 44px; height: 44px;
	border-radius: var(--dt-radius-sm);
	margin-bottom: 18px;
	background: var(--dt-blue-tint-10);
}
.dt-card__icon::before {
	content: "";
	display: block;
	width: 22px; height: 22px;
	background: linear-gradient(180deg, var(--dt-blue), var(--dt-blue-vivid));
	-webkit-mask-size: contain;
	mask-size: contain;
	-webkit-mask-repeat: no-repeat;
	mask-repeat: no-repeat;
	-webkit-mask-position: center;
	mask-position: center;
}
.dt-card__icon--camera::before { -webkit-mask-image: url('assets/icons/camera.svg'); mask-image: url('assets/icons/camera.svg'); }
.dt-card__icon--satellite::before { -webkit-mask-image: url('assets/icons/satellite-dish.svg'); mask-image: url('assets/icons/satellite-dish.svg'); }
.dt-card__icon--tv::before { -webkit-mask-image: url('assets/icons/tv.svg'); mask-image: url('assets/icons/tv.svg'); }
.dt-card__icon--lightbulb::before { -webkit-mask-image: url('assets/icons/lightbulb.svg'); mask-image: url('assets/icons/lightbulb.svg'); }
.dt-card__icon--computer::before { -webkit-mask-image: url('assets/icons/computer.svg'); mask-image: url('assets/icons/computer.svg'); }

/* ==========================================================================
   8b. Coverage / fleet (class: dt-coverage) — the van photo on a brand-blue
       panel. Sits between the trusted-by strip and "why us" so the
       real-work photography (hero, here, why-us) isn't all doing the same
       job: hero leads with a wide install shot, this makes the service
       area concrete with the van, why-us backs up the years-trading claim
       with its own photo.
   ========================================================================== */
.dt-coverage { padding: 88px 0; }
.dt-coverage__grid {
	display: grid;
	grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr);
	column-gap: 56px;
	align-items: center;
}
.dt-coverage__copy { max-width: 46ch; }
.dt-coverage__copy h2 { margin-bottom: .45em; }
.dt-coverage__copy p { font-size: 1.1rem; margin-bottom: 28px; }
.dt-coverage__actions { display: flex; align-items: center; flex-wrap: wrap; gap: 30px; }
/* The phone number is a real alternative action, not a second button of
   equal weight next to "Get a Free Quote" — a plain text link keeps the
   visual hierarchy honest (see design rule 9: don't make every button
   equally dominant). */
.dt-coverage__phone { display: flex; flex-direction: column; line-height: 1.25; }
.dt-coverage__phone-label { font-family: var(--dt-font-label); font-size: .78rem; font-weight: 600; text-transform: uppercase; letter-spacing: .04em; color: var(--dt-muted); }
.dt-coverage__phone-number { font-size: 1.05rem; font-weight: 700; color: var(--dt-black); }
.dt-coverage__phone:hover .dt-coverage__phone-number,
.dt-coverage__phone:focus-visible .dt-coverage__phone-number { color: var(--dt-blue); }

.dt-coverage__panel {
	position: relative;
	background: linear-gradient(150deg, var(--dt-blue) 0%, var(--dt-blue-bright) 100%);
	border-radius: var(--dt-radius);
	padding: 36px;
}
.dt-coverage__van {
	display: block;
	width: 100%;
	height: auto;
	filter: drop-shadow(0 22px 30px rgba(4, 20, 40, .35));
}

@media (max-width: 992px) {
	.dt-coverage__grid { grid-template-columns: 1fr; row-gap: 32px; }
	.dt-coverage__copy { max-width: 60ch; }
	.dt-coverage__panel { max-width: 460px; margin: 0 auto; }
}
@media (max-width: 781px) {
	/* Stacked and centred on a phone — capped smaller so the van doesn't
	   dominate the screen. */
	.dt-coverage { padding: 56px 0; }
	.dt-coverage__panel { max-width: 340px; padding: 26px; }
}

/* ==========================================================================
   9. Editorial checklist (class: dt-checklist on a List block)
   ========================================================================== */
.dt-why-us { padding: 88px 0; background: var(--dt-bg-alt); position: relative; overflow: hidden; }
.dt-why-us__inner.wp-block-columns { align-items: center; gap: 48px; }
.dt-why-us__inner img { border-radius: var(--dt-radius); box-shadow: var(--dt-shadow); }

/* Stat panel — a real DeviceTech installation photo (a branded CCTV camera
   actually fitted at a customer's property) with the "20+ years" stat laid
   over a bottom scrim. Replaces the earlier illustrated version once real
   photography was available — a genuine photo plus a genuine stat pulled
   from the brief, rather than an invented graphic standing in for one. */
.dt-stat-panel {
	position: relative;
	overflow: hidden;
	border-radius: var(--dt-radius);
	box-shadow: var(--dt-shadow);
	min-height: 340px;
}
.dt-stat-panel__photo {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
	margin: 0;
}
.dt-stat-panel__overlay {
	position: relative;
	z-index: 1;
	min-height: 340px;
	display: flex;
	flex-direction: column;
	justify-content: flex-end;
	padding: 32px;
	background: linear-gradient(180deg, rgba(3, 10, 20, 0) 32%, rgba(3, 10, 20, .58) 68%, rgba(3, 10, 20, .88) 100%);
}
.dt-stat-panel__num {
	font-family: var(--dt-font-display);
	font-weight: 400;
	font-size: clamp(2.6rem, 5vw, 3.6rem);
	line-height: 1;
	color: #fff;
	margin: 0 0 6px;
}
.dt-stat-panel__label {
	font-weight: 700;
	font-size: 1.1rem;
	color: #fff;
	max-width: 22ch;
	margin: 0 0 10px;
}
.dt-stat-panel__sub {
	font-family: var(--dt-font-label);
	font-size: .85rem;
	font-weight: 600;
	color: rgba(255, 255, 255, .8);
	margin: 0;
}
/* Price anchor callout — a quick "from £X" figure dropped into a service
   page's body content via a wp:html block. */
.dt-price-anchor { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 20px; background: var(--dt-bg-alt); border: 1px solid var(--dt-line); border-radius: var(--dt-radius); padding: 20px 24px; margin: 24px 0; }
.dt-price-anchor__price { font-family: var(--dt-font-display); font-weight: 400; font-size: 1.3rem; color: var(--dt-blue); }
.dt-price-anchor__note { font-family: var(--dt-font-label); font-size: .85rem; font-weight: 600; color: var(--dt-ink-soft); }

/* Domestic/commercial (or any two-way) split cards inside body content. */
.dt-split-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(280px, 100%), 1fr)); gap: 24px; margin: 24px 0 32px; }
.dt-split-card { background: #fff; border: 1px solid var(--dt-line); border-radius: var(--dt-radius); padding: 28px; box-shadow: var(--dt-shadow-sm); }
.dt-split-card__accent { display: inline-flex; width: 8px; height: 28px; border-radius: 4px; margin-bottom: 14px; background: linear-gradient(180deg, var(--dt-blue), var(--dt-blue-vivid)); }
.dt-split-card h3 { margin-bottom: 8px; }
.dt-split-card p { font-size: .95rem; margin-bottom: 0; }

.dt-checklist { list-style: none !important; padding-left: 0 !important; margin: 24px 0 32px !important; display: grid; gap: 14px; }
.dt-checklist li {
	position: relative;
	padding-left: 30px !important;
	color: var(--dt-ink-soft);
}
.dt-checklist li::before {
	content: "";
	position: absolute; left: 0; top: 4px;
	width: 18px; height: 18px;
	background: var(--dt-blue);
	-webkit-mask: url("assets/icons/check.svg") center / contain no-repeat;
	mask: url("assets/icons/check.svg") center / contain no-repeat;
}

/* ==========================================================================
   10. Process (genuine sequence — numbering allowed; class: dt-process-grid)
   ========================================================================== */
.dt-process { padding: 88px 0; }
.dt-process-grid { display: grid !important; grid-template-columns: repeat(auto-fit, minmax(min(240px, 100%), 1fr)); gap: 32px; }
.dt-process-step { text-align: center; padding: 0 12px; }
.dt-process-step__num {
	display: inline-flex; align-items: center; justify-content: center;
	width: 48px; height: 48px;
	border-radius: 50%;
	background: var(--dt-black);
	color: #fff;
	font-family: var(--dt-font-display);
	font-weight: 400;
	margin-bottom: 18px;
}

/* ==========================================================================
   11. Testimonials (rendered by the [devicetech_testimonials] shortcode)
   ========================================================================== */
.dt-testimonials { padding: 88px 0; background: var(--dt-bg-alt); }
.dt-testimonial-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(280px, 100%), 1fr)); gap: 24px; }
.dt-testimonial-card { background: #fff; border-radius: var(--dt-radius); padding: 28px; box-shadow: var(--dt-shadow-sm); }
.dt-testimonial-card__quote-mark { width: 26px; height: 26px; color: var(--dt-blue-tint); margin-bottom: 12px; }
.dt-testimonial-card p { color: var(--dt-ink); }
.dt-testimonial-card__name { font-weight: 700; color: var(--dt-black); font-size: .9rem; }

/* ==========================================================================
   12. CTA banner (class: dt-cta-banner on a Group block)
   ========================================================================== */
.dt-cta-banner { padding: 76px 0; background: linear-gradient(135deg, var(--dt-charcoal), var(--dt-black)); color: #fff; position: relative; overflow: hidden; }
.dt-cta-banner__inner { text-align: center; max-width: 640px; margin: 0 auto; position: relative; }
.dt-cta-banner h2 { color: #fff; }
.dt-cta-banner p { color: rgba(255,255,255,.75); }
.dt-cta-banner .wp-block-buttons { justify-content: center; margin-top: 24px; gap: 14px; }

/* ==========================================================================
   13. Footer
   ========================================================================== */
.site-footer { background: var(--dt-black); color: rgba(255,255,255,.7); }
.footer-cta { border-bottom: 1px solid rgba(255,255,255,.1); }
.footer-cta__inner { display: flex; align-items: center; justify-content: space-between; gap: 24px; padding: 44px 24px; flex-wrap: wrap; }
.footer-cta h2 { color: #fff; margin-bottom: 6px; }
.footer-cta p { color: rgba(255,255,255,.65); margin: 0; }
.footer-cta__actions { display: flex; gap: 12px; flex-wrap: wrap; }
.footer-main { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(200px, 100%), 1fr)); gap: 40px; padding: 60px 24px; }
.footer-col p { color: rgba(255,255,255,.6); font-size: .92rem; }
.footer-widget__title { color: #fff; font-size: .92rem; font-family: var(--dt-font-label); font-weight: 700; text-transform: uppercase; letter-spacing: .05em; margin-bottom: 18px; }
.footer-col ul { display: grid; gap: 10px; }
.footer-col a { color: rgba(255,255,255,.7); font-size: .92rem; display: inline-flex; align-items: center; min-height: 32px; }
.footer-col a:hover { color: #fff; }
.footer-contact li { display: flex; align-items: flex-start; gap: 8px; color: rgba(255,255,255,.7); font-size: .92rem; }
.footer-contact .dt-icon { margin-top: 4px; flex-shrink: 0; color: var(--dt-blue-tint); }
.footer-social { display: flex; gap: 10px; margin-top: 18px; }
.footer-social a { width: 36px; height: 36px; border-radius: 50%; background: rgba(255,255,255,.08); justify-content: center; }
.footer-social a:hover { background: rgba(255,255,255,.16); }
.footer-bottom { border-top: 1px solid rgba(255,255,255,.1); padding: 20px 0; }
.footer-bottom__inner { display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 12px; font-size: .82rem; }
.footer-bottom p { margin: 0; color: rgba(255,255,255,.5); }
.footer-menu { display: flex; gap: 18px; }
.footer-menu a { color: rgba(255,255,255,.6); font-size: .82rem; min-height: auto; }

/* ==========================================================================
   14. Inner pages
   ========================================================================== */
.page-hero {
	position: relative;
	padding: 60px 0;
	background: linear-gradient(135deg, var(--dt-charcoal), var(--dt-black));
	color: #fff;
	background-size: cover;
	background-position: center;
	overflow: hidden;
}
.page-hero h1 { color: #fff; margin-bottom: 8px; position: relative; }
.page-hero .eyebrow { color: var(--dt-blue-tint); position: relative; }
.page-hero .eyebrow::before { background: var(--dt-blue-tint); }
.page-hero__subtitle { color: rgba(255,255,255,.75); font-size: 1.1rem; max-width: 60ch; position: relative; }
.page-hero .wp-block-buttons { margin-top: 24px; position: relative; }

/* A plain text page (Starlink, Home Entertainment, Smart Home Automation —
   just a paragraph, a heading, a checklist) reads best as a narrow,
   centred prose column. A page that also carries a wide component (a real
   install photo, the two-up split-grid cards, the price-anchor banner,
   the price calculator on CCTV & Alarms / Custom PC Builds; the two-column
   contact-details-plus-form layout on Contact) needs the full site width
   instead, or that component ends up squeezed into the same ~820px column
   and looks cramped next to the homepage's full-width sections. :has()
   picks between the two automatically per page, from whatever the page
   actually contains, rather than needing a template-level flag. */
.page-content { padding: 68px 24px; max-width: 820px; margin: 0 auto; }
.page-content:has(> img, .dt-split-grid, .dt-price-anchor, .dtcalc, .dt-contact-layout) {
	max-width: var(--dt-container);
}
.page-content:has(> img, .dt-split-grid, .dt-price-anchor, .dtcalc, .dt-contact-layout) > p,
.page-content:has(> img, .dt-split-grid, .dt-price-anchor, .dtcalc, .dt-contact-layout) > ul.wp-block-list {
	max-width: 68ch;
}
.page-content h2 { margin-top: 1.4em; }
.page-content img { border-radius: var(--dt-radius); margin: 24px 0; box-shadow: var(--dt-shadow-sm); }

.dt-related-services { padding: 0 0 88px; }

/* ==========================================================================
   15. Contact page (rendered by [devicetech_contact_form])
   ========================================================================== */
.dt-contact-layout { display: grid; grid-template-columns: minmax(0,.72fr) minmax(0,1.28fr); gap: 56px; padding: 24px 0 24px; }
.dt-contact-details { display: grid; gap: 0; margin: 8px 0 0; border-top: 1px solid var(--dt-line); }
.dt-contact-details li { display: grid; gap: 6px; padding: 22px 0; border-bottom: 1px solid var(--dt-line); }
.dt-contact-details li > span:first-child { display: inline-flex; align-items: center; gap: 8px; color: var(--dt-ink-soft); font-size: .8rem; text-transform: uppercase; letter-spacing: .06em; font-weight: 700; }
.dt-contact-details .dt-icon { color: var(--dt-blue); width: 15px; height: 15px; }
.dt-contact-details li > a,
.dt-contact-details li > span:last-child:not(:first-child) { font-family: var(--dt-font-display); font-weight: 400; font-size: 1.3rem; color: var(--dt-black); }
.dt-contact-details li > a:hover { color: var(--dt-blue); }

/* The actual form fields are rendered by LPD Arsenal's [lpd_form] shortcode
   (its own plugin CSS styles them) — this wrapper just gives it the same
   card treatment as the rest of the contact page. .dt-form-notice is only
   ever shown to a logged-in admin, if the form hasn't been configured yet. */
.dt-contact-form-wrap { background: var(--dt-bg-alt); border-radius: var(--dt-radius); padding: 32px; }
.dt-form-notice { padding: 14px 18px; border-radius: var(--dt-radius-sm); margin-bottom: 20px; font-weight: 600; font-size: .92rem; }
.dt-form-notice--success { background: #e4f5ec; color: var(--dt-success); }
.dt-form-notice--error { background: #fbe7e5; color: var(--dt-danger); }

/* ==========================================================================
   16. Blog
   ========================================================================== */
.blog-layout { display: grid; grid-template-columns: minmax(0,2.2fr) minmax(0,1fr); gap: 48px; padding: 68px 0 88px; }
.blog-grid { display: grid; gap: 32px; }
.blog-card { display: grid; grid-template-columns: 220px minmax(0,1fr); gap: 24px; border-bottom: 1px solid var(--dt-line); padding-bottom: 32px; }
.blog-card__thumb { border-radius: var(--dt-radius-sm); overflow: hidden; background: var(--dt-bg-alt); aspect-ratio: 4/3; }
.blog-card__thumb-placeholder { display: block; width: 100%; height: 100%; background: linear-gradient(135deg, var(--dt-blue), var(--dt-blue-tint)); }
.blog-card__date { font-family: var(--dt-font-label); font-size: .76rem; color: var(--dt-muted); text-transform: uppercase; letter-spacing: .05em; font-weight: 700; }
.blog-card__title { margin: 8px 0 10px; font-family: var(--dt-font-body); font-weight: 700; font-size: 1.25rem; }
.blog-card__title a { color: var(--dt-black); }
.single-post__thumb { border-radius: var(--dt-radius); overflow: hidden; margin-bottom: 32px; }
.pagination { margin-top: 40px; display: flex; gap: 12px; }
.pagination .page-numbers { min-width: 44px; min-height: 44px; display: inline-flex; align-items: center; justify-content: center; padding: 8px 14px; border: 1px solid var(--dt-line); border-radius: var(--dt-radius-sm); font-weight: 600; }
.pagination .current { background: var(--dt-black); color: #fff; border-color: var(--dt-black); }

/* ==========================================================================
   17. 404 / search
   ========================================================================== */
.not-found { padding: 110px 0; text-align: center; }
.not-found .container { max-width: 560px; }
.not-found .search-form { margin: 28px auto; display: flex; gap: 10px; max-width: 420px; }
.search-form .search-field { flex: 1; min-height: 48px; padding: 12px 16px; border-radius: 999px; border: 1px solid var(--dt-line); }
.search-form .search-submit { border-radius: 999px; }

/* ==========================================================================
   18. Comments
   ========================================================================== */
.comments-area { margin-top: 48px; padding-top: 32px; border-top: 1px solid var(--dt-line); }
.comment-list { display: grid; gap: 24px; }

/* ==========================================================================
   19. Scroll reveal — staggered for card ROWS only, instant for tall
       single-column content. Respects prefers-reduced-motion.
   ========================================================================== */
.dt-reveal-group > * {
	opacity: 0;
	transform: translateY(18px);
	transition: opacity .6s var(--ease-enter), transform .6s var(--ease-enter);
}
.dt-reveal-group.is-visible > * { opacity: 1; transform: translateY(0); }
.dt-reveal-group.is-visible > *:nth-child(1) { transition-delay: 0ms; }
.dt-reveal-group.is-visible > *:nth-child(2) { transition-delay: 80ms; }
.dt-reveal-group.is-visible > *:nth-child(3) { transition-delay: 160ms; }
.dt-reveal-group.is-visible > *:nth-child(4) { transition-delay: 240ms; }
.dt-reveal-group.is-visible > *:nth-child(5) { transition-delay: 320ms; }
.dt-reveal-group.is-visible > *:nth-child(6) { transition-delay: 400ms; }

.dt-reveal {
	opacity: 0;
	transform: translateY(14px);
	transition: opacity .5s var(--ease-enter), transform .5s var(--ease-enter);
}
.dt-reveal.is-visible { opacity: 1; transform: translateY(0); }

@media (prefers-reduced-motion: reduce) {
	.dt-reveal-group > *,
	.dt-reveal { opacity: 1 !important; transform: none !important; transition: none !important; }
}

/* ==========================================================================
   20. Icons (inline SVG masks for a few chrome elements)
   ========================================================================== */
.top-bar .dt-icon { width: 13px; height: 13px; }

/* ==========================================================================
   21. Responsive
   ========================================================================== */
@media (max-width: 960px) {
	.dt-contact-layout, .blog-layout { grid-template-columns: 1fr; }
}
/* Core Columns blocks (hero, why-us) already stack responsively on their own. */

/* The desktop header (logo + 6-item nav + CTA button, all in one row) needs
   roughly 1360px to fit without crowding even after tightening the nav's
   own spacing — narrower than that, the nav wraps onto a second line and
   the whole header looks broken. Rather than fight for space down to some
   arbitrary "tablet" width, the hamburger menu now takes over at the width
   the content actually stops fitting. */
@media (max-width: 1360px) {
	.dt-hero { padding: 44px 0 52px; }
	.dt-services, .dt-why-us, .dt-process, .dt-testimonials { padding: 56px 0; }
	.dt-cta-banner { padding: 52px 0; }
	.page-hero { padding: 44px 0; }
	.page-content { padding: 44px 24px; }
	.dt-section-heading { margin-bottom: 32px; }
	.dt-why-us__inner.wp-block-columns { gap: 28px; }
	.top-bar__inner { flex-direction: column; gap: 6px; padding: 10px 24px; text-align: center; }
	.main-navigation {
		position: fixed;
		top: 0; right: 0;
		width: min(320px, 84vw);
		height: 100vh;
		background: #fff;
		box-shadow: -20px 0 40px rgba(11,20,38,.15);
		padding: 90px 28px 28px;
		transform: translateX(100%);
		transition: transform .3s var(--ease-interact);
		overflow-y: auto;
		/* Override the desktop row layout (flex:1; justify-content:center) —
		   without flex-direction:column here, the close button, menu list and
		   footer stack as flex ROW children instead of a vertical drawer. */
		flex: none;
		flex-direction: column;
		align-items: stretch;
		justify-content: flex-start;
		z-index: 1000;
	}
	.main-navigation.is-open { transform: translateX(0); }
	/* Lock the page behind the open drawer so scrolling the menu doesn't
	   also scroll the page underneath it. */
	body.nav-open { overflow: hidden; }
	.nav-backdrop {
		position: fixed;
		inset: 0;
		background: rgba(11, 20, 38, .45);
		z-index: 999;
	}
	.nav-backdrop[hidden] { display: none; }
	/* A dedicated, always-visible close control inside the drawer itself —
	   the header's own hamburger button sits underneath the open drawer
	   (it shares the header's stacking context, and the drawer/backdrop
	   render above it), so it isn't a reliable way to close the menu once
	   open. Escape and tapping the dimmed backdrop still work too, but a
	   real X a thumb can find is the one that matters on a phone. */
	.nav-close {
		position: absolute;
		top: 20px;
		right: 20px;
		width: 44px;
		height: 44px;
		display: flex;
		align-items: center;
		justify-content: center;
		background: var(--dt-bg-alt);
		border: none;
		border-radius: 50%;
		cursor: pointer;
		color: var(--dt-black);
	}
	.nav-close svg { width: 16px; height: 16px; }
	.nav-close:hover { background: var(--dt-line); }
	.primary-menu { flex-direction: column; align-items: stretch; gap: 4px; }
	.primary-menu .sub-menu { position: static; box-shadow: none; opacity: 1; visibility: visible; transform: none; display: none; border: none; padding-left: 12px; }
	.primary-menu .menu-item.is-open .sub-menu { display: block; }
	.submenu-toggle { display: flex; align-items: center; justify-content: center; position: absolute; right: 0; top: 0; width: 44px; height: 44px; background: none; border: none; }
	.site-header__cta { display: none; }
	.menu-toggle { display: flex; }
	/* The header's own "Get a Free Quote" button is hidden on mobile (the
	   rule right above), so without this the primary call-to-action
	   disappears from the header entirely below 1100px — repeated here so
	   the one screen a mobile visitor is most likely to be deliberately
	   looking at (the open menu) still offers a fast way to convert. */
	.main-navigation__footer {
		margin-top: 24px;
		padding-top: 24px;
		border-top: 1px solid var(--dt-line);
		display: flex;
		flex-direction: column;
		gap: 16px;
	}
	.main-navigation__footer .btn { width: 100%; }
	.main-navigation__phone {
		display: flex;
		align-items: center;
		justify-content: center;
		gap: 8px;
		min-height: 44px;
		font-weight: 700;
		color: var(--dt-black);
	}
	.footer-main { grid-template-columns: 1fr; padding: 44px 24px; }
	.footer-cta__inner { flex-direction: column; text-align: center; }
	/* The LPD cookie-settings widget floats fixed at bottom-left (20px, 46px
	   square) on every page. On desktop the copyright row is wide enough
	   that it never reaches that corner, but on mobile it wraps to sit right
	   under it. Stack the row and clear the widget with left padding so the
	   text is never hidden behind it. */
	.footer-bottom__inner { flex-direction: column; align-items: flex-start; gap: 8px; }
	.footer-bottom p { padding-left: 62px; }
	.blog-card { grid-template-columns: 1fr; }
	.dt-contact-layout { padding: 8px 0 8px; }
	.dt-contact-details li > a,
	.dt-contact-details li > span:last-child:not(:first-child) { font-size: 1.15rem; }
}

@media (max-width: 420px) {
	.footer-cta__actions .btn,
	.dt-cta-banner .wp-block-buttons .wp-block-button { width: 100%; }
	.footer-cta__actions .btn,
	.dt-cta-banner .wp-block-button__link { width: 100%; }
	.footer-cta__actions { flex-direction: column; align-items: stretch; }
	.dt-hero__actions { flex-direction: column; align-items: flex-start; gap: 16px; }
	.dt-hero__actions .btn { width: 100%; justify-content: center; }
}
