/* fonts.css is loaded as a sibling <link> in the head, not @import-ed here.
   An @import cannot be discovered until THIS file has downloaded and
   parsed, so the @font-face declarations arrive a full hop late and the
   preloaded woff2 sits unused until they do. Measured on latent, the same
   pattern delayed the font request from 86ms (parallel) to 158ms (chained). */

/* ==========================================================================
   North East Florida Junk Removal & Demolition
   Palette and type derived from the client's own printed flyer:
   gold #FFB722 on true black, heavy condensed display, wide tracking.
   Signature device: the "bite", a stepped notch taken from the excavator
   bucket in his logo mark. It recurs as panel edges and band dividers.
   ========================================================================== */

:root{
  --black:#000000;
  --ink:#0C0C0D;
  --ink-2:#17171A;
  --ink-3:#232327;
  --paper:#F7F5F2;
  --tint:#EBE7E1;
  --gold:#FFB722;
  --gold-hi:#FFC94D;
  --gold-lo:#8F5B00;      /* amber for TEXT on light: 5.27 on paper, 4.65 on tint.
                             #E09A05 was 2.19 and failed the 4.5 floor outright */
  --gold-star:#BE8000;    /* stars on a white card: 3.35, clears the 3.0 graphic floor */
  --body:#26262A;
  --muted:#56565E;
  --line:#D9D4CC;
  --line-dk:#33333A;

  --ff-d:"Big Shoulders Display","Big Shoulders Display Fallback","Archivo","Archivo Fallback",system-ui,sans-serif;
  --ff-b:"Archivo","Archivo Fallback",system-ui,-apple-system,"Segoe UI",sans-serif;

  --gut:clamp(20px,5vw,64px);
  --wrap:1280px;
  --r:14px;
  --r-s:8px;

  --util-h:34px;
  --nav-h:64px;
  --hdr-h:98px;          /* republished by JS on transitionend */
  --bar-h:0px;           /* mobile action bar, set by JS */

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

*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%;scroll-behavior:smooth}
html{scrollbar-gutter:stable}  /* reserve the scrollbar gutter always, or the
   viewport widens while the preloader locks scrolling and every line re-wraps
   the instant the curtain lifts. Measured: 15px of shift. */

html{scroll-padding-top:calc(var(--hdr-h) + 16px)}

/* clip, never hidden: overflow-x:hidden on body makes body a scroll container
   and breaks position:sticky on iOS Safari. */
body{
  margin:0;
  overflow-x:clip;
  overflow-y:visible;
  background:var(--paper);
  color:var(--body);
  font:400 17px/1.62 var(--ff-b);
  -webkit-font-smoothing:antialiased;
  text-rendering:optimizeLegibility;
}

img,svg,video{max-width:100%}
img{height:auto;display:block}
picture{display:contents}

a{color:inherit}
button{font:inherit}

::selection{background:var(--gold);color:#000}

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

.wrap{width:min(var(--wrap),100% - var(--gut)*2);margin-inline:auto}
.wrap-n{width:min(1080px,100% - var(--gut)*2);margin-inline:auto}

.sr{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;
  clip:rect(0 0 0 0);white-space:nowrap;border:0}

.skip{position:absolute;left:8px;top:-60px;z-index:200;background:var(--gold);color:#000;
  padding:12px 18px;border-radius:var(--r-s);font-weight:700;transition:top .18s var(--e)}
.skip:focus{top:8px}

/* ---------- type ---------------------------------------------------------- */

h1,h2,h3{margin:0;font-family:var(--ff-d);font-weight:800;line-height:.98;
  letter-spacing:.005em;color:var(--ink)}
h1{font-size:clamp(2.6rem,6vw,4.7rem);text-transform:uppercase}
h2{font-size:clamp(2.1rem,4.6vw,3.5rem);text-transform:uppercase}
h3{font-size:clamp(1.45rem,2.4vw,1.95rem);text-transform:uppercase}
h4{margin:0;font-family:var(--ff-b);font-weight:700;font-size:1.06rem;line-height:1.34;
  letter-spacing:0;text-transform:none;color:var(--ink)}
p{margin:0 0 1.05em}
.lede{font-size:clamp(1.08rem,1.6vw,1.28rem);line-height:1.6;color:var(--muted);max-width:62ch}
/* A .lede is a section SUBTITLE when it stands alone and a LEAD PARAGRAPH when
   prose follows it, and those want opposite colours. Standing alone under a
   heading, muted is right. Leading a prose block it must not be fainter than the
   body beneath it: on the about page the intro measured 20.48px #56565E sitting
   directly above body at 17px #26262A, so the most important sentence in the
   block was also the palest thing in it. Adam spotted it as "the font or font
   sizes are diff". Keep the size step, drop the colour inversion. */
.lede:has(+ p){color:var(--body)}
.dark .lede:has(+ p),.blackband .lede:has(+ p),.statband .lede:has(+ p){color:#CFCFD6}
.dark .lede,.phero .lede,.hero .lede{color:#CFCFD6}

.eyebrow{display:inline-flex;align-items:center;gap:.6rem;font-family:var(--ff-b);
  font-weight:700;font-size:.8rem;letter-spacing:.16em;text-transform:uppercase;
  color:var(--gold-lo);margin:0 0 1rem}
.dark .eyebrow,.phero .eyebrow,.hero .eyebrow{color:var(--gold)}
.eyebrow::before{content:"";width:26px;height:3px;background:currentColor;flex:none}

.kicker{font-family:var(--ff-b);font-weight:700;font-size:.82rem;letter-spacing:.13em;
  text-transform:uppercase;color:var(--muted)}
.dark .kicker{color:#9A9AA4}

.gold{color:var(--gold)}
.measure{max-width:66ch}

/* ---------- bands --------------------------------------------------------- */

section{position:relative}
.band{padding-block:clamp(58px,8vw,112px)}
.band-tall{padding-block:clamp(78px,11vw,152px)}
.band-tight{padding-block:clamp(42px,5.5vw,72px)}
.tintband{background:var(--tint)}
.dark{background:var(--ink);color:#E4E4EA}
.dark h2,.dark h3{color:#fff}
.blackband{background:var(--black);color:#E4E4EA}
.blackband h2,.blackband h3{color:#fff}
.goldband{background:var(--gold);color:#000}
.goldband .marquee{padding-block:2px}
.goldband .mq-item{font-size:clamp(1.15rem,1.9vw,1.55rem);line-height:1.5;padding:0 1.6rem}
.goldband .mq-item{color:#000}
.goldband .mq-item .dot{background:#000}

/* dividers: real amplitude, one per seam, fill matches the NEXT band */
.dv{position:absolute;left:0;right:0;line-height:0;pointer-events:none;z-index:3}
.dv-b{bottom:-1px}
.dv-t{top:-1px}
.dv-t svg{transform:scaleY(-1)}
.dv svg{width:100%;height:clamp(44px,6vw,86px);display:block}

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

.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:.55rem;
  min-height:52px;padding:.9rem 1.6rem;border-radius:var(--r-s);
  font-family:var(--ff-b);font-weight:700;font-size:1rem;letter-spacing:.01em;
  text-decoration:none;cursor:pointer;border:2px solid transparent;
  background:var(--gold);color:#000;
  appearance:none;-webkit-appearance:none;
  transition:transform .14s var(--e),background-color .18s var(--e),color .18s var(--e),border-color .18s var(--e);
  touch-action:manipulation;position:relative;
}
.btn:hover{background:var(--gold-hi)}
.btn:active{transform:translateY(1px)}
.btn svg{width:20px;height:20px;flex:none}

.btn-out{background:transparent;color:var(--ghost,var(--ink));border-color:currentColor}
.btn-out:hover{background:var(--ghost,var(--ink));color:var(--ghost-ink,var(--paper))}
.hero,.dark,.blackband,.phero,.statband,.ctaband{--ghost:#fff;--ghost-ink:#000}

.btn-ghost-gold{background:transparent;color:var(--gold);border-color:var(--gold)}
.btn-ghost-gold:hover{background:var(--gold);color:#000}

.btn-lg{min-height:58px;padding:1.05rem 2rem;font-size:1.06rem}
.btns{display:flex;flex-wrap:wrap;gap:.9rem;margin-top:1.7rem}

/* rotation-only spinner: functional feedback, not decorative motion */
.btn[data-pending="true"]{pointer-events:none;opacity:.82}
.btn[data-pending="true"]::after{
  content:"";width:17px;height:17px;border:2.5px solid currentColor;border-top-color:transparent;
  border-radius:50%;animation:spin .62s linear infinite}
@keyframes spin{to{transform:rotate(360deg)}}

/* ---------- header -------------------------------------------------------- */

.hdr{position:fixed;inset:0 0 auto;z-index:90;
  transition:background-color .3s var(--e),box-shadow .3s var(--e)}
.hdr::before{content:"";position:absolute;inset:0;z-index:-1;
  background:linear-gradient(180deg,rgba(0,0,0,.72),rgba(0,0,0,0));
  opacity:1;transition:opacity .3s var(--e)}
.hdr[data-solid="true"]{background:var(--black);box-shadow:0 8px 30px rgba(0,0,0,.28)}
.hdr[data-solid="true"]::before{opacity:0}

.util{display:grid;grid-template-rows:1fr;align-items:stretch;
  overflow:hidden;min-height:0;
  border-bottom:1px solid rgba(255,255,255,.14);
  transition:grid-template-rows .3s var(--e),opacity .22s var(--e)}
.hdr[data-solid="true"] .util{grid-template-rows:0fr;opacity:0;border-bottom-color:transparent}
.util-in{min-height:0;overflow:hidden;display:flex;align-items:center;justify-content:space-between;
  gap:1rem;height:var(--util-h);font-size:.8rem;letter-spacing:.06em;color:#C9C9D2}
.util-in a{text-decoration:none}
.util-l,.util-r{display:flex;align-items:center;gap:1.3rem;min-width:0}
.util-r a{display:inline-flex;align-items:center;gap:.42rem;color:#fff;font-weight:600}
.util-r svg{width:15px;height:15px}
.util .star{color:var(--gold);font-weight:700}

.nav{display:flex;align-items:center;justify-content:space-between;gap:1rem;
  height:var(--nav-h);transition:height .3s var(--e)}
.hdr[data-solid="true"] .nav{height:72px}

.brand{display:flex;align-items:center;gap:.72rem;text-decoration:none;flex:none;min-height:44px}
.brand .mark{width:auto;height:42px;flex:none;display:block}
.brand-t{display:flex;flex-direction:column;line-height:1}
.brand-t b{font-family:var(--ff-d);font-weight:800;font-size:1.12rem;letter-spacing:.03em;
  color:#fff;text-transform:uppercase}
.brand-t span{font-size:.82rem;letter-spacing:.11em;color:var(--gold);text-transform:uppercase;
  font-weight:700;margin-top:3px}

.menu{display:flex;align-items:center;gap:.3rem;list-style:none;margin:0;padding:0}
.menu > li{position:relative}
.menu > li > a{display:inline-flex;align-items:center;gap:.34rem;padding:.7rem .78rem;
  color:#fff;text-decoration:none;font-weight:600;font-size:.95rem;position:relative;
  text-shadow:0 1px 3px rgba(0,0,0,.45)}
.hdr[data-solid="true"] .menu > li > a{text-shadow:none}
.menu > li > a::after{content:"";position:absolute;left:.78rem;right:.78rem;bottom:.42rem;
  height:2px;background:var(--gold);transform:scaleX(0);transform-origin:left;
  transition:transform .24s var(--e)}
.menu > li > a:hover::after,.menu > li > a:focus-visible::after,
.menu > li[aria-current="page"] > a::after{transform:scaleX(1)}
.menu .caret{width:11px;height:11px;transition:transform .24s var(--e)}
.menu > li:hover .caret{transform:rotate(180deg)}

.sub{position:absolute;top:100%;left:0;min-width:262px;background:#fff;
  border-radius:var(--r-s);box-shadow:0 22px 54px rgba(0,0,0,.26);
  list-style:none;margin:0;padding:.5rem;
  opacity:0;visibility:hidden;transform:translateY(8px);
  transition:opacity .2s var(--e),transform .2s var(--e),visibility .2s}
.menu > li:hover .sub,.menu > li:focus-within .sub{opacity:1;visibility:visible;transform:none}
.sub a{display:block;padding:.62rem .8rem;border-radius:6px;text-decoration:none;
  color:var(--ink);font-weight:600;font-size:.93rem;transition:background-color .16s var(--e)}
.sub a:hover{background:var(--tint)}
.sub small{display:block;font-weight:400;color:var(--muted);font-size:.78rem;margin-top:2px}

.nav-r{display:flex;align-items:center;gap:.7rem;flex:none}
.phpill{display:inline-flex;align-items:center;gap:.45rem;padding:.62rem 1rem;
  border:2px solid rgba(255,255,255,.5);border-radius:var(--r-s);color:#fff;
  text-decoration:none;font-weight:700;font-size:.95rem;
  transition:border-color .18s var(--e),background-color .18s var(--e)}
.phpill:hover{border-color:var(--gold);background:rgba(255,183,34,.14)}
.phpill svg{width:17px;height:17px}

.burger{display:none;width:46px;height:46px;border:0;background:transparent;
  border-radius:8px;cursor:pointer;position:relative;z-index:95;flex:none;
  touch-action:manipulation}
.burger span{position:absolute;left:11px;right:11px;height:2.5px;background:#fff;border-radius:2px;
  transition:transform .26s var(--e),opacity .18s var(--e),background-color .2s var(--e)}
.burger span:nth-child(1){top:15px}
.burger span:nth-child(2){top:22px}
.burger span:nth-child(3){top:29px}
body[data-menu="open"] .burger span{background:#fff}
body[data-menu="open"] .burger span:nth-child(1){transform:translateY(7px) rotate(45deg)}
body[data-menu="open"] .burger span:nth-child(2){opacity:0}
body[data-menu="open"] .burger span:nth-child(3){transform:translateY(-7px) rotate(-45deg)}

/* scroll progress: its OWN element, never shared with the loading bar */
.prog{position:fixed;left:0;top:0;height:3px;width:100%;transform:scaleX(0);
  transform-origin:left;background:var(--gold);z-index:96;pointer-events:none}
.navload{position:fixed;left:0;top:0;height:3px;width:100%;transform:scaleX(0);
  transform-origin:left;background:var(--gold-hi);z-index:97;pointer-events:none;opacity:0}
.navload[data-on="true"]{opacity:1;animation:loadbar 1.1s var(--e) forwards}
@keyframes loadbar{0%{transform:scaleX(0)}64%{transform:scaleX(.72)}100%{transform:scaleX(.94)}}

/* ---------- mobile menu --------------------------------------------------- */

.mnav{position:fixed;left:0;right:0;top:var(--hdr-h);bottom:0;z-index:88;
  background:var(--black);padding:14px var(--gut) calc(28px + var(--bar-h) + env(safe-area-inset-bottom));
  overflow-y:auto;overscroll-behavior:contain;
  opacity:0;visibility:hidden;transform:translateY(-10px);
  transition:opacity .24s var(--e),transform .24s var(--e),visibility .24s}
body[data-menu="open"] .mnav{opacity:1;visibility:visible;transform:none}
.mnav ul{list-style:none;margin:0;padding:0}
.mnav > ul > li{border-bottom:1px solid var(--line-dk);
  display:grid;grid-template-rows:auto 0fr;align-items:stretch;
  transition:grid-template-rows .28s var(--e)}
.mnav > ul > li.open{grid-template-rows:auto 1fr}
.mnav .row{display:flex;align-items:center;justify-content:space-between;gap:.5rem}
.mnav .row > a{flex:1;display:block;padding:16px 0;color:#fff;text-decoration:none;
  font-family:var(--ff-d);font-weight:800;font-size:1.4rem;text-transform:uppercase;letter-spacing:.02em}
.mnav .tog{width:46px;height:46px;border:0;background:transparent;color:var(--gold);
  cursor:pointer;display:grid;place-items:center;border-radius:8px;touch-action:manipulation}
.mnav .tog svg{width:16px;height:16px;transition:transform .26s var(--e)}
.mnav li.open .tog svg{transform:rotate(180deg)}
.mnav .msub{overflow:hidden;min-height:0}
.mnav .msub a{display:block;padding:11px 0 11px 16px;color:#C9C9D2;text-decoration:none;
  font-size:1rem;border-left:2px solid var(--line-dk)}
.mnav .msub li:last-child a{padding-bottom:18px}
.mnav .mcta{margin-top:22px;display:grid;gap:.7rem}

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

/* no isolation here: it creates a stacking context the seal cannot escape,
   so the seal was clipped by the band below instead of straddling it */
.hero{position:relative;background:var(--black);color:#fff}
.hero-grid{display:grid;grid-template-columns:minmax(0,1.02fr) minmax(0,1fr);align-items:stretch;
  min-height:min(96svh,860px)}
.hero-copy{display:flex;flex-direction:column;justify-content:center;
  padding:calc(var(--hdr-h) + clamp(30px,5vw,60px)) clamp(24px,4vw,60px) clamp(46px,6vw,76px) var(--gut);
  position:relative;z-index:2}
.hero-media{position:relative;overflow:hidden;background:#0A0A0B}
.hero-media img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
  will-change:transform}
/* the bite: a stepped notch echoing the excavator bucket, on a backdrop layer
   only, never on the container that holds the buttons (clip-path clips hit regions) */
.hero-bite{position:absolute;top:0;bottom:0;left:-2px;width:clamp(46px,5vw,84px);z-index:2;
  background:var(--black);
  clip-path:polygon(0 0,100% 0,100% 12%,38% 12%,38% 30%,100% 30%,100% 46%,38% 46%,38% 64%,100% 64%,100% 80%,38% 80%,38% 100%,0 100%)}
.hero h1{color:#fff}
.hero h1 em{font-style:normal;color:var(--gold);display:block;font-size:.58em;
  line-height:1.02;margin-top:.34em;letter-spacing:.01em}
.hero .lede{margin-top:1.25rem}
.hero-proof{display:flex;flex-wrap:wrap;gap:1.5rem 2.2rem;margin-top:2.1rem;
  padding-top:1.6rem;border-top:1px solid rgba(255,255,255,.16)}
.hero-proof a{text-decoration:none;display:flex;flex-direction:column;gap:.18rem;
  transition:transform .16s var(--e)}
.hero-proof a:hover{transform:translateY(-2px)}
.hero-proof b{font-family:var(--ff-d);font-weight:800;font-size:1.7rem;color:var(--gold);line-height:1}
.hero-proof span{font-size:.79rem;letter-spacing:.11em;text-transform:uppercase;color:#A9A9B4;font-weight:600}

/* the seal: a circular medallion straddling the hero's bottom edge, which is
   the hero's one deliberate overlap */
/* Direct child of .hero, never of .hero-media: that has overflow:hidden for the
   parallax and silently clipped the bottom third of the seal. getBoundingClientRect
   ignores ancestor clipping, so the rect looked correct the whole time. */
.seal{position:absolute;right:clamp(16px,4vw,56px);bottom:clamp(12px,2.2vw,22px);
  z-index:20;width:clamp(96px,10vw,142px);pointer-events:none}
.seal svg{width:100%;height:auto;display:block}
.seal .st{fill:#FFB722;font-family:var(--ff-b);font-weight:700}
.seal .sc{fill:#000;font-family:var(--ff-d);font-weight:800;letter-spacing:.02em}

/* his own mark, oversized and dimmed, as a layer behind dark bands. Depth from
   the brand itself rather than from a decorative texture. */
.wm{position:absolute;inset:0;overflow:hidden;pointer-events:none;z-index:0}
.wm::before{content:"";position:absolute;right:-4%;top:50%;translate:0 -50%;
  width:min(520px,52vw);aspect-ratio:324/279;opacity:.055;
  background:url("/assets/img/mark-fl-512.png") center/contain no-repeat}
.wm-l::before{right:auto;left:-6%;opacity:.05}
.statband .wrap,.dark .wrap{position:relative;z-index:1}

/* inner-page photo header */
.phero{position:relative;background:var(--ink);color:#fff;isolation:isolate;overflow:hidden}
.phero-bg{position:absolute;inset:0;z-index:-2}
.phero-bg img{width:100%;height:100%;object-fit:cover}
.phero::before{content:"";position:absolute;inset:0;z-index:-1;
  background:linear-gradient(100deg,rgba(0,0,0,.90) 0%,rgba(0,0,0,.76) 42%,rgba(0,0,0,.44) 100%)}
.phero-in{padding:calc(var(--hdr-h) + clamp(38px,6vw,68px)) 0 clamp(56px,8vw,96px)}
.phero h1{color:#fff;font-size:clamp(2.4rem,5.6vw,4.2rem)}
.phero .lede{margin-top:1.1rem}

.crumbs{display:flex;flex-wrap:wrap;align-items:center;gap:.42rem;margin:0 0 1.15rem;padding:0;
  list-style:none;font-size:.84rem;color:#B4B4BE}
.crumbs a{text-decoration:none;color:#B4B4BE;border-bottom:1px solid transparent}
.crumbs a:hover{color:#fff;border-bottom-color:var(--gold)}
.crumbs li::after{content:"/";margin-left:.42rem;color:#5E5E68}
.crumbs li:last-child::after{content:""}
.crumbs [aria-current]{color:#fff}

/* ---------- grids, cards, masks ------------------------------------------- */

.g2{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:clamp(18px,2.4vw,32px)}
.g3{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:clamp(18px,2.4vw,30px)}
.g4{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:clamp(16px,2vw,26px)}

.split{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);
  gap:clamp(28px,5vw,72px);align-items:center}
.split.flip .split-media{order:2}

.head{max-width:62ch;margin-bottom:clamp(30px,4vw,52px)}
.head.center{margin-inline:auto;text-align:center}

/* photo card: a grid cell always carries an image, never bare text */
.pcard{position:relative;display:block;border-radius:var(--r);overflow:hidden;
  text-decoration:none;color:#fff;background:var(--ink-2);isolation:isolate;
  transition:transform .3s var(--e)}
.pcard:hover{transform:translateY(-5px)}
.pcard img{width:100%;height:100%;object-fit:cover;position:absolute;inset:0;z-index:-2;
  transition:transform .5s var(--e)}
.pcard:hover img{transform:scale(1.05)}
.pcard::before{content:"";position:absolute;inset:0;z-index:-1;
  background:linear-gradient(180deg,rgba(0,0,0,.16) 0%,rgba(0,0,0,.52) 52%,rgba(0,0,0,.88) 100%)}
.pcard-in{position:relative;display:flex;flex-direction:column;justify-content:flex-end;
  min-height:300px;padding:clamp(20px,2.4vw,28px)}
.pcard h3{color:#fff;margin-bottom:.45rem}
.pcard p{color:#C7C7D0;font-size:.94rem;margin:0}
.pcard .go{display:inline-grid;place-items:center;width:40px;height:40px;border-radius:50%;
  border:2px solid rgba(255,255,255,.55);margin-top:1.1rem;
  transition:background-color .2s var(--e),border-color .2s var(--e),color .2s var(--e)}
.pcard:hover .go{background:var(--gold);border-color:var(--gold);color:#000}
.pcard .go svg{width:17px;height:17px}

.card{background:#fff;border:1px solid var(--line);border-radius:var(--r);
  padding:clamp(20px,2.4vw,28px)}
.dark .card,.blackband .card{background:var(--ink-2);border-color:var(--line-dk)}

/* mask silhouettes, rotate them, never the same rectangle twice */
.m{overflow:hidden;position:relative;background:var(--tint)}
.m img{width:100%;height:100%;object-fit:cover}
.m-arch{border-radius:50% 50% 12px 12px / 40% 40% 12px 12px;aspect-ratio:4/5}
.m-circle{border-radius:50%;aspect-ratio:1}
.m-blob{border-radius:58% 42% 46% 54% / 44% 52% 48% 56%;aspect-ratio:5/4}
.m-bite{aspect-ratio:4/3;border-radius:var(--r);
  clip-path:polygon(0 0,100% 0,100% 62%,86% 62%,86% 74%,72% 74%,72% 86%,58% 86%,58% 100%,0 100%)}
.m-tall{aspect-ratio:3/4;border-radius:var(--r)}
.m-wide{aspect-ratio:16/10;border-radius:var(--r)}

/* one deliberate overlap per section */
.media-stack{position:relative}
.float-card{position:absolute;left:-34px;bottom:-24px;z-index:3;max-width:262px;
  background:var(--black);color:#fff;border-radius:var(--r);padding:18px 20px;
  box-shadow:0 20px 48px rgba(0,0,0,.30);border-left:4px solid var(--gold)}
.float-card b{display:block;font-family:var(--ff-d);font-weight:800;font-size:2rem;
  color:var(--gold);line-height:1}
.float-card span{font-size:.83rem;color:#B9B9C4;line-height:1.4;display:block;margin-top:.3rem}

/* ---------- ticks / lists ------------------------------------------------- */
/* marker is decoration, never a grid column: a grid li makes the text after a
   <b> a third anonymous item that wraps into the marker column. */
.ticks{list-style:none;margin:0;padding:0;display:grid;gap:.78rem}
.ticks li{position:relative;padding-left:2.1rem;line-height:1.55}
.ticks li::before{content:"";position:absolute;left:0;top:.36em;width:20px;height:20px;
  border-radius:50%;background:var(--gold);
  -webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23000' d='M9.6 16.8 4.8 12l1.7-1.7 3.1 3.1 8-8L19.3 7z'/%3E%3C/svg%3E") center/contain no-repeat;
  mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23000' d='M9.6 16.8 4.8 12l1.7-1.7 3.1 3.1 8-8L19.3 7z'/%3E%3C/svg%3E") center/contain no-repeat}
.ticks.on-dark li::before{background:var(--gold)}

.numlist{list-style:none;margin:0;padding:0;counter-reset:n;display:grid;gap:1.6rem}
.numlist li{position:relative;padding-left:4.6rem;counter-increment:n}
.numlist li::before{content:counter(n,decimal-leading-zero);position:absolute;left:0;top:-.16em;
  font-family:var(--ff-d);font-weight:800;font-size:2.7rem;line-height:1;color:var(--gold);
  width:3.4rem;text-align:left}
.numlist h4{margin-bottom:.3rem}
.numlist p{margin:0;color:var(--muted);font-size:.97rem}
.dark .numlist p{color:#A9A9B4}

/* ---------- stats --------------------------------------------------------- */

.statband{background:var(--black);color:#fff}
/* .statband sets its own background, so it must set heading colour too:
   headings default to var(--ink) and rendered near-black on black. */
.statband h2,.statband h3,.statband h4{color:#fff}
.statband .lede{color:#CFCFD6}
.statband .eyebrow{color:var(--gold)}
.statband .kicker{color:#9A9AA4}   /* --muted on black is 2.89, fails the floor */
.goldband h2,.goldband h3{color:#000}

.stats{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:clamp(18px,2.4vw,28px)}
.stat{border-left:3px solid var(--gold);padding:.3rem 0 .3rem 1.15rem}
.stat b{display:block;font-family:var(--ff-d);font-weight:800;
  font-size:clamp(2.6rem,5vw,4rem);line-height:.94;color:#fff}
.stat b .suf{color:var(--gold)}
/* child combinator, not descendant: `.stat span` also matched the spans INSIDE
   <b>, so every count-up rendered at 13px block instead of 64px */
.stat > span{display:block;margin-top:.5rem;font-size:.82rem;letter-spacing:.12em;
  text-transform:uppercase;color:#A2A2AD;font-weight:600}
.stat b > span{display:inline;font:inherit;color:inherit;letter-spacing:inherit;
  text-transform:none;margin:0}
.stat b > span.suf{color:var(--gold)}
.stat > small{display:block;margin-top:.42rem;font-size:.86rem;color:#8B8B96;letter-spacing:0;
  text-transform:none;font-weight:400;line-height:1.45}

/* ---------- rail (carousel + marquee share one engine) -------------------- */

.railwrap{position:relative}
.rail{display:flex;gap:18px;overflow-x:auto;scroll-snap-type:none;
  scrollbar-width:none;-ms-overflow-style:none;padding:6px 0 16px;cursor:grab;
  touch-action:pan-x pan-y pinch-zoom;-webkit-overflow-scrolling:touch;
  overscroll-behavior-x:contain}
.rail::-webkit-scrollbar{display:none}
.rail.dragging{cursor:grabbing;scroll-behavior:auto}
.rail > *{flex:none}

.railbtns{display:flex;gap:.6rem;margin-top:.4rem}
.rbtn{width:48px;height:48px;border-radius:50%;border:2px solid var(--line);
  background:#fff;color:var(--ink);display:grid;place-items:center;cursor:pointer;
  transition:background-color .18s var(--e),border-color .18s var(--e),color .18s var(--e)}
.rbtn:hover{background:var(--gold);border-color:var(--gold);color:#000}
.rbtn svg{width:19px;height:19px}
.dark .rbtn,.blackband .rbtn{background:transparent;border-color:var(--line-dk);color:#fff}
.dark .rbtn:hover,.blackband .rbtn:hover{background:var(--gold);border-color:var(--gold);color:#000}

.rev{width:min(430px,84vw);background:#fff;border:1px solid var(--line);
  border-radius:var(--r);padding:26px;display:flex;flex-direction:column}
.dark .rev,.blackband .rev{background:var(--ink-2);border-color:var(--line-dk)}
.rev .strs{color:var(--gold-star);letter-spacing:.14em;font-size:1rem;margin-bottom:.85rem}
.dark .rev .strs,.blackband .rev .strs{color:var(--gold)}
.rev p{font-size:1rem;line-height:1.62;margin:0 0 1.15rem;flex:1}
.dark .rev p,.blackband .rev p{color:#D4D4DC}
.rev footer{display:flex;align-items:center;justify-content:space-between;gap:1rem;
  padding-top:.95rem;border-top:1px solid var(--line)}
.dark .rev footer,.blackband .rev footer{border-top-color:var(--line-dk)}
.rev cite{font-style:normal;font-weight:700;font-size:.95rem}
.rev .src{font-size:.82rem;color:var(--muted);text-decoration:none;display:inline-flex;
  align-items:center;gap:.3rem;border-bottom:1px solid transparent;white-space:nowrap;
  min-height:44px;padding-left:.6rem}
.rev .src:hover{color:var(--ink);border-bottom-color:var(--gold)}
.dark .rev .src,.blackband .rev .src{color:#9A9AA4}
.dark .rev .src:hover,.blackband .rev .src:hover{color:#fff}
.rev .src svg{width:13px;height:13px}

.marquee{display:flex;gap:0;overflow-x:auto;scrollbar-width:none;-ms-overflow-style:none;
  touch-action:pan-x pan-y pinch-zoom;cursor:grab;padding:0;overscroll-behavior-x:contain}
.marquee::-webkit-scrollbar{display:none}
.marquee.dragging{cursor:grabbing}
.mq-item{flex:none;display:inline-flex;align-items:center;gap:.85rem;
  padding:0 2.1rem;font-family:var(--ff-d);font-weight:800;
  font-size:clamp(1.5rem,2.6vw,2.1rem);text-transform:uppercase;letter-spacing:.03em;
  color:#fff;white-space:nowrap}
.mq-item .dot{width:9px;height:9px;border-radius:50%;background:var(--gold);flex:none}

/* ---------- gallery + lightbox ------------------------------------------- */

.gal{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:14px}
.gcell{position:relative;border:0;padding:0;background:var(--tint);border-radius:var(--r-s);
  overflow:hidden;aspect-ratio:4/3;cursor:pointer;display:block;width:100%}
.gcell img{width:100%;height:100%;object-fit:cover;transition:transform .45s var(--e)}
.gcell:hover img{transform:scale(1.06)}

.lb{position:fixed;inset:0;z-index:120;background:rgba(0,0,0,.94);
  display:none;place-items:center;padding:22px}
.lb[data-open="true"]{display:grid}
.lb img{max-width:100%;max-height:calc(100svh - 132px);object-fit:contain;border-radius:var(--r-s);
  transition:opacity .18s var(--e)}
.lb[data-loading="true"] img{opacity:.62}
.lb-cap{position:absolute;left:0;right:0;bottom:26px;text-align:center;color:#C9C9D2;font-size:.9rem}
.lb-x{position:absolute;top:16px;right:16px;width:50px;height:50px;border-radius:50%;
  border:2px solid rgba(255,255,255,.4);background:rgba(0,0,0,.55);color:#fff;
  display:grid;place-items:center;cursor:pointer;z-index:2}
.lb-x:hover{background:var(--gold);border-color:var(--gold);color:#000}
.lb-nav{position:absolute;top:50%;transform:translateY(-50%);width:52px;height:52px;
  border-radius:50%;border:2px solid rgba(255,255,255,.4);background:rgba(0,0,0,.55);
  color:#fff;display:grid;place-items:center;cursor:pointer;z-index:2}
.lb-nav:hover{background:var(--gold);border-color:var(--gold);color:#000}
.lb-prev{left:16px}
.lb-next{right:16px}

/* diagrams are authored at ~500-700px; letting them fill a 1080px column
   scales every label by 2x and the type stops matching the page */
.dia{max-width:min(740px,100%);margin-inline:auto}
.dia svg{width:100%;height:auto;display:block}
.dia + .dia-note{max-width:min(740px,100%);margin:1.1rem auto 0;font-size:.92rem;
  color:var(--muted);text-align:center}
.dark .dia-note{color:#9A9AA4}

/* A map embed must be OUT OF FLOW. iOS Safari resizes an iframe to the full
   height of its content and ignores width/height/CSS, which inflates
   scrollHeight and lets the page scroll past the footer. Desktop never shows it. */
.embed{position:relative;aspect-ratio:16/10;overflow:hidden;border-radius:var(--r);
  background:var(--ink-2);border:1px solid var(--line-dk)}
.embed iframe{position:absolute;inset:0;width:100%;height:100%;border:0}
.embed-cap{margin-top:.85rem;font-size:.86rem;color:#9A9AA4}

/* ---------- service-area map --------------------------------------------- */

/* Three items, two columns. The map and the town list are both PICKERS, so they
   share the left column; the panel is the ANSWER and gets the right one to
   itself. The panel used to carry the list as well, which made one column far
   taller than the other and left dead space under the map. */
/* Map and panel side by side, and the town list BELOW BOTH, spanning the full
   width. Ten buttons across five columns is two tidy rows, which is far shorter
   than a stacked list and removes the tall narrow column entirely. Earlier
   attempts put the list in the map's column, which made that column tall, which
   in turn stretched the panel and blew the photo up to fill it. */
/* 1.25:1 is solved, not chosen by eye. The map's height is (colW - 48) * 0.946
   from its viewBox, the panel's is colW * 0.625 for the photo plus about 314 of
   text. Setting those equal across a 1256px row gives 698 and 558. At any other
   ratio one box is stretched and carries visible slack, which is what made the
   map float inside an over-tall container. */
.maprow{max-width:920px;margin-inline:auto;
  display:grid;grid-template-columns:minmax(0,.92fr) minmax(0,1fr);
  grid-template-areas:"map panel" "towns towns";
  gap:clamp(16px,1.8vw,24px);align-items:stretch}
.maprow>.mapbox{grid-area:map}
.maprow>.mpanel{grid-area:panel}
.maprow>.mp-towns{grid-area:towns}
/* The three columns are stretched to a common height, so whichever box has the
   least content ends up with slack. Centre the content rather than letting it
   all pool at the bottom, which reads as a half-empty box. */
.mapbox{background:var(--ink-2);border:1px solid var(--line-dk);border-radius:var(--r);
  padding:clamp(14px,2vw,24px);display:grid;align-content:center}
/* Cap the map so the whole thing fits on a phone instead of running past the
   fold. The viewBox is 620x660, taller than it is wide, so at full width on a
   440px screen the southern towns sat below the visible area. */
/* NO max-height. An SVG keeps its aspect, so capping the height letterboxed it:
   the box stayed full width while the drawing shrank inside it, leaving big empty
   margins either side. That was the ugly version. Size the map by its COLUMN
   WIDTH instead, which is what the grid ratio below is for. */
.mapbox svg{width:100%;height:auto;display:block}
.mpin{cursor:pointer}
/* The hit disc is a <circle> too, so every rule written for "the pin circle"
   catches it. Selecting a town filled the r=38 invisible disc gold and painted a
   blob over the label and its neighbours. It stays transparent, always, and the
   :not() is what keeps the styling rules off it. */
.mpin-hit{pointer-events:all;fill:transparent!important;transition:none!important}
.mpin:focus-visible{outline:2px solid var(--gold);outline-offset:2px}
.mpin circle:not(.mpin-hit){transition:r .2s var(--e),fill .2s var(--e)}
.mpin:hover circle:not(.mpin-hit),
.mpin[data-on="true"] circle:not(.mpin-hit){fill:var(--gold)}
.mpin text{font-family:var(--ff-b);font-size:25px;font-weight:600;fill:#D6D6DE;
  paint-order:stroke;stroke:#17171A;stroke-width:4px;stroke-linejoin:round}
.mpin:hover text,.mpin[data-on="true"] text{fill:#fff}
.mpanel{background:var(--black);border:1px solid var(--line-dk);border-radius:var(--r);
  overflow:hidden;color:#fff;display:flex;flex-direction:column}
/* flex:1 lets the photo take up whatever height the left column has that the
   text does not need, so the two columns finish level without either one
   carrying empty space. min-height keeps it a photo rather than a sliver, and
   width:100% is the iOS aspect-ratio guard (see field-lessons #229). */
/* A banner strip, not a hero. Left to grow, the photo alone was 277px and the
   panel 634, which is what kept this section off the screen. object-fit:cover
   on the img handles the crop. */
.mpanel .mp-img{background:var(--ink-2);flex:0 0 auto;height:clamp(120px,13vw,165px);
  width:100%;justify-self:stretch}
.mpanel .mp-img img{width:100%;height:100%;object-fit:cover}
/* FIXED HEIGHT, SOLVED RATHER THAN TYPED. Every town's block is in the DOM and
   every one of them is placed in the SAME grid cell, so the cell is as tall as
   the tallest town at whatever width the browser happens to be. Selecting a
   town therefore cannot change the section's height at any viewport, and it
   stays true if the copy is edited later. A min-height per breakpoint would be
   three magic numbers, wrong at every width in between, stale on the first copy
   edit.
   visibility:hidden, NOT display:none: a hidden-by-visibility box still takes
   part in layout, which is the whole mechanism. It also keeps the nine inactive
   blocks out of the accessibility tree and out of the tab order, which
   display:none would do too but opacity:0 would not.
   The slack collects UNDER the last bullet because the content stays top
   aligned. Centring it would make the heading move per town, which is the
   jitter this rule exists to remove.

   SCOPED TO .maprow ON PURPOSE, and it is load bearing. build/fix-critical-css.py
   keeps a rule when any class in its selector is an above-the-fold "anchor", and
   it decides anchors from the first 4000 BYTES inside <main>. On this page that
   window is eaten by the map's 25KB of inline SVG path data, so `.maprow` and
   `.mapbox` land inside it and everything written after the SVG does not. Result:
   the container ships in the inlined critical block while its children do not,
   and for the one paint before the stylesheet arrives the ten blocks stack. That
   measured +1800px of document height. Naming .maprow in these selectors makes
   the children travel with the container, so the component is either wholly in
   critical or wholly out of it, never half. */
.maprow .mp-in{padding:clamp(13px,1.5vw,18px);display:grid}
.maprow .mp-slot{grid-area:1/1;visibility:hidden}
.maprow .mp-slot[data-on]{visibility:visible}
/* the town list. Same selection as the map, either one drives the other. */
/* Below the detail, not above it: the picture and the words are the answer,
   the list is how you ask a different question. So the separator is on TOP. */
/* Its own card now that it sits beside the panel rather than inside it. */
.mp-towns{display:grid;grid-template-columns:repeat(5,minmax(0,1fr));gap:6px;
  padding:clamp(11px,1.3vw,14px);background:var(--ink-2);
  border:1px solid var(--line-dk);border-radius:var(--r)}
/* This one band is sized to fit a screen, so it does not take the fleet-wide
   112px band padding or the standard heading gap. */
/* This one band is sized to fit a screen. Measured at 1440x1000 it was 1347px
   tall against 901px of usable height, so 446px over. The savings, in order of
   size: the three-column row above (-351), the h2 released from the 62ch measure
   so it sets on ONE line instead of two (-56), tighter band padding (-36) and a
   smaller heading gap (-8). The lede keeps its measure, because a 1280px line of
   body copy is unreadable. */
/* Asymmetric on purpose. The bottom divider is position:absolute at the section
   edge and clamp(44px,6vw,86px) tall, so bottom padding under 86px lets content
   run straight into it: the town list was sitting on the gold wave. Top has no
   divider to clear, so it stays tight. */
.band-fit{padding-block:clamp(10px,1.2vw,14px) clamp(70px,6.6vw,94px)}
.band-fit .head h2{font-size:clamp(1.9rem,3vw,2.6rem)}
/* Match the row: the block is capped at 920 and centred, so a full-width
   heading left it hanging out to the left with dead space beside it. */
.band-fit .head{margin-bottom:clamp(8px,1vw,14px);max-width:920px;margin-inline:auto}
.band-fit .head h2{max-width:none}
.band-fit .head .lede{max-width:62ch}
.mp-town{min-height:44px;padding:.55rem .7rem;text-align:left;cursor:pointer;
  font:600 .92rem/1.25 var(--ff-b);color:#C9C9D2;background:transparent;
  border:1px solid var(--line-dk);border-radius:8px;
  transition:background-color .16s var(--e),color .16s var(--e),border-color .16s var(--e)}
.mp-town:hover{color:#fff;border-color:#4A4A55}
.mp-town[aria-current="true"]{background:var(--gold);border-color:var(--gold);color:#000}
@media (max-width:1240px){.mp-towns{grid-template-columns:repeat(3,minmax(0,1fr))}}
@media (max-width:1040px){.mp-towns{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media (max-width:520px){.mp-towns{grid-template-columns:1fr}}
.mpanel h3{color:#fff;margin-bottom:.55rem}
.mpanel p{color:#B4B4BE;font-size:.95rem;margin:0 0 1rem}

/* ---------- forms --------------------------------------------------------- */

.formcard{background:#fff;border:1px solid var(--line);border-radius:var(--r);
  padding:clamp(22px,3vw,38px)}
.fgrid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:16px}
.field{display:flex;flex-direction:column;gap:.42rem}
.field.wide{grid-column:1/-1}
.field label{font-weight:700;font-size:.88rem;letter-spacing:.03em}
.field .hint{font-weight:400;color:var(--muted);font-size:.82rem}
.field input,.field textarea,.field select{
  font:400 16px/1.5 var(--ff-b);   /* 16px floor: below it iOS zooms and never returns */
  padding:.85rem .95rem;border:2px solid var(--line);border-radius:var(--r-s);
  background:#fff;color:var(--body);width:100%;
  transition:border-color .18s var(--e)}
.field input,.field select{min-height:52px}
.field textarea{min-height:132px;resize:vertical}
.field input:focus,.field textarea:focus,.field select:focus{border-color:var(--gold);outline:none}
.field input::placeholder,.field textarea::placeholder{color:#93939C}

.selwrap{position:relative}
.selwrap select{appearance:none;-webkit-appearance:none;padding-right:2.8rem;cursor:pointer}
.selwrap::after{content:"";position:absolute;right:1rem;top:50%;width:12px;height:8px;
  margin-top:-4px;pointer-events:none;background:var(--ink);
  -webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'%3E%3Cpath fill='%23000' d='M1.4 0 6 4.6 10.6 0 12 1.4 6 7.4 0 1.4z'/%3E%3C/svg%3E") center/contain no-repeat;
  mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'%3E%3Cpath fill='%23000' d='M1.4 0 6 4.6 10.6 0 12 1.4 6 7.4 0 1.4z'/%3E%3C/svg%3E") center/contain no-repeat}

/* The UA file button cannot be themed, so it is never shown. `.field .filein`
   and not `.filein`: `.field input{width:100%}` above is (0,1,1) and beat the
   bare class, and because nothing here is a positioned ancestor that 100%
   resolved against the VIEWPORT, giving a 1425px input starting at x=112 and
   97px of horizontal overflow on every desktop width. Phone hid it. */
.field .filein{position:absolute;width:1px;height:1px;opacity:0;pointer-events:none;
  clip:rect(0 0 0 0);clip-path:inset(50%);overflow:hidden}
.filelab{display:flex;align-items:center;gap:.7rem;padding:1rem;border:2px dashed var(--line);
  border-radius:var(--r-s);cursor:pointer;color:var(--muted);font-size:.94rem;min-height:52px;
  transition:border-color .18s var(--e),color .18s var(--e)}
.filelab:hover{border-color:var(--gold);color:var(--ink)}
.filelab svg{width:20px;height:20px;flex:none}
.field .filein:focus-visible + .filelab{outline:3px solid var(--gold);outline-offset:3px}
.filelab[data-has="true"]{border-style:solid;border-color:var(--gold);color:var(--ink);font-weight:600}

.formnote{font-size:.84rem;color:var(--muted);margin-top:1rem}

/* ---------- FAQ ----------------------------------------------------------- */

.faq{display:grid;gap:.7rem}
.faq details{background:#fff;border:1px solid var(--line);border-radius:var(--r-s);overflow:hidden}
.dark .faq details{background:var(--ink-2);border-color:var(--line-dk)}
.faq summary{list-style:none;cursor:pointer;padding:1.15rem 3.2rem 1.15rem 1.3rem;
  font-weight:700;font-size:1.03rem;position:relative;min-height:56px;display:flex;align-items:center}
.faq summary::-webkit-details-marker{display:none}
.faq summary::after{content:"";position:absolute;right:1.3rem;top:50%;width:13px;height:9px;
  margin-top:-4px;background:var(--gold);transition:transform .24s var(--e);
  -webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'%3E%3Cpath fill='%23000' d='M1.4 0 6 4.6 10.6 0 12 1.4 6 7.4 0 1.4z'/%3E%3C/svg%3E") center/contain no-repeat;
  mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'%3E%3Cpath fill='%23000' d='M1.4 0 6 4.6 10.6 0 12 1.4 6 7.4 0 1.4z'/%3E%3C/svg%3E") center/contain no-repeat}
.faq details[open] summary::after{transform:rotate(180deg)}
.faq .ans{padding:0 1.3rem 1.3rem;color:var(--muted)}
.dark .faq .ans{color:#A9A9B4}
.faq .ans p:last-child{margin-bottom:0}

/* ---------- CTA band ------------------------------------------------------ */

.ctaband{background:var(--gold);color:#000}
.ctaband h2{color:#000}
.ctaband p{color:#3A2C05;max-width:56ch}
.ctaband .btn{background:#000;color:var(--gold)}
.ctaband .btn:hover{background:var(--ink-2)}
.ctaband .btn-out{--ghost:#000;--ghost-ink:var(--gold)}

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

.foot{background:var(--black);color:#9C9CA6;padding-block:clamp(48px,6vw,76px) 0}
.foot-g{display:grid;grid-template-columns:1.5fr 1fr 1fr 1.25fr;gap:clamp(24px,3vw,44px)}
.foot h4{color:#fff;font-size:.83rem;letter-spacing:.14em;text-transform:uppercase;
  margin-bottom:1.05rem}
.foot ul{list-style:none;margin:0;padding:0;display:grid;gap:.6rem}
.foot ul a{text-decoration:none;font-size:.95rem;position:relative;display:inline-block}
.foot ul a::after{content:"";position:absolute;left:0;right:0;bottom:-3px;height:1.5px;
  background:var(--gold);transform:scaleX(0);transform-origin:left;
  transition:transform .24s var(--e)}
.foot ul a:hover{color:#fff}
.foot ul a:hover::after{transform:scaleX(1)}
.foot .fbrand .mark{width:auto;height:76px;margin-bottom:1.1rem;display:block}
.foot .fbrand p{font-size:.94rem;max-width:36ch}
.socials{display:flex;gap:.6rem;margin-top:1.1rem}
/* No outer tile. Facebook's mark is a circle, Nextdoor's is a rounded square and
   Google's G has no container at all, so wrapping all three in a fourth box gave a
   nested box-in-a-box and three mismatched silhouettes inside it. The official
   artwork IS the button; the 44px anchor is the tap target around it.
   Sized per mark for equal optical weight: a filled square reads heavier than a
   circle at the same height, and an open glyph reads lighter than both. */
.socials a{width:44px;height:44px;display:grid;place-items:center;
  transition:transform .18s var(--e),opacity .18s var(--e)}
.socials a:hover{transform:translateY(-2px)}
.leaverev{display:inline-flex;align-items:center;gap:.5rem;margin-top:1rem;min-height:44px;
  font:600 .95rem/1.2 var(--ff-b);color:#C9C9D2;text-decoration:none;
  transition:color .18s var(--e)}
.leaverev svg{width:17px;height:17px;color:var(--gold)}
.leaverev:hover{color:#fff}
.socials a:active{transform:translateY(0)}
.socials svg{width:auto}
.socials .bm-fb{height:30px}
.socials .bm-g{height:28px}
.socials .bm-nd{height:27px}
.foot-b{margin-top:clamp(34px,4vw,54px);border-top:1px solid var(--line-dk);
  padding-block:1.5rem calc(1.5rem + var(--bar-h) + env(safe-area-inset-bottom));
  display:flex;flex-wrap:wrap;gap:.8rem 1.6rem;justify-content:space-between;font-size:.84rem}


/* ---------- fixed mobile action bar --------------------------------------- */

.actionbar{position:fixed;left:0;right:0;bottom:0;z-index:92;display:none;
  grid-template-columns:1fr 1fr;background:var(--black);
  padding-bottom:env(safe-area-inset-bottom)}
.actionbar a{display:flex;align-items:center;justify-content:center;gap:.5rem;
  min-height:58px;text-decoration:none;font-weight:700;font-size:1rem;
  border-top:1px solid var(--line-dk)}
.actionbar .ab-call{background:var(--gold);color:#000;border-top-color:var(--gold)}
.actionbar .ab-quote{background:var(--black);color:#fff;border-left:1px solid var(--line-dk)}
.actionbar svg{width:19px;height:19px}

.totop{position:fixed;right:18px;bottom:calc(18px + var(--bar-h) + env(safe-area-inset-bottom));
  width:50px;height:50px;border-radius:50%;border:2px solid var(--line-dk);
  background:var(--black);color:#fff;display:grid;place-items:center;cursor:pointer;z-index:91;
  opacity:0;visibility:hidden;transform:translateY(10px);
  transition:opacity .24s var(--e),transform .24s var(--e),visibility .24s,background-color .18s var(--e)}
.totop[data-on="true"]{opacity:1;visibility:visible;transform:none}
.totop:hover{background:var(--gold);border-color:var(--gold);color:#000}
.totop svg{width:19px;height:19px}

/* 404 "did you mean" */
.suggest{margin-top:1.8rem;padding:18px 20px;border-left:4px solid var(--gold);
  background:#fff;border-radius:var(--r-s);border:1px solid var(--line);
  display:flex;flex-direction:column;gap:.5rem;max-width:520px}
.suggest[hidden]{display:none}
.sg-link{display:inline-flex;align-items:center;gap:.6rem;text-decoration:none;
  font-family:var(--ff-d);font-weight:800;font-size:1.5rem;text-transform:uppercase;
  color:var(--ink);min-height:44px}
.sg-link svg{width:20px;height:20px;color:var(--gold-lo);transition:transform .2s var(--e)}
.sg-link:hover svg{transform:translateX(4px)}

.pagelist{margin-top:clamp(34px,4vw,54px);display:grid;
  grid-template-columns:repeat(auto-fill,minmax(240px,1fr));gap:10px}
.pagelist a{display:flex;flex-direction:column;gap:.2rem;padding:14px 16px;min-height:44px;
  background:#fff;border:1px solid var(--line);border-radius:var(--r-s);text-decoration:none;
  transition:border-color .18s var(--e),transform .18s var(--e)}
.pagelist a:hover{border-color:var(--gold);transform:translateY(-2px)}
.pagelist b{font-size:.98rem;color:var(--ink)}
.pagelist span{font-size:.82rem;color:var(--muted)}

/* ---------- preloader (home only) ----------------------------------------
   Panel sits over the hero, shows the mark, a real progress bar and a spinner,
   then swipes UP off the page rather than cross-fading into it.
   With JS off the panel is hidden by a <noscript> rule in the head, and with JS
   on a hard cap in site.js removes it regardless of what the network does.
   A 0s-duration CSS animation was tried as the failsafe and applied its END
   state immediately, so the preloader never painted at all. */
/* scroll lock tied to the element's existence, not to JS state: remove the
   panel and the lock goes with it. A JS-set overflow can leak if anything
   throws between locking and unlocking. */
html:has(.pre){overflow:hidden}
.pre{position:fixed;inset:0;z-index:200;background:var(--black);
  display:grid;place-items:center;
  transform:translateY(0);
  transition:transform .72s cubic-bezier(.76,0,.24,1)}
.pre.up{transform:translateY(-101%)}
.pre-in{display:flex;flex-direction:column;align-items:center;gap:1.05rem;
  padding:0 var(--gut);text-align:center;
  transition:opacity .34s var(--e),transform .34s var(--e)}
.pre.done .pre-in{opacity:0;transform:translateY(-10px)}
.pre-mark{width:clamp(78px,11vw,116px);height:auto;display:block}
.pre-name{font-family:var(--ff-d);font-weight:800;font-size:clamp(1.5rem,3.4vw,2.2rem);
  letter-spacing:.03em;text-transform:uppercase;color:#fff;line-height:1}
.pre-sub{font-size:.82rem;letter-spacing:.13em;text-transform:uppercase;
  color:var(--gold);font-weight:700}
.pre-bar{width:min(280px,62vw);height:3px;background:rgba(255,255,255,.16);
  border-radius:2px;overflow:hidden;margin-top:.4rem}
.pre-bar i{display:block;height:100%;width:100%;background:var(--gold);
  transform:translateX(-100%);transition:transform .32s var(--e)}
.pre-spin{width:19px;height:19px;border:2.5px solid rgba(255,255,255,.28);
  border-top-color:var(--gold);border-radius:50%;
  animation:spin .68s linear infinite}
@media (prefers-reduced-motion:reduce){
  .pre{display:none}
}

/* ---------- reveals ------------------------------------------------------- */

.rv{opacity:0;transform:translateY(22px);
  transition:opacity .62s var(--e),transform .62s var(--e)}
.rv[data-in="true"]{opacity:1;transform:none}
.rv-d1{transition-delay:.07s}
.rv-d2{transition-delay:.14s}
.rv-d3{transition-delay:.21s}

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

@media (max-width:1180px){
  .foot-g{grid-template-columns:1fr 1fr}
  .stats{grid-template-columns:repeat(2,minmax(0,1fr))}
}

@media (max-width:1040px){
  .menu,.phpill{display:none}
  /* the nav CTA plus the logo plus the burger exceeds a phone viewport and
     pushes the burger off-screen. The action bar and the open menu both carry
     the CTA already, so the nav does not need to. */
  .nav-r .btn{display:none}
  .util-in{height:auto;min-height:44px;padding-block:4px}
  .util-l{display:none}
  .util-r{width:100%;justify-content:space-between;gap:.8rem}
  .util-r a{min-height:44px}
  .burger{display:block}
  /* Structural header clearance. The copy used to rely on the photo above it
     for that clearance, so anything that collapsed or reordered the photo put
     the headline under the fixed nav. Adam hit exactly that on an iPhone while
     a 390px emulator rendered it correctly. Padding on .hero cannot be reordered
     away and does not depend on the photo existing. */
  .hero{padding-top:var(--hdr-h)}
  .hero-grid{grid-template-columns:1fr;min-height:0}
  /* width:100% is LOAD-BEARING, not belt-and-braces. `justify-items:normal` on a
     grid resolves to `stretch` EXCEPT for an item with an intrinsic aspect ratio,
     where the spec says `start`. WebKit implements that; Blink stretches anyway.
     Every browser on iOS is WebKit, so without this the box is sized from its
     min-height through the ratio: 180 x 16/11 = 262px wide on a 440px phone.
     Measured on Adam's iPhone 16 Pro Max at 259px. No Chrome emulator reproduces it. */
  .hero-media{aspect-ratio:16/11;order:-1;min-height:180px;width:100%;justify-self:stretch}
  .hero-media img{position:absolute}
  .hero-bite{display:none}
  .hero-copy{padding:clamp(34px,6vw,54px) var(--gut) clamp(46px,7vw,64px)}
  .maprow{grid-template-columns:1fr;grid-template-areas:"map" "panel" "towns"}
}

@media (max-width:880px){
  .g3,.g4{grid-template-columns:repeat(2,minmax(0,1fr))}
  .split{grid-template-columns:1fr;gap:32px}
  .split.flip .split-media{order:0}
  .gal{grid-template-columns:repeat(2,minmax(0,1fr))}
  .actionbar{display:grid}
  .float-card{position:static;max-width:none;margin-top:16px;box-shadow:none}
  .seal{width:clamp(84px,22vw,104px);right:12px;bottom:clamp(10px,2vw,16px)}
  .m-circle,.m-arch{max-width:min(400px,74vw);margin-inline:auto}
}

@media (max-width:600px){
  body{font-size:16px}
  .foot ul{gap:.15rem}
  .foot ul a{padding-block:.62rem}
  .crumbs a{padding-block:.4rem}
  .g2,.g3,.g4{grid-template-columns:1fr}
  .fgrid{grid-template-columns:1fr}
  .foot-g{grid-template-columns:1fr}
  .stats{grid-template-columns:1fr}
  .gal{grid-template-columns:1fr 1fr;gap:10px}
  .hero-proof{gap:1.1rem 1.6rem}
  .hero-proof b{font-size:1.42rem}
  .btns .btn{width:100%}
}

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

/* ---------- TOUCH TARGETS (retrofit 2026-08) ---------------------------
   Craft floor: 44px for any standalone control, verified at a real 390x844
   touch viewport. Scoped to (pointer: coarse) so the desktop look is
   unchanged: a mouse does not need a 44px target. Height is the binding
   constraint; a short text link may stay narrow. */
@media (pointer: coarse) {
  /* min-height carries !important deliberately. This is an accessibility floor,
     not styling: component rules elsewhere set min-height:24px and, being more
     specific, silently beat an appended override. A floor that any component can
     out-specify is not a floor. Scoped to coarse pointers, so the desktop
     cascade is untouched.
     Container list came from MEASURING at 390x844, not from guessing. Not a
     blanket rule on every <a>: that inflates the line box of inline prose links. */
  .crumb a, .crumbs a, .u-r a, .util a, .lede a, .socs a, .proof a, .who a,
  .foot a, footer a, nav a, .rev a, .card a, .chips a,
  header .wrap > a, footer .wrap > a{
    display:inline-flex;align-items:center;min-height:44px !important}
  .socs a{min-width:44px;justify-content:center}
  .snav,.totop,.burger{min-width:44px !important;min-height:44px !important}
  .chip,.gf,.sndbtn,.pill{min-height:44px !important}
}
