Skip to main content

Documentation Index

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

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

The Projects page — titled “Incantations” — presents each portfolio piece as a physical card that flips in three dimensions when hovered. The front of every card displays an arcane SVG sigil with an interactive radial glow that follows the mouse cursor. The back reveals the project name (written as a Roman numeral), a plain-language description, a row of technology badges, and a link to inspect the work. Cards stagger into view on page load so the grid assembles itself sequentially rather than all at once.

Project Cards

3D Flip Mechanic

Each card is built from three nested divs:
  1. Container — sets perspective on the CSS context so child transforms look three-dimensional.
  2. Inner wrapper — has transform-style: preserve-3d and transitions rotateY from 0deg to 180deg on :hover. This is the element that physically rotates.
  3. Front and back faces — both are position: absolute, full-size, and set to backface-visibility: hidden. The back face starts pre-rotated at rotateY(180deg) so it is hidden at rest and visible after the flip.
// Simplified card structure
<div style={{ perspective: "1000px" }}>
  <div
    className="relative transition-transform duration-700"
    style={{
      transformStyle: "preserve-3d",
      transform: isFlipped ? "rotateY(180deg)" : "rotateY(0deg)",
    }}
    onMouseEnter={() => setIsFlipped(true)}
    onMouseLeave={() => setIsFlipped(false)}
  >
    {/* Front face */}
    <div style={{ backfaceVisibility: "hidden" }}>
      {/* arcane SVG symbol */}
    </div>

    {/* Back face */}
    <div
      style={{
        backfaceVisibility: "hidden",
        transform: "rotateY(180deg)",
      }}
    >
      {/* project details */}
    </div>
  </div>
</div>

Front Face — Arcane Symbol and Radial Glow

The front of each card renders an SVG arcane sigil composed of:
  • An outer circle that frames the symbol
  • Two triangles pointing in opposite directions, overlapping to form a hexagram-like shape
  • A smaller inner circle at the centre
The card also listens to onMouseMove events. As the cursor moves across the front face, its position is tracked relative to the card’s bounding box and used to paint a CSS radial-gradient highlight that follows the pointer in real time:
const handleMouseMove = (e) => {
  const rect = e.currentTarget.getBoundingClientRect();
  const x = e.clientX - rect.left;
  const y = e.clientY - rect.top;
  setGlowPosition({ x, y });
};

// Applied as an inline style overlay on the front face
background: `radial-gradient(
  circle at ${glowPosition.x}px ${glowPosition.y}px,
  rgba(45, 212, 191, 0.15),
  transparent 60%
)`
Once flipped, the card shows:
  • Roman numeral (I, II, III, or IV) as a large decorative heading
  • Project title in full
  • Plain-language description of what the project does
  • Tech stack badges — each technology name rendered as a small pill
  • An “Inspect Spell →” anchor that points to the project URL

Card Entrance Animation

Cards are animated in with Framer Motion. Each card starts shifted 50 px below its final position and invisible, then rises and fades in. The delay is proportional to the card’s index in the array so they arrive one after another:
<motion.div
  initial={{ opacity: 0, y: 50 }}
  animate={{ opacity: 1, y: 0 }}
  transition={{ duration: 0.8, delay: index * 0.2, ease: "easeOut" }}
>
  {/* card */}
</motion.div>
Card indexEntrance delay
00.0 s
10.2 s
20.4 s
30.6 s

Project Data

All four projects are stored in a single array inside the ProjectsPage component. Each entry carries an id, display title, short numeral, description, tech array, and a link:
const projects = [
  {
    id: 1,
    title: "The Alchemist's Ledger",
    numeral: "I",
    description:
      "A full-stack financial dashboard conjured with React, Node.js, and PostgreSQL. " +
      "Features real-time market scrying and automated portfolio balancing.",
    tech: ["React", "Node.js", "PostgreSQL", "WebSockets"],
    link: "#",
  },
  {
    id: 2,
    title: "Grimoire.md",
    numeral: "II",
    description:
      "A markdown editor for modern spellcasters. Includes live preview, syntax " +
      "highlighting for 40+ languages, and cloud synchronization.",
    tech: ["TypeScript", "Next.js", "Tailwind", "Prisma"],
    link: "#",
  },
  {
    id: 3,
    title: "Astral Projection API",
    numeral: "III",
    description:
      "A globally distributed GraphQL API serving geospatial data with sub-50ms " +
      "latency across 12 regions.",
    tech: ["GraphQL", "Go", "Redis", "Docker"],
    link: "#",
  },
  {
    id: 4,
    title: "Familiar Tracker",
    numeral: "IV",
    description:
      "IoT dashboard for tracking pet familiars. Integrates with GPS collars to " +
      "provide real-time location and activity metrics.",
    tech: ["React Native", "Firebase", "IoT", "Maps"],
    link: "#",
  },
];

Adding a Project

1

Locate the projects array in ProjectsPage

Open the ProjectsPage component and find the projects array defined near the top of the component. The array contains four object literals matching the structure above.
2

Append a new project object

Add a fifth object at the end of the array, incrementing id to 5 and choosing the next Roman numeral (V) for numeral. Fill in the remaining fields:
{
  id: 5,
  title: "Your Project Title",
  numeral: "V",
  description: "A concise description of what the project does and why it matters.",
  tech: ["Tech A", "Tech B", "Tech C"],
  link: "https://github.com/yourname/your-project",
}
The card grid uses CSS to auto-flow new entries, so no layout changes are needed — the fifth card will appear after the existing four.
Replace link: "#" with the actual URL of your deployed project or repository. The “Inspect Spell →” anchor on the card back uses this value directly as its href, so a placeholder "#" will keep the user on the same page instead of navigating anywhere.

Build docs developers (and LLMs) love