diff --git a/docs/css-refactor-plan.md b/docs/css-refactor-plan.md index 5606ee1..ada2b2b 100644 --- a/docs/css-refactor-plan.md +++ b/docs/css-refactor-plan.md @@ -1,5 +1,7 @@ # CSS Layer Refactor Plan +> **Superseded by:** `openspec/changes/css-refactor/` — this document is kept as historical reference. Agents should read the OpenSpec change tasks, not this file. + **Project:** ASW — Agentic Semantic Web **Goal:** Restructure CSS layers to clean architecture, alias all Open Props primitives through `01-tokens.css`, redistribute misplaced content, remove unused values. **Method:** One atomic step per agent session. Build check after every step. No step touches more than two files. diff --git a/openspec/changes/css-refactor/proposal.md b/openspec/changes/css-refactor/proposal.md new file mode 100644 index 0000000..4434b83 --- /dev/null +++ b/openspec/changes/css-refactor/proposal.md @@ -0,0 +1,60 @@ +# Proposal: CSS Layer Refactor + +## Intent + +Restructure CSS layers to clean architecture: alias all Open Props primitives through `01-tokens.css`, split the monolithic `03-components.css` into purpose-specific files, redistribute misplaced content, and rename files to match their actual responsibilities. + +**Goal: each CSS file has a single clear purpose, and no file references Open Props primitives directly.** + +This plan was originally documented in `docs/css-refactor-plan.md` and is imported here as an OpenSpec change for tracking and execution. + +## Scope + +### In Scope +- Add missing semantic aliases to token file (~10 new aliases) +- Extract editorial rules out of token file into their proper layers +- Rename `01-asw.css` → `01-tokens.css` (pure tokens, no rules) +- Fix all Open Props primitive leaks across all layers +- Split `03-components.css` into: `03-landmarks.css`, `04-forms.css`, slimmed `05-components.css`, `06-navigation.css` +- Rename all files to final numbering scheme +- Merge `08a-essay.css` into layout layer +- Audit and remove unused tokens + +### Out of Scope +- New CSS features or components +- Layout changes +- Content changes +- Repo restructure (separate change, happens first) + +### Current → Target Layer Map + +``` +CURRENT TARGET +═══════ ══════ +00-reset.css 00-reset.css (unchanged) +01-asw.css ──▶ 01-tokens.css (pure :root, no rules) +02-semantic.css ──▶ 02-typography.css +03-components.css ──▶ 03-landmarks.css (nav, article, footer, hgroup) + ──▶ 04-forms.css (inputs, buttons, selects) + ──▶ 05-components.css (dialog, accordion, breadcrumb) + ──▶ 06-navigation.css (sidebar, TOC) +04-data-attrs.css ──▶ 07-data-attrs.css +05-utilities.css ──▶ 08-utilities.css +06-charts.css ──▶ 09-charts.css +07-chroma.css ──▶ 10-chroma.css +08-layout.css + 08a-essay ──▶ 11-layout.css (merged) +09-landing.css ──▶ 12-landing.css +``` + +## Approach + +One atomic step per session. Build check after every step. No step touches more than two files. Full plan in `docs/css-refactor-plan.md`. + +## Prerequisites + +- **Depends on:** `repo-restructure` (files must be in `src/layers/` first) + +## Risks + +- **Visual regression** — mitigated by build + visual check after each step +- **Specificity changes** — layer reordering could affect cascade. Mitigated by keeping relative order. diff --git a/openspec/changes/css-refactor/tasks.md b/openspec/changes/css-refactor/tasks.md new file mode 100644 index 0000000..6ce3e63 --- /dev/null +++ b/openspec/changes/css-refactor/tasks.md @@ -0,0 +1,94 @@ +# Tasks: CSS Layer Refactor + +Imported from `docs/css-refactor-plan.md`. Each step = one agent session. + +**Prerequisite:** `repo-restructure` change must be complete. All files in `src/layers/`. + +--- + +## Task 1 — Add missing aliases to token file +**Files:** `src/layers/01-asw.css` (pre-rename) +**Action:** Add semantic aliases for `--font-weight-N`, `--shadow-N`, `--border-size-2`, `--size-px-12`, and `--space-5a` gap. +**Acceptance:** Build passes. No visual change. New aliases exist in `:root`. + +--- + +## Task 2 — Extract editorial rules from token file +**Files:** `src/layers/01-asw.css`, `src/layers/08-layout.css` +**Action:** Move `body > nav` padding rule to `03-components.css`. Move `[data-layout="docs"] > article` max-width to `08-layout.css`. Token file becomes pure `:root` only. +**Acceptance:** Build passes. Nav centering and docs prose width unchanged. + +--- + +## Task 3 — Rename `01-asw.css` → `01-tokens.css` +**Files:** `src/layers/01-asw.css`, `src/main.css` +**Action:** Rename file, update `@import`. +**Acceptance:** Build passes. + +--- + +## Task 4 — Fix primitive leaks in `03-components.css` +**Files:** `src/layers/03-components.css` +**Action:** Replace all `--font-weight-N`, `--size-N`, `--shadow-N`, `--border-size-N` with semantic aliases. +**Acceptance:** Build passes. No visual change. + +--- + +## Task 5 — Fix primitive leaks in `06-charts.css` +**Files:** `src/layers/06-charts.css` +**Action:** Replace `--size-1/2/3` with `--space-1/2/4`. +**Acceptance:** Build passes. Charts render unchanged. + +--- + +## Task 6 — Fix primitive leaks in remaining files +**Files:** `src/layers/02-semantic.css`, `src/layers/07-chroma.css`, `src/layers/08-layout.css`, `src/layers/09-landing.css` +**Action:** Replace all remaining `--font-weight-N`, `--size-N` primitives with semantic aliases. +**Acceptance:** Build passes after each file. + +--- + +## Task 7 — Create `03-landmarks.css`, extract from `03-components.css` +**Files:** `src/layers/03-components.css`, new `src/layers/03-landmarks.css`, `src/main.css` +**Action:** Move landmark sections (nav, article, dt/dd, section, hgroup, footer) to new file. +**Acceptance:** Build passes. All landmark styles render unchanged. + +--- + +## Task 8 — Create `04-forms.css`, extract from `03-components.css` +**Files:** `src/layers/03-components.css`, new `src/layers/04-forms.css`, `src/main.css` +**Action:** Move buttons and form elements to new file. +**Acceptance:** Build passes. + +--- + +## Task 9 — Create `06-navigation.css`, extract from `03-components.css` +**Files:** `src/layers/03-components.css`, new `src/layers/06-navigation.css`, `src/main.css` +**Action:** Move sidebar nav and TOC sections to new file. +**Acceptance:** Build passes. Sidebar and TOC render unchanged. + +--- + +## Task 10 — Rename files to final numbering + merge essay +**Files:** All layer files, `src/main.css` +**Action:** Rename to final numbers (see proposal layer map). Merge `08a-essay.css` into `11-layout.css`. Update all `@import` statements. +**Acceptance:** Build passes. + +--- + +## Task 11 — Audit unused tokens +**Files:** `src/layers/01-tokens.css` +**Action:** Build CSS, grep for token usage, diff defined vs used. Remove confirmed unused. +**Acceptance:** Build passes. Spot-check 3-4 pages visually. + +--- + +## Task 12 — Fix HTML template issues from sidebar/TOC refactor +**Files:** `site/layouts/docs/single.html`, `site/layouts/notes/single.html` (post-restructure paths) +**Action:** From `docs/css-html-cleanup-todo.md`: +- Remove redundant `nav[data-nav="sidebar"] ul li { margin: 0; padding: 0 }` resets (if not already caught in Tasks 7/9) +- Remove redundant `aside[data-toc] nav ul li { margin: 0; padding: 0 }` resets (if not already caught in Tasks 7/9) +- Replace `← Previous` / `Next →` with appropriate element in prev/next footer +- Remove `role="main"` from `
` in docs single layout +- Move hardcoded `"On this page"` string to Hugo i18n or site param +**Acceptance:** Build passes. Prev/next links render correctly. TOC heading uses i18n string. No `role="main"` on `
`. diff --git a/openspec/changes/legacy-import/proposal.md b/openspec/changes/legacy-import/proposal.md new file mode 100644 index 0000000..d18070a --- /dev/null +++ b/openspec/changes/legacy-import/proposal.md @@ -0,0 +1,78 @@ +# Proposal: Legacy Import + +## Intent + +Import valuable material from `agentic-semantic-web/` (legacy repo) into the restructured `asw/` repo. The legacy repo was the standalone single-file version of ASW. It contains packs, templates, examples, lab experiments, error pages, and documentation that belong in the current repo. + +**Goal: everything worth keeping lives in `asw/`. Legacy repo is archived.** + +## Scope + +### Triage Categories + +Material from `agentic-semantic-web/` falls into: + +**Import as-is:** +- `packs/apache/` → `packs/apache/` +- `packs/caddy/` → `packs/caddy/` +- `packs/flask/` → `packs/flask/` +- `packs/nginx/` → `packs/nginx/` +- `packs/pandoc/` → `packs/pandoc/` +- `packs/python/` → `packs/python/` +- `packs/hugo/` → `packs/hugo/` (base Hugo pack) +- `errors/` → `packs/` (distributed to relevant packs, or shared errors dir) +- `LICENSE` + +**Import and adapt:** +- `examples/` → `examples/` (update CSS paths to `dist/asw.css`) +- `templates/` → review, merge into packs or docs +- `llms.txt` → `docs/llms.txt` (update for current state) +- `content/vocabulary.md` → `docs/vocabulary.md` +- `content/philosophy.md` → `docs/` (may already exist) +- `content/agent-directive.md` → `docs/` or merge into existing docs +- `themes/` → `src/themes/` or `examples/themes/` (needs decision) + +**Import as reference/lineage:** +- `openspec/changes/pico-absorption/` → content for `docs/lineage.md` +- `content/architecture.md`, `content/design-tokens.md` → inform specs, don't import verbatim +- `MISSION_REPORT.md`, `SIZE_AUDIT.md` → historical, extract lessons into lineage + +**Do not import:** +- `dist/agentic.css` — superseded by `dist/asw.css` +- `agentic.css` (root) — old entry point +- `src/layers/` — superseded by current `src/layers/` +- `build.sh`, `migrate-tokens.sh` — legacy build tools +- `web-fonts.css` — evaluate if still needed +- `lib/open-props/` — replaced by `vendor/open-props/` +- `lab/hugo-demo/` — superseded by `site/` +- `.pi/` — agent config, not framework material +- `index.html` — legacy landing page + +**Needs triage decision:** +- `lab/` (non-Hugo) — some experiments may be worth keeping in `src/lab/` +- `docs/missions/` — historical mission reports, lineage value? +- `content/charts-css-exploration.md` — inform charts spec? +- `content/architecture-research.md` — inform design decisions? + +### Out of Scope +- Modifying imported CSS (that's the css-refactor change) +- Creating new content +- Archiving the legacy repo (separate operational task) + +## Prerequisites + +- **Depends on:** `repo-restructure` (directories must exist first) + +## Approach + +1. Triage: review each directory/file, confirm category +2. Import packs (bulk, low risk) +3. Import examples (need path updates) +4. Import docs (need review/merge) +5. Write `docs/lineage.md` from pico-absorption and historical material +6. Final audit: nothing valuable left behind + +## Risks + +- **Stale content** — legacy material references `agentic.css`, old paths, old URLs. All imported material needs path/name updates. +- **Duplication** — some legacy content already exists in ASW in evolved form. Need careful merge, not overwrite. diff --git a/openspec/changes/repo-restructure/design.md b/openspec/changes/repo-restructure/design.md new file mode 100644 index 0000000..f6520ec --- /dev/null +++ b/openspec/changes/repo-restructure/design.md @@ -0,0 +1,115 @@ +# 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`: +```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`: +```bash +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: ``. 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. diff --git a/openspec/changes/repo-restructure/proposal.md b/openspec/changes/repo-restructure/proposal.md new file mode 100644 index 0000000..f907cc4 --- /dev/null +++ b/openspec/changes/repo-restructure/proposal.md @@ -0,0 +1,42 @@ +# Proposal: Repository Restructure + +## Intent + +The ASW repo currently has a flat Hugo-centric layout where framework source, website content, and build tooling are interleaved. This restructure separates the framework (`src/`), its documentation (`docs/`), its engine integrations (`packs/`), its built output (`dist/`), its dependencies (`vendor/`), and its website (`site/`) into clearly bounded directories. + +**Goal: anyone landing on this repo immediately understands what ASW is and where things live.** + +## Scope + +### In Scope +- Move `assets/css/layers/` → `src/layers/` +- Move `assets/css/main.css` → `src/main.css` +- Create `dist/` at root for built output (`asw.css`, `asw.min.css`) +- Create `vendor/open-props/` with vendored copies + VERSION file +- Move Hugo files (`content/`, `layouts/`, `hugo.toml`, `archetypes/`) → `site/` +- Configure Hugo module mount: `docs/` → `site/content/docs/` +- Restructure `docs/` as engine-agnostic markdown (already mostly there) +- Create `src/lab/` for experiments +- Create `examples/` at root for static HTML showcases +- Update build paths in `postcss.config.js` and `package.json` + +### Out of Scope +- CSS refactor (separate change, works on `src/layers/` after this) +- Legacy repo import (separate change, lands material after this) +- Content writing or new docs +- New pack creation + +## Approach + +Incremental moves with build verification after each step. The site must remain buildable and deployable throughout. + +## Risks + +- **Hugo path breakage** — Hugo has opinions about where `assets/` lives. Module mounts should handle this but need testing. +- **Deploy script breakage** — `deploy.sh` hardcodes paths. Will need updating (or removal if temporary). +- **Symlink/mount complexity** — `docs/` → `site/content/docs/` via Hugo mount is clean but adds config complexity. + +## Files Touched + +Primary: `assets/css/`, `content/`, `layouts/`, `hugo.toml`, `postcss.config.js`, `package.json` +Created: `src/`, `dist/`, `vendor/`, `site/`, `examples/`, `src/lab/` diff --git a/openspec/changes/repo-restructure/tasks.md b/openspec/changes/repo-restructure/tasks.md new file mode 100644 index 0000000..bb6282e --- /dev/null +++ b/openspec/changes/repo-restructure/tasks.md @@ -0,0 +1,115 @@ +# Tasks: Repository Restructure + +## Task 1 — Create directory skeleton +**Files:** (new directories only) +**Action:** +- Create `src/`, `src/layers/`, `src/lab/` +- Create `dist/` +- Create `vendor/open-props/` +- Create `site/` +- Create `examples/` +**Acceptance:** Directories exist. No files moved yet. Build still passes from current layout. + +--- + +## Task 2 — Move CSS source to src/ +**Files:** `assets/css/layers/*.css` → `src/layers/`, `assets/css/main.css` → `src/main.css` +**Action:** +- `git mv assets/css/layers/ src/layers/` +- `git mv assets/css/main.css src/main.css` +- Update `@import` paths in `src/main.css` if needed (should be relative, likely unchanged) +**Acceptance:** `src/layers/` contains all 11 CSS files. `src/main.css` imports them. `assets/css/` is gone. +**Note:** Site will be temporarily broken until Hugo mounts are configured (Task 5). + +--- + +## Task 3 — Set up vendor/ +**Files:** `vendor/open-props/`, `vendor/README.md` +**Action:** +- Copy `node_modules/open-props/open-props.min.css` → `vendor/open-props/` +- Copy `node_modules/open-props/media.min.css` → `vendor/open-props/` +- Create `vendor/open-props/VERSION` with package version and date +- Create `vendor/README.md` explaining what's vendored and how to update +- Remove `static/vendor/` (old location) +**Acceptance:** `vendor/open-props/` contains the two CSS files + VERSION. `static/vendor/` is gone. + +--- + +## Task 4 — Move Hugo files to site/ +**Files:** `content/`, `layouts/`, `archetypes/`, `hugo.toml`, `hugo_stats.json` +**Action:** +- `git mv content/ site/content/` +- `git mv layouts/ site/layouts/` +- `git mv archetypes/ site/archetypes/` +- `git mv hugo.toml site/hugo.toml` +- `git mv hugo_stats.json site/hugo_stats.json` +- Move site-specific static files: `static/palette-test.html` → `site/static/` +- Move `static/asw.css` → `dist/asw.css` (this is the built output) +**Acceptance:** All Hugo content/layout/config files are in `site/`. Root has no Hugo files. + +--- + +## Task 5 — Configure Hugo module mounts +**Files:** `site/hugo.toml` +**Action:** Add module mounts: +- `../src` → `assets/css` (framework CSS in Hugo's asset pipeline) +- `../docs` → `content/docs` (framework docs as site content) +- `../vendor/open-props` → `assets/css/open-props` (Open Props in asset pipeline) +- `static` → `static` (site's own static files) +**Acceptance:** `hugo server --source site/` builds successfully. All pages render. CSS loads correctly. + +--- + +## Task 6 — Build dist/asw.css from new paths +**Files:** `postcss.config.js`, `package.json` +**Action:** +- Update PostCSS config if paths changed +- Run: `npx postcss src/main.css -o dist/asw.css` +- Run: `npx postcss src/main.css -o dist/asw.min.css` +- Verify output matches previous `static/asw.css` +- Add npm scripts to `package.json`: `"build": "postcss src/main.css -o dist/asw.css"` +**Acceptance:** `dist/asw.css` exists and is equivalent to the previous build. `npm run build` works. + +--- + +## Task 7 — Restructure docs/ +**Files:** `docs/` +**Action:** +- Existing docs stay: `context.md`, `css-refactor-plan.md`, `css-html-cleanup-todo.md`, `frontmatter.md`, `template-h1-title.md` +- Verify Hugo mount serves them at `content/docs/` +- Add `docs/llms.txt` (move from legacy or create) +- Add `docs/lineage.md` placeholder (Pico absorption story, Open Props relationship) +**Acceptance:** Framework docs are all in `docs/`. Hugo renders them as site pages via mount. + +--- + +## Task 8 — Create examples/ from site content +**Files:** `examples/` +**Action:** +- Identify existing pages that are pure component/layout demos +- Create standalone HTML versions in `examples/` that load `dist/asw.css` +- Organize into `examples/components/`, `examples/layout/`, `examples/charts/`, `examples/vault/` +**Acceptance:** At least 3 example files exist, each standalone and openable in a browser. + +--- + +## Task 9 — Update .gitignore and clean up +**Files:** `.gitignore`, root directory +**Action:** +- Update `.gitignore` for new paths +- Remove empty `assets/` directory if still present +- Remove `static/css/layers/` (dev-mode output, will be regenerated) +- Verify no orphaned files remain in old locations +**Acceptance:** `git status` is clean. No files in old locations. `.gitignore` covers `node_modules/`, `site/public/`, `site/resources/`. + +--- + +## Task 10 — Verify full build cycle +**Files:** (none modified, verification only) +**Action:** +- `npm run build` → `dist/asw.css` generated +- `hugo --source site/` → `site/public/` generated +- Spot-check 3-4 pages visually +- Verify `docs/` content appears in site +- Verify CSS loads and renders correctly +**Acceptance:** Full build passes. Site looks identical to pre-restructure. dist/ output is valid. diff --git a/openspec/config.yaml b/openspec/config.yaml new file mode 100644 index 0000000..f3722c8 --- /dev/null +++ b/openspec/config.yaml @@ -0,0 +1,48 @@ +schema: spec-driven + +context: | + Project: ASW — Agentic Semantic Web + Purpose: A CSS framework built for agents, not humans. Semantic HTML + data-* attributes. + + Core idea: LLMs produce semantic HTML naturally. ASW makes that HTML look correct + without the agent touching CSS. No classes, no inline styles, no presentation vocabulary. + + Stack: Pure CSS framework. PostCSS build (postcss-import, postcss-custom-media, cssnano). + Foundation: Open Props provides primitive token scales; ASW aliases them to semantic names. + + Engine-agnostic: ASW ships as CSS + packs. Packs integrate with Hugo, Apache, Caddy, + Flask, Nginx, Pandoc, Python. The framework's own website currently uses the Hugo pack. + + Repo structure (target): + src/ — framework CSS source (layers/) and lab experiments (lab/) + dist/ — built output: asw.css, asw.min.css + vendor/ — explicit dependencies (Open Props with version tracking) + packs/ — engine integration bundles + docs/ — framework documentation (markdown only, engine-agnostic) + examples/ — static HTML showcases of framework capabilities + site/ — the ASW website (currently Hugo, consumes docs/ as content) + openspec/ — specs and changes + + Key constraint: layers 02+ must only reference semantic aliases from 01-tokens.css, + never Open Props primitives directly. + + Lineage: Pico CSS (component patterns, absorbed), Open Props (token scales, foundation), + Charts.css (data-* attribute pattern, inspiration). + + Forgejo: git.trentuna.com/trentuna/asw + Legacy repo: git.trentuna.com/trentuna/agentic-semantic-web (to be archived after import) + +rules: + proposal: + - Keep scope tight — this is a CSS framework, not a JS library + - Name the files that will be touched + - Consider impact on existing deployed pages (trentuna.com) + specs: + - Use Given/When/Then for behavior scenarios + - Specs should be testable by visual inspection in a browser + - Map 1:1 to CSS layer files where applicable + tasks: + - Each task should be a standalone unit of work for a single agent session + - Include acceptance criteria + - No task should touch more than 3 files + - Build check after every task diff --git a/openspec/specs/framework/charts/spec.md b/openspec/specs/framework/charts/spec.md new file mode 100644 index 0000000..2cbea2f --- /dev/null +++ b/openspec/specs/framework/charts/spec.md @@ -0,0 +1,32 @@ +# Spec: Charts (Layer 09) + +File: `src/layers/09-charts.css` + +## Purpose + +Data visualization using pure CSS and HTML tables. Inspired by Charts.css — uses `data-*` attributes to transform tables into visual charts. + +## Scope + +### In scope +- Bar charts (horizontal and vertical) +- Line charts +- Area charts +- Radial/gauge charts +- Chart axes, labels, legends +- Responsive chart sizing +- Chart color schemes using design tokens + +### Out of scope +- JavaScript-powered charts +- Interactive chart features (tooltips on hover are CSS-only) + +## Lineage + +Inspired by Charts.css `data-*` attribute pattern. Not a port — reimplemented for ASW's token system and semantic approach. + +## Constraints + +- References only semantic aliases from `01-tokens.css` +- Charts must be readable without CSS (the underlying table has the data) +- Color choices must work for colorblind users diff --git a/openspec/specs/framework/components/spec.md b/openspec/specs/framework/components/spec.md new file mode 100644 index 0000000..79e0111 --- /dev/null +++ b/openspec/specs/framework/components/spec.md @@ -0,0 +1,26 @@ +# Spec: Components (Layer 05) + +File: `src/layers/05-components.css` + +## Purpose + +Compound UI patterns that go beyond single-element semantics. These are patterns that require specific HTML structures. + +## Scope + +### In scope +- `dialog` — modal dialogs +- `details` / `summary` — accordion pattern +- Breadcrumb navigation (`[data-role="breadcrumb"]`) +- Step indicators (`[data-role="steps"]`) + +### Out of scope +- Single HTML elements with default styling (→ landmarks, typography, forms) +- Sidebar navigation (→ navigation layer) +- Charts (→ charts layer) +- Data-attribute vocabulary (→ data-attributes layer) + +## Constraints + +- This layer should be small — if a pattern can be expressed by a semantic HTML element alone, it belongs in landmarks or typography, not here +- References only semantic aliases from `01-tokens.css` diff --git a/openspec/specs/framework/data-attributes/spec.md b/openspec/specs/framework/data-attributes/spec.md new file mode 100644 index 0000000..253e612 --- /dev/null +++ b/openspec/specs/framework/data-attributes/spec.md @@ -0,0 +1,42 @@ +# Spec: Data Attributes (Layer 07) + +File: `src/layers/07-data-attrs.css` + +## Purpose + +The ASW vocabulary extension layer. `data-*` attributes express concepts that HTML has no native element for. This is the core differentiator — the semantic vocabulary agents use. + +## Vocabulary + +### Task states +- `data-task="done|todo|blocked|wip"` — task status indicators + +### Callouts +- `data-callout="note|tip|warning|error"` — admonition blocks + +### Status +- `data-status="active|sleeping|blocked"` — entity status + +### Links +- `data-wikilink` — vault/wiki-style note links + +### Layout +- `data-layout="docs|grid-2|grid-3|console"` — page layout selection + +### Table of contents +- `data-toc` — marks an element as an in-page TOC + +### Roles +- `data-role="breadcrumb|steps|accordion|card"` — component role disambiguation + +## Design Principle + +Every `data-*` attribute added to the vocabulary is cognitive load on every agent using the framework. Add only what cannot be expressed by existing semantic HTML. + +**The bar for addition:** "Can this be expressed with an existing HTML element?" If yes, don't add a data attribute. + +## Constraints + +- References only semantic aliases from `01-tokens.css` +- Each attribute must have a clear semantic meaning (not stylistic) +- Attribute values should be exhaustive and documented diff --git a/openspec/specs/framework/forms/spec.md b/openspec/specs/framework/forms/spec.md new file mode 100644 index 0000000..e00bee4 --- /dev/null +++ b/openspec/specs/framework/forms/spec.md @@ -0,0 +1,30 @@ +# Spec: Forms (Layer 04) + +File: `src/layers/04-forms.css` + +## Purpose + +Form element styling. Inputs, selects, textareas, buttons, checkboxes, radios, fieldsets, labels. Accessible by default. + +## Scope + +### In scope +- `button`, `input[type="button"]`, `input[type="submit"]`, `input[type="reset"]` +- `input[type="text|email|password|number|search|url|tel|date|time|datetime-local"]` +- `select`, `textarea` +- `fieldset`, `legend`, `label` +- `input[type="checkbox"]`, `input[type="radio"]` +- `progress`, `meter` +- `:focus-visible` ring styling +- `aria-invalid`, `aria-busy` states +- `[disabled]` styling + +### Out of scope +- Form layout/grid (→ layouts layer) +- Custom form components built with data-attributes (→ data-attributes layer) + +## Constraints + +- References only semantic aliases from `01-tokens.css` +- All interactive elements must have visible focus indicators +- Respects `prefers-color-scheme` and `prefers-contrast` diff --git a/openspec/specs/framework/landmarks/spec.md b/openspec/specs/framework/landmarks/spec.md new file mode 100644 index 0000000..27f9a4b --- /dev/null +++ b/openspec/specs/framework/landmarks/spec.md @@ -0,0 +1,29 @@ +# Spec: Landmarks (Layer 03) + +File: `src/layers/03-landmarks.css` + +## Purpose + +Styling for HTML landmark elements — the structural bones of a page. These elements convey document structure to both browsers and screen readers. + +## Scope + +### In scope +- `body > nav` — global navigation bar +- `article` — content card or post +- `aside` — sidebar panels +- `section` — content grouping +- `body > footer` — global footer +- `hgroup` — heading groups +- `header` within landmarks +- `dt`, `dd` — definition lists (structural, not component) + +### Out of scope +- Navigation menus and dropdowns (→ navigation layer) +- Sidebar nav behavior `nav[data-nav="sidebar"]` (→ navigation layer) +- Article styling within specific layouts (→ layouts layer) + +## Constraints + +- References only semantic aliases from `01-tokens.css` +- Landmark styling should be layout-independent — works in any `data-layout` diff --git a/openspec/specs/framework/layouts/spec.md b/openspec/specs/framework/layouts/spec.md new file mode 100644 index 0000000..66a291f --- /dev/null +++ b/openspec/specs/framework/layouts/spec.md @@ -0,0 +1,42 @@ +# Spec: Layouts (Layer 11) + +File: `src/layers/11-layout.css` + +## Purpose + +Page-level layout systems. Controls how landmarks arrange on the page. Selected via `data-layout` attribute. + +## Layout Types + +### `data-layout="docs"` — Documentation +Three-column layout: sidebar navigation, main content, table of contents. The standard documentation pattern. + +### `data-layout="console"` — Console +Docs variant: sidebar flush to viewport edge. Prototype — not yet used in production. + +### `data-layout="grid-2"` / `data-layout="grid-3"` — Grids +Multi-column content grids for cards, galleries, dashboards. + +### Essay layout +Long-form prose with table of contents. Wider reading measure, typographic refinements. + +### Prose width +`--width-prose` constrains content to readable line length within any layout. + +## Scope + +### In scope +- `data-layout` attribute styling +- Prose width constraints +- Responsive layout breakpoints +- Essay/long-form layout variant + +### Out of scope +- Landmark styling within layouts (→ landmarks layer) +- Navigation behavior within layouts (→ navigation layer) + +## Constraints + +- References only semantic aliases from `01-tokens.css` +- Layouts must degrade gracefully on mobile (single column) +- No layout should require JavaScript diff --git a/openspec/specs/framework/navigation/spec.md b/openspec/specs/framework/navigation/spec.md new file mode 100644 index 0000000..175bc9e --- /dev/null +++ b/openspec/specs/framework/navigation/spec.md @@ -0,0 +1,27 @@ +# Spec: Navigation (Layer 06) + +File: `src/layers/06-navigation.css` + +## Purpose + +Navigation patterns that go beyond the basic `nav` landmark. Sidebar navigation, table of contents, dropdown menus, navigation state management. + +## Scope + +### In scope +- `nav[data-nav="sidebar"]` — sidebar navigation tree +- `aside[data-toc]` — in-page table of contents +- Dropdown menus within navigation +- Active/current page indicators (`aria-current`) +- Mobile navigation patterns +- Navigation collapse/expand behavior + +### Out of scope +- The `body > nav` landmark itself (→ landmarks layer) +- Breadcrumbs (→ components layer) + +## Constraints + +- References only semantic aliases from `01-tokens.css` +- Navigation must be keyboard-accessible +- Active states use `aria-current`, not classes diff --git a/openspec/specs/framework/tokens/spec.md b/openspec/specs/framework/tokens/spec.md new file mode 100644 index 0000000..ce542e5 --- /dev/null +++ b/openspec/specs/framework/tokens/spec.md @@ -0,0 +1,77 @@ +# Spec: Tokens (Layer 01) + +File: `src/layers/01-tokens.css` + +## Purpose + +Pure design token definitions. Aliases Open Props primitives to semantic names. Contains only `:root {}` variable declarations — no rules, no selectors, no styling. + +## Open Props Dependency + +ASW builds on Open Props as its primitive token source. Open Props provides: +- Color scales: `--color-0` through `--color-16` +- Size scale: `--size-1` through `--size-15`, `--size-px-1` through `--size-px-12` +- Font sizes: `--font-size-0` through `--font-size-8` +- Font weights: `--font-weight-1` through `--font-weight-9` +- Shadows: `--shadow-1` through `--shadow-6` +- Border sizes: `--border-size-1` through `--border-size-5` +- Animations, easings, gradients, and more + +**Version:** tracked in `vendor/open-props/VERSION` + +## Aliasing Contract + +Every Open Props primitive used in the framework MUST be aliased through this file. Downstream layers (02+) MUST reference semantic aliases, never primitives. + +```css +/* YES — downstream layers use this */ +color: var(--text); +font-weight: var(--weight-bold); +padding: var(--space-4); + +/* NO — never in layers 02+ */ +color: var(--color-6); +font-weight: var(--font-weight-7); +padding: var(--size-3); +``` + +## Token Categories + +### Colors +- `--surface`, `--surface-alt` — background colors +- `--text`, `--text-muted` — foreground colors +- `--accent`, `--accent-hover` — interactive/brand color +- `--border`, `--border-muted` — border colors +- `--code-bg`, `--code-text` — code block colors + +### Spacing +- `--space-1` through `--space-7` — spacing scale +- Maps to Open Props `--size-N` scale + +### Typography +- `--weight-normal`, `--weight-medium`, `--weight-semibold`, `--weight-bold` +- `--font-body`, `--font-mono` — font stacks +- `--line-height-body`, `--line-height-heading` +- `--width-prose` — max-width for readable text + +### Shadows +- `--shadow-dropdown`, `--shadow-modal` — purpose-named shadows + +### Focus / Interaction +- `--focus-ring-width` — keyboard focus ring width + +## Scenarios + +### Given a new primitive reference needed +- **When** a downstream layer needs an Open Props value +- **Then** add a semantic alias to this file first +- **And** reference only the alias in the downstream layer + +### Given an unused token +- **When** auditing finds a token alias with zero references in layers 02+ +- **Then** it may be removed from this file + +### Given this file +- **When** inspected +- **Then** it contains only `:root {}` with `--custom-property: value;` declarations +- **And** no element selectors, no class selectors, no rules diff --git a/openspec/specs/framework/typography/spec.md b/openspec/specs/framework/typography/spec.md new file mode 100644 index 0000000..f177e66 --- /dev/null +++ b/openspec/specs/framework/typography/spec.md @@ -0,0 +1,30 @@ +# Spec: Typography (Layer 02) + +File: `src/layers/02-typography.css` + +## Purpose + +Prose and heading defaults. Responsive typography scale, font stacks, line heights, heading hierarchy, inline elements (code, mark, links, abbreviations). + +## Scope + +### In scope +- `body` font defaults +- `h1`–`h6` sizing and weight hierarchy +- `p`, `blockquote`, `ul`, `ol`, `li` prose rhythm +- `a` link styling +- `code`, `kbd`, `pre` inline/block code +- `mark`, `abbr`, `small`, `sub`, `sup` inline semantics +- `hr` horizontal rules +- Responsive font-size scaling + +### Out of scope +- Syntax highlighting colors (→ chroma layer) +- Navigation typography (→ navigation layer) +- Component-specific text styling (→ components layer) + +## Constraints + +- References only semantic aliases from `01-tokens.css` +- No Open Props primitives directly +- No element selectors that belong to landmarks (nav, footer, header) diff --git a/openspec/specs/framework/utilities/spec.md b/openspec/specs/framework/utilities/spec.md new file mode 100644 index 0000000..f9938b7 --- /dev/null +++ b/openspec/specs/framework/utilities/spec.md @@ -0,0 +1,27 @@ +# Spec: Utilities (Layer 08) + +File: `src/layers/08-utilities.css` + +## Purpose + +Small, single-purpose helpers for text, visibility, and accessibility. The escape hatch for edge cases that don't warrant a data-attribute. + +## Scope + +### In scope +- Text alignment helpers +- Visually-hidden (screen reader only) +- Visibility toggles +- Print styles +- `prefers-reduced-motion` resets +- `prefers-contrast` adjustments + +### Out of scope +- Layout utilities (→ layouts layer) +- Spacing/sizing utilities (use tokens directly) +- Color utilities (use tokens directly) + +## Constraints + +- This layer should be minimal — most needs should be met by semantic elements + data attributes +- References only semantic aliases from `01-tokens.css` diff --git a/openspec/specs/packs/spec.md b/openspec/specs/packs/spec.md new file mode 100644 index 0000000..7ecf71d --- /dev/null +++ b/openspec/specs/packs/spec.md @@ -0,0 +1,46 @@ +# Spec: Packs + +Directory: `packs/` + +## Purpose + +Engine integration bundles. Each pack adapts ASW for a specific web server or static site generator. A pack is a self-contained directory that someone can copy into their project. + +## Current Packs + +| Pack | Purpose | Source | +|------|---------|--------| +| `hugo/` | Hugo theme: layouts, partials, archetypes, static assets | Legacy repo | +| `apache/` | Autoindex styling, error pages, Apache conf snippets | Legacy repo | +| `caddy/` | Browse template, error pages, Caddyfile snippets | Legacy repo | +| `flask/` | Python error handler, Flask integration | Legacy repo | +| `nginx/` | Autoindex header, error pages, Nginx conf snippets | Legacy repo | +| `pandoc/` | HTML5 template, Lua filter for ASW output | Legacy repo | +| `python/` | Simple Python HTTP server with ASW styling | Legacy repo | + +## Pack Contract + +Each pack directory MUST contain: +- `README.md` — what the pack does, how to install/use it +- All files needed for integration (conf snippets, templates, static assets) + +Each pack SHOULD: +- Reference `dist/asw.css` for the framework CSS (not `src/layers/`) +- Be self-contained — no dependencies outside the pack directory and `dist/` +- Include example configuration + +## Scenarios + +### Given a new engine integration +- **When** someone wants ASW support for a new engine +- **Then** they create `packs//` with a README and integration files +- **And** the pack references `dist/asw.css` + +### Given the Hugo pack +- **When** the ASW website is built +- **Then** it uses `packs/hugo/` for layouts, partials, and configuration +- **And** `site/` contains Hugo-specific overrides on top of the pack + +## Note + +The Hugo pack is special: the ASW website (`site/`) is built with it. The pack provides the base; `site/` adds content and any site-specific customization. This is both a real integration and a living example. diff --git a/openspec/specs/repo-structure/spec.md b/openspec/specs/repo-structure/spec.md new file mode 100644 index 0000000..4aa47c8 --- /dev/null +++ b/openspec/specs/repo-structure/spec.md @@ -0,0 +1,96 @@ +# Spec: Repository Structure + +The directory layout contract for ASW. Defines what lives where and the boundary rules. + +## Directory Map + +``` +asw/ + src/ Framework CSS source + layers/ Numbered CSS layer files (00-reset through 12-landing) + main.css Entry point — @import chain for all layers + lab/ Experiments and test pages (not published) + dist/ Built output (committed to repo) + asw.css Single concatenated file + asw.min.css Minified + vendor/ Explicit external dependencies + open-props/ Open Props CSS (with VERSION file) + README.md What's vendored, why, how to update + packs/ Engine integration bundles + hugo/ Hugo theme/partial integration + apache/ Apache autoindex + error pages + caddy/ Caddy browse + error pages + flask/ Flask error handlers + nginx/ Nginx autoindex + error pages + pandoc/ Pandoc HTML5 template + Lua filter + python/ Python HTTP server with ASW styling + docs/ Framework documentation (markdown only) + examples/ Static HTML showcases (no build step needed) + site/ The ASW website (currently uses Hugo pack) + content/ Site-specific content (articles, essays, notes) + layouts/ Hugo templates + hugo.toml Hugo config (mounts docs/ as content/docs/) + static/ Site static assets + openspec/ Specs and changes +``` + +## Boundary Rules + +### src/ — framework only +- Contains only CSS source files and lab experiments +- No Hugo-specific files, no content, no templates +- `main.css` imports from `layers/` using relative paths +- `lab/` contains HTML files that reference layers directly — never published + +### dist/ — build artifacts, committed +- Built by PostCSS from `src/main.css` +- Committed to repo so consumers can grab without a build step +- Regenerated on deploy, not manually edited + +### vendor/ — visible dependencies +- Open Props source files copied from npm, with version tracking +- `VERSION` file records package version and date of last update +- Updated manually when bumping Open Props + +### packs/ — engine-agnostic integrations +- Each subdirectory is a self-contained integration for one engine +- A pack may reference `dist/asw.css` or `src/layers/` depending on its needs +- Packs ship their own README + +### docs/ — markdown only +- No HTML, no engine-specific markup +- The site consumes these as content source (Hugo module mount) +- GitHub/Forgejo renders these directly — no build step to read docs + +### examples/ — static HTML +- Each file is a standalone demo that loads ASW +- Can be opened in a browser by cloning the repo — no build step +- The site may link to these but they exist independently + +### site/ — website concerns +- All Hugo-specific files live here +- `content/docs/` is mounted from `../docs/`, not duplicated +- Site-specific content (articles, essays, notes) lives in `content/` +- Changes to the site do not affect the framework; changes to the framework may affect the site + +## Scenarios + +### Given a new CSS layer +- **When** an agent creates it +- **Then** it goes in `src/layers/` with the next number +- **And** `src/main.css` gets an @import line + +### Given a new framework doc +- **When** an agent writes documentation +- **Then** it goes in `docs/` as a .md file +- **And** the site picks it up automatically via Hugo mount + +### Given a new engine integration +- **When** someone adds support for a new engine (e.g., Eleventy) +- **Then** it goes in `packs//` with its own README + +### Given a lab experiment +- **When** an agent wants to test a CSS pattern +- **Then** it creates a file in `src/lab/` +- **And** it references layers via relative paths +- **And** it is never published to the site diff --git a/openspec/specs/site/spec.md b/openspec/specs/site/spec.md new file mode 100644 index 0000000..c226034 --- /dev/null +++ b/openspec/specs/site/spec.md @@ -0,0 +1,52 @@ +# Spec: Site + +Directory: `site/` + +## Purpose + +The ASW framework's own website. Serves as documentation site, demo platform, and living proof that the framework works. Currently built with the Hugo pack. + +## Content Types + +### Docs (from `../docs/`) +Framework documentation, mounted as Hugo content via module mount. Not duplicated — sourced from the engine-agnostic `docs/` directory. + +### Articles (`content/articles/`) +Short-form writing about ASW concepts, patterns, and techniques. No TOC. + +### Essays (`content/essays/`) +Long-form writing. TOC, description, wider reading measure. + +### Notes (`content/notes/`) +Exported PKM vault notes. Session logs, diffs, status, tasks, wikilinks. + +### Pages (`content/pages/`) +Static pages: about, etc. + +## Engine + +Currently Hugo. The site uses `packs/hugo/` as its base and adds: +- Site-specific layouts and overrides +- `hugo.toml` with module mounts +- Site-specific static assets + +## Principle + +The site is a consumer of the framework, not part of it. A different site could be built with `packs/flask/` or `packs/caddy/` using the same `docs/` and `dist/asw.css`. The framework does not depend on the site. The site depends on the framework. + +## Scenarios + +### Given a framework docs change +- **When** a markdown file in `docs/` is modified +- **Then** the site picks it up automatically via Hugo mount +- **And** no file in `site/` needs to change + +### Given a CSS framework change +- **When** `src/layers/` is modified +- **Then** `dist/asw.css` is rebuilt +- **And** the site serves the updated CSS + +### Given a site-only change (new article, essay) +- **When** content is added to `site/content/` +- **Then** only the site is affected +- **And** `src/`, `dist/`, `docs/` are untouched