Documentation Index
Fetch the complete documentation index at: https://mintlify.com/apursley2012/web-weaver/llms.txt
Use this file to discover all available pages before exploring further.
EmberCursor transforms the mundane system cursor into a signature piece of Web Weaver’s aesthetic: a glowing teal ember that leaves a trail of luminous particles as it moves. The native cursor is hidden across the entire site, and every mouse movement spawns a new flicker of light. The result is an immersive, witchcraft-inspired interaction layer that makes even idle browsing feel atmospheric. This component runs continuously and silently in the background — visitors will notice its magic without ever needing to trigger it deliberately.
Visual behaviour
When the page loads, the system cursor is hidden via a globalcursor: none rule applied to body. In its place, EmberCursor renders two visual layers:
- Glowing dot — A small, intensely lit teal circle that tracks the exact pointer position in real time. It has a soft box-shadow bloom to simulate ember light.
- Trailing particles — On each
mousemoveevent, one or more translucent ember particles are spawned at the cursor position. Each particle animates outward, fades, and is removed, creating the illusion of a smouldering trail.
motion.div elements, giving each particle its own independent spring or tween animation.
Where it’s used
EmberCursor is mounted once inside the Layout component, outside the React Router <Routes> tree. This means it is present on every page of the portfolio without any page-level import.
Props
EmberCursor is a fully self-contained component and accepts no props. All behaviour — colours, particle count, animation timing, and cursor-hiding CSS — is encapsulated within the module.
Because there are no props, you cannot change the cursor colour or particle behaviour at runtime without editing the source module directly.
Implementation notes
Event listener lifecycle
The component attaches a
mousemove listener to window inside a useEffect hook. The listener is cleaned up when the component unmounts, preventing memory leaks. Since Layout never unmounts, the listener lives for the full session.Framer Motion particles
Each trailing particle is a
motion.div with an animate prop driving opacity from 1 → 0 and a small random translation. Once the exit animation completes the element is removed from the DOM, keeping the node count stable.z-index strategy
The cursor elements use a very high
z-index (typically 9999) so they render above all page content, modals, and overlays. pointer-events: none is set on all cursor elements so they never intercept clicks intended for page content.cursor: none scope
The
cursor: none declaration is applied to body (or via a global style) when the component mounts, and restored on unmount. This ensures no residual hidden-cursor state if the component were ever conditionally removed.Customisation tips
AlthoughEmberCursor is not prop-driven, its source module is the right place for the following tweaks: