# Contributing

How to work on @oscarkalid/ui.

## Getting set up

```sh
git clone https://github.com/yajesta/ui
cd ui
pnpm install
pnpm dev
```

```sh
pnpm dev        # workbench on http://localhost:3200
pnpm build      # production build, writes to .next-build
pnpm typecheck  # types across the workspace
pnpm lint
```

## Where things live

```text
packages/
  ui/          the library: tokens, components, hooks, styles
  workbench/   the site: docs plus full application demos
  db/          demo data the workbench renders against
```

## The two rules that matter most

**Nothing defines its own colours, spacing, radii or transitions.** They all come
from `packages/ui`. A hex code, a px value or a `transition:` declaration in the
workbench belongs in the design system as a token.

```tsx
// No.
<div className="bg-[#101113] p-[14px] transition-[200ms]" />

// Yes. Every value is a token, so re-theming is one edit in one file.
<div className="bg-surface p-3 transition-colors" />
```

**Write each CSS property exactly once per element.** Never put a base value in
the class list and then override it conditionally.

```tsx
// Broken. Tailwind resolves same-property conflicts by the order it emits
// rules, not the order they appear in the string. .bg-transparent is emitted
// after .bg-accent-soft, so the base wins and the selected state never shows.
cn("bg-transparent", selected && "bg-accent-soft")

// Correct. The property is written once, in branches.
cn(selected ? "bg-accent-soft" : "bg-transparent")
```

It never throws. The base value wins and the conditional one never appears.

## Design system rules

- **Token layers.** Primitives (`--blue-500`) are the raw palette. Components
  never reference them. Semantic tokens (`--surface-raised`, `--accent`) name a
  role and are the only thing components use.
- **Themes are data.** A theme is a set of semantic token values on
  `[data-theme]`. Adding one must not require touching a component.
- **Transitions are tokens too.** No component writes `300ms ease-in-out`.
- **Import from the package root**, never from `@oscarkalid/ui/src/...`.
- **WCAG 2.2 AA.** A component with a broken focus ring is not finished.
- **A component ships with its page.** A new component needs a page in the
  workbench, with the source visible.

## House style

No em dashes anywhere: UI copy, code, comments, docs, commit messages, PR
bodies. Use commas, colons or parentheses.

Comments explain the reasoning behind the code.

## Before you open the PR

```sh
pnpm typecheck
pnpm lint
pnpm build
```
