/* ===========================================================================
   Arena Rise — logo intro, hero showreel backdrop, hero pointer response.

   INTRO PHASE TABLE (single 3000ms timeline, percentages are of that)
   ---------------------------------------------------------------------------
   phase              %          ms          what moves
   setup              0          0           mark at .82, invisible
   anticipation       0–25       0–750       mark eases DOWN to .78 while fading
                                             in — the counter-move that makes the
                                             growth read as a push, not a fade
   commitment         25–45      750–1350    mark .78 → 1.05, full opacity
   settle             45–54      1350–1620   1.05 → 1.00, overshoot recovered
   secondary          30–62      900–1860    wordmark masks up: starts AFTER the
                                             mark commits, settles AFTER it lands
   hold               54–80      1620–2400   rule draws, tagline fades in
   exit anticipation  80–85      2400–2560   lockup drifts DOWN 6px
   exit               85–100     2560–3000   lockup lifts and fades, curtain
                                             wipes up to reveal the page
   ---------------------------------------------------------------------------
   Every channel is a pure function of elapsed time — no frame-to-frame state,
   so a skip or a reduced-motion run lands in exactly the same end pose.
   =========================================================================== */

.intro{
  position:fixed;inset:0;z-index:120;background:#000;
  display:grid;place-items:center;
  will-change:transform;
  animation:intro-curtain 3000ms cubic-bezier(.16,1,.3,1) both;
}
body.intro-open{overflow:hidden}

.intro__lockup{display:flex;flex-direction:column;align-items:center;gap:22px;padding:24px}

.intro__mark{width:clamp(96px,14vw,168px);height:auto;display:block;
  animation:intro-mark 3000ms cubic-bezier(.16,1,.3,1) both}

/* the wordmark rises out of a clip, so its entrance reads as a reveal
   rather than a fade — same mask vocabulary as the hero headline */
.intro__word{display:block;overflow:hidden;padding-block:4px}
.intro__word span{
  display:block;
  font:var(--fw-black) clamp(20px,3.2vw,34px)/1 var(--font-display);
  letter-spacing:var(--ls-wider);text-transform:uppercase;color:#fff;
  animation:intro-word 3000ms cubic-bezier(.16,1,.3,1) both}

.intro__rule{width:88px;height:2px;background:var(--ar-teal-400);transform-origin:center;
  animation:intro-rule 3000ms cubic-bezier(.16,1,.3,1) both}

.intro__tag{font-size:var(--fs-3xs);letter-spacing:var(--ls-widest);text-transform:uppercase;
  color:rgba(255,255,255,.62);white-space:nowrap;
  animation:intro-tag 3000ms linear both}

@keyframes intro-curtain{
  0%,85%{transform:translateY(0)}
  100%  {transform:translateY(-101%)}
}
@keyframes intro-mark{
  0%   {opacity:0;   transform:translateY(0) scale(.82)}
  25%  {opacity:.45; transform:translateY(0) scale(.78)}   /* anticipation */
  45%  {opacity:1;   transform:translateY(0) scale(1.05)}  /* commitment */
  54%  {opacity:1;   transform:translateY(0) scale(1)}     /* settle */
  80%  {opacity:1;   transform:translateY(0) scale(1)}     /* hold */
  85%  {opacity:1;   transform:translateY(6px) scale(1)}   /* exit anticipation */
  100% {opacity:0;   transform:translateY(-26px) scale(1.02)}
}
@keyframes intro-word{
  0%,30%{opacity:0; transform:translateY(105%)}
  62%   {opacity:1; transform:translateY(0)}
  80%   {opacity:1; transform:translateY(0)}
  85%   {opacity:1; transform:translateY(4px)}
  100%  {opacity:0; transform:translateY(-22px)}
}
@keyframes intro-rule{
  0%,52%{transform:scaleX(0);opacity:1}
  72%   {transform:scaleX(1);opacity:1}
  85%   {transform:scaleX(1);opacity:1}
  100%  {transform:scaleX(1);opacity:0}
}
@keyframes intro-tag{
  0%,58%{opacity:0}
  75%   {opacity:.62}
  85%   {opacity:.62}
  100%  {opacity:0}
}

/* skip: collapse to the same end pose, fast, without replaying anything */
.intro.is-done{
  animation:none;transform:translateY(-101%);
  transition:transform 420ms cubic-bezier(.16,1,.3,1)}
.intro.is-done *{animation:none!important;opacity:0;transition:opacity 200ms linear}

@media (prefers-reduced-motion:reduce){
  .intro,.intro *{animation:none!important}
  .intro{display:none}
}

/* ------------------------------------------------------- hero showreel --- */
/* Sits above the page-wide canvas, below the veil and the type. Muted, looped
   and silent — it is a backdrop, not a player; the same film is watchable with
   sound from the work grid. */
.hero__video{
  position:absolute;inset:0;width:100%;height:100%;
  object-fit:cover;display:block;z-index:-3;
  opacity:0;transition:opacity 1200ms var(--ease-out)}
.hero__video.is-live{opacity:1}
/* where the loop is withheld — phone, metered connection, reduced motion —
   the element still carries the poster, so the hero keeps the same
   composition as a still instead of falling back to a bare canvas */
.hero__video.is-poster{opacity:.62}

/* ------------------------------------------------------- sound toggle --- */
/* stacked above the floating WhatsApp button, which owns this corner */
.hero__sound{
  position:absolute;inset-inline-end:38px;bottom:100px;z-index:3;
  width:44px;height:44px;border-radius:50%;display:grid;place-items:center;
  cursor:pointer;padding:0;
  background:rgba(0,0,0,.42);border:1px solid rgba(255,255,255,.34);color:#fff;
  backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);
  transition:background-color var(--dur-fast) var(--ease-standard),
             border-color var(--dur-fast) var(--ease-standard),
             color var(--dur-fast) var(--ease-standard),
             transform var(--dur-base) var(--ease-out)}
.hero__sound:hover{background:var(--ar-teal-400);border-color:var(--ar-teal-400);
  color:var(--ar-ink);transform:scale(1.06)}
.hero__sound svg{width:19px;height:19px;display:block}
.hero__sound-on,.hero__sound-off{display:none;line-height:0}
/* the icon shows the CURRENT state, not the action — a crossed speaker while
   muted is the convention people already read correctly */
.hero__sound[data-muted="false"] .hero__sound-on{display:block}
.hero__sound[data-muted="true"]  .hero__sound-off{display:block}
/* while sound is still waiting on a gesture, the control asks to be pressed */
.hero__sound[data-await="true"]{border-color:var(--ar-teal-400);
  box-shadow:0 0 0 0 rgba(69,195,194,.55);animation:sound-ask 2.6s var(--ease-standard) infinite}
@keyframes sound-ask{
  0%,70%,100%{box-shadow:0 0 0 0 rgba(69,195,194,.45)}
  35%        {box-shadow:0 0 0 9px rgba(69,195,194,0)}
}
@media (max-width:760px){
  .hero__sound{inset-inline-end:26px;bottom:84px;width:40px;height:40px}
}
@media (prefers-reduced-motion:reduce){
  .hero__sound[data-await="true"]{animation:none}
}

/* a teal light that follows the cursor across the hero */
.hero__spot{
  position:absolute;inset:0;z-index:-1;pointer-events:none;opacity:0;
  transition:opacity 600ms var(--ease-standard);
  background:radial-gradient(520px 380px at var(--spot-x,50%) var(--spot-y,40%),
             rgba(69,195,194,.20),rgba(69,195,194,.06) 42%,transparent 68%)}
.hero.is-pointing .hero__spot{opacity:1}

/* the hero column counter-drifts against the pointer — small, and slower than
   the cursor, so it reads as depth rather than as the content chasing a mouse */
.hero__inner{will-change:transform}

/* The desktop veil is a horizontal ramp tuned for the RTL text column. On a
   phone the copy spans the full width, so the ramp has to run top-to-bottom
   instead or the headline sits on open picture. */
@media (max-width:760px){
  .hero__video.is-poster{opacity:.5}
  .hero__veil{background:
    radial-gradient(90% 55% at 72% 10%,rgba(69,195,194,.12),transparent 62%),
    linear-gradient(to bottom,rgba(0,0,0,.58),rgba(0,0,0,.74) 55%,rgba(0,0,0,.86))}
}

@media (prefers-reduced-motion:reduce){
  .hero__video{transition:none}
  .hero__spot{display:none}
}
