/* ═══════════════════════════════════════════════════════════════════════════
   CHIP AWAY BATH REPAIRS
   Static site stylesheet · v1.0 · no build step · no external requests
   ---------------------------------------------------------------------------
   CONTENTS
     01  Design tokens — colour, type, space, radius, shadow, motion
     02  Dark theme tokens
     03  Reset and base elements
     04  Typography roles
     05  Layout primitives — container, section, flow, bands
     06  Chips motif — hero field, divider, button flick, card wells
     07  Buttons and links
     08  Skip link, header, nav, theme toggle
     09  Hero
     10  Trust strip
     11  Panels, cards, steps
     12  Before / after gallery
     13  Lightbox
     14  FAQ
     15  Suburb list
     16  Quote form
     17  Footer
     18  Sticky mobile call bar
     19  Placeholders (demo content markers)
     20  Focus, motion and print
   ═══════════════════════════════════════════════════════════════════════════ */


/* ═══ 01 · DESIGN TOKENS ══════════════════════════════════════════════════ */

:root {
  /* ── Indigo ramp — hue anchored on the existing logo chips ─────────────── */
  --indigo-50:  #F2F3FF;
  --indigo-100: #E4E5FF;
  --indigo-200: #CBCCFF;
  --indigo-300: #A5A6FF;
  --indigo-400: #7C7DFF;
  --indigo-500: #4A4BFE;  /* BRAND ANCHOR — unchanged from the logo file */
  --indigo-600: #3634DB;  /* interactive primary — all CTA fills */
  --indigo-700: #2A28B0;  /* hover, text links, eyebrows */
  --indigo-800: #211E86;  /* active / pressed */
  --indigo-900: #1A1863;

  /* ── Ink — navy-biased near-black. Never pure #000 in body copy. ───────── */
  --ink-900: #0F1330;
  --ink-800: #1A1F45;
  --ink-700: #2B3150;
  --ink-600: #4A5270;
  --ink-400: #8A90A8;
  --ink-200: #D5D8E4;

  /* ── Warm neutral surface — the "paper" ────────────────────────────────── */
  --paper:     #FAF8F5;   /* DEFAULT PAGE BACKGROUND — never #FFF */
  --paper-100: #F5F2ED;
  --paper-200: #EAE5DC;
  --paper-300: #D8D3C9;
  --white:     #FFFFFF;

  /* ── Semantic accents ──────────────────────────────────────────────────── */
  --repaired-600: #0D6B47;
  --repaired-700: #0B5A3C;
  --repaired-50:  #E9F6F0;
  --damage-700:   #8A3E06;
  --damage-50:    #FFF6E8;
  --danger-600:   #B8241C;

  /* ── Semantic tokens. Components use THESE, not the ramps. ─────────────── */
  --color-bg: var(--paper);
  --color-bg-alt: var(--paper-100);
  --color-bg-inverse: var(--ink-800);
  --color-surface: var(--white);
  --color-surface-2: var(--paper-100);
  --color-surface-tint: var(--indigo-50);
  --color-text: var(--ink-900);
  --color-text-muted: var(--ink-600);
  --color-text-inverse: var(--white);
  --color-text-inverse-mut: var(--indigo-200);
  --color-text-link: var(--indigo-700);
  --color-border: var(--paper-200);
  --color-border-strong: var(--ink-200);
  --color-focus: var(--indigo-500);
  --color-cta-bg: var(--indigo-600);
  --color-cta-bg-hover: var(--indigo-700);
  --color-cta-bg-active: var(--indigo-800);
  --color-cta-text: var(--white);
  --color-chip: var(--indigo-500);
  --color-eyebrow: var(--indigo-700);

  /* Photo grade. One grade for every photo — consistency is what makes
     an old photo library read as curated rather than as snapshots. */
  --photo-grade: saturate(.90) contrast(1.06) brightness(1.02);

  /* ── Type stacks — system only, zero bytes, zero requests ──────────────── */
  --font-display: "SF Pro Display", -apple-system, BlinkMacSystemFont,
                  "Segoe UI Variable Display", "Segoe UI", Inter, Roboto,
                  "Helvetica Neue", Arial, sans-serif;
  --font-body:    -apple-system, BlinkMacSystemFont, "Segoe UI Variable Text",
                  "Segoe UI", Inter, Roboto, "Helvetica Neue", Arial, sans-serif;
  --font-numeric: ui-monospace, "SF Mono", "Cascadia Mono", "Segoe UI Mono",
                  Menlo, Consolas, monospace;

  /* ── Type scale — 1.250 at mobile to 1.333 at desktop ─────────────────── */
  --step--2: clamp(0.694rem, 0.68rem + 0.07vw,  0.75rem);
  --step--1: clamp(0.833rem, 0.80rem + 0.16vw,  0.938rem);
  --step-0:  clamp(1.0625rem, 1.03rem + 0.16vw, 1.125rem);
  --step-1:  clamp(1.25rem,  1.19rem + 0.31vw,  1.5rem);
  --step-2:  clamp(1.5rem,   1.38rem + 0.59vw,  2rem);
  --step-3:  clamp(1.875rem, 1.66rem + 1.07vw,  2.666rem);
  --step-4:  clamp(2.25rem,  1.86rem + 1.95vw,  3.553rem);
  --step-5:  clamp(2.5rem,   1.90rem + 3.05vw,  4.738rem);

  /* ── Space ─────────────────────────────────────────────────────────────── */
  --space-3xs:.25rem; --space-2xs:.5rem; --space-xs:.75rem; --space-sm:1rem;
  --space-md:1.5rem;  --space-lg:2rem;   --space-xl:3rem;   --space-2xl:4rem;
  --space-3xl:6rem;   --space-4xl:8rem;

  --section-y:    clamp(3.5rem, 2.2rem + 6.5vw, 7rem);
  --section-y-lg: clamp(4.5rem, 3.0rem + 8vw,  9rem);
  --stack: var(--space-md);

  --container-sm:40rem; --container-md:52rem;
  --container-lg:68rem; --container-xl:82rem;
  --gutter: clamp(1.25rem, 0.9rem + 1.75vw, 2.5rem);

  --radius-xs:4px; --radius-sm:8px; --radius-md:12px; --radius-lg:16px;
  --radius-xl:24px; --radius-2xl:32px; --radius-pill:999px;

  /* Shadows are tinted ink, never black — black on warm paper goes muddy. */
  --shadow-xs:0 1px 2px rgba(15,19,48,.05);
  --shadow-sm:0 1px 2px rgba(15,19,48,.06), 0 2px 6px rgba(15,19,48,.05);
  --shadow-md:0 2px 4px rgba(15,19,48,.05), 0 6px 16px rgba(15,19,48,.07);
  --shadow-lg:0 4px 8px rgba(15,19,48,.05), 0 14px 32px rgba(15,19,48,.09);
  --shadow-xl:0 8px 16px rgba(15,19,48,.06), 0 28px 60px rgba(15,19,48,.12);
  --shadow-cta:0 1px 2px rgba(15,19,48,.10), 0 6px 20px rgba(54,52,219,.28);
  --shadow-cta-hover:0 2px 4px rgba(15,19,48,.12), 0 10px 28px rgba(54,52,219,.36);
  --ring-subtle: inset 0 0 0 1px var(--color-border);

  --ease-out: cubic-bezier(.22,.61,.36,1);
  --ease-spring: cubic-bezier(.34,1.32,.64,1);
  --dur-fast:140ms; --dur-base:240ms; --dur-slow:420ms;

  /* Chrome heights — used for sticky offsets and scroll padding. */
  --header-h: 4.25rem;
  --callbar-h: 4rem;
}


/* ═══ 02 · DARK THEME TOKENS ══════════════════════════════════════════════
   Not an inversion. The page becomes deep ink, cards lift one step, the
   indigo anchor brightens so white type still clears 4.5:1 on the CTA, and
   the photo grade loses a little brightness so the flash-lit bathroom shots
   do not glare against a dark surround.
   Every pairing below was checked against WCAG 2.1 AA.
     #FFFFFF on #4A4BFE  5.63:1   CTA fill
     #FFFFFF on #5B5CFF  4.80:1   CTA hover
     #FFFFFF on #3A3BE5  7.15:1   CTA active
     #F3F4FB on #0D1029 17.9:1    body text on page
     #A8AECB on #0D1029  8.46:1   muted text on page
     #A8AECB on #171B3D  7.49:1   muted text on cards
     #A5A6FF on #0D1029  8.45:1   links and eyebrows
   ═══════════════════════════════════════════════════════════════════════ */

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --color-bg: #0D1029;
    --color-bg-alt: #121635;
    --color-bg-inverse: #060818;
    --color-surface: #171B3D;
    --color-surface-2: #1D2148;
    --color-surface-tint: #1B1F4C;
    --color-text: #F3F4FB;
    --color-text-muted: #A8AECB;
    --color-text-inverse: #F3F4FB;
    --color-text-inverse-mut: #A8AECB;
    --color-text-link: #A5A6FF;
    --color-border: #262B55;
    --color-border-strong: #39406E;
    --color-cta-bg: #4A4BFE;
    --color-cta-bg-hover: #5B5CFF;
    --color-cta-bg-active: #3A3BE5;
    --color-cta-text: #FFFFFF;
    --color-eyebrow: #A5A6FF;
    --color-chip: #7C7DFF;

    --damage-50: #33200C;
    --damage-700: #FFB877;
    --repaired-600: #0F7A51;

    --photo-grade: saturate(.92) contrast(1.05) brightness(.94);

    --shadow-sm:0 1px 2px rgba(0,0,0,.45), 0 2px 6px rgba(0,0,0,.35);
    --shadow-md:0 2px 4px rgba(0,0,0,.40), 0 6px 16px rgba(0,0,0,.42);
    --shadow-lg:0 4px 8px rgba(0,0,0,.40), 0 14px 32px rgba(0,0,0,.48);
    --shadow-xl:0 8px 16px rgba(0,0,0,.45), 0 28px 60px rgba(0,0,0,.55);
    --shadow-cta:0 1px 2px rgba(0,0,0,.5), 0 6px 20px rgba(74,75,254,.30);
    --shadow-cta-hover:0 2px 4px rgba(0,0,0,.5), 0 10px 28px rgba(74,75,254,.42);
  }
}

/* Manual override — the header toggle stamps data-theme on <html>.
   Kept identical to the media-query block above. */
:root[data-theme="dark"] {
  --color-bg: #0D1029;
  --color-bg-alt: #121635;
  --color-bg-inverse: #060818;
  --color-surface: #171B3D;
  --color-surface-2: #1D2148;
  --color-surface-tint: #1B1F4C;
  --color-text: #F3F4FB;
  --color-text-muted: #A8AECB;
  --color-text-inverse: #F3F4FB;
  --color-text-inverse-mut: #A8AECB;
  --color-text-link: #A5A6FF;
  --color-border: #262B55;
  --color-border-strong: #39406E;
  --color-cta-bg: #4A4BFE;
  --color-cta-bg-hover: #5B5CFF;
  --color-cta-bg-active: #3A3BE5;
  --color-cta-text: #FFFFFF;
  --color-eyebrow: #A5A6FF;
  --color-chip: #7C7DFF;

  --damage-50: #33200C;
  --damage-700: #FFB877;
  --repaired-600: #0F7A51;

  --photo-grade: saturate(.92) contrast(1.05) brightness(.94);

  --shadow-sm:0 1px 2px rgba(0,0,0,.45), 0 2px 6px rgba(0,0,0,.35);
  --shadow-md:0 2px 4px rgba(0,0,0,.40), 0 6px 16px rgba(0,0,0,.42);
  --shadow-lg:0 4px 8px rgba(0,0,0,.40), 0 14px 32px rgba(0,0,0,.48);
  --shadow-xl:0 8px 16px rgba(0,0,0,.45), 0 28px 60px rgba(0,0,0,.55);
  --shadow-cta:0 1px 2px rgba(0,0,0,.5), 0 6px 20px rgba(74,75,254,.30);
  --shadow-cta-hover:0 2px 4px rgba(0,0,0,.5), 0 10px 28px rgba(74,75,254,.42);
}


/* ═══ 03 · RESET AND BASE ═════════════════════════════════════════════════ */

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

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  /* Anchor targets must clear the sticky demo bar and the sticky header. */
  scroll-padding-block-start: calc(var(--header-h) + 1.5rem);
}

body {
  margin: 0;
  background: var(--color-bg);
  color: var(--color-text);
  font-family: var(--font-body);
  font-size: var(--step-0);
  line-height: 1.62;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

img, svg, picture, video { max-width: 100%; }
img { height: auto; border: 0; }

h1, h2, h3, h4, p, figure, blockquote, ul, ol, dl, dd { margin: 0; }
ul[class], ol[class] { list-style: none; padding: 0; }

a { color: var(--color-text-link); text-underline-offset: .18em; }
a:hover { text-decoration-thickness: 2px; }

button { font: inherit; color: inherit; }

hr { border: 0; border-block-start: 1px solid var(--color-border); margin: 0; }

::selection { background: var(--indigo-200); color: var(--ink-900); }


/* ═══ 04 · TYPOGRAPHY ROLES ═══════════════════════════════════════════════
   Letter-spacing scales inversely with size: -0.028em at the hero through
   0 at body to +0.13em at the eyebrow. Uniform tracking is the single most
   reliable tell of a template.
   ═══════════════════════════════════════════════════════════════════════ */

p { max-width: 68ch; text-wrap: pretty; }

.hero-title {
  font-family: var(--font-display);
  font-size: var(--step-5);
  font-weight: 700;
  line-height: 1.02;
  letter-spacing: -0.028em;
  max-width: 11ch;          /* forces the break after the comma */
  text-wrap: balance;
  color: var(--color-text);
}

h2 {
  font-family: var(--font-display);
  font-size: var(--step-3);
  font-weight: 700;
  line-height: 1.10;
  letter-spacing: -0.020em;
  text-wrap: balance;
  max-width: 22ch;
  color: var(--color-text);
}

h3 {
  font-family: var(--font-display);
  font-size: var(--step-2);
  font-weight: 650;
  line-height: 1.18;
  letter-spacing: -0.012em;
  text-wrap: balance;
}

.lead {
  font-size: var(--step-1);
  font-weight: 400;
  line-height: 1.45;
  color: var(--color-text-muted);
  max-width: 46ch;
  text-wrap: pretty;
}

/* Eyebrow. The three-chip fragment replaces the coloured bar every trade
   template reaches for. Drawn in CSS — no image, no extra request. */
.eyebrow {
  font-size: var(--step--1);
  font-weight: 700;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--color-eyebrow);
  display: flex;
  align-items: center;
  gap: .6em;
  max-width: none;
}
.eyebrow::before {
  content: "";
  flex: 0 0 auto;
  inline-size: 26px;
  block-size: .5em;
  background-image: radial-gradient(ellipse 3px 2px at center,
                    currentColor 0 99%, transparent 100%);
  background-size: 9px 100%;
  background-repeat: repeat-x;
  opacity: .55;
  transform: rotate(-8deg);
}

/* The phone number is always tabular monospace so it reads as a fact. */
.phone-cta {
  font-family: var(--font-numeric);
  font-size: var(--step-2);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.01em;
  text-decoration: none;
}
.phone-inline {
  font-family: var(--font-numeric);
  font-variant-numeric: tabular-nums;
  letter-spacing: 0;
  font-size: .95em;
}

.caption { font-size: var(--step--1); line-height: 1.45; color: var(--color-text-muted); }


/* ═══ 05 · LAYOUT PRIMITIVES ══════════════════════════════════════════════
   Rule that does most of the work: vertical space BETWEEN sections is at
   least twice the largest gap INSIDE a section.
   ═══════════════════════════════════════════════════════════════════════ */

.container {
  width: 100%;
  max-width: var(--container-lg);
  margin-inline: auto;
  padding-inline: var(--gutter);
}
.container--wide { max-width: var(--container-xl); }

.section { padding-block: var(--section-y); }
.section--hero, .section--gallery { padding-block: var(--section-y-lg); }
.section--tight { padding-block: clamp(2rem, 1.2rem + 3.5vw, 3.5rem); }

.flow > * + * { margin-block-start: var(--stack); }
.flow > .eyebrow + h2 { margin-block-start: var(--space-2xs); }
.flow > h2 + .lead { margin-block-start: var(--space-sm); }

.band-alt  { background: var(--color-bg-alt); }
.band-ink  { background: var(--color-bg-inverse); color: var(--color-text-inverse); }
.band-ink h2, .band-ink h3 { color: var(--color-text-inverse); }
.band-ink .lead, .band-ink p { color: var(--color-text-inverse-mut); }
.band-ink .eyebrow { color: var(--indigo-300); }
.band-ink a { color: var(--indigo-300); }

/* Two-column blocks. Single column until there is genuinely room for two. */
.two-col {
  display: grid;
  gap: clamp(var(--space-lg), 4vw, var(--space-2xl));
  align-items: start;
}
@media (min-width: 56rem) {
  .two-col { grid-template-columns: 1.15fr .85fr; }
  .two-col--balanced { grid-template-columns: 1fr 1fr; }
  .two-col--form { grid-template-columns: .9fr 1.1fr; }
  /* The map is tall and portrait, so it gets the narrower column and the
     copy gets room to breathe beside it. */
  .two-col--map { grid-template-columns: 1.1fr .9fr; align-items: center; }
}

.section-foot {
  margin-block-start: var(--space-xl);
  color: var(--color-text-muted);
  max-width: 60ch;
}


/* ═══ 06 · CHIPS MOTIF ════════════════════════════════════════════════════
   One deterministic nine-chip constellation, defined once as an SVG symbol
   in the HTML and reused. Always diagonal bottom-right to top-left, always
   one hue, never above 20% opacity behind text, never used as wallpaper.
   ═══════════════════════════════════════════════════════════════════════ */

.chips { display: block; inline-size: 100%; block-size: 100%; fill: currentColor; }

/* (a) Hero chip field — two instances, cropped by the viewport edge. */
.hero { position: relative; isolation: isolate; overflow: clip; }
.hero__chipfield {
  position: absolute;
  inset-block-start: -8%;
  inset-inline-end: -14%;
  inline-size: min(56rem, 78vw);
  aspect-ratio: 120 / 100;
  color: var(--color-chip);
  opacity: .10;
  z-index: -1;
  pointer-events: none;
}
.hero__chipfield svg { inline-size: 100%; block-size: 100%; fill: currentColor; }
.hero__chipfield--near {
  inset-block-start: 42%;
  inset-inline-end: 6%;
  inline-size: min(22rem, 34vw);
  opacity: .16;
  transform: rotate(9deg);
}
@media (prefers-reduced-motion: no-preference) {
  @supports (animation-timeline: view()) {
    .hero__chipfield {
      animation: chipDrift linear both;
      animation-timeline: scroll(root);
      animation-range: 0 60vh;
    }
    @keyframes chipDrift { to { transform: translate3d(-26px,-14px,0) rotate(-3deg); } }
  }
}

/* (b) Section divider — chips converging and vanishing left to right.
   Placed once, at the pivot from "here is the damage" to "here is the proof". */
.chip-divider {
  --chip-size: 9px;
  block-size: var(--space-3xl);
  display: grid;
  place-items: center;
  overflow: clip;
  background: linear-gradient(180deg, var(--color-bg-alt) 0%, var(--color-bg) 100%);
}
.chip-divider__track {
  inline-size: min(var(--container-md), 90vw);
  block-size: var(--chip-size);
  position: relative;
}
.chip-divider__track::before {
  content: "";
  position: absolute;
  inset: 0;
  background-image: radial-gradient(ellipse 4.5px 3px at center,
                    var(--color-chip) 0 99%, transparent 100%);
  background-repeat: repeat-x;
  background-size: 34px 100%;
  -webkit-mask-image: linear-gradient(90deg, rgba(0,0,0,1) 0%, rgba(0,0,0,.85) 22%,
                      rgba(0,0,0,.4) 55%, rgba(0,0,0,0) 88%);
  mask-image: linear-gradient(90deg, rgba(0,0,0,1) 0%, rgba(0,0,0,.85) 22%,
              rgba(0,0,0,.4) 55%, rgba(0,0,0,0) 88%);
  transform: rotate(-2.2deg);
  opacity: .8;
}
.chip-divider__track::after {
  content: "";
  position: absolute;
  inset-inline-end: 4%;
  inset-block-start: 1px;
  inline-size: 5px; block-size: 3.4px;
  border-radius: 50%;
  background: var(--indigo-300);
}


/* ═══ 07 · BUTTONS AND LINKS ══════════════════════════════════════════════ */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2xs);
  padding: var(--space-sm) var(--space-lg);
  border: 0;
  border-radius: var(--radius-pill);
  font-weight: 650;
  font-size: var(--step-0);
  line-height: 1.2;
  text-align: center;
  text-decoration: none;
  cursor: pointer;
  min-block-size: 3rem;      /* comfortable touch target */
}

/* (c) CTA hover and focus — three chips flick off the leading edge, then
   they are gone. The motif animates only on deliberate user action. */
.btn-primary {
  position: relative;
  background: var(--color-cta-bg);
  color: var(--color-cta-text);
  box-shadow: var(--shadow-cta);
  transition: background var(--dur-fast) var(--ease-out),
              box-shadow var(--dur-base) var(--ease-out),
              transform var(--dur-fast) var(--ease-out);
}
.btn-primary:hover { background: var(--color-cta-bg-hover); box-shadow: var(--shadow-cta-hover); transform: translateY(-1px); }
.btn-primary:active { background: var(--color-cta-bg-active); transform: translateY(0); }

.btn-primary__chips {
  position: absolute;
  inset-inline-start: -6px;
  inset-block-start: 50%;
  inline-size: 34px;
  aspect-ratio: 120 / 100;
  translate: 0 -50%;
  color: var(--indigo-500);
  opacity: 0;
  pointer-events: none;
}
.btn-primary__chips svg { inline-size: 100%; block-size: 100%; fill: currentColor; }

@media (prefers-reduced-motion: no-preference) {
  .btn-primary:hover .btn-primary__chips,
  .btn-primary:focus-visible .btn-primary__chips {
    animation: chipFlick 380ms var(--ease-out) forwards;
  }
  @keyframes chipFlick {
    0%   { opacity: 0; translate: 0 -50%; scale: .6; }
    30%  { opacity: .85; }
    100% { opacity: 0; translate: -22px calc(-50% - 12px); scale: 1.15; }
  }
}

.btn-ghost {
  background: transparent;
  color: var(--color-cta-bg);
  box-shadow: inset 0 0 0 2px currentColor;
  transition: background var(--dur-fast) var(--ease-out), color var(--dur-fast) var(--ease-out);
}
.btn-ghost:hover { background: var(--color-surface-tint); color: var(--color-cta-bg-hover); }

.band-ink .btn-ghost { color: var(--indigo-300); }
.band-ink .btn-ghost:hover { background: rgba(165,166,255,.12); color: var(--indigo-200); }

.btn-block { display: flex; width: 100%; }

.link-arrow {
  font-weight: 650;
  text-decoration: none;
  display: inline-flex;
  align-items: baseline;
  gap: .4em;
}
.link-arrow::after { content: "\2192"; transition: transform var(--dur-fast) var(--ease-out); }
.link-arrow:hover { text-decoration: underline; }
.link-arrow:hover::after { transform: translateX(3px); }

.icon-btn {
  display: inline-grid;
  place-items: center;
  inline-size: 2.75rem;
  block-size: 2.75rem;
  padding: 0;
  border: 0;
  border-radius: var(--radius-pill);
  background: transparent;
  cursor: pointer;
  color: var(--color-text);
}
.icon-btn:hover { background: var(--color-surface-tint); }
.icon-btn svg { inline-size: 1.35rem; block-size: 1.35rem; fill: none; stroke: currentColor; stroke-width: 1.9; }


/* ═══ 08 · SKIP LINK, HEADER, NAV ═════════════════════════════════════════ */

.skip-link {
  position: absolute;
  inset-block-start: -100%;
  inset-inline-start: var(--space-sm);
  z-index: 200;
  padding: var(--space-2xs) var(--space-sm);
  background: var(--color-cta-bg);
  color: var(--color-cta-text);
  border-radius: 0 0 var(--radius-sm) var(--radius-sm);
  text-decoration: none;
  font-weight: 650;
}
.skip-link:focus { inset-block-start: 0; }




.site-header {
  position: sticky;
  inset-block-start: 0;
  z-index: 100;
  background: var(--color-bg);
  border-block-end: 1px solid transparent;
  transition: box-shadow var(--dur-base) var(--ease-out),
              border-color var(--dur-base) var(--ease-out);
}
.site-header.is-stuck {
  box-shadow: var(--shadow-sm);
  border-block-end-color: var(--color-border);
}
.site-header__inner {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  min-block-size: var(--header-h);
}

.logo-link { display: block; flex: 0 0 auto; line-height: 0; margin-inline-end: auto; }
.logo-link__img { inline-size: clamp(9.5rem, 6rem + 12vw, 12.5rem); block-size: auto; }

.site-nav { display: none; }
.site-nav__list { display: flex; flex-wrap: nowrap; gap: clamp(.75rem, .2rem + 1vw, 1.5rem); }
.site-nav__list a {
  text-decoration: none;
  color: var(--color-text);
  font-size: var(--step--1);
  font-weight: 600;
  padding-block: .5rem;
  border-block-end: 2px solid transparent;
  /* Multi-word labels must never break across lines — a wrapped nav item
     pushes the header to two and three rows. */
  white-space: nowrap;
}
.site-nav__list a:hover { color: var(--color-text-link); border-block-end-color: currentColor; }

.site-header__contact { display: none; text-align: end; line-height: 1.25; }
/* Hours stay out of the header until there is genuinely room for them.
   The footer carries the same information at every width. */
.site-header__hours { display: none; font-size: var(--step--2); }
.site-header__phone { color: var(--color-text); font-size: var(--step-1); display: block; }
.site-header__phone:hover { color: var(--color-text-link); }

.site-header__quote { display: none; padding: .65rem 1.15rem; min-block-size: 2.75rem; font-size: var(--step--1); }

.nav-toggle { flex: 0 0 auto; }
.nav-toggle__bars { display: grid; gap: 4px; inline-size: 1.3rem; }
.nav-toggle__bars i {
  display: block; block-size: 2px; background: currentColor; border-radius: 2px;
  transition: transform var(--dur-base) var(--ease-out), opacity var(--dur-base) var(--ease-out);
}
/* Open state — main.js sets .is-open. Bars fold into a cross. */
.nav-toggle.is-open .nav-toggle__bars i:nth-child(1) { transform: translateY(6px) rotate(45deg); }
.nav-toggle.is-open .nav-toggle__bars i:nth-child(2) { opacity: 0; }
.nav-toggle.is-open .nav-toggle__bars i:nth-child(3) { transform: translateY(-6px) rotate(-45deg); }

.theme-toggle__moon { display: none; }
:root[data-theme="dark"] .theme-toggle__sun { display: none; }
:root[data-theme="dark"] .theme-toggle__moon { display: block; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .theme-toggle__sun { display: none; }
  :root:not([data-theme="light"]) .theme-toggle__moon { display: block; }
}
.theme-toggle svg { fill: none; stroke: currentColor; stroke-width: 1.8; }
.theme-toggle__moon { fill: currentColor; stroke: none; }

.mobile-panel {
  border-block-start: 1px solid var(--color-border);
  background: var(--color-bg);
  padding-block: var(--space-sm) var(--space-md);
}
.mobile-panel[hidden] { display: none; }
.mobile-panel__list { display: grid; gap: 2px; }
.mobile-panel__list a {
  display: block;
  padding: .8rem var(--space-2xs);
  text-decoration: none;
  color: var(--color-text);
  font-weight: 600;
  border-radius: var(--radius-sm);
}
.mobile-panel__list a:hover { background: var(--color-surface-tint); color: var(--color-text-link); }
.mobile-panel__hours { margin-block-start: var(--space-sm); }

@media (min-width: 62rem) {
  .site-nav { display: block; }
  .site-header__contact { display: block; }
  .site-header__quote { display: inline-flex; }
  .nav-toggle { display: none; }
  .mobile-panel { display: none !important; }
  .logo-link { margin-inline-end: var(--space-md); }
  .site-nav { margin-inline-end: auto; }
}

/* Widest desktops only — enough room to bring the hours back into the header. */
@media (min-width: 82rem) {
  .site-header__hours { display: block; }
}


/* ═══ 09 · HERO ═══════════════════════════════════════════════════════════ */

.hero__inner {
  display: grid;
  gap: clamp(var(--space-xl), 5vw, var(--space-3xl));
  align-items: center;
}
@media (min-width: 64rem) {
  .hero__inner { grid-template-columns: 1.05fr .95fr; max-width: var(--container-xl); }
}

.hero__copy > * + * { margin-block-start: var(--space-md); }
.hero__copy > .eyebrow + .hero-title { margin-block-start: var(--space-sm); }

.hero__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-sm);
  margin-block-start: var(--space-lg);
}
.hero__actions .btn { flex: 1 1 auto; }
@media (min-width: 30rem) { .hero__actions .btn { flex: 0 0 auto; } }

.hero__reassure { color: var(--color-text-muted); max-width: 46ch; }
.hero__areas {
  font-size: var(--step--1);
  color: var(--color-text-muted);
  max-width: 46ch;
  padding-block-start: var(--space-sm);
  border-block-start: 1px solid var(--color-border);
}

.ba--hero { max-inline-size: 44rem; margin-inline: auto; }


/* ═══ 10 · TRUST STRIP ════════════════════════════════════════════════════ */

.trust__list {
  display: grid;
  gap: var(--space-md) var(--space-lg);
  grid-template-columns: 1fr;
}
@media (min-width: 34rem) { .trust__list { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 64rem) { .trust__list { grid-template-columns: repeat(4, 1fr); } }

.trust__item p:not(.eyebrow) {
  margin-block-start: var(--space-2xs);
  font-size: var(--step--1);
  line-height: 1.5;
  color: var(--color-text);
  max-width: 34ch;
}
.trust__holds {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2xs);
  margin-block-start: var(--space-lg);
  max-width: none;
}


/* ═══ 11 · PANELS, CARDS, STEPS ═══════════════════════════════════════════
   Nested radii obey inner = outer - padding. Getting this wrong is the most
   visible amateur tell in a card layout.
   ═══════════════════════════════════════════════════════════════════════ */

.panel {
  background: var(--color-surface);
  border-radius: var(--radius-xl);
  padding: clamp(var(--space-md), 3vw, var(--space-xl));
  box-shadow: var(--shadow-md), var(--ring-subtle);
}
.panel__title { font-size: var(--step-2); margin-block-end: var(--space-md); }

.pull-quote {
  margin: 0;
  padding-inline-start: var(--space-md);
  border-inline-start: 3px solid var(--color-chip);
}
.pull-quote p { max-width: 44ch; }

.tick-list { display: grid; gap: var(--space-sm); }
.tick-list li {
  position: relative;
  padding-inline-start: 1.9rem;
  line-height: 1.5;
  color: var(--color-text);
}
.tick-list li::before {
  content: "";
  position: absolute;
  inset-inline-start: 0;
  inset-block-start: .62em;
  inline-size: 9px; block-size: 6px;
  border-radius: 50%;
  background: var(--damage-700);
  transform: rotate(-18deg);
}

.card-grid {
  display: grid;
  gap: var(--space-lg);
  grid-template-columns: 1fr;
  margin-block-start: var(--space-xl);
}
@media (min-width: 40rem) { .card-grid { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 64rem) { .card-grid { grid-template-columns: repeat(3, 1fr); } }
@media (min-width: 40rem) { .card-grid--2 { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 64rem) { .card-grid--2 { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 64rem) { .card-grid--3 { grid-template-columns: repeat(3, 1fr); } }

.card {
  position: relative;
  background: var(--color-surface);
  border-radius: var(--radius-xl);
  padding: clamp(var(--space-md), 2.5vw, var(--space-lg));
  box-shadow: var(--shadow-sm), var(--ring-subtle);
  transition: box-shadow var(--dur-base) var(--ease-out), transform var(--dur-base) var(--ease-out);
}
.card:hover { box-shadow: var(--shadow-md), var(--ring-subtle); transform: translateY(-2px); }
.card h3 { margin-block-end: var(--space-2xs); font-size: var(--step-2); }
.card p { font-size: var(--step-0); }
.card p + p { margin-block-start: var(--space-sm); }
.card__materials { font-size: var(--step--1); color: var(--color-text-muted); }

/* Service-card icon well: a chips instance at 8%, lifting to 14% and
   translating up-left on hover. Nothing else on the card moves. */
.card__well {
  display: block;
  inline-size: 3.25rem;
  aspect-ratio: 120 / 100;
  margin-block-end: var(--space-sm);
  color: var(--color-chip);
  opacity: .08;
  transition: opacity var(--dur-base) var(--ease-out), transform var(--dur-base) var(--ease-out);
}
.card:hover .card__well { opacity: .14; transform: translate(-4px, -2px); }

.card--audience p { color: var(--color-text-muted); }
.card--audience h3 { color: var(--color-text); }
.card--placeholder { background: transparent; box-shadow: none; padding: 0; }
.card--placeholder:hover { transform: none; }

.steps {
  display: grid;
  gap: var(--space-lg);
  grid-template-columns: 1fr;
  margin-block-start: var(--space-xl);
  counter-reset: step;
}
@media (min-width: 40rem) { .steps { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 68rem) { .steps { grid-template-columns: repeat(4, 1fr); } }

.step {
  padding-block-start: var(--space-md);
  border-block-start: 2px solid var(--color-border-strong);
}
.step__num {
  display: block;
  font-family: var(--font-numeric);
  font-variant-numeric: tabular-nums;
  font-size: var(--step-2);
  font-weight: 700;
  color: var(--color-chip);
  line-height: 1;
  margin-block-end: var(--space-2xs);
}
.step h3 { font-size: var(--step-1); margin-block-end: var(--space-2xs); }
.step p { font-size: var(--step--1); line-height: 1.55; color: var(--color-text-muted); }
.step p + p { margin-block-start: var(--space-sm); }


/* ═══ 12 · BEFORE / AFTER GALLERY ═════════════════════════════════════════
   IMPORTANT, and the reason this does not use a drag slider:
   every source photo the client supplied is a SINGLE image that already
   contains both states — some stacked (before above, after below), some
   side by side (before left, after right). There is no separate "before"
   and "after" file to cross-fade or wipe between, and the two halves are
   not shot from a locked-off camera, so a wipe would visibly tear.
   The honest treatment is a framed plate with the labels placed to match
   each photo's own orientation, plus a lightbox for the detail.
   ═══════════════════════════════════════════════════════════════════════ */

.ba-grid {
  display: grid;
  gap: var(--space-lg);
  grid-template-columns: 1fr;
  align-items: start;
  margin-block-start: var(--space-xl);
}
@media (min-width: 40rem) { .ba-grid { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 64rem) {
  .ba-grid { grid-template-columns: repeat(3, 1fr); }
  /* The two panoramic pairs (705x300) span two columns so they are not
     squeezed into a portrait cell. 5 normal + 2 double = exactly 3 rows. */
  .ba--wide { grid-column: span 2; }
}

.ba {
  --ba-radius: var(--radius-lg);
  margin: 0;
  background: var(--color-surface);
  border-radius: calc(var(--ba-radius) + var(--space-2xs));  /* inner = outer - padding */
  padding: var(--space-2xs);
  box-shadow: var(--shadow-md), var(--ring-subtle);
  transition: box-shadow var(--dur-base) var(--ease-out), transform var(--dur-base) var(--ease-out);
}
.ba:hover { box-shadow: var(--shadow-lg), var(--ring-subtle); transform: translateY(-2px); }

.ba__zoom {
  display: block;
  inline-size: 100%;
  padding: 0;
  border: 0;
  background: none;
  cursor: zoom-in;
  border-radius: var(--ba-radius);
}

.ba__frame {
  display: block;
  position: relative;
  aspect-ratio: var(--ar, 4 / 3);
  border-radius: var(--ba-radius);
  overflow: hidden;
  background: var(--color-surface-2);
}
.ba__frame img {
  display: block;
  inline-size: 100%;
  block-size: 100%;
  object-fit: cover;             /* frame ratio == natural ratio, so nothing crops */
  filter: var(--photo-grade);
  transition: filter var(--dur-slow) var(--ease-out), transform var(--dur-slow) var(--ease-out);
}
.ba__zoom:hover .ba__frame img { filter: saturate(.96) contrast(1.08) brightness(1.03); }

/* 1px inset ring keeps low-resolution edges from bleeding into the mount. */
.ba__frame::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  border-radius: inherit;
  box-shadow: inset 0 0 0 1px rgba(15,19,48,.10);
}

.ba__label {
  position: absolute;
  z-index: 2;
  padding: .28rem var(--space-xs);
  border-radius: var(--radius-pill);
  font-family: var(--font-body);
  font-size: var(--step--1);
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
  line-height: 1.2;
  color: #FFFFFF;                /* solid fills only — never translucent over photos */
  box-shadow: 0 1px 3px rgba(15,19,48,.28);
}
.ba__label--before { background: #8A3E06; }   /* 7.57:1 with white */
.ba__label--after  { background: #0D6B47; }   /* 6.54:1 with white */

/* Label placement follows the photo's own orientation. */
.ba--stacked .ba__label--before { inset-block-start: var(--space-2xs); inset-inline-start: var(--space-2xs); }
.ba--stacked .ba__label--after  { inset-block-end: var(--space-2xs);   inset-inline-start: var(--space-2xs); }
.ba--side .ba__label--before    { inset-block-end: var(--space-2xs);   inset-inline-start: var(--space-2xs); }
.ba--side .ba__label--after     { inset-block-end: var(--space-2xs);   inset-inline-end: var(--space-2xs); }

/* ── Two-image pairs ──────────────────────────────────────────────────────
   Brad's newer photos arrive as separate before and after files rather than
   one frame containing both, so these sit side by side inside one figure.
   Each half is its own lightbox entry (data-state drives which label shows).
   ─────────────────────────────────────────────────────────────────────── */
.ba--pair .ba__pairimgs {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 3px;
  border-radius: var(--ba-radius);
  overflow: hidden;
}
.ba--pair .ba__zoom { display: block; inline-size: 100%; }
.ba--pair .ba__frame { border-radius: 0; }
.ba--pair .ba__label--before,
.ba--pair .ba__label--after {
  inset-block-end: var(--space-2xs);
  inset-inline-start: var(--space-2xs);
  inset-block-start: auto;
  inset-inline-end: auto;
}

.ba__zoomcue {
  position: absolute;
  z-index: 2;
  inset-block-start: var(--space-2xs);
  inset-inline-end: var(--space-2xs);
  padding: .28rem var(--space-xs);
  border-radius: var(--radius-pill);
  background: rgba(15,19,48,.78);
  color: #FFFFFF;
  font-size: var(--step--2);
  font-weight: 650;
  letter-spacing: .05em;
  text-transform: uppercase;
  opacity: 0;
  transition: opacity var(--dur-base) var(--ease-out);
}
.ba__zoom:hover .ba__zoomcue,
.ba__zoom:focus-visible /* ── Two-image pairs ──────────────────────────────────────────────────────
   Brad's newer photos arrive as separate before and after files rather than
   one frame containing both, so these sit side by side inside one figure.
   Each half is its own lightbox entry (data-state drives which label shows).
   ─────────────────────────────────────────────────────────────────────── */
.ba--pair .ba__pairimgs {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 3px;
  border-radius: var(--ba-radius);
  overflow: hidden;
}
.ba--pair .ba__zoom { display: block; inline-size: 100%; }
.ba--pair .ba__frame { border-radius: 0; }
.ba--pair .ba__label--before,
.ba--pair .ba__label--after {
  inset-block-end: var(--space-2xs);
  inset-inline-start: var(--space-2xs);
  inset-block-start: auto;
  inset-inline-end: auto;
}

.ba__zoomcue { opacity: 1; }

.ba__caption {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: .2rem .5rem;
  padding: var(--space-sm) var(--space-2xs) var(--space-2xs);
  font-size: var(--step--1);
  line-height: 1.45;
  color: var(--color-text-muted);
}
.ba__what { font-weight: 700; color: var(--color-text); }
.ba__sep { color: var(--color-border-strong); }
.ba__orient { font-variant-caps: all-small-caps; letter-spacing: .06em; }
.ba__body { flex: 1 0 100%; }

.gallery__note { max-width: 60ch; }

/* HARD GUARD for ba-alu-frame.jpg (286x215) and any other small original.
   It is not rendered in the gallery today — see the note in index.html —
   but if it is ever added, this stops it being blown up past native size. */
.ba--natural .ba__frame { max-inline-size: 286px; }
.ba--natural .ba__frame img { image-rendering: auto; }


/* ═══ 13 · LIGHTBOX ═══════════════════════════════════════════════════════ */

.lightbox {
  border: 0;
  padding: 0;
  max-inline-size: 100vw;
  max-block-size: 100dvh;
  inline-size: 100%;
  block-size: 100%;
  background: transparent;
  color: var(--white);
  overflow: hidden;
}
.lightbox::backdrop { background: rgba(6,8,24,.92); }

.lightbox__inner {
  position: relative;
  block-size: 100%;
  display: grid;
  place-items: center;
  padding: clamp(3.5rem, 8vw, 5rem) clamp(1rem, 6vw, 4.5rem);
}

.lightbox__close { position: absolute; inset-block-start: .75rem; inset-inline-end: .75rem; color: var(--white); }
.lightbox__nav   { position: absolute; inset-block-start: 50%; translate: 0 -50%; color: var(--white); }
.lightbox__nav--prev { inset-inline-start: .5rem; }
.lightbox__nav--next { inset-inline-end: .5rem; }
.lightbox__close:hover, .lightbox__nav:hover { background: rgba(255,255,255,.16); }

.lightbox__fig { display: grid; gap: var(--space-sm); justify-items: center; max-block-size: 100%; }

.lightbox__stage {
  position: relative;
  display: inline-block;
  line-height: 0;
  border-radius: var(--radius-md);
  overflow: hidden;
  box-shadow: var(--shadow-xl);
  background: #060818;
}
.lightbox__stage img {
  display: block;
  inline-size: auto;
  block-size: auto;
  max-inline-size: 100%;
  max-block-size: min(72dvh, 900px);
  filter: var(--photo-grade);
}
.lightbox__stage.is-stacked .ba__label--before { inset-block-start: var(--space-2xs); inset-inline-start: var(--space-2xs); }
.lightbox__stage.is-stacked .ba__label--after  { inset-block-end: var(--space-2xs);   inset-inline-start: var(--space-2xs); }
.lightbox__stage.is-side .ba__label--before    { inset-block-end: var(--space-2xs);   inset-inline-start: var(--space-2xs); }
.lightbox__stage.is-side .ba__label--after     { inset-block-end: var(--space-2xs);   inset-inline-end: var(--space-2xs); }

.lightbox__cap {
  max-inline-size: 62ch;
  text-align: center;
  font-size: var(--step--1);
  line-height: 1.5;
  color: #E6E7F5;
}


/* ═══ 14 · FAQ ════════════════════════════════════════════════════════════ */

.faq {
  max-width: var(--container-md);
  margin-block-start: var(--space-xl);
  border-block-start: 1px solid var(--color-border-strong);
}
.faq__item { border-block-end: 1px solid var(--color-border-strong); }
.faq__item summary {
  display: flex;
  align-items: flex-start;
  gap: var(--space-sm);
  padding-block: var(--space-md);
  cursor: pointer;
  list-style: none;
  font-family: var(--font-display);
  font-size: var(--step-1);
  font-weight: 650;
  line-height: 1.3;
  letter-spacing: -0.012em;
  color: var(--color-text);
}
.faq__item summary::-webkit-details-marker { display: none; }
.faq__item summary::after {
  content: "";
  flex: 0 0 auto;
  margin-inline-start: auto;
  margin-block-start: .35em;
  inline-size: .8em; block-size: .8em;
  border-inline-end: 2.5px solid var(--color-chip);
  border-block-end: 2.5px solid var(--color-chip);
  rotate: 45deg;
  transition: rotate var(--dur-base) var(--ease-out);
}
.faq__item[open] summary::after { rotate: -135deg; }
.faq__item summary:hover { color: var(--color-text-link); }
.faq__body { padding-block-end: var(--space-md); }
.faq__body p { color: var(--color-text-muted); }
.faq__body p + p { margin-block-start: var(--space-sm); }


/* ═══ 15 · SUBURB LIST ════════════════════════════════════════════════════ */

.suburb-list {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2xs);
}
.suburb-list li {
  padding: .35rem .8rem;
  border-radius: var(--radius-pill);
  background: var(--color-surface-tint);
  color: var(--color-text);
  font-size: var(--step--1);
  font-weight: 600;
}

.areas__panel { margin-block-start: var(--space-xl); }
.panel__foot {
  margin-block-start: var(--space-md);
  font-size: var(--step--1);
  color: var(--color-text-muted);
}


/* ═══ SERVICE AREA MAP ════════════════════════════════════════════════════
   Hand-drawn inline SVG, equirectangular projection of the western side of
   Port Phillip Bay. Inline rather than an embed because the CSP forbids any
   external request, and because it themes with the rest of the page.
   Regenerate with scratchpad/genmap.py if the boundary changes.
   ═══════════════════════════════════════════════════════════════════════ */

.areamap { margin: 0; }

.areamap__frame {
  background: var(--map-water);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  overflow: hidden;
  box-shadow: var(--shadow-sm);
}

.areamap__svg { display: block; inline-size: 100%; block-size: auto; }

/* Map palette. Kept as its own tokens so the map can be retuned without
   touching page colours. */
:root {
  --map-land:  var(--paper-200);
  --map-water: var(--indigo-100);
  --map-area:  var(--indigo-500);
  --map-line:  var(--ink-400);
  --map-ink:   var(--ink-900);
  --map-sea:   var(--indigo-400);
}
:root[data-theme="dark"] {
  --map-land:  #1B2048;
  --map-water: #10142F;
  --map-area:  #5B5CFF;
  --map-line:  #4A5280;
  --map-ink:   #F3F4FB;
  --map-sea:   #5A6099;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --map-land:  #1B2048;
    --map-water: #10142F;
    --map-area:  #5B5CFF;
    --map-line:  #4A5280;
    --map-ink:   #F3F4FB;
    --map-sea:   #5A6099;
  }
}

.areamap__land  { fill: var(--map-land); }
.areamap__area  { fill: var(--map-area); fill-opacity: .22; stroke: var(--map-area);
                  stroke-width: 3; stroke-opacity: .55; }
.areamap__water { fill: var(--map-water); }
.areamap__fwy   { fill: none; stroke: var(--map-line); stroke-width: 4;
                  stroke-dasharray: 14 12; stroke-linecap: round; opacity: .8; }

.areamap__sea {
  fill: var(--map-sea);
  font-size: 26px;
  font-weight: 700;
  letter-spacing: .14em;
  text-anchor: middle;
}
.areamap__sea--sm { font-size: 19px; }

.areamap__place circle { fill: var(--map-area); stroke: var(--map-water); stroke-width: 3; }
.areamap__place text {
  fill: var(--map-ink);
  font-size: 27px;
  font-weight: 650;
  paint-order: stroke;
  stroke: var(--map-land);
  stroke-width: 5;
  stroke-linejoin: round;
}

.areamap__cap {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-xs) var(--space-md);
  margin-block-start: var(--space-sm);
  font-size: var(--step--1);
  color: var(--color-text-muted);
}
.areamap__key { display: inline-flex; align-items: center; gap: .5rem; font-weight: 600;
                color: var(--color-text); }
.areamap__swatch {
  inline-size: 1.1rem; block-size: 1.1rem; border-radius: 4px;
  background: color-mix(in srgb, var(--map-area) 22%, transparent);
  border: 2px solid color-mix(in srgb, var(--map-area) 55%, transparent);
}


/* ═══ 16 · QUOTE FORM ═════════════════════════════════════════════════════ */

.form-wrap {
  background: var(--color-surface);
  border-radius: var(--radius-2xl);
  padding: clamp(var(--space-md), 3vw, var(--space-xl));
  box-shadow: var(--shadow-lg), var(--ring-subtle);
}

.hp-field { position: absolute; inline-size: 1px; block-size: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }

.field + .field { margin-block-start: var(--space-md); }
.field label {
  display: block;
  font-weight: 650;
  font-size: var(--step--1);
  margin-block-end: var(--space-3xs);
  color: var(--color-text);
}
.field__opt { font-weight: 400; color: var(--color-text-muted); }

.field input[type="text"],
.field input[type="tel"],
.field input[type="email"],
.field textarea {
  inline-size: 100%;
  padding: .8rem var(--space-sm);
  font: inherit;
  font-size: var(--step-0);
  color: var(--color-text);
  background: var(--color-bg);
  border: 1.5px solid var(--color-border-strong);
  border-radius: var(--radius-md);
  transition: border-color var(--dur-fast) var(--ease-out), box-shadow var(--dur-fast) var(--ease-out);
}
.field textarea { resize: vertical; min-block-size: 6rem; line-height: 1.5; }
.field input:hover, .field textarea:hover { border-color: var(--color-chip); }
.field input:focus, .field textarea:focus {
  outline: none;
  border-color: var(--color-chip);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-chip) 32%, transparent);
}
.field input[type="file"] {
  inline-size: 100%;
  font-size: var(--step--1);
  padding: .7rem;
  border: 1.5px dashed var(--color-border-strong);
  border-radius: var(--radius-md);
  background: var(--color-bg);
  color: var(--color-text-muted);
}
.field input[type="file"]::file-selector-button {
  font: inherit;
  font-weight: 650;
  margin-inline-end: var(--space-sm);
  padding: .5rem 1rem;
  border: 0;
  border-radius: var(--radius-pill);
  background: var(--color-surface-tint);
  color: var(--color-cta-bg);
  cursor: pointer;
}
.field__help { margin-block-start: var(--space-3xs); font-size: var(--step--1); color: var(--color-text-muted); }

.quote-form button[type="submit"] { margin-block-start: var(--space-lg); }
.form-foot { margin-block-start: var(--space-sm); font-size: var(--step--1); color: var(--color-text-muted); text-align: center; }

.form-error {
  margin-block-start: var(--space-md);
  padding: var(--space-sm);
  border-radius: var(--radius-md);
  background: var(--danger-600);
  color: #FFFFFF;
  font-size: var(--step--1);
}
.form-error a { color: #FFFFFF; }
.form-error[hidden] { display: none; }

.form-success {
  border-radius: var(--radius-lg);
  padding: var(--space-lg);
  background: var(--repaired-50);
  border: 1.5px solid var(--repaired-600);
}
.form-success h3 { font-size: var(--step-2); color: var(--repaired-700); margin-block-end: var(--space-2xs); }
.form-success p { color: var(--ink-900); }
.form-success a { color: var(--repaired-700); }
.form-success[hidden] { display: none; }
:root[data-theme="dark"] .form-success,
:root[data-theme="dark"] .form-success p { color: #F3F4FB; }
:root[data-theme="dark"] .form-success { background: #0E2B22; }
:root[data-theme="dark"] .form-success h3,
:root[data-theme="dark"] .form-success a { color: #7DE0B4; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .form-success { background: #0E2B22; }
  :root:not([data-theme="light"]) .form-success p { color: #F3F4FB; }
  :root:not([data-theme="light"]) .form-success h3,
  :root:not([data-theme="light"]) .form-success a { color: #7DE0B4; }
}


/* ═══ 17 · FOOTER ═════════════════════════════════════════════════════════ */

.site-footer {
  background: var(--ink-900);
  color: #FFFFFF;
  padding-block: var(--section-y) var(--space-xl);
}
.site-footer__grid {
  display: grid;
  gap: var(--space-xl);
  grid-template-columns: 1fr;
}
@media (min-width: 48rem) { .site-footer__grid { grid-template-columns: 1.3fr 1fr 1fr; } }

.site-footer__brand img { inline-size: 11rem; block-size: auto; margin-block-end: var(--space-md); }
.site-footer p { color: var(--indigo-200); font-size: var(--step--1); line-height: 1.6; }
.site-footer a { color: #FFFFFF; }
.site-footer__h {
  font-size: var(--step--1);
  font-weight: 700;
  letter-spacing: .13em;
  text-transform: uppercase;
  color: var(--indigo-300);
  margin-block-end: var(--space-sm);
  max-width: none;
}
.site-footer__col p + p { margin-block-start: var(--space-2xs); }
.site-footer .phone-cta { color: #FFFFFF; font-size: var(--step-1); }
.site-footer__services { color: var(--indigo-200); }

.site-footer__legal {
  margin-block-start: var(--space-xl);
  padding-block-start: var(--space-md);
  border-block-start: 1px solid rgba(255,255,255,.14);
}
.site-footer__legal p { font-size: var(--step--2); color: var(--indigo-200); max-width: none; }


/* ═══ 18 · STICKY MOBILE CALL BAR ═════════════════════════════════════════
   The highest-leverage element on a phone-conversion trade site. Below 48rem
   only. Body gains matching bottom padding so it never covers the footer.
   ═══════════════════════════════════════════════════════════════════════ */

.callbar { display: none; }

@media (max-width: 47.99rem) {
  body { padding-block-end: calc(var(--callbar-h) + env(safe-area-inset-bottom, 0px)); }

  .callbar {
    position: fixed;
    inset-inline: 0;
    inset-block-end: 0;
    z-index: 110;
    display: flex;
    min-block-size: var(--callbar-h);
    padding-block-end: env(safe-area-inset-bottom, 0px);
    background: var(--indigo-600);
    box-shadow: 0 -4px 8px rgba(15,19,48,.10), 0 -14px 32px rgba(15,19,48,.18);
    transition: transform var(--dur-base) var(--ease-out);
  }
  /* Hidden while the quote form is on screen — the user is already converting. */
  .callbar.is-hidden { transform: translateY(110%); }

  .callbar__primary,
  .callbar__secondary {
    display: flex;
    align-items: center;
    justify-content: center;
    text-decoration: none;
    color: #FFFFFF;
    font-weight: 650;
  }
  .callbar__primary {
    flex: 0 0 65%;
    flex-direction: column;
    gap: 1px;
    line-height: 1.15;
  }
  .callbar__label { font-size: var(--step--2); letter-spacing: .1em; text-transform: uppercase; opacity: .85; }
  .callbar__num { font-size: 1.05rem; font-weight: 700; }
  .callbar__secondary {
    flex: 1 1 35%;
    font-size: var(--step--1);
    text-align: center;
    padding-inline: var(--space-2xs);
    border-inline-start: 1px solid rgba(255,255,255,.28);
  }
  .callbar__primary:active, .callbar__secondary:active { background: var(--indigo-800); }
}


/* ═══ 19 · PLACEHOLDERS ═══════════════════════════════════════════════════
   Anything not verifiable from the client's own material ships as a visibly
   unfinished, bracketed placeholder. They are part of the deliverable: they
   show Claire and Brad exactly what is still needed.
   ═══════════════════════════════════════════════════════════════════════ */

.placeholder {
  display: inline-block;
  background: var(--damage-50);
  border: 1px dashed var(--damage-700);
  border-radius: var(--radius-sm);
  padding: var(--space-2xs) var(--space-xs);
  color: var(--color-text);
  font-size: var(--step--1);
  font-style: normal;
  line-height: 1.4;
  max-width: 100%;
}
.placeholder--tight { padding: .1rem .4rem; font-size: var(--step--2); }
.placeholder--block { display: block; }
.card--placeholder .placeholder { min-block-size: 9rem; }


/* ═══ 20 · FOCUS, MOTION, PRINT ═══════════════════════════════════════════ */

:focus-visible {
  outline: 3px solid var(--color-focus);
  outline-offset: 3px;
  border-radius: var(--radius-xs);
}
.btn:focus-visible, .icon-btn:focus-visible { outline-offset: 3px; }
.ba__zoom:focus-visible { outline-offset: 4px; }
.faq__item summary:focus-visible { outline-offset: -3px; }
/* Reset the UA's dotted outline so the ring above is the only one drawn. */
:focus:not(:focus-visible) { outline: none; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
  .link-arrow:hover::after { transform: none; }
  .card:hover, .ba:hover, .btn-primary:hover { transform: none; }
}

/* ═══ THE REPAIR ITSELF (7 steps) ════════════════════════════════════════ */

.process {
  display: grid;
  gap: var(--space-md);
  counter-reset: none;
  grid-template-columns: 1fr;
}
@media (min-width: 34rem) { .process { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 56rem) { .process { grid-template-columns: repeat(3, 1fr); } }
@media (min-width: 76rem) { .process { grid-template-columns: repeat(4, 1fr); } }

.process__step {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  padding: var(--space-md);
  display: grid;
  gap: .45rem;
  align-content: start;
}
.process__num {
  inline-size: 2rem; block-size: 2rem;
  display: grid; place-items: center;
  border-radius: 50%;
  background: var(--color-surface-tint);
  color: var(--color-text-link);
  font-weight: 700;
  font-size: var(--step--1);
  font-variant-numeric: tabular-nums;
}
.process__step h3 { font-size: var(--step-1); line-height: 1.2; }
.process__step p { font-size: var(--step--1); color: var(--color-text-muted); }

.process__honest {
  margin-block-start: var(--space-lg);
  max-inline-size: 62ch;
  padding-inline-start: var(--space-md);
  border-inline-start: 3px solid var(--color-chip);
  color: var(--color-text);
}

/* ═══ SERVICE AREA PAGES ══════════════════════════════════════════════════
   Used by /areas/<suburb>/, generated by tools/gen-areas.py.
   ═══════════════════════════════════════════════════════════════════════ */

.area-hero { padding-block-start: var(--space-xl); }
/* One step down from the homepage hero, which uses --step-5.
   NOTE: the scale stops at --step-5. There is no --step-6. */
.area-hero h1 {
  font-family: var(--font-display);
  font-size: var(--step-4);
  font-weight: 700;
  line-height: 1.06;
  letter-spacing: -.022em;
}

/* Breadcrumb */
.crumbs {
  font-size: var(--step--1);
  color: var(--color-text-muted);
  display: flex;
  flex-wrap: wrap;
  gap: .45rem;
  align-items: center;
}
.crumbs a { color: var(--color-text-muted); text-decoration: none; border-block-end: 1px solid transparent; }
.crumbs a:hover { color: var(--color-text-link); border-block-end-color: currentColor; }
.crumbs [aria-current] { color: var(--color-text); font-weight: 600; }

/* Service list in the side panel */
.svc-list { display: grid; gap: var(--space-sm); }
.svc-list li {
  display: grid;
  gap: .15rem;
  padding-block-end: var(--space-sm);
  border-block-end: 1px solid var(--color-border);
}
.svc-list li:last-child { border-block-end: 0; padding-block-end: 0; }
.svc-list strong { font-weight: 650; }
.svc-list span { font-size: var(--step--1); color: var(--color-text-muted); }

/* Nearby suburb links */
.nearby-list { display: flex; flex-wrap: wrap; gap: var(--space-2xs); }
.nearby-list a {
  display: inline-block;
  padding: .4rem .9rem;
  border-radius: var(--radius-pill);
  background: var(--color-surface-tint);
  color: var(--color-text);
  font-size: var(--step--1);
  font-weight: 600;
  text-decoration: none;
}
.nearby-list a:hover { background: var(--color-cta-bg); color: var(--color-cta-text); }

/* Two photos side by side on the area pages */
.ba-grid--pair { grid-template-columns: 1fr; }
@media (min-width: 46rem) { .ba-grid--pair { grid-template-columns: repeat(2, 1fr); } }

.hero__actions--centre { justify-content: center; }

/* Ghost button sitting on the dark band. The homepage used this class
   before the area pages existed, but it was never actually styled. */
.btn-on-ink {
  border-color: rgba(255, 255, 255, .55);
  color: var(--white);
}
.btn-on-ink:hover {
  background: rgba(255, 255, 255, .12);
  border-color: var(--white);
  color: var(--white);
}

@media print {
  .site-header, .callbar, .lightbox, .hero__chipfield, .chip-divider { display: none !important; }
  body { background: #fff; color: #000; }
  .ba { break-inside: avoid; }
  a[href^="tel:"]::after { content: " (" attr(href) ")"; }
}

/* Suburb chips that link to their own area page. */
.suburb-list--linked a {
  display: block;
  color: inherit;
  text-decoration: none;
}
.suburb-list--linked li { padding: 0; background: none; }
.suburb-list--linked li a {
  padding: .35rem .8rem;
  border-radius: var(--radius-pill);
  background: var(--color-surface-tint);
}
.suburb-list--linked li a:hover {
  background: var(--color-cta-bg);
  color: var(--color-cta-text);
}

/* Lightbox showing one half of a pair: single label, bottom left. */
.lightbox__stage.is-single .ba__label--before,
.lightbox__stage.is-single .ba__label--after {
  inset-block-end: var(--space-2xs);
  inset-inline-start: var(--space-2xs);
  inset-block-start: auto;
  inset-inline-end: auto;
}

/* ═══ REVIEWS ═════════════════════════════════════════════════════════════
   Real Google reviews, quoted verbatim (typos and all — they are quotes). */
.review { display: grid; gap: var(--space-sm); align-content: start; }
.review__quote { margin: 0; }
.review__quote p { font-size: var(--step-0); line-height: 1.55; }
.review__quote p::before { content: "\201C"; color: var(--color-chip); font-weight: 700; }
.review__quote p::after  { content: "\201D"; color: var(--color-chip); font-weight: 700; }
.review__who { font-size: var(--step--1); font-weight: 650; color: var(--color-text-muted); }

/* ═══ THEME-AWARE HEADER LOGO ═════════════════════════════════════════════
   Two <img>s swapped by the same cascade as every other theme token.
   A <picture media> source only follows the system preference and ignores
   the manual data-theme toggle, which put a dark-text logo on the dark
   header (Brad's "heading disappears" bug, 15 Aug). */
.logo-link__img--dark { display: none; }
:root[data-theme="dark"] .logo-link__img--light { display: none; }
:root[data-theme="dark"] .logo-link__img--dark { display: block; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .logo-link__img--light { display: none; }
  :root:not([data-theme="light"]) .logo-link__img--dark { display: block; }
}
