/* =====================================================================
   SandFly Exuma — site stylesheet
   Loaded AFTER tokens.css + components.css. This file only adds what the
   design system doesn't already cover: self-hosted @font-face rules, page
   layout (wrap/section rhythm), the mobile nav panel, and small fixes for
   places this page uses components.css classes on tags the design system's
   reference didn't demo (e.g. <a class="btn">).
   ===================================================================== */

/* ================= Fonts (self-hosted) =================
   "Archivo Condensed" isn't a separate font file anymore — Google folds it
   into the variable "Archivo" font's width axis. These files are that font
   pre-set to a condensed width (wdth 75) and aliased to the family name
   tokens.css already expects, so tokens.css/components.css need no edits. */
@font-face {
  font-family: "Archivo Condensed";
  font-style: normal;
  font-weight: 700 800;
  font-stretch: 75%;
  font-display: swap;
  src: url("/assets/fonts/archivo-condensed-var.woff2") format("woff2");
}
@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 400 600;
  font-display: swap;
  src: url("/assets/fonts/inter-var.woff2") format("woff2");
}

/* ================= Base / a11y helpers ================= */
.visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

.skip-link {
  position: absolute;
  top: -48px;
  left: var(--sp-4);
  z-index: 100;
  background: var(--accent);
  color: var(--paper);
  padding: var(--sp-3) var(--sp-4);
  font-weight: 700;
  text-decoration: none;
  transition: top .15s ease;
}
.skip-link:focus {
  top: var(--sp-4);
}

/* Anchor-as-button: components.css only demos <button class="btn">.
   This page also uses <a class="btn"> (nav CTA, hero, pricing, footer),
   so anchors need the underline removed explicitly. */
.btn { text-decoration: none; }
a.wordmark { text-decoration: none; color: inherit; display: inline-block; }

/* components.css's `.on-ink a { color: var(--accent) }` (specificity 0,1,1)
   otherwise beats `.btn--primary`'s own color (specificity 0,1,0) whenever
   the primary button is a real link rather than a <button> — turning its
   white label into invisible orange-on-orange. Only `<a class="btn">` on
   ink hits this; components.css already carries the equivalent fix for
   `.btn--secondary`/`.btn--text`. */
.on-ink .btn--primary { color: var(--paper); }

/* ================= Layout rhythm ================= */
.wrap {
  max-width: var(--max-width);
  margin: 0 auto;
  padding: 0 20px;
}

.section { padding: var(--sp-24) 0; }
.section--tight { padding: var(--sp-16) 0; }
@media (min-width: 900px) {
  .section { padding: var(--sp-32) 0; }
  .section--tight { padding: var(--sp-24) 0; }
}

.section-body { color: var(--muted); max-width: 640px; margin-top: var(--sp-4); }
.on-ink .section-body { color: var(--muted-on-ink); }
.section-note { color: var(--muted); font-size: var(--fs-small); margin-top: var(--sp-4); }
.section-closing { font-family: var(--font-heading); font-weight: 800; text-transform: uppercase; font-size: var(--fs-h3); margin-top: var(--sp-8); }

/* Narrow phones: wordmark + full "Book Free Consultation" button + burger
   don't fit on one line. The design system's own reference demos both a
   compact single-line mobile wordmark AND a shortened "Book" button label
   for exactly this bar — both applied here as breakpoints. */
@media (max-width: 479px) {
  .site-header .wordmark__main { font-size: 1.1rem; }
  .site-header .wordmark__sub { display: none; }
}
.btn__short { display: none; }
@media (max-width: 400px) {
  .nav-bar__actions .btn__full { display: none; }
  .nav-bar__actions .btn__short { display: inline; }
}

/* Right at the desktop-nav cutoff (768px+), the four nav links + full-width
   wordmark + full CTA label are close enough to the edge that "How It
   Works" wraps mid-word inside its own link. Tighten the two nav gaps just
   in this range — comfortably wide again by ~900px. */
@media (min-width: 768px) and (max-width: 900px) {
  .nav-bar { gap: var(--sp-4); }
  .nav-bar__links { gap: var(--sp-4); }
}

/* ================= Trust banner =================
   Sits inside the hero's on-ink section (full-bleed, above the centered
   hero content) so it reads as part of the navy block rather than a
   separate strip above the header — orange/white makes it the one thing
   on that block that isn't ink or sand, so it actually stands out. */
.trust-banner {
  margin: 0;
  background: var(--accent);
  color: var(--paper);
  text-align: center;
  padding: var(--sp-2) var(--sp-4);
  font-family: var(--font-heading);
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  font-size: var(--fs-small);
}

/* ================= Sticky header ================= */
.site-header {
  position: sticky;
  top: 0;
  z-index: 50;
}

/* ================= Mobile nav panel =================
   components.css hides .nav-bar__links under 768px unconditionally; this
   adds the JS-driven open state (full-width dropdown panel) on top of it. */
.nav-bar { position: relative; }
@media (max-width: 767px) {
  .site-header.is-nav-open .nav-bar__links {
    display: flex;
    flex-direction: column;
    gap: var(--sp-4);
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    background: var(--paper);
    border-bottom: var(--border);
    padding: var(--sp-4) var(--sp-6) var(--sp-6);
  }
  .site-header.is-nav-open .nav-bar__links a {
    display: block;
    padding: var(--sp-2) 0;
  }
  .site-header.is-nav-open .nav-bar__burger span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
  .site-header.is-nav-open .nav-bar__burger span:nth-child(2) { opacity: 0; }
  .site-header.is-nav-open .nav-bar__burger span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }
  .nav-bar__burger span { transition: transform .15s ease, opacity .15s ease; }
}

/* ================= Hero =================
   Overrides .section's padding-top/bottom (0 here) because the hero manages
   its own vertical rhythm via min-height + centered content — and because
   the trust banner needs to sit flush against the section's top edge, not
   inset by the standard section padding. */
.section--hero {
  min-height: 85vh;
  padding: 0;
  display: flex;
  flex-direction: column;
}
.hero__center {
  flex: 1;
  display: flex;
  align-items: center;
}
.hero__inner { padding-top: var(--sp-16); padding-bottom: var(--sp-16); }
.fs-display { font-size: var(--fs-display); margin-bottom: var(--sp-6); }
.hero__sub {
  font-size: var(--fs-body-lg);
  color: var(--muted-on-ink);
  max-width: 640px;
  margin-bottom: var(--sp-8);
}
.hero__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-4);
  margin-bottom: var(--sp-8);
}
.hero__meta { margin: 0; }
.hero__eyebrow { font-size: 1rem; }

/* ================= Tag strip checkmarks =================
   components.css's .tag is just a bordered text label with no icon slot;
   this adds one so each pest chip can carry the same orange checkmark used
   in the "Who It's For" checklist. */
.tag-strip .tag {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
}
.tag-strip .tag svg {
  width: 14px;
  height: 14px;
  flex: none;
  color: var(--accent);
}

/* ================= Pricing section ================= */
.pricing__inner { text-align: left; }
.pricing__inner .section-header { max-width: 720px; margin-bottom: var(--sp-8); }
.pricing__card-row {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: var(--sp-6);
  margin-bottom: var(--sp-8);
}
/* components.css's .price-card__addon uses justify-content: space-between
   with no gap — fine when there's slack in the row, but our addon label is
   long enough on a 360px-max card that it butts straight into the price
   with zero space between them. Force a minimum gap and allow wrapping. */
.price-card__addon { gap: var(--sp-2) var(--sp-3); flex-wrap: wrap; }

.price-card__unit {
  font-family: var(--font-body);
  font-weight: 500;
  font-size: var(--fs-body);
  text-transform: none;
  color: var(--muted);
}
.price-note {
  color: var(--muted-on-ink);
  font-size: var(--fs-small);
  max-width: 320px;
  padding-top: var(--sp-2);
}

/* ================= Contact ================= */
.contact__inner {
  display: grid;
  gap: var(--sp-12);
}
@media (min-width: 900px) {
  .contact__inner {
    grid-template-columns: 1fr 1.2fr;
    gap: var(--sp-16);
    align-items: start;
  }
}
.contact__form { max-width: 480px; }
.hidden-field { display: none; }

/* Native validity styling only after interaction, never on page load */
.field .input:user-invalid,
.field select:user-invalid,
.field textarea:user-invalid {
  border-color: #B3261E;
}

/* ================= Footer extras ================= */
.footer__area {
  color: var(--muted-on-ink);
  font-size: var(--fs-small);
  margin-top: var(--sp-3);
  max-width: 260px;
}

/* ================= Media slot =================
   Not used on the page yet (no photography exists — see build brief).
   Drop a real <img>/<picture> inside a .media-slot element later and it
   will hold its aspect ratio without needing any other layout changes. */
.media-slot {
  background: var(--sand);
  border: var(--border);
  aspect-ratio: 4 / 3;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}
.on-ink .media-slot { background: var(--line-on-ink); border-color: var(--line-on-ink); }
.media-slot img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* ================= Motion ================= */
@media (prefers-reduced-motion: reduce) {
  * {
    scroll-behavior: auto !important;
    transition-duration: 0.001ms !important;
    animation-duration: 0.001ms !important;
  }
}
