Principles
Concern skills say what each layer may do. These principles say how to decide when there is a choice. They are foundational to any effort that leverages the AutoCSS Architecture. When a principle and a concern skill agree, follow them. When they appear to conflict, surface it to the user — never resolve silently.
Each principle below carries: the rule, the why, how it shows up in this architecture, and the tell (how to catch a violation).
The thesis these principles serve — one UI, every project at once
AutoCSS is not one project's UI; it is every project's UI at once. One presentation layer, served once from one place, called remotely like a font or an image, rendering each back-end's data. This is the claim that makes the architecture matter, and every principle below exists to protect it.
- The stove-pipe it dissolves. In siloed, high-security environments each project is walled off, so it is treated as law that every project starts its front-end from scratch. Frameworks only soften the restart — each project still ships an isolated copy, built independently. Because the data and data-logic differ per project, teams assume the UI must differ too, so every project rebuilds and re-owns its own front-end (and increasingly one overloaded full-stack developer owns both ends). AutoCSS rejects that assumption.
- Why it is now possible. Native declarative browser features —
:has(), :empty / :not(:empty), container and style queries, light-dark() — let a single remotely-served UI (not a copy) lay out, style, and render each project's content from the presence and shape of the data itself, with no relationship to that data. For the first time the same UI serves many unrelated back-ends without being forked.
- What that buys. Usability, accessibility, and standards-compliance stop being per-project rework and become one shared channel of effort — fixed once, inherited by every consumer. No framework-per-project stack can match that.
- Consistency and individuality at once. Department heads want a coherent look/feel across a department's apps while each app keeps its own identity for unique requirements. The shared UI provides the coherence; data-presence-driven rendering gives each app its individuality — both from the same source, no fork.
- Each engineer's best work, not a watered-down average. Because presentation and data are air-gapped, UI/UX specialists spend their seniority on UI/UX and data engineers on data — neither is conscripted into the other's craft. The customer gets each person's best, and department heads staff to solve real problems instead of hoping one overloaded generalist covers everything.
- The compounding payoff. Higher-quality apps in less time → better usability → happier, more productive users → more work done at lower total cost. Every app ships faster — a win for users, engineers, and whoever pays for the work.
- Why the principles follow. All eggs in one basket → the basket must be the single most durable, universal thing there is: one dependency, the modern browser. One basket for everyone makes decay catastrophic → future-proofing is existential, and
modern-web-guidance + MDN are how the basket stays current and correct (not optional advice). A shared UI can only be worked as its own channel if it is fully isolated from every back-end → air-gapped Separation of Concerns is the enabler, not a nicety.
Hold this as the overall context (Charter §8) on every AutoCSS response: you are never touching one project — you are touching all of them at once, which is why usability, accessibility, and standards compliance are always in force, for every consumer, all the time.
Least Power
- Rule: For any task, use the least powerful technology that expresses the intent declaratively. Ask in order — can HTML do it? If not, can CSS? Only then JS. JS is never used for the presentation layer.
- Why: Less powerful tools are more portable, more inspectable, harder to misuse, and outlive frameworks.
- Shows up: semantic HTML for structure; CSS for all UI/state/visibility; JS only for data transport on the
oninput lifecycle.
- Tell: a script doing what a selector could (
:has(), :empty, :checked) is a Least-Power violation — re-engineer to the lower tool.
Separation of Concerns (the air-gap)
- Rule: Each concern is independent; a change in one produces no change in another. HTML never names a CSS class; CSS never reads JS state; JS never writes presentation; JSON never carries markup.
- Why: Air-gapped layers can be read, tested, and replaced in isolation, and enable a strict CSP with no
unsafe-* (see the security skill).
- Shows up: the four-layer table in the
architecture skill; one concern per file.
- Tell: the
architecture skill's air-gap test — if an HTML change forces a CSS/JS change, the design is wrong.
DRY — one source of truth
- Rule: Every fact lives in exactly one place. Do not restate a rule, value, or datum that already exists elsewhere.
- Why: Duplication drifts out of sync and doubles maintenance.
- Shows up: canonical laws in ONE file (
Autocss-com/ai AGENTS.md); PROGRESS.json as the single backlog source; design tokens as custom properties set once; the @layer order derived from <link> order, not a second master list.
- Tell: a value or rule copied into two files — collapse to one and reference it.
Minimum Entropy / Minimal New Code
- Rule: Adding code or files always increases entropy. The default is to add nothing. The best solution adjusts an existing behavior to meet the ask with no new code.
- Why: Every line and file is future maintenance and future risk.
- Shows up: new utilities/patterns/files only on explicit user instruction; prefer tuning an existing rule over writing a new one.
- Tell: reaching for a new file/function before proving the existing ones cannot express the intent.
Simplicity over Complexity
- Rule: Prefer the simpler construction. "Simplicity is the ultimate sophistication."
- Why: Simple systems are readable end-to-end by any qualified person and fail in obvious ways.
- Shows up: flat semantic markup over nested wrappers; one obvious way to do each thing; CSS Grid instead of wrapper-and-flex stacks.
- Tell: if explaining the mechanism needs a diagram of layers, look for the simpler expression first.
Universal Compatibility & Interoperability
- Rule: Build on web standards so the output works everywhere the platform does, and so other systems can embed it without a fight.
- Why: Standards are the widest, longest-lived contract.
- Shows up: keeping our own styles in low-priority
@layers so a consumer's unlayered styles win by default (see the css layers reference); zero framework lock-in.
- Tell: a construction that only works inside this app's assumptions, not as a portable static resource.
Browser-Native Accessibility (baked-in)
- Rule: Prefer cross-browser, browser-native accessibility features and engineer the UI to depend on them — accessibility is a load-bearing part of the design, not a bolt-on.
- Why: Native semantics and states are free, correct, and survive refactors.
- Shows up:
:focus-visible, native form control states, semantic elements, keyboard-operable state machines; honoring prefers-reduced-motion / forced-colors (see the css a11y reference).
- Tell: a control that is invisible to keyboard/AT (e.g. a focusable element hidden with
display:none) — fix so native accessibility carries it.
Minimum O&M
- Rule: Minimize the operations-and-maintenance surface: fewer moving parts, fewer dependencies to patch, fewer build steps.
- Why: The cheapest system to run is the one with the least to maintain.
- Shows up: no bundler/compiler, no runtime dependencies, static shell deployable anywhere.
- Tell: a convenience that adds an ongoing operational burden (a service to keep alive, a dependency to keep patched).
Future-Proofing — zero third-party dependencies
- Rule: Zero third-party (non-native-browser) dependencies. Third-party = any code that cannot render natively in an evergreen browser without help.
- Why: The platform outlives every framework; native features do not get abandoned.
- Shows up: no npm runtime packages, no CDN scripts; self-host fonts and assets; use cutting-edge native CSS instead of libraries (anchor positioning instead of Popper, popover instead of a menu lib).
- Tell: a CDN
<link>/<script> or an npm runtime import — replace with the native capability or self-host.
Usability — for end-users AND future developers
- Rule: Optimize for the people who use the surface daily and the developers who maintain it. Both deserve clarity.
- Why: A system only succeeds if both audiences can work with it.
- Shows up: data rendered as
<ul>/<li> so CSS can reshape it on the user's terms (list/card views); names that describe the concern so the next developer isn't misled (see the naming skill).
- Tell: a choice that helps the machine but confuses a person reading the code or using the app.
Reuse before Create
- Rule: Review and reuse existing functions, patterns, and files before making new ones.
- Why: Reuse keeps entropy low and behavior consistent.
- Shows up: each skill catalogues the permitted utilities; check them first.
- Tell: writing a helper that duplicates one already in
assets/js/ or a pattern already in a skill.
Never New Patterns
- Rule: All patterns here are already established and documented in a skill. If a task seems to need a new pattern, the design is wrong — re-engineer until an existing pattern fits.
- Why: A fixed pattern vocabulary is what makes the system readable end-to-end.
- Shows up: state machines,
oninput lifecycle, data-flow rendering, @layer cascade — the whole vocabulary lives in the skills.
- Tell: inventing a mechanism not found in any skill — stop and find the established one.
Verify and cite (standards-first)
- Rule: Never guess. Verify feature behavior and support against authoritative sources (MDN Web Docs + BCD, the
modern-web-guidance reference) and cite them. Those sources are advisory and subordinate — on any conflict, the AutoCSS rules win, but the duty to consult and reconcile is canonical.
- Why: A claim of correctness is not correctness; the platform moves and only fresh checks catch drift.
- Shows up: the css references' dated "Baseline & support" sections;
@supports feature-detection over assumption.
- Tell: an assertion about support or behavior with no source and no recent check.
When principles conflict
Surface the conflict to the user with the trade-off named. The user is the sole arbiter. Never pick silently, and never let one principle quietly override another without saying so.
Baseline & support
Checked against MDN as of 2026-07-16.
Canonical rules: https://github.com/Autocss-com/ai/blob/main/AGENTS.md
Reference
1---2name: principles3description: The foundational engineering principles every AutoCSS effort obeys, one section per principle. These sit beneath the concern skills (html/css/javascript/json/…) and decide trade-offs when a task could be solved more than one way. Use when choosing an approach, justifying a design, resolving "which tool", or reviewing whether a change earns its place.4license: MIT5---67# Principles89Concern skills say *what* each layer may do. These principles say *how to decide* when there is a choice. They are foundational to any effort that leverages the AutoCSS Architecture. When a principle and a concern skill agree, follow them. When they appear to conflict, surface it to the user — never resolve silently.1011Each principle below carries: the **rule**, the **why**, how it **shows up** in this architecture, and the **tell** (how to catch a violation).1213## The thesis these principles serve — one UI, every project at once1415AutoCSS is not one project's UI; it is **every** project's UI at once. One presentation layer, served once from one place, called remotely like a font or an image, rendering each back-end's data. This is the claim that makes the architecture matter, and every principle below exists to protect it.1617- **The stove-pipe it dissolves.** In siloed, high-security environments each project is walled off, so it is treated as law that every project starts its front-end from scratch. Frameworks only soften the restart — each project still ships an isolated *copy*, built independently. Because the data and data-logic differ per project, teams assume the *UI* must differ too, so every project rebuilds and re-owns its own front-end (and increasingly one overloaded full-stack developer owns both ends). AutoCSS rejects that assumption.18- **Why it is now possible.** Native declarative browser features — `:has()`, `:empty` / `:not(:empty)`, container and style queries, `light-dark()` — let a single remotely-served UI (not a copy) lay out, style, and render each project's content from the **presence and shape of the data itself**, with no relationship to that data. For the first time the same UI serves many unrelated back-ends without being forked.19- **What that buys.** Usability, accessibility, and standards-compliance stop being per-project rework and become **one shared channel of effort** — fixed once, inherited by every consumer. No framework-per-project stack can match that.20- **Consistency *and* individuality at once.** Department heads want a coherent look/feel across a department's apps while each app keeps its own identity for unique requirements. The shared UI provides the coherence; data-presence-driven rendering gives each app its individuality — both from the same source, no fork.21- **Each engineer's best work, not a watered-down average.** Because presentation and data are air-gapped, UI/UX specialists spend their seniority on UI/UX and data engineers on data — neither is conscripted into the other's craft. The customer gets each person's *best*, and department heads staff to solve real problems instead of hoping one overloaded generalist covers everything.22- **The compounding payoff.** Higher-quality apps in less time → better usability → happier, more productive users → more work done at lower total cost. Every app ships faster — a win for users, engineers, and whoever pays for the work.23- **Why the principles follow.** All eggs in one basket → the basket must be the single most durable, universal thing there is: **one dependency, the modern browser**. One basket for everyone makes decay catastrophic → **future-proofing is existential**, and `modern-web-guidance` + MDN are how the basket stays current and correct (not optional advice). A shared UI can only be worked as its own channel if it is fully isolated from every back-end → **air-gapped Separation of Concerns is the enabler**, not a nicety.2425Hold this as the **overall context** (Charter §8) on every AutoCSS response: you are never touching one project — you are touching all of them at once, which is why usability, accessibility, and standards compliance are always in force, for every consumer, all the time.2627## Least Power2829- **Rule:** For any task, use the least powerful technology that expresses the intent declaratively. Ask in order — can HTML do it? If not, can CSS? Only then JS. JS is never used for the presentation layer.30- **Why:** Less powerful tools are more portable, more inspectable, harder to misuse, and outlive frameworks.31- **Shows up:** semantic HTML for structure; CSS for all UI/state/visibility; JS only for data transport on the `oninput` lifecycle.32- **Tell:** a script doing what a selector could (`:has()`, `:empty`, `:checked`) is a Least-Power violation — re-engineer to the lower tool.3334## Separation of Concerns (the air-gap)3536- **Rule:** Each concern is independent; a change in one produces no change in another. HTML never names a CSS class; CSS never reads JS state; JS never writes presentation; JSON never carries markup.37- **Why:** Air-gapped layers can be read, tested, and replaced in isolation, and enable a strict CSP with no `unsafe-*` (see the `security` skill).38- **Shows up:** the four-layer table in the `architecture` skill; one concern per file.39- **Tell:** the `architecture` skill's air-gap test — if an HTML change forces a CSS/JS change, the design is wrong.4041## DRY — one source of truth4243- **Rule:** Every fact lives in exactly one place. Do not restate a rule, value, or datum that already exists elsewhere.44- **Why:** Duplication drifts out of sync and doubles maintenance.45- **Shows up:** canonical laws in ONE file (`Autocss-com/ai` AGENTS.md); `PROGRESS.json` as the single backlog source; design tokens as custom properties set once; the `@layer` order derived from `<link>` order, not a second master list.46- **Tell:** a value or rule copied into two files — collapse to one and reference it.4748## Minimum Entropy / Minimal New Code4950- **Rule:** Adding code or files always increases entropy. The default is to add nothing. The best solution adjusts an existing behavior to meet the ask with no new code.51- **Why:** Every line and file is future maintenance and future risk.52- **Shows up:** new utilities/patterns/files only on explicit user instruction; prefer tuning an existing rule over writing a new one.53- **Tell:** reaching for a new file/function before proving the existing ones cannot express the intent.5455## Simplicity over Complexity5657- **Rule:** Prefer the simpler construction. "Simplicity is the ultimate sophistication."58- **Why:** Simple systems are readable end-to-end by any qualified person and fail in obvious ways.59- **Shows up:** flat semantic markup over nested wrappers; one obvious way to do each thing; CSS Grid instead of wrapper-and-flex stacks.60- **Tell:** if explaining the mechanism needs a diagram of layers, look for the simpler expression first.6162## Universal Compatibility & Interoperability6364- **Rule:** Build on web standards so the output works everywhere the platform does, and so other systems can embed it without a fight.65- **Why:** Standards are the widest, longest-lived contract.66- **Shows up:** keeping our own styles in low-priority `@layer`s so a consumer's unlayered styles win by default (see the `css` `layers` reference); zero framework lock-in.67- **Tell:** a construction that only works inside this app's assumptions, not as a portable static resource.6869## Browser-Native Accessibility (baked-in)7071- **Rule:** Prefer cross-browser, browser-native accessibility features and engineer the UI to depend on them — accessibility is a load-bearing part of the design, not a bolt-on.72- **Why:** Native semantics and states are free, correct, and survive refactors.73- **Shows up:** `:focus-visible`, native form control states, semantic elements, keyboard-operable state machines; honoring `prefers-reduced-motion` / forced-colors (see the `css` `a11y` reference).74- **Tell:** a control that is invisible to keyboard/AT (e.g. a focusable element hidden with `display:none`) — fix so native accessibility carries it.7576## Minimum O&M7778- **Rule:** Minimize the operations-and-maintenance surface: fewer moving parts, fewer dependencies to patch, fewer build steps.79- **Why:** The cheapest system to run is the one with the least to maintain.80- **Shows up:** no bundler/compiler, no runtime dependencies, static shell deployable anywhere.81- **Tell:** a convenience that adds an ongoing operational burden (a service to keep alive, a dependency to keep patched).8283## Future-Proofing — zero third-party dependencies8485- **Rule:** Zero third-party (non-native-browser) dependencies. Third-party = any code that cannot render natively in an evergreen browser without help.86- **Why:** The platform outlives every framework; native features do not get abandoned.87- **Shows up:** no npm runtime packages, no CDN scripts; self-host fonts and assets; use cutting-edge native CSS instead of libraries (anchor positioning instead of Popper, popover instead of a menu lib).88- **Tell:** a CDN `<link>`/`<script>` or an npm runtime import — replace with the native capability or self-host.8990## Usability — for end-users AND future developers9192- **Rule:** Optimize for the people who use the surface daily *and* the developers who maintain it. Both deserve clarity.93- **Why:** A system only succeeds if both audiences can work with it.94- **Shows up:** data rendered as `<ul>`/`<li>` so CSS can reshape it on the user's terms (list/card views); names that describe the concern so the next developer isn't misled (see the `naming` skill).95- **Tell:** a choice that helps the machine but confuses a person reading the code or using the app.9697## Reuse before Create9899- **Rule:** Review and reuse existing functions, patterns, and files before making new ones.100- **Why:** Reuse keeps entropy low and behavior consistent.101- **Shows up:** each skill catalogues the permitted utilities; check them first.102- **Tell:** writing a helper that duplicates one already in `assets/js/` or a pattern already in a skill.103104## Never New Patterns105106- **Rule:** All patterns here are already established and documented in a skill. If a task seems to need a new pattern, the design is wrong — re-engineer until an existing pattern fits.107- **Why:** A fixed pattern vocabulary is what makes the system readable end-to-end.108- **Shows up:** state machines, `oninput` lifecycle, data-flow rendering, `@layer` cascade — the whole vocabulary lives in the skills.109- **Tell:** inventing a mechanism not found in any skill — stop and find the established one.110111## Verify and cite (standards-first)112113- **Rule:** Never guess. Verify feature behavior and support against authoritative sources (MDN Web Docs + BCD, the `modern-web-guidance` reference) and cite them. Those sources are advisory and subordinate — on any conflict, the AutoCSS rules win, but the duty to consult and reconcile is canonical.114- **Why:** A claim of correctness is not correctness; the platform moves and only fresh checks catch drift.115- **Shows up:** the css references' dated "Baseline & support" sections; `@supports` feature-detection over assumption.116- **Tell:** an assertion about support or behavior with no source and no recent check.117118## When principles conflict119120Surface the conflict to the user with the trade-off named. The user is the sole arbiter. Never pick silently, and never let one principle quietly override another without saying so.121122## Baseline & support123124_Checked against MDN as of 2026-07-16._125126- `:has()` — **Baseline Widely available** — https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Selectors/:has127- `:empty` — **Baseline Widely available** — https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Selectors/:empty128- `light-dark()` — **Baseline Newly available** — https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Values/color_value/light-dark129130**Canonical rules:** https://github.com/Autocss-com/ai/blob/main/AGENTS.md131132## Reference133134- MDN Web Docs (authoritative platform reference): https://developer.mozilla.org/135- W3C TR index (standards): https://www.w3.org/TR/136- W3C — Rule of Least Power: https://www.w3.org/2001/tag/doc/leastPower.html137- AutoCSS Architecture + Response Integrity Charter (canonical): https://github.com/Autocss-com/ai/blob/main/AGENTS.md