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 Navigation component is the primary wayfinding system of the Cosmic Developer portfolio. It sits permanently fixed at the top of every page, rendering a minimal bar that holds the Star Chart brand logo on the left and a hamburger menu trigger on the right. When the trigger is activated, a full-screen overlay unfurls over the viewport — its blurred dark backdrop diffusing the starfield below — and each destination link animates in with a staggered Framer Motion entrance. The result is a navigation experience that feels less like a drop-down menu and more like deploying a mission-briefing screen from orbit.

Usage

Navigation is a zero-prop component. Drop it once inside your app shell and it handles all open/close state internally.
import { Navigation } from '../components/cosmos/Navigation'

<Navigation />
Because Navigation uses React Router’s NavLink under the hood, it must be rendered inside a <BrowserRouter> (or equivalent router provider). The app shell in main.jsx already satisfies this requirement.

Layout

The top bar is positioned with fixed top-0 left-0 w-full z-50 so it floats above every page layer, including the StarfieldBackground and AuroraBackground canvases. Horizontal rhythm is set by px-6 py-4 with flex justify-between items-center splitting the logo and the menu button to opposite ends. The key visual trick is mix-blend-difference on the <nav> element itself. This CSS blend mode inverts the nav’s foreground colours against whatever sits below it, meaning the white star text and aurora-teal compass icon remain legible whether they’re floating over a pitch-black void or a bright aurora bloom — no semi-transparent background required.
<nav className="fixed top-0 left-0 w-full z-50 px-6 py-4
                flex justify-between items-center mix-blend-difference">
  {/* Star Chart logo — left */}
  {/* Hamburger button — right */}
</nav>
The left slot is a React Router <Link to="/"> containing a Framer Motion <motion.div> that rotates the Lucide Compass icon 180° on hover, paired with the bold uppercase logotype “Star Chart” in the font-heading typeface.

Hamburger Trigger

The right slot is a plain <button> rendering the Lucide Menu icon (w-8 h-8). Clicking it calls setIsOpen(true), which mounts the overlay via AnimatePresence.

Overlay Menu

When isOpen is true, AnimatePresence mounts a Framer Motion <motion.div> that covers the entire viewport (fixed inset-0 z-[100]). The overlay animates its opacity from 0 → 1 and its backdropFilter from blur(0px) → blur(16px) simultaneously, producing the characteristic frosted-glass materialisation effect.
<motion.div
  initial={{ opacity: 0, backdropFilter: 'blur(0px)' }}
  animate={{ opacity: 1, backdropFilter: 'blur(16px)' }}
  exit={{ opacity: 0, backdropFilter: 'blur(0px)' }}
  className="fixed inset-0 z-[100] bg-cosmic-black/80
             flex flex-col justify-center items-center"
>
  {/* Close button — top-right */}
  {/* Nav items list */}
  {/* CTRL+ALT+ASCEND label — bottom */}
</motion.div>
Each nav item is wrapped in its own <motion.div> with an initial of opacity: 0, y: 20 and an animate of opacity: 1, y: 0. The delay is derived from the item’s array index multiplied by 0.05 seconds, creating a cascade that reads from top to bottom:
<motion.div
  initial={{ opacity: 0, y: 20 }}
  animate={{ opacity: 1, y: 0 }}
  exit={{ opacity: 0, y: -20 }}
  transition={{ delay: index * 0.05 }}
>
  <NavLink to={item.path} onClick={() => setIsOpen(false)}>
    <span className="font-mono text-xs text-aurora-violet/70 uppercase tracking-widest">
      {item.desc}
    </span>
    <span className="font-heading text-3xl md:text-5xl font-bold">
      {item.label}
    </span>
  </NavLink>
</motion.div>
Each link presents two text layers: a small monospace desc in muted aurora-violet/70 above a large display-heading label in font-heading. A 2px aurora-teal underline bar also animates from w-0 → w-full on hover via an additional <motion.div>.

Close Button

A close button positioned absolute top-6 right-6 renders the Lucide X icon (w-10 h-10) and calls setIsOpen(false) on click. Its hover colour is aurora-magenta to distinguish it visually from the teal-dominant palette of the links.
The complete navItems array defined in Navigation.js maps every route in the portfolio:
PathLabelDescription
/EarthriseHome
/aboutOrigin CoordinatesAbout
/projectsProbes & PayloadsProjects
/skillsInstrumentsSkills
/workMission LogWork
/case-studiesFlight RecordingsCase Studies
/articlesTransmissionsArticles
/testimonialsGround Control SaysTestimonials
/contactOpen ChannelContact

Customizing Nav Items

The navItems array lives at the top of Navigation.js, just before the component function definition. Each entry is a plain object with three fields:
const navItems = [
  { path: '/',            label: 'Earthrise',          desc: 'Home'        },
  { path: '/about',       label: 'Origin Coordinates', desc: 'About'       },
  { path: '/projects',    label: 'Probes & Payloads',  desc: 'Projects'    },
  { path: '/skills',      label: 'Instruments',        desc: 'Skills'      },
  { path: '/work',        label: 'Mission Log',        desc: 'Work'        },
  { path: '/case-studies',label: 'Flight Recordings',  desc: 'Case Studies'},
  { path: '/articles',    label: 'Transmissions',      desc: 'Articles'    },
  { path: '/testimonials',label: 'Ground Control Says',desc: 'Testimonials'},
  { path: '/contact',     label: 'Open Channel',       desc: 'Contact'     },
]
To add a new route, append an object to the array:
{ path: '/lab', label: 'Experimental Module', desc: 'Lab' }
To rename a destination, change the label (the large heading displayed in the overlay) and/or the desc (the small monospace descriptor shown above it). The path value must match the React Router route definition in App.jsx.
Removing the root / entry will break the Star Chart logo link, which navigates to "/" unconditionally. Always keep at least one entry with path: '/'.

Active State Styling

Navigation uses React Router’s <NavLink> for each overlay link. The className prop receives a callback that is called with { isActive } — a boolean that is true when the current URL matches the link’s path. The active link receives text-aurora-teal; all others receive text-star-white:
className={({ isActive }) =>
  `group relative inline-block interactive py-2 ${
    isActive ? 'text-aurora-teal' : 'text-star-white'
  }`
}
This means the active destination glows in teal at all times while the overlay is open, providing instant spatial orientation — particularly useful when arriving at a page directly via URL rather than through the overlay itself.

Easter Egg

A small CTRL+ALT+ASCEND label is pinned absolute bottom-8 at the base of the overlay. It fades in after a 0.5s delay — after all the nav links have settled — and is styled in the muted text-star-dim monospace typeface. It carries no interactivity; it is purely a piece of cosmetic lore for visitors who pause long enough to notice it.

Build docs developers (and LLMs) love