Components and tokens for building Django Control Room panels.
Extend panel_base.html to inherit this design system in any panel.
The page header sits at the top of every panel view. It supports four compositions: plain title, panel overview (icon + title + status pill + subtitle), detail page (back link + icon + title + badge(s) + meta + actions), and minimal with actions.
Usage
<div class="dcr-page-header">
<h1 class="dcr-page-header__title">Cache Keys</h1>
<div class="dcr-page-header__actions">
<button class="dcr-btn">Flush All</button>
</div>
</div>
Track unhandled exceptions captured from views, middleware, and Celery tasks. Drill into any event for traceback and frame locals.
Inspect every signal registered in your Django project, including built in and custom signals.
Usage
<div class="dcr-page-header">
<div class="dcr-page-header__main">
<div class="dcr-page-header__icon" style="background:var(--dcr-color-danger)">
<svg ...></svg>
</div>
<div class="dcr-page-header__body">
<div class="dcr-page-header__title-row">
<h1 class="dcr-page-header__title">Errors Panel</h1>
<span class="dcr-pill dcr-pill--danger"><span class="dcr-pill__dot"></span>19 UNRESOLVED</span>
</div>
<p class="dcr-page-header__subtitle">Track unhandled exceptions…</p>
</div>
</div>
</div>
'stripe_customer_id'
Usage
<a href="..." class="dcr-back-link">Back to all errors</a>
<div class="dcr-page-header">
<div class="dcr-page-header__main">
<div class="dcr-page-header__icon" style="background:var(--dcr-color-danger)">
<svg ...></svg>
</div>
<div class="dcr-page-header__body">
<div class="dcr-page-header__title-row">
<h1 class="dcr-page-header__title">KeyError</h1>
<span class="dcr-badge dcr-badge--solid dcr-badge--danger">ERROR</span>
</div>
<p class="dcr-page-header__subtitle">'stripe_customer_id'</p>
<p class="dcr-page-header__meta">event evt-9f3a2b1c · group g-9c1</p>
</div>
</div>
<div class="dcr-page-header__actions">
<button class="dcr-btn dcr-btn--ghost dcr-btn--sm">Copy event ID</button>
<button class="dcr-btn dcr-btn--success dcr-btn--ghost dcr-btn--sm">✓ Resolve</button>
<button class="dcr-btn dcr-btn--ghost dcr-btn--sm">✕ Ignore</button>
</div>
</div>
Sent at the end of a model's save() method. Receivers can react to updated rows by inspecting the created flag and the instance.
Usage
<a href="..." class="dcr-back-link">Back to all signals</a>
<div class="dcr-page-header">
<div class="dcr-page-header__main">
<div class="dcr-page-header__icon" style="background:var(--dcr-color-accent)">
<svg ...></svg>
</div>
<div class="dcr-page-header__body">
<div class="dcr-page-header__title-row">
<h1 class="dcr-page-header__title" style="font-family:var(--dcr-font-mono)">post_save</h1>
<span class="dcr-badge dcr-badge--muted">BUILT-IN</span>
<span class="dcr-pill dcr-pill--success"><span class="dcr-pill__dot"></span>4 RECEIVERS</span>
</div>
<p class="dcr-page-header__subtitle">Sent at the end of a model's save() method…</p>
</div>
</div>
</div>
Centered, max-width wrappers for panel content. Wrap your dcr-page-header and body content in dcr-content with a size modifier. Most panels should use --lg.
Usage
<!-- modifiers: sm (640px) · md (960px) · lg (1280px) · xl (1600px) · full -->
<div class="dcr-content dcr-content--lg">
<div class="dcr-page-header">…</div>
<!-- panel body -->
</div>
Uppercase label used to head sub-sections on a panel page. Default variant extends a midline rule to full width. Add --plain to suppress the rule. Optionally place a badge inline.
Usage
<!-- default: midline rule -->
<div class="dcr-section-header">
<h2 class="dcr-section-header__title">Key Information</h2>
</div>
<!-- with inline badge -->
<div class="dcr-section-header">
<h2 class="dcr-section-header__title">Stored Value</h2>
<span class="dcr-badge dcr-badge--warning">HASH</span>
</div>
<!-- plain: no rule -->
<div class="dcr-section-header dcr-section-header--plain">
<h2 class="dcr-section-header__title">Overview</h2>
</div>
Static informational panel with a left-border accent. For persistent guidance, not flash messages.
Default callout with no modifier.
Info
Use for contextual guidance and configuration notes.
Success
Operation completed without errors.
Warning
Check your configuration before proceeding.
Danger
This action cannot be undone.
Usage
<!-- modifiers: (none) · info · success · warning · danger -->
<div class="dcr-callout dcr-callout--info">
<p class="dcr-callout__title">Info</p>
<p class="dcr-callout__body">Contextual guidance here.</p>
</div>
Visually isolated section for irreversible operations. Always pair with a confirmation mechanism.
Flush all cache keys
Permanently deletes every key in the selected cache backend. This cannot be undone.
Usage
<div class="dcr-danger-zone">
<p class="dcr-danger-zone__title">Flush all cache keys</p>
<p class="dcr-danger-zone__body">Permanently deletes every key…</p>
<button class="dcr-btn dcr-btn--danger">Flush cache</button>
</div>
Monospace display for keys, values, payloads, or any machine-readable content. Inline and block variants.
Cache key: sessions:abc123def456
{"status": "ok", "workers": 4, "queues": ["default", "high"]}
Usage
<code class="dcr-code">sessions:abc123</code>
<code class="dcr-code dcr-code--block">{"status": "ok"}</code>
Palette swatches reflect the current mode. All dcr-* components consume only these tokens - override them on :root to theme every component at once.
Surfaces
Page, card, and control backgrounds plus border colours.
bg
--dcr-color-bg
Page and card background
bg-subtle
--dcr-color-bg-subtle
Table headers, controls zones
border
--dcr-color-border
Card borders, row dividers
text
--dcr-color-text
Primary body text
text-muted
--dcr-color-text-muted
Labels, captions, placeholders
Semantic
Solid colours for buttons, badges, icons, and status indicators.
accent
--dcr-color-accent
Primary actions, links
success
--dcr-color-success
Healthy, active, connected
warning
--dcr-color-warning
Caution, degraded states
danger
--dcr-color-danger
Errors, destructive actions
info
--dcr-color-info
Informational, neutral notices
muted
--dcr-color-muted
Disabled, secondary content
Tinted backgrounds
Soft fills paired with each semantic colour - used for tinted badges and hover states.
accent-bg
--dcr-color-accent-bg
Default badge fill
success-bg
--dcr-color-success-bg
Success badge fill
warning-bg
--dcr-color-warning-bg
Warning badge fill
danger-bg
--dcr-color-danger-bg
Danger badge fill
info-bg
--dcr-color-info-bg
Info badge fill
muted-bg
--dcr-color-muted-bg
Muted badge fill
purple-bg
--dcr-color-purple-bg
Purple badge fill
indigo-bg
--dcr-color-indigo-bg
Indigo badge fill
Extended semantic
Additional colours for task states, log levels, and signal kinds.
purple
--dcr-color-purple
Pending, scheduled states
indigo
--dcr-color-indigo
Custom signals, built-in tags
Five-step scale used for padding, margin, and gap throughout the design system. Always reference a token - never hardcode pixel values.
Usage
<!-- padding -->
<div style="padding: var(--dcr-space-md)">...</div>
<!-- margin -->
<p style="margin-bottom: var(--dcr-space-lg)">...</p>
<!-- gap in a flex/grid container -->
<div style="display:flex; gap: var(--dcr-space-sm)">...</div>
In CSS
<style>
.my-card {
padding: var(--dcr-space-md) var(--dcr-space-lg);
margin-bottom: var(--dcr-space-xl);
gap: var(--dcr-space-sm);
}
</style>
Single-purpose helper classes for composing layouts inline. All utilities use !important so they always override component defaults.
dcr-text-xs dcr-text-muted
dcr-text-sm dcr-text-default
dcr-text-base dcr-font-bold dcr-text-success
dcr-text-lg dcr-font-mono dcr-text-accent
dcr-text-danger
dcr-text-warning
dcr-text-info
dcr-text-purple
dcr-text-indigo
Usage
<!-- typography -->
<p class="dcr-text-sm dcr-text-muted">Hint text</p>
<span class="dcr-font-bold dcr-text-danger">Error</span>
<code class="dcr-font-mono dcr-text-xs">cache:key:42</code>
<!-- layout -->
<div class="dcr-d-flex dcr-items-center dcr-justify-between dcr-gap-sm">
<h2>Title</h2>
<button class="dcr-btn">Action</button>
</div>
<!-- spacing -->
<div class="dcr-mb-lg dcr-px-md">…</div>
<!-- overflow -->
<p class="dcr-truncate">Very long value that should clip…</p>
<!-- screen-reader label -->
<span class="dcr-sr-only">Loading…</span>
Composable form primitives. Combine dcr-form, dcr-form__row, dcr-field, dcr-input / dcr-select, and dcr-input-group to build any panel form.
Plain input and select
Search + filter form
Usage
<!-- Plain input -->
<div class="dcr-field">
<label class="dcr-field__label" for="name">Queue name</label>
<input id="name" class="dcr-input" type="text" placeholder="e.g. celery">
</div>
<!-- Select -->
<div class="dcr-field">
<label class="dcr-field__label" for="state">State</label>
<select id="state" class="dcr-select"><option>All states</option></select>
</div>
<!-- Search + button (input group) -->
<div class="dcr-form__group">
<label class="dcr-form__label" for="q">Search by task name or ID</label>
<div class="dcr-form__row--stretch">
<div class="dcr-input-group">
<svg class="dcr-input-group__icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"/><path d="m21 21-4.3-4.3"/></svg>
<input id="q" class="dcr-input-group__input" type="text" placeholder="e.g. send_order_email">
</div>
<button type="submit" class="dcr-btn dcr-btn--primary">Search</button>
</div>
</div>
<!-- Full search + filter form -->
<form class="dcr-form">
<div class="dcr-form__group">
<label class="dcr-form__label" for="q">Search by task name or ID</label>
<div class="dcr-form__row--stretch">
<div class="dcr-input-group">…</div>
<button class="dcr-btn dcr-btn--primary">Search</button>
</div>
</div>
<div class="dcr-form__row">
<div class="dcr-field">
<label class="dcr-field__label" for="state">▿ State</label>
<select id="state" class="dcr-select"><option>All states</option></select>
</div>
</div>
</form>
Edit a single value in place without navigating to a full change form. Useful for TTLs, retry counts, or short string values. Wrap the input in dcr-inline-edit__field to add a left-side icon.
Usage
<!-- Wrap input + icon in dcr-inline-edit__field -->
<span class="dcr-inline-edit">
<span class="dcr-inline-edit__field">
<svg class="dcr-inline-edit__icon" ...>...</svg>
<input class="dcr-inline-edit__input" type="text" value="86400">
</span>
<button class="dcr-inline-edit__btn">✓</button>
<button class="dcr-inline-edit__btn dcr-inline-edit__btn--danger">✕</button>
</span>
Card-wrapped table with four named zones: header (title + badge + subtitle + right meta), controls (search + filters, subtle bg), table body, and pagination. All zones are optional - use only what you need. Add dcr-data-table__header--subtle to tint the header, and dcr-data-table__title-icon on an SVG to place an icon before the title text.
| Hostname | Pool | Conc. | Active | Uptime |
|---|---|---|---|---|
| celery@worker-1.prod | prefork | 8 | 3 | 12d 4h |
| celery@worker-3.prod | gevent | 50 | 0 | - |
Usage
<div class="dcr-data-table">
<div class="dcr-data-table__header dcr-data-table__header--subtle">
<div class="dcr-data-table__header-info">
<h3 class="dcr-data-table__title">
<svg class="dcr-data-table__title-icon" ...></svg>
Workers <span class="dcr-badge dcr-badge--success">2 ONLINE</span>
</h3>
</div>
</div>
<table>…</table>
</div>
| App | Label | Models | Migrations |
|---|---|---|---|
| django.contrib.auth | auth | 4 | up to date |
| django.contrib.contenttypes | contenttypes | 1 | up to date |
| myapp.billing | billing | 6 | 1 pending |
Usage
<!-- No-stripe modifier removes alternating row color -->
<div class="dcr-data-table dcr-data-table--no-stripe">
<table>…</table>
</div>
Browse every key across all databases on this Redis instance.
| Key | Type | DB | Size | TTL |
|---|---|---|---|---|
| user:42:profile | hash | db0 | 412 B | 1h |
| session:s9k2lq | string | db1 | 1.2 KB | 14d |
| queue:default | list | db0 | 8.2 KB | never |
Usage
<div class="dcr-data-table">
<!-- Zone 1: header -->
<div class="dcr-data-table__header">
<div class="dcr-data-table__header-info">
<h3 class="dcr-data-table__title">Key Browser <span class="dcr-badge">12 TOTAL</span></h3>
<p class="dcr-data-table__subtitle">Browse every key across all databases.</p>
</div>
<div class="dcr-data-table__meta">
<div class="dcr-data-table__meta-info">
<span>Showing 8 of 12</span>
<span>Updated just now</span>
</div>
<button type="button" class="dcr-btn dcr-btn--ghost dcr-btn--sm">
<svg class="dcr-btn__icon" …></svg> CLEAR
</button>
</div>
</div>
<!-- Zone 2: controls (optional) -->
<div class="dcr-data-table__controls">
<form class="dcr-form">…</form>
</div>
<!-- Zone 3: table body -->
<table>…</table>
<!-- Zone 4: pagination (optional) -->
<div class="dcr-pagination">…</div>
</div>
Add a dcr-col--expand column with a dcr-data-table__expand-btn toggle. Each row pairs with a hidden dcr-data-table__expand-row sibling. Toggle is-open and aria-expanded via JS.
| Receiver | Sender | Module | Flags | |
|---|---|---|---|---|
create_profile |
auth.User | profiles.signals | uid | |
|
SOURCE
|
||||
send_order_email |
orders.Order | notifications.signals | weak | |
|
SOURCE
|
||||
reindex_post |
blog.Post | search.signals | uid | |
|
SOURCE
|
||||
Usage
<div class="dcr-data-table dcr-data-table--no-stripe">
<table>
<thead>
<tr>
<th class="dcr-col--expand"></th>
<th>Receiver</th>
...
</tr>
</thead>
<tbody>
<!-- data row -->
<tr>
<td class="dcr-col--expand">
<button class="dcr-data-table__expand-btn"
aria-expanded="false"
aria-controls="row-1">
<svg ...></svg>
</button>
</td>
<td>create_profile</td>
...
</tr>
<!-- expand content row (hidden until toggled) -->
<tr class="dcr-data-table__expand-row" id="row-1">
<td colspan="5">
<div class="dcr-code-viewer">…</div>
</td>
</tr>
</tbody>
</table>
</div>
<script>
document.querySelectorAll('.dcr-data-table__expand-btn').forEach(function (btn) {
btn.addEventListener('click', function () {
var row = document.getElementById(btn.getAttribute('aria-controls'));
var open = btn.getAttribute('aria-expanded') === 'true';
btn.setAttribute('aria-expanded', !open);
row.classList.toggle('is-open', !open);
});
});
</script>
Placed inside a dcr-data-table card, after the <table>. Supports numbered pages and cursor-only (prev / next) modes. Use <a> for active controls, <span aria-disabled> for disabled ones.
Usage
<div class="dcr-pagination">
<div class="dcr-pagination__per-page">
<span class="dcr-pagination__summary">Showing <strong>1–20</strong> of <strong>847</strong></span>
<label>Per page <select class="dcr-pagination__per-page-select">…</select></label>
</div>
<div class="dcr-pagination__controls">
<span class="dcr-pagination__btn dcr-pagination__btn--prev" aria-disabled="true">Previous</span>
<span class="dcr-pagination__page dcr-pagination__page--active">1</span>
<a href="?page=2" class="dcr-pagination__page">2</a>
<span class="dcr-pagination__ellipsis">…</span>
<a href="?page=43" class="dcr-pagination__page">43</a>
<a href="?page=2" class="dcr-pagination__btn dcr-pagination__btn--next">Next</a>
</div>
</div>
Usage
<!-- Cursor-based: no page numbers, just prev/next -->
<div class="dcr-pagination">
<span class="dcr-pagination__summary">Cursor scan - page 2</span>
<div class="dcr-pagination__controls">
<a href="?cursor=prev" class="dcr-pagination__btn dcr-pagination__btn--prev">Previous</a>
<a href="?cursor=next" class="dcr-pagination__btn dcr-pagination__btn--next">Next</a>
</div>
</div>
Place dcr-empty inside a <tbody> cell spanning all columns so the table headers remain visible. Two patterns: no data at all, and no results matching active filters.
| Title | Occurrences | Last seen | Status |
|---|---|---|---|
|
No errors recorded Errors captured from your views, middleware, and Celery tasks will appear here. |
|||
Usage
<div class="dcr-data-table dcr-data-table--no-hover">
<div class="dcr-data-table__header">
<h3 class="dcr-data-table__title">Error Groups</h3>
</div>
<table>
<thead>
<tr>
<th>Title</th>
<th>Occurrences</th>
<th>Last seen</th>
<th>Status</th>
</tr>
</thead>
<tbody>
<tr>
<td colspan="4">
<div class="dcr-empty">
<div class="dcr-empty__icon">...</div>
<p class="dcr-empty__title">No errors recorded</p>
<p class="dcr-empty__body">Errors captured from your views, middleware, and Celery tasks will appear here.</p>
</div>
</td>
</tr>
</tbody>
</table>
</div>
Tabular display of what a backend supports. Use on overview pages that manage multiple backends.
| Backend | Key listing | TTL support | Flush | Inline edit |
|---|---|---|---|---|
LocMemCache |
✓ | – | ✓ | – |
RedisCache |
✓ | ✓ | ✓ | ✓ |
Usage
<div class="dcr-data-table">
<div class="dcr-data-table__header">
<h3 class="dcr-data-table__title">Backend Capabilities</h3>
</div>
<table>
<thead>
<tr><th>Backend</th><th>Key listing</th><th>TTL support</th></tr>
</thead>
<tbody>
<tr>
<td><code class="dcr-code">RedisCache</code></td>
<td><span class="dcr-ability-indicator dcr-ability-indicator--yes">✓</span></td>
<td><span class="dcr-ability-indicator dcr-ability-indicator--no">–</span></td>
</tr>
</tbody>
</table>
</div>
KPI tiles for at-a-glance numeric summaries. Wrap tiles in dcr-metric-grid for automatic responsive columns.
Usage
<!-- value modifiers: (none) · success · warning · danger · disabled -->
<div class="dcr-metric-grid">
<div class="dcr-metric">
<span class="dcr-metric__label">Tasks Processed</span>
<span class="dcr-metric__value dcr-metric__value--success">847</span>
</div>
</div>
Label / value pairs on a subtle background. Two layouts: vertical (stacked rows, default) and horizontal (inline info bar, add --horizontal).
Vertical (default)
Usage
<dl class="dcr-dl">
<div class="dcr-dl__row">
<dt class="dcr-dl__label">Key</dt>
<dd class="dcr-dl__value dcr-dl__value--mono">user:42:profile</dd>
</div>
<div class="dcr-dl__row">
<dt class="dcr-dl__label">Type</dt>
<dd class="dcr-dl__value"><span class="dcr-badge dcr-badge--warning">HASH</span></dd>
</div>
<div class="dcr-dl__row">
<dt class="dcr-dl__label">TTL</dt>
<dd class="dcr-dl__value">1h <span class="dcr-dl__secondary">(31m remaining)</span></dd>
</div>
</dl>
Horizontal (--horizontal)
Usage
<dl class="dcr-dl dcr-dl--horizontal">
<div class="dcr-dl__item">
<dt class="dcr-dl__label">Host</dt>
<dd class="dcr-dl__value dcr-dl__value--mono">redis-prod-1.internal:6379</dd>
</div>
<div class="dcr-dl__item">
<dt class="dcr-dl__label">Version</dt>
<dd class="dcr-dl__value">7.2.4</dd>
</div>
</dl>
Horizontal with action (--horizontal + __actions)
Usage
<dl class="dcr-dl dcr-dl--horizontal">
<div class="dcr-dl__item">
<dt class="dcr-dl__label">Total Events</dt>
<dd class="dcr-dl__value">1,842</dd>
</div>
<div class="dcr-dl__item">
<dt class="dcr-dl__label">Unresolved</dt>
<dd class="dcr-dl__value" style="color:var(--dcr-color-danger)">19</dd>
</div>
<!-- __actions is pushed to the far right via margin-left:auto -->
<div class="dcr-dl__actions">
<a href="…" class="dcr-btn dcr-btn--ghost dcr-btn--sm">View grouped</a>
</div>
</dl>
Responsive grid for the panel index page. Use dcr-panel-grid as the container and dcr-panel-card for each item. Wrap the icon in dcr-panel-card__icon-wrap with a colour modifier. Use dcr-badge variants for install status. Add dcr-panel-card--coming-soon to dim unavailable panels.
Monitor connections, memory, keys, and throughput.
Inspect cached entries, hit/miss ratios.
Monitor errors, stack traces, and exceptions.
Core framework for Django Control Room panels.
Usage
<!-- section label -->
<div class="dcr-section-header">
<h3 class="dcr-section-header__title">Featured Panels</h3>
</div>
<div class="dcr-panel-grid">
<!-- installed - accent icon wrap -->
<div class="dcr-panel-card">
<div class="dcr-panel-card__top">
<div class="dcr-panel-card__icon-wrap dcr-panel-card__icon-wrap--accent">
<svg class="dcr-panel-card__icon" …></svg>
</div>
<span class="dcr-badge dcr-badge--success">INSTALLED</span>
</div>
<h3 class="dcr-panel-card__title">Redis Panel</h3>
<p class="dcr-panel-card__desc">Monitor connections…</p>
<div class="dcr-panel-card__footer">
<a href="/redis/" class="dcr-panel-card__link">View panel</a>
</div>
</div>
<!-- icon wrap colour variants -->
<!-- (none) · accent · success · warning · danger · info · muted · purple · indigo -->
<!-- not installed -->
<div class="dcr-panel-card">
…
<span class="dcr-badge dcr-badge--muted">NOT INSTALLED</span>
…
<a href="#" class="dcr-panel-card__link">Install panel</a>
</div>
<!-- coming soon -->
<div class="dcr-panel-card dcr-panel-card--coming-soon">
…
<span class="dcr-badge dcr-badge--warning">COMING SOON</span>
…
<span class="dcr-panel-card__link dcr-panel-card__link--muted">Coming soon</span>
</div>
</div>
</div>
A full-width bordered card divided into equal columns by vertical rules. Add as many dcr-split-card__section children as needed - the dividers are generated automatically. Stacks vertically on narrow viewports. Compose freely with dcr-panel-card__icon-wrap and dcr-panel-card__link inside each section.
We're building more tools to bring full observability to your Django admin. Follow our progress on GitHub.
Django Control Room is built to be extended. Use our cookiecutter template to scaffold a fully structured panel plugin in seconds.
Usage
<div class="dcr-split-card">
<div class="dcr-split-card__section">
<div class="dcr-panel-card__icon-wrap dcr-panel-card__icon-wrap--info">
<svg class="dcr-panel-card__icon" …></svg>
</div>
<h3 class="dcr-split-card__title">More panels on the way</h3>
<p class="dcr-split-card__desc">Description text.</p>
<div class="dcr-split-card__footer">
<a href="#" class="dcr-panel-card__link">GitHub</a>
</div>
</div>
<div class="dcr-split-card__section">
<!-- second section … -->
</div>
</div>
MIT-licensed and fully open. Inspect the code, file issues, or contribute on GitHub.
Full API reference, configuration options, and how-to guides for panel authors.
Ask questions, share panels, and stay up to date in the Django Control Room Discord.
Usage
<!-- 3-way split: just add a third section -->
<div class="dcr-split-card">
<div class="dcr-split-card__section">…</div>
<div class="dcr-split-card__section">…</div>
<div class="dcr-split-card__section">…</div>
</div>
Generic bordered container for building any card-like panel UI. Compose dcr-card__header, dcr-card__body, dcr-card__row, and dcr-card__footer as needed. Add dcr-card__header--subtle to tint the header. Use dcr-card__body--flush to remove padding from the body (e.g. when the body contains a table or list).
Body content goes here. Use dcr-card__body for padded content.
Use dcr-card__header--subtle for a tinted header row.
Cards don't require a header. Drop any zone you don't need.
Usage
<!-- header + body -->
<div class="dcr-card">
<div class="dcr-card__header">
<h3 class="dcr-card__title">
<svg class="dcr-card__title-icon" …></svg>
Card title
</h3>
<span class="dcr-card__meta">meta</span>
</div>
<div class="dcr-card__body">…</div>
<div class="dcr-card__footer">Footer note</div>
</div>
<!-- subtle (tinted) header -->
<div class="dcr-card">
<div class="dcr-card__header dcr-card__header--subtle">…</div>
…
</div>
<!-- flush body (no padding - use for tables, lists) -->
<div class="dcr-card">
<div class="dcr-card__header">…</div>
<div class="dcr-card__body dcr-card__body--flush">…</div>
</div>
Use dcr-card with dcr-card__row items. Each row uses dcr-card__row-source (badge), dcr-card__row-text, and dcr-card__row-time.
Usage
<div class="dcr-card">
<div class="dcr-card__header">
<h3 class="dcr-card__title">
<svg class="dcr-card__title-icon" …></svg>
Recent activity
</h3>
<span class="dcr-card__meta">Across all panels</span>
</div>
<div class="dcr-card__row">
<span class="dcr-card__row-source"><span class="dcr-badge dcr-badge--warning">ERRORS</span></span>
<span class="dcr-card__row-text">KeyError in checkout.views.create_order</span>
<span class="dcr-card__row-time">2m ago</span>
</div>
</div>
Use dcr-card with dcr-card__row items. Each row uses dcr-card__row-label and dcr-card__row-value (add --bold for emphasis). dcr-card__footer adds a muted note below the rows.
Usage
<div class="dcr-card">
<div class="dcr-card__header">
<h3 class="dcr-card__title">System</h3>
</div>
<div class="dcr-card__row">
<span class="dcr-card__row-label">Django</span>
<span class="dcr-card__row-value">5.0.6</span>
</div>
<div class="dcr-card__row">
<span class="dcr-card__row-label">Database</span>
<span class="dcr-card__row-value dcr-card__row-value--bold">PostgreSQL 16</span>
</div>
<div class="dcr-card__footer">Last refreshed just now.</div>
</div>
Use dcr-code-viewer as the outer wrapper. dcr-code-viewer__header / __label / __meta style the labelled header strip. dcr-code-viewer__body holds the highlight.js code block. Optionally add a dcr-code-viewer__title zone for function signatures.
{"id": "42", "username": "ada", "theme": "dark"}
Usage
<div class="dcr-code-viewer">
<div class="dcr-code-viewer__header">
<span class="dcr-code-viewer__label"><> Raw Value</span>
<span class="dcr-code-viewer__meta">412 B</span>
</div>
<pre class="dcr-code-viewer__body"><code class="language-json">{"key": "value"}</code></pre>
</div>
<!-- With optional title zone -->
<div class="dcr-code-viewer">
<div class="dcr-code-viewer__title">
<div class="dcr-code-viewer__title-main">
<div class="dcr-code-viewer__title-sig">
<span class="dcr-code-viewer__title-lineno">1</span>
<span class="dcr-code-viewer__title-name">create_profile</span>
<span class="dcr-code-viewer__title-params">sender = auth.User</span>
</div>
<div class="dcr-code-viewer__title-path">profiles/signals.py:14</div>
</div>
<div class="dcr-code-viewer__title-tags">
<span class="dcr-badge">profiles</span>
</div>
</div>
<div class="dcr-code-viewer__header">…</div>
<pre class="dcr-code-viewer__body">…</pre>
</div>