@import url('fonts.css');

/* ============================================================
   Stone & Glass Protection — design system
   Palette sampled directly from the approved reference comp.
   ============================================================ */

:root {
  /* Brand — one teal-cyan accent, used everywhere */
  --cyan:        #0192a9;
  --cyan-deep:   #01829a;
  --cyan-press:  #016d82;
  --cyan-bright: #22b2cb;   /* small text on dark, hover states */
  --cyan-pale:   #60c7e0;   /* the light cyan from the logo mark */

  /* Neutrals */
  --ink:      #080909;      /* the dark sections */
  --ink-2:    #0d1012;      /* raised dark surface */
  --ink-3:    #16191b;      /* hairline-adjacent fills */
  --paper:    #ffffff;
  --paper-2:  #f5f7f8;
  --text:     #0b0e0f;
  --muted:    #5d686b;
  --muted-d:  #9aa5a8;      /* muted text on dark */

  --gold:     #fbbc04;      /* Google's review-star amber, borrowed on purpose */

  --line:     #e4e8ea;
  --line-d:   rgba(255,255,255,.13);

  /* Type */
  --f-display: 'Archivo', 'Helvetica Neue', Arial, sans-serif;
  --f-body:    'Barlow', 'Helvetica Neue', Arial, sans-serif;

  /* Layout */
  --wrap: 1240px;
  --gut: clamp(20px, 4vw, 48px);
  --header-h: 76px;
  /* Distance from viewport edge to the .wrap content edge. Lets a full-bleed
     block keep its inner text aligned with everything else on the page. */
  --edge: max(var(--gut), calc((100vw - var(--wrap)) / 2 + var(--gut)));

  /* Motion */
  --ease: cubic-bezier(.22, .61, .36, 1);
  --dur: .38s;
}

/* ---------- reset ---------- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
body {
  margin: 0;
  background: var(--paper);
  color: var(--text);
  font-family: var(--f-body);
  font-size: 17px;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
}
img, svg, video { display: block; max-width: 100%; }
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; }
h1, h2, h3, h4 { margin: 0; font-family: var(--f-display); font-weight: 800; line-height: 1.02; letter-spacing: -.018em; text-transform: uppercase; }
p { margin: 0; }
::selection { background: var(--cyan); color: #fff; }

:focus-visible {
  outline: 2px solid var(--cyan-bright);
  outline-offset: 3px;
}

/* ---------- primitives ---------- */
.wrap { width: 100%; max-width: var(--wrap); margin-inline: auto; padding-inline: var(--gut); }

.eyebrow {
  font-family: var(--f-display);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .22em;
  text-transform: uppercase;
  color: var(--cyan-bright);
  margin: 0 0 18px;
}

/* Sharp-cornered buttons — a defining trait of the comp */
.btn {
  --btn-bg: var(--cyan);
  --btn-fg: #fff;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 16px 30px;
  background: var(--btn-bg);
  color: var(--btn-fg);
  border-radius: 0;
  font-family: var(--f-display);
  font-size: 13.5px;
  font-weight: 700;
  letter-spacing: .13em;
  text-transform: uppercase;
  white-space: nowrap;
  transition: background var(--dur) var(--ease), transform var(--dur) var(--ease),
              box-shadow var(--dur) var(--ease), color var(--dur) var(--ease),
              border-color var(--dur) var(--ease);
}
.btn:hover { --btn-bg: var(--cyan-deep); transform: translateY(-2px); box-shadow: 0 12px 30px -12px rgba(1,146,169,.75); }
.btn:active { --btn-bg: var(--cyan-press); transform: translateY(0); }

.btn--outline {
  --btn-bg: transparent;
  --btn-fg: #fff;
  border: 1.5px solid rgba(255,255,255,.75);
}
.btn--outline:hover { --btn-bg: #fff; --btn-fg: var(--cyan); border-color: #fff; box-shadow: 0 12px 30px -14px rgba(0,0,0,.5); }

.btn--dark { --btn-bg: var(--ink); }
.btn--dark:hover { --btn-bg: #1b2124; }

/* Heading flanked by hairlines (dark "every surface" band) */
.rule-head {
  display: flex;
  align-items: center;
  gap: clamp(18px, 4vw, 46px);
  margin: 0 0 clamp(38px, 6vw, 62px);
}
.rule-head::before, .rule-head::after {
  content: '';
  flex: 1;
  height: 1px;
  background: linear-gradient(90deg, transparent, var(--cyan) 55%);
}
.rule-head::after { background: linear-gradient(270deg, transparent, var(--cyan) 55%); }
.rule-head h2 {
  font-size: clamp(21px, 3.1vw, 33px);
  letter-spacing: .01em;
  color: #fff;
  text-align: center;
}
.rule-head .hl { color: var(--cyan-bright); }

.section { padding-block: clamp(64px, 9vw, 118px); }
.section--dark { background: var(--ink); color: #fff; }
/* Soft neutral ground so white cards read as surfaces rather than floating */
.section--tint { background: var(--paper-2); }

/* ============================================================
   Header
   ============================================================ */
.site-header {
  position: sticky;
  top: 0;
  z-index: 90;
  background: rgba(255,255,255,.92);
  backdrop-filter: saturate(1.6) blur(14px);
  -webkit-backdrop-filter: saturate(1.6) blur(14px);
  border-bottom: 1px solid var(--line);
  transition: box-shadow var(--dur) var(--ease);
}
.site-header.is-stuck { box-shadow: 0 10px 34px -22px rgba(8,9,9,.55); }

.hdr {
  display: flex;
  align-items: center;
  gap: 24px;
  height: var(--header-h);
}
.hdr__logo { flex: none; display: flex; align-items: center; }
.hdr__logo img { height: 42px; width: auto; }

.hdr__nav { margin-left: auto; display: flex; align-items: center; gap: clamp(16px, 2.4vw, 34px); }

.navlink {
  position: relative;
  font-family: var(--f-display);
  font-size: 13px;
  font-weight: 700;
  letter-spacing: .13em;
  text-transform: uppercase;
  color: #23292b;
  padding: 6px 0;
  transition: color var(--dur) var(--ease);
}
.navlink::after {
  content: '';
  position: absolute;
  left: 0; right: 0; bottom: -2px;
  height: 2px;
  background: var(--cyan);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--dur) var(--ease);
}
.navlink:hover { color: var(--cyan); }
.navlink:hover::after { transform: scaleX(1); }
.navlink[aria-current='page'] { color: var(--cyan); }
.navlink[aria-current='page']::after { transform: scaleX(1); }

/* ---- About Us dropdown ---- */
.navitem { position: relative; display: flex; align-items: center; }
.navlink--menu { display: inline-flex; align-items: center; gap: 7px; }
.navlink__chev {
  width: 9px;
  height: 6px;
  flex: none;
  transition: transform var(--dur) var(--ease);
}
.navitem:hover .navlink__chev,
.navitem:focus-within .navlink__chev { transform: rotate(180deg); }

.navmenu {
  position: absolute;
  top: 100%;
  left: 50%;
  min-width: 214px;
  display: flex;
  flex-direction: column;
  padding: 8px;
  background: #fff;
  border: 1px solid var(--line);
  box-shadow: 0 24px 48px -26px rgba(11,14,15,.45);
  opacity: 0;
  visibility: hidden;
  transform: translateX(-50%) translateY(4px);
  transition: opacity .26s var(--ease), transform .26s var(--ease), visibility .26s;
  z-index: 95;
}
/* bridges the gap so the menu survives the trip from link to panel */
.navmenu::before {
  content: '';
  position: absolute;
  left: 0; right: 0;
  top: -14px;
  height: 14px;
}
.navitem:hover .navmenu,
.navitem:focus-within .navmenu {
  opacity: 1;
  visibility: visible;
  transform: translateX(-50%) translateY(0);
}
.navmenu a {
  padding: 12px 14px;
  font-family: var(--f-display);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: #23292b;
  white-space: nowrap;
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
}
.navmenu a:hover { background: var(--paper-2); color: var(--cyan); }
.navmenu a[aria-current='page'] { color: var(--cyan); }

.hdr__cta { flex: none; }
.hdr__cta .btn { padding: 14px 26px; font-size: 12.5px; }

/* Burger */
.burger {
  display: none;
  flex: none;
  margin-left: auto;
  width: 46px; height: 46px;
  align-items: center;
  justify-content: center;
}
.burger span {
  display: block;
  position: relative;
  width: 24px; height: 2px;
  background: var(--text);
  transition: background .16s var(--ease);
}
.burger span::before, .burger span::after {
  content: '';
  position: absolute;
  left: 0;
  width: 24px; height: 2px;
  background: var(--text);
  transition: transform var(--dur) var(--ease), top var(--dur) var(--ease);
}
.burger span::before { top: -7px; }
.burger span::after { top: 7px; }
body.nav-open .burger span { background: transparent; }
body.nav-open .burger span::before { top: 0; transform: rotate(45deg); }
body.nav-open .burger span::after { top: 0; transform: rotate(-45deg); }

/* Mobile drawer */
.mobile-nav {
  position: fixed;
  inset: var(--header-h) 0 0;
  z-index: 88;
  background: var(--ink);
  padding: 34px var(--gut) 44px;
  display: flex;
  flex-direction: column;
  gap: 4px;
  transform: translateY(-12px);
  opacity: 0;
  visibility: hidden;
  overflow-y: auto;
  transition: opacity var(--dur) var(--ease), transform var(--dur) var(--ease), visibility var(--dur);
}
body.nav-open .mobile-nav { opacity: 1; visibility: visible; transform: none; }
.mobile-nav a {
  font-family: var(--f-display);
  font-size: 26px;
  font-weight: 800;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: #fff;
  padding: 15px 0;
  border-bottom: 1px solid var(--line-d);
}
.mobile-nav a[aria-current='page'] { color: var(--cyan-bright); }
/* child of About Us — indented and stepped down a size */
.mobile-nav a.mobile-nav__sub {
  font-size: 19px;
  padding-left: 22px;
  color: rgba(255,255,255,.7);
  position: relative;
}
.mobile-nav a.mobile-nav__sub[aria-current='page'] { color: var(--cyan-bright); }
.mobile-nav a.mobile-nav__sub::before {
  content: '';
  position: absolute;
  left: 0;
  top: 50%;
  width: 10px;
  height: 1px;
  background: var(--cyan);
}
.mobile-nav .btn { margin-top: 26px; align-self: flex-start; }

/* ============================================================
   Hero — video background
   ============================================================ */
.hero {
  position: relative;
  min-height: clamp(600px, 90vh, 900px);
  display: flex;
  align-items: center;
  overflow: hidden;
  background: var(--ink);
  isolation: isolate;
}
.hero__media { position: absolute; inset: 0; z-index: 0; }
.hero__media video,
.hero__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
/* Blur is baked into the encode (cheap on mobile); this only adds depth. */
.hero__media::after {
  content: '';
  position: absolute;
  inset: 0;
  /* Calibrated scrim: the source swings luma 48→170 behind the headline,
     so the left column is held at ~.72 to keep white text >7:1 throughout.
     The third layer is a cyan cast that ties the footage to the brand. */
  background:
    linear-gradient(90deg, rgba(6,8,9,.88) 0%, rgba(6,8,9,.74) 36%, rgba(6,8,9,.42) 68%, rgba(6,8,9,.26) 100%),
    linear-gradient(0deg, rgba(6,8,9,.62) 0%, transparent 46%),
    radial-gradient(80% 90% at 4% 52%, rgba(1,146,169,.26), transparent 62%);
}
/* thin brand rule where the hero meets the next section */
.hero::after {
  content: '';
  position: absolute;
  left: 0; right: 0; bottom: 0;
  z-index: 3;
  height: 3px;
  background: linear-gradient(90deg, var(--cyan) 0%, var(--cyan-pale) 26%, transparent 62%);
}
.hero__inner { position: relative; z-index: 2; width: 100%; padding-block: clamp(70px, 10vw, 104px); }
/* wide enough to keep the six service cities on a single row */
.hero__copy { max-width: 760px; }

/* Eyebrow with a leading rule — anchors the headline and adds provenance */
.hero__eyebrow {
  display: flex;
  align-items: center;
  gap: 14px;
  margin-bottom: clamp(18px, 2.4vw, 26px);
  font-family: var(--f-display);
  font-size: clamp(10.5px, 1.1vw, 12.5px);
  font-weight: 700;
  letter-spacing: .3em;
  text-transform: uppercase;
  color: var(--cyan-pale);
  text-shadow: 0 1px 12px rgba(0,0,0,.6);
}
.hero__eyebrow::before {
  content: '';
  width: clamp(28px, 4vw, 54px);
  height: 2px;
  flex: none;
  background: var(--cyan-bright);
}

.hero h1 {
  font-size: clamp(50px, 9.6vw, 124px);
  font-weight: 900;
  line-height: .88;
  letter-spacing: -.035em;
  color: #fff;
  text-shadow: 0 4px 40px rgba(0,0,0,.5);
}
.hero h1 .hl { color: var(--cyan-bright); display: block; }
.hero h1 .dot { color: var(--cyan-bright); }

.hero__sub {
  margin: clamp(22px, 3.2vw, 34px) 0 clamp(32px, 4.6vw, 46px);
  /* Two sentences, one hard <br> between them. Wide enough that the first
     sentence holds a single line; the mobile override below lets both wrap. */
  max-width: 58ch;
  font-size: clamp(17.5px, 2vw, 22px);
  font-weight: 500;
  line-height: 1.45;
  color: rgba(255,255,255,.94);
  text-shadow: 0 1px 16px rgba(0,0,0,.55);
}

/* Service-area strip pinned to the base of the hero */
.hero__areas {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 10px 14px;
  margin-top: clamp(34px, 5vw, 54px);
  padding-top: clamp(18px, 2.4vw, 26px);
  border-top: 1px solid rgba(255,255,255,.22);
  max-width: 100%;
}
.hero__areas span {
  font-family: var(--f-display);
  font-size: clamp(10px, 1.05vw, 12px);
  font-weight: 700;
  letter-spacing: .17em;
  text-transform: uppercase;
  color: rgba(255,255,255,.8);
  text-shadow: 0 1px 10px rgba(0,0,0,.6);
}
/* Separator hangs off the END of each item, never the start — a leading bullet
   is what you get if the list wraps and the marker is a ::before. */
.hero__areas span:not(:last-child)::after {
  content: '';
  display: inline-block;
  width: 4px; height: 4px;
  margin-left: 14px;
  vertical-align: 2px;
  background: var(--cyan-bright);
}
/* Once it has to wrap, drop the markers and let the gap do the work. */
@media (max-width: 760px) {
  .hero__areas { gap: 8px 16px; }
  .hero__areas span:not(:last-child)::after { display: none; }
}

/* Social placeholders. Square, hairline, zero radius to match .btn. Outlined so
   they stay secondary to the two CTAs they share the row with.
   They sit at the RIGHT end of .hero__actions rather than on the service-area
   hairline below: that list already runs 737px inside a 760px column, so a group
   on the same line wrapped to its own row and read as a mistake. */
.hero__social { display: flex; align-items: center; gap: 10px; margin-left: auto; }
.sociallink {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  padding: 0;
  border: 1px solid rgba(255,255,255,.3);
  background: rgba(0,0,0,.18);
  color: rgba(255,255,255,.86);
  cursor: pointer;
  transition: color var(--dur) var(--ease), border-color var(--dur) var(--ease),
              background-color var(--dur) var(--ease), transform var(--dur) var(--ease);
}
.sociallink svg { width: 17px; height: 17px; fill: currentColor; display: block; }
.sociallink:hover {
  color: var(--cyan-bright);
  border-color: var(--cyan-bright);
  background: rgba(0,0,0,.34);
  transform: translateY(-2px);
}
.sociallink:focus-visible { outline: 2px solid var(--cyan-bright); outline-offset: 3px; }
/* Once the row wraps, margin-left:auto would shove the icons to the far right of
   their own line, away from everything. Let them sit under the buttons instead. */
@media (max-width: 700px) {
  .hero__social { margin-left: 0; }
}
.hero__actions { display: flex; align-items: center; gap: clamp(18px, 3vw, 30px); flex-wrap: wrap; }

/* Play / watch-video control */
.playbtn {
  display: inline-flex;
  align-items: center;
  gap: 14px;
  color: #fff;
  font-family: var(--f-display);
  font-size: 13px;
  font-weight: 700;
  letter-spacing: .14em;
  text-transform: uppercase;
}
.playbtn__ring {
  position: relative;
  display: grid;
  place-items: center;
  width: 46px; height: 46px;
  border: 1.5px solid rgba(255,255,255,.8);
  border-radius: 50%;
  transition: background var(--dur) var(--ease), border-color var(--dur) var(--ease), transform var(--dur) var(--ease);
}
.playbtn__ring svg { width: 13px; height: 13px; margin-left: 2px; fill: #fff; transition: fill var(--dur) var(--ease); }
.playbtn:hover .playbtn__ring { background: #fff; border-color: #fff; transform: scale(1.06); }
.playbtn:hover .playbtn__ring svg { fill: var(--cyan); }

/* ============================================================
   Page hero (interior pages) — same palette, no video
   ============================================================ */
.pagehero {
  position: relative;
  background: var(--ink);
  color: #fff;
  padding-block: clamp(64px, 10vw, 116px);
  overflow: hidden;
}
.pagehero::before {
  content: '';
  position: absolute;
  inset: 0;
  background:
    radial-gradient(120% 150% at 8% 0%, rgba(1,146,169,.30), transparent 58%),
    radial-gradient(90% 120% at 100% 100%, rgba(96,199,224,.13), transparent 60%);
}
.pagehero::after {
  content: '';
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 1px;
  background: linear-gradient(90deg, var(--cyan), transparent 70%);
}
.pagehero .wrap { position: relative; z-index: 1; }
.pagehero h1 {
  font-size: clamp(38px, 6.6vw, 76px);
  font-weight: 900;
  letter-spacing: -.025em;
  max-width: 18ch;
}
.pagehero h1 .hl { color: var(--cyan-bright); }
.pagehero__sub {
  margin-top: 20px;
  max-width: 56ch;
  font-size: clamp(16.5px, 1.8vw, 19px);
  color: rgba(255,255,255,.74);
}

.crumbs {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 22px;
  font-family: var(--f-display);
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: rgba(255,255,255,.5);
}
.crumbs a { color: var(--cyan-bright); }
.crumbs a:hover { color: #fff; }

/* ============================================================
   Surfaces strip
   ============================================================ */
.surfaces {
  background: var(--ink);          /* flat black, no wash */
  color: #fff;
  padding-block: clamp(66px, 8.5vw, 110px);
}

.surfaces__grid {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
}
.surface {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 22px;
  padding: 6px clamp(10px, 1.6vw, 24px) 4px;
  text-align: center;
}
/* hairline between columns only — nothing enclosing the items */
.surface + .surface { border-left: 1px solid var(--line-d); }

.surface svg {
  width: clamp(40px, 4.4vw, 54px);
  height: clamp(40px, 4.4vw, 54px);
  stroke: var(--cyan-bright);
  fill: none;
  stroke-width: 1.3;
  stroke-linecap: square;
  stroke-linejoin: miter;
  transition: stroke var(--dur) var(--ease), transform var(--dur) var(--ease);
}
.surface h3 {
  position: relative;
  font-size: clamp(12.5px, 1.35vw, 14.5px);
  font-weight: 700;
  letter-spacing: .07em;
  line-height: 1.34;
  color: #fff;
  padding-bottom: 12px;
}
/* a short rule grows under the label instead of a box lighting up */
.surface h3::after {
  content: '';
  position: absolute;
  left: 50%;
  bottom: 0;
  width: 26px;
  height: 2px;
  background: var(--cyan);
  transform: translateX(-50%) scaleX(0);
  transition: transform .4s var(--ease);
}
/* Lift the icon, not the cell: the divider hairline lives on the cell, so
   transforming the cell drags the line out of alignment with its neighbours. */
.surface:hover svg, .surface:focus-visible svg { stroke: #fff; transform: translateY(-5px); }
.surface:hover h3::after, .surface:focus-visible h3::after { transform: translateX(-50%) scaleX(1); }


/* ============================================================
   About split
   ============================================================ */
.about { background: var(--ink); color: #fff; }
/* Full-bleed: the tile strip runs to the right edge of the viewport, while the
   copy keeps its left edge aligned to .wrap via --edge. Matches the comp. */
/* Copy column is sized directly rather than as a fraction: an fr share keeps
   growing on ultrawide screens and strands empty space beside the text. */
.about__split {
  display: grid;
  grid-template-columns: minmax(0, clamp(480px, 47vw, 780px)) minmax(0, 1fr);
  align-items: stretch;
}

.about__copy {
  /* --edge keeps growing with the viewport, but this section bleeds off the
     right, so on wide screens the left margin ends up wider than the text
     itself. Cap it: aligned with .wrap up to ~1440, fixed beyond that. */
  padding: clamp(50px, 5.6vw, 72px) clamp(28px, 3.4vw, 56px)
           clamp(50px, 5.6vw, 72px) min(var(--edge), 150px);
  display: flex;
  flex-direction: column;
  justify-content: center;
}
.about__copy h2 {
  font-size: clamp(30px, 3.9vw, 47px);
  font-weight: 800;
  line-height: 1.06;
}
.about__copy h2 .hl { color: var(--cyan-bright); }
.about__copy p {
  margin: 22px 0 0;
  max-width: 58ch;
  color: rgba(255,255,255,.72);
  font-size: 16.5px;
}
.about__copy h2 + p { margin-top: 26px; }
.about__copy .btn { margin-top: 34px; }
/* service areas — set apart from the body copy */
.about__copy .about__areas {
  padding-top: 20px;
  border-top: 1px solid var(--line-d);
  color: rgba(255,255,255,.9);
  font-weight: 500;
}
.about__copy .btn { align-self: flex-start; }

/* Stretched flush to the section, as in the comp. The stills end up as tall
   vertical slices (~0.3 aspect) — they still read, and centring them instead
   leaves a dead band under the tiles once the About copy runs long. */
.about__tiles { display: grid; grid-template-columns: repeat(3, 1fr); width: 100%; }
.tile {
  position: relative;
  min-height: clamp(320px, 44vw, 600px);
  display: flex;
  align-items: flex-end;
  justify-content: center;
  padding: 34px 18px 40px;
  overflow: hidden;
  isolation: isolate;
}
.tile img {
  position: absolute;
  inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  /* Full colour: the countertop and window shots carry the section, and
     desaturating them throws away the reason they were chosen. */
  filter: saturate(1.06) contrast(1.05) brightness(.8);
  transform: scale(1.02);
  transition: transform .8s var(--ease), filter .8s var(--ease);
  z-index: -2;
}
.tile::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  /* Foot is dark enough to carry the caption; the upper two-thirds stays open
     so the photograph actually reads. */
  background: linear-gradient(0deg, rgba(6,8,9,.9) 2%, rgba(6,8,9,.6) 34%, rgba(6,8,9,.12) 70%, rgba(6,8,9,.34) 100%);
  transition: background var(--dur) var(--ease);
}
/* The kitchen shot is far wider than the tile, so cover crops it hard on X.
   Dead centre cuts the vase in half against the left edge; this holds it whole. */
.tile--kitchen img { object-position: 38% 50%; }
.tile + .tile { border-left: 1px solid rgba(255,255,255,.16); }
.tile:hover img { transform: scale(1.09); filter: saturate(1.12) contrast(1.06) brightness(.82); }
.tile:hover::after { background: linear-gradient(0deg, rgba(1,146,169,.62) 4%, rgba(6,8,9,.3) 62%, rgba(6,8,9,.5) 100%); }

.tile__in { display: flex; flex-direction: column; align-items: center; gap: 20px; text-align: center; }
.tile__in svg { width: 42px; height: 42px; stroke: #fff; fill: none; stroke-width: 1.4; }
.tile__in h3 { font-size: clamp(13.5px, 1.5vw, 16px); font-weight: 700; letter-spacing: .05em; line-height: 1.3; color: #fff; }

/* ============================================================
   Cyan CTA band
   ============================================================ */
/* Rebuilt 2026-07-31. Was a left copy block + outline button pushed apart by
   space-between, over two radial gradients. The gradients only muddied the teal at
   the corners, and the outline button read as a SECONDARY action on the one band
   whose entire job is to be the primary one. Now: flat teal, centred, type doing
   the work, and two real ways to act. */
.ctaband {
  background: var(--cyan);
  color: #fff;
  padding-block: clamp(58px, 7vw, 88px);
  text-align: center;
}
.ctaband__in {
  display: flex;
  flex-direction: column;
  align-items: center;
}
.ctaband h2 {
  font-size: clamp(30px, 4.4vw, 52px);
  font-weight: 900;
  line-height: 1.06;
  letter-spacing: -.015em;
  text-wrap: balance;
}
.ctaband__sub {
  margin-top: 16px;
  max-width: 46ch;
  color: rgba(255,255,255,.9);
  font-size: clamp(16px, 1.5vw, 18.5px);
  line-height: 1.6;
}
.ctaband__actions {
  margin-top: clamp(28px, 3.2vw, 40px);
  display: flex;
  align-items: center;
  justify-content: center;
  gap: clamp(18px, 2.6vw, 34px);
  flex-wrap: wrap;
}
/* solid white, not the outline: on teal it is the only treatment that outranks
   the headline's own weight */
.btn--onteal { --btn-bg: #fff; --btn-fg: var(--ink); }
.btn--onteal:hover {
  --btn-bg: var(--ink);
  --btn-fg: #fff;
  box-shadow: 0 14px 32px -14px rgba(0,0,0,.55);
}
.ctaband__tel {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding-bottom: 3px;
  border-bottom: 1px solid rgba(255,255,255,.42);
  font-family: var(--f-display);
  font-size: clamp(15px, 1.6vw, 18px);
  font-weight: 700;
  letter-spacing: .05em;
  color: #fff;
  transition: border-color var(--dur) var(--ease);
}
.ctaband__tel:hover { border-color: #fff; }
.ctaband__tel svg { width: 18px; height: 18px; flex: none; stroke: currentColor; fill: none; stroke-width: 1.7; }

/* Social proof under the two actions rather than beside them: a third item in the
   actions row competes with the button, and this is evidence, not a call to act.
   Stars stay --gold because that is the same signal the reviews block it links to
   uses; recolouring them to the site cyan would stop reading as "reviews". */
.ctaband__reviews {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  margin-top: clamp(20px, 2.2vw, 26px);
  padding-bottom: 2px;
  border-bottom: 1px solid transparent;
  color: rgba(255,255,255,.9);
  /* set in caps, so it takes the display face and tracking the site's other
     uppercase labels use — caps in the body font at this size read as shouting */
  font-family: var(--f-display);
  font-size: 13px;
  font-weight: 700;
  letter-spacing: .11em;
  transition: color var(--dur) var(--ease), border-color var(--dur) var(--ease);
}
.ctaband__reviews:hover { color: #fff; border-color: rgba(255,255,255,.65); }
.ctaband__stars { display: inline-flex; gap: 2px; }
.ctaband__stars svg { width: 15px; height: 15px; fill: var(--gold); }

/* Anchor targets have to clear the fixed header or the jump lands under it. */
:target { scroll-margin-top: calc(var(--header-h) + 24px); }

/* ============================================================
   Footer
   ============================================================ */
.site-footer { background: var(--ink); color: #fff; padding-block: clamp(40px, 5vw, 56px); }
.foot {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: clamp(26px, 4vw, 56px);
}
.foot__logo img { height: 46px; width: auto; }
.foot__nav { display: flex; justify-content: center; gap: clamp(16px, 2.4vw, 34px); flex-wrap: wrap; }
.foot__nav a {
  font-family: var(--f-display);
  font-size: 12.5px;
  font-weight: 700;
  letter-spacing: .13em;
  text-transform: uppercase;
  color: rgba(255,255,255,.82);
  transition: color var(--dur) var(--ease);
}
.foot__nav a:hover, .foot__nav a[aria-current='page'] { color: var(--cyan-bright); }

.foot__contact { display: flex; flex-direction: column; gap: 10px; }
.foot__contact a {
  display: flex;
  align-items: center;
  gap: 12px;
  color: rgba(255,255,255,.88);
  font-size: 15.5px;
  /* the email address is long and has no natural break opportunities */
  overflow-wrap: anywhere;
  transition: color var(--dur) var(--ease);
}
.foot__contact a:hover { color: var(--cyan-bright); }
.foot__contact svg { width: 17px; height: 17px; flex: none; stroke: var(--cyan-bright); fill: none; stroke-width: 1.6; }

/* Offices — quiet reference block, one column per location */
.foot__offices {
  margin-top: clamp(32px, 4.2vw, 48px);
  padding-top: clamp(24px, 3vw, 32px);
  border-top: 1px solid var(--line-d);
  text-align: center;
}
.foot__offices__label {
  font-family: var(--f-display);
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: .22em;
  text-transform: uppercase;
  color: rgba(255,255,255,.38);
}
/* Service-area line. Sits between the label and the office columns so the markets
   are stated before the addresses, since the two do not map one to one (four
   offices cover eleven named towns). Capped in ch so it never runs the full
   1200px wrap as one unreadable line. */
.foot__offices__areas {
  margin: 14px auto 0;
  max-width: 92ch;
  color: rgba(255,255,255,.5);
  font-size: 13.5px;
  line-height: 1.6;
  text-wrap: pretty;
}
/* Flex, not grid, because the block is centred now and there are FIVE offices in
   three columns. A grid leaves the last two hanging in columns 1 and 2 with an
   empty third, which reads as a mistake once everything else is centred; flex
   centres the orphan row. The basis reproduces the old 3-column widths exactly. */
.foot__offices ul {
  --off-gap: clamp(22px, 2.6vw, 36px);
  list-style: none;
  margin: 22px 0 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  /* Three wide columns, not five: each address has to sit on ONE line, and the
     longest is ~50 characters. Five columns forced them to wrap. */
  gap: var(--off-gap);
}
.foot__offices li {
  flex: 0 1 calc((100% - var(--off-gap) * 2) / 3);
  padding-top: 16px;
  border-top: 1px solid rgba(255,255,255,.1);
}
.foot__offices b {
  display: block;
  margin-bottom: 9px;
  font-family: var(--f-display);
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: rgba(255,255,255,.82);
}
.foot__offices address {
  font-style: normal;
  font-size: 12.5px;
  line-height: 1.5;
  color: rgba(255,255,255,.4);
  text-wrap: pretty;
}
.foot__offices__tel {
  display: inline-block;
  margin-top: 10px;
  font-family: var(--f-display);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .06em;
  color: rgba(255,255,255,.62);
  transition: color var(--dur) var(--ease);
}
.foot__offices__tel:hover { color: var(--cyan-bright); }
/* Corporate HQ. Same cell anatomy as an office so it still reads as part of the
   set, but the cyan rail and brighter ink mark it as THE address to write to. */
.foot__offices li.is-hq { border-top-color: var(--cyan); }
.foot__offices li.is-hq b { color: var(--cyan-bright); }
.foot__offices li.is-hq address { color: rgba(255,255,255,.62); }

/* Partner mark — a credit line, not a badge: no box, no plate, no border.
   Nothing frames it, so it still reads as someone else's brand. */
.foot__brands {
  margin-top: clamp(22px, 2.8vw, 30px);
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 16px;
}
.foot__brands__label {
  font-family: var(--f-display);
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: rgba(255,255,255,.34);
}
/* Sized by INK, not by canvas. The old amber file carried 30% transparent padding,
   so its approved 42px box only ever drew a 29px mark; xpel-white.webp is trimmed
   tight, so 29px here reproduces that same approved size. Bumping this number now
   scales the glyph 1:1 — 42px would make it 43% bigger than what the client signed
   off on. Opacity .88 keeps the white just under the site logo's. */
.foot__brands img { display: block; height: 29px; width: auto; opacity: .88; }

/* the mark already supplies the breathing room above the rule */
.foot__brands + .foot__legal { margin-top: clamp(20px, 2.6vw, 26px); }

.foot__legal {
  margin-top: clamp(26px, 3.4vw, 38px);
  padding-top: 22px;
  border-top: 1px solid var(--line-d);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  color: rgba(255,255,255,.42);
  font-size: 13.5px;
}
.foot__legal__links { display: flex; gap: clamp(14px, 2vw, 26px); flex-wrap: wrap; }
.foot__legal__links a {
  color: rgba(255,255,255,.52);
  transition: color var(--dur) var(--ease);
}
.foot__legal__links a:hover,
.foot__legal__links a[aria-current='page'] { color: var(--cyan-bright); }

/* ============================================================
   Reusable interior blocks
   ============================================================ */
.lede { max-width: 62ch; font-size: clamp(17px, 1.9vw, 20px); color: var(--muted); }

/* Parent-company name set in brand colour inside running copy. Uses --cyan-press
   rather than --cyan: at body size on white, --cyan only reaches 3.7:1, which is
   under AA. This is 6:1 and reads as the same teal. Dark grounds take the bright. */
.brandname { color: var(--cyan-press); font-weight: 600; }
.section--dark .brandname, .ctaband .brandname, .site-footer .brandname { color: var(--cyan-bright); }


/* No max-width here — a ch limit on the wrapper also throttles the heading,
   which is set far larger than the body text. Constrain the paragraph only. */
.sec-head { margin-bottom: clamp(38px, 5.2vw, 60px); }
.sec-head h2 { font-size: clamp(28px, 3.7vw, 45px); font-weight: 800; line-height: 1.06; }
.sec-head h2 .hl { color: var(--cyan); }
.section--dark .sec-head h2 .hl { color: var(--cyan-bright); }
.sec-head p {
  margin-top: 18px;
  max-width: 56ch;
  color: var(--muted);
  font-size: clamp(16px, 1.6vw, 17.5px);
  text-wrap: pretty;      /* keeps a lone word off the last line */
}
.section--dark .sec-head p { color: rgba(255,255,255,.7); }

/* Real gap rather than the 1px hairline trick, so a short trailing row simply
   ends — no divider colour leaking out of an empty cell. */
.cards { display: grid; gap: clamp(14px, 1.5vw, 20px); }
.cards--3 { grid-template-columns: repeat(3, 1fr); }
.cards--4 { grid-template-columns: repeat(4, 1fr); }
/* four-up cells are narrow — give the text back some of the padding */
.cards--4 .card { padding: clamp(24px, 2.2vw, 32px); }

.card {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  background: var(--paper);
  border: 1px solid var(--line);
  padding: clamp(28px, 2.9vw, 40px);
  overflow: hidden;
  transition: transform var(--dur) var(--ease), box-shadow var(--dur) var(--ease),
              border-color var(--dur) var(--ease), background var(--dur) var(--ease);
}
/* one cyan accent, drawn on hover — the only ornament on the card */
.card::before {
  content: '';
  position: absolute;
  inset: 0 0 auto 0;
  height: 2px;
  background: var(--cyan);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform .45s var(--ease);
}
.card:hover {
  transform: translateY(-4px);
  border-color: transparent;
  box-shadow: 0 22px 44px -26px rgba(11,14,15,.34), 0 2px 8px -4px rgba(11,14,15,.08);
}
.card:hover::before { transform: scaleX(1); }

.card svg {
  width: 46px;
  height: 46px;
  stroke: var(--cyan);
  fill: none;
  stroke-width: 1.3;
  margin-bottom: clamp(22px, 2.4vw, 30px);
  transition: transform var(--dur) var(--ease);
}
.card:hover svg { transform: translateY(-3px); }

.card h3 {
  font-size: clamp(16px, 1.35vw, 18px);
  font-weight: 800;
  letter-spacing: .015em;
  line-height: 1.25;
  margin-bottom: 14px;
}
.card p {
  color: var(--muted);
  font-size: 15.5px;
  line-height: 1.62;
  text-wrap: pretty;
}

/* dark sections keep the same anatomy, just inverted */
.section--dark .card { background: var(--ink-2); border-color: var(--line-d); }
.section--dark .card:hover {
  background: #12171a;
  border-color: rgba(34,178,203,.34);
  box-shadow: 0 22px 46px -26px rgba(0,0,0,.9);
}
.section--dark .card svg { stroke: var(--cyan-bright); }
.section--dark .card p { color: rgba(255,255,255,.66); }

/* numbered process cards */
.card__num {
  font-family: var(--f-display);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .2em;
  color: var(--cyan);
  padding-bottom: 14px;
  margin-bottom: 20px;
  border-bottom: 2px solid rgba(1,146,169,.22);
  transition: border-color var(--dur) var(--ease);
}
.card:hover .card__num { border-bottom-color: var(--cyan); }
.section--dark .card__num { color: var(--cyan-bright); border-bottom-color: rgba(34,178,203,.28); }

/* Gallery — 9 tiles on a fixed 3-up grid so rows always fill exactly */
.gallery { display: grid; grid-template-columns: repeat(3, 1fr); gap: 14px; }
.shot {
  position: relative;
  /* PRE-EXISTING BUG, fixed 2026-08-12. <figure> carries a UA default of
     `margin: 1em 40px` and the reset never zeroed it, so every gallery tile
     was inset 40px each side and rendered ~292px inside a 372px column.
     services.html had been patching it per-element with an inline margin:0.
     Zeroing it here fixes the gallery and makes that inline redundant. */
  margin: 0;
  aspect-ratio: 4 / 3;
  overflow: hidden;
  background: var(--ink-2);
}
.shot img { width: 100%; height: 100%; object-fit: cover; transition: transform .85s var(--ease), filter .85s var(--ease); }
.shot figcaption {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  padding: 26px 22px 20px;
  background: linear-gradient(0deg, rgba(6,8,9,.9), transparent);
  font-family: var(--f-display);
  font-size: 12.5px;
  font-weight: 700;
  letter-spacing: .13em;
  text-transform: uppercase;
  color: #fff;
}
.shot:hover img { transform: scale(1.06); }

/* ============================================================
   About — story (copy + layered media)
   ============================================================ */
.story {
  background: var(--paper);
  padding-block: clamp(56px, 7vw, 100px);
  /* extra room at the base: the clip hangs below the photo */
  padding-bottom: clamp(76px, 8vw, 112px);
}
.storygrid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, .9fr);
  gap: clamp(34px, 5vw, 78px);
  align-items: center;
}

.storygrid__copy h2 {
  font-size: clamp(30px, 4vw, 50px);
  font-weight: 900;
  line-height: 1.02;
  letter-spacing: -.025em;
  text-wrap: balance;
}
.storygrid__copy h2 .hl { color: var(--cyan); }
/* keeps the hyphenated compound from splitting across lines */
.storygrid__copy h2 .nb { white-space: nowrap; }

.storygrid__copy p { margin-top: 20px; max-width: 56ch; color: var(--muted); font-size: 16.5px; text-wrap: pretty; }
/* first paragraph carries the weight (two classes outrank the rule above) */
.storygrid__copy .story__lede {
  margin-top: clamp(24px, 3vw, 32px);
  font-size: clamp(17.5px, 1.9vw, 20px);
  line-height: 1.55;
  color: var(--text);
}
/* service areas as a solid fact panel rather than a faint aside */
.storygrid__copy .story__areas {
  margin-top: clamp(28px, 3.4vw, 38px);
  padding: clamp(18px, 2.2vw, 24px) clamp(20px, 2.4vw, 26px);
  background: var(--ink);
  border-left: 3px solid var(--cyan);
  color: rgba(255,255,255,.82);
  font-size: 14.5px;
  line-height: 1.6;
  max-width: none;
}

/* ---- layered media ---- */
.storymedia { position: relative; }
.storymedia__base {
  width: 100%;
  /* height:auto is required — the img's height attribute is a presentational
     hint that otherwise wins and aspect-ratio never takes effect */
  height: auto;
  aspect-ratio: 1 / 1;
  object-fit: cover;
  object-position: 60% 50%;   /* keeps the two installers in frame */
  display: block;
}

.storymedia__clip {
  position: absolute;
  left: clamp(-40px, -2.4vw, -18px);
  bottom: clamp(-44px, -2.6vw, -20px);
  width: 62%;
  margin: 0;
  /* white mat + shadow so it separates from the photograph underneath */
  padding: 7px;
  background: var(--paper);
  box-shadow: 0 26px 54px -22px rgba(11,14,15,.55);
  transition: transform var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}
.storymedia__clip video {
  display: block;
  width: 100%;
  aspect-ratio: 710 / 274;
  object-fit: cover;
  background: var(--ink);
}
/* brand rule along the base of the card */
.storymedia__clip::after {
  content: '';
  position: absolute;
  left: 7px; right: 7px; bottom: 0;
  height: 3px;
  background: linear-gradient(90deg, var(--cyan), var(--cyan-pale) 60%, transparent);
}
.storymedia__clip:hover {
  transform: translateY(-5px);
  box-shadow: 0 34px 64px -22px rgba(11,14,15,.6);
}

@media (max-width: 900px) {
  .storygrid { grid-template-columns: 1fr; gap: 30px; }
  .storygrid__copy { order: 2; }
  .storymedia { order: 1; margin-bottom: 26px; }
  .storymedia__base { aspect-ratio: 3 / 2; }
  .storymedia__clip { width: 66%; left: -12px; bottom: -26px; }
}

@media (max-width: 520px) {
  .storymedia__clip { width: 74%; left: -8px; bottom: -22px; padding: 5px; }
}

/* ============================================================
   Hiring page
   ============================================================ */
/* Centred statement block. Width is set in px for the heading; the paragraph
   gets its own ch limit, because a ch cap here throttles the much larger h2. */
/* Same anatomy as .srvhead: heading left, intro right, one hairline under both.
   This replaced a 780px centred stack whose ragged centred paragraph and pill
   chips read as a template. Centred type has no left edge for the eye to track,
   which is most of why the old version looked unprofessional. */
.joinlede__head {
  display: grid;
  /* 34% aside, same as .srvhead: any wider and "surface protection." breaks across
     two lines instead of holding the intended two-line title */
  grid-template-columns: 1fr minmax(260px, 34%);
  gap: clamp(22px, 4vw, 70px);
  align-items: end;
  padding-bottom: clamp(24px, 3vw, 36px);
  border-bottom: 1px solid var(--line);
}
.joinlede h2 {
  margin-top: 14px;
  font-size: clamp(30px, 4.4vw, 54px);
  font-weight: 900;
  line-height: 1.02;
  letter-spacing: -.025em;
}
.joinlede h2 .hl { color: var(--cyan); }
.joinlede__aside p {
  color: var(--muted);
  font-size: clamp(15.5px, 1.55vw, 17.5px);
  line-height: 1.62;
  text-wrap: pretty;
}
/* Cities as a typographic run with the hero's cyan tick separators. The old pill
   chips looked like disabled buttons, and with seven of them the seventh always
   orphaned onto a centred line of its own. */
.joinlede__markets {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 10px clamp(16px, 2vw, 26px);
  margin-top: clamp(20px, 2.4vw, 28px);
}
.joinlede__label {
  flex: none;
  font-family: var(--f-display);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--muted-2, #8b9497);
}
.joinlede__cities { display: flex; align-items: baseline; flex-wrap: wrap; gap: 8px 14px; }
.joinlede__cities span {
  font-family: var(--f-display);
  font-size: clamp(11.5px, 1.1vw, 13px);
  font-weight: 700;
  letter-spacing: .15em;
  text-transform: uppercase;
  color: var(--text);
}
/* separator hangs off the END, so a wrapped row never starts with a tick */
.joinlede__cities span:not(:last-child)::after {
  content: '';
  display: inline-block;
  width: 4px; height: 4px;
  margin-left: 14px;
  vertical-align: 2px;
  background: var(--cyan);
}
@media (max-width: 820px) {
  .joinlede__head { grid-template-columns: 1fr; align-items: start; }
  .joinlede__cities span:not(:last-child)::after { display: none; }
}

/* Roles — a plain hairline list, deliberately lighter than the card decks */
/* Brand mascot beside the roles. He lives on THIS section for two reasons: a figure
   in company uniform belongs on the recruiting page, and the film sheet he is holding
   is genuinely semi-transparent in the artwork, so it only reads as film over a dark
   ground. On white it would flatten to a pale blob. */
.roleswrap {
  display: grid;
  grid-template-columns: 1fr minmax(240px, 30%);
  gap: clamp(20px, 4vw, 64px);
  align-items: end;
}
.roleswrap__figure { align-self: end; }
.roleswrap__figure img {
  display: block;
  width: 100%;
  height: auto;
  /* he is drawn cropped at the waist, so seat him ON the section floor rather than
     leaving a gap that reads as a mistake */
  margin-bottom: calc(clamp(64px, 9vw, 118px) * -1);
}
/* Below the two-column break he would sit under a long list and just add scroll. */
@media (max-width: 900px) {
  .roleswrap { grid-template-columns: 1fr; }
  .roleswrap__figure { display: none; }
}

.rolelist {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  column-gap: clamp(28px, 5vw, 80px);
  border-top: 1px solid var(--line-d);
}
.role {
  padding: clamp(20px, 2.3vw, 28px) 0;
  border-bottom: 1px solid var(--line-d);
}
.role h3 {
  font-size: clamp(15px, 1.5vw, 17.5px);
  font-weight: 800;
  letter-spacing: .015em;
  color: #fff;
  margin-bottom: 7px;
  transition: color var(--dur) var(--ease);
}
.role p { color: rgba(255,255,255,.6); font-size: 15.5px; }
.role:hover h3 { color: var(--cyan-bright); }
.rolelist__note {
  margin-top: clamp(26px, 3vw, 36px);
  color: rgba(255,255,255,.5);
  font-size: 15.5px;
}

/* Application form on a single raised card — one obvious thing to do */
.formcard {
  max-width: 880px;
  margin-inline: auto;
  background: var(--paper);
  border: 1px solid var(--line);
  box-shadow: 0 30px 70px -46px rgba(11,14,15,.4);
  padding: clamp(28px, 4vw, 56px);
}
.formcard__head { margin-bottom: clamp(28px, 3.4vw, 40px); }
.formcard__head h2 { font-size: clamp(25px, 3.1vw, 36px); font-weight: 800; line-height: 1.08; }
.formcard__head h2 .hl { color: var(--cyan); }
.formcard__head p {
  margin-top: 14px;
  max-width: 58ch;
  color: var(--muted);
  font-size: 16px;
  text-wrap: pretty;
}
.formcard__head a { color: var(--cyan); font-weight: 600; }
.formcard__head a:hover { text-decoration: underline; }

.field__opt {
  text-transform: none;
  letter-spacing: 0;
  font-weight: 400;
  color: #9aa5a8;
}

@media (max-width: 720px) {
  .rolelist { grid-template-columns: 1fr; }
}

/* ============================================================
   FAQ
   ============================================================ */
.faqlayout {
  display: grid;
  grid-template-columns: minmax(0, .78fr) minmax(0, 1.22fr);
  gap: clamp(32px, 5vw, 72px);
  align-items: start;
}
.faqlayout__side { position: sticky; top: calc(var(--header-h) + 40px); }
.faqside h2 { font-size: clamp(28px, 3.4vw, 42px); font-weight: 800; line-height: 1.05; }
.faqside h2 .hl { color: var(--cyan); }
.faqside > p { margin-top: 16px; max-width: 34ch; color: var(--muted); }

.faqside__card {
  margin-top: clamp(28px, 3.4vw, 40px);
  padding: clamp(24px, 2.6vw, 32px);
  background: var(--ink);
  color: #fff;
}
.faqside__card h3 { font-size: 17px; font-weight: 800; letter-spacing: .02em; }
.faqside__card p { margin: 12px 0 22px; color: rgba(255,255,255,.66); font-size: 15px; }
.faqside__tel {
  display: block;
  margin-top: 18px;
  font-family: var(--f-display);
  font-size: 13px;
  font-weight: 700;
  letter-spacing: .1em;
  color: var(--cyan-bright);
}
.faqside__tel:hover { color: #fff; }

/* --- accordion --- */
.faq { display: flex; flex-direction: column; gap: 10px; }

/* Categories are the outer accordion. Only the OPEN one is dark: five black slabs
   stacked next to the dark side card was far too much black on one page. Closed
   bars are light with a fine diagonal hatch, so they still have a surface of their
   own against the tinted section without adding mass. The hatch is a hard-edged
   1px line pattern, NOT a soft gradient fade. */
.faqcat {
  position: relative;
  background: var(--paper);
  border: 1px solid var(--line);
  overflow: hidden;
  transition: border-color var(--dur) var(--ease);
}
/* cyan rail down the whole open category, same language as the question cards */
.faqcat::before {
  content: '';
  position: absolute;
  left: 0; top: 0; bottom: 0;
  width: 3px;
  z-index: 2;
  background: var(--cyan);
  transform: scaleY(0);
  transform-origin: top;
  transition: transform .4s var(--ease);
}
.faqcat[open]::before { transform: scaleY(1); }
/* Hatch lives on the BAR, not on .faqcat, or it would also wash over the white
   question cards inside an open category. Opacity is baked into the SVG stroke. */
.faqcat__sum {
  position: relative;
  background-color: var(--paper);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='9' height='9'%3E%3Cpath d='M0 9L9 0' stroke='%230b0e0f' stroke-opacity='.045' stroke-width='1'/%3E%3C/svg%3E");
  transition: background-color var(--dur) var(--ease);
}
.faqcat[open] .faqcat__sum {
  background-color: var(--ink);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='9' height='9'%3E%3Cpath d='M0 9L9 0' stroke='%23ffffff' stroke-opacity='.05' stroke-width='1'/%3E%3C/svg%3E");
}
.faqcat__sum {
  list-style: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 16px;
  padding: clamp(17px, 1.9vw, 22px) clamp(18px, 2vw, 26px);
}
.faqcat__sum::-webkit-details-marker { display: none; }
.faqcat__title {
  font-family: var(--f-display);
  font-size: clamp(14px, 1.5vw, 16.5px);
  font-weight: 800;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--text);
  transition: color var(--dur) var(--ease);
}
.faqcat[open] .faqcat__title { color: #fff; }
.faqcat__count {
  font-size: 12.5px;
  color: var(--muted);
  white-space: nowrap;
  transition: color var(--dur) var(--ease);
}
.faqcat[open] .faqcat__count { color: rgba(255,255,255,.5); }
.faqcat__ic {
  position: relative;
  flex: none;
  margin-left: auto;
  width: 26px; height: 26px;
  border: 1px solid var(--line);
  transition: transform var(--dur) var(--ease), background-color var(--dur) var(--ease),
              border-color var(--dur) var(--ease);
}
.faqcat__ic::before, .faqcat__ic::after {
  content: '';
  position: absolute;
  left: 50%; top: 50%;
  background: var(--text);
  transition: background-color var(--dur) var(--ease);
}
.faqcat[open] .faqcat__ic::before,
.faqcat[open] .faqcat__ic::after { background: #fff; }
.faqcat__ic::before { width: 11px; height: 2px; transform: translate(-50%, -50%); }
.faqcat__ic::after  { width: 2px; height: 11px; transform: translate(-50%, -50%); }
.faqcat__sum:hover .faqcat__title { color: var(--cyan); }
.faqcat__sum:hover .faqcat__ic { border-color: var(--cyan); }
.faqcat[open] .faqcat__sum:hover .faqcat__title { color: var(--cyan-bright); }
.faqcat[open] .faqcat__ic {
  background: var(--cyan);
  border-color: var(--cyan);
  transform: rotate(180deg);
}
/* only the vertical bar retracts, leaving a minus */
.faqcat[open] .faqcat__ic::after { transform: translate(-50%, -50%) scaleY(0); }
.faqcat__a { overflow: hidden; }
/* the questions sit on the tint, not on the dark bar */
.faqcat__a-in {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 14px clamp(10px, 1.2vw, 14px) clamp(14px, 1.6vw, 18px);
  background: var(--paper-2);
}
.faq__item {
  background: var(--paper);
  border: 1px solid var(--line);
  transition: border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease),
              transform var(--dur) var(--ease);
}
.faq__item:hover { border-color: #cfd6d9; }
.faq__item[open] {
  border-color: transparent;
  box-shadow: 0 22px 46px -28px rgba(11,14,15,.4);
}
/* cyan rail down the open item */
.faq__item::before {
  content: '';
  position: absolute;
  left: 0; top: 0; bottom: 0;
  width: 3px;
  background: var(--cyan);
  transform: scaleY(0);
  transform-origin: top;
  transition: transform .4s var(--ease);
}
.faq__item { position: relative; }
.faq__item[open]::before { transform: scaleY(1); }

.faq__item > summary {
  list-style: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: clamp(14px, 1.8vw, 22px);
  padding: clamp(20px, 2.2vw, 26px) clamp(18px, 2.2vw, 28px);
}
.faq__item > summary::-webkit-details-marker { display: none; }

.faq__n {
  flex: none;
  font-family: var(--f-display);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .14em;
  color: var(--cyan);
  transition: color var(--dur) var(--ease);
}
.faq__q {
  flex: 1;
  font-family: var(--f-display);
  font-size: clamp(15px, 1.65vw, 18px);
  font-weight: 700;
  letter-spacing: .01em;
  line-height: 1.3;
  text-transform: uppercase;
  transition: color var(--dur) var(--ease);
}
.faq__item > summary:hover .faq__q { color: var(--cyan); }

/* + / − mark, rotates to a minus when open */
.faq__ic {
  position: relative;
  flex: none;
  width: 34px; height: 34px;
  border: 1px solid var(--line);
  border-radius: 50%;
  transition: background var(--dur) var(--ease), border-color var(--dur) var(--ease),
              transform var(--dur) var(--ease);
}
.faq__ic::before, .faq__ic::after {
  content: '';
  position: absolute;
  left: 50%; top: 50%;
  background: var(--cyan);
  transition: transform .42s var(--ease), background var(--dur) var(--ease);
}
.faq__ic::before { width: 12px; height: 2px; transform: translate(-50%, -50%); }
.faq__ic::after  { width: 2px; height: 12px; transform: translate(-50%, -50%); }
.faq__item > summary:hover .faq__ic { border-color: var(--cyan); transform: rotate(90deg); }
.faq__item[open] .faq__ic { background: var(--cyan); border-color: var(--cyan); transform: rotate(180deg); }
.faq__item[open] .faq__ic::before { background: #fff; }
.faq__item[open] .faq__ic::after { transform: translate(-50%, -50%) scaleY(0); background: #fff; }
.faq__item[open] .faq__q { color: var(--cyan); }

/* height is driven by JS so it can transition; overflow hides the reveal */
.faq__a { overflow: hidden; }
.faq__a-in {
  padding: 0 clamp(18px, 2.2vw, 28px) clamp(22px, 2.4vw, 28px) calc(clamp(18px, 2.2vw, 28px) + 34px + clamp(14px, 1.8vw, 22px));
  max-width: 66ch;
  color: var(--muted);
  line-height: 1.65;
  text-wrap: pretty;
  opacity: 0;
  transform: translateY(-6px);
  transition: opacity .34s var(--ease) .06s, transform .34s var(--ease) .06s;
}
.faq__item[open] .faq__a-in { opacity: 1; transform: none; }

@media (max-width: 900px) {
  .faqlayout { grid-template-columns: 1fr; }
  .faqlayout__side { position: static; }
  .faq__a-in { padding-left: clamp(18px, 2.2vw, 28px); }
}

/* ============================================================
   Reviews
   ============================================================ */
/* Google summary band. The four-colour G and the gold stars are the whole point
   here: they are the only two marks a visitor reads as "these came from Google"
   without having to read any copy, so both stay in Google's colours and are NOT
   restyled to the site's cyan. */
/* Dark, because the section is light. The previous white-on-tint version had a 2%
   luminance gap between the band, the cards and the ground, so nothing carried any
   weight. One black anchor gives the gold and the four Google colours something to
   sit against, and it is a single object rather than a second dark BAND stacked
   under the process section above. */
.gsum {
  display: flex;
  align-items: center;
  gap: clamp(20px, 3vw, 40px);
  flex-wrap: wrap;
  margin-bottom: clamp(18px, 2vw, 26px);
  padding: clamp(24px, 2.8vw, 34px) clamp(26px, 3vw, 38px);
  background: var(--ink);
  box-shadow: 0 26px 60px -34px rgba(11,14,15,.6);
}
.glogo { width: 40px; height: 40px; flex: none; display: block; }
/* Label, stars and attribution stack as one unit. An earlier pass floated the
   stars on their own between the logo and the CTA and they read as orphaned,
   with a dead 330px gap either side. */
.gsum__text { display: flex; flex-direction: column; gap: 9px; }
.gsum__label {
  font-family: var(--f-display);
  font-size: clamp(17px, 1.9vw, 21px);
  font-weight: 800;
  letter-spacing: .01em;
  text-transform: uppercase;
  color: #fff;
  line-height: 1.1;
}
.gsum__stars { display: inline-flex; gap: 3px; }
.gsum__stars svg { width: 26px; height: 26px; fill: var(--gold); }
.gsum__count { font-size: 13.5px; color: rgba(255,255,255,.6); }
.gsum__cta { margin-left: auto; }
@media (max-width: 860px) {
  .gsum__cta { margin-left: 0; width: 100%; }
}

.reviewgrid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(16px, 1.8vw, 24px);
}
/* Elevation is ON by default now. These used to be a 1px hairline on a tint that
   was 2% off white, so the cards read as flat panels rather than surfaces, and all
   the lift only appeared on hover where most visitors never see it. The gold top
   rule carries the star colour through the whole deck. */
.review {
  position: relative;
  display: flex;
  flex-direction: column;
  margin: 0;
  padding: clamp(26px, 2.8vw, 36px);
  background: var(--paper);
  box-shadow: 0 2px 4px rgba(11,14,15,.04), 0 14px 34px -22px rgba(11,14,15,.28);
  transition: transform var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}
.review::before {
  content: '';
  position: absolute;
  left: 0; right: 0; top: 0;
  height: 3px;
  background: var(--gold);
}
.review:hover {
  transform: translateY(-5px);
  box-shadow: 0 4px 8px rgba(11,14,15,.05), 0 30px 58px -26px rgba(11,14,15,.4);
}

.review__top {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  margin-bottom: 18px;
}
/* Gold, not the site cyan: a five-star row only reads as a rating if it is the
   colour every review platform uses. This is Google's own star amber. */
.review__stars { display: inline-flex; gap: 3px; }
.review__stars svg { width: 18px; height: 18px; fill: var(--gold); }

.review__tags { display: inline-flex; gap: 6px; flex-wrap: wrap; }
.review__tags span {
  padding: 3px 9px;
  background: var(--paper-2);
  border: 1px solid var(--line);
  font-family: var(--f-display);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--muted);
}

.review blockquote {
  margin: 0 0 26px;
  flex: 1;                       /* pushes every attribution to the same baseline */
  font-size: 16.5px;
  line-height: 1.66;
  color: var(--text);
  text-wrap: pretty;
}

/* Small G at the end of the attribution row, the way a Google review card is
   laid out. margin-left:auto so it pins right whatever the name length. */
.review figcaption { display: flex; align-items: center; gap: 12px; }
.review figcaption .glogo { width: 19px; height: 19px; margin-left: auto; }
.review__avatar {
  flex: none;
  display: grid;
  place-items: center;
  width: 40px; height: 40px;
  border-radius: 50%;
  background: var(--ink);
  color: #fff;
  font-family: var(--f-display);
  font-size: 12.5px;
  font-weight: 700;
  letter-spacing: .04em;
}
.review__who { display: flex; flex-direction: column; min-width: 0; }
.review__who b {
  font-size: 14.5px;
  font-weight: 600;
  color: var(--text);
  line-height: 1.3;
  overflow-wrap: anywhere;       /* hyphenated surnames */
}
.review__who em {
  font-style: normal;
  font-size: 12.5px;
  color: var(--muted-d);
  margin-top: 2px;
}

@media (max-width: 1000px) { .reviewgrid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 720px)  { .reviewgrid { grid-template-columns: 1fr; } }

/* Forms */
.form { display: grid; gap: 20px; grid-template-columns: repeat(2, 1fr); }
.field { display: flex; flex-direction: column; gap: 9px; }
.field--full { grid-column: 1 / -1; }
.field label {
  font-family: var(--f-display);
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--muted);
}
.field input, .field select, .field textarea {
  font-family: var(--f-body);
  font-size: 16px;
  color: var(--text);
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: 0;
  padding: 15px 16px;
  transition: border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
  width: 100%;
}
.field textarea { min-height: 138px; resize: vertical; }
.field input:focus, .field select:focus, .field textarea:focus {
  outline: none;
  border-color: var(--cyan);
  box-shadow: 0 0 0 3px rgba(1,146,169,.15);
}
.form__note { grid-column: 1 / -1; color: var(--muted); font-size: 14px; line-height: 1.6; text-wrap: pretty; }
/* required marker. Cyan rather than a red asterisk: nothing has gone wrong yet, so
   this is a label, not an error. */
.req { color: var(--cyan); }
/* the browser's own bubble is suppressed by novalidate, so failures are shown here */
.field input[aria-invalid='true'], .field select[aria-invalid='true'] { border-color: #c0392b; }
.field__err {
  display: none;
  color: #c0392b;
  font-size: 13px;
}
.field.is-invalid .field__err { display: block; }
.form__ok {
  grid-column: 1 / -1;
  padding: 16px 18px;
  background: rgba(1,146,169,.09);
  border-left: 3px solid var(--cyan);
  color: var(--text);
  font-size: 15.5px;
}

.split { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: clamp(30px, 5vw, 70px); align-items: start; }
/* form + sidebar: asymmetric on desktop, stacked once there is no room.
   Tighter gutter than the generic .split: that one separates two full-width
   content blocks, whereas here a ~390px panel sits beside the form and the
   inherited 70px trench read as a hole in the layout. */
.split--aside {
  grid-template-columns: minmax(0, 1.5fr) minmax(0, .85fr);
  gap: clamp(28px, 3.2vw, 46px);
}
@media (max-width: 860px) { .split--aside { grid-template-columns: 1fr; } }

.statline { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 1px; background: var(--line-d); }
.stat { background: var(--ink); padding: clamp(24px, 3vw, 34px); }
.stat b { display: block; font-family: var(--f-display); font-size: clamp(30px, 4.4vw, 48px); font-weight: 900; letter-spacing: -.02em; color: var(--cyan-bright); line-height: 1; }
.stat span { display: block; margin-top: 10px; font-size: 14.5px; color: rgba(255,255,255,.66); }

/* ============================================================
   Video lightbox
   ============================================================ */
.lightbox {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: grid;
  place-items: center;
  padding: var(--gut);
  background: rgba(4,6,7,.9);
  backdrop-filter: blur(10px);
  opacity: 0;
  visibility: hidden;
  transition: opacity var(--dur) var(--ease), visibility var(--dur);
}
.lightbox.is-open { opacity: 1; visibility: visible; }
.lightbox__body { width: min(1080px, 100%); position: relative; transform: scale(.97); transition: transform var(--dur) var(--ease); }
.lightbox.is-open .lightbox__body { transform: none; }
.lightbox video { width: 100%; height: auto; background: #000; }
.lightbox__close {
  position: absolute;
  top: -50px; right: 0;
  display: inline-flex;
  align-items: center;
  gap: 9px;
  color: #fff;
  font-family: var(--f-display);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .16em;
  text-transform: uppercase;
}
.lightbox__close:hover { color: var(--cyan-bright); }

/* ============================================================
   Toast — small transient notice, bottom centre
   ============================================================ */
/* Centred with left/right + auto margins, NOT left:50% + translateX(-50%). Under
   the 50% version the shrink-to-fit width can only use the half-viewport to the
   right of the anchor, so on a 390px phone the notice came out 195px wide and
   five lines tall. This way it sizes to its text and stays centred. */
.toast {
  position: fixed;
  left: 16px;
  right: 16px;
  bottom: 28px;
  z-index: 200;
  width: fit-content;
  max-width: min(440px, 100%);
  margin-inline: auto;
  padding: 14px 20px;
  background: var(--ink-2);
  border: 1px solid var(--line-d);
  border-left: 2px solid var(--cyan-bright);
  box-shadow: 0 18px 44px rgba(0,0,0,.5);
  color: rgba(255,255,255,.92);
  font-size: 14.5px;
  line-height: 1.45;
  transform: translateY(14px);
  opacity: 0;
  visibility: hidden;
  transition: opacity var(--dur) var(--ease), transform var(--dur) var(--ease),
              visibility 0s linear var(--dur);
}
.toast.is-open {
  opacity: 1;
  visibility: visible;
  transform: none;
  transition-delay: 0s;
}
@media (prefers-reduced-motion: reduce) {
  .toast { transition: opacity .01s, visibility 0s; transform: none; }
}

/* ============================================================
   Hero entrance — staggered, runs once on load
   ============================================================ */
@keyframes heroRise {
  from { opacity: 0; transform: translateY(26px); }
  to   { opacity: 1; transform: none; }
}
.hero__copy > * {
  opacity: 0;
  animation: heroRise .9s var(--ease) forwards;
}
.hero__copy > *:nth-child(1) { animation-delay: .10s; }
.hero__copy > *:nth-child(2) { animation-delay: .20s; }
.hero__copy > *:nth-child(3) { animation-delay: .32s; }
.hero__copy > *:nth-child(4) { animation-delay: .44s; }
.hero__copy > *:nth-child(5) { animation-delay: .56s; }

@media (prefers-reduced-motion: reduce) {
  .hero__copy > * { opacity: 1; animation: none; }
}

/* ============================================================
   Reveal-on-scroll
   ============================================================ */
.rv { opacity: 0; transform: translateY(20px); transition: opacity .7s var(--ease), transform .7s var(--ease); }
.rv.in { opacity: 1; transform: none; }

/* ============================================================
   Responsive
   ============================================================ */
/* Below the wrap width there is no longer room for copy + three tiles side by
   side without squeezing the tiles into slivers — stack instead. */
@media (max-width: 1240px) {
  .about__split { grid-template-columns: 1fr; }
  .about__copy { padding: clamp(48px, 8vw, 72px) var(--edge); }
  .tile { min-height: 300px; }
}

@media (max-width: 1000px) {
  /* 6 and 4 card decks both divide by 2 — still no empty cells */
  .cards--3, .cards--4 { grid-template-columns: repeat(2, 1fr); }
  .foot__offices li { flex-basis: calc((100% - var(--off-gap)) / 2); }
}

@media (max-width: 900px) {
  :root { --header-h: 68px; }
  .hdr__nav, .hdr__cta { display: none; }
  .burger { display: flex; }
  .hdr__logo img { height: 36px; }

  /* 6 items divide evenly into 3 and 2, so the gap grid never leaves a hole */
  .surfaces__grid { grid-template-columns: repeat(3, 1fr); }
  .surface { padding: 30px 12px 26px; }

  .foot { grid-template-columns: 1fr; justify-items: center; text-align: center; gap: 30px; }
  .foot__contact { align-items: center; }
  .foot__legal { justify-content: center; text-align: center; }
  .foot__brands { justify-content: center; }
  .foot__offices li { flex-basis: calc((100% - var(--off-gap)) / 2); }

  .gallery { grid-template-columns: repeat(2, 1fr); }
}

@media (max-width: 640px) {
  /* one per row so the full address still fits on a single line */
  .foot__offices li { flex-basis: 100%; }
}

@media (max-width: 620px) {
  .cards--3, .cards--4 { grid-template-columns: 1fr; }
  .gallery { grid-template-columns: 1fr; }
}

@media (max-width: 720px) {
  body { font-size: 16px; }
  .hero { min-height: 84vh; }
  /* Vertical scrim reads better than a side gradient on a narrow screen */
  .hero__media::after {
    background:
      linear-gradient(180deg, rgba(6,8,9,.7) 0%, rgba(6,8,9,.62) 42%, rgba(6,8,9,.9) 100%);
  }
  .hero__copy { max-width: none; }
  .hero__sub { max-width: 34ch; }
  .hero__actions { gap: 18px; }
  .hero__actions .btn { width: 100%; }

  .about__tiles { grid-template-columns: 1fr; }
  .tile { min-height: 232px; }
  .tile + .tile { border-left: 0; border-top: 1px solid rgba(255,255,255,.16); }

  /* the band is centred at every width now; only the actions need to stack */
  .ctaband__actions { flex-direction: column; gap: 22px; width: 100%; }
  .ctaband__actions .btn { width: 100%; }

  .form { grid-template-columns: 1fr; }
  .lightbox__close { top: -44px; }
}

@media (max-width: 520px) {
  .surfaces__grid { grid-template-columns: repeat(2, 1fr); }
  .surface { padding: 26px 10px 22px; gap: 14px; }
}

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

/* ============================================================
   Legal pages (privacy, terms) — long-form prose, one column
   ============================================================ */
.legal { max-width: 76ch; }
.legal__meta {
  font-family: var(--f-display);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--muted-d);
}
.legal__note {
  margin-top: 26px;
  padding: 18px 20px;
  background: var(--paper-2);
  border-left: 2px solid var(--cyan);
  font-size: 14.5px;
  line-height: 1.6;
  color: var(--muted);
}
.legal h2 {
  margin-top: clamp(38px, 4.4vw, 56px);
  font-size: clamp(19px, 2vw, 24px);
  font-weight: 800;
  text-transform: none;
  letter-spacing: -.01em;
}
.legal h2 + p, .legal h2 + ul { margin-top: 14px; }
.legal p, .legal li {
  font-size: 16px;
  line-height: 1.72;
  color: var(--muted);
  text-wrap: pretty;
}
.legal p + p, .legal ul + p { margin-top: 16px; }
.legal p + ul { margin-top: 14px; }
.legal ul { margin: 0; padding-left: 22px; display: grid; gap: 9px; }
.legal a { color: var(--cyan); text-decoration: underline; text-underline-offset: 3px; }
.legal a:hover { color: var(--ink); }

/* ============================================================
   Services index — photo-led surface grid
   Deliberately not the .card treatment: the client rejected bordered
   cells and icon plates here, so the photography carries the section
   and type does the rest. No boxes, no plates, no glow.
   ============================================================ */
.srvhead {
  display: grid;
  grid-template-columns: 1fr minmax(260px, 34%);
  gap: clamp(22px, 4vw, 70px);
  align-items: end;
  padding-bottom: clamp(24px, 3vw, 36px);
  border-bottom: 1px solid var(--line);
  margin-bottom: clamp(32px, 4.2vw, 52px);
}
.srvhead h2 { font-size: clamp(31px, 4.6vw, 56px); font-weight: 900; line-height: 1.02; }
.srvhead h2 .hl { color: var(--cyan); }
.srvhead__aside p {
  color: var(--muted);
  font-size: clamp(15.5px, 1.5vw, 17px);
  text-wrap: pretty;
}

.arrowlink {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  margin-top: 16px;
  font-family: var(--f-display);
  font-size: 12.5px;
  font-weight: 700;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--cyan);
}
.arrowlink svg { width: 22px; height: 10px; transition: transform var(--dur) var(--ease); }
.arrowlink:hover svg { transform: translateX(5px); }

.srvgrid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(22px, 2.6vw, 40px) clamp(18px, 2.2vw, 32px);
}
.srv { margin: 0; }
.srv__fig {
  margin: 0 0 clamp(18px, 1.8vw, 24px);
  aspect-ratio: 1 / 1;
  overflow: hidden;              /* the scale-on-hover has to be clipped */
  background: var(--paper-2);    /* holds the box while the photo decodes */
}
.srv__fig img {
  width: 100%; height: 100%;
  object-fit: cover;
  transition: transform .9s var(--ease);
}
.srv:hover .srv__fig img { transform: scale(1.05); }

.srv__n {
  display: inline-block;
  font-family: var(--f-display);
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: .18em;
  color: var(--cyan);
}
/* the rule grows under the number on hover — the restrained cue the client
   approved on the homepage band, reused here instead of a card border */
.srv__n::after {
  content: '';
  display: block;
  width: 100%;
  height: 2px;
  margin-top: 7px;
  background: var(--cyan);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--dur) var(--ease);
}
.srv:hover .srv__n::after { transform: scaleX(1); }

.srv h3 {
  margin-top: 12px;
  font-size: clamp(16.5px, 1.5vw, 19px);
  font-weight: 800;
  letter-spacing: -.008em;
}
.srv__body p {
  margin-top: 11px;
  color: var(--muted);
  font-size: 15.5px;
  line-height: 1.62;
  text-wrap: pretty;
}

@media (max-width: 1000px) {
  .srvhead { grid-template-columns: 1fr; align-items: start; }
  .srvgrid { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 600px) {
  .srvgrid { grid-template-columns: 1fr; gap: 34px; }
  .srv__fig { aspect-ratio: 4 / 3; }
}

/* ============================================================
   Quote page — direct-contact aside
   ============================================================ */
/* The aside column runs ~700px shorter than the form beside it, so the bottom of
   that column was dead white space. The brand mascot fills it. He has to sit on a
   DARK ground: the film sheet he is holding is genuinely semi-transparent in the
   artwork and flattens to a pale blob on white (same reason he is on the dark band
   on join.html). */
.qaside {
  --qaside-pad: clamp(28px, 3.4vw, 40px);
  background: var(--ink);
  color: #fff;
  padding: var(--qaside-pad);
  overflow: hidden;
}
.qaside__figure {
  /* Inset to the panel's own padding so he lines up with the text above him.
     He used to be full-bleed to the panel edges, which read as cramped against
     the box. Still flush to the FLOOR, so the artwork's mid-thigh crop lands on
     the panel edge and reads as him standing on it rather than being cut off. */
  margin: clamp(18px, 2.2vw, 28px) 0 calc(var(--qaside-pad) * -1);
}
.qaside__figure img { display: block; width: 100%; height: auto; }

/* Below 860px the aside goes full page width, where a full-bleed figure would be
   enormous. Cap him and stand him at the right edge instead. */
@media (max-width: 860px) {
  .qaside__figure { max-width: 210px; margin-left: auto; }
}

/* ============================================================
   Modal — form confirmation popup
   ============================================================ */
/* Same open/close mechanics as .lightbox (is-open + aria-hidden, Escape and
   backdrop both close) so there is one modal behaviour on the site, not two. */
.modal {
  position: fixed;
  inset: 0;
  z-index: 300;
  display: grid;
  place-items: center;
  padding: 20px;
  background: rgba(4,5,5,.72);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  opacity: 0;
  visibility: hidden;
  transition: opacity var(--dur) var(--ease), visibility 0s linear var(--dur);
}
.modal.is-open { opacity: 1; visibility: visible; transition-delay: 0s; }
.modal__panel {
  position: relative;
  width: min(520px, 100%);
  max-height: calc(100vh - 40px);
  overflow-y: auto;
  padding: clamp(30px, 4vw, 46px);
  padding-right: clamp(46px, 5vw, 62px);
  background: var(--ink);
  color: #fff;
  /* 3px cyan rail, the same signal the open FAQ category uses */
  border-left: 3px solid var(--cyan);
  box-shadow: 0 30px 80px rgba(0,0,0,.55);
  transform: translateY(12px);
  transition: transform var(--dur) var(--ease);
}
.modal.is-open .modal__panel { transform: none; }
.modal__x {
  position: absolute;
  top: 14px;
  right: 14px;
  display: grid;
  place-items: center;
  width: 38px;
  height: 38px;
  background: transparent;
  border: 1px solid var(--line-d);
  color: rgba(255,255,255,.7);
  cursor: pointer;
  transition: color var(--dur) var(--ease), border-color var(--dur) var(--ease);
}
.modal__x:hover { color: #fff; border-color: rgba(255,255,255,.55); }
.modal__x svg { width: 15px; height: 15px; fill: none; stroke: currentColor; stroke-width: 2; }
/* Square 0-radius check plate, same sharp-cornered language as the buttons.
   Scales in slightly behind the panel so the confirmation registers as an event. */
.modal__mark {
  display: grid;
  place-items: center;
  width: 46px;
  height: 46px;
  margin-bottom: 24px;
  border: 1px solid var(--cyan);
  color: var(--cyan-bright);
  opacity: 0;
  transform: scale(.86);
  transition: opacity .3s var(--ease) .1s, transform .4s var(--ease) .1s;
}
.modal.is-open .modal__mark { opacity: 1; transform: none; }
.modal__mark svg {
  width: 22px;
  height: 22px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2.2;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.modal__title {
  margin-top: 12px;
  font-size: clamp(22px, 2.5vw, 29px);
  font-weight: 800;
  line-height: 1.15;
  letter-spacing: -.01em;
}
.modal__body {
  margin-top: 14px;
  color: rgba(255,255,255,.74);
  font-size: 16px;
  line-height: 1.65;
}
.modal__body a { color: var(--cyan-bright); border-bottom: 1px solid rgba(96,199,224,.4); }
.modal__body a:hover { border-color: var(--cyan-bright); }
/* The phone gets its own zone under a hairline so the number reads as the
   fallback action, not as a clause buried in the paragraph. */
.modal__call {
  margin-top: 26px;
  padding-top: 22px;
  border-top: 1px solid var(--line-d);
}
.modal__call__label {
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: .13em;
  text-transform: uppercase;
  color: rgba(255,255,255,.5);
}
.modal__tel {
  display: inline-block;
  margin-top: 10px;
  padding-bottom: 3px;
  font-size: clamp(21px, 2.6vw, 27px);
  font-weight: 800;
  letter-spacing: -.01em;
  color: #fff;
  border-bottom: 2px solid var(--cyan);
  transition: color var(--dur) var(--ease), border-color var(--dur) var(--ease);
}
.modal__tel:hover { color: var(--cyan-bright); border-color: var(--cyan-bright); }
@media (prefers-reduced-motion: reduce) {
  .modal, .modal__panel, .modal__mark { transition: opacity .01s, visibility 0s; transform: none; }
}

/* ============================================================
   CRAFT BAND (homepage) — full-bleed install footage
   ============================================================
   Same architecture as the hero (video background + calibrated scrim),
   but the footage here is SHARP where the hero's is blurred in the encode.
   The hero clip is atmosphere behind an h1; this one is the product, so the
   scrim only has to buy contrast under the left copy column and must leave
   the glasswork on the right legible.
   Calibration: luma across the left 45% of the source swings 37 to 106
   over the four cuts, so the left is held near .90 composite. Do not thin
   these stops out without re-measuring, the bright cut at 1.0s will eat
   white text. */
.craft {
  position: relative;
  display: flex;
  align-items: center;
  min-height: clamp(460px, 62vh, 660px);
  overflow: hidden;
  isolation: isolate;
  background: var(--ink);
  color: #fff;
}
.craft__media { position: absolute; inset: 0; z-index: 0; }
.craft__media video,
.craft__media img { width: 100%; height: 100%; object-fit: cover; }
.craft__media::after {
  content: '';
  position: absolute;
  inset: 0;
  background:
    linear-gradient(90deg, rgba(6,8,9,.90) 0%, rgba(6,8,9,.82) 34%, rgba(6,8,9,.46) 66%, rgba(6,8,9,.30) 100%),
    linear-gradient(0deg, rgba(6,8,9,.55) 0%, transparent 42%),
    radial-gradient(72% 82% at 2% 50%, rgba(1,146,169,.22), transparent 60%);
}
/* Brand rule on the top seam. The hero carries the same rule on its BOTTOM
   edge, so the two video bands bracket the page between them. */
.craft::before {
  content: '';
  position: absolute;
  left: 0; right: 0; top: 0;
  z-index: 3;
  height: 3px;
  background: linear-gradient(90deg, var(--cyan) 0%, var(--cyan-pale) 26%, transparent 62%);
}
.craft__inner {
  position: relative;
  z-index: 2;
  width: 100%;
  padding-block: clamp(78px, 10vw, 128px);
}
.craft__copy { max-width: 700px; }
.craft h2 {
  font-family: var(--f-display);
  font-size: clamp(31px, 4.4vw, 54px);
  line-height: 1.05;
  letter-spacing: -.015em;
  margin: 0 0 22px;
}
.craft h2 .hl { color: var(--cyan-bright); }
.craft__sub {
  /* ch is fine here because it resolves against this element's own font */
  max-width: 54ch;
  font-size: clamp(15.5px, 1.2vw, 17.5px);
  line-height: 1.66;
  color: rgba(255, 255, 255, .82);
  margin: 0;
}
.craft__steps {
  display: flex;
  flex-wrap: wrap;
  gap: 13px clamp(24px, 3vw, 46px);
  margin: clamp(28px, 3.2vw, 42px) 0 0;
  padding: clamp(22px, 2.4vw, 30px) 0 0;
  list-style: none;
  border-top: 1px solid rgba(255, 255, 255, .18);
}
.craft__steps li {
  display: flex;
  align-items: baseline;
  gap: 9px;
  font-family: var(--f-display);
  font-size: 12.5px;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
}
/* Labels are kept short on purpose: at this tracking, three items only stay
   on one line inside the 700px copy column while each stays under ~23 chars. */
.craft__n { font-size: 11.5px; color: var(--cyan-pale); }

@media (max-width: 860px) {
  /* Copy spans the full width down here, so the scrim has to be flat rather
     than a left-to-right ramp or the tail of each line loses contrast.
     Held at .84 rather than the .92 this started on: a phone only sees the
     middle ~42% of the frame after the cover crop, which is the dark door,
     so the heavier scrim crushed the footage to a flat black slab and the
     band stopped reading as video at all. These stops measure 5.98:1 for
     white body text across all four cuts (AA is 4.5) while keeping about
     50% more of the image visible. Shifting object-position toward the
     bright glass does NOT help, that side is a flat wall with less detail. */
  .craft__media::after {
    background:
      linear-gradient(90deg, rgba(6,8,9,.84) 0%, rgba(6,8,9,.78) 58%, rgba(6,8,9,.62) 100%),
      linear-gradient(0deg, rgba(6,8,9,.5) 0%, transparent 46%);
  }
  .craft { min-height: 0; }
  .craft__steps { gap: 12px 22px; }
}

/* ============================================================
   Detail accent — a small photo LAID OVER the page (.detail)
   ============================================================
   One square close-up of the work, dropped into a single spot on a
   few different pages so it turns up as you move through the site
   rather than being collected into one block.
   FIRST VERSION SAT FLAT IN THE FLOW AND WAS REJECTED: "sort of in
   the middle of nowhere, out of place". It was a photo alone in
   whitespace with nothing to relate to, so it read as an orphan.
   The fix is the idiom .storymedia__clip already established on
   about.html and the client signed off on: a white mat plus a soft
   shadow, hung across the edge of something else with a negative
   offset. The mat is what turns a picture into a separate LAYER, and
   it only announces itself where it crosses onto a dark ground,
   which is exactly where each of these is placed. So the accent is
   quiet on the page and crisp over the thing it overlaps.
   Kept SMALL and square on purpose: at ~340px a tight crop of a tool
   or a pair of hands still reads instantly, where a wide frame at
   that size does not. No radius and no hover state, in line with the
   rest of the site: these are asides in the page, not things to
   click. The shadow is the same one .storymedia__clip uses. It is
   for separation from what sits underneath, not a glow. */
.detail {
  position: relative;
  z-index: 2;
  margin: 0;
  width: 100%;
  max-width: 380px;
  padding: 9px;
  background: var(--paper);
  box-shadow: 0 26px 54px -22px rgba(11, 14, 15, .55);
}
/* height:auto is LOAD-BEARING, and the same note sits on
   .storymedia__base for the same reason. The reset is
   `img { display:block; max-width:100% }` with no height rule, so the
   width/height HTML attributes still apply as presentational hints,
   and an explicit height beats aspect-ratio rather than being derived
   from it. Drop this and the square renders 380x760, with object-fit
   quietly cover-cropping the photo to a vertical slice. */
.detail__img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 1 / 1;
  object-fit: cover;
  background: var(--ink-2);
}
.detail__cap {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 13px 4px 5px;
  color: var(--text);
  font-family: var(--f-display);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .13em;
  line-height: 1.4;
  text-transform: uppercase;
}
/* A rule rather than a bullet or a chip: the same cue the surfaces
   band uses under its labels, and it cannot wrap away from the text. */
.detail__tick { flex: none; width: 14px; height: 2px; background: var(--cyan); }

/* ---- placements ----------------------------------------------
   Each one hangs across the edge of a DARK object, which is what
   makes the white mat read. The overlap distances are deliberately
   set in the same clamp() scale as the section padding they cross,
   so the accent never eats into live copy at any width. */

/* faq.html — laid over the bottom edge of the black .faqside__card.
   max-width is dropped so the print is as wide as the card, so the
   overlap reads as a deliberate stack rather than a near-miss.
   THE OVERLAP MUST STAY INSIDE THE CARD'S BOTTOM PADDING, which is
   clamp(24px,2.6vw,32px). A deeper pull looks better in isolation but
   covers the card's phone number, which is the last thing in it, and
   .faqside__tel is display:block so it spans the full inner width,
   meaning no horizontal offset can dodge it. 20px sits under the 24px
   floor that padding hits at 901px, the narrowest this layout runs
   before the sidebar stacks. 26px was 2px into the link at that width. */
.faqside .detail {
  max-width: none;
  margin-top: -20px;
  margin-left: clamp(20px, 3vw, 34px);
}

/* about.html + services.html — hung off the base of a dark band so the
   top of the print sits on ink and the rest drops onto the light
   section below. Absolute, so it reserves no space.
   THE SECTION IS PADDED OUT TO MAKE ROOM. A print this size cannot sit
   half on each side of the seam using the default padding: it is taller
   than the two sections' facing paddings combined, so it landed on top
   of card 04's copy. The dark band therefore carries extra bottom
   padding, sized so the print's top always clears the card row. It
   drops deeper than the next section's top padding, which is fine
   because it hangs at the RIGHT edge while every following section
   opens with a left-aligned .sec-head whose paragraph is capped at
   56ch, leaving that side empty. Verified clear from 901px to 1600px. */
.detailhang { position: relative; padding-bottom: clamp(190px, 16vw, 215px); }
.detailhang .detail {
  position: absolute;
  right: var(--edge);
  bottom: clamp(-120px, -10vw, -88px);
  width: clamp(200px, 20vw, 250px);
}

@media (max-width: 900px) {
  /* Below this the bands are too short to carry an absolute element
     without it landing on the cards, so the accent returns to normal
     flow and sits under them, and the extra padding comes back off. */
  .detailhang { padding-bottom: clamp(64px, 9vw, 118px); }
  .detailhang .detail {
    position: static;
    width: 100%;
    max-width: 340px;
    margin: clamp(34px, 5vw, 46px) 0 0 auto;
  }
}

/* ------------------------------------------------------------
   Gallery, tall tiles
   ------------------------------------------------------------
   Appended after the .shot block on purpose: .shot carries
   aspect-ratio 4/3 and both selectors are a single class, so these
   only win by coming later in the file. Keep this below .shot.
   A portrait frame spans two rows rather than being squeezed into the
   landscape tile, which would have kept only the middle 44% of the
   photograph and cut the hands out of the trim and squeegee shots.
   WHY height:100% AND aspect-ratio:auto, rather than aspect-ratio 2/3:
   Chrome resolves aspect-ratio in preference to the grid's default
   stretch, so a 2/3 tile sizes itself to 1.5 columns and stops, while
   the two rows it spans measure 1.5 columns PLUS the 14px gap. That
   left a 14px hole under every tall tile. Dropping the ratio and
   filling the area instead makes the span exact, and object-fit:cover
   on the image absorbs the difference.
   The cost is that a tall tile no longer has an intrinsic height, so
   it cannot size a row on its own: every row must contain at least one
   ordinary tile. The DOM order in gallery.html satisfies that at three
   columns. Reordering those figures can silently collapse a row. */
.shot--tall { grid-row: span 2; aspect-ratio: auto; height: 100%; }

@media (max-width: 900px) {
  /* Two columns. Here the spans cannot be kept: the placement puts two
     tall tiles alone in the first two rows, and with no ordinary tile
     to give those rows a height they collapse to nothing. So spans come
     off and every tile shares one square shape, which keeps the grid
     solid and crops the portraits by a third rather than by half. */
  .shot,
  .shot--tall { aspect-ratio: 1 / 1; }
  .shot--tall { grid-row: auto; height: auto; }
}

@media (max-width: 620px) {
  /* Single column, so nothing can collide and no row can collapse.
     The photographs get their own shapes back. */
  .shot { aspect-ratio: 4 / 3; }
  .shot--tall { aspect-ratio: 2 / 3; }
}

/* ============================================================
   Financing — how it works + apply
   ------------------------------------------------------------
   Adapted from the client's reference: a dark label plate hung on
   the top edge of a light cell, a line icon, then the step copy.
   Ours keeps the site's 0-radius, hairline, cyan-accent language
   rather than the reference's navy tabs and rounded shadowed
   panels, and the copy is LEFT aligned: centred body text was the
   thing that made the join.html pitch read as a template.
   ============================================================ */
/* The lede is the only thing in its band, so the srvhead's own bottom margin
   would stack on top of the section padding and leave a dead white gap above
   the ink band. The hairline is doing the closing here. */
.finlede { padding-bottom: clamp(38px, 4.6vw, 58px); }
.finlede .srvhead { margin-bottom: 0; }

.finsteps {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(34px, 3vw, 44px) clamp(18px, 2.2vw, 30px);
}

.finstep {
  position: relative;
  /* room for the plate, which hangs above the cell's top edge */
  margin-top: 22px;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  background: var(--paper);
  border: 1px solid var(--line);
  padding: clamp(42px, 3.6vw, 54px) clamp(24px, 2.4vw, 34px) clamp(30px, 2.8vw, 38px);
  transition: transform var(--dur) var(--ease), box-shadow var(--dur) var(--ease),
              border-color var(--dur) var(--ease);
}
.finstep:hover {
  transform: translateY(-4px);
  border-color: transparent;
  box-shadow: 0 22px 44px -26px rgba(11,14,15,.34), 0 2px 8px -4px rgba(11,14,15,.08);
}

/* On the ink band the cells invert the way .card does, and the plate turns
   cyan: an ink plate would disappear into an ink-2 cell, and the accent is
   the one thing on the card that should carry across the room. */
.section--dark .finstep { background: var(--ink-2); border-color: var(--line-d); }
.section--dark .finstep:hover {
  background: #12171a;
  border-color: rgba(34,178,203,.34);
  box-shadow: 0 22px 46px -26px rgba(0,0,0,.9);
}
.section--dark .finstep svg { stroke: var(--cyan-bright); }
.section--dark .finstep p:not(.finstep__plate) { color: rgba(255,255,255,.68); }
.section--dark .finstep__plate { background: var(--cyan); }
.section--dark .finstep__n { color: rgba(255,255,255,.66); }

/* Plate is pinned to the cell's OUTER left edge (-1px covers the border),
   not hung off to the left as in the reference: every section on this site
   shares one left edge and a protruding plate would break that rhythm. */
.finstep__plate {
  position: absolute;
  top: -21px;
  left: -1px;
  display: inline-flex;
  align-items: baseline;
  gap: 11px;
  padding: 12px 22px;
  background: var(--ink);
  color: #fff;
  font-family: var(--f-display);
  font-size: clamp(13px, 1.15vw, 14.5px);
  font-weight: 800;
  letter-spacing: .11em;
  text-transform: uppercase;
  white-space: nowrap;
}
.finstep__n { color: var(--cyan-bright); }

.finstep svg {
  width: 54px;
  height: 54px;
  stroke: var(--cyan);
  fill: none;
  stroke-width: 1.3;
  stroke-linecap: square;
  stroke-linejoin: miter;
  margin-bottom: clamp(24px, 2.6vw, 32px);
  transition: transform var(--dur) var(--ease);
}
.finstep:hover svg { transform: translateY(-3px); }

.finstep p:not(.finstep__plate) {
  color: var(--muted);
  font-size: 15.5px;
  line-height: 1.62;
  text-wrap: pretty;
}

/* ---- apply row ---- */
.finapply {
  display: grid;
  grid-template-columns: minmax(0, 1.06fr) minmax(0, 1fr);
  gap: clamp(30px, 4vw, 62px);
  align-items: center;
}

.finmedia { position: relative; margin: 0; }
.finmedia > img {
  width: 100%;
  height: auto;                 /* the reset has no height:auto, and the HTML
                                   height attribute would otherwise win */
  aspect-ratio: 4 / 3;
  object-fit: cover;
  background: var(--ink-2);
}
/* Hung off the bottom-right corner so the mat crosses from the dark of the
   door onto the tint. Both offsets are negative on purpose: an inset mat
   sits ON the photo and reads as a sticker, one that overhangs reads as a
   separate layer. The gap either side is wide enough that it never reaches
   the copy column. */
.finmedia__qr {
  position: absolute;
  right: clamp(-26px, -2vw, -18px);
  bottom: clamp(-26px, -2vw, -18px);
  padding: 9px;
  background: var(--paper);
  box-shadow: 0 26px 50px -26px rgba(11,14,15,.45), 0 2px 8px -4px rgba(11,14,15,.12);
}
.finmedia__qr img { width: clamp(116px, 10.5vw, 146px); height: auto; }
.finmedia__cap {
  display: block;
  margin-top: 8px;
  padding-top: 7px;
  border-top: 1px solid var(--line);
  font-family: var(--f-display);
  font-size: 9.5px;
  font-weight: 700;
  letter-spacing: .16em;
  text-transform: uppercase;
  text-align: center;
  color: var(--muted);
}

.finapply__body { max-width: 62ch; }
.finapply__body h3 {
  font-size: clamp(21px, 2.3vw, 27px);
  font-weight: 800;
  letter-spacing: -.01em;
}
.finapply__body > p {
  margin-top: 14px;
  color: var(--muted);
  font-size: clamp(15.5px, 1.5vw, 17px);
  text-wrap: pretty;
}
.finapply__body .btn { margin-top: 26px; }
.finapply__note {
  margin-top: 22px !important;
  max-width: 64ch;
  font-size: 13.5px !important;
  line-height: 1.6;
  color: var(--muted);
  opacity: .85;
}

@media (max-width: 980px) {
  /* Three narrow cells cannot hold a plate on one line, and two columns
     would orphan the third step. One column keeps the sequence obvious. */
  .finsteps { grid-template-columns: 1fr; }
}
@media (max-width: 820px) {
  /* Stacked, so the mat has no column edge to hang past. It tucks inside the
     photo's bottom-right instead, still on the dark of the door, and the
     copy below gets the clearance the overhang used to need. */
  .finapply { grid-template-columns: 1fr; gap: 44px; }
  /* Still hangs, just off the bottom edge rather than the corner: fully
     inset it covered a third of the photograph on a phone. The 44px gap
     leaves clearance under the overhang. */
  .finmedia__qr { right: 12px; bottom: -20px; }
  .finmedia__qr img { width: 112px; }
  .finapply__body .btn { width: 100%; }
}

/* ============================================================
   Financing — coming-soon placeholder
   ============================================================ */
.soon { max-width: 64ch; }
.soon__mark {
  display: grid;
  place-items: center;
  width: 54px;
  height: 54px;
  border: 2px solid var(--cyan);
  margin-bottom: 28px;
}
.soon__mark svg { width: 26px; height: 26px; stroke: var(--cyan); fill: none; stroke-width: 1.6; }
.soon h2 { font-size: clamp(28px, 3.7vw, 45px); line-height: 1.06; }
.soon > p {
  margin-top: 18px;
  color: var(--muted);
  font-size: clamp(16px, 1.6vw, 17.5px);
  text-wrap: pretty;
}
.soonactions { display: flex; flex-wrap: wrap; gap: 14px; margin-top: 32px; }
.soon__back { margin-top: 30px; }
.arrowlink--back { color: var(--cyan-press); }
.arrowlink--back:hover svg { transform: translateX(-5px); }

@media (max-width: 560px) {
  .soonactions { flex-direction: column; align-items: stretch; }
}

/* ------------------------------------------------------------
   Header, small-laptop band (adding Financing made it six items)
   ------------------------------------------------------------
   Five nav items fitted one row down to the 900px burger
   breakpoint. Six do not: at 1100px the nav wrapped to a second
   line, and under 1000px the header pushed the page wider than the
   viewport. Rather than drop to the burger earlier, which would
   hide the nav on a small laptop, the whole header tightens for
   this band only: the logo, the link tracking and the CTA all give
   back a little. Must stay AFTER the .hdr / .navlink rules above.
   ------------------------------------------------------------ */
@media (min-width: 901px) and (max-width: 1160px) {
  .hdr { gap: 18px; }
  .hdr__logo img { height: 36px; }
  .hdr__nav { gap: 17px; }
  .navlink { font-size: 12px; letter-spacing: .075em; }
  .navlink--menu { gap: 5px; }
  .hdr__cta .btn { padding: 13px 19px; font-size: 12px; letter-spacing: .1em; }
}
/* Bottom of that band is the tightest point: at 901px, one step above
   the burger, the six items still wrapped. A little more give here. */
@media (min-width: 901px) and (max-width: 980px) {
  .hdr { gap: 14px; }
  .hdr__nav { gap: 13px; }
  .navlink { font-size: 11.5px; letter-spacing: .05em; }
  .hdr__cta .btn { padding: 12px 15px; font-size: 11.5px; letter-spacing: .08em; }
}

/* ============================================================
   Countertop band (index.html only)
   ------------------------------------------------------------
   The homepage runs --ink from the hero straight through .about,
   so this is the one light surface above the teal CTA. That is
   deliberate and it is the whole mechanism: no ornament was added,
   the band stands out because it is the only thing on the page
   that is not black.
   The media is a STACK, not a pair. The video sits in a contained
   3:2 frame and the still hangs across its bottom-left corner on
   the same 9px white mat and shadow .storymedia__clip and
   .finmedia__qr use. Both offsets are negative on purpose: an
   inset mat sits ON the video and reads as a sticker, one that
   overhangs reads as a separate layer. On this light ground the
   video IS the dark object the mat needs in order to announce
   itself, which is why the print is hung on the frame rather than
   dropped somewhere in the band.
   The overlap is held near 20% of the frame width. Cut one of the
   clip has the installer entering from the left at about x=21%,
   so a deeper pull starts clipping him.
   ============================================================ */
.counter { background: var(--paper-2); }
.counter__split {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr);
  gap: clamp(34px, 5vw, 76px);
  align-items: center;
}
/* --cyan-bright is the default and it is too pale on a light band,
   the same correction the Google review eyebrow needed. */
.counter .eyebrow { color: var(--cyan); }
/* Held below the 50px the other section heads run at: "COUNTERTOPS THAT"
   is 16 characters and has to survive on ONE line in this column, or the
   hard break after "that" orphans it. */
.counter__copy h2 {
  font-size: clamp(29px, 3.5vw, 43px);
  font-weight: 900;
  line-height: 1.04;
  letter-spacing: -.015em;
}
.counter__copy h2 .hl { color: var(--cyan); }
.counter__copy > p {
  margin-top: 22px;
  max-width: 52ch;
  color: var(--muted);
  font-size: clamp(15.5px, 1.5vw, 17px);
  line-height: 1.72;
  text-wrap: pretty;
}

.counter__media { position: relative; }
.counter__frame { position: relative; margin: 0; }
.counter__frame video {
  display: block;
  width: 100%;
  /* height:auto is load-bearing here for the same reason it is on
     .detail__img: the reset sets no height, so a height attribute
     or a UA default would beat aspect-ratio instead of deriving
     from it. */
  height: auto;
  aspect-ratio: 3 / 2;
  object-fit: cover;
  background: var(--ink-2);
}

.counter__print {
  position: absolute;
  /* The pull left has to stay well under the column gap, which is 5vw:
     what is left over is the only clearance between the mat and the
     headline, and the headline always fills its column because both
     scale on vw. At 4vw that came out to 1vw of daylight, 9px at 901px,
     the narrowest this runs before it stacks. 2.6vw leaves ~2.4vw. */
  left: clamp(-52px, -2.6vw, -20px);
  bottom: clamp(-46px, -3vw, -26px);
  width: clamp(126px, 13vw, 172px);
  max-width: none;              /* .detail caps at 380px; sized here instead */
  z-index: 2;
}
/* .detail__img is square by default. This frame is the client's own
   2:3 photograph and resizes with no crop at all, so keep the ratio. */
.counter__print .detail__img { aspect-ratio: 2 / 3; }
.counter__print .detail__cap { font-size: 10px; letter-spacing: .12em; padding-top: 11px; }

@media (max-width: 900px) {
  .counter__split { grid-template-columns: 1fr; gap: clamp(30px, 5vw, 42px); }
  /* Stacked, the media is page-wide, so a negative left offset would
     run under the viewport edge (body is overflow-x:hidden, so it
     would clip rather than scroll). It tucks inside the frame's
     bottom-left and still overhangs the bottom edge, which is the
     half of the offset that does the layering work. Same move
     .finmedia__qr makes at 820px. */
  .counter__print {
    left: -10px;
    bottom: -26px;
    width: clamp(118px, 26vw, 152px);
  }
}
/* A 2:3 print beside a 3:2 frame out-heights it as soon as the frame is
   page-wide, so it keeps shrinking as the viewport does. The caption goes
   at the point where it can no longer hold one line: two stacked lines of
   tracked caps under a small print reads as a label stuck on the photo,
   and the FAQ accent already ships captionless on the client's own call. */
@media (max-width: 560px) {
  .counter__print { left: -10px; bottom: -24px; width: 34%; padding: 7px; }
  .counter__print .detail__cap { display: none; }
}

/* The lender line under the financing lede. Bold and set in --text
   rather than --muted so it separates from the paragraph above it
   without needing a rule: the aside already sits directly on the
   .srvhead hairline, and a second hairline this close reads as an
   empty row. */
.finsyn {
  margin-top: 16px;
  color: var(--text) !important;
  font-size: 15.5px !important;
  line-height: 1.55;
}
.finsyn strong { font-weight: 700; }
