Brendan Chen 6b06d00115 feat: add @bchen/ui v0.1.0 — dark-mode token palette and 16px base rule
- 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
2026-05-13 17:56:08 -07:00

@bchen/ui

Shared CSS tokens and UI components for the bchen.dev fleet.

What's included

Export Contents
@bchen/ui/tokens.css Semantic-token palette — light mode :root block + @media (prefers-color-scheme: dark) override
@bchen/ui/base.css input, textarea, select { font-size: 16px; } — prevents iOS Safari auto-zoom on focus

Consumer integration (four steps)

1. Add the dependency

// package.json
"dependencies": {
  "@bchen/ui": "git+https://gitea.bchen.dev/brendan/bchen-ui.git#v0.1.0"
}

Then run npm install (requires git in your build image — see Step 2).

2. Dockerfile — copy CSS to your public dir

After npm ci, copy the dist files into your served static directory so they're available at runtime without bundler involvement:

FROM node:24-alpine
RUN apk add --no-cache python3 make g++ git

WORKDIR /app
COPY package*.json ./
RUN npm ci

# Copy @bchen/ui dist files into public vendor dir
RUN mkdir -p public/vendor/@bchen/ui && \
    cp -r node_modules/@bchen/ui/dist/. public/vendor/@bchen/ui/

COPY . .
<head>
  <!-- vendor CSS first -->
  <link rel="stylesheet" href="/vendor/@bchen/ui/tokens.css">
  <link rel="stylesheet" href="/vendor/@bchen/ui/base.css">

  <!-- your app CSS after -->
  <link rel="stylesheet" href="/style.css">
</head>

4. App CSS — your overrides come after vendor

Your style.css can reference the tokens directly:

/* style.css — loaded after vendor, so tokens are already defined */
body {
  background: var(--bg);
  color: var(--fg);
  font-family: var(--font);
}

a { color: var(--accent); }
.muted { color: var(--fg-muted); }

Dark mode is automatic — no JavaScript required. The tokens.css @media (prefers-color-scheme: dark) block overrides the palette based on the OS setting.

Token reference

Primitive palette (resolve base values)

Token Light Dark
--black #000
--white #fff
--gray-50 #fafafa
--gray-100 #f0f0f0
--gray-200 #e0e0e0
--gray-400 #999
--gray-600 #555
--red #c00

Semantic color tokens

Token Light Dark
--fg #000 #e5e7eb
--fg-muted #555 #9ca3af
--bg #fff #0f1115
--bg-elevated #fafafa #1a1d23
--surface #fff #0f1115
--accent #000 #e5e7eb
--accent-fg #fff #0f1115
--accent-hover #555 #cbd5e1
--danger #c00 #f87171
--danger-fg #fff #0f1115
--danger-bg #fff5f5 rgba(248,113,113,0.12)
--warning #555
--border-color #e0e0e0 #374151
--border-strong #000 #6b7280
--border 1px solid #000 1px solid #6b7280

Input tokens

Token Light Dark
--input-bg #fff #1a1d23
--input-fg #000 #e5e7eb
--input-border #000 #6b7280
--input-bg-focus #fafafa #0f1115

WCAG contrast guarantees

All values in tokens.css are tested (see tests/tokens.test.ts) to meet:

  • AA body text (≥ 4.5:1): --fg/--bg, --fg-muted/--bg in both light and dark
  • UI elements (≥ 3.0:1): --border-strong/--bg in both light and dark

Changelog

See CHANGELOG.md.

Description
Shared CSS tokens + framework-less UI components for the bchen.dev fleet. Empty placeholder created during 2026-05-13 queue migration to host the v1 spec issue; first commit pending implementer pickup.
Readme 51 KiB
Languages
TypeScript 100%