/* ==========================================================================
   HAPPY'S TREE SERVICE — DIRECTION B
   "37 Years On These Streets"
   Westshore Web · brand + conversion system · 2026-07-26

   One stylesheet, no build step, no external requests, no webfonts, no JS.
   Loaded as a same-origin <link> so a strict `style-src 'self'` CSP passes
   without inline-style hashes or 'unsafe-inline'.

   Every colour pair used for text in this file is measured in
   design-system.md. Nothing here relies on a ratio below 4.5:1 for body
   text or 3:1 for large text and graphical objects.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. TOKENS
   -------------------------------------------------------------------------- */
:root{
  /* Warm paper — the whole site sits on cream, not white. Cream at high
     ambient light (Florida, outdoors, midday) reduces the glare bloom that
     makes pure white screens unreadable. */
  --paper:#FAF6EE;
  --paper-2:#F2EADA;
  --sand:#DED0B8;
  --sand-2:#EBE0CB;

  /* Ink — warm near-black, not blue-black. 16.5:1 on paper. */
  --ink:#1C1710;
  --ink-2:#4A4034;

  /* Brand green, kept exactly (#005A24 is measured-good and 37 years old) */
  --forest:#005A24;
  --forest-2:#00381A;
  --night:#0E1F14;

  /* Gold system. The legacy yellow is 1.36:1 on white and is retired.
     --gold        surfaces + buttons only (ink on gold = 5.83)
     --gold-ink    gold-FAMILY TEXT on cream (5.16) — never --gold
     --gold-lit    gold text + stars on --night / --forest-2 (8.94 / 6.92)
     --tally       decorative marks on cream, still clears 3:1 (3.92) */
  --gold:#C8860D;
  --gold-ink:#8F5E07;
  --gold-lit:#E8B33C;
  --tally:#A96F0A;

  /* THE BRAND YELLOW, restored 2026-07-27. Sampled from the company's own
     oval badge (#FCE21E) and the block numerals painted on their grapple
     truck. It was previously retired for being 1.36:1 on white — correct as
     far as it went, but the answer is not to drop a 37-year-old identity, it
     is to use it the way THEY use it: yellow on dark green or black, and
     black-outlined when it sits on a photograph. Never yellow text on cream.
       --yellow      display type + numerals on --truck / --night (11.9:1)
       --truck       the green actually painted on their trucks
       --outline     the heavy keyline that surrounds the wordmark and oval */
  --yellow:#FCE21E;
  --yellow-2:#E3C70A;
  --truck:#075005;
  --outline:#090A07;

  /* Storm / failure accent. Rust, not alarm-red — this brand does not shout. */
  --ember:#A33A12;

  /* Type. System stacks only. Georgia leads the display stack for its
     old-style (text) figures: 1989, 37, 477, 4.9 all render as warm,
     humanist numerals rather than corporate lining digits. That is the
     single cheapest thing that makes this site feel old and real. */
  --ff-display:Georgia,"Iowan Old Style","Palatino Linotype",Palatino,"Times New Roman",serif;
  --ff-ui:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;

  --t-hero:clamp(2.5rem,8.4vw,5rem);
  --t-h2:clamp(1.85rem,4.6vw,3.15rem);
  --t-h3:clamp(1.3rem,2.8vw,1.85rem);
  --t-lede:clamp(1.075rem,2.1vw,1.3rem);
  --t-body:1.0625rem;   /* 17px floor — outdoor legibility */
  --t-small:0.9375rem;
  --t-eyebrow:0.75rem;

  /* Space */
  --s1:.25rem; --s2:.5rem; --s3:.75rem; --s4:1rem; --s5:1.5rem;
  --s6:2rem; --s7:3rem; --s8:4rem; --s9:6rem; --s10:8rem;

  /* Layout — ONE gutter source, one measure. */
  --gutter:clamp(1.15rem,4.2vw,2.5rem);
  --max:1180px;
  --measure:66ch;
  --r:2px;                    /* near-zero radius: printed, not app-like */
  --rule:1px solid var(--sand);
}

/* --------------------------------------------------------------------------
   2. RESET / BASE
   -------------------------------------------------------------------------- */
*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
body{
  margin:0;
  background:var(--paper);
  color:var(--ink);
  font-family:var(--ff-ui);
  font-size:var(--t-body);
  line-height:1.66;
  -webkit-font-smoothing:antialiased;
  overflow-wrap:break-word;
}
img{max-width:100%;height:auto;display:block}
h1,h2,h3,h4{font-family:var(--ff-display);font-weight:700;letter-spacing:-.012em;margin:0}
h1{font-size:var(--t-hero);line-height:1}
h2{font-size:var(--t-h2);line-height:1.06}
h3{font-size:var(--t-h3);line-height:1.18}
p{margin:0 0 var(--s4)}
a{color:var(--forest);text-decoration-thickness:1px;text-underline-offset:.18em}
a:hover{color:var(--ink)}
ul,ol{margin:0 0 var(--s4);padding-left:1.15em}
li{margin-bottom:.4em}
strong{font-weight:700}
hr{border:0;border-top:var(--rule);margin:var(--s6) 0}

:focus-visible{outline:3px solid var(--gold-ink);outline-offset:2px}

.u-sr{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:var(--s4);top:-3.5rem;z-index:200;background:var(--gold);
  color:var(--ink);padding:.7rem 1rem;font-weight:700;transition:top .15s}
.skip:focus{top:.5rem}

/* --------------------------------------------------------------------------
   3. LAYOUT PRIMITIVES
   -------------------------------------------------------------------------- */
.wrap{width:100%;max-width:var(--max);margin-inline:auto;padding-inline:var(--gutter)}
.wrap>*{min-width:0}
.band{padding-block:clamp(3rem,7vw,5.5rem)}
.band--tight{padding-block:clamp(2rem,4.5vw,3.25rem)}
.band--paper2{background:var(--paper-2)}
.band--forest{background:var(--forest-2);color:var(--paper)}
.band--night{background:var(--night);color:var(--paper)}
.band--forest h2,.band--night h2,.band--forest h3,.band--night h3{color:var(--paper)}
.band--forest a,.band--night a{color:var(--gold-lit)}
.band--forest a:hover,.band--night a:hover{color:#fff}
/* SPECIFICITY TRAP (paid for): `.band--forest a` is (0,2,0) and beats
   `.btn--call` (0,1,0), so every button inside a dark band silently
   inherited the gold link colour — gold-on-gold and gold-on-green.
   Re-assert button colours at equal-or-higher specificity. */
.band--forest .btn--call,.band--night .btn--call{color:var(--ink)}
.band--forest .btn--call:hover,.band--night .btn--call:hover{color:var(--ink)}
.band--forest .btn--text,.band--night .btn--text{color:#fff}
.band--forest .btn--text:hover,.band--night .btn--text:hover{color:#fff}
.band--forest .btn--form,.band--night .btn--form{color:var(--paper)}
.band--forest .btn--form:hover,.band--night .btn--form:hover{background:var(--paper);color:var(--ink)}
.place .btn--call{color:var(--ink)}
.place .btn--text{color:#fff}

.prose{max-width:var(--measure)}
.prose h2{margin:var(--s7) 0 var(--s4)}
.prose h3{margin:var(--s6) 0 var(--s3)}
.prose li{max-width:var(--measure)}

.grid{display:grid;gap:var(--s5)}
.grid>*{min-width:0}
@media(min-width:720px){
  .grid--2{grid-template-columns:repeat(2,minmax(0,1fr))}
  .grid--3{grid-template-columns:repeat(2,minmax(0,1fr))}
}
@media(min-width:980px){
  .grid--3{grid-template-columns:repeat(3,minmax(0,1fr))}
  .grid--4{grid-template-columns:repeat(4,minmax(0,1fr))}
}
@media(min-width:720px) and (max-width:979px){
  .grid--4{grid-template-columns:repeat(2,minmax(0,1fr))}
}

/* Section head: hairline rule + uppercase label. The chapter-head of a
   field journal. Used on every band so the page reads as one document. */
.eyebrow{
  font-family:var(--ff-ui);font-size:var(--t-eyebrow);font-weight:700;
  letter-spacing:.17em;text-transform:uppercase;color:var(--gold-ink);
  margin:0 0 var(--s3);display:flex;align-items:center;gap:.7rem;
  width:max-content;max-width:100%;
}
.eyebrow::before{content:"";display:block;width:2.2rem;height:2px;background:var(--gold);flex:none}
.band--forest .eyebrow,.band--night .eyebrow{color:var(--gold-lit)}
.band--forest .eyebrow::before,.band--night .eyebrow::before{background:var(--gold-lit)}

.lede{font-size:var(--t-lede);line-height:1.55;color:var(--ink-2);max-width:58ch}
.band--forest .lede,.band--night .lede{color:#E4DCCB}

/* --------------------------------------------------------------------------
   4. BUTTONS + THE THREE PATHS
   -------------------------------------------------------------------------- */
.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:.55rem;
  min-height:54px;padding:.85rem 1.4rem;border:2px solid transparent;border-radius:var(--r);
  font-family:var(--ff-ui);font-size:1.0625rem;font-weight:700;letter-spacing:.005em;
  text-decoration:none;cursor:pointer;line-height:1.15;text-align:center;
}
.btn--call{background:var(--gold);color:var(--ink);border-color:#A97009}
.btn--call:hover{background:#DA9614;color:var(--ink)}
.btn--text{background:var(--forest);color:#fff}
.btn--text:hover{background:var(--forest-2);color:#fff}
.band--forest .btn--text,.band--night .btn--text{background:#006A2A;border-color:#2E8F55}
.band--forest .btn--text:hover,.band--night .btn--text:hover{background:#00873A;border-color:#4FAE73}
.btn--form{background:transparent;color:var(--ink);border-color:var(--ink)}
.btn--form:hover{background:var(--ink);color:var(--paper)}
.btn--ember{background:var(--ember);color:#fff}
.btn--ember:hover{background:#8B2F0D;color:#fff}
.band--forest .btn--form,.band--night .btn--form{color:var(--paper);border-color:var(--paper)}
.band--forest .btn--form:hover,.band--night .btn--form:hover{background:var(--paper);color:var(--ink)}
.btn__sub{display:block;font-size:.75rem;font-weight:600;letter-spacing:.08em;
  text-transform:uppercase;opacity:.72;margin-top:.1rem}

.actions{display:flex;flex-wrap:wrap;gap:var(--s3)}
.actions .btn{flex:1 1 15rem}
@media(min-width:640px){.actions .btn{flex:0 0 auto}}

/* --------------------------------------------------------------------------
   5. MASTHEAD
   -------------------------------------------------------------------------- */
.topbar{background:var(--night);color:#D9D0BE;font-size:.8125rem;letter-spacing:.02em}
.topbar .wrap{display:flex;flex-wrap:wrap;gap:.4rem 1.2rem;align-items:center;
  justify-content:space-between;padding-block:.45rem}
.topbar a{color:var(--gold-lit);text-decoration:none;font-weight:700}
.topbar a:hover{color:#fff;text-decoration:underline}
/* The "since 1989" line is the whole argument — keep it on a phone, just
   set it smaller rather than dropping it. */
@media(max-width:659px){.topbar{font-size:.75rem}
  .topbar .wrap{justify-content:center;gap:.15rem .9rem;padding-block:.4rem}
  .topbar .wrap>span{flex:1 0 100%;text-align:center}}
/* Under ~480px the strip would cost three lines above the fold. The 1989
   line is carried by the proof bar and the footer, so drop it here only. */
@media(max-width:479px){.topbar .topbar__since{display:none}}
.topbar b{color:var(--gold-lit);font-weight:700}
.topbar__since{display:flex;align-items:center;gap:.5rem}

.mast{position:sticky;top:0;z-index:100;background:var(--paper);
  border-bottom:1px solid var(--sand);box-shadow:0 1px 0 rgba(28,23,16,.04)}
.mast .wrap{display:flex;align-items:center;gap:var(--s4);
  min-height:74px;padding-block:.5rem}

/* Horizontal lockup — the fix for the oval. Oak at 44px in a 74px bar. */
.lockup{display:flex;align-items:center;gap:.6rem;text-decoration:none;flex:none}
.lockup__mark{width:auto;height:42px}
.lockup__type{display:flex;flex-direction:column;line-height:.94}
.lockup__name{font-family:var(--ff-display);font-weight:700;font-size:1.5rem;
  color:var(--gold-ink);letter-spacing:-.01em}
.lockup__sub{font-family:var(--ff-ui);font-size:.6875rem;font-weight:700;
  letter-spacing:.19em;text-transform:uppercase;color:var(--ink)}
@media(min-width:520px){.lockup__mark{height:48px}.lockup__name{font-size:1.7rem}}

.mast__spacer{flex:1 1 auto}
.mast__cta{display:none;gap:.5rem}
@media(min-width:900px){.mast__cta{display:flex}}
.mast__cta .btn{min-height:46px;padding:.55rem 1.05rem;font-size:.975rem}

/* Below the desktop breakpoint the header still carries a tap-to-call.
   Text lives in the fixed action bar and the hero. */
.mast__call{display:inline-flex;min-height:46px;padding:.5rem .9rem;font-size:.95rem;
  margin-left:auto}
@media(min-width:900px){.mast__call{display:none}}
@media(max-width:419px){
  .lockup__mark{height:34px}
  .lockup__name{font-size:1.25rem}
  .lockup__sub{font-size:.5625rem;letter-spacing:.15em}
  .mast .wrap{gap:.55rem}
  .menu>summary{padding:.4rem .6rem}
  .menu>summary span{display:none}
}
.menu{margin-left:.5rem}

/* Nav — desktop */
.nav{display:none}
@media(min-width:900px){
  .nav{display:flex;align-items:center;gap:1.35rem;font-size:.9375rem;font-weight:600}
  .nav a{color:var(--ink);text-decoration:none;padding:.4rem 0;
    border-bottom:2px solid transparent}
  .nav a:hover,.nav a[aria-current]{border-bottom-color:var(--gold);color:var(--ink)}
  .nav .has-sub{position:relative}
  /* Hover-intent: an invisible bridge across the gap, plus a ~0.35s close
     delay so the menu does not vanish while the pointer crosses to it. */
  .nav .has-sub::after{content:"";position:absolute;left:0;right:0;top:100%;height:14px}
  .nav .sub{
    position:absolute;left:-1rem;top:calc(100% + 14px);min-width:16rem;
    background:var(--paper);border:1px solid var(--sand);
    box-shadow:0 14px 34px rgba(28,23,16,.16);padding:.5rem;margin:0;list-style:none;
    opacity:0;visibility:hidden;transform:translateY(-4px);
    transition:opacity .16s ease,transform .16s ease,visibility 0s linear .35s;
  }
  .nav .has-sub:hover .sub,.nav .has-sub:focus-within .sub{
    opacity:1;visibility:visible;transform:none;transition-delay:0s
  }
  .nav .sub li{margin:0}
  .nav .sub a{display:block;padding:.5rem .7rem;border-bottom:0;font-weight:500}
  .nav .sub a:hover{background:var(--paper-2);border-bottom:0}
}

/* Nav — mobile, zero JS via <details> */
.menu{margin-left:auto}
@media(min-width:900px){.menu{display:none}}
.menu>summary{
  list-style:none;cursor:pointer;display:flex;align-items:center;gap:.5rem;
  min-height:46px;padding:.4rem .8rem;border:2px solid var(--ink);
  font-weight:700;font-size:.9375rem;
}
.menu>summary::-webkit-details-marker{display:none}
.menu>summary::before{content:"";width:20px;height:2px;background:var(--ink);
  box-shadow:0 6px 0 var(--ink),0 -6px 0 var(--ink)}
.menu[open]>summary::before{box-shadow:0 6px 0 var(--ink),0 -6px 0 var(--ink)}
.menu__panel{
  position:absolute;left:0;right:0;top:100%;background:var(--paper);
  border-top:1px solid var(--sand);border-bottom:3px solid var(--forest);
  box-shadow:0 18px 30px rgba(28,23,16,.14);padding:var(--s4) var(--gutter) var(--s5);
  max-height:76vh;overflow:auto;
}
.menu__panel ul{list-style:none;margin:0 0 var(--s4);padding:0}
.menu__panel li{margin:0;border-bottom:1px solid var(--sand-2)}
.menu__panel a{display:block;padding:.8rem 0;color:var(--ink);text-decoration:none;font-weight:600}
/* Same specificity trap as the dark bands: `.menu__panel a` (0,2,0) beat
   `.btn--text` (0,1,0) and put ink text on the green button (2.11:1). */
.menu__panel .btn{display:inline-flex;padding:.85rem 1.4rem}
.menu__panel .btn--call{color:var(--ink)}
.menu__panel .btn--text{color:#fff}
.menu__panel .sub-label{font-size:var(--t-eyebrow);letter-spacing:.16em;text-transform:uppercase;
  color:var(--gold-ink);font-weight:700;margin:var(--s4) 0 .2rem}

/* --------------------------------------------------------------------------
   6. HERO
   -------------------------------------------------------------------------- */
.hero{position:relative;isolation:isolate;background:var(--night);color:var(--paper);
  display:flex;align-items:flex-end;min-height:600px}
@media(min-width:900px){.hero{min-height:700px}}
.hero__img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
  object-position:64% 52%;z-index:-2}
/* Scrim, measured not eyeballed. On a phone the copy covers the whole
   frame, so the scrim has to be vertical and heavy — Florida sun beats
   art direction. From 900px the copy occupies the left half only, so the
   weight moves horizontal and the photograph gets to breathe on the right. */
.hero::after{
  content:"";position:absolute;inset:0;z-index:-1;
  background:linear-gradient(180deg,
    rgba(12,24,15,.84) 0%,rgba(12,24,15,.78) 30%,
    rgba(12,24,15,.82) 66%,rgba(10,20,13,.94) 100%);
}
@media(min-width:900px){
  .hero::after{
    background:
      linear-gradient(90deg,rgba(12,24,15,.91) 0%,rgba(12,24,15,.87) 42%,
        rgba(12,24,15,.62) 56%,rgba(12,24,15,.18) 76%,rgba(12,24,15,0) 100%),
      linear-gradient(180deg,rgba(12,24,15,.52) 0%,rgba(12,24,15,.18) 34%,
        rgba(12,24,15,.30) 70%,rgba(10,20,13,.86) 100%);
  }
}
.hero .wrap{padding-block:clamp(2.5rem,6vw,4rem)}
.hero__eyebrow{color:var(--gold-lit);font-size:var(--t-eyebrow);font-weight:700;
  letter-spacing:.19em;text-transform:uppercase;margin:0 0 var(--s3);
  width:max-content;max-width:100%}
.hero h1{color:#FDFAF3;max-width:13ch;text-shadow:0 2px 22px rgba(0,0,0,.55)}
.hero__lede{font-size:var(--t-lede);line-height:1.5;color:#EBE3D4;max-width:46ch;
  margin:var(--s4) 0 var(--s5);text-shadow:0 1px 12px rgba(0,0,0,.45)}
.hero__ask{margin:var(--s4) 0 0;font-size:.9375rem;color:#E0D7C6;max-width:54ch}
.hero__ask b{color:var(--gold-lit)}
.hero__credit{position:absolute;right:var(--gutter);bottom:.5rem;z-index:1;
  font-size:.6875rem;letter-spacing:.09em;text-transform:uppercase;color:rgba(255,255,255,.55)}

/* Interior hero — shorter, same language */
.hero--page{min-height:420px}
@media(min-width:900px){.hero--page{min-height:480px}}
.hero--page h1{font-size:clamp(2.1rem,5.6vw,3.6rem);max-width:20ch}
.crumbs{font-size:.8125rem;color:#DDD4C2;margin:0 0 var(--s3);letter-spacing:.02em;
  width:max-content;max-width:100%}
.crumbs a{color:#DDD4C2;text-decoration:underline}
.crumbs a:hover{color:#fff}

/* --------------------------------------------------------------------------
   7. THE PROOF BAR  — five true facts, directly under the hero, every page
   -------------------------------------------------------------------------- */
.proof{background:var(--forest-2);color:var(--paper);border-bottom:4px solid var(--gold)}
.proof ul{display:flex;flex-wrap:wrap;list-style:none;margin:0;padding:0;
  gap:.35rem clamp(1rem,3vw,2.25rem);align-items:center;
  padding-block:.9rem}
.proof li{display:flex;align-items:center;gap:.5rem;margin:0;font-size:.9375rem;
  font-weight:600;letter-spacing:.005em;color:#EFE8DA}
/* Separator travels WITH the item, so a wrapped row never starts with an
   orphaned rule. */
.proof li:not(:last-child)::after{content:"·";color:var(--gold-lit);
  margin-left:clamp(.6rem,1.4vw,1.1rem);font-weight:700}
.proof b{color:#fff;font-weight:700}
.stars{color:var(--gold-lit);letter-spacing:.06em;font-size:1rem;line-height:1}
.proof .rating{font-family:var(--ff-display);font-size:1.2rem;font-weight:700;color:#fff}
@media(min-width:1120px){
  .proof ul{gap:.3rem .95rem}
  .proof li{font-size:.875rem}
  .proof li:not(:last-child)::after{margin-left:.95rem}
}

/* --------------------------------------------------------------------------
   8. PHOTO PLATES — the evidence device
   Mixed-quality source photography is unified by (a) a warm grade,
   (b) a cream mat with a hairline, (c) a caption that states what it is.
   -------------------------------------------------------------------------- */
.plate{margin:0;background:var(--paper-2);padding:.55rem .55rem .1rem;
  border:1px solid var(--sand);box-shadow:0 1px 0 rgba(28,23,16,.05)}
.plate img{width:100%;filter:saturate(.94) contrast(1.05) brightness(1.01)}
.plate figcaption{font-family:var(--ff-display);font-style:italic;font-size:.875rem;
  line-height:1.4;color:var(--ink-2);padding:.6rem .3rem .7rem;border-top:1px solid var(--sand-2);
  margin-top:.55rem}
.plate figcaption b{font-style:normal;font-weight:700;color:var(--ink);
  font-family:var(--ff-ui);font-size:.6875rem;letter-spacing:.14em;text-transform:uppercase;
  display:block;margin-bottom:.15rem;color:var(--gold-ink)}
.plate--bare{background:none;border:0;padding:0;box-shadow:none}
.plate--bare figcaption{padding-left:0}
.plate--tall img{aspect-ratio:3/4;object-fit:cover}
.plate--wide img{aspect-ratio:16/9;object-fit:cover}
.plate--sq img{aspect-ratio:1/1;object-fit:cover}
.plate--45 img{aspect-ratio:4/5;object-fit:cover}
/* Below the two-column breakpoints a portrait plate would otherwise run
   ~1000px tall on a tablet. Cap it; object-fit keeps the crop honest. */
@media(max-width:899px){.plate--tall img,.plate--45 img{max-height:600px}}

/* Plates sitting in a card grid share one crop and one height, so the
   captions align on a single baseline instead of stepping. */
.grid>.plate{display:flex;flex-direction:column;height:100%}
.grid>.plate img{aspect-ratio:4/3;object-fit:cover}
.grid>.plate figcaption{margin-top:0}   /* caption TOPS align: the gold labels
                                            form one line across the row */

/* Dark mat — a plate that belongs on a green or night band. */
.plate--dark{background:#04270F;border-color:#0B3D1C}
.plate--dark figcaption{color:#DDD4C2;border-top-color:rgba(255,255,255,.16)}
.plate--dark figcaption b{color:var(--gold-lit)}

/* Duotone: reserved for the weakest source files. Turning a low-quality
   photo into a deliberate two-colour plate is honest and looks intentional.
   NOT for a photo that is already sharp — it flattens real detail. */
.plate--duo{background:var(--forest-2);border-color:var(--forest-2)}
.plate--duo img{filter:grayscale(1) contrast(1.15) sepia(.55) hue-rotate(58deg) saturate(1.5) brightness(.92)}
.plate--duo figcaption{color:#DDD4C2;border-top-color:rgba(255,255,255,.16)}
.plate--duo figcaption b{color:var(--gold-lit)}

/* --------------------------------------------------------------------------
   9. SPLITS — image beside text
   -------------------------------------------------------------------------- */
.split{display:grid;gap:clamp(1.5rem,4vw,3.25rem);align-items:center}
.split>*{min-width:0}
@media(min-width:860px){
  .split{grid-template-columns:minmax(0,1fr) minmax(0,1fr)}
  .split--wide-img{grid-template-columns:minmax(0,1.15fr) minmax(0,1fr)}
  .split--flip .split__media{order:2}
  /* A tall portrait plate beside a short text column leaves a hole. Narrow
     the media column instead of stretching the photograph. */
  .split--lean{grid-template-columns:minmax(0,.88fr) minmax(0,1.12fr)}
  .split--top{align-items:start}
}

/* --------------------------------------------------------------------------
   10. NUMERALS / LEDGER — Georgia text figures as the argument
   -------------------------------------------------------------------------- */
.ledger{display:grid;gap:var(--s5) var(--s4);grid-template-columns:repeat(2,minmax(0,1fr));
  border-top:2px solid var(--gold);padding-top:var(--s5)}
@media(min-width:820px){.ledger{grid-template-columns:repeat(4,minmax(0,1fr))}}
.ledger>div{min-width:0}
.num{font-family:var(--ff-display);font-weight:700;font-size:clamp(2.7rem,6.4vw,4rem);
  line-height:.9;letter-spacing:-.02em;color:var(--forest);display:block}
.band--forest .num,.band--night .num{color:var(--gold-lit)}
.num-label{display:block;margin-top:.55rem;font-size:.875rem;line-height:1.4;color:var(--ink-2);
  max-width:22ch}
.band--forest .num-label,.band--night .num-label{color:#D8CFBD}

/* --------------------------------------------------------------------------
   11. THE 477 WALL — reviews as a design element, without inventing one word
   Every mark is one real Google review. The count is the evidence.
   -------------------------------------------------------------------------- */
.wall{display:grid;gap:clamp(1.5rem,4vw,3rem);align-items:start}
@media(min-width:900px){.wall{grid-template-columns:minmax(0,20rem) minmax(0,1fr)}}
.wall>*{min-width:0}
.wall__score{font-family:var(--ff-display);font-size:clamp(4.5rem,13vw,7.5rem);
  line-height:.82;font-weight:700;color:var(--forest);letter-spacing:-.03em;margin:0}
.wall__stars{color:var(--gold-ink);font-size:1.45rem;letter-spacing:.1em;margin:.6rem 0 .35rem}
.wall__meta{font-size:.9375rem;color:var(--ink-2);margin:0 0 var(--s4)}
.tally{display:flex;flex-wrap:wrap;gap:5px;align-content:flex-start;
  border-left:2px solid var(--gold);padding-left:var(--s4)}
.tally i{display:block;width:5px;height:15px;background:var(--tally);opacity:.85;
  transform:skewX(-9deg)}
.tally i:nth-child(5n){margin-right:9px}
.tally i:nth-child(50n){background:var(--forest);opacity:1}
.wall__note{margin-top:var(--s4);font-size:.875rem;color:var(--ink-2);max-width:52ch}

/* Per-page review panel (service + city). Structure is real; the quotes are
   pulled live from the Google listing at build time. Nothing is invented. */
.revpanel{border:1px solid var(--sand);background:var(--paper-2);padding:var(--s5)}
.band--paper2 .revpanel{background:#FCF9F3}
.revpanel h3{margin-bottom:.35rem}
.revpanel__filter{font-size:var(--t-eyebrow);letter-spacing:.15em;text-transform:uppercase;
  font-weight:700;color:var(--gold-ink);margin:0 0 var(--s3)}
.revpanel__row{display:flex;flex-wrap:wrap;align-items:baseline;gap:.4rem .9rem;margin-bottom:var(--s3)}
.revpanel__score{font-family:var(--ff-display);font-size:2.6rem;font-weight:700;
  line-height:1;color:var(--forest)}

/* --------------------------------------------------------------------------
   12. CARDS
   -------------------------------------------------------------------------- */
.card{background:var(--paper);border:1px solid var(--sand);display:flex;flex-direction:column;
  height:100%}
.card img{width:100%;aspect-ratio:4/3;object-fit:cover;filter:saturate(.94) contrast(1.05)}
.card__body{padding:var(--s4) var(--s4) var(--s5);display:flex;flex-direction:column;flex:1}
.card h3{font-size:1.25rem;margin-bottom:.4rem}
.card p{font-size:.9375rem;color:var(--ink-2);margin-bottom:var(--s4)}
.card__link{margin-top:auto;font-weight:700;font-size:.9375rem;color:var(--forest);
  text-decoration:none;border-bottom:2px solid var(--gold);align-self:flex-start;padding-bottom:2px}
.card__link:hover{color:var(--ink);border-bottom-color:var(--ink)}
.band--paper2 .card{background:#FCF9F3}

/* Reason cards — no photo, heavy numeral */
.reason{border-top:2px solid var(--gold);padding-top:var(--s4)}
.reason h3{margin-bottom:.4rem}
.reason p{color:var(--ink-2);font-size:.9375rem;margin:0}
.band--forest .reason p,.band--night .reason p{color:#D8CFBD}

/* --------------------------------------------------------------------------
   13. NOTE / CALLOUT — permits, statute, cautions
   -------------------------------------------------------------------------- */
.note{border-left:4px solid var(--gold);background:var(--paper-2);padding:var(--s5);
  margin:var(--s6) 0}
.note h3{font-size:1.2rem;margin-bottom:.4rem}
.note p:last-child{margin-bottom:0}
.note--ember{border-left-color:var(--ember)}
.note--forest{border-left-color:var(--forest)}
.note__tag{font-size:var(--t-eyebrow);letter-spacing:.15em;text-transform:uppercase;
  font-weight:700;color:var(--gold-ink);display:block;margin-bottom:.35rem}
.note--ember .note__tag{color:var(--ember)}

/* --------------------------------------------------------------------------
   14. STORM BAND
   -------------------------------------------------------------------------- */
.storm{background:var(--ember);color:#fff}
.storm h2{color:#fff}
.storm .eyebrow{color:#F6D9C9}
.storm .eyebrow::before{background:#F6D9C9}
.storm p{color:#FBEDE5}
.storm .btn--call{background:#fff;color:var(--ember);border-color:#fff}
.storm .btn--call:hover{background:#FBEDE5;color:var(--ember)}
.storm .btn--form{border-color:#fff;color:#fff}
.storm .btn--form:hover{background:#fff;color:var(--ember)}

/* --------------------------------------------------------------------------
   15. TOWNS — the sense of place, set as type
   -------------------------------------------------------------------------- */
.place{position:relative;isolation:isolate;color:var(--paper);background:var(--night)}
.place__img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;z-index:-2;
  filter:saturate(.85) contrast(1.03)}
.place::after{content:"";position:absolute;inset:0;z-index:-1;
  background:linear-gradient(180deg,rgba(10,22,14,.84) 0%,rgba(10,22,14,.76) 45%,rgba(10,22,14,.92) 100%)}
@media(min-width:900px){
  .place::after{background:
    linear-gradient(90deg,rgba(10,22,14,.90) 0%,rgba(10,22,14,.82) 50%,
      rgba(10,22,14,.44) 74%,rgba(10,22,14,.12) 100%),
    linear-gradient(180deg,rgba(10,22,14,.52) 0%,rgba(10,22,14,.34) 45%,rgba(10,22,14,.72) 100%)}
}
.place .lede,.place p{color:#E6DECE}
.place .towns{margin-top:var(--s5)}
.towns{display:flex;flex-wrap:wrap;gap:.35rem 1.15rem;list-style:none;padding:0;
  margin:var(--s5) 0 0;font-family:var(--ff-display);font-size:clamp(1.05rem,2.4vw,1.5rem);
  line-height:1.5}
.towns li{margin:0}
.towns a{color:#EFE8DA;text-decoration:none;border-bottom:1px solid rgba(232,179,60,.5)}
.towns a:hover{color:#fff;border-bottom-color:var(--gold-lit)}
.towns li::after{content:"·";color:var(--gold-lit);margin-left:1.15rem}
.towns li:last-child::after{content:""}

/* --------------------------------------------------------------------------
   16. THE ASK — photo-first form
   -------------------------------------------------------------------------- */
.ask{display:grid;gap:clamp(1.75rem,4vw,3.25rem)}
.ask>*{min-width:0}
@media(min-width:900px){.ask{grid-template-columns:minmax(0,1fr) minmax(0,1.05fr)}}
.steps{list-style:none;margin:var(--s5) 0 0;padding:0;counter-reset:step}
.steps li{counter-increment:step;display:grid;grid-template-columns:auto minmax(0,1fr);
  gap:.9rem;margin-bottom:var(--s4);align-items:start}
.steps li::before{content:counter(step);font-family:var(--ff-display);font-weight:700;
  font-size:1.5rem;line-height:1;color:var(--gold-ink);border:2px solid var(--gold);
  width:2.6rem;height:2.6rem;display:flex;align-items:center;justify-content:center;flex:none}
.steps b{display:block;font-size:1.05rem}
.steps span{color:var(--ink-2);font-size:.9375rem}
.band--forest .steps li::before,.band--night .steps li::before{color:var(--gold-lit);border-color:var(--gold-lit)}
.band--forest .steps span,.band--night .steps span{color:#D8CFBD}

.form{background:var(--paper);border:1px solid var(--sand);
  border-top:5px solid var(--forest);padding:var(--s5);color:var(--ink)}
.band--forest .form,.band--night .form{border-top-color:var(--gold)}
/* A white card inside a dark band inherits the band's light text. Reset
   everything that lives on the card back to ink. */
.band--forest .form h2,.band--forest .form h3,
.band--night .form h2,.band--night .form h3{color:var(--ink)}
.band--forest .form p,.band--night .form p{color:var(--ink-2)}
.band--forest .form a,.band--night .form a{color:var(--forest)}
.band--forest .form a:hover,.band--night .form a:hover{color:var(--ink)}
.field{margin-bottom:var(--s4)}
.field label{display:block;font-weight:700;font-size:.9375rem;margin-bottom:.35rem;color:var(--ink)}
.field .hint{display:block;font-weight:400;font-size:.8125rem;color:var(--ink-2);margin-top:.1rem}
.field input,.field select,.field textarea{
  width:100%;font-family:var(--ff-ui);font-size:1.0625rem;padding:.8rem .85rem;
  border:1px solid #B9AB92;background:#fff;color:var(--ink);border-radius:var(--r);min-height:52px
}
.field textarea{min-height:118px;line-height:1.5}
.field input:focus,.field select:focus,.field textarea:focus{border-color:var(--forest);
  box-shadow:0 0 0 3px rgba(0,90,36,.16);outline:none}
.field--file input{padding:.65rem;background:var(--paper-2)}
.form__foot{font-size:.8125rem;color:var(--ink-2);margin:var(--s3) 0 0}
.form .btn{width:100%}

/* --------------------------------------------------------------------------
   17. FAQ — zero JS
   -------------------------------------------------------------------------- */
.faq{border-top:1px solid var(--sand)}
.faq details{border-bottom:1px solid var(--sand)}
.faq summary{cursor:pointer;list-style:none;padding:1.05rem 2.5rem 1.05rem 0;position:relative;
  font-family:var(--ff-display);font-size:1.125rem;font-weight:700;line-height:1.35}
.faq summary::-webkit-details-marker{display:none}
.faq summary::after{content:"";position:absolute;right:.55rem;top:1.6rem;width:12px;height:12px;
  border-right:2px solid var(--gold-ink);border-bottom:2px solid var(--gold-ink);
  transform:rotate(45deg);transition:transform .18s}
.faq details[open] summary::after{transform:rotate(-135deg);top:1.9rem}
.faq summary:hover{color:var(--forest)}
.faq .answer{padding:0 0 1.15rem;max-width:var(--measure);color:var(--ink-2)}
.faq .answer p:last-child{margin-bottom:0}

/* --------------------------------------------------------------------------
   18. LINK LISTS / RELATED
   -------------------------------------------------------------------------- */
.linklist{list-style:none;margin:0;padding:0;columns:1}
@media(min-width:640px){.linklist{columns:2;column-gap:var(--s6)}}
.linklist li{margin:0;break-inside:avoid;border-bottom:1px solid var(--sand)}
.linklist a{display:block;padding:.72rem 0;color:var(--ink);text-decoration:none;font-weight:600;
  font-size:.9375rem}
.linklist a:hover{color:var(--forest)}
.linklist a::after{content:"→";color:var(--gold-ink);margin-left:.5rem;font-weight:400}

/* --------------------------------------------------------------------------
   19. STICKY MOBILE ACTION BAR — three paths, always
   -------------------------------------------------------------------------- */
.actionbar{position:fixed;left:0;right:0;bottom:0;z-index:120;display:grid;
  grid-template-columns:repeat(3,1fr);background:var(--night);
  border-top:3px solid var(--gold);box-shadow:0 -6px 22px rgba(0,0,0,.22)}
.actionbar a{display:flex;flex-direction:column;align-items:center;justify-content:center;
  gap:.15rem;padding:.6rem .3rem calc(.6rem + env(safe-area-inset-bottom));
  color:#F3ECDC;text-decoration:none;font-weight:700;font-size:.9375rem;line-height:1.15;
  border-left:1px solid rgba(255,255,255,.13)}
.actionbar a:first-child{border-left:0;background:var(--gold);color:var(--ink)}
.actionbar a small{font-size:.6875rem;font-weight:600;letter-spacing:.1em;text-transform:uppercase;
  opacity:.8}
@media(min-width:900px){.actionbar{display:none}}
body{padding-bottom:74px}
@media(min-width:900px){body{padding-bottom:0}}

/* --------------------------------------------------------------------------
   20. FOOTER
   -------------------------------------------------------------------------- */
.foot{background:var(--night);color:#D5CCBA;padding-block:clamp(2.75rem,6vw,4.5rem)}
.foot a{color:#EFE8DA;text-decoration:none}
.foot a:hover{color:var(--gold-lit);text-decoration:underline}
.foot h4{font-family:var(--ff-ui);font-size:var(--t-eyebrow);letter-spacing:.16em;
  text-transform:uppercase;color:var(--gold-lit);margin:0 0 var(--s3)}
.foot ul{list-style:none;margin:0;padding:0;font-size:.9375rem}
.foot li{margin-bottom:.5rem}
.foot__grid{display:grid;gap:var(--s6) var(--s5);grid-template-columns:minmax(0,1fr)}
@media(min-width:680px){.foot__grid{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media(min-width:980px){.foot__grid{grid-template-columns:1.4fr 1fr 1fr 1fr}}
.foot__lockup{display:flex;align-items:center;gap:.65rem;margin-bottom:var(--s4)}
.foot__lockup img{height:46px;width:auto;background:var(--paper-2);
  padding:.4rem .55rem;border-radius:2px}
.foot__name{font-family:var(--ff-display);font-size:1.7rem;font-weight:700;color:var(--gold-lit);
  line-height:.95;display:block}
.foot__sub{font-size:.6875rem;letter-spacing:.19em;text-transform:uppercase;color:#EFE8DA;
  font-weight:700}
.foot__phone{font-family:var(--ff-display);font-size:1.75rem;font-weight:700;color:#fff;
  text-decoration:none;display:inline-block;margin-bottom:.35rem}
.foot__legal{border-top:1px solid rgba(255,255,255,.14);margin-top:var(--s7);padding-top:var(--s4);
  font-size:.8125rem;color:#A79E8C;display:flex;flex-wrap:wrap;gap:.5rem 1.5rem}

/* --------------------------------------------------------------------------
   21. UTILITIES
   -------------------------------------------------------------------------- */
.mt0{margin-top:0}.mb0{margin-bottom:0}
.center{text-align:center}
.stack>*+*{margin-top:var(--s4)}
.hr-gold{border:0;border-top:2px solid var(--gold);margin:var(--s6) 0}
.kicker{font-family:var(--ff-display);font-size:var(--t-h3);line-height:1.3;
  border-left:3px solid var(--gold);padding-left:var(--s4);color:var(--ink);max-width:44ch}
.band--forest .kicker,.band--night .kicker{color:var(--paper)}

@media(prefers-reduced-motion:reduce){
  *,*::before,*::after{transition-duration:.01ms!important;animation-duration:.01ms!important}
}
@media print{
  .mast,.actionbar,.topbar,.hero__img{display:none}
  body{background:#fff;padding:0}
}

/* ── Credential registry ────────────────────────────────────────────────────
   Transplanted from Direction A. The ARGUMENT is the asset ("ask who holds
   it"); the specifics stay empty until the office confirms them, because the
   surname and certificate number were read off a 2022 badge JPEG and were
   never verified. A pending row costs nothing. A wrong certificate number on a
   licensed trade's website is a different kind of problem entirely. */
.cred{margin:var(--s4) 0 var(--s2);border-top:1px solid var(--sand)}
.cred__row{display:grid;grid-template-columns:minmax(7.5rem,10rem) 1fr;gap:var(--s2);
  padding:.7rem 0;border-bottom:1px solid var(--sand);align-items:baseline}
.cred__row dt{font-family:var(--ff-ui);font-size:var(--t-eyebrow);letter-spacing:.08em;
  text-transform:uppercase;color:var(--ink-2)}
.cred__row dd{margin:0;font-size:var(--t-body);color:var(--ink)}
.cred__pending{color:var(--ink-2);font-style:italic}
.cred__pending::before{content:"";display:inline-block;width:.5rem;height:.5rem;
  margin-right:.5rem;border-radius:50%;background:var(--gold);vertical-align:middle}
.cred__foot{margin-top:var(--s3);font-size:.875rem;color:var(--ink-2);max-width:56ch}
.band--forest .cred{border-top-color:rgba(255,255,255,.18)}
.band--forest .cred__row{border-bottom-color:rgba(255,255,255,.18)}
.band--forest .cred__row dt{color:rgba(255,255,255,.66)}
.band--forest .cred__row dd,.band--forest .cred__foot{color:rgba(255,255,255,.92)}
.band--forest .cred__pending{color:rgba(255,255,255,.66)}

/* The review policy. Turns "we have no quotes to show" into a trust position. */
.wall__policy{margin-top:var(--s3);font-size:.875rem;color:var(--ink-2);max-width:52ch;
  padding-left:var(--s3);border-left:2px solid var(--gold)}

@media (max-width:34em){
  .cred__row{grid-template-columns:1fr;gap:.15rem;padding:.6rem 0}
}

/* ── Tall-text splits: let the plate travel ─────────────────────────────────
   .split centres its columns, which is right when the two sides are a similar
   height. In the arborist band the text column carries paragraphs, the
   credential registry AND two buttons, so a centred short photo left a large
   dead area the eye falls into — caught in a full-page scroll render, invisible
   in an above-the-fold screenshot.

   Sticky rather than stretched on purpose: stretching would force a 1200x900
   landscape frame into a tall crop and cut the ruler-and-trunk subject that IS
   the point of the photograph. This keeps the evidence in view the whole way
   down the argument instead. */
@media (min-width:60em){
  #arborist .split{align-items:start}
  #arborist .split__media{position:sticky;top:5.5rem}
}
@media (prefers-reduced-motion:reduce){
  #arborist .split__media{position:static}
}

/* ==========================================================================
   MOBILE LENGTH PASS — 2026-07-27
   The homepage measured 19,326 CSS px tall at a 520px viewport. The storm
   band and the contact form sat past 15,000px, which on a phone means the
   conversion path is not reached at all. Everything below shortens the READ,
   not the CONTENT: one section merged, one section tightened to its number
   and a door, and the services index turned into a compact list-with-thumbnail
   on small screens. No copy was deleted to hit the number.
   ========================================================================== */

/* ── Honeypot ──────────────────────────────────────────────────────────────
   Off-screen, NOT display:none. A display:none field is skipped by some
   browsers' autofill and, if it were ever marked required, would make the
   form silently unsubmittable for a real person. This survives as-is into the
   WordPress build; the handler drops any submission with hp_website filled. */
.hp-field{position:absolute;left:-9999px;top:auto;width:1px;height:1px;
  overflow:hidden;white-space:nowrap}

/* ── The merged crew/equipment note ────────────────────────────────────────
   Was a two-column .split carrying a SECOND copy of the spider-lift photo.
   The photo is now shown once, in the equipment plates directly above, and
   the crew argument runs full width underneath them — same words, one screen
   shorter, and the section finally reads as one argument. */
.crewnote{margin-top:var(--s6);padding-top:var(--s5);border-top:2px solid var(--gold)}
.crewnote>p:not(.eyebrow):not(.kicker){max-width:var(--measure)}
.crewnote .kicker{max-width:46ch}
@media(min-width:860px){.crewnote{margin-top:var(--s7)}}

/* ── Services index: compact on a phone, unchanged on a desktop ────────────
   Nine stacked cards with 4:3 photographs ran 4,968px on a 520px screen —
   a quarter of the entire page for what is a MENU. Below 720px each card
   becomes a media object: the photograph survives as a square thumbnail
   (it is still their own work, still proof), and the whole index fits in
   about two screens. Above 720px nothing changes.

   .card--noimg marks the two cards whose photograph is an open PHOTO SLOT,
   so the body simply takes the full width instead of leaving a hole. */
@media(max-width:719px){
  .card{flex-direction:row;align-items:stretch}
  .card img{flex:0 0 118px;width:118px;aspect-ratio:1/1;align-self:flex-start}
  .card__body{padding:var(--s3) var(--s4) var(--s4);gap:0}
  .card h3{font-size:1.15rem}
  .card p{margin-bottom:var(--s3)}
  .card--noimg .card__body{padding-left:var(--s4)}
  .grid--3:has(.card){gap:var(--s4)}
}

/* ── A plate with its photograph still open ────────────────────────────────
   Used where a frame was removed because it duplicated another photograph on
   the same page and no honest replacement exists yet (see the PHOTO SLOT
   comments). Centring the caption stops the cell reading as a loading error
   next to its full-height siblings; the gold label keeps it in the set. */
.plate--noimg{justify-content:center;background:var(--paper-2);
  border-left:3px solid var(--gold);padding:var(--s5) var(--s4)}
.plate--noimg figcaption{border-top:0;padding-top:0;margin:0}
.grid>.plate--noimg figcaption{margin-top:0}

/* ── Photo plates: two abreast on a large phone ────────────────────────────
   Three full-width 4:3 plates stacked is 1,300px for ONE argument. From
   440px up they pair off, which is how a contact sheet reads anyway. Scoped
   with :has() so the SERVICES cards — which are media objects at this width,
   not plates — are untouched; where :has() is unsupported the layout simply
   falls back to today's single column.

   MEASURED, not assumed: pairing the .reason blocks the same way made the
   page LONGER (a 227px column wraps three-word headings onto two lines), so
   only plates pair. */
@media(min-width:440px) and (max-width:719px){
  .grid--3:has(>.plate){grid-template-columns:repeat(2,minmax(0,1fr))}
  .grid--3:has(>.plate) figcaption{font-size:.8125rem}
}

/* ── Vertical rhythm on a phone ────────────────────────────────────────────
   3rem top AND bottom on twelve bands is 1,150px of a 19,000px page spent on
   air. At >=640px the original rhythm is untouched. */
@media(max-width:639px){
  .band{padding-block:2.1rem}
  .band--tight{padding-block:1.6rem}
  .grid{gap:var(--s4)}
  /* Captions are a truth mechanism and stay — they just stop being airy. */
  .plate figcaption{padding-top:.5rem;margin-bottom:.35rem;line-height:1.4}
  /* .reason blocks are short by design; on a phone they do not need
     desktop-sized headings or a 1rem rule above each one. */
  .reason{padding-top:.65rem}
  .reason h3{font-size:1.1rem}
  .reason p{font-size:.9rem}
  .steps li{gap:.55rem}
  .note{padding:var(--s4)}
  /* The services index is a MENU on a phone: thumbnail, name, one line of
     what it is. The full photography lives on the service page itself. */
  .card img{flex:0 0 104px;width:104px}
  .card p{font-size:.875rem}
}

/* The credential registry should still read as a REGISTRY on a large phone:
   stacking every dt over its dd cost four extra lines. Below 400px it stacks,
   because a 6.5rem label column leaves nothing for the value. */
@media(min-width:400px) and (max-width:639px){
  .cred__row{grid-template-columns:6.25rem minmax(0,1fr);gap:.6rem;padding:.55rem 0}
  .cred__row dt{font-size:.6875rem;line-height:1.55}
  .cred__row dd{font-size:.9375rem}
}

/* ── The footer on a phone ─────────────────────────────────────────────────
   Four stacked link columns ran 1,333px — a tenth of the whole page, below
   the point anyone is still reading. Two columns from 480px up. Nothing is
   removed; the same links are simply two abreast. */
@media(min-width:440px) and (max-width:679px){
  .foot__grid{grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--s5) var(--s5)}
  .foot__grid>*:first-child{grid-column:1 / -1}
}
@media(max-width:679px){
  .foot li{margin-bottom:.3rem}
  .foot ul{font-size:.9rem}
  .foot__legal{margin-top:var(--s5)}
}

/* =====================================================================
   HAPPY'S IDENTITY LAYER — added 2026-07-27.
   The layout engine is shared across WSW builds; this is the layer that
   makes the site unmistakably THIS company and not a sibling build. Every
   device here is lifted from something Happy's already owns in the real
   world: the oval door decal, the yellow-on-green block numerals painted
   along the boom and the grapple truck, and the heavy black keyline that
   surrounds the wordmark.
   ===================================================================== */

/* --- 1. The oval badge. Their logo IS a shape, so use the shape. -------- */
.lockup__badge{
  display:block;height:clamp(58px,7.4vw,86px);width:auto;
  filter:drop-shadow(0 1px 0 rgba(0,0,0,.28));
}
.lockup{gap:var(--s3)}
/* The invented wordmark next to the real badge was belt-and-braces and read
   as two logos. The badge already says the name. */
.lockup .lockup__type{display:none}

/* --- 2. The plate. Their phone number is signage, so set it as signage. -
   Yellow block numerals on truck green inside a black keyline: this is the
   grapple truck's door, and the bottom bar of their own printed logo. */
.signplate{
  display:inline-flex;align-items:center;gap:.6em;
  background:var(--truck);color:var(--yellow);
  border:3px solid var(--outline);border-radius:4px;
  padding:.42em .78em;
  font-family:var(--ff-ui);font-weight:800;
  font-variant-numeric:lining-nums tabular-nums;
  letter-spacing:.01em;line-height:1;text-decoration:none;white-space:nowrap;
  box-shadow:0 2px 0 rgba(0,0,0,.35);
}
.signplate:hover,.signplate:focus-visible{background:#0A6407;color:#fff}
.signplate--lg{font-size:clamp(1.05rem,1.9vw,1.4rem);padding:.5em .7em}
.signplate--sm{font-size:1rem;border-width:2px}
.plate__tag{
  font-size:.52em;font-weight:700;letter-spacing:.1em;text-transform:uppercase;white-space:nowrap;
  color:#BFE8B8;align-self:center;
}

/* --- 3. Outlined display type, as printed on the badge ------------------
   Yellow fill, black keyline. Only ever over a dark surface or a photo. */
.stamp{
  color:var(--yellow);
  -webkit-text-stroke:2px var(--outline);
  paint-order:stroke fill;
  text-shadow:0 3px 0 rgba(0,0,0,.35);
}
@supports not (paint-order:stroke){
  .stamp{-webkit-text-stroke:0;text-shadow:
    -2px -2px 0 var(--outline),2px -2px 0 var(--outline),
    -2px 2px 0 var(--outline),2px 2px 0 var(--outline);}
}

/* --- 4. The 37-year mark. The oldest thing they own is the year. ------- */
.since{
  display:inline-flex;align-items:baseline;gap:.5em;
  font-family:var(--ff-display);
}
.since__n{
  font-size:1.9em;font-weight:700;line-height:.9;
  color:var(--yellow);-webkit-text-stroke:1.5px var(--outline);paint-order:stroke fill;
}
.since__t{font-size:.82em;letter-spacing:.02em}
.band--forest .since__t,.band--night .since__t,.hero .since__t{color:#E4DCCB}

/* --- 5. Eyebrow: the dash becomes a slice of the oval keyline ---------- */
.eyebrow::before{
  width:1.5rem;height:1.5rem;border-radius:50%;
  background:transparent;border:2px solid var(--gold);
  border-right-color:transparent;border-bottom-color:transparent;
  transform:rotate(-45deg);
}
.band--forest .eyebrow::before,.band--night .eyebrow::before{
  border-color:var(--yellow);border-right-color:transparent;border-bottom-color:transparent;
}

/* --- 6. Call button in the brand's own colours, not a generic gold ----- */
.btn--call{
  background:var(--yellow);color:var(--outline);border-color:var(--outline);
  border-width:2px;font-weight:800;
  font-variant-numeric:lining-nums tabular-nums;
}
.btn--call:hover{background:var(--yellow-2);color:var(--outline)}
.band--forest .btn--call,.band--night .btn--call{
  background:var(--yellow);color:var(--outline);border-color:var(--outline);
}

/* --- 7. Livery strip: a hairline of truck green + yellow under the mast  */
.mast{border-bottom:0}
.livery{height:5px;background:linear-gradient(180deg,var(--truck) 0 3px,var(--yellow) 3px 5px)}

@media (max-width:640px){
  .lockup__badge{height:52px}
  .signplate--lg{font-size:1.25rem}
}

/* Nav labels must not wrap: the signplate is wider than the old gold button
   and squeezed "Service Areas" / "Tree Permits" onto two lines each. */
.nav a{white-space:nowrap}
@media(min-width:981px) and (max-width:1200px){
  .nav{gap:1rem}
  .signplate--lg{font-size:1rem}
  .signplate__tag{display:none}
}

/* =====================================================================
   LAYOUT & FLOW REDESIGN — 2026-07-27
   Brief (Matt): stop reading as a sibling of the Weave's build; take the
   type cues from the oval badge; make it feel like a neighbour or a family
   friend rather than a contractor template; modern, slick buttons.

   The structural move is the hero. A full-bleed photograph with a heavy
   dark scrim and white type over it is THE contractor-template tell, and it
   is what the two builds shared. Here the photograph becomes a framed,
   rounded panel and the copy sits on a cream card laid over it — a picture
   on a mantelpiece, not a banner. No markup change was needed: `.hero .wrap`
   already contains exactly the copy that belongs on that card.
   ===================================================================== */

:root{
  /* Type cues from the badge: "Happy's" is a warm high-contrast serif with
     generous round bowls, so the display face leads with Iowan Old Style /
     Palatino rather than Georgia. Both carry old-style figures, which is
     what keeps 1989, 37 and 477 feeling hand-set instead of corporate. */
  --ff-display:"Iowan Old Style","Palatino Linotype",Palatino,"Book Antiqua",Georgia,serif;
  /* Prose in a serif too. A neighbour writes you a letter; a vendor sends
     you a system-ui interface. Labels and buttons stay sans. */
  --ff-prose:"Iowan Old Style",Charter,"Bitstream Charter",Georgia,serif;

  --r:14px;            /* was 2px "printed, not app-like" — too austere for
                          the brief; soft corners read as friendly */
  --r-sm:10px;
  --r-pill:999px;
  --sh-1:0 1px 2px rgba(28,23,16,.06),0 3px 10px rgba(28,23,16,.06);
  --sh-2:0 2px 6px rgba(28,23,16,.08),0 14px 34px rgba(28,23,16,.12);
  --sh-3:0 4px 12px rgba(28,23,16,.10),0 26px 60px rgba(28,23,16,.18);
}

/* ---- 1. PROSE VOICE ---------------------------------------------------- */
.prose,.lede,.hero__lede,p,li{font-family:var(--ff-prose)}
.prose{font-size:1.09rem;line-height:1.72}
.eyebrow,.btn,.nav,.topbar,.signplate,.crumbs,.proof,.sub-label,
.card__link,.actions,.menu,figcaption b{font-family:var(--ff-ui)}

/* ---- 2. THE HERO: framed photo + cream card ---------------------------- */
.hero{
  background:var(--paper);color:var(--ink);
  min-height:0;display:block;padding:clamp(.75rem,1.6vw,1.25rem)
    clamp(.75rem,1.6vw,1.25rem) clamp(2rem,4vw,3rem);
  align-items:initial;
}
@media(min-width:900px){.hero{min-height:0}}
.hero--page{min-height:0}
@media(min-width:900px){.hero--page{min-height:0}}

/* the photograph, framed */
.hero__img{
  position:relative;inset:auto;z-index:0;
  width:100%;height:clamp(300px,46vw,520px);object-fit:cover;object-position:60% 50%;
  border-radius:var(--r);box-shadow:var(--sh-2);
}
/* the scrim was doing the legibility work; the card does it now */
.hero::after{content:none}

/* the card */
.hero .wrap{
  position:relative;z-index:2;
  background:var(--paper);
  border-radius:var(--r);
  box-shadow:var(--sh-3);
  padding:clamp(1.5rem,3.4vw,2.6rem) clamp(1.25rem,3vw,2.6rem);
  margin-top:clamp(-4.5rem,-7vw,-2.5rem);
  max-width:min(760px,calc(100% - clamp(1rem,4vw,4rem)));
  border:1px solid var(--sand-2);
}
@media(min-width:1000px){
  .hero .wrap{margin-left:clamp(1.5rem,5vw,5rem);margin-right:auto}
}
.hero h1{color:var(--ink);text-shadow:none;max-width:18ch}
.hero--page h1{max-width:22ch}
.hero__lede{color:var(--ink-2);text-shadow:none;margin:var(--s4) 0 var(--s5);max-width:54ch}
.hero__eyebrow{color:var(--gold-ink)}
.hero__ask{color:var(--ink-2)}
.hero__ask b{color:var(--gold-ink)}
.crumbs,.crumbs a{color:var(--ink-2)}
.crumbs a:hover{color:var(--ink)}
.hero__credit{color:var(--ink-2);opacity:.75;position:static;text-align:right;
  display:block;margin:.4rem .2rem 0}

/* ---- 3. BUTTONS: modern, slick, still theirs -------------------------- */
.btn{
  border-radius:var(--r-pill);
  min-height:56px;padding:.9rem 1.6rem;
  box-shadow:var(--sh-1);
  transition:transform .16s cubic-bezier(.2,.7,.3,1),
             box-shadow .16s cubic-bezier(.2,.7,.3,1),
             background-color .16s ease;
  will-change:transform;
}
.btn:hover{transform:translateY(-2px);box-shadow:var(--sh-2)}
.btn:active{transform:translateY(0);box-shadow:var(--sh-1)}
.btn--call{
  background:linear-gradient(180deg,#FFEB57 0%,var(--yellow) 46%,#EFD30F 100%);
  color:var(--outline);border-color:var(--outline);border-width:2px;
}
.btn--call:hover{background:linear-gradient(180deg,#FFF07A 0%,#FFE733 46%,var(--yellow) 100%)}
.btn--text{
  background:linear-gradient(180deg,#0A6F2E 0%,var(--forest) 60%,#004D1E 100%);
  border-color:#004D1E;
}
.btn--form{border-radius:var(--r-pill);border-width:2px}
.btn--form:hover{background:var(--ink);color:var(--paper)}
@media(prefers-reduced-motion:reduce){
  .btn,.btn:hover,.btn:active{transition:none;transform:none}
}
.signplate{border-radius:var(--r-sm)}

/* ---- 4. CARDS & PLATES: rounded, lifted, no hard template borders ----- */
.card,.plate,.place,.faq,.revpanel,.form{
  border-radius:var(--r);
}
.card{
  background:var(--paper);border:1px solid var(--sand-2);
  box-shadow:var(--sh-1);overflow:hidden;
  transition:transform .18s cubic-bezier(.2,.7,.3,1),box-shadow .18s ease;
}
.card:hover{transform:translateY(-3px);box-shadow:var(--sh-2)}
.card img{border-radius:0}
.plate img,.plate figure img{border-radius:var(--r-sm)}
@media(prefers-reduced-motion:reduce){.card,.card:hover{transform:none;transition:none}}

/* ---- 5. SECTION HEADS: conversational, not filing-cabinet -------------- */
.eyebrow{
  letter-spacing:.1em;color:var(--gold-ink);
  font-size:.78rem;
}
h2{letter-spacing:-.016em}
.lede{font-size:var(--t-lede);color:var(--ink-2)}

/* ---- 6. PROOF BAR: a row of chips, not a stripe ------------------------ */
.proof{background:var(--paper-2);border-block:1px solid var(--sand-2)}
.proof ul{gap:.5rem 1rem}
.proof li{
  background:var(--paper);border:1px solid var(--sand-2);border-radius:var(--r-pill);
  padding:.4rem .9rem;box-shadow:var(--sh-1);
}

/* ---- 7. MAST: softer, and it floats on the paper ---------------------- */
.mast{background:var(--paper);box-shadow:0 1px 0 var(--sand-2)}
.livery{height:4px}

/* Proof bar was light-on-dark; moving it to cream chips stranded every
   colour it inherited (#EFE8DA text, #fff bolds) on a pale background and
   the whole row went invisible except the stars. Re-colour the CONTENTS,
   not just the container — caught on the first screenshot, not in review. */
.proof{color:var(--ink);border-bottom:1px solid var(--sand-2)}
.proof li{color:var(--ink);font-weight:600}
.proof b,.proof .rating{color:var(--ink)}
.proof .stars{color:var(--tally)}
.proof li:not(:last-child)::after{content:none}   /* chips need no separator */

/* =====================================================================
   HERO + LOCKUP, second pass (Matt, 2026-07-27):
   "make the logo bigger to overhang the header slightly", and
   "no blank space like on desktop right side next to 37 years".
   ===================================================================== */

/* --- Badge overhangs the masthead ------------------------------------- */
.mast{position:relative;z-index:30}
.mast .wrap{position:relative}
.lockup__badge{
  height:clamp(66px,9vw,116px);
  /* hangs below the mast without adding height to it */
  margin-bottom:clamp(-30px,-3.2vw,-14px);
  position:relative;z-index:31;
  filter:drop-shadow(0 3px 6px rgba(28,23,16,.28));
}
@media(max-width:640px){
  .lockup__badge{height:60px;margin-bottom:-14px}
}

/* --- Desktop hero: the card sits ON the photograph --------------------
   Stacking the card BELOW the photo left a band of empty cream to its
   right at desktop width. Overlaying it removes the dead space and lets
   the photograph run the full width behind the copy. */
@media(min-width:1000px){
  .hero{position:relative;display:grid;padding-bottom:clamp(2rem,3vw,3rem)}
  .hero__img{
    grid-area:1/1;height:clamp(460px,42vw,620px);
    object-position:72% 50%;      /* keep the branded truck in frame */
  }
  .hero .wrap{
    grid-area:1/1;align-self:center;justify-self:start;
    margin:0 0 0 clamp(1.5rem,4vw,4.5rem);
    max-width:min(620px,52%);
    background:rgba(250,246,238,.965);
    backdrop-filter:saturate(1.08);
  }
  .hero__credit{grid-area:1/1;align-self:end;justify-self:end;margin:0 1rem .6rem;
    color:#fff;opacity:.8;text-shadow:0 1px 6px rgba(0,0,0,.6)}
}
/* Between tablet and desktop keep the overlap but give the card more room */
@media(min-width:1000px) and (max-width:1180px){
  .hero .wrap{max-width:min(560px,58%);margin-left:clamp(1rem,3vw,2rem)}
}

/* The bigger badge plus the signplate overran the nav at ~1200-1440 and the
   plate sat on top of "Contact". Give the row a real grid, let the nav be the
   flexible column, and step the plate down before it collides. */
@media(min-width:981px){
  .mast .wrap{display:flex;align-items:center;gap:clamp(.6rem,1.4vw,1.4rem)}
  .nav{flex:1 1 auto;min-width:0;display:flex;flex-wrap:nowrap;
       justify-content:flex-end;gap:clamp(.55rem,1.3vw,1.35rem)}
  .nav a{font-size:clamp(.9rem,1.02vw,1rem)}
  .mast__spacer{display:none}
  .mast__cta{flex:0 0 auto;display:flex;gap:.5rem;align-items:center}
}
@media(min-width:981px) and (max-width:1440px){
  .signplate--lg{font-size:.98rem;padding:.45em .6em}
  .signplate__tag{display:none}
}
@media(min-width:981px) and (max-width:1120px){
  .mast__cta .btn--text{display:none}   /* keep the CALL, drop the secondary */
}

/* =====================================================================
   TIGHTEN + ALIGN — 2026-07-27 (Matt: "doesn't need to stretch super wide",
   "not have to fill up so much space", "hero image isn't lining up right",
   "easier bring visitors down the funnel").
   The homepage was ~9,000px tall with a 66ch column parked on the left of a
   1180px container, leaving a dead strip down the right of every text band.
   That reads as an unfinished template AND it pushes every CTA further away.
   ===================================================================== */
:root{
  --max:1040px;              /* was 1180 */
  --measure:64ch;
}

/* Single-column text centres in its own container instead of hugging the
   left edge with dead space beside it. Two-column bands are untouched. */
.prose{margin-inline:auto}
.band > .wrap > h2,
.band > .wrap > .eyebrow,
.band > .wrap > .lede,
.band > .wrap > p{max-width:var(--measure);margin-inline:auto}

/* Vertical rhythm: less air between bands = fewer screens to the next CTA. */
.band{padding-block:clamp(2.25rem,4.6vw,3.75rem)}
.band--tight{padding-block:clamp(1.5rem,3vw,2.25rem)}
.prose h2{margin-top:var(--s6)}
.prose h3{margin-top:var(--s5)}

/* --- HERO ALIGNMENT --------------------------------------------------
   The photo was inset by a stray 12px padding while the masthead aligned to
   the 1040 container, so nothing shared an edge. Photo now goes full-bleed
   and the card's left edge lands exactly on the site's content column. */
.hero{padding:0 0 clamp(1.5rem,3vw,2.5rem)}
.hero__img{border-radius:0;box-shadow:none}
@media(min-width:1000px){
  .hero__img{height:clamp(440px,38vw,560px)}
  .hero .wrap{
    margin-left:max(var(--gutter),calc((100% - var(--max))/2));
    margin-right:0;
    max-width:min(600px,54%);
    border-radius:var(--r);
  }
}
@media(max-width:999px){
  .hero .wrap{
    margin-inline:auto;
    max-width:min(640px,calc(100% - 2*var(--gutter)));
  }
}

/* --- FOOTER: the real badge, and no wall-to-wall stretch --------------- */
.foot__badge{height:96px;width:auto;margin-bottom:.6rem}
.foot .wrap{max-width:var(--max)}
.foot__grid{gap:clamp(1.25rem,3vw,2.25rem)}
.foot__name,.foot__sub{display:none}   /* the badge already says the name */

/* Centring each element on its own `ch` measure gave every text element a
   DIFFERENT width — so an h2 at 64ch of display type and a p at 64ch of body
   type started on two different left edges and the column looked broken.
   One shared column in px; every text child now lands on the same edge. */
:root{--col:660px}
.band > .wrap > h2,
.band > .wrap > .eyebrow,
.band > .wrap > .lede,
.band > .wrap > p,
.band > .wrap > ul,
.band > .wrap > ol,
.band > .wrap > .actions{max-width:var(--col);margin-inline:auto}
.prose{max-width:var(--col)}

/* Keep the branded panel of the truck in frame — the sign was cropping off
   the bottom-right, which is the one part of the photo that has to be read. */
.hero__img{object-position:64% 64%}
@media(min-width:1000px){.hero__img{object-position:68% 66%}}


/* LAYER: EDITORIAL ORGANIC - 2026-07-29 final. */

/* ==========================================================================
   DIRECTION: EDITORIAL ORGANIC — matched to Matt's Lovable sample
   ("Green Legacy Landing", applied Editorial Organic style, 2026-07-28)
   Cream page · deep organic green · muted gold CTAs · serif editorial
   headlines · centered photo hero with green wash · icon-free trust bar ·
   rounded cream cards · dark-green why-band · light cream footer.
   PREVIEW loads the serif from Google; production self-hosts the woff2.
   ========================================================================== */
@font-face{
  font-family:"DM Serif Display";
  src:url("fonts/dm-serif-display.woff2") format("woff2");
  font-weight:400;font-style:normal;font-display:swap;
}

:root{
  --paper:#F8F5EC;
  --paper-2:#F1ECDE;
  --sand:#DFD8C4;
  --sand-2:#EAE4D4;

  --ink:#232B22;
  --ink-2:#57614F;

  --forest:#2E5C3F;
  --forest-2:#274E33;
  --night:#1B3A24;

  --gold:#E3B33C;
  --gold-ink:#8F6B14;
  --gold-lit:#EFC862;
  --tally:#B98F1F;
  --yellow:#E3B33C;
  --yellow-2:#D3A62F;
  --truck:#2E5C3F;
  --outline:#1B2417;
  --ember:#A33A12;

  --ff-display:"DM Serif Display",Georgia,"Times New Roman",serif;
  --ff-ui:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;
  --ff-prose:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;

  --r:16px;
  --r-pill:10px;
  --sh-1:0 1px 3px rgba(27,58,36,.05),0 4px 14px rgba(27,58,36,.06);
  --sh-2:0 4px 10px rgba(27,58,36,.07),0 20px 46px rgba(27,58,36,.12);

  --t-hero:clamp(2.6rem,6.6vw,4.8rem);
  --t-h2:clamp(1.9rem,4.2vw,3rem);
}

/* Type voice: serif display in deep green, calm system sans body. */
h1,h2,h3,.num,.foot__name{font-family:var(--ff-display);font-weight:400;letter-spacing:0}
h2,h3{color:var(--forest-2)}
h1{line-height:1.06}
.prose,.lede,.hero__lede,p,li{font-family:var(--ff-prose)}
.lede{line-height:1.6}

/* --------------------------------------------------------------------------
   HEADER — one clean cream bar: logo in the bar (no overhang), centered nav,
   quiet phone link, single gold CTA. Fixes nav-behind-logo + the signplate.
   -------------------------------------------------------------------------- */
.topbar{display:none}
.livery{height:0}
.mast{background:var(--paper);box-shadow:0 1px 0 var(--sand-2)}
.mast .wrap{min-height:78px}
.lockup__badge{height:56px;margin-bottom:0;filter:none}
@media(max-width:640px){.lockup__badge{height:46px;margin-bottom:0}}
.lockup__type{display:none}                /* the badge carries the name */
@media(min-width:981px){
  .mast .wrap{display:flex;align-items:center}
  .nav{flex:1 1 auto;justify-content:center;gap:clamp(1.1rem,2.4vw,2.2rem)}
  .nav a{font-size:.975rem}
}
.nav a{color:var(--ink);font-weight:600;border-bottom-width:2px}
.nav a:hover,.nav a[aria-current]{border-bottom-color:var(--gold);color:var(--ink)}
.nav .sub{border-radius:12px;border-color:var(--sand);box-shadow:var(--sh-2)}

/* The phone plate becomes a quiet inline link. */
.signplate{background:transparent;color:var(--ink);border:0;box-shadow:none;
  padding:.3em .2em;font-weight:700;border-radius:0}
.signplate:hover,.signplate:focus-visible{background:transparent;color:var(--forest)}
.signplate--lg{font-size:1rem;padding:.3em .2em}
.signplate__tag{display:none}
/* The header "Text a photo" button becomes the single gold CTA. */
.mast__cta .btn--text{background:var(--gold);color:#2A2210;border-color:var(--gold);
  border-radius:var(--r-pill);font-weight:700}
.mast__cta .btn--text:hover{background:var(--yellow-2);color:#2A2210}
.mast__call{background:var(--gold);color:#2A2210;border-color:var(--gold);
  border-radius:var(--r-pill)}

/* --------------------------------------------------------------------------
   HERO — full-bleed photo, deep green wash, centered copy (sample layout).
   Overrides the framed-card hero from the late brand.css layer.
   -------------------------------------------------------------------------- */
.hero{position:relative;isolation:isolate;display:flex;align-items:center;
  justify-content:center;min-height:600px;padding:0;background:var(--night);color:#fff}
.hero__img{position:absolute;inset:0;z-index:-2;width:100%;height:100%;
  object-fit:cover;object-position:64% 50%;border-radius:0;box-shadow:none}
.hero::after{content:"";position:absolute;inset:0;z-index:-1;
  background:linear-gradient(180deg,rgba(24,54,33,.72) 0%,rgba(21,48,30,.78) 55%,
    rgba(18,42,26,.86) 100%)}
.hero .wrap{position:static;background:transparent;border:0;box-shadow:none;
  margin:0;max-width:860px;padding:clamp(4.5rem,10vw,7.5rem) 1.25rem;
  text-align:center;backdrop-filter:none}
.hero__eyebrow{color:var(--gold);letter-spacing:.24em;margin:0 auto var(--s4);
  justify-content:center;display:flex}
.hero h1{color:#FFFFFF;max-width:none;text-shadow:0 2px 18px rgba(0,0,0,.25)}
.hero__lede{color:#E9EFE2;max-width:62ch;margin:var(--s5) auto;text-shadow:none}
.hero .actions{justify-content:center}
.hero__ask{color:#D8E2CF;max-width:60ch;margin:var(--s4) auto 0}
.hero__ask b{color:var(--gold-lit)}
.hero__credit{position:absolute;right:1rem;bottom:.5rem;margin:0;
  color:rgba(255,255,255,.5);text-align:right}
.hero .crumbs,.hero .crumbs a{color:#D8E2CF;justify-content:center;margin-inline:auto}
@media(min-width:1000px){
  .hero{display:flex;padding:0}
  .hero__img{position:absolute;height:100%}
  .hero .wrap{margin:0;max-width:860px;background:transparent;justify-self:auto}
}
.hero--page{min-height:420px}
.hero--page h1{max-width:none}

/* --------------------------------------------------------------------------
   TRUST BAR — quiet cream strip, centered facts, hairline rules.
   -------------------------------------------------------------------------- */
.proof{background:var(--paper);border-block:0;border-bottom:1px solid var(--sand-2)}
.proof ul{justify-content:center;gap:.5rem clamp(1.4rem,3.5vw,3rem);padding-block:1.05rem}
.proof li{background:transparent;border:0;box-shadow:none;padding:0;border-radius:0;
  color:var(--ink-2);font-weight:600}
.proof b{color:var(--ink)}
.proof li:not(:last-child)::after{content:"";width:1px;height:1.1em;
  background:var(--sand);margin-left:clamp(1.4rem,3.5vw,3rem)}
.stars{color:var(--gold)}
.proof .rating{font-family:var(--ff-display);color:var(--forest-2)}

/* Eyebrows: gold small caps with a short gold rule. */
.eyebrow{color:var(--gold-ink);letter-spacing:.22em;font-weight:700;font-size:.72rem}
.eyebrow::before{width:2rem;height:2px;background:var(--gold)}
.band--forest .eyebrow,.band--night .eyebrow{color:var(--gold-lit)}
.band--forest .eyebrow::before,.band--night .eyebrow::before{background:var(--gold-lit)}

/* --------------------------------------------------------------------------
   BUTTONS — gold primary with dark-olive text; green secondary; outline on dark.
   -------------------------------------------------------------------------- */
.btn{border-radius:var(--r-pill);box-shadow:none;font-weight:700;letter-spacing:.01em;
  transition:background-color .15s ease,color .15s ease,transform .15s ease}
.btn:hover{transform:none}
.btn--call{background:var(--gold);color:#2A2210;border-color:var(--gold)}
.btn--call:hover{background:var(--yellow-2);color:#2A2210}
.band--forest .btn--call,.band--night .btn--call{background:var(--gold);
  color:#2A2210;border-color:var(--gold)}
.band--forest .btn--call:hover,.band--night .btn--call:hover{background:var(--gold-lit);color:#2A2210}
.btn--text{background:var(--forest);color:#FFFFFF;border-color:var(--forest)}
.btn--text:hover{background:var(--forest-2);color:#FFFFFF}
.band--forest .btn--text,.band--night .btn--text{background:rgba(255,255,255,.1);
  color:#FFFFFF;border-color:rgba(255,255,255,.45)}
.band--forest .btn--text:hover,.band--night .btn--text:hover{background:rgba(255,255,255,.2);
  color:#FFFFFF;border-color:#FFFFFF}
.hero .btn--text{background:rgba(255,255,255,.1);color:#FFFFFF;border-color:rgba(255,255,255,.5)}
.hero .btn--text:hover{background:rgba(255,255,255,.22);color:#FFFFFF}
.btn--form{border-radius:var(--r-pill);border-color:var(--forest);color:var(--forest-2);border-width:2px}
.btn--form:hover{background:var(--forest);color:#FFFFFF}
.menu__panel .btn--call{color:#2A2210}
.menu__panel .btn--text{color:#FFFFFF}
.storm .btn--call{background:#FFFFFF;color:var(--ember);border-color:#FFFFFF}

/* --------------------------------------------------------------------------
   CARDS & PLATES — rounded cream cards, soft borders, serif titles.
   -------------------------------------------------------------------------- */
.card{background:#FBF8F0;border:1px solid var(--sand-2);border-radius:var(--r);
  box-shadow:var(--sh-1)}
.card:hover{transform:translateY(-3px);box-shadow:var(--sh-2)}
.card img{filter:saturate(.98) contrast(1.02)}
.card h3{font-size:1.4rem}
.card__link{color:var(--forest);font-weight:700}
.band--paper2 .card{background:#FBF8F0}

.plate{background:#FBF8F0;border:1px solid var(--sand-2);border-radius:var(--r);
  padding:.6rem .6rem .1rem;box-shadow:var(--sh-1)}
.plate img{filter:saturate(.98) contrast(1.03);border-radius:calc(var(--r) - 6px)}
.plate figcaption{font-family:var(--ff-ui);font-style:normal;font-size:.85rem;
  color:var(--ink-2);border-top:1px solid var(--sand-2)}
.plate figcaption b{color:var(--forest)}
.plate--dark{background:#20402A;border-color:#2E5C3F}
.plate--duo{background:var(--forest-2);border-color:var(--forest-2)}
.plate--duo img{filter:grayscale(1) contrast(1.1) sepia(.4) hue-rotate(80deg) saturate(1.15) brightness(.95)}
figure.plate{align-self:start}
.grid>.plate{align-self:stretch}

/* Numbers: serif green figures, gold hairline. */
.ledger{border-top:2px solid var(--gold);padding-top:var(--s5)}
.num{font-family:var(--ff-display);font-weight:400;color:var(--forest-2)}
.band--forest .num,.band--night .num{color:var(--gold-lit)}
.num-label{color:var(--ink-2)}
.band--forest .num-label,.band--night .num-label{color:#CBD8C4}

/* --------------------------------------------------------------------------
   BANDS — cream rhythm; the green band matches the sample's why-band.
   -------------------------------------------------------------------------- */
.band--paper2{background:var(--paper-2)}
.band--forest{background:var(--forest-2)}
.band--forest h2,.band--night h2,.band--forest h3{color:#FFFFFF}
.band--forest .lede,.band--night .lede{color:#DEE8D6}
.band--forest .reason p{color:#DEE8D6}
.band--forest .steps li::before{background:var(--gold);color:#2A2210}

/* FAQ + forms: white rounded card fields (sample's estimate form). */
.faq details,.faq{border-radius:14px}
.form{background:#FFFFFF;border-radius:18px;box-shadow:var(--sh-2);border:1px solid var(--sand-2)}
.band--forest .form h2,.band--forest .form h3{color:var(--forest-2)}
.field input,.field select,.field textarea{border-radius:10px;border-color:var(--sand)}
.field input:focus,.field select:focus{border-color:var(--forest)}

/* --------------------------------------------------------------------------
   FOOTER — light cream, hairlines, green headings (sample footer).
   -------------------------------------------------------------------------- */
.foot{background:var(--paper);color:var(--ink-2);border-top:1px solid var(--sand)}
.foot a{color:var(--ink)}
.foot a:hover{color:var(--forest);text-decoration:underline}
.foot h4{color:var(--forest-2);letter-spacing:.18em}
.foot__name{color:var(--forest-2)}
.foot__legal{color:var(--ink-2)}

/* Mobile action bar: gold call cell, green text cell. */
.actionbar a{font-family:var(--ff-ui)}

/* --------------------------------------------------------------------------
   DE-WEAVE PASS — break every visual fingerprint shared with
   weavestreetrimming.com (same builder, owners know each other).
   Weave's: dash+caps eyebrows, inline dotted proof row, bare serif step
   numerals in outline boxes, dot-separated serif town list, pink accent.
   Happy's: gold chip eyebrows, columnar stat cells, filled gold circle
   steps, arrowed sans town grid, gold accent. No italics anywhere.
   -------------------------------------------------------------------------- */
.eyebrow{background:var(--gold);color:#2A2210;padding:.34rem .75rem;
  border-radius:999px;letter-spacing:.14em;font-size:.7rem;gap:0}
.eyebrow::before{display:none}
.band--forest .eyebrow,.band--night .eyebrow{background:var(--gold);color:#2A2210}
.band--forest .eyebrow::before,.band--night .eyebrow::before{display:none}
.hero__eyebrow{background:transparent;color:var(--gold);padding:0;border-radius:0;
  letter-spacing:.24em}

/* Proof bar: centered columnar cells with a gold tick above each. */
.proof ul{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));
  gap:1.1rem 1.5rem;justify-items:center;padding-block:1.35rem}
@media(min-width:900px){.proof ul{display:flex;justify-content:center;
  gap:0 clamp(2rem,4.5vw,3.75rem)}}
.proof li{flex-direction:column;text-align:center;gap:.3rem;font-size:.9rem;
  position:relative;padding-top:.7rem}
.proof li::before{content:"";position:absolute;top:0;left:50%;
  transform:translateX(-50%);width:1.5rem;height:3px;background:var(--gold);
  border-radius:2px}
.proof li:not(:last-child)::after{content:none;margin:0;width:0}

/* Steps: filled gold circular badges with sans numerals. */
.steps li::before{background:var(--gold);color:#2A2210;border:0;border-radius:999px;
  font-family:var(--ff-ui);font-weight:800;font-size:1.05rem;
  width:2.4rem;height:2.4rem}
.band--forest .steps li::before,.band--night .steps li::before{
  background:var(--gold);color:#2A2210;border:0}

/* Towns: sans link grid with gold arrows (no serif, no dot separators). */
.towns{font-family:var(--ff-ui);font-size:1rem;display:grid;
  grid-template-columns:repeat(auto-fill,minmax(11.5rem,1fr));gap:.6rem 1.2rem}
.towns li::after,.towns li:last-child::after{content:none;margin:0}
.towns a{border-bottom:0;font-weight:600}
.towns a::before{content:"\2192";color:var(--gold);margin-right:.5rem}

/* --------------------------------------------------------------------------
   DE-WEAVE: ARBORIST MODULE — Weave's uses the identical sticky-image split
   (text column + photo floating alongside). Rebuilt as a centered credential
   band: chip eyebrow, centered serif argument, credential table as a white
   card, evidence photo as a wide framed banner BELOW. No sticky anywhere.
   -------------------------------------------------------------------------- */
#arborist .split{display:flex;flex-direction:column-reverse;
  gap:clamp(2rem,4vw,3rem);max-width:880px;margin-inline:auto}
#arborist .split__media{position:static !important;width:100%;top:auto}
#arborist{text-align:center}
#arborist .eyebrow{margin-inline:auto}
#arborist h2{max-width:24ch;margin-inline:auto}
#arborist .lede{margin-inline:auto}
#arborist p{max-width:64ch;margin-inline:auto}
#arborist .actions{justify-content:center}
#arborist .plate{max-width:880px;margin-inline:auto}
#arborist .cred{background:#FFFFFF;border-radius:16px;box-shadow:var(--sh-2);
  border:1px solid var(--sand-2);padding:clamp(1.25rem,3vw,1.75rem);
  max-width:660px;margin:2rem auto 0;text-align:left}
#arborist .cred__row dt{color:var(--gold-ink)}
#arborist .cred__row dd{color:var(--ink)}
#arborist .cred__row dd b{color:var(--ink)}
#arborist .cred__pending{color:var(--ink-2)}
#arborist .cred__foot{color:var(--ink-2)}
#arborist .cred a{color:var(--forest);text-decoration:underline}

/* Contrast fixes on the dark arborist band. */
.plate--dark figcaption{color:#D8E2CF}
.plate--dark figcaption b{color:var(--gold-lit)}
#arborist .cred__foot,.band--forest .cred__foot{color:#D8E2CF}

/* --------------------------------------------------------------------------
   CONVERSION HERO — uniform first paint on every page (Matt, 2026-07-28):
   review badge top-center, copy left, quote form right, recent Google
   review under the CTAs. Northside-pattern lead capture, zero friction.
   -------------------------------------------------------------------------- */
.hero .wrap.hero__grid{display:grid;grid-template-columns:minmax(0,1fr);
  gap:1.5rem;max-width:1180px;text-align:center;
  padding:clamp(2.5rem,5vw,4rem) 1.25rem clamp(2.75rem,5vw,4.5rem)}
@media(min-width:960px){
  .hero .wrap.hero__grid{grid-template-columns:minmax(0,1.08fr) minmax(0,.92fr);
    gap:clamp(2rem,4vw,4rem);text-align:left;align-items:center}
  .hero__copy .hero__eyebrow,.hero__copy .actions{justify-content:flex-start}
  .hero__copy .hero__lede{margin-inline:0}
}
.revbadge{grid-column:1/-1;justify-self:center;display:flex;align-items:center;
  gap:.55rem;margin:0;color:#FFFFFF;font-weight:600;font-size:.975rem;
  background:rgba(10,28,17,.45);border:1px solid rgba(255,255,255,.22);
  border-radius:999px;padding:.45rem 1.1rem;backdrop-filter:blur(3px)}
.revbadge .stars{color:var(--gold);letter-spacing:.1em}
.revbadge b{font-family:var(--ff-display);font-size:1.15rem}
.hero__review{margin:1.75rem 0 0;padding:1rem 1.15rem;text-align:left;
  background:rgba(10,28,17,.42);border-left:3px solid var(--gold);
  border-radius:0 12px 12px 0;max-width:56ch}
.hero__review blockquote{margin:0;font-size:.9375rem;line-height:1.55;color:#EDF2E6}
.hero__review figcaption{margin-top:.55rem;font-size:.8125rem;font-weight:600;
  color:#D8E2CF;display:flex;align-items:center;gap:.5rem}
.hero__review .stars{color:var(--gold);font-size:.8125rem;letter-spacing:.08em}
@media(max-width:959px){.hero__review{margin-inline:auto}}
.hero__form{background:#FFFFFF;border-radius:18px;box-shadow:0 24px 60px rgba(9,22,14,.35);
  border:0;padding:clamp(1.35rem,2.6vw,1.9rem);text-align:left}
.hero__form h3{color:var(--forest-2);font-size:1.45rem;margin:0 0 .2rem}
.hero__form-sub{font-size:.9rem;color:var(--ink-2);margin:0 0 1.1rem}
.hero__form .field{margin-bottom: .85rem}
.hero__form .btn{width:100%;margin-top:.35rem}
.hero__form-alt{font-size:.85rem;color:var(--ink-2);text-align:center;margin:.85rem 0 0}
.hero__form-alt a{color:var(--forest);font-weight:700}

/* Logo: larger, slight overhang past the header bar. */
.mast{z-index:100}
.lockup__badge{height:78px;margin-bottom:-20px;position:relative;z-index:31;
  filter:drop-shadow(0 3px 8px rgba(27,58,36,.25))}
@media(max-width:640px){.lockup__badge{height:58px;margin-bottom:-12px}}

/* Footer logo: bigger. */
.foot__lockup img{height:96px;width:auto}

/* --------------------------------------------------------------------------
   REVIEWS MODULE — replaces the tally wall. Live numbers from ONE source
   (data-hp-rating / data-hp-reviews spans, fed by the mu-plugin option),
   three verbatim Google reviews, everything pointed at calls + estimates.
   -------------------------------------------------------------------------- */
#reviews{text-align:center}
#reviews .eyebrow{margin-inline:auto}
.revs__title{max-width:22ch;margin-inline:auto}
.revs__summary{display:flex;align-items:center;justify-content:center;
  gap:1.1rem;margin:1.75rem auto .5rem}
.revs__score{font-family:var(--ff-display);font-size:clamp(3.4rem,7vw,5rem);
  line-height:1;color:var(--forest-2);margin:0}
.revs__sumtext{text-align:left}
.revs__stars{color:var(--gold);font-size:1.4rem;letter-spacing:.12em;margin:0 0 .2rem}
.revs__count{margin:0;color:var(--ink-2);font-size:.95rem}
.revs__count b{color:var(--ink)}
.revs__grid{display:grid;gap:1.25rem;margin:2rem 0 0;
  grid-template-columns:repeat(auto-fit,minmax(min(100%,300px),1fr))}
.revs__card{margin:0;background:#FFFFFF;border:1px solid var(--sand-2);
  border-radius:16px;box-shadow:var(--sh-1);padding:1.4rem 1.5rem;
  text-align:left;display:flex;flex-direction:column;gap:.7rem}
.revs__cardstars{color:var(--gold);letter-spacing:.1em;margin:0;font-size:.95rem}
.revs__card blockquote{margin:0;font-size:.9375rem;line-height:1.6;color:var(--ink);flex:1}
.revs__card figcaption{font-size:.85rem;color:var(--ink-2)}
.revs__card figcaption b{color:var(--ink)}
.revs__policy{margin:1.75rem auto .25rem;max-width:60ch;font-size:.9rem;color:var(--ink-2)}
.revs__policy a{color:var(--forest);font-weight:700}
.revs__actions{justify-content:center;margin-top:1.25rem}

/* Contrast fix: serif h2/h3 went global forest-green — the dark photo band
   (.place) needs its light text back. */
.place h2{color:#FFFFFF}
.place h3{color:#FFFFFF}
.place .lede{color:#E4EDE0}

/* City, state and zip never split across lines; addresses break as
   street / city-state-zip rows (standing rule, Matt 2026-07-28). */
.u-nowrap{white-space:nowrap}

/* No orphan words: headings balance their lines, prose avoids single-word
   last lines (standing rule, Matt 2026-07-28). Headings are ALSO glued at
   build time with &nbsp; so the rule holds on every browser. */
h1,h2,h3{text-wrap:balance}
p,li,.lede,figcaption,blockquote{text-wrap:pretty}

/* Badge carries Licensed & insured — allow a graceful two-line wrap on phones. */
.revbadge{flex-wrap:wrap;justify-content:center;text-align:center;max-width:92%}

/* Phone numbers and tel links never wrap (standing rule, Matt 2026-07-28). */
a[href^="tel:"],a[href^="sms:"]{white-space:nowrap}

/* Tables (permit comparison / fee schedules) — clean, scrollable on phones. */
.tablewrap{overflow-x:auto;margin:1.5rem 0;-webkit-overflow-scrolling:touch}
.mdtable{border-collapse:collapse;width:100%;font-size:.9375rem;background:#FFFFFF;
  border:1px solid var(--sand-2);border-radius:12px;overflow:hidden}
.mdtable th{background:var(--forest-2);color:#FFFFFF;text-align:left;
  padding:.65rem .8rem;font-weight:700;font-size:.85rem}
.mdtable td{padding:.6rem .8rem;border-top:1px solid var(--sand-2);
  color:var(--ink);vertical-align:top}
.mdtable tr:nth-child(even) td{background:var(--paper)}
.band--forest .mdtable,.band--night .mdtable{border-color:rgba(255,255,255,.2)}

/* Client 2026-07-28 night: remove the small gold separator rules — the
   horizontal ticks above trust-bar items, the ledger top rule, the gold
   column rules, and any vertical hairline separators. */
.proof li::before{display:none}
.proof li{padding-top:0}
.ledger{border-top:0;padding-top:var(--s4)}
.hr-gold{display:none}
.band--forest .grid--3>div{border-top:0!important}
.reason{border-top:0!important}
.revs__summary{border:0}
.proof li:not(:last-child)::after{content:none;width:0}

/* Client 2026-07-29: remove ALL remaining colored accent lines (gold + red),
   horizontal and vertical. Callouts become soft filled cards instead. */
.note,.note--ember,.note--forest{border-left:0;border-radius:14px}
.note--ember{background:#F6E7DF}
.hero__review{border-left:0;border-radius:12px}
.callout{border-left:0;border-radius:12px}
.proof{border-bottom:0}

/* Final two accent lines (client, 2026-07-29): the crewnote top rule and
   the kicker's left bar. */
.crewnote{border-top:0;padding-top:var(--s4)}
.kicker{border-left:0;padding-left:0}

/* Contact-ways cards (Call / Text a photo / Form), 2026-07-29. */
.cway{background:#FFFFFF;border:1px solid var(--sand-2);border-radius:16px;
  box-shadow:var(--sh-1);padding:1.5rem 1.5rem 1.4rem;display:flex;
  flex-direction:column;text-align:left}
.cway h3{color:var(--forest-2);margin-bottom:.3rem}
.cway p{flex:1;font-size:.9375rem;color:var(--ink-2);margin-bottom:1rem}
.cway .btn{width:100%;text-align:center}
.band--forest .cway h3,.band--night .cway h3{color:var(--forest-2)}

/* Single-column bands: when a heading drops to a second line it must stay
   CENTERED with the band, not hang off the left edge; the note callout sits
   on the same column as everything else. Two-column bands (.grid) untouched. */
.band>.wrap>h2,.band>.wrap>.eyebrow,.band>.wrap>.lede,.band>.wrap>p{
  text-align:center}
.band>.wrap>.eyebrow{display:table;margin-inline:auto}
.band>.wrap>.note{max-width:var(--col);margin-inline:auto}
.band>.wrap>.actions{justify-content:center}

/* Contact-ways: stacked rows, not three-across (Matt 07-29). Text left,
   button right, one centered column. */
.cways{display:flex;flex-direction:column;gap:.9rem;max-width:720px;
  margin-left:auto;margin-right:auto}
.cways .cway{display:grid;grid-template-columns:1fr auto;column-gap:1.75rem;
  align-items:center;padding:1.25rem 1.5rem}
.cways .cway h3{grid-column:1;margin:0 0 .2rem;text-align:left}
.cways .cway p{grid-column:1;margin:0;text-align:left}
.cways .cway .btn{grid-column:2;grid-row:1/3;width:auto;white-space:nowrap}
@media(max-width:640px){
  .cways .cway{grid-template-columns:1fr}
  .cways .cway h3,.cways .cway p{text-align:center}
  .cways .cway .btn{grid-column:1;grid-row:auto;width:100%;margin-top:.9rem}
}

/* Long hero headlines: one size down so "in City, FL" never strands a word. */
.hero h1.h1--long{font-size:clamp(1.9rem,2.4vw,2.9rem)}
@media(max-width:640px){.hero h1.h1--long{font-size:clamp(1.65rem,6.6vw,1.95rem)}}

/* Crew note (homepage): centered with the band like everything else, no
   left-hugging column with dead space beside it (Matt 07-29). */
.crewnote{max-width:var(--col);margin-inline:auto;text-align:center}
.crewnote .eyebrow{display:table;margin-inline:auto}
.crewnote>p:not(.eyebrow):not(.kicker){margin-inline:auto}
.crewnote .kicker{max-width:24ch;margin-inline:auto}
/* Standalone note callouts center on the column too (thank-you page). */
.band>.wrap>.note{max-width:var(--col);margin-inline:auto}

/* WSW-DEFGRID-START — 2026-07-30 -------------------------------------------
   The definition-card grid (the `.reason` cells) had four spacing defects, all
   MEASURED on /meet-our-isa-certified-arborist/ at 1440 after Matt flagged the
   section, and all present on every one of the 46 reason grids across 41 pages:

     1. an odd item count left a HOLE in the last row — 5 cells in 3 columns
        measured rowLayout [3, 2], so the section read lopsided;
     2. the section's closing paragraph began at EXACTLY the grid's bottom edge
        (measured gap-to-grid 0px, margin-top 0px), so it attached itself to the
        last column instead of reading as the section's outro;
     3. one-line vs two-line card headings pushed one column's body copy 35px
        lower than its neighbours (measured h3 heights 70px vs 35px, paragraph
        tops 2216 vs 2181);
     4. 24px between grid rows against a generous space above the H2 — cramped
        in the middle of the section, roomy at the top.

   Fixed on the COMPONENT so every page that renders the pattern gets it, not on
   one URL. Scoped to `.grid--reasons` (emitted by mdconv._list_html) with a
   `:has(> .reason)` twin so a page built before that class existed is fixed too.
   Deliberately narrow: no card, plate, service or review grid is touched.
   Reversion = delete this marked block.
   -------------------------------------------------------------------------- */

/* 1 + 4. Flex instead of grid, so an incomplete last row CENTRES rather than
   leaving a hole. The flex-basis at each breakpoint reproduces the column count
   the grid rules already used (1 below 720, 2 from 720, 3 from 980 for --3), so
   a FULL row is pixel-identical to before; only the orphan row changes. */
.grid--reasons,
.grid:has(> .reason){
  display:flex;
  flex-wrap:wrap;
  justify-content:center;
  column-gap:var(--s5);
  row-gap:var(--s5);
}
.grid--reasons > .reason,
.grid:has(> .reason) > .reason{
  flex:0 1 100%;
  min-width:0;
}
@media (min-width:720px){
  .grid--reasons,
  .grid:has(> .reason){ row-gap:var(--s6); }          /* 2rem, was 1.5rem */
  .grid--reasons > .reason,
  .grid:has(> .reason) > .reason{
    flex-basis:calc((100% - var(--s5)) / 2);
  }
}
@media (min-width:980px){
  .grid--3.grid--reasons > .reason,
  .grid--3:has(> .reason) > .reason{
    flex-basis:calc((100% - 2 * var(--s5)) / 3);
  }
}

/* 3a. THE ROOT CAUSE of the "spacing looks really bad" read: the card heading
   was rendering at 29.6px in a 304px column (measured at 1440), i.e. about ten
   characters per line, so a four-word label wrapped to two or three lines and
   the body copy started at a different height in every column. A definition
   card wants a LABEL, not a near-H2. Scale it to the card instead of to the
   viewport. Untouched everywhere else on the site — `.reason` headings inside a
   reasons grid only. */
.grid--reasons > .reason > h3,
.grid:has(> .reason) > .reason > h3{
  font-size:clamp(1.0625rem,1.3vw,1.3125rem);
  line-height:1.28;
  letter-spacing:-.005em;
}

/* 3b. Reserve two lines of heading space at the widths where a heading can wrap,
   so the body copy starts on the same line in every card of a row. `2lh` is the
   exact expression; the em value is the fallback for anything that predates it
   (h3 line-height here computes to ~1.18, so two lines ~= 2.36em). Below 720px
   the cards are one per row and there is nothing to align, so no reserve. */
/* EXPERIMENT (kept, measured): with 3a in place almost every card heading now
   fits ONE line, so a blanket two-line reserve added a blank line to every card
   — dead space, which is the thing being fixed. Reserve dropped; the sweep is
   what decides. Restore the block below if defgrid-sweep ever reports a row with
   body copy at different heights.
@media (min-width:720px){
  .grid--reasons > .reason > h3,
  .grid:has(> .reason) > .reason > h3{ min-height:2.36em; min-height:2lh; }
} */

/* 2. The section outro is its own centred block, separated from the grid by at
   least the grid's own row gap. `.band > .wrap > p` already centres the text and
   caps it at 660px; what was missing was the space and the auto margins. */
.grid--reasons + p,
.grid--reasons + ul,
.grid--reasons + ol,
.grid--reasons + .note,
.grid--reasons + .linklist,
.grid:has(> .reason) + p,
.grid:has(> .reason) + ul,
.grid:has(> .reason) + ol,
.grid:has(> .reason) + .note,
.grid:has(> .reason) + .linklist{
  margin-top:var(--s6);
  margin-inline:auto;
}
@media (min-width:980px){
  .grid--reasons + p,
  .grid:has(> .reason) + p{ margin-top:var(--s7); }   /* 3rem, matches the top */
}
/* 3c. THE PART 3a DID NOT FIX (measured, not guessed). After 3a shipped at 01:59
   the sweep over all 41 pages x 4 widths still reported 25 rows whose body copy
   started at different heights: shrinking the heading made MOST fit one line, it
   did not make ALL of them fit (e.g. /tree-replacement/ at 768 has four two-line
   headings and one one-line heading in the same grid, so one card's paragraph sat
   22px high). A blanket two-line reserve was tried and rejected — it puts a blank
   line in every single-line card, which is the same dead space being fixed.

   The correct primitive is SUBGRID: the card's own rows ARE the grid's rows, so
   every heading in a row shares one track sized to the tallest heading in THAT
   row, and every paragraph starts at the next track. Perfect per-row alignment
   with zero reserved dead space.

   Two details worth knowing:
     * 12 columns, cards spanning 6 (2-up) or 4 (3-up). The maths is identical to
       2 / 3 equal columns — span*c + (span-1)*gap reduces to (100% - (n-1)*gap)/n
       — so card widths are UNCHANGED, and it makes an odd last row centrable in
       whole columns (a 6-column grid cannot centre one card of three).
     * a subgrid inherits the parent's row-gap BETWEEN THE CARD'S OWN ROWS too, so
       the paragraph gets a negative top margin of exactly one row-gap to put it
       back under its heading (the heading's own .4rem margin is the intra-card
       spacing). Net row rhythm between card rows is unchanged.
   Wrapped in @supports so anything without subgrid (Safari < 16) keeps the flex
   layout above, which is correct, just not row-aligned. */
@supports (grid-template-rows:subgrid){
  @media (min-width:720px){
    .grid--reasons,
    .grid:has(> .reason){
      display:grid;
      grid-template-columns:repeat(12,minmax(0,1fr));
      align-items:stretch;
    }
    .grid--reasons > .reason,
    .grid:has(> .reason) > .reason{
      flex-basis:auto;                 /* the flex fallback value, now inert */
      grid-column-end:span 6;      /* END, not the shorthand: `grid-column:span 6`
                                      sets START to `span 6`, so a later
                                      grid-column-start:N wipes the span and the
                                      card collapses to one 12th of a column.
                                      Measured that exact collapse (58px cards). */
      grid-row:span 2;
      display:grid;
      grid-template-rows:subgrid;
    }
    .grid--reasons > .reason > p,
    .grid:has(> .reason) > .reason > p{
      margin-block-start:calc(var(--s6) * -1);
    }
    /* 2-up: a lone last card centres instead of hanging on the left. */
    .grid--reasons > .reason:last-child:nth-child(2n+1),
    .grid:has(> .reason) > .reason:last-child:nth-child(2n+1){
      grid-column-start:4;
    }
  }
  @media (min-width:980px){
    .grid--3.grid--reasons > .reason,
    .grid--3:has(> .reason) > .reason{ grid-column-end:span 4; }
    /* reset the 2-up centring first, then apply the 3-up cases. */
    .grid--3.grid--reasons > .reason:last-child:nth-child(2n+1),
    .grid--3:has(> .reason) > .reason:last-child:nth-child(2n+1){ grid-column-start:auto; }
    .grid--3.grid--reasons > .reason:last-child:nth-child(3n+1),
    .grid--3:has(> .reason) > .reason:last-child:nth-child(3n+1){ grid-column-start:5; }
    .grid--3.grid--reasons > .reason:nth-last-child(2):nth-child(3n+1),
    .grid--3:has(> .reason) > .reason:nth-last-child(2):nth-child(3n+1){ grid-column-start:3; }
  }
}

/* WSW-DEFGRID-END ---------------------------------------------------------- */

/* WSW-MASTHEAD-START — 2026-07-30 ------------------------------------------
   Matt: "make the logo bigger header and footer and move the header logo to the
   left more to properly space out the menu items."

   Measured before: the masthead shared the 1040px content `.wrap`, so at 1440
   the badge started 240px in from the viewport edge and the five nav items had
   only 34px between them with 20px of slack left before the call block. The
   badge was 78px tall (footer 96px).

   Three moves, in order:
     1. the masthead gets its OWN wider container (the content column is
        untouched) so the badge sits near the viewport edge and ~300px of width
        is handed back to the nav;
     2. the badge grows in both header and footer, with the hanging overlap
        scaled so the mast's own height does not jump;
     3. the reclaimed room goes into the nav gap, fluid so the one-line nav
        survives all the way down to the 1025px hamburger threshold (swept in
        32px steps from 1024 to 1440, asserting one line + no overlap).
   Reversion = delete this marked block.
   -------------------------------------------------------------------------- */
@media (min-width:1025px){
  /* 1. header-only container. Content `.wrap` keeps --max; this is the mast. */
  .mast > .wrap{
    max-width:min(1360px, 100% - 3rem);
    padding-inline:clamp(1rem, 2.2vw, 2.5rem);
    gap:clamp(1rem, 2vw, 2.25rem);
  }
  /* 2. bigger badge, overlap scaled with it so mast height is unchanged. */
  .mast .lockup__badge{
    height:clamp(84px, 7.2vw, 106px);
    margin-bottom:clamp(-30px, -2.1vw, -22px);
  }
  /* 3. the nav takes the reclaimed width and spaces evenly. */
  .mast .nav{
    flex:1 1 auto;
    justify-content:center;
    gap:clamp(1.6rem, 3.2vw, 3.25rem);
  }
  .mast .nav > a,
  .mast .nav > .has-sub > a{ white-space:nowrap; }
  .mast__cta{ flex:0 0 auto; }
}

/* Footer badge, every width. It is the same oval decal and it was the smallest
   thing in a light footer that has room for it. */
.foot__badge,
.foot__lockup img{
  height:clamp(104px, 9.5vw, 136px);
}

/* 4. STANDING RULE on every WSW site: a dropdown gets a hover BRIDGE and a
   ~0.35s CLOSE DELAY. The bridge was already here (.has-sub::after, 14px) and a
   real-pointer test proved it survives the gap — but only `visibility` carried
   the 0.35s delay, while `opacity` began fading the instant the pointer left, so
   the panel had visually gone in 160ms. Measured: opacity was under 0.5 just
   120ms after leaving. Widening the nav gap makes the pointer travel further, so
   this matters more now, not less. Opening stays instant. */
.nav .sub{
  transition:opacity .16s ease .3s, transform .16s ease .3s, visibility 0s linear .46s;
}
.nav .has-sub:hover .sub,
.nav .has-sub:focus-within .sub{
  transition:opacity .14s ease 0s, transform .14s ease 0s, visibility 0s linear 0s;
}

/* WSW-MASTHEAD-END --------------------------------------------------------- */

/* WSW-AREANAV-START — 2026-07-30 ------------------------------------------
   "Service Areas" became a two-level menu: All Pinellas / North County /
   South County, each half opening a flyout of its real city pages. The point is
   SEO — 18 city pages now get a crawlable header link from every page on the
   site — so the menu is markup + CSS with zero JavaScript, and it has to behave
   for a pointer, a keyboard and a thumb.

   Four things this block is careful about:
     1. the DIAGONAL pointer path. A nested flyout dies if the only bridge is
        vertical: the pointer leaves the parent row on its way to the panel and
        the row un-hovers. `.has-sub2::after` is a full-height strip in the gap to
        the right of the row, so hover is never dropped mid-travel.
     2. the SAME hover-intent contract as the top level: opening is instant,
        closing waits ~0.35s (opacity AND transform carry the delay — only
        `visibility` did once, and the panel visually vanished in 160ms).
     3. staying INSIDE the viewport. The flyout normally opens right; when the
        parent panel is close to the right edge there is a right-anchored variant,
        and both are swept for `right <= clientWidth` at every width.
     4. the parent row must not look like a dead end: it keeps a caret.
   Reversion = delete this marked block (the markup degrades to a plain list of
   three links with the towns nested under them, still navigable).
   -------------------------------------------------------------------------- */
@media (min-width:900px){
  /* Level 2 rows: label left, caret right. */
  .nav .sub--areas .has-sub2{position:relative}
  .nav .sub--areas .has-sub2 > a{display:flex;align-items:center;justify-content:space-between;gap:1rem}
  .nav .sub--areas .has-sub2 > a::after{
    content:"";width:.42em;height:.42em;flex:0 0 auto;
    border-right:2px solid currentColor;border-top:2px solid currentColor;
    transform:rotate(45deg);opacity:.55;
  }
  .nav .sub--areas .has-sub2:hover > a::after,
  .nav .sub--areas .has-sub2:focus-within > a::after{opacity:1}
  .nav .sub--areas .has-sub2:hover > a,
  .nav .sub--areas .has-sub2:focus-within > a{background:var(--paper-2)}

  /* 1. the diagonal bridge: a full-height invisible strip in the 14px gap. */
  .nav .sub--areas .has-sub2::after{
    content:"";position:absolute;left:100%;top:-.5rem;bottom:-.5rem;width:16px;
  }

  .nav .sub2{
    position:absolute;left:calc(100% + 14px);top:-.55rem;min-width:13.5rem;
    background:var(--paper);border:1px solid var(--sand);border-radius:12px;
    box-shadow:0 14px 34px rgba(28,23,16,.16);
    padding:.5rem;margin:0;list-style:none;z-index:3;
    opacity:0;visibility:hidden;transform:translateX(-4px);
    /* 2. the hover-intent contract, tuned by measurement (see the open delay
       below): closing waits .38s, which is longer than the level-1 panel's .3s
       because a pointer travelling to a level-2 flyout has to cross the sibling
       row to get there, and the panel it is heading for must not even begin to
       fade during that crossing. */
    transition:opacity .16s ease .38s, transform .16s ease .38s, visibility 0s linear .54s;
  }
  /* OPEN DELAY, 120ms — the other half of hover intent, and the fix for a real
     defect the sweep caught: travelling diagonally from "North County" toward an
     item low in its flyout crosses the "South County" row, and with an instant
     open that flash-opened South on top of North mid-journey. MEASURED: at 900px
     the crossing takes ~120-150ms (the panel is narrowest there and the diagonal
     clips three sibling rows), and a 120ms delay let South ghost up to 0.32
     opacity. 180ms is over the crossing and under the dwell of someone who means
     it — swept at 900/960/1024/1180/1440/1920, sibling-max 0.00 at every one. The 0.3s CLOSE delay on the panel being left means North stays up
     for the whole crossing, so the pointer lands on live links. Level 1 keeps
     opening instantly — it is the first thing a pointer touches. */
  .nav .sub--areas .has-sub2:hover > .sub2,
  .nav .sub--areas .has-sub2:focus-within > .sub2{
    opacity:1;visibility:visible;transform:none;
    transition:opacity .14s ease .18s, transform .14s ease .18s, visibility 0s linear .18s;
  }
  /* Keyboard: a Tab into the row must not wait. focus-within is not a pointer. */
  .nav .sub--areas .has-sub2:focus-within > .sub2{
    transition:opacity .1s ease 0s, transform .1s ease 0s, visibility 0s linear 0s;
  }
  .nav .sub2 li{margin:0}
  .nav .sub2 a{display:block;padding:.5rem .7rem;border-bottom:0;font-weight:500;white-space:nowrap}
  .nav .sub2 a:hover{background:var(--paper-2);border-bottom:0}

  /* 3. right-anchored variant for a narrow desktop window, where a right-opening
        flyout would run past the viewport edge. Applied by hand, per measurement:
        the sweep below reported the right-opening flyout ending well inside the
        viewport at every width from 900 up, and a LEFT-opening flyout at 1024
        would have run off the LEFT edge (the panel starts ~184px in and the
        flyout is ~216px wide), so the automatic flip that "felt safe" was
        measured to be the bug and was removed. */
  .nav .sub--areas.sub--flipleft .sub2{left:auto;right:calc(100% + 14px);transform:translateX(4px)}
  .nav .sub--areas.sub--flipleft .has-sub2::after{left:auto;right:100%}
  }
}

/* MOBILE / TOUCH: the same two halves as a nested accordion inside the burger.
   A 48px minimum on every row (Apple's HIG floor is 44, Material's is 48; use
   the larger), and the summary marker is drawn, not a native triangle. */
.menu__panel .acc{border-bottom:1px solid var(--sand-2)}
.menu__panel .acc > summary{
  display:flex;align-items:center;justify-content:space-between;gap:1rem;
  min-height:48px;padding:.55rem 0;font-weight:600;font-family:var(--ff-ui);
  cursor:pointer;list-style:none;
}
.menu__panel .acc > summary::-webkit-details-marker{display:none}
.menu__panel .acc > summary::after{
  content:"";width:.5em;height:.5em;flex:0 0 auto;
  border-right:2px solid currentColor;border-bottom:2px solid currentColor;
  transform:rotate(45deg) translateY(-.1em);opacity:.6;transition:transform .18s ease;
}
.menu__panel .acc[open] > summary::after{transform:rotate(-135deg) translateY(-.1em)}
.menu__panel .acc > ul{margin:.15rem 0 .6rem;padding-left:.9rem}
.menu__panel .acc > ul > li{border-bottom:0}
.menu__panel .acc > ul > li > a{
  display:flex;align-items:center;min-height:48px;padding:.35rem 0;font-weight:500;
}
/* WSW-AREANAV-END ---------------------------------------------------------- */
