Ship
Quality gate
Consistency is enforced at source boundaries, then checked in the browser where layout, focus, motion, and appearance become real.
Source contract
Repository checks prevent the easiest forms of design-system drift.
- Import the shared stylesheet exactly once in each app’s root CSS.
- Consume public controls and compositions from
@jungle/design-kit/react. - Keep direct imports declared in the owning workspace manifest.
- Do not add app-local button, field, modal, theme, or foundation implementations.
- Do not fix the root document to dark mode or omit the three-way appearance choice.
- Keep
@jungle/directoutside production dependency graphs.
Component verification
Tests protect semantics and state transitions, not snapshots of implementation details.
Shared interactive components require deterministic examples for keyboard behavior, accessible naming, disabled and pending semantics, owned selection, and focus restoration. Parsers, reducers, ordering, range normalization, and round trips also receive property tests when their input space is wider than a few named cases.
Browser matrix
A production-shaped route is checked across appearance, viewport, and input mode.
| Dimension | Required checks |
|---|---|
| Appearance | First visit is Light; Light, Dark, and System persist and resolve correctly. |
| Viewport | Compact mobile, medium content, and wide desktop; no hidden actions or accidental clipping. |
| Input | Keyboard-only completion, visible focus, pointer use, and touch-sized targets. |
| Motion | Route continuity at normal settings and no essential animation under reduced motion. |
| Content | Empty, loading, populated, overflow, recoverable failure, and long authored values. |
| Contrast | Text, focus, selected state, and status meaning remain clear in both themes and forced colors. |
Review questions
Ask these before debating small visual preferences.
- Is the information architecture obvious without animation or color?
- Can every action be named and completed with a keyboard?
- Does the same semantic role mean the same thing across apps?
- What happens with no data, slow data, invalid data, and too much data?
- Does the persistent shell stay stable while the intended stage changes?
- Is this behavior documented through the production export?