Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 71 additions & 0 deletions .spec/decisions/architecture/repo.ecosystem.css_style_authoring.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
---
id: repo.ecosystem.css_style_authoring
status: accepted
date: 2026-05-15
affects:
- ecosystem.dsl_iur_symbiosis
- unified_ui.dsl
- unified_ui.theming
- unified_ui.compiler
- unified_iur.theming
---

# CSS Stylesheet Blocks Lower Into Canonical Style Data

## Context

The current styling and theming model is canonical: authors declare style and
theme intent in `unified_ui`, the compiler resolves that intent, and runtimes
consume renderer-independent `unified_iur` style and theme data. This keeps the
ecosystem portable across web, desktop, terminal, and other runtime targets.

Authors also expect CSS as a familiar authoring language, especially for class,
state, selector, and declaration-based styling. The ecosystem can support that
authoring workflow without making browser CSS the canonical interchange
contract. The boundary needs to accept real CSS syntax, recover like CSS
parsers do, translate supported style meaning into the existing canonical style
model, and ignore unsupported concepts without losing deterministic diagnostics.

## Decision

1. `unified_ui` may expose CSS stylesheet blocks as an authored styling
convenience inside the DSL.
2. CSS stylesheet blocks are parsed through a CSS Syntax-compatible stylesheet
parser with stylesheet-level error recovery rather than through ad-hoc
string parsing.
3. Supported CSS selectors and declarations are lowered into canonical style
and theme data before canonical `unified_iur` output is emitted.
4. Raw CSS is not a new `unified_iur` interchange format. Runtimes continue to
consume canonical style and theme data, although renderers may realize that
canonical data through native CSS, classes, terminal attributes, desktop
drawing primitives, or other runtime-native mechanisms.
5. The initial selector model should match authored nodes through canonical
identity, portable classes, widget or component kinds, explicitly supported
structural selectors, and supported state pseudo-classes.
6. For supported rules, cascade resolution follows CSS specificity and source
order, then participates in the existing canonical style precedence where
theme defaults and referenced component styles are weaker than CSS-derived
rules, and explicit local style declarations remain strongest.
7. Unsupported at-rules, selectors, properties, values, units, functions, and
unsafe external-resource features are ignored with diagnostics. Ignoring an
unsupported CSS construct shall not make the whole CSS block invalid when
the CSS parser can recover and continue.
8. Accepting actual CSS syntax is not a promise of full browser CSS semantic
equivalence. Only CSS concepts with an explicit canonical style meaning are
translated into the ecosystem contract.

## Consequences

- CSS authoring becomes a front-end authoring convenience for canonical style
data, not a renderer-specific escape hatch.
- `unified_ui` needs parser, selector matching, cascade, declaration
translation, diagnostics, and inspection behavior for CSS stylesheet blocks.
- `unified_iur` needs to represent CSS-derived results as ordinary canonical
style and theme data, with optional renderer-independent provenance or
diagnostics metadata for tooling.
- Runtime libraries do not need to understand authored CSS blocks directly, but
they must continue to realize the canonical style data that results from CSS
lowering.
- The implementation plan should phase parser boundaries first, then selector
and cascade behavior, then declaration translation, and finally compiler,
IUR, tooling, and runtime alignment.
46 changes: 46 additions & 0 deletions .spec/planning/css_style_authoring/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# CSS Style Authoring Planning

This directory contains the phased implementation plan for CSS stylesheet
authoring in `UnifiedUi`, canonical style lowering into `UnifiedIUR`, and
tooling/runtime alignment for CSS-derived canonical style data.

The plan aligns to:
- [CSS Style Authoring ADR](../../decisions/architecture/repo.ecosystem.css_style_authoring.md)
- [DSL and IUR Symbiosis](../../specs/dsl_iur_symbiosis.spec.md)
- [UnifiedUi DSL](../../specs/unified-ui/dsl.spec.md)
- [Unified UI Theming](../../specs/unified-ui/theming.spec.md)
- [UnifiedUi Compiler](../../specs/unified-ui/compiler.spec.md)
- [UnifiedIUR Theming](../../specs/unified-iur/theming.spec.md)

## Phase Files

1. [Phase 1 - CSS Authoring Surface and Parser Boundary](./phase-01-css-authoring-surface-and-parser-boundary.md): implement the authored CSS block shape, parser adapter, source model, and recoverable syntax diagnostics.
2. [Phase 2 - Selector Matching and Cascade Resolution](./phase-02-selector-matching-and-cascade-resolution.md): implement the supported selector subset, authored-node matching, specificity, source order, and style precedence behavior.
3. [Phase 3 - Declaration Translation and Canonical Style Mapping](./phase-03-declaration-translation-and-canonical-style-mapping.md): map supported CSS declarations, values, units, shorthands, and state-scoped rules into canonical style concepts while ignoring unsupported constructs with diagnostics.
4. [Phase 4 - Compiler, IUR, Tooling, and Runtime Alignment](./phase-04-compiler-iur-tooling-and-runtime-alignment.md): integrate CSS lowering into compiler output, IUR representation, inspection/export tooling, examples, and runtime realization checks.

## Numbering

- Phases: `N`
- Sections: `N.M`
- Tasks: `N.M.K`
- Subtasks: `N.M.K.L`

Every phase, section, task, and subtask uses Markdown checkboxes. Every phase,
section, and task starts with a short description paragraph. Each phase ends
with an integration-testing section.

## Shared Assumptions and Defaults

- CSS stylesheet blocks are an authored DSL convenience, not a raw CSS runtime
interchange format.
- CSS input is parsed through a CSS Syntax-compatible stylesheet parser with
standard recovery behavior.
- Accepting actual CSS syntax does not imply full browser CSS semantic
equivalence.
- Unsupported selectors, at-rules, declarations, values, units, functions, and
unsafe external-resource features are ignored with deterministic diagnostics.
- Supported CSS rules lower into canonical style and theme data before
`UnifiedIUR` output is emitted.
- Runtime packages remain native UI libraries and consume canonical style data
rather than authored CSS blocks.
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
# Phase 1 - CSS Authoring Surface and Parser Boundary

Back to index: [README](./README.md)

## Relevant Shared APIs / Interfaces

- `UnifiedUi.Dsl`
- `UnifiedUi.Dsl.Node`
- `UnifiedUi.Dsl.Sections.Themes`
- `UnifiedUi.Style`
- `UnifiedUi.Compiler`
- `UnifiedUi.Tooling`
- CSS parser adapter module to be introduced under `UnifiedUi`

## Relevant Assumptions / Defaults

- The authored API may use a `css` stylesheet block or an equivalent named DSL
section, but the block contents remain CSS stylesheet text.
- Multiple authored CSS blocks are allowed and preserve deterministic source
order.
- Class selectors use portable authored class metadata; a class name is not
treated as proof that a runtime stylesheet already exists.
- Parser selection is an implementation detail behind a small internal adapter.
- Parser recovery diagnostics are surfaced without treating every recoverable
CSS syntax issue as a fatal DSL error.

[x] 1 Phase 1 - CSS Authoring Surface and Parser Boundary
Define the authored CSS stylesheet block, parser adapter, source-order model,
and recoverable diagnostics needed before selector matching or style lowering
can be implemented.

[x] 1.1 Section - Authored CSS Block Shape
Establish the DSL syntax and source metadata for authored CSS stylesheet
blocks while keeping existing style and theme authoring intact.

[x] 1.1.1 Task - Define CSS block placement and identity
Specify where CSS blocks may appear and how they are named, ordered, and
associated with authored modules or fragments.

[x] 1.1.1.1 Subtask - Define whether the primary authoring surface is a top-level `css` block, a theming-section entry, or both.
[x] 1.1.1.2 Subtask - Define source names, optional block ids, and deterministic ordering for multiple CSS blocks in one authored module.
[x] 1.1.1.3 Subtask - Define how CSS blocks compose with existing theme definitions, `style_refs`, local `style` values, and widget props.
[x] 1.1.1.4 Subtask - Reject CSS block placement that would make style meaning depend on renderer-specific module loading.

[x] 1.1.2 Task - Define portable class and identity authoring
Clarify how CSS selectors can target authored nodes without treating
browser class attributes as the only canonical selector mechanism.

[x] 1.1.2.1 Subtask - Define the canonical source of selector identity for `#id` rules using authored stable node identity.
[x] 1.1.2.2 Subtask - Define class metadata normalization for `.class` selectors, including whitespace handling and deterministic class ordering.
[x] 1.1.2.3 Subtask - Document that authored `class` values are portable selector metadata and optional runtime hooks, not automatic stylesheet loading.
[x] 1.1.2.4 Subtask - Preserve current explicit style and theme props while adding CSS block authoring as an additional style source.

[x] 1.2 Section - CSS Parser Adapter and Syntax Recovery
Introduce a parser boundary that accepts real CSS stylesheet text and
normalizes parser output into an internal shape used by later phases.

[x] 1.2.1 Task - Select and isolate the CSS parser strategy
Evaluate parser options and hide the selected implementation behind a
small adapter so the DSL and compiler do not depend on parser-specific
data structures.

[x] 1.2.1.1 Subtask - Evaluate available Elixir, Erlang, NIF, or port-based CSS parser options against CSS Syntax stylesheet parsing and recovery needs.
[x] 1.2.1.2 Subtask - Define the parser adapter input and output contract, including source spans, rule order, declaration order, and recoverable error reporting.
[x] 1.2.1.3 Subtask - Add a fallback parser-selection decision record if no dependency satisfies the required CSS Syntax-compatible behavior.

[x] 1.2.2 Task - Normalize parsed stylesheet rules
Convert parser output into a deterministic internal representation that
later phases can match, cascade, translate, and inspect.

[x] 1.2.2.1 Subtask - Normalize style rules, selector lists, declaration names, declaration values, importance flags, source spans, and source order.
[x] 1.2.2.2 Subtask - Preserve recoverable parser diagnostics with enough source context for author-facing messages.
[x] 1.2.2.3 Subtask - Normalize unsupported at-rules into ignored diagnostic entries rather than dropping them silently.
[x] 1.2.2.4 Subtask - Ensure comments and insignificant whitespace do not affect deterministic parser output.

[x] 1.3 Section - Authoring Diagnostics and Inspection
Make CSS block behavior visible to authors before any canonical style
lowering changes runtime output.

[x] 1.3.1 Task - Add CSS authoring diagnostics
Define the diagnostic categories and severity rules for parse recovery
and ignored CSS constructs.

[x] 1.3.1.1 Subtask - Add diagnostics for parser recovery, malformed declaration values, ignored at-rules, ignored selectors, and ignored properties.
[x] 1.3.1.2 Subtask - Distinguish fatal parser failures from recoverable CSS issues that can continue through style lowering.
[x] 1.3.1.3 Subtask - Include source block id, selector text, declaration name, and source span where available.
[x] 1.3.1.4 Subtask - Keep diagnostic ordering deterministic across equivalent authored modules.

[x] 1.3.2 Task - Expose parsed CSS inspection output
Let developers inspect CSS blocks and parser diagnostics without running
a renderer or relying on runtime stylesheet output.

[x] 1.3.2.1 Subtask - Extend inspection output to list authored CSS blocks, normalized rule count, declaration count, ignored construct count, and recoverable parse diagnostics.
[x] 1.3.2.2 Subtask - Extend export output with deterministic CSS block metadata suitable for review diffs.
[x] 1.3.2.3 Subtask - Add examples that show valid CSS, recoverable parser issues, and ignored unsupported at-rules.

[x] 1.4 Section - Phase 1 Integration Tests
Validate authored CSS block parsing, ordering, diagnostics, and inspection
before selector matching and canonical style lowering are introduced.

[x] 1.4.1 Task - CSS block authoring scenarios
Verify the DSL accepts valid CSS stylesheet blocks and preserves
deterministic source metadata.

[x] 1.4.1.1 Subtask - Verify a module with one CSS block parses valid selector and declaration syntax successfully.
[x] 1.4.1.2 Subtask - Verify a module with multiple CSS blocks preserves deterministic block and rule source order.
[x] 1.4.1.3 Subtask - Verify CSS block authoring composes with existing style, theme, and widget declarations without changing their public syntax.
[x] 1.4.1.4 Subtask - Verify malformed block placement fails with an actionable DSL diagnostic.

[x] 1.4.2 Task - Parser recovery and inspection scenarios
Verify CSS parser recovery and inspection output are deterministic and
useful before lowering is implemented.

[x] 1.4.2.1 Subtask - Verify recoverable CSS syntax errors produce diagnostics while preserving later valid rules.
[x] 1.4.2.2 Subtask - Verify unsupported at-rules are represented as ignored diagnostics with source context.
[x] 1.4.2.3 Subtask - Verify comments and whitespace do not change normalized parser output.
[x] 1.4.2.4 Subtask - Verify inspection and export output list CSS block metadata and diagnostics in deterministic order.
Loading
Loading