diff --git a/ui/src/styles/base.css b/ui/src/styles/base.css index 1cfa2e3ef2d..b376d83d244 100644 --- a/ui/src/styles/base.css +++ b/ui/src/styles/base.css @@ -1,54 +1,60 @@ -@import url("https://fonts.googleapis.com/css2?family=Fraunces:opsz,wght@9..144,600;9..144,700&family=JetBrains+Mono:wght@400;500&family=Space+Grotesk:wght@400;500;600;700&display=swap"); +@import url("https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;500&family=Unbounded:wght@400;500;600&family=Work+Sans:wght@400;500;600;700&display=swap"); :root { - --bg: #0a0e14; - --bg-accent: #101826; - --bg-grad-1: #1a2740; - --bg-grad-2: #241626; - --bg-overlay: rgba(255, 255, 255, 0.03); - --bg-glow: rgba(54, 207, 201, 0.08); - --panel: rgba(18, 24, 36, 0.92); - --panel-strong: rgba(24, 32, 46, 0.95); - --chrome: rgba(10, 14, 20, 0.75); - --chrome-strong: rgba(10, 14, 20, 0.82); - --text: rgba(246, 248, 252, 0.95); - --chat-text: rgba(246, 248, 252, 0.88); - --muted: rgba(210, 218, 230, 0.62); - --border: rgba(255, 255, 255, 0.08); - --accent: #ff7a3d; - --accent-2: #36cfc9; - --ok: #1bd98a; + --bg: #0a0f14; + --bg-accent: #111826; + --bg-grad-1: #162031; + --bg-grad-2: #1f2a22; + --bg-overlay: rgba(255, 255, 255, 0.05); + --bg-glow: rgba(245, 159, 74, 0.12); + --panel: rgba(14, 20, 30, 0.88); + --panel-strong: rgba(18, 26, 38, 0.96); + --chrome: rgba(9, 14, 20, 0.72); + --chrome-strong: rgba(9, 14, 20, 0.86); + --text: rgba(244, 246, 251, 0.96); + --chat-text: rgba(231, 237, 244, 0.92); + --muted: rgba(156, 169, 189, 0.72); + --border: rgba(255, 255, 255, 0.09); + --border-strong: rgba(255, 255, 255, 0.16); + --accent: #f59f4a; + --accent-2: #34c7b7; + --ok: #2bd97f; --warn: #f2c94c; - --danger: #ff5c5c; + --danger: #ff6b6b; + --focus: rgba(245, 159, 74, 0.35); + --grid-line: rgba(255, 255, 255, 0.04); --theme-switch-x: 50%; --theme-switch-y: 50%; - --mono: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, + --mono: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; - --font-body: "Space Grotesk", system-ui, sans-serif; - --font-display: "Fraunces", "Times New Roman", serif; + --font-body: "Work Sans", system-ui, sans-serif; + --font-display: "Unbounded", "Times New Roman", serif; color-scheme: dark; } :root[data-theme="light"] { - --bg: #f5f7fb; + --bg: #f5f1ea; --bg-accent: #ffffff; - --bg-grad-1: #e3edf9; - --bg-grad-2: #f7e6f0; - --bg-overlay: rgba(28, 32, 46, 0.04); - --bg-glow: rgba(54, 207, 201, 0.12); + --bg-grad-1: #f1e6d6; + --bg-grad-2: #e5eef4; + --bg-overlay: rgba(28, 32, 46, 0.05); + --bg-glow: rgba(52, 199, 183, 0.14); --panel: rgba(255, 255, 255, 0.9); - --panel-strong: rgba(255, 255, 255, 0.98); - --chrome: rgba(255, 255, 255, 0.72); - --chrome-strong: rgba(255, 255, 255, 0.82); - --text: rgba(20, 24, 36, 0.96); - --chat-text: rgba(20, 24, 36, 0.82); - --muted: rgba(50, 58, 76, 0.6); - --border: rgba(16, 24, 40, 0.12); - --accent: #ff7a3d; - --accent-2: #1bb9b1; - --ok: #15b97a; - --warn: #c58a1a; - --danger: #e84343; + --panel-strong: rgba(255, 255, 255, 0.97); + --chrome: rgba(255, 255, 255, 0.75); + --chrome-strong: rgba(255, 255, 255, 0.88); + --text: rgba(27, 36, 50, 0.98); + --chat-text: rgba(36, 48, 66, 0.9); + --muted: rgba(80, 94, 114, 0.7); + --border: rgba(18, 24, 40, 0.12); + --border-strong: rgba(18, 24, 40, 0.2); + --accent: #e28a3f; + --accent-2: #1ba99d; + --ok: #1aa86c; + --warn: #b3771c; + --danger: #d44848; + --focus: rgba(226, 138, 63, 0.35); + --grid-line: rgba(18, 24, 40, 0.06); color-scheme: light; } @@ -63,16 +69,13 @@ body { body { margin: 0; - font: 15px/1.4 var(--font-body); - background: radial-gradient( - 1200px 900px at 20% 0%, - var(--bg-grad-1) 0%, - var(--bg) 55% - ) + font: 15px/1.5 var(--font-body); + background: + radial-gradient(1200px 900px at 15% -10%, var(--bg-grad-1) 0%, transparent 55%) fixed, - radial-gradient(900px 700px at 90% 10%, var(--bg-grad-2) 0%, transparent 55%) + radial-gradient(900px 700px at 80% 10%, var(--bg-grad-2) 0%, transparent 60%) fixed, - var(--bg); + linear-gradient(160deg, var(--bg) 0%, var(--bg-accent) 100%) fixed; color: var(--text); } @@ -80,16 +83,37 @@ body::before { content: ""; position: fixed; inset: 0; - background: linear-gradient( - 135deg, + background: + linear-gradient( + 140deg, var(--bg-overlay) 0%, - rgba(255, 255, 255, 0) 35% + rgba(255, 255, 255, 0) 40% ), - radial-gradient( - 600px 400px at 80% 80%, - var(--bg-glow), - transparent 60% + radial-gradient(620px 420px at 75% 75%, var(--bg-glow), transparent 60%); + pointer-events: none; + z-index: 0; +} + +body::after { + content: ""; + position: fixed; + inset: 0; + background: + repeating-linear-gradient( + 90deg, + var(--grid-line) 0, + var(--grid-line) 1px, + transparent 1px, + transparent 140px + ), + repeating-linear-gradient( + 0deg, + var(--grid-line) 0, + var(--grid-line) 1px, + transparent 1px, + transparent 140px ); + opacity: 0.45; pointer-events: none; z-index: 0; } @@ -160,3 +184,14 @@ select { transform: translateY(0); } } + +@keyframes dashboard-enter { + from { + opacity: 0; + transform: translateY(12px); + } + to { + opacity: 1; + transform: translateY(0); + } +} diff --git a/ui/src/styles/components.css b/ui/src/styles/components.css index 670ef1d2aca..5a0e155d472 100644 --- a/ui/src/styles/components.css +++ b/ui/src/styles/components.css @@ -1,34 +1,38 @@ .card { border: 1px solid var(--border); - background: var(--panel); - border-radius: 18px; + background: linear-gradient(160deg, rgba(255, 255, 255, 0.04), transparent 65%), + var(--panel); + border-radius: 16px; padding: 16px; - box-shadow: 0 18px 40px rgba(0, 0, 0, 0.25); - animation: rise 0.35s ease; + box-shadow: 0 18px 36px rgba(0, 0, 0, 0.28); + animation: rise 0.4s ease; } .card-title { font-family: var(--font-display); - font-size: 18px; + font-size: 16px; + letter-spacing: 0.6px; + text-transform: uppercase; } .card-sub { color: var(--muted); - font-size: 13px; + font-size: 12px; } .stat { - background: var(--panel-strong); + background: linear-gradient(140deg, rgba(255, 255, 255, 0.04), transparent 70%), + var(--panel-strong); border-radius: 14px; padding: 12px; - border: 1px solid rgba(255, 255, 255, 0.06); + border: 1px solid var(--border-strong); } .stat-label { color: var(--muted); - font-size: 12px; + font-size: 11px; text-transform: uppercase; - letter-spacing: 0.8px; + letter-spacing: 1px; } .stat-value { @@ -51,6 +55,7 @@ .note-title { font-weight: 600; + letter-spacing: 0.2px; } .status-list { @@ -72,19 +77,20 @@ .label { color: var(--muted); - font-size: 12px; + font-size: 11px; text-transform: uppercase; - letter-spacing: 0.6px; + letter-spacing: 0.9px; } .pill { display: inline-flex; align-items: center; gap: 8px; - border: 1px solid var(--border); - padding: 6px 10px; + border: 1px solid var(--border-strong); + padding: 6px 12px; border-radius: 999px; - background: var(--panel); + background: linear-gradient(160deg, rgba(255, 255, 255, 0.06), transparent), + var(--panel); } .theme-toggle { @@ -101,8 +107,8 @@ gap: var(--theme-gap); padding: var(--theme-pad); border-radius: 999px; - border: 1px solid var(--border); - background: rgba(255, 255, 255, 0.02); + border: 1px solid var(--border-strong); + background: rgba(255, 255, 255, 0.04); } .theme-toggle__indicator { @@ -114,10 +120,12 @@ border-radius: 999px; transform: translateY(-50%) translateX(calc(var(--theme-index, 0) * (var(--theme-item) + var(--theme-gap)))); - background: var(--panel-strong); - border: 1px solid var(--border); - box-shadow: 0 8px 18px rgba(0, 0, 0, 0.25); - transition: transform 180ms ease-out, background 180ms ease-out; + background: linear-gradient(160deg, rgba(255, 255, 255, 0.12), transparent), + var(--panel-strong); + border: 1px solid var(--border-strong); + box-shadow: 0 8px 16px rgba(0, 0, 0, 0.25); + transition: transform 180ms ease-out, background 180ms ease-out, + box-shadow 180ms ease-out; z-index: 0; } @@ -170,28 +178,31 @@ .statusDot.ok { background: var(--ok); + box-shadow: 0 0 0 2px rgba(0, 0, 0, 0.25), 0 0 10px rgba(43, 217, 127, 0.4); } .btn { - border: 1px solid var(--border); + border: 1px solid var(--border-strong); background: rgba(255, 255, 255, 0.04); - padding: 8px 12px; - border-radius: 10px; + padding: 8px 14px; + border-radius: 999px; cursor: pointer; + transition: transform 150ms ease, border-color 150ms ease, background 150ms ease; } .btn:hover { - background: rgba(255, 255, 255, 0.08); + background: rgba(255, 255, 255, 0.1); + transform: translateY(-1px); } .btn.primary { - border-color: rgba(255, 122, 61, 0.35); - background: rgba(255, 122, 61, 0.18); + border-color: rgba(245, 159, 74, 0.45); + background: rgba(245, 159, 74, 0.2); } .btn.danger { - border-color: rgba(255, 92, 92, 0.4); - background: rgba(255, 92, 92, 0.16); + border-color: rgba(255, 107, 107, 0.45); + background: rgba(255, 107, 107, 0.18); } .field { @@ -201,17 +212,28 @@ .field span { color: var(--muted); - font-size: 12px; + font-size: 11px; + letter-spacing: 0.4px; } .field input, .field textarea, .field select { - border: 1px solid var(--border); - background: rgba(0, 0, 0, 0.3); - border-radius: 10px; - padding: 8px 10px; + border: 1px solid var(--border-strong); + background: rgba(0, 0, 0, 0.22); + border-radius: 12px; + padding: 9px 11px; outline: none; + transition: border-color 150ms ease, box-shadow 150ms ease, + background 150ms ease; +} + +.field input:focus, +.field textarea:focus, +.field select:focus { + border-color: var(--accent); + box-shadow: 0 0 0 3px var(--focus); + background: rgba(0, 0, 0, 0.28); } .field select { @@ -238,6 +260,10 @@ white-space: pre; } +.field textarea:focus { + background: rgba(0, 0, 0, 0.32); +} + .field.checkbox { grid-template-columns: auto 1fr; align-items: center; @@ -249,6 +275,19 @@ grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); } +:root[data-theme="light"] .field input, +:root[data-theme="light"] .field textarea, +:root[data-theme="light"] .field select { + background: rgba(255, 255, 255, 0.9); + border-color: var(--border-strong); +} + +:root[data-theme="light"] .field input:focus, +:root[data-theme="light"] .field textarea:focus, +:root[data-theme="light"] .field select:focus { + background: #ffffff; +} + .muted { color: var(--muted); } @@ -259,9 +298,10 @@ .callout { padding: 10px 12px; - border-radius: 12px; - background: rgba(255, 255, 255, 0.05); - border: 1px solid rgba(255, 255, 255, 0.08); + border-radius: 14px; + background: linear-gradient(160deg, rgba(255, 255, 255, 0.06), transparent), + rgba(255, 255, 255, 0.03); + border: 1px solid var(--border); } .callout.danger { @@ -274,12 +314,19 @@ font-size: 12px; background: rgba(0, 0, 0, 0.35); padding: 10px; - border-radius: 10px; - border: 1px solid rgba(255, 255, 255, 0.06); + border-radius: 12px; + border: 1px solid var(--border); max-height: 360px; overflow: auto; } +:root[data-theme="light"] .code-block, +:root[data-theme="light"] .list-item, +:root[data-theme="light"] .table-row, +:root[data-theme="light"] .chip { + background: rgba(255, 255, 255, 0.85); +} + .list { display: grid; gap: 12px; @@ -308,13 +355,13 @@ .list-sub { color: var(--muted); - font-size: 13px; + font-size: 12px; } .list-meta { text-align: right; color: var(--muted); - font-size: 12px; + font-size: 11px; display: grid; gap: 4px; min-width: 220px; @@ -333,7 +380,7 @@ } .chip { - font-size: 12px; + font-size: 11px; border: 1px solid var(--border); border-radius: 999px; padding: 4px 8px; @@ -365,7 +412,7 @@ } .table-head { - font-size: 12px; + font-size: 11px; text-transform: uppercase; letter-spacing: 0.8px; color: var(--muted); @@ -414,11 +461,11 @@ padding: 14px 12px; min-width: 0; border-radius: 16px; - border: 1px solid rgba(255, 255, 255, 0.08); + border: 1px solid var(--border); background: linear-gradient( 180deg, - rgba(0, 0, 0, 0.18) 0%, - rgba(0, 0, 0, 0.26) 100% + rgba(0, 0, 0, 0.2) 0%, + rgba(0, 0, 0, 0.3) 100% ); } @@ -457,10 +504,10 @@ .chat-bubble { border: 1px solid var(--border); background: rgba(0, 0, 0, 0.24); - border-radius: 18px; + border-radius: 16px; padding: 10px 12px; min-width: 0; - box-shadow: 0 12px 26px rgba(0, 0, 0, 0.22); + box-shadow: 0 12px 22px rgba(0, 0, 0, 0.24); } :root[data-theme="light"] .chat-bubble { @@ -469,20 +516,20 @@ } .chat-line.user .chat-bubble { - border-color: rgba(255, 122, 61, 0.35); + border-color: rgba(245, 159, 74, 0.45); background: linear-gradient( 135deg, - rgba(255, 122, 61, 0.24) 0%, - rgba(255, 122, 61, 0.12) 100% + rgba(245, 159, 74, 0.26) 0%, + rgba(245, 159, 74, 0.12) 100% ); } .chat-line.assistant .chat-bubble { - border-color: rgba(54, 207, 201, 0.16); + border-color: rgba(52, 199, 183, 0.2); background: linear-gradient( 135deg, - rgba(54, 207, 201, 0.08) 0%, - rgba(0, 0, 0, 0.22) 100% + rgba(52, 199, 183, 0.12) 0%, + rgba(0, 0, 0, 0.24) 100% ); } @@ -496,18 +543,18 @@ @keyframes chatStreamPulse { 0% { - box-shadow: 0 12px 26px rgba(0, 0, 0, 0.22), 0 0 0 0 rgba(54, 207, 201, 0); + box-shadow: 0 12px 22px rgba(0, 0, 0, 0.24), 0 0 0 0 rgba(52, 199, 183, 0); } 60% { - box-shadow: 0 12px 26px rgba(0, 0, 0, 0.22), 0 0 0 6px rgba(54, 207, 201, 0.06); + box-shadow: 0 12px 22px rgba(0, 0, 0, 0.24), 0 0 0 6px rgba(52, 199, 183, 0.08); } 100% { - box-shadow: 0 12px 26px rgba(0, 0, 0, 0.22), 0 0 0 0 rgba(54, 207, 201, 0); + box-shadow: 0 12px 22px rgba(0, 0, 0, 0.24), 0 0 0 0 rgba(52, 199, 183, 0); } } .chat-bubble.streaming { - border-color: rgba(54, 207, 201, 0.32); + border-color: rgba(52, 199, 183, 0.4); animation: chatStreamPulse 1.6s ease-in-out infinite; } @@ -548,7 +595,7 @@ .chat-compose__field textarea { min-height: 72px; padding: 10px 12px; - border-radius: 14px; + border-radius: 16px; resize: vertical; white-space: pre-wrap; font-family: var(--font-body); @@ -579,7 +626,7 @@ margin-top: 12px; border-radius: 14px; background: rgba(0, 0, 0, 0.2); - border: 1px dashed rgba(255, 255, 255, 0.12); + border: 1px dashed rgba(255, 255, 255, 0.18); padding: 12px; display: inline-flex; } diff --git a/ui/src/styles/layout.css b/ui/src/styles/layout.css index 1a81fa7769c..45e7073ec1c 100644 --- a/ui/src/styles/layout.css +++ b/ui/src/styles/layout.css @@ -1,11 +1,14 @@ .shell { min-height: 100vh; display: grid; - grid-template-columns: 240px 1fr; + grid-template-columns: minmax(220px, 280px) minmax(0, 1fr); grid-template-rows: auto 1fr; grid-template-areas: "topbar topbar" "nav content"; + gap: 18px; + padding: 18px; + animation: dashboard-enter 0.6s ease-out; } .topbar { @@ -13,21 +16,31 @@ display: flex; justify-content: space-between; align-items: center; - padding: 18px 24px; - border-bottom: 1px solid var(--border); - background: var(--chrome); - backdrop-filter: blur(16px); + padding: 16px 20px; + border: 1px solid var(--border); + border-radius: 18px; + background: linear-gradient(135deg, var(--chrome), rgba(255, 255, 255, 0.02)); + backdrop-filter: blur(18px); + box-shadow: 0 18px 40px rgba(0, 0, 0, 0.28); +} + +.brand { + display: grid; + gap: 4px; } .brand-title { font-family: var(--font-display); - font-size: 22px; - letter-spacing: 0.4px; + font-size: 20px; + letter-spacing: 0.6px; + text-transform: uppercase; } .brand-sub { color: var(--muted); - font-size: 13px; + font-size: 12px; + letter-spacing: 1.2px; + text-transform: uppercase; } .topbar-status { @@ -38,49 +51,87 @@ .nav { grid-area: nav; - padding: 18px 16px; - border-right: 1px solid var(--border); - background: var(--chrome-strong); + padding: 16px; + border: 1px solid var(--border); + border-radius: 20px; + background: var(--panel); + box-shadow: 0 18px 40px rgba(0, 0, 0, 0.25); + backdrop-filter: blur(18px); } .nav-group { margin-bottom: 18px; display: grid; gap: 6px; + padding-bottom: 12px; + border-bottom: 1px dashed rgba(255, 255, 255, 0.08); +} + +.nav-group:last-child { + margin-bottom: 0; + padding-bottom: 0; + border-bottom: none; } .nav-label { - font-size: 11px; + font-size: 10px; text-transform: uppercase; - letter-spacing: 1.4px; + letter-spacing: 1.6px; color: var(--muted); } .nav-item { + position: relative; display: flex; align-items: center; justify-content: space-between; gap: 10px; - padding: 9px 12px; + padding: 10px 12px 10px 14px; border-radius: 12px; border: 1px solid transparent; - background: rgba(255, 255, 255, 0.03); + background: rgba(255, 255, 255, 0.02); color: var(--muted); cursor: pointer; + transition: border-color 160ms ease, background 160ms ease, color 160ms ease, + transform 160ms ease; +} + +.nav-item:hover { + color: var(--text); + border-color: rgba(255, 255, 255, 0.12); + background: rgba(255, 255, 255, 0.06); +} + +.nav-item::before { + content: ""; + position: absolute; + left: 6px; + top: 50%; + width: 4px; + height: 60%; + border-radius: 999px; + transform: translateY(-50%); + background: transparent; } .nav-item.active { color: var(--text); - border-color: rgba(255, 122, 61, 0.45); - background: rgba(255, 122, 61, 0.14); + border-color: rgba(245, 159, 74, 0.45); + background: rgba(245, 159, 74, 0.16); + transform: translateX(2px); +} + +.nav-item.active::before { + background: var(--accent); + box-shadow: 0 0 12px rgba(245, 159, 74, 0.4); } .content { grid-area: content; - padding: 24px 28px 32px; + padding: 8px 6px 20px; display: flex; flex-direction: column; - gap: 18px; + gap: 20px; } .content-header { @@ -88,17 +139,19 @@ align-items: flex-end; justify-content: space-between; gap: 12px; + padding: 0 6px; } .page-title { font-family: var(--font-display); - font-size: 24px; - letter-spacing: 0.4px; + font-size: 26px; + letter-spacing: 0.6px; } .page-sub { color: var(--muted); - font-size: 13px; + font-size: 12px; + letter-spacing: 0.4px; } .page-meta { @@ -108,7 +161,7 @@ .grid { display: grid; - gap: 16px; + gap: 18px; } .grid-cols-2 { @@ -121,13 +174,13 @@ .stat-grid { display: grid; - gap: 12px; + gap: 14px; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); } .note-grid { display: grid; - gap: 12px; + gap: 14px; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); } @@ -139,13 +192,13 @@ .stack { display: grid; - gap: 12px; + gap: 14px; } .filters { display: flex; flex-wrap: wrap; - gap: 12px; + gap: 10px; align-items: center; } @@ -157,6 +210,7 @@ "topbar" "nav" "content"; + padding: 12px; } .nav { @@ -164,12 +218,14 @@ gap: 16px; overflow-x: auto; border-right: none; - border-bottom: 1px solid var(--border); + padding: 12px; } .nav-group { grid-auto-flow: column; grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); + border-bottom: none; + padding-bottom: 0; } .grid-cols-2,