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.

DoorPanel presents each work history entry as a full-height haunted wooden door. The door face shows the company name and a subtle “Click to open” prompt. Clicking swings the door open — a spring-animated 3D rotateY transform — exposing the job details (role, period, and description) on the dark wall behind it. Clicking again closes it.

Usage

DoorPanel takes a job object and its position index. The Work page in assets/main.js maps over the workHistory array and wraps each door in a Framer Motion entrance animation:
import { DoorPanel } from '../components/DoorPanel';

<DoorPanel job={job} index={0} />
The full layout in assets/main.js:
// assets/main.js — Work page
{workHistory.map((job, index) => (
  <motion.div
    key={job.company}
    initial={{ opacity: 0, x: -50 }}
    animate={{ opacity: 1, x: 0 }}
    transition={{ delay: index * 0.2 }}
    className="flex-1"
  >
    <DoorPanel job={job} index={index} />
  </motion.div>
))}

Props

job.company
string
required
The employer name. Displayed on the front face of the door inside a dark plaque, visible before the door is opened.
job.role
string
required
The job title. Revealed on the wall behind the door when the user clicks it open. Styled in the Spooky font with pumpkin-orange color.
job.period
string
required
The employment timeframe, e.g. "2022 - Present". Displayed beneath the role in monospace ghost text once the door is open.
job.description
string
required
A short paragraph describing responsibilities and achievements. Displayed as body copy on the revealed wall panel.
index
number
required
Zero-based position in the work history array. Used by the parent to stagger entrance animations with a delay of index * 0.2 seconds.

Open / Close Interaction

The component holds an isOpen boolean in local state. Clicking anywhere on the door panel toggles it. The door itself is a motion.div with transformOrigin: 'left' so it pivots from its hinge edge, exactly like a real door:
const [isOpen, setIsOpen] = useState(false);

<motion.div
  style={{ transformOrigin: 'left' }}
  animate={{ rotateY: isOpen ? -105 : 0 }}
  transition={{ duration: 0.8, type: 'spring', bounce: 0.2 }}
  onClick={() => setIsOpen(!isOpen)}
>
At rotateY: -105, the door swings past 90° so its inner edge passes the frame, giving it a convincing physical feel. The bounce: 0.2 spring setting adds a slight overshoot and settle.
The “Click to open” hint is wrapped in Framer Motion’s AnimatePresence and fades out when the door opens. It reappears with initial={{ opacity: 0 }} animate={{ opacity: 1 }} whenever the door closes again.

Layout Structure

Each DoorPanel is 500px tall with perspective-1000 applied to its wrapper. Three layers stack inside:
Layerz-indexPurpose
Back wallz-0Dark panel with a diagonal crosshatch pattern that holds the role/period/description
Door borderz-20Decorative wood-colored border with pointer-events-none
Door facez-10Animated wooden door that rotates open on click
The back wall uses an inline repeating-linear-gradient to render a subtle woven-texture pattern at 5% opacity, adding depth when the door is open.

Work History Data

Update the workHistory array in assets/main.js to reflect your own employment history:
// assets/main.js
const workHistory = [
  {
    company: 'Phantom Tech',
    role: 'Senior Frontend Engineer',
    period: '2022 - Present',
    description:
      'Leading a team of ghouls to build high-performance React applications. ' +
      'Reduced load times by 40% and implemented a spooky new design system.',
  },
  {
    company: 'Goblin Corp',
    role: 'Frontend Developer',
    period: '2020 - 2022',
    description:
      'Maintained legacy codebases that refused to die. Migrated monolithic ' +
      'jQuery apps to modern React architectures.',
  },
  {
    company: 'WebWeavers',
    role: 'Web Developer',
    period: '2018 - 2020',
    description:
      'Spun intricate webs of HTML/CSS for local businesses. Specialized in ' +
      'responsive design and accessibility.',
  },
];

Customization

Change the door swing angle — The default open angle is -105deg. Reduce it toward -90 for a door that opens flush to the wall, or increase it beyond -105 for a wider swing:
animate={{ rotateY: isOpen ? -90 : 0 }}  // flush open
animate={{ rotateY: isOpen ? -120 : 0 }} // extra-wide swing
Adjust the spring feel — Increase bounce for a bouncier settle, or set it to 0 for a critically-damped close:
transition={{ duration: 0.8, type: 'spring', bounce: 0 }}   // smooth stop
transition={{ duration: 0.8, type: 'spring', bounce: 0.4 }} // bouncy
Add more work entries — Each additional object in workHistory creates another door. The Work page renders them in a horizontal flex row on desktop and a column on mobile. With more than four entries, consider wrapping in a scrollable container.
Keep description values under three sentences. The content panel behind the door is 500px tall; longer descriptions will overflow the visible area on smaller screens.

Build docs developers (and LLMs) love