Styles
A style decides how everything looks: the dashboard, HQ, every block, the AI chat and mini-apps. Styles are data (convex/lib/styles.ts), never code. Classic and Futuristic are the two built-in styles and are written exactly the way anyone's own style is written, so they are the worked examples. Inspired by chat-app's styles (docs/STYLES.md there), but every setting is open, not only six colours.
What a style holds #
| Setting | What it is | Options |
|---|---|---|
colors | Colours for every scheme | Core names: bg surface raised text text2 text3 line grid accent accent2 onAccent success warn danger. Any other name (gold, win, felt, wheel-1) is allowed for blocks, kits and mini-apps. |
schemes | Named schemes, each overriding colors | light, dark, or any name (night, contrast); up to 8 |
type | Fonts and text | body, display: system, rounded, serif, mono · scale 0.75–1.5 · weights 400–800 · headingCase none/upper · tracking |
shape | Corners and lines | radius, radiusSmall, line width, marks (corner marks on boxes) |
space | Density | compact, regular, roomy (6, 8 or 10 px steps) |
surface | How boxes are drawn | treatment fill/outline/glass/gradient · depth flat/shadow/glow |
backdrop | The ground behind everything (drawn by src/components/Scene.tsx) | plain, grid, dots, gradient · size · beams (moving light) · the lit scene (convex/lib/scene.ts): lines (1–4 colours the grid sweeps through), glow (0–3 drifting lights), floor (a lit floor of lines moving toward you), streaks (0–3 light streaks) |
motion | Feel | speed off/calm/normal/snappy · haptics off/light/full |
parts | Per-part overrides | pane card button input bubbleMine bubbleTheirs tabbar header: treatment, depth, radius, bg, text, line |
extends | Start from another style | a style lists only what it changes |
Colour values (convex/lib/color.ts): #rrggbb, #rrggbbaa, white, black, transparent, another colour's name, mix(a, b, 40%), alpha(a, 20%), contrast(a). They nest, so a style can set three colours and derive the rest. A value that can't resolve falls back to Classic's colour, so a mistake never breaks a screen.
Layers #
Lowest first; each layer is the same shape, so any layer can change anything:
- The platform default (every setting has a value)
- The style, and whatever it extends (
blueprint.look.style, from the built-ins orblueprint.styles) - The space's own changes (
blueprint.look.changes), such as just a new accent - A page's look (
page.look) - Later: a person's own look on their device
The scheme is blueprint.look.scheme: system follows the device, or any scheme the style has.
Rules #
- Screens never write a colour, size or font. They read the resolved style through
src/lib/workspace.tsx(surface,bodyText,headingText,gap,color). A screen that needs something new adds a setting or a colour name here first. - Blocks never hold looks in their props. A different look is a style, a page look or a part override.
- Checked on the server.
checkStyles/checkLayerrefuse unknown settings, values out of range and anything that isn't a colour value, so a style can't fake a screen or run code. - Mini-apps get the style as CSS variables (
--bg,--accent,--gold,--radius…) and aswindow.myaibio.style, so a game matches every style, including ones made after it.
Starters #
During onboarding people pick Classic or Futuristic (src/components/Onboarding.tsx, drawn by StylePreview.tsx); each card is drawn in its own style. HQ → Style switches style and scheme at any time (saved as a version, so it can be undone). Anything else, such as "a warm paper look with a serif font", is asked of the AI, which writes a new style that extends one of these.