/* ==========================================================================
   site.css — Right Edge Lawn Care, Springfield IL.
   Archetype: poster-hero (brief §4). Tokens only — no raw hex/px/font
   literals (house-tech-spec §3). The two escape hatches are the house
   breakpoints (48em/64em) and an explicit @allow-literal comment.
   ========================================================================== */

/* --- Section headings (brief §3.2) -----------------------------------------
   base.css sets h1-h4's family/weight/leading/tracking but deliberately no
   font-size — that is the per-brief type scale's job. Every h2 on this site
   is a section heading, small and kicker-scale by the brief's own token
   table (§3.2: 15.2-18.4px, smaller than body) — the section heading reads
   as a quiet label, not a second display moment, so the H1 stays the one
   loud line on the page (design-rules §0). Without this rule h2 falls back
   to the browser's UA default (~24px) and reads as a second, competing size. */

h2 {
  font-size: var(--text-h2);
}

/* --- Layout primitives (house, from skeleton) ----------------------------- */

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

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

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

/* --- Header & navigation (house, from skeleton) ---------------------------
   Progressive enhancement: with JS off the nav list is plain and always
   visible; the toggle ships [hidden]. With JS on, narrow viewports collapse
   the list behind the toggle. Nothing about navigation depends on JS. */

.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);
  font-size: var(--text-h3);
  text-decoration: none;
  letter-spacing: var(--tracking-tight);
}

.nav-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2xs);
  padding-block: var(--space-2xs);
  border: var(--border-hairline) var(--border-style) var(--color-border-strong);
  border-radius: var(--radius-sm);
  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-size: var(--text-small);
  font-weight: var(--font-weight-body-strong);
}

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

.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 (house, from skeleton) ---------------------------------------- */

.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-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 {
  border-color: var(--color-border-strong);
  color: var(--color-ink);
}

/* --- Form (house, from skeleton) -------------------------------------------- */

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

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

.field__label {
  font-size: var(--text-small);
  font-weight: var(--font-weight-body-strong);
}

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

.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 (house, from skeleton) ------------------------------------------ */

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

/* --- Header overrides — brief §4.2 --------------------------------------
   Header target ≈48px: padding-block --space-xs (12px) top/bottom, one line
   at >=360px. The phone control is pulled OUT of the collapsible nav so it
   stays always-visible per the brief's 1440px description ("phone number and
   pill nav-CTA both visible inline") — only Services/Get a Quote collapse
   behind the hamburger below 48em.

   GRID, NOT FLEX, AND WHY. The house default is flexbox with flex-wrap; two
   measured defects came from it and both are structural, not tunable:
     1. flex-wrap decides line breaks from each item's HYPOTHETICAL (unshrunk)
        size, so the full-width brand triggered a wrap onto a second row
        before flex-shrink ever got a chance — measured doubling the header's
        height against the brief's one-line requirement.
     2. Once the brand was made the flexible remainder (flex-grow) to fix
        that, its rendered width became coupled to its siblings' widths —
        so the phone control's own text reflowing a few px on the Nunito
        Sans font-display swap shifted the brand, which shifted the phone
        control itself. Lighthouse traced this exactly: layout-shifts named
        .site-header__phone, caused by "Web font loaded". Fixed-width
        siblings alone did not close it either, because the nav-toggle
        control (hidden -> visible once main.js runs, and itself carrying
        swappable text) sits in the same coupled row.
   An explicit grid template's column widths belong to the CONTAINER, not to
   the children's content or visibility — a hidden or reflowing item cannot
   move a track it was never sized from. That removes both defects at their
   root instead of chasing each symptom. */

.site-header__inner {
  display: grid;
  grid-template-columns: minmax(0, 1fr) var(--header-phone-width) var(--header-toggle-width);
  align-items: center;
}

@media (min-width: 48em) {
  .site-header__inner {
    grid-template-columns: minmax(0, 1fr) var(--header-phone-width) auto;
  }
}

.site-header {
  padding-block: var(--space-xs);
}

.site-header__brand {
  font-weight: var(--font-weight-display-medium);
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.site-header__phone {
  display: inline-flex;
  align-items: center;
  justify-content: flex-end;
  font-family: var(--font-body);
  font-size: var(--text-small);
  font-weight: var(--font-weight-body-strong);
  color: var(--color-ink);
  text-decoration: none;
  white-space: nowrap;
}

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

/* The toggle sits in the grid's third column (fixed width) at mobile, filling
   it by the grid default (justify-self: stretch) with its own label centered
   via justify-content above — so the column's width is never derived from the
   label's own content. The same column holds .site-nav at >=48em once the
   toggle is display:none (grid places the next visible item into the vacated
   track); that column is `auto` there; the nav content aligns to its end. */
/* Open mobile nav spans the full row (grid's flex-basis:100% equivalent —
   the house rule sets flex-basis, inert under this grid parent). Grid's
   own auto-placement already advances it to a new row on its own, since
   row 1's three columns are already occupied by brand/phone/toggle. */
[data-nav-ready] .site-nav[data-nav-open='true'] {
  grid-column: 1 / -1;
}

@media (min-width: 48em) {
  .site-nav {
    justify-self: end;
  }
}

/* --- Buttons — brief §3.3: CTA buttons and the pill nav-CTA use --radius-pill,
   the family norm ("rounded"). Overrides the skeleton's --radius-sm default. */

.btn {
  border-radius: var(--radius-pill);
  font-family: var(--font-display);
  font-weight: var(--font-weight-display-medium);
}

.btn--quiet {
  background-color: transparent;
}

/* --- Section-boundary hairline — brief §4.6 ornament table: --color-turf-dark,
   1px, top of every .section after the hero, spanning the content measure. */

.section:not(.hero) > .container {
  position: relative;
}

.section:not(.hero) > .container::before {
  content: '';
  display: block;
  width: 100%;
  max-width: var(--layout-measure);
  height: var(--border-hairline);
  background-color: var(--color-turf-dark);
  margin-inline: auto;
  margin-block-end: var(--space-lg);
}

/* --- Hero — poster-hero archetype (brief §4.1, §4.2, §5.1) ---------------
   DOM order: eyebrow -> H1 -> primary+secondary CTA -> field (living-turf
   band) -> lede. No facts row in the hero (brief §4.1). The hero is the
   page's one living-hero moment (design-rules §0); it is never reveal-gated. */

.hero {
  position: relative;
  padding-block-start: var(--space-md);
  padding-block-end: var(--section-gap);
  background: radial-gradient(120% 85% at 50% 0%, var(--color-atmos-top) 0%, var(--color-bg) 55%, var(--color-atmos-edge) 100%);
}

.hero__inner {
  display: flex;
  flex-direction: column;
  max-width: var(--layout-measure);
}

.hero__eyebrow {
  font-family: var(--font-body);
  font-size: var(--text-eyebrow);
  font-weight: var(--font-weight-body-strong);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--color-ink-muted);
  margin-block-end: var(--space-2xs);
}

.hero__headline {
  font-size: var(--text-hero);
  line-height: var(--leading-tight);
  margin-block-end: var(--space-sm);
}

.hero__headline .accent-word {
  color: var(--color-accent);
}

.hero__cta-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-md);
  margin-block-end: var(--space-xs);
}

.hero__cta-secondary {
  font-size: var(--text-small);
  font-weight: var(--font-weight-body-strong);
  color: var(--color-ink);
  text-decoration: none;
  border-block-end: var(--border-hairline) var(--border-style) var(--color-ink-muted);
  padding-block-end: var(--space-3xs);
}

.hero__cta-secondary:hover,
.hero__cta-secondary:focus-visible {
  color: var(--color-accent);
  border-color: var(--color-accent);
}

.hero__field {
  position: relative;
  height: var(--hero-field-height);
  overflow: hidden;
  margin-block-end: var(--space-sm);
}

.hero__field picture {
  display: block;
  height: 100%;
}

.hero__field img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 100%;
  /* round-2 per brief §0.3 [QA-r1]: bottom-anchors the crop so any vertical
     overflow trims from the top (pale sky/tallest seed heads) rather than
     splitting the crop symmetrically, protecting the green base. */
}

.hero__blades {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}

.blade {
  transform-origin: 50% 100%;
}

.blade-a { animation: sway var(--sway-duration-a) var(--ease-in-out) infinite alternate; }
.blade-b { animation: sway var(--sway-duration-b) var(--ease-in-out) infinite alternate; animation-delay: var(--sway-delay-b); }
.blade-c { animation: sway var(--sway-duration-c) var(--ease-in-out) infinite alternate; animation-delay: var(--sway-delay-c); }
.blade-a2 { animation: sway var(--sway-duration-a) var(--ease-in-out) infinite alternate; animation-delay: var(--sway-delay-a2); }
.blade-b2 { animation: sway var(--sway-duration-b) var(--ease-in-out) infinite alternate; animation-delay: var(--sway-delay-b2); }
.blade-c2 { animation: sway var(--sway-duration-c) var(--ease-in-out) infinite alternate; animation-delay: var(--sway-delay-c2); }

@keyframes sway {
  from { transform: rotate(-4deg); }
  to { transform: rotate(4.5deg); }
  /* @allow-literal: signature-move rotation amplitude, brief §6/Tile C's own
     carried-forward physics — not a reusable token, a one-off keyframe value */
}

@media (prefers-reduced-motion: reduce) {
  .blade-a, .blade-b, .blade-c, .blade-a2, .blade-b2, .blade-c2 {
    animation: none;
  }
}

.hero__lede {
  font-size: var(--text-lead);
  line-height: var(--leading-lead);
  color: var(--color-ink-muted);
}

@media (min-width: 64em) {
  .hero__inner {
    max-width: var(--layout-measure);
  }
}

/* --- Services — poster-numeral index (brief §4.5, §4.6) ------------------ */

.index-row {
  display: flex;
  align-items: baseline;
  gap: var(--space-md);
  padding-block: var(--space-md);
  border-block-end: var(--border-hairline) var(--border-style) var(--color-border);
}

.index-row:first-of-type {
  border-block-start: var(--border-hairline) var(--border-style) var(--color-border);
}

.index-row__num {
  flex: 0 0 auto;
  min-width: var(--index-numeral-col);
  font-family: var(--font-display);
  font-weight: var(--font-weight-display);
  font-size: var(--index-num-size);
  color: var(--color-accent);
  line-height: 1;
}

.index-row__name {
  font-weight: var(--font-weight-body-strong);
  margin-block-end: var(--space-3xs);
}

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

/* --- Season strip — 4 cards, current tinted (brief §4.5, §4.6) ----------- */
/* Turf-texture supporting image (brief §5.2 slot 2): low-opacity background
   layer behind the season strip, frame-filling, never competing with text. */

.season-texture {
  position: relative;
  overflow: hidden;
}

.season-texture__bg {
  position: absolute;
  inset: 0;
  z-index: var(--z-base);
  opacity: 0.5;
  /* @allow-literal: unitless opacity multiplier, not a hex/px/font literal —
     raised to 0.5 round-3 per brief §0.5/§0.6 [QA-r2]: safe now that every
     .season-card carries an opaque background (below), which removes the
     only text pairing (season-card body text sitting directly on this
     layer) that had capped this value at 0.34 in round-2. This is again a
     binding value, not a range, and the Builder may not tune past it on its
     own judgment if it still under-delivers (§0.5). */
}

.season-texture__bg picture {
  display: block;
  height: 100%;
}

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

.season-texture > .container {
  position: relative;
  z-index: 1;
}

.season-strip {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--space-sm);
}

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

.season-card {
  background-color: var(--color-bg);
  /* round-3, brief §0.5/§0.6 [QA-r2]: opaque so body text never sits
     directly on the composited texture layer behind this section. Reuses
     §2.3 row 2 (ink-muted vs bg flat, 6.01:1) — no new contrast pairing. */
  padding: var(--space-md);
  border: var(--border-hairline) var(--border-style) var(--color-border);
  border-radius: var(--radius-sm);
}

.season-card[data-current] {
  background-color: var(--color-surface);
  border-color: var(--color-border-strong);
}

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

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

/* --- Trust facts — plain typographic statement, no card, no badges
   (brief §4.5, §8) -------------------------------------------------------- */

.trust-facts__list {
  margin: 0 0 var(--space-md);
  padding: 0;
  list-style: none;
  display: grid;
  gap: var(--space-2xs);
}

.trust-facts__list li {
  font-family: var(--font-display);
  font-size: var(--text-h3);
  font-weight: var(--font-weight-display);
}

/* --- Reviews — 3 curated verbatim cards (brief §3.3: radius-lg + shadow-sm,
   the one section reading as "evidence") ----------------------------------- */

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

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

.review-card {
  padding: var(--space-md);
  background-color: var(--color-surface);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
}

.review-card blockquote {
  margin: 0 0 var(--space-sm);
  font-size: var(--text-small);
  line-height: var(--leading-body);
}

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

/* --- Service area — paragraph + bluestem specimen (brief §3.3: radius-md,
   contained not full-bleed) ------------------------------------------------ */

.service-area__grid {
  display: grid;
  gap: var(--space-lg);
  align-items: center;
}

@media (min-width: 48em) {
  .service-area__grid {
    grid-template-columns: 1.2fr 1fr;
  }
}

.service-area__image {
  border-radius: var(--radius-md);
  overflow: hidden;
}

.service-area__image img {
  width: 100%;
  height: auto;
}

/* --- Final CTA band — card on --color-surface, radius-lg, no shadow
   (brief §3.3) -------------------------------------------------------------- */

.cta-band__card {
  padding: var(--space-lg);
  background-color: var(--color-surface);
  border-radius: var(--radius-lg);
  max-width: var(--layout-measure);
}

.cta-band__card .btn {
  margin-block-end: var(--space-md);
}

/* --- Footer additions — veteran line, social row, licensing line
   (copy.md §1) -------------------------------------------------------------- */

.site-footer__extra {
  margin-block-start: var(--space-xs);
}

.site-footer__social {
  display: flex;
  gap: var(--space-sm);
  margin-block-start: var(--space-xs);
  padding: 0;
  list-style: none;
}
