Documentation Index
Fetch the complete documentation index at: https://mintlify.com/apursley2012/windows-98/llms.txt
Use this file to discover all available pages before exploring further.
CustomCursor replaces the browser’s native mouse pointer with a hand-crafted pixel-art SVG cursor that adapts to context and responds to clicks with a burst animation. It is a purely cosmetic, self-contained layer that adds to the Windows 98 desktop illusion without interfering with any interactive elements beneath it. All cursor elements are rendered with pointer-events-none so they never block clicks or hover states on the actual UI.
How it works
On mount,CustomCursor attaches two window event listeners inside a useEffect:
-
mousemove— Updates an{ x, y }state position (sourced fromevent.clientX/event.clientY). Afixeddivis translated to this position viatransform: translate(Xpx, Ypx), keeping the SVG cursor anchored to the real pointer at all times. The component also inspectsevent.targeton every move to determine whether the pointer mode cursor should be shown (see below). -
click— Appends a new sparkle object{ id: Date.now(), x, y }to a state array. Each sparkle is automatically removed after 400 ms viasetTimeout, matching the length of its exit animation.
useEffect cleanup function to prevent memory leaks on unmount.
The component also sets cursor: none globally on document.body (via a CSS rule in the project stylesheet) so the browser’s default arrow is hidden. CustomCursor itself renders as a fixed top-0 left-0 element at z-[10000], above all other UI layers.
Normal mode cursor
When the pointer is over a non-interactive element, a black pixel-art arrow SVG (24×24px viewBox) is displayed. The arrow shape is constructed from two<path> elements:
- A black (
#0a0a0a) outer fill forming the arrow silhouette. - A white (
#ffffff) inner fill inset by one pixel, producing a bright pixel-art outline typical of 1990s desktop cursors.
drop-shadow-md applied for subtle depth on lighter backgrounds.
Pointer mode cursor
The pointer mode activates whenevent.target matches any of the following conditions:
- The element’s computed style has
cursor: pointer. - The element’s tag name is
<a>or<button>. - The element is a descendant of an
<a>or<button>(checked via.closest()).
#ec4899) pixel-art diamond/crosshair SVG (also 24×24px), with a white inner highlight, signalling that a click is available. This replaces the browser’s default hand cursor that would otherwise appear.
Click sparkle animation
Every click spawns a turquoise sparkle burst centered on the click coordinates. The sparkle is a 16×16px SVG built from five colored rectangles arranged as a four-point star:motion.div managed inside AnimatePresence. Its animation:
| Property | Initial | Animate |
|---|---|---|
opacity | 1 | 0 |
scale | 0.5 | 1.5 |
y | click Y − 10px | click Y − 30px |
| Duration | — | 0.4s, easeOut |
fixed top-0 left-0 z-[9999] (one layer below the main cursor) so they always appear above page content but below the cursor itself. Multiple sparkles can exist simultaneously if the user clicks in rapid succession.
Touch device fallback
After mounting and attaching its event listeners,CustomCursor evaluates:
true — meaning the primary input device does not support hover, as is the case on touchscreens — the component returns null and renders nothing. The browser’s default touch interaction is left completely untouched.
Usage
CustomCursor accepts no props. Add it once at the application root alongside Taskbar so it covers all pages:
VisitorCounter
The LED counter in the system tray, exported from VisitorCounter.js.
Taskbar
Add both CustomCursor and Taskbar at the app root for the full Win98 feel.
Architecture: Styling
How the retro color palette (turquoise, magenta, navy) is defined.
Getting Started
Setting up the project from scratch.