/* ==========================================================================
   site.css — Culp Landscaping (Athens, GA). Built FROM tokens (spec §3). No
   raw hex/px/font literals — escape hatches: house breakpoints (48em/64em)
   and an explicit `@allow-literal: reason` comment on the preceding line.

   Archetype: tag-stack (brief §5.1) — a hand-labelled nursery tag hangs from
   twine in the hero, settles once, then sways on its own slow loop; the same
   device recurs static/shrunk as the three Services tag-cards. No third
   moment: season-strip/trust-strip/process/FAQ are calm, zero rotation/shadow.

   Structure below: skeleton shell primitives first (container, section
   rhythm, header/nav, buttons, form, footer), this brief's token values; the
   brief's own components (hero/tag-stack/season-strip/trust-strip/process/
   service-area/FAQ) after.
   ========================================================================== */

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

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

/* --- Header & nav (brief §5.3 step 1). <=56px + 1px border (brief §7). CTA
   is rectangular (--radius-sm), never a pill (brief §1, corrected at C4). */

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

.site-header__inner {
  block-size: 100%;
  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-size: var(--text-h3);
  font-weight: var(--font-weight-display);
  text-decoration: none;
  letter-spacing: var(--tracking-tight);
}

.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 — use --color-border-strong. */
  border: var(--border-hairline) var(--border-style) var(--color-border-strong);
  border-radius: var(--radius-sm);
  font-family: var(--font-body);
  font-size: var(--text-small);
  font-weight: var(--font-weight-body-strong);
}

.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);
  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);
}

/* House pattern (QA r3 FIX perf/cls): collapsed is the plain CSS default
   below 48em, no JS gate, so there is no post-paint collapse race. JS-off
   gets the nav back via the <noscript> 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: two roles, tokens only. 44px tall below 768, 50px at >=768
   (brief §7.1/§7.2). */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2xs);
  padding: var(--space-xs) var(--space-md);
  min-height: var(--cta-height);
  border: var(--border-hairline) var(--border-style) transparent;
  border-radius: var(--radius-sm);
  font-family: var(--font-body);
  font-weight: var(--font-weight-body-strong);
  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);
}

.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, not the decorative hairline (WCAG 1.4.11). */
  border-color: var(--color-border-strong);
  color: var(--color-ink);
}

/* --- Form: one per site (spec §6), plain HTML POST with JS off. */

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

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

.field__label {
  font-family: var(--font-body);
  font-weight: var(--font-weight-body-strong);
  font-size: var(--text-small);
  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);
  font-family: var(--font-body);
  border: var(--border-hairline) var(--border-style) var(--color-border);
  border-radius: var(--radius-sm);
}

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

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

/* Honeypot: present in the DOM for bots, unreachable for humans and assistive
   tech. Not display:none — some bots skip those. */
.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);
}

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

.site-footer__nap {
  font-style: normal;
}

/* --- Hero (brief §5.3 step 2, §7.1, §7.2). DOM order: eyebrow -> H1 ->
   primary CTA -> field (twine+tag+sprig) -> lead -> facts. Every gap is its
   own token (tokens.css's --hero-gap-* block) — each pair has a distinct
   measured value, not a uniform gap. */

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

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

.hero h1 {
  margin-block: var(--hero-gap-eyebrow-h1) 0;
  font-size: var(--text-hero);
  line-height: var(--leading-tight);
}

.hero__cta {
  margin-block: var(--hero-gap-h1-cta) 0;
}

/* The field: a scaling vector graphic (inline viewBox SVG, brief §7.3).
   Fixed height at every width; only position yields. The gradient is the
   largest concentration of the playbook §6.1 anchor hue in the hero frame
   (brief §4.5: 42.4% of the visible fold at 375px). */
.hero__field {
  position: relative;
  margin-block: var(--hero-gap-cta-field) 0;
  block-size: var(--field-height);
  inline-size: 100%;
  overflow: hidden;
  background: radial-gradient(120% 140% at 65% 15%,
    var(--color-boxwood-light) 0%, var(--color-boxwood) 45%, var(--color-ink) 100%);
}

.hero__field svg {
  position: absolute;
  inset: 0;
  inline-size: 100%;
  block-size: 100%;
}

.hero__lead {
  margin-block: var(--hero-gap-field-lead) 0;
  font-size: var(--text-lead);
  line-height: var(--leading-snug);
}

.hero__facts {
  margin-block: var(--hero-gap-lead-facts) 0;
  font-size: var(--text-small);
  line-height: var(--leading-caps);
  color: var(--color-ink-muted);
}

/* --- Hero satellite motion (brief §7.4/§8), unchanged from tile-c.html: twine
   draws once, tag settles (overshoot) then sways, sprig sways independently,
   un-synced timing — all tokenised (tokens.css), never raw here.
   Every SVG colour below is a class reading a token, never inline hex (spec
   §3): twine/tag string = hairline; tag = surface/border-strong (§4.3 row 2);
   marks = ink-muted; sprig = the two boxwood stops. */
.field__twine,
.field__tag-string {
  stroke: var(--color-border);
  fill: none;
}

.field__tag-rect {
  fill: var(--color-surface);
  stroke: var(--color-border-strong);
}

.field__tag-hole {
  fill: none;
  stroke: var(--color-border-strong);
}

.field__tag-mark {
  fill: none;
  stroke: var(--color-ink-muted);
  opacity: 0.55;
}

.field__sprig-stem {
  stroke: var(--color-boxwood);
  fill: none;
}

.field__sprig-leaf {
  fill: none;
  stroke: var(--color-boxwood-light);
}

.field__twine {
  /* @allow-literal: 210 is this path's own authored length in user units
     (the twine line runs x=60 to x=270 in the shared viewBox, i.e. 210 units
     long) — it is what stroke-dasharray/-offset must match to animate a
     draw-on of THIS path, and it cannot be expressed as a token because it
     is geometry, not styling. */
  stroke-dasharray: 210;
  stroke-dashoffset: 0;
}

.field__tag {
  transform-origin: var(--tag-transform-origin);
}

.field__sprig {
  transform-origin: var(--sprig-transform-origin);
}

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

  .field__tag {
    animation:
      tag-settle var(--duration-tag-settle) var(--ease-tag-settle) var(--delay-tag-settle) both,
      tag-sway var(--duration-tag-sway) ease-in-out var(--delay-tag-sway) infinite alternate;
  }

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

/* Reduced motion (spec §8): twine drawn immediately, tag/sprig at rest, no
   sway — C2-DECISION's verified PASS state. base.css's kill switch handles
   reveals; these three need their own rule. */
@media (prefers-reduced-motion: reduce) {
  .field__tag {
    transform: rotate(var(--tag-rest-rotate));
  }

  .field__sprig {
    transform: rotate(var(--sprig-rest-rotate));
  }
}

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

@keyframes tag-settle {
  0%   { transform: rotate(var(--tag-settle-start-rotate)) translateY(var(--tag-settle-start-y)); opacity: 0; }
  100% { transform: rotate(var(--tag-rest-rotate)) translateY(0); opacity: 1; }
}

@keyframes tag-sway {
  from { transform: rotate(var(--tag-rest-rotate)); }
  to   { transform: rotate(var(--tag-sway-rotate)); }
}

@keyframes sprig-sway {
  from { transform: rotate(var(--sprig-rest-rotate)); }
  to   { transform: rotate(var(--sprig-sway-rotate)); }
}

/* --- Section heads (shared across Services/season-strip/trust-strip/process/
   service-area/FAQ) --------------------------------------------------------- */

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

.section__body {
  margin-block: var(--space-sm) 0;
}

/* --- Services — tag-stack device, repeated static (brief §5.1, §5.3 step 3,
   §7.3) -------------------------------------------------------------------- */

.tag-stack {
  position: relative;
  margin-block-start: var(--space-lg);
}

/* A dashed line the cards visually hang from — decorative only, the
   letterpress-card register (ref-010), never a control boundary. */
.tag-stack::before {
  content: '';
  position: absolute;
  inset-block-start: 0;
  inset-inline: 0;
  border-block-start: var(--border-hairline) dashed var(--color-border-strong);
}

.tag-row {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--space-lg);
  margin-block: var(--space-lg) 0;
}

/* `.tag-card` carries data-reveal (stagger target, brief §8) and must have NO
   transform of its own — base.css's reveal translateY lives on this element,
   and CSS `transform` is not additive across rules. Permanent rotation lives
   one level down, on `.tag-card__face`, so the two never contend. */
.tag-card {
  inline-size: var(--tag-card-w);
}

.tag-card__face {
  background-color: var(--color-surface);
  border: var(--border-hairline) var(--border-style) var(--color-border);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow-sm);
  padding: var(--space-sm);
  text-align: center;
}

.tag-row .tag-card:nth-child(1) .tag-card__face { transform: rotate(var(--tag-rotate-1)); }
.tag-row .tag-card:nth-child(2) .tag-card__face { transform: rotate(var(--tag-rotate-2)); }
.tag-row .tag-card:nth-child(3) .tag-card__face { transform: rotate(var(--tag-rotate-3)); }

.tag-card__hole {
  display: block;
  inline-size: var(--space-2xs);
  block-size: var(--space-2xs);
  margin-inline: auto;
  margin-block-end: var(--space-xs);
  background-color: var(--color-bg);
  border: var(--border-hairline) var(--border-style) var(--color-border-strong);
  /* @allow-literal: the punched hole is round by definition of the craft
     device (ref-010, brief §1); it is not the site's uniform radius scale. */
  border-radius: 50%;
}

.tag-card__title {
  display: block;
  font-family: var(--font-body);
  font-weight: var(--font-weight-body-strong);
  font-size: var(--text-body);
  color: var(--color-ink);
}

.tag-card__sub {
  display: block;
  margin-block-start: var(--space-2xs);
  font-size: var(--text-small);
  color: var(--color-ink-muted);
}

/* Services decorative texture (imagery slot 1, brief §6) — the "hero-
   weighted" slot, echoing the hero's boxwood-to-clay palette. Decorative:
   aria-hidden, never competing with the tag-row's own device. */
.section__texture {
  display: block;
  margin-block-start: var(--space-lg);
  margin-inline: auto;
  inline-size: 100%;
  max-inline-size: calc(var(--space-3xl) * 2);
  overflow: hidden;
}

.section__texture img {
  display: block;
  inline-size: 100%;
  block-size: auto;
}

/* --- Season-strip (brief §5.3 step 4) — 4 unnumbered, plain surface cards.
   No rotation, no shadow: the tag-stack device is spent once, in the hero and
   Services (brief §5.1). ---------------------------------------------------- */

.season-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-sm);
  margin-block: var(--space-lg) 0;
}

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

.season-card {
  background-color: var(--color-surface);
  padding: var(--space-md);
}

.season-card h3 {
  margin-block: 0;
  font-size: var(--text-h3);
}

.season-card__tag {
  margin-block: var(--space-2xs) 0;
  font-family: var(--font-body);
  font-weight: var(--font-weight-body-strong);
  font-size: var(--text-small);
  color: var(--color-ink-muted);
}

.season-card p {
  margin-block: var(--space-2xs) 0;
  font-size: var(--text-body);
  color: var(--color-ink-muted);
}

.season-card p + p {
  margin-block-start: var(--space-sm);
}

/* --- Trust-strip (brief §5.3 step 5, §5.6) ---------------------------------- */

.trust-strip {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-lg);
}

.trust-strip__body {
  flex: 1 1 var(--space-3xl);
}

.trust-strip__body p {
  margin-block: var(--space-sm) 0;
  max-width: var(--layout-measure);
}

.trust-strip__texture {
  flex: 0 0 auto;
  inline-size: var(--space-3xl);
  overflow: hidden;
}

.trust-strip__texture img {
  display: block;
  inline-size: 100%;
  block-size: auto;
}

/* --- Process — "How It Works" (brief §5.3 step 6). The one section carrying
   its own top-level numerals (brief §2.6 nested-counter check) — a plain
   ordered list, native decimal markers via ::marker, no custom badge. */

.process-list {
  margin-block: var(--space-lg) 0;
  padding-inline-start: var(--space-lg);
  display: grid;
  gap: var(--space-md);
  max-width: var(--layout-measure);
}

.process-list li::marker {
  font-family: var(--font-display);
  font-weight: var(--font-weight-display);
  color: var(--color-accent);
}

.process-list h3 {
  display: inline;
  font-size: var(--text-h3);
}

.process-list p {
  margin-block: var(--space-2xs) 0;
  color: var(--color-ink-muted);
}

/* --- Service area (brief §5.3 step 7): imagery slot 3 (brief §6) as a low-
   opacity wide background band — "earth and sky" a third time. */

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

.service-area__band {
  position: absolute;
  inset: 0;
  z-index: var(--z-base);
  margin: 0;
  opacity: 0.28;
}

.service-area__band img {
  display: block;
  inline-size: 100%;
  block-size: 100%;
  object-fit: cover;
}

.service-area .container {
  position: relative;
  z-index: 1;
}

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

.service-area p + p {
  margin-block-start: var(--space-sm);
}

/* --- FAQ (brief §5.3 step 8) — native <details>/<summary>, plain surface
   rows, no counters (own disclosure marker is the sub-list's ornament,
   brief §2.6 limit 2). --------------------------------------------------- */

.faq-list {
  display: grid;
  gap: var(--space-xs);
  margin-block: var(--space-lg) 0;
}

.faq-item {
  background-color: var(--color-surface);
  padding: var(--space-md);
}

.faq-item summary {
  font-family: var(--font-body);
  font-weight: var(--font-weight-body-strong);
  font-size: var(--text-body);
  color: var(--color-ink);
  cursor: pointer;
}

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

/* --- Final CTA / contact block (brief §5.3 step 10) ------------------------- */

#contact .measure {
  margin-block-start: var(--space-sm);
}

#contact .form {
  margin-block-start: var(--space-lg);
}

.contact__mailto {
  margin-block: var(--space-md) 0;
  font-size: var(--text-small);
  color: var(--color-ink-muted);
}
