/* ==========================================================================
   Champion Roofing, Oklahoma City
   Design system. Palette sampled from the real logo (#E22425 + black roofline).
   Motif: the roof ridge, repeated across chips, badges, rules and grips.
   ========================================================================== */

/* ---------- Fonts (self-hosted, Oct 2026) ----------
   The Google Fonts latin variable files, weight axis only (Archivo 400-800,
   Inter 400-700), served from /assets/fonts and preloaded in the head. One
   face per weight Google used to serve (Archivo 400/500/600/700/800, Inter
   400/500/600/650/700), all on the same file, so font matching is unchanged:
   Archivo 650 still draws at 700 and Inter 550 at 600. A single 400-800
   range would draw the true 650/550 and make that text lighter. No width
   axis: font-stretch: 112% matches the normal face, as it always has.
   The "Fallback" faces are Arial scaled to each font's measured width and
   vertical metrics, so the swap no longer re-wraps the hero. */
@font-face {
  font-family: 'Archivo';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(/assets/fonts/archivo-latin-wght.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: 'Archivo';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url(/assets/fonts/archivo-latin-wght.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: 'Archivo';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url(/assets/fonts/archivo-latin-wght.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: 'Archivo';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url(/assets/fonts/archivo-latin-wght.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: 'Archivo';
  font-style: normal;
  font-weight: 800;
  font-display: swap;
  src: url(/assets/fonts/archivo-latin-wght.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(/assets/fonts/inter-latin-wght.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url(/assets/fonts/inter-latin-wght.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url(/assets/fonts/inter-latin-wght.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 650;
  font-display: swap;
  src: url(/assets/fonts/inter-latin-wght.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url(/assets/fonts/inter-latin-wght.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: 'Archivo Fallback';
  font-weight: 100 599;
  src: local('Arial'), local('ArialMT'), local('Liberation Sans'), local('Arimo');
  size-adjust: 99%;
  ascent-override: 88.7%;
  descent-override: 21.2%;
  line-gap-override: 0%;
}
@font-face {
  font-family: 'Archivo Fallback';
  font-weight: 600 900;
  src: local('Arial Bold'), local('Arial-BoldMT'), local('Liberation Sans Bold'), local('Arimo Bold');
  size-adjust: 98.2%;
  ascent-override: 89.4%;
  descent-override: 21.4%;
  line-gap-override: 0%;
}
@font-face {
  font-family: 'Inter Fallback';
  font-weight: 100 599;
  src: local('Arial'), local('ArialMT'), local('Liberation Sans'), local('Arimo');
  size-adjust: 106.5%;
  ascent-override: 91%;
  descent-override: 22.6%;
  line-gap-override: 0%;
}
@font-face {
  font-family: 'Inter Fallback';
  font-weight: 600 900;
  src: local('Arial Bold'), local('Arial-BoldMT'), local('Liberation Sans Bold'), local('Arimo Bold');
  size-adjust: 101.4%;
  ascent-override: 95.5%;
  descent-override: 23.8%;
  line-gap-override: 0%;
}

/* ---------- Tokens ---------- */
:root {
  /* Brand red, sampled from the logo file */
  --red: #e22425;
  --red-deep: #b8191a;
  --red-dark: #8f1213;
  --red-soft: #f0605f;
  --red-wash: #fbeceb;

  /* Near-black, tinted warm toward the brand hue (never pure black) */
  --ink: #100c0c;
  --ink-2: #191313;
  --ink-3: #241c1c;
  --ink-4: #332727;

  /* Warm paper */
  --paper: #f8f5f2;
  --paper-2: #f0ebe6;
  --paper-3: #e4ddd6;

  /* Warm accent for stars, awards, eyebrows on dark */
  --gold: #c9a44d;
  --gold-soft: #d9bc79;
  --gold-light: #e7cf96;

  --white: #ffffff;
  --body: #4a4342;
  /* 5:1 or better on paper and tint (it was 4.3:1 on tint). */
  --body-dim: #6a6260;

  --line: rgba(16, 12, 12, 0.10);
  --line-2: rgba(16, 12, 12, 0.16);
  --line-dark: rgba(255, 255, 255, 0.12);
  --line-dark-2: rgba(255, 255, 255, 0.20);

  /* Radii */
  --r-sm: 6px;
  --r: 12px;
  --r-lg: 18px;
  --r-xl: 26px;
  --r-pill: 999px;

  /* Shadows */
  --sh-sm: 0 1px 2px rgba(16, 12, 12, .06), 0 2px 6px rgba(16, 12, 12, .04);
  --sh: 0 2px 6px rgba(16, 12, 12, .06), 0 12px 28px rgba(16, 12, 12, .08);
  --sh-lg: 0 8px 24px rgba(16, 12, 12, .10), 0 32px 64px rgba(16, 12, 12, .12);
  --sh-red: 0 10px 30px rgba(226, 36, 37, .28);

  /* Fluid type scale. Tightened roughly 13% from the first pass: the headings
     were carrying too much weight and pushing sections apart. */
  --t-eyebrow: clamp(.7rem, .66rem + .14vw, .76rem);
  --t-sm: clamp(.82rem, .79rem + .12vw, .88rem);
  --t-body: clamp(.94rem, .91rem + .14vw, 1rem);
  --t-lead: clamp(1rem, .95rem + .3vw, 1.14rem);
  --t-h4: clamp(1rem, .94rem + .34vw, 1.16rem);
  --t-h3: clamp(1.15rem, 1.02rem + .62vw, 1.52rem);
  --t-h2: clamp(1.6rem, 1.25rem + 1.6vw, 2.65rem);
  --t-h1: clamp(2rem, 1.45rem + 2.5vw, 3.85rem);
  --t-display: clamp(2.4rem, 1.4rem + 4.6vw, 6.2rem);

  /* Rhythm */
  --gap: clamp(1rem, .8rem + .9vw, 1.6rem);
  --sec-y: clamp(4rem, 2.6rem + 5.4vw, 8.5rem);
  --sec-y-sm: clamp(2.6rem, 1.8rem + 3.4vw, 5rem);
  --pad-x: clamp(1.15rem, .5rem + 2.6vw, 3rem);
  --max: 1360px;
  --max-wide: 1620px;
  --max-text: 74ch;

  /* Total height of the sticky header including its 1px rule. .head-inner is
     sized from this, so the two can never drift apart: sticky offsets and the
     hero overlay both measure from here. */
  --header-h: 84px;

  --ease: cubic-bezier(.22, .61, .36, 1);
  --ease-out: cubic-bezier(.16, 1, .3, 1);

  --font-display: 'Archivo', 'Archivo Fallback', 'Arial Narrow', system-ui, sans-serif;
  --font-body: 'Inter', 'Inter Fallback', system-ui, -apple-system, 'Segoe UI', sans-serif;
}

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

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  overflow-x: clip;
  /* Focus, anchors, scrollIntoView and native form validation all stop below
     the sticky header instead of under it. */
  scroll-padding-top: calc(var(--header-h) + 1rem);
}
/* The sticky header sits inside that band itself, so its own links cancel it
   out; otherwise tabbing into the header would scroll the page up. */
.site-head * { scroll-margin-top: calc(-1 * (var(--header-h) + 1rem)); }

body {
  font-family: var(--font-body);
  font-size: var(--t-body);
  line-height: 1.68;
  color: var(--body);
  background: var(--paper);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: clip;
  font-feature-settings: 'kern' 1, 'liga' 1, 'cv05' 1;
}

img, picture, svg, video { display: block; max-width: 100%; }
img { height: auto; }

/* <picture> is an extra box between a sized container and its <img>.
   Left at auto height it collapses to the image's natural ratio and
   `height:100%` on the img resolves against nothing, leaving a gap.
   Anywhere a container defines the crop box, the picture must fill it. */
.card-media picture,
.split-media picture,
.tile picture,
.explorer-media picture,
.compare picture,
.compare-top picture,
.hero-slide picture,
.phero-bg picture,
.cta-band-bg picture { width: 100%; height: 100%; }
input, button, textarea, select { font: inherit; color: inherit; }
button { background: none; border: 0; cursor: pointer; }
a { color: inherit; text-decoration: none; }
ul, ol { list-style: none; padding: 0; }

h1, h2, h3, h4, h5 {
  font-family: var(--font-display);
  font-weight: 700;
  line-height: 1.03;
  letter-spacing: -.015em;
  color: var(--ink);
  text-wrap: balance;
  font-stretch: 112%;
}

p { text-wrap: pretty; }

:focus-visible {
  outline: 3px solid var(--red);
  outline-offset: 3px;
  border-radius: 3px;
}

::selection { background: var(--red); color: #fff; }

/* ---------- Layout ---------- */
.wrap { width: 100%; max-width: var(--max); margin-inline: auto; padding-inline: var(--pad-x); }
.wrap-wide { width: 100%; max-width: var(--max-wide); margin-inline: auto; padding-inline: var(--pad-x); }
.wrap-narrow { width: 100%; max-width: 900px; margin-inline: auto; padding-inline: var(--pad-x); }
.sec { padding-block: var(--sec-y); position: relative; }
.sec-sm { padding-block: var(--sec-y-sm); position: relative; }
.sec-dark { background: var(--ink); color: rgba(255, 255, 255, .78); }
.sec-dark h1, .sec-dark h2, .sec-dark h3, .sec-dark h4 { color: #fff; }
.sec-tint { background: var(--paper-2); }
.center { text-align: center; }
.center .sec-head { margin-inline: auto; }

/* Film grain on dark surfaces */
.sec-dark::before {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  opacity: .5;
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)' opacity='.32'/%3E%3C/svg%3E");
}
.sec-dark > * { position: relative; z-index: 1; }

/* ---------- Type helpers ---------- */
.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: .6rem;
  font-family: var(--font-display);
  font-size: var(--t-eyebrow);
  font-weight: 700;
  letter-spacing: .17em;
  text-transform: uppercase;
  /* The deeper red keeps the small caps at 5.5:1 or better on paper and
     tint; the ridge icon stays the bright brand red. */
  color: var(--red-deep);
  font-stretch: 112%;
}
.sec-dark .eyebrow { color: var(--gold); }
.eyebrow svg { width: 17px; height: 17px; flex: none; color: var(--red); }
/* Dark grounds outside .sec-dark take the gold too, icon included. */
.phero .eyebrow, .contact-panel .eyebrow { color: var(--gold); }
.sec-dark .eyebrow svg, .phero .eyebrow svg, .contact-panel .eyebrow svg { color: inherit; }

.sec-head { max-width: 62ch; margin-bottom: clamp(2rem, 1.4rem + 2vw, 3.4rem); }
.sec-head h2 { font-size: var(--t-h2); margin-block: .7rem .9rem; }
.sec-head p { font-size: var(--t-lead); color: var(--body-dim); max-width: 58ch; }
.sec-dark .sec-head p { color: rgba(255, 255, 255, .68); }

.lead { font-size: var(--t-lead); color: var(--body-dim); }
.prose > * + * { margin-top: 1.15em; }
.prose h2 { font-size: var(--t-h3); margin-top: 2.2em; }
.prose h3 { font-size: var(--t-h4); margin-top: 1.8em; }
.prose ul { display: grid; gap: .7rem; }
.prose ul li { padding-left: 1.9rem; position: relative; }
.prose ul li::before {
  content: '';
  position: absolute;
  left: 0; top: .62em;
  width: 13px; height: 8px;
  background: var(--red);
  clip-path: polygon(0 100%, 50% 0, 100% 100%, 50% 62%);
}
.prose strong { color: var(--ink); font-weight: 650; }
.prose a:not(.btn) { color: var(--red-deep); text-decoration: underline; text-underline-offset: 3px; text-decoration-thickness: 1.5px; }
/* Blog articles (DS-39): body text a touch larger and the measure held near
   66 characters a line, since long-form reading tires on wider lines. The
   measure is in ch so it follows the text size (the root size is fluid); a ch
   is the width of a zero, wider than the average letter, so 51ch sets about
   66 characters (median, measured over all four articles). */
.prose-article { max-width: 51ch; font-size: 1.0625rem; line-height: 1.72; }
/* The opening paragraph never reads smaller than the body text after it. */
.prose-article > .lead { font-size: max(var(--t-lead), 1.05em); }
/* "Consider it when:", "The hail note:" and the like, set off by a rule. */
.prose .callout { padding: .1rem 0 .1rem 1.1rem; border-left: 3px solid var(--red); }
.prose .callout strong { color: var(--ink); }

/* Ghost watermark typography behind section headers */
.ghost {
  position: absolute;
  font-family: var(--font-display);
  font-weight: 800;
  font-stretch: 112%;
  font-size: var(--t-display);
  letter-spacing: -.03em;
  line-height: .8;
  text-transform: uppercase;
  -webkit-text-stroke: 1.5px rgba(16, 12, 12, .075);
  color: transparent;
  pointer-events: none;
  user-select: none;
  white-space: nowrap;
  z-index: 0;
  top: clamp(.4rem, 1vw, 1.6rem);
  left: var(--pad-x);
}
.sec-dark .ghost { -webkit-text-stroke-color: rgba(255, 255, 255, .085); }
.ghost-r { left: auto; right: var(--pad-x); }
.sec > .wrap, .sec > .wrap-wide, .sec-sm > .wrap { position: relative; z-index: 1; }

/* ---------- Buttons ---------- */
.btn {
  --btn-bg: var(--red);
  --btn-fg: #fff;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .6rem;
  padding: 1.02rem 1.85rem;
  background: var(--btn-bg);
  color: var(--btn-fg);
  border-radius: var(--r-pill);
  font-family: var(--font-display);
  font-weight: 700;
  font-size: var(--t-sm);
  letter-spacing: .04em;
  text-transform: uppercase;
  font-stretch: 112%;
  line-height: 1;
  position: relative;
  overflow: hidden;
  transition: transform .32s var(--ease-out), box-shadow .32s var(--ease-out), background .25s;
  will-change: transform;
  text-align: center;
}
.btn svg { width: 17px; height: 17px; flex: none; }
.btn::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(115deg, transparent 30%, rgba(255, 255, 255, .26) 50%, transparent 70%);
  transform: translateX(-110%);
  transition: transform .7s var(--ease-out);
}
.btn:hover { box-shadow: var(--sh-red); }
.btn:hover::after { transform: translateX(110%); }
.btn:active { transform: scale(.975); }

.btn-dark { --btn-bg: var(--ink); --btn-fg: #fff; }
.btn-dark:hover { box-shadow: 0 10px 30px rgba(16, 12, 12, .3); }
.btn-ghost {
  --btn-bg: transparent;
  --btn-fg: var(--ink);
  box-shadow: inset 0 0 0 1.5px var(--line-2);
}
.btn-ghost:hover { --btn-bg: var(--ink); --btn-fg: #fff; box-shadow: inset 0 0 0 1.5px var(--ink); }
/* Any dark surface, not just .sec-dark: the heroes and CTA band are dark too. */
.sec-dark .btn-ghost,
.hero .btn-ghost,
.phero .btn-ghost,
.cta-band .btn-ghost,
.contact-panel .btn-ghost { --btn-fg: #fff; box-shadow: inset 0 0 0 1.5px var(--line-dark-2); }
.sec-dark .btn-ghost:hover,
.hero .btn-ghost:hover,
.phero .btn-ghost:hover,
.cta-band .btn-ghost:hover,
.contact-panel .btn-ghost:hover { --btn-bg: #fff; --btn-fg: var(--ink); box-shadow: inset 0 0 0 1.5px #fff; }
.btn-lg { padding: 1.2rem 2.3rem; font-size: var(--t-body); }
.btn-sm { padding: .78rem 1.3rem; font-size: .78rem; }
.btn-row { display: flex; flex-wrap: wrap; gap: .85rem; }

/* Text link with animated ridge underline */
.link-ridge {
  display: inline-flex;
  align-items: center;
  gap: .5rem;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: var(--t-sm);
  letter-spacing: .05em;
  text-transform: uppercase;
  font-stretch: 112%;
  color: var(--red);
  position: relative;
  padding-bottom: .35rem;
}
.link-ridge::after {
  content: '';
  position: absolute;
  left: 0; bottom: 0;
  height: 2px;
  width: 100%;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: left;
  transition: transform .4s var(--ease-out);
}
.link-ridge:hover::after { transform: scaleX(1); }
.link-ridge svg { width: 15px; height: 15px; transition: transform .35s var(--ease-out); }
.link-ridge:hover svg { transform: translateX(4px); }

/* ---------- Ridge motif ---------- */
.ridge-chip {
  display: inline-grid;
  place-items: center; place-content: center;
  width: 52px; height: 52px;
  flex: none;
  border-radius: 14px;
  background: var(--red-wash);
  color: var(--red);
  transition: background .3s, color .3s, transform .4s var(--ease-out);
}
.ridge-chip svg { width: 25px; height: 25px; }
.sec-dark .ridge-chip { background: rgba(255, 255, 255, .07); color: var(--gold); }

/* Zigzag ridge rule used as a divider */
.ridge-rule {
  height: 10px;
  width: 100%;
  background-image: linear-gradient(135deg, var(--red) 25%, transparent 25%),
                    linear-gradient(225deg, var(--red) 25%, transparent 25%);
  background-size: 14px 10px;
  background-repeat: repeat-x;
  opacity: .3;
}

/* Roof-peak badge for numbered steps */
.peak-badge {
  width: 62px; height: 62px;
  flex: none;
  display: grid;
  place-items: center; place-content: center;
  background: var(--red);
  color: #fff;
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 1.25rem;
  font-stretch: 112%;
  clip-path: polygon(50% 0, 100% 33%, 100% 100%, 0 100%, 0 33%);
}

/* ---------- Header ---------- */
.scroll-bar {
  position: fixed;
  top: 0; left: 0;
  height: 3px;
  width: 100%;
  transform: scaleX(0);
  transform-origin: left;
  background: linear-gradient(90deg, var(--red), var(--red-soft));
  z-index: 200;
}

/* White since Oct 2026, at the owner's request: the site now opens light. */
.topbar {
  background: #fff;
  color: var(--body);
  font-size: .8rem;
  border-bottom: 1px solid var(--line);
}
.topbar .wrap-wide {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.4rem;
  min-height: 44px;
  flex-wrap: wrap;
}
.topbar-facts { display: flex; align-items: center; gap: 1.4rem; flex-wrap: wrap; }
.topbar-facts > span { display: inline-flex; align-items: center; gap: .45rem; }
.topbar-facts svg { width: 14px; height: 14px; color: var(--red); flex: none; }
.topbar a:hover { color: var(--ink); }
.topbar .status-pill { background: var(--paper-2); color: var(--ink); }

/* Live open/closed pill */
.status-pill {
  display: inline-flex;
  align-items: center;
  gap: .5rem;
  padding: .3rem .8rem;
  border-radius: var(--r-pill);
  background: rgba(255, 255, 255, .07);
  font-weight: 600;
  font-size: .78rem;
  white-space: nowrap;
}
.status-dot {
  width: 8px; height: 8px;
  border-radius: 50%;
  background: #3fbf6a;
  flex: none;
  position: relative;
}
.status-dot::after {
  content: '';
  position: absolute;
  inset: -4px;
  border-radius: 50%;
  border: 1.5px solid #3fbf6a;
  animation: ping 2.2s var(--ease) infinite;
}
.status-pill[data-open="false"] .status-dot { background: var(--gold); }
.status-pill[data-open="false"] .status-dot::after { border-color: var(--gold); }
@keyframes ping {
  0% { transform: scale(.6); opacity: 1; }
  80%, 100% { transform: scale(1.5); opacity: 0; }
}

.site-head {
  position: sticky;
  top: 0;
  z-index: 120;
  background: rgba(255, 255, 255, .92);
  backdrop-filter: saturate(180%) blur(16px);
  -webkit-backdrop-filter: saturate(180%) blur(16px);
  border-bottom: 1px solid var(--line);
  transition: box-shadow .3s, background .35s var(--ease), border-color .35s var(--ease), backdrop-filter .35s;
}
.site-head.is-stuck { box-shadow: 0 6px 26px rgba(16, 12, 12, .09); }
.head-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.2rem;
  min-height: calc(var(--header-h) - 1px);
}

/* ---------- Transparent header over a dark hero ----------
   On pages that open with a dark hero the header carries no ground of its
   own: the negative margin lets the hero rise under it, and the hero pads
   itself back down by the same amount so nothing sits beneath the nav. The
   first scroll returns it to the frosted bar. */
body.has-hero .site-head {
  margin-bottom: calc(-1 * var(--header-h));
  background: transparent;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
  border-bottom-color: rgba(255, 255, 255, .14);
}
body.has-hero > main > .hero,
body.has-hero > main > .phero,
body.has-hero > main > .errpage { padding-top: var(--header-h); }

/* A scrim carried by the header rather than by each hero: it keeps the white
   nav readable wherever a photograph turns bright behind it, sky included. */
body.has-hero .site-head::before {
  content: '';
  position: absolute;
  left: 0; right: 0; top: 0;
  height: calc(var(--header-h) * 2);
  background: linear-gradient(to bottom, rgba(16, 12, 12, .78) 0%, rgba(16, 12, 12, .42) 46%, transparent 100%);
  pointer-events: none;
  transition: opacity .35s var(--ease);
}
body.has-hero .site-head.is-stuck::before { opacity: 0; }
.head-inner { position: relative; z-index: 1; }

/* The first scroll hands the ground back. */
body.has-hero .site-head.is-stuck {
  background: rgba(255, 255, 255, .92);
  backdrop-filter: saturate(180%) blur(16px);
  -webkit-backdrop-filter: saturate(180%) blur(16px);
  border-bottom-color: var(--line);
}

body.has-hero .site-head:not(.is-stuck) .nav > li > a,
body.has-hero .site-head:not(.is-stuck) .nav > li > button,
body.has-hero .site-head:not(.is-stuck) .head-phone b { color: #fff; }
body.has-hero .site-head:not(.is-stuck) .head-phone small { color: rgba(255, 255, 255, .62); }
body.has-hero .site-head:not(.is-stuck) .burger span { background: #fff; }

.brand { display: flex; align-items: center; flex: none; position: relative; }
.brand-mark { transition: opacity .35s var(--ease); }
.brand-light { position: absolute; top: 50%; left: 0; translate: 0 -50%; opacity: 0; }
body.has-hero .site-head:not(.is-stuck) .brand-mark { opacity: 0; }
body.has-hero .site-head:not(.is-stuck) .brand-light { opacity: 1; }
.brand img { width: 190px; height: auto; }
/* The WebP <picture> wrapper must not become a box of its own. */
.brand picture { display: contents; }

.nav { display: flex; align-items: center; gap: .2rem; }
.nav > li { position: relative; }
.nav > li > a, .nav > li > button {
  display: inline-flex;
  align-items: center;
  gap: .35rem;
  padding: .8rem .85rem;
  font-family: var(--font-display);
  font-weight: 650;
  font-size: .85rem;
  letter-spacing: .045em;
  text-transform: uppercase;
  font-stretch: 112%;
  color: var(--ink);
  position: relative;
  white-space: nowrap;
}
.nav > li > a::after, .nav > li > button::after {
  content: '';
  position: absolute;
  left: .85rem; right: .85rem;
  bottom: .45rem;
  height: 2px;
  background: var(--red);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform .35s var(--ease-out);
}
.nav > li > a:hover::after, .nav > li:hover > a::after, .nav > li.is-open > a::after, .nav > li:hover > button::after, .nav > li > a[aria-current="page"]::after, .nav > li.is-section > a::after { transform: scaleX(1); }
/* Label link plus a caret button that opens the panel. The button is narrow
   to the eye but its ::before widens the hit area to 44 by 44. It widens to
   the right only, into the gap before the next item, so it never reaches
   over the label's own letters: the label always follows its link. */
.nav > li.has-mega { display: flex; align-items: center; }
.nav > li.has-mega > a { padding-right: .2rem; }
.nav > li.has-mega > a::after { right: .2rem; }
.nav > li > .nav-caret { padding: 0; width: 30px; height: 44px; justify-content: center; z-index: 1; border-radius: var(--r); }
.nav > li > .nav-caret::after { content: none; }
.nav-caret::before { content: ''; position: absolute; inset: 0 -14px 0 0; }
.nav-caret svg { width: 11px; height: 11px; transition: transform .3s; }
.nav-caret[aria-expanded="true"] svg, .no-js .nav > li:hover .nav-caret svg { transform: rotate(180deg); }

/* Mega menu */
.mega {
  position: absolute;
  top: calc(100% + 6px);
  /* Anchored to the nav item, not centred on it: centring a 760px panel on an
     item near the left edge pushed it off screen at narrower desktop widths. */
  left: 0;
  translate: none;
  width: min(620px, calc(100vw - var(--pad-x) * 2));
  background: #fff;
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--sh-lg);
  padding: .9rem;
  opacity: 0;
  visibility: hidden;
  transform: translateY(10px);
  transition: opacity .28s var(--ease), transform .28s var(--ease), visibility .28s;
  z-index: 50;
}
/* app.js opens the panel (hover, caret, keyboard) so Escape can always close
   it; a CSS :hover would hold it open. Without JS, hover still works. */
.nav > li.is-open .mega, .no-js .nav > li:hover .mega { opacity: 1; visibility: visible; transform: translateY(0); }
/* Ten service areas need a wider panel to lay out five up. */
.mega:has(.mega-item:nth-child(9)) { width: min(760px, calc(100vw - var(--pad-x) * 2)); }
.mega:not(:has(.mega-item:nth-child(4))) { width: min(360px, calc(100vw - var(--pad-x) * 2)); }
/* Auto-fit so an 8 item menu lays out in 3 columns instead of a tall 2 column list. */
/* Columns follow the count so no item is left alone on a row:
   up to 3 items one column, 4 to 8 two columns, 9 three columns. */
.mega-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: .1rem .6rem; }
.mega-grid:not(:has(.mega-item:nth-child(4))) { grid-template-columns: 1fr; }
.mega-grid:has(.mega-item:nth-child(9)) { grid-template-columns: repeat(3, 1fr); }
.mega-item {
  display: flex;
  gap: .6rem;
  padding: .45rem .55rem;
  border-radius: var(--r);
  transition: background .22s;
}
.mega-item:hover { background: var(--paper-2); }
.mega-item .ridge-chip { width: 30px; height: 30px; border-radius: 8px; }
.mega-item .ridge-chip svg { width: 16px; height: 16px; }
.mega-item strong {
  display: block;
  font-family: var(--font-display);
  font-size: .84rem;
  font-weight: 700;
  color: var(--ink);
  font-stretch: 112%;
  letter-spacing: -.005em;
}
.mega-item span { font-size: .72rem; line-height: 1.35; color: var(--body-dim); display: block; margin-top: .02rem; }
.mega-note {
  margin-top: .7rem;
  padding-top: .7rem;
  border-top: 1px solid var(--line);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
  font-size: .78rem;
  color: var(--body-dim);
}
.mega-note .link-ridge { min-height: 44px; }
.mega-item[aria-current="page"] { background: var(--paper-2); box-shadow: inset 3px 0 0 var(--red); }


.head-cta { display: flex; align-items: center; gap: .9rem; flex: none; }
.head-phone {
  display: flex;
  flex-direction: column;
  line-height: 1.15;
  text-align: right;
}
.head-phone small {
  font-size: .66rem;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--body-dim);
  font-weight: 600;
}
.head-phone b {
  font-family: var(--font-display);
  font-size: 1.16rem;
  font-weight: 800;
  color: var(--ink);
  font-stretch: 112%;
  letter-spacing: -.01em;
}
.head-phone:hover b { color: var(--red); }

.burger { display: none; width: 46px; height: 46px; place-items: center; place-content: center; border-radius: var(--r); }
.burger span { display: block; width: 22px; height: 2px; background: var(--ink); border-radius: 2px; transition: .3s var(--ease); }
.burger span + span { margin-top: 5px; }
.burger[aria-expanded="true"] span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.burger[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.burger[aria-expanded="true"] span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

/* Mobile drawer (a modal dialog, see app.js). Closed, it is hidden as well as
   off canvas, so its links never take Tab stops; visibility waits for the
   slide out before it switches. Its own scroll never runs on into the page. */
.drawer {
  position: fixed;
  inset: 0 0 0 auto;
  width: min(410px, 90vw);
  background: var(--ink);
  color: #fff;
  z-index: 190;
  transform: translateX(100%);
  visibility: hidden;
  transition: transform .42s var(--ease-out), visibility 0s linear .42s;
  overflow-y: auto;
  overscroll-behavior: contain;
  /* A link tabbed to scrolls clear of the pinned action bar and its fade.
     app.js measures the bar into --drawer-foot; 9rem is its usual height. */
  scroll-padding-bottom: calc(var(--drawer-foot, 9rem) + .75rem);
  padding: 1.4rem var(--pad-x) 0;
  display: flex;
  flex-direction: column;
  gap: .2rem;
}
.drawer.is-open { transform: translateX(0); visibility: visible; transition: transform .42s var(--ease-out), visibility 0s; }
.drawer-top { display: flex; justify-content: flex-end; margin-bottom: .8rem; }
.drawer-close { width: 44px; height: 44px; display: grid; place-items: center; place-content: center; color: #fff; border-radius: var(--r); background: rgba(255,255,255,.08); }
.drawer-close svg { width: 20px; height: 20px; }
.drawer-link {
  padding: .85rem 0;
  border-bottom: 1px solid rgba(255, 255, 255, .09);
  font-family: var(--font-display);
  font-weight: 650;
  font-size: 1.02rem;
  font-stretch: 112%;
  display: flex;
  align-items: center;
  min-height: 52px;
}
/* A section with pages under it: the label goes to the hub, the chevron
   beside it opens the list (DS-1). Closed lists are hidden from Tab and from
   screen readers as well as collapsed. */
.drawer-row { display: flex; align-items: stretch; border-bottom: 1px solid rgba(255, 255, 255, .09); }
.drawer-row .drawer-link { flex: 1; border-bottom: 0; }
.drawer-toggle { flex: none; width: 52px; display: grid; place-items: center; place-content: center; color: rgba(255, 255, 255, .78); border-left: 1px solid rgba(255, 255, 255, .09); }
.drawer-toggle svg { width: 18px; height: 18px; transition: transform .35s var(--ease-out); }
.drawer-toggle[aria-expanded="true"] svg { transform: rotate(180deg); }
@media (hover: hover) { .drawer-toggle:hover { color: #fff; background: rgba(255, 255, 255, .05); } }
.drawer-sub { display: grid; grid-template-rows: 0fr; visibility: hidden; transition: grid-template-rows .38s var(--ease-out), visibility 0s linear .38s; }
.drawer-group.is-open .drawer-sub { grid-template-rows: 1fr; visibility: visible; transition: grid-template-rows .38s var(--ease-out), visibility 0s; }
.drawer-sub > div { min-height: 0; overflow: hidden; display: grid; }
.drawer-group.is-open .drawer-sub > div { padding-block: .25rem .5rem; border-bottom: 1px solid rgba(255, 255, 255, .09); }
.drawer a.sub { display: flex; align-items: center; justify-content: flex-start; min-height: 44px; padding: .55rem 0 .55rem 1.1rem; font-size: .92rem; font-weight: 500; color: rgba(255, 255, 255, .72); }
.drawer a.sub:hover { color: #fff; }
.drawer a.sub::before { content: ''; width: 11px; height: 7px; background: var(--red); clip-path: polygon(0 100%, 50% 0, 100% 100%); margin-right: .6rem; flex: none; }
/* The page you are on, and the section it sits in, carry a red rule. */
.drawer-link[aria-current="page"], .drawer-link.is-section { color: #fff; box-shadow: inset 3px 0 0 var(--red); padding-left: .9rem; }
.drawer a.sub[aria-current="page"] { color: #fff; box-shadow: inset 3px 0 0 var(--red); }
/* Call and assessment stay pinned to the foot of the menu while it scrolls. */
.drawer-actions {
  position: sticky;
  bottom: 0;
  margin: auto calc(-1 * var(--pad-x)) 0;
  padding: 1rem var(--pad-x) max(1.1rem, env(safe-area-inset-bottom));
  display: grid;
  gap: .6rem;
  background: var(--ink);
  border-top: 1px solid rgba(255, 255, 255, .09);
  box-shadow: 0 -18px 24px -6px var(--ink);
}
.drawer .btn { justify-content: center; }
.drawer .btn-ghost { --btn-fg: #fff; box-shadow: inset 0 0 0 1.5px var(--line-dark-2); }
.drawer .btn-ghost:hover { --btn-bg: #fff; --btn-fg: var(--ink); box-shadow: inset 0 0 0 1.5px #fff; }
.scrim {
  position: fixed;
  inset: 0;
  background: rgba(16, 12, 12, .55);
  backdrop-filter: blur(3px);
  z-index: 180;
  opacity: 0;
  visibility: hidden;
  transition: .35s;
}
.scrim.is-open { opacity: 1; visibility: visible; }

/* ---------- Hero ---------- */
.hero {
  position: relative;
  background: var(--ink);
  color: #fff;
  overflow: hidden;
  isolation: isolate;
}
.hero-slides { position: absolute; inset: 0; z-index: 0; }
.hero-slide {
  position: absolute;
  inset: 0;
  opacity: 0;
  transition: opacity 1.5s var(--ease);
}
.hero-slide.is-active { opacity: 1; }
.hero-slide img { width: 100%; height: 100%; object-fit: cover; }
/* Amprite style slow zoom: the active photo settles from 1.06 to 1.0 across the
   slide's eight seconds. The same settle on every slide, so the hero has one
   consistent rhythm. Scale runs on the image inside an overflow clipped slide,
   so nothing spills and layout never shifts. */
.hero-slide { overflow: hidden; }
.hero-slide img { transform: scale(1.06); transform-origin: 50% 40%; will-change: transform; }
.hero-slide.is-active img { animation: heroSettle 9s cubic-bezier(.22, .61, .36, 1) forwards; }
@keyframes heroSettle { from { transform: scale(1.06); } to { transform: scale(1); } }
.hero-slides::after {
  content: '';
  position: absolute;
  inset: 0;
  background:
    linear-gradient(105deg, rgba(16, 12, 12, .93) 0%, rgba(16, 12, 12, .78) 38%, rgba(16, 12, 12, .35) 68%, rgba(16, 12, 12, .5) 100%),
    linear-gradient(to top, rgba(16, 12, 12, .8), transparent 42%);
  z-index: 2;
}
.hero-inner {
  position: relative;
  z-index: 3;
  padding-block: clamp(3.4rem, 2rem + 7vw, 8rem) clamp(8rem, 4rem + 12vw, 12rem);
  display: grid;
  gap: 1.35rem;
  justify-items: start;
  text-align: left;
}
/* Constrain the copy, not the container: the block stays flush left with the
   logo and the line length stays readable. */
.hero-inner > * { max-width: 780px; }
.hero h1 { font-size: clamp(2.35rem, 1.65rem + 3.15vw, 4.75rem); color: #fff; letter-spacing: -.028em; }
.hero h1 em { font-style: normal; color: var(--red-soft); }
.hero-lede { font-size: var(--t-lead); color: rgba(255, 255, 255, .8); max-width: 60ch; }

.hero-badge {
  display: inline-flex;
  align-items: center;
  gap: .6rem;
  align-self: start;
  padding: .5rem 1.05rem .5rem .5rem;
  border-radius: var(--r-pill);
  background: rgba(255, 255, 255, .09);
  border: 1px solid rgba(255, 255, 255, .16);
  backdrop-filter: blur(8px);
  font-size: .82rem;
  font-weight: 600;
  color: #fff;
}
.hero-badge b { display: grid; place-items: center; place-content: center; width: 27px; height: 27px; border-radius: 50%; background: var(--red); }
.hero-badge b svg { width: 15px; height: 15px; }

.hero-proof {
  display: flex;
  align-items: center;
  gap: .7rem;
  font-size: .92rem;
  color: rgba(255, 255, 255, .8);
  flex-wrap: wrap;
}
.stars { display: inline-flex; gap: 2px; }
.stars svg { width: 16px; height: 16px; color: var(--gold); }

/* Hero controls */
.hero-ctl {
  position: absolute;
  bottom: clamp(6.2rem, 3rem + 9vw, 9rem);
  right: var(--pad-x);
  z-index: 4;
  display: flex;
  align-items: center;
  gap: 1.5rem;
}
.hero-caption {
  font-size: .82rem;
  color: rgba(255, 255, 255, .74);
  max-width: 30ch;
  text-align: right;
  line-height: 1.45;
}
.hero-arrows { display: flex; align-items: center; gap: 1.1rem; }
.hero-arrow {
  color: rgba(255, 255, 255, .6);
  transition: color .3s, transform .3s var(--ease-out);
  padding: .5rem 0;
}
.hero-arrow svg { width: 46px; height: 13px; }
.hero-arrow:hover { color: #fff; }
.hero-arrow[data-dir="prev"]:hover { transform: translateX(-5px); }
.hero-arrow[data-dir="next"]:hover { transform: translateX(5px); }
.hero-count { font-family: var(--font-display); font-weight: 700; font-size: .84rem; letter-spacing: .1em; color: rgba(255,255,255,.75); font-stretch: 112%; }
.hero-count b { color: #fff; }
.hero-progress {
  position: absolute;
  left: var(--pad-x);
  right: var(--pad-x);
  bottom: clamp(5.4rem, 2.6rem + 8vw, 8rem);
  height: 2px;
  background: rgba(255, 255, 255, .16);
  z-index: 4;
}
.hero-progress i { display: block; height: 100%; background: var(--red); width: 0; }

/* ---------- Docked lead form ---------- */
.dock {
  margin-top: clamp(-7rem, -5vw, -4.5rem);
  /* Breathing room before whatever follows the form, usually the ticker. */
  padding-bottom: clamp(2.5rem, 1.6rem + 3vw, 5rem);
  position: relative;
  z-index: 20;
}
.lead-card {
  background: #fff;
  border-radius: var(--r-xl);
  box-shadow: var(--sh-lg);
  padding: clamp(1.2rem, .95rem + 1.15vw, 1.9rem);
  border: 1px solid var(--line);
}
.lead-card-head { display: flex; justify-content: space-between; align-items: flex-end; gap: 1.2rem; flex-wrap: wrap; margin-bottom: 1rem; }
.lead-card-head h2 { font-size: var(--t-h3); margin-top: .5rem; }
.lead-card-head p { font-size: .86rem; color: var(--body-dim); margin-top: .25rem; }

.field-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: .65rem .75rem; align-items: end; }
.field.wide { grid-column: span 2; }
.field { display: grid; gap: .28rem; }
.field.wide { grid-column: span 2; }
.field.full { grid-column: 1 / -1; }
.field label {
  font-size: .74rem;
  font-weight: 650;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--ink);
}
.field label .req { color: var(--red); }
.field input, .field select, .field textarea {
  width: 100%;
  padding: .48rem .75rem;
  font-size: .9rem;
  background: var(--paper);
  border: 1.5px solid var(--line);
  border-radius: var(--r);
  font-size: .97rem;
  transition: border-color .25s, background .25s, box-shadow .25s;
  min-height: 48px;
}
.field textarea { min-height: 52px; resize: vertical; }
.field select { appearance: none; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23756c6a' stroke-width='2.5' stroke-linecap='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E"); background-repeat: no-repeat; background-position: right 1rem center; background-size: 15px; padding-right: 2.6rem; }
.field input:focus, .field select:focus, .field textarea:focus {
  /* Invisible normally; forced colours paint it, where the ring below is lost. */
  outline: 3px solid transparent;
  outline-offset: 2px;
  border-color: var(--red);
  background: #fff;
  box-shadow: 0 0 0 4px var(--red-wash);
}
.field .err { font-size: .78rem; color: var(--red-deep); display: none; }
/* Without JavaScript the browser validates and :user-invalid shows the note.
   With it, app.js validates (form.is-js) and marks the field .is-invalid with
   a message for the actual problem: empty, or the wrong format. */
form:not(.is-js) .field input:user-invalid, form:not(.is-js) .field select:user-invalid { border-color: var(--red-deep); }
form:not(.is-js) .field input:user-invalid ~ .err, form:not(.is-js) .field select:user-invalid ~ .err { display: block; }
.field.is-invalid input, .field.is-invalid select { border-color: var(--red-deep); }
.field.is-invalid .err { display: block; }
.hp { position: absolute; left: -9999px; opacity: 0; height: 0; width: 0; }
.form-foot { display: flex; align-items: center; justify-content: space-between; gap: 1rem; flex-wrap: wrap; margin-top: 1.3rem; }
.form-foot small { font-size: .78rem; color: var(--body-dim); max-width: 52ch; line-height: 1.5; }
.form-foot small a { color: var(--ink); text-decoration: underline; text-underline-offset: 2px; }
.form-foot small a:hover { color: var(--red-deep); }
/* Sending: the button visibly changes (label, spinner, dimmed) and cannot be
   pressed twice. app.js puts the original label and arrow back afterwards. */
form[data-lead] .btn:disabled { cursor: progress; opacity: .78; box-shadow: none; transform: none; }
form[data-lead] .btn:disabled::after { display: none; }
form[data-lead] .btn:disabled::before {
  content: '';
  width: 15px;
  height: 15px;
  flex: none;
  border-radius: 50%;
  border: 2px solid rgba(255, 255, 255, .45);
  border-top-color: #fff;
  animation: btn-spin .8s linear infinite;
}
@keyframes btn-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { form[data-lead] .btn:disabled::before { animation: none; } }
/* The one line under the button for anything that went wrong (role="alert"). */
.form-msg { margin-top: .9rem; font-size: .9rem; line-height: 1.5; color: var(--red-deep); font-weight: 550; }
.form-msg:empty { margin-top: 0; }
.form-msg.is-note { color: var(--body-dim); font-weight: 400; }
.form-msg a { color: inherit; text-decoration: underline; text-underline-offset: 2px; white-space: nowrap; }
/* Without JavaScript a failed post comes back as ?error=<code>#form-error-<code>
   and :target shows that one baked message above the fields. With JavaScript
   (form.is-js) app.js shows the message under the button instead. The html
   scroll-padding already clears the sticky header, so the jump only adds a
   little air here. */
.form-err { display: none; margin: 0 0 1.1rem; scroll-margin-top: .5rem; }
.form-err:target { display: block; }
form.is-js .form-err { display: none; }
/* Cloudflare Turnstile slot. Interaction only: it stays zero height for most
   people (the margin then collapses into .form-foot's) and only opens when
   Cloudflare asks for a tick. */
.ts-slot { max-width: 100%; margin-top: 1rem; }

/* ---------- Ticker ---------- */
.ticker {
  background: var(--ink);
  color: rgba(255, 255, 255, .82);
  padding-block: 1.05rem;
  overflow: hidden;
  border-block: 1px solid rgba(255, 255, 255, .08);
}
/* About 90px a second; ticker() doubles each group, hence the longer loop. */
.ticker-track { display: flex; width: max-content; animation: ticker 57s linear infinite; }
.ticker:hover .ticker-track { animation-play-state: paused; }
.ticker-group { display: flex; align-items: center; flex: none; }
.ticker-item {
  display: inline-flex;
  align-items: center;
  gap: .7rem;
  padding-inline: 1.5rem;
  font-family: var(--font-display);
  font-weight: 650;
  font-size: .88rem;
  letter-spacing: .06em;
  text-transform: uppercase;
  white-space: nowrap;
  font-stretch: 112%;
}
.ticker-item::after {
  content: '';
  width: 13px; height: 8px;
  background: var(--red);
  clip-path: polygon(0 100%, 50% 0, 100% 100%, 50% 62%);
  margin-left: 1.5rem;
  flex: none;
}
@keyframes ticker { to { transform: translateX(-50%); } }

/* ---------- Cards ---------- */
.grid { display: grid; gap: var(--gap); }
.g-2 { grid-template-columns: repeat(2, 1fr); }
.g-3 { grid-template-columns: repeat(3, 1fr); }
.g-4 { grid-template-columns: repeat(4, 1fr); }

.card {
  background: #fff;
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  overflow: hidden;
  transition: transform .45s var(--ease-out), box-shadow .45s var(--ease-out), border-color .35s;
  display: flex;
  flex-direction: column;
  position: relative;
}
.card:is(a, :has(> a), :has(.card-body a)):hover { transform: translateY(-7px); box-shadow: var(--sh-lg); border-color: transparent; }
.card-media { position: relative; aspect-ratio: 4 / 3; overflow: hidden; background: var(--paper-3); }
.card-media img { width: 100%; height: 100%; object-fit: cover; }
.card-media::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(to top, rgba(16, 12, 12, .58), transparent 55%);
}
.card-tag {
  position: absolute;
  left: 1rem; top: 1rem;
  z-index: 2;
  padding: .34rem .8rem;
  border-radius: var(--r-pill);
  background: rgba(16, 12, 12, .72);
  backdrop-filter: blur(6px);
  color: #fff;
  font-size: .7rem;
  font-weight: 650;
  letter-spacing: .09em;
  text-transform: uppercase;
}
.card-body { padding: 1.5rem; display: flex; flex-direction: column; gap: .7rem; flex: 1; }
.card-body h3 { font-size: var(--t-h4); }
.card-body p { font-size: .95rem; color: var(--body-dim); flex: 1; }
.card .link-ridge { align-self: flex-start; margin-top: .3rem; }

/* Service card with ridge reveal on hover */
.svc-card .card-body::before {
  content: '';
  position: absolute;
  left: 0; top: 0;
  height: 3px;
  width: 100%;
  background: var(--red);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform .5s var(--ease-out);
}
.svc-card:hover .card-body::before { transform: scaleX(1); }
.svc-card .card-body { position: relative; }
/* Compact rows (serviceGrid rows option, /services). Once the grid is one
   column, twelve photo cards would run past 11,000px on a phone, so each
   becomes a row: thumbnail, title, a two line summary and an arrow. The tag
   repeats the title and is kept for screen readers only. */
@media (max-width: 760px) {
  .svc-rows { gap: .65rem; }
  .svc-rows .svc-card { flex-direction: row; align-items: stretch; }
  .svc-rows .svc-card.card:hover { transform: none; }
  .svc-rows .card-media { flex: none; width: 128px; aspect-ratio: auto; min-height: 104px; }
  .svc-rows .card-media::after { display: none; }
  .svc-rows .card-tag { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
  .svc-rows .card-body { justify-content: center; gap: .3rem; padding: .85rem 2.6rem .85rem 1rem; }
  .svc-rows .card-body h3 { font-size: 1.06rem; line-height: 1.25; }
  .svc-rows .card-body p { flex: none; font-size: .86rem; line-height: 1.45; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
  .svc-rows .link-ridge { position: absolute; right: .9rem; top: 50%; translate: 0 -50%; margin: 0; padding: 0; font-size: 0; }
  .svc-rows .link-ridge::after { display: none; }
  .svc-rows .link-ridge svg { width: 18px; height: 18px; }
}
@media (max-width: 560px) {
  .svc-rows .card-media { width: 96px; min-height: 96px; }
}

/* Dark card with pointer-tracking glow */
.glow-card {
  position: relative;
  background: var(--ink-2);
  border: 1px solid var(--line-dark);
  border-radius: var(--r-lg);
  padding: 1.9rem;
  overflow: hidden;
  transition: border-color .35s, transform .45s var(--ease-out);
}
.glow-card::before {
  content: '';
  position: absolute;
  inset: 0;
  background: radial-gradient(340px circle at var(--mx, 50%) var(--my, 50%), rgba(226, 36, 37, .16), transparent 62%);
  opacity: 0;
  transition: opacity .4s;
  pointer-events: none;
}
.glow-card:hover { border-color: var(--line-dark-2); transform: translateY(-4px); }
.glow-card:hover::before { opacity: 1; }
.glow-card > * { position: relative; }
.glow-card h3 { font-size: var(--t-h4); margin-block: 1rem .55rem; color: #fff; }
.glow-card p { font-size: .94rem; color: rgba(255, 255, 255, .66); }

/* ---------- Stats ---------- */
.stat-strip { background: var(--ink); color: #fff; }
.stat-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 1px; background: rgba(255, 255, 255, .1); }
.stat {
  background: var(--ink);
  padding: clamp(1.8rem, 1.2rem + 2vw, 3rem) 1.4rem;
  text-align: center;
}
.stat b {
  display: block;
  font-family: var(--font-display);
  font-size: clamp(1.85rem, 1.3rem + 2.1vw, 2.9rem);
  font-weight: 800;
  line-height: 1;
  color: #fff;
  font-stretch: 112%;
  letter-spacing: -.02em;
}
.stat b .suf { color: var(--red-soft); }
/* Direct child only: the count-up and suffix spans live inside <b> and must
   keep the display size, not the label size. */
.stat > span {
  display: block;
  margin-top: .6rem;
  font-size: .78rem;
  letter-spacing: .13em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, .58);
  font-weight: 600;
}

/* ---------- Split feature ---------- */
.split { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(2rem, 1rem + 4vw, 5rem); align-items: center; }
.split-media { position: relative; border-radius: var(--r-xl); overflow: hidden; box-shadow: var(--sh-lg); }
.split-media img { width: 100%; height: 100%; object-fit: cover; aspect-ratio: 4 / 3.2; }
/* Uneven splits only open up beside each other on wide screens. At 1024px and
   below .split is one column: the form then the office panel, the article
   then its aside. */
.split-single { grid-template-columns: 1fr; }
@media (min-width: 1025px) {
  .split-form { grid-template-columns: 1.25fr .75fr; }
  .split-article { grid-template-columns: 1.35fr .65fr; }
  .split-aside { position: sticky; top: 110px; }
  /* A blog article fills the page width like every other section: the text
     starts in line with the hero, keeps its readable measure, and the aside
     takes the right edge (Aida, 9 Oct; the earlier aside-beside-the-text
     layout left the spare width as a blank band on wide screens). */
  .split-post { grid-template-columns: minmax(0, 1.6fr) minmax(320px, 1fr); }
}
/* Aida (9 Oct): the article text fills its column right up to the aside.
   From 1280px the text steps up in size, so the longer lines stay readable
   (medians about 80 to 85 characters a line). */
@media (min-width: 1025px) { .split-post .prose-article { max-width: none; } }
@media (min-width: 1280px) { .split-post .prose-article { font-size: 1.125rem; } .split-post .prose-article > .lead { font-size: 1.08em; } }
@media (min-width: 1920px) { .split-post .prose-article { font-size: 1.1875rem; } }
.split-media.tall img { aspect-ratio: 3 / 3.6; }

/* Floating credential card over media */
/* Credential bar: sits flush inside the bottom edge of the image rather than
   hanging off the corner as a card, so nothing clips and nothing floats. */
.float-card {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: 1.05rem clamp(1.1rem, .8rem + 1vw, 1.7rem);
  background: linear-gradient(to top, rgba(10, 8, 8, .93) 30%, rgba(10, 8, 8, .62) 75%, transparent);
  backdrop-filter: blur(2px);
  -webkit-backdrop-filter: blur(2px);
  color: #fff;
}
.float-card::before {
  content: '';
  position: absolute;
  left: clamp(1.1rem, .8rem + 1vw, 1.7rem);
  right: clamp(1.1rem, .8rem + 1vw, 1.7rem);
  top: 0;
  height: 1px;
  background: linear-gradient(90deg, var(--gold), rgba(201, 164, 77, 0));
}
.float-card .ridge-chip {
  width: 40px; height: 40px;
  border-radius: 11px;
  background: rgba(255, 255, 255, .1);
  color: var(--gold);
  border: 1px solid rgba(255, 255, 255, .16);
}
.float-card .ridge-chip svg { width: 20px; height: 20px; }
.float-card b {
  display: block;
  font-family: var(--font-display);
  font-size: 1.02rem;
  color: #fff;
  font-stretch: 112%;
  line-height: 1.15;
  letter-spacing: -.005em;
}
.float-card span {
  display: block;
  font-size: .82rem;
  color: rgba(255, 255, 255, .68);
  margin-top: .15rem;
}

/* Checklist */
.checks { display: grid; gap: .85rem; margin-top: 1.6rem; }
.checks li { display: flex; gap: .85rem; align-items: flex-start; font-size: .97rem; }
.checks li svg { width: 21px; height: 21px; color: var(--red); flex: none; margin-top: .18rem; }
.sec-dark .checks li svg { color: var(--gold); }
.checks li b { color: var(--ink); font-weight: 650; }
.sec-dark .checks li b { color: #fff; }

/* ---------- Process timeline ---------- */
.steps { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--gap); position: relative; }
.step { position: relative; }
.step::after {
  content: '';
  position: absolute;
  top: 31px;
  left: 74px;
  right: calc(-1 * var(--gap) + 12px);
  border-top: 2px dashed var(--line-2);
}
.step:last-child::after, .step:nth-child(4n)::after { display: none; }
/* steps() adds a count class. Five steps sit on one row and six run 3 + 3,
   so no step is left alone on a row, and the connector stops at the last
   item of each row. On tablets five steps run 3 + 2 on a six track grid. */
@media (min-width: 1025px) {
  .steps.steps-n5 { grid-template-columns: repeat(5, 1fr); }
  .steps.steps-n6 { grid-template-columns: repeat(3, 1fr); }
  .steps-n5 .step:nth-child(4n)::after, .steps-n6 .step:nth-child(4n)::after { display: block; }
  .steps-n6 .step:nth-child(3n)::after { display: none; }
}
@media (min-width: 761px) and (max-width: 1024px) {
  .steps.steps-n5 { grid-template-columns: repeat(6, 1fr); }
  .steps-n5 .step { grid-column: span 2; }
  .steps-n5 .step:nth-child(n+4) { grid-column: span 3; }
}
.sec-dark .step::after { border-color: rgba(255, 255, 255, .16); }
.step .peak-badge { margin-bottom: 1.1rem; }
.step h3 { font-size: var(--t-h4); margin-bottom: .5rem; }
.step p { font-size: .93rem; color: var(--body-dim); }
.sec-dark .step p { color: rgba(255, 255, 255, .64); }

/* ---------- Center-stage carousel ---------- */
.stage { position: relative; overflow: hidden; padding-block: 1rem 0; }
.stage-track { display: flex; gap: var(--gap); transition: transform .65s var(--ease-out); will-change: transform; }
.stage-item { flex: 0 0 clamp(270px, 30vw, 400px); opacity: .42; transform: scale(.93); transition: opacity .55s var(--ease-out), transform .55s var(--ease-out); }
.stage-item.is-active { opacity: 1; transform: scale(1); }
.stage-nav { display: flex; align-items: center; justify-content: center; gap: 1.6rem; margin-top: 2.2rem; }
.stage-btn {
  width: 54px; height: 54px;
  display: grid; place-items: center; place-content: center;
  border-radius: 50%;
  border: 1.5px solid var(--line-2);
  color: var(--ink);
  transition: .3s var(--ease-out);
}
.stage-btn:hover { background: var(--ink); color: #fff; border-color: var(--ink); }
.stage-btn svg { width: 19px; height: 19px; }
.sec-dark .stage-btn { border-color: var(--line-dark-2); color: #fff; }
.sec-dark .stage-btn:hover { background: #fff; color: var(--ink); }
.stage-dots { display: flex; gap: .45rem; align-items: center; }
.stage-dots button { width: 8px; height: 8px; border-radius: 50%; background: var(--line-2); transition: .3s; }
.stage-dots button[aria-selected="true"] { background: var(--red); width: 26px; border-radius: var(--r-pill); }

/* ---------- Annotated roof hotspots ---------- */
.hotspot-wrap { display: grid; grid-template-columns: 1.35fr .65fr; gap: clamp(1.6rem, 1rem + 3vw, 3.4rem); align-items: center; }
.hotspot-media { position: relative; border-radius: var(--r-xl); overflow: hidden; margin: 0; }
.hotspot-media picture, .hotspot-media img { width: 100%; height: 100%; }
.hotspot-media img { aspect-ratio: 16 / 11; object-fit: cover; }
.hotspot-media::after { content: ''; position: absolute; inset: 0; background: linear-gradient(200deg, rgba(16,12,12,.15), rgba(16,12,12,.55)); }
.hotspot {
  position: absolute;
  z-index: 2;
  translate: -50% -50%;
  width: 44px; height: 44px;
  display: grid;
  place-items: center; place-content: center;
  border-radius: 50%;
  background: rgba(16, 12, 12, .6);
  border: 1.5px solid rgba(255, 255, 255, .5);
  backdrop-filter: blur(6px);
  color: #fff;
  font-family: var(--font-display);
  font-weight: 800;
  font-size: .9rem;
  transition: .35s var(--ease-out);
}
.hotspot::after {
  content: '';
  position: absolute;
  inset: -7px;
  border-radius: 50%;
  border: 1.5px solid var(--red);
  opacity: 0;
  transition: opacity .35s;
}
.hotspot:hover, .hotspot[aria-pressed="true"] { background: var(--red); border-color: var(--red); scale: 1.12; }
.hotspot[aria-pressed="true"]::after { opacity: 1; animation: ping 2.2s var(--ease) infinite; }
.hotspot-panels { display: grid; }
.hotspot-panel { display: none; animation: fadeUp .5s var(--ease-out); }
.hotspot-panel.is-active { display: block; }
.hotspot-num { font-family: var(--font-display); font-weight: 800; font-size: .82rem; letter-spacing: .18em; color: var(--gold); font-stretch: 112%; }
.hotspot-panel h3 { font-size: var(--t-h3); color: #fff; margin-block: .5rem .7rem; }
.hotspot-panel p { color: rgba(255, 255, 255, .7); font-size: .99rem; }
.hotspot-note { margin-top: 1.8rem; padding-top: 1.4rem; border-top: 1px solid var(--line-dark); font-size: .9rem; color: rgba(255, 255, 255, .55); }

/* ---------- Sticky feature ---------- */
.stik { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(2rem, 1.2rem + 3vw, 4.5rem); align-items: stretch; }
.stik-media { height: 100%; }
.stik-frame {
  position: sticky;
  top: calc(var(--header-h) + 1.6rem);
  border-radius: var(--r-xl);
  overflow: hidden;
  box-shadow: var(--sh-lg);
  aspect-ratio: 4 / 3.35;
}
.stik-img { position: absolute; inset: 0; margin: 0; opacity: 0; transition: opacity .6s var(--ease); }
.stik-img.is-live { opacity: 1; }
.stik-img picture, .stik-img img { width: 100%; height: 100%; }
.stik-img img { object-fit: cover; }
.stik-frame::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(to top, rgba(16, 12, 12, .34), transparent 45%);
  pointer-events: none;
}
.stik-rule {
  position: absolute;
  left: 1.4rem; right: 1.4rem; bottom: 1.4rem;
  z-index: 3;
  height: 2px;
  background: rgba(255, 255, 255, .26);
  border-radius: 2px;
  overflow: hidden;
}
.stik-rule i { display: block; height: 100%; width: 0; background: var(--red); transition: width .5s var(--ease); }
.stik-copy { display: grid; gap: 0; }
.stik-block { min-height: 0; display: flex; flex-direction: column; justify-content: flex-start; padding-block: 0 clamp(2.2rem, 1.6rem + 2vw, 3.6rem); }
.stik-block:last-child { padding-bottom: 0; }
.stik-block { cursor: default; transition: opacity .3s; }
@media (hover: hover) { .stik:has(.stik-block:hover) .stik-block:not(:hover) { opacity: .55; } }
.stik-block h3 { font-size: var(--t-h3); margin-bottom: .8rem; }
.stik-block p { color: var(--body-dim); max-width: 52ch; }
.stik-block p + p { margin-top: .85rem; }
.sec-dark .stik-block p { color: rgba(255, 255, 255, .68); }

/* ---------- Manifesto ledger ---------- */
.ledger { border-top: 1px solid var(--line-2); }
.sec-dark .ledger { border-color: var(--line-dark); }
.ledger-row {
  display: grid;
  grid-template-columns: minmax(210px, 320px) 1fr;
  gap: clamp(1.4rem, 1rem + 2.5vw, 4rem);
  padding-block: clamp(1.6rem, 1.2rem + 1.4vw, 2.6rem);
  border-bottom: 1px solid var(--line-2);
}
.sec-dark .ledger-row { border-color: var(--line-dark); }
.ledger-claim { display: flex; gap: .9rem; align-items: flex-start; }
.ledger-claim .ridge-chip { width: 34px; height: 34px; border-radius: 10px; flex: none; }
.ledger-claim .ridge-chip svg { width: 17px; height: 17px; }
.ledger-claim h3 { font-size: var(--t-h4); line-height: 1.25; }
.ledger-body p { color: var(--body-dim); max-width: 62ch; }
.ledger-body p + p { margin-top: .8rem; }
.sec-dark .ledger-body p { color: rgba(255, 255, 255, .66); }
.ledger-quote {
  margin: 0 0 1rem;
  padding-left: 1.1rem;
  border-left: 2px solid var(--red);
  font-family: var(--font-display);
  font-size: clamp(1.05rem, .95rem + .5vw, 1.45rem);
  font-weight: 600;
  font-stretch: 112%;
  line-height: 1.4;
  letter-spacing: -.012em;
  color: var(--ink);
}
.sec-dark .ledger-quote { color: #fff; }

/* ---------- Gallery trio ---------- */
.trio { display: grid; grid-template-columns: repeat(3, 1fr); gap: clamp(1.4rem, 1rem + 1.8vw, 2.6rem); }
.trio-item { display: flex; flex-direction: column; }
.trio-media {
  position: relative;
  margin: 0 0 1.3rem;
  border-radius: var(--r-lg);
  overflow: hidden;
  box-shadow: var(--sh);
}
.trio-media picture, .trio-media img { width: 100%; height: 100%; }
.trio-media img { aspect-ratio: 4 / 4.4; object-fit: cover; }
.trio-media::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(to top, rgba(16, 12, 12, .5), transparent 42%);
}
.trio-num {
  position: absolute;
  left: 0; bottom: 0;
  z-index: 2;
  padding: .45rem 1.5rem .45rem 1.05rem;
  background: var(--red);
  color: #fff;
  font-family: var(--font-display);
  font-weight: 800;
  font-size: .92rem;
  font-stretch: 112%;
  letter-spacing: .05em;
  clip-path: polygon(0 0, calc(100% - 13px) 0, 100% 100%, 0 100%);
}
.trio-item h3 { font-size: var(--t-h4); margin-bottom: .6rem; }
.trio-item p { font-size: .93rem; color: var(--body-dim); }
.trio-item p + p { margin-top: .75rem; }
.sec-dark .trio-item p { color: rgba(255, 255, 255, .66); }

/* ---------- Editorial stack ---------- */
.ed-stack { display: grid; gap: clamp(2.4rem, 1.6rem + 3vw, 5rem); }
.ed-row { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(1.6rem, 1rem + 3vw, 3.6rem); align-items: center; }
.ed-row.rev .ed-media { order: 2; }
.ed-media { position: relative; margin: 0; border-radius: var(--r-xl); overflow: hidden; box-shadow: var(--sh-lg); }
.ed-media picture, .ed-media img { width: 100%; height: 100%; }
.ed-media img { aspect-ratio: 4 / 3; object-fit: cover; }
.ed-index {
  position: absolute;
  left: 0; bottom: 0;
  padding: .55rem 1.15rem;
  background: var(--red);
  color: #fff;
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 1.05rem;
  font-stretch: 112%;
  letter-spacing: .04em;
  clip-path: polygon(0 0, calc(100% - 14px) 0, 100% 100%, 0 100%);
  padding-right: 1.7rem;
}
.ed-kicker {
  display: inline-flex;
  align-items: center;
  gap: .5rem;
  font-family: var(--font-display);
  font-size: var(--t-eyebrow);
  font-weight: 700;
  letter-spacing: .17em;
  text-transform: uppercase;
  color: var(--red);
  font-stretch: 112%;
}
.ed-kicker svg { width: 16px; height: 16px; }
.ed-body h3 { font-size: clamp(1.15rem, .98rem + .78vw, 1.6rem); margin-block: .8rem .9rem; }
.ed-body p { color: var(--body-dim); }
.ed-body p + p { margin-top: .9rem; }

/* The roof build-up has its own stylesheet, buildup.css, loaded only on the
   page that shows it. */

/* ---------- Detail accordion ---------- */
.detail-grid { display: grid; gap: .8rem; }
.detail-card {
  background: #fff;
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  overflow: hidden;
  transition: border-color .3s, box-shadow .3s;
}
.sec-dark .detail-card { background: var(--ink-2); border-color: var(--line-dark); }
.detail-card[open] { box-shadow: var(--sh); }
.detail-card summary {
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: 1.25rem 3.6rem 1.25rem 1.4rem;
  cursor: pointer;
  position: relative;
  list-style: none;
}
.detail-card summary::-webkit-details-marker { display: none; }
.detail-card summary::after {
  content: '';
  position: absolute;
  right: 1.5rem; top: 50%;
  translate: 0 -50%;
  width: 14px; height: 9px;
  background: var(--red);
  clip-path: polygon(0 0, 50% 100%, 100% 0, 50% 38%);
  transition: transform .35s var(--ease-out);
}
.detail-card[open] summary::after { transform: rotate(180deg); }
.detail-sum b { display: block; font-family: var(--font-display); font-size: 1.08rem; font-stretch: 112%; color: var(--ink); line-height: 1.25; }
.sec-dark .detail-sum b { color: #fff; }
.detail-sum > span { display: block; font-size: .85rem; color: var(--body-dim); margin-top: .15rem; }
.detail-body { padding: 0 1.4rem 1.5rem 4.4rem; font-size: .97rem; color: var(--body-dim); }
.detail-body > * + * { margin-top: .9rem; }
/* Cap the paragraphs, not the padded box: at 1280 and up they ran 145 to
   176 characters a line. */
.detail-body > p { max-width: 70ch; }
/* With a photo: cards on the left and a sticky portrait crop on the right
   from 1025px up; below that a short landscape band above the cards. */
.detail-split { align-items: start; }
@media (min-width: 1025px) {
  .detail-split > .detail-grid { grid-column: 1; grid-row: 1; }
  .detail-split > .detail-media { grid-column: 2; grid-row: 1; }
  .detail-media img { aspect-ratio: 3 / 3.6; }
}
@media (max-width: 1024px) {
  .detail-media img { aspect-ratio: 16 / 9; }
}

/* ---------- Drag compare ---------- */
.compare { position: relative; border-radius: var(--r-xl); overflow: hidden; box-shadow: var(--sh-lg); user-select: none; touch-action: pan-y; }
.compare img { width: 100%; display: block; aspect-ratio: 16 / 11; object-fit: cover; }
.compare-top { position: absolute; inset: 0; clip-path: inset(0 50% 0 0); }
.compare-top img { width: 100%; height: 100%; }
.compare-range { position: absolute; inset: 0; width: 100%; height: 100%; opacity: 0; cursor: ew-resize; margin: 0; z-index: 4; }
.compare-grip {
  position: absolute;
  top: 0; bottom: 0;
  left: 50%;
  width: 3px;
  background: #fff;
  translate: -50% 0;
  pointer-events: none;
  z-index: 3;
  box-shadow: 0 0 20px rgba(0, 0, 0, .4);
}
.compare-grip::after {
  content: '';
  position: absolute;
  top: 50%; left: 50%;
  translate: -50% -50%;
  width: 56px; height: 56px;
  border-radius: 50%;
  background: var(--red);
  box-shadow: 0 6px 22px rgba(0, 0, 0, .35);
  clip-path: polygon(50% 0, 100% 33%, 100% 100%, 0 100%, 0 33%);
}
.compare-grip::before {
  content: '';
  position: absolute;
  top: 50%; left: 50%;
  translate: -50% -46%;
  z-index: 2;
  width: 20px; height: 12px;
  background: #fff;
  clip-path: polygon(0 100%, 50% 0, 100% 100%, 50% 62%);
}
.compare-label {
  position: absolute;
  bottom: 1.1rem;
  z-index: 3;
  padding: .4rem .95rem;
  border-radius: var(--r-pill);
  background: rgba(16, 12, 12, .75);
  backdrop-filter: blur(6px);
  color: #fff;
  font-size: .74rem;
  font-weight: 650;
  letter-spacing: .1em;
  text-transform: uppercase;
}
.compare-label.l { left: 1.1rem; }
.compare-label.r { right: 1.1rem; }

/* ---------- Material explorer ---------- */
.explorer { display: grid; grid-template-columns: 320px 1fr; gap: clamp(1.5rem, 1rem + 2vw, 3rem); align-items: start; }
.explorer-tabs { display: grid; gap: .5rem; }
.explorer-tab {
  display: flex;
  align-items: center;
  gap: .9rem;
  width: 100%;
  padding: 1rem 1.15rem;
  border-radius: var(--r);
  border: 1.5px solid var(--line-dark);
  color: rgba(255, 255, 255, .74);
  text-align: left;
  transition: .32s var(--ease-out);
  font-family: var(--font-display);
  font-weight: 650;
  font-size: .96rem;
  font-stretch: 112%;
}
.explorer-tab svg { width: 22px; height: 22px; flex: none; color: var(--gold); transition: color .3s; }
.explorer-tab:hover { border-color: var(--line-dark-2); color: #fff; }
.explorer-tab[aria-selected="true"] { background: var(--red); border-color: var(--red); color: #fff; }
.explorer-tab[aria-selected="true"] svg { color: #fff; }
.explorer-panel { display: none; }
.explorer-panel.is-active { display: grid; grid-template-columns: 1.05fr .95fr; gap: clamp(1.4rem, 1rem + 2vw, 2.6rem); align-items: center; animation: fadeUp .55s var(--ease-out); }
.explorer-panel h3 { font-size: var(--t-h3); color: #fff; margin-bottom: .7rem; }
.explorer-panel p { color: rgba(255, 255, 255, .7); font-size: .98rem; }
.explorer-media { border-radius: var(--r-lg); overflow: hidden; }
.explorer-media img { aspect-ratio: 4 / 3.4; object-fit: cover; width: 100%; }
.spec-row { display: grid; gap: .55rem; margin-top: 1.3rem; }
.spec-row div { display: flex; justify-content: space-between; gap: 1rem; padding: .6rem 0; border-bottom: 1px solid var(--line-dark); font-size: .9rem; }
.spec-row dt { color: rgba(255, 255, 255, .55); }
.spec-row dd { color: #fff; font-weight: 600; text-align: right; }

@keyframes fadeUp { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } }

/* The "How we inspect" laps are styled in drone.css, loaded with them. */

/* ---------- Reviews ---------- */
.marquee { overflow: hidden; -webkit-mask-image: linear-gradient(90deg, transparent, #000 7%, #000 93%, transparent); mask-image: linear-gradient(90deg, transparent, #000 7%, #000 93%, transparent); }
.marquee-track { display: flex; gap: var(--gap); width: max-content; animation: ticker 68s linear infinite; }
.marquee:hover .marquee-track { animation-play-state: paused; }
.review {
  flex: 0 0 min(400px, 82vw);
  background: #fff;
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  padding: 1.7rem;
  display: flex;
  flex-direction: column;
  gap: .9rem;
}
.review { position: relative; }
.review-mark { position: absolute; right: 1.4rem; top: 1.3rem; width: 34px; color: var(--red); opacity: .13; }
.review-mark svg { width: 100%; height: auto; }
.review blockquote { margin: 0; flex: 1; }
.review p { font-size: .96rem; color: var(--body); line-height: 1.68; }
.review-tag {
  align-self: flex-start;
  padding: .34rem .8rem;
  border-radius: var(--r-pill);
  background: var(--red-wash);
  color: var(--red-deep);
  font-size: .72rem;
  font-weight: 700;
  letter-spacing: .07em;
  text-transform: uppercase;
}
.review-who { display: flex; align-items: center; gap: .8rem; padding-top: .9rem; border-top: 1px solid var(--line); }
.review-id b { display: block; font-family: var(--font-display); font-size: .96rem; color: var(--ink); font-stretch: 112%; }
.review-id > span { display: block; font-size: .8rem; color: var(--body-dim); }
.avatar {
  width: 42px; height: 42px;
  display: grid; place-items: center; place-content: center;
  background: var(--ink);
  color: #fff;
  font-family: var(--font-display);
  font-weight: 800;
  font-size: .95rem;
  flex: none;
  clip-path: polygon(50% 0, 100% 33%, 100% 100%, 0 100%, 0 33%);
  /* The roof peak adds empty area at the top, so the visible shape's centre sits
     below the box centre. A small top pad drops the initials onto it. */
  padding-top: 11px;
  letter-spacing: .02em;
  line-height: 1;
}
.review-id b { display: block; font-size: .93rem; color: var(--ink); }
.review-id > span { display: block; font-size: .8rem; color: var(--body-dim); }

/* Rating block */
.rating-split { display: grid; grid-template-columns: .82fr 1.18fr; gap: clamp(1.8rem, 1rem + 3vw, 4rem); align-items: center; }
.rating-split > * { min-width: 0; }
.rating-big { display: flex; align-items: center; gap: 1.1rem; margin-top: 1rem; }
.rating-big > b {
  font-family: var(--font-display);
  font-size: clamp(2.6rem, 1.9rem + 2.6vw, 4.1rem);
  font-weight: 800;
  font-stretch: 112%;
  line-height: .9;
  letter-spacing: -.03em;
  color: var(--ink);
}
.rating-big > span { display: grid; gap: .3rem; }
.rating-big .stars svg { width: 21px; height: 21px; }
.rating-big > span > span { font-size: .92rem; color: var(--body-dim); font-weight: 600; }

.topic-cloud { display: flex; flex-wrap: wrap; gap: .6rem; align-items: center; }
.topic-chip {
  display: inline-flex;
  align-items: center;
  gap: .6rem;
  padding: .6rem 1.1rem .6rem .6rem;
  border-radius: var(--r-pill);
  background: #fff;
  border: 1px solid var(--line);
  font-size: .9rem;
  font-weight: 600;
  color: var(--ink);
  box-shadow: var(--sh-sm);
  transition: transform .35s var(--ease-out), box-shadow .35s var(--ease-out);
}
.topic-chip:hover { transform: translateY(-3px); box-shadow: var(--sh); }
.topic-chip b {
  display: grid;
  place-items: center; place-content: center;
  width: 30px; height: 30px;
  border-radius: 50%;
  background: var(--red);
  color: #fff;
  font-family: var(--font-display);
  font-size: .84rem;
  font-weight: 800;
  flex: none;
}
.sec-tint .topic-chip { background: #fff; }
.topic-evidence { display: grid; grid-template-columns: .9fr 1.1fr; gap: clamp(1.4rem, 1rem + 2vw, 3rem); align-items: center; }

/* ---------- Error pages (404, 410) ---------- */
.errpage {
  position: relative;
  min-height: calc(100vh - var(--header-h) - 2rem);
  display: grid;
  align-items: center;
  background: radial-gradient(120% 90% at 20% 0%, #241012 0%, var(--ink) 50%, #0c0708 100%);
  color: #fff;
  overflow: hidden;
  isolation: isolate;
}
.errpage-ghost {
  position: absolute;
  right: -2vw; top: 50%;
  translate: 0 -54%;
  font-family: var(--font-display);
  font-weight: 800;
  font-stretch: 112%;
  font-size: clamp(12rem, 34vw, 40rem);
  line-height: 1;
  letter-spacing: -.05em;
  color: transparent;
  -webkit-text-stroke: 1.5px rgba(255, 255, 255, .08);
  user-select: none;
  pointer-events: none;
  z-index: 0;
}
.errpage-ridge { position: absolute; left: 0; right: 0; bottom: -2px; width: 100%; height: 22%; z-index: 0; pointer-events: none; opacity: .8; }
.errpage-inner { position: relative; z-index: 2; padding-block: clamp(4rem, 3rem + 6vw, 9rem); }
.errpage-inner > * { max-width: 720px; }
.errpage-code {
  display: inline-flex; align-items: center; gap: .5rem;
  font-family: var(--font-display); font-size: var(--t-eyebrow); font-weight: 700;
  letter-spacing: .17em; text-transform: uppercase; color: var(--red-soft); font-stretch: 112%;
}
.errpage-code svg { width: 14px; height: 14px; }
.errpage h1 { font-size: clamp(2.4rem, 1.6rem + 3.6vw, 5rem); color: #fff; letter-spacing: -.03em; margin-block: 1rem 1.1rem; max-width: 14ch; }
.errpage-lede { font-size: var(--t-lead); color: rgba(255, 255, 255, .72); max-width: 48ch; }
.errpage-links { display: grid; grid-template-columns: 1fr 1fr; gap: .7rem; margin-top: 2.4rem; }
.errpage-link {
  display: flex; align-items: center; gap: .9rem;
  padding: .95rem 1.1rem;
  border-radius: var(--r-lg);
  background: rgba(255, 255, 255, .05);
  border: 1px solid var(--line-dark);
  color: #fff;
  transition: .35s var(--ease-out);
}
.errpage-link:hover { background: rgba(255, 255, 255, .09); border-color: var(--line-dark-2); transform: translateY(-2px); }
.errpage-link .ridge-chip { width: 40px; height: 40px; border-radius: 11px; background: rgba(226, 36, 37, .16); color: var(--red-soft); flex: none; }
.errpage-link .ridge-chip svg { width: 20px; height: 20px; }
.errpage-link-txt { flex: 1; }
.errpage-link-txt b { display: block; font-family: var(--font-display); font-size: .98rem; font-stretch: 112%; }
.errpage-link-txt span { display: block; font-size: .8rem; color: rgba(255, 255, 255, .58); margin-top: .1rem; }
.errpage-link > svg:last-child { width: 18px; height: 18px; color: var(--red-soft); opacity: 0; transform: translateX(-4px); transition: .3s var(--ease-out); }
.errpage-link:hover > svg:last-child { opacity: 1; transform: none; }
.errpage-foot { margin-top: 2rem; font-size: .9rem; color: rgba(255, 255, 255, .58); }
.errpage-foot a { color: #fff; font-weight: 600; border-bottom: 1px solid var(--red); }

/* /thank-you next steps (CRO-12): when the call comes, what to have ready,
   and photos by email. Glass panels on the dark page, like the links. */
.ty-when { display: inline-flex; align-items: center; gap: .75rem; margin-top: 1.6rem; padding: .7rem 1.1rem .7rem 1rem; border-radius: var(--r-lg); background: rgba(255, 255, 255, .06); border: 1px solid var(--line-dark); font-size: .92rem; font-weight: 500; color: #fff; line-height: 1.45; }
.ty-when[data-open="false"] .status-dot { background: var(--gold); }
.ty-when[data-open="false"] .status-dot::after { border-color: var(--gold); }
.errpage-inner > .ty-next, .errpage-inner > .ty-next ~ .errpage-links { max-width: 940px; }
.ty-next { display: grid; grid-template-columns: minmax(0, 1.3fr) minmax(0, 1fr); gap: .7rem; margin-top: 2rem; }
.ty-ready, .ty-photos { padding: clamp(1.2rem, 1rem + 1vw, 1.7rem); border-radius: var(--r-lg); background: rgba(255, 255, 255, .05); border: 1px solid var(--line-dark); -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px); }
.ty-next h2 { font-size: 1.15rem; color: #fff; letter-spacing: -.01em; }
.ty-next p { font-size: .88rem; color: rgba(255, 255, 255, .62); margin-top: .35rem; }
.ty-ready ul { display: grid; gap: .6rem; margin-top: 1.1rem; }
.ty-ready li { display: flex; gap: .7rem; align-items: flex-start; font-size: .92rem; color: rgba(255, 255, 255, .72); line-height: 1.5; }
.ty-ready li svg { width: 19px; height: 19px; flex: none; margin-top: .12rem; color: var(--red-soft); }
.ty-ready li b { color: #fff; font-weight: 600; }
.ty-photos { display: flex; flex-direction: column; align-items: flex-start; }
.ty-photos .ridge-chip { width: 44px; height: 44px; border-radius: 12px; background: rgba(226, 36, 37, .16); color: var(--red-soft); margin-bottom: 1rem; }
.ty-photos .ridge-chip svg { width: 21px; height: 21px; }
.ty-photos .btn { margin-top: auto; }
.ty-photos p { margin-bottom: 1.3rem; }
.ty-photos small { margin-top: .6rem; font-size: .78rem; color: rgba(255, 255, 255, .5); overflow-wrap: anywhere; }
.errpage-links-h { margin-top: 2.6rem; font-family: var(--font-display); font-size: .78rem; font-weight: 700; letter-spacing: .14em; text-transform: uppercase; color: var(--gold); font-stretch: 112%; }
.errpage-links-h + .errpage-links { margin-top: 1rem; }
@media (max-width: 760px) { .ty-next { grid-template-columns: 1fr; } .ty-when { display: flex; } }
/* The page runs long, so the ridge keeps a set height and sits in the
   bottom padding, under the last line, never behind the cards. */
.errpage-long { --ridge-h: clamp(70px, 2rem + 6vw, 150px); }
.errpage-long .errpage-ridge { height: var(--ridge-h); }
.errpage-long .errpage-inner { padding-bottom: calc(var(--ridge-h) + clamp(1.5rem, 1rem + 2vw, 3rem)); }

/* /about community (DS-41): the three organizations set large, no photo. */
.community-grid { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: clamp(2rem, 1rem + 4vw, 5rem); align-items: center; }
.community-copy h2 { font-size: var(--t-h2); margin-block: .7rem 1rem; }
.community-copy p + p { margin-top: 1rem; }
.community-list { border-top: 1px solid var(--line-2); }
.community-list li { display: grid; grid-template-columns: auto minmax(0, 1fr); column-gap: 1.1rem; row-gap: .35rem; padding-block: clamp(1.2rem, 1rem + .8vw, 1.7rem); border-bottom: 1px solid var(--line-2); }
.community-mark { grid-row: span 2; display: grid; place-items: center; width: 40px; height: 40px; border-radius: 11px; background: var(--red-wash); color: var(--red); }
.community-mark svg { width: 20px; height: 20px; }
.community-list b { font-family: var(--font-display); font-size: clamp(1.35rem, 1.05rem + 1.1vw, 2rem); font-weight: 750; line-height: 1.15; letter-spacing: -.015em; color: var(--ink); }
.community-list li > span:last-child { font-size: .76rem; font-weight: 700; letter-spacing: .12em; text-transform: uppercase; color: var(--body-dim); font-stretch: 112%; }
@media (max-width: 900px) { .community-grid { grid-template-columns: 1fr; } }

/* ---------- 404 page (Oct 2026) ----------
   The photograph stays bright and nothing ever sits over the dog. Below 1025
   the photo comes first, framed on the dog, with the copy on the dark band
   underneath; from 1025 it runs full bleed and the copy sits over the tiles
   on the left, on a scrim no darker than the inner page hero wash that fades
   out before the dog. The 410 page keeps the .errpage rules above. */
.errpage-nf { display: block; min-height: 0; background: var(--ink); }
.nf-hero { position: relative; }
.nf-media { position: relative; aspect-ratio: 4 / 3; overflow: hidden; background: #3a2420; }
.nf-media picture { width: 100%; height: 100%; }
.nf-media img { width: 100%; height: 100%; object-fit: cover; }
.nf-copy { position: relative; z-index: 2; padding-block: clamp(2rem, 1.5rem + 2.4vw, 3rem) clamp(2.4rem, 1.8rem + 2.4vw, 3.4rem); }
.errpage-nf .eyebrow { color: var(--gold); }
.errpage-nf .eyebrow svg { color: inherit; }
.errpage-nf h1 { font-size: clamp(2.15rem, 1.5rem + 2.9vw, 4.15rem); color: #fff; letter-spacing: -.026em; margin-block: 1.1rem .9rem; max-width: 14ch; }
.nf-lede { font-size: var(--t-lead); color: rgba(255, 255, 255, .8); max-width: 44ch; }
.errpage-nf .btn-row { margin-top: 2rem; }
.errpage-nf .btn-ghost { --btn-fg: #fff; box-shadow: inset 0 0 0 1.5px var(--line-dark-2); }
.errpage-nf .btn-ghost:hover { --btn-bg: #fff; --btn-fg: var(--ink); box-shadow: inset 0 0 0 1.5px #fff; }
.nf-popular { padding-block: 0 clamp(3.4rem, 2rem + 5vw, 6rem); }
.nf-popular h2 { font-size: clamp(1.25rem, 1.1rem + .6vw, 1.6rem); color: #fff; padding-top: clamp(2rem, 1.4rem + 2vw, 3rem); border-top: 1px solid var(--line-dark); margin-bottom: 1.2rem; }
.nf-links { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: .7rem; }
.nf-links .errpage-link { height: 100%; }
@media (max-width: 1024px) { .nf-links { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 641px) and (max-width: 1024px) { .nf-media { aspect-ratio: 2 / 1; } }
@media (max-width: 640px) { .nf-links { grid-template-columns: minmax(0, 1fr); } }
@media (min-width: 1025px) {
  body.has-hero > main > .errpage-nf { padding-top: 0; }
  .nf-hero { display: grid; align-items: center; min-height: clamp(36rem, 48vw, 54rem); }
  .nf-media { position: absolute; inset: 0; aspect-ratio: auto; }
  .nf-media::after { content: ''; position: absolute; inset: 0; pointer-events: none; background: linear-gradient(90deg, rgba(16, 12, 12, .84) 0%, rgba(16, 12, 12, .84) 12%, rgba(16, 12, 12, .72) 28%, rgba(16, 12, 12, .64) 40%, rgba(16, 12, 12, 0) 51%); }
  .nf-copy { padding-block: calc(var(--header-h) + 2.4rem) 3.4rem; }
  .nf-copy > * { max-width: min(34rem, calc(40vw - var(--pad-x))); }
  .nf-copy :is(.eyebrow, h1, p) { text-shadow: 0 0 2px rgba(16, 12, 12, .6), 0 1px 10px rgba(0, 0, 0, .5); }
  .nf-popular h2 { border-top: 0; }
}

/* ---------- Review carousel (centre stage) ---------- */
.rcar { position: relative; overflow: hidden; min-width: 0; width: 100%; }
.sec > .wrap > .rcar, .sec > .wrap > * > .rcar { margin-inline: calc(var(--pad-x) * -1); padding-inline: var(--pad-x); width: auto; }
.rcar-track { display: flex; gap: 1.2rem; transition: transform .55s var(--ease-out); will-change: transform; }
.rcar-slide { flex: 0 0 calc((100% - 2 * 1.2rem) / 3); min-width: 0; }
.rcar-slide .review { cursor: default; }
@media (max-width: 1024px) { .rcar-slide { flex-basis: calc((100% - 1.2rem) / 2); } }
@media (max-width: 640px) { .rcar-slide { flex-basis: 86%; } }
.rcar-slide .review { height: 100%; }
.rcar-ctl { display: flex; align-items: center; gap: 1.2rem; margin-top: 1.6rem; }
.rcar-btn { width: 60px; height: 28px; color: var(--ink); opacity: .7; transition: opacity .3s, transform .3s var(--ease-out); }
.rcar-btn svg { width: 100%; height: 100%; }
.rcar-btn:hover { opacity: 1; transform: translateX(2px); }
.rcar-btn[data-rdir="-1"]:hover { transform: translateX(-2px); }
.rcar-count { font-family: var(--font-display); font-weight: 700; font-size: .86rem; letter-spacing: .1em; color: var(--body-dim); font-stretch: 112%; }
.rcar-count b { color: var(--ink); }
.sec-dark .rcar-btn { color: #fff; }
.sec-dark .rcar-count b { color: #fff; }
/* Long reviews clamp on the card; the full text is a click away on /reviews. */
.rcar .review p { display: -webkit-box; -webkit-line-clamp: 7; -webkit-box-orient: vertical; overflow: hidden; }

/* ---------- Reviews page: uniform grid with read more ---------- */
.rev-head { display: flex; justify-content: space-between; align-items: flex-end; gap: 1.5rem; flex-wrap: wrap; margin-bottom: clamp(1.8rem, 1.2rem + 2vw, 3rem); }
.rev-head h2 { font-size: var(--t-h2); margin-block: .6rem .6rem; max-width: 18ch; }
.rev-head p { color: var(--body-dim); max-width: 46ch; }
.rev-head .btn svg:first-child { width: 16px; height: 16px; }
.rev-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1.2rem; align-items: stretch; }
.rev-grid .review { height: 100%; }
/* Every card reserves the same text block so the grid stays level; long ones
   clamp inside it, short ones leave quiet space, open ones grow past it. */
.rev-grid .review blockquote { min-height: calc(1.68em * 6); }
.rev-grid .review:not(.is-clamp) blockquote { margin-bottom: 2.1rem; }
.review.is-clamp p { display: -webkit-box; -webkit-line-clamp: 6; -webkit-box-orient: vertical; overflow: hidden; }
.review.is-clamp.is-open p { display: block; -webkit-line-clamp: unset; overflow: visible; }
.review-more {
  align-self: flex-start;
  display: inline-flex; align-items: center; gap: .3rem;
  margin-top: -.2rem;
  font-family: var(--font-display); font-size: .78rem; font-weight: 700;
  letter-spacing: .08em; text-transform: uppercase; color: var(--red);
  font-stretch: 112%;
}
.review-more svg { width: 14px; height: 14px; transition: transform .3s var(--ease-out); }
.review.is-open .review-more svg { transform: rotate(180deg); }
.review-more:hover { color: var(--red-deep); }

/* Review filters and theme bars */
.filter-row { display: flex; flex-wrap: wrap; gap: .5rem; }
.filter-row .area-chip { border-color: var(--line-2); color: var(--body); background: #fff; cursor: pointer; }
.filter-row .area-chip.is-live { background: var(--red); border-color: var(--red); color: #fff; }

.theme-bars { display: grid; gap: .75rem; max-width: 900px; }
.theme-bar { display: grid; grid-template-columns: minmax(120px, 190px) 1fr auto; gap: 1rem; align-items: center; }
.theme-label { font-size: .92rem; font-weight: 600; color: var(--ink); }
.theme-track { height: 12px; border-radius: var(--r-pill); background: var(--paper-3); overflow: hidden; }
.theme-track i {
  display: block;
  height: 100%;
  border-radius: var(--r-pill);
  background: linear-gradient(90deg, var(--red-deep), var(--red-soft));
  transform-origin: left;
  animation: growBar .9s var(--ease-out) both;
}
.theme-count {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 1rem;
  color: var(--ink);
  font-stretch: 112%;
  min-width: 2ch;
  text-align: right;
}
@keyframes growBar { from { transform: scaleX(0); } to { transform: scaleX(1); } }

/* ---------- Pull quote ---------- */
/* Quote band: a drawn ridge-pattern ground rather than a photograph, so the
   words carry the section on their own. */
.quote-band { background: radial-gradient(120% 90% at 22% 0%, #241012 0%, var(--ink) 52%, #0c0708 100%); overflow: hidden; }
.quote-bg { position: absolute; inset: 0; z-index: 0; pointer-events: none; }
.quote-bg svg { width: 100%; height: 100%; display: block; }
/* The drawn house. Each stroke is a dash the length of its own path, held at
   zero until the quote is in view, then pulled back: the roofline signs first
   in red, the elevation sketches in behind it. */
.quote-draw { fill: none; stroke-linecap: round; stroke-linejoin: round; }
.quote-draw path { stroke-dasharray: 1; stroke-dashoffset: 1; }
.quote-bg.is-drawn .quote-draw path { animation: qdraw 1.5s cubic-bezier(.45, .05, .55, .95) forwards; }
.quote-draw .d-roof { stroke: var(--red); stroke-width: 2.6; opacity: .62; }
.quote-bg.is-drawn .quote-draw .d-roof { animation-duration: 2s; }
.quote-draw .d-line { stroke: rgba(255, 255, 255, .2); stroke-width: 1.5; }
.quote-draw .d-fine { stroke: rgba(255, 255, 255, .11); stroke-width: 1.2; }
.quote-draw [data-d="ground"] { animation-delay: 0s; }
.quote-draw [data-d="roof"] { animation-delay: .15s; }
.quote-draw [data-d="eave"] { animation-delay: .9s; }
.quote-draw [data-d="wall-l"], .quote-draw [data-d="wall-r"] { animation-delay: 1.15s; }
.quote-draw [data-d="chimney"] { animation-delay: 1.4s; }
.quote-draw [data-d="gable"] { animation-delay: 1.5s; }
.quote-draw [data-d="dormer"] { animation-delay: 1.9s; }
.quote-draw [data-d="door"] { animation-delay: 1.8s; }
.quote-draw [data-d="win-l"], .quote-draw [data-d="win-r"] { animation-delay: 2.05s; }
.quote-draw [data-d="course-1"] { animation-delay: 2.3s; }
.quote-draw [data-d="course-2"] { animation-delay: 2.45s; }
.quote-draw [data-d="course-3"] { animation-delay: 2.6s; }
@keyframes qdraw { to { stroke-dashoffset: 0; } }
.quote-draw { transform: scale(1.15); transform-origin: 50% 60%; }
@media (max-width: 640px) { .quote-draw { transform: scale(1.35); transform-origin: 50% 58%; } }
/* The window page's review: two still double-hung windows either side of
   the words instead of the drawn house. Faint, so the words stay the subject;
   they only show where there is room beside the quote. */
.quote-bg .quote-win { display: none; position: absolute; top: 50%; width: clamp(96px, calc(50vw - 540px), 150px); height: auto; aspect-ratio: 1 / 2; transform: translateY(-50%); fill: none; stroke-linejoin: round; }
.quote-bg .quote-win-l { right: calc(50% + 470px); }
.quote-bg .quote-win-r { left: calc(50% + 470px); }
.quote-win .w-frame { stroke: rgba(255, 255, 255, .2); stroke-width: 2.2; }
.quote-win .w-bar { stroke: rgba(255, 255, 255, .1); stroke-width: 1.6; }
.quote-win .w-sill { stroke: rgba(201, 164, 77, .4); stroke-width: 2; }
@media (min-width: 1280px) { .quote-bg .quote-win { display: block; } }
.quote-band > .wrap { position: relative; z-index: 2; }
.quote-mark { display: block; width: 46px; margin: 0 auto clamp(1.1rem, .8rem + 1vw, 1.8rem); color: var(--red); }
.quote-mark svg { width: 100%; height: auto; }

/* The measure has to be set where the display font applies. On the wrapper a
   ch unit resolves against body size and squeezes the quote to one word a line. */
.pullquote { text-align: center; max-width: 1200px; margin-inline: auto; }
.pullquote blockquote {
  max-width: 20ch;
  margin-inline: auto;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(1.95rem, 1.3rem + 3.2vw, 4.4rem);
  line-height: 1.05;
  letter-spacing: -.025em;
  color: #fff;
  font-stretch: 112%;
  text-wrap: balance;
}
.pullquote blockquote em { font-style: normal; color: var(--red-soft); }
.pullquote cite { display: block; margin-top: 1.8rem; font-style: normal; font-size: .88rem; letter-spacing: .13em; text-transform: uppercase; color: var(--gold); font-weight: 650; }
/* A single Google review in the band (/window-replacement). Same marks and
   cite as the company quotes, set smaller because a review runs longer. */
.pq-review { max-width: 980px; }
.pq-review .pq-stars { display: flex; justify-content: center; margin-bottom: 1.1rem; }
.pq-review .pq-stars svg { width: 19px; height: 19px; }
.pq-review blockquote { max-width: 36ch; font-size: clamp(1.3rem, 1rem + 1.45vw, 2.2rem); line-height: 1.24; letter-spacing: -.012em; font-weight: 650; }
.pq-review blockquote p { margin: 0; }
.pq-review figcaption { margin-top: 1.7rem; display: flex; flex-direction: column; align-items: center; gap: .5rem; }
.pq-review cite { margin-top: 0; }
.pq-review .review-src { display: inline-flex; align-items: center; gap: .4rem; font-size: .8rem; color: rgba(255, 255, 255, .68); }
.pq-review .pq-act { justify-content: center; margin-top: 1.6rem; }

/* ---------- Accordion (server-rendered, CSS-collapsed) ---------- */
.faq { display: grid; gap: .8rem; max-width: 920px; }
.faq-main .faq { max-width: none; }
.faq details { scroll-margin-top: calc(var(--header-h) + 1.5rem); }
.faq details {
  background: #fff;
  border: 1px solid var(--line);
  border-radius: var(--r);
  overflow: hidden;
  transition: border-color .3s, box-shadow .3s;
}
.faq details[open] { border-color: var(--line-2); box-shadow: var(--sh-sm); }
.faq summary {
  padding: 1.25rem 3.4rem 1.25rem 1.4rem;
  cursor: pointer;
  position: relative;
  font-family: var(--font-display);
  font-weight: 650;
  font-size: 1.04rem;
  color: var(--ink);
  list-style: none;
  font-stretch: 112%;
  line-height: 1.4;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after {
  content: '';
  position: absolute;
  right: 1.4rem; top: 50%;
  translate: 0 -50%;
  width: 14px; height: 9px;
  background: var(--red);
  clip-path: polygon(0 0, 50% 100%, 100% 0, 50% 38%);
  transition: transform .35s var(--ease-out);
}
.faq details[open] summary::after { transform: rotate(180deg); }
.faq .faq-a { padding: 0 1.4rem 1.4rem; font-size: .97rem; color: var(--body-dim); }
.faq .faq-a > * + * { margin-top: .85rem; }

/* ---------- Service area map ---------- */
.areas { display: grid; grid-template-columns: 1.1fr .9fr; gap: clamp(2rem, 1rem + 4vw, 4rem); align-items: center; }
.area-map { position: relative; }
.area-map svg { width: 100%; height: auto; }
.area-pin { cursor: pointer; }
/* Only the dot grows on hover: a grown label or hit circle would spread over
   the neighbouring pin and take its clicks. */
.area-pin circle:not(.pin-hit) { transition: transform .3s var(--ease-out); transform-box: fill-box; transform-origin: center; }
.area-pin:hover circle:not(.pin-hit), .area-pin.is-live circle:not(.pin-hit) { transform: scale(1.35); }
.area-pin text { transition: fill .3s var(--ease-out); }
.area-pin:hover text, .area-pin.is-live text { fill: #fff; }
/* Phones: the 500 x 400 map renders about 350px wide, so labels go up to
   20 units (about 14px) and the crowded ones move beside their pins, with
   Oklahoma City under its pin. */
@media (max-width: 640px) {
  .area-map text { font-size: 20px; }
  .area-pin[data-city="Yukon"] text { text-anchor: end; }
  .area-pin[data-city="Midwest City"] text, .area-pin[data-city="Del City"] text { text-anchor: start; }
  .area-pin[data-city="Yukon"] text { transform: translate(-12px, 21px); }
  .area-pin[data-city="Midwest City"] text { transform: translate(-8px, 0); }
  .area-pin[data-city="Del City"] text { transform: translate(12px, 21px); }
  .area-pin[data-city="Oklahoma City"] text { transform: translate(0, 53px); }
  .area-pin[data-city="Mustang"] text { text-anchor: end; transform: translate(-12px, 21px); }
}
.area-chips { display: flex; flex-wrap: wrap; gap: .55rem; margin-top: 1.6rem; }
.area-chip {
  padding: .58rem 1.1rem;
  border-radius: var(--r-pill);
  border: 1.5px solid var(--line-dark);
  color: rgba(255, 255, 255, .78);
  font-size: .88rem;
  font-weight: 600;
  transition: .3s var(--ease-out);
}
.area-chip:hover, .area-chip.is-live { background: var(--red); border-color: var(--red); color: #fff; }

/* ---------- Gallery ----------
   Filter chips over a uniform three across grid of 3:2 frames, each numbered
   and labelled with its group, caption set beneath rather than over the
   photograph. Four across on large screens, two on tablet, one on phones. */
.gal-filters { display: flex; flex-wrap: wrap; gap: .55rem; margin-bottom: clamp(1.4rem, 1rem + 1.4vw, 2.2rem); }
.gal-chip { display: inline-flex; align-items: center; gap: .5rem; min-height: 42px; padding: .55rem 1rem; border-radius: var(--r-pill); border: 1px solid var(--line-2); background: #fff; color: var(--ink); font-weight: 600; font-size: .86rem; transition: background .25s, border-color .25s, color .25s; }
.gal-chip b { font-family: var(--font-display); font-weight: 700; font-stretch: 112%; font-size: .72rem; letter-spacing: .06em; padding: .15rem .5rem; border-radius: var(--r-pill); background: var(--paper-2); color: var(--body-dim); }
.gal-chip:hover { border-color: var(--ink); }
.gal-chip.is-on { background: var(--ink); border-color: var(--ink); color: #fff; }
.gal-chip.is-on b { background: var(--red); color: #fff; }
.mosaic { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: clamp(1rem, .8rem + 1vw, 1.8rem) var(--gap); }
.tile { position: relative; margin: 0; display: grid; gap: .7rem; cursor: zoom-in; }
.tile[hidden] { display: none; }
.tile-media { position: relative; display: block; aspect-ratio: 3 / 2; border-radius: var(--r-lg); overflow: hidden; background: var(--paper-3); }
.tile-media picture, .tile-media img { position: absolute; inset: 0; width: 100%; height: 100%; }
.tile-media img { object-fit: cover; }
.tile-media::after { content: ''; position: absolute; inset: 0; background: linear-gradient(to top, rgba(16,12,12,.28), transparent 45%); opacity: 0; transition: opacity .4s; }
.tile:hover .tile-media::after { opacity: 1; }
.tile figcaption { font-size: .9rem; color: var(--body); line-height: 1.45; padding-inline: .2rem; }
.tile:focus-visible { outline: 3px solid var(--red); outline-offset: 4px; border-radius: var(--r-lg); }
.gal-empty { margin-top: 1.4rem; color: var(--body-dim); font-size: .95rem; }
/* The heading and filters sit in .wrap, the photographs in .wrap-wide. */
.sec > .gal { position: relative; z-index: 1; }
/* The closing tile: same frame as a photograph, never filtered out. It is a
   size container, so the words it holds follow the column, not the window. */
.tile-cta {
  container-type: inline-size;
  align-self: start; position: relative; display: flex; flex-direction: column; gap: .55rem;
  aspect-ratio: 3 / 2; padding: clamp(1.3rem, 1rem + 1vw, 2rem); border-radius: var(--r-lg);
  background: var(--ink); color: rgba(255, 255, 255, .78); font-size: .95rem; line-height: 1.5;
}
.tile-cta .ridge-chip { margin-bottom: auto; background: rgba(255, 255, 255, .07); color: var(--gold); }
.tile-cta b { font-family: var(--font-display); font-size: var(--t-h3); line-height: 1.15; color: #fff; }
.tile-cta > span:not([class]) { max-width: 42ch; }
/* A narrow column has room for the heading only; the line under it would push
   the frame taller than the photographs beside it. */
@container (max-width: 19rem) { .tile-cta > span:not([class]) { display: none; } }
.tile-cta-go { position: absolute; top: clamp(1.3rem, 1rem + 1vw, 2rem); right: clamp(1.3rem, 1rem + 1vw, 2rem); display: grid; place-items: center; width: 46px; height: 46px; border-radius: 50%; background: var(--red); color: #fff; transition: transform .3s var(--ease-out); }
.tile-cta-go svg { width: 18px; height: 18px; }
.tile-cta:hover .tile-cta-go { transform: translateX(3px); }
.tile-cta:focus-visible { outline: 3px solid var(--red); outline-offset: 4px; }
/* Loupe */
.loupe {
  position: fixed; top: 0; left: 0; z-index: 150;
  width: 300px; height: 300px; border-radius: 50%;
  border: 4px solid rgba(255, 255, 255, .95);
  box-shadow: 0 24px 60px rgba(16, 12, 12, .45), 0 0 0 1px rgba(16, 12, 12, .25);
  background-color: var(--ink); background-repeat: no-repeat;
  pointer-events: none; opacity: 0; scale: .8;
  transition: opacity .25s var(--ease-out), scale .35s var(--ease-out);
  will-change: transform;
}
.loupe.is-on { opacity: 1; scale: 1; }
.loupe::after { content: ''; position: absolute; inset: 50% auto auto 50%; width: 28px; height: 28px; translate: -50% -50%; border-radius: 50%; border: 1.5px solid rgba(255, 255, 255, .65); }
.tile-media { transition: opacity .35s; }
.mosaic.is-looking .tile:not(:hover) .tile-media { opacity: .45; }
@media (pointer: fine) { .mosaic.is-looking .tile-media { cursor: none; } }
@media (min-width: 1920px) { .mosaic { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
/* ---------- Contact panel ---------- */
.contact-panel {
  background: var(--ink);
  color: rgba(255, 255, 255, .74);
  border-radius: var(--r-xl);
  padding: clamp(1.6rem, 1.1rem + 2vw, 2.6rem);
  display: grid;
  gap: 1.5rem;
  align-content: start;
  position: relative;
  overflow: hidden;
}
.contact-phone { display: block; }
.contact-phone small { font-size: .72rem; letter-spacing: .14em; text-transform: uppercase; color: var(--gold); font-weight: 650; }
.contact-phone b {
  display: block;
  white-space: nowrap;
  font-family: var(--font-display);
  font-size: clamp(1.6rem, 1.2rem + 1.5vw, 2.3rem);
  /* The number never wraps, so it also never grows past the panel's own
     width (13cqi: the number is about 7.3 times as wide as its size). That
     keeps it inside the padding in the narrow article aside at 1025-1240px
     and at a larger browser text size. */
  font-size: min(clamp(1.6rem, 1.2rem + 1.5vw, 2.3rem), 13cqi);
  font-weight: 800;
  color: #fff;
  font-stretch: 112%;
  letter-spacing: -.02em;
  margin-top: .25rem;
  line-height: 1;
}
.contact-phone:hover b { color: var(--red-soft); }
.contact-rows { display: grid; gap: 1.1rem; }
/* On a 320px phone the office email is wider than the panel: let it wrap
   rather than push the whole panel column past its padding. The panel is
   also the size container for the phone number above. */
.contact-panel { grid-template-columns: minmax(0, 1fr); container-type: inline-size; }
.contact-row > span { min-width: 0; }
.contact-row a[href^="mailto:"] { overflow-wrap: anywhere; }
.contact-row { display: flex; gap: .95rem; align-items: flex-start; font-size: .95rem; }
.contact-row svg { width: 20px; height: 20px; color: var(--gold); flex: none; margin-top: .2rem; }
.contact-row b { display: block; color: #fff; font-weight: 650; font-size: .88rem; }
.trust-pills { display: flex; flex-wrap: wrap; gap: .5rem; }
.trust-pill {
  padding: .45rem .9rem;
  border-radius: var(--r-pill);
  background: rgba(255, 255, 255, .07);
  border: 1px solid var(--line-dark);
  font-size: .78rem;
  font-weight: 600;
  color: rgba(255, 255, 255, .8);
}

/* ---------- CTA band ---------- */
.cta-band { position: relative; background: radial-gradient(110% 100% at 14% 0%, #2a1113 0%, #171010 48%, var(--ink) 100%); color: #fff; overflow: hidden; }
.cta-band-bg { position: absolute; inset: 0; z-index: 0; }
.cta-band-bg img { width: 100%; height: 100%; object-fit: cover; opacity: .6; }
.cta-band-bg::after { content: ''; position: absolute; inset: 0; background: linear-gradient(100deg, rgba(16, 12, 12, .9) 0%, rgba(16, 12, 12, .72) 40%, rgba(16, 12, 12, .25) 70%, rgba(16, 12, 12, .1) 100%); }
.cta-band::before { content: ''; position: absolute; left: 0; right: 0; top: 0; height: 3px; background: linear-gradient(90deg, var(--red), rgba(226,36,37,0) 70%); z-index: 3; }
.cta-band .wrap { position: relative; z-index: 2; }
.cta-band h2 { font-size: clamp(2.2rem, 1.5rem + 2.9vw, 4.2rem); color: #fff; max-width: 17ch; letter-spacing: -.028em; line-height: 1.02; }
.cta-band p { font-size: clamp(1.05rem, .98rem + .4vw, 1.25rem); color: rgba(255, 255, 255, .84); max-width: 50ch; margin-block: 1.1rem 2.2rem; }

/* ---------- Breadcrumbs ---------- */
.crumbs { display: flex; flex-wrap: wrap; gap: .5rem; align-items: center; font-size: .82rem; color: rgba(255, 255, 255, .6); }
.crumbs a:hover { color: #fff; }
.crumbs li { display: flex; align-items: center; gap: .5rem; }
.crumbs li + li::before { content: ''; width: 8px; height: 8px; border-right: 1.5px solid currentColor; border-top: 1.5px solid currentColor; rotate: 45deg; opacity: .5; }
.crumbs [aria-current] { color: #fff; }
/* Phones: a three level trail wraps over two or three lines and pushes the
   H1 down, so it shows as one back link to the parent. The full list (and
   the BreadcrumbList schema) is still in the page. */
@media (max-width: 640px) {
  .crumbs-deep li { display: none; }
  .crumbs-deep li:nth-last-child(2) { display: flex; }
  .crumbs-deep li:nth-last-child(2)::before { rotate: -135deg; }
}

/* ---------- Page hero ---------- */
.phero { position: relative; background: var(--ink); color: #fff; overflow: hidden; isolation: isolate; }
.phero-bg { position: absolute; inset: 0; z-index: 0; }
.phero-bg img { width: 100%; height: 100%; object-fit: cover; }
.phero-bg::after { content: ''; position: absolute; inset: 0; background: linear-gradient(102deg, rgba(16, 12, 12, .94) 12%, rgba(16, 12, 12, .8) 48%, rgba(16, 12, 12, .5)); }
.phero .wrap { position: relative; z-index: 2; padding-block: clamp(2.4rem, 1.6rem + 3.4vw, 4rem) clamp(3.4rem, 2rem + 5vw, 6rem); }
.phero h1 { font-size: clamp(2.15rem, 1.5rem + 2.9vw, 4.15rem); color: #fff; margin-block: 1.2rem .9rem; max-width: 19ch; letter-spacing: -.026em; }
.phero p { font-size: var(--t-lead); color: rgba(255, 255, 255, .76); max-width: 62ch; }
.phero .btn-row { margin-top: 2rem; }
/* An article's byline and dates under the lede (SEO-01). */
.phero p.phero-meta { margin-top: 1.1rem; max-width: none; font-size: .9rem; font-weight: 500; letter-spacing: .01em; color: rgba(255, 255, 255, .88); }
.phero-meta > span:not(.sep) { white-space: nowrap; }
.phero-meta .sep { margin-inline: .15em; opacity: .6; }
/* Too narrow for one line: one part per line, so no line ends on a dot. */
@media (max-width: 760px) { .phero-meta .sep { display: none; } .phero-meta > span:not(.sep) { display: block; } }

/* ---------- Footer ---------- */
.site-foot { background: var(--ink); color: rgba(255, 255, 255, .6); padding-block: clamp(3rem, 2rem + 3vw, 5rem) clamp(2.2rem, 1.6rem + 2vw, 3.5rem); position: relative; overflow: hidden; }
.foot-grid { display: grid; grid-template-columns: 1.5fr 1fr 1fr 1.2fr; gap: clamp(1.6rem, 1rem + 2.4vw, 3.4rem); }
.foot-brand img { width: 205px; background: #fff; padding: .7rem .9rem; border-radius: var(--r); }
.foot-brand p { font-size: .93rem; margin-top: 1.2rem; max-width: 38ch; }
.foot-title { font-size: .82rem; letter-spacing: .14em; text-transform: uppercase; color: #fff; margin-bottom: 1.2rem; }
.foot-col ul { display: grid; gap: .6rem; }
.foot-col a { font-size: .92rem; transition: color .25s, padding-left .25s; display: inline-block; }
.foot-col a:hover { color: #fff; padding-left: 5px; }
.foot-col .foot-hours { font-size: .92rem; padding-block: .6rem; }
.socials { display: flex; gap: .6rem; margin-top: 1.4rem; }
.socials a { width: 42px; height: 42px; display: grid; place-items: center; place-content: center; border-radius: 50%; border: 1px solid var(--line-dark); transition: .3s var(--ease-out); }
.socials a:hover { background: var(--red); border-color: var(--red); color: #fff; transform: translateY(-3px); }
.socials svg { width: 18px; height: 18px; }
.foot-bar {
  margin-top: clamp(2.4rem, 1.6rem + 2.4vw, 4rem);
  padding-block: 1.6rem;
  border-top: 1px solid var(--line-dark);
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
  font-size: .84rem;
}
.foot-bar ul { display: flex; gap: 1.3rem; flex-wrap: wrap; }
.foot-legal { font-size: .8rem; color: rgba(255, 255, 255, .55); max-width: 70ch; margin-top: .5rem; }

/* ---------- Mobile call bar ---------- */
.callbar {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 150;
  display: none;
  background: rgba(16, 12, 12, .96);
  backdrop-filter: blur(12px);
  border-top: 1px solid var(--line-dark);
  padding: .6rem;
  gap: .6rem;
  padding-bottom: max(.6rem, env(safe-area-inset-bottom));
}
.callbar .btn { flex: 1; padding: .95rem .6rem; font-size: .8rem; }

/* ---------- Reveal animation ---------- */
[data-reveal] { opacity: 0; transform: translateY(26px); transition: opacity .8s var(--ease-out), transform .8s var(--ease-out); }
[data-reveal].is-in { opacity: 1; transform: none; }
[data-reveal-delay="1"] { transition-delay: .09s; }
[data-reveal-delay="2"] { transition-delay: .18s; }
[data-reveal-delay="3"] { transition-delay: .27s; }
[data-reveal-delay="4"] { transition-delay: .36s; }

/* ---------- Utilities ---------- */
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
.skip {
  position: absolute; left: 50%; translate: -50% -120%;
  z-index: 300; background: var(--red); color: #fff;
  padding: .8rem 1.4rem; border-radius: 0 0 var(--r) var(--r);
  font-weight: 650; transition: translate .25s;
}
.skip:focus { translate: -50% 0; }
.note {
  padding: 1.15rem 1.35rem;
  border-left: 3px solid var(--red);
  background: var(--red-wash);
  border-radius: 0 var(--r) var(--r) 0;
  font-size: .95rem;
}
.note b { color: var(--ink); }

/* ---------- Responsive ---------- */
/* Header. The full row needs about 1,450px, so from 1439 down it compacts:
   160px logo, tighter links and gaps. From 1279 down the links move into the
   burger menu, but the phone number and the assessment button stay in the
   bar until the call bar takes over at 1024. scripts/head-audit.mjs checks it. */
@media (max-width: 1439px) {
  .brand img { width: 160px; }
  .nav { gap: .1rem; }
  .nav > li > a, .nav > li > button { padding: .8rem .45rem; font-size: .8rem; }
  .nav > li > a::after { left: .45rem; right: .45rem; }
  .nav > li.has-mega > a { padding-right: .1rem; }
  .nav > li.has-mega > a::after { right: .1rem; }
  /* The tighter links leave too little gap for the caret's 44px hit area
     to stay off the next label, so the caret itself takes 7px more. */
  .nav > li > .nav-caret { width: 37px; }
  .nav-caret::before { inset: 0 -7px 0 0; }
  .head-inner { gap: .75rem; }
  .head-cta { gap: .6rem; }
}
/* 1280 to 1365, the narrowest full nav: a touch less tracking and gap pays
   for the wider carets. The self-hosted fonts set a little wider, hence the
   .35rem row gap (the links' own padding still spaces them off the logo). */
@media (min-width: 1280px) and (max-width: 1365px) {
  .nav > li > a { letter-spacing: .03em; }
  .head-inner { gap: .35rem; }
  .head-cta { gap: .45rem; }
}
@media (max-width: 1279px) {
  .nav { display: none; }
  .burger { display: grid; }
}
/* The menu dialog only exists where the burger does. */
@media (min-width: 1280px) {
  .drawer, .scrim { display: none; }
}
@media (max-width: 1024px) {
  .head-phone, .head-cta .btn { display: none; }
  .g-4 { grid-template-columns: repeat(2, 1fr); }
  .steps { grid-template-columns: repeat(2, 1fr); }
  .step::after { display: none; }
  .explorer { grid-template-columns: 1fr; }
  .explorer-tabs { grid-template-columns: repeat(2, 1fr); }
  .areas { grid-template-columns: 1fr; }
  /* Plain splits stay two up to 761px; the form and article splits stack. */
  .split-form, .split-article { grid-template-columns: 1fr; }
  .foot-grid { grid-template-columns: repeat(2, 1fr); }
  .mosaic { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .callbar { display: flex; }
  /* Room for the call bar is reserved inside the dark footer, not on the
     body, so no pale strip shows between the footer and the bar. */
  .site-foot { padding-bottom: calc(clamp(2.2rem, 1.6rem + 2vw, 3.5rem) + 72px); }
  .field-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 760px) {
  .g-2, .g-3, .g-4 { grid-template-columns: 1fr; }
  .split { grid-template-columns: 1fr; }
  .split.rev .split-media { order: -1; }
  .stat-grid { grid-template-columns: repeat(2, 1fr); }
  .steps { grid-template-columns: 1fr; }
  .topbar-facts > span:nth-child(n+3) { display: none; }
  .hero-ctl { left: var(--pad-x); right: var(--pad-x); justify-content: space-between; }
  .hero-caption { display: none; }
  .dock { margin-top: -3rem; }
  /* The credential bar stays inside the image on mobile too. */
  .split-media { box-shadow: var(--sh); }
  .foot-bar { flex-direction: column; }
  .pullquote { max-width: 100%; }
  .pullquote blockquote { max-width: 100%; }
  .compare img { aspect-ratio: 4 / 3.4; }
}
@media (max-width: 560px) {
  .field-grid { grid-template-columns: 1fr; }
  .field.wide { grid-column: span 1; }
  .mosaic { grid-template-columns: 1fr; }
  /* Stats stay 2 x 2 on phones, with smaller figures and tighter labels. */
  .stat { padding: 1.5rem .7rem; }
  .stat b { font-size: 2rem; }
  .stat > span { letter-spacing: .06em; line-height: 1.35; }
  /* The two link lists sit side by side; brand and contact span both. */
  .foot-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1.6rem 1.2rem; }
  .foot-brand, .foot-grid > .foot-col:last-child { grid-column: 1 / -1; }
  /* "Commercial and more" wraps at this width; both list headings reserve
     two lines so the two lists start level. */
  .foot-grid > .foot-col:not(:last-child) .foot-title { min-height: 2.1em; }
  .btn { width: 100%; }
  .btn-row { flex-direction: column; align-items: stretch; }
  .callbar .btn { width: auto; }
  .hero-badge { font-size: .76rem; }
}

/* Very large screens: let the design breathe rather than stretch */
@media (min-width: 1800px) {
  :root { --max: 1480px; --max-wide: 1760px; }
}


@media (max-width: 1024px) {
  .rating-split, .topic-evidence { grid-template-columns: 1fr; }
}


@media (max-width: 1024px) {
  .detail-body { padding-left: 1.4rem; }
}
@media (max-width: 640px) {
  .theme-bar { grid-template-columns: 1fr auto; }
  .theme-track { grid-column: 1 / -1; order: 3; }
}


@media (max-width: 1024px) {
  .hotspot-wrap { grid-template-columns: 1fr; }
  .ed-row { grid-template-columns: 1fr; }
  .ed-row.rev .ed-media { order: 0; }
}
@media (max-width: 560px) {
  .hotspot { width: 32px; height: 32px; font-size: .78rem; }
}


@media (max-width: 900px) {
  .trio { grid-template-columns: 1fr; gap: 2.2rem; }
  .trio-media img { aspect-ratio: 16 / 10; }
}


@media (max-width: 900px) {
  .stik { grid-template-columns: 1fr; }
  .stik-frame { aspect-ratio: 16 / 10; top: calc(var(--header-h) + .6rem); }
  .stik-copy { gap: 2.4rem; }
  .stik-block { min-height: 0; padding-block: 0; }
  .ledger-row { grid-template-columns: 1fr; gap: .9rem; }
}

/* Hero copy is left aligned and held to a narrower measure so the headline
   stacks the way it does on the reference builds. */
.hero-lede { max-width: 54ch; }
[data-hero-badge], [data-hero-lede] { transition: opacity .26s var(--ease), transform .26s var(--ease); }
[data-hero-badge].is-fading, [data-hero-lede].is-fading { opacity: 0; transform: translateY(6px); }


@media (max-width: 640px) {
  .errpage-links { grid-template-columns: 1fr; }
  .errpage-ghost { font-size: 11rem; right: -6vw; top: 12%; translate: 0 0; }
}

@media (max-width: 1024px) { .rev-grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 640px) { .rev-grid { grid-template-columns: 1fr; } }
/* One column has no row to keep level, so short reviews get short cards. */
@media (max-width: 640px) { .rev-grid .review blockquote { min-height: 0; } }


/* Tap targets: 44px minimum on every control a thumb has to hit. */
.btn { min-height: 44px; }
.drawer .btn { min-height: 48px; }
.foot-col a { display: inline-block; padding-block: .6rem; min-height: 44px; }
.foot-col ul { gap: .15rem; }
.rcar-btn { min-height: 44px; min-width: 60px; padding-block: 8px; }
.hero-arrow { min-height: 44px; padding-block: 8px; }
.crumbs a { padding: .75rem .4rem; margin-inline: -.25rem; display: inline-block; }
.review-more { min-height: 44px; padding-block: .6rem; margin-top: -.6rem; }

@media (max-width: 640px) { .hero-badge { font-size: .82rem; } }

/* Phone and tablet readability: functional text never drops under 13px, up
   to 1024px. Decorative micro-labels (eyebrows, the howl tagline, the city
   file kickers) are exempt on purpose; eyebrows and stat labels only lift on
   phones. */
@media (max-width: 1024px) {
  .field label, .field .err, .form-foot small, .review-tag, .review-more,
  .compare-label, .trust-pill, .foot-legal, .callbar .btn, .btn-sm,
  .topbar, .howl-txt, .card-tag, .contact-phone small, .status-pill { font-size: .8175rem; }
}
/* (The city file sources, notes and dates and the badge verify links are
   declared further down, so they take the same floor in the accessibility
   block at the end of this file.) */
@media (max-width: 640px) {
  .eyebrow, .stat > span { font-size: .8175rem; }
}


/* Mobile: the top bar collapses to one line (address only, status pill on the
   right) so the brand is on screen immediately. The hero overlay lightens so
   the photograph is visible rather than a sliver, with a stronger bottom
   gradient carrying the copy instead. */
@media (max-width: 640px) {
  .topbar .wrap-wide { flex-wrap: nowrap; gap: .6rem; }
  .topbar-facts > span:nth-child(n+2) { display: none; }
  .topbar-facts { min-width: 0; flex: 1; }
  .topbar-facts > span:first-child { min-width: 0; overflow: hidden; }
  .topbar-facts > span:first-child > span { display: block; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; }
  .topbar .status-pill { flex: none; }
  .topbar .status-pill [data-status-text] { display: none; }
  .topbar .status-pill[data-open="true"]::after { content: "Open"; }
  .topbar .status-pill[data-open="false"]::after { content: "Closed"; }
  .hero-slides::after {
    background:
      linear-gradient(180deg, rgba(16, 12, 12, .35) 0%, rgba(16, 12, 12, .2) 30%, rgba(16, 12, 12, .72) 62%, rgba(16, 12, 12, .94) 100%);
  }
  .hero-slide img { object-position: 62% 40%; }
  .hero-inner { padding-top: clamp(5rem, 22vh, 8.5rem); }
}


/* ---------- Local Howl credit ---------- */
.howl {
  display: inline-flex;
  align-items: center;
  gap: .6rem;
  margin-top: 1.6rem;
  padding: .5rem .9rem .5rem .6rem;
  border-radius: var(--r-pill);
  border: 1px solid var(--line-dark);
  color: rgba(255, 255, 255, .55);
  font-size: .8rem;
  transition: color .3s, border-color .3s;
}
.howl b { color: rgba(255, 255, 255, .8); font-weight: 650; transition: color .3s; }
.howl-mark { width: 26px; height: 26px; flex: none; position: relative; }
.howl-mark svg { width: 100%; height: 100%; overflow: visible; }
.howl-wolf { transform-origin: 45% 80%; transition: transform .45s var(--ease-out); }
.howl-w1, .howl-w2 { opacity: 0; transform: translate(-3px, 3px); transition: opacity .3s, transform .45s var(--ease-out); }
.howl-w2 { transition-delay: .1s; }
.howl-tag {
  max-width: 0;
  overflow: hidden;
  white-space: nowrap;
  opacity: 0;
  font-family: var(--font-display);
  font-size: .68rem;
  font-weight: 700;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--gold);
  font-stretch: 112%;
  transition: max-width .5s var(--ease-out), opacity .35s .1s;
}
.howl:hover { color: rgba(255, 255, 255, .85); border-color: var(--line-dark-2); }
.howl:hover b { color: #fff; }
/* The howl: head tips back, sound arcs ripple out one after the other. */
.howl:hover .howl-wolf { transform: rotate(-10deg); }
.howl:hover .howl-w1, .howl:hover .howl-w2 { opacity: 1; transform: none; }
.howl:hover .howl-w1 { animation: howlPulse 1.6s var(--ease) .15s infinite; }
.howl:hover .howl-w2 { animation: howlPulse 1.6s var(--ease) .35s infinite; }
.howl:hover .howl-tag { max-width: 200px; opacity: 1; }
@keyframes howlPulse { 0%, 100% { opacity: 1; } 50% { opacity: .25; } }


/* ---------- Core services row ---------- */
/* Title on the left, the supporting line and button on the right, both
   resting on the same baseline so neither column is left empty. */
.csr-head { display: grid; grid-template-columns: minmax(0, 1.25fr) minmax(0, .75fr); gap: 1.6rem clamp(2rem, 5vw, 6rem); align-items: end; margin-bottom: clamp(1.8rem, 1.2rem + 2vw, 3rem); }
.csr-head-left h2 { font-size: var(--t-h2); letter-spacing: -.024em; line-height: 1.08; margin-top: .8rem; max-width: 22ch; }
.csr-head-left h2 em { font-style: normal; color: var(--red); }
.csr-head-right { padding-bottom: .35rem; }
.csr-head-right p { color: var(--body-dim); max-width: 42ch; }
.csr-head-cta { margin-top: 1.3rem; }
.csr-links { display: flex; flex-wrap: wrap; gap: .5rem; margin-top: 1.1rem; }
.csr-link { display: inline-flex; align-items: center; gap: .45rem; min-height: 44px; padding: .55rem 1.05rem; border-radius: var(--r-pill); border: 1.5px solid var(--line-2); color: var(--ink); font-size: .86rem; font-weight: 600; transition: border-color .25s, color .25s; }
.csr-link svg { width: 15px; height: 15px; flex: none; }
.csr-link:hover { border-color: var(--red); color: var(--red-deep); }
.csr-wrap { position: relative; }
.csr-row {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: clamp(280px, 24vw, 340px);
  gap: 1rem;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  padding-bottom: .4rem;
  cursor: grab;
  scrollbar-width: none;
}
.csr-row.is-drag { cursor: grabbing; scroll-snap-type: none; }
.csr-row::-webkit-scrollbar { display: none; }
.csr-card {
  position: relative;
  scroll-snap-align: start;
  display: flex;
  flex-direction: column;
  min-height: 420px;
  border-radius: var(--r-lg);
  overflow: hidden;
  background: #fff;
  border: 1px solid var(--line);
  transition: transform .4s var(--ease-out), box-shadow .4s;
}
.csr-card:hover { transform: translateY(-4px); box-shadow: var(--sh-lg); }
.csr-body { display: block; padding: 1.4rem 1.4rem 1.1rem; }
.csr-title { display: block; font-family: var(--font-display); font-weight: 700; font-stretch: 112%; font-size: 1.22rem; letter-spacing: -.012em; color: var(--ink); line-height: inherit; text-wrap: wrap; }
.csr-desc { display: block; margin-top: .5rem; font-size: .92rem; line-height: 1.55; color: var(--body-dim); }
.csr-card .csr-media { position: relative; margin: 0; flex: 1; min-height: 190px; }
.csr-card .csr-media picture, .csr-card .csr-media img { width: 100%; height: 100%; position: absolute; inset: 0; }
.csr-card .csr-media img { object-fit: cover; }
.csr-go {
  position: absolute; right: .9rem; bottom: .9rem; z-index: 3;
  width: 40px; height: 40px;
  display: grid; place-items: center; place-content: center;
  border-radius: 50%;
  background: rgba(255, 255, 255, .92);
  color: var(--ink);
  box-shadow: var(--sh-sm);
  transition: background .3s, color .3s, transform .35s var(--ease-out);
}
.csr-go svg { width: 18px; height: 18px; }
.csr-card:hover .csr-go { background: var(--red); color: #fff; transform: translateX(3px); }
/* Featured card: the photograph is the card. */
.csr-feature { background: var(--ink); border: 0; }
.csr-feature .csr-media { position: absolute; inset: 0; flex: none; }
.csr-feature::after { content: ''; position: absolute; inset: 0; z-index: 1; background: linear-gradient(to top, rgba(16,12,12,.9) 0%, rgba(16,12,12,.3) 55%, rgba(16,12,12,.05) 100%); }
.csr-overlay { position: relative; z-index: 2; margin-top: auto; padding: 1.4rem 4.4rem 1.4rem 1.4rem; display: block; }
.csr-feature .csr-title { color: #fff; font-size: 1.35rem; }
.csr-feature .csr-desc { color: rgba(255,255,255,.8); }
.csr-ctl { display: flex; align-items: center; gap: 1.2rem; margin-top: 1rem; }
.csr-track { flex: 1; position: relative; height: 2px; margin-left: .8rem; background: var(--line-2); border-radius: 2px; overflow: hidden; }
.csr-track i { position: absolute; top: 0; bottom: 0; left: 0; background: var(--red); border-radius: 2px; transition: transform .25s var(--ease-out); will-change: transform; }
.csr-ctl .rcar-btn { transition: opacity .3s, transform .3s var(--ease-out); }
@media (max-width: 900px) {
  .csr-head { grid-template-columns: 1fr; align-items: start; }
  .csr-row { grid-auto-columns: 86vw; }
}
/* Tablets show two service cards across rather than one 660px card. */
@media (min-width: 641px) and (max-width: 900px) { .csr-row { grid-auto-columns: 46vw; } }

/* ---------- Motion preferences ---------- */
@media (prefers-reduced-motion: reduce) {
  .howl:hover .howl-w1, .howl:hover .howl-w2 { animation: none; }
  .hero-slide img, .hero-slide.is-active img { animation: none !important; transform: none !important; }
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
    scroll-behavior: auto !important;
  }
  [data-reveal] { opacity: 1; transform: none; }
  .quote-draw path { animation: none !important; stroke-dashoffset: 0; }
  .ticker-track, .marquee-track { animation: none; }
}

/* No-JS fallback: nothing may ever render invisible or unstyled */
.no-js [data-reveal] { opacity: 1; transform: none; }
.no-js .quote-draw path { stroke-dashoffset: 0; }
.no-js .hero-slide:first-child { opacity: 1; }
.no-js .explorer-panel:first-of-type { display: grid; }
.no-js .drawer, .no-js .scrim { display: none; }

/* ---------- Large screens ----------
   The whole type scale and rhythm system is rem-based, so scaling the root
   font size lifts every clamp cap, gap and heading together. The containers
   widen with it so the content column keeps its proportion of the viewport. */
@media (min-width: 1920px) {
  html { font-size: 17px; }
  :root { --max: 1520px; --max-wide: 1800px; }
  .csr-row { grid-auto-columns: clamp(300px, 19vw, 400px); }
  .csr-card { min-height: 460px; }
}
@media (min-width: 2400px) {
  html { font-size: 18.5px; }
  :root { --max: 1700px; --max-wide: 2020px; }
  .csr-row { grid-auto-columns: clamp(340px, 17vw, 460px); }
  .csr-card { min-height: 500px; }
}

/* ---------- Lead form: text opt in ---------- */
.consent { display: flex; gap: .75rem; align-items: flex-start; margin-top: 1.1rem; font-size: .8175rem; line-height: 1.5; color: var(--body-dim); cursor: pointer; }
.consent input { flex: none; width: 18px; height: 18px; margin-top: .15rem; accent-color: var(--red); cursor: pointer; }
.consent a { color: var(--ink); text-decoration: underline; text-underline-offset: 2px; }
.consent a:hover { color: var(--red-deep); }

/* ---------- Certifications ---------- */
.cert-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--gap); }
.cert { background: #fff; border: 1px solid var(--line); border-radius: var(--r-lg); overflow: hidden; transition: box-shadow .3s, transform .3s var(--ease-out); }
.cert:hover, .cert[open] { box-shadow: var(--sh); }
.cert summary { list-style: none; display: grid; grid-template-columns: auto 1fr auto; align-items: center; gap: 1rem; padding: 1.3rem 1.4rem; cursor: pointer; }
.cert summary::-webkit-details-marker { display: none; }
/* A fixed 76 x 64 slot, so every name column starts at the same x and the
   heads wrap evenly. Two word marks wrap onto two lines inside it. */
.cert-mark {
  display: grid; place-items: center; place-content: center;
  width: 76px; height: 64px; padding-inline: .3rem;
  border-radius: var(--r);
  background: var(--ink); color: #fff;
  font-family: var(--font-display); font-weight: 800; font-stretch: 112%;
  font-size: .66rem; letter-spacing: .02em; text-transform: uppercase; text-align: center; line-height: 1.1;
}
.cert-head { display: grid; gap: .2rem; min-width: 0; }
.cert-head b { font-family: var(--font-display); font-weight: 700; font-stretch: 112%; font-size: 1.05rem; letter-spacing: -.01em; color: var(--ink); }
.cert-head span { font-size: .84rem; color: var(--body-dim); }
.cert-toggle { width: 34px; height: 34px; border-radius: 50%; border: 1px solid var(--line-2); display: grid; place-items: center; color: var(--ink); transition: transform .35s var(--ease-out), background .3s, color .3s; }
.cert-toggle svg { width: 16px; height: 16px; }
.cert[open] .cert-toggle { transform: rotate(180deg); background: var(--red); border-color: var(--red); color: #fff; }
.cert-list { list-style: none; margin: 0; padding: 0 1.4rem 1.4rem; display: grid; gap: .75rem; border-top: 1px solid var(--line); padding-top: 1.1rem; }
.cert-list li { display: grid; gap: .15rem; padding-left: 1.1rem; position: relative; }
.cert-list li::before { content: ''; position: absolute; left: 0; top: .5em; width: 9px; height: 6px; background: var(--red); clip-path: polygon(0 100%, 50% 0, 100% 100%); }
.cert-list b { font-size: .92rem; color: var(--ink); }
.cert-list span { font-size: .88rem; color: var(--body-dim); line-height: 1.5; }
.cert-bbb { margin-top: var(--gap); display: grid; grid-template-columns: auto 1fr auto; align-items: center; gap: 1.4rem; padding: 1.4rem 1.6rem; border-radius: var(--r-lg); background: var(--ink); color: #fff; }
.cert-bbb-mark { display: grid; place-items: center; width: 72px; height: 72px; border-radius: var(--r); background: var(--red); font-family: var(--font-display); font-weight: 800; font-stretch: 112%; font-size: 1.7rem; letter-spacing: -.02em; }
.cert-bbb-txt b { display: block; font-family: var(--font-display); font-weight: 700; font-stretch: 112%; font-size: 1.15rem; margin-bottom: .25rem; }
.cert-bbb-txt p { font-size: .92rem; color: rgba(255, 255, 255, .72); max-width: 60ch; }
@media (max-width: 1024px) { .cert-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 640px) {
  .cert-grid { grid-template-columns: 1fr; }
  .cert-bbb { grid-template-columns: auto 1fr; }
  .cert-bbb .btn { grid-column: 1 / -1; justify-self: start; }
}

/* ---------- Our work: lightbox ---------- */
.lightbox { border: 0; padding: 0; background: transparent; max-width: none; max-height: none; width: 100vw; height: 100vh; display: none; place-items: center; }
.lightbox[open] { display: grid; }
.lightbox::backdrop { background: rgba(16, 12, 12, .94); backdrop-filter: blur(6px); }
.lightbox figure { --lb-top: 4.5rem; --lb-bottom: 2rem; margin: 0; display: grid; gap: .9rem; justify-items: center; padding: var(--lb-top) 4.5rem var(--lb-bottom); }
/* Width allows for the figure's side padding, so the photo never runs under the arrows or off the right edge.
   Height allows for the figure's top and bottom padding, the gap and two lines of caption, so the caption stays on screen. */
.lightbox img { max-width: min(calc(100vw - 9rem), 1600px); max-height: 80vh; max-height: min(80vh, calc(100dvh - var(--lb-top) - var(--lb-bottom) - .9rem - 2.9rem)); width: auto; height: auto; border-radius: var(--r-lg); box-shadow: var(--sh-lg); }
.lightbox figcaption { color: rgba(255, 255, 255, .82); font-size: .92rem; line-height: 1.55; text-align: center; }
.lb-close, .lb-nav {
  position: fixed; z-index: 2; width: 46px; height: 46px; border-radius: 50%;
  background: rgba(255, 255, 255, .1); border: 1px solid rgba(255, 255, 255, .22); color: #fff;
  display: grid; place-items: center; transition: background .3s;
}
.lb-close:hover, .lb-nav:hover { background: var(--red); border-color: var(--red); }
.lb-close svg, .lb-nav svg { width: 20px; height: 20px; }
.lb-close { top: 1rem; right: 1rem; }
.lb-nav { top: 50%; translate: 0 -50%; }
.lb-prev { left: 1rem; }
.lb-next { right: 1rem; }
/* Phones: the arrows move to the bottom corners, so the bottom padding keeps their row (1rem inset, 46px, a little air) clear for the caption. */
@media (max-width: 640px) { .lightbox figure { --lb-top: 4rem; --lb-bottom: calc(1rem + 46px + .6rem); padding-inline: 1rem; } .lightbox img { max-width: calc(100vw - 2rem); } .lb-nav { top: auto; bottom: 1rem; translate: none; } }
/* Short windows at any width (a phone turned sideways, a page zoomed to 200% or
   more, DS-42): the arrows go back to the sides, the photo sits between them
   clear of the close button and starts near the top, and the caption is held
   to two smaller lines, so photo and caption always fit. */
@media (max-height: 500px) {
  .lightbox figure { --lb-top: .75rem; --lb-bottom: .75rem; gap: .5rem; padding-inline: 4rem; }
  .lightbox img { max-width: min(calc(100vw - 8rem), 1600px); max-height: calc(100dvh - var(--lb-top) - var(--lb-bottom) - .5rem - 2.3rem); }
  .lightbox figcaption { font-size: .8rem; line-height: 1.4; max-width: calc(100vw - 8rem); display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
  .lb-nav { top: 50%; bottom: auto; translate: 0 -50%; }
  .lb-prev { left: .5rem; }
  .lb-next { right: .5rem; }
  .lb-close { top: .5rem; right: .5rem; }
}
/* The page stays put behind the open lightbox. */
:root:has(dialog.lightbox[open]) { overflow: hidden; }

/* ---------- Sixty second roof check ---------- */
.rcheck-grid { display: grid; grid-template-columns: minmax(0, .9fr) minmax(0, 1.1fr); gap: clamp(2rem, 1rem + 3vw, 5rem); align-items: start; }
.rcheck-intro h2 { font-size: var(--t-h2); margin-block: .7rem 1rem; }
.rcheck-intro h2 em { font-style: normal; color: var(--red); }
.rcheck-intro > p { color: var(--body-dim); max-width: 46ch; }
.rcheck-steps { list-style: none; padding: 0; margin: 2rem 0 0; display: grid; gap: .55rem; }
.rcheck-steps li { display: flex; align-items: center; gap: .8rem; color: rgba(16, 12, 12, .58); font-size: .9rem; transition: color .3s; }
.rcheck-steps li b { font-family: var(--font-display); font-weight: 700; font-stretch: 112%; font-size: .72rem; letter-spacing: .12em; width: 2.2rem; }
.rcheck-steps li::before { content: ''; width: 9px; height: 6px; background: var(--line-2); clip-path: polygon(0 100%, 50% 0, 100% 100%); flex: none; order: -1; transition: background .3s; }
.rcheck-steps li.is-done { color: var(--body); }
.rcheck-steps li.is-done::before { background: var(--gold); }
.rcheck-steps li.is-live { color: var(--ink); font-weight: 600; }
.rcheck-steps li.is-live::before { background: var(--red); }
.rcheck-note { display: flex; align-items: center; gap: .55rem; margin-top: 1.8rem; font-size: .82rem; color: var(--body-dim); }
.rcheck-note svg { width: 16px; height: 16px; color: var(--red); flex: none; }

.rcheck-card { background: #fff; color: var(--body); border: 1px solid var(--line); border-radius: var(--r-xl); padding: clamp(1.4rem, 1rem + 1.6vw, 2.4rem); box-shadow: var(--sh-lg); min-height: 380px; display: grid; }
.rcheck-step { border: 0; padding: 0; margin: 0; display: none; }
.rcheck-step.is-live { display: block; animation: rcIn .35s var(--ease-out) both; }
@keyframes rcIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }
.rcheck-step legend { font-family: var(--font-display); font-weight: 700; font-stretch: 112%; font-size: clamp(1.15rem, 1rem + .7vw, 1.5rem); letter-spacing: -.015em; color: var(--ink); margin-bottom: 1.2rem; line-height: 1.2; }
.rcheck-step legend small { display: block; font: 500 .84rem/1.4 var(--font-body); color: var(--body-dim); margin-top: .3rem; letter-spacing: 0; }
.chips { display: flex; flex-wrap: wrap; gap: .6rem; }
.chip { position: relative; }
.chip input { position: absolute; inset: 0; opacity: 0; margin: 0; cursor: pointer; }
.chip span { display: inline-flex; align-items: center; min-height: 44px; padding: .6rem 1.1rem; border-radius: var(--r-pill); border: 1px solid var(--line-2); background: #fff; color: var(--ink); font-weight: 550; font-size: .92rem; transition: background .25s, border-color .25s, color .25s, transform .25s var(--ease-out); }
.chip:hover span { border-color: var(--ink); }
.chip input:checked + span { background: var(--ink); border-color: var(--ink); color: #fff; transform: translateY(-1px); }
.chip input:focus-visible + span { outline: 3px solid var(--red); outline-offset: 2px; }
.rcheck-hint { font-size: .84rem; color: var(--red-deep); margin-top: .9rem; }
.rcheck-nav { display: flex; align-items: center; justify-content: space-between; gap: 1rem; margin-top: 1.8rem; padding-top: 1.2rem; border-top: 1px solid var(--line); }
.rcheck-back { display: inline-flex; align-items: center; gap: .5rem; color: var(--body-dim); font-weight: 600; font-size: .84rem; letter-spacing: .04em; text-transform: uppercase; min-height: 44px; transition: color .25s; }
.rcheck-back svg { width: 34px; height: 12px; }
.rcheck-back:not(:disabled):hover { color: var(--ink); }
.rcheck-back:disabled { opacity: .35; cursor: default; }
.rcheck-count { font-family: var(--font-display); font-weight: 700; font-stretch: 112%; font-size: .84rem; letter-spacing: .1em; color: var(--body-dim); }
.rcheck-count b { color: var(--ink); }

.rcheck-result { animation: rcIn .4s var(--ease-out) both; }
.rcheck-badge { display: inline-flex; align-items: center; gap: .5rem; padding: .4rem .9rem; border-radius: var(--r-pill); font-size: .74rem; font-weight: 700; letter-spacing: .1em; text-transform: uppercase; color: #fff; background: var(--red); }
.rcheck-badge.is-watch { background: var(--gold); color: var(--ink); }
.rcheck-badge.is-fine { background: var(--ink); }
.rcheck-result h3 { font-size: clamp(1.4rem, 1.1rem + 1.2vw, 2rem); letter-spacing: -.02em; color: var(--ink); margin: 1rem 0 1.1rem; line-height: 1.12; }
.rcheck-points { list-style: none; padding: 0; margin: 0 0 1.5rem; display: grid; gap: .8rem; }
.rcheck-points li { position: relative; padding-left: 1.4rem; font-size: .95rem; line-height: 1.55; color: var(--body); }
.rcheck-points li::before { content: ''; position: absolute; left: 0; top: .55em; width: 11px; height: 7px; background: var(--red); clip-path: polygon(0 100%, 50% 0, 100% 100%); }
.btn-ghost-ink { background: transparent; color: var(--ink); border: 1px solid var(--line-2); }
.btn-ghost-ink:hover { border-color: var(--ink); color: var(--ink); }
.rcheck-again { margin-top: 1.1rem; font-size: .82rem; color: var(--body-dim); text-decoration: underline; text-underline-offset: 3px; }
.rcheck-again:hover { color: var(--ink); }
.lead-card.is-prefilled { box-shadow: 0 0 0 3px var(--red), var(--sh-lg); transition: box-shadow .6s; }

@media (max-width: 900px) {
  .rcheck-grid { grid-template-columns: 1fr; gap: 1.6rem; }
  .rcheck-steps { display: flex; flex-wrap: wrap; gap: .5rem 1.1rem; margin-top: 1.4rem; }
  .rcheck-steps li b { width: auto; }
  .rcheck-card { min-height: 0; }
}
@media (max-width: 640px) { .chip span { font-size: .8175rem; padding: .55rem .95rem; } }

/* Print */
/* The white top bar keeps to one line on laptops and tablets: from 1180 down
   it is the address and the open/closed pill only (it wrapped to 75px). */
@media (max-width: 1180px) { .topbar-facts > span:nth-child(n+2) { display: none; } }

/* ---------- Lighter hero wash (Oct 2026) ----------
   The owner found the dark gradient over the banner photos too heavy. The
   wash is now roughly a third lighter and clears completely on the right, so
   the house reads at full brightness; a soft text shadow carries the copy
   where the photo turns bright behind it. */
.hero-slides::after {
  background:
    linear-gradient(100deg, rgba(16, 12, 12, .62) 0%, rgba(16, 12, 12, .4) 40%, rgba(16, 12, 12, .1) 70%, rgba(16, 12, 12, 0) 100%),
    linear-gradient(to top, rgba(16, 12, 12, .4), transparent 30%);
}
.hero h1 { text-shadow: 0 2px 24px rgba(0, 0, 0, .25); }
.hero-lede, .hero-proof { color: rgba(255, 255, 255, .92); text-shadow: 0 1px 12px rgba(0, 0, 0, .35); }
.hero-badge { background: rgba(255, 255, 255, .12); border-color: rgba(255, 255, 255, .22); }
.hero .btn-ghost { box-shadow: inset 0 0 0 1.5px rgba(255, 255, 255, .5); }
.hero-caption { color: rgba(255, 255, 255, .85); }
.hero-arrow { color: rgba(255, 255, 255, .75); }
.hero-count { color: #fff; }
.hero-progress { background: rgba(255, 255, 255, .25); }
@media (max-width: 640px) {
  .hero-slides::after {
    background: linear-gradient(180deg, rgba(16, 12, 12, .1) 0%, rgba(16, 12, 12, .4) 45%, rgba(16, 12, 12, .62) 100%);
  }
}

/* ---------- Lighter page heroes and CTA band (Oct 2026) ----------
   Same request as the home hero, applied with a lighter hand: the wash over
   inner page banners and the closing CTA photo is eased back so more of the
   photograph shows, while the left side still carries white copy. */
.phero-bg::after { background: linear-gradient(102deg, rgba(16, 12, 12, .84) 12%, rgba(16, 12, 12, .64) 48%, rgba(16, 12, 12, .32)); }
.cta-band-bg img { opacity: .78; }
.cta-band-bg::after { background: linear-gradient(100deg, rgba(16, 12, 12, .8) 0%, rgba(16, 12, 12, .58) 40%, rgba(16, 12, 12, .16) 70%, rgba(16, 12, 12, .04) 100%); }

/* ---------- Where to go next (Oct 2026) ----------
   An intro column and a list of link rows, rather than four look-alike cards
   with an "Open" label. Each row reads as one target: icon, title, line, arrow. */
/* A white band (Aida, 7 Oct) between the paper sections around it; the
   cards take the paper tone so they still read as cards on white. */
.next { background: #fff; border-block: 1px solid var(--line); }
/* After the white stat strip (/commercial/roof-coatings) the strip's own
   bottom rule is the divider; a second one would double it. */
.stat-light + .next { border-top: 0; }
.next-grid { display: grid; grid-template-columns: minmax(0, .8fr) minmax(0, 1.6fr); gap: clamp(1.6rem, 1rem + 3vw, 4.5rem); align-items: start; }
.next-intro h2 { font-size: var(--t-h2); margin-block: .7rem .7rem; }
.next-intro p { color: var(--body-dim); max-width: 34ch; }
.next-links { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: .75rem; }
.next-link {
  display: grid; grid-template-columns: auto 1fr auto; align-items: center; gap: 1rem;
  padding: 1.15rem 1.2rem; border-radius: var(--r-lg); background: var(--paper); border: 1px solid var(--line);
  transition: border-color .3s var(--ease-out), box-shadow .3s var(--ease-out), transform .3s var(--ease-out), background .3s var(--ease-out);
}
.next-ico { display: grid; place-items: center; width: 46px; height: 46px; border-radius: 12px; background: var(--red-wash); color: var(--red); transition: background .3s, color .3s; }
.next-ico svg { width: 22px; height: 22px; }
.next-txt { display: grid; gap: .2rem; min-width: 0; }
.next-txt b { font-family: var(--font-display); font-size: 1.02rem; color: var(--ink); }
.next-txt span { font-size: .88rem; color: var(--body-dim); line-height: 1.45; }
.next-go { display: grid; place-items: center; width: 38px; height: 38px; border-radius: 50%; border: 1.5px solid var(--line-2); color: var(--ink); transition: .3s var(--ease-out); }
.next-go svg { width: 16px; height: 16px; }
.next-link:hover { border-color: var(--red); background: #fff; box-shadow: var(--sh); transform: translateY(-2px); }
.next-link:hover .next-ico { background: var(--red); color: #fff; }
.next-link:hover .next-go { background: var(--red); border-color: var(--red); color: #fff; transform: translateX(3px); }
/* City chips under the cards (SEO-11): service pages link their city pages here. */
.next-areas { grid-column: 2; display: grid; gap: .7rem; margin-top: calc(-1 * clamp(.6rem, .2rem + 1.5vw, 2rem)); }
.next-areas-h { display: inline-flex; align-items: center; gap: .45rem; font-size: .8rem; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--body-dim); }
.next-areas-h svg { width: 16px; height: 16px; color: var(--red); flex: none; }
.next-areas .csr-links { margin-top: 0; }
.next-areas .csr-link { background: var(--paper); max-width: 100%; }
@media (max-width: 900px) {
  .next-grid { grid-template-columns: 1fr; }
  .next-links { grid-template-columns: 1fr; }
  .next-areas { grid-column: auto; margin-top: 0; }
}

/* ---------- City pages: local roofing file (Oct 2026) ---------- */
.lf-head { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 1.4rem 3rem; align-items: end; margin-bottom: clamp(1.6rem, 1rem + 2vw, 2.6rem); }
.lf-head .sec-head { margin-bottom: 0; }
.lf-drive { display: inline-flex; align-items: center; gap: .7rem; padding: .8rem 1.15rem; border-radius: var(--r-pill); background: #fff; border: 1px solid var(--line); font-size: .9rem; color: var(--body); max-width: 30rem; }
.lf-drive svg { width: 20px; height: 20px; color: var(--red); flex: none; }
.lf-drive b { color: var(--ink); }
.lf-grid { display: grid; grid-template-columns: minmax(0, .9fr) minmax(0, 1.25fr) minmax(0, 1fr); gap: 1rem; align-items: stretch; }
.lf-card { background: #fff; border: 1px solid var(--line); border-radius: var(--r-xl); padding: clamp(1.3rem, 1rem + 1vw, 1.9rem); display: flex; flex-direction: column; gap: 1rem; }
.lf-card p { font-size: .92rem; color: var(--body); line-height: 1.6; }
.lf-kicker { display: inline-flex; align-items: center; gap: .55rem; font-family: var(--font-display); font-weight: 700; font-size: .74rem; letter-spacing: .14em; text-transform: uppercase; color: var(--red); }
.lf-kicker svg { width: 18px; height: 18px; }
.lf-big { display: grid; gap: .25rem; }
.lf-big b { font-family: var(--font-display); font-size: clamp(3rem, 2.2rem + 2.6vw, 4.4rem); line-height: .95; letter-spacing: -.03em; color: var(--ink); }
.lf-big span { font-size: .86rem; color: var(--body-dim); }
.lf-stat { display: flex; align-items: baseline; gap: .6rem; padding-block: .8rem; border-block: 1px solid var(--line); }
.lf-stat b { font-family: var(--font-display); font-size: 1.5rem; color: var(--red); }
.lf-stat span { font-size: .88rem; color: var(--body); }
.lf-timeline { display: grid; gap: 0; position: relative; }
.lf-timeline li { position: relative; padding: 0 0 1.15rem 1.6rem; display: grid; gap: .15rem; }
.lf-timeline li::before { content: ''; position: absolute; left: 0; top: .35rem; width: 10px; height: 10px; border-radius: 50%; background: var(--red); box-shadow: 0 0 0 4px var(--red-wash); }
.lf-timeline li::after { content: ''; position: absolute; left: 4.5px; top: 1.1rem; bottom: .1rem; width: 1px; background: var(--line-2); }
.lf-timeline li:last-child { padding-bottom: 0; }
.lf-timeline li:last-child::after { display: none; }
.lf-timeline time { font-size: .78rem; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--body-dim); }
.lf-timeline b { font-family: var(--font-display); font-size: 1.08rem; color: var(--ink); }
.lf-rules-list { display: grid; gap: 1.1rem; }
.lf-rules-list li { display: grid; gap: .3rem; padding-left: 1rem; border-left: 2px solid var(--red); }
.lf-rules-list b { font-family: var(--font-display); font-size: 1rem; color: var(--ink); }
/* Citations read as small labels, not underlined links in the copy (Aida's rule). */
.lf-src { font-size: .7rem; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--body-dim); text-decoration: none; white-space: nowrap; }
.lf-src::after { content: '\2197'; margin-left: .3em; letter-spacing: 0; }
.lf-src:hover { color: var(--red); }
.lf-pdf { display: inline-block; margin-left: .35em; padding: .05em .4em; border: 1px solid currentColor; border-radius: 4px; font-size: .62rem; font-weight: 700; letter-spacing: .06em; line-height: 1.3; text-decoration: none; vertical-align: .12em; }
.lf-card > .lf-src { margin-top: auto; }
.lf-note { margin-top: 1.4rem; font-size: .8rem; color: var(--body-dim); max-width: 80ch; }
@media (max-width: 1024px) {
  .lf-grid { grid-template-columns: 1fr 1fr; }
  .lf-storms { grid-column: span 2; }
}
@media (max-width: 760px) {
  .lf-head { grid-template-columns: 1fr; }
  .lf-drive { border-radius: var(--r-lg); }
  .lf-grid { grid-template-columns: 1fr; }
  .lf-storms { grid-column: auto; }
}

/* Area map pins are links to each city page. */
a.area-pin { cursor: pointer; }
a.area-pin:focus-visible { outline: none; }
a.area-pin:focus-visible circle:not(.pin-hit) { stroke: #fff; stroke-width: 3; }

/* ---------- Service areas hub: city cards (Oct 2026) ---------- */
.city-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 1rem; }
.city-card { display: flex; flex-direction: column; background: #fff; border: 1px solid var(--line); border-radius: var(--r-xl); overflow: hidden; transition: transform .35s var(--ease-out), box-shadow .35s var(--ease-out), border-color .35s; }
.city-card:hover { transform: translateY(-5px); box-shadow: var(--sh-lg); border-color: transparent; }
.city-media { position: relative; aspect-ratio: 16 / 10; overflow: hidden; background: var(--paper-3); }
.city-media picture, .city-media img { width: 100%; height: 100%; }
.city-media img { object-fit: cover; transition: transform .8s var(--ease-out); }
.city-card:hover .city-media img { transform: scale(1.04); }
.city-pos { position: absolute; left: .9rem; top: .9rem; padding: .35rem .75rem; border-radius: var(--r-pill); background: rgba(255, 255, 255, .94); font-size: .72rem; font-weight: 700; letter-spacing: .1em; text-transform: uppercase; color: var(--ink); }
.city-body { display: flex; flex-direction: column; gap: .5rem; padding: 1.25rem 1.35rem 1.4rem; flex: 1; }
.city-body h3 { font-size: var(--t-h4); }
.city-body p { font-size: .93rem; color: var(--body-dim); line-height: 1.5; }
.city-go { margin-top: auto; padding-top: .6rem; display: inline-flex; align-items: center; gap: .5rem; font-family: var(--font-display); font-weight: 700; font-size: .8rem; letter-spacing: .08em; text-transform: uppercase; color: var(--red); }
.city-go svg { width: 16px; height: 16px; transition: transform .3s var(--ease-out); }
.city-card:hover .city-go svg { transform: translateX(4px); }
@media (max-width: 1024px) { .city-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
/* Phones: two smaller tiles a row, photos kept, so the nine cities take
   about half the scroll a single column did. */
@media (max-width: 640px) {
  .city-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: .7rem; }
  .city-media { aspect-ratio: 4 / 3; }
  .city-pos { left: .5rem; top: .5rem; padding: .25rem .55rem; font-size: .7rem; letter-spacing: .05em; }
  .city-body { gap: .35rem; padding: .85rem .85rem 1rem; }
  .city-body h3 { font-size: 1rem; line-height: 1.25; }
  .city-body p { font-size: .8175rem; line-height: 1.45; }
  .city-go { padding-top: .35rem; font-size: .8175rem; letter-spacing: .03em; }
  /* An odd last tile spans the row, photo beside the text. */
  .city-grid > .city-card:last-child:nth-child(odd) { grid-column: 1 / -1; display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
  .city-grid > .city-card:last-child:nth-child(odd) .city-media { aspect-ratio: auto; height: 100%; min-height: 150px; }
}
/* The narrowest phones: sentence case and tighter spacing keep "Southwest
   metro" on one line with room to spare, without shrinking the type. */
@media (max-width: 379px) {
  .city-pos { left: .35rem; top: .35rem; padding: .25rem .5rem; letter-spacing: .02em; text-transform: none; }
}

/* Light stat strip, for pages where the strip would otherwise sit against
   another dark band. */
.stat-strip.stat-light { background: #fff; color: var(--ink); border-block: 1px solid var(--line); }
.stat-light .stat-grid { background: var(--line); }
.stat-light .stat { background: #fff; }
.stat-light .stat b { color: var(--ink); }
.stat-light .stat b .suf { color: var(--red); }
.stat-light .stat > span { color: var(--body-dim); }

@media (max-width: 1100px) { .csr-head { align-items: start; } }
/* Pins get a finger sized hit area. */
.area-pin .pin-hit { fill: transparent; }

/* ---------- FAQ: two columns, search, a person to call (Oct 2026) ---------- */
/* The call card follows the questions in the source. On desktop it sits at
   the foot of the left column: the first row stretches with the list, so the
   heading and search above it stay sticky. Only the inner block is sticky,
   and its box (.faq-side) ends at row 1, so it never covers the call card. */
.faq-grid { display: grid; grid-template-columns: minmax(0, .85fr) minmax(0, 1.5fr); grid-template-rows: 1fr auto; column-gap: clamp(1.8rem, 1rem + 3.5vw, 4.5rem); row-gap: 1.4rem; align-items: start; }
.faq-side { grid-column: 1; grid-row: 1; align-self: stretch; }
.faq-side-in { position: sticky; top: calc(var(--header-h) + 1.6rem); display: grid; gap: 1.4rem; }
.faq-main { grid-column: 2; grid-row: 1 / span 2; }
.faq-grid > .faq-call { grid-column: 1; grid-row: 2; }
.faq-side .sec-head { margin-bottom: 0; }
.faq-search { position: relative; display: flex; align-items: center; background: #fff; border: 1.5px solid var(--line-2); border-radius: var(--r-pill); transition: border-color .25s, box-shadow .25s; }
.faq-search:focus-within { border-color: var(--red); box-shadow: 0 0 0 4px var(--red-wash); }
.faq-search > svg { position: absolute; left: 1.05rem; width: 18px; height: 18px; color: var(--body-dim); pointer-events: none; }
.faq-search input { width: 100%; min-height: 50px; padding: .8rem 3rem .8rem 2.9rem; border: 0; background: transparent; font: inherit; font-size: .97rem; color: var(--ink); border-radius: inherit; outline: none; }
.faq-search input::-webkit-search-cancel-button { display: none; }
/* The clear button only shows once there is text, and the placeholder only
   while there is none, so an empty field gives the hint the button's room. */
.faq-search input:placeholder-shown { padding-right: 1.1rem; }
.faq-clear { position: absolute; right: .45rem; width: 36px; height: 36px; display: grid; place-items: center; border-radius: 50%; color: var(--body-dim); }
.faq-clear:hover { background: var(--paper-2); color: var(--ink); }
.faq-clear svg { width: 16px; height: 16px; }
.faq-count { font-size: .82rem; font-weight: 600; letter-spacing: .04em; color: var(--body-dim); margin-bottom: .9rem; }
.faq-count:empty { display: none; }
.faq-count:focus:not(:focus-visible) { outline: none; }
.faq-empty { padding: 1.6rem; border: 1.5px dashed var(--line-2); border-radius: var(--r-lg); background: #fff; }
.faq-empty b { font-family: var(--font-display); color: var(--ink); }
.faq-empty p { margin-top: .4rem; font-size: .95rem; color: var(--body-dim); }
/* Where to go from an empty search: buttons, never links in the sentence. */
.faq-empty-act { display: flex; flex-wrap: wrap; gap: .55rem; margin-top: 1rem; }
/* The hub's "matches only in other topics" state (DS-34). */
.faq-empty-all { margin-top: 1rem; gap: .55rem; }
.faq-empty-all span { font-size: .74rem; color: var(--body-dim); }
.faq-empty-all span:empty { display: none; }
.faq summary mark, .hub-q mark { background: #ffe58a; color: inherit; border-radius: 3px; padding: 0 .1em; }
.faq-call { display: grid; grid-template-columns: auto 1fr; gap: 1rem; align-items: start; padding: 1.3rem; border-radius: var(--r-lg); background: var(--ink); color: rgba(255, 255, 255, .75); }
.faq-call-ico { display: grid; place-items: center; width: 44px; height: 44px; border-radius: 50%; background: var(--red); color: #fff; }
.faq-call-ico svg { width: 20px; height: 20px; }
.faq-call b { display: block; font-family: var(--font-display); color: #fff; font-size: 1.02rem; }
.faq-call p { font-size: .88rem; margin-top: .25rem; }
.faq-call-link { display: inline-flex; align-items: center; gap: .5rem; margin-top: .7rem; font-family: var(--font-display); font-weight: 700; color: #fff; font-size: 1.05rem; }
.faq-call-link svg { width: 16px; height: 16px; color: var(--red-soft); transition: transform .3s var(--ease-out); }
.faq-call-link:hover svg { transform: translateX(4px); }
.sec-dark .faq-search { background: rgba(255, 255, 255, .06); border-color: var(--line-dark-2); }
.sec-dark .faq-search input { color: #fff; }

/* A sticky column that never outgrows the window (DS-15): capped to the
   height left under the header, it scrolls on its own when its content is
   taller, so nothing in it is ever out of reach on a short laptop screen.
   Shared by the /faq rail and the blog article's aside. The padding and
   matching negative margin keep focus rings and shadows from being clipped
   at its edges. */
.sticky-fit {
  position: sticky;
  top: calc(var(--header-h) + 1.6rem);
  max-height: calc(100vh - var(--header-h) - 3.2rem);
  max-height: calc(100dvh - var(--header-h) - 3.2rem);
  overflow-y: auto;
  scrollbar-width: thin;
  scrollbar-color: var(--line-2) transparent;
  padding: 6px;
  margin: -6px;
  scroll-padding-block: 3rem;
}
/* While there is more of it above or below, that edge fades out, so a
   capped column reads as one that scrolls (app.js sets the classes). The
   wheel carries on to the page once the column reaches its end. The scroll
   padding above matches the fade, so a link or topic reached by keyboard is
   brought clear of the faded edge. */
.sticky-fit.is-more-below { -webkit-mask-image: linear-gradient(to bottom, #000 calc(100% - 3rem), transparent); mask-image: linear-gradient(to bottom, #000 calc(100% - 3rem), transparent); }
.sticky-fit.is-more-above { -webkit-mask-image: linear-gradient(to bottom, transparent, #000 3rem); mask-image: linear-gradient(to bottom, transparent, #000 3rem); }
.sticky-fit.is-more-above.is-more-below { -webkit-mask-image: linear-gradient(to bottom, transparent, #000 3rem, #000 calc(100% - 3rem), transparent); mask-image: linear-gradient(to bottom, transparent, #000 3rem, #000 calc(100% - 3rem), transparent); }

/* The /faq hub: a sticky rail with the call card, search and topics, and
   the answers on the right. */
.hub-grid { --hub-gap: clamp(2rem, 1.4rem + 1.5vw, 3rem); display: grid; grid-template-columns: minmax(0, .75fr) minmax(0, 1.65fr); gap: clamp(1.8rem, 1rem + 3.5vw, 4.5rem); align-items: start; }
.hub-rail { display: grid; gap: 1.6rem; }
.hub-tools, .hub-bar { display: grid; gap: 1.1rem; }
/* The office number never breaks across lines. Where the rail is at its
   narrowest (901 to 1080px) the call card stacks its icon above the text. */
.faq-call-link { white-space: nowrap; }
@media (min-width: 901px) and (max-width: 1080px) { .hub-rail .faq-call { grid-template-columns: 1fr; gap: .8rem; } }
.hub-chips { display: flex; flex-wrap: wrap; gap: .45rem; }
.hub-chip { display: inline-flex; align-items: center; gap: .45rem; min-height: 40px; padding: .45rem .9rem; border-radius: var(--r-pill); border: 1.5px solid var(--line-2); background: #fff; font-size: .86rem; font-weight: 600; color: var(--body); transition: .25s var(--ease-out); }
.hub-chip span { font-size: .74rem; color: var(--body-dim); }
.hub-chip:hover { border-color: var(--ink); color: var(--ink); }
.hub-chip[aria-pressed="true"] { background: var(--red); border-color: var(--red); color: #fff; }
.hub-chip[aria-pressed="true"] span { color: rgba(255, 255, 255, .8); }
/* No matches in that topic for the current search: still there, quieter. */
.hub-chip.is-none:not([aria-pressed="true"]) { color: var(--body-dim); border-color: var(--line); background: transparent; }
.hub-main { display: grid; gap: var(--hub-gap); }
/* The count sits just above the first group, not a full group gap away. */
.hub-main > .faq-count { margin-bottom: calc(.9rem - var(--hub-gap)); }
.hub-h { font-size: var(--t-h3); margin-bottom: 1rem; padding-bottom: .7rem; border-bottom: 2px solid var(--ink); }
.hub-list { display: grid; gap: .5rem; }
.hub-q { display: flex; align-items: center; justify-content: space-between; gap: 1rem; padding: 1rem 1.2rem; background: #fff; border: 1px solid var(--line); border-radius: var(--r); transition: border-color .25s, box-shadow .25s; }
.hub-q:hover { border-color: var(--red); box-shadow: var(--sh-sm); }
.hub-q-text { font-family: var(--font-display); font-weight: 650; color: var(--ink); line-height: 1.4; }
.hub-q-where { flex: none; display: inline-flex; align-items: center; gap: .4rem; font-size: .76rem; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--red); }
.hub-q-where svg { width: 14px; height: 14px; }
[data-faq-root] [hidden] { display: none !important; }
/* The hub's General questions run the full column like the groups below
   them; the answer text keeps a readable measure instead. */
.hub-main .faq { max-width: none; }
.faq .faq-a { max-width: 72ch; }
@media (max-width: 900px) {
  .faq-grid { grid-template-columns: 1fr; }
  .faq-side-in { position: static; }
  .hub-q { flex-direction: column; align-items: flex-start; gap: .45rem; }
  /* The hub on phones and tablets (DS-14). One column; the rail and its
     group give up their boxes, so the eyebrow, the bar and the results are
     siblings in one flex column and the bar can stay stuck all the way down
     the answers. The call card steps aside; the closing band with the office
     number follows the results. */
  .hub-grid { display: flex; flex-direction: column; align-items: stretch; gap: 0; }
  .hub-rail, .hub-tools { display: contents; }
  .hub-rail > .faq-call { display: none; }
  .hub-tools > .eyebrow { margin-bottom: .55rem; }
  .hub-bar {
    position: sticky; top: calc(var(--header-h) - 1px); z-index: 30;
    gap: .6rem; margin-inline: calc(var(--pad-x) * -1); padding: .6rem var(--pad-x) .7rem;
    background: var(--paper);
    border-bottom: 1px solid transparent;
    transition: box-shadow .3s var(--ease), border-color .3s var(--ease);
  }
  .hub-bar.is-stuck { border-bottom-color: var(--line); box-shadow: 0 12px 22px -16px rgba(16, 12, 12, .28); }
  .hub-bar .faq-search input { min-height: 46px; padding-block: .6rem; }
  /* The topics run as one row that scrolls sideways; the right edge fades to
     say there is more. */
  .hub-chips {
    flex-wrap: nowrap; overflow-x: auto; overscroll-behavior-x: contain;
    margin-inline: calc(var(--pad-x) * -1); padding: 2px var(--pad-x);
    scroll-padding-inline: var(--pad-x); scroll-snap-type: x proximity; scrollbar-width: none;
    -webkit-mask-image: linear-gradient(to right, transparent, #000 var(--pad-x), #000 calc(100% - 2.6rem), transparent);
    mask-image: linear-gradient(to right, transparent, #000 var(--pad-x), #000 calc(100% - 2.6rem), transparent);
  }
  .hub-chips::-webkit-scrollbar { display: none; }
  .hub-chip { flex: none; scroll-snap-align: start; }
  /* The row clips anything outside it, so the focus ring draws inside. */
  .hub-chips .hub-chip:focus-visible { outline-offset: -3px; }
  .hub-main { margin-top: 1.3rem; }
  /* Anything in the answers that takes focus, or is reached by an anchor,
     stops below the stuck bar as well as the header (the html scroll padding
     already clears the header), so tabbing back up never hides it (DS-14). */
  .hub-main *, .hub-main .faq details { scroll-margin-top: 7.5rem; }
  /* One column in source order: the heading and search, the questions
     they filter, then the call card. */
  .faq-grid { grid-template-rows: none; }
  .faq-side, .faq-main, .faq-grid > .faq-call { grid-column: auto; grid-row: auto; }
}
/* Up to 1024px the call bar is fixed along the bottom of the window, so the
   rail stops above it too. */
@media (max-width: 1024px) {
  .sticky-fit { max-height: calc(100vh - var(--header-h) - 3.2rem - 4.75rem); max-height: calc(100dvh - var(--header-h) - 3.2rem - 4.75rem); }
}
/* Phones: the stuck header is 60px tall, so the bar tucks in under it. */
@media (max-width: 760px) { .hub-bar { top: 59px; } }
/* Short screens (landscape phones, 200% zoom): the header scrolls away, so
   the bar sticks to the very top and slims down, leaving the answers most of
   the height. Sticky columns beside the content start at the top too. */
@media (max-height: 500px) {
  .sticky-fit { top: 1.6rem; max-height: calc(100vh - 3.2rem); max-height: calc(100dvh - 3.2rem); }
}
@media (max-width: 1024px) and (max-height: 500px) {
  .sticky-fit { max-height: calc(100vh - 3.2rem - 3.5rem); max-height: calc(100dvh - 3.2rem - 3.5rem); }
}
@media (max-width: 900px) and (max-height: 500px) {
  .hub-bar { top: 0; gap: .45rem; padding-block: .4rem .45rem; }
  .hub-bar .faq-search input { min-height: 40px; padding-block: .4rem; }
  .hub-bar .faq-clear { width: 32px; height: 32px; }
  .hub-bar .hub-chip { min-height: 36px; padding-block: .3rem; }
  /* The header scrolls away here, so the band is the slim bar alone. */
  .hub-main *, .hub-main .faq details { scroll-margin-top: 6rem; }
}
/* The article aside stacks under the article up to 1024px (FX-01), so it
   only sticks beside it. */
@media (max-width: 1024px) { .split-aside.sticky-fit { position: static; max-height: none; overflow: visible; padding: 0; margin: 0; } }
/* On paper nothing sticks and nothing scrolls, so nothing is cut off. */
@media print { .sticky-fit, .hub-bar { position: static !important; max-height: none !important; overflow: visible !important; } }

/* ---------- Photo story and image signs (Oct 2026) ---------- */
.ps-grid { display: grid; grid-template-columns: minmax(0, 1.55fr) minmax(0, 1fr); gap: 1rem; }
.ps-side { display: grid; gap: 1rem; }
.ps-fig { margin: 0; display: flex; flex-direction: column; background: #fff; border: 1px solid var(--line); border-radius: var(--r-xl); overflow: hidden; }
.ps-media { position: relative; overflow: hidden; background: var(--paper-3); flex: 1; min-height: 0; }
.ps-media picture, .ps-media img { width: 100%; height: 100%; }
.ps-media img { object-fit: cover; aspect-ratio: 16 / 10; transition: transform .8s var(--ease-out); }
.ps-big .ps-media img { aspect-ratio: auto; min-height: 100%; }
.ps-fig:hover .ps-media img { transform: scale(1.03); }
.ps-fig figcaption { display: grid; grid-template-columns: auto 1fr; column-gap: .9rem; row-gap: .2rem; padding: 1.1rem 1.3rem 1.25rem; }
.ps-num { grid-row: span 2; font-family: var(--font-display); font-weight: 800; font-size: .82rem; letter-spacing: .12em; color: var(--red); padding-top: .2rem; }
.ps-fig figcaption b { font-family: var(--font-display); font-size: 1.05rem; color: var(--ink); }
.ps-fig figcaption span:last-child { font-size: .9rem; color: var(--body-dim); line-height: 1.5; }
.signs-grid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 1rem; }
.signs-grid.has-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.sign { background: #fff; border: 1px solid var(--line); border-radius: var(--r-xl); overflow: hidden; display: flex; flex-direction: column; }
.sign-media { position: relative; aspect-ratio: 4 / 3; overflow: hidden; background: var(--paper-3); }
.sign-media picture, .sign-media img { width: 100%; height: 100%; }
.sign-media img { object-fit: cover; }
.sign-num { position: absolute; left: .9rem; top: .9rem; display: grid; place-items: center; width: 40px; height: 40px; border-radius: 50%; background: var(--red); color: #fff; font-family: var(--font-display); font-weight: 800; font-size: .86rem; box-shadow: var(--sh); }
.sign-body { padding: 1.2rem 1.3rem 1.4rem; display: grid; gap: .45rem; }
.sign-body h3 { font-size: 1.08rem; }
.sign-body p { font-size: .92rem; color: var(--body-dim); line-height: 1.55; }
@media (max-width: 1024px) { .signs-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 900px) {
  .ps-grid { grid-template-columns: 1fr; }
  .ps-big .ps-media img { aspect-ratio: 16 / 10; }
}
@media (max-width: 560px) { .signs-grid { grid-template-columns: 1fr; } }
/* Three signs keep one row of three down to 761px; a 2 + 1 split would strand
   the last card, so phones stack all three. */
@media (max-width: 760px) { .signs-grid.has-3 { grid-template-columns: 1fr; } }

/* Hero credentials as badges rather than a run-on sentence (Oct 2026). */
.hero-chips { display: flex; flex-wrap: wrap; gap: .5rem; margin: 0; padding: 0; list-style: none; max-width: none !important; }
.hero-chips li { display: inline-flex; align-items: center; gap: .5rem; padding: .5rem .85rem; border-radius: var(--r-pill); background: rgba(255, 255, 255, .12); border: 1px solid rgba(255, 255, 255, .24); backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px); color: #fff; font-size: .84rem; font-weight: 600; line-height: 1; white-space: nowrap; }
.hero-chips li b { font-family: var(--font-display); font-size: .95rem; }
.hero-chips li > svg { width: 15px; height: 15px; color: var(--gold); flex: none; }
.hero-chips .stars svg { width: 13px; height: 13px; }
@media (max-width: 560px) { .hero-chips li { font-size: .8175rem; padding: .45rem .75rem; } }

/* Homepage reviews: rating and links in one row above the carousel (Oct 2026). */
.rating-bar { display: flex; align-items: flex-end; justify-content: space-between; gap: 1.4rem 2rem; flex-wrap: wrap; padding-bottom: 1.6rem; margin-bottom: 2rem; border-bottom: 1px solid var(--line); }
.rating-bar .rating-big { margin-top: .8rem; }
.rcar.is-static .rcar-ctl { display: none; }
/* Every card in view (a lone review, or all of them fit): nothing moves, so
   the controls go and the 7 line clamp lifts, since there is no next card or
   control to reach the rest of the text. The cards keep the carousel's size
   and start at the heading's left edge, like every other review row
   (CHAT-WINREV, 7 Oct). */
.rcar.is-static .review p { display: block; -webkit-line-clamp: unset; overflow: visible; }

/* Contact page form: fields in pairs, address and message full width. */
.field-grid.field-grid-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.field-grid-2 .field.full { grid-column: 1 / -1; }
@media (max-width: 560px) { .field-grid.field-grid-2 { grid-template-columns: 1fr; } }

/* Blog index: the newest article featured, the rest in a row of three. */
.blog-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.blog-grid .card-media { aspect-ratio: 16 / 10; }
.blog-feature { grid-column: 1 / -1; display: grid; grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr); }
.blog-feature .card-media { aspect-ratio: auto; min-height: 360px; height: 100%; }
.blog-feature .card-body { padding: clamp(1.6rem, 1rem + 2vw, 2.6rem); justify-content: center; }
.blog-feature h3 { font-size: clamp(1.45rem, 1.1rem + 1.2vw, 2rem); line-height: 1.15; }
.blog-feature .card-body p { flex: 0; }
/* Two columns: the feature spans the row, so the last card only widens when
   the cards after it are odd in number (an even nth-child), which would
   otherwise leave it alone with a gap beside it. */
@media (max-width: 1024px) { .blog-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } .blog-grid > a:last-child:nth-child(even):not(.blog-feature) { grid-column: 1 / -1; display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); } .blog-grid > a:last-child:nth-child(even):not(.blog-feature) .card-media { aspect-ratio: auto; height: 100%; min-height: 240px; } }
@media (max-width: 900px) { .blog-feature { grid-template-columns: 1fr; } .blog-feature .card-media { min-height: 0; aspect-ratio: 16 / 10; } }
@media (max-width: 640px) { .blog-grid { grid-template-columns: 1fr; } .blog-grid > a:last-child:nth-child(even):not(.blog-feature) { grid-column: auto; display: flex; } .blog-grid > a:last-child:nth-child(even):not(.blog-feature) .card-media { aspect-ratio: 16 / 10; height: auto; min-height: 0; } }

.cert-mark.has-badge { background: none; padding: 0; }
.cert-mark.has-badge img { width: 100%; height: 100%; object-fit: contain; }
.cert-verify { display: inline-flex; align-items: center; gap: .45rem; margin: .2rem 1.4rem 1.3rem; font-family: var(--font-display); font-weight: 700; font-size: .78rem; letter-spacing: .08em; text-transform: uppercase; color: var(--red); }
.cert-verify svg { width: 15px; height: 15px; }

@media print {
  .site-head, .topbar, .callbar, .site-foot, .hero-ctl, .hero-progress, .scroll-bar { display: none !important; }
  body { color: #000; background: #fff; }
}

/* ---------- Header, menu and page chrome (Oct 2026) ---------- */
/* Menu open: the page behind cannot scroll. The lock sits on <html> because
   html{overflow-x:clip} keeps a body overflow from reaching the viewport, and
   the body is pinned in place (app.js sets its top) so iOS Safari holds too. */
html.is-locked { overflow: hidden; scrollbar-gutter: stable; }
html.is-locked body { position: fixed; left: 0; right: 0; width: 100%; }

/* Focused links and invalid fields stop above the call bar as well. */
@media (max-width: 1024px) { html { scroll-padding-bottom: 88px; } }

/* Phones: once stuck, the header drops from 84px to 60px with a 120px logo
   (the white top bar is unchanged). Its margin takes up the difference, so
   nothing below it moves as it shrinks. */
@media (max-width: 760px) {
  .site-head { transition: box-shadow .3s, background .35s var(--ease), border-color .35s var(--ease), backdrop-filter .35s, margin-bottom .3s var(--ease); }
  .head-inner { transition: min-height .3s var(--ease); }
  .brand img { transition: opacity .35s var(--ease), width .3s var(--ease); }
  .site-head.is-stuck { margin-bottom: 24px; }
  body.has-hero .site-head.is-stuck { margin-bottom: -60px; }
  .site-head.is-stuck .head-inner { min-height: 59px; }
  .site-head.is-stuck .brand img { width: 120px; }
}

/* Very wide screens: the top bar, header and footer line up with the content
   column instead of running wider than it (below 1800 the header needs the
   wider wrap). The hero progress line and slide controls keep the same edge. */
:root { --col-edge: var(--pad-x); }
@media (min-width: 1800px) {
  :root { --col-edge: max(var(--pad-x), calc((100% - var(--max)) / 2 + var(--pad-x))); }
  .topbar .wrap-wide, .head-inner, .site-foot .wrap-wide { max-width: var(--max); }
}
.hero-progress { left: var(--col-edge); right: var(--col-edge); }
.hero-ctl { right: var(--col-edge); }

/* Short screens (landscape phones, 200 to 400% zoom): the header scrolls away
   with the page and the call bar slims to about 48px. The call bar stays, as
   it is the only phone link below 1025px. */
@media (max-height: 500px) {
  .site-head { position: relative; }
  html { scroll-padding-top: 1rem; }
  /* The header no longer sits in that band, so its links keep the margin. */
  .site-head * { scroll-margin-top: 0; }
  .callbar { padding: .2rem .5rem max(.2rem, env(safe-area-inset-bottom)); gap: .5rem; }
  .callbar .btn { min-height: 40px; padding-block: .5rem; }
}
@media (max-width: 1024px) and (max-height: 500px) { html { scroll-padding-bottom: 64px; } }
/* The menu's pinned action bar shrinks to one row on short screens, so the
   links keep most of the height. At 300px and under (400% zoom) it stops
   pinning and follows the last link instead. */
@media (max-height: 500px) {
  .drawer { padding-top: .6rem; }
  .drawer-top { margin-bottom: .3rem; }
  .drawer-actions { grid-template-columns: 1fr 1fr; gap: .5rem; padding-block: .5rem max(.5rem, env(safe-area-inset-bottom)); box-shadow: 0 -12px 16px -6px var(--ink); }
  .drawer .btn { min-height: 44px; padding: .45rem .7rem; font-size: .72rem; letter-spacing: .02em; gap: .4rem; text-align: center; }
}
@media (max-height: 300px) {
  .drawer { scroll-padding-bottom: .5rem; }
  .drawer-actions { position: static; margin-top: .6rem; box-shadow: none; }
}

/* Windows High Contrast and other forced colour modes: shapes drawn with a
   background colour would turn into the page colour, the burger included. */
@media (forced-colors: active) {
  .burger { border: 1px solid ButtonText; }
  .tile-cta { border: 1px solid CanvasText; }
  .burger span { background: CanvasText !important; }
  .faq summary::after, .detail-card summary::after { background: CanvasText; }
  .drawer a.sub::before { background: CanvasText; }
  /* The red underline and the inset rules for "you are here" are background
     and box-shadow, which forced colours paint as Canvas or drop. */
  .nav > li > a::after, .nav > li > button::after { background: CanvasText; }
  .drawer-link[aria-current="page"], .drawer-link.is-section, .drawer a.sub[aria-current="page"], .mega-item[aria-current="page"] { border-left: 3px solid Highlight; }
  /* The footer marks its page with colour alone, which forced colours flatten. */
  .site-foot a[aria-current="page"] { border-left: 3px solid Highlight; padding-left: .5rem; }
  .hero-progress i { background: Highlight; }
  .status-dot { background: CanvasText; }
}
.site-foot a[aria-current="page"] { color: #fff; }

/* ---------- Homepage hero and widgets (Oct 2026) ---------- */
/* The hero copy sits in one stage that app.js holds at the height of the
   tallest slide, so the buttons, chips and docked form never move. */
.hero-copy { display: grid; gap: 1.35rem; justify-items: start; align-content: start; justify-self: stretch; }
[data-hero-h1] { transition: opacity .26s var(--ease), transform .26s var(--ease); }
[data-hero-h1].is-fading { opacity: 0; transform: translateY(6px); }
/* The controls sit at least 16px clear of the chips at every width. */
.hero-inner { padding-bottom: max(clamp(8rem, 4rem + 12vw, 12rem), calc(clamp(6.2rem, 3rem + 9vw, 9rem) + 44px + 1rem)); }
/* Wider screens show the caption: on its glass backing it runs one or two
   lines, so the row is held at the two-line height (the arrows never nudge
   between slides) and that height is what the padding reserves. */
@media (min-width: 761px) {
  .hero-ctl { min-height: 3.25rem; }
  .hero-inner { padding-bottom: max(clamp(8rem, 4rem + 12vw, 12rem), calc(clamp(6.2rem, 3rem + 9vw, 9rem) + 3.25rem + 1rem)); }
}
/* The progress line is the slide clock: one CSS animation per slide, held
   with the slide (hover, focus, touch, off screen). */
.hero-progress i { width: 100%; transform: scaleX(0); transform-origin: left center; }
.hero.is-timing .hero-progress i { animation: heroBar var(--hero-dur, 8s) linear forwards; }
.hero.is-held .hero-progress i, .hero.is-held .hero-slide.is-active img { animation-play-state: paused; }
@keyframes heroBar { to { transform: scaleX(1); } }
/* Ticker: held on hover (base rule) and while focus is inside. */
.ticker:focus-within .ticker-track { animation-play-state: paused; }
.hb-short { display: none; }
@media (max-width: 640px) {
  /* Phones: a shorter badge that stays on one line (ellipsis only as a last
     resort on the narrowest screens), and a modestly shorter top margin. */
  .hb-long { display: none; }
  .hb-short { display: inline; }
  .hero-badge { max-width: 100%; }
  [data-hero-badge] { min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  /* The top margin follows the height of the first screen as the visitor
     sees it (svh: browser toolbars showing, which on a real iPhone is about
     660px in Safari, not the 844px of the device spec). It stays 6rem where
     that is 844px or more, and gives way to 2rem by 812px, so on most real
     phones the main button, and where it fits the rating chip, sits above
     the call bar. Plain vh (older browsers) is the toolbars-hidden height. */
  .hero-inner { padding-top: clamp(2rem, (100vh - 796px) * 2, 6rem); padding-top: clamp(2rem, (100svh - 796px) * 2, 6rem); }
  /* The rating chip on its own row, the three credentials in one row that
     scrolls sideways edge to edge. The rating stays put while they scroll. */
  .hero-chips { display: grid; grid-template-columns: repeat(3, max-content); justify-self: stretch; overflow-x: auto; overscroll-behavior-x: contain; scrollbar-width: none; margin-inline: calc(var(--pad-x) * -1); padding-inline: var(--pad-x); }
  .hero-chips::-webkit-scrollbar { display: none; }
  .hero-chips li:first-child { grid-column: 1 / -1; justify-self: start; position: sticky; left: 0; z-index: 1; }
}
/* Short phones (820px tall or less): slightly tighter spacing in the hero
   copy as well. app.js measures the stage with these gaps. */
@media (max-width: 640px) and (max-height: 820px) {
  .hero-inner, .hero-copy { row-gap: 1rem; }
}
/* Roof check: the counter and Back arrow never squeeze at 390, Next takes
   the rest of the row, and Next lights up once a sign is ticked. Where the
   three do not fit on one line (narrower than about 360px) Next drops to a
   full-width row of its own, so the nav never sets the column's width; the
   columns themselves may shrink below their content. */
.rcheck-intro, .rcheck-card { min-width: 0; }
.rcheck-count { white-space: nowrap; flex: none; }
.rcheck-back svg { flex: none; }
.rcheck-step legend:focus { outline: none; }
.rcheck-step legend:focus-visible, .rcheck-result h3:focus-visible { outline: 3px solid var(--red); outline-offset: 4px; }
.rcheck-result h3:focus:not(:focus-visible) { outline: none; }
.rcheck-nav .btn.is-ready { box-shadow: 0 0 0 4px var(--red-wash), var(--sh); }
@media (max-width: 560px) {
  .rcheck-nav { flex-wrap: wrap; row-gap: .9rem; }
  /* Next wraps by a fixed 8rem basis, not by its label, so "Next" and the
     wider "See the answer" break the row at the same width and the last
     step keeps the same layout; a long label runs to two lines instead. */
  .rcheck-nav .btn { flex: 1 1 8rem; min-width: 0; width: auto; padding-inline: 1.2rem; line-height: 1.15; }
}
/* A tighter gap keeps the one-line nav down to 360. */
@media (max-width: 380px) { .rcheck-nav { column-gap: .6rem; } }
/* Tabs never resize their section: every panel shares one grid cell and only
   the selected one is visible, so the tallest sets the height. */
.explorer-panels { display: grid; }
.explorer-panel, .explorer-panel.is-active { grid-area: 1 / 1; display: grid; grid-template-columns: 1.05fr .95fr; gap: clamp(1.4rem, 1rem + 2vw, 2.6rem); align-items: center; visibility: hidden; }
.explorer-panel.is-active { visibility: visible; }
@media (max-width: 760px) { .explorer-panel, .explorer-panel.is-active { grid-template-columns: 1fr; } }
/* Quote band: the glow is a CSS gradient across the whole band (the SVG one
   was letterboxed and left seams). On phones the drawing sits lower and the
   red roofline is quieter, so it does not run through the words. */
.quote-bg { background: radial-gradient(80% 85% at 50% 24%, rgba(240, 96, 95, .2), rgba(240, 96, 95, 0) 100%); }
@media (max-width: 640px) {
  .quote-draw { transform-origin: 50% 75%; }
  .quote-draw .d-roof { opacity: .35; }
}
/* Compare slider: the real control is a transparent range input, so its
   keyboard focus is drawn on the grip. */
.compare:has(.compare-range:focus-visible) .compare-grip { outline: 3px solid #fff; outline-offset: 3px; box-shadow: 0 0 0 6px var(--red); }
/* end homepage hero and widgets */

/* ---------- Accessibility pass (Oct 2026) ----------
   Contrast over photographs, focus rings, forced colours (Windows High
   Contrast), print, tap targets and type floors. The washes themselves are
   untouched: copy over a photograph is carried by text shadows and small
   dark glass backings instead. */

/* Home hero: the headline and lede get a tighter dark halo, the red half of
   each headline a denser one; the badge, chips, caption and slide counter
   sit on dark glass. */
.hero h1 { text-shadow: 0 0 1px rgba(16, 12, 12, .6), 0 0 4px rgba(16, 12, 12, .5), 0 1px 14px rgba(16, 12, 12, .5), 0 2px 30px rgba(16, 12, 12, .4); }
.hero h1 em { text-shadow: 0 0 3px #100c0c, 0 0 4px #100c0c, 0 0 6px #100c0c, 0 0 12px rgba(16, 12, 12, .8), 0 2px 26px rgba(16, 12, 12, .5); }
/* On phones the headline sits in the lightest band of the wash, so its
   halo is held denser close to the letters. */
@media (max-width: 640px) {
  .hero h1 { text-shadow: 0 0 3px rgba(16, 12, 12, .9), 0 0 5px rgba(16, 12, 12, .8), 0 0 10px rgba(16, 12, 12, .6), 0 2px 24px rgba(16, 12, 12, .5); }
}
.hero-lede { text-shadow: 0 0 2px rgba(16, 12, 12, .5), 0 1px 12px rgba(16, 12, 12, .55); }
/* Up to tablet width the lede runs out past the washed left side of the
   photo (over the bright roof on some slides), so its halo is denser close
   to the letters; the plain ghost button gets the same dark glass as the
   inner heroes and the CTA band. */
@media (max-width: 1024px) {
  .hero-lede { text-shadow: 0 0 2px rgba(16, 12, 12, .95), 0 0 4px rgba(16, 12, 12, .9), 0 0 9px rgba(16, 12, 12, .7), 0 1px 16px rgba(0, 0, 0, .55); }
}
.hero .btn-ghost { --btn-bg: rgba(16, 12, 12, .45); backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px); }
.hero-badge, .hero-chips li { background: rgba(16, 12, 12, .5); backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px); }
.hero-caption { padding: .4rem .75rem; border-radius: var(--r); background: rgba(16, 12, 12, .5); backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px); }
.hero-count { padding: .3rem .65rem; border-radius: var(--r-pill); background: rgba(16, 12, 12, .5); backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px); }

/* Inner page heroes: the eyebrow is gold (with the dark grounds, near the
   top of this file); it, the lede and the trail get a tight dark halo. */
.phero .eyebrow, .phero p, .phero .crumbs { text-shadow: 0 0 2px rgba(16, 12, 12, .6), 0 1px 10px rgba(0, 0, 0, .5); }
.phero .btn-ghost { --btn-bg: rgba(16, 12, 12, .45); backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px); }
/* Up to small laptop width (tablets in landscape included) the lede runs
   out over the lighter right side of the photo: it is white and its halo
   is held denser close to the letters and in the gaps between lines. */
@media (max-width: 1279px) {
  .phero p { color: #fff; text-shadow: 0 0 2px rgba(16, 12, 12, .95), 0 0 4px rgba(16, 12, 12, .9), 0 0 9px rgba(16, 12, 12, .7), 0 0 16px rgba(16, 12, 12, .5), 0 1px 16px rgba(0, 0, 0, .55); }
}
/* The eyebrow is small uppercase type, so its halo is held dense at every
   width (very wide screens show a lighter part of the photo behind it). */
.phero .eyebrow { text-shadow: 0 0 2px rgba(16, 12, 12, .9), 0 0 4px rgba(16, 12, 12, .85), 0 0 8px rgba(16, 12, 12, .7), 0 0 14px rgba(16, 12, 12, .5), 0 1px 14px rgba(0, 0, 0, .5); }
/* On phones and small tablets the trail does the same, and the eyebrow sits
   on the same dark glass as the home hero badge. */
@media (max-width: 760px) {
  .phero .crumbs { text-shadow: 0 0 2px rgba(16, 12, 12, .9), 0 0 4px rgba(16, 12, 12, .8), 0 0 8px rgba(16, 12, 12, .6), 0 1px 14px rgba(0, 0, 0, .5); }
  .phero .eyebrow { padding: .4rem .75rem; border-radius: var(--r-pill); background: rgba(16, 12, 12, .5); backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px); }
}

/* CTA band: on phones the paragraph runs out over the lightest part of the
   photo, so it is white with a shadow, and the phone button has a backing. */
.cta-band p { color: #fff; text-shadow: 0 0 2px rgba(16, 12, 12, .6), 0 1px 12px rgba(0, 0, 0, .5); }
.cta-band .btn-ghost { --btn-bg: rgba(16, 12, 12, .45); backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px); }
/* Up to small laptop width the paragraph still reaches the bright right
   side, so its halo is held denser close to the letters. */
@media (max-width: 1279px) {
  .cta-band p { text-shadow: 0 0 2px rgba(16, 12, 12, .95), 0 0 4px rgba(16, 12, 12, .9), 0 0 9px rgba(16, 12, 12, .7), 0 1px 16px rgba(0, 0, 0, .55); }
}

/* Focus. The accordions clip their overflow, so the ring on a question is
   drawn just inside it; the footer logo link takes its image's box. */
.faq summary:focus-visible, .detail-card summary:focus-visible, .cert summary:focus-visible { outline-offset: -3px; border-radius: inherit; }
.foot-brand a { display: inline-block; }
/* The search field's ring is a box shadow; forced colours paint this one. */
.faq-search:focus-within { outline: 3px solid transparent; outline-offset: 2px; }

/* Tap targets: 44px wherever a thumb has to land, by padding rather than
   larger type, with the padding taken back out of the layout. */
.foot-bar ul { column-gap: 1.3rem; row-gap: 0; margin-block: -.85rem; }
.foot-bar a { display: inline-block; padding-block: .85rem; }
.faq-call-link { min-height: 44px; }
.socials a { width: 44px; height: 44px; }
/* The source links sit inline at the end of a sentence, so their target is
   a transparent box around the text: tall enough at the smaller desktop
   type, and a touch wider for a short label like "Source". It is drawn
   outside the link's own box, so the focus ring stays tight on the words
   and does not cut through the line above. It uses ::before because ::after
   carries the citation arrow. */
.lf-src { position: relative; }
.lf-src::before { content: ''; position: absolute; inset: -.95rem -.15rem; }
.cert-verify { min-height: 44px; padding-block: .7rem; margin-block: -.5rem .6rem; }
.hub-chip { min-height: 44px; }
.contact-row a { display: inline-block; padding-block: .7rem; margin-block: -.7rem; }
.hotspot::before { content: ''; position: absolute; inset: -6px; border-radius: 50%; }
/* The map renders about 350px wide on phones: a 32 unit hit circle there is
   45px across. */
@media (max-width: 760px) { .area-pin .pin-hit { r: 32px; } }

/* Readability floor for functional text declared below the main block. */
@media (max-width: 1024px) {
  .lf-src, .lf-note, .lf-timeline time, .cert-verify { font-size: .8175rem; }
}

/* Homepage reviews heading, in the rating bar. */
.rating-bar-h { font-size: var(--t-h3); margin-top: .7rem; }

/* Print: blocks not yet scrolled to are still at opacity 0 (app.js also
   reveals them on beforeprint); the ghost words are decoration. The stacked
   halos above are drawn into a PDF as extra copies of the text, so a search
   or a screen reader would meet each line several times. Without them the
   white type on the photo bands needs the wash behind it, which a browser
   leaves out by default when printing (and greys the type for white paper),
   so those bands always print with their photo and wash. */
@media print {
  [data-reveal] { opacity: 1 !important; transform: none !important; transition: none !important; }
  .ghost, .errpage-ghost { display: none !important; }
  .hero h1, .hero h1 em, .hero-lede, .phero .eyebrow, .phero p, .phero .crumbs, .cta-band p { text-shadow: none !important; }
  .hero, .phero, .cta-band { -webkit-print-color-adjust: exact; print-color-adjust: exact; }
}

/* Forced colours. Selected states keep the system highlight so they read as
   selected; the map and the compare grip are drawn in system colours, since
   SVG fills and background shapes are otherwise lost; the outlined ghost
   words would render as solid type, so they go. */
@media (forced-colors: active) {
  .ghost, .errpage-ghost { display: none; }
  .chip input:checked + span,
  .gal-chip.is-on,
  .hub-chip[aria-pressed="true"],
  .explorer-tab[aria-selected="true"],
  .bu-btn[aria-pressed="true"],
  .filter-row .area-chip.is-live { forced-color-adjust: none; background: Highlight; border-color: Highlight; color: HighlightText; }
  .gal-chip.is-on b,
  .bu-btn[aria-pressed="true"] .chip { forced-color-adjust: none; background: HighlightText; color: Highlight; }
  .hub-chip[aria-pressed="true"] span,
  .explorer-tab[aria-selected="true"] svg,
  .bu-btn[aria-pressed="true"] :is(b, small) { color: HighlightText; }
  .compare-grip { forced-color-adjust: none; background: CanvasText; }
  .compare-grip::after { background: CanvasText; }
  .compare-grip::before { background: Canvas; }
  .area-map text { fill: CanvasText; }
  .area-map path { stroke: GrayText; }
  .area-pin circle:not(.pin-hit) { fill: CanvasText; }
  .area-pin circle[fill="none"] { fill: none; stroke: CanvasText; }
  a.area-pin:focus-visible circle:not(.pin-hit) { stroke: Highlight; stroke-width: 3; }
  /* The live (hovered or focused) pin: its label stays the system text
     colour, as the white it brightens to would vanish on a light canvas,
     and its dot takes the highlight. */
  .area-pin:hover text, .area-pin.is-live text { fill: CanvasText; }
  .area-pin:hover circle:not(.pin-hit):not([fill="none"]), .area-pin.is-live circle:not(.pin-hit):not([fill="none"]) { fill: Highlight; }
  .area-pin:hover circle[fill="none"], .area-pin.is-live circle[fill="none"] { stroke: Highlight; }
}
/* end accessibility pass */

/* Print, CT-59: every word on the page prints legibly. Dark bands print black
   on white (their photo layers, including the featured service card's photo
   and gradient, drop out, or the black type would sit on the photo); the
   inspection checklist prints all six panels; the review carousel unrolls with
   full review text and no arrows. Collapsed FAQ answers are opened by app.js
   on beforeprint. Rules from the audit's tested print stylesheet. */
@media print {
  .phero-bg, .cta-band-bg, .hotspot-media, .hotspot, .rcar-ctl, .csr-feature .csr-media, .csr-feature::after { display: none !important; }
  .phero, .sec-dark, .cta-band, .stat-strip, .contact-panel, .faq-call, .csr-feature, .cert-bbb { background: #fff !important; color: #000 !important; }
  :is(.phero, .sec-dark, .cta-band, .stat-strip, .contact-panel, .faq-call, .csr-feature, .cert-bbb) * { color: #000 !important; -webkit-text-stroke: 0 !important; text-shadow: none !important; }
  .contact-panel a { word-break: break-all; }
  .hotspot-panel { display: block !important; animation: none !important; margin-bottom: 8pt; break-inside: avoid; }
  .rcar-track { display: block !important; transform: none !important; overflow: visible !important; }
  .rcar-slide { display: block !important; width: auto !important; max-width: none !important; break-inside: avoid; margin-bottom: 8pt; }
  .rcar .review p, .review.is-clamp p { display: block !important; -webkit-line-clamp: unset !important; overflow: visible !important; }
}

/* ---------- Global components: forms, call bar, carousels, menus (Oct 2026) ---------- */
/* iOS Safari zooms into any field set under 16px, so on phones and tablets
   every field, the FAQ search included, is 16px (DS-2). */
@media (max-width: 1024px) {
  .field input, .field select, .field textarea, .faq-search input { font-size: 16px; }
  /* Room for a few lines of detail, with the example in full (DS-43). */
  .field textarea { min-height: 120px; }
}
/* The roof check has carried its answers into the form below (DS-3). */
.lead-prefill { display: flex; align-items: center; gap: .55rem; margin: -.2rem 0 1rem; padding: .7rem .95rem; border-radius: var(--r); background: var(--red-wash); color: var(--red-deep); font-size: .9rem; font-weight: 600; line-height: 1.4; }
.lead-prefill[hidden] { display: none; }
.lead-prefill svg { width: 18px; height: 18px; flex: none; }

/* Call bar: the second button is a white outline pill, so it reads as a
   button beside the red Call (DS-6, CRO-6). */
.callbar .btn-ghost { --btn-bg: transparent; --btn-fg: #fff; box-shadow: inset 0 0 0 1.5px rgba(255, 255, 255, .55); }
.callbar .btn-ghost:hover { --btn-bg: #fff; --btn-fg: var(--ink); box-shadow: inset 0 0 0 1.5px #fff; }
/* High contrast modes drop background colours and inset shadows, which is
   all that draws a button here, so every button gets a real border there
   (CRO-6); the padding gives the 2px back. */
@media (forced-colors: active) {
  .btn { border: 2px solid ButtonText; padding: calc(1.02rem - 2px) calc(1.85rem - 2px); }
  .btn-lg { padding: calc(1.2rem - 2px) calc(2.3rem - 2px); }
  .btn-sm { padding: calc(.78rem - 2px) calc(1.3rem - 2px); }
  .callbar .btn { padding: calc(.95rem - 2px) calc(.6rem - 2px); }
}
@media (forced-colors: active) and (max-height: 500px) {
  .callbar .btn { padding-block: calc(.5rem - 2px); }
}

/* Review carousel. A vertical scroll that starts on it scrolls the page and
   never flips a card; a sideways swipe moves the track under the finger
   (DS-7). A long review opens in place (DS-19): the other cards keep their
   height and the track grows with the open one. */
.rcar { touch-action: pan-y; }
.rcar.is-dragging .rcar-track { transition: none; }
.rcar .review.is-clamp p { -webkit-line-clamp: 7; }
.rcar.has-open .rcar-track { align-items: flex-start; }
.rcar.has-open .rcar-slide .review { height: auto; min-height: var(--rcar-h, 0); }
.rcar .review-more[hidden] { display: none; }
.no-js .rcar .review p { display: block; -webkit-line-clamp: unset; overflow: visible; }
/* Under the name: a Google review, and the month it was written (TR-5). */
.review-id > .review-src { display: flex; align-items: center; gap: .4rem; margin-top: .1rem; }
.review-src svg { width: 13px; height: 13px; flex: none; }
.review-src time { white-space: nowrap; }

/* Compare slider: the pointer is handled in app.js (a drag only starts once
   it is clearly sideways), so a scroll that starts on the photo stays a
   scroll. The range input stays for the keyboard (DS-33). */
.compare.is-js .compare-range { pointer-events: none; }
@media (pointer: fine) { .compare.is-js { cursor: ew-resize; } }

/* Quote band on phones: the drawing sits at its natural size and quieter, so
   the roofline never runs through the words (DS-46). */
@media (max-width: 640px) {
  .quote-draw { transform: none; }
  .quote-draw .d-roof { opacity: .25; }
  .quote-draw .d-line { stroke: rgba(255, 255, 255, .08); }
  .quote-draw .d-fine { stroke: rgba(255, 255, 255, .06); }
}

/* Mega menu: moving from one menu to the next swaps the panels at once,
   rather than fading one out over the other (DS-32). */
.mega.is-instant { transition: none; }

/* Numbered chips, where no icon would mean its label (DS-30). */
.ridge-num { font-family: var(--font-display); font-weight: 800; font-size: 1.08rem; font-stretch: 112%; letter-spacing: .02em; font-variant-numeric: tabular-nums; }

/* Print (DS-50, with FX-26 and CT-59 above): photos under a gradient print
   without it, rather than as a blank box, and no photo fills a page. */
@media print {
  .card-media::after, .hotspot-media::after, .split-media::after { display: none !important; }
  /* A min-height (the tall photo-story frame) would beat the cap. */
  img { max-height: 70mm !important; min-height: 0 !important; width: auto !important; }
  /* The photo no longer fills its frame, so the frame's shadow and fill go
     too, and the photo sits in the middle of it rather than at the left. */
  .split-media, .card-media, .ed-media, .trio-media, .ps-fig { box-shadow: none !important; }
  .split-media, .card-media, .ed-media, .trio-media, .ps-media { background: none !important; }
  :is(.split-media, .card-media, .ed-media, .trio-media, .ps-media) img { display: block; margin-inline: auto; }
  /* The same for every other frame round a photo (DS-50-b: the sticky
     feature, gallery tiles, service cards, city and sign photos, the
     before/after slider), so none prints left-aligned on its fill. A centred
     photo also keeps the slider's 50% clip on the middle of both photos.
     The logo links are left out. */
  :not(a) > picture > img { display: block; margin-inline: auto; }
  :not(a, .phero-bg, .cta-band-bg):has(> picture) { background: none !important; box-shadow: none !important; }
  .stik-frame, .compare { box-shadow: none !important; }
  .stik-frame::after, .tile-media::after { display: none !important; }
  figure, img, picture, blockquote { break-inside: avoid; }
  .review-more { display: none !important; }
}

/* ---------- Homepage widgets, second pass (Oct 2026) ---------- */
/* Hero rating chip: the whole chip goes to the reviews (#reviews), with a
   larger hit area than its outline. */
.hero-chip-link { position: relative; display: inline-flex; align-items: center; gap: .5rem; color: inherit; }
.hero-chip-link::after { content: ''; position: absolute; inset: -.6rem -.9rem; }
.hero-chips li:has(.hero-chip-link) { transition: border-color .25s, background-color .25s; }
.hero-chips li:has(.hero-chip-link:hover) { border-color: rgba(255, 255, 255, .5); }
.hero-chip-link:focus-visible { outline-offset: 8px; border-radius: var(--r-pill); }

/* Material explorer (audit DS-13). A tab never changes text off screen:
   - 761 to 1024: the tabs in two columns, the panel's text beside its photo
     (as on desktop) right under them, not below a photo 800px tall;
   - 760 and under: the tabs are one row of chips that scrolls sideways, and
     the text comes before a 16:9 photo capped at about 340px.
   The dark design and the shared panel cell (no jump between tabs) stay. */
@media (max-width: 760px) {
  .explorer-tabs {
    display: flex;
    gap: .5rem;
    overflow-x: auto;
    overscroll-behavior-x: contain;
    scroll-snap-type: x mandatory;
    scroll-padding-inline: var(--pad-x);
    scrollbar-width: none;
    margin-inline: calc(var(--pad-x) * -1);
    padding: .1rem var(--pad-x) .2rem;
  }
  .explorer-tabs::-webkit-scrollbar { display: none; }
  .explorer-tab { flex: none; width: auto; min-height: 46px; padding: .62rem 1.05rem .62rem .85rem; gap: .6rem; border-radius: var(--r-pill); font-size: .9rem; white-space: nowrap; scroll-snap-align: start; }
  .explorer-tab svg { width: 19px; height: 19px; }
  .explorer-media img { aspect-ratio: 16 / 9; max-height: 340px; }
}

/* Inspection hotspots (/roof-inspection, audit DS-13): the photo and its
   panel stay side by side down to 861px, so a marker never changes text a
   screen below it; narrower, app.js brings the panel into view when needed. */
@media (min-width: 861px) and (max-width: 1024px) {
  .hotspot-wrap { grid-template-columns: 1.3fr .7fr; }
}

/* Core services row (audit DS-18): the row runs out to the edge of the
   screen on both sides, so the card cut off at the right reads as more to
   come rather than a crop, and fades out over the last few rem. The first
   card still lines up with the heading (padding and snap both use the same
   bleed), and the end of the row stops at the content edge. The section
   clips sideways, so a desktop scrollbar (inside 100vw) never adds a page
   scroll. Rows are shared through subgrid, so every photo band starts at
   the same height whatever the length of the text above it. */
.csr-sec { overflow-x: clip; }
.csr-row {
  --bleed: calc((100vw - min(100vw, var(--max))) / 2 + var(--pad-x));
  --fade: min(var(--bleed), 5rem);
  margin-inline: calc(var(--bleed) * -1);
  padding-inline: var(--bleed);
  scroll-padding-inline: var(--bleed);
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 var(--fade), #000 calc(100% - var(--fade)), transparent);
  mask-image: linear-gradient(90deg, transparent, #000 var(--fade), #000 calc(100% - var(--fade)), transparent);
  grid-template-rows: auto minmax(190px, 1fr);
}
.csr-card { grid-row: span 2; }
.csr-card:not(.csr-feature) { display: grid; grid-template-rows: subgrid; }
.csr-card:not(.csr-feature) .csr-media { min-height: 0; }
/* Short laptop screens (a 1366x768 screen shows about 657px of page): the
   main button and the chips are on the first screen (audit CRO-4). Only the
   top margin, the headline size and the gaps give way, each in a straight
   line with the height from its short value at 657px up to its largest
   normal value at 820px (and never above the normal one), so there is no
   jump at the 820px edge, at any width, and 1440x900 and larger screens are
   unchanged. Phones have their own rule above. */
@media (min-width: 1025px) and (max-height: 820px) {
  .hero-inner { padding-top: min(clamp(3.4rem, 2rem + 7vw, 8rem), max(2rem, 8rem - (820px - 100vh) * .61)); }
  .hero-inner, .hero-copy { row-gap: clamp(1.1rem, 1.35rem - (820px - 100vh) * .0245, 1.35rem); }
  .hero h1 { font-size: min(clamp(2.35rem, 1.65rem + 3.15vw, 4.75rem), 4.75rem - (820px - 100vh) * .12); }
}
/* The same lines on the larger root sizes (17px from 1920, 18.5px from
   2400): the whole hero is 17/16 or 18.5/16 taller there, so the edge moves
   up in proportion (820px x 17/16 = 871px, x 18.5/16 = 948px). Each value
   still meets its normal one exactly at that edge, so there is no jump, and
   a 2560x800 window keeps the button and the chips on the first screen. */
@media (min-width: 1920px) and (max-height: 871px) {
  .hero-inner { padding-top: min(clamp(3.4rem, 2rem + 7vw, 8rem), max(2rem, 8rem - (871.25px - 100vh) * .61)); }
  .hero-inner, .hero-copy { row-gap: clamp(1.1rem, 1.35rem - (871.25px - 100vh) * .0245, 1.35rem); }
  .hero h1 { font-size: min(clamp(2.35rem, 1.65rem + 3.15vw, 4.75rem), 4.75rem - (871.25px - 100vh) * .12); }
}
@media (min-width: 2400px) and (max-height: 948px) {
  .hero-inner { padding-top: min(clamp(3.4rem, 2rem + 7vw, 8rem), max(2rem, 8rem - (948.125px - 100vh) * .61)); }
  .hero-inner, .hero-copy { row-gap: clamp(1.1rem, 1.35rem - (948.125px - 100vh) * .0245, 1.35rem); }
  .hero h1 { font-size: min(clamp(2.35rem, 1.65rem + 3.15vw, 4.75rem), 4.75rem - (948.125px - 100vh) * .12); }
}
/* end homepage widgets, second pass */

/* ---------- Check us yourself (audit TR-10) ----------
   The public records behind the credentials: chips, never underlined links
   in the copy. Each opens the record (or the public search that finds it) in
   a new tab, so the label carries the source and the citation arrow. Light
   by default (under the /contact form and panel too); .proof-dark on the dark straight talk
   blocks. */
.proof { display: grid; gap: .75rem; }
.proof-h { display: inline-flex; align-items: center; gap: .5rem; margin: 0; font-family: var(--font-display); font-size: .78rem; font-weight: 700; letter-spacing: .1em; text-transform: uppercase; color: var(--ink); }
.proof-h svg { width: 16px; height: 16px; flex: none; color: var(--red); }
.proof-links { display: flex; flex-wrap: wrap; gap: .5rem; margin: 0; padding: 0; list-style: none; }
.proof-links li { display: flex; max-width: 100%; }
/* Every chip is the same two lines, the record over its source, so a row
   of them reads as one set at any width rather than a mix of one and two
   line pills. */
.proof-link {
  display: inline-flex; flex-direction: column; align-items: flex-start; justify-content: center; gap: .12rem;
  min-height: 44px; max-width: 100%; padding: .6rem 1.1rem .62rem; border-radius: var(--r-lg);
  border: 1.5px solid var(--line-2); background: #fff; color: var(--ink); text-decoration: none;
  transition: border-color .25s, color .25s, background-color .25s;
}
.proof-link b { font-size: .86rem; font-weight: 650; }
.proof-src { font-size: .72rem; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--body-dim); white-space: nowrap; }
.proof-src::after { content: '\2197'; margin-left: .3em; letter-spacing: 0; }
.proof-link:hover { border-color: var(--red); color: var(--red-deep); }
.proof-link:hover .proof-src { color: var(--red-deep); }
.proof-dark .proof-h { color: #fff; }
.proof-dark .proof-h svg { color: var(--gold); }
.proof-dark .proof-link { background: rgba(255, 255, 255, .06); border-color: var(--line-dark-2); color: #fff; }
.proof-dark .proof-src { color: rgba(255, 255, 255, .66); }
.proof-dark .proof-link:hover { background: rgba(255, 255, 255, .12); border-color: #fff; color: #fff; }
.proof-dark .proof-link:hover .proof-src { color: #fff; }
/* On /contact the chips run under the form and the office panel. */
.contact-proof { margin-top: clamp(1.6rem, 1.2rem + 1.2vw, 2.4rem); }
/* Under an answer: a little air after the last paragraph. In the /about
   credentials block: between the heading and the brand tiles. */
.faq-a .proof { margin-top: 1.1rem; }
.cert-proof { margin-bottom: clamp(1.6rem, 1.2rem + 1.4vw, 2.4rem); }
.honest-proof { margin-top: 1.4rem; }
@media (max-width: 1024px) { .proof-src { font-size: .8175rem; } }
/* Phones: one column of equal rows, like the /contact panel, rather than a
   ragged wrap of chips of different widths. */
@media (max-width: 640px) {
  .proof-links { display: grid; grid-template-columns: minmax(0, 1fr); }
  .proof-link { width: 100%; }
  .proof-link b { font-size: .9rem; }
}

/* ---------- Content pages, page structure (cluster E1, Oct 2026) ---------- */
/* Prompt to act (audit CRO-8, DS-24): one line, the red booking button and
   the office number, as a white bar under a section's cards. Phones stack
   the line over two full width buttons. */
.act-line {
  display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 1rem 2rem;
  margin-top: clamp(1.4rem, 1rem + 1.4vw, 2.2rem); padding: 1rem 1rem 1rem 1.2rem;
  background: #fff; border: 1px solid var(--line); border-radius: var(--r-xl); box-shadow: var(--sh-sm);
}
.act-text { display: flex; align-items: center; gap: .85rem; margin: 0; font-family: var(--font-display); font-weight: 650; font-size: var(--t-h4); line-height: 1.35; color: var(--ink); }
.act-text > svg { flex: none; box-sizing: content-box; width: 18px; height: 18px; padding: 9px; border-radius: 50%; background: var(--red-wash); color: var(--red-deep); }
.act-line .btn-row { flex: none; gap: .6rem; }
.act-dark { background: rgba(255, 255, 255, .05); border-color: var(--line-dark-2); box-shadow: none; }
.act-dark .act-text { color: #fff; }
.act-dark .act-text > svg { background: rgba(255, 255, 255, .08); color: var(--gold); }
@media (max-width: 640px) {
  .act-line { flex-direction: column; align-items: stretch; padding: 1.1rem; }
  .act-line .btn-row { display: grid; grid-template-columns: minmax(0, 1fr); }
  .act-line .btn { justify-content: center; }
}
@media (forced-colors: active) { .act-text > svg { forced-color-adjust: auto; background: none; } }

/* Blog posts: the same offer as a small box where the second section ends
   (CRO-8). From 1025px the sticky aside sits beside the text with it. */
.prose .post-act { margin-block: 2.2rem; padding: 1.3rem 1.4rem 1.4rem; background: var(--paper-2); border-left: 3px solid var(--red); border-radius: 0 var(--r) var(--r) 0; }
.prose .post-act p { margin: 0 0 1rem; color: var(--body); }
.prose .post-act p b { display: block; margin-bottom: .2rem; font-family: var(--font-display); font-size: var(--t-h4); color: var(--ink); }
.prose .post-act .btn-row { gap: .6rem; }
.prose .post-act + h2 { margin-top: 0; }
@media (min-width: 1025px) { .prose .post-act { display: none; } }

/* A showcase of four (the /commercial services) fills one row from 1025px
   instead of scrolling (four columns of about 225px still hold the card
   text); narrower screens keep the swipe row. app.js drops the row's
   focus stop and "scroll sideways" label while it does not overflow. */
@media (min-width: 1025px) {
  .csr-fit .csr-row { grid-auto-flow: row; grid-auto-columns: auto; grid-template-columns: repeat(4, minmax(0, 1fr)); overflow: visible; cursor: auto; }
  .csr-fit .csr-ctl { display: none; }
}

/* /services: a group's hub as a pill under its heading (DS-29). */
.svc-links { margin: calc(-1 * clamp(1rem, .6rem + 1.2vw, 1.9rem)) 0 clamp(1.6rem, 1.2rem + 1.4vw, 2.4rem); }

/* A group of two (gutters and windows) lays each card sideways from 1180px,
   so two cards do not carry 470px photographs. Below that the text column
   would be too narrow for the card's link on one line, so tablets and small
   laptops keep the upright two up cards of the groups above it. From 1025px,
   where those groups go three up, the pair's photos are cut to 2:1 so they
   stand about as tall as the three up photos beside them. Sideways, each
   body starts at the top and its link sits at the bottom, so the two
   headings and the two links line up. */
@media (min-width: 1025px) and (max-width: 1179px) {
  .svc-pair .card-media { aspect-ratio: 2 / 1; }
}
@media (min-width: 1180px) {
  .svc-pair .svc-card { flex-direction: row; }
  .svc-pair .card-media { flex: 0 0 42%; aspect-ratio: auto; min-height: 260px; }
  .svc-pair .card-body { padding: 1.6rem 1.7rem; }
}

/* Footer: gutters and windows under the commercial links (DS-29). */
.foot-title.foot-sub { margin-top: 1.9rem; }
@media (max-width: 560px) { .foot-grid > .foot-col:not(:last-child) .foot-title.foot-sub { min-height: 0; } }

/* /faq: the homepage questions after the full general answers, and the two
   city rows, a question with a chip for each city (DS-36). */
.hub-list-more { margin-top: .9rem; }
.hub-multi { background: #fff; border: 1px solid var(--line); border-radius: var(--r); }
.hub-multi .hub-q { background: none; border: 0; padding-bottom: .55rem; }
.hub-multi .hub-q:hover { box-shadow: none; }
.hub-multi .hub-q-where { color: var(--body-dim); }
.hub-cities { display: flex; flex-wrap: wrap; gap: .4rem; padding: 0 1.2rem 1.1rem; }
.hub-cities a { display: inline-flex; align-items: center; gap: .35rem; min-height: 44px; padding: .5rem .85rem; border: 1.5px solid var(--line-2); border-radius: var(--r-pill); font-size: .84rem; font-weight: 600; color: var(--ink); transition: border-color .25s, color .25s; }
.hub-cities a svg { width: 13px; height: 13px; flex: none; }
.hub-cities a:hover { border-color: var(--red); color: var(--red-deep); }
@media (max-width: 560px) { .hub-cities { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); } .hub-cities a { justify-content: space-between; } }
/* end cluster E1 */

/* ==========================================================================
   Cluster E2 (Oct 2026): new sections and the local articles.
   ========================================================================== */

/* A light split on white with a hairline above, so it does not run into the
   tinted split before it (homepage gutters, HOME-COMM-GUT). */
.sec-white { background: #fff; border-top: 1px solid var(--line); }
/* A quiet line of credentials over a split's buttons. */
.split-note { display: flex; align-items: flex-start; gap: .6rem; margin-top: 1.5rem; padding-top: 1.1rem; border-top: 1px solid var(--line); font-size: var(--t-sm); line-height: 1.55; color: var(--body-dim); }
.split-note svg { width: 18px; height: 18px; flex: none; margin-top: .1rem; color: var(--gold); }

/* ---------- Credentials you can check for yourself (homepage) ---------- */
.creds-sec { overflow: hidden; }
.creds-head { text-align: center; max-width: 46rem; margin-inline: auto; }
.creds-head h2 { font-size: var(--t-h2); margin-block: .7rem .9rem; }
.creds-head h2 em { font-style: normal; color: var(--red); display: block; }
.creds-head p { font-size: var(--t-lead); color: var(--body-dim); max-width: 52ch; margin-inline: auto; }
.creds-facts { list-style: none; margin: clamp(1.6rem, 1.2rem + 1vw, 2.2rem) auto 0; padding: 0; width: min(680px, 100%); display: grid; grid-template-columns: repeat(3, 1fr); gap: 1px; background: var(--line); border-block: 1px solid var(--line); }
.creds-facts li { background: var(--paper); padding: 1.05rem .8rem 1.1rem; text-align: center; }
.creds-facts b { display: block; font-family: var(--font-display); font-stretch: 112%; font-weight: 800; font-size: clamp(1.5rem, 1.2rem + 1vw, 2rem); line-height: 1; letter-spacing: -.02em; color: var(--ink); }
.creds-facts b .suf { color: var(--red); }
.creds-facts li > span { display: block; margin-top: .5rem; font-size: .7rem; font-weight: 600; letter-spacing: .12em; text-transform: uppercase; color: var(--body-dim); line-height: 1.35; }
.creds { margin-top: clamp(2.2rem, 1.6rem + 2vw, 3.4rem); }
.creds-track {
  --cred-w: clamp(300px, 26vw, 440px);
  list-style: none; margin: 0;
  display: flex; gap: clamp(1rem, .7rem + .8vw, 1.5rem);
  overflow-x: auto; overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory; scroll-behavior: smooth;
  padding: .4rem var(--col-edge) 1.6rem;
  scroll-padding-inline: var(--col-edge);
  scrollbar-width: none;
}
.creds-track::-webkit-scrollbar { display: none; }
.creds-track:focus-visible { outline: 3px solid var(--red); outline-offset: -3px; }
.cred { flex: 0 0 var(--cred-w); scroll-snap-align: start; display: flex; flex-direction: column; background: #fff; border: 1px solid var(--line); border-radius: var(--r-lg); overflow: hidden; box-shadow: var(--sh); }
.cred-media { position: relative; margin: 0; aspect-ratio: 16 / 10; overflow: hidden; background: var(--paper-3); }
.cred-media picture, .cred-media img { display: block; width: 100%; height: 100%; object-fit: cover; }
.cred-media::after { content: ''; position: absolute; inset: 0; background: linear-gradient(180deg, rgba(16, 12, 12, .28), rgba(16, 12, 12, 0) 42%); pointer-events: none; }
/* Typeset credential mark, the slot an official badge file takes later. */
.cred-mark { position: absolute; z-index: 1; top: .9rem; right: .9rem; display: grid; justify-items: center; gap: .38rem; min-width: 104px; padding: .7rem .9rem .65rem; background: rgba(16, 12, 12, .66); backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px); border: 1px solid rgba(217, 188, 121, .34); border-radius: 12px; text-align: center; }
.cred-mark b { font-family: var(--font-display); font-stretch: 112%; font-weight: 800; font-size: 1.12rem; line-height: 1; color: #fff; letter-spacing: -.01em; }
.cred-mark i { display: block; width: 22px; height: 2px; border-radius: 2px; background: var(--gold); }
.cred-mark small { font-family: var(--font-display); font-stretch: 112%; font-weight: 700; font-size: .58rem; letter-spacing: .18em; text-transform: uppercase; color: var(--gold-soft); line-height: 1.2; }
.cred-mark.has-badge { min-width: 0; padding: .5rem; background: #fff; border-color: var(--line); }
.cred-mark.has-badge img { width: 64px; height: 64px; object-fit: contain; }
.cred-body { display: flex; flex-direction: column; flex: 1; padding: clamp(1.2rem, 1rem + .6vw, 1.6rem); }
/* The count, then the issuer wrapping in its own column, in a two line slot
   filled from the bottom, so a long issuer (BBB, CIB) running to a second
   line does not push its title below its neighbours'. */
.cred-meta { display: flex; flex-wrap: nowrap; align-items: flex-end; min-height: 2.8em; gap: .65rem; margin-bottom: .6rem; font-family: var(--font-display); font-stretch: 112%; font-weight: 700; font-size: .68rem; letter-spacing: .16em; text-transform: uppercase; color: var(--red-deep); line-height: 1.4; }
.cred-meta span:first-child { color: var(--body-dim); white-space: nowrap; }
.cred-meta span:last-child { min-width: 0; }
.cred-body h3 { font-size: var(--t-h4); line-height: 1.2; color: var(--ink); }
.cred-body p:not(.cred-meta) { margin-top: .5rem; font-size: .95rem; line-height: 1.6; color: var(--body-dim); }
/* The button sits in a fixed top row and the note under it in a reserved two
   line row, so every card's button lines up whether it has a note or not. */
.cred-verify { margin-top: auto; padding-top: 1.2rem; display: grid; grid-template-rows: auto calc(2 * 1.35 * .78rem); justify-items: start; align-items: start; row-gap: .55rem; }
.cred-who { grid-row: 2; font-size: .78rem; color: var(--body-dim); line-height: 1.35; }
.creds-ctl { justify-content: center; margin-top: .6rem; }
.creds-ctl .rcar-btn[aria-disabled="true"] { opacity: .25; cursor: default; transform: none; }
.creds-note { margin-top: .9rem; text-align: center; font-size: var(--t-sm); color: var(--body-dim); }
@media (max-width: 1024px) { .creds-track { --cred-w: min(46vw, 400px); } }
@media (max-width: 640px) {
  .creds-track { --cred-w: calc(100vw - 2 * var(--pad-x) - 2.2rem); }
  .creds-facts li { padding: .9rem .35rem .95rem; }
  .creds-facts li > span { font-size: .62rem; letter-spacing: .07em; }
}
/* 360px and narrower: tighter tracking keeps the longest issuer (CIB) to
   the two line slot. */
@media (max-width: 380px) { .cred-meta { letter-spacing: .1em; gap: .5rem; } }
@media (prefers-reduced-motion: reduce) { .creds-track { scroll-behavior: auto; } }
/* Without JavaScript the row still scrolls; the buttons would do nothing. */
.no-js .creds-ctl { display: none; }

/* ---------- What every Champion roof includes (/roof-replacement) ---------- */
.inc-grid { display: grid; grid-template-columns: minmax(0, .82fr) minmax(0, 1.18fr); gap: clamp(2rem, 1rem + 4vw, 5.5rem); align-items: start; }
.inc-media { position: sticky; top: calc(var(--header-h) + 1.5rem); margin: 0; border-radius: var(--r-xl); overflow: hidden; box-shadow: 0 30px 70px rgba(0, 0, 0, .45); border-top: 3px solid var(--red); }
.inc-media picture { display: block; aspect-ratio: 4 / 5.1; }
.inc-media img { display: block; width: 100%; height: 100%; object-fit: cover; }
.inc-cap { position: absolute; left: 0; right: 0; bottom: 0; display: flex; align-items: center; gap: .9rem; padding: 1.4rem 1.3rem 1.2rem; background: linear-gradient(to top, rgba(10, 8, 8, .9) 35%, transparent); color: #fff; }
.inc-cap .ridge-chip { width: 40px; height: 40px; border-radius: 11px; background: rgba(255, 255, 255, .1); color: var(--gold); border: 1px solid rgba(201, 164, 77, .4); }
.inc-cap .ridge-chip svg { width: 19px; height: 19px; }
.inc-cap b { display: block; font-family: var(--font-display); font-stretch: 112%; font-size: 1rem; line-height: 1.2; color: #fff; }
.inc-cap span span { display: block; font-size: .8rem; color: rgba(255, 255, 255, .66); margin-top: .1rem; }
.inc-head h2 { font-size: var(--t-h2); margin-block: .7rem .9rem; }
.inc-head h2 em { font-style: normal; color: var(--red-soft); }
.inc-head p { font-size: var(--t-lead); color: rgba(255, 255, 255, .7); max-width: 54ch; }
.inc-list { list-style: none; margin: clamp(1.8rem, 1.4rem + 1vw, 2.4rem) 0 0; padding: 0; border-top: 1px solid var(--line-dark); }
.inc-item { display: grid; grid-template-columns: 4.2rem 1fr; gap: 1rem; padding: 1.6rem 0; border-bottom: 1px solid var(--line-dark); }
.inc-num { font-family: var(--font-display); font-stretch: 112%; font-weight: 800; font-size: 2.2rem; line-height: .9; letter-spacing: -.02em; color: transparent; -webkit-text-stroke: 1.2px var(--gold); padding-top: .02em; }
.inc-item h3 { font-size: var(--t-h4); line-height: 1.25; }
.inc-item p { margin-top: .5rem; font-size: .96rem; line-height: 1.66; color: rgba(255, 255, 255, .66); max-width: 62ch; }
.inc-tag { display: inline-flex; align-items: center; gap: .45rem; margin-top: .9rem; padding: .38rem .8rem; border-radius: var(--r-pill); border: 1px dashed rgba(217, 188, 121, .55); font-family: var(--font-display); font-stretch: 112%; font-weight: 700; font-size: .66rem; letter-spacing: .14em; text-transform: uppercase; color: var(--gold-soft); }
.inc-tag svg { width: 14px; height: 14px; flex: none; }
.inc-foot { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 1.4rem 2rem; margin-top: 2rem; }
.inc-marks { display: flex; gap: 1.6rem; }
.inc-mark + .inc-mark { padding-left: 1.6rem; border-left: 1px solid var(--line-dark); }
.inc-mark b { display: flex; align-items: center; gap: .5rem; font-family: var(--font-display); font-stretch: 112%; font-size: .98rem; color: #fff; }
.inc-mark .stars svg { width: 13px; height: 13px; }
.inc-mark small { display: block; margin-top: .3rem; font-size: .66rem; font-weight: 600; letter-spacing: .14em; text-transform: uppercase; color: rgba(255, 255, 255, .55); }
@media (max-width: 900px) {
  .inc-grid { grid-template-columns: 1fr; }
  .inc-media { position: relative; top: auto; }
  .inc-media picture { aspect-ratio: 4 / 3.4; }
}
@media (max-width: 640px) {
  .inc-item { grid-template-columns: 3rem 1fr; gap: .7rem; padding: 1.35rem 0; }
  .inc-num { font-size: 1.7rem; }
  .inc-foot { flex-direction: column; align-items: stretch; }
  .inc-foot .btn-row .btn { width: 100%; }
}

/* ---------- Materials and warranty band (/residential-roofing) ---------- */
.wband { display: grid; grid-template-columns: 1fr 1fr; background: var(--ink); }
/* The photo is landscape and the panel beside it is tall, so the photo is one
   screen high and sticks while the panel scrolls: a full-height half would
   crop it to a garage door and stretch it past its 1280px source. The band's
   own focal point (sections.mjs) keeps the main house in the frame. */
.wband-media { position: sticky; top: var(--header-h); align-self: start; height: min(calc(100svh - var(--header-h)), 100%); overflow: hidden; }
.wband-media picture { position: absolute; inset: 0; }
.wband-media img { width: 100%; height: 100%; object-fit: cover; }
.wband-cred { position: absolute; left: 0; right: 0; bottom: 0; display: flex; align-items: center; gap: 1rem; padding: 2.4rem clamp(1.2rem, .8rem + 2vw, 3rem) 1.6rem; background: linear-gradient(to top, rgba(10, 8, 8, .92) 40%, transparent); color: #fff; }
.wband-cred::before { content: ''; position: absolute; left: clamp(1.2rem, .8rem + 2vw, 3rem); right: 30%; top: 1.2rem; height: 1px; background: linear-gradient(90deg, var(--gold), rgba(201, 164, 77, 0)); }
.wband-cred .ridge-chip { width: 42px; height: 42px; border-radius: 11px; background: rgba(255, 255, 255, .1); color: var(--gold); border: 1px solid rgba(255, 255, 255, .16); }
.wband-cred .ridge-chip svg { width: 20px; height: 20px; }
.wband-cred b { display: block; font-family: var(--font-display); font-stretch: 112%; font-size: 1.08rem; color: #fff; line-height: 1.2; }
.wband-cred span span { display: block; margin-top: .2rem; font-size: .84rem; color: rgba(255, 255, 255, .7); }
.wband-panel { position: relative; overflow: hidden; background: var(--ink); color: rgba(255, 255, 255, .72); padding: var(--sec-y) clamp(1.4rem, .5rem + 4vw, 6rem); }
.wband-panel::before { content: ''; position: absolute; inset: 0; pointer-events: none; opacity: .5; mix-blend-mode: overlay; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)' opacity='.32'/%3E%3C/svg%3E"); }
.wband-panel .ghost { -webkit-text-stroke-color: rgba(255, 255, 255, .085); left: auto; right: clamp(1rem, 2vw, 2.5rem); }
.wband-panel .eyebrow { color: var(--gold); }
.wband-panel .eyebrow svg { color: inherit; }
.wband-inner { position: relative; z-index: 1; max-width: 600px; }
.wband-inner h2 { color: #fff; font-size: var(--t-h2); margin-block: .7rem 1rem; }
.wband-inner h2 em { font-style: normal; color: var(--red-soft); display: block; }
.wband-lede { font-size: var(--t-lead); color: rgba(255, 255, 255, .7); }
.wband-terms { list-style: none; margin: clamp(1.6rem, 1.2rem + 1vw, 2.2rem) 0 2rem; padding: 0; border-top: 1px solid var(--line-dark); }
.wband-terms li { display: grid; grid-template-columns: 8.4rem 1fr; gap: 1.2rem; padding: 1.35rem 0; border-bottom: 1px solid var(--line-dark); }
.wband-val b { display: block; font-family: var(--font-display); font-stretch: 112%; font-weight: 800; font-size: 1.85rem; line-height: 1; letter-spacing: -.02em; color: var(--gold-soft); white-space: nowrap; }
.wband-val b small { font-size: .55em; letter-spacing: 0; }
.wband-val span { display: block; margin-top: .45rem; font-size: .64rem; font-weight: 700; letter-spacing: .15em; text-transform: uppercase; color: rgba(255, 255, 255, .55); }
.wband-terms h3 { color: #fff; font-size: var(--t-h4); line-height: 1.25; }
.wband-terms p { margin-top: .35rem; font-size: .94rem; line-height: 1.62; color: rgba(255, 255, 255, .64); }
.wband .btn-ghost { --btn-fg: #fff; box-shadow: inset 0 0 0 1.5px var(--line-dark-2); }
.wband .btn-ghost:hover { --btn-bg: #fff; --btn-fg: var(--ink); box-shadow: inset 0 0 0 1.5px #fff; }
/* Clear of the call bar, which shows at 1024 and below. */
@media (max-width: 1024px) {
  .wband-media { height: min(calc(100svh - var(--header-h) - 72px), 100%); }
}
@media (max-width: 900px) {
  .wband { grid-template-columns: 1fr; }
  .wband-media { position: relative; top: auto; height: auto; }
  .wband-media picture { position: static; }
  .wband-media img { aspect-ratio: 4 / 3; }
  /* On phones the credential is its own strip under the photo. */
  .wband-cred { position: static; background: var(--ink-2); padding: 1.2rem var(--pad-x); border-bottom: 1px solid var(--line-dark); }
  .wband-cred::before { display: none; }
  .wband-panel { padding-inline: var(--pad-x); }
}
@media (max-width: 640px) {
  .wband-panel .ghost { display: none; }
  .wband-terms li { grid-template-columns: 1fr; gap: .55rem; }
  .wband-val { display: flex; align-items: baseline; gap: .8rem; }
  .wband-val span { margin-top: 0; }
  .wband .btn-row .btn { width: 100%; }
}

/* ---------- Featured customer story (/storm-damage-roof-repair) ---------- */
.story-sec { padding-bottom: calc(var(--sec-y) * .8); }
.story { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.08fr); gap: clamp(2rem, 1rem + 4vw, 5.5rem); align-items: center; }
.story-media { position: relative; padding-top: 1.8rem; }
.story-photo { position: relative; margin: 0; border-radius: var(--r-xl); overflow: hidden; box-shadow: var(--sh-lg); }
.story-photo picture { display: block; aspect-ratio: 1 / 1.04; }
.story-photo img { display: block; width: 100%; height: 100%; object-fit: cover; }
.story-cap { position: absolute; left: 0; right: 0; bottom: 0; display: flex; align-items: center; gap: .8rem; padding: 2.4rem 1.3rem 1.2rem; background: linear-gradient(to top, rgba(10, 8, 8, .78), transparent); color: #fff; }
.story-cap .ridge-chip { width: 38px; height: 38px; border-radius: 10px; background: rgba(255, 255, 255, .14); color: #fff; border: 1px solid rgba(255, 255, 255, .22); }
.story-cap .ridge-chip svg { width: 18px; height: 18px; }
.story-cap b { display: block; font-family: var(--font-display); font-stretch: 112%; font-size: .98rem; color: #fff; line-height: 1.2; }
.story-cap span span { display: block; font-size: .78rem; color: rgba(255, 255, 255, .75); }
.story-rating { position: absolute; top: 0; right: clamp(-1.6rem, -1vw, -.5rem); display: flex; align-items: center; gap: .9rem; padding: .95rem 1.3rem; background: #fff; border-radius: var(--r-lg); box-shadow: var(--sh-lg); border-top: 3px solid var(--red); }
.story-rating > b { font-family: var(--font-display); font-stretch: 112%; font-weight: 800; font-size: 2.3rem; line-height: 1; color: var(--ink); letter-spacing: -.02em; }
.story-rating .stars { display: flex; }
.story-rating > span > span:not(.stars) { display: block; margin-top: .25rem; font-size: .8rem; color: var(--body-dim); }
.story-copy h2 { font-size: var(--t-h2); margin-block: .7rem 1rem; }
.story-copy h2 em { font-style: normal; color: var(--red); }
.story-lead { font-size: var(--t-lead); color: var(--body-dim); max-width: 56ch; }
.story-quote { margin: 1.8rem 0 2rem; padding-left: clamp(1.1rem, .8rem + 1vw, 1.7rem); border-left: 3px solid var(--red); }
.story-stars .stars svg { width: 15px; height: 15px; }
.story-quote blockquote { margin: .7rem 0 0; }
.story-quote blockquote p { font-size: 1.02rem; line-height: 1.75; color: var(--body); }
.story-who { display: flex; flex-wrap: wrap; align-items: center; gap: .8rem 1rem; margin-top: 1.2rem; }
.story-who .review-id { margin-right: auto; }
.story-who .review-id > .review-src { display: flex; align-items: center; gap: .4rem; font-size: .8rem; color: var(--body-dim); }
@media (max-width: 900px) {
  .story { grid-template-columns: 1fr; }
  .story-media { max-width: 560px; }
  .story-photo picture { aspect-ratio: 4 / 3; }
  .story-rating { right: .8rem; }
}
@media (max-width: 640px) {
  .story-rating { padding: .7rem .95rem; gap: .7rem; }
  .story-rating > b { font-size: 1.8rem; }
  .story-who .review-tag { flex-basis: 100%; align-self: flex-start; width: max-content; }
  .story-copy .btn-row .btn { width: 100%; }
}

/* ---------- Articles: comparison tables, sources, link chips (NS-5, NS-8) ---------- */
.prose .csr-links { margin-top: .2rem; margin-bottom: 1.6rem; }
.prose a.csr-link { text-decoration: none; color: var(--ink); font-size: .84rem; }
.prose a.csr-link:hover { border-color: var(--red); color: var(--red-deep); }
.post-checked { display: flex; align-items: flex-start; gap: .55rem; padding: .85rem 1rem; border-radius: var(--r); background: var(--paper-2); font-size: .88rem; line-height: 1.5; color: var(--body-dim); }
.post-checked svg { width: 18px; height: 18px; flex: none; margin-top: .05rem; color: var(--red); }
.prose table { width: 100%; border-collapse: collapse; font-size: .9rem; line-height: 1.5; }
.prose caption { caption-side: top; text-align: left; padding-bottom: .7rem; font-family: var(--font-display); font-stretch: 112%; font-weight: 700; font-size: .7rem; letter-spacing: .15em; text-transform: uppercase; color: var(--red-deep); }
.prose th, .prose td { text-align: left; vertical-align: top; }
/* Comparison table: a striped table, laid out as one block per row so five
   columns stay readable in the article column at every width. */
.cmp-wrap { margin-block: 1.4rem 2rem; }
.cmp thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.cmp tbody { display: grid; border: 1px solid var(--line); border-radius: var(--r); overflow: hidden; }
.cmp tr { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: .55rem 1.2rem; padding: 1rem 1.1rem 1.1rem; background: #fff; }
.cmp tr:nth-child(even) { background: var(--paper-2); }
.cmp tr + tr { border-top: 1px solid var(--line); }
.cmp th[scope="row"] { grid-column: 1 / -1; font-family: var(--font-display); font-stretch: 112%; font-size: 1rem; color: var(--ink); }
.cmp td { color: var(--body); }
.cmp td::before { content: attr(data-label); display: block; margin-bottom: .1rem; font-size: .66rem; font-weight: 700; letter-spacing: .12em; text-transform: uppercase; color: var(--body-dim); }
@media (max-width: 480px) { .cmp tr { grid-template-columns: 1fr; } }
/* Two column verdict under each factor (metal vs asphalt). */
.verdict { margin-block: 1.1rem 2rem; border-collapse: separate; border-spacing: 0; }
.verdict thead th:first-child { border-top-left-radius: var(--r); }
.verdict thead th:last-child { border-top-right-radius: var(--r); }
.verdict td { border-bottom: 1px solid var(--line); }
.verdict td:first-child { border-left: 1px solid var(--line); border-bottom-left-radius: var(--r); }
.verdict td:last-child { border-right: 1px solid var(--line); border-bottom-right-radius: var(--r); }
.verdict thead th { padding: .65rem 1rem; background: var(--ink); color: #fff; font-family: var(--font-display); font-stretch: 112%; font-size: .78rem; letter-spacing: .06em; width: 50%; }
.verdict td { padding: .8rem 1rem .9rem; background: #fff; color: var(--body); }
.verdict td + td, .verdict th + th { border-left: 1px solid var(--line); }
.verdict th + th { border-left-color: rgba(255, 255, 255, .14); }
@media (max-width: 480px) {
  .verdict thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }
  .verdict tr, .verdict td { display: block; }
  .verdict td { border: 1px solid var(--line); border-radius: 0; }
  .verdict td + td { border-top: 0; }
  .verdict td:first-child { border-radius: var(--r) var(--r) 0 0; }
  .verdict td:last-child { border-radius: 0 0 var(--r) var(--r); }
  .verdict td::before { content: attr(data-label); display: block; font-size: .66rem; font-weight: 700; letter-spacing: .12em; text-transform: uppercase; color: var(--body-dim); margin-bottom: .1rem; }
}
.prose .post-src-h { margin-top: 2.4rem; font-size: .78rem; font-family: var(--font-display); font-stretch: 112%; letter-spacing: .15em; text-transform: uppercase; color: var(--body-dim); }
.prose .post-src { list-style: none; padding: 0; margin-top: .6rem; display: grid; gap: .35rem; }
.prose .post-src li { padding-left: 0; font-size: .84rem; line-height: 1.45; }
.prose .post-src li::before { display: none; }
.prose .post-src a { color: var(--body-dim); text-decoration: none; }
.prose .post-src a:hover { color: var(--red-deep); }
@media print { .creds-track { overflow: visible; flex-wrap: wrap; } .cred { flex-basis: 45%; break-inside: avoid; } .creds-ctl { display: none !important; } }
/* end cluster E2 */

/* ---------- Legal pages: the short version and the analytics cards (TR-3) ----------
   /privacy opens with a four point summary, and "Cookies and analytics" names
   every outside service the site loads as a card: what it records, where it
   runs, the cookies it may set, and opt-out links as the same citation chips
   as "Check us yourself" (never underlined links in the copy). */
.prose .legal-short { margin-top: 1.8rem; padding: 1.3rem 1.5rem 1.4rem; background: #fff; border: 1px solid var(--line); border-left: 3px solid var(--red); border-radius: 0 var(--r) var(--r) 0; box-shadow: var(--sh-sm); }
.legal-short-h { display: inline-flex; align-items: center; gap: .5rem; margin: 0 0 .9rem; font-family: var(--font-display); font-stretch: 112%; font-size: .78rem; font-weight: 700; letter-spacing: .12em; text-transform: uppercase; color: var(--ink); }
.legal-short-h svg { width: 16px; height: 16px; flex: none; color: var(--red); }
.prose .legal-short ul { gap: .55rem; }
.prose .legal-tools { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 330px), 1fr)); gap: 1rem; margin-block: 1.5rem; }
.legal-tool { display: flex; flex-direction: column; gap: .85rem; min-width: 0; padding: 1.25rem 1.35rem 1.35rem; background: #fff; border: 1px solid var(--line); border-radius: var(--r-lg); }
.prose .legal-tool h3 { margin: 0; font-size: var(--t-h4); line-height: 1.25; }
.legal-tool-h p { margin: .25rem 0 0; font-size: .7rem; font-weight: 700; letter-spacing: .1em; text-transform: uppercase; color: var(--body-dim); }
.legal-tool > p { margin: 0; font-size: .92rem; line-height: 1.58; }
.legal-tool-meta { display: grid; gap: .55rem; margin: 0; padding-top: .9rem; border-top: 1px solid var(--line); }
.legal-tool-meta > div { display: grid; grid-template-columns: 4.6rem minmax(0, 1fr); gap: .75rem; align-items: baseline; }
.legal-tool-meta dt { font-size: .66rem; font-weight: 700; letter-spacing: .12em; text-transform: uppercase; color: var(--body-dim); }
.legal-tool-meta dd { display: flex; flex-wrap: wrap; gap: .4rem .75rem; margin: 0; font-size: .86rem; line-height: 1.45; color: var(--body); }
/* Cookies: one row per cookie, the name chip and its lifetime side by side
   (a long lifetime wraps in its own cell, never under the chip). */
.legal-tool-meta dd.legal-cks { display: grid; gap: .4rem; }
.legal-ck { display: grid; grid-template-columns: auto minmax(0, 1fr); align-items: baseline; gap: .5rem; font-size: .8rem; color: var(--body-dim); }
.legal-ck code { padding: .08rem .42rem; border-radius: var(--r-sm); background: var(--paper-2); font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: .78rem; color: var(--ink); overflow-wrap: anywhere; }
/* The description sits at the top and the facts and links at the foot, so
   cards side by side line up along their bottom edge. */
.legal-tool-meta { margin-top: auto; }
/* Where subgrid is supported, each card shares four rows (heading,
   description, facts, links) with the card beside it, so the rule above
   "Runs on" and the link chips line up across a row as well. */
@supports (grid-template-rows: subgrid) {
  .legal-tool { display: grid; grid-row: span 4; grid-template-rows: subgrid; row-gap: .85rem; }
  .legal-tool-meta { margin-top: 0; align-self: start; }
  /* A heading that wraps makes the shared row taller; the shorter heading
     sits at the foot of it, right above its description. */
  .legal-tool-h { align-self: end; }
}
/* A narrow card puts each label above its facts, so a cookie and its
   lifetime always fit on one line. (The query sits on the list, not the
   card: containment on the card would switch its subgrid off.) */
.legal-tool-meta { container-type: inline-size; }
@container (max-width: 19rem) {
  .legal-tool-meta > div { grid-template-columns: minmax(0, 1fr); gap: .3rem; }
}
/* .prose sets ul as a ridge-bulleted grid and underlines links; the chips
   keep their own look inside the policy text. */
.prose .proof-links { display: flex; gap: .5rem; }
.prose .proof-links li { padding-left: 0; }
.prose .proof-links li::before { display: none; }
.prose a.proof-link { color: var(--ink); text-decoration: none; }
.prose a.proof-link:hover { color: var(--red-deep); }
/* Phones: the chips stack as one full-width column, as "Check us yourself"
   does everywhere else (this block's display: flex would otherwise win). */
@media (max-width: 640px) {
  .prose .proof-links { display: grid; grid-template-columns: minmax(0, 1fr); }
  .prose .proof-link { width: 100%; }
}
@media (max-width: 480px) {
  .prose .legal-short { padding: 1.1rem 1.15rem 1.2rem; }
  .legal-tool { padding: 1.1rem 1.1rem 1.2rem; }
}
@media print {
  .prose .legal-short, .legal-tool { box-shadow: none; break-inside: avoid; }
  .prose .legal-tools { grid-template-columns: 1fr 1fr; }
}
/* end cluster E3 */
