From 69a68443247b92761c068bb7e792b32befec06a0 Mon Sep 17 00:00:00 2001 From: Arthur Belleville Date: Sun, 10 May 2026 10:42:13 +0200 Subject: [PATCH] docs: add css-sources-per-primitive design spec --- ...ackend-css-sources-per-primitive-design.md | 162 ++++++++++++++++++ 1 file changed, 162 insertions(+) create mode 100644 docs/superpowers/specs/2026-05-10-go-backend-css-sources-per-primitive-design.md diff --git a/docs/superpowers/specs/2026-05-10-go-backend-css-sources-per-primitive-design.md b/docs/superpowers/specs/2026-05-10-go-backend-css-sources-per-primitive-design.md new file mode 100644 index 0000000..cb046f0 --- /dev/null +++ b/docs/superpowers/specs/2026-05-10-go-backend-css-sources-per-primitive-design.md @@ -0,0 +1,162 @@ +# Go Backend CSS Sources Per Primitive Design + +**Date:** 2026-05-10 + +**Goal** + +Refactor the Go backend design-system CSS so each UI primitive owns its own source stylesheet while the app and generated catalog continue shipping a single compiled `go-backend/static/styles.css`. + +**Chosen Approach** + +Split CSS at the source level by primitive and aggregate those source files into the existing `styles.css` output during the build. This keeps runtime behavior unchanged while making the CSS easier to scale, review, and extend. + +**Scope** + +- Move shared design-system CSS rules into source files organized by primitive. +- Keep one final shipped stylesheet: `go-backend/static/styles.css`. +- Keep app templates and generated design-system pages linking the same single output file. +- Add a small verification layer that proves the final built stylesheet still contains representative selectors for the primitives. + +**Out Of Scope** + +- Shipping multiple CSS files to the browser +- Changing component HTML contracts just to fit the refactor +- Replacing the current Tailwind pipeline +- Reworking unrelated dashboard or app styles outside the design-system slice +- Introducing CSS-in-JS or Go-generated CSS + +**Architecture** + +The design-system CSS should have two layers: + +1. **Primitive source files** + - one file per UI primitive or catalog responsibility + - these files are the new source of truth for design-system styling + +2. **Aggregate build entry** + - a single stylesheet entry imports those primitive files in a deterministic order + - the build continues emitting `go-backend/static/styles.css` + +This preserves the current runtime contract: + +- app pages still load `/static/styles.css` +- generated catalog pages still load `../../go-backend/static/styles.css` + +**Source File Structure** + +Recommended source directory: + +- `go-backend/static/css/catalog.css` +- `go-backend/static/css/button.css` +- `go-backend/static/css/badge.css` +- `go-backend/static/css/icon-button.css` +- `go-backend/static/css/input.css` +- `go-backend/static/css/form-field.css` +- `go-backend/static/css/modal.css` +- `go-backend/static/css/table.css` +- `go-backend/static/css/empty-state.css` +- `go-backend/static/css/card.css` +- `go-backend/static/css/spacing.css` + +Recommended aggregate entry: + +- `go-backend/static/css/styles.css` + +The aggregate entry should import the primitive files in a stable order so later files can intentionally override earlier shared primitive rules where needed. + +**Responsibility Boundaries** + +`catalog.css` + +- catalog page chrome +- catalog example wrappers +- catalog-only preview helpers + +Primitive CSS files + +- only selectors directly tied to that primitive’s API or rendering contract +- examples: + - `button.css` owns `.ui-button*` + - `badge.css` owns `.ui-badge*` + - `icon-button.css` owns `.ui-icon-button*` and `.borderless-icon-button*` + - `card.css` owns `.ui-card*` + - `spacing.css` owns `.ui-space-*` + +Shared non-design-system app selectors such as dashboard-only `.project-*` styles should not be mixed into primitive CSS just because they are nearby in the current file. If they must remain in this refactor slice, they should be isolated intentionally rather than silently attached to a primitive that does not own them. + +**Build Contract** + +The build should continue producing: + +- `go-backend/static/styles.css` + +Preferred shape: + +- the build reads the new aggregate source entry +- the output path remains unchanged + +If the current tooling expects a specific input file location, update that input path rather than changing all HTML consumers. + +**Ordering Rules** + +Import order should be explicit and stable: + +1. catalog layout and wrappers +2. low-level primitives used broadly +3. higher-level primitives +4. any intentionally shared compatibility rules last + +This avoids accidental cascade regressions during future additions. + +**Migration Strategy** + +Refactor incrementally but land as one coherent slice: + +- create the new source directory and aggregate entry +- move selectors from the monolithic stylesheet into primitive files without renaming selectors +- regenerate `go-backend/static/styles.css` +- verify component tests and catalog generation still pass + +Selector names should remain stable during this slice. The purpose is ownership and scalability, not visual redesign. + +**Testing** + +Verification should cover: + +- UI tests still passing for existing primitives +- catalog tests still passing +- design-system generator tests still passing +- representative selectors from each extracted primitive still present in the built `styles.css` + +Representative examples: + +- `.ui-button-solid.ui-button-default` +- `.ui-badge-warning` +- `.ui-icon-button-solid.ui-icon-button-neutral` +- `.ui-card` +- `.ui-space-x-md` +- `.catalog-page` + +**Risks** + +Primary risks: + +- breaking cascade order while moving selectors +- accidentally mixing app-only selectors into primitive files +- changing build inputs without regenerating the checked-in output + +Mitigation: + +- keep selectors unchanged +- move files in clearly bounded groups +- verify the built artifact and tests after the refactor + +**Success Criteria** + +This work is complete when: + +- each design-system primitive has its own source CSS file +- catalog-specific CSS is separated from primitive CSS +- the app still ships one `go-backend/static/styles.css` +- app and catalog HTML consumers remain unchanged +- tests and generated catalog output still pass