Skip to main content

Documentation Index

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

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

The Projects page presents completed work as a collection of spell-cards under the heading “Spells Cast”. Each project is a <TarotCard type="project"> that starts face-down and flips on hover to reveal the project name, a one-line description, its tech ingredients, and a link to view the work.

What’s on This Page

Heading block: The heading animates in from above (initial: { opacity: 0, y: -20 }animate: { opacity: 1, y: 0 }):
Spells Cast
A collection of successful rituals and bindings.
Below the heading, four cards are arranged in a flex-wrap grid that flows into multiple rows on smaller screens. The container uses justify-center gap-8 md:gap-12. The four project cards:
TitleSubtitleIngredients
Grimoire.jsDocumentation GeneratorReact, AST Parsing, Tailwind
Soul CatcherAnalytics DashboardNext.js, D3.js, PostgreSQL
Alchemist’s ForgeComponent LibraryTypeScript, Radix UI, Framer Motion
Divination APIPredictive SearchRust, Redis, Cloudflare Workers
Card face (before hover): A dark panel with a border-violet/40 border, a subtle radial gradient from violet/10 to transparent, and a centered amber diamond symbol with nested rotated borders. The card type label (“project”) is shown in muted violet below the diamond. Card back (after hover/click): The flipped face shows:
  • Title in font-serif text-xl text-bone
  • Subtitle in amber font-accent text-sm
  • Description text in text-bone/80
  • Ingredients as small pill badges with bg-violet/20 border-violet/30 styling
  • A “Speak Incantation →” link in amber that opens the project URL in a new tab

Key Interactions

  • Spring-physics entrance — Each card wrapper uses initial: { opacity: 0, scale: 0.8, rotate: -10 }animate: { opacity: 1, scale: 1, rotate: 0 } with type: 'spring', stiffness: 100. Cards are staggered with delay: i * 0.2 (0 s, 0.2 s, 0.4 s, 0.6 s).
  • Flip on hover — Hovering a card triggers a rotateY flip to reveal the back face.
  • Link isolation — The “Speak Incantation →” <a> tag calls e.stopPropagation() so clicking the link does not re-flip the card.

Customizing

Replace the project data array in src/pages/Projects.jsx with your own work. Each object maps directly to <TarotCard> props:
// src/pages/Projects.jsx
const projects = [
  {
    title: 'Grimoire.js',
    subtitle: 'Documentation Generator',
    description:
      'A tool that parses your chaotic codebase and generates beautiful, ' +
      'readable documentation that looks like ancient manuscripts. ' +
      'Includes automated dependency graphing.',
    ingredients: ['React', 'AST Parsing', 'Tailwind'],
    link: '#',
  },
  {
    title: 'Soul Catcher',
    subtitle: 'Analytics Dashboard',
    description:
      'Privacy-first analytics that tracks user intent rather than identity. ' +
      'Visualizes traffic as flowing ethereal energy streams across a dark map.',
    ingredients: ['Next.js', 'D3.js', 'PostgreSQL'],
    link: '#',
  },
  {
    title: "Alchemist's Forge",
    subtitle: 'Component Library',
    description:
      'A highly accessible, headless component library for building complex ' +
      'interfaces. Focuses on keyboard navigation and screen reader support.',
    ingredients: ['TypeScript', 'Radix UI', 'Framer Motion'],
    link: '#',
  },
  {
    title: 'Divination API',
    subtitle: 'Predictive Search',
    description:
      'A fast, edge-hosted search API that predicts what users are looking ' +
      'for before they finish typing, using lightweight ML models.',
    ingredients: ['Rust', 'Redis', 'Cloudflare Workers'],
    link: '#',
  },
];
Then render them in a loop with staggered delays:
<div className="flex flex-wrap justify-center gap-8 md:gap-12">
  {projects.map((project, index) => (
    <motion.div
      key={project.title}
      initial={{ opacity: 0, scale: 0.8, rotate: -10 }}
      animate={{ opacity: 1, scale: 1, rotate: 0 }}
      transition={{ delay: index * 0.2, type: 'spring', stiffness: 100 }}
    >
      <TarotCard
        type="project"
        title={project.title}
        subtitle={project.subtitle}
        description={project.description}
        ingredients={project.ingredients}
        link={project.link}
      />
    </motion.div>
  ))}
</div>
The link prop is optional. If you omit it, the “Speak Incantation →” footer row is hidden entirely — useful for work-in-progress or confidential projects.
The ingredients prop renders as pill badges on the card back. Keep each ingredient label short (one or two words) so the badges wrap cleanly within the card’s fixed width. Long labels like "Framer Motion" work fine; full sentences will overflow.

Build docs developers (and LLMs) love