/* ══════════════════════════════════════════════════════════
   Cardiff Car Wash — design system
   Palette sampled from the ABC sign proof (2718_PS-SI-S).
   Display: Anton, skewed -8deg. Body: Archivo.
   ══════════════════════════════════════════════════════════ */

:root{
  --sun:#FAC021;
  --sun-deep:#EE920B;
  --burnt:#BB510B;
  --sky:#57A0D7;
  --deep:#08699E;
  --navy:#092145;
  --navy-soft:#123156;
  --tan:#E7A557;
  --foam:#F1F8FC;
  --line:#E3EDF5;
  --white:#fff;
  --ink:#12233B;
  --ink-soft:#5C6C82;

  --display:"Anton",Impact,sans-serif;
  --sans:"Archivo",-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;

  --gutter:clamp(1.15rem, 4vw, 5rem);
  --skew:-8deg;

  --t-hero:clamp(2.4rem, 1rem + 5.5vw, 5.6rem);
  --t-h2:clamp(2rem, 1.1rem + 3vw, 4rem);
  --t-h3:clamp(1.05rem, .95rem + .5vw, 1.35rem);
  --t-micro:.7rem;

  --ease:cubic-bezier(.22,.61,.36,1);
}

*,*::before,*::after{box-sizing:border-box}
/* skewX() pushes skewed headings a few px past the viewport edge.
   `clip` (not `hidden`) kills the sideways scroll without breaking position:sticky on .nav */
html,body{overflow-x:clip}
body{margin:0;background:var(--white);color:var(--ink);font-family:var(--sans);
  font-size:clamp(1rem,.96rem + .2vw,1.08rem);line-height:1.65;-webkit-font-smoothing:antialiased}
img{display:block;max-width:100%;height:auto}
a{color:inherit;text-decoration:none}
/* NB: anything that also carries .wrap must use padding-block, never the
   `padding` shorthand — the shorthand zeroes padding-inline and kills the gutter. */
.wrap{max-width:1240px;margin-inline:auto;padding-inline:var(--gutter)}
.sr{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}

/* ── type ─────────────────────────────────────────── */
.slant{font-family:var(--display);font-weight:400;text-transform:uppercase;
  transform:skewX(var(--skew));letter-spacing:.005em;line-height:.92;margin:0}
.eyebrow{font-family:var(--display);text-transform:uppercase;transform:skewX(var(--skew));
  font-size:clamp(.95rem,.85rem + .45vw,1.35rem);color:var(--sky);letter-spacing:.02em;margin:0 0 .5rem}
.eyebrow--sun{color:var(--sun)}
.eyebrow--burnt{color:var(--burnt)}
.pop{color:var(--sun)}
.pop--deep{color:var(--deep)}

/* ── buttons ──────────────────────────────────────── */
.btn{display:inline-flex;align-items:center;gap:.55rem;font-family:var(--display);
  text-transform:uppercase;font-size:.95rem;letter-spacing:.02em;padding:.85rem 1.5rem;
  border-radius:999px;border:2px solid transparent;cursor:pointer;transform:skewX(var(--skew));
  transition:transform .25s var(--ease),background .25s var(--ease),box-shadow .25s var(--ease)}
.btn > *{transform:skewX(calc(-1 * var(--skew)))}
.btn--sun{background:var(--sun);color:var(--navy);box-shadow:0 6px 0 var(--sun-deep)}
.btn--sun:hover{transform:skewX(var(--skew)) translateY(-2px);box-shadow:0 8px 0 var(--sun-deep)}
.btn--ghost{background:transparent;color:#fff;border-color:rgba(255,255,255,.6)}
.btn--ghost:hover{background:rgba(255,255,255,.12);border-color:#fff}
.btn--navy{background:var(--navy);color:#fff;box-shadow:0 6px 0 #04122a}
.btn--navy:hover{transform:skewX(var(--skew)) translateY(-2px)}
.btn--sm{font-size:.8rem;padding:.6rem 1.1rem}

/* ── chrome: utility bar + nav ────────────────────── */
/* Micro-strip: ONE centered muted line — status · temp · rating. Fixed-height,
   nowrap, nothing else lives here. Call/Directions are nav icon buttons now. */
.util{background:var(--navy);color:rgba(255,255,255,.66);font-size:.76rem}
.util__in{display:flex;justify-content:center;align-items:center;gap:.55rem;
  padding-block:.38rem;white-space:nowrap;overflow:hidden}
.util__open{display:inline-flex;align-items:center;gap:.45rem}
.util__open b{font-weight:600;color:rgba(255,255,255,.85)}
.util__wx{color:rgba(255,255,255,.66)}
.util__wx::before{content:"·";margin-right:.55rem;opacity:.45}
.util__rating{color:rgba(255,255,255,.66);font-weight:600}
.util__rating::before{content:"·";margin-right:.55rem;opacity:.45;font-weight:400}
.util__rating:hover{color:#fff}
.util__count{font-weight:400}
@media(max-width:520px){.util__count{display:none}}

/* Flat + a hairline instead of the old blue gradient; the gradient plus
   underline-on-hover links was the "2010s hyperlink bar" look. */
.nav{background:var(--navy);position:sticky;top:0;z-index:50;border-top:1px solid rgba(255,255,255,.07);
  border-bottom:1px solid rgba(255,255,255,.14);box-shadow:0 4px 24px rgba(9,33,69,.22)}
.nav__in{display:flex;align-items:center;gap:1.5rem;padding-block:.5rem}
.nav__logo{flex:none;width:64px}
.nav__links{display:flex;gap:.2rem;margin-left:auto;list-style:none;padding:0}
/* Pill links, matching the button language (both are border-radius:999px) —
   the hover is a filled chip rather than an underline. */
.nav__links a{position:relative;display:block;color:rgba(255,255,255,.72);font-weight:700;
  font-size:.78rem;letter-spacing:.05em;text-transform:uppercase;padding:.55rem .85rem;
  border-radius:999px;transition:background .2s var(--ease),color .2s var(--ease)}
.nav__links a:hover{background:rgba(255,255,255,.13);color:#fff}
.nav__links a[aria-current]{background:rgba(255,255,255,.1);color:#fff}
/* the current page keeps a sun marker so state is not carried by colour alone */
.nav__links a[aria-current]::after{content:"";position:absolute;left:50%;bottom:.3rem;
  width:14px;height:3px;border-radius:999px;background:var(--sun);transform:translateX(-50%)}
.nav__cta{display:flex;gap:.55rem;flex:none;align-items:center}
.nav__ico{width:38px;height:38px;border:1.5px solid rgba(255,255,255,.32);border-radius:50%;
  display:inline-flex;align-items:center;justify-content:center;color:rgba(255,255,255,.85);
  transition:background .2s var(--ease),border-color .2s var(--ease)}
.nav__ico:hover{background:rgba(255,255,255,.12);border-color:rgba(255,255,255,.6);color:#fff}
@media(max-width:520px){.nav__ico{display:none}}
@media(max-width:1000px){.nav__links{display:none}.nav__cta{margin-left:auto}}
@media(max-width:520px){.nav__cta .btn--ghost{display:none}}


/* Purchase receipt on the thank-you pages — populated from the Stripe return
   params, hidden until JS fills it so it never flashes an empty chip. */
.receipt{display:inline-block;margin:1.1rem 0 0;padding:.5rem .95rem;border-radius:.7rem;
  background:rgba(255,255,255,.12);border:1px solid rgba(255,255,255,.28);
  font-family:var(--display);text-transform:uppercase;letter-spacing:.03em;
  font-size:.85rem;color:#fff}
.receipt[hidden]{display:none}

/* ── hero ─────────────────────────────────────────── */
.hero{position:relative;background:var(--navy);color:#fff;overflow:hidden;isolation:isolate}
picture{display:contents}
.hero__bg{position:absolute;inset:0;z-index:-2;width:100%;height:100%;object-fit:cover;object-position:55% 50%}
/* video sits above the still image (both z-index:-2, later in DOM wins) */
.hero__bg--video{z-index:-2}
/* Mobile no longer hides the hero video (Scott, 8/03 — he wants the About
   drone loop on phones). The still image stays the guaranteed floor: it renders
   first and remains for reduced-motion users and while the mp4 loads. */
@media (prefers-reduced-motion:reduce){.hero__bg--video{display:none}}
.hero::before{content:"";position:absolute;inset:0;z-index:-1;
  background:linear-gradient(100deg,rgba(9,33,69,.94) 0%,rgba(9,33,69,.86) 42%,rgba(8,105,158,.55) 100%)}
/* photo-forward heroes (dark imagery that carries its own contrast): let the
   picture through — heavy wash only where the text sits */
.hero--light::before{background:linear-gradient(100deg,rgba(9,33,69,.78) 0%,rgba(9,33,69,.45) 45%,rgba(8,105,158,.12) 100%)}
/* portrait sources: aim the crop at the badge + hood crest, not the mid-hood band */
.hero--light .hero__bg{object-position:60% 32%}
.rig__car img[src*="lambo-foam"]{object-position:50% 36%}
.hero__in{padding-block:clamp(2.5rem,7vh,5.5rem) clamp(6rem,14vh,10rem)}
.hero h1{font-size:var(--t-hero);text-shadow:0 6px 0 rgba(0,0,0,.22);white-space:nowrap}
/* Long DYNAMIC titles (blog posts) must wrap at every width — nowrap clipped
   them at the viewport edge on desktop/tablet with no ellipsis. */
.hero h1.hero-h1--wrap{white-space:normal;max-width:22ch}
@media(max-width:520px){.hero h1.hero-h1--wrap{padding-right:.6rem}}
@media(max-width:520px){.hero h1{white-space:normal}}
.hero__sub{margin:1.6rem 0 0;max-width:46ch;color:rgba(255,255,255,.86);font-size:clamp(1rem,.95rem + .35vw,1.18rem)}
.hero__actions{display:flex;flex-wrap:wrap;gap:.9rem;margin-top:2.2rem}

/* ── the dog surfs the page's own wave dividers ──────
   He is never pasted over a photograph. He sits on the crest of the wave that
   separates two sections, so his wave and the page's wave are the same wave. */
.surf{position:relative;line-height:0}
/* wave sits ABOVE the dog so the crest cuts across his board — he's in the water, not on it */
.surf .wave{position:relative;z-index:2}
.surf__dog{
  position:absolute;z-index:1;
  right:clamp(1rem,7vw,7rem);
  bottom:16%;
  width:clamp(110px,14vw,210px);
  filter:drop-shadow(0 10px 14px rgba(9,33,69,.35));
  animation:bob 5.5s ease-in-out infinite;
  transform-origin:50% 90%;
}
@keyframes bob{0%,100%{transform:translateY(0) rotate(0)}50%{transform:translateY(-9px) rotate(-1.6deg)}}
@media(max-width:560px){.surf__dog{width:84px;bottom:2%}
}
.hero__stats{display:flex;flex-wrap:wrap;gap:.6rem 2.4rem;margin-top:2.6rem;font-size:.74rem;
  letter-spacing:.16em;text-transform:uppercase;color:rgba(255,255,255,.6);font-weight:700}

/* suds — screen-blended so they read as soap, not ball bearings */
.sud{position:absolute;border-radius:50%;pointer-events:none;z-index:-1;mix-blend-mode:screen;
  background:
    radial-gradient(circle at 30% 26%,rgba(255,255,255,.9) 0 6%,rgba(255,255,255,.28) 22%,rgba(255,255,255,0) 55%),
    radial-gradient(circle at 50% 50%,rgba(255,255,255,0) 62%,rgba(180,225,255,.34) 88%,rgba(255,255,255,0) 100%);
  animation:rise linear infinite}
@keyframes rise{from{transform:translateY(20px) scale(.9);opacity:0}
  15%{opacity:.7} 85%{opacity:.45} to{transform:translateY(-130px) scale(1.06);opacity:0}}

/* ── wave dividers ────────────────────────────────── */
.wave{display:block;width:100%;height:auto;margin-bottom:-1px}
/* A divider wave is transparent above its curve. The wrapper carries the colour
   of the section ABOVE it (set inline by wave()/surfWave()), so the gap shows
   that section and the wave sits flush.
   Do NOT reintroduce a negative margin here: pulling the wave up over the
   previous section clips that section's content whenever its bottom padding is
   less than the wave's rendered height (7.64vw) — that is what was cutting the
   bottom off the wash cards. */
.wave-wrap{line-height:0}
/* Carter clearance, global: the dog rides ABOVE the crest into the previous
   section. When that wrapper also carries the section colour (.surf.wave-wrap =
   every joinCTA wave), pad the top so his wave never clips a card's corner —
   one rule instead of per-page patches (contact/memberships/gold-wash/blog). */
.surf.wave-wrap{padding-top:clamp(2.5rem,6vw,5.5rem)}

/* ── the difference diagram ───────────────────────── */
.diff{background:linear-gradient(180deg,var(--foam),#fff);padding:0 0 clamp(3rem,7vh,6rem)}
.diff--pad{padding-top:clamp(2.75rem,7vh,4.5rem)}
.diff__head{text-align:center;max-width:56ch;margin:0 auto clamp(2rem,5vh,3.5rem)}
.diff__head h2{font-size:var(--t-h2);color:var(--navy)}
.diff__head p{color:var(--ink-soft);margin:1.1rem 0 0}
.rig{position:relative;max-width:1080px;margin-inline:auto}
.rig__car{border-radius:1.5rem;overflow:hidden;box-shadow:0 30px 60px -22px rgba(9,33,69,.55);
  aspect-ratio:16/10;background:var(--navy)}
.rig__car img{width:100%;height:100%;object-fit:cover}
.call{display:grid;gap:1rem;margin-top:1.5rem;grid-template-columns:repeat(2,1fr)}
.call > .call__item:last-child:nth-child(odd){grid-column:span 2}
@media(max-width:700px){.call{grid-template-columns:1fr}.call > .call__item:last-child:nth-child(odd){grid-column:auto}}
/* Sticker language, matching .wash/.cform cards — the pale 2px var(--line)
   outline was the last survivor of the rejected quiet draft. */
.call__item{display:flex;gap:.9rem;align-items:flex-start;background:#fff;border:2.5px solid var(--navy);
  border-radius:1rem;padding:1rem 1.1rem;box-shadow:4px 5px 0 var(--navy);
  transition:transform .2s var(--ease),box-shadow .2s var(--ease)}
.call__item:hover{transform:translate(-2px,-3px);box-shadow:6px 8px 0 var(--navy)}
.call__dot{flex:none;width:2.35rem;height:2.35rem;border-radius:50%;background:var(--foam);color:var(--deep);
  display:grid;place-items:center;font-family:var(--display);font-size:.95rem}
.call__item h3{font-family:var(--display);text-transform:uppercase;font-size:.98rem;margin:.15rem 0 .2rem;
  color:var(--navy);letter-spacing:.01em}
.call__item p{margin:0;font-size:.86rem;color:var(--ink-soft);line-height:1.5}
/* Float the callouts around the car ONLY inside .rig. Elsewhere (.faqs, wash tiers)
   .call stays a plain grid — unscoped, these absolute rules stack every item on top of itself. */
@media(min-width:1080px){
  /* 3-row grid: cards size their rows, the photo spans all three and stretches —
     fixed %-top pinning let tall cards overlap their neighbors (05/06 bug). */
  .rig{display:grid;grid-template-columns:15rem minmax(0,1fr) 15rem;gap:1.25rem 2rem;align-items:stretch;padding:0}
  .rig__car{grid-column:2;grid-row:1/4;aspect-ratio:auto;height:100%;min-height:24rem}
  .rig .call{display:contents}
  .rig .call__item{position:relative;width:auto;margin:0;background:rgba(255,255,255,.97);backdrop-filter:blur(4px);align-self:center}
  .rig .call__item::after{content:"";position:absolute;top:50%;width:2rem;height:2px;background:var(--sky)}
  .rig .call__item[data-side="l"]::after{right:-2.4rem}
  .rig .call__item[data-side="r"]::after{left:-2.4rem}
  .rig .call__item:nth-child(1){grid-column:1;grid-row:1}
  .rig .call__item:nth-child(2){grid-column:1;grid-row:2}
  .rig .call__item:nth-child(3){grid-column:1;grid-row:3}
  .rig .call__item:nth-child(4){grid-column:3;grid-row:1}
  .rig .call__item:nth-child(5){grid-column:3;grid-row:2}
  .rig .call__item:nth-child(6){grid-column:3;grid-row:3}
}

/* ── plan cards ───────────────────────────────────── */
/* padding-top is load-bearing: without it a child margin collapses out and
   opens a white gap above the section. */
.plans{background:var(--navy);color:#fff;position:relative;
  padding:clamp(2.5rem,7vh,4.5rem) 0 clamp(3rem,7vh,5rem)}
.plans__head{text-align:center;max-width:56ch;margin:0 auto}
.plans__head h2{font-size:var(--t-h2)}
.plans__head p{color:rgba(255,255,255,.72);margin:1.1rem 0 0}
.plans__toggle{text-align:center}
.toggle{display:inline-flex;background:rgba(255,255,255,.1);border-radius:999px;padding:.35rem;
  margin:2rem auto 0;border:1px solid rgba(255,255,255,.2)}
.toggle button{appearance:none;border:0;cursor:pointer;background:transparent;color:rgba(255,255,255,.7);
  font-family:var(--display);text-transform:uppercase;font-size:.85rem;letter-spacing:.05em;
  padding:.7rem 1.5rem;border-radius:999px;transition:background .3s var(--ease),color .3s var(--ease)}
.toggle button[aria-pressed="true"]{background:var(--sun);color:var(--navy)}

.cards{display:grid;gap:1.75rem;margin-top:3rem;grid-template-columns:repeat(auto-fit,minmax(min(100%,24rem),1fr))}
.card{position:relative;background:#fff;color:var(--ink);border-radius:1.5rem;padding:2.25rem 2rem 2rem;
  box-shadow:0 26px 50px -24px rgba(0,0,0,.6)}
.card--best{border:4px solid var(--sun)}
.flag{position:absolute;top:-.95rem;left:50%;transform:translateX(-50%) skewX(var(--skew));background:var(--sun);
  color:var(--navy);font-family:var(--display);text-transform:uppercase;font-size:.78rem;letter-spacing:.06em;
  padding:.4rem 1.1rem;border-radius:.4rem;white-space:nowrap}
.card h3{font-family:var(--display);text-transform:uppercase;font-size:1.9rem;color:var(--navy);margin:0;
  transform:skewX(var(--skew))}
.card__note{color:var(--ink-soft);font-size:.92rem;margin:.4rem 0 0}
.price{display:flex;align-items:flex-start;gap:.2rem;margin:1.5rem 0 .3rem;min-height:4.6rem}
.price__cur{font-family:var(--display);font-size:1.6rem;color:var(--deep);margin-top:.55rem}
.price__num{font-family:var(--display);font-size:clamp(3.6rem,2.4rem + 3vw,4.8rem);line-height:.9;
  color:var(--navy);font-variant-numeric:tabular-nums}
.price__per{align-self:flex-end;color:var(--ink-soft);font-size:.9rem;font-weight:600;margin-bottom:.55rem}
.price__sub{font-size:.88rem;color:var(--ink-soft);margin:0;min-height:1.4rem}
.price__sub b{color:var(--burnt)}
.card ul{list-style:none;margin:1.6rem 0 0;padding:0}
.card li{display:flex;gap:.75rem;align-items:baseline;padding:.6rem 0;border-bottom:1px solid #EDF2F6;font-size:.94rem}
.card li::before{content:"";flex:none;width:.75rem;height:.75rem;border-radius:50%;background:var(--sun);
  box-shadow:inset 0 0 0 2px #fff,0 0 0 2px var(--sun-deep);transform:translateY(-.05rem)}
.card .btn{width:100%;justify-content:center;margin-top:1.9rem}

/* ── break-even ledger ────────────────────────────── */
.even{background:var(--sun);color:var(--navy);padding:clamp(3rem,7vh,5rem) 0}
.even__in{display:grid;gap:2rem}
@media(min-width:860px){.even__in{grid-template-columns:1.05fr .95fr;align-items:center;gap:3.5rem}}
.even h2{font-size:var(--t-h2)}
.even p{margin:1.1rem 0 0;max-width:44ch;color:#3a3212;font-weight:500}
.ledger{background:var(--navy);color:#fff;border-radius:1.25rem;padding:1.75rem;
  box-shadow:0 20px 40px -20px rgba(0,0,0,.5)}
.ledger__row{display:flex;justify-content:space-between;align-items:center;gap:1rem;padding:.9rem 0;
  border-bottom:1px solid rgba(255,255,255,.14)}
.ledger__row:last-child{border-bottom:0}
.ledger__k{font-size:.9rem;color:rgba(255,255,255,.72)}
.ledger__v{font-family:var(--display);font-size:1.7rem;font-variant-numeric:tabular-nums}
.ledger__v--sun{color:var(--sun)}

/* ── plates (link cards) ──────────────────────────── */
.plates{padding:clamp(3.5rem,9vh,6.5rem) 0}
.plates h2{font-size:var(--t-h2);color:var(--navy);text-align:center}
.plates__grid{display:grid;gap:1.75rem;margin-top:2.75rem;grid-template-columns:1fr}
@media(min-width:900px){
  .plates__grid{grid-template-columns:repeat(6,1fr)}
  .plates__grid > .plate{grid-column:span 2}
  .plates__grid > .plate:nth-last-child(1):nth-child(3n+1){grid-column:3/span 2}
  .plates__grid > .plate:nth-last-child(2):nth-child(3n+1){grid-column:2/span 2}}
.plate{display:block;border-radius:1.25rem;overflow:hidden;background:#fff;border:2px solid var(--line);
  transition:transform .3s var(--ease),border-color .3s var(--ease)}
.plate:hover{transform:translateY(-5px);border-color:var(--sun)}
.plate__img{aspect-ratio:4/3;overflow:hidden}
.plate__img img{width:100%;height:100%;object-fit:cover;transition:transform .9s var(--ease)}
.plate:hover .plate__img img{transform:scale(1.06)}
.plate__body{padding:1.4rem 1.5rem 1.7rem}
.plate h3{font-family:var(--display);text-transform:uppercase;font-size:1.3rem;color:var(--navy);margin:0 0 .4rem;
  transform:skewX(var(--skew))}
.plate p{margin:0;color:var(--ink-soft);font-size:.9rem}
.plate span{display:inline-block;margin-top:.9rem;font-family:var(--display);text-transform:uppercase;
  font-size:.8rem;color:var(--sun-deep);letter-spacing:.04em}

/* ── wash menu strip ──────────────────────────────── */
.menu{background:var(--foam);padding:clamp(3.5rem,9vh,6rem) 0}
.menu__head{text-align:center;max-width:52ch;margin:0 auto clamp(2rem,5vh,3rem)}
.menu__head h2{font-size:var(--t-h2);color:var(--navy)}
.menu__head p{color:var(--ink-soft);margin:1.1rem 0 0}
.menu__grid{display:grid;gap:1.25rem;grid-template-columns:1fr}
@media(min-width:640px){.menu__grid--4{grid-template-columns:repeat(2,1fr)}}
@media(min-width:1080px){.menu__grid--4{grid-template-columns:repeat(4,1fr)}}
@media(min-width:560px) and (max-width:899px){
  .menu__grid--3{grid-template-columns:repeat(2,1fr)}
  .menu__grid--3 > *:last-child:nth-child(odd){grid-column:span 2}}
@media(min-width:900px){
  .menu__grid--3{grid-template-columns:repeat(6,1fr)}
  .menu__grid--3 > *{grid-column:span 2}
  .menu__grid--3 > *:nth-last-child(1):nth-child(3n+1){grid-column:3/span 2}
  .menu__grid--3 > *:nth-last-child(2):nth-child(3n+1){grid-column:2/span 2}}
.wash{background:#fff;border:2px solid var(--line);border-radius:1.25rem;padding:1.6rem 1.5rem;
  display:flex;flex-direction:column;transition:border-color .25s var(--ease),transform .25s var(--ease)}
.wash:hover{border-color:var(--sun);transform:translateY(-4px)}
.wash h3{font-family:var(--display);text-transform:uppercase;font-size:1.35rem;color:var(--navy);margin:0;
  transform:skewX(var(--skew))}
.wash__price{font-family:var(--display);font-size:2.3rem;color:var(--deep);line-height:1;margin:.85rem 0 .1rem;
  font-variant-numeric:tabular-nums}
.wash__price small{font-size:1rem;color:var(--ink-soft)}
.wash__meta{font-size:.85rem;color:var(--ink-soft);margin:0}
.wash__link{margin-top:auto;padding-top:1.1rem;font-family:var(--display);text-transform:uppercase;
  font-size:.78rem;letter-spacing:.05em;color:var(--sun-deep)}
/* Membership hook, at the moment the price is being read. Gold + Platinum only. */
.even__cta{margin-top:1.5rem}
.wash__upsell{align-self:flex-start;margin-top:.9rem;background:var(--sun);color:var(--navy);
  border:2px solid var(--navy);border-radius:999px;padding:.3rem .7rem;
  font-family:var(--display);text-transform:uppercase;font-size:.72rem;letter-spacing:.04em;
  box-shadow:2px 3px 0 var(--navy)}
.wash__upsell--member{background:var(--deep);color:#fff}
/* block, not inline-block: inside .plate__body the next element is the inline
   "See details →" span, which otherwise sits on the same line and overlaps the pill.
   Colour is restated here because `.plate span` (0,1,1) sets the link orange and
   outranks the pill's own colour rule (0,1,0). */
.plate .wash__upsell{display:block;width:fit-content;margin:.6rem 0 .55rem;color:var(--navy)}
.plate .wash__upsell--member{color:#fff}

/* ── photo band ───────────────────────────────────── */
.band{background:var(--navy);padding:clamp(3rem,8vh,5.5rem) 0 clamp(2rem,5vh,3.25rem)}
.band__head{text-align:center;max-width:54ch;margin:0 auto clamp(2rem,5vh,3rem);color:#fff}
.band__head h2{font-size:var(--t-h2)}
.band__head p{color:rgba(255,255,255,.7);margin:1.1rem 0 0}
.band__grid{display:grid;gap:.9rem;grid-template-columns:repeat(2,1fr)}
.band__cell{overflow:hidden;border-radius:1rem;aspect-ratio:4/3}
.band__cell img{width:100%;height:100%;object-fit:cover;transition:transform 1s var(--ease)}
.band__cell:hover img{transform:scale(1.06)}
@media(max-width:759px){.band__cell:nth-child(5){grid-column:span 2}}
/* 2x2 feature + four 1x1 tiles the 4-col x 2-row grid exactly */
@media(min-width:760px){
  .band__grid{grid-template-columns:repeat(4,1fr);grid-template-rows:repeat(2,clamp(9rem,17vw,15rem))}
  .band__cell{aspect-ratio:auto;height:100%}
  .band__cell:nth-child(1){grid-column:span 2;grid-row:span 2}
}
/* --even variant: uniform tiles, any multiple of 4 (about page uses 8). The
   default mosaic template NEEDS exactly 5 cells — the about page fed it 3 and
   rendered a lopsided strip with a dead hole, which is what got it called
   trash. No feature cell here, every tile 4/3. */
.band__grid--even{grid-template-columns:repeat(2,1fr)}
@media(min-width:760px){
  .band__grid--even{grid-template-columns:repeat(4,1fr);grid-template-rows:none}
  .band__grid--even .band__cell{aspect-ratio:4/3;height:auto}
  .band__grid--even .band__cell:nth-child(1){grid-column:auto;grid-row:auto}
}
.band__cta{text-align:center;margin-top:clamp(1.6rem,4vh,2.4rem)}
/* gallery — masonry columns so portrait + landscape shots pack naturally */
.gallery{display:grid;gap:.9rem;margin-top:2.5rem;grid-template-columns:repeat(2,1fr)}
.gallery > .gallery__item:last-child:nth-child(odd){grid-column:span 2}
@media(min-width:640px){.gallery{grid-template-columns:repeat(3,1fr)}
  .gallery > .gallery__item:last-child:nth-child(odd){grid-column:auto}}
.gallery__item{overflow:hidden;border-radius:1rem;background:#0d2a4d;aspect-ratio:4/3}
.gallery__item img{width:100%;height:100%;object-fit:cover;display:block;transition:transform .9s var(--ease)}
.gallery__item:hover img{transform:scale(1.05)}

/* ── service area ─────────────────────────────────── */
.area{padding:clamp(3.5rem,9vh,6rem) 0;text-align:center}
.area h2{font-size:var(--t-h2);color:var(--navy)}
.area p{color:var(--ink-soft);max-width:52ch;margin:1.1rem auto 0}
.area__list{display:grid;gap:.6rem;margin-top:2.2rem;list-style:none;padding:0;grid-template-columns:repeat(2,1fr)}
.area__list li:last-child:nth-child(odd){grid-column:span 2}
@media(min-width:820px){
  .area__list{grid-template-columns:repeat(6,1fr)}
  .area__list li{grid-column:span 2}
  .area__list li:last-child:nth-child(odd){grid-column:span 2}
  .area__list li:last-child:nth-child(3n+1){grid-column:3/5}
  .area__list li:nth-last-child(2):nth-child(3n+1){grid-column:2/4}
  .area__list li:last-child:nth-child(3n+2){grid-column:4/6}
}
.area__list li{text-align:center}
.area__list li{border:2px solid var(--line);border-radius:999px;padding:.5rem 1.1rem;font-size:.85rem;
  font-weight:600;color:var(--ink-soft);transition:border-color .25s var(--ease),color .25s var(--ease)}
.area__list li:hover{border-color:var(--sun);color:var(--navy)}

/* ── join ─────────────────────────────────────────── */
.join{position:relative;background:var(--deep);color:#fff;overflow:hidden;text-align:center;isolation:isolate}
.join__in{padding-block:clamp(3.5rem,9vh,6.5rem) clamp(4rem,10vh,7rem)}
.join h2{font-size:var(--t-h2)}
.join p{color:rgba(255,255,255,.82);max-width:44ch;margin:1.2rem auto 0}
.join__actions{display:flex;gap:.9rem;justify-content:center;flex-wrap:wrap;margin-top:2.2rem}

/* ── footer ───────────────────────────────────────── */
.foot{background:var(--navy);color:rgba(255,255,255,.6);font-size:.85rem;padding:2.5rem 0}
.foot__in{display:flex;flex-wrap:wrap;gap:1rem 2.5rem;justify-content:space-between;align-items:center}
.foot a{color:rgba(255,255,255,.85);font-weight:600}
.foot a:hover{color:var(--sun)}

/* ── motion ───────────────────────────────────────────
   Gated behind .js: without JS (or if IntersectionObserver never fires) content
   must still be VISIBLE. Hiding by default made the service-area chips vanish. */
.js .rise{opacity:0;transform:translateY(24px);transition:opacity .8s var(--ease),transform .8s var(--ease)}
.js .rise.in{opacity:1;transform:none}
@media(prefers-reduced-motion:reduce){
  .rise{opacity:1;transform:none}
  .surf__dog{animation:none}
  .sud{display:none}
  *{animation:none!important;transition:none!important}
}


/* ── Carter contact form ─────────────────────────────
   Speech bubble + dog on the left, sticker-style form on the right. The bubble
   tail points down-right at Carter. Inputs get the Chrome-autofill inset-shadow
   fix — autofill's yellow paint otherwise covers the white field. */
.cform{background:var(--foam);padding-block:clamp(3rem,8vh,5.5rem)}
.cform__in{display:grid;grid-template-columns:minmax(0,5fr) minmax(0,7fr);gap:clamp(2rem,5vw,4rem);align-items:start}
.cform__carter{position:sticky;top:110px;text-align:center}
.cform__bubble{position:relative;background:#fff;border:3px solid var(--navy);border-radius:1.25rem;
  padding:1.3rem 1.4rem;text-align:left;box-shadow:6px 7px 0 var(--navy)}
.cform__bubble p{margin:0;font-size:.97rem;line-height:1.55}
.cform__bubble::after{content:"";position:absolute;bottom:-16px;right:22%;width:26px;height:26px;
  background:#fff;border-right:3px solid var(--navy);border-bottom:3px solid var(--navy);
  transform:rotate(45deg);clip-path:polygon(100% 0,100% 100%,0 100%)}
.cform__dog{width:clamp(150px,14vw,210px);height:auto;margin:1.4rem auto 0;display:block;
  filter:drop-shadow(0 10px 14px rgba(9,33,69,.25))}
.cform__form{background:#fff;border:3px solid var(--navy);border-radius:1.1rem;
  box-shadow:8px 9px 0 var(--navy);padding:1.7rem 1.6rem}
.cform__row{display:grid;grid-template-columns:1fr 1fr;gap:0 1rem}
.cform__form label{display:block;margin-bottom:1.05rem;font-family:var(--display);text-transform:uppercase;
  font-size:.8rem;letter-spacing:.05em;color:var(--navy)}
.cform__opt{color:var(--ink-soft);text-transform:none;font-family:var(--sans);font-weight:400}
.cform__form input,.cform__form textarea{display:block;width:100%;margin-top:.35rem;
  font:inherit;font-size:1rem;color:var(--ink);background:#fff;
  border:2px solid var(--line);border-radius:.7rem;padding:.65rem .8rem;
  transition:border-color .2s var(--ease)}
.cform__form input:focus,.cform__form textarea:focus{outline:none;border-color:var(--deep)}
.cform__form input:-webkit-autofill{-webkit-box-shadow:0 0 0 40px #fff inset;-webkit-text-fill-color:var(--ink)}
.cform__form textarea{resize:vertical;min-height:7.5rem}
.cform__form .btn{margin-top:.3rem}
.cform__hp{position:absolute !important;left:-9999px;top:-9999px}
.cform__note{margin:1rem 0 0;font-size:.95rem;background:#FFF4D6;border:2px solid var(--sun-deep);
  border-radius:.7rem;padding:.8rem 1rem}
.cform__note--ok{background:#E8F7EC;border-color:#2E7D48}
.cform__note[hidden]{display:none}
@media(max-width:900px){
  .cform__in{grid-template-columns:1fr}
  .cform__carter{position:static;display:grid;grid-template-columns:minmax(0,1fr) auto;gap:1rem;align-items:end;text-align:left}
  .cform__bubble::after{right:-14px;bottom:22%;transform:rotate(-45deg)}
  .cform__dog{width:110px;margin:0}
  .cform__row{grid-template-columns:1fr}
}


/* City pages: joinCTA's wave (with Carter on it) directly follows the plan
   cards — give the cards room so his board never clips the Platinum card. */
.plans--cleardog{padding-bottom:clamp(4.5rem,10vh,7.5rem)}



/* ── Carter newsletter band (sitewide, above the footer) ───────── */
.news{background:var(--sand);border-top:1px solid rgba(9,33,69,.14);padding-block:clamp(1.8rem,4.5vh,2.8rem)}
.news__in{display:grid;grid-template-columns:minmax(0,7fr) minmax(0,5fr);gap:clamp(1.5rem,4vw,3.5rem);align-items:center}
.news__carter{display:flex;gap:1rem;align-items:flex-end}
.news__dog{width:92px;height:auto;flex:none;filter:drop-shadow(0 6px 8px rgba(9,33,69,.22))}
.news__bubble{position:relative;background:#fff;border:2.5px solid var(--navy);border-radius:1rem;
  padding:.8rem 1rem;box-shadow:4px 5px 0 var(--navy)}
.news__bubble p{margin:0;font-size:.9rem;line-height:1.5}
.news__bubble a{color:var(--deep);font-weight:700;text-decoration:underline}
.news__bubble::after{content:"";position:absolute;left:-11px;bottom:18%;width:18px;height:18px;background:#fff;
  border-left:2.5px solid var(--navy);border-bottom:2.5px solid var(--navy);transform:rotate(45deg);
  clip-path:polygon(0 0,0 100%,100% 100%)}
.news__form{display:flex;gap:.6rem;flex-wrap:wrap;position:relative}
.news__form input[type="email"]{flex:1 1 14rem;font:inherit;font-size:1rem;color:var(--ink);
  border:2px solid var(--navy);border-radius:999px;padding:.72rem 1.1rem;background:#fff}
.news__form input[type="email"]:focus{outline:none;border-color:var(--deep)}
.news__form input:-webkit-autofill{-webkit-box-shadow:0 0 0 40px #fff inset;-webkit-text-fill-color:var(--ink)}
.news__note{flex-basis:100%;margin:.4rem 0 0;font-size:.88rem;background:#FFF4D6;
  border:2px solid var(--sun-deep);border-radius:.7rem;padding:.6rem .9rem}
.news__note--ok,.cform__note--ok{background:#E8F7EC;border-color:#2E7D48}
.news__note[hidden]{display:none}
.news__legal{flex-basis:100%;margin:.5rem 0 0;font-size:.74rem;color:var(--ink-soft)}
.news__legal a{text-decoration:underline;color:var(--deep)}
.cform__form .news__legal{margin-top:.8rem}
@media(max-width:900px){.news__in{grid-template-columns:1fr;gap:1.2rem}}


/* ── Carter weather toast (desktop, once per session) ── */
.wx-toast{position:fixed;right:1.1rem;bottom:1.1rem;z-index:60;display:flex;align-items:flex-end;
  gap:.55rem;max-width:21rem;animation:wxin .5s var(--ease)}
.wx-toast__bubble{position:relative;background:#fff;border:2.5px solid var(--navy);border-radius:1rem;
  padding:.85rem 2rem .85rem 1rem;box-shadow:4px 5px 0 var(--navy)}
.wx-toast__bubble p{margin:0;font-size:.9rem;line-height:1.45}
.wx-toast__bubble::after{content:"";position:absolute;right:-11px;bottom:16%;width:18px;height:18px;background:#fff;
  border-right:2.5px solid var(--navy);border-top:2.5px solid var(--navy);transform:rotate(45deg);
  clip-path:polygon(0 0,100% 0,100% 100%)}
.wx-toast__x{position:absolute;top:.3rem;right:.45rem;border:0;background:none;font-size:1.1rem;
  line-height:1;color:var(--ink-soft);cursor:pointer;padding:.15rem}
.wx-toast__x:hover{color:var(--navy)}
.wx-toast img{width:84px;height:auto;flex:none;filter:drop-shadow(0 8px 10px rgba(9,33,69,.3))}
.wx-toast--bye{opacity:0;transform:translateY(12px);transition:opacity .55s ease,transform .55s ease}
@keyframes wxin{from{opacity:0;transform:translateY(16px)}to{opacity:1;transform:none}}
@media(max-width:820px){
  /* ride above the sticky cta-bar; slightly tighter footprint */
  .wx-toast{bottom:calc(86px + env(safe-area-inset-bottom));right:.8rem;max-width:19rem}
  .wx-toast img{width:68px}
}



/* ── click-reliability hardening ──
   Decorative overlays must never eat a tap: the surf dog, card chips, and the
   weather toast's transparent bounding box all sat over clickable things. */
.surf__dog{pointer-events:none}
.chip{pointer-events:none}
.wx-toast{pointer-events:none}
.wx-toast__bubble{pointer-events:auto}
/* touch devices: no hover-transforms — some mobile browsers spend the first
   tap "hovering" an element whose style changes, forcing a second tap */
@media(hover:none){
  .wash:hover,.plate:hover,.call__item:hover{transform:none;box-shadow:inherit}
  .plate:hover .plate__img img{transform:none}
}




@keyframes cbin{from{opacity:0;transform:translateY(14px)}to{opacity:1;transform:none}}
.cookiebar--pulse{animation:cbpulse .55s ease 2}
@keyframes cbpulse{50%{transform:scale(1.025);box-shadow:0 0 0 4px rgba(250,192,33,.55)}}
@media(prefers-reduced-motion:reduce){.cookiebar,.cookiebar--pulse{animation:none}}

/* checkout failure notice on /join/ */
.join__error{margin:1.5rem auto 0;max-width:44ch;text-align:center;background:#FFF4D6;
  border:2px solid var(--sun);border-radius:1rem;padding:1rem 1.25rem;color:var(--ink);font-weight:600}

/* ── footer nav: the site's link graph ────────────── */
.foot__nav{background:#071B39;color:rgba(255,255,255,.62);padding:clamp(2.5rem,6vh,4.5rem) 0 1rem;
  border-bottom:1px solid rgba(255,255,255,.08)}
.foot__grid{display:grid;align-items:start;gap:2rem clamp(1.5rem,3vw,3rem);
  grid-template-columns:repeat(auto-fit,minmax(min(100%,11rem),1fr))}
.foot__col h3{font-family:var(--display);text-transform:uppercase;font-size:.85rem;letter-spacing:.06em;
  color:var(--sun);margin:0 0 .9rem;transform:skewX(var(--skew))}
.foot__col ul{list-style:none;margin:0;padding:0}
.foot__col li{margin:0 0 .5rem;line-height:1.35}
.foot__col a{font-size:.85rem;color:rgba(255,255,255,.66);transition:color .2s var(--ease)}
.foot__col a:hover{color:#fff}

/* ── blog teaser ──────────────────────────────────── */
.reads{background:var(--foam);padding:clamp(3.5rem,9vh,6rem) 0}
.reads__head{text-align:center;max-width:52ch;margin:0 auto clamp(2rem,5vh,3rem)}
.reads__head h2{font-size:var(--t-h2);color:var(--navy)}
.reads__head p{color:var(--ink-soft);margin:1.1rem 0 0}
.reads__grid{display:grid;gap:1.5rem;grid-template-columns:repeat(3,1fr)}
@media(max-width:1000px){.reads__grid{grid-template-columns:1fr 1fr}
  .reads__grid > .read:last-child:nth-child(odd){grid-column:1/-1}}
@media(max-width:640px){.reads__grid{grid-template-columns:1fr}}
.read{background:#fff;border:2px solid var(--line);border-radius:1.25rem;padding:1.6rem 1.5rem;
  display:flex;flex-direction:column;transition:border-color .25s var(--ease),transform .25s var(--ease)}
.read:hover{border-color:var(--sun);transform:translateY(-4px)}
.read h3{font-family:var(--display);text-transform:uppercase;font-size:1.05rem;line-height:1.2;
  color:var(--navy);margin:0 0 .6rem;transform:skewX(var(--skew))}
.read p{margin:0;font-size:.88rem;color:var(--ink-soft)}
.read span{margin-top:auto;padding-top:1.1rem;font-family:var(--display);text-transform:uppercase;
  font-size:.78rem;letter-spacing:.05em;color:var(--sun-deep)}
.reads__all{text-align:center;margin-top:2.5rem}

/* ── coupons ──────────────────────────────────────── */
/* Explicit 6-track grid (not auto-fit): each card spans 2, so a full row is 3.
   The nth-child math centers a lone last card or a last pair — no orphans. */
.coupons__grid{display:grid;gap:1.5rem;grid-template-columns:repeat(6,1fr)}
.coupons__grid > .coupon{grid-column:span 2}
.coupons__grid > .coupon:last-child:nth-child(3n+1){grid-column:3/5}
.coupons__grid > .coupon:nth-last-child(2):nth-child(3n+1){grid-column:2/4}
.coupons__grid > .coupon:last-child:nth-child(3n+2){grid-column:4/6}
@media(max-width:1000px){
  .coupons__grid{grid-template-columns:1fr 1fr}
  .coupons__grid > .coupon{grid-column:auto}
  .coupons__grid > .coupon:last-child:nth-child(odd){grid-column:1/-1;justify-self:center;width:min(100%,34rem)}
}
@media(max-width:640px){.coupons__grid{grid-template-columns:1fr}
  .coupons__grid > .coupon:last-child:nth-child(odd){width:100%}}
.coupon{position:relative;background:#fff;border:2px dashed var(--sun-deep);border-radius:1.25rem;
  padding:1.75rem 1.6rem 1.4rem;display:flex;flex-direction:column}
.coupon__top{display:flex;align-items:baseline;justify-content:space-between;gap:1rem;
  border-bottom:2px dashed var(--line);padding-bottom:1rem;margin-bottom:1.1rem}
.coupon h3{font-family:var(--display);text-transform:uppercase;font-size:1.15rem;color:var(--navy);
  margin:0;transform:skewX(var(--skew));line-height:1.1}
.coupon__val{font-family:var(--display);font-size:2rem;color:var(--sun-deep);margin:0;
  line-height:1;font-variant-numeric:tabular-nums;white-space:nowrap}
.coupon__val small{font-size:.9rem;color:var(--ink-soft)}
/* struck-through regular price — only rendered when it comes from real menu data */
.coupon__was{font-size:1.15rem;color:var(--ink-soft);text-decoration-thickness:2px;
  text-decoration-color:var(--burnt);margin-right:.15rem}
.coupon ul{list-style:none;margin:0;padding:0}
.coupon li{font-size:.9rem;padding:.35rem 0;display:flex;gap:.6rem;align-items:baseline}
.coupon li::before{content:"";flex:none;width:.5rem;height:.5rem;border-radius:50%;background:var(--sun)}
/* margin-top:auto pins the fine print + barcode to the bottom of the card, so
   across a row every barcode lands on the same line however uneven the bullet
   lists above them are. Without it the codes float mid-card at random heights. */
.coupon__fine{margin:1.2rem 0 0;margin-top:auto;padding-top:1rem;border-top:1px solid var(--line);
  font-size:.72rem;line-height:1.5;color:var(--ink-soft)}
/* The scan stub. Dashed rule matches .coupon__top's divider so it reads as part
   of the coupon language rather than a pasted-on image. */
.coupon__code{margin-top:1rem;padding-top:1rem;border-top:2px dashed var(--line);
  display:flex;flex-direction:column;align-items:center;gap:.5rem}
.coupon__scan{font-family:var(--display);text-transform:uppercase;letter-spacing:.06em;
  font-size:.62rem;color:var(--ink-soft)}
/* Rendered at the GIF's natural 226x100 so the bars are never resampled — a
   scaled barcode is what a handheld scanner misreads. The padding is the quiet
   zone: the source GIF's ink runs to within 1px of its right edge, and a scanner
   needs clear space either side of the bars to find them. */
.coupon__code img{width:226px;max-width:100%;height:auto;background:#fff;
  padding:.4rem .7rem;border-radius:.35rem;
  image-rendering:-webkit-optimize-contrast;image-rendering:crisp-edges}
@media(max-width:420px){.coupon__code img{padding:.4rem .3rem}}

/* ── trust stats strip ────────────────────────────── */
.stats{background:var(--foam);padding:clamp(2rem,5vh,3.25rem) 0;border-bottom:1px solid var(--line)}
.stats__grid{display:grid;gap:1.5rem;grid-template-columns:repeat(auto-fit,minmax(min(50%,10rem),1fr));text-align:center}
.stat__v{display:block;font-family:var(--display);font-size:clamp(2rem,1.2rem + 2vw,2.9rem);
  color:var(--deep);line-height:1;transform:skewX(var(--skew))}
.stat__l{display:block;margin-top:.5rem;font-size:.78rem;letter-spacing:.14em;text-transform:uppercase;
  font-weight:700;color:var(--ink-soft)}

/* ── how it works ─────────────────────────────────── */
.how{background:#fff;padding:clamp(3.5rem,9vh,6rem) 0}
.how__head{text-align:center;max-width:56ch;margin:0 auto clamp(2rem,5vh,3rem)}
.how__head h2{font-size:var(--t-h2);color:var(--navy)}
.how__head p{color:var(--ink-soft);margin:1.1rem 0 0}
.how__grid{display:grid;gap:1.5rem;grid-template-columns:1fr}
@media(min-width:900px){.how__grid{grid-template-columns:repeat(3,1fr)}}
.step{background:var(--foam);border-radius:1.25rem;padding:2rem 1.75rem}
.step__n{font-family:var(--display);font-size:3rem;color:var(--sun);line-height:1;display:block;
  transform:skewX(var(--skew));margin-bottom:.75rem}
.step h3{font-family:var(--display);text-transform:uppercase;font-size:1.15rem;color:var(--navy);
  margin:0 0 .5rem;transform:skewX(var(--skew))}
.step p{margin:0;font-size:.92rem;color:var(--ink-soft)}

/* ── reviews ──────────────────────────────────────── */
.says{background:var(--navy);color:#fff;padding:clamp(3.5rem,9vh,6rem) 0}
.says__head{text-align:center;margin:0 auto clamp(2rem,5vh,3rem)}
.says__head h2{font-size:var(--t-h2)}
.says__grid{display:grid;gap:1.5rem;grid-template-columns:1fr}
@media(min-width:640px){.says__grid{grid-template-columns:repeat(2,1fr)}}
@media(min-width:1080px){.says__grid{grid-template-columns:repeat(4,1fr)}}
.say{margin:0;background:rgba(255,255,255,.06);border:1px solid rgba(255,255,255,.12);
  border-radius:1.25rem;padding:1.75rem 1.5rem;display:flex;flex-direction:column}
.say__stars{color:var(--sun);letter-spacing:.15em;font-size:.95rem;margin-bottom:.9rem}
.say blockquote{margin:0;font-size:.95rem;line-height:1.6;color:rgba(255,255,255,.88)}
.say figcaption{margin-top:auto;padding-top:1.2rem;font-size:.78rem;letter-spacing:.1em;
  text-transform:uppercase;font-weight:700;color:rgba(255,255,255,.5)}

/* ═══════ v3 "beach depth" pass — Moxom layering × sticker borders × Waves warmth ═══════ */
:root{--sand:#F7EFDC;--sand-deep:#EFE2C2}

/* layered hero: giant type behind, framed video card in front, dog on the frame */
.h3{position:relative;background:var(--sand);color:var(--navy);overflow:hidden;isolation:isolate}
.h3__word{position:absolute;z-index:0;top:clamp(.5rem,3vh,2rem);left:50%;transform:translateX(-50%) skewX(-8deg);
  font-family:Anton,sans-serif;font-size:clamp(7rem,23vw,21rem);line-height:.9;
  color:transparent;-webkit-text-stroke:2px rgba(9,33,69,.13);white-space:nowrap;user-select:none;pointer-events:none}
.h3__in{position:relative;z-index:1;display:grid;grid-template-columns:minmax(0,11fr) minmax(0,10fr);
  gap:clamp(2.5rem,6vw,5rem);align-items:center;
  padding-block:clamp(3.5rem,9vh,6.5rem) clamp(4.5rem,11vh,8rem)}
.h3 h1{font-size:clamp(2.1rem,.9rem + 3.9vw,4.15rem)}
.h3__sub{margin:1.5rem 0 0;max-width:44ch;color:rgba(9,33,69,.78);font-size:clamp(1rem,.95rem + .35vw,1.15rem)}
.h3__stats{display:flex;flex-wrap:wrap;gap:.6rem 2rem;margin-top:2.4rem;font-size:.74rem;
  letter-spacing:.14em;text-transform:uppercase;font-weight:700;color:rgba(9,33,69,.55)}
.chrome{background:linear-gradient(180deg,#FFE28C 8%,#FAC021 38%,#EE920B 64%,#BB510B 96%);
  -webkit-background-clip:text;background-clip:text;color:transparent;
  filter:drop-shadow(2px 3px 0 rgba(9,33,69,.92))}

.vcard{position:relative;border:5px solid var(--navy);border-radius:1.4rem;background:var(--navy);
  box-shadow:14px 16px 0 var(--navy),14px 16px 0 1px rgba(9,33,69,.2);transform:rotate(1.5deg)}
.vcard--tall{max-width:clamp(280px,26vw,370px);margin-left:auto;transform:rotate(2deg)}
.vcard--tall .vcard__media{aspect-ratio:9/16}
.vcard__media{border-radius:.95rem;overflow:hidden;display:block;aspect-ratio:16/10;background:var(--navy)}
.vcard__media video,.vcard__media img{width:100%;height:100%;object-fit:cover;display:block}
.vcard__dog{position:absolute;z-index:3;left:-2.2rem;bottom:-2.4rem;width:clamp(90px,9vw,135px);
  transform:rotate(-7deg);transform-origin:50% 90%;
  filter:drop-shadow(0 10px 12px rgba(9,33,69,.35));animation:bob 5.5s ease-in-out infinite}
.chip{position:absolute;z-index:3;background:#fff;border:3px solid var(--navy);border-radius:999px;
  padding:.5rem 1.05rem;font-weight:800;font-size:.86rem;color:var(--navy);
  box-shadow:5px 6px 0 var(--navy);white-space:nowrap}
.chip--sun{background:var(--sun)}
/* Chips hang off the card corners on wide screens. Once the card sits against
   the gutter (tablet) that overhang gets clipped by .h3's overflow, so tuck them
   inside instead of letting half the price chip disappear. */
.chip--tr{top:-1.15rem;right:-.7rem}
.chip--tl{top:-1.15rem;left:-.7rem}
.chip--br{bottom:-1.25rem;right:-.8rem}
@media(max-width:1000px){
  .chip--tr{top:-1rem;right:.6rem}
  .chip--tl{top:-1rem;right:.6rem;left:auto}
  /* the card is narrow here, so this chip's text runs left under the surfing dog
     and loses its first characters. The address is already in the util bar, the
     hero copy and the footer — drop the chip rather than have the two collide. */
  .chip--br{display:none}
}
.chip b{font-family:Anton,sans-serif;font-weight:400;font-size:1.02rem;letter-spacing:.03em;margin-right:.3rem}
/* Stack at 820, NOT 950. The two breakpoints have to agree: below 820 the sticky
   cta-bar takes over the hero's buttons, so stacking at 950 left 820–950px with a
   single-column hero, no sticky bar, and the giant word running through the H1. */
@media(max-width:820px){
  .h3__in{grid-template-columns:1fr;gap:1.6rem;padding-block:clamp(1.6rem,4vh,3rem) clamp(4.5rem,10vh,7rem)}
  .vcard{transform:rotate(0);margin-left:1.5rem;margin-right:.5rem}
  .vcard--tall{margin:.4rem auto 0;max-width:min(70vw,300px)}
  .h3__word{font-size:clamp(6rem,26vw,12rem)}
  .h3__sub{margin-top:1rem}
  .h3 .hero__actions{margin-top:1.4rem}
}
/* mobile: the sticky cta-bar already carries Call + Join — don't repeat them in
   the hero; one button + the video reel above the fold instead */
@media(max-width:820px){
  .h3 .hero__actions .btn--sun,.h3 .hero__actions .btn--line{display:none}
  .h3__stats{display:none}
}

/* Phone: get the video reel above the fold. Everything above it is on a budget —
   the sub is clamped (full text stays in the DOM for crawlers), padding is tight,
   and the card goes 4/5 instead of 9/16 so it is wide rather than tall. Tuned
   against 390x844 minus the 70px sticky cta-bar. */
@media(max-width:560px){
  .h3__in{padding-block:1rem 3rem;gap:1.1rem}
  /* NO line-clamp. Truncated marketing copy ("never by…") reads as broken.
     If a sub is too long for a phone, shorten the COPY — don't cut it in CSS. */
  .h3__sub{margin-top:.7rem}
  .h3 .hero__actions{margin-top:1rem}
  .vcard--tall{max-width:min(76vw,290px);margin-top:0}
  /* Fixed ratio on purpose. Do NOT size this from 100dvh: dvh changes as Safari's
     URL bar collapses on scroll, so the card visibly resizes mid-scroll and
     reflows the page under the reader. A stable card that may sit slightly under
     the fold beats one that jumps. */
  .vcard--tall .vcard__media{aspect-ratio:4/5}
  .util__in{padding-block:.4rem}
}

/* benefits ticker */
.tick{background:var(--navy);overflow:hidden}
.tick__row{display:flex;width:max-content;white-space:nowrap;padding-block:.72rem;
  font-family:Anton,sans-serif;color:var(--sun);text-transform:uppercase;letter-spacing:.07em;
  font-size:clamp(.95rem,.85rem + .5vw,1.25rem);animation:tickmove 32s linear infinite}
.tick__row span{padding-inline:1.35rem;display:inline-flex;align-items:center}
.tick__row .tick__dot{color:var(--sky);padding-inline:0}
@keyframes tickmove{to{transform:translateX(-50%)}}
@media(prefers-reduced-motion:reduce){.tick__row{animation:none}}

/* Moxom-style numbered stats */
.nstats{background:var(--sand);border-top:1px solid rgba(9,33,69,.14);border-bottom:1px solid rgba(9,33,69,.14)}
.nstats__grid{display:grid;grid-template-columns:repeat(4,1fr)}
.nstat{display:flex;gap:.85rem;align-items:baseline;padding:1.9rem 1.5rem;border-left:1px solid rgba(9,33,69,.14)}
.nstat:first-child{border-left:0}
.nstat__n{font-family:Anton,sans-serif;font-size:clamp(2.4rem,1.8rem + 2.2vw,3.9rem);line-height:1;color:var(--deep)}
.nstat__l{display:block;font-size:.7rem;letter-spacing:.16em;text-transform:uppercase;font-weight:700;color:var(--burnt)}
.nstat__v{display:block;font-family:Anton,sans-serif;font-size:clamp(1.05rem,1rem + .5vw,1.5rem);color:var(--navy);margin-top:.2rem}
@media(max-width:820px){
  .nstats__grid{grid-template-columns:1fr 1fr}
  .nstat{padding:1.05rem .95rem;gap:.65rem;align-items:flex-start}
  .nstat:nth-child(3){border-left:0}
  .nstat:nth-child(n+3){border-top:1px solid rgba(9,33,69,.14)}
  .nstat__n{font-size:1.9rem;line-height:1.05}
  .nstat__l{font-size:.58rem;letter-spacing:.09em;line-height:1.45}
  .nstat__v{font-size:1.12rem;margin-top:.1rem}
}

/* sticker cards (wash menu, sitewide) */
.menu{background:var(--sand)}
.wash{border:3px solid var(--navy);border-radius:1.1rem;box-shadow:8px 9px 0 var(--navy);
  transition:transform .18s ease,box-shadow .18s ease}
.wash:hover{transform:translate(-3px,-4px);box-shadow:12px 14px 0 var(--navy);border-color:var(--navy)}

/* polaroid photo band */
.band__cell{background:#fff;padding:.5rem .5rem 1.6rem;border-radius:.45rem;
  box-shadow:0 16px 32px rgba(0,0,0,.38);transform:rotate(-1.2deg);
  display:flex;flex-direction:column}
.band__cell:nth-child(2n){transform:rotate(1deg)}
.band__cell:nth-child(5){transform:rotate(-.6deg)}
.band__cell img{border-radius:.25rem;flex:1 1 auto;min-height:0;width:100%;height:100%;object-fit:cover}
.band__cell:hover{transform:rotate(0) scale(1.02);transition:transform .25s ease}

/* v3 CTA architecture */
.btn--line{background:transparent;color:var(--navy);border-color:var(--navy)}
.btn--line:hover{background:rgba(9,33,69,.08)}
.nav__call{border-color:rgba(255,255,255,.5)!important}
@media(max-width:700px){.nav__call{display:none}}
.diff__cta{text-align:center;margin:2.2rem 0 0}
.cta-bar{display:none}
@media(max-width:820px){
  body{padding-bottom:70px}
  /* Three EQUAL columns. The old 1fr/1.25fr/1.6fr ratio left the bar visibly
     ragged; the label shrinks to fit rather than the button growing. */
  .cta-bar{position:fixed;bottom:0;left:0;right:0;z-index:70;display:grid;
    grid-template-columns:repeat(3,1fr);gap:.55rem;background:var(--navy);
    border-top:3px solid var(--sun);padding:.55rem .7rem calc(.55rem + env(safe-area-inset-bottom))}
  .cta-bar a{display:flex;align-items:center;justify-content:center;font-family:var(--display);
    text-transform:uppercase;letter-spacing:.02em;font-size:clamp(.68rem,3vw,.92rem);color:#fff;
    white-space:nowrap;border:2px solid rgba(255,255,255,.4);border-radius:.7rem;padding:.68rem .3rem}
  .cta-bar a.cta-bar__join{background:var(--sun);color:var(--navy);border-color:var(--sun)}
}

/* v3 photo density: card image tops, step photos, filmstrip marquee */
.wash{overflow:hidden}
.wash__img{margin:-1.6rem -1.5rem 1.1rem;border-bottom:3px solid var(--navy);aspect-ratio:16/9;overflow:hidden}
.wash__img img{width:100%;height:100%;object-fit:cover}
/* Tier badge. A contained sticker chip, NOT a full-bleed panel: blown up to
   hero size these line icons read thin and cheap, and the empty gradient around
   them dwarfed the price. Each tier tints a step deeper so the row still reads
   as a ladder. */
.wash__badge{width:5.4rem;height:5.4rem;flex:none;border-radius:1rem;margin-bottom:1rem;
  display:grid;place-items:center;background:#EAF3FB;
  border:3px solid var(--navy);box-shadow:4px 5px 0 var(--navy)}
.wash__badge--2{background:#DDEDFA}
.wash__badge--3{background:#CFE4F7}
.wash__badge--4{background:#BFDAF3}
.wash__ico{display:block;width:3.5rem;height:3.5rem;object-fit:contain}
.wash:hover .wash__badge,.plate:hover .wash__badge{transform:translate(-2px,-2px);
  box-shadow:6px 7px 0 var(--navy);transition:transform .2s ease,box-shadow .2s ease}
.plate__badge{margin:1.4rem 1.5rem 0}
.step__img{border-radius:.8rem;overflow:hidden;aspect-ratio:16/10;margin-bottom:1rem;border:3px solid var(--navy);box-shadow:6px 7px 0 var(--navy)}
.step__img img{width:100%;height:100%;object-fit:cover}
.strip{background:var(--navy);padding-block:1.6rem;overflow:hidden;position:relative}
.strip__row{display:flex;gap:1rem;width:max-content;animation:tickmove 55s linear infinite}
.strip__cell{width:clamp(200px,24vw,320px);aspect-ratio:3/2;border-radius:.8rem;overflow:hidden;
  border:3px solid rgba(255,255,255,.9);transform:rotate(-1.2deg)}
.strip__cell:nth-child(2n){transform:rotate(1.1deg)}
.strip__cell img{width:100%;height:100%;object-fit:cover}
.strip__cta{text-align:center;margin-top:1.4rem}
@media(prefers-reduced-motion:reduce){.strip__row{animation:none}}

/* ── mobile header: burger + slide-down menu ── */
.nav__burger{display:none;flex-direction:column;justify-content:center;gap:5px;width:44px;height:44px;
  background:transparent;border:2px solid rgba(255,255,255,.5);border-radius:.6rem;cursor:pointer;padding:9px}
.nav__burger span{display:block;height:2.5px;border-radius:2px;background:#fff;transition:transform .22s var(--ease),opacity .22s}
.nav__burger.is-open span:nth-child(1){transform:translateY(7.5px) rotate(45deg)}
.nav__burger.is-open span:nth-child(2){opacity:0}
.nav__burger.is-open span:nth-child(3){transform:translateY(-7.5px) rotate(-45deg)}
@media(max-width:1000px){.nav__burger{display:flex}}
.mnav{position:absolute;top:100%;left:0;right:0;background:var(--navy);z-index:49;
  box-shadow:0 24px 40px rgba(4,14,30,.5);border-top:3px solid var(--sun)}
.nav{position:sticky}
.mnav__links{list-style:none;margin:0;padding:.6rem 0}
.mnav__links a{display:block;padding:.85rem var(--gutter);color:#fff;font-family:var(--display);
  text-transform:uppercase;letter-spacing:.05em;font-size:1.05rem;border-bottom:1px solid rgba(255,255,255,.08)}
.mnav__links a:active,.mnav__links a:hover{background:rgba(255,255,255,.06);color:var(--sun)}
/* Deliberate 2-col grid, not flex-wrap: wrapping left the three buttons ragged
   (long Join button on its own line, then two odd-width ghosts). Join spans the
   full width; Call and Directions are exact halves. */
.mnav__actions{display:grid;grid-template-columns:1fr 1fr;gap:.7rem;padding:1rem var(--gutter) 1.3rem}
.mnav__actions > .btn{width:100%;justify-content:center;padding-inline:.75rem;text-align:center}
.mnav__actions > .btn:first-child{grid-column:1 / -1}
/* tighten small-screen chrome */
@media(max-width:640px){
  .util__in > span:last-child{display:none}
  .util__in{justify-content:center}
}
@media(max-width:520px){
  .nav__logo{width:52px}
  .nav__in{gap:.8rem}
  .nav__cta .btn--sm{font-size:.74rem;padding:.55rem .9rem}
}
.says__all{text-align:center;margin:2rem 0 0}

/* cookie consent banner */
.cookiebar{animation:cbin .4s var(--ease);position:fixed;z-index:80;left:1rem;bottom:1rem;max-width:26rem;background:#fff;
  border:3px solid var(--navy);border-radius:1rem;box-shadow:8px 9px 0 var(--navy);
  padding:1rem 1.1rem;font-size:.9rem;line-height:1.5}
.cookiebar p{margin:0 0 .8rem;color:var(--ink)}
.cookiebar a{color:var(--deep);font-weight:700;text-decoration:underline}
.cookiebar__btns{display:flex;gap:.6rem;flex-wrap:wrap}
.cookiebar button{font-family:var(--display);text-transform:uppercase;letter-spacing:.03em;
  font-size:.85rem;padding:.55rem 1rem;border-radius:999px;cursor:pointer;border:2px solid var(--navy)}
.cookiebar__accept{background:var(--sun);color:var(--navy);box-shadow:0 4px 0 var(--sun-deep)}
.cookiebar__accept:hover{transform:translateY(-1px)}
.cookiebar__min{background:#fff;color:var(--navy)}
.cookiebar__min:hover{background:rgba(9,33,69,.06)}
@media(max-width:820px){
  .cookiebar{left:.7rem;right:.7rem;max-width:none;bottom:calc(78px + env(safe-area-inset-bottom))}
}

/* service-area city cards: one clean grid, drive times instead of link lists */
.area__grid{display:grid;gap:.9rem;margin-top:2.4rem;grid-template-columns:repeat(3,1fr)}
.citycard{display:flex;flex-direction:column;gap:.15rem;background:#fff;border:2px solid var(--navy);
  border-radius:.9rem;padding:.95rem 1.1rem;box-shadow:5px 6px 0 var(--navy);
  transition:transform .18s ease,box-shadow .18s ease;text-align:left}
.citycard b{font-family:var(--display);font-weight:400;text-transform:uppercase;
  letter-spacing:.02em;color:var(--navy);font-size:1.02rem}
.citycard span{font-size:.78rem;color:var(--ink-soft)}
.citycard:hover{transform:translate(-2px,-3px);box-shadow:8px 10px 0 var(--navy)}
@media(max-width:700px){.area__grid{grid-template-columns:repeat(2,1fr)}
  .citycard:last-child:nth-child(odd){grid-column:span 2}}

/* modern util bar: live open status + rating */
.util__open{display:inline-flex;align-items:center;gap:.45rem}
.util__open b{font-weight:700;letter-spacing:.02em}
.util__dot{width:.55rem;height:.55rem;border-radius:50%;background:#2ecc71;box-shadow:0 0 0 0 rgba(46,204,113,.55);animation:pulse 2.2s infinite}
.util__dot--closed{background:#e67e22;animation:none}
@keyframes pulse{0%{box-shadow:0 0 0 0 rgba(46,204,113,.55)}70%{box-shadow:0 0 0 7px rgba(46,204,113,0)}100%{box-shadow:0 0 0 0 rgba(46,204,113,0)}}
@media(max-width:640px){.util__addr{display:none}.util__meta .util__sep{display:none}}

/* detailing reel section */
.reel{background:var(--sand);padding-block:clamp(2.5rem,7vh,4.5rem)}
.reel__in{display:grid;grid-template-columns:minmax(0,7fr) minmax(0,5fr);gap:clamp(2rem,5vw,4rem);align-items:center}
.reel h2{font-size:var(--t-h2);color:var(--navy)}
.reel p{color:var(--ink-soft);max-width:48ch}
@media(max-width:900px){.reel__in{grid-template-columns:1fr;gap:1.8rem}}

/* Nav JOIN button: the global 4px sun shadow reads heavy on the slim navy bar —
   soften it here only, never globally. */
.nav__cta .btn--sun{box-shadow:0 3px 0 var(--sun-deep)}
.nav__cta .btn--sun:hover{box-shadow:0 5px 0 var(--sun-deep)}

/* Carter's weather line in the util bar (populated by site.js; hidden until it is) */
.util__wx{color:rgba(255,255,255,.72)}
.util__wx::before{content:"\00b7";margin:0 .6rem;opacity:.4}
/* below ~1200 the line forces the bar onto two rows — hide it rather than wrap */
@media(max-width:1199px){.util__wx{display:none}}
