# Machine Registry Format

The catalogue is data-driven from `src/data/machineRegistry.ts`. New machines can be added without modifying catalogue cards, filters, search, the detail page, or route metadata.

## Required fields

Each `MachineRegistryItem` contains:

| Field | Description |
| --- | --- |
| `id` | Stable internal identifier. |
| `slug` | URL-safe route segment used by `/machines/:machineSlug`. |
| `title` | Human-readable machine name. |
| `subtitle` | Short engineering descriptor. |
| `shortDescription` | One-sentence card description. |
| `description` | One-paragraph reference description. |
| `category` | One of the values in `MACHINE_CATEGORIES`. |
| `difficulty` | `Beginner`, `Intermediate`, or `Advanced`. |
| `releasePhase` | `core` or `stretch`. |
| `publishedAt` | ISO date string used by newest sorting. |
| `complexity` | 1–5 integer used by complexity sorting and display. |
| `estimatedPartCount` | Approximate model/part count for shell stats. |
| `tags` | Visible card/detail tags. |
| `keywords` | Search-only terms and synonyms. |
| `thumbnail` | Procedural thumbnail variant and colour palette. |
| `facts` | Key engineering facts shown on cards/detail pages. |
| `parts` | Component names and descriptions for future viewer sidebars. |
| `applications` | Common real-world uses. |
| `learningObjectives` | Guided-tour learning goals. |
| `relatedSlugs` | Related machines for detail-page suggestions. |

## Adding a machine

1. Add a new object to `machineRegistry`.
2. Choose a unique `slug`.
3. Use an existing `category`, `difficulty`, and `thumbnail.variant`.
4. Include at least four meaningful `parts`.
5. Add two to four `relatedSlugs` that already exist in the registry.
6. Run `npm run check`.

Example:

```ts
{
  id: 'mechanism-example',
  slug: 'example-mechanism',
  title: 'Example Mechanism',
  subtitle: 'Demonstrates registry extensibility',
  shortDescription: 'A compact example for documentation.',
  description: 'A complete paragraph describing the system and its engineering context.',
  category: 'Mechanisms',
  difficulty: 'Beginner',
  releasePhase: 'stretch',
  publishedAt: '2026-01-01',
  complexity: 2,
  estimatedPartCount: 18,
  tags: ['Kinematics', 'Linkage'],
  keywords: ['example', 'mechanism'],
  thumbnail: {
    variant: 'mechanism',
    accent: '#4C8DFF',
    secondary: '#FFB04C'
  },
  facts: [{ label: 'Motion', value: 'Rotary to linear' }],
  parts: [
    {
      id: 'input-crank',
      name: 'Input crank',
      description: 'Receives rotary input from the drive shaft.'
    }
  ],
  applications: ['Teaching rigs'],
  learningObjectives: ['Identify the input and output motion.'],
  relatedSlugs: ['slider-crank']
}
```

## Search coverage

Search indexes these fields:

- title and subtitle
- category and difficulty
- release phase
- tags and keywords
- short and long descriptions
- applications
- facts
- part names and descriptions

No search index needs to be manually rebuilt; the utility functions derive text from the registry at runtime.

## Future 3D integration

The `parts` array is intentionally aligned with future viewer requirements:

- component list
- per-part visibility
- per-part opacity
- selection drawer descriptions
- guided-tour highlights
- annotation labels

Future GLB/GLTF assets should use matching semantic part identifiers where possible.
