﻿/* Layout DNA preview engine â€” style schools as token sets.
   One school per site (docs/layout-dna.md). Accent comes from demo art. */
* { box-sizing:border-box; margin:0; }
img { max-width:100%; display:block; }

:root {
  --ink:#1A2330; --dim:#5C6B7A; --bg:#FFFFFF; --soft:#F5F7FA; --line:#E4E9EF;
  /* --accent fills (buttons, bands). --accent-text is the same colour used as
     TYPE, and it is not always the same value: a pale client brand colour is
     fine behind dark ink and unreadable at 15px on white. dna.js/site.js
     override this with a contrast-corrected version when the accent needs it;
     an already-legible accent comes through untouched. */
  --accent:#1E62D0; --accent-ink:#fff; --accent-text:var(--accent);
  --font:'Inter',-apple-system,"Segoe UI",sans-serif;
  --disp:var(--font); --dispWeight:800; --dispSpace:-0.02em; --dispCase:none;
  --radius:12px; --btnRadius:10px; --pad:88px; --cardBorder:1px solid var(--line);
  --cardShadow:none; --h1:clamp(32px,5vw,50px);
  /* ---- Fluid type scale ----
   * Ported from the Frostline build. Every step is clamp(floor, grows-with-
   * width, ceiling), so type answers to the width it is actually rendered in.
   *
   * That last part matters more here than on an ordinary site: the showcase
   * renders these pages inside an IFRAME, and `vw` inside an iframe is the
   * IFRAME's width. So the same stylesheet reads correctly in a 390px phone
   * frame and a 1000px desktop frame without a media query — which is exactly
   * the case fixed pixels get wrong, because 15px next to a 50px headline is
   * a different relationship than 15px next to a 32px one.
   *
   * Deliberately NOT applied to small UI text — labels, notes, badges. Fluid
   * 12px is a legibility risk for the sake of nothing. */
  --step-0: clamp(15px, 14.4px + 0.25vw, 17px);    /* body */
  --step-1: clamp(16.5px, 15.4px + 0.45vw, 20px);  /* hero tag, lead */
  --step-2: clamp(17.5px, 16.3px + 0.55vw, 22px);  /* card headings */
  --step-3: clamp(24px, 21.5px + 1.15vw, 32px);    /* section headings */

}

/* ---- schools ---- */
[data-school="calm"] {
  --radius:18px; --btnRadius:999px; --pad:96px; --dispWeight:750;
  --cardBorder:0; --cardShadow:0 10px 30px rgba(26,35,48,.08);
}
[data-school="trade"] {
  --radius:4px; --btnRadius:6px; --pad:72px; --dispWeight:850; --dispSpace:-0.025em;
  --disp:'Archivo','Inter',sans-serif;
  --cardBorder:1.5px solid var(--line); --cardShadow:none;
}
[data-school="warm"] {
  --bg:#FDFAF3; --soft:#F5EEE0; --line:#E8DFCC; --ink:#2E2820; --dim:#6E6353;
  --disp:'Source Serif 4',Georgia,serif; --dispWeight:640; --dispSpace:-0.01em;
  --radius:10px; --btnRadius:8px; --pad:100px;
  --cardBorder:0; --cardShadow:0 8px 26px rgba(70,55,30,.10);
}
[data-school="editorial"] {
  --radius:0; --btnRadius:0; --pad:128px; --line:#D9DEE5;
  --disp:'Source Serif 4',Georgia,serif; --dispWeight:480; --dispSpace:-0.015em;
  --cardBorder:0; --cardShadow:none; --h1:clamp(44px,7.2vw,84px);
}
[data-school="darkpremium"] {
  --bg:#12100E; --soft:#1C1916; --line:#2E2A25; --ink:#F2EDE6; --dim:#A79E92;
  --radius:2px; --btnRadius:2px; --pad:110px; --dispWeight:560;
  --disp:'Source Serif 4',Georgia,serif;
  --cardBorder:1px solid var(--line); --cardShadow:none;
}

body { font-family:var(--font); color:var(--ink); background:var(--bg); line-height:1.65; font-size:var(--step-0); }
.wrap { max-width:1040px; margin:0 auto; padding:0 22px; }
.hand { font-family:'Caveat',cursive; font-weight:600; }

/* ---- header ---- */
header.top { position:sticky; top:0; background:var(--bg); border-bottom:1px solid var(--line); z-index:10; }
/* padding-block, NOT the shorthand — see the note in styles.css */
.topRow { display:flex; align-items:center; justify-content:space-between; padding-top:15px; padding-bottom:15px; gap:12px; }
.logo { font-family:var(--disp); font-weight:var(--dispWeight); font-size:20px; color:var(--ink); text-decoration:none; letter-spacing:var(--dispSpace); }
nav.mainNav { display:flex; gap:20px; align-items:center; }
nav.mainNav a { color:var(--ink); text-decoration:none; font-weight:600; font-size:15px; }
nav.mainNav a.navCta { background:var(--accent); color:var(--accent-ink); padding:10px 20px; border-radius:var(--btnRadius); font-weight:800; }
nav.mainNav .navPhone { font-weight:800; color:var(--accent-text); }

.btn { display:inline-block; padding:14px 28px; border-radius:var(--btnRadius); font-weight:800; text-decoration:none; font-size:16px; }
.btn.primary { background:var(--accent); color:var(--accent-ink); }
.btn.ghost { border:1.5px solid currentColor; color:var(--ink); }
.btn.arrow { padding:14px 0; color:var(--ink); border-bottom:2px solid var(--accent); border-radius:0; }
.btn.arrow::after { content:' \2192'; }

h2 { font-family:var(--disp); font-weight:var(--dispWeight); letter-spacing:var(--dispSpace); font-size:var(--step-3); margin-bottom:12px; }
section { padding:calc(var(--pad) * .62) 0; }
.kicker { font-size:13px; font-weight:800; letter-spacing:.14em; text-transform:uppercase; color:var(--accent-text); margin-bottom:10px; }

/* ---- heroes ---- */
.heroForm { padding:calc(var(--pad) * .7) 0; }
.heroForm .cols { display:grid; grid-template-columns:1.05fr .95fr; gap:44px; align-items:start; }
.heroForm h1 { font-family:var(--disp); font-weight:var(--dispWeight); letter-spacing:var(--dispSpace); font-size:var(--h1); line-height:1.08; }
.heroForm .tag { margin-top:16px; font-size:var(--step-1); color:var(--dim); max-width:520px; }
.heroForm .heroSnap { margin-top:26px; border-radius:var(--radius); overflow:hidden; aspect-ratio:16/8; background-size:cover; background-position:center; }

.heroFormOv { position:relative; }
.heroFormOv .bgimg { position:absolute; inset:0; background-size:cover; background-position:center; }
.heroFormOv .scrim { position:absolute; inset:0; background:linear-gradient(105deg, rgba(8,20,18,.88) 0%, rgba(8,20,18,.62) 55%, rgba(8,20,18,.38) 100%); }
.heroFormOv .inner { position:relative; padding:88px 0 72px; }
.heroFormOv .cols { display:grid; grid-template-columns:1.05fr .95fr; gap:48px; align-items:center; }
.heroFormOv h1 { font-family:var(--disp); font-weight:var(--dispWeight); letter-spacing:var(--dispSpace); color:#fff; font-size:var(--h1); line-height:1.07; }
.heroFormOv .tag { color:rgba(255,255,255,.88); margin-top:16px; font-size:var(--step-1); max-width:480px; }
.heroFormOv .ctaRow .btn.ghost { color:#fff; border-color:rgba(255,255,255,.75); }
.heroFormOv .calcAnno { color:#fff; text-shadow:0 1px 10px rgba(0,0,0,.6); }

.tintband { background:color-mix(in srgb, var(--accent) 8%, var(--bg)); }

.heroOverlay { position:relative; min-height:74vh; display:flex; align-items:flex-end; }
.heroOverlay .bgimg { position:absolute; inset:0; background-size:cover; background-position:center; }
.heroOverlay .scrim { position:absolute; inset:0; background:linear-gradient(160deg, rgba(8,10,13,.78) 8%, rgba(8,10,13,.38) 55%, rgba(8,10,13,.55) 100%); }
[data-school="warm"] .heroOverlay .scrim { background:linear-gradient(165deg, rgba(46,32,12,.72) 5%, rgba(46,32,12,.28) 60%, rgba(46,32,12,.5) 100%); }
.heroOverlay .inner { position:relative; padding:120px 0 64px; width:100%; }
.heroOverlay h1 { font-family:var(--disp); font-weight:var(--dispWeight); letter-spacing:var(--dispSpace); color:#fff; font-size:var(--h1); line-height:1.06; max-width:640px; }
.heroOverlay .tag { color:rgba(255,255,255,.9); margin-top:16px; font-size:var(--step-1); max-width:540px; }
.heroOverlay .ctaRow .btn.ghost { color:#fff; border-color:#fff; }

.heroEditorial { padding:calc(var(--pad) * .9) 0 calc(var(--pad) * .55); }
.heroEditorial .edCols { display:grid; grid-template-columns:1fr; }
.heroEditorial.hasPhoto .edCols { grid-template-columns:1.1fr .9fr; gap:52px; align-items:center; }
.edPhoto { border-radius:var(--radius); min-height:400px; background-size:cover; background-position:center;
  box-shadow:0 26px 60px rgba(20,28,40,.22); }
@media (max-width:900px) { .heroEditorial.hasPhoto .edCols { grid-template-columns:1fr; } .edPhoto { display:none; } }
.heroEditorial .rule { height:1px; background:var(--ink); opacity:.25; margin-bottom:34px; }
.heroEditorial h1 { font-family:var(--disp); font-weight:var(--dispWeight); letter-spacing:var(--dispSpace); font-size:var(--h1); line-height:1.04; max-width:15ch; }
.heroEditorial .tag { margin-top:22px; font-size:var(--step-1); color:var(--dim); max-width:52ch; }
/* These three are the trust strip — the proof sitting directly under the CTA,
   and for a trade with no reviews yet they are the entire case. At 14.5px dim
   they read as a footnote, which is the opposite of their job. The Denver
   competitors give this line real weight (Grandma's puts "Licensed & Insured"
   and its rates above the fold at body size or larger). The number leads, the
   label supports. */
.heroEditorial .metaRow { display:flex; gap:34px; margin-top:44px; padding-top:20px; border-top:1px solid var(--line); color:var(--dim); font-size:16px; flex-wrap:wrap; }
.heroEditorial .metaRow div { display:flex; flex-direction:column; gap:1px; }
.heroEditorial .metaRow b { color:var(--ink); font-size:21px; line-height:1.15; font-weight:800; letter-spacing:-0.01em; }

.heroBand { padding:calc(var(--pad) * .8) 0 0; text-align:center; }
.heroBand h1 { font-family:var(--disp); font-weight:var(--dispWeight); letter-spacing:var(--dispSpace); font-size:var(--h1); line-height:1.08; max-width:22ch; margin:0 auto; }
.heroBand .tag { margin:16px auto 0; font-size:var(--step-1); color:var(--dim); max-width:56ch; }
.heroBand .ctaRow { justify-content:center; }
.ctaRow { margin-top:28px; display:flex; gap:14px; flex-wrap:wrap; align-items:center; }

/* ---- proof ---- */
.proofStrip { display:grid; grid-template-columns:repeat(auto-fit,minmax(150px,1fr)); gap:14px; padding:30px 0; border-top:1px solid var(--line); border-bottom:1px solid var(--line); }
.proofStrip .stat { text-align:center; }
.proofStrip b { display:block; font-family:var(--disp); font-size:26px; font-weight:800; color:var(--accent-text); }
.proofStrip span { color:var(--dim); font-size:13.5px; }
.darkband { background:var(--band, #141A22); color:#EAF0F6; padding:52px 0; }
[data-school="darkpremium"] .darkband { background:var(--soft); }
.darkband .cols { display:grid; grid-template-columns:repeat(auto-fit,minmax(170px,1fr)); gap:22px; }
.darkband b { display:block; font-family:var(--disp); font-size:clamp(34px,4.5vw,52px); font-weight:850; color:var(--accent); line-height:1; }
.darkband span { color:#93A1B0; font-size:14px; }

/* ---- services variants ---- */
.svcGrid { display:grid; grid-template-columns:repeat(auto-fit,minmax(240px,1fr)); gap:18px; }
.svcGrid.four { grid-template-columns:1fr 1fr; }
.card { background:var(--soft); border:var(--cardBorder); box-shadow:var(--cardShadow); border-radius:var(--radius); padding:26px; }
.card h3 { font-family:var(--disp); font-size:var(--step-2); margin-bottom:8px; font-weight:750; }
.card p { color:var(--dim); font-size:15px; }
.card .price { margin-top:14px; font-weight:800; color:var(--accent-text); }

.featRest { display:grid; grid-template-columns:1.25fr 1fr; gap:22px; align-items:start; }
.featRest .featured { background:var(--accent); color:var(--accent-ink); border-radius:var(--radius); padding:34px 30px; }
.featRest .featured h3 { font-family:var(--disp); font-size:24px; margin-bottom:10px; }
.featRest .featured p { opacity:.92; font-size:16px; }
.featRest .featured .price { margin-top:18px; font-weight:900; font-size:19px; }
.featRest .rest { display:flex; flex-direction:column; }
.featRest .rest .row { padding:18px 4px; border-bottom:1px solid var(--line); }
.featRest .rest .row:first-child { padding-top:6px; }
.featRest .row h3 { font-size:16.5px; display:flex; justify-content:space-between; gap:14px; }
.featRest .row h3 span { color:var(--accent-text); white-space:nowrap; font-weight:800; }
.featRest .row p { color:var(--dim); font-size:14px; margin-top:4px; }

.numList .item { display:grid; grid-template-columns:110px 1fr auto; gap:26px; padding:34px 0; border-top:1px solid var(--line); align-items:baseline; }
.numList .n { font-family:var(--disp); font-size:clamp(38px,5vw,58px); font-weight:300; color:var(--dim); opacity:.55; line-height:1; }
.numList h3 { font-family:var(--disp); font-size:22px; font-weight:600; }
.numList p { color:var(--dim); margin-top:6px; max-width:52ch; }
.numList .price { font-weight:700; color:var(--ink); white-space:nowrap; }

.menuRows .row { display:flex; align-items:baseline; gap:10px; padding:16px 0; }
.menuRows h3 { font-family:var(--disp); font-size:19px; font-weight:650; white-space:nowrap; }
.menuRows .dots { flex:1; border-bottom:2px dotted var(--line); transform:translateY(-4px); }
.menuRows .price { font-weight:800; color:var(--accent-text); white-space:nowrap; }
.menuRows p { color:var(--dim); font-size:14.5px; margin:-8px 0 6px; max-width:60ch; }

.tiers { display:grid; grid-template-columns:repeat(3,1fr); gap:0; align-items:center; }
.tiers .card { text-align:left; }
.tiers .card.mid { transform:scale(1.06); position:relative; z-index:2; border:2px solid var(--accent); box-shadow:0 18px 44px rgba(26,35,48,.14); }
.tiers .card.mid .tag { display:inline-block; background:var(--accent); color:var(--accent-ink); font-size:12px; font-weight:800; padding:3px 10px; border-radius:999px; margin-bottom:10px; }

/* ---- offers / emergency ---- */
.offers { display:grid; grid-template-columns:1fr 1fr; gap:18px; }
.coupon { border:2px dashed var(--accent); border-radius:var(--radius); padding:24px 26px; display:flex; justify-content:space-between; gap:16px; align-items:center; flex-wrap:wrap; }
.coupon h3 { font-family:var(--disp); font-size:21px; }
.coupon .exp { color:var(--dim); font-size:13.5px; margin-top:4px; }
.emergency { background:var(--accent); color:var(--accent-ink); padding:18px 0; }
.emergency .row { display:flex; justify-content:space-between; align-items:center; gap:14px; flex-wrap:wrap; }
.emergency b { font-size:17px; }
.emergency a { color:inherit; font-weight:900; text-decoration:none; font-size:19px; border-bottom:2px solid currentColor; }

/* ---- gallery / quote / pullquote ---- */
.tiles { display:grid; grid-template-columns:1fr 1fr; gap:14px; }
.gtile { position:relative; border-radius:var(--radius); overflow:hidden; aspect-ratio:4/3; display:flex; align-items:flex-end; }
.tiles .gtile:first-child { grid-column:span 2; aspect-ratio:21/8; }
.gtile .cap { position:relative; width:100%; padding:12px 14px; color:#fff; font-weight:700; font-size:13.5px; background:linear-gradient(transparent, rgba(0,0,0,.55)); }
.galNote { margin-top:12px; font-size:13px; color:var(--dim); }

.spotlight { max-width:760px; }
.spotlight .mark { font-family:var(--disp); font-size:88px; line-height:.4; color:var(--accent-text); display:block; margin-bottom:18px; opacity:.85; }
.spotlight p { font-family:var(--disp); font-size:clamp(21px,2.6vw,28px); font-weight:520; line-height:1.42; }
.spotlight .who { margin-top:16px; color:var(--dim); font-weight:700; font-size:15px; }

.pullquote { border-top:1px solid var(--line); border-bottom:1px solid var(--line); }
.pullquote p { font-family:var(--disp); font-style:italic; font-weight:420; font-size:clamp(26px,3.6vw,40px); line-height:1.3; max-width:24ch; }
.pullquote .sig { margin-top:18px; font-size:30px; color:var(--dim); }

/* ---- signature moments (one bespoke element per page) ---- */
.polaroids { display:flex; gap:30px; flex-wrap:wrap; align-items:flex-start; margin-top:8px; }
.pol { background:#FFFDF8; padding:12px 12px 44px; box-shadow:0 16px 36px rgba(0,0,0,.35); position:relative; flex:1 1 240px; max-width:300px; transform:rotate(-2.2deg); }
.pol:nth-child(2) { transform:rotate(1.6deg) translateY(14px); }
.pol:nth-child(3) { transform:rotate(-0.8deg) translateY(4px); }
.pol::before { content:''; position:absolute; top:-13px; left:50%; transform:translateX(-50%) rotate(-3deg); width:92px; height:26px; background:rgba(255,252,235,.7); border:1px solid rgba(0,0,0,.06); box-shadow:0 1px 3px rgba(0,0,0,.12); }
.pol .ph { aspect-ratio:1/1; background-size:cover; background-position:center; }
.pol .cap { position:absolute; left:12px; right:12px; bottom:10px; font-family:'Caveat',cursive; font-weight:600; font-size:20px; color:#3A342C; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }

/* Shared by the checklist and the oven/lawn board: both are a signature
   card that maxes out around 460-520px, so alone in a full-width section
   they leave half of it empty and read as a missing picture. */
.checkWrap, .boardWrap { display:flex; gap:44px; align-items:center; flex-wrap:wrap; }
/* .checklist sets its own flex basis and so grows to fill; .ovenboard did
   not, and shrank to its content (363px of a 996px row). Same basis, same
   balance - its own max-width:460px still caps it. */
.boardWrap .ovenboard { flex:1 1 320px; }
.checkPhoto { flex:1 1 240px; max-width:320px; aspect-ratio:1/1; background-size:cover; background-position:center; border:12px solid #fff; box-shadow:0 16px 36px rgba(26,35,48,.2); transform:rotate(1.8deg); }
.checklist { background:#FFFDF6; color:#2B2823; border-radius:4px; padding:30px 34px 64px; flex:1 1 320px; max-width:520px; box-shadow:0 14px 34px rgba(26,35,48,.16); transform:rotate(-0.6deg); position:relative; }
.checklist h3 { font-family:'Caveat',cursive; font-weight:600; font-size:26px; margin-bottom:14px; }
.checklist .item { display:flex; gap:12px; padding:7px 0; border-bottom:1px dashed #E5DFCF; font-size:15.5px; align-items:center; }
.checklist .item:last-child { border-bottom:0; }
.checklist .tick { font-family:'Caveat',cursive; font-weight:600; font-size:22px; color:var(--accent-text); line-height:1; }
.checklist .item.circled span:last-child { border:2.5px solid var(--accent); border-radius:50% / 42%; padding:2px 12px; transform:rotate(-1.5deg); }
.checklist .note { position:absolute; right:-14px; bottom:-20px; transform:rotate(-4deg); font-family:'Caveat',cursive; font-weight:600; font-size:23px; color:var(--accent-text); }

.ovenboard { background:#233128; color:#F2EFE4; border-radius:8px; padding:34px 38px; max-width:460px; transform:rotate(-0.5deg); box-shadow:0 16px 38px rgba(20,30,20,.35); border:10px solid #17211B; }
.ovenboard h3 { font-family:'Caveat',cursive; font-weight:600; font-size:30px; margin-bottom:12px; color:#FFF9E8; }
.ovenboard .row { display:flex; justify-content:space-between; gap:14px; font-family:'Caveat',cursive; font-weight:600; font-size:24px; padding:5px 0; border-bottom:1px solid rgba(242,239,228,.14); }
.ovenboard .row:last-of-type { border-bottom:0; }
.ovenboard .bnote { margin-top:14px; font-family:'Caveat',cursive; font-size:20px; color:rgba(242,239,228,.75); }

.bigstat { max-width:720px; }
.bigstat b { display:block; font-family:var(--disp); font-weight:700; font-size:clamp(56px,9vw,110px); line-height:1; letter-spacing:-0.02em; }
.bigstat svg { display:block; margin-top:6px; }
.bigstat .lbl { margin-top:10px; font-size:18px; color:var(--dim); }
.bigstat .snote { margin-top:6px; font-family:'Caveat',cursive; font-weight:600; font-size:22px; color:var(--accent-text); }

.gtile .anno { position:absolute; right:16px; bottom:44px; font-family:'Caveat',cursive; font-weight:600; font-size:23px; color:#fff; text-shadow:0 2px 10px rgba(0,0,0,.65); transform:rotate(-2.5deg); }

/* ---- about / area / calc ---- */
.aboutSplit { display:grid; grid-template-columns:1.15fr .85fr; gap:44px; align-items:center; }
.aboutSplit .photo { border-radius:var(--radius); overflow:hidden; aspect-ratio:4/3.4; background-size:cover; background-position:center; }
.aboutProse p { color:var(--dim); max-width:64ch; font-size:16.5px; }
.aboutProse h2 + p, .aboutSplit h2 + p { margin-top:6px; }

.reviews { display:grid; grid-template-columns:repeat(auto-fit,minmax(240px,1fr)); gap:16px; margin-top:18px; }
.rev { background:var(--soft); border:1px solid var(--line); border-radius:var(--radius); padding:18px 20px; }
.rev .stars { color:var(--accent-text); letter-spacing:2.5px; font-size:13.5px; }
.rev p { margin-top:8px; font-size:15px; line-height:1.55; }
.rev .rwho { margin-top:10px; font-size:13px; color:var(--dim); font-weight:700; }
.rev .rwho span { font-weight:400; }
.dfaq { max-width:720px; margin-top:6px; }
.dfaq dt { font-weight:750; margin-top:20px; font-size:16px; }
.dfaq dd { margin:6px 0 0; color:var(--dim); font-size:15px; }
footer.bottom .credit { margin-top:14px; font-size:12.5px; opacity:.55; }
footer.bottom .credit a { color:inherit; text-decoration:none; }
footer.bottom .credit a:hover { text-decoration:underline; }
.callbar { display:none; }
@media (max-width:640px) {
  /* The number is already in the sticky call bar at the bottom of this same
     breakpoint — dna.js adds both from one condition (dna.navPhone). Keeping
     it in the header too meant three items fighting over ~350px, and on a
     real customer's phone every one of them wrapped: the business name onto
     two lines, the number onto two, the button onto two. A 101px header of
     broken text. The bar is the better home for it: thumb-height, always
     visible, one tap.
     Measured on an iPhone-width viewport 2026-08-03 against a live client. */
  nav.mainNav .navPhone { display:none; }
  /* a long name stacks to two lines here; tight leading makes that read as
     a wordmark rather than as text that broke */
  .logo { font-size:17px; line-height:1.12; }
  nav.mainNav a.navCta { padding:9px 15px; font-size:14px; white-space:nowrap; }

  /* NAVIGATION MUST SURVIVE THE PHONE.
   *
   * The 760px rule hides every nav link except the CTA and the phone. Once the
   * phone number moved to the call bar, a phone visitor was left with a logo
   * and one button — Services and About were unreachable from the homepage on
   * the device most of his customers use. Hiding the number fixed the header
   * and quietly removed the site's navigation.
   *
   * Links come back on their own line: CTA ordered first so it stays beside
   * the logo, the rest wrapping beneath it. No hamburger for two links. */
  nav.mainNav { flex-wrap:nowrap; justify-content:flex-end; gap:18px; }
  /* The header CTA goes on phones. The hero carries "Get an estimate" a
     screen-inch below, and the call bar is pinned to the thumb — three copies
     of the same ask, and the third was the one shoving the nav links onto a
     second line. What the header owes a phone visitor is somewhere to GO. */
  nav.mainNav a.navCta { display:none; }
  /* higher specificity than the 760px rule that hides these — that block sits
     LATER in the file, so at phone width it was winning and the links stayed
     hidden even after this one was added */
  header.top nav.mainNav a:not(.navCta):not(.navPhone) { display:inline-block; font-size:14.5px; }
  /* padding-block only — see the note in styles.css */
  .topRow { align-items:flex-start; padding-top:12px; padding-bottom:12px; }
  .logo { padding-top:3px; }

  /* Both hero buttons on one line. Stacked, the second sits below the fold on
     a short screen and reads as an afterthought; side by side they are a
     choice. Equal widths, no wrap. */
  .ctaRow { flex-wrap:nowrap; gap:8px; }
  .ctaRow .btn { flex:1 1 0; min-width:0; text-align:center; padding-left:10px; padding-right:10px; font-size:15px; }

  /* The signature card's arrow points at the photo BESIDE it. Stacked on a
     phone the photo is underneath, so the arrow points into empty space —
     a leftover pointing at nothing reads as a broken layout. */
  .noteArrow { display:none; }

  /* Stacked under the card, the square crop is 320px of stock tools before the
     next real section. Landscape keeps the picture and gives the height back. */
  .checkPhoto { aspect-ratio:16/10; max-width:100%; }

  /* PHONE-FIRST SPACING.
   *
   * --pad is 88-128px depending on school and it was applied at full desktop
   * scale on a 390px screen: section padding alone ate 176px+ between blocks,
   * and .heroEditorial's 90%-of-pad top margin left an 86px band of nothing
   * between the header and the first word. Measured on a live client site the
   * headline sat at 225px and the call button at 434px of a ~700px first view
   * — a third of the screen spent before the page said anything.
   *
   * Desktop is unchanged; this only applies where the screen is small enough
   * that vertical space is the scarce resource. */
  [data-school] { --pad:46px; }
  .heroEditorial { padding-top:26px; }
  .heroEditorial .rule { margin-bottom:20px; }
  .heroEditorial .tag { margin-top:14px; font-size:17px; }
  /* Three stats, one line. Flex-wrapped they broke 2+1 at phone width, which
     reads as a fourth stat missing rather than a tidy pair. A 3-column grid
     forces the row; equal auto-rows keep the cells the same height when one
     label wraps and another doesn't. */
  .heroEditorial .metaRow { display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); gap:10px;
    grid-auto-rows:1fr; margin-top:24px; padding-top:16px; }
  .heroEditorial .metaRow b { font-size:18px; overflow-wrap:anywhere; }
  .heroEditorial .metaRow div { font-size:12.5px; line-height:1.35; }
  .heroBand, .heroForm, .heroOverlay, .heroFormOv { padding-top:26px; }
  .ctaRow { margin-top:20px; gap:10px; }

  /* A service name cannot be nowrap inside a 340px frame — it pushes the price
     off the edge and the whole page slides. Let the name fold instead. */
  .menuRows .row { flex-wrap:wrap; }
  .menuRows h3 { white-space:normal; min-width:0; }

  /* Once the call bar is on screen the phone number is on the page twice, and
     the header cannot afford it: name + number + button at 390px wrapped all
     three onto two lines each — a business name broken as "My Guy / Repair"
     above a broken phone number above a broken button. The bar keeps the
     number one thumb away, so the nav gives its copy up. */
  nav.mainNav .navPhone { display:none; }
  .callbar { display:block; position:fixed; left:0; right:0; bottom:0; z-index:40; background:var(--accent); text-align:center; box-shadow:0 -8px 24px rgba(0,0,0,.18); }
  /* Padding lives on the LINK, not the bar. With it on the bar the anchor was
     an inline 20px box inside a 46px strip, so most of the thing that looks
     tappable did nothing â€” on the one control a phone visitor is meant to hit. */
  .callbar a { display:block; padding:13px 16px; color:var(--accent-ink); font-weight:800; font-size:16.5px; text-decoration:none; letter-spacing:.02em; }
  body.hasCallbar { padding-bottom:54px; }
}

.chips { display:flex; flex-wrap:wrap; gap:9px; }
.chip { border:1px solid var(--line); background:var(--soft); border-radius:999px; padding:7px 15px; font-size:14px; font-weight:600; }
.areaProse { color:var(--dim); font-size:16.5px; max-width:60ch; }
.areaProse b { color:var(--ink); }

.calcBand { padding:36px 0 8px; }
.calcBand .calcCard { max-width:600px; margin:0 auto; }
.calcCard { background:var(--bg); border:var(--cardBorder); box-shadow:0 22px 54px rgba(26,35,48,.16); border-radius:var(--radius); padding:26px 28px; position:relative; }
[data-school="darkpremium"] .calcCard { background:var(--soft); }
.calcCard .calcTitle { font-family:var(--disp); font-weight:750; font-size:19px; margin-bottom:14px; }
.calcRow { display:flex; gap:16px; flex-wrap:wrap; align-items:center; }
.calcRow label { font-weight:700; font-size:14px; }
.calcCard select { margin-left:8px; padding:8px 12px; border:1.5px solid var(--line); border-radius:8px; font:inherit; background:var(--bg); color:var(--ink); }
.calcFreq { display:flex; gap:8px; flex-wrap:wrap; margin-top:16px; }
.freqBtn { padding:8px 14px; border:1.5px solid var(--line); border-radius:999px; background:transparent; color:var(--ink); font:inherit; font-weight:700; font-size:13.5px; cursor:pointer; }
.freqBtn.on { background:var(--accent); border-color:var(--accent-text); color:var(--accent-ink); }
.freqBtn em { font-style:normal; opacity:.75; font-weight:600; }
.calcAdd { display:flex; gap:13px; flex-wrap:wrap; margin-top:14px; font-size:13.5px; }
.calcAdd label { display:flex; gap:6px; align-items:center; font-weight:600; }
.calcAdd span { color:var(--dim); }
.calcOut { display:flex; align-items:center; justify-content:space-between; gap:14px; margin-top:18px; padding-top:16px; border-top:1px solid var(--line); flex-wrap:wrap; }
.calcPrice { font-family:var(--disp); font-size:36px; font-weight:850; }
.calcPer { color:var(--dim); font-size:14px; margin-left:6px; }
.calcNote { margin-top:10px; font-size:12.5px; color:var(--dim); }
.calcAnno { position:absolute; top:-14px; right:18px; transform:rotate(-3deg); font-size:21px; color:var(--accent-text); }

/* quote form (non-calculator form heroes) */
.qform label { display:block; font-weight:700; font-size:14px; margin:13px 0 5px; }
.qform input, .qform select, .qform textarea { width:100%; border:1.5px solid var(--line); border-radius:8px; padding:11px 12px; font:inherit; background:var(--bg); color:var(--ink); }
.qform button { margin-top:16px; width:100%; background:var(--accent); color:var(--accent-ink); border:0; font-weight:800; font-size:16px; padding:13px; border-radius:var(--btnRadius); cursor:pointer; }

footer.bottom { border-top:1px solid var(--line); padding:32px 0 46px; color:var(--dim); font-size:14px; }
footer.bottom .row { display:flex; justify-content:space-between; gap:14px; flex-wrap:wrap; }
footer.bottom a { color:var(--dim); }

@media (max-width:760px) {
  nav.mainNav a:not(.navCta):not(.navPhone) { display:none; }
  .heroForm .cols, .heroFormOv .cols, .featRest, .aboutSplit, .offers { grid-template-columns:1fr; }
  .tiers { grid-template-columns:1fr; gap:14px; }
  .tiers .card.mid { transform:none; }
  .tiles { grid-template-columns:1fr 1fr; }
  .tiles .gtile:first-child { grid-column:span 2; aspect-ratio:16/9; }
  .numList .item { grid-template-columns:64px 1fr; }
  .numList .price { grid-column:2; }
  .heroOverlay { min-height:60vh; }
  /* The handwritten margin note hangs off the card corner by design. On a
     phone the card is nearly the full width, so hanging it right:-14px ran
     the line into the screen edge with no margin. In flow under the list it
     still reads as a note in his hand, and it stays on the page. */
  .checklist .note { position:static; right:auto; bottom:auto; display:block;
    margin-top:16px; transform:rotate(-1.5deg); }
}

/* Strengths — three short answers to "what is he like to deal with" */
.strengthRow { display:grid; grid-template-columns:repeat(3,1fr); gap:28px; }
.strength h3 { font-size:16.5px; margin-bottom:6px; }
.strength p { color:var(--dim); font-size:15px; line-height:1.55; }
@media (max-width:760px) { .strengthRow { grid-template-columns:1fr; gap:20px; } }

/* ---- booking widget (assets/booking.js) ---- */
.bookBox { max-width:620px; }
.bookLoad { color:var(--dim); font-size:15px; }
.bookSlots { display:flex; flex-wrap:wrap; gap:10px; margin-bottom:18px; }
.bookSlot { flex:0 0 auto; background:var(--panel,#fff); border:1.5px solid var(--line); border-radius:10px;
  padding:12px 16px; font:700 15px inherit; color:inherit; cursor:pointer; line-height:1.2; }
.bookSlot:hover { border-color:var(--accent); }
.bookSlot.on { background:var(--accent); border-color:var(--accent); color:#fff; }
.bookForm { display:flex; flex-wrap:wrap; gap:10px; align-items:center; }
.bookForm input { flex:1 1 200px; min-width:0; border:1.5px solid var(--line); border-radius:10px;
  padding:13px 14px; font:inherit; font-size:16px; background:var(--bg,#fff); color:inherit; }
.bookForm button { flex:0 0 auto; background:var(--accent); color:#fff; border:0; border-radius:10px;
  padding:14px 24px; font:800 15px inherit; cursor:pointer; }
.bookForm button:disabled { opacity:.6; cursor:default; }
.bookFine { flex:1 1 100%; margin:0; color:var(--dim); font-size:13.5px; }
.bookMsg { margin-top:10px; font-weight:700; font-size:14.5px; color:var(--accent); min-height:20px; }
.bookNote { color:var(--dim); font-size:14px; margin-top:12px; max-width:56ch; }
.bookDone { border:1.5px solid var(--accent); border-radius:12px; padding:18px 20px; }
.bookDone p { margin-top:6px; color:var(--dim); font-size:15px; }
@media (max-width:640px) {
  /* One tap target per row beats two half-width ones a thumb keeps missing. */
  .bookSlots { flex-direction:column; }
  .bookSlot { width:100%; text-align:left; }
  .bookForm input, .bookForm button { flex:1 1 100%; }
}

/* ---------- Range estimator (assets/estimator.js) ----------
 * Trade-agnostic, data-driven, and it prints its own arithmetic. The working
 * panel is the point: a number a customer can check is worth more than a
 * number they have to believe, and it is the thing a low bid cannot survive. */
.estTitle { font-weight:800; font-size:18px; }
.estLabel { display:block; font-weight:700; font-size:13.5px; margin-top:14px; color:var(--dim); }
.estArea { display:flex; align-items:center; gap:8px; margin-top:6px; }
.estArea input { flex:1 1 auto; min-width:0; border:1.5px solid var(--line); border-radius:9px;
  padding:11px 13px; font:inherit; font-size:17px; background:var(--bg); color:var(--ink); }
.estArea span { color:var(--dim); font-size:14px; font-weight:700; }
.estPresets, .estBands { display:flex; flex-wrap:wrap; gap:7px; margin-top:10px; }
.estChip { border:1.5px solid var(--line); background:transparent; color:var(--ink);
  border-radius:999px; padding:6px 13px; font:700 13px inherit; cursor:pointer; }
.estChip.on { border-color:var(--accent); background:var(--accent); color:var(--accent-ink,#fff); }
.estBands { flex-direction:column; gap:8px; }
.estBand { display:block; width:100%; text-align:left; border:1.5px solid var(--line);
  background:transparent; border-radius:11px; padding:11px 14px; cursor:pointer; color:var(--ink); }
.estBand.on { border-color:var(--accent); box-shadow:inset 0 0 0 1px var(--accent); }
.estBand b { display:block; font-size:15px; }
.estBand span { display:block; color:var(--dim); font-size:13px; margin-top:3px; }
.estMods { margin-top:12px; display:flex; flex-direction:column; gap:9px; }
.estMod { display:flex; gap:10px; align-items:flex-start; font-size:14.5px; cursor:pointer; }
.estMod input { margin-top:3px; flex:0 0 auto; }
.estMod b { font-weight:700; }
.estMod em { display:block; font-style:normal; color:var(--dim); font-size:13px; margin-top:2px; }
.estOut { display:flex; flex-wrap:wrap; gap:12px; align-items:center; justify-content:space-between;
  margin-top:16px; padding-top:14px; border-top:1px solid var(--line); }
.estRange b { font-size:clamp(22px,5vw,30px); font-weight:800; letter-spacing:-.01em; }
.estToggle { background:none; border:0; padding:8px 0 0; color:var(--accent-text,var(--accent));
  font:700 13.5px inherit; cursor:pointer; }
.estWork { margin-top:8px; border-top:1px dashed var(--line); padding-top:10px; }
.estTable { width:100%; border-collapse:collapse; font-size:13.5px; }
.estTable th { text-align:left; font-weight:700; padding:6px 10px 6px 0; vertical-align:top; width:40%; }
.estTable td { color:var(--dim); padding:6px 0; vertical-align:top; }
.estAssume { margin-top:10px; font-size:13px; color:var(--dim); }
.estAssume b { color:var(--ink); display:block; margin-bottom:4px; }
.estAssume ul { margin:0; padding-left:18px; }
.estAssume li { margin-top:3px; }
.estNote { color:var(--dim); font-size:12.5px; margin-top:12px; }
@media (max-width:560px) { .estOut { flex-direction:column; align-items:stretch; }
  .estOut .btn { text-align:center; } .estTable th { width:46%; } }

/* ---------- Failure catalog ----------
 * The trade research, on the CLIENT's site rather than only on ours. Cause on
 * the left, prevention on the right — the competitor cannot copy it without
 * conceding the same point. */
.failGrid { display:grid; grid-template-columns:1fr; gap:0; margin-top:22px; border-top:1px solid var(--line); }
.failRow { display:grid; grid-template-columns:1fr 1fr; gap:26px; padding:18px 0; border-bottom:1px solid var(--line); }
.failRow .cause b, .failRow .fix b { display:block; font-size:11px; letter-spacing:.1em; text-transform:uppercase;
  color:var(--dim); margin-bottom:5px; }
.failRow .fix { border-left:2px solid var(--accent); padding-left:16px; }
.failRow p { font-size:14.5px; }
.failNote { margin-top:18px; color:var(--dim); font-size:14px; max-width:62ch; }
@media (max-width:640px) { .failRow { grid-template-columns:1fr; gap:12px; } }

/* The estimator's option rows are flex, and the text block was left at
   min-width:auto — so it could not shrink below its own min-content and shoved
   the row past the card on a phone. Fence overflowed by 31px, landscaping by
   47px, on the only two trade pages carrying an estimator. */
.estMod { flex-wrap:wrap; }
.estMod > span { min-width:0; flex:1 1 auto; }

/* Room for the handwritten note.
   It is positioned bottom:-20px so it hangs off the corner like a margin
   scribble, but the card reserved no space for it — so at every width above
   640px the two lines of it rose back up and printed across the last item on
   the list. The extra bottom padding is the space it hangs into. */

/* THE EDITORIAL HERO ON A LAPTOP (2026-08-05)
 *
 * Two faults, both only visible between about 950px and 1500px — the width
 * most people actually browse at, and the one nobody had measured.
 *
 * The three proof stats were a flex row with a 34px gap inside a ~519px
 * column. Any nine-character value — a license number — pushed the third onto
 * a second row, so real estate showed "Weekly / 2 towns" above a lonely
 * "201245781". A three-column grid with minmax(0,…) cannot wrap, and the
 * long-value shrink now applies at every width rather than only on a phone.
 *
 * And the photo was a fixed 400px beside an 816px column of text, centred, so
 * the hero carried 400px of empty white down its right-hand side. It stretches
 * to the column now, capped so a short column cannot make it absurd.
 */
.heroEditorial .metaRow { display:grid; grid-template-columns:repeat(3,minmax(0,1fr));
  gap:18px; align-items:start; }
.heroEditorial .metaRow b.long { font-size:17px; letter-spacing:-0.02em; }
.heroEditorial.hasPhoto .edCols { align-items:stretch; }
.edPhoto { height:100%; max-height:620px; }

/* THE HANDWRITTEN NOTE, FOR GOOD.
 *
 * I fixed this once today by reserving 64px of bottom padding for it. That
 * held for a two-line note and failed on the first three-line one — real
 * estate's runs to three lines and printed straight through "Final
 * walkthrough, then closing".
 *
 * Reserving a fixed amount of space for a variable amount of text is the bug,
 * not the number. It sits in normal flow now and pushes the card taller by
 * exactly its own height, so it can never overlap, whatever its length. The
 * negative right margin keeps it hanging off the corner, which was the point
 * of the effect in the first place.
 */
.checklist { padding-bottom:30px; }
.checklist .note { position:static; display:block; margin:20px -14px 0 auto;
  max-width:340px; text-align:right; }

/* What a service includes. The list is the trust moment on the page, so it
   gets room rather than being squeezed under the paragraph. Ticks are drawn
   with a pseudo-element so the markup stays a plain <ul> for screen readers. */
.svcInc { list-style:none; margin:12px 0 0; padding:0; display:grid; gap:7px; }
.svcInc li { position:relative; padding-left:20px; color:var(--dim);
  font-size:14px; line-height:1.5; }
.svcInc li::before { content:''; position:absolute; left:2px; top:.5em;
  width:9px; height:5px; border-left:2px solid var(--accent);
  border-bottom:2px solid var(--accent); transform:rotate(-45deg); }
.card .svcInc + .price, .featured .svcInc + .price { margin-top:14px; }
.menuRows .svcInc { margin:0 0 14px; }
.rest .svcInc { margin-top:8px; }

/* The featured card is filled with the accent color, so the list inherits
   dim body text on a dark ground and ticks drawn in the same color as the
   background behind them. Both were invisible. */
.featRest .featured .svcInc li { color:var(--accent-ink); opacity:.92; }
.featRest .featured .svcInc li::before { border-color:var(--accent-ink); }

/* The asterisk on a services heading, pointing at the note under the section.
   Superscript and lighter, so it reads as a footnote marker rather than as
   part of the heading. */
h2 .ast { font-size:.5em; vertical-align:super; margin-left:.15em;
  color:var(--dim); font-weight:400; }
.featRest .featured .svcInc + .price { margin-top:14px; }
