/* ==========================================================================
   Keyframes
   ========================================================================== */
@keyframes preloaderPulse{
  0%,100%{ transform:scale(1); opacity:1; }
  50%{ transform:scale(.85); opacity:.7; }
}

@keyframes blinkCursor{
  0%,100%{ opacity:1; }
  50%{ opacity:0; }
}

@keyframes scrollWheel{
  0%{ transform:translateY(0); opacity:1; }
  70%{ opacity:1; }
  100%{ transform:translateY(14px); opacity:0; }
}

@keyframes floatY{
  0%,100%{ transform:translateY(0); }
  50%{ transform:translateY(-14px); }
}

@keyframes floatSlow{
  0%,100%{ transform:translate(0,0) scale(1); }
  50%{ transform:translate(10px,-16px) scale(1.03); }
}

@keyframes spinSlow{
  to{ transform:rotate(360deg); }
}

@keyframes shine{
  0%{ background-position:-200% 0; }
  100%{ background-position:200% 0; }
}

/* ==========================================================================
   Scroll reveal system (driven by IntersectionObserver in main.js)
   Elements start hidden via [data-aos]; ".is-visible" triggers the reveal.
   ========================================================================== */
[data-aos]{
  opacity:0;
  transition-property:opacity, transform, filter;
  transition-duration:.8s;
  transition-timing-function:cubic-bezier(.22,1,.36,1);
  will-change:transform, opacity;
}

[data-aos="fade-up"]{ transform:translateY(46px); }
[data-aos="fade-down"]{ transform:translateY(-46px); }
[data-aos="fade-left"]{ transform:translateX(56px); }
[data-aos="fade-right"]{ transform:translateX(-56px); }
[data-aos="zoom-in"]{ transform:scale(.86); }
[data-aos="scale"]{ transform:scale(.92); }
[data-aos="blur-reveal"]{ filter:blur(14px); transform:translateY(20px); }

[data-aos].is-visible{
  opacity:1;
  transform:translate(0,0) scale(1);
  filter:blur(0);
}

/* stagger helper: children get incremental delay via inline --d custom property set in JS,
   or explicit utility classes for markup that can't use JS timing */
[data-aos-delay="1"]{ transition-delay:.08s; }
[data-aos-delay="2"]{ transition-delay:.16s; }
[data-aos-delay="3"]{ transition-delay:.24s; }
[data-aos-delay="4"]{ transition-delay:.32s; }
[data-aos-delay="5"]{ transition-delay:.4s; }
[data-aos-delay="6"]{ transition-delay:.48s; }
[data-aos-delay="7"]{ transition-delay:.56s; }
[data-aos-delay="8"]{ transition-delay:.64s; }
[data-aos-delay="9"]{ transition-delay:.72s; }

@media (prefers-reduced-motion: reduce){
  [data-aos]{ opacity:1 !important; transform:none !important; filter:none !important; transition:none !important; }
}

/* ==========================================================================
   Floating decorative helpers
   ========================================================================== */
.float{ animation:floatY 5s ease-in-out infinite; }
.float-slow{ animation:floatSlow 8s ease-in-out infinite; }
.spin-slow{ animation:spinSlow 18s linear infinite; }

.hero__badge--top{ animation:floatY 6s ease-in-out infinite; }
.hero__badge--bottom{ animation:floatY 6.5s ease-in-out infinite 1s; }

/* ==========================================================================
   Entrance sequence for hero (plays once on load, independent of scroll)
   ========================================================================== */
.hero [data-entrance]{
  opacity:0;
  transform:translateY(30px);
  animation:heroEntrance .9s var(--ease) forwards;
}
@keyframes heroEntrance{
  to{ opacity:1; transform:translateY(0); }
}
.hero [data-entrance="1"]{ animation-delay:.05s; }
.hero [data-entrance="2"]{ animation-delay:.18s; }
.hero [data-entrance="3"]{ animation-delay:.3s; }
.hero [data-entrance="4"]{ animation-delay:.42s; }
.hero [data-entrance="5"]{ animation-delay:.54s; }
.hero [data-entrance="6"]{ animation-delay:.66s; }

@media (prefers-reduced-motion: reduce){
  .hero [data-entrance]{ animation:none; opacity:1; transform:none; }
}

/* ==========================================================================
   Projects — scroll-triggered "drawing" card reveal
   Card surface is clip-path drawn top→bottom (2s, cubic-bezier(.25,1,.35,1))
   while a laser-line sweep tracks the reveal edge; both are driven by the
   ".is-drawing" class + "--draw-delay" custom property set in main.js.
   ========================================================================== */
.project-card__surface{
  clip-path:inset(0 0 100% 0 round var(--radius-lg));
  will-change:clip-path;
}

.project-card__laser{
  position:absolute;
  left:0; top:0;
  width:100%; height:3px;
  background:#fff;
  box-shadow:
    0 0 10px #fff,
    0 0 20px var(--color-primary),
    0 0 35px var(--color-primary);
  z-index:20;
  pointer-events:none;
  opacity:0;
  transform:translateY(-5px);
  border-radius:999px;
}

.project-card.is-drawing .project-card__surface{
  animation:projectCardDraw 2s cubic-bezier(.25,1,.35,1) forwards;
  animation-delay:var(--draw-delay, 0s);
}
.project-card.is-drawing .project-card__laser{
  animation:projectLaserDraw 2s cubic-bezier(.25,1,.35,1) forwards;
  animation-delay:var(--draw-delay, 0s);
}

@keyframes projectCardDraw{
  0%{ clip-path:inset(0 0 100% 0 round var(--radius-lg)); }
  100%{ clip-path:inset(0 0 0% 0 round var(--radius-lg)); }
}

@keyframes projectLaserDraw{
  0%{ top:0%; opacity:0; }
  4%{ opacity:1; }
  96%{ opacity:1; }
  100%{ top:100%; opacity:0; }
}

@media (prefers-reduced-motion: reduce){
  .project-card__surface{ clip-path:none !important; animation:none !important; }
  .project-card__laser{ display:none; }
}

/* ==========================================================================
   Counter number pop (used once counted value settles)
   ========================================================================== */
.stat-card.is-counted .stat-card__num{ animation:countPop .4s var(--ease); }
@keyframes countPop{
  0%{ transform:scale(1); }
  50%{ transform:scale(1.12); }
  100%{ transform:scale(1); }
}
