Colour
Two themes carry Tempio’s colour. neutral is the app’s and the console’s
look, measured off Attio: a near-black ink on white, colour by alpha, Inter.
tempio is the site’s, the docs’ and the emails’, built on the kit’s purple.
This page opens on neutral. Pick tempio above and the semantic layer, the
feel colours, the chart series and the objects repaint, with the values
printed under them. The lane colours and the ramps are the same in every
theme, and the grounds specimen always draws tempio.
Semantic layer
What components read. Each theme maps these once per mode: tempio
onto the scale steps further down, neutral onto the values measured off
Attio, except success and warning, which read green.9 and amber.9.
Brand primitives (--brand-*) never change.
Under each name, the light value, then the dark value, of the theme the switcher shows.
--background#FFFFFF · #171216--foreground#171216 · #F4ECF2--card#FFFFFF · #1E181D--card-foreground#171216 · #F4ECF2--popover#FFFFFF · #262025--popover-foreground#171216 · #F4ECF2--primary#5B054F · #5B054F--primary-foreground#FFFFFF · #FFFFFF--secondary#F4ECF2 · #262025--secondary-foreground#171216 · #F4ECF2--muted#F4ECF2 · #262025--muted-foreground#5A5358 · #C7BFC5--accent#EAE2E8 · #2D272C--accent-foreground#171216 · #F4ECF2--destructive#A30006 · #FF1A1A--destructive-foreground#FFFFFF · #171216--success#26B759 · #27B759--success-foreground#171216 · #171216--warning#F39A46 · #F39A46--warning-foreground#171216 · #171216--border#D0C8CE · #423C41--input#BCB5BB · #534D52--ring#D979B6 · #8D3370--link#731058 · #F88ED1--chart-1#A4237F · #CD4EA4--chart-2#E88C69 · #E88C69--chart-3#FFB162 · #FFB162--chart-4#5B054F · #B863A7--chart-5#766F75 · #938C92--sidebar#FCF4FA · #1E181D--sidebar-foreground#171216 · #F4ECF2--sidebar-primary#5B054F · #5B054F--sidebar-primary-foreground#FFFFFF · #FFFFFF--sidebar-accent#F4ECF2 · #2D272C--sidebar-accent-foreground#171216 · #F4ECF2--sidebar-border#D0C8CE · #423C41--sidebar-ring#D979B6 · #8D3370Feel colours
The roles beside the semantic layer, among them the hover and active fills,
the placeholder and subtle inks, the selection, cell and row tints, the skeleton
pair, the tooltip, the sidebar’s hover and labels, a dialog’s frosted frame,
a count badge’s ink, and the edges of a checkbox and a toggle’s thumb.
Most of neutral’s are measured off Attio; the $comment in neutral.json
names the few that were not. tempio writes most of its own as references
to its roles, such as var(--muted); three are transparent, because
tempio draws no cell or enrichment tint and no frost round a dialog.
Every theme without a feel of its own takes tempio’s, so it draws what it
drew before the feel existed.
--hovervar(--muted) · color-mix(in oklab, var(--muted) 50%, transparent)--activevar(--accent) · var(--accent)--primary-hovercolor-mix(in oklab, var(--primary) 80%, transparent) · color-mix(in oklab, var(--primary) 80%, transparent)--secondary-hovercolor-mix(in oklch, var(--secondary), var(--foreground) 5%) · color-mix(in oklch, var(--secondary), var(--foreground) 5%)--subtle-foregroundvar(--muted-foreground) · var(--muted-foreground)--placeholdervar(--muted-foreground) · var(--muted-foreground)--border-strongvar(--border) · var(--input)--link-underlinevar(--link) · var(--link)--selectioncolor-mix(in oklch, var(--primary) 25%, transparent) · color-mix(in oklch, var(--primary) 25%, transparent)--cell-active-tinttransparent · transparent--row-selected-tintvar(--muted) · var(--muted)--enriched-tinttransparent · transparent--skeletonvar(--muted) · var(--muted)--skeleton-highlightvar(--accent) · var(--accent)--tooltipvar(--foreground) · var(--foreground)--tooltip-foregroundvar(--background) · var(--background)--sidebar-hovervar(--sidebar-accent) · var(--sidebar-accent)--sidebar-muted-foregroundcolor-mix(in oklab, var(--sidebar-foreground) 70%, transparent) · color-mix(in oklab, var(--sidebar-foreground) 70%, transparent)--frosttransparent · transparent--badge-foregroundvar(--secondary-foreground) · var(--secondary-foreground)--control-bordervar(--input) · var(--input)--control-thumb-ringvar(--border) · var(--border)--tag-grey#F6F7F7 · #1B1C1F--tag-grey-ring#EEEFF1 · #2F3033--tag-grey-foreground#505155 · #D9DADE--tag-red#FFEBEB · #4E1B28--tag-red-ring#FFDCDB · #692623--tag-red-foreground#BA2525 · #FFD1D1--tag-orange#FEEEE1 · #432410--tag-orange-ring#FEE0C8 · #593217--tag-orange-foreground#9E3F00 · #FFC89E--tag-amber#FFF3CC · #3A2D12--tag-amber-ring#FFE59E · #523817--tag-amber-foreground#874D00 · #FFD269--tag-lime#F4FBCB · #2F3802--tag-lime-ring#E9F797 · #3B4217--tag-lime-foreground#536300 · #D7EB67--tag-green#E0FCED · #1D4034--tag-green-ring#CBF7E1 · #244A3A--tag-green-foreground#007D53 · #A7F2CF--tag-cyan#DDF7FF · #1A3946--tag-cyan-ring#D0EFF7 · #0A4E6B--tag-cyan-foreground#056C87 · #A9EBFC--tag-blue#E5EEFF · #1D2E55--tag-blue-ring#D6E5FF · #2B3E6D--tag-blue-foreground#215BC4 · #C2D6FF--tag-purple#F5F0FF · #2F1E5A--tag-purple-ring#E8DDFE · #45297D--tag-purple-foreground#6238B5 · #D8C4FF--tag-fuchsia#FDEDFF · #431B4B--tag-fuchsia-ring#FAD6FF · #5C2169--tag-fuchsia-foreground#9C1BAB · #F6BDFC--tag-pink#FEECF3 · #4E1B30--tag-pink-ring#FDDDEA · #642640--tag-pink-foreground#B81C5D · #FFBFDA--tag-yellow#FDF7C4 · #373313--tag-yellow-ring#FCEF7E · #423E17--tag-yellow-foreground#665A00 · #F5E242Chart series
Charts read seven series, in order. chart-1 to chart-5 are semantic
slots; chart-6 and chart-7 are feel colours, which tempio points at
destructive and warning. Under neutral the seven are the fit sheet’s
blue, green, orange, violet, pink, red and amber, and a chart that asks for
a wash paints none behind it.
--chart-1#A4237F · #CD4EA4--chart-2#E88C69 · #E88C69--chart-3#FFB162 · #FFB162--chart-4#5B054F · #B863A7--chart-5#766F75 · #938C92--chart-6var(--destructive) · var(--destructive)--chart-7var(--warning) · var(--warning)Objects and tiles
Each object in the app and the console has a colour: the fill of its tile,
then a tint, the tint’s inset ring and the ink written on the tint, for a
chip that names it. Each row starts with the chip as ObjectChip draws it,
then the fill, the ring and the ink. Below the objects are the tile’s own
colours: the 1px ring every tile wears, the glyph’s white, the grey tile in
⌘K and toasts, and the fallback tile of a record with no logo.
The icons page draws them as tiles.
- campaign
- plan
- review
- library
- creative
- agent
- connection
- company
- person
- deal
- list
- object
--tile-ringcolor-mix(in oklab, var(--foreground) 10%, transparent) · color-mix(in oklab, var(--foreground) 10%, transparent)--tile-glyphvar(--primary-foreground) · var(--primary-foreground)--tile-neutralvar(--muted) · var(--muted)--tile-neutral-ringvar(--border) · var(--border)--tile-fallbackvar(--muted) · var(--muted)--tile-fallback-ringvar(--border) · var(--border)--tile-fallback-glyphvar(--muted-foreground) · var(--muted-foreground)Categorical
The planner’s lane colours: fifteen a person can give a bar on the Gantt. Each
is a fill, the ink written on it and a hover shade for its handles, then a tag
style for a chip that names the colour: a tint, the tint’s ring and the ink
written on the tint. All six come per mode and are the same in every theme.
The first row is the fill with its name in its own ink, then the ink, then the
hover shade. The second is the tint with its name in the tag’s ink inside its
ring, then the ring, then the ink. build:tokens stops on an ink that reads
below 4.5:1 on the fill, the hover shade or the tint.
The planner page draws them on bars.
- redred
- orangeorange
- amberamber
- yellowyellow
- limelime
- greengreen
- tealteal
- aquaaqua
- blueblue
- indigoindigo
- purplepurple
- magentamagenta
- pinkpink
- roserose
- slateslate
Status colour
Status as a fill is the semantic solid with its foreground: bg-success with
text-success-foreground. Status as text or an icon is step 11 of the hue:
text-green-11, text-amber-11.
Under tempio, the solids are the kit’s own success, warning and danger
colours. White reads 2.6:1 on the green and 2.2:1 on the amber, so success
and warning carry dark ink in both modes. destructive is red.11 under
white in light, the one red step that also reads as text on the paper, and
red.9 with the ground as its ink in dark.
Grounds and the sidebar
Under tempio, only the page changes with the mode. In light, the page is the
kit’s pink-white paper and cards are white on it. In dark, the page is the
ground, the near-black moved onto the purple’s hue, and a card is one step
above it. The sidebar is the kit’s purple, plum.9, in both modes, under
white ink. The specimen below draws tempio whatever the switcher shows.
The dark theme writes the sidebar and the primary as plum.light.9, a
reference that holds the light ramp’s value: the dark ramp lifts its own step 9
so a solid shows on the ground, and white on the lifted step fails AA. The
sidebar’s hover is plum.10, its border plum.8, and its ring and its one
filled mark peach.9, so nothing on it is black.
Step roles
Twelve steps per hue, generated from a seed in tokens/brand.json. Geist numbers
ten steps 100–1000 and holds its two page backgrounds in a separate pair; those
ten are steps 3–12 here and the pair is steps 1–2. The slots in the table are
tempio’s; neutral reads two steps, green.9 and amber.9.
| Step | Geist alias | Role | Tempio slots that read it |
|---|---|---|---|
| 1 | background-1 | App background | light card, popover (neutral, pinned white); dark destructive-foreground, success-foreground, warning-foreground |
| 2 | background-2 | Subtle background, a card lifted off the ground | dark card |
| 3 | 100 | Component background at rest | secondary, muted; dark popover |
| 4 | 200 | Hovered component background | accent |
| 5 | 300 | Active or selected component background | none by default; available as bg-<hue>-5 |
| 6 | 400 | Subtle border, separator | border |
| 7 | 500 | Component border, hovered border | input |
| 8 | 600 | Strong border, focus ring | ring (magenta.8), sidebar-border (plum.8) |
| 9 | 700 | Solid accent: buttons, badges, chart series | primary, sidebar, sidebar-primary-foreground (plum.9); sidebar-primary, sidebar-ring (peach.9); success, warning; dark destructive; chart-1..5 |
| 10 | 800 | Hovered solid accent | sidebar-accent (plum.10); hover states of the solids |
| 11 | 900 | Low-contrast text, icons, status text | muted-foreground, link (magenta.11); light destructive (red.11) |
| 12 | 1000 | High-contrast text | foreground, every *-foreground on a surface; light success-foreground, warning-foreground |
- Step 1Geist background-1
App background
light
card,popover(neutral, pinned white); darkdestructive-foreground,success-foreground,warning-foreground - Step 2Geist background-2
Subtle background, a card lifted off the ground
dark
card - Step 3Geist 100
Component background at rest
secondary,muted; darkpopover - Step 4Geist 200
Hovered component background
accent - Step 5Geist 300
Active or selected component background
none by default; available as
bg-<hue>-5 - Step 6Geist 400
Subtle border, separator
border - Step 7Geist 500
Component border, hovered border
input - Step 8Geist 600
Strong border, focus ring
ring(magenta.8),sidebar-border(plum.8) - Step 9Geist 700
Solid accent: buttons, badges, chart series
primary,sidebar,sidebar-primary-foreground(plum.9);sidebar-primary,sidebar-ring(peach.9);success,warning; darkdestructive;chart-1..5 - Step 10Geist 800
Hovered solid accent
sidebar-accent(plum.10); hover states of the solids - Step 11Geist 900
Low-contrast text, icons, status text
muted-foreground,link(magenta.11); lightdestructive(red.11) - Step 12Geist 1000
High-contrast text
foreground, every*-foregroundon a surface; lightsuccess-foreground,warning-foreground
background reads no step: it is the paper in light and the ground in dark,
both brand primitives. chart-5 is neutral.9.
Scales
Light and dark ramps; toggle the mode above and the labels follow it. The ramps are the same in every theme. An accent hue’s seed is its step 9 in light, verbatim. The neutral’s seed is a ground rather than a solid, so it sets the lightness of the ramp’s ends instead: step 12 in light, step 1 in dark.
neutral
- 1#FFFFFF
- 2#FCF4FA
- 3#F4ECF2
- 4#EAE2E8
- 5#DED6DC
- 6#D0C8CE
- 7#BCB5BB
- 8#A39CA2
- 9#766F75
- 10#686166
- 11#5A5358
- 12#171216
magenta
- 1#FFFAFD
- 2#FFF3FA
- 3#FFE6F4
- 4#FFD7EE
- 5#FDC6E7
- 6#F6B2DB
- 7#E99ACB
- 8#D979B6
- 9#A4237F
- 10#930A70
- 11#731058
- 12#3B0C2C
coral
- 1#FFFBF9
- 2#FEF4F1
- 3#FFEBE4
- 4#FFE1D6
- 5#FDD6C7
- 6#F9C9B7
- 7#F3B9A3
- 8#EBA48A
- 9#E88C69
- 10#D77C5A
- 11#824027
- 12#37170B
peach
- 1#FFFBF8
- 2#FDF5EE
- 3#FEEEE0
- 4#FFE6D0
- 5#FFDEC1
- 6#FED6B1
- 7#FBCCA0
- 8#FBC088
- 9#FFB162
- 10#EEA151
- 11#7B4701
- 12#341B00
plum
- 1#FFFAFE
- 2#FDF3FA
- 3#FBE8F6
- 4#F7DBF0
- 5#F2CCE8
- 6#E8BADC
- 7#DAA4CC
- 8#C785B8
- 9#5B054F
- 10#48003E
- 11#420338
- 12#32142C
red
- 1#FFFBFA
- 2#FFF4F2
- 3#FFE9E5
- 4#FFDBD5
- 5#FFCBC3
- 6#FFB5AA
- 7#FF9688
- 8#FE6657
- 9#FF1B1B
- 10#E8010D
- 11#A30006
- 12#470001
amber
- 1#FFFBF8
- 2#FEF5EE
- 3#FFEDDE
- 4#FFE3CE
- 5#FFDABB
- 6#FCCEA9
- 7#F8C093
- 8#F2AF76
- 9#F39A46
- 10#E28A34
- 11#7E4500
- 12#351A00
green
- 1#F8FEF9
- 2#EFFAF0
- 3#DFF7E3
- 4#CFF1D4
- 5#BDEBC4
- 6#A8E2B2
- 7#8ED59C
- 8#6AC57E
- 9#26B759
- 10#00A74A
- 11#00672B
- 12#002A0E
Themes
The Theme control on these pages offers tempio, neutral, ember and
ocean; the last two are demos of a theme file. The 36 themes imported from
the shadcnblocks Admin Kit’s presets stay in tokens.css and nothing offers
them. Each is a [data-theme] block that remaps the semantic layer and sets
its own --radius, takes tempio’s feel, and leaves the face alone.
neutral is the one theme besides tempio with a feel of its own, so its
radius steps, shadows, motion, type, focus ring and icon stroke differ too;
the Feel table on the DESIGN.md page lists every
value beside tempio’s.
pnpm --filter @tempio/ui import:themes runs
scripts/import-theme-presets.ts, which rewrites the set from the kit. Where a
preset fails a pair, the script moves the colour until it reads AA and writes
the move into that theme’s $comment. A preset whose page fails the step 11
gate is skipped, which is why Doom 64 is not in the set.
Contrast
Four gates run at build, before anything is written. checkContrast holds
every theme and mode to WCAG AA (4.5:1) on the text pairs in
scripts/tokens/contrast.ts. checkFeelContrast holds the feel’s inks to the
same bar in the two themes that set a feel, tempio and neutral, each
object chip’s ink on its tint among them. checkScaleText holds step 11 of
every hue to the same bar on background and on card, which is what makes
the status-text rule above safe. checkCategorical holds the lane colours’
inks, as the Categorical section says.
A failing pair is fixed in the theme, the seed or the ladder, never by deleting the pair. A theme that fails cannot ship.