/* ==========================================================
   Sri Sai Mosquito Solutions
   ========================================================== */

:root {
  /* Palette sampled directly from the logo artwork:
     #01274d navy (SRI wordmark, dark swoosh) · #018bc8 azure ·
     #03bdf0 cyan (waves, SAI wordmark). */
  --brand:      #016699;   /* primary actions, links */
  --brand-600:  #01527d;   /* hover */
  --brand-700:  #01274d;   /* logo navy — dark bands, headings */
  --brand-500:  #018bc8;   /* logo azure — icons, decorative */
  --brand-300:  #6ecff5;
  --brand-100:  #bfe4f6;
  --brand-50:   #eaf5fc;

  /* The logo carries no warm colour, so the loud CTA is the logo cyan with a
     navy label — 7.4:1 contrast, where white on cyan would only reach 2.6:1. */
  --accent:     #03bdf0;
  --accent-600: #02a3d1;
  --accent-ink: #01274d;

  --ink:        #071a2e;
  --ink-2:      #33475c;
  --muted:      #64798c;

  --line:       #dbe6ef;
  --surface:    #ffffff;
  --surface-2:  #f4f8fb;
  --surface-3:  #e8f1f8;

  --footer-bg:  #041526;

  --wa:         #25d366;

  /* Gold accent. Used only on the two dark heroes (home + dealer) and the
     primary CTA that sits on them — declared here rather than scoped to
     .dealer-hero so .btn--gold works on both. */
  --gold:       #d8a83a;
  --gold-hi:    #ecc464;
  --gold-ink:   #2a1c00;   /* 8.1:1 on the gold; white would be 2.1:1 */
  --danger:     #c0392b;
  --success:    #016699;

  /* Sharp edges throughout — no rounding on buttons, cards, inputs or pills.
     The three tokens are kept (rather than deleted) so the whole site's corner
     treatment stays a one-line change if it is ever revisited. */
  --radius:     0;
  --radius-lg:  0;
  --radius-sm:  0;

  --shadow-sm:  0 1px 2px rgba(4,21,38,.06), 0 1px 3px rgba(4,21,38,.05);
  --shadow:     0 4px 14px rgba(4,21,38,.07), 0 1px 3px rgba(4,21,38,.05);
  --shadow-lg:  0 18px 44px rgba(4,21,38,.12), 0 4px 12px rgba(4,21,38,.06);

  --container:  1180px;
  --header-h:   78px;

  --font: "Plus Jakarta Sans", -apple-system, BlinkMacSystemFont, "Segoe UI",
          Roboto, "Helvetica Neue", Arial, sans-serif;
}

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

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  /* so an #enquiry jump does not land under the sticky header */
  scroll-padding-top: calc(var(--header-total, 118px) + 16px);
}

body {
  margin: 0;
  font-family: var(--font);
  font-size: 16.5px;
  line-height: 1.65;
  color: var(--ink-2);
  background: var(--surface);
  -webkit-font-smoothing: antialiased;
}

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

a { color: var(--brand-600); text-decoration: none; }
a:hover { color: var(--brand-700); }

h1, h2, h3, h4 {
  margin: 0 0 .5em;
  color: var(--ink);
  font-weight: 800;
  line-height: 1.18;
  letter-spacing: -.021em;
}
h1 { font-size: clamp(2.05rem, 4.6vw, 3.35rem); }
h2 { font-size: clamp(1.6rem, 3.2vw, 2.4rem); }
h3 { font-size: clamp(1.12rem, 1.7vw, 1.32rem); }
h4 { font-size: 1.02rem; font-weight: 700; }
p  { margin: 0 0 1rem; }

ul, ol { margin: 0 0 1rem; padding-left: 1.15rem; }

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

/* ---------- layout ---------- */

.container {
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: 20px;
}

.section        { padding: clamp(38px, 4.4vw, 64px) 0; }
.section--tight { padding: clamp(26px, 3vw, 40px) 0; }
.section--alt   { background: var(--surface-2); }
.section--brand { background: var(--brand-700); color: #c6dcee; }
.section--brand h2, .section--brand h3 { color: #fff; }

.section-head { max-width: 660px; margin-bottom: clamp(22px, 2.8vw, 34px); }
.section-head--center { margin-inline: auto; text-align: center; }
.section-head p { font-size: 1.06rem; color: var(--muted); margin-bottom: 0; }

.eyebrow {
  display: inline-block;
  font-size: .775rem;
  font-weight: 700;
  letter-spacing: .13em;
  text-transform: uppercase;
  color: var(--brand);
  margin-bottom: .7rem;
}
.section--brand .eyebrow { color: var(--brand-300); }

.lead { font-size: 1.1rem; color: var(--ink-2); }

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

/* Squared-off with a soft radius rather than a full pill: it echoes the
   aluminium profiles the business actually makes, and reads as more
   considered than a capsule. Depth comes from a top inner highlight plus a
   brand-tinted shadow, not from a heavy gradient. */

.btn {
  --btn-bg:    var(--brand);
  --btn-bg-hi: var(--brand-500);
  --btn-fg:    #fff;
  --btn-bd:    transparent;
  --btn-ring:  rgba(1, 102, 153, .30);

  position: relative;
  isolation: isolate;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .6em;
  padding: .88em 1.55em;
  border: 1.5px solid var(--btn-bd);
  border-radius: 0;
  background: var(--btn-bg);
  color: var(--btn-fg);
  font: inherit;
  font-size: .95rem;
  font-weight: 700;
  line-height: 1.2;
  letter-spacing: -.005em;
  text-align: center;
  text-wrap: balance;
  cursor: pointer;
  overflow: hidden;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, .22),
    0 1px 2px rgba(4, 21, 38, .10),
    0 2px 8px var(--btn-ring);
  transition: transform .16s cubic-bezier(.2,.7,.3,1),
              box-shadow .2s ease,
              background-color .2s ease,
              border-color .2s ease;
}

/* a light sweep that crosses the face on hover */
.btn::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(115deg,
    transparent 20%,
    rgba(255, 255, 255, .26) 46%,
    transparent 72%);
  transform: translateX(-120%);
  transition: transform .55s cubic-bezier(.2,.7,.3,1);
}

.btn:hover {
  color: var(--btn-fg);
  background: var(--btn-bg-hi);
  transform: translateY(-2px);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, .26),
    0 2px 4px rgba(4, 21, 38, .10),
    0 10px 22px var(--btn-ring);
}
.btn:hover::after { transform: translateX(120%); }

.btn:active {
  transform: translateY(0);
  box-shadow:
    inset 0 2px 5px rgba(4, 21, 38, .22),
    0 1px 2px rgba(4, 21, 38, .10);
}

.btn:focus-visible {
  outline: 3px solid var(--brand-500);
  outline-offset: 3px;
}

.btn svg { width: 1.15em; height: 1.15em; flex: none; }
/* the trailing arrow leans into the direction of travel */
.btn svg:last-child:not(:first-child) { transition: transform .2s ease; }
.btn:hover svg:last-child:not(:first-child) { transform: translateX(3px); }

/* --- the loud call to action: logo cyan, navy label ---
   White on this cyan is only 2.6:1; navy on it is 7.4:1. */
.btn--accent {
  --btn-bg:    var(--accent);
  --btn-bg-hi: #1ac9f7;
  --btn-fg:    var(--accent-ink);
  --btn-ring:  rgba(3, 189, 240, .38);
}
.btn--accent::after { background: linear-gradient(115deg, transparent 20%, rgba(255,255,255,.42) 46%, transparent 72%); }

.btn--wa {
  --btn-bg:    var(--wa);
  --btn-bg-hi: #1fc45e;
  --btn-ring:  rgba(37, 211, 102, .34);
}

.btn--ghost {
  --btn-bg:    #fff;
  --btn-bg-hi: var(--brand-50);
  --btn-fg:    var(--brand-700);
  --btn-bd:    var(--line);
  --btn-ring:  rgba(4, 21, 38, .05);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, .6),
    0 1px 2px rgba(4, 21, 38, .06);
}
.btn--ghost:hover { --btn-bd: var(--brand-100); }
.btn--ghost::after { display: none; }

.btn--light {
  --btn-bg:    #fff;
  --btn-bg-hi: #eef7fd;
  --btn-fg:    var(--brand-700);
  --btn-ring:  rgba(4, 21, 38, .18);
}

.btn--outline-light {
  --btn-bg:    rgba(255, 255, 255, .06);
  --btn-bg-hi: rgba(255, 255, 255, .16);
  --btn-fg:    #fff;
  --btn-bd:    rgba(255, 255, 255, .40);
  --btn-ring:  rgba(0, 0, 0, .12);
  backdrop-filter: blur(4px);
}
.btn--outline-light:hover { --btn-bd: rgba(255, 255, 255, .8); }

.btn--sm    { padding: .62em 1.1em; font-size: .87rem; border-radius: 0; }
.btn--block { width: 100%; }

.btn-row { display: flex; flex-wrap: wrap; gap: .7rem; }

@media (prefers-reduced-motion: reduce) {
  .btn::after { display: none; }
}

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

.site-header {
  position: sticky;
  top: 0;
  z-index: 90;
  background: rgba(255,255,255,.94);
  backdrop-filter: saturate(160%) blur(12px);
  border-bottom: 1px solid var(--line);
}
.site-header.is-scrolled { box-shadow: var(--shadow-sm); }

.topbar {
  background: var(--brand-700);
  color: #a9c9e2;
  font-size: .83rem;
}
.topbar .container {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: .4rem 1.2rem;
  min-height: 38px;
  padding-block: 6px;
}
.topbar a { color: #eaf6fd; font-weight: 600; }
.topbar a:hover { color: #fff; text-decoration: underline; }
.topbar__links { display: flex; flex-wrap: wrap; gap: 1.1rem; align-items: center; }
.topbar__item { display: inline-flex; align-items: center; gap: .4em; }
.topbar__item svg { width: 14px; height: 14px; opacity: .85; }

.header-bar {
  display: flex;
  align-items: center;
  gap: 1.2rem;
  min-height: var(--header-h);
}

.brand { display: flex; align-items: center; gap: .6rem; margin-right: auto; }
.brand__mark { width: auto; height: 52px; flex: none; }
.brand__text { display: flex; flex-direction: column; line-height: 1.05; }

/* Mirrors the logo's own hierarchy — big navy name, cyan sub-line — as live
   text, so it stays sharp and readable at any size. */
.brand__name {
  font-size: 1.56rem;
  font-weight: 800;
  letter-spacing: -.02em;
  color: var(--brand-700);
  text-transform: uppercase;
}
.brand__sub {
  font-size: .70rem;
  font-weight: 700;
  letter-spacing: .155em;
  text-transform: uppercase;
  color: var(--brand-500);
}

.brand--footer { margin-right: 0; }
.brand--footer .brand__name { color: #fff; }
.brand--footer .brand__sub  { color: var(--brand-300); }

.nav { display: flex; align-items: center; gap: .35rem; }
.nav a {
  padding: .55em .9em;
  border-radius: 0;
  color: var(--ink-2);
  font-size: .95rem;
  font-weight: 600;
  transition: background-color .16s ease, color .16s ease;
}
.nav a:hover { background: var(--surface-2); color: var(--ink); }
.nav a.is-active { background: var(--brand-50); color: var(--brand-700); }

.nav a { white-space: nowrap; }

/* products dropdown */
.nav__group { position: relative; }
.nav__caret {
  display: inline-block;
  width: .42em; height: .42em;
  margin-left: .12em;
  border-right: 1.7px solid currentColor;
  border-bottom: 1.7px solid currentColor;
  transform: translateY(-2px) rotate(45deg);
  opacity: .6;
}
.nav__menu {
  position: absolute;
  top: calc(100% + 10px);
  left: 0;
  z-index: 5;
  min-width: 268px;
  padding: 8px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: #fff;
  box-shadow: var(--shadow-lg);
  opacity: 0;
  visibility: hidden;
  transform: translateY(-6px);
  transition: opacity .16s ease, transform .16s ease, visibility .16s;
}
/* bridge the gap so the menu does not close while the pointer travels to it */
.nav__group::after {
  content: "";
  position: absolute;
  top: 100%; left: 0;
  width: 100%; height: 12px;
}
.nav__group:hover .nav__menu,
.nav__group:focus-within .nav__menu {
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
}
.nav__menu a {
  display: flex;
  flex-direction: column;
  gap: .1rem;
  padding: .6em .8em;
  border-radius: var(--radius-sm);
  white-space: normal;
}
.nav__menu b { font-size: .93rem; font-weight: 700; color: var(--ink); }
.nav__menu small { font-size: .78rem; color: var(--muted); }
.nav__menu a:hover b { color: var(--brand-700); }

.nav-toggle {
  display: none;
  width: 44px; height: 44px;
  padding: 0;
  border: 1.5px solid var(--line);
  border-radius: 0;
  background: #fff;
  cursor: pointer;
}
.nav-toggle span {
  display: block;
  width: 19px; height: 2px;
  margin: 4px auto;
  border-radius: 0;
  background: var(--ink);
  transition: transform .2s ease, opacity .2s ease;
}
.nav-toggle[aria-expanded="true"] span:nth-child(1) { transform: translateY(6px) rotate(45deg); }
.nav-toggle[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.nav-toggle[aria-expanded="true"] span:nth-child(3) { transform: translateY(-6px) rotate(-45deg); }

/* ---------- hero ----------
   Full-viewport animated scene with the copy overlaid on it. The scene used to
   be a bordered card in a two-column grid; that card, its border, radius and
   shadow are gone, and the canvas now paints the whole section. Dark navy +
   gold, matching the dealer page — it is also what makes white copy readable
   over a moving background. */

.hero {
  position: relative;
  overflow: hidden;
  display: flex;
  align-items: center;
  /* svh, not vh: on mobile Safari vh counts the retracted toolbar and pushes
     the trust chips under the fold on first paint. The header is sticky, so it
     takes real layout space above this section — subtracting its height is what
     makes the hero end exactly at the fold instead of just past it.
     --header-total is published by main.js; the fallback is the measured value
     for the default two-row header. */
  min-height: calc(100svh - var(--header-total, 118px));
  padding: clamp(28px, 5vh, 72px) 0;
  color: #cfe0ef;
  background:
    radial-gradient(820px 620px at 72% 30%, rgba(3, 189, 240, .16) 0%, rgba(3, 189, 240, 0) 66%),
    radial-gradient(700px 560px at 6% 88%, rgba(216, 168, 58, .10) 0%, rgba(216, 168, 58, 0) 64%),
    linear-gradient(158deg, #021a33 0%, #01274d 48%, #010c18 100%);
}

/* The animated scene, full-bleed behind everything. */
.hero-scene {
  position: absolute;
  inset: 0;
  z-index: 0;
  cursor: crosshair;
  touch-action: pan-y;
}
.hero-scene canvas {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
}

/* Still mesh pattern, so the section reads even with JS off. The canvas fades
   it out once it takes over. Positioned to sit roughly where the canvas draws
   its window — right of centre, clear of the headline. */
.hero-scene::before {
  content: "";
  position: absolute;
  inset: 24% 20% 24% 54%;
  border: 3px solid rgba(191, 228, 246, .35);
  border-radius: 0;
  background:
    repeating-linear-gradient(0deg,  rgba(255, 255, 255, .16) 0 1px, transparent 1px 8px),
    repeating-linear-gradient(90deg, rgba(255, 255, 255, .16) 0 1px, transparent 1px 8px);
  transform: perspective(600px) rotateY(-17deg);
  transition: opacity .5s ease;
}
.hero-scene.is-live::before { opacity: 0; }

/* Scrim under the copy. Without it the headline sits on moving mesh and the
   contrast fails wherever a bright breeze streak passes behind a letter. */
.hero::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background: linear-gradient(96deg,
    rgba(1, 12, 24, .90) 0%,
    rgba(1, 12, 24, .72) 34%,
    rgba(1, 12, 24, .30) 58%,
    rgba(1, 12, 24, 0) 78%);
}

/* a soft floor, so the section hands over to the stats band instead of cutting */
.hero::after {
  content: "";
  position: absolute;
  inset: auto 0 0 0;
  height: 140px;
  z-index: 1;
  pointer-events: none;
  background: linear-gradient(180deg, rgba(1, 12, 24, 0) 0%, rgba(1, 12, 24, .55) 100%);
}

.hero .container { position: relative; z-index: 2; width: 100%; }

/* Shared right-hand column for the readouts that stack beside the window.
   The min() is a guard, not decoration: at ~1440px the window's right edge is
   close enough to the viewport edge that hugging it would slide these under the
   floating dock. 250px reserves the widest readout plus the dock. */
.hero {
  --scene-col-right: min(calc(var(--scene-right, 58%) + 14px), calc(100% - 250px));
}

/* 36rem, not 40: the label that flanks the window's left edge needs the gap
   between this column and the window to stay clear. */
.hero__copy { max-width: 36rem; min-width: 0; }

/* ---- home hero headline: two lines, two faces, two entrances ---- */

.hero-title {
  color: #fff;
  margin-bottom: .7rem;
  /* the two lines set their own size, so the shared h1 clamp is not wanted */
  font-size: 0;
  line-height: 1;
  overflow: visible;
}

/* The mask is what makes each line wipe rather than fade. Its own line-height
   gives the descenders and the gold rule room — overflow:hidden on a box
   fitted exactly to the cap height would shear them off. */
.hero-title__mask {
  display: block;
  overflow: hidden;
  padding-bottom: .12em;
}

.hero-title__line {
  display: block;
  width: 100%;
  min-width: 0;
  word-wrap: break-word;
  overflow-wrap: break-word;
}

/* Line one: the barrier. Geometric, heavy, tight — and it arrives from the
   right and stops hard, the way an insect stops at the mesh. */
.hero-title__line--block {
  font-family: var(--font);
  font-size: clamp(2rem, 4.3vw, 3.15rem);
  font-weight: 800;
  letter-spacing: -.028em;
  line-height: 1.1;
  animation: titleBlock .72s cubic-bezier(.16, .9, .28, 1) .1s both;
}

/* Line two: the airflow. A different face entirely — Playfair italic, lighter,
   gold — drifting in from the left, slower and further, with no hard stop. */
.hero-title__line--flow {
  font-family: "Playfair Display", Georgia, "Times New Roman", serif;
  font-size: clamp(2.1rem, 4.7vw, 3.45rem);
  font-style: italic;
  font-weight: 500;
  letter-spacing: -.012em;
  line-height: 1.16;
  color: #ecc464;
  animation: titleFlow 1.15s cubic-bezier(.22, .61, .24, 1) .42s both;
}

/* An underline that wipes in behind the second line once it has landed. Drawn
   as a pseudo-element so it can be timed separately from the text. */
.hero-title__line--flow::after {
  content: "";
  display: block;
  height: 3px;
  margin-top: .12em;
  background: linear-gradient(90deg, rgba(216, 168, 58, .85), rgba(216, 168, 58, 0));
  transform-origin: left center;
  animation: titleRule .8s cubic-bezier(.2, .7, .3, 1) 1.25s both;
}

@keyframes titleBlock {
  from { opacity: 0; transform: translateX(1.1em); }
  to   { opacity: 1; transform: translateX(0); }
}
@keyframes titleFlow {
  from { opacity: 0; transform: translateX(-1.6em); }
  to   { opacity: 1; transform: translateX(0); }
}
@keyframes titleRule {
  from { transform: scaleX(0); }
  to   { transform: scaleX(1); }
}
.hero__sub {
  font-size: clamp(1.02rem, 1.5vw, 1.16rem);
  color: #b9cfe3;
  max-width: 50ch;
  margin-bottom: 1.7rem;
}
.hero .btn-row { margin-bottom: 1.8rem; }

/* Which side is which — makes the metaphor legible at a glance.
   Positioned off the window's own projected box (--scene-* are published by
   hero.js on resize) rather than off the viewport corners: full-screen, a
   corner-pinned "Outside" label floated over the headline nowhere near the
   window it was labelling. The offsets are calc'd rather than done with a
   transform because these elements already run the heroRise entrance
   animation, and that animates transform. */
.hero-scene__side {
  position: absolute;
  /* Vertical position is a fraction down the window itself (see the per-label
     rules below) rather than a fixed offset, so the labels keep their relation
     to the frame at any size. */
  z-index: 2;
  padding: .3em .7em;
  border-radius: 0;
  font-size: .715rem;
  font-weight: 700;
  letter-spacing: .07em;
  text-transform: uppercase;
  backdrop-filter: blur(4px);
}
/* Outside: high on the left, where the insects are still arriving. */
.hero-scene__side--out {
  /* right edge lands 14px clear of the window's left edge */
  right: calc(100% - var(--scene-left, 42%) + 14px);
  left: auto;
  top: calc(var(--scene-top, 130px) + var(--scene-h, 400px) * .20);
  background: rgba(255, 255, 255, .10);
  color: #cfe0ef;
}
/* Your room: lower on the right, past the mesh. */
.hero-scene__side--in {
  left: var(--scene-col-right, 58%);
  right: auto;
  top: calc(var(--scene-top, 130px) + var(--scene-h, 400px) * .55);
  background: rgba(3, 189, 240, .20);
  color: #9fe6fb;
}

/* live tally of insects turned away */
/* The tally belongs with the room side it is counting for, so it sits directly
   under the "Your room" label rather than off in the viewport corner. */
.hero-scene__stat {
  position: absolute;
  top: calc(var(--scene-top, 130px) + var(--scene-h, 400px) * .68);
  left: var(--scene-col-right, 58%);
  right: auto;
  z-index: 2;
  display: flex;
  align-items: baseline;
  gap: .4rem;
  padding: .5rem .8rem;
  border-radius: 0;
  border: 1px solid rgba(255, 255, 255, .14);
  background: rgba(1, 20, 38, .55);
  backdrop-filter: blur(6px);
}
.hero-scene__stat-num {
  font-size: 1.5rem;
  font-weight: 800;
  line-height: 1;
  color: #ecc464;
  font-variant-numeric: tabular-nums;
}
.hero-scene__stat-label {
  font-size: .66rem;
  font-weight: 700;
  line-height: 1.15;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: #9db4c8;
}

/* ---- photo frame used on About and elsewhere ---- */
.media-frame {
  margin: 0 0 1.2rem;
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: var(--surface-2);
  box-shadow: var(--shadow);
  line-height: 0;
}
.media-frame img { width: 100%; height: auto; }

/* Photo fills the frame edge to edge. line-height:0 on .media-frame is not
   enough on its own: the button wrapper is inline-block, which adds a baseline
   gap under the image, so it becomes a block here. */
/* Flush frames sit in an equal-height grid row, so the row is as tall as its
   tallest photo and a shorter one would leave a strip of frame showing beneath
   it. Stretching the chain to full height and covering fills the box. */
.media-frame--flush {
  padding: 0;
  height: 100%;
}
.media-frame > .album__zoom,
.media-frame--flush > .album__zoom {
  display: block;
  width: 100%;
  height: 100%;
  padding: 0;
  border: 0;
  background: none;
  cursor: zoom-in;
  line-height: 0;
}
.media-frame--flush > .album__zoom img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
/* :not(), because this and the --flush rule above have identical specificity —
   whichever came last was winning, and it was this one, which is why the flush
   images kept falling back to height:auto and leaving frame showing. */
.media-frame:not(.media-frame--flush) > .album__zoom img {
  display: block;
  width: 100%;
  height: auto;
}


.hero__badge {
  position: absolute;
  z-index: 2;
  bottom: 26px;
  right: 22px;
  display: flex; align-items: center; gap: .7rem;
  padding: .8rem 1.05rem;
  border: 1px solid rgba(255, 255, 255, .14);
  background: rgba(1, 20, 38, .62);
  backdrop-filter: blur(8px);
}
.hero__badge svg { width: 28px; height: 28px; color: #6ecff5; flex: none; }
.hero__badge b { display: block; color: #fff; font-size: .96rem; line-height: 1.2; }
.hero__badge span { font-size: .8rem; color: #9db4c8; }

.trust-row {
  display: flex;
  flex-wrap: wrap;
  gap: .5rem .55rem;
}
.chip {
  display: inline-flex;
  align-items: center;
  gap: .45em;
  padding: .44em .9em;
  border: 1px solid var(--line);
  border-radius: 0;
  background: #fff;
  font-size: .845rem;
  font-weight: 600;
  color: var(--ink-2);
}
.chip svg { width: 15px; height: 15px; color: var(--brand); flex: none; }

/* ---- hero entrance: a short staggered rise, once, on load ---- */
@keyframes heroRise {
  from { opacity: 0; transform: translateY(16px); }
  to   { opacity: 1; transform: translateY(0); }
}

.hero__copy > * {
  animation: heroRise .7s cubic-bezier(.2, .7, .3, 1) both;
}
/* The headline is child 1 and runs its own two-line entrance (titleBlock /
   titleFlow), so it opts out of the generic stagger — otherwise it fades in
   twice. The rest follow once the headline has landed. */
.hero-title { animation: none; }
.hero__copy > *:nth-child(2) { animation-delay: .52s; }   /* sub-headline */
.hero__copy > *:nth-child(3) { animation-delay: .64s; }   /* buttons */
.hero__copy > *:nth-child(4) { animation-delay: .76s; }   /* trust chips */

/* The scene no longer animates in. `sceneIn` used to scale the panel from
   .975, and hero.js measures with clientWidth precisely because a transform
   corrupts that measurement — at full-bleed the mis-sized canvas would be a
   pale band down the whole viewport. It fades instead. */
@keyframes sceneFade { from { opacity: 0; } to { opacity: 1; } }
.hero-scene { animation: sceneFade 1s ease .15s both; }
.hero__badge,
.hero-scene__stat,
.hero-scene__side {
  animation: heroRise .6s cubic-bezier(.2, .7, .3, 1) .8s both;
}

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

.stats {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 1px;
  background: var(--line);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  overflow: hidden;
}
.stat { padding: clamp(20px, 3vw, 30px) 22px; background: #fff; text-align: center; }
.stat b {
  display: block;
  overflow-wrap: anywhere;
  font-size: clamp(1.55rem, 3vw, 2.15rem);
  font-weight: 800;
  color: var(--brand);
  letter-spacing: -.03em;
  line-height: 1.1;
}
.stat span { font-size: .87rem; color: var(--muted); font-weight: 600; }

/* "ISO 9001:2015" is a fixed string, not a number that can be shortened. Between
   1025px and ~1150px the stats row is still 4 columns but each tile is narrow,
   and the value wrapped to two lines — which dropped this tile's label below the
   other three and made the row look uneven. A slightly tighter clamp keeps it on
   one line there; at wide widths it resolves to 2.15rem, identical to the numbers. */
.stat b.stat__text { font-size: clamp(1.3rem, 2.3vw, 2.15rem); white-space: nowrap; }

/* ---------- generic card grids ---------- */

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

/* ---------- category cards ---------- */

.cat-card {
  display: flex;
  flex-direction: column;
  padding: clamp(22px, 2.6vw, 30px);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background: #fff;
  box-shadow: var(--shadow-sm);
  transition: transform .18s ease, box-shadow .2s ease, border-color .2s ease;
}
.cat-card:hover {
  transform: translateY(-3px);
  border-color: var(--brand-100);
  box-shadow: var(--shadow-lg);
}
.cat-card__icon {
  display: grid;
  place-items: center;
  width: 52px; height: 52px;
  margin-bottom: 1rem;
  border-radius: 0;
  background: var(--brand-50);
  color: var(--brand);
}
.cat-card__icon svg { width: 26px; height: 26px; }
.cat-card h3 { margin-bottom: .4rem; }
.cat-card p { color: var(--muted); font-size: .95rem; margin-bottom: 1.1rem; }
.cat-card__link {
  margin-top: auto;
  font-weight: 700;
  font-size: .93rem;
  display: inline-flex;
  align-items: center;
  gap: .4em;
}
.cat-card__link::after { content: "→"; transition: transform .18s ease; }
.cat-card:hover .cat-card__link::after { transform: translateX(3px); }

/* ---------- product cards ---------- */

.product-card {
  display: flex;
  flex-direction: column;
  overflow: hidden;
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background: #fff;
  box-shadow: var(--shadow-sm);
  transition: transform .18s ease, box-shadow .2s ease, border-color .2s ease;
}
.product-card:hover {
  transform: translateY(-3px);
  border-color: var(--brand-100);
  box-shadow: var(--shadow-lg);
}
.product-card__media {
  position: relative;
  display: block;
  aspect-ratio: 4 / 3;
  background: var(--surface-2);
  overflow: hidden;
}
.product-card__media img {
  width: 100%; height: 100%;
  object-fit: cover;
  transition: transform .5s cubic-bezier(.2,.7,.3,1);
}
.product-card:hover .product-card__media img { transform: scale(1.04); }

.product-card__tag {
  position: absolute;
  top: 12px; left: 12px;
  padding: .32em .75em;
  border-radius: 0;
  background: rgba(255,255,255,.94);
  font-size: .715rem;
  font-weight: 700;
  letter-spacing: .045em;
  text-transform: uppercase;
  color: var(--brand-700);
  box-shadow: var(--shadow-sm);
}

.product-card__body {
  display: flex;
  flex-direction: column;
  flex: 1;
  padding: 20px 20px 22px;
}
.product-card__body h3 { font-size: 1.1rem; margin-bottom: .35rem; }
.product-card__body h3 a { color: inherit; }
.product-card__body h3 a:hover { color: var(--brand-600); }
.product-card__desc {
  font-size: .915rem;
  color: var(--muted);
  margin-bottom: 1.05rem;
}
.product-card__actions { display: flex; gap: .5rem; margin-top: auto; }
.product-card__actions .btn { flex: 1; }

/* ---------- feature list ---------- */

.feature {
  display: flex;
  gap: 1rem;
  padding: clamp(20px, 2.4vw, 26px);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: #fff;
}
.feature__icon {
  display: grid; place-items: center;
  width: 44px; height: 44px; flex: none;
  border-radius: 0;
  background: var(--brand-50);
  color: var(--brand);
}
.feature__icon svg { width: 22px; height: 22px; }
.feature h4 { margin-bottom: .25rem; }
.feature p { font-size: .92rem; color: var(--muted); margin-bottom: 0; }

/* ---------- steps ---------- */

.steps { counter-reset: step; }
.step {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  padding: clamp(22px, 2.6vw, 28px);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background: #fff;
}
/* The number sits in normal flow rather than absolutely positioned: a badge
   taller than its reserved padding used to overlap the heading. */
.step::before {
  counter-increment: step;
  content: counter(step);
  display: grid;
  place-items: center;
  flex: none;
  width: 34px;
  height: 34px;
  margin-bottom: 1rem;
  border-radius: 0;
  background: var(--brand);
  color: #fff;
  font-size: .95rem;
  font-weight: 800;
  line-height: 1;
}
.step h4 { margin-bottom: .35rem; }
.step p { font-size: .93rem; color: var(--muted); margin-bottom: 0; }

/* ---------- method comparison ---------- */

.compare-card {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  padding: clamp(20px, 2.4vw, 26px);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background: var(--surface-2);
}
.compare-card__icon {
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  margin-bottom: 1rem;
  border-radius: 0;
  background: #fff;
  border: 1px solid var(--line);
  color: var(--muted);
}
.compare-card__icon svg { width: 22px; height: 22px; }
.compare-card h3 { font-size: 1.02rem; margin-bottom: .4rem; }
.compare-card p { font-size: .9rem; color: var(--muted); margin-bottom: 0; }

/* the one we sell reads as the answer, not just another option */
.compare-card--win {
  background: #fff;
  border-color: var(--brand-100);
  box-shadow: var(--shadow);
}
.compare-card--win .compare-card__icon {
  background: var(--brand-50);
  border-color: var(--brand-100);
  color: var(--brand);
}
.compare-card--win p { color: var(--ink-2); }
.compare-card__flag {
  margin-top: 1rem;
  padding: .28em .7em;
  border-radius: 0;
  background: var(--accent);
  color: var(--accent-ink);
  font-size: .69rem;
  font-weight: 800;
  letter-spacing: .07em;
  text-transform: uppercase;
}

/* ---------- cta band ---------- */

.cta-band {
  position: relative;
  overflow: hidden;
  border-radius: var(--radius-lg);
  background: var(--brand-700);
  color: #c6dcee;
  isolation: isolate;
}
.cta-band__grid {
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, .95fr);
  align-items: center;
}
.cta-band__body { padding: clamp(30px, 4.4vw, 56px); }
.cta-band h2 { color: #fff; margin-bottom: .6rem; }
.cta-band p { color: #b6d4ea; }
.cta-band__media { align-self: stretch; min-height: 260px; }
.cta-band__media img { width: 100%; height: 100%; object-fit: cover; }

/* ---------- faq ---------- */

.faq { max-width: 820px; margin-inline: auto; }
.faq details {
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: #fff;
  margin-bottom: .7rem;
  overflow: hidden;
}
.faq details[open] { border-color: var(--brand-100); box-shadow: var(--shadow-sm); }
.faq summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 1.05rem 1.25rem;
  cursor: pointer;
  font-weight: 700;
  color: var(--ink);
  list-style: none;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after {
  content: "+";
  flex: none;
  font-size: 1.35rem;
  font-weight: 500;
  color: var(--brand);
  transition: transform .2s ease;
}
.faq details[open] summary::after { transform: rotate(45deg); }
.faq__body { padding: 0 1.25rem 1.2rem; font-size: .96rem; color: var(--ink-2); }
.faq__body p:last-child { margin-bottom: 0; }

/* ---------- pagination ---------- */

.pager {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: .4rem;
  max-width: 820px;
  margin: 1.6rem auto 0;
}
.pager__btn {
  min-width: 40px;
  padding: .5em .75em;
  border: 1.5px solid var(--line);
  border-radius: 0;
  background: #fff;
  color: var(--ink-2);
  font: inherit;
  font-size: .88rem;
  font-weight: 700;
  line-height: 1;
  cursor: pointer;
  transition: background-color .16s ease, border-color .16s ease, color .16s ease;
}
.pager__btn:hover:not(:disabled) {
  border-color: var(--brand-100);
  background: var(--brand-50);
  color: var(--brand-700);
}
.pager__btn.is-current {
  background: var(--brand);
  border-color: var(--brand);
  color: #fff;
}
.pager__btn:disabled { opacity: .4; cursor: not-allowed; }
.pager__btn:focus-visible { outline: 3px solid var(--brand-500); outline-offset: 2px; }
.pager__btn--nav { min-width: 0; }
.pager__status {
  flex-basis: 100%;
  text-align: center;
  margin-top: .5rem;
  font-size: .82rem;
  color: var(--muted);
}

@media (max-width: 480px) {
  /* numbers alone would wrap badly on a phone — prev/next plus the status
     line carries the same information */
  .pager__btn[data-page] { display: none; }
  .pager__btn--nav { flex: 1; }
}

@media (max-width: 620px) {
  /* Under 16px, iOS Safari zooms the page in when a field takes focus and
     leaves it zoomed — which is what was throwing the layout sideways as soon
     as anyone started filling the enquiry form. */
  .field input,
  .field select,
  .field textarea { font-size: 16px; }
}

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

.page-head {
  padding: clamp(26px, 3.2vw, 42px) 0 clamp(20px, 2.6vw, 32px);
  background: linear-gradient(180deg, var(--brand-50) 0%, #fbfdfc 100%);
  border-bottom: 1px solid var(--line);
}
.page-head h1 { margin-bottom: .45rem; }
.page-head p { max-width: 62ch; color: var(--ink-2); margin-bottom: 0; }

.breadcrumb {
  display: flex;
  flex-wrap: wrap;
  gap: .4rem;
  align-items: center;
  margin-bottom: .9rem;
  font-size: .85rem;
  color: var(--muted);
}
.breadcrumb a { color: var(--muted); font-weight: 600; }
.breadcrumb a:hover { color: var(--brand-600); }
.breadcrumb li { list-style: none; display: flex; align-items: center; gap: .4rem; }
.breadcrumb ol { display: flex; flex-wrap: wrap; gap: .4rem; margin: 0; padding: 0; }
.breadcrumb li + li::before { content: "/"; opacity: .5; }
.breadcrumb [aria-current] { color: var(--ink-2); }

/* ---------- filter tabs ---------- */

.filters {
  display: flex;
  flex-wrap: wrap;
  gap: .5rem;
  margin-bottom: clamp(24px, 3vw, 36px);
}
.filters a {
  padding: .58em 1.15em;
  border: 1.5px solid var(--line);
  border-radius: 0;
  background: #fff;
  font-size: .91rem;
  font-weight: 700;
  color: var(--ink-2);
  transition: all .16s ease;
}
.filters a:hover { border-color: var(--brand-100); background: var(--brand-50); color: var(--brand-700); }
.filters a.is-active {
  background: var(--brand);
  border-color: var(--brand);
  color: #fff;
}
.filters a small { font-weight: 600; opacity: .7; }

/* ---------- product detail ---------- */

.pd-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.02fr) minmax(0, .98fr);
  gap: clamp(28px, 4vw, 54px);
  align-items: start;
}

.pd-gallery { position: sticky; top: calc(var(--header-total, 118px) + 18px); }
.pd-gallery__main {
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background: var(--surface-2);
  overflow: hidden;
}
.pd-gallery__main img {
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: contain;          /* never crop — hardware sheets are a wider shape */
  background: var(--surface-2);
}
.pd-thumbs { display: flex; gap: .6rem; margin-top: .7rem; }
.pd-thumbs button {
  flex: 0 0 88px;
  padding: 0;
  border: 2px solid var(--line);
  border-radius: 0;
  background: var(--surface-2);
  cursor: pointer;
  overflow: hidden;
  transition: border-color .16s ease;
}
.pd-thumbs button.is-active { border-color: var(--brand); }
.pd-thumbs img { width: 100%; aspect-ratio: 4/3; object-fit: contain; }

.pd-title { margin-bottom: .5rem; }
.pd-tagline { font-size: 1.06rem; color: var(--ink-2); margin-bottom: 1.3rem; }

.pd-cta {
  display: flex;
  flex-wrap: wrap;
  gap: .6rem;
  padding: 1.05rem;
  margin-bottom: 1.6rem;
  border: 1px solid var(--brand-100);
  border-radius: var(--radius);
  background: var(--brand-50);
}
.pd-cta .btn { flex: 1 1 160px; }
.pd-cta__note {
  flex-basis: 100%;
  margin: 0;
  font-size: .84rem;
  color: var(--brand-700);
  text-align: center;
}

.spec-table { width: 100%; border-collapse: collapse; font-size: .94rem; }
.spec-table th, .spec-table td {
  padding: .72rem .2rem;
  border-bottom: 1px solid var(--line);
  text-align: left;
  vertical-align: top;
}
.spec-table th { width: 40%; color: var(--ink); font-weight: 700; }
.spec-table tr:last-child th, .spec-table tr:last-child td { border-bottom: 0; }

.check-list { list-style: none; padding: 0; margin: 0; }
.check-list li {
  position: relative;
  padding-left: 1.75rem;
  margin-bottom: .55rem;
  font-size: .95rem;
}
.check-list li::before {
  content: "";
  position: absolute;
  left: 0; top: .42em;
  width: 16px; height: 16px;
  border-radius: 0;
  background: var(--brand-50) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23016699' stroke-width='3.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='20 6 9 17 4 12'/%3E%3C/svg%3E") center / 11px no-repeat;
}

.pill-list { display: flex; flex-wrap: wrap; gap: .45rem; padding: 0; margin: 0; list-style: none; }
.pill-list li {
  padding: .38em .85em;
  border: 1px solid var(--line);
  border-radius: 0;
  background: var(--surface-2);
  font-size: .855rem;
  font-weight: 600;
  color: var(--ink-2);
}

.pd-block { margin-bottom: 1.9rem; }
.pd-block > h3 {
  padding-bottom: .55rem;
  margin-bottom: .95rem;
  border-bottom: 2px solid var(--brand-50);
  font-size: 1.08rem;
}

.note-box {
  display: flex;
  gap: .8rem;
  padding: 1rem 1.15rem;
  border-radius: var(--radius);
  border-left: 3px solid var(--accent);
  background: var(--brand-50);
  font-size: .92rem;
  color: #0b3a5c;
}
.note-box svg { width: 20px; height: 20px; flex: none; color: var(--brand); margin-top: .15rem; }
.note-box p { margin: 0; }

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

.form-card {
  padding: clamp(24px, 3.2vw, 38px);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background: #fff;
  box-shadow: var(--shadow);
}

.form-grid { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 1rem 1.1rem; }
.field { display: flex; flex-direction: column; gap: .35rem; }
.field--full { grid-column: 1 / -1; }

.field label { font-size: .875rem; font-weight: 700; color: var(--ink); }
.field label .req { color: var(--danger); }
.field .hint { font-size: .79rem; color: var(--muted); font-weight: 500; }

.field input,
.field select,
.field textarea {
  width: 100%;
  padding: .78em .95em;
  border: 1.5px solid var(--line);
  border-radius: var(--radius-sm);
  background: #fff;
  font: inherit;
  font-size: .95rem;
  color: var(--ink);
  transition: border-color .16s ease, box-shadow .16s ease;
}
.field textarea { min-height: 118px; resize: vertical; }
.field select {
  appearance: none;
  padding-right: 2.4em;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2364798c' stroke-width='2.5' stroke-linecap='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right .85em center;
  background-size: 16px;
}
.field input:focus,
.field select:focus,
.field textarea:focus {
  outline: none;
  border-color: var(--brand);
  box-shadow: 0 0 0 3.5px var(--brand-50);
}
.field input::placeholder, .field textarea::placeholder { color: #9aada7; }

.field.has-error input,
.field.has-error select,
.field.has-error textarea { border-color: var(--danger); }
.field__error { font-size: .8rem; font-weight: 600; color: var(--danger); }

.hp-field {
  position: absolute !important;
  left: -9999px;
  width: 1px; height: 1px;
  overflow: hidden;
}

.form-foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .8rem;
  margin-top: 1.3rem;
}
/* Two buttons share the first row; the reassurance line sits under them. */
.form-foot .privacy { flex: 1 1 100%; font-size: .8rem; color: var(--muted); margin: 0; }

.alert {
  display: flex;
  gap: .7rem;
  padding: .95rem 1.15rem;
  margin-bottom: 1.4rem;
  border-radius: var(--radius);
  font-size: .93rem;
  font-weight: 600;
}
.alert svg { width: 20px; height: 20px; flex: none; margin-top: .1rem; }
.alert--success { background: var(--brand-50); color: var(--brand-700); border: 1px solid var(--brand-100); }
.alert--error   { background: #fdecea; color: #90291d; border: 1px solid #f6cfca; }
.alert p { margin: 0; }

/* ---------- contact ---------- */

.contact-grid {
  display: grid;
  grid-template-columns: minmax(0, .82fr) minmax(0, 1.18fr);
  gap: clamp(26px, 3.4vw, 48px);
  align-items: start;
}
.contact-list { list-style: none; padding: 0; margin: 0 0 1.6rem; }
.contact-list li {
  display: flex;
  gap: .9rem;
  padding: 1rem 0;
  border-bottom: 1px solid var(--line);
}
.contact-list li:last-child { border-bottom: 0; }
.contact-list__icon {
  display: grid; place-items: center;
  width: 40px; height: 40px; flex: none;
  border-radius: 0;
  background: var(--brand-50);
  color: var(--brand);
}
.contact-list__icon svg { width: 20px; height: 20px; }
.contact-list b { display: block; font-size: .8rem; letter-spacing: .05em; text-transform: uppercase; color: var(--muted); }
.contact-list a, .contact-list span { color: var(--ink); font-weight: 600; }
.contact-list a:hover { color: var(--brand-600); }

.map-frame {
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: var(--surface-2);
  line-height: 0;
}
.map-frame iframe { width: 100%; height: 340px; border: 0; }

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

.site-footer {
  padding: clamp(34px, 4vw, 52px) 0 0;
  background: var(--footer-bg);
  color: #93a9bf;
  font-size: .94rem;
}
.footer-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr) minmax(0, 1fr) minmax(0, 1.25fr);
  gap: clamp(22px, 2.8vw, 38px);
  padding-bottom: clamp(24px, 3vw, 36px);
}
.site-footer h4 {
  margin-bottom: 1rem;
  color: #fff;
  font-size: .8rem;
  font-weight: 700;
  letter-spacing: .11em;
  text-transform: uppercase;
}
.site-footer a { color: #93a9bf; }
.site-footer a:hover { color: #fff; }
.site-footer ul { list-style: none; padding: 0; margin: 0; }
.site-footer li { margin-bottom: .55rem; }

.footer-brand p { margin: 1.05rem 0 0; max-width: 34ch; font-size: .91rem; }

/* ---- footer columns: plain headings on desktop, collapsible on phones ---- */
.footer-areas {
  padding: 1.4rem 0 1.5rem;
  border-top: 1px solid rgba(255,255,255,.1);
}
.footer-areas h4 { margin-bottom: .8rem; }

/* ---- areas ticker: one line, scrolling like a news crawl ---- */
.ticker {
  position: relative;
  overflow: hidden;
  /* fade the ends so items appear and vanish rather than being chopped */
  mask-image: linear-gradient(90deg, transparent, #000 5%, #000 95%, transparent);
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 5%, #000 95%, transparent);
}
.ticker__track {
  display: flex;
  width: max-content;
  animation: ticker-crawl 68s linear infinite;
}
/* pause so the links can actually be clicked */
.ticker:hover .ticker__track,
.ticker:focus-within .ticker__track { animation-play-state: paused; }

.ticker__run {
  display: flex;
  align-items: center;
  gap: 0;
  margin: 0;
  padding: 0;
  list-style: none;
}
.ticker__run li {
  display: flex;
  align-items: center;
  margin: 0;
  white-space: nowrap;
  font-size: .875rem;
}
/* a dot between entries, drawn on the item rather than as extra markup */
.ticker__run li::after {
  content: "";
  width: 4px;
  height: 4px;
  margin: 0 1.15rem;
  border-radius: 0;
  background: var(--brand-500);
  opacity: .55;
  flex: none;
}
.ticker__run a { color: #cfe0f0; }
.ticker__run a:hover { color: #fff; text-decoration: underline; }
.ticker__run span { color: #7b93aa; }

@keyframes ticker-crawl {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }   /* exactly one of the two copies */
}

@media (prefers-reduced-motion: reduce) {
  /* no crawl — let people scroll it themselves */
  .ticker { overflow-x: auto; mask-image: none; -webkit-mask-image: none; }
  .ticker__track { animation: none; }
  .ticker__run:last-child { display: none; }
}

.footer-credit strong { color: #cfe0f0; font-weight: 700; }

.footer-bottom {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: .6rem 1.4rem;
  padding: 1.15rem 0;
  border-top: 1px solid rgba(255,255,255,.1);
  font-size: .855rem;
}
.footer-bottom p { margin: 0; }

/* ==========================================================
   Dealer Partner Program (/dealer)
   ----------------------------------------------------------
   The trade-facing page, and the only place the brief's dark navy + gold
   treatment is applied. Deliberately scoped: the gold tokens live on
   .dealer-hero, not on :root, so nothing on the customer-facing pages can
   inherit them by accident.
   ========================================================== */

.dealer-hero {
  position: relative;
  overflow: hidden;
  padding: clamp(46px, 6vw, 88px) 0 clamp(40px, 5vw, 70px);
  color: #cfe0ef;
  background:
    /* gold bloom from the top right, so the accent reads as light not paint */
    radial-gradient(760px 520px at 88% 6%, rgba(216, 168, 58, .20) 0%, rgba(216, 168, 58, 0) 62%),
    radial-gradient(700px 560px at 4% 92%, rgba(1, 139, 200, .22) 0%, rgba(1, 139, 200, 0) 66%),
    linear-gradient(158deg, #021a33 0%, #01274d 46%, #010c18 100%);
}

/* the mesh weave again, as texture — the product, not decoration */
.dealer-hero::before {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background:
    repeating-linear-gradient(0deg,  rgba(255, 255, 255, .05) 0 1px, transparent 1px 24px),
    repeating-linear-gradient(90deg, rgba(255, 255, 255, .05) 0 1px, transparent 1px 24px);
  mask-image: radial-gradient(105% 85% at 78% 20%, #000 12%, transparent 74%);
  -webkit-mask-image: radial-gradient(105% 85% at 78% 20%, #000 12%, transparent 74%);
}

.dealer-hero .container { position: relative; z-index: 1; }
.dealer-hero__grid {
  display: grid;
  grid-template-columns: minmax(0, 1.15fr) minmax(0, .85fr);
  gap: clamp(24px, 4vw, 56px);
  align-items: center;
}
.dealer-hero__inner { max-width: 760px; }
.dealer-hero__media { margin: 0; }
.dealer-hero__media img {
  width: 100%;
  height: auto;
  border: 1px solid rgba(255, 255, 255, .14);
}

.eyebrow--gold { color: var(--gold-hi); }

.dealer-hero h1 { color: #fff; margin-bottom: .35rem; }
.dealer-hero h1 em {
  /* block, so "Authorized Dealer" always starts its own line and is never split
     across two; fit-content, so the gold rule hugs the words instead of running
     the full width of the heading. */
  display: block;
  width: fit-content;
  font-style: normal;
  color: var(--gold-hi);
  /* underline rather than a fill: gold text on navy already carries enough
     weight, and a block of gold behind it drops the contrast below 4.5:1 */
  border-bottom: 3px solid rgba(216, 168, 58, .45);
}

.dealer-hero__tagline {
  margin-bottom: 1rem;
  font-size: clamp(1.1rem, 2.1vw, 1.44rem);
  font-weight: 700;
  color: var(--gold-hi);
  letter-spacing: -.01em;
}
.dealer-hero__sub {
  max-width: 58ch;
  margin-bottom: 1.7rem;
  font-size: clamp(1rem, 1.4vw, 1.12rem);
  color: #b9cfe3;
}

.dealer-hero .btn-row { margin-bottom: 1.7rem; }

.btn--gold {
  --btn-bg:    var(--gold);
  --btn-bg-hi: var(--gold-hi);
  --btn-fg:    var(--gold-ink);
  --btn-ring:  rgba(216, 168, 58, .34);
}

.dealer-hero__points { display: flex; flex-wrap: wrap; gap: .5rem .55rem; }
.chip--dark {
  border-color: rgba(255, 255, 255, .18);
  background: rgba(255, 255, 255, .07);
  color: #dceaf5;
  backdrop-filter: blur(4px);
}
.chip--dark svg { color: var(--gold-hi); }

/* ---- the seven steps ---- */

.dealer-steps {
  counter-reset: dealer-step;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1rem 1.4rem;
  max-width: 940px;
  margin: 0 auto;
  padding: 0;
  list-style: none;
}
/* Seven is odd, so the last step would sit alone in a half-width box. Letting
   it span both columns turns that stray into the visible pay-off line. */
.dealer-steps > :last-child { grid-column: 1 / -1; }

.dealer-step {
  display: flex;
  gap: 1rem;
  padding: clamp(16px, 2vw, 22px);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: #fff;
}
.dealer-step__num {
  display: grid;
  place-items: center;
  width: 38px; height: 38px;
  flex: none;
  border-radius: 0;
  background: var(--brand-700);
  color: #fff;
  font-size: .95rem;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
}
.dealer-steps > :last-child .dealer-step__num { background: #b8860b; }
.dealer-step h4 { margin-bottom: .2rem; }
.dealer-step p { margin-bottom: 0; font-size: .92rem; color: var(--muted); }

/* ---- benefit cards ---- */

.benefit-card {
  padding: clamp(20px, 2.4vw, 26px);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: #fff;
  transition: transform .16s ease, box-shadow .2s ease, border-color .16s ease;
}
.benefit-card:hover {
  transform: translateY(-3px);
  border-color: var(--brand-100);
  box-shadow: var(--shadow);
}
.benefit-card__icon {
  display: grid; place-items: center;
  width: 46px; height: 46px;
  margin-bottom: .9rem;
  border-radius: 0;
  background: linear-gradient(150deg, #fbf1d8 0%, #f3e0b0 100%);
  color: #8a6410;
}
.benefit-card__icon svg { width: 23px; height: 23px; }
.benefit-card h3 { font-size: 1.02rem; margin-bottom: .3rem; }
.benefit-card p { margin-bottom: 0; font-size: .91rem; color: var(--muted); }

/* ---------- process flow (About) ----------
   Customer → Measurement → Factory → Delivery → Installation, shown as a chain.
   The connector is a pseudo-element on each step except the last, so the arrow
   count always matches the step count and rotates to point down when the row
   wraps into a column. */

.flow {
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: 1rem;
  margin: 0;
  padding: 0;
  list-style: none;
  counter-reset: flow;
}
.flow__step {
  position: relative;
  padding: clamp(18px, 2.2vw, 24px) clamp(14px, 1.6vw, 20px);
  border: 1px solid var(--line);
  background: #fff;
  text-align: center;
}
.flow__step:not(:last-child)::after {
  content: "";
  position: absolute;
  top: 50%;
  right: -.72rem;
  width: .5rem;
  height: .5rem;
  border-right: 2px solid var(--brand-300);
  border-bottom: 2px solid var(--brand-300);
  transform: translateY(-50%) rotate(-45deg);
}
.flow__icon {
  display: grid;
  place-items: center;
  width: 46px; height: 46px;
  margin: 0 auto .8rem;
  background: var(--brand-50);
  color: var(--brand);
}
.flow__icon svg { width: 23px; height: 23px; }
.flow__step h4 { margin-bottom: .3rem; }
.flow__step p { margin-bottom: 0; font-size: .88rem; color: var(--muted); }

/* ---------- dealer reach map ---------- */

.reach {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, .9fr);
  gap: clamp(24px, 4vw, 52px);
  align-items: center;
}
.reach__body p { color: var(--muted); }
.reach__body .btn-row { margin-top: 1.4rem; }
.reach__map { margin: 0; }
.reach__map img { width: 100%; height: auto; }

/* ---------- process flow with photographs ---------- */

.flow--photo .flow__step { padding: 0; text-align: left; overflow: hidden; }
.flow__media { position: relative; line-height: 0; }
.flow__media img {
  width: 100%;
  aspect-ratio: 4 / 3;
  /* the files are already cut to 4:3, so this only guards against a future
     replacement of a different shape leaving bars in the tile */
  object-fit: cover;
  display: block;
}
/* the icon stays, as a badge over the photo, so each step still reads at a
   glance when the images are busy */
.flow--photo .flow__icon {
  position: absolute;
  bottom: 0; left: 0;
  width: 40px; height: 40px;
  margin: 0;
  background: var(--brand);
  color: #fff;
}
.flow--photo .flow__icon svg { width: 20px; height: 20px; }
.flow__body { padding: .85rem 1rem 1.1rem; }
.flow--photo .flow__step h4 { margin-bottom: .25rem; }

/* ---------- placeholder warning strip ----------
   Deliberately loud. It sits on any section still showing stand-in content, so
   the site cannot be signed off or launched with placeholders in it by accident. */

.placeholder-note {
  display: flex;
  align-items: flex-start;
  gap: .8rem;
  margin: 0 0 1.6rem;
  padding: .9rem 1.1rem;
  border: 1px solid #e0b23c;
  border-left-width: 4px;
  background: #fdf6e3;
  color: #5c4408;
}
.placeholder-note svg { width: 20px; height: 20px; flex: none; margin-top: .15rem; }
.placeholder-note p { margin: 0; font-size: .92rem; }
.placeholder-note code {
  padding: .1em .35em;
  background: rgba(92, 68, 8, .1);
  font-size: .88em;
}
/* dashed edge, so a placeholder card reads as unfinished at a glance */
.review--placeholder { border-style: dashed; }

/* ---------- project gallery (album) ----------
   Justified rows, three / two large / three. Each item's flex-grow is its own
   aspect ratio, so within a row the widths land proportional to the shapes and
   the heights come out equal — which is how a row of mixed portrait and
   landscape photographs can align without a single one being cropped. */

.album { display: flex; flex-direction: column; gap: var(--album-gap, 14px); }

.album__row {
  display: flex;
  gap: var(--album-gap, 14px);
  align-items: stretch;
}
.album__item {
  /* grow by shape; basis 0 so the ratio alone decides the split */
  flex: var(--aspect, 1) 1 0;
  min-width: 0;
  margin: 0;
  position: relative;
  overflow: hidden;
  background: var(--surface-2);
}
/* the whole photo, at its own shape — no object-fit, no fixed ratio */
.album__item img { width: 100%; height: 100%; display: block; object-fit: cover; }

/* A row left with a single visible photo after filtering would otherwise
   stretch it across the full width. */
.album__row.is-sparse { justify-content: flex-start; }
.album__row.is-sparse .album__item { flex: 0 1 auto; max-width: 420px; }
.album__row.is-sparse .album__item img { height: auto; }

.album__zoom {
  display: block;
  position: relative;
  width: 100%;
  height: 100%;
  padding: 0;
  border: 0;
  background: none;
  cursor: zoom-in;
  text-align: left;
}
.album__zoom::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  background: rgba(1, 39, 77, 0);
  transition: background .18s ease;
}
.album__zoom:hover::before { background: rgba(1, 39, 77, .18); }
.album__zoom:focus-visible { outline: 3px solid var(--brand-500); outline-offset: -3px; }

/* Titles. The brief's reference album has none; these sit over the foot of each
   photo on a gradient so they read without a caption bar breaking the grid. */
.album__cap {
  position: absolute;
  z-index: 2;
  inset: auto 0 0 0;
  /* the caption is a sibling of the zoom button, so it must not swallow the
     click that belongs to the photo underneath it */
  pointer-events: none;
  padding: 1.6rem .9rem .8rem;
  background: linear-gradient(180deg, rgba(1, 12, 24, 0) 0%, rgba(1, 12, 24, .82) 65%);
  color: #fff;
}
.album__cap b { display: block; font-size: .95rem; line-height: 1.25; }
.album__cap small { color: #bcd2e4; font-size: .8rem; }

.album__item[hidden] { display: none; }
.album__row[hidden] { display: none; }

/* ---------- lightbox ---------- */

.lightbox {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: none;
  align-items: center;
  justify-content: center;
  padding: clamp(12px, 3vw, 40px);
  background: rgba(1, 12, 24, .92);
}
.lightbox.is-open { display: flex; }
.lightbox__img {
  max-width: 100%;
  /* the image is never scaled past its own pixels — enlarging a 650px photo to
     fill a 1440px screen just makes it soft */
  max-height: 100%;
  width: auto;
  height: auto;
  box-shadow: 0 30px 80px rgba(0, 0, 0, .6);
}
.lightbox__cap {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  padding: 1rem 1.2rem;
  background: linear-gradient(180deg, rgba(1,12,24,0), rgba(1,12,24,.85));
  color: #dceaf5;
  font-size: .92rem;
  text-align: center;
}
.lightbox__close {
  position: absolute;
  top: 14px; right: 14px;
  width: 46px; height: 46px;
  display: grid;
  place-items: center;
  border: 1px solid rgba(255, 255, 255, .25);
  background: rgba(255, 255, 255, .08);
  color: #fff;
  font-size: 1.5rem;
  line-height: 1;
  cursor: pointer;
}
.lightbox__close:hover { background: rgba(255, 255, 255, .18); }

/* ---------- testimonials ---------- */

.review {
  display: flex;
  flex-direction: column;
  gap: .9rem;
  margin: 0;
  padding: clamp(20px, 2.4vw, 28px);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: #fff;
}
.review blockquote { margin: 0; flex: 1; }
.review blockquote p {
  margin: 0;
  font-size: 1.02rem;
  color: var(--ink-2);
}
/* the quote mark is decoration, so it is drawn rather than typed — a literal
   " in the text would be read out by a screen reader */
.review blockquote p::before { content: "\201C"; }
.review blockquote p::after  { content: "\201D"; }

.stars { display: inline-flex; gap: .1rem; }
.stars svg { width: 17px; height: 17px; }
.stars__on  svg { color: #d8a83a; fill: #d8a83a; }
.stars__off svg { color: var(--line); }

.review__by { display: flex; align-items: center; gap: .7rem; }
.review__photo {
  width: 44px; height: 44px;
  flex: none;
  border-radius: 0;
  object-fit: cover;
}
.review__photo--initial {
  display: grid;
  place-items: center;
  background: var(--brand-50);
  color: var(--brand-700);
  font-weight: 800;
  font-size: 1.1rem;
}
.review__by b { display: block; color: var(--ink); font-size: .95rem; }
.review__by small { color: var(--muted); font-size: .82rem; }

/* ---------- floating action dock ----------
   Pinned to the right edge, vertically centred. Since the header and hero CTAs
   were removed this is the only call/WhatsApp path above the fold, so it is
   never scroll-revealed and never hidden.

   Collapsed to a square icon button by default; on hover or keyboard focus the
   button grows leftward and the label appears after the icon, reading
   icon-then-label. */

.action-dock {
  position: fixed;
  right: 0;
  /* Sits above the true middle: dead-centre put it level with the widest part
     of the hero scene, and a little higher keeps it clear of the readouts that
     stack down the right of the window. */
  top: 42%;
  transform: translateY(-50%);
  z-index: 80;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 9px;
  transition: opacity .22s ease, visibility .22s ease;
}

/* On a phone the dock floats over the page, and where the page already offers
   the same two actions — the product CTA block, an enquiry form — it landed
   directly on top of those buttons. main.js drops this class on while one of
   those blocks is on screen, so the dock never competes with the real thing.
   No transform here: the desktop dock is centred with translateY(-50%) and
   animating transform would knock it out of place. */
.action-dock.is-hidden {
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
}
.action-dock__btn {
  display: inline-flex;
  align-items: center;
  /* Square while collapsed: 25px icon + .85rem either side ≈ 54px, comfortably
     over the 44px minimum tap target. */
  padding: .85rem;
  border-radius: 0;
  color: #fff;
  font-weight: 700;
  font-size: .94rem;
  line-height: 1;
  white-space: nowrap;
  transition: box-shadow .2s ease;
}
.action-dock__btn svg { width: 25px; height: 25px; flex: none; }
.action-dock__btn:hover { color: #fff; }

/* The label is always in the DOM — it is clipped, not removed, so the slide has
   something to reveal. The accessible name comes from the anchor's aria-label,
   so a clipped label costs nothing to a screen reader. max-width is the thing
   being animated: it is the only way to transition to an intrinsic text width
   without measuring it in JS. */
.action-dock__btn span {
  display: block;
  max-width: 0;
  /* the label sits after the icon, so this is the gap between the two */
  margin-left: 0;
  opacity: 0;
  overflow: hidden;
  transition: max-width .3s cubic-bezier(.2, .7, .3, 1),
              margin-left .3s cubic-bezier(.2, .7, .3, 1),
              opacity .22s ease;
}
.action-dock__btn:hover span,
.action-dock__btn:focus-visible span {
  max-width: 9rem;
  margin-left: .6rem;
  opacity: 1;
}
.action-dock__btn--wa {
  background: var(--wa);
  box-shadow: 0 8px 26px rgba(37, 211, 102, .40);
}
.action-dock__btn--wa:hover { box-shadow: 0 12px 32px rgba(37, 211, 102, .52); }
.action-dock__btn--call {
  background: var(--brand);
  box-shadow: 0 8px 26px rgba(1, 102, 153, .38);
}
.action-dock__btn--call:hover { box-shadow: 0 12px 32px rgba(1, 102, 153, .50); }

/* ---------- misc ---------- */

.empty-state {
  padding: clamp(38px, 5vw, 62px) 24px;
  border: 1px dashed var(--line);
  border-radius: var(--radius-lg);
  background: var(--surface-2);
  text-align: center;
}

.thankyou {
  max-width: 620px;
  margin-inline: auto;
  text-align: center;
}
.thankyou__mark {
  display: grid; place-items: center;
  width: 78px; height: 78px;
  margin: 0 auto 1.5rem;
  border-radius: 0;
  background: var(--brand-50);
  color: var(--brand);
}
.thankyou__mark svg { width: 40px; height: 40px; }

.prose > :last-child { margin-bottom: 0; }
.text-center { text-align: center; }
.mt-0 { margin-top: 0; }
.mb-0 { margin-bottom: 0; }
.sr-only {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0,0,0,0); white-space: nowrap; border: 0;
}

/* ==========================================================
   Responsive
   ========================================================== */

@media (max-width: 1150px) {
  /* five across stops fitting here well before the layout breakpoint */
  .flow { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .flow__step:not(:last-child)::after { display: none; }

  /* Below this width the gap between the copy column and the window closes up,
     and a label beside the window would land on the paragraph. The labels move
     to the window's own top corners, and the tally goes back to the viewport
     corner where there is still room for it. */
  .hero-scene__side--out,
  .hero-scene__side--in { top: max(12px, calc(var(--scene-top, 130px) - 34px)); }
  .hero-scene__side--out {
    right: auto;
    left: calc(var(--scene-left, 42%) + 2px);
  }
  .hero-scene__side--in {
    left: auto;
    right: calc(100% - var(--scene-right, 58%) + 2px);
  }
  .hero-scene__stat { top: 56px; left: auto; right: 22px; }
}

@media (max-width: 1024px) {
  .footer-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .grid--4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .stats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .pd-gallery { position: static; }
}

@media (max-width: 900px) {
  :root { --header-h: 66px; }

  .nav-toggle { display: block; order: 3; }

  .nav {
    position: fixed;
    /* --header-h is the logo row alone; the sticky header also carries the
       topbar above it. Offsetting by the row height dropped the panel on top
       of the logo and the toggle that opens it, so the whole measured header
       height (published by main.js) is what the panel has to clear. */
    inset: var(--header-total, 128px) 0 auto 0;
    flex-direction: column;
    align-items: stretch;
    gap: .2rem;
    max-height: 0;
    padding: 0 20px;
    overflow: hidden;
    background: #fff;
    border-bottom: 1px solid transparent;
    transition: max-height .28s ease, padding .28s ease;
  }
  .nav.is-open {
    /* 70vh cut the last two links off on a 640px phone. Everything below the
       header is fair game — the panel scrolls only if it still cannot fit. */
    max-height: calc(100svh - var(--header-total, 128px) - 8px);
    padding: 12px 20px 18px;
    border-bottom-color: var(--line);
    overflow-y: auto;
    overscroll-behavior: contain;
    box-shadow: var(--shadow-lg);
  }
  .nav a { padding: .8em 1em; border-radius: var(--radius-sm); }

  /* the dropdown becomes a plain inline list — no hover on touch */
  .nav__caret { display: none; }
  .nav__group::after { display: none; }
  .nav__menu {
    position: static;
    min-width: 0;
    margin: .2rem 0 .4rem .9rem;
    padding: 0 0 0 .8rem;
    border: 0;
    border-left: 2px solid var(--brand-50);
    border-radius: 0;
    background: none;
    box-shadow: none;
    opacity: 1;
    visibility: visible;
    transform: none;
  }
  .nav__menu a { padding: .6em .8em; }

  .pd-grid,
  .contact-grid,
  .cta-band__grid { grid-template-columns: minmax(0, 1fr); }

  /* Below this width the copy spans the full column, so it can no longer sit
     beside the window — it sits under it. The scene draws in the upper third
     (see hero.js) and the copy is bottom-aligned against a scrim that is
     nearly opaque where the text actually is. A side-to-side fade cannot work
     here: there is no clear side left. */
  .hero {
    align-items: flex-end;
    padding-bottom: clamp(26px, 6vh, 54px);
    /* The readouts are pinned to the top of the section, but the copy is
       bottom-aligned — so on a short phone, where the copy is taller than the
       section, it rode up underneath the tally. This reserves the band they
       occupy. It costs nothing on a tall screen: the copy is shorter than the
       box there, so flex-end still parks it at the bottom. */
    padding-top: 112px;
  }
  .hero::before {
    background: linear-gradient(180deg,
      rgba(1, 12, 24, .26) 0%,
      rgba(1, 12, 24, .60) 40%,
      rgba(1, 12, 24, .93) 70%,
      rgba(1, 12, 24, .97) 100%);
  }
  .hero::after { display: none; }             /* the scrim already lands dark */
  .hero-scene::before { inset: 8% 24% 48% 24%; }
  .hero__copy { max-width: none; }

  .cta-band__media { min-height: 220px; order: -1; }
  .grid--3 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 620px) {
  body { font-size: 16px; }
  /* Phones: the section keeps full height but the readouts shrink and the
     badge moves out from under the floating dock in the bottom-right. */
  /* The window spans most of a phone's width, so there is no room to flank it
     — the labels go back to the top corners here. */
  .hero-scene__side { top: 12px; }
  .hero-scene__side--out { left: 14px; right: auto; }
  .hero-scene__side--in  { right: 14px; left: auto; }
  .hero-scene__stat {
    top: 46px;
    left: auto;
    right: 14px;
    padding: .4rem .6rem;
  }
  /* it would sit on top of the third trust chip at this width */
  .hero__badge { display: none; }
  .hero-scene__stat-num { font-size: 1.2rem; }
  /* Both buttons are available in the floating dock and throughout the site;
     hiding them from the hero on phones saves vertical space and reduces clutter. */
  .hero .btn-row { display: none; }
  /* The topbar shows address, hours, and phone — all available in the footer
     and via the floating dock. Hiding it saves ~38px of header space. */
  .topbar { display: none; }
  :root { --header-h: 48px; }

  /* The readout band is shorter here than on a tablet (see the 900px rule),
     so less of the section has to be held back for it. */
  .hero { padding-top: 100px; }
  /* Reclaim what that reserve costs, so the trust chips stay near the fold on
     a 640px-tall phone instead of being pushed a screen below it. */
  .hero-title { margin-bottom: .45rem; }
  .hero__sub { margin-bottom: 1.15rem; font-size: 1rem; }
  .hero .btn-row { margin-bottom: 1.15rem; }
  .trust-row { gap: .4rem .45rem; }
  .trust-row .chip { padding: .38em .72em; font-size: .79rem; }
  .grid--2, .grid--3, .grid--4 { grid-template-columns: minmax(0, 1fr); }
  .dealer-steps { grid-template-columns: minmax(0, 1fr); }
  /* the three/two rhythm cannot survive here, so every row becomes a pair */
  .album__row { flex-wrap: wrap; }
  .album__item { flex: 1 1 calc(50% - var(--album-gap, 14px)); }
  .flow { grid-template-columns: minmax(0, 1fr); }
  .reach { grid-template-columns: minmax(0, 1fr); }
  .dealer-hero__grid { grid-template-columns: minmax(0, 1fr); }
  .dealer-hero__media { order: -1; max-width: 560px; }
  .reach__map { max-width: 460px; margin-inline: auto; }
  /* the connector swings from pointing right to pointing down */
  .flow__step:not(:last-child)::after {
    top: auto;
    bottom: -.72rem;
    right: 50%;
    transform: translateX(50%) rotate(45deg);
  }
  .form-grid { grid-template-columns: minmax(0, 1fr); }
  /* Tighter, because the sticky header carries this bar on every scroll —
     every pixel here is a pixel of every page the phone never gets to show.
     At 390px and up the two items now fit on one line instead of two. */
  .topbar { font-size: .79rem; }
  .topbar__links { gap: .75rem; }
  .topbar .container { justify-content: center; gap: .2rem .8rem; min-height: 32px; padding-block: 5px; }
  .btn-row .btn { flex: 1 1 100%; }
  .pd-cta .btn { flex: 1 1 100%; }
  .product-card__actions { flex-direction: column; }
  /* Bottom-right on phones so both stay inside thumb reach, and icon-only so
     they never cover a form field. 52px keeps the tap target above 44px. */
  .action-dock {
    right: 12px;
    top: auto;
    /* clears the home indicator on a gesture-bar phone */
    bottom: calc(12px + env(safe-area-inset-bottom, 0px));
    transform: none;
    gap: 8px;
  }
  .action-dock__btn {
    width: 50px;
    height: 50px;
    padding: 0;
    border-radius: 0;
    justify-content: center;
  }
  /* Touch has no hover, and a tap that expands the label instead of dialling
     would be a dead first tap. Removed outright here rather than left clipped. */
  .action-dock__btn span { display: none; }
  .footer-grid { grid-template-columns: minmax(0, 1fr); gap: 0; }

  /* Four stacked columns made the footer very long on a phone, so each one
     collapses here. Desktop keeps plain headings and full lists — there is
     nothing to expand there. */
  .footer-col { border-top: 1px solid rgba(255, 255, 255, .1); }
  .footer-col__title {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    margin: 0;
    padding: .95rem 0;
  }
  .footer-col.is-collapsible > .footer-col__title { cursor: pointer; }
  .footer-col.is-collapsible > .footer-col__title::after {
    content: "";
    width: .48rem;
    height: .48rem;
    margin-right: .2rem;
    border-right: 2px solid var(--brand-300);
    border-bottom: 2px solid var(--brand-300);
    transform: translateY(-2px) rotate(45deg);
    transition: transform .2s ease;
  }
  .footer-col.is-open > .footer-col__title::after { transform: translateY(1px) rotate(-135deg); }
  .footer-col.is-collapsible > .footer-col__list { display: none; }
  .footer-col.is-collapsible.is-open > .footer-col__list { display: block; padding-bottom: 1rem; }
  .footer-brand { padding-bottom: 1.2rem; }

.footer-bottom { justify-content: center; text-align: center; }
  .map-frame iframe { height: 260px; }
}

@media (max-width: 620px) {
  /* the topbar repeats what the header and footer already show — trim it to
     one line on phones instead of stacking four */
  .topbar__item--hours,
  .topbar__item--email { display: none; }
}

/* The brand had been shrunk further than the header bar actually required —
   the logo row on a 360px phone holds the mark, the wordmark and the toggle
   with room to spare, and the name was reading as fine print. These sizes are
   set against the narrowest case (320px), where the whole lockup still clears
   the toggle. */
@media (max-width: 480px) {
  /* Two photos across leaves each about 160px wide, and the caption plate sits
     on the bottom of the photo — at that size the title wrapped to three lines
     and covered most of the picture it was labelling. One across here. */
  .album__row { flex-wrap: wrap; }
  .album__item { flex: 1 1 100%; }
  .album__item img { height: auto; }

  .brand__mark { height: 50px; }
  .brand__name { font-size: 1.5rem; }
  .brand__sub { font-size: .67rem; letter-spacing: .14em; }
}

@media (max-width: 420px) {
  .brand__mark { height: 46px; }
  .brand__name { font-size: 1.36rem; }
  .brand__sub { font-size: .615rem; letter-spacing: .115em; }
  .stats { grid-template-columns: minmax(0, 1fr); }
}

@media (max-width: 390px) {
  /* On narrow phones, disable headline animations, reduce font size, and allow
     text to overflow the mask since Playfair italic is extremely wide. */
  .hero-title__mask {
    overflow: visible;
  }
  .hero-title__line--block {
    font-size: 1.7rem;
    animation: none;
  }
  .hero-title__line--flow {
    font-size: 1.8rem;
    letter-spacing: -.02em;
    animation: none;
  }
}

@media (max-width: 340px) {
  .brand__mark { height: 40px; }
  .brand__name { font-size: 1.18rem; }
  .brand__sub { font-size: .55rem; letter-spacing: .09em; }
}

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

@media print {
  .site-header, .site-footer, .action-dock, .pd-cta, .form-card { display: none !important; }
}
