witch-dev is a single-page application built with React 18 and Vite, deployed as a fully static site to GitHub Pages. Rather than relying on a server to rewrite URLs, each route is backed by its own static HTML shell that bootstraps the same compiled React bundle. All navigation, animation, and rendering logic lives client-side — no backend, no API calls, no build-time data fetching.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/apursley2012/witch-dev/llms.txt
Use this file to discover all available pages before exploring further.
Component Tree
The root component (xe) acts as the persistent app shell. It mounts three global layers that are always present regardless of the active route, then delegates page content to a React Router <Outlet /> wrapped in a Framer Motion <AnimatePresence> block.
<main> content right by md:ml-20 on medium screens and above, while remaining fixed so it never scrolls with page content.
Z-Index Layer Table
Each visual layer occupies a dedicated stacking slot so animated elements never bleed into each other.| Layer | Component | z-index | Position | Notes |
|---|---|---|---|---|
| Background | BackgroundEffects | z-0 | fixed inset-0 | Particles, fog blobs, sigil pattern |
| Content | <main> | z-10 | relative | All page components render here |
| Navigation | Navigation | z-50 | fixed left-0 | Sidebar on desktop |
| Mobile Menu | Mobile overlay | z-[60] | fixed inset-0 | Animated full-screen nav |
| Cursor | CursorTrail | z-[100] | fixed inset-0 | Always on top of everything |
Static Shell + SPA Hybrid
GitHub Pages serves files exactly as they exist on disk — there is no URL rewriting layer. witch-dev works around this by shipping a dedicated.html file for every route under the pages/ directory. Each shell does two things:
- Sets
window.__STATIC_PAGE_ROUTE__to the logical route path (e.g."/about"). - Runs an IIFE that redirects any bare URL to its hash equivalent (e.g.
/pages/About.html→/pages/About.html#/about).
assets/main.js bundle for every shell. React Router reads the hash fragment and renders the appropriate page component. The __STATIC_PAGE_ROUTE__ value is consumed by useScreenInit.js to synchronise the initial router state without a flicker.
Data Flow
witch-dev contains no external API calls. All page content — project cards, skills data, writing posts — is declared as static JavaScript arrays compiled directly intoassets/main.js at build time by Vite. This keeps the bundle self-contained and the site fully functional without a network connection after the initial load.
Page Transition System
Every route change triggers a choreographed blur-and-scale animation powered by Framer Motion’s<AnimatePresence> with mode="wait". The outgoing page fully exits before the incoming page begins its entrance, preventing two pages from occupying the content area simultaneously.
key prop is set to r.pathname (from useLocation()), so React treats each route as a distinct component instance. The asymmetric scale values (0.95 entering, 1.05 exiting) give the transition a subtle push-through depth effect that reinforces the occult aesthetic.