/* ─────────────────────────────────────────────────────────────
   SAYLOR DETAILING · saylordetailing.com
   One page, phone first, built to book. White, black, Geist.
   Hero: the ring of Sam's cars turns around the copy, and the first
   screen carries both prices and a Book button in thumb reach.
   Every Book button opens the booking sheet (see BOOKING in the script),
   and every Leave a review button opens the review sheet (see REVIEW).
   Text fades in as sections arrive; the cars roll left to right with
   the scroll. No 3D library, no chromatic smear, no streaks.
   ───────────────────────────────────────────────────────────── */
@font-face{font-family:'Geist';font-style:normal;font-weight:100 900;font-display:swap;src:url('/_shared/fonts/Geist-Variable.woff2') format('woff2')}
:root{
  --bg:#FFFFFF; --ground:#F5F5F7; --ink:#1D1D1F; --ink-2:#6E6E73; --hair:#E5E5EA; --blue:#0077CC; --brand:#0091FA; --red:#D70015;
  --font:'Geist',-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,'Helvetica Neue',Arial,sans-serif;
  --gut:clamp(20px,5vw,48px); --ease:cubic-bezier(.22,1,.36,1); --r:28px;
}
*,*::before,*::after{box-sizing:border-box}
*{margin:0;padding:0}
html{-webkit-text-size-adjust:100%;text-size-adjust:100%;-webkit-tap-highlight-color:transparent;scroll-behavior:smooth;scroll-padding-top:72px;scrollbar-gutter:stable}
html.lock{overflow:hidden}
html.lock body{position:fixed;left:0;right:0}
body{background:var(--bg);color:var(--ink);font:400 17px/1.5 var(--font);letter-spacing:-.01em;-webkit-font-smoothing:antialiased;overflow-x:clip}
img,video{display:block;max-width:100%}
picture{display:block}
a{color:inherit}
button{font:inherit;color:inherit;background:none;border:0;cursor:pointer;text-align:inherit}
:focus-visible{outline:2px solid var(--ink);outline-offset:3px}
.sr{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}
svg.ico{width:16px;height:16px;flex:none}
[hidden]{display:none!important}

.pill{display:inline-flex;align-items:center;justify-content:center;gap:8px;min-height:48px;padding:0 24px;border-radius:999px;background:var(--ink);color:#fff;font-weight:600;font-size:16px;letter-spacing:-.01em;line-height:1;text-decoration:none;white-space:nowrap;transition:transform .3s var(--ease),background-color .2s}
.pill{background:var(--blue)}.pill:hover{background:#0068B3}
.pill:active{transform:scale(.97)}
.pill.sm{min-height:40px;padding:0 18px;font-size:15px}
.pill.lg{min-height:56px;padding:0 32px;font-size:17px}
.pill.block{display:flex;width:100%}
.pill.ghost{background:var(--ground);color:var(--ink)}
.pill.ghost:hover{background:var(--hair)}
.pill.white{background:#fff;color:var(--ink)}
.pill.white:hover{background:#ECECEF}
.pill.clear{background:rgba(255,255,255,.14);color:#fff}
.pill.clear:hover{background:rgba(255,255,255,.22)}

/* nav */
.nav{position:fixed;inset:0 0 auto;z-index:30;display:flex;justify-content:space-between;align-items:center;padding:calc(10px + env(safe-area-inset-top,0px)) var(--gut) 10px;transition:background-color .3s,box-shadow .3s}
.nav.solid{background:rgba(255,255,255,.84);-webkit-backdrop-filter:saturate(180%) blur(18px);backdrop-filter:saturate(180%) blur(18px);box-shadow:0 1px 0 var(--hair)}
.mark{font-weight:700;font-size:19px;letter-spacing:-.035em;line-height:1;text-decoration:none}
.mark svg{display:block;height:19px;width:auto;color:var(--ink)}@media(min-width:820px){.mark svg{height:22px}}.mark small{display:block;font-weight:500;font-size:11px;letter-spacing:.01em;color:var(--ink-2);margin-top:4px}

/* hero */
.hero{position:relative;min-height:100vh;min-height:100svh;display:grid;grid-template-rows:1fr auto;padding:calc(74px + env(safe-area-inset-top,0px)) var(--gut) calc(18px + env(safe-area-inset-bottom,0px));overflow:hidden;isolation:isolate}
.ring{position:absolute;inset:0;z-index:-1;pointer-events:none}
.orb{position:absolute;left:0;top:0;cursor:pointer;width:var(--d,72px);height:var(--d,72px);border-radius:50%;overflow:hidden;opacity:0;background:var(--ground);will-change:transform,opacity;transform-origin:50% 50%}
.orb picture,.orb img{width:100%;height:100%;object-fit:cover}
.hero-copy{align-self:center;display:grid;justify-items:center;text-align:center}
.faces{display:inline-flex;align-items:center;gap:10px;padding:4px 14px 4px 4px;margin-bottom:20px;border-radius:999px;background:var(--ground);font-size:14px;font-weight:600;letter-spacing:-.01em;transition:background-color .2s}
.faces:hover{background:var(--hair)}
.face{position:relative;width:40px;height:40px;border-radius:50%;overflow:hidden;background:var(--hair);flex:none}
.face picture,.face img,.face video{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.face video{opacity:0;transition:opacity .6s}
.face.live video{opacity:1}
h1{font-weight:600;font-size:clamp(46px,12.4vw,96px);line-height:.98;letter-spacing:-.05em;text-wrap:balance}
.hero .sub{margin-top:16px;max-width:31ch;color:var(--ink-2);font-size:clamp(17px,4.4vw,21px);line-height:1.42;text-wrap:pretty}
.hero-foot{display:grid;justify-items:center;gap:14px;padding-top:18px}
.price-line{display:flex;flex-wrap:wrap;justify-content:center;gap:2px 16px;font-size:15px;color:var(--ink-2)}
.price-line b{color:var(--ink);font-weight:600}
.hero-foot .pill{width:min(100%,360px)}
@keyframes bloom{from{opacity:0;filter:blur(12px);transform:translateY(12px)}to{opacity:1;filter:none;transform:none}}
.bloom{animation:bloom .9s var(--ease) both}
.bloom.d1{animation-delay:.06s}.bloom.d2{animation-delay:.12s}.bloom.d3{animation-delay:.2s}

/* sections */
.sec{padding:clamp(64px,11vw,128px) var(--gut)}
.sec.ground{background:var(--ground)}
.wrap{max-width:1120px;margin-inline:auto}
.eyebrow{font-size:13px;font-weight:600;letter-spacing:.01em;color:var(--ink-2);margin-bottom:10px}
h2{font-weight:600;font-size:clamp(36px,9vw,58px);line-height:1.02;letter-spacing:-.045em;text-wrap:balance}
h3{font-weight:600;font-size:22px;line-height:1.2;letter-spacing:-.025em;text-wrap:balance}
.lede{margin-top:14px;color:var(--ink-2);font-size:clamp(17px,2vw,19px);max-width:36ch;text-wrap:pretty}
html.js .reveal{opacity:0;transform:translateY(18px);filter:blur(10px);transition:opacity 1s var(--ease),transform 1s var(--ease),filter 1s var(--ease)}
html.js .reveal-m{opacity:0;transform:translateY(28px);transition:opacity 1s var(--ease),transform 1s var(--ease)}
html.js .reveal.on,html.js .reveal-m.on{opacity:1;transform:none;filter:none}

/* the wash */
.cards{display:grid;gap:14px}
.card{position:relative;overflow:hidden;background:var(--bg);border-radius:var(--r);padding:clamp(26px,5vw,48px)}
.card.media{padding:0;aspect-ratio:4/5;background:#dcdcdf}
.card.media picture,.card.media img{width:100%;height:100%;object-fit:cover}
.checks{list-style:none;margin-top:26px;display:grid;gap:14px}
.checks li{display:flex;align-items:center;gap:14px;font-size:17px;line-height:1.3}
.checks li::before{content:"";flex:none;width:24px;height:24px;border-radius:50%;background:var(--brand) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M7 12.5l3.2 3.2L17 9' fill='none' stroke='white' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center/100% no-repeat}
.prices{display:grid;grid-template-columns:repeat(3,1fr);gap:12px;margin-top:30px;padding-top:26px;border-top:1px solid var(--hair)}
.prices b{display:block;font-weight:600;font-size:clamp(30px,7.8vw,46px);line-height:1;letter-spacing:-.045em}
.prices span{display:block;margin-top:8px;font-size:15px;color:var(--ink-2)}
.prices small{display:block;margin-bottom:6px;font-size:15px;font-weight:500;color:var(--ink-2)}
.band{background:var(--ink);color:#fff;border-radius:var(--r);padding:clamp(40px,8vw,76px) clamp(24px,5vw,48px);text-align:center}
.band p{margin:14px auto 0;max-width:34ch;color:rgba(255,255,255,.72);text-wrap:pretty}
.band .btns{display:flex;flex-wrap:wrap;justify-content:center;gap:10px;margin-top:28px}
.band .btns .pill{flex:1 1 230px;max-width:340px}

/* before and after */
.proof{display:grid;gap:22px}
.cmp{position:relative;aspect-ratio:3/4;overflow:hidden;border-radius:22px;background:var(--ground);touch-action:pan-y;user-select:none;-webkit-user-select:none;cursor:ew-resize;--p:50%}
.cmp.wide{aspect-ratio:4/3}
.cmp picture,.cmp img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;pointer-events:none}
.cmp .before{clip-path:inset(0 calc(100% - var(--p)) 0 0)}
.cmp .bar{position:absolute;top:0;bottom:0;left:var(--p);width:2px;margin-left:-1px;background:#fff;box-shadow:0 0 0 .5px rgba(0,0,0,.08);pointer-events:none}
.cmp .bar i{position:absolute;top:50%;left:50%;width:46px;height:46px;margin:-23px 0 0 -23px;border-radius:50%;background:#fff url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M9 7l-5 5 5 5M15 7l5 5-5 5' fill='none' stroke='%231D1D1F' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center/22px no-repeat;box-shadow:0 6px 22px rgba(0,0,0,.22)}
.cmp .tag{position:absolute;top:12px;padding:6px 11px;border-radius:999px;font-size:12px;font-weight:600;line-height:1.2;pointer-events:none}
.cmp .tb{left:12px;background:rgba(29,29,31,.84);color:#fff}
.cmp .ta{right:12px;background:rgba(255,255,255,.92);color:var(--ink)}
.cmp:has(input:focus-visible){outline:2px solid var(--ink);outline-offset:3px}
.chips{display:flex;flex-wrap:wrap;gap:8px}
.chip{min-height:42px;padding:0 16px;border-radius:999px;background:var(--ground);font-size:15px;font-weight:500;transition:background-color .2s,color .2s}
.chip:hover{background:var(--hair)}
.chip[aria-pressed="true"]{background:var(--ink);color:#fff}

/* reviews: Google-style cards on a slow marquee that holds still for a hover, a touch or an open card */
.sec.flush{padding-top:0}
.revs-head{margin-bottom:26px}
.marquee{margin-inline:calc(-1 * var(--gut));overflow:hidden;-webkit-mask-image:linear-gradient(90deg,transparent,#000 6%,#000 94%,transparent);mask-image:linear-gradient(90deg,transparent,#000 6%,#000 94%,transparent)}
.marquee:focus-visible{outline-offset:-2px}
.marquee::-webkit-scrollbar{display:none}
/* two copies of the cards, so sliding one copy's width lands exactly where it started */
.marquee-track{display:flex;width:max-content;animation:marquee var(--dur,80s) linear infinite}
.marquee-track .set{display:flex}
@keyframes marquee{to{transform:translateX(-50%)}}
.marquee.hold .marquee-track,.marquee.reading .marquee-track,.marquee.off .marquee-track,.marquee:focus-visible .marquee-track,.marquee:has(:focus-visible) .marquee-track{animation-play-state:paused}
@media(hover:hover){.marquee:hover .marquee-track{animation-play-state:paused}}
.rev{flex:none;display:flex;flex-direction:column;gap:12px;width:clamp(264px,74vw,320px);margin-right:12px;padding:18px 18px 16px;border-radius:18px;background:var(--ground)}
.rev-top{display:flex;align-items:center;gap:12px}
.ava{flex:none;display:grid;place-items:center;width:40px;height:40px;border-radius:50%;background:var(--c);color:#fff;font-size:18px;font-weight:500;line-height:1}
.rev-who{flex:1;min-width:0}
.rev cite{display:block;overflow:hidden;font-style:normal;font-size:15px;font-weight:600;letter-spacing:-.01em;white-space:nowrap;text-overflow:ellipsis}
.rev-meta{display:flex;align-items:center;gap:8px;margin-top:3px;font-size:13px;color:var(--ink-2)}
.rate{display:flex;gap:1px}
.rate svg{width:14px;height:14px;fill:#FBBC04}
.rate svg.off{fill:var(--hair)}
.g{flex:none;align-self:flex-start;width:20px;height:20px}
.rev p{display:-webkit-box;overflow:hidden;-webkit-box-orient:vertical;-webkit-line-clamp:4;font-size:15px;line-height:1.45;text-wrap:pretty}
.rev.open p{display:block}
/* while one is open, the other cards keep their own height instead of stretching to match it */
.marquee.reading .set{align-items:flex-start}
.more{align-self:flex-start;margin-top:-4px;font-size:14px;font-weight:600;color:var(--ink-2)}
.revs-foot{display:flex;flex-wrap:wrap;align-items:center;gap:14px 20px;margin-top:24px}
.revs-foot .fine{margin:0}

/* Taylor and Sam */
.team{display:grid;gap:30px;align-items:center}
.vid{position:relative;aspect-ratio:4/5;overflow:hidden;border-radius:var(--r);background:#c9d3c6}
.vid video{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.play{position:absolute;left:14px;bottom:14px;display:inline-flex;align-items:center;gap:8px;min-height:44px;padding:0 18px 0 14px;border-radius:999px;background:rgba(255,255,255,.92);color:var(--ink);font-size:15px;font-weight:600;-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);transition:transform .3s var(--ease)}
.play:active{transform:scale(.96)}
.play .stop,.play.on .go{display:none}
.play.on .stop{display:block}
.refer{margin-top:30px;padding-top:26px;border-top:1px solid var(--hair)}
.refer p{margin-top:8px;color:var(--ink-2);max-width:38ch;text-wrap:pretty}
.share{display:flex;flex-wrap:wrap;gap:10px;margin-top:18px}
.refer .fine{margin-top:12px}

/* cars */
.cars-head{margin-bottom:30px}
.rail{overflow-x:auto;overscroll-behavior-x:contain;scroll-behavior:auto;scrollbar-width:none;padding-bottom:4px}
.rail::-webkit-scrollbar{display:none}
.row{display:flex;gap:12px;width:max-content;padding-inline:var(--gut)}
.car{flex:none;width:clamp(170px,46vw,280px);border-radius:22px}
.car picture{aspect-ratio:1;overflow:hidden;border-radius:22px;background:var(--ground)}
.car img{width:100%;height:100%;object-fit:cover;transition:transform .7s var(--ease)}
.car:hover img{transform:scale(1.04)}
.car span{display:block;margin-top:10px;font-size:15px;font-weight:600;letter-spacing:-.015em}
html:not(.drive) .rail{scroll-snap-type:x proximity}
html:not(.drive) .car{scroll-snap-align:center}

/* footer */
.foot{background:var(--ground);padding:clamp(56px,9vw,96px) var(--gut) calc(36px + env(safe-area-inset-bottom,0px))}
.foot-grid{display:grid;gap:34px}
.foot .lede{margin-top:10px}
.foot .lede a{color:var(--ink);text-decoration-color:var(--hair);text-underline-offset:3px}.foot .lede a:hover{text-decoration-color:currentColor}
.foot .pill{margin-top:22px}
.contact{list-style:none}
.contact li+li{border-top:1px solid var(--hair)}
.contact a{display:flex;align-items:center;justify-content:space-between;gap:12px;min-height:54px;font-size:17px;font-weight:500;text-decoration:none}
.contact a span{color:var(--ink-2);font-weight:400;font-size:15px}
.fine{margin-top:26px;font-size:14px;color:var(--ink-2)}
.fine a{color:var(--ink);font-weight:500;white-space:nowrap}

/* dock: phones only, once the hero's button has scrolled away */
.dock{position:fixed;left:10px;right:10px;bottom:calc(10px + env(safe-area-inset-bottom,0px));z-index:25;display:flex;align-items:center;justify-content:space-between;gap:12px;padding:8px 8px 8px 20px;border-radius:999px;background:rgba(255,255,255,.9);-webkit-backdrop-filter:saturate(180%) blur(20px);backdrop-filter:saturate(180%) blur(20px);box-shadow:0 14px 40px -10px rgba(0,0,0,.28),0 0 0 .5px rgba(0,0,0,.08);transform:translateY(calc(100% + 30px));transition:transform .5s var(--ease)}
.dock.on{transform:none}
.dock p{font-size:13px;line-height:1.25;color:var(--ink-2)}
.dock p b{display:block;font-size:15px;font-weight:600;color:var(--ink)}

/* sheets */
dialog.sheet{position:fixed;inset:auto 0 0 0;width:100%;max-width:100%;max-height:92vh;max-height:92svh;margin:0;padding:0;border:0;border-radius:24px 24px 0 0;background:var(--bg);color:var(--ink);box-shadow:0 -20px 60px rgba(0,0,0,.16);overflow:auto;overscroll-behavior:contain;transform:translateY(100%);transition:transform .5s var(--ease)}
dialog.sheet{transition:transform .5s var(--ease),overlay .5s allow-discrete,display .5s allow-discrete}
dialog.sheet[open]{transform:none}
@starting-style{dialog.sheet[open]{transform:translateY(100%)}}
dialog.sheet::backdrop{background:rgba(0,0,0,0);transition:background-color .35s}
dialog.sheet::backdrop{transition:background-color .35s,overlay .5s allow-discrete,display .5s allow-discrete}
dialog.sheet[open]::backdrop{background:rgba(0,0,0,.4)}
@starting-style{dialog.sheet[open]::backdrop{background:rgba(0,0,0,0)}}
.sheet-in{--sp:18px;padding:10px var(--sp) 0}
.grab{width:36px;height:5px;margin:0 auto 10px;border-radius:3px;background:var(--hair)}
.sheet-top{display:flex;justify-content:space-between;align-items:flex-start;gap:12px}
.sheet h2{font-size:30px;letter-spacing:-.04em}
#book-sheet .sheet-top,#rv-sheet .sheet-top{align-items:center}
.x{flex:none;display:grid;place-items:center;width:38px;height:38px;border-radius:50%;background:var(--ground);color:var(--ink-2)}
.x:hover{background:var(--hair)}
.pick{border:0;margin-top:16px}
.pick legend{margin-bottom:8px;font-size:13px;font-weight:600;color:var(--ink-2)}
.opts{display:grid;grid-template-columns:repeat(4,1fr);gap:8px}
.opt{position:relative;display:block}
.opt input{position:absolute;inset:0;width:100%;height:100%;margin:0;opacity:0;cursor:pointer}
.opt span{display:grid;align-content:center;justify-items:center;min-height:44px;padding:10px 4px;border-radius:16px;background:var(--ground);font-size:15px;font-weight:600;line-height:1.2;text-align:center;transition:background-color .2s,color .2s}
.opt svg{width:56px;height:28px;margin-bottom:6px;fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
.opt small{display:block;margin-top:2px;font-size:13px;font-weight:500;color:var(--ink-2);transition:color .2s}
.opt input:checked+span{background:var(--ink);color:#fff;animation:pick .45s var(--ease)}
.opt input:checked+span small{color:rgba(255,255,255,.72)}
/* the motion plays on the pick, not the press: iPhone Safari skips :active on a tap */
@keyframes pick{from{transform:scale(.95)}}
.opt input:focus-visible+span{outline:2px solid var(--ink);outline-offset:2px}
.towns{display:flex;flex-wrap:wrap}
.towns .opt{flex:1 0 auto}
.towns .opt span{padding:0 8px;border-radius:999px;white-space:nowrap}
/* four town names need about 352px; narrower than that they go two and two */
@media(max-width:359px){.towns .opt{flex-basis:40%}}
/* an invisible copy of the longest possible text holds the bubble's height, so picking never moves the buttons */
.msg{display:grid;margin-top:16px}
.msg small{margin-bottom:6px;font-size:13px;font-weight:600;color:var(--ink-2);text-align:right}
.msg p{grid-area:2/1;align-self:start;margin-left:auto;width:fit-content;max-width:88%;padding:10px 14px;border-radius:20px 20px 6px 20px;background:var(--blue);color:#fff;font-size:16px;line-height:1.35}
.msg p[aria-hidden]{visibility:hidden}
.sheet .fine{margin-top:10px;text-align:center}
.shot{overflow:hidden;border-radius:18px;background:var(--ground);aspect-ratio:3/4;margin-top:16px;touch-action:pan-y}
.shot.wide{aspect-ratio:4/3}
.shot picture,.shot img{width:100%;height:100%;object-fit:cover}
#car-body h3{margin:22px 0 10px;font-size:15px;color:var(--ink-2)}
#car-body .cmp+.cmp{margin-top:10px}
.sheet-bar{position:sticky;bottom:0;z-index:2;margin:14px calc(-1 * var(--sp)) 0;padding:14px var(--sp) calc(14px + env(safe-area-inset-bottom,0px));background:linear-gradient(rgba(255,255,255,0),#fff 26%)}
.sheet-nav{display:grid;grid-template-columns:56px 1fr 56px;gap:10px}
.round{display:grid;place-items:center;width:56px;height:56px;border-radius:50%;background:var(--ground);color:var(--ink);transition:background-color .2s}
.round:hover{background:var(--hair)}
.round svg.ico{width:20px;height:20px}
/* review sheet: stars, then Google or a note to Sam; JS shows each part by its data-on states */
.stars{display:grid;grid-template-columns:repeat(5,1fr);min-width:0;margin-top:8px;border:0}
.star{position:relative;display:grid;place-items:center;min-height:56px;color:var(--ink-2);cursor:pointer}
.star input{position:absolute;inset:0;width:100%;height:100%;margin:0;opacity:0;cursor:pointer}
.star svg{width:42px;height:42px;fill:none;stroke:currentColor;stroke-width:1.5;stroke-linejoin:round;transition:fill .2s,color .2s}
.star.on{color:var(--ink)}
.star.on svg{fill:currentColor}
.star input:checked+svg{animation:pop .5s var(--ease)}
@keyframes pop{40%{transform:scale(1.16)}}
.star input:focus-visible+svg{outline:2px solid var(--ink);outline-offset:6px;border-radius:10px}
@media(hover:hover){
  .stars:has(.star:hover) .star{color:var(--ink)}
  .stars:has(.star:hover) .star svg{fill:currentColor}
  .stars .star:hover~.star{color:var(--ink-2)}
  .stars .star:hover~.star svg{fill:none}
}
.rv-say{margin-top:10px;font-size:17px;line-height:1.4;text-wrap:pretty}
#rv-sheet:is([data-state="rate"],[data-state="going"]) .rv-say{margin-top:6px;font-size:15px;color:var(--ink-2);text-align:center}
#rv-sheet:is([data-state="rate"],[data-state="going"]) .sheet-in{padding-bottom:calc(24px + env(safe-area-inset-bottom,0px))}
.rv-step{animation:rise .45s var(--ease)}
@keyframes rise{from{opacity:0;transform:translateY(8px)}}
.field{display:grid;gap:6px;margin-top:12px}
.field span{font-size:13px;font-weight:600;color:var(--ink-2)}
.field i{font-style:normal;font-weight:400}
/* 17px keeps iPhone Safari from zooming in when a field is tapped */
.field input,.field textarea{display:block;width:100%;min-height:48px;padding:12px 14px;border:0;border-radius:14px;background:var(--ground);color:var(--ink);font:inherit;font-size:17px;line-height:1.35;resize:none;-webkit-appearance:none;appearance:none;transition:background-color .2s,box-shadow .2s}
.field textarea{min-height:100px}
.field input:focus,.field textarea:focus{outline:0;background:var(--bg);box-shadow:inset 0 0 0 1.5px var(--ink)}
/* browser autofill paints fields yellow; ours stay the site's light blue instead */
.field input:-webkit-autofill{animation:bk-af .01s}
@keyframes bk-af{from{opacity:1}to{opacity:1}}
.field input:-webkit-autofill,.field input:-webkit-autofill:hover,.field input:-webkit-autofill:focus{-webkit-text-fill-color:var(--ink);-webkit-box-shadow:0 0 0 1000px #EEF5FF inset;box-shadow:0 0 0 1000px #EEF5FF inset;caret-color:var(--ink);transition:background-color 99999s}
/* a field filled in right: light blue, and a check pops in beside it */
.bk-you .field{position:relative}
.bk-you .field input{padding-right:46px}
.bk-you .field.is-ok input:not(:focus){background:#EEF5FF}
.ok-mark{position:absolute;right:13px;bottom:13px;display:grid;place-items:center;width:22px;height:22px;border-radius:50%;background:var(--blue);opacity:0;transform:scale(.4);transition:opacity .2s,transform .35s var(--ease);pointer-events:none}
.ok-mark svg{width:14px;height:14px;fill:none;stroke:#fff;stroke-width:2.2;stroke-linecap:round;stroke-linejoin:round}
.ok-mark path{stroke-dasharray:14;stroke-dashoffset:14;transition:stroke-dashoffset .3s .12s var(--ease)}
.field.is-ok .ok-mark{opacity:1;transform:none}
.field.is-ok .ok-mark path{stroke-dashoffset:0}
@media(prefers-reduced-motion:reduce){.ok-mark,.ok-mark path{transition:none}}
.field [aria-invalid="true"]{box-shadow:inset 0 0 0 1.5px var(--red)}
.rv-err{margin-top:6px;font-size:14px;color:var(--red)}
/* under the button: the bar's top edge fades out, so text above the button would sit on the fields */
.rv-status{font-size:15px;line-height:1.35;text-align:center;text-wrap:pretty}
#rv-sheet[data-state="failed"] .rv-status{margin-top:10px}
.rv-err:empty{margin:0}
.hp{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}
/* live booking steps (the day and time picker itself is _shared/booking-picker.css) */
.bk-back{display:inline-flex;align-items:center;gap:4px;min-height:32px;margin:-4px 0 4px -4px;padding:0 4px;font-size:15px;font-weight:500;color:var(--ink-2)}
.bk-back:hover{color:var(--ink)}
/* booked: the whole screen, a mark, and soap bubbles. data-mark="check" is a black circle with a white check;
   "bubble" is one big soap bubble with the check inside. A burst rises and pops, then a few keep drifting. */
/* phones: the booking sheet is the whole screen, like its own page. The back arrow sits top left in every step
   (from the first it closes the sheet), the phone's own back closes it too, and the X only shows once booked.
   The main button (See open times, Book it) holds the same spot at the bottom of every step; it steps aside
   while the keyboard is up so nothing floats over the keyboard. Car and town are big two-by-two tiles centered
   in the space between the title and the button. */
@media(max-width:819px){
  #book-sheet{inset:0;height:100vh;height:100svh;max-height:100svh;border-radius:0;box-shadow:none}
  #book-sheet .sheet-in{display:flex;flex-direction:column;min-height:100%;padding-top:calc(10px + env(safe-area-inset-top,0px))}
  #book-sheet .grab{display:none}
  #book-sheet:not([data-state="booked"]):not([data-state="cancelled"]) .sheet-top .x{display:none}
  #book-sheet .bk-back{align-self:flex-start;margin-bottom:8px}
  #book-sheet .sheet-bar{margin-top:auto}
  #book-sheet:has(.bk-you input:focus) .sheet-bar{display:none}
  #book-sheet[data-state="pick"] #bk-form{margin:auto 0;padding:12px 0}
  #book-sheet[data-state="text"] #bk-form{margin-top:20px}
  #book-sheet[data-state="pick"] .sheet-bar{margin-top:14px}
  #book-sheet .pick{margin-top:22px}
  #book-sheet .pick:first-child{margin-top:0}
  #book-sheet .pick legend{margin-bottom:10px;font-size:15px}
  #book-sheet .opts{grid-template-columns:repeat(2,1fr);gap:10px}
  #book-sheet .opt span{min-height:60px;border-radius:18px;font-size:17px}
  #book-sheet .opts:not(.towns) .opt span{min-height:118px}
  #book-sheet .opt svg{width:76px;height:38px;margin-bottom:8px}
  #book-sheet .opt small{font-size:14px}
  #book-sheet .towns{display:grid}
  #book-sheet .towns .opt span{padding:0 8px;border-radius:18px}
}
@media(min-width:820px){#book-sheet:is([data-state="pick"],[data-state="text"]) .bk-back{display:none}}
@media(min-width:820px){#book-sheet:is([data-state="booked"],[data-state="sending"]){min-height:min(720px,calc(100svh - 48px))}#book-sheet[data-state="booked"] .bk-bubbles{position:absolute}}
#book-sheet:is([data-state="booked"],[data-state="sending"]) .sheet-in{display:flex;flex-direction:column;min-height:100%;padding-top:calc(16px + env(safe-area-inset-top,0px))}
#book-sheet:is([data-state="booked"],[data-state="sending"]) .grab{visibility:hidden}
#book-sheet:is([data-state="booked"],[data-state="sending"]) .sheet-top{position:relative;z-index:3;justify-content:flex-end}
#book-sheet:is([data-state="booked"],[data-state="sending"]) #bk-h{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%)}
#book-sheet[data-state="booked"] .sheet-bar{margin-top:auto;z-index:3;background:none}
/* Book it tapped: everything else steps away and a small bubble breathes where the big one will be; when the
   booking lands, that same bubble grows into the confirmation (bk-grow) */
#book-sheet[data-state="sending"] .sheet-top,#book-sheet[data-state="sending"] .bk-done > :not(.bk-mark){visibility:hidden}
#book-sheet[data-state="sending"] .sheet-bar{display:none}
#book-sheet[data-state="sending"] .bk-done{animation:bk-fade .35s var(--ease) both}
#book-sheet[data-state="sending"][data-mark] .bk-mark{animation:bk-breathe 1.5s ease-in-out infinite;transform:scale(.42)}
#book-sheet[data-state="sending"] .bk-mark path{animation:none;stroke-dashoffset:60}
@keyframes bk-breathe{0%,100%{transform:scale(.4)}50%{transform:scale(.5)}}
@keyframes bk-fade{from{opacity:0}}
.bk-done{position:relative;flex:1;display:flex;flex-direction:column;align-items:center;text-align:center;padding-top:6vh}
.bk-bubbles{position:fixed;inset:0;overflow:hidden;pointer-events:none;z-index:1}
.bk-done > :not(.bk-bubbles){position:relative;z-index:2}
.bk-mark{display:grid;place-items:center;width:132px;height:132px;border-radius:50%;background:var(--ink);animation:bk-pop .6s var(--ease) both}
.bk-mark svg{width:64px;height:64px;fill:none;stroke:#fff;stroke-width:7;stroke-linecap:round;stroke-linejoin:round}
.bk-mark path{stroke-dasharray:60;stroke-dashoffset:60;animation:bk-draw .5s .35s var(--ease) forwards}
#book-sheet[data-mark="bubble"] .bk-mark{width:220px;height:220px;background:
    radial-gradient(circle at 30% 26%,rgba(255,255,255,.95) 0 5%,rgba(255,255,255,0) 6%),
    radial-gradient(circle at 50% 50%,rgba(255,255,255,0) 62%,rgba(150,200,255,.4) 72%,rgba(255,170,230,.42) 82%,rgba(170,255,220,.45) 92%,rgba(255,255,255,.1) 100%);
  box-shadow:inset 0 0 0 1.5px rgba(140,170,210,.35),inset -14px -18px 30px rgba(120,170,255,.14),0 30px 60px -30px rgba(80,120,200,.25);
  animation:bk-grow .8s var(--ease) both,bk-wobble 3.4s .8s ease-in-out infinite}
#book-sheet[data-mark="bubble"] .bk-mark svg{width:84px;height:84px;stroke:var(--ink)}
#book-sheet[data-mark="bubble"] .bk-mark path{animation-delay:.45s}
.bk-title{margin-top:30px;font-size:44px;font-weight:700;line-height:1.05;letter-spacing:-.045em}
.bk-when-big{margin-top:14px;font-size:19px;font-weight:600}
.bk-where{margin-top:4px;font-size:16px;color:var(--ink-2)}
.bk-note{margin-top:26px;font-size:15px;line-height:1.45;color:var(--ink-2);text-wrap:pretty}
.bk-done .bk-title,.bk-done .bk-when-big,.bk-done .bk-where,.bk-done .bk-note{animation:rise .5s .25s var(--ease) both}
.bk-b{position:absolute;bottom:-90px;border-radius:50%;
  background:radial-gradient(circle at 32% 28%,rgba(255,255,255,.95) 0 6%,rgba(255,255,255,0) 7%),
    radial-gradient(circle at 68% 74%,rgba(255,255,255,.55) 0 3%,rgba(255,255,255,0) 4%),
    radial-gradient(circle at 50% 50%,rgba(255,255,255,0) 58%,rgba(150,200,255,.32) 70%,rgba(255,170,230,.34) 80%,rgba(170,255,220,.38) 90%,rgba(255,255,255,.05) 100%);
  box-shadow:inset 0 0 0 1px rgba(140,170,210,.28),inset -6px -8px 14px rgba(120,170,255,.10)}
.bk-b.burst{animation:bk-rise var(--d) var(--ease) var(--w) both}
.bk-b.drift{opacity:.75;animation:bk-drift var(--d) linear var(--w) infinite}
@keyframes bk-pop{0%{transform:scale(.4);opacity:0}60%{transform:scale(1.06);opacity:1}100%{transform:scale(1)}}
@keyframes bk-draw{to{stroke-dashoffset:0}}
@keyframes bk-grow{from{transform:scale(.45)}}
@keyframes bk-wobble{0%,100%{border-radius:50%;transform:translateY(0)}50%{border-radius:48% 52% 50% 50%/52% 48% 52% 48%;transform:translateY(-6px)}}
@keyframes bk-rise{0%{transform:translate(0,0) scale(.6);opacity:0}12%{opacity:1}80%{opacity:1;transform:translate(var(--x),var(--y)) scale(1)}90%{transform:translate(var(--x),var(--y)) scale(1.18);opacity:.6}100%{transform:translate(var(--x),var(--y)) scale(1.3);opacity:0}}
@keyframes bk-drift{0%{transform:translate(0,0);opacity:0}10%{opacity:.75}50%{transform:translate(var(--x),-55vh)}88%{opacity:.75}96%{transform:translate(calc(var(--x) * -.4),-104vh) scale(1.15);opacity:.4}100%{transform:translate(calc(var(--x) * -.4),-110vh) scale(1.25);opacity:0}}
@media(prefers-reduced-motion:reduce){.bk-b{display:none}.bk-mark,.bk-mark path,.bk-done *{animation:none!important}.bk-mark path{stroke-dashoffset:0}}
#book-sheet{overflow-x:hidden}
#book-sheet[data-dir="fwd"] .bk-in{animation:bk-push .38s var(--ease) both}
#book-sheet[data-dir="back"] .bk-in{animation:bk-push-back .38s var(--ease) both}
@keyframes bk-push{from{opacity:0;transform:translateX(32px)}}
@keyframes bk-push-back{from{opacity:0;transform:translateX(-32px)}}
.bk-what{margin-top:6px;font-size:15px;color:var(--ink-2)}
/* each step's pieces arrive one after another, a few hundredths apart */
.bk-stag{animation:bk-arrive .5s var(--ease) both;animation-delay:calc(70ms + var(--i,0) * 35ms)}
@keyframes bk-arrive{from{opacity:0;transform:translateY(10px)}}
/* See open times stays quiet until a car and a town are picked */
#bk-times{transition:transform .3s var(--ease),background-color .2s,opacity .3s}
#book-sheet:not(:has(#bk-form input[name="size"]:checked)) #bk-times,#book-sheet:not(:has(#bk-form input[name="town"]:checked)) #bk-times{opacity:.35}
/* a tile gives under the finger */
.opt span{transition:background-color .2s,color .2s,transform .25s var(--ease)}
.opt:active span{transform:scale(.96)}
@media(prefers-reduced-motion:reduce){.bk-stag{animation:none}.opt:active span{transform:none}}
#bk-picker{margin-top:14px}
#bk-picker .bkp-next{display:none}   /* the month and the list already show the first open day */
@media(prefers-reduced-motion:reduce){#book-sheet .bk-in{animation:none!important}}
#book-sheet .bk-textline{margin-top:22px;padding-bottom:calc(20px + env(safe-area-inset-bottom,0px))}
/* a bar with nothing showing in it would only fade over the times */
#book-sheet .sheet-bar:not(:has(> :not([hidden]))){display:none}
.pill .spin{width:18px;height:18px;border:2px solid rgba(255,255,255,.35);border-top-color:#fff;border-radius:50%;animation:spin .8s linear infinite}
@keyframes spin{to{transform:rotate(360deg)}}
@media(prefers-reduced-motion:reduce){.pill .spin{animation-duration:2s}}
.bk-sum{margin-top:14px;padding:14px 16px;border-radius:16px;background:var(--ground);font-size:16px;line-height:1.45}
.bk-sum b{font-weight:600}
.bk-done .rv-say{font-size:16px;color:var(--ink-2)}
.bk-status{margin-top:14px;font-size:15px;line-height:1.4;color:var(--ink-2);text-align:center;text-wrap:pretty}
#book-sheet h2:focus{outline:0}
.rv-status button{font-weight:500;color:var(--ink);text-decoration:underline;white-space:nowrap}
/* photos step, the guided shots (crm/photo-pricing-plan.md, "Guided shots"): one card per shot (an example from Sam's
   own before photos, the shot's name, one line on how), a strip of the six that fills in, and Take photo in the main
   button's spot, opening the camera with no menu. After Use Photo the next card slides in under the same button.
   With all six in, the step turns into the six named photos, the optional problem spots, and Book it. */
.bk-ph-say{margin-top:6px;font-size:17px;line-height:1.4;text-wrap:pretty}
.bk-ph-strip{display:grid;grid-template-columns:repeat(6,1fr);gap:6px;margin-top:16px}
.bk-ph-slot{display:block;aspect-ratio:1;border-radius:10px;background:var(--ground);min-width:0}
.bk-ph-slot.now{box-shadow:inset 0 0 0 2px var(--blue)}
.bk-ph-count{margin-top:16px;font-size:15px;font-weight:600;color:var(--ink-2)}
.bk-ph-card{margin-top:6px}
.bk-ph-card.next{animation:bk-ph-next .42s var(--ease) both}
@keyframes bk-ph-next{from{opacity:0;transform:translateX(28px)}to{opacity:1;transform:none}}
.bk-ph-ex{position:relative;display:block;aspect-ratio:4/3;overflow:hidden;border-radius:18px;background:var(--ground)}
.bk-ph-ex picture{display:block;height:100%}
.bk-ph-ex img{display:block;width:100%;height:100%;object-fit:cover}
.bk-ph-ex span{position:absolute;left:12px;bottom:10px;font-size:13px;font-weight:600;color:#fff;text-shadow:0 1px 6px rgba(0,0,0,.6)}
.bk-ph-name{margin-top:14px;font-size:24px;font-weight:650;letter-spacing:-.03em;line-height:1.15}
.bk-ph-hint{margin-top:4px;font-size:17px;line-height:1.4;color:var(--ink-2);text-wrap:pretty}
.bk-ph-lib{margin-top:18px;font-size:15px;line-height:1.4;color:var(--ink-2);text-align:center}
.bk-ph-lib button{min-height:32px;font-weight:600;color:var(--blue)}
.bk-ph-h{margin-top:16px;font-size:15px;font-weight:600;color:var(--ink-2)}
.bk-ph-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:10px 8px;margin-top:6px}
.bk-ph-cell{min-width:0}
.bk-ph-at{display:block}
.bk-ph-cell p{margin-top:5px;font-size:13px;line-height:1.25;color:var(--ink-2)}
.bk-ph-tap{margin-top:12px;font-size:15px;color:var(--ink-2)}
.bk-ph-spots{margin-top:20px;padding-top:16px;border-top:1px solid var(--hair)}
.bk-ph-spots h3{font-size:19px;font-weight:650;letter-spacing:-.02em}
.bk-ph-spots h3 i{font-style:normal;font-size:15px;font-weight:500;color:var(--ink-2)}
.bk-ph-spots > p{margin-top:2px;font-size:15px;color:var(--ink-2)}
.bk-ph-row{display:grid;grid-template-columns:repeat(4,1fr);gap:8px;margin-top:10px}
.bk-ph-add{display:grid;align-content:center;justify-items:center;gap:4px;aspect-ratio:1;border-radius:14px;background:var(--ground);font-size:13px;font-weight:600;color:var(--blue)}
.bk-ph-add svg{width:24px;height:24px;fill:none;stroke:currentColor;stroke-width:1.8;stroke-linecap:round}
.bk-ph{position:relative;display:block;width:100%;overflow:hidden;aspect-ratio:1;border-radius:10px;background:var(--ground);transition:transform .25s var(--ease)}
.bk-ph-all .bk-ph{border-radius:14px}
.bk-ph:active{transform:scale(.97)}
.bk-ph img{width:100%;height:100%;object-fit:cover;transition:opacity .3s}
.bk-ph-ring,.bk-ph-ok{position:absolute;right:4px;bottom:4px;display:grid;place-items:center;width:20px;height:20px;border-radius:50%;opacity:0;transform:scale(.4);transition:opacity .2s,transform .35s var(--ease)}
.bk-ph-all :is(.bk-ph-ring,.bk-ph-ok){right:6px;bottom:6px;width:24px;height:24px}
.bk-ph-ring{background:rgba(255,255,255,.94)}
.bk-ph-ring svg{width:16px;height:16px;transform:rotate(-90deg);fill:none;stroke-width:3;stroke-linecap:round}
.bk-ph-ring circle{stroke:var(--hair)}
.bk-ph-ring .arc{stroke:var(--blue);stroke-dasharray:100;stroke-dashoffset:100;transition:stroke-dashoffset .2s}
.bk-ph-ok{background:var(--blue)}
.bk-ph-ok svg{width:12px;height:12px;fill:none;stroke:#fff;stroke-width:2.4;stroke-linecap:round;stroke-linejoin:round}
.bk-ph[data-st="up"] .bk-ph-ring,.bk-ph[data-st="ok"] .bk-ph-ok{opacity:1;transform:none}
.bk-ph[data-st="up"] img{opacity:.75}
.bk-ph[data-st="bad"] img{opacity:.3}
.bk-ph[data-st="bad"]::after{content:"!";position:absolute;inset:0;margin:auto;display:grid;place-items:center;width:24px;height:24px;border-radius:50%;background:var(--red);color:#fff;font-size:15px;font-weight:600}
.bk-photos .rv-err{margin-top:14px}
.bk-photos .fine{margin-top:6px}
#bk-book[aria-disabled="true"]{opacity:.35}
#bk-shoot svg{width:22px;height:22px;fill:none;stroke:currentColor;stroke-width:1.8;stroke-linejoin:round}
.bk-gone{margin-top:18px;font-size:17px;color:var(--ink);text-align:left}
/* on a phone the shot fills the screen without scrolling: the example takes whatever height is left (never under
   150px or over 4:3), so the library line sits just over the button, where a thumb already is */
@media(max-width:819px){
  #book-sheet .bk-photos:not([hidden]),#book-sheet .bk-ph-shoot:not([hidden]){display:flex;flex-direction:column;flex:1}
  #book-sheet .bk-ph-card{display:flex;flex-direction:column;flex:1 1 0;min-height:0}
  #book-sheet .bk-ph-ex:not([hidden]){flex:1 1 0;aspect-ratio:auto;min-height:150px;max-height:calc((100vw - 36px) * .75)}
  #book-sheet .bk-ph-lib{margin-top:auto;padding-top:14px}
}
@media(prefers-reduced-motion:reduce){.bk-ph,.bk-ph img,.bk-ph-ring,.bk-ph-ok,.bk-ph-ring .arc{transition:none}.bk-ph:active{transform:none}.bk-ph-card.next{animation:none}}

@media(min-width:820px){
  .cards.wash{grid-template-columns:1fr 1fr}
  .cards .band{grid-column:1/-1}
  .card.media{aspect-ratio:auto;min-height:100%}
  .proof{grid-template-columns:minmax(0,460px) 1fr;grid-template-areas:"cmp copy" "cmp chips";column-gap:72px;row-gap:26px;align-items:center}
  .proof-copy{grid-area:copy;align-self:end}
  #proof-cmp{grid-area:cmp}
  .proof .chips{grid-area:chips;align-self:start}
  .team{grid-template-columns:minmax(0,440px) 1fr;gap:72px}
  .foot-grid{grid-template-columns:1.1fr 1fr;align-items:start}
  .dock{display:none}
  dialog.sheet{inset:0;margin:auto;width:min(460px,calc(100% - 48px));height:fit-content;max-height:calc(100svh - 48px);border-radius:24px;opacity:0;transform:translateY(24px);transition:transform .45s var(--ease),opacity .3s}
  dialog.sheet{transition:transform .45s var(--ease),opacity .3s,overlay .45s allow-discrete,display .45s allow-discrete}
  dialog.sheet[open]{opacity:1;transform:none}
  @starting-style{dialog.sheet[open]{opacity:0;transform:translateY(24px)}}
  .grab{display:none}
  .sheet-in{--sp:26px;padding:26px var(--sp) 0}
}
@media(prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  .bloom,.opt input:checked+span,.star input:checked+svg,.rv-step{animation:none}
  html.js .reveal,html.js .reveal-m{opacity:1;transform:none;filter:none;transition:none}
  dialog.sheet,dialog.sheet::backdrop,.dock,.pill,.car img,.star svg{transition:none}
  /* no marquee: the reviews become a row you swipe */
  .marquee{overflow-x:auto;overscroll-behavior-x:contain;scroll-snap-type:x proximity;scrollbar-width:none;-webkit-mask-image:none;mask-image:none}
  .marquee-track{animation:none;padding-inline:var(--gut)}
  .marquee-track .set+.set{display:none}
  .rev{scroll-snap-align:start;scroll-margin-inline:var(--gut)}
}
html.still .bloom,html.still .marquee-track{animation:none}
html.still.js .reveal,html.still.js .reveal-m{opacity:1;transform:none;filter:none;transition:none}
/* focus rings are for keyboard users: after a tap (or focus moved by script after a tap) they stay off */
html:not(.kb) :focus-visible,html:not(.kb) :focus-visible+span,html:not(.kb) :focus-visible+svg,html:not(.kb) :has(input:focus-visible){outline:none!important}
