/* Self-hosted type, shared with the homepage. No third-party CSS on the render path. */
@font-face{font-family:"Archivo";font-style:normal;font-weight:400 900;font-stretch:74% 100%;font-display:swap;src:url("/fonts/archivo-vf.woff2") format("woff2")}
@font-face{font-family:"Lora";font-style:normal;font-weight:400 700;font-display:swap;src:url("/fonts/lora.woff2") format("woff2")}
@font-face{font-family:"Lora";font-style:italic;font-weight:400 700;font-display:swap;src:url("/fonts/lora-italic.woff2") format("woff2")}
@font-face{font-family:"Space Mono";font-style:normal;font-weight:400;font-display:swap;src:url("/fonts/spacemono-400.woff2") format("woff2")}

/* ---------------------------------------------------------------------------
   WILLOW CREEK GROUP — shared visual system.

   Extracted from index.html so every page other than the homepage speaks the
   same language. index.html still carries its own copy of these tokens inline,
   because its hero, shader and rescue slider are welded to that stylesheet and
   pulling them apart was not worth the risk. If you change a token here,
   change it there too. That duplication is the one loose end in this file.

   Loaded AFTER each page's own <style> block on purpose: same specificity,
   later wins, so the old declarations are overridden without deleting them.
   --------------------------------------------------------------------------- */

:root{
  --cream:#F7F4EC;
  --wire:#33322C;
  --willow:#5F8266;
  --sky:#A9C9E2;
  --taupe:#B3A992;
  --rust:#A8503A;
  --ink:#1C1B17;
  --rule:#D8D2C2;
  --maxw:1240px;

  /* The old pages painted on --paper #FBF9F3 and set --ink to #33322C, which is
     actually --wire. Both are repointed at the real brand values here, so every
     existing reference on those pages lands on the right colour without having
     to hunt down each rule. */
  --paper:#F7F4EC;
  --card-line:#D8D2C2;
  --sky-tint:#CFE0EF;

  /* --willow on --cream is 3.92:1, under the 4.5 AA floor, so the accented
     "Free Audit" link was failing everywhere it sat on a cream background.
     This is the same hue pulled down until it passes, at 5.3:1. Used only for
     willow text on cream. Fills, borders and dark-background uses keep the
     real --willow. */
  --willow-ink:#4F6C53;
}

*{box-sizing:border-box}
html{scroll-behavior:smooth}

/* Very wide viewports. The design is drawn for ~1200-1920 CSS px: content caps
   at --maxw 1240 and the hero at 182px. On a 4K panel at 100% scaling, or an
   ultrawide, the viewport runs 2600-3840 CSS px and everything reads tiny in a
   sea of background. Rather than re-clamp every measurement, the whole page
   scales up in steps so it always renders as if on a viewport it was drawn
   for. `zoom` is supported by Chrome, Edge, Safari and Firefox 126+; older
   Firefox simply keeps today's rendering. */
@media (min-width:2200px){html{zoom:1.22}}
@media (min-width:2900px){html{zoom:1.5}}
@media (min-width:3500px){html{zoom:1.85}}

body{
  margin:0;
  background:var(--cream);
  color:var(--ink);
  font-family:'Lora',Georgia,serif;
  font-size:18px;
  line-height:1.65;
  -webkit-font-smoothing:antialiased;
  overflow-x:hidden;
}

h1,h2,h3,.ui{font-family:'Archivo',system-ui,sans-serif;color:var(--ink)}
a{color:inherit}
.wrap{max-width:var(--maxw);margin:0 auto;padding:0 32px}

/* Space Mono is the label face. The old pages never loaded it. */
.tag{
  font-family:'Space Mono',monospace;font-size:11px;letter-spacing:.22em;
  text-transform:uppercase;color:var(--willow);margin:0 0 20px;
  display:flex;align-items:center;gap:12px;
}
.tag::before{content:"";width:26px;height:1px;background:var(--willow);flex:none}

h2.big{font-size:clamp(36px,6.2vw,86px);font-weight:900;line-height:.94;letter-spacing:-.035em;margin:0 0 22px}
.lede{font-size:19px;max-width:56ch;color:#4a483f;margin:0 0 44px}

/* ---------- nav ---------- */

.nav{
  position:fixed;top:0;left:0;right:0;z-index:80;
  display:flex;align-items:center;justify-content:space-between;
  padding:18px 32px;transition:background .35s,padding .35s,border-color .35s;
  border-bottom:1px solid transparent;color:var(--cream);
}

/* The homepage nav floats transparent over a full-bleed video and turns solid
   on scroll. Inner pages have no video behind it, so they run the solid state
   permanently and sit in normal flow rather than over the top of the content.
   Same paint, same metrics, no overlap and no padding hack. */
.nav--solid{
  position:sticky;color:var(--ink);
  background:rgba(247,244,236,.93);
  backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);
  border-bottom-color:var(--rule);padding:12px 32px;
}
.nav--solid .brand b{color:var(--ink)}
.nav--solid .nav-cta{background:var(--wire);color:var(--cream)}
.nav--solid .nav-links .nav-hot{color:var(--willow-ink)}

.brand{display:flex;align-items:center;gap:11px;text-decoration:none}
.brand b{font-family:'Archivo';font-weight:900;font-size:13px;letter-spacing:.13em}

/* The real logo. favicon.png is 192x192 with transparency, rendered at 28px so
   it stays crisp at 2x and 3x. Referenced as one shared file, never re-inlined.
   The .brand img rule on some inner pages sets 40px, so this carries the extra
   .brand-mark class to outrank it. */
.brand img.brand-mark{width:28px;height:28px;flex:none;display:block}

/* Three states, and the middle one is the catch. The homepage nav floats
   transparent over the video where the green mark disappears, so tint it cream
   to match the wordmark. The moment the nav turns solid, on scroll (.stuck) or
   when the mobile menu opens (.menu-open), the background is cream and a cream
   logo would vanish, so the original green comes back. Inner pages are
   .nav--solid from the start and are never tinted. */
.nav:not(.nav--solid):not(.stuck):not(.menu-open) .brand img.brand-mark{
  filter:brightness(0) invert(1) sepia(.10) saturate(1.5) hue-rotate(3deg);
  /* the mark is an image, so it lifts with a drop-shadow rather than text-shadow */
  filter:brightness(0) invert(1) sepia(.10) saturate(1.5) hue-rotate(3deg)
         drop-shadow(0 1px 2px rgba(18,20,15,.55))
         drop-shadow(0 2px 8px rgba(18,20,15,.40));
}

/* Nav type only lifts while the bar is transparent over the video. Once it is
   solid, or on an inner page, it is dark type on cream and a shadow would just
   look dirty. */
.nav:not(.nav--solid):not(.stuck):not(.menu-open) .brand b,
.nav:not(.nav--solid):not(.stuck):not(.menu-open) .nav-links a:not(.nav-cta){
  text-shadow:
    0 1px 2px rgba(18,20,15,.55),
    0 2px 8px rgba(18,20,15,.45),
    0 4px 24px rgba(18,20,15,.35);
}
.nav:not(.nav--solid):not(.stuck):not(.menu-open) .nav-cta{
  box-shadow:
    0 1px 2px rgba(18,20,15,.40),
    0 2px 8px rgba(18,20,15,.30);
}

.nav-links{display:flex;align-items:center;gap:20px}
.nav-links a{
  font-family:'Archivo';font-size:11.5px;font-weight:600;letter-spacing:.09em;
  text-transform:uppercase;text-decoration:none;white-space:nowrap;
}
.nav-links .nav-hot{color:var(--willow-ink)}
.nav-links a:hover{color:var(--willow-ink)}
.nav-tel{font-variant-numeric:tabular-nums}
.nav-cta{background:var(--wire);color:var(--cream);padding:10px 20px;border-radius:2px}
.nav-cta:hover{background:var(--willow);color:var(--cream)!important}

/* ---------- desktop nav over the video ----------
   Only the homepage nav is ever transparent; inner pages carry .nav--solid and
   are excluded by the :not() chain. Desktop only: on mobile the closed nav shows
   just the burger, and the open menu paints on cream where a shadow would look
   dirty, so the rules above stand there unchanged. */
@media (min-width:761px){
  /* Two layers, tighter and slightly stronger than the three-layer stack above.
     A wide 24px layer smears into a halo once there is a band behind it too. */
  .nav:not(.nav--solid):not(.stuck):not(.menu-open) .brand b,
  .nav:not(.nav--solid):not(.stuck):not(.menu-open) .nav-links a:not(.nav-cta){
    text-shadow:
      0 1px 2px rgba(18,20,15,.6),
      0 2px 10px rgba(18,20,15,.45);
  }
  /* The mark is an image, so the same two layers have to be drop-shadows. The
     tint filter has to be repeated or it is lost when this rule replaces it. */
  .nav:not(.nav--solid):not(.stuck):not(.menu-open) .brand img.brand-mark{
    filter:brightness(0) invert(1) sepia(.10) saturate(1.5) hue-rotate(3deg)
           drop-shadow(0 1px 2px rgba(18,20,15,.6))
           drop-shadow(0 2px 10px rgba(18,20,15,.45));
  }
  /* "Free Audit" was willow-ink green over dense green foliage, which is close
     to invisible on the canopy frames. Over the video it reads cream like every
     other link and is marked out by a hairline underline instead of by colour,
     so it survives a bright-water frame and a colour-blind visitor equally.
     The moment the bar is stuck on cream the green comes back: it already
     passes there, and the underline would then be redundant. */
  .nav:not(.nav--solid):not(.stuck):not(.menu-open) .nav-links .nav-hot{
    color:var(--cream);
    text-decoration:underline;
    text-decoration-thickness:1px;
    text-underline-offset:5px;
    text-decoration-color:rgba(247,244,236,.8);
  }
  .nav:not(.nav--solid):not(.stuck):not(.menu-open) .nav-links .nav-hot:hover{
    color:var(--cream);
    text-decoration-color:var(--cream);
  }
}

/* width:auto and padding:0 are not decoration. quote.html styles the bare
   element selector with button{width:100%;padding:16px} for its form submit,
   which stretched the burger to 184x54. Reset them explicitly here. */
.burger{
  display:none;background:none;border:0;font-size:22px;cursor:pointer;color:inherit;
  width:auto;padding:0;margin:0;
  min-width:44px;min-height:44px;line-height:1;
}

/* ---------- buttons: one style, 2px radius ---------- */

.btn{
  font-family:'Archivo';font-size:14px;font-weight:700;letter-spacing:.03em;
  padding:16px 30px;text-decoration:none;display:inline-block;border:0;cursor:pointer;
  border-radius:2px;transition:transform .2s,background .2s,color .2s;
}
.btn-solid{background:var(--wire);color:var(--cream)}
.btn-solid:hover{background:var(--willow);transform:translateY(-2px)}
.btn-line{border:1px solid var(--wire);color:var(--ink);background:transparent}
.btn-line:hover{background:var(--wire);color:var(--cream);transform:translateY(-2px)}

/* The inner pages carry their own button classes. Normalise the corner and the
   padding without touching their colour, so nothing changes meaning. */
.au-btn,.btn2,.cta,.bigbtn,button,input[type="submit"],input[type="button"]{border-radius:2px}
.au-btn,.btn2,.cta,.bigbtn{padding:16px 30px}

/* ---------- tel: links get a real touch target ---------- */

a[href^="tel:"]{display:inline-flex;align-items:center;min-height:44px}

/* ---------- footer ---------- */

.foot{background:var(--wire);color:var(--cream);padding:56px 0 44px;margin-top:auto}
.foot-in{display:flex;justify-content:space-between;gap:30px;flex-wrap:wrap;align-items:flex-start}
.foot p{margin:0;font-size:14.5px;color:rgba(247,244,236,.65);line-height:1.75}
.foot b{font-family:'Archivo';font-weight:900;font-size:13px;letter-spacing:.13em;color:var(--cream)}
.foot .fb{display:flex;gap:10px}
.foot .fb a{
  font-family:'Archivo';font-size:13px;font-weight:700;padding:13px 24px;
  text-decoration:none;border-radius:2px;
  display:inline-flex;align-items:center;min-height:44px;
  /* same motion vocabulary as every other button on the site */
  transition:transform .35s cubic-bezier(.16,.8,.3,1),
             background-color .35s cubic-bezier(.16,.8,.3,1),
             border-color .35s cubic-bezier(.16,.8,.3,1),
             box-shadow .35s cubic-bezier(.16,.8,.3,1);
}
.foot .fb a:hover{transform:translateY(-2px)}
.foot .fb a:active{transform:translateY(0)}
.foot .f1{background:var(--cream);color:var(--wire)}
.foot .f1:hover{background:var(--willow);color:var(--cream);box-shadow:0 8px 20px -8px rgba(0,0,0,.5)}
.foot .f2{border:1px solid rgba(247,244,236,.35);color:var(--cream)}
.foot .f2:hover{border-color:var(--cream);background:rgba(247,244,236,.08)}
@media (prefers-reduced-motion:reduce){
  .foot .fb a{transition:none}
  .foot .fb a:hover{transform:none}
}

/* Privacy and Terms. Deliberately quiet: they sit as the last line of the
   footer address block rather than as buttons, because nobody is looking for
   them until they are, and the two .fb buttons are the ones that earn money.
   Excluded from the .f1/.f2 button styling and from main's drawing underline,
   so they need their own colour. */
.foot .fl{
  font-family:'Archivo';font-size:12.5px;font-weight:600;letter-spacing:.06em;
  color:rgba(247,244,236,.55);text-decoration:underline;text-underline-offset:3px;
  text-decoration-color:rgba(247,244,236,.28);
}
.foot .fl:hover,.foot .fl:focus-visible{color:var(--cream);text-decoration-color:var(--cream)}

/* thanks.html and 404.html centre a single card on the body itself, which
   leaves nowhere for a nav or a footer to sit. Body becomes a column, the card
   keeps its own centring inside. No copy moves. */
body.stub{display:flex;flex-direction:column;min-height:100svh;padding:0;text-align:center}
body.stub .stub-main{flex:1;display:flex;align-items:center;justify-content:center;padding:22px}
body.stub .card{background:#fff;border:1px solid var(--rule);border-radius:2px}

/* Between the mobile breakpoint and roughly 940px the desktop nav does not fit:
   nine links measure 638px, the brand takes ~200px, and 32px of padding either
   side puts the right edge at 776px inside a 768px viewport. The homepage has
   the same problem but hides it, because its nav is position:fixed and clipped
   by overflow-x:hidden, so it silently cuts off "Get a quote" instead. Rather
   than move the breakpoint away from the homepage's 760px, tighten the metrics
   across that band so the row fits. Same markup, same breakpoint, no clipping.
   Upper bound raised 940 -> 1023 when the nav label went back to "Client Login".
   At 92px instead of 42px the links row measures 689px, which moves the
   collision point from ~952 up to ~1005. */
@media (min-width:761px) and (max-width:1120px){ .nav-links a.nav-tel{display:none} }
@media (min-width:761px) and (max-width:1023px){
  .nav--solid{padding:12px 18px}
  .nav-links{gap:11px}
  .nav-links a{font-size:10px;letter-spacing:.05em}
  .nav-cta{padding:9px 13px}
  .brand b{font-size:11px;letter-spacing:.08em}
}

@media (max-width:760px){
  body{font-size:17px}
  .wrap{padding:0 22px}
  .nav-links{
    position:fixed;top:0;left:0;right:0;flex-direction:column;gap:0;
    padding:74px 22px 22px;background:var(--cream);border-bottom:1px solid var(--rule);
    transform:translateY(-102%);transition:transform .4s cubic-bezier(.16,.8,.3,1),visibility 0s .4s;
    visibility:hidden;   /* closed links leave the tab order */
  }
  .nav-links.open{transform:none;visibility:visible;transition-delay:0s}
  .nav-links a{
    width:100%;padding:15px 0;border-bottom:1px solid var(--rule);
    font-size:13px;color:var(--ink);min-height:44px;display:flex;align-items:center;
  }
  .nav-links .nav-cta{background:var(--wire);color:var(--cream)}
  .nav-cta{text-align:center;margin-top:14px;border-bottom:0!important;justify-content:center}
  .burger{display:block;z-index:90}
  .foot-in{flex-direction:column;align-items:stretch}
  .foot .fb{flex-wrap:wrap;width:100%}
  .foot .fb a{flex:1 1 auto;min-width:130px;text-align:center;justify-content:center}
}

/* ===========================================================================
   POLISH LAYER
   Lifted from index.html so it runs on every page instead of one. The numbers
   here are the homepage's numbers, not new guesses.
   =========================================================================== */

/* ---------- one easing curve, one duration scale ---------- */
:root{
  --ease:cubic-bezier(.16,.8,.3,1);   /* the homepage reveal curve */
  --ease-exit:cubic-bezier(.4,0,1,1);
  --ease-enter:cubic-bezier(0,0,.2,1);
  --dur-1:.18s;   /* colour, small state changes */
  --dur-2:.32s;   /* movement, underlines */
  --dur-3:.8s;    /* reveals */
}

/* ---------- view transitions ---------- */
@view-transition{ navigation: auto; }
::view-transition-old(root){ animation: vt-out .28s var(--ease-exit) both; }
::view-transition-new(root){ animation: vt-in .42s var(--ease-enter) both; }
@keyframes vt-out{ to{ opacity:0; transform:translateY(-8px); } }
@keyframes vt-in{ from{ opacity:0; transform:translateY(10px); } }
/* named so the chrome persists across navigation instead of redrawing */
.nav{view-transition-name:sitenav}
.foot{view-transition-name:sitefoot}

/* ---------- micro-detail: one transition on everything interactive ---------- */
a,button,.btn,.nav-cta,.au-btn,.btn2,.cta,
.price-row,ul.tasks li,.call,.stat,.prob,.fb a{
  transition:
    color var(--dur-1) var(--ease),
    background-color var(--dur-1) var(--ease),
    border-color var(--dur-1) var(--ease),
    transform var(--dur-2) var(--ease);
}
.price-row:hover{background:rgba(95,130,102,.055)}
ul.tasks li:hover{background:rgba(95,130,102,.045)}
.stat:hover,.prob:hover{border-color:var(--willow)}

/* Focus ring: visible, on-brand, and never clipped by a tight parent. */
:focus-visible{
  outline:2px solid var(--willow-ink);
  outline-offset:3px;
  border-radius:2px;
}
.nav :focus-visible,.foot :focus-visible{outline-color:var(--sky)}

/* Underlines that draw. A faint rule stays at rest so links are still
   identifiable without hover, then a solid willow one wipes across. */
main a:not(.btn):not(.nav-cta):not(.au-btn):not(.f1):not(.f2){
  text-decoration:underline;
  text-decoration-color:rgba(95,130,102,.38);
  text-underline-offset:4px;
  background-image:linear-gradient(var(--willow-ink),var(--willow-ink));
  background-repeat:no-repeat;
  background-position:0 calc(100% - 1px);
  background-size:0% 2px;
  transition:background-size var(--dur-2) var(--ease),text-decoration-color var(--dur-1) var(--ease);
}
main a:not(.btn):not(.nav-cta):not(.au-btn):not(.f1):not(.f2):hover,
main a:not(.btn):not(.nav-cta):not(.au-btn):not(.f1):not(.f2):focus-visible{
  background-size:100% 2px;
  text-decoration-color:transparent;
}

/* Hairlines. The inner pages drew 3px double taupe rules, which read as a
   different system to the homepage's 1px --rule. Unify, and pull the list
   dividers out to the text edge so they line up optically with the copy
   rather than with the padding box. */
header.page,header.rz-hero,header.rep-hero,header.au-hero,.cta-band,nav{
  border-color:var(--rule)!important;
}
header.page,header.rz-hero,header.rep-hero,header.au-hero{
  border-bottom:1px solid var(--rule)!important;
}
.cta-band{border-top:1px solid var(--rule)!important}
ul.tasks li{border-bottom:1px solid var(--rule)}
ul.tasks li::before{left:0}
ul.tasks li{padding-left:24px}

/* ---------- reveals, inverted so they fail visible ----------
   Default is visible. wcg-nav.js stamps html.js-reveal on first run, which is
   what hides them; the observer then adds .in. No script, no hiding, page
   reads in full. This replaces the old opacity:0-by-default plus <noscript>
   patch, which left 38/40/23 blocks blank whenever the script did not run. */
.rv{
  opacity:1;transform:none;
  transition:opacity var(--dur-3) var(--ease),transform var(--dur-3) var(--ease);
}
/* .pre is added by the script, per element, and removed to reveal. An element
   level class rather than an ancestor rule, so there is exactly one thing to
   look at when this misbehaves. */
.rv.pre{opacity:0;transform:translateY(24px)}

/* ---------- magnetic buttons ---------- */
.btn,.nav-cta,.au-btn,.btn2{will-change:transform}



@media (prefers-reduced-motion:reduce){
  ::view-transition-old(root),::view-transition-new(root){animation:none!important}
  *{animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important}
  /* content stays visible even if the hiding class was applied */
  .rv.pre{opacity:1!important;transform:none!important}

  html{scroll-behavior:auto}
}


/* ===================================================================
   Site audit, 2026-08-29. Three classes of defect found across the
   thirteen pages that share this stylesheet.
   =================================================================== */

/* --- 1. tap targets ---
   The brand lockup was a 179x23 hit area and the nav links were 17-25px tall,
   on a site whose visitors are largely on a phone on a job site. */
.brand{ padding-block:11px; }
.nav-links a{ display:inline-flex; align-items:center; min-height:44px; }
.nav-links .nav-cta{ min-height:44px; }
.burger{ min-width:44px; min-height:44px; }

/* --- 2. --willow as TEXT ---
   #5F8266 on cream is 3.92:1, under the AA floor for body sizes. CLAUDE.md
   already solved this once: --willow-ink is the same hue at 5.3:1. --willow
   stays correct as a FILL. */
.label,
.rep-kick,
h3.willow,
.nav-links .nav-hot{ color:var(--willow-ink); }

/* --- 3. muted greys ---
   #8B877C measured 3.26:1 and #9A9484 measured 2.75:1 on cream. Same
   intention, taken to 5.2:1. */
.muted,.line.muted,.rz-cap,.sub-muted{ color:#6F6A5E; }

/* Footer links were 25px tall. They live in .px-foot__links (px-inner.css),
   not .foot/.footer, which is why the first attempt missed them.
   Inline links inside a sentence are deliberately NOT padded: WCAG exempts
   them, and padding them breaks the line rhythm of body copy. */
.px-foot__links a{ display:inline-flex; align-items:center; min-height:44px; }

/* FAQ accordions were a 27px hit area on the one page that uses them */
summary{ min-height:44px; display:flex; align-items:center; }

/* White on --willow measures 4.31:1, just under the 4.5 floor for button text.
   --willow-ink is the same hue at 5.3:1, which is what CLAUDE.md already
   established for willow carrying text. --willow stays right as a FILL. */
.btn,.dl,a.btn,button.btn{ background:var(--willow-ink); }


/* The footer contact links were 19px tall on a phone. They are inline inside a
   prose paragraph, so the padding is cancelled by an equal negative margin:
   the hit area grows to 44px, the line box does not move. */
.px-foot__addr a,
.px-foot__addr a[href^="mailto:"],
.px-foot__addr a[href^="tel:"]{
  display:inline-block;
  padding-block:12px;
  margin-block:-12px;
}

/* ---------- Messenger button ----------
   Same button as the homepage, different z-index because this page system has a
   different stack: .nav is z-index 80, so 79 puts the button UNDER it and the
   open mobile menu covers it with no :has() and no JS. */
.msgr{
  position:fixed; right:20px; bottom:20px; z-index:79;
  width:56px; height:56px; border-radius:2px;
  display:grid; place-items:center;
  background:var(--wire); color:var(--cream);
  border:1px solid rgba(247,244,236,.14);
  box-shadow:0 12px 28px -12px rgba(0,0,0,.45);
  transition:transform .18s ease, background .18s ease, border-color .18s ease;
}
.msgr svg{ width:26px; height:26px; fill:currentColor; display:block; }
.msgr:hover{ background:var(--willow-ink); border-color:var(--willow); transform:translateY(-2px); }
.msgr:focus-visible{ outline:2px solid var(--willow-ink); outline-offset:3px; }
@media (max-width:600px){
  .msgr{ right:14px; bottom:14px; width:50px; height:50px; }
  .msgr svg{ width:23px; height:23px; }
}
@media (prefers-reduced-motion:reduce){
  .msgr{ transition:none; }
  .msgr:hover{ transform:none; }
}
