Skip to main content

Documentation Index

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

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

The Projects page presents the developer’s portfolio work as a graveyard of tombstones. Each project gets its own Tombstone card that rises up from the ground with a staggered Framer Motion entrance. Projects that are actively maintained stand tall with full colour and live links; archived or abandoned projects are rendered with muted styling and a “RIP” epitaph to indicate they have been laid to rest.
Route: /projects
Static HTML: pages/Projects.html
Page function: D() in assets/main.js
Data array: M in assets/main.js

What the page displays

ElementContent
Section heading (h1)The Graveyard
SubtitleSkeletons in the closet and things that go bump in the night.
Layoutgrid-cols-1 md:grid-cols-2 lg:grid-cols-3 — responsive 3-column grid
Card componentTombstone — one per project

Projects data

The five projects are stored in the M array in assets/main.js.
TitleEpitaphTech stackStatusGitHubLive link
Specter UIA hauntingly beautiful component library.React, Tailwind, Framer✅ Alive
Crypt TrackerKeeping tabs on your digital assets before they vanish.Next.js, TypeScript, Prisma✅ Alive
PoltergeistAutomated testing that goes bump in the night.Node.js, Jest, Puppeteer✅ Alive
Vampire CRMSucked the life out of me. RIP 2021-2022.Vue, Firebase❌ Dead
Zombie AppIt keeps coming back from the dead. Legacy code.jQuery, PHP❌ Dead

Raw data structure

// assets/main.js — array M
const M = [
  {
    title: "Specter UI",
    epitaph: "A hauntingly beautiful component library.",
    tech: ["React", "Tailwind", "Framer"],
    isAlive: true,
    github: "#",
    link: "#",
  },
  {
    title: "Crypt Tracker",
    epitaph: "Keeping tabs on your digital assets before they vanish.",
    tech: ["Next.js", "TypeScript", "Prisma"],
    isAlive: true,
    github: "#",
    link: "#",
  },
  {
    title: "Poltergeist",
    epitaph: "Automated testing that goes bump in the night.",
    tech: ["Node.js", "Jest", "Puppeteer"],
    isAlive: true,
    github: "#",
  },
  {
    title: "Vampire CRM",
    epitaph: "Sucked the life out of me. RIP 2021-2022.",
    tech: ["Vue", "Firebase"],
    isAlive: false,
    github: "#",
  },
  {
    title: "Zombie App",
    epitaph: "It keeps coming back from the dead. Legacy code.",
    tech: ["jQuery", "PHP"],
    isAlive: false,
  },
];

Halloween-themed concept

The graveyard metaphor maps naturally to a project portfolio: every project is a “tombstone”, and whether it is alive or dead determines how it is rendered. Active projects are vibrant, fully clickable stones; dead projects are dimmed with muted styles and their epitaph field doubles as a RIP inscription, giving even abandoned work a sense of dark humour rather than simply hiding it.

Dead vs. alive rendering

The isAlive boolean on each project object controls how the Tombstone component renders:
  • isAlive: true — Full-colour tombstone, technology badges are highlighted, GitHub and live-link icons are active.
  • isAlive: false — Muted / desaturated tombstone, no live-link icon rendered, and the epitaph is treated as an RIP inscription.

Framer Motion animations

Each tombstone rises up from below with a staggered delay based on its array index.
// Per-card wrapper (motion.div)
{
  initial: { opacity: 0, y: 50 },
  animate: { opacity: 1, y: 0 },
  transition: { delay: index * 0.1 }
}
The header block (heading + subtitle) uses a separate entrance that drops from above:
// Header motion.div
{
  initial: { y: -20, opacity: 0 },
  animate: { y: 0,   opacity: 1 }
}

How to customise

1

Add a new project

Append a new object to the M array in assets/main.js. Set isAlive: true to give it full styling, or isAlive: false to render it as a dead project. Omit the link key if there is no live URL; omit github if the repo is private.
2

Edit an existing project

Find the object by title in the M array and update any field — epitaph, tech, github, or link.
3

Archive a live project

Set isAlive: false on the relevant object. Update the epitaph to an RIP message that explains what happened (e.g. "Deprecated in favour of Specter UI v2.").
4

Reorder projects

The grid renders in M’s array order. Drag objects within the array to change which cards appear first or which column they fall into.
The stagger delay is index * 0.1 seconds. With 5 cards the last card waits 0.4 s before animating in. If you add many more projects, consider reducing the multiplier (e.g. index * 0.05) so the last card doesn’t wait too long.

Build docs developers (and LLMs) love