Feat: Build out server shell

This commit is contained in:
MangoPig
2026-06-16 13:11:14 +01:00
parent 35586729ba
commit 829d7b3d8f
28 changed files with 1990 additions and 149 deletions

View File

@@ -0,0 +1,177 @@
{
"schemaVersion": "1.0.0",
"id": "moku-styling-sample",
"name": "Moku Styling Sample",
"description": "Sample theme showing the background, surface, border, accent, and primary tokens documented in Documentation/STYLING.md.",
"author": "Moku Work",
"tokens": {
"shared": {
"palette": {
"gray": {
"0": "hsl(210 20% 99%)",
"50": "hsl(220 20% 97%)",
"100": "hsl(220 16% 93%)",
"200": "hsl(220 13% 87%)",
"300": "hsl(220 11% 75%)",
"400": "hsl(220 9% 58%)",
"500": "hsl(220 10% 45%)",
"600": "hsl(220 14% 34%)",
"700": "hsl(220 18% 24%)",
"800": "hsl(220 22% 16%)",
"900": "hsl(220 28% 10%)"
},
"blue": {
"400": "hsl(218 88% 61%)",
"500": "hsl(221 83% 53%)",
"600": "hsl(224 76% 48%)"
},
"green": {
"500": "hsl(154 60% 40%)"
},
"red": {
"500": "hsl(0 72% 54%)"
},
"amber": {
"500": "hsl(36 100% 50%)"
}
},
"space": {
"1": "0.25rem",
"2": "0.5rem",
"3": "0.75rem",
"4": "1rem",
"5": "1.25rem",
"6": "1.5rem",
"8": "2rem",
"10": "2.5rem",
"12": "3rem"
},
"radius": {
"sm": "0.375rem",
"md": "0.625rem",
"lg": "0.875rem",
"xl": "1.25rem",
"pill": "999px"
},
"size": {
"controlMd": "2.25rem",
"controlLg": "2.5rem",
"contentWidthWide": "72rem",
"blurOverlay": "18px"
},
"shadow": {
"soft": "0 12px 32px hsl(220 30% 10% / 0.08)",
"strong": "0 20px 48px hsl(220 30% 10% / 0.16)"
},
"zIndex": {
"base": "1",
"dropdown": "100",
"sticky": "200",
"overlay": "400",
"modal": "500",
"toast": "600"
},
"motion": {
"durationFast": "140ms",
"durationBase": "220ms",
"durationSlow": "320ms",
"easeStandard": "cubic-bezier(0.2, 0.8, 0.2, 1)"
},
"typography": {
"fontFamily": {
"sans": "ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", \"Helvetica Neue\", Arial, sans-serif",
"heading": "\"Avenir Next\", \"Segoe UI\", \"Helvetica Neue\", Arial, sans-serif",
"display": "\"Avenir Next\", \"Segoe UI\", \"Helvetica Neue\", Arial, sans-serif",
"serif": "ui-serif, Georgia, Cambria, \"Times New Roman\", Times, serif",
"mono": "ui-monospace, \"SF Mono\", \"SFMono-Regular\", Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace"
},
"fontSize": {
"caption": "0.75rem",
"label": "0.875rem",
"body": "1rem",
"title": "clamp(1.125rem, 1.05rem + 0.3vw, 1.25rem)",
"heading": "clamp(1.5rem, 1.2rem + 1vw, 2.125rem)",
"display": "clamp(2.25rem, 1.7rem + 2.2vw, 3.75rem)"
},
"lineHeight": {
"caption": "1.4",
"label": "1.35",
"body": "1.55",
"title": "1.3",
"heading": "1.15",
"display": "1.05"
},
"fontWeight": {
"caption": "500",
"label": "600",
"body": "400",
"title": "600",
"heading": "600",
"display": "700"
},
"letterSpacing": {
"caption": "0.01em",
"label": "0.005em",
"body": "0",
"title": "-0.01em",
"heading": "-0.02em",
"display": "-0.03em"
}
}
},
"modes": {
"light": {
"colorScheme": "light",
"colors": {
"canvas": "var(--gray-50)",
"surface": "hsl(0 0% 100% / 0.9)",
"surfaceMuted": "var(--gray-0)",
"surfaceHover": "var(--gray-100)",
"border": "hsl(220 15% 85% / 0.9)",
"borderStrong": "hsl(220 12% 70% / 0.9)",
"text": "var(--gray-800)",
"textMuted": "var(--gray-500)",
"accent": "var(--blue-500)",
"accentStrong": "var(--blue-600)",
"accentSoft": "hsl(218 88% 61% / 0.12)",
"accentContrast": "hsl(0 0% 100%)",
"primaryOne": "var(--blue-500)",
"primaryTwo": "hsl(271 72% 60%)",
"primaryThree": "hsl(192 76% 48%)",
"success": "var(--green-500)",
"danger": "var(--red-500)",
"warning": "var(--amber-500)",
"focusRing": "hsl(221 83% 53% / 0.55)"
}
},
"dark": {
"colorScheme": "dark",
"colors": {
"canvas": "var(--gray-900)",
"surface": "hsl(220 23% 14% / 0.92)",
"surfaceMuted": "hsl(220 22% 12% / 0.96)",
"surfaceHover": "hsl(220 18% 20% / 0.96)",
"border": "hsl(220 12% 26% / 0.9)",
"borderStrong": "hsl(220 12% 38% / 0.9)",
"text": "hsl(210 20% 96%)",
"textMuted": "hsl(220 12% 70%)",
"accent": "hsl(217 91% 67%)",
"accentStrong": "hsl(218 88% 61%)",
"accentSoft": "hsl(217 91% 67% / 0.18)",
"accentContrast": "hsl(220 28% 10%)",
"primaryOne": "hsl(217 91% 67%)",
"primaryTwo": "hsl(272 80% 70%)",
"primaryThree": "hsl(190 84% 62%)",
"success": "hsl(154 55% 48%)",
"danger": "hsl(0 72% 62%)",
"warning": "hsl(36 100% 60%)",
"focusRing": "hsl(217 91% 67% / 0.65)"
},
"shadow": {
"soft": "0 16px 40px hsl(220 40% 3% / 0.45)",
"strong": "0 24px 60px hsl(220 40% 3% / 0.55)"
}
}
}
}
}

327
Documentation/STYLING.md Normal file
View File

@@ -0,0 +1,327 @@
# Styling Reference
This document explains which theme tokens control the main backgrounds, surfaces,
borders, and shell gradients in Moku Work.
It is focused on the current frontend shell scaffold so future visual tuning can
be done intentionally instead of by guesswork.
## Source Of Truth
There are two places to look when changing styling tokens:
- Runtime theme payload:
- `Frontend/public/themes/moku-default.json`
- SCSS fallback defaults:
- `Frontend/src/styles/themes/_light.scss`
- `Frontend/src/styles/themes/_dark.scss`
- Full sample theme file:
- `Documentation/STYLING-THEME-SAMPLE.json`
If you want to change the actual themed values used by the app, update the theme
JSON first. The SCSS files act as fallback/default variables.
---
## Core Surface Tokens
These are the main tokens currently driving shell backgrounds and card surfaces:
- `--color-canvas`
- outer page background
- `--color-surface`
- standard panel/card/topbar surface
- `--color-surface-muted`
- quieter secondary panels and dropdown surfaces
- `--color-surface-hover`
- hover state for solid surface rows
- `--color-border`
- standard card/panel border
- `--color-border-strong`
- stronger shell edges, separators, and emphasized borders
- `--color-text`
- primary text color
- `--color-text-muted`
- secondary/meta text color
- `--color-accent`
- primary accent lane
- `--color-accent-strong`
- stronger accent emphasis
- `--color-accent-soft`
- soft accent wash for subtle fills
There are also ring-only multi-primary tokens currently used for the top-right
profile ring:
- `--color-primary-1`
- `--color-primary-2`
- `--color-primary-3`
---
## Light Mode Values
Current light-mode surface values:
```text
--color-canvas: var(--gray-50)
--color-surface: hsl(0 0% 100% / 0.9)
--color-surface-muted: var(--gray-0)
--color-surface-hover: var(--gray-100)
--color-border: hsl(220 15% 85% / 0.9)
--color-border-strong: hsl(220 12% 70% / 0.9)
--color-text: var(--gray-800)
--color-text-muted: var(--gray-500)
--color-accent: var(--blue-500)
--color-accent-strong: var(--blue-600)
--color-accent-soft: hsl(218 88% 61% / 0.12)
--color-primary-1: var(--blue-500)
--color-primary-2: hsl(271 72% 60%)
--color-primary-3: hsl(192 76% 48%)
```
## Dark Mode Values
Current dark-mode surface values:
```text
--color-canvas: var(--gray-900)
--color-surface: hsl(220 23% 14% / 0.92)
--color-surface-muted: hsl(220 22% 12% / 0.96)
--color-surface-hover: hsl(220 18% 20% / 0.96)
--color-border: hsl(220 12% 26% / 0.9)
--color-border-strong: hsl(220 12% 38% / 0.9)
--color-text: hsl(210 20% 96%)
--color-text-muted: hsl(220 12% 70%)
--color-accent: hsl(217 91% 67%)
--color-accent-strong: hsl(218 88% 61%)
--color-accent-soft: hsl(217 91% 67% / 0.18)
--color-primary-1: hsl(217 91% 67%)
--color-primary-2: hsl(272 80% 70%)
--color-primary-3: hsl(190 84% 62%)
```
---
## What Controls What
### 1. App Background
File:
- `Frontend/src/components/shell/AppShell/AppShell.module.scss`
The outer app frame uses:
```scss
background: var(--color-canvas);
color: var(--color-text);
```
So if you want to change the overall page backdrop, change `--color-canvas`.
### 2. Main Shell Split Background
File:
- `Frontend/src/components/shell/AppShell/AppShell.module.scss`
The shell derives two important internal surface blends:
```text
--sidebar-panel-surface: color-mix(in srgb, var(--color-surface-muted) 92%, transparent)
--workspace-panel-surface: color-mix(in srgb, var(--color-canvas) 94%, var(--color-surface))
```
It also derives frame/separator borders:
```text
--shell-frame-border: color-mix(in srgb, var(--color-border-strong) 44%, transparent)
--shell-divider-border: color-mix(in srgb, var(--color-border-strong) 34%, transparent)
```
Surface usage inside the shell:
- `.body``var(--color-surface)`
- `.railColumn``var(--color-surface)`
- `.sidebarColumn``var(--sidebar-panel-surface)`
- `.workspaceMain``var(--workspace-panel-surface)`
The major left/right shell background is drawn by `workspaceRegion::before` using a
horizontal gradient from sidebar surface to workspace surface.
### 3. Standard Content Cards
File:
- `Frontend/src/components/workspace-home/WorkspaceHome/WorkspaceHome.module.scss`
Cards currently use:
```text
background: var(--color-surface)
border: 1px solid var(--color-border)
box-shadow: var(--shadow-soft)
```
If cards feel too flat or too strong, start by adjusting:
- `--color-surface`
- `--color-border`
### 4. Top Bar
File:
- `Frontend/src/components/shell/TopBar/TopBar.module.scss`
The top bar itself uses:
```text
background: var(--color-surface)
```
Hover/focus states for top-right controls use transparent mixes based on:
- `--color-text`
- `--color-accent-strong`
So the bar is mostly controlled by `--color-surface`, while the interactive polish
comes from text/accent tokens.
### 5. Server Dock
File:
- `Frontend/src/components/shell/ServerDock/ServerDock.module.scss`
The dock uses two derived tokens:
```text
--server-dock-border: color-mix(in srgb, var(--color-border-strong) 75%, transparent)
--server-dock-surface: color-mix(in srgb, var(--color-surface) 94%, transparent)
```
That means the dock is visually tied most strongly to:
- `--color-surface`
- `--color-border-strong`
The server glyph fill uses a soft accent wash derived from:
- `--color-accent-soft`
### 6. Project Drawer
File:
- `Frontend/src/components/shell/ProjectSelector/ProjectSelector.module.scss`
Important layers:
- scrim:
- `color-mix(in srgb, black 8%, transparent)`
- drawer panel surface:
- defined in `.drawer::before`
- vertical gradient from `--color-surface` to `--color-surface-muted`
- current-project summary block:
- `color-mix(in srgb, var(--color-surface) 72%, transparent)`
- menu row hover:
- based on `--color-surface-hover`
- menu row active:
- based on `--color-surface`
So the drawers look is mainly shaped by:
- `--color-surface`
- `--color-surface-muted`
- `--color-surface-hover`
- `--color-border-strong`
### 7. Department Selector Dropdown
File:
- `Frontend/src/components/shell/DepartmentSelector/DepartmentSelector.module.scss`
The department dropdown is intentionally solid, not blurred.
It uses:
```text
.menu background: var(--color-surface-muted)
.menu border: 1px solid var(--color-border-strong)
.menuItem background: var(--color-surface-muted)
.submenuItem background: var(--color-surface-muted)
hover/active rows: var(--color-surface)
```
If the department menu feels too heavy or too subtle, start by adjusting:
- `--color-surface-muted`
- `--color-surface`
- `--color-border-strong`
---
## Quick Tuning Guide
If you want to change the overall visual mood quickly, these are the highest-leverage tokens:
### Make the app feel lighter / airier
Adjust:
- `--color-canvas`
- `--color-surface`
- `--color-surface-muted`
### Make shells/cards feel more separated
Adjust:
- `--color-border`
- `--color-border-strong`
- `--color-surface-muted`
### Make accent washes more or less noticeable
Adjust:
- `--color-accent-soft`
### Change the visual personality of the profile ring
Adjust:
- `--color-primary-1`
- `--color-primary-2`
- `--color-primary-3`
---
## Practical Rule Of Thumb
Use this mental model:
```text
canvas = app/page background
surface = primary panel or card
surface-muted = quieter secondary panel
surface-hover = solid hover state
border = normal edge
border-strong = stronger shell edge or divider
accent-soft = subtle tinted wash
primary-1/2/3 = decorative multi-color accents
```
If you are unsure where to start, tune these in this order:
1. `--color-canvas`
2. `--color-surface`
3. `--color-surface-muted`
4. `--color-border`
5. `--color-border-strong`
6. `--color-accent-soft`
That usually gives the biggest visual shift with the fewest unintended side effects.