/* ==========================================================================
   Henderson's Landscape Services
   --------------------------------------------------------------------------
   The interface is an irrigation controller faceplate. The green housing on
   the left is fixed hardware: numbered stations hung off a manifold line, a
   gold cursor that sits at the live station, and a readout that remembers
   the visitor's water district. The paper pane inside it is the document.

   Hardware does not reload. That is the whole reason this site uses
   cross-document view transitions: every page is a real, indexable URL, but
   the housing never flickers and the cursor slides from station to station
   across the navigation.

   Palette and type follow DESIGN.md at the repo root (settled Sep 6 2026).
   Read that first; where it and this file disagree, this file is behind.
   Summary: white ground, deep green only in the seal, a lighter "leaf" green
   for everything you press, gold in four roles and never on a button, DM Sans
   for text and Big Shoulders Display for the hero and prices only.

   The housing (rail / masthead / footer) is paper now, not dark green - Seth's
   call, twice: "too much dark green". The faceplate metaphor survives as
   structure, not as colour.
   ========================================================================== */

:root{
  --deep:#003016; --core:#0A572D; --mid:#136B38; --bright:#298E4C;
  --leaf:#2E9E55; --leaf-wash:#E3F2E7;   /* the interactive green - see DESIGN.md */
  --gold:#FFCD2F;
  --gold-ink:#7A5B00; --gold-wash:#FFF3C4;
  --link:#1F8A48;            /* gold as TEXT on paper — #FFCD2F fails AA there */
  --paper:#F2F5F1; --paper-hi:#FBFAF6; --sunk:#E4EAE3; --card:#FFFFFF;
  --ink:#101A14; --ink-2:#3C4A42; --ink-faint:#5A6960;
  --line:#D3DCD2; --line-2:#BCC7BA;
  --shell:#F2F5F1; --shell-ink:#101A14; --shell-faint:#5A6960;
  --shell-line:#D3DCD2;
  --film:#0B0F0C;            /* the photo sequence ground - a neutral dark, not green */
  --rail:250px; --rad:14px;
  --f-display:"Big Shoulders Display","Big Shoulders",Haettenschweiler,"Arial Narrow",sans-serif;
  --f-head:"DM Sans",system-ui,sans-serif;
  --f-body:"DM Sans",system-ui,-apple-system,BlinkMacSystemFont,sans-serif;
  --f-mono:"DM Sans",system-ui,sans-serif;   /* labels keep their small-caps rhythm, one family */
}
@media (prefers-color-scheme: dark){
  :root:not([data-theme="light"]){
    --paper:#111713; --paper-hi:#161D18; --sunk:#0C110E; --card:#1A231C;
    --ink:#E6EBE5; --ink-2:#AEBBB1; --ink-faint:#8A9990;
    --line:#26302A; --line-2:#354139;
    --shell:#0C110E; --shell-ink:#E6EBE5; --shell-faint:#8A9990;
    --shell-line:#26302A;
    --core:#0F6836; --bright:#3FA95F; --leaf:#4CB86D; --leaf-wash:#17301F;
    --gold-ink:#FFCD2F; --gold-wash:#2A2410; --link:#3FA95F;
  }
}
:root[data-theme="dark"]{
  --paper:#111713; --paper-hi:#161D18; --sunk:#0C110E; --card:#1A231C;
  --ink:#E6EBE5; --ink-2:#AEBBB1; --ink-faint:#8A9990;
  --line:#26302A; --line-2:#354139;
  --shell:#0C110E; --shell-ink:#E6EBE5; --shell-faint:#8A9990;
  --shell-line:#26302A;
  --core:#0F6836; --bright:#3FA95F; --leaf:#4CB86D; --leaf-wash:#17301F;
  --gold-ink:#FFCD2F; --gold-wash:#2A2410; --link:#3FA95F;
}

*{box-sizing:border-box}
html{height:100%}
body{
  margin:0; min-height:100%; background:var(--shell); color:var(--ink);
  font-family:var(--f-body); font-size:15.5px; line-height:1.55; font-optical-sizing:auto;
  -webkit-font-smoothing:antialiased;
  display:grid; grid-template-columns:var(--rail) 1fr;
}
.skip{
  position:absolute; left:-9999px; top:0; z-index:200; background:var(--gold); color:#231A00;
  padding:.7rem 1rem; font-family:var(--f-mono); font-size:12px; border-radius:0 0 8px 0;
}
.skip:focus{left:0}

/* ==========================================================================
   1. Cross-document view transitions
   The housing is named so it is captured as its own layer and simply does
   not animate; only the pane crossfades and the cursor morphs.
   ========================================================================== */
@view-transition{ navigation:auto; }
@media (prefers-reduced-motion: reduce){
  @view-transition{ navigation:none; }
}

.rail        { view-transition-name:rail; }
.station-cursor{ view-transition-name:station-cursor; }
.pane        { view-transition-name:pane; }
.readout     { view-transition-name:readout; }

::view-transition-group(rail),
::view-transition-group(seal),
::view-transition-group(readout){ animation-duration:0s; }

/* The home page has no rail, every interior page does. When a transition has
   only one image for a name, that pseudo-element is an :only-child - which is
   the one way CSS can tell "the housing is present on both sides, hold it
   still" from "the housing is arriving, so bring it in". */
::view-transition-new(rail):only-child{ animation:.34s cubic-bezier(.2,.7,.3,1) both hos-rail-in; }
::view-transition-old(rail):only-child{ animation:.22s ease-in both hos-rail-out; }
@keyframes hos-rail-in { from{ transform:translateX(-100%); opacity:0 } }
@keyframes hos-rail-out{ to  { transform:translateX(-100%); opacity:0 } }
@media (max-width:1000px){
  /* on small screens the housing is a bottom bar, so it arrives from below */
  @keyframes hos-rail-in { from{ transform:translateY(100%); opacity:0 } }
  @keyframes hos-rail-out{ to  { transform:translateY(100%); opacity:0 } }
}
::view-transition-old(rail),
::view-transition-new(rail),
::view-transition-old(readout),
::view-transition-new(readout){ animation:none; mix-blend-mode:normal; }

/* The cursor travels. 0.42s critically damped — the same response the rest
   of the site's springs use, expressed as a sampled easing curve. */
::view-transition-group(station-cursor){
  animation-duration:.42s;
  animation-timing-function:linear(0,.0072,.0286,.0637,.1118,.1719,.2431,.3243,.4144,.5121,.6161,.7247,.8362,.9487,1.0604,1.1694,1.274,1.3287,1.3213,1.2887,1.2427,1.1917,1.1414,1.0956,1.0568,1.0261,1.0038,.9895,.9821,.9803,.9827,.9878,.9942,1.0004,1.0055,1.0087,1,1);
}
::view-transition-old(pane){ animation:.24s ease-in both hos-pane-out; }
::view-transition-new(pane){ animation:.36s ease-out both hos-pane-in; }
@keyframes hos-pane-out{ to{ opacity:0; transform:translateY(-8px); } }
@keyframes hos-pane-in { from{ opacity:0; transform:translateY(12px); } }

/* ==========================================================================
   2. The housing
   ========================================================================== */
.rail{
  position:sticky; top:0; align-self:start; height:100dvh;
  background:var(--shell); color:var(--shell-ink);
  display:flex; flex-direction:column; min-height:0;
  border-right:1px solid var(--shell-line);
}
.brand{display:flex; gap:.7rem; align-items:center; padding:1.15rem 1.15rem 1rem; text-decoration:none; color:inherit}
/* The real seal, not a stand-in monogram. The art carries its own concentric
   rings, so no border here — a CSS ring on top of drawn rings reads as a
   mistake. It keeps its own view-transition-name so it holds still across a
   navigation instead of being re-snapshotted with the rail. */
/* The mark ships exactly as drawn - keyline, shadow and all - so there is no
   border, no ring and no box-shadow here. There used to be a fake white ring
   compensating for a keyline the generator had cropped off; the generator no
   longer crops, so the compensation is gone with it.
   Spec calls for 74-112px on flyers and tiles. A nav bar cannot carry that, so
   this is as large as the shell allows - see the note in ROADMAP.md. */
.seal{
  width:48px; height:48px; flex:0 0 48px;
  display:block; object-fit:contain;
  border-radius:50%;
  view-transition-name:seal;
}
/* Only one seal may carry the transition name. On the deployed site the
   masthead and the rail never coexist, but the preview harness renders both
   into one document, and two elements sharing a view-transition-name is
   invalid - it kills the transition outright. The rail's is the one that has
   to persist across pages, so the masthead's opts out. */
.masthead .seal{width:44px; height:44px; flex-basis:44px; view-transition-name:none}
.brand-name{display:block; font-family:var(--f-head); font-weight:700; font-size:14px; letter-spacing:-.01em; line-height:1.2; color:var(--ink)}
.brand-sub{display:block; font-family:var(--f-mono); font-weight:500; font-size:10px; letter-spacing:.09em; text-transform:uppercase; color:var(--shell-faint); margin-top:3px}

/* --- stations on a manifold ------------------------------------------- */
.stations{list-style:none; margin:0; padding:.3rem .8rem; position:relative; overflow-y:auto; flex:1 1 auto; min-height:0}
.stations::before{           /* the manifold the stations hang off */
  content:""; position:absolute; left:1.42rem; top:.9rem; bottom:.9rem;
  width:1px; background:var(--shell-line);
}
.stations a{
  position:relative; display:flex; align-items:center; gap:.75rem;
  padding:.5rem .6rem .5rem .35rem; border-radius:9px;
  color:var(--ink-2); text-decoration:none;
  font-size:14px; font-weight:500; line-height:1.25;
}
.stations .emitter{           /* the take-off point on the manifold */
  position:relative; z-index:2; flex:0 0 9px; width:9px; height:9px; border-radius:50%;
  background:var(--shell); border:1.5px solid var(--shell-faint); opacity:.65;
}
.stations .n{
  font-family:var(--f-mono); font-size:9.5px; letter-spacing:.06em;
  color:var(--shell-faint); opacity:.7; font-variant-numeric:tabular-nums;
}
.stations a:hover{color:var(--ink); background:var(--sunk)}
.stations a:hover .emitter{opacity:1; border-color:var(--ink)}
.stations a[aria-current="page"]{color:var(--ink); font-weight:600}
.stations a[aria-current="page"] .emitter{background:var(--leaf); border-color:var(--leaf); opacity:1}
.stations a[aria-current="page"] .n{color:var(--gold-ink); opacity:1}
.station-cursor{
  position:absolute; left:.3rem; width:3px; border-radius:2px; background:var(--leaf);
  pointer-events:none;
}

.rail-foot{padding:.9rem 1.15rem 1.15rem; display:flex; flex-direction:column; gap:.8rem; border-top:1px solid var(--shell-line)}
.readout{
  border:1px solid var(--shell-line); border-radius:10px; background:var(--card);
  font-family:var(--f-mono); font-size:10.5px; overflow:hidden;
}
.readout dl{margin:0; display:grid; grid-template-columns:auto 1fr}
.readout dt{
  padding:.4rem .6rem; color:var(--shell-faint); font-size:9px; letter-spacing:.12em;
  text-transform:uppercase; border-bottom:1px solid var(--shell-line);
}
.readout dd{
  margin:0; padding:.4rem .6rem; text-align:right; color:var(--ink); font-variant-numeric:tabular-nums;
  border-bottom:1px solid var(--shell-line);
}
.readout dd.gold{color:var(--gold-ink); font-weight:600}
.readout dl > :nth-last-child(-n+2){border-bottom:0}
.readout-set{
  display:block; width:100%; text-align:center; appearance:none; cursor:pointer;
  background:var(--sunk); border:0; border-top:1px solid var(--shell-line);
  color:var(--shell-faint); font-family:var(--f-mono); font-size:9px;
  letter-spacing:.12em; text-transform:uppercase; padding:.42rem;
}
.readout-set:hover{color:var(--ink)}
.rail-phone{display:inline-flex; align-items:center; justify-content:center; font-family:var(--f-mono); font-size:14px; font-weight:700;
  color:#241B00; background:var(--gold); text-decoration:none; padding:.55rem .9rem; border-radius:999px; white-space:nowrap}
.rail-phone span{display:none}

/* ==========================================================================
   3. The pane
   ========================================================================== */
.pane-wrap{padding:10px 10px 10px 0; min-width:0}
.pane{
  background:var(--paper-hi); border-radius:var(--rad); min-width:0;
  /* `clip` rather than `hidden`: both clip to the rounded corners, but
     `hidden` makes this element the containing block for any descendant
     using position:sticky, which silently broke the sticky scroll track
     inside it. `clip` creates no scroll container, so sticky keeps
     resolving against the viewport. */
  overflow:hidden; overflow:clip;
  box-shadow:0 1px 2px rgba(0,0,0,.06),0 10px 30px rgba(0,0,0,.07); border:1px solid var(--line);
}
.topbar{
  position:sticky; top:10px; z-index:30; display:flex; align-items:center; gap:1rem;
  padding:.55rem 1.5rem; border-bottom:1px solid transparent;
  background:color-mix(in srgb, var(--paper-hi) 84%, transparent);
  -webkit-backdrop-filter:blur(18px) saturate(180%); backdrop-filter:blur(18px) saturate(180%);
}
.crumb{font-family:var(--f-mono); font-size:10px; letter-spacing:.13em; text-transform:uppercase; color:var(--ink-faint)}
.topbar .spacer{margin-left:auto}
.theme-btn{
  appearance:none; border:1px solid var(--line-2); background:transparent; color:var(--ink-2);
  font-family:var(--f-mono); font-size:10px; letter-spacing:.1em; text-transform:uppercase;
  padding:.3rem .6rem; border-radius:7px; cursor:pointer;
}
.theme-btn:hover{color:var(--ink); border-color:var(--ink-faint)}
.wrap{max-width:940px; margin:0 auto; padding:0 1.5rem}
.wrap-wide{max-width:1180px; margin:0 auto; padding:0 1.5rem}
section{padding:clamp(3rem,6vw,4.75rem) 0}

:is(.stations a, .btn, .cityopt, .sym, .theme-btn, .readout-set, .shot-zoom, .lb-close, a):focus-visible{
  outline:2px solid var(--gold); outline-offset:2px; border-radius:4px;
}

/* ==========================================================================
   4. Type
   ========================================================================== */
.eyebrow{font-family:var(--f-mono); font-weight:500; font-size:12px; letter-spacing:.07em; text-transform:uppercase; color:var(--ink-faint); margin:0}
h1,h2,h3{text-wrap:balance; margin:0}
.h-display{
  font-family:var(--f-display); font-weight:800; text-transform:uppercase;
  font-size:clamp(3rem,7.5vw,5.6rem); line-height:.92; letter-spacing:.005em; color:var(--ink);
}
/* One emphasised word per headline: leaf green with a gold underline. */
.h-display em{font-style:normal; color:var(--leaf); position:relative; display:inline-block}
.h-display em::after{content:""; position:absolute; left:.02em; right:.02em; bottom:-.04em; height:.08em; background:var(--gold); border-radius:2px}
h2{font-family:var(--f-head); font-weight:600; font-size:clamp(1.6rem,3.2vw,2.15rem); line-height:1.15; letter-spacing:-.02em}
h3{font-family:var(--f-head); font-weight:600; font-size:1.1rem; line-height:1.25; letter-spacing:-.015em}
p{margin:0 0 1rem}
.lede{font-size:clamp(1.02rem,1.6vw,1.16rem); line-height:1.6; color:var(--ink-2); max-width:62ch}
.stack > * + *{margin-top:1rem}
.gold-rule{height:3px; width:64px; background:var(--leaf); border-radius:2px}
.section-head{max-width:66ch; margin-bottom:2.25rem}
.section-head h2{margin:.7rem 0 .9rem}
.legal{border-top:1px solid var(--line); margin-top:1rem; padding:1.5rem 0 3rem; font-size:.8rem; color:var(--ink-faint); line-height:1.55}

/* ==========================================================================
   5. Hero, with drip laterals that draw themselves
   ========================================================================== */
.hero{position:relative; background:var(--paper-hi); color:var(--ink); overflow:hidden; padding:clamp(3.2rem,8vw,6rem) 0 clamp(2.8rem,6vw,4.5rem)}
.hero .wrap{position:relative; z-index:2}
.hero .h-display{margin:1.15rem 0 1.3rem}
.hero .lede{color:var(--ink-2)}
.hero .lede strong{color:var(--ink); font-weight:600}
.laterals{position:absolute; inset:0; width:100%; height:100%; z-index:1; opacity:.35; pointer-events:none}
.laterals path{fill:none; stroke:var(--leaf); stroke-width:1}
.laterals circle{fill:var(--gold); opacity:.5}
@media (prefers-reduced-motion: no-preference){
  .laterals path{stroke-dasharray:1400; stroke-dashoffset:1400; animation:hos-draw 2.6s cubic-bezier(.22,.61,.36,1) forwards}
  .laterals circle{opacity:0; animation:hos-emit .5s ease-out forwards}
}
@keyframes hos-draw{ to{ stroke-dashoffset:0 } }
@keyframes hos-emit{ to{ opacity:.5 } }

.row{display:flex; flex-wrap:wrap; gap:.7rem; margin-top:2rem}
.btn{
  appearance:none; border:1px solid transparent; cursor:pointer; text-decoration:none;
  font-family:var(--f-body); font-size:14.5px; font-weight:600; letter-spacing:0; text-transform:none;
  padding:.72rem 1.15rem; border-radius:9px; display:inline-flex; align-items:center; gap:.5rem;
}
/* .btn-gold is the class the build uses for the one primary action per view.
   DESIGN.md: green means press, gold means notice - so the primary is leaf. */
.btn-gold{background:var(--leaf); color:#fff}
.btn-gold:hover{background:var(--bright)}
.btn-ghost{background:transparent; border-color:var(--line-2); color:var(--ink)}
.btn-ghost:hover{border-color:var(--leaf)}
.btn-dark{background:transparent; border-color:var(--line-2); color:var(--ink)}
.btn-dark:hover{border-color:var(--leaf)}
.btn-line{background:transparent; border-color:var(--line-2); color:var(--ink-2)}
.btn-line:hover{border-color:var(--ink-faint); color:var(--ink)}
.btn[disabled]{opacity:.4; cursor:not-allowed}
.is-pressed{transform:scale(.975)}
.btn,.cityopt,.sym,.stations a,.shot-zoom{transition:transform 110ms ease-out, background-color 140ms ease-out, border-color 140ms ease-out, color 140ms ease-out}

/* ==========================================================================
   6. Blocks
   ========================================================================== */
.band{background:var(--paper); color:var(--ink)}
.split{display:grid; grid-template-columns:1.35fr .95fr; gap:clamp(1.5rem,4vw,3.25rem); align-items:start}
.note{border-left:3px solid var(--leaf-wash); background:var(--card); padding:1.15rem 1.25rem; border-radius:0 10px 10px 0}
.note .k{font-family:var(--f-mono); font-size:10px; letter-spacing:.13em; text-transform:uppercase; color:var(--ink-faint); display:block; margin-bottom:.6rem}
.note p{font-size:.94rem; color:var(--ink-2)}
.note p:last-child{margin-bottom:0}

.grid-3{display:grid; grid-template-columns:repeat(auto-fit,minmax(230px,1fr)); gap:1rem}
.tile{border:1px solid var(--line); background:var(--card); border-radius:var(--rad); padding:1.15rem 1.2rem}
.tile h3{margin-bottom:.45rem}
.tile p{font-size:.9rem; color:var(--ink-2); margin:0}
.tile .n{font-family:var(--f-mono); font-size:9.5px; letter-spacing:.13em; text-transform:uppercase; color:var(--ink-faint); display:block; margin-bottom:.5rem}

.opts{display:grid; grid-template-columns:repeat(3,1fr); gap:1rem; align-items:stretch}
.opt{border:1px solid var(--line); background:var(--card); border-radius:var(--rad); padding:1.35rem 1.25rem; display:flex; flex-direction:column}
/* The recommended option is the one card allowed to look different - gold. */
.opt.rec{border-color:var(--gold); box-shadow:0 0 0 3px var(--gold-wash); position:relative}
.opt-tag{position:absolute; top:-11px; left:1.1rem; background:var(--gold); color:#241B00;
  font-family:var(--f-mono); font-size:11px; font-weight:700; letter-spacing:.05em; text-transform:uppercase; padding:.18rem .6rem; border-radius:999px}
.opt-n{font-family:var(--f-mono); font-weight:500; font-size:12px; letter-spacing:.07em; text-transform:uppercase; color:var(--ink-faint)}
.opt h3{margin:.45rem 0 .55rem; font-size:1.25rem}
/* Prices in the display face: big numbers like an estimate, echoing the hero. */
.opt-price{font-family:var(--f-display); font-size:2.1rem; font-weight:800; line-height:1; letter-spacing:.01em; color:var(--ink); font-variant-numeric:tabular-nums}
.opt-price em{font-style:normal; color:var(--ink-faint); font-size:.7em; padding:0 .12em}
.opt-terms{display:block; font-family:var(--f-display); font-size:1.45rem; font-weight:800; line-height:1.05; letter-spacing:.01em; text-transform:uppercase; color:var(--leaf)}
.terms{font-size:.85rem; color:var(--ink-2)}
.terms summary{cursor:pointer; color:var(--link); font-weight:600}
.terms ul{margin:.6rem 0 0; padding-left:1.1rem; display:grid; gap:.45rem}
.terms li{line-height:1.45}
.opt-desc{font-size:.9rem; color:var(--ink-2); margin:.75rem 0 .9rem}
.opt ul{list-style:none; margin:0 0 1rem; padding:0; display:flex; flex-direction:column; gap:.45rem}
.opt li{font-size:.875rem; color:var(--ink-2); padding-left:1.05rem; position:relative; line-height:1.42}
.opt li::before{content:"—"; position:absolute; left:0; color:var(--leaf)}
.opt-when{margin-top:auto; padding-top:.9rem; border-top:1px solid var(--line); font-size:.85rem; color:var(--ink-faint)}
.opt-when b{color:var(--gold-ink); font-weight:600}

.tbl-scroll{overflow-x:auto; border:1px solid var(--line); border-radius:10px; background:var(--card)}
table{width:100%; border-collapse:collapse; font-size:.9rem; min-width:420px}
th,td{text-align:left; padding:.72rem .95rem; border-bottom:1px solid var(--line)}
tr:last-child td{border-bottom:0}
th{font-family:var(--f-mono); font-size:11px; letter-spacing:.07em; text-transform:uppercase; color:var(--ink-faint); font-weight:500; background:var(--sunk)}
td{color:var(--ink-2)} td b{color:var(--ink)}
td.num{font-family:var(--f-mono); font-variant-numeric:tabular-nums; color:var(--ink); font-weight:600}

/* ==========================================================================
   7. Cities
   ========================================================================== */
.cities{display:grid; grid-template-columns:repeat(auto-fit,minmax(178px,1fr)); gap:.65rem}
.cityopt{
  appearance:none; text-align:left; cursor:pointer; font:inherit; text-decoration:none;
  border:1px solid var(--line); background:var(--card); border-radius:var(--rad);
  padding:1rem 1.05rem; color:var(--ink); display:flex; flex-direction:column; gap:.35rem; min-height:96px;
}
.cityopt:hover{border-color:var(--leaf)}
.cityopt[aria-pressed="true"],.cityopt[aria-current="page"]{border-color:var(--leaf); box-shadow:inset 0 0 0 1px var(--leaf)}
.cityopt .cn{display:block; font-family:var(--f-head); font-weight:600; font-size:1.05rem; letter-spacing:-.01em}
.cityopt .cp{display:flex; justify-content:space-between; gap:.5rem; font-family:var(--f-mono); font-size:13px; margin-top:auto; color:var(--ink-faint); font-variant-numeric:tabular-nums}
.cityopt .cp b{color:var(--ink); font-weight:600}

.rules{border:1px solid var(--line); border-radius:var(--rad); background:var(--card); overflow:hidden}
.rules-head{padding:1.15rem 1.25rem; border-bottom:1px solid var(--line); background:var(--sunk)}
.rules-head .prov{font-family:var(--f-mono); font-size:10px; letter-spacing:.11em; text-transform:uppercase; color:var(--ink-faint); margin-top:.35rem; display:block}
.rule{padding:1rem 1.25rem; border-bottom:1px solid var(--line)}
.rule:last-child{border-bottom:0}
.rule .rk{font-family:var(--f-mono); font-size:9.5px; letter-spacing:.13em; text-transform:uppercase; color:var(--ink-faint); display:block; margin-bottom:.35rem}
.rule p{margin:0; font-size:.9rem; color:var(--ink-2)}
.rule b{color:var(--ink)}
.verified{font-family:var(--f-mono); font-size:10px; color:var(--ink-faint); padding:.75rem 1.25rem; background:var(--sunk)}
.covers{display:flex; flex-wrap:wrap; gap:.35rem; margin-top:.7rem}
.covers span{
  font-family:var(--f-mono); font-size:10px; padding:.2rem .5rem; border-radius:5px;
  background:var(--sunk); color:var(--ink-faint); border:1px solid var(--line);
}


/* --- the ZIP tile: eighth card on the area grid --------------------------- */
.cityopt.zip{background:var(--sunk); border-style:dashed; cursor:default; gap:.5rem; grid-column:span 2}
.cityopt.zip:hover{border-color:var(--line-2)}
.zip-l{font-size:13px; color:var(--ink-faint); line-height:1.35}
.zip-row{display:flex; gap:.45rem; margin-top:auto}
.zip-row input{
  flex:1 1 0; min-width:0; font:inherit; font-size:15px; padding:.5rem .65rem; border-radius:9px;
  border:1px solid var(--line-2); background:var(--card); color:var(--ink); font-variant-numeric:tabular-nums;
}
.zip-row input:focus-visible{outline:2px solid var(--gold); outline-offset:1px}
.zip-msg{font-size:13px; color:var(--ink-2); line-height:1.4; min-height:0}
.zip-msg:empty{display:none}
.zip-msg a{color:var(--link)}
.zip-pick{font:inherit; font-size:13px; font-weight:600; padding:.3rem .65rem; border-radius:999px; border:1px solid var(--leaf); background:var(--card); color:var(--ink); cursor:pointer; margin-top:.25rem}
.zip-pick:hover{background:var(--leaf); color:#fff}

/* ==========================================================================
   8. Scroll-driven photo sequence
   ========================================================================== */
.seq-track{height:340svh; position:relative; background:var(--film)}
.seq-sticky{position:sticky; top:0; height:100svh; display:flex; flex-direction:column; justify-content:center; overflow:hidden; color:#fff}
.seq-sticky::after{content:""; position:absolute; inset:0; pointer-events:none;
  background:radial-gradient(100% 80% at 20% 100%, rgba(255,255,255,.06), transparent 60%)}
.seq-inner{position:relative; z-index:2; width:100%; max-width:1180px; margin:0 auto; padding:0 1.5rem}
.seq-head{max-width:52ch; margin-bottom:1.6rem}
.seq-head .eyebrow{color:#9FC5AC}
.seq-head h2{color:#fff; font-size:clamp(1.35rem,2.6vw,1.95rem); margin-top:.6rem}
.seq-stage{display:grid; grid-template-columns:minmax(0,1fr) minmax(0,320px); gap:clamp(1.25rem,3vw,2.5rem); align-items:center}
.seq-frames{position:relative; aspect-ratio:4/3; border-radius:12px; overflow:hidden; background:#000}
.seq-frames img{position:absolute; inset:0; width:100%; height:100%; object-fit:cover; opacity:0; transform:scale(1.06); transition:opacity .45s ease, transform .6s ease}
.seq-frames img.on{opacity:1; transform:scale(1)}
.seq-meta .stage-k{font-family:var(--f-mono); font-size:11px; letter-spacing:.15em; text-transform:uppercase; color:var(--gold); display:block}
.seq-meta time{font-family:var(--f-mono); font-size:11px; color:#8FAE99; display:block; margin-top:.3rem}
.seq-meta p{color:#CEDFD4; font-size:.95rem; margin:.9rem 0 0}
.seq-bar{display:flex; gap:6px; margin-top:1.5rem}
.seq-bar i{flex:1; height:3px; border-radius:2px; background:rgba(255,255,255,.16); position:relative; overflow:hidden}
.seq-bar i b{position:absolute; inset:0; background:var(--gold); transform:scaleX(0); transform-origin:left center}
.seq-count{font-family:var(--f-mono); font-size:10.5px; letter-spacing:.1em; color:#8FAE99; margin-top:.7rem; font-variant-numeric:tabular-nums}

/* Native scroll-driven reveals where supported; the JS fallback below
   handles everything else. */
@media (prefers-reduced-motion: no-preference){
  @supports (animation-timeline: view()){
    [data-reveal]{
      animation:hos-reveal auto linear both;
      animation-timeline:view();
      animation-range:entry 8% entry 46%;
    }
    .js-reveal [data-reveal]{animation:none}
  }
}
@keyframes hos-reveal{ from{ opacity:0; transform:translateY(18px) } to{ opacity:1; transform:none } }
.js-reveal [data-reveal]{opacity:0; transform:translateY(18px)}
.js-reveal [data-reveal].shown{opacity:1; transform:none; transition:opacity .5s ease, transform .5s cubic-bezier(.22,.61,.36,1)}

/* ==========================================================================
   9. Photos + lightbox
   ========================================================================== */
figure.shot{margin:0; display:flex; flex-direction:column; gap:.55rem}
.shot-zoom{appearance:none; border:0; padding:0; background:transparent; cursor:zoom-in; border-radius:10px; overflow:hidden; display:block; width:100%}
.shot-zoom img,figure.shot img{display:block; width:100%; height:auto; border-radius:10px}
figure.shot figcaption{font-size:.85rem; color:var(--ink-faint); line-height:1.45}
figure.shot figcaption b{color:var(--ink-2); font-family:var(--f-mono); font-size:.8rem; letter-spacing:.08em; text-transform:uppercase}
.shots{display:grid; grid-template-columns:repeat(auto-fit,minmax(240px,1fr)); gap:1.25rem}
.lb{position:fixed; inset:0; z-index:100; display:grid; place-items:center}
.lb-scrim{position:absolute; inset:0; background:rgba(4,16,10,.62); -webkit-backdrop-filter:blur(18px) saturate(140%); backdrop-filter:blur(18px) saturate(140%)}
.lb-frame{position:relative; z-index:2; max-width:min(92vw,1000px); margin:0}
.lb-frame img{display:block; width:100%; height:auto; max-height:82svh; object-fit:contain; border-radius:10px}
.lb-close{position:absolute; top:1rem; right:1rem; z-index:3; appearance:none; cursor:pointer;
  background:rgba(255,255,255,.14); border:1px solid rgba(255,255,255,.3); color:#fff;
  font-family:var(--f-mono); font-size:10.5px; letter-spacing:.12em; text-transform:uppercase;
  padding:.5rem .8rem; border-radius:8px; -webkit-backdrop-filter:blur(14px); backdrop-filter:blur(14px)}

/* ==========================================================================
   10. Booking flow
   ========================================================================== */
.flow{max-width:720px; margin:0 auto}
/* Steps ship visible so the form is complete and usable with scripting off.
   The `js` class is set in the document head before first paint, so there is
   no flash of all four steps when scripting is on. */
.js [data-step]{display:none}
.js [data-step].is-live{display:block}
.js .nojs-note{display:none}
.nojs-note{background:var(--paper-hi); border:1px solid var(--line); border-radius:10px;
  padding:.9rem 1rem; font-size:.9rem; color:var(--ink-2); margin-bottom:1.5rem}
/* Without JavaScript every step is on screen at once, so the step buttons are
   inert and the only control that means anything is the submit - and that only
   works once an access key is configured. A later rule in section 8 sets
   .flow-actions to flex, which used to silently win over a bare display:none
   here and leave dead Continue buttons on the no-JS page. These are scoped so
   that cannot happen again. */
html:not(.js) [data-next],
html:not(.js) [data-back],
html:not(.js) [data-restart]{display:none}
html:not(.js) .flow-actions{display:none}
/* Only the row that actually holds the submit - the other three would render
   as empty flex rows carrying their own top margin. */
html:not(.js) form[data-send="1"] .flow-actions:has([data-send-btn]){display:flex}
[data-step] + [data-step]{border-top:1px solid var(--line); margin-top:2.5rem; padding-top:2.5rem}
.js [data-step] + [data-step]{border-top:0; margin-top:0; padding-top:0}
.steps{display:flex; gap:6px; margin-bottom:2rem}
.steps i{flex:1; height:3px; border-radius:2px; background:var(--line-2); position:relative; overflow:hidden}
.steps i b{position:absolute; inset:0; background:var(--leaf); transform:scaleX(0); transform-origin:left center; transition:transform .4s cubic-bezier(.22,.61,.36,1)}
.step-k{font-family:var(--f-mono); font-size:10.5px; letter-spacing:.14em; text-transform:uppercase; color:var(--ink-faint)}
.step h2{margin:.7rem 0 .8rem}
.syms{display:grid; grid-template-columns:repeat(auto-fit,minmax(210px,1fr)); gap:.6rem; margin:1.5rem 0}
.sym{appearance:none; cursor:pointer; font:inherit; text-align:left; border:1px solid var(--line);
  background:var(--paper-hi); border-radius:10px; padding:.8rem .9rem; color:var(--ink);
  font-size:.92rem; display:flex; gap:.65rem; align-items:flex-start}
.sym:hover{border-color:var(--leaf)}
.sym .box{width:16px; height:16px; flex:0 0 16px; border:1.5px solid var(--line-2); border-radius:4px; margin-top:2px; display:grid; place-items:center; font-size:11px; color:#fff}
.sym[aria-pressed="true"]{border-color:var(--leaf)}
.sym[aria-pressed="true"] .box{background:var(--leaf); border-color:var(--leaf)}
.flow-actions{display:flex; gap:.6rem; margin-top:1.75rem; flex-wrap:wrap; align-items:center}
.quote{border:1px solid var(--line); border-radius:var(--rad); background:var(--card); padding:1.35rem 1.4rem; margin:1.5rem 0}
.quote-row{display:flex; justify-content:space-between; align-items:baseline; gap:1rem; padding:.55rem 0; border-bottom:1px solid var(--line)}
.quote-row:last-child{border-bottom:0}
.quote-row .k{font-family:var(--f-mono); font-size:10px; letter-spacing:.12em; text-transform:uppercase; color:var(--ink-faint)}
.quote-row .v{font-family:var(--f-head); font-weight:700; font-size:1rem; text-align:right}
.quote-row .v.big{font-family:var(--f-display); font-weight:800; font-size:2rem; line-height:1; color:var(--gold-ink); font-variant-numeric:tabular-nums}
.field{display:flex; flex-direction:column; gap:.35rem; margin-bottom:.9rem}
.field label{font-family:var(--f-mono); font-size:10px; letter-spacing:.12em; text-transform:uppercase; color:var(--ink-faint)}
.field input{font:inherit; font-size:.95rem; padding:.65rem .8rem; border-radius:9px; border:1px solid var(--line-2); background:var(--paper); color:var(--ink)}
.field input:focus{outline:2px solid var(--gold); outline-offset:1px; border-color:transparent}
.done{text-align:center; padding:2rem 0}
.done .tick{width:56px; height:56px; margin:0 auto 1.25rem; border-radius:50%; background:var(--leaf); color:#fff; display:grid; place-items:center; font-size:26px}

/* ==========================================================================
   11. Responsive — the housing becomes a bottom rail
   ========================================================================== */
@media (max-width:1000px){
  body{grid-template-columns:1fr; grid-template-rows:1fr auto}
  .pane-wrap{padding:0; order:1; min-height:0}
  .pane{border-radius:0; box-shadow:none}
  .topbar{top:0}
  .rail{
    order:2; position:sticky; bottom:0; top:auto; height:auto; align-self:stretch;
    flex-direction:row; align-items:center; border-right:0; border-top:1px solid var(--shell-line);
    overflow-x:auto; padding:0 .4rem; scrollbar-width:none;
  }
  .rail::-webkit-scrollbar{display:none}
  .brand,.rail-foot{display:none}
  .stations{flex-direction:row; display:flex; padding:.5rem .3rem; gap:2px; overflow:visible}
  .stations::before{left:.9rem; right:.9rem; top:auto; bottom:1.05rem; width:auto; height:1px}
  .stations li{flex:0 0 auto}
  .stations a{white-space:nowrap; font-size:12.5px; padding:.45rem .7rem; flex-direction:column; gap:.3rem; align-items:flex-start}
  .stations .emitter{display:none}
  .station-cursor{left:auto; width:auto; height:2px !important; bottom:.3rem; border-radius:1px}
  .split{grid-template-columns:1fr}
  .opts{grid-template-columns:1fr}
  .seq-stage{grid-template-columns:1fr; gap:1rem}
  .seq-frames{aspect-ratio:16/11}
  .seq-track{height:300svh}
  .seq-meta p{display:none}
}
@media (max-width:560px){
  .cityopt.zip{grid-column:1 / -1}
  .wrap,.wrap-wide,.seq-inner{padding:0 1.1rem}
  .topbar{padding:.5rem 1.1rem}
  .cities{grid-template-columns:1fr 1fr}
  .shots{grid-template-columns:1fr}
}

@media (prefers-reduced-motion: reduce){
  *{animation-duration:.01ms !important; animation-iteration-count:1 !important}
  .is-pressed{transform:none}
  .seq-frames img{transform:none}
  .js-reveal [data-reveal]{opacity:1; transform:none}
  .laterals path{stroke-dashoffset:0}
  .laterals circle{opacity:.5}
}

/* ==========================================================================
   12. The full-bleed shell — home page only
   The faceplate is the interior experience. The home page drops it entirely
   and gives the content the whole viewport, so arriving at an interior page
   reads as stepping into the console rather than as more of the same.
   ========================================================================== */
/* minmax(0,1fr), not 1fr: an auto/1fr track floors at the item's MIN-content
   width, so one wide thing inside .pane (the numbered sheet in
   .band.has-sheet) was widening the whole document between 900 and about
   1110px and giving the page a sideways scrollbar. .pane already clips its
   own overflow; this stops the track from growing to meet it. */
body.full{grid-template-columns:minmax(0,1fr)}
body.full .topbar{display:none}   /* the rail is not rendered at all on this shell */
body.full .pane-wrap{padding:0; min-width:0}
body.full .pane{
  background:var(--paper-hi); border-radius:0; box-shadow:none; border:0;
  /* still clip, not hidden - the sticky sequence lives in here */
  overflow:hidden; overflow:clip;
}

/* --- masthead ---------------------------------------------------------- */
.masthead{
  position:sticky; top:0; z-index:60; display:flex; align-items:center; gap:1.4rem;
  padding:.6rem clamp(1.1rem,3vw,2rem);
  background:color-mix(in srgb, var(--shell) 82%, transparent);
  -webkit-backdrop-filter:blur(20px) saturate(180%); backdrop-filter:blur(20px) saturate(180%);
  border-bottom:1px solid var(--shell-line);
}
.mast-brand{display:flex; align-items:center; gap:.6rem; text-decoration:none; color:inherit; flex:0 0 auto}
.mast-name{
  font-family:var(--f-head); font-weight:700; font-size:14px; line-height:1.15;
  letter-spacing:-.01em; color:var(--ink);
}
.mast-nav{display:flex; gap:.2rem; margin-left:.6rem; min-width:0; overflow-x:auto; scrollbar-width:none}
.mast-nav::-webkit-scrollbar{display:none}
.mast-nav a{
  color:var(--ink-2); text-decoration:none; font-size:14px; font-weight:500;
  padding:.42rem .62rem; border-radius:8px; white-space:nowrap;
}
.mast-nav a:hover{color:var(--ink); background:var(--sunk)}
.mast-act{margin-left:auto; display:flex; align-items:center; gap:.7rem; flex:0 0 auto}
.mast-tel{
  font-family:var(--f-mono); font-size:14px; font-weight:700; color:#241B00; background:var(--gold);
  text-decoration:none; white-space:nowrap; padding:.45rem .8rem; border-radius:999px;
}
.btn-sm{padding:.46rem .85rem; font-size:11px}
.masthead .theme-btn{border-color:var(--shell-line); color:var(--shell-faint)}
.masthead .theme-btn:hover{color:var(--ink); border-color:var(--ink-faint)}

/* --- footer navigation ------------------------------------------------- */
/* The home page has no rail, so the complete link set lives here. Every one of
   the sixteen URLs is reachable from the home page as a real anchor - the seven
   area pages are the whole SEO play and must not depend on an interior page. */
.site-foot{
  /* No top margin: the section above may already be dark, and a gap there
     showed as a stray strip of paper between two green blocks. */
  background:var(--shell); color:var(--shell-ink);
  padding:3.4rem 0 2.4rem; border-top:1px solid var(--shell-line);
}
.site-foot .eyebrow{margin:0 0 1rem}
.foot-grid{display:grid; grid-template-columns:1.1fr .9fr 1fr; gap:clamp(1.6rem,4vw,3.4rem)}
.foot-nav,.foot-areas{list-style:none; margin:0; padding:0; display:grid; gap:.55rem}
.foot-areas{grid-template-columns:1fr 1fr}
.foot-nav li{display:flex; align-items:baseline; gap:.7rem}
.foot-nav .n{
  font-family:var(--f-mono); font-size:11px; color:var(--ink-faint);
  font-variant-numeric:tabular-nums; flex:0 0 auto;
}
.foot-nav a,.foot-areas a{color:var(--ink-2); text-decoration:none; font-size:14px; font-weight:500}
.foot-nav a:hover,.foot-areas a:hover{color:var(--ink)}
.foot-tel{
  display:inline-block; font-family:var(--f-mono); font-size:17px; font-weight:700;
  color:#241B00; background:var(--gold); text-decoration:none; margin-bottom:.9rem;
  padding:.55rem 1rem; border-radius:999px;
}
.foot-note{color:var(--ink-2); font-size:13.5px; line-height:1.5; margin:0 0 1.2rem; max-width:36ch}
body.full .legal{border-top:0}
.foot-legal{
  color:var(--ink-faint); border-top:1px solid var(--shell-line);
  margin-top:2.6rem; padding:1.5rem 0 0; font-size:.78rem;
}

@media (max-width:900px){
  .foot-grid{grid-template-columns:1fr; gap:2.2rem}
  .mast-nav{display:none}
  .mast-name{font-size:11.5px}
}
@media (max-width:560px){
  .mast-tel{display:none}
  .masthead{gap:.8rem; padding:.55rem 1.1rem}
}

/* ==========================================================================
   13. The diagnostic
   Everything renders. The script only filters, so without JavaScript the page
   is the complete reference - which is also what makes it worth ranking for
   "why is my sprinkler misting".
   ========================================================================== */
.hero-tight{padding-bottom:2.4rem}
.band-tight{padding:2.2rem 0}
.sym-pick{display:flex; flex-wrap:wrap; gap:.55rem}
.sym-btn{
  appearance:none; cursor:pointer; font:inherit; font-weight:600; font-size:14px;
  padding:.7rem 1.05rem; border-radius:11px; border:1px solid var(--line-2);
  background:var(--paper-hi); color:var(--ink-2); transition:.18s ease;
}
.sym-btn:hover{border-color:var(--ink-faint); color:var(--ink)}
.js .sym-btn.on{
  background:var(--leaf); border-color:var(--leaf); color:#fff;
  box-shadow:none;
}

/* Without the script every panel stays visible. With it, one at a time. */
.js [data-sym-panel]{display:none}
.js [data-sym-panel].is-live{display:block}
.sym{padding:2.6rem 0 1rem; scroll-margin-top:5rem}
.causes{display:grid; gap:1.1rem; margin-top:1.6rem}

.cause{
  background:var(--paper-hi); border:1px solid var(--line); border-radius:var(--rad);
  padding:1.35rem 1.5rem; position:relative;
}
.cause-odds{
  font-family:var(--f-mono); font-size:10px; letter-spacing:.14em; text-transform:uppercase;
  color:var(--gold-ink); margin:0 0 .45rem;
}
.cause h3{margin:0 0 .6rem; font-size:1.1rem; line-height:1.25}
.cause p{margin:0 0 .7rem; color:var(--ink-2); font-size:.95rem}
.cause > p:last-child{margin-bottom:0}
.cause-tell,.cause-hos{padding-left:.9rem; border-left:2px solid var(--line-2)}
.cause-tell span,.cause-hos span{
  display:block; font-family:var(--f-mono); font-size:9.5px; letter-spacing:.13em;
  text-transform:uppercase; color:var(--ink-faint); margin-bottom:.2rem;
}
.cause-hos{border-left-color:var(--leaf)}
.cause-opt{font-size:.88rem}
.cause-opt a{color:var(--ink); text-decoration-color:var(--leaf)}

/* Inline links in running prose.
   Every other link on this site takes its colour from a parent - .mast-nav a,
   .foot-nav a, .stations a, .cause-opt a. A bare <a> inside body copy matched
   none of them and fell through to the browser's default blue. That is how the
   footer phone and email, the Roseville rebate link and the water-district
   citation all shipped unbranded, on a site whose whole argument is that the
   details were checked.
   --mid is the designated link colour and is 5.99:1 on light paper, but it is
   not redefined for the dark theme, where it lands at 2.76:1 and fails. --link
   carries a dark value so both themes clear AA. */
.stack a:not([class]),.note a:not([class]),.rule a:not([class]),
.nojs-note a:not([class]),.done a:not([class]){
  color:var(--link); text-decoration-line:underline; text-decoration-thickness:1px;
  text-underline-offset:.18em; text-decoration-color:var(--line-2);
}
.stack a:not([class]):hover,.note a:not([class]):hover,.rule a:not([class]):hover,
.nojs-note a:not([class]):hover,.done a:not([class]):hover{text-decoration-color:var(--link)}

/* The DIY block. Locked rule: when the honest answer is a cheap fix the owner
   can do, say so plainly - and still offer to do it. Both, not either. */
.diy{
  background:color-mix(in srgb, var(--gold) 12%, var(--paper));
  border:1px solid color-mix(in srgb, var(--gold) 38%, var(--line));
  border-radius:10px; padding:.9rem 1.05rem; margin:0 0 .8rem;
}
.diy-k{
  font-family:var(--f-mono); font-size:10px; letter-spacing:.1em; text-transform:uppercase;
  color:var(--gold-ink); margin:0 0 .4rem !important; font-weight:600;
}
.diy p{color:var(--ink); font-size:.92rem}
.diy-us{color:var(--ink-faint) !important; font-size:.85rem !important; margin-bottom:0 !important}

.waste{
  border-top:1px solid var(--line); margin-top:1rem; padding-top:.9rem;
  display:grid; gap:.15rem;
}
.waste-k{
  font-family:var(--f-mono); font-size:9.5px; letter-spacing:.13em; text-transform:uppercase;
  color:var(--ink-faint); margin:0 !important;
}
.waste-n{margin:0 !important; font-size:1rem !important; color:var(--ink) !important}
.waste-n b{font-variant-numeric:tabular-nums}
.waste-d{margin:0 !important; font-size:.95rem !important; color:var(--gold-ink) !important; font-weight:600}
.waste-b{
  margin:.35rem 0 0 !important; font-size:.78rem !important; line-height:1.45;
  color:var(--ink-faint) !important; font-family:var(--f-mono);
}

@media (min-width:860px){
  .causes{grid-template-columns:repeat(3,1fr); align-items:start}
}
@media (max-width:560px){
  .sym-btn{font-size:13px; padding:.62rem .85rem}
}

/* --- the work ---------------------------------------------------------- */
.job{padding:2.8rem 0 1rem}
.job + .job{border-top:1px solid var(--line)}
.job-head{max-width:62ch; margin-bottom:1.8rem}
.job-head h2{margin:.5rem 0 .8rem}

/* These are real job photographs, portrait and landscape mixed. A row-based
   grid leaves ragged holes under the shorter ones, and cropping them all to
   one ratio would throw away the vertical context in a trench shot. Columns
   flow them like a contact sheet instead: natural aspect, no gaps. */
.job .shots{display:block; column-count:3; column-gap:1.25rem}
.job .shots .shot{break-inside:avoid; margin:0 0 1.25rem; display:inline-block; width:100%}
@media (max-width:900px){ .job .shots{column-count:2} }
@media (max-width:560px){ .job .shots{column-count:1} }

/* --- booking: contact fields and send state ---------------------------- */
.field .opt{font-weight:400; color:var(--ink-faint); font-size:.85em}
.field textarea{
  width:100%; font:inherit; font-size:.95rem; padding:.65rem .8rem; border-radius:9px;
  border:1px solid var(--line-2); background:var(--paper-hi); color:var(--ink); resize:vertical;
}
.field textarea:focus-visible{outline:2px solid var(--gold); outline-offset:1px}
.flow-err{
  color:#8C1D18; background:#FDECEA; border:1px solid #F3C7C2;
  border-radius:9px; padding:.7rem .9rem; font-size:.9rem; margin:.2rem 0 1rem;
}
:root[data-theme="dark"] .flow-err,
html:not([data-theme="light"]) .flow-err{background:#2A1512; border-color:#5A2A24; color:#FFB4A9}
.done-note{color:var(--ink-faint); font-size:.85rem; margin-top:1.2rem}
.hp{position:absolute!important; left:-9999px}

/* ==========================================================================
   14. Brand marks — a municipal engineering document
   Every device here carries information: the sheet block carries the station
   number, the stamp carries the real source and date, the emblem carries the
   option number, the icons carry the check step. Decoration that says nothing
   is what made this page feel generic in the first place.
   ========================================================================== */

/* --- drawing-sheet furniture ------------------------------------------- */
.sheet{position:absolute; inset:0; pointer-events:none; z-index:1}
.sheet-corners{position:absolute; inset:1.1rem; width:calc(100% - 2.2rem); height:calc(100% - 2.2rem)}
.sheet-corners path{
  fill:none; stroke:currentColor; opacity:.28; stroke-width:1;
  vector-effect:non-scaling-stroke;
}
.sheet-block{
  position:absolute; right:1.1rem; bottom:1.1rem; text-align:right;
  display:grid; gap:.15rem; padding:.5rem .7rem;
  border:1px solid currentColor; border-radius:2px; opacity:.42;
}
.sheet-n,.sheet-l{
  font-family:var(--f-mono); font-size:9px; letter-spacing:.16em;
  text-transform:uppercase; line-height:1.3; display:block;
}
.sheet-l{opacity:.7}
.has-sheet{position:relative}

/* --- inspection stamp --------------------------------------------------- */
.stamp{
  display:flex; align-items:center; gap:.75rem;
  border:1px solid var(--line-2); border-left:3px solid var(--leaf);
  border-radius:8px; padding:.7rem .9rem; background:var(--card);
  max-width:44ch;
}
.stamp-mark{flex:0 0 30px; width:30px; height:30px}
.stamp-mark circle,.stamp-mark path{fill:none; stroke:var(--leaf); stroke-width:2}
.stamp-mark path{stroke-width:3; stroke-linecap:round; stroke-linejoin:round}
.stamp-k{
  display:block; font-family:var(--f-mono); font-size:9.5px; letter-spacing:.14em;
  text-transform:uppercase; color:var(--leaf);
}
.stamp-t{display:block; font-size:.84rem; color:var(--ink-2); margin-top:.15rem; line-height:1.4}
.band .stamp{background:var(--card)}

/* --- part-number emblem ------------------------------------------------- */
.emblem{width:44px; height:48px; flex:0 0 44px; display:block}
.emblem-body{fill:var(--deep); stroke:none}
.emblem-inner{fill:none; stroke:var(--leaf); stroke-width:1.5}
.emblem-n{
  font-family:var(--f-mono); font-size:19px; font-weight:600; fill:var(--gold);
  letter-spacing:.02em;
}
.opt .emblem{margin-bottom:.9rem}

/* --- schematic icons ---------------------------------------------------- */
.ico{width:32px; height:32px; flex:0 0 32px; display:block; margin-bottom:.7rem}
.ico path,.ico circle,.ico rect{
  /* --bright, not --mid: --mid has no dark-theme override, so on the dark
     paper ground the icons were #136B38 on #111713 and all but invisible. */
  fill:none; stroke:var(--leaf); stroke-width:1.6;
  stroke-linecap:round; stroke-linejoin:round;
}


/* --- the seal at plan-sheet scale --------------------------------------- */
/* Bled off the edge of a dark band. The brand spec allows the mark on a solid
   plate, and a flat green band is exactly that - it is never over a photo. */
.watermark{
  position:absolute; right:-8%; bottom:-22%; width:min(46%, 460px); height:auto;
  opacity:.05; pointer-events:none; z-index:0; filter:saturate(0);
}
@media (max-width:860px){ .watermark{width:70%; right:-22%; bottom:-12%} }

/* --- survey tick rule on a band seam ------------------------------------ */
.tickrule{display:block; width:100%; height:12px}
.tickrule path{stroke:currentColor; stroke-width:1; opacity:.3; vector-effect:non-scaling-stroke}
.band .tickrule{color:var(--ink-faint)}

/* keep real content above the watermark and the sheet furniture */
.band .wrap,.band .wrap-wide,.has-sheet .wrap,.has-sheet .wrap-wide{position:relative; z-index:2}
@media (max-width:720px){
  .sheet-block{display:none}
  .sheet-corners{inset:.6rem; width:calc(100% - 1.2rem); height:calc(100% - 1.2rem)}
}

/* ==========================================================================
   15. Page weight - see the head script in build.py
   html.lite is the lighter site. Nothing here is a fallback for broken
   scripting (that is handled elsewhere); it is a deliberate second edition
   of the same page for slow connections and small devices.
   ========================================================================== */
.lite .laterals{display:none}
.lite .js-reveal [data-reveal]{opacity:1; transform:none; transition:none}
.lite [data-reveal]{animation:none !important}
/* The photo sequence: no scroll track, no sticky stage. The frames stack with
   their captions, in order, and the meta column and progress bar go away. */
.lite .seq-track{height:auto; background:var(--paper); color:var(--ink)}
.lite .seq-sticky{position:static; height:auto; overflow:visible; color:inherit; padding:clamp(3rem,6vw,4.75rem) 0}
.lite .seq-sticky::after{display:none}
.lite .seq-head .eyebrow{color:var(--ink-faint)}
.lite .seq-head h2{color:var(--head)}
.lite .seq-stage{display:block}
.lite .seq-frames{position:static; aspect-ratio:auto; display:grid; gap:1rem; background:transparent; border-radius:0; overflow:visible}
.lite .seq-frames img{position:static; opacity:1; transform:none; transition:none; width:100%; height:auto; aspect-ratio:4/3; object-fit:cover; border-radius:12px; display:block}
.lite .seq-cap{display:block; font-size:.85rem; color:var(--ink-2); margin-top:.45rem; line-height:1.4}
.lite .seq-cap b{display:block; font-size:12px; letter-spacing:.07em; text-transform:uppercase; color:var(--gold-ink); font-weight:600; margin-bottom:.15rem}
.lite .seq-frames figure{margin:0}
.lite .seq-meta,.lite .seq-bar,.lite .seq-count{display:none}
@media (min-width:760px){ .lite .seq-frames{grid-template-columns:1fr 1fr} }
/* Cinematic video, when it lands (ROADMAP B2): mark it data-cinematic and
   give it a poster. The lite site shows the poster and never fetches the file. */
.lite video[data-cinematic]{display:none}
.lite [data-cinematic-poster]{display:block}
[data-cinematic-poster]{display:none}
/* the footer switch */
.weight-note{margin:1rem 0 0; display:flex; flex-wrap:wrap; gap:.6rem 1rem; align-items:center}
.weight-btn{appearance:none; font:inherit; font-size:.78rem; font-weight:600; color:var(--link); background:transparent; border:0; padding:0; cursor:pointer; text-decoration:underline; text-underline-offset:.18em}
[data-weight-is]{display:none}
.weight-full [data-weight-is="full"],.weight-lite [data-weight-is="lite"]{display:inline}
.weight-full [data-weight-set="full"],.weight-lite [data-weight-set="lite"]{display:none}


/* ---- 16. Review round, Sep 8 2026: zones, chart, hold-us, plain words ---- */
:root{--zA:var(--leaf); --zB:var(--gold); --zC:#8A9990}
.fn{font-size:.85rem;color:var(--ink-faint);margin-top:1rem;max-width:70ch;line-height:1.5}
.fn b{color:var(--ink-2)}

.zone-split{display:grid;grid-template-columns:minmax(300px,500px) 1fr;gap:clamp(1.25rem,3vw,2.5rem);align-items:start}
.zone-map{margin:0;background:var(--card);border:1px solid var(--line);border-radius:var(--rad);padding:.6rem}
.zone-map svg{display:block;width:100%;height:auto}
.zone-map figcaption{font-family:var(--f-mono);font-size:10px;letter-spacing:.1em;text-transform:uppercase;color:var(--ink-faint);padding:.55rem .3rem 0}
.zone-map svg{background:var(--paper);border-radius:10px}
.zone-map .zring{fill:none;stroke:var(--line-2);stroke-dasharray:3 3}
.zone-map .zr-l{font-family:var(--f-mono);font-size:9px;letter-spacing:.1em;fill:var(--ink-faint);text-anchor:middle}
.zone-map .zbase{fill:var(--ink)}
.zone-map .za{stroke:var(--card);stroke-width:1;stroke-linejoin:round;fill-opacity:.62;transition:fill-opacity .2s}
.zone-map .za:hover{fill-opacity:.9}
.zone-map .za.zA{fill:var(--zA)} .zone-map .za.zB{fill:var(--zB)} .zone-map .za.zC{fill:var(--zC)}
.zone-map .zt{font-family:var(--f-body);font-size:9.5px;font-weight:500;fill:var(--ink);paint-order:stroke;stroke:var(--paper);stroke-width:3px;stroke-linejoin:round;pointer-events:none}

.zone-legend{list-style:none;margin:0;padding:0;display:grid;gap:.6rem}
.zl{display:grid;grid-template-columns:auto 1fr auto;gap:.85rem;align-items:start;background:var(--card);border:1px solid var(--line);border-radius:12px;padding:.85rem 1rem}
.zl-chip{width:14px;height:14px;border-radius:50%;margin-top:.25rem;border:2px solid var(--card);box-shadow:0 0 0 1px var(--line-2)}
.zl.zA .zl-chip{background:var(--zA)} .zl.zB .zl-chip{background:var(--zB)} .zl.zC .zl-chip{background:var(--zC)}
.zl-body b{color:var(--ink)} .zl-m{color:var(--ink-faint);font-size:.88rem}
.zl-c{display:block;font-size:.9rem;color:var(--ink-2);margin-top:.2rem;line-height:1.45}
.zl-p{font-family:var(--f-display);font-size:1.55rem;font-weight:800;letter-spacing:.01em;font-variant-numeric:tabular-nums;color:var(--ink);line-height:1}

.chart th{vertical-align:top}
.chart .th-s{display:block;font-weight:400;letter-spacing:.02em;text-transform:none;font-size:11px;margin-top:.2rem;color:var(--ink-faint)}
.chart td.yes,.chart td.no{text-align:center;font-family:var(--f-mono);font-size:10.5px;letter-spacing:.08em;text-transform:uppercase}
.chart td.yes span,.chart td.no span{display:inline-block;padding:.22rem .6rem;border-radius:999px}
.chart td.yes span{background:var(--leaf-wash);color:var(--ink)} .chart td.yes span::before{content:"\2713\00a0"}
.chart td.no span{color:var(--ink-faint)} .chart td.no span::before{content:"\00d7\00a0"}

.band-hold{padding:2.2rem 0}
.hold{border:1px solid var(--line);border-left:3px solid var(--gold);background:var(--card);border-radius:0 var(--rad) var(--rad) 0;padding:1.15rem 1.2rem}
.hold .n{font-family:var(--f-mono);font-size:9.5px;letter-spacing:.13em;text-transform:uppercase;color:var(--ink-faint);display:block;margin-bottom:.5rem}
.hold h3{margin-bottom:.45rem} .hold p{font-size:.9rem;color:var(--ink-2);margin:0}

.plain-words{border-top:1px solid var(--line);background:var(--paper)}
.pw-h{font-size:1.25rem;margin:.6rem 0 1.2rem}
.pw-list{display:grid;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));gap:.9rem 2rem;margin:0}
.pw dt{font-weight:600;color:var(--ink)} .pw dd{margin:.25rem 0 0;font-size:.9rem;color:var(--ink-2);line-height:1.5}
.pw-page{grid-template-columns:1fr;gap:1.4rem;max-width:66ch} .pw-page dt{font-size:1.1rem}
@media (max-width:900px){.zone-split{grid-template-columns:1fr}.zone-map{max-width:460px}}


/* ---- The scope builder (W7) ------------------------------------------- */
.svcs{display:grid; gap:.6rem; margin:1.5rem 0}
.svc{appearance:none; cursor:pointer; font:inherit; text-align:left; width:100%;
  border:1px solid var(--line); border-radius:10px; background:var(--paper-hi);
  padding:.95rem 1rem; display:flex; gap:.7rem; align-items:flex-start; color:inherit}
.svc:hover{border-color:var(--leaf)}
.svc .box{width:16px; height:16px; flex:0 0 16px; border:1.5px solid var(--line-2);
  border-radius:50%; margin-top:3px; display:grid; place-items:center; font-size:11px; color:#fff}
.svc[aria-pressed="true"]{border-color:var(--leaf)}
.svc[aria-pressed="true"] .box{background:var(--leaf); border-color:var(--leaf)}
.svc-t{display:block}
.svc-t b{display:block; font-weight:600}
.svc-t i{display:block; font-style:normal; font-size:.88rem; color:var(--ink-faint); margin-top:.15rem}

.js [data-branch]{display:none}
.js [data-branch].is-live{display:block}
.branch{margin-top:1.4rem}
.js .branch-h{display:none}
.branch-h{font-size:1.05rem; margin:2rem 0 .4rem}
.q{margin:1.5rem 0}
.qk{font-weight:600; margin:0 0 .2rem}
.qh{font-size:.88rem; color:var(--ink-faint); margin:0 0 .6rem}
.qopts{display:flex; flex-wrap:wrap; gap:.5rem; margin-top:.55rem}
.qopt{appearance:none; cursor:pointer; font:inherit; font-size:.92rem; color:inherit;
  border:1px solid var(--line); border-radius:999px; background:var(--paper-hi);
  padding:.5rem .85rem; display:inline-flex; gap:.45rem; align-items:center}
.qopt:hover{border-color:var(--leaf)}
.qopt .box{width:14px; height:14px; flex:0 0 14px; border:1.5px solid var(--line-2);
  border-radius:4px; display:grid; place-items:center; font-size:10px; color:#fff}
.qopt[aria-pressed="true"]{border-color:var(--leaf)}
.qopt[aria-pressed="true"] .box{background:var(--leaf); border-color:var(--leaf)}
.qtext{width:100%; font:inherit; color:inherit; background:var(--paper-hi); margin-top:.55rem;
  border:1px solid var(--line); border-radius:10px; padding:.7rem .8rem; resize:vertical}
.scope-sum{font-weight:500; font-size:.9rem; max-width:60%; text-align:right; line-height:1.5}

/* The credit ledger. Every figure here is one already published: the check
   struck against itself, never against an invented repair total. */
.ledger{margin:1.4rem 0 .5rem; border:1px solid var(--line); border-radius:12px;
  background:var(--paper-hi); padding:.4rem 1rem}
.lrow{display:flex; justify-content:space-between; align-items:baseline; gap:1rem;
  padding:.7rem 0; border-bottom:1px solid var(--line)}
.lrow:last-child{border-bottom:0}
.lrow span{color:var(--ink-2); font-size:.93rem}
.lrow b{font-weight:600; font-variant-numeric:tabular-nums}
.lstrike{position:relative; display:inline-block}
.lstrike::after{content:""; position:absolute; left:-2px; right:-2px; top:50%; height:1.5px;
  background:currentColor; transform:scaleX(0); transform-origin:left center;
  transition:transform .5s cubic-bezier(.22,.61,.36,1)}
.ledger.is-struck .lstrike::after{transform:scaleX(1)}
.lcred{opacity:0; transform:translateY(-4px); transition:opacity .4s ease-out .35s, transform .4s ease-out .35s}
.ledger.is-struck .lcred{opacity:1; transform:none}
.ltot b{font-size:1.35rem; color:var(--leaf)}
.ltot{opacity:0; transition:opacity .4s ease-out .6s}
.ledger.is-struck .ltot{opacity:1}
.lnote{font-size:.86rem; color:var(--ink-faint); margin:.2rem 0 1.2rem}
.photo-note{font-size:.88rem; color:var(--ink-2); background:var(--paper-hi);
  border:1px solid var(--line); border-radius:10px; padding:.8rem .9rem; margin:.2rem 0 1rem}
@media (prefers-reduced-motion: reduce){
  .lstrike::after,.lcred,.ltot{transition:none}
  .lcred{opacity:1; transform:none}
  .ltot{opacity:1}
  .lstrike::after{transform:scaleX(1)}
}
@media (max-width:560px){
  .scope-sum{max-width:100%; text-align:left}
  .quote-row{flex-wrap:wrap}
}


/* ==========================================================================
   17. The seal as a cast object - home hero only (Sep 11 2026)
   Named seal-cast, not emblem: .emblem is the hexagonal numbered badge and
   carries height:48px, which flattened this to a 48px strip on first deploy.
   Settled from the study artifact: turns right round, strong lean toward the
   pointer, two faces so a full turn never shows a blank disc. src/emblem.js
   draws it and will not run at all on html.lite - that is deliberate, it is a
   611 KB download. prefers-reduced-motion keeps the seal and stops it moving.
   ========================================================================== */
.hero-seal .wrap{max-width:1240px}
@media (min-width:900px){
  .hero-seal .wrap{
    display:grid;
    /* The second track IS the seal: sized against the viewport's width, its
       height, and a hard ceiling, so a short window shrinks it rather than
       pushing everything below it off the screen. */
    grid-template-columns:minmax(0,1fr) min(46vw, 68vh, 640px);
    gap:clamp(2rem,4vw,3.5rem); align-items:center;
  }
}
.seal-cast{
  /* 300, not 340: with a photograph behind it now, a seal at 87% of a phone's
     width covers the span completely and the picture stops being a picture. */
  position:relative; width:100%; max-width:300px; aspect-ratio:1/1;
  height:auto;              /* stated, not assumed - a stray height beats aspect-ratio */
  margin:2.75rem auto 0;
}
@media (min-width:900px){ .seal-cast{max-width:none; margin:0 0 0 auto} }
.seal-cast canvas{display:block; width:100%; height:100%}
.seal-cast-flat{
  position:absolute; inset:6%; width:88%; height:88%;
  object-fit:contain; transition:opacity .6s ease;
}
.seal-cast.is-live .seal-cast-flat{opacity:0}
@media (prefers-reduced-motion: reduce){ .seal-cast-flat{transition:none} }
/* Lite never loads the renderer, so the flat mark is the whole story - and it
   does not need to be hero-sized to do that job. */
.lite .seal-cast{max-width:190px}


/* ==========================================================================
   18. Photographs of the place, and paired work frames (Sep 11 2026)
   .placestrip is a row of portraits. On the home page and /service-area/ it
   carries Sacramento - place, not work, and the copy beside it says so. The
   .two variant is a before/after or a matched pair.
   ========================================================================== */
.placestrip{
  display:grid; gap:clamp(.7rem,1.6vw,1.15rem); margin-top:2rem;
  grid-template-columns:repeat(auto-fit,minmax(min(46%,240px),1fr));
}
.placestrip.two{grid-template-columns:repeat(auto-fit,minmax(min(100%,320px),1fr))}
.place{margin:0}
.place picture{display:block}
.place img{
  display:block; width:100%; height:auto; border-radius:var(--rad);
  background:var(--sunk);
}
.place figcaption{
  margin-top:.55rem; font-size:.82rem; line-height:1.45; color:var(--ink-faint);
}

/* ---- clips: silent loops of real work ---------------------------------- */
.clips{
  display:grid; gap:clamp(.7rem,1.6vw,1.15rem); margin-top:clamp(1.2rem,2.5vw,2rem);
  /* These are 9:16 phone clips. Let them take a full content column and each
     one is taller than the viewport, so the row is capped and centred. */
  grid-template-columns:repeat(2,minmax(0,1fr)); max-width:660px; margin-inline:auto;
}
@media (max-width:560px){ .clips{grid-template-columns:1fr; max-width:330px} }
.clip{margin:0}
.clip video,.clip img{
  display:block; width:100%; height:auto; border-radius:var(--rad);
  background:var(--film); aspect-ratio:9/16; object-fit:cover;
}
.clip figcaption{margin-top:.55rem; font-size:.82rem; line-height:1.45; color:var(--ink-faint)}
/* Reduced motion gets the poster and nothing that moves - same deal as lite. */
@media (prefers-reduced-motion: reduce){
  .clip video[data-cinematic]{display:none}
  .clip [data-cinematic-poster]{display:block}
}


/* ==========================================================================
   19. Cards that are links (Sep 11 2026)
   A card people obviously want to press should be the link itself, not a card
   with a link somewhere inside it. Colour and text stay exactly as they were -
   these rules only remove the anchor defaults and add a press state, so a
   linked card is not visually louder than the ones that are only for reading.
   ========================================================================== */
.opt-link,.hold-link,a.tile{
  text-decoration:none; color:inherit; display:flex; flex-direction:column;
  transition:border-color .16s ease, box-shadow .16s ease, transform .16s ease;
}
.opt-link:hover,.hold-link:hover,a.tile:hover{border-color:var(--leaf)}
.opt-link:hover,a.tile:hover{transform:translateY(-2px)}
.opt-link.rec:hover{border-color:var(--gold-ink)}
.opt-link h3,.hold-link h3,a.tile h3{color:var(--ink)}
/* The card names its own destination, so the target is never a guess. */
.opt-go{
  margin-top:.85rem; font-size:.85rem; font-weight:600; color:var(--link);
}
.opt-go::after{content:" \2192"}
.opt-link:hover .opt-go{text-decoration:underline; text-underline-offset:.18em}
:is(.opt-link,.hold-link,a.tile):focus-visible{
  outline:2px solid var(--gold); outline-offset:3px; border-radius:var(--rad);
}
@media (prefers-reduced-motion: reduce){
  .opt-link,.hold-link,a.tile{transition:none}
  .opt-link:hover,a.tile:hover{transform:none}
}

/* ---- the zone map: every area is a link into the booking flow ---------- */
.zlink{cursor:pointer}
.zlink .za{transition:fill-opacity .16s ease, stroke-width .16s ease}
.zlink:hover .za,.zlink:focus-visible .za{fill-opacity:1; stroke-width:2.4}
.zlink:focus-visible{outline:2px solid var(--gold); outline-offset:2px}
@media (prefers-reduced-motion: reduce){ .zlink .za{transition:none} }

/* ---- email in the rail, and the social row ----------------------------- */
.rail-mail{
  display:block; margin-top:.5rem; text-decoration:none; color:var(--ink-2);
  font-size:.9rem; font-weight:600;
}
.rail-mail span{
  display:block; font-size:11px; font-weight:500; letter-spacing:.07em;
  text-transform:uppercase; color:var(--ink-faint);
}
.rail-mail:hover{color:var(--link)}
.foot-mail{
  display:block; margin-top:.35rem; color:var(--ink-2); font-size:.92rem;
  text-decoration:none; word-break:break-word;
}
.foot-mail:hover{color:var(--link); text-decoration:underline; text-underline-offset:.18em}
.foot-social{
  list-style:none; margin:1rem 0 0; padding:0; display:flex; flex-wrap:wrap; gap:.5rem .9rem;
}
.foot-social a{
  color:var(--ink-2); font-size:.88rem; font-weight:600; text-decoration:none;
  border-bottom:1px solid var(--line-2); padding-bottom:1px;
}
.foot-social a:hover{color:var(--link); border-color:var(--leaf)}

/* Mobile-only contact in the top bar. Above 1000px the rail carries these, so
   they would be a duplicate; below it the rail's contact block is hidden and
   an interior page had no way to call or write at all. */
.topbar-link{display:none}
@media (max-width:1000px){
  .topbar-link{
    display:inline-block; margin-right:.55rem; padding:.3rem .6rem;
    border:1px solid var(--shell-line); border-radius:8px;
    font-size:12px; font-weight:600; letter-spacing:.02em;
    color:var(--shell-ink); text-decoration:none; white-space:nowrap;
  }
  .topbar-link:hover,.topbar-link:focus-visible{border-color:var(--leaf); color:var(--link)}
}


/* ==========================================================================
   20. The home hero photograph, and the bar that sits on it (Sep 11 2026)
   Seth's call: full bleed, with the menu as a dark bar on the light theme and
   a light bar on the dark one - the bar is always the opposite of the page, so
   it never dissolves into it the way the old paper-on-paper bar did.
   ========================================================================== */
:root{
  /* The bar inverts against the page. Declared here in the bare :root so the
     un-stamped "follow the device" state resolves like any other. */
  --bar-bg:#003016; --bar-ink:#EDF3EE; --bar-ink-2:#B4C9BA;
  --bar-line:#0B3E20; --bar-btn-bg:#F2F5F1; --bar-btn-ink:#00250F;
  --bar-hover:rgba(255,255,255,.10);
  /* Holds the headline readable over the photograph. Heaviest on the left,
     where the text is; the right stays open so the picture is still a picture. */
  --hero-scrim:linear-gradient(96deg,
    var(--paper-hi) 24%, color-mix(in srgb, var(--paper-hi) 92%, transparent) 43%,
    color-mix(in srgb, var(--paper-hi) 42%, transparent) 71%,
    color-mix(in srgb, var(--paper-hi) 16%, transparent) 100%);
  /* Phones get a different problem: there is no empty right-hand half to put
     the picture in, so the copy sits straight over the frame. The veil below
     is vertical instead of horizontal - solid paper through the headline, the
     lede and the two buttons, thinning to a watermark under the seal. It is
     deliberately heavy: the ghost "Call" button is an outline in --ink, and an
     outline needs a light ground far more than a filled button does. */
  --hero-veil:linear-gradient(180deg,
    var(--paper-hi) 0%,
    var(--paper-hi) 62%,
    color-mix(in srgb, var(--paper-hi) 90%, transparent) 70%,
    color-mix(in srgb, var(--paper-hi) 50%, transparent) 82%,
    color-mix(in srgb, var(--paper-hi) 30%, transparent) 100%);
}
@media (prefers-color-scheme: dark){
  :root:not([data-theme="light"]){
    --bar-bg:#F2F5F1; --bar-ink:#101A14; --bar-ink-2:#3C4A42;
    --bar-line:#D3DCD2; --bar-btn-bg:#2E9E55; --bar-btn-ink:#FFFFFF;
    --bar-hover:rgba(16,26,20,.07);
  }
}
:root[data-theme="dark"]{
  --bar-bg:#F2F5F1; --bar-ink:#101A14; --bar-ink-2:#3C4A42;
  --bar-line:#D3DCD2; --bar-btn-bg:#2E9E55; --bar-btn-ink:#FFFFFF;
  --bar-hover:rgba(16,26,20,.07);
}

/* ---- the bar ---------------------------------------------------------- */
.masthead{
  background:var(--bar-bg);
  border-bottom:1px solid var(--bar-line);
  -webkit-backdrop-filter:none; backdrop-filter:none;   /* opaque now; the blur bought nothing */
}
.masthead .mast-name{color:var(--bar-ink)}
.mast-nav a{color:var(--bar-ink-2); position:relative}
.mast-nav a:hover,.mast-nav a:focus-visible{color:var(--bar-ink); background:var(--bar-hover)}
/* A link should look like a control before you touch it, not only after. */
.mast-nav a::after{
  content:""; position:absolute; left:.62rem; right:.62rem; bottom:.22rem; height:2px;
  border-radius:1px; background:var(--gold); transform:scaleX(0); transform-origin:left;
  transition:transform .18s ease;
}
.mast-nav a:hover::after,.mast-nav a:focus-visible::after{transform:scaleX(1)}
.masthead .btn-gold{background:var(--bar-btn-bg); color:var(--bar-btn-ink)}
.masthead .btn-gold:hover{background:var(--gold); color:#241B00}
.masthead .theme-btn{border-color:var(--bar-line); color:var(--bar-ink-2)}
.masthead .theme-btn:hover{color:var(--bar-ink); border-color:var(--bar-ink-2)}
@media (prefers-reduced-motion: reduce){ .mast-nav a::after{transition:none} }

/* ---- the photograph --------------------------------------------------- */
.hero.has-photo{background:var(--paper-hi)}
.hero-photo{position:absolute; inset:0; z-index:0; pointer-events:none}
.hero-photo picture,.hero-photo img{display:block; width:100%; height:100%}
.hero-photo img{object-fit:cover; object-position:50% 50%}
.hero-photo::after{content:""; position:absolute; inset:0; background:var(--hero-scrim)}
/* Below the two-column breakpoint the text sits over the middle of the frame,
   so the left-weighted scrim is replaced outright, not layered under. */
@media (max-width:899px){
  .hero-photo::after{background:var(--hero-veil)}
  /* The phone crop is 9:10 against a much taller box, so the whole height
     shows and only the width is trimmed - centred is what we want. Where the
     span sits vertically is decided in make_images.py, not here. */
  .hero-photo img{object-position:50% 50%}
}
.has-photo .laterals{opacity:.16}

/* ==========================================================================
   21. The promo bar and the project builder (Oct 31 2026)
   The bar sits inside .pane above the topbar on every page while
   PROMO_LIVE. The builder is /plan/: a two-column form, lines on the left,
   a sticky ballpark on the right, that collapses to one column on phones.
   Older eyes read this: 16px floors, dark ink, gold only as --gold-ink text.
   ========================================================================== */
.promo-bar{
  display:flex; flex-wrap:wrap; align-items:center; justify-content:center; gap:.35rem 1rem;
  padding:.55rem 1.25rem; background:var(--gold-wash); color:var(--gold-ink);
  font-size:.95rem; font-weight:600; text-align:center; border-bottom:1px solid var(--line);
}
.promo-bar a{color:var(--gold-ink); text-decoration:underline; text-underline-offset:3px; white-space:nowrap}
:root:not([data-theme="light"]) .promo-bar{ background:#2A2410; color:#FFD75E; border-color:var(--line) }
:root:not([data-theme="light"]) .promo-bar a{ color:#FFD75E }
@media (prefers-color-scheme: light){ :root:not([data-theme="dark"]) .promo-bar{ background:var(--gold-wash); color:var(--gold-ink) } :root:not([data-theme="dark"]) .promo-bar a{ color:var(--gold-ink) } }
.promo-line{margin:.9rem 0 .25rem; font-size:1rem; color:var(--ink)}
.promo-line s{color:var(--ink-faint); margin-right:.15rem}
.promo-line b{color:var(--gold-ink)}
:root:not([data-theme="light"]) .promo-line b{ color:#FFD75E }
@media (prefers-color-scheme: light){ :root:not([data-theme="dark"]) .promo-line b{ color:var(--gold-ink) } }

.plan-cols{display:grid; grid-template-columns:minmax(0,1.5fr) minmax(300px,.9fr); gap:1.5rem; align-items:start}
.plan-group{border:1px solid var(--line); background:var(--card); border-radius:var(--rad); padding:.9rem 1.1rem 1rem; margin:0 0 1rem}
.plan-group legend{font-family:var(--f-mono); font-size:11px; letter-spacing:.13em; text-transform:uppercase; color:var(--ink-faint); padding:0 .4rem}
.plan-line{display:grid; grid-template-columns:auto minmax(0,1fr) auto minmax(5.5rem,auto); gap:.6rem .8rem; align-items:center; padding:.6rem 0; border-top:1px solid var(--line); cursor:pointer}
.plan-line:first-of-type{border-top:0}
.plan-line input[type=checkbox]{width:20px; height:20px; accent-color:var(--leaf); margin:0}
.plan-name{display:flex; flex-direction:column; gap:.1rem; min-width:0}
.plan-name b{font-size:1rem; color:var(--ink)}
.plan-name small{font-size:.85rem; color:var(--ink-2)}
.plan-qty{display:inline-flex; align-items:center; gap:.25rem; opacity:.45; transition:opacity .15s}
.plan-line.is-on .plan-qty{opacity:1}
.plan-qty input{width:4.6rem; padding:.35rem .4rem; font:inherit; font-size:1rem; text-align:center; border:1px solid var(--line-2); border-radius:8px; background:var(--paper-hi); color:var(--ink)}
.plan-qty small{font-size:.8rem; color:var(--ink-faint); white-space:nowrap}
.plan-qty button{width:2rem; height:2rem; border:1px solid var(--line-2); border-radius:8px; background:var(--paper-hi); color:var(--ink); font-size:1.1rem; line-height:1; cursor:pointer}
.plan-sum{font-family:var(--f-display); font-size:1.15rem; text-align:right; color:var(--ink); min-width:5.5rem}
.plan-sum:empty::before{content:'\00a0'}
.plan-zones{display:grid; grid-template-columns:repeat(3,1fr); gap:.6rem}
.plan-zones legend{grid-column:1/-1}
.plan-zone{display:flex; flex-direction:column; gap:.1rem; padding:.7rem .8rem; border:1px solid var(--line); border-radius:10px; cursor:pointer; background:var(--paper-hi)}
.plan-zone:has(input:checked){border-color:var(--leaf); box-shadow:0 0 0 2px var(--leaf-wash)}
.plan-zone input{position:absolute; opacity:0; pointer-events:none}
.plan-zone span{font-weight:600; color:var(--ink)}
.plan-zone small{font-size:.8rem; color:var(--ink-2)}
.plan-note{grid-column:1/-1; font-size:.85rem; color:var(--ink-2); margin:.4rem 0 0}
.plan-total{position:sticky; top:4.5rem; border:1px solid var(--line); background:var(--card); border-radius:var(--rad); padding:1.1rem 1.2rem}
.plan-total .k{font-family:var(--f-mono); font-size:10px; letter-spacing:.13em; text-transform:uppercase; color:var(--ink-faint); display:block; margin-bottom:.5rem}
.plan-range{font-family:var(--f-display); font-size:clamp(1.9rem,4vw,2.6rem); line-height:1; margin:0 0 .5rem; color:var(--ink)}
.plan-small{font-size:.85rem; color:var(--ink-2); margin:.25rem 0}
.plan-walk{margin:1rem 0; padding:.9rem 1rem; border-left:3px solid var(--leaf); background:var(--paper-hi); border-radius:0 10px 10px 0}
.plan-walk p{margin:0; font-size:.95rem; color:var(--ink)}
.plan-walk.is-free{border-left-color:var(--gold)}
.plan-contact{display:grid; gap:.6rem; margin-top:1rem}
.plan-contact label{display:flex; flex-direction:column; gap:.25rem; font-size:.85rem; color:var(--ink-2)}
.plan-contact input,.plan-contact textarea{font:inherit; font-size:1rem; padding:.55rem .65rem; border:1px solid var(--line-2); border-radius:8px; background:var(--paper-hi); color:var(--ink)}
.plan-contact .btn{justify-self:start; margin-top:.3rem}
.plan-sent{font-size:1rem; color:var(--ink); margin-top:1rem}
@media (max-width:900px){
  .plan-cols{grid-template-columns:1fr}
  .plan-total{position:static}
  .plan-line{grid-template-columns:auto minmax(0,1fr); grid-template-areas:"box name" "box qty" "box sum"}
  .plan-line input[type=checkbox]{grid-area:box; align-self:start; margin-top:.2rem}
  .plan-name{grid-area:name}
  .plan-qty{grid-area:qty}
  .plan-sum{grid-area:sum; text-align:left; min-width:0}
  .plan-sum:empty{display:none}
  .plan-zones{grid-template-columns:1fr}
}
