Connection lost. Reconnecting… attempt 1 of 8
Paused. Your work is held on the server.
Could not reconnect.
This session has expired on the server.
DR.Simple_UI
Showing main. This can be ahead of the version your app has installed — check what a class says it needs before copying it. Releases (opens in a new tab)

Concepts

this site, not the package

Six things that decide how an app writes CSS against this library. Everything else on this site is markup to copy.

The two tiers

Tier 1 — the frame Shell, sidebar and nav, header, user widget, toasts, the modal shell. Pixel-identical in every app and never restyled per project.
Tier 2 — the paint Tables, forms, cards, badges, buttons, panels, alerts. Pages write plain HTML and apply the classes.

Both tiers are CSS classes. There is no <DataTable>, no <AppShell>, and there will not be either. The package ships the stylesheet, the script, the icons, the token export, and a small C# surface for what markup cannot express: which nav link is the current page, typed access to the browser API, and the service registration.

Cascade layers

The whole stylesheet is inside six layers, in this order.

LayerPart numbersWhat lives there
dr.tokens00–04Tokens and the theme remap blocks
dr.base05–09Bare elements — html, body, a, code, headings
dr.frame10–29Tier 1
dr.paint30–79Tier 2, then RTL, forced colours and print
dr.utilities80–89Single-purpose classes
dr.overrides90–99Density and reduced motion — the last word
Your stylesheet is unlayered, so it beats every rule here whatever the specificity. You never have to out-specify the library, and you should not try: .card { padding: 12px } in your own file wins against anything, with no !important and no compound selector. If a rule here has to be overridden to make something work, that is a design problem worth reporting rather than a specificity puzzle.

A later layer beats an earlier one regardless of specificity. That is what makes .text-end at (0,1,0) win against .table td at (0,1,1), and it is why the reduced-motion block sits in the last layer — motion has to be switchable off whatever declared it.

The library uses no !important, and you should not use one against it. Inside a layer an !important declaration becomes harder to override rather than easier, because layer order inverts for important declarations.

One control height

--control-height-sm (28px), --control-height (36px) and --control-height-lg (44px) are the height of everything that can sit in a row with another control: buttons, icon buttons, inputs, selects, the read-only value, the input group, the stepper, the search box and the chip.

Two rules follow if you size a control yourself. Keep its own padding and line box under the tier, or the tier stops deciding anything and the control grows past it. And if a wrapper draws the border — an input group does — the wrapper takes the height and the children give theirs up, or the wrapper ends up two border-pixels taller than a bare control.

The token contract

  • Every colour resolves through a token No hex, rgb() or colour keyword anywhere outside the token blocks. A test enforces it.
  • A theme is a token remap, never a selector override The light and colour-blind blocks contain values and no rules, which is why CSS load order does not affect them.
  • Redefine only names the library declares A new -- name risks colliding with a future token. Use an app-prefixed one until yours ships.
  • Some tokens are derived --brand-tint, the three rings and --brand-glow are mixed from --brand, so redefining it carries all five.

Naming

ShapeRule
.card, .btn-goSemantic, lowercase-kebab, no app or vendor prefix
.dr-row, .dr-scrollLibrary-owned utilities that need a namespace
.tab--activeA modifier is -- on the block
go, warn, danger, info, secretSemantic families, chosen by meaning across buttons, badges and alerts
cyan, orange, tealCategorical hues with no meaning at all
A plain name is a claim on the shared namespace. An app that already styles .list or .menu silently gets both rule sets merged on upgrade — no error, just a changed appearance. Every release lists the class names it adds, so a consuming app can grep its own CSS before bumping.

Z-order

Shared by every app. Use one of these values for a new overlay — a test fails on any other. 0 and 1 are for local stacking inside a component and are not part of the scale.

Layerz-index
Topbar, floating action button60
User widget200
Collapsed-rail flyout400
Drawer scrim480
Drawer panel490
Modal backdrop500
Spotlight510
Dropdown menu, palette, popover550
Toast600
Hover hints, reconnect banner1000
Two things the numbers do not say. .topbar and .user-widget establish stacking contexts, so a panel nested in either is ordered within it and cannot be lifted above the modal backdrop by z-index alone. And the top layer — anything promoted by popover or dialog.showModal() — ignores z-index entirely and orders by promotion, which is why the palette and the confirmation dialog carry no rung of their own.
The drawer sits below the modal backdrop on purpose. A modal opened from inside a drawer has to cover it — the case a single shared “overlay” value gets wrong.

Direction and density

Every directional property in the library is a logical one, so the whole layout mirrors from dir="rtl" on <html>. Use the switch in the header to check any page on this site.

Two things logical properties cannot express, and both are handled for you: transform: translateX() has no logical form, and a background-position percentage is always measured from the physical left edge. Anything else you write with margin-inline-start, border-inline-end, inset-inline and text-align: start mirrors for free. data-density="compact" tightens table and cell padding; tighten your own page-specific components alongside it.