Standard provides physical color families with 12 steps: 100, 150,
200, 300, 400, 500, 600, 700, 800, 850, 900, and 950.
The interactive palette
shows the actual source colors in light and dark appearance.
Start with semantic roles
Use roles for component surfaces, text, focus, and state. The defaults are:
| Role | Default palette | Use |
|---|---|---|
primary |
ink |
Primary actions and emphasis |
neutral |
gray |
General surfaces, borders, and text |
focused |
Follows global neutral |
Focus treatment |
success |
jade |
Successful outcomes |
warning |
amber |
Warnings |
failure |
red |
Errors and destructive outcomes |
general |
blue |
Informational state |
<div class="bg-color:neutral-100 border-color:neutral-600 text-color:neutral-950">
A surface that follows the selected neutral palette
</div>| Step range | Typical role |
|---|---|
100–150 |
Backgrounds |
200–400 |
Interactive surfaces |
500–700 |
Borders and accents |
800–850 |
Solid treatments |
900–950 |
Text |
Steps guide selection; they do not guarantee contrast. Check the actual
text/background pair in both appearances and do not communicate state through
color alone. Fixed physical names such as teal-600 remain valid for content
that requires that specific hue; reusable components should follow roles.
The default ink palette supplies gray surfaces and near-black 800/850
fills in light appearance, with near-white fills in dark appearance. Its
200 step remains a subtle surface. It has all 12 steps and is consumed
through the existing primary role. gray and sage remain available.
TeaCSS 0.7.1 also sets lime-800 to Yiplex’s #C2D435 accent in both
appearances. Its 850 hover is darker in light appearance and lighter in
dark appearance. Those bright fills need dark text: use neutral-950 in
light appearance and neutral-100 in dark appearance. For text on subtle
surfaces, prefer the appearance-dependent lime-900 or lime-950.
Register palette choices
The CSS entry declares which built-in physical palettes a role may select:
@presets "standard,icons,official";
@primary "ink,gray,blue";
@neutral "gray,sage,slate";
@focused "gray,blue";
@success "jade,green";
@warning "amber,orange";
@failure "red,ruby";
@general "blue,cyan";
@teacss;Lists register choices without changing the default. Their names must be built-in physical palettes; custom colors and role-to-role references cannot be registered as choices. Repeated lists are combined.
Absent role attributes use the ink/gray defaults even without candidate
lists. Explicit root selections, including ink, require a matching list.
To keep the earlier gray/sage combination when upgrading, register both
palettes and select data-css-primary="gray" data-css-neutral="sage" on
html; a list alone does not select them.
Choose a registered palette on <html>:
<html lang="en" data-css-primary="blue" data-css-neutral="slate" data-css-appearance="light">
<body>...</body>
</html>These attributes are document-wide. Descendant attributes do not create a
local palette. Missing, empty, unknown, or unregistered role choices restore
the configured defaults. focused follows the effective global neutral
selection unless a valid focused selection or explicit default override is
provided. No regeneration is needed to switch among registered choices.
Resolve light and dark appearance
Set data-css-appearance="light" or data-css-appearance="dark" on <html>.
It selects color-mode values and drives @light and @dark conditions;
@os-light and @os-dark independently follow the operating system.
There is no implicit .dark class or descendant theme scope. Without a valid
explicit appearance, neither @light nor @dark matches, while the configured
base color table still applies.
Astra applications can place one AppearanceScript in <head> before styles
and use AppearanceSwitch to manage the preference. See
Astra for ownership and persistence.
The root stores the resolved light or dark value; system is a preference
that the manager resolves, not a third CSS appearance.
Add application colors
Register supported color values in the CSS entry:
@presets "standard";
@source "./src/**/*.{astro,html,js,jsx,ts,tsx}";
@custom {
--color-brand-500: #0f766e;
}
@teacss;This adds bg-color:brand-500 and text-color:brand-500. Custom names remain
utility values; this does not add a selectable physical palette. @custom
accepts supported theme namespaces. Ordinary application variables belong in
native CSS or the $name:value utility. Color mode blocks can override colors;
non-color values do not become per-mode theme settings.
Continue with Standard for properties and conditions.