Foundations
Product themes
The base and the product layer: how to add the ShadeNotes, portfolio or a new theme
The base goes into every product first and is the same for all. The product layer changes only the accent: --primary, --primary-foreground, --primary-ink, --primary-edge. A new product makes its own layer from this pattern
npx shadcn@latest add @umbra/theme-baseThe foundation of the system: CSS variables (tokens.css), base styles (base.css) and a bridge to Tailwind. Files go to styles/umbra/
tokens.css: window, tile, nested surface, text, color roles, glass, geometry, font, typography, motion. Light theme in:root, dark in.darkbase.css: SF Pro via the system stack (Inter as fallback),text-wrap: balanceon headings andprettyon paragraphs, a 4 px scrollbar in--textat 22%,.glass,.glass-soft,.glass-dense,.glass-pop,.edge-fade,.umbra-fill(cards two per row, one per row in a narrow window; an odd last card spans the full width), motion utilities (.umbra-appear,.umbra-rise,.umbra-leave,.umbra-exit,.umbra-stagger,.umbra-transition,.umbra-spin),prefers-reduced-motionandprefers-reduced-transparencyrulestailwind-v4.css:@theme inlineand@utilityfor Tailwind 4tailwind-v3-preset.cjs: a preset for Tailwind 3.4. The classes match v4 one to one
When to use
Always, as the first step in a new product and before any @umbra component
When not to use
If tokens.css is already added to the product by hand. Don’t install it twice: variables are defined in one place
Surfaces
Light
window
tile
nested
popover
skeleton
nav-active
Dark
window
tile
nested
popover
skeleton
nav-active
Color roles
Light
primary
indigo
indigo-soft
giants
record
destructive
Dark
primary
indigo
indigo-soft
giants
record
destructive
Typography
Light
Display 36/40
Title 22/28
Heading 20/28
Body 15/22: main app text
Label 14/20: button labels
Caption 13/18: meta
MONO 12/16 · TUE, 10:00
Dark
Display 36/40
Title 22/28
Heading 20/28
Body 15/22: main app text
Label 14/20: button labels
Caption 13/18: meta
MONO 12/16 · TUE, 10:00
Glass over content
Light
.glass
sticky header, menus, tooltips
Dark
.glass
sticky header, menus, tooltips
Do
- Take color only through a role:
bg-tile,text-muted,bg-primary - Role text goes on the soft tones
bg-indigo-soft,bg-giants-soft; on the saturatedbg-indigo,bg-giantsonly icons - Ink
text-*-ink: icons and text. Small text only where the pair passes Lc 75 inpnpm apca:text-primary-inkeverywhere,text-indigo-inkandtext-giants-inkonly in the light theme; in the dark theme they are only for large semibold text (text-title,text-heading) - Glass only on things that sit above content: sticky header, menus, tooltips, dialogs, dock
Don’t
- Raw colors,
p-[13px],rounded-lg, opacity modifiers (bg-primary/50):@umbra/eslintcatches them - Rewrite
tokens.cssin a product. A product changes only the accent inproduct.css - The
dark:modifier for colors: the theme switches via variables, the classes stay the same - Mix
base.cssclasses (.umbra-transition,.glass) with utilities for the same property on one element (umbra-transition duration-base): in Tailwind 4base.csssits outside layers and beats utilities, in 3.4 it loses. Need a different duration? Usetransition-all duration-base ease-outwithout.umbra-transition
npx shadcn@latest add @umbra/theme-shadenotesThe ShadeNotes product.css. It sets only the accent: --primary, --primary-foreground, --primary-ink, --primary-edge and the product name. Everything else comes from the base
| Token | Light | Dark |
|---|---|---|
--primary |
#E4FB77 |
#E4FB77 |
--primary-foreground |
#111111 |
#111111 |
--primary-ink |
#576E00 |
#E4FB77 |
--primary-edge |
#98B620 |
#E4FB77 |
When to use
In ShadeNotes, once, after @umbra/theme-base. Add it to the global CSS after tokens.css
When not to use
In the portfolio (it uses @umbra/theme-portfolio) and in a new product: a new product needs its own product.css, derived by the rule in DESIGN.md (Colors, “Product accent”)
Light
Saved: accent as ink
Selected chipDark
Saved: accent as ink
Selected chipDon’t
- Add anything to
product.cssexcept the accent, logo and name
npx shadcn@latest add @umbra/theme-portfolioThe portfolio product.css, product name --product-name: "Aidyn Beisembin". Cobalt works as a button fill with white text (Lc 89), but as text and icons on #0A0A0A it doesn’t read (Lc 18), so --primary-ink is lightened in the dark theme
| Token | Light | Dark |
|---|---|---|
--primary |
#3044D8 |
#3044D8 |
--primary-foreground |
#FFFFFF |
#FFFFFF |
--primary-ink |
#3044D8 |
#C4CBFF |
--primary-edge |
#3044D8 |
#C4CBFF |
The site is dark-only for now (the dark class on <html>), but light values are set so the light theme can be turned on without recoloring
When to use
In the portfolio, once, after @umbra/theme-base
When not to use
In ShadeNotes and in a new product
Light
Saved: accent as ink
Selected chipDark
Saved: accent as ink
Selected chip