Define CultUI style system target
This commit is contained in:
parent
83ad5bcb7d
commit
fc6c3d1017
3 changed files with 261 additions and 13 deletions
232
docs/cultui-style-system.md
Normal file
232
docs/cultui-style-system.md
Normal file
|
|
@ -0,0 +1,232 @@
|
|||
# CultUI Composition And Style System
|
||||
|
||||
CultUI is Eve's UI DSL.
|
||||
|
||||
The old CultUI was a Unity code-first composition library. Its best idea was
|
||||
ergonomic binary composition: start with a vertical base layout, then use
|
||||
horizontal and grid sugar to finish the tree without making every screen feel
|
||||
like manual box bookkeeping.
|
||||
|
||||
The new CultUI keeps that ergonomic shape, but moves the authority into Eve's
|
||||
portable retained surface model. A provider publishes a CultUI tree and style
|
||||
state. Eve runtimes lower that tree into browser, Direct2D, UIKit, Android, TUI,
|
||||
or future clients. The renderer is not the designer. The stylesheet is not the
|
||||
truth.
|
||||
|
||||
## Objectives
|
||||
|
||||
- Make composition readable enough to write by hand and structured enough to
|
||||
generate from typed providers.
|
||||
- Preserve the builder ergonomics of vertical-first composition with horizontal
|
||||
and grid sugar.
|
||||
- Treat styling as typed provider-owned state, not as hidden renderer CSS.
|
||||
- Make cross-runtime lowering boring: tokens, rules, variants, states, and
|
||||
capability gaps are explicit.
|
||||
- Learn from CSS without inheriting the parts that made CSS a haunted attic:
|
||||
global selector fights, cascade traps, specificity escalation, layout/style
|
||||
entanglement, and browser-only assumptions.
|
||||
|
||||
## Authority
|
||||
|
||||
- Provider owns the CultUI tree, style profiles, token values, variants,
|
||||
accepted commands, and `style.patch` results.
|
||||
- CultMesh owns publication, subscriptions, replay, freshness, and provenance.
|
||||
- Eve owns the CultUI contract, parser/compiler, renderer parity harness, and
|
||||
local input/sensor publication.
|
||||
- Runtimes own lowering into local UI primitives: DOM/CSS variables,
|
||||
DirectWrite/Direct2D brushes, UIKit views, Android views/styles, TUI cells, or
|
||||
overlays.
|
||||
|
||||
CSS, UIKit, Android XML, Direct2D brushes, and TUI attributes are generated
|
||||
lowerings. They are not portable state owners.
|
||||
|
||||
## Composition Model
|
||||
|
||||
CultUI's default composition axis is vertical. The common tree should read like
|
||||
the shape a person sees:
|
||||
|
||||
```cultui
|
||||
surface repixelizer.operator
|
||||
pane "Repixelizer hosted demo"
|
||||
text "Force fake pixel art back onto a real grid."
|
||||
h
|
||||
card "Open demo"
|
||||
card "Upload image"
|
||||
end
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
The structural primitives should stay small:
|
||||
|
||||
- `surface`: root of a provider-owned UI surface.
|
||||
- `v` / implicit stack: vertical flow.
|
||||
- `h`: horizontal flow.
|
||||
- `grid`: repeated or dashboard-like layout.
|
||||
- `dock`: rails and fixed regions.
|
||||
- `pane`: section with stable role and optional title.
|
||||
- `card`: repeated or framed unit.
|
||||
- `text`, `metric`, `image`, `control.*`, `inspector.*`, `embed.*`: content
|
||||
and interaction leaves.
|
||||
|
||||
Builder sugar should lower into the same tree every runtime receives. A
|
||||
horizontal helper is not a different layout authority; it is a more humane way
|
||||
to write a tree.
|
||||
|
||||
## Style Model
|
||||
|
||||
CultUI style has four layers:
|
||||
|
||||
1. Tokens: named values owned by the provider.
|
||||
2. Roles: semantic component intent such as `body`, `title`, `danger`, `primary`,
|
||||
`mono`, `surface`, `panel`, or `pixel-art-preview`.
|
||||
3. Variants: named style packages for a component or profile, such as
|
||||
`repixelizer-retro-card`.
|
||||
4. States: renderer-observed state such as focused, pressed, disabled, stale,
|
||||
predicted, denied, selected, loading, or capability-gap.
|
||||
|
||||
The portable style document should look like data:
|
||||
|
||||
```json
|
||||
{
|
||||
"profile": "repixelizer.retro.pixel",
|
||||
"tokens": {
|
||||
"colorBackgroundTop": "#01040b",
|
||||
"colorPanel": "#0a2239",
|
||||
"colorText": "#efe5c9",
|
||||
"fontTitle": "Press Start 2P",
|
||||
"fontBody": "VT323",
|
||||
"borderWidthPx": 4,
|
||||
"pixelArt": true,
|
||||
"scanlineOverlay": true
|
||||
},
|
||||
"variants": {
|
||||
"card.retro": {
|
||||
"role": "card",
|
||||
"tokens": {
|
||||
"borderBottomWidthPx": 5,
|
||||
"cornerAccentPx": 12
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Rules should target component roles, variants, and state, not arbitrary global
|
||||
text selectors. If a style cannot explain which component role or variant it
|
||||
serves, it probably belongs in a runtime lowerer or nowhere.
|
||||
|
||||
## What CultUI Takes From CSS
|
||||
|
||||
Keep:
|
||||
|
||||
- reusable tokens;
|
||||
- inheritance for a narrow set of text and color defaults;
|
||||
- responsive constraints;
|
||||
- stateful styling;
|
||||
- media/capability queries;
|
||||
- custom properties as a browser lowering target.
|
||||
|
||||
Cut:
|
||||
|
||||
- global selector soup;
|
||||
- specificity games;
|
||||
- source-order dependency as a normal design tool;
|
||||
- implicit layout side effects hidden in style rules;
|
||||
- browser-only units as portable truth;
|
||||
- pseudo-elements as the only way to express common decoration;
|
||||
- untyped stringly class names as the core style API.
|
||||
|
||||
## Layout And Style Separation
|
||||
|
||||
Layout belongs in the CultUI tree and layout props. Style may influence spacing,
|
||||
border, typography, colors, and decoration, but it should not secretly rewrite
|
||||
the semantic structure.
|
||||
|
||||
Allowed style influence:
|
||||
|
||||
- gaps, padding, border widths, radius, shadows;
|
||||
- typography and text roles;
|
||||
- image rendering mode;
|
||||
- motion preferences;
|
||||
- visibility of purely decorative layers such as scanlines.
|
||||
|
||||
Suspicious style influence:
|
||||
|
||||
- changing component kind;
|
||||
- reparenting;
|
||||
- hiding provider-owned state without an advertised reason;
|
||||
- replacing a command control with a different command;
|
||||
- making stale/denied/predicted state invisible.
|
||||
|
||||
## Cross-Runtime Lowering
|
||||
|
||||
Each runtime needs one style lowerer:
|
||||
|
||||
- Web: tokens to CSS custom properties and a small stable class set.
|
||||
- Fensalir Direct2D: tokens to brushes, text formats, panel geometry, image
|
||||
sampling flags, and overlay materials.
|
||||
- iOS/UIKit: tokens to colors, fonts, view metrics, layer borders, and image
|
||||
sampling.
|
||||
- Android/Kotlin: tokens to native colors, typefaces, dimensions, view
|
||||
backgrounds, and image sampling.
|
||||
- TUI: tokens to color pairs, text roles, borders, density, and glyph hints.
|
||||
|
||||
Runtime lowerers must report capability gaps. If Android cannot yet render
|
||||
Repixelizer's pixel-art image preview or cleanup canvas, the surface should say
|
||||
that plainly instead of faking a control that cannot carry the command.
|
||||
|
||||
## Style Patches
|
||||
|
||||
Style controls emit `style.patch`. The provider accepts, rejects, or reconciles
|
||||
the patch and republishes the next surface version.
|
||||
|
||||
Local preview is allowed, but it must be marked pending. Provider state is the
|
||||
authority.
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "surface-command",
|
||||
"schema": "gamecult.eve.command.v1",
|
||||
"command": "style.patch",
|
||||
"payload": {
|
||||
"profile": "repixelizer.retro.pixel",
|
||||
"tokens": {
|
||||
"colorAccent": "#ffd84a"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Repixelizer First Target
|
||||
|
||||
Repixelizer is the first useful proving ground because its style is not generic
|
||||
dashboard chrome. The portable style system must carry:
|
||||
|
||||
- pixel fonts;
|
||||
- dark shell surfaces;
|
||||
- blue panels;
|
||||
- warm yellow/orange accents;
|
||||
- chunky borders;
|
||||
- corner accents;
|
||||
- scanline and pixel-grid decoration;
|
||||
- pixelated image sampling;
|
||||
- comparison/editor capability gaps.
|
||||
|
||||
If CultUI can make Repixelizer recognizable across web, Direct2D, iOS, and
|
||||
Android without smuggling CSS into every runtime, the mousetrap is earning its
|
||||
name.
|
||||
|
||||
## Design Test
|
||||
|
||||
For every CultUI style feature, ask:
|
||||
|
||||
- What provider-owned value does this express?
|
||||
- Which component role or state does it serve?
|
||||
- How does each runtime lower it?
|
||||
- What happens when a runtime cannot lower it?
|
||||
- Can the user or provider patch it through a typed command?
|
||||
- Does this make the UI more portable, or did we just reinvent CSS cruft with
|
||||
cleaner indentation?
|
||||
|
||||
If the answer is awkward, stop and sharpen the contract before adding syntax.
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
# Eve DSL And Reactive CultMesh Bindings
|
||||
# CultUI DSL And Reactive CultMesh Bindings
|
||||
|
||||
Eve surfaces need a small declarative language for visual composition. The DSL
|
||||
is not a command language for agents and not an application state owner. It is a
|
||||
portable way to describe a surface that Eve can lower into the shared
|
||||
Eve surfaces need a small declarative language for visual composition. That DSL
|
||||
is CultUI. It is not a command language for agents and not an application state
|
||||
owner. It is a portable way to describe a surface that Eve can lower into the shared
|
||||
`gamecult.eve.surface.v1` retained tree.
|
||||
|
||||
## Authority
|
||||
|
|
@ -95,7 +95,7 @@ rerender calls.
|
|||
|
||||
## DSL Contract
|
||||
|
||||
The DSL should stay declarative:
|
||||
CultUI should stay declarative:
|
||||
|
||||
- describe components, bindings, and actions;
|
||||
- avoid hidden imperative renderer behavior;
|
||||
|
|
@ -139,6 +139,11 @@ Do not turn this into a universal scripting language. If a feature needs
|
|||
authority, persistence, or side effects, it belongs behind a provider command or
|
||||
CultMesh action, not inside the visual DSL.
|
||||
|
||||
The composition surface should preserve CultUI's old ergonomic instinct:
|
||||
vertical layout is the base case, with horizontal and grid sugar lowering into
|
||||
the same retained tree. Styling is a first-class typed system, not a bag of CSS
|
||||
selectors. See [cultui-style-system.md](./cultui-style-system.md).
|
||||
|
||||
## Public Context
|
||||
|
||||
The DSL is the renderer-facing half of the public surface-web claim. The
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
# Eve Surface Contract v1
|
||||
|
||||
`gamecult.eve.surface.v1` is the shared CultMesh UI document for Eve surfaces.
|
||||
It is the contract that CultUI should consume. Renderers may be web, UIKit,
|
||||
Android native views, Flutter, Windows Direct2D/DirectWrite, or another local
|
||||
client, but the semantic surface is the same retained tree.
|
||||
It is the retained tree that CultUI emits and Eve runtimes lower. Renderers may
|
||||
be web, UIKit, Android native views, Flutter, Windows Direct2D/DirectWrite, or
|
||||
another local client, but the semantic surface is the same retained tree.
|
||||
|
||||
## Authority
|
||||
|
||||
|
|
@ -42,11 +42,17 @@ These fields are display projections. New renderers should prefer
|
|||
|
||||
## Eve DSL
|
||||
|
||||
The Eve DSL is a source language for authoring `gamecult.eve.surface.v1`
|
||||
documents. It is not a second runtime authority. A DSL compiler may lower cards,
|
||||
text, metrics, lists, graphs, charts, formulas, and composites into
|
||||
`surface.root`, while CultMesh still owns live state identity and providers still
|
||||
own accepted commands.
|
||||
CultUI is Eve's DSL for authoring `gamecult.eve.surface.v1` documents. It is
|
||||
not a second runtime authority. A DSL compiler may lower cards, text, metrics,
|
||||
lists, graphs, charts, formulas, and composites into `surface.root`, while
|
||||
CultMesh still owns live state identity and providers still own accepted
|
||||
commands.
|
||||
|
||||
The composition model inherits the useful part of the old Unity CultUI: start
|
||||
from a vertical base layout, then use horizontal and grid sugar to complete the
|
||||
tree without making every screen feel like manual box bookkeeping. See
|
||||
[cultui-style-system.md](./cultui-style-system.md) for the composition and
|
||||
styling design target.
|
||||
|
||||
Browser reference support starts in `web/eve-dsl.js` and the fixture
|
||||
`web/fixtures/reactive-composition.eve`. The first binding primitives are:
|
||||
|
|
@ -212,6 +218,11 @@ brushes, overlay material parameters, TUI attributes, or platform equivalents.
|
|||
For migrated products, the first source of truth may be an existing CSS system,
|
||||
but the canonical portable form is the Eve token set, not the stylesheet.
|
||||
|
||||
CultUI style is intentionally not CSS with different punctuation. Style should
|
||||
be typed provider-owned state made of tokens, roles, variants, and states.
|
||||
Runtime stylesheets, brushes, platform view styles, and TUI attributes are
|
||||
lowerings, not authorities.
|
||||
|
||||
Style controls are ordinary controls whose command is usually `style.patch`.
|
||||
They synchronize appearance by sending token edits back to the provider. The
|
||||
provider accepts or rejects the patch and republishes the next surface version.
|
||||
|
|
|
|||
Loading…
Reference in a new issue