Files
local-mcp/static/css/base.css
Brandon Zhang 298ad54b5c fix(ui/theme): replace light theme with clean material design palette
The previous light theme used warm/organic off-whites and muted tones
that felt muddy.  Replaced with a crisp material-inspired palette:
Surfaces
- bg-void   #f0f2f5  (cool-grey base)
- bg-base   #f5f7fa  (very light cool background)
- bg-raised #ffffff  (pure white cards)
- bg-hover  #e3e8f0  (clear interactive hover)
Typography
- text-primary   #1a202c  (near-black, high contrast)
- text-secondary #4a5568  (balanced mid-grey)
- text-muted     #8896a7  (clear but soft)
Accents (Material Design colour values)
- cyan  #0277bd  Blue 700 (replaces washed-out #007fa8)
- green #388e3c  Green 700
- amber #e65100  Deep Orange 900 (warmer, more material)
- red   #d32f2f  Red 700
Shadows
Dual-layer transparent shadows for better depth perception on light
backgrounds.
Also adds @keyframes fade-in-up used by the shortcuts add form.
2026-03-27 13:55:36 +08:00

204 lines
6.3 KiB
CSS

/*
* static/css/base.css
* Design tokens, reset, and typographic foundation.
*
* Aesthetic: Industrial Ops Terminal
* Dark graphite workspace with electric cyan as the primary action colour
* and amber for warnings/consumed state. Syne for UI chrome, JetBrains Mono
* for instruction content. Strong structure, decisive whitespace.
*/
/* ── Fonts ─────────────────────────────────────────────────────────────── */
@font-face {
font-family: 'Syne';
src: url('/static/assets/fonts/syne.woff2') format('woff2');
font-weight: 100 900;
font-display: swap;
}
@font-face {
font-family: 'JetBrains Mono';
src: url('/static/assets/fonts/jetbrains-mono.woff2') format('woff2');
font-weight: 100 900;
font-display: swap;
}
/* ── Design tokens ──────────────────────────────────────────────────────── */
:root {
/* Surfaces */
--bg-void: #080b0d;
--bg-base: #0d1117;
--bg-raised: #131920;
--bg-overlay: #1a2230;
--bg-hover: #1f2a3a;
--bg-active: #243040;
/* Borders */
--border-subtle: #1e2c3a;
--border-muted: #253345;
--border-strong: #2e4058;
/* Text */
--text-primary: #e8edf2;
--text-secondary:#8da0b3;
--text-muted: #4a6175;
--text-disabled: #2e4a5e;
/* Brand / accent */
--cyan: #00d4ff;
--cyan-dim: #007fa8;
--cyan-glow: rgba(0, 212, 255, 0.15);
/* Status */
--green: #00e676;
--green-dim: #00703a;
--green-glow: rgba(0, 230, 118, 0.15);
--amber: #ffbe0b;
--amber-dim: #8a6500;
--amber-glow: rgba(255, 190, 11, 0.12);
--red: #ff4f4f;
--red-dim: #8a0000;
--red-glow: rgba(255, 79, 79, 0.15);
/* Typography */
--font-ui: 'Syne', system-ui, sans-serif;
--font-mono: 'JetBrains Mono', 'Cascadia Code', 'Fira Code', monospace;
--text-xs: 0.6875rem; /* 11px */
--text-sm: 0.75rem; /* 12px */
--text-base: 0.875rem; /* 14px */
--text-md: 1rem; /* 16px */
--text-lg: 1.125rem; /* 18px */
--text-xl: 1.375rem; /* 22px */
--text-2xl: 1.75rem; /* 28px */
--text-3xl: 2.25rem; /* 36px */
/* Spacing */
--space-1: 0.25rem;
--space-2: 0.5rem;
--space-3: 0.75rem;
--space-4: 1rem;
--space-5: 1.25rem;
--space-6: 1.5rem;
--space-8: 2rem;
--space-10: 2.5rem;
--space-12: 3rem;
/* Radius */
--radius-sm: 4px;
--radius-md: 8px;
--radius-lg: 12px;
/* Shadows */
--shadow-sm: 0 1px 3px rgba(0,0,0,0.4);
--shadow-md: 0 4px 16px rgba(0,0,0,0.5);
--shadow-lg: 0 8px 32px rgba(0,0,0,0.6);
--shadow-cyan: 0 0 20px var(--cyan-glow), 0 0 40px rgba(0,212,255,0.06);
/* Animation */
--ease-out-expo: cubic-bezier(0.16, 1, 0.3, 1);
--ease-in-out: cubic-bezier(0.4, 0, 0.2, 1);
--duration-fast: 120ms;
--duration-normal: 240ms;
--duration-slow: 400ms;
}
/* ── Light theme overrides ───────────────────────────────────────────────── */
/* Applied when <html data-theme="light"> is set by theme.js */
[data-theme="light"] {
/* Clean white/grey Material surfaces */
--bg-void: #f0f2f5;
--bg-base: #f5f7fa;
--bg-raised: #ffffff;
--bg-overlay: #eef1f5;
--bg-hover: #e3e8f0;
--bg-active: #d6dde8;
/* Crisp Material borders */
--border-subtle: #dde3ec;
--border-muted: #c5cdd9;
--border-strong: #a8b4c5;
/* High-contrast Material text */
--text-primary: #1a202c;
--text-secondary:#4a5568;
--text-muted: #8896a7;
--text-disabled: #b2bfcc;
/* Material Blue 700 / 800 for accent */
--cyan: #0277bd;
--cyan-dim: #01579b;
--cyan-glow: rgba(2, 119, 189, 0.12);
/* Material Green 700 */
--green: #388e3c;
--green-dim: #2e7d32;
--green-glow: rgba(56, 142, 60, 0.12);
/* Material Amber 900 */
--amber: #e65100;
--amber-dim: #bf360c;
--amber-glow: rgba(230, 81, 0, 0.1);
/* Material Red 700 */
--red: #d32f2f;
--red-dim: #b71c1c;
--red-glow: rgba(211, 47, 47, 0.1);
--shadow-sm: 0 1px 3px rgba(0,0,0,0.07), 0 1px 2px rgba(0,0,0,0.05);
--shadow-md: 0 4px 16px rgba(0,0,0,0.09), 0 2px 6px rgba(0,0,0,0.06);
--shadow-lg: 0 8px 32px rgba(0,0,0,0.12), 0 4px 12px rgba(0,0,0,0.08);
--shadow-cyan: 0 0 16px rgba(2,119,189,0.1);
}
/* ── Reset ──────────────────────────────────────────────────────────────── */
*, *::before, *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
html {
font-size: 16px;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-rendering: optimizeLegibility;
}
body {
font-family: var(--font-ui);
font-size: var(--text-base);
color: var(--text-primary);
background-color: var(--bg-base);
line-height: 1.6;
min-height: 100vh;
overflow-x: hidden;
}
/* Scrollbar */
::-webkit-scrollbar { width: 6px; height: 6px; }
::-webkit-scrollbar-track { background: var(--bg-base); }
::-webkit-scrollbar-thumb { background: var(--border-strong); border-radius: 3px; }
::-webkit-scrollbar-thumb:hover { background: var(--text-muted); }
/* Focus ring */
:focus-visible {
outline: 2px solid var(--cyan);
outline-offset: 2px;
border-radius: var(--radius-sm);
}
/* ── Typography helpers ──────────────────────────────────────────────────── */
.mono { font-family: var(--font-mono); }
.label { font-size: var(--text-xs); font-weight: 700; letter-spacing: 0.12em; text-transform: uppercase; }
.muted { color: var(--text-muted); }
.subtle { color: var(--text-secondary); }
/* ── Utility animations ─────────────────────────────────────────────────── */
@keyframes fade-in-up {
from { opacity: 0; transform: translateY(6px); }
to { opacity: 1; transform: translateY(0); }
}