/*
 * base.css — Structure, layout and behaviour
 * ============================================
 * Consumes tokens from tokens.css exclusively.
 * ZERO literal colour values — any hex here is a theming bug.
 *
 * Load order in <head>:
 *   <link rel="stylesheet" href="/static/css/tokens.css">
 *   <link rel="stylesheet" href="/static/css/base.css">
 *
 * Contents
 *   1.  Reset & globals
 *   2.  Accessibility utilities
 *   3.  Motion — prefers-reduced-motion escape hatch
 *   4.  Focus indicator (two-tone, variant-safe)
 *   5.  Typography
 *   6.  Banners (emergency, demo)
 *   7.  Header & navigation
 *   8.  Buttons
 *   9.  Layout primitives (main, footer)
 *  10.  Cards — three-weight system
 *  11.  Forms
 *  12.  Hero
 *  13.  Service cards grid
 *  14.  Gallery
 *  15.  Testimonials
 *  16.  GBP badge
 *  17.  Badges
 *  18.  FAQ
 *  19.  Business directory
 *  20.  Results / feedback / price estimator
 *  21.  Sticky mobile CTA bar
 *  22.  WhatsApp floating button
 *  23.  Cookie banner
 *  24.  Admin & utility
 *  25.  Responsive overrides
 */


/* ── 1. Reset & globals ──────────────────────────────────────── */

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

html {
  scroll-behavior: smooth;
}

/*
 * Keep anchor targets clear of the sticky header.
 *
 * .site-header is position:sticky, so jumping to #enquiry parked the heading
 * underneath it — "Request a call back" rendered as "…p … back", sliced
 * through the letterforms. Measured 65px hidden on mobile, 74-76px on desktop.
 * The nav's own "Contact" link is one of the offenders, so it affected every
 * site in the range.
 *
 * Applied to any element with an id, since that is exactly the set that can
 * be an anchor target. --header-clearance is a little over the tallest
 * rendered header so the heading lands with breathing room, not flush.
 */
[id] {
  scroll-margin-top: var(--header-clearance, 5.5rem);
}

body {
  margin: 0;
  font-family: var(--font-sans);
  background: var(--color-bg);
  color: var(--color-text);
  line-height: var(--leading-normal);
  font-size: var(--text-base);
  /* padding-bottom only applied at ≤640px — see §25 */
}

a {
  color: var(--color-link);
}


/* ── 2. Accessibility utilities ──────────────────────────────── */

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

.skip-link {
  position: absolute;
  left: -999px;
  top: 0;
  background: var(--color-primary);
  color: var(--color-text-inverse);
  padding: var(--space-3) var(--space-4);
  z-index: 200;
}
.skip-link:focus {
  left: 0;
}

.honeypot {
  position: absolute !important;
  left: -10000px !important;
  width: 1px !important;
  height: 1px !important;
  overflow: hidden !important;
}


/* ── 3. Motion — prefers-reduced-motion ──────────────────────── */
/*
 * Users who prefer reduced motion get no smooth scrolling and
 * no transform animations. The transition rule matches only
 * properties that could animate layout or cause vestibular
 * discomfort. Opacity and colour transitions are left intact
 * so interactive states remain perceptible.
 */
@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }

  .service-card,
  .service-card:hover {
    transform: none;
    transition: none;
  }
}


/* ── 4. Focus indicator ──────────────────────────────────────── */
/*
 * Two-tone ring: white inner outline + near-black outer halo.
 * Guarantees ≥3:1 against every button and surface colour in
 * the token set. See tokens.css §3 for measured ratios.
 *
 * Do NOT remove or simplify this to a single-colour outline —
 * that recreates the 1.00:1 WCAG 1.4.11 failure this replaces.
 */
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
button:focus-visible,
a:focus-visible,
[tabindex]:focus-visible {
  outline: var(--focus-ring-inner);
  outline-offset: var(--focus-ring-offset);
  box-shadow: var(--focus-ring-outer);
}

/* Suppress the ring for POINTER focus only.
 *
 * This rule previously read `input:focus, … { outline: none }`. It has the
 * same specificity (0,1,1) as the :focus-visible rule above and comes later,
 * so it won — silently killing the white inner outline on every button, link
 * and input on every site, leaving only the dark halo. That is exactly the
 * single-band failure the comment above warns against, and it measured 1.05:1
 * against the cookie banner.
 *
 * `:not(:focus-visible)` raises specificity to (0,2,1) AND narrows the match
 * to focus the browser judged not keyboard-driven, so a mouse click still
 * doesn't draw a ring while a Tab press always does.
 */
input:focus:not(:focus-visible),
select:focus:not(:focus-visible),
textarea:focus:not(:focus-visible),
button:focus:not(:focus-visible),
a:focus:not(:focus-visible) {
  outline: none;
  box-shadow: none;
}


/* ── 5. Typography ───────────────────────────────────────────── */

h1, h2, h3, h4 {
  font-family: var(--font-heading);
  line-height: var(--leading-tight);
  margin-top: 0;
}

h1 { font-size: var(--text-4xl); }
h2 { font-size: var(--text-3xl); }
h3 { font-size: var(--text-2xl); }
h4 { font-size: var(--text-xl); }

.small-print {
  font-size: var(--text-sm);
  color: var(--color-muted);
  margin-top: var(--space-4);
}

.error-text {
  color: var(--color-error-text);
  font-weight: var(--weight-bold);
}

.success-text {
  color: var(--color-success-text);
  font-weight: var(--weight-bold);
}


/* ── 6. Banners ──────────────────────────────────────────────── */

.emergency-banner {
  background: var(--color-emergency);
  color: var(--color-emergency-text);
  text-align: center;
  padding: var(--space-2) var(--space-4);
  font-size: var(--text-sm);
}
.emergency-banner a {
  color: var(--color-emergency-text);
  text-decoration: underline;
  font-weight: var(--weight-bold);
}

.demo-banner {
  background: var(--demo-bg);
  color: var(--demo-text);
  text-align: center;
  padding: var(--space-1) var(--space-4);
  font-size: var(--text-xs);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
}


/* ── 7. Header & navigation ──────────────────────────────────── */

.site-header {
  background: var(--header-bg);
  border-bottom: 1px solid var(--color-border);
  position: sticky;
  top: 0;
  z-index: 50;
}

.header-inner {
  max-width: var(--layout-max-w);
  margin: 0 auto;
  padding: var(--header-padding-y) var(--header-padding-x);
  display: flex;
  align-items: center;
  gap: var(--space-4);
  flex-wrap: wrap;
}

.brand-link {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  text-decoration: none;
  color: var(--color-text);
}

.logo {
  border-radius: var(--radius-md);
}

.brand-name {
  font-weight: var(--brand-name-weight);
  font-size: var(--brand-name-size);
}

.nav-toggle {
  display: none;
  margin-left: auto;
  background: none;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  font-size: 1.3rem;
  padding: var(--space-1) var(--space-3);
  cursor: pointer;
  color: var(--color-text);
}

.main-nav {
  display: flex;
  gap: var(--nav-gap);
  margin-left: var(--space-4);
  flex: 1;
}

.main-nav a {
  text-decoration: none;
  color: var(--color-text);
  font-weight: var(--nav-font-weight);
  font-size: var(--nav-font-size);
}

.main-nav a:hover {
  color: var(--color-primary);
}

.header-cta {
  margin-left: auto;
}

.breadcrumbs {
  font-size: var(--breadcrumb-font);
  color: var(--color-muted);
  margin: var(--space-4) var(--layout-gutter) 0;
}

.breadcrumbs a {
  color: var(--color-muted);
}


/* ── 8. Buttons ──────────────────────────────────────────────── */

.btn {
  display: inline-block;
  padding: var(--btn-padding-y) var(--btn-padding-x);
  border-radius: var(--btn-radius);
  font-weight: var(--weight-bold);
  text-decoration: none;
  border: none;
  cursor: pointer;
  font-size: var(--text-base);
}

.btn-call {
  background: var(--color-emergency);
  color: var(--color-emergency-text);
}
.btn-call:hover {
  background: var(--color-emergency-dark);
}

.btn-whatsapp {
  background: var(--color-whatsapp);
  color: var(--color-text-inverse);
}
.btn-whatsapp:hover {
  background: var(--color-whatsapp-dark);
}

.btn-large {
  padding: var(--btn-padding-y-lg) var(--btn-padding-x-lg);
  font-size: var(--text-lg);
}

.btn-block {
  flex: 1;
  text-align: center;
}

/* Generic submit / primary button (not using .btn modifier) */
button:not(.btn):not(.btn-delete):not(.nav-toggle):not(.link-button):not(#cookie-accept):not(#cookie-reject) {
  background: var(--color-primary);
  color: var(--color-text-inverse);
  border: none;
  border-radius: var(--btn-radius);
  padding: var(--space-3) var(--space-6);
  font-size: var(--text-base);
  cursor: pointer;
  margin-top: var(--space-3);
}
button:not(.btn):not(.btn-delete):not(.nav-toggle):not(.link-button):not(#cookie-accept):not(#cookie-reject):hover {
  background: var(--color-primary-dark);
}

.btn-delete {
  background: none;
  border: 1px solid var(--color-border-error);
  color: var(--color-error-text);
  border-radius: var(--radius-md);
  padding: var(--space-1) var(--space-3);
  font-size: var(--text-sm);
  cursor: pointer;
}

.link-button {
  background: none;
  border: 0;
  padding: 0;
  text-decoration: underline;
  cursor: pointer;
  font: inherit;
  color: var(--color-link);
}

.pagination-controls {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  justify-content: center;
  margin: var(--space-6) 0;
}

.pagination-controls .btn[aria-disabled="true"] {
  pointer-events: none;
  opacity: 0.5;
}


/* ── 9. Layout primitives ────────────────────────────────────── */
/*
 * main and .site-footer share --layout-max-w with the header
 * so content never appears narrower than the chrome framing it.
 */
main {
  max-width: var(--layout-max-w);
  margin: 0 auto;
  padding: var(--layout-gutter);
}

.site-footer {
  max-width: var(--layout-max-w);
  margin: 0 auto;
  padding: var(--space-8) var(--layout-gutter) var(--space-4);
}

.footer-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: var(--space-6);
  margin-bottom: var(--space-6);
}

.plain-list {
  list-style: none;
  padding: 0;
  margin: 0;
}

.plain-list li {
  margin-bottom: var(--space-1);
}

.legal-nav {
  text-align: center;
  margin-bottom: var(--space-2);
}

.policy-page {
  max-width: 700px;
}


/* ── 10. Cards — three-weight system ─────────────────────────── */
/*
 * CONVERSION  .card--conversion
 *   The price estimator and enquiry form. Accent background,
 *   bold left-rule accent stripe, deep shadow, top-tier z-weight.
 *   The eye should land here first on any page.
 *
 * NEUTRAL  .card  (default, no modifier)
 *   Content sections, testimonials, FAQ accordions, business
 *   directory. White surface, 1px border, soft shadow — readable
 *   but not competing with conversion surfaces.
 *
 * RECEDE  .card--recede
 *   Accreditation badges, legal copy, secondary supporting info.
 *   Grey surface, no border, no shadow. Sits behind the neutral
 *   layer visually and invites the eye to move on.
 *
 * The distinction is not a single-pixel border change:
 *   conversion has a 4px accent stripe + coloured bg + large shadow
 *   recede has a different background and no elevation at all
 */

.card {
  background: var(--card-neutral-bg);
  border: var(--card-neutral-border);
  border-radius: var(--card-neutral-radius);
  box-shadow: var(--card-neutral-shadow);
  padding: var(--space-6);
  margin-bottom: var(--space-6);
}

.card--conversion {
  background: var(--card-conversion-bg);
  border: var(--card-conversion-border);
  border-left: var(--card-conversion-border-l);
  border-radius: var(--card-conversion-radius);
  box-shadow: var(--card-conversion-shadow);
  padding: var(--space-6);
  margin-bottom: var(--space-6);
}

.card--recede {
  background: var(--card-recede-bg);
  border: var(--card-recede-border);
  border-radius: var(--card-recede-radius);
  box-shadow: var(--card-recede-shadow);
  padding: var(--space-6);
  margin-bottom: var(--space-6);
}

/* Admin alert uses the error border treatment */
.admin-alert-banner {
  border-color: var(--color-border-error);
  border-width: 2px;
  background: var(--color-alert-bg);
}


/* ── 11. Forms ───────────────────────────────────────────────── */

label {
  display: block;
  font-weight: var(--weight-semibold);
  margin: var(--space-3) 0 var(--space-1);
}

input[type="text"],
input[type="email"],
input[type="tel"],
input[type="number"],
input[type="file"],
select,
textarea {
  width: 100%;
  padding: var(--input-padding);
  border: var(--input-border);
  border-radius: var(--input-radius);
  font-size: var(--text-base);
  font-family: inherit;
  background: var(--color-surface);
  color: var(--color-text);
}

.consent-row {
  display: flex;
  gap: var(--space-2);
  align-items: flex-start;
  margin-top: var(--space-4);
}

.consent-row input {
  width: auto;
  margin-top: var(--space-1);
}

.consent-row label {
  font-weight: var(--weight-normal);
  margin: 0;
}

.review-option {
  display: block;
  margin: var(--space-4) 0;
  padding: var(--space-4);
  border: 1px solid var(--color-border);
  border-radius: var(--btn-radius);
}

.review-option input {
  margin-right: var(--space-2);
}


/* ── 12. Hero ────────────────────────────────────────────────── */

.hero {
  display: flex;
  gap: var(--space-8);
  align-items: center;
  /* `wrap` (not `wrap-reverse`) so that when the hero collapses to one column
     on mobile the <h1> stays above the image. wrap-reverse pushed the image
     above the headline, which cost LCP and shoved the value proposition
     off-screen on small phones. Desktop layout is unchanged: text left,
     image right. */
  flex-wrap: wrap;
  padding: var(--space-6) 0 var(--space-8);
}

.hero-text {
  flex: 1 1 380px;
}

.hero-text h1 {
  font-size: var(--text-4xl);
  margin-bottom: var(--space-2);
}

.hero-sub {
  color: var(--color-muted);
  font-size: var(--text-lg);
}

.hero-ctas {
  display: flex;
  gap: var(--space-3);
  flex-wrap: wrap;
  margin: var(--space-5) 0;
}

.trust-strip {
  list-style: none;
  padding: 0;
  display: flex;
  gap: var(--space-4);
  flex-wrap: wrap;
  font-size: var(--text-sm);
  color: var(--color-muted);
}

.hero-image {
  flex: 1 1 280px;
  text-align: center;
}

.hero-image img {
  max-width: 100%;
  height: auto;
  border-radius: var(--radius-lg);
}


/* ── 13. Service cards grid ──────────────────────────────────── */

/*
 * 260px, not 220px. Every trade pack ships exactly six services, and at the
 * 1100px content width a 220px minimum resolves to FOUR columns — so the
 * second row held two cards and two empty cells, on all 90 desktop homepages.
 * 260px resolves to three, giving a clean 3+3. Checked across the range: no
 * width leaves a gap for six items (3 cols ~830-1100px, 2 below, 1 on phones).
 *
 * The card surface stays --color-surface-recede rather than moving to
 * --color-surface-raised: `raised` resolves to the same value as `surface` in
 * all 15 packs, so switching would leave the tiles separated from the section
 * behind them by nothing but a 1px border. The tone concern the review raised
 * is really the recede/neutral contrast inversion in five packs, which is a
 * pack-level fix.
 */
.services-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: var(--space-4);
}

.service-card {
  display: block;
  background: var(--color-surface-recede);
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  padding: var(--space-4);
  text-decoration: none;
  color: var(--color-text);
  transition: box-shadow var(--duration-fast) var(--ease-standard),
              transform var(--duration-fast) var(--ease-standard);
}

.service-card:hover {
  box-shadow: var(--shadow-card-hover);
  transform: translateY(-2px);
}

/* transform suppressed in §3 when prefers-reduced-motion: reduce */

.link-arrow {
  color: var(--color-primary);
  font-weight: var(--weight-bold);
  font-size: var(--text-sm);
}


/* ── 14. Gallery ─────────────────────────────────────────────── */
/*
 * Fixes layout shift: HTML carries width="300" height="220"
 * while CSS was width:100%; height:auto. Now aspect-ratio
 * reserves the correct space before the image loads.
 */

.gallery-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
  gap: var(--space-4);
}

.gallery-item img {
  width: 100%;
  height: auto;
  aspect-ratio: var(--gallery-aspect-ratio);
  object-fit: cover;
  border-radius: var(--btn-radius);
  display: block;
}

.gallery-item figcaption {
  font-size: var(--text-sm);
  color: var(--color-muted);
  margin-top: var(--space-1);
}


/* ── 15. Testimonials ────────────────────────────────────────── */

.testimonial-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: var(--space-4);
}

.testimonial-card {
  margin: 0;
  background: var(--color-surface-recede);
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  padding: var(--space-4);
}

.testimonial-card img {
  border-radius: var(--radius-full);
  margin-bottom: var(--space-2);
}

.testimonial-card footer {
  color: var(--color-muted);
  font-size: var(--text-sm);
  margin-top: var(--space-2);
}


/* ── 16. GBP badge ───────────────────────────────────────────── */

.gbp-rating-badge {
  display: inline-block;
  background: var(--color-badge-bg);
  border: 1px solid var(--color-badge-border);
  border-radius: var(--btn-radius);
  padding: var(--space-2) var(--space-4);
  margin-bottom: var(--space-4);
  font-size: var(--text-lg);
}

.gbp-attribution {
  margin-top: var(--space-3);
}


/* ── 17. Accreditation badges ────────────────────────────────── */

.badge-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
  gap: var(--space-4);
  text-align: center;
}

.badge-item img {
  margin-bottom: var(--space-1);
}


/* ── 18. FAQ ─────────────────────────────────────────────────── */

.faq-item {
  border-bottom: 1px solid var(--color-border);
  padding: var(--space-3) 0;
}

.faq-item summary {
  cursor: pointer;
  font-weight: var(--weight-semibold);
}


/* ── 19. Business directory ──────────────────────────────────── */

.business-directory {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
  gap: var(--space-4);
}

.business-card {
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  padding: var(--space-4);
  background: var(--color-surface);
}


/* ── 20. Results / feedback / price estimator ────────────────── */

.result-item {
  padding: var(--space-3);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  margin-top: var(--space-2);
}

.result-item.covered {
  border-left: 4px solid var(--color-primary);
}

.result-item.not-covered {
  border-left: 4px solid var(--color-muted);
  opacity: 0.8;
}

.breakdown-line {
  display: flex;
  justify-content: space-between;
  padding: var(--space-1) 0;
  border-bottom: 1px dashed var(--color-border);
}

.breakdown-total {
  display: flex;
  justify-content: space-between;
  font-weight: var(--weight-bold);
  padding-top: var(--space-2);
}


/* ── 21. Sticky mobile CTA bar ───────────────────────────────── */
/*
 * --sticky-cta-height is the single source of truth for the
 * bar's height. The cookie banner bottom offset (§23) reads
 * the same token so neither ever overlaps the other.
 */

/* Hidden by initStickyBar() while the hero's own CTAs are on screen, so the
   bar never slices through a button offering the same action. Visible by
   default: without JS the behaviour is unchanged. */
.sticky-cta-bar.is-hidden {
  display: none !important;
}

.sticky-cta-bar {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  height: var(--sticky-cta-height);
  display: none;
  gap: var(--space-2);
  padding: var(--space-2);
  background: var(--color-surface);
  border-top: 1px solid var(--color-border);
  z-index: 100;
}


/* ── 22. WhatsApp floating button (desktop) ──────────────────── */

.whatsapp-fab {
  position: fixed;
  bottom: var(--space-6);
  right: var(--space-6);
  width: 56px;
  height: 56px;
  background: var(--color-whatsapp);
  color: var(--color-text-inverse);
  border-radius: var(--radius-full);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.6rem;
  text-decoration: none;
  box-shadow: var(--shadow-fab);
  z-index: 100;
}

.whatsapp-fab:hover {
  background: var(--color-whatsapp-dark);
}


/* ── 23. Cookie banner ───────────────────────────────────────── */
/*
 * On mobile the banner sits above the sticky CTA bar using
 * --sticky-cta-height — the same token that sets the bar's height.
 * This replaces the hardcoded 56px guess in the original.
 */

#cookie-banner {
  /* In normal flow at the top of the document. It was position:fixed at the
     bottom, which floated it over whatever sat at the foot of the viewport on
     first paint — burying a hero CTA on 4 of the 5 layout archetypes, because
     hero height varies by layout. In flow it pushes content down instead. */
  background: var(--color-surface-dark);
  color: var(--color-text-inverse);
  padding: var(--space-4) var(--layout-gutter);
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4);
  justify-content: space-between;
  align-items: center;
  z-index: 300;
}

/* No reserved-space rules needed: an in-flow banner occupies real layout
   space, so nothing has to compensate for it. */

#cookie-banner p {
  margin: 0;
  flex: 1 1 300px;
  font-size: var(--text-sm);
}

#cookie-banner a {
  color: var(--color-text-inverse);
}

.cookie-actions {
  display: flex;
  gap: var(--space-2);
}

.cookie-actions button {
  border-radius: var(--radius-md);
  padding: var(--space-2) var(--space-4);
  font-size: var(--text-sm);
  cursor: pointer;
  border: none;
  margin-top: 0;
}

#cookie-accept {
  background: var(--color-primary);
  color: var(--color-text-inverse);
}

#cookie-reject {
  background: transparent;
  border: 1px solid var(--color-text-inverse);
  color: var(--color-text-inverse);
}


/* ── 24. Admin & utility ─────────────────────────────────────── */

.admin-page {
  max-width: 800px;
  margin: var(--space-8) auto;
  padding: 0 var(--layout-gutter);
}

.admin-summary-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: var(--space-4);
  margin-bottom: var(--space-6);
}

.admin-summary-grid .card {
  text-align: center;
}

.admin-summary-grid h2 {
  font-size: var(--text-3xl);
  margin: 0 0 var(--space-1);
}

.admin-table {
  width: 100%;
  border-collapse: collapse;
  margin-top: var(--space-4);
}

.admin-table th,
.admin-table td {
  text-align: left;
  padding: var(--space-2);
  border-bottom: 1px solid var(--color-border);
  font-size: var(--admin-table-font);
}


/* ── 25. Responsive overrides ────────────────────────────────── */

@media (max-width: 640px) {

  /* Body bottom padding — only needed on mobile to clear the sticky bar */
  body {
    padding-bottom: var(--sticky-cta-height);
  }

  /* Tighter banner on small screens — it does not need three lines of
     padding to ask one question. Measured on a 375x667 phone: 158px before,
     ~85px after, which is what lifts it clear of the hero's second CTA. */
  #cookie-banner {
    padding: var(--space-2) var(--layout-gutter);
    gap: var(--space-2);
    row-gap: var(--space-2);
  }

  #cookie-banner p {
    flex-basis: 100%;
    font-size: var(--text-xs);
    line-height: var(--leading-tight);
  }

  .cookie-actions button {
    padding: var(--space-2) var(--space-3);
  }

  /* Navigation collapses behind toggle */
  .main-nav {
    display: none;
  }

  .main-nav.open {
    display: flex;
    flex-direction: column;
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    background: var(--color-surface);
    padding: var(--space-4) var(--layout-gutter);
    border-bottom: 1px solid var(--color-border);
  }

  .nav-toggle {
    display: block;
  }

  .header-cta {
    display: none;
  }

  /* Sticky CTA bar appears */
  .sticky-cta-bar {
    display: flex;
  }

  /* FAB hidden — covered by sticky bar */
  .whatsapp-fab {
    display: none;
  }

}
