asw/openspec/changes/repo-restructure/design.md
Ludo 5bf233348d
feat: add OpenSpec specs and changes for ASW restructure
Specs: repo-structure, 10 framework layer specs, packs, site.
Changes: repo-restructure (10 tasks), css-refactor (12 tasks),
legacy-import (proposal + triage categories).

Supersede docs/css-refactor-plan.md in favor of OpenSpec change.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 14:58:39 +02:00

4 KiB

Design: Repository Restructure

Current → Target Mapping

CURRENT                              TARGET
═══════                              ══════
assets/css/layers/*.css      ──▶     src/layers/*.css
assets/css/main.css          ──▶     src/main.css
(new)                        ──▶     src/lab/
static/asw.css               ──▶     dist/asw.css
(new)                        ──▶     dist/asw.min.css
static/vendor/               ──▶     vendor/open-props/
(new)                        ──▶     vendor/open-props/VERSION
(new)                        ──▶     vendor/README.md
content/                     ──▶     site/content/
layouts/                     ──▶     site/layouts/
archetypes/                  ──▶     site/archetypes/
hugo.toml                    ──▶     site/hugo.toml
static/ (non-vendor)         ──▶     site/static/
docs/                        ──▶     docs/  (stays, add new docs)
(new)                        ──▶     examples/
postcss.config.js            ──▶     postcss.config.js (updated paths)
package.json                 ──▶     package.json (stays at root)
node_modules/                ──▶     node_modules/ (stays at root)

Key Design Decisions

Hugo assets resolution

Hugo looks for assets/ relative to the site root. With Hugo files in site/, we need either:

  • Option A: site/assets/css/main.css that imports from ../../src/layers/ — fragile
  • Option B: Hugo module mount maps src/ into Hugo's asset pipeline — clean

Decision: Option B. Hugo config in site/hugo.toml:

[[module.mounts]]
  source = "static"
  target = "static"

[[module.mounts]]
  source = "../src"
  target = "assets/css"

[[module.mounts]]
  source = "../docs"
  target = "content/docs"

[[module.mounts]]
  source = "../vendor/open-props"
  target = "assets/css/open-props"

This way Hugo sees src/layers/ as assets/css/layers/ and src/main.css as assets/css/main.css — zero path changes in the CSS files themselves.

Vendor directory

vendor/
  open-props/
    open-props.min.css
    media.min.css
    VERSION                 ← "1.7.x (npm open-props@1.7.x, vendored 2025-xx-xx)"
  README.md                 ← "How to update: npm update open-props && cp ..."

npm install still works for the build toolchain. vendor/ is the inspectable, committed copy with version tracking. The build reads from node_modules/ (PostCSS import resolution), but agents and humans can read vendor/ to understand what Open Props provides.

dist/ generation

dist/asw.css is built by PostCSS from src/main.css:

npx postcss src/main.css -o dist/asw.css
npx postcss src/main.css -o dist/asw.min.css  # with cssnano

Committed to repo. Consumers grab dist/asw.css without needing npm/PostCSS.

examples/ structure

examples/
  components/       ← buttons, forms, callouts, dialogs
  layout/           ← docs layout, grid, prose, timeline
  charts/           ← chart showcases
  vault/            ← vault note rendering examples

Each HTML file is standalone: <link rel="stylesheet" href="../dist/asw.css">. Open in browser, no build step.

dev workflow

dev.sh (or its successor) runs from project root:

  1. Watches src/layers/ for changes
  2. Processes individual layers → somewhere Hugo can serve them (for devtools visibility)
  3. Runs hugo server with working directory site/

The key change: Hugo is invoked as hugo server --source site/ or from within site/.

What Stays at Root

asw/
  package.json              ← build tooling (PostCSS, Open Props)
  postcss.config.js         ← production PostCSS config
  postcss.dev.config.js     ← dev PostCSS config
  node_modules/             ← npm packages (gitignored)
  .gitignore
  README.md
  LICENSE
  openspec/

Build tooling stays at root because it serves both dist/ (framework build) and site/ (dev server). It's a project-level concern, not framework or site.