/* ═══════════════════════════════════════════════════════════════
   WACKT — PANEL ANIMATIONS
   ═══════════════════════════════════════════════════════════════
   EVERY mobile project-panel animation lives in this file and
   nowhere else. Edit here; layout stays untouched.

   ── HOW IT WORKS ───────────────────────────────────────────────
   Each .proj-group contains TWO effect layers:

     <div class="panel-amb  amb-film">    z-index 1  — behind cards
     <div class="panel-rev  rev-film">    z-index 6  — OVER cards

   .panel-amb = permanent atmosphere (glow, grid, vignette)
   .panel-rev = the reveal that clears away (curtain, bars, rings)

   The reveal layer sits ABOVE the cards so you actually see it,
   then moves off-screen leaving the content visible. This is why
   the theatre curtain read well and the old film effect did not —
   the old one was buried behind the cards.

   Animations fire when JS adds .inview to the .proj-group.

   ── TIMING KNOBS (edit these) ──────────────────────────────────  */
:root{
  --fx-reveal:   1.35s;   /* UNIFORM — how long every reveal takes to clear, matched to the curtain */
  --fx-delay:    .05s;    /* UNIFORM — pause before every reveal starts */
  --fx-beat:     .55s;    /* a short internal beat (clap, ignite, sweep) that happens BEFORE the reveal starts */
  --fx-ease:     cubic-bezier(.76,0,.24,1);
  --fx-curtain:  #5A1D18; /* theatre velvet                     */
  --fx-bar:      #0B0C10; /* cinema letterbox                   */
  --fx-gold:     #AC945F; /* champagne accent                   */
}

.panel-amb,.panel-rev{position:absolute;inset:0;pointer-events:none;overflow:hidden;}
.panel-amb{z-index:1;}
.panel-rev{z-index:6;}
@media (min-width:901px){.panel-amb,.panel-rev{display:none;}}

/* ══════════════════════════════════════════════════════════════
   01 · TV & FILM  —  "The Clapperboard"
   Beat (0 → .55s): slate face reveals, clap arm snaps, ACTION stamps.
   Reveal (.55s → .55s+1.35s): camera racks focus THROUGH the slate —
   it blooms outward and blurs like a push-in, rather than sliding
   off — so the exit reads as "into the story", not "away".
   Matches --fx-reveal / --fx-delay used by every other category.
   ══════════════════════════════════════════════════════════════ */
.rev-slate{
  background:#0B0C10;
  transition:transform var(--fx-reveal) var(--fx-beat) var(--fx-ease),
             opacity var(--fx-reveal) var(--fx-beat) var(--fx-ease),
             filter var(--fx-reveal) var(--fx-beat) ease-out;
  filter:blur(0);
}
.proj-group.inview .rev-slate{transform:scale(2.4);opacity:0;filter:blur(14px);}

.rev-slate .slate{
  position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);
  width:min(78vw,340px);
  transition:opacity .3s calc(var(--fx-beat) * .5) ease;
}
.proj-group.inview .rev-slate .slate{opacity:0;}  /* fades a beat before the push-in finishes */

.rev-slate .clap{
  display:flex;height:38px;border-radius:3px;overflow:hidden;
  transform-origin:0 100%;transform:rotate(-19deg);
  box-shadow:0 6px 18px rgba(0,0,0,.5);
}
.proj-group.inview .rev-slate .clap{animation:fxClap .4s .08s cubic-bezier(.6,0,.2,1) forwards;}
@keyframes fxClap{0%{transform:rotate(-19deg)}70%{transform:rotate(2deg)}100%{transform:rotate(0)}}
.rev-slate .clap i{flex:1;background:#F7F7F5;}
.rev-slate .clap i:nth-child(even){background:#141419;}

.rev-slate .slate-face{
  background:#141419;border:1px solid rgba(255,255,255,.14);
  border-top:none;border-radius:0 0 4px 4px;padding:14px 16px;
  display:flex;flex-direction:column;gap:9px;
}
.rev-slate .sl-row{display:flex;justify-content:space-between;align-items:baseline;
  border-bottom:1px solid rgba(255,255,255,.09);padding-bottom:7px;}
.rev-slate .sl-row:last-child{border-bottom:none;padding-bottom:0;}
.rev-slate .sl-row b{font-family:var(--mono,monospace);font-size:.56rem;letter-spacing:.24em;
  color:rgba(247,247,245,.42);font-weight:600;}
.rev-slate .sl-row u{text-decoration:none;font-size:.8rem;font-weight:700;
  color:#F7F7F5;letter-spacing:.05em;}

/* ACTION stamp — fires right as the clap shuts, before the push-in */
.rev-slate .slate-cut{
  position:absolute;top:calc(100% + 20px);left:50%;transform:translateX(-50%) scale(.7);
  font-family:var(--mono,monospace);font-size:.72rem;letter-spacing:.42em;font-weight:700;
  color:var(--fx-gold);border:1px solid rgba(172,148,95,.5);padding:7px 16px;border-radius:3px;
  opacity:0;white-space:nowrap;
}
.proj-group.inview .rev-slate .slate-cut{animation:fxAction .42s .32s cubic-bezier(.2,1.4,.4,1) forwards;}
@keyframes fxAction{0%{opacity:0;transform:translateX(-50%) scale(.7)}
  55%{opacity:1;transform:translateX(-50%) scale(1.06)}
  100%{opacity:1;transform:translateX(-50%) scale(1)}}

.amb-slate .vig{position:absolute;inset:0;
  background:radial-gradient(circle at 50% 45%,transparent 0 38%,rgba(11,12,16,.09) 80%);}
.amb-slate .warm{position:absolute;inset:0;
  background:radial-gradient(ellipse at 62% 30%,rgba(172,148,95,.15),transparent 62%);}

/* ══════════════════════════════════════════════════════════════
   02 · LIVE & THEATRE  —  "The Curtain"   (unchanged — it works)
   ══════════════════════════════════════════════════════════════ */
.rev-curtain .cur{
  position:absolute;top:0;bottom:0;width:52%;
  background:
    repeating-linear-gradient(90deg,rgba(0,0,0,.34) 0 7px,
      rgba(255,255,255,.06) 7px 15px,rgba(0,0,0,.24) 15px 24px),
    linear-gradient(180deg,var(--fx-curtain) 0%,#3E120F 45%,#260A08 100%);
  box-shadow:0 0 70px rgba(0,0,0,.55) inset;
  transition:transform var(--fx-reveal) var(--fx-delay) var(--fx-ease);
}
.rev-curtain .cur.l{left:0}
.rev-curtain .cur.r{right:0}
.proj-group.inview .rev-curtain .cur.l{transform:translateX(-101%)}
.proj-group.inview .rev-curtain .cur.r{transform:translateX(101%)}
.rev-curtain .pelmet{
  position:absolute;top:0;left:0;right:0;height:54px;
  background:linear-gradient(180deg,#6B241D,#3E120F);
  box-shadow:0 6px 20px rgba(0,0,0,.35);
  transition:transform 1.05s var(--fx-ease);
}
.proj-group.inview .rev-curtain .pelmet{transform:translateY(-100%)}
.amb-curtain .spot{
  position:absolute;inset:0;
  background:radial-gradient(ellipse at 50% 38%,rgba(172,148,95,.22),transparent 62%);
  opacity:0;transition:opacity 1.1s .55s ease;
}
.proj-group.inview .amb-curtain .spot{opacity:1}

/* ══════════════════════════════════════════════════════════════
   03 · INTERACTIVE & PRODUCT  —  "System Online"
   A 7.1 speaker array ignites in one breath, a ring locks them
   together, and a labelled HUD states plainly what you're seeing.
   Compressed to the uniform --fx-reveal timing to match the rest.
   ══════════════════════════════════════════════════════════════ */
.rev-atelier{
  background:#0B0C10;
  transition:opacity calc(var(--fx-reveal) * 2) var(--fx-delay) ease,
             visibility 0s calc(var(--fx-reveal) * 2) linear;
}
.proj-group.inview .rev-atelier{opacity:0;visibility:hidden;}

.rev-atelier .room{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);
  width:min(74vw,300px);height:min(74vw,300px);}

.rev-atelier .core{
  position:absolute;top:50%;left:50%;width:14px;height:14px;margin:-7px 0 0 -7px;
  border-radius:50%;background:var(--fx-gold);opacity:0;transform:scale(.3);
  box-shadow:0 0 24px 6px rgba(172,148,95,.45);
  transition:opacity .6s var(--fx-delay) ease,transform .9s var(--fx-delay) cubic-bezier(.2,1.5,.4,1);}
.proj-group.inview .rev-atelier .core{opacity:1;transform:scale(1);}

/* all 8 speakers ignite in ONE breath, not a chase */
.rev-atelier .node{position:absolute;width:11px;height:11px;margin:-5.5px 0 0 -5.5px;
  border-radius:50%;background:#F7F7F5;opacity:0;transform:scale(.3);}
.proj-group.inview .rev-atelier .node{animation:fxNode 1.1s .2s cubic-bezier(.2,1.5,.4,1) forwards;}
@keyframes fxNode{0%{opacity:0;transform:scale(.3)}100%{opacity:.95;transform:scale(1)}}
.rev-atelier .n1{top:2%;left:50%}.rev-atelier .n2{top:15%;left:85%}
.rev-atelier .n3{top:50%;left:98%}.rev-atelier .n4{top:85%;left:85%}
.rev-atelier .n5{top:98%;left:50%}.rev-atelier .n6{top:85%;left:15%}
.rev-atelier .n7{top:50%;left:2%}.rev-atelier .n8{top:15%;left:15%}

.rev-atelier .ring{position:absolute;inset:0;border-radius:50%;
  border:1px solid rgba(172,148,95,.55);
  opacity:0;transform:scale(.75) rotate(-90deg);
  transition:opacity 1s .6s ease,transform 1.2s .6s cubic-bezier(.2,1.2,.4,1);}
.proj-group.inview .rev-atelier .ring{opacity:1;transform:scale(1) rotate(0);}

/* HUD — appears once, holds, no blink */
.rev-atelier .hud{
  position:absolute;top:calc(100% + 26px);left:50%;transform:translateX(-50%);
  display:flex;flex-direction:column;align-items:center;gap:7px;white-space:nowrap;}
.rev-atelier .hud b{font-family:var(--mono,monospace);font-size:.66rem;letter-spacing:.34em;
  font-weight:700;color:#F7F7F5;opacity:0;transform:translateY(9px);
  transition:opacity .8s 1s ease,transform .8s 1s cubic-bezier(.16,1,.3,1);}
.rev-atelier .hud u{text-decoration:none;font-family:var(--mono,monospace);font-size:.56rem;
  letter-spacing:.28em;color:var(--fx-gold);opacity:0;transition:opacity .7s 1.36s ease;}
.proj-group.inview .rev-atelier .hud b{opacity:1;transform:translateY(0);}
.proj-group.inview .rev-atelier .hud u{opacity:1;}

.amb-atelier .bloom{position:absolute;inset:0;opacity:0;
  background:radial-gradient(ellipse at 50% 46%,rgba(172,148,95,.20),transparent 58%);
  transition:opacity 1.2s calc(var(--fx-reveal) * 1) ease;}
.proj-group.inview .amb-atelier .bloom{opacity:1;animation:fxBreathe 6s calc(var(--fx-reveal) * 2 + .6s) ease-in-out infinite;}
@keyframes fxBreathe{0%,100%{opacity:.7}50%{opacity:1}}

/* ══════════════════════════════════════════════════════════════
   03 · LIVE SHOWS  —  "House Lights Down"
   Tells the production-management story in one gesture: two
   spotlights cross-sweep and lock on a performer silhouette
   centre-stage, a haze bar sits at the floor, and a row of
   audience silhouettes appears below — sound, light, artist,
   and audience, all in the room together. Same uniform timing.
   ══════════════════════════════════════════════════════════════ */
.rev-live{
  background:#0B0C10;
  transition:opacity calc(var(--fx-reveal) * 2) var(--fx-delay) ease,
             visibility 0s calc(var(--fx-reveal) * 2) linear;
}
.proj-group.inview .rev-live{opacity:0;visibility:hidden;}

/* two beams cross-sweeping in from opposite top corners */
.rev-live .beam{
  position:absolute;top:-10%;width:38%;height:135%;
  background:linear-gradient(180deg,rgba(247,247,245,.28),rgba(247,247,245,0) 78%);
  transform-origin:top center;opacity:0;
}
.rev-live .beam.l{left:8%;transform:rotate(-24deg) scaleY(.6);}
.rev-live .beam.r{right:8%;transform:rotate(24deg) scaleY(.6);}
.proj-group.inview .rev-live .beam{animation:fxBeamSwing 1.2s .08s cubic-bezier(.3,0,.2,1) forwards;}
@keyframes fxBeamSwing{
  0%{opacity:0;}
  30%{opacity:1;}
  100%{opacity:.85;transform-origin:top center;}
}
.proj-group.inview .rev-live .beam.l{animation-name:fxBeamL;}
.proj-group.inview .rev-live .beam.r{animation-name:fxBeamR;}
@keyframes fxBeamL{0%{opacity:0;transform:rotate(-46deg) scaleY(.5)}
  35%{opacity:1}100%{opacity:.85;transform:rotate(-10deg) scaleY(1)}}
@keyframes fxBeamR{0%{opacity:0;transform:rotate(46deg) scaleY(.5)}
  35%{opacity:1}100%{opacity:.85;transform:rotate(10deg) scaleY(1)}}

/* performer silhouette — where the beams land */
.rev-live .performer{
  position:absolute;bottom:30%;left:50%;transform:translateX(-50%) scaleY(.7);
  width:10px;height:46px;border-radius:6px 6px 2px 2px;
  background:#0B0C10;box-shadow:0 0 0 1px rgba(247,247,245,.06);
  opacity:0;
}
.proj-group.inview .rev-live .performer{
  animation:fxPerformer .8s .76s cubic-bezier(.2,1.4,.4,1) forwards;
}
@keyframes fxPerformer{0%{opacity:0;transform:translateX(-50%) scaleY(.7)}
  100%{opacity:1;transform:translateX(-50%) scaleY(1)}}
/* hot spot the beams create on the performer */
.rev-live .hotspot{
  position:absolute;bottom:30%;left:50%;width:70px;height:70px;
  margin:0 0 -10px -35px;border-radius:50%;
  background:radial-gradient(circle,rgba(247,247,245,.5),transparent 70%);
  opacity:0;transition:opacity .6s .9s ease;
}
.proj-group.inview .rev-live .hotspot{opacity:1;}

/* haze bar at the stage floor */
.rev-live .haze{
  position:absolute;left:0;right:0;bottom:28%;height:2px;
  background:linear-gradient(90deg,transparent,rgba(247,247,245,.4) 30%,rgba(247,247,245,.4) 70%,transparent);
  filter:blur(6px);opacity:0;transition:opacity 1s .6s ease;
}
.proj-group.inview .rev-live .haze{opacity:1;}

/* audience row — small dark heads along the bottom, backlit */
.rev-live .crowd{position:absolute;left:0;right:0;bottom:8%;height:22px;
  display:flex;justify-content:center;gap:9px;opacity:0;
  transition:opacity .8s 1.1s ease;}
.proj-group.inview .rev-live .crowd{opacity:.55;}
.rev-live .crowd i{width:9px;height:9px;border-radius:50%;background:#0B0C10;
  box-shadow:0 -3px 5px rgba(247,247,245,.15);flex-shrink:0;}

.amb-live .warm{position:absolute;inset:0;opacity:0;
  background:radial-gradient(ellipse at 50% 40%,rgba(172,148,95,.15),transparent 62%);
  transition:opacity 1s calc(var(--fx-reveal) * .8) ease;}
.proj-group.inview .amb-live .warm{opacity:1;}

/* ══════════════════════════════════════════════════════════════
   FAILSAFES — if JS never runs, nothing may cover the content
   ══════════════════════════════════════════════════════════════ */
html:not(.fx-ready) .rev-slate{transform:translateY(-101%);}
html:not(.fx-ready) .rev-atelier{opacity:0;visibility:hidden;}
html:not(.fx-ready) .rev-curtain .cur.l{transform:translateX(-101%);}
html:not(.fx-ready) .rev-curtain .cur.r{transform:translateX(101%);}
html:not(.fx-ready) .rev-curtain .pelmet{transform:translateY(-100%);}
html:not(.fx-ready) .rev-live{opacity:0;visibility:hidden;}
html:not(.fx-ready) .amb-live .warm,
html:not(.fx-ready) .amb-curtain .spot,
html:not(.fx-ready) .amb-atelier .bloom{opacity:1;}

@media (prefers-reduced-motion:reduce){
  .rev-slate,.rev-atelier,.rev-live,.rev-curtain .cur,.rev-curtain .pelmet{transition:none!important;}
  .rev-slate{transform:scale(2.4);opacity:0;filter:blur(14px);}
  .rev-atelier,.rev-live{opacity:0;visibility:hidden;}
  .rev-curtain .cur.l{transform:translateX(-101%);}
  .rev-curtain .cur.r{transform:translateX(101%);}
  .rev-curtain .pelmet{transform:translateY(-100%);}
  .rev-slate .clap,.rev-slate .slate-cut,.rev-atelier .node,.rev-live .beam,
  .amb-atelier .bloom,.amb-curtain .spot,.amb-live .warm{animation:none!important;opacity:1!important;}
}
