@tailwind base;
@tailwind components;
@tailwind utilities;

body { font-family: 'Plus Jakarta Sans', sans-serif; overflow-x: hidden; scroll-behavior: smooth; line-height: 1.618; transition: background-color 0.5s ease, color 0.5s ease; }

/* =========================================================================
   Liquid Glass UI Base
   (Optimized: blur radius trimmed slightly — 20px -> 16px reads almost
   identical but is noticeably cheaper for the compositor — and transform
   is promoted to its own layer up front instead of only during transition.)
========================================================================= */
.glass-panel, .glass-card {
  background: rgba(255, 255, 255, 0.45);
  backdrop-filter: blur(16px) saturate(150%);
  -webkit-backdrop-filter: blur(16px) saturate(150%);
  border: 1px solid rgba(255, 255, 255, 0.6);
  box-shadow: 0 20px 40px -10px rgba(1, 45, 29, 0.05);
  transition: background 0.5s ease, border-color 0.5s ease, box-shadow 0.5s ease, transform 0.4s ease;
  transform: translateZ(0);
}

/* Optimized: box-shadow is no longer animated on hover. Animating
   box-shadow forces a repaint every frame; instead we fade in a
   pre-rendered shadow layer on a pseudo-element, which only ever
   animates `opacity` (composited, effectively free). */
.liquid-gradient, .liquid-btn {
  position: relative;
  background: linear-gradient(135deg, #ffdea9, #fdc2a3);
  transition: transform 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275);
  border: 1px solid rgba(255,255,255,0.5);
}

.liquid-gradient::after, .liquid-btn::after {
  content: '';
  position: absolute;
  inset: -4px;
  border-radius: inherit;
  box-shadow: 0 10px 25px -5px rgba(253, 194, 163, 0.6);
  opacity: 0;
  transition: opacity 0.4s ease;
  pointer-events: none;
  z-index: -1;
}

.liquid-gradient:hover, .liquid-btn:hover {
  transform: translateY(-3px) scale(1.02);
}

.liquid-gradient:hover::after, .liquid-btn:hover::after {
  opacity: 1;
}

/* Dark Mode Overrides */
html.dark body { background: #121413; color: #e1e3e1; }
html.dark .glass-panel, html.dark .glass-card {
  background: rgba(26, 28, 27, 0.6);
  border: 1px solid rgba(255, 255, 255, 0.05);
  box-shadow: 0 20px 40px -10px rgba(0, 0, 0, 0.5);
}
html.dark .text-primary { color: #c1ecd4; }
html.dark .text-on-surface-variant { color: #a5a9a6; }
html.dark .bg-surface { background-color: #1a1c1b; }
html.dark .liquid-gradient, html.dark .liquid-btn {
  background: linear-gradient(135deg, #80543b, #653d26);
  border-color: rgba(255,255,255,0.1);
  color: #ffdbca;
}
html.dark .skeleton-bg { background: #2a2c2b; }
html.dark .skeleton-bg::after {
  background: linear-gradient(90deg, transparent, rgba(255,255,255,0.08), transparent);
}
html.dark .bnav-item.active-item { background: rgba(101, 61, 38, 0.85); color: #ffdbca; }
html.dark nav#main-nav { background: rgba(26, 28, 27, 0.8); border-bottom-color: rgba(255,255,255,0.1); }
html.dark .bg-white { background-color: #2a2c2b; color: #c1ecd4; }
html.dark .filter-btn.bg-primary { background-color: #c1ecd4; color: #012d1d; }

/* Enhanced Animated Blobs
   These animate forever (infinite keyframes), so unlike .reveal/.lazy-image
   they never go idle — keeping will-change permanent here is correct. */
.blob-animated {
  transition: background-color 0.7s ease;
  will-change: transform;
}

/* =========================================================================
   Theme Transition Animation Overlay
   `will-change` is now managed dynamically in JS (set right before the
   clip-path animation starts, released to 'auto' right after it ends) —
   see themeToggleBtn click handler in script.js. Do not also set it here:
   a static value in CSS would just get silently overridden by the inline
   style JS sets on every click, so keeping both is redundant/misleading.
   `contain: strict` still isolates this layer's rendering so the browser
   doesn't re-check layout/paint outside its bounds while it animates.
========================================================================= */
.theme-transition-overlay {
  position: fixed; top: 0; left: 0; width: 100vw; height: 100vh;
  background: #121413; z-index: 999999;
  clip-path: circle(0% at 50% 50%);
  pointer-events: none;
  transition: clip-path 0.8s cubic-bezier(0.645, 0.045, 0.355, 1);
  contain: strict;
}
html.dark .theme-transition-overlay { background: #f8f9fa; }

/* =========================================================================
   Skeleton & Lazy
   (Optimized: the shimmer no longer animates `background-position`, which
   forces a full repaint every frame. Instead a translucent highlight band
   slides across via `transform: translateX()` on a pseudo-element, which
   the compositor can animate without repainting the element underneath.)
========================================================================= */
.skeleton-bg {
  position: relative;
  overflow: hidden;
  background: #e5e7eb;
}
.skeleton-bg::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(90deg, transparent, rgba(255,255,255,0.7), transparent);
  transform: translateX(-100%);
  animation: shimmer-slide 1.8s infinite linear;
  will-change: transform;
}
@keyframes shimmer-slide {
  100% { transform: translateX(100%); }
}

/* Optimized: will-change is only applied while an image is actually
   pending/animating (`:not(.loaded)`), so once it finishes loading the
   browser can drop the dedicated compositor layer instead of keeping one
   around for every image on the page indefinitely. */
.lazy-image { opacity: 0; transition: opacity 0.8s ease-in-out, transform 0.8s cubic-bezier(0.2, 0, 0, 1); }
.lazy-image:not(.loaded) { will-change: opacity, transform; }
.lazy-image.loaded { opacity: 1; }

/* Utilities */
#splash-screen { transition: opacity 0.6s ease-out, visibility 0.6s ease-out; }
#splash-screen.hidden-splash { opacity: 0; visibility: hidden; pointer-events: none; }

/* =========================================================================
   Scroll Reveal
   (Optimized: will-change now gates on BOTH `.reveal-armed` AND
   `:not(.visible)`, not just `:not(.visible)` alone. `.reveal-armed` is
   added by a second, wide-rootMargin IntersectionObserver in script.js
   (revealArmObserver) shortly before an element nears the viewport —
   previously every `.reveal` section on the active page got its own
   compositor layer the instant the page loaded, even ones far below the
   fold (e.g. the closing CTA at the bottom of the long "Tentang" page).
   Gating through the observer means a layer is only allocated when the
   element is actually about to be seen, same principle as the lazy-image
   rule above.)
========================================================================= */
.reveal { opacity: 0; transform: translateY(40px); transition: opacity 0.8s cubic-bezier(0.2, 0, 0, 1), transform 0.8s cubic-bezier(0.2, 0, 0, 1); }
.reveal.reveal-armed:not(.visible) { will-change: opacity, transform; }
.reveal.visible { opacity: 1; transform: translateY(0); }
.delay-100 { transition-delay: 100ms; }
.delay-200 { transition-delay: 200ms; }
.delay-300 { transition-delay: 300ms; }
.page { display: none; opacity: 0; transform: translateY(15px); transition: opacity 0.4s ease, transform 0.4s ease; }
.page.active { display: block; }
.page.show { opacity: 1; transform: translateY(0); }

/* Navbar */
.nav-link { position: relative; }
.nav-link::after { content: ''; position: absolute; width: 0%; height: 2px; bottom: -4px; left: 0; background-color: #fdc2a3; transition: width 0.3s ease; }
.nav-link.active-link::after, .nav-link:hover::after { width: 100%; }
html.dark .nav-link::after { background-color: #c1ecd4; }
.bnav-item.active-item { background: rgba(253, 194, 163, 0.85); color: #311302; transform: translateY(-2px); box-shadow: 0 4px 15px rgba(253, 194, 163, 0.4); }

.no-scrollbar::-webkit-scrollbar { display: none; }
.no-scrollbar { -ms-overflow-style: none; scrollbar-width: none; }
.desc-clamp { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.catalog-item { transition: opacity 0.4s ease, transform 0.4s ease; }

/* FAQ accordion */
.faq-item .faq-answer { max-height: 0; overflow: hidden; transition: max-height 0.4s cubic-bezier(0.2,0,0,1), padding 0.3s ease; }
.faq-item.faq-open .faq-answer { max-height: 500px; }
.faq-item .faq-icon { transition: transform 0.3s ease; }
.faq-item.faq-open .faq-icon { transform: rotate(45deg); }

/* Navbar Scroll Smoothing */
nav#main-nav { transition: padding 0.3s ease, background-color 0.3s ease, box-shadow 0.3s ease; }
nav#main-nav.scrolled { padding-top: 0.75rem; padding-bottom: 0.75rem; box-shadow: 0 4px 20px rgba(0,0,0,0.05); }

/* =========================================================================
   Product spec bars (#product-spec1-bar / #product-spec2-bar)
   script.js drives these with `transform: scaleX(value)` instead of the
   `width` property (width animation is layout-triggering; scaleX is a
   compositor-only property). transform-origin must be `left` so the bar
   still shrinks/grows from its starting edge instead of its center.
========================================================================= */
#product-spec1-bar, #product-spec2-bar {
  transform-origin: left;
  transition: transform 0.6s ease;
  will-change: transform;
}

/* Visible keyboard focus (a11y quality floor) */
a:focus-visible, button:focus-visible {
  outline: 2px solid #fdc2a3;
  outline-offset: 3px;
  border-radius: 0.5rem;
}
html.dark a:focus-visible, html.dark button:focus-visible { outline-color: #c1ecd4; }

/* Screen-reader only utility, for live-region page announcements */
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0;
}

/* Respect reduced motion preference: keep the site usable, drop the flourish */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
  .reveal { opacity: 1 !important; transform: none !important; }
  .theme-transition-overlay { display: none !important; }
}