panelware static

Every state an attribute can reach, rendered with no JavaScript at all. Nothing on this page responds: the sliders are parked at fixed values, the tabs are two states side by side rather than a working strip, and the pause control is disabled. That is the point of the page. It is the proof the CSS works without React, and it is what the contrast gate measures.

The live components are here, where everything works. Absolute, because this page ships inside the package and the live one does not: it needs a bundled React that a consumer has no reason to carry.

Button

Rest, primary, glossed, and disabled. The press and the hover are pointer states and are not mocked up here.

Toggle

Off is raised, on is sunken and heavier. Neither state is carried by colour.

Tabs

The active trigger sits a pixel lower and drops its bottom line, so it fuses with the panel.

The panel and the active trigger share an edge. That fuse is the only thing separating a tab strip from a row of pressed buttons.

Dialog

Held in flow by demo.css so it can be seen next to everything else. In the kit it is fixed and centred, over a flat scrim with no backdrop-filter.

Playlist

A listbox, and one tab stop rather than one per row. Three states are shown at once and they are all different things: the first row is playing, the third is selected, the fifth is where the keyboard is. Winamp colour-codes its rows and that is the one thing here not taken from it, because colour alone says nothing to a reader who cannot see it.

  • DJ Mike Llama - Llama Whippin Intro 0:05 , now playing
  • Mori Calliope - Go-Getters 3:15
  • CircusP - Goodbye 3:24
  • AmaLee - Siren 4:02
  • Crusher-P - Echo 3:50
  • M83 - Midnight City 4:03

Window chrome

A title bar, its controls, and the chassis. The dialog uses the same bar, because a dialog is a window that happens to be modal. The bar does not pretend to drag: there is no window to move, and a handle that looks draggable and is not is the same failure as a button that looks pressable and is not.

Playlist

3 tracks
Controls only render when a handler is passed, so a window with nothing to close has no close button rather than a dead one.

Transport and seek

Icon-only is the one place the kit allows a mark without a word, and the component charges for it: every button requires a label, which becomes its accessible name. Live, this is a Radix Toolbar, so Tab enters the cluster once and the arrow keys move inside it.

Slider

Track sunken, thumb raised. The thumb never sinks: a sunken grip reads as dropped rather than held. The grip is 22 by 28 and its hit area is 44 by 44. Radix positions the thumb in the real component; these offsets stand in for it.

Icons

One 16 by 16 sheet, drawn as bitmap rows and generated, applied as a mask so every mark is painted in the ink of whatever it sits inside. Shown here at scale 1 and scale 2; the scale is a whole number because a pixel grid tears at any other.

play pause stop previous next eject close minimize maximize restore chevron-down chevron-up chevron-right chevron-left check exclamation dot minus plus caret-down search info question ellipsis spinner-1 spinner-2 spinner-3 spinner-4 spinner-5 spinner-6 spinner-7 spinner-8
play pause stop previous next eject close minimize maximize restore chevron-down chevron-up chevron-right chevron-left check exclamation dot minus plus caret-down search info question ellipsis spinner-1 spinner-2 spinner-3 spinner-4 spinner-5 spinner-6 spinner-7 spinner-8

Equaliser

Ten independent bands, not a multi-thumb slider. A multi-thumb slider is a range and re-sorts its thumbs, so driving one band would silently renumber it into another. The fill leaves the zero line and travels to the value, in whichever direction that is, because a cut drawn as a short bar rising from the floor is a lie about the shape of the curve.

Form controls

Text field, textarea, checkbox, radio and combo box, in every state the attributes can reach. This page had none of them: they were added to the live page and never mirrored here, so their CSS had no proof it works without React and the runtime contrast gate, which reads this page, had never measured them.

Visualiser

A spectrum analyser, parked at fixed levels here because this page has no JavaScript. The gradient is sized to the full column and anchored to its floor, so a bar shows the slice of the ramp its level reaches: the tall bands are red at the top and the short ones are green all the way up. That is what the original did, and it is the difference between an analyser and a stacked bar chart. The thin line above each bar is the held peak.

Switch, collapsible, toolbar, separator, tooltip

A switch is not a toggle: the state is where the thumb is, and the tint on the track is the second signal rather than the first. The tooltip is rendered open here, which is the only place its surface gets measured: on the live page it is portalled and only exists while the pointer is on the trigger.

The chevron turns rather than the height animating, because height is a layout property.

Spinner

Eight cells on the sheet, stepped. Not one glyph rotated: only a quarter turn is exact on a pixel grid, so the other seven positions are drawn.

Loading

Metadata

Field and value pairs set small and tracked. The quiet is size and tracking; the ink is the same one the body uses, because small text gets no contrast exemption for being decorative.

Session
2038 282 92L28
Signal
Interrupted, retrying
Position
21.0652, 55.3157
Build
deck-r7
Rate
44.1 kHz
Depth
24 bit
Latency
11 ms

Status badge

Every badge is a glyph and a word. A coloured dot alone is the failure this component exists to avoid.

Connected Buffering No device

Readout

A sprite sheet stepped by whole pixels, painted through a mask so the ink stays a token. Each one is an image of text, so it carries its string as a label rather than as a live region. The last one scrolls, and its pause control is the mechanism a keyboard or touch user has. The control is disabled here because this page runs no JavaScript; it works on the live page.

Depth 0

The same components with --pw-bevel-depth set to 0. Every offset in the bevel is a calc of that number, so the whole stack collapses to nothing. A single literal px in there would leave a ghost edge here.

Connected