/* ═══════════════════════════════════════════════
   BUDGET HARDWARE — Premium Redesign + Motion System
   Palette: Deep Navy · Clean White · Budget Blue
   ═══════════════════════════════════════════════ */

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

:root {
  --bg:       #F4F8FC;
  --white:    #FFFFFF;
  --ink:      #081625;
  --ink2:     #0D2034;
  --blue:     #075FAE;
  --blue-h:   #044982;
  --blue-light: #5CB7FF;
  --blue-rgb: 7,95,174;
  --blue-light-rgb: 92,183,255;
  --muted:    #5F7083;
  --border:   #DDE8F2;
  --sans:     'Inter', system-ui, sans-serif;
  --serif:    'Playfair Display', Georgia, serif;

  /* Fluid layout rhythm — one source of truth for horizontal gutters
     and vertical band spacing. Scales 22px → 80px across viewports so
     no breakpoint is ever left with desktop padding on a phone. */
  --gutter:      clamp(22px, 6vw, 80px);
  --band-y:      clamp(64px, 10vw, 120px);
  --band-y-lg:   clamp(80px, 12vw, 180px);
  --band-y-hero: clamp(116px, 22vw, 180px);
  --stack-gap:   clamp(36px, 8vw, 100px);
}

html { scroll-behavior: smooth; overflow-x: hidden; }
body {
  font-family: var(--sans); background: var(--bg); color: var(--ink);
  overflow-x: hidden;
  overscroll-behavior-x: none;   /* no horizontal rubber-banding */
  width: 100%;
}

/* ══════════════════════════════════════════════
   CUSTOM CURSOR
   ══════════════════════════════════════════════ */
* { cursor: none; }
@media (hover: none), (max-width: 1024px) {
  * { cursor: auto; }
  .cursor-dot, .cursor-ring { display: none !important; }
}
.cursor-dot {
  position: fixed; top: 0; left: 0; width: 6px; height: 6px;
  background: var(--blue); border-radius: 50%;
  pointer-events: none; z-index: 9999;
  transform: translate(-50%, -50%);
  will-change: transform;
}
.cursor-ring {
  position: fixed; top: 0; left: 0; width: 36px; height: 36px;
  border: 1px solid rgba(var(--blue-rgb),0.5); border-radius: 50%;
  pointer-events: none; z-index: 9998;
  transform: translate(-50%, -50%);
  transition: width 0.35s cubic-bezier(0.16,1,0.3,1),
              height 0.35s cubic-bezier(0.16,1,0.3,1),
              border-color 0.3s, background 0.3s;
  will-change: transform;
  display: flex; align-items: center; justify-content: center;
}
.cursor-ring.hovering {
  width: 72px; height: 72px;
  background: rgba(var(--blue-rgb),0.08);
  border-color: var(--blue);
}
.cursor-ring.hovering::after {
  content: 'VIEW';
  font-family: var(--sans); font-size: 8px; letter-spacing: 0.2em;
  color: var(--blue); font-weight: 500;
}
.cursor-ring.clicking {
  width: 28px; height: 28px;
  background: rgba(var(--blue-rgb),0.2);
}

/* ══════════════════════════════════════════════
   SCROLL REVEAL BASE SYSTEM
   ══════════════════════════════════════════════ */
.reveal {
  opacity: 0; transform: translateY(46px) scale(0.985);
  transition: opacity 0.85s cubic-bezier(0.16,1,0.3,1), transform 0.9s cubic-bezier(0.16,1,0.3,1);
  transition-delay: var(--d, 0ms);
}
.reveal.visible { opacity: 1; transform: translateY(0) scale(1); }
.reveal-delay-1 { transition-delay: 0.1s; }
.reveal-delay-2 { transition-delay: 0.2s; }
.reveal-delay-3 { transition-delay: 0.32s; }
.reveal-delay-4 { transition-delay: 0.44s; }
.reveal-delay-5 { transition-delay: 0.56s; }
.reveal-left {
  opacity: 0; transform: translateX(-56px);
  transition: opacity 0.9s cubic-bezier(0.16,1,0.3,1), transform 0.95s cubic-bezier(0.16,1,0.3,1);
  transition-delay: var(--d, 0ms);
}
.reveal-left.visible { opacity: 1; transform: translateX(0); }
.reveal-right {
  opacity: 0; transform: translateX(56px);
  transition: opacity 0.9s cubic-bezier(0.16,1,0.3,1), transform 0.95s cubic-bezier(0.16,1,0.3,1);
  transition-delay: var(--d, 0ms);
}
.reveal-right.visible { opacity: 1; transform: translateX(0); }
.reveal-scale {
  opacity: 0; transform: scale(0.9);
  transition: opacity 0.8s cubic-bezier(0.16,1,0.3,1), transform 0.85s cubic-bezier(0.16,1,0.3,1);
  transition-delay: var(--d, 0ms);
}
.reveal-scale.visible { opacity: 1; transform: scale(1); }

/* ══════════════════════════════════════════════
   STAGGER
   The site already revealed almost everything — but each group fired at
   once, so five service rows or twelve brand cells arrived as a single
   slab. Rhythm is what was missing, not motion. A container marked
   .stagger hands its children an incremental --d, which the reveal
   transitions below consume. One mechanism, used by every repeating group.
   A .reveal-delay-* class still wins where a delay was set by hand.
   ══════════════════════════════════════════════ */
.stagger > *:nth-child(1)  { --d: 0ms; }
.stagger > *:nth-child(2)  { --d: 70ms; }
.stagger > *:nth-child(3)  { --d: 140ms; }
.stagger > *:nth-child(4)  { --d: 210ms; }
.stagger > *:nth-child(5)  { --d: 280ms; }
.stagger > *:nth-child(6)  { --d: 350ms; }
.stagger > *:nth-child(7)  { --d: 420ms; }
.stagger > *:nth-child(8)  { --d: 490ms; }
.stagger > *:nth-child(9)  { --d: 560ms; }
.stagger > *:nth-child(10) { --d: 630ms; }
.stagger > *:nth-child(11) { --d: 700ms; }
.stagger > *:nth-child(12) { --d: 770ms; }
/* Wider groups read better a little quicker — twelve cells at 70ms is a
   two-second wait for the last one. */
.stagger-tight > *:nth-child(n) { --d: 0ms; }
.stagger-tight > *:nth-child(2)  { --d: 42ms; }
.stagger-tight > *:nth-child(3)  { --d: 84ms; }
.stagger-tight > *:nth-child(4)  { --d: 126ms; }
.stagger-tight > *:nth-child(5)  { --d: 168ms; }
.stagger-tight > *:nth-child(6)  { --d: 210ms; }
.stagger-tight > *:nth-child(7)  { --d: 252ms; }
.stagger-tight > *:nth-child(8)  { --d: 294ms; }
.stagger-tight > *:nth-child(9)  { --d: 336ms; }
.stagger-tight > *:nth-child(10) { --d: 378ms; }
.stagger-tight > *:nth-child(11) { --d: 420ms; }
.stagger-tight > *:nth-child(12) { --d: 462ms; }

/* ══════════════════════════════════════════════
   ALTERNATING POP — the magazine grid
   Cards enter one at a time, alternating side: 01 from the left, 02 from
   the right, and so on down the numbered order. The sequence follows the
   card LABELS, not the DOM — the grid nests columns inside columns, so
   nth-child could never express the order the eye actually reads.
   Hence an explicit --pop index per card.
   ══════════════════════════════════════════════ */
/* Scoped to .cat-card.pop on purpose. `.cat-card` declares
   `transition: box-shadow 0.5s` further down this sheet at the SAME
   specificity (0,1,0), so on source order it would win and its shorthand
   would reset the whole property — the cards would snap into place with no
   animation at all. One extra class outranks it; box-shadow is folded back
   in so the hover lift still animates. */
.cat-card.pop {
  opacity: 0;
  transform: translateX(var(--from, -80px)) scale(0.92);
  transition: opacity 0.8s cubic-bezier(0.16,1,0.3,1),
              transform 0.95s cubic-bezier(0.16,1,0.3,1),
              box-shadow 0.5s cubic-bezier(0.16,1,0.3,1);
  transition-delay: calc(var(--pop, 0) * 115ms), calc(var(--pop, 0) * 115ms), 0s;
  will-change: transform, opacity;
}
.pop-l { --from: -84px; }
.pop-r { --from:  84px; }
.cat-card.pop.visible { opacity: 1; transform: translateX(0) scale(1); }

/* Second beat: once a card has landed, its own title rises into it. The
   card arriving and the card naming itself are two separate events, and
   separating them is most of why this reads as deliberate rather than
   as six things sliding about.
   Only .cat-name / .cat-count take part — .cat-info and .cat-label carry
   the 3D translateZ used on pointer devices, and overwriting their
   transform here would flatten the card on desktop. */
.pop .cat-name, .pop .cat-count {
  opacity: 0; transform: translateY(15px);
  transition: opacity 0.55s ease, transform 0.7s cubic-bezier(0.16,1,0.3,1);
  transition-delay: calc(var(--pop, 0) * 115ms + 400ms);
}
.pop .cat-count { transition-delay: calc(var(--pop, 0) * 115ms + 470ms); }
.pop.visible .cat-name,
.pop.visible .cat-count { opacity: 1; transform: translateY(0); }

/* ══════════════════════════════════════════════
   SPLIT-TEXT HEADING REVEAL
   ══════════════════════════════════════════════ */
.split-line { display: block; overflow: hidden; line-height: 1.15; }
.split-line > span {
  display: block;
  transform: translateY(110%) rotate(1.5deg);
  transition: transform 1.05s cubic-bezier(0.16,1,0.3,1);
  transform-origin: left bottom;
}
.split-line.in-view > span { transform: translateY(0) rotate(0deg); }
.split-line:nth-child(2) > span { transition-delay: 0.13s; }
.split-line:nth-child(3) > span { transition-delay: 0.26s; }
.split-line:nth-child(4) > span { transition-delay: 0.39s; }

/* ══════════════════════════════════════════════
   IMAGE CURTAIN REVEAL
   ══════════════════════════════════════════════ */
.img-curtain { position: relative; overflow: hidden; }
.img-curtain img {
  clip-path: inset(100% 0 0 0);
  transform: scale(1.12);
  transition: clip-path 1.3s cubic-bezier(0.77,0,0.18,1),
              transform 1.8s cubic-bezier(0.16,1,0.3,1);
}
.img-curtain.curtain-visible img {
  clip-path: inset(0% 0 0 0);
  transform: scale(1);
}

/* ══════════════════════════════════════════════
   ACCENT LINE
   ══════════════════════════════════════════════ */
.seam {
  height: 1px; max-width: 1280px; margin: 0 auto 0;
  background: var(--blue); opacity: 0.22;
  transform: scaleX(0); transform-origin: left;
  transition: transform 1.5s cubic-bezier(0.77,0,0.18,1);
}
.seam.seam-visible { transform: scaleX(1); }
.seam-full { max-width: none; width: 100%; padding: 0 var(--gutter); box-sizing: border-box; }

/* ══════════════════════════════════════════════
   NAV
   ══════════════════════════════════════════════ */
#nav {
  position: fixed; top: 0; left: 0; right: 0; z-index: 120;
  transition: all 0.5s cubic-bezier(0.16,1,0.3,1);
  padding: 0 48px;
}
#nav.transparent .nav-inner {
  background: transparent; border: none; box-shadow: none;
  border-radius: 0; padding: 32px 0; max-width: none; margin: 0;
}
#nav.transparent .nav-logo,
#nav.transparent .nav-links a { color: #fff; }
#nav.transparent .nav-logo em { color: var(--blue-light); }
#nav.transparent .nav-links a:hover,
#nav.transparent .nav-links a.active { color: var(--blue-light); }
#nav.transparent .nav-cta { border-color: rgba(255,255,255,0.4); color: #fff; }
#nav.transparent .nav-cta:hover { background: rgba(255,255,255,0.12); }
#nav.transparent .nav-menu-btn span { background: #fff; }
#nav.scrolled { padding: 12px 48px; }
#nav.scrolled .nav-inner {
  background: rgba(255,255,255,0.9);
  backdrop-filter: blur(24px) saturate(1.4);
  -webkit-backdrop-filter: blur(24px) saturate(1.4);
  border: 1px solid rgba(var(--blue-rgb),0.15);
  box-shadow: 0 4px 48px rgba(0,0,0,0.1);
  border-radius: 16px; padding: 14px 32px;
  max-width: 1440px; margin: 0 auto;
  animation: navMorph 0.55s cubic-bezier(0.34,1.56,0.64,1) both;
}
@keyframes navMorph {
  from { transform: scaleX(0.94) translateY(-10px); opacity: 0.5; }
  to   { transform: scaleX(1) translateY(0); opacity: 1; }
}
.nav-inner { display: flex; align-items: center; justify-content: space-between; transition: all 0.5s cubic-bezier(0.16,1,0.3,1); }
.nav-logo { font-family: var(--serif); font-size: 22px; font-weight: 400; color: var(--ink); text-decoration: none; letter-spacing: 0.03em; transition: color 0.3s; cursor: none; }
.nav-logo em { font-style: italic; color: var(--blue); }
.nav-links { display: flex; gap: 36px; list-style: none; }
.nav-links a { font-size: 12px; font-weight: 400; letter-spacing: 0.1em; color: var(--ink); text-decoration: none; text-transform: uppercase; transition: color 0.3s, opacity 0.3s; opacity: 0.55; cursor: none; }
.nav-links a:hover, .nav-links a.active { opacity: 1; color: var(--blue); }
.nav-cta {
  font-size: 11px; font-weight: 500; letter-spacing: 0.12em; text-transform: uppercase;
  padding: 10px 24px; border: 1px solid var(--ink); border-radius: 100px;
  background: transparent; color: var(--ink); cursor: none; transition: background 0.3s, color 0.3s, box-shadow 0.3s;
}
.nav-cta:hover { background: var(--ink); color: #fff; }

/* ── MOBILE MENU BUTTON ──────────────────────────
   Two rules of unequal length, not three equal bars. Two is what makes the
   open state a geometrically exact X — three forces a bar to vanish and the
   cross to fake its centre. The short rule extending to meet the long one on
   press is the whole micro-interaction; nothing else moves.
   The button stays anchored and becomes the close control, so the drawer
   carries no second dismiss affordance. */
.nav-menu-btn {
  display: none;
  position: relative;
  width: 44px; height: 44px;      /* full touch target, larger than the mark */
  margin-right: -11px;            /* optical alignment: mark to the gutter */
  background: transparent; border: none; padding: 0; cursor: pointer;
  border-radius: 50%;
  -webkit-tap-highlight-color: transparent;
}
.nav-menu-btn span {
  position: absolute; left: 50%; top: 50%;
  height: 1.5px; border-radius: 2px;
  background: var(--ink);
  transition: width 0.45s cubic-bezier(0.16,1,0.3,1),
              transform 0.5s cubic-bezier(0.16,1,0.3,1),
              background-color 0.3s;
}
.nav-menu-btn span:nth-child(1) { width: 22px; transform: translate(-50%,-50%) translateY(-4px); }
.nav-menu-btn span:nth-child(2) { width: 14px; transform: translate(-50%,-50%) translateY(4px); }
.nav-menu-btn:hover span:nth-child(2),
.nav-menu-btn:focus-visible span:nth-child(2) { width: 22px; }
.nav-menu-btn.open span { width: 21px; }
.nav-menu-btn.open span:nth-child(1) { transform: translate(-50%,-50%) rotate(45deg); }
.nav-menu-btn.open span:nth-child(2) { transform: translate(-50%,-50%) rotate(-45deg); }
.nav-menu-btn:focus-visible { outline: 2px solid var(--blue-light); outline-offset: 3px; }

#nav.transparent .nav-menu-btn span,
#nav.menu-open   .nav-menu-btn span { background: #fff; }

/* While the drawer is open the bar keeps only its logo and mark: the scrolled
   pill would otherwise float as a white slab on top of the dark panel. */
#nav.menu-open .nav-inner {
  background: transparent; border-color: transparent; box-shadow: none;
  backdrop-filter: none; -webkit-backdrop-filter: none;
}
#nav.menu-open .nav-logo { color: #fff; }
#nav.menu-open .nav-logo em { color: var(--blue-light); }

/* ── DRAWER ──────────────────────────────────────
   Signature: a plumb line. A hairline drops down the left of the list as the
   drawer opens, and a diamond marks where you currently stand on it. The
   plumb line is the one reference a builder trusts for true vertical, and the
   diamond is already this site's own mark — it sets every beat of the
   marquee. So the structure is drawn from the trade rather than applied to
   it, and it replaces the row of hairline underlines that used to separate
   the links: the line carries the structure now, so the rules came out. */
.nav-mobile-panel {
  position: fixed; top: 0; right: 0; height: 100vh; width: 100%; max-width: 396px;
  background: linear-gradient(158deg, #10273E 0%, #081625 52%, #04101B 100%);
  z-index: 105;
  transform: translateX(100%);
  /* Closed, the drawer is taken OUT of the render tree — not merely shoved
     off-canvas. Parking it at translateX(100%) and trusting
     body{overflow-x:hidden} to swallow it is a mask, not containment:
     Chromium honours it, but iOS Safari still lets you pan to the parked
     panel, which reads as dead space on the right of every page.
     visibility:hidden removes it from paint, hit-testing and the a11y tree,
     so there is nothing left out there to reach or tab into. */
  visibility: hidden;
  pointer-events: none;
  /* Exit runs at ~65% of entry so dismissing feels answered, not narrated. */
  transition: transform 0.34s cubic-bezier(0.7,0,0.84,0),
              visibility 0s linear 0.34s;
  display: flex; flex-direction: column;
  padding: 104px 34px 36px;
  overflow-y: auto; overscroll-behavior: contain;
}
@supports (height: 100dvh) { .nav-mobile-panel { height: 100dvh; } }
.nav-mobile-panel.open {
  transform: translateX(0);
  visibility: visible;
  pointer-events: auto;
  transition: transform 0.58s cubic-bezier(0.16,1,0.3,1), visibility 0s;
}
/* A single hairline of brand blue down the trailing edge — the drawer reads
   as a measured edge rather than a slab that ends. */
.nav-mobile-panel::after {
  content: ''; position: absolute; top: 0; bottom: 0; left: 0; width: 1px;
  background: linear-gradient(to bottom,
    transparent, rgba(var(--blue-light-rgb),0.42) 22%,
    rgba(var(--blue-light-rgb),0.42) 78%, transparent);
}

.nav-mobile-eyebrow {
  font-size: 10px; font-weight: 500; letter-spacing: 0.24em; text-transform: uppercase;
  color: rgba(var(--blue-light-rgb),0.72);
  margin-bottom: 26px;
  opacity: 0; transform: translateY(8px);
  transition: opacity 0.5s ease 0.14s, transform 0.5s cubic-bezier(0.16,1,0.3,1) 0.14s;
}
.nav-mobile-panel.open .nav-mobile-eyebrow { opacity: 1; transform: translateY(0); }

/* The list is inset past the plumb line, which is drawn on the <ul>. */
.nav-mobile-links {
  position: relative; list-style: none;
  display: flex; flex-direction: column;
  padding-left: 26px;
}
.nav-mobile-links::before {
  content: ''; position: absolute; left: 0; top: 4px; bottom: 4px; width: 1px;
  background: linear-gradient(to bottom,
    rgba(255,255,255,0.22), rgba(255,255,255,0.09));
  transform: scaleY(0); transform-origin: top center;
  transition: transform 0.72s cubic-bezier(0.16,1,0.3,1) 0.1s;
}
.nav-mobile-panel.open .nav-mobile-links::before { transform: scaleY(1); }

.nav-mobile-links li { position: relative; }
.nav-mobile-links a {
  display: block;
  font-family: var(--serif);
  font-size: clamp(29px, 8.4vw, 38px);
  font-weight: 400; letter-spacing: -0.022em; line-height: 1.04;
  color: rgba(255,255,255,0.52);
  text-decoration: none; cursor: pointer;
  padding: 13px 0;                       /* ≥44px touch target at this size */
  opacity: 0; transform: translateY(16px);
  transition: opacity 0.55s ease,
              transform 0.6s cubic-bezier(0.16,1,0.3,1),
              color 0.3s;
}
.nav-mobile-panel.open .nav-mobile-links a { opacity: 1; transform: translateY(0); }
/* 44ms apart — inside the 30–50ms band where a stagger reads as one gesture
   rather than six separate arrivals. */
.nav-mobile-panel.open .nav-mobile-links li:nth-child(1) a { transition-delay: 0.22s, 0.22s, 0s; }
.nav-mobile-panel.open .nav-mobile-links li:nth-child(2) a { transition-delay: 0.264s, 0.264s, 0s; }
.nav-mobile-panel.open .nav-mobile-links li:nth-child(3) a { transition-delay: 0.308s, 0.308s, 0s; }
.nav-mobile-panel.open .nav-mobile-links li:nth-child(4) a { transition-delay: 0.352s, 0.352s, 0s; }
.nav-mobile-panel.open .nav-mobile-links li:nth-child(5) a { transition-delay: 0.396s, 0.396s, 0s; }
.nav-mobile-panel.open .nav-mobile-links li:nth-child(6) a { transition-delay: 0.44s,  0.44s,  0s; }

.nav-mobile-links a:hover,
.nav-mobile-links a:focus-visible { color: rgba(255,255,255,0.86); }
.nav-mobile-links a:focus-visible { outline: 2px solid var(--blue-light); outline-offset: 4px; border-radius: 2px; }
.nav-mobile-links a:active { color: #fff; }

/* The bob: where you currently stand on the line. */
.nav-mobile-links a.active { color: #fff; }
.nav-mobile-links a.active::before {
  content: ''; position: absolute; left: -30px; top: 50%;
  width: 7px; height: 7px; margin-top: -3.5px;
  background: var(--blue-light);
  transform: rotate(45deg) scale(0);
  box-shadow: 0 0 14px rgba(var(--blue-light-rgb),0.85);
  transition: transform 0.6s cubic-bezier(0.34,1.56,0.64,1) 0.5s;
}
.nav-mobile-panel.open .nav-mobile-links a.active::before { transform: rotate(45deg) scale(1); }

/* Pressing a link runs a tick out from the plumb line towards it. */
.nav-mobile-links a:not(.active)::before {
  content: ''; position: absolute; left: -26px; top: 50%;
  width: 16px; height: 1px; margin-top: -0.5px;
  background: var(--blue-light);
  transform: scaleX(0); transform-origin: left center;
  transition: transform 0.4s cubic-bezier(0.16,1,0.3,1);
}
.nav-mobile-links a:not(.active):hover::before,
.nav-mobile-links a:not(.active):active::before { transform: scaleX(1); }

/* ── DRAWER FOOTER ──
   The old drawer ended on a floating outline pill that said "Visit Store"
   and went to the contact page. On a phone, a contractor tapping that wants
   the address or the phone — so the footer gives both directly, and the
   button states the actual destination. */
.nav-mobile-foot {
  margin-top: auto; padding-top: 34px;
  opacity: 0; transform: translateY(12px);
  transition: opacity 0.55s ease 0.5s, transform 0.6s cubic-bezier(0.16,1,0.3,1) 0.5s;
}
.nav-mobile-panel.open .nav-mobile-foot { opacity: 1; transform: translateY(0); }
.nav-mobile-foot-rule {
  height: 1px; margin-bottom: 22px;
  background: linear-gradient(to right, rgba(255,255,255,0.18), transparent);
}
.nav-mobile-foot-label {
  font-size: 9.5px; font-weight: 500; letter-spacing: 0.2em; text-transform: uppercase;
  color: rgba(255,255,255,0.3); margin-bottom: 10px;
}
.nav-mobile-foot a {
  display: block; font-size: 14px; line-height: 1.6;
  color: rgba(255,255,255,0.62); text-decoration: none;
  transition: color 0.3s;
}
.nav-mobile-foot a:hover, .nav-mobile-foot a:focus-visible { color: var(--blue-light); }
.nav-mobile-foot-addr { font-size: 13.5px; line-height: 1.65; color: rgba(255,255,255,0.4); margin-bottom: 14px; }
.nav-mobile-cta {
  margin-top: 22px; width: 100%;
  display: inline-flex; align-items: center; justify-content: center; gap: 10px;
  font-family: var(--sans);
  font-size: 11px; font-weight: 500; letter-spacing: 0.14em; text-transform: uppercase;
  padding: 16px 28px; border: none; border-radius: 100px;
  background: var(--blue); color: #fff; cursor: pointer;
  transition: background 0.3s, box-shadow 0.3s, transform 0.3s;
}
.nav-mobile-cta:hover { background: var(--blue-h); box-shadow: 0 10px 30px rgba(var(--blue-rgb),0.4); }
.nav-mobile-cta:active { transform: scale(0.985); }
.nav-mobile-cta svg { width: 13px; height: 13px; stroke: currentColor; fill: none; }

.nav-mobile-backdrop {
  position: fixed; inset: 0;
  background: rgba(3,9,16,0.6);
  backdrop-filter: blur(7px) saturate(0.8);
  -webkit-backdrop-filter: blur(7px) saturate(0.8);
  z-index: 104; opacity: 0; pointer-events: none;
  transition: opacity 0.45s ease;
}
.nav-mobile-backdrop.open { opacity: 1; pointer-events: auto; }

/* ══════════════════════════════════════════════
   PAGES
   ══════════════════════════════════════════════ */
.page { display: none; }
.page.active { display: block; }
.page { animation: pageFade 0.65s cubic-bezier(0.16,1,0.3,1) both; }
@keyframes pageFade { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: translateY(0); } }

/* ══════════════════════════════════════════════
   SECTION COMMONS
   ══════════════════════════════════════════════ */
section { padding: var(--band-y) var(--gutter); }

/* ── BAND UTILITIES ──────────────────────────────
   Replaces the per-page inline `padding:180px 80px` styles.
   Inline styles outrank media queries, so any section that
   carried them kept 80px side padding on a 375px phone and
   crushed its text into a ~215px column. These classes keep
   the same desktop look but breathe on small screens. */
.band        { padding: var(--band-y) var(--gutter); }
.band-lg     { padding: var(--band-y-lg) var(--gutter); }
.band-hero   { padding: var(--band-y-hero) var(--gutter) var(--band-y); }
.band-dark   { background: var(--ink); }
.band-light  { background: var(--bg); }
.band-white  { background: var(--white); }
.band-inner  { max-width: 1280px; margin: 0 auto; }
.band-center { text-align: center; }
.band-center .section-eyebrow,
.band-center .section-h2,
.band-center .band-lede { text-align: center; }
.band-center .section-h2 { max-width: 580px; margin-left: auto; margin-right: auto; }
.band-lede {
  font-size: 15px; line-height: 1.8; color: rgba(255,255,255,0.38);
  max-width: 400px; margin: 0 auto 44px;
}

/* Two-column editorial split that collapses to a single stack */
.split-2 {
  display: grid; grid-template-columns: 1fr 1fr;
  gap: var(--stack-gap); align-items: center;
  max-width: 1280px; margin: 0 auto;
}

/* Forced line breaks that only make sense on wide screens */
@media (max-width: 700px) { .br-lg { display: none; } }

/* Dark page-header title (brands / contact / categories heroes) */
.page-title {
  color: #fff;
  font-size: clamp(32px, 8vw, 68px);
  max-width: 640px;
}

.section-eyebrow {
  font-size: 10px; font-weight: 500; letter-spacing: 0.22em; text-transform: uppercase;
  color: var(--blue); margin-bottom: 16px; display: block;
}
.section-h2 {
  font-family: var(--serif); font-size: clamp(32px, 4vw, 56px);
  font-weight: 400; line-height: 1.1; letter-spacing: -0.03em; margin-bottom: 24px;
}
.section-body { font-size: 16px; color: var(--muted); line-height: 1.85; max-width: 540px; }
.divider { width: 40px; height: 1px; background: var(--blue); opacity: 0.5; margin-bottom: 44px; }

/* ══════════════════════════════════════════════
   BUTTONS — magnetic transform owned by JS
   ══════════════════════════════════════════════ */
.btn-primary {
  font-size: 11px; font-weight: 500; letter-spacing: 0.14em; text-transform: uppercase;
  padding: 15px 36px; background: var(--blue); color: #fff;
  border: none; border-radius: 100px; cursor: none;
  display: inline-flex; align-items: center; gap: 10px;
  transition: background 0.3s, box-shadow 0.3s;
  will-change: transform;
}
.btn-primary:hover { background: var(--blue-h); box-shadow: 0 8px 28px rgba(var(--blue-rgb),0.35); }
.btn-ghost {
  font-size: 11px; font-weight: 500; letter-spacing: 0.14em; text-transform: uppercase;
  padding: 15px 36px; background: transparent; color: #fff;
  border: 1px solid rgba(255,255,255,0.35); border-radius: 100px;
  cursor: none; transition: background 0.3s, border-color 0.3s;
  will-change: transform;
}
.btn-ghost:hover { background: rgba(255,255,255,0.1); border-color: rgba(255,255,255,0.65); }
.btn-dark {
  font-size: 11px; font-weight: 500; letter-spacing: 0.14em; text-transform: uppercase;
  padding: 15px 36px; background: var(--ink); color: #fff;
  border: none; border-radius: 100px; cursor: none;
  display: inline-flex; align-items: center; gap: 10px;
  transition: background 0.3s, box-shadow 0.3s;
  will-change: transform;
}
.btn-dark:hover { background: #222220; box-shadow: 0 8px 28px rgba(0,0,0,0.25); }

/* ══════════════════════════════════════════════
   HERO
   ══════════════════════════════════════════════ */
.hero {
  position: relative; width: 100%; height: 100vh; min-height: 700px;
  overflow: hidden; display: flex; align-items: center;
}
@supports (height: 100dvh) { .hero { height: 100dvh; } }
.hero-bg {
  position: absolute; inset: 0;
  background-image: url('../images/hero.jpg');
  background-size: cover; background-position: center;
  transform: scale(1.06); will-change: transform;
  animation: heroZoom 10s cubic-bezier(0.16,1,0.3,1) forwards;
}
@keyframes heroZoom { from { transform: scale(1.06); } to { transform: scale(1.0); } }
.hero-overlay {
  position: absolute; inset: 0;
  background: linear-gradient(105deg, rgba(0,0,0,0.75) 0%, rgba(0,0,0,0.45) 55%, rgba(0,0,0,0.18) 100%);
}
.hero-word {
  position: absolute; bottom: -60px; right: -40px;
  font-family: var(--serif); font-size: clamp(180px, 28vw, 360px);
  font-weight: 400; color: rgba(255,255,255,0.035);
  line-height: 1; pointer-events: none; user-select: none; letter-spacing: -0.04em;
  will-change: transform;
}
.hero-line {
  position: absolute; left: 80px; top: 50%; transform: translateY(-50%);
  width: 1px; height: 120px; background: rgba(255,255,255,0.15);
  animation: lineGrow 1.4s cubic-bezier(0.16,1,0.3,1) 0.6s both;
  transform-origin: top center;
}
@keyframes lineGrow { from { transform: translateY(-50%) scaleY(0); } to { transform: translateY(-50%) scaleY(1); } }
.hero-content {
  position: relative; z-index: 2;
  padding: 0 80px; max-width: 820px;
  animation: heroFade 1.2s cubic-bezier(0.16,1,0.3,1) 0.3s both;
  will-change: transform, opacity;
}
@keyframes heroFade { from { opacity: 0; transform: translateY(40px); } to { opacity: 1; transform: translateY(0); } }
.hero-eyebrow {
  font-size: 10px; font-weight: 500; letter-spacing: 0.24em; text-transform: uppercase;
  color: var(--blue-light); margin-bottom: 28px; display: flex; align-items: center; gap: 14px;
}
.hero-eyebrow::before { content: ''; display: block; width: 32px; height: 1px; background: var(--blue-light); }
.hero-h1 {
  font-family: var(--serif); font-size: clamp(48px, 6.5vw, 88px);
  font-weight: 400; color: #fff; line-height: 1.04; margin-bottom: 32px;
  letter-spacing: -0.04em;
}
.hero-h1 em { font-style: italic; color: rgba(255,255,255,0.55); }
.hero-sub { font-size: 16px; font-weight: 300; color: rgba(255,255,255,0.6); line-height: 1.8; max-width: 440px; margin-bottom: 48px; }
.hero-btns { display: flex; gap: 14px; flex-wrap: wrap; }
.hero-scroll { position: absolute; bottom: 40px; left: 80px; z-index: 2; display: flex; align-items: center; gap: 14px; }
.scroll-line { width: 56px; height: 1px; background: rgba(255,255,255,0.25); }
.scroll-label { font-size: 10px; letter-spacing: 0.24em; text-transform: uppercase; color: rgba(255,255,255,0.35); }

/* ══════════════════════════════════════════════
   MARQUEE — constant speed, not linked to scroll
   ══════════════════════════════════════════════ */
.marquee-strip {
  background: var(--blue); overflow: hidden;
  padding: 18px 0; white-space: nowrap;
}
.marquee-track {
  display: inline-flex; gap: 0;
  animation: marqueeScroll 28s linear infinite;
}
.marquee-item {
  font-family: var(--serif); font-size: 15px; font-weight: 400; color: #fff;
  letter-spacing: 0.06em; padding: 0 40px;
  display: inline-flex; align-items: center; gap: 40px;
}
.marquee-item::after { content: '◆'; font-size: 7px; opacity: 0.6; }
@keyframes marqueeScroll { 0% { transform: translateX(0); } 100% { transform: translateX(-50%); } }

/* ══════════════════════════════════════════════
   INTRO
   ══════════════════════════════════════════════ */
.intro { background: var(--white); padding: var(--band-y) var(--gutter); }
.intro-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 100px; align-items: center; max-width: 1280px; margin: 0 auto; }
/* ══════════════════════════════════════════════
   FOUNDATION FIGURES
   Was a 2x2 ruled grid: four numbers at identical weight in four identical
   boxes. That flattens the story, because the four facts are not the same
   kind of fact — 32 years is a span, the other three are counts — and it
   gives a marketing section the texture of a spreadsheet.
   One hero figure now leads and three marks support it.

   Signature: the span is drawn as a DIMENSION LINE — hairline, tick
   terminators, extent labelled at each end. That is how a builder annotates
   a measurement on a drawing, and the headline directly above it reads
   "Where craft meets precision." The device is the headline made visual.

   No bars anywhere: 12K products, 8K contractors and 6 locations share no
   unit, so any common scale would invent a comparison that does not exist.
   ══════════════════════════════════════════════ */
.foundation { margin-top: 56px; }

.foundation-hero {
  padding-top: 34px;
  border-top: 1px solid var(--border);
}
.foundation-figure {
  font-family: var(--serif);
  /* Proportional figures, not tabular: at display sizes tabular-nums pads
     every digit to the width of a 0 and a two-digit number reads loose. */
  font-variant-numeric: proportional-nums;
  font-size: clamp(66px, 17vw, 104px);
  font-weight: 400; line-height: 0.88; letter-spacing: -0.05em;
  color: var(--ink);
}
.foundation-legend {
  font-size: 10px; font-weight: 500; letter-spacing: 0.2em; text-transform: uppercase;
  color: var(--muted); margin-top: 14px;
}

/* ── The dimension line ── */
.dimension {
  position: relative;
  height: 1px; margin: 30px 0 9px;
  background: rgba(var(--blue-rgb),0.34);
  transform: scaleX(0); transform-origin: left center;
  transition: transform 1.1s cubic-bezier(0.77,0,0.18,1) 0.15s;
}
.reveal.visible .dimension,
.dimension.drawn { transform: scaleX(1); }
.dimension::before, .dimension::after {
  content: ''; position: absolute; top: -4.5px;
  width: 1px; height: 10px;
  background: rgba(var(--blue-rgb),0.55);
}
.dimension::before { left: 0; }
.dimension::after  { right: 0; }
.dimension-ends {
  display: flex; justify-content: space-between;
  font-size: 10px; font-weight: 500; letter-spacing: 0.16em;
  /* Tabular here, and only here: two values that must sit square under the
     terminators of the same line. */
  font-variant-numeric: tabular-nums;
  color: rgba(var(--blue-rgb),0.75);
}

/* ── The three supporting marks ── */
.foundation-marks {
  display: grid; grid-template-columns: repeat(3, 1fr);
  list-style: none;
  margin-top: 40px;
  border-top: 1px solid var(--border);
}
.foundation-marks li {
  position: relative;
  padding: 26px 14px 0 0;
}
/* Hairline separators between marks rather than cells with backgrounds —
   the rule divides, it does not box. */
.foundation-marks li + li {
  padding-left: 18px;
  border-left: 1px solid var(--border);
}
/* The three marks slide up in sequence once the block has arrived. Transform
   only: .foundation is itself a .reveal, and animating child opacity inside a
   fading parent multiplies the two and looks muddy. */
.foundation-marks li { transform: translateY(20px); transition: transform 0.75s cubic-bezier(0.16,1,0.3,1); }
.foundation.visible .foundation-marks li { transform: none; }
.foundation.visible .foundation-marks li:nth-child(2) { transition-delay: 0.09s; }
.foundation.visible .foundation-marks li:nth-child(3) { transition-delay: 0.18s; }

.mark-num {
  display: block;
  font-family: var(--serif);
  font-variant-numeric: proportional-nums;
  font-size: clamp(27px, 7.2vw, 36px);
  font-weight: 400; line-height: 1; letter-spacing: -0.035em;
  color: var(--ink);
}
.mark-label {
  display: block; margin-top: 9px;
  font-size: 9.5px; font-weight: 500; letter-spacing: 0.15em; text-transform: uppercase;
  color: var(--muted); line-height: 1.4;
}
/* The mark that is also a link to its section gets a quiet affordance. */
.foundation-marks a {
  text-decoration: none; color: inherit; cursor: pointer;
  display: block;
}
.foundation-marks a::after {
  content: ''; display: block; width: 0; height: 1px; margin-top: 12px;
  background: var(--blue);
  transition: width 0.55s cubic-bezier(0.16,1,0.3,1);
}
.foundation-marks a:hover::after,
.foundation-marks a:focus-visible::after { width: 26px; }
.foundation-marks a:focus-visible { outline: 2px solid var(--blue); outline-offset: 4px; }
.intro-img-wrap {
  position: relative; width: 100%; aspect-ratio: 3/4; overflow: hidden;
  background: var(--ink2);   /* nothing white can show through a gap */
}
/* Scoped under the wrap on purpose. This element is BOTH a slideshow frame
   and an .img-curtain child, and `.img-curtain img` (0,1,1) outranks a bare
   `.intro-img` (0,1,0). Its `transition` shorthand resets the whole property,
   so the opacity fade declared there was being thrown away and every switch
   was a hard cut. Raising specificity here — and restating the curtain's own
   transitions so they survive — is what actually makes this fade. */
.intro-img-wrap .intro-img {
  position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover;
  opacity: 0; z-index: 0;
  /* Linear, not ease-in-out: over an opaque underlay a crossfade blends at a
     constant rate, and easing both ends makes it visibly hesitate mid-blend. */
  transition: opacity 0.75s linear,
              clip-path 1.3s cubic-bezier(0.77,0,0.18,1),
              transform 1.8s cubic-bezier(0.16,1,0.3,1);
  will-change: opacity;
}
.intro-img-wrap .intro-img.active { opacity: 1; z-index: 2; }
/* The outgoing frame holds at full opacity UNDERNEATH while the incoming one
   fades in on top of it. Before, both frames crossfaded at once, so halfway
   through each switch both sat near 50% opacity and roughly a quarter of the
   white section background bled between them — a pale flash on every change.
   Keeping the stack opaque at all times is what removes it. */
.intro-img-wrap .intro-img.holding { opacity: 1; z-index: 1; transition: none; }

/* ══════════════════════════════════════════════
   CATEGORIES — Fixed-height mosaic
   No dead space, all cards flush, different sizes
   ══════════════════════════════════════════════ */
.cats-strip { background: var(--bg); padding: var(--band-y) var(--gutter); }
.cats-header {
  display: flex; justify-content: space-between; align-items: flex-end;
  margin-bottom: 64px; max-width: 1280px; margin-left: auto; margin-right: auto;
}
.cats-header .section-h2 { margin-bottom: 0; }

.cats-magazine {
  display: grid;
  grid-template-columns: 1.4fr 1fr 1.4fr;
  grid-template-rows: 1fr;
  gap: 2px;
  max-width: 1280px; margin: 0 auto;
  height: 640px;
  perspective: 1400px;
}

.cats-col-stacked {
  display: grid;
  grid-template-rows: minmax(0, 1fr) minmax(0, 1fr);
  gap: 2px;
  height: 100%;
  min-height: 0;
  min-width: 0;
}

.cat-card {
  position: relative; overflow: hidden; cursor: none;
  background: var(--ink2);
  height: 100%; width: 100%;
  min-height: 0; min-width: 0;
  transform-style: preserve-3d;
  will-change: transform;
  transition: box-shadow 0.5s cubic-bezier(0.16,1,0.3,1);
}
.cat-card:hover { box-shadow: 0 32px 64px -20px rgba(0,0,0,0.55); z-index: 2; }

.cat-card img {
  position: absolute; inset: 0;
  width: 100%; height: 100%; object-fit: cover;
  transition: transform 0.95s cubic-bezier(0.16,1,0.3,1), filter 0.5s ease;
  filter: brightness(0.6) saturate(0.85);
  will-change: transform, filter;
}
.cat-card:hover img { transform: scale(1.07); filter: brightness(0.42) saturate(0.7); }

.cat-card-overlay {
  position: absolute; inset: 0;
  background: linear-gradient(to top, rgba(0,0,0,0.78) 0%, rgba(0,0,0,0) 50%);
  transition: background 0.45s ease;
}
.cat-card:hover .cat-card-overlay {
  background: linear-gradient(to top, rgba(0,0,0,0.88) 0%, rgba(0,0,0,0.18) 70%);
}

/* Content floats on Z-axis above tilting image */
.cat-info {
  position: absolute; bottom: 0; left: 0; right: 0; padding: 32px 28px;
  transform: translateZ(40px);
  transition: transform 0.4s cubic-bezier(0.16,1,0.3,1);
}
.cat-card:hover .cat-info { transform: translateZ(40px) translateY(-6px); }
.cat-name { font-family: var(--serif); font-size: clamp(18px, 2vw, 26px); color: #fff; font-weight: 400; margin-bottom: 6px; letter-spacing: -0.01em; }
.cat-count { font-size: 10px; color: rgba(255,255,255,0.5); letter-spacing: 0.14em; text-transform: uppercase; }
.cat-arrow {
  position: absolute; top: 24px; right: 24px; width: 38px; height: 38px;
  border: 1px solid rgba(255,255,255,0.3); border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  opacity: 0; transform: translateZ(40px) scale(0.8);
  transition: all 0.35s cubic-bezier(0.16,1,0.3,1);
  background: rgba(var(--blue-light-rgb),0.16);
}
.cat-arrow svg { width: 14px; height: 14px; stroke: var(--blue-light); fill: none; }
.cat-card:hover .cat-arrow { opacity: 1; transform: translateZ(40px) scale(1); border-color: var(--blue-light); }
.cat-label {
  position: absolute; top: 24px; left: 24px;
  font-size: 10px; letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--blue-light); background: rgba(0,0,0,0.5); padding: 5px 12px; border-radius: 100px;
  backdrop-filter: blur(8px); transform: translateZ(40px);
}

/* ══════════════════════════════════════════════
   FEATURE SPLIT
   ══════════════════════════════════════════════ */
.feature-split { background: var(--white); }
.feature-split-inner { display: grid; grid-template-columns: 1fr 1fr; max-width: 1280px; margin: 0 auto; gap: 100px; align-items: center; }
.feature-img { width: 100%; aspect-ratio: 1; object-fit: cover; }
.feature-list { display: flex; flex-direction: column; gap: 0; margin-top: 44px; }
.feature-item { display: flex; gap: 24px; padding: 22px 0; border-bottom: 1px solid var(--border); align-items: flex-start; }
.feature-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--blue); flex-shrink: 0; margin-top: 6px; }
.feature-text { font-size: 15px; color: var(--muted); line-height: 1.65; }

/* ══════════════════════════════════════════════
   BRANDS MINI
   ══════════════════════════════════════════════ */
.brands-mini { background: var(--ink); padding: clamp(56px, 8vw, 80px) var(--gutter); }
.brands-mini-inner { max-width: 1280px; margin: 0 auto; }
.brands-mini .section-eyebrow { color: rgba(var(--blue-light-rgb),0.75); }
.brands-mini .section-h2 { color: #fff; }
.brands-row {
  display: flex; justify-content: space-between; align-items: center;
  margin-top: 56px; flex-wrap: wrap; gap: 32px 48px;
  padding-top: 44px; border-top: 1px solid rgba(255,255,255,0.06);
}
.brand-logo {
  font-family: var(--serif); font-size: 20px; font-weight: 400;
  color: rgba(255,255,255,0.25); letter-spacing: 0.04em;
  transition: color 0.4s, transform 0.4s cubic-bezier(0.16,1,0.3,1);
  cursor: none;
}
.brand-logo:hover { color: rgba(255,255,255,0.88); transform: translateY(-3px); }

/* ══════════════════════════════════════════════
   ABOUT
   ══════════════════════════════════════════════ */
.about-hero { position: relative; width: 100%; height: 75vh; overflow: hidden; }
.about-hero img { width: 100%; height: 100%; object-fit: cover; filter: brightness(0.5) saturate(0.8); }
.about-hero-content { position: absolute; inset: 0; display: flex; align-items: flex-end; padding: clamp(40px, 7vw, 80px) var(--gutter); }
.about-hero-content .section-h2 { color: #fff; font-size: clamp(40px, 6vw, 76px); max-width: 700px; }
.about-body { background: var(--white); }
.about-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 100px; max-width: 1280px; margin: 0 auto; align-items: start; }
.timeline { display: flex; flex-direction: column; gap: 0; margin-top: 48px; }
.tl-item { display: grid; grid-template-columns: 72px 1fr; gap: 20px; padding: 24px 0; border-bottom: 1px solid var(--border); }
.tl-year { font-size: 12px; font-weight: 500; color: var(--blue); letter-spacing: 0.06em; padding-top: 2px; }
.tl-desc { font-size: 14px; color: var(--muted); line-height: 1.7; }
.values-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 1px; background: var(--border); margin-top: 44px; }
.value-card { background: var(--white); padding: 36px; transition: background 0.3s; }
.value-card:hover { background: var(--bg); }
.value-title { font-size: 15px; font-weight: 500; margin-bottom: 10px; color: var(--ink); }
.value-desc { font-size: 14px; color: var(--muted); line-height: 1.7; }

/* ══════════════════════════════════════════════
   CATEGORIES PAGE
   ══════════════════════════════════════════════ */
.cats-page-hero { background: var(--ink); padding: var(--band-y-hero) var(--gutter) clamp(56px, 8vw, 80px); }
.cats-page-hero .section-h2 { color: #fff; font-size: clamp(40px, 5vw, 68px); max-width: 680px; }
.cats-full { background: var(--bg); }
.cat-full-item { display: grid; grid-template-columns: 1fr 1fr; gap: 0; }
.cat-full-item:nth-child(even) .cat-full-img { order: 1; }
.cat-full-item:nth-child(even) .cat-full-text { order: 0; }
.cat-full-img { aspect-ratio: 4/3; overflow: hidden; }
.cat-full-img img { width: 100%; height: 100%; object-fit: cover; transition: transform 0.95s cubic-bezier(0.16,1,0.3,1); filter: saturate(0.9); }
.cat-full-item:hover .cat-full-img img { transform: scale(1.045); }
.cat-full-text { padding: clamp(44px, 7vw, 80px) var(--gutter); display: flex; flex-direction: column; justify-content: center; background: var(--white); }
.cat-full-item:nth-child(even) .cat-full-text { background: var(--bg); }
.cat-tag {
  display: inline-block; font-size: 10px; letter-spacing: 0.18em; text-transform: uppercase;
  color: var(--blue); border: 1px solid rgba(var(--blue-rgb),0.4); padding: 6px 16px;
  border-radius: 100px; margin-bottom: 28px; width: fit-content;
}
.cat-full-h3 { font-family: var(--serif); font-size: clamp(28px, 3vw, 44px); font-weight: 400; margin-bottom: 20px; letter-spacing: -0.02em; }
.cat-full-p { font-size: 15px; color: var(--muted); line-height: 1.85; }

/* ══════════════════════════════════════════════
   SERVICES
   ══════════════════════════════════════════════ */
.services-list { background: var(--white); }
.service-row {
  display: grid; grid-template-columns: 72px 1fr 1fr; gap: 0;
  padding: clamp(36px, 5vw, 64px) var(--gutter); border-bottom: 1px solid var(--border);
  align-items: start; max-width: 1440px; margin: 0 auto;
  transition: background 0.35s, padding-left 0.35s;
  cursor: none;
}
.service-row:hover { background: var(--bg); padding-left: 100px; }
.svc-num { font-size: 11px; color: rgba(var(--blue-rgb),0.6); letter-spacing: 0.1em; padding-top: 8px; font-weight: 500; }
.svc-name { font-family: var(--serif); font-size: clamp(22px, 2.5vw, 38px); font-weight: 400; letter-spacing: -0.02em; }
.svc-desc { font-size: 15px; color: var(--muted); line-height: 1.75; padding-top: 8px; }

/* ══════════════════════════════════════════════
   BRANDS PAGE
   ══════════════════════════════════════════════ */
.brands-featured { display: grid; grid-template-columns: repeat(3, 1fr); gap: 2px; background: var(--border); border: 1px solid var(--border); }
.brand-cell {
  background: var(--white); padding: clamp(24px, 4vw, 56px) clamp(18px, 3vw, 40px);
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 12px; cursor: none; transition: background 0.3s;
  aspect-ratio: 16 / 11; min-height: 150px; overflow: hidden; text-align: center;
}
.brand-cell:hover { background: var(--bg); }
.brand-cell-name { font-family: var(--serif); font-size: clamp(20px, 4.4vw, 28px); font-weight: 400; color: var(--ink); line-height: 1.15; }
.brand-cell-tag { font-size: clamp(9.5px, 2.4vw, 11px); color: var(--muted); letter-spacing: 0.1em; text-transform: uppercase; line-height: 1.5; }
.brand-cell-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--blue); flex-shrink: 0; }

/* Logo tiles — contain, never crop. `cover` was slicing the ends off
   wordmarks like Makita; one tile also used contain, so the wall read
   as four different treatments. One rule now covers all of them. */
.brand-cell.is-logo { padding: clamp(18px, 4vw, 34px); }
.brand-logo-img {
  width: 100%; height: 100%;
  object-fit: contain; object-position: center;
  transition: transform 0.5s cubic-bezier(0.16,1,0.3,1);
}
.brand-cell.is-logo:hover .brand-logo-img { transform: scale(1.04); }

.brands-all { display: grid; grid-template-columns: repeat(4, 1fr); gap: 1px; background: var(--border); margin-top: 2px; }
.brand-all-cell {
  background: var(--white); padding: 36px 28px;
  font-family: var(--serif); font-size: 20px; font-weight: 400; color: var(--muted);
  cursor: none; transition: all 0.3s;
}
.brand-all-cell:hover { color: var(--ink); background: var(--bg); }

/* ══════════════════════════════════════════════
   CONTACT
   ══════════════════════════════════════════════ */
.contact-body { background: var(--white); }
.contact-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 0; }
.contact-form-side { padding: clamp(44px, 7vw, 88px) var(--gutter); }
.contact-info-side { padding: clamp(44px, 7vw, 88px) var(--gutter); background: var(--ink); }
.form-group { margin-bottom: 32px; }
.form-label { display: block; font-size: 10px; letter-spacing: 0.14em; text-transform: uppercase; color: var(--blue); margin-bottom: 12px; }
.form-input, .form-textarea {
  width: 100%; padding: 14px 0;
  border: none; border-bottom: 1px solid var(--border);
  background: transparent; font-family: var(--sans); font-size: 15px; color: var(--ink);
  transition: border-color 0.3s; outline: none; resize: none; cursor: text;
}
.form-input::placeholder, .form-textarea::placeholder { color: rgba(95,112,131,0.55); }
.form-input:focus, .form-textarea:focus { border-bottom-color: var(--blue); }
.form-textarea { height: 120px; }
.form-submit {
  display: inline-flex; align-items: center; gap: 10px;
  font-size: 11px; font-weight: 500; letter-spacing: 0.14em; text-transform: uppercase;
  padding: 16px 40px; background: var(--blue); color: #fff; border: none;
  border-radius: 100px; cursor: none;
  transition: background 0.3s, box-shadow 0.3s; margin-top: 16px;
  will-change: transform;
}
.form-submit:hover { background: var(--blue-h); box-shadow: 0 8px 28px rgba(var(--blue-rgb),0.35); }
.info-item { margin-bottom: 44px; }
.info-label { font-size: 10px; letter-spacing: 0.16em; text-transform: uppercase; color: rgba(var(--blue-light-rgb),0.75); margin-bottom: 12px; }
.info-val { font-size: 15px; color: rgba(255,255,255,0.75); line-height: 1.65; }
.info-val a { color: inherit; text-decoration: none; transition: color 0.3s; }
.info-val a:hover { color: var(--blue-light); }
.hours-grid { display: flex; flex-direction: column; gap: 8px; margin-top: 10px; }
.hours-row { display: flex; justify-content: space-between; font-size: 14px; color: rgba(255,255,255,0.5); padding-bottom: 10px; border-bottom: 1px solid rgba(255,255,255,0.07); }

/* ══════════════════════════════════════════════
   FOOTER
   ══════════════════════════════════════════════ */
footer { background: var(--ink); padding: clamp(56px, 8vw, 88px) var(--gutter) clamp(40px, 6vw, 64px); }
.footer-inner { max-width: 1280px; margin: 0 auto; }
.footer-top { display: grid; grid-template-columns: 2fr 1fr 1fr 1fr; gap: 60px; padding-bottom: 60px; border-bottom: 1px solid rgba(255,255,255,0.06); }
.footer-brand { font-family: var(--serif); font-size: 22px; color: rgba(255,255,255,0.8); font-weight: 400; margin-bottom: 16px; letter-spacing: 0.02em; }
.footer-brand em { font-style: italic; color: var(--blue-light); }
.footer-tagline { font-size: 14px; color: rgba(255,255,255,0.25); line-height: 1.8; max-width: 280px; }
.footer-col h4 { font-size: 10px; letter-spacing: 0.18em; text-transform: uppercase; color: rgba(255,255,255,0.2); margin-bottom: 24px; }
.footer-col a { display: block; font-size: 14px; color: rgba(255,255,255,0.45); text-decoration: none; margin-bottom: 14px; cursor: pointer; transition: color 0.3s; }
.footer-col a:hover { color: rgba(255,255,255,0.9); }
.footer-bottom { display: flex; justify-content: space-between; align-items: center; padding-top: 36px; }
.footer-copy { font-size: 12px; color: rgba(255,255,255,0.18); letter-spacing: 0.04em; }
.footer-copy em { font-style: italic; color: var(--blue-light); opacity: 0.65; }
.footer-accent-line,
.footer-gold-line { width: 100%; height: 1px; background: linear-gradient(to right, transparent, var(--blue-light), transparent); opacity: 0.26; margin-bottom: 48px; }

/* ══════════════════════════════════════════════
   NATIVE CSS SCROLL-DRIVEN DEPTH (modern browsers)
   ══════════════════════════════════════════════ */
@supports (animation-timeline: view()) {
  .depth-far {
    animation: depthFar linear both;
    animation-timeline: view();
    animation-range: entry 0% exit 100%;
  }
  .depth-near {
    animation: depthNear linear both;
    animation-timeline: view();
    animation-range: entry 0% exit 100%;
  }
  @keyframes depthFar  { from { transform: translateY(70px) scale(0.97); } to { transform: translateY(-70px) scale(1.01); } }
  @keyframes depthNear { from { transform: translateY(110px); } to { transform: translateY(-110px); } }
}

/* ══════════════════════════════════════════════
   RESPONSIVE
   ══════════════════════════════════════════════ */
@media (max-width: 1300px) {
  #nav { padding: 0 36px; }
  #nav.scrolled { padding: 12px 36px; }
  .nav-links { gap: 28px; }
  .nav-links a { font-size: 11.5px; }
}
@media (max-width: 1150px) {
  #nav { padding: 0 24px; }
  #nav.scrolled { padding: 12px 24px; }
  .nav-links { gap: 22px; }
  .nav-cta { padding: 9px 20px; }
}
@media (max-width: 1024px) {
  .nav-links { display: none; }
  .nav-cta { display: none; }
  .nav-menu-btn { display: flex; }
}
@media (max-width: 900px) {
  #nav { padding: 0 24px; }
  #nav.scrolled { padding: 12px 24px; }
  .hero-content { padding: 0 var(--gutter); }
  .hero-scroll { left: var(--gutter); }
  .hero-line { left: var(--gutter); }
  .intro-grid, .about-grid, .contact-grid, .feature-split-inner, .split-2 { grid-template-columns: 1fr; }

  /* Fallback for engines without overflow-x:clip. A horizontal slide here
     would park the element outside the viewport with only body{overflow-x}
     masking it — the nav-drawer trap — so these move vertically instead.
     The @supports block further down overrides this wherever the browser can
     actually contain the motion. */
  .reveal-left, .reveal-right { transform: translateY(34px); }
  .reveal-left.visible, .reveal-right.visible { transform: translateY(0); }

  /* One column means each item is read on its own, so the beats are spaced
     further apart than on desktop — the sequence is the point. */
  .stagger > *:nth-child(2)  { --d: 95ms; }
  .stagger > *:nth-child(3)  { --d: 190ms; }
  .stagger > *:nth-child(4)  { --d: 285ms; }
  .stagger > *:nth-child(5)  { --d: 380ms; }
  .stagger > *:nth-child(6)  { --d: 475ms; }
  .reveal { transform: translateY(58px) scale(0.97); }
  .reveal-scale { transform: scale(0.84); }
  .cats-magazine { grid-template-columns: 1fr 1fr; height: auto; }
  .cats-col-stacked { grid-template-rows: 1fr 1fr; height: auto; }
  .cat-card { min-height: 260px; }
  .cat-full-item { grid-template-columns: 1fr; }
  .cat-full-item:nth-child(even) .cat-full-img { order: 0; }
  .cat-full-item:nth-child(even) .cat-full-text { order: 1; }
  .service-row { grid-template-columns: 48px 1fr; row-gap: 16px; padding: 44px var(--gutter); }
  .service-row:hover { padding-left: var(--gutter); }
  .svc-desc { grid-column: 2; }
  .brands-featured { grid-template-columns: 1fr 1fr; }
  .brands-all { grid-template-columns: repeat(3, 1fr); }
  .footer-top { grid-template-columns: 1fr 1fr; gap: 40px; }
  .contact-form-side, .contact-info-side { padding: 56px var(--gutter); }
  .cat-full-text { padding: 56px var(--gutter); }
  footer { padding: 64px var(--gutter) 48px; }
  .brands-mini { padding: 64px var(--gutter); }
  .cats-strip { padding: 80px var(--gutter); }
}
@media (max-width: 600px) {
  .nav-links { display: none; }
  .nav-cta { display: none; }
  .nav-menu-btn { display: flex; }

  /* Keep the wordmark whole — at 375px the scrolled pill was clipping it */
  .nav-logo { font-size: 18px; letter-spacing: 0.01em; white-space: nowrap; }
  #nav.scrolled { padding: 10px 14px; }
  #nav.scrolled .nav-inner { padding: 12px 18px; border-radius: 14px; }

  /* The desktop overlay fades left→right because copy sits in the left
     column. On a phone the copy is full-bleed, so the pale right end left
     white text sitting on bright sky. Vertical scrim instead. */
  .hero-overlay {
    background: linear-gradient(180deg, rgba(0,0,0,0.78) 0%, rgba(0,0,0,0.5) 42%, rgba(0,0,0,0.72) 100%);
  }
  .hero { min-height: 560px; }
  .hero-h1 { font-size: clamp(38px, 9vw, 56px); margin-bottom: 24px; }
  .hero-eyebrow { margin-bottom: 20px; font-size: 9.5px; letter-spacing: 0.18em; }
  .hero-sub { font-size: 15px; max-width: none; margin-bottom: 32px; }
  .hero-btns { flex-direction: column; align-items: stretch; gap: 10px; }
  .hero-btns button { width: 100%; text-align: center; justify-content: center; padding: 17px 28px; }
  .hero-scroll { bottom: 28px; }
  .hero-word { display: none; }

  /* TEXT MEASURE — headings and body were inheriting desktop max-widths
     and centring margins inside a narrow column, which read as broken
     alignment. On phones text runs the full gutter-to-gutter measure. */
  .section-h2 { font-size: clamp(30px, 8.2vw, 42px); letter-spacing: -0.02em; }
  .section-body, .band-lede, .cat-full-p, .svc-desc, .feature-text {
    max-width: none; font-size: 15px; line-height: 1.75;
  }
  .band-center .section-h2,
  .band-center .band-lede { max-width: 100%; margin-left: 0; margin-right: 0; }
  .band-center .band-lede { margin-bottom: 36px; }
  .divider { margin-bottom: 28px; }

  /* The grid clips, so a card can travel well outside its own column without
     ever reaching the viewport edge. That is what lets this go BIGGER on a
     phone than on desktop rather than smaller: the entrance becomes a masked
     slide from behind the edge, with a tilt and an overshoot that would be
     reckless if the box could actually escape. */
  .cats-magazine { grid-template-columns: 1fr; gap: 2px; height: auto; overflow: hidden; }
  .cats-col-stacked { grid-template-rows: auto auto; gap: 2px; }
  .cat-card.pop {
    transform: translateX(var(--from, -110px)) scale(0.86) rotate(var(--tilt, -3deg));
    transition: opacity 0.7s cubic-bezier(0.16,1,0.3,1),
                transform 1.05s cubic-bezier(0.34,1.32,0.52,1),
                box-shadow 0.5s ease;
    transition-delay: calc(var(--pop, 0) * 145ms), calc(var(--pop, 0) * 145ms), 0s;
  }
  .cat-card.pop.visible { transform: translateX(0) scale(1) rotate(0deg); }
  .pop-l { --from: -112px; --tilt: -3.5deg; }
  .pop-r { --from:  112px; --tilt:  3.5deg; }
  .pop .cat-name, .pop .cat-count { transform: translateY(22px); }
  .pop .cat-name  { transition-delay: calc(var(--pop, 0) * 145ms + 430ms); }
  .pop .cat-count { transition-delay: calc(var(--pop, 0) * 145ms + 510ms); }
  .cat-card { min-height: 240px; }
  .cats-header { flex-direction: column; align-items: flex-start; gap: 24px; margin-bottom: 40px; }
  .cats-header .btn-dark { width: 100%; justify-content: center; }
  /* Card copy sits closer to the edge when the card is full-width */
  .cat-info { padding: 26px 22px; }
  .cat-name { font-size: 22px; }

  /* ── BRANDS PAGE, PHONE ──────────────────────
     Was 1 column: every logo became a 240px-tall band and the
     list ran ~1400px of scroll. Two even columns keeps the wall
     legible, halves the scroll, and gives logos a sane tile. */
  .brands-featured { grid-template-columns: 1fr 1fr; }
  .brand-cell { aspect-ratio: 1 / 1; min-height: 0; padding: 20px 14px; gap: 8px; }
  .brand-cell.is-logo { padding: 16px; }
  .brand-cell-name { font-size: 19px; }
  .brand-cell-tag { font-size: 9.5px; letter-spacing: 0.08em; }
  .brands-all { grid-template-columns: repeat(3, 1fr); }
  .brand-all-cell {
    padding: 20px 8px; font-size: 16px; text-align: center;
    display: flex; align-items: center; justify-content: center; min-height: 64px;
  }
  .brands-row { gap: 24px 32px; justify-content: flex-start; }

  .values-grid { grid-template-columns: 1fr; }
  .cat-full-text { padding: 44px var(--gutter); }
  .cat-full-h3 { font-size: 28px; }
  .service-row { grid-template-columns: 1fr; padding: 36px var(--gutter); }
  .svc-desc { grid-column: 1; }
  .svc-num { padding-top: 0; }
  .contact-form-side, .contact-info-side { padding: 44px var(--gutter); }
  /* 16px keeps iOS from auto-zooming the whole page on focus, and the
     taller padding gets each field over the 44px touch-target floor. */
  .form-input, .form-textarea { font-size: 16px; padding: 15px 0; }
  .form-submit { width: 100%; justify-content: center; padding: 18px 32px; }
  .hours-row { font-size: 13.5px; gap: 12px; }

  .footer-top { grid-template-columns: 1fr; gap: 36px; }
  footer { padding: 56px var(--gutter) 40px; }
  .footer-bottom { flex-direction: column; align-items: flex-start; gap: 8px; }
  .nav-mobile-panel { max-width: 100%; padding: 96px 28px 32px; }
  .nav-mobile-links a { font-size: 26px; }
  .hero-line { display: none; }
  .about-hero-content { padding: 48px var(--gutter); }
  .cats-page-hero { padding: 140px var(--gutter) 60px; }
  .brands-mini { padding: 64px var(--gutter); }
}

/* The magazine cards tilt in 3D on pointer move. Touch devices never
   fire that, and preserve-3d + translateZ layers are a known source of
   paint glitches on mobile GPUs — so flatten them where hover is absent. */
@media (hover: none), (max-width: 900px) {
  .cats-magazine { perspective: none; }
  /* No `transform: none !important` here any more — it was overriding the
     cards' own entrance animation, so on a phone they had no motion at all.
     initTilt() now refuses to attach below this width, so nothing writes an
     inline transform that would need overriding. */
  .cat-card { transform-style: flat; }
  .cat-info, .cat-label { transform: none; }
  .cat-card:hover .cat-info { transform: none; }
  .cat-arrow { transform: scale(0.8); }
  .cat-card:hover .cat-arrow { transform: scale(1); }
}

/* ── SMALL PHONES (≤400px) ── */
@media (max-width: 400px) {
  .brands-all { grid-template-columns: 1fr 1fr; }
  .brand-all-cell { font-size: 17px; }
  .foundation-marks li { padding-right: 8px; }
  .foundation-marks li + li { padding-left: 12px; }
  .mark-label { font-size: 8.8px; letter-spacing: 0.1em; }
}

/* ══════════════════════════════════════════════
   RECLAIMING THE REVEAL TRANSITIONS
   Several components declare their own `transition` shorthand further down
   this sheet at the same specificity as .reveal (0,1,0). On source order
   they win, and a shorthand resets the WHOLE property — so those elements
   were sitting at opacity 0 and then snapping to visible with no animation.
   Some of this predates the current work: the CTA buttons and the brand row
   have never actually animated in.

   Group A — transform is safe here, so the reveal transition is re-asserted
   one class higher with each component's own animated properties folded in.
   ══════════════════════════════════════════════ */
.value-card.reveal,
.brand-cell.reveal-scale,
.brand-all-cell.reveal,
.service-row.reveal {
  transition:
    opacity   0.85s cubic-bezier(0.16,1,0.3,1) var(--d, 0ms),
    transform 0.9s  cubic-bezier(0.16,1,0.3,1) var(--d, 0ms),
    background   0.35s ease,
    color        0.3s  ease,
    padding-left 0.35s cubic-bezier(0.16,1,0.3,1);
}

/* Group B — transform is NOT safe. initMagnetic() writes style.transform
   inline on the buttons, and an inline style outranks every rule here, so a
   transform-based entrance would be cancelled the moment the cursor moved
   over one. .brand-logo likewise needs its own 0.4s hover lift to stay
   snappy rather than inheriting a 0.9s entrance duration.
   A keyframe animation cannot be reset by a `transition` shorthand at all,
   which is what makes it the right tool for these two. */
@keyframes revealFade { from { opacity: 0; } to { opacity: 1; } }
.btn-primary.reveal,
.btn-dark.reveal,
.brand-logo.reveal { opacity: 0; transform: none; }
.btn-primary.reveal.visible,
.btn-dark.reveal.visible,
.brand-logo.reveal.visible {
  animation: revealFade 0.7s cubic-bezier(0.16,1,0.3,1) var(--d, 0ms) both;
}

/* ══════════════════════════════════════════════
   MOBILE — HORIZONTAL MOTION, CONTAINED
   Sideways entrances were dropped on phones because the element would sit
   outside the viewport while it travelled, with only body{overflow-x:hidden}
   masking it — which iOS Safari does not reliably honour.
   Where the browser supports overflow-x:clip the parent can contain the
   motion for real, so the horizontal slide comes back and goes FURTHER than
   desktop: the clip turns it into a masked slide from behind the edge.

   clip, not hidden: `overflow-x: hidden` forces the computed overflow-y to
   auto, which would make every one of these a scroll container and trap the
   page's scrolling. `clip` leaves the other axis visible, so the
   scroll-driven .depth-far / .depth-near drift still shows.
   ══════════════════════════════════════════════ */
@supports (overflow-x: clip) {
  /* At EVERY width, not just mobile. These grids are full-bleed, so a
     half sliding in from ±56px hangs outside the viewport while it travels —
     on contact.html at 1280 the two panels measured L-56 and R1321. Clipping
     the container contains it for real at any size.
     clip, not hidden: hidden would force overflow-y to auto and turn each of
     these into a scroll container, which would also cut off the
     scroll-driven .depth-far drift. */
  .intro-grid, .about-grid, .contact-grid, .feature-split-inner,
  .split-2, .cat-full-item { overflow-x: clip; }

  @media (max-width: 900px) {
    .reveal-left  { transform: translateX(-78px) scale(0.95); }
    .reveal-right { transform: translateX(78px)  scale(0.95); }
    .reveal-left.visible,
    .reveal-right.visible { transform: translateX(0) scale(1); }
    .reveal-left, .reveal-right {
      transition: opacity 0.8s cubic-bezier(0.16,1,0.3,1) var(--d, 0ms),
                  transform 1s cubic-bezier(0.34,1.28,0.54,1) var(--d, 0ms);
    }
  }
}

/* ══════════════════════════════════════════════
   KEYBOARD ACCESS
   The category cards and brand marks were clickable <div>s, and every nav,
   footer and logo link was an <a> with no href — an anchor without one is
   not in the tab order, so the entire navigation was unreachable by keyboard.
   They are real links now; these rules restore the block behaviour the divs
   had and give every one of them a visible focus ring. The site hides the
   system cursor, which makes a visible focus state more important here than
   usual, not less.
   ══════════════════════════════════════════════ */
a.cat-card { display: block; text-decoration: none; color: inherit; }
a.brand-logo { text-decoration: none; }

a.cat-card:focus-visible,
a.brand-logo:focus-visible,
.nav-links a:focus-visible,
.nav-mobile-links a:focus-visible,
.footer-col a:focus-visible,
.nav-logo:focus-visible,
.foundation-marks a:focus-visible,
.info-val a:focus-visible,
.nav-mobile-foot a:focus-visible {
  outline: 2px solid var(--blue);
  outline-offset: 3px;
  border-radius: 2px;
}
/* On the dark surfaces the ink-blue ring has too little contrast to read. */
.nav-mobile-links a:focus-visible,
.nav-mobile-foot a:focus-visible,
.footer-col a:focus-visible,
.info-val a:focus-visible,
#nav.transparent .nav-links a:focus-visible,
#nav.transparent .nav-logo:focus-visible,
a.cat-card:focus-visible { outline-color: var(--blue-light); }

/* Skip link — keyboard users should not have to tab the whole nav on
   every page before reaching the content. */
.skip-link {
  position: absolute; left: 8px; top: -60px; z-index: 200;
  background: var(--ink); color: #fff;
  font-size: 12px; letter-spacing: 0.08em; text-transform: uppercase;
  padding: 12px 20px; border-radius: 0 0 8px 8px; text-decoration: none;
  transition: top 0.25s cubic-bezier(0.16,1,0.3,1);
}
.skip-link:focus { top: 0; outline: 2px solid var(--blue-light); outline-offset: 2px; }

/* ══════════════════════════════════════════════
   REDUCED MOTION — kill everything
   ══════════════════════════════════════════════ */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition: none !important; }
  * { cursor: auto !important; }
  .cursor-dot, .cursor-ring { display: none !important; }
  .reveal, .reveal-left, .reveal-right, .reveal-scale, .pop { opacity: 1; transform: none; }
  /* Group B is animation-driven and its opacity:0 out-ranks the line above,
     so it must be neutralised at matching specificity or these stay invisible. */
  .btn-primary.reveal, .btn-dark.reveal, .brand-logo.reveal { opacity: 1; }
  /* .pop is scoped to .cat-card.pop so it can outrank .cat-card's own
     transition, so the reset needs that same reach or the six cards stay dark. */
  .cat-card.pop { opacity: 1; transform: none; }
  .pop .cat-name, .pop .cat-count { transform: none; }
  .foundation-marks li { transform: none; }
  .pop .cat-name, .pop .cat-count { opacity: 1; transform: none; }
  .split-line > span { transform: none; }
  .img-curtain img { clip-path: none; transform: none; }
  .seam { transform: none; opacity: 0.22; }
  .marquee-track { animation: none; }
  .hero-bg { animation: none; }
}
/* ══════════════════════════════════════════════
   WHATSAPP FLOAT — hidden over the hero, rises in once
   the hero has scrolled away (see initWhatsApp in main.js)
   ══════════════════════════════════════════════ */
.wa-float {
  position: fixed; z-index: 150;
  right: clamp(16px, 4vw, 34px);
  bottom: clamp(16px, 4vw, 34px);
  width: 56px; height: 56px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: #25D366; color: #fff;
  box-shadow: 0 10px 30px rgba(7,25,40,0.28);
  text-decoration: none;
  /* Parked out of reach until .visible lands, so it can't be tabbed to or
     clicked while it is invisible over the hero. */
  opacity: 0; visibility: hidden; pointer-events: none;
  transform: translateY(18px) scale(0.85);
  transition: opacity 0.45s cubic-bezier(0.16,1,0.3,1),
              transform 0.45s cubic-bezier(0.16,1,0.3,1),
              visibility 0s linear 0.45s,
              box-shadow 0.3s, background 0.3s;
}
.wa-float.visible {
  opacity: 1; visibility: visible; pointer-events: auto;
  transform: translateY(0) scale(1);
  transition-delay: 0s;
}
.wa-float:hover { background: #1FB955; box-shadow: 0 14px 38px rgba(37,211,102,0.42); }
.wa-float:focus-visible { outline: 2px solid var(--blue-light); outline-offset: 4px; }
.wa-float svg { width: 28px; height: 28px; fill: currentColor; }

/* The drawer covers the page, so the bubble steps out of its way. */
body.wa-hide .wa-float { opacity: 0; pointer-events: none; transform: translateY(18px) scale(0.85); }

@media (max-width: 600px) { .wa-float { width: 52px; height: 52px; } .wa-float svg { width: 26px; height: 26px; } }

@media (prefers-reduced-motion: reduce) {
  .wa-float { transform: none; }
  .wa-float.visible { transform: none; }
}
