diff --git a/core/http/static/components.css b/core/http/static/components.css
index 1ede88093..4abcc6ce6 100644
--- a/core/http/static/components.css
+++ b/core/http/static/components.css
@@ -418,6 +418,337 @@ textarea.input-success {
animation: nodeGlow 3s ease-in-out infinite;
}
+/* ============================================
+ Sidebar Navigation
+ ============================================ */
+.sidebar {
+ position: fixed;
+ top: 0;
+ left: 0;
+ bottom: 0;
+ width: var(--sidebar-width);
+ background: var(--sidebar-bg);
+ border-right: 1px solid var(--sidebar-border);
+ box-shadow: var(--shadow-sidebar);
+ display: flex;
+ flex-direction: column;
+ z-index: 40;
+ transition: transform var(--duration-normal) var(--ease-default);
+}
+
+.sidebar-header {
+ padding: 1rem 1.25rem;
+ border-bottom: 1px solid var(--color-border-divider);
+ position: relative;
+}
+
+.sidebar-logo {
+ display: flex;
+ align-items: center;
+ gap: 0.75rem;
+ text-decoration: none;
+}
+
+.sidebar-logo img {
+ height: 2rem;
+ width: auto;
+}
+
+.sidebar-logo-text {
+ font-family: var(--font-body);
+ font-size: var(--text-lg);
+ font-weight: var(--weight-semibold);
+ color: var(--color-text-primary);
+ letter-spacing: -0.02em;
+}
+
+.sidebar-content {
+ flex: 1;
+ overflow-y: auto;
+ overflow-x: hidden;
+ padding: 0.75rem 0;
+}
+
+.sidebar-section {
+ padding: 0.25rem 0;
+}
+
+.sidebar-section-title {
+ font-family: var(--font-body);
+ font-size: var(--text-xs);
+ font-weight: var(--weight-medium);
+ color: var(--color-text-muted);
+ text-transform: uppercase;
+ letter-spacing: 0.05em;
+ padding: 0.75rem 1.25rem 0.25rem;
+ margin-bottom: 0;
+}
+
+.nav-item {
+ display: flex;
+ align-items: center;
+ gap: 0.75rem;
+ padding: 0.625rem 1.25rem;
+ margin: 0;
+ border-radius: 0;
+ color: var(--color-text-secondary);
+ text-decoration: none;
+ font-family: var(--font-body);
+ font-size: var(--text-sm);
+ font-weight: var(--weight-normal);
+ transition: all var(--duration-fast) var(--ease-default);
+ cursor: pointer;
+ border: none;
+ background: transparent;
+ width: 100%;
+ text-align: left;
+ border-left: 3px solid transparent;
+ position: relative;
+}
+
+.nav-item:hover {
+ background: var(--color-bg-secondary);
+ color: var(--color-text-primary);
+ border-left-color: var(--color-primary);
+}
+
+.nav-item.active {
+ background: var(--color-primary-light);
+ color: var(--color-primary);
+ font-weight: var(--weight-medium);
+ border-left-color: var(--color-primary);
+}
+
+.nav-item i,
+.nav-item .nav-icon {
+ width: 1.25rem;
+ text-align: center;
+ font-size: var(--text-base);
+ flex-shrink: 0;
+}
+
+.nav-item .nav-label {
+ flex: 1;
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
+
+.nav-item .nav-chevron {
+ font-size: var(--text-xs);
+ transition: transform var(--duration-fast) var(--ease-default);
+ margin-left: auto;
+}
+
+.nav-item.expanded .nav-chevron {
+ transform: rotate(180deg);
+}
+
+/* Dropdown submenu */
+.nav-submenu {
+ max-height: 0;
+ overflow: hidden;
+ transition: max-height var(--duration-normal) var(--ease-default);
+}
+
+.nav-submenu.open {
+ max-height: 300px;
+}
+
+.nav-submenu .nav-item {
+ padding-left: 2.75rem;
+ font-size: var(--text-xs);
+}
+
+.nav-submenu .nav-item i,
+.nav-submenu .nav-item .nav-icon {
+ width: 1rem;
+ font-size: var(--text-xs);
+}
+
+/* Sidebar footer with theme toggle */
+.sidebar-footer {
+ padding: 0.75rem;
+ border-top: 1px solid var(--color-border-divider);
+}
+
+.theme-toggle {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ padding: 0.625rem 0.875rem;
+ margin: 0.125rem 0.5rem;
+ border-radius: var(--radius-md);
+ background: var(--color-bg-secondary);
+ border: 1px solid var(--color-border-subtle);
+}
+
+.theme-toggle-label {
+ display: flex;
+ align-items: center;
+ gap: 0.5rem;
+ font-family: var(--font-body);
+ font-size: var(--text-xs);
+ color: var(--color-text-secondary);
+}
+
+.theme-toggle-label i {
+ font-size: var(--text-sm);
+}
+
+/* Toggle switch */
+.toggle-switch {
+ position: relative;
+ width: 2.5rem;
+ height: 1.375rem;
+ background: var(--color-bg-primary);
+ border-radius: var(--radius-full);
+ cursor: pointer;
+ transition: background-color var(--duration-fast) var(--ease-default);
+}
+
+.toggle-switch::after {
+ content: '';
+ position: absolute;
+ top: 2px;
+ left: 2px;
+ width: 1.125rem;
+ height: 1.125rem;
+ background: var(--color-text-secondary);
+ border-radius: var(--radius-full);
+ transition: all var(--duration-fast) var(--ease-default);
+}
+
+.toggle-switch.active {
+ background: var(--color-primary);
+}
+
+.toggle-switch.active::after {
+ transform: translateX(1.125rem);
+ background: white;
+}
+
+/* Mobile overlay */
+.sidebar-overlay {
+ position: fixed;
+ inset: 0;
+ background: rgba(0, 0, 0, 0.5);
+ z-index: 35;
+ opacity: 0;
+ visibility: hidden;
+ transition: opacity var(--duration-normal) var(--ease-default),
+ visibility var(--duration-normal) var(--ease-default);
+}
+
+.sidebar-overlay.open {
+ opacity: 1;
+ visibility: visible;
+}
+
+/* Mobile menu button */
+.mobile-menu-btn {
+ display: none;
+ position: fixed;
+ top: 1rem;
+ left: 1rem;
+ z-index: 50;
+ width: 2.5rem;
+ height: 2.5rem;
+ background: var(--color-bg-secondary);
+ border: none;
+ border-radius: var(--radius-full);
+ color: var(--color-text-secondary);
+ cursor: pointer;
+ transition: all var(--duration-fast) var(--ease-default);
+ box-shadow: var(--shadow-sm);
+}
+
+.mobile-menu-btn:hover {
+ background: var(--color-bg-primary);
+ color: var(--color-primary);
+ transform: scale(1.05);
+}
+
+.mobile-menu-btn:active {
+ transform: scale(0.95);
+}
+
+/* Hide menu button when sidebar is open */
+.mobile-menu-btn[style*="opacity: 0"] {
+ pointer-events: none;
+}
+
+/* Mobile close button inside sidebar */
+.sidebar-close-btn {
+ display: none;
+ position: absolute;
+ top: 1rem;
+ right: 1rem;
+ width: 2rem;
+ height: 2rem;
+ background: transparent;
+ border: none;
+ border-radius: var(--radius-md);
+ color: var(--color-text-secondary);
+ cursor: pointer;
+ transition: all var(--duration-fast) var(--ease-default);
+}
+
+.sidebar-close-btn:hover {
+ background: var(--color-bg-primary);
+ color: var(--color-text-primary);
+}
+
+/* ============================================
+ Tables
+ ============================================ */
+table {
+ width: 100%;
+ border-collapse: collapse;
+ background: var(--color-bg-secondary);
+ color: var(--color-text-primary);
+}
+
+thead {
+ background: var(--color-bg-primary);
+}
+
+thead tr {
+ border-bottom: 1px solid var(--color-border-subtle);
+}
+
+th {
+ text-align: left;
+ padding: 0.5rem;
+ font-size: var(--text-xs);
+ font-weight: var(--weight-semibold);
+ color: var(--color-text-primary);
+ border-bottom: 1px solid var(--color-border-subtle);
+}
+
+tbody tr {
+ border-bottom: 1px solid var(--color-border-subtle);
+ transition: background-color var(--duration-fast) var(--ease-default);
+}
+
+tbody tr:hover {
+ background: var(--color-bg-primary);
+}
+
+td {
+ padding: 0.5rem;
+ font-size: var(--text-xs);
+ color: var(--color-text-primary);
+}
+
+/* Table container */
+.table-container {
+ background: var(--color-bg-secondary);
+ border-radius: var(--radius-xl);
+ border: 1px solid var(--color-border-subtle);
+ overflow: hidden;
+}
+
/* ============================================
Responsive Adjustments
============================================ */
@@ -439,3 +770,36 @@ textarea.input-success {
}
}
+/* Tablet and mobile - sidebar becomes overlay */
+@media (max-width: 1023px) {
+ .mobile-menu-btn {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ }
+
+ .sidebar {
+ transform: translateX(-100%);
+ z-index: 45;
+ }
+
+ .sidebar.open {
+ transform: translateX(0);
+ }
+
+ .sidebar-close-btn {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ }
+
+ .sidebar-header {
+ padding-right: 3rem;
+ }
+
+ .sidebar-overlay.open + .sidebar,
+ .sidebar.open {
+ transform: translateX(0);
+ }
+}
+
diff --git a/core/http/static/general.css b/core/http/static/general.css
index f0de5397a..3bfd63d31 100644
--- a/core/http/static/general.css
+++ b/core/http/static/general.css
@@ -1,6 +1,49 @@
+/* Layout Structure */
+html {
+ height: 100%;
+}
+
body {
font-family: var(--font-body, 'Space Grotesk', -apple-system, BlinkMacSystemFont, sans-serif);
+ margin: 0;
+ padding: 0;
+ min-height: 100%;
+ background-color: var(--color-bg-primary);
+ color: var(--color-text-primary);
+ transition: background-color var(--duration-normal) var(--ease-default),
+ color var(--duration-normal) var(--ease-default);
}
+
+.app-layout {
+ display: flex;
+ min-height: 100vh;
+ background-color: var(--color-bg-primary);
+}
+
+.main-content {
+ flex: 1;
+ margin-left: var(--sidebar-width);
+ min-height: 100vh;
+ display: flex;
+ flex-direction: column;
+ background-color: var(--color-bg-primary);
+ transition: margin-left var(--duration-normal) var(--ease-default);
+}
+
+.main-content-inner {
+ flex: 1;
+ display: flex;
+ flex-direction: column;
+ background-color: var(--color-bg-primary);
+}
+
+/* Tablet and mobile */
+@media (max-width: 1023px) {
+ .main-content {
+ margin-left: 0;
+ }
+}
+
.chat-container { height: 90vh; display: flex; flex-direction: column; }
.chat-messages { overflow-y: auto; flex-grow: 1; }
.htmx-indicator{
diff --git a/core/http/static/theme.css b/core/http/static/theme.css
index 229987b33..c7f891b53 100644
--- a/core/http/static/theme.css
+++ b/core/http/static/theme.css
@@ -1,12 +1,18 @@
/* LocalAI Theme - CSS Variables System */
/* Based on logo color palette: cyan, teal, navy, purple */
-:root {
- /* Base Colors */
- --color-bg-primary: #0F172A; /* Deep navy background */
- --color-bg-secondary: #1E293B; /* Elevated surfaces */
- --color-bg-tertiary: #1E293B; /* Cards, panels */
- --color-bg-overlay: rgba(15, 23, 42, 0.8); /* Modals, overlays */
+/* Dark Theme (Default) - Charcoal Gray Style */
+:root,
+[data-theme="dark"],
+.dark {
+ /* Base Colors - Charcoal Gray */
+ --color-bg-primary: #121212; /* Main background */
+ --color-bg-secondary: #1A1A1A; /* Elevated surfaces */
+ --color-bg-tertiary: #222222; /* Cards, panels */
+ --color-bg-overlay: rgba(18, 18, 18, 0.95); /* Modals, overlays */
+
+ /* Override tw-elements dark background */
+ background-color: #121212 !important;
/* Brand Colors */
--color-primary: #38BDF8; /* Cyan - primary actions */
@@ -32,16 +38,16 @@
--color-text-secondary: #94A3B8; /* Secondary text */
--color-text-muted: #64748B; /* Tertiary text */
--color-text-disabled: #475569; /* Disabled text */
- --color-text-inverse: #0F172A; /* Text on light backgrounds */
+ --color-text-inverse: #FFFFFF; /* Text on light backgrounds */
- /* Border Colors - Minimal System */
- --color-border-subtle: rgba(148, 163, 184, 0.08); /* Minimal borders */
- --color-border-default: rgba(148, 163, 184, 0.12); /* Default borders */
- --color-border-strong: rgba(56, 189, 248, 0.2); /* Focus borders */
- --color-border-divider: rgba(148, 163, 184, 0.06); /* Section dividers */
- --color-border-primary: rgba(56, 189, 248, 0.15); /* Primary borders (reduced opacity) */
- --color-border-secondary: rgba(148, 163, 184, 0.1);
- --color-border-focus: rgba(56, 189, 248, 0.3); /* Focus borders (reduced) */
+ /* Border Colors - Visible on charcoal */
+ --color-border-subtle: rgba(255, 255, 255, 0.08); /* Minimal borders */
+ --color-border-default: rgba(255, 255, 255, 0.12); /* Default borders */
+ --color-border-strong: rgba(56, 189, 248, 0.3); /* Focus borders */
+ --color-border-divider: rgba(255, 255, 255, 0.05); /* Section dividers */
+ --color-border-primary: rgba(56, 189, 248, 0.2); /* Primary borders */
+ --color-border-secondary: rgba(255, 255, 255, 0.1);
+ --color-border-focus: rgba(56, 189, 248, 0.4); /* Focus borders */
/* Status Colors */
--color-success: #14B8A6; /* Use teal for success (aligned with logo) */
@@ -55,17 +61,18 @@
/* Gradient Definitions */
--gradient-primary: linear-gradient(135deg, #38BDF8 0%, #8B5CF6 50%, #14B8A6 100%);
- --gradient-hero: linear-gradient(135deg, #0F172A 0%, #1E293B 50%, #0F172A 100%);
- --gradient-card: linear-gradient(135deg, rgba(56, 189, 248, 0.05) 0%, rgba(139, 92, 246, 0.05) 100%);
+ --gradient-hero: linear-gradient(135deg, #121212 0%, #1A1A1A 50%, #121212 100%);
+ --gradient-card: linear-gradient(135deg, rgba(56, 189, 248, 0.04) 0%, rgba(139, 92, 246, 0.04) 100%);
--gradient-text: linear-gradient(135deg, #38BDF8 0%, #8B5CF6 50%, #14B8A6 100%);
- /* Shadows - Minimal System */
+ /* Shadows - Charcoal theme */
--shadow-none: none;
- --shadow-subtle: 0 1px 2px rgba(0, 0, 0, 0.1);
- --shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.12);
- --shadow-md: 0 4px 6px rgba(0, 0, 0, 0.1);
- --shadow-lg: 0 10px 15px rgba(0, 0, 0, 0.1);
- --shadow-glow: 0 0 0 1px rgba(56, 189, 248, 0.1), 0 0 8px rgba(56, 189, 248, 0.15); /* Minimal glow */
+ --shadow-subtle: 0 1px 2px rgba(0, 0, 0, 0.2);
+ --shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.25);
+ --shadow-md: 0 4px 6px rgba(0, 0, 0, 0.3);
+ --shadow-lg: 0 10px 15px rgba(0, 0, 0, 0.35);
+ --shadow-glow: 0 0 0 1px rgba(56, 189, 248, 0.15), 0 0 12px rgba(56, 189, 248, 0.2);
+ --shadow-sidebar: 1px 0 3px rgba(0, 0, 0, 0.25);
/* Animation Timing - Minimal */
--duration-instant: 100ms;
@@ -109,5 +116,83 @@
--width-5xl: 64rem; /* 1024px */
--width-6xl: 72rem; /* 1152px */
--width-7xl: 80rem; /* 1280px */
+
+ /* Sidebar */
+ --sidebar-width: 220px;
+ --sidebar-bg: var(--color-bg-primary);
+ --sidebar-border: var(--color-border-subtle);
+}
+
+/* Light Theme */
+[data-theme="light"] {
+ /* Base Colors */
+ --color-bg-primary: #F8FAFC; /* Soft gray background */
+ --color-bg-secondary: #FFFFFF; /* Elevated surfaces */
+ --color-bg-tertiary: #FFFFFF; /* Cards, panels */
+ --color-bg-overlay: rgba(248, 250, 252, 0.9); /* Modals, overlays */
+
+ /* Brand Colors - Slightly adjusted for light backgrounds */
+ --color-primary: #0EA5E9; /* Slightly darker cyan for better contrast */
+ --color-primary-hover: #0284C7; /* Darker on hover */
+ --color-primary-active: #0369A1; /* Active state */
+ --color-primary-text: #FFFFFF; /* Text on primary background */
+ --color-primary-light: rgba(14, 165, 233, 0.08); /* Light cyan backgrounds */
+ --color-primary-border: rgba(14, 165, 233, 0.2); /* Cyan borders */
+
+ --color-secondary: #0D9488; /* Teal - secondary actions */
+ --color-secondary-hover: #0F766E; /* Darker teal on hover */
+ --color-secondary-light: rgba(13, 148, 136, 0.1);
+
+ --color-accent: #7C3AED; /* Purple - special states */
+ --color-accent-hover: #6D28D9; /* Darker purple on hover */
+ --color-accent-light: rgba(124, 58, 237, 0.1);
+
+ --color-accent-purple: #A78BFA; /* Light purple for gradients */
+ --color-accent-teal: #2DD4BF; /* Light teal for gradients */
+
+ /* Text Colors */
+ --color-text-primary: #1E293B; /* Primary text - dark slate */
+ --color-text-secondary: #64748B; /* Secondary text */
+ --color-text-muted: #94A3B8; /* Tertiary text */
+ --color-text-disabled: #CBD5E1; /* Disabled text */
+ --color-text-inverse: #FFFFFF; /* Text on dark backgrounds */
+
+ /* Border Colors */
+ --color-border-subtle: rgba(15, 23, 42, 0.06); /* Minimal borders */
+ --color-border-default: rgba(15, 23, 42, 0.1); /* Default borders */
+ --color-border-strong: rgba(14, 165, 233, 0.3); /* Focus borders */
+ --color-border-divider: rgba(15, 23, 42, 0.04); /* Section dividers */
+ --color-border-primary: rgba(14, 165, 233, 0.2); /* Primary borders */
+ --color-border-secondary: rgba(15, 23, 42, 0.08);
+ --color-border-focus: rgba(14, 165, 233, 0.4); /* Focus borders */
+
+ /* Status Colors - Adjusted for light theme */
+ --color-success: #0D9488;
+ --color-success-light: rgba(13, 148, 136, 0.1);
+ --color-warning: #D97706;
+ --color-warning-light: rgba(217, 119, 6, 0.1);
+ --color-error: #DC2626;
+ --color-error-light: rgba(220, 38, 38, 0.1);
+ --color-info: #0EA5E9;
+ --color-info-light: rgba(14, 165, 233, 0.1);
+
+ /* Gradient Definitions */
+ --gradient-primary: linear-gradient(135deg, #0EA5E9 0%, #7C3AED 50%, #0D9488 100%);
+ --gradient-hero: linear-gradient(135deg, #F8FAFC 0%, #FFFFFF 50%, #F8FAFC 100%);
+ --gradient-card: linear-gradient(135deg, rgba(14, 165, 233, 0.03) 0%, rgba(124, 58, 237, 0.03) 100%);
+ --gradient-text: linear-gradient(135deg, #0EA5E9 0%, #7C3AED 50%, #0D9488 100%);
+
+ /* Shadows - More visible in light theme */
+ --shadow-none: none;
+ --shadow-subtle: 0 1px 2px rgba(0, 0, 0, 0.05);
+ --shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.08);
+ --shadow-md: 0 4px 6px rgba(0, 0, 0, 0.07);
+ --shadow-lg: 0 10px 15px rgba(0, 0, 0, 0.08);
+ --shadow-glow: 0 0 0 1px rgba(14, 165, 233, 0.15), 0 0 8px rgba(14, 165, 233, 0.2);
+ --shadow-sidebar: 1px 0 3px rgba(0, 0, 0, 0.08);
+
+ /* Sidebar */
+ --sidebar-bg: #FFFFFF;
+ --sidebar-border: rgba(15, 23, 42, 0.06);
}
diff --git a/core/http/views/404.html b/core/http/views/404.html
index c5961f286..2ac69b9e3 100644
--- a/core/http/views/404.html
+++ b/core/http/views/404.html
@@ -2,30 +2,31 @@
{{template "views/partials/head" .}}
-
-
-
- {{template "views/partials/navbar" .}}
+
+
+ {{template "views/partials/navbar" .}}
+
+
+
-
-
+
-
+
404 - Page Not Found
-
The page you're looking for doesn't exist or has been moved
+
The page you're looking for doesn't exist or has been moved
-
-
+
{{template "views/partials/footer" .}}
+
+
diff --git a/core/http/views/agent-job-details.html b/core/http/views/agent-job-details.html
index 2b7d6516e..82a30be57 100644
--- a/core/http/views/agent-job-details.html
+++ b/core/http/views/agent-job-details.html
@@ -2,10 +2,12 @@
{{template "views/partials/head" .}}
-
-
-
- {{template "views/partials/navbar" .}}
+
+
+ {{template "views/partials/navbar" .}}
+
+
+
@@ -17,7 +19,7 @@
Live job status, reasoning traces, and execution details
-
+
Back to Jobs
@@ -26,7 +28,7 @@
-
Job Status
+
Job Status
-
-
+
+
-
-
+
+
-
Agent Prompt Template
-
The original prompt template from the task definition.
-
+
Agent Prompt Template
+
The original prompt template from the task definition.
+
-
-
Cron Parameters
-
Parameters configured for cron-triggered executions of this task.
-
+
+
Cron Parameters
+
Parameters configured for cron-triggered executions of this task.
+
-
-
Job Parameters
-
Parameters used for this specific job execution.
-
+
+
Job Parameters
+
Parameters used for this specific job execution.
+
-
Rendered Job Prompt
-
The prompt with parameters substituted, as it was sent to the agent.
-
+
Rendered Job Prompt
+
The prompt with parameters substituted, as it was sent to the agent.
+
-
-
Result
-
+
@@ -115,18 +117,18 @@
-
-
Execution Traces
-
+
+
Execution Traces
+
No execution traces available yet. Traces will appear here as the job executes.
-
+
-
-
@@ -151,16 +153,16 @@
-
-
Webhook Status
+
+
Webhook Status
-
+
-
-
+
@@ -320,7 +322,9 @@
}
}
+ {{template "views/partials/footer" .}}
+
+
-
-
+
\ No newline at end of file
diff --git a/core/http/views/agent-jobs.html b/core/http/views/agent-jobs.html
index a439f6bd2..2762bf29d 100644
--- a/core/http/views/agent-jobs.html
+++ b/core/http/views/agent-jobs.html
@@ -3,9 +3,11 @@
{{template "views/partials/head" .}}
-
-
- {{template "views/partials/navbar" .}}
+
+ {{template "views/partials/navbar" .}}
+
+
+
@@ -140,13 +142,13 @@
-
-
-
+
\ No newline at end of file
diff --git a/core/http/views/agent-task-details.html b/core/http/views/agent-task-details.html
index e3c257ef7..80d2b0de8 100644
--- a/core/http/views/agent-task-details.html
+++ b/core/http/views/agent-task-details.html
@@ -2,20 +2,22 @@
{{template "views/partials/head" .}}
-
-
-
- {{template "views/partials/navbar" .}}
+
+
+ {{template "views/partials/navbar" .}}
+
+
+
-
+
@@ -37,7 +39,7 @@
-
+
Back
@@ -57,62 +59,62 @@