Writing guides
Last updated:
This page is the reference for guide authors. Everything below is enforced by convention and code review, not by the system itself — which is what keeps the format consistent across guides without locking us into a rigid schema.
For a complete worked example that exercises every convention here, see Reference Assembly — a deliberately fake guide kept up to date as the canonical structural template.
File layout
Section titled “File layout”Each guide is a folder under src/content/docs/guides/:
src/content/docs/guides/<slug>/├── index.mdx # the guide content├── step-1.png # images, co-located with the guide├── step-2.png└── ...Images are referenced relatively (./step-1.png) so Astro’s asset pipeline picks them up and emits optimized WebP variants at build time.
Metadata
Section titled “Metadata”Every guide starts with a small <table class="guide-meta"> block holding the basic facts:
| Field | What it means |
|---|---|
| Product | Assembly name. |
| Hardware rev | The hardware revision this guide applies to. Bump when the hardware changes. Do not bump for typo fixes or wording changes — git is the source of truth for instruction history. |
| Author | Original author. |
The page’s lastUpdated date and time come automatically from git history and render under the title — you don’t author it.
A step is one image worth of work that ends in a verifiable state change.
Three properties any step must satisfy:
- One photo per step. If you find yourself wanting two photos, it’s two steps.
- Verifiable end state. After the step, the assembly is visibly different in a way the builder can confirm. Pure setup actions (“place in fixture”) are not steps unless they leave a visible result.
- Independently undoable. Reversing step N returns the assembly to the state at the end of step N−1. If undoing requires touching earlier steps, the boundary is wrong.
Heuristics that fall out:
- “And” in a step is a smell — likely two steps.
- A step whose only verb is “tighten” referring to a screw placed earlier should be merged with that earlier step.
- Long-cure / wait steps are valid (they have a verifiable end state and can’t be merged).
- Target the junior tech for granularity. Senior techs skim past granular steps; juniors fail at batched ones.
Step groups
Section titled “Step groups”Use H2 headings to group steps into sub-assembly milestones:
## Main board prep
### 1. Mount the main board...
### 2. Seat the ribbon connector...
## Sensor head
### 3. Install the sensor module...- Numbering is continuous across groups (1, 2, 3, 4…), not reset per group. Builders refer to “step 7” verbally; group resets break that.
- No single-step groups. If a group has one step in it, it isn’t a real boundary — fold it into a neighbor.
- No nesting. H4 sub-steps inside H3 steps inside H2 groups is forbidden.
- Group titles name the sub-assembly milestone (“Sensor head”), not the step range (“Steps 3–6”).
- Break a group out into its own guide only when it’s built at a different time, by a different person, or on a different bench setup.
Parts and tools
Section titled “Parts and tools”Each step opens with an italic line listing what the step consumes:
### 3. Install the sensor module
_Parts: 1× sensor module, 2× M2×6 SHCS. Tools: 1.5 mm hex key._

Instruction text...Conventions:
- Include
Parts:andTools:when present, omit when not. Don’t write “Tools: none.” - The aggregated BOM is derived from per-step lines, not authored separately. There is no top-of-page BOM section. If you find yourself wanting one, it means the procurement view should be a build-time aggregation — file an issue.
- Every part in the assembly should appear in some step. Decals, desiccant, foam inserts — they all belong in steps (often a final pack-out step). If a part doesn’t fit any step, the steps are incomplete.
Callouts
Section titled “Callouts”For warnings or info inside a step, use Starlight’s <Aside>:
<Aside type="caution">Torque to 0.4 N·m. Over-torque cracks the housing.</Aside>Types: note, tip, caution, danger. Use sparingly — only when something genuinely matters to a builder on the floor.
Annotated images
Section titled “Annotated images”To call out specific points on a photo, wrap the image in <AnnotatedImage> and add numbered bubbles:
import step1 from './step-1.png';
<AnnotatedImage src={step1} alt="..."> <Bubble at={[15, 70]} number={1} /> <Bubble at={[50, 85]} number={2} /></AnnotatedImage>
Lift the rear housing carefully — the flex cable (1) is short, so do not pull beyond 30°. The battery (2) remains seated.Coordinates are percentages of image dimensions (0–100), naming the center of the bubble. Percentages survive image re-exports at any resolution.
Live example:
Bubble colors
Section titled “Bubble colors”Bubbles default to red. Pass a color prop to change it:
<Bubble at={[50, 50]} number={2} color="blue" />Available colors: red (default), green, blue. The dev panel has three matching swatches — click one to make it active, then click an existing bubble to repaint or click empty image area to add a new bubble in that color.
Use color sparingly — if every bubble is a different color, none of them stand out. Stick to red unless a bubble means something genuinely different (e.g., red for parts being added, green for the orientation reference point, blue for an alignment guide).
Dev-mode tool
Section titled “Dev-mode tool”In npm run dev, every <AnnotatedImage> exposes a small panel below it:
- Click empty image area → drops a new bubble there, auto-numbered.
- Drag a bubble → reposition. The readout updates live as you drag.
- Shift+click a bubble → removes it, renumbering remaining bubbles to stay sequential.
- Click “Save” → rewrites the
<Bubble>lines in the MDX file directly. The dev server then hot-reloads.
If “Save” reports failure, the most likely cause is a conditional or self-closing <AnnotatedImage> in the source. Open it to a normal <AnnotatedImage>...</AnnotatedImage> form and retry.
The dev panel and endpoint are gated behind import.meta.env.DEV — they don’t exist in production builds.
What is not a step
Section titled “What is not a step”- Conditional branches per hardware rev — branch the whole guide per rev instead of putting “if rev B, do this” into a step. Conditional steps break the independently-undoable property and confuse builders.
- Recovery hints — put inside an existing step as an
<Aside>, not as their own step. - Workspace setup — put in a “Before you start” section above the first H2 group, not as a numbered step.
Verification
Section titled “Verification”After the last step, add a ## Verification section with observable checks the builder runs before shipping the assembly:
## Verification
- [ ] All four perimeter screws sit flush.- [ ] No gap between housings exceeds 0.2 mm at any edge.- [ ] LED illuminates when power is applied.These are inspection-only and shouldn’t appear as steps — they don’t change state, they confirm state.