/* Cozy Bloom — Scroll Animations & Page Loader */

/* ============================================================
   COZY BLOOM — SCROLL ANIMATIONS & PAGE LOADER
   Version 1.4.0

   All animation rules are gated on .js-animations (added to
   <html> by animations.js) so content is always accessible
   without JavaScript or when JS hasn't loaded yet.
   ============================================================ */

/* ── Prevent horizontal overflow from left/right reveals ─── */
html, body { overflow-x: hidden; }

/* ============================================================
   REVEAL SYSTEM
   Usage:
     <div class="reveal reveal-up">…</div>
     <div class="cb-stagger">
       <div class="reveal reveal-up">…</div>
     </div>
   ============================================================ */

/* Initial hidden state — only when JS is active */
.js-animations .reveal {
  opacity: 0;
  transition: opacity 0.8s cubic-bezier(0.22, 1, 0.36, 1),
              transform 0.8s cubic-bezier(0.22, 1, 0.36, 1);
  will-change: opacity, transform;
}

/* Transform variants */
.js-animations .reveal-up    { transform: translateY(35px); }
.js-animations .reveal-down  { transform: translateY(-35px); }
.js-animations .reveal-left  { transform: translateX(-35px); }
.js-animations .reveal-right { transform: translateX(35px); }
.js-animations .reveal-scale { transform: scale(0.96); }
/* reveal-fade uses opacity only — no transform needed */

/* Revealed state — added by IntersectionObserver */
.js-animations .reveal.is-visible {
  opacity: 1;
  transform: none;
}

/* Optional explicit delay utility classes */
.reveal-delay-1 { transition-delay: 100ms; }
.reveal-delay-2 { transition-delay: 200ms; }
.reveal-delay-3 { transition-delay: 300ms; }
.reveal-delay-4 { transition-delay: 400ms; }
.reveal-delay-5 { transition-delay: 500ms; }
.reveal-delay-6 { transition-delay: 600ms; }

/* ============================================================
   HERO ENTRANCE ANIMATION
   Triggered by .hero--animated class added by animations.js
   ============================================================ */

/* Start state — only when JS is active */
.js-animations .hero .hero-copy > *,
.js-animations .hero .hero-art {
  opacity: 0;
  transform: translateY(22px);
  transition: opacity 0.82s cubic-bezier(0.22, 1, 0.36, 1),
              transform 0.82s cubic-bezier(0.22, 1, 0.36, 1);
  will-change: opacity, transform;
}

/* Staggered delays per child */
.js-animations .hero .hero-copy > *:nth-child(1) { transition-delay: 0.12s; }
.js-animations .hero .hero-copy > *:nth-child(2) { transition-delay: 0.27s; }
.js-animations .hero .hero-copy > *:nth-child(3) { transition-delay: 0.42s; }
.js-animations .hero .hero-copy > *:nth-child(4) { transition-delay: 0.57s; }

/* Hero image: slight scale effect too */
.js-animations .hero .hero-art {
  transform: translateY(16px) scale(0.97);
  transition-delay: 0.32s;
}

/* Final state — applied when .hero--animated is added.
   Specificity (0,4,0) intentionally beats the (0,3,0) initial-state rule above. */
.js-animations .hero.hero--animated .hero-copy > *,
.js-animations .hero.hero--animated .hero-art {
  opacity: 1;
  transform: none;
}

/* ============================================================
   HOVER ENHANCEMENTS
   Adds missing hover lift to info-cards and testi-cards.
   (Other cards already have hover in the base stylesheet.)
   ============================================================ */

.info-card {
  transition: transform 0.26s cubic-bezier(0.22, 1, 0.36, 1),
              box-shadow 0.26s ease;
}
.info-card:hover {
  transform: translateY(-4px);
  box-shadow: 0 22px 44px rgba(70,82,60,.12);
}

.cb-testi-card-inner {
  transition: transform 0.26s cubic-bezier(0.22, 1, 0.36, 1),
              box-shadow 0.26s ease;
}
.cb-testi-card:hover .cb-testi-card-inner {
  transform: translateY(-3px);
  box-shadow: 0 20px 40px rgba(70,82,60,.10);
}

/* ============================================================
   PAGE LOADER
   A branded bloom animation shown while the page loads.
   Hidden via .cb-loader--out then display:none via JS.
   ============================================================ */

.cb-loader {
  position: fixed;
  inset: 0;
  z-index: 99999;
  background: var(--cb-cream, #faf5ed);
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 1;
  transition: opacity 0.62s ease;
}

/* Fade-out state added by JS */
.cb-loader--out {
  opacity: 0;
  pointer-events: none;
}

.cb-loader-inner {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1.4rem;
}

/* ── Flower wrap ── */
.cb-loader-flower-wrap {
  position: relative;
  width: 120px;
  height: 120px;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* ── SVG bloom ── */
.cb-loader-svg {
  width: 84px;
  height: 84px;
  position: relative;
  z-index: 2;
  opacity: 0;
  animation: cb-flower-bloom 1.1s cubic-bezier(0.34, 1.46, 0.64, 1) 0.15s forwards;
}

@keyframes cb-flower-bloom {
  0%   { transform: scale(0.05) rotate(-60deg); opacity: 0; }
  55%  { opacity: 1; }
  100% { transform: scale(1) rotate(0deg); opacity: 1; }
}

/* ── Expanding ring ── */
.cb-loader-ring {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  border: 1.5px solid rgba(106,119,86,.32);
  opacity: 0;
  animation: cb-ring-pulse 2.2s cubic-bezier(0.4, 0, 0.6, 1) 0.5s infinite;
}

@keyframes cb-ring-pulse {
  0%   { transform: scale(0.7); opacity: 0.6; }
  60%  { opacity: 0.08; }
  100% { transform: scale(1.55); opacity: 0; }
}

/* ── Brand text ── */
.cb-loader-brand {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.25rem;
  opacity: 0;
  transform: translateY(10px);
  animation: cb-brand-rise 0.65s cubic-bezier(0.22, 1, 0.36, 1) 0.85s forwards;
}

@keyframes cb-brand-rise {
  to { opacity: 1; transform: translateY(0); }
}

.cb-loader-name {
  font-family: 'Playfair Display', Georgia, serif;
  font-size: 1.45rem;
  font-weight: 600;
  color: var(--cb-sage-deep, #46523c);
  letter-spacing: 0.02em;
  line-height: 1.2;
}

.cb-loader-tagline {
  font-family: 'Poppins', sans-serif;
  font-size: 0.74rem;
  font-weight: 400;
  color: var(--cb-muted, #6e756b);
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

/* ============================================================
   ACCESSIBILITY — REDUCED MOTION
   Override all animations and transitions for users who
   have requested reduced motion in their OS settings.
   The loader still disappears but without animated effects.
   ============================================================ */
@media (prefers-reduced-motion: reduce) {

  /* Show all reveal elements immediately */
  .reveal,
  .js-animations .reveal {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
    will-change: auto !important;
  }

  /* Show hero elements immediately */
  .js-animations .hero .hero-copy > *,
  .js-animations .hero .hero-art {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
    will-change: auto !important;
  }

  /* Disable loader animations */
  .cb-loader-svg {
    animation: none !important;
    opacity: 1 !important;
  }
  .cb-loader-ring {
    animation: none !important;
    opacity: 0.3 !important;
    transform: none !important;
  }
  .cb-loader-brand {
    animation: none !important;
    opacity: 1 !important;
    transform: none !important;
  }

  /* Loader still fades out — just without keyframes */
  .cb-loader--out {
    opacity: 0 !important;
    transition: opacity 0.3s ease !important;
  }

  /* Disable page-hero keyframe animations */
  .js-animations.loader-done .page-hero .container > *,
  .js-animations.loader-done .page-hero .container-xl > *,
  .js-animations.loader-done .cb-contact-hero .cb-contact-hero-inner > * {
    animation: none !important;
    opacity: 1 !important;
    transform: none !important;
  }
}

/* ============================================================
   PAGE-HERO ENTRANCE ANIMATION (inner pages)
   Gated on .js-animations.loader-done — fires only AFTER the
   page loader has fully hidden so the user actually sees it.
   ============================================================ */
@keyframes cb-page-hero-in {
  from { opacity: 0; transform: translateY(22px); }
  to   { opacity: 1; transform: none; }
}

.js-animations.loader-done .page-hero .container > *,
.js-animations.loader-done .page-hero .container-xl > * {
  animation: cb-page-hero-in 0.65s cubic-bezier(0.22, 1, 0.36, 1) both;
}
.js-animations.loader-done .page-hero .container > *:nth-child(1),
.js-animations.loader-done .page-hero .container-xl > *:nth-child(1) { animation-delay: 0s; }
.js-animations.loader-done .page-hero .container > *:nth-child(2),
.js-animations.loader-done .page-hero .container-xl > *:nth-child(2) { animation-delay: 0.12s; }
.js-animations.loader-done .page-hero .container > *:nth-child(3),
.js-animations.loader-done .page-hero .container-xl > *:nth-child(3) { animation-delay: 0.22s; }

/* Contact page hero — separate structure */
.js-animations.loader-done .cb-contact-hero .cb-contact-hero-inner > * {
  animation: cb-page-hero-in 0.65s cubic-bezier(0.22, 1, 0.36, 1) both;
}
.js-animations.loader-done .cb-contact-hero .cb-contact-hero-inner > *:nth-child(1) { animation-delay: 0s; }
.js-animations.loader-done .cb-contact-hero .cb-contact-hero-inner > *:nth-child(2) { animation-delay: 0.12s; }
