Create, validate, and maintain space portfolio system data. Use when adding new projects, experiences, or skills to the portfolio galaxy, or when understanding the data schema requirements. Handles System, Planet, and Moon object creation with full field reference and best practices.
The space portfolio uses a three-level data hierarchy to represent portfolio content:
System (Solar System)
├─ Planet (Clickable detail/aspect)
│ └─ Moon (Sub-detail)
└─ Moon (System-level achievement)
System = Project, experience, skill group, or About Me section
Planet = Key facet (overview, tech stack, key achievement, etc.)
Moon = Secondary detail or sub-achievement
All data lives in src/data/systems.ts and is typed by src/types/systems.ts.
Every System requires:
id — unique slug, lowercase, no spaces (e.g., "my-awesome-project")name — display name, any format (e.g., "My Awesome Project")position — [x, y, z] coordinates in world space (recommend ±200 range)type — one of: "project", "side-project", "experience", "skill", "about"starColor — hex color for the system's star (e.g., "#4f8eff")planets — array of Planet objects (minimum 1 planet)Optional System fields:
tagline — short subtitle (max 80 chars)description — long-form description (200–400 chars)categories — tags for filteringdates — { start, end } ISO dates for timelinescontributors — array of { name, role, url }visual — { starSize, glowIntensity, nebulaTint, nebulaIntensity, starModelPath }discovery — { hidden, featured, proximityDistance, proximityIcon }links — array of { label, url, icon }metadata — { description, imageUrl, keywords } for SEO/sharingrelations — { relatedSystems, predecessor, successors }flags — { archived, experimental, openSource: { enabled, license, repositoryUrl } }custom — arbitrary extensibility objectEvery Planet requires:
id — unique within the system (e.g., "overview", "tech-stack")name — display namedescription — 100–300 character descriptiontags — array of tech/skill tags (3–6 items)links — array of { label, url, icon? } (can be empty)orbitRadius — distance from star (recommend 6–18 world units)Optional Planet fields:
modelPath — path to custom .glb modelmoons — array of Moon objectscolor — hex color for this planetglowIntensity — bloom intensity (0–1)featured — if true, appears first/highlightedcomplexity — difficulty level (1–5)Every Moon requires:
id — unique within parentname — display namedescription — brief description (max 100 chars)orbitRadius — distance from parent (recommend 2–4 for planet moons)Optional Moon fields:
badge — emoji or icon| Type | Position | Star Color | Planets | Size | Glow | Featured |
|---|---|---|---|---|---|---|
| project | Center/mid-ring | Vibrant (blue, purple, teal, pink) | 3–4 | 1.3–2.0 | 0.8–1.0 | Yes (important) |
| side-project | Mid/outer ring | Softer colors | 1–2 | 0.8–1.0 | 0.5–0.7 | No |
| experience | Center | Warm (gold, warm pink, orange) | 3–5 | 2.0+ | 0.9–1.0 | Yes |
| skill | Scattered (belt) | Cool (cyan, green, gray) | 4–6 | 1.0–1.2 | 0.6–0.8 | No |
| about | Center [0,0,0] | White/gold/signature | 2–3 | 1.0 | 1.0 | Yes |
const id = "project-slug"; // unique kebab-case ID
const name = "Project Name"; // display name
const position = [x, y, z]; // [x, y, z] coordinates
const type = "project"; // type enum
const starColor = "#4f8eff"; // hex color
{
id,
name,
position,
type,
starColor,
tagline: "Short description",
planets: [
{
id: "overview",
name: "Overview",
description: "What is this project?",
tags: ["React", "TypeScript"],
links: [
{ label: "Live", url: "https://..." }
],
orbitRadius: 8,
}
],
}
Add it to the systems array in src/data/systems.ts. It automatically appears in the galaxy!
Before committing a new system:
id is kebab-case, unique across all systemsname is descriptive, under 50 charsposition is within ±200 and not too close to otherstype is one of the 5 enum valuesstarColor is valid hex (e.g., #ff0000, #abcdef)npm run type-check)| File | Purpose |
|---|---|
src/types/systems.ts | Full TypeScript interfaces with JSDoc |
src/data/systems.ts | Data entries + 8 example systems |
src/data/SCHEMA_GUIDE.md | Detailed guide (20+ sections) |
project-roadmap/world-design-document.md | Design constraints & content structure |
If you modify the schema (types, fields, or requirements), you MUST update all of the following:
src/types/systems.ts
isValidSystem() type guard if neededsrc/data/systems.ts
src/data/SCHEMA_GUIDE.md
project-roadmap/world-design-document.md
This Skill File (SKILL.md)
Sync Process:
src/types/systems.tssrc/data/systems.ts to matchSCHEMA_GUIDE.md to document the new field(s)world-design-document.md — update if it documents the schema structurenpm run type-check to verify everything compiles| Change | Type | Guide | Examples | World Doc | Skill |
|---|---|---|---|---|---|
| Add optional field | ✓ | ✓ | ✓ | Check | ✓ |
| Remove field | ✓ | ✓ | Update | Check | ✓ |
| Change field type | ✓ | ✓ | ✓ | Check | ✓ |
| Add new system type | ✓ | ✓ | Add example | ✓ | ✓ |
| Change validation rules | ✓ | ✓ | ✓ | Check | ✓ |
{
id: "color-generator",
name: "Color Palette Generator",
position: [120, -40, 100],
type: "side-project",
starColor: "#ffd700",
planets: [
{
id: "overview",
name: "Overview",
description: "AI-powered color palette generation from a single seed color.",
tags: ["React", "AI", "Design Tools"],
links: [{ label: "Try It", url: "https://example.com" }],
orbitRadius: 8,
}
],
}
{
id: "flagship-project",
name: "My Flagship Project",
position: [50, 20, -50],
type: "project",
starColor: "#4f8eff",
tagline: "A 3D interactive experience",
description: "Built with React Three Fiber...",
planets: [
{
id: "overview",
name: "Overview",
description: "Project description",
tags: ["React", "Three.js", "TypeScript"],
links: [
{ label: "Live", url: "https://example.com" },
{ label: "GitHub", url: "https://github.com/user/project" }
],
orbitRadius: 8,
featured: true,
},
{
id: "tech",
name: "Tech Stack",
description: "Technologies used...",
tags: ["React Three Fiber", "Drei", "GSAP"],
links: [],
orbitRadius: 12,
}
],
visual: { starSize: 1.5, glowIntensity: 0.9 },
discovery: { featured: true },
}
{
id: "senior-dev-role",
name: "Senior Frontend Developer",
position: [-30, 0, 40],
type: "experience",
starColor: "#ff6b9d",
dates: { start: "2023-01-15", end: "2025-01-31" },
contributors: [
{ name: "You", role: "Tech Lead" },
{ name: "Team Member", role: "Backend Lead" }
],
planets: [
{
id: "role",
name: "Role Overview",
description: "Led 4-person frontend team...",
tags: ["Leadership", "React", "Performance"],
links: [],
orbitRadius: 10,
featured: true,
}
],
}
| Issue | Solution |
|---|---|
| System doesn't appear | Check: id, name, position, type, starColor, planets (not empty) |
| Planet isn't clickable | Check: planet id, name, description, orbitRadius (6–18) |
| Colors look wrong | Verify hex code is valid; increase glowIntensity |
| TypeScript error | Run npm run type-check; check syntax |
| Info panel cut off | Reduce description length, keep under 300 chars |
After creating a new system:
npm run type-check to verify schema complianceLast updated: April 8, 2026
Version: 1.0 — Architecture Complete