/* ==========================================================================
   site.css — Honest A's Pool Cleaning. sidebar-anchor archetype, the
   living-hero board+Joshua-tree+glint signature move (brief §5/§6). Tokens
   only — no raw hex/px/font literals below (house-tech-spec §3); the two
   escape hatches are the house breakpoints and an explicit @allow-literal
   comment. Breakpoint note: the brief's own 900px is 56.25em at the house
   16px root, matching the pattern victors-pool-service-mesa-az's brief set
   for the same family.
   ========================================================================== */

/* --- Layout primitives (house, unchanged 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 ---------------------------------------------------
   Fixed content height (brief §5.1: "56px content + 1px border-bottom",
   expiry bar 0-44 + header 44-101). min-height so the row resolves to
   --header-height regardless of the CTA button's own height. */

.site-header {
  position: relative;
  z-index: var(--z-header);
  padding-block: 0;
  min-height: var(--header-height);
  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);
  min-height: var(--header-height);
}

/* --text-brand, not the generic --text-h3 (services sub-heads, board
   headings) — brief §5.1's own 360px one-line arithmetic. */
.site-header__brand {
  overflow: hidden;
  min-width: 0;
  white-space: nowrap;
  text-overflow: ellipsis;
  font-family: var(--font-display);
  font-size: var(--text-brand);
  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-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);
}

/* Closed by CSS default below 48em (QA r3 perf/cls precedent) — the
   <noscript> override in @shared:head-boilerplate restores it for JS-off. */
.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. Radius, weight and colour all come from the brief via
   tokens — including --radius-none, which is a legitimate answer.          */

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

/* --color-accent-deep, NOT --color-accent (skeleton default) — brief §3:
   --color-accent is decorative/rule-work ONLY (3.88:1, fails 4.5:1 body);
   --color-accent-deep is the text-bearing role, 6.54:1 vs accent-ink. */
.btn--primary {
  background-color: var(--color-accent-deep);
  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);
}

.skip-link {
  background-color: var(--color-accent-deep);
}

/* --- Form -------------------------------------------------------------------
   One form per site (spec §6). POSTs to the endpoint constant in main.js;
   works as a plain HTML POST with JS off; auto-hides when no endpoint is
   configured so a spec site never shows a dead form.                       */

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

.form-intro,
.form-call {
  margin: 0 0 var(--space-sm);
}

.form-call {
  margin-block-end: var(--space-md);
}

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

.site-footer .container > * + * {
  margin-block-start: var(--space-sm);
}

/* ==========================================================================
   HERO — sidebar-anchor archetype (brief §2/§5/§6). House order at every
   width (design-rules §7.2 rule 1): eyebrow -> h1 -> primary CTA -> field ->
   lead -> facts. DOM order carries this at every breakpoint; at >= 900px a
   non-sticky rail (wordmark, phone, primary CTA, compact board device)
   appears BESIDE this content, never reordering it.
   ========================================================================== */

.hero {
  padding-block-start: var(--space-sm);
  padding-block-end: var(--section-gap);
  background-color: var(--color-bg);
  overflow: hidden;
}

.hero__layout {
  display: block;
}

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

.hero h1 {
  margin: var(--space-2xs) 0 0;
  font-size: var(--text-hero);
}

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

/* The living-hero field. NO TEXT SITS OVER IT (brief §3) — every text
   element (eyebrow, H1, CTA, lead, facts, the rail's own wordmark/list)
   sits in normal document flow, never overlaid on the gradient or the
   illustration layers. */
.hero__field {
  position: relative;
  overflow: hidden;
  height: var(--hero-field-height);
  margin-inline: calc(var(--layout-gutter) * -1);
  margin-block-start: var(--space-sm);
}

.hero__atmosphere {
  position: absolute;
  inset: 0;
  background:
    radial-gradient(120% 90% at 50% 0%, var(--color-atmosphere-accent), transparent 60%),
    radial-gradient(90% 70% at 85% 100%, var(--color-atmosphere-teal), transparent 55%),
    linear-gradient(180deg, var(--color-atmosphere-ground-top) 0%, var(--color-atmosphere-ground-mid) 45%, var(--color-atmosphere-ground-deep) 78%, var(--color-atmosphere-ground-bottom) 100%);
}

/* Background layer — the Joshua tree (with its own leaning skimmer-pole
   silhouette at its base), independent sway loop. object-fit: contain so it
   scales rather than crops if the field's own height ever drops below
   --hero-band-min (brief §6). */
.hero__joshua {
  position: absolute;
  inset-inline-start: 6%;
  inset-block-end: 0;
  width: 30%;
  max-height: 94%;
  object-fit: contain;
  object-position: bottom;
  transform-origin: 50% 100%;   /* base of the plant */
  animation: joshuaSway var(--duration-joshua-sway) var(--ease-signature) infinite var(--delay-joshua-sway);
}

/* Foreground layer — the hung board, the LCP element and the §6.1 anchor
   (brief §6: "the horizontal centre of the field, roughly 25-70% across and
   5-30% down its height"). */
.hero__board {
  position: absolute;
  inset-inline-start: 25%;
  inset-block-start: 5%;
  width: 45%;
  height: 72%;
  object-fit: contain;
  object-position: center top;
  transform-origin: 50% 0%;   /* the chain-bracket point, top-centre of the board */
  animation: boardSwing var(--duration-board-swing) var(--ease-signature) infinite;
}

/* The sun-glint — a soft travelling highlight sweeping the field, ambient
   only, aria-hidden (it is inside the already aria-hidden field). */
.hero__glint {
  position: absolute;
  inset-block-start: 8%;
  inset-inline-start: 10%;
  width: 14%;
  aspect-ratio: 1;
  background-image: radial-gradient(circle, var(--color-atmosphere-ground-top), transparent 70%);
  opacity: 0;
  animation: sunGlint var(--duration-sun-glint) var(--ease-linear) infinite;
}

@keyframes boardSwing {
  0%, 100% { transform: rotate(-2deg); }
  50%      { transform: rotate(2deg); }
}

@keyframes joshuaSway {
  0%, 100% { transform: rotate(-1.5deg); }
  50%      { transform: rotate(1.5deg); }
}

@keyframes sunGlint {
  0%   { transform: translateX(var(--motion-glint-start)); opacity: 0; }
  10%  { opacity: .6; }
  90%  { opacity: .6; }
  100% { transform: translateX(var(--motion-glint-end)); opacity: 0; }
}

/* Reduced motion (house-tech-spec §8, absolute, no exception — brief §6).
   base.css's kill switch already collapses the duration tokens to ~0.01ms
   at :root (tokens.css); these explicit end-states are the belt to that
   brace, matching the brief's own reduced-motion block exactly. */
@media (prefers-reduced-motion: reduce) {
  .hero__board,
  .hero__joshua,
  .hero__glint {
    animation: none;
  }
  .hero__board {
    transform: rotate(0deg);
  }
  .hero__glint {
    opacity: 0;
  }
}

.hero__lead {
  margin: var(--space-sm) 0 0;
  font-size: var(--text-lead);
  line-height: var(--leading-body);
  max-width: var(--layout-measure);
}

.facts {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2xs);
  margin: var(--space-xs) 0 0;
  padding: 0;
  list-style: none;
}

.facts li {
  padding: var(--space-3xs) var(--space-xs);
  background-color: var(--color-surface);
  border-radius: var(--radius-sm);
  font-size: var(--text-small);
  font-weight: var(--font-weight-body-strong);
  color: var(--color-accent-deep);
}

/* ==========================================================================
   THE RAIL — brief §2's archetype definition, precisely: at >= 900px a
   persistent, NON-STICKY left rail (fixed width, --rail-width) runs beside
   the hero content, carrying wordmark, phone, primary CTA and a compact
   version of the neighborhood board (brief §6.2's content, rendered here
   instead of in the standalone .route section below — never both on one
   viewport, house-tech-spec's "content relocates by breakpoint" rule).
   Below 900px this whole block is hidden; .route (further down the page)
   carries the same five neighborhoods as its own full-width section.
   ========================================================================== */

.hero__rail {
  display: none;
}

.hero__rail-brand {
  display: inline-block;
  margin: 0 0 var(--space-sm);
  font-family: var(--font-display);
  font-size: var(--text-brand);
  font-weight: var(--font-weight-display);
  color: var(--color-ink);
  text-decoration: none;
}

.hero__rail-phone {
  display: block;
  margin: 0 0 var(--space-xs);
  color: var(--color-accent-deep);
  font-weight: var(--font-weight-body-strong);
  text-decoration: none;
}

.hero__rail-cta {
  margin-block-end: var(--space-md);
  width: 100%;
}

/* The compact board device — the rail's own version of the hung sign,
   dark board-ground with light board-ink text (brief §3's palette table:
   accent-ink on ink ground, 15.17:1 — "the board's own wordmark/list
   text"). Reused for the standalone .route section's slats too. */
.board-panel {
  background-color: var(--color-ink);
  color: var(--color-accent-ink);
  padding: var(--space-md);
  border-radius: var(--radius-sm);
}

.board-panel__title {
  margin: 0 0 var(--space-2xs);
  font-size: var(--text-h3);
  color: var(--color-accent-ink);
}

.board-panel__intro {
  margin: 0 0 var(--space-sm);
  font-size: var(--text-small);
  color: var(--color-accent-ink);
  opacity: 0.85;
}

.board-panel__list {
  margin: 0 0 var(--space-sm);
  padding: 0;
  list-style: none;
  display: grid;
  gap: var(--space-2xs);
}

.board-panel__list li {
  display: flex;
  align-items: center;
  gap: var(--space-2xs);
  font-size: var(--text-small);
  font-weight: var(--font-weight-body-strong);
}

.board-panel__list li::before {
  content: '';
  flex: 0 0 auto;
  width: var(--route-dot-size);
  height: var(--route-dot-size);
  border-radius: 50%;
  /* board's own large-UI-only role for --color-accent (brief §3: 3.53:1 on
     the ink board ground — large text/UI only, never small body text). A
     structural dot is exactly that carve-out, not a concept icon. */
  background-color: var(--color-accent);
}

.board-panel__note {
  margin: 0;
  font-size: var(--text-small);
  color: var(--color-accent-ink);
  opacity: 0.85;
}

@media (min-width: 56.25em) {
  .hero__layout {
    display: flex;
    align-items: flex-start;
    gap: var(--space-xl);
  }

  .hero__rail {
    display: block;
    flex: 0 0 var(--rail-width);
    width: var(--rail-width);
  }

  .hero__content {
    flex: 1 1 auto;
    min-width: 0;
  }

  /* Content relocates, never duplicates (house-tech-spec): the standalone
     Route section's content now lives in the rail above. */
  .route {
    display: none;
  }
}

/* ==========================================================================
   THE ROUTE — standalone, full-width section below 900px only (brief §5,
   §6.2). Five named neighborhoods, no invented radius, no icon beyond a
   single flat --color-accent-deep dot (a structural ornament, not a
   concept icon) — clears design-rules §4's banned three/four-card grid by
   being a plain ruled list of real, currently-served place names.
   ========================================================================== */

.route-list {
  margin: var(--space-md) 0 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: var(--space-2xs);
  border-block-start: var(--border-hairline) var(--border-style) var(--color-border);
}

.route-list li {
  display: flex;
  align-items: center;
  gap: var(--space-xs);
  padding-block: var(--space-2xs);
  border-block-end: var(--border-hairline) var(--border-style) var(--color-border);
  font-weight: var(--font-weight-body-strong);
}

.route-list li::before {
  content: '';
  flex: 0 0 auto;
  width: var(--route-dot-size);
  height: var(--route-dot-size);
  border-radius: 50%;
  background-color: var(--color-accent-deep);
}

.route-note {
  margin: var(--space-md) 0 0;
  color: var(--color-ink-muted);
  max-width: var(--layout-measure);
}

/* ==========================================================================
   WHAT A WEEKLY VISIT INCLUDES — a ledger, not a card grid. Matches the
   plain, custodial register (dossier §4.4) and introduces no competing
   counter or icon set (design-rules §4). Imagery slot 3 (brief §7): a
   below-fold, lazy still life beside the text body.
   ========================================================================== */

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

@media (min-width: 56.25em) {
  .visit-grid {
    grid-template-columns: 3fr 2fr;
    align-items: start;
    gap: var(--space-xl);
  }
}

.visit-grid__image img {
  width: 100%;
  height: auto;
  border-radius: var(--radius-sm);
}

.visit-list {
  margin: var(--space-md) 0 0;
  padding: 0;
  list-style: none;
  border-block-start: var(--border-hairline) var(--border-style) var(--color-border);
}

.visit-list li {
  padding-block: var(--space-2xs);
  border-block-end: var(--border-hairline) var(--border-style) var(--color-border);
}

.visit-filter-line {
  margin: var(--space-md) 0 0;
}

/* The C2-required review quote (brief §0) — closing trust line. Reuses the
   review-tag device (below) at a smaller scale rather than inventing a
   fourth visual idiom for one quote. */
.visit-quote {
  margin: var(--space-lg) 0 0;
}

/* ==========================================================================
   DIVIDER STRIP — imagery slot 4 (brief §7): full-bleed, decorative, no
   text overlay. 96px = --space-2xl, so no new token is needed.
   ========================================================================== */

.divider-strip {
  height: var(--space-2xl);
  overflow: hidden;
}

.divider-strip picture {
  display: block;
  height: 100%;
}

.divider-strip img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center 55%;
}

/* ==========================================================================
   SERVICES — the four named differentiators beyond the weekly staple
   (brief §6.5). Explicitly content-driven, not a generic icon/title/blurb
   grid (design-rules §4): every row is the business's own named service
   with its own dossier-sourced description, no invented benefit language.
   ========================================================================== */

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

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

.service-row {
  background-color: var(--color-surface);
  padding: var(--space-md);
  border-radius: var(--radius-sm);
}

.service-row__title {
  margin: 0 0 var(--space-2xs);
  font-size: var(--text-h3);
}

.service-row p {
  margin: 0;
  font-size: var(--text-body);
}

.services-image {
  margin-block-start: var(--space-lg);
}

.services-image img {
  width: 100%;
  height: auto;
  border-radius: var(--radius-sm);
}

/* ==========================================================================
   WHAT THE NEIGHBORS SAY — the C2-required load-bearing reviews section
   (brief §0, §6.4). Opens with one line rather than a standalone Trust
   section; three verbatim quotes, each in a hung-tag device echoing the
   board's own sign-shop register.
   ========================================================================== */

.reviews-lead {
  margin: var(--space-sm) 0 0;
  max-width: var(--layout-measure);
}

.reviews-fact {
  display: inline-flex;
  margin: var(--space-sm) 0 0;
  padding: var(--space-3xs) var(--space-sm);
  background-color: var(--color-surface);
  border-radius: var(--radius-sm);
  font-weight: var(--font-weight-body-strong);
  color: var(--color-accent-deep);
}

.reviews-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-md);
  margin-block-start: var(--space-lg);
}

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

/* The hung-tag device: a small painted tag shape, --color-surface ground,
   --color-accent-deep border (brief §6.4 — "reusing the family's device
   rather than introducing a fourth visual idiom"). */
.review-tag {
  background-color: var(--color-surface);
  border: var(--border-thick) var(--border-style) var(--color-accent-deep);
  border-radius: var(--radius-sm);
  padding: var(--space-md);
}

.review-tag blockquote {
  margin: 0 0 var(--space-sm);
  font-size: var(--text-body);
}

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

/* The visit section's own smaller closing quote reuses the same tag. */
.visit-quote .review-tag {
  max-width: var(--layout-measure);
}

.reviews-phone {
  margin: var(--space-lg) 0 0;
  font-weight: var(--font-weight-body-strong);
}

.reviews-phone a {
  color: var(--color-accent-deep);
}

/* ==========================================================================
   REQUEST FORM — playbook §5/§10, brief §10's chosen field shape.
   ========================================================================== */

.contact-call {
  margin: var(--space-sm) 0 var(--space-lg);
}
