/* ============================================================
   aCquatica Pool Service — Ocala, FL
   Palette: cobalt pool tile + waterline aqua + marble coping
   Type:    Bricolage Grotesque (display) / Public Sans (body)
   ============================================================ */

:root{
  /* ground */
  --marble:      #F2F1EC;
  --marble-warm: #E9E7DF;
  --white:       #FFFFFF;

  /* tile */
  --navy:        #123A5E;
  --navy-deep:   #0C2942;
  --navy-ink:    #081D2F;
  --glaze:       #1E5C8A;
  --aqua:        #2FB3C9;
  --aqua-lit:    #57CFE0;

  /* ink — biased toward the navy, never a neutral grey */
  --ink:         #0D1B26;
  --ink-2:       #35505F;
  --ink-3:       #6C8492;
  --line:        #D9D8D0;
  --line-dark:   rgba(255,255,255,.14);

  --radius:   14px;
  --radius-s: 9px;
  --shadow:   0 1px 2px rgba(13,27,38,.05), 0 8px 26px -14px rgba(13,27,38,.28);
  --shadow-l: 0 2px 4px rgba(13,27,38,.06), 0 26px 60px -28px rgba(13,27,38,.42);

  --ease: cubic-bezier(.2,.65,.25,1);

  --s1:8px; --s2:12px; --s3:16px; --s4:24px; --s5:32px; --s6:48px; --s7:74px; --s8:110px;

  --wrap: 1160px;
}

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

html,body{ overflow-x:clip; }

html{ scroll-behavior:smooth; -webkit-text-size-adjust:100%; }

body{
  margin:0;
  background:var(--marble);
  color:var(--ink);
  font-family:"Public Sans",system-ui,-apple-system,"Segoe UI",sans-serif;
  font-size:17px;
  line-height:1.62;
  -webkit-font-smoothing:antialiased;
}

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

a{ color:inherit; }

h1,h2,h3{
  font-family:"Bricolage Grotesque","Public Sans",system-ui,sans-serif;
  font-weight:700;
  line-height:1.06;
  letter-spacing:-.022em;
  text-wrap:balance;
  margin:0;
}
h1{ font-size:clamp(40px,6.6vw,76px); }
h2{ font-size:clamp(29px,4.2vw,48px); }
h3{ font-size:20px; letter-spacing:-.012em; line-height:1.24; }

p{ margin:0; }

.wrap{ width:100%; max-width:var(--wrap); margin-inline:auto; padding-inline:var(--s4); }

.eyebrow{
  font-size:12px; font-weight:700; letter-spacing:.16em;
  text-transform:uppercase; color:var(--aqua); margin:0;
}

.stars{ color:var(--aqua); letter-spacing:.1em; font-size:14px; }

.cu{ font-variant-numeric:tabular-nums; }

.skip{
  position:absolute; left:-9999px; top:0; z-index:200;
  background:var(--navy); color:#fff; padding:12px 18px; border-radius:0 0 var(--radius-s) 0;
}
.skip:focus{ left:0; }

:where(a,button,input,select,textarea,[tabindex]):focus-visible{
  outline:3px solid var(--aqua);
  outline-offset:3px;
  border-radius:4px;
}

/* ---------------- buttons ---------------- */

.btn{
  --btn-bg:var(--aqua);
  display:inline-flex; align-items:center; justify-content:center;
  gap:8px; min-height:48px; padding:0 22px;
  background:var(--btn-bg); color:var(--navy-ink);
  font-family:"Public Sans",sans-serif; font-weight:700; font-size:15.5px;
  letter-spacing:.005em; text-decoration:none; white-space:nowrap;
  border:0; border-radius:999px; cursor:pointer;
  transition:transform .2s var(--ease), background-color .2s var(--ease), box-shadow .2s var(--ease);
  box-shadow:0 1px 0 rgba(255,255,255,.35) inset;
}
.btn:hover{ background:var(--aqua-lit); transform:translateY(-2px); }
.btn:active{ transform:translateY(0); }
.btn-sm{ min-height:44px; padding:0 18px; font-size:14.5px; }
.btn-lg{ min-height:56px; padding:0 30px; font-size:16.5px; }
.btn-full{ width:100%; }
.btn-ghost{
  --btn-bg:transparent;
  color:#fff; box-shadow:inset 0 0 0 1.5px rgba(255,255,255,.5);
}
.btn-ghost:hover{ --btn-bg:rgba(255,255,255,.12); box-shadow:inset 0 0 0 1.5px #fff; }

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

.nav{
  position:sticky; top:0; z-index:60;
  background:rgba(242,241,236,.92);
  border-bottom:1px solid var(--line);
}
.nav-in{
  max-width:var(--wrap); margin-inline:auto;
  padding:12px var(--s4);
  display:flex; align-items:center; gap:var(--s4);
}
/* Every anchor target clears the sticky header when jumped to. */
section[id], #main, #top{ scroll-margin-top:82px; }
#top{ position:absolute; top:0; height:0; }

.brand{
  display:flex; align-items:center; gap:11px; text-decoration:none;
  margin-right:auto; min-height:44px; padding-right:6px;
}
.brand-mark{
  width:30px; height:30px; border-radius:9px; flex:none;
  background:
    radial-gradient(120% 120% at 30% 20%, var(--aqua-lit) 0%, var(--glaze) 45%, var(--navy) 100%);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.5);
}
.brand-txt{ display:flex; flex-direction:column; line-height:1.05; }
.brand-txt b{
  font-family:"Bricolage Grotesque",sans-serif; font-size:19px; font-weight:800;
  letter-spacing:-.02em; color:var(--navy);
}
.brand-txt span{ font-size:10.5px; letter-spacing:.15em; text-transform:uppercase; color:var(--ink-3); }
.nav-links{ display:flex; gap:26px; }
.nav-links a{
  font-size:15px; font-weight:500; color:var(--ink-2); text-decoration:none;
  transition:color .18s var(--ease);
}
.nav-links a:hover{ color:var(--navy); }

/* ---------------- hero ---------------- */

.hero{
  position:relative; isolation:isolate;
  min-height:clamp(560px,88svh,860px);
  display:flex; align-items:flex-end;
  padding:var(--s8) 0 var(--s7);
  color:#fff;
}
.hero-media{ position:absolute; inset:0; z-index:-1; overflow:hidden; }
.hero-media img{ width:100%; height:100%; object-fit:cover; }
.hero-scrim{
  position:absolute; inset:0; pointer-events:none;
  background:
    linear-gradient(180deg, rgba(8,29,47,.62) 0%, rgba(8,29,47,.30) 34%, rgba(8,29,47,.78) 82%, rgba(8,29,47,.92) 100%),
    linear-gradient(90deg, rgba(12,41,66,.72) 0%, rgba(12,41,66,.12) 62%);
}
.hero-in{
  width:100%; max-width:var(--wrap); margin-inline:auto; padding-inline:var(--s4);
  display:flex; flex-direction:column; gap:var(--s4); align-items:flex-start;
}
.hero-in h1{ max-width:15ch; }
.hero .lede{ max-width:56ch; font-size:18.5px; color:rgba(255,255,255,.9); }
.hero-cta{ display:flex; flex-wrap:wrap; gap:var(--s2); }
.hero-proof{
  display:flex; flex-wrap:wrap; align-items:center; gap:10px 14px;
  font-size:15px; color:rgba(255,255,255,.86);
  padding-top:var(--s2);
}
.hero-proof b{ color:#fff; }
.dot{ width:4px; height:4px; border-radius:50%; background:rgba(255,255,255,.45); }

/* ---------------- section heads ---------------- */

.sec-head{ display:flex; flex-direction:column; gap:var(--s3); max-width:64ch; }
.sec-head h2{ max-width:20ch; }
.sec-lede{ color:var(--ink-2); font-size:18px; max-width:60ch; }

/* ---------------- recovery / compare ---------------- */

.recovery{
  background:var(--navy-deep);
  color:#fff;
  padding:var(--s8) 0;
  position:relative; z-index:1;
}
.recovery .sec-lede{ color:rgba(255,255,255,.76); }
.recovery h2{ max-width:22ch; }

.cmp{ margin-top:var(--s6); }
.cmp-frame{
  position:relative; overflow:hidden;
  border-radius:var(--radius);
  box-shadow:var(--shadow-l);
  aspect-ratio:3/2;
  touch-action:pan-y;
  --pos:58%;
}
.cmp-frame > img,
.cmp-before img{
  position:absolute; inset:0;
  width:100%; height:100%; object-fit:cover;
  /* Both sources are 3:2, so nothing crops on desktop. On the taller mobile
     crop this keeps each pool in the same part of the frame so the two halves
     line up as the handle passes over them. */
  object-position:50% 34%;
}
/* Mask, don't resize. Clipping by width squashes the image horizontally, so the
   two halves stop lining up and it reads as a different photo. clip-path keeps
   both layers at identical size and simply hides part of the top one. */
.cmp-before{
  position:absolute; inset:0;
  width:100%;
  clip-path:inset(0 calc(100% - var(--pos)) 0 0);
}
/* Both sides are real photographs now — no colour grading, no overlay. */
.cmp-bar{
  position:absolute; top:0; bottom:0; left:var(--pos);
  width:3px; margin-left:-1.5px;
  background:rgba(255,255,255,.92);
  box-shadow:0 0 0 1px rgba(8,29,47,.28);
  pointer-events:none;
}
.cmp-knob{
  position:absolute; top:50%; left:50%; transform:translate(-50%,-50%);
  width:52px; height:52px; border-radius:50%;
  background:rgba(255,255,255,.96);
  box-shadow:0 6px 20px -6px rgba(8,29,47,.6);
  display:grid; place-items:center;
}
.cmp-knob::before,
.cmp-knob::after{
  content:""; position:absolute;
  width:0; height:0;
  border-block:5px solid transparent;
}
.cmp-knob::before{ left:13px; border-right:7px solid var(--navy); }
.cmp-knob::after{ right:13px; border-left:7px solid var(--navy); }

.cmp-tag{
  position:absolute; top:14px;
  font-size:11.5px; font-weight:700; letter-spacing:.1em; text-transform:uppercase;
  padding:6px 11px; border-radius:999px;
  background:rgba(8,29,47,.6); color:#fff;
  backdrop-filter:none;
}
.cmp-tag-l{ left:14px; }
.cmp-tag-r{ right:14px; }

.cmp-sr{
  position:absolute; width:1px; height:1px; overflow:hidden;
  clip:rect(0 0 0 0); clip-path:inset(50%); white-space:nowrap;
}
.cmp-range{
  position:absolute; inset:0; width:100%; height:100%;
  margin:0; opacity:0; cursor:ew-resize;
  -webkit-appearance:none; appearance:none; background:transparent;
}
.cmp-range::-webkit-slider-thumb{ -webkit-appearance:none; width:64px; height:100%; }
.cmp-range::-moz-range-thumb{ width:64px; height:100%; border:0; opacity:0; }

.cmp-hint{
  margin:var(--s3) 0 0; text-align:center;
  font-size:13px; letter-spacing:.14em; text-transform:uppercase;
  color:rgba(255,255,255,.5);
}
.cmp.is-touched .cmp-hint{ opacity:0; transition:opacity .3s var(--ease); }

.recovery-note{
  margin-top:var(--s5);
  padding:var(--s4);
  border-radius:var(--radius-s);
  background:rgba(255,255,255,.06);
  border:1px solid var(--line-dark);
  max-width:72ch;
  color:rgba(255,255,255,.84);
  font-size:16.5px;
}
.recovery-note a{ color:var(--aqua-lit); text-underline-offset:3px; }

/* ---------------- services ---------------- */

.services{ padding:var(--s8) 0; position:relative; z-index:1; }
.svc-grid{
  margin-top:var(--s6);
  display:grid; gap:var(--s4);
  grid-template-columns:repeat(auto-fit,minmax(280px,1fr));
}
.svc{
  background:var(--white);
  border:1px solid var(--line);
  border-radius:var(--radius);
  overflow:hidden;
  box-shadow:var(--shadow);
  display:flex; flex-direction:column;
  transition:transform .25s var(--ease), box-shadow .25s var(--ease);
}
.svc:hover{ transform:translateY(-4px); box-shadow:var(--shadow-l); }
.svc-img{ overflow:hidden; aspect-ratio:8/5; }
.svc-img img{ width:100%; height:100%; object-fit:cover; transition:transform .5s var(--ease); }
.svc:hover .svc-img img{ transform:scale(1.045); }
.svc-lead .svc-img{ aspect-ratio:16/7; }
.svc-body{ padding:var(--s4); display:flex; flex-direction:column; gap:10px; }
.svc-body p{ color:var(--ink-2); font-size:16px; }
.pill{
  align-self:flex-start;
  font-size:11px; font-weight:700; letter-spacing:.1em; text-transform:uppercase;
  color:var(--navy); background:#CFEAF0;
  padding:4px 10px; border-radius:999px;
}
.svc-lead{ grid-column:span 2; }


/* ---------------- trust band ---------------- */

.band{
  background:var(--navy);
  color:#fff;
  padding:var(--s7) 0;
  position:relative; z-index:1;
}
.band-in{
  display:grid; gap:var(--s5);
  grid-template-columns:repeat(auto-fit,minmax(160px,1fr));
  text-align:center;
}
.stat{ display:flex; flex-direction:column; gap:2px; }
.stat b{
  font-family:"Bricolage Grotesque",sans-serif;
  font-size:clamp(44px,6vw,66px); font-weight:800; line-height:1;
  letter-spacing:-.03em; color:var(--aqua-lit);
  font-variant-numeric:tabular-nums;
}
.stat b span{ font:inherit; color:inherit; }
.stat > span{
  font-size:12px; letter-spacing:.14em; text-transform:uppercase;
  color:rgba(255,255,255,.66);
}

/* ---------------- about ---------------- */

.about{ padding:var(--s8) 0; position:relative; z-index:1; }
.about-in{
  display:grid; gap:var(--s6);
  grid-template-columns:minmax(0,.9fr) minmax(0,1fr);
  align-items:center;
}
.about-media{ border-radius:var(--radius); overflow:hidden; box-shadow:var(--shadow-l); }
.about-media img{ width:100%; aspect-ratio:4/3; object-fit:cover; }
.about-txt{ display:flex; flex-direction:column; gap:var(--s3); }
.about-txt p{ color:var(--ink-2); font-size:17.5px; max-width:56ch; }
.about-list{
  list-style:none; margin:var(--s2) 0 0; padding:0;
  display:flex; flex-direction:column; gap:10px;
}
.about-list li{
  position:relative; padding-left:26px; color:var(--ink-2); font-size:16.5px;
}
.about-list li::before{
  content:""; position:absolute; left:0; top:.62em;
  width:11px; height:11px; border-radius:50%;
  background:var(--aqua); box-shadow:0 0 0 4px rgba(47,179,201,.18);
}

/* ---------------- reviews ---------------- */

.reviews{
  background:var(--marble-warm);
  padding:var(--s8) 0;
  position:relative; z-index:1;
  border-block:1px solid var(--line);
}
.rev-grid{
  margin-top:var(--s6);
  display:grid; gap:var(--s4);
  grid-template-columns:repeat(auto-fit,minmax(270px,1fr));
}
.rev{
  margin:0; padding:var(--s5) var(--s4);
  background:var(--white); border:1px solid var(--line);
  border-radius:var(--radius);
  display:flex; flex-direction:column; gap:var(--s3);
  box-shadow:var(--shadow);
}
.rev blockquote{
  margin:0; font-size:18px; line-height:1.5; color:var(--ink);
  font-family:"Bricolage Grotesque",sans-serif; font-weight:400;
  letter-spacing:-.008em;
}
.rev figcaption{
  margin-top:auto; font-weight:700; font-size:15px;
  display:flex; align-items:baseline; gap:8px;
}
.rev figcaption span{
  font-weight:500; font-size:12px; letter-spacing:.1em;
  text-transform:uppercase; color:var(--ink-3);
}

/* ---------------- quote ---------------- */

.quote{
  background:var(--navy-ink); color:#fff;
  padding:var(--s8) 0;
  position:relative; z-index:1;
}
.quote-in{
  display:grid; gap:var(--s6);
  grid-template-columns:minmax(0,1fr) minmax(0,1.05fr);
  align-items:start;
}
.quote-txt{ display:flex; flex-direction:column; gap:var(--s3); }
.quote-txt p{ color:rgba(255,255,255,.78); font-size:17.5px; max-width:48ch; }
.quote-contact{
  list-style:none; margin:var(--s3) 0 0; padding:0;
  display:flex; flex-direction:column; gap:var(--s2);
  border-top:1px solid var(--line-dark); padding-top:var(--s4);
}
.quote-contact li{
  display:flex; gap:var(--s3); align-items:baseline;
  font-size:16.5px; color:rgba(255,255,255,.9);
}
.quote-contact li > span{
  flex:0 0 62px; font-size:11.5px; letter-spacing:.14em;
  text-transform:uppercase; color:rgba(255,255,255,.5);
}
.quote-contact a{
  color:var(--aqua-lit); text-decoration:none; font-weight:600;
  display:inline-flex; align-items:center; min-height:44px;
}

.form{
  background:rgba(255,255,255,.05);
  border:1px solid var(--line-dark);
  border-radius:var(--radius);
  padding:var(--s5);
  display:flex; flex-direction:column; gap:var(--s4);
}
.fields{ display:grid; gap:var(--s3); grid-template-columns:1fr 1fr; }
.field{ display:flex; flex-direction:column; gap:6px; }
.field-wide{ grid-column:1/-1; }
.field label{
  font-size:13px; font-weight:600; letter-spacing:.04em;
  color:rgba(255,255,255,.82);
}
.field label .opt{ font-weight:400; color:rgba(255,255,255,.45); text-transform:none; letter-spacing:0; }
.field input,
.field select,
.field textarea{
  width:100%; min-height:48px; padding:12px 14px;
  font-family:inherit; font-size:16px; color:#fff;
  background:rgba(255,255,255,.07);
  border:1px solid rgba(255,255,255,.2);
  border-radius:var(--radius-s);
  transition:border-color .18s var(--ease), background-color .18s var(--ease);
}
.field textarea{ resize:vertical; min-height:92px; }
/* A select with appearance:none loses its native arrow and reads as plain text.
   Put a chevron back so it's obviously a dropdown, not a field to type in. */
.field select{
  appearance:none;
  cursor:pointer;
  padding-right:46px;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2357CFE0' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  background-repeat:no-repeat;
  background-position:right 14px center;
  background-size:19px 19px;
  transition:border-color .18s var(--ease), background-color .18s var(--ease);
}
.field select:hover{ border-color:rgba(87,207,224,.55); }
.field select option{ color:var(--ink); background:var(--white); }
.field input:hover,
.field textarea:hover,
.field select:hover{ border-color:rgba(255,255,255,.38); }
.field input:focus,
.field textarea:focus,
.field select:focus{ background:rgba(255,255,255,.11); }
.field input::placeholder,
.field textarea::placeholder{ color:rgba(255,255,255,.4); }
.hint{ font-size:13px; color:rgba(255,255,255,.5); }

/* ---- photo upload (optional) ---- */

#photo-field{ scroll-margin-top:100px; }
.field-label{
  font-size:13px; font-weight:600; letter-spacing:.04em;
  color:rgba(255,255,255,.82);
}
.photo-row{
  display:flex; flex-wrap:wrap; align-items:center;
  gap:10px 14px; margin-top:4px;
}
.photo-btn{
  display:inline-flex; align-items:center; gap:9px;
  min-height:48px; padding:0 20px;
  border-radius:999px; cursor:pointer;
  background:rgba(255,255,255,.09);
  border:1.5px dashed rgba(255,255,255,.38);
  color:#fff; font-size:15.5px; font-weight:600;
  transition:background-color .18s var(--ease), border-color .18s var(--ease);
}
.photo-btn:hover{ background:rgba(255,255,255,.15); border-color:var(--aqua); }
.photo-btn svg{ width:20px; height:20px; flex:none; }
/* The native input stays keyboard-reachable; the label is what you see.
   Input sits before .photo-row so focus can be forwarded to the button. */
.photo-input{
  position:absolute; width:1px; height:1px; opacity:0;
  overflow:hidden; clip:rect(0 0 0 0); clip-path:inset(50%);
}
.photo-input:focus-visible ~ .photo-row .photo-btn{
  outline:3px solid var(--aqua); outline-offset:3px;
}
.photo-alt{
  display:inline-flex; align-items:center; min-height:44px;
  color:var(--aqua-lit); font-size:14.5px; font-weight:600;
  text-decoration:none; border-bottom:1px solid rgba(87,207,224,.4);
}
.photo-alt:hover{ border-bottom-color:var(--aqua-lit); }

.photo-list{
  list-style:none; margin:12px 0 0; padding:0;
  display:flex; flex-direction:column; gap:8px;
}
.photo-list:empty{ display:none; }
.photo-list li{
  display:flex; align-items:center; gap:12px;
  background:rgba(255,255,255,.07);
  border:1px solid rgba(255,255,255,.16);
  border-radius:var(--radius-s);
  padding:8px 8px 8px 12px;
  font-size:14px; color:rgba(255,255,255,.9);
}
.photo-thumb{
  width:44px; height:44px; flex:none; border-radius:6px;
  object-fit:cover; background:rgba(0,0,0,.25);
}
.photo-name{
  flex:1; min-width:0; overflow:hidden;
  text-overflow:ellipsis; white-space:nowrap;
}
.photo-size{ color:rgba(255,255,255,.5); font-size:13px; font-variant-numeric:tabular-nums; }
.photo-drop{
  flex:none; width:44px; height:44px; border-radius:50%;
  background:transparent; border:0; cursor:pointer;
  color:rgba(255,255,255,.7); font-size:20px; line-height:1;
  transition:background-color .18s var(--ease), color .18s var(--ease);
}
.photo-drop:hover{ background:rgba(255,255,255,.12); color:#fff; }
.err{ font-size:13px; color:#FF9E8C; min-height:0; }
.field.is-bad input{ border-color:#FF9E8C; }
.form-note{ font-size:13.5px; color:rgba(255,255,255,.5); text-align:center; }
.form-status{ font-size:15px; color:var(--aqua-lit); text-align:center; }

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

.foot{
  background:var(--navy-ink); color:rgba(255,255,255,.7);
  border-top:1px solid var(--line-dark);
  padding:var(--s6) 0 calc(var(--s6) + 72px);
  position:relative; z-index:1;
  font-size:15px;
}
.foot-in{
  display:grid; gap:var(--s4);
  grid-template-columns:repeat(auto-fit,minmax(220px,1fr));
}
.foot p{ margin:0 0 6px; }
.foot a{
  color:rgba(255,255,255,.88); text-decoration:none;
  display:inline-flex; align-items:center; min-height:44px;
}
.foot a:hover{ color:var(--aqua-lit); }
.foot-brand{
  font-family:"Bricolage Grotesque",sans-serif; font-weight:700;
  font-size:17px; color:#fff; letter-spacing:-.01em;
}
/* Column headings. The left column deliberately has none — the business name
   is already its heading, and leaving it bare keeps it the anchor of the row. */
.foot-head{
  font-size:11.5px; font-weight:700; letter-spacing:.16em;
  text-transform:uppercase; color:var(--aqua);
  margin:0 0 10px;
}

/* ---------------- mobile call bar ---------------- */

.callbar{
  position:fixed; left:0; right:0; bottom:0; z-index:70;
  display:none; gap:10px; padding:10px 14px calc(10px + env(safe-area-inset-bottom));
  background:var(--navy-ink);
  border-top:1px solid var(--line-dark);
}
.callbar-btn{
  flex:1; min-height:48px; border-radius:999px;
  display:flex; align-items:center; justify-content:center;
  background:var(--aqua); color:var(--navy-ink);
  font-weight:700; font-size:16px; text-decoration:none;
}
.callbar-alt{ background:transparent; color:#fff; box-shadow:inset 0 0 0 1.5px rgba(255,255,255,.45); }

/* ============================================================
   REVEALS
   Desktop: reversible — different curve entering vs leaving.
   Mobile:  fires once, then stays put (no scroll-linked work).
   ============================================================ */

/* Visible by default. Only the .js class (set by main.js) arms the reveal,
   so no-JS visitors and any script failure still get a complete page. */
.rv{ opacity:1; transform:none; }

.js .rv{
  opacity:0;
  transform:translate3d(0,16px,0);
  transition:
    opacity .22s var(--ease),
    transform .22s var(--ease);
  /* Stagger capped at three steps. Beyond that the later cards in a grid
     arrive after you've already scrolled to them. */
  transition-delay:calc((min(var(--i,1), 3) - 1) * 40ms);
  /* No will-change here. Promoting 36 elements to their own GPU layer for the
     whole life of the page is what made phones stutter while scrolling. */
}
.js .rv.in{ opacity:1; transform:translate3d(0,0,0); }
/* Leaving upward: softer and slower than the entrance, but still quick. */
.js .rv.out{
  opacity:0;
  transform:translate3d(0,22px,0);
  transition:
    opacity .3s var(--ease),
    transform .3s var(--ease);
  transition-delay:0ms;
}
.no-js .rv,
.rv.settled{ opacity:1; transform:none; transition:none; }

/* ---------------- responsive ---------------- */

@media (max-width:1000px){
  .about-in,
  .quote-in{ grid-template-columns:1fr; }
  .svc-lead{ grid-column:auto; }

}

@media (max-width:860px){
  :root{ --s7:56px; --s8:66px; }

  /* Trim supporting copy on phones. The sentences stay in the HTML for desktop
     and for search engines; they just don't crowd a small screen. */
  .wide-only{ display:none; }
  body{ font-size:16.5px; }
  .nav-links{ display:none; }
  .hero{ min-height:clamp(520px,84svh,760px); padding-bottom:var(--s6); }
  .hero .lede{ font-size:17px; }
  .hero-cta .btn{ flex:1 1 100%; }
  .callbar{ display:flex; }
  .cmp-frame{ aspect-ratio:4/5; }
  .cmp-knob{ width:60px; height:60px; }
  .cmp-tag{ font-size:10.5px; padding:5px 9px; }
  .fields{ grid-template-columns:1fr; }
  .form{ padding:var(--s4); }
  .rev blockquote{ font-size:17px; }

  /* Phones: keep it reversible and visible, but cheap. Shorter travel, and the
     exit fades only — animating just opacity avoids a second composited
     property while the page is already moving under momentum scroll. */
  .js .rv{
    transform:translate3d(0,9px,0);
    transition:opacity .2s var(--ease), transform .2s var(--ease);
    transition-delay:calc((min(var(--i,1), 2) - 1) * 35ms);
  }
  .js .rv.out{
    transform:none;
    transition:opacity .26s var(--ease);
  }
}

@media (max-width:520px){
  .wrap{ padding-inline:18px; }
  .hero-in{ padding-inline:18px; }
  .cmp-frame{ aspect-ratio:1/1; }
}

@media (prefers-reduced-motion:reduce){
  html{ scroll-behavior:auto; }
  *,*::before,*::after{
    animation-duration:.001ms !important;
    animation-iteration-count:1 !important;
    transition-duration:.001ms !important;
  }
  .rv,.rv.in,.rv.out{ opacity:1 !important; transform:none !important; }
  .cmp-hint{ display:none; }
}
