Skip to content

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.

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.

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.

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)
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)
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

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