/* ============================================================
   FERNHOLLOW GARDEN STUDIO
   Multi-page Bespoke edition for Weavo Studio portfolio

   CONFIG-DRIVEN:
   - Every swappable value (brand, copy, colours, fonts, images) lives in
     brand.config.json and is applied by build.js. There are no hand-edited
     "SWAP" placeholders any more — change the config and rebuild.
   - The :root below holds the DEFAULT palette/fonts. build.js injects a
     <style id="brand-tokens"> :root override in <head> from config.colors
     and config.fonts, so per-brand values win without touching this file.
   - Structure: pages share this one CSS file. Extend by adding
     page-specific sections below the shared components.

   FILE STRUCTURE:
   index.html ............ Home
   about.html ............ About the designer
   services.html ......... Services (combined)
   portfolio.html ........ Portfolio overview grid
   projects/*.html ....... Individual project case studies
   contact.html .......... Contact / consultation
   ============================================================ */

/* --- FONTS ---
   Fonts are loaded in the document <head> (see templates/partials/head.html)
   via preconnect + an async stylesheet (rel=preload as=style, swapped to
   rel=stylesheet onload) with display=swap, so the font CSS never blocks
   render and text paints immediately in the fallback. The families come from
   brand.config.json (fonts.googleFamilies). To change fonts globally, edit
   fonts.* in the config and rebuild. To self-host, drop @font-face rules here
   and remove the font links from head.html.
*/


/* @critical:start */
/* ============================================================
   DESIGN TOKENS
   ============================================================ */
:root {
  /* Default palette — Somerset lichen/limestone/meadow inspired.
     Cool sage off-white, deep forest charcoal. Overridden per-brand by
     the build (config.colors). Edit brand.config.json, not these defaults. */
  --color-bg:         #F0F1ED;
  --color-bg-alt:     #E5E7E1;
  --color-bg-deep:    #2C3128;
  --color-text:       #2C3128;
  --color-text-mid:   #5A5F55;
  --color-text-light: #888C84;
  --color-text-on-dark: #E8EAE4;
  --color-accent:     #6B7A5E;
  --color-accent-hover: #566A48;
  --color-border:     #D0D3CA;
  --color-border-light: #DCDFD7;
  --color-white:      #FAFBF8;

  /* Typography scale */
  --font-display: 'Cormorant', Georgia, 'Times New Roman', serif;
  --font-body:    'DM Sans', system-ui, -apple-system, 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:  2rem;
  --text-4xl:  2.5rem;
  --text-5xl:  3.25rem;
  --text-6xl:  4rem;

  /* Spacing */
  --space-xs:  0.5rem;
  --space-sm:  1rem;
  --space-md:  1.5rem;
  --space-lg:  2rem;
  --space-xl:  3rem;
  --space-2xl: 4rem;
  --space-3xl: 6rem;
  --space-4xl: 8rem;

  /* Layout */
  --max-width: 1320px;
  --max-width-narrow: 780px;
  --gutter: clamp(1.25rem, 4vw, 3rem);

  /* Corner radii — all-soft system, consistent */
  --radius-sm: 4px;
  --radius-md: 8px;
  --radius-lg: 12px;

  /* Transitions */
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --duration-fast: 0.2s;
  --duration-base: 0.4s;
  --duration-slow: 0.6s;
}


/* ============================================================
   RESET & BASE
   ============================================================ */
*, *::before, *::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

html {
  scroll-behavior: smooth;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

body {
  font-family: var(--font-body);
  font-size: var(--text-base);
  line-height: 1.65;
  color: var(--color-text);
  background-color: var(--color-bg);
  /* Avoid ugly one-word last lines in paragraphs (progressive enhancement) */
  text-wrap: pretty;
}

img {
  max-width: 100%;
  height: auto;
  display: block;
}

/* Anchored sections clear the fixed navigation when scrolled/linked to */
[id] {
  scroll-margin-top: 5.5rem;
}

a {
  color: inherit;
  text-decoration: none;
}

button {
  font-family: inherit;
  cursor: pointer;
  border: none;
  background: none;
}

:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 3px;
  border-radius: var(--radius-sm);
}


/* ============================================================
   UTILITIES
   ============================================================ */
.container {
  max-width: var(--max-width);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.container-narrow {
  max-width: var(--max-width-narrow);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

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


/* ============================================================
   TYPOGRAPHY
   ============================================================ */
h1, h2, h3, h4 {
  font-family: var(--font-display);
  font-weight: 500;
  line-height: 1.1;
  letter-spacing: -0.01em;
  /* Balance multi-line headings so they don't leave a lone word on the last line */
  text-wrap: balance;
}

h1 { font-size: clamp(2.5rem, 5vw + 1rem, var(--text-6xl)); }
h2 { font-size: clamp(2rem, 3vw + 0.5rem, var(--text-5xl)); }
h3 { font-size: clamp(1.5rem, 2vw + 0.5rem, var(--text-3xl)); }
h4 { font-size: var(--text-xl); }

.body-lg {
  font-size: var(--text-lg);
  line-height: 1.7;
  max-width: 60ch;
}

.label {
  font-family: var(--font-body);
  font-size: var(--text-xs);
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-text-mid);
}


/* ============================================================
   BUTTONS
   ============================================================ */
.btn {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-family: var(--font-body);
  font-size: var(--text-sm);
  font-weight: 500;
  letter-spacing: 0.04em;
  padding: 0.875rem 1.75rem;
  border-radius: var(--radius-md);
  transition: all var(--duration-fast) var(--ease-out);
  white-space: nowrap;
}

.btn:active {
  transform: scale(0.98);
}

.btn-primary {
  background-color: var(--color-accent);
  color: var(--color-white);
}

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

.btn-outline {
  background: transparent;
  color: var(--color-text);
  border: 1px solid var(--color-border);
}

.btn-outline:hover {
  border-color: var(--color-accent);
  color: var(--color-accent);
}

.btn-on-dark {
  background-color: var(--color-white);
  color: var(--color-bg-deep);
}

.btn-on-dark:hover {
  background-color: var(--color-bg);
}

/* Text-style link with arrow */
.link-arrow {
  font-size: var(--text-sm);
  font-weight: 500;
  color: var(--color-accent);
  transition: color var(--duration-fast) var(--ease-out);
}

.link-arrow::after {
  content: ' \2192';
  transition: transform var(--duration-fast) var(--ease-out);
  display: inline-block;
}

.link-arrow:hover {
  color: var(--color-accent-hover);
}

.link-arrow:hover::after {
  transform: translateX(3px);
}


/* ============================================================
   SHARED: NAVIGATION
   Used on all pages. On home, starts transparent over hero.
   On inner pages, starts with the .scrolled look immediately
   via the .nav-inner-page class on body or nav.
   ============================================================ */
.site-nav {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 100;
  padding: var(--space-md) 0;
  transition: background var(--duration-base) var(--ease-out),
              padding var(--duration-base) var(--ease-out);
}

/* Legibility scrim — a top-to-transparent dark gradient behind the
   transparent nav (home hero) so light nav text keeps contrast over bright
   parts of the photo (e.g. sky). Sits above the hero image but below the nav
   text. Fades out once the nav goes solid (scrolled / inner pages), so it
   never reads as a heavy black bar. */
.site-nav::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 160px;
  background: linear-gradient(to bottom, rgba(0, 0, 0, 0.55), rgba(0, 0, 0, 0) 160px);
  pointer-events: none;
  z-index: -1;
  opacity: 1;
  transition: opacity var(--duration-base) var(--ease-out);
}

.site-nav.scrolled::before,
.site-nav.nav-inner-page::before {
  opacity: 0;
}

@media (prefers-reduced-motion: reduce) {
  .site-nav::before { transition: none; }
}

.site-nav.scrolled,
.site-nav.nav-inner-page {
  background: rgba(240, 241, 237, 0.92);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  padding: var(--space-sm) 0;
  border-bottom: 1px solid var(--color-border-light);
}

.nav-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.nav-logo {
  font-family: var(--font-display);
  font-size: var(--text-lg);
  font-weight: 600;
  color: var(--color-white);
  letter-spacing: -0.01em;
  /* Keep the logo legible over light patches of the hero */
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.4);
  transition: color var(--duration-base) var(--ease-out);
}

.site-nav.scrolled .nav-logo,
.site-nav.nav-inner-page .nav-logo {
  color: var(--color-text);
  text-shadow: none; /* solid nav on light bg — no shadow needed */
}

.nav-links {
  display: none;
  list-style: none;
  gap: var(--space-lg);
  align-items: center;
}

.nav-links a {
  font-size: var(--text-sm);
  font-weight: 500;
  color: rgba(255, 255, 255, 0.8);
  /* Keep links legible over light patches of the hero */
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.4);
  transition: color var(--duration-fast) var(--ease-out);
}

.nav-links a:hover,
.nav-links a.active {
  color: var(--color-white);
}

.site-nav.scrolled .nav-links a,
.site-nav.nav-inner-page .nav-links a {
  color: var(--color-text-mid);
  text-shadow: none; /* solid nav on light bg — no shadow needed */
}

.site-nav.scrolled .nav-links a:hover,
.site-nav.scrolled .nav-links a.active,
.site-nav.nav-inner-page .nav-links a:hover,
.site-nav.nav-inner-page .nav-links a.active {
  color: var(--color-text);
}

.nav-cta {
  display: none;
  color: var(--color-white);
  /* Dark translucent fill + brighter border so it reads as a button over any
     part of the hero, not just the dark areas */
  background: rgba(0, 0, 0, 0.25);
  border-color: rgba(255, 255, 255, 0.5);
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.4);
}

.nav-cta:hover {
  color: var(--color-white);
  background: rgba(0, 0, 0, 0.38);
  border-color: rgba(255, 255, 255, 0.75);
}

.site-nav.scrolled .nav-cta,
.site-nav.nav-inner-page .nav-cta {
  color: var(--color-text);
  background: transparent; /* solid nav on light bg — no dark fill */
  border-color: var(--color-border);
  text-shadow: none;
}

.site-nav.scrolled .nav-cta:hover,
.site-nav.nav-inner-page .nav-cta:hover {
  color: var(--color-accent);
  background: transparent;
  border-color: var(--color-accent);
}

/* Mobile menu toggle */
.nav-toggle {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 5px;
  padding: 8px;
  min-width: 44px;
  min-height: 44px;
}

.nav-toggle span {
  display: block;
  width: 22px;
  height: 1.5px;
  background: var(--color-white);
  transition: background var(--duration-fast) var(--ease-out);
}

.site-nav.scrolled .nav-toggle span,
.site-nav.nav-inner-page .nav-toggle span {
  background: var(--color-text);
}

/* Mobile menu overlay */
.mobile-menu {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 99;
  background: var(--color-bg-deep);
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  gap: var(--space-lg);
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--duration-base) var(--ease-out);
}

.mobile-menu.open {
  opacity: 1;
  pointer-events: all;
}

.mobile-menu a {
  font-family: var(--font-display);
  font-size: var(--text-3xl);
  color: var(--color-text-on-dark);
  transition: color var(--duration-fast) var(--ease-out);
}

.mobile-menu a:hover {
  color: var(--color-white);
}

.mobile-menu-close {
  position: absolute;
  top: var(--space-md);
  right: var(--gutter);
  font-size: var(--text-xl);
  color: var(--color-text-on-dark);
  display: flex;
  align-items: center;
  justify-content: center;
  min-width: 44px;
  min-height: 44px;
  padding: 8px;
}

@media (min-width: 768px) {
  .nav-links { display: flex; }
  .nav-cta   { display: inline-flex; }
  .nav-toggle { display: none; }
}
/* @critical:end */

/* ====== HEADER CALL LINK (cfg.nav.showPhone) ======================
   On a lead-gen site the number is the primary conversion path, so it
   sits in the nav itself — on mobile between the logo and the menu
   toggle, so it is one tap away without opening the menu.

   These rules live OUTSIDE the @critical block and are inlined into the
   <head> only for configs that switch the feature on (build.js reads the
   @critical-if:navPhone markers). A site without a header phone pays no
   bytes for it and its markup is unchanged. */
/* @critical-if:navPhone:start */
.nav-phone {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  margin-left: auto;              /* mobile: sit beside the menu toggle */
  margin-right: var(--space-sm);
  padding: 6px 8px;
  min-height: 44px;               /* full tap target */
  font-size: var(--text-base);   /* one step up — 45-75 audience */
  font-weight: 600;
  letter-spacing: -0.01em;
  white-space: nowrap;
  color: var(--color-white);
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.4);
  transition: color var(--duration-fast) var(--ease-out);
}

.nav-phone svg {
  width: 16px;
  height: 16px;
  flex: none;
  fill: currentColor;
}

.site-nav.scrolled .nav-phone,
.site-nav.nav-inner-page .nav-phone {
  color: var(--color-text);
  text-shadow: none;
}

.site-nav.scrolled .nav-phone:hover,
.site-nav.nav-inner-page .nav-phone:hover {
  color: var(--color-accent);
}

@media (min-width: 768px) {
  /* Desktop: part of the right-hand cluster, just before the CTA button. */
  .nav-phone {
    margin-left: 0;
    margin-right: var(--space-md);
    font-size: var(--text-lg);
  }
}

/* Call entry at the top of the mobile menu overlay. Same specificity as
   `.mobile-menu a` and defined after it, so it wins the cascade. */
.mobile-menu .mobile-menu-call {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.9rem 1.75rem;
  border-radius: 999px;
  background: var(--color-accent);
  color: var(--color-white);
  font-family: var(--font-body);
  font-size: var(--text-lg);
  font-weight: 600;
  letter-spacing: -0.01em;
}

.mobile-menu .mobile-menu-call:hover {
  background: var(--color-accent-hover);
  color: var(--color-white);
}

.mobile-menu .mobile-menu-call svg {
  width: 18px;
  height: 18px;
  flex: none;
  fill: currentColor;
}
/* @critical-if:navPhone:end */

/* ====== SECOND HERO BUTTON (cfg.hero.secondaryCta) =================
   Sits next to the primary hero action — typically "get a quote" beside a
   call button. .btn-outline is styled for light backgrounds, so over the
   hero photo it needs the same treatment .nav-cta gets. Inlined only for
   configs that define a secondary CTA. */
/* @critical-if:heroSecondary:start */
.hero-cta-secondary {
  margin-left: var(--space-sm);
  color: var(--color-white);
  background: rgba(0, 0, 0, 0.25);
  border-color: rgba(255, 255, 255, 0.5);
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.4);
}

.hero-cta-secondary:hover {
  color: var(--color-white);
  background: rgba(0, 0, 0, 0.38);
  border-color: rgba(255, 255, 255, 0.75);
}

@media (max-width: 479px) {
  /* Stack full-width on small phones instead of squeezing two buttons
     onto one line — both are primary conversion targets. */
  .hero-content .btn {
    display: flex;
    justify-content: center;
  }
  .hero-cta-secondary {
    margin-left: 0;
    margin-top: var(--space-sm);
  }
}
/* @critical-if:heroSecondary:end */

/* ====== STICKY MOBILE CALL BAR (cfg.callBar.enabled) ==============
   Fixed to the bottom of the viewport on phones only. It is above the
   fold by definition, so its rules are inlined for configs that switch
   it on. body.has-call-bar (added by the build) reserves the matching
   space so the footer and last section stay fully readable. */
/* @critical-if:callBar:start */
.site-call-bar {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 150;
  padding: 0.5rem var(--gutter);
  /* Clear the home indicator on notched phones */
  padding-bottom: calc(0.5rem + env(safe-area-inset-bottom));
  background: var(--color-bg);
  border-top: 1px solid var(--color-border);
  box-shadow: 0 -4px 16px rgba(0, 0, 0, 0.08);
}

.site-call-bar-btn {
  display: flex;
  width: 100%;
  min-height: 48px;              /* thumb-sized tap target */
  justify-content: center;
  font-size: var(--text-base);
  font-weight: 600;
  letter-spacing: 0;
}

.site-call-bar-btn svg {
  width: 18px;
  height: 18px;
  flex: none;
  fill: currentColor;
}

body.has-call-bar {
  padding-bottom: calc(4.25rem + env(safe-area-inset-bottom));
}

/* The open mobile menu carries its own call button — no need for both. */
.mobile-menu.open ~ .site-call-bar {
  display: none;
}

/* Demo builds pin the watermark to the bottom too. The watermark is a
   respect rail and must stay visible, so the call bar stacks above it
   and the body reserves the height of both. */
body.has-demo-watermark .site-call-bar {
  bottom: 3.25rem;
}

body.has-demo-watermark.has-call-bar {
  padding-bottom: calc(7.5rem + env(safe-area-inset-bottom));
}

@media (min-width: 768px) {
  /* Desktop has the header number and the CTA buttons; no bar. */
  .site-call-bar { display: none; }
  body.has-call-bar { padding-bottom: 0; }
  body.has-demo-watermark.has-call-bar { padding-bottom: 3.25rem; }
}
/* @critical-if:callBar:end */

/* ====== SOLID NAV CTA (cfg.nav.ctaSolid) =========================
   The outline button reads as secondary against a photo. Filling it with
   the brand accent makes the quote path unmistakable — and keeps the same
   treatment once the nav goes solid, so it never changes character on
   scroll. Above the fold, so inlined when the flag is on. */
/* @critical-if:navCtaSolid:start */
.nav-cta {
  background: var(--color-accent);
  border-color: var(--color-accent);
  color: var(--color-white);
  font-weight: 600;
  text-shadow: none;
}

.nav-cta:hover {
  background: var(--color-accent-hover);
  border-color: var(--color-accent-hover);
  color: var(--color-white);
}

.site-nav.scrolled .nav-cta,
.site-nav.nav-inner-page .nav-cta {
  background: var(--color-accent);
  border-color: var(--color-accent);
  color: var(--color-white);
}

.site-nav.scrolled .nav-cta:hover,
.site-nav.nav-inner-page .nav-cta:hover {
  background: var(--color-accent-hover);
  border-color: var(--color-accent-hover);
  color: var(--color-white);
}
/* @critical-if:navCtaSolid:end */

/* ====== HERO OVERLAY STRENGTH (cfg.hero.overlay) =================
   Restates the .hero-media::after gradient with its three alpha stops
   driven by custom properties, which build.js emits into the brand-tokens
   :root block when the config sets an overlay. cfg.hero.overlay is the
   BOTTOM (strongest) stop, where the headline sits; the other two scale
   with it so the gradient keeps its shape.

   The var() fallbacks are the engine defaults (0.7 / 0.2 / 0.05), so this
   rule is a no-op for any config that does not set an overlay — it has to
   be, because unlike the other optional blocks this selector exists on
   every site and the full stylesheet is loaded by all of them. */
/* @critical-if:heroOverlay:start */
.hero-media::after {
  background: linear-gradient(to top,
    rgba(44, 49, 40, var(--hero-overlay-strong, 0.7)) 0%,
    rgba(44, 49, 40, var(--hero-overlay-mid, 0.2)) 40%,
    rgba(44, 49, 40, var(--hero-overlay-soft, 0.05)) 100%);
}
/* @critical-if:heroOverlay:end */


/* ============================================================
   SHARED: FOOTER
   ============================================================ */
.site-footer {
  padding: var(--space-2xl) 0;
  border-top: 1px solid var(--color-border);
}

.footer-inner {
  display: flex;
  flex-direction: column;
  gap: var(--space-md);
  align-items: center;
  text-align: center;
}

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

.footer-brand {
  font-family: var(--font-display);
  font-size: var(--text-lg);
  font-weight: 600;
  color: var(--color-text);
}

.footer-meta {
  font-size: var(--text-sm);
  color: var(--color-text-light);
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-sm);
  justify-content: center;
}

@media (min-width: 768px) {
  .footer-meta { justify-content: flex-end; }
}

.footer-meta span {
  white-space: nowrap;
}

/* Footer NAP block (cfg.footer.napBlock) — name, phone, email, service area.
   Entity-SEO consistency: these values are rendered verbatim from the config,
   the same source the JSON-LD business node is built from. */
.footer-nap {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  font-style: normal;              /* <address> italicises by default */
  font-size: var(--text-sm);
  color: var(--color-text-mid);
  text-align: center;
}

@media (min-width: 768px) {
  .footer-nap { text-align: left; }
}

.footer-nap-name {
  font-weight: 600;
  color: var(--color-text);
}

.footer-nap a {
  color: var(--color-text-mid);
  transition: color var(--duration-fast) var(--ease-out);
}

.footer-nap a:hover {
  color: var(--color-accent);
}

.footer-nap-phone {
  font-weight: 600;
  color: var(--color-text);
}

.footer-nap-area {
  color: var(--color-text-light);
}


/* @critical:start */
/* ============================================================
   SCROLL REVEAL ANIMATIONS
   Gentle fade-up. Respects reduced motion.
   ============================================================ */
@media (prefers-reduced-motion: no-preference) {
  .reveal {
    opacity: 0;
    transform: translateY(20px);
    transition: opacity var(--duration-slow) var(--ease-out),
                transform var(--duration-slow) var(--ease-out);
  }

  .reveal.visible {
    opacity: 1;
    transform: translateY(0);
  }

  .reveal-stagger > .reveal:nth-child(2) { transition-delay: 0.08s; }
  .reveal-stagger > .reveal:nth-child(3) { transition-delay: 0.16s; }
  .reveal-stagger > .reveal:nth-child(4) { transition-delay: 0.24s; }
  .reveal-stagger > .reveal:nth-child(5) { transition-delay: 0.32s; }
  .reveal-stagger > .reveal:nth-child(6) { transition-delay: 0.40s; }
}

@media (prefers-reduced-motion: reduce) {
  .reveal {
    opacity: 1;
    transform: none;
  }
}


/* ============================================================
   HOME PAGE: HERO (full-bleed, photography-led)
   ============================================================ */
.hero {
  position: relative;
  min-height: 100vh;      /* fallback for browsers without dvh */
  min-height: 100dvh;     /* accounts for mobile browser chrome */
  display: flex;
  align-items: flex-end;
  padding: var(--space-3xl) 0 var(--space-2xl);
  overflow: hidden;
}

/* Hero photograph is a real <img> inside .hero-media, kept full-bleed
   via object-fit so the visual presentation matches a background image
   while remaining crawlable and Lighthouse-friendly. */
.hero-media {
  position: absolute;
  inset: 0;
  z-index: 0;
}

.hero-media img,
.hero-media .img-placeholder {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center 40%;
  display: block;
}

.hero-media::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(to top, rgba(44,49,40,0.7) 0%, rgba(44,49,40,0.2) 40%, rgba(44,49,40,0.05) 100%);
}

.hero-content {
  position: relative;
  z-index: 1;
  max-width: 680px;
}

.hero h1 {
  color: var(--color-white);
  margin-bottom: var(--space-md);
  line-height: 1.05;
  padding-bottom: 0.125em;
}

.hero h1 em {
  font-style: italic;
  font-weight: 400;
}

.hero-subtitle {
  font-size: var(--text-lg);
  color: rgba(232, 234, 228, 0.85);
  max-width: 48ch;
  margin-bottom: var(--space-lg);
  line-height: 1.6;
}

.hero-image-alt {
  position: absolute;
  bottom: var(--space-sm);
  right: var(--gutter);
  font-size: var(--text-xs);
  color: rgba(255,255,255,0.35);
  z-index: 1;
}


/* @critical:end */


/* ============================================================
   HOME PAGE: INTRO / ETHOS TEASER
   ============================================================ */
.intro {
  padding: var(--space-4xl) 0;
}

.intro-inner {
  max-width: 680px;
  margin-inline: auto;
  text-align: center;
}

.intro h2 {
  margin-bottom: var(--space-lg);
}

.intro p {
  font-size: var(--text-lg);
  line-height: 1.75;
  color: var(--color-text-mid);
  max-width: 58ch;
  margin-inline: auto;
}

.intro .link-arrow {
  display: inline-block;
  margin-top: var(--space-md);
}


/* ============================================================
   HOME PAGE: FEATURED PROJECTS TEASER (Accordion gallery)
   Reused from the single-page version — the signature element.
   ============================================================ */
.portfolio-section {
  padding: var(--space-3xl) 0 var(--space-4xl);
}

.portfolio-section-header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: var(--space-sm);
  margin-bottom: var(--space-2xl);
}

.accordion-gallery {
  display: flex;
  height: clamp(400px, 60vh, 650px);
  gap: 4px;
  border-radius: var(--radius-lg);
  overflow: hidden;
}

.accordion-strip {
  position: relative;
  flex: 1;
  min-width: 0;
  overflow: hidden;
  cursor: pointer;
  transition: flex var(--duration-slow) var(--ease-out);
  text-decoration: none;
  display: block;
}

.accordion-strip:hover,
.accordion-strip:focus-within {
  flex: 4;
}

/* Each strip's photo is a real <img> inside .accordion-strip-media,
   generated from config.projects by build.js. */
.accordion-strip-media {
  position: absolute;
  inset: 0;
  background-color: var(--color-bg-deep); /* fallback while loading */
}

.accordion-strip-media img,
.accordion-strip-media .img-placeholder {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform var(--duration-slow) var(--ease-out);
}

.accordion-strip:hover .accordion-strip-media img {
  transform: scale(1.03);
}

.accordion-strip::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(to top, rgba(44,49,40,0.75) 0%, rgba(44,49,40,0.1) 50%, transparent 100%);
  z-index: 1;
}

.accordion-strip-content {
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  padding: var(--space-lg);
  z-index: 2;
}

.accordion-strip-category {
  font-family: var(--font-body);
  font-size: 0.6875rem;
  font-weight: 500;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: rgba(232, 234, 228, 0.7);
  margin-bottom: var(--space-xs);
  opacity: 0;
  transform: translateY(8px);
  transition: opacity var(--duration-base) var(--ease-out),
              transform var(--duration-base) var(--ease-out);
}

.accordion-strip:hover .accordion-strip-category,
.accordion-strip:focus-within .accordion-strip-category {
  opacity: 1;
  transform: translateY(0);
}

.accordion-strip-title {
  font-family: var(--font-display);
  font-size: var(--text-2xl);
  font-weight: 500;
  color: var(--color-white);
  line-height: 1.15;
  margin-bottom: 0.25rem;
  writing-mode: vertical-lr;
  transform: rotate(180deg);
  white-space: nowrap;
  transition: all var(--duration-base) var(--ease-out);
}

.accordion-strip:hover .accordion-strip-title,
.accordion-strip:focus-within .accordion-strip-title {
  writing-mode: horizontal-tb;
  transform: rotate(0deg);
  font-size: clamp(1.5rem, 2vw, var(--text-3xl));
}

.accordion-strip-location {
  font-size: var(--text-sm);
  color: rgba(232, 234, 228, 0.65);
  opacity: 0;
  transform: translateY(8px);
  transition: opacity var(--duration-base) var(--ease-out) 0.05s,
              transform var(--duration-base) var(--ease-out) 0.05s;
}

.accordion-strip:hover .accordion-strip-location,
.accordion-strip:focus-within .accordion-strip-location {
  opacity: 1;
  transform: translateY(0);
}

.accordion-strip-desc {
  font-size: var(--text-sm);
  color: rgba(232, 234, 228, 0.6);
  margin-top: var(--space-xs);
  max-width: 36ch;
  opacity: 0;
  transform: translateY(8px);
  transition: opacity var(--duration-base) var(--ease-out) 0.1s,
              transform var(--duration-base) var(--ease-out) 0.1s;
}

.accordion-strip:hover .accordion-strip-desc,
.accordion-strip:focus-within .accordion-strip-desc {
  opacity: 1;
  transform: translateY(0);
}

@media (max-width: 767px) {
  .accordion-gallery {
    flex-direction: column;
    height: auto;
    gap: var(--space-sm);
    border-radius: var(--radius-md);
  }

  .accordion-strip {
    height: 220px;
    flex: none;
    border-radius: var(--radius-md);
  }

  /* Touch: tapping a strip must NOT trigger the desktop expand/zoom.
     Those :hover/:focus-within rules are more specific than the mobile
     layout, so neutralise them here or the tapped card jumps and the
     image scales before navigation. */
  .accordion-strip:hover,
  .accordion-strip:focus-within {
    flex: none;
  }

  .accordion-strip:hover .accordion-strip-media img,
  .accordion-strip:focus-within .accordion-strip-media img {
    transform: none;
  }

  .accordion-strip-title,
  .accordion-strip:hover .accordion-strip-title,
  .accordion-strip:focus-within .accordion-strip-title {
    writing-mode: horizontal-tb;
    transform: rotate(0deg);
    font-size: var(--text-xl);
  }

  .accordion-strip-category,
  .accordion-strip-location,
  .accordion-strip-desc {
    opacity: 1;
    transform: translateY(0);
  }

  /* Premium tap feedback: a subtle press-in on the card + a gentle image
     lift, driven by :active (only while the finger is down), so it feels
     tactile and reverts instantly — never sticks like the old expand.
     Placed after the neutralise rules so the :active image scale wins. */
  .accordion-strip {
    transition: transform var(--duration-fast) var(--ease-out);
    -webkit-tap-highlight-color: transparent;
  }

  .accordion-strip:active {
    transform: scale(0.985);
  }

  .accordion-strip-media img {
    transition: transform var(--duration-base) var(--ease-out);
  }

  .accordion-strip:active .accordion-strip-media img {
    transform: scale(1.05);
  }
}


/* ============================================================
   HOME PAGE: SERVICES TEASER
   ============================================================ */
.services-teaser {
  padding: var(--space-4xl) 0;
  background-color: var(--color-bg-alt);
}

.services-teaser-header {
  max-width: 520px;
  margin-bottom: var(--space-2xl);
}

.services-teaser-header h2 {
  margin-bottom: var(--space-sm);
}

.services-teaser-header p {
  color: var(--color-text-mid);
}

.services-teaser-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-lg);
  margin-bottom: var(--space-xl);
}

@media (min-width: 640px) {
  .services-teaser-grid { grid-template-columns: 1fr 1fr; }
}
@media (min-width: 1024px) {
  .services-teaser-grid { grid-template-columns: repeat(4, 1fr); }
}

.service-teaser-item {
  padding-top: var(--space-md);
  border-top: 1px solid var(--color-border);
}

.service-teaser-item h3 {
  font-family: var(--font-display);
  font-size: var(--text-xl);
  font-weight: 500;
  margin-bottom: var(--space-xs);
}

.service-teaser-item p {
  font-size: var(--text-sm);
  color: var(--color-text-mid);
  line-height: 1.65;
  max-width: 32ch;
}


/* ============================================================
   HOME PAGE: TESTIMONIAL FEATURE (single quote)
   ============================================================ */
.testimonial-feature {
  padding: var(--space-4xl) 0;
  background-color: var(--color-bg-deep);
  color: var(--color-text-on-dark);
}

.testimonial-feature-inner {
  max-width: 700px;
  margin-inline: auto;
  text-align: center;
}

.testimonial-feature blockquote {
  font-family: var(--font-display);
  font-size: clamp(var(--text-xl), 2.5vw, var(--text-3xl));
  font-weight: 400;
  font-style: italic;
  line-height: 1.45;
  margin-bottom: var(--space-lg);
  padding-bottom: 0.15em;
}

.testimonial-feature .testimonial-attr {
  font-size: var(--text-sm);
  color: rgba(232, 234, 228, 0.5);
}

.testimonial-feature .testimonial-attr strong {
  color: rgba(232, 234, 228, 0.75);
  font-weight: 500;
}


/* ============================================================
   HOME PAGE: CONTACT CTA STRIP
   ============================================================ */
.cta-strip {
  padding: var(--space-3xl) 0;
  text-align: center;
}

.cta-strip h2 {
  margin-bottom: var(--space-md);
}

.cta-strip p {
  color: var(--color-text-mid);
  max-width: 48ch;
  margin-inline: auto;
  margin-bottom: var(--space-lg);
}

/* Second strip button (cfg.ctaStrips.mode "both") — the contact path beside
   a call button. Below the fold, so these rules ride the async stylesheet.
   .btn-outline is styled for light backgrounds; the feature strip sits on a
   dark photo and needs the same treatment the hero's second button gets. */
.cta-strip-secondary {
  margin-left: var(--space-sm);
}

.cta-strip--feature[style*="background-image"] .cta-strip-secondary {
  color: var(--color-white);
  background: rgba(0, 0, 0, 0.25);
  border-color: rgba(255, 255, 255, 0.5);
}

.cta-strip--feature[style*="background-image"] .cta-strip-secondary:hover {
  color: var(--color-white);
  background: rgba(0, 0, 0, 0.38);
  border-color: rgba(255, 255, 255, 0.75);
}

@media (max-width: 479px) {
  /* Stack rather than squeeze two conversion buttons onto one line. */
  .cta-strip .btn {
    display: flex;
    justify-content: center;
  }
  .cta-strip-secondary {
    margin-left: 0;
    margin-top: var(--space-sm);
  }
}


/* @critical:start */
/* ============================================================
   INNER PAGE: PAGE HEADER
   Used on About, Services, Portfolio, Contact pages.
   Compact hero with coloured background (no photograph).
   ============================================================ */
.page-header {
  padding: calc(var(--space-4xl) + 2rem) 0 var(--space-2xl);
  background-color: var(--color-bg-alt);
}

.page-header h1 {
  color: var(--color-text);
  margin-bottom: var(--space-sm);
}

.page-header p {
  font-size: var(--text-lg);
  color: var(--color-text-mid);
  max-width: 52ch;
  line-height: 1.6;
}


/* @critical:end */


/* ============================================================
   ABOUT PAGE
   ============================================================ */
.about-intro {
  padding: var(--space-4xl) 0;
}

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

@media (min-width: 768px) {
  .about-intro-grid {
    grid-template-columns: 5fr 7fr;
    gap: var(--space-3xl);
  }
}

/* About image lives in .about-portrait-wrap. When a scene/portrait photo
   is configured it renders as a real <img>; when none is provided it
   degrades to a tasteful non-photo treatment (.about-portrait--placeholder)
   — deliberately never a fake AI person. */
.about-portrait-wrap {
  max-width: 420px;
  aspect-ratio: 3 / 4;
  border-radius: var(--radius-lg);
  overflow: hidden;
}

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

.about-portrait--placeholder {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: flex-end;
  padding: var(--space-lg);
  background:
    radial-gradient(120% 100% at 50% 0%, rgba(255,255,255,0.10), transparent 60%),
    linear-gradient(160deg, var(--color-accent), var(--color-bg-deep));
  color: var(--color-text-on-dark);
}

.about-portrait--placeholder .about-portrait-monogram {
  font-family: var(--font-display);
  font-size: var(--text-4xl);
  font-weight: 500;
  line-height: 1;
  opacity: 0.9;
}

.about-text h2 {
  margin-bottom: var(--space-md);
}

.about-text p {
  color: var(--color-text-mid);
  margin-bottom: var(--space-md);
  max-width: 56ch;
}

/* About: Philosophy section */
.about-philosophy {
  padding: var(--space-3xl) 0 var(--space-4xl);
  background-color: var(--color-bg-alt);
}

.about-philosophy-inner {
  max-width: 680px;
  margin-inline: auto;
}

.about-philosophy h2 {
  margin-bottom: var(--space-lg);
}

.about-philosophy p {
  font-size: var(--text-lg);
  line-height: 1.75;
  color: var(--color-text-mid);
  margin-bottom: var(--space-md);
}

/* About: Credentials */
.about-credentials {
  padding: var(--space-3xl) 0 var(--space-4xl);
}

.about-credentials h2 {
  margin-bottom: var(--space-2xl);
  text-align: center;
}

.credentials-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--space-lg);
  max-width: 720px;
  margin-inline: auto;
}

@media (min-width: 640px) {
  .credentials-grid { grid-template-columns: repeat(4, 1fr); }
}

.credential-card {
  text-align: center;
  padding: var(--space-lg) var(--space-sm);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
}

.credential-card-name {
  font-family: var(--font-display);
  font-size: var(--text-xl);
  font-weight: 600;
  color: var(--color-accent);
  margin-bottom: var(--space-xs);
}

.credential-card p {
  font-size: var(--text-xs);
  color: var(--color-text-mid);
  line-height: 1.5;
}

/* About: Press mentions */
.about-press {
  padding: var(--space-xl) 0 var(--space-4xl);
}

.about-press p {
  text-align: center;
  color: var(--color-text-light);
  font-size: var(--text-sm);
}


/* ============================================================
   SERVICES PAGE
   ============================================================ */
.services-detail {
  padding: var(--space-4xl) 0;
}

.service-block {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-xl);
  padding-bottom: var(--space-3xl);
  margin-bottom: var(--space-3xl);
  border-bottom: 1px solid var(--color-border);
}

.service-block:last-child {
  border-bottom: none;
  margin-bottom: 0;
  padding-bottom: 0;
}

@media (min-width: 768px) {
  .service-block {
    grid-template-columns: 5fr 7fr;
    gap: var(--space-3xl);
  }
}

.service-block h2 {
  margin-bottom: var(--space-sm);
}

.service-block-intro {
  color: var(--color-text-mid);
  font-size: var(--text-lg);
  line-height: 1.7;
}

.service-block-body h3 {
  margin-bottom: var(--space-sm);
  font-size: var(--text-xl);
}

.service-block-body p {
  color: var(--color-text-mid);
  margin-bottom: var(--space-md);
  max-width: 56ch;
}

.service-block-body ul {
  list-style: none;
  margin-bottom: var(--space-lg);
}

.service-block-body li {
  position: relative;
  padding-left: 1.25rem;
  color: var(--color-text-mid);
  margin-bottom: var(--space-xs);
  font-size: var(--text-sm);
  line-height: 1.65;
}

.service-block-body li::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0.55em;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--color-accent);
  opacity: 0.5;
}

/* Services: process summary */
.services-process {
  padding: var(--space-3xl) 0 var(--space-4xl);
  background-color: var(--color-bg-alt);
}

.services-process h2 {
  margin-bottom: var(--space-2xl);
}

.process-steps {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-lg);
}

@media (min-width: 768px) {
  .process-steps { grid-template-columns: repeat(4, 1fr); }
}

.process-step {
  padding-top: var(--space-md);
  border-top: 1px solid var(--color-border);
}

.process-step h4 {
  font-family: var(--font-display);
  font-size: var(--text-xl);
  font-weight: 500;
  margin-bottom: var(--space-xs);
}

.process-step p {
  font-size: var(--text-sm);
  color: var(--color-text-mid);
  line-height: 1.65;
}


/* ============================================================
   PORTFOLIO OVERVIEW PAGE: PROJECT GRID
   ============================================================ */
.portfolio-grid-section {
  padding: var(--space-3xl) 0 var(--space-4xl);
}

.portfolio-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-lg);
}

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

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

.portfolio-card {
  display: block;
  text-decoration: none;
  border-radius: var(--radius-lg);
  overflow: hidden;
  transition: transform var(--duration-base) var(--ease-out);
}

.portfolio-card:hover {
  transform: translateY(-4px);
}

/* Each card's photo is a real <img> (or .img-placeholder) inside
   .portfolio-card-image-wrap, generated from config by build.js. */
.portfolio-card-image {
  display: block;
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  background-color: var(--color-bg-deep);
  transition: transform var(--duration-slow) var(--ease-out);
}

.portfolio-card:hover .portfolio-card-image {
  transform: scale(1.03);
}

.portfolio-card-image-wrap {
  overflow: hidden;
  border-radius: var(--radius-lg);
}

.portfolio-card-body {
  padding: var(--space-md) 0 0;
}

.portfolio-card-category {
  font-family: var(--font-body);
  font-size: 0.6875rem;
  font-weight: 500;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--color-text-light);
  margin-bottom: 0.25rem;
}

.portfolio-card-title {
  font-family: var(--font-display);
  font-size: var(--text-2xl);
  font-weight: 500;
  color: var(--color-text);
  line-height: 1.2;
  margin-bottom: 0.125rem;
}

.portfolio-card-location {
  font-size: var(--text-sm);
  color: var(--color-text-mid);
}


/* ============================================================
   PROJECT CASE-STUDY PAGES
   ============================================================ */

/* @critical:start */
/* Project hero — full-width image with title overlay */
.project-hero {
  position: relative;
  min-height: 60vh;       /* fallback for browsers without dvh */
  min-height: 60dvh;
  display: flex;
  align-items: flex-end;
  padding: calc(var(--space-4xl) + 2rem) 0 var(--space-2xl);
  overflow: hidden;
}

/* Project hero photograph is a real <img> inside .project-hero-media. */
.project-hero-media {
  position: absolute;
  inset: 0;
  z-index: 0;
  background-color: var(--color-bg-deep);
}

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

.project-hero-media::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(to top, rgba(44,49,40,0.75) 0%, rgba(44,49,40,0.15) 50%, rgba(44,49,40,0.05) 100%);
}

.project-hero-content {
  position: relative;
  z-index: 1;
}

.project-hero-category {
  font-family: var(--font-body);
  font-size: 0.6875rem;
  font-weight: 500;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: rgba(232, 234, 228, 0.65);
  margin-bottom: var(--space-sm);
}

.project-hero h1 {
  color: var(--color-white);
  margin-bottom: var(--space-xs);
  padding-bottom: 0.1em;
}

.project-hero-location {
  font-size: var(--text-lg);
  color: rgba(232, 234, 228, 0.7);
}
/* @critical:end */

/* Project meta bar */
.project-meta {
  padding: var(--space-lg) 0;
  border-bottom: 1px solid var(--color-border);
}

.project-meta-inner {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-xl);
}

.project-meta-item {
  min-width: 0;
}

.project-meta-label {
  font-size: var(--text-xs);
  font-weight: 500;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--color-text-light);
  margin-bottom: 0.125rem;
}

.project-meta-value {
  font-size: var(--text-sm);
  color: var(--color-text);
}

/* Project body — narrative sections */
.project-body {
  padding: var(--space-3xl) 0 var(--space-4xl);
}

.project-narrative {
  max-width: var(--max-width-narrow);
  margin-inline: auto;
  margin-bottom: var(--space-3xl);
}

.project-narrative h2 {
  margin-bottom: var(--space-md);
}

.project-narrative p {
  color: var(--color-text-mid);
  margin-bottom: var(--space-md);
  font-size: var(--text-lg);
  line-height: 1.75;
}

/* Project: image grid (2-up or full-width) */
.project-images {
  margin-bottom: var(--space-3xl);
}

.project-images-2up {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-sm);
}

@media (min-width: 640px) {
  .project-images-2up { grid-template-columns: 1fr 1fr; }
}

/* Project images — use <img> tags with these wrapper classes */
.project-img {
  width: 100%;
  height: auto;
  border-radius: var(--radius-lg);
  display: block;
  object-fit: cover;
}

.project-img.landscape-wide {
  aspect-ratio: 16 / 9;
}

.project-img.standard {
  aspect-ratio: 4 / 3;
}

/* Fallback placeholder for images not yet replaced */
.project-img-placeholder {
  aspect-ratio: 4 / 3;
  border-radius: var(--radius-lg);
  background: linear-gradient(135deg, #6a7a5e, #4a5a3e, #8a9a7e);
  overflow: hidden;
}

.project-img-placeholder.landscape-wide {
  aspect-ratio: 16 / 9;
}

/* Before & After */
.project-before-after {
  margin-bottom: var(--space-3xl);
}

.project-before-after h2 {
  margin-bottom: var(--space-lg);
  max-width: var(--max-width-narrow);
  margin-inline: auto;
}

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

.before-after-item {
  border-radius: var(--radius-md);
  overflow: hidden;
}

.before-after-img {
  width: 100%;
  aspect-ratio: 3 / 2;
  object-fit: cover;
  display: block;
}

.before-after-img.before {
  filter: saturate(0.6);
}

.before-after-label {
  padding: var(--space-xs) var(--space-sm);
  font-size: var(--text-xs);
  font-weight: 500;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--color-text-mid);
}

/* Project: client testimonial */
.project-testimonial {
  padding: var(--space-3xl) 0;
  background-color: var(--color-bg-alt);
}

.project-testimonial-inner {
  max-width: 640px;
  margin-inline: auto;
  text-align: center;
}

.project-testimonial blockquote {
  font-family: var(--font-display);
  font-size: clamp(var(--text-xl), 2.5vw, var(--text-3xl));
  font-weight: 400;
  font-style: italic;
  line-height: 1.45;
  margin-bottom: var(--space-md);
  padding-bottom: 0.15em;
}

.project-testimonial .testimonial-attr {
  font-size: var(--text-sm);
  color: var(--color-text-mid);
}

.project-testimonial .testimonial-attr strong {
  color: var(--color-text);
  font-weight: 500;
}

/* Project: next project link */
.project-next {
  padding: var(--space-2xl) 0;
  border-top: 1px solid var(--color-border);
  text-align: center;
}

.project-next p {
  font-size: var(--text-sm);
  color: var(--color-text-light);
  margin-bottom: var(--space-xs);
}

.project-next a {
  font-family: var(--font-display);
  font-size: var(--text-3xl);
  font-weight: 500;
  color: var(--color-text);
  transition: color var(--duration-fast) var(--ease-out);
}

.project-next a:hover {
  color: var(--color-accent);
}


/* ============================================================
   CONTACT PAGE
   ============================================================ */
.contact-section {
  padding: var(--space-3xl) 0 var(--space-4xl);
}

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

@media (min-width: 768px) {
  .contact-grid {
    grid-template-columns: 5fr 7fr;
    gap: var(--space-3xl);
  }
}

.contact-info h2 {
  margin-bottom: var(--space-md);
}

.contact-info > p {
  color: var(--color-text-mid);
  margin-bottom: var(--space-lg);
  max-width: 40ch;
}

.contact-detail {
  margin-bottom: var(--space-sm);
}

.contact-detail-label {
  font-size: var(--text-xs);
  font-weight: 500;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--color-text-light);
  margin-bottom: 0.25rem;
}

.contact-detail-value {
  color: var(--color-text);
  font-size: var(--text-base);
}

.contact-detail-value a {
  transition: color var(--duration-fast) var(--ease-out);
}

.contact-detail-value a:hover {
  color: var(--color-accent);
}

/* Form */
.contact-form {
  display: flex;
  flex-direction: column;
  gap: var(--space-md);
}

.form-group {
  display: flex;
  flex-direction: column;
  gap: 0.375rem;
}

.form-group label {
  font-size: var(--text-sm);
  font-weight: 500;
  color: var(--color-text);
}

.form-group input,
.form-group select,
.form-group textarea {
  font-family: var(--font-body);
  font-size: var(--text-base);
  padding: 0.75rem 1rem;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-white);
  color: var(--color-text);
  transition: border-color var(--duration-fast) var(--ease-out);
}

.form-group input::placeholder,
.form-group textarea::placeholder {
  color: var(--color-text-light);
}

.form-group input:focus,
.form-group select:focus,
.form-group textarea:focus {
  outline: none;
  border-color: var(--color-accent);
  box-shadow: 0 0 0 3px rgba(107, 122, 94, 0.12);
}

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

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

@media (min-width: 640px) {
  .form-row { grid-template-columns: 1fr 1fr; }
}

.form-submit {
  margin-top: var(--space-xs);
  align-self: flex-start;
}

/* Honeypot — visually and semantically hidden, but present for bots.
   Not display:none (some bots skip those); pushed offscreen instead. */
.hp-field {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* Inline form status message (demo notice / success / error) */
.form-status {
  font-size: var(--text-sm);
  line-height: 1.5;
  color: var(--color-text-mid);
}

.form-status:empty {
  display: none;
}

.form-status.is-success {
  color: var(--color-accent-hover);
}

.form-status.is-error {
  color: #a1443a;
}


/* ============================================================
   IMAGE PLACEHOLDER
   Neutral treatment shown when a configured image slot has no
   source file. Accessible (carries the intended alt as aria-label).
   ============================================================ */
.img-placeholder {
  width: 100%;
  height: 100%;
  min-height: 120px;
  display: flex;
  align-items: center;
  justify-content: center;
  background:
    repeating-linear-gradient(135deg, rgba(255,255,255,0.04) 0 12px, transparent 12px 24px),
    linear-gradient(160deg, var(--color-accent), var(--color-bg-deep));
  color: rgba(255, 255, 255, 0.55);
}

.img-placeholder::after {
  content: '';
  width: 28px;
  height: 28px;
  border-radius: 50%;
  border: 2px solid currentColor;
  opacity: 0.5;
}


/* ============================================================
   FAQ SECTION (GEO / answer-engine friendly)
   ============================================================ */
.faq-section {
  padding: var(--space-3xl) 0 var(--space-4xl);
}

.faq-section > .container > h2 {
  margin-bottom: var(--space-2xl);
}

.faq-list {
  max-width: var(--max-width-narrow);
  margin-inline: auto;
}

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

.faq-item:last-child {
  border-bottom: 1px solid var(--color-border);
}

.faq-item h3 {
  font-size: var(--text-xl);
  margin-bottom: var(--space-sm);
}

.faq-item p {
  color: var(--color-text-mid);
  max-width: 62ch;
}

/* Compact homepage variant — a 3-question teaser near the CTA. */
.faq-section--home {
  padding: var(--space-3xl) 0;
  background-color: var(--color-bg-alt);
}

.faq-section--home > .container > h2 {
  text-align: center;
}

.faq-section--home .faq-list {
  margin-bottom: 0;
}


/* ============================================================
   HOME CTA STRIP — optional decorative photograph background
   ============================================================ */
.cta-strip--feature {
  position: relative;
  overflow: hidden;
}

.cta-strip--feature[style*="background-image"] {
  background-size: cover;
  background-position: center;
  color: var(--color-text-on-dark);
}

.cta-strip--feature[style*="background-image"]::before {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(to top, rgba(44,49,40,0.82), rgba(44,49,40,0.62));
  z-index: 0;
}

.cta-strip--feature[style*="background-image"] > .container {
  position: relative;
  z-index: 1;
}

.cta-strip--feature[style*="background-image"] h2 {
  color: var(--color-white);
}

.cta-strip--feature[style*="background-image"] p {
  color: rgba(232, 234, 228, 0.85);
}


/* ============================================================
   THANK-YOU PAGE
   ============================================================ */
.thankyou-section {
  padding: var(--space-3xl) 0 var(--space-4xl);
}

.thankyou-inner {
  max-width: var(--max-width-narrow);
  margin-inline: auto;
}

.thankyou-inner > p {
  font-size: var(--text-lg);
  color: var(--color-text-mid);
  margin-bottom: var(--space-lg);
}

.thankyou-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-md);
  margin-bottom: var(--space-xl);
}

.thankyou-contact {
  font-size: var(--text-sm);
  color: var(--color-text-light);
}

.thankyou-contact a {
  color: var(--color-accent);
}


/* @critical:start */
/* ============================================================
   DEMO WATERMARK
   Fixed footer banner shown only when demo.isDemo is true.
   ============================================================ */
.demo-watermark {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  z-index: 200;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: center;
  gap: 0.25rem 0.75rem;
  padding: 0.6rem 1rem;
  background: rgba(44, 49, 40, 0.94);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  color: var(--color-text-on-dark);
  font-family: var(--font-body);
  font-size: var(--text-xs);
  text-align: center;
  border-top: 1px solid rgba(255, 255, 255, 0.12);
}

.demo-watermark strong {
  font-weight: 600;
  color: var(--color-white);
}

.demo-watermark .demo-watermark-expiry {
  opacity: 0.7;
}

/* Keep the fixed watermark from covering page-bottom content */
body.has-demo-watermark {
  padding-bottom: 3.25rem;
}
/* @critical:end */
