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)

Grids

tier 2 — classes

Three layout primitives, all breakpoint-free: they respond to the space they are given rather than to the viewport width, so they behave correctly inside a narrow column too.

Page-specific grids stay in the app. Only reusable layout primitives live here. A two-pane layout or a tile grid tuned to one page's card size belongs in that page.

.card-masonry

Cards of similar height flow across as many balanced columns as the width allows, and stack to fill each column instead of piling into one strip. Every child is kept whole. auto-fit collapses empty tracks, so the cards that are present always stretch to fill the row — remove one and nothing is left stranded. Resize this window to watch it recolumn.

Appearance
Notifications
Account
Signed in asalex.fischer
Roleadmin
<div class="card-masonry">
    <div class="card">
        <div class="card-head"><strong>Appearance</strong></div>
        <div class="card-body" style="display:flex; flex-direction:column; gap:10px">
            <label class="form-check"><input type="checkbox" /> Light theme</label>
            <label class="form-check"><input type="checkbox" /> Colour-blind palette</label>
            <label class="form-check"><input type="checkbox" checked /> Compact tables</label>
        </div>
    </div>
    <div class="card">
        <div class="card-head"><strong>Notifications</strong></div>
        <div class="card-body" style="display:flex; flex-direction:column; gap:10px">
            <label class="form-check"><input type="checkbox" checked /> Desktop notifications</label>
            <label class="form-check"><input type="checkbox" /> Sound</label>
        </div>
    </div>
    <div class="card">
        <div class="card-head"><strong>Account</strong></div>
        <div class="card-body">
            <div class="kv"><span class="k">Signed in as</span><span class="v">alex.fischer</span></div>
            <div class="kv"><span class="k">Role</span><span class="v">admin</span></div>
        </div>
    </div>
</div>

.card-grid

A set of peers in a plain wrapping grid. It differs from .card-masonry in the one way that decides which to use: auto-fill keeps the track count stable, so three cards stay three columns wide instead of stretching to fill the row. Use this when the cards are equals of similar height; use .card-masonry when their heights differ a lot.

QueueFulfilment
Waiting12
QueueNetwork
Waiting3
QueueOn call
Waiting0
<div class="card-grid">
    <div class="card">
        <div class="card-body">
            <div class="kv"><span class="k">Queue</span><span class="v">Fulfilment</span></div>
            <div class="kv"><span class="k">Waiting</span><span class="v">12</span></div>
        </div>
    </div>
    <div class="card">
        <div class="card-body">
            <div class="kv"><span class="k">Queue</span><span class="v">Network</span></div>
            <div class="kv"><span class="k">Waiting</span><span class="v">3</span></div>
        </div>
    </div>
    <div class="card">
        <div class="card-body">
            <div class="kv"><span class="k">Queue</span><span class="v">On call</span></div>
            <div class="kv"><span class="k">Waiting</span><span class="v">0</span></div>
        </div>
    </div>
</div>

.field-grid

Form fields side by side, collapsing to one column below roughly 200px per field. Use it for values that belong together — a from/to pair, a host and port.

<div class="field-grid">
    <div class="form-field">
        <label class="form-label" for="g-host">Host</label>
        <input class="form-input" id="g-host" type="text" value="192.0.2.20" />
    </div>
    <div class="form-field">
        <label class="form-label" for="g-port">Port</label>
        <input class="form-input" id="g-port" type="text" value="3306" />
    </div>
    <div class="form-field">
        <label class="form-label" for="g-db">Database</label>
        <input class="form-input" id="g-db" type="text" value="orders" />
    </div>
</div>
Page width needs no wrapper. .page holds content to --page-max (1800px) and centres it by growing its horizontal padding rather than capping its width, which keeps the scrollbar at the right edge of the screen.

A dashboard row

The composition a dashboard is actually made of: a .stat-row of figures above a .card-grid of the things behind them. Both are breakpoint-free, so the whole block behaves correctly inside a narrow column too.

Nothing here is a page-specific grid. If a layout needs a named area or a fixed column count, it belongs in the app that owns the page rather than in this library.

Dispatched this week 1,204 8% on last week
Awaiting stock 37 of 1,204 orders
Median time to dispatch 4.2h 20 min faster
EU-West Live
Waiting12
Oldest2 h 14 m
EU-Central Degraded
Waiting25
Oldest9 h 02 m
UK-South Idle
Waiting0
Oldest
<div class="dr-col dr-gap-3">
    <div class="stat-row">
        <div class="stat">
            <span class="stat-label">Dispatched this week</span>
            <span class="stat-value">1,204</span>
            <span class="stat-delta stat-delta--good"><i class="ri-arrow-up-line"></i> 8% on last week</span>
        </div>
        <div class="stat">
            <span class="stat-label">Awaiting stock</span>
            <span class="stat-value">37</span>
            <span class="stat-target">of 1,204 orders</span>
        </div>
        <div class="stat">
            <span class="stat-label">Median time to dispatch</span>
            <span class="stat-value">4.2<span class="stat-unit">h</span></span>
            <span class="stat-delta stat-delta--good"><i class="ri-arrow-down-line"></i> 20 min faster</span>
        </div>
    </div>
    <div class="card-grid">
        <div class="card">
            <div class="card-head">
                <strong>EU-West</strong>
                <span class="health-badge health-badge--live"><span class="health-dot"></span> Live</span>
            </div>
            <div class="card-body">
                <div class="kv"><span class="k">Waiting</span><span class="v">12</span></div>
                <div class="kv"><span class="k">Oldest</span><span class="v">2 h 14 m</span></div>
            </div>
        </div>
        <div class="card">
            <div class="card-head">
                <strong>EU-Central</strong>
                <span class="health-badge health-badge--degraded"><span class="health-dot"></span> Degraded</span>
            </div>
            <div class="card-body">
                <div class="kv"><span class="k">Waiting</span><span class="v">25</span></div>
                <div class="kv"><span class="k">Oldest</span><span class="v">9 h 02 m</span></div>
            </div>
        </div>
        <div class="card">
            <div class="card-head">
                <strong>UK-South</strong>
                <span class="health-badge health-badge--idle"><span class="health-dot"></span> Idle</span>
            </div>
            <div class="card-body">
                <div class="kv"><span class="k">Waiting</span><span class="v">0</span></div>
                <div class="kv"><span class="k">Oldest</span><span class="v">&mdash;</span></div>
            </div>
        </div>
    </div>
</div>