From a54c60ea4149ef810a9d17dddebf4c4d1bc4fea2 Mon Sep 17 00:00:00 2001 From: v0 Date: Wed, 1 Apr 2026 17:17:43 +0000 Subject: [PATCH] style: apply Windows 2000 aesthetic redesign MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Update UI elements to classic Win2k look and color scheme Co-authored-by: Göktuğ Ceyhan <17319750+goktugcy@users.noreply.github.com> --- app/globals.css | 691 ++++++++++++------ app/layout.tsx | 17 +- components/dashboard/metrics-chart.tsx | 24 +- components/dashboard/node-telemetry-board.tsx | 24 +- components/dashboard/recent-events-feed.tsx | 46 +- components/layout/app-shell.tsx | 25 +- components/layout/app-sidebar.tsx | 36 +- components/layout/topbar.tsx | 119 ++- components/ui/section-panel.tsx | 78 +- components/ui/stat-strip.tsx | 126 +++- 10 files changed, 847 insertions(+), 339 deletions(-) diff --git a/app/globals.css b/app/globals.css index 8045e91..3b61f53 100644 --- a/app/globals.css +++ b/app/globals.css @@ -48,311 +48,578 @@ --radius-3xl: calc(var(--radius) * 2.2); } +/* ============================================================ + MICROSOFT WINDOWS 2000 THEME + Classic silver/gray UI with beveled borders, system fonts, + teal title bars, and that iconic early-2000s desktop feel. + ============================================================ */ + :root { - --background: oklch(0.985 0.001 106); - --foreground: oklch(0.255 0.01 20); - --card: oklch(0.998 0.001 106); - --card-foreground: oklch(0.255 0.01 20); - --popover: oklch(1 0 0); - --popover-foreground: oklch(0.255 0.01 20); - --primary: oklch(0.61 0.24 28); - --primary-foreground: oklch(0.985 0.001 106); - --secondary: oklch(0.968 0.002 106); - --secondary-foreground: oklch(0.32 0.01 20); - --muted: oklch(0.962 0.002 106); - --muted-foreground: oklch(0.53 0.012 20); - --accent: oklch(0.956 0.003 106); - --accent-foreground: oklch(0.32 0.01 20); - --destructive: oklch(0.6 0.22 28); - --semantic-success: oklch(0.58 0.17 154); - --semantic-success-foreground: oklch(0.44 0.13 154); - --semantic-warning: oklch(0.74 0.16 72); - --semantic-warning-foreground: oklch(0.52 0.13 72); - --semantic-danger-foreground: oklch(0.54 0.18 28); - --semantic-neutral-foreground: oklch(0.45 0.01 20); - --border: oklch(0.922 0.003 106); - --input: oklch(0.922 0.003 106); - --ring: oklch(0.61 0.24 28 / 0.2); - --chart-1: oklch(0.61 0.24 28); - --chart-2: oklch(0.66 0.16 12); - --chart-3: oklch(0.72 0.14 92); - --chart-4: oklch(0.68 0.16 34); - --chart-5: oklch(0.42 0.03 20); - --radius: 0.8rem; - --sidebar: oklch(0.992 0.001 106 / 0.98); - --sidebar-foreground: oklch(0.255 0.01 20); - --sidebar-primary: oklch(0.61 0.24 28); - --sidebar-primary-foreground: oklch(0.985 0.001 106); - --sidebar-accent: oklch(0.972 0.002 106); - --sidebar-accent-foreground: oklch(0.255 0.01 20); - --sidebar-border: oklch(0.922 0.003 106 / 0.95); - --sidebar-ring: oklch(0.61 0.24 28 / 0.16); - --surface-panel: var(--card); - --surface-subtle: color-mix(in oklch, var(--muted) 72%, white); - --surface-feature: color-mix(in oklch, var(--card) 94%, var(--primary) 6%); - --surface-dialog: var(--popover); - --control-surface: color-mix(in oklch, var(--card) 94%, var(--muted)); - --control-hover: color-mix(in oklch, var(--accent) 88%, white); - --popover-surface: var(--popover); - --surface-hover-border: color-mix(in oklch, var(--primary) 16%, var(--border)); - --shadow-dashboard: 0 1px 2px rgba(15, 23, 42, 0.04), - 0 12px 28px -22px rgba(15, 23, 42, 0.12); - --shadow-dashboard-hover: 0 16px 38px -24px rgba(15, 23, 42, 0.16), - 0 3px 10px rgba(15, 23, 42, 0.06); + /* Win2k system gray palette */ + --win2k-silver: #c0c0c0; + --win2k-silver-light: #e0e0e0; + --win2k-silver-dark: #808080; + --win2k-white: #ffffff; + --win2k-black: #000000; + --win2k-blue: #0000aa; + --win2k-teal: #008080; + --win2k-teal-dark: #006060; + --win2k-desktop: #008080; + --win2k-highlight: #000080; + --win2k-highlight-text: #ffffff; + --win2k-btn-face: #d4d0c8; + --win2k-btn-shadow: #808080; + --win2k-btn-highlight: #ffffff; + --win2k-btn-dark-shadow: #404040; + --win2k-btn-text: #000000; + --win2k-window: #ffffff; + --win2k-window-frame: #000000; + --win2k-active-title: #0a246a; + --win2k-active-title-text: #ffffff; + --win2k-active-title-grad: #a6caf0; + --win2k-inactive-title: #808080; + --win2k-menu: #d4d0c8; + --win2k-menu-text: #000000; + --win2k-scrollbar: #d4d0c8; + --win2k-3d-face: #d4d0c8; + --win2k-info-background: #ffffe1; + --win2k-info-text: #000000; + --win2k-red: #cc0000; + --win2k-green: #008000; + --win2k-orange: #cc6600; + --win2k-yellow: #cccc00; + + /* Map to Tailwind semantic tokens */ + --background: #d4d0c8; + --foreground: #000000; + --card: #d4d0c8; + --card-foreground: #000000; + --popover: #d4d0c8; + --popover-foreground: #000000; + --primary: #0a246a; + --primary-foreground: #ffffff; + --secondary: #c0c0c0; + --secondary-foreground: #000000; + --muted: #c8c4bc; + --muted-foreground: #444444; + --accent: #e0ddd6; + --accent-foreground: #000000; + --destructive: #cc0000; + --semantic-success: #008000; + --semantic-success-foreground: #005000; + --semantic-warning: #cc6600; + --semantic-warning-foreground: #884400; + --semantic-danger-foreground: #880000; + --semantic-neutral-foreground: #444444; + --border: #808080; + --input: #ffffff; + --ring: #000080; + --chart-1: #0000aa; + --chart-2: #008000; + --chart-3: #cc6600; + --chart-4: #cc0000; + --chart-5: #800080; + --radius: 0px; + --sidebar: #d4d0c8; + --sidebar-foreground: #000000; + --sidebar-primary: #0a246a; + --sidebar-primary-foreground: #ffffff; + --sidebar-accent: #c0c0c0; + --sidebar-accent-foreground: #000000; + --sidebar-border: #808080; + --sidebar-ring: #000080; + --surface-panel: #d4d0c8; + --surface-subtle: #c8c4bc; + --surface-feature: #d4d0c8; + --surface-dialog: #d4d0c8; + --control-surface: #d4d0c8; + --control-hover: #e0ddd6; + --popover-surface: #d4d0c8; + --surface-hover-border: #000080; + /* Classic raised-button bevel shadow */ + --shadow-dashboard: inset -1px -1px 0 #404040, inset 1px 1px 0 #ffffff, inset -2px -2px 0 #808080, inset 2px 2px 0 #e0e0e0; + --shadow-dashboard-hover: inset -1px -1px 0 #404040, inset 1px 1px 0 #ffffff, inset -2px -2px 0 #808080, inset 2px 2px 0 #e0e0e0; + /* Bevel variants */ + --bevel-raised: inset -1px -1px 0 #404040, inset 1px 1px 0 #ffffff, inset -2px -2px 0 #808080, inset 2px 2px 0 #e0e0e0; + --bevel-sunken: inset 1px 1px 0 #404040, inset -1px -1px 0 #ffffff, inset 2px 2px 0 #808080, inset -2px -2px 0 #e0e0e0; + --bevel-flat: 1px 1px 0 #808080; } +/* Dark mode = classic Win2k "High Contrast Black" scheme */ .dark { - --background: oklch(0.145 0 0); - --foreground: oklch(0.962 0 0); - --card: oklch(0.18 0 0); - --card-foreground: oklch(0.962 0 0); - --popover: oklch(0.2 0 0); - --popover-foreground: oklch(0.962 0 0); - --primary: oklch(0.63 0.22 28); - --primary-foreground: oklch(0.98 0 0); - --secondary: oklch(0.22 0 0); - --secondary-foreground: oklch(0.95 0 0); - --muted: oklch(0.215 0 0); - --muted-foreground: oklch(0.7 0 0); - --accent: oklch(0.24 0 0); - --accent-foreground: oklch(0.95 0 0); - --destructive: oklch(0.69 0.2 28); - --semantic-success: oklch(0.74 0.15 154); - --semantic-success-foreground: oklch(0.8 0.11 154); - --semantic-warning: oklch(0.79 0.14 72); - --semantic-warning-foreground: oklch(0.84 0.09 72); - --semantic-danger-foreground: oklch(0.8 0.12 28); - --semantic-neutral-foreground: oklch(0.72 0 0); - --border: oklch(1 0 0 / 0.08); - --input: oklch(1 0 0 / 0.08); - --ring: oklch(0.63 0.22 28 / 0.24); - --chart-1: oklch(0.63 0.22 28); - --chart-2: oklch(0.69 0.17 12); - --chart-3: oklch(0.78 0.12 92); - --chart-4: oklch(0.74 0.14 34); - --chart-5: oklch(0.6 0.03 20); - --sidebar: oklch(0.165 0 0 / 0.98); - --sidebar-foreground: oklch(0.962 0 0); - --sidebar-primary: oklch(0.63 0.22 28); - --sidebar-primary-foreground: oklch(0.98 0 0); - --sidebar-accent: oklch(0.205 0 0); - --sidebar-accent-foreground: oklch(0.962 0 0); - --sidebar-border: oklch(1 0 0 / 0.08); - --sidebar-ring: oklch(0.63 0.22 28 / 0.18); - --surface-panel: var(--card); - --surface-subtle: color-mix(in oklch, var(--card) 86%, var(--muted)); - --surface-feature: color-mix(in oklch, var(--card) 96%, var(--primary) 4%); - --surface-dialog: var(--popover); - --control-surface: color-mix(in oklch, var(--card) 88%, var(--background)); - --control-hover: color-mix(in oklch, var(--accent) 72%, var(--card)); - --popover-surface: var(--popover); - --surface-hover-border: color-mix(in oklch, var(--primary) 14%, var(--border)); - --shadow-dashboard: 0 1px 2px rgba(0, 0, 0, 0.2), - 0 16px 36px -24px rgba(0, 0, 0, 0.45); - --shadow-dashboard-hover: 0 18px 44px -24px rgba(0, 0, 0, 0.56), - 0 4px 12px rgba(0, 0, 0, 0.24); + --background: #000000; + --foreground: #ffffff; + --card: #1a1a1a; + --card-foreground: #ffffff; + --popover: #1a1a1a; + --popover-foreground: #ffffff; + --primary: #0a246a; + --primary-foreground: #ffffff; + --secondary: #333333; + --secondary-foreground: #ffffff; + --muted: #222222; + --muted-foreground: #aaaaaa; + --accent: #222222; + --accent-foreground: #ffffff; + --destructive: #ff0000; + --semantic-success: #00ff00; + --semantic-success-foreground: #00cc00; + --semantic-warning: #ffaa00; + --semantic-warning-foreground: #cc8800; + --semantic-danger-foreground: #ff4444; + --semantic-neutral-foreground: #aaaaaa; + --border: #808080; + --input: #000000; + --ring: #0000aa; + --chart-1: #4444ff; + --chart-2: #00cc00; + --chart-3: #ffaa00; + --chart-4: #ff4444; + --chart-5: #aa00aa; + --sidebar: #1a1a1a; + --sidebar-foreground: #ffffff; + --sidebar-primary: #0a246a; + --sidebar-primary-foreground: #ffffff; + --sidebar-accent: #333333; + --sidebar-accent-foreground: #ffffff; + --sidebar-border: #808080; + --sidebar-ring: #0000aa; + --surface-panel: #1a1a1a; + --surface-subtle: #111111; + --surface-feature: #1a1a1a; + --surface-dialog: #1a1a1a; + --control-surface: #222222; + --control-hover: #333333; + --popover-surface: #1a1a1a; + --surface-hover-border: #0000aa; + --shadow-dashboard: inset -1px -1px 0 #000000, inset 1px 1px 0 #666666, inset -2px -2px 0 #333333, inset 2px 2px 0 #555555; + --shadow-dashboard-hover: inset -1px -1px 0 #000000, inset 1px 1px 0 #666666, inset -2px -2px 0 #333333, inset 2px 2px 0 #555555; + --bevel-raised: inset -1px -1px 0 #000000, inset 1px 1px 0 #666666, inset -2px -2px 0 #333333, inset 2px 2px 0 #555555; + --bevel-sunken: inset 1px 1px 0 #000000, inset -1px -1px 0 #666666, inset 2px 2px 0 #333333, inset -2px -2px 0 #555555; } @layer base { * { @apply border-border outline-ring/50; + border-radius: 0 !important; + /* Kill all modern border-radius everywhere */ + font-family: "Tahoma", "MS Sans Serif", "Arial", sans-serif !important; + -webkit-font-smoothing: none !important; + font-smoothing: none !important; } html { - @apply h-full scroll-smooth font-sans; + @apply h-full scroll-smooth; } body { - @apply min-h-full overflow-x-hidden bg-background text-foreground antialiased; - background-image: radial-gradient( - circle at top right, - color-mix(in oklch, var(--primary) 6%, transparent), - transparent 24rem - ), - linear-gradient( - 180deg, - color-mix(in oklch, var(--background) 98%, var(--muted) 2%), - var(--background) - ); - } - - .dark body { - background-image: linear-gradient( - 180deg, - color-mix(in oklch, var(--background) 97%, var(--secondary) 3%), - var(--background) - ); + @apply min-h-full overflow-x-hidden bg-background text-foreground; + background-color: var(--win2k-desktop) !important; + background-image: none !important; } ::selection { - background: color-mix(in oklch, var(--primary) 24%, transparent); - color: var(--foreground); + background: var(--win2k-highlight); + color: var(--win2k-highlight-text); + } + + /* Win2k scrollbars */ + ::-webkit-scrollbar { + width: 17px; + height: 17px; + } + + ::-webkit-scrollbar-track { + background: var(--win2k-scrollbar); + } + + ::-webkit-scrollbar-thumb { + background: var(--win2k-btn-face); + border-radius: 0; + border: none; + box-shadow: var(--bevel-raised); + } + + ::-webkit-scrollbar-button { + background: var(--win2k-btn-face); + box-shadow: var(--bevel-raised); + width: 17px; + height: 17px; + } + + ::-webkit-scrollbar-corner { + background: var(--win2k-scrollbar); } } @layer utilities { .app-shell-grid { - background-image: - linear-gradient(rgba(148, 163, 184, 0.06) 1px, transparent 1px), - linear-gradient(90deg, rgba(148, 163, 184, 0.06) 1px, transparent 1px); - background-size: 52px 52px; - mask-image: linear-gradient(180deg, black 0%, transparent 100%); + background-image: none; } .glass-panel { - background: color-mix(in oklch, var(--surface-panel) 92%, transparent); - backdrop-filter: blur(18px); + background: var(--win2k-btn-face); + backdrop-filter: none; } + /* Win2k raised panel (default window look) */ .surface-panel { - border-color: color-mix(in oklch, var(--border) 96%, transparent); - background: var(--surface-panel); - box-shadow: var(--shadow-dashboard); + background: var(--win2k-btn-face) !important; + border: 2px solid !important; + border-color: var(--win2k-btn-highlight) var(--win2k-btn-shadow) var(--win2k-btn-shadow) var(--win2k-btn-highlight) !important; + box-shadow: 1px 1px 0 var(--win2k-btn-dark-shadow) !important; + border-radius: 0 !important; } .surface-feature { - border-color: color-mix(in oklch, var(--primary) 10%, var(--border)); - background: - linear-gradient(180deg, color-mix(in oklch, var(--primary) 4%, transparent), transparent 5rem), - var(--surface-feature); - box-shadow: var(--shadow-dashboard); + background: var(--win2k-btn-face) !important; + border: 2px solid !important; + border-color: var(--win2k-btn-highlight) var(--win2k-btn-shadow) var(--win2k-btn-shadow) var(--win2k-btn-highlight) !important; + box-shadow: 1px 1px 0 var(--win2k-btn-dark-shadow) !important; + border-radius: 0 !important; } + /* Win2k sunken input/inset look */ .surface-subtle { - border-color: color-mix(in oklch, var(--border) 90%, transparent); - background: var(--surface-subtle); + background: var(--win2k-silver) !important; + border: 2px solid !important; + border-color: var(--win2k-btn-shadow) var(--win2k-btn-highlight) var(--win2k-btn-highlight) var(--win2k-btn-shadow) !important; + box-shadow: -1px -1px 0 var(--win2k-btn-dark-shadow) !important; + border-radius: 0 !important; } .control-surface { - border-color: color-mix(in oklch, var(--border) 95%, transparent); - background: var(--control-surface); + background: var(--win2k-btn-face) !important; + border: 2px solid !important; + border-color: var(--win2k-btn-highlight) var(--win2k-btn-shadow) var(--win2k-btn-shadow) var(--win2k-btn-highlight) !important; + border-radius: 0 !important; } .control-surface:hover { - border-color: var(--surface-hover-border); - background: var(--control-hover); + background: var(--win2k-silver-light) !important; + border-color: var(--win2k-btn-dark-shadow) var(--win2k-btn-highlight) var(--win2k-btn-highlight) var(--win2k-btn-dark-shadow) !important; } .popover-surface { - border-color: color-mix(in oklch, var(--border) 90%, transparent); - background: var(--popover-surface); - box-shadow: var(--shadow-dashboard-hover); + background: var(--win2k-btn-face) !important; + border: 2px solid !important; + border-color: var(--win2k-btn-highlight) var(--win2k-btn-shadow) var(--win2k-btn-shadow) var(--win2k-btn-highlight) !important; + box-shadow: 2px 2px 0 var(--win2k-btn-dark-shadow) !important; + border-radius: 0 !important; } .surface-hover { - transition: - border-color 160ms ease, - box-shadow 160ms ease, - background-color 160ms ease; + transition: none !important; } .surface-hover:hover { - border-color: var(--surface-hover-border); - box-shadow: var(--shadow-dashboard-hover); + border-color: var(--win2k-highlight) !important; + box-shadow: var(--bevel-raised) !important; } .xterm { height: 100%; } + /* Win2k brand badge = classic title bar accent */ .brand-badge { - border-color: color-mix(in oklch, var(--primary) 10%, var(--border)); - background: linear-gradient( - 180deg, - color-mix(in oklch, var(--surface-panel) 92%, var(--primary) 8%), - var(--surface-panel) - ); - box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.14); + background: var(--win2k-active-title) !important; + border: 1px solid var(--win2k-btn-dark-shadow) !important; + box-shadow: none !important; + border-radius: 0 !important; } + /* Tone classes — Win2k inspired status colors */ .tone-brand { - border-color: color-mix(in oklch, var(--primary) 16%, transparent); - background: color-mix(in oklch, var(--primary) 10%, transparent); - color: var(--primary); + border: 2px solid !important; + border-color: var(--win2k-btn-highlight) var(--win2k-btn-shadow) var(--win2k-btn-shadow) var(--win2k-btn-highlight) !important; + background: #d0e8ff !important; + color: var(--win2k-active-title) !important; } .tone-success { - border-color: color-mix(in oklch, var(--semantic-success) 16%, transparent); - background: color-mix(in oklch, var(--semantic-success) 10%, transparent); - color: var(--semantic-success-foreground); + border: 2px solid !important; + border-color: var(--win2k-btn-highlight) var(--win2k-btn-shadow) var(--win2k-btn-shadow) var(--win2k-btn-highlight) !important; + background: #d0ffd0 !important; + color: #004400 !important; } .tone-warning { - border-color: color-mix(in oklch, var(--semantic-warning) 16%, transparent); - background: color-mix(in oklch, var(--semantic-warning) 10%, transparent); - color: var(--semantic-warning-foreground); + border: 2px solid !important; + border-color: var(--win2k-btn-highlight) var(--win2k-btn-shadow) var(--win2k-btn-shadow) var(--win2k-btn-highlight) !important; + background: #fff0c8 !important; + color: #884400 !important; } .tone-danger { - border-color: color-mix(in oklch, var(--destructive) 16%, transparent); - background: color-mix(in oklch, var(--destructive) 10%, transparent); - color: var(--semantic-danger-foreground); + border: 2px solid !important; + border-color: var(--win2k-btn-highlight) var(--win2k-btn-shadow) var(--win2k-btn-shadow) var(--win2k-btn-highlight) !important; + background: #ffd0d0 !important; + color: #880000 !important; } .tone-neutral { - border-color: color-mix(in oklch, var(--border) 96%, transparent); - background: color-mix(in oklch, var(--muted) 72%, transparent); - color: var(--semantic-neutral-foreground); + border: 2px solid !important; + border-color: var(--win2k-btn-shadow) var(--win2k-btn-highlight) var(--win2k-btn-highlight) var(--win2k-btn-shadow) !important; + background: var(--win2k-silver) !important; + color: var(--win2k-btn-text) !important; } - .text-tone-brand { - color: var(--primary); + .text-tone-brand { color: var(--win2k-active-title); } + .text-tone-success { color: #005000; } + .text-tone-warning { color: #884400; } + .text-tone-danger { color: #880000; } + .text-tone-neutral { color: #444444; } + + .data-grid { + background-image: none; } - .text-tone-success { - color: var(--semantic-success-foreground); + .text-shimmer { + background: none; + color: var(--foreground); + animation: none; } - .text-tone-warning { - color: var(--semantic-warning-foreground); + .shadow-dashboard { + box-shadow: var(--shadow-dashboard); } - .text-tone-danger { - color: var(--semantic-danger-foreground); + /* Win2k title bar gradient */ + .win2k-titlebar { + background: linear-gradient(to right, var(--win2k-active-title), var(--win2k-active-title-grad)) !important; + color: var(--win2k-active-title-text) !important; + font-weight: bold !important; + padding: 3px 6px !important; + font-size: 12px !important; + letter-spacing: 0 !important; } - .text-tone-neutral { - color: var(--semantic-neutral-foreground); + /* Win2k classic button */ + .win2k-btn { + background: var(--win2k-btn-face) !important; + border: 2px solid !important; + border-color: var(--win2k-btn-highlight) var(--win2k-btn-shadow) var(--win2k-btn-shadow) var(--win2k-btn-highlight) !important; + box-shadow: 1px 1px 0 var(--win2k-btn-dark-shadow) !important; + color: var(--win2k-btn-text) !important; + border-radius: 0 !important; + padding: 2px 8px !important; + font-size: 11px !important; + cursor: pointer; } - .data-grid { - background-image: - linear-gradient(rgba(148, 163, 184, 0.06) 1px, transparent 1px), - linear-gradient(90deg, rgba(148, 163, 184, 0.06) 1px, transparent 1px); - background-size: 22px 22px; + .win2k-btn:active { + border-color: var(--win2k-btn-shadow) var(--win2k-btn-highlight) var(--win2k-btn-highlight) var(--win2k-btn-shadow) !important; + box-shadow: -1px -1px 0 var(--win2k-btn-dark-shadow) !important; } - .text-shimmer { - background-image: linear-gradient( - 110deg, - var(--foreground) 15%, - color-mix(in oklch, var(--primary) 30%, var(--foreground)) 45%, - var(--foreground) 80% - ); - background-size: 200% 100%; - -webkit-background-clip: text; - background-clip: text; - color: transparent; - animation: shimmer 2.8s linear infinite; + /* Sunken inset field */ + .win2k-field { + background: var(--win2k-white) !important; + border: 2px solid !important; + border-color: var(--win2k-btn-shadow) var(--win2k-btn-highlight) var(--win2k-btn-highlight) var(--win2k-btn-shadow) !important; + border-radius: 0 !important; + color: #000000 !important; } - .shadow-dashboard { - box-shadow: var(--shadow-dashboard); + /* Status bar */ + .win2k-statusbar { + background: var(--win2k-btn-face) !important; + border-top: 2px solid var(--win2k-btn-shadow) !important; + font-size: 11px !important; + padding: 2px 6px !important; + } + + /* Classic menu bar */ + .win2k-menubar { + background: var(--win2k-menu) !important; + border-bottom: 1px solid var(--win2k-btn-shadow) !important; + font-size: 11px !important; } } -::-webkit-scrollbar { - width: 10px; - height: 10px; +/* Override all shadcn rounded corners globally */ +[class*="rounded"] { + border-radius: 0 !important; +} + +/* Win2k table styles */ +table { + border-collapse: collapse !important; +} + +th { + background: var(--win2k-btn-face) !important; + border: 1px solid var(--win2k-btn-shadow) !important; + font-weight: bold !important; + font-size: 11px !important; + padding: 3px 6px !important; + text-align: left !important; + color: var(--win2k-btn-text) !important; +} + +td { + border: 1px solid var(--win2k-btn-shadow) !important; + font-size: 11px !important; + padding: 2px 6px !important; + background: var(--win2k-white) !important; + color: var(--win2k-btn-text) !important; +} + +tr:hover td { + background: var(--win2k-highlight) !important; + color: var(--win2k-highlight-text) !important; +} + +/* Win2k card header = title bar */ +[class*="CardHeader"], +[data-slot="card-header"] { + background: linear-gradient(to right, var(--win2k-active-title), var(--win2k-active-title-grad)) !important; + color: var(--win2k-active-title-text) !important; + border-bottom: 2px solid var(--win2k-btn-dark-shadow) !important; + padding: 4px 8px !important; + border-radius: 0 !important; +} + +[class*="CardTitle"], +[data-slot="card-title"] { + color: var(--win2k-active-title-text) !important; + font-size: 12px !important; + font-weight: bold !important; + letter-spacing: 0 !important; +} + +[class*="CardDescription"], +[data-slot="card-description"] { + color: #c8d8f0 !important; + font-size: 10px !important; +} + +/* Win2k badge = classic label */ +[class*="Badge"], +[data-slot="badge"] { + border-radius: 0 !important; + font-size: 10px !important; + padding: 1px 4px !important; + font-weight: bold !important; + border: 1px solid var(--win2k-btn-dark-shadow) !important; +} + +/* Win2k buttons */ +button:not([class*="ghost"]):not([class*="link"]) { + border-radius: 0 !important; +} + +/* Win2k inputs */ +input[type="text"], +input[type="search"], +input[type="email"], +input[type="password"], +textarea, +select { + background: var(--win2k-white) !important; + border: 2px solid !important; + border-color: var(--win2k-btn-shadow) var(--win2k-btn-highlight) var(--win2k-btn-highlight) var(--win2k-btn-shadow) !important; + border-radius: 0 !important; + color: #000000 !important; + font-size: 11px !important; +} + +/* Win2k progress bars */ +[role="progressbar"] { + border-radius: 0 !important; + background: var(--win2k-white) !important; + border: 2px solid !important; + border-color: var(--win2k-btn-shadow) var(--win2k-btn-highlight) var(--win2k-btn-highlight) var(--win2k-btn-shadow) !important; +} + +/* Win2k tooltip = ToolTip yellow */ +[role="tooltip"], +[data-slot="tooltip-content"] { + background: var(--win2k-info-background) !important; + color: var(--win2k-info-text) !important; + border: 1px solid #000000 !important; + border-radius: 0 !important; + font-size: 11px !important; + box-shadow: 1px 1px 0 #808080 !important; + padding: 2px 4px !important; +} + +/* Win2k separator */ +hr, [data-slot="separator"] { + border-color: var(--win2k-btn-shadow) !important; + border-style: solid !important; + border-width: 1px 0 0 0 !important; +} + +/* Override any gradients on body/backgrounds */ +.min-h-screen { + background-color: var(--win2k-desktop) !important; + background-image: none !important; +} + +/* Win2k sidebar = classic Explorer sidebar */ +aside, [class*="sidebar"] { + background: var(--win2k-btn-face) !important; + border-right: 2px solid var(--win2k-btn-shadow) !important; +} + +/* Win2k header/topbar = classic menu bar */ +header { + background: var(--win2k-btn-face) !important; + border-bottom: 2px solid var(--win2k-btn-shadow) !important; + backdrop-filter: none !important; +} + +/* Win2k dropdown menus */ +[data-slot="dropdown-menu-content"], +[data-slot="popover-content"] { + background: var(--win2k-menu) !important; + border: 2px solid !important; + border-color: var(--win2k-btn-highlight) var(--win2k-btn-shadow) var(--win2k-btn-shadow) var(--win2k-btn-highlight) !important; + box-shadow: 2px 2px 0 var(--win2k-btn-dark-shadow) !important; + border-radius: 0 !important; +} + +/* Win2k tab bar */ +[data-slot="tabs-list"] { + background: var(--win2k-btn-face) !important; + border-radius: 0 !important; + border-bottom: 2px solid var(--win2k-btn-shadow) !important; +} + +[data-slot="tabs-trigger"] { + border-radius: 0 !important; + font-size: 11px !important; +} + +[data-slot="tabs-trigger"][data-state="active"] { + background: var(--win2k-btn-face) !important; + box-shadow: var(--bevel-raised) !important; +} + +/* Win2k Avatar = generic person icon */ +[data-slot="avatar"] { + border-radius: 0 !important; + border: 2px solid var(--win2k-btn-shadow) !important; +} + +/* Win2k skeleton = flat gray */ +[data-slot="skeleton"] { + background: var(--win2k-silver) !important; + border: 1px solid var(--win2k-btn-shadow) !important; + border-radius: 0 !important; + animation: none !important; } -::-webkit-scrollbar-track { - background: transparent; +/* Muted text override */ +.text-muted-foreground { + color: #444444 !important; } -::-webkit-scrollbar-thumb { - background: color-mix(in oklch, var(--muted-foreground) 30%, transparent); - border-radius: 999px; - border: 2px solid transparent; - background-clip: padding-box; +/* Disable all transitions for that instant Win2k feel */ +*, *::before, *::after { + transition: none !important; + animation-duration: 0s !important; + animation-delay: 0s !important; } diff --git a/app/layout.tsx b/app/layout.tsx index 40ac265..34d7aa2 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -1,19 +1,16 @@ import type { Metadata } from "next"; -import { JetBrains_Mono, Plus_Jakarta_Sans } from "next/font/google"; +import { Cousine } from "next/font/google"; import { AppProviders } from "@/components/providers/app-providers"; import { cn } from "@/lib/utils"; import "./globals.css"; -const plusJakarta = Plus_Jakarta_Sans({ - variable: "--font-jakarta", - subsets: ["latin"], -}); - -const jetBrainsMono = JetBrains_Mono({ +// Cousine is the closest Google Font to Courier/system mono +const cousine = Cousine({ variable: "--font-mono-ui", subsets: ["latin"], + weight: ["400", "700"], }); export const metadata: Metadata = { @@ -35,10 +32,10 @@ export default function RootLayout({ {children} diff --git a/components/dashboard/metrics-chart.tsx b/components/dashboard/metrics-chart.tsx index a7c3c38..1be177a 100644 --- a/components/dashboard/metrics-chart.tsx +++ b/components/dashboard/metrics-chart.tsx @@ -81,12 +81,28 @@ export const MetricsChart = ({ const MetricIcon = metricMeta[metric].icon; return ( - - + +
- {title} - {description} + {title} + {description}
{ null; return ( - - + +
- Node telemetry board - + Node telemetry board + Nodes are shown in groups of four so each telemetry snapshot stays separate and easy to scan. diff --git a/components/dashboard/recent-events-feed.tsx b/components/dashboard/recent-events-feed.tsx index ae80d4e..b22db8d 100644 --- a/components/dashboard/recent-events-feed.tsx +++ b/components/dashboard/recent-events-feed.tsx @@ -25,21 +25,55 @@ export const RecentEventsFeed = ({ events }: { events: EventRecord[] }) => { }; return ( - - - Recent events - + + + Recent events + Alerts, state changes, and task transitions ordered by recency. - +
{events.map((event) => ( { + (e.currentTarget as HTMLElement).style.background = "#000080"; + (e.currentTarget as HTMLElement).style.color = "#ffffff"; + }} + onMouseLeave={(e) => { + (e.currentTarget as HTMLElement).style.background = "#ffffff"; + (e.currentTarget as HTMLElement).style.color = "#000000"; + }} >
diff --git a/components/layout/app-shell.tsx b/components/layout/app-shell.tsx index ff838fb..fdf80ab 100644 --- a/components/layout/app-shell.tsx +++ b/components/layout/app-shell.tsx @@ -16,21 +16,36 @@ export const AppShell = ({ children }: { children: React.ReactNode }) => { useRealtimeBridge(); return ( -
+
-
+
{workspace?.isArchived ? ( -
- -

+

+ +

This workspace is archived. You can still inspect data, but create, update, delete, enrollment, and scheduling actions are read-only until the workspace is restored. diff --git a/components/layout/app-sidebar.tsx b/components/layout/app-sidebar.tsx index 3fae1b6..9d5de26 100644 --- a/components/layout/app-sidebar.tsx +++ b/components/layout/app-sidebar.tsx @@ -173,14 +173,18 @@ const SidebarContent = ({ "flex h-16 items-center gap-3 border-b border-sidebar-border px-5", collapsed && "justify-center px-0", )} + style={{ + background: "linear-gradient(to right, #0a246a, #a6caf0)", + borderBottom: "2px solid #404040", + }} > {!collapsed ? (

-

+

Noderax

-

Operations center

+

Operations center

) : null}
@@ -190,7 +194,10 @@ const SidebarContent = ({ {visibleNavigation.map((group) => (
{!collapsed ? ( -

+

{group.label}

) : null} @@ -332,14 +339,22 @@ const SidebarContent = ({ )} > {!collapsed ? ( -
-

+

+

{workspace ? "Workspace" : "Connection"}

-

+

{workspace?.name ?? realtimeLabels[realtimeStatus]}

-

+

{workspace ? `Timezone ${workspace.defaultTimezone} · ${workspace.currentUserRole ?? "member"} access` : "Select a workspace to scope nodes, tasks, metrics, and events."} @@ -378,9 +393,14 @@ export const AppSidebar = () => { <>

diff --git a/components/layout/topbar.tsx b/components/layout/topbar.tsx index e1ff142..c8029fd 100644 --- a/components/layout/topbar.tsx +++ b/components/layout/topbar.tsx @@ -301,7 +301,15 @@ const TopbarContent = () => { }; return ( -
+
- {/*

Control Center

*/}
-

+

{section}

{statusConfig.label} - • {statusHint} + • {statusHint}
{queuedAlertTone ? (
{queuedAlertTone === "danger" @@ -345,7 +366,10 @@ const TopbarContent = () => {
) : null}
-

+

{sectionDescription}

@@ -355,17 +379,24 @@ const TopbarContent = () => { {workspace ? (
-

+

{workspace.name}

-

+

{workspace.defaultTimezone}

- +
@@ -396,7 +427,7 @@ const TopbarContent = () => {
) : null}
- + { : "Search this page" } className="h-10 pl-10" + style={{ + background: "#ffffff", + border: "2px solid", + borderColor: "#808080 #ffffff #ffffff #808080", + borderRadius: "0", + fontSize: "11px", + color: "#000000", + }} /> {showWorkspaceSearchResults ? ( -
+
{workspaceSearchQuery.isPending ? ( -

+

Searching workspace…

) : searchResults.length ? (
{searchResults.map((group) => (
-

+

{group.label}

{group.hits.map((hit) => (
) : ( -

- No workspace results matched “{deferredSearchQuery}”. +

+ No results matched "{deferredSearchQuery}".

)}
@@ -460,17 +508,26 @@ const TopbarContent = () => { - - {initials} + + {initials}
-

+

{session?.user.name ?? "Operator"}

- +
diff --git a/components/ui/section-panel.tsx b/components/ui/section-panel.tsx index 16aaa53..f06649c 100644 --- a/components/ui/section-panel.tsx +++ b/components/ui/section-panel.tsx @@ -1,4 +1,3 @@ -import { Card, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"; import { cn } from "@/lib/utils"; type SectionPanelProps = { @@ -13,11 +12,6 @@ type SectionPanelProps = { contentClassName?: string; }; -const variants = { - default: "surface-panel", - feature: "surface-feature", -}; - export const SectionPanel = ({ title, description, @@ -32,44 +26,62 @@ export const SectionPanel = ({ const hasHeader = Boolean(title || description || eyebrow || action); return ( - {hasHeader ? ( - -
-
- {eyebrow ? ( -

- {eyebrow} -

- ) : null} - {title ? {title} : null} - {description ? ( - {description} - ) : null} -
- {action ? ( -
{action}
+
+ {eyebrow ? ( +

+ {eyebrow} +

+ ) : null} + {title ? ( +

+ {title} +

+ ) : null} + {description ? ( +

+ {description} +

) : null}
- + {action ? ( +
+ {action} +
+ ) : null} +
) : null}
{children}
-
+
); }; + diff --git a/components/ui/stat-strip.tsx b/components/ui/stat-strip.tsx index 563a364..d5039c1 100644 --- a/components/ui/stat-strip.tsx +++ b/components/ui/stat-strip.tsx @@ -13,12 +13,20 @@ type StatStripItem = { tone?: StatTone; }; -const tones: Record = { - brand: "tone-brand", - success: "tone-success", - warning: "tone-warning", - danger: "tone-danger", - neutral: "tone-neutral", +const toneBg: Record = { + brand: "#d0e8ff", + success: "#d0ffd0", + warning: "#fff0c8", + danger: "#ffd0d0", + neutral: "#d4d0c8", +}; + +const toneColor: Record = { + brand: "#0a246a", + success: "#004400", + warning: "#884400", + danger: "#880000", + neutral: "#000000", }; export const StatStrip = ({ @@ -31,37 +39,103 @@ export const StatStrip = ({
{items.map((item, index) => { const Icon = item.icon; + const tone = item.tone ?? "neutral"; return (
-
-
-

- {item.label} -

-
- {item.value} -
-
+ {/* Win2k title bar */} +
+ + {item.label} + {Icon ? ( -
+ ) : null} +
+ {/* Win2k content area */} +
+
+ {item.value} +
+ {item.description ? ( +

- -

+ {item.description} +

) : null}
- {item.description ? ( -

{item.description}

- ) : null} + {/* Win2k status bar */} +
+ + Ready +
); })}
); +