# Layout Runtime v1 Design Doc

## Summary

This project is a small ECMAScript-native UI runtime for expressive layouts on the web.

It is based on one rule:

**Parents compose children.**

Children do not decide where they go. Children describe themselves, measure themselves within constraints, and render inside the room they are given. Parents choose layout modes, choose child presentation modes, allocate rooms, place children, and make the final decision.

The runtime outputs real DOM so it keeps:

- accessibility
- native text rendering
- forms and input behavior
- focus handling
- selection
- browser event behavior

The browser is used as the output and interaction platform, not as the main layout engine.

The goal is to avoid:

- CSS layout chaos
- global constraint solvers
- JSX/DSL syntax
- large framework complexity
- full canvas/WebGL rendering

The initial target is a Persona-style messaging UI with expressive but sane layout.

---

## Goals

### Primary goals

Build a system that:

- uses plain ECMAScript
- has a small runtime
- produces semantic DOM output
- supports parent-owned layout
- supports responsive layout by local parent policy
- supports simple decorative layers
- compiles layout to flat positioned output
- is predictable and debuggable

### Non-goals for v1

v1 will not try to solve:

- full general graph layout
- arbitrary child-to-child negotiation
- line-by-line text geometry
- custom text shaping
- shape-aware text flow
- cross-parent dependency systems
- a full React-like component framework
- a global constraint solver
- a custom language or transpiler-only syntax

---

## Core idea

The web mixes too many concerns into one structure.

This runtime separates them conceptually:

- **semantic tree**: what things are
- **layout ownership tree**: which parent composes which children
- **visual output scene**: the final positioned DOM/SVG result

The runtime does not expose that as a complicated public architecture. Publicly, the system stays simple:

- build nodes in plain JavaScript
- parents choose layout
- children measure and render
- runtime outputs DOM

---

## Mental model

The mental model is:

**Children describe themselves. Parents compose children.**

More concretely:

### Children are responsible for

- semantic meaning
- intrinsic content
- measurement within constraints
- rendering inside assigned bounds
- local decoration inside or around their room
- optional overflow declaration

### Parents are responsible for

- choosing a local layout mode
- choosing child presentation modes
- measuring children under chosen constraints
- resolving sibling conflicts
- assigning final rooms
- placing children
- ordering visual layers
- optionally refining once

### Parents have final authority

Children may inform layout. They do not negotiate indefinitely. Children do not move siblings. Children do not decide final placement.

The process must stop.

---

## Why this exists

CSS layout is often hard because responsibility is unclear.

A parent affects children, children affect parent sizing, siblings affect each other indirectly, and rules can come from anywhere. This makes even simple layout feel global and unstable.

This runtime replaces that with:

- local ownership
- explicit phases
- bounded adaptation
- deterministic final authority

It borrows the clean part of systems like Compose while keeping DOM output and avoiding a large framework.

---

## Product shape

This project starts as a small layout/runtime library, not a full framework.

It should feel closer to:

- a compact DOM/runtime library
- a modern jQuery/D3-style construction API
- a retained UI tree with explicit layout passes

It should not feel like:

- React
- JSX
- a schema language
- a CSS replacement language
- a giant UI framework

---

## Authoring model

### Principle

The public API should use only normal ECMAScript syntax:

- functions
- method calls
- closures
- objects
- arrays
- modules

No JSX. No new syntax. No declarative mini-language.

### API style

The API should feel like a small fluent builder library in the spirit of jQuery or D3, but for retained layout rather than DOM mutation.

The exact API can evolve, but the style should stay:

- simple
- chainable where useful
- plain JS
- small vocabulary

### Simplicity rule

v1 should prefer one simple authoring style over mixing multiple styles. The system should start minimal and add features only when needed.

---

## Output model

The runtime emits:

- real DOM elements
- mostly absolute-positioned layout boxes
- z-index ordering
- optional SVG or DOM overlay layers for decoration

This means:

- browser text rendering remains native
- accessibility remains native
- interaction remains native
- layout logic belongs to the runtime

The browser is not asked to solve the main scene layout beyond intrinsic measurement of leaves and normal internal text layout.

---

## Rendering model

The runtime is a retained tree.

Nodes persist between updates. Updates invalidate affected layout/render regions. The runtime recomputes only what is necessary.

It is not:

- immediate-mode canvas rendering
- direct jQuery-style DOM mutation as the primary abstraction

---

## Layout model

### Default rule

The parent determines where the children go.

This is the foundational invariant.

### Child freedom

A child is free to decorate its room however it wants, as long as:

- it renders within or explicitly overflows its assigned space
- it does not reposition itself outside parent authority
- it does not affect sibling placement directly

### Parent adaptation

Sometimes the parent must adjust after hearing from children.

Example:

- a child reports a larger preferred width
- a child reports overflow
- a child's chosen presentation mode no longer fits

The parent may revise layout, but only within a bounded pass structure.

---

## Layout modes

### Container layout modes

A layout parent may support multiple modes such as:

- roomy
- compact
- stacked
- dense

Mode choice is controlled by the parent.

### Mode selection

For v1, mode selection is driven by predicates, not media-query syntax and not child self-selection.

The parent decides:

- which mode applies in current conditions
- what those conditions are
- which child presentation modes go with that container mode

Example kinds of conditions:

- available width
- available height
- child count
- measured aggregate size
- viewport constraints
- container-local state

### Why parent-owned modes

This keeps responsiveness local and understandable.

Instead of every child hiding its own breakpoint logic, the parent decides:

- what arrangement it wants
- how to trade off sibling needs
- how the whole group should degrade

---

## Child presentation modes

Children may support multiple presentation modes, but the parent chooses them.

Examples:

- full
- compact
- minimal

These are not autonomous child variants. They are parent-selected render/measure modes.

A child must not decide its own mode at runtime based on private policy in a way that breaks parent authority.

This keeps adaptation centralized.

---

## Measurement contract

v1 keeps the child contract intentionally simple.

A child measures itself under constraints and returns:

- measured size
- optional overflow insets

Possible future additions include min/preferred/max size, but v1 should stay minimal unless required by the implementation.

### v1 child measurement output

- width
- height
- overflowTop
- overflowRight
- overflowBottom
- overflowLeft

### Why so small

v1 is not trying to solve typography-driven art direction or fine-grained text geometry. The main goal is proving the parent-owned layout model.

---

## Text in v1

Text is treated as a normal block-measured child.

The browser may still wrap text internally, but the parent sees only resulting bounds.

v1 does not expose:

- line boxes
- baselines
- glyph positions
- contour extraction
- shape-aware wrapping

This is deliberately postponed.

### Why

Text geometry becomes a complexity multiplier very quickly. It is not required to validate the core architecture.

If the parent-owned layout model works, richer text geometry can be added later as a specialized extension.

---

## Negotiation model

The runtime allows bounded consultation, not open-ended negotiation.

### Process

1. Parent chooses constraints and candidate layout mode
2. Children measure within those constraints
3. Parent places children
4. Optional single refinement pass
5. Finalize

### Important rule

Children may report needs. Children may not bargain forever.

Children do not:

- reject placement indefinitely
- trigger unbounded reflow loops
- reposition siblings
- solve layout globally

### Conflict resolution

When siblings compete, the parent decides using policy.

v1 should favor:

- simple priority ordering
- optional overrides
- mode fallback

It should not use flex-like weighting as the central concept.

---

## Iteration budget

v1 allows at most:

- one initial measure/layout pass
- one optional refinement pass

That is enough to support practical adjustment while keeping the system predictable.

No open-ended convergence loops in v1.

---

## Relative references

The design discussed relative references like:

- previous sibling row
- nearest matching child
- first item of a type

These are useful, but they are not foundational in v1.

v1 should start with a simpler parent-owned placement model and only add scoped relative queries when necessary.

If added later, relative references should be:

- local to a parent scope
- deterministic
- compiled to explicit dependencies
- limited in cardinality and meaning

They should never become a reintroduction of CSS-style hidden global dependency.

---

## Visual layers

The runtime supports two kinds of decoration:

### Child-owned decoration

A child may render decorative chrome in or around its room.

Examples:

- message bubble background
- avatar halo
- icon plate
- local highlight

### Parent-owned decoration

A parent may render overlays or shared visual treatment around its children.

Examples:

- group background
- thread connector
- active conversation highlight
- transition layer

This supports expressive layout without requiring the DOM structure to match the decorative structure exactly.

---

## Semantics

Semantics remain real and primary.

The runtime should preserve:

- actual element tags where appropriate
- roles where needed
- focusable elements as real focusable DOM
- native form controls where possible
- screen-reader compatibility

The semantic hierarchy belongs to the runtime tree and is emitted as real DOM.

Layout compilation must not destroy semantics.

---

## DOM strategy

The DOM strategy is:

- use semantic nodes for content and interaction
- compute explicit positioned frames
- emit positioned DOM nodes
- emit optional SVG overlays for decoration

This keeps the strengths of the web while moving layout authority into the runtime.

---

## Animation and transitions

Animation must not break layout ownership.

Two important cases were discussed:

### Scrollbar reflow

This is treated as a normal constraint change. Container width changes, affected parents remeasure and replace layout.

### Elements animating between parents

This must not become a layout exception.

The layout model stays:

- old parent owns old frame
- new parent owns new frame

A transition layer may interpolate visually between those states. Animation is a rendering concern, not a reason to weaken layout authority.

---

## Layout boundaries

Not every node needs to be a layout parent.

A node may be:

- a semantic/leaf node
- a simple grouping node
- a layout-owning parent

v1 should keep layout ownership explicit and cheap.

This avoids making every node a custom layout engine.

---

## Built-in layout vocabulary

v1 should start with a very small set of built-in containers with concise names.

Examples of the right scale:

- vertical stack
- horizontal stack
- overlay
- freeform parent layout

Exact names can stay concise, but the set should remain minimal.

The goal is not to design a huge catalog. The goal is to validate the core model.

A freeform parent layout container is likely necessary for the first demo.

---

## Parent policy

The parent needs a simple way to arbitrate child competition.

v1 should use simple concepts such as:

- importance
- ordering
- mode choice
- fallback

Avoid turning this into flexbox weights or a full solver.

The parent should be able to say, in effect:

- keep this child roomy as long as possible
- collapse that child earlier
- let that decoration overflow
- prefer this layout mode if it fits

---

## Runtime phases

The runtime should have explicit phases.

1. **Build** — Build or update the retained tree from plain ECMAScript API usage.
2. **Mode choice** — Each layout parent chooses its active container mode.
3. **Child mode choice** — Each layout parent chooses presentation modes for children.
4. **Measure** — Children measure themselves under given constraints.
5. **Place** — Parent computes final child rooms and positions.
6. **Refine** — Optional single extra pass if parent requests it.
7. **Render** — Emit DOM/SVG output.

These phases should be visible in the architecture and in debugging tools.

---

## Debuggability

Debuggability is a primary design requirement.

The first devtools priority is:

**resolved frames**

A developer must be able to inspect:

- final child bounds
- parent bounds
- overflow
- active mode
- child presentation modes
- z/layer order

This system only wins if it is easier to understand than CSS.

Later tooling may expose more, but resolved layout output must come first.

---

## Performance model

Performance should come from:

- small runtime
- local layout ownership
- retained tree
- bounded passes
- explicit invalidation
- simple measurement contracts

The system deliberately avoids:

- global solving
- hidden cascading dependency
- open-ended layout loops

---

## Initial implementation constraints

To keep v1 focused:

### Keep

- plain ECMAScript API
- small runtime
- parent-owned layout
- predicate-based container mode choice
- parent-selected child presentation modes
- real DOM output
- block-bound text treatment
- one optional refinement pass
- concise built-in containers
- child and parent decoration support

### Defer

- advanced text geometry
- shape-aware text layout
- general graph layout
- cross-parent anchor systems
- generalized selector dependencies
- large component catalogs
- framework-like state/runtime complexity
- multiple competing authoring styles

---

## First demo target

The first serious demo is a Persona-style messaging app.

This is a good target because it exercises:

- parent-owned composition
- nested layout
- responsive local mode choice
- message groups
- overlays
- expressive visuals
- text-driven intrinsic sizing without requiring fine text geometry
- semantic DOM output
- animation layers

It is complex enough to prove the model without requiring the full complexity of a desktop UI system.

---

## API philosophy

The API should feel like:

- modern JavaScript
- small, direct, chainable where useful
- closer to jQuery/D3 in spirit than React
- no syntax invention
- no DSL
- no JSX

The system should exploit ECMAScript by leaning on:

- functions
- closures
- fluent method calls
- normal composition patterns

The final API is not frozen in this document, but its style is.

---

## Guiding principles

1. Parents compose children.
2. Children describe themselves; parents decide.
3. Use the DOM as output, not as the layout brain.
4. Keep semantics real.
5. Start simple.
6. Avoid global solvers.
7. Bound adaptation.
8. Make layout local and inspectable.
9. Defer complexity until proven necessary.
10. Stay inside normal ECMAScript.

---

## Open items for later, not for v1

These are intentionally postponed:

- richer text metrics
- shape-based text flow
- scoped relative references
- cross-parent spatial relations
- advanced transition orchestration
- richer child contracts
- custom extensibility model
- larger standard library of containers and leaves

They should only be added when the v1 model proves insufficient.

---

## Proposed v1 statement

> A small ECMAScript-native retained UI runtime for the web, where parents choose layout modes, measure and place children, and emit semantic DOM with explicit positioned output.

That is the design.

The next step is turning this into:

1. a runtime architecture doc, or
2. a concrete API sketch for the messaging demo.
