This page covers the repository layout of Player One and explains how the different pieces fit together at runtime. The project follows a Vite static-export pattern: a single React application is compiled into a shared set of JavaScript and CSS bundles, and then a lightweight HTML entry file is generated for each route. Understanding this layout makes it straightforward to add new pages, customise components, or deploy the site to any static host.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/apursley2012/player-one/llms.txt
Use this file to discover all available pages before exploring further.
Directory Tree
Static Export Approach
Player One uses Vite to produce a fully static build. Rather than relying on a singleindex.html with client-side routing fallbacks, the build generates one HTML file per route inside the pages/ directory. Each of these HTML files is structurally identical — they all load the same shared JS and CSS bundles from assets/ — but each one injects a small inline <script> block that tells the React application which route to render.
The key mechanism is the global variable window.__STATIC_PAGE_ROUTE__. Before assets/main.js initialises the React tree, the per-page script sets this variable to the route string for that page (e.g. "/about", "/contact"). The React Router bootstrap inside main.js reads this value and uses it to pre-seed the hash location, so the correct page content renders immediately without any extra navigation.
Hash-Based Routing
Player One uses React Router’sHashRouter throughout the application. With HashRouter, every URL includes a # fragment before the path — for example, https://yoursite.com/#/projects. Because the hash is never sent to the web server, the browser always loads the HTML file it was directed to, and React Router handles all navigation client-side.
This approach has an important practical benefit: no server-side redirect or rewrite rules are required. The site deploys identically to GitHub Pages, Netlify (with no _redirects file), Amazon S3, or any plain file host. Each pages/*.html file covers its own route, and refreshing any page or navigating directly to a #/ URL will work correctly.
Per-Page Route Bootstrap Script
Each HTML file inpages/ contains the following inline script pattern. Here is the example for the About page:
- Sets
window.__STATIC_PAGE_ROUTE__to the canonical route string. The React bootstrap reads this value to know which route to activate. - Redirects bare visits — if someone navigates directly to
pages/About.htmlwithout a hash fragment (or with only a bare#), the IIFE immediately replaces the location with the correct#/abouthash. This ensures the React RouterHashRouteralways sees a well-formed hash URL when it initialises.
index.html uses the same pattern with window.__STATIC_PAGE_ROUTE__ = "/" and appends #/ instead.
Asset Bundles
All shared JavaScript is compiled into theassets/ directory and loaded via <link rel="modulepreload"> in every HTML file:
| File | Purpose |
|---|---|
assets/main.js | Application entry — mounts the React tree into #root |
assets/main.css | Compiled Tailwind CSS plus all custom arcade utility classes and animations |
assets/jsx-runtime.js | React’s JSX transform runtime (react/jsx-runtime) |
assets/createLucideIcon.js | Lucide React’s icon factory function, shared by all icon references |
assets/proxy.js | Combined bundle of Framer Motion (motion) and React Router (HashRouter, useNavigate, Routes, Link, etc.) |
Component Descriptions
Each file undercomponents/ is a pre-built ES module that exports a single React component:
| Component | Export | Description |
|---|---|---|
Navigation.js | N (Navigation) | Pixel-art navigation bar with links to all seven routes and an inventory/modal panel. Imports from proxy.js for routing hooks. |
HUD.js | H (HUD) | Fixed-position overlay rendering PLAYER_1, a static score of 999999, an “INSERT COIN” blinker, a credits counter, and a live clock that updates every second. |
CRTOverlay.js | C (CRTOverlay) | Renders two absolutely-positioned, pointer-events-none layers — crt-overlay (horizontal scanlines) and crt-vignette (radial darkening) — that sit above the entire viewport. |
GhostSprite.js | G (GhostSprite) | An SVG pixel-art ghost animated by Framer Motion to travel horizontally across the screen in a looping path, with configurable color, delay, duration, startX, startY, and scale props. |
PageTransition.js | P (PageTransition) | Wraps page content in a Framer Motion div that animates opacity, scale (0.95 → 1), and filter: blur on entrance and exit over 400 ms. |
ArcadeCabinet.js | A (ArcadeCabinet) | Renders a project card in the silhouette of a three-part arcade cabinet: a marquee header with the project title, a screen body showing the description, and a control panel footer with RUN DEMO, SOURCE, and README action buttons. |
Build Output
Runningnpm run build produces a dist/ directory that mirrors the source layout:
- One HTML file per route (root
index.htmlplus one per page inpages/) dist/assets/main.css— the complete Tailwind + arcade CSS bundledist/assets/main.jsand associated JS chunks- All component and runtime modules