feat(ui,api,telegram): shared conversation panel for obsidian and /admin/panel, bind materializes a window, inbox survives link previews

This commit is contained in:
hh
2026-08-29 18:30:33 +02:00
parent a989d2909d
commit 9efff6e814
58 changed files with 2858 additions and 499 deletions
+489 -46
View File
@@ -1,54 +1,452 @@
{
"schemaVersion": 2,
"generatedAt": "2026-08-28T00:00:00Z",
"generatedAt": "2026-08-29T00:00:00Z",
"title": "Design System: Beaver admin",
"extensions": {
"colorMeta": {
"primary": { "role": "primary", "displayName": "Mulberry", "canonical": "oklch(0.47 0.13 340)", "dark": "#7c3871", "tonalRamp": ["oklch(0.15 0.13 340)", "oklch(0.26 0.13 340)", "oklch(0.37 0.13 340)", "oklch(0.47 0.13 340)", "oklch(0.58 0.13 340)", "oklch(0.70 0.13 340)", "oklch(0.83 0.13 340)", "oklch(0.95 0.13 340)"] },
"signal": { "role": "primary", "displayName": "Orchid Signal", "canonical": "oklch(0.48 0.21 342)", "dark": "#ff82f3", "tonalRamp": ["oklch(0.15 0.21 342)", "oklch(0.26 0.21 342)", "oklch(0.37 0.21 342)", "oklch(0.48 0.21 342)", "oklch(0.60 0.21 342)", "oklch(0.72 0.21 342)", "oklch(0.84 0.21 342)", "oklch(0.95 0.21 342)"] },
"ring": { "role": "primary", "displayName": "Focus Ring", "canonical": "oklch(0.55 0.2 342)", "dark": "#ff82f3", "tonalRamp": ["oklch(0.15 0.2 342)", "oklch(0.26 0.2 342)", "oklch(0.38 0.2 342)", "oklch(0.55 0.2 342)", "oklch(0.64 0.2 342)", "oklch(0.74 0.2 342)", "oklch(0.85 0.2 342)", "oklch(0.95 0.2 342)"] },
"status-reply": { "role": "secondary", "displayName": "Branch Blue", "canonical": "oklch(0.55 0.14 235)", "dark": "oklch(0.72 0.13 235)", "tonalRamp": ["oklch(0.15 0.14 235)", "oklch(0.26 0.14 235)", "oklch(0.40 0.14 235)", "oklch(0.55 0.14 235)", "oklch(0.65 0.14 235)", "oklch(0.75 0.14 235)", "oklch(0.85 0.14 235)", "oklch(0.95 0.14 235)"] },
"status-meeting": { "role": "secondary", "displayName": "Deep Violet", "canonical": "oklch(0.5 0.2 300)", "dark": "oklch(0.72 0.16 300)", "tonalRamp": ["oklch(0.15 0.2 300)", "oklch(0.26 0.2 300)", "oklch(0.38 0.2 300)", "oklch(0.50 0.2 300)", "oklch(0.62 0.2 300)", "oklch(0.74 0.2 300)", "oklch(0.85 0.2 300)", "oklch(0.95 0.2 300)"] },
"status-work": { "role": "secondary", "displayName": "Job Teal", "canonical": "oklch(0.55 0.13 195)", "dark": "oklch(0.75 0.12 195)", "tonalRamp": ["oklch(0.15 0.13 195)", "oklch(0.26 0.13 195)", "oklch(0.40 0.13 195)", "oklch(0.55 0.13 195)", "oklch(0.65 0.13 195)", "oklch(0.75 0.13 195)", "oklch(0.85 0.13 195)", "oklch(0.95 0.13 195)"] },
"status-skip": { "role": "secondary", "displayName": "Fork Grey", "canonical": "oklch(0.5 0.04 340)", "dark": "#a989a3", "tonalRamp": ["oklch(0.15 0.04 340)", "oklch(0.26 0.04 340)", "oklch(0.38 0.04 340)", "oklch(0.50 0.04 340)", "oklch(0.62 0.04 340)", "oklch(0.74 0.04 340)", "oklch(0.85 0.04 340)", "oklch(0.95 0.04 340)"] },
"status-done": { "role": "tertiary", "displayName": "OK Green", "canonical": "oklch(0.55 0.14 155)", "dark": "oklch(0.74 0.14 155)", "tonalRamp": ["oklch(0.15 0.14 155)", "oklch(0.26 0.14 155)", "oklch(0.40 0.14 155)", "oklch(0.55 0.14 155)", "oklch(0.65 0.14 155)", "oklch(0.75 0.14 155)", "oklch(0.85 0.14 155)", "oklch(0.95 0.14 155)"] },
"warn": { "role": "tertiary", "displayName": "Warn Amber", "canonical": "oklch(0.55 0.13 75)", "dark": "oklch(0.8 0.13 75)", "tonalRamp": ["oklch(0.15 0.13 75)", "oklch(0.26 0.13 75)", "oklch(0.40 0.13 75)", "oklch(0.55 0.13 75)", "oklch(0.65 0.13 75)", "oklch(0.75 0.13 75)", "oklch(0.85 0.13 75)", "oklch(0.95 0.13 75)"] },
"note": { "role": "tertiary", "displayName": "Inject Amber", "canonical": "oklch(0.52 0.13 78)", "dark": "oklch(0.84 0.14 88)", "tonalRamp": ["oklch(0.15 0.13 78)", "oklch(0.26 0.13 78)", "oklch(0.40 0.13 78)", "oklch(0.52 0.13 78)", "oklch(0.64 0.13 78)", "oklch(0.75 0.13 78)", "oklch(0.85 0.13 78)", "oklch(0.95 0.13 78)"] },
"destructive": { "role": "tertiary", "displayName": "Error Red", "canonical": "oklch(0.58 0.22 25)", "dark": "oklch(0.62 0.2 25)", "tonalRamp": ["oklch(0.15 0.22 25)", "oklch(0.26 0.22 25)", "oklch(0.40 0.22 25)", "oklch(0.58 0.22 25)", "oklch(0.66 0.22 25)", "oklch(0.75 0.22 25)", "oklch(0.85 0.22 25)", "oklch(0.95 0.22 25)"] },
"background": { "role": "neutral", "displayName": "Blush Paper", "canonical": "oklch(0.99 0.004 340)", "dark": "#22111e", "tonalRamp": ["oklch(0.15 0.004 340)", "oklch(0.26 0.004 340)", "oklch(0.40 0.004 340)", "oklch(0.55 0.004 340)", "oklch(0.70 0.004 340)", "oklch(0.85 0.004 340)", "oklch(0.95 0.004 340)", "oklch(0.99 0.004 340)"] },
"foreground": { "role": "neutral", "displayName": "Plum Ink", "canonical": "oklch(0.24 0.03 340)", "dark": "#f5f5f5", "tonalRamp": ["oklch(0.15 0.03 340)", "oklch(0.24 0.03 340)", "oklch(0.38 0.03 340)", "oklch(0.50 0.03 340)", "oklch(0.62 0.03 340)", "oklch(0.75 0.03 340)", "oklch(0.87 0.03 340)", "oklch(0.95 0.03 340)"] },
"sidebar": { "role": "neutral", "displayName": "Sidebar Layer", "canonical": "oklch(0.975 0.01 340)", "dark": "#2c1b29", "tonalRamp": ["oklch(0.15 0.01 340)", "oklch(0.26 0.01 340)", "oklch(0.40 0.01 340)", "oklch(0.55 0.01 340)", "oklch(0.70 0.01 340)", "oklch(0.85 0.01 340)", "oklch(0.94 0.01 340)", "oklch(0.975 0.01 340)"] },
"sidebar-accent": { "role": "neutral", "displayName": "Sidebar Accent", "canonical": "oklch(0.94 0.016 340)", "dark": "#341d2f", "tonalRamp": ["oklch(0.15 0.016 340)", "oklch(0.26 0.016 340)", "oklch(0.40 0.016 340)", "oklch(0.55 0.016 340)", "oklch(0.70 0.016 340)", "oklch(0.85 0.016 340)", "oklch(0.94 0.016 340)", "oklch(0.98 0.016 340)"] },
"muted": { "role": "neutral", "displayName": "Muted", "canonical": "oklch(0.96 0.012 340)", "dark": "#40283a", "tonalRamp": ["oklch(0.15 0.012 340)", "oklch(0.26 0.012 340)", "oklch(0.40 0.012 340)", "oklch(0.55 0.012 340)", "oklch(0.70 0.012 340)", "oklch(0.85 0.012 340)", "oklch(0.96 0.012 340)", "oklch(0.99 0.012 340)"] },
"muted-foreground": { "role": "neutral", "displayName": "Muted Ink", "canonical": "oklch(0.5 0.04 340)", "dark": "#a989a3", "tonalRamp": ["oklch(0.15 0.04 340)", "oklch(0.26 0.04 340)", "oklch(0.38 0.04 340)", "oklch(0.50 0.04 340)", "oklch(0.62 0.04 340)", "oklch(0.74 0.04 340)", "oklch(0.85 0.04 340)", "oklch(0.95 0.04 340)"] },
"icon": { "role": "neutral", "displayName": "Icon", "canonical": "oklch(0.55 0.03 340)", "dark": "#877384", "tonalRamp": ["oklch(0.15 0.03 340)", "oklch(0.26 0.03 340)", "oklch(0.40 0.03 340)", "oklch(0.55 0.03 340)", "oklch(0.65 0.03 340)", "oklch(0.75 0.03 340)", "oklch(0.85 0.03 340)", "oklch(0.95 0.03 340)"] },
"border": { "role": "neutral", "displayName": "Hairline", "canonical": "oklch(0.9 0.02 340)", "dark": "oklch(0.92 0.04 340 / 10%)", "tonalRamp": ["oklch(0.15 0.02 340)", "oklch(0.26 0.02 340)", "oklch(0.40 0.02 340)", "oklch(0.55 0.02 340)", "oklch(0.70 0.02 340)", "oklch(0.80 0.02 340)", "oklch(0.90 0.02 340)", "oklch(0.97 0.02 340)"] }
"primary": {
"role": "primary",
"displayName": "Mulberry",
"canonical": "oklch(0.47 0.13 340)",
"dark": "#7c3871",
"tonalRamp": [
"oklch(0.15 0.13 340)",
"oklch(0.26 0.13 340)",
"oklch(0.37 0.13 340)",
"oklch(0.47 0.13 340)",
"oklch(0.58 0.13 340)",
"oklch(0.70 0.13 340)",
"oklch(0.83 0.13 340)",
"oklch(0.95 0.13 340)"
]
},
"signal": {
"role": "primary",
"displayName": "Orchid Signal",
"canonical": "oklch(0.48 0.21 342)",
"dark": "#ff82f3",
"tonalRamp": [
"oklch(0.15 0.21 342)",
"oklch(0.26 0.21 342)",
"oklch(0.37 0.21 342)",
"oklch(0.48 0.21 342)",
"oklch(0.60 0.21 342)",
"oklch(0.72 0.21 342)",
"oklch(0.84 0.21 342)",
"oklch(0.95 0.21 342)"
]
},
"ring": {
"role": "primary",
"displayName": "Focus Ring",
"canonical": "oklch(0.55 0.2 342)",
"dark": "#ff82f3",
"tonalRamp": [
"oklch(0.15 0.2 342)",
"oklch(0.26 0.2 342)",
"oklch(0.38 0.2 342)",
"oklch(0.55 0.2 342)",
"oklch(0.64 0.2 342)",
"oklch(0.74 0.2 342)",
"oklch(0.85 0.2 342)",
"oklch(0.95 0.2 342)"
]
},
"status-reply": {
"role": "secondary",
"displayName": "Branch Blue",
"canonical": "oklch(0.55 0.14 235)",
"dark": "oklch(0.72 0.13 235)",
"tonalRamp": [
"oklch(0.15 0.14 235)",
"oklch(0.26 0.14 235)",
"oklch(0.40 0.14 235)",
"oklch(0.55 0.14 235)",
"oklch(0.65 0.14 235)",
"oklch(0.75 0.14 235)",
"oklch(0.85 0.14 235)",
"oklch(0.95 0.14 235)"
]
},
"status-meeting": {
"role": "secondary",
"displayName": "Deep Violet",
"canonical": "oklch(0.5 0.2 300)",
"dark": "oklch(0.72 0.16 300)",
"tonalRamp": [
"oklch(0.15 0.2 300)",
"oklch(0.26 0.2 300)",
"oklch(0.38 0.2 300)",
"oklch(0.50 0.2 300)",
"oklch(0.62 0.2 300)",
"oklch(0.74 0.2 300)",
"oklch(0.85 0.2 300)",
"oklch(0.95 0.2 300)"
]
},
"status-work": {
"role": "secondary",
"displayName": "Job Teal",
"canonical": "oklch(0.55 0.13 195)",
"dark": "oklch(0.75 0.12 195)",
"tonalRamp": [
"oklch(0.15 0.13 195)",
"oklch(0.26 0.13 195)",
"oklch(0.40 0.13 195)",
"oklch(0.55 0.13 195)",
"oklch(0.65 0.13 195)",
"oklch(0.75 0.13 195)",
"oklch(0.85 0.13 195)",
"oklch(0.95 0.13 195)"
]
},
"status-skip": {
"role": "secondary",
"displayName": "Fork Grey",
"canonical": "oklch(0.5 0.04 340)",
"dark": "#a989a3",
"tonalRamp": [
"oklch(0.15 0.04 340)",
"oklch(0.26 0.04 340)",
"oklch(0.38 0.04 340)",
"oklch(0.50 0.04 340)",
"oklch(0.62 0.04 340)",
"oklch(0.74 0.04 340)",
"oklch(0.85 0.04 340)",
"oklch(0.95 0.04 340)"
]
},
"status-done": {
"role": "tertiary",
"displayName": "OK Green",
"canonical": "oklch(0.55 0.14 155)",
"dark": "oklch(0.74 0.14 155)",
"tonalRamp": [
"oklch(0.15 0.14 155)",
"oklch(0.26 0.14 155)",
"oklch(0.40 0.14 155)",
"oklch(0.55 0.14 155)",
"oklch(0.65 0.14 155)",
"oklch(0.75 0.14 155)",
"oklch(0.85 0.14 155)",
"oklch(0.95 0.14 155)"
]
},
"warn": {
"role": "tertiary",
"displayName": "Warn Amber",
"canonical": "oklch(0.55 0.13 75)",
"dark": "oklch(0.8 0.13 75)",
"tonalRamp": [
"oklch(0.15 0.13 75)",
"oklch(0.26 0.13 75)",
"oklch(0.40 0.13 75)",
"oklch(0.55 0.13 75)",
"oklch(0.65 0.13 75)",
"oklch(0.75 0.13 75)",
"oklch(0.85 0.13 75)",
"oklch(0.95 0.13 75)"
]
},
"note": {
"role": "tertiary",
"displayName": "Inject Amber",
"canonical": "oklch(0.52 0.13 78)",
"dark": "oklch(0.84 0.14 88)",
"tonalRamp": [
"oklch(0.15 0.13 78)",
"oklch(0.26 0.13 78)",
"oklch(0.40 0.13 78)",
"oklch(0.52 0.13 78)",
"oklch(0.64 0.13 78)",
"oklch(0.75 0.13 78)",
"oklch(0.85 0.13 78)",
"oklch(0.95 0.13 78)"
]
},
"destructive": {
"role": "tertiary",
"displayName": "Error Red",
"canonical": "oklch(0.58 0.22 25)",
"dark": "oklch(0.62 0.2 25)",
"tonalRamp": [
"oklch(0.15 0.22 25)",
"oklch(0.26 0.22 25)",
"oklch(0.40 0.22 25)",
"oklch(0.58 0.22 25)",
"oklch(0.66 0.22 25)",
"oklch(0.75 0.22 25)",
"oklch(0.85 0.22 25)",
"oklch(0.95 0.22 25)"
]
},
"background": {
"role": "neutral",
"displayName": "Blush Paper",
"canonical": "oklch(0.99 0.004 340)",
"dark": "#22111e",
"tonalRamp": [
"oklch(0.15 0.004 340)",
"oklch(0.26 0.004 340)",
"oklch(0.40 0.004 340)",
"oklch(0.55 0.004 340)",
"oklch(0.70 0.004 340)",
"oklch(0.85 0.004 340)",
"oklch(0.95 0.004 340)",
"oklch(0.99 0.004 340)"
]
},
"foreground": {
"role": "neutral",
"displayName": "Plum Ink",
"canonical": "oklch(0.24 0.03 340)",
"dark": "#f5f5f5",
"tonalRamp": [
"oklch(0.15 0.03 340)",
"oklch(0.24 0.03 340)",
"oklch(0.38 0.03 340)",
"oklch(0.50 0.03 340)",
"oklch(0.62 0.03 340)",
"oklch(0.75 0.03 340)",
"oklch(0.87 0.03 340)",
"oklch(0.95 0.03 340)"
]
},
"sidebar": {
"role": "neutral",
"displayName": "Sidebar Layer",
"canonical": "oklch(0.975 0.01 340)",
"dark": "#2c1b29",
"tonalRamp": [
"oklch(0.15 0.01 340)",
"oklch(0.26 0.01 340)",
"oklch(0.40 0.01 340)",
"oklch(0.55 0.01 340)",
"oklch(0.70 0.01 340)",
"oklch(0.85 0.01 340)",
"oklch(0.94 0.01 340)",
"oklch(0.975 0.01 340)"
]
},
"sidebar-accent": {
"role": "neutral",
"displayName": "Sidebar Accent",
"canonical": "oklch(0.94 0.016 340)",
"dark": "#341d2f",
"tonalRamp": [
"oklch(0.15 0.016 340)",
"oklch(0.26 0.016 340)",
"oklch(0.40 0.016 340)",
"oklch(0.55 0.016 340)",
"oklch(0.70 0.016 340)",
"oklch(0.85 0.016 340)",
"oklch(0.94 0.016 340)",
"oklch(0.98 0.016 340)"
]
},
"muted": {
"role": "neutral",
"displayName": "Muted",
"canonical": "oklch(0.96 0.012 340)",
"dark": "#40283a",
"tonalRamp": [
"oklch(0.15 0.012 340)",
"oklch(0.26 0.012 340)",
"oklch(0.40 0.012 340)",
"oklch(0.55 0.012 340)",
"oklch(0.70 0.012 340)",
"oklch(0.85 0.012 340)",
"oklch(0.96 0.012 340)",
"oklch(0.99 0.012 340)"
]
},
"muted-foreground": {
"role": "neutral",
"displayName": "Muted Ink",
"canonical": "oklch(0.5 0.04 340)",
"dark": "#a989a3",
"tonalRamp": [
"oklch(0.15 0.04 340)",
"oklch(0.26 0.04 340)",
"oklch(0.38 0.04 340)",
"oklch(0.50 0.04 340)",
"oklch(0.62 0.04 340)",
"oklch(0.74 0.04 340)",
"oklch(0.85 0.04 340)",
"oklch(0.95 0.04 340)"
]
},
"icon": {
"role": "neutral",
"displayName": "Icon",
"canonical": "oklch(0.55 0.03 340)",
"dark": "#877384",
"tonalRamp": [
"oklch(0.15 0.03 340)",
"oklch(0.26 0.03 340)",
"oklch(0.40 0.03 340)",
"oklch(0.55 0.03 340)",
"oklch(0.65 0.03 340)",
"oklch(0.75 0.03 340)",
"oklch(0.85 0.03 340)",
"oklch(0.95 0.03 340)"
]
},
"border": {
"role": "neutral",
"displayName": "Hairline",
"canonical": "oklch(0.9 0.02 340)",
"dark": "oklch(0.92 0.04 340 / 10%)",
"tonalRamp": [
"oklch(0.15 0.02 340)",
"oklch(0.26 0.02 340)",
"oklch(0.40 0.02 340)",
"oklch(0.55 0.02 340)",
"oklch(0.70 0.02 340)",
"oklch(0.80 0.02 340)",
"oklch(0.90 0.02 340)",
"oklch(0.97 0.02 340)"
]
}
},
"typographyMeta": {
"headline": { "displayName": "Headline", "purpose": "Page titles in page-header.svelte; the sidebar wordmark shares weight and tracking." },
"title": { "displayName": "Title", "purpose": "Thread title, stat values (tabular), memory file path." },
"body": { "displayName": "Body", "purpose": "Rows, cells, bubbles, dialogs; primary row text at 500." },
"label": { "displayName": "Label", "purpose": "Uppercase section headings; same size without uppercase for table headers, badges, pills, meta lines." },
"mono": { "displayName": "Mono", "purpose": "Raw JSON, tool input/result blocks, event tape, ids, the plaintext token." }
"headline": {
"displayName": "Headline",
"purpose": "Page titles in page-header.svelte; the sidebar wordmark shares weight and tracking."
},
"title": {
"displayName": "Title",
"purpose": "Thread title, stat values (tabular), memory file path."
},
"body": {
"displayName": "Body",
"purpose": "Rows, cells, bubbles, dialogs; primary row text at 500."
},
"label": {
"displayName": "Label",
"purpose": "Uppercase section headings; same size without uppercase for table headers, badges, pills, meta lines."
},
"mono": {
"displayName": "Mono",
"purpose": "Raw JSON, tool input/result blocks, event tape, ids, the plaintext token."
}
},
"shadows": [
{ "name": "login-lift", "value": "0 8px 24px -12px rgb(0 0 0 / 0.25)", "purpose": "The sign-in card only (routes/login/+page.svelte). The single application-layer shadow." },
{ "name": "popover", "value": "shadow-xl plus ring-1 ring-foreground/5 (10% dark)", "purpose": "Luma dialogs, sheets, menus, selects. Overlay surfaces only." }
{
"name": "login-lift",
"value": "0 8px 24px -12px rgb(0 0 0 / 0.25)",
"purpose": "The sign-in card only (routes/login/+page.svelte). The single application-layer shadow."
},
{
"name": "popover",
"value": "shadow-xl plus ring-1 ring-foreground/5 (10% dark)",
"purpose": "Luma dialogs, sheets, menus, selects. Overlay surfaces only."
}
],
"motion": [
{ "name": "pulse-dot", "value": "pulse-dot 1.6s cubic-bezier(0.4, 0, 0.6, 1) infinite", "purpose": "Signal-colored halo (0 to 5px, 55% to 0% alpha) on live and running dots." },
{ "name": "rise", "value": "rise 220ms cubic-bezier(0.16, 1, 0.3, 1) both", "purpose": "Opacity 0 to 1 and translateY 3px to 0 when a turn card lands in the activity feed." },
{ "name": "row-hover", "value": "background-color 150ms ease-out", "purpose": "Ink wash at 4% on interactive rows." },
{ "name": "chevron", "value": "transform 150ms", "purpose": "90 degree rotation of expand chevrons in tool nodes, raw entries, memory tree." },
{ "name": "bar-fill", "value": "width 300ms", "purpose": "Utilization bar fill in limit-bar.svelte." },
{ "name": "dialog", "value": "fade-in and zoom-in-95 over 100ms", "purpose": "Luma dialog open and close." },
{ "name": "reduced-motion", "value": "transition-duration and animation-duration 0.01ms under prefers-reduced-motion", "purpose": "Global kill switch in layout.css." }
{
"name": "pulse-dot",
"value": "pulse-dot 1.6s cubic-bezier(0.4, 0, 0.6, 1) infinite",
"purpose": "Signal-colored halo (0 to 5px, 55% to 0% alpha) on live and running dots."
},
{
"name": "rise",
"value": "rise 220ms cubic-bezier(0.16, 1, 0.3, 1) both",
"purpose": "Opacity 0 to 1 and translateY 3px to 0 when a turn card lands in the activity feed."
},
{
"name": "row-hover",
"value": "background-color 150ms ease-out",
"purpose": "Ink wash at 4% on interactive rows."
},
{
"name": "chevron",
"value": "transform 150ms",
"purpose": "90 degree rotation of expand chevrons in tool nodes, raw entries, memory tree."
},
{
"name": "bar-fill",
"value": "width 300ms",
"purpose": "Utilization bar fill in limit-bar.svelte."
},
{
"name": "dialog",
"value": "fade-in and zoom-in-95 over 100ms",
"purpose": "Luma dialog open and close."
},
{
"name": "reduced-motion",
"value": "transition-duration and animation-duration 0.01ms under prefers-reduced-motion",
"purpose": "Global kill switch in layout.css."
}
],
"breakpoints": [
{ "name": "sm", "value": "640px", "purpose": "Sidebar replaces bottom nav; header padding 24px; hidden row columns return." },
{ "name": "md", "value": "768px", "purpose": "Memory tree and file split side by side." },
{ "name": "lg", "value": "1024px", "purpose": "Thread meta rail (18rem) and two-column dashboard sections." }
]
{
"name": "sm",
"value": "640px",
"purpose": "Sidebar replaces bottom nav; header padding 24px; hidden row columns return."
},
{
"name": "md",
"value": "768px",
"purpose": "Memory tree and file split side by side."
},
{
"name": "lg",
"value": "1024px",
"purpose": "Thread meta rail (18rem) and two-column dashboard sections."
},
{
"name": "panel-rail",
"value": "768px",
"purpose": "Panel container width, not viewport: below it the switcher bar names the thread, from it the 18rem conversation rail shows."
}
],
"obsidian": {
"root": ".beaver-root",
"source": "beaver-plugin-obsidian/src/tailwind.css",
"aliases": {
"background": "--background-primary",
"card": "--background-primary-alt",
"popover": "--background-secondary",
"sidebar": "--background-secondary",
"foreground": "--text-normal",
"muted-foreground": "--text-muted",
"icon": "--text-muted",
"status-skip": "--text-faint",
"border": "--background-modifier-border",
"input": "--background-modifier-border",
"muted": "--background-modifier-hover",
"secondary": "--background-modifier-hover",
"accent": "--background-modifier-hover",
"sidebar-accent": "--background-modifier-hover",
"primary": "--color-accent",
"signal": "--color-accent",
"ring": "--color-accent",
"status-new": "--color-accent",
"primary-foreground": "--text-on-accent",
"link": "--link-color, --text-accent",
"destructive": "--text-error",
"font-sans": "--font-interface",
"font-mono": "--font-monospace"
},
"radii": {
"button, select-trigger": "--button-radius",
"input, tabs-trigger, menu items": "--input-radius",
"tabs-list, skeleton, dialog, popover, menus": "--radius-m (8px)",
"rows and notes": "--radius 0.45rem"
},
"overlays": {
"border": "1px var(--border)",
"shadow": "var(--shadow-s)",
"menuBackground": "var(--popover), opaque, no backdrop",
"portal": ".beaver-root.beaver-portal on body at --layer-menu (65)"
},
"tabs": {
"list": "color-mix(in oklab, var(--text-normal) 6%, transparent)",
"active": "color-mix(in oklab, var(--text-normal) 14%, transparent)"
}
}
},
"components": [
{
@@ -153,12 +551,51 @@
"Light and dark modes, both tinted toward hue 340; dark borders are 10% alpha overlays"
],
"rules": [
{ "name": "The Pink Ration Rule", "body": "signal marks live state (pulsing dots, running rows, busy sessions, the running count) and selection (active mobile nav, master kind). It never decorates a heading, a button, or a static surface. Hover is a 4% ink wash, not pink.", "section": "colors" },
{ "name": "The Twelve Percent Rule", "body": "Every colored chip is its hue at 12% alpha behind full-strength text of the same hue (kind-badge.svelte, sidebar running count). Solid colored chips do not exist.", "section": "colors" },
{ "name": "The Two Layers Rule", "body": "Navigation and rails sit on sidebar (or sidebar/50); content sits on background. There is no third surface color; depth beyond that is a hairline.", "section": "colors" },
{ "name": "The Tabular Rule", "body": "Every number - durations, token counts, money, percentages, timestamps, ids, byte sizes - carries the tabular utility (font-variant-numeric: tabular-nums, layout.css). Numeric table columns are right-aligned.", "section": "typography" },
{ "name": "The One Heading Rule", "body": "A page has one headline (the header) and any number of uppercase 12px section labels; there is no intermediate heading size. Section labels are h2 elements, not decorative kickers.", "section": "typography" },
{ "name": "The Flat Ledger Rule", "body": "Nothing inside the main column casts a shadow. Overlays (dialog, sheet, menu) and the login card are the only lifted surfaces.", "section": "elevation" }
{
"name": "The Pink Ration Rule",
"body": "signal marks live state (pulsing dots, running rows, busy sessions, the running count) and selection (active mobile nav, master kind). It never decorates a heading, a button, or a static surface. Hover is a 4% ink wash, not pink.",
"section": "colors"
},
{
"name": "The Twelve Percent Rule",
"body": "Every colored chip is its hue at 12% alpha behind full-strength text of the same hue (kind-badge.svelte, sidebar running count). Solid colored chips do not exist.",
"section": "colors"
},
{
"name": "The Two Layers Rule",
"body": "Navigation and rails sit on sidebar (or sidebar/50); content sits on background. There is no third surface color; depth beyond that is a hairline.",
"section": "colors"
},
{
"name": "The Tabular Rule",
"body": "Every number - durations, token counts, money, percentages, timestamps, ids, byte sizes - carries the tabular utility (font-variant-numeric: tabular-nums, layout.css). Numeric table columns are right-aligned.",
"section": "typography"
},
{
"name": "The One Heading Rule",
"body": "A page has one headline (the header) and any number of uppercase 12px section labels; there is no intermediate heading size. Section labels are h2 elements, not decorative kickers.",
"section": "typography"
},
{
"name": "The Flat Ledger Rule",
"body": "Nothing inside the main column casts a shadow. Overlays (dialog, sheet, menu) and the login card are the only lifted surfaces.",
"section": "elevation"
},
{
"name": "The Host Accent Rule",
"body": "Inside Obsidian signal and primary are one variable. Live dots, running rows, the running count, the selected row, the primary button and the focus ring all take the user's accent; the Pink Ration Rule becomes an accent ration with the same two meanings, live and selected.",
"section": "obsidian"
},
{
"name": "The Borrowed Corner Rule",
"body": "No control chooses its own radius. Rows and notes use --radius; luma primitives are re-rounded to Obsidian's --button-radius, --input-radius and --radius-m so the panel sits beside the app's own settings and menus without a seam.",
"section": "obsidian"
},
{
"name": "The Alias Only Rule",
"body": "Panel components use token aliases (bg-primary/5, text-link, border-b) and the panel.css utilities. A literal colour, font or radius in ui/src/lib/panel/ breaks the Obsidian mapping.",
"section": "obsidian"
}
],
"dos": [
"Do build lists as ledger-grid rows with border-b and a per-row column template; use a native table when there are more than four numeric columns.",
@@ -170,7 +607,10 @@
"Do put secondary surfaces (rails, trees) on bg-sidebar/50 with a hairline, not on a card.",
"Do show every error as error-note.svelte with a retry and every empty list as empty-state.svelte with a one-line hint.",
"Do respect prefers-reduced-motion; new motion must be a CSS transition or one of animate-pulse-dot and animate-rise.",
"Do keep the luma primitives as shipped; compose them with size=\"sm\" and variant=\"outline\" or \"ghost\" for in-page actions."
"Do keep the luma primitives as shipped; compose them with size=\"sm\" and variant=\"outline\" or \"ghost\" for in-page actions.",
"Do write panel components (ui/src/lib/panel/) against token aliases and panel.css utilities only, and check them in both the admin and the plugin.",
"Do decide panel layout from the panel's own width (@container, bind:clientWidth); 768px is where the rail replaces the switcher.",
"Do add conversation actions to actions.svelte.ts so the header menu and the row menu stay one list."
],
"donts": [
"Don't put a card inside a card, or wrap ledger rows in a bordered container.",
@@ -179,7 +619,10 @@
"Don't introduce a heading size between the page headline (1rem) and the section label (0.75rem uppercase).",
"Don't render solid colored chips; chips are hue/12 behind hue text.",
"Don't use hue-chip, hairline, touch-shown or scrollbar-none from layout.css as if they were system rules - they are defined and currently unused by the admin.",
"Don't apply this palette inside Obsidian; the panel takes Obsidian's variables (PRODUCT.md brand commitment)."
"Don't apply this palette inside Obsidian; the panel takes Obsidian's variables (PRODUCT.md brand commitment).",
"Don't expect pills inside Obsidian; every radius there is the host's (--button-radius, --input-radius, --radius-m).",
"Don't mark an active tab with bg-background in panel code; the plugin overrides it to ink at 14%.",
"Don't let a menu or dialog render inside the sidedock; overlays mount in .beaver-root.beaver-portal at --layer-menu."
]
}
}