Theming
PaperStack's theme engine is built entirely on CSS custom properties. Themes are SCSS
files that redefine the token layer — no JavaScript required. You can switch themes at
runtime by swapping a data-theme attribute on <html> or any
scoped element.
Built-in Themes
| Theme | Key | Description |
|---|---|---|
| Light (default) | light | Clean parchment-white with ink typography |
| Dark Parchment | dark-parchment | Dark surfaces with warm off-white text |
| Vintage Paper | vintage-paper | Aged, sepia-toned with warm browns |
| Terminal Paper | terminal-paper | Monochrome green-on-dark, typewriter aesthetic |
Import all themes from @paperstack/themes, or import individual files:
/* All themes (generates data-theme selectors) */
@use "@paperstack/themes/src/index.scss";
/* Or individual themes */
@use "@paperstack/themes/src/dark-parchment.scss";
@use "@paperstack/themes/src/vintage-paper.scss"; Applying a Theme
Set data-theme on the <html> element to activate a theme globally,
or on any element for scoped theming.
<!-- Global -->
<html data-theme="dark-parchment">
<!-- Scoped to a single card -->
<div data-theme="vintage-paper" class="ps-card">
...
</div> Switch themes at runtime with a few lines of JavaScript:
function setTheme(theme) {
document.documentElement.dataset.theme = theme;
localStorage.setItem("ps-theme", theme);
}
// Restore on load
const saved = localStorage.getItem("ps-theme");
if (saved) document.documentElement.dataset.theme = saved; Custom Themes
Create a custom theme by overriding the semantic token layer. You only need to redefine the tokens you want to change — everything else inherits from the base.
/* my-theme.scss */
[data-theme="my-theme"] {
--color-surface: #f5f0e8;
--color-text: #2a1f0e;
--color-border: rgba(42, 31, 14, 0.15);
--color-primary: #8b4513;
--color-primary-text: #fff;
/* Override font if needed */
--font-reading: "Libre Baskerville", Georgia, serif;
} Import your custom theme file anywhere in your stylesheet pipeline after the base tokens.
Dark Mode
PaperStack respects prefers-color-scheme: dark automatically when using the
dark-parchment theme as your dark variant. Configure it like this:
/* Apply dark-parchment automatically for OS dark mode */
@media (prefers-color-scheme: dark) {
:root {
@include dark-parchment-tokens;
}
}
Or use data-theme="dark-parchment" on your theme toggle button's handler alongside
a prefers-color-scheme media query listener for a hybrid approach.
Content Density
The density system adjusts spacing and sizing tokens via a single attribute. Three levels are available:
| Attribute | Scale | Best for |
|---|---|---|
data-density="compact" | 0.75× | Data-dense UIs, tables, admin dashboards |
| (none / default) | 1× | General applications |
data-density="comfortable" | 1.25× | Reading-first, content apps |
<html data-theme="light" data-density="compact">