Theme Composer
Pick an accent, a corner radius, a density, a type scale and a font. Every control on the canvas below is the real Shiny control, reading the same tokens your app reads — so what you see is what you ship.
Why it is only a handful of knobs
Section titled “Why it is only a handful of knobs”A theme has two layers. You author about thirty-five values; the stylesheet derives the other
hundred and fifty-three from them with color-mix() and calc().
That is what makes this page possible. An accent is one token — --shiny-primary — and the container
tint, the surface tint, the hover state and the focus ring all follow it because they are expressed
over it, not listed beside it. Driving the flat token set directly would have meant writing eight role
colours per scheme, by hand, with the tonal maths right, for every change of a single knob.
The same split is why a pack is now a ~40-line delta over the base theme instead of a 364-line re-declaration of everything.
Taking the design with you
Section titled “Taking the design with you”Get code in the dock prints both halves of the contract:
| Platform | Details |
|---|---|
| Blazor | a small block of custom properties. Put it in your own stylesheet and link that after shiny-theme.css; your declarations win on source order, and every derived token re-derives from them automatically. |
| MAUI | the same values as a ResourceDictionary. Merge it after the pack’s own dictionary, or paste the colours into a copy of one of the shipped theme dictionaries. |
Copy link puts the whole design in a URL. The ?preset= code is one character per knob, so it is
short enough to paste into an issue or a review and have the other person see exactly what you saw.
Going further than the knobs
Section titled “Going further than the knobs”The dock covers the axes most themes actually move. To author a theme properly — every authoring
token, both schemes, checked in — write a themes/<slug>.json in the controls repo and run:
dotnet run --project tools/ShinyThemeGenThat emits both hosts from one source: the Blazor stylesheet and the MAUI XAML dictionaries. See Theming for the full token reference, and Theme packs for what the five shipped packs each change.


