chore: adding docs
This commit is contained in:
parent
23816d00f7
commit
81c5112409
39 changed files with 7257 additions and 2 deletions
125
data/docs/go-bananas-0005-shared-token-contract.md
Normal file
125
data/docs/go-bananas-0005-shared-token-contract.md
Normal file
|
|
@ -0,0 +1,125 @@
|
|||
<!-- go-doc:generated:begin source=go-bananas:docs/adr/0005-shared-token-contract.md signature=7d8b696ba971c1cbd2e19854d26de304 generated=2026-10-05 18:14 UTC -->
|
||||
Imported from docs/adr/0005-shared-token-contract.md in the go-bananas repository.
|
||||
|
||||
---
|
||||
|
||||
# ADR 0005: One token contract for every application, with a legacy alias layer
|
||||
|
||||
- **Status:** accepted
|
||||
- **Date:** 2026-10-05
|
||||
- **Revisit when:** an application adopts Tailwind v4 as its only styling mechanism, which
|
||||
would let the alias layer be dropped
|
||||
|
||||
## Context
|
||||
|
||||
Six applications consume design decisions today, each in its own dialect:
|
||||
|
||||
| Application | Mechanism | Palettes | Light/dark | Token indirection |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| `go-doc` | Tailwind v4 `@theme` | 1, dark hardcoded | none | `--color-ink-*` |
|
||||
| `go-guess` | one 2800-line CSS file | 1, light hardcoded | none | 11 `:root` vars, mostly bypassed by ~120 hardcoded hexes |
|
||||
| `go-loose` | plain CSS | 4 × 2 modes | works | `[data-theme=X]` + `[data-mode=light]` |
|
||||
| `go-mad` | plain CSS, copied from `go-loose` | 1 × 2 modes | CSS present, JS dead | `[data-mode=X]` |
|
||||
| `go-places` | JS-injected `<style>` | 2 objects | broken | inline custom properties |
|
||||
| `go-tell` | plain CSS, **no custom properties at all** | 4, all dark | none | 340 hardcoded hexes |
|
||||
|
||||
Four problems follow from that, and only one of them is aesthetic:
|
||||
|
||||
1. **No shared vocabulary.** `--navy` in `go-guess` and `--surface` in `go-loose` mean
|
||||
unrelated things, so nothing can be shared and no token can be changed in one place.
|
||||
2. **No light mode in three of six.** A theme is the wrong level of abstraction to fix
|
||||
this: the missing axis is *appearance*, and a theme that is dark-only cannot express
|
||||
it.
|
||||
3. **Two incompatible theme mechanisms.** `go-loose` sets `data-theme` and `data-mode`
|
||||
as separate attributes; `go-tell` sets `data-theme` only, with the mode baked into
|
||||
each palette. An application can adopt one or the other, not both.
|
||||
4. **Tailwind is a different language.** A Tailwind application cannot consume a
|
||||
`:root` block; it needs `@theme`.
|
||||
|
||||
The brief was to consolidate, find the middle ground, and make that styling available to
|
||||
every application.
|
||||
|
||||
## Decision
|
||||
|
||||
Adopt `go-loose`'s two-attribute model as the contract, because it is the only
|
||||
mechanism that is both working and already copied by another application:
|
||||
|
||||
```html
|
||||
<html data-theme="tokyo-night" data-mode="dark">
|
||||
```
|
||||
|
||||
Two orthogonal axes. `data-theme` is the palette, `data-mode` is the appearance. Every
|
||||
theme therefore has both a light and a dark rendering, which fixes problem 2 without
|
||||
inventing a second concept.
|
||||
|
||||
Token names are namespaced with `--bn-`, and the rendered stylesheet emits a **legacy
|
||||
alias block** underneath:
|
||||
|
||||
```css
|
||||
:root[data-theme='tokyo-night'][data-mode='dark'] {
|
||||
--bn-bg: #1a1b26;
|
||||
--bn-surface: #20222f;
|
||||
/* ... */
|
||||
}
|
||||
|
||||
/* Compatibility with applications that already use these names. */
|
||||
:root[data-theme='tokyo-night'][data-mode='dark'] {
|
||||
--bg: var(--bn-bg);
|
||||
--surface: var(--bn-surface);
|
||||
--text: var(--bn-text);
|
||||
--muted: var(--bn-muted);
|
||||
--line: var(--bn-border);
|
||||
--accent: var(--bn-accent);
|
||||
--good: var(--bn-good);
|
||||
--danger: var(--bn-danger);
|
||||
--radius: var(--bn-radius);
|
||||
}
|
||||
```
|
||||
|
||||
The alias block is the middle ground made literal. `go-loose` and `go-mad` keep working
|
||||
unchanged, and the other four applications can migrate by deleting their own `:root`
|
||||
block and renaming nothing.
|
||||
|
||||
## Rationale
|
||||
|
||||
**Namespaced names, because the stylesheet is injected into someone else's page.** An
|
||||
unprefixed `--surface` on a host page is a collision waiting to happen, and the host's
|
||||
value wins or loses depending on order. `--bn-bg` cannot collide with anything.
|
||||
|
||||
**Aliases, because a rename is a coordinated six-application change.** Emitting both
|
||||
means an application adopts the contract by adding one `<link>`, with no call sites
|
||||
edited. That is the difference between a migration that happens and one that is
|
||||
proposed.
|
||||
|
||||
**Two axes rather than N themes.** Six applications currently have 13 palettes between
|
||||
them, several of which are the same palette twice. Splitting palette from appearance
|
||||
turns 13 one-dimensional choices into 7 palettes × 2 modes, and makes "give me a light
|
||||
version" a solvable problem instead of a request for a new theme.
|
||||
|
||||
**Attributes, not classes.** `[data-theme=X]` beats `.theme-x` because an attribute is
|
||||
one axis for two features, and because a consumer can set it in the `<head>` before
|
||||
first paint. A class list forces the two axes into an ordering the cascade then has to
|
||||
be told about.
|
||||
|
||||
**`color-mix`, not extra tokens.** `go-loose` and `go-mad` already derive hover and
|
||||
subtle states with `color-mix(in srgb, var(--bn-accent) 12%, var(--bn-surface))`. That
|
||||
is kept: it means one accent serves every interaction state, instead of a hand-tuned
|
||||
ladder that drifts between themes.
|
||||
|
||||
**`--bn-font-*` and `--bn-radius` join the set.** Both applications that have a scale
|
||||
disagree (`go-loose` uses 16px cards, `go-mad` 8px; `go-doc` uses Tailwind defaults).
|
||||
Consolidation without them would leave typography and geometry app-local.
|
||||
|
||||
## Consequences
|
||||
|
||||
- The rendered stylesheet grows by the alias block. It is small, it is compressible, and
|
||||
it is removed entirely once an application has renamed its own references.
|
||||
- `go-doc` needs a three-line Tailwind bridge, because `@theme` cannot read a runtime
|
||||
custom property. It becomes `@theme inline { --color-bn-bg: var(--bn-bg) }`.
|
||||
- `go-tell`'s four themes are palettes with the appearance baked in. They become four
|
||||
`data-theme` values with their dark values as the `dark` mode, and their light
|
||||
counterparts have to be authored. That work is the honest cost of the migration.
|
||||
- Appearance preference is per-application. Two applications on the same browser do not
|
||||
share a `data-mode` unless they agree on a storage key; the shipped components use one
|
||||
key per origin and document it.
|
||||
<!-- go-doc:generated:end -->
|
||||
Loading…
Add table
Add a link
Reference in a new issue