/* ==========================================================================
   Mercuri Garden & Building Supplies, Design System
   ========================================================================== */

:root {
  /* Palette rebuilt from the CURRENT logo artwork (assets/images/logo.webp). The blues
     below were sampled out of that artwork rather than carried over from the previous
     logo: the navy panel fill measures #0f4c86 and the aqua frame #46a7cd, so the
     primary ramp is derived from the navy and every tint from the aqua. Charcoal is
     kept for headings and body text. */
  --color-charcoal-950: #14171a;
  --color-charcoal-900: #1c2024;
  --color-charcoal-800: #2a2e33;
  --color-charcoal-700: #3d4349;

  /* brand ramp (logo colours) */
  --color-accent-900: #0c3b69;   /* darkest navy - hover, dark gradient stops */
  --color-accent-800: #0d4477;   /* mid-dark navy */
  --color-accent-700: #0f4c86;   /* PRIMARY navy (sampled) - links, eyebrows, active */
  --color-accent-600: #0f4c86;   /* primary button fill (the same navy) */
  --color-accent-500: #3a6c9c;   /* focus ring + decorative markers */
  --color-accent-300: #46a7cd;   /* aqua frame colour (sampled) - decorative */
  --color-accent-200: #b9deec;   /* light aqua tint - light text on dark bands */
  --color-accent-100: #e5f3f8;   /* palest aqua tint - small highlight surfaces */

  /* highlight surfaces: were grey, now logo tints */
  --color-tint-band: #daedf5;    /* section bands (aqua-derived) */
  --color-tint-soft: #e9f4f9;    /* chips, badges, inputs, trust strip */
  --color-tint-line: #b1daea;    /* hairline on/around tinted surfaces */

  --color-ink: #22262a;
  /* Near-black label for the aqua hero CTA. White on the aqua (#46a7cd) is only 2.74:1,
     which fails; this measures 7.15:1 on it (AAA) and 5.85:1 on the hover shade. */
  --color-on-aqua: #0a0c0f;
  /* darkened from #5c6066: soft body text must clear AAA on the tinted bands
     (was 4.82:1 on --color-tint-band) */
  --color-ink-soft: #42464c;
  --color-white: #ffffff;
  --color-border: #cbe6f1;       /* cool aqua-tinted hairline */
  --color-oncharcoal: #cdd2d6;
  --color-oncharcoal-soft: #b6bcc1;
  --color-oncharcoal-faint: #93989d;

  --font-sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;

  --radius-sm: 6px;
  --radius-md: 10px;
  --radius-lg: 14px;
  --shadow-sm: 0 1px 2px rgba(20, 22, 24, 0.06);
  --shadow-md: 0 6px 18px rgba(20, 22, 24, 0.09);
  --shadow-lg: 0 14px 32px rgba(20, 22, 24, 0.16);

  --mobile-bar-h: 76px;               /* sticky call bar: 12px + 52px button + 12px */
  --container-w: 1416px;              /* 1180 x 1.2 = +20% (client) */
  --container-gutter: clamp(20px, 2.5vw, 40px);
}

* , *::before, *::after { box-sizing: border-box; }
html { scroll-behavior: smooth; }
body {
  margin: 0;
  font-family: var(--font-sans);
  color: var(--color-ink);
  background: var(--color-white);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}
img { max-width: 100%; height: auto; display: block; }
a { color: inherit; }
h1, h2, h3, h4 { line-height: 1.18; margin: 0 0 0.5em; font-weight: 700; letter-spacing: -0.01em; color: var(--color-charcoal-900); }
h1 { font-size: clamp(2rem, 4.5vw, 3.1rem); }
h2 { font-size: clamp(1.5rem, 3vw, 2.2rem); }
h3 { font-size: 1.25rem; }
p { margin: 0 0 1em; }
ul, ol { margin: 0 0 1em; padding-left: 1.25em; }
.container {
  width: 100%;
  max-width: var(--container-w);       /* still centred, just 20% wider */
  margin-inline: auto;
  padding-inline: var(--container-gutter);
}
section { padding: 64px 0; }
.section-tight { padding: 40px 0; }
@media (max-width: 640px) {
  section { padding: 44px 0; }
  .section-tight { padding: 30px 0; }
}
.bg-forest { background: var(--color-charcoal-900); color: var(--color-white); }
.bg-forest h2, .bg-forest h3 { color: var(--color-white); }
.bg-sand { background: var(--color-tint-band); }
.bg-white { background: var(--color-white); }
.eyebrow {
  display: inline-block;
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-accent-700);
  margin-bottom: 10px;
}
.bg-forest .eyebrow { color: var(--color-accent-200); }
.lede { font-size: 1.1rem; color: var(--color-ink-soft); max-width: 62ch; }
.bg-forest .lede { color: var(--color-oncharcoal-soft); }
.center { text-align: center; margin-inline: auto; }
.visually-hidden {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0;
}
.skip-link {
  position: absolute; left: 8px; top: -60px; background: var(--color-charcoal-900);
  color: #fff; padding: 10px 16px; border-radius: var(--radius-sm); z-index: 200;
  transition: top 0.15s ease;
}
.skip-link:focus { top: 8px; }

/* ---- Buttons ---- */
/* Every button renders at exactly ONE size: 52px tall, 15px text, same padding and\n   radius. The height is fixed rather than derived from padding + line-height, so no\n   variant can drift a few px, and every variant carries the same 2px border so the box\n   is identical. 52px is deliberate: 44 x 1.2, i.e. the header CTA's earlier +20% - so\n   the header keeps that gain while everything else normalises to the same size. */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  height: 52px; padding: 0 26px; border-radius: var(--radius-md);
  font-weight: 700; font-size: 15px; line-height: 1;
  white-space: nowrap;
  text-decoration: none; border: 2px solid transparent; cursor: pointer;
  transition: transform 0.12s ease, box-shadow 0.12s ease, background 0.12s ease, color .12s ease;
}
.btn:hover { transform: translateY(-1px); }
.btn-primary { background: var(--color-accent-600); color: #fff; box-shadow: var(--shadow-sm); }
.btn-primary:hover { background: var(--color-accent-900); box-shadow: var(--shadow-md); }
.btn-secondary { background: var(--color-white); color: var(--color-charcoal-800); border-color: var(--color-border); }
.btn-secondary:hover { background: var(--color-accent-100); border-color: var(--color-accent-600); }
.btn-outline-light { background: transparent; color: #fff; border-color: rgba(255,255,255,0.5); }
.btn-outline-light:hover { background: rgba(255,255,255,0.12); }
/* .btn-lg and .btn-header no longer change the size: every button is 52px / 15px now,
   so the hero CTAs came down from 54px and the header CTA up from 44px to meet in the
   middle. The class names stay in the markup as no-ops. */
.btn-block { width: 100%; }
.cta-row { display: flex; flex-wrap: wrap; gap: 14px; margin-top: 24px; }
/* Mobile CTA rows: one button per line at full container width, so the buttons in a row
   match each other AND match the floating call bar (also full width). Same <=700px range
   as the floating bar, so the two never disagree about what "mobile" is. */
@media (max-width: 700px) {
  .cta-row { flex-direction: column; align-items: stretch; }
  .cta-row .btn { width: 100%; }
  /* The floating call bar below already carries the quote action at this width, so the
     page-hero's own quote button is dropped here, leaving one quote CTA, not two. Same
     <=700px range as the bar, so the button only reappears once the bar is gone. */
  .page-hero .cta-row .btn-outline-light { display: none; }
}
/* Hero click-to-call. Hidden by default because the header carries a click-to-call CTA
   at every width down to 561px. It is restored in the <=560px block below - the exact
   point where the header drops its own call button and becomes logo + menu only.
   Styled as a SOLID brand aqua so the hero shows a light blue-green action next to the
   deep-blue primary, instead of the near-white outline it used to carry. The label is
   near-black (--color-on-aqua) because white on this aqua is only 2.74:1. */
.hero-call {
  display: none;
  background: var(--color-accent-300);
  color: var(--color-on-aqua);
  border-color: var(--color-accent-300);
}
.hero-call:hover {
  background: #3f96b9; border-color: #3f96b9; color: var(--color-on-aqua);
}

/* ---- Header ---- */
/* NOTE: deliberately no backdrop-filter here. A filter on the header makes it the
   containing block for its position:fixed descendants, which broke the mobile
   .nav-scrim (it collapsed to the header's height) and pushed the off-canvas
   .nav-links drawer into scrollWidth, causing horizontal overflow. The header
   background is near-opaque anyway, so the blur was not visible. */
.site-header {
  position: sticky; top: 0; z-index: 100; background: rgba(255,255,255,0.97);
  border-bottom: 1px solid var(--color-border);
}
/* NOTE: the utility bar that used to sit above the header was removed at the
   client's explicit request. The phone is the header CTA (a tel: button), and also
   appears in the sticky mobile call bar, the footer and the homepage FAQ. */
.navbar { display: flex; align-items: center; justify-content: space-between; padding-block: 14px; gap: 16px; }
.brand { display: flex; align-items: center; gap: 10px; text-decoration: none; flex: 0 0 auto; }
.brand img { height: 74px; width: auto; max-width: none; flex: 0 0 auto; }
.nav-links { display: flex; gap: 18px; list-style: none; margin: 0; padding: 0; }
/* Header nav links: no underline and no shape. The hover/current state is carried by
   the deep-blue text colour, plus font-weight 700 on the current page, so it is still
   not signalled by colour alone. (The light-blue rounded halo that used to sit behind
   hovered/current items was removed at the client's request.) */
.nav-links a {
  text-decoration: none; font-weight: 600; color: var(--color-ink); font-size: 0.96rem;
  padding: 6px 2px; white-space: nowrap;
}
.nav-links a:hover { color: var(--color-accent-700); }
.nav-links a[aria-current="page"] { color: var(--color-accent-700); font-weight: 700; }
@media (min-width: 1080px) {
  .nav-links a { transition: color .15s ease; }
}
.nav-actions { display: flex; align-items: center; gap: 12px; }
.nav-toggle {
  display: none; background: none; border: 2px solid var(--color-border); border-radius: var(--radius-sm);
  padding: 8px 10px; cursor: pointer;
}
.nav-toggle svg { display: block; }

/* Drawer close control. Lives inside the drawer and is only rendered there. */
.nav-drawer-head { display: none; }
.nav-close {
  align-items: center; justify-content: center; width: 44px; height: 44px; padding: 0;
  background: none; border: 2px solid var(--color-border); border-radius: var(--radius-sm);
  color: var(--color-charcoal-900); cursor: pointer;
}
.nav-close svg { display: block; }
.nav-close:hover { background: var(--color-tint-soft); border-color: var(--color-tint-line); }

@media (max-width: 1079px) {
  /* The closed drawer sits off-canvas via translateX(100%). That still counts toward
     scrollable overflow at narrow widths (8px of horizontal scroll at 360px).
     `overflow-x: clip` contains it WITHOUT creating a scroll container, so the
     sticky header keeps working (unlike overflow:hidden, which would break it). */
  html { overflow-x: clip; }
  /* Stacking order matters here. .site-header is sticky with z-index 100, so the
     scrim and the drawer must both sit ABOVE it (110 / 120) or the header paints
     over the open drawer - that was the cause of the page strip and the hamburger
     showing inside the panel. */
  .nav-links { position: fixed; inset: 0 0 0 auto; width: min(78vw, 340px); height: 100vh; background: #fff;
    flex-direction: column; padding: 84px 28px 28px; gap: 8px; box-shadow: var(--shadow-lg);
    transform: translateX(100%); transition: transform 0.22s ease; overflow-y: auto; z-index: 120; }
  .nav-links.is-open { transform: translateX(0); }
  /* Drawer rows: no divider underlines either - the row's tinted pill carries the
     current/hover state instead. */
  .nav-links a { display: block; padding: 12px 12px; font-size: 1.05rem; border-radius: 10px; }
  .nav-links a:hover,
  .nav-links a[aria-current="page"] { background: var(--color-tint-soft); }
  /* The drawer carries its own close control, so the header toggle is hidden while
     the menu is open rather than floating over the panel. */
  .nav-drawer-head { display: block; }
  .nav-close { display: inline-flex; position: absolute; top: 18px; right: 18px; z-index: 2; }
  .nav-toggle { display: inline-flex; }
  body.menu-open .nav-toggle { visibility: hidden; }
  body.menu-open { overflow: hidden; }
  .nav-scrim { position: fixed; inset: 0; background: rgba(14,17,20,0.62); z-index: 110; opacity: 0; pointer-events: none; transition: opacity .2s ease; }
  .nav-scrim.is-open { opacity: 1; pointer-events: auto; }
}

/* Narrow mobile: drop the call CTA from the navbar row, the logo already carries
   the brand, and the phone is one tap away via the sticky mobile call bar, so this
   row stays to just logo + menu. */
@media (max-width: 560px) {
  /* Header collapses to logo + menu at this width, so the hero takes over the call
     action (paired with .hero-call { display: none } outside this block). The hero's
     quote CTA is dropped here instead - the floating call bar already carries it. */
  .nav-actions .btn-primary { display: none; }
  .hero-call { display: inline-flex; }
  .hero-quote { display: none; }
  /* Full-cover panel: at this width the drawer covers the viewport exactly, so no
     strip of the page shows behind it (client request). */
  .nav-links { width: 100%; padding: 76px 22px 32px; box-shadow: none; }
  .nav-links a { font-size: 1.12rem; padding: 14px 4px; }
  .nav-close { top: 14px; right: 14px; }
}

/* ---- Hero ---- */
.hero {
  position: relative; color: #fff; overflow: hidden;
  background:
    radial-gradient(circle at 85% 0%, rgba(255,255,255,0.06), transparent 45%),
    linear-gradient(160deg, var(--color-accent-900) 0%, var(--color-charcoal-950) 100%);
  padding: 72px 0 80px;
}
.hero .container { position: relative; z-index: 1; }
.hero-inner { max-width: 720px; }
.hero .eyebrow { color: var(--color-accent-200); }
.hero h1 { color: #fff; margin-bottom: 16px; }
.hero p.lede { color: var(--color-oncharcoal-soft); }
.hero-badges { display: flex; flex-wrap: wrap; gap: 10px 22px; margin-top: 28px; font-size: 0.92rem; color: var(--color-oncharcoal); }
.hero-badges li { list-style: none; display: flex; align-items: center; gap: 8px; }
.hero-badges ul { display: flex; flex-wrap: wrap; gap: 10px 22px; padding: 0; margin: 26px 0 0; }

.page-hero {
  background: linear-gradient(160deg, var(--color-accent-900) 0%, var(--color-charcoal-950) 100%); color: #fff; padding: 48px 0 40px;
}
.page-hero h1 { color: #fff; }
.page-hero .lede { color: var(--color-oncharcoal-soft); }
/* The .page-hero band is dark, so the default accent-700 eyebrow would barely be
   legible against it. Use the light accent tint, as .hero does. */
.page-hero .eyebrow { color: var(--color-accent-200); }

/* ---- Breadcrumb ---- */
.breadcrumb { list-style: none; display: flex; flex-wrap: wrap; gap: 6px; padding: 0; margin: 0 0 14px; font-size: 0.85rem; }
.breadcrumb li { display: flex; align-items: center; gap: 6px; color: var(--color-oncharcoal-faint); }
.breadcrumb a { color: var(--color-oncharcoal-soft); text-decoration: none; }
.breadcrumb a:hover { text-decoration: underline; }
.breadcrumb li:last-child { color: #fff; font-weight: 600; }

/* ---- Trust strip ---- */
/* One restrained band under the hero: single hairline, no card boxes or shadows.
   Four equal columns >900px; a clean 2x2 below that, with the icon stacked over
   the label so the longer labels stay on one line instead of wrapping. */
.trust-strip {
  background: var(--color-tint-soft);
  border-bottom: 1px solid var(--color-tint-line);
}
.trust-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 20px;
  padding-block: 20px;
}
.trust-item {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  font-size: 0.9rem;
  font-weight: 600;
  line-height: 1.3;
  color: var(--color-charcoal-800);
}
/* Same icon box, same stroke weight, every item -> icons share one baseline. */
.trust-item svg {
  flex: 0 0 20px;
  width: 20px;
  height: 20px;
  color: var(--color-accent-600);
}
@media (max-width: 900px) {
  .trust-grid {
    grid-template-columns: repeat(2, 1fr);
    gap: 8px 12px;
    padding-block: 16px;
  }
  .trust-item {
    flex-direction: column;
    /* flex-start (not center) keeps every icon on the same line within its row,
       even if one label happens to wrap and makes that cell taller. */
    justify-content: flex-start;
    gap: 6px;
    font-size: 0.8rem;
    line-height: 1.3;
    text-align: center;
  }
}
/* Narrow phones (<=380px): step the label down a notch so the longest label,
   "Local Bundoora business", stays on one line instead of wrapping. */
@media (max-width: 380px) {
  .trust-item { font-size: 0.75rem; }
}

/* ---- Cards / grids ---- */
.grid { display: grid; gap: 24px; }
.grid-2 { grid-template-columns: repeat(2, 1fr); }
.grid-3 { grid-template-columns: repeat(3, 1fr); }
.grid-4 { grid-template-columns: repeat(4, 1fr); }
@media (max-width: 900px) {
  .grid-2, .grid-3, .grid-4 { grid-template-columns: 1fr; }
}
@media (min-width: 601px) and (max-width: 900px) {
  .grid-3, .grid-4 { grid-template-columns: repeat(2, 1fr); }
}

.card {
  background: #fff; border: 1px solid var(--color-tint-line); border-radius: var(--radius-lg);
  padding: 26px; box-shadow: var(--shadow-sm); transition: box-shadow .15s ease, transform .15s ease, border-color .15s ease;
  text-decoration: none; display: block;
}
.card:hover { box-shadow: var(--shadow-md); transform: translateY(-2px); border-color: var(--color-tint-line); }
.card-icon {
  width: 48px; height: 48px; border-radius: var(--radius-sm); background: var(--color-accent-100);
  display: flex; align-items: center; justify-content: center; margin-bottom: 16px; color: var(--color-accent-700);
  font-size: 1.3rem;
}
.card h3 { margin-bottom: 8px; }
.card p { color: var(--color-ink-soft); margin-bottom: 14px; }
.card-link { font-weight: 700; color: var(--color-accent-700); text-decoration: none; display: inline-flex; align-items: center; gap: 6px; }
.card-link:hover { text-decoration: underline; }

.pathway-card {
  position: relative; overflow: hidden; border-radius: var(--radius-lg); color: #fff; min-height: 260px;
  display: flex; flex-direction: column; justify-content: flex-end; padding: 30px; text-decoration: none;
  box-shadow: var(--shadow-md);
}
.pathway-card::before { content: ""; position: absolute; inset: 0; }
.pathway-card--garden::before { background: linear-gradient(160deg, var(--color-accent-600), var(--color-accent-900) 85%); }
.pathway-card--building::before { background: linear-gradient(160deg, var(--color-charcoal-700), var(--color-charcoal-950) 85%); }
.pathway-card .card-icon-lg {
  position: relative; z-index: 1; font-size: 1.4rem; margin-bottom: 14px;
  width: 44px; height: 44px; display: flex; align-items: center; justify-content: center;
  border-radius: var(--radius-sm); background: rgba(255,255,255,0.14);
}
.pathway-card > * { position: relative; z-index: 1; }
.pathway-card h3 { color: #fff; font-size: 1.5rem; margin-bottom: 6px; }
.pathway-card p { color: var(--color-oncharcoal-soft); margin-bottom: 16px; }
.pathway-card .btn { align-self: flex-start; }

/* ---- Swatch card (non-photographic material representation) ---- */
.swatch-card {
  border-radius: var(--radius-lg); padding: 28px; color: #fff; position: relative; overflow: hidden;
  min-height: 200px; display: flex; flex-direction: column; justify-content: flex-end; box-shadow: var(--shadow-sm);
}
.swatch-card > * { position: relative; z-index: 1; }
.swatch-card .swatch-icon {
  font-size: 1.2rem; margin-bottom: 10px; width: 38px; height: 38px; display: flex; align-items: center;
  justify-content: center; border-radius: var(--radius-sm); background: rgba(255,255,255,0.16);
}
.swatch-card strong { display: block; font-size: 1.1rem; }
.swatch-card span { color: rgba(255,255,255,0.82); font-size: 0.88rem; }
.swatch-red { background: linear-gradient(160deg, var(--color-accent-600), var(--color-accent-900)); }
.swatch-forest { background: linear-gradient(160deg, var(--color-accent-700), var(--color-charcoal-900)); }
.swatch-stone { background: linear-gradient(160deg, var(--color-accent-500), var(--color-charcoal-800)); }
.swatch-sand { background: linear-gradient(160deg, var(--color-tint-line), var(--color-accent-300)); }
.swatch-slate { background: linear-gradient(160deg, var(--color-charcoal-700), var(--color-charcoal-950)); }

.icon-panel {
  border-radius: var(--radius-lg); background: var(--color-accent-100); padding: 44px 32px; text-align: center;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 10px; min-height: 240px;
}
.icon-panel .icon-panel-glyph {
  font-size: 1.6rem; width: 56px; height: 56px; display: flex; align-items: center; justify-content: center;
  border-radius: 50%; background: #fff; box-shadow: var(--shadow-sm); margin-bottom: 4px;
}
.icon-panel strong { color: var(--color-charcoal-900); font-size: 1.1rem; }
.icon-panel span { color: var(--color-ink-soft); font-size: 0.92rem; max-width: 30ch; }

/* Product listing */
.product-list { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(2, 1fr); gap: 10px 24px; }
.product-list li { padding: 10px 0 10px 30px; border-bottom: 1px solid var(--color-border); position: relative; font-weight: 600; }
/* Wide variant reflows by available width rather than a fixed column count, so it
   stays 4-up on desktop and single-column on phones. A hard-coded 3-column inline
   style used to override the <=640px rule and push the list past the viewport. */
.product-list--wide { grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); }
.product-list li::before {
  content: ""; position: absolute; left: 0; top: 15px; width: 14px; height: 14px; border-radius: 4px;
  background: var(--color-accent-500);
}
@media (max-width: 640px) { .product-list { grid-template-columns: 1fr; } }
.product-group { margin-bottom: 36px; }
.product-group h3 { display: flex; align-items: center; gap: 10px; color: var(--color-charcoal-800); }


/* ---- Service area ---- */
.suburb-chips { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 20px; padding: 0; list-style: none; }
.suburb-chips li {
  background: var(--color-tint-soft); border: 1px solid var(--color-tint-line); border-radius: 999px;
  font-weight: 700; font-size: 0.9rem; color: var(--color-charcoal-800);
}
.suburb-chips li a {
  display: block; padding: 9px 16px; color: inherit; text-decoration: none; border-radius: 999px;
  transition: background .15s ease, color .15s ease, border-color .15s ease;
}
.suburb-chips li:has(a:hover),
.suburb-chips li a:focus-visible { background: var(--color-accent-600); border-color: var(--color-accent-600); color: #fff; }
.suburb-chips li a:focus-visible { outline: 2px solid var(--color-accent-900); outline-offset: 2px; }
.bg-forest .suburb-chips li { background: rgba(255,255,255,0.08); border-color: rgba(255,255,255,0.25); color: #fff; }
.bg-forest .suburb-chips li:has(a:hover) { background: var(--color-accent-600); border-color: var(--color-accent-600); }

/* ---- Testimonials (social proof) ---- */
/* A deep-blue band so a real review reads as a deliberate social-proof moment rather
   than another content block. Heading and the Google CTA share one row, then the
   reviews ticker below.
   NOTE: these rules were lost when the grid was converted to a ticker (the ticker
   commit replaced this whole block), which left the band unstyled: the section had no
   background at all, so the white quote text sat on the white page and the reviews were
   invisible on mobile. Restored here, directly above the ticker rules. */
.testimonials {
  background: linear-gradient(165deg, var(--color-accent-900) 0%, var(--color-charcoal-950) 100%);
}
.testimonials .eyebrow { color: var(--color-accent-200); }
.testimonials h2 { color: #fff; margin-bottom: 0; }
.testimonials-head {
  display: flex; flex-wrap: wrap; align-items: flex-end;
  justify-content: space-between; gap: 18px 32px;
}
.testimonials-cta { margin: 0; }

/* ---- Testimonials: one complete review at a time ---- */
/* Each review is a SELF-CONTAINED card exactly as wide as the visible window, holding
   its stars, its quote and the reviewer name together. The previous build made every
   review one nowrap line about 2,612px wide, so a 350px phone window could only ever
   show a mid-word slice of it - and the stars and the name sat at the far ends of that
   line, so they were effectively never in view.
   A 319-character quote cannot physically sit on one line on a phone (that is exactly
   why it measured 2,612px), so the quote wraps here: visibility beats a literal
   one-line layout.
   Motion: the track holds two identical strips of 4 cards and each card is exactly 1/8
   of the track, so a -12.5% step is exactly one card and -50% is the seamless loop
   point. The keyframes dwell on each card fully visible, then slide to the next - the
   slow "one review travelling at a time" feel, with every review readable in the band. */
.reviews-marquee {
  position: relative; overflow: hidden; margin-top: 34px;
  /* Rotation pacing. Each card dwells fully visible, then slides to the next. Tuned so
     the rotation is unmistakable: ~3.75s dwell + ~0.75s slide per review, a full
     4-review cycle in 18s (the previous 72s cycle spent 14s motionless per card, which
     read as frozen). The keyframe percentages below are exactly these two durations as
     a share of --ticker-duration: dwell 3.75/18 = 20.833%, slide 0.75/18 = 4.167%. If
     you retune the durations, recompute those four percentages to match. */
  --ticker-dwell: 3.75s;       /* per review, fully visible and uncut */
  --ticker-slide: 0.75s;       /* per review, eased move to the next card */
  --ticker-duration: 18s;      /* = 4 x (--ticker-dwell + --ticker-slide) */
  --ticker-gap: 28px;          /* space between cards */
  --ticker-mask: 20px;         /* edge fade; cards pad by the same amount, so text is
                                  never faded or cut at the band edge while dwelling */
}
.reviews-ticker {
  overflow: hidden;            /* clipped inside the band */
  -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 var(--ticker-mask), #000 calc(100% - var(--ticker-mask)), transparent 100%);
  mask-image: linear-gradient(90deg, transparent 0, #000 var(--ticker-mask), #000 calc(100% - var(--ticker-mask)), transparent 100%);
}
.reviews-track {
  display: flex; width: 800%;  /* 2 strips x 4 cards, each card one window wide */
  animation: reviews-scroll var(--ticker-duration) linear infinite;
  will-change: transform;
}
.reviews-strip { display: flex; width: 50%; list-style: none; margin: 0; padding: 0; }
.testimonial {
  flex: 0 0 25%;               /* exactly the visible window width */
  display: flex; flex-direction: column; align-items: center; gap: 10px;
  text-align: center;
  /* Symmetric padding so the centred content sits on the true centre line. These used
     to differ (mask 20px left, gap 28px right), which left the text 4px off centre. */
  padding-left: var(--ticker-gap); padding-right: var(--ticker-gap);
  white-space: normal;         /* the quote wraps - it cannot fit on one line */
  font-size: 0.95rem; line-height: 1.5; color: #fff;
}
.testimonial-mark { display: none; }   /* decorative glyph from the one-line layout */
.testimonial-stars { display: flex; gap: 3px; color: var(--color-accent-100); }
.testimonial-stars svg { display: block; }
.testimonial-quote { display: block; margin: 0; padding: 0; border: 0; }
.testimonial-quote p { display: block; margin: 0; font-size: 0.92rem; font-weight: 500; letter-spacing: 0.004em; }
.testimonial-author { display: inline-flex; align-items: baseline; flex-wrap: wrap; gap: 8px; }
.testimonial-author strong { color: #fff; font-weight: 700; }
.testimonial-author span { color: var(--color-accent-200); font-size: 0.84rem; font-weight: 600; letter-spacing: 0.02em; }

/* One card per step. -12.5% of the track is exactly one card; -50% is one full strip,
   the seamless loop point. Percentages = the dwell/slide durations above as a share of
   --ticker-duration (20.833% dwell, 4.167% slide, 25% per card). */
@keyframes reviews-scroll {
  0%       { transform: translate3d(0, 0, 0);      animation-timing-function: linear; }
  20.833%  { transform: translate3d(0, 0, 0);      animation-timing-function: ease-in-out; }
  25%      { transform: translate3d(-12.5%, 0, 0); animation-timing-function: linear; }
  45.833%  { transform: translate3d(-12.5%, 0, 0); animation-timing-function: ease-in-out; }
  50%      { transform: translate3d(-25%, 0, 0);   animation-timing-function: linear; }
  70.833%  { transform: translate3d(-25%, 0, 0);   animation-timing-function: ease-in-out; }
  75%      { transform: translate3d(-37.5%, 0, 0); animation-timing-function: linear; }
  95.833%  { transform: translate3d(-37.5%, 0, 0); animation-timing-function: ease-in-out; }
  100%     { transform: translate3d(-50%, 0, 0); }
}

/* Pausable: on hover, on keyboard focus anywhere in the marquee, and via the control. */
.reviews-marquee:hover .reviews-track,
.reviews-marquee:focus-within .reviews-track,
.reviews-marquee.is-paused .reviews-track { animation-play-state: paused; }

.reviews-toggle {
  display: inline-flex; align-items: center; gap: 8px; margin-top: 18px;
  padding: 8px 14px; font: inherit; font-size: 0.86rem; font-weight: 600;
  color: #fff; background: transparent; border: 1px solid rgba(255,255,255,0.42);
  border-radius: 999px; cursor: pointer;
}
.reviews-toggle:hover { background: rgba(255,255,255,0.14); }
.reviews-toggle .icon-play, .reviews-toggle .label-play { display: none; }
.reviews-toggle[aria-pressed="true"] .icon-pause,
.reviews-toggle[aria-pressed="true"] .label-pause { display: none; }
.reviews-toggle[aria-pressed="true"] .icon-play { display: inline-block; }
.reviews-toggle[aria-pressed="true"] .label-play { display: inline; }

/* Reduced motion: no movement at all - fall back to the static stacked list. */
@media (prefers-reduced-motion: reduce) {
  .reviews-track { animation: none; display: block; width: auto; }
  .reviews-ticker { overflow: visible; -webkit-mask-image: none; mask-image: none; }
  .reviews-strip { display: block; width: auto; }
  /* must beat .reviews-strip above (same specificity otherwise), or the duplicate
     strip stays visible and the reviews appear twice in the static list */
  .reviews-strip.reviews-strip--clone { display: none; }
  .testimonial { display: flex; width: auto; padding-left: 0; padding-right: 0; padding-bottom: 22px; }
  .reviews-toggle { display: none; }                  /* nothing to pause */
}

/* ---- FAQ ---- */
.faq { max-width: 800px; margin-inline: auto; }
.faq-item { border-bottom: 1px solid var(--color-border); }
.faq-item summary {
  cursor: pointer; list-style: none; display: flex; justify-content: space-between; align-items: center;
  padding: 20px 4px; font-weight: 700; font-size: 1.02rem; color: var(--color-charcoal-900);
}
.faq-item summary::-webkit-details-marker { display: none; }
.faq-item summary::after { content: "+"; font-size: 1.4rem; color: var(--color-accent-600); margin-left: 16px; flex-shrink: 0; }
.faq-item[open] summary::after { content: "\2212"; }
.faq-item p { padding: 0 4px 20px; color: var(--color-ink-soft); margin: 0; }

/* ---- Callout / delivery banner ---- */
.callout {
  background: var(--color-tint-soft); border: 1px solid var(--color-tint-line); border-radius: var(--radius-lg); padding: 36px;
  display: flex; align-items: center; justify-content: space-between; gap: 24px; flex-wrap: wrap;
  box-shadow: var(--shadow-sm);
}
.callout h3 { color: var(--color-charcoal-900); margin-bottom: 6px; }
.callout p { color: var(--color-ink-soft); margin: 0; }

/* ---- Steps ---- */
.steps { counter-reset: step; list-style: none; padding: 0; margin: 0; display: grid; gap: 20px; grid-template-columns: repeat(3, 1fr); }
@media (max-width: 900px) { .steps { grid-template-columns: 1fr; } }
.steps li { counter-increment: step; position: relative; padding-left: 52px; }
.steps li::before {
  content: counter(step); position: absolute; left: 0; top: 0; width: 38px; height: 38px; border-radius: 50%;
  background: var(--color-accent-700); color: #fff; display: flex; align-items: center; justify-content: center; font-weight: 800;
}
.steps h4 { margin: 0 0 4px; font-size: 1.05rem; color: var(--color-charcoal-900); }
.steps p { color: var(--color-ink-soft); margin: 0; }

/* ---- Forms ---- */
.form-card { background: #fff; border: 1px solid var(--color-border); border-radius: var(--radius-lg); padding: 32px; box-shadow: var(--shadow-sm); }
.form-row { margin-bottom: 18px; }
.form-row label { display: block; font-weight: 700; margin-bottom: 6px; font-size: 0.92rem; }
.form-row input, .form-row select, .form-row textarea {
  width: 100%; padding: 12px 14px; border: 1.5px solid var(--color-border); border-radius: var(--radius-sm);
  font-family: inherit; font-size: 0.98rem; background: var(--color-tint-soft);
}
.form-row input:focus, .form-row select:focus, .form-row textarea:focus { outline: 2px solid var(--color-accent-500); outline-offset: 1px; }
.form-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 0 18px; }
@media (max-width: 640px) { .form-grid { grid-template-columns: 1fr; } }
fieldset { border: none; padding: 0; margin: 0 0 18px; }
.radio-row { display: flex; gap: 20px; align-items: center; }
.radio-row label { display: flex; align-items: center; gap: 6px; font-weight: 600; }
.radio-row input { width: auto; }
.form-note { font-size: 0.85rem; color: var(--color-ink-soft); margin-top: 10px; }

/* ---- Info list (contact) ---- */
.info-list { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 18px; }
.info-list li { display: flex; gap: 14px; align-items: flex-start; }
.info-list .info-icon {
  width: 44px; height: 44px; border-radius: 12px; background: var(--color-accent-100); color: var(--color-accent-700);
  display: flex; align-items: center; justify-content: center; flex-shrink: 0;
}
.info-list strong { display: block; color: var(--color-charcoal-900); }
.info-list span, .info-list a { color: var(--color-ink-soft); text-decoration: none; }
.info-list a:hover { text-decoration: underline; }

/* ---- Footer ---- */
.site-footer { background: var(--color-charcoal-950); color: var(--color-oncharcoal); padding-top: 64px; }
/* Four columns: brand, areas, contact, hours. Source order matches this, so the
   560px single-column collapse already reads in the right mobile order without
   needing an explicit `order` override. */
.footer-grid { display: grid; grid-template-columns: 1.05fr 1.1fr 1.5fr 1fr; gap: 44px; padding-bottom: 40px; }
/* Below this the four-column layout can't hold the long contact email on one
   line, so it steps down to a 2x2 grid rather than wrapping the address. */
@media (max-width: 1099px) { .footer-grid { grid-template-columns: 1fr 1fr; gap: 32px 44px; } }
@media (max-width: 560px) { .footer-grid { grid-template-columns: 1fr; gap: 28px; } }
.footer-grid h4 { color: #fff; font-size: 0.9rem; letter-spacing: 0.04em; text-transform: uppercase; margin-bottom: 16px; }
.footer-grid ul { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 12px; }
.footer-grid a { color: var(--color-oncharcoal); text-decoration: none; font-size: 0.9rem; }
.footer-grid a:hover { color: #fff; text-decoration: underline; }
.footer-grid a:focus-visible, .footer-bottom a:focus-visible { outline: 2px solid #fff; outline-offset: 3px; border-radius: 2px; }
/* 11 suburbs in one stack runs too tall next to the other columns, so the list
   itself becomes a compact two-column grid. Needs the extra `.footer-grid`
   qualifier so its specificity (0,2,0) beats `.footer-grid ul` (0,1,1) above. */
.footer-grid .footer-areas-list { display: grid; grid-template-columns: repeat(2, 1fr); column-gap: 16px; row-gap: 10px; margin-bottom: 14px; }
.footer-areas-all { display: inline-flex; color: #fff; font-weight: 600; text-decoration: none; }
.footer-areas-all:hover { text-decoration: underline; }
/* The contact email is one long unbreakable string. As a flex/grid item its
   automatic min-width is the string's min-content width (~344px), which forced
   horizontal scroll below ~370px. `anywhere` (unlike `break-word`) lowers
   min-content too, so it applies wherever the address appears. */
a[href^="mailto:"] { overflow-wrap: anywhere; }
/* The new artwork already carries its own white field inside an aqua frame, so the old
   white card + padding read as a redundant box-in-box on the dark footer. Dropping them
   and adding width:auto also fixes the proportion: the 140px width attribute plus the
   horizontal padding was stretching the logo (content box 120x28, aspect 4.29 against
   the artwork's 2.857). height:40px + width:auto renders it 114x40, undistorted. */
.footer-brand img { height: 40px; width: auto; margin-bottom: 14px; }
.footer-brand p { color: var(--color-oncharcoal-faint); font-size: 0.9rem; max-width: 32ch; }
.footer-bottom { border-top: 1px solid rgba(255,255,255,0.12); padding: 24px 0 40px; font-size: 0.82rem; line-height: 1.7; color: var(--color-oncharcoal-faint); display: flex; justify-content: space-between; flex-wrap: wrap; gap: 10px; }
.footer-bottom a { color: var(--color-oncharcoal-faint); }
.footer-bottom a:hover { color: #fff; text-decoration: underline; }

/* ---- Sticky mobile call bar ---- */
.mobile-call-bar {
  display: none; position: fixed; bottom: 0; left: 0; right: 0; z-index: 95; background: var(--color-charcoal-900);
  /* padding-inline uses the container gutter so this bar's button is exactly the same
     width as a .cta-row button stacked above it. padding-block is (bar height - button)
     / 2, so the bar's real height always equals --mobile-bar-h - which is what the body
     reserves below the footer. Previously this was a flat 12px with a flat 70px body
     reserve, and since the button grew to 52px the 76px bar covered the copyright line
     by 6px. */
  padding: calc((var(--mobile-bar-h) - 52px) / 2) var(--container-gutter);
  /* Add the device's bottom safe-area inset (gesture bar / nav bar) on top of the
     usual bottom padding, so the button clears system UI instead of sitting behind it.
     The fallback 0px keeps browsers without env() support at the old padding. */
  padding-bottom: calc((var(--mobile-bar-h) - 52px) / 2 + env(safe-area-inset-bottom, 0px));
  box-shadow: 0 -6px 20px rgba(0,0,0,0.2);
}
.mobile-call-bar a { display: flex; align-items: center; justify-content: center; gap: 8px; }
@media (max-width: 700px) {
  .mobile-call-bar { display: block; }
  /* Reserve exactly the bar's height (see --mobile-bar-h), not a guess: at 70px the
     bar overlapped the last footer line by 6px. */
  /* +16px so the footer's bottom edge keeps a visible gap above the bar, not just the
     text (the text already gained room from .footer-bottom's 40px bottom padding).
     The bar's own height now grows by the safe-area inset too (see .mobile-call-bar),
     so the same inset is added here or the footer would clear the old height, not the
     real one. */
  body { padding-bottom: calc(var(--mobile-bar-h) + 16px + env(safe-area-inset-bottom, 0px)); }
}

/* ---- Misc ---- */
.two-col { display: grid; grid-template-columns: 1.1fr 0.9fr; gap: 48px; align-items: center; }
/* Let columns shrink below their content's min-content width (form fields, long
   addresses) instead of overflowing the viewport on narrow screens. */
.two-col > * { min-width: 0; }
@media (max-width: 900px) { .two-col { grid-template-columns: 1fr; } }
.two-col img { border-radius: var(--radius-lg); }
.badge-pill {
  display: inline-flex; align-items: center; gap: 6px; background: var(--color-accent-100); color: var(--color-accent-700);
  padding: 6px 14px; border-radius: 999px; font-size: 0.82rem; font-weight: 700; margin-bottom: 14px;
}
hr.divider { border: none; border-top: 1px solid var(--color-border); margin: 48px 0; }
.article-body h2 { margin-top: 1.6em; }
.article-body { max-width: 72ch; margin-inline: auto; }
.post-meta { color: var(--color-ink-soft); font-size: 0.9rem; margin-bottom: 24px; }
.blog-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 28px; }
@media (max-width: 800px) { .blog-grid { grid-template-columns: 1fr; } }
.blog-card { border: 1px solid var(--color-border); border-radius: var(--radius-lg); overflow: hidden; background: #fff; box-shadow: var(--shadow-sm); text-decoration: none; display: flex; flex-direction: column; }
.blog-card-body { padding: 24px; }
.blog-card time { font-size: 0.82rem; font-weight: 700; color: var(--color-accent-700); text-transform: uppercase; letter-spacing: 0.04em; }
.blog-card h3 { margin: 8px 0 10px; }
.blog-card p { color: var(--color-ink-soft); }

/* ---- Photography ---- */
/* Hero photo sits behind the headline; the scrim keeps the white text legible. */
.hero-photo {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; object-position: center 58%; z-index: 0;
}
.hero-scrim {
  position: absolute; inset: 0; z-index: 0;
  background: linear-gradient(100deg, rgba(14,17,20,0.93) 0%, rgba(14,17,20,0.80) 40%, rgba(14,17,20,0.46) 72%, rgba(14,17,20,0.30) 100%);
}

/* Pathway cards (homepage 2-up), photo with a scrim, text on top. */
.pathway-media { position: absolute; inset: 0; overflow: hidden; border-radius: inherit; }
.pathway-media img { width: 100%; height: 100%; object-fit: cover; display: block; }
.pathway-media::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(165deg, rgba(18,26,32,0.50) 0%, rgba(12,16,20,0.86) 78%, rgba(12,16,20,0.94) 100%);
}

/* Category cards with a real photo header. */
.card--photo { padding: 0; overflow: hidden; display: flex; flex-direction: column; }
.card--photo .card-photo { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; display: block; }
.card--photo .card-body { padding: 22px 24px 26px; display: flex; flex-direction: column; flex: 1 1 auto; }
.card--photo .card-body .card-link { margin-top: auto; }

/* In-page feature photo used in two-col sections. */
.feature-photo { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; display: block; box-shadow: var(--shadow-sm); }
.feature-figure { margin: 0; }
.feature-figure figcaption { margin-top: 14px; color: var(--color-ink-soft); font-size: 0.92rem; }
.feature-figure figcaption strong { display: block; color: var(--color-charcoal-900); font-size: 1rem; margin-bottom: 2px; }

/* Photo gallery tiles. */
.gallery-tile {
  position: relative; margin: 0; border-radius: var(--radius-lg); overflow: hidden;
  background: var(--color-tint-soft); box-shadow: var(--shadow-sm);
}
.gallery-tile img { width: 100%; aspect-ratio: 2 / 3; object-fit: cover; display: block; }
.gallery-tile figcaption {
  position: absolute; left: 0; right: 0; bottom: 0; padding: 34px 14px 12px;
  color: #fff; font-weight: 700; font-size: 0.95rem; line-height: 1.3;
  background: linear-gradient(to top, rgba(10,14,17,0.90) 0%, rgba(10,14,17,0.55) 55%, rgba(10,14,17,0) 100%);
}
.gallery-tile figcaption h3 { margin: 0; font-size: 0.95rem; font-weight: 700; color: #fff; line-height: 1.3; }
/* Whole tile is a link to the order form; the "Order now" caption is always visible
   (not hover-only) so the affordance works on touch, not just mouse/keyboard. */
.gallery-tile-link { display: block; color: inherit; text-decoration: none; }
.gallery-tile-link img { transition: transform .25s ease; }
.gallery-tile-link:hover img, .gallery-tile-link:focus-visible img { transform: scale(1.05); }
.gallery-tile-link:focus-visible { outline: 2px solid var(--color-accent-500); outline-offset: 3px; }
.gallery-tile-cta { display: block; margin-top: 4px; font-size: 0.78rem; font-weight: 700; color: var(--color-accent-200); }
.gallery-tile-link:hover .gallery-tile-cta, .gallery-tile-link:focus-visible .gallery-tile-cta { color: #fff; text-decoration: underline; }
/* Material tiles we have no honest photo for. Deliberately dark + a "sample chip",
   so they read as designed swatches. A light stone tile would be indistinguishable
   from the .gallery-tile background a failed image falls back to. */
.gallery-tile--text {
  aspect-ratio: 2 / 3; padding: 18px 16px; display: flex; flex-direction: column; justify-content: flex-end; gap: 6px;
  background: linear-gradient(160deg, var(--color-charcoal-700) 0%, var(--color-charcoal-950) 100%);
  box-shadow: var(--shadow-sm); position: relative;
}
.gallery-tile--text::before {
  content: ""; position: absolute; top: 18px; left: 16px; width: 36px; height: 36px; border-radius: 50%;
  background: radial-gradient(circle at 32% 28%, var(--color-tint-line) 0%, var(--color-accent-300) 72%);
  box-shadow: inset 0 1px 2px rgba(255,255,255,0.35), var(--shadow-sm);
}
.gallery-tile--text h3 { margin: 0; font-size: 1rem; color: #fff; line-height: 1.25; }
.gallery-tile--text span { font-size: 0.76rem; font-weight: 600; color: var(--color-oncharcoal-soft); }
