asw/openspec/changes/asw-v01-release/design.md
B.A. Baracus a433b935fa
asw-v01: drop OpenProps, native CSS tokens system
- Replace OpenProps (~25KB) with native src/tokens.css (~40 tokens)
- Remove open-props, postcss-import from package.json + postcss.config
- Update main.css: remove @import open-props/*, import ./tokens.css
- Rewrite 01-tokens.css header to reference tokens.css
- All raw OpenProps values (font stacks, sizes, weights, colors,
  easings, durations, shadows, radii, animations, media queries)
  now defined natively in tokens.css
- Build uses cat concat + cssnano (no postcss-import needed)
- Build output: 78KB minified (saved ~24KB from OpenProps removal)
2026-06-07 10:43:34 +02:00

5.9 KiB

Context

ASW is a classless CSS framework for AI agents. The framework itself is working — semantic HTML + data-attributes are styled correctly across 13 CSS layers. But it's bundled with OpenProps (~25KB overhead, ~40 of 500+ tokens actually used), wrapped in a Hugo documentation site, and has no publishable templates (current examples use SSI <!--#include-->).

The repo has three unshipped development concerns (engine packs, lab experiments, Hugo site) mixed into the root alongside the framework source. For 0.1, these are deferred — moved to archive/ but never deleted.

Goals / Non-Goals

Goals:

  • Replace OpenProps with a hand-authored native CSS token system (~4KB)
  • Remove open-props npm dependency and PostCSS import
  • Move non-0.1 content into archive/ directory
  • Create 5-6 standalone working HTML templates
  • Rewrite README for 0.1 publication
  • Tag v0.1 on git

Non-Goals:

  • Documentation site (0.2)
  • Engine packs (0.3)
  • CSS layer refactoring (cosmetic renames can happen but aren't required)
  • New CSS features beyond the token replacement
  • Backward compatibility with OpenProps-based custom themes

Decisions

D1: Native CSS token system over OpenProps

Decision: Replace @import "open-props/open-props.min.css" with a single src/tokens.css file defining ~40 CSS custom properties using oklch() and relative color syntax. Remove open-props from package.json. Remove postcss-import from the build chain.

BEFORE:                     AFTER:
@import "open-props/..."    →  (removed)
var(--size-3)               →  1rem
var(--gray-0)               →  oklch(0.95 0.01 250)
var(--ease-3)               →  var(--ease-out-quad) [or concrete cubic-bezier]
var(--font-mono)            →  'Fira Code', 'Cascadia Code', monospace

Rationale:

  • ASW uses ~40 of 500+ OpenProps tokens — 85% dead weight shipped to every page
  • Native CSS (oklch(), light-dark(), color-mix(), relative color syntax) now covers every use case OpenProps was providing
  • Eliminates an external dependency and the postcss-import build step
  • The ~40 values are trivially derivable — font stacks, size scales, and gray steps are design constants, not secrets
  • MIT license on OpenProps allows verbatim value copying where useful

Alternatives considered:

  • Keep OpenProps: Still works, but 25KB tax for no marginal benefit
  • Terrazzo/DTCG: Full design-token toolchain is overkill for a project that needs ~40 values
  • Style Dictionary v4: Enterprise-grade, too heavy for a CSS-only framework

D2: In-place archive pattern for deferred content

Decision: Move packs/, site/, and src/lab/ into archive/ at repo root. No files deleted. No orphan branches. Everything remains in git history.

asw/
├── src/                  # Framework CSS (active)
├── templates/            # Standalone HTML templates (new)
├── dist/                 # Built CSS
├── docs/                 # Engine-agnostic docs
├── archive/              # Deferred for 0.2/0.3
│   ├── packs/            # Engine integrations
│   ├── site/             # Hugo documentation website
│   └── lab/              # Experiments
├── openspec/
├── README.md
└── CHANGELOG.md

Rationale:

  • Single repo, single URL, single git history
  • archive/ is a clear signal: "these exist but are not 0.1"
  • Easy to restore when 0.2/0.3 come: git mv archive/packs/ ./
  • No git history surgery, no divergence between branches

D3: Flexbox layout system via data-attributes

Decision: The 0.1 template system uses semantic HTML + data-layout attributes for flexbox layouts. No grid. No classes. No wrappers.

data-layout="row"       →  display: flex; flex-direction: row
data-layout="col"       →  display: flex; flex-direction: column
data-layout="spread"    →  display: flex; justify-content: space-between
data-layout="center"    →  display: flex; align-items: center; justify-content: center
data-layout="stack"     →  display: flex; flex-direction: column; gap: var(--space-4)
data-layout="grid-2"    →  display: grid; grid-template-columns: repeat(2, 1fr)  (kept from existing)
data-layout="grid-3"    →  display: grid; grid-template-columns: repeat(3, 1fr)  (kept from existing)

Rationale:

  • Flexbox over grid for the 0.1 layouts (simpler, better for content-flow patterns like nav, hero, footer, sidebar+content)
  • Keeps the existing data-layout="grid-2/3" patterns from the current framework (they work, no need to change)
  • Self-documenting: data-layout="spread" is readable by both humans and agents

D4: PostCSS stays for minification only

Decision: Keep PostCSS + cssnano for minification. Remove postcss-import and open-props. Build script becomes:

postcss src/main.css -o dist/asw.css --no-import

Or, if all imports are removed from src/main.css, simplify to just cssnano on the single file.

Rationale:

  • Minification is still valuable for distribution
  • No more build-time dependency on OpenProps or CSS import resolution
  • Future: could eliminate PostCSS entirely and use lightningcss or just ship unminified

Risks / Trade-offs

Risk Mitigation
oklch values don't match OpenProps grays exactly OpenProps uses sRGB hex. oklch gray values are perceptually different. Visual regression acceptable — 0.1 is a new baseline, not a patch.
Users who customized ASW via OpenProps overrides will break 0.1 is a new baseline. Document breaking change in CHANGELOG. There are no known external users yet.
archive/ dir grows stale and confusing Each future release (0.2, 0.3) explicitly pulls from archive/. If stuff remains archived two releases, evaluate deletion.
PostCSS removal may need re-evaluation If cssnano is the only plugin, consider swapping to lightningcss (Rust-based) or just shipping unminified with a gzip note. Defer to 0.2.