/* ==========================================================================
   Gardening — Formal Garden Design
   Design system & site stylesheet
   Block classes (.block-*) map 1:1 to the Gutenberg block names used in
   content.json, so the WordPress/Gutenberg build can share this exact
   visual language. See /README.md for the block-name ↔ class mapping.
   ========================================================================== */

/* ---------- Design tokens ---------- */
:root {
  /* Brand colors — chosen for a premium, formal European garden business
     targeting UK homeowners. Primary = refined boxwood green (trust,
     nature, craftsmanship). Secondary = ~40% darker forest green for
     depth, footers and overlays. Accent = muted brass/gold for a formal,
     estate-garden feel on hovers and dividers. */
  --color-primary: #3F6B44;
  --color-primary-dark: #2E4F33;
  --color-secondary: #26402D;
  --color-accent: #B79657;
  --color-accent-dark: #93762D;

  --color-bg: #FBF9F4;
  --color-bg-alt: #F2EFE6;
  --color-surface: #FFFFFF;
  --color-ink: #1F2A22;
  --color-ink-soft: #4B554D;
  --color-border: #E2DDCE;

  --color-on-dark: #F5F2E9;
  --color-on-dark-soft: #C9D2C8;

  --font-display: 'Playfair Display', Georgia, 'Times New Roman', serif;
  --font-body: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;

  --container: 1180px;
  --radius: 4px;
  --radius-lg: 10px;
  --shadow-sm: 0 1px 3px rgba(31, 42, 34, 0.08);
  --shadow-md: 0 10px 30px rgba(31, 42, 34, 0.12);
  --shadow-lg: 0 24px 60px rgba(31, 42, 34, 0.18);

  --space-1: 0.5rem;
  --space-2: 1rem;
  --space-3: 1.5rem;
  --space-4: 2rem;
  --space-5: 3rem;
  --space-6: 4.5rem;
  --space-7: 7rem;

  --transition: 220ms cubic-bezier(.4,0,.2,1);
}

/* ---------- Reset ---------- */
*, *::before, *::after { box-sizing: border-box; }
html { scroll-behavior: smooth; }
body {
  margin: 0;
  font-family: var(--font-body);
  color: var(--color-ink);
  background: var(--color-bg);
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
}
img { max-width: 100%; display: block; }
a { color: inherit; text-decoration: none; }
ul { list-style: none; margin: 0; padding: 0; }
h1, h2, h3, h4 { font-family: var(--font-display); font-weight: 600; line-height: 1.2; margin: 0 0 var(--space-2); color: var(--color-ink); }
p { margin: 0 0 var(--space-2); }
button { font-family: inherit; cursor: pointer; }
.container { max-width: var(--container); margin: 0 auto; padding: 0 var(--space-3); }

@media (max-width: 640px) {
  :root { --space-6: 3rem; --space-7: 4rem; }
}

/* ---------- Utility ---------- */
.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-family: var(--font-body);
  font-size: 0.78rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  font-weight: 600;
  color: var(--color-accent-dark);
  margin-bottom: var(--space-2);
}
.eyebrow::before { content: ""; width: 26px; height: 1px; background: var(--color-accent-dark); display: inline-block; }

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  padding: 0.9rem 1.7rem;
  border-radius: var(--radius);
  font-weight: 600;
  font-size: 0.95rem;
  letter-spacing: 0.01em;
  border: 1px solid transparent;
  transition: transform var(--transition), background var(--transition), color var(--transition), border-color var(--transition), box-shadow var(--transition);
  white-space: nowrap;
}
.btn:hover, .btn:focus-visible { transform: translateY(-2px); }
.btn:focus-visible { outline: 2px solid var(--color-accent); outline-offset: 2px; }
.btn-primary { background: var(--color-primary); color: #fff; box-shadow: var(--shadow-sm); }
.btn-primary:hover { background: var(--color-primary-dark); box-shadow: var(--shadow-md); }
.btn-outline { background: transparent; border-color: currentColor; color: var(--color-ink); }
.btn-outline:hover { background: var(--color-ink); color: #fff; }
.btn-on-dark { background: var(--color-accent); color: var(--color-secondary); }
.btn-on-dark:hover { background: #fff; }
.btn-outline-on-dark { background: transparent; border-color: rgba(245,242,233,0.55); color: var(--color-on-dark); }
.btn-outline-on-dark:hover { background: rgba(245,242,233,0.12); border-color: #fff; }

.btn-row { display: flex; flex-wrap: wrap; gap: var(--space-2); }

.section-head { max-width: 640px; margin: 0 0 var(--space-5); }
.section-head.center { margin-left: auto; margin-right: auto; text-align: center; }
.section-head h2 { font-size: clamp(1.6rem, 2.4vw, 2.1rem); }
.section-head p { color: var(--color-ink-soft); font-size: 1.02rem; }

/* Scroll-reveal is opt-in via JS: the "js-armed" class is added by an
   inline script at the top of <head>, synchronously, before paint. If
   JavaScript is unavailable or hasn't run yet, .reveal content is shown
   immediately — it never depends on scroll position or observer timing
   to become visible (important for SEO crawlers, slow connections, and
   printing/screenshot tools). */
.reveal { transition: opacity 700ms ease, transform 700ms ease; }
html.js-armed .reveal { opacity: 0; transform: translateY(22px); }
html.js-armed .reveal.is-visible { opacity: 1; transform: none; }

.deco-motif {
  width: 100%; height: 100%;
  background-image: radial-gradient(circle at 8px 8px, rgba(255,255,255,0.20) 2px, transparent 2.6px);
  background-size: 42px 42px;
}

/* ---------- Skip link ---------- */
.skip-link {
  position: absolute; left: -999px; top: 0; z-index: 999;
  background: var(--color-ink); color: #fff; padding: 0.75rem 1.25rem; border-radius: 0 0 6px 0;
}
.skip-link:focus { left: 0; }

/* ---------- Header ---------- */
.site-header {
  position: sticky; top: 0; z-index: 100;
  border-bottom: 1px solid transparent;
  transition: border-color var(--transition);
}
/* The glass-blur background lives on a ::before, not on .site-header itself.
   backdrop-filter (like filter/transform) on an ANCESTOR establishes a new
   containing block for position:fixed descendants — and .main-nav (the
   mobile slide-in menu) is one such descendant. Putting it directly on
   .site-header broke the mobile nav panel, sizing it against the ~88px
   header box instead of the viewport. A ::before is a child, not an
   ancestor, of the header's other children, so it can't cause that. */
.site-header::before {
  content: ""; position: absolute; inset: 0; z-index: -1;
  background: rgba(251, 249, 244, 0.92);
  backdrop-filter: saturate(140%) blur(8px);
  box-shadow: 0 1px 3px rgba(31, 42, 34, 0);
  transition: box-shadow var(--transition);
}
.site-header.is-scrolled::before { box-shadow: var(--shadow-sm); }
.site-header.is-scrolled { border-color: var(--color-border); }
.header-inner { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); padding: 1.1rem 0; }

.brand { display: flex; align-items: center; gap: 0.65rem; font-family: var(--font-display); font-size: 1.35rem; font-weight: 600; color: var(--color-ink); }
.brand-mark { width: 34px; height: 34px; flex: none; }
.brand-mark svg { width: 100%; height: 100%; display: block; }
.brand small { display: block; font-family: var(--font-body); font-size: 0.62rem; letter-spacing: 0.16em; text-transform: uppercase; color: var(--color-ink-soft); font-weight: 600; }

.main-nav { display: flex; }
.main-nav ul { display: flex; align-items: center; gap: var(--space-4); }
.main-nav a {
  font-size: 0.92rem; font-weight: 500; color: var(--color-ink-soft);
  position: relative; padding: 0.3rem 0; transition: color var(--transition);
}
.main-nav a::after {
  content: ""; position: absolute; left: 0; right: 100%; bottom: -2px; height: 2px; background: var(--color-accent);
  transition: right var(--transition);
}
.main-nav a:hover, .main-nav a:focus-visible, .main-nav a.is-active { color: var(--color-ink); }
.main-nav a:hover::after, .main-nav a:focus-visible::after, .main-nav a.is-active::after { right: 0; }

.header-cta { display: flex; align-items: center; gap: var(--space-3); }
.header-phone { display: none; font-size: 0.92rem; font-weight: 600; color: var(--color-ink); }
.header-phone svg { width: 16px; height: 16px; margin-right: 0.4rem; vertical-align: -3px; color: var(--color-accent-dark); }

.nav-toggle {
  display: inline-flex; align-items: center; justify-content: center;
  width: 42px; height: 42px; border: 1px solid var(--color-border); border-radius: var(--radius);
  background: var(--color-surface);
}
.nav-toggle span, .nav-toggle span::before, .nav-toggle span::after {
  content: ""; display: block; width: 18px; height: 2px; background: var(--color-ink); position: relative; transition: transform var(--transition), opacity var(--transition);
}
.nav-toggle span::before { position: absolute; top: -6px; }
.nav-toggle span::after { position: absolute; top: 6px; }
.nav-open .nav-toggle span { background: transparent; }
.nav-open .nav-toggle span::before { transform: translateY(6px) rotate(45deg); }
.nav-open .nav-toggle span::after { transform: translateY(-6px) rotate(-45deg); }

@media (max-width: 900px) {
  .main-nav {
    position: fixed; inset: 0 0 0 30%; top: var(--header-h, 72px);
    background: var(--color-surface); border-left: 1px solid var(--color-border);
    transform: translateX(100%); transition: transform var(--transition); overflow-y: auto;
    box-shadow: var(--shadow-lg);
  }
  .nav-open .main-nav { transform: translateX(0); }
  .main-nav ul { flex-direction: column; align-items: flex-start; gap: 0; padding: var(--space-4); width: 100%; }
  .main-nav li { width: 100%; border-bottom: 1px solid var(--color-border); }
  .main-nav a { display: block; padding: 1rem 0; }
  .nav-toggle { display: inline-flex; }
}
@media (min-width: 901px) {
  .nav-toggle { display: none; }
  .header-phone { display: inline-flex; align-items: center; }
}
@media (max-width: 560px) { .main-nav { left: 12%; } }
@media (max-width: 660px) {
  /* Brand + "Request a Quote" + hamburger don't all fit on narrow phones —
     the in-page hero/CTA sections already repeat this call to action, so
     drop the header button here and keep just the menu toggle. */
  .header-cta .btn-primary { display: none; }
}
@media (max-width: 380px) {
  .brand small { display: none; }
}

/* ---------- Hero (hero_sage) ---------- */
.block-hero-sage {
  position: relative;
  color: var(--color-on-dark);
  background: linear-gradient(155deg, var(--color-secondary), var(--color-primary-dark) 60%, var(--color-primary));
  overflow: hidden;
}
.block-hero-sage .container { position: relative; z-index: 2; }
.hero-inner { padding: var(--space-7) 0 var(--space-6); max-width: 760px; }
.block-hero-sage.layout-split .hero-inner { max-width: none; display: grid; grid-template-columns: 1.1fr 0.9fr; gap: var(--space-5); align-items: center; }
.block-hero-sage.layout-split .hero-copy { max-width: 620px; }
.hero-visual { position: relative; border-radius: var(--radius-lg); overflow: hidden; aspect-ratio: 4/5; box-shadow: var(--shadow-lg); border: 1px solid rgba(255,255,255,0.15); }
.hero-rating { display: inline-flex; align-items: center; gap: 0.5rem; font-size: 0.82rem; font-weight: 600; letter-spacing: 0.05em; text-transform: uppercase; color: var(--color-on-dark-soft); margin-bottom: var(--space-3); }
.hero-rating svg { width: 16px; height: 16px; color: var(--color-accent); }
.block-hero-sage h1 { font-size: clamp(2.1rem, 4.6vw, 3.4rem); color: #fff; max-width: 18ch; }
.block-hero-sage .hero-text { font-size: 1.08rem; color: var(--color-on-dark-soft); max-width: 56ch; margin-bottom: var(--space-4); }
.hero-actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-3); }
.hero-phone { display: inline-flex; align-items: center; gap: 0.5rem; font-weight: 600; color: #fff; }
.hero-phone svg { width: 18px; height: 18px; color: var(--color-accent); }

/* Hybrid editing (v1.0.7+): hero-sage's eyebrow/heading/body/button
   content is real WordPress core blocks (paragraph/heading/buttons/
   button) rendered via InnerBlocks, not our own hand-built markup —
   see build/generate_blocks.py and shared/sage-blocks-renderer.php.
   ".hero-rating"/".hero-actions"/".hero-phone-btn" are the exact
   classNames each inner block instance is published with, so most of
   the rules above already apply unchanged; the pieces below only
   restyle what's genuinely different — the button link now being
   "wp-block-button__link" instead of our own "btn" class, and the
   eyebrow/phone icons, which used to be an inline <svg> and now have
   to come from CSS instead, since a plain WordPress paragraph/button
   block has nowhere to put one. Kept as their own block (rather than
   folded into the rules above) so it's obvious this is the one area
   of the design system that's driven by the editor's own block
   markup instead of by shared/sage-blocks-renderer.php. */
.hero-rating::before {
  content: ""; width: 16px; height: 16px; flex-shrink: 0; display: inline-block;
  background-color: var(--color-accent);
  -webkit-mask: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0iYmxhY2siPjxwYXRoIGQ9Ik0xMiAyLjUgMTQuOSA5bDcuMS42LTUuNCA0LjdMMTguMiAyMSAxMiAxNy4zIDUuOCAyMWwxLjYtNi43TDIgOS42IDkuMSA5IDEyIDIuNVoiLz48L3N2Zz4=") center / contain no-repeat;
  mask: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0iYmxhY2siPjxwYXRoIGQ9Ik0xMiAyLjUgMTQuOSA5bDcuMS42LTUuNCA0LjdMMTguMiAyMSAxMiAxNy4zIDUuOCAyMWwxLjYtNi43TDIgOS42IDkuMSA5IDEyIDIuNVoiLz48L3N2Zz4=") center / contain no-repeat;
}
.hero-actions .wp-block-button__link {
  display: inline-flex; align-items: center; justify-content: center; gap: 0.5rem;
  padding: 0.9rem 1.7rem; border-radius: var(--radius); font-weight: 600; font-size: 0.95rem;
  letter-spacing: 0.01em; border: 1px solid transparent; text-decoration: none; white-space: nowrap;
  transition: transform var(--transition), background var(--transition), color var(--transition), border-color var(--transition), box-shadow var(--transition);
}
.hero-actions .wp-block-button__link:hover, .hero-actions .wp-block-button__link:focus-visible { transform: translateY(-2px); }
.hero-actions .wp-block-button.btn-on-dark .wp-block-button__link { background: var(--color-accent); color: var(--color-secondary); }
.hero-actions .wp-block-button.btn-on-dark .wp-block-button__link:hover { background: #fff; }
.hero-actions .wp-block-button.hero-phone-btn .wp-block-button__link {
  background: transparent; border-color: transparent; padding: 0.5rem 0; color: #fff;
}
.hero-actions .wp-block-button.hero-phone-btn .wp-block-button__link:hover { background: transparent; transform: none; }
.hero-actions .wp-block-button.hero-phone-btn .wp-block-button__link::before {
  content: ""; width: 18px; height: 18px; flex-shrink: 0; display: inline-block;
  background-color: var(--color-accent);
  -webkit-mask: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSI+PHBhdGggZD0iTTYuNiAxMC44YzEuNCAyLjggMy44IDUuMSA2LjYgNi42bDIuMi0yLjJjLjMtLjMuNy0uNCAxLS4yIDEuMS40IDIuMy42IDMuNi42LjYgMCAxIC40IDEgMVYyMGMwIC42LS40IDEtMSAxQzEwLjMgMjEgMyAxMy43IDMgNC45YzAtLjYuNC0xIDEtMWgzLjRjLjYgMCAxIC40IDEgMSAwIDEuMy4yIDIuNS42IDMuNi4xLjQgMCAuOC0uMiAxTDYuNiAxMC44WiIgc3Ryb2tlPSJibGFjayIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0cm9rZS1saW5lam9pbj0icm91bmQiLz48L3N2Zz4=") center / contain no-repeat;
  mask: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSI+PHBhdGggZD0iTTYuNiAxMC44YzEuNCAyLjggMy44IDUuMSA2LjYgNi42bDIuMi0yLjJjLjMtLjMuNy0uNCAxLS4yIDEuMS40IDIuMy42IDMuNi42LjYgMCAxIC40IDEgMVYyMGMwIC42LS40IDEtMSAxQzEwLjMgMjEgMyAxMy43IDMgNC45YzAtLjYuNC0xIDEtMWgzLjRjLjYgMCAxIC40IDEgMSAwIDEuMy4yIDIuNS42IDMuNi4xLjQgMCAuOC0uMiAxTDYuNiAxMC44WiIgc3Ryb2tlPSJibGFjayIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0cm9rZS1saW5lam9pbj0icm91bmQiLz48L3N2Zz4=") center / contain no-repeat;
}

.hero-decor {
  position: absolute; inset: 0; opacity: 0.55; pointer-events: none;
  background-image: radial-gradient(circle at 10px 10px, rgba(255,255,255,0.16) 2px, transparent 2.6px);
  background-size: 48px 48px;
}
.hero-decor::after {
  content: ""; position: absolute; inset: 0;
  background: radial-gradient(ellipse at 80% 20%, rgba(183,150,87,0.16), transparent 55%);
}

/* ---------- about_checklist ---------- */
.block-about-checklist { padding: var(--space-7) 0; }
.about-grid { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-6); align-items: center; }
.block-about-checklist.layout-image-right .about-grid { direction: rtl; }
.block-about-checklist.layout-image-right .about-grid > * { direction: ltr; }
.about-media { position: relative; aspect-ratio: 5/4.2; border-radius: var(--radius-lg); overflow: hidden; box-shadow: var(--shadow-md); }
.about-copy p { color: var(--color-ink-soft); font-size: 1.03rem; }
.about-copy .btn { margin-top: var(--space-2); }

/* Hybrid editing (v1.1.0+): about-checklist's eyebrow/heading/body/
   button content is real WordPress core blocks (paragraph/heading/
   buttons/button) rendered via InnerBlocks — see
   build/generate_blocks.py and shared/sage-blocks-renderer.php. The
   button link is now "wp-block-button__link" instead of our own "btn"
   class; styled here to look identical to .btn-outline. */
.about-copy .wp-block-buttons { margin-top: var(--space-2); }
.about-copy .wp-block-button__link {
  display: inline-flex; align-items: center; justify-content: center; gap: 0.5rem;
  padding: 0.9rem 1.7rem; border-radius: var(--radius); font-weight: 600; font-size: 0.95rem;
  letter-spacing: 0.01em; border: 1px solid currentColor; text-decoration: none; white-space: nowrap;
  background: transparent; color: var(--color-ink);
  transition: transform var(--transition), background var(--transition), color var(--transition);
}
.about-copy .wp-block-button__link:hover, .about-copy .wp-block-button__link:focus-visible {
  background: var(--color-ink); color: #fff; transform: translateY(-2px);
}

/* ---------- experience_sage ---------- */
.block-experience-sage { padding: var(--space-7) 0; background: var(--color-bg-alt); }
.experience-grid { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-6); align-items: center; }
.block-experience-sage.layout-image-left .experience-grid { direction: rtl; }
.block-experience-sage.layout-image-left .experience-grid > * { direction: ltr; }
.experience-media { position: relative; aspect-ratio: 1/1; border-radius: 50%; overflow: hidden; box-shadow: var(--shadow-md); border: 8px solid var(--color-surface); max-width: 380px; }
.experience-copy p { color: var(--color-ink-soft); font-size: 1.03rem; }

/* ---------- Media blocks (used across sections) ---------- */
.media-frame { position: relative; width: 100%; height: 100%; background: linear-gradient(150deg, #7C9C7F, #3F6B44 55%, #26402D); }
.media-frame .motif { position: absolute; inset: 0; opacity: 0.55; }
/* Real image (v1.1.0+ demo images / WordPress Media Library — see
   uw_media_frame_html() in shared/sage-blocks-renderer.php): fills the
   same frame the placeholder gradient/motif used to, so no layout
   changes are needed wherever a section already had a real photo. */
.media-frame img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block; }
.media-caption {
  position: absolute; left: 0; right: 0; bottom: 0; padding: 0.9rem 1.1rem;
  background: linear-gradient(0deg, rgba(0,0,0,0.55), transparent);
  color: #fff; font-size: 0.72rem; letter-spacing: 0.04em;
}

/* ---------- services_grid_sage ---------- */
.block-services-grid-sage { padding: var(--space-7) 0; }
.services-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--space-3); }
.block-services-grid-sage.layout-list-rows .services-grid { grid-template-columns: 1fr; }
.service-card {
  background: var(--color-surface); border: 1px solid var(--color-border); border-radius: var(--radius-lg);
  padding: var(--space-3); display: flex; flex-direction: column; gap: 0.6rem;
  transition: transform var(--transition), box-shadow var(--transition), border-color var(--transition);
}
.block-services-grid-sage.layout-list-rows .service-card { flex-direction: row; align-items: flex-start; gap: var(--space-3); padding: var(--space-3) var(--space-4); }
.service-card:hover { transform: translateY(-6px); box-shadow: var(--shadow-md); border-color: var(--color-primary); }
.service-icon { width: 44px; height: 44px; flex: none; border-radius: 50%; background: var(--color-bg-alt); display: flex; align-items: center; justify-content: center; color: var(--color-primary); }
.service-icon svg { width: 22px; height: 22px; }
.service-card h3 { font-size: 1.08rem; margin-bottom: 0.15rem; }
.service-card p { color: var(--color-ink-soft); font-size: 0.93rem; margin-bottom: 0.4rem; flex: 1; }
.service-link { font-size: 0.85rem; font-weight: 600; color: var(--color-primary-dark); display: inline-flex; align-items: center; gap: 0.3rem; }
.service-link svg { width: 14px; height: 14px; transition: transform var(--transition); }
.service-link:hover svg { transform: translateX(3px); }

@media (max-width: 1080px) { .services-grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 560px) { .services-grid { grid-template-columns: 1fr; } }

/* ---------- promise_checklist ---------- */
.block-promise-checklist { padding: var(--space-7) 0; }
.block-promise-checklist.layout-tint-band { background: var(--color-bg-alt); }
.promise-grid { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-6); align-items: center; }
.block-promise-checklist.layout-split-image .promise-grid { grid-template-columns: 0.9fr 1.1fr; }
.checklist { display: grid; gap: 0.75rem; margin: var(--space-3) 0 var(--space-4); }
.checklist li { display: flex; align-items: flex-start; gap: 0.7rem; font-size: 0.98rem; color: var(--color-ink); }
.checklist svg { width: 20px; height: 20px; flex: none; color: var(--color-primary); margin-top: 0.1rem; }
.promise-media { position: relative; aspect-ratio: 4/3.4; border-radius: var(--radius-lg); overflow: hidden; box-shadow: var(--shadow-md); }

/* ---------- testimonials_sage ---------- */
.block-testimonials-sage { padding: var(--space-7) 0; }
.block-testimonials-sage.layout-dark-band { background: linear-gradient(160deg, var(--color-secondary), var(--color-primary-dark)); color: var(--color-on-dark); }
.block-testimonials-sage.layout-dark-band .section-head h2 { color: #fff; }
.block-testimonials-sage.layout-dark-band .section-head p { color: var(--color-on-dark-soft); }
.testimonial-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--space-3); }
.testimonial-card {
  border-radius: var(--radius-lg); padding: var(--space-4); position: relative;
  background: var(--color-surface); border: 1px solid var(--color-border);
}
.layout-dark-band .testimonial-card { background: rgba(255,255,255,0.06); border-color: rgba(255,255,255,0.14); backdrop-filter: blur(2px); }
.testimonial-quote-mark { font-family: var(--font-display); font-size: 2.6rem; line-height: 1; color: var(--color-accent); display: block; margin-bottom: 0.4rem; }
.testimonial-card p.t-text { font-size: 0.98rem; color: inherit; }
.layout-dark-band .testimonial-card p.t-text { color: var(--color-on-dark-soft); }
.t-author { display: flex; align-items: center; gap: 0.7rem; margin-top: var(--space-2); }
.t-avatar { width: 40px; height: 40px; border-radius: 50%; background: var(--color-accent); color: var(--color-secondary); display: flex; align-items: center; justify-content: center; font-weight: 700; font-family: var(--font-display); flex: none; }
.t-author strong { display: block; font-size: 0.92rem; }
.t-author span { display: block; font-size: 0.8rem; color: var(--color-ink-soft); }
.layout-dark-band .t-author span { color: var(--color-on-dark-soft); }
@media (max-width: 900px) { .testimonial-grid { grid-template-columns: 1fr; } }

/* ---------- faq_sage ---------- */
.block-faq-sage { padding: var(--space-6) 0; }
.faq-list { display: grid; gap: 0.8rem; }
.block-faq-sage.layout-two-column .faq-list { grid-template-columns: 1fr 1fr; align-items: start; }
.block-faq-sage.layout-single-column-centered { max-width: 780px; margin: 0 auto; }
.faq-item { border: 1px solid var(--color-border); border-radius: var(--radius); background: var(--color-surface); overflow: hidden; }
.faq-q {
  width: 100%; display: flex; align-items: center; justify-content: space-between; gap: var(--space-2);
  padding: 1.1rem 1.3rem; text-align: left; background: transparent; border: none; font-family: var(--font-body);
  font-weight: 600; font-size: 0.98rem; color: var(--color-ink);
}
.faq-q .plus { width: 22px; height: 22px; flex: none; position: relative; }
.faq-q .plus::before, .faq-q .plus::after { content: ""; position: absolute; background: var(--color-primary); transition: transform var(--transition); }
.faq-q .plus::before { left: 0; top: 50%; width: 100%; height: 2px; transform: translateY(-50%); }
.faq-q .plus::after { top: 0; left: 50%; width: 2px; height: 100%; transform: translateX(-50%); }
.faq-item.is-open .plus::after { transform: translateX(-50%) rotate(90deg); opacity: 0; }
.faq-a { max-height: 0; overflow: hidden; transition: max-height 320ms ease; }
.faq-a p { padding: 0 1.3rem 1.2rem; color: var(--color-ink-soft); font-size: 0.95rem; margin: 0; }
@media (max-width: 760px) { .block-faq-sage.layout-two-column .faq-list { grid-template-columns: 1fr; } }

/* ---------- cta_bottom_sage ---------- */
.block-cta-bottom-sage { position: relative; color: var(--color-on-dark); overflow: hidden; }
.block-cta-bottom-sage.layout-cover-image { background: linear-gradient(160deg, var(--color-secondary), var(--color-primary-dark)); }
.block-cta-bottom-sage.layout-solid-band { background: var(--color-ink); }
.cta-inner { padding: var(--space-6) 0; text-align: center; max-width: 720px; margin: 0 auto; position: relative; z-index: 2; }
.block-cta-bottom-sage h2 { color: #fff; font-size: clamp(1.7rem, 3.2vw, 2.3rem); }
.block-cta-bottom-sage p { color: var(--color-on-dark-soft); font-size: 1.03rem; margin-bottom: var(--space-4); }
.cta-actions { display: flex; flex-wrap: wrap; justify-content: center; gap: var(--space-3); }

/* Hybrid editing (v1.1.0+): cta-bottom-sage's heading/body/buttons
   content is real WordPress core blocks rendered via InnerBlocks —
   see build/generate_blocks.py and shared/sage-blocks-renderer.php.
   The buttons group is published with className "cta-actions" (so the
   flex layout above already applies); the two button variants below
   mirror .btn-on-dark / .btn-outline-on-dark exactly, since the link
   itself is now "wp-block-button__link" rather than our own "btn". */
.cta-actions .wp-block-button__link {
  display: inline-flex; align-items: center; justify-content: center; gap: 0.5rem;
  padding: 0.9rem 1.7rem; border-radius: var(--radius); font-weight: 600; font-size: 0.95rem;
  letter-spacing: 0.01em; border: 1px solid transparent; text-decoration: none; white-space: nowrap;
  transition: transform var(--transition), background var(--transition), color var(--transition), border-color var(--transition);
}
.cta-actions .wp-block-button__link:hover, .cta-actions .wp-block-button__link:focus-visible { transform: translateY(-2px); }
.cta-actions .wp-block-button.btn-on-dark .wp-block-button__link { background: var(--color-accent); color: var(--color-secondary); }
.cta-actions .wp-block-button.btn-on-dark .wp-block-button__link:hover { background: #fff; }
.cta-actions .wp-block-button.btn-outline-on-dark .wp-block-button__link { background: transparent; border-color: rgba(245,242,233,0.55); color: var(--color-on-dark); }
.cta-actions .wp-block-button.btn-outline-on-dark .wp-block-button__link:hover { background: rgba(245,242,233,0.12); border-color: #fff; }

/* ---------- contact_cards ---------- */
.block-contact-cards { padding: var(--space-7) 0; background: var(--color-bg-alt); }
.contact-grid { display: grid; grid-template-columns: 0.9fr 1.1fr; gap: var(--space-5); }
.contact-info { background: var(--color-secondary); color: var(--color-on-dark); border-radius: var(--radius-lg); padding: var(--space-5); }
.contact-info h3 { color: #fff; font-size: 1.3rem; }
.contact-info p { color: var(--color-on-dark-soft); }
.contact-list { display: grid; gap: var(--space-3); margin-top: var(--space-4); }
.contact-list li { display: flex; gap: 0.8rem; align-items: flex-start; }
.contact-list svg { width: 20px; height: 20px; color: var(--color-accent); flex: none; margin-top: 0.15rem; }
.contact-list a, .contact-list span { font-size: 0.96rem; color: #fff; }
.social-row { display: flex; gap: 0.6rem; margin-top: var(--space-4); }
.social-row a {
  width: 38px; height: 38px; border-radius: 50%; border: 1px solid rgba(255,255,255,0.3);
  display: flex; align-items: center; justify-content: center; transition: background var(--transition), border-color var(--transition);
}
.social-row a:hover { background: rgba(255,255,255,0.12); border-color: #fff; }
.social-row svg { width: 16px; height: 16px; color: #fff; }

.quote-form { background: var(--color-surface); border-radius: var(--radius-lg); padding: var(--space-5); box-shadow: var(--shadow-md); }
.form-row { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-3); }
.form-group { margin-bottom: var(--space-3); display: flex; flex-direction: column; gap: 0.4rem; }
.form-group label { font-size: 0.85rem; font-weight: 600; color: var(--color-ink); }
.form-group input, .form-group select, .form-group textarea {
  border: 1px solid var(--color-border); border-radius: var(--radius); padding: 0.75rem 0.9rem;
  font-family: var(--font-body); font-size: 0.95rem; background: var(--color-bg); color: var(--color-ink);
  transition: border-color var(--transition), box-shadow var(--transition);
}
.form-group input:focus, .form-group select:focus, .form-group textarea:focus {
  outline: none; border-color: var(--color-primary); box-shadow: 0 0 0 3px rgba(63,107,68,0.15);
}
.form-group.has-error input, .form-group.has-error textarea, .form-group.has-error select { border-color: #B3452F; }
.field-error { font-size: 0.78rem; color: #B3452F; display: none; }
.form-group.has-error .field-error { display: block; }
.form-note { font-size: 0.82rem; color: var(--color-ink-soft); margin-top: var(--space-2); }
.form-success {
  display: none; align-items: center; gap: 0.6rem; background: #EAF2EA; border: 1px solid var(--color-primary);
  color: var(--color-primary-dark); padding: 0.9rem 1.1rem; border-radius: var(--radius); font-size: 0.92rem; margin-bottom: var(--space-3);
}
.form-success.is-visible { display: flex; }
.form-success svg { width: 18px; height: 18px; flex: none; }

@media (max-width: 900px) { .contact-grid { grid-template-columns: 1fr; } }
@media (max-width: 560px) { .form-row { grid-template-columns: 1fr; } }

/* ---------- service_areas_grid ---------- */
.block-service-areas-grid { padding: var(--space-7) 0; }
.areas-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--space-3); }
.area-card {
  border: 1px solid var(--color-border); border-radius: var(--radius); padding: var(--space-3) var(--space-3);
  display: flex; align-items: center; gap: 0.7rem; background: var(--color-surface);
  transition: border-color var(--transition), transform var(--transition);
}
.area-card:hover { border-color: var(--color-primary); transform: translateY(-3px); }
.area-card svg { width: 20px; height: 20px; color: var(--color-primary); flex: none; }
.area-card span { font-weight: 600; font-size: 0.95rem; }
@media (max-width: 900px) { .areas-grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 480px) { .areas-grid { grid-template-columns: 1fr; } }

/* ---------- Footer ---------- */
.site-footer { background: var(--color-ink); color: var(--color-on-dark-soft); padding: var(--space-6) 0 var(--space-3); }
.footer-grid { display: grid; grid-template-columns: 1.4fr 1fr 1fr 1.1fr; gap: var(--space-5); padding-bottom: var(--space-5); border-bottom: 1px solid rgba(255,255,255,0.1); }
.footer-brand .brand { color: #fff; }
.footer-brand p { margin-top: var(--space-2); font-size: 0.92rem; max-width: 32ch; }
.footer-col h4 { color: #fff; font-family: var(--font-body); font-size: 0.82rem; letter-spacing: 0.08em; text-transform: uppercase; margin-bottom: var(--space-2); }
.footer-col ul { display: grid; gap: 0.6rem; }
.footer-col a { font-size: 0.92rem; transition: color var(--transition); }
.footer-col a:hover { color: #fff; }
.footer-bottom { display: flex; flex-wrap: wrap; justify-content: space-between; gap: var(--space-2); padding-top: var(--space-3); font-size: 0.82rem; }
.footer-social { display: flex; gap: 0.6rem; }
.footer-social a { width: 34px; height: 34px; border-radius: 50%; border: 1px solid rgba(255,255,255,0.16); display: flex; align-items: center; justify-content: center; }
.footer-social svg { width: 14px; height: 14px; }

@media (max-width: 900px) { .footer-grid { grid-template-columns: 1fr 1fr; } }
@media (max-width: 560px) { .footer-grid { grid-template-columns: 1fr; } .footer-bottom { flex-direction: column; } }

/* ---------- Generic responsive grid collapses ---------- */
@media (max-width: 900px) {
  .about-grid, .experience-grid, .promise-grid, .contact-grid { grid-template-columns: 1fr; }
  .block-about-checklist.layout-image-right .about-grid,
  .block-experience-sage.layout-image-left .experience-grid { direction: ltr; }
  .experience-media { margin: 0 auto; }
  .block-hero-sage.layout-split .hero-inner { grid-template-columns: 1fr; }
  .hero-visual { max-width: 420px; }
}

/* ==========================================================================
   WordPress / Gutenberg build helpers
   Native core blocks (list, paragraph, group) can't carry the inline SVG
   icons used in the static HTML build, so these rules give the same
   visual result — a checkmark badge, a card icon circle, etc. — using
   CSS alone. Everything else (colors, type, spacing, grid, buttons,
   cards, hover states) is shared with the HTML build via the classes
   already defined above.
   ========================================================================== */
.checklist-native { display: grid; gap: 0.75rem; margin: var(--space-3) 0 var(--space-4); list-style: none; padding-left: 0; }
.checklist-native li { position: relative; padding-left: 1.85rem; font-size: 0.98rem; color: var(--color-ink); }
.checklist-native li::before {
  content: "\2713"; position: absolute; left: 0; top: -1px; width: 20px; height: 20px; border-radius: 50%;
  background: var(--color-primary); color: #fff; font-size: 0.68rem; line-height: 20px; text-align: center;
}
.wp-block-group.service-icon {
  width: 44px; height: 44px; border-radius: 50%; background: var(--color-bg-alt);
  position: relative; margin-bottom: 0.4rem;
}
.wp-block-group.service-icon::before {
  content: "\2766"; position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  color: var(--color-primary); font-size: 1.1rem;
}
.t-meta { font-size: 0.85rem; font-weight: 600; color: var(--color-ink-soft); margin-top: 0.5rem; }
.layout-dark-band .t-meta { color: var(--color-on-dark-soft); }
.area-card .area-name { margin: 0; font-weight: 600; font-size: 0.95rem; }
.contact-list-native { display: grid; gap: var(--space-3); margin-top: var(--space-4); list-style: none; padding: 0; }
.contact-list-native a, .contact-list-native li { color: #fff; font-size: 0.96rem; }
.wp-block-details.faq-item { border: 1px solid var(--color-border); border-radius: var(--radius); background: var(--color-surface); padding: 0; margin: 0 0 0.8rem; }
.wp-block-details.faq-item summary.faq-q { padding: 1.1rem 1.3rem; font-weight: 600; font-size: 0.98rem; cursor: pointer; list-style: none; }
.wp-block-details.faq-item summary.faq-q::-webkit-details-marker { display: none; }
.wp-block-details.faq-item summary.faq-q::after { content: "+"; float: right; font-size: 1.2rem; color: var(--color-primary); }
.wp-block-details.faq-item[open] summary.faq-q::after { content: "\2212"; }
.wp-block-details.faq-item p { padding: 0 1.3rem 1.2rem; margin: 0; color: var(--color-ink-soft); font-size: 0.95rem; }
.hero-phone a, p.hero-phone a { color: #fff; font-weight: 600; }
p.form-note { font-size: 0.9rem; color: var(--color-ink-soft); font-style: italic; }

/* ---------- Print niceties ---------- */
@media print {
  .site-header, .nav-toggle, .block-cta-bottom-sage, .quote-form { display: none !important; }
}
