# Architecture

How the pieces of the ASK design system fit together, and what the rules of motion are between them.

## One picture

```
                  ┌──────────────────────────────────────────────────┐
                  │             design-tokens/tokens.json            │  ◀── source of truth
                  │             (W3C DTCG format)                    │
                  └────────────────────────┬─────────────────────────┘
                                           │
            ┌──────────────────────────────┼──────────────────────────────┐
            │                              │                              │
            ▼                              ▼                              ▼
  ┌──────────────────┐         ┌──────────────────────┐         ┌───────────────────┐
  │  curated CSS     │         │  curated Figma JSON  │         │  curated TS theme │
  │  globals.css     │         │  tokens-studio.json  │         │  theme.ts         │
  │  tailwind.preset │         │                      │         │                   │
  └────────┬─────────┘         └──────────┬───────────┘         └─────────┬─────────┘
           │                              │                               │
           ▼                              ▼                               ▼
   shadcn components                Figma variables                   Storybook
   in product repos                 + text styles                     + Chromatic

           ▲                              ▲                               ▲
           │                              │                               │
           └──────────────── parity enforced by ─────────────────────────┘
                       scripts/check-tokens.mjs + Figma library publish

  ┌──────────────────────────────────────────────────────────────────────┐
  │  Style Dictionary build (scripts/build-tokens.mjs) emits dist/:      │
  │  • CSS variables   • SCSS variables + map                            │
  │  • JS / TS module  • flat & nested JSON                              │
  │  These are CONSUMER outputs, not the source. dist/ is gitignored.    │
  └──────────────────────────────────────────────────────────────────────┘
```

## Why three layers (source / curated / generated)?

### Source — `tokens.json` (DTCG)

One file, machine-readable, schema-validated. Designers and engineers both reference it. It's hand-edited but never duplicated.

### Curated — `shadcn/`, `figma/`, `storybook/`

Each downstream tool has its own *opinion* about how tokens should be expressed:

- **shadcn** wants HSL channels without the wrapper (`354 78% 52%`) so `hsl(var(--primary) / <alpha>)` works.
- **Tokens Studio** wants its own dialect (no `$` prefix on `value`/`type`).
- **Storybook** wants a flat TypeScript object with brand-specific keys.

A pure generator can produce all three but loses the human-readable comments and the `.dark` override structure. So we hand-write these files and use `scripts/check-tokens.mjs` to enforce **value parity** (every hex in source appears in every consumer).

### Generated — `dist/`

For consumers that just want "a CSS file with variables" or "a JS object" without caring about shadcn conventions. Produced fresh on every build, never committed.

## Why no Figma → code component sync?

Because automated Figma-component → shadcn-code generation is, today, lossy. It produces JSX that doesn't match how engineers actually write components. So:

- **Tokens** sync automatically (Tokens Studio ↔ git PR).
- **Components** are built twice — once in Figma, once in shadcn. Discipline keeps them in parity.

This is the same trade-off Linear, Vercel, and Stripe make. The cost is real but it's lower than the cost of accepting generated code.

## The version contract

```
ask-design@1.0.0     initial release
ask-design@1.x.0     additive — new tokens, new components
ask-design@x.0.0     breaking — rename or removal
ask-design@x.y.z+meta build metadata (rare; for hotfix tagging)
```

Product repos pin to a tag. Pinned product repos do not get surprised by token changes.

## Where the boundaries are

| Lives here (this repo) | Lives in product repos |
|---|---|
| `tokens.json` | shadcn component implementations |
| Brand voice docs | Translations (i18n) |
| Logo SVG/PNG | Marketing copy variants |
| Compliance pattern *specs* | Compliance pattern *implementations* |
| Figma library files | Per-feature design files |
| Storybook theme | Storybook stories |

If you're tempted to put product-specific code here ("the chat composer", "the agent fleet table") — stop. That belongs in the product repo. This repo is the *vocabulary*, not the *sentences*.

## When the system changes

1. Issue filed (token / component / pattern).
2. Owner aligns direction in the issue thread.
3. PR opened — branch protection runs:
   - `ci.yml` → lint, format, token validate, drift check, link check.
   - `tokens-build.yml` → regenerates `dist/`, fails on diff.
   - `chromatic.yml` → visual regression on the Storybook build.
4. CODEOWNERS approval (always Matteo; sometimes `@ask-security`).
5. Merge to `main`.
6. Owner cuts a release tag (`ask-design@x.y.z`). `release.yml` bundles the tarball and writes the release notes from the matching `CHANGELOG.md` section.
7. Product repos bump their submodule / dep pointer to the new tag.

## When the system doesn't change

Most of the time. The system is finished when it stops changing daily. New tokens land monthly; new components, weekly; new patterns, quarterly.
