Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/apursley2012/nightshade/llms.txt

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

The Summonings page (/projects) renders the ProjectsPage component — a full-screen orbital display where four project cards circle a bubbling cauldron SVG. Hovering any card shifts the cauldron’s ambient glow to that project’s accent color; clicking expands the card in-place to reveal the project description and tech stack.

Route

/projectsProjectsPage (Be in main.js)

Page Structure

The page is divided into two layers stacked inside a max-w-4xl container at h-[600px]:
  1. Central cauldron — an absolutely positioned SVG and glow layer that reacts to the hovered project.
  2. Orbital cards — four motion.div elements arranged at 90° intervals around a 220 px orbit radius.

Cauldron Glow

A blurred motion.div behind the cauldron SVG transitions its backgroundColor to the hovered project’s color value. While a project is hovered the glow pulses with a looping scale: [1, 1.2, 1] animation. When nothing is hovered the opacity drops to 0.1. Bubble particles are rendered inside the cauldron using AnimatePresence. While a project is hovered, two motion.circle elements animate upward (y: -20 and y: -15) and fade out on repeat, colored to match the active project.

Orbital Cards

Each card is positioned using Framer Motion’s x and y props, computed from its index angle:
const h = d * (360 / T.length) * (Math.PI / 180);
const m = 220;
const x = Math.cos(h) * m;
const y = Math.sin(h) * m;
Cards animate to x: 0, y: 0, scale: 1.2 when clicked (expanded state), and spring back to their orbit position on a second click. The AnimatePresence block inside each card toggles the description and stack tags with a height: 0 → "auto" animation.

Project Data

The four projects are defined as a top-level constant in main.js:
const projects = [
  {
    id: 1,
    title: "Aetherial UI",
    type: "Component Library",
    color: "#0d9488",
    desc: "A collection of accessible, headless components summoned for modern React applications. Built with Radix and Tailwind.",
    stack: ["React", "TypeScript", "Tailwind"],
  },
  {
    id: 2,
    title: "Nether-Sync",
    type: "Realtime Engine",
    color: "#581c87",
    desc: "A WebSocket-based state synchronization engine that keeps clients in perfect harmony across the void.",
    stack: ["Node.js", "Socket.io", "Redis"],
  },
  {
    id: 3,
    title: "Specter Analytics",
    type: "Dashboard",
    color: "#14b8a6",
    desc: "Invisible tracking for user behavior. Gathers insights without disturbing the mortal realm (privacy-first).",
    stack: ["Next.js", "PostgreSQL", "Prisma"],
  },
  {
    id: 4,
    title: "Hex-Breaker",
    type: "Testing Suite",
    color: "#f59e0b",
    desc: "An automated end-to-end testing framework designed to banish regressions before they reach production.",
    stack: ["Playwright", "Vitest", "CI/CD"],
  },
];
Each color drives the cauldron glow, the expanded card’s title color, and the border highlight shadow-[0_0_30px_rgba(...)].

Interaction States

Cards sit at their computed (x, y) position on the 220 px orbit. The card border is border-witch-plum/30. A small "Click to unfurl" hint appears in amber below the card type label.
onMouseEnter sets hoveredId state. The cauldron glow shifts color and begins its pulse loop. Bubble particles (two per hover) animate out of the cauldron mouth in the project’s color. The card border changes to border-witch-turquoise.
onClick toggles expandedId. When expanded, the card animates to x: 0, y: 0 (center of the container) and scale: 1.2. AnimatePresence fades in the description paragraph and the stack tag row. The card border becomes border-witch-amber with an amber drop shadow. Clicking again collapses and re-orbits.

Customization

Adding a New Project

Append an entry to the projects array. The orbit math automatically redistributes all cards:
{
  id: 5,
  title: "Wraith Cache",
  type: "CDN Layer",
  color: "#7c3aed",
  desc: "An edge-caching layer that intercepts requests before they ever reach the origin server.",
  stack: ["Cloudflare Workers", "Hono", "KV"],
},
With five projects the cards space at 72° intervals. The orbit radius is fixed at 220 px via the m constant — if you add many projects, increase m in the orbit calculation to avoid card overlap.

Changing Colors

Each project’s color is a plain hex string. It is applied to three places simultaneously:
  • The cauldron glow backgroundColor and bubble fill
  • The expanded card’s h3 title via inline style={{ color: project.color }}
  • The amber-like shadow on the expanded card border
Pick any value that meets contrast requirements against the dark parchment background.

Changing Stack Tags

Stack tags render as small pill spans styled with bg-witch-dark border-witch-plum/50 text-witch-turquoise. They accept any string — keep them short (under 15 characters) so they wrap cleanly inside the w-64 card.

Build docs developers (and LLMs) love