{% extends "admin/base.html" %} {% block content %}
The philosophy behind Plain Admin's design
Honest and straightforward. Not trying too hard. The design should feel natural and unforced, never showy or overwrought.
Polished and professional, but approachable. Like a quality hand tool—clean, functional, built to last. Not a showpiece.
Warm stone neutrals inspired by nature. Colors that feel grounded and real, not synthetic or harsh. Earthy without being rustic.
Dense where it needs to be, spacious where it helps. Every element earns its place. No wasteful whitespace, no unnecessary decoration.
Blue links, obvious buttons, clear hierarchy. Use patterns people already know. Innovate on functionality, not on basic interactions.
Should complement, not compete with, the user's own brand. Neutral enough to feel at home in any project. Themeable in spirit.
How styling is organized and applied
Element selectors that apply automatically. No classes needed.
table, input, select, textarea, label, button, aside, code, dl
Reusable classes for explicit styling. Apply where needed.
.plain-btn .plain-btn-primary, .plain-label .plain-label-success, .plain-link
Semantic attributes for behavior.
data-dropdown
Documented class combinations for common UI patterns.
Typography, breadcrumbs, pagination, empty states
Color tokens defined in :root for theming
--plain-olive
Primary buttons, checkboxes
--plain-steel
Links
stone-800
Text, headings
--plain-success
--plain-warning
--plain-danger
--plain-info
These elements are styled automatically via element selectors. Just use the HTML—no classes needed.
Styled via table, th, td, tbody tr selectors.
| Package | Version | Status |
|---|---|---|
| plain-models | 1.0.0 | Stable |
| plain-htmx | 0.9.0 | Beta |
| plain-cache | 1.2.0 | Stable |
Includes hover states, border styling, and proper spacing.
Styled via label, input[type="*"], textarea, select selectors.
Includes focus states, placeholder styling, and checkbox accent color.
Styled via main :is(p, li, dd) a selector. Links in prose content (paragraphs, lists, definition lists) are steel blue with underline.
Manage your settings in the dashboard. See documentation for details.
Styled via code and pre code selectors.
Run plain dev to start the server, or plain test for tests.
from plain.models import Model
class User(Model):
name = models.CharField(max_length=100)
Styled via .card class. Use section for the body.
Use col-span-4 for full-width table cards:
| Event | User | Time |
|---|---|---|
| User created | admin@example.com | 2 min ago |
| Settings updated | dave@example.com | 1 hour ago |
Styled via dl, dt, dd selectors. Add grid classes for layout.
Use grid grid-cols-[160px_1fr] for key-value layout.
Styled via main button and button[type="submit"] selectors.
Submit buttons automatically get primary (olive) styling. Regular buttons get default (gray) styling.
Explicit classes for when you need specific styling beyond the defaults.
Use .plain-btn as the base class, optionally with a variant for color.
.plain-btn, .plain-btn .plain-btn-primary, .plain-btn .plain-btn-success, ...
Use .plain-label as the base class, optionally with a variant for color.
.plain-label, .plain-label .plain-label-success, .plain-label .plain-label-warning, ...
For links outside of <main> that need steel blue color.
Steel link for use in headers or navigation.
.plain-link
For form validation errors.
Please enter a valid email address.
.plain-error (on input), text-[var(--plain-danger)] (on error text)
Semantic attributes that trigger styling or behavior.
Documented class combinations for common UI patterns not covered by Global CSS.
Text styles and hierarchy.
text-2xl font-semibold
text-lg font-semibold
text-base font-medium
text-sm
text-sm text-black/60
text-sm text-stone-500
text-[11px] font-semibold uppercase tracking-wider text-stone-400
Navigation path showing current location.
Links separated by / with current item in text-stone-700
Page navigation for list views.
Informational placeholders for empty views. Keep them subtle—they inform without demanding attention.
No items yet
A hairline border maintains visual flow. Centered text reads as a state message. Differentiate between "no results" (search) and "no items yet" (empty table).
Bordered containers with background fills, prominent centered icons (especially in circles), and inbox/tray icons signal interactivity—drag-and-drop, file upload. Empty states should feel informational, not interactive.