Theming
Components take their colours from CSS variables. To change the theme, you edit those variables and leave the components alone.
Where the tokens live
In vendor/shadwire/shadwire.css. shadwire init
installs it and imports it in your app's Tailwind entrypoint, whose path
bin/shadwire status --json shows under tailwind.css.
The file has three layers:
@theme inline turns --primary into the
bg-primary and text-primary utilities. The colours
are written in OKLCH.
Edit :root and .dark, never @theme inline
@theme inline block only maps each variable to a Tailwind utility. The
colours themselves are set in the :root (light) and .dark blocks.
The tokens
Each background token has a -foreground token for the text on top of
it. Use the two together, as in bg-muted text-muted-foreground, rather
than bg-muted with the default text colour.
| Token | Controls | Used by |
|---|---|---|
background / foreground |
Application background and default text | Page shell, sections, default text |
card / card-foreground |
Raised surfaces | Card, dashboard and settings panels |
popover / popover-foreground |
Floating surfaces | Popover, DropdownMenu, ContextMenu, overlays |
primary / primary-foreground |
High-emphasis actions, brand | Default Button, selected states, badges |
secondary / secondary-foreground |
Lower-emphasis filled actions | Secondary buttons and badges |
muted / muted-foreground |
Subtle surfaces, secondary content | Descriptions, placeholders, empty states, supporting text |
accent / accent-foreground |
Hover, focus and active surfaces | Ghost buttons, menu highlight, hovered rows |
destructive / destructive-foreground |
Destructive actions, errors | Destructive buttons, invalid states |
border |
Borders and separators | Cards, menus, tables, dividers |
input |
Form control borders | Input, Textarea, Select, outline controls |
ring |
Focus rings | Buttons, inputs, checkboxes, menus |
chart-1 … chart-5 |
Chart palette | Charts and chart-driven blocks |
sidebar / sidebar-foreground |
Sidebar surface and text | The Sidebar container |
sidebar-primary / -foreground |
High-emphasis actions in the sidebar | Active items, icon tiles, CTAs |
sidebar-accent / -foreground |
Hover and selection in the sidebar | Menu hover, open items |
sidebar-border |
Sidebar borders | Sidebar headers, groups and dividers |
sidebar-ring |
Sidebar focus rings | Focused controls in the sidebar |
radius |
Base corner radius | Cards, inputs, buttons, popovers |
Changing the brand colour
Set --primary and --primary-foreground in both
blocks, and every component that uses bg-primary picks up the new
colour.
Choose a foreground with enough contrast against the new primary, and check it in both light and dark mode.
Adding a token
Declare the variable in both blocks and map it in @theme inline so
Tailwind generates the utilities:
After that, bg-success and
text-success-foreground work like any other token.
Corner radius
radius-sm, radius-md and
radius-lg are all derived from --radius, so
changing it changes the corners of cards, inputs, buttons and popovers in one go.
Adding a variant
Variants are frozen Ruby hashes in the component's class. The file is yours, so adding a variant means adding a key:
This counts as a local edit: bin/shadwire diff will list the file as
modified, and bin/shadwire update would overwrite it.
Keeping your edits
bin/shadwire diff <name>: see what you changed.-
bin/shadwire update <name>without--yes: it asks about each modified file and shows the diff. - Put your edits back on top of the new version.
Where you can, add things (a new variant, a new token) instead of rewriting existing classes. Additions are much easier to carry over when you update.