Player One’s animation system operates on two independent layers. The first is Framer Motion — a React animation library that handles orchestrated JS-driven transitions: page entrances and exits, floating ghost sprites, and interactive hover lifts. The second is CSS keyframes — lightweight, GPU-accelerated loops that run entirely off the main thread and handle the perpetual ambient effects: CRT flicker, scanline overlays, and the glitch text corruption. Together, the two layers create a display that feels alive without sacrificing performance.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/apursley2012/player-one/llms.txt
Use this file to discover all available pages before exploring further.
Page Transition
Every route change is wrapped in aPageTransition component that blurs and scales the outgoing page out, then blurs and scales the incoming page in. The simultaneous scale and blur change creates the impression of a screen powering on — as if the new stage is snapping into focus from an out-of-sync signal.
| State | opacity | scale | filter |
|---|---|---|---|
initial (enter start) | 0 | 0.95 | blur(10px) |
animate (settled) | 1 | 1 | blur(0px) |
exit (leave end) | 0 | 1.05 | blur(10px) |
1.05) so the outgoing page appears to push away rather than simply fade — a subtle depth cue that distinguishes a forward navigation from a backward one.
Ghost Sprite Animation
AGhostSprite component drifts a pixel-art ghost across the full viewport width at a randomized height, repeating forever. The traversal and vertical oscillation are driven by two separate Framer Motion animate calls composed together.
Traversal keyframes. Starts at
-10vw so the sprite enters from fully off-screen left; ends at 110vw so it exits fully off-screen right before looping.Vertical oscillation keyframes in pixels, expressed relative to
startY (the sprite’s randomized spawn height). The mirror repeat type reverses the sequence on alternate iterations, producing a smooth floating bob rather than a hard reset.12 seconds per full traversal. Adjust to control ghost speed — lower values produce a faster, more frantic sprite.duration / 2 — half the sprite’s total traversal duration per oscillation cycle. Runs independently of x so the vertical phase drifts relative to the horizontal position on each pass.CRT Flicker
The.crt-overlay class drives a continuous 0.15 s opacity loop that simulates the natural luminance instability of a cathode-ray tube operating at the edge of its refresh cycle.
0.85 at 5 % followed by a recovery and a hold at full opacity — produces an irregular flutter rather than a uniform pulse. This matches the characteristic one-sided flicker pattern of fluorescent-phosphor displays rather than a simple sine-wave strobe.
The flicker animation is applied to
.crt-overlay, which also carries the scanline and color-fringing background layers. Animating a single overlay element keeps the effect to one composite layer, avoiding the GPU cost of independently animating every element on the page.Glitch Animation
The glitch effect uses two@keyframes sequences that move a clip rectangle across the element’s height at different speeds and offsets, making it look as if horizontal strips of the text are being misread from corrupted video memory.
::before pseudo-element runs glitch-anim-2 at 3 s with a #ff00aa (magenta) text shadow, and ::after runs glitch-anim at 2.5 s with a #00ffff (cyan) text shadow. Because the two durations are not integer multiples of each other, the two corruption layers never fall into a repeating visual pattern, keeping the glitch looking genuinely random.
Hover Effects
Player One layers three distinct hover interactions depending on the element type.ArcadeCabinet Card Lift
Project cards use Framer Motion’swhileHover to lift 10 px upward on hover, simulating the physical push of an arcade button being raised:
Button Color Transitions
Interactive buttons and links use a CSStransition at 150 ms — short enough to feel instant but long enough to avoid a harsh snap:
Box Glow on Hover
Bordered panels and nav items use the.hover:box-glow-* utility classes to activate the inset neon glow when focused or hovered:
Navigation Modal
The full-screen navigation overlay mounts and unmounts through Framer Motion’sAnimatePresence, which keeps the exit animation alive until it completes before removing the element from the DOM.
AnimatePresence is required any time you need a Framer Motion component to animate on exit. Without it, React unmounts the component immediately on a state change and the exit variant never runs. The Navigation modal relies on AnimatePresence so the opacity fade-out completes before the overlay is removed from the DOM — preventing a jarring instant disappearance.