Recipes
Patterns that come up often enough to be worth canonicalizing.
1. Brand color override (no new pack)
You don't need to author a full pack just to recolor your accent. Override
the relevant tokens in your input.css:
/* static/css/input.css */
:root {
--primary: 280 85% 60%; /* purple */
--primary-foreground: 0 0% 100%;
--ring: 280 85% 60%;
--link: 280 85% 60%;
--link-hover: 280 85% 70%;
}
This wins over the active pack because the cascade resolves your explicit
:root rule last. Switching packs still works for everything else (cards,
borders, surfaces, text) — they just won't override --primary while
your stylesheet is loaded.
When to use: you want one consistent brand color regardless of which shipped pack the user picked.
2. Page-level theme wrapper
A different look on a single page (e.g. a marketing landing inside an admin app):
/* static/css/input.css */
.theme-marketing {
--background: 40 30% 7%;
--foreground: 40 20% 92%;
--primary: 28 85% 55%;
--primary-foreground: 30 25% 8%;
--card: 40 20% 9%;
--border: 0 0% 16%;
}
{% extends "base.html" %}
{% block body %}
<body class="theme-marketing">
{% block content %}...{% endblock %}
</body>
{% endblock %}
Tailwind utilities and djust components on that page will repaint to the overridden tokens. The user-facing pack switcher still affects every other page on the site.
When to use: a landing page with a designer-controlled palette inside an otherwise theme-switchable app.
3. Per-section accent
Sometimes one section needs a different accent without changing the rest:
/* Pricing card group with a green accent */
.pricing-grid {
--primary: 160 60% 40%;
--primary-foreground: 0 0% 100%;
}
<section class="pricing-grid">
<article class="pricing-card">
<h3>Pro</h3>
<button class="bg-brand-rust">Choose Pro</button>
<!-- ^ uses --primary, now green here -->
</article>
</section>
The CSS-variable inheritance scope means the override applies to every descendant.
4. Dark-mode-only styling without @media (prefers-color-scheme)
djust's mode switch flips a .dark class on <html> (or sets
:root[data-theme="dark"], depending on pack config). Use it for any
truly mode-specific styling:
.dark .my-card {
background: hsl(var(--card));
box-shadow: 0 4px 12px rgba(0 0 0 / 0.5);
}
:root:not(.dark) .my-card {
background: hsl(var(--card));
box-shadow: 0 4px 12px rgba(0 0 0 / 0.05); /* softer in light */
}
This respects the user's session-persisted choice — prefers-color-scheme
would only respect the OS-level setting and would conflict with the
in-app switcher.
5. Component-scoped variable (no pack involvement)
For a component that needs a knob the pack doesn't model, declare the variable on the component root:
.toast {
--toast-duration: 4s;
--toast-max-width: 360px;
animation: toast-fade var(--toast-duration);
max-width: var(--toast-max-width);
}
To override per-instance, just inline:
<div class="toast" style="--toast-duration: 8s">Long-running message</div>
No pack changes needed.
6. Honoring system theme on first visit
Default to the OS preference for first-time visitors, persist their explicit choice afterward:
# settings.py
LIVEVIEW_CONFIG = {
'theme': {
'pack': 'docs',
'default_mode': 'dark', # used when no session + no OS hint
'enable_dark_mode': True,
'persist_in_session': True,
'respect_system_preference': True, # opt-in, falls through if no
# session value is set
},
}
The user's first visit reads prefers-color-scheme; their first explicit
toggle of the mode switcher writes a session value that wins from then
on.
7. Showing the active pack in a debug strip
Useful in staging — drop a small badge in the corner so the QA team can see which pack is rendering:
{% if request.user.is_staff %}
<div class="debug-strip">
pack: {{ request.theme.pack.name }}
· mode: {{ request.theme.mode }}
</div>
{% endif %}
.debug-strip {
position: fixed; bottom: 8px; left: 8px;
padding: 4px 8px; font-family: monospace; font-size: 11px;
color: hsl(var(--muted-foreground));
background: hsl(var(--card) / 0.9);
border: 1px solid hsl(var(--border));
border-radius: 4px;
pointer-events: none; z-index: 9999;
}
See also
- Authoring a pack — for the cases these recipes can't cover.
extra_css_vars— for project-specific knobs that should travel with the pack.- Troubleshooting — when a recipe doesn't work.