Skip to content

Theme tokens ​

Every color, font, size, spacing step, shadow, and timing in the app reads a named token. A theme file sets tokens by name, and anything it leaves out keeps its default. The defaults below are what Orion's Classic theme uses. Vibrant, the default theme, sets its own colors over them, but a theme file builds on these.

Names describe the role a value plays, such as card.background, rather than the value itself. Each token is also a CSS custom property, named by swapping the dots for dashes and adding two in front: card.background is --card-background. A theme file uses the name. A value that refers to another token uses the property, as in var(--surface-background).

Names are a contract ​

Token names are a public contract for theme files.

  • New tokens can be added at any time. A theme that doesn't set one gets the default.
  • Renames follow Orion's release stages. Before 0.1.0, a renamed token takes its new name with no alias. From 1.0.0, a renamed token keeps its old name as an alias, in theme files and as a custom property.
  • No token is dropped silently. One is removed only on purpose, and the change that removes it says so.

Color ​

Colors have a light and a dark default. Classic sets both, and a theme can set either.

NameLightDarkUsed for
canvas.background#f3f5f6#0f1619The canvas and the app background
canvas.dots#c3ccd1#26343aGrid dots on the canvas
surface.background#ffffff#172227Menus, panels, and other raised surfaces
card.backgroundvar(--surface-background)var(--surface-background)A card's fill
card.bordervar(--border-default)var(--border-default)A card's outline
text.primary#17242b#e3eaedBody text and icons
text.muted#5d6d75#92a3aaSecondary text and quiet icons
border.default#d3dbdf#2b3a41Dividers and outlines
accent.default#0d6f74#4fc1c4Focus rings, links, and selection
accent.subtle#d8eeee#163a3cTinted backgrounds behind accent content
edge.default#9aa9b0#4c5d65Links between cards
edge.hot#0d6f74#4fc1c4Live and held links
edge.heldcolor-mix(in srgb, var(--edge-hot) 25%, var(--edge-default))color-mix(in srgb, var(--edge-hot) 25%, var(--edge-default))Links held in place by a dependency
edge.stillcolor-mix(in srgb, var(--text-primary) 45%, var(--edge-default))color-mix(in srgb, var(--text-primary) 45%, var(--edge-default))Links out of components, which carry no work
note.background#fbf3d5#2e2a17A note's paper
note.border#d9b94a#8a7428A note's edge and fold
note.text#7a6418#d9c272A note's text
snap.guide#e0457b#ff6f9cAlignment guides while dragging
sticker.edge#fff#fffThe die-cut edge around a sticker
window.close.background#c42b1c#c42b1cThe window's close button on hover
window.close.text#fff#fffThe close button's glyph on hover
companion.body#fff#fffThe star companion's fill
companion.edge#1d1a33transparentThe outline around each of the companion's stars
companion.ink#1d1a33#1a1240The companion's face
companion.halorgb(76 64 160 / 0.18)rgb(255 255 255 / 0.55)The soft light right around the companion's stars
companion.glowrgb(98 80 200 / 0.22)color-mix(in srgb, var(--accent-default) 50%, transparent)The glow around the companion and its tethers
companion.tethercolor-mix(in srgb, var(--companion-edge) 70%, transparent)color-mix(in srgb, var(--companion-body) 70%, transparent)The lines joining the companion's three stars

Status ​

Each status color also carries a shape, so color never has to stand alone. The colorblind status colors in Settings replace these in every theme.

NameLightDarkUsed for
status.todo#5d6d75#92a3aaNot started, and deferred work
status.readyvar(--accent-default)var(--accent-default)Work that can start now
status.active#1f62c9#6ea2f2In progress
status.review#a56300#e2a34aWaiting on review
status.blocked#c0362c#f07a6fWaiting on open work
status.done#2f7d4a#6cc28aFinished

Tint ​

Groups and components in a system diagram can take one of these colors. A group's tint washes its frame and header, and the components inside take it unless they set their own.

NameLightDarkUsed for
tint.teal#0d8a8f#4fc1c4Teal groups and components
tint.blue#2f6fd6#6ea2f2Blue groups and components
tint.purple#7a52cc#a98bf0Purple groups and components
tint.amber#c27a0e#e2a34aAmber groups and components
tint.rose#cc4a6a#f07a95Rose groups and components
tint.green#2f8a4f#6cc28aGreen groups and components
tint.slate#5f6f7a#92a3aaSlate groups and components

Font ​

NameDefaultUsed for
font.ui'Schibsted Grotesk', system-ui, -apple-system, 'Segoe UI', sans-serifInterface text
font.data'JetBrains Mono', ui-monospace, 'SF Mono', Menlo, monospaceMonospace text, such as shortcuts and identifiers

Weight ​

NameDefaultUsed for
weight.regular400Quiet text beside bolder labels
weight.medium500Most labels, buttons, and headings
weight.semibold600Group titles, tooltips, and the title field
weight.bold700The Done stamp, counts, and search matches
weight.extrabold800The companion's sleepy Z's

Text size ​

Each size is named for the role it most often plays, and every role that uses that exact size shares it.

NameDefaultUsed for
text.size.mini8pxSmallest tags
text.size.nano9pxThe Plain skin's card meta and a snooze glyph
text.size.tiny10pxLevel and status badges
text.size.micro10.5pxCard meta and keyboard keys
text.size.caption11pxEdge labels and counts
text.size.detail11.5pxSecondary facts and footers
text.size.small12pxHelper text and image labels
text.size.label12.5pxCard labels and buttons
text.size.body13pxMost controls and settings text
text.size.emphasis13.5pxGroup headings on the canvas
text.size.base14pxThe page's base size
text.size.subheading15pxSettings navigation headings
text.size.input16pxThe command palette's input
text.size.heading17pxSettings section headings and tool icons
text.size.glyph18pxSmall glyph buttons
text.size.glyph-large20pxThe settings close glyph
text.size.sticker28pxSticker wheel items
text.size.sticker-art40pxStickers on the canvas

Line height ​

A bare number multiplies the text size. Like text sizes, each value is shared by every role that uses it.

NameDefaultUsed for
line-height.glyph1Glyphs, badges, and close buttons that sit on one line
line-height.tight1.2A folded group's facts and the Plain skin's notes
line-height.label1.25Card labels, group titles, and component notes
line-height.note1.3Note text and labels in the focus view
line-height.preview1.4The Done stamp and note previews
line-height.base1.45The page's base
line-height.prose1.5Notes and Markdown in the inspector
line-height.poster1.15Trading card titles when zoomed out

Radius ​

NameDefaultUsed for
radius.xs4pxSmall tags and chips
radius.sm6pxButtons and inputs
radius.md8pxMenus and rows
radius.lg12pxLarge panels and images
radius.cardvar(--radius-md)Cards
radius.pill999pxFully rounded tags and counts
radius.round50%Circles
radius.hairline2pxA thin bar
radius.note-corner0 7px 0 3pxA note's folded corner

Border ​

Widths for borders that outline or frame a box, such as a card, a group, or a control.

NameDefaultUsed for
border.width.default1pxCards, panels, menus, rows, and chips
border.width.strong1.5pxGroup frames, drop targets, handles, and card gate marks
border.width.rule2pxQuote bars and the timeline's rail
border.width.stamp2.5pxThe Done stamp's border

Ring ​

Rings sit around or inside a box without changing its size. They mark focus, selection, and status.

NameDefaultUsed for
ring.width.hairline1pxTraced cards, cards ready to merge, and the merge button
ring.width.inset1.5pxThe sticker wheel's current and filling slots
ring.width.default2pxFocus outlines, link targets, a fresh sticker, and a folded group that needs attention
ring.width.selection3pxA selected card and a picked sticker
ring.width.pulse8pxHow far the pulse around active work spreads
ring.offset.default1pxThe gap between a control and its focus outline
ring.offset.wide2pxThe gap around round buttons and selected images
ring.offset.selection3pxThe gap between a selected card and its outline
stripe.width.default3pxThe status stripe down a card's left edge
stripe.width.strong4pxThe stripe on ready, active, and review cards

Focus outlines that have to stay inside a clipped control, such as the window buttons, use the negative of an offset.

Line width ​

Stroke widths for lines drawn on the canvas. A link's dash pattern shows what kind of link it is, so it stays fixed.

NameDefaultUsed for
link.width.default1.3pxLinks between cards
link.width.focus1.5pxLinks in the focus view
link.width.still1.6pxLinks out of components, and related links in the focus view
link.width.held1.7pxLinks held in place by a dependency
link.width.focus-held1.8pxHeld and still links in the focus view
link.width.attention2pxThe line toward work that needs attention
link.width.related2.2pxRelated links, drawn as dots
link.width.traced2.6pxTraced, hovered, and live links in the focus view
link.width.picked2.8pxA picked link
link.width.pulse4pxThe pulse running down a chain closing out
snap.guide.width1pxAlignment guides while dragging

Space ​

Spacing for gaps, padding, and margins follows a 2px rhythm. A step ending in .5, such as space.1.5, sits halfway between its neighbors, for the small nudges that line things up.

NameDefault
space.0.51px
space.12px
space.1.53px
space.24px
space.2.55px
space.36px
space.3.57px
space.48px
space.4.59px
space.510px
space.5.511px
space.612px
space.714px
space.7.515px
space.816px
space.8.518px
space.920px
space.9.522px
space.1024px

Shadow ​

shadow.raised has to read on the theme's background, so Classic gives it a lighter shadow in light mode. The sticker shadows go inside drop-shadow(), so each must be a single shadow with no inset or spread.

NameDefaultUsed for
shadow.raised0 1px 2px light-dark(rgb(23 36 43 / 0.06), rgb(0 0 0 / 0.3)), 0 5px 16px light-dark(rgb(23 36 43 / 0.06), rgb(0 0 0 / 0.25))Cards, panels, menus, and other raised surfaces
shadow.image0 8px 24px #0002Image nodes
shadow.dialog0 14px 50px color-mix(in srgb, var(--text-primary) 20%, transparent)Settings and the command palette
shadow.selection0 0 0 9px color-mix(in srgb, var(--accent-default) 26%, transparent)The halo around a selected card
shadow.lift0 0 0 3px color-mix(in srgb, var(--text-primary) 16%, transparent), 0 14px 28px -10px rgb(0 0 0 / 0.4)The hovered card: a light ring and a deeper shadow
shadow.sticker0 2px 2px rgb(23 36 43 / 0.25)A sticker resting on the canvas
shadow.sticker-held0 9px 7px rgb(23 36 43 / 0.22)A sticker being dragged

Motion ​

Durations and easings for transitions and one-shot animations. When Orion waits for an animation to finish, it reads the token, so a longer value is never cut off. Like text sizes, each exact value is one token, named for the role it most often plays. The Animations setting still decides whether anything moves.

NameDefaultUsed for
motion.duration.stagger16msThe delay between sticker wheel items opening
motion.duration.blink80msThe companion's eyes closing and opening
motion.duration.instant120msTooltips and sticker wheel hovers
motion.duration.quick140msA sticker growing under the pointer
motion.duration.fast150msHandles, hover actions, and border changes
motion.duration.open160msThe sticker wheel opening
motion.duration.fade180msNodes and panels fading in and out
motion.duration.base200msCard, group, and link fades
motion.duration.reveal240msSticker wheel items popping in
motion.duration.hint250msThe companion's hint growing in
motion.duration.camera-focus260msThe camera heading for a card it's focusing
motion.duration.chain300msThe delay between each card past the third hop down a chain closing out
motion.duration.pop340msA far-zoom card popping up
motion.duration.stamp360msThe finish stamp landing
motion.duration.clear420msA finish stamp clearing
motion.duration.camera450msThe camera panning and zooming, such as to fit the canvas
motion.duration.sticker-ring480msThe ring around a fresh sticker
motion.duration.sticker-stamp520msA fresh sticker stamping down
motion.duration.flourish640msThe rings around the last card of a chain closing out
NameDefaultUsed for
motion.easing.standardeaseHover changes
motion.easing.enterease-outThings appearing
motion.easing.exitease-inThings leaving
motion.easing.popcubic-bezier(0.2, 0.9, 0.3, 1.25)Stamps and far-zoom cards, with a bounce
motion.easing.bouncecubic-bezier(0.2, 0.9, 0.3, 1.3)Sticker wheel items, with more bounce
motion.easing.stampcubic-bezier(0.2, 0.9, 0.3, 1.2)A sticker stamping down
motion.easing.springcubic-bezier(0.3, 1.6, 0.5, 1)The companion's hint, with a spring

Looping animations ​

One cycle of each animation that repeats while something is live. Most loops step at 15 frames a second at their default length to keep repaints down, so a longer loop also moves in coarser steps. Loops stop when the canvas is zoomed far out or moving, and when animations are off.

NameDefaultUsed for
motion.loop.twinkle0.5sThe sparkle in the companion's eyes
motion.loop.attention0.6sThe marching line toward work that needs attention
motion.loop.flow0.8sLive links flowing toward the work they lead to
motion.loop.flow-group1.2sLive links into a folded group
motion.loop.sync1.2sThe sync button spinning
motion.loop.check1.6sRunning checks breathing
motion.loop.shimmer2.4sFinished work shimmering until it is closed out
motion.loop.snooze2.4sThe companion's sleepy Z's, each a third of a cycle apart
motion.loop.pulse3.2sThe ring pulsing around active work
motion.loop.spin1.4sThe spinner for running checks on a trading card

Trading cards ​

The trading card skin is always dark, so its colors have one value for both schemes. Each card's art gradient is part of its drawing and stays fixed, as do the sizes on the card, which is drawn at one size and scaled to fit the canvas.

NameLightDarkUsed for
trading.background#120d30#120d30The card's fill, and the scrim under its title
trading.tile#1b1442#1b1442The tile that shows the card's kind
trading.text#f4f0ff#f4f0ffTitles, the kind tile's rim, and focus outlines
trading.text-muted#a39bcc#a39bccBlocker counts on a zoomed-out card
trading.ink#0c0920#0c0920Text on bright badges and fact chips
trading.edgergb(255 255 255 / 0.1)rgb(255 255 255 / 0.1)The hairline around the card
trading.gate#ffd166#ffd166The ring around a gate card
trading.lock#fff#fffThe lock over a blocked card's kind
trading.blockers#3c3370#3c3370The badge counting open blockers
trading.unblocks#18d6c0#18d6c0The badge counting what finishing frees up
trading.note.background#251c57#251c57A note's fill
trading.note.text#d4cdf3#d4cdf3A note's text
NameDefaultUsed for
trading.radius16pxThe card's corners
trading.shadow.card0 18px 40px rgb(0 0 0 / 0.45)The shadow under a card
trading.shadow.badge0 4px 12px rgb(12 9 32 / 0.5)The shadow under the status badge
trading.shadow.tile0 5px 0 rgb(12 9 32 / 0.45)The hard shadow under the kind tile

Not tokens ​

These stay fixed, since changing them would change what something means or how the app is laid out rather than how it looks:

  • Layout sizes, such as widths, positions, and the room kept beside badges and buttons.
  • A link's dash pattern, which tells held, related, and component links apart.
  • The strokes inside icons and the companion's face, which are part of the drawing.
  • The canvas dot grid's pitch and size.
  • The trading card's art gradients and dot screen, and the sizes on the card.

Sounds will get their own tokens with the sound layer.