# Design System Introduction > How `whynot-design` fits into the broader `whynot` workflow — from atelier exploration to production deploys. > > Audience: anyone (human or agent) about to add `whynot-design` as a dependency, or contribute changes back to it. --- ## 1. Mental model — three places, three jobs `whynot-design` is one of three surfaces. Each has a different job. Don't confuse them. | Place | Job | What lives there | |---|---|---| | **Claude atelier project** (`WhyNot Design System` template) | Explore, decide, mock | HTML cards, UI-kit JSX prototypes, 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: CSS tokens, components, the logo bundle. Source of truth for the *artefact*. | | **`whynot-*` consuming repos** (apps, prototypes, marketing sites) | Use | `pnpm add @whynot/design`, import tokens + components, build the app. | 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. Same separation, same vocabulary. > The Claude-Design template is the atelier for the *next* design exploration — mocking a new screen, a beta landing page, a signal-record view. It is **not** what production code consumes. Production consumes this repo. --- ## 2. What this repo contains ``` whynot-design/ ├── README.md Quick start + manifest. ├── DesignSystemIntroduction.md This file. ├── SKILL.md Agent Skill manifest — also usable by Claude Code. ├── CONTRIBUTING.md How to propose, review, and ship a change. ├── CHANGELOG.md Hand-edited, one entry per release. ├── package.json Name: @whynot/design. │ ├── tokens/ Source-of-truth design tokens (JSON). │ ├── colors.json │ ├── type.json │ └── spacing.json │ ├── src/ │ ├── styles/ │ │ └── colors_and_type.css Drop-in CSS variables + semantic element styles. │ ├── components/ JSX, consumed from source (no build step at A1). │ └── index.js Barrel export. │ ├── assets/ Logo, favicon-ready marks, future imagery. ├── examples/ │ └── whynot-control/ Working UI-kit recreation — also the visual-regression target. └── .gitea/workflows/ └── ci.yml Lint + Playwright screenshot diff on PR. ``` There is intentionally **no build step**. Consumers import the JSX and CSS directly. This keeps the A1 pipeline trivially debuggable. Add a build step when the system grows past ~30 components or needs to support non-React consumers. --- ## 3. Integrating with a consuming codebase ### 3.1 The two viable distribution channels at A1 In order of effort: **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. ```jsonc // consuming-app/package.json { "dependencies": { "@whynot/design": "workspace:*" } } ``` **b) Install directly from Gitea** — no registry needed. ```sh pnpm add git+ssh://git@gitea.example.com/whynot/whynot-design.git#v0.3.1 ``` Pin to a tag, not `main`. Tag-pinning is the entire versioning discipline at A1. When you outgrow either of these (a second team needs read access without repo cloning, or you want semver resolution), publish to **Gitea Packages** (supports npm protocol natively) or set up a private Verdaccio. ### 3.2 What a consumer imports ```jsx // At the root of the consuming app — once. import "@whynot/design/styles/colors_and_type.css"; // In any component file. import { Button, Tag, PrototypeCard, Eyebrow } from "@whynot/design"; export default function NewBetaPage() { return (
whynot · closed beta

Concierge prototype triage

Five seats. Two weeks. One learning question.

); } ``` Three rules of consumption: 1. **Import the CSS exactly once**, at the app's root. 2. **Use CSS variables for any colour, type, or spacing decision**, not hex codes. If the token doesn't exist, that's a signal to extend the system — not to invent. 3. **Don't restyle components by overriding their CSS.** If a component doesn't fit a use case, add a variant in `whynot-design` itself. The discipline that makes a design system valuable is the discipline of not forking it locally. ### 3.3 Bootstrapping a new consuming repo ```sh mkdir whynot-prototype-WNO-022 cd whynot-prototype-WNO-022 pnpm init pnpm add react react-dom pnpm add git+ssh://git@gitea.example.com/whynot/whynot-design.git#v0.1.0 echo 'import "@whynot/design/styles/colors_and_type.css"' >> src/main.jsx ``` That's the whole onboarding. If it takes longer than this, the design system is fighting you. --- ## 4. Propagation pipeline — five hops The end-to-end flow for a single design change: ``` [Claude atelier] [whynot-design] [Consuming repo] [Deploy] explore variants ──► PR with token / ──► Renovate / pnpm ──► staging in the template component change up opens PR bumping user approves + Playwright diff @whynot/design │ + CHANGELOG entry ▼ │ │ prod tag v0.3.1 CI runs visual CI publishes / regression on the attaches release consuming app asset │ │ merge if green └──────────────────────────────┘ ``` ### Hop-by-hop 1. **Atelier → `whynot-design` PR.** Someone (you, a designer, or an agent) takes a change agreed in the Claude project — "the prototype card's hover bar is 3px not 2px" — and opens a PR against `whynot-design`. The PR description quotes the atelier decision, e.g. *"Decided in atelier 2026-04-12: thicker hover bar reads better at 14” preview sizes."* 2. **`whynot-design` CI** runs: - Lint + (optional) typecheck. - **Visual regression** — Playwright screenshots `examples/whynot-control/index.html` and any other registered example, diffs against baselines. This is the single most valuable piece of automation; everything else is bookkeeping. - A `CHANGELOG.md` entry is required (enforce with a small CI check, or use `changesets` once you outgrow hand-editing). 3. **Merge → tag → publish.** On merge to `main`: - Bump `package.json` (patch for token tweaks, minor for new components, major for renames/removals). - Tag `v0.3.1`. - Push tag. CI uploads release notes from the CHANGELOG. (Once a registry is in use, this step also runs `npm publish`.) 4. **Consumer auto-PR.** Renovate or Dependabot watches `@whynot/design` and opens a PR in every consuming repo bumping the version. Renovate config groups these so all `whynot-*` prototypes update on the same schedule (e.g. weekly). 5. **Consumer CI + deploy.** The consuming repo's *own* CI runs *its* visual regression — does the new token change anything in *this* app's screens? If not, auto-merge (Renovate can do this for patch versions with green CI). If yes, a human reviews. Merge triggers the existing deploy to staging → prod. The whole loop, warm, takes minutes. The key insight: **automation works only because every step has a deterministic check** — visual regression on the design-system side, visual regression on the consumer side, semver, changelogs. Skip those and the "pipeline" is a slow manual process with extra tools. --- ## 5. Versioning discipline Strict semver, even at A1. | Change | Bump | |---|---| | Token value tweak that doesn't visibly break any existing example | **patch** — `0.1.0 → 0.1.1` | | New component, new variant, new token | **minor** — `0.1.1 → 0.2.0` | | Removing / renaming a component, prop, or token; changing default behaviour | **major** — `0.2.0 → 1.0.0` | Stay in `0.x.x` until something 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. --- ## 6. Where Claude fits Two distinct roles, both useful: - **The Claude atelier template** — used at hop 1. Designer (or you) opens a new project from the template, mocks variations, decides, hands off a PR description + diff to whoever (or whatever) writes the `whynot-design` PR. The atelier never publishes anything to production directly. - **Claude Code with `SKILL.md`** — used at hop 1 *and* hop 5. The same SKILL file works in both contexts: - Pointed at `whynot-design`, Claude Code knows the rules and can write component PRs. - Pointed at a consuming repo, Claude Code knows the rules and can build screens that respect them. That's why `SKILL.md` ships with this repo. Drop it into `.claude/skills/` of any consuming repo (or copy its contents into a project-level `CLAUDE.md`) and any agent operating in that repo will know the visual language. --- ## 7. Pragmatic A1 staging — don't build the whole pipeline yet Right now, `whynot` is at A1 Incubating with one or two prototype apps in flight. Build the smallest pipeline that still has the right *shape*. Promote each piece only when a real signal demands it. | Hop | A1 version | Promote to full when… | |---|---|---| | Atelier | Claude template, as-is. | Never — stays here. | | `whynot-design` repo | This seed. CSS + JSX consumed from source. No build step. | Second non-React consumer appears, or bundle size becomes a measurable problem. | | Distribution | pnpm workspace, or `git+ssh` install from tags. | An external collaborator needs read access without cloning. | | Visual regression | One Playwright test screenshotting `examples/whynot-control/index.html`. | The system has >20 components or >2 consuming apps. | | Dependency updates | Manual `pnpm up` once a week. | More than two consuming repos. | | Release notes | Hand-edited `CHANGELOG.md`. | More than two contributors, or releases become weekly. | | Component-level visual coverage | One screenshot of the whole UI kit. | The system has >20 components. | 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. Don't pay the cost of the second one until you're in it. --- ## 8. First-week checklist For whoever is bootstrapping this repo right now: - [ ] Push the seed contents to `gitea.example.com/whynot/whynot-design`. - [ ] Tag `v0.1.0` immediately so consumers can pin. - [ ] Add the repo as a remote dependency in **one** consuming app and verify imports work. - [ ] Open one trivial PR against `whynot-design` (e.g. a CHANGELOG typo) to confirm CI passes end-to-end. - [ ] Record this bootstrap in `whynot-control/DECISIONS.md` as DEC-004 or similar — *"Established whynot-design as the implementation surface for the visual language."* - [ ] Update `whynot-control/SCOPE.md` to mention `whynot-design` in the out-of-scope list (it's a sibling, not absorbed scope). 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.