feat: initial shared design system extracted from newerror

Foundation + chrome for the bchen.dev static sites: design tokens, Spectral /
Helvetica / IBM Plex Mono type, base + .prose typography, data-driven nav +
footer, and prefers-color-scheme + [data-theme] dark mode with a pre-paint
init. Colors are overridable CSS custom properties (defaults = newerror's
palette); each site sets only its own colors.css.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01C96hwEU9cM7mJpqATiv7R5
This commit is contained in:
2026-06-30 21:20:21 -04:00
commit b61cb986f1
7 changed files with 584 additions and 0 deletions

110
README.md Normal file
View File

@@ -0,0 +1,110 @@
# static-design-system
Shared visual foundation for the bchen.dev static (Jekyll) sites. The canonical
design is **A New Error** (newerror.bchen.dev) — Spectral serif body, Helvetica
sans UI, IBM Plex Mono. Every site shares fonts, spacing, typography,
nav/footer chrome, and light/dark behavior, and keeps **only its own colors**.
## What's here
| File | Purpose |
|---|---|
| `base.css` | Tokens, font stacks, base + `.prose` typography, `.nav`/`.foot` chrome, mobile menu, icon swaps. Colors are CSS custom properties with defaults; sites override them. |
| `theme-init.js` | Pre-paint theme read (inlined in `<head>`, no flash). |
| `theme-toggle.js` | Theme-toggle + mobile-menu behavior (served + loaded at end of body). |
| `head.html` | Shared `<head>` contents (meta/OG, fonts, CSS links, inlined theme-init). |
| `nav.html` | Data-driven nav + mobile menu. |
| `footer.html` | Shared footer. |
Blog-specific components (ledger feed, archive, reader/prose-article chrome)
are **not** here — they live in newerror's own repo.
## Consuming it in a Jekyll site
This is designed for **legacy GitHub Pages** (Jekyll in safe mode: no custom
plugins, no symlinks). The trick is to mount this repo as a submodule *inside*
`_includes/` and deliver CSS/JS through tiny served wrapper files.
1. **Add the submodule at `_includes/ds`** (use the read-only **https** URL — a
legacy Pages build cannot fetch ssh submodules):
```sh
git submodule add https://gitea.bchen.dev/brendan/static-design-system.git _includes/ds
```
2. **Serve the CSS** — create `assets/ds.css`:
```liquid
---
---
{% include ds/base.css %}
```
3. **Serve the JS** — create `assets/ds.js`:
```liquid
---
---
{% include ds/theme-toggle.js %}
```
4. **Add your palette** — create `assets/colors.css` overriding only the color
tokens (`--bg --ink --muted --faint --rule --rule-2 --accent --accent-hover
--field`) for light, `:root[data-theme="dark"]`, and the
`prefers-color-scheme: dark` block. This loads *after* `ds.css`.
5. **Nav links** — create `_data/nav.yml`:
```yaml
- title: Guides
url: /guides
- title: FAQ
url: /support
```
6. **Layout** — in `_layouts/default.html`:
```liquid
<!DOCTYPE html>
<html lang="en">
<head>{% include ds/head.html %}</head>
<body>
<div class="page">
<div class="shell">{% include ds/nav.html %}</div>
<main><div class="shell">
{% if page.prose %}<div class="prose">{{ content }}</div>{% else %}{{ content }}{% endif %}
</div></main>
<div class="shell">{% include ds/footer.html %}</div>
</div>
<script src="/assets/ds.js"></script>
</body>
</html>
```
Add `prose: true` to the front matter of markdown content pages to get the
shared `.prose` typography; leave it off for bespoke landing pages.
## Config keys the includes read
| Key | Used by | Notes |
|---|---|---|
| `site.title` | nav mast, head | |
| `site.description`, `site.author`, `site.url` | head meta | |
| `site.data.nav` | nav | list of `{ title, url }` |
| `site.rss_url` | nav | optional; shows an RSS link when set |
| `site.author_url` | footer | optional; links the author name |
| `site.footer_years` | footer | optional; e.g. `20252026` |
## Notes / gotchas
- **Push over ssh, reference over https.** Consuming sites' `.gitmodules` must
use the https URL for the Pages build to fetch it; you can still push here
over ssh.
- **Keep `base.css` / the `.js` files Liquid-safe** — no `{{` or `{%`
sequences, since their contents pass through the Jekyll include tag.
- **Build-time dependency:** a consuming site's build now depends on
`gitea.bchen.dev` being reachable (public, valid TLS).
- **Local dev:** clone consumers with `--recurse-submodules`, or run
`git submodule update --init` after cloning.
- **Versioning:** tags (`v1`, `v2`, …) mark known-good states; a consuming
site pins a commit and bumps deliberately.