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

   band-rhythm (design-rules §7; brief §5): alternating full-width bands —
   light ground (bg) <-> raised surface (surface), never two identical
   grounds adjacent (brief §5.1 rule 1). Every band opens with the same
   object, the ring mark (brief §5.1 rule 2) — one geometry, two jobs: the
   hero's own living moment (the generated badge, "the badge holds") and the
   page's own navigational spine, flattened to a static 28px mark at every
   section head.

   Section ground order (alternating, hero exempt as its own gradient/field
   hybrid): services=surface, trust=bg, book=surface (brief §6.5, explicit),
   process=bg, reviews=surface (brief §6.7's "light ground", i.e. not the
   dark band — surface qualifies), area=bg, faq=surface, contact=bg.
   ========================================================================== */

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

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

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

.section--surface {
  background-color: var(--color-surface);
}

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

/* --- Section head — the ring mark, brief §5.1 rule 2 / §5.4 ---------------
   "Every band opens with the same object: the ring mark." Ring -> eyebrow
   12px, eyebrow -> h1/h2 12px (brief §5.5) — every section head, hero
   included. The ring mark is 28px at every width by construction; nothing
   yields it except its inner glyph detail below 320px (brief §5.2). */

.section__head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
}

.section__head > * {
  flex: 0 0 100%;
}

.section__head > * + * {
  margin-block-start: var(--space-xs);
}

.ring-mark {
  inline-size: var(--ring-mark-size);
  block-size: var(--ring-mark-size);
  flex: none;
}

/* Below 320px of available width the ring mark's own crossed-tool detail
   yields — it becomes a plain accent-coloured dot rather than shrinking
   past legible detail (brief §5.2's yield order, §5.4). */
@media (max-width: 20em) {
  .ring-mark circle,
  .ring-mark line {
    display: none;
  }

  .ring-mark {
    border-radius: 50%;
    background-color: var(--color-accent);
  }
}

.section__eyebrow {
  margin: 0;
  font-family: var(--font-body-strong);
  font-weight: var(--font-weight-body-strong);
  font-size: var(--text-eyebrow);
  line-height: var(--leading-caps);
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--color-ink-muted);
}

.section__title {
  margin: 0;
  font-family: var(--font-display);
  font-weight: var(--font-weight-display);
  font-size: var(--text-h2);
  line-height: var(--leading-tight);
  color: var(--color-ink);
}

/* Generic "section head -> content" gap — 24px, every section (brief §5.5). */
.section__head + * {
  margin-block-start: var(--space-md);
}

/* --- Header & navigation ---------------------------------------------------
   Brief §5.6: header is 60px at every width — padding-block 8px
   (--space-2xs) top and bottom around the 44px tel: CTA, the row's tallest
   element (8 + 44 + 8 = 60). Sticky beneath the expiry bar
   (css/preview.css's brief override). */

.site-header {
  position: relative;
  z-index: var(--z-header);
  padding-block: var(--space-2xs);
  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);
  font-weight: var(--font-weight-display);
  font-size: var(--text-lead);
  color: var(--color-ink);
  text-decoration: none;
  letter-spacing: var(--tracking-display);
}

.nav-toggle {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2xs);
  padding: var(--space-2xs) var(--space-xs);
  /* The nav-toggle's only shape is this hairline, so it is a CONTROL
     boundary (WCAG 1.4.11, >= 3:1), not a decorative one. */
  border: var(--border-hairline) var(--border-style) var(--color-border-strong);
  border-radius: var(--radius-sm);
  font-family: var(--font-body-strong);
  font-size: var(--text-small);
  font-weight: var(--font-weight-body-strong);
  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-body-strong);
  font-size: var(--text-small);
  font-weight: var(--font-weight-body-strong);
  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 pattern, kept from the skeleton): closed is the
   plain CSS default below 48em, un-gated by [data-nav-ready], so the header
   never collapses AFTER first paint. JS-off visitors get the nav back via
   the <noscript> stylesheet override in @shared:head-boilerplate. */
.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 ---------------------------------------------------------------
   --radius-sm (2px) — a sign-painted board's square-ish edge. No drop
   shadow on any control (R9; --shadow-none is the only shadow token). */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2xs);
  padding: var(--space-xs) var(--space-md);
  border: var(--border-hairline) var(--border-style) transparent;
  border-radius: var(--radius-sm);
  font-family: var(--font-body-strong);
  font-weight: var(--font-weight-body-strong);
  font-size: var(--text-small);
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  line-height: var(--leading-snug);
  text-align: center;
  text-decoration: none;
  box-shadow: var(--shadow-none);
  transition: background-color var(--duration-fast) var(--ease-out),
              color var(--duration-fast) var(--ease-out);
}

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

.btn--quiet {
  border-color: var(--color-border-strong);
  color: var(--color-ink);
}

/* --- Hero — §I hero-call ----------------------------------------------------
   The ask zone (ring mark -> eyebrow -> h1 -> primary CTA) sits on the
   hero's own CSS radial-gradient atmosphere (brief §4.3, R1) — never a
   photograph. The field zone below carries its own flat --color-surface
   local ground, fully opaque, so the gradient's lower stops are never seen
   behind text. Never a reveal target — it is the LCP element. */

.hero {
  padding-block-start: var(--hero-pad-top);
  padding-block-end: var(--section-gap);
  background: radial-gradient(
    120% 90% at 50% 0%,
    var(--color-hero-glow) 0%,
    var(--color-surface) 55%,
    var(--color-hero-shade) 100%
  );
}

.hero h1 {
  margin-block-start: var(--space-xs);
  margin-block-end: 0;
  font-size: var(--text-hero);
  max-width: var(--h1-max);
  color: var(--color-ink);
}

/* R4: the accent-coloured word inside the h1 renders at --text-hero scale
   only, never smaller (brief §4.3 — the 4.10:1 worst-case measurement is
   only valid at that scale). No italic clause — emphasis_font: null. */
.hero h1 em {
  font-style: normal;
  color: var(--color-accent);
}

.hero__cta {
  display: flex;
  width: 100%;
  margin-block-start: var(--space-sm);
}

@media (min-width: 48em) {
  .hero__cta {
    display: inline-flex;
    width: auto;
    min-width: var(--hero-cta-min-width);
  }
}

/* The hero field — image slot 1, the LCP element. Full-bleed to the
   viewport edge below 48rem (breaking out of .container's own gutter);
   contained to --hero-field-max, centred, at 48rem and up (brief §5.1 rule
   3). aspect-ratio is CONSTANT at every width (brief §5.2). Its own flat
   --color-surface local ground sits under the image (brief §4.3, §6.2). */
.hero__field-wrap {
  position: relative;
  margin-block-start: var(--space-md);
  aspect-ratio: var(--hero-field-ratio);
  overflow: hidden;
  background-color: var(--color-surface);
  /* @allow-literal: full-bleed breakout, structural geometry not a design value */
  width: 100vw;
  /* @allow-literal: full-bleed breakout, structural geometry not a design value */
  margin-inline-start: calc(50% - 50vw);
}

@media (min-width: 48em) {
  .hero__field-wrap {
    width: 100%;
    max-width: var(--hero-field-max);
    margin-inline: auto;
  }
}

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

/* The signature move — "the badge holds" (brief §8.2). On load, the badge
   settles into place: a short scale-and-rotate resolve over
   --duration-badge (760ms), beginning at a 160ms delay. */
.hero__badge-img {
  animation: hero-badge-settle var(--duration-badge) var(--ease-out) 160ms both;
  transform-origin: center;
}

@keyframes hero-badge-settle {
  0% { transform: scale(0.92) rotate(-3deg); }
  100% { transform: scale(1) rotate(0deg); }
}

/* Immediately after the badge settles (at 760ms = 160ms delay + 600ms of
   the 760ms duration having elapsed... measured from load: settle ends at
   160ms + 760ms = 920ms), a single thin highlight sweeps once across the
   brass ring: a 420ms opacity pulse along the ring's circumference, then
   holds its final resting position (fully transparent) for the rest of the
   visit. Positioned centred on the badge, proportional to the generated
   frame's own central-crop composition (brief §7.3 Block A: the badge sits
   centred in the central 65% of the frame). */
.hero__ring-sweep {
  position: absolute;
  inset: 0;
  margin: auto;
  width: 34%;
  aspect-ratio: 1 / 1;
  opacity: 0;
  animation: hero-ring-sweep 420ms ease-out 920ms 1;
}

@keyframes hero-ring-sweep {
  0%   { opacity: 0; transform: rotate(0deg); }
  40%  { opacity: 0.9; }
  100% { opacity: 0; transform: rotate(300deg); }
}

/* Ambient satellite motion — the hero field only (brief §8.3). Three loops,
   no two durations shared (17/21/26s — pairwise coprime, so the set never
   re-synchronises within any visit-length window). Positioned near the
   badge ring's upper-right arc (glints) and the generated frame's own
   background stack silhouette (ghost), proportional to the crop. */
.hero__glint {
  position: absolute;
  border-radius: 50%;
  background-color: var(--color-accent-ink);
  opacity: 0.2;
}

.hero__glint--1 {
  inset-block-start: 30%;
  inset-inline-start: 58%;
  /* @allow-literal: ring-glint size, brief §8.3 bespoke ambient device */
  width: 5px;
  /* @allow-literal: ring-glint size, brief §8.3 bespoke ambient device */
  height: 5px;
  animation: hero-glint-pulse 17s var(--ease-out) infinite;
}

.hero__glint--2 {
  inset-block-start: 34%;
  inset-inline-start: 61%;
  /* @allow-literal: ring-glint size, brief §8.3 bespoke ambient device */
  width: 4px;
  /* @allow-literal: ring-glint size, brief §8.3 bespoke ambient device */
  height: 4px;
  animation: hero-glint-pulse 21s var(--ease-out) infinite;
  animation-delay: -9s;
}

@keyframes hero-glint-pulse {
  0%, 100% { opacity: 0.2; }
  50%      { opacity: 0.75; }
}

.hero__stack-ghost {
  position: absolute;
  inset-block-start: 4%;
  inset-inline-start: 60%;
  /* @allow-literal: stack-ghost size, brief §8.3 bespoke ambient device, proportional to the generated frame's own background chimney silhouette */
  width: 18px;
  /* @allow-literal: stack-ghost size, brief §8.3 bespoke ambient device */
  height: 44px;
  opacity: 0.35;
  animation: hero-stack-drift 26s var(--ease-out) infinite;
}

@keyframes hero-stack-drift {
  0%, 100% { transform: translateX(0); }
  50% {
    /* @allow-literal: brief §8.3's exact stack-ghost drift value */
    transform: translateX(6px);
  }
}

@media (prefers-reduced-motion: reduce) {
  .hero__badge-img {
    animation: none;
    transform: scale(1) rotate(0deg);
  }

  .hero__ring-sweep {
    animation: none;
    opacity: 0;
  }

  .hero__glint {
    animation: none;
    opacity: 0.2;
  }

  .hero__stack-ghost {
    animation: none;
    transform: translateX(0);
  }
}

.hero__lead {
  margin-block-start: var(--space-md);
  font-size: var(--text-lead);
  line-height: var(--leading-snug);
  color: var(--color-ink);
  max-width: var(--layout-measure);
}

.hero__facts {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-sm) var(--space-md);
  margin: 0;
  margin-block-start: var(--space-sm);
  padding: 0;
  padding-block-start: var(--space-sm);
  border-block-start: var(--border-hairline) var(--border-style) var(--color-border);
  list-style: none;
  font-size: var(--text-small);
  color: var(--color-ink-muted);
}

/* --- Services — §II, a hairline index, never a card grid ------------------- */

.service-list {
  margin: 0;
  /* the largest intra-section gap, 40px (brief §5.5) — before the rows begin */
  margin-block-start: var(--space-lg);
  padding: 0;
  list-style: none;
  border-block-start: var(--border-hairline) var(--border-style) var(--color-border);
}

.service-list li {
  padding-block: var(--space-sm);
  border-block-end: var(--border-hairline) var(--border-style) var(--color-border);
  font-size: var(--text-body);
  color: var(--color-ink);
}

/* The hairline yields entirely below 240px of content width (brief §5.2's
   yield order) — every row is still fully readable without the divider. */
@media (max-width: 15em) {
  .service-list {
    border-block-start: 0;
  }

  .service-list li {
    border-block-end: 0;
  }
}

/* --- Section-foot figures — slots 2, 3, 4 (brief §7.2) ---------------------
   A single-column supporting accent, contained rather than full-bleed. */

.section-figure {
  margin-block-start: var(--space-lg);
  max-width: var(--figure-max-width);
}

.section-figure img {
  width: 100%;
  height: auto;
}

/* --- Trust-strip — §III, three factual tags --------------------------------
   --radius-md cards, --color-brass top-border ornament (never carrying
   text, R3), body text on --color-surface — a raised panel regardless of
   the section's own ground (brief §6.4). */

.trust-list {
  display: grid;
  gap: var(--space-md);
  margin: 0;
  /* the largest intra-section gap, 40px (brief §5.5) */
  margin-block-start: var(--space-lg);
  padding: 0;
  list-style: none;
}

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

.trust-tag {
  padding: var(--space-md);
  background-color: var(--color-surface);
  border-block-start: var(--border-thick) var(--border-style) var(--color-brass);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-none);
}

.trust-tag__kicker {
  margin: 0;
  font-family: var(--font-body-strong);
  font-weight: var(--font-weight-body-strong);
  font-size: var(--text-small);
  color: var(--color-ink);
}

.trust-tag__body {
  margin: 0;
  margin-block-start: var(--space-3xs);
  color: var(--color-ink-muted);
}

/* --- Process — §V, four steps, a distinct numeral system from the ring
   mark (design-rules §5's nested-counter rule): a plain 20px filled-circle
   digit, no crossed-tool glyph, no shared ornament with the ring mark. ---- */

.process-list {
  display: grid;
  gap: var(--space-md);
  margin: 0;
  margin-block-start: var(--space-md);
  padding: 0;
  list-style: none;
}

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

.process-step__num {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  /* @allow-literal: the process step's own numeral-circle size, distinct from --ring-mark-size by design (design-rules §5 nested-counter rule) */
  inline-size: 20px;
  /* @allow-literal: see above */
  block-size: 20px;
  border-radius: 50%;
  background-color: var(--color-accent);
  color: var(--color-accent-ink);
  font-family: var(--font-body-strong);
  font-weight: var(--font-weight-body-strong);
  font-size: var(--text-small);
}

.process-step p {
  margin: 0;
}

/* --- Reviews — §VI, light ground (surface), no dark band ------------------- */

.review-list {
  display: grid;
  gap: var(--space-lg);
  margin: 0;
  margin-block-start: var(--space-md);
  padding: 0;
  list-style: none;
}

.review {
  margin: 0;
}

.review__quote {
  margin: 0;
}

.review__quote p {
  margin: 0;
  font-size: var(--text-body);
  line-height: var(--leading-body);
}

.review__attribution {
  display: block;
  margin-block-start: var(--space-xs);
  font-family: var(--font-body-strong);
  font-weight: var(--font-weight-body-strong);
  font-size: var(--text-small);
  font-style: normal;
  color: var(--color-ink-muted);
}

/* --- FAQ — §VIII, native disclosure, no numeral ----------------------------- */

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

.faq-list li + li {
  /* the largest intra-section gap, 40px (brief §5.5) */
  margin-block-start: var(--space-lg);
}

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

.faq-item summary {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-sm);
  font-family: var(--font-body-strong);
  font-weight: var(--font-weight-body-strong);
  font-size: var(--text-body);
  color: var(--color-ink);
  cursor: pointer;
  list-style: none;
}

.faq-item summary::-webkit-details-marker {
  display: none;
}

.faq-item summary::after {
  content: '+';
  flex: none;
  color: var(--color-accent);
  font-family: var(--font-body-strong);
  font-weight: var(--font-weight-body-strong);
}

.faq-item[open] summary::after {
  content: '\2212';
}

.faq-item p {
  margin: 0;
  margin-block-start: var(--space-sm);
  color: var(--color-ink-muted);
}

/* --- Form -------------------------------------------------------------------
   One form per site. name / phone / message only (brief §6.11, R6). */

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

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

.field__label {
  font-family: var(--font-body-strong);
  font-size: var(--text-small);
  font-weight: var(--font-weight-body-strong);
  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-surface);
  color: var(--color-ink);
  /* 1.4.11-bound control edge — never the decorative --color-border. */
  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);
}

/* --- 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);
}

.site-footer__nap strong {
  font-family: var(--font-display);
  font-weight: var(--font-weight-display);
  font-size: var(--text-lead);
}

.site-footer p + p {
  margin-block-start: var(--space-2xs);
}

/* --- thanks.html — brief §5.6, "section rule -> ring mark -> eyebrow -> h2
   -> tel control -> lead", space-sm (16px) head -> tel control ----------- */

.section__head + .thanks__cta {
  margin-block-start: var(--space-sm);
}

.thanks__cta + p {
  margin-block-start: var(--space-md);
}
