The Projects page presents the developer’s portfolio work as a filterable grid of project cards. Visitors can narrow the view by selecting a moon phase — each phase maps to a project status, from live production work down to experimental unreleased experiments. Clicking a moon phase SVG button instantly re-filters the grid without a page reload, giving the interaction a fluid, magical feel.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.
Route
#/projects or click the Projects link in the site navigation.
Visual Layout
Moon Phase Filter Bar
A horizontal row of four clickable SVG moon icons at the top of the page. Each icon represents a project status phase. The active filter is highlighted; clicking a different icon updates the grid immediately.
Project Card Grid
A responsive multi-column grid of project cards. Each card shows the project title, a status badge, a short description, and a row of technology tags. Cards that do not match the active filter are hidden.
Phase Labels
Below each moon icon a short label names the phase: Unreleased Visions, Brews in Progress, Live Hexes, Fading Echoes.
Tech Tags
Each project card renders its
tech array as a series of pill-shaped tags at the card footer.Moon Phase Reference
| Phase value | Label | Meaning |
|---|---|---|
new | Unreleased Visions | Experimental / not yet public |
waxing | Brews in Progress | Actively in development |
full | Live Hexes | Shipped to production |
waning | Fading Echoes | Deprecated or winding down |
Data & Configuration
Projects are stored in theM array inside assets/main.js. Each object has four fields:
Field reference
| Field | Type | Purpose |
|---|---|---|
id | string | Unique identifier; used as the React list key |
title | string | Project name displayed as the card heading |
phase | 'new' | 'waxing' | 'full' | 'waning' | Controls which moon filter shows this card |
description | string | Short prose description shown in the card body |
tech | string[] | Technology names rendered as pill tags |
Customisation
Add a new project
Append a new object to the
M array with a unique id, a title, the appropriate phase, a description, and a tech array. The card will appear automatically in the filtered grid.Change a project's phase
Update the
phase field on the relevant object. Valid values are 'new', 'waxing', 'full', and 'waning'. This controls which filter bucket the project appears under.Add a link to a project
The
M schema does not currently include a url field. To add one, extend each object with url: 'https://...' and update the ProjectCard component to render an anchor tag using that value.Rename the phase labels
Phase display labels are defined in the
MoonPhaseFilter component alongside the SVG icons. Locate the label strings there and update them to suit your preferred terminology.Key Components
| Component | Description | Docs |
|---|---|---|
MoonPhase | Renders the four clickable SVG moon icons and manages active-filter state | /components/moon-phase |
ProjectCard | Displays a single project — title, phase badge, description, tech tags | Internal |
MoonPhase | Individual SVG moon icon used inside the filter bar | /components/moon-phase |
Interactive Behaviour
Moon phase filtering
Moon phase filtering
The active phase is held in a
useState variable inside the Projects page component. When a MoonPhase button is clicked, the state updates and the rendered list re-evaluates — only cards whose phase matches the active filter are shown. The filter is purely client-side; no network request is made.Card entrance animation
Card entrance animation
When the filter changes, cards entering the visible grid do so with a subtle fade-in via Framer Motion’s
AnimatePresence and motion.div. Cards that are filtered out unmount with a reciprocal fade-out. This prevents jarring layout jumps when the grid changes size.Project
id values are strings, not numbers. This is intentional — it allows non-sequential identifiers (e.g. slugs) without a schema change. Keep them unique across the M array to avoid React key warnings.