Surface
incubatingStatus of this Document
This report was published by the User Journal Graph Community Group . It is not a W3C Standard nor is it on the W3C Standards Track. Please note that under the W3C Community Contributor License Agreement (CLA) there is a limited opt-out and other conditions apply. Learn more about W3C Community and Business Groups .
Title: org.openuji.specs.ujg.surface.v1
Status: incubating implementation extension for generator-facing surface materialization carried in UJG Core extensions.
1. Namespace
Canonical namespace string:
org.openuji.specs.ujg.surface.v1Payload location:
extensions["org.openuji.specs.ujg.surface.v1"]Published JSON Schema:
https://ujg.specs.openuji.org/ed/ns/surface.schema.json
2. Purpose
This extension is the main generator-facing materialization payload for surface realization.
It exists to answer, in one self-contained place, the questions a generator needs answered before it can materialize a state or shared template:
what kind of surface is this,
which slots or regions matter,
which semantic blocks belong on the surface,
which structural variants are expected,
which token or theme sources influence it,
which presentation modes matter,
which component-family placeholder or shared library family it expects,
which recipes or semantic render roles should be used.
This extension intentionally merges structural, visual, and component-family placeholder concerns so that a generator can understand the surface without first resolving separate scaffold, design, and library extensions.
3. Scope
This extension covers:
surface kind,
composition pattern,
slots or regions,
semantic blocks assigned to slots,
structural variants,
grouped theme description including token sources and supported modes,
semantic surface and block recipes,
library family placeholder identity,
platform adaptation posture.
The extension is self-contained. A generator may combine it with Templates, Routing, and L10n, but it does not need private IDs from any other extension to understand the surface payload.
4. Non-goals
This extension does not standardize:
full component trees,
DOM trees,
raw CSS,
utility-class mappings,
framework component files,
platform theme code,
exact breakpoints,
pixel-perfect cross-platform parity.
5. Primary Attachment Targets
TemplateStateCompositeState
Template is the preferred reusable host for shared surface identity. State is the preferred host
for effective realized surfaces. CompositeState is the preferred host for subflow-wide defaults.
6. Secondary Attachment Targets
Journeyfor broad surface defaults such as theme posture or common slot namesTransitionwhen a transition needs lightweight presentation hints for its invocation or result affordance
7. Discouraged Or Disallowed Attachment Targets
OutgoingTransitionGroupis discouraged because it groups reusable outgoing edges rather than realized surfaces.Routeis discouraged because addressability belongs in Routing and should not become a surrogate surface host.MessageBundleis disallowed in normal use because localization resources are not surface resources.UJGDocumentis disallowed because Core extensions are node-scoped.
8. Inheritance Model
For a realized state, generators should apply surface inheritance in this order:
Journeyeach enclosing
CompositeState, from outermost to innermostresolved
Template, iftemplateRefis presentthe local
State
For transition-attached surface hints, generators should use:
Journeyenclosing
CompositeStatesource
Statelocal
Transition
Template inheritance is the main reusable mechanism for shared surfaces. State attachment is the main override mechanism.
9. Precedence And Override Rules
When the same surface concern appears in more than one host, use this precedence order:
StateTemplateinnermost
CompositeStateouter
CompositeStateJourney
For transition-local hints, use:
Transitionsource
Stateinnermost
CompositeStateouter
CompositeStateJourney
Merge and replacement rules:
surfaceKind,composition,library, andadaptationare singular values or objects. The more specific value replaces the inherited one, except where object members merge as described below.theme.defaultMode,theme.defaultContrastMode, andtheme.defaultDensityModeare singular. The more specific value replaces the inherited one.theme.tokenSources,theme.supportedModes,theme.supportedContrastModes, andtheme.supportedDensityModescombine across inheritance with duplicate removal.slotsmerges byname.blocksmerges byid.variantsmerges byname.recipesmerges by semantic key.a more specific
slot,block, orvariantmay suppress an inherited one by repeating the same identity and settingdisabled: true.
10. Property Vocabulary
surfaceKind: the semantic kind of materialized surface. Expected shape: string. Recommended values are listed below. Implementation intent: lets a generator choose a page, screen, dialog, prompt, stream, or comparable container without defining platform code.composition: the high-level structural arrangement of the surface. Expected shape: string. Allowed categories are generic composition patterns such as stepped, split, stacked, or streaming. Implementation intent: gives generators enough structure to lay out major regions.slots: the named surface regions. Expected shape: array of strings or array of objects withnameand optionalrole,required,multiple, anddisabled. A string value is shorthand for a slot object whosenameis that string. Implementation intent: names the regions a generator must account for while allowing a compact form when slot metadata is not needed.blocks: the semantic content or interaction blocks that belong on the surface. Expected shape: array of objects withid,kind,slot, and optionalrecipe,appearanceRole,importance,variant, anddisabled. Implementation intent: gives generators a flat block plan without requiring a full component tree.variants: named structural overlays. Expected shape: array of objects withname,when, and optionaloverrides. Implementation intent: lets a producer declare compact, modal, native, or CLI-oriented surface variants without hard-coding framework conditions.theme: grouped theme description. Expected shape: object with optionaltokenSources,themeRef,defaultMode,supportedModes,defaultContrastMode,supportedContrastModes,defaultDensityMode, andsupportedDensityModes. Allowed categories fordefaultModeandsupportedModes:light,dark,system. Allowed categories fordefaultContrastModeandsupportedContrastModes:normal,high,system. Allowed categories fordefaultDensityModeandsupportedDensityModes:compact,comfortable,spacious. Implementation intent: keeps token sources and mode support in one object so the generator can see both the available modes and the preferred defaults.recipes: semantic recipe bindings. Expected shape: object whose keys are semantic roles such assurface,primaryAction,summary, ordangerNoticeand whose values are recipe names. Implementation intent: gives generators stable semantic presentation names instead of raw classes.library: grouped library placeholder. Expected shape: object withfamilyand optionalversion. Allowed categories: generic family IDs, published library identifiers, or registry or catalog family identifiers. A value such asshadcn-uiis valid when the target adapter knows how to resolve that family, and a published registry or catalog identifier is also valid when the producer wants to point to a more explicit source. Implementation intent: lets adapters choose the right component inventory without relying on file paths, install commands, or framework internals.adaptation: posture for cross-platform adaptation. Expected shape: string or object keyed by platform family. Allowed categories:strict,balanced,platform-native. Implementation intent: tells generators how tightly to preserve shared surface intent.
11. Recommended Controlled Values
Recommended surfaceKind values:
pagescreendialogsheetpanelwizard-steppromptstreamjob
Recommended composition values:
singlesplitstackedsteppedstreamingbackground
Recommended theme.defaultMode and theme.supportedModes values:
lightdarksystem
Recommended theme.defaultContrastMode and theme.supportedContrastModes values:
normalhighsystem
Recommended theme.defaultDensityMode and theme.supportedDensityModes values:
compactcomfortablespacious
Recommended adaptation values:
strictbalancedplatform-native
12. Processing Model
A generator implementing this extension should:
Resolve the effective graph host and, if present, resolve
templateRef.Compute the inherited surface payload using the inheritance and precedence rules above.
Normalize slot shorthand strings to slot objects.
Resolve the effective
surfaceKind,composition, groupedtheme, groupedlibrary, and recipe map.Merge and normalize
slots,blocks, and activevariants.Combine the resulting surface plan with Routing if the node has
routeRef.Combine the resulting surface plan with L10n if the node has
copyRef.Materialize a target-specific surface while preserving graph behavior as the source of truth.
Graph remains the source of truth for state and transition behavior. This extension only describes implementation-facing realization intent.
13. Cross-Stack Interpretation Notes
Web: map to pages, dialogs, drawers, shells, and block layouts in frameworks such as Next.js or Astro without standardizing file structure.
Native: map to screens, sheets, dialogs, and cards in React Native, Compose, or Flutter while preserving semantic slots and recipes.
CMS: map to page templates, editorial regions, and render recipes while leaving vendor internals outside the spec.
Commerce: map to storefront shells, checkout steps, side summaries, and action areas.
CLI or headless or background: map to prompts, streams, diagnostics sections, or job-status surfaces while reusing the same high-level slot and block semantics.
14. Published JSON Schema
The published schema for this extension is defined below and is published at
https://ujg.specs.openuji.org/ed/ns/surface.schema.json.
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://ujg.specs.openuji.org/ed/ns/surface.schema.json",
"title": "UJG Surface Extension Payload",
"type": "object",
"additionalProperties": false,
"properties": {
"surfaceKind": {
"type": "string",
"enum": ["page", "screen", "dialog", "sheet", "panel", "wizard-step", "prompt", "stream", "job"]
},
"composition": {
"type": "string",
"enum": ["single", "split", "stacked", "stepped", "streaming", "background"]
},
"slots": {
"type": "array",
"items": {
"oneOf": [
{ "type": "string" },
{ "$ref": "#/$defs/slot" }
]
}
},
"blocks": {
"type": "array",
"items": { "$ref": "#/$defs/block" }
},
"variants": {
"type": "array",
"items": { "$ref": "#/$defs/variant" }
},
"theme": { "$ref": "#/$defs/theme" },
"recipes": {
"type": "object",
"additionalProperties": { "type": "string" }
},
"library": { "$ref": "#/$defs/library" },
"adaptation": {
"oneOf": [
{
"type": "string",
"enum": ["strict", "balanced", "platform-native"]
},
{
"type": "object",
"additionalProperties": {
"type": "string",
"enum": ["strict", "balanced", "platform-native"]
}
}
]
}
},
"$defs": {
"slot": {
"type": "object",
"additionalProperties": false,
"properties": {
"name": { "type": "string" },
"role": { "type": "string" },
"required": { "type": "boolean" },
"multiple": { "type": "boolean" },
"disabled": { "type": "boolean" }
},
"required": ["name"]
},
"block": {
"type": "object",
"additionalProperties": false,
"properties": {
"id": { "type": "string" },
"kind": { "type": "string" },
"slot": { "type": "string" },
"recipe": { "type": "string" },
"appearanceRole": { "type": "string" },
"importance": {
"type": "string",
"enum": ["primary", "secondary", "supporting"]
},
"variant": { "type": "string" },
"disabled": { "type": "boolean" }
},
"required": ["id", "kind", "slot"]
},
"variant": {
"type": "object",
"additionalProperties": false,
"properties": {
"name": { "type": "string" },
"when": { "$ref": "#/$defs/selector" },
"overrides": {
"type": "object",
"additionalProperties": false,
"properties": {
"surfaceKind": {
"type": "string",
"enum": ["page", "screen", "dialog", "sheet", "panel", "wizard-step", "prompt", "stream", "job"]
},
"composition": {
"type": "string",
"enum": ["single", "split", "stacked", "stepped", "streaming", "background"]
},
"disabledSlots": {
"type": "array",
"items": { "type": "string" }
},
"disabledBlocks": {
"type": "array",
"items": { "type": "string" }
}
}
},
"disabled": { "type": "boolean" }
},
"required": ["name", "when"]
},
"selector": {
"type": "object",
"additionalProperties": false,
"properties": {
"axis": {
"type": "string",
"enum": ["platform", "viewport", "mode", "input", "context"]
},
"value": { "type": "string" }
},
"required": ["axis", "value"]
},
"theme": {
"type": "object",
"additionalProperties": false,
"properties": {
"tokenSources": {
"type": "array",
"items": { "type": "string" }
},
"themeRef": { "type": "string" },
"defaultMode": {
"type": "string",
"enum": ["light", "dark", "system"]
},
"supportedModes": {
"type": "array",
"items": {
"type": "string",
"enum": ["light", "dark", "system"]
}
},
"defaultContrastMode": {
"type": "string",
"enum": ["normal", "high", "system"]
},
"supportedContrastModes": {
"type": "array",
"items": {
"type": "string",
"enum": ["normal", "high", "system"]
}
},
"defaultDensityMode": {
"type": "string",
"enum": ["compact", "comfortable", "spacious"]
},
"supportedDensityModes": {
"type": "array",
"items": {
"type": "string",
"enum": ["compact", "comfortable", "spacious"]
}
}
}
},
"library": {
"type": "object",
"additionalProperties": false,
"properties": {
"family": { "type": "string" },
"version": { "type": "string" }
},
"required": ["family"]
}
}
} {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://ujg.specs.openuji.org/ed/ns/surface.schema.json",
"title": "UJG Surface Extension Payload",
"type": "object",
"additionalProperties": false,
"properties": {
"surfaceKind": {
"type": "string",
"enum": ["page", "screen", "dialog", "sheet", "panel", "wizard-step", "prompt", "stream", "job"]
},
"composition": {
"type": "string",
"enum": ["single", "split", "stacked", "stepped", "streaming", "background"]
},
"slots": {
"type": "array",
"items": {
"oneOf": [
{ "type": "string" },
{ "$ref": "#/$defs/slot" }
]
}
},
"blocks": {
"type": "array",
"items": { "$ref": "#/$defs/block" }
},
"variants": {
"type": "array",
"items": { "$ref": "#/$defs/variant" }
},
"theme": { "$ref": "#/$defs/theme" },
"recipes": {
"type": "object",
"additionalProperties": { "type": "string" }
},
"library": { "$ref": "#/$defs/library" },
"adaptation": {
"oneOf": [
{
"type": "string",
"enum": ["strict", "balanced", "platform-native"]
},
{
"type": "object",
"additionalProperties": {
"type": "string",
"enum": ["strict", "balanced", "platform-native"]
}
}
]
}
},
"$defs": {
"slot": {
"type": "object",
"additionalProperties": false,
"properties": {
"name": { "type": "string" },
"role": { "type": "string" },
"required": { "type": "boolean" },
"multiple": { "type": "boolean" },
"disabled": { "type": "boolean" }
},
"required": ["name"]
},
"block": {
"type": "object",
"additionalProperties": false,
"properties": {
"id": { "type": "string" },
"kind": { "type": "string" },
"slot": { "type": "string" },
"recipe": { "type": "string" },
"appearanceRole": { "type": "string" },
"importance": {
"type": "string",
"enum": ["primary", "secondary", "supporting"]
},
"variant": { "type": "string" },
"disabled": { "type": "boolean" }
},
"required": ["id", "kind", "slot"]
},
"variant": {
"type": "object",
"additionalProperties": false,
"properties": {
"name": { "type": "string" },
"when": { "$ref": "#/$defs/selector" },
"overrides": {
"type": "object",
"additionalProperties": false,
"properties": {
"surfaceKind": {
"type": "string",
"enum": ["page", "screen", "dialog", "sheet", "panel", "wizard-step", "prompt", "stream", "job"]
},
"composition": {
"type": "string",
"enum": ["single", "split", "stacked", "stepped", "streaming", "background"]
},
"disabledSlots": {
"type": "array",
"items": { "type": "string" }
},
"disabledBlocks": {
"type": "array",
"items": { "type": "string" }
}
}
},
"disabled": { "type": "boolean" }
},
"required": ["name", "when"]
},
"selector": {
"type": "object",
"additionalProperties": false,
"properties": {
"axis": {
"type": "string",
"enum": ["platform", "viewport", "mode", "input", "context"]
},
"value": { "type": "string" }
},
"required": ["axis", "value"]
},
"theme": {
"type": "object",
"additionalProperties": false,
"properties": {
"tokenSources": {
"type": "array",
"items": { "type": "string" }
},
"themeRef": { "type": "string" },
"defaultMode": {
"type": "string",
"enum": ["light", "dark", "system"]
},
"supportedModes": {
"type": "array",
"items": {
"type": "string",
"enum": ["light", "dark", "system"]
}
},
"defaultContrastMode": {
"type": "string",
"enum": ["normal", "high", "system"]
},
"supportedContrastModes": {
"type": "array",
"items": {
"type": "string",
"enum": ["normal", "high", "system"]
}
},
"defaultDensityMode": {
"type": "string",
"enum": ["compact", "comfortable", "spacious"]
},
"supportedDensityModes": {
"type": "array",
"items": {
"type": "string",
"enum": ["compact", "comfortable", "spacious"]
}
}
}
},
"library": {
"type": "object",
"additionalProperties": false,
"properties": {
"family": { "type": "string" },
"version": { "type": "string" }
},
"required": ["family"]
}
}
} 15. Minimal Example Payload
{
"@id": "urn:state:payment",
"@type": "State",
"extensions": {
"org.openuji.specs.ujg.surface.v1": {
"surfaceKind": "page",
"composition": "split",
"slots": ["header", "main", "aside", "footer"],
"blocks": [
{ "id": "summary", "kind": "summary", "slot": "aside", "recipe": "card.summary" },
{ "id": "form", "kind": "form", "slot": "main", "recipe": "form.default" }
],
"theme": {
"tokenSources": [
"https://example.com/tokens/base.json",
"https://example.com/tokens/brand.json"
],
"defaultMode": "light",
"supportedModes": ["light", "dark"],
"defaultContrastMode": "high",
"defaultDensityMode": "comfortable"
},
"recipes": {
"surface": "checkout-shell",
"primaryAction": "cta-emphasis"
},
"library": {
"family": "shadcn-ui",
"version": "1"
},
"adaptation": "balanced"
}
}
} {
"@id": "urn:state:payment",
"@type": "State",
"extensions": {
"org.openuji.specs.ujg.surface.v1": {
"surfaceKind": "page",
"composition": "split",
"slots": ["header", "main", "aside", "footer"],
"blocks": [
{ "id": "summary", "kind": "summary", "slot": "aside", "recipe": "card.summary" },
{ "id": "form", "kind": "form", "slot": "main", "recipe": "form.default" }
],
"theme": {
"tokenSources": [
"https://example.com/tokens/base.json",
"https://example.com/tokens/brand.json"
],
"defaultMode": "light",
"supportedModes": ["light", "dark"],
"defaultContrastMode": "high",
"defaultDensityMode": "comfortable"
},
"recipes": {
"surface": "checkout-shell",
"primaryAction": "cta-emphasis"
},
"library": {
"family": "shadcn-ui",
"version": "1"
},
"adaptation": "balanced"
}
}
} 16. Graduation Guidance
Thin parts that may later graduate into optional modules or shared references include:
a surface reference,
a slot reference,
a theme or token-source reference,
a recipe reference.
The following should remain extension-only:
block plans,
structural variants,
component-family placeholders,
adaptation posture,
merged structural and visual realization detail.