/* ==========================================================================
   site.css — per-site layout & components, built FROM tokens.

   HARD RULE (house-tech-spec §3): no raw hex, no px/rem size literals, no
   font-name literals in this file. Tokens only.
   ========================================================================== */

/* --- Layout primitives ---------------------------------------------------- */

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

/* Vertical rhythm hook. --section-gap is the only inter-section spacing value
   on a site (design-rules §7.1); the brief picks which scale step it is. */
.section {
  padding-block: var(--section-gap);
}

/* band-rhythm's alternating full-width bands (brief §3, design-rules §7):
   every other band sits on the surface ground instead of the page ground. */
.section--surface {
  background-color: var(--color-surface);
}

.measure {
  max-width: var(--layout-measure);
}

.container.container--narrow {
  max-width: var(--layout-measure);
}

/* --- Shared label device: eyebrows share one uppercase, tracked, growth-
   coloured treatment — the anchor's copy-role carrier (brief §2.1: "green
   and growth" in eyebrow, ratio labels, plan-line, focus ring). Natural case
   in the DOM, uppercased with text-transform (spec §8). ------------------- */

.eyebrow {
  display: block;
  font-family: var(--font-display);
  font-size: var(--text-eyebrow);
  font-weight: var(--font-weight-brand);
  line-height: var(--leading-eyebrow);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--color-growth);
  margin-block-end: var(--space-2xs);
}

.section__head {
  margin-block-end: var(--space-lg);
}

.section__head h2 {
  font-size: var(--text-h2);
  margin-block-start: 0;
}

/* --- Header & navigation --------------------------------------------------
   Progressive enhancement: with JS off the nav list is a plain, always-visible
   list of links and the toggle stays [hidden]. With JS on, narrow viewports
   collapse the list behind the toggle. */

.site-header {
  position: relative;
  z-index: var(--z-header);
  padding-block: var(--space-sm);
  border-bottom: var(--border-hairline) var(--border-style) var(--color-border);
  background-color: var(--color-bg);
}

.site-header__inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-sm);
}

.site-header__brand {
  font-family: var(--font-display);
  /* CLS/overflow fix (self-check, this build): "Innovative Landscape
     Design" (27 characters) at --text-h3 measures ~301px, which plus the
     nav-toggle button (~64px) and their gap overruns the ~335px content
     width available at 375px (and the ~320px available at the brief's own
     360px check, §3 item 1's "no nav overflow risk at 360px"), wrapping the
     header row onto two lines the moment main.js un-hides the toggle — a
     real, measured layout shift (header height 77px -> 137px), not a
     flake. --text-body measures ~222px for this business's name, well
     inside budget at both widths with the toggle beside it; --text-h3
     returns once the toggle is hidden at >=48em, where this row only ever
     holds the wordmark. */
  font-size: var(--text-body);
  font-weight: var(--font-weight-display);
  text-decoration: none;
  letter-spacing: var(--tracking-tight);
  color: var(--color-ink);
}

@media (min-width: 48em) {
  .site-header__brand {
    font-size: var(--text-h3);
  }
}

.nav-toggle {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2xs);
  padding: var(--space-2xs) var(--space-xs);
  /* Hairline-only control boundary: WCAG 1.4.11, >= 3:1. */
  border: var(--border-hairline) var(--border-style) var(--color-border-strong);
  border-radius: var(--radius-sm);
  font-family: var(--font-display);
  font-size: var(--text-small);
  font-weight: var(--font-weight-brand);
  color: var(--color-ink);
}

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

.site-nav__link {
  display: inline-flex;
  align-items: center;
  text-decoration: none;
  font-family: var(--font-display);
  font-size: var(--text-small);
  font-weight: var(--font-weight-brand);
  color: var(--color-ink);
}

.site-nav__link:hover,
.site-nav__link:focus-visible {
  text-decoration: underline;
  text-underline-offset: var(--space-3xs);
}

/* QA r3 FIX perf/cls (house skeleton defect, present on every prior build
   from it): the collapsed state used to apply only once a deferred
   `type="module"` script called `initNav()`, so the full nav list rendered
   open at first paint and then collapsed into the hamburger AFTER first
   contentful paint. Inverting the default removes the race entirely: closed
   is the plain CSS default below 48em, no JS gate. The <noscript> override in
   @shared:head-boilerplate restores it for JS-off visitors. */
.site-nav {
  display: none;
}

[data-nav-ready] .site-nav[data-nav-open='true'] {
  display: block;
  flex-basis: 100%;
}

@media (min-width: 48em) {
  .site-nav {
    display: block;
  }

  [data-nav-ready] .nav-toggle {
    display: none;
  }
}

/* --- Buttons --------------------------------------------------------------
   Two roles, no more. */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2xs);
  /* @allow-literal: brief §2.3's em-based ornament check — .85em/1.3em computed against Public Sans 600's real vertical metrics at --text-small, not a spacing-scale value */
  padding: .85em 1.3em;
  border: var(--border-hairline) var(--border-style) transparent;
  border-radius: var(--radius-sm);
  font-family: var(--font-display);
  font-size: var(--text-small);
  font-weight: var(--font-weight-brand);
  line-height: var(--leading-snug);
  text-align: center;
  text-decoration: none;
  transition: background-color var(--duration-fast) var(--ease-out),
              color var(--duration-fast) var(--ease-out),
              border-color var(--duration-fast) var(--ease-out);
}

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

.btn--quiet {
  /* Outline button: the border is the whole control, so it takes the 3:1
     control-boundary token (WCAG 1.4.11). */
  border-color: var(--color-border-strong);
  color: var(--color-ink);
  /* @allow-literal: brief §2.3's em-based ornament check — .8em/1.2em computed against Public Sans 600's real vertical metrics at --text-small, not a spacing-scale value */
  padding: .8em 1.2em;
}

/* --- Form -----------------------------------------------------------------
   One form per site (spec §6). Skeleton's default name/phone/message shape
   only — no reserved field added. */

.form {
  display: grid;
  gap: var(--space-md);
  max-width: var(--layout-measure);
  margin-block-start: var(--space-lg);
}

.field {
  display: grid;
  gap: var(--space-3xs);
}

.field__label {
  font-family: var(--font-display);
  font-size: var(--text-small);
  font-weight: var(--font-weight-brand);
  color: var(--color-ink);
}

.field__control {
  width: 100%;
  min-height: var(--layout-tap-min);
  padding: var(--space-2xs) var(--space-xs);
  background-color: var(--color-bg);
  color: var(--color-ink);
  border: var(--border-hairline) var(--border-style) var(--color-border-strong);
  border-radius: var(--radius-sm);
  font-family: var(--font-body);
}

textarea.field__control {
  min-height: var(--space-3xl);
  resize: vertical;
}

.field__hint {
  font-size: var(--text-small);
  color: var(--color-ink-muted);
}

.form__trap {
  position: absolute;
  /* @allow-literal: off-canvas parking position, not a design value */
  left: -9999px;
  opacity: 0;
  pointer-events: none;
}

.form__status {
  font-size: var(--text-small);
  color: var(--color-ink-muted);
}

.form__status[data-state='error'] {
  color: var(--color-ink);
  font-weight: var(--font-weight-body-strong);
}

.quote__secondary {
  margin-block-start: var(--space-md);
  color: var(--color-ink-muted);
}

/* --- Footer ---------------------------------------------------------------- */

.site-footer {
  padding-block: var(--space-xl);
  border-top: var(--border-hairline) var(--border-style) var(--color-border);
  font-size: var(--text-small);
  color: var(--color-ink-muted);
}

.site-footer a {
  color: var(--color-ink);
  text-underline-offset: var(--space-3xs);
}

.site-footer__nap {
  font-style: normal;
  color: var(--color-ink);
  margin-block-end: var(--space-sm);
}

.site-footer__area {
  margin-block-end: var(--space-2xs);
}

/* ==========================================================================
   BRIEF COMPONENTS — ild-innovative-landscape-florence-sc, brief.md v1 (C3
   approved 2026-09-15). clean-clinical / band-rhythm. Tokens only, spec §3.
   ========================================================================== */

/* --- Hero (brief §3/§4/§6) ----------------------------------------------
   House order: eyebrow -> h1 -> primary CTA -> field -> lead -> facts. CSS
   grid named areas keep that DOM order at every width; only the visual
   placement changes at >=48em. --------------------------------------- */

.hero {
  padding-block-end: var(--section-gap);
}

.hero__grid {
  display: grid;
  grid-template-areas:
    'eyebrow'
    'h1'
    'cta'
    'field'
    'lead'
    'facts';
  row-gap: var(--space-sm);
  padding-block-start: var(--space-md);
}

.hero__eyebrow {
  grid-area: eyebrow;
  margin-block-end: 0;
}

.hero__title {
  grid-area: h1;
  font-size: var(--text-hero);
  letter-spacing: var(--tracking-tight);
  color: var(--color-ink);
  margin-block-end: 0;
}

.hero__act {
  grid-area: cta;
  margin-block: 0;
}

.hero__field {
  grid-area: field;
  position: relative;
  overflow: hidden;
  border-radius: var(--radius-sm);
  background-color: var(--color-field-placeholder);
  aspect-ratio: var(--hero-field-ratio);
}

/* The living-hero "atmosphere" (design-rules §0): a soft radial glow behind
   the generated asset rather than a flat ground, in the anchor's own hue. */
.hero__field::before {
  content: '';
  position: absolute;
  /* @allow-literal: bleed beyond the field so the glow has no hard edge */
  inset: -15%;
  background: radial-gradient(circle at 50% 28%,
    color-mix(in srgb, var(--color-growth) 20%, transparent) 0%,
    transparent 68%);
  z-index: var(--z-base);
}

.hero__field picture,
.hero__field img {
  position: relative;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.hero__overlay {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
}

.plan-line {
  stroke-dasharray: 300;
  stroke-dashoffset: 0;
}

.plan-node {
  fill: var(--color-growth);
}

.sprig-group {
  /* @allow-literal: SVG transform-origin in the overlay's own viewBox units, not a design token */
  transform-origin: 34px 150px;
}

@media (prefers-reduced-motion: no-preference) {
  .plan-line {
    stroke-dashoffset: 300;
    animation: draw-plan-line var(--duration-plan-draw) var(--ease-out) forwards;
  }

  .plan-node {
    opacity: 0;
    animation: node-settle var(--duration-fast) var(--ease-out) var(--duration-plan-draw) forwards;
  }

  .sprig-group {
    animation: sprig-sway var(--loop-sprig-sway) var(--ease-in-out) infinite alternate;
  }
}

@keyframes draw-plan-line {
  to {
    stroke-dashoffset: 0;
  }
}

@keyframes node-settle {
  to {
    opacity: 1;
  }
}

@keyframes sprig-sway {
  from {
    transform: rotate(-3deg);
  }
  to {
    transform: rotate(4deg);
  }
}

.hero__lead {
  grid-area: lead;
  font-family: var(--font-body);
  font-size: var(--text-lead);
  line-height: var(--leading-snug);
  color: var(--color-ink);
  max-width: var(--layout-measure);
  margin-block-end: 0;
}

.hero__facts {
  grid-area: facts;
  font-size: var(--text-small);
  color: var(--color-ink-muted);
  border-block-start: var(--border-hairline) var(--border-style) var(--color-border);
  padding-block-start: var(--space-xs);
  margin-block-end: 0;
}

@media (min-width: 48em) {
  .hero__grid {
    grid-template-columns: 3fr 2fr;
    column-gap: var(--space-xl);
    align-items: center;
    grid-template-areas:
      'eyebrow field'
      'h1      field'
      'cta     field'
      'lead    field'
      'facts   field';
  }
}

/* --- Trust-strip (brief §3, item 3) -------------------------------------- */

.trust-panel {
  background-color: var(--color-bg);
  border: var(--border-hairline) var(--border-style) var(--color-border);
  border-radius: var(--radius-sm);
}

.trust-row {
  padding: var(--space-md) var(--space-lg);
  border-block-end: var(--border-hairline) var(--border-style) var(--color-border);
}

.trust-row:last-child {
  border-block-end: none;
}

.trust-row__title {
  font-family: var(--font-display);
  font-weight: var(--font-weight-body-strong);
  color: var(--color-ink);
  margin-block-end: var(--space-3xs);
}

.trust-row__body {
  color: var(--color-ink-muted);
  margin-block-end: 0;
}

/* --- Services (brief §3, item 4, load-bearing) --------------------------- */

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

.service-card {
  background-color: var(--color-surface);
  border: var(--border-hairline) var(--border-style) var(--color-border);
  border-radius: var(--radius-sm);
  padding: var(--space-lg);
}

.service-card__tag {
  display: inline-block;
  font-family: var(--font-display);
  font-size: var(--text-eyebrow);
  font-weight: var(--font-weight-brand);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--color-accent);
  margin-block-end: var(--space-xs);
}

.service-card__media {
  width: var(--size-study-sm);
  aspect-ratio: 1;
  border-radius: var(--radius-sm);
  overflow: hidden;
  margin-block-end: var(--space-sm);
}

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

.service-card__name {
  font-size: var(--text-h3);
  margin-block-end: var(--space-2xs);
}

.service-card__body {
  color: var(--color-ink-muted);
  margin-block-end: 0;
}

@media (min-width: 48em) {
  .services-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (min-width: 64em) {
  .services-grid {
    grid-template-columns: repeat(3, 1fr);
  }
}

/* --- Mid-page CTA band (brief §3, item 5) — the site's one display-feature
   type moment. ------------------------------------------------------------ */

.cta-band {
  text-align: center;
}

.cta-band__title {
  font-family: var(--font-display);
  font-size: var(--text-display-feature);
  font-weight: var(--font-weight-display);
  letter-spacing: var(--tracking-tight);
  color: var(--color-ink);
  margin-block-end: var(--space-sm);
}

.cta-band__body {
  color: var(--color-ink-muted);
  max-width: var(--layout-measure);
  margin-inline: auto;
  margin-block-end: var(--space-lg);
}

.cta-band__actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--space-sm);
}

/* --- Process (brief §3, item 6) — reuses the hero's plan-node motif,
   static, as each step's marker (brief §3.1). ----------------------------- */

.process-grid {
  display: grid;
  gap: var(--space-lg);
}

.process-step__marker {
  width: var(--size-node);
  height: var(--size-node);
  margin-block-end: var(--space-xs);
  fill: var(--color-growth);
}

.process-step h3 {
  font-size: var(--text-h3);
  margin-block-end: var(--space-2xs);
}

.process-step p {
  color: var(--color-ink-muted);
  margin-block-end: 0;
}

.process-motif {
  width: var(--size-motif-process);
  aspect-ratio: 1;
  margin-block-start: var(--space-lg);
  border-radius: var(--radius-sm);
  overflow: hidden;
}

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

@media (min-width: 48em) {
  .process-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

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

/* --- Reviews (brief §3, item 7, load-bearing) ---------------------------- */

.review-grid {
  display: grid;
  gap: var(--space-md);
}

.review-card {
  margin: 0;
  background-color: var(--color-bg);
  border: var(--border-hairline) var(--border-style) var(--color-border);
  border-radius: var(--radius-sm);
  padding: var(--space-lg);
}

.review-card__quote {
  font-size: var(--text-lead);
  line-height: var(--leading-snug);
  color: var(--color-ink);
  margin-block-end: var(--space-sm);
}

.review-card__attribution {
  display: block;
  font-style: normal;
  font-weight: var(--font-weight-body-strong);
  font-size: var(--text-small);
  color: var(--color-ink-muted);
}

.review-tally {
  margin-block-start: var(--space-lg);
  font-size: var(--text-small);
  color: var(--color-ink-muted);
}

@media (min-width: 48em) {
  .review-grid {
    grid-template-columns: repeat(3, 1fr);
  }
}

/* --- FAQ (brief §3, item 8) ------------------------------------------------ */

.faq-list {
  display: grid;
  gap: 0;
  margin: 0;
}

.faq-item {
  padding-block: var(--space-md);
  border-block-end: var(--border-hairline) var(--border-style) var(--color-border);
}

.faq-item:first-child {
  border-block-start: var(--border-hairline) var(--border-style) var(--color-border);
}

.faq-question {
  font-family: var(--font-display);
  font-weight: var(--font-weight-body-strong);
  color: var(--color-ink);
  margin-block-end: var(--space-2xs);
}

.faq-answer {
  margin: 0;
  color: var(--color-ink-muted);
}
