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