/* Full Service Web Design — site stylesheet.
   Mobile-first. Design at 390px, scale up. */

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

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

body {
  font-family: var(--font-body);
  font-size: clamp(1.0625rem, .35vw + 1rem, 1.125rem);
  line-height: 1.65;
  color: var(--ink-2);
  background: var(--surface);
  -webkit-font-smoothing: antialiased;
  padding-bottom: 64px; /* room for the sticky mobile bar */
  overflow-wrap: break-word;
}
@media (min-width: 768px) { body { padding-bottom: 0; } }

/* Grid and flex children default to min-width:auto, so one long word inside a
   card or trust-bar item can push a track wider than its column and give the
   whole page a horizontal scrollbar. This is the fix, not overflow-x:hidden. */
.hero__grid > *, .grid > *, .trustbar > *, .stats > *, .steps > *,
.footer__grid > *, .cta-band__inner > *, .cta-opts > *, .site-header__bar > * {
  min-width: 0;
}
.trustbar__item > div, .cta-opt > span { min-width: 0; }

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

h1, h2, h3, h4 {
  font-family: var(--font-head);
  color: var(--ink);
  line-height: 1.15;
  letter-spacing: -.02em;
  text-wrap: balance;
}
h1 { font-size: clamp(2.125rem, 4.4vw + 1rem, 3.5rem); line-height: 1.08; font-weight: 700; }
h2 { font-size: clamp(1.625rem, 2.2vw + 1rem, 2.375rem); font-weight: 700; }
h3 { font-size: clamp(1.25rem, .8vw + 1rem, 1.5rem);     font-weight: 600; }
h4 { font-size: 1.0625rem; font-weight: 600; }

p { text-wrap: pretty; }
p + p { margin-top: var(--s2); }

a { color: var(--teal-text); text-underline-offset: 3px; }
a:hover { color: var(--green-text); }
:focus-visible { outline: 3px solid var(--teal); outline-offset: 2px; border-radius: 4px; }

/* ---------- layout ---------- */
.wrap { width: 100%; max-width: var(--wrap); margin-inline: auto; padding-inline: var(--gutter); }
.section { padding-block: var(--section-y); }
.section--alt  { background: var(--surface-2); }
.section--dark { background: var(--dark); color: var(--on-dark-2); }
.section--dark h2, .section--dark h3, .section--dark h1 { color: #fff; }
.section--tight { padding-block: clamp(36px, 6vw, 56px); }

/* ---------- coloured section tones ----------
   The site was white, light-grey, white, light-grey the whole way down. These
   give a page some rhythm without touching the copy.

   CONTRAST, since white text is involved (tokens.css sets the rule: never body
   text on raw cyan, which is 2.2:1 on white):
     --accent gradient runs #0A4A58 -> #0F6F8C. White on the LIGHT end is
     5.4:1, so every stop on the ramp is AA or better for body text.
     The tinted tones keep --ink text on a near-white wash, so they are all 12:1+. */
.section--brand { background: linear-gradient(180deg, rgba(0,185,231,.09) 0%, rgba(0,185,231,.03) 100%); }
.section--amber { background: linear-gradient(180deg, rgba(245,158,11,.13) 0%, rgba(245,158,11,.04) 100%); }

.section--accent { background: linear-gradient(135deg, #0A4A58 0%, #0F6F8C 100%); color: #E8F6FA; }
.section--accent h1, .section--accent h2, .section--accent h3, .section--accent strong { color: #fff; }
.section--accent .lede { color: #D3ECF4; }
.section--accent .eyebrow { color: #7FE0FA; }
/* Cards and list marks have to be re-stated on a dark ground — they default to
   white backgrounds and dark ink, which vanish or glare here. */
.section--accent .card { background: rgba(255,255,255,.08); border-color: rgba(255,255,255,.22); box-shadow: none; }
.section--accent .card p, .section--accent .card__meta { color: #D3ECF4; }
.section--accent .card h3 a { color: #fff; }
.section--accent .ticks li { color: #E8F6FA; }
.section--accent .ticks li::before { background: rgba(255,255,255,.16); color: #fff; }
.section--accent .step h3 { color: #fff; }
.section--accent .step p { color: #D3ECF4; }
.section--accent .step::before { background: rgba(255,255,255,.16); color: #fff; }
.section--accent .chip { background: rgba(255,255,255,.14); }
.section--accent .chip svg { stroke: #fff; }
.section--accent .faq details { border-color: rgba(255,255,255,.22); }
.section--accent .faq summary { color: #fff; }
.section--accent .faq div { color: #D3ECF4; }
.section--accent a { color: #A8E9FB; }
.section--accent .btn--secondary { background: transparent; color: #fff; border-color: rgba(255,255,255,.5); }
.section--accent .btn--secondary:hover { background: rgba(255,255,255,.12); color: #fff; }
/* Prose and tables default to dark ink, which is invisible here. */
.section--accent .prose, .section--accent .prose p { color: #E8F6FA; }
.section--accent .prose blockquote { border-left-color: #7FE0FA; }
.section--accent .prose blockquote p { color: #D3ECF4; }
.section--accent th { color: #fff; }
.section--accent th, .section--accent td { border-bottom-color: rgba(255,255,255,.22); }
.section--accent .pill { background: rgba(255,255,255,.12); border-color: rgba(255,255,255,.3); color: #fff; }
.section--accent .linkcols a { color: #D3ECF4; }
.section--accent .stat b { color: #fff; }
.section--accent .stat span { color: #D3ECF4; }

.lede { font-size: clamp(1.0625rem, .6vw + 1rem, 1.25rem); color: var(--ink-2); max-width: 62ch; }
.eyebrow {
  font-family: var(--font-head); font-weight: 600; font-size: .8125rem;
  letter-spacing: .1em; text-transform: uppercase; color: var(--green-text);
  margin-bottom: var(--s2);
}
.section--dark .eyebrow { color: var(--green); }
.center { text-align: center; }
.measure { max-width: 68ch; }
.mt2 { margin-top: var(--s2); } .mt3 { margin-top: var(--s3); }
.mt4 { margin-top: var(--s4); } .mt5 { margin-top: var(--s5); }

/* ---------- ribbon: the one motif that carries brand recognition ---------- */
.ribbon { height: 6px; background: var(--ribbon); border: 0; }
.ribbon--thin { height: 4px; }

/* ---------- utility bar ----------
   Carries the phone number above the nav. White on the deep teal ramp
   (#0A4A58 -> #0F6F8C) is 5.4:1 at the light end, so it is AA at every stop. */
.topbar { background: linear-gradient(90deg, #0A4A58 0%, #0F6F8C 100%); color: #D3ECF4; font-size: .875rem; }
.topbar__inner { display: flex; align-items: center; justify-content: space-between; gap: var(--s2); min-height: 40px; flex-wrap: wrap; }
.topbar__note { color: #BFE4EF; }
.topbar__phone { display: inline-flex; align-items: center; gap: 8px; color: #fff; font-weight: 700; text-decoration: none; font-family: var(--font-head); letter-spacing: -.01em; }
.topbar__phone:hover { color: #A8E9FB; }
.topbar__phone svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 2; }
/* On a phone the sticky call bar at the bottom already carries this, and the
   descriptor is the first thing worth dropping. */
/* The address shows on phones too (2026-09-19): stacked and centred instead of hidden. */
@media (max-width: 640px) { .topbar__inner { justify-content: center; flex-direction: column; gap: 2px; padding-top: 4px; padding-bottom: 4px; } .topbar__note { text-align: center; font-size: .8125rem; } }
.topbar__addr { display: inline-flex; align-items: center; gap: 6px; text-decoration: none; }
.topbar__addr:hover, .topbar__addr:focus-visible { color: #fff; text-decoration: underline; }
.topbar__addr svg { width: 14px; height: 14px; flex: none; fill: none; stroke: currentColor; stroke-width: 2; }

/* ---------- header ---------- */
.site-header { position: sticky; top: 0; z-index: 50; background: rgba(255,255,255,.92); backdrop-filter: blur(10px); border-bottom: 1px solid var(--line); }
/* Was 68px, which left a 57px mark only ~5px of clearance top and bottom and
   read as cramped against the bottom border. */
.site-header__bar { display: flex; align-items: center; gap: var(--s3); min-height: 76px; }
.brand { display: flex; align-items: center; gap: 10px; font-family: var(--font-head); font-weight: 700; color: var(--ink); text-decoration: none; font-size: 1.0625rem; letter-spacing: -.02em; }
/* 57px = 38 x 1.5. Keep in step with the width/height attributes in
   brand_lockup() and the 1x/2x files built by siteConf/optimize-images.php. */
.brand img { width: 57px; height: 57px; border-radius: 9px; }
.brand span { display: none; }
@media (min-width: 480px) { .brand span { display: inline; } }

/* Nine nav items, a brand name and two buttons is a full bar. With the logo at
   57px it overflowed at 1280px and the last nav link collided with the phone
   button. Tighter gap and type buy back ~110px, which is enough; the brand and
   the buttons are pinned so they can never be the thing that compresses. */
.nav { display: none; margin-left: auto; align-items: center; gap: 14px; }
@media (min-width: 980px) { .nav { display: flex; } }
.nav a { color: var(--ink-2); text-decoration: none; font-weight: 500; font-size: .875rem; white-space: nowrap; }
.brand { flex: none; }
.nav a:hover { color: var(--ink); }
.header-cta { margin-left: auto; display: flex; gap: 10px; align-items: center; flex: none; }
@media (min-width: 980px) { .header-cta { margin-left: 0; } }
.nav-toggle { display: inline-flex; align-items: center; gap: 8px; background: none; border: 1.5px solid var(--line); border-radius: var(--radius-sm); padding: 9px 12px; font: inherit; font-size: .875rem; color: var(--ink); cursor: pointer; }
@media (min-width: 980px) { .nav-toggle { display: none; } }
.mobile-nav { display: none; border-top: 1px solid var(--line); padding-block: var(--s2) var(--s3); }
.mobile-nav[data-open="true"] { display: block; }
.mobile-nav a { display: block; padding: 11px 0; color: var(--ink); text-decoration: none; font-weight: 500; border-bottom: 1px solid var(--line); }

/* ---------- buttons ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  min-height: 48px; padding: 13px 26px; white-space: nowrap;
  font-family: var(--font-head); font-weight: 600; font-size: 1rem;
  border-radius: var(--radius); border: 1.5px solid transparent;
  text-decoration: none; cursor: pointer; transition: background .15s, transform .15s, box-shadow .15s;
}
.btn--primary   { background: var(--green); color: #fff; box-shadow: 0 2px 10px rgba(111,174,18,.28); }
.btn--primary:hover { background: var(--green-700); color: #fff; transform: translateY(-1px); }
.btn--secondary { background: transparent; color: var(--ink); border-color: var(--ink); }
.btn--secondary:hover { background: var(--ink); color: #fff; }
.btn--ondark    { background: #fff; color: var(--ink); }
.btn--ondark:hover { background: var(--surface-2); color: var(--ink); }
.btn--ghost-dark { background: transparent; color: #fff; border-color: rgba(255,255,255,.4); }
.btn--ghost-dark:hover { background: rgba(255,255,255,.1); color: #fff; }
.btn--sm { min-height: 40px; padding: 9px 16px; font-size: .9375rem; }
.btn-row { display: flex; flex-wrap: wrap; gap: 12px; }

/* ---------- hero ---------- */
/* Brand wash rather than flat grey. The dot grid below still reads through it;
   the gradient is kept pale so the h1 stays on a near-white ground and holds
   its 12:1 contrast. */
.hero {
  position: relative; overflow: hidden; padding-block: clamp(48px, 8vw, 88px);
  background:
    radial-gradient(1000px 420px at 88% -8%, rgba(0,185,231,.20) 0%, transparent 62%),
    radial-gradient(760px 380px at 4% 108%, rgba(245,158,11,.14) 0%, transparent 60%),
    linear-gradient(180deg, #F7FBFD 0%, var(--surface-2) 100%);
}
.hero::before {
  content: ""; position: absolute; inset: 0; opacity: .5; pointer-events: none;
  background-image:
    radial-gradient(circle at 1px 1px, rgba(11,13,16,.11) 1px, transparent 0);
  background-size: 26px 26px;
  mask-image: linear-gradient(160deg, transparent 30%, #000 100%);
  -webkit-mask-image: linear-gradient(160deg, transparent 30%, #000 100%);
}
.hero > * { position: relative; }
.hero__grid { display: grid; gap: var(--s5); }
@media (min-width: 900px) { .hero__grid { grid-template-columns: 1.15fr .85fr; align-items: center; } }
.hero h1 .accent { color: var(--green); }
.hero h1 .accent-2 { color: var(--red); }
.hero .lede { margin-top: var(--s3); }
.hero .btn-row { margin-top: var(--s4); }
.hero__note { margin-top: var(--s3); font-size: .9375rem; color: var(--ink-3); }

/* ---------- trust bar ---------- */
.trustbar { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--s3); }
@media (min-width: 760px) { .trustbar { grid-template-columns: repeat(4, 1fr); } }
.trustbar__item { display: flex; gap: 12px; align-items: flex-start; }
.trustbar__item strong { display: block; font-family: var(--font-head); color: var(--ink); font-size: .9375rem; line-height: 1.3; margin-bottom: 2px; }
.trustbar__item span { display: block; font-size: .875rem; color: var(--ink-3); line-height: 1.45; }

/* ---------- icon chip ---------- */
.chip { flex: 0 0 auto; width: 44px; height: 44px; border-radius: 50%; display: grid; place-items: center; }
.chip svg { width: 22px; height: 22px; stroke-width: 2; fill: none; }
.chip--green { background: var(--green-050); } .chip--green svg { stroke: var(--green-text); }
.chip--teal  { background: var(--teal-050);  } .chip--teal  svg { stroke: var(--teal-text); }
.chip--amber { background: var(--amber-050); } .chip--amber svg { stroke: #8A6100; }
.chip--red   { background: var(--red-050);   } .chip--red   svg { stroke: var(--red-text); }

/* ---------- cards ---------- */
.grid { display: grid; gap: var(--s3); }
.grid--2 { grid-template-columns: 1fr; }
.grid--3 { grid-template-columns: 1fr; }
.grid--4 { grid-template-columns: repeat(2, 1fr); }
@media (min-width: 700px) { .grid--2 { grid-template-columns: repeat(2, 1fr); } .grid--3 { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 980px) { .grid--3 { grid-template-columns: repeat(3, 1fr); } .grid--4 { grid-template-columns: repeat(4, 1fr); } }

.card {
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
  padding: var(--s3); box-shadow: var(--shadow-sm);
  transition: box-shadow .18s, transform .18s;
}
/* A brand edge on every card. 3px of colour on an otherwise white box is what
   stops a grid of six cards reading as a grid of six empty rectangles. */
.card { position: relative; overflow: hidden; }
.card::before {
  content: ""; position: absolute; inset: 0 0 auto 0; height: 3px;
  background: var(--ribbon); opacity: .85;
}
.section--accent .card::before { background: rgba(255,255,255,.5); }
.card--link:hover { box-shadow: var(--shadow-md); transform: translateY(-2px); }
.card--link:hover::before { opacity: 1; }
.card h3 { margin-bottom: 10px; }
.card h3 a { color: inherit; text-decoration: none; }
.card p { font-size: .9688rem; }
.card__meta { margin-top: var(--s2); font-size: .875rem; color: var(--ink-3); font-weight: 500; }
.card .chip { margin-bottom: var(--s2); }

/* ---------- stats ---------- */
.stats { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--s3); }
@media (min-width: 760px) { .stats { grid-template-columns: repeat(4, 1fr); } }
.stat b { display: block; font-family: var(--font-head); font-weight: 700; font-size: clamp(2rem, 3vw, 2.5rem); color: var(--green); line-height: 1.1; }
.section--dark .stat b { color: var(--green); }
.stat span { font-size: .9375rem; color: var(--ink-3); }
.section--dark .stat span { color: var(--on-dark-2); }

/* ---------- steps ---------- */
.steps { counter-reset: step; display: grid; gap: var(--s3); }
/* auto-fit, not repeat(4): the home page has FIVE steps, and a hard 4-column
   grid dropped the fifth onto its own row looking orphaned. */
@media (min-width: 900px) { .steps { grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); } }
.step { position: relative; padding-top: var(--s4); }
.step::before {
  counter-increment: step; content: counter(step);
  position: absolute; top: 0; left: 0;
  width: 34px; height: 34px; border-radius: 50%;
  background: var(--ink); color: #fff;
  font-family: var(--font-head); font-weight: 700; font-size: .9375rem;
  display: grid; place-items: center;
}
.step h3 { font-size: 1.0625rem; margin-bottom: 6px; }
.step p { font-size: .9375rem; }

/* ---------- lists ---------- */
.ticks { list-style: none; padding: 0; display: grid; gap: 12px; }
.ticks li { position: relative; padding-left: 30px; }
.ticks li::before {
  content: ""; position: absolute; left: 0; top: .45em;
  width: 16px; height: 9px; border-left: 2.5px solid var(--green); border-bottom: 2.5px solid var(--green);
  transform: rotate(-45deg);
}
.section--dark .ticks li::before { border-color: var(--green); }

/* ---------- FAQ ---------- */
.faq { border-top: 1px solid var(--line); }
.faq details { border-bottom: 1px solid var(--line); }
.faq summary {
  cursor: pointer; list-style: none; padding: var(--s3) 40px var(--s3) 0; position: relative;
  font-family: var(--font-head); font-weight: 600; color: var(--ink); font-size: 1.0625rem;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after {
  content: ""; position: absolute; right: 6px; top: 50%; width: 11px; height: 11px;
  border-right: 2.5px solid var(--ink-3); border-bottom: 2.5px solid var(--ink-3);
  transform: translateY(-70%) rotate(45deg); transition: transform .2s;
}
.faq details[open] summary::after { transform: translateY(-30%) rotate(-135deg); }
.faq details > div { padding-bottom: var(--s3); max-width: 74ch; }

/* ---------- tables ---------- */
.table-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; }
table { border-collapse: collapse; width: 100%; font-size: .9375rem; }
th, td { text-align: left; padding: 12px 14px; border-bottom: 1px solid var(--line); }
th { font-family: var(--font-head); font-weight: 600; color: var(--ink); white-space: nowrap; }

/* ---------- forms ---------- */
.form { display: grid; gap: var(--s2); }
.field label { display: block; font-weight: 600; font-size: .9375rem; color: var(--ink); margin-bottom: 6px; }
.field input, .field select, .field textarea {
  width: 100%; padding: 12px 14px; font: inherit; font-size: 1rem; color: var(--ink);
  background: #fff; border: 1.5px solid var(--line); border-radius: var(--radius-sm);
  min-height: 48px;
}
.field input:focus, .field select:focus, .field textarea:focus { border-color: var(--teal); outline: none; box-shadow: 0 0 0 3px var(--teal-050); }
.field textarea { min-height: 110px; resize: vertical; }
.field--half { display: grid; gap: var(--s2); }
@media (min-width: 560px) { .field--half { grid-template-columns: 1fr 1fr; } }
.form__note { font-size: .8125rem; color: var(--ink-3); }
.hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

.form-card { background: #fff; border: 1px solid var(--line); border-radius: var(--radius-lg); padding: var(--s4); box-shadow: var(--shadow-md); }
/* Validation summary. Red is carried by the border and the heading weight as
   well as the colour, so it still reads as an error without colour vision. */
.form-alert { margin-top: var(--s3); padding: var(--s2) var(--s3); background: var(--red-050);
  border: 1.5px solid var(--red); border-left-width: 5px; border-radius: var(--radius-sm); color: var(--red-text); }
.form-alert strong { display: block; font-family: var(--font-head); font-size: 1rem; }
.form-alert ul { margin: var(--s1) 0 0; padding-left: 1.1em; font-size: .9375rem; color: var(--ink-2); }
.form-alert li + li { margin-top: 4px; }
.form-alert:focus { outline: 3px solid var(--red); outline-offset: 3px; }
.form-card h2 { font-size: 1.5rem; }

/* Optional-field marker and hint text. Both classes were already used by the
   warehouse form markup but had never been given any styling. */
.opt { font-weight: 400; color: var(--ink-3); font-size: .875rem; }
.field__hint { margin-top: 6px; font-size: .8125rem; color: var(--ink-3); }

/* ---------- two-step form progress ----------
   Order and completion are carried by the numeral in each marker, not by
   colour alone, so the step you are on is still obvious in monochrome or with
   the accent colours unavailable. aria-current="step" does the same job for a
   screen reader. */
.form-steps { display: flex; flex-wrap: wrap; gap: var(--s2); list-style: none; margin: 0 0 var(--s3); padding: 0; }
.form-steps li { display: flex; align-items: center; gap: 8px; font-size: .8125rem; font-weight: 600; color: var(--ink-3); }
.form-steps__n {
  display: grid; place-items: center; width: 22px; height: 22px; flex: none;
  border-radius: 50%; border: 1.5px solid var(--line);
  font-size: .75rem; line-height: 1; color: var(--ink-3); background: #fff;
}
.form-steps .is-on { color: var(--ink); }
.form-steps .is-on .form-steps__n { border-color: var(--green); background: var(--green); color: #fff; }
.form-steps .is-done { color: var(--green-text); }
.form-steps .is-done .form-steps__n { border-color: var(--green); color: var(--green-text); background: var(--green-050); }

/* The skip-out of step 2. Deliberately quiet next to the submit button, but a
   real, obvious link — step 2 is optional and hiding that would be a dark
   pattern on a page the visitor has already converted on. */
.form__skip { text-align: center; margin-top: var(--s2); }
.form__skip a { color: var(--ink-3); text-decoration: underline; }
.form__skip a:hover { color: var(--ink); }

/* ---------- booking placeholder ---------- */
.booking { border: 1.5px dashed var(--line); border-radius: var(--radius); padding: var(--s4); text-align: center; background: var(--surface-2); }

/* ---------- booking modal ----------
   Google's scheduler needs ~600px of width before it lays the month grid and
   the time slots out side by side. The dialog gives it the viewport, which is
   the whole point: it was previously mounted in a ~400px sidebar column. */
.booking-dialog {
  width: min(1120px, 96vw);
  height: min(880px, 90vh);
  max-width: none; max-height: none;   /* UA default is 90% — we set our own */
  /* Explicit inset + margin:auto. The UA centres a dialog with margin:auto,
     but only while its size is auto; giving it a fixed width and height
     leaves it pinned to the top-left without these two lines. */
  inset: 0; margin: auto;
  padding: 0; border: 0; border-radius: var(--radius-lg);
  background: var(--surface); color: var(--ink);
  box-shadow: 0 24px 64px rgba(11, 13, 16, .28);
  overflow: hidden;
}
.booking-dialog::backdrop { background: rgba(11, 13, 16, .62); }
.booking-dialog[open] { display: grid; grid-template-rows: auto 1fr auto; }

.booking-dialog__bar { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--s3);
  padding: var(--s3) var(--s4); border-bottom: 1px solid var(--line); }
.booking-dialog__bar h2 { font-size: 1.25rem; }
.booking-dialog__bar p { font-size: .9375rem; color: var(--ink-3); margin-top: 2px; }

.booking-dialog__close { flex: 0 0 auto; width: 44px; height: 44px; display: grid; place-items: center;
  background: var(--surface-2); border: 1px solid var(--line); border-radius: 50%; cursor: pointer; color: var(--ink); }
.booking-dialog__close:hover { background: var(--surface-3); }
.booking-dialog__close:focus-visible { outline: 3px solid var(--teal); outline-offset: 2px; }
.booking-dialog__close svg { width: 20px; height: 20px; fill: none; stroke: currentColor; stroke-width: 2; }

.booking-dialog__body { position: relative; min-height: 0; background: var(--surface-2); }
.booking-dialog__loading { position: absolute; inset: 0; display: grid; place-items: center; color: var(--ink-3); font-size: .9375rem; }
/* Opaque so the loading message cannot show through before load fires. */
.booking-dialog__frame { position: relative; display: block; width: 100%; height: 100%; border: 0; background: #fff; }

.booking-dialog__foot { padding: 12px var(--s4); border-top: 1px solid var(--line);
  font-size: .8125rem; color: var(--ink-3); text-align: center; }

/* Phones: take the whole screen. The scheduler stacks month over slots there
   and needs every pixel of height it can get. dvh keeps it correct while
   mobile browser chrome shows and hides. */
@media (max-width: 700px) {
  .booking-dialog { width: 100vw; height: 100dvh; max-height: 100dvh; border-radius: 0; }
  .booking-dialog__bar { padding: var(--s2) var(--s3); }
  .booking-dialog__bar p { display: none; }
  .booking-dialog__foot { padding: 10px var(--s3); }
}

/* ---------- photography ---------- */
.photo { margin: 0; border-radius: var(--radius-lg); overflow: hidden; box-shadow: var(--shadow-md); position: relative; }
.photo img { width: 100%; height: auto; display: block; }
/* A whisper of brand over the photo so it belongs to this palette rather than
   sitting in the page as a foreign rectangle. */
.photo::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(150deg, rgba(0,185,231,.16) 0%, transparent 45%, rgba(15,20,32,.16) 100%);
}
.photo--band { border-radius: 0; box-shadow: none; }
.photo--band img { max-height: 380px; object-fit: cover; }
.photo--tall img { aspect-ratio: 4 / 5; object-fit: cover; }

/* ---------- full-bleed photo band ----------
   White text over a photograph whose brightness we do not control, so the
   overlay is a contrast floor rather than a mood effect: the darkest stop sits
   behind the headline and keeps it legible on any underlying image. */
.band { position: relative; isolation: isolate; padding-block: clamp(64px, 10vw, 120px); color: #fff; overflow: hidden; }
.band__bg { position: absolute; inset: 0; z-index: -2; display: block; }
.band__bg img { width: 100%; height: 100%; object-fit: cover; display: block; }
/* Dark only where the words are. A flat 80-90% veil across the whole band made
   the photograph unreadable — it looked like a solid teal panel, which defeats
   the point of putting a photo there. This keeps ~.75 behind the headline
   (white on that composite is ~7:1 even over a blown-out white sky) and drops
   to .15 on the right, where the picture is actually visible. */
/* The dark stop has to cover the WHOLE text column, not just the headline. The
   St. George photo has a brightly lit town right where the body copy sits, and
   at .45 there the paragraph washed out completely while the big white headline
   still looked fine. Holding ~.75 to 58% keeps body text near 8:1 even over the
   brightest part of the picture, and the fall-off still leaves the right third
   of the photograph clearly visible. */
/* 90deg, not 95: a tilted ramp made the right end of the paragraph lighter than
   the left end of the same line, so copy faded mid-sentence. Pure horizontal
   keeps every line evenly backed. The hold to 56% covers the whole 44ch text
   column, and the fall-off gives the photograph the right third cleanly. */
.band::after {
  content: ""; position: absolute; inset: 0; z-index: -1;
  background: linear-gradient(90deg,
    rgba(8,26,34,.93) 0%,
    rgba(8,26,34,.90) 56%,
    rgba(8,26,34,.45) 72%,
    rgba(8,26,34,.10) 100%);
}
@media (max-width: 780px) {
  /* No room for the photo to breathe beside the text at this width, so the
     veil goes back to even coverage rather than leaving half the headline
     sitting on bare photograph. */
  .band::after { background: linear-gradient(180deg, rgba(8,26,34,.86) 0%, rgba(8,26,34,.80) 100%); }
}
.band__inner { max-width: 44ch; }
/* Text shadows are the backstop, not the plan. The gradient above does the real
   work; these keep the copy readable if a future photo is brighter than this
   one behind the same words. */
/* Descendant selectors, not bare .band__body / .band__eyebrow.
   theme.css loads AFTER site.css and sets `.lede { color: var(--ink-2) }`, so a
   single-class rule here loses the cascade on equal specificity and the band
   paragraph rendered in dark ink on a dark photo — invisible. `.band .x` is
   0,2,0 and wins. Same reason `.section--accent .lede` is written that way. */
.band h2 { color: #fff; font-size: clamp(1.75rem, 3.4vw, 2.6rem); text-shadow: 0 2px 10px rgba(0,0,0,.45); }
.band .band__eyebrow { color: #8FE6FF; text-shadow: 0 1px 6px rgba(0,0,0,.5); }
.band .band__body { color: #EAF6FA; margin-top: var(--s3); text-shadow: 0 1px 6px rgba(0,0,0,.55); }
.band .btn--secondary { background: transparent; color: #fff; border-color: rgba(255,255,255,.55); }
.band .btn--secondary:hover { background: rgba(255,255,255,.14); color: #fff; }

/* ---------- click-to-call callout ----------
   Deliberately loud: on the quote and pricing pages the phone is the faster
   conversion and it was previously a line of small grey text. */
.phone-callout {
  display: flex; align-items: center; gap: var(--s3);
  padding: var(--s3); margin-top: var(--s4);
  background: linear-gradient(135deg, #0A4A58 0%, #0F6F8C 100%);
  border-radius: var(--radius-lg); color: #fff; text-decoration: none;
  box-shadow: var(--shadow-md);
  transition: transform .18s, box-shadow .18s;
}
.phone-callout:hover { transform: translateY(-2px); box-shadow: 0 10px 28px rgba(10,74,88,.32); color: #fff; }
.phone-callout__icon {
  display: grid; place-items: center; flex: none;
  width: 52px; height: 52px; border-radius: 50%; background: rgba(255,255,255,.16);
}
.phone-callout__icon svg { width: 26px; height: 26px; fill: none; stroke: #fff; stroke-width: 2; }
.phone-callout__text { display: grid; gap: 2px; min-width: 0; }
.phone-callout__label { font-size: .8125rem; letter-spacing: .08em; text-transform: uppercase; color: #A8E9FB; font-weight: 600; }
.phone-callout__number { font-family: var(--font-head); font-size: clamp(1.375rem, 3vw, 1.75rem); line-height: 1.1; color: #fff; }
.phone-callout__sub { font-size: .875rem; color: #D3ECF4; }

/* Sitemap sub-services, indented under their hub. Replaces two escaped &nbsp;
   that were printing literally in front of every sub-service name. */
.linkcols a.is-sub { padding-left: var(--s3); font-size: .9375rem; color: var(--ink-3); }
.linkcols a.is-sub::before { content: "\2014\00a0"; color: var(--line); }

/* ---------- price anchor ---------- */
.price-anchor {
  background: linear-gradient(135deg, rgba(0,185,231,.12) 0%, rgba(245,158,11,.10) 100%);
  border: 1px solid rgba(0,185,231,.28);
  border-radius: var(--radius-lg); padding: var(--s5) var(--s4); text-align: center;
}
.price-anchor__figure { font-family: var(--font-head); font-size: clamp(1.5rem, 4vw, 2.25rem); color: var(--ink); }
.price-anchor__figure strong { color: var(--green-text); }
.price-anchor__body { max-width: 60ch; margin: var(--s3) auto 0; color: var(--ink-2); }
.price-anchor .btn-row { justify-content: center; }

/* ---------- dark CTA band ---------- */
.cta-band { background: var(--dark); color: var(--on-dark-2); }
.cta-band__inner { padding-block: var(--section-y); display: grid; gap: var(--s4); }
@media (min-width: 900px) { .cta-band__inner { grid-template-columns: 1.1fr .9fr; align-items: center; } }
.cta-band h2 { color: #fff; }
.cta-band .btn-row { margin-top: var(--s3); }
.cta-opts { display: grid; gap: 12px; }
.cta-opt { display: flex; gap: 12px; align-items: flex-start; padding: 14px 16px; background: var(--dark-2); border-radius: var(--radius); text-decoration: none; color: var(--on-dark-2); border: 1px solid rgba(255,255,255,.07); }
.cta-opt:hover { border-color: rgba(255,255,255,.22); color: #fff; }
.cta-opt strong { display: block; color: #fff; font-family: var(--font-head); font-size: .9688rem; }
.cta-opt span { font-size: .875rem; }

/* ---------- breadcrumb ---------- */
.crumbs { font-size: .875rem; color: var(--ink-3); padding-block: var(--s2); }
.crumbs ol { list-style: none; padding: 0; display: flex; flex-wrap: wrap; gap: 6px; }
.crumbs li + li::before { content: "/"; margin-right: 6px; color: var(--line); }
.crumbs a { color: var(--ink-3); text-decoration: none; }
.crumbs a:hover { color: var(--ink); text-decoration: underline; }

/* ---------- link columns (locations, sitemap) ---------- */
.linkcols { columns: 2; column-gap: var(--s4); }
@media (min-width: 700px) { .linkcols { columns: 3; } }
@media (min-width: 1000px) { .linkcols { columns: 4; } }
.linkcols a { display: block; padding: 5px 0; font-size: .9375rem; color: var(--ink-2); text-decoration: none; break-inside: avoid; }
.linkcols a:hover { color: var(--green-text); text-decoration: underline; }

.pill-row { display: flex; flex-wrap: wrap; gap: 8px; }
.pill { display: inline-block; padding: 7px 13px; border: 1px solid var(--line); border-radius: 999px; font-size: .875rem; color: var(--ink-2); text-decoration: none; background: #fff; }
.pill:hover { border-color: var(--green); color: var(--green-text); }

/* ---------- footer ---------- */
.site-footer { background: var(--dark); color: var(--on-dark-2); padding-block: var(--s6) var(--s4); font-size: .9375rem; }
.site-footer h4 { color: #fff; font-size: .8125rem; letter-spacing: .1em; text-transform: uppercase; margin-bottom: var(--s2); }
.site-footer a { color: var(--on-dark-2); text-decoration: none; }
.site-footer a:hover { color: #fff; text-decoration: underline; }
.footer__grid { display: grid; gap: var(--s4); }
@media (min-width: 760px) { .footer__grid { grid-template-columns: 1.4fr 1fr 1fr 1fr; } }
.footer__links { list-style: none; padding: 0; display: grid; gap: 9px; }
.footer__legal { margin-top: var(--s5); padding-top: var(--s3); border-top: 1px solid rgba(255,255,255,.1); display: flex; flex-wrap: wrap; gap: var(--s3); justify-content: space-between; font-size: .875rem; }

/* ---------- sticky mobile CTA ---------- */
.sticky-cta {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 60;
  display: grid; grid-template-columns: 1fr 1fr; gap: 1px;
  background: var(--line); border-top: 1px solid var(--line);
  box-shadow: 0 -2px 14px rgba(11,13,16,.10);
}
@media (min-width: 768px) { .sticky-cta { display: none; } }
.sticky-cta a { display: flex; align-items: center; justify-content: center; gap: 8px; min-height: 56px; background: #fff; color: var(--ink); font-family: var(--font-head); font-weight: 600; font-size: .9688rem; text-decoration: none; }
.sticky-cta a.is-primary { background: var(--green); color: #fff; }
.sticky-cta svg { width: 18px; height: 18px; stroke: currentColor; stroke-width: 2; fill: none; }

/* ---------- prose ---------- */
.prose h2 { margin-top: var(--s5); margin-bottom: var(--s2); }
.prose h3 { margin-top: var(--s4); margin-bottom: 10px; }
.prose > *:first-child { margin-top: 0; }
.prose ul, .prose ol { margin-top: var(--s2); padding-left: 22px; display: grid; gap: 8px; }
.prose p + p { margin-top: var(--s2); }
.prose blockquote { margin: var(--s3) 0; padding: var(--s2) var(--s3); border-left: 4px solid var(--teal);
  background: var(--teal-050); border-radius: 0 var(--radius-sm) var(--radius-sm) 0; }
.prose blockquote p { font-size: 1.0625rem; color: var(--ink-2); }
.prose ol { list-style: decimal; }

/* ---------- config placeholder warning: must never ship silently ---------- */
.todo { background: var(--amber-050); border: 1px dashed var(--amber); border-radius: var(--radius-sm); padding: 3px 8px; font-size: .8125rem; font-weight: 600; color: #6B4A00; }

/* ---------- articles ---------- */
.measure-wide { max-width: 78ch; }
.article__head { padding: var(--s5) 0 var(--s3); }
.article__meta { margin-top: var(--s3); font-size: .875rem; color: var(--ink-3); display: flex; flex-wrap: wrap; gap: 8px; }
.article__figure { margin: var(--s3) 0 0; border-radius: var(--radius-lg); overflow: hidden; background: var(--surface-2); }
.article__figure img { display: block; width: 100%; height: auto; }
.article__grid { display: grid; gap: var(--s5); padding: var(--s5) 0 var(--section-y); align-items: start; }
.article__body { max-width: 68ch; }
.article__body .prose + .prose { margin-top: var(--s5); }
@media (min-width: 1000px) {
  .article__grid { grid-template-columns: minmax(0, 1fr) 260px; }
  .article__side { position: sticky; top: var(--s3); }
}

/* Table of contents. Ordered so the reading sequence is obvious without JS. */
.toc { border-left: 3px solid var(--line); padding-left: var(--s3); }
.toc h2 { font-size: .8125rem; text-transform: uppercase; letter-spacing: .08em; color: var(--ink-3); }
.toc ol { margin-top: var(--s2); padding-left: 1.1em; display: grid; gap: 10px; font-size: .9375rem; }
.toc a { color: var(--ink-2); text-decoration: none; }
.toc a:hover { color: var(--green-text); text-decoration: underline; }

.takeaway { background: var(--surface-2); border-radius: var(--radius); padding: var(--s3); margin-bottom: var(--s5); }
.takeaway h2 { font-size: .8125rem; text-transform: uppercase; letter-spacing: .08em; color: var(--ink-3); }
.takeaway ul { margin-top: var(--s2); padding-left: 20px; display: grid; gap: 8px; font-size: .9688rem; }

.inline-cta { margin: var(--s5) 0; padding: var(--s3); border: 1.5px solid var(--line); border-left: 5px solid var(--green);
  border-radius: var(--radius); display: grid; gap: var(--s2); align-items: center; background: var(--green-050); }
.inline-cta h3 { font-size: 1.125rem; }
.inline-cta p { font-size: .9375rem; color: var(--ink-2); margin-top: 4px; }
@media (min-width: 700px) { .inline-cta { grid-template-columns: 1fr auto; gap: var(--s3); } }

.authorbox { margin-top: var(--s5); padding-top: var(--s4); border-top: 1px solid var(--line); display: grid; gap: var(--s2); }
.authorbox p { font-size: .9375rem; color: var(--ink-2); }
@media (min-width: 700px) { .authorbox { grid-template-columns: auto 1fr; gap: var(--s3); } }

.card__img { display: block; width: calc(100% + var(--s3) * 2); max-width: none; margin: calc(var(--s3) * -1) 0 var(--s3) calc(var(--s3) * -1);
  height: auto; aspect-ratio: 16 / 9; object-fit: cover; border-radius: var(--radius) var(--radius) 0 0; background: var(--surface-2); }

.skip-link { position: absolute; left: -9999px; }
.skip-link:focus { left: var(--gutter); top: 10px; z-index: 100; background: #fff; padding: 10px 16px; border-radius: var(--radius-sm); box-shadow: var(--shadow-md); }
