/* Gecko Lawns clone — custom overrides on top of the compiled Tailwind bundle */

/* iOS Safari auto-zooms any focused input/textarea under 16px. Force 16px on mobile. */
@media (max-width: 767px) {
  input, select, textarea { font-size: 16px !important; }
}

/* Ringing call-button icon wiggle */
@keyframes wiggle {
  0%, 100% { transform: rotate(0deg); }
  20% { transform: rotate(-15deg); }
  40% { transform: rotate(12deg); }
  60% { transform: rotate(-8deg); }
  80% { transform: rotate(5deg); }
}

/* Phone-buzzing-on-a-desk style vibrate, used on the header Call Now icon */
@keyframes phone-vibrate {
  0%, 100% { transform: translate(0, 0); }
  10% { transform: translate(-1.5px, -1px); }
  20% { transform: translate(1.5px, 1px); }
  30% { transform: translate(-1.5px, 1px); }
  40% { transform: translate(1.5px, -1px); }
  50% { transform: translate(-1.5px, -1px); }
  60% { transform: translate(1.5px, 1px); }
  70% { transform: translate(-1.5px, 1px); }
  80% { transform: translate(1.5px, -1px); }
  90% { transform: translate(-1px, 0); }
}
.animate-phone-vibrate { animation: phone-vibrate 0.5s ease-in-out infinite; }

/* Chat popup panel */
#chat-widget-root { max-width: 92vw; }
#chat-panel {
  animation: chat-pop .18s ease-out;
  max-height: min(760px, calc(100vh - 100px));
}
/* Scoped to :not(.hidden) — an unconditional "display: flex" here would beat the
   ".hidden { display:none }" utility class on specificity (ID always beats class),
   permanently defeating the JS open/close toggle regardless of which class is applied. */
#chat-panel:not(.hidden) {
  display: flex;
  flex-direction: column;
}
/* "p-5" isn't in the reused Tailwind bundle (never used on the original site), so it silently
   applies zero padding. Set it explicitly rather than relying on the arbitrary class. */
#chat-panel #chat-form { overflow-y: auto; padding: 1.25rem; }
/* Success/error messages live as siblings of #chat-form (not children) — see main.js notes:
   nesting them inside the form meant form.style.display='none' hid the confirmation too. */
#chat-panel #chat-success,
#chat-panel #chat-error { padding: 0 1.25rem 1.25rem; }
@keyframes chat-pop { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: translateY(0); } }
#chat-toggle-close { display: none; }
#chat-toggle.is-open #chat-toggle-avatar,
#chat-toggle.is-open #chat-toggle-dot { display: none; }
#chat-toggle.is-open #chat-toggle-close { display: flex; }

/* Header close (X) button — "p-1"/"-m-1" also aren't in the bundle. Give it an explicit,
   unambiguous 44x44 tap target instead of relying on classes that resolve to nothing. */
#chat-close {
  width: 44px;
  height: 44px;
  min-height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  background: transparent;
  border: 0;
}

/* Blog cards */
.blog-more-note { color: hsl(var(--muted-foreground, 215 16% 47%)); }

/* Mobile menu */
#mobile-menu.is-open { display: block; }

/* Static review cards (crawlable, above the live Fouita widget) */
.review-card { background: #fff; border: 1px solid rgba(0,0,0,.08); border-radius: 0.75rem; padding: 1.25rem 1.5rem; box-shadow: 0 1px 3px rgba(0,0,0,.06); }
.review-stars { color: #FBBC05; letter-spacing: 2px; }

/* Ensure tap targets are comfortable on phones */
@media (max-width: 480px) {
  a, button { min-height: 40px; }
}

/* Scroll-reveal animations. The "reveal-ready" class is added by JS only once it has
   confirmed it can actually observe and un-hide elements — content is never hidden by
   CSS alone, so a JS failure or slow load never leaves anything permanently invisible. */
html.reveal-ready [data-reveal] {
  opacity: 0;
  transform: translateY(24px);
  transition: opacity .6s ease, transform .6s ease;
}
html.reveal-ready [data-reveal].is-visible {
  opacity: 1;
  transform: translateY(0);
}
@media (prefers-reduced-motion: reduce) {
  html.reveal-ready [data-reveal] {
    opacity: 1;
    transform: none;
    transition: none;
  }
}

/* Tall hero used on the home page and every post/suburb page: taller feature image, lighter overlay so the photo reads.
   Defined here rather than as Tailwind arbitrary values, because the compiled
   stylesheet is pre-built and will not contain new arbitrary class names. */
.hero-tall { min-height: 520px; }
@media (min-width: 768px) { .hero-tall { min-height: 1000px; } }
.hero-scrim { background: rgba(0,0,0,.45); }

/* Slow drift on the home hero. Same 16s ease-in-out alternate feel as the other
   builds, but driven by transform because this hero is an <img>, not a background.
   Stopped completely for anyone who has asked for reduced motion. */
.hero-zoom { animation: heroZoom 16s ease-in-out infinite alternate; will-change: transform; }
@keyframes heroZoom { from { transform: scale(1); } to { transform: scale(1.12); } }
@media (prefers-reduced-motion: reduce) { .hero-zoom { animation: none; transform: none; } }

/* Live character counter under any textarea[maxlength]. */
.char-count { font-size: 12px; color: #6b7280; text-align: right; margin-top: 4px; }

/* ============================================================
   Gecko Lawns brand palette
   Source of truth: OneDrive\5 Claude Files\GECKO-LAWNS-DESIGN.md
   Sampled from gecko-lawns-logo-header.webp. Contrast checked.
   The compiled Tailwind bundle is HSL-token driven, so the whole
   theme is re-skinned by redefining :root here (this file loads
   after style.css). Hardcoded/arbitrary hexes left over from the
   original clone are remapped underneath.
   ============================================================ */
:root {
  /* Raw brand hexes, for anything that needs a literal value */
  --gk-moss:  #12300F;  /* dark anchor        */
  --gk-bark:  #121C0A;  /* body text, outline */
  --gk-fern:  #1A6B28;  /* headings on light  */
  --gk-clover:#3C7A14;  /* links, green text  */
  --gk-lime:  #7CBF2A;  /* primary action     */
  --gk-sprout:#A8DB5A;  /* accent on dark     */
  --gk-sun:   #F0F024;  /* offer bar, badge   */
  --gk-butter:#FFF8C2;  /* soft yellow panel  */
  --gk-meadow:#E9F5CE;  /* proof panel        */
  --gk-bone:  #FAFBF3;  /* page background    */
  --gk-stone: #5E7052;  /* captions           */
  --gk-line:  #DFE6D2;  /* hairline border    */

  /* Theme tokens (H S% L%, consumed as hsl(var(--token))) */
  --background: 0 0% 100%;
  --foreground: 93 47% 7%;      /* Bark  — 17.6:1 on white */
  --card: 0 0% 100%;
  --card-foreground: 93 47% 7%;
  --popover: 0 0% 100%;
  --popover-foreground: 93 47% 7%;
  --primary: 87 64% 46%;             /* Lime — fills only */
  --primary-foreground: 114 52% 12%; /* Moss on Lime — 6.4:1 */
  --secondary: 78 66% 88%;           /* Meadow */
  --secondary-foreground: 130 61% 26%; /* Fern */
  --muted: 68 50% 97%;               /* Bone */
  --muted-foreground: 96 15% 38%;    /* Stone — 5.2:1 on Bone */
  --accent: 84 64% 61%;              /* Sprout */
  --accent-foreground: 114 52% 12%;
  --border: 81 29% 86%;
  --input: 81 29% 86%;
  --ring: 87 64% 46%;
  --sidebar-background: 68 50% 97%;
  --sidebar-foreground: 93 47% 7%;
  --sidebar-primary: 87 64% 46%;
  --sidebar-primary-foreground: 114 52% 12%;
  --sidebar-accent: 78 66% 88%;
  --sidebar-accent-foreground: 130 61% 26%;
  --sidebar-border: 81 29% 86%;
  --sidebar-ring: 87 64% 46%;
}

/* Lime is a FILL colour only — 2.3:1 on white, it fails as text.
   Green text and links use Clover (5.3:1). This splits the single
   --primary token back into "fill = Lime" / "text = Clover". */
.text-primary { color: var(--gk-clover); }
.hover\:text-primary:hover { color: var(--gk-clover); }

/* Dark blocks are Moss, the brand's ground, not near-black Bark. */
.bg-foreground { background-color: var(--gk-moss); }
.text-background { color: var(--gk-bone); }

/* Hero headline accent: Sprout is the accent-on-dark colour.
   (The Moss --primary-foreground would vanish against the photo.) */
.hero-accent { color: var(--gk-sprout); }

/* --- Leftover hardcoded hexes from the original clone -------------
   Matched on the class attribute rather than the escaped arbitrary
   selectors, so a rebuild of the bundle can't quietly drop these. */
[class*="bg-[#4CAF50]"] {                      /* material green CTA */
  background-color: var(--gk-lime) !important;
  color: var(--gk-moss) !important;            /* was text-white: 2.3:1 on Lime */
}
[class*="hover:bg-[#45a049]"]:hover { background-color: #6FAD22 !important; } /* Moss on this: 5.4:1 */
[class*="bg-[#33691e]"] { background-color: var(--gk-moss) !important; }
[class*="text-[#33691e]"] { color: var(--gk-moss) !important; }
[class*="bg-[#22c55e]"] { background-color: var(--gk-lime) !important; }      /* chat "online" dot */
[class*="bg-[#f0f9f0]"] { background-color: var(--gk-meadow) !important; }
input[type="radio"], input[type="checkbox"] { accent-color: var(--gk-clover) !important; } /* beats inline accent-color */

/* ============================================================
   Theme pass — bring this site's look in line with the
   geckolawns.nz licence page (same brand, tighter, warmer).
   Palette was already shared; what differed was the *surfaces*:
   white page + light header + square buttons here, versus
   Bone page + Moss masthead + pill buttons there.
   All of it is done from this file so the 20 static pages
   stay untouched.
   ============================================================ */

/* --- 1. Surfaces -------------------------------------------
   Bone is the page ground, not white. Alternating sections go
   to a light Meadow tint instead of Bone, so the rhythm still
   reads once the body itself is Bone. Cards stay pure white
   and now actually pop off both. */
:root {
  --background: 68 50% 97%;   /* Bone   — page ground */
  --muted: 78 55% 93%;        /* Meadow tint — alternating section */
}

/* --- 2. Masthead is Moss ------------------------------------
   The header logo is dark-outlined with a Lime/Sun wordmark, so
   it reads better on Moss than it ever did on white. */
header[class*="bg-background"],
.md\:hidden.sticky[class*="bg-background"] {
  background-color: var(--gk-moss) !important;
  border-color: rgba(255, 255, 255, .12) !important;
}
header[class*="bg-background"] nav a { color: rgba(255, 255, 255, .86) !important; }
header[class*="bg-background"] nav a:hover { color: #fff !important; }
header[class*="bg-background"] button { color: #fff !important; }
#mobile-menu {
  background-color: var(--gk-moss) !important;
  border-top-color: rgba(255, 255, 255, .12) !important;
}
#mobile-menu a { color: #fff !important; border-bottom-color: rgba(255, 255, 255, .14) !important; }

/* --- 3. Pill buttons ---------------------------------------
   The licence page has one radius for actions: fully round.
   Matched on "inline-flex + rounded-md" so it only catches
   buttons — inputs use "flex w-full rounded-md" and are left
   as square-ish fields. */
[class*="inline-flex"][class*="rounded-md"] { border-radius: 999px !important; }

/* --- 4. Type ------------------------------------------------
   Heavier headings on a tighter track, and section headings in
   Moss rather than near-black Bark. */
h1, h2, h3 { letter-spacing: -.02em; }
h1, h2 { font-weight: 800 !important; }
h1[class*="text-foreground"], h2[class*="text-foreground"], h3[class*="text-foreground"] { color: var(--gk-moss) !important; }

/* --- 5. Hero scrim -----------------------------------------
   Flat 45% black was killing the photo's colour. This is the
   same Moss-tinted wash the licence hero uses, weighted to the
   bottom so the centred headline still has something to sit on. */
.hero-scrim {
  background: linear-gradient(180deg,
    rgba(7, 15, 5, .62) 0%,
    rgba(7, 15, 5, .40) 38%,
    rgba(10, 22, 7, .82) 100%);
}

/* --- 6. Cards ----------------------------------------------
   Hairline Line border + the soft green-cast shadow, 14px
   radius. Scoped to shadow-sm so the chat panel (shadow-2xl)
   is not caught. */
[class*="rounded-2xl"][class*="shadow-sm"],
.review-card {
  border: 1px solid var(--gk-line) !important;
  border-radius: 14px !important;
  box-shadow: 0 1px 2px rgba(18, 48, 15, .06), 0 8px 24px rgba(18, 48, 15, .08) !important;
}

/* The Google reviews bar carries its own inline <style> further down the
   document, so its 8px radius survives everything above. Pull it into line
   with the pills. Colour is left alone — it is deliberately Google's, not ours. */
.gr-cta { border-radius: 999px !important; }

/* A deeper version of .hero-scrim for a hero photo that is itself busy and
   pale — the contact page sits on a picture of white paper review notes, and
   the lighter wash used over grass and sky leaves white text competing with
   white paper. Same Moss cast, more of it. */
.hero-scrim-deep {
  background:
    radial-gradient(ellipse 72% 62% at 50% 52%,
      rgba(7, 15, 5, .86) 0%,
      rgba(7, 15, 5, .62) 55%,
      rgba(7, 15, 5, .34) 100%),
    linear-gradient(180deg,
      rgba(7, 15, 5, .34) 0%,
      rgba(7, 15, 5, .28) 50%,
      rgba(10, 22, 7, .56) 100%);
}

/* max-w-xl was never used on the original site, so it is not in the compiled
   bundle and has been silently doing nothing — the review cards that carry it
   (contact, about, locations, services, home) have been stretching to the full
   container width instead of the intended 36rem. Same class of trap as the
   "p-5" note further up. Declared here rather than swapped for max-w-2xl so
   the markup keeps saying what it means. */
.max-w-xl { max-width: 36rem; }
