Style tokens
Every look in Zvessa comes from a style: a small record of settings called tokens. Screens and blocks never pick a colour, font or size of their own; they ask the style. So changing one token changes every screen at once, and anyone (or their AI) can make a new look without code.
There are three built-in styles, made exactly the way anyone's own style is made:
| Style | id | Feel |
|---|---|---|
| Classic | classic | Clean surfaces, soft corners, gentle shadows. chat-app's classic look. |
| Futuristic | futuristic | Deep background, glowing outlines, a grid with moving coloured lines. |
| Tech | tech | chat-app's futuristic look, value for value: near-black glass, thin lit lines, a quiet grid, Space Grotesk and mono numbers. |
This page lists every token: what it controls and its value in each built-in style. Values are generated from convex/lib/styles.ts, so they match the app.
The five tokens that change the most #
If you only change a few things, change these. Ask the AI ("make the accent green") or set them in /look/changes:
| Token | Example | What you see |
|---|---|---|
look.style | "tech" | The whole look at once. |
colors.accent | "#22c55e" | Buttons, links, the open chat, glows. |
colors.bg | "#0b0d12" | The page behind everything. |
shape.radius | 8 | How round cards and bubbles are. |
type.body | "grotesk" | The font for all words. |
{ "look": { "style": "tech", "changes": { "colors": { "accent": "#22c55e" } } } }
How tokens fit together #
- Groups. Tokens sit in eight groups:
colors,type,shape,space,surface,backdrop,motionandparts. A style only lists what it changes; everything else comes from Classic. - Layers. Lowest first: Classic's base → the style (and what it
extends) → the space'slook.changes→ a page's ownlook→ a person's own look on their device. Each layer has the same shape, so any of them can change any token. - Schemes.
schemes.darkandschemes.light(or any name, likenight) hold the colours that differ between them.colorsholds the ones that don't. - Colour values can be
#rrggbb,#rrggbbaa,white,black,transparent, another colour's name (accent),mix(a, b, 30%)(30% of a, the rest b),alpha(a, 20%)orcontrast(a). Formulas nest. Any new colour name you add (saybrand2) can be used by blocks and mini-apps.
1. Colours #
colors and schemes.<name>. The five columns are the built-in styles in their schemes; "·" means the style doesn't set it (screens fall back as described).
Ground and panels #
| Token | Controls | Classic light | Classic dark | Futuristic dark | Tech dark | Tech light |
|---|---|---|---|---|---|---|
bg | The page behind everything. | #f6f7f9 | #0d0f14 | #06080c | #06080c | #edeceb |
surface | Cards, panes and sheets (Tech: see-through glass). | #ffffff | #171a22 | rgba(34, 211, 238, 0.04) | rgba(13, 19, 27, 0.82) | rgba(245, 245, 244, 0.82) |
raised | Things that sit on a card: menus, their bubbles, popovers. | #ffffff | #1d212b | rgba(34, 211, 238, 0.09) | #121a24 | #fffdf8 |
panel | Tech only: the glass colour that surface (82%) and rowFill (55%) are made from. | · | · | · | #0d131b | #f5f5f4 |
elev | Tech only: sheets, menus and toasts that float over everything. | · | · | · | #0a0f15 | #fffdf8 |
glass | Tech only: header and tab bar fill (bg at 66%, frosted on the web). | · | · | · | rgba(6, 8, 12, 0.66) | rgba(237, 236, 235, 0.8) |
rowFill | Tech only: the faint card behind each chat list row. | · | · | · | rgba(13, 19, 27, 0.55) | rgba(245, 245, 244, 0.55) |
grid | The backdrop grid lines (transparent = no grid). | rgba(0, 0, 0, 0) | rgba(0, 0, 0, 0) | rgba(34, 211, 238, 0.07) | rgba(120, 200, 255, 0.035) | rgba(61, 107, 255, 0.07) |
Text #
| Token | Controls | Classic light | Classic dark | Futuristic dark | Tech dark | Tech light |
|---|---|---|---|---|---|---|
text | Main words. | #0f172a | #eef1f7 | #e6f6ff | #e6edf3 | #1b1d22 |
text2 | Second lines: previews, descriptions. | #545a68 | #abadb3 | #a7b3bb | #b7c2cf | #464b55 |
text3 | Quiet words: times, hints, labels. | #777c87 | #898b91 | #7a848a | #8c9aab | #636a75 |
Lines #
| Token | Controls | Classic light | Classic dark | Futuristic dark | Tech dark | Tech light |
|---|---|---|---|---|---|---|
line | Every thin line: card edges, dividers, outlined chips. | rgba(15, 23, 42, 0.1) | rgba(255, 255, 255, 0.09) | rgba(34, 211, 238, 0.3) | rgba(120, 200, 240, 0.14) | rgba(59, 83, 145, 0.22) |
lineTint | Tech only: the hue lines are made from (chat-app's --fx-line). | · | · | · | #78c8f0 | #3b5391 |
lineStrong | Tech only: a slightly brighter line (their bubbles). | · | · | · | rgba(120, 200, 240, 0.2) | rgba(59, 83, 145, 0.3) |
Accent #
| Token | Controls | Classic light | Classic dark | Futuristic dark | Tech dark | Tech light |
|---|---|---|---|---|---|---|
accent | The space's colour: buttons, links, the open row, glows. | #3d6bff | #6d8dff | #22d3ee | #6d8dff | #3d6bff |
accent2 | A second accent: gradients (Classic's own bubble runs accent → accent2). | #5c65ff | #7979ff | #a78bfa | #8a76ff | #8a76ff |
onAccent | Text on a filled accent. | #ffffff | #ffffff | #111827 | #ffffff | #ffffff |
accentSoft | Tech only: the faint accent fill of selected things. | · | · | · | rgba(109, 141, 255, 0.06) | rgba(61, 107, 255, 0.07) |
accentLine | Tech only: the lit accent outline (buttons, your bubbles). | · | · | · | rgba(109, 141, 255, 0.6) | rgba(61, 107, 255, 0.6) |
Status #
| Token | Controls | Classic light | Classic dark | Futuristic dark | Tech dark | Tech light |
|---|---|---|---|---|---|---|
success | Done, online, applied. | #16a34a | #16a34a | #34d399 | #4fe3a0 | #12804f |
warn | Waiting, needs a look. | #d97706 | #d97706 | #fbbf24 | #f2a35e | #b8620f |
danger | Errors, failed replies, delete. | #dc2626 | #dc2626 | #f87171 | #ff6b6b | #cc3339 |
gold | Coins, prizes, 1st place. | #f59e0b | #f59e0b | #fbbf24 | #f59e0b | #f59e0b |
win | Wins in games. | #12a150 | #12a150 | #34d399 | #4fe3a0 | #4fe3a0 |
Chat #
| Token | Controls | Classic light | Classic dark | Futuristic dark | Tech dark | Tech light |
|---|---|---|---|---|---|---|
bubbleMine | Tech only: fill of your bubbles (Classic uses an accent gradient). | · | · | · | rgba(109, 141, 255, 0.05) | #e0e5f6 |
bubbleTheirs | Tech only: fill of other people's bubbles (Classic uses raised). | · | · | · | rgba(255, 255, 255, 0.02) | rgba(255, 253, 248, 0.7) |
field | Tech only: the message box and search fill. | · | · | · | rgba(255, 255, 255, 0.02) | rgba(255, 253, 248, 0.6) |
note | Tech only: team-only notes. | · | · | · | #1c1810 | #fbf2dc |
noteText | Tech only: words in a note. | · | · | · | #f2c46e | #7a4f00 |
Media #
| Token | Controls | Classic light | Classic dark | Futuristic dark | Tech dark | Tech light |
|---|---|---|---|---|---|---|
media | Behind photos and videos. | #000000 | #000000 | #000000 | #000000 | #000000 |
onMedia | Words over photos and videos. | #ffffff | #ffffff | #ffffff | #ffffff | #ffffff |
2. Text #
type. Fonts are names, never files: system, rounded, serif, mono, and two bundled with the app, grotesk (Space Grotesk) and jetbrains (JetBrains Mono). They load only when a style uses them (about 145 KB together).
| Token | Controls | Classic | Futuristic | Tech |
|---|---|---|---|---|
type.body | Font for all words. | system | system | grotesk |
type.display | Font for titles and headings. | system | mono | grotesk |
type.mono | Font for numbers, times, counts and status lines. | mono | mono | jetbrains |
type.scale | Multiplies every text size (0.75 to 1.5). | 1 | 1 | 1 |
type.bodyWeight | Weight of normal words (400 to 800). | 400 | 400 | 400 |
type.headingWeight | Weight of titles. | 700 | 600 | 700 |
type.headingCase | upper makes titles capitals. | none | upper | none |
type.tracking | Letter spacing of titles, in px. | 0 | 1.5 | 0 |
Text roles (type.roles, from the "Layout and text blocks" work): every piece of text is one of display, title, headline, subtitle, body, callout, caption, label, overline, number, quote, code. Each role can set size, weight, font (body, display, mono or a font name), case, tracking, leading and tone (a colour). A block names a role, never a size. Tech's label and overline are chat-app's small caps line: 10.5 px, mono, uppercase, wide tracking, in text3; its number role is mono.
3. Shape #
shape.
| Token | Controls | Classic | Futuristic | Tech |
|---|---|---|---|---|
shape.radius | Corners of cards, sheets and bubbles (0 to 40). | 14 | 4 | 18 |
shape.radiusSmall | Corners of buttons, fields and chips. | 10 | 2 | 12 |
shape.line | Width of every line (0 to 4). | 1 | 1 | 1 |
shape.marks | Marks on cards: true/corners = small L marks on all four corners; lit = one lit top-left corner (Tech). | False | True | lit |
4. Space #
space.
| Token | Controls | Classic | Futuristic | Tech |
|---|---|---|---|---|
space.density | compact (6 px steps), regular (8), roomy (10). | regular | regular | regular |
5. Surfaces, edges and glow #
surface. How boxes are drawn.
| Token | Controls | Classic | Futuristic | Tech |
|---|---|---|---|---|
surface.treatment | fill (solid), outline (a line, nearly empty inside), glass (see-through), gradient. | fill | outline | glass |
surface.depth | flat, shadow (soft drop shadow) or glow (a light in the accent). | shadow | glow | glow |
surface.edge | Header bottoms and tab bar tops: line, or lit = an accent line that fades out at both ends (chat-app's futuristic headers). | line | line | lit |
surface.glow | How strong glows are, 0 to 1. Under 0.5 a soft halo (Futuristic); 0.5 and up a tight neon edge (Tech). | 0.22 | 0.22 | 1 |
6. Backdrop #
backdrop. The ground behind pages and chats. It never moves while you read, stops when the app is in the background, and turns off when the device asks for less motion.
| Token | Controls | Classic | Futuristic | Tech |
|---|---|---|---|---|
backdrop.kind | plain, grid, dots or gradient. | "plain" | "grid" | "grid" |
backdrop.size | Grid or dot spacing, in px. | 24 | 24 | 30 |
backdrop.beams | A line of light that sweeps down the grid, again and again. | false | true | false |
backdrop.lights | Now and then a short light runs along one grid line, across or down (chat-app's; one about every 20 s). | false | false | true |
backdrop.lines | 1 to 4 colours the grid lines sweep through. | [] | ["#22d3ee", "#a78bfa", "#ff5c9a"] | [] |
backdrop.glow | 0 to 3 colours of soft light that drift behind everything. | [] | ["rgba(34, 211, 238, 0.5)"] | [] |
backdrop.floor | A lit floor of lines at the bottom that moves toward you. | false | false | false |
backdrop.streaks | 0 to 3 thin light streaks that cross now and then. | 0 | 2 | 0 |
7. Motion #
motion.
| Token | Controls | Classic | Futuristic | Tech |
|---|---|---|---|---|
motion.speed | off, calm, normal or snappy. | normal | snappy | normal |
motion.haptics | Taps you feel: off, light or full. | light | light | light |
8. Parts #
parts.<part>. One piece of the screen restyled on its own, on top of surface. Each part can set treatment, depth, radius, bg, text and line (colours or formulas).
| Part | What it is | Without a setting |
|---|---|---|
pane | A large area (a side pane). | surface |
card | Cards and panels. | raised |
button | Main buttons. | filled accent |
input | Text fields. | surface |
bubbleMine | Your chat bubbles. | Classic: accent → accent2 gradient |
bubbleTheirs | Other people's bubbles. | Classic: raised with a faint shadow |
tabbar | The bottom tab bar. | surface |
header | Top bars. | surface |
row | Chat list rows (and HQ, AI and page rows). | bare (no box) |
avatar | Pictures without a photo. | a gradient in the name's colour |
badge | Unread counts. | filled accent |
tile, chip | App tiles and small pills (Layout work). | from surface |
What the built-in styles set:
Futuristic
| Part | treatment | depth | radius | bg | text | line |
|---|---|---|---|---|---|---|
bubbleMine | outline | · | · | rgba(34, 211, 238, 0.08) | #e6f6ff | #22d3ee |
button | outline | · | · | rgba(34, 211, 238, 0.1) | #22d3ee | #22d3ee |
Tech (dark)
| Part | treatment | depth | radius | bg | text | line |
|---|---|---|---|---|---|---|
card | glass | flat | · | rgba(13, 19, 27, 0.82) | · | rgba(120, 200, 240, 0.14) |
pane | glass | flat | · | rgba(13, 19, 27, 0.82) | · | rgba(120, 200, 240, 0.14) |
button | outline | glow | 12 | rgba(109, 141, 255, 0.06) | #6d8dff | rgba(109, 141, 255, 0.6) |
input | outline | flat | 12 | rgba(255, 255, 255, 0.02) | · | rgba(109, 141, 255, 0.28) |
bubbleMine | outline | glow | · | rgba(109, 141, 255, 0.05) | #e6edf3 | rgba(109, 141, 255, 0.6) |
bubbleTheirs | outline | flat | · | rgba(255, 255, 255, 0.02) | #e6edf3 | rgba(120, 200, 240, 0.2) |
header | glass | flat | · | rgba(6, 8, 12, 0.66) | · | rgba(0, 0, 0, 0) |
tabbar | glass | flat | 22 | rgba(10, 15, 21, 0.9) | · | rgba(120, 200, 240, 0.14) |
row | outline | flat | 16 | rgba(13, 19, 27, 0.55) | · | rgba(120, 200, 240, 0.08) |
avatar | outline | glow | · | · | · | · |
badge | outline | glow | · | rgba(109, 141, 255, 0.1) | #6d8dff | rgba(109, 141, 255, 0.65) |
Classic sets no parts.
Examples #
Tech with a green accent. Everything else stays Tech:
{ "look": { "style": "tech", "changes": { "colors": { "accent": "#22c55e" } } } }
A style of your own, made from Tech. List only what changes:
{
"id": "midnight",
"name": "Midnight",
"extends": "tech",
"schemes": { "dark": { "bg": "#05060a", "accent": "#f59e0b" } },
"shape": { "radius": 12 },
"backdrop": { "lights": false }
}
Classic, rounder and roomier, in a serif:
{ "look": { "style": "classic", "changes": { "shape": { "radius": 22 }, "space": { "density": "roomy" }, "type": { "display": "serif" } } } }
A page with its own look (a games page that glows), in /pages/N/look:
{ "schemes": { "dark": { "bg": "#070814" } }, "backdrop": { "kind": "grid", "lines": ["#2dd4bf", "#a78bfa"], "glow": ["alpha(accent, 40%)"], "floor": true } }
For developers #
- Read the resolved style through
src/lib/workspace.tsx:useWorkspace().theme,surface(theme, part),bodyText,headingText,monoText,captionText,glowShadow,litEdges,fontFamily(font, weight). - Chat pieces read
src/kits/talk/look.ts(rows, counts, pills, search) andsrc/kits/talk/chatLook.tsx(bubbles, message box, send button), so every chat in the app matches. MarksandEdgeLineinsrc/components/ui.tsxdraw a card's lit corner and a header's lit line.- Never write a hex value, font or fixed size in a screen; add a token instead, with a value for each built-in style.