/* Self-hosted fonts (SIL OFL), latin subset. Regenerate with scripts/fetch-fonts.py */
@font-face {
  font-family: 'Public Sans';
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url(/assets/fonts/public-sans-italic.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: 'Public Sans';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(/assets/fonts/public-sans-normal.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: 'Public Sans';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url(/assets/fonts/public-sans-normal.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: 'Public Sans';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url(/assets/fonts/public-sans-normal.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: 'Zilla Slab';
  font-style: italic;
  font-weight: 600;
  font-display: swap;
  src: url(/assets/fonts/zilla-slab-italic-600.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: 'Zilla Slab';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url(/assets/fonts/zilla-slab-normal-600.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: 'Zilla Slab';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url(/assets/fonts/zilla-slab-normal-700.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;
}
/* =====================================================================
   Shea Plumbing & Gas: design system v5 (2026-10-06)
   Cinematic, calm, premium. Navy is the brand, brass the accent (the
   border and bolts of the sign), red only means "call now". Headings are
   Zilla Slab, the slab of the sign's lettering. Everything traces to a token below.
   Previous versions: .backup/styles-v2.css, .backup/styles-v3.css,
   .backup/pre-rebrand/styles-before-brass.css (v4: copper accent, Source Serif)
   ===================================================================== */

:root {
  /* colour roles */
  --bg: #f6f7f8;
  --paper: #fdfdfc;
  --tint: #eef2f6;
  --text: #111c2a;
  --muted: #4f5b69;
  --line: #dde3ea;
  --navy: #112f5b;
  --navy-600: #1b4178;
  --navy-800: #0d2547;
  --navy-900: #091a33;
  --brass: #b8913a;        /* the sign's border and bolts: rules, underlines, borders. Never text on light (2.7:1) */
  --gold: #ad842a;         /* THE text gold, one shade everywhere (Braidon, 2026-10-06): gold words, labels, icons, rings and bars on navy and
                              on white. 5.1:1 on --navy-900, 3.9:1 on --navy (big words only there), 3.2:1 on --bg (big words: large text needs 3:1) */
  --gold-small: #8b6711;   /* the one exception: small gold labels on white (eyebrows, card labels) need 4.5:1, so they take this deeper shade,
                              4.8:1 on --bg. On navy, small labels use --gold */
  --red: #c8272a;
  --red-700: #a51f22;
  --red-50: #fcefef;
  --amber-50: #fff6d6;
  --amber: #8a6100;
  --green: #1e6b43;

  /* type */
  --display: 'Zilla Slab', Rockwell, 'Roboto Slab', Georgia, serif;
  --body: 'Public Sans', 'Segoe UI', sans-serif;

  /* space (8pt) */
  --s1: 4px; --s2: 8px; --s3: 12px; --s4: 16px; --s5: 24px; --s6: 32px; --s7: 48px; --s8: 64px; --s9: 96px; --s10: 128px;
  --section: clamp(72px, 8vw, 128px);

  /* shape + depth: two elevations, used only on things that float */
  --r-s: 8px;
  --r-m: 14px;
  --r-l: 22px;
  --shadow-1: 0 1px 2px rgb(9 26 51 / 0.05), 0 12px 32px -18px rgb(9 26 51 / 0.28);
  --shadow-2: 0 2px 4px rgb(9 26 51 / 0.06), 0 40px 80px -36px rgb(9 26 51 / 0.55);

  /* motion */
  --ease: cubic-bezier(0.2, 0.7, 0.2, 1);
  --fast: 180ms;
  --slow: 700ms;

  --wrap: 1240px;
  --measure: 66ch;
  --header-h: 80px;
}

/* ---------- base ---------- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-padding-top: calc(var(--header-h) + 16px); scroll-behavior: smooth; }
body { margin: 0; background: var(--bg); color: var(--text); font: 400 1.125rem/1.65 var(--body); text-rendering: optimizeLegibility; -webkit-font-smoothing: antialiased; }
img { max-width: 100%; height: auto; display: block; }
a { color: var(--navy-600); text-underline-offset: 3px; text-decoration-thickness: 1px; transition: color var(--fast) var(--ease); }
a:hover { color: var(--navy); text-decoration-thickness: 2px; }
:focus-visible { outline: 3px solid var(--navy-600); outline-offset: 3px; border-radius: 3px; }
::selection { background: var(--navy); color: #fff; }

h1, h2, h3 { font-family: var(--display); color: var(--navy); font-weight: 600; margin: 0 0 var(--s4); text-wrap: balance; }
h1 { font-size: clamp(2.5rem, 1.3rem + 4.2vw, 5.1rem); line-height: 1.03; letter-spacing: -0.012em; }
h2 { font-size: clamp(2rem, 1.3rem + 2.1vw, 3.05rem); line-height: 1.08; letter-spacing: -0.008em; }
h3 { font-size: 1.3rem; line-height: 1.25; letter-spacing: -0.005em; }
h1 em, h2 em { font-style: italic; font-weight: 600; color: var(--gold); }
p { margin: 0 0 var(--s4); }
ul, ol { margin: 0 0 var(--s4); padding-left: 1.2em; }

.wrap { width: min(100% - 2 * var(--s5), var(--wrap)); margin-inline: auto; }
.narrow { max-width: 860px; }
.visually-hidden { position: absolute !important; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.skip { position: absolute; left: var(--s4); top: -60px; background: var(--navy); color: #fff; padding: var(--s2) var(--s4); z-index: 200; border-radius: var(--r-s); }
.skip:focus { top: var(--s2); }
.muted { color: var(--muted); }
.small { font-size: 0.925rem; }
.img-note { font-size: 0.75rem; letter-spacing: 0.04em; color: var(--muted); margin: var(--s2) 0 0; }

.eyebrow { display: inline-flex; align-items: center; gap: var(--s3); font: 700 0.78rem/1.3 var(--body); letter-spacing: 0.16em; text-transform: uppercase; color: var(--gold-small); margin: 0 0 var(--s4); }
.eyebrow::before { content: ''; width: 28px; height: 1.5px; background: currentColor; opacity: 0.7; }
.lede { font-size: clamp(1.1rem, 1rem + 0.35vw, 1.3rem); line-height: 1.55; color: var(--muted); max-width: 44ch; }

/* ---------- buttons ---------- */
.btn { position: relative; display: inline-flex; align-items: center; justify-content: center; gap: var(--s2); min-height: 50px; padding: 0 var(--s5); border-radius: var(--r-s); border: 1.5px solid transparent; font: 700 1rem/1 var(--body); letter-spacing: 0.005em; text-decoration: none; white-space: nowrap; cursor: pointer; transition: transform var(--fast) var(--ease), background var(--fast) var(--ease), box-shadow var(--fast) var(--ease), border-color var(--fast) var(--ease), color var(--fast) var(--ease); }
.btn:hover { text-decoration: none; transform: translateY(-1px); }
.btn:active { transform: translateY(0) scale(0.985); }
.btn-lg { min-height: 58px; padding: 0 var(--s6); font-size: 1.05rem; }
.btn-block { width: 100%; }
.btn-call { background: var(--red); color: #fff; box-shadow: 0 12px 24px -14px rgb(200 39 42 / 0.8); }
.btn-call:hover { background: var(--red-700); color: #fff; }
.btn-primary { background: var(--navy); color: #fff; box-shadow: 0 12px 24px -14px rgb(17 47 91 / 0.8); }
.btn-primary:hover { background: var(--navy-800); color: #fff; }
.btn-quiet { background: transparent; color: var(--navy); border-color: #b9c6d4; }
.btn-quiet:hover { border-color: var(--navy); color: var(--navy); }
.btn-ghost { background: rgb(255 255 255 / 0.06); color: #fff; border-color: rgb(255 255 255 / 0.55); }
.btn-ghost:hover { background: #fff; color: var(--navy); border-color: #fff; }
.actions { display: flex; flex-wrap: wrap; gap: var(--s3); margin: var(--s6) 0 var(--s5); }
.text-link { display: inline-flex; align-items: center; gap: var(--s2); font-weight: 700; text-decoration: none; }
.text-link svg { transition: transform var(--fast) var(--ease); }
.text-link:hover svg { transform: translateX(4px); }

/* ---------- top bar + header ---------- */
.topbar { background: var(--navy-900); color: #cdd8e6; font-size: 0.8125rem; position: relative; z-index: 60; }
/* The seasonal line: centred, a gold dot, the message, an arrow. Balanced wrapping on phones (no orphaned last word). */
.topbar-row { display: flex; justify-content: center; align-items: center; gap: var(--s4); min-height: 38px; text-align: center; }
.topbar p { margin: 0; text-wrap: balance; }
.topbar a { color: #fff; font-weight: 600; text-decoration: none; letter-spacing: 0.01em; }
.topbar .tb-dot { display: inline-block; width: 6px; height: 6px; border-radius: 50%; background: var(--gold); margin-right: var(--s3); vertical-align: 0.12em; box-shadow: 0 0 0 3px rgb(173 132 42 / 0.25); }
.topbar .tb-go { display: inline-block; margin-left: var(--s2); color: var(--gold); transition: transform var(--fast) var(--ease); }
.topbar a:hover .tb-text { text-decoration: underline; text-underline-offset: 3px; }
.topbar a:hover .tb-go { transform: translateX(3px); }

.site-header { position: sticky; top: 0; z-index: 50; background: var(--paper); border-bottom: 1px solid var(--line); transition: background-color 0.35s var(--ease), box-shadow 0.35s var(--ease), border-color 0.35s var(--ease); }
.header-row { display: flex; align-items: center; gap: var(--s6); min-height: var(--header-h); }
.brand { display: inline-flex; align-items: center; flex: none; text-decoration: none; }
/* The full sign hangs from the bar like a real one: the plaque fills the bar and the KINGSTON tab hangs below it, at
   the size where KINGSTON reads (about 8 px letters). --logo-hang is how far it reaches below the bar, so what sits
   under the bar (breadcrumbs, the hero's words) clears it. */
:root { --logo-h: 108px; --logo-top: 8px; --logo-hang: calc(var(--logo-top) + var(--logo-h) - var(--header-h)); }
.site-header .brand { align-self: flex-start; align-items: flex-start; height: var(--header-h); }
.brand img { height: var(--logo-h); width: auto; margin-top: var(--logo-top); filter: drop-shadow(0 10px 14px rgb(9 26 51 / 0.35)); }
.main-nav { margin-left: auto; }
.nav-list { display: flex; align-items: center; gap: var(--s1); }
.nav-list a { position: relative; padding: var(--s2) var(--s3); color: var(--text); text-decoration: none; font-weight: 600; font-size: 0.98rem; white-space: nowrap; transition: color 0.35s var(--ease); }
.nav-list a::after { content: ''; position: absolute; left: var(--s3); right: var(--s3); bottom: 2px; height: 2px; background: var(--brass); transform: scaleX(0); transform-origin: left; transition: transform var(--fast) var(--ease); }
.nav-list a:hover::after, .nav-list a[aria-current='page']::after { transform: scaleX(1); }
.nav-list .nav-book { display: none; }
.nav-toggle { display: none; }
.header-actions { display: flex; gap: var(--s2); }
.site-header.is-solid { box-shadow: var(--shadow-1); }

/* home: header floats over the cinematic hero until you scroll */
/* Home: clear on the first frame, with the film running up behind it. The moment you scroll it fades to solid navy over
   the dark hero (no white band across the film), then to the light header once the hero has gone by.
   site.js sets html.is-scrolled and .is-solid; the colours fade, so it reads as one smooth move. */
.site-header.is-over:not(.is-solid) { background-color: transparent; border-color: transparent; }
.is-scrolled .site-header.is-over:not(.is-solid) { background-color: var(--navy-900); border-color: rgb(255 255 255 / 0.08); box-shadow: 0 14px 32px -22px rgb(0 0 0 / 0.75); }
.site-header.is-over:not(.is-solid) .nav-list > a { color: #fff; }

@media (max-width: 1100px) {
  :root { --header-h: 68px; }
  :root { --logo-h: 92px; --logo-top: 6px; }
  .nav-toggle { display: inline-grid; place-items: center; width: 46px; height: 46px; border: 1px solid var(--line); background: var(--paper); border-radius: var(--r-s); cursor: pointer; }
  .nav-toggle span:first-child, .nav-toggle span:first-child::before, .nav-toggle span:first-child::after { display: block; width: 20px; height: 2px; background: var(--navy); border-radius: 2px; position: relative; transition: transform var(--fast) var(--ease), background var(--fast); }
  .nav-toggle span:first-child::before, .nav-toggle span:first-child::after { content: ''; position: absolute; left: 0; }
  .nav-toggle span:first-child::before { top: -6px; } .nav-toggle span:first-child::after { top: 6px; }
  .nav-toggle[aria-expanded='true'] span:first-child { background: transparent; }
  .nav-toggle[aria-expanded='true'] span:first-child::before { transform: translateY(6px) rotate(45deg); }
  .nav-toggle[aria-expanded='true'] span:first-child::after { transform: translateY(-6px) rotate(-45deg); }
  .main-nav { order: 3; margin-left: 0; }
  .header-actions { margin-left: auto; }
  .nav-list { display: none; position: absolute; left: 0; right: 0; top: 100%; flex-direction: column; align-items: stretch; gap: 0; background: var(--paper); border-bottom: 1px solid var(--line); box-shadow: var(--shadow-2); padding: var(--s3) var(--s5) var(--s5); }
  .nav-list.open { display: flex; }
  /* the open menu starts under the bar, where the sign hangs: keep the sign on top and start the links below its tab */
  .site-header .brand { position: relative; z-index: 2; }
  .nav-list { padding-top: calc(var(--logo-hang) + var(--s3)); }
  .nav-list a, .site-header.is-over:not(.is-solid) .nav-list > a { color: var(--text); padding: var(--s4) 0; font-size: 1.1rem; border-bottom: 1px solid var(--line); }
  .nav-list a::after { display: none; }
  .nav-list .nav-book { display: flex; justify-content: center; margin-top: var(--s4); border: 0; background: var(--navy); color: #fff !important; border-radius: var(--r-s); }
  .site-header.is-over:not(.is-solid) .nav-toggle { background: transparent; border-color: rgb(255 255 255 / 0.4); }
  .site-header.is-over:not(.is-solid) .nav-toggle span:first-child, .site-header.is-over:not(.is-solid) .nav-toggle span:first-child::before, .site-header.is-over:not(.is-solid) .nav-toggle span:first-child::after { background: #fff; }
  .site-header.is-over:not(.is-solid) .nav-toggle[aria-expanded='true'] span:first-child { background: transparent; }
}
@media (max-width: 640px) {
  .header-actions .btn-call span { display: none; }
  .header-actions .btn-call { width: 46px; padding: 0; min-height: 46px; }
  .topbar-row > a { display: none; }   /* the campaign message stays: it is the bar's only content */
  .topbar-row { padding-block: var(--s2); }
}

/* ---------- breadcrumbs ---------- */
.crumbs ol { list-style: none; display: flex; flex-wrap: wrap; gap: var(--s2); padding: calc(var(--s5) + var(--logo-hang)) 0 0; margin: 0; font-size: 0.9rem; color: var(--muted); }
.crumbs li + li::before { content: '/'; margin-right: var(--s2); color: #b9c6d4; }
.crumbs a { color: var(--muted); text-decoration: none; }
.crumbs a:hover { color: var(--navy); text-decoration: underline; }

/* ---------- cinematic hero (home) ---------- */
.hero-cine { position: relative; isolation: isolate; color: #fff; background: var(--navy-900); min-height: min(94vh, 900px); min-height: min(94svh, 900px); display: grid; grid-template-rows: 1fr auto; overflow: hidden; }
.page-home .hero-cine { margin-top: calc(-1 * var(--header-h)); padding-top: var(--header-h); }
.hero-bg { position: absolute; inset: 0; z-index: -1; }
.hero-img { width: 100%; height: 100%; object-fit: cover; object-position: 72% 50%; transform-origin: 70% 50%; animation: hero-zoom 2.6s var(--ease) both; }
.hero-bg::after { content: ''; position: absolute; inset: 0; background:
  linear-gradient(90deg, rgb(9 26 51 / 0.94) 0%, rgb(9 26 51 / 0.78) 34%, rgb(9 26 51 / 0.2) 66%, rgb(9 26 51 / 0) 100%),
  linear-gradient(0deg, rgb(9 26 51 / 0.9) 0%, rgb(9 26 51 / 0) 34%),
  linear-gradient(180deg, rgb(9 26 51 / 0.55) 0%, rgb(9 26 51 / 0) 22%); }
.hero-inner { align-self: center; padding: var(--s9) 0 var(--s7); }
.hero-cine h1 { color: #fff; max-width: 19ch; font-size: clamp(2.5rem, 1.2rem + 3.9vw, 4.7rem); }
.hero-cine h1 em { color: var(--gold); display: block; }
.hero-cine .eyebrow { color: var(--gold); }
.hero-cine .lede { color: #d5deea; max-width: 46ch; }
/* its own row under the buttons (inline, it shared a line with the scroll cue) */
.after-hours { display: flex; width: fit-content; align-items: center; gap: var(--s2); margin: 0; font-size: 0.95rem; color: #d5deea; }
.after-hours::before { content: ''; width: 8px; height: 8px; border-radius: 50%; background: var(--gold); }
.hero-foot { padding-bottom: var(--s6); }
.hero-strip { display: grid; grid-template-columns: repeat(4, 1fr); margin: 0; border-top: 1px solid rgb(255 255 255 / 0.18); padding-top: var(--s5); }
.hero-strip div { display: flex; flex-direction: column-reverse; gap: 2px; padding-right: var(--s5); }
.hero-strip div + div { padding-left: var(--s5); border-left: 1px solid rgb(255 255 255 / 0.14); }
.hero-strip dd { margin: 0; font: 600 clamp(1.5rem, 1.1rem + 1vw, 2.2rem)/1.1 var(--display); color: #fff; }
.hero-strip dt { font-size: 0.875rem; color: #aebdd0; }
.strip-star { color: var(--gold); font-size: 0.8em; margin-left: 2px; }
.hero-note { position: absolute; right: var(--s5); bottom: var(--s2); margin: 0; color: rgb(255 255 255 / 0.5); }
.hero-in { animation: rise 0.9s var(--ease) both; }
.hero-inner .hero-in:nth-child(2) { animation-delay: 0.08s; }
.hero-inner .hero-in:nth-child(3) { animation-delay: 0.16s; }
.hero-inner .hero-in:nth-child(4) { animation-delay: 0.24s; }
.hero-foot.hero-in { animation-delay: 0.4s; }
@keyframes rise { from { opacity: 0; transform: translateY(18px); } to { opacity: 1; transform: none; } }
@keyframes hero-zoom { from { transform: scale(1.08); } to { transform: scale(1); } }
@media (max-width: 800px) {
  .hero-cine { min-height: 0; }
  .hero-img { object-position: 78% 50%; }
  .hero-bg::after { background: linear-gradient(180deg, rgb(9 26 51 / 0.55) 0%, rgb(9 26 51 / 0.82) 40%, rgb(9 26 51 / 0.96) 100%); }
  .hero-inner { padding: var(--s8) 0 var(--s6); }
  .hero-strip { grid-template-columns: 1fr 1fr; row-gap: var(--s5); }
  .hero-strip div:nth-child(3) { padding-left: 0; border-left: 0; }
  .hero-cine .actions .btn { flex: 1 1 100%; }
}

/* ---------- page hero (services, areas, hubs) ---------- */
.page-hero { padding: var(--s6) 0 var(--s8); background: linear-gradient(180deg, var(--bg) 0%, var(--tint) 100%); }
.page-hero-simple { padding-bottom: var(--s7); }
.hero-split { display: grid; grid-template-columns: 1.05fr 0.95fr; gap: clamp(32px, 6vw, 96px); align-items: center; }
.page-hero h1 { font-size: clamp(2.3rem, 1.3rem + 3vw, 4rem); }
.page-hero-simple .lede { max-width: 60ch; }
.hero-photo { margin: 0; position: relative; }
.hero-photo img { width: 100%; aspect-ratio: 4 / 4.6; object-fit: cover; border-radius: var(--r-l); box-shadow: var(--shadow-2); }
.hero-illus img { aspect-ratio: 3 / 2.1; }
.hero-photo figcaption { margin-top: var(--s3); }
.hero-media { position: relative; }
.proof-row { list-style: none; padding: 0; margin: 0; display: flex; flex-wrap: wrap; gap: var(--s3) var(--s5); font-size: 0.95rem; color: var(--muted); }
.proof-row li, .proof-row a { display: inline-flex; align-items: center; gap: var(--s2); color: var(--text); text-decoration: none; }
.proof-row a:hover { text-decoration: underline; }
.stars { display: inline-flex; color: #d99a00; }
.badge-mark { display: inline-grid; place-items: center; min-width: 30px; height: 22px; padding: 0 5px; border: 1.5px solid var(--navy); border-radius: 4px; font: 800 0.68rem/1 var(--body); color: var(--navy); }
@media (max-width: 900px) {
  .hero-split { grid-template-columns: 1fr; gap: var(--s6); }
  .page-hero .hero-photo { display: none; }
  .page-hero .hero-illus { display: block; order: -1; }
  .page-hero { padding-bottom: var(--s7); }
}
@media (max-width: 560px) { .actions .btn { flex: 1 1 100%; } }

/* ---------- sections ---------- */
.section { padding: var(--section) 0; }
.section.tint { background: var(--tint); }
.section-head { max-width: 760px; margin-bottom: var(--s7); }
.section-head p:not(.eyebrow) { color: var(--muted); font-size: 1.1rem; }
.section-head.center { margin-inline: auto; text-align: center; }
.section-head.center .eyebrow { justify-content: center; }

/* service cards: image-led */
.svc-grid { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--s5); }
.svc-card a { display: flex; flex-direction: column; height: 100%; background: var(--paper); border-radius: var(--r-m); overflow: hidden; text-decoration: none; color: var(--muted); box-shadow: var(--shadow-1); transition: transform var(--slow) var(--ease), box-shadow var(--slow) var(--ease); }
.svc-card a:hover { transform: translateY(-4px); box-shadow: var(--shadow-2); }
.svc-media { display: block; overflow: hidden; aspect-ratio: 4 / 3; background: var(--tint); }
.svc-media img { width: 100%; height: 100%; object-fit: cover; transition: transform 1.2s var(--ease); }
.svc-card a:hover .svc-media img { transform: scale(1.05); }
.svc-body { display: flex; flex-direction: column; gap: var(--s2); padding: var(--s5); flex: 1; }
.svc-title { font: 600 1.35rem/1.2 var(--display); color: var(--navy); }
.svc-desc { font-size: 1rem; flex: 1; }
.svc-more { display: inline-flex; align-items: center; gap: var(--s1); font-weight: 700; font-size: 0.95rem; color: var(--navy-600); margin-top: var(--s2); }
.svc-more svg { transition: transform var(--fast) var(--ease); }
.svc-card a:hover .svc-more svg { transform: translateX(4px); }
.svc-more-list { list-style: none; padding: 0; margin: var(--s6) 0 0; display: grid; grid-template-columns: repeat(2, 1fr); gap: 0 var(--s6); }
.svc-more-list a { display: grid; grid-template-columns: auto 1fr auto; gap: var(--s4); align-items: center; padding: var(--s5) 0; border-top: 1px solid var(--line); text-decoration: none; color: var(--muted); font-size: 0.975rem; }
.svc-more-list strong { display: block; font: 600 1.15rem/1.3 var(--display); color: var(--navy); }
.svc-more-list > li > a > svg { color: var(--navy-600); transition: transform var(--fast) var(--ease); }
.svc-more-list a:hover > svg { transform: translateX(4px); }
.svc-mini { display: grid; place-items: center; width: 48px; height: 48px; border-radius: 12px; background: var(--tint); color: var(--navy); }
@media (max-width: 640px) {
  .svc-grid { display: flex; overflow-x: auto; scroll-snap-type: x mandatory; gap: var(--s4); margin: 0 calc(-1 * var(--s5)); padding: var(--s2) var(--s5) var(--s5); scroll-padding-inline: var(--s5); scrollbar-width: none; }
  .svc-grid::-webkit-scrollbar { display: none; }
  .svc-grid > li { flex: 0 0 82%; scroll-snap-align: start; }
  .svc-more-list { grid-template-columns: 1fr; }
}
/* legacy icon grid (kept for any page still using it) */
.service-grid { list-style: none; padding: 0; margin: 0; display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: var(--s4); }
.service-grid a { display: flex; flex-direction: column; gap: var(--s2); height: 100%; padding: var(--s5); background: var(--paper); border-radius: var(--r-m); text-decoration: none; color: var(--muted); box-shadow: var(--shadow-1); }
.svc-badge { display: grid; place-items: center; width: 52px; height: 52px; border-radius: 12px; background: var(--tint); color: var(--navy); }
.service-name { font: 600 1.25rem/1.2 var(--display); color: var(--navy); }

/* ---------- interactive house guide (signature) ---------- */
.cutaway { background: #f7f5f2; }
.cut-layout { display: grid; grid-template-columns: minmax(0, 1fr) 380px; gap: var(--s6); align-items: stretch; }
.cut-stage { position: relative; align-self: start; }
.cut-img { width: 100%; height: auto; }
.spot { position: absolute; width: 30px; height: 30px; margin: -15px 0 0 -15px; border-radius: 50%; border: 0; padding: 0; cursor: pointer; background: var(--navy); color: #fff; font: 700 0.8rem/30px var(--body); text-align: center; box-shadow: 0 0 0 3px rgb(255 255 255 / 0.95), 0 6px 14px -4px rgb(9 26 51 / 0.5); transition: transform var(--fast) var(--ease), background var(--fast); z-index: 2; }
.spot::after { content: ''; position: absolute; inset: -3px; border-radius: 50%; border: 2px solid var(--navy); animation: ping 3.2s var(--ease) infinite; pointer-events: none; }
.spot:nth-child(3n)::after { animation-delay: 1s; } .spot:nth-child(3n+1)::after { animation-delay: 2s; }
.spot:hover, .spot:focus-visible { transform: scale(1.18); }
.spot.active { background: var(--red); transform: scale(1.22); z-index: 3; }
.spot.active::after { border-color: var(--red); }
.cut-layout.has-active .spot:not(.active) { opacity: 0.55; }
.cut-layout.has-active .spot:not(.active):hover { opacity: 1; }
@keyframes ping { 0% { transform: scale(1); opacity: 0.6; } 70%, 100% { transform: scale(2); opacity: 0; } }

.cut-panel { position: relative; background: var(--paper); border-radius: var(--r-l); box-shadow: var(--shadow-1); min-height: 420px; }
.cut-panel-inner { position: absolute; inset: 0; overflow-y: auto; padding: var(--s5) var(--s5) var(--s6); scroll-behavior: smooth; scrollbar-width: thin; scrollbar-color: #c8d2dd transparent; }
.cut-hint { font-size: 0.9rem; color: var(--muted); margin: 0 0 var(--s4); }
.cut-group + .cut-group { margin-top: var(--s5); }
.cut-group h3 { font: 700 0.75rem/1 var(--body); letter-spacing: 0.16em; text-transform: uppercase; color: var(--gold-small); margin: 0 0 var(--s2); }
.spot-item { border-top: 1px solid var(--line); }
.spot-item summary { list-style: none; cursor: pointer; display: grid; grid-template-columns: 30px 1fr 12px; gap: var(--s3); align-items: center; padding: var(--s3) 0; font-weight: 600; color: var(--text); }
.spot-item summary::-webkit-details-marker { display: none; }
.spot-item summary::after { content: ''; width: 8px; height: 8px; border-right: 2px solid var(--muted); border-bottom: 2px solid var(--muted); transform: rotate(45deg); transition: transform var(--fast) var(--ease); }
.spot-item[open] summary::after { transform: rotate(225deg); }
.spot-item summary:hover .spot-t { color: var(--navy); }
.cut-n { display: grid; place-items: center; width: 26px; height: 26px; border-radius: 50%; background: var(--navy); color: #fff; font: 700 0.75rem var(--body); }
.spot-item[open] .cut-n { background: var(--red); }
.spot-body { padding: 0 0 var(--s4) 42px; font-size: 0.95rem; color: var(--muted); }
.spot-body ul { margin: 0 0 var(--s3); padding-left: 1.1em; }
.spot-body li { margin-bottom: 2px; }
.spot-h { font: 700 0.72rem/1 var(--body); letter-spacing: 0.14em; text-transform: uppercase; color: var(--navy); margin: var(--s2) 0 var(--s2); }
.spot-now { background: var(--tint); border-left: 3px solid var(--brass); border-radius: var(--r-s); padding: var(--s3) var(--s4); color: var(--text); margin: 0 0 var(--s3); }
.spot-body .text-link { font-size: 0.95rem; }
.cutaway .img-note { text-align: center; margin-top: var(--s4); }
@media (max-width: 960px) {
  .cut-layout { grid-template-columns: 1fr; }
  .cut-panel { min-height: 0; }
  .cut-panel-inner { position: static; overflow: visible; }
}
@media (max-width: 640px) {
  .spot { width: 24px; height: 24px; margin: -12px 0 0 -12px; font-size: 0.66rem; line-height: 24px; box-shadow: 0 0 0 2px #fff; }
  .spot::after { display: none; }
}

/* ---------- problem finder ---------- */
.finder { background: var(--paper); }
.finder-grid { display: grid; grid-template-columns: 1fr 1fr; gap: var(--s6); align-items: stretch; }
.finder-options { list-style: none; padding: 0; margin: 0; display: grid; grid-template-columns: 1fr 1fr; gap: var(--s3); align-content: start; }
.finder-opt { display: flex; align-items: center; min-height: 68px; padding: var(--s3) var(--s5); border: 1px solid var(--line); border-radius: var(--r-m); background: var(--bg); color: var(--text); font-weight: 600; text-decoration: none; transition: border-color var(--fast), background var(--fast), color var(--fast), transform var(--fast) var(--ease); }
.finder-opt:hover { border-color: var(--navy); background: var(--paper); color: var(--navy); text-decoration: none; transform: translateY(-1px); }
.finder-opt[aria-current='true'] { border-color: var(--navy); background: var(--navy); color: #fff; }
.finder-result { position: relative; padding: var(--s6); border-radius: var(--r-l); background: var(--navy-900); color: #cdd8e6; box-shadow: var(--shadow-2); }
.finder-result:focus { outline: none; }
.finder-result h3 { color: #fff; font-size: 1.6rem; margin-bottom: var(--s2); }
.finder-result .steps { margin: var(--s5) 0 0; font-size: 1rem; }
.finder-result .steps li::before { background: var(--gold); color: var(--navy-900); }
.finder-result strong { color: #fff; }
.finder-result .actions { margin: var(--s5) 0 var(--s3); }
.finder-result .text-link { color: var(--gold); }
.lv { display: inline-block; padding: var(--s1) var(--s3); border-radius: 999px; font: 700 0.78rem/1.4 var(--body); letter-spacing: 0.06em; text-transform: uppercase; margin: 0 0 var(--s3); }
.lv-lead { margin: 0; }
.lv-now, .lv-gas { background: var(--red); color: #fff; }
.lv-today { background: #f3c07a; color: #3d2400; }
.lv-soon { background: #f7e3a1; color: #3d2d00; }
.lv-book { background: #bfe3cd; color: #0f3b24; }
@media (max-width: 900px) { .finder-grid { grid-template-columns: 1fr; } }
@media (max-width: 520px) { .finder-options { grid-template-columns: 1fr; } }

/* ---------- the promise (editorial split) ---------- */
.promise { padding: 0; background: var(--paper); }
.promise-grid { display: grid; grid-template-columns: 1fr 1fr; min-height: 720px; }
.promise-media { position: relative; overflow: hidden; }
.promise-media img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
/* Wide screens: the photo is one screen tall and stays in view while the six promises scroll past. Stretched down the
   whole list (~1,300 px) it was cropped into a soft, blown-up close-up. */
@media (min-width: 901px) {
  .promise-media { position: sticky; top: var(--header-h); align-self: start; height: calc(100vh - var(--header-h)); height: calc(100svh - var(--header-h)); }
}
.promise-copy { padding: var(--section) clamp(24px, 6vw, 96px); align-self: center; max-width: 680px; }
.promise-list { list-style: none; counter-reset: pr; padding: 0; margin: var(--s6) 0 var(--s5); }
.promise-list li { counter-increment: pr; display: grid; grid-template-columns: 52px 1fr; column-gap: var(--s4); padding: var(--s4) 0; border-top: 1px solid var(--line); }
.promise-list li::before { content: counter(pr, decimal-leading-zero); grid-row: span 2; font: italic 600 1.5rem/1.3 var(--display); color: var(--gold); }
.promise-list strong { font: 600 1.2rem/1.3 var(--display); color: var(--navy); }
.promise-list span { color: var(--muted); font-size: 1rem; }
@media (max-width: 900px) {
  .promise-grid { grid-template-columns: 1fr; min-height: 0; }
  .promise-media { aspect-ratio: 16 / 10; }
  .promise-copy { padding: var(--s8) var(--s5); }
}
/* compact promise card (hub pages) */
.inc-grid { display: grid; grid-template-columns: 0.8fr 1.2fr; gap: var(--s8); }
.includes { background: var(--paper); border-radius: var(--r-m); box-shadow: var(--shadow-1); padding: var(--s3) var(--s6); }
.includes ul { list-style: none; margin: 0; padding: 0; }
.includes li { display: grid; grid-template-columns: 24px 1fr; gap: var(--s3); padding: var(--s4) 0; border-bottom: 1px solid var(--line); }
.includes li:last-child { border-bottom: 0; }
.includes strong { display: block; color: var(--navy); }
.includes span { color: var(--muted); font-size: 1rem; }

/* ---------- owner band ---------- */
.owner-band { background: var(--navy-900); color: #b9c8da; position: relative; overflow: hidden; }
.owner-band h2 { color: #fff; }
.owner-band h2 em { color: var(--gold); }
.owner-band .eyebrow { color: var(--gold); }
.owner-grid { display: grid; grid-template-columns: 0.85fr 1.15fr; gap: clamp(32px, 7vw, 112px); align-items: center; }
.owner-photo { margin: 0; }
.owner-photo img { width: 100%; aspect-ratio: 4 / 4.8; object-fit: cover; border-radius: var(--r-l); box-shadow: 0 40px 80px -40px rgb(0 0 0 / 0.7); }
.owner-photo figcaption { font-size: 0.8rem; color: #8ea2ba; margin-top: var(--s3); }
.owner-quote { margin: 0 0 var(--s6); padding: 0; border: 0; }
.owner-quote p { font: italic 600 clamp(1.3rem, 1.05rem + 0.7vw, 1.7rem)/1.45 var(--display); color: #fff; margin-bottom: var(--s3); }
.owner-quote footer { font-size: 0.95rem; color: #8ea2ba; }
.owner-facts { list-style: none; padding: 0; margin: 0 0 var(--s6); display: grid; grid-template-columns: repeat(4, auto); justify-content: start; gap: var(--s6); }
.owner-facts li { display: flex; flex-direction: column; }
.owner-facts strong { font: 600 1.6rem/1.1 var(--display); color: #fff; }
.owner-facts span { font-size: 0.875rem; color: #8ea2ba; }
.owner-band .text-link { color: #fff; }
.owner-band :focus-visible { outline-color: var(--gold); }
.note-card { background: rgb(255 255 255 / 0.04); border-left: 3px solid var(--gold); border-radius: var(--r-s); padding: var(--s5); }
@media (max-width: 900px) { .owner-grid { grid-template-columns: 1fr; } .owner-photo img { aspect-ratio: 4 / 3; } .owner-facts { grid-template-columns: repeat(2, auto); } }

/* ---------- reviews carousel ---------- */
.rv-head { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: flex-end; gap: var(--s5); margin-bottom: var(--s6); }
.rv-head h2 { margin: 0; }
.rv-head .eyebrow { margin-bottom: var(--s3); }
.rv-summary { display: grid; grid-template-columns: auto auto; align-items: center; column-gap: var(--s5); row-gap: var(--s2); }
.rv-score { grid-row: span 2; display: flex; flex-direction: column; margin: 0; font: 600 3.4rem/1 var(--display); color: var(--navy); }
.rv-score .stars { margin-top: 6px; }
.rv-count { margin: 0; color: var(--muted); font-size: 0.95rem; }
.rv-summary .btn { min-height: 42px; padding: 0 var(--s4); font-size: 0.95rem; justify-self: start; }
.rv-rail { position: relative; }
.rv-track { list-style: none; margin: 0 calc(-1 * var(--s5)); padding: var(--s3) var(--s5) var(--s6); display: flex; gap: var(--s5); overflow-x: auto; scroll-snap-type: x mandatory; scroll-padding-inline: var(--s5); scrollbar-width: none; overscroll-behavior-x: contain; }
.rv-track::-webkit-scrollbar { display: none; }
.rv-card { flex: 0 0 min(380px, 84vw); scroll-snap-align: start; }
.rv-card article, .rv-more > div { height: 100%; display: flex; flex-direction: column; gap: var(--s4); padding: var(--s6); background: var(--paper); border-radius: var(--r-m); box-shadow: var(--shadow-1); }
.rv-who { display: flex; gap: var(--s3); align-items: center; }
.rv-who strong { display: block; color: var(--text); }
.rv-who a { color: inherit; text-decoration: none; }
.rv-avatar { flex: none; width: 46px; height: 46px; border-radius: 50%; display: grid; place-items: center; background: var(--tint); color: var(--navy); font: 600 1.15rem var(--display); object-fit: cover; }
.rv-meta { display: flex; align-items: center; gap: var(--s2); font-size: 0.85rem; color: var(--muted); }
.rv-meta .stars svg { width: 14px; height: 14px; }
.rv-stars { color: #d99a00; letter-spacing: 1px; }
.rv-text { margin: 0; font: 400 1.06rem/1.65 var(--body); color: var(--text); display: -webkit-box; -webkit-line-clamp: 7; -webkit-box-orient: vertical; overflow: hidden; }
.rv-text.open { -webkit-line-clamp: unset; display: block; }
.rv-toggle { align-self: flex-start; background: none; border: 0; padding: 0; font: 700 0.95rem var(--body); color: var(--navy-600); cursor: pointer; text-decoration: underline; text-underline-offset: 3px; }
.rv-more > div { justify-content: center; background: var(--navy); color: #cdd8e6; }
.rv-more-score { display: flex; align-items: center; gap: var(--s2); margin: 0; font: 600 2.6rem/1 var(--display); color: #fff; }
.rv-more p { margin: 0; }
.rv-more .btn-primary { background: #fff; color: var(--navy); align-self: flex-start; box-shadow: none; }
.rv-more .text-link { color: #fff; }
.rv-nav { position: absolute; top: calc(50% - 34px); width: 52px; height: 52px; border-radius: 50%; border: 0; background: var(--paper); color: var(--navy); display: grid; place-items: center; cursor: pointer; box-shadow: var(--shadow-2); z-index: 2; transition: transform var(--fast) var(--ease), opacity var(--fast); }
.rv-nav:hover { transform: scale(1.06); }
.rv-nav[hidden] { display: none; }
.rv-nav:disabled { opacity: 0; pointer-events: none; }
.rv-prev { left: -26px; } .rv-prev svg { transform: rotate(180deg); }
.rv-next { right: -26px; }
.rv-attrib { font-size: 0.8rem; color: var(--muted); margin: 0; }
@media (max-width: 760px) { .rv-nav { display: none; } .rv-score { font-size: 2.6rem; } }
.rating-line { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s2); }
.review-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: var(--s4); }

/* ---------- map + areas ---------- */
.map-grid { display: grid; grid-template-columns: 1.4fr 1fr; gap: var(--s6); align-items: start; }
.area-map { margin: 0; }
.area-map svg { width: 100%; height: auto; display: block; border-radius: var(--r-l); box-shadow: var(--shadow-1); background: #eef1ea; }
.area-map figcaption { font-size: 0.8rem; color: var(--muted); margin-top: var(--s3); }
.map-water { font: italic 600 16px var(--display); fill: #3f7da3; letter-spacing: 0.1em; }
.map-road { fill: none; stroke: #c9cfc3; stroke-width: 5; stroke-linecap: round; stroke-linejoin: round; }
.map-road-minor { stroke-width: 3; }
.map-roadlabel { font: 700 11px var(--body); fill: #7c8578; }
.map-town circle { fill: var(--navy); stroke: #fff; stroke-width: 2.5; transition: fill var(--fast); }
.map-town text { font: 700 14px var(--body); fill: var(--text); paint-order: stroke; stroke: #eef1ea; stroke-width: 4px; }
.map-home circle { fill: var(--red); }
.map-home text { font-size: 17px; fill: var(--navy); }
.map-town:hover circle, .map-town:focus circle { fill: var(--red); }
.map-town:hover text { fill: var(--navy); text-decoration: underline; }
.town-check { background: var(--paper); border-radius: var(--r-m); padding: var(--s6); box-shadow: var(--shadow-1); }
.town-check label { display: block; font: 600 1.35rem/1.2 var(--display); color: var(--navy); margin-bottom: var(--s4); }
.town-row { display: flex; gap: var(--s2); }
.town-row input { flex: 1; min-width: 0; font: inherit; padding: var(--s3) var(--s4); border: 1.5px solid #b9c6d4; border-radius: var(--r-s); min-height: 50px; background: #fff; }
.town-row input:focus { border-color: var(--navy-600); outline: 3px solid rgb(27 65 120 / 0.18); outline-offset: 0; }
.town-result { margin: var(--s3) 0 0; font-size: 1rem; }
.town-result:empty { display: none; }
.town-result.ok { color: var(--green); }
.inline-links { list-style: none; padding: 0; margin: var(--s5) 0 0; display: flex; flex-wrap: wrap; gap: var(--s2); }
.inline-links a { display: inline-block; padding: var(--s2) var(--s4); border-radius: 999px; background: var(--paper); border: 1px solid var(--line); text-decoration: none; font-weight: 600; font-size: 0.95rem; color: var(--navy); transition: border-color var(--fast), background var(--fast); }
.inline-links a:hover { border-color: var(--navy); }
.area-list { list-style: none; padding: 0; margin: 0; display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); gap: var(--s4); }
.area-list a { display: flex; flex-direction: column; gap: var(--s1); height: 100%; padding: var(--s5); background: var(--paper); border-radius: var(--r-m); text-decoration: none; color: var(--muted); font-size: 1rem; box-shadow: var(--shadow-1); transition: transform var(--slow) var(--ease); }
.area-list strong { font: 600 1.2rem/1.2 var(--display); color: var(--navy); }
.area-list a:hover { transform: translateY(-3px); }
@media (max-width: 960px) { .map-grid { grid-template-columns: 1fr; } }

/* ---------- FAQ (editorial two-column) ---------- */
.faq .narrow { max-width: var(--wrap); display: grid; grid-template-columns: 0.8fr 1.2fr; gap: 0 var(--s8); align-items: start; }
/* The questions set the section's height; the side column (heading + question mark) fills it without adding to it
   (size containment), so the question mark scales to the list: it ends where the questions end. Long lists: it's full
   size (300 px wide) and the heading and question mark stay in view while you read. Very short lists: it's hidden
   (container query) rather than shown as a speck. */
.faq .narrow > .faq-side { grid-row: span 50; align-self: stretch; contain: size; margin-bottom: calc(var(--section) * -0.75); } /* the question mark may grow into most of the section's bottom padding: bigger, and the drop has room to fall */
.faq-side-inner { position: sticky; top: calc(var(--header-h) + 24px); height: min(100%, calc(100vh - var(--header-h) - 48px)); display: flex; flex-direction: column; }
.faq-side-inner h2 { flex: none; }
.faq-art { flex: 1 1 0; min-height: 0; margin-top: var(--s4); container-type: size; }
.faq-art-frame { position: relative; display: block; height: min(100%, 522px); width: auto; max-width: 100%; aspect-ratio: 600 / 1044; margin-left: var(--qm-x, 50%); transform: translateX(-50%); }
/* --qm-x: the centre of the heading's actual text (site.js measures its line boxes), so the question mark sits centred
   under the words, not under the wider heading box (Braidon). Without JS it's centred in the column. */
.faq-art img, .faq-art video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; object-position: center top; -webkit-mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent), linear-gradient(0deg, transparent, #000 16%, #000 94%, transparent); -webkit-mask-composite: source-in; mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent), linear-gradient(0deg, transparent, #000 16%, #000 94%, transparent); mask-composite: intersect; }
@container (max-height: 110px) { .faq-art-frame { display: none; } }
.faq .narrow > details { grid-column: 2; }
.faq details { border-top: 1px solid var(--line); }
.faq details:last-of-type { border-bottom: 1px solid var(--line); }
.faq summary { list-style: none; cursor: pointer; display: flex; justify-content: space-between; align-items: center; gap: var(--s4); padding: var(--s5) 0; }
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after { content: ''; flex: none; width: 12px; height: 12px; border-right: 2px solid var(--navy); border-bottom: 2px solid var(--navy); transform: rotate(45deg) translate(-3px, -3px); transition: transform var(--fast) var(--ease); }
.faq details[open] summary::after { transform: rotate(225deg) translate(-3px, -3px); }
.faq summary h3 { margin: 0; font-size: 1.2rem; }
.faq summary:hover h3 { color: var(--navy-600); }
.faq .answer { padding: 0 0 var(--s5); max-width: var(--measure); color: var(--muted); }
@media (max-width: 900px) { .faq .narrow { grid-template-columns: 1fr; } .faq .narrow > .faq-side { contain: none; grid-row: auto; margin-bottom: 0; } .faq-side-inner { position: static; height: auto; } .faq-side h2 { margin-bottom: var(--s5); } .faq-art { display: none; } .faq .narrow > details { grid-column: 1; } }

/* ---------- final CTA ---------- */
.cta-band { position: relative; overflow: hidden; background: var(--navy); color: #cdd8e6; padding: clamp(72px, 9vw, 120px) 0; }
/* The words and buttons on the left; the ringing red phone centred in the right half, close to them, gently floating.
   Its backdrop is the band's navy (scripts/make-live-loops.py) and the edges are feathered, so it has no box. */
.cta-row { position: relative; display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); align-items: center; gap: var(--s6) var(--s8); }
.cta-copy { display: grid; gap: var(--s6); }
.cta-phone { justify-self: center; width: clamp(280px, 30vw, 430px); margin: calc(-1 * var(--s7)) 0; transform: rotate(1.5deg); animation: cta-float 8s ease-in-out infinite alternate; }
.cta-phone { position: relative; }
.cta-phone video { position: absolute; inset: 0; height: 100%; }
.cta-phone img, .cta-phone video { display: block; width: 100%; -webkit-mask-image: linear-gradient(90deg, transparent, #000 9%, #000 91%, transparent), linear-gradient(0deg, transparent, #000 9%, #000 91%, transparent); -webkit-mask-composite: source-in; mask-image: linear-gradient(90deg, transparent, #000 9%, #000 91%, transparent), linear-gradient(0deg, transparent, #000 9%, #000 91%, transparent); mask-composite: intersect; }
@keyframes cta-float { from { transform: translateY(-6px) rotate(1deg); } to { transform: translateY(8px) rotate(2.2deg); } }
@media (max-width: 860px) {
  .cta-row { grid-template-columns: minmax(0, 1fr); }
  .cta-phone { order: -1; justify-self: start; width: min(62vw, 250px); margin: calc(-1 * var(--s6)) 0 calc(-1 * var(--s4)) calc(-1 * var(--s4)); }
}
.cta-band h2 { color: #fff; font-size: clamp(2.2rem, 1.3rem + 2.8vw, 3.6rem); margin-bottom: var(--s3); }
.cta-band h2 em { color: var(--gold); }
.cta-band p { margin: 0; max-width: 52ch; }
.cta-actions { display: flex; flex-wrap: wrap; gap: var(--s3); }
.cta-band .btn-primary { background: #fff; color: var(--navy); box-shadow: none; }
.cta-band .btn-primary:hover { background: var(--tint); }
.cta-band :focus-visible { outline-color: var(--gold); }

/* ---------- article pages ---------- */
.content-grid { display: grid; grid-template-columns: minmax(0, 1fr) 340px; gap: clamp(32px, 6vw, 96px); align-items: start; padding: var(--s8) 0; }
.sidebar { position: sticky; top: calc(var(--header-h) + 24px); display: grid; gap: var(--s4); }
@media (max-width: 960px) { .content-grid { grid-template-columns: 1fr; } .sidebar { position: static; } }
.prose { max-width: var(--measure); }
.prose h2 { margin-top: var(--s8); font-size: clamp(1.7rem, 1.2rem + 1.2vw, 2.3rem); }
.prose h3 { margin-top: var(--s5); }
.byline { font-size: 0.95rem; color: var(--muted); border-top: 1px solid var(--line); padding-top: var(--s4); margin-top: var(--s8); }
.quick { background: var(--paper); border-radius: var(--r-m); border-left: 3px solid var(--brass); padding: var(--s5) var(--s6); margin-bottom: var(--s6); box-shadow: var(--shadow-1); }
.quick-label { font: 700 0.75rem/1 var(--body); letter-spacing: 0.16em; text-transform: uppercase; color: var(--gold-small); margin-bottom: var(--s3); }
.quick p:last-child { margin: 0; font-size: 1.1rem; }
.ticks { list-style: none; padding: 0; }
.ticks li { position: relative; padding-left: 34px; margin-bottom: var(--s3); }
.ticks li::before { content: ''; position: absolute; left: 0; top: 6px; width: 20px; height: 20px; border-radius: 50%; background: var(--tint) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Cpath fill='none' stroke='%237a6224' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round' d='m5.5 10.5 3 3 6-7'/%3E%3C/svg%3E") center / 14px no-repeat; }
.steps { list-style: none; counter-reset: st; padding: 0; }
.steps li { counter-increment: st; position: relative; padding-left: 48px; margin-bottom: var(--s4); }
.steps li::before { content: counter(st); position: absolute; left: 0; top: 0; width: 32px; height: 32px; display: grid; place-items: center; border-radius: 50%; background: var(--navy); color: #fff; font: 700 0.95rem/1 var(--body); }
.link-list { padding-left: 1.2em; }
.link-list li { margin-bottom: var(--s2); }
.table-wrap { overflow-x: auto; margin: 0 0 var(--s6); border-radius: var(--r-m); background: var(--paper); box-shadow: var(--shadow-1); }
table { border-collapse: collapse; width: 100%; font-size: 1rem; }
th, td { text-align: left; padding: var(--s3) var(--s5); border-bottom: 1px solid var(--line); vertical-align: top; }
thead th { background: var(--tint); color: var(--navy); font-weight: 700; font-size: 0.9rem; letter-spacing: 0.02em; }
tbody tr:last-child > * { border-bottom: 0; }
.facts th { width: 38%; color: var(--muted); font-weight: 600; }
/* Phones: three-column tables (symptom → cause → how soon) become one card per row, the first cell as its title and the
   others under their column names (scripts/build.mjs adds data-label and the ARIA roles). Squeezed into three columns,
   "Book a visit" stacked one word to a line. */
@media (max-width: 640px) {
  table.stack thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
  table.stack, table.stack tbody, table.stack tr, table.stack td { display: block; }
  table.stack tr { padding: var(--s4) var(--s5); border-bottom: 1px solid var(--line); }
  table.stack tbody tr:last-child { border-bottom: 0; }
  table.stack td { padding: 0; border: 0; }
  table.stack td:first-child { font-weight: 600; color: var(--navy); margin-bottom: var(--s2); }
  table.stack td + td { display: grid; grid-template-columns: 6.5rem minmax(0, 1fr); gap: var(--s3); margin-top: var(--s1); color: var(--text); }
  table.stack td + td::before { content: attr(data-label); font: 700 0.7rem/1.9 var(--body); letter-spacing: 0.1em; text-transform: uppercase; color: var(--gold-small); }
}
/* the forms' spam trap: off-screen, never focused; bots fill it in, people don't */
.hp { position: absolute; left: -10000px; top: auto; width: 1px; height: 1px; overflow: hidden; }
.hp input { font-size: 16px; }
.note-box { background: var(--paper); border-radius: var(--r-m); padding: var(--s6); margin-top: var(--s6); box-shadow: var(--shadow-1); }
.note-box h2 { font-size: 1.35rem; }
.note-box p:last-child { margin: 0; }
.sidebar .note-box { margin-top: 0; font-size: 1rem; padding: var(--s5); }

/* credential card */
.cred { background: var(--paper); border-radius: var(--r-m); padding: var(--s6); box-shadow: var(--shadow-1); border-top: 3px solid var(--navy); }
.cred-label { font: 700 0.75rem/1 var(--body); letter-spacing: 0.16em; text-transform: uppercase; color: var(--gold-small); margin-bottom: var(--s3); }
.cred-name { font: 600 1.55rem/1.1 var(--display); color: var(--navy); margin-bottom: var(--s1); }
.cred-role { color: var(--muted); font-size: 0.975rem; margin-bottom: var(--s4); }
.cred-facts { list-style: none; padding: 0; margin: 0 0 var(--s5); display: grid; gap: var(--s2); font-size: 0.975rem; }
.cred-facts li { display: flex; gap: var(--s2); align-items: flex-start; }
.cred-facts svg { color: var(--gold); flex: none; margin-top: 4px; }
.cred-note { font-size: 0.875rem; color: var(--muted); margin: var(--s3) 0 0; text-align: center; }
.offer-note { background: var(--tint); border-radius: var(--r-m); padding: var(--s5); font-size: 0.975rem; }
.offer-note ul { list-style: none; padding: 0; margin: 0 0 var(--s3); display: grid; gap: var(--s2); }
.offer-note li { display: flex; gap: var(--s2); align-items: flex-start; font-weight: 600; color: var(--navy); }
.offer-note svg { color: var(--gold); flex: none; margin-top: 3px; }
.offer-note a { font-weight: 700; font-size: 0.95rem; }

/* widgets */
.widget { background: var(--paper); border-radius: var(--r-m); padding: var(--s6); margin: 0 0 var(--s7); box-shadow: var(--shadow-1); }
.widget-label { font: 700 0.75rem/1 var(--body); letter-spacing: 0.16em; text-transform: uppercase; color: var(--gold-small); margin-bottom: var(--s3); }
.widget h3 { margin-top: 0; font-size: 1.45rem; }
.widget select { font: inherit; width: 100%; min-height: 50px; padding: 0 var(--s4); border: 1.5px solid #b9c6d4; border-radius: var(--r-s); background: #fff; color: var(--text); }
.meter { position: relative; height: 12px; border-radius: 999px; margin: var(--s5) 0 var(--s6); background: linear-gradient(90deg, #cdebd9 0 53%, #fbe7b5 53% 80%, #f6d0d0 80% 100%); }
.meter-fill { position: absolute; left: 0; top: 0; bottom: 0; width: 0; border-radius: 999px; background: var(--navy); transition: width 0.7s var(--ease); }
.meter-mark { position: absolute; top: 18px; transform: translateX(-50%); font-size: 0.78rem; color: var(--muted); }
.heater-result { margin: 0; }
.heater[data-state='replace'] .meter-fill { background: var(--red); }
.freeze-days { list-style: none; padding: 0; margin: var(--s4) 0; display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--s3); }
.freeze-days li { display: flex; flex-direction: column; gap: 2px; padding: var(--s4); border-radius: var(--r-s); background: var(--tint); }
.freeze-days li.freeze-loading { grid-column: 1 / -1; color: var(--muted); }
.fz-day { font-size: 0.875rem; color: var(--muted); }
.fz-temp { font: 600 1.9rem/1.1 var(--display); color: var(--navy); }
.fz-risk { font-weight: 700; font-size: 0.875rem; }
.fz-lo .fz-risk { color: var(--green); }
.freeze-days .fz-mid { background: #fff4df; } .fz-mid .fz-risk { color: #8a4b00; }
.freeze-days .fz-hi { background: var(--red-50); } .fz-hi .fz-risk { color: var(--red-700); }
.freeze-note { font-size: 0.875rem; color: var(--muted); margin: 0; }
@media (max-width: 520px) { .freeze-days { grid-template-columns: 1fr; } }

/* jobs log */
.jobs { list-style: none; padding: 0; margin: 0; }
.jobs li { padding: var(--s4) 0; border-top: 1px solid var(--line); }
.jobs p { margin: 0; }
.job-meta { font-size: 0.875rem; font-weight: 700; color: var(--gold-small); }

/* profiles */
.profiles { margin-top: var(--s2); }
.profiles-h { font: 700 0.75rem/1 var(--body); letter-spacing: 0.16em; text-transform: uppercase; color: var(--muted); margin-bottom: var(--s3); }
.profiles ul { list-style: none; padding: 0; margin: 0; display: flex; flex-wrap: wrap; gap: var(--s2); }
.profiles a { display: inline-flex; align-items: center; gap: var(--s2); padding: var(--s3) var(--s4); border: 1px solid var(--line); border-radius: var(--r-s); background: var(--paper); text-decoration: none; color: var(--text); font-size: 0.95rem; }
.profiles a:hover { border-color: var(--navy); }
.profiles strong { color: var(--navy); }
.profiles span { color: var(--muted); }
.sidebar .profiles ul { flex-direction: column; }
.brand-icon { flex: none; }
.profiles .brand-icon { color: var(--navy); }
.brand-bbb { display: inline-grid; place-items: center; height: 18px; padding: 0 4px; border: 1.5px solid currentColor; border-radius: 3px; font: 800 0.6rem/1 var(--body); letter-spacing: 0.04em; }

/* forms */
.book-form { background: var(--paper); border-radius: var(--r-l); padding: var(--s6); display: grid; gap: var(--s5); max-width: 640px; box-shadow: var(--shadow-1); }
.field label { display: block; font-weight: 700; margin-bottom: var(--s2); font-size: 0.975rem; }
.field input, .field textarea { width: 100%; font: inherit; padding: var(--s3) var(--s4); border: 1.5px solid #b9c6d4; border-radius: var(--r-s); background: #fff; color: var(--text); min-height: 52px; transition: border-color var(--fast), box-shadow var(--fast); }
.field input:focus, .field textarea:focus { border-color: var(--navy-600); outline: none; box-shadow: 0 0 0 4px rgb(27 65 120 / 0.14); }
.field [aria-invalid='true'] { border-color: var(--red); }
.hint { font-size: 0.9rem; color: var(--muted); margin: var(--s2) 0 0; }
.optional { font-weight: 400; color: var(--muted); }
.form-status { margin: 0; font-weight: 600; }
.form-status:empty { display: none; }
.consent { display: grid; grid-template-columns: 22px 1fr; gap: var(--s3); font-size: 0.9rem; color: var(--muted); align-items: start; }
.consent input { width: 20px; height: 20px; margin: 2px 0 0; accent-color: var(--navy); }

/* reminder sign-up */
.reminder-box { display: grid; grid-template-columns: 1fr 1fr; gap: var(--s7); align-items: center; background: var(--navy-900); color: #b9c8da; border-radius: var(--r-l); padding: clamp(28px, 5vw, 56px); box-shadow: var(--shadow-2); }
.reminder-box h2 { color: #fff; font-size: clamp(1.6rem, 1.2rem + 1.2vw, 2.3rem); }
.reminder-box .eyebrow { color: var(--gold); }
.reminder-form { display: grid; gap: var(--s4); }
.reminder-form label, .reminder-form .consent { color: #cdd8e6; }
.reminder-form .hint { color: #8ea2ba; }
.reminder-form .form-status { color: #fff; }
.reminder-form .btn-primary { background: #fff; color: var(--navy); justify-self: start; box-shadow: none; }
.reminder-box :focus-visible { outline-color: var(--gold); }
@media (max-width: 860px) { .reminder-box { grid-template-columns: 1fr; gap: var(--s5); } }

/* ---------- landing page ---------- */
.lp-hero { padding: var(--s8) 0 var(--section); background: linear-gradient(180deg, var(--bg) 0%, var(--tint) 100%); }
.lp-grid { display: grid; grid-template-columns: 1.1fr 0.9fr; gap: clamp(32px, 6vw, 96px); align-items: start; }
.lp-copy h1 { font-size: clamp(2.3rem, 1.3rem + 3vw, 4rem); }
.lp-checks { list-style: none; padding: 0; margin: var(--s6) 0; display: grid; gap: var(--s4); }
.lp-checks li { display: grid; grid-template-columns: 24px 1fr; gap: var(--s3); }
.lp-checks svg { color: var(--gold); margin-top: 4px; }
.lp-checks strong { display: block; color: var(--navy); }
.lp-copy .hero-strip { border-color: var(--line); }
.lp-copy .hero-strip dd { color: var(--navy); }
.lp-copy .hero-strip dt { color: var(--muted); }
.lp-copy .hero-strip div + div { border-color: var(--line); }
.lp-form { position: sticky; top: calc(var(--header-h) + 24px); box-shadow: var(--shadow-2); }
.lp-form h2 { font-size: 1.6rem; margin: 0; }
@media (max-width: 900px) { .lp-grid { grid-template-columns: 1fr; } .lp-form { position: static; } }

/* ---------- footer ---------- */
.site-footer { background: var(--navy-900); color: #b9c8da; padding: var(--s9) 0 var(--s5); font-size: 0.975rem; }
.site-footer a { color: #fff; }
.footer-grid { display: grid; grid-template-columns: 1.5fr 1fr 1fr 0.9fr; gap: var(--s7); }
.footer-logo { display: block; }
.footer-logo img { width: min(100%, 340px); height: auto; } /* the full sign, as wide as the column's text: KINGSTON reads */
.site-footer h2 { font: 700 0.75rem/1 var(--body); letter-spacing: 0.16em; text-transform: uppercase; color: var(--gold); margin-bottom: var(--s5); }
.site-footer ul { list-style: none; padding: 0; margin: 0; display: grid; gap: var(--s2); }
.site-footer ul a { color: #dfe7f1; text-decoration: none; }
.site-footer ul a:hover { color: #fff; text-decoration: underline; }
.footer-nap p { margin-top: var(--s5); max-width: 340px; }
/* the brand column matches the link columns: the promise in two lines (every area is linked under Service areas), the
   name, address, phone and email in four, and its links styled like the rest of the footer's */
.footer-nap .nap { line-height: 1.75; }
.footer-nap .nap strong { color: #fff; font-weight: 600; }
.footer-nap .nap a { color: #dfe7f1; text-decoration: none; }
.footer-nap .nap a:hover { color: #fff; text-decoration: underline; }
.footer-profiles { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s4); margin-top: var(--s8); padding-top: var(--s5); border-top: 1px solid rgb(255 255 255 / 0.1); }
.footer-profiles p { margin: 0; font: 700 0.75rem/1 var(--body); letter-spacing: 0.16em; text-transform: uppercase; color: #8ea2ba; }
.footer-profiles ul { display: flex; flex-wrap: wrap; gap: var(--s3); }
.footer-profiles a { display: inline-flex; align-items: center; gap: var(--s2); padding: var(--s2) var(--s4); border: 1px solid rgb(255 255 255 / 0.18); border-radius: 999px; color: #fff; text-decoration: none; font-weight: 700; font-size: 0.925rem; transition: border-color var(--fast), background var(--fast); }
.footer-profiles a:hover { border-color: #fff; background: rgb(255 255 255 / 0.05); }
.footer-profiles span { color: #aebdd0; font-weight: 400; }
.footer-profiles .brand-icon { color: #fff; }
.footer-base { margin-top: var(--s5); font-size: 0.875rem; color: #8ea2ba; display: flex; flex-wrap: wrap; justify-content: space-between; align-items: baseline; gap: 0 var(--s5); }
.footer-credit a { color: inherit; text-decoration: underline; text-underline-offset: 3px; display: inline-block; padding: 12px 0; }
.footer-credit a:hover { color: var(--paper); }
.site-footer.bare { padding: var(--s6) 0; }
.site-footer :focus-visible { outline-color: var(--gold); }
@media (max-width: 900px) { .footer-grid { grid-template-columns: 1fr 1fr; } }
@media (max-width: 520px) { .footer-grid { grid-template-columns: 1fr; } }

/* ---------- mobile call bar ---------- */
.callbar { display: none; }
@media (max-width: 800px) {
  .callbar { display: grid; grid-template-columns: 1fr 1fr; gap: var(--s2); position: fixed; left: 0; right: 0; bottom: 0; z-index: 60; padding: var(--s2) var(--s3) calc(var(--s2) + env(safe-area-inset-bottom)); background: rgb(253 253 252 / 0.97); border-top: 1px solid var(--line); box-shadow: 0 -12px 30px -20px rgb(9 26 51 / 0.4); }
  body { padding-bottom: 74px; }
}

/* ---------- review mode (only with ?review) ---------- */
.draft-banner { background: var(--amber-50); color: var(--amber); border: 1px solid #ecd48a; border-radius: var(--r-s); padding: var(--s3) var(--s4); font-weight: 600; margin-top: var(--s4); }
body.show-verify .verify { background: var(--amber-50); outline: 2px dashed var(--amber); outline-offset: 2px; cursor: help; }
body.show-verify .verify:empty::before { content: '[needs detail]'; color: var(--amber); font-weight: 700; }
.review-toggle { position: fixed; right: var(--s4); bottom: var(--s4); z-index: 70; background: var(--amber-50); color: var(--amber); border: 1.5px solid #ecd48a; border-radius: 999px; padding: var(--s2) var(--s4); font: 700 0.875rem var(--body); cursor: pointer; }
@media (max-width: 800px) { .review-toggle { bottom: 86px; } }

/* ---------- motion ---------- */
/* Page to page: a soft cross-fade instead of a white flash, with the header held in place (Chrome, Edge, Safari 18.2+;
   other browsers just navigate). Off for reduced motion. */
@media (prefers-reduced-motion: no-preference) {
  @view-transition { navigation: auto; }
  .site-header { view-transition-name: site-header; }
  ::view-transition-old(root), ::view-transition-new(root) { animation-duration: 0.28s; animation-timing-function: var(--ease); }
}
.js-reveal .reveal { opacity: 0; transform: translateY(22px); transition: opacity 0.8s var(--ease), transform 0.8s var(--ease); }
.js-reveal .reveal.in { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation: none !important; transition: none !important; }
  .js-reveal .reveal { opacity: 1; transform: none; }
}
.widget .widget-title { margin-top: 0; font-size: 1.45rem; }
[hidden] { display: none !important; }
.site-header.bare .header-actions { margin-left: auto; }
.lp-copy .hero-strip { grid-template-columns: 1fr 1fr; row-gap: var(--s5); }
.lp-copy .hero-strip div:nth-child(3) { padding-left: 0; border-left: 0; }
.cutaway .wrap { width: min(100% - 2 * var(--s5), 1440px); }
.cut-layout { grid-template-columns: minmax(0, 1fr) 360px; }
@media (max-width: 960px) { .cut-layout { grid-template-columns: 1fr; } }

/* ---------- hero film (v4) ---------- */
/* --film-bg matches the film's studio backdrop, so the hero, the house guide below it and the frame edges read as one space. */
:root { --film-bg: #0a1528; --topbar-h: 0px; }
html.has-topbar { --topbar-h: 38px; }
/* Scroll lengths match site.js: the stage (one screen), the opening (0.6 of a screen) and a hold (to 0.75). Merged
   with the house guide: its settling and a hold (to 1), then one more screen for the next section to slide over. */
.film { position: relative; height: 175vh; background: var(--film-bg); color: #fff; }
.film.merged { height: 300vh; }
/* The header is --header-h plus its 1px bottom border (clear here), so the film comes up that 1px further. */
.page-home .film { margin-top: calc(-1 * var(--header-h) - 1px); }
/* Desktop: the film also runs up behind the seasonal bar, so the hero reaches the top edge with no seam. */
@media (min-width: 801px) {
  .page-home .topbar { background-color: transparent; transition: background-color 0.35s var(--ease); }
  .is-scrolled .page-home .topbar { background-color: var(--navy-900); }
  .page-home .film { margin-top: calc(-1 * (var(--header-h) + var(--topbar-h)) - 1px); }
  .page-home .film-inner { padding-top: calc(var(--header-h) + var(--topbar-h) + var(--s5) + var(--logo-hang)); }
}
/* The stage is the viewport minus the top bar, so nothing is cut off at load; once pinned the difference is backdrop. */
.film-sticky { position: sticky; top: 0; height: calc(100vh - var(--topbar-h)); height: calc(100svh - var(--topbar-h)); min-height: 620px; overflow: hidden; display: grid; grid-template-rows: 1fr auto; isolation: isolate; }
.film-media { position: absolute; inset: 0; z-index: -2; overflow: hidden; background: var(--film-edge, var(--film-bg)); }
.film-poster, .film-canvas { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: 62% 50%; }
.film-canvas { z-index: -2; opacity: 0; transition: opacity 0.5s var(--ease); }
.film.ready .film-canvas { opacity: 1; }
/* Desktop with motion: the canvas draws the closed house in its real place from the start (site.js), so the
   cover-cropped poster under it is never shown; it stays for phones, reduced motion and no-JS. */
@media (min-width: 801px) and (prefers-reduced-motion: no-preference) { html.js .film-poster { visibility: hidden; } }
/* No JavaScript, or reduced motion, on wide screens: the still sits right of the words, as the film's first frame does,
   never under them. */
@media (min-width: 1000px) {
  html:not(.js) .film-poster, .film.static .film-poster { left: auto; right: 2%; width: 58%; object-fit: contain; object-position: right center; }
}
.film-video { display: none; }
.film-clip, .film-clip-rev { position: absolute; width: 1px; height: 1px; opacity: 0.01; pointer-events: none; }
.film-shade { position: absolute; inset: 0; z-index: -1; pointer-events: none; background:
  linear-gradient(180deg, rgb(10 21 40 / 0.6) 0%, rgb(10 21 40 / 0) 20%),
  linear-gradient(90deg, rgb(10 21 40 / calc(0.9 - var(--f, 0) * 0.5)) 0%, rgb(10 21 40 / calc(0.66 - var(--f, 0) * 0.55)) 38%, rgb(10 21 40 / 0) 60%),
  linear-gradient(0deg, rgb(10 21 40 / 0.88) 0%, rgb(10 21 40 / 0) 30%); }
.film-inner { align-self: center; padding: calc(var(--header-h) + var(--s5)) 0 var(--s5); opacity: calc(1 - var(--f, 0) * 5); transform: translateY(calc(var(--f, 0) * -120px)); transition: opacity 0.2s linear; }
.film-inner h1 { color: #fff; max-width: 19ch; font-size: clamp(2.5rem, 1.2rem + 3.6vw, 4.5rem); }
.film-inner h1 em { color: var(--gold); display: block; }
.film-inner .eyebrow { color: var(--gold); }
.film-inner .lede { color: #d5deea; max-width: 44ch; }
.film-inner .actions { margin-bottom: var(--s4); }
/* The scroll cue, in the bottom bar above the proof strip, so it stays on screen while the words fade. "Scroll to look
   inside" at the top, then "Keep scrolling" and a line that fills as you go (site.js: .going, --q). When the line is
   full, the stage moves on. Blind testers (2026-10-06) weren't sure whether to keep scrolling once the house moved. */
.film-cue { display: flex; align-items: center; gap: var(--s3); margin: 0 0 var(--s4); font: 700 0.78rem/1 var(--body); letter-spacing: 0.16em; text-transform: uppercase; color: rgb(255 255 255 / 0.88); text-shadow: 0 1px 10px rgb(10 21 40 / 0.9); }
.cue-line { flex: none; width: 1.5px; height: 28px; background: linear-gradient(var(--gold), rgb(173 132 42 / 0)); transform-origin: top; animation: cue 2.4s var(--ease) infinite; }
@keyframes cue { 0% { transform: scaleY(0); opacity: 1; } 55% { transform: scaleY(1); opacity: 1; } 100% { transform: scaleY(1); opacity: 0; } }
.cue-words { position: relative; } /* as wide as the words showing, so the line follows them */
.cue-words > span { display: block; white-space: nowrap; transition: opacity 0.3s var(--ease); }
.cue-words > span + span, .film.going .cue-words > span:first-child { position: absolute; left: 0; top: 0; opacity: 0; }
.film.going .cue-words > span + span { position: static; opacity: 1; }
.cue-track { flex: none; width: 96px; height: 2px; border-radius: 1px; background: rgb(255 255 255 / 0.22); overflow: hidden; opacity: 0; transition: opacity 0.3s var(--ease); }
.cue-fill { display: block; height: 100%; background: var(--gold); transform: scaleX(var(--q, 0)); transform-origin: left; }
.film.going .cue-track { opacity: 1; }
/* Captions that build up as the house opens: the line stays, then the button joins it. They sit just above the
   bottom bar (--foot-h, from site.js). */
.film-steps { position: absolute; left: 0; right: 0; bottom: calc(var(--foot-h, 170px) + var(--s4)); display: flex; flex-direction: column; align-items: flex-start; gap: var(--s5); pointer-events: none; }
.film-step { margin: 0; max-width: 24ch; font: italic 600 clamp(1.6rem, 1rem + 1.6vw, 2.5rem)/1.2 var(--display); color: #fff; opacity: 0; transform: translateY(16px); transition: opacity 0.6s var(--ease), transform 0.6s var(--ease); text-shadow: 0 2px 24px rgb(10 21 40 / 0.85); }
.film-step em { color: var(--gold); }
.film-step.on { opacity: 1; transform: none; pointer-events: auto; }
.film-go { background: #fff; color: var(--navy); font-style: normal; text-shadow: none; box-shadow: 0 16px 32px -16px rgb(0 0 0 / 0.6); }
.film-go:hover { background: var(--gold); color: var(--navy-900); }
.film-go svg { transform: rotate(90deg); transition: transform var(--fast) var(--ease); }
.film-go:hover svg { transform: rotate(90deg) translateX(3px); }
.film .hero-foot { padding-bottom: var(--s6); }
.film:not(.static) .hero-note { bottom: var(--s2); }

/* Phones and reduced motion: no scrubbing. Done in CSS (not the .static class) so the very first paint already has the
   final layout; otherwise the image is first laid out full-screen, Chrome files it as a background, and LCP skips it. */
@media (min-width: 801px) and (prefers-reduced-motion: no-preference) {
  .page-home .film-sticky { height: 100vh; height: 100svh; }
}
@media (prefers-reduced-motion: reduce), (max-width: 800px) {
  .film { height: auto; }
  .film-sticky { position: relative; height: auto; min-height: min(92vh, 860px); min-height: min(92svh, 860px); }
  .film-canvas, .film-steps, .film-cue { display: none; }
  .film-inner { opacity: 1; transform: none; }
}

/* phones: the house gets its own band under the header (a cropped clip that plays once), the words sit below it on the backdrop */
@media (max-width: 800px) {
  .film-sticky { min-height: 0; grid-template-rows: auto auto auto; }
  .film-media { position: relative; inset: auto; z-index: 0; margin-top: var(--header-h); aspect-ratio: 720 / 548; }
  .film-media::after { content: ''; position: absolute; left: 0; right: 0; bottom: 0; height: 26%; background: linear-gradient(rgb(10 21 40 / 0), var(--film-bg)); pointer-events: none; }
  /* and in from the top: the clip's own studio (whole roof, chimney pots) meets the page with no edge */
  .film-media::before { content: ''; position: absolute; left: 0; right: 0; top: 0; height: 8%; z-index: 1; background: linear-gradient(var(--film-bg), rgb(10 21 40 / 0)); pointer-events: none; }
  .film-poster { object-position: 50% 50%; }
  .film-video { display: block; position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; opacity: 0; transition: opacity 0.35s var(--ease); }
  .film.playing .film-video { opacity: 1; }
  .film-shade { display: none; }
  .film-inner { padding: var(--s3) 0 var(--s5); }
  .film .hero-note { top: calc(var(--header-h) + 100vw * 548 / 720 - 26px); bottom: auto; right: var(--s3); }
}

/* ---------- house guide on the film's last frame (v4) ---------- */
.cutaway { background: var(--film-bg); color: #b9c8da; padding-top: var(--s9); }
.cutaway .section-head h2 { color: #fff; }
.cutaway .section-head h2 em { color: var(--gold); }
.cutaway .eyebrow { color: var(--gold); }
.cutaway .section-head p:not(.eyebrow) { color: #aebdd0; }
.cutaway .img-note { color: #8ea2ba; }
.cutaway :focus-visible { outline-color: var(--gold); }
/* feather the photo's edges into the backdrop so it has no visible frame */
.cutaway .cut-img { -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 5%, #000 95%, transparent 100%), linear-gradient(180deg, transparent 0, #000 4%, #000 93%, transparent 100%); -webkit-mask-composite: source-in; mask-image: linear-gradient(90deg, transparent 0, #000 5%, #000 95%, transparent 100%), linear-gradient(180deg, transparent 0, #000 4%, #000 93%, transparent 100%); mask-composite: intersect; }
.cutaway .spot { background: #fff; color: var(--navy); box-shadow: 0 0 0 3px rgb(10 21 40 / 0.45), 0 8px 18px -6px rgb(0 0 0 / 0.7); }
.cutaway .spot::after { border-color: var(--gold); }
.cutaway .spot.active { background: var(--red); color: #fff; }
.cutaway .spot.active::after { border-color: var(--red); }
.cutaway .cut-layout.has-active .spot:not(.active) { opacity: 0.6; }
@keyframes pin-in { from { opacity: 0; transform: translateY(-12px) scale(0.4); } }
.js-reveal .cut-layout:not(.pins-in) .spot { opacity: 0; }
.cut-layout.pins-in .spot { animation: pin-in 0.55s var(--ease) backwards; animation-delay: calc(var(--i, 0) * 55ms + 150ms); }
.cut-panel { box-shadow: 0 30px 60px -30px rgb(0 0 0 / 0.7); }

/* ---------- inner-page heroes: the same proof strip as the home hero, on light ---------- */
.page-hero .hero-strip { margin-top: var(--s6); border-color: var(--line); padding-top: var(--s4); }
.page-hero .hero-strip div { padding-right: var(--s4); }
.page-hero .hero-strip div + div { padding-left: var(--s4); border-color: var(--line); }
.page-hero .hero-strip dd { color: var(--navy); font-size: clamp(1.3rem, 1rem + 0.8vw, 1.75rem); }
.page-hero .hero-strip dt { color: var(--muted); font-size: 0.8rem; }
@media (max-width: 800px) { .page-hero .hero-strip div:nth-child(3) { padding-left: 0; border-left: 0; } }

/* service pages: where we work, as one row of links */
.section-tight { padding: var(--s8) 0; }
.area-row { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--s4) var(--s6); }
.area-row h2 { margin: 0; font-size: clamp(1.5rem, 1.2rem + 0.8vw, 2rem); }
.area-row .inline-links { margin: 0; }

/* contact: what happens after you press send */
.next-steps { list-style: none; counter-reset: ns; padding: 0; margin: var(--s6) 0 0; display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--s5); }
.next-steps li { counter-increment: ns; display: grid; grid-template-columns: 32px 1fr; column-gap: var(--s3); align-items: start; }
.next-steps li::before { content: counter(ns); grid-row: span 2; width: 32px; height: 32px; border-radius: 50%; display: grid; place-items: center; background: var(--navy); color: #fff; font: 700 0.9rem/1 var(--body); }
.next-steps strong { color: var(--navy); font-size: 1rem; line-height: 1.4; }
.next-steps span { color: var(--muted); font-size: 0.925rem; line-height: 1.45; }
@media (max-width: 700px) { .next-steps { grid-template-columns: 1fr; gap: var(--s4); } }

/* phones: grid columns may never be wider than the screen (a table or the map was widening the whole page) */
.content-grid > *, .map-grid > *, .cut-layout > * { min-width: 0; }
@media (max-width: 960px) { .content-grid, .map-grid, .cut-layout { grid-template-columns: minmax(0, 1fr); } }

/* ---------- recent work: real job photos from the Google Business Profile ---------- */
.work-grid { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(4, 1fr); grid-auto-rows: clamp(220px, 22vw, 320px); gap: var(--s4); }
.work-item.wide { grid-column: span 2; }
.work-item a { position: relative; display: block; height: 100%; border-radius: var(--r-m); overflow: hidden; background: var(--tint); box-shadow: var(--shadow-1); }
.work-item img { width: 100%; height: 100%; object-fit: cover; transition: transform 1.2s var(--ease); }
.work-item a:hover img { transform: scale(1.04); }
.work-cap { position: absolute; left: 0; right: 0; bottom: 0; padding: var(--s7) var(--s4) var(--s3); font: 600 0.9rem/1.35 var(--body); color: #fff; background: linear-gradient(rgb(10 21 40 / 0), rgb(10 21 40 / 0.85)); }
.work-more { margin: var(--s5) 0 0; }
@media (max-width: 900px) { .work-grid { grid-template-columns: repeat(2, 1fr); grid-auto-rows: clamp(190px, 46vw, 300px); gap: var(--s3); } .work-cap { font-size: 0.82rem; padding: var(--s6) var(--s3) var(--s2); } }
.promise-media { margin: 0; }
.photo-tag { position: absolute; left: var(--s4); bottom: var(--s4); margin: 0; padding: var(--s1) var(--s3); border-radius: 999px; background: rgb(10 21 40 / 0.72); color: #fff; font: 600 0.78rem/1.4 var(--body); }

/* photo viewer (site.js builds the <dialog> on first open) */
.lightbox { border: 0; padding: 0; background: transparent; max-width: min(94vw, 1200px); max-height: 94vh; overflow: visible; color: #fff; }
.lightbox::backdrop { background: rgb(10 21 40 / 0.92); }
.lightbox figure { margin: 0; display: grid; gap: var(--s3); justify-items: center; }
.lightbox img { max-width: min(94vw, 1200px); max-height: 82vh; width: auto; height: auto; border-radius: var(--r-s); }
.lightbox figcaption { font: 600 1rem/1.4 var(--body); color: #dfe7f1; text-align: center; }
.lb-btn { position: fixed; top: 50%; transform: translateY(-50%); width: 52px; height: 52px; border-radius: 50%; border: 0; background: rgb(255 255 255 / 0.12); color: #fff; font: 400 1.8rem/1 var(--body); cursor: pointer; display: grid; place-items: center; transition: background var(--fast); }
.lb-btn:hover { background: rgb(255 255 255 / 0.25); }
.lb-prev { left: var(--s4); }
.lb-next { right: var(--s4); }
.lb-close { top: var(--s5); right: var(--s4); transform: none; }
.lightbox :focus-visible { outline-color: var(--gold); }
/* phones: illustrations stay hidden in service heroes, but Conor's real job photos show under the buttons */
@media (max-width: 900px) { .page-hero .hero-photo.is-job { display: block; } .page-hero .hero-photo.is-job img { aspect-ratio: 4 / 3; } }

/* ---------- final audit ---------- */
.faq-more { margin: var(--s5) 0 0; }
.rv-attrib a { color: var(--navy-600); }
@media (max-width: 800px) {
  .text-link { padding: 7px 0; }                 /* 44px tall tap targets */
  .crumbs ol { gap: var(--s3); }
  .crumbs a, .crumbs span { display: inline-block; padding: 6px 0; }
}

/* area cards: image-led, same system as the service cards */
.area-list { grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: var(--s5); }
.area-list .area-card a { padding: 0; overflow: hidden; gap: 0; }
.area-media { display: block; aspect-ratio: 16 / 10; overflow: hidden; background: var(--tint); }
.area-media img { width: 100%; height: 100%; object-fit: cover; transition: transform 1.2s var(--ease); }
.area-card a:hover .area-media img { transform: scale(1.05); }
.area-body { display: flex; flex-direction: column; gap: var(--s1); padding: var(--s4) var(--s5) var(--s5); }
@media (max-width: 640px) {
  .area-list { display: flex; overflow-x: auto; scroll-snap-type: x mandatory; gap: var(--s4); margin: 0 calc(-1 * var(--s5)); padding: var(--s2) var(--s5) var(--s5); scroll-padding-inline: var(--s5); scrollbar-width: none; }
  .area-list::-webkit-scrollbar { display: none; }
  .area-list > li { flex: 0 0 76%; scroll-snap-align: start; }
}
@media (max-width: 480px) { .town-row { flex-wrap: wrap; } .town-row .btn { flex: 1 1 100%; } }

/* Without JavaScript (html lacks .js, set inline in <head>) the hero is a normal-height still and nothing promises a scroll effect. */
html:not(.js) .film { height: auto; }
html:not(.js) .film-sticky { position: relative; height: auto; min-height: min(92vh, 860px); }
html:not(.js) .film-cue, html:not(.js) .film-steps { display: none; }

/* ---------- the house guide on the film's last frame (desktop, merged by site.js) ---------- */
.film-guide { position: absolute; inset: 0; z-index: 2; pointer-events: none; }
.film-pins { position: absolute; inset: 0; }
.film-guide .spot { position: absolute; margin: -15px 0 0 -15px; pointer-events: auto; opacity: 0; background: #fff; color: var(--navy); box-shadow: 0 0 0 3px rgb(10 21 40 / 0.45), 0 8px 18px -6px rgb(0 0 0 / 0.7); }
.film-guide .spot::after { border-color: var(--gold); }
.film-guide .spot.active { background: var(--red); color: #fff; }
.film-guide .spot.active::after { border-color: var(--red); }
.film-guide.on .spot { opacity: 1; animation: pin-in 0.55s var(--ease) backwards; animation-delay: calc(var(--i, 0) * 45ms + 120ms); }
.film-guide.on.has-active .spot:not(.active) { opacity: 0.6; }
/* the panel comes in with the scroll, in the second half, once the house has slid left out of its way (--g, from site.js) */
.film-guide .cut-panel { pointer-events: auto; position: absolute; right: max(var(--s5), calc((100% - var(--wrap)) / 2)); top: 50%; width: 360px; height: min(62vh, 580px); min-height: 0; transform: translate(calc((1 - var(--g, 0)) * 56px), -50%); opacity: calc(var(--g, 0) * 2.2 - 1.2); }
.cutaway.merged { display: none; }
/* the page continues out of the dark stage through a short fade, not a hard edge */
/* The film into the page: an eased fade (the navy holds, then clears quickly), not a straight blend through flat grey. */
.page-home .svc-section { background: linear-gradient(180deg, var(--film-bg) 0, rgb(10 21 40 / 0.86) 26px, rgb(84 97 117) 62px, rgb(205 210 217) 96px, var(--bg) 128px); padding-top: calc(var(--section) + 80px); }
/* Desktop with the guide merged: the next section slides up over the pinned stage like a sheet (the film's last
   screen), so the stage never lurches away; scrolling back up slides it down again. */
.film.merged ~ .svc-section { position: relative; z-index: 3; margin-top: -100vh; padding-top: var(--section); background: var(--bg); border-radius: calc(var(--r-l) + 6px) calc(var(--r-l) + 6px) 0 0; box-shadow: 0 -20px 44px -24px rgb(0 0 0 / 0.65); }
/* Short laptop screens (1366 x 768 and the like): the first screen still holds the words, the buttons and the proof
   strip. The headline scales with the height as well as the width, and the scroll cue moves to the end of the strip's
   row instead of taking a row of its own. */
@media (min-width: 801px) and (max-height: 780px) and (prefers-reduced-motion: no-preference) {
  .film-inner h1 { font-size: max(2.25rem, min(1.2rem + 3.6vw, 0.6rem + 6.8vh)); }
  .page-home .film-inner { padding-top: calc(var(--header-h) + var(--topbar-h) + var(--s3) + var(--logo-hang)); padding-bottom: var(--s3); }
  .film .hero-foot { display: grid; grid-template-columns: minmax(0, 1fr) auto; padding-bottom: var(--s4); }
  .film .hero-foot .film-cue { grid-column: 2; grid-row: 1; margin: 0; padding: var(--s4) 0 0 var(--s5); border-top: 1px solid rgb(255 255 255 / 0.18); }
  .film .hero-strip { padding-top: var(--s4); }
  .film .hero-strip dd { font-size: 1.5rem; }
}

/* header: call and book side by side on wide screens */
.header-book { display: none; }
@media (min-width: 1280px) { .header-book { display: inline-flex; min-height: 46px; padding: 0 var(--s4); transition-duration: 0.35s; } } /* fades with the header (clear → white) */
.site-header.is-over:not(.is-solid) .header-book { color: #fff; border-color: rgb(255 255 255 / 0.5); }
.site-header.is-over:not(.is-solid) .header-book:hover { background: rgb(255 255 255 / 0.1); border-color: #fff; }
.cred-book { text-align: center; margin: var(--s3) 0 0; font-size: 0.95rem; }
.actions .actions-sms { align-self: center; min-height: 44px; padding: 0 var(--s2); }
/* on the dark hero the text link goes white, like the words around it */
.film .actions-sms, .hero-cine .actions-sms, .cta-band .actions-sms { color: #fff; }
.film .actions-sms:hover, .hero-cine .actions-sms:hover, .cta-band .actions-sms:hover { color: var(--gold); }

/* ---------- proof from counted reviews ---------- */
.promise-list li::before { grid-row: span 3; }
.promise-list .proof { grid-column: 2; }
.promise-list .proof, .vs-proof li { display: flex; align-items: baseline; gap: var(--s2); margin-top: var(--s2); font: 600 0.85rem/1.4 var(--body); color: var(--gold-small); }
.promise-list .proof::before, .vs-proof li::before { content: '★'; font-size: 0.8em; }
.counted { list-style: none; padding: 0; margin: var(--s5) 0; display: grid; grid-template-columns: repeat(2, 1fr); gap: 0 var(--s6); }
.counted li { display: grid; grid-template-columns: 56px 1fr; align-items: baseline; gap: var(--s3); padding: var(--s3) 0; border-top: 1px solid var(--line); margin: 0; }
.counted strong { font: 600 1.9rem/1 var(--display); color: var(--navy); }
.counted span { color: var(--muted); font-size: 1rem; }
@media (max-width: 640px) { .counted { grid-template-columns: 1fr; } }

/* ---------- /why-shea-plumbing/: the complaint on the left, the answer and its proof on the right ---------- */
.vs-list { list-style: none; counter-reset: vs; padding: 0; margin: 0 0 var(--s5); }
.vs-item { counter-increment: vs; display: grid; grid-template-columns: 52px 1fr 1fr; gap: var(--s4) var(--s7); padding: var(--s6) 0; border-top: 1px solid var(--line); }
.vs-item::before { content: counter(vs, decimal-leading-zero); font: italic 600 1.5rem/1.3 var(--display); color: var(--gold); }
.vs-problem h3 { font-size: 1.35rem; margin-bottom: var(--s2); }
.vs-problem p { color: var(--muted); font-size: 0.975rem; margin: 0; }
.vs-answer { background: var(--paper); border-radius: var(--r-m); padding: var(--s5); box-shadow: var(--shadow-1); border-left: 3px solid var(--brass); align-self: start; }
.vs-answer p { margin: 0; }
.vs-answer .vs-label { font: 700 0.72rem/1 var(--body); letter-spacing: 0.16em; text-transform: uppercase; color: var(--gold-small); margin-bottom: var(--s2); }
.vs-proof { list-style: none; padding: 0; margin: var(--s3) 0 0; }
@media (max-width: 860px) { .vs-item { grid-template-columns: 36px 1fr; gap: var(--s3) var(--s3); } .vs-answer { grid-column: 2; } }

/* the price promise on service and area pages */
.price-note { background: var(--navy-900); color: #cdd8e6; border-radius: var(--r-m); padding: var(--s5) var(--s6); margin: var(--s7) 0 0; box-shadow: var(--shadow-1); }
.price-note .quick-label { color: var(--gold); }
.price-note p { margin: 0 0 var(--s3); }
.price-note p:nth-child(2) { color: #fff; font-size: 1.1rem; }
.price-note .price-proof { margin: 0; font-size: 0.9rem; color: var(--gold); }
.price-note a { color: #fff; }

/* customers' own words for honest, reliable, professional (business.reviews[].mark) */
.rv-text mark { color: inherit; background: linear-gradient(transparent 58%, rgb(173 132 42 / .32) 58%); padding: 0 .08em; }

/* job photo galleries: fill holes left by wide photos on phones; Conor's own caption on its own line */
.work-grid { grid-auto-flow: row dense; }
.work-cap q { display: block; margin-top: 2px; font: italic 600 0.95em/1.35 var(--display); color: var(--gold); quotes: '“' '”'; }
.work-cap q::after { content: '” Conor'; font: 600 0.8em var(--body); font-style: normal; color: #cdd8e6; }

/* problem finder: every option the same size, whatever its label length */
.finder-options { grid-auto-rows: 1fr; }
.finder-options > li { display: flex; }
.finder-opt { flex: 1; }

/* service cards: one card style everywhere, and every row full. All ten services = two rows of five
   (serviceCards adds .cols-5); three related services = one row of three. */
.svc-grid.cols-5 { grid-template-columns: repeat(5, minmax(0, 1fr)); gap: var(--s4); }
.svc-grid.cols-5 .svc-body { padding: var(--s4); }
.svc-grid.cols-5 .svc-title { font-size: 1.12rem; min-height: 2.4em; }
.svc-grid.cols-5 .svc-desc { font-size: 0.92rem; }
@media (min-width: 641px) and (max-width: 1199px) {
  .svc-grid.cols-5 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .svc-grid.cols-5 a { flex-direction: row; }
  .svc-grid.cols-5 .svc-media { flex: 0 0 38%; aspect-ratio: auto; min-height: 170px; }
  .svc-grid.cols-5 .svc-title { min-height: 0; }
}
@media (min-width: 641px) and (max-width: 1000px) { .svc-grid:not(.cols-5) { gap: var(--s4); } .svc-grid:not(.cols-5) .svc-body { padding: var(--s4); } }

/* proof strip: numbers share one top line, whatever their labels do */
.hero-strip div { justify-content: flex-end; }

/* "Your plumber" card: a face beside the name */
.cred-head { display: flex; align-items: center; gap: var(--s4); }
.cred-head > div { min-width: 0; }
.cred-face { display: block; width: 64px; height: 64px; border-radius: 50%; object-fit: cover; box-shadow: 0 0 0 3px var(--paper), 0 0 0 4px var(--line); }
/* all ten service cards: every row the same height */
.svc-grid.cols-5 { grid-auto-rows: 1fr; }

/* review arrows hang 26px outside the rail, but never past the page edge (they caused a 2px sideways scroll at ~950px) */
.rv-prev { left: calc(-1 * min(26px, (100vw - 100%) / 2 - 16px)); }
.rv-next { right: calc(-1 * min(26px, (100vw - 100%) / 2 - 16px)); }

/* service-area map: OpenStreetMap base image (scripts/make-map.py) with the SVG labels on top */
.area-map .map-frame { position: relative; aspect-ratio: 8 / 5; border-radius: var(--r-l); overflow: hidden; box-shadow: var(--shadow-1); background: #e2e5e0; }
.area-map .map-frame img, .area-map .map-frame svg { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
.area-map svg { border-radius: 0; box-shadow: none; background: none; }
.area-map figcaption a { color: inherit; }
.map-water { font: italic 600 16px var(--display); fill: #3c739a; letter-spacing: 0.08em; }
.map-region { font: 600 10.5px var(--body); fill: #8a9097; letter-spacing: 0.14em; text-transform: uppercase; }
.map-island text { font: italic 600 14px var(--display); fill: #46647b; paint-order: stroke; stroke: #fbf8f1; stroke-width: 3px; }
.map-island:hover text, .map-island:focus text { fill: var(--navy); text-decoration: underline; }
.map-town text { font: 700 15px var(--body); stroke: #fbf8f1; stroke-width: 4px; }
.map-home text { font: 700 19px var(--display); }
.map-shield rect { fill: #fff; stroke: #97a1ad; stroke-width: 1.2; }
.map-shield text { font: 700 10px var(--body); fill: #4a5563; }
.map-shield.is-401 rect { fill: #1b4178; stroke: #fff; }
.map-shield.is-401 text { fill: #fff; }
.map-scale rect, .map-key rect { fill: rgb(255 255 255 / 0.88); }
.map-scale path { fill: none; stroke: var(--navy); stroke-width: 1.5; }
.map-scale text, .map-key text { font: 600 10.5px var(--body); fill: var(--navy); }
.map-key .map-key-swatch { fill: #fbf8f1; stroke: #b8913a; stroke-width: 1.5; }
/* phones: the 800-wide drawing shrinks to under half, so fewer, bigger labels */
@media (max-width: 600px) {
  .map-town text { font-size: 21px; stroke-width: 5px; }
  .map-home text { font-size: 25px; }
  .map-town.minor text, .map-region, .map-shield:not(.is-401) { display: none; }
  .map-town circle { r: 7px; }
  .map-home circle { r: 10px; }
  .map-island text { font-size: 18px; stroke-width: 4px; }
  .map-water { font-size: 20px; }
  .map-scale text, .map-key text { font-size: 15px; }
}

/* Kingston neighbourhoods, by part of the city */
.hood-list { list-style: none; padding: 0; margin: 0 0 var(--s5); display: grid; gap: var(--s3); }
.map-island circle { fill: var(--navy); }
.map-island text { font: italic 600 14px var(--display); fill: #46647b; }
@media (max-width: 600px) { .map-island text { font-size: 18px; } .map-island circle { r: 7px; } }

/* area pages without their own illustration yet: a text-led hero, and a signpost card of the villages */
.page-hero-text .hero-copy { max-width: 760px; }
.area-sign { display: grid; place-items: center; background: linear-gradient(160deg, var(--navy-900), #1b4178); color: var(--gold); text-align: center; padding: var(--s4); }
.area-sign span { font: italic 600 1.05rem/1.55 var(--display); letter-spacing: 0.01em; }
/* map: arrows to the areas north of the frame */
.map-beyond rect { fill: rgb(255 255 255 / 0.92); stroke: #b8913a; stroke-width: 1.2; }
.map-beyond path { fill: var(--navy); }
.map-beyond text { font: 700 12px var(--body); fill: var(--navy); }
.map-beyond .map-beyond-sub { font: 500 9.5px var(--body); fill: var(--muted); }
.map-beyond:hover rect, .map-beyond:focus rect { stroke: var(--navy); }
@media (max-width: 600px) { .map-beyond-sub { display: none; } .map-beyond text { font-size: 15px; } }

/* address checker: postal code first */
.town-check input { text-transform: uppercase; }
.town-check input::placeholder { text-transform: none; }
.town-hint { margin: var(--s2) 0 0; font-size: 0.85rem; color: var(--muted); }
.town-result.no { border-left-color: var(--muted); }

/* area cards: eight areas = two full rows of four (two across on tablets; phones keep the swipe row) */
@media (min-width: 641px) { .area-list { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 1001px) { .area-list { grid-template-columns: repeat(4, minmax(0, 1fr)); } }

/* "Meet your plumber": Conor's line, the fuller statement, then who's saying it */
.owner-quote .owner-quote-lead { font: italic 600 clamp(1.35rem, 1.1rem + 0.8vw, 1.8rem)/1.35 var(--display); color: #fff; margin: 0 0 var(--s4); }
.owner-quote .owner-quote-body { font: 400 1.1rem/1.65 var(--body); color: #d5deea; margin: 0 0 var(--s5); max-width: 56ch; }
.owner-quote footer { display: flex; align-items: center; gap: var(--s3); }
.owner-quote footer > span { display: flex; flex-direction: column; line-height: 1.35; }
.owner-quote footer strong { color: #fff; font-weight: 600; font-size: 1rem; }
.owner-quote footer strong + span { color: #8ea2ba; font-size: 0.9rem; }
.owner-face { display: block; width: 52px; height: 52px; border-radius: 50%; object-fit: cover; box-shadow: 0 0 0 2px var(--gold); }
.owner-proof { display: flex; gap: var(--s2); align-items: baseline; margin: 0 0 var(--s6); font: 600 0.9rem/1.45 var(--body); color: var(--gold); }
.owner-proof::before { content: '★'; }
.owner-quote footer { border-left: 2px solid var(--gold); padding-left: var(--s3); }
/* the bigger map shrinks more on phones: larger labels there */
@media (max-width: 600px) {
  .map-town text { font-size: 27px; stroke-width: 6px; }
  .map-home text { font-size: 31px; }
  .map-island text { font-size: 23px; }
  .map-water { font-size: 24px; }
  .map-town circle { r: 8px; }
  .map-scale text, .map-key text { font-size: 18px; }
}
@media (max-width: 600px) { .map-key { display: none; } }

/* Hub heroes: a navy panel of real proof or quick facts where there's no picture */
.hero-panel { background: var(--navy-900); color: #cdd8e6; border-radius: var(--r-l); padding: clamp(24px, 3.4vw, 40px); box-shadow: var(--shadow-2); }
.hero-panel a { color: #fff; }
.hp-label { font: 700 0.75rem/1 var(--body); letter-spacing: 0.16em; text-transform: uppercase; color: var(--gold); margin: 0 0 var(--s4); }
.hp-score { display: flex; align-items: center; gap: var(--s3); margin: 0; font: 600 3.4rem/1 var(--display); color: #fff; }
.hp-score .stars svg { width: 24px; height: 24px; }
.hp-sub { margin: var(--s2) 0 var(--s5); }
.hp-bars { list-style: none; margin: 0; padding: var(--s5) 0 0; border-top: 1px solid rgb(255 255 255 / 0.12); display: grid; gap: var(--s4); }
.hp-bars li { display: grid; grid-template-columns: 2.4rem minmax(0, 1fr); column-gap: var(--s3); align-items: baseline; }
.hp-n { font: 600 1.6rem/1 var(--display); color: #fff; font-variant-numeric: tabular-nums; }
.hp-t { font-size: 0.95rem; line-height: 1.4; }
.hp-bar { grid-column: 2; height: 4px; margin-top: var(--s2); border-radius: 2px; background: linear-gradient(90deg, var(--gold) var(--w), rgb(255 255 255 / 0.12) var(--w)); }
.hp-ticks { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--s4); font: 600 1.15rem/1.35 var(--display); color: #fff; }
.hp-ticks li { display: flex; gap: var(--s3); align-items: flex-start; }
.hp-ticks svg { color: var(--gold); flex: none; margin-top: 4px; }
.hp-facts { margin: 0; }
.hp-facts div { display: grid; grid-template-columns: 7.5rem minmax(0, 1fr); gap: var(--s3); padding: var(--s3) 0; border-top: 1px solid rgb(255 255 255 / 0.1); }
.hp-facts div:first-child { border-top: 0; padding-top: 0; }
.hp-facts dt { color: #9fb1c8; font-size: 0.9rem; line-height: 1.5; }
.hp-facts dd { margin: 0; color: #fff; font-weight: 600; line-height: 1.5; }
.hp-foot { margin: var(--s5) 0 0; padding-top: var(--s4); border-top: 1px solid rgb(255 255 255 / 0.12); font-size: 0.92rem; }
.hero-split .next-steps { grid-template-columns: 1fr; gap: var(--s4); }
.hero-copy .town-check { margin-top: var(--s6); }
.area-tiers { background: var(--paper); border-radius: var(--r-m); padding: var(--s6); box-shadow: var(--shadow-1); }
.area-tiers h3 { margin: 0 0 var(--s4); font: 600 1.35rem/1.2 var(--display); color: var(--navy); }
.area-tiers ul { list-style: none; margin: 0 0 var(--s4); padding: 0; display: grid; gap: var(--s4); }
.area-tiers li { color: var(--muted); font-size: 0.975rem; line-height: 1.5; }
.area-tiers li strong { display: block; color: var(--navy); font-size: 1rem; }
@media (max-width: 480px) { .hp-facts div { grid-template-columns: 1fr; gap: 2px; } .hp-score { font-size: 2.8rem; } }
/* Postal code checker in the 340px sidebar (contact page): stack the button under the input */
.sidebar { grid-template-columns: minmax(0, 1fr); }
.sidebar .town-check { padding: var(--s5); }
.sidebar .town-check label { font-size: 1.2rem; }
.sidebar .town-row { flex-wrap: wrap; }
.sidebar .town-row .btn { flex: 1 1 100%; }
