Skip to main content

Documentation Index

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

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

Nav turns the site’s top navigation bar into a graveyard fence. Each link is shaped like a tombstone — rounded top, flat base — and animates upward when hovered or active, giving the impression of tombstones rising from the ground. The component is rendered inside the sticky <header> in Layout. The full set of routes is declared as a static constant inside the component:
const LINKS = [
  { path: '/',             label: 'Home' },
  { path: '/about',        label: 'About' },
  { path: '/projects',     label: 'Projects' },
  { path: '/skills',       label: 'Skills' },
  { path: '/work',         label: 'Work' },
  { path: '/case-studies', label: 'Cases' },
  { path: '/articles',     label: 'Articles' },
  { path: '/testimonials', label: 'Praise' },
  { path: '/contact',      label: 'Contact' },
];
Each entry maps directly to a <Route> defined in main.js.

Tombstone shape and styling

Every nav item is a w-16 md:w-24 h-24 md:h-32 rounded-t-full <div>, which produces the characteristic tombstone silhouette across all viewport sizes. The label text sits centred inside.
StateClasses applied
Defaultbg-haunt-tombstone border-t-4 border-x-4 border-haunt-tombstoneDark text-haunt-bone
Hoverhover:bg-haunt-tombstoneDark hover:-translate-y-2
Active routebg-haunt-tombstoneDark border-haunt-moon/50 text-haunt-moon -translate-y-4
The active tombstone is lifted 16 px (-translate-y-4) and glows with a teal border tint (border-haunt-moon/50), making the current page immediately recognisable.

Framer Motion opacity animation

A motion.div wraps the glow gradient overlay inside each tombstone. When a link becomes the active route, the motion.div animates its opacity from 0 to 1, producing a subtle fade-in on the teal highlight. This prevents the active state from appearing abruptly on navigation. initial={false} skips the animation on the first render so the correct active state is shown immediately on page load.
<motion.div
  className="absolute inset-0 rounded-t-full opacity-0 group-hover:opacity-100 bg-gradient-to-t from-transparent to-haunt-moon/10 pointer-events-none"
  initial={false}
  animate={{ opacity: isActive ? 1 : 0 }}
/>
The outer <nav> element carries w-full py-8 px-4 overflow-x-auto, which enables horizontal scrolling when the tombstone row exceeds the viewport width. The inner <ul> uses flex justify-center items-end gap-2 md:gap-4 min-w-max mx-auto to keep all tombstones on one line and centred.
On mobile viewports the tombstone row can exceed the screen width. The overflow-x-auto class on the <nav> element enables horizontal scrolling so all nine links remain accessible without wrapping or truncation. No JavaScript is needed — it is pure CSS scrolling behaviour.

Adding a new nav item

1

Add an entry to LINKS

Open components/layout/Nav.js and append a new object to the LINKS array:
{ path: '/uses', label: 'Uses' },
2

Add a matching Route in main.js

Open assets/main.js and add a <Route> inside the root layout route:
<Route path="uses" element={<UsesPage />} />
The path value must match the path field you added to LINKS (without the leading /).
3

Create the page component

Create the corresponding page component and import it in main.js. The new tombstone will appear automatically in the nav bar and will receive the active lift animation when its route is visited.

Source location

components/layout/Nav.js

Build docs developers (and LLMs) love