/* Central Property Services — cpskentucky.com
   Implements ../../DESIGN-SYSTEM.md. Every colour pair in the palette was
   computed against WCAG 2.1, not eyeballed; the ratios are in that file.

   Sibling brand, deliberately not a twin: Central Roof Repair is limestone /
   slate / orange, Archivo + Public Sans, aimed at a homeowner. This is aimed at
   a facilities manager who reads contracts, so the reference is a specification
   sheet rather than a brochure. */

/* Self-hosted, latin subset only. No render-blocking request to a third party.
   All three families are SIL Open Font License; OFL.txt copies live in fonts/. */
@font-face{font-family:"Instrument Sans";font-style:normal;font-weight:600;font-display:swap;src:url("fonts/instrument-sans-600.woff2") format("woff2");unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;}
@font-face{font-family:"Instrument Sans";font-style:normal;font-weight:700;font-display:swap;src:url("fonts/instrument-sans-700.woff2") format("woff2");unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;}
@font-face{font-family:"IBM Plex Sans";font-style:normal;font-weight:400;font-display:swap;src:url("fonts/ibm-plex-sans-400.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:"IBM Plex Sans";font-style:normal;font-weight:500;font-display:swap;src:url("fonts/ibm-plex-sans-500.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:"IBM Plex Sans";font-style:normal;font-weight:600;font-display:swap;src:url("fonts/ibm-plex-sans-600.woff2") format("woff2");unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;}
@font-face{font-family:"IBM Plex Mono";font-style:normal;font-weight:400;font-display:swap;src:url("fonts/ibm-plex-mono-400.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:"IBM Plex Mono";font-style:normal;font-weight:500;font-display:swap;src:url("fonts/ibm-plex-mono-500.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;}

/* ---------------------------------------------------------------- tokens */
:root {
  --paper:       #FAFAF8;
  --card:        #FFFFFF;
  --ink:         #14181B;
  --graphite:    #5A646B;
  --rule:        #DFE3E1;  /* decorative hairlines ONLY — 1.24:1, carries no meaning */
  --rule-strong: #7C8A85;  /* form borders, focus, any boundary that means something */
  --signal:      #0F5C4A;
  --signal-deep: #0A4438;
  --alert:       #B4471F;

  --display: "Instrument Sans", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
  --body:    "IBM Plex Sans", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
  --mono:    "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;

  --content: 720px;
  --wide:   1140px;

  --s1: 4px;  --s2: 8px;  --s3: 12px; --s4: 16px;
  --s5: 24px; --s6: 32px; --s7: 48px; --s8: 64px; --s9: 96px;
}

/* ---------------------------------------------------------------- base */
*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

/* A flex or grid child defaults to min-width:auto and will NOT shrink below its
   min-content width. One long nav row is then wider than a phone, that widens the
   body, and every width:100% element inherits the widened body — so the whole page
   overflows and text clips at the right edge. Measured at 390px on the homepage
   before this rule existed. Fixing it at the source beats overflow-x:hidden on
   body, which hides the symptom and leaves the layout broken. */
.bar > *, .site-nav > *, .grid > *, .hero-actions > * { min-width: 0; }

/* No overflow-x:clip on body. Measured with Playwright at 375px: scrollWidth ==
   clientWidth, zero overflowing elements — there is nothing to hide, and hiding
   it is how a real overflow later goes unnoticed. Verify width with a real
   viewport (Playwright), not headless Chrome --window-size, which crops a
   wider layout and looks exactly like an overflow bug. */
.table-scroll { max-width: 100%; }

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--body);
  font-size: clamp(1rem, 0.98rem + 0.15vw, 1.0625rem);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

img { max-width: 100%; height: auto; display: block; }

/* Native UX integrity (clarity gate pillar 3): no scroll-jacking, no custom
   cursor, and motion is a preference, not a decision we make for the reader. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .01ms !important; transition-duration: .01ms !important; scroll-behavior: auto !important; }
}

/* ---------------------------------------------------------------- layout */
.wrap    { width: 100%; max-width: var(--content); margin-inline: auto; padding-inline: var(--s5); }
.wrap-wide { width: 100%; max-width: var(--wide); margin-inline: auto; padding-inline: var(--s5); }

/* The gutter never drops below 20px at any width. */
@media (max-width: 420px) {
  .wrap, .wrap-wide { padding-inline: 20px; }
}

section { padding-block: var(--s8); }
section + section { border-top: 1px solid var(--rule); }

.band-ink    { background: var(--ink);    color: var(--paper); border-top: none; }
.band-signal { background: var(--signal); color: #fff;         border-top: none; }
.band-ink a, .band-signal a { color: inherit; }

/* ---------------------------------------------------------------- type */
h1, h2, h3 { font-family: var(--display); font-weight: 700; line-height: 1.15; letter-spacing: -0.015em; margin: 0 0 var(--s4); text-wrap: balance; }
h1 { font-size: clamp(2.25rem, 1.7rem + 2.4vw, 3.25rem); }
h2 { font-size: clamp(1.75rem, 1.45rem + 1.3vw, 2.25rem); margin-top: 0; }
h3 { font-size: clamp(1.25rem, 1.15rem + 0.5vw, 1.5rem); font-weight: 600; }

p, ul, ol { margin: 0 0 var(--s4); max-width: 68ch; overflow-wrap: break-word; }
h1, h2, h3, a, td, th, li { overflow-wrap: break-word; }
.lead { font-size: clamp(1.125rem, 1.05rem + 0.4vw, 1.25rem); color: var(--ink); max-width: 62ch; }
.small   { font-size: .875rem; }
.caption { font-size: .8125rem; color: var(--graphite); }
.muted   { color: var(--graphite); }

/* The mono role is load-bearing, not decoration: it marks a fact CPS is willing
   to be held to. A number set in mono on this site is a commitment — which is
   exactly why it may never be invented. */
.fact { font-family: var(--mono); font-size: .9375em; font-weight: 500; font-variant-numeric: tabular-nums; }

.eyebrow {
  font-family: var(--mono); font-size: .75rem; font-weight: 500;
  letter-spacing: .08em; text-transform: uppercase; color: var(--signal);
  margin: 0 0 var(--s3);
}
.band-ink .eyebrow, .band-signal .eyebrow { color: inherit; opacity: .8; }

a { color: var(--signal); text-underline-offset: 3px; }
a:hover { color: var(--signal-deep); }
.band-ink a:hover, .band-signal a:hover { color: inherit; }

:focus-visible { outline: 3px solid var(--signal-deep); outline-offset: 2px; border-radius: 2px; }
.band-ink :focus-visible, .band-signal :focus-visible { outline-color: #fff; }

/* ---------------------------------------------------------------- buttons */
.btn {
  display: inline-block; font-family: var(--body); font-weight: 600;
  font-size: 1rem; line-height: 1.2; text-decoration: none;
  padding: var(--s3) var(--s5); border-radius: 4px; border: 2px solid transparent;
  background: var(--signal); color: #fff;
  transition: background-color .15s ease;
}
.btn:hover { background: var(--signal-deep); color: #fff; }
.btn-lg { font-size: 1.0625rem; padding: var(--s4) var(--s6); }
.btn-outline { background: transparent; color: var(--signal); border-color: var(--signal); }
.btn-outline:hover { background: var(--signal); color: #fff; }
.band-signal .btn { background: #fff; color: var(--signal-deep); }
.band-signal .btn:hover { background: var(--paper); color: var(--signal-deep); }

/* ---------------------------------------------------------------- hero */
.hero { padding-block: var(--s9) var(--s8); }
.hero .lead { margin-bottom: var(--s6); }
.hero-actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s5); }

/* One primary action. The secondary is a text link, visually subordinate on
   purpose — a hero with two co-equal CTAs converts worse than one. */
.hero-actions .secondary { font-weight: 600; }

/* ---------------------------------------------------------------- cards */
.grid { display: grid; gap: var(--s5); }
.grid-2 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 300px), 1fr)); }
.grid-3 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 260px), 1fr)); }
.grid-4 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 240px), 1fr)); }

/* The CRR mid-word-break trap: a three-column block that inherited the 720px
   content width left each card 208px wide and rendered "COMMERCI / AL ROOFS" at
   1440x900. minmax(min(100%, N), 1fr) is what prevents it here — the min()
   lets a card go full width on a phone instead of overflowing. */

.card {
  background: var(--card); border: 1px solid var(--rule); border-radius: 6px;
  padding: var(--s5);
}
.card h3 { margin-bottom: var(--s2); }
.card p:last-child { margin-bottom: 0; }

/* ---------------------------------------------------------------- scope block
   A numbered scope is always paired with its exclusions. Never one without the
   other — the pairing IS the credibility, and a scope with the awkward parts
   removed is marketing. */
.scope { background: var(--card); border: 1px solid var(--rule); border-radius: 6px; padding: var(--s5) var(--s5) var(--s4); }
.scope ol { list-style: none; counter-reset: step; padding: 0; margin: 0; max-width: none; }
.scope ol li { counter-increment: step; position: relative; padding: 0 0 var(--s4) 3rem; }
.scope ol li::before {
  content: counter(step, decimal-leading-zero);
  position: absolute; left: 0; top: .1em;
  font-family: var(--mono); font-size: .8125rem; font-weight: 500; color: var(--signal);
}
.scope ol li strong { display: block; font-weight: 600; }
.scope ol li:last-child { padding-bottom: 0; }

.exclusions { border-left: 3px solid var(--rule-strong); padding: var(--s2) 0 var(--s2) var(--s5); margin-block: var(--s5); }
.exclusions h3 { font-size: 1.0625rem; margin-bottom: var(--s2); }
.exclusions p:last-child { margin-bottom: 0; }

/* ---------------------------------------------------------------- limits
   The component whose whole job is to say no. No brochure site has one. */
.limits { border-left: 4px solid var(--alert); background: var(--card); padding: var(--s5); border-radius: 0 6px 6px 0; }
.limits h3 { color: var(--alert); }
.limits ul { margin-bottom: 0; }

/* The roof line. Appears on every service page that touches water. */
.roofline { border: 1px solid var(--rule-strong); border-radius: 6px; padding: var(--s5); background: var(--card); }
.roofline h3 { font-size: 1.0625rem; }
.roofline p:last-child { margin-bottom: 0; }

/* ---------------------------------------------------------------- tables
   First-class citizens here, not an afterthought. A facilities manager reads
   tables for a living. */
.table-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; margin-bottom: var(--s5); }
table { border-collapse: collapse; width: 100%; background: var(--card); font-size: .9375rem; }
caption { text-align: left; font-size: .8125rem; color: var(--graphite); padding-bottom: var(--s2); }
th, td { text-align: left; padding: var(--s3) var(--s4); border-bottom: 1px solid var(--rule); vertical-align: top; }
th { font-weight: 600; font-size: .8125rem; letter-spacing: .04em; text-transform: uppercase; color: var(--graphite); }
td.num, th.num { text-align: right; font-family: var(--mono); font-variant-numeric: tabular-nums; }
tbody tr:last-child td { border-bottom: none; }

/* ---------------------------------------------------------------- forms */
.field { margin-bottom: var(--s4); }
label { display: block; font-weight: 600; font-size: .9375rem; margin-bottom: var(--s1); }
.hint { display: block; font-weight: 400; font-size: .8125rem; color: var(--graphite); margin-bottom: var(--s2); }

input[type=text], input[type=email], input[type=tel], input[type=url], select, textarea {
  width: 100%; font: inherit; font-size: 1rem; color: var(--ink);
  background: var(--card);
  border: 1px solid var(--rule-strong);   /* 3.45:1 — a boundary that means something */
  border-radius: 4px; padding: var(--s3);
}
textarea { min-height: 7rem; resize: vertical; }
input:focus-visible, select:focus-visible, textarea:focus-visible { border-color: var(--signal-deep); }

/* Errors carry text, never colour alone. */
.error { color: var(--alert); font-size: .875rem; font-weight: 600; margin-top: var(--s1); }
.required { color: var(--alert); }

/* ---------------------------------------------------------------- nav/footer */
.site-header { border-bottom: 1px solid var(--rule); background: var(--card); }
.site-header .bar { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--s4); padding-block: var(--s4); }
.brand { font-family: var(--display); font-weight: 700; font-size: 1.0625rem; color: var(--ink); text-decoration: none; letter-spacing: -0.01em; }
.brand span { display: block; font-family: var(--mono); font-size: .6875rem; font-weight: 400; letter-spacing: .06em; text-transform: uppercase; color: var(--graphite); }
.site-nav { display: flex; flex-wrap: wrap; gap: var(--s5); font-size: .9375rem; font-weight: 500; }
.site-nav a { color: var(--ink); text-decoration: none; }
.site-nav a:hover { color: var(--signal); text-decoration: underline; }

.site-footer { background: var(--ink); color: var(--paper); padding-block: var(--s7); }
.site-footer a { color: var(--paper); }
.site-footer .caption { color: #A8B2B0; }

/* Skip link — keyboard users reach the content without walking the nav. */
.skip { position: absolute; left: -9999px; }
.skip:focus { left: var(--s4); top: var(--s4); z-index: 10; background: var(--card); color: var(--ink); padding: var(--s3) var(--s4); border-radius: 4px; }

/* ---------------------------------------------------------------- utility */
.stack > * + * { margin-top: var(--s5); }
.mt-0 { margin-top: 0; } .mb-0 { margin-bottom: 0; }
.center { text-align: center; }
.visually-hidden { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }

/* ---------------------------------------------------------------- hero media (2026-09-20)
   One eager photograph per page, atmosphere only (DESIGN-SYSTEM §Assets: stock is never
   evidence, never captioned as our work). Two columns from 900px; below that the image
   follows the actions so the H1 and the primary CTA stay inside the first phone viewport
   (clarity gate pillar 1, measured at 390x844 before this rule existed: no CTA visible). */
.hero-grid { display: grid; gap: var(--s7); align-items: center; }
@media (min-width: 900px) { .hero-grid { grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr); } }
.hero-copy > :last-child { margin-bottom: 0; }
.hero-media { margin: 0; }
.hero-media img { width: 100%; aspect-ratio: 16 / 9; object-fit: cover; border: 1px solid var(--rule); border-radius: 4px; background: var(--rule); }
@media (max-width: 720px) { .hero { padding-block: var(--s7); } .hero-grid { gap: var(--s6); } }

/* ---------------------------------------------------------------- mobile nav (2026-09-20)
   Six links wrapped to three rows on a phone and pushed the H1 to ~430px. Below 720px the
   nav collapses behind a real <button> (aria-expanded), toggled by ten lines of vanilla JS
   at the end of each page. No jQuery, no hover-to-reveal. */
.nav-toggle { display: none; font: 600 .9375rem/1 var(--body); color: var(--ink); background: var(--card);
  border: 1px solid var(--rule-strong); border-radius: 4px; padding: var(--s3) var(--s4); cursor: pointer; }
.nav-toggle:focus-visible { outline: 2px solid var(--signal-deep); outline-offset: 2px; }
.nav-toggle[aria-expanded="true"] { background: var(--paper); }
@media (max-width: 720px) {
  .site-header .bar { flex-wrap: wrap; }
  .site-header .brand { flex: 1 1 auto; }
  .nav-toggle { display: inline-flex; align-items: center; gap: var(--s2); }
  .site-nav { display: none; flex: 1 1 100%; flex-direction: column; gap: var(--s3); padding-top: var(--s3); border-top: 1px solid var(--rule); }
  .site-nav.is-open { display: flex; }
  .site-nav a { padding-block: var(--s2); }
}

/* ===== v2 industrial editorial (2026-09-20) =====
   Homepage pilot of the approved restyle (Marcos, 2026-09-20): Linear structure,
   Mercury typographic weight and section bands, utilitarian trade photography.
   Every colour pair introduced here has its computed WCAG ratio in
   DESIGN-SYSTEM.md "v2 - industrial editorial". Nothing above this line was
   removed; the twelve other pages still render on the v1 rules, and every v2
   rule is scoped to a v2 class (.v2, .hero--dark, .has-mark, .band-*) so a v1
   page that never uses them is untouched. */

:root {
  --mint: #7FD1B9;   /* the accent's readable form on ink: 9.97:1 (signal itself on ink is 2.25:1) */
  --dust: #A8B2B0;   /* secondary text on ink: 8.21:1 */
  --ease-out: cubic-bezier(.23, 1, .32, 1);
}

/* Browser surfaces carry the design too: selection in the accent, not the OS blue. */
::selection { background: var(--signal); color: #fff; }

/* -- header: the mark sits beside the wordmark. Scoped to .has-mark so the v1
      header (plain text + block span) on the other pages is unchanged. */
.brand.has-mark { display: inline-flex; align-items: center; gap: var(--s3); }
.brand.has-mark .brand-mark { width: 28px; height: 28px; flex: 0 0 28px; }
.brand.has-mark .brand-text {
  display: block; font-family: var(--display); font-size: 1.0625rem; font-weight: 700;
  letter-spacing: -0.01em; text-transform: none; color: var(--ink); line-height: 1.15;
}

/* -- buttons: press feedback (160ms, transform only) and a paper outline variant
      for dark bands. The paper outline is a real 2px border, so on ink it reads
      as a control at 17.08:1 without a fill. */
.btn { transition: background-color .15s ease, color .15s ease, transform .16s var(--ease-out); }
.btn:active { transform: scale(.98); }
.btn-paper, .band-ink .btn-paper, .hero--dark .btn-paper {
  background: transparent; color: var(--paper); border-color: var(--paper);
}
.btn-paper:hover, .band-ink .btn-paper:hover, .hero--dark .btn-paper:hover {
  background: var(--paper); color: var(--ink);
}
.btn-paper .fact { white-space: nowrap; }  /* the number never breaks across lines inside a button */
/* Signal fill on ink is only 2.25:1 as a shape, so the label (7.92:1) is what
   identifies the control; a half-strength mint edge (3.3:1) draws the boundary. */
.band-ink .btn:not(.btn-paper) { border-color: rgba(127, 209, 185, .5); }

/* -- hero: full-bleed ink band, the page photograph under a scrim. The <img>
      keeps its src/srcset/sizes/loading/fetchpriority; only its box changes.
      The scrim is the one gradient on the site: .94 ink at the text edge,
      .70 at the far edge (paper on the far-edge worst case is 6.33:1). */
.hero--dark {
  position: relative; overflow: hidden; isolation: isolate;
  background: var(--ink); color: var(--paper);
  display: flex; align-items: center; min-height: 70vh;
  padding-block: var(--s9) var(--s8);
}
.hero--dark > .wrap-wide { position: relative; z-index: 1; }
.hero--dark .hero-media { position: absolute; inset: 0; margin: 0; z-index: 0; }
.hero--dark .hero-media img {
  width: 100%; height: 100%; aspect-ratio: auto; object-fit: cover; object-position: 60% 50%;
  border: 0; border-radius: 0; background: var(--ink);
}
.hero--dark .hero-media::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(90deg, rgba(20,24,27,.94) 0%, rgba(20,24,27,.90) 42%, rgba(20,24,27,.70) 100%);
}
.hero--dark .hero-copy { max-width: 48rem; }  /* r1 judge: 43rem set the H1 five lines deep at 1440; 48rem is four */
.hero--dark .eyebrow { color: var(--mint); opacity: 1; margin-bottom: var(--s4); }
.hero--dark h1 {
  font-size: clamp(2.5rem, 6vw, 4.5rem); line-height: 1.02; letter-spacing: -0.028em;
  color: var(--paper); margin-bottom: var(--s5);
}
.hero--dark .lead {
  color: var(--paper); opacity: .85; max-width: 56ch;
  font-size: clamp(1.0625rem, 1rem + .4vw, 1.25rem); line-height: 1.5; margin-bottom: var(--s6);
}
.hero--dark .hero-actions { gap: var(--s4); }
.hero--dark .hero-copy > p:not(.eyebrow):not(.lead) { max-width: 60ch; }
.hero--dark .hero-actions + p { margin-top: var(--s5); opacity: .85; }  /* the "call 911 first" line under the buttons */
/* One authored moment: the hero copy settles in over 300ms on load, from an
   already-visible default. Reduced-motion collapses it through the global rule. */
.hero--dark .hero-copy { transition: opacity .3s var(--ease-out), transform .3s var(--ease-out); }
@starting-style { .hero--dark .hero-copy { opacity: 0; transform: translateY(8px); } }
@media (max-width: 720px) {
  .hero--dark { min-height: auto; padding-block: var(--s6) var(--s7); }
  /* Rollout: the two longest H1s (gutter, exterior cleaning) pushed the primary CTA
     under the call bar at 390x844 at 2.5rem. Phones step the H1 down one size;
     the desktop clamp is untouched. */
  .hero--dark h1 { font-size: clamp(2rem, 9.4vw, 2.5rem); }
  .hero--dark .lead { font-size: 1rem; }
  .hero--dark .hero-media::after { background: rgba(20, 24, 27, .84); }  /* flat on phones: text spans the width */
  .hero--dark .hero-actions { flex-direction: column; align-items: stretch; }
  .hero--dark .hero-actions .btn { text-align: center; padding-inline: var(--s4); }  /* r1 judge at 375: the emergency label wrapped at 32px side padding */
}
/* r1 judge at 375px: brand + Menu button wrapped to two rows. Under 420px the
   wordmark steps down one size so the header stays a single 74px row. */
@media (max-width: 420px) {
  .site-header .bar { gap: var(--s3); }
  .brand.has-mark { gap: var(--s2); }
  .brand.has-mark .brand-text { font-size: .9375rem; }
  .brand.has-mark .brand-text span { font-size: .625rem; }
}

/* -- section rhythm: numbered mono kicker, larger H2, wider vertical beat.
      Bands alternate paper / card / ink; each declares its own ground. */
.v2 section { padding-block: clamp(64px, 7vw, 96px); }
.v2 h2 { font-size: clamp(1.875rem, 1.35rem + 1.7vw, 2.5rem); letter-spacing: -0.022em; margin-bottom: var(--s5); }
.band-paper { background: var(--paper); }
.band-card  { background: var(--card); }
.kicker {
  display: flex; align-items: center; gap: var(--s3); margin: 0 0 var(--s4);
  font-family: var(--mono); font-size: .8125rem; font-weight: 500;
  letter-spacing: .06em; text-transform: uppercase; color: var(--signal);
}
.kicker b { display: inline-flex; align-items: center; gap: var(--s3); font-weight: 500; font-variant-numeric: tabular-nums; }
.kicker b::after { content: ""; width: 24px; height: 1px; background: currentColor; opacity: .55; }
.band-ink .kicker { color: var(--mint); }
.v2 .card, .v2 .scope, .v2 .roofline { border-radius: 4px; }
.v2 .limits { border-radius: 0 4px 4px 0; }

/* -- trust row: three true statements, one icon each. No numbers, no badges. */
.v2 .trust { padding-block: var(--s5); }  /* the following section's own top hairline closes the strip */
.trust-row {
  list-style: none; margin: 0; padding: 0; max-width: none;
  display: grid; gap: var(--s4) var(--s6);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 280px), 1fr));
}
.trust-row li { display: flex; align-items: flex-start; gap: var(--s3); min-width: 0; font-size: .9375rem; line-height: 1.4; }
.trust-row svg { flex: 0 0 24px; width: 24px; height: 24px; color: var(--signal); margin-top: 1px; }
.trust-row b { display: block; font-weight: 600; color: var(--ink); }
.trust-row span { color: var(--graphite); }

/* -- service tiles: photo on top, title, the two-line summary, an arrow link.
      One column under 560px, 2x2 to 899px, four across from 900px. Every
      column is minmax(0, 1fr) so a long word shrinks the column, never the
      other way round (the CRR mid-word-break trap). */
.tiles { display: grid; gap: var(--s5); grid-template-columns: minmax(0, 1fr); margin-top: var(--s6); }
@media (min-width: 560px) { .tiles { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 900px) { .tiles { grid-template-columns: repeat(4, minmax(0, 1fr)); } .tiles--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
.tiles + .grid { margin-top: var(--s5); }
.tile {
  display: flex; flex-direction: column; min-width: 0;
  background: var(--card); border: 1px solid var(--rule); border-radius: 4px; overflow: hidden;
}
.tile-media { margin: 0; aspect-ratio: 16 / 9; overflow: hidden; background: var(--rule); border-bottom: 1px solid var(--rule); }
.tile-media img { width: 100%; height: 100%; object-fit: cover; transition: transform .3s var(--ease-out); }
@media (hover: hover) and (pointer: fine) { .tile:hover .tile-media img { transform: scale(1.03); } }
.tile-body { display: flex; flex-direction: column; flex: 1 1 auto; padding: var(--s5); }
.tile-body h3 { font-size: 1.1875rem; margin-bottom: var(--s2); }
.tile-body p { font-size: .9375rem; color: var(--graphite); }
.tile-body p:last-child { margin-top: auto; margin-bottom: 0; padding-top: var(--s3); }
/* Inline, not inline-flex: the arrow follows the last word wherever the label
   wraps (r1 judge: inline-flex left "build-" on one line and "out ->" on the next). */
.arrow { font-weight: 600; text-decoration: none; }
.arrow .kw { white-space: nowrap; }  /* r2 judge: the arrow was landing alone on a third line; it now travels with the last word */
.arrow svg { display: inline-block; width: 16px; height: 16px; vertical-align: -3px; margin-left: var(--s2); transition: transform .2s var(--ease-out); }
.tile-body p, .v2 .card p, .v2 .limits p, .trust-row b { text-wrap: pretty; }
.trust-row b { text-wrap: balance; }
.arrow:hover { text-decoration: underline; }
@media (hover: hover) and (pointer: fine) { .arrow:hover svg { transform: translateX(3px); } }
.v2 .roofline { margin-top: var(--s7); }

/* -- scope block, restyled: a 4px signal rule down the left, step numbers at
      body size. The exclusions pairing is untouched (the pairing is the credibility). */
.v2 .scope { border-left: 4px solid var(--signal); border-radius: 0 4px 4px 0; padding: var(--s6) var(--s6) var(--s5); }
.v2 .scope ol li { padding-left: 3.5rem; padding-bottom: var(--s5); }
.v2 .scope ol li::before { font-size: 1rem; top: 0; }
.v2 .scope ol li strong { font-family: var(--display); font-size: 1.0625rem; }
.v2 .scope ol li:last-child { padding-bottom: 0; }
.v2 .exclusions { margin-block: var(--s6); }
/* Inside an ink band the exclusions box inverts to paper-on-ink; the scope
   stays a white document on the dark ground. Not exercised on the pilot page. */
.band-ink .scope { color: var(--ink); border-left-color: var(--mint); }
.band-ink .exclusions { color: var(--paper); border-left-color: var(--dust); }
.band-ink .exclusions h3 { color: var(--paper); }

/* -- "what we put in writing" on ink: the three cards go paper-on-ink, the
      middle card keeps its alert rule. Links inside the cards return to signal
      (7.58:1 on paper) because .band-ink a otherwise inherits paper. */
.band-ink .card, .band-ink .limits { background: var(--paper); color: var(--ink); border-color: transparent; }
.band-ink .limits { border-left-color: var(--alert); }
.band-ink .limits h3 { color: var(--alert); }
.band-ink .card a, .band-ink .limits a { color: var(--signal); }
.band-ink .card a:hover, .band-ink .limits a:hover { color: var(--signal-deep); }
/* Rollout (2026-09-20): whatever the last content section of a page holds lands on
   the ink band, so every light component declares its own ink text there. */
.band-ink .roofline { background: var(--paper); color: var(--ink); border-color: transparent; }
.band-ink .roofline a { color: var(--signal); }
.band-ink .roofline a:hover { color: var(--signal-deep); }
.band-ink table { color: var(--ink); }
.band-ink caption, .band-ink .caption, .band-ink .muted, .band-ink .hint { color: var(--dust); }
.band-ink .card .caption, .band-ink .limits .caption, .band-ink .scope .caption, .band-ink .roofline .caption,
.band-ink .card .muted, .band-ink .limits .muted { color: var(--graphite); }
.band-ink .scope a { color: var(--signal); }
.band-ink .exclusions a { color: inherit; }
/* A filled button inside a paper card on ink keeps its white label (rollout judge,
   approved-vendor: the signal-on-signal button had vanished). */
.band-ink .card .btn, .band-ink .limits .btn, .band-ink .scope .btn, .band-ink .roofline .btn { color: #fff; }
.band-ink .card .btn:hover, .band-ink .limits .btn:hover { color: #fff; background: var(--signal-deep); }
/* A heading or paragraph that follows a boxed component gets air above it. */
.v2 .card + h3, .v2 .scope + h3, .v2 .limits + h3, .v2 .roofline + h3,
.v2 .card + p, .v2 .scope + p, .v2 .limits + p, .v2 .roofline + p { margin-top: var(--s6); }

/* Two ink bands in a row (a page's last content section, then the CTA band, then the
   footer) keep a faint paper hairline between them so the dark tail still reads as
   three surfaces, not one block. */
.band-ink + .band-ink, .v2-footer { border-top: 1px solid rgba(250, 250, 248, .14); }

/* -- vendor CTA band: ink, the mark as an 8% watermark on the right. */
.cta-band { position: relative; overflow: hidden; }
.cta-band > .wrap { position: relative; z-index: 1; }
.cta-band h2 { font-size: clamp(2rem, 1.4rem + 2.4vw, 3rem); max-width: 24ch; }
.cta-band .lead { color: var(--paper); opacity: .85; }
.cta-band .eyebrow { color: var(--mint); opacity: 1; }
.cta-band .hero-actions { margin-top: var(--s5); }
.cta-band .hero-actions + p { margin-top: var(--s5); }
.cta-band p:not(.eyebrow) { max-width: 62ch; }
.cta-mark {
  position: absolute; right: -6vw; top: 50%; transform: translateY(-50%);
  width: min(44vw, 440px); height: auto; opacity: .08; pointer-events: none;
}
@media (max-width: 720px) { .cta-mark { width: 70vw; right: -30vw; } }

/* -- footer: ink, three columns, hairline, caption. */
.v2-footer { padding-block: var(--s8) var(--s6); }
.footer-grid {
  display: grid; gap: var(--s6);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 240px), 1fr));
  padding-bottom: var(--s6); margin-bottom: var(--s5);
  border-bottom: 1px solid rgba(250, 250, 248, .14);
}
@media (min-width: 900px) { .footer-grid { grid-template-columns: 1.5fr 1fr 1fr; } }
.footer-grid > * { min-width: 0; }
.footer-brand { display: flex; align-items: center; gap: var(--s3); font-family: var(--display); font-weight: 700; font-size: 1.0625rem; margin-bottom: var(--s3); }
.footer-brand svg { width: 28px; height: 28px; flex: 0 0 28px; }
.footer-col p { max-width: 44ch; }
.footer-head {
  font-family: var(--mono); font-size: .75rem; font-weight: 500; letter-spacing: .08em;
  text-transform: uppercase; color: var(--dust); margin: 0 0 var(--s3);
}
.footer-col ul { list-style: none; margin: 0; padding: 0; }
.footer-col li { padding-block: var(--s1); }
.footer-phone { display: inline-block; font-family: var(--mono); font-weight: 500; font-size: 1.0625rem; text-decoration: none; margin-block: var(--s2) var(--s3); }
.footer-phone:hover { text-decoration: underline; }
.site-footer a { text-decoration-color: rgba(250, 250, 248, .45); }
.site-footer a:hover { text-decoration-color: currentColor; }

/* -- sticky call bar, phones only (<=720px). A real tel: link, 48px tall, sits
      above the home indicator; the body reserves the same height so the footer
      caption is never hidden behind it. :has() scopes the reserve to pages that
      carry the bar. */
.call-bar { display: none; }
@media (max-width: 720px) {
  .call-bar {
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 20;
    display: flex; align-items: center; justify-content: center; gap: var(--s2);
    height: calc(48px + env(safe-area-inset-bottom)); padding-bottom: env(safe-area-inset-bottom);
    background: var(--signal); color: #fff; font-weight: 600; font-size: 1rem; text-decoration: none;
    border-top: 1px solid var(--signal-deep);
  }
  .call-bar svg { width: 20px; height: 20px; flex: 0 0 20px; }
  .call-bar .fact { color: inherit; }
  .call-bar:active { background: var(--signal-deep); }
  body:has(.call-bar) { padding-bottom: calc(48px + env(safe-area-inset-bottom)); }
}

/* --- theme reset for the chrome-free templates (whole <body> lives in post content) --- */
.wp-site-blocks > .wp-block-post-content,
.wp-block-post-content { max-width: none !important; padding: 0 !important; margin: 0 !important; }
.wp-site-blocks { padding: 0 !important; margin: 0 !important; }
.entry-content > * { max-width: none; }
body { padding: 0 !important; }
/* WP flow layout puts a 40px margin-block-start on every sibling (header, main, footer) - measured live 2026-09-20 */
.wp-block-post-content.is-layout-flow > *, .wp-site-blocks > * { margin-block-start: 0 !important; margin-block-end: 0 !important; }
