Strata component anatomy
One page per component, with the headings from section 17 of the design language. Each page is the component’s markup contract (section 18): plain HTML, React, Vue and Astro render exactly the DOM it shows, and binding tests compare against it.
Conventions
Section titled “Conventions”Class names use the ug- prefix, Bootstrap-style: a block (ug-button), modifiers
(ug-button--accent) and parts (ug-switch__knob). States come from native pseudo-classes and ARIA or
native attributes (:hover, :active, :focus-visible, :checked, :disabled, aria-invalid,
aria-busy, aria-pressed), never from state classes.
Strata attributes use the data-strata- prefix:
| Attribute | On | Meaning |
|---|---|---|
data-strata-face |
Any element the material pass lights | The relief primitive: raised, well, groove, knob, mark, ring or flat (below) |
data-strata-material |
A face, a component or a scope | A material role (buttonPrimary) or preset (lacquer); overrides the role default |
data-strata-elevation |
A raised face | An elevation token name (raised, floating); the component’s default when absent |
data-strata-level |
A component or a scope | relief, objects, instrument or scene, overriding the scope’s level |
data-strata-depth |
A scope | Depth for the subtree, 0–1 |
data-strata-theme |
The root or a scope | light, dark, contrast or contrast-dark; the root follows the system without it |
data-strata-density |
The root or a scope | compact, comfortable or spacious |
data-strata-size |
A component or a scope | small, medium (default) or large: indicator, switch and control sizes |
data-strata-mode |
The root or a scope | face: the GPU paints relief, so CSS paints flat faces (no bevel, shadow or finish) |
data-strata-preview |
A control | hover, active or focus: shows a state statically, for specimens and tests only |
data-strata-form |
A Switch’s row, or a Button or ToggleButton | slide, rocker, bat or wall: the switch’s hardware form (Switch, Forms); momentary (Button) or latching (ToggleButton): a push button (Button, ToggleButton) |
data-strata-down |
A push button, or a latching form’s key (.ug-latch) |
true while it is held (the pointer or a key down), false once released: its ring lit and its cap down; set by attachStrataPushButtons |
data-strata-form (latching forms) |
A Checkbox’s row, a RadioGroup’s or SegmentedControl’s fieldset | latching (Checkbox, SegmentedControl) or bank (RadioGroup): the native control drawn as latching buttons; flush, or none, is the look before (Checkbox, RadioGroup, SegmentedControl) |
data-strata-form (structural forms) |
A Slider’s drawn root (.ug-knob, .ug-fader), a Card, a Panel, a Dialog or a Drawer |
knob or fader (Slider), plate or tray (Card, Panel), plate (Dialog) or tray (Drawer): the control drawn as the Knob’s or the Fader’s object over the Slider’s own input, as a machined plate or a recessed tray, a plate that rises out of the chassis or a tray that slides out of its edge; flush, or none, is the look before (Slider, Card, Panel, Dialog, Drawer) |
data-strata-form (select and tabs forms) |
A Select’s drawn root (.ug-rotary, .ug-select-display and its .ug-display), a Tabs’ root |
selector or display (Select: the RotarySelector’s dial over the Select’s own select, or a Display with two step buttons; a selector of more than eight options, long labels or optgroups is drawn as display), rail (Tabs: the tablist a plinth, each tab a latching key with an LED), wheel (Slider: the Fader’s track with a ridged roller), selector (RadioGroup: the RotarySelector’s dial over the radios; nine radios or a long label is drawn as bank); flush, or none, is the look before (Select, Tabs) |
data-strata-segments |
A Display’s root | seven: the text under the glass in the seven-segment face, with the unlit segments printed behind it; none is the display of before (Display, section 11) |
data-strata-step |
A display Select’s step button | -1 (previous) or 1 (next): the selectedIndex step a click makes (Select) |
data-strata-colour |
A Lamp or StatusLight | The lens’s colour role: glowOn (default), accent, success, warning, danger or info (Lamp) |
data-strata-lit |
A StatusLight | false: an unlit light (lit when absent) |
data-strata-form (indicator forms) |
A Rating’s fieldset, a Badge, a ProgressBar’s wrapper (.ug-progress-bar) or a Spinner |
lamps (Rating), led (Badge), meter (ProgressBar) or ring (Spinner): the control drawn as LED lenses, each an emitter lit by --strata-lit; flush, or none, is the look before. data-strata-colour is the lenses’ role there too, accent by default for a bar and a ring (Rating, Badge, ProgressBar, Spinner) |
data-strata-blink |
A StatusLight | A tempo token, slow, normal or fast: a lit light blinks, off under reduced motion (StatusLight) |
data-strata-wrap |
A JogWheel’s input | "true": the value goes round at the ends, as the wheel does (JogWheel) |
data-strata-drag |
A JogWheel | vertical: a vertical drag, a turn per jog.dragPx, instead of the circular one |
data-strata-backlight |
A Display’s root (data-strata-form="display", a TextField’s display form or a read-only Display) |
The backlight’s role: glowOn (default, absent), accent, success, warning, danger, info or off; data-strata-lit="false" on it switches the light off (Display) |
data-strata-colour (pads) |
A Pad | The glow’s colour role, as a Lamp’s (Pad) |
data-strata-velocity |
A Pad | The last press’s velocity, 0–1 (position, pressure or key), set at each press by attachStrataPads; optional (Pad) |
data-strata-shifted |
A Keypad’s fieldset | true: each key’s second legend is printed large and its first small (Keypad) |
Relief primitives. Each is a rounded box (or a circle) taken from the element’s border box and its
border-radius. The GPU reads them from the markers, and the CSS presentation styles the same elements.
| Primitive | Shape | Lighting | Shadow | Examples |
|---|---|---|---|---|
raised |
Rounded box at an elevation | Bevel lit from the light, interior within interior.max |
Cast, from height | Button key, card, panel |
well |
Rounded box sunk by elevation.well |
Inverted bevel: the edge nearest the light is dark | Inner, from the rim | Field, switch track, checkbox box |
groove |
A thin well, at most 8 px high | As well, narrower bevel |
Inner | Progress bar, slider rail, divider |
knob |
Circle (or pill) on a well | Spherical shading | Cast onto the well | Switch knob, slider thumb, radio dot |
mark |
A glyph or shape raised inside a well | Bevel on its outline | Small cast | Check mark, indeterminate bar |
ring |
Annulus, with an optional arc | As groove; the arc as the fill |
Inner | Spinner |
flat |
Rounded box, no height | Material only, no bevel | None | Badge, divider in forced colours |
Edges. Wells, tracks and unchecked marks carry a 1 px colour.edge outline, so their shape meets 3:1
against the panel (non-text contrast). Knobs carry one when they do not
reach 3:1 against their track.
Derived parts. A slider’s puck and a progress bar’s fill have no element of their own: the GPU and the
CSS pseudo-elements (::-webkit-slider-thumb, ::-webkit-progress-value and their equivalents) place them
from the native value.
Moving parts (knob, mark, a pressed key) never change the native element’s box. Their travel lives in
the GPU pose and in CSS transform, inside the box (the footprint rule).
Overlays. Dialog and Drawer are top-level panels rendered into a container: the page body, or the Underglass
root, where @underglass/ui/gpu presents each as its own GPU panel over a GPU-faded scrim. They are never inside a layer
and are made modal by showStrataDialog (inert background, focus, Escape). Other floating parts (menus, popovers,
tooltips, select popups) still portal to the Underglass overlay host and are CSS-presented there; Tooltip and Popover
portal to <body> and float in the top layer. Tier A has no
overlays: the native <select> opens the browser’s own list.
Specimen
Section titled “Specimen”The specimen page (ui-specimen.html in the playground) shows
every token, material, elevation and Tier A state from @underglass/ui/css in plain HTML and CSS. Its browser
test is the accessibility harness: axe in every theme and under forced colours, contrast on decoded pixels, the
light and depth, reduced motion, keyboard input and reflow.
Tier A
Section titled “Tier A”| Component | Native element | Object |
|---|---|---|
| Button | <button> |
Key; form="momentary": a push button, a machined cap with a lit ring |
| IconButton | <button> with aria-label |
Square key |
| ToggleButton | <button aria-pressed> |
Latching key; form="latching": a push button that stays down, with an LED |
| ButtonGroup | <div role="group"> |
Keys on one plinth |
| Link | <a href> |
None (flat text) |
| Field | <div> with <label>, help and error |
None (layout) |
| TextField | <input>; form="display": a glass window in a bezel (Display) |
Well with a bezel |
| TextArea | <textarea> |
Well with a bezel |
| Checkbox | <input type="checkbox"> |
Small well with a raised mark; form="latching": a small latching square button whose ring lights when checked (Latching form) |
| Radio and RadioGroup | <input type="radio"> in <fieldset> |
Round well with a knob; form="bank": a preset bank, interlocking latching keys on one plinth (Latching form); form="selector": the RotarySelector’s dial over the same radios (Selector) |
| Switch | <input type="checkbox" role="switch"> |
Track well with a knob; hardware forms: slide, rocker, bat and wall |
| Select | <select> |
Key with a chevron; form="selector": the RotarySelector’s dial over the same select, "display": a Display window with step buttons (Hardware forms) |
| Slider | <input type="range"> |
Rail groove with a puck; form="knob", "fader" or "wheel": the Knob’s or the Fader’s object, or a ridged roller rolling in a slot, over the same input (Hardware forms) |
| Card | <article> or <section> |
Raised slab; form="plate": a machined plate, "tray": the body a recessed tray (Plate and tray forms) |
| Panel | <section> |
Raised slab, the GPU layer unit; form="plate" or "tray" as the Card (Plate and tray forms) |
| Divider | <hr> |
Groove |
| Badge | <span> |
Flat pill; form="led": an LED pill, the StatusLight’s lens before the text (Indicator form) |
| Spinner | <span role="status"> |
Ring groove with an emissive arc; form="ring": a ring of eight LEDs chasing at chase.spinner (Indicator form) |
| ProgressBar | <progress> |
Groove with an emissive fill; form="meter": a groove of LED segments lit from the value, a running head while indeterminate (Indicator form) |
Tier B
Section titled “Tier B”| Component | Native element | Object |
|---|---|---|
| Dialog | <section role="dialog" aria-modal> |
Raised slab at elevation.modal, over a scrim; form="plate": a plate that rises out of the chassis (Plate form) |
| Drawer | <section role="dialog" aria-modal> |
Raised slab on a viewport edge; form="tray": a tray that slides out of its edge (Tray form) |
| Accordion | <details> with <summary> |
A stack of raised slabs; the header’s chevron turns |
| AppBar | <header> |
A raised slab across the top, with controls on it |
| Avatar | <span role="img"> or an <img> |
A raised coin |
| Chip and Tag | <span>, or <button aria-pressed> |
A small raised pill; a filter chip latches |
| Breadcrumb | <nav> around an <ol> of links |
None (flat links) |
| List | <ul role="list"> of <li> rows |
One raised slab; actionable rows are flat links or buttons |
| MessageBar | <div role="status"> or role="alert" |
A raised slab with an intent stripe |
| Pagination | <nav> around page links or buttons |
A row of small keys; the current page is held down |
| Skeleton | <span aria-hidden> placeholders |
None (flat, shimmering) |
| Tooltip | <div role="tooltip" popover> |
A small floating slab in the top layer |
| Toast | A <section> region with a role="status" list, from script |
Floating MessageBars in the top layer |
| Toolbar | <div role="toolbar"> |
Keys on one plinth, one tab stop |
| Table | <table> with <caption> and sortable headers |
One raised slab; rows are flat |
| Tabs | <button role="tab"> in a role="tablist" |
Flat tabs over a rail groove; the selected tab’s indicator is a mark in it; form="rail": latching keys on one plinth with an LED each (Rail form) |
Tier C
Section titled “Tier C”| Component | Native element | Object |
|---|---|---|
| SegmentedControl | Native radios in a <fieldset> |
Keys on one plinth; the selected key is held down; form="latching": interlocking latching keys with an LED each (Latching form) |
| Rating | Native radios in a <fieldset>; a role="img" display |
Stars printed on the panel (captured, no relief) |
| Stepper | An <ol> with aria-current="step" |
Coins on a groove; steps to come are flat |
| NavigationRail | A <nav> with a list of links, aria-current="page" |
Keys on a raised slab down the start edge |
| Popover | <div popover role="dialog"> opened by a <button popovertarget> |
A floating slab in the top layer |
| TreeView | <ul role="tree"> of nested treeitems |
One raised slab; rows are flat |
| Carousel | A <section aria-roledescription="carousel"> of slides, with buttons |
Captured slides in a frame, keys under it |
| Menu | <div popover role="menu"> of menuitem buttons, opened by a menu button |
A floating slab with flat rows |
| Combobox | <input list> with a <datalist>; the browser’s own list |
A TextField well with a printed chevron |
| DatePicker | <input type="date">; the browser’s own calendar |
A TextField well with a printed calendar |
Instrument
Section titled “Instrument”The Instrument level’s components: hardware objects over native controls, at every presentation.
| Component | Native element | Object |
|---|---|---|
| Knob | <input type="range"> over a printed dial |
A skirt and a cap with a turning pointer, a scale printed on the face |
| Fader | <input type="range">, vertical (writing-mode: vertical-lr) or horizontal, its thumb the carriage |
A slot in the faceplate with a capped carriage, a scale printed beside it |
| JogWheel | <input type="range"> over a flat wheel; wrap makes the value go round |
A wheel in a bearing recess with a finger dimple that turns on an accumulated angle (never back), coasting after a flick on spring.jog |
| PatchPoint, PatchBay | <input type="checkbox"> (or a <button aria-pressed>) per jack; a bay is a <fieldset> |
A jack in a washer; connected, a plug stands out of the hole with a short cable; an optional LED |
| RotarySelector | <select> over a printed dial, one detent per <option> |
A knob that turns to the chosen option, the options’ labels printed round it |
| Lamp | <input type="checkbox" role="switch"> in its label row, or a <button aria-pressed> when momentary |
A lens on a bezel: dark glass off, glowing and emitting on |
| StatusLight | <span role="img" aria-label>, a <span> with its label, or a live <output> |
A small lens with an emitter; colour a role, blink a tempo token |
| Meter | <meter> (role meter) with min, max, low, high, optimum |
A bar of LED segments lit from the value (each an emitter, in its zone’s colour), or a needle on a printed arc on spring.meter; a held peak |
| Gauge | <meter> (a bounded measurement; not <progress>) |
A round dial under glass: a needle on spring.gauge over a printed scale, a red zone from high |
| Display | The TextField’s <input> as form="display", or a read-only <output> |
A glass window in a bezel over the printed text, backlit by emitters (backlight a colour role); the text stays captured content; segments: the text in a seven-segment face with the unlit segments faintly printed (section 11) |
| Pad, PadGrid | <button>, with aria-pressed when latching; a grid is a <div role="group"> |
A square soft cap in a grid, a lit rim under it: dark off, glowing and emitting while struck or latched; the cap travels |
| Keypad | A <fieldset> of <button>s, the Grid navigation pattern for the arrows |
Machined square caps with printed legends on one polished plinth; each key travels |