Files
stack/docs/design/tokens.json
T
jason.woltjeandClaude Opus 5.5 811e7ba562 docs(design): handoff package for implementing the design
Jason accepted the draft 1 direction on 2026-10-10; the refined Relay
mark stays as a placeholder. Adds IMPLEMENTING.md (gap map against
row 40 and the bus/CLI modules, strings, boundaries, acceptance,
proposed rows for Sage), tokens.json and generated tokens.css using the
webui's existing names, icons.svg, and tools/build-tokens.mjs and
tools/check-design.mjs. Coverage statuses corrected against the code
(digest implemented; mosaic stop is row 41; priority and agent state
not in the bus reads). No packages/ change.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-10 11:22:06 -05:00

815 lines
19 KiB
JSON
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{
"$comment": "Mosaic Stack design tokens, draft 1. Source of truth for web and terminal colour, type and shape. Palette values equal agents/dewey/work/wui/assets/palettes.json. Regenerate tokens.css with: node docs/design/tools/build-tokens.mjs",
"version": "draft-1",
"default": {
"palette": "harbor",
"mode": "system",
"$comment": "Provisional (Jason 2026-10-10 accepted the direction; the default is still open)."
},
"modes": [
"light",
"dim",
"dark"
],
"modeRules": {
"system": "light unless prefers-color-scheme is dark, then dark",
"dim": "only by explicit choice"
},
"color": {
"semantic": {
"canvas": "page background",
"surface": "panels, tables, inspector",
"raised": "selected nav, hover, chips",
"line": "hairlines and table rules",
"border": "control borders that must meet 3:1",
"text": "body text",
"strong": "derived: text mixed 72% with black (light) or 70% with white (dim, dark); headings and emphasis",
"muted": "secondary text, timestamps",
"action": "links, primary buttons, selection",
"onAction": "text on action fills",
"accent": "the PM, decisions, the second voice",
"focus": "focus rings",
"success": "working, pass, fresh",
"warning": "waiting, stale, expiring, outcome unknown",
"danger": "blocking, refused, error, conflict"
}
},
"palettes": [
{
"id": "harbor",
"name": "Harbor",
"theory": "Complementary",
"note": "Clear blue with a restrained copper counterpoint. The warm accent balances cool navigation and gives selected details a second voice.",
"modes": {
"light": {
"canvas": "#f3f5f7",
"surface": "#ffffff",
"raised": "#e6eaef",
"line": "#ced5df",
"border": "#636e7e",
"text": "#434d5b",
"muted": "#5e6978",
"action": "#2266bf",
"onAction": "#ffffff",
"accent": "#8d5e20",
"focus": "#2266bf",
"success": "#287658",
"warning": "#8f5c19",
"danger": "#ba2e26"
},
"dim": {
"canvas": "#242d38",
"surface": "#2e3947",
"raised": "#384556",
"line": "#47576c",
"border": "#a4acb7",
"text": "#d6dbe1",
"muted": "#a9b1bc",
"action": "#8ab4ea",
"onAction": "#10141a",
"accent": "#e1b47a",
"focus": "#8ab4ea",
"success": "#85d5b7",
"warning": "#e7b574",
"danger": "#ea9d99"
},
"dark": {
"canvas": "#12161c",
"surface": "#1c232b",
"raised": "#28323e",
"line": "#384556",
"border": "#a4acb7",
"text": "#b9c1cb",
"muted": "#a4acb7",
"action": "#74a6e7",
"onAction": "#10141a",
"accent": "#e1b47a",
"focus": "#74a6e7",
"success": "#85d5b7",
"warning": "#e7b574",
"danger": "#e37d78"
}
}
},
{
"id": "carmine",
"name": "Carmine",
"theory": "Near-complementary",
"note": "A red-led identity with a cool turquoise counterpoint. Rose-tinted neutrals keep the red from covering every surface.",
"modes": {
"light": {
"canvas": "#f7f3f3",
"surface": "#ffffff",
"raised": "#efe7e8",
"line": "#deced1",
"border": "#7e6367",
"text": "#5e4549",
"muted": "#7b6065",
"action": "#b92740",
"onAction": "#ffffff",
"accent": "#2e706c",
"focus": "#b92740",
"success": "#287658",
"warning": "#8f5c19",
"danger": "#ba2e26"
},
"dim": {
"canvas": "#372528",
"surface": "#462f33",
"raised": "#55393e",
"line": "#6b484e",
"border": "#b7a4a7",
"text": "#ded3d5",
"muted": "#bca9ac",
"action": "#e996a4",
"onAction": "#10141a",
"accent": "#8bd0cb",
"focus": "#e996a4",
"success": "#85d5b7",
"warning": "#e7b574",
"danger": "#e99995"
},
"dark": {
"canvas": "#1b1214",
"surface": "#2b1d1f",
"raised": "#3d292c",
"line": "#55393e",
"border": "#b7a4a7",
"text": "#c9b6b9",
"muted": "#b7a4a7",
"action": "#e2788a",
"onAction": "#10141a",
"accent": "#8bd0cb",
"focus": "#e2788a",
"success": "#85d5b7",
"warning": "#e7b574",
"danger": "#e37d78"
}
}
},
{
"id": "atlantic",
"name": "Atlantic",
"theory": "Analogous",
"note": "Ocean blue and teal sit close on the hue wheel. Their shared cool bias makes a quieter combination than an opposing accent.",
"modes": {
"light": {
"canvas": "#f3f6f7",
"surface": "#ffffff",
"raised": "#e6ecef",
"line": "#cdd9df",
"border": "#63757e",
"text": "#3f4e55",
"muted": "#5c6d75",
"action": "#19719a",
"onAction": "#ffffff",
"accent": "#257467",
"focus": "#19719a",
"success": "#287658",
"warning": "#935f1a",
"danger": "#ba2e26"
},
"dim": {
"canvas": "#243238",
"surface": "#2e3f47",
"raised": "#384d57",
"line": "#46606d",
"border": "#a4b1b7",
"text": "#e2e7e9",
"muted": "#afbbc0",
"action": "#73c3e8",
"onAction": "#10141a",
"accent": "#83d8ca",
"focus": "#73c3e8",
"success": "#85d5b7",
"warning": "#e7b574",
"danger": "#edaaa6"
},
"dark": {
"canvas": "#12191c",
"surface": "#1c272b",
"raised": "#28373e",
"line": "#384d57",
"border": "#a4b1b7",
"text": "#bcc8cd",
"muted": "#a4b1b7",
"action": "#73c3e8",
"onAction": "#10141a",
"accent": "#83d8ca",
"focus": "#73c3e8",
"success": "#85d5b7",
"warning": "#e7b574",
"danger": "#e4817c"
}
}
},
{
"id": "terracotta",
"name": "Terracotta",
"theory": "Complementary",
"note": "Fired-clay orange meets a desaturated steel blue. Warm neutral surfaces connect the palette without needing a beige wash everywhere.",
"modes": {
"light": {
"canvas": "#f7f4f3",
"surface": "#ffffff",
"raised": "#eee9e7",
"line": "#ded3cf",
"border": "#7e6b63",
"text": "#584841",
"muted": "#78665e",
"action": "#a74f2a",
"onAction": "#ffffff",
"accent": "#356f88",
"focus": "#a74f2a",
"success": "#287658",
"warning": "#8f5c19",
"danger": "#ba2e26"
},
"dim": {
"canvas": "#362b26",
"surface": "#453630",
"raised": "#54423b",
"line": "#695349",
"border": "#b7a9a4",
"text": "#e5dfdc",
"muted": "#beb2ac",
"action": "#e2a68d",
"onAction": "#10141a",
"accent": "#89bcd1",
"focus": "#e2a68d",
"success": "#85d5b7",
"warning": "#e7b574",
"danger": "#eba29e"
},
"dark": {
"canvas": "#1b1513",
"surface": "#2a211d",
"raised": "#3c2f2a",
"line": "#54423b",
"border": "#b7a9a4",
"text": "#cbbeb9",
"muted": "#b7a9a4",
"action": "#de9a7c",
"onAction": "#10141a",
"accent": "#89bcd1",
"focus": "#de9a7c",
"success": "#85d5b7",
"warning": "#e7b574",
"danger": "#e37d78"
}
}
},
{
"id": "aubergine",
"name": "Aubergine",
"theory": "Triadic pair",
"note": "Muted plum and ochre sit 120 degrees apart on the hue wheel. The third triadic hue, teal, is left out so the interface has two brand accents rather than three.",
"modes": {
"light": {
"canvas": "#f5f4f6",
"surface": "#ffffff",
"raised": "#ece8ed",
"line": "#d9d2db",
"border": "#78637e",
"text": "#59455e",
"muted": "#75607b",
"action": "#88469b",
"onAction": "#ffffff",
"accent": "#77672c",
"focus": "#88469b",
"success": "#287658",
"warning": "#8f5c19",
"danger": "#ba2e26"
},
"dim": {
"canvas": "#312933",
"surface": "#3e3441",
"raised": "#4c3f50",
"line": "#5f4f63",
"border": "#b3a4b7",
"text": "#e1d9e3",
"muted": "#baacbe",
"action": "#cba4d6",
"onAction": "#10141a",
"accent": "#d3c388",
"focus": "#cba4d6",
"success": "#85d5b7",
"warning": "#e7b574",
"danger": "#ea9d99"
},
"dark": {
"canvas": "#18141a",
"surface": "#262028",
"raised": "#362d39",
"line": "#4c3f50",
"border": "#b3a4b7",
"text": "#c7b9cb",
"muted": "#b3a4b7",
"action": "#bf8ecc",
"onAction": "#10141a",
"accent": "#d3c388",
"focus": "#bf8ecc",
"success": "#85d5b7",
"warning": "#e7b574",
"danger": "#e37d78"
}
}
},
{
"id": "mineral",
"name": "Mineral",
"theory": "Complementary",
"note": "Deep teal and dusty rose oppose each other while keeping saturation restrained. Blue-green tinted layers carry the identity in dark mode.",
"modes": {
"light": {
"canvas": "#f3f6f6",
"surface": "#ffffff",
"raised": "#e8eded",
"line": "#d0dcda",
"border": "#637e7a",
"text": "#3d524f",
"muted": "#586f6c",
"action": "#2a7469",
"onAction": "#ffffff",
"accent": "#9f414f",
"focus": "#2a7469",
"success": "#287658",
"warning": "#935f1a",
"danger": "#ba2e26"
},
"dim": {
"canvas": "#273432",
"surface": "#324340",
"raised": "#3d514e",
"line": "#4d6662",
"border": "#a4b7b4",
"text": "#e5ebea",
"muted": "#b2c2c0",
"action": "#87d4c8",
"onAction": "#10141a",
"accent": "#e0b3ba",
"focus": "#87d4c8",
"success": "#85d5b7",
"warning": "#e7b574",
"danger": "#eeaeaa"
},
"dark": {
"canvas": "#141a19",
"surface": "#1f2927",
"raised": "#2c3a38",
"line": "#3d514e",
"border": "#a4b7b4",
"text": "#b9cbc8",
"muted": "#a4b7b4",
"action": "#87d4c8",
"onAction": "#10141a",
"accent": "#d18f99",
"focus": "#87d4c8",
"success": "#85d5b7",
"warning": "#e7b574",
"danger": "#e58580"
}
}
},
{
"id": "cobalt",
"name": "Cobalt",
"theory": "Complementary",
"note": "A stronger royal blue meets a small amber accent. The high hue separation is controlled by using amber only in secondary details.",
"modes": {
"light": {
"canvas": "#f3f3f7",
"surface": "#ffffff",
"raised": "#e6e8ef",
"line": "#cdd1df",
"border": "#63687e",
"text": "#454a5e",
"muted": "#60657b",
"action": "#1c3bc4",
"onAction": "#ffffff",
"accent": "#79671b",
"focus": "#1c3bc4",
"success": "#277255",
"warning": "#8f5c19",
"danger": "#ba2e26"
},
"dim": {
"canvas": "#242838",
"surface": "#2e3248",
"raised": "#383d57",
"line": "#464d6d",
"border": "#a4a7b7",
"text": "#d0d2dc",
"muted": "#a6aab9",
"action": "#94a5f0",
"onAction": "#10141a",
"accent": "#e1ce7a",
"focus": "#94a5f0",
"success": "#85d5b7",
"warning": "#e7b574",
"danger": "#e89591"
},
"dark": {
"canvas": "#12141c",
"surface": "#1c1f2c",
"raised": "#282c3e",
"line": "#383d57",
"border": "#a4a7b7",
"text": "#b6b9c9",
"muted": "#a4a7b7",
"action": "#798eec",
"onAction": "#10141a",
"accent": "#e1ce7a",
"focus": "#798eec",
"success": "#85d5b7",
"warning": "#e7b574",
"danger": "#e37d78"
}
}
},
{
"id": "rosewood",
"name": "Rosewood",
"theory": "Triadic pair",
"note": "Dusty pink and steel blue occupy two points of a triadic relationship. The third, yellow-green, is omitted to avoid an overly colorful interface.",
"modes": {
"light": {
"canvas": "#f6f3f5",
"surface": "#ffffff",
"raised": "#ede8eb",
"line": "#dcd0d6",
"border": "#7e6371",
"text": "#5e4552",
"muted": "#7b606e",
"action": "#a53b72",
"onAction": "#ffffff",
"accent": "#416c95",
"focus": "#a53b72",
"success": "#287658",
"warning": "#8f5c19",
"danger": "#ba2e26"
},
"dim": {
"canvas": "#34272e",
"surface": "#43323b",
"raised": "#513d48",
"line": "#664d5a",
"border": "#b7a4ae",
"text": "#e1d6db",
"muted": "#beacb5",
"action": "#dc9ebe",
"onAction": "#10141a",
"accent": "#95b3d0",
"focus": "#dc9ebe",
"success": "#85d5b7",
"warning": "#e7b574",
"danger": "#ea9d99"
},
"dark": {
"canvas": "#1a1417",
"surface": "#291f24",
"raised": "#3a2c33",
"line": "#513d48",
"border": "#b7a4ae",
"text": "#cbb9c2",
"muted": "#b7a4ae",
"action": "#d487af",
"onAction": "#10141a",
"accent": "#8eaecd",
"focus": "#d487af",
"success": "#85d5b7",
"warning": "#e7b574",
"danger": "#e37d78"
}
}
},
{
"id": "graphite",
"name": "Graphite",
"theory": "Monochromatic",
"note": "One blue-gray hue uses value and saturation changes instead of a second brand hue. Semantic status colors remain independent.",
"modes": {
"light": {
"canvas": "#f5f5f5",
"surface": "#ffffff",
"raised": "#eaeaeb",
"line": "#d5d6d7",
"border": "#636e7e",
"text": "#434d5b",
"muted": "#5e6978",
"action": "#616975",
"onAction": "#ffffff",
"accent": "#5e6978",
"focus": "#616975",
"success": "#287658",
"warning": "#8f5c19",
"danger": "#ba2e26"
},
"dim": {
"canvas": "#2d2e2f",
"surface": "#393a3c",
"raised": "#454749",
"line": "#57595c",
"border": "#a4abb7",
"text": "#dfe2e7",
"muted": "#afb6c0",
"action": "#b1b6be",
"onAction": "#10141a",
"accent": "#afb6c0",
"focus": "#b1b6be",
"success": "#85d5b7",
"warning": "#e7b574",
"danger": "#eba29e"
},
"dark": {
"canvas": "#161718",
"surface": "#232425",
"raised": "#323334",
"line": "#454749",
"border": "#a4abb7",
"text": "#bcc3cd",
"muted": "#a4abb7",
"action": "#a6acb5",
"onAction": "#10141a",
"accent": "#a4abb7",
"focus": "#a6acb5",
"success": "#85d5b7",
"warning": "#e7b574",
"danger": "#e37d78"
}
}
},
{
"id": "grove",
"name": "Grove",
"theory": "Split-complementary pair",
"note": "Muted forest green meets dusty rose, 30 degrees to one side of its magenta complement. The second split accent is omitted. Low-saturation surfaces keep green from dominating.",
"modes": {
"light": {
"canvas": "#f4f6f5",
"surface": "#ffffff",
"raised": "#e8edea",
"line": "#d2dbd6",
"border": "#637e6e",
"text": "#3d5246",
"muted": "#586f62",
"action": "#377752",
"onAction": "#ffffff",
"accent": "#9c444a",
"focus": "#377752",
"success": "#287658",
"warning": "#935f1a",
"danger": "#ba2e26"
},
"dim": {
"canvas": "#29332d",
"surface": "#34413a",
"raised": "#3f4f46",
"line": "#4f6358",
"border": "#a4b7ac",
"text": "#e2e9e5",
"muted": "#afc0b6",
"action": "#8fcca9",
"onAction": "#10141a",
"accent": "#ddb1b4",
"focus": "#8fcca9",
"success": "#85d5b7",
"warning": "#e7b574",
"danger": "#edaaa6"
},
"dark": {
"canvas": "#141917",
"surface": "#202823",
"raised": "#2d3932",
"line": "#3f4f46",
"border": "#a4b7ac",
"text": "#b9cbc1",
"muted": "#a4b7ac",
"action": "#8fcca9",
"onAction": "#10141a",
"accent": "#cd8e92",
"focus": "#8fcca9",
"success": "#85d5b7",
"warning": "#e7b574",
"danger": "#e58580"
}
}
}
],
"font": {
"sans": {
"family": "Manrope",
"stack": "\"Manrope\", ui-sans-serif, system-ui, -apple-system, \"Segoe UI\", sans-serif",
"weights": [
400,
500,
600,
700,
800
]
},
"mono": {
"family": "JetBrains Mono",
"stack": "\"JetBrains Mono\", ui-monospace, \"SFMono-Regular\", Menlo, Consolas, monospace",
"weights": [
400,
500,
700
],
"use": "ids, refs, actions, refusal codes, commands: anything a person might type or paste"
},
"source": "Self-host the woff2 files: the console's CSP blocks external hosts. packages/webui already serves Manrope 400-700; weight 800 and JetBrains Mono 400/500/700 still need adding (or drop 800 and use 700). The design preview loads both from Google Fonts only because it is a standalone page."
},
"type": {
"page": {
"size": 28,
"weight": 800
},
"section": {
"size": 20,
"weight": 800
},
"question": {
"size": 16,
"weight": 700
},
"body": {
"size": 14,
"weight": 400,
"lineHeight": 1.5
},
"table": {
"size": 13,
"weight": 400,
"cellPadding": [
7,
10
]
},
"label": {
"size": 11,
"weight": 700,
"case": "upper",
"tracking": "0.06em"
},
"mono": {
"size": 12.5,
"weight": 400
},
"numerals": "tabular-nums in any column of digits"
},
"shape": {
"radius": {
"control": 6,
"panel": 10,
"pill": 999,
"kbd": 4,
"table": 8
},
"stroke": {
"hairline": 1
},
"focusRing": {
"width": 2,
"offset": 2
}
},
"space": {
"gutter": 16,
"scale": [
4,
6,
8,
10,
12,
14,
16,
20
],
"$comment": "Values the preview uses; gap 8 is the common sibling gap.",
"gap": 12
},
"layout": {
"console": {
"sideList": 220,
"inspector": {
"min": 300,
"max": 370
},
"breakpoints": {
"inspectorOverlay": 1100,
"singleColumn": 760
}
},
"maxWidth": 1320
},
"icon": {
"grid": 24,
"stroke": 1.75,
"linecap": "round",
"linejoin": "round",
"fill": "none",
"sprite": "docs/design/icons.svg"
},
"terminal": {
"size": {
"design": [
120,
36
],
"minimum": [
80,
24
],
"keysOnlyNavBelow": 100
},
"ansi": [
{
"role": "action",
"ansi": "blue (4)",
"use": "action, selection, links, your messages"
},
{
"role": "accent",
"ansi": "yellow (3)",
"use": "the PM, decisions"
},
{
"role": "success",
"ansi": "green (2)",
"use": "working, pass, fresh"
},
{
"role": "warning",
"ansi": "bright yellow (11)",
"use": "waiting, stale, expiring, outcome unknown"
},
{
"role": "danger",
"ansi": "red (1)",
"use": "blocking, refused, error, conflict"
},
{
"role": "muted",
"ansi": "bright black (8)",
"use": "timestamps, hints, rules"
},
{
"role": "selection",
"ansi": "reverse video",
"use": "selected row"
}
],
"noColor": "NO_COLOR set: no SGR colour; every state still reads from its word and mark; selection keeps reverse video"
},
"status": {
"agent": [
[
"working",
"●"
],
[
"waiting",
"◐"
],
[
"error",
"▲"
],
[
"offline",
"○"
],
[
"idle",
"–"
],
[
"unknown",
"?"
]
],
"decision": [
"routine",
"within-role",
"cross-role",
"gated",
"BLOCKING"
],
"taskMarker": [
"changed in Vikunja",
"not created by the stack",
"conflict",
"missing: moved",
"not-found",
"no-access"
]
},
"mark": {
"status": "placeholder (Jason 2026-10-10: use it for now, revise later)",
"file": "docs/design/brand/relay-refined.svg",
"viewBox": "0 0 16 17",
"fill": "action"
}
}