/* ==========================================================================
   KATARI JYOTHSNA - animations.css
   Keyframes, scroll-reveal utilities, scroll-driven timelines, preloader,
   custom cursor, view transitions, reduced-motion guard.
   ========================================================================== */

/* ==========================================================================
   1. KEYFRAMES
   ========================================================================== */
@keyframes fade-up      { from { opacity: 0; transform: translateY(28px); } to { opacity: 1; transform: none; } }
@keyframes fade-down    { from { opacity: 0; transform: translateY(-24px); } to { opacity: 1; transform: none; } }
@keyframes fade-in      { from { opacity: 0; } to { opacity: 1; } }
@keyframes zoom-in      { from { opacity: 0; transform: scale(.94); } to { opacity: 1; transform: none; } }
@keyframes slide-right  { from { opacity: 0; transform: translateX(-34px); } to { opacity: 1; transform: none; } }
@keyframes slide-left   { from { opacity: 0; transform: translateX(34px); } to { opacity: 1; transform: none; } }

@keyframes spin         { to { transform: rotate(360deg); } }
@keyframes spin-rev     { to { transform: rotate(-360deg); } }

@keyframes marquee-slide { from { transform: translateX(0); } to { transform: translateX(-100%); } }

@keyframes sheen-drift  { from { background-position: 0% 50%; } to { background-position: 220% 50%; } }

@keyframes grain-drift {
  0%   { background-position:   0px   0px; }
  10%  { background-position: -12px  -8px; }
  20%  { background-position: -30px  16px; }
  30%  { background-position:  12px -34px; }
  40%  { background-position:  -8px  28px; }
  50%  { background-position: -24px   8px; }
  60%  { background-position:  28px   0px; }
  70%  { background-position:   0px  24px; }
  80%  { background-position:  16px -12px; }
  90%  { background-position: -16px  20px; }
  100% { background-position:   0px   0px; }
}

@keyframes orb-a {
  from { transform: translate3d(0, 0, 0) scale(1); }
  to   { transform: translate3d(9%, 12%, 0) scale(1.18); }
}
@keyframes orb-b {
  from { transform: translate3d(0, 0, 0) scale(1.1); }
  to   { transform: translate3d(-11%, -9%, 0) scale(.92); }
}

@keyframes float-soft {
  0%, 100% { transform: translateY(0) rotate(0deg); }
  50%      { transform: translateY(-14px) rotate(1.5deg); }
}

@keyframes pulse-dot {
  0%   { box-shadow: 0 0 0 0 currentColor; opacity: 1; }
  70%  { box-shadow: 0 0 0 .55em transparent; opacity: .85; }
  100% { box-shadow: 0 0 0 0 transparent; opacity: 1; }
}

@keyframes flame-flicker {
  0%, 100% { transform: scaleY(1) scaleX(1); opacity: 1; }
  25%      { transform: scaleY(1.07) scaleX(.96); opacity: .92; }
  55%      { transform: scaleY(.95) scaleX(1.04); opacity: 1; }
  78%      { transform: scaleY(1.04) scaleX(.98); opacity: .95; }
}

@keyframes petal-fall {
  0%   { transform: translate3d(0, -8vh, 0) rotate(0deg); opacity: 0; }
  10%  { opacity: .34; }
  80%  { opacity: .22; }
  100% { transform: translate3d(var(--drift, 6vw), 106vh, 0) rotate(540deg); opacity: 0; }
}

@keyframes draw-stroke { to { stroke-dashoffset: 0; } }

@keyframes loader-out {
  to { clip-path: inset(0 0 100% 0); }
}

@keyframes shimmer-line {
  0%   { transform: translateX(-100%); }
  100% { transform: translateX(100%); }
}

@keyframes tilt-in {
  from { opacity: 0; transform: perspective(900px) rotateX(14deg) translateY(38px); }
  to   { opacity: 1; transform: perspective(900px) rotateX(0) translateY(0); }
}

@keyframes bob { 0%,100% { transform: translateY(0); } 50% { transform: translateY(6px); } }

/* ==========================================================================
   2. SCROLL REVEAL - JS adds .is-in when the element enters the viewport
   ========================================================================== */
[data-reveal] {
  opacity: 0;
  will-change: transform, opacity;
  transition:
    opacity var(--reveal-dur, 900ms) var(--ease-out-expo) var(--reveal-delay, 0ms),
    transform var(--reveal-dur, 900ms) var(--ease-out-expo) var(--reveal-delay, 0ms),
    clip-path var(--reveal-dur, 900ms) var(--ease-out-expo) var(--reveal-delay, 0ms);
}
[data-reveal="up"]     { transform: translateY(38px); }
[data-reveal="down"]   { transform: translateY(-30px); }
[data-reveal="left"]   { transform: translateX(-46px); }
[data-reveal="right"]  { transform: translateX(46px); }
[data-reveal="zoom"]   { transform: scale(.93); }
[data-reveal="tilt"]   { transform: perspective(900px) rotateX(12deg) translateY(38px); }
[data-reveal="mask"]   { clip-path: inset(0 0 100% 0); opacity: 1; transform: translateY(14px); }
[data-reveal="wipe"]   { clip-path: inset(0 100% 0 0); opacity: 1; }
[data-reveal="blur"]   { filter: blur(14px); transform: translateY(20px); }

[data-reveal].is-in {
  opacity: 1;
  transform: none;
  clip-path: inset(0 0 0 0);
  filter: none;
}

/* Stagger children: JS sets --i on each child */
[data-stagger] > * {
  --reveal-delay: calc(var(--i, 0) * var(--stagger-step, 90ms));
}

/* Word-by-word headline reveal (JS splits the text).
   The mask is what makes words appear to rise out of nothing, so the line
   needs overflow:hidden - but a tight display line-height would then clip
   descenders (g, y, j). The padding/negative-margin pair buys that room
   back without changing the visual rhythm. */
.split-line,
.hero__title .line,
.display .line {
  display: block;
  overflow: hidden;
  padding-bottom: .12em;
  margin-bottom: -.12em;
}
.split-word {
  display: inline-block;
  transform: translateY(115%);
  opacity: 0;
  transition: transform 1000ms var(--ease-out-expo), opacity 700ms linear;
  transition-delay: calc(var(--w, 0) * 55ms);
  will-change: transform;
}
.is-in .split-word,
.split-ready.is-in .split-word { transform: translateY(0); opacity: 1; }

/* Letters (used sparingly - logo, single words) */
.split-char {
  display: inline-block;
  transform: translateY(90%) rotate(6deg);
  opacity: 0;
  transition: transform 820ms var(--ease-out-expo), opacity 520ms linear;
  transition-delay: calc(var(--c, 0) * 32ms);
}
.is-in .split-char { transform: none; opacity: 1; }

/* ==========================================================================
   3. NATIVE SCROLL-DRIVEN ANIMATIONS (progressive enhancement)
   ========================================================================== */
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    /* Parallax drift on marked media */
    .sd-parallax {
      animation: sd-drift linear both;
      animation-timeline: view();
      animation-range: entry 0% exit 100%;
    }
    @keyframes sd-drift {
      from { transform: translateY(var(--pxl, 7%)); }
      to   { transform: translateY(calc(var(--pxl, 7%) * -1)); }
    }

    /* Section that lifts + fades as it scrolls in */
    .sd-rise {
      animation: sd-rise-kf linear both;
      animation-timeline: view();
      animation-range: entry 12% cover 34%;
    }
    @keyframes sd-rise-kf {
      from { opacity: .12; transform: translateY(44px) scale(.975); }
      to   { opacity: 1; transform: none; }
    }

    /* Sticky hero that shrinks away under the next section */
    .sd-pin {
      animation: sd-pin-kf linear both;
      animation-timeline: view();
      animation-range: exit 0% exit 100%;
    }
    @keyframes sd-pin-kf {
      to { transform: scale(.9) translateY(-4%); opacity: .3; filter: blur(6px); }
    }

    /* Gold rule that draws across as you scroll */
    .sd-draw {
      transform-origin: left center;
      animation: sd-draw-kf linear both;
      animation-timeline: view();
      animation-range: entry 20% cover 45%;
    }
    @keyframes sd-draw-kf { from { transform: scaleX(0); } to { transform: scaleX(1); } }
  }
}

/* ==========================================================================
   4. HOVER / IDLE MOTION HELPERS
   ========================================================================== */
.float      { animation: float-soft 7s var(--ease-in-out) infinite; }
.float--alt { animation: float-soft 9s var(--ease-in-out) infinite reverse; }
.spin-slow  { animation: spin 24s linear infinite; }
.spin-slow-rev { animation: spin-rev 30s linear infinite; }
.bob        { animation: bob 2.4s var(--ease-in-out) infinite; }

/* Magnetic hover target - JS moves the inner element */
.magnetic { display: inline-block; will-change: transform; }
.magnetic__inner { display: inline-block; transition: transform 420ms var(--ease-out-expo); }

/* Tilt card - JS sets --rx / --ry from pointer position */
.tilt {
  transform: perspective(1000px) rotateX(var(--rx, 0deg)) rotateY(var(--ry, 0deg));
  transition: transform 500ms var(--ease-out-expo);
  transform-style: preserve-3d;
}
.tilt__lift { transform: translateZ(38px); }

/* A shimmering highlight that runs across a surface */
.shimmer { position: relative; overflow: hidden; }
.shimmer::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(100deg, transparent 30%, color-mix(in oklab, var(--gold) 26%, transparent) 50%, transparent 70%);
  transform: translateX(-100%);
  pointer-events: none;
}
.shimmer:hover::after { animation: shimmer-line 1.1s var(--ease-out-quint); }

/* Falling marigold petals layer */
.petals {
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
  z-index: 1;
}
/* Petals are atmosphere, not confetti: small, soft-edged and barely
   there. Anything more saturated reads as decoration rather than air. */
.petal {
  position: absolute;
  top: 0;
  width: var(--size, 9px);
  height: calc(var(--size, 9px) * .62);
  border-radius: 60% 40% 55% 45% / 60% 55% 45% 40%;
  background: linear-gradient(135deg, var(--brand-marigold), var(--brand-amber-500));
  filter: blur(.4px);
  opacity: 0;
  animation: petal-fall var(--dur, 18s) linear var(--delay, 0s) infinite;
  will-change: transform;
}
.petal--plum  { background: linear-gradient(135deg, var(--brand-plum-200), var(--brand-plum-400)); }
.petal--blush { background: linear-gradient(135deg, var(--brand-magenta-200), var(--brand-magenta-400)); }

/* Candle flame (SVG child) */
.flame { transform-origin: 50% 100%; animation: flame-flicker 1.7s var(--ease-in-out) infinite; }

/* SVG line-draw: element must set stroke-dasharray/offset inline or here */
.draw-in {
  stroke-dasharray: var(--len, 1200);
  stroke-dashoffset: var(--len, 1200);
  animation: draw-stroke var(--draw-dur, 2.4s) var(--ease-out-expo) forwards;
}

/* ==========================================================================
   5. PRELOADER
   ========================================================================== */
.preloader {
  position: fixed;
  inset: 0;
  z-index: var(--z-loader);
  display: grid;
  place-items: center;
  background: var(--brand-plum-900);
  color: var(--brand-cream-100);
}
.preloader__inner {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: clamp(1.4rem, 3vw, 2.2rem);
  padding-inline: var(--gutter);
  text-align: center;
}
.preloader__name {
  font-family: var(--font-display);
  font-weight: 300;
  font-size: clamp(2rem, 7vw, 4.2rem);
  line-height: 1;
  letter-spacing: .02em;
  color: var(--brand-cream-100);
  opacity: 0;
  animation: fade-up 900ms var(--ease-out-expo) 80ms forwards;
}
/* A hairline that fills left-to-right as loading progresses */
.preloader__rule {
  display: block;
  width: min(52vw, 20rem);
  height: 1px;
  background: color-mix(in oklab, var(--brand-cream-100) 18%, transparent);
  overflow: hidden;
}
.preloader__rule i {
  display: block;
  height: 100%;
  width: 100%;
  background: var(--brand-marigold);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 260ms linear;
}
.preloader__pct {
  display: inline-flex;
  align-items: baseline;
  gap: .1em;
  font-family: var(--font-body);
  font-size: .78rem;
  font-weight: 600;
  letter-spacing: .34em;
  color: var(--brand-marigold);
  font-variant-numeric: tabular-nums;
  opacity: 0;
  animation: fade-in 600ms linear 240ms forwards;
}
.preloader__pct em { font-style: normal; opacity: .65; }

.preloader.is-done { animation: loader-out 900ms var(--ease-out-expo) forwards; pointer-events: none; }

/* Page content entrance once the loader clears */
body.is-ready .hero__stage > * { animation-play-state: running; }

/* ==========================================================================
   6. CUSTOM CURSOR (pointer-fine devices only)
   ========================================================================== */
.cursor,
.cursor-dot {
  position: fixed;
  top: 0; left: 0;
  z-index: var(--z-cursor);
  pointer-events: none;
  border-radius: 50%;
  opacity: 0;
  transition: opacity 300ms linear, width 320ms var(--ease-out-expo),
              height 320ms var(--ease-out-expo), background-color 320ms linear,
              border-color 320ms linear, transform 200ms var(--ease-out-expo);
  will-change: transform;
}
.cursor {
  width: 2.4rem; height: 2.4rem;
  border: 1px solid color-mix(in oklab, var(--accent) 70%, transparent);
  margin: -1.2rem 0 0 -1.2rem;
  backdrop-filter: invert(4%);
}
.cursor-dot {
  width: .4rem; height: .4rem;
  background: var(--accent);
  margin: -.2rem 0 0 -.2rem;
}
body.cursor-active .cursor,
body.cursor-active .cursor-dot { opacity: 1; }
.cursor.is-hovering {
  width: 4.6rem; height: 4.6rem;
  margin: -2.3rem 0 0 -2.3rem;
  background: color-mix(in oklab, var(--accent) 16%, transparent);
  border-color: transparent;
}
.cursor.is-view::after {
  content: "VIEW";
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  font-family: var(--font-body);
  font-size: .56rem;
  font-weight: 700;
  letter-spacing: .18em;
  color: var(--accent);
}
.cursor.is-down { transform: scale(.82); }

@media (hover: none), (pointer: coarse) {
  .cursor, .cursor-dot { display: none; }
}

/* ==========================================================================
   7. CROSS-DOCUMENT VIEW TRANSITIONS
   ========================================================================== */
@view-transition { navigation: auto; }

@media (prefers-reduced-motion: no-preference) {
  ::view-transition-old(root) {
    animation: vt-out 320ms var(--ease-in-out) both;
  }
  ::view-transition-new(root) {
    animation: vt-in 460ms var(--ease-out-expo) both;
  }
  @keyframes vt-out { to { opacity: 0; transform: translateY(-10px) scale(.995); } }
  @keyframes vt-in  { from { opacity: 0; transform: translateY(14px) scale(.995); } }

  /* The header must not slide with the page */
  .site-header { view-transition-name: site-header; }
  .site-footer { view-transition-name: site-footer; }
  ::view-transition-group(site-header),
  ::view-transition-group(site-footer) { animation-duration: 260ms; }
}

/* ==========================================================================
   8. REDUCED MOTION - honour the visitor above all else
   ========================================================================== */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
    scroll-behavior: auto !important;
  }
  [data-reveal],
  .split-word,
  .split-char {
    opacity: 1 !important;
    transform: none !important;
    clip-path: none !important;
    filter: none !important;
  }
  .petals, .grain { display: none; }
  .marquee__track { animation: none; }
  .cursor, .cursor-dot { display: none; }
  ::view-transition-old(root),
  ::view-transition-new(root) { animation: none; }
}
