Design/UI Systems Guide
Intent
This guide defines the cross-stack design and UI system model for Anarchitecture Bricks. It explains how to consume @anarchitects/* packages so design contracts, composition APIs, and runtime layouts stay consistent across domains and applications.
Contract ownership for DTOs and domain models is defined in the canonical TS Contracts Guide.
System Layers
The UI system is layered and should be adopted in order:
@anarchitects/common-angular-design@anarchitects/common-angular-ui-composition@anarchitects/common-angular-ui-primitives@anarchitects/common-angular-ui-layouts- Domain UI slices (
@anarchitects/forms-angular/ui,@anarchitects/auth-angular/ui)
Domain orchestration should still follow Angular layering:
ui <- feature -> state -> data-access.
Backend support should still follow Nest layering:
presentation -> application <- infrastructure.
Token and Theme Model
Use token and theme contracts from @anarchitects/common-angular-design as the primary extension mechanism:
- Keep shared packages unbranded.
- Apply product branding via token overrides and theme contexts.
- Use semantic hooks (
data-anx-theme,data-anx-density,data-anx-surface,data-anx-layout) to scope behavior.
Example:
.anx-root[data-anx-theme='brand-a'] {
--anx-sys-color-primary: #0f766e;
--anx-sys-color-accent: #0ea5e9;
--anx-layout-content-max-width: 72rem;
}
Shell/Layout Contract Hardening (Phase 2)
Shell and layout contracts are intentionally separated to prevent collisions.
Source-of-truth symbols:
ANX_SHELL_UTILITY_CLASSNAMESANX_DESIGN_HOOK_CLASSNAMESANX_SEMANTIC_CLASSNAMES(backward-compatibility union)isAnxShellUtilityClass(...)
Package author rule source:
ANX_PACKAGE_AUTHOR_RULESin@anarchitects/common-angular-design/styles
Enforcement source:
tools/guardrails/shell-utility-collision.test.mjs
Package Author CSS Class Rules
When building UI package components, understand the two categories of semantic classes.
Shell Utility Classes (Consumer Use Only)
These classes control layout and spacing in consumer app shells and must not be applied to package component host elements:
anx-region— block padding wrapperanx-stack— vertical grid flow (gap-based)anx-inline— flex inline rowanx-grid— multi-column grid layout
Critical Rule: Applying these to package component hosts causes unintended double-spacing when the component is nested inside a consumer's layout container using the same utilities.
Design Hook Classes (Component-Safe)
These classes define visual treatment safe for component styling:
anx-surface— border, shadow, and background treatmentanx-heading— heading typography sizinganx-text— muted secondary textanx-action— button-like action styling
Correct Package Component Spacing
Use :host CSS for component-internal spacing instead:
@Component({
selector: 'anarchitects-ui-card',
host: {
class: 'anx-card anx-surface', // Design hooks OK; no shell utilities
'[class.anx-card--interactive]': 'interactive()',
},
styles: `
:host {
padding: var(--anx-layout-block-padding-current);
gap: var(--anx-layout-gap-stack);
}
`,
})
export class AnarchitectsCard {}
For details, see the CSS Class Rules in the contracts documentation.
Single-Source Theme Setup
Use one canonical app-bootstrap path for shared design context:
- Apply base styles once before rendering.
- Register
provideDesignSystemConfig(...)at app root. - Avoid manual
data-anx-theme,data-anx-density, anddata-anx-surfaceon the root in new setups.
Example:
import { bootstrapApplication } from '@angular/platform-browser';
import { provideDesignSystemConfig } from '@anarchitects/common-angular-design/config';
import { applyAnxBaseStyles } from '@anarchitects/common-angular-design/styles';
applyAnxBaseStyles();
bootstrapApplication(AppComponent, {
providers: [
...provideDesignSystemConfig({
theme: 'default',
density: 'comfortable',
surface: 'plain',
layout: 'list',
columns: 1,
}),
],
});
The provider applies anx-root, data-anx-theme, data-anx-density, and
data-anx-surface on document.documentElement during bootstrap.
data-anx-layout and data-anx-columns remain explicit where local layout
scope is required.
Precedence Rules
For managed root values (theme, density, surface) the resolution order is:
- Directive input (
designTheme,designDensity,designSurface) - Explicit host/root attribute value (
data-anx-*) - Provider configuration (
provideDesignSystemConfig)
This keeps migration safe because existing explicit attributes remain authoritative.
Migration and Validation Workflow
When migrating existing consumers to hardened shell/layout contracts:
- Keep shell utility classes only in consumer shell wrappers.
- Remove shell utility classes from shared package component hosts and internal templates.
- Move component spacing to explicit component CSS (
:host, component-scoped selectors). - Validate contract enforcement and downstream behavior:
yarn nx run guardrails:testyarn nx run forms-angular-ui:test --testFile=libs/forms/angular/ui/src/form.spec.ts
- Run docs verification:
yarn nx run docs-hub:validate-contentyarn nx run docs-hub:buildyarn nx run docs-hub:verify
For full migration sequence examples, see the Theme Migration Guide.
Composition Contracts
Use @anarchitects/common-angular-ui-composition for stable projection contracts:
- Canonical slots via
anxSlot="..."as public API. - Templates via
ng-template[anxTemplate]for host customization. - Alias compatibility only as migration support, not as new API surface.
Example:
<anarchitects-ui-card>
<h3 anxSlot="header">Summary</h3>
<p anxSlot="content">Rendered with stable slot contracts.</p>
<div anxSlot="footer">
<button anxSlot="actions">Continue</button>
</div>
</anarchitects-ui-card>
Primitive Contracts
Use @anarchitects/common-angular-ui-primitives for reusable, non-domain visual building blocks:
- Keep primitive APIs token-driven and wrapper-friendly.
- Keep business decisions in feature/state layers.
- Extend via app wrappers instead of modifying shared primitive contracts.
Layout Runtime Contracts
Use @anarchitects/common-angular-ui-layouts when runtime layout selection is required:
- Layout kinds: form, list, detail.
- Resolution precedence: host input, provider defaults, built-in fallback.
- Extend through provider APIs (
provideAnxLayouts,provideAnxLayoutDefaults) instead of hardcoded branching.
Domain Integration Matrix
| Domain Package | Role | Design/UI System Integration |
|---|---|---|
@anarchitects/forms-angular |
Dynamic form/list/detail flows | Consumes shared composition, primitives, and layout runtime contracts |
@anarchitects/auth-angular |
Auth feature orchestration and domain UI | Uses shared design tokens/primitives and contract-safe state composition |
@anarchitects/forms-nest |
Forms API/service backend | Must preserve contract stability used by frontend layouts and form rendering |
@anarchitects/auth-nest |
Auth lifecycle backend | Must preserve contract stability used by frontend state/feature and policy flows |
Cookbook Patterns
- Pattern: baseline app setup apply base styles first, then register provider config before rendering domain UI.
- Pattern: product theming apply token/theme overrides in app shell, not shared packages.
- Pattern: shell utility ownership keep shell utility classes in consumer layout wrappers only.
- Pattern: projection stability publish canonical slot/template names and avoid breaking renames.
- Pattern: backend-safe evolution update DTO contracts first, regenerate OpenAPI, then adapt frontend consumers.
- Pattern: layout extensibility register custom layouts via providers and preserve deterministic fallbacks.
Anti-Patterns
- Treating design packages as optional CSS rather than contract infrastructure.
- Hardcoding brand styles inside shared primitives.
- Embedding orchestration/state logic in primitive components.
- Breaking slot or template names without migration path.
- Applying shell utility classes to shared package component hosts.
- Shipping backend schema changes without OpenAPI and frontend consumer verification.
Adoption Checklist
- Add
@anarchitects/common-angular-design, callapplyAnxBaseStyles(), and registerprovideDesignSystemConfig(...)in app providers. - Adopt
@anarchitects/common-angular-ui-compositionslot/template contracts in shared and domain UI. - Use
@anarchitects/common-angular-ui-primitivesas base visual building blocks. - Add
@anarchitects/common-angular-ui-layoutsonly when runtime-selectable layout behavior is required. - Keep forms and auth frontend packages aligned with backend contracts (
@anarchitects/forms-angular,@anarchitects/auth-angular,@anarchitects/forms-nest,@anarchitects/auth-nest). - Keep shell utility classes in consumer layout wrappers and out of shared package hosts.
- Validate guardrails and downstream integration:
yarn nx run guardrails:testandyarn nx run forms-angular-ui:test --testFile=libs/forms/angular/ui/src/form.spec.ts. - Validate docs and generated outputs:
yarn nx run docs-hub:validate-content,yarn nx run docs-hub:build,yarn nx run docs-hub:verify.