Skip to main content

Documentation Index

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

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

The About page turns a standard bio section into an interactive solar-system metaphor. A stylised planet rendered with CSS radial gradients and a subtle box-shadow glow occupies the left half of the screen. Three coloured orbital buttons circle the sphere at 120° intervals; clicking one rotates the planet toward that “sector” and simultaneously swaps the content in the glass panel on the right, using Framer Motion’s AnimatePresence for smooth enter/exit transitions.

Visual Overview

The page layout is a two-column composition (stacked on mobile):
ColumnContents
Left — Planet panelRotating CSS sphere + three orbital navigation buttons
Right — Data panelGlass-morphism card with TeletypeText header + animated sector content
A TeletypeText line — “Scanning sector… Bio-data retrieved.” — animates into view at the top of the right panel on first load, establishing the mission-control reading of your biography.

The Planet

The planet is a <div> styled as a circle with:
  • A radial gradient producing a lit/shadow hemisphere effect.
  • A box-shadow with aurora color spread to create an atmospheric glow.
  • A Framer Motion spring animation on rotate that fires whenever the active sector changes.
The three orbital buttons are absolutely positioned around the planet at 120° intervals using trigonometry (o * 120 * Math.PI / 180) at a radius of 40% of the planet div. Each button has a distinct accent color that matches its sector:
  • Sector 01 — aurora-teal (bg-aurora-teal)
  • Sector 02 — aurora-magenta (bg-aurora-magenta)
  • Sector 03 — aurora-violet (bg-aurora-violet)

The Data Panel

The right-side glass panel renders whichever sector is currently active. AnimatePresence wraps the content block so that the outgoing sector slides and fades out while the incoming sector slides in from the opposite direction.

Data Sectors

The three biographical sectors and their content are defined in the I array in the xt component:
const sectors = [
  {
    id: 'core',
    title: 'Core Directives',
    content: "I believe in building interfaces that respect the user's time and attention. Performance is a feature, and accessibility is a requirement, not an afterthought.",
    color: 'bg-aurora-teal',
  },
  {
    id: 'history',
    title: 'Formation',
    content: 'Started as a designer, evolved into a developer. This dual perspective allows me to bridge the gap between visual intent and technical execution seamlessly.',
    color: 'bg-aurora-magenta',
  },
  {
    id: 'future',
    title: 'Trajectory',
    content: 'Currently exploring the intersections of WebGL, creative coding, and AI-assisted interfaces. Always looking for the next frontier in web experiences.',
    color: 'bg-aurora-violet',
  },
]
Each sector has a string id (not a number), a title displayed as the panel heading, a content string rendered as a paragraph, and a color Tailwind class applied to the indicator dot.

Sector Reference Table

SectoridTitleAccent Color
01'core'Core Directivesbg-aurora-teal
02'history'Formationbg-aurora-magenta
03'future'Trajectorybg-aurora-violet

Planet Rotation Logic

When the user selects a sector, the planet’s spring animation targets a new rotate angle derived from the sector index (0, 1, or 2):
// Planet wrapper uses a Framer Motion spring on the `rotate` style
<motion.div
  animate={{ rotate: activeDegrees }}
  transition={{ type: 'spring', stiffness: 50, damping: 20 }}
>
  {/* orbital buttons + planet surface */}
</motion.div>

// On button click — rotate to sectorIndex * 120 degrees
function handleSectorSelect(sector, index) {
  setActiveSector(sector);
  setActiveDegrees(index * 120);
}
The stiffness: 50 and damping: 20 values produce a natural overshoot-and-settle motion. Increase stiffness for a snappier rotation or raise damping to eliminate the overshoot entirely.

AnimatePresence Panel Transitions

The sector content inside the right glass panel uses AnimatePresence so the old content fades and slides out before the new content slides in:
import { AnimatePresence, motion } from 'framer-motion';

<AnimatePresence>
  <motion.div
    key={activeSector.id}
    initial={{ opacity: 0, y: 20 }}
    animate={{ opacity: 1, y: 0 }}
    exit={{ opacity: 0, y: -20 }}
    transition={{ duration: 0.3 }}
  >
    <h3>{activeSector.title}</h3>
    <p>{activeSector.content}</p>
  </motion.div>
</AnimatePresence>
The content slides vertically (y: 20 → 0 on enter, y: 0 → -20 on exit), giving a smooth upward-reveal feel as sectors change.

Sector Navigation Buttons

Below the glass panel, three text buttons let users switch sectors without clicking the orbital dots:
{sectors.map((sector, index) => (
  <button
    key={`nav-${sector.id}`}
    onClick={() => handleSectorSelect(sector, index)}
    className={`font-mono text-xs px-3 py-1 rounded border interactive transition-colors ${
      activeSector.id === sector.id
        ? 'border-aurora-teal text-aurora-teal bg-aurora-teal/10'
        : 'border-star-dim/30 text-star-dim hover:border-star-white/50'
    }`}
  >
    Sector 0{index + 1}
  </button>
))}
The active sector button is highlighted with an aurora-teal border and background tint; inactive buttons use a dimmed ghost style.

TeletypeText Configuration

<TeletypeText
  text="Scanning sector... Bio-data retrieved."
  className="text-aurora-magenta font-mono text-sm"
/>
The teletype fires once on mount, independent of sector selection. It serves as a page-level establishing line rather than reacting to button clicks.

Customization

  1. Edit sector content — Locate the sectors array in the xt component source and update the content string for each entry with your own biographical copy.
  2. Rename sector titles — Change 'Core Directives', 'Formation', and 'Trajectory' to labels that better reflect your story (e.g., 'Philosophy', 'Background', 'Goals').
  3. Change accent colors — Each sector has a color key mapped to a Tailwind background class. Replace bg-aurora-teal, bg-aurora-magenta, and bg-aurora-violet with any color defined in your tailwind.config.js.
  4. Add a fourth sector — Duplicate one entry in the sectors array, assign it a new string id, title, content, and color. Add a corresponding orbital button; space all four buttons at 90° intervals by changing the rotation multiplier from 120 to 90.
  5. Adjust spring physics — Tune stiffness (snap speed) and damping (oscillation) in the transition object to change the feel of the planet rotation.
  6. Change the teletype line — Update the text prop on TeletypeText to set your own scanning message.
The orbital buttons are absolutely positioned using trigonometry: left: 50 + 40 * Math.cos(angle)% and top: 50 + 40 * Math.sin(angle)%. If you add a fourth sector, change the angle multiplier from 120 to 90 degrees so all four buttons are evenly spaced around the sphere.
The planet’s 3D illusion is achieved purely with CSS — no WebGL or Three.js required. The sphere is a border-radius: 50% div with a background: radial-gradient(...) and a coloured box-shadow. To make the planet appear larger on desktop, increase its width and height values and the orbital button radius (d variable, currently 40) proportionally.

Build docs developers (and LLMs) love