/* base.css — fleet-shared foundation. NEVER edited per client.
   Brand comes from :root tokens (head.php) + one skin file.
   Skins may set: --radius, --shadow, --section-bg-alt, --hero-overlay,
   --btn-style hooks, heading transforms. Keep skins small. */

*{margin:0;padding:0;box-sizing:border-box}
html{scroll-behavior:smooth;overflow-x:clip}
@media (prefers-reduced-motion:reduce){html{scroll-behavior:auto}}
body{overflow-x:clip;font-family:var(--body);background:var(--paper,#fff);
  color:var(--ink,#1c1c1c);line-height:1.65;-webkit-font-smoothing:antialiased}
img,video{max-width:100%;display:block}
a{color:inherit}
.wrap{max-width:1140px;margin:0 auto;padding:0 22px}
h1,h2,h3{font-family:var(--display);font-weight:800;line-height:1.08;letter-spacing:-.015em}
h1{font-size:clamp(2.2rem,5.2vw,3.6rem)}
h2{font-size:clamp(1.7rem,3.6vw,2.5rem);margin:.5rem 0 1rem}
.eyebrow{display:inline-block;font-weight:700;font-size:.8rem;letter-spacing:.14em;
  text-transform:uppercase;color:var(--primary)}
.sub{font-size:1.05rem;max-width:58ch;color:var(--muted,#4b4b4b)}
section{padding:4.4rem 0}
.section-alt{background:var(--section-bg-alt,#f6f6f4)}

/* a11y */
.skip{position:absolute;left:-9999px;top:0;background:var(--accent);color:var(--dark);
  padding:.6rem 1rem;font-weight:600;z-index:200}
.skip:focus{left:0}
:focus-visible{outline:3px solid var(--primary);outline-offset:3px}

/* buttons */
.btn{display:inline-flex;align-items:center;gap:.5rem;font-weight:600;font-size:.95rem;
  text-decoration:none;padding:.75rem 1.35rem;border-radius:var(--radius,10px);cursor:pointer;
  border:2px solid var(--dark);background:#fff;color:var(--dark);
  box-shadow:var(--shadow,0 2px 8px rgba(0,0,0,.12));transition:transform .12s ease}
.btn:hover{transform:translateY(-2px)}
.btn-accent{background:var(--accent);border-color:var(--accent-border,var(--dark));color:var(--accent-text,var(--dark))}
.btn-primary{background:var(--primary);border-color:var(--primary);color:#fff}
.btn-big{font-size:1.05rem;padding:.95rem 1.5rem;justify-content:center}

/* header */
.site-header{position:fixed;inset:0 0 auto 0;z-index:100;background:var(--paper,#fff);
  border-bottom:var(--header-line,1px solid #e4e4e0);display:flex;align-items:center;
  justify-content:space-between;padding:12px 22px;gap:16px}
.brand img{height:48px;width:auto}
.main-nav{display:flex;align-items:center;gap:22px}
.main-nav a{text-decoration:none;font-size:.93rem;font-weight:500}
.main-nav a:hover,.main-nav a[aria-current]{color:var(--primary)}
.hdr-cta{display:flex;align-items:center;gap:14px}
.tel-mini{font-weight:600;font-size:.9rem;text-decoration:none;white-space:nowrap}
.menu-btn{display:none;background:#fff;border:2px solid var(--dark);border-radius:8px;
  padding:.5rem .8rem;font-family:var(--display);font-weight:800;cursor:pointer}
.mobile-nav{display:none;position:fixed;top:66px;left:0;right:0;z-index:99;background:var(--paper,#fff);
  border-bottom:1px solid #e4e4e0;padding:1rem 22px 1.3rem;max-height:calc(100vh - 66px);overflow:auto}
.mobile-nav.open{display:block}
.mobile-nav a{display:block;padding:.7rem 0;font-weight:600;text-decoration:none;border-bottom:1px solid #eee}
/* 860, not 960: with a dropdown nav the top level is only ~4 items (~350px),
   so the desktop bar fits comfortably down to here. At 960 a Windows laptop at
   125-150% display scaling reports under the breakpoint and silently gets the
   MOBILE menu — which reads as "the desktop dropdown is broken". */
@media (max-width:860px){.main-nav{display:none}.tel-mini{display:none}
  .hdr-cta .btn{display:none}.menu-btn{display:inline-flex}.brand img{height:40px}}

/* ---------- dropdown nav (parents are inferred from the URL path) ----------
   Desktop opens on :hover AND :focus-within, so keyboard users get the same
   menu without any JS. Never hover-only — that strands keyboard and switch
   users on the parent page. */
.nav-item{position:relative;display:flex;align-items:center}
.nav-item > a{text-decoration:none;font-size:.93rem;font-weight:500;
  display:inline-flex;align-items:center;gap:.32rem;padding:.5rem 0}
.nav-item > a:hover,.nav-item > a[aria-current],.nav-item > a.is-ancestor{color:var(--primary)}
.nav-caret{background:none;border:0;cursor:pointer;padding:.5rem .1rem .5rem .3rem;
  display:inline-flex;align-items:center;color:inherit;line-height:1}
.caret{width:0;height:0;border-left:4px solid transparent;border-right:4px solid transparent;
  border-top:5px solid currentColor;opacity:.55;transition:transform .15s ease}
.nav-item:hover .caret,.nav-item:focus-within .caret,.nav-item.open .caret{transform:rotate(180deg);opacity:1}
.sub-menu{position:absolute;top:100%;left:50%;transform:translate(-50%,6px);
  min-width:210px;background:var(--paper,#fff);border:1px solid #e4e4e0;
  border-radius:var(--radius,10px);box-shadow:0 12px 30px rgba(0,0,0,.14);
  padding:.5rem;opacity:0;visibility:hidden;pointer-events:none;
  transition:opacity .15s ease,transform .15s ease;z-index:120}
.sub-menu.cols2{min-width:400px;columns:2;column-gap:.4rem}
.nav-item:hover .sub-menu,.nav-item:focus-within .sub-menu,.nav-item.open .sub-menu{
  opacity:1;visibility:visible;pointer-events:auto;transform:translate(-50%,0)}
.sub-menu a{display:block;padding:.5rem .7rem;font-size:.9rem;font-weight:500;
  text-decoration:none;border-radius:7px;break-inside:avoid;white-space:nowrap}
.sub-menu a:hover,.sub-menu a[aria-current]{background:var(--section-bg-alt,#f6f6f4);color:var(--primary)}
/* hover bridge — stops the menu closing in the gap between link and panel */
.nav-item.has-sub::after{content:"";position:absolute;top:100%;left:0;right:0;height:10px}

/* ---------- mobile nav: collapsed submenus ---------- */
.m-row{display:flex;align-items:center;justify-content:space-between;gap:.5rem;
  border-bottom:1px solid #eee}
.m-row a{flex:1;border-bottom:0 !important}
.m-toggle{flex:0 0 auto;background:none;border:0;padding:.7rem .4rem;cursor:pointer;
  font-family:var(--display);font-weight:800;font-size:1.25rem;line-height:1;color:var(--primary);
  min-width:44px;min-height:44px}
.m-sub{padding-left:.9rem;border-left:2px solid var(--accent);margin:.2rem 0 .5rem}
.m-sub[hidden]{display:none}
.m-sub a{font-weight:500;font-size:.94rem;padding:.55rem 0}

/* ---------- HERO (standard: photo + scroll motion, no video weight) ---------- */
.hero{position:relative;min-height:76vh;display:flex;align-items:center;
  padding:7.5rem 0 4rem;overflow:hidden;color:#fff}
.hero-media{position:absolute;inset:-12% 0;z-index:0}
.hero-media img{width:100%;height:100%;object-fit:cover}
.hero-shade{position:absolute;inset:0;z-index:1;background:var(--hero-overlay,
  linear-gradient(180deg,rgba(10,10,12,.62),rgba(10,10,12,.38) 50%,rgba(10,10,12,.66)))}
.hero .wrap{position:relative;z-index:2;width:100%}
.hero .eyebrow{color:var(--accent)}
.hero .sub{color:rgba(255,255,255,.92)}
.hero-grid{display:grid;grid-template-columns:1fr;gap:2.2rem;align-items:center}
.hero-grid.has-form{grid-template-columns:1.05fr .95fr}
@media (max-width:920px){.hero-grid.has-form{grid-template-columns:1fr}}
.hero .cta-row{display:flex;flex-wrap:wrap;gap:14px;margin-top:1.8rem}

/* scroll-driven hero pan/zoom — CSS-only where supported */
@supports (animation-timeline: scroll()) {
  @media (prefers-reduced-motion: no-preference) {
    .hero-media img{animation:heroPan linear both;animation-timeline:scroll();
      animation-range:0 120vh;transform-origin:center}
    @keyframes heroPan{from{transform:scale(1.12) translateY(0)}to{transform:scale(1) translateY(6%)}}
  }
}

/* ---------- scroll reveals (IO adds .in via site.js; CSS-only upgrade below) ---------- */
@media (prefers-reduced-motion: no-preference){
  .rv{opacity:0;transform:translateY(16px);transition:opacity .55s ease,transform .55s ease}
  .rv.in{opacity:1;transform:none}
}

/* ---------- content blocks ---------- */
.grid3{display:grid;grid-template-columns:repeat(3,1fr);gap:20px;margin-top:2.3rem}
@media (max-width:960px){.grid3{grid-template-columns:repeat(2,1fr)}}
@media (max-width:620px){.grid3{grid-template-columns:1fr}}
.tile{background:#fff;border:var(--tile-border,1px solid #e4e4e0);
  border-radius:var(--radius,12px);padding:1.6rem 1.5rem;box-shadow:var(--shadow,0 2px 10px rgba(0,0,0,.06))}
.tile h3{font-size:1.08rem;margin-bottom:.5rem}
.tile p{font-size:.94rem;color:var(--muted,#4b4b4b)}
.split{display:grid;grid-template-columns:1.1fr .9fr;gap:44px;align-items:center}
@media (max-width:860px){.split{grid-template-columns:1fr}}
/* Uncropped, and capped so the photo never dominates the row.
   WIDTH-driven with a ratio-derived cap: width:100% fills the column, max-width
   stops it before it would exceed the height cap (420px desktop, 320px phones),
   and height:auto lets the ratio set the height.

   Why not the old `height:420px; width:auto`: for a LANDSCAPE ratio the derived
   width (420 x 4/3 = 560px) is wider than the .9fr column (473px at a 1140px
   wrap), so max-width:100% clamped it to 473x420 — ratio 1.127, not 1.333 — and
   object-fit:cover then quietly cropped ~18% off the SIDES of every landscape
   photo. Measured on a real render, invisible in the stylesheet. Portrait hid
   the bug for a year because 420 x 3/4 = 315px always fitted the column.
   Width-driven fits both orientations with no crop at any viewport.

   Do NOT switch to width:auto + max-height — that leaves a lazy image at 0x0
   until it loads (measured), the exact layout shift the width/height attributes
   exist to prevent. width:100% + aspect-ratio reserves the box either way. */
.split img{width:100%;max-width:calc(420px * var(--photo-ratio,3/4));
  height:auto;aspect-ratio:var(--photo-ratio,3/4);
  object-fit:cover;display:block;margin:0 auto;
  border-radius:var(--radius,12px);box-shadow:var(--shadow,0 6px 24px rgba(0,0,0,.12))}
@media (max-width:860px){.split img{max-width:calc(320px * var(--photo-ratio,3/4))}}

/* ---------- before / after pairs (cleanouts, restoration, painting, detailing) ----------
   Markup: .ba-set > div > (.ba > figure.ba-before + figure.ba-after) + .ba-cap
   Pairs must be the SAME shot from the SAME position — that is the whole point.

   PHONE PHOTOS ARE PORTRAIT. Rendered at their native 3:4 they tower: two of
   them side by side in a 1140px wrap is 750px tall, and a stack of three pairs
   on a phone is an endless scroll nobody reaches the bottom of. So we CROP to
   landscape with object-fit rather than letting the source dictate height. */
/* DO NOT crop these to landscape. Client photos come off a phone in portrait
   (3:4); forcing them into a 4:3 box throws away ~44% of the frame, which is
   exactly the half of a room that shows how full it was. The good junk-removal
   galleries all use LANDSCAPE SOURCE photos shown uncropped — so we match the
   box to the source instead of the other way round, and control height by
   limiting how wide a PAIR gets rather than by cutting the picture.
   --photo-ratio matches the client's photos: 3/4 portrait (default) or 4/3 if
   they shoot landscape. Set it ONCE per site (it drives .split img too); never
   crop against it. */
.ba-set{display:grid;gap:2.6rem;margin-top:2.3rem;justify-items:center}
.ba{display:grid;grid-template-columns:1fr 1fr;gap:12px;width:100%;max-width:560px}
.ba figure{margin:0;position:relative}
.ba img{width:100%;height:auto;aspect-ratio:var(--photo-ratio,3/4);object-fit:cover;
  border-radius:var(--radius,12px);border:var(--tile-border,1px solid #e4e4e0)}
.ba figcaption{position:absolute;top:10px;left:10px;font-family:var(--display);font-weight:800;
  font-size:.7rem;letter-spacing:.12em;text-transform:uppercase;padding:.32rem .62rem;
  border-radius:6px;background:var(--dark);color:#fff}
.ba .ba-after figcaption{background:var(--accent);color:var(--accent-text,var(--dark))}
.ba-cap{margin-top:.7rem;font-size:.92rem;color:var(--muted,#4b4b4b)}
.ba-hint{display:none;font-size:.82rem;color:var(--muted,#4b4b4b);margin-top:.8rem}

/* Phone: swipe between PAIRS instead of scrolling past six tall photos.
   Within a pair, before STACKS ABOVE after rather than sitting beside it —
   two 140px thumbnails side by side on a 375px screen are too small to read,
   which defeats the point. Stacked, each photo gets the full card width and
   the comparison still works because they are adjacent. */
@media (max-width:760px){
  .ba-set{display:flex;gap:14px;overflow-x:auto;scroll-snap-type:x mandatory;
    -webkit-overflow-scrolling:touch;scrollbar-width:none;
    margin-left:-22px;margin-right:-22px;padding:0 22px 4px;scroll-padding-left:22px}
  .ba-set::-webkit-scrollbar{display:none}
  .ba-set > *{flex:0 0 86%;scroll-snap-align:start}
  /* Side by side on a phone puts each photo at ~160px, which is too small to
     read — the exact complaint that started this. Stacked, each gets the full
     card width and the pair still reads as a pair because they are adjacent
     and labelled. The carousel means only one card is on screen at a time. */
  .ba{grid-template-columns:1fr;gap:8px;max-width:none}
  .ba-hint{display:block}
}

/* ---------- plain fact list (services, FAQ answers) ---------- */
.ticks{list-style:none;margin-top:1rem;columns:2;column-gap:2rem}
.ticks li{font-size:.94rem;padding:.2rem 0 .2rem 1.4rem;position:relative;break-inside:avoid}
.ticks li::before{content:"";position:absolute;left:0;top:.62em;width:9px;height:9px;
  background:var(--accent);border-radius:2px}
@media (max-width:620px){.ticks{columns:1}}

/* ---------- FAQ ---------- */
.faq{margin-top:1.6rem;max-width:74ch}
.faq details{border-bottom:1px solid #dededa;padding:1rem 0}
.faq summary{font-family:var(--display);font-weight:800;font-size:1.02rem;cursor:pointer;
  list-style:none;display:flex;justify-content:space-between;gap:1rem;align-items:center}
.faq summary::-webkit-details-marker{display:none}
.faq summary::after{content:"+";color:var(--primary);font-size:1.3rem;line-height:1}
.faq details[open] summary::after{content:"–"}
.faq p{margin-top:.7rem;font-size:.95rem;color:var(--muted,#4b4b4b);max-width:68ch}

/* ---------- steps ---------- */
.steps{counter-reset:step;display:grid;grid-template-columns:repeat(4,1fr);gap:20px;margin-top:2.3rem}
@media (max-width:900px){.steps{grid-template-columns:repeat(2,1fr)}}
@media (max-width:520px){.steps{grid-template-columns:1fr}}
.steps li{list-style:none;counter-increment:step}
.steps li::before{content:counter(step);display:flex;align-items:center;justify-content:center;
  width:38px;height:38px;border-radius:50%;background:var(--accent);color:var(--accent-text,var(--dark));
  font-family:var(--display);font-weight:800;margin-bottom:.7rem}
.steps h3{font-size:1rem;margin-bottom:.35rem}
.steps p{font-size:.92rem;color:var(--muted,#4b4b4b)}

/* ---------- lead form panel ---------- */
.lead-panel{background:#fff;color:var(--ink,#1c1c1c);border-radius:var(--radius,14px);
  overflow:hidden;border:var(--tile-border,1px solid #e4e4e0);
  box-shadow:var(--shadow,0 10px 34px rgba(0,0,0,.18))}
.lead-head{padding:1rem 1.3rem;border-bottom:var(--tile-border,1px solid #e4e4e0);
  font-family:var(--display);font-weight:800;font-size:1.1rem}
.lead-form{padding:1.3rem;display:grid;gap:1rem}
.lead-form label{display:grid;gap:.35rem;font-weight:600;font-size:.86rem}
.lead-form input,.lead-form textarea{font-family:var(--body);font-size:.95rem;
  padding:.72rem .8rem;border:1.5px solid #c9c9c4;border-radius:8px;background:#fff}
.lead-form input:focus,.lead-form textarea:focus{outline:3px solid var(--primary);outline-offset:0}
.lead-form .fine{font-size:.8rem;color:var(--muted,#4b4b4b)}
.lead-form .fine a{font-weight:600}
.hp{position:absolute;left:-9999px;opacity:0;height:0;overflow:hidden}
@media (max-width:560px){
  .lead-form input,.lead-form textarea{font-size:16px;padding:.8rem .85rem} /* stops iOS zoom */
}

/* ---------- client portal ---------- */
.portal-stats{display:grid;grid-template-columns:repeat(4,1fr);gap:14px;margin-top:1.8rem}
@media (max-width:620px){.portal-stats{grid-template-columns:repeat(2,1fr)}}
.portal-stat{background:#fff;border:var(--tile-border,1px solid #e4e4e0);border-radius:var(--radius,12px);
  padding:1rem 1.1rem;text-align:center}
.portal-stat b{display:block;font-family:var(--display);font-weight:800;font-size:1.7rem;color:var(--primary)}
.portal-stat span{font-size:.8rem;color:var(--muted,#4b4b4b);text-transform:uppercase;letter-spacing:.04em}
.portal-toolbar{display:flex;align-items:center;gap:1rem;flex-wrap:wrap;margin:1.6rem 0}
.portal-toolbar input{flex:1 1 260px;max-width:420px;padding:.72rem .8rem;
  border:1.5px solid #c9c9c4;border-radius:8px;font-size:.95rem}
.portal-count{font-size:.85rem;color:var(--muted,#4b4b4b);white-space:nowrap}
.portal-ago{font-size:.78rem;color:var(--muted,#4b4b4b)}
.portal-badge-new{display:inline-block;background:var(--accent);color:var(--accent-text,var(--dark));
  font-size:.68rem;font-weight:800;text-transform:uppercase;letter-spacing:.04em;
  padding:.15rem .45rem;border-radius:5px;vertical-align:middle}
.portal-table{width:100%;border-collapse:collapse;font-size:.9rem;min-width:640px}
.portal-table th{text-align:left;font-family:var(--display);font-weight:800;font-size:.75rem;
  letter-spacing:.05em;text-transform:uppercase;padding:.6rem .7rem;border-bottom:2px solid #ddd;
  color:var(--muted,#4b4b4b)}
.portal-table td{padding:.65rem .7rem;border-bottom:1px solid #eee;vertical-align:top}
.portal-table tr:hover td{background:var(--section-bg-alt,#f6f6f4)}
.portal-table td a{text-decoration:none;font-weight:600}
@media (max-width:640px){
  /* stacked "label: value" cards instead of a horizontally-scrolled table —
     a lead list read on a phone in a truck should not need side-scrolling */
  .portal-table thead{display:none}
  .portal-table, .portal-table tbody, .portal-table tr, .portal-table td{display:block;width:100%}
  .portal-table tr{border:1px solid #e4e4e0;border-radius:10px;margin-bottom:.9rem;padding:.4rem .8rem}
  .portal-table td{border-bottom:0;padding:.35rem 0}
  .portal-table td::before{content:attr(data-label) ": ";font-weight:700;color:var(--muted,#4b4b4b)}
}

/* ---------- reviews ---------- */
.reviews-shell{margin-top:2rem}
.reviews-more{margin-top:1rem;font-size:.92rem}
.reviews-more a{font-weight:600;color:var(--primary)}

/* ---------- footer ---------- */
/* Kept deliberately compact: the footer is the least-read part of the page and
   every row of it pushes the real content further from the viewer. Hours are
   collapsed into day RANGES in footer.php rather than seven near-identical
   rows, which is the single biggest saving. */
.site-footer{background:var(--dark);color:#e8e8e6;padding:2.3rem 0 1rem;margin-top:2rem}
/* minmax(0,1fr), not 1fr: a bare 1fr is minmax(auto,1fr), so a column holding a
   long unbreakable town name grows past its share and skews the whole row. */
.foot-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(170px,1fr));
  gap:1.5rem 2rem;align-items:start}
.foot-areas{list-style:none;font-size:.86rem;columns:2;column-gap:1rem}
.foot-areas li{padding:.1rem 0;break-inside:avoid}
.foot-areas a{text-decoration:none}
.foot-areas a:hover{color:var(--accent)}
.foot-areas-all{font-weight:600;color:var(--accent);white-space:nowrap}
/* Stay two-up on phones — a single stacked column turns four short blocks into
   an 800px wall of footer between the last CTA and the bottom of the page.
   These overrides MUST come after the base .foot-areas rules above, or the
   base columns:2 wins on equal specificity and the phone layout skews. */
@media (max-width:760px){
  .foot-grid{grid-template-columns:repeat(2,minmax(0,1fr));gap:1.3rem 1.2rem}
  .foot-hours li{max-width:none}
  /* Areas stays a normal grid cell, single sub-column. Spanning it full width
     to keep two sub-columns was tried and MEASURED WORSE (695px vs 567px):
     the span gives it a row of its own instead of letting it sit beside
     another block. Do not "fix" this back. */
  .foot-areas{columns:1}
}
@media (max-width:340px){.foot-grid{grid-template-columns:minmax(0,1fr)}}
.foot-logo{height:32px;width:auto;margin-bottom:.6rem}
.foot-nap,.foot-area{font-size:.86rem;line-height:1.5}
.foot-area{margin-top:.35rem;color:rgba(232,232,230,.75)}
.foot-nap a{text-decoration:none;font-weight:600}
.foot-head{font-family:var(--display);display:block;margin-bottom:.45rem;font-size:.95rem}
.foot-hours{list-style:none;font-size:.86rem}
.foot-hours li{display:flex;justify-content:space-between;gap:.8rem;padding:.1rem 0;max-width:230px}
.foot-links{list-style:none;font-size:.86rem}
.foot-links li{padding:.1rem 0}
.foot-links a{text-decoration:none}
.foot-links a:hover{color:var(--accent)}
.foot-legal{margin-top:1.4rem;padding-top:.85rem;border-top:1px solid rgba(255,255,255,.15);
  font-size:.78rem;color:rgba(232,232,230,.7)}
.foot-legal a{color:inherit}
