/*
  theme.css — Acadiana Pressure Washing
  Custom build. Extends Foundation/foundation-base.css (loaded AFTER it,
  and AFTER modules/module-system.css so these tokens win).

  Variant contract: T1-B (Bold). Near-black ground throughout, full-bleed
  photo hero under a heavy overlay, Barlow Condensed set heavy + uppercase,
  hard edges (0 radius), fewer sections with more air.

  Design thesis: this business publishes its prices. Almost no competitor in
  the trade does. So the price IS the design — oversized tabular numerals are
  the loudest element on the page, in the hero and again in the services rows.
  Every other decision is subordinate to reading a number fast.
*/

/* ── Tokens ──────────────────────────────────────────────────── */
:root {
  /* Variant identity (T1-B ground) */
  --color-bg:         #0A0C10;
  --color-surface:    #12151C;
  --color-surface-2:  #1A1E28;
  --color-text:       #F4F7FA;
  --color-text-muted: #7E8CA0;
  --color-border:     #262C38;
  --v-band-bg:        #06070A;

  /* Client brand — hydrated from content.json theme.colors */
  --color-primary:    #14324f;
  --color-secondary:  #5b6770;
  --color-accent:     #d9a441;
  --color-accent-ink: #0A0C10;

  --font-display: 'Barlow Condensed', 'Arial Narrow', system-ui, sans-serif;
  --font-body:    'Inter', system-ui, -apple-system, sans-serif;

  --v-radius: 0px;
  --v-maxw: var(--container-max, 1200px);

  /* Error red — the ONE hue outside the brand palette, tokenised so it has a
     single point of change. The critique flagged it at 2.8:1 against #ffffff,
     but it never renders on white: measured 6.02:1 against its real ground
     (--color-surface-2 #1A1E28), which clears AA. Kept as-is for that reason;
     if the form is ever moved to a light surface, re-check before reusing. */
  --color-error:      #f87171;
  --color-error-edge: #ef4444;

  /* Derived tints — color-mix only, never hardcoded, so hydration holds */
  --accent-dim:   color-mix(in srgb, var(--color-accent) 22%, transparent);
  --accent-hair:  color-mix(in srgb, var(--color-accent) 45%, transparent);
  --primary-deep: color-mix(in srgb, var(--color-primary) 78%, #000);
}

/* ── Base ────────────────────────────────────────────────────── */
body {
  font-family: var(--font-body);
  background: var(--color-bg);
  color: var(--color-text);
  -webkit-font-smoothing: antialiased;
}

.wrap {
  width: 100%;
  max-width: var(--v-maxw);
  margin-inline: auto;
  padding-inline: var(--container-padding, 1rem);
}

.section { padding-block: clamp(4rem, 9vw, 7.5rem); }
.section--tight { padding-block: clamp(2.75rem, 5vw, 4rem); }

.eyebrow {
  font-family: var(--font-display);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.18em;
  font-size: 0.82rem;
  color: var(--color-accent);
  margin-bottom: 0.6rem;
}

h1, h2, h3 { font-family: var(--font-display); text-transform: uppercase; }
h2 {
  font-weight: 800;
  font-size: clamp(2.2rem, 6vw, 4rem);
  line-height: 0.95;
  letter-spacing: 0.01em;
}
.section__head { margin-bottom: clamp(2rem, 4vw, 3.5rem); max-width: 46rem; }
.section__head p { color: var(--color-text-muted); margin-top: 0.9rem; font-size: 1.05rem; }

a { color: inherit; }

/* ── Buttons ─────────────────────────────────────────────────── */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 0.5rem;
  font-family: var(--font-display); font-weight: 700; text-transform: uppercase;
  letter-spacing: 0.05em; font-size: 1.1rem;
  padding: 0.85rem 1.9rem; border-radius: var(--v-radius);
  border: 2px solid transparent; text-decoration: none; min-height: 50px;
  transition: filter .15s, transform .1s, border-color .15s, color .15s;
}
.btn--primary { background: var(--color-accent); color: var(--color-accent-ink); }
.btn--primary:hover { filter: brightness(1.08); }
.btn--ghost { background: transparent; color: var(--color-text); border-color: rgba(255,255,255,.35); }
.btn--ghost:hover { border-color: var(--color-accent); color: var(--color-accent); }

/* ── Header ──────────────────────────────────────────────────── */
.header {
  position: sticky; top: 0; z-index: 100;
  background: color-mix(in srgb, var(--color-bg) 88%, transparent);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--color-border);
}
.nav {
  display: flex; align-items: center; gap: 1rem; min-height: 72px;
  max-width: var(--v-maxw); margin-inline: auto;
  padding: .5rem var(--container-padding, 1rem);
}
.nav__brand {
  display: flex; align-items: center; gap: .6rem; text-decoration: none;
  font-family: var(--font-display); font-weight: 800; text-transform: uppercase;
  font-size: 1.2rem; letter-spacing: .02em; line-height: 1;
}
.nav__brand img { height: 38px; width: auto; display: block; }
.nav__spacer { flex: 1; }
.nav__tel {
  font-family: var(--font-display); font-weight: 700; font-size: 1.25rem;
  letter-spacing: .02em; text-decoration: none; color: var(--color-text);
  white-space: nowrap;
}
.nav__tel:hover { color: var(--color-accent); }
.nav .btn { font-size: .95rem; padding: .6rem 1.2rem; min-height: 44px; }
@media (max-width: 640px) { .nav__cta { display: none; } }

/* Blog link: hidden until the client publishes a featured post (body.has-blog) */
.nav__link {
  font-family: var(--font-display); font-weight: 700; text-transform: uppercase;
  letter-spacing: .08em; font-size: 1rem; text-decoration: none; color: var(--color-text);
}
.nav__link:hover { color: var(--color-accent); }
.nav-blog { display: none; }
body.has-blog .nav-blog { display: inline-block; }

/* ── Hero — full-bleed photo, heavy overlay, price row ────────── */
.hero { position: relative; isolation: isolate; overflow: clip; }
.hero__media {
  position: absolute; inset: 0; z-index: -2;
  background-image: var(--hero-img);
  background-size: cover;
  /* Landscape frame, but a standing figure biases the subject upward —
     top-leaning crop keeps the head and the spray, not the wet pavement. */
  background-position: center 30%;
}
.hero::after {
  content: ''; position: absolute; inset: 0; z-index: -1;
  background:
    linear-gradient(to bottom,
      color-mix(in srgb, var(--color-bg) 55%, transparent) 0%,
      color-mix(in srgb, var(--color-bg) 78%, transparent) 55%,
      var(--color-bg) 100%);
}
.hero__inner { padding-block: clamp(5rem, 14vw, 9.5rem) clamp(3rem, 7vw, 5rem); }
.hero h1 {
  font-weight: 800;
  font-size: clamp(2.8rem, 10vw, 6.5rem);
  line-height: .9;
  max-width: 15ch;
  letter-spacing: .005em;
}
.hero h1 em { font-style: normal; color: var(--color-accent); display: block; }
/* Critique (hero): at 1.1rem/82% the tagline read at body scale and got lost
   between the headline and the price row. Up one step and lightened so it
   registers as voice copy rather than filler — it is the client's own line. */
.hero__tag {
  margin-top: 1.15rem; max-width: 40ch;
  font-size: clamp(1.2rem, 2.2vw, 1.45rem); line-height: 1.4;
  color: color-mix(in srgb, var(--color-text) 92%, transparent);
}

/* The price row — the reason this page exists */
.pricerow {
  display: grid; grid-template-columns: 1fr; gap: 0;
  margin-top: clamp(2.25rem, 5vw, 3.25rem);
  border-top: 1px solid var(--accent-hair);
  max-width: 46rem;
}
.pricerow__item {
  display: flex; align-items: baseline; gap: .9rem;
  padding-block: .95rem;
  border-bottom: 1px solid var(--color-border);
}
.pricerow__num {
  font-family: var(--font-display); font-weight: 800;
  font-size: clamp(2.4rem, 7vw, 3.4rem); line-height: 1;
  color: var(--color-accent);
  font-variant-numeric: tabular-nums;
  min-width: 4.4ch;
}
.pricerow__label {
  font-family: var(--font-display); font-weight: 700; text-transform: uppercase;
  letter-spacing: .06em; font-size: 1.05rem; color: var(--color-text);
}
.pricerow__from {
  font-family: var(--font-body); font-size: .72rem; letter-spacing: .14em;
  text-transform: uppercase; color: var(--color-text-muted); margin-left: auto;
  white-space: nowrap;
}
.hero__actions { display: flex; flex-wrap: wrap; gap: .85rem; margin-top: 2rem; }

@media (min-width: 720px) {
  .pricerow { grid-template-columns: repeat(3, 1fr); border-top: 1px solid var(--accent-hair); }
  .pricerow__item {
    flex-direction: column; align-items: flex-start; gap: .15rem;
    padding: 1.4rem 1.5rem 1.4rem 0; border-bottom: 0;
  }
  .pricerow__item + .pricerow__item { border-left: 1px solid var(--color-border); padding-left: 1.5rem; }
  .pricerow__from { margin-left: 0; margin-top: .35rem; }
}

/* ── Services — ruled price rows, no cards, no icon bubbles ───── */
.svc { border-top: 1px solid var(--color-border); }
.svc__row {
  display: grid; grid-template-columns: 1fr auto; gap: .5rem 1.5rem;
  align-items: start;
  /* Critique (services): rows were tight and uniform, which undercut the
     display-scale numerals. +~28% vertical air — the price is the product. */
  padding-block: clamp(2.05rem, 4.5vw, 3.1rem);
  border-bottom: 1px solid var(--color-border);
  transition: background .18s;
}
.svc__row:hover { background: var(--color-surface); }
.svc__idx {
  font-family: var(--font-display); font-weight: 700; font-size: .8rem;
  letter-spacing: .2em; color: var(--color-text-muted);
  grid-column: 1 / -1; margin-bottom: .35rem;
}
.svc__name {
  font-family: var(--font-display); font-weight: 800; text-transform: uppercase;
  font-size: clamp(1.6rem, 4.5vw, 2.6rem); line-height: 1; letter-spacing: .01em;
}
.svc__blurb {
  grid-column: 1 / -1; color: var(--color-text-muted);
  max-width: 52ch; margin-top: .6rem; font-size: 1rem;
}
.svc__price {
  font-family: var(--font-display); font-weight: 800;
  font-size: clamp(2rem, 6vw, 3.2rem); line-height: 1;
  color: var(--color-accent); font-variant-numeric: tabular-nums;
  justify-self: end;
}
.svc__note {
  margin-top: 1.75rem; color: var(--color-text-muted); font-size: .95rem;
  max-width: 52ch;
}

/* ── Gallery (C2) — full-bleed scroll-snap filmstrip ──────────── */
#work { background: var(--v-band-bg); }
#page-sections #sovran-c2 .c2-grid {
  display: flex; gap: 1px;
  overflow-x: auto; scroll-snap-type: x mandatory;
  -webkit-overflow-scrolling: touch;
  padding-bottom: .5rem;
}
#page-sections #sovran-c2 .c2-grid > * {
  flex: 0 0 min(86vw, 640px); scroll-snap-align: start;
}
#page-sections #sovran-c2 img {
  width: 100%; height: clamp(260px, 46vw, 440px); object-fit: cover; display: block;
}
/* Module-injected chrome the host section owns instead */
#page-sections #sovran-c2 .mod-eyebrow,
#page-sections #sovran-c2 .c2-cat-pill,
#page-sections #sovran-c2 .mod-filters { display: none; }
/* C2 renders its own heading as h2.mod-h (NOT .mod-title — that class does not
   exist in this module). The host section owns the heading, so suppress the
   module's; leaving it produced a duplicate "Recent Work" under the section's
   own "The Difference Is The Detail". */
#page-sections #sovran-c2 .mod-h,
#page-sections #sovran-c2 .mod-title,
#page-sections #sovran-c2 .mod-sub,
#page-sections #sovran-c2 .mod-subtitle { display: none; }
/* The module wrap adds its own block padding; the host section already supplies it. */
#page-sections #sovran-c2 .mod-wrap { padding-block: 0; max-width: none; }

/* ── Areas band ──────────────────────────────────────────────── */
#areas { background: var(--primary-deep); }
.areas__list {
  display: flex; flex-wrap: wrap; gap: 0 2.5rem;
  margin-top: 1.5rem; padding-top: 1.5rem;
  border-top: 1px solid var(--accent-hair);
}
.areas__list li {
  font-family: var(--font-display); font-weight: 800; text-transform: uppercase;
  font-size: clamp(1.5rem, 5vw, 2.4rem); line-height: 1.35; letter-spacing: .01em;
  list-style: none;
}
/* Critique (mobile): the four towns collapsed into a 2x2 grid at ~390px and the
   type dropped well below the display scale the desktop treatment carries. Stack
   them one per line and size up, so the recorded "oversized list" treatment
   survives to mobile instead of degrading into a grid. */
@media (max-width: 640px) {
  .areas__list { flex-direction: column; gap: .1rem; }
  .areas__list li { font-size: clamp(2.3rem, 9vw, 3rem); line-height: 1.15; }
}
.areas__hours { margin-top: 2rem; color: color-mix(in srgb, var(--color-text) 75%, transparent); }
.areas__hours dl { display: grid; grid-template-columns: auto 1fr; gap: .3rem 1.25rem; max-width: 26rem; }
.areas__hours dt { font-family: var(--font-display); font-weight: 700; text-transform: uppercase; letter-spacing: .08em; }
.areas__hours dd { font-variant-numeric: tabular-nums; }

/* ── FAQ (C5) + Blog (C3) — collapse when the client has no items ── */
#faq:has(#sovran-c5:empty),
#blog:has(#sovran-c3:empty) { display: none; }
#page-sections #sovran-c5 .mod-eyebrow { display: none; }
#page-sections #sovran-c5 .c5-q { font-family: var(--font-display); text-transform: uppercase; font-size: 1.15rem; }

/* ── Quote form band ─────────────────────────────────────────── */
#contact { background: var(--color-surface); border-top: 1px solid var(--color-border); }
.quote { display: grid; gap: clamp(2rem, 5vw, 3.5rem); }
.quote__pitch p { color: var(--color-text-muted); margin-top: 1rem; max-width: 44ch; }
.quote__tel {
  display: inline-block; margin-top: 1.5rem;
  font-family: var(--font-display); font-weight: 800;
  font-size: clamp(1.9rem, 5vw, 2.6rem); letter-spacing: .01em;
  color: var(--color-accent); text-decoration: none;
}
.quote__tel:hover { filter: brightness(1.1); }
@media (min-width: 900px) { .quote { grid-template-columns: 1fr 1.15fr; align-items: start; } }

/* Dropdown option contrast: browsers can paint <option> text near-black on a
   dark system surface (flagged ~1.2:1). Force the site's own tokens so the
   text stays legible on the dark option background. */
.sl-select option { color: var(--color-text); background: var(--color-bg); }

/* ── Footer ──────────────────────────────────────────────────── */
.footer { background: var(--v-band-bg); border-top: 1px solid var(--color-border); padding-block: 3rem 2rem; }
.footer__grid { display: grid; gap: 2rem; }
@media (min-width: 720px) { .footer__grid { grid-template-columns: 1.4fr 1fr 1fr; } }
.footer h3 {
  font-size: .8rem; letter-spacing: .18em; font-weight: 700;
  color: var(--color-text-muted); margin-bottom: .75rem;
}
.footer a { text-decoration: none; }
.footer a:hover { color: var(--color-accent); }
.footer ul { list-style: none; }
.footer li { margin-bottom: .4rem; color: var(--color-text-muted); }
.footer__base {
  margin-top: 2.5rem; padding-top: 1.25rem; border-top: 1px solid var(--color-border);
  display: flex; flex-wrap: wrap; gap: .5rem 1.5rem; justify-content: space-between;
  font-size: .82rem; color: var(--color-text-muted);
}
.footer__credit { color: var(--color-text-muted); text-decoration: none; }
.footer__credit:hover { color: var(--color-accent); }

/* ── Hero motion: content-only (DESIGN-DECISIONS.json) ────────
   Opt-IN under no-preference. Content is visible by default, so reduced
   motion and a JS failure both leave a complete, legible hero. Never
   opacity:0 in the base layer with an animation as the only way back. */
@media (prefers-reduced-motion: no-preference) {
  .hero h1, .hero__tag, .hero .pricerow, .hero__actions {
    animation: heroRise .55s cubic-bezier(.22,.61,.36,1) both;
  }
  .hero__tag      { animation-delay: .06s; }
  .hero .pricerow { animation-delay: .12s; }
  .hero__actions  { animation-delay: .18s; }
}
@keyframes heroRise {
  from { opacity: 0; transform: translateY(14px); }
  to   { opacity: 1; transform: none; }
}

/* Scroll reveals — standard tier: hand-rolled IntersectionObserver.
   Fallback in index.html forces .is-in after 2.5s so nothing can stay hidden. */
@media (prefers-reduced-motion: no-preference) {
  .reveal { opacity: 0; transform: translateY(18px); transition: opacity .5s ease, transform .5s ease; }
  .reveal.is-in { opacity: 1; transform: none; }
}

/* ── Focus visibility ────────────────────────────────────────── */
:focus-visible { outline: 2px solid var(--color-accent); outline-offset: 3px; }
