Tokens
All styling reads --bless-* custom properties from tokens.css — 91 of them. Override on :root to retheme the whole app; override on a subtree to change individual values there (a palette or dark mode, which are attribute-driven on <html>, stay app-wide).
:root {
--bless-lean: -6deg; /* a gentler lean */
--bless-font-sans: "Inter", system-ui, sans-serif;
}To change the accent, pick a palette or define a whole one — the accent is a family (accent, accent-text, accent-soft, accent-2, badge, chart-1) with contrast rules, and changing accent alone leaves the rest on Megumi's pink.
Greys
texttext-mutedbgsurfacesurface-2watermarkborderrule
Accent family
accentaccent-textaccent-softaccent-2badge
Status
dangerdanger-textwarningsuccessinfoinfo-text
On a fill
on-accenton-texton-light
Chart
chart-1chart-2chart-3chart-4chart-5
Overlay
backdropmedia-bg
| Group | Props |
|---|---|
| Colour | --bless-color-{text,text-muted,bg,surface,surface-2,watermark,accent,accent-soft,accent-2,accent-text,danger,danger-text,badge,warning,success,info,info-text,on-accent,on-text,on-light,border,rule,backdrop,media-bg,chart-1..5} |
| Font | --bless-font-sans, --bless-font-weight-{thin,light,normal,bold} |
| Type scale | --bless-text-{2xs,xs,sm,md,lg,xl,headline,display} — fluid clamp(), 8→151px; headline is the hanging page title (36–73px), display the watermark |
| Leading / tracking | --bless-leading-{none,tight,normal}, --bless-tracking-{tight,normal,wide,wider} |
| Space | --bless-space-{1,2,3,4,6,8,12,16} — 4px base |
| Shape | --bless-lean, --bless-skew, --bless-skew-counter, --bless-petal, --bless-radius-petal (+-lg), --bless-radius, --bless-radius-plate (0, override points), --bless-border-width, --bless-dash-width |
| Elevation | --bless-shadow-plate (1px 1px 0 accent, via --bless-plate-offset), --bless-shadow-none; --bless-shadow-md is an alias of plate |
| Motion | --bless-duration-{fast,base,slow,slower}, --bless-ease-{in-out,out,linear}, --bless-hover-opacity, --bless-press-scale, --bless-lean-transition |
| Layout | --bless-sidebar-width, --bless-sidebar-inner, --bless-content-max, --bless-z-{bg,nav,modal}, --bless-safe-{top,right,bottom,left} (env(safe-area-inset-*), for notches) |
Durations collapse to 0s under prefers-reduced-motion.
What flips, what swaps
- Dark mode redefines the greys and what sits on them:
text,text-muted,bg,surface,surface-2,watermark,border,rule,backdrop,danger,danger-text,info-text,accent-text,chart-2..5, andfont-weight-thin(100 → 300, hairlines read thinner light-on-dark). The accent family is untouched. - A palette swaps only the accent family:
accent,accent-soft,accent-2,accent-text,badge,chart-1. Greys, type and geometry stay. - Right-to-left mirrors
leanand the petal corners.
Shape
One shape — see Conventions. --bless-lean is the house angle; --bless-skew / --bless-skew-counter are the current lean every plate and its text read — 0deg at rest, set to the lean on hover, focus, press or while writing. Set --bless-skew: var(--bless-lean) (and the counter to its negative) on an element to make it lean at rest; set --bless-lean: 0deg to turn the lean off. A control of your own that sets its own transition should append var(--bless-lean-transition) to the list, or its lean snaps instead of animating. --bless-radius-petal (and -lg for chat bubbles) is what avatars, switches, chips, bubbles, fabs and thumbs read for their corners; it is square because --bless-petal is 0. Set --bless-petal to round two opposite corners of those parts, or --bless-radius / --bless-radius-plate to round boxes and plates — the library itself sets none of them.
Colour pairs
accent-text— the accent as text onbg/surface: darkened per palette to ≥4.5:1 (links, active nav, selected rows). Fills useaccent, deepened per palette to carry white text at 4.5:1; as text on the page it's too light, so useaccent-text.- The accent's contract, for any palette of your own:
accentmust carry white text at 4.5:1, andaccent-textmust reach 4.5:1 onbgandsurfacein both themes. badge—BlessBadge color="badge"and notification counts; a step of the accent family, so it re-tints with the palette and carries white at 4.5:1. Badges are ink by default.danger/danger-text—dangeris the fill (destructive buttons, invalid borders);danger-textis error copy, ≥4.5:1 onbgandsurface. They're the same red in light mode; dark mode lifts the text one so it stays readable on the dark greys, where no single red could be both.info/info-text— the same split:info-textfor info as text (outline badges, alert titles).on-accent— text on any accent / danger / info fill (white).on-text— text on a--bless-color-textfill; equalsbg, so it inverts with the theme.on-light— text on warning / success fills, which are too pale for white.chart-1..5— categorical series, all ≥3:1 onbgandsurfacein both themes.
Tailwind v4
Tokens are plain custom properties, so they slot into Tailwind's @theme and come out as utilities (bg-accent, text-text, border-border…). Blessing itself doesn't depend on Tailwind.
@theme {
--color-accent: var(--bless-color-accent);
--color-text: var(--bless-color-text);
--color-border: var(--bless-color-border);
}