feat: @bchen/ui v0.1.0 — dark-mode token palette and 16px base rule #2

Merged
brendan merged 2 commits from feat/v0.1.0-tokens-extraction into main 2026-05-14 01:02:13 +00:00
Owner

Summary

  • Bootstraps the @bchen/ui shared CSS package (public repo on gitea.bchen.dev)
  • Ships dist/tokens.css — the canonical dark-mode semantic-token palette (light :root + @media (prefers-color-scheme: dark) block), extracted from the cross-project dark-mode roll-out (inventory-canonical, cross-checked against authd and buchinese)
  • Ships dist/base.cssinput, textarea, select { font-size: 16px; } (the universal iOS focus-zoom prevention rule)
  • Tests: 9 assertions covering token presence in both light and dark scopes, WCAG AA contrast (≥4.5:1 for body text pairs, ≥3.0:1 for UI element pairs), and the 16px form-input rule
  • Release CI workflow (.gitea/workflows/release.yml): tag-triggered, runs npm test, validates CHANGELOG entry, runs security grep on dist/scripts/, attaches dist/ as release artifact

Closes #1

Security

Findings discovered in scope and how each was addressed:

  • dist/tokens.css and dist/base.css are pure CSS — no JS eval, no innerHTML, no script injection surface
  • release.yml includes an explicit dist/scripts/ security grep step (guards against XSS vectors in future script additions), gated with [ -d dist/scripts ] so it skips cleanly in v0.1.0
  • No secrets committed; GITEA_TOKEN is a Gitea CI secret reference
  • npm audit --omit=dev → 0 vulnerabilities in production deps

Consumer integration shape (documented in README)

# 1. package.json
"@bchen/ui": "git+ssh://git@gitea.bchen.dev:2222/brendan/bchen-ui.git#v0.1.0"

# 2. Dockerfile (after npm ci)
RUN cp -r node_modules/@bchen/ui/dist /app/public/vendor/bchen-ui

# 3. HTML
<link rel="stylesheet" href="/vendor/bchen-ui/tokens.css">
<link rel="stylesheet" href="/vendor/bchen-ui/base.css">

# 4. App CSS (loaded after vendor files)
<link rel="stylesheet" href="/style.css">

Out of scope (follow-up features)

  • Consumer migrations (authd, buchinese, dashcam, inventory, movement, nanodrop, firehose) — each is its own follow-up feature
  • Header chrome, form/button primitives, card primitive, SW skeleton, manifest template, login-redirect script — each is a follow-up after at least one consumer is on v0.1.0
  • npm registry migration (vs git-URL install)

Test plan

  • npm test — 9 tests across 2 files, all pass
  • Token presence in :root (light) + @media (prefers-color-scheme: dark) for all 17 tokens
  • WCAG AA contrast: --fg/--bg ≥4.5:1 light and dark; --fg-muted/--bg ≥4.5:1 light and dark; --border-strong/--bg ≥3.0:1 light and dark
  • dist/base.css 16px form-input rule assertion
  • npm audit --omit=dev → 0 vulnerabilities
  • Security review: no eval/innerHTML/script injection in dist/
  • Env-var gate: no new required env vars
  • Scope gate: no consumer migrations, no primitives beyond tokens, no build step

🤖 Generated with Claude Code (implementer tick)

## Summary - Bootstraps the `@bchen/ui` shared CSS package (public repo on gitea.bchen.dev) - Ships `dist/tokens.css` — the canonical dark-mode semantic-token palette (light `:root` + `@media (prefers-color-scheme: dark)` block), extracted from the cross-project dark-mode roll-out (inventory-canonical, cross-checked against authd and buchinese) - Ships `dist/base.css` — `input, textarea, select { font-size: 16px; }` (the universal iOS focus-zoom prevention rule) - Tests: 9 assertions covering token presence in both light and dark scopes, WCAG AA contrast (≥4.5:1 for body text pairs, ≥3.0:1 for UI element pairs), and the 16px form-input rule - Release CI workflow (`.gitea/workflows/release.yml`): tag-triggered, runs `npm test`, validates CHANGELOG entry, runs security grep on `dist/scripts/`, attaches `dist/` as release artifact Closes #1 ## Security Findings discovered in scope and how each was addressed: - `dist/tokens.css` and `dist/base.css` are pure CSS — no JS eval, no innerHTML, no script injection surface - `release.yml` includes an explicit `dist/scripts/` security grep step (guards against XSS vectors in future script additions), gated with `[ -d dist/scripts ]` so it skips cleanly in v0.1.0 - No secrets committed; `GITEA_TOKEN` is a Gitea CI secret reference - `npm audit --omit=dev` → 0 vulnerabilities in production deps ## Consumer integration shape (documented in README) ```sh # 1. package.json "@bchen/ui": "git+ssh://git@gitea.bchen.dev:2222/brendan/bchen-ui.git#v0.1.0" # 2. Dockerfile (after npm ci) RUN cp -r node_modules/@bchen/ui/dist /app/public/vendor/bchen-ui # 3. HTML <link rel="stylesheet" href="/vendor/bchen-ui/tokens.css"> <link rel="stylesheet" href="/vendor/bchen-ui/base.css"> # 4. App CSS (loaded after vendor files) <link rel="stylesheet" href="/style.css"> ``` ## Out of scope (follow-up features) - Consumer migrations (authd, buchinese, dashcam, inventory, movement, nanodrop, firehose) — each is its own follow-up feature - Header chrome, form/button primitives, card primitive, SW skeleton, manifest template, login-redirect script — each is a follow-up after at least one consumer is on v0.1.0 - npm registry migration (vs git-URL install) ## Test plan - [x] `npm test` — 9 tests across 2 files, all pass - [x] Token presence in `:root` (light) + `@media (prefers-color-scheme: dark)` for all 17 tokens - [x] WCAG AA contrast: `--fg/--bg` ≥4.5:1 light and dark; `--fg-muted/--bg` ≥4.5:1 light and dark; `--border-strong/--bg` ≥3.0:1 light and dark - [x] `dist/base.css` 16px form-input rule assertion - [x] `npm audit --omit=dev` → 0 vulnerabilities - [x] Security review: no eval/innerHTML/script injection in dist/ - [x] Env-var gate: no new required env vars - [x] Scope gate: no consumer migrations, no primitives beyond tokens, no build step 🤖 Generated with Claude Code (implementer tick)
brendan added 2 commits 2026-05-14 01:01:57 +00:00
- dist/tokens.css: canonical light + @media dark semantic-token palette
  extracted from inventory (cross-checked against authd and buchinese).
  Covers --fg, --fg-muted, --bg, --bg-elevated, --surface, --accent*,
  --danger*, --border*, --input-*, --warning, primitive --gray-* scale.
- dist/base.css: `input, textarea, select { font-size: 16px; }` prevents
  iOS Safari auto-zoom on focus.
- tests/tokens.test.ts: vitest — token presence in both light and dark
  blocks; WCAG AA contrast (>=4.5:1 body, >=3.0:1 UI) via inline
  hex-to-luminance math. All 10 tests green.
- tests/base.test.ts: vitest — asserts 16px rule covers all three selectors.
- .gitea/workflows/release.yml: tag-triggered CI — npm ci + npm test,
  CHANGELOG version gate, dist/scripts security grep, Gitea release
  artifact upload.
- README.md: four-step consumer integration guide with copy-pasteable
  snippets (package.json dep, Dockerfile cp, HTML link tags, app CSS).
- CHANGELOG.md: v0.1.0 entry.

npm audit --omit=dev: 0 vulnerabilities

Closes #1
- Collapse extractRootBlock + extractDarkBlock into a single extractBlock
  helper; the two functions shared identical body logic (same regex, same
  return) and differed only in the string they received — now the call
  sites pass the appropriate slice inline.
- Remove the second test in base.test.ts ("covers all three form control
  selectors in one rule"): the first test's regex already asserts all
  three selectors appear together with font-size: 16px, so the individual
  /input/, /textarea/, /select/ matches added no coverage.
brendan merged commit 68e6cc3b80 into main 2026-05-14 01:02:13 +00:00
Sign in to join this conversation.