Skip to main content

Documentation Index

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

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

SwirlNav is the fixed navigation bar rendered on every page of the portfolio. It reads the current route from React Router’s useLocation hook and uses a Framer Motion layoutId pill to smoothly animate between active navigation items as the user moves between pages — no jarring jumps, just a fluid spring that chases the active link. The nine portfolio routes are defined as a plain array of { path, label } objects at the top of components/SwirlNav.js:
const routes = [
  { path: '/',            label: 'The Swirl' },
  { path: '/about',       label: 'Out of the Dye Bath' },
  { path: '/projects',    label: 'The Color Wheel' },
  { path: '/skills',      label: 'Pigments' },
  { path: '/work',        label: 'The Long Strip' },
  { path: '/case-studies',label: 'Deep Dyes' },
  { path: '/blog',        label: 'Field Notes' },
  { path: '/contact',     label: 'Drop a Note' },
  { path: '/testimonials',label: 'Kind Words' },
];
Each label is the display text shown in the navigation bar. Each path corresponds to the React Router route registered in the app.

Desktop behavior

On wide viewports SwirlNav renders all nine links in a horizontal pill bar. The active route is highlighted with a bg-teal-100 rounded-full background pill. This pill is a Framer Motion motion.span with layoutId: 'nav-pill', which means Framer Motion automatically animates it from its previous position to the new active item whenever the route changes. The spring physics that drive the animation are:
PropertyValue
typespring
stiffness300
damping30
A decorative tie-dye background layer sits behind the link list at 20% opacity using the .tie-dye-bg CSS class. The entire nav bar is position: fixed, z-index: 50, and uses backdrop-filter: blur so it remains legible over any page background.

Mobile behavior

On narrow viewports the link list is hidden and a hamburger button takes its place. The icon toggles between Lucide’s Menu and X icons depending on whether the menu is open. Tapping the button shows a full-width dropdown menu that animates in with Framer Motion AnimatePresence:
Stateopacityy
Enter (initial)0-20px
Visible (animate)10px
Exit0
Tapping any link in the mobile menu calls the menu-close handler before React Router navigates, so the dropdown always collapses cleanly on route change.

Customizing labels

To change a navigation label, open components/SwirlNav.js and edit the label field of the relevant entry in the routes array. The label is purely display text — it has no effect on routing. To change where a link points, edit the path field. The value must match the route string registered in the React Router configuration in assets/main.js. Mismatched paths will cause the active-pill highlight to fail silently on that route.
The routes array is defined in the source file as the variable used internally by the component (named Mo in the compiled output). When editing the compiled .js file directly, search for the array literal containing 'The Swirl' to locate it.

Accessibility notes

The cursor trail (DyeCursor) and the tie-dye background decoration are both rendered with pointer-events: none, so they never obscure or intercept interaction with navigation links. All links are standard anchor elements rendered by React Router’s Link component, which means they respond to keyboard focus, support Tab navigation, and fire normal click events. Screen readers will announce them as links with the label text from the routes array.

Build docs developers (and LLMs) love