Skip to main content

Documentation Index

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

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

The Projects page lays out your portfolio work as a responsive two-column card grid where every entry is wrapped in a WindowFrame component — giving each project its own desktop-window chrome complete with a title bar, control buttons, and inset borders. Cards have a slight initial tilt (set via the rotation field) and spring back to straight on hover, with a glowing gradient halo behind each window for extra retro flair. On narrow viewports the grid collapses to a single column.

Project Card Data Structure

Each project is represented by a plain JavaScript object with the following shape:
FieldTypeDescription
titlestringProject name — used as the WindowFrame title bar (appended .exe)
descstringOne- or two-sentence summary of what the project does
techstringComma-separated technology names shown in a yellow “TECH STACK” label
imgstringURL to a preview/screenshot image displayed at the top of the card
rotationnumberInitial CSS rotation in degrees (e.g. -2, 3) for the tilt effect
const projects = [
  {
    title: 'E-Commerce 2.0',
    desc: 'A fully responsive shopping cart built with React and Redux. It actually works!',
    tech: 'React, Node.js, Stripe',
    img: 'https://example.com/screenshot.jpg',
    rotation: -2,
  },
  // ...
];
The built-in demo projects are: E-Commerce 2.0, Crypto Dashboard, AI Chatbot, and Retro Portfolio.

Single Card JSX

Each entry in projects is mapped to a motion.div wrapper that holds a WindowFrame. A simplified version of the render logic:
{projects.map((project, i) => (
  <motion.div
    key={i}
    initial={{ rotate: project.rotation }}
    whileHover={{ scale: 1.05, rotate: 0, zIndex: 10 }}
    transition={{ type: 'spring', stiffness: 300 }}
    className="relative"
  >
    {/* Glow halo */}
    <div className="absolute -inset-2 bg-gradient-to-r from-retro-pink via-retro-cyan to-retro-lime opacity-50 blur-sm animate-pulse rounded-lg" />

    <WindowFrame title={`${project.title}.exe`} className="relative z-10 h-full">
      <div className="flex flex-col h-full">
        <div className="border-2 border-black p-1 bg-black mb-3">
          <img src={project.img} alt={project.title} className="w-full h-48 object-cover" />
        </div>
        <h3 className="font-impact text-2xl text-retro-blue mb-2">{project.title}</h3>
        <p className="font-times text-base mb-4 flex-grow">{project.desc}</p>
        <div className="bg-yellow-100 border border-yellow-400 p-2 font-pixel text-[8px]">
          TECH STACK: {project.tech}
        </div>
        <div className="mt-4 flex justify-end gap-2">
          <button className="...">View Source</button>
          <button className="...">Launch</button>
        </div>
      </div>
    </WindowFrame>
  </motion.div>
))}
The WindowFrame component handles all the retro chrome (title bar, close/minimize/maximize buttons, border inset). The card body only needs to supply the content inside.
The View Source and Launch buttons are rendered as <button> elements. In the current source they have no onClick handler — wire them up to your repository URL and live deployment URL as needed.

Route Registration

The Projects component (Fp in the compiled bundle) is mounted at /projects:
// Inside <Routes>:
<Route path="/projects" element={<Projects />} />

Adding a New Project

Open the Projects component source and append a new object to the projects array:
const projects = [
  // ...existing entries...
  {
    title: 'My New Project',
    desc: 'A real-time collaborative whiteboard built with WebSockets.',
    tech: 'React, Socket.io, Canvas API',
    img: 'https://example.com/new-project.jpg',
    rotation: 1,
  },
];
The new card will be rendered automatically — no changes to the JSX template are needed. The grid reflows to accommodate the additional card.

Removing a Project

Delete the corresponding object from the projects array. The grid will reflow and close the gap left by the removed card.
Keep rotation values small (between -4 and 4 degrees) for the best tilt effect. Values outside this range can make cards look skewed rather than charmingly tilted.

Build docs developers (and LLMs) love