/*
Theme Name: Northera Design
Theme URI: https://northeradesign.ca/
Description: GeneratePress child theme for Northera Design — custom carpentry and millwork, Vancouver BC.
Author: Agency Dev Team
Version: 1.0.0
Template: generatepress
Text Domain: northera
*/

/* ============================================================================
   SECTION INDEX — grep a marker to jump straight to a block.
   Keep these markers in sync when adding a new component.

     == TOKENS ==        :root custom properties (colors, type, space, radius)
     == BASE ==          resets, html/body, headings, links, forms
     == LAYOUT ==        .page-container, .section and modifiers, .grid
     == COMPONENTS ==    .btn, .card, .badge
     == ANNOUNCE ==      .announce-bar (dismissible strip above header)
     == HEADER ==        .bt-header, .bt-logo, .bt-nav, .bt-header__pill
     == ABOUT ==         .about-story, .team-profile, .about-area (page-about.php)
     == CONTACT ==       .contact-grid, .contact-tile (page-contact.php)
     == PROJECTS ==      .projects, .project-tile (template-parts/project-grid.php)
     == HOMEHEADS ==     .section__header--row, .trust-bar__grid, .step, .cta-band
     == HERO ==          .hero and its media/CTA children
     == TRUST ==         .trust-bar
     == HOME ==          homepage-only sections
     == FAQ ==           .faqs accordion
     == TESTIMONIALS ==  .testimonials carousel, .tcard
     == STICKY ==        .sticky-cta (mobile fixed bottom bar)
     == FOOTER ==        .footer-wrap and children
     == MOBILE ==        max-width: 767px overrides
   ========================================================================== */

/* == TOKENS == */

:root {
  /* Colors */
  --color-primary: #0A398A;
  --color-primary-dark: #082760;

  /* Primary button color (separate from brand so it can be A/B tested
     without recoloring links, header, labels, etc.).
     --color-btn-text is the label color — use #fff on dark buttons,
     a dark value on light buttons (e.g. amber) so text stays legible. */
  --color-btn: #ffb703;
  /* Hover partner for --color-btn. Both are injectable, because a hover shade
     cannot be computed from a hex in CSS and guessing one off-brand is exactly
     what happened here (this was #d99c03, an amber left from the template). */
  --color-btn-dark: #3a3733;
  --color-btn-text: var(--color-text-dark);
  --color-accent: #0fa5e9;
  /* Accent for use ON dark surfaces. One accent value cannot clear 4.5:1 on
     both white and near-black — darkening it for light backgrounds pushes it
     under on dark ones. Keep the pair. */
  --color-accent-on-dark: #7dd3fc;
  --color-text-dark: #082760;
  --color-text: #0f172a;
  --color-footer-bg: #082760;
  --color-footer-bottom-bg: #051a42;
  --color-surface-100: #f8fafc;
  --color-surface-200: #f1f5f9;
  --color-border: #e2e8f0;
  --color-wood: #76513b;
  --color-muted: #64748b;
  --color-white: #ffffff;
  --color-star: #f59e0b;

  /* Typography */
  --font-family-base: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  --font-family-heading: 'Montserrat', 'Inter', sans-serif;
  --text-xs: 0.75rem;
  --text-sm: 0.875rem;
  --text-base: 1rem;
  --text-lg: 1.125rem;
  --text-xl: 1.25rem;
  --text-2xl: 1.5rem;
  --text-3xl: 1.875rem;
  --text-4xl: 2.25rem;
  --text-5xl: 3rem;
  --text-6xl: 3.75rem;
  --text-7xl: 4.5rem;
  --font-normal: 400;
  --font-medium: 500;
  --font-semibold: 600;
  --font-bold: 700;
  --font-extrabold: 800;
  --leading-tight: 1.1;
  --leading-snug: 1.25;
  --leading-normal: 1.5;
  --leading-relaxed: 1.75;

  /* Badge / eyebrow label — shared across all small uppercase labels and pills */
  --badge-font-size: 0.6875rem; /* 11px */
  --badge-tracking: 0.04em;

  /* Spacing */
  --space-xs: 4px;
  --space-sm: 8px;
  --space-md: 16px;
  --space-lg: 24px;
  --space-xl: 32px;
  --space-2xl: 48px;
  --space-3xl: 64px;
  --space-4xl: 96px;
  --space-5xl: 128px;

  /* Border radius */
  --radius-sm: 2px;
  --radius-md: 4px;
  --radius-lg: 8px;
  --radius-xl: 12px;
  --radius-2xl: 16px;
  --radius-3xl: 32px;
  --radius-full: 9999px;

  /* Shadows */
  --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05);
  --shadow-md: 0 4px 6px rgba(0, 0, 0, 0.07);
  --shadow-lg: 0 10px 15px rgba(0, 0, 0, 0.1);
  --shadow-xl: 0 20px 25px rgba(0, 0, 0, 0.1);

  /* Transitions */
  --transition-fast: 150ms ease;
  --transition-base: 200ms ease;
  --transition-slow: 300ms ease;
}

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

/* Mobile overflow guard: clip horizontal overflow at the root without
   creating a scroll container (so position: sticky keeps working).
   `clip` is preferred over `hidden` for exactly this reason. */
html,
body {
  overflow-x: clip;
  max-width: 100%;
}

body {
  font-family: var(--font-family-base);
  color: var(--color-text);
  background: var(--color-surface-100);
  margin: 0;
}

h1, h2, h3, h4, h5, h6 {
  font-family: var(--font-family-heading);
  font-weight: var(--font-bold);
  line-height: var(--leading-tight);
  color: var(--color-text-dark);
  margin: 0 0 var(--space-md);
}

/* ── PAGE TITLE SCALE ──────────────────────────────────────────────────────
   Two tiers for the h1 that names a page, and they must never be the size of
   an h2 — before this, five of eight pages rendered their h1 at --text-4xl,
   the same 36px as every section heading below it, so there was no hierarchy
   between "this page is about X" and "this section is Y".

     landing   .hero__headline           40 → 60px    home, about, contact
     detail    .service-hero__title,     36 → 60px    services, service and
               .section__title--page                  location pages, gallery,
                                                      projects
     section   .section__title           36px         every h2
     card      .step__title, h3          24px

   Both h1 tiers are fluid (clamp) so they hold from 375 to 1440; the section
   and card steps are fixed. Weight 800 and -0.035em tracking across both
   tiers — .service-hero__title used to be 900 with no tracking, which nobody
   chose. */
h1 { font-size: var(--text-4xl); }
h2 { font-size: var(--text-3xl); }
h3 { font-size: var(--text-2xl); }
h4 { font-size: var(--text-xl); }
h5 { font-size: var(--text-lg); font-weight: var(--font-semibold); }
h6 { font-size: var(--text-base); font-weight: var(--font-semibold); }

p {
  margin: 0 0 var(--space-md);
  line-height: var(--leading-normal);
}

a {
  color: var(--color-primary);
  text-decoration: none;
  transition: color var(--transition-fast);
}

a:hover {
  color: var(--color-primary-dark);
}

a:focus-visible,
button:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: 2px;
}

ul, ol {
  margin: 0 0 var(--space-md);
  padding-left: var(--space-xl);
  line-height: var(--leading-normal);
}

li { margin-bottom: var(--space-xs); }

blockquote {
  border-left: 3px solid var(--color-primary);
  margin: var(--space-xl) 0;
  padding: var(--space-md) var(--space-lg);
  background: var(--color-surface-100);
  color: var(--color-muted);
  font-style: italic;
  border-radius: 0 var(--radius-md) var(--radius-md) 0;
}

strong, b { font-weight: var(--font-bold); }
em, i { font-style: italic; }
img { max-width: 100%; height: auto; display: block; }

hr {
  border: none;
  border-top: 1px solid var(--color-border);
  margin: var(--space-xl) 0;
}

.grid-container {
  max-width: 1200px;
}

.inside-article {
  padding: 0;
}

/* GP wraps everything in #page.grid-container at 1200px. Sections need to span
   the viewport so their backgrounds band edge to edge and every .page-container
   inside them resolves to the same width.

   This used to be applied ad hoc — .hero and .services carried their own escape
   and nothing else did, so section content sat at 1320px on some bands and
   1152px on others, on the same page. */
.site-main > .section,
.site-main > .trust-bar {
  width: 100vw;
  margin-left: calc(50% - 50vw);
  margin-right: calc(50% - 50vw);
}

.page-container {
  width: min(1320px, calc(100% - 3rem));
  margin: 0 auto;
}

/* Icons */
.icon {
  display: inline-block;
  vertical-align: middle;
  flex-shrink: 0;
}

/* ── Entry Content (blog posts, inner pages) ── */
.entry-content {
  padding: var(--space-3xl) 0;
}

.entry-content > * + * {
  margin-top: var(--space-md);
}

.entry-content h2 {
  margin-top: var(--space-2xl);
  font-size: var(--text-2xl);
}

.entry-content h3 {
  margin-top: var(--space-xl);
  font-size: var(--text-xl);
}

.entry-content a {
  text-decoration: underline;
}

.entry-content ul,
.entry-content ol {
  padding-left: var(--space-xl);
}

.entry-content img {
  border-radius: var(--radius-lg);
  margin: var(--space-lg) 0;
}

/* GP inner page: entry header above content */
.entry-header {
  padding: var(--space-3xl) 0 var(--space-xl);
  border-bottom: 1px solid var(--color-border);
  margin-bottom: var(--space-xl);
}

.entry-title {
  font-size: var(--text-4xl);
  font-weight: var(--font-extrabold);
  line-height: var(--leading-tight);
  color: var(--color-text-dark);
  margin: 0;
}

.entry-meta {
  font-size: var(--text-sm);
  color: var(--color-muted);
  margin-top: var(--space-sm);
}

.entry-meta a {
  color: var(--color-muted);
  text-decoration: underline;
}

/* ── Announcement bar (accent strip above header) ── */
.announce-bar {
  background: #076ea6;
  color: var(--color-white);
  font-size: var(--text-sm);
  font-weight: var(--font-semibold);
}

.announce-bar__inner {
  width: min(1600px, calc(100% - 3rem));
  margin: 0 auto;
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-sm);
  min-height: 38px;
}

.announce-bar__text {
  margin: 0;
  text-align: center;
}

.announce-bar__close {
  position: absolute;
  right: 0;
  top: 50%;
  transform: translateY(-50%);
  display: inline-flex;
  padding: 6px;
  background: none;
  border: 0;
  color: var(--color-white);
  cursor: pointer;
  line-height: 0;
  opacity: 0.85;
  transition: opacity var(--transition-fast);
}

.announce-bar__close:hover {
  opacity: 1;
}

/* ── Custom site header (white bar: stacked wordmark · nav · dark pill CTA) ──
   GP paints its own background on .site-header via inline styles. The child
   style.css is enqueued a second time as `generate-child` AFTER those inline
   styles (see CLAUDE.md → GP Gotchas 5), which is what lets this declaration
   win. Do not dequeue that duplicate. */
.bt-header {
  background: var(--color-white);
  padding: 0;
  border-bottom: 1px solid var(--color-border);
}

.bt-header__inner {
  width: min(1600px, calc(100% - 3rem));
  margin: 0 auto;
  display: flex;
  align-items: center;
  gap: var(--space-lg);
  min-height: 78px;
  padding: var(--space-sm) 0;
}

/* Logo */
.bt-logo {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  line-height: 1;
  text-decoration: none;
}

.bt-logo__img {
  display: block;
  width: 58px;
  height: 58px;
  object-fit: contain;
}

/* Stacked wordmark: NORTHERA over DESIGN, both letterspaced.
   The accent line is deliberately much smaller and far more widely tracked —
   that contrast is what makes the pair read as a mark rather than two words. */
.bt-logo__word {
  display: inline-flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 3px;
  font-family: var(--font-family-heading);
  line-height: 1;
}

.bt-logo__primary {
  font-size: var(--text-2xl);
  font-weight: var(--font-bold);
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.bt-logo__accent {
  font-size: var(--text-xs);
  font-weight: var(--font-normal);
  letter-spacing: 0.42em;
  text-transform: uppercase;
  /* Trailing tracking pushes the line optically right; pull it back so the
     two lines share a left edge. */
  margin-right: -0.42em;
}

/* GP generates `.site-header a { color: #3a3a3a }`, so the wordmark colour has
   to be scoped under .bt-header to win. */
.bt-header .bt-logo,
.bt-header .bt-logo:hover,
.bt-header .bt-logo:focus,
.bt-header .bt-logo__primary,
.bt-header .bt-logo__accent {
  color: var(--color-text-dark);
}

/* Not a pill any more — a transparent flex row holding nav + CTA.
   The class name is kept because assets/js/header.js and the toggle's
   aria-controls both target it for the mobile dropdown. */
.bt-header__pill {
  flex: 1;
  display: flex;
  align-items: center;
  gap: var(--space-xl);
  padding: 0;
  background: none;
  border-radius: 0;
  box-shadow: none;
}

/* Nav sits centred, CTA is pushed to the right edge by the nav's flex: 1. */
.bt-nav {
  flex: 1;
  display: flex;
  justify-content: center;
}

.bt-nav__menu {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  margin: 0;
  padding: 0;
  list-style: none;
}

.bt-nav__menu li {
  position: relative;
}

/* Scoped under .bt-header so the link colour outranks GP's generated
   `.site-header a { color: #3a3a3a }`. */
.bt-header .bt-nav__menu a,
.bt-nav__menu a,
.bt-nav__parent {
  color: var(--color-text-dark);
  font-size: var(--text-sm);
  font-weight: var(--font-medium);
  text-decoration: none;
  white-space: nowrap;
  padding: var(--space-sm) var(--space-md);
  border-radius: var(--radius-md);
  transition: color var(--transition-fast), background var(--transition-fast);
}

.bt-nav__parent {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  border: 0;
  background: transparent;
  font-family: inherit;
  line-height: inherit;
  cursor: pointer;
}

.bt-nav__menu > li.current-menu-item > a {
  color: var(--color-primary);
}

/* Hover/focus comes last so it wins even on items WP marks as current. */
.bt-nav__menu > li > a:hover,
.bt-nav__menu > li:focus-within > a,
.bt-nav__menu > li > .bt-nav__parent:hover,
.bt-nav__menu > li:focus-within > .bt-nav__parent {
  color: var(--color-accent);
  background: var(--color-surface-100);
}

/* Caret on items that have a submenu */
.bt-nav__menu .menu-item-has-children > a,
.bt-nav__menu .menu-item-has-children > .bt-nav__parent {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

.bt-nav__menu .menu-item-has-children > a::after,
.bt-nav__menu .menu-item-has-children > .bt-nav__parent::after {
  content: "▾";
  font-size: 0.7em;
  line-height: 1;
  color: var(--color-muted);
  transition: transform var(--transition-fast), color var(--transition-fast);
}

.bt-nav__menu .menu-item-has-children:hover > a::after,
.bt-nav__menu .menu-item-has-children:focus-within > a::after,
.bt-nav__menu .menu-item-has-children:hover > .bt-nav__parent::after,
.bt-nav__menu .menu-item-has-children:focus-within > .bt-nav__parent::after {
  transform: rotate(180deg);
  color: var(--color-primary);
}

/* Submenu dropdown */
.bt-nav__menu ul.sub-menu {
  position: absolute;
  top: calc(100% + 12px);
  left: 50%;
  z-index: 50;
  min-width: 230px;
  margin: 0;
  padding: var(--space-sm);
  list-style: none;
  background: var(--color-white);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow-xl);
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transform: translateX(-50%) translateY(6px);
  transition: opacity var(--transition-fast), transform var(--transition-fast), visibility var(--transition-fast);
}

/* Pointer notch */
.bt-nav__menu ul.sub-menu::before {
  content: "";
  position: absolute;
  top: -6px;
  left: 50%;
  width: 12px;
  height: 12px;
  background: var(--color-white);
  border-left: 1px solid var(--color-border);
  border-top: 1px solid var(--color-border);
  transform: translateX(-50%) rotate(45deg);
}

/* Invisible bridge over the 12px gap so the menu stays open while the
   mouse travels from the parent item down to the dropdown. */
.bt-nav__menu ul.sub-menu::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: -16px;
  height: 16px;
}

.bt-nav__menu li:hover > ul.sub-menu,
.bt-nav__menu li:focus-within > ul.sub-menu {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
  transform: translateX(-50%) translateY(0);
}

.bt-nav__menu ul.sub-menu li {
  width: 100%;
}

.bt-nav__menu ul.sub-menu a {
  display: block;
  padding: var(--space-sm) var(--space-md);
  border-radius: var(--radius-md);
  font-size: var(--text-sm);
  font-weight: var(--font-medium);
  color: var(--color-text);
  white-space: nowrap;
  transition: background var(--transition-fast), color var(--transition-fast);
}

.bt-nav__menu ul.sub-menu a:hover,
.bt-nav__menu ul.sub-menu a:focus {
  background: var(--color-surface-100);
  color: var(--color-primary);
}

/* Header CTA. It is .btn.btn--dark.btn--sm now — this rule only supplies what
   the shared component cannot: GP generates `.site-header a { color:#3a3a3a }`,
   which out-specifies .btn--dark, so the colours have to be re-asserted scoped
   under .bt-header. */
.bt-header .bt-header__book,
.bt-header .bt-header__book:hover,
.bt-header .bt-header__book:focus {
  background: var(--color-text-dark);
  color: var(--color-white);
  text-decoration: none;
}

.bt-header .bt-header__book:hover,
.bt-header .bt-header__book:focus {
  background: var(--color-text);
}

/* GP/normalize override an inline SVG's width/height attributes, so the icon
   needs an explicit CSS size or it collapses inside the flex row
   (CLAUDE.md → GP Gotchas 2). */
.bt-header__book-icon {
  width: 1rem;
  height: 1rem;
  flex-shrink: 0;
}

/* Mobile toggle (hidden on desktop). GP paints a dark background on
   button:focus, so :focus is given an explicit background here and
   :focus-visible supplies the keyboard ring (CLAUDE.md → GP Gotchas 1). */
.bt-header__toggle {
  display: none;
  align-items: center;
  justify-content: center;
  padding: 4px;
  background: none;
  border: 0;
  color: var(--color-text-dark);
  cursor: pointer;
}

.bt-header__toggle svg {
  width: 1.625rem;
  height: 1.625rem;
  flex-shrink: 0;
}

/* ── Buttons ──────────────────────────────────────────────────────────
   Fully-rounded pill, medium weight, flat — no hover lift or shadow. Every
   CTA on the site uses .btn + a colour variant + an optional size.

   Previously a 12px-radius bold rectangle with a translateY(-1px) lift. That
   made the header CTA an "exception" that had to re-declare radius-full and
   cancel the lift locally; with the pill as the standard, the exception is
   gone and the header CTA is just .btn.btn--dark. */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-sm);
  padding: 0.85rem var(--space-xl);
  border-radius: var(--radius-full);
  text-decoration: none;
  font-size: var(--text-base);
  font-weight: var(--font-medium);
  white-space: nowrap;
  border: 1px solid transparent;
  cursor: pointer;
  transition: background var(--transition-fast), box-shadow var(--transition-fast),
              transform var(--transition-fast), color var(--transition-fast);
}

@media (max-width: 767px) {
  .btn {
    padding-inline: var(--space-md);
  }
}

.btn:hover {
  box-shadow: none;
}

/* GP paints a dark background on button:focus, so any .btn rendered as a
   <button> needs its own focus ring rather than inheriting that fill. */
.btn:focus-visible {
  outline: 2px solid var(--color-text-dark);
  outline-offset: 2px;
}

/* Color variants */
.btn--primary {
  background: var(--color-btn);
  border-color: var(--color-btn);
  color: var(--color-btn-text);
}

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

/* White card with border + dark text — the hero "Book" / secondary CTA */
.btn--outline {
  background: var(--color-white);
  border-color: var(--color-border);
  color: var(--color-text-dark);
}

.btn--outline:hover {
  background: var(--color-surface-100);
  color: var(--color-text-dark);
}

.btn--dark {
  background: var(--color-text-dark);
  color: var(--color-white);
}

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

/* Size modifiers */
.btn--lg    { padding: 1.05rem var(--space-2xl); font-size: var(--text-base); }
.btn--sm    { padding: 0.6rem var(--space-lg); font-size: var(--text-sm); }
.btn--block {
  width: 100%;
  box-sizing: border-box;
}


/* ── Section Utilities ── */
/* Wrap each homepage section in .section; add modifiers for background variants */
/* Vertical rhythm is deliberate, not uniform.
   Note this is per-side: two stacked .section elements put 2x this between
   their content, which is why the default is one step below the hero's. Going
   straight to --space-4xl here produced 192px gaps that read as dead air. */
.section {
  padding: var(--space-3xl) 0;
}

/* surface-100 is the page background, so using it here painted the band the
   colour it already was — the modifier was a no-op on 19 sections. surface-200
   is the token with contrast against the body. */
.section--surface {
  background: var(--color-surface-200);
}

/* Centered title + optional label + subtitle — use inside any section */
.section__header {
  text-align: center;
  max-width: 640px;
  margin: 0 auto var(--space-2xl);
}

.section__label {
  display: inline-block;
  font-size: var(--badge-font-size);
  font-weight: var(--font-bold);
  text-transform: uppercase;
  letter-spacing: var(--badge-tracking);
  color: var(--color-primary);
  margin-bottom: var(--space-sm);
}

/* Section tier — an h2. A page's own h1 uses .section__title--page instead.
   Fluid for the same reason the h1 tiers are: at a fixed 36px this was LARGER
   than the page title on a 375px screen, inverting the hierarchy. */
.section__title {
  font-size: clamp(1.75rem, 4.5vw, var(--text-4xl));
  font-weight: var(--font-extrabold);
  line-height: var(--leading-tight);
  color: var(--color-text-dark);
  margin: 0 0 var(--space-md);
}

.section__subtitle {
  font-size: var(--text-lg);
  color: var(--color-muted);
  line-height: var(--leading-relaxed);
  margin: 0;
}

/* ── Grid Utilities ── */
.grid {
  display: grid;
  gap: var(--space-lg);
}

.grid--2 { grid-template-columns: repeat(2, 1fr); }
.grid--3 { grid-template-columns: repeat(3, 1fr); }
.grid--4 { grid-template-columns: repeat(4, 1fr); }

/* The fixed grids never had a collapse rule, despite being documented as
   "fixed, collapse mobile" — .grid--4 held four columns all the way down and
   overflowed the viewport. Anything using them inherits this. */
@media (max-width: 900px) {
  .grid--3,
  .grid--4 { grid-template-columns: repeat(2, 1fr); }
}

@media (max-width: 767px) {
  .grid--2,
  .grid--3,
  .grid--4 { grid-template-columns: 1fr; }
}

/* Left-aligned heading with an aside on the right — the comp's pattern for
   Our Services, Featured Projects, Our Process, and Testimonials.
   A modifier on .section__header rather than a parallel component: this was
   built three separate times (section__head-row / projects__head /
   testimonials__head) before being folded back into one. */
.section__header--stack {
  text-align: left;
  max-width: none;
  margin-bottom: var(--space-2xl);
}

.section__header--stack .section__title,
.section__header--stack .section__label {
  text-align: left;
  margin: 0;
}

.section__header--stack .section__title {
  margin-top: var(--space-sm);
}

.section__header--row {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--space-2xl);
  text-align: left;
  margin-bottom: var(--space-xl);
  max-width: none;
}

.section__header--row .section__title {
  text-align: left;
  margin: 0;
}

.section__header--row .section__label {
  display: block;
  text-align: left;
}

/* The aside: either a link or a short intro paragraph. */
.section__header--row .section__subtitle {
  max-width: 34ch;
  margin: 0;
  text-align: left;
}

.section__head-link {
  display: inline-flex;
  align-items: center;
  gap: var(--space-xs);
  flex-shrink: 0;
  font-size: var(--text-sm);
  font-weight: var(--font-medium);
  color: var(--color-muted);
  text-decoration: none;
  transition: color var(--transition-fast);
}

.section__head-link:hover,
.section__head-link:focus {
  color: var(--color-text-dark);
}

/* GP/normalize override the SVG's width/height attributes. */
.section__head-link-icon {
  width: 0.9rem;
  height: 0.9rem;
  flex-shrink: 0;
}

@media (max-width: 767px) {
  .section__header--row {
    flex-direction: column;
    align-items: flex-start;
    gap: var(--space-sm);
  }

  .section__header--row .section__subtitle {
    max-width: none;
  }
}

/* ── Card Component ── */
.card {
  background: var(--color-white);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-md);
  padding: var(--space-lg);
  display: flex;
  flex-direction: column;
  transition: box-shadow var(--transition-base);
}

.card:hover {
  box-shadow: var(--shadow-lg);
}

.card--bordered {
  box-shadow: none;
  border: 1px solid var(--color-border);
}

.card--bordered:hover {
  box-shadow: var(--shadow-md);
}

/* Image-topped card: photo fills the top, a single title row sits beneath it.
   Used for the homepage services row and the /services/ grid. The whole card
   is an <a>, so the padding lives on .card__media-foot rather than on .card —
   otherwise the image cannot reach the card's edges. */
.card--media {
  padding: 0;
  overflow: hidden;
  text-decoration: none;
}

.card__media {
  display: block;
  aspect-ratio: 5 / 4;
  overflow: hidden;
  background: var(--color-surface-100);
}

.card__media img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform var(--transition-slow);
}

.card--media:hover .card__media img {
  transform: scale(1.04);
}

/* Fallback when no photograph exists yet: the icon sits centred in the media
   box instead of rendering an empty grey panel. */
.card__media-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  color: var(--color-muted);
}

.card__media-icon svg {
  width: 1.75rem;
  height: 1.75rem;
  flex-shrink: 0;
  opacity: 0.65;
}

.card__media-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-sm);
  padding: var(--space-md) var(--space-md);
}

/* Scoped so the title colour survives GP's global link colour when the card
   itself is an anchor. */
.card--media .card__media-title,
a.card--media:hover .card__media-title,
a.card--media:focus .card__media-title {
  font-size: var(--text-sm);
  font-weight: var(--font-medium);
  color: var(--color-text-dark);
  margin: 0;
  line-height: var(--leading-snug);
}

.card__media-arrow {
  flex-shrink: 0;
  width: 1rem;
  height: 1rem;
  color: var(--color-muted);
  transition: transform var(--transition-fast), color var(--transition-fast);
}

.card--media:hover .card__media-arrow {
  color: var(--color-text-dark);
  transform: translateX(3px);
}

a.card--media:focus-visible {
  outline: 2px solid var(--color-text-dark);
  outline-offset: 2px;
}

.card__icon {
  color: var(--color-primary);
  margin-bottom: var(--space-md);
}

/* .card is display:flex/column, so a .badge child stretches edge to edge on
   the cross axis. Every badge used inside a card needs to opt out. */
.card > .badge {
  align-self: flex-start;
  margin-bottom: var(--space-sm);
}

.card__title {
  font-size: var(--text-xl);
  font-weight: var(--font-bold);
  color: var(--color-text-dark);
  margin: 0 0 var(--space-sm);
  line-height: var(--leading-snug);
}

.card__body {
  font-size: var(--text-base);
  color: var(--color-muted);
  line-height: var(--leading-relaxed);
  flex: 1;
  margin: 0;
}

.card__link {
  display: inline-flex;
  align-items: center;
  gap: var(--space-xs);
  margin-top: var(--space-md);
  font-size: var(--text-sm);
  font-weight: var(--font-semibold);
  color: var(--color-primary);
}

.card__link:hover {
  color: var(--color-primary-dark);
}

/* ── Badge / Pill ── */
.badge {
  display: inline-flex;
  align-items: center;
  gap: var(--space-xs);
  padding: 4px var(--space-sm);
  border-radius: var(--radius-full);
  font-size: var(--badge-font-size);
  font-weight: var(--font-semibold);
  letter-spacing: var(--badge-tracking);
  line-height: 1;
  white-space: nowrap;
}

.badge--surface {
  background: var(--color-surface-200);
  color: var(--color-text-dark);
}

/* Pagination */
.pagination {
  display: flex;
  gap: var(--space-sm);
  justify-content: center;
  flex-wrap: wrap;
  margin-top: var(--space-2xl);
}

.page-numbers {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 36px;
  height: 36px;
  padding: 0 var(--space-sm);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  text-decoration: none;
  color: var(--color-text-dark);
  font-size: var(--text-sm);
  font-weight: var(--font-medium);
  transition: all var(--transition-fast);
}

.page-numbers.current,
.page-numbers:hover {
  background: var(--color-primary);
  border-color: var(--color-primary);
  color: var(--color-white);
}

/* ── Forms ── */
input[type="text"],
input[type="email"],
input[type="tel"],
input[type="url"],
input[type="number"],
input[type="password"],
input[type="search"],
input[type="date"],
textarea,
select {
  width: 100%;
  padding: 10px 14px;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  font-family: var(--font-family-base);
  font-size: var(--text-base);
  color: var(--color-text);
  background: var(--color-white);
  transition: border-color var(--transition-fast), box-shadow var(--transition-fast);
  line-height: var(--leading-normal);
}

input:focus,
textarea:focus,
select:focus {
  outline: none;
  border-color: var(--color-primary);
  box-shadow: 0 0 0 3px rgba(28, 27, 25, 0.14);
}

textarea {
  resize: vertical;
  min-height: 120px;
}

label {
  display: block;
  font-size: var(--text-sm);
  font-weight: var(--font-semibold);
  color: var(--color-text-dark);
  margin-bottom: var(--space-xs);
}

/* Fluent Form overrides — keeps forms on-brand without touching plugin styles */
.ff-el-group { margin-bottom: var(--space-md); }

.ff-el-input--label label {
  font-size: var(--text-sm);
  font-weight: var(--font-semibold);
  color: var(--color-text-dark);
  margin-bottom: var(--space-xs);
}

.ff-el-form-control {
  border: 1px solid var(--color-border) !important;
  border-radius: var(--radius-md) !important;
  font-family: var(--font-family-base) !important;
  font-size: var(--text-base) !important;
  color: var(--color-text) !important;
  padding: 10px 14px !important;
  transition: border-color var(--transition-fast), box-shadow var(--transition-fast) !important;
}

.ff-el-form-control:focus {
  border-color: var(--color-primary) !important;
  box-shadow: 0 0 0 3px rgba(28, 27, 25, 0.14) !important;
  outline: none !important;
}

.ff_submit_btn_container .ff-btn-submit {
  background: var(--color-primary) !important;
  border-color: var(--color-primary) !important;
  font-family: var(--font-family-base) !important;
  font-weight: var(--font-bold) !important;
  font-size: var(--text-base) !important;
  border-radius: var(--radius-md) !important;
  padding: 10px var(--space-xl) !important;
  transition: background var(--transition-fast) !important;
}

.ff_submit_btn_container .ff-btn-submit:hover {
  background: var(--color-primary-dark) !important;
  border-color: var(--color-primary-dark) !important;
}

/* ── Footer — light five-column layout ──
   brand · link columns (config/site.php) · contact · location + social.
   Every column self-guards in custom-footer.php, so a business missing hours
   or social accounts renders fewer columns rather than empty headings. */
.footer-main {
  background: var(--color-surface-100);
  color: var(--color-text);
  border-top: 1px solid var(--color-border);
  padding: var(--space-2xl) 0;
}

/* Not five equal columns: they hold very different amounts. Company needs ~80px
   for its longest link while Contact needs 175 for "Monday-Friday: 8am-5pm",
   and the icon beside it takes 25 of those — so at an equal 1fr the hours split
   across two lines mid-range. Widths measured against the longest string each
   column actually has to hold. */
.footer-cols {
  display: grid;
  grid-template-columns: 1.5fr 1fr 0.85fr 1.25fr 1.1fr;
  gap: 0;
  align-items: start;
}

/* Hairline rules between columns. Applied as border-left on every column after
   the first so the count adapts when a column self-hides — a fixed set of
   separator elements would leave a stray rule behind. */
.footer-col {
  min-width: 0;
  padding: 0 var(--space-xl);
  border-left: 1px solid var(--color-border);
}

.footer-col--brand {
  padding-left: 0;
  border-left: 0;
}

.footer-col__blurb {
  margin: var(--space-lg) 0 0;
  font-size: var(--text-sm);
  /* --color-text, not --color-muted: muted grey on this surface measures
     under 4.5:1. Do not swap it back. */
  color: var(--color-text);
  line-height: var(--leading-relaxed);
  max-width: 30ch;
}

.footer-col__heading {
  margin: 0 0 var(--space-md);
  font-size: var(--text-sm);
  font-weight: var(--font-semibold);
  color: var(--color-text-dark);
  letter-spacing: 0;
}

.footer-col__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: var(--space-sm);
}

.footer-col__list li {
  margin: 0;
}

/* Scoped under .footer-wrap so GP's generated global link colour cannot
   override these. */
.footer-wrap .footer-col__list a {
  font-size: var(--text-sm);
  color: var(--color-text);
  text-decoration: none;
  transition: color var(--transition-fast);
}

.footer-wrap .footer-col__list a:hover,
.footer-wrap .footer-col__list a:focus {
  color: var(--color-text-dark);
  text-decoration: underline;
}

/* ── Icon rows (Contact / Location) ── */
.footer-col__list--icons {
  gap: var(--space-md);
}

.footer-item {
  display: flex;
  align-items: flex-start;
  gap: var(--space-sm);
}

/* GP/normalize override an inline SVG's width/height attributes, so every
   footer icon needs an explicit CSS size or it collapses in the flex row. */
.footer-item__icon {
  width: 1.05rem;
  height: 1.05rem;
  flex-shrink: 0;
  margin-top: 2px;
  color: var(--color-text-dark);
}

.footer-item__text {
  display: block;
  font-size: var(--text-sm);
  line-height: var(--leading-snug);
}

.footer-item__line {
  display: block;
}

.footer-item__line + .footer-item__line {
  margin-top: 2px;
}

/* ── Social ── */
.footer-social-row {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-sm);
  list-style: none;
  margin: var(--space-lg) 0 0;
  padding: 0;
}

.footer-social {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.5rem;
  height: 2.5rem;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-full);
  background: var(--color-white);
  transition: border-color var(--transition-fast);
}

.footer-wrap .footer-social,
.footer-wrap .footer-social:hover,
.footer-wrap .footer-social:focus {
  color: var(--color-text-dark);
  text-decoration: none;
}

.footer-social:hover,
.footer-social:focus {
  border-color: var(--color-text-dark);
}

.footer-social:focus-visible {
  outline: 2px solid var(--color-text-dark);
  outline-offset: 2px;
}

.footer-social__icon {
  width: 1.1rem;
  height: 1.1rem;
  flex-shrink: 0;
}

.footer-social__initial {
  font-size: var(--text-sm);
  font-weight: var(--font-semibold);
  line-height: 1;
}

/* Five columns need more room than .page-container's 1200px allows before the
   link lists start wrapping mid-word. */
@media (max-width: 1100px) {
  .footer-cols {
    grid-template-columns: 1.4fr repeat(2, 1fr);
    row-gap: var(--space-2xl);
  }

  /* With three per row, the divider belongs on columns 2 and 3 only. */
  .footer-col:nth-child(3n + 1) {
    padding-left: 0;
    border-left: 0;
  }
}

@media (max-width: 767px) {
  .footer-cols {
    grid-template-columns: 1fr;
    row-gap: var(--space-xl);
  }

  .footer-col {
    padding: 0;
    border-left: 0;
  }
}

.footer-bottom {
  background: var(--color-white);
  color: var(--color-text);
  border-top: 1px solid var(--color-border);
  padding: var(--space-md) 0;
}

.footer-bottom__inner {
  display: flex;
  flex-direction: column;
  gap: 10px;
  align-items: center;
  text-align: center;
}

.footer-bottom__copy {
  margin: 0;
  font-size: var(--text-xs);
  color: var(--color-text);
}

.footer-bottom__badges {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}

.footer-bottom__badges span {
  background: var(--color-surface-100);
  border: 1px solid var(--color-border);
  color: var(--color-text-dark);
  border-radius: var(--radius-full);
  font-size: var(--text-xs);
  padding: 6px 10px;
}

.footer-bottom__legal {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--space-sm) var(--space-md);
}

.footer-wrap .footer-bottom__legal a {
  color: var(--color-text);
  font-size: var(--text-xs);
  text-decoration: none;
}

.footer-wrap .footer-bottom__legal a:hover,
.footer-wrap .footer-bottom__legal a:focus {
  color: var(--color-text-dark);
  text-decoration: underline;
}

/* Legal pages (Privacy Policy, Terms of Service) */
.legal__inner {
  max-width: 820px;
}

.legal__body h1 {
  margin-bottom: var(--space-xs);
}

.legal__updated {
  color: var(--color-muted);
  font-size: var(--text-sm);
  margin-bottom: var(--space-xl);
}

.legal__body h2 {
  margin-top: var(--space-2xl);
  font-size: var(--text-xl);
}

.legal__body p,
.legal__body li {
  line-height: var(--leading-relaxed);
}

/* 404 */
.error-404 {
  text-align: center;
  padding: var(--space-4xl) 0;
}

.error-404__title {
  font-size: var(--text-4xl);
  font-weight: var(--font-extrabold);
  margin: 0 0 var(--space-md);
  color: var(--color-text);
}

.error-404__message {
  font-size: var(--text-lg);
  color: var(--color-muted);
  margin: 0 0 var(--space-xl);
  max-width: 480px;
  margin-left: auto;
  margin-right: auto;
}

.error-404__search {
  max-width: 400px;
  margin: 0 auto var(--space-lg);
}

.error-404__search .search-form {
  display: flex;
  gap: var(--space-sm);
}

.error-404__search .search-field {
  flex: 1;
  padding: 10px 14px;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  font-size: var(--text-base);
}

.error-404__search .search-submit {
  padding: 10px 18px;
  background: var(--color-primary);
  color: #fff;
  border: 0;
  border-radius: var(--radius-md);
  font-weight: var(--font-bold);
  font-size: var(--text-sm);
  cursor: pointer;
}

.error-404__search .search-submit:hover {
  background: var(--color-primary-dark);
}

.error-404__home {
  display: inline-block;
}

/* Sticky CTA — fixed mobile bar with two equal standard buttons.
   Hidden at page top; header.js reveals it after a fixed scroll threshold. */
.sticky-cta {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 999;
  display: none;
  width: 100%;
  max-width: 100vw;
  box-sizing: border-box;
  overflow: hidden;
  background: var(--color-white);
  border-top: 1px solid var(--color-border);
  box-shadow: 0 -4px 12px rgba(0, 0, 0, 0.08);
  padding: 6px max(8px, env(safe-area-inset-right)) 6px max(8px, env(safe-area-inset-left));
  padding-bottom: calc(6px + env(safe-area-inset-bottom));
  transform: translateY(100%);
  visibility: hidden;
  transition: transform var(--transition-base), visibility var(--transition-base);
}

.sticky-cta.is-visible {
  transform: translateY(0);
  visibility: visible;
}

.sticky-cta__inner {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-sm);
  width: 100%;
  max-width: 520px;
  margin: 0 auto;
}

/* Each button fills half the bar; the lift on a fixed bar is dropped. */
.sticky-cta__btn {
  width: 100%;
  box-sizing: border-box;
  min-width: 0;
  min-height: 46px;
  padding: 7px 8px;
  gap: 8px;
  border-radius: var(--radius-lg);
  overflow: hidden;
}

.sticky-cta__btn .icon {
  width: 18px;
  height: 18px;
  flex: 0 0 18px;
}

.sticky-cta__btn:hover,
.sticky-cta__btn:focus {
  transform: none;
}

.sticky-cta__btn:active {
  transform: scale(0.985);
  box-shadow: none;
}

.sticky-cta__label {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  line-height: 1.15;
  min-width: 0;
  max-width: 100%;
  overflow: hidden;
}

.sticky-cta__title {
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: var(--text-sm);
  font-weight: var(--font-bold);
}

.sticky-cta__sub {
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 11px;
  font-weight: var(--font-semibold);
  opacity: 0.85;
}

@media (max-width: 360px) {
  .sticky-cta {
    padding-left: max(6px, env(safe-area-inset-left));
    padding-right: max(6px, env(safe-area-inset-right));
  }

  .sticky-cta__inner {
    gap: 6px;
  }

  .sticky-cta__btn {
    min-height: 44px;
    padding: 6px;
    gap: 6px;
  }

  .sticky-cta__title {
    font-size: 12px;
  }

  .sticky-cta__sub {
    font-size: 10px;
  }
}

@media (min-width: 768px) {
  .footer-bottom__inner {
    flex-direction: row;
    justify-content: space-between;
    text-align: left;
  }
}

@media (max-width: 767px) {
  body {
    padding-bottom: calc(62px + env(safe-area-inset-bottom));
  }

  /* Hero photo returns to the flow and stacks above the copy; the horizontal
     fade only reads against a left/right split, so it is switched off. */
  .hero__media {
    position: static;
    width: 100%;
    aspect-ratio: 4 / 3;
    border-radius: var(--radius-2xl);
    margin-bottom: var(--space-xl);
  }

  .hero__media::after {
    display: none;
  }

  .hero__text {
    max-width: none;
  }

  .sticky-cta {
    display: block;
  }

  /* Header collapses: logo + phone + hamburger on one row; pill becomes a dropdown */
  .bt-header__inner {
    flex-wrap: wrap;
    width: min(100% - 1.25rem, 1600px);
    column-gap: var(--space-sm);
    row-gap: 0;
    min-height: 64px;
    padding: 10px 0;
  }

  .bt-logo__img {
    width: 52px;
    height: 52px;
  }

  .bt-logo__primary {
    font-size: var(--text-xl);
  }

  /* The header is white now, so the toggle's affordance comes from a light
     surface rather than a translucent white. GP fills button:focus with a dark
     background, hence the explicit :focus background below. */
  .bt-header__toggle {
    display: inline-flex;
    order: 3;
    margin-left: auto;
    width: 42px;
    height: 42px;
    border-radius: var(--radius-lg);
    background: var(--color-surface-100);
  }

  .bt-header__toggle:hover,
  .bt-header__toggle:focus,
  .bt-header__toggle[aria-expanded="true"] {
    background: var(--color-surface-200);
    color: var(--color-text-dark);
  }

  .bt-header__toggle:focus-visible {
    outline: 2px solid var(--color-text-dark);
    outline-offset: -2px;
  }

  .bt-header__pill {
    order: 5;
    flex-basis: 100%;
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    margin-top: 10px;
    padding: 10px 14px;
    background: var(--color-white);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-lg);
    display: none;
  }

  /* The CTA stays visible in the mobile dropdown — it is the primary
     conversion path now that the header carries no phone number. */
  .bt-header__pill .bt-header__book {
    order: 2;
    justify-content: center;
    margin-top: 10px;
  }

  .bt-header--open .bt-header__pill {
    display: flex;
  }

  .bt-nav {
    justify-content: flex-start;
  }

  .bt-nav__menu {
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    width: 100%;
  }

  .bt-nav__menu a,
  .bt-nav__parent {
    display: block;
    width: 100%;
    padding: 12px 0;
    border-bottom: 1px solid var(--color-border);
    border-radius: 0;
    white-space: normal;
    text-align: left;
  }

  .bt-nav__menu .menu-item-has-children > a,
  .bt-nav__menu .menu-item-has-children > .bt-nav__parent {
    display: flex;
    justify-content: space-between;
    width: 100%;
  }

  .bt-nav__menu ul.sub-menu {
    position: static;
    transform: none;
    opacity: 1;
    visibility: visible;
    pointer-events: auto;
    min-width: 0;
    margin: 0;
    padding: 3px 0 8px var(--space-md);
    border: 0;
    border-radius: 0;
    box-shadow: none;
    background: transparent;
  }

  .bt-nav__accordion-item > ul.sub-menu {
    display: none;
  }

  .bt-nav__accordion-item.bt-nav__item--open > ul.sub-menu {
    display: block;
  }

  .bt-nav__accordion-item.bt-nav__item--open > .bt-nav__parent::after {
    transform: rotate(180deg);
    color: var(--color-primary);
  }

  .bt-nav__menu li:hover > ul.sub-menu,
  .bt-nav__menu li:focus-within > ul.sub-menu {
    transform: none;
  }

  .bt-nav__menu ul.sub-menu::before,
  .bt-nav__menu ul.sub-menu::after {
    display: none;
  }

  .bt-nav__menu ul.sub-menu a {
    padding: 8px 0;
    border-bottom: 0;
    color: var(--color-text);
    font-size: var(--text-sm);
  }

  .bt-nav__menu > li:last-child > a,
  .bt-nav__menu > li:last-child > .bt-nav__parent {
    border-bottom: 0;
  }

  .bt-header__book {
    width: 100%;
    justify-content: center;
  }
}

/* .bt-logo__word is a flex column now, so the size has to be set on the two
   lines individually rather than inherited from the wrapper. */
@media (max-width: 420px) {
  .bt-logo__primary {
    font-size: var(--text-lg);
    letter-spacing: 0.12em;
  }

  .bt-logo__accent {
    letter-spacing: 0.34em;
    margin-right: -0.34em;
  }
}

@media (max-width: 360px) {
  .bt-logo__img {
    width: 46px;
    height: 46px;
  }

  .bt-logo__primary {
    font-size: var(--text-base);
    letter-spacing: 0.1em;
  }

  .bt-logo__accent {
    font-size: 0.625rem;
    letter-spacing: 0.28em;
    margin-right: -0.28em;
  }
}


/* ══════════════════════════════════════════════════════════════════════
   HOME SECTION HEADS / TRUST GRID / PROCESS STEPS / CTA BAND
   ══════════════════════════════════════════════════════════════════════ */

/* Left-aligned section head with a link on the right — the mockup's pattern
   for Our Services, Featured Projects, and Our Process. */
/* GP/normalize override an inline SVG's width/height attributes, so these
   need an explicit CSS size or they collapse inside the flex row. */
/* ── Trust strip: four value props across ── */
.trust-bar__grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--space-xl);
  padding: var(--space-2xl) 0;
  border-top: 1px solid var(--color-border);
  border-bottom: 1px solid var(--color-border);
}

.trust-bar__cell {
  display: flex;
  align-items: flex-start;
  gap: var(--space-md);
}

.trust-bar__cell-icon {
  flex-shrink: 0;
  color: var(--color-text-dark);
}

.trust-bar__cell-icon svg {
  width: 1.5rem;
  height: 1.5rem;
  flex-shrink: 0;
}

.trust-bar__cell-text {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
}

.trust-bar__cell-title {
  font-size: var(--text-sm);
  font-weight: var(--font-semibold);
  color: var(--color-text-dark);
  line-height: var(--leading-snug);
}

/* --color-text, not --color-muted: this strip sits on white and muted grey
   measures under 4.5:1 at this size. Do not swap it back. */
.trust-bar__cell-copy {
  font-size: var(--text-xs);
  color: var(--color-text);
  line-height: var(--leading-relaxed);
}

/* ── Process steps ──
   Previously a raised white card on a surface section. The card is gone: its
   background is now simply the section's, so the steps run the full content
   width with hairlines between them and no inner frame. */
.process-steps {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
}

/* Rules between steps only — never before the first, and the count adapts if
   the step list ever changes length. */
.process-steps .step + .step {
  border-left: 1px solid var(--color-border);
}

.step {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-md);
  padding: 0 var(--space-xl);
}

.process-steps .step:first-child {
  padding-left: 0;
}

.process-steps .step:last-child {
  padding-right: 0;
}

.step__num {
  font-size: var(--text-sm);
  font-weight: var(--font-normal);
  color: var(--color-muted);
  letter-spacing: 0.02em;
}

/* Bare icon, not a chip. GP/normalize override the SVG's width/height
   attributes, so the size has to be set in CSS. */
.step__icon {
  display: inline-flex;
  color: var(--color-text-dark);
}

.step__icon svg {
  width: 2.75rem;
  height: 2.75rem;
  flex-shrink: 0;
  stroke-width: 1.25;
}

/* Drawn artwork rather than a glyph, so it runs larger than the 2.75rem SVG it
   replaces. Sized by rendering the row at 52/64/76px: at 52 the interior detail
   closes up, at 76 it competes with the step title. object-fit keeps each
   drawing's own proportions inside the square box. */
.step__icon-img {
  width: 4rem;
  height: 4rem;
  flex-shrink: 0;
  object-fit: contain;
}

.step__title {
  font-size: var(--text-2xl);
  font-weight: var(--font-medium);
  color: var(--color-text-dark);
  margin: var(--space-xs) 0 0;
  line-height: var(--leading-snug);
}

.step__copy {
  font-size: var(--text-base);
  color: var(--color-text);
  line-height: var(--leading-relaxed);
  margin: 0;
  max-width: 24ch;
}

@media (max-width: 900px) {
  .process-steps {
    grid-template-columns: repeat(2, 1fr);
    row-gap: var(--space-2xl);
  }

  /* With two per row the divider belongs on the second column only. */
  .process-steps .step:nth-child(odd) {
    padding-left: 0;
    border-left: 0;
  }

  .process-steps .step:nth-child(even) {
    padding-right: 0;
  }
}

@media (max-width: 600px) {
  .process-steps {
    grid-template-columns: 1fr;
    row-gap: var(--space-xl);
  }

  .process-steps .step {
    padding: 0;
    border-left: 0;
  }
}

/* ── Closing CTA band ──
   Two layouts from one component. With a photo (.cta-band--media) it splits
   into text | image; without one it stays a single full-width row. The
   fallback is a finished design, not a degraded version of the other. */
.cta-band {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: var(--space-xl);
  padding: var(--space-2xl);
  background: var(--color-surface-100);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-2xl);
}

.cta-band__body {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: var(--space-xl);
  flex: 1;
  min-width: 0;
}

.cta-band__title {
  font-size: var(--text-4xl);
  font-weight: var(--font-bold);
  color: var(--color-text-dark);
  margin: 0 0 var(--space-xs);
  line-height: var(--leading-tight);
}

.cta-band__copy {
  font-size: var(--text-base);
  color: var(--color-text);
  margin: 0;
}

.cta-band__actions {
  display: flex;
  align-items: center;
  gap: var(--space-lg);
  flex-shrink: 0;
}

.cta-band__phone {
  display: inline-flex;
  align-items: center;
  gap: var(--space-xs);
  font-size: var(--text-sm);
  font-weight: var(--font-medium);
  color: var(--color-text-dark);
  text-decoration: none;
}

.cta-band__phone-icon {
  width: 1rem;
  height: 1rem;
  flex-shrink: 0;
}

/* ── With a photograph ──
   Built to the comp rather than assembled from existing parts: the photo fills
   the whole card and a light panel sits on top of it, its right edge a large
   convex arc sweeping into the image. An earlier version split the card at 52%
   with a linear-gradient fade, which is a different (and flatter) thing. */
.cta-band--media {
  position: relative;
  display: flex;
  align-items: stretch;
  gap: 0;
  padding: 0;
  border: 0;
  border-radius: var(--radius-3xl);
  overflow: hidden;
  background: var(--color-white);
  box-shadow: var(--shadow-sm);
  min-height: 26rem;
}

/* Fills the entire card and sits behind the panel — not a column beside it. */
.cta-band__media {
  position: absolute;
  inset: 0;
  overflow: hidden;
}

.cta-band__media img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.cta-band--media .cta-band__body {
  position: relative;
  z-index: 1;
  flex: 0 0 auto;
  width: 62%;
  flex-direction: column;
  align-items: flex-start;
  justify-content: center;
  gap: var(--space-xl);
  /* The panel fades into the photograph along a straight vertical edge — the
     comp is a soft horizontal gradient, not a shaped edge. An earlier version
     used an elliptical border-radius here, which was a misread of the design.
     The fade is carried by the panel's own background so no overlay element is
     needed, and the transparent stop must be rgba white rather than
     `transparent`, which some engines interpolate through black. */
  background: linear-gradient(
    to right,
    var(--color-white) 0%,
    var(--color-white) 58%,
    rgba(255, 255, 255, 0.92) 76%,
    rgba(255, 255, 255, 0) 100%
  );
  padding: var(--space-3xl) var(--space-4xl) var(--space-3xl) var(--space-2xl);
}

.cta-band--media .cta-band__title {
  font-size: clamp(1.75rem, 2.6vw, var(--text-5xl));
  line-height: 1.06;
  letter-spacing: -0.03em;
  max-width: 16ch;
}

.cta-band--media .cta-band__copy {
  font-size: var(--text-lg);
}

.cta-band--media .cta-band__actions {
  flex-wrap: wrap;
}

@media (max-width: 900px) {
  .trust-bar__grid {
    grid-template-columns: repeat(2, 1fr);
    gap: var(--space-lg);
  }
}

@media (max-width: 767px) {
    .trust-bar__grid {
    grid-template-columns: 1fr;
  }

  .cta-band {
    padding: var(--space-xl);
  }

  .cta-band--media {
    flex-direction: column;
    padding: 0;
  }

  .cta-band--media .cta-band__body {
    flex-basis: auto;
    width: 100%;
    padding: var(--space-xl);
  }

  .cta-band__media {
    position: static;
    width: 100%;
    aspect-ratio: 16 / 10;
    order: -1;
  }

  .cta-band__actions {
    width: 100%;
    flex-direction: column;
    align-items: stretch;
  }
}

/* ══════════════════════════════════════════════════════════════════════
   ABOUT  —  page-about.php
   ══════════════════════════════════════════════════════════════════════ */

.about-story {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-2xl);
}

.about-story__body p {
  margin: 0 0 var(--space-lg);
  font-size: var(--text-lg);
  color: var(--color-text);
  line-height: var(--leading-relaxed);
  max-width: 62ch;
}

.about-story__body p:last-child {
  margin-bottom: 0;
}

.about-story__aside {
  align-self: start;
  padding: var(--space-xl);
  background: var(--color-surface-100);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-2xl);
}

.about-story__aside-title {
  margin: 0 0 var(--space-md);
  font-size: var(--text-sm);
  font-weight: var(--font-semibold);
  color: var(--color-text-dark);
}

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

.about-story__list li + li {
  border-top: 1px solid var(--color-border);
}

/* Scoped so GP's global link colour cannot recolour these. */
.about-story__list a,
.about-story__list a:hover,
.about-story__list a:focus {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-sm);
  padding: var(--space-sm) 0;
  font-size: var(--text-base);
  color: var(--color-text-dark);
  text-decoration: none;
}

.about-story__list a:hover {
  text-decoration: underline;
}

/* The service's own line icon, leading the row. 2rem, not the 0.9rem of the
   trailing arrow: these are drawings rather than UI glyphs, and below ~28px
   the detail closes up. Sized by rendering the row at 24/32/40 — 24 loses the
   drawing, 40 overpowers the 16px label. object-fit keeps the artwork's own
   proportions inside the square box (the table is landscape where the
   cabinets are portrait). */
.about-story__list-svc {
  width: 2rem;
  height: 2rem;
  flex-shrink: 0;
  object-fit: contain;
}

/* Takes the free space so the trailing arrow stays pinned right once a leading
   icon is in the row — `justify-content: space-between` alone would centre the
   name between the two icons. */
.about-story__list-name {
  flex: 1;
}

/* GP/normalize override the SVG's width/height attributes. */
.about-story__list-icon {
  width: 0.9rem;
  height: 0.9rem;
  flex-shrink: 0;
  color: var(--color-muted);
}

.team-featured {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-2xl);
}

.team-profile__media {
  display: block;
  width: 100%;
  aspect-ratio: 4 / 3;
  overflow: hidden;
  border: 0.375rem solid var(--color-wood);
  border-radius: var(--radius-2xl);
  background: var(--color-surface-200);
}

.team-profile__media img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.team-profile__initials {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  font-family: var(--font-family-heading);
  font-size: var(--text-3xl);
  font-weight: var(--font-medium);
  color: var(--color-muted);
}

.team-profile__body {
  padding-top: var(--space-lg);
}

.team-profile__name {
  margin: 0;
  font-size: var(--text-lg);
  font-weight: var(--font-semibold);
  color: var(--color-text-dark);
  line-height: var(--leading-snug);
}

.team-profile__role {
  margin: var(--space-xs) 0 0;
  font-size: var(--text-sm);
  font-weight: var(--font-semibold);
  letter-spacing: var(--badge-tracking);
  text-transform: uppercase;
  color: var(--color-primary);
}

.team-profile__bio {
  margin: var(--space-md) 0 0;
  max-width: 58ch;
  font-size: var(--text-base);
  color: var(--color-muted);
  line-height: var(--leading-relaxed);
}

.team-supporting {
  margin-top: var(--space-3xl);
  padding-top: var(--space-xl);
  border-top: 1px solid var(--color-border);
}

.team-supporting__grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
}

.team-profile--supporting {
  padding: 0 var(--space-xl);
  border-left: 1px solid var(--color-border);
}

.team-profile--supporting:first-child {
  padding-left: 0;
  border-left: 0;
}

.team-profile--supporting:last-child {
  padding-right: 0;
}

.team-profile--has-thumbnail {
  display: grid;
  grid-template-columns: 9rem minmax(0, 1fr);
  align-items: start;
  gap: var(--space-lg);
}

.team-profile__content {
  min-width: 0;
}

.team-profile__thumbnail {
  display: block;
  width: 100%;
  aspect-ratio: 4 / 5;
  overflow: hidden;
  border: 0.375rem solid var(--color-wood);
  border-radius: var(--radius-lg);
  background: var(--color-surface-200);
}

.team-profile__thumbnail img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center top;
}

.team-profile--supporting .team-profile__bio {
  margin-top: var(--space-sm);
  font-size: var(--text-sm);
  line-height: var(--leading-relaxed);
}

@media (max-width: 767px) {
  .team-featured,
  .team-supporting__grid {
    grid-template-columns: 1fr;
  }

  .team-profile--supporting,
  .team-profile--supporting:first-child,
  .team-profile--supporting:last-child {
    padding: var(--space-lg) 0;
    border-top: 1px solid var(--color-border);
    border-left: 0;
  }

  .team-profile--supporting:first-child {
    padding-top: 0;
    border-top: 0;
  }

  .team-profile--has-thumbnail {
    grid-template-columns: 7rem minmax(0, 1fr);
    gap: var(--space-md);
  }

  .team-featured {
    gap: var(--space-2xl);
  }

  .team-supporting {
    margin-top: var(--space-2xl);
  }
}

/* Area tiles pack from the left and size to their label. A fixed .grid--4 gave
   a lone location one filled cell and three empty ones, which reads as a page
   that failed to load rather than a business that works in one city. The
   catalog legitimately holds anywhere from one location to five. */
.area-tiles {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-lg);
}

.area-tiles .contact-area {
  flex: 0 1 auto;
  min-width: 12rem;
}

.about-area__copy {
  margin: 0 0 var(--space-2xl);
  max-width: 72ch;
  font-size: var(--text-lg);
  color: var(--color-text);
  line-height: var(--leading-relaxed);
}

/* The about hero leads with an eyebrow above the headline. */
.about-hero .section__label {
  display: block;
  margin-bottom: var(--space-sm);
}

/* Runs flush into the section below — the team row supplies its own top
   padding. The only rule worth keeping from the deleted assets/css/about.css;
   `overflow` clips the hero photo when one is set. */
.section.about-hero {
  padding: var(--space-3xl) 0 0;
  overflow: hidden;
}

@media (min-width: 900px) {
  .about-story {
    grid-template-columns: 1.6fr 1fr;
    gap: var(--space-3xl);
  }
}

/* ══════════════════════════════════════════════════════════════════════
   CONTACT  —  page-contact.php
   ══════════════════════════════════════════════════════════════════════ */

.contact-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  gap: 0;
  border-top: 1px solid var(--color-border);
  border-bottom: 1px solid var(--color-border);
}

/* Hairlines between tiles only, so a shorter row (no email, no hours) does not
   leave a rule hanging on the end. */
.contact-tile {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-sm);
  padding: var(--space-2xl) var(--space-xl);
  text-decoration: none;
  border-left: 1px solid var(--color-border);
}

.contact-tile:first-child {
  border-left: 0;
  padding-left: 0;
}

.contact-tile__icon {
  display: inline-flex;
  color: var(--color-text-dark);
}

/* GP/normalize override an inline SVG's width/height attributes. */
.contact-tile__icon svg {
  width: 1.5rem;
  height: 1.5rem;
  flex-shrink: 0;
}

.contact-tile__label {
  font-size: var(--text-xs);
  font-weight: var(--font-medium);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-muted);
}

/* Scoped so GP's global link colour cannot recolour a tile rendered as an <a>. */
.contact-tile .contact-tile__value,
a.contact-tile:hover .contact-tile__value,
a.contact-tile:focus .contact-tile__value {
  font-size: var(--text-base);
  color: var(--color-text-dark);
  line-height: var(--leading-snug);
}

a.contact-tile:hover .contact-tile__value {
  text-decoration: underline;
}

.contact-tile__line {
  display: block;
  color: inherit;
  text-decoration: none;
}

.contact-tile__line + .contact-tile__line {
  margin-top: 2px;
}

a.contact-tile__line:hover,
a.contact-tile__line:focus-visible {
  color: var(--color-text-dark);
  text-decoration: underline;
}

.contact-grid__aside {
  margin: var(--space-lg) 0 0;
}

/* ── Service-area cards ── */
.contact-area {
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: var(--space-sm);
  padding: var(--space-lg);
  text-decoration: none;
}

.contact-area__icon {
  display: inline-flex;
  color: var(--color-muted);
}

.contact-area__icon svg {
  width: 1.15rem;
  height: 1.15rem;
  flex-shrink: 0;
}

.contact-area .contact-area__name,
a.contact-area:hover .contact-area__name {
  font-size: var(--text-base);
  font-weight: var(--font-medium);
  color: var(--color-text-dark);
}

/* The quote widget sits beside the hero copy at desktop and below it on
   mobile; .hero__inner supplies the stacking. */
.contact-hero .hero__text {
  max-width: none;
}

@media (min-width: 768px) {
  .contact-hero .hero__inner {
    grid-template-columns: 1fr 1fr;
    gap: var(--space-3xl);
    /* Top-aligned, not centred. The copy column is roughly half the height of
       the quote widget beside it, so centring left the headline floating with
       224px of dead space under it and its top edge 128px below the widget's. */
    align-items: start;
  }
}

@media (max-width: 767px) {
  .contact-tile {
    border-left: 0;
    border-top: 1px solid var(--color-border);
    padding: var(--space-xl) 0;
  }

  .contact-tile:first-child {
    border-top: 0;
  }
}

/* ══════════════════════════════════════════════════════════════════════
   PROJECTS  —  template-parts/project-grid.php
   ══════════════════════════════════════════════════════════════════════ */

/* GP/normalize override the SVG's width/height attributes, so the icon needs
   an explicit CSS size or it collapses in the flex row. */
/* ── Gallery page ── */
.gallery-page__hero {
  padding: var(--space-2xl) 0;
}

.gallery-page__header {
  max-width: 52rem;
  margin-bottom: 0;
}

.gallery-page__grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--space-lg);
}

.gallery-tile {
  margin: 0;
}

.gallery-tile__link {
  position: relative;
  display: block;
  overflow: hidden;
  border-radius: var(--radius-lg);
  background: var(--color-surface-100);
}

.gallery-tile__image {
  display: block;
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  transition: transform var(--transition-slow);
}

.gallery-tile__project {
  position: absolute;
  inset: auto 0 0;
  padding: var(--space-xl) var(--space-md) var(--space-md);
  background: linear-gradient(to top, rgba(0, 0, 0, 0.72), rgba(0, 0, 0, 0));
  color: var(--color-white);
  font-size: var(--text-sm);
  font-weight: var(--font-semibold);
}

.gallery-tile__link:hover .gallery-tile__image {
  transform: scale(1.025);
}

.gallery-tile__link:focus-visible {
  outline: 2px solid var(--color-text-dark);
  outline-offset: 3px;
}

@media (max-width: 900px) {
  .gallery-page__grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (max-width: 600px) {
  .gallery-page__grid {
    grid-template-columns: 1fr;
  }
}

/* ── Projects archive ── */
.projects-archive__hero {
  padding: var(--space-2xl) 0;
}

.projects-archive__header {
  max-width: 52rem;
  margin-bottom: 0;
}

/* ── Project tile ── */
.project-tile {
  position: relative;
  display: block;
  overflow: hidden;
  border-radius: var(--radius-lg);
  aspect-ratio: 4 / 3;
  text-decoration: none;
  background: var(--color-surface-200);
}

.project-tile__media,
.project-tile__media img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.project-tile__media img {
  transition: transform var(--transition-slow);
}

.project-tile:hover .project-tile__media img {
  transform: scale(1.04);
}

/* A defined scrim, not a soft wash. The solid lower stop guarantees the text
   band stays dark enough for contrast regardless of what the photograph does
   behind it — a fade to transparent fails on light images at some widths. */
.project-tile__scrim {
  position: absolute;
  inset: 0;
  background: linear-gradient(
    to top,
    rgba(0, 0, 0, 0.78) 0%,
    rgba(0, 0, 0, 0.55) 22%,
    rgba(0, 0, 0, 0.12) 48%,
    rgba(0, 0, 0, 0) 70%
  );
  pointer-events: none;
}

.project-tile__body {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  display: flex;
  flex-direction: column;
  gap: 3px;
  padding: var(--space-lg);
}

/* Scoped so GP's `.site-header a`-style global link colours can never darken
   text that has to sit on a photograph. */
.project-tile .project-tile__title,
.project-tile:hover .project-tile__title,
.project-tile:focus .project-tile__title {
  font-size: var(--text-lg);
  font-weight: var(--font-semibold);
  color: var(--color-white);
  line-height: var(--leading-snug);
}

.project-tile .project-tile__tag {
  font-size: var(--text-xs);
  font-weight: var(--font-medium);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  /* 0.85 on the solid part of the scrim clears 4.5:1; do not lower it. */
  color: rgba(255, 255, 255, 0.85);
}

.project-tile:focus-visible {
  outline: 2px solid var(--color-text-dark);
  outline-offset: 3px;
}

@media (max-width: 767px) {
    .project-tile {
    aspect-ratio: 3 / 2;
  }

  .project-tile__body {
    padding: var(--space-md);
  }
}

/* ── Project detail ────────────────────────────────────────────────────
   The cover remains a real image (not a CSS background) for alt text and
   eager loading, but fills the hero behind a two-axis contrast scrim. */
.project-detail__header {
  position: relative;
  z-index: 2;
  max-width: 58rem;
  margin: 0;
  padding: clamp(var(--space-xl), 5vw, var(--space-3xl));
}

.project-detail__breadcrumb {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-xs);
  margin-bottom: var(--space-lg);
  color: rgba(255, 255, 255, 0.82);
  font-size: var(--text-sm);
}

.project-detail__breadcrumb a {
  color: var(--color-white);
  text-decoration: none;
}

.project-detail__breadcrumb a:hover {
  color: var(--color-white);
  text-decoration: underline;
}

.project-detail__breadcrumb svg {
  flex-shrink: 0;
}

.project-detail__title {
  max-width: 15ch;
  margin: 0 0 var(--space-md);
  color: var(--color-white);
  font-size: clamp(2.75rem, 7vw, 6.5rem);
  font-weight: var(--font-bold);
  letter-spacing: -0.045em;
  line-height: 0.95;
}

.project-detail__lede {
  max-width: 48rem;
  margin: 0;
  color: rgba(255, 255, 255, 0.92);
  font-size: var(--text-xl);
  line-height: var(--leading-relaxed);
}

.project-detail__services {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-sm);
  margin-top: var(--space-xl);
}

.project-detail__services a {
  padding: 0.55rem 0.9rem;
  border: 1px solid rgba(255, 255, 255, 0.58);
  border-radius: var(--radius-full);
  color: var(--color-white);
  font-size: var(--text-xs);
  font-weight: var(--font-semibold);
  letter-spacing: 0.06em;
  text-decoration: none;
  text-transform: uppercase;
  transition: border-color var(--transition-fast), background var(--transition-fast);
}

.project-detail__services a:hover,
.project-detail__services a:focus-visible {
  border-color: var(--color-white);
  background: rgba(255, 255, 255, 0.16);
}

.project-detail__hero,
.project-detail__figure {
  margin: 0;
}

.project-detail__hero {
  position: relative;
  display: flex;
  min-height: clamp(38rem, 68vh, 48rem);
  align-items: flex-end;
  overflow: hidden;
  margin-bottom: var(--space-3xl);
  border-radius: var(--radius-xl);
  background: var(--color-text-dark);
}

.project-detail__hero::after {
  position: absolute;
  z-index: 1;
  inset: 0;
  background:
    linear-gradient(to top, rgba(8, 8, 7, 0.9) 0%, rgba(8, 8, 7, 0.58) 48%, rgba(8, 8, 7, 0.12) 78%),
    linear-gradient(to right, rgba(8, 8, 7, 0.42), rgba(8, 8, 7, 0) 70%);
  content: "";
  pointer-events: none;
}

.project-detail__hero > .project-detail__image-link {
  position: absolute;
  inset: 0;
  border-radius: inherit;
}

.project-detail__hero .project-detail__image {
  height: 100%;
  aspect-ratio: auto;
  object-position: center;
}

.project-detail__hero .project-detail__expand {
  z-index: 3;
  top: var(--space-md);
  bottom: auto;
}

.project-detail__image-link {
  position: relative;
  display: block;
  overflow: hidden;
  border-radius: var(--radius-xl);
  background: var(--color-surface-200);
}

.project-detail__image {
  display: block;
  width: 100%;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  transition: transform var(--transition-slow);
}

.project-detail__image-link:hover .project-detail__image {
  transform: scale(1.01);
}

.project-detail__image-link:focus-visible {
  outline: 2px solid var(--color-text-dark);
  outline-offset: 4px;
}

.project-detail__expand {
  position: absolute;
  right: var(--space-md);
  bottom: var(--space-md);
  display: grid;
  width: 2.5rem;
  height: 2.5rem;
  place-items: center;
  border-radius: var(--radius-full);
  background: var(--color-white);
  box-shadow: var(--shadow-md);
  color: var(--color-text-dark);
}

.project-detail__expand svg {
  transform: rotate(-45deg);
}

.project-detail__overview {
  display: grid;
  grid-template-columns: minmax(0, 1.1fr) minmax(18rem, 0.9fr);
  gap: clamp(var(--space-2xl), 7vw, var(--space-4xl));
  padding: var(--space-3xl) 0;
  border-top: 1px solid var(--color-border);
  border-bottom: 1px solid var(--color-border);
}

.project-detail__overview-copy .section__title {
  margin-bottom: var(--space-lg);
}

.project-detail__overview-copy p {
  max-width: 42rem;
  margin: 0 0 var(--space-md);
  color: var(--color-text);
  font-size: var(--text-lg);
  line-height: var(--leading-relaxed);
}

.project-detail__overview-copy p:last-child {
  margin-bottom: 0;
}

.project-detail__highlights {
  padding-left: var(--space-xl);
  border-left: 1px solid var(--color-border);
}

.project-detail__highlights > h2 {
  margin: 0 0 var(--space-lg);
  color: var(--color-text-dark);
  font-size: var(--text-xl);
}

.project-detail__highlight {
  padding: var(--space-md) 0;
  border-top: 1px solid var(--color-border);
}

.project-detail__highlight h3 {
  margin: 0 0 var(--space-xs);
  color: var(--color-text-dark);
  font-size: var(--text-base);
}

.project-detail__highlight p {
  margin: 0;
  color: var(--color-muted);
  font-size: var(--text-sm);
  line-height: var(--leading-relaxed);
}

.project-detail__gallery {
  padding-top: var(--space-4xl);
}

.project-detail__gallery-head {
  margin-bottom: var(--space-xl);
}

.project-detail__gallery-pair,
.project-detail__story {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-lg);
  margin: var(--space-3xl) 0;
}

.project-detail__caption {
  margin-top: var(--space-sm);
  color: var(--color-muted);
  font-size: var(--text-sm);
  line-height: var(--leading-relaxed);
}

.project-detail__story {
  gap: clamp(var(--space-xl), 6vw, var(--space-4xl));
  padding: var(--space-3xl) 0;
  border-top: 1px solid var(--color-border);
  border-bottom: 1px solid var(--color-border);
}

.project-detail__story h3 {
  margin: 0 0 var(--space-sm);
  color: var(--color-text-dark);
  font-size: var(--text-2xl);
}

.project-detail__story p {
  margin: 0;
  color: var(--color-text);
  font-size: var(--text-base);
  line-height: var(--leading-relaxed);
}

.project-detail__related {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(22rem, 1fr);
  gap: var(--space-2xl);
  align-items: end;
  margin-top: var(--space-4xl);
  padding-top: var(--space-3xl);
  border-top: 1px solid var(--color-border);
}

.project-detail__related-links {
  display: grid;
  gap: var(--space-sm);
}

.project-detail__related-links a {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-md);
  padding: var(--space-md) 0;
  border-bottom: 1px solid var(--color-border);
  color: var(--color-text-dark);
  font-weight: var(--font-semibold);
  text-decoration: none;
}

.project-detail__related-links a:hover svg {
  transform: translateX(3px);
}

.project-detail__related-links svg {
  flex-shrink: 0;
  transition: transform var(--transition-fast);
}

.project-lightbox {
  width: min(96vw, 100rem);
  max-width: none;
  padding: 0;
  border: 0;
  background: transparent;
  overflow: visible;
}

.project-lightbox::backdrop {
  background: rgba(0, 0, 0, 0.88);
}

.project-lightbox__panel {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-sm);
}

.project-lightbox__image {
  display: block;
  max-width: 100%;
  max-height: 84vh;
  border-radius: var(--radius-lg);
  object-fit: contain;
}

.project-lightbox__caption {
  max-width: 60rem;
  margin: 0;
  color: var(--color-white);
  font-size: var(--text-sm);
  text-align: center;
}

.project-lightbox__close {
  position: absolute;
  z-index: 1;
  top: var(--space-sm);
  right: var(--space-sm);
  display: grid;
  width: 2.75rem;
  height: 2.75rem;
  padding: 0;
  place-items: center;
  border: 0;
  border-radius: var(--radius-full);
  background: var(--color-white);
  color: var(--color-text-dark);
  cursor: pointer;
  font-size: var(--text-2xl);
  line-height: 1;
}

@media (max-width: 767px) {
  .project-detail__hero {
    min-height: max(42rem, 72svh);
    margin-bottom: var(--space-2xl);
  }

  .project-detail__hero::after {
    background:
      linear-gradient(to top, rgba(8, 8, 7, 0.94) 0%, rgba(8, 8, 7, 0.68) 58%, rgba(8, 8, 7, 0.18) 84%),
      linear-gradient(to right, rgba(8, 8, 7, 0.26), rgba(8, 8, 7, 0));
  }

  .project-detail__header {
    padding: var(--space-lg);
  }

  .project-detail__breadcrumb {
    margin-bottom: var(--space-md);
    font-size: var(--text-xs);
  }

  .project-detail__title {
    font-size: clamp(2.5rem, 12vw, 3.75rem);
  }

  .project-detail__lede {
    font-size: var(--text-base);
    line-height: 1.55;
  }

  .project-detail__services {
    margin-top: var(--space-lg);
  }

  .project-detail__overview,
  .project-detail__gallery-pair,
  .project-detail__story,
  .project-detail__related {
    grid-template-columns: 1fr;
  }

  .project-detail__highlights {
    padding: var(--space-xl) 0 0;
    border-top: 1px solid var(--color-border);
    border-left: 0;
  }

  .project-detail__gallery-pair {
    margin: var(--space-2xl) 0;
  }

  .project-detail__story {
    padding: var(--space-2xl) 0;
  }

  .project-detail__related {
    align-items: start;
  }

  .project-lightbox {
    width: 100vw;
  }
}


/* ══════════════════════════════════════════════════════════════════════
   HOMEPAGE SECTIONS
   ══════════════════════════════════════════════════════════════════════ */

/* ── Hero ─────────────────────────────────────────────────────────── */
/* GP's separate-containers layout applies margin-top: 20px to .site-main. On a
   page whose first section is full-bleed that reads as a gap between the header
   and the hero photo — and it looks like a hero bug, which is where the time
   goes. Scoped so ordinary pages keep GP's spacing. */
.home .site-main,
.site-main:has(> .hero:first-child) {
  margin-top: 0;
}

/* Same layout, second symptom: separate-containers also puts margin-bottom:20px
   on every direct child of .site-main, so a 20px seam opens between every
   section on the page. Sections carry their own vertical rhythm here, so this
   only loosens it — and it is invisible in the markup, which is what makes it
   expensive to track down. */
.home .site-main > *,
.site-main:has(> .hero:first-child) > * {
  margin-bottom: 0;
}

.hero {
  background: var(--color-surface-100);
  overflow: hidden;
  position: relative;
  padding: var(--space-3xl) 0 var(--space-4xl);
  /* Full-bleed: break out of GP's centered content container so the hero
     background spans the full viewport width, like the other sections. */
  width: 100vw;
  margin-left: calc(50% - 50vw);
  margin-right: calc(50% - 50vw);
  padding: var(--space-4xl) 0;
  min-height: 32rem;
  display: flex;
  align-items: center;
}

.hero__glow {
  position: absolute;
  border-radius: 9999px;
  filter: blur(64px);
  pointer-events: none;
}

.hero__glow--tl {
  top: -20%;
  left: -10%;
  width: 50%;
  height: 50%;
  background: var(--color-surface-100);
}

.hero__glow--br {
  bottom: 0;
  right: 0;
  width: 40%;
  height: 45%;
  background: rgba(165, 243, 252, 0.06);
}

.hero__inner {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-3xl);
  align-items: center;
}

.hero__text {
  display: flex;
  flex-direction: column;
  gap: var(--space-xl);
  /* Readable measure for a hero with no photo beside it. Kept at specificity
     0,1,0 so a page-specific rule (.contact-hero .hero__text) still wins. */
  max-width: 46rem;
}

/* The service/location hero eyebrow. It already carried the same type tokens
   as .section__label; what set it apart was a #eff6ff pill with a
   rgba(219,234,254,…) border — a pale blue from the reference build's palette,
   and the only chipped eyebrow on a site where every other one is bare. The
   accent dot went with the pill for the same reason. */
.hero__badge {
  display: inline-block;
  font-size: var(--badge-font-size);
  font-weight: var(--font-bold);
  text-transform: uppercase;
  letter-spacing: var(--badge-tracking);
  color: var(--color-primary);
  width: fit-content;
}

.hero__headline {
  font-family: var(--font-family-heading);
  font-size: clamp(2.5rem, 6vw, var(--text-7xl));
  font-weight: var(--font-extrabold);
  line-height: 1.02;
  letter-spacing: -0.035em;
  color: var(--color-text-dark);
  margin: 0;
}

@media (min-width: 768px) {
  .hero__headline {
    font-size: clamp(2.5rem, 5vw, var(--text-6xl));
  }

  .hero--image .hero__sub {
    max-width: 34rem;
  }
}

.hero__ctas {
  display: flex;
  flex-direction: column;
  gap: var(--space-md);
  align-items: flex-start;
}

.hero__ctas .btn span {
  white-space: nowrap;
}

@media (max-width: 767px) {
  .hero__ctas {
    gap: var(--space-sm);
  }

  .hero__ctas .btn {
    width: 100%;
    min-height: 52px;
    padding: 11px 16px;
    gap: 10px;
    border-radius: var(--radius-lg);
    font-size: var(--text-base);
    line-height: 1.15;
    box-shadow: none;
  }

  .hero__ctas .btn .icon {
    width: 18px;
    height: 18px;
    flex: 0 0 18px;
  }

  .hero__ctas .btn span {
    white-space: nowrap;
  }

  .hero__ctas .btn:hover,
  .hero__ctas .btn:focus {
    transform: none;
  }

  .hero__ctas .btn:active {
    transform: scale(0.985);
  }
}

.hero__pills {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-md);
}

.hero__pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: var(--text-xs);
  font-weight: var(--font-semibold);
  color: var(--color-muted);
}

.hero__pill .icon {
  color: var(--color-accent);
}

/* Hero media (team photo, replaces the form in the right column).
   Stretches the full hero height and anchors the photo to the bottom so the
   team stands on the hero's base instead of floating mid-column. */
/* Full-bleed hero photo: out of flow so it fills the hero's full height and
   runs to the viewport's right edge, rather than sitting as a contained box in
   a grid column. The previous rule sized the image by its natural aspect
   (height:auto) with a negative bottom margin — a hack for cutout team photos
   that leaves an interior shot floating mid-band. */
.hero__media {
  position: absolute;
  inset: 0 0 0 50%;
  overflow: hidden;
  pointer-events: none;
}

.hero__media-img {
  display: block;
  width: 100%;
  max-width: none;
  height: 100%;
  object-fit: cover;
  margin-bottom: 0;
}

/* Soft fade from the hero surface into the photo's left edge. Decorative only
   — the headline sits well clear of the image, so unlike a hero scrim this
   carries no contrast risk. rgba white rather than `transparent`, which some
   engines interpolate through black. */
.hero__media::after {
  content: "";
  position: absolute;
  inset: 0 auto 0 0;
  width: 34%;
  background: linear-gradient(
    to right,
    var(--color-surface-100) 0%,
    rgba(250, 249, 247, 0.88) 42%,
    rgba(250, 249, 247, 0) 100%
  );
}

/* On mobile, the kitchen image becomes a full-bleed background, matching the
   project-detail treatment. Desktop retains the existing split copy/photo
   hero. */
@media (max-width: 767px) {
  .hero--image {
    position: relative;
    min-height: max(42rem, 72svh);
    padding: 0;
    background: var(--color-text-dark);
  }

  .hero--image .hero__inner {
    position: relative;
    z-index: 2;
    display: flex;
    min-height: inherit;
    align-items: flex-end;
  }

  .hero--image .hero__media {
    position: absolute;
    inset: 0;
    width: auto;
    height: auto;
    aspect-ratio: auto;
    margin: 0;
    border-radius: 0;
  }

  .hero--image .hero__media::after {
    display: block;
    inset: 0;
    width: auto;
    background:
      linear-gradient(to top, rgba(8, 8, 7, 0.94) 0%, rgba(8, 8, 7, 0.68) 58%, rgba(8, 8, 7, 0.18) 84%),
      linear-gradient(to right, rgba(8, 8, 7, 0.26), rgba(8, 8, 7, 0));
  }

  .hero--image .hero__text {
    max-width: 52rem;
    padding: var(--space-lg);
  }

  .hero--image .hero__headline,
  .hero--image .hero__sub {
    color: var(--color-white);
  }

  .hero--image .hero__sub {
    margin: 0;
    color: rgba(255, 255, 255, 0.92);
  }

  .hero--image .btn--dark {
    background: var(--color-white);
    color: var(--color-text-dark);
  }

  .hero--image .btn--dark:hover {
    background: var(--color-surface-100);
    color: var(--color-text-dark);
  }

  .hero--image .btn--outline {
    border-color: rgba(255, 255, 255, 0.58);
    background: rgba(255, 255, 255, 0.08);
    color: var(--color-white);
  }

  .hero--image .btn--outline:hover {
    border-color: var(--color-white);
    background: rgba(255, 255, 255, 0.16);
    color: var(--color-white);
  }
}

/* Widget */
.hero__widget-wrap {
  display: flex;
  flex-direction: column;
}

.hero__widget {
  background: var(--color-white);
  border: 1px solid var(--color-surface-200);
  /* Bottom corners squared so .hero__widget-foot closes the card off. */
  border-radius: var(--radius-2xl) var(--radius-2xl) 0 0;
  border-bottom: 0;
  box-shadow: 0 15px 50px rgba(0, 0, 0, 0.06);
  overflow: hidden;
  position: relative;
}

.hero__widget-head {
  display: flex;
  align-items: center;
  gap: var(--space-md);
  padding: var(--space-xl) var(--space-xl) 0;
  padding-top: calc(var(--space-xl) + 6px);
}

/* ── Quote form — fields and success screen ──────────────────────────────
   Restored: an earlier dead-CSS purge matched these by the `modal__` prefix
   rather than by the confirmed dead-class list, and took the in-use rules out
   with the booking-modal ones. The success screen lost its centring, its pill
   and its green tick. Rules below are the originals, recovered verbatim. */
.modal__label {
  display: block;
  font-size: var(--text-xs);
  font-weight: var(--font-bold);
  color: var(--color-text-dark);
  margin-bottom: 4px;
}

.modal__input {
  width: 100%;
  padding: 10px var(--space-md);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  font-size: var(--text-sm);
  color: var(--color-text);
  background: var(--color-white);
  outline: none;
  transition: border-color var(--transition-fast), box-shadow var(--transition-fast);
}

.modal__input:focus {
  border-color: var(--color-primary);
  box-shadow: 0 0 0 3px rgba(28, 27, 25, 0.14);
}

.modal__success {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: var(--space-md);
  padding: var(--space-xl) 0;
}

.modal__success-tag {
  font-size: 10px;
  font-weight: var(--font-bold);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--color-primary);
  background: var(--color-surface-100);
  padding: 4px var(--space-md);
  border-radius: var(--radius-full);
}

.modal__success-title {
  font-family: var(--font-family-heading);
  font-size: var(--text-2xl);
  font-weight: var(--font-bold);
  color: var(--color-text-dark);
  margin: 0;
}

.modal__success-copy {
  font-size: var(--text-sm);
  color: var(--color-muted);
  line-height: var(--leading-relaxed);
  max-width: 320px;
  margin: 0;
}

.modal__success-icon {
  color: #10b981;
}

/* Bare icon, not a chip — same treatment as .step__icon. It used to sit on a
   #eff6ff rounded square, a pale blue from the reference build's palette that
   no longer belongs to any colour on this site. */
.hero__widget-icon-wrap {
  color: var(--color-primary);
  flex-shrink: 0;
}

.hero__widget-title {
  font-family: var(--font-family-heading);
  font-size: var(--text-lg);
  font-weight: var(--font-bold);
  color: var(--color-primary);
  margin: 0;
}

.hero__widget-desc {
  font-size: var(--text-xs);
  color: var(--color-muted);
  margin: 2px 0 0;
}

.hero__widget-body {
  padding: var(--space-lg) var(--space-xl) var(--space-xl);
  display: flex;
  flex-direction: column;
  gap: var(--space-lg);
}

.hero__field-label {
  display: block;
  font-size: 10px;
  font-weight: var(--font-bold);
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--color-muted);
  margin-bottom: var(--space-sm);
}

.hero__select {
  width: 100%;
  background: var(--color-surface-100);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: 10px var(--space-md);
  font-size: var(--text-sm);
  font-weight: var(--font-semibold);
  color: var(--color-text-dark);
  outline: none;
  cursor: pointer;
}

.hero__select:focus {
  border-color: var(--color-primary);
  box-shadow: 0 0 0 3px rgba(28, 27, 25, 0.14);
}

.hero__svc-btns {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-sm);
}

.hero__svc-btn {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 10px;
  border-radius: var(--radius-lg);
  border: 1px solid var(--color-border);
  background: var(--color-white);
  color: var(--color-muted);
  font-size: 10px;
  font-weight: var(--font-bold);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  gap: 6px;
  cursor: pointer;
  transition: all var(--transition-fast);
}

.hero__svc-btn:hover,
.hero__svc-btn:focus {
  background: var(--color-surface-100);
  border-color: var(--color-muted);
  color: var(--color-text-dark);
}

.hero__svc-btn:focus-visible {
  outline: 2px solid var(--color-text-dark);
  outline-offset: 2px;
}

.hero__svc-btn--active,
.hero__svc-btn--active:hover,
.hero__svc-btn--active:focus {
  background: var(--color-surface-200) !important;
  border-color: var(--color-text-dark);
  color: var(--color-text-dark) !important;
  box-shadow: none;
}

/* The card's own footer, not a floating strip. It used to sit 16px below with
   its own full border and radius, which read as a stray bar. Colours were
   rgba() slate literals from the reference build's palette — tokens now. */
.hero__widget-foot {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  padding: 12px var(--space-lg);
  background: var(--color-surface-100);
  border: 1px solid var(--color-surface-200);
  border-top: 0;
  border-radius: 0 0 var(--radius-2xl) var(--radius-2xl);
  font-size: var(--text-xs);
  font-weight: var(--font-semibold);
  color: var(--color-muted);
}

.hero__widget-foot .icon {
  color: var(--color-primary);
  flex-shrink: 0;
}

.hero__widget-online {
  margin-left: auto;
  color: var(--color-accent);
  font-weight: var(--font-bold);
}

@media (min-width: 768px) {
  .hero__inner {
    grid-template-columns: 1fr;
  }

  /* 44% only makes sense when a photo occupies the other half. theme_image()
     returns '' on a miss, so an unset hero image left the copy at 44% of the
     band with 56% blank — the guarded empty state has to reflow, not just
     hide the image. */
  .hero__inner:has(.hero__media) .hero__text {
    max-width: 44%;
  }

  .hero__ctas {
    flex-direction: row;
    flex-wrap: wrap;
  }

  .hero__ctas .btn {
    flex: 0 1 auto;
  }
}

/* ── Trust Bar ────────────────────────────────────────────────────── */
/* No section padding: the strip's rules meet the hero's bottom edge. */
.trust-bar {
  padding: 0;
  position: relative;
  z-index: 3;
}

/* Full-bleed white sections */
#professional_services_section,
#about_section {
  background: var(--color-white);
  width: 100vw;
  margin-left: calc(50% - 50vw);
  margin-right: calc(50% - 50vw);
}

/* extra top room so the heading clears the overlapping trust card */
#professional_services_section {
  padding-top: var(--space-4xl);
}


/* ── Why Choose Us ────────────────────────────────────────────────── */
.why-us {
  background: var(--color-white);
}

/* ── Testimonials carousel ────────────────────────────────────────────
   Peek carousel: the active card is centred and full-strength, neighbours sit
   either side at reduced opacity. Cards are rendered server-side; home.js only
   moves the track. */
/* The viewport clips the track; the negative margin lets neighbour cards bleed
   toward the page edges rather than being cut at the container. */
.testimonials__viewport {
  overflow: hidden;
  margin: 0 calc(var(--space-2xl) * -1);
  padding: var(--space-md) 0;
}

.testimonials__track {
  display: flex;
  align-items: stretch;
  gap: var(--space-xl);
  align-items: stretch;
  transition: transform var(--transition-slow);
  will-change: transform;
}

/* Reduced motion: no sliding, and no autoplay (handled in home.js). */
@media (prefers-reduced-motion: reduce) {
  .testimonials__track {
    transition: none;
  }
}

.tcard {
  flex: 0 0 min(58%, 620px);
  display: flex;
  flex-direction: column;
  box-sizing: border-box;
  padding: var(--space-xl);
  background: var(--color-white);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-2xl);
  cursor: pointer;
  opacity: 0.45;
  transition: opacity var(--transition-base), box-shadow var(--transition-base);
}

.tcard--active {
  opacity: 1;
  box-shadow: var(--shadow-lg);
  cursor: default;
}

/* GP/normalize override the SVG's width/height attributes, so the quote mark
   needs an explicit CSS size or it collapses. */
.tcard__quote {
  width: 2rem;
  height: 2rem;
  flex-shrink: 0;
  color: var(--color-surface-200);
  margin-bottom: var(--space-md);
}

/* GP styles bare <blockquote> with italics, a grey background panel, and a
   left border. Scoped under .tcard to out-rank it — a review is body copy
   here, not a pull quote. */
.tcard blockquote.tcard__text {
  margin: 0 0 var(--space-lg);
  padding: 0;
  border: 0;
  background: none;
  font-style: normal;
  font-size: var(--text-lg);
  font-weight: var(--font-normal);
  color: var(--color-text-dark);
  line-height: var(--leading-relaxed);
}

.tcard blockquote.tcard__text::before,
.tcard blockquote.tcard__text::after {
  content: none;
}

.tcard__foot {
  display: flex;
  align-items: center;
  gap: var(--space-md);
  margin-top: auto;
  padding-top: var(--space-md);
  border-top: 1px solid var(--color-border);
}

.tcard__avatar {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 2.75rem;
  height: 2.75rem;
  overflow: hidden;
  border-radius: var(--radius-full);
  background: var(--color-surface-200);
  color: var(--color-text-dark);
  font-size: var(--text-lg);
  font-weight: var(--font-semibold);
  line-height: 1;
}

.tcard__avatar--photo {
  background: none;
}

.tcard__avatar img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.tcard__person {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

.tcard__author {
  font-size: var(--text-base);
  font-weight: var(--font-semibold);
  color: var(--color-text-dark);
}

.tcard__role {
  font-size: var(--text-sm);
  color: var(--color-text);
}

/* ── Dots ── */
.testimonials__dots {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-sm);
  margin-top: var(--space-2xl);
}

/* GP paints a dark background on button:focus, so :focus gets an explicit
   background here and :focus-visible supplies the keyboard ring. */
.testimonials__dot,
.testimonials__dot:hover,
.testimonials__dot:focus {
  width: 0.625rem;
  height: 0.625rem;
  padding: 0;
  border: 0;
  border-radius: var(--radius-full);
  background: var(--color-surface-200);
  cursor: pointer;
  transition: background var(--transition-fast);
}

.testimonials__dot:hover,
.testimonials__dot:focus {
  background: var(--color-muted);
}

.testimonials__dot.is-active,
.testimonials__dot.is-active:hover,
.testimonials__dot.is-active:focus {
  background: var(--color-text-dark);
}

.testimonials__dot:focus-visible {
  outline: 2px solid var(--color-text-dark);
  outline-offset: 3px;
}

@media (max-width: 767px) {
  .testimonials__viewport {
    margin: 0 calc(var(--space-lg) * -1);
  }

  .testimonials__track {
    gap: var(--space-md);
  }

  .tcard {
    flex-basis: 84%;
    padding: var(--space-xl);
  }

  .tcard__text {
    font-size: var(--text-lg);
  }
}


/* ── FAQs ─────────────────────────────────────────────────────────── */
/* Left-aligned, not centred: every section header on the site now uses
   .section__header--stack, so an auto-margined list sat ~300px right of its
   own heading. The 720px measure stays — a full-width accordion is a worse
   read than a narrow one. */
/* Heading in one column, accordion in the other. A 720px list under a
   full-width header left 600px of the container empty beside it. */
.faqs-layout {
  display: grid;
  gap: var(--space-2xl);
}

@media (min-width: 900px) {
  .faqs-layout {
    grid-template-columns: 1fr 1.45fr;
    gap: var(--space-3xl);
    align-items: start;
  }

  .faqs-layout .section__header {
    margin-bottom: 0;
  }

  /* The column already constrains the measure. */
  .faqs-layout .faqs__list {
    max-width: none;
  }
}

.faqs__list {
  max-width: 720px;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 0;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-xl);
  overflow: hidden;
  background: var(--color-white);
}

.faqs__item {
  border-bottom: 1px solid var(--color-surface-200);
}

.faqs__item:last-child {
  border-bottom: none;
}

.faqs__q {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-md);
  padding: var(--space-lg) var(--space-xl);
  background: none;
  border: none;
  text-align: left;
  font-size: var(--text-base);
  font-weight: var(--font-semibold);
  color: var(--color-text-dark);
  cursor: pointer;
  transition: background var(--transition-fast), color var(--transition-fast);
}

.faqs__q:hover,
.faqs__q:focus {
  background: var(--color-surface-100);
  color: var(--color-primary);
}

.faqs__q:hover .faqs__chevron,
.faqs__q:focus .faqs__chevron {
  color: var(--color-primary);
}

/* Keyboard-only focus ring; removes GP's dark button-focus background. */
.faqs__q:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: -2px;
}

.faqs__q[aria-expanded="true"] {
  color: var(--color-primary);
}

.faqs__chevron {
  flex-shrink: 0;
  transition: transform var(--transition-base);
  color: var(--color-muted);
}

.faqs__q[aria-expanded="true"] .faqs__chevron {
  transform: rotate(180deg);
  color: var(--color-primary);
}

.faqs__a {
  padding: 0 var(--space-xl) var(--space-lg);
}

.faqs__a p {
  font-size: var(--text-sm);
  color: var(--color-muted);
  line-height: var(--leading-relaxed);
  margin: 0;
}

/* ── Service Areas ────────────────────────────────────────────────── */
.service-areas__grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--space-md);
  margin-bottom: var(--space-2xl);
}

/* Stack the area cards on small phones so they never overflow (<~390px). */
@media (max-width: 520px) {
  .service-areas__grid {
    grid-template-columns: 1fr;
  }
}

.service-areas__card {
  background: var(--color-white);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-xl);
  padding: var(--space-xl);
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-sm);
  transition: box-shadow var(--transition-base);
}

.service-areas__card:hover {
  box-shadow: var(--shadow-md);
}

.service-areas__pin {
  color: var(--color-primary);
}

.service-areas__name {
  font-family: var(--font-family-heading);
  font-size: var(--text-lg);
  font-weight: var(--font-bold);
  color: var(--color-text-dark);
}
/* The dark .service-areas__bar band and the .service-final block that wrapped
   it were the reference build's closing CTA — including .service-areas__logo-blue
   / __logo-cyan, the BLUE/TAP wordmark, and a #0f172a navy from a palette this
   site does not use. Removed with the markup; the closing CTA is now
   template-parts/closing-cta.php. .service-areas__grid/__card/__name/__pin are
   still in use and stay. */

@media (min-width: 768px) {
  /* Two service areas: keep them a centered pair, not stretched across
     four columns (which left the right half empty). */
  .service-areas__grid {
    grid-template-columns: repeat(2, 1fr);
    max-width: 760px;
    margin-left: auto;
    margin-right: auto;
  }
}

/* ── Service Pages ────────────────────────────────────────────────── */
.service-hero {
  padding-bottom: var(--space-xl);
}

.service-hero__inner,
.service-scope__grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-2xl);
  align-items: center;
}

/* Mobile: single column, content first, photo below */
.service-hero__inner {
  justify-items: start;
  text-align: left;
}

.service-hero__media {
  display: flex;
  justify-content: center;
  width: 100%;
  margin: 0;
  overflow: hidden;
  border-radius: var(--radius-2xl);
  background: var(--color-surface-200);
}

.service-hero__image {
  display: block;
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
}

@media (min-width: 768px) {
  /* Two-up only when there is a photo. The media div is now omitted entirely
     when no slug resolves, so a hero without imagery runs full width instead
     of leaving half the band empty. */
  .service-hero__inner:has(.service-hero__media) {
    grid-template-columns: 1fr 1fr;
    justify-items: start;
    text-align: left;
  }

  .service-hero__media {
    justify-content: flex-end;
  }
}

.service-hero__content,
.service-scope__copy {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  gap: var(--space-xl);
}

.service-hero__content {
  align-items: flex-start;
}

/* Detail tier of the page-title scale — see PAGE TITLE SCALE above. */
.service-hero__title,
.section__title--page {
  margin: 0;
  color: var(--color-text-dark);
  font-family: var(--font-family-heading);
  font-size: clamp(2.25rem, 4.5vw, var(--text-6xl));
  font-weight: var(--font-extrabold);
  line-height: 1.05;
  letter-spacing: -0.035em;
}

.service-hero__copy,
.service-scope__copy p {
  margin: 0;
  color: var(--color-muted);
  font-size: var(--text-lg);
  line-height: var(--leading-relaxed);
}

.service-intro__grid,
.service-craft__grid,
.service-details__grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-2xl);
  align-items: start;
}

.service-intro__copy,
.service-craft__copy p {
  margin: 0;
  color: var(--color-text);
  font-size: var(--text-lg);
  line-height: var(--leading-relaxed);
}

.service-capabilities__grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-md);
}

.service-capability {
  display: flex;
  flex-direction: column;
  gap: var(--space-md);
  padding: var(--space-xl);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-xl);
  background: var(--color-white);
}

.service-capability__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.75rem;
  height: 2.75rem;
  border-radius: var(--radius-lg);
  background: var(--color-surface-100);
  color: var(--color-primary);
}

.service-capability h3 {
  margin: 0;
  color: var(--color-text-dark);
  font-size: var(--text-xl);
}

.service-capability p {
  margin: 0;
  color: var(--color-text);
  font-size: var(--text-sm);
  line-height: var(--leading-relaxed);
}

.service-craft__copy {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-lg);
}

.service-craft__media {
  width: 100%;
  margin: 0;
  overflow: hidden;
  border-radius: var(--radius-2xl);
  background: var(--color-surface-200);
}

.service-craft__image {
  display: block;
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
}

.service-detail-list {
  display: grid;
  grid-template-columns: 1fr;
  gap: 0;
  margin: 0;
  padding: 0;
  border-top: 1px solid var(--color-border);
  list-style: none;
}

.service-detail-list li {
  display: flex;
  align-items: flex-start;
  gap: var(--space-sm);
  padding: var(--space-md) 0;
  border-bottom: 1px solid var(--color-border);
  color: var(--color-text);
  line-height: var(--leading-relaxed);
}

.service-detail-list svg {
  flex-shrink: 0;
  margin-top: 0.25em;
  color: var(--color-primary);
}

.service-card-grid,
.service-related__grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-md);
}

.service-card,
.service-scope__panel {
  background: var(--color-white);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-xl);
  padding: var(--space-xl);
  box-shadow: var(--shadow-sm);
}

.service-card {
  display: flex;
  flex-direction: column;
  gap: var(--space-md);
}

.service-card__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.75rem;
  height: 2.75rem;
  border-radius: var(--radius-lg);
  background: var(--color-surface-100);
  color: var(--color-primary);
}

.service-card h3,
.service-scope__panel h3 {
  margin: 0;
  color: var(--color-text-dark);
  font-size: var(--text-xl);
  font-weight: 900;
}

.service-card p {
  margin: 0;
  color: var(--color-muted);
  font-size: var(--text-sm);
  line-height: var(--leading-relaxed);
}

/* Services page category row: intro column beside the cards rather than a
   full-width header stacked above them. The intro is deliberately the narrow
   column — it holds three short lines, the cards hold everything else. */
.services-cat {
  display: grid;
  gap: var(--space-2xl);
}

.services-cat__intro .section__header {
  margin-bottom: 0;
}

@media (min-width: 1000px) {
  .services-cat {
    grid-template-columns: minmax(0, 0.8fr) minmax(0, 2fr);
    gap: var(--space-3xl);
    align-items: start;
  }
}

/* auto-fit does not collapse the spare track here, so three cards in a
   four-track grid left one column empty. Sized off the column instead. */
.services-cat__grid {
  display: grid;
  gap: var(--space-lg);
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
  margin-top: 0;
}

.service-inline-cta {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-md);
}

.service-scope__panel {
  position: relative;
  overflow: hidden;
}

.service-scope__panel-bar {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 5px;
  background: linear-gradient(90deg, var(--color-primary), var(--color-accent));
}

.service-scope__panel h3 {
  margin-top: var(--space-sm);
  margin-bottom: var(--space-md);
}

.service-scope__panel ul {
  display: grid;
  gap: var(--space-sm);
  margin: 0;
  padding: 0;
  list-style: none;
}

.service-scope__panel li {
  position: relative;
  margin: 0;
  padding-left: var(--space-lg);
  color: var(--color-muted);
  font-size: var(--text-sm);
  line-height: var(--leading-relaxed);
}

.service-scope__panel li::before {
  content: '';
  position: absolute;
  top: 0.7em;
  left: 0;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--color-accent);
}

.service-related__card {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-md);
  padding: var(--space-lg);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-xl);
  background: var(--color-white);
  color: var(--color-text-dark);
  font-size: var(--text-base);
  font-weight: var(--font-bold);
  text-align: left;
  cursor: pointer;
  transition: box-shadow var(--transition-fast), color var(--transition-fast);
}

.service-related__card:hover,
.service-related__card:focus {
  color: var(--color-primary);
  box-shadow: var(--shadow-md);
}

.location-jump {
  background: var(--color-white);
  border-top: 1px solid var(--color-border);
  border-bottom: 1px solid var(--color-border);
}

.location-jump__inner {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--space-sm);
  padding-top: var(--space-md);
  padding-bottom: var(--space-md);
}

.location-jump__inner a {
  border: 1px solid var(--color-border);
  border-radius: var(--radius-full);
  padding: 7px 12px;
  background: var(--color-surface-100);
  color: var(--color-text-dark);
  font-size: var(--text-xs);
  font-weight: var(--font-bold);
}

.location-jump__inner a:hover,
.location-problem-card:hover {
  color: var(--color-primary);
  box-shadow: var(--shadow-md);
}

.location-problem-card {
  color: var(--color-text-dark);
  text-decoration: none;
  transition: box-shadow var(--transition-fast), color var(--transition-fast);
}

.service-page-areas .service-areas__grid {
  margin-bottom: 0;
}


.service-placeholder {
  min-height: 58vh;
  background: var(--color-surface-100);
}

.service-placeholder__card {
  max-width: 760px;
  margin: 0 auto;
  padding: var(--space-2xl);
  background: var(--color-white);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-2xl);
  box-shadow: var(--shadow-md);
}

.service-placeholder__card h1 {
  margin: 0 0 var(--space-md);
  font-size: var(--text-4xl);
  font-weight: 900;
  letter-spacing: 0;
}

.service-placeholder__card p {
  max-width: 620px;
  color: var(--color-muted);
  font-size: var(--text-lg);
  line-height: var(--leading-relaxed);
}

.service-placeholder__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-md);
  margin-top: var(--space-xl);
}

@media (min-width: 768px) {
  .service-intro__grid {
    grid-template-columns: minmax(0, 0.8fr) minmax(0, 1.2fr);
    gap: var(--space-3xl);
  }

  .service-capabilities__grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .service-craft__grid {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: var(--space-3xl);
    align-items: center;
  }

  .service-details__grid {
    grid-template-columns: minmax(0, 0.8fr) minmax(0, 1.2fr);
    gap: var(--space-3xl);
  }

  .service-scope__grid {
    grid-template-columns: 1fr 0.76fr;
  }

  .service-card-grid,
  .service-related__grid {
    grid-template-columns: repeat(4, 1fr);
  }

}

@media (min-width: 1100px) {
  .service-capabilities__grid {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }
}

@media (max-width: 767px) {
  .service-hero__title {
    font-size: var(--text-4xl);
  }

  .service-hero__copy,
  .service-scope__copy p {
    font-size: var(--text-base);
  }
}

/* ── Booking Modal ────────────────────────────────────────────────── */
.modal {
  position: fixed;
  inset: 0;
  z-index: 9999;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-md);
}

.modal[hidden] {
  display: none;
}

/* ── Footer brand name ────────────────────────────────────────────
   Stacked to match the header wordmark. The previous inline rule used
   clamp(2rem, 6vw, 2.65rem) at weight 900, which overflowed its grid column
   as soon as the wordmark ran longer than the short one it was tuned for. */
.footer-brand {
  display: inline-flex;
  align-items: center;
  gap: var(--space-sm);
  flex-shrink: 0;
  text-decoration: none;
}

.footer-brand__img {
  flex-shrink: 0;
  width: 44px;
  height: 44px;
  object-fit: contain;
}

.footer-brand__word {
  display: inline-flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 3px;
  font-family: var(--font-family-heading);
  line-height: 1;
}

.footer-brand__primary {
  font-size: var(--text-xl);
  font-weight: var(--font-bold);
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.footer-brand__accent {
  font-size: var(--text-xs);
  font-weight: var(--font-normal);
  letter-spacing: 0.42em;
  text-transform: uppercase;
  margin-right: -0.42em;
}

/* Scoped so GP's global link colour cannot darken or recolour the wordmark. */
.footer-wrap .footer-brand,
.footer-wrap .footer-brand:hover,
.footer-wrap .footer-brand:focus,
.footer-wrap .footer-brand__primary,
.footer-wrap .footer-brand__accent {
  color: var(--color-text-dark);
}

/* ══════════════════════════════════════════════════════════════════════
   MOBILE HERO / TRUST SPACING
   Placed last so these win source-order against the base .trust-bar rule
   and the #professional_services_section ID rule (which only need their
   large desktop spacing for the straddling trust card).
   ══════════════════════════════════════════════════════════════════════ */
@media (max-width: 767px) {
  .hero {
    min-height: 0;
    padding-top: var(--space-xl);
    padding-bottom: var(--space-xl);
  }
  .hero__inner {
    gap: var(--space-xl);
  }
  /* Tighten the vertical rhythm so the hero copy reads as one compact block
     instead of three widely-spaced rows on a narrow screen. */
  .hero__text {
    gap: var(--space-lg);
  }
  /* Line-height only. The font-size cap that used to sit here (max 2.5rem) was
     tuned to keep the reference build's "You Can Count On" accent on one line;
     that copy is gone, and the cap left the page title smaller than the
     section headings below it on a narrow screen. The base clamp handles the
     range — see PAGE TITLE SCALE. */
  .hero__headline {
    line-height: 1.1;
  }
  .hero__media {
    position: relative;
    inset: auto;
    width: 100%;
    aspect-ratio: 4 / 3;
    margin: 0;
    border-radius: var(--radius-2xl);
  }
  /* Keep the in-flow trust strip close to the hero on narrow screens. */
  .trust-bar {
    padding: 0 0 var(--space-lg);
  }
  #professional_services_section {
    padding-top: var(--space-xl);
  }
}

/* Mobile: tighten vertical section rhythm (client: too much empty space) */
@media (max-width: 767px) {
  .section {
    padding: var(--space-2xl) 0;
  }
}

/* ── Opt-in scroll reveals ─────────────────────────────────────────── */
[data-reveal].reveal-ready {
  opacity: 0;
  transform: translate3d(0, 1rem, 0);
  will-change: opacity, transform;
}

[data-reveal="image"].reveal-ready {
  transform: translate3d(0, 0.75rem, 0) scale(0.985);
}

[data-reveal="left"].reveal-ready {
  transform: translate3d(1rem, 0, 0);
}

[data-reveal="from-left"].reveal-ready {
  transform: translate3d(-2.5rem, 0, 0) scale(1.03);
}

[data-reveal="from-right"].reveal-ready {
  transform: translate3d(2.5rem, 0, 0) scale(1.03);
}

/* The two featured About portraits use a calmer slide without the image-scale
   jump used by more decorative media reveals. */
.team-profile__media[data-reveal="from-left"].reveal-ready {
  transform: translate3d(-1.5rem, 0, 0);
}

.team-profile__media[data-reveal="from-right"].reveal-ready {
  transform: translate3d(1.5rem, 0, 0);
}

[data-reveal].reveal-ready.reveal-active {
  transition: opacity 460ms ease-out var(--reveal-delay, 0ms), transform 460ms ease-out var(--reveal-delay, 0ms);
}

.team-profile__media[data-reveal].reveal-ready.reveal-active {
  transition: opacity 1100ms cubic-bezier(0.16, 1, 0.3, 1) var(--reveal-delay, 0ms), transform 1100ms cubic-bezier(0.16, 1, 0.3, 1) var(--reveal-delay, 0ms);
}

[data-reveal].reveal-ready.is-revealed {
  opacity: 1;
  transform: translate3d(0, 0, 0);
  will-change: auto;
}

@media (prefers-reduced-motion: reduce) {
  [data-reveal].reveal-ready {
    opacity: 1;
    transform: none;
    transition: none;
  }

}
