/* Self-hosted font faces. Generated by tools/fetch-fonts.mjs - do not hand-edit.
 * Same families and weights as the previous Google Fonts <link>; only the
 * delivery origin changed. Latin subset only (the site is English-only).
 */
@font-face {
  font-family: "Archivo";
  font-style: normal;
  font-weight: 600 700;
  font-display: swap;
  src: url("/assets/fonts/archivo.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url("/assets/fonts/inter.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* ==========================================================================
   Kelly Heating & Electric - design system
   Tokens, base, components. Root-relative asset paths. Decorative gradients and
   glassmorphism are avoided; image-backed heroes may use a functional dark
   gradient when it is required to preserve readable text over photography.
   ========================================================================== */

/* ---- Design tokens ------------------------------------------------------- */
:root {
  /* Brand */
  --kelly-navy: #1B3A63;
  --kelly-navy-deep: #142c4b;
  --kelly-blue: #2E5C99;
  --kelly-cream: #FAF5EE;
  --charcoal: #23272E;
  --bryant-red: #D0102A;
  --bryant-red-dark: #b00c22;
  /* Call-to-action red. Deliberately deeper and less saturated than
     --bryant-red, which stays as-is on the 24/7 emergency strip where the
     shout is the point. On a button the brighter red read as too intense
     (owner's call). Measures 6.52:1 against white text, comfortably past the
     4.5:1 minimum. */
  --cta-red: #AA3140;
  --cta-red-dark: #8F2837;
  --gold: #C9A24B;
  /* Gold on a translucent-white-over-navy surface (the .cta-phone tiles).
     --gold there measures 3.77:1, under the 4.5:1 needed for normal-size text.
     This lighter step measures 4.99:1 on the same composite background and is
     the same hue, so nothing about the look changes. Do not swap --gold itself:
     on solid navy it already passes, and lightening it everywhere would wash
     out the kickers. */
  --gold-on-navy: #E0BC6A;
  --white: #ffffff;

  /* Neutrals */
  --ink: var(--charcoal);
  --ink-soft: #4a515c;
  --line: #e6e2db;
  --line-strong: #d4cec4;
  --bg: #ffffff;
  --bg-cream: var(--kelly-cream);

  /* Type */
  --font-display: "Archivo", "Helvetica Neue", Arial, sans-serif;
  --font-body: "Inter", system-ui, -apple-system, Segoe UI, Roboto, sans-serif;

  /* Spacing scale (8px base) */
  --sp-1: 0.5rem;   /* 8  */
  --sp-2: 1rem;     /* 16 */
  --sp-3: 1.5rem;   /* 24 */
  --sp-4: 2.5rem;   /* 40 */
  --sp-5: 4rem;     /* 64 */
  --sp-6: 6rem;     /* 96 */
  --section-pad: clamp(3.5rem, 2rem + 6vw, 6rem); /* 56 -> 96 */

  /* Structure */
  --container: 1200px;
  --radius: 12px;
  --radius-sm: 8px;
  --radius-pill: 999px;

  /* Shadows (two levels, same light direction) */
  --shadow-1: 0 4px 16px rgba(27, 58, 99, 0.08);
  --shadow-2: 0 14px 34px rgba(27, 58, 99, 0.14);

  --header-h: 76px;
}

/* ---- Reset / base -------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }

body {
  margin: 0;
  font-family: var(--font-body);
  font-size: clamp(1rem, 0.95rem + 0.3vw, 1.125rem);
  line-height: 1.65;
  color: var(--ink);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

h1, h2, h3, h4 {
  font-family: var(--font-display);
  font-weight: 700;
  line-height: 1.12;
  color: var(--kelly-navy);
  margin: 0 0 0.5em;
  letter-spacing: -0.01em;
}
h1 { font-size: clamp(2.2rem, 5vw + 0.5rem, 3.6rem); }
h2 { font-size: clamp(1.7rem, 3vw + 0.5rem, 2.5rem); }
h3 { font-size: clamp(1.25rem, 1.4vw + 0.7rem, 1.6rem); }
h4 { font-size: 1.15rem; }

p { margin: 0 0 1rem; }
p:last-child { margin-bottom: 0; }

a { color: var(--kelly-blue); text-decoration: none; }
a:hover { color: var(--kelly-navy); }

img { max-width: 100%; height: auto; display: block; }

ul, ol { margin: 0 0 1rem; padding-left: 1.2rem; }

strong { font-weight: 700; }

:focus-visible {
  outline: 3px solid var(--kelly-blue);
  outline-offset: 2px;
  border-radius: 4px;
}

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 200;
  background: var(--kelly-navy);
  color: #fff;
  padding: 0.75rem 1.25rem;
  border-radius: 0 0 var(--radius-sm) 0;
}
.skip-link:focus { left: 0; color: #fff; }

/* ---- Layout helpers ------------------------------------------------------ */
.container {
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: clamp(1.1rem, 4vw, 2rem);
}

.section { padding-block: var(--section-pad); }
.section-cream { background: var(--bg-cream); }
.section-navy { background: var(--kelly-navy); color: #eaf0f8; }
.section-navy h1, .section-navy h2, .section-navy h3 { color: #fff; }

.section-head { max-width: 62ch; margin-bottom: var(--sp-4); }
.section-head.center { margin-inline: auto; text-align: center; }

.kicker {
  font-family: var(--font-body);
  text-transform: uppercase;
  letter-spacing: 0.14em;
  font-size: 0.8rem;
  font-weight: 700;
  color: var(--kelly-blue);
  margin: 0 0 0.6rem;
}
.section-navy .kicker { color: var(--gold); }

.lead { font-size: 1.15rem; color: var(--ink-soft); }

/* ---- Buttons ------------------------------------------------------------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.55rem;
  font-family: var(--font-body);
  font-weight: 700;
  font-size: 1rem;
  line-height: 1;
  padding: 0.95rem 1.6rem;
  border-radius: var(--radius-sm);
  border: 2px solid transparent;
  cursor: pointer;
  text-align: center;
  transition: transform .18s ease, box-shadow .18s ease, background-color .18s ease, color .18s ease, border-color .18s ease;
}
.btn:hover { transform: translateY(-2px); box-shadow: var(--shadow-2); }
.btn:active { transform: translateY(0); box-shadow: var(--shadow-1); }

.btn-primary { background: var(--kelly-navy); color: #fff; }
.btn-primary:hover { background: var(--kelly-navy-deep); color: #fff; }

.btn-emergency { background: var(--cta-red); color: #fff; }
.btn-emergency:hover { background: var(--cta-red-dark); color: #fff; }

.btn-outline {
  background: transparent;
  color: var(--kelly-navy);
  border-color: var(--kelly-navy);
}
.btn-outline:hover { background: var(--kelly-navy); color: #fff; }

.btn-light { background: #fff; color: var(--kelly-navy); }
.btn-light:hover { background: var(--kelly-cream); color: var(--kelly-navy); }

.btn-outline-light {
  background: transparent;
  color: #fff;
  border-color: rgba(255,255,255,0.7);
}
.btn-outline-light:hover { background: #fff; color: var(--kelly-navy); border-color: #fff; }

/* ---- Top utility bar ----------------------------------------------------- */
/* Slim navy bar above the white header. Static: it scrolls away and the white
   .site-header below stays sticky at top:0. Never fixed/sticky. */
.top-bar {
  background: var(--kelly-navy);
  color: #fff;
  font-family: var(--font-body);
  font-size: 0.82rem;
}
.top-bar-inner {
  display: flex;
  flex-wrap: nowrap;
  align-items: stretch;
  justify-content: space-between;
  gap: 1rem;
  min-height: 42px;
}
.top-bar-left { display: flex; align-items: stretch; gap: 0.2rem; }
.top-bar-right { display: flex; align-items: center; gap: 1rem; }

.top-bar-emergency {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  background: var(--bryant-red);
  color: #fff;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  white-space: nowrap;
  padding-inline: 1rem;
  /* Bleed flush to the left edge of the bar, past the container padding. */
  margin-left: calc(-1 * clamp(1.1rem, 4vw, 2rem));
  padding-left: clamp(1.1rem, 4vw, 2rem);
  transition: background-color .18s ease;
}
.top-bar-emergency:hover { background: var(--bryant-red-dark); color: #fff; }
.top-bar-emergency svg { flex: 0 0 auto; }

.top-bar-link {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  color: #fff;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  white-space: nowrap;
  padding-inline: 0.5rem;
}
.top-bar-link:hover { color: var(--gold); }
.top-bar-link svg { flex: 0 0 auto; }

.top-bar-phone {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  color: #fff;
  font-weight: 700;
  white-space: nowrap;
  border: 1.5px solid rgba(255,255,255,0.6);
  border-radius: var(--radius-pill);
  padding: 0.28rem 0.95rem;
  transition: background-color .18s ease, color .18s ease, border-color .18s ease;
}
.top-bar-phone svg { flex: 0 0 auto; }
.top-bar-phone:hover { background: #fff; color: var(--kelly-navy); border-color: #fff; }

/* ---- Header + nav -------------------------------------------------------- */
.site-header {
  position: sticky;
  top: 0;
  z-index: 100;
  background: #fff;
  border-bottom: 1px solid var(--line);
  box-shadow: var(--shadow-1);
}
.header-inner {
  display: flex;
  align-items: center;
  gap: 1rem;
  min-height: var(--header-h);
  padding-block: 0.6rem;
}
.brand { flex: 0 0 auto; margin-right: auto; }
.brand-logo { height: 68px; width: auto; }

.primary-nav { margin-left: auto; }
.nav-list {
  list-style: none;
  display: flex;
  align-items: center;
  gap: 0.2rem;
  margin: 0;
  padding: 0;
}
.nav-item { position: relative; }

.nav-item > a,
.dropdown-toggle {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 0.95rem;
  color: var(--kelly-navy);
  background: none;
  border: 0;
  cursor: pointer;
  padding: 0.6rem 0.7rem;
  border-radius: var(--radius-sm);
  white-space: nowrap;
}
.nav-item > a { position: relative; }
.nav-item > a::after {
  content: "";
  position: absolute;
  left: 0.7rem;
  right: 0.7rem;
  bottom: 0.35rem;
  height: 2px;
  background: var(--kelly-blue);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform .22s ease;
}
.nav-item > a:hover::after,
.nav-item > a[aria-current="page"]::after { transform: scaleX(1); }
.dropdown-toggle:hover { color: var(--kelly-blue); }
.chevron { transition: transform .2s ease; }

.dropdown {
  list-style: none;
  margin: 0;
  padding: 0.5rem;
  position: absolute;
  top: calc(100% + 2px);
  left: 0;
  min-width: 230px;
  background: #fff;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow-2);
  opacity: 0;
  visibility: hidden;
  transform: translateY(6px);
  transition: opacity .18s ease, transform .18s ease, visibility .18s;
  z-index: 120;
}
.dropdown-wide {
  min-width: 460px;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.1rem 0.4rem;
}
.dropdown li { margin: 0; }
.dropdown a {
  display: block;
  padding: 0.55rem 0.7rem;
  border-radius: var(--radius-sm);
  font-size: 0.92rem;
  font-weight: 500;
  color: var(--ink);
}
.dropdown a:hover { background: var(--kelly-cream); color: var(--kelly-navy); }

/* Pointer hover opens a desktop menu. Keyboard users with JavaScript open the
   disclosure explicitly, keeping aria-expanded and visible state synchronized;
   the .no-js focus-within rule preserves a keyboard fallback when scripts are
   unavailable. */
.has-dropdown:hover > .dropdown,
.no-js .has-dropdown:focus-within > .dropdown,
.has-dropdown .dropdown-toggle[aria-expanded="true"] + .dropdown {
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
}
.has-dropdown:hover > .dropdown-toggle .chevron,
.dropdown-toggle[aria-expanded="true"] .chevron { transform: rotate(180deg); }

.nav-toggle {
  display: none;
  flex-direction: column;
  justify-content: center;
  gap: 5px;
  width: 44px;
  height: 44px;
  padding: 0;
  background: none;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-sm);
  cursor: pointer;
}
.nav-toggle-bar {
  display: block;
  width: 22px;
  height: 2px;
  margin-inline: auto;
  background: var(--kelly-navy);
  transition: transform .2s ease, opacity .2s ease;
}
.nav-toggle[aria-expanded="true"] .nav-toggle-bar:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.nav-toggle[aria-expanded="true"] .nav-toggle-bar:nth-child(2) { opacity: 0; }
.nav-toggle[aria-expanded="true"] .nav-toggle-bar:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

/* ---- Hero ---------------------------------------------------------------- */
.hero {
  position: relative;
  min-height: clamp(520px, 74vh, 680px);
  display: flex;
  align-items: center;
  overflow: hidden;
  color: #fff;
}
.hero-media { position: absolute; inset: 0; z-index: 0; }
.hero-video, .hero-fallback { width: 100%; height: 100%; object-fit: cover; }
.hero-video { display: block; background: #1B3A63; }
.hero-fallback {
  display: none;
  animation: kenburns 26s ease-in-out infinite alternate;
  transform-origin: center;
}
@keyframes kenburns {
  from { transform: scale(1); }
  to   { transform: scale(1.08) translate(-1.5%, -1%); }
}
.hero-video-toggle {
  position: absolute;
  right: clamp(1rem, 3vw, 2rem);
  bottom: clamp(1rem, 3vw, 2rem);
  z-index: 2;
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  padding: 0;
  border: 1px solid rgba(255, 255, 255, 0.72);
  border-radius: 50%;
  background: rgba(15, 26, 43, 0.78);
  color: #fff;
  cursor: pointer;
  box-shadow: 0 5px 18px rgba(15, 26, 43, 0.3);
}
.hero-video-toggle[hidden] { display: none; }
.hero-video-toggle:hover { background: rgba(15, 26, 43, 0.94); }
.hero-video-toggle:focus-visible { outline: 3px solid #fff; outline-offset: 3px; }
.hero-video-toggle .icon-play { display: none; }
.hero-video-toggle[aria-pressed="true"] .icon-pause { display: none; }
.hero-video-toggle[aria-pressed="true"] .icon-play { display: block; }
@media (max-width: 700px) {
  .hero-video { display: none; }
  .hero-fallback { display: block; animation: none; }
  .hero-video-toggle { display: none !important; }
}
.hero-overlay {
  position: absolute;
  inset: 0;
  z-index: 1;
  /* Purely decorative: it sits above .hero-media (z-index 0), which is where
     the pause/play button lives, so without this it swallowed every mouse and
     touch event aimed at that button. Keyboard users could still reach the
     control, which is exactly why this went unnoticed. */
  pointer-events: none;
  background:
    linear-gradient(to right, rgba(15,26,43,0.82) 0%, rgba(15,26,43,0.55) 52%, rgba(15,26,43,0.28) 100%),
    linear-gradient(to top, rgba(15,26,43,0.6) 0%, transparent 42%);
}
.hero-content {
  position: relative;
  z-index: 2;
  padding-block: clamp(3rem, 8vh, 5rem);
  max-width: 720px;
}
.hero h1 {
  color: #fff;
  font-size: clamp(2.4rem, 5.2vw + 0.5rem, 4rem);
  margin-bottom: 0.5rem;
}
.hero-sub {
  font-size: clamp(1.1rem, 1.6vw + 0.5rem, 1.4rem);
  color: #e8eef7;
  margin-bottom: 2rem;
  max-width: 44ch;
}
/* Phone-only hero calls to action. See the note in the home page markup for
   why the desktop hero deliberately has none. The mobile sizing lives in the
   768px block further down. */
.hero-actions { display: none; }
/* Google rating badge (hero) */
.google-badge {
  display: inline-flex;
  align-items: center;
  gap: 0.8rem;
  width: min(290px, 100%);
  background: #fff;
  border-top: 3px solid #34A853;
  border-radius: var(--radius-sm);
  padding: 0.8rem 1.05rem;
  box-shadow: 0 10px 26px rgba(15, 26, 43, 0.3);
  color: var(--ink);
  transition: transform .18s ease, box-shadow .18s ease;
}
.google-badge:hover {
  transform: translateY(-3px);
  box-shadow: 0 16px 34px rgba(15, 26, 43, 0.36);
  color: var(--ink);
}
.google-badge-logo { flex: 0 0 auto; }
.google-badge-logo svg { width: 34px; height: 34px; display: block; }
.google-badge-body { display: flex; flex-direction: column; gap: 0.15rem; min-width: 0; }
.google-badge-label { font-size: 0.72rem; font-weight: 600; color: #5f6368; }
.google-badge-score { display: inline-flex; align-items: center; gap: 0.4rem; }
.google-badge-num {
  font-family: var(--font-display);
  font-size: 1.2rem;
  font-weight: 700;
  color: var(--kelly-blue);
  line-height: 1;
}
.google-badge-stars { display: inline-flex; gap: 1px; color: #F29900; }
.google-badge-stars svg { width: 15px; height: 15px; display: block; }
.google-badge-count { font-size: 0.72rem; color: #5f6368; }
/* Same badge on a light section (home reviews): the hero's heavy drop shadow
   reads muddy on white, so soften it and add a hairline instead. */
.section-head .google-badge {
  box-shadow: var(--shadow-1);
  border: 1px solid var(--line);
  margin: 0.75rem auto 0;
}
.section-head .google-badge:hover { box-shadow: var(--shadow-2); }

/* Star rating */
.stars { display: inline-flex; gap: 2px; color: var(--gold); }
.stars svg { width: 18px; height: 18px; display: block; }
.trust-inline {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  flex-wrap: wrap;
  font-weight: 600;
}
.trust-inline .rating-num { font-family: var(--font-display); font-size: 1.25rem; font-weight: 700; }
.hero .trust-inline { color: #fff; }

/* ---- Trust strip --------------------------------------------------------- */
.trust-strip { background: var(--kelly-navy); color: #eaf0f8; }
.trust-strip-inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 1.25rem 2rem;
  padding-block: 1.25rem;
}
.trust-strip-badge { height: 54px; width: auto; background: #fff; border-radius: var(--radius-sm); padding: 6px 10px; }
.trust-strip ul {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem 1.75rem;
  margin: 0;
  padding: 0;
  font-weight: 600;
}
.trust-strip li { display: inline-flex; align-items: center; gap: 0.5rem; }
.trust-strip li svg { color: var(--gold); flex: 0 0 auto; }

/* ---- Cards / grids ------------------------------------------------------- */
.grid { display: grid; gap: clamp(1.1rem, 2vw, 1.75rem); }
.grid-2 { grid-template-columns: repeat(2, 1fr); }
.grid-3 { grid-template-columns: repeat(3, 1fr); }
.grid-4 { grid-template-columns: repeat(4, 1fr); }

.card {
  background: #fff;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow-1);
  overflow: hidden;
  transition: transform .22s ease, box-shadow .22s ease;
}
.card:hover { transform: translateY(-4px); box-shadow: var(--shadow-2); }

.photo-frame { overflow: hidden; }
.photo-frame img { transition: transform .4s ease; }
a:hover .photo-frame img,
.card:hover .photo-frame img { transform: scale(1.04); }

/* Service card (photo on top, link) */
.service-card { display: flex; flex-direction: column; color: var(--ink); }
.service-card .photo-frame { aspect-ratio: 4 / 3; }
.service-card .photo-frame img { width: 100%; height: 100%; object-fit: cover; }
.service-card .photo-frame.contain { background: var(--kelly-cream); border-bottom: 1px solid var(--line); }
.service-card .photo-frame.contain img { object-fit: contain; padding: 1.25rem; }
.service-card-body { padding: 1.15rem 1.25rem 1.35rem; display: flex; flex-direction: column; gap: 0.4rem; }
.service-card h3 { margin: 0; }
.service-card p { color: var(--ink-soft); font-size: 0.98rem; }
.service-card .card-link {
  margin-top: auto;
  font-weight: 700;
  color: var(--kelly-blue);
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
}
.service-card .card-link svg { transition: transform .2s ease; }
.service-card:hover .card-link svg { transform: translateX(3px); }

/* SiteLink review cards are first-party, no-JavaScript product summaries.
   They appear only in the noindex staging build while Tim reviews the models. */
.product-review-grid { list-style: none; margin: 0; padding: 0; align-items: start; }
.product-review-card { padding: 0; overflow: clip; }
.product-review-image {
  display: grid;
  place-items: center;
  min-height: 15rem;
  padding: 1.25rem;
  background: var(--white);
  border-bottom: 1px solid var(--line);
}
.product-review-image picture { display: contents; }
.product-review-image img {
  width: 100%;
  height: 13rem;
  object-fit: contain;
}
.product-review-copy { padding: 1.35rem; }
.product-review-card h3 {
  margin: 0 0 0.55rem;
  font-size: clamp(1.05rem, 1.6vw, 1.2rem);
  line-height: 1.35;
}
.product-review-card .product-model { margin: 0; color: var(--ink-soft); font-weight: 700; }
.product-evidence { margin: 0.45rem 0 0; }
.product-evidence-link {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  color: var(--kelly-blue);
  font-weight: 800;
  text-decoration: underline;
  text-decoration-thickness: 0.1em;
  text-underline-offset: 0.18em;
}
.product-evidence-link:hover { color: var(--bryant-red-dark); }
.manufacturer-details {
  margin-top: 1rem;
  border-top: 1px solid var(--line);
}
.manufacturer-details summary {
  min-height: 44px;
  padding: 0.8rem 0;
  color: var(--kelly-blue);
  font-weight: 800;
  cursor: pointer;
}
.manufacturer-details summary:hover { color: var(--bryant-red-dark); }
.manufacturer-details summary:focus-visible {
  outline: 3px solid var(--kelly-blue);
  outline-offset: 3px;
  border-radius: 2px;
}
.product-review-note {
  margin: 1rem 0 0;
  padding: 0.8rem 0.9rem;
  border-left: 4px solid var(--bryant-red);
  border-radius: var(--radius-sm);
  background: #fdf1f3;
  color: var(--ink);
  font-size: 0.9rem;
  line-height: 1.5;
}
.manufacturer-details-body { padding: 0.1rem 0 0.25rem; overflow-wrap: anywhere; }
.manufacturer-details-body h4 {
  margin: 1rem 0 0.45rem;
  color: var(--kelly-navy);
  font-size: 0.95rem;
  letter-spacing: 0.02em;
}
.manufacturer-details-body ul { margin: 0; padding-left: 1.2rem; }
.manufacturer-details-body li { margin: 0.4rem 0; color: var(--ink-soft); }

/* ---- About teaser -------------------------------------------------------- */
.split {
  display: grid;
  grid-template-columns: 1.05fr 1fr;
  gap: clamp(1.75rem, 4vw, 3.5rem);
  align-items: center;
}
.split-media { border-radius: var(--radius); overflow: hidden; box-shadow: var(--shadow-2); }
.split-media img { width: 100%; height: 100%; object-fit: cover; }
.split-body h2 { margin-bottom: 0.6rem; }

/* ---- Reviews ------------------------------------------------------------- */
.review-card {
  background: #fff;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow-1);
  padding: 1.5rem 1.5rem 1.35rem;
  display: flex;
  flex-direction: column;
  gap: 0.85rem;
  transition: transform .22s ease, box-shadow .22s ease;
}
.review-card:hover { transform: translateY(-4px); box-shadow: var(--shadow-2); }
.review-quote { font-size: 1.02rem; color: var(--ink); margin: 0; }
.review-attr { margin-top: auto; font-weight: 600; color: var(--kelly-navy); }
.review-source { display: block; font-weight: 500; font-size: 0.85rem; color: var(--ink-soft); }

/* ---- Contact CTA band ---------------------------------------------------- */
.cta-band { background: var(--kelly-navy); color: #eaf0f8; padding-block: var(--section-pad); }
.cta-band h2 { color: #fff; }
.cta-band-inner {
  display: grid;
  grid-template-columns: 1.1fr 1fr;
  gap: clamp(1.5rem, 4vw, 3rem);
  align-items: center;
}
.cta-band-copy p { color: #cdd8e8; margin: 0; }
.cta-band-actions { display: flex; flex-direction: column; gap: 1rem; align-items: flex-start; }
.cta-phones { display: flex; flex-wrap: wrap; gap: 0.75rem; }
.cta-phone {
  display: flex;
  flex-direction: column;
  background: rgba(255,255,255,0.08);
  border: 1px solid rgba(255,255,255,0.18);
  border-radius: var(--radius-sm);
  padding: 0.7rem 1.1rem;
  color: #fff;
  transition: background-color .18s ease, transform .18s ease;
}
.cta-phone:hover { background: rgba(255,255,255,0.16); color: #fff; transform: translateY(-2px); }
.cta-phone-city { font-size: 0.75rem; text-transform: uppercase; letter-spacing: 0.08em; color: var(--gold-on-navy); font-weight: 700; }
.cta-phone-num { font-family: var(--font-display); font-size: 1.4rem; font-weight: 700; letter-spacing: -0.01em; }

/* ---- Page banner (interior pages) --------------------------------------- */
.page-banner {
  background: var(--kelly-navy);
  color: #eaf0f8;
  padding-block: clamp(2rem, 4vw, 3.25rem);
}
.page-banner-slim { padding-block: 1rem; }
.page-banner-title { color: #fff; margin: 0.5rem 0 0.4rem; }
.page-banner-subtitle { color: #cdd8e8; max-width: 60ch; margin: 0; }

.breadcrumbs { font-size: 0.85rem; display: flex; gap: 0.5rem; align-items: center; flex-wrap: wrap; }
.breadcrumbs a { color: #cdd8e8; }
.breadcrumbs a:hover { color: #fff; }
.breadcrumbs [aria-current="page"] { color: #fff; font-weight: 600; }
.breadcrumbs span[aria-hidden] { color: #7f93b0; }
.breadcrumbs-light a { color: #e8eef7; }
.breadcrumbs-light [aria-current="page"] { color: #fff; }

/* ---- Service hero (service-category template) --------------------------- */
/* The source image remains a real eager <img> for semantics, responsive
   sources, and LCP discovery. It is positioned as a full-height visual layer,
   then feathered into the navy surface so no standalone photo card remains.
   The overlay is intentionally darkest beneath the copy. */
.service-band {
  position: relative;
  isolation: isolate;
  background: var(--kelly-navy-deep);
  color: #eaf0f8;
  overflow: hidden;
}
.service-band::after {
  content: "";
  position: absolute;
  z-index: 1;
  inset: 0;
  pointer-events: none;
  background: linear-gradient(90deg,
    rgba(20, 44, 75, 1) 0%,
    rgba(20, 44, 75, 0.98) 36%,
    rgba(20, 44, 75, 0.88) 55%,
    rgba(20, 44, 75, 0.5) 78%,
    rgba(20, 44, 75, 0.28) 100%);
}
.service-band-inner {
  position: relative;
  z-index: 2;
  display: flex;
  align-items: center;
  min-height: clamp(27rem, 37vw, 32rem);
  padding-block: clamp(2.5rem, 5vw, 4rem);
}
.service-band-copy { width: min(59%, 44rem); }
.service-band-title { color: #fff; margin: 0.7rem 0 0.5rem; }
.service-band-subtitle { color: #e0e8f3; max-width: 52ch; margin: 0 0 1.5rem; }
.service-band-actions { display: flex; flex-wrap: wrap; gap: 0.75rem; }
.service-band a:focus-visible { outline-color: var(--gold-on-navy); outline-offset: 4px; }
.service-hero-media {
  position: absolute;
  z-index: 0;
  inset: 0 0 0 auto;
  width: min(72%, 61.25rem);
  overflow: hidden;
  -webkit-mask-image: linear-gradient(90deg, transparent 0%, #000 28%, #000 100%);
  mask-image: linear-gradient(90deg, transparent 0%, #000 28%, #000 100%);
}
.service-hero-media.focus-heating { width: min(58%, 47.5rem); }
.service-hero-media picture {
  display: block;
  width: 100%;
  height: 100%;
}
.service-hero-media img {
  width: 100%;
  height: 100%;
  max-height: none;
  object-fit: cover;
  opacity: 0.92;
}
.service-hero-media.focus-heating img { object-position: 50% 60%; }
.service-hero-media.focus-cooling img { object-position: 50% 52%; }
.service-hero-media.focus-electrical img { object-position: 58% 46%; }
.service-hero-media.focus-hybrid img { object-position: 52% 48%; }

/* ---- Product detail ------------------------------------------------------ */
.product-intro-grid {
  display: grid;
  grid-template-columns: 1.05fr 0.95fr;
  gap: clamp(1.5rem, 4vw, 3rem);
  align-items: center;
}
.product-figure {
  margin: 0;
  background: var(--kelly-cream);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: clamp(1.5rem, 4vw, 3rem);
  display: flex;
  align-items: center;
  justify-content: center;
}
.product-figure picture { display: contents; }
.product-image { max-height: 360px; width: auto; }
.product-figure-review {
  flex-direction: column;
  gap: 1rem;
  min-height: 25rem;
  background: var(--white);
  box-shadow: var(--shadow-1);
}
.product-figure-review .product-image {
  width: 100%;
  height: clamp(15rem, 25vw, 20rem);
  object-fit: contain;
}
.product-figure-caption {
  max-width: 46ch;
  margin: 0;
  padding-top: 0.9rem;
  border-top: 1px solid var(--line);
  color: var(--ink-soft);
  font-size: 0.82rem;
  line-height: 1.5;
}
.product-title { margin: 0.2rem 0 0.5rem; }
.product-subtitle { font-size: 1.1rem; color: var(--ink-soft); margin-bottom: 1.4rem; }
.product-actions { display: flex; flex-wrap: wrap; gap: 0.75rem; }

/* ---- Steps strip --------------------------------------------------------- */
.steps { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(3, 1fr); gap: 1.25rem; counter-reset: step; }
.step { position: relative; padding-left: 3.25rem; }
.step::before {
  counter-increment: step;
  content: counter(step);
  position: absolute;
  left: 0;
  top: 0;
  width: 2.4rem;
  height: 2.4rem;
  display: grid;
  place-items: center;
  background: var(--kelly-navy);
  color: #fff;
  font-family: var(--font-display);
  font-weight: 700;
  border-radius: 50%;
}
.step h3 { margin: 0.2rem 0 0.3rem; font-size: 1.15rem; }
.step p { margin: 0; color: var(--ink-soft); font-size: 0.98rem; }

/* ---- Contact page -------------------------------------------------------- */
.contact-cards { display: grid; grid-template-columns: repeat(2, 1fr); gap: clamp(1.1rem, 2vw, 1.75rem); }
.contact-card {
  background: #fff;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow-1);
  padding: 1.6rem 1.6rem;
}
.contact-card.primary { border-color: var(--kelly-navy); border-width: 2px; }
.contact-card .kicker { margin-bottom: 0.4rem; }
.contact-card .big-phone {
  font-family: var(--font-display);
  font-size: clamp(1.7rem, 3vw, 2.2rem);
  font-weight: 700;
  color: var(--kelly-navy);
  letter-spacing: -0.02em;
  display: inline-block;
  margin-bottom: 0.4rem;
}
.contact-card address { font-style: normal; color: var(--ink-soft); }
.contact-card .hours-row { display: flex; justify-content: space-between; gap: 1rem; padding: 0.3rem 0; border-bottom: 1px solid var(--line); }
.contact-card .hours-row:last-child { border-bottom: 0; }

.emergency-note {
  background: #fbe9ec;
  border: 1px solid #f2c4cc;
  border-left: 4px solid var(--bryant-red);
  border-radius: var(--radius-sm);
  padding: 1rem 1.2rem;
  color: #6a0f1c;
}
.emergency-note strong { color: var(--bryant-red-dark); }

.map-embed {
  border: 0;
  width: 100%;
  height: 380px;
  border-radius: var(--radius);
  box-shadow: var(--shadow-1);
  display: block;
}
.map-placeholder {
  height: auto;
  min-height: 380px;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: flex-start;
  padding: clamp(1.4rem, 4vw, 2.2rem);
  border: 1px solid var(--line);
  background: #fff;
}
.map-placeholder > p:not(.kicker) { max-width: 34rem; }

/* ---- Forms --------------------------------------------------------------- */
.form-card {
  background: #fff;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow-1);
  padding: clamp(1.5rem, 3vw, 2.25rem);
}
.form-card p a:not(.btn) {
  text-decoration: underline;
  text-underline-offset: 0.15em;
}
.form-card p a:not(.btn):hover,
.form-card p a:not(.btn):focus-visible {
  text-decoration-thickness: 2px;
}
.form-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem 1.25rem; }
.field { display: flex; flex-direction: column; gap: 0.35rem; }
.field.full { grid-column: 1 / -1; }
.field label { font-weight: 600; font-size: 0.92rem; color: var(--kelly-navy); }
.field input,
.field select,
.field textarea {
  font-family: var(--font-body);
  font-size: 1rem;
  padding: 0.75rem 0.85rem;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-sm);
  background: #fff;
  color: var(--ink);
  width: 100%;
}
.field textarea { min-height: 130px; resize: vertical; }
.field input:focus, .field select:focus, .field textarea:focus {
  outline: none;
  border-color: var(--kelly-blue);
  box-shadow: 0 0 0 3px rgba(46, 92, 153, 0.18);
}
.form-hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }
.form-success {
  background: #e8f3ec;
  border: 1px solid #bcdcc7;
  border-left: 4px solid #2e7d46;
  border-radius: var(--radius-sm);
  padding: 1.1rem 1.25rem;
  color: #1e5230;
  font-weight: 600;
}
.form-success:focus-visible { outline: 3px solid var(--kelly-blue); outline-offset: 2px; }

/* Validation states. Built from the existing tokens (Bryant red, the shared
   radius, the same field spacing) so error styling reads as part of the
   approved system rather than a new one. Errors are never colour-only: each
   one carries text, and the input gets aria-invalid. */
.field.has-error input,
.field.has-error select,
.field.has-error textarea {
  border-color: var(--bryant-red);
  background: #fffafa;
}
.field.has-error input:focus,
.field.has-error select:focus,
.field.has-error textarea:focus {
  border-color: var(--bryant-red);
  box-shadow: 0 0 0 3px rgba(208, 16, 42, 0.16);
}
.field-error {
  margin: 0;
  font-size: 0.86rem;
  font-weight: 600;
  color: var(--bryant-red-dark);
}
.form-error-summary {
  background: #fdf1f3;
  border: 1px solid #f2c6ce;
  border-left: 4px solid var(--bryant-red);
  border-radius: var(--radius-sm);
  padding: 1rem 1.15rem;
  margin-bottom: 1.25rem;
}
.form-error-summary:focus-visible { outline: 3px solid var(--bryant-red); outline-offset: 2px; }
.form-error-summary-title {
  margin: 0 0 0.5rem;
  font-weight: 700;
  color: var(--bryant-red-dark);
}
.form-error-summary ul { margin: 0; padding-left: 1.15rem; }
.form-error-summary li + li { margin-top: 0.3rem; }
.form-error-summary a { color: var(--bryant-red-dark); }

/* Live region for send/failure status. Empty by default and takes no vertical
   space until it has something to say, so the form layout does not shift. */
.form-status { margin: 0.75rem 0 0; font-size: 0.9rem; font-weight: 600; }
.form-status:empty { display: none; }
.form-status-pending { color: var(--ink-soft); }
.form-status-error { color: var(--bryant-red-dark); }
.form-note { font-size: 0.85rem; color: var(--ink-soft); margin-top: 0.75rem; }

/* Required / optional cues. Shown in words rather than an asterisk: an
   asterisk means nothing on its own and is routinely announced as "star". */
.field-required,
.field-optional {
  font-weight: 500;
  font-size: 0.82rem;
  color: var(--ink-soft);
}

/* "Phone or email" is one requirement covering two inputs, so the two sit in a
   fieldset whose legend states the rule once. */
.field-group {
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  padding: 0.9rem 1rem 1rem;
  margin: 0 0 1rem;
  min-width: 0;
}
.field-group legend {
  font-weight: 600;
  font-size: 0.92rem;
  color: var(--kelly-navy);
  padding-inline: 0.35rem;
}
.field-group .form-grid { margin: 0; }

.field-hint { font-size: 0.82rem; color: var(--ink-soft); margin: 0; }

.form-privacy {
  font-size: 0.82rem;
  color: var(--ink-soft);
  line-height: 1.5;
  margin: 0 0 1rem;
}

/* The no-JS fallback note beside the submit button.
   It ships VISIBLE and the button ships disabled; src/scripts/forms.js hides
   this and enables the button once it has wired the form. Styling it as an
   error would overstate things - it is an instruction, not a failure. */
.form-nojs,
.form-nojs-static {
  font-size: 0.85rem;
  color: var(--ink);
  background: var(--bg-cream);
  border-left: 3px solid var(--gold);
  padding: 0.6rem 0.8rem;
  margin: 0.75rem 0 0;
  border-radius: var(--radius-sm);
}
.form-nojs[hidden] { display: none; }

/* ---- Accordion (FAQ) ----------------------------------------------------- */
.accordion { border: 1px solid var(--line); border-radius: var(--radius); overflow: hidden; background: #fff; }
.accordion-item + .accordion-item { border-top: 1px solid var(--line); }
.accordion-trigger {
  width: 100%;
  text-align: left;
  background: #fff;
  border: 0;
  cursor: pointer;
  padding: 1.15rem 1.35rem;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 1.1rem;
  color: var(--kelly-navy);
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 1rem;
}
.accordion-trigger:hover { background: var(--kelly-cream); }
.accordion-icon { flex: 0 0 auto; transition: transform .22s ease; color: var(--kelly-blue); }
.accordion-trigger[aria-expanded="true"] .accordion-icon { transform: rotate(45deg); }
.accordion-panel { padding: 0 1.35rem; max-height: 0; overflow: hidden; transition: max-height .28s ease, padding .28s ease; }
.accordion-panel[hidden] { display: block; } /* JS controls via max-height, keep readable without JS */
.accordion-trigger[aria-expanded="true"] + .accordion-panel { padding-bottom: 1.25rem; }
.no-js .accordion-panel { max-height: none; padding-bottom: 1.25rem; }

/* ---- Footer -------------------------------------------------------------- */
.site-footer { background: var(--kelly-navy-deep); color: #c6d2e2; }
.footer-grid {
  display: grid;
  grid-template-columns: 1.4fr 1fr 1fr 1fr;
  gap: 2rem;
  padding-block: clamp(2.5rem, 5vw, 4rem);
}
.footer-logo { height: 40px; width: auto; background: #fff; border-radius: 6px; padding: 6px 10px; margin-bottom: 0.9rem; }
.footer-tagline { color: #aebdd4; margin-bottom: 1rem; max-width: 34ch; }
.footer-badge { background: #fff; border-radius: var(--radius-sm); padding: 8px; }
.footer-heading { color: #fff; font-size: 1.05rem; margin-bottom: 0.9rem; }
.footer-nap p { margin: 0 0 0.35rem; }
.footer-nap a, .footer-links a, .footer-hours a { color: #c6d2e2; }
.footer-nap a:hover, .footer-links a:hover, .footer-hours a:hover { color: #fff; }
.footer-hours { color: #aebdd4; font-size: 0.95rem; margin-top: 0.6rem; }
/* The emergency number in the hours block is a link on a dark surface. Without
   this it inherited the default link blue (#2E5C99), which measures 2.08:1
   against the footer - unreadable, and the only accessibility regression the
   Lighthouse run caught. Underlined as well as recoloured so it still reads as
   a link against the surrounding light text. */
.footer-hours a { text-decoration: underline; text-underline-offset: 0.15em; }
.footer-links { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0.5rem; }
.footer-social { display: flex; gap: 0.6rem; margin-top: 1.1rem; }
.footer-social a {
  width: 40px; height: 40px;
  display: grid; place-items: center;
  border-radius: 50%;
  background: rgba(255,255,255,0.1);
  color: #fff;
  transition: background-color .18s ease, transform .18s ease;
}
.footer-social a:hover { background: var(--kelly-blue); transform: translateY(-2px); }
.footer-bottom { border-top: 1px solid rgba(255,255,255,0.12); }
.footer-bottom-inner {
  display: flex; flex-wrap: wrap; justify-content: space-between; gap: 0.5rem 1.5rem;
  padding-block: 1.1rem; font-size: 0.85rem; color: #9fb0c9;
}
.footer-meta { color: #9fb0c9; }
.footer-meta a { color: inherit; }
.footer-meta a:hover { color: #fff; text-decoration: underline; }

/* ---- Motion: scroll reveal ---------------------------------------------- */
.reveal {
  opacity: 0;
  transform: translateY(18px);
  transition: opacity .5s ease, transform .5s ease;
}
.reveal.is-visible { opacity: 1; transform: none; }

[data-reveal-group] > * {
  opacity: 0;
  transform: translateY(14px);
  transition: opacity .45s ease, transform .45s ease;
}
[data-reveal-group].is-visible > * { opacity: 1; transform: none; }
[data-reveal-group].is-visible > *:nth-child(2) { transition-delay: .08s; }
[data-reveal-group].is-visible > *:nth-child(3) { transition-delay: .16s; }
[data-reveal-group].is-visible > *:nth-child(4) { transition-delay: .24s; }
[data-reveal-group].is-visible > *:nth-child(5) { transition-delay: .32s; }
[data-reveal-group].is-visible > *:nth-child(6) { transition-delay: .40s; }

/* Content is never hidden when JS is off */
.no-js .reveal,
.no-js [data-reveal-group] > * { opacity: 1; transform: none; }

/* ---- Responsive ---------------------------------------------------------- */
/* Tighten the desktop nav before it collapses to the hamburger (1080px) so the
   menu never overflows the header at common laptop widths (1280 / 1366 / 1440).

   The hamburger threshold is 1080, not 900. Seven top-level items plus the logo
   need about 1040px, so between 901 and roughly 1030 the desktop nav ran past
   the right edge of the header and pushed the whole document into horizontal
   scroll. That was true before the logo was enlarged; the larger logo only made
   the window wider and easier to notice. Keep this in step with `mobileQuery`
   in src/scripts/main.js, which decides when a dropdown needs an explicit tap
   rather than hover. */
@media (min-width: 1081px) and (max-width: 1540px) {
  .header-inner { gap: 0.5rem; }
  .nav-list { gap: 0; }
  .nav-item > a,
  .dropdown-toggle {
    padding: 0.6rem 0.5rem;
    font-size: 0.86rem;
  }
  .dropdown-toggle .chevron { width: 10px; height: 10px; }
}
@media (min-width: 1081px) and (max-width: 1220px) {
  .nav-item > a,
  .dropdown-toggle { font-size: 0.8rem; padding: 0.6rem 0.4rem; }
}

@media (max-width: 960px) {
  .grid-4 { grid-template-columns: repeat(2, 1fr); }
  .grid-3 { grid-template-columns: repeat(2, 1fr); }
  .split { grid-template-columns: 1fr; }
  .cta-band-inner { grid-template-columns: 1fr; }
  .product-intro-grid { grid-template-columns: 1fr; }
  .contact-cards { grid-template-columns: 1fr; }
  .steps { grid-template-columns: 1fr; }
  /* At tablet and phone widths the same image becomes a true full-band layer.
     A near-solid vertical navy wash keeps long headings and both actions text-
     safe while the per-page focal point retains the meaningful subject. */
  .service-band::after {
    background: linear-gradient(180deg,
      rgba(20, 44, 75, 0.88) 0%,
      rgba(20, 44, 75, 0.9) 55%,
      rgba(20, 44, 75, 0.96) 100%);
  }
  .service-band-inner {
    min-height: 0;
    padding-block: clamp(2.25rem, 8vw, 3.5rem);
  }
  .service-band-copy { width: min(100%, 44rem); }
  .service-hero-media,
  .service-hero-media.focus-heating {
    inset: 0;
    width: 100%;
    -webkit-mask-image: none;
    mask-image: none;
  }
  .service-hero-media img { opacity: 0.72; }
  .service-hero-media.focus-heating img { object-position: 50% 58%; }
  .service-hero-media.focus-cooling img { object-position: 50% 52%; }
  .service-hero-media.focus-electrical img { object-position: 52% 48%; }
  .service-hero-media.focus-hybrid img { object-position: 52% 50%; }
}

/* Mobile nav: hamburger accordion */
@media (max-width: 1080px) {
  .nav-toggle { display: flex; }
  .primary-nav {
    position: fixed;
    top: var(--header-h);
    left: 0; right: 0;
    bottom: 0;
    background: #fff;
    border-top: 1px solid var(--line);
    overflow-y: auto;
    padding: 0.75rem clamp(1.1rem, 4vw, 2rem) 6rem;
    transform: translateX(-100%);
    transition: transform .25s ease;
    margin: 0;
    box-shadow: var(--shadow-2);
  }
  .primary-nav.is-open { transform: translateX(0); }
  .nav-list { flex-direction: column; align-items: stretch; gap: 0; }
  .nav-item { border-bottom: 1px solid var(--line); }
  .nav-item > a,
  .dropdown-toggle {
    width: 100%;
    justify-content: space-between;
    padding: 1rem 0.5rem;
    font-size: 1.05rem;
    min-height: 52px;
  }
  .nav-item > a::after { display: none; }
  .dropdown {
    position: static;
    opacity: 1;
    visibility: visible;
    transform: none;
    box-shadow: none;
    border: 0;
    min-width: 0;
    padding: 0 0 0 0.5rem;
    max-height: 0;
    overflow: hidden;
    transition: max-height .28s ease, padding-bottom .28s ease;
  }
  .dropdown-wide { grid-template-columns: 1fr; }
  .dropdown-toggle[aria-expanded="true"] + .dropdown { max-height: 720px; padding-bottom: 0.5rem; }
  .dropdown a { padding: 0.7rem 0.6rem; min-height: 46px; display: flex; align-items: center; }
  .no-js .dropdown { max-height: none; padding-bottom: 0.5rem; }

  /* No JS: the hamburger toggle can't run, so the nav must be visible and
     reachable by default instead of parked off-screen. */
  .no-js .header-inner { flex-wrap: wrap; }
  .no-js .nav-toggle { display: none; }
  .no-js .primary-nav {
    position: static;
    transform: none;
    margin-left: 0;
    width: 100%;
    order: 10;
    box-shadow: none;
    border-top: 1px solid var(--line);
    padding: 0.5rem clamp(1.1rem, 4vw, 2rem) 1rem;
    overflow-y: visible;
  }
}

@media (max-width: 768px) {
  /* Top bar: keep one slim row - just the red 24/7 block and the phone. */
  .top-bar-link { display: none; }
  .top-bar-emergency {
    font-size: 0.74rem;
    letter-spacing: 0.03em;
    padding-right: 0.85rem;
    /* keep the left edge flush with the bar (bleed past container padding) */
    padding-left: clamp(1.1rem, 4vw, 2rem);
  }
  .top-bar-phone { padding: 0.24rem 0.75rem; }
  .brand-logo { height: 58px; }
  .grid-4, .grid-3, .grid-2 { grid-template-columns: 1fr; }
  .cta-band-actions { align-items: stretch; }
  .footer-grid { grid-template-columns: 1fr 1fr; }

  /* ---- Phone hero: headline, then two full-width calls to action ---------
     The hero shortens and the headline steps down so both buttons and the
     trust line land inside the first screenful on a 667px-tall phone, which is
     the shortest handset still in real use. */
  .hero {
    min-height: 0;
    align-items: stretch;
  }
  .hero h1 { font-size: clamp(1.9rem, 8vw, 2.4rem); }
  .hero-content { padding-block: 1.75rem 2rem; max-width: none; }
  .hero-sub {
    font-size: 1rem;
    margin-bottom: 1.5rem;
    max-width: 36ch;
  }
  .hero-actions { display: block; }
  .hero-action {
    width: 100%;
    /* Comfortably past the 44px touch-target minimum, and tall enough to be
       the obvious thing to press with a thumb. */
    min-height: 56px;
    font-size: 1.05rem;
  }
  .hero-action + .hero-action { margin-top: 0.65rem; }
  .btn-outline-light.hero-action {
    /* A hairline outline disappears against a photo; this reads as a button. */
    background: rgba(255, 255, 255, 0.12);
    border-color: #fff;
    backdrop-filter: blur(2px);
  }
  .hero-trust {
    margin: 0.9rem 0 0;
    font-size: 0.78rem;
    color: #cbd7e6;
    text-align: center;
  }
}

@media (max-width: 520px) {
  .footer-grid { grid-template-columns: 1fr; }
  .top-bar-emergency { font-size: 0.68rem; }
  .service-band-title { font-size: clamp(2rem, 9.5vw, 2.65rem); }
  .service-band-actions { display: grid; grid-template-columns: minmax(0, 1fr); }
  .service-band-actions .btn { width: 100%; min-height: 52px; }
}

/* Very narrow screens, and the 400%-zoom equivalent of a normal one.
   The top bar is a single nowrap row of two fixed-content blocks, so below
   roughly 430px its natural width (measured: 363px of content in a 320px
   viewport) pushed the whole document into horizontal scroll and clipped the
   phone control off the right edge.
   Nothing is removed except the two decorative icons, which are aria-hidden
   and duplicate text that is right beside them. */
@media (max-width: 430px) {
  .header-inner { gap: 0.5rem; }
  .brand { flex: 1 1 auto; min-width: 0; }
  .brand-logo { max-width: 100%; height: auto; }
  .nav-toggle { flex: 0 0 44px; }
  .top-bar-inner { gap: 0.35rem; }
  .top-bar-emergency {
    letter-spacing: 0;
    font-size: 0.66rem;
    padding-right: 0.55rem;
    padding-left: 0.75rem;
    margin-left: calc(-1 * clamp(1.1rem, 4vw, 2rem));
  }
  .top-bar-emergency svg,
  .top-bar-phone svg { display: none; }
  .top-bar-phone {
    font-size: 0.78rem;
    padding: 0.24rem 0.6rem;
  }
}

/* ---- Small utilities ----------------------------------------------------- */
/* These replace inline style="" attributes that were scattered through page
   content. Moving them here is what lets the CSP drop 'unsafe-inline' for
   style-src; the rendered result is identical. */
.center { text-align: center; }
/* Prose-width container for text-only pages (privacy). Reading measure, not a
   new layout: it sits inside the standard .container. */
/* Centred rather than flush left: at 1200px the container is much wider than a
   74ch measure, and a left-aligned column leaves the page looking half-empty. */
.narrow { max-width: 74ch; margin-inline: auto; }
.narrow h2 { margin-top: 2rem; }
.narrow h2:first-child { margin-top: 0; }
.narrow p { margin-bottom: 1rem; line-height: 1.7; }
.inline-contact-links a {
  text-decoration: underline;
  text-decoration-thickness: 0.08em;
  text-underline-offset: 0.15em;
}
/* The service pages are body copy first, so the list treatment matches the
   paragraph rhythm rather than the tighter default. */
.narrow ul { margin: 0 0 1.1rem; padding-left: 1.25rem; line-height: 1.7; }
.narrow li { margin-bottom: 0.5rem; }
.narrow > :last-child { margin-bottom: 0; }
.card-pad { padding: 1.75rem; }
.btn-card { margin-top: 0.75rem; }
.btn-block { margin-top: 1rem; width: 100%; }
.muted-note { margin-top: 1.75rem; color: var(--ink-soft); }
/* Rate Our Business badge panel on /leave-a-review/ (was an inline style). */
.review-badge-frame {
  aspect-ratio: 5 / 4;
  background: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  margin: -1.75rem -1.75rem 0.75rem;
  padding: 1rem;
}
.review-badge-img { max-height: 100px; width: auto; }
.stack-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  justify-content: center;
  margin-top: 2rem;
}

/* Visible to screen readers, invisible on screen. Used for section names that
   are obvious sighted but missing from the accessibility tree. Deliberately not
   display:none, which would remove it from that tree entirely. */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* ---- Service areas ------------------------------------------------------- */
.service-area-actions,
.service-area-contact-actions,
.service-map-actions {
  display: flex;
  gap: 0.75rem;
  flex-wrap: wrap;
  align-items: center;
}
.service-area-contact-actions { justify-content: center; }
.service-area-list-note {
  margin-top: 1.75rem;
  color: var(--ink-soft);
}

/* The first-party regional map is the initial, privacy-preserving treatment.
   The entire shell is replaced by the opt-in iframe only after a button click. */
.service-map-shell {
  margin-top: clamp(2rem, 4vw, 3rem);
  overflow: hidden;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: #fff;
  box-shadow: var(--shadow-1);
}
.regional-map { margin: 0; }
.regional-map img {
  display: block;
  width: 100%;
  height: auto;
  border: 0;
  border-radius: 0;
  background: #EAF0F6;
}
.regional-map figcaption {
  margin: 0;
  padding: 0.75rem clamp(1rem, 3vw, 1.5rem);
  border-top: 1px solid var(--line);
  font-size: 0.9rem;
  color: var(--ink-soft);
}
.service-map-controls {
  display: grid;
  grid-template-columns: minmax(15rem, 1fr) auto;
  gap: 1.25rem 2rem;
  align-items: center;
  padding: clamp(1.25rem, 3vw, 2rem);
  border-top: 1px solid var(--line);
}
.service-map-controls p { margin-bottom: 0.5rem; }
.service-map-controls p:last-child { margin-bottom: 0; }
.service-map-controls a:not(.btn) {
  text-decoration: underline;
  text-underline-offset: 0.15em;
}
.service-map-nojs {
  grid-column: 1 / -1;
  padding-top: 1rem;
  border-top: 1px solid var(--line);
}
.service-area-map .map-embed {
  min-height: clamp(34rem, 65vw, 45rem);
  border-radius: var(--radius);
}

/* A dense, scan-friendly list on wide screens, with fewer columns as the
   viewport narrows. Long place names wrap inside their own column. */
.area-list {
  list-style: none;
  margin: 0;
  padding: 0;
  columns: 4;
  column-gap: clamp(1.25rem, 3vw, 2.5rem);
}
.area-list li {
  break-inside: avoid;
  padding: 0.32rem 0;
  line-height: 1.45;
  color: var(--ink);
  border-bottom: 1px solid var(--line, rgba(0, 0, 0, 0.08));
  overflow-wrap: anywhere;
}

/* ---- HTML site map ------------------------------------------------------- */
.sitemap-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 2rem 2.5rem;
}
.sitemap-group h3 {
  font-size: 1.05rem;
  color: var(--kelly-navy);
  padding-bottom: 0.5rem;
  margin-bottom: 0.75rem;
  border-bottom: 2px solid var(--line);
}
.sitemap-list { list-style: none; margin: 0; padding: 0; }
.sitemap-list li { padding: 0.3rem 0; line-height: 1.5; }
/* These sit in a plain list with no surrounding body text, so link colour was
   doing all the work of saying "this is a link" - and against the body text it
   measured about 1.18:1, which is no distinction at all for anyone who does not
   perceive the hue. An underline is a cue that does not depend on colour. */
.sitemap-list a { text-decoration: underline; text-underline-offset: 0.15em; }
.sitemap-list a:hover { text-decoration-thickness: 2px; }

/* ---- Blog ---------------------------------------------------------------- */
/* Moved verbatim out of <style> blocks that sat inside <main> on /blog/ and the
   blog post. Rules are unchanged - this is a relocation, not a restyle. */

/* blog index: post-card grid built on the site's .card component */
.blog-grid {
  display: grid;
  /* min(320px, 100%), not a bare 320px: a bare minimum track cannot shrink, so
     on a 320px phone the track plus the container padding pushed the document
     into horizontal scroll. */
  grid-template-columns: repeat(auto-fill, minmax(min(320px, 100%), 1fr));
  gap: clamp(1.25rem, 3vw, 2rem);
}
.blog-card {
  display: flex;
  flex-direction: column;
  overflow: hidden;
  padding: 0;
}
.blog-card-media {
  aspect-ratio: 16 / 9;
  overflow: hidden;
}
.blog-card-media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.blog-card-body {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  padding: 1.5rem;
}
.blog-card-date {
  font-size: 0.85rem;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: var(--ink-soft);
  margin: 0;
}
.blog-card-title {
  margin: 0;
  font-size: 1.3rem;
  line-height: 1.3;
}
.blog-card-title a {
  color: var(--kelly-navy);
  text-decoration: none;
}
.blog-card-title a:hover {
  text-decoration: underline;
}
.blog-card-excerpt {
  margin: 0;
  color: var(--ink-soft);
}
.blog-card-more {
  margin-top: auto;
  font-weight: 600;
  text-decoration: none;
}
.blog-card-more:hover {
  text-decoration: underline;
}

/* article typography: comfortable reading measure + rhythm for long-form posts */
.blog-post {
  max-width: 70ch;
  margin-inline: auto;
}
.blog-post-byline {
  font-size: 0.9rem;
  letter-spacing: 0.02em;
  color: var(--ink-soft);
  margin: 0 0 1.75rem;
  padding-bottom: 1.25rem;
  border-bottom: 1px solid var(--line, #e3e6ea);
}
.blog-post h2 {
  margin-top: 2.5rem;
  margin-bottom: 0.75rem;
  line-height: 1.25;
}
.blog-post h3 {
  margin-top: 1.75rem;
  margin-bottom: 0.5rem;
  font-size: 1.15rem;
  color: var(--kelly-navy);
}
.blog-post p {
  margin: 0 0 1.1rem;
  line-height: 1.7;
}
.blog-post ul {
  margin: 0 0 1.1rem;
  padding-left: 1.25rem;
  line-height: 1.7;
}
.blog-post li {
  margin-bottom: 0.5rem;
}
.blog-post-callout {
  background: var(--kelly-cream, #f6f3ee);
  border-left: 4px solid var(--kelly-navy);
  border-radius: 8px;
  padding: 1.25rem 1.5rem;
  margin: 2rem 0;
}
.blog-post-callout p {
  margin: 0;
}

/* New: publication/update dates sit inside the existing byline rule, and the
   author box below reuses the cream/line/radius tokens already in use. */
.blog-post-byline .blog-post-dates { display: block; margin-top: 0.25rem; }
.blog-post-author {
  display: flex;
  align-items: center;
  gap: 0.9rem;
  background: var(--kelly-cream);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 1.1rem 1.25rem;
  margin-top: 2.5rem;
}
.blog-post-author img { flex: 0 0 auto; width: 64px; height: auto; }
.blog-post-author p { margin: 0; font-size: 0.9rem; color: var(--ink-soft); line-height: 1.5; }
.blog-post-author .blog-post-author-name {
  display: block;
  font-weight: 700;
  color: var(--kelly-navy);
  font-family: var(--font-display);
}

@media (max-width: 900px) {
  .area-list { columns: 3; }
  .service-map-controls { grid-template-columns: 1fr; }
}
@media (max-width: 600px) {
  .area-list { columns: 2; column-gap: 1.25rem; }
  .service-map-actions .btn { width: 100%; }
}
@media (max-width: 350px) {
  .area-list { columns: 1; }
}

/* ---- Reduced motion (master switch) ------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
  .reveal, [data-reveal-group] > * { opacity: 1 !important; transform: none !important; }
  .hero-video { display: none; }
  .hero-fallback { display: block; animation: none !important; }
  .hero-video-toggle { display: none !important; }
}

