> How `whynot-design` fits into the broader `whynot` workflow — from atelier exploration to production deploys, across React, Django, plain HTML, or any future consumer.
| **Claude atelier project** (`WhyNot Design System` template) | Explore, decide, mock | HTML cards, prototypes of new components, the README that defines the rules. Source of truth for the *language* of the system. |
| **`whynot-design` repo** (this one) | Distribute | A versioned, publishable package: tokens, CSS, web components, the logo bundle. Source of truth for the *artefact*. |
| **`whynot-*` consuming repos** (apps, prototypes, marketing sites) | Use | Add `@whynot/design` as a dependency. Use it from React, Django, Vue, or plain HTML — see [`MultiFrameworkSupport.md`](./MultiFrameworkSupport.md). |
This mirrors the existing organisational logic. `whynot-control` is the *control* surface (intent, scope, decisions, governance). `whynot-design` is the *implementation* surface for the visual language.
> The Claude-Design template is the atelier for the *next* design exploration. It is **not** what production code consumes. Production consumes this repo.
- **Layer 1 is the bedrock.** Tokens are framework-agnostic by definition. `colors_and_type.css` is just CSS variables — Django, Rails, Phoenix, plain HTML, any framework can `<link>` to it and inherit the system's typography and palette tomorrow. The component utility classes in `components.css` (e.g. `.wn-btn`, `.wn-card`) compose those tokens into the canonical recipes. **Anything in this repo can be consumed with no JS at all.**
- **Layer 2 adds behaviour without lock-in.** Web Components are a stable platform feature — they're not a framework dependency that ages out. Lit is the implementation detail; the *contract* is the HTML custom-element API. A `<wn-button variant="primary">` works in a React JSX file, a Django template, a Vue SFC, and `index.html` identically. **Layer 2 components render to light DOM**, which means Layer 1's CSS styles them — no shadow-DOM style isolation, no FOUC, no SSR friction.
- **Layer 3 is convenience, not commitment.** If a consumer wants typed React props or Django `{% include %}` shorthand, the repo ships *thin* wrappers in `adapters/`. They delegate to Layer 2. Removing or refactoring them does not break Layer 2 consumers.
### Which layer should *you* use?
| If your consumer is… | Use this layer | Example |
| Plain HTML page / a prototype landing page | Layer 2 directly | `<wn-button variant="primary">Sign up</wn-button>` |
| Email, PDF, or no-JS context | Layer 1 only | `<button class="wn-btn wn-btn--primary">Open</button>` |
| You only need typography & colours | Layer 1 only | Just `<link>` the CSS. |
The discipline: **do not subclass, fork, or restyle Layer 2 components in your repo**. If a component doesn't fit a use case, add a variant *upstream* in `whynot-design`. The thing that makes a design system valuable is the discipline of not forking it locally.
For the full how-to per framework — including SSR, hydration, the `noscript` story, form participation, and HTMX integration — see [`MultiFrameworkSupport.md`](./MultiFrameworkSupport.md).
**a) pnpm workspaces (recommended for now)** — put `whynot-design` and your consuming app in the same monorepo (or use `file:` / `link:` references). Zero registry, zero auth, instant updates.
**b) Install directly from Gitea** — no registry needed.
When you outgrow either (second team needs read access without cloning, semver resolution becomes valuable), publish to **Gitea Packages** (native npm protocol) or a private Verdaccio.
1.**Import the CSS once at the app's root.** Both stylesheets.
2.**Use tokens for any colour, type, or spacing decision** that components don't cover. If the token doesn't exist, that's a signal to extend the system upstream — not to invent.
3.**Don't restyle components by overriding their CSS.** If a component doesn't fit, contribute a variant.
1.**Atelier → `whynot-design` PR.** Someone (you, a designer, or an agent) takes a change agreed in the Claude project and opens a PR against `whynot-design`. The PR description quotes the atelier decision.
- **Visual regression** — Playwright screenshots `examples/showcase/index.html` and `examples/whynot-control/index.html`, diffs against baselines. This catches both styling regressions and behavioural ones.
5.**Consumer CI + deploy.** The consuming repo's *own* CI runs *its* visual regression. If unchanged, auto-merge. If changed, a human reviews. Merge triggers existing deploys to staging → prod.
The whole loop, warm, takes minutes. **Automation works only because every step has a deterministic check** — visual regression on both sides, semver, changelogs. Skip those and the pipeline is a slow manual process with extra tools.
Stay in `0.x.x` until something built with this system is in production. While in `0.x.x`, **minor bumps are allowed to break things** — that's the convention. This gives you permission to iterate without ceremony.
Promotion past `1.0.0` should appear in `whynot-control/DECISIONS.md`. Same rule as promotion to Helix or Coulomb: it's a deliberate act, not a release-script side-effect.
- **The Claude atelier template** — used at hop 1. Designer (or you) opens a new project, mocks variations, decides, hands off a PR description + diff to whoever writes the `whynot-design` PR. The atelier never publishes anything to production directly.
That's why `SKILL.md` ships with this repo. Drop it into `.claude/skills/` of any consuming repo and any agent operating in that repo will know the visual language.
Right now, `whynot` is at A1 Incubating. Build the smallest pipeline that still has the right *shape*. Promote each piece only when a real signal demands it.
This staging is exactly the *"low-cost learning first"* posture in `whynot-control/OPERATING_MODEL.md`. A design system with one consumer and one author does not need Chromatic. A design system with five consumers and three authors absolutely does.
- [ ] Add the repo as a remote dependency in **one** consuming app (the Django one) and verify imports work end-to-end. Follow [`MultiFrameworkSupport.md` §Django](./MultiFrameworkSupport.md#django-server-rendered-templates--htmx).
- [ ] Record this bootstrap in `whynot-control/DECISIONS.md` as DEC-004 — *"Established whynot-design as the implementation surface, three-layer architecture, Lit web components as the canonical component layer."*
- [ ] Update `whynot-control/SCOPE.md` to mention `whynot-design` as a sibling.
That's it. Anything more is over-engineering for the current stage.
---
> A design system can be interesting and still be parked. `whynot-design` exists to reduce visual uncertainty across prototypes, not to create more obligations.