version 0.2.0 replaces fromer version!
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
# Design System Introduction
|
||||
|
||||
> How `whynot-design` fits into the broader `whynot` workflow — from atelier exploration to production deploys.
|
||||
> How `whynot-design` fits into the broader `whynot` workflow — from atelier exploration to production deploys, across React, Django, plain HTML, or any future consumer.
|
||||
>
|
||||
> Audience: anyone (human or agent) about to add `whynot-design` as a dependency, or contribute changes back to it.
|
||||
|
||||
@@ -12,92 +12,143 @@
|
||||
|
||||
| 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. |
|
||||
| **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. Same separation, same vocabulary.
|
||||
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 — mocking a new screen, a beta landing page, a signal-record view. It is **not** what production code consumes. Production consumes this repo.
|
||||
> The Claude-Design template is the atelier for the *next* design exploration. It is **not** what production code consumes. Production consumes this repo.
|
||||
|
||||
---
|
||||
|
||||
## 2. What this repo contains
|
||||
## 2. The three-layer architecture
|
||||
|
||||
`whynot-design` is **deliberately framework-agnostic**. It ships in three stacked layers, and consumers pick how deep they go.
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ Layer 3 — Framework adapters (optional) │
|
||||
│ Django partials · React thin wrappers · Vue, Svelte, … │
|
||||
│ All thin. All delegate to Layer 2. │
|
||||
├─────────────────────────────────────────────────────────────┤
|
||||
│ Layer 2 — Web components (canonical) │
|
||||
│ <wn-button>, <wn-card>, <wn-modal>, <wn-prototype-card>… │
|
||||
│ Lit-based. Light DOM. SSR-friendly. Work in any framework. │
|
||||
├─────────────────────────────────────────────────────────────┤
|
||||
│ Layer 1 — Tokens + CSS │
|
||||
│ colors_and_type.css · components.css · tokens/*.json │
|
||||
│ Plain CSS variables and utility classes. Works in any HTML.│
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### Why this shape
|
||||
|
||||
- **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 |
|
||||
|---|---|---|
|
||||
| Django (server-rendered HTML + HTMX) | Layer 1 + 2 directly, or Layer 3 partials | `<wn-button variant="primary">{{ label }}</wn-button>` |
|
||||
| React (any meta-framework) | Layer 2 directly | `<wn-button variant="primary">Promote</wn-button>` — React handles custom elements natively |
|
||||
| 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).
|
||||
|
||||
---
|
||||
|
||||
## 3. 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.
|
||||
├── README.md Full design language.
|
||||
├── DesignSystemIntroduction.md This file.
|
||||
├── MultiFrameworkSupport.md How to consume from React, Django, Vue, plain HTML.
|
||||
├── SKILL.md Agent Skill manifest, cross-compatible with Claude Code.
|
||||
├── CONTRIBUTING.md How to propose, review, and ship a change.
|
||||
├── CHANGELOG.md Hand-edited, one entry per release.
|
||||
├── BOOTSTRAP.md First-push instructions. Delete after use.
|
||||
├── package.json @whynot/design — Lit is the one runtime dependency.
|
||||
│
|
||||
├── tokens/ Source-of-truth design tokens (JSON).
|
||||
│ ├── colors.json
|
||||
│ ├── type.json
|
||||
│ └── spacing.json
|
||||
├── tokens/ Source-of-truth design tokens (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.
|
||||
│ │ ├── colors_and_type.css Layer 1 — tokens + semantic element styles.
|
||||
│ │ └── components.css Layer 1 — utility classes for all components.
|
||||
│ ├── elements/ Layer 2 — Lit web components, light DOM.
|
||||
│ │ ├── atoms.js button, tag, eyebrow, stamp, stage-dot, phase-dot, icon
|
||||
│ │ ├── form.js input, textarea, select, search-input, field-row
|
||||
│ │ ├── layout.js card, modal, table, toast, empty-state, breadcrumb
|
||||
│ │ └── chrome.js top-nav, sidebar, page-header, pipeline, prototype-card
|
||||
│ └── index.js Side-effect import: registers all custom elements.
|
||||
│
|
||||
├── assets/ Logo, favicon-ready marks, future imagery.
|
||||
├── adapters/ Layer 3 — optional wrappers.
|
||||
│ └── django/templates/whynot/ Django {% include %} partials over the web components.
|
||||
│
|
||||
├── assets/ Logo, mark, future imagery.
|
||||
├── examples/
|
||||
│ └── whynot-control/ Working UI-kit recreation — also the visual-regression target.
|
||||
└── .gitea/workflows/
|
||||
└── ci.yml Lint + Playwright screenshot diff on PR.
|
||||
│ ├── showcase/ Plain-HTML demo of every component.
|
||||
│ └── whynot-control/ React + custom-element click-through UI kit.
|
||||
└── .gitea/workflows/ Lint + Playwright visual regression 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
|
||||
## 4. Integrating with a consuming codebase
|
||||
|
||||
### 3.1 The two viable distribution channels at A1
|
||||
### 4.1 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
|
||||
pnpm add git+ssh://git@gitea.example.com/whynot/whynot-design.git#v0.2.0
|
||||
```
|
||||
|
||||
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.
|
||||
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.
|
||||
|
||||
### 3.2 What a consumer imports
|
||||
### 4.2 What a consumer imports
|
||||
|
||||
The smallest viable consumption is:
|
||||
|
||||
```html
|
||||
<link rel="stylesheet" href="/static/whynot/colors_and_type.css">
|
||||
<link rel="stylesheet" href="/static/whynot/components.css">
|
||||
<script type="module" src="/static/whynot/index.js"></script>
|
||||
```
|
||||
|
||||
That's it. Now `<wn-button>`, `<wn-card>`, `<wn-modal>` etc. work everywhere on the page, in any framework, server-rendered or client-rendered.
|
||||
|
||||
For a Node-tooled consumer:
|
||||
|
||||
```jsx
|
||||
// At the root of the consuming app — once.
|
||||
// At app root, once.
|
||||
import "@whynot/design/styles/colors_and_type.css";
|
||||
import "@whynot/design/styles/components.css";
|
||||
import "@whynot/design"; // side-effect: registers all custom elements
|
||||
|
||||
// In any component file.
|
||||
import { Button, Tag, PrototypeCard, Eyebrow } from "@whynot/design";
|
||||
|
||||
export default function NewBetaPage() {
|
||||
// In any component file — React, Vue, Svelte, all behave the same.
|
||||
function NewBetaPage() {
|
||||
return (
|
||||
<article>
|
||||
<Eyebrow>whynot · closed beta</Eyebrow>
|
||||
<wn-eyebrow>whynot · closed beta</wn-eyebrow>
|
||||
<h1>Concierge prototype triage</h1>
|
||||
<p className="lead">Five seats. Two weeks. One learning question.</p>
|
||||
<Button variant="primary">Request an invite</Button>
|
||||
<wn-button variant="primary">Request an invite</wn-button>
|
||||
</article>
|
||||
);
|
||||
}
|
||||
@@ -105,26 +156,28 @@ export default function NewBetaPage() {
|
||||
|
||||
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.
|
||||
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.
|
||||
|
||||
### 3.3 Bootstrapping a new consuming repo
|
||||
### 4.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
|
||||
pnpm add @whynot/design # or the git+ssh URL
|
||||
# Then in your entry point:
|
||||
echo 'import "@whynot/design/styles/colors_and_type.css"' >> src/main.js
|
||||
echo 'import "@whynot/design/styles/components.css"' >> src/main.js
|
||||
echo 'import "@whynot/design"' >> src/main.js
|
||||
```
|
||||
|
||||
That's the whole onboarding. If it takes longer than this, the design system is fighting you.
|
||||
If it takes longer than this, the design system is fighting you.
|
||||
|
||||
---
|
||||
|
||||
## 4. Propagation pipeline — five hops
|
||||
## 5. Propagation pipeline — five hops
|
||||
|
||||
The end-to-end flow for a single design change:
|
||||
|
||||
@@ -146,84 +199,84 @@ The end-to-end flow for a single design change:
|
||||
|
||||
### 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."*
|
||||
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.
|
||||
|
||||
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).
|
||||
- **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.
|
||||
- A `CHANGELOG.md` entry is required.
|
||||
|
||||
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`.)
|
||||
- Push tag. CI uploads release notes from the CHANGELOG.
|
||||
|
||||
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).
|
||||
4. **Consumer auto-PR.** Renovate or Dependabot watches `@whynot/design` and opens a PR in every consuming repo bumping the version.
|
||||
|
||||
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.
|
||||
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. 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.
|
||||
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.
|
||||
|
||||
---
|
||||
|
||||
## 5. Versioning discipline
|
||||
## 6. 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` |
|
||||
| Token value tweak that doesn't visibly break any existing example | **patch** — `0.2.0 → 0.2.1` |
|
||||
| New component, new variant, new token | **minor** — `0.2.0 → 0.3.0` |
|
||||
| Removing / renaming a component, prop, or token; changing default behaviour | **major** — `0.3.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.
|
||||
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.
|
||||
|
||||
---
|
||||
|
||||
## 6. Where Claude fits
|
||||
## 7. 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.
|
||||
- **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.
|
||||
|
||||
- **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.
|
||||
- Pointed at `whynot-design`, Claude Code can write component PRs.
|
||||
- Pointed at a consuming repo, Claude Code can build screens that respect the rules.
|
||||
|
||||
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.
|
||||
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.
|
||||
|
||||
---
|
||||
|
||||
## 7. Pragmatic A1 staging — don't build the whole pipeline yet
|
||||
## 8. 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.
|
||||
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.
|
||||
|
||||
| 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. |
|
||||
| `whynot-design` repo | This seed. Tokens + CSS + Lit web components. | Never — this is the canonical shape. |
|
||||
| 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. |
|
||||
| Visual regression | Playwright over `examples/showcase/` and `examples/whynot-control/`. | The system has >40 components or >3 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. |
|
||||
| Release notes | Hand-edited `CHANGELOG.md`. | More than two contributors. |
|
||||
| Per-framework adapters | Django partials only, for the 4–5 most-used components. | Another non-React, non-Django consumer appears. |
|
||||
|
||||
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.
|
||||
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.
|
||||
|
||||
---
|
||||
|
||||
## 8. First-week checklist
|
||||
## 9. 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.
|
||||
- [ ] Tag `v0.2.0` immediately so consumers can pin.
|
||||
- [ ] 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).
|
||||
- [ ] 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).
|
||||
- [ ] 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.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user