Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/apursley2012/developer-exe/llms.txt

Use this file to discover all available pages before exploring further.

developer.exe runs two parallel animation systems. The first is Framer Motion — a JavaScript library that handles page transitions, entrance animations, and interactive micro-interactions with spring physics and gesture hooks. The second is a set of custom CSS keyframes defined in main.css that run entirely in the browser’s compositor thread: the synthwave grid scroll, the glitch text offset, and the opacity pulse used on blinking HUD elements. Keeping these two systems separate means the most visually intensive effects (the continuously looping grid and glitch animations) never compete with JavaScript execution.

Page Transitions

The app wraps each route in <AnimatePresence mode="wait"> so that the exiting page finishes its leave animation before the entering page begins. Card grids stagger their children by multiplying the card index by a delay offset:
<AnimatePresence mode="wait">
  <motion.div
    initial={{ opacity: 0, y: 20 }}
    animate={{ opacity: 1, y: 0 }}
    transition={{ delay: index * 0.1 }}
  >
    {/* card content */}
  </motion.div>
</AnimatePresence>
Each card fades up from y: 20 to y: 0, with the stagger delay creating a cascading reveal effect across the grid.

HUD Entrance Animation

The site’s persistent HUD slides down from off-screen on initial mount. The element starts at y: -50 (50 px above the viewport edge) and animates to its resting position:
<motion.div initial={{ y: -50 }} animate={{ y: 0 }}>
  {/* HUD content */}
</motion.div>
Because no transition prop is provided, Framer Motion uses its default spring, which produces a natural deceleration that feels like the HUD snapping into place.

Scroll-Triggered Reveals

Content sections use whileInView with viewport={{ once: true }} so each element animates in only the first time it enters the viewport — subsequent scrolls do not re-trigger the animation:
<motion.div
  initial={{ opacity: 0, x: -20 }}
  whileInView={{ opacity: 1, x: 0 }}
  viewport={{ once: true }}
  transition={{ delay: index * 0.2 }}
/>
The x: -20 starting offset gives a subtle left-to-right slide that reinforces the reading direction. Staggering by index * 0.2 creates a sequential cascade when multiple items are in the same viewport.

Scroll Progress Indicator

The Case Studies page drives a “BOSS HP” progress bar using Framer Motion’s useScroll and useSpring hooks. useScroll tracks the page scroll position relative to a container ref, and useSpring smooths the raw value into a spring-interpolated output that drives a scaleY transform on the bar element:
const { scrollYProgress } = useScroll({ target: ref });
const scaleY = useSpring(scrollYProgress, { stiffness: 100, damping: 30 });
The stiffness: 100, damping: 30 spring configuration gives a slight lag behind the actual scroll position — the bar trails the user’s reading progress rather than jumping instantly, reinforcing the feeling of draining a boss health bar.

CSS Keyframe Animations

Synthwave Grid — grid-move

The perspective grid in SynthwaveGrid.js scrolls continuously downward using a simple translateY loop, creating the illusion of infinite forward motion. The .synthwave-grid element is positioned with bottom: -50%; left: -50% and sized at 200% × 200% so the 50 px translateY shift is visually seamless — the grid pattern tiles before the edge becomes visible. The rotateX(75deg) transform and transform-origin: top center on the container create the receding perspective plane:
@keyframes grid-move {
  0%   { transform: translateY(0); }
  100% { transform: translateY(50px); }
}

.synthwave-grid {
  position: absolute;
  bottom: -50%;
  left: -50%;
  width: 200%;
  height: 200%;
  background-image:
    linear-gradient(to right, rgba(34, 211, 238, 0.3) 1px, transparent 1px),
    linear-gradient(to bottom, rgba(255, 43, 214, 0.3) 1px, transparent 1px);
  background-size: 50px 50px;
  transform: rotateX(75deg);
  transform-origin: top center;
  animation: grid-move 2s linear infinite;
}
The Tailwind utility class animate-[grid-move_2s_linear_infinite] applies the same animation inline without a separate CSS class.

Pulse — animate-pulse and animate-pulse-fast

Two pulse variants drive blinking UI elements such as score readouts and pinned badges:
  • animate-pulse — standard 2 s Tailwind pulse (opacity drops to 0.5 at 50% of the cycle)
  • animate-pulse-fast — same keyframe at 1 s duration for a more urgent blink
@keyframes pulse {
  50% { opacity: 0.5; }
}
.animate-pulse      { animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite; }
.animate-pulse-fast { animation: pulse 1s cubic-bezier(0.4, 0, 0.6, 1) infinite; }

Glitch Text — glitch-anim and glitch-anim-2

The glitch effect is built on CSS pseudo-elements. .glitch-text-base renders the text with a permanent dual-color text-shadow on the base element itself, then :before and :after each duplicate the text content via attr(data-text), cover the base with a solid background, and shift horizontally with contrasting neon text-shadow values driven by the named keyframe animations:
.glitch-text-base {
  position: relative;
  display: inline-block;
  text-shadow: 2px 0 var(--hot-magenta), -2px 0 var(--electric-cyan);
}

.glitch-text-base::before,
.glitch-text-base::after {
  content: attr(data-text);
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: #06070d;
}

.glitch-text-base::before {
  left: 2px;
  text-shadow: -2px 0 var(--hot-magenta);
  animation: glitch-anim 3s infinite linear alternate-reverse;
}

.glitch-text-base::after {
  left: -2px;
  text-shadow: -2px 0 var(--electric-cyan);
  animation: glitch-anim-2 2.5s infinite linear alternate-reverse;
}
The two pseudo-elements run at different durations (3 s and 2.5 s) and both use alternate-reverse, ensuring the offset phases drift in and out of sync over time rather than repeating a predictable pattern. The magenta layer shifts right; the cyan layer shifts left — producing the characteristic RGB-split glitch look.

PixelButton Hover and Tap

PixelButton.js applies Framer Motion gesture props directly to the <motion.button> element for snappy interactive feedback. The component accepts a variant prop that switches between four predefined color schemes:
<motion.button
  whileHover={{ scale: 1.05 }}
  whileTap={{ scale: 0.95 }}
  className={`
    font-pixel text-xs md:text-sm uppercase px-6 py-3
    pixel-border transition-colors duration-200
    ${variantClasses}
  `}
>
  {children}
</motion.button>
The four variants and their Tailwind class sets:
VariantBackgroundTextHover
primary (default)bg-neon-magentatext-whitehover:bg-neon-cyan hover:text-arcade-black
secondarybg-arcade-navytext-neon-cyanhover:bg-neon-cyan hover:text-arcade-navy
dangerbg-arcade-blacktext-neon-greenhover:bg-neon-green hover:text-arcade-black
ghostbg-transparenttext-neon-yellowhover:bg-neon-yellow/20
whileHover scales the button up 5 % to signal interactivity; whileTap scales it down 5 % to simulate a physical button press. Framer Motion’s default spring makes both transitions feel snappy without needing explicit transition configuration.
The interactive prop on <GlitchText> gates the glitch animation behind mouse hover using onMouseEnter and onMouseLeave state. Pass interactive={false} (the default) to run the glitch loop at all times, or interactive={true} to activate it only on hover. The hover-only mode is useful on text-heavy pages where many simultaneously animating pseudo-elements would cause unnecessary paint work.

Build docs developers (and LLMs) love