DR.Simple_UI
One design-token contract. Semantic CSS. Consistent Blazor apps.
—design tokens
—CSS classes
—bundled icons
0third-party dependencies
An app built with it
Every class below is the shipped one — the shell, the sidebar, the topbar, the stat row, the toolbar and the table. Nothing here is a picture. Flip the theme, the palette, the density or the direction in the header and watch it all move together.
<div class="layout" style="height:420px; border:1px solid var(--border); border-radius:var(--radius-panel); overflow:hidden">
<aside class="sidebar" style="width:190px">
<a class="brand" href="#">
<span class="brand-logo" style="background:var(--brand)"></span>
<span class="brand-text"><strong>Acme Ops</strong><span class="brand-sub">orders</span></span>
</a>
<nav class="nav">
<div class="nav-scroll">
<div class="nav-section">
<span class="nav-section-label">Today</span>
<a class="nav-link active" href="#"><i class="ri-inbox-line"></i><span>Orders</span><span class="nav-count">12</span></a>
<a class="nav-link" href="#"><i class="ri-truck-line"></i><span>Shipments</span></a>
<a class="nav-link" href="#"><i class="ri-archive-line"></i><span>Stock</span></a>
</div>
</div>
<div class="nav-tools">
<a class="nav-link nav-link-tool" href="#"><i class="ri-settings-3-line"></i><span>Settings</span></a>
</div>
</nav>
</aside>
<div class="content">
<header class="topbar">
<div class="search" style="max-width:260px">
<i class="ri-search-line search-icon" aria-hidden="true"></i>
<input class="search-input" type="search" placeholder="Search orders…" aria-label="Search orders" />
</div>
<div class="topbar-spacer"></div>
<span class="health-badge health-badge--live"><span class="health-dot"></span> Live</span>
<div class="user-widget">
<button class="user-trigger" type="button">
<span class="user-avatar">JW</span>
<span class="user-info">
<span class="user-name">Jordan Weiss</span>
<span class="user-email">jordan.weiss@example.com</span>
</span>
</button>
</div>
</header>
<div class="page" style="padding:16px">
<div class="page-head">
<h1 style="font-size:18px">Orders</h1>
<div class="page-head-actions">
<button class="btn btn-sm"><i class="ri-download-2-line"></i> Export</button>
<button class="btn btn-sm btn-primary"><i class="ri-add-line"></i> New order</button>
</div>
</div>
<div class="stat-row stat-row--divided" style="margin-bottom:14px">
<span class="stat">
<span class="stat-label">Dispatched</span>
<span class="stat-value">248</span>
<span class="stat-delta stat-delta--good"><i class="ri-arrow-up-line"></i> 12%</span>
</span>
<span class="stat">
<span class="stat-label">Backordered</span>
<span class="stat-value">12</span>
<span class="stat-target">of a 20 cap</span>
</span>
<span class="stat">
<span class="stat-label">Returns</span>
<span class="stat-value">3</span>
<span class="stat-delta stat-delta--good"><i class="ri-arrow-down-line"></i> 2</span>
</span>
</div>
<div class="toolbar">
<div class="toolbar-field">
<i class="ri-search-line"></i>
<input class="form-input form-input-sm" type="search" placeholder="Filter" aria-label="Filter orders" />
</div>
<span class="chip"><span class="chip-label">EU-West</span>
<button class="chip-dismiss" type="button" aria-label="Remove the region filter"><i class="ri-close-line"></i></button>
</span>
<span class="dr-push toolbar-count">12 of 1,204</span>
</div>
<table class="table">
<thead>
<tr><th>Order</th><th>Customer</th><th>State</th><th class="col-num">Total</th></tr>
</thead>
<tbody>
<tr>
<td class="text-mono">ORD-4182</td>
<td>
<span class="list-row list-row--flush">
<span class="avatar avatar-sm">PN</span>
<span class="list-main"><span class="list-title">Priya Nair</span></span>
</span>
</td>
<td><span class="badge badge-go">Dispatched</span></td>
<td class="col-num">1,240.00</td>
</tr>
<tr>
<td class="text-mono">ORD-4181</td>
<td>
<span class="list-row list-row--flush">
<span class="avatar avatar-sm">MK</span>
<span class="list-main"><span class="list-title">Milan Kovac</span></span>
</span>
</td>
<td><span class="badge badge-warn">Awaiting stock</span></td>
<td class="col-num">318.50</td>
</tr>
<tr>
<td class="text-mono">ORD-4180</td>
<td>
<span class="list-row list-row--flush">
<span class="avatar avatar-sm avatar--muted"><i class="ri-user-line"></i></span>
<span class="list-main"><span class="list-title">Guest checkout</span></span>
</span>
</td>
<td><span class="badge">Draft</span></td>
<td class="col-num">96.00</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
This whole site is built with
DR.Simple_UI and is a Blazor app like yours, so a
regression in the frame shows up here first.
For an AI agent, add the MCP server —
{ "type": "http", "url": "https://simpleui.dennisrahmen.dev/mcp" }. It searches this catalogue,
returns the exact markup for an example, and says which release first shipped a class.
Everything else
Start
Getting started
Install the package, wire the host page, and rebrand the app.
Concepts
The two tiers, the cascade layers, the z-order scale and the token contract.
Tokens
Every colour, font and shadow token, read live from the loaded stylesheet.
Frame
Shell and nav
Layout, sidebar, topbar and user widget — the chrome this site is built from.
Layouts
Auth and full-bleed shells, collapsible nav groups, and the skip link.
Structure
Page structure
Title rows, dividers, callouts and code blocks.
Cards
Head, body and key/value rows. Put whatever markup you need inside.
Grids
Three breakpoint-free layout primitives.
Collections
Lists, steps, timelines, accordions and trees.
Tabs and segmented
Swap a region of content, or change a setting in place.
Actions
Buttons
Six variants chosen by meaning, three sizes, plus icon-only, ghost and the FAB.
Button groups
Adjacent actions joined into one control, and the split button.
Toolbar
The filter bar that sits above a table or list.
Menus and popovers
A dropdown of actions, an anchored panel of content, and the value trigger.
Forms
Forms
Fields, selects, checkboxes, radios, switches, validation and input groups.
File inputs
File pickers and a dropzone that takes a real drop.
Ranges and steppers
Ranges, steppers and date inputs — the controls whose internals are per-engine.
Data
Tables
One class on the table, plus sticky headers, sorting and a stacked layout.
Stats
One number that matters, which way it moved, and what it is measured against.
Badges
Semantic pills in three sizes, plus three categorical hues.
Chips
Removable filters and recipients, and the set they sit in.
Avatars
A person or an actor, the group, and the lockup that names them.
Pagination and breadcrumbs
Moving through a long result set, and where the page sits.
Text and media
Media and prose
Bounded media, long-form text, and redacted values.
Markdown
Rendered Markdown, and an editor with a live preview.
Feedback
Alerts
Inline banners for a state that persists while the page is open.
Toasts
A confirmation that appears, says what happened, and goes away.
Progress and spinners
Determinate bars, indeterminate bars, spinners and skeletons.
Empty and live states
Nothing to show, waiting for something, and the state of a live connection.
Overlays
Modal
A question that has to be answered before anything else happens.
Drawers and sheets
A panel from an edge, for a secondary flow that can be left.
Command palette
The Ctrl-K box: type, see matching commands, run one.
Spotlight
Dims the page except one element, for a tour or a first-run hint.