/* Clear Class Cleaning. Palette measured from the flyer (design brief section 2).
   One family, system sans, no web fonts. Tokens carry both themes; nothing below
   sets a color outside a token. */

:root{
  color-scheme: light dark;

  --navy:#0C3C6C;
  --navy-deep:#092c50;
  --blue:#0C90D8;
  --sky:#00B4E4;
  --green:#4A732E;          /* flyer green darkened to clear AA on paper and on --green-bg */
  --green-bg:#EAF4E2;

  --paper:#FBFBFA;
  --surface:#FFFFFF;
  --surface-2:#F2F4F7;
  --line:#D9DEE5;
  --text:#1A1A1A;
  --muted:#4F5864;

  --ink-on-accent:#FFFFFF;
  --accent:var(--navy);
  --link:var(--navy);
  --focus:#00587A;

  /* Fixed in both themes: the logo is navy on white and is never recolored, so it sits on
     a white plate in dark mode; the lightbox is a dark scrim whatever the theme. */
  --plate:#FFFFFF;
  --on-plate:#0C3C6C;
  --scrim:#091420EB;
  --on-scrim:#FFFFFF;

  --radius:14px;
  --radius-sm:10px;
  --radius-full:999px;
  --shadow:0 1px 2px rgba(12,60,108,.06), 0 8px 24px rgba(12,60,108,.07);
  --header-h:64px;
  --wrap:1120px;
  --gap:clamp(18px,3vw,32px);
}

@media (prefers-color-scheme: dark){
  :root{
    --navy:#4F8FE0;
    --navy-deep:#6A9FE6;          /* hover lifts lighter in dark; #3f7ac6 held only 4.28:1 under the dark ink */
    --blue:#54B4EC;
    --sky:#65D2F2;
    --green:#9BD173;
    --green-bg:#1B2A18;

    --paper:#101820;
    --surface:#16202A;
    --surface-2:#1D2935;
    --line:#2E3C49;
    --text:#ECECEC;
    --muted:#AAB6C2;

    --ink-on-accent:#08131F;
    --accent:#4F8FE0;
    --link:#7FB6EE;
    --focus:#65D2F2;
    --shadow:0 1px 2px rgba(0,0,0,.4), 0 8px 24px rgba(0,0,0,.35);
  }
}

*,*::before,*::after{box-sizing:border-box}

html{scroll-padding-top:calc(var(--header-h) + 12px)}

body{
  margin:0;
  background:var(--paper);
  color:var(--text);
  font:17px/1.55 -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
  -webkit-text-size-adjust:100%;
}
@media (min-width:768px){ body{font-size:18px} }

img{max-width:100%;height:auto}

h1,h2,h3{line-height:1.15;font-weight:700;text-wrap:balance;margin:0 0 .4em}
h1{font-size:clamp(1.9rem,1.3rem + 2.4vw,3rem);letter-spacing:-.015em;color:var(--navy)}
h2{font-size:clamp(1.35rem,1.1rem + 1vw,1.9rem);letter-spacing:-.01em;color:var(--navy)}
h3{font-size:1.1rem}
p{margin:0 0 1em}
ul,ol{margin:0 0 1em;padding-inline-start:1.25em}
li{margin:.3em 0}

a{color:var(--link);text-underline-offset:.16em}
a:hover{text-decoration-thickness:2px}

:focus-visible{outline:3px solid var(--focus);outline-offset:2px;border-radius:4px}

.wrap{max-width:var(--wrap);margin:0 auto;padding:0 20px}
.narrow{max-width:760px}

.skip{position:absolute;inset-inline-start:-9999px;top:0;z-index:100;background:var(--surface);color:var(--link);padding:12px 18px;border-radius:0 0 var(--radius-sm) 0;font-weight:700}
.skip:focus{inset-inline-start:0}

/* ---------- header ---------- */
.site-header{
  position:sticky;top:0;z-index:50;
  background:var(--surface);
  border-bottom:1px solid var(--line);
}
.header-in{display:flex;align-items:center;gap:16px;min-height:var(--header-h);max-width:var(--wrap);margin:0 auto;padding:8px 20px}
.brand{display:flex;align-items:center;gap:10px;text-decoration:none;flex:0 0 auto}
.brand img.mark{width:34px;height:auto;display:block}
.brand img.wordmark{width:172px;height:auto;display:block}
@media (prefers-color-scheme: dark){
  .brand{background:var(--plate);padding:6px 10px;border-radius:var(--radius-sm)}
}
.site-nav{margin-inline-start:auto;display:flex;align-items:center;gap:4px}
.site-nav a{
  display:inline-flex;align-items:center;min-height:44px;padding:0 12px;
  text-decoration:none;color:var(--text);font-weight:600;font-size:.97rem;border-radius:var(--radius-sm);
}
.site-nav a:hover{background:var(--surface-2)}
.site-nav a[aria-current="page"]{color:var(--navy);box-shadow:inset 0 -3px 0 var(--navy)}
.header-cta{display:flex;align-items:center;gap:8px;flex:0 0 auto}

.nav-toggle{display:none}

@media (max-width:980px){
  .header-in{flex-wrap:wrap;gap:10px}
  .brand img.wordmark{width:148px}
  .nav-toggle{
    display:inline-flex;align-items:center;justify-content:center;gap:8px;
    margin-inline-start:auto;min-height:44px;min-width:44px;padding:0 14px;
    background:var(--surface-2);color:var(--text);border:1px solid var(--line);
    border-radius:var(--radius-sm);font:inherit;font-weight:700;cursor:pointer;
  }
  .site-nav{
    order:3;width:100%;margin-inline-start:0;flex-direction:column;align-items:stretch;gap:2px;
    padding-bottom:10px;
  }
  .site-nav[hidden]{display:none}
  .site-nav a{min-height:48px;padding:0 14px}
  .site-nav a[aria-current="page"]{box-shadow:inset 3px 0 0 var(--navy);background:var(--surface-2)}
  .header-cta .btn.ghost{display:none}
}

/* ---------- buttons ---------- */
.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:8px;
  min-height:46px;padding:0 20px;border-radius:var(--radius-full);
  font:inherit;font-weight:700;text-decoration:none;text-align:center;white-space:nowrap;
  background:var(--accent);color:var(--ink-on-accent);border:2px solid var(--accent);cursor:pointer;
}
.btn:hover{background:var(--navy-deep);border-color:var(--navy-deep)}
.btn.ghost{background:transparent;color:var(--link);border-color:currentColor}
.btn.ghost:hover{background:var(--surface-2)}
.btn.big{min-height:54px;padding:0 28px;font-size:1.05rem}
.btn.block{width:100%}

/* ---------- pills and badges ---------- */
.pill,.badge{
  display:inline-flex;align-items:center;justify-content:center;
  text-align:center;white-space:nowrap;
  border-radius:var(--radius-full);font-weight:700;font-size:.85rem;line-height:1;
  padding:8px 14px;
}
.badge{background:var(--surface);border:1px solid var(--line);color:var(--text)}
.badge.assured{background:var(--green-bg);border-color:transparent;color:var(--green)}
.pill{background:var(--surface-2);color:var(--muted)}
.pill-row{display:flex;flex-wrap:wrap;gap:8px;margin:0 0 1em;padding:0;list-style:none}

/* ---------- sections ---------- */
.section{padding:clamp(40px,6vw,72px) 0;border-top:1px solid var(--line)}
.section:first-of-type{border-top:0}
.section-head{max-width:720px;margin:0 0 clamp(20px,3vw,34px)}
.section-head p{color:var(--muted);margin:0}
.eyebrow{display:block;text-transform:uppercase;letter-spacing:.09em;font-size:.78rem;font-weight:700;color:var(--muted);margin:0 0 .6em}

/* ---------- hero ---------- */
.hero{padding:clamp(28px,5vw,56px) 0 clamp(32px,5vw,60px)}
.hero-grid{display:grid;gap:var(--gap);align-items:start}
@media (min-width:900px){ .hero-grid{grid-template-columns:1.05fr .95fr} }
.hero p.lede{font-size:clamp(1.05rem,1rem + .5vw,1.25rem);color:var(--muted);max-width:44ch}
.hero-photo{border-radius:var(--radius);box-shadow:var(--shadow);display:block;width:100%}

/* ---------- cards ---------- */
.grid{display:grid;gap:var(--gap)}
@media (min-width:640px){ .grid.two{grid-template-columns:repeat(2,1fr)} }
/* Order matters: the 640 rule comes first so the 900 rule can win above 900px. */
@media (min-width:640px){ .grid.three{grid-template-columns:repeat(2,1fr)} }
@media (min-width:900px){ .grid.three{grid-template-columns:repeat(3,1fr)} }

figure.card{margin:0}
.card{
  background:var(--surface);border:1px solid var(--line);border-radius:var(--radius);
  padding:clamp(18px,2.4vw,26px);display:flex;flex-direction:column;gap:10px;
}
.card h3{margin:0;color:var(--navy)}
.card p{margin:0;color:var(--muted)}
.card .card-link{margin-top:auto;padding-top:6px;font-weight:700;text-decoration:none}
.card .card-link::after{content:" \203A"}
[dir="rtl"] .card .card-link::after{content:" \2039"}

.step{display:flex;gap:14px;align-items:flex-start}
.step-n{
  flex:0 0 auto;width:34px;height:34px;border-radius:50%;
  background:var(--navy);color:var(--ink-on-accent);
  display:inline-flex;align-items:center;justify-content:center;font-weight:700;
}

.checklist{list-style:none;padding:0;margin:0}
.checklist li{position:relative;padding-inline-start:1.7em;margin:.45em 0}
.checklist li::before{content:"";position:absolute;inset-inline-start:.15em;top:.5em;width:.5em;height:.9em;border:solid var(--green);border-width:0 3px 3px 0;transform:rotate(45deg)}

/* ---------- forms ---------- */
.form{background:var(--surface);border:1px solid var(--line);border-radius:var(--radius);padding:clamp(18px,2.6vw,28px);box-shadow:var(--shadow)}
.field{margin:0 0 16px}
.field label{display:block;font-weight:700;margin:0 0 6px;font-size:.95rem}
.field .hint{display:block;font-weight:400;color:var(--muted);font-size:.87rem;margin-top:2px}
.field input,.field select,.field textarea{
  width:100%;min-height:46px;padding:11px 13px;
  background:var(--paper);color:var(--text);
  border:1px solid var(--line);border-radius:var(--radius-sm);
  font:inherit;
}
.field textarea{min-height:110px;resize:vertical}
.field input:focus-visible,.field select:focus-visible,.field textarea:focus-visible{outline:3px solid var(--focus);outline-offset:1px}
.field-row{display:grid;gap:14px;align-items:end;margin:0 0 16px}
.field-row .field{margin-bottom:0}
@media (min-width:560px){ .field-row.two{grid-template-columns:1fr 1fr} }
.choices{display:flex;flex-wrap:wrap;gap:8px;margin:0;padding:0;border:0}
.choices legend{font-weight:700;margin:0 0 6px;padding:0;font-size:.95rem}
.choice{position:relative}
.choice input{position:absolute;opacity:0;width:100%;height:100%;margin:0;cursor:pointer}
.choice span{
  display:inline-flex;align-items:center;justify-content:center;min-height:44px;padding:0 16px;
  border:1px solid var(--line);border-radius:var(--radius-full);background:var(--surface);
  font-weight:600;white-space:nowrap;text-align:center;
}
.choice input:checked + span{background:var(--navy);border-color:var(--navy);color:var(--ink-on-accent)}
.choice input:focus-visible + span{outline:3px solid var(--focus);outline-offset:2px}
.hp{position:absolute;inset-inline-start:-9999px;width:1px;height:1px;overflow:hidden}

.form-note{color:var(--muted);font-size:.9rem;margin:10px 0 0}
.result{margin:16px 0 0;padding:16px;border-radius:var(--radius-sm);background:var(--surface-2);border:1px solid var(--line)}
.result[hidden]{display:none}
.result .figure{font-size:1.5rem;font-weight:700;color:var(--navy);display:block;margin:0 0 4px}
.status{margin:14px 0 0;padding:12px 14px;border-radius:var(--radius-sm);font-weight:600}
.status[hidden]{display:none}
.status.ok{background:var(--green-bg);color:var(--green)}
.status.err{background:var(--surface-2);color:var(--text);border:1px solid var(--line)}

/* ---------- FAQ ---------- */
.faq details{border:1px solid var(--line);border-radius:var(--radius-sm);background:var(--surface);margin:0 0 10px}
.faq summary{
  cursor:pointer;list-style:none;padding:16px 18px;font-weight:700;
  display:flex;justify-content:space-between;align-items:center;gap:12px;min-height:44px;
}
.faq summary::-webkit-details-marker{display:none}
.faq summary::after{content:"+";font-size:1.4rem;line-height:1;color:var(--navy);flex:0 0 auto}
.faq details[open] summary::after{content:"\2013"}
.faq .answer{padding:0 18px 16px;color:var(--muted)}
.faq .answer p:last-child{margin-bottom:0}

/* ---------- reviews ---------- */
.review{background:var(--surface);border:1px solid var(--line);border-radius:var(--radius);padding:20px}
.review .stars{color:var(--green);font-weight:700;letter-spacing:.1em}
.review .who{color:var(--muted);font-size:.9rem;margin:10px 0 0}

/* ---------- callout ---------- */
.callout{background:var(--surface-2);border:1px solid var(--line);border-inline-start:4px solid var(--navy);border-radius:var(--radius-sm);padding:18px 20px}
.callout :last-child{margin-bottom:0}

/* ---------- footer ---------- */
.site-footer{border-top:1px solid var(--line);background:var(--surface);padding:clamp(32px,5vw,52px) 0;margin-top:clamp(40px,6vw,72px)}
.footer-grid{display:grid;gap:var(--gap)}
@media (min-width:760px){ .footer-grid{grid-template-columns:1.4fr 1fr 1fr} }
.site-footer h2{font-size:.86rem;text-transform:uppercase;letter-spacing:.09em;color:var(--muted)}
.site-footer ul{list-style:none;padding:0;margin:0}
.site-footer li{margin:.4em 0}
/* :not(.btn) matters. Without it this rule (0,1,1) outranks .btn (0,1,0) and paints
   the footer's "Get a quote" in body ink on the navy pill: 1.56:1, unreadable. Caught on
   a real iPhone 2026-09-17, not by the palette check, which tested the tokens I meant to
   use rather than the color that actually rendered. check_contrast.py now tests the latter. */
.site-footer a:not(.btn){color:var(--text);text-decoration:none}
.site-footer a:not(.btn):hover{text-decoration:underline}
/* A link inside running text cannot be signalled by color alone (WCAG 1.4.1). The rule
   above suits the standalone link lists; in the legal sentence the links sat at 1.74:1
   against the surrounding muted text with no underline, so they were invisible as links.
   axe-core, 2026-09-18. */
.site-footer .legal a:not(.btn){text-decoration:underline;text-underline-offset:.16em}
.legal{margin-top:28px;padding-top:20px;border-top:1px solid var(--line);color:var(--muted);font-size:.88rem}

/* ---------- mobile call bar ---------- */
.callbar{
  position:fixed;inset-inline:0;bottom:0;z-index:60;
  display:none;gap:10px;padding:10px 14px calc(10px + env(safe-area-inset-bottom));
  background:var(--surface);border-top:1px solid var(--line);
}
.callbar .btn{flex:1 1 0;min-height:48px}
@media (max-width:780px){
  .callbar{display:flex}
  body{padding-bottom:84px}
}

/* ---------- utility ---------- */
.muted{color:var(--muted)}
.center{text-align:center}
.stack-sm > * + *{margin-top:10px}
.cta-row{display:flex;flex-wrap:wrap;gap:12px;margin:1.4em 0 0}
.visually-hidden{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}

@media (prefers-reduced-motion: reduce){
  *,*::before,*::after{animation-duration:.001ms !important;animation-iteration-count:1 !important;transition-duration:.001ms !important;scroll-behavior:auto !important}
}
.cta-row.center-row{justify-content:center}

/* Service chips: what we clean, at a glance, where the hero photo will go. */
.chip-list{display:flex;flex-wrap:wrap;gap:8px;list-style:none;padding:0;margin:1.6em 0 0}
.chip-list a{
  display:inline-flex;align-items:center;min-height:40px;padding:0 14px;
  border:1px solid var(--line);border-radius:var(--radius-full);background:var(--surface);
  text-decoration:none;color:var(--text);font-weight:600;font-size:.92rem;white-space:nowrap;text-align:center;
}
.chip-list a:hover{border-color:var(--navy);color:var(--navy)}

/* Grid and flex children default to min-width:auto, so a wide child (a select whose
   longest option is "Recurring home cleaning") can stretch its track past the screen.
   Measured clean at 500 px on 2026-09-17; these keep it that way as content grows. */
.grid > *,
.hero-grid > *,
.field-row > *,
.footer-grid > *,
.header-in > *,
.step > *{min-width:0}

.form,
.card,
.field select,
.field input,
.field textarea{max-width:100%}

/* ---------- image lightbox (the fleet's one pattern, not a second invention) ----------
   A real <button> wraps the image so it is keyboard operable (WCAG 2.1.1); the overlay is
   role=dialog aria-modal with a visible close, Escape closes, focus returns to the trigger,
   body scroll is locked while open. Built before the photos land so the gallery and the
   before-and-after blocks are zoomable the day Donnell sends them, all of them or none. */
.zoom-trigger{display:block;padding:0;border:0;background:none;cursor:zoom-in;width:100%;border-radius:var(--radius-sm);overflow:hidden}
.zoom-trigger img{display:block;width:100%;height:auto}
.zoom-trigger:focus-visible{outline:3px solid var(--focus);outline-offset:3px}

.lightbox{
  position:fixed;inset:0;z-index:100;
  display:flex;align-items:center;justify-content:center;
  padding:24px;background:var(--scrim);
}
.lightbox[hidden]{display:none}
.lightbox img{max-width:100%;max-height:82vh;width:auto;height:auto;border-radius:var(--radius-sm);background:var(--surface)}
.lightbox figcaption{color:var(--on-scrim);margin-top:12px;text-align:center;font-size:.95rem}
.lb-close{
  position:absolute;top:16px;inset-inline-end:16px;
  min-height:44px;min-width:44px;padding:0 16px;border-radius:var(--radius-full);
  background:var(--plate);color:var(--on-plate);border:0;font:inherit;font-weight:700;cursor:pointer;
}
.lb-close:focus-visible{outline:3px solid var(--on-scrim);outline-offset:3px}
body.lb-open{overflow:hidden}
@media (prefers-reduced-motion: no-preference){
  .lightbox img{animation:lb-in .18s ease-out}
}
@keyframes lb-in{from{opacity:0;transform:scale(.98)}to{opacity:1;transform:none}}
.hero-figure{margin:clamp(20px,2.4vw,30px) 0 0}
.motto{font-style:italic;color:var(--navy);font-weight:600;margin:.6em 0 0}

/* Below 430px the call bar keeps the verb and drops the digits, so a longer word in
   another language cannot clip the most-tapped control on the site. The link's
   aria-label still carries the full number. */
@media (max-width:430px){ .cb-num{display:none} }

/* The owners' portrait is 771px native, so it is capped well below the text column rather
   than stretched across it. A soft, upscaled photograph of the people you are hiring does
   the opposite of what the photograph is there for. */
.about-portrait{max-width:320px;margin:0 0 1.6em}
.about-portrait img{border-radius:var(--radius);display:block;width:100%;height:auto}
/* Floated beside the opening prose, not cleared by headings. Clearing was tried and made it
   worse: the About page leads with an h2, so every heading dropped below the photograph and
   the float became dead space with the whole article underneath it. A smaller portrait
   releases the text sooner, which is the real fix for an awkward wrap. */
@media (min-width:700px){ .about-portrait{float:inline-start;margin-inline-end:26px;max-width:290px} }
