Skip to main content

Documentation Index

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

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

The Layout component is the structural backbone of Mystery Haunting. It wraps every page of the portfolio with a fixed sidebar navigation on the left and a main content area on the right. Beyond structure, it mounts all ambient GlobalEffects overlays so they appear on every route, and orchestrates a 3D rotateY “book-flip” page transition using Framer Motion’s AnimatePresence whenever the active route changes. The sidebar is a fixed-position <nav> element with a width of w-64, anchored to the left edge of the viewport. It is divided into three vertical zones:

Logo Area

At the top of the sidebar sits a GhostIcon component alongside the site’s brand heading rendered in font-spooky. The heading text is MORTAL — a tongue-in-cheek label that identifies the site owner as a mortal soul among haunted things. Below the logo, the sidebar renders a list of nine route links sourced from the internal nav array. Each link carries a path and a spooky themed label that replaces conventional navigation language with in-world location names.
PathLabel
/The Foyer
/aboutThe Attic
/projectsThe Graveyard
/skillsThe Lab
/workPrevious Hauntings
/case-studiesAutopsy Reports
/blogForbidden Library
/testimonialsEye-Witnesses
/contactSéance Circle
Active link styles — When a link matches the current route, it receives the ghost-teal text color and a text-glow-teal shadow effect. An active indicator dot (filled, ghost-teal with a glow box-shadow) appears beside the label. Inactive link styles — Non-active links render in bone/60 opacity and transition to the pumpkin accent color on hover. Their indicator dot is transparent by default, showing a pumpkin-colored border on hover. At the bottom of the sidebar, a small footer section displays two lines of ambient status text:
  • Status: Currently Haunting
  • Caffeine: Depleted
The full route table is defined in the nav array (Jp in the compiled bundle). Each entry supplies the path consumed by the router and the label rendered in the sidebar link list.

Page Transitions

Page changes are animated using Framer Motion’s AnimatePresence with mode="wait", which ensures the exiting page fully completes its exit animation before the entering page begins. The motion.div wrapping each page’s content applies a 3D rotateY book-flip — the page appears to turn like a physical book page around a vertical axis.
const pageVariants = {
  initial: { opacity: 0, rotateY: -90, transformPerspective: 1200, transformOrigin: 'left center' },
  in: { opacity: 1, rotateY: 0, transition: { duration: 0.8, ease: 'easeOut' } },
  out: { opacity: 0, rotateY: 90, transformOrigin: 'right center', transition: { duration: 0.8, ease: 'easeIn' } }
};
The <main> element has perspective-[1200px] applied as a Tailwind arbitrary value so the browser renders the 3D transform correctly. Without this perspective context the rotateY animation would appear flat.

Layout Structure

The following diagram shows the DOM hierarchy of the Layout component at runtime:
┌─────────────────────────────────────────────┐
│  div.min-h-screen (bg-spooky-black)          │
│  ┌────────────┐  ┌───────────────────────┐  │
│  │  <nav>     │  │  <main>               │  │
│  │  w-64      │  │  flex-1 h-screen      │  │
│  │  sidebar   │  │  perspective-1200px   │  │
│  │            │  │  AnimatePresence      │  │
│  │  Logo      │  │  motion.div           │  │
│  │  Nav Links │  │  (page content)       │  │
│  │  Footer    │  │                       │  │
│  └────────────┘  └───────────────────────┘  │
└─────────────────────────────────────────────┘
GlobalEffects components are rendered inside the outer wrapper div, before the <nav>, so they overlay the entire viewport. This placement ensures the ambient effects (fireflies, fog, lightning, cursor trail) sit beneath all interactive UI elements and appear consistently across every page.

Build docs developers (and LLMs) love