4.7 KiB
Contributing to whynot-design
Thanks for the curiosity. A few things before you open a PR.
Where the language is decided
Visual decisions are made in the Claude atelier project (the WhyNot Design System template), not in this repo. This repo is the implementation — it ships what the atelier agreed.
If your change is purely visual (a new component, a token tweak, a new variant), do it in the atelier first. Get a designer or whynot lead to approve the variation. Then open a PR here with:
- A link to the atelier project / screenshot of the approved variation.
- A one-sentence rationale, written in
whynotvoice. E.g. "The hover bar reads as 3px at 14” preview sizes; 2px disappears."
If your change is purely mechanical (CI, tooling, dependency bumps, doc typos), skip the atelier — just open the PR.
House rules
These are enforced by review, not CI. Internalise them.
- Quiet voice. Sentence case. No emoji (except
→and?!). No hype. No marketing language. - No new colour without a fight. The system is two neutrals and one accent. Adding a colour is a major decision. Add a token (e.g. status ramp extension) before adding a colour.
- No gradients. Anywhere.
- No shadows on cards. Elevation is intentionally near-zero. Popovers and modals only.
- Square corners on big things. 0–4 px radii for cards/sheets; 8 px for large modals; pill only for label capsules.
- No hand-rolled SVG icons or emoji. Lucide at 1.5 px stroke, or a placeholder.
- Lowercase organisation name (
whynot) in body copy.
When in doubt, re-read README.md and SKILL.md. Both are authoritative.
Workflow
[atelier] [this repo] [consumers]
explore ──► PR: tokens / components / CSS ──► Renovate PR
decide + CHANGELOG entry (auto, weekly)
+ Playwright snapshot updated
│ │
▼ ▼
merge → tag → release consumer CI
(CI handles) + visual regression
Branches
mainis always releasable. TagvN.N.Ndirectly frommain.- Feature branches:
feat/<short-slug>. PRs squash-merge.
Commits
Conventional Commits, lightly.
feat: add StageDot pulse variantfix(button): nudge ghost padding to match secondarytokens: tighten --tr-tight to -0.025emdocs: clarify Lucide stroke overridechore: bump @playwright/test
The tokens: prefix is non-standard but useful — it marks PRs that touch tokens/*.json or src/styles/colors_and_type.css and trigger consumer visual-regression review.
What CI checks
pnpm installsucceeds.CHANGELOG.mdhas a new entry that mentions the PR (this isscripts/check-changelog.mjs). Skip with the labelno-changelogfor trivial doc-only PRs.pnpm test:visual— Playwright opensexamples/whynot-control/index.htmland compares against snapshots inexamples/whynot-control/__screenshots__/.
If a snapshot intentionally needs to change, run pnpm test:visual:update locally, commit the new PNGs, and call it out in the PR description: "Snapshot updated — see Prototype.png, hover bar is now 3 px."
Release process
After PR merge:
-
Bump
package.jsonversion following the versioning rules inDesignSystemIntroduction.md§5. -
Move the
## [Unreleased]block inCHANGELOG.mdunder a new## [vX.Y.Z] — YYYY-MM-DDheader. -
Tag:
git tag vX.Y.Z && git push --tags. -
CI's release workflow attaches the CHANGELOG slice to the Gitea release. (If publishing to a registry, this is where
npm publishruns.) -
Renovate picks up the new tag in consumer repos within ~24h. Or manually:
cd ../whynot-prototype-WNO-022 pnpm up @whynot/design
Promoting past 1.0.0
Stay in 0.x.x until something built with this system is in production for >30 days with at least S2 signal. Promotion to 1.0.0 must be recorded in whynot-control/DECISIONS.md, same as promotion to Helix, Coulomb, etc.
What we don't accept
- PRs that add a colour palette without a corresponding atelier decision.
- PRs that import a UI library (Radix, Headless UI, shadcn) and re-export it. The system is small on purpose.
- PRs that add a build step before the system has >20 components.
- PRs that add storybook before the system has >2 contributors.
A contribution can be interesting and still be parked.
whynot-designexists to reduce visual uncertainty, not to absorb every good idea.