/* =========================================================
   GoGypsyGo — Static Home Page Styles
   Ported 1:1 from src/index.css (React project source of truth)
   ========================================================= */

:root {
  --font-heading: 'Playfair Display', Georgia, serif;
  --font-ui: 'Roboto', system-ui, -apple-system, sans-serif;

  --color-primary-maroon: #641415;
  --color-rich-maroon: #a40305;
  --color-dark-maroon: #4A0F10;
  --color-luxury-burgundy: #7A1C1E;
  --color-deep-brown-maroon: #35170C;
  --color-gold: #D4AF37;
  --color-soft-gold: #C89B3C;
  --color-champagne: #641415;
  --color-cream-white: #FFF9F2;
  --color-light-beige: #F5EEE6;
  --color-text: #1F1F1F;
  --color-muted: #666666;
}

html[lang="mr"], html[lang="hi"],
html[data-lang="MR"], html[data-lang="HI"],
[data-lang="MR"], [data-lang="HI"],
.lang-mr, .lang-hi {
  --font-heading: 'Noto Serif Devanagari', 'Playfair Display', Georgia, serif;
  --font-ui: 'Noto Sans Devanagari', 'Roboto', system-ui, -apple-system, sans-serif;
}

/* H8 FINAL IMPROVEMENT PASS Part 22/24 — verified LIVE in the running
   app (Chrome, 375px mobile width, /?lang=mr and /search?lang=mr and
   /events?lang=mr): Devanagari glyphs render visually wider than Latin
   ones at the same font-size, so the mobile header's location chip
   (templates/home/components/header.html's `.js-current-location-
   label-short`, English-tuned to `max-w-[70px]`/`max-w-[90px]`) clipped
   "एक्सप्लोर" (Marathi for "Explore") to "एक्सप्लोर...". Widened ONLY for
   Marathi/Hindi, ONLY on this one element this pass actually found
   clipped live — every other `truncate` in the app (an unusually long
   saved location/place name, for example) is left exactly as-is, since
   removing `truncate` more broadly would risk the opposite problem: a
   genuinely long value breaking the header's layout. Specificity here
   (two selectors) already outranks the single-class Tailwind utility
   it overrides, so no `!important` is needed. */
html[lang="mr"] .js-current-location-label-short,
html[lang="hi"] .js-current-location-label-short {
  max-width: 108px;
}

@media (min-width: 640px) {
  html[lang="mr"] .js-current-location-label-short,
  html[lang="hi"] .js-current-location-label-short {
    max-width: 130px;
  }
}

body {
  font-family: var(--font-ui);
  background-color: #F5EEE6;
  color: #1F1F1F;
  overflow-x: hidden;
  letter-spacing: 0.2px;
  line-height: 1.6;
}

h1, h2, h3, h4, h5, h6, .font-serif-heading {
  font-family: var(--font-heading);
  letter-spacing: normal;
}

.font-sans, .font-ui {
  font-family: var(--font-ui);
}

.card-body { line-height: 1.5; }
.article-body { line-height: 1.8; }

/* Luxury Brand Gradients */
.brand-gradient {
  background: linear-gradient(0deg, rgba(192,54,57,1) 11.2%, rgba(100,20,21,1) 56.8%);
}

.brand-gradient-alt {
  background: linear-gradient(135deg, #a40305 0%, #7A1C1E 50%, #641415 100%);
}

.gold-gradient {
  background: linear-gradient(135deg, #D4AF37 0%, #C89B3C 100%);
}

/* Glassmorphism card utilities */
.glass-card {
  background: rgba(255, 249, 242, 0.92);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  border: 1px solid rgba(212, 175, 55, 0.3);
  border-radius: 20px;
  box-shadow: 0 8px 30px 0 rgba(74, 15, 16, 0.08);
}

.glass-card-hover {
  transition: all 0.3s cubic-bezier(0.16, 1, 0.3, 1);
}

.glass-card-hover:hover {
  transform: translateY(-3px);
  border-color: rgba(212, 175, 55, 0.6);
  box-shadow: 0 14px 36px 0 rgba(100, 20, 21, 0.15);
}

.glass-header {
  background: linear-gradient(0deg, rgba(192,54,57,1) 11.2%, rgba(100,20,21,1) 56.8%);
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
  border-bottom: 1.5px solid rgba(212, 175, 55, 0.4);
}

.border-gold { border-color: rgba(212, 175, 55, 0.4); }
.text-gold { color: #D4AF37; }
.text-maroon { color: #641415; }

/* Custom Scrollbars */
::-webkit-scrollbar { width: 6px; height: 6px; }
::-webkit-scrollbar-track { background: #F5EEE6; }
::-webkit-scrollbar-thumb { background: #D4AF37; border-radius: 999px; }
::-webkit-scrollbar-thumb:hover { background: #641415; }

.no-scrollbar::-webkit-scrollbar { display: none; }
.no-scrollbar { -ms-overflow-style: none; scrollbar-width: none; }

/* =========================================================
   Utilities present in the React build's Tailwind output that
   aren't part of core Tailwind (no plugin was registered for
   them in package.json) — reproduced here with equivalent,
   understated motion so the static page matches the intended
   visual result described in the design brief.
   ========================================================= */
@keyframes gg-fade-in {
  from { opacity: 0; }
  to { opacity: 1; }
}
.animate-in.fade-in,
.animate-in.fade-in-0 {
  animation: gg-fade-in 0.35s ease-out;
}

@keyframes gg-slide-in-from-bottom {
  from { transform: translateY(16px); opacity: 0.4; }
  to { transform: translateY(0); opacity: 1; }
}
.animate-in.slide-in-from-bottom {
  animation: gg-slide-in-from-bottom 0.3s cubic-bezier(0.16, 1, 0.3, 1);
}

@keyframes gg-spin-slow {
  to { transform: rotate(360deg); }
}
.animate-spin-slow {
  animation: gg-spin-slow 8s linear infinite;
}

/* line-clamp fallback (Tailwind's core plugin already covers this,
   kept here so the static page never depends on CDN version) */
.line-clamp-1 {
  display: -webkit-box;
  -webkit-line-clamp: 1;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.line-clamp-2 {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* Lucide icon sizing helper — mirrors the w-*/h-* utility classes
   applied directly to <i data-lucide> tags */
[data-lucide] {
  display: inline-block;
  vertical-align: middle;
  flex-shrink: 0;
}

/* Toast (placeholder-navigation feedback) */
#gg-toast-root {
  position: fixed;
  left: 50%;
  bottom: 84px;
  transform: translateX(-50%);
  z-index: 70;
  display: flex;
  flex-direction: column;
  gap: 8px;
  align-items: center;
  pointer-events: none;
}
@media (min-width: 1024px) {
  #gg-toast-root { bottom: 24px; }
}
.gg-toast {
  background: #35170C;
  color: #FFF9F2;
  border: 1px solid rgba(212,175,55,0.5);
  padding: 8px 16px;
  border-radius: 999px;
  font-size: 12px;
  font-weight: 600;
  box-shadow: 0 8px 24px rgba(0,0,0,0.25);
  animation: gg-fade-in 0.2s ease-out;
  white-space: nowrap;
}

/* Simple skeleton shimmer used only if an image is slow to load */
.gg-img-fallback {
  background: linear-gradient(90deg, #F5EEE6 25%, #FFF9F2 37%, #F5EEE6 63%);
}

/* text selection color (mirrors selection:bg-[#D4AF37] selection:text-white
   from the React root container; kept as a plain rule too since ::selection
   does not support the `selection:` Tailwind variant on every CDN version) */
.gg-selection ::selection { background: #D4AF37; color: #ffffff; }
::selection { background: #D4AF37; color: #ffffff; }

/* Tailwind v4 introduced shadow-2xs (the React source's Tailwind version);
   the v3 CDN build used here doesn't ship that token, so it's defined here */
.gg-shadow-2xs { box-shadow: 0 1px 1px 0 rgb(0 0 0 / 0.04); }

/* BottomNavigation's center "+" icon uses stroke-[3] in the React source */
.gg-fab-plus-icon { stroke-width: 3; }

/* =========================================================
   Preloader (new — branded GoGypsyGo loading screen, section 7
   of the PHP-view conversion brief)
   ========================================================= */
#gg-preloader {
  position: fixed;
  inset: 0;
  z-index: 100;
  display: flex;
  align-items: center;
  justify-content: center;
  background: linear-gradient(160deg, #3D0A0C 0%, #641415 55%, #35170C 100%);
  transition: opacity 0.5s ease, visibility 0.5s ease;
}
#gg-preloader.gg-preloader-hidden {
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
}
/* CSS-only fallback: guarantees the preloader clears itself even if
   static/js/preloader.js is delayed or fails to load, so the Home
   page is never permanently blocked by JS. */
#gg-preloader {
  animation: gg-preloader-fallback-hide 0s linear 3.2s forwards;
}
@keyframes gg-preloader-fallback-hide {
  to { opacity: 0; visibility: hidden; pointer-events: none; }
}

.gg-preloader-ring {
  position: absolute;
  inset: 0;
  margin: auto;
  width: 140px;
  height: 140px;
  border-radius: 999px;
  border: 2px solid rgba(212, 175, 55, 0.25);
  border-top-color: #D4AF37;
  animation: gg-preloader-spin 1.4s linear infinite;
}
.gg-preloader-ring-outer {
  width: 176px;
  height: 176px;
  border-width: 1px;
  border-top-color: rgba(212, 175, 55, 0.65);
  animation-duration: 2.4s;
  animation-direction: reverse;
}
@keyframes gg-preloader-spin {
  to { transform: rotate(360deg); }
}
.gg-preloader-glow {
  position: absolute;
  inset: 0;
  margin: auto;
  width: 220px;
  height: 220px;
  border-radius: 999px;
  background: radial-gradient(circle, rgba(212, 175, 55, 0.28) 0%, rgba(212, 175, 55, 0) 70%);
  animation: gg-preloader-pulse 2.2s ease-in-out infinite;
}
@keyframes gg-preloader-pulse {
  0%, 100% { opacity: 0.6; transform: scale(0.96); }
  50% { opacity: 1; transform: scale(1.04); }
}
.gg-preloader-logo {
  position: relative;
  z-index: 1;
  animation: gg-preloader-glossy 2.6s ease-in-out infinite;
}
@keyframes gg-preloader-glossy {
  0%, 100% { filter: drop-shadow(0 0 10px rgba(212, 175, 55, 0.35)); }
  50% { filter: drop-shadow(0 0 22px rgba(212, 175, 55, 0.65)); }
}
.gg-preloader-dot {
  animation: gg-preloader-dot-bounce 1.2s ease-in-out infinite;
}
.gg-preloader-dot:nth-child(2) { animation-delay: 0.15s; }
.gg-preloader-dot:nth-child(3) { animation-delay: 0.3s; }
@keyframes gg-preloader-dot-bounce {
  0%, 80%, 100% { transform: translateY(0); opacity: 0.5; }
  40% { transform: translateY(-4px); opacity: 1; }
}

/* If JS is unavailable entirely, this stylesheet still can't know
   "the page is ready" — the 3.2s CSS fallback animation above handles
   that case so the preloader never blocks the page indefinitely. */

/* =========================================================
   A4 UI/UX PASS — Premium Article/Travel Story Experience
   (templates/home/article_detail.html, static/js/
   article_experience.js, and small feed.html card additions)
   ========================================================= */

/* PWA-readiness: base.html now sets viewport-fit=cover so a fixed
   bottom bar can sit flush with the screen edge on notched/gesture-nav
   phones WITHOUT being obscured by the OS's own home-indicator area —
   env() resolves to 0 on browsers that don't support viewport-fit, so
   this is a no-op there (see spec item 26). Applied to the pre-existing
   Home bottom nav too so it isn't regressed by the viewport change. */
.gg-safe-bottom { padding-bottom: env(safe-area-inset-bottom, 0px); }
.gg-safe-top { padding-top: env(safe-area-inset-top, 0px); }

/* Article Detail's own contextual bottom action bar (spec item 2) —
   deliberately separate from Home's 5-tab app nav (bottom_navigation
   .html): this one is about acting on THIS article (Home/Listen/Like/
   Comment/Share), not general site navigation. */
.gg-article-bottombar {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 40;
}
.gg-article-bottombar-inner {
  display: flex;
  align-items: center;
  justify-content: space-around;
  max-width: 28rem;
  margin: 0 auto;
  padding: 0.4rem 0.5rem;
}
.gg-article-bottombar button,
.gg-article-bottombar a {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  min-width: 3rem;
  padding: 0.25rem 0.4rem;
  font-size: 10px;
  font-weight: 700;
  color: rgba(255, 255, 255, 0.82);
  text-decoration: none;
  background: none;
  border: none;
  transition: color 0.15s ease, transform 0.15s ease;
}
.gg-article-bottombar button:active,
.gg-article-bottombar a:active { transform: scale(0.92); }
.gg-article-bottombar button.gg-active,
.gg-article-bottombar button[aria-pressed="true"] { color: #D4AF37; }

/* Page padding so the fixed bottom bar never covers the last bit of
   content (spec item 2: "Do not allow the bottom bar to cover article
   content") — only needed below lg, where the bar itself shows. */
.gg-article-bottombar-spacer { height: 0; }
@media (max-width: 1023px) {
  .gg-article-bottombar-spacer { height: 4.25rem; }
}
@media (min-width: 1024px) {
  .gg-article-bottombar { display: none; }
}

/* Returned-to-card highlight (spec item 3: Back to Home restores
   position at the same Article card) — a brief gold pulse, not a
   permanent style change. */
@keyframes gg-card-highlight {
  0%, 100% { box-shadow: 0 0 0 0 rgba(212, 175, 55, 0); }
  25% { box-shadow: 0 0 0 4px rgba(212, 175, 55, 0.55); }
}
.gg-card-highlight {
  animation: gg-card-highlight 1.6s ease-out 2;
  scroll-margin-top: 84px;
}

/* Gallery image counter chip ("1 / 6" — spec item 4) */
.gg-gallery-counter {
  font-variant-numeric: tabular-nums;
}

/* "About this story" highlighted intro box (spec item 7) */
.gg-story-intro {
  position: relative;
  background: linear-gradient(160deg, rgba(212, 175, 55, 0.12) 0%, rgba(255, 249, 242, 0.9) 60%);
  border: 1px solid rgba(212, 175, 55, 0.45);
  border-left: 3px solid #D4AF37;
  border-radius: 16px;
  padding: 14px 16px;
}

/* Long-form article typography (spec items 8-9) — justified body copy
   on a comfortable measure, headings/labels stay left-aligned (never
   targeted by this rule since it's scoped to the body copy container,
   not applied globally). */
.gg-article-copy {
  max-width: 68ch;
  font-size: 15px;
  line-height: 1.85;
}
@media (min-width: 640px) {
  .gg-article-copy { font-size: 15.5px; }
}
.gg-justify { text-align: justify; text-justify: inter-word; }

/* Listen (Web Speech API) control states (spec item 10) */
.gg-listen-btn[data-state="playing"] { color: #a40305; }
.gg-listen-btn[data-state="paused"] { color: #641415; }

/* Premium Additional-Information tabs (spec item 12) — horizontally
   scrollable on mobile instead of wrapping into a multi-line mess. */
.gg-tabs-scroll {
  display: flex;
  gap: 0.5rem;
  overflow-x: auto;
  scroll-snap-type: x proximity;
  -webkit-overflow-scrolling: touch;
  padding-bottom: 2px;
}
.gg-tabs-scroll::-webkit-scrollbar { display: none; }
.gg-tabs-scroll { scrollbar-width: none; -ms-overflow-style: none; }
.gg-tabs-scroll > button { scroll-snap-align: start; white-space: nowrap; flex-shrink: 0; }

/* Additional-Information section expand/collapse (spec item 13) */
.gg-info-section-body {
  position: relative;
  max-height: 220px;
  overflow: hidden;
}
.gg-info-section-body.gg-expanded { max-height: none; }
.gg-info-section-body:not(.gg-expanded)::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 56px;
  background: linear-gradient(to bottom, rgba(255, 249, 242, 0) 0%, rgba(255, 249, 242, 0.96) 85%);
  pointer-events: none;
}

/* Comment bottom-sheet / modal (spec item 16). Bottom sheet on mobile,
   centered modal from sm+ up. Originally built for Article Detail's
   #commentSheet only, UI-ready but with no backend; A4-D.6 gave it a
   real comment thread, and this same markup/CSS is now reused for
   Home's own #homeCommentSheet (A4-D.6 IMPROVEMENT PASS — PART 2) —
   one comment-sheet look across both pages, per spec PART 8's "Home
   and Detail must be consistent" rule.

   A4-D.6 IMPROVEMENT PASS — PART 2 FIX: real mobile testing found
   comments not scrolling correctly inside the sheet — the classic
   flexbox bug where a flex child's default min-height (`auto`) refuses
   to shrink below its own content size, so `overflow-y: auto` on
   #commentSheetList/#homeCommentSheetList never actually kicked in and
   the PANEL grew/overflowed instead of the LIST scrolling inside it.
   `min-height: 0` on the scrollable child is the standard fix — see
   the two rules below. Also switched the mobile height from `vh` to
   `dvh` (falls back harmlessly where unsupported) so the sheet sizes
   itself to the browser's actual visible viewport rather than the
   full layout viewport, which is what was letting the sheet run
   UNDER the mobile browser chrome / bottom nav (spec PART 2: "no
   content should be hidden behind browser bottom navigation";
   "keyboard opening should not destroy the layout"). */
.gg-comment-sheet {
  position: fixed;
  inset: 0;
  z-index: 70;
  display: flex;
  align-items: flex-end;
  justify-content: center;
}
@media (min-width: 640px) {
  .gg-comment-sheet { align-items: center; }
}
.gg-comment-sheet-panel {
  width: 100%;
  max-height: 80vh;
  max-height: 80dvh;
  background: #FFF9F2;
  border: 1px solid rgba(212, 175, 55, 0.4);
  border-radius: 20px 20px 0 0;
  box-shadow: 0 -8px 30px rgba(74, 15, 16, 0.18);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  /* Safe-area padding so the composer never sits under a device's
     home-indicator / gesture bar (spec PART 2's mobile requirements) —
     harmless no-op on devices/browsers without a safe-area inset. */
  padding-bottom: env(safe-area-inset-bottom, 0px);
}
@media (min-width: 640px) {
  .gg-comment-sheet-panel {
    max-width: 28rem;
    max-height: 70vh;
    max-height: 70dvh;
    border-radius: 20px;
    box-shadow: 0 20px 50px rgba(74, 15, 16, 0.25);
    padding-bottom: 0;
  }
}
/* THE FIX: both #commentSheetList (Article Detail) and
   #homeCommentSheetList (Home) already carry Tailwind's `flex-1
   overflow-y-auto` utility classes in their markup — `min-height: 0`
   here is the one declaration Tailwind's own utility set doesn't
   provide, and is what actually makes that overflow rule take effect
   inside a flex column instead of the whole panel growing past its
   own max-height. */
#commentSheetList,
#homeCommentSheetList {
  min-height: 0;
}

/* NOTE: an earlier drop had a ".gg-video-facade" class here for a
   thumbnail-plus-fake-play-button Home preview. The A4 HOME FEED MEDIA
   CORRECTION removed that treatment entirely — a video is now either
   the real embed (Home Feed Display = "YouTube Video") or not shown at
   all on Home (Display = "Image / Gallery"), never an image styled to
   look like a paused video. See templates/home/components/feed.html.
*/

/* A4-D.9.23.1 — PUBLIC BUSINESS PROFILE 2.0. A jump target used by the
   new section nav (Overview/Offerings/Reviews/Photos/Location/About)
   so a smooth-scroll lands BELOW the sticky nav bar itself, not
   underneath it — mirrors .gg-card-highlight's own identical
   scroll-margin-top convention above, just reusable as a plain,
   non-animated class. */
.gg-section-anchor {
  scroll-margin-top: 88px;
}
html {
  scroll-behavior: smooth;
}
@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }
}

/* A4-D.9.23.1 — a small, dependency-free horizontal-scroll "carousel"
   for the Offerings tabs (Products/Services/Rooms) — same no-scrollbar
   + scroll-snap treatment .gg-tabs-scroll already uses above, just
   sized for a card strip instead of a row of tab buttons. */
.gg-carousel {
  display: flex;
  gap: 0.75rem;
  overflow-x: auto;
  scroll-snap-type: x proximity;
  -webkit-overflow-scrolling: touch;
  padding-bottom: 2px;
}
.gg-carousel::-webkit-scrollbar { display: none; }
.gg-carousel { scrollbar-width: none; -ms-overflow-style: none; }
.gg-carousel > * { scroll-snap-align: start; }

/* A4-D.9.23.1 — the active state for an Offerings tab button
   (static/js/business_offerings_tabs.js toggles this on click; the
   server also renders the FIRST enabled tab with it already applied,
   so the correct tab is highlighted even with JavaScript disabled). */
.gg-tab-active {
  background: #641415;
  color: #ffffff;
}

/* A4-D.9.23.1 — the About section's <details>/<summary> accordion
   chevron rotates open/closed; kept as a plain class toggled by a
   small inline script (not a Tailwind `group-open:` variant) so it
   behaves identically regardless of which Tailwind build serves this
   page. */
.gg-accordion-chevron {
  transition: transform 0.2s ease;
}
.gg-accordion-chevron.gg-rotated {
  transform: rotate(180deg);
}

/* H17 (sidebar/footer/about/contact chunk) — templates/home/components/
   floating_support.html's floating WhatsApp button: a small, slow,
   CSS-only pulse ring, deliberately subtle (spec's own "animated/
   vibrant but subtle... no aggressive animation" instruction) — same
   "plain CSS class, no new JS/library" approach as .gg-preloader-pulse
   above, just a softer amplitude/longer duration since this one runs
   indefinitely on every public page rather than only during a brief
   page-load preloader. */
/* H17 DROP 3.2 — FLOATING CONTROLS, REAL FIXED POSITIONING.
   templates/home/components/floating_support.html (WhatsApp) and
   templates/home/components/back_to_top.html previously relied on
   Tailwind's own JIT-generated `.fixed`/`left-*`/`bottom-*`/`right-*`/
   `z-*` utility classes for their positioning. Those utility rules are
   injected into <head> by the Tailwind Play CDN script at runtime
   (static/css/tailwind.css's own documented "no build pipeline yet"
   note) — whether that injected stylesheet ends up BEFORE or AFTER this
   file's own `<link rel="stylesheet" href=".../gypsy.css">` in cascade
   order is not something this project's `<script>`-tag-based CDN setup
   guarantees, and two same-specificity single-class rules for the same
   property resolve to whichever one is LATER in that order — the exact
   kind of UI non-determinism live browser testing flagged ("not
   reliably fixed... positioned with page content"). The fix is to stop
   depending on that ordering at all: every positioning property these
   two controls need (position/left/right/bottom/z-index, plus their
   full visual shape) is now defined ONCE, explicitly, right here in
   GYPSY's own stylesheet — no Tailwind utility classes are used for
   positioning on either element any more (see both templates' own
   updated class lists). z-index stays 40, unchanged from before and
   consistent with every other site-wide floating control in this file
   (the header is also z-40; modals are z-50/60/70, intentionally above
   these two). */
.gg-whatsapp-float {
  position: fixed;
  left: 1rem;
  right: auto;
  bottom: 5rem;
  z-index: 40;
  width: 3rem;
  height: 3rem;
  border-radius: 9999px;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.15), 0 8px 10px -6px rgba(0, 0, 0, 0.15);
  background: #25D366;
  animation: gg-float-pulse-ring 2.4s ease-in-out infinite;
}
@media (min-width: 1024px) {
  .gg-whatsapp-float {
    left: auto;
    right: 1.5rem;
    bottom: 1.5rem;
  }
}
@keyframes gg-float-pulse-ring {
  0%, 100% { box-shadow: 0 0 0 0 rgba(37, 211, 102, 0.45); }
  50% { box-shadow: 0 0 0 8px rgba(37, 211, 102, 0); }
}

/* templates/home/components/back_to_top.html, toggled by static/js/
   back_to_top.js. Hidden by default (opacity 0 + no pointer events, NOT
   display:none, so the opacity transition below can actually animate it
   in/out) — .gg-visible is added once the page has scrolled past the
   threshold. Stacks directly above .gg-whatsapp-float on the same side
   on mobile (bottom-36 = 9rem, one offset step above WhatsApp's own
   bottom-20 = 5rem) so the two never overlap; see the modifier class
   below for the one case (desktop, Home page only) where its LEFT
   offset differs from WhatsApp's. */
.gg-back-to-top {
  position: fixed;
  left: 1rem;
  bottom: 9rem;
  z-index: 40;
  width: 2.5rem;
  height: 2.5rem;
  border-radius: 9999px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #ffffff;
  border: 1px solid rgba(212, 175, 55, 0.4);
  box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.15), 0 8px 10px -6px rgba(0, 0, 0, 0.15);
  color: #641415;
  opacity: 0;
  pointer-events: none;
  transform: translateY(8px);
  transition: opacity 0.2s ease, transform 0.2s ease, background-color 0.2s ease;
}
.gg-back-to-top:hover {
  background: #FFF9F2;
}
.gg-back-to-top.gg-visible {
  opacity: 1;
  pointer-events: auto;
  transform: translateY(0);
}
@media (min-width: 1024px) {
  .gg-back-to-top {
    left: 1.5rem;
    bottom: 1.5rem;
  }
  /* Home only (templates/home/components/left_sidebar.html is an
     in-flow, static 320px column there on desktop, not an overlay — see
     back_to_top.html's own docstring) — clears that column's width with
     a one-rem gap instead of sitting on top of it. */
  .gg-back-to-top.gg-back-to-top--home {
    left: 21rem;
  }
}

/* =========================================================
   H17 FINAL UI/UX POLISH PASS — mobile floating utility rail,
   mobile ad-action reveal-on-tap, and a couple of small footer/FAB
   sizing tweaks. See templates/home/components/
   mobile_utility_rail.html's own docstring for the full reasoning.
   ========================================================= */

/* The standalone WhatsApp float and Back-to-Top button are replaced by
   .gg-utility-rail below AT EVERY WIDTH as of the H17 FINAL CORRECTION
   PASS (Part 1) — previously this was a mobile-only swap (the rule
   re-enabled `display: flex` at >=1024px); now that the rail itself
   renders on desktop/tablet too (see .gg-utility-rail below), these two
   original elements are simply retired everywhere, unconditionally.
   This is a literal, unconditional display rule in THIS stylesheet only
   (never a Tailwind `hidden` utility class on these two elements) —
   putting `display` under the control of two different stylesheets for
   the same element is exactly the cascade-order hazard already fixed
   for `position`/`left`/`bottom` on these same two controls (see their
   own rules above). Their templates (floating_support.html/
   back_to_top.html) are still included site-wide from base.html,
   unchanged — hiding them here rather than removing the include keeps
   static/js/back_to_top.js's existing "toggle .gg-visible on every
   .gg-back-to-top-trigger element" behavior harmlessly running against
   an element that is simply never shown, with zero risk to any other
   page's template logic (e.g. the Home-only `.gg-back-to-top--home`
   sidebar-offset modifier). */
.gg-whatsapp-float,
.gg-back-to-top {
  display: none !important;
}

.gg-utility-rail {
  position: fixed;
  left: -5px;
  top: 50%;
  transform: translateY(-50%);
  z-index: 40;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  background: #641415;
  border-radius: 0 0.875rem 0.875rem 0;
  box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.15), 0 8px 10px -6px rgba(0, 0, 0, 0.15);
  overflow: hidden;
  padding: 0.25rem 0;
}
/* H17 FINAL CORRECTION PASS — PART 1: Home's left_sidebar.html is an
   in-flow, static 320px column on desktop only (`lg:static lg:w-80`,
   i.e. >=1024px) — see back_to_top.html's own docstring, which already
   solved this exact problem for the old standalone button with the
   same 21rem value. The rail reuses that identical, already-correct
   offset rather than inventing a second number. Below 1024px (including
   tablet widths, where Home's sidebar is not an in-flow column) the
   rail stays flush at the left edge. */
@media (min-width: 1024px) {
  .gg-utility-rail.gg-utility-rail--home {
    left: -3px;
  }
}
/* On a real mouse/trackpad (never a touch-only phone or tablet — see
   static/js/mobile_utility_rail.js's matching `(hover: hover) and
   (pointer: fine)` check, which also skips its own tap-to-reveal
   interception on exactly these devices), hovering the rail reveals
   the labels the same way tapping does on touch, and moving the mouse
   away collapses it again — no JS needed for this part, the same way
   :focus-within below needs none for keyboard users. This is additive:
   it changes nothing about how `.gg-expanded`/`:focus-within` already
   work for touch/keyboard. */
@media (hover: hover) and (pointer: fine) {
  .gg-utility-rail:hover .gg-utility-rail-label {
    max-width: 6rem;
    opacity: 1;
    margin-left: 0.1rem;
    padding-right: 0.85rem;
  }
}
.gg-utility-rail-btn {
  display: flex;
  align-items: center;
  justify-content: flex-start;
  border: none;
  background: transparent;
  color: #D4AF37;
  text-decoration: none;
  cursor: pointer;
  padding: 0;
  font-family: var(--font-ui);
}
.gg-utility-rail-btn + .gg-utility-rail-btn {
  border-top: 1px solid rgba(212, 175, 55, 0.25);
}
.gg-utility-rail-btn:active {
  background: rgba(212, 175, 55, 0.15);
}
.gg-utility-rail-btn:focus-visible {
  outline: 2px solid #D4AF37;
  outline-offset: -2px;
}
.gg-utility-rail-icon {
  width: 2rem;
  height: 2rem;
  min-width: 2rem;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}
.gg-utility-rail-label {
  max-width: 0;
  opacity: 0;
  margin-left: 0;
  overflow: hidden;
  white-space: nowrap;
  font-size: 10px;
  font-weight: 700;
  padding-right: 0;
  transition: max-width 0.22s ease, opacity 0.18s ease, margin-left 0.22s ease, padding-right 0.22s ease;
}
.gg-utility-rail.gg-expanded .gg-utility-rail-label,
.gg-utility-rail:focus-within .gg-utility-rail-label {
  max-width: 6rem;
  opacity: 1;
  margin-left: 0.1rem;
  padding-right: 0.85rem;
}
/* Back-to-top's row inside the rail keeps the SAME "hidden until
   scrolled past the threshold" behavior as the desktop button — toggled
   by the same static/js/back_to_top.js, via the same .gg-visible class,
   now applied to every .gg-back-to-top-trigger element it finds. */
.gg-utility-rail-btn.gg-back-to-top-trigger {
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.2s ease;
}
.gg-utility-rail-btn.gg-back-to-top-trigger.gg-visible {
  opacity: 1;
  pointer-events: auto;
}
/* A restrained, non-repeating pulse so a first-time visitor notices the
   rail is interactive — finite iteration-count, never infinite, and
   skipped entirely under reduced motion (the expand/collapse
   interaction itself is unaffected, since it is functional, not
   decorative). */
@keyframes gg-rail-pulse-hint {
  0%, 100% { box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.15), 0 8px 10px -6px rgba(0, 0, 0, 0.15); }
  50% { box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.15), 0 8px 10px -6px rgba(0, 0, 0, 0.15), 0 0 0 6px rgba(212, 175, 55, 0.3); }
}
.gg-utility-rail.gg-pulse-hint {
  animation: gg-rail-pulse-hint 1.6s ease-in-out 2;
}
@media (prefers-reduced-motion: reduce) {
  .gg-utility-rail.gg-pulse-hint {
    animation: none;
  }
}

/* H17 FINAL UI/UX POLISH PASS — live mobile QA: the rail is fixed and
   vertically centered (~50vh) regardless of scroll position, so on a
   long page it can land on top of whatever happens to be at that band
   — most visibly templates/home/components/footer.html's own Support
   column, whose links/contact lines otherwise start flush against the
   same left edge (see that file's own comment on `.gg-footer-inner`).
   A static left-padding reserve for the rail's width is simpler and
   more robust than trying to detect/avoid the rail's position
   dynamically, and only applies below 1024px — the footer's desktop
   layout (where the rail never renders) is completely untouched. */
@media (max-width: 1023px) {
  /* !important here (the one exception in this stylesheet, see this
     file's own note above its very first rule on why !important is
     normally unnecessary): footer.html's wrapper carries Tailwind's own
     `px-4` utility for its base padding, and live testing showed the
     Tailwind CDN's own injected stylesheet is NOT reliably ordered
     before this one in every load — exactly the same non-deterministic-
     injection-order risk already documented for this rail elsewhere in
     this file, just landing on `padding-left` instead of `display`/
     `position` this time. A plain cascade-order rule silently lost to
     `px-4` in testing; `!important` is the only way to guarantee this
     specific, narrow safety margin always applies. */
  .gg-footer-inner {
    padding-left: 2.75rem !important;
  }
}

/* H17 FINAL UI/UX POLISH PASS — PART 5: mobile_facility_fab.html's
   "Find Nearby" trigger, compacted to icon-only by default on mobile,
   with a brief ONE-TIME label reveal on page load rather than the
   label being permanently shown (which is what made it consume too
   much feed width). Tapping it still opens the sheet immediately, every
   time — this pass never added a reveal-first step to this particular
   control, since unlike the ad action buttons or the new utility rail,
   a single, well-known destination for this icon already existed
   (`aria-label`), and a reveal-before-open pattern would only add
   friction to an action users already understand and use often. */
#mobileFabTrigger {
  width: 2.75rem;
  height: 2.75rem;
  padding: 0;
  justify-content: center;
  border-radius: 9999px;
}
#mobileFabTrigger .gg-fab-label {
  max-width: 0;
  opacity: 0;
  margin-left: 0;
  overflow: hidden;
  white-space: nowrap;
  transition: max-width 0.3s ease, opacity 0.25s ease, margin-left 0.3s ease;
}
@keyframes gg-fab-reveal-hint {
  0%, 18% { max-width: 0; opacity: 0; margin-left: 0; }
  28%, 72% { max-width: 7rem; opacity: 1; margin-left: 0.5rem; }
  100% { max-width: 0; opacity: 0; margin-left: 0; }
}
#mobileFabTrigger .gg-fab-label {
  animation: gg-fab-reveal-hint 4.5s ease-in-out 1 both;
}
#mobileFabTrigger:hover .gg-fab-label,
#mobileFabTrigger:focus-visible .gg-fab-label {
  animation: none;
  max-width: 7rem;
  opacity: 1;
  margin-left: 0.5rem;
}
@media (prefers-reduced-motion: reduce) {
  #mobileFabTrigger .gg-fab-label {
    animation: none;
  }
}

/* H17 FINAL UI/UX POLISH PASS — PART 6: templates/ads/_ad_slot.html's
   image-format action-button row. Previously `opacity-100
   sm:opacity-0 sm:group-hover:opacity-100 sm:group-focus-within:
   opacity-100` (plain Tailwind utility classes only, no competing rule
   in this file) kept it permanently visible on mobile. Now that a
   mobile-only JS-driven `.gg-ad-actions-open` toggle class also needs
   to control this SAME `opacity` property, both the "always-visible-
   until-640px" default AND the desktop hover/focus-within reveal are
   defined here instead, in one place, so `opacity` is never set by two
   different sources for the same element again (the same reasoning as
   the WhatsApp/Back-to-Top fix above) — see _ad_slot.html's own
   updated comment for the template-side half of this. */
.ad-action-overlay {
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.2s ease;
}
.ad-action-overlay.gg-ad-actions-open {
  opacity: 1;
  pointer-events: auto;
}
@media (min-width: 640px) {
  .group:hover .ad-action-overlay,
  .group:focus-within .ad-action-overlay {
    opacity: 1;
    pointer-events: auto;
  }
}
.ad-actions-toggle {
  position: absolute;
  right: 0.5rem;
  bottom: 0.5rem;
  z-index: 5;
  width: 1.75rem;
  height: 1.75rem;
  border-radius: 9999px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(0, 0, 0, 0.55);
  color: #ffffff;
  border: none;
  cursor: pointer;
  transition: transform 0.2s ease, background-color 0.2s ease;
}
.ad-actions-toggle[aria-expanded="true"] {
  transform: rotate(180deg);
  background: rgba(0, 0, 0, 0.75);
}
.ad-actions-toggle:focus-visible {
  outline: 2px solid #D4AF37;
  outline-offset: 2px;
}
@media (min-width: 640px) {
  .ad-actions-toggle {
    display: none;
  }
}

/* =========================================================
   H17 FINAL CORRECTION / UI + TRANSLATION PASS — PARTS 4-5:
   overflow-aware show/hide + boundary-disable for static/js/
   scroll_arrows.js's existing [data-scroll-group]/[data-scroll-left]/
   [data-scroll-right] contract (H17 DROP 3.1, already live on
   templates/home/components/top_reels.html — this pass only makes
   that same script smarter, it does not introduce a second mechanism).
   `.gg-scroll-arrow-hidden` is a plain, literal CSS class (never a
   Tailwind `hidden` utility toggled by JS) for the same reason this
   file avoids that everywhere else: these buttons already carry
   Tailwind's own `hidden lg:flex` utility classes for the breakpoint
   cut, and letting a second stylesheet-driven mechanism fight over the
   same `display` property is the exact cascade-order hazard documented
   at this file's `.gg-whatsapp-float`/`.gg-back-to-top` rules above.
   `!important` here mirrors `.gg-footer-inner`'s own one documented
   exception, for the identical reason: this class must always be able
   to force-hide the arrow regardless of whichever width-based Tailwind
   utility would otherwise apply. ========================================================= */
.gg-scroll-arrow-hidden {
  display: none !important;
}
[data-scroll-left]:disabled,
[data-scroll-right]:disabled {
  opacity: 0.35;
  cursor: default;
  pointer-events: none;
}

/* H17 FINAL CORRECTION / UI + TRANSLATION PASS — PART 4: the same
   generic scroll-arrow treatment applied to Public Facilities' chip
   rows (templates/public/public_facilities.html), styled to match
   those rows' own compact pill language rather than top_reels.html's
   larger card-carousel arrows — smaller, flush to the chip row's own
   rounded corners instead of overlapping past its edge. Desktop/tablet
   only (`lg:flex`, same convention as every other scroll-arrow in this
   file); mobile keeps its existing untouched native touch scroll. */
.gg-chip-scroll-arrow {
  width: 1.75rem;
  height: 1.75rem;
  border-radius: 9999px;
  background: #ffffff;
  border: 1px solid rgba(212, 175, 55, 0.4);
  color: #641415;
  box-shadow: 0 4px 10px -2px rgba(0, 0, 0, 0.15);
}
.gg-chip-scroll-arrow:hover:not(:disabled) {
  background: #FFF9F2;
}

