Feat: Build out server shell
This commit is contained in:
177
Documentation/STYLING-THEME-SAMPLE.json
Normal file
177
Documentation/STYLING-THEME-SAMPLE.json
Normal 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
327
Documentation/STYLING.md
Normal 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 drawer’s 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.
|
||||
Reference in New Issue
Block a user