/* =============================================================
   BlueOak Outdoor — site.css
   The single stylesheet for all 13 pages (Phase 2, D-01).
   Reconciles three prior CSS generations (index.html / the 11
   byte-identical subpages / contact.html) onto index.html's terms.

   TYPE SCALE (D-02) — fluid clamp() per step, no media queries
   used for font-size anywhere in this sheet. Floor rule: nothing
   in this sheet resolves below 14px; body copy and form controls
   never resolve below 16px.

     --step--1   14px  -> 15px   fine print, kickers, chips
     --step-0    16px  -> 17px   body copy
     --step-1    18px  -> 20px   secondary headings (e.g. .path h3)
     --step-2    21px  -> 24px   .ctaband h3
     --step-3  24.8px  -> 32px   h2.title
     --step-4  33.6px  -> 53.6px .hero h1

   SECTION ORDER — the cascade is a stated decision, not an
   artefact of merge order:
     1. tokens
     2. reset
     3. base typography
     4. layout containers
     5. chrome (topbar, nav, sticky bar, footer)
     6. hero and pagehero
     7. components
     8. forms
     9. utilities
     10. print
   ============================================================= */

/* ---------- 1. tokens ---------- */
:root{
  /* pre-existing tokens, carried forward unchanged */
  --blue:#0B1D34;--green:#4C6B2A;--ink:#1c2430;--muted:#5b6673;--bg:#ffffff;--soft:#f3f6f9;--mint:#eef4e6;--line:#e2e8ee;
  --font-body:"DM Sans",system-ui,sans-serif;--font-display:Oswald,Impact,sans-serif;
  --danger:#8a2b2b;--danger-on-dark:#ffc9c9;

  /* new tokens (D-05) — every literal colour used more than once
     across the three prior generations, named */
  --white:#fff;
  --green-on-dark:#a9c780;
  --ink-on-dark:#c3cedb;
  /* KNOWN WARNING — unreferenced, retained deliberately (03-06, per the
     Phase 2 no-delete-on-unused precedent). Do not use for text on dark:
     it computes to ~4.09:1 on the .85 navy pill, below the 4.5:1 AA floor,
     which is why .hero .fine was moved off it. Reach for --ink-on-dark
     (~6.73:1) instead. Accepted 2026-08-17: low risk, revisit if reused. */
  --muted-on-dark:#8fa2b5;
  --soft-2:#eef3f8;
  --soft-3:#e7edf3;
  --line-dash:#cfd9e2;
  --line-hover:#cddae6;
  --mint-line:#d5e3c2;
  --danger-bg:#f8ecec;
  --star:#a8760a;
  --blue-rgb:11,29,52;

  /* additional channel-triple tokens, required to satisfy D-05's
     "no literal rgb channel triple outside :root" rule — the three
     prior generations used raw rgba(0,0,0,...) drop-shadows and
     rgba(138,43,43,...)/rgba(255,201,201,...) danger overlays that
     the Artifacts table's 12 named tokens don't individually cover */
  --black-rgb:0,0,0;
  --white-rgb:255,255,255;
  --danger-rgb:138,43,43;
  --danger-on-dark-rgb:255,201,201;

  /* type scale (D-02) */
  --step--1:clamp(0.875rem,0.83rem + 0.2vw,0.9375rem);
  --step-0:clamp(1rem,0.95rem + 0.25vw,1.0625rem);
  --step-1:clamp(1.125rem,1.05rem + 0.4vw,1.25rem);
  --step-2:clamp(1.3125rem,1.15rem + 0.8vw,1.5rem);
  --step-3:clamp(1.55rem,1.3rem + 1.2vw,2rem);
  --step-4:clamp(2.1rem,1.4rem + 3.5vw,3.35rem);

  /* spacing scale (Claude's Discretion) */
  --space-1:4px;--space-2:8px;--space-3:16px;--space-4:24px;--space-5:32px;--space-6:48px;
}

/* ---------- 2. reset ---------- */
*{margin:0;padding:0;box-sizing:border-box}

/* ---------- 3. base typography ---------- */
body{font-family:var(--font-body);color:var(--ink);font-size:var(--step-0);background:var(--bg);line-height:1.55}

/* Base link. Every other `a` rule in this sheet is component-scoped
   (.navlinks, footer, .svc-rail, .btn, .stickybar, .notebox's parent...), so a
   link in ordinary body copy matched no rule at all and fell through to the
   browser default: blue, purple once visited, no hover. That is what this
   closes. Every component rule out-specifies it, so none of them changes.
   Deliberately a base rule rather than one more component-scoped rule --
   scoping is what opened the gap, and prose added in later phases should
   inherit this instead of falling through it again.
   Underlined, not colour-only: --green against --ink is 2.5:1, below the 3:1
   WCAG 1.4.1 wants before colour alone may distinguish a link in text. */
a{color:var(--green);text-decoration:underline;text-underline-offset:.15em}
a:hover{color:var(--blue);text-decoration-thickness:2px}

/* ---------- 4. layout containers ---------- */
.container{max-width:1080px;margin:0 auto;padding:0 20px}
.center{text-align:center}
.center .sub{margin-left:auto;margin-right:auto}
section.block{padding:56px 0}

/* ---------- 5. chrome: topbar, nav, mobile menu, sticky bar, footer ---------- */
.topbar{background:var(--blue);color:var(--white);font-size:var(--step--1);padding:8px 0}
.topbar .container{display:flex;align-items:baseline;justify-content:space-between;gap:12px;flex-wrap:wrap}
.topbar a{color:var(--green-on-dark);font-weight:700;text-decoration:none;display:inline-block;padding:6px 2px;margin-block:-6px}
nav{border-bottom:1px solid var(--line);background:var(--white);position:sticky;top:0;z-index:5}
nav .container{display:flex;align-items:center;justify-content:space-between;padding-block:10px;gap:14px;flex-wrap:wrap}
.brand{display:flex;flex-direction:column;align-items:flex-start;text-decoration:none;gap:2px}
.logo{font-family:var(--font-display);font-size:clamp(1.64rem,1.4rem + 2.63vw,2.41rem);line-height:1.1;font-weight:700;color:var(--blue);letter-spacing:.06em;text-transform:uppercase;white-space:nowrap}
.logo b{color:var(--green)}
.dba{font-family:var(--font-body);font-size:var(--step--1);font-style:italic;font-weight:400;color:var(--blue);margin-left:3px;white-space:normal}
.navlinks{display:flex;align-items:center;gap:18px;font-size:var(--step--1);font-weight:600}
.navlinks a{color:var(--ink);text-decoration:none}
.navlinks a:hover{color:var(--green)}
/* Services dropdown (R-37, nav half). CSS only — no script, and never the
   only path to a service page: the parent "Services" link still navigates to
   /services, which is what a touch device gets when there is no hover, and
   what the mobile menu below 840px gets when .navlinks is hidden entirely.
   :focus-within is what makes it keyboard-reachable; without it the panel
   would be mouse-only. .hasmenu's padding-block/margin-block pair widens the
   hover target down to the panel's top edge without changing the nav's height,
   so the pointer never crosses dead space on the way down and the panel does
   not flicker shut. */
.navlinks .hasmenu{position:relative;display:flex;align-items:center;padding-block:12px;margin-block:-12px}
.navlinks .hasmenu>a::after{content:"";display:inline-block;width:.4em;height:.4em;margin-left:.4em;border-right:2px solid currentColor;border-bottom:2px solid currentColor;transform:translateY(-.15em) rotate(45deg)}
.subnav{position:absolute;left:0;top:100%;display:none;flex-direction:column;min-width:200px;padding:6px;background:var(--white);border:1px solid var(--line);border-radius:12px;box-shadow:0 12px 30px rgba(var(--blue-rgb),.16);z-index:30}
.navlinks .hasmenu:hover .subnav,.navlinks .hasmenu:focus-within .subnav{display:flex}
.subnav a{padding:10px 12px;color:var(--ink);text-decoration:none;font-weight:700;border-radius:8px;white-space:nowrap}
.subnav a:hover{background:var(--soft);color:var(--green)}
.navactions{display:flex;gap:10px;align-items:center}
.btn{display:inline-block;background:var(--green);color:var(--white);font-weight:800;padding:12px 22px;border-radius:8px;font-size:14.5px;text-decoration:none;white-space:nowrap}
.btn.navy{background:var(--blue)}
.btn.ghost{background:transparent;color:var(--blue);border:2px solid var(--blue);padding:10px 20px}
.btn.ghostlight{background:transparent;color:var(--white);border:2px solid var(--white)}
.btn:hover{filter:brightness(1.08)}
.btn:active{transform:translateY(1px)}
/* mobile menu (no JS) */
.menu{display:none;position:relative}
.menu summary{list-style:none;cursor:pointer;font-weight:800;font-size:var(--step--1);color:var(--blue);border:2px solid var(--blue);border-radius:8px;padding:9px 14px}
.menu summary::-webkit-details-marker{display:none}
.menupanel{position:absolute;right:0;top:calc(100% + 8px);background:var(--white);border:1px solid var(--line);border-radius:12px;box-shadow:0 12px 30px rgba(var(--blue-rgb),.16);min-width:210px;padding:6px;display:flex;flex-direction:column;z-index:30}
.menupanel a{padding:12px 14px;color:var(--ink);text-decoration:none;font-weight:700;font-size:15px;border-radius:8px}
.menupanel a:hover{background:var(--soft)}
.stickybar{display:none}
.stickybar a{flex:1;text-align:center;padding:15px 0;font-weight:800;font-size:15px;text-decoration:none}
.stickybar .call{background:var(--blue);color:var(--white)}
.stickybar .quote{background:var(--green);color:var(--white)}
footer{background:var(--blue);color:var(--ink-on-dark);padding:34px 0;font-size:var(--step--1);text-align:center}
footer a{color:var(--green-on-dark);font-weight:700;text-decoration:none}
.topbar a:hover,footer a:hover,.hiring a:hover{text-decoration:underline}

@supports (animation-timeline: scroll()) {
  nav .container{
    animation: nav-shrink linear both;
    animation-timeline: scroll(root block);
    animation-range: 0px 140px;
  }
  @keyframes nav-shrink{
    from{ padding-block:10px; }
    to{ padding-block:4px; }
  }
}

/* ---------- 6. hero and pagehero (D-03) ---------- */
.hero{position:relative;background:var(--blue);color:var(--white);padding:72px 0 68px;text-align:center;overflow:hidden}
.hero::before{content:"";position:absolute;inset:0;background-image:linear-gradient(rgba(var(--blue-rgb),.30),rgba(var(--blue-rgb),.50)),url('/img/mow-stripes-front-lawn.jpg');background-size:cover;background-position:center 62%}
.hero .container{position:relative;z-index:1}
.hero .tag{color:var(--green-on-dark);font-weight:800;font-size:var(--step--1);letter-spacing:2.5px;text-transform:uppercase}
.hero h1{font-family:var(--font-display);font-size:var(--step-4);font-weight:700;line-height:1.05;letter-spacing:.01em;text-transform:uppercase;margin:12px auto 14px;max-width:820px}
.hero p{color:var(--ink-on-dark);font-size:17px;max-width:560px;margin:0 auto 22px;line-height:1.5}
/* Headline scrim (R-33, D-08) — a dedicated panel behind .tag/h1/p so white
   text keeps a guaranteed contrast floor regardless of what pixel of the
   now much-lighter hero photograph sits behind it. Padding-driven, no fixed
   height/width, so a headline wrapping to three lines on a narrow phone
   grows the panel instead of overflowing it. */
.hero-scrim{display:inline-block;max-width:820px;margin:0 auto;padding:24px 28px;background:rgba(var(--blue-rgb),.85);border-radius:16px;box-shadow:0 10px 30px rgba(var(--black-rgb),.25)}
.hero-scrim .tag{margin-bottom:6px}
.hero-scrim h1{margin:12px 0 14px}
.hero-scrim p{margin:0 auto}
/* ink-on-dark: chosen for .hero .fine so both lines clear 4.5:1 AA (normal
   text at 14-15px) against the .85 pill composited over a worst-case
   near-white photo pixel — ink-on-dark computes to ~6.73:1 here, well above
   the floor, while the dimmer on-dark muted token previously in use landed
   at ~4.09:1 and failed it. The .fine a link colour was separately computed
   at ~5.70:1 against the same background and clears the floor unchanged. */
/* One box, two stacked lines. These were two separate inline-block pills of
   different widths, which read as a split box on desktop and as ragged steps on
   a phone. Radius drops 999px -> 16px because a multi-line block with a full
   pill radius bows at the corners; 16px matches .hero-scrim above it.
   The colours are unchanged and are load-bearing - see the --muted-on-dark note
   at the top of this file. Both lines still clear 4.5:1 AA composited over the
   lightest part of the photo, which check 1.7 asserts. */
.hero .fine{display:inline-block;max-width:560px;text-align:center;background:rgba(var(--blue-rgb),.85);border-radius:16px;padding:12px 18px;margin-top:14px;font-size:var(--step--1);color:var(--ink-on-dark)}
.hero .fine p{margin:0}
.hero .fine p + p{margin-top:6px}
.hero .fine a{color:var(--green-on-dark);font-weight:700;text-decoration:none}
.hero :focus-visible,.area :focus-visible,.path.com :focus-visible,footer :focus-visible,.ctaband :focus-visible{outline-color:var(--green-on-dark)}

/* .pagehero — subpage hero. D-03 originally kept every subpage a flat
   brand block because no honest photo existed. Reversed 2026-08-16 by
   owner decision: 10 subpages now carry a hero photograph. Seven are real
   BlueOak work; tree-care, snow-ice and christmas-lights are licensed
   stock stand-ins until Kim's photographer delivers, and are recorded in
   brand/placeholder-photo-provenance.md. thanks and 404 stay flat — they
   are utility pages, not service pages.
   Swapping a photo is one line in the pg-* block below plus the file. */
.pagehero{background:var(--blue);color:var(--white);padding:44px 0}
.pagehero h1{font-family:var(--font-display);letter-spacing:.02em;text-transform:uppercase;font-size:clamp(1.875rem,1.6rem + 2.5vw,2.125rem);font-weight:800;line-height:1.15;max-width:760px}
.pagehero p{color:var(--ink-on-dark);font-size:16px;max-width:640px;margin-top:10px}
.pagehero .crumb{color:var(--green-on-dark);font-weight:800;font-size:var(--step--1);letter-spacing:2px;text-transform:uppercase;margin-bottom:8px}
.pagehero.has-photo{position:relative;overflow:hidden}
.pagehero.has-photo::before{content:"";position:absolute;inset:0;background-image:linear-gradient(rgba(var(--blue-rgb),.70),rgba(var(--blue-rgb),.85)),var(--pagehero-photo, none);background-size:cover;background-position:center}
.pagehero.has-photo .container{position:relative;z-index:1}

/* Per-page hero photographs. Declared here, not inline on each page, so the
   one-stylesheet rule (R-21, D-01) still holds: a page carries a semantic
   class and never a style attribute. */
.pagehero.pg-about{--pagehero-photo:url('/img/hero-about.jpg')}
.pagehero.pg-services{--pagehero-photo:url('/img/hero-services.jpg')}
.pagehero.pg-lawn-care{--pagehero-photo:url('/img/hero-lawn-care.jpg')}
.pagehero.pg-mowing{--pagehero-photo:url('/img/mow-stripes-front-lawn.jpg')}
.pagehero.pg-cleanup{--pagehero-photo:url('/img/overgrowth-cleared.jpg')}
.pagehero.pg-trimming-pruning{--pagehero-photo:url('/img/hoa-monument.jpg')}
.pagehero.pg-landscaping{--pagehero-photo:url('/img/hero-landscaping.jpg')}
.pagehero.pg-tree-care{--pagehero-photo:url('/img/hero-tree-care.jpg')}
.pagehero.pg-snow-ice{--pagehero-photo:url('/img/hero-snow-ice.jpg')}
.pagehero.pg-christmas-lights{--pagehero-photo:url('/img/hero-christmas-lights.jpg')}
.pagehero.pg-commercial{--pagehero-photo:url('/img/hero-commercial.jpg')}
.pagehero.pg-careers{--pagehero-photo:url('/img/hero-careers.jpg')}
.pagehero.pg-contact{--pagehero-photo:url('/img/hero-contact.jpg')}
.pagehero.pg-our-work{--pagehero-photo:url('/img/mow-stripes-estate.jpg')}

/* ---------- 7. components ---------- */
.kicker{color:var(--green);font-weight:800;font-size:var(--step--1);letter-spacing:2px;text-transform:uppercase}
h2.title{font-family:var(--font-display);font-size:var(--step-3);color:var(--blue);margin:6px 0 10px;font-weight:700;letter-spacing:.02em;text-transform:uppercase}
.sub{color:var(--muted);margin-bottom:26px;font-size:15px;max-width:640px}

.strip{background:var(--mint);padding:14px 0;text-align:center;font-size:14.5px;font-weight:700;color:var(--green)}
.strip-doors{padding:12px 0 0;font-size:var(--step--1);font-weight:600;color:var(--blue)}
.strip-doors a{color:var(--green);font-weight:800;text-decoration:none}
.strip-doors a:hover{text-decoration:underline}

.grid3{display:grid;grid-template-columns:repeat(3,1fr);gap:16px}
.svc{background:var(--white);border:1px solid var(--line);border-radius:12px;padding:20px;text-align:center;position:relative;transition:box-shadow .18s ease,border-color .18s ease}
.svc:hover{box-shadow:0 6px 18px rgba(var(--blue-rgb),.09);border-color:var(--line-hover)}
.svc .ic{color:var(--green);margin-bottom:8px}
.svc h3{color:var(--blue);font-size:16px;margin-bottom:4px}
.svc p{font-size:var(--step--1);color:var(--muted);margin-bottom:8px}
.svc .more{font-size:var(--step--1);font-weight:800;color:var(--green);text-decoration:none}
.more:hover{text-decoration:underline}
.price{display:inline-block;background:var(--mint);color:var(--green);font-weight:800;font-size:var(--step--1);border-radius:999px;padding:4px 11px;margin-bottom:8px}
/* ── Home page surface sequence ────────────────────────────────────────────
   Read top to bottom, this is the page's vertical rhythm:

     hero IMAGE -> .strip MINT -> pricing SOFT -> paths WHITE -> facts SOFT
     -> reviews WHITE -> .area NAVY -> .services SOFT -> .work-strip WHITE
     -> .ctaband NAVY

   No two adjacent sections share a surface. Before 2026-08-21 four ran white
   in a row - 1,613px, 40% of a 4,039px page - and .services/.work-strip added
   another 968px of unbroken soft.

   Which section gets which surface is NOT free choice. DESIGN.md specifies the
   cards, and a card has to contrast with its field:
     .fact and .svc are white with a 1px line  -> tinted field
     .rev is soft with no border               -> white field
     .paths cards are mint and navy            -> self-contrasting, either field
   That constraint, not preference, fixes the order above. Moving one section's
   surface means checking its cards do not vanish. */
.block.center{background:var(--soft)}
.facts-section{background:var(--soft)}
.services{background:var(--soft)}

.steps{display:grid;grid-template-columns:repeat(3,1fr);gap:16px;max-width:900px;margin:20px auto 0}
.step{border:1px solid var(--line);border-radius:14px;padding:22px;text-align:center}
.step .num{width:34px;height:34px;border-radius:50%;background:var(--green);color:var(--white);font-weight:800;display:flex;align-items:center;justify-content:center;margin:0 auto 10px}
.step h3{color:var(--blue);font-size:15.5px;margin-bottom:6px}
.step p{font-size:var(--step--1);color:var(--muted)}

.paths{display:grid;grid-template-columns:1fr 1fr;gap:20px;margin-top:20px}
.path{border:1px solid var(--line);border-radius:16px;padding:28px}
.path.res{background:var(--mint);border-color:var(--mint-line)}
.path.com{background:var(--blue);color:var(--white)}
.path h3{font-size:var(--step-1);font-weight:800;margin-bottom:8px}
.path.res h3{color:var(--blue)}
.path p{font-size:14.5px;margin-bottom:16px}
.path.res p{color:var(--muted)}
.path.com p{color:var(--ink-on-dark)}
/* nowrap is right for every short button; the commercial label is not short,
   and unwrapped it gives this grid item a ~360px min-content width. */
.path .btn{white-space:normal}

.prow{display:grid;grid-template-columns:repeat(3,1fr);gap:16px;max-width:860px;margin:20px auto 0}
.pcard{border:1px solid var(--line);border-radius:14px;padding:24px;background:var(--white)}
.pcard.hot{border:2px solid var(--green);position:relative}
.pcard .flag{position:absolute;top:-11px;left:50%;transform:translateX(-50%);background:var(--green);color:var(--white);font-size:var(--step--1);font-weight:800;border-radius:999px;padding:3px 12px;letter-spacing:.5px}
.pcard h3{color:var(--blue);font-size:16px}
.pcard .money{font-size:30px;font-weight:800;color:var(--green);margin:8px 0 2px;font-family:var(--font-display);letter-spacing:.02em}
.pcard .per{font-size:var(--step--1);color:var(--muted)}
.pcard p{font-size:var(--step--1);color:var(--muted);margin-top:10px}

.path h3,.pcard h3,.step h3{font-family:var(--font-display);font-weight:700;letter-spacing:.02em;text-transform:uppercase}

.discount{background:var(--white);border-radius:14px;padding:16px 22px;text-align:center;margin:26px auto 0;max-width:860px;font-size:var(--step--1);color:var(--muted);line-height:1.55}
.discount b{color:var(--green)}
.dtag{background:var(--white);border:1px solid var(--line);border-radius:999px;padding:5px 12px;font-weight:700;font-size:var(--step--1);color:var(--blue)}

/* Proof facts (R-34, D-09/D-10/D-11) — three equal boxes, never data-driven.
   The third box is a peer, not a placeholder: it carries a true non-numeric
   statement until Kim supplies the real Google rating, review count and
   Business-profile URL. */
.facts{display:grid;grid-template-columns:repeat(3,1fr);gap:16px;max-width:900px;margin:20px auto 0}
.fact{background:var(--white);border:1px solid var(--line);border-radius:14px;padding:24px 20px;text-align:center}
.fact-num{font-family:var(--font-display);font-size:var(--step-3);font-weight:700;color:var(--blue);letter-spacing:.02em;text-transform:uppercase}
.fact-label{font-size:var(--step--1);color:var(--muted);margin-top:6px;font-weight:600}
.fact-pending{border-style:dashed;border-color:var(--line-dash)}
.fact-pending .fact-num{font-size:var(--step-1);color:var(--muted)}
.continuity{max-width:640px;margin:22px auto 0;font-size:15px;color:var(--muted);text-align:center}

/* white, not soft: this sits directly under .services, which is soft. The two
   ran together as 968px of one unbroken pale field with no boundary between
   "what we do" and "proof of the work". */
.work-strip{background:var(--white)}
.shots{display:grid;grid-template-columns:repeat(3,1fr);gap:12px;margin-top:20px}
/* .shot: aspect-ratio/placeholder-gradient carried from the
   pre-photography design, then overridden to the real-photo
   treatment (padding/border/overflow/background) — merged into one
   rule since both applied to the same selector unconditionally */
.shot{aspect-ratio:4/3;border-radius:12px;padding:0;border:none;overflow:hidden;background:var(--line);display:flex;align-items:center;justify-content:center;color:var(--muted);font-size:var(--step--1);font-weight:700}
.shot img{width:100%;height:100%;object-fit:cover;display:block}

.reviews{text-align:center}
.rev3{display:grid;grid-template-columns:repeat(3,1fr);gap:16px;text-align:left;margin-top:20px;align-items:start}
.rev{background:var(--soft);border-radius:12px;padding:18px;font-size:var(--step--1)}
.rev blockquote{font-style:normal}
.stars{color:var(--star);letter-spacing:2px;margin-bottom:6px}
.rev .who{margin-top:8px;font-weight:800;color:var(--blue);font-size:var(--step--1)}
.rev .who span{color:var(--muted);font-weight:600}
.revnote{margin-top:14px;font-size:var(--step--1);color:var(--muted)}

.area{background:var(--blue);color:var(--white)}
.area .title{color:var(--white)}
.area .sub{color:var(--ink-on-dark)}
.towns{display:flex;gap:10px;flex-wrap:wrap;justify-content:center;margin-top:8px}
.town{background:rgba(var(--white-rgb),.08);border:1px solid rgba(var(--white-rgb),.18);border-radius:999px;padding:6px 14px;font-size:var(--step--1);font-weight:700}

.price-proof{display:flex;flex-wrap:wrap;justify-content:center;gap:10px;margin:22px auto 0;max-width:720px}
.price-proof .chip{background:var(--mint);color:var(--green);font-weight:800;font-size:var(--step--1);border-radius:999px;padding:8px 14px}
.price-proof .chip b{font-family:var(--font-display);font-size:15px;letter-spacing:.02em}

.svc-rail{display:flex;flex-wrap:wrap;justify-content:center;gap:10px;margin-top:22px;max-width:900px;margin-left:auto;margin-right:auto}
.svc-rail a{display:inline-flex;align-items:center;gap:8px;padding:10px 16px;border:1px solid var(--line);border-radius:999px;background:var(--white);color:var(--blue);font-weight:800;font-size:var(--step--1);text-decoration:none;transition:border-color .15s ease,box-shadow .15s ease}
.svc-rail a:hover{border-color:var(--green);box-shadow:0 6px 18px rgba(var(--blue-rgb),.09)}
.svc-rail a span{color:var(--muted);font-weight:600;font-size:var(--step--1)}

.contact .wrap{display:grid;grid-template-columns:1fr 1fr;gap:36px;align-items:start;margin-top:20px}
.cinfo{font-size:15px}
.cinfo .bigphone{display:block;font-size:26px;font-weight:800;color:var(--green);text-decoration:none;margin:6px 0 2px}
.cinfo p{color:var(--muted);font-size:var(--step--1);margin-bottom:14px}

.hiring{background:var(--green);color:var(--white);padding:20px 0;text-align:center;font-size:15px}
.hiring b{margin-right:10px}
.hiring a{color:var(--white);font-weight:800;text-decoration:none}

.herorow{margin-top:16px;display:flex;gap:12px;justify-content:center;align-items:center;flex-wrap:wrap}

/* page-body components (subpages: about, services, lawn-care, ...) */
.body{padding:48px 0}
.body h2{font-size:24px;color:var(--blue);font-weight:800;margin:28px 0 8px}
.body h2:first-child{margin-top:0}
.body p{font-size:15.5px;color:var(--ink);max-width:720px;margin-bottom:12px}
.body ul{max-width:720px;margin:0 0 12px 20px;font-size:15px}
.body li{margin-bottom:6px}
.pricetable{width:100%;max-width:640px;border-collapse:collapse;margin:14px 0 22px}
.pricetable td{border:1px solid var(--line);padding:11px 14px;font-size:14.5px}
.pricetable td:last-child{font-weight:800;color:var(--green);white-space:nowrap}
.ctaband{background:var(--blue);color:var(--white);padding:40px 0;text-align:center}
.ctaband h3{font-size:var(--step-2);font-weight:800;margin-bottom:6px}
.ctaband p{color:var(--ink-on-dark);margin-bottom:18px}
.notebox{background:var(--mint);border-radius:12px;padding:16px 20px;max-width:720px;font-size:14.5px;margin:14px 0}
.icons4{display:grid;grid-template-columns:repeat(4,1fr);gap:14px;margin:18px 0;max-width:860px}
.icons4 div{background:var(--soft);border-radius:12px;padding:14px;text-align:center;font-weight:800;font-size:var(--step--1);color:var(--blue)}

/* Our Work page (R-32, D-05) — per-service section wrapper, reusing
   .shots/.shot verbatim from the homepage "From the field" grid. */
.ow-service{margin-bottom:40px}
.ow-service:last-of-type{margin-bottom:0}
.ow-service h2{font-family:var(--font-display);font-size:var(--step-2);color:var(--blue);font-weight:700;text-transform:uppercase;letter-spacing:.02em;margin-bottom:14px}

.ow-empty{border:2px dashed var(--line-dash);border-radius:12px;background:var(--soft);padding:32px 20px;text-align:center}
.ow-empty p{font-size:var(--step--1);color:var(--muted);max-width:480px;margin:0 auto}
.ow-empty-note{font-size:var(--step--1);color:var(--muted);max-width:640px}

.ow-video-slot{border:2px dashed var(--line-dash);border-radius:12px;background:var(--soft);
  max-width:720px;aspect-ratio:16/9;display:flex;flex-direction:column;align-items:center;
  justify-content:center;gap:8px;margin:0 auto}
.ow-video-ic{font-size:var(--step-3);color:var(--muted)}
.ow-video-slot p{font-size:var(--step--1);color:var(--muted)}

.ow-clients{max-width:860px}
.ow-clients .town{margin:4px}

/* About page crew placeholder grid (R-41, D-12) — dashed-circle slots
   that plainly read as placeholders; no names, no headcount claim. */
.crew-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:16px;max-width:720px;margin:24px 0 0}
.crew-slot{text-align:center}
.crew-avatar{aspect-ratio:1/1;border-radius:50%;border:2px dashed var(--line-dash);background:var(--soft);margin:0 auto 8px;max-width:140px}
.crew-slot p{font-size:var(--step--1);color:var(--muted);font-weight:600}

/* ---------- 8. forms ---------- */
/* margin-top: the scrim and this form sat flush at 0px, so the navy panel and
   the white card read as one shape with a seam. */
.zip-wrap{max-width:560px;margin:18px auto 0}
.zip{display:flex;flex-direction:column;width:100%;background:var(--white);border-radius:12px;padding:6px;gap:6px;box-shadow:0 10px 30px rgba(var(--black-rgb),.25)}
.zip-row{display:flex;gap:6px;align-items:stretch}
/* The field has to LOOK like a field. border:none on a white input sitting on
   .zip's white card gave it no boundary at all - only the placeholder hinted
   there was an input, and below 840px where .zip-row stacks, that invisible
   field read as an empty white panel above the button. Reported as a "weird
   ghost box" on 2026-08-21.
   The honeypot is unaffected: input.sr-only is equal specificity (0,1,1) and
   later in this file, so its border:0/padding:0/width:1px still win. */
.zip input{flex:1;border:1px solid var(--line);background:var(--soft);padding:14px 16px;font-size:16px;border-radius:8px;color:var(--ink);min-width:0;font-family:inherit;width:100%}
.zip input:focus{background:var(--white);border-color:var(--line-hover)}
.zip .btn{flex-shrink:0}
.zip button{border:none;cursor:pointer;font-family:inherit}

.cform{display:grid;grid-template-columns:1fr 1fr;gap:14px}
.cform input,.cform select,.cform textarea{border:1px solid var(--line);border-radius:8px;padding:12px 14px;font-size:16px;font-family:inherit;width:100%;background:var(--white);color:var(--ink)}
.cform textarea{min-height:90px;resize:vertical}
.field{display:flex;flex-direction:column;gap:5px;min-width:0}
.field label{font-size:var(--step--1);font-weight:700;color:var(--blue)}
.cform .full{grid-column:1/-1}
.cform button{grid-column:1/-1;border:none;cursor:pointer;font-family:inherit;text-align:center}
.prefill-hint{font-weight:600;color:var(--muted)}
/* Multi-select service picker (2026-08-17). Replaced a single <select>, which
   forced one answer out of people who routinely want three. Each box is a real
   checkbox with name="service", so the whole thing works with no JavaScript —
   the grid is presentation, not behaviour. :has() drives the selected state; a
   browser without it simply shows no highlight, which is a cosmetic loss and
   not a functional one. */
.svcpick{border:none;padding:0;margin:0;min-width:0}
.svcpick legend{padding:0;font-weight:700;font-size:var(--step--1);color:var(--ink)}
.svcpick-hint{font-weight:400;color:var(--muted)}
.svchead{display:block;font-weight:800;font-size:var(--step--1);letter-spacing:1px;text-transform:uppercase;color:var(--muted);margin:14px 0 6px}
.svcgrid{display:grid;grid-template-columns:1fr 1fr;gap:6px 12px}
.svcopt{display:flex;align-items:flex-start;gap:9px;padding:10px 12px;border:1px solid var(--line);border-radius:8px;background:var(--white);cursor:pointer;line-height:1.35;font-size:var(--step--1)}
.svcopt:hover{border-color:var(--line-hover);background:var(--soft)}
.cform .svcopt input[type="checkbox"]{width:auto;min-width:0;flex:none;margin:2px 0 0;padding:0;border:none;border-radius:0;accent-color:var(--green)}
.svcopt:has(input:checked){border-color:var(--green);background:var(--mint)}
.prefill-note{grid-column:1/-1;margin:0;font-weight:700;font-size:var(--step--1);color:var(--green)}
.formnote{font-size:var(--step--1);color:var(--muted);margin-top:-2px}

.form-status{display:block;width:100%;box-sizing:border-box;font-size:13.5px;font-weight:700;color:var(--blue);margin-top:12px;padding:10px 14px;border-radius:8px;background:var(--soft);text-align:center;line-height:1.4}
.form-status.is-error{color:var(--danger);background:var(--danger-bg)}
.form-offline-tip{font-size:var(--step--1);color:var(--muted);margin-top:10px}
.form-offline-tip a{color:var(--green);font-weight:800;text-decoration:none}
.hero .form-status{color:var(--white);background:rgba(var(--white-rgb),.1);border:1px solid rgba(var(--white-rgb),.22)}
.hero .form-status.is-error{color:var(--danger-on-dark);background:rgba(var(--danger-rgb),.35);border-color:rgba(var(--danger-on-dark-rgb),.45)}
.hero .form-offline-tip{color:var(--ink-on-dark);text-align:center}
.hero .form-offline-tip a{color:var(--green-on-dark)}
.cform .form-status{grid-column:1/-1}
.cform .form-offline-tip{grid-column:1/-1}

/* ---------- 9. utilities ---------- */
a,button,summary{transition:background-color .15s ease,color .15s ease,border-color .15s ease,box-shadow .15s ease,transform .15s ease}

/* Honour the OS setting. Added 2026-08-21 after the UI audit found real motion
   shipping with no guard at all: the scroll-driven nav-shrink above, this
   transform transition, and the card hover shadows. WCAG 2.3.3.
   Not `animation:none` — killing the nav-shrink keyframe outright would leave
   the header at whichever padding the animation last computed. Setting the
   duration to a hair and the iteration count to 1 lets it settle at its end
   state instantly, which is the same layout a non-supporting browser gets. */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
}
:focus-visible{outline:3px solid var(--green);outline-offset:2px;border-radius:4px}
.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}
/* .zip input and .cform input (0,1,1) out-specify .sr-only (0,1,0), so the
   honeypot was laid out at full width while absolutely positioned and dragged
   both form pages sideways. clip stops it painting, not its layout box.
   padding and border have to come off too: everything is border-box, so
   width:1px alone still leaves .zip input's 16px side padding standing the
   field up 32px wide. */
input.sr-only{width:1px;padding:0;border:0}
.skip{position:absolute;left:-9999px;top:0;background:var(--green);color:var(--white);padding:10px 16px;font-weight:800;z-index:60}
.skip:focus{left:8px;top:8px}
figure{margin:0}
figcaption{font-size:var(--step--1);color:var(--muted);margin-top:6px;text-align:center}

/* Responsive (D-02: never used for font-size — every text override
   above is expressed as a clamp() step instead). Each selector that
   also has a non-media rule above gets its own single-rule block;
   this keeps every override structurally distinct from its
   desktop-default counterpart. */
@media(max-width:840px){.grid3,.rev3,.prow,.paths,.steps,.contact .wrap,.shots,.facts{grid-template-columns:1fr}}
@media(max-width:840px){.navlinks{display:none}}
@media(max-width:840px){.navactions{display:none}}
@media(max-width:840px){.menu{display:block}}
@media(max-width:840px){.zip-row{flex-direction:column}}
@media(max-width:840px){.zip .btn{width:100%}}
@media(max-width:840px){.svc-rail a{flex:1 1 calc(50% - 10px);justify-content:center}}
@media(max-width:840px){.cform{grid-template-columns:1fr}}
@media(max-width:560px){.svcgrid{grid-template-columns:1fr}}
@media(max-width:840px){.icons4{grid-template-columns:1fr 1fr}}
@media(max-width:840px){.stickybar{display:flex;position:fixed;bottom:0;left:0;right:0;z-index:20;gap:1px;background:var(--line)}}
@media(max-width:840px){body{padding-bottom:58px}}
@media(max-width:840px){.crew-grid{grid-template-columns:repeat(2,1fr)}}

/* ---------- 10. print ---------- */
/* No print-specific overrides exist in any of the three prior
   generations. Declared here, last, so a future print stylesheet
   has a stated place in the cascade rather than landing wherever
   is convenient. */
