The Foyer is the first thing visitors encounter when they arrive at Mystery Haunting. It sets the tone immediately: a darkened viewport dominated by a haunted house silhouette, a pulsing ghost-teal orb, and a welcome message that materializes one letter at a time. The page exists to make an impression before anything else — it is atmosphere first, portfolio second. A single call-to-action button invites the visitor deeper into the experience.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.
Visual Overview
The background is anchored by a full-width haunted house silhouette rendered as an SVG, positioned at the bottom of the viewport with jagged rooflines and darkened windows. Overlaid on the scene is a large ghost-teal glowing orb — a radial gradient that pulses softly and casts an eerie ambient light across the silhouette below. Scattered across the screen are floating ghost icons, each drifting upward on an independent looping animation path. The ghosts use theanimate-float-ghost Tailwind utility class, which applies a keyframe sequence cycling through vertical translation and subtle opacity shifts to give each ghost its own weightless, wandering feel.
At the center of the viewport, the welcome text renders in two lines:
- Primary title:
WELCOME, MORTAL— displayed in a large display font, each character animated independently - Subtitle:
Full-Stack Developer & Digital Poltergeist— fades in beneath the title after the letter sequence completes
Animation Details
The title animation is driven by Framer Motion. The string'WELCOME, MORTAL' is split into individual characters, and each character is wrapped in a motion.span. Every span receives a spring-based entrance animation with a staggered delay based on its index position.
| Property | Value |
|---|---|
| Animation type | Spring (type: 'spring') |
| Stiffness | 100 |
| Delay per letter | index * 0.1s |
| Initial state | opacity: 0, y: 40 |
| Animate state | opacity: 1, y: 0 |
animate-float-ghost class. Each ghost starts at a different vertical offset and cycles through a continuous upward drift, resetting when it exits the top of the frame.
CTA Button
Below the subtitle sits theENTER IF YOU DARE button. It is styled with a pumpkin-colored border, transparent background, and spaced uppercase lettering. On hover, the background fills with a ghost-teal tint and the border shifts to match, giving it a “charging up” feel before the user clicks.
Clicking the button navigates to the /about route using a React Router <Link> component.
Customization
How to change the welcome text
How to change the welcome text
The title is split into individual characters at render time using JavaScript’s Spaces in the string are preserved as non-breaking spaces (
.split('') method. To change the welcome message, update the string passed to .split(). Each resulting character becomes its own animated motion.span, so the stagger animation applies automatically regardless of message length.\u00A0) so the layout does not collapse mid-animation.How to change the CTA destination
How to change the CTA destination
The button uses a React Router The button label itself is plain text inside the
<Link> component. Update the to prop to point to any route in the application.<button> element — update it to any string to match the new destination.