Skip to main content

Documentation Index

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

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

Aurora Cosmos has two distinct animation systems working in parallel. Framer Motion drives everything that responds to scroll or requires smooth, physics-aware interpolation — the drifting aurora gradient layers, the starfield parallax, and the navigation active indicator. CSS keyframes handle the ambient, looping effects — star twinkle, shooting stars, orbiting decorative elements, and the generic pulse utility. Understanding which system controls which effect makes tuning straightforward.

Aurora background tuning

The three aurora gradient layers in components/AuroraBackground.js each receive their own Framer Motion animate and transition props. The values below are the defaults used in the template.
// components/AuroraBackground.js — Layer 1 (turquoise/teal/violet)
<motion.div
  animate={{
    x:      ["-10%", "5%",  "-10%"],
    y:      ["-5%",  "5%",  "-5%"],
    rotate: [0, 2, 0],
  }}
  transition={{
    duration: 25,        // seconds per full cycle — increase for slower drift
    repeat:   Infinity,
    ease:     "linear",
  }}
  className="absolute -top-[20%] -left-[10%] w-[120%] h-[60%] opacity-40 mix-blend-screen filter blur-[100px]"
>
  <div className="absolute inset-0 bg-gradient-to-r from-aurora-turquoise via-aurora-teal to-cosmic-violet rounded-full transform -rotate-12 scale-y-50" />
</motion.div>

// Layer 2 (magenta/violet/teal) — 30 s cycle, counter-rotation
<motion.div
  animate={{
    x:      ["5%",  "-5%", "5%"],
    y:      ["5%",  "-5%", "5%"],
    rotate: [0, -2, 0],
  }}
  transition={{ duration: 30, repeat: Infinity, ease: "linear" }}
  className="absolute top-[10%] -right-[20%] w-[100%] h-[50%] opacity-30 mix-blend-screen filter blur-[120px]"
>
  <div className="absolute inset-0 bg-gradient-to-l from-cosmic-magenta via-cosmic-violet to-aurora-teal rounded-full transform rotate-12 scale-y-50" />
</motion.div>

// Layer 3 (green/teal) — 20 s cycle, vertical drift only
<motion.div
  animate={{
    x: ["-5%", "5%",  "-5%"],
    y: ["10%", "0%",  "10%"],
  }}
  transition={{ duration: 20, repeat: Infinity, ease: "linear" }}
  className="absolute bottom-0 left-[10%] w-[80%] h-[40%] opacity-20 mix-blend-screen filter blur-[90px]"
>
  <div className="absolute inset-0 bg-gradient-to-t from-aurora-green via-aurora-teal to-transparent rounded-full scale-y-50" />
</motion.div>
Increasing duration slows the drift and creates a more tranquil atmosphere. Decreasing it adds energy. The ease: "linear" value keeps the motion perfectly loopable without any acceleration artifacts — switching to "easeInOut" will cause subtle speed pulsing at each cycle boundary.

Reducing aurora intensity

Each layer exposes two levers for dialing back the visual weight without touching the motion values. Opacity — each layer <motion.div> has an opacity-* class. The defaults are opacity-40, opacity-30, and opacity-20 for layers 1, 2, and 3 respectively. Reducing these values makes the aurora more subtle against the dark background. Blur radius — the blur-[Npx] class on each layer controls how far the gradient softens outward. The defaults are blur-[100px], blur-[120px], and blur-[90px]. Larger values create a more diffuse, lower-contrast glow; smaller values make the aurora shapes tighter and more defined.
// Example: muted aurora — lower opacity and tighter blur on all three layers
className="... opacity-20 mix-blend-screen filter blur-[80px]"   // layer 1
className="... opacity-15 mix-blend-screen filter blur-[100px]"  // layer 2
className="... opacity-10 mix-blend-screen filter blur-[70px]"   // layer 3

Starfield parallax

components/Starfield.js uses Framer Motion’s useScroll and useTransform to move three star layers at different speeds as the visitor scrolls down the page, creating a depth-of-field illusion.
// components/Starfield.js — scroll-linked parallax mapping
const { scrollY } = useScroll();

// layer1: slowest — large, close-looking stars
const layer1Y = useTransform(scrollY, [0, 2000], [0, -100]);

// layer2: medium — mid-distance stars (aurora-turquoise tinted)
const layer2Y = useTransform(scrollY, [0, 2000], [0, -250]);

// layer3: fastest — small, distant cosmic-violet stars with glow
const layer3Y = useTransform(scrollY, [0, 2000], [0, -500]);
The second argument to useTransform is the input range (scroll position in pixels) and the third is the output range (pixel offset applied to the layer). To reduce the parallax effect — useful for users who find heavy motion distracting — decrease the absolute value of the output range endpoints:
// Gentler parallax — half the default travel distance
const layer1Y = useTransform(scrollY, [0, 2000], [0, -50]);
const layer2Y = useTransform(scrollY, [0, 2000], [0, -125]);
const layer3Y = useTransform(scrollY, [0, 2000], [0, -250]);

Star density

The three star layers are generated in a useEffect inside Starfield.js using Array.from({length: N}). The default counts are 100 stars for layer 1, 50 for layer 2, and 25 for layer 3.
// components/Starfield.js — star generation
const generateStars = (count, minSize, maxSize) =>
  Array.from({ length: count }).map((_, i) => ({
    id:      i,
    x:       Math.random() * 100,
    y:       Math.random() * 100,
    size:    Math.random() * (maxSize - minSize) + minSize,
    opacity: Math.random() * 0.8 + 0.2,
  }));

setStars({
  layer1: generateStars(100, 1, 2),  // ← change 100 to increase/decrease density
  layer2: generateStars(50,  2, 3),  // ← change 50
  layer3: generateStars(25,  3, 4),  // ← change 25
});
Larger counts create a denser, Milky-Way-style field. Lower counts give a sparse, minimalist sky. Star sizes are in pixels and scale with each layer to reinforce the depth effect.

CSS keyframe durations

The four looping CSS animations are defined as @keyframes blocks in assets/main.css. Edit the animation duration value in that file to change the speed of each effect.
/* assets/main.css */
@keyframes twinkle {
  0%, 100% { opacity: 0.2; }
  50%       { opacity: 1;   }
}
.animate-twinkle {
  animation: twinkle 4s ease-in-out infinite; /* increase for slower fade */
}
The animationDelay on individual shooting star elements is set inline in Starfield.js — the first streak fires after 5s and the second after 12s. Increase these delay values to space the streaks further apart and reduce how often they appear.
// components/Starfield.js — shooting star delay values
<div style={{ animationDelay: "5s" }}  className="... animate-shooting-star" />
<div style={{ animationDelay: "12s" }} className="... animate-shooting-star" />

Disabling animations for reduced motion

Wrap any Framer Motion component with the useReducedMotion hook to detect when the visitor’s OS-level “reduce motion” preference is active, then skip the animation entirely.
import { motion, useReducedMotion } from "framer-motion";

function AuroraBackground() {
  const prefersReducedMotion = useReducedMotion();

  const layer1Animate = prefersReducedMotion
    ? {}                                          // static — no animation
    : { x: ["-10%", "5%", "-10%"], y: ["-5%", "5%", "-5%"], rotate: [0, 2, 0] };

  const layer1Transition = prefersReducedMotion
    ? {}
    : { duration: 25, repeat: Infinity, ease: "linear" };

  return (
    <motion.div animate={layer1Animate} transition={layer1Transition} className="...">
      {/* gradient div */}
    </motion.div>
  );
}
For the CSS keyframe animations on star and shooting-star elements, add a prefers-reduced-motion media query in assets/main.css:
/* assets/main.css — respect OS reduced-motion preference */
@media (prefers-reduced-motion: reduce) {
  .animate-twinkle,
  .animate-shooting-star,
  .animate-orbit,
  .animate-pulse {
    animation: none;
  }
}
Aurora Cosmos’s page sections each fade and slide in as they enter the viewport. These entrance animations use a stagger pattern — each child element starts its animation a fixed number of milliseconds after the previous one, creating a cascading reveal. To adjust stagger timing, look for transition={{ delay: index * 0.1 }} patterns in the page components and change the multiplier. A value of 0.05 feels snappier; 0.2 feels more deliberate and editorial.

Build docs developers (and LLMs) love