/* =============================================================
 * KABALON Smooth Pack v1 — homepage polish only
 * 13 micro-interactions: entrance / scroll / hover / form / image
 *
 * Performance budget:
 *   - Pure CSS transform + opacity (GPU-accelerated)
 *   - No layout shifts
 *   - No animation libs
 *   - Honors prefers-reduced-motion
 *
 * 2026-04-30 created by smoothness-pack task.
 * ============================================================= */

/* --- Honor user's motion preference: kill all our animations --- */
@media (prefers-reduced-motion: reduce) {
  .hero__eyebrow, .hero h1, .hero__sub, .hero__ctas, .hero__micro,
  .kbn-reveal, .kbn-reveal.kbn-revealed,
  .nav, .product-card, .product-card__image img,
  .sticky-bar__zalo::before, .form-field input, .form-field select,
  img.kbn-img-fade {
    animation: none !important;
    transition: none !important;
    opacity: 1 !important;
    transform: none !important;
    filter: none !important;
  }
}

/* =============================================================
 * #1 — Hero entrance: staggered fade-up on first paint
 *      H1 is the LCP element; keep delay short.
 * ============================================================= */
.hero__eyebrow,
.hero h1,
.hero__sub,
.hero__ctas,
.hero__micro {
  opacity: 0;
  transform: translateY(12px);
  animation: kbn-fade-up 600ms cubic-bezier(0.22, 1, 0.36, 1) forwards;
  will-change: opacity, transform;
}
.hero__eyebrow { animation-delay: 60ms;  }
.hero h1       { animation-delay: 140ms; }
.hero__sub     { animation-delay: 220ms; }
.hero__ctas    { animation-delay: 300ms; }
.hero__micro   { animation-delay: 380ms; }

@keyframes kbn-fade-up {
  to { opacity: 1; transform: translateY(0); }
}

/* =============================================================
 * #2 — Section scroll-triggered fade-up (v2: bigger travel + scale)
 *      JS adds .kbn-reveal to off-screen sections, then
 *      .kbn-revealed when they enter viewport.
 *      Sections already in viewport at init are never hidden.
 * ============================================================= */
.kbn-reveal {
  opacity: 0;
  transform: translateY(40px) scale(0.97);
  transition: opacity 820ms cubic-bezier(0.22, 1, 0.36, 1),
              transform 820ms cubic-bezier(0.22, 1, 0.36, 1);
  will-change: opacity, transform;
}
.kbn-reveal.kbn-revealed {
  opacity: 1;
  transform: translateY(0) scale(1);
}

/* Inner element micro-cascade: when a section reveals, its direct
 * children hierarchy stagger in 60ms apart for a richer feel. */
.kbn-reveal > .wrap > *,
.kbn-reveal > .why__inner > *,
.kbn-reveal > .factory__inner > *,
.kbn-reveal > .testimonials__head,
.kbn-reveal > .testimonials__grid > *,
.kbn-reveal > .form-card > *,
.kbn-reveal .faq-wrap > * {
  opacity: 0;
  transform: translateY(18px);
  transition: opacity 700ms cubic-bezier(0.22, 1, 0.36, 1),
              transform 700ms cubic-bezier(0.22, 1, 0.36, 1);
}
.kbn-reveal.kbn-revealed > .wrap > *,
.kbn-reveal.kbn-revealed > .why__inner > *,
.kbn-reveal.kbn-revealed > .factory__inner > *,
.kbn-reveal.kbn-revealed > .testimonials__head,
.kbn-reveal.kbn-revealed > .testimonials__grid > *,
.kbn-reveal.kbn-revealed > .form-card > *,
.kbn-reveal.kbn-revealed .faq-wrap > * {
  opacity: 1;
  transform: translateY(0);
}
.kbn-reveal.kbn-revealed > .wrap > *:nth-child(1),
.kbn-reveal.kbn-revealed > .why__inner > *:nth-child(1),
.kbn-reveal.kbn-revealed > .factory__inner > *:nth-child(1) { transition-delay: 80ms; }
.kbn-reveal.kbn-revealed > .wrap > *:nth-child(2),
.kbn-reveal.kbn-revealed > .why__inner > *:nth-child(2),
.kbn-reveal.kbn-revealed > .factory__inner > *:nth-child(2) { transition-delay: 160ms; }
.kbn-reveal.kbn-revealed > .wrap > *:nth-child(3),
.kbn-reveal.kbn-revealed > .why__inner > *:nth-child(3),
.kbn-reveal.kbn-revealed > .factory__inner > *:nth-child(3) { transition-delay: 240ms; }
.kbn-reveal.kbn-revealed > .wrap > *:nth-child(n+4),
.kbn-reveal.kbn-revealed > .why__inner > *:nth-child(n+4),
.kbn-reveal.kbn-revealed > .factory__inner > *:nth-child(n+4) { transition-delay: 320ms; }

/* =============================================================
 * #15 (v2) — Hero parallax & smooth-scroll plumbing
 *      JS sets --kbn-hero-parallax custom prop on .hero__carousel
 * ============================================================= */
.hero__carousel {
  transform: translate3d(0, var(--kbn-hero-parallax, 0px), 0);
  will-change: transform;
}

/* Smooth-scroll mode: kill native CSS smooth-scroll for anchors
 * (we handle anchor jumps via JS so they go through the lerp loop). */
html.kbn-smooth-scroll {
  scroll-behavior: auto;
}

/* When smooth scroll is on, the body itself never scrolls past the
 * content, so we need the body to track pointer events naturally. */
html.kbn-smooth-scroll body {
  overscroll-behavior-y: none;
}

/* =============================================================
 * #4 — Sticky header smart hide on scroll-down, show on scroll-up
 * ============================================================= */
.nav {
  transition: transform 280ms cubic-bezier(0.22, 1, 0.36, 1),
              box-shadow 280ms ease,
              background 280ms ease;
  will-change: transform;
}
.nav.kbn-nav-hidden {
  transform: translateY(-100%);
}
.nav.kbn-nav-shadow {
  box-shadow: 0 2px 14px rgba(15, 30, 56, 0.08);
}

/* =============================================================
 * #5 — Top scroll progress bar (KABALON gold)
 * ============================================================= */
.kbn-progress {
  position: fixed;
  top: 0; left: 0;
  height: 2px;
  width: 0%;
  background: linear-gradient(90deg, var(--gold, #c89543), var(--gold-bright, #e8c272));
  z-index: 99999;
  pointer-events: none;
  will-change: width;
  transition: width 80ms linear;
}

/* =============================================================
 * #6 — CTA button hover/tap feedback
 *      Lift on hover (desktop only), scale-down on tap (mobile).
 * ============================================================= */
.btn {
  transition: transform 220ms cubic-bezier(0.22, 1, 0.36, 1),
              box-shadow 220ms ease,
              background 180ms ease;
  will-change: transform;
}
@media (hover: hover) {
  .btn:hover {
    transform: translateY(-2px);
    box-shadow: var(--shadow-lg, 0 20px 40px rgba(15, 30, 56, 0.15));
  }
  .btn--primary:hover { background: var(--orange-hover, #c2410c); }
  .btn--zalo:hover    { background: var(--zalo-deep, #0070d6); }
}
.btn:active {
  transform: scale(0.97);
  transition-duration: 80ms;
}

/* =============================================================
 * #7 — Product card hover lift + image zoom
 * ============================================================= */
.product-card {
  transition: transform 320ms cubic-bezier(0.22, 1, 0.36, 1),
              box-shadow 320ms ease;
  will-change: transform;
}
.product-card__image {
  overflow: hidden;
}
.product-card__image img {
  transition: transform 540ms cubic-bezier(0.22, 1, 0.36, 1);
  will-change: transform;
}
@media (hover: hover) {
  .product-card:hover {
    transform: translateY(-4px);
    box-shadow: var(--shadow-lg, 0 20px 40px rgba(15, 30, 56, 0.15));
  }
  .product-card:hover .product-card__image img {
    transform: scale(1.04);
  }
}

/* =============================================================
 * #8 — Floating Zalo button breathing pulse (idle indicator)
 *      Triggered by JS after 3s idle, suppressed on interaction.
 * ============================================================= */
.sticky-bar__zalo {
  position: relative;
  overflow: visible;
}
.sticky-bar__zalo::before {
  content: '';
  position: absolute;
  inset: -3px;
  border-radius: inherit;
  border: 2px solid rgba(0, 132, 255, 0.55);
  opacity: 0;
  pointer-events: none;
}
.sticky-bar__zalo.kbn-pulse::before {
  animation: kbn-pulse 2.6s cubic-bezier(0, 0, 0.2, 1) infinite;
}
@keyframes kbn-pulse {
  0%   { transform: scale(0.94); opacity: 0.6; }
  100% { transform: scale(1.20); opacity: 0; }
}

/* =============================================================
 * #9 — Form field smoother focus + label color shift
 *      (Existing CSS already does focus border + glow at 0.15s.
 *       We slow it slightly + add label color shift on focus.)
 * ============================================================= */
.form-field input,
.form-field select {
  transition: border-color 220ms cubic-bezier(0.22, 1, 0.36, 1),
              background 220ms ease,
              box-shadow 220ms ease;
}
.form-field {
  position: relative;
}
.form-field label {
  transition: color 220ms ease;
}
.form-field:focus-within label {
  color: var(--gold-deep, #a07526);
}

/* =============================================================
 * #12 — Form validation shake (added by JS on invalid submit)
 * ============================================================= */
.form-field.kbn-shake input,
.form-field.kbn-shake select {
  animation: kbn-shake 380ms cubic-bezier(0.36, 0.07, 0.19, 0.97);
  border-color: var(--orange, #ea580c) !important;
  box-shadow: 0 0 0 3px rgba(234, 88, 12, 0.20) !important;
}
@keyframes kbn-shake {
  10%, 90% { transform: translateX(-1px); }
  20%, 80% { transform: translateX(2px); }
  30%, 50%, 70% { transform: translateX(-4px); }
  40%, 60% { transform: translateX(4px); }
}

/* =============================================================
 * #11 — Submit button loading / success / error states
 *      JS swaps button.dataset.state; CSS reads & themes.
 * ============================================================= */
.btn[data-state="loading"],
.btn[data-state="success"],
.btn[data-state="error"] {
  pointer-events: none;
  cursor: wait;
}
.btn[data-state="success"] {
  background: #16a34a !important;
  color: #fff !important;
}
.btn[data-state="error"] {
  background: var(--orange, #ea580c) !important;
  color: #fff !important;
}
.kbn-btn-spinner {
  display: inline-block;
  width: 16px;
  height: 16px;
  border: 2px solid rgba(255, 255, 255, 0.35);
  border-top-color: #fff;
  border-radius: 50%;
  animation: kbn-spin 720ms linear infinite;
  vertical-align: -3px;
  margin-right: 6px;
}
@keyframes kbn-spin {
  to { transform: rotate(360deg); }
}

/* =============================================================
 * #10 — Phone input visual hint (prefix shown faintly when empty)
 *      Pure CSS doesn't auto-format; that's JS. This just dresses up.
 * ============================================================= */
.form-field input[type="tel"] {
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.01em;
}

/* =============================================================
 * #13 — Image fade-in on load (smooth out lazy-loaded images)
 *      JS adds .kbn-img-fade pre-load and .kbn-img-loaded on load.
 * ============================================================= */
img.kbn-img-fade {
  opacity: 0;
  filter: blur(6px);
  transform: scale(1.015);
  transition: opacity 480ms ease,
              filter 480ms ease,
              transform 480ms ease;
  will-change: opacity, filter, transform;
}
img.kbn-img-loaded {
  opacity: 1;
  filter: blur(0);
  transform: scale(1);
}
/* Don't fade hero priority image — it's the LCP, must be instant */
.hero__slide[data-slide-index="0"] img.kbn-img-fade {
  opacity: 1 !important;
  filter: none !important;
  transform: none !important;
}

/* =============================================================
 * #14 — Hero preload signal (handled in functions.php via
 *      <link rel="preload"> + existing fetchpriority="high")
 *      Nothing to do in CSS.
 * ============================================================= */
