/* ============================================================
   Tjakrabirawa Portfolio Theme — animations.css
   Modern, minimalist motion system.
   ============================================================ */

/*
  Easing reference:
  expo-out  → cubic-bezier(0.16, 1, 0.3, 1)   fast start, silky landing
  quart-out → cubic-bezier(0.25, 1, 0.5, 1)   slightly softer
  spring    → cubic-bezier(0.34, 1.56, 0.64, 1) slight overshoot / pop
*/

/* ─── 1. Page Load Fade-In ───────────────────────────────────
   Body starts invisible; JS adds .page-loaded after DOMContentLoaded.
   This prevents a flash of unstyled content on slower connections.  */
body {
  opacity: 0;
  transition: opacity 0.38s ease;
}
body.page-loaded {
  opacity: 1;
}

/* ─── 2. Scroll Reveal ───────────────────────────────────────
   Elements with .reveal / .reveal-left / .reveal-right start
   hidden. IntersectionObserver adds .revealed to trigger.       */
.reveal {
  opacity: 0;
  transform: translateY(22px);
  transition: opacity 0.72s cubic-bezier(0.16, 1, 0.3, 1),
              transform 0.72s cubic-bezier(0.16, 1, 0.3, 1);
  will-change: opacity, transform;
}
.reveal.revealed {
  opacity: 1;
  transform: translateY(0);
}

.reveal-left {
  opacity: 0;
  transform: translateX(-26px);
  transition: opacity 0.72s cubic-bezier(0.16, 1, 0.3, 1),
              transform 0.72s cubic-bezier(0.16, 1, 0.3, 1);
  will-change: opacity, transform;
}
.reveal-left.revealed {
  opacity: 1;
  transform: translateX(0);
}

.reveal-right {
  opacity: 0;
  transform: translateX(26px);
  transition: opacity 0.72s cubic-bezier(0.16, 1, 0.3, 1),
              transform 0.72s cubic-bezier(0.16, 1, 0.3, 1);
  will-change: opacity, transform;
}
.reveal-right.revealed {
  opacity: 1;
  transform: translateX(0);
}

/* ─── 3. Staggered Children ──────────────────────────────────
   Parent gets .stagger-children; JS adds .revealed on scroll.
   Each child animates in with increasing delay.               */
.stagger-children > * {
  opacity: 0;
  transform: translateY(16px);
  will-change: opacity, transform;
}
.stagger-children.revealed > *:nth-child(1)  { animation: fadeUp 0.65s 0.00s cubic-bezier(0.16,1,0.3,1) forwards; }
.stagger-children.revealed > *:nth-child(2)  { animation: fadeUp 0.65s 0.07s cubic-bezier(0.16,1,0.3,1) forwards; }
.stagger-children.revealed > *:nth-child(3)  { animation: fadeUp 0.65s 0.14s cubic-bezier(0.16,1,0.3,1) forwards; }
.stagger-children.revealed > *:nth-child(4)  { animation: fadeUp 0.65s 0.21s cubic-bezier(0.16,1,0.3,1) forwards; }
.stagger-children.revealed > *:nth-child(5)  { animation: fadeUp 0.65s 0.28s cubic-bezier(0.16,1,0.3,1) forwards; }
.stagger-children.revealed > *:nth-child(6)  { animation: fadeUp 0.65s 0.35s cubic-bezier(0.16,1,0.3,1) forwards; }
.stagger-children.revealed > *:nth-child(7)  { animation: fadeUp 0.65s 0.42s cubic-bezier(0.16,1,0.3,1) forwards; }
.stagger-children.revealed > *:nth-child(8)  { animation: fadeUp 0.65s 0.49s cubic-bezier(0.16,1,0.3,1) forwards; }
.stagger-children.revealed > *:nth-child(n+9){ animation: fadeUp 0.65s 0.56s cubic-bezier(0.16,1,0.3,1) forwards; }

@keyframes fadeUp {
  from { opacity: 0; transform: translateY(16px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* ─── 4. Hero Entrance ───────────────────────────────────────
   Triggered by JS adding .hero-animate-in to the hero section.
   Elements stagger in sequentially after page loads.          */
.hero-animate-in .hero-open-badge  { animation: heroUp 0.60s 0.04s cubic-bezier(0.16,1,0.3,1) both; }
.hero-animate-in .hero-eyebrow     { animation: heroUp 0.60s 0.10s cubic-bezier(0.16,1,0.3,1) both; }
.hero-animate-in .hero-name        { animation: heroUp 0.72s 0.22s cubic-bezier(0.16,1,0.3,1) both; }
.hero-animate-in .hero-name-jp     { animation: heroUp 0.60s 0.34s cubic-bezier(0.16,1,0.3,1) both; }
.hero-animate-in .hero-specialise  { animation: heroUp 0.60s 0.38s cubic-bezier(0.16,1,0.3,1) both; }
.hero-animate-in .hero-tagline     { animation: heroUp 0.60s 0.43s cubic-bezier(0.16,1,0.3,1) both; }
.hero-animate-in .hero-statement   { animation: heroUp 0.60s 0.48s cubic-bezier(0.16,1,0.3,1) both; }
.hero-animate-in .hero-cta         { animation: heroUp 0.60s 0.52s cubic-bezier(0.16,1,0.3,1) both; }
.hero-animate-in .hero-social      { animation: heroUp 0.60s 0.61s cubic-bezier(0.16,1,0.3,1) both; }
.hero-animate-in .hero-visual      { animation: heroSlide 0.88s 0.30s cubic-bezier(0.16,1,0.3,1) both; }
.hero-animate-in .hero-badge       { animation: heroPop  0.52s 0.72s cubic-bezier(0.34,1.56,0.64,1) both; }

@keyframes heroUp {
  from { opacity: 0; transform: translateY(18px); }
  to   { opacity: 1; transform: translateY(0); }
}

@keyframes heroSlide {
  from { opacity: 0; transform: translateX(20px); }
  to   { opacity: 1; transform: translateX(0); }
}

@keyframes heroPop {
  from { opacity: 0; transform: scale(0.84); }
  to   { opacity: 1; transform: scale(1); }
}

/* ─── 5. Counter (Stats) ─────────────────────────────────────
   Numbers flash to accent color while counting up.            */
.stat-number {
  transition: color 0.28s ease;
  display: inline-block;
}
.stat-number.counting { color: var(--color-accent); }

/* ─── 6. Card Hover — hardware-accelerated ───────────────────
   Apply will-change only on hover so we don't reserve GPU
   compositor layers for every card on the page at once.       */
.project-card,
.activity-card,
.award-card,
.experience-card,
.contact-channel,
.about-teaser-card {
  will-change: auto;
}
.project-card:hover,
.activity-card:hover,
.award-card:hover,
.experience-card:hover,
.contact-channel:hover,
.about-teaser-card:hover {
  will-change: transform, filter;
}

/* ─── 7. Social Link Hover ───────────────────────────────────*/
.social-link {
  transition: background 0.20s cubic-bezier(0.16,1,0.3,1),
              color 0.20s cubic-bezier(0.16,1,0.3,1),
              filter 0.20s cubic-bezier(0.16,1,0.3,1),
              transform 0.20s cubic-bezier(0.16,1,0.3,1);
}
.social-link:hover {
  transform: translateY(-2px);
  filter: drop-shadow(0 4px 10px rgba(207,11,40,.28));
}

/* ─── 8. Nav Link Hover ──────────────────────────────────────
   Underline grows from center on hover / active page.         */
.nav-menu li a {
  transition: color 0.18s cubic-bezier(0.16,1,0.3,1);
}

/* ─── 9. Accent line draw on section entry ───────────────────*/
.section-eyebrow::before {
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.48s 0.22s cubic-bezier(0.16,1,0.3,1);
}
.revealed .section-eyebrow::before,
.section-header.revealed .section-eyebrow::before {
  transform: scaleX(1);
}

/* ─── 10. Hero decorative panels ────────────────────────────
   The ::before / ::after parallelogram panels fade in gently.  */
.hero-section::before,
.hero-section::after {
  transition: opacity 0.90s 0.18s cubic-bezier(0.16,1,0.3,1);
}

/* ─── 11. Image zoom on card hover ──────────────────────────*/
.project-card-image img {
  transition: transform 0.55s cubic-bezier(0.16,1,0.3,1);
}
.project-card:hover .project-card-image img {
  transform: scale(1.055);
}

/* ─── 12. Contact channel hover ─────────────────────────────*/
.contact-channel {
  transition: transform 0.25s cubic-bezier(0.16,1,0.3,1),
              filter 0.25s cubic-bezier(0.16,1,0.3,1),
              border-color 0.25s;
}
.contact-channel:hover {
  transform: translateX(4px);
}

/* ─── Reduced Motion ─────────────────────────────────────────
   Respects user's OS accessibility setting.                   */
@media (prefers-reduced-motion: reduce) {
  body { opacity: 1; transition: none; }

  .reveal,
  .reveal-left,
  .reveal-right {
    opacity: 1;
    transform: none;
    transition: none;
    will-change: auto;
  }

  .stagger-children > * {
    opacity: 1;
    transform: none;
    animation: none;
    will-change: auto;
  }

  .hero-animate-in * {
    animation: none;
    opacity: 1;
    transform: none;
  }

  .project-card,
  .activity-card,
  .award-card,
  .experience-card,
  .contact-channel,
  .social-link,
  .btn {
    will-change: auto;
    transition: background 0.1s, color 0.1s, border-color 0.1s;
  }

  .project-card-image img { transition: none; }
  .section-eyebrow::before { transition: none; transform: scaleX(1); }
}

/* ═══════════════════════════════════════════════════════════════
   NEW ANIMATIONS v1.13
   ═══════════════════════════════════════════════════════════════ */

/* ─── A. Page Transition — diagonal wipe ────────────────────── */
#page-transition {
  position: fixed;
  inset: 0;
  z-index: 99999;
  pointer-events: none;
  display: flex;
}
#page-transition .pt-panel {
  flex: 1;
  background: var(--color-accent);
  transform: scaleY(1);  /* visible by default */
  transform-origin: top;
  will-change: transform;
}
#page-transition .pt-panel:nth-child(1) { transition: transform 0.42s 0.00s cubic-bezier(0.76, 0, 0.24, 1); }
#page-transition .pt-panel:nth-child(2) { transition: transform 0.42s 0.07s cubic-bezier(0.76, 0, 0.24, 1); }
#page-transition .pt-panel:nth-child(3) { transition: transform 0.42s 0.14s cubic-bezier(0.76, 0, 0.24, 1); }

/* Leave (reveal) — panels retract upward */
#page-transition.pt-leave .pt-panel {
  transform: scaleY(0);
  transform-origin: top;
}
/* Enter (exit click) — panels sweep down from top */
#page-transition.pt-enter .pt-panel {
  transform: scaleY(1);
  transform-origin: top;
}
#page-transition .pt-panel:nth-child(1) { clip-path: polygon(0 0, 100% 3%, 100% 100%, 0% 97%); }
#page-transition .pt-panel:nth-child(2) { clip-path: polygon(0 2%, 100% 0, 100% 98%, 0% 100%); margin-inline: -1px; }
#page-transition .pt-panel:nth-child(3) { clip-path: polygon(0 3%, 100% 0, 100% 97%, 0% 100%); }

/* ─── B. Project card diagonal reveal ───────────────────────── */
/* Cards enter from bottom-right with a slight tilt, then settle. */
/* JS adds .card-reveal-init on IntersectionObserver, then after
   a rAF adds .card-reveal-in to trigger the transition. */
.project-card-wrap.card-reveal-init {
  opacity: 0;
  transform: translateY(24px) translateX(10px) rotate(1.2deg);
  will-change: opacity, transform;
}
.project-card-wrap.card-reveal-in {
  opacity: 1;
  transform: translateY(0) translateX(0) rotate(0deg);
  transition: opacity 0.65s cubic-bezier(0.16, 1, 0.3, 1),
              transform 0.65s cubic-bezier(0.16, 1, 0.3, 1);
}
/* Activities cards — same treatment */
.act-card-wrap.card-reveal-init {
  opacity: 0;
  transform: translateY(24px) translateX(10px) rotate(1.2deg);
  will-change: opacity, transform;
}
.act-card-wrap.card-reveal-in {
  opacity: 1;
  transform: translateY(0) translateX(0) rotate(0deg);
  transition: opacity 0.65s cubic-bezier(0.16, 1, 0.3, 1),
              transform 0.65s cubic-bezier(0.16, 1, 0.3, 1);
}

/* ─── C. Skill badge shimmer ─────────────────────────────────── */
/* Badges in the project sidebar play a shimmer sweep once on
   entry — triggered by JS adding .badge-shimmer class. */
@keyframes badgeShimmer {
  0%   { background-position: -200% center; }
  100% { background-position: 200% center; }
}
.project-skill-badge.badge-shimmer {
  background-image: linear-gradient(
    90deg,
    var(--color-accent-light) 0%,
    rgba(255,255,255,0.9) 40%,
    var(--color-accent-light) 55%,
    var(--color-accent-light) 100%
  );
  background-size: 200% auto;
  animation: badgeShimmer 0.7s ease forwards;
  color: var(--color-accent);
  border-color: var(--color-accent);
}

/* ─── D. Section heading slash draw-in ──────────────────────── */
/* Fix: restore the animated draw for section eyebrow dashes.
   The Memphis layer above added a static skewed version —
   this overrides it with the correct animated behaviour. */
.section-eyebrow::before {
  content: '';
  display: inline-block;
  width: 18px;
  height: 2px;
  background: var(--color-accent);
  flex-shrink: 0;
  transform: scaleX(0) skewX(-20deg);
  transform-origin: left;
  transition: transform 0.45s 0.25s cubic-bezier(0.16, 1, 0.3, 1);
  margin-right: 0; /* gap handles spacing */
}
.section-header.revealed .section-eyebrow::before,
.revealed .section-eyebrow::before {
  transform: scaleX(1) skewX(-20deg);
}

/* Project section titles (Gallery, Outcome, etc.) — slash draws in */
.project-section-title::before {
  content: '';
  display: inline-block;
  width: 12px;
  height: 14px;
  background: var(--color-accent);
  opacity: 0;
  clip-path: polygon(30% 0%, 100% 0%, 70% 100%, 0% 100%);
  margin-right: .5rem;
  flex-shrink: 0;
  transform: translateX(-6px);
  transition: opacity 0.4s cubic-bezier(0.16, 1, 0.3, 1),
              transform 0.4s cubic-bezier(0.16, 1, 0.3, 1);
}
.project-section-title.title-revealed::before {
  opacity: .3;
  transform: translateX(0);
}

/* Page hero eyebrow — also draws in on load */
.page-hero-eyebrow {
  clip-path: polygon(var(--clip-x) 0%, 100% 0%, calc(100% - var(--clip-x)) 100%, 0% 100%);
}

/* ─── Reduced motion overrides ───────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  #page-transition { display: none !important; }
  .project-card-wrap.card-reveal-init,
  .act-card-wrap.card-reveal-init { opacity: 1; transform: none; }
  .project-skill-badge.badge-shimmer { animation: none; }
  .section-eyebrow::before { transition: none; transform: scaleX(1) skewX(-20deg); }
  .project-section-title::before { transition: none; opacity: .3; transform: none; }
}
