.frame[data-frame="01"] {
  /* True black void — overrides the global --surface-void (#040712) just for F01
     so the gold halo + medallion read with maximum contrast.
     Warms toward gold-tinted dark as --f01-exit rises (portal transition). */
  --f01-exit: 0;
  background:
    radial-gradient(
      circle at center,
      rgba(60, 36, 4, calc(var(--f01-exit) * 0.55)) 0%,
      rgba(26, 15, 0, calc(var(--f01-exit) * 0.85)) 45%,
      rgba(0, 0, 0, 0) 80%
    ),
    #000000;
  transition: background 0.6s var(--ease-default);
}

.frame[data-frame="01"] .stage {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* Warm gold halo — lit-from-behind backdrop for the medallion. */
.frame[data-frame="01"] .logo-halo {
  position: absolute;
  top: 50%;
  left: 50%;
  width: min(86vmin, 1080px);
  height: min(86vmin, 1080px);
  transform: translate(-50%, -50%);
  background: radial-gradient(
    circle at center,
    rgba(232, 188, 96, 0.30) 0%,
    rgba(212, 168, 74, 0.18) 18%,
    rgba(184, 134, 11, 0.10) 38%,
    rgba(184, 134, 11, 0.03) 60%,
    rgba(0, 0, 0, 0) 78%
  );
  filter: blur(3px);
  pointer-events: none;
  opacity: 0;
  transition: opacity 1.8s var(--ease-default) 0.2s, transform 0.6s var(--ease-default);
  will-change: transform, opacity;
}

.frame[data-frame="01"].is-active .logo-halo {
  /* Halo scales faster than medallion (×~1.5) and brightens toward a full-screen
     white-gold wash as --f01-exit climbs. At exit=1 it dominates the viewport,
     so the F02 swap dissolves out of a gold wash instead of cutting. */
  opacity: calc(1 + var(--f01-exit) * 3.2);
  transform:
    translate(-50%, -50%)
    scale(calc(1 + var(--f01-exit) * 5.5));
}

/* During active exit motion the transform should respond instantly to the
   scroll-driven custom property; the 0.6s transition only applies on reset
   (F02 → F01 reverse) so the halo eases back. */
.frame[data-frame="01"].is-exiting .logo-halo,
.frame[data-frame="01"].is-exiting .logo-medallion {
  transition: none;
}

/* The medallion = wrapper that owns the 3D sway + entry animation.
   Inner <img> handles navy→gold color conversion via filter chain.
   Inner .logo-sheen adds a top-edge highlight (the "raised brass" feel). */
.frame[data-frame="01"] .logo-medallion {
  position: relative;
  display: inline-block;
  cursor: pointer;
  opacity: 0;
  transform: perspective(1000px) rotateY(0deg) scale(0.92);
  transform-style: preserve-3d;
  will-change: transform, opacity;
  filter:
    drop-shadow(0 6px 14px rgba(0, 0, 0, 0.55))
    drop-shadow(0 0 36px rgba(184, 134, 11, 0.32))
    drop-shadow(0 0 80px rgba(184, 134, 11, 0.14));
  transition: filter 0.4s var(--ease-default);
}

.frame[data-frame="01"] .logo-medallion:hover {
  filter:
    drop-shadow(0 8px 18px rgba(0, 0, 0, 0.60))
    drop-shadow(0 0 44px rgba(232, 188, 96, 0.42))
    drop-shadow(0 0 96px rgba(184, 134, 11, 0.18));
}

.frame[data-frame="01"].is-active .logo-medallion {
  animation:
    f01-medallion-in 1.4s var(--ease-default) 0.2s forwards,
    f01-medallion-sway 8s ease-in-out 1.8s infinite,
    f01-medallion-breathe 3.5s ease-in-out 1.6s infinite;
  transition: transform 0.6s var(--ease-default), opacity 0.6s var(--ease-default);
}

/* Once exitProgress > 0.02, kill the sway/breathe keyframes so the
   scroll-driven transform owns the medallion. The medallion grows
   along the camera axis (perspective + translateZ + scale) so it reads
   as a push-in / portal, not a flat zoom.

   Scale  1.0 → 10  (linear over 0..1)
   TranslateZ  0 → 360px  (adds parallax push-in)
   Opacity  1 hold 0..0.7  →  0 by 1.0  (dissolves into the wash) */
.frame[data-frame="01"].is-exiting .logo-medallion {
  animation: none;
  transform:
    perspective(1000px)
    translateZ(calc(var(--f01-exit) * 360px))
    scale(calc(1 + var(--f01-exit) * 9));
  opacity: clamp(0, calc((1 - var(--f01-exit)) / 0.3), 1);
}

/* The PNG: SVG filter thresholds it into gold-where-navy, white-where-white.
   The filter is defined inline in index for the F01 frame (see 01-arrival.js). */
.frame[data-frame="01"] .logo-hero {
  display: block;
  position: relative;
  height: clamp(28vh, 42vh, 46vh);
  width: auto;
  max-width: 86vw;
  filter: url(#f01-gold-white);
}

/* Top-edge highlight band — masked by the same PNG so it only lights the
   medallion area, not the void. Subtle: just lifts the top edge of the gold. */
.frame[data-frame="01"] .logo-sheen {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: linear-gradient(
    180deg,
    rgba(255, 240, 196, 0.32) 0%,
    rgba(255, 220, 140, 0.10) 18%,
    rgba(0, 0, 0, 0) 40%,
    rgba(0, 0, 0, 0) 82%,
    rgba(0, 0, 0, 0.18) 100%
  );
  mix-blend-mode: overlay;
  -webkit-mask-image: url('/02-IMAGES/penn_state_nittany_lions_logo_primary_19838537.png');
  mask-image: url('/02-IMAGES/penn_state_nittany_lions_logo_primary_19838537.png');
  -webkit-mask-size: contain;
  mask-size: contain;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  -webkit-mask-position: center;
  mask-position: center;
}

/* PENN STATE wordmark — rendered as HTML below the medallion in clean white.
   Kept separate so the recoloring filter on the logo doesn't touch it. */
.frame[data-frame="01"] .logo-wordmark {
  position: absolute;
  top: calc(50% + clamp(16vh, 24vh, 26vh));
  left: 50%;
  transform: translate(-50%, 0);
  font-family: var(--font-display);
  font-size: clamp(0.9rem, 1.6vw, 1.2rem);
  letter-spacing: 0.42em;
  color: rgba(245, 243, 238, 0.92);
  text-transform: uppercase;
  pointer-events: none;
  opacity: 0;
  transition: opacity 1.2s var(--ease-default) 1.1s;
}

.frame[data-frame="01"].is-active .logo-wordmark {
  /* Fade fast (0 → 0.3 of exitProgress) so the medallion owns the frame
     during the push-in. */
  opacity: clamp(0, calc(1 - var(--f01-exit) / 0.3), 1);
}

@keyframes f01-medallion-in {
  from { opacity: 0; transform: perspective(1000px) rotateY(-6deg) scale(0.92); }
  to   { opacity: 1; transform: perspective(1000px) rotateY(0deg)  scale(1);    }
}

/* Slow 3D sway — perspective rotation ±6deg, 8s cycle, with a tiny
   scale-pulse baked in so we keep the "breathing" feel without a second
   transform animation fighting this one. */
@keyframes f01-medallion-sway {
  0%,  100% { transform: perspective(1000px) rotateY(-6deg) scale(1.000); }
  25%       { transform: perspective(1000px) rotateY( 0deg) scale(1.012); }
  50%       { transform: perspective(1000px) rotateY( 6deg) scale(1.000); }
  75%       { transform: perspective(1000px) rotateY( 0deg) scale(1.012); }
}

/* Breathe — applied as a parallel scale via a tiny additional animation.
   Stays subtle (1 → 1.015) so it doesn't fight the sway. */
@keyframes f01-medallion-breathe {
  0%, 100% { filter:
    drop-shadow(0 6px 14px rgba(0, 0, 0, 0.55))
    drop-shadow(0 0 36px rgba(184, 134, 11, 0.32))
    drop-shadow(0 0 80px rgba(184, 134, 11, 0.14)); }
  50%      { filter:
    drop-shadow(0 6px 14px rgba(0, 0, 0, 0.55))
    drop-shadow(0 0 44px rgba(212, 168, 74, 0.40))
    drop-shadow(0 0 96px rgba(184, 134, 11, 0.18)); }
}

@media (prefers-reduced-motion: reduce) {
  .frame[data-frame="01"].is-active .logo-medallion {
    animation: none;
    opacity: 1;
    transform: perspective(1000px) rotateY(0deg) scale(1);
  }
  .frame[data-frame="01"] .logo-halo {
    transition: none;
  }
}

.frame[data-frame="01"] .tagline {
  position: absolute;
  left: 50%;
  bottom: clamp(var(--space-xl), 12vh, var(--space-3xl));
  transform: translateX(-50%);
  max-width: 36rem;
  padding: 0 var(--space-md);
  text-align: center;
  font-family: var(--font-serif);
  font-style: italic;
  font-size: clamp(1rem, 1.6vw, 1.25rem);
  line-height: 1.6;
  color: var(--ink-muted);
  opacity: 0;
  transition: opacity 1.2s var(--ease-default) 0.6s;
  pointer-events: none;
}

.frame[data-frame="01"].is-active .tagline {
  opacity: clamp(0, calc(1 - var(--f01-exit) / 0.3), 1);
}

.frame[data-frame="01"] .hint {
  position: absolute;
  left: 50%;
  bottom: var(--space-md);
  transform: translateX(-50%);
  font-family: var(--font-display);
  font-size: 0.7rem;
  letter-spacing: 0.4em;
  color: rgba(245, 243, 238, 0.25);
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.8s var(--ease-default) 1.6s;
}

.frame[data-frame="01"].is-active .hint {
  opacity: clamp(0, calc(1 - var(--f01-exit) / 0.3), 1);
}
