feat(whoosh): add /metrics + admin health alias; serve UI assets at root; ui: auth token control, spinner fix, delete repo/project, correct repo POST payload
This commit is contained in:
297
ui/index.html
297
ui/index.html
@@ -3,277 +3,34 @@
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>WHOOSH - Council Formation Engine [External UI]</title>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter+Tight:wght@100;200;300;400;500;600;700;800;900&family=Exo:wght@100;200;300;400;500;600;700;800;900&family=Inconsolata:wght@200;300;400;500;600;700;800;900&display=swap" rel="stylesheet">
|
||||
<link rel="stylesheet" href="/ui/styles.css">
|
||||
<title>WHOOSH UI</title>
|
||||
<link rel="stylesheet" href="/styles.css">
|
||||
</head>
|
||||
<body>
|
||||
<header class="header">
|
||||
<div class="logo">
|
||||
<strong>WHOOSH</strong>
|
||||
<span class="tagline">Council Formation Engine</span>
|
||||
<div id="app">
|
||||
<header>
|
||||
<h1>WHOOSH</h1>
|
||||
<nav>
|
||||
<a href="#dashboard">Dashboard</a>
|
||||
<a href="#councils">Councils</a>
|
||||
<a href="#tasks">Tasks</a>
|
||||
<a href="#repositories">Repositories</a>
|
||||
<a href="#analysis">Analysis</a>
|
||||
</nav>
|
||||
<div id="auth-controls">
|
||||
<span id="auth-status" title="Authorization status">Guest</span>
|
||||
<input type="password" id="auth-token-input" placeholder="Paste token" autocomplete="off">
|
||||
<button class="button" id="save-auth-token">Save</button>
|
||||
<button class="button danger" id="clear-auth-token">Clear</button>
|
||||
</div>
|
||||
</header>
|
||||
<main id="main-content">
|
||||
<!-- Content will be loaded here -->
|
||||
</main>
|
||||
<div id="loading-spinner" class="hidden">
|
||||
<div class="spinner"></div>
|
||||
</div>
|
||||
<div class="status-info">
|
||||
<div class="status-dot online"></div>
|
||||
<span id="connection-status">Connected</span>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<nav class="nav">
|
||||
<button class="nav-tab active" data-tab="dashboard">Dashboard</button>
|
||||
<button class="nav-tab" data-tab="tasks">Tasks</button>
|
||||
<button class="nav-tab" data-tab="teams">Teams</button>
|
||||
<button class="nav-tab" data-tab="agents">Agents</button>
|
||||
<button class="nav-tab" data-tab="config">Configuration</button>
|
||||
<button class="nav-tab" data-tab="repositories">Repositories</button>
|
||||
</nav>
|
||||
|
||||
<main class="content">
|
||||
<!-- Dashboard Tab -->
|
||||
<div id="dashboard" class="tab-content active">
|
||||
<div class="dashboard-grid">
|
||||
<div class="card">
|
||||
<h3><img src="https://brand.chorus.services/icons/coolicons.v4.1/coolicons%20PNG/White/Interface/Chart_Bar_Vertical_01.png" alt="Chart" class="card-icon" style="display: inline; vertical-align: text-top;"> System Metrics</h3>
|
||||
<div class="metric">
|
||||
<span class="metric-label">Active Councils</span>
|
||||
<span class="metric-value">0</span>
|
||||
</div>
|
||||
<div class="metric">
|
||||
<span class="metric-label">Deployed Agents</span>
|
||||
<span class="metric-value">0</span>
|
||||
</div>
|
||||
<div class="metric">
|
||||
<span class="metric-label">Completed Tasks</span>
|
||||
<span class="metric-value">0</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<h3><img src="https://brand.chorus.services/icons/coolicons.v4.1/coolicons%20PNG/White/Arrow/Arrow_Reload_02.png" alt="Refresh" class="card-icon" style="display: inline; vertical-align: text-top;"> Recent Activity</h3>
|
||||
<div id="recent-activity">
|
||||
<div class="empty-state-icon"><img src="https://brand.chorus.services/icons/coolicons.v4.1/coolicons%20PNG/White/File/Folder_Document.png" alt="Empty" style="width: 3rem; height: 3rem; opacity: 0.5;"></div>
|
||||
<p>No recent activity</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<h3><img src="https://brand.chorus.services/icons/coolicons.v4.1/coolicons%20PNG/White/Warning/Circle_Check.png" alt="Status" class="card-icon" style="display: inline; vertical-align: text-top;"> System Status</h3>
|
||||
<div class="metric">
|
||||
<span class="metric-label">Database</span>
|
||||
<span class="metric-value success-indicator">✅ Healthy</span>
|
||||
</div>
|
||||
<div class="metric">
|
||||
<span class="metric-label">GITEA Integration</span>
|
||||
<span class="metric-value success-indicator">✅ Connected</span>
|
||||
</div>
|
||||
<div class="metric">
|
||||
<span class="metric-label">BACKBEAT</span>
|
||||
<span class="metric-value success-indicator">✅ Active</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<div class="metric">
|
||||
<span class="metric-label">Tempo</span>
|
||||
<span class="metric-value" id="beat-tempo" style="color: var(--ocean-400);">--</span>
|
||||
</div>
|
||||
<div class="metric">
|
||||
<span class="metric-label">Volume</span>
|
||||
<span class="metric-value" id="beat-volume" style="color: var(--ocean-400);">--</span>
|
||||
</div>
|
||||
<div class="metric">
|
||||
<span class="metric-label">Phase</span>
|
||||
<span class="metric-value" id="beat-phase" style="color: var(--ocean-400);">--</span>
|
||||
</div>
|
||||
<div style="margin-top: 1rem; height: 60px; background: var(--carbon-800); border-radius: 0; position: relative; overflow: hidden; border: 1px solid var(--mulberry-800);">
|
||||
<canvas id="pulse-trace" width="100%" height="60" style="width: 100%; height: 60px;"></canvas>
|
||||
</div>
|
||||
<div class="backbeat-label">
|
||||
Live BACKBEAT Pulse
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Tasks Tab -->
|
||||
<div id="tasks" class="tab-content">
|
||||
<div class="card">
|
||||
<button class="btn btn-primary" onclick="refreshTasks()"><img src="https://brand.chorus.services/icons/coolicons.v4.1/coolicons%20PNG/White/Arrow/Arrow_Reload_02.png" alt="Refresh" style="width: 1rem; height: 1rem; margin-right: 0.5rem; vertical-align: text-top;"> Refresh Tasks</button>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<div class="tabs">
|
||||
<h3><img src="https://brand.chorus.services/icons/coolicons.v4.1/coolicons%20PNG/White/Edit/List_Check.png" alt="Tasks" class="card-icon" style="display: inline; vertical-align: text-top;"> Active Tasks</h3>
|
||||
<div id="active-tasks">
|
||||
<div style="text-align: center; padding: 2rem 0; color: var(--mulberry-300);">
|
||||
<div class="empty-state-icon"><img src="https://brand.chorus.services/icons/coolicons.v4.1/coolicons%20PNG/White/Edit/List_Check.png" alt="No tasks" style="width: 3rem; height: 3rem; opacity: 0.5;"></div>
|
||||
<p>No active tasks found</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="tabs">
|
||||
<h4>Scheduled Tasks</h4>
|
||||
<div id="scheduled-tasks">
|
||||
<div style="text-align: center; padding: 2rem 0; color: var(--mulberry-300);">
|
||||
<div class="empty-state-icon"><img src="https://brand.chorus.services/icons/coolicons.v4.1/coolicons%20PNG/White/Calendar/Calendar.png" alt="No scheduled tasks" style="width: 3rem; height: 3rem; opacity: 0.5;"></div>
|
||||
<p>No scheduled tasks found</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Teams Tab -->
|
||||
<div id="teams" class="tab-content">
|
||||
<div class="card">
|
||||
<h2><img src="https://brand.chorus.services/icons/coolicons.v4.1/coolicons%20PNG/White/User/Users_Group.png" alt="Team" style="width: 1.5rem; height: 1.5rem; margin-right: 0.5rem; vertical-align: text-bottom;"> Team Management</h2>
|
||||
<button class="btn btn-primary" onclick="loadTeams()"><img src="https://brand.chorus.services/icons/coolicons.v4.1/coolicons%20PNG/White/Arrow/Arrow_Reload_02.png" alt="Refresh" style="width: 1rem; height: 1rem; margin-right: 0.5rem; vertical-align: text-top;"> Refresh Teams</button>
|
||||
</div>
|
||||
|
||||
<div class="card" id="teams-list">
|
||||
<div style="text-align: center; padding: 3rem 0; color: var(--mulberry-300);">
|
||||
<div class="empty-state-icon"><img src="https://brand.chorus.services/icons/coolicons.v4.1/coolicons%20PNG/White/User/Users_Group.png" alt="No teams" style="width: 3rem; height: 3rem; opacity: 0.5;"></div>
|
||||
<p>No teams configured yet</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Agents Tab -->
|
||||
<div id="agents" class="tab-content">
|
||||
<div class="card">
|
||||
<h2><img src="https://brand.chorus.services/icons/coolicons.v4.1/coolicons%20PNG/White/System/Window_Check.png" alt="Agents" style="width: 1.5rem; height: 1.5rem; margin-right: 0.5rem; vertical-align: text-bottom;"> Agent Management</h2>
|
||||
<button class="btn btn-primary" onclick="loadAgents()"><img src="https://brand.chorus.services/icons/coolicons.v4.1/coolicons%20PNG/White/Arrow/Arrow_Reload_02.png" alt="Refresh" style="width: 1rem; height: 1rem; margin-right: 0.5rem; vertical-align: text-top;"> Refresh Agents</button>
|
||||
</div>
|
||||
|
||||
<div class="card" id="agents-list">
|
||||
<div style="text-align: center; padding: 3rem 0; color: var(--mulberry-300);">
|
||||
<div class="empty-state-icon"><img src="https://brand.chorus.services/icons/coolicons.v4.1/coolicons%20PNG/White/System/Window_Check.png" alt="No agents" style="width: 3rem; height: 3rem; opacity: 0.5;"></div>
|
||||
<p>No agents registered yet</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Configuration Tab -->
|
||||
<div id="config" class="tab-content">
|
||||
<h2><img src="https://brand.chorus.services/icons/coolicons.v4.1/coolicons%20PNG/White/Interface/Settings.png" alt="Settings" style="width: 1.5rem; height: 1.5rem; margin-right: 0.5rem; vertical-align: text-bottom;"> System Configuration</h2>
|
||||
|
||||
<div class="dashboard-grid">
|
||||
<div class="card">
|
||||
<h3>GITEA Integration</h3>
|
||||
<div class="metric">
|
||||
<span class="metric-label">Base URL</span>
|
||||
<span class="metric-value">https://gitea.chorus.services</span>
|
||||
</div>
|
||||
<div class="metric">
|
||||
<span class="metric-label">Webhook Path</span>
|
||||
<span class="metric-value">/webhooks/gitea</span>
|
||||
</div>
|
||||
<div class="metric">
|
||||
<span class="metric-label">Token Status</span>
|
||||
<span class="metric-value" style="color: var(--eucalyptus-500);"><img src="https://brand.chorus.services/icons/coolicons.v4.1/coolicons%20PNG/White/Interface/Check.png" alt="Valid" style="width: 1rem; height: 1rem; margin-right: 0.25rem; vertical-align: text-top;"> Valid</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<h3>Repository Management</h3>
|
||||
<button class="btn btn-primary" onclick="showAddRepositoryForm()">+ Add Repository</button>
|
||||
|
||||
<div id="add-repository-form" style="display: none; margin-top: 1rem; background: var(--carbon-800); padding: 1rem; border: 1px solid var(--mulberry-700);">
|
||||
<h4>Add New Repository</h4>
|
||||
<form id="repository-form">
|
||||
<div style="margin-bottom: 1rem;">
|
||||
<label>Repository Name:</label>
|
||||
<input type="text" id="repo-name" required style="width: 100%; padding: 8px; border: 1px solid var(--carbon-300); border-radius: 0.375rem;" placeholder="e.g., WHOOSH">
|
||||
</div>
|
||||
<div style="margin-bottom: 1rem;">
|
||||
<label>Owner:</label>
|
||||
<input type="text" id="repo-owner" required style="width: 100%; padding: 8px; border: 1px solid var(--carbon-300); border-radius: 0.375rem;" placeholder="e.g., tony">
|
||||
</div>
|
||||
|
||||
<div style="margin-bottom: 1rem;">
|
||||
<label>Repository URL:</label>
|
||||
<input type="url" id="repo-url" required style="width: 100%; padding: 8px; border: 1px solid var(--carbon-300); border-radius: 0.375rem;" placeholder="https://gitea.chorus.services/tony/WHOOSH">
|
||||
</div>
|
||||
|
||||
<div style="margin-bottom: 1rem;">
|
||||
<label>Source Type:</label>
|
||||
<select id="repo-source-type" style="width: 100%; padding: 8px; border: 1px solid var(--carbon-300); border-radius: 0.375rem;">
|
||||
<option value="git">Git Repository</option>
|
||||
<option value="gitea">GITEA</option>
|
||||
<option value="github">GitHub</option>
|
||||
<option value="gitlab">GitLab</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div style="margin-bottom: 1rem;">
|
||||
<label>Default Branch:</label>
|
||||
<input type="text" id="repo-branch" value="main" style="width: 100%; padding: 8px; border: 1px solid var(--carbon-300); border-radius: 0.375rem;">
|
||||
</div>
|
||||
|
||||
<div style="margin-bottom: 1rem;">
|
||||
<label>Description:</label>
|
||||
<textarea id="repo-description" rows="2" style="width: 100%; padding: 8px; border: 1px solid var(--carbon-300); border-radius: 0.375rem;" placeholder="Brief description of this repository..."></textarea>
|
||||
</div>
|
||||
|
||||
<div style="margin-bottom: 1rem;">
|
||||
<label style="display: flex; align-items: center; gap: 8px;">
|
||||
<input type="checkbox" id="repo-monitor-issues" checked>
|
||||
Monitor Issues (listen for chorus-entrypoint labels)
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div style="margin-bottom: 1rem;">
|
||||
<label style="display: flex; align-items: center; gap: 8px;">
|
||||
<input type="checkbox" id="repo-enable-chorus">
|
||||
Enable CHORUS Integration
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div style="display: flex; gap: 10px;">
|
||||
<button type="button" onclick="hideAddRepositoryForm()" style="background: var(--carbon-300); color: var(--carbon-600); border: none; padding: 8px 16px; border-radius: 0.375rem; cursor: pointer; margin-right: 10px;">Cancel</button>
|
||||
<button type="submit" style="background: var(--eucalyptus-500); color: white; border: none; padding: 8px 16px; border-radius: 0.375rem; cursor: pointer; font-weight: 500;">Add Repository</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<h3><img src="https://brand.chorus.services/icons/coolicons.v4.1/coolicons%20PNG/White/Interface/Chart_Bar_Vertical_01.png" alt="Chart" class="card-icon" style="display: inline; vertical-align: text-top;"> Repository Stats</h3>
|
||||
<div class="metric">
|
||||
<span class="metric-label">Total Repositories</span>
|
||||
<span class="metric-value" id="total-repos">--</span>
|
||||
</div>
|
||||
<div class="metric">
|
||||
<span class="metric-label">Active Monitoring</span>
|
||||
<span class="metric-value" id="active-repos">--</span>
|
||||
</div>
|
||||
<div class="metric">
|
||||
<span class="metric-label">Last Sync</span>
|
||||
<span class="metric-value" id="last-sync">--</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Repositories Tab -->
|
||||
<div id="repositories" class="tab-content">
|
||||
<div class="card">
|
||||
<h2>Repository Management</h2>
|
||||
<button class="btn btn-primary" onclick="loadRepositories()">Refresh Repositories</button>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<h3>Monitored Repositories</h3>
|
||||
<div id="repositories-list">
|
||||
<p style="text-align: center; color: var(--mulberry-300); padding: 20px;">Loading repositories...</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<script src="/ui/script.js"></script>
|
||||
</div>
|
||||
<script src="/script.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
|
||||
1152
ui/script.js
1152
ui/script.js
File diff suppressed because it is too large
Load Diff
634
ui/styles.css
634
ui/styles.css
@@ -1,463 +1,249 @@
|
||||
/* CHORUS Brand Variables */
|
||||
:root {
|
||||
font-size: 18px; /* CHORUS proportional base */
|
||||
/* Carbon Colors (Primary Neutral) */
|
||||
--carbon-950: #000000;
|
||||
--carbon-900: #0a0a0a;
|
||||
--carbon-800: #1a1a1a;
|
||||
--carbon-700: #2a2a2a;
|
||||
--carbon-600: #666666;
|
||||
--carbon-500: #808080;
|
||||
--carbon-400: #a0a0a0;
|
||||
--carbon-300: #c0c0c0;
|
||||
--carbon-200: #e0e0e0;
|
||||
--carbon-100: #f0f0f0;
|
||||
--carbon-50: #f8f8f8;
|
||||
|
||||
/* Mulberry Colors (Brand Accent) */
|
||||
--mulberry-950: #0b0213;
|
||||
--mulberry-900: #1a1426;
|
||||
--mulberry-800: #2a2639;
|
||||
--mulberry-700: #3a384c;
|
||||
--mulberry-600: #4a4a5f;
|
||||
--mulberry-500: #5a5c72;
|
||||
--mulberry-400: #7a7e95;
|
||||
--mulberry-300: #9aa0b8;
|
||||
--mulberry-200: #bac2db;
|
||||
--mulberry-100: #dae4fe;
|
||||
--mulberry-50: #f0f4ff;
|
||||
|
||||
/* Ocean Colors (Primary Action) */
|
||||
--ocean-950: #2a3441;
|
||||
--ocean-900: #3a4654;
|
||||
--ocean-800: #4a5867;
|
||||
--ocean-700: #5a6c80;
|
||||
--ocean-600: #6a7e99;
|
||||
--ocean-500: #7a90b2;
|
||||
--ocean-400: #8ba3c4;
|
||||
--ocean-300: #9bb6d6;
|
||||
--ocean-200: #abc9e8;
|
||||
--ocean-100: #bbdcfa;
|
||||
--ocean-50: #cbefff;
|
||||
|
||||
/* Eucalyptus Colors (Success) */
|
||||
--eucalyptus-950: #2a3330;
|
||||
--eucalyptus-900: #3a4540;
|
||||
--eucalyptus-800: #4a5750;
|
||||
--eucalyptus-700: #515d54;
|
||||
--eucalyptus-600: #5a6964;
|
||||
--eucalyptus-500: #6a7974;
|
||||
--eucalyptus-400: #7a8a7f;
|
||||
--eucalyptus-300: #8a9b8f;
|
||||
--eucalyptus-200: #9aac9f;
|
||||
--eucalyptus-100: #aabdaf;
|
||||
--eucalyptus-50: #bacfbf;
|
||||
|
||||
/* Coral Colors (Error/Warning) */
|
||||
--coral-700: #dc2626;
|
||||
--coral-500: #ef4444;
|
||||
--coral-300: #fca5a5;
|
||||
}
|
||||
|
||||
/* Base Styles with CHORUS Branding */
|
||||
body {
|
||||
font-family: 'Inter Tight', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
background: var(--carbon-950);
|
||||
color: var(--carbon-100);
|
||||
/* Basic Styles */
|
||||
body {
|
||||
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||
margin: 0;
|
||||
background-color: #f4f7f6;
|
||||
color: #333;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
/* CHORUS Dark Mode Header */
|
||||
.header {
|
||||
background: linear-gradient(135deg, var(--carbon-900) 0%, var(--mulberry-900) 100%);
|
||||
color: white;
|
||||
padding: 1.33rem 0; /* 24px at 18px base */
|
||||
border-bottom: 1px solid var(--mulberry-800);
|
||||
#app {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
header {
|
||||
background-color: #2c3e50; /* Darker header for contrast */
|
||||
padding: 1rem 2rem;
|
||||
border-bottom: 1px solid #34495e;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
color: #ecf0f1;
|
||||
}
|
||||
|
||||
header h1 {
|
||||
margin: 0;
|
||||
font-size: 1.8rem;
|
||||
color: #ecf0f1;
|
||||
}
|
||||
|
||||
nav a {
|
||||
margin: 0 1rem;
|
||||
text-decoration: none;
|
||||
color: #bdc3c7; /* Lighter grey for navigation */
|
||||
font-weight: 500;
|
||||
transition: color 0.3s ease;
|
||||
}
|
||||
|
||||
nav a:hover {
|
||||
color: #ecf0f1;
|
||||
}
|
||||
|
||||
#auth-controls {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
#auth-status {
|
||||
font-size: 0.9rem;
|
||||
padding: 0.25rem 0.5rem;
|
||||
border-radius: 4px;
|
||||
background: #7f8c8d;
|
||||
}
|
||||
|
||||
#auth-status.authed {
|
||||
background: #2ecc71;
|
||||
}
|
||||
|
||||
#auth-token-input {
|
||||
width: 220px;
|
||||
padding: 0.4rem 0.6rem;
|
||||
border: 1px solid #95a5a6;
|
||||
border-radius: 4px;
|
||||
background: #ecf0f1;
|
||||
color: #2c3e50;
|
||||
}
|
||||
|
||||
main {
|
||||
flex-grow: 1;
|
||||
padding: 2rem;
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
padding-left: 1.33rem;
|
||||
padding-right: 1.33rem;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.header-content {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
padding: 0 1.33rem;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
/* Reusable Components */
|
||||
.card {
|
||||
background-color: #fff;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 4px 8px rgba(0,0,0,0.05);
|
||||
padding: 1.5rem;
|
||||
margin-bottom: 2rem;
|
||||
animation: card-fade-in 0.5s ease-in-out;
|
||||
border: 1px solid #e0e0e0;
|
||||
}
|
||||
|
||||
.logo {
|
||||
font-family: 'Exo', sans-serif;
|
||||
font-size: 1.33rem; /* 24px at 18px base */
|
||||
font-weight: 300;
|
||||
color: white;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.67rem;
|
||||
@keyframes card-fade-in {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(20px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
.logo .tagline {
|
||||
font-size: 0.78rem;
|
||||
color: var(--mulberry-300);
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
.logo::before {
|
||||
content: "";
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
.status-info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
color: var(--eucalyptus-400);
|
||||
font-size: 0.78rem;
|
||||
}
|
||||
|
||||
.status-dot {
|
||||
width: 0.67rem;
|
||||
height: 0.67rem;
|
||||
border-radius: 50%;
|
||||
background: var(--eucalyptus-400);
|
||||
margin-right: 0.44rem;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
/* CHORUS Navigation */
|
||||
.nav {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
padding: 0 1.33rem;
|
||||
display: flex;
|
||||
border-bottom: 1px solid var(--mulberry-800);
|
||||
background: var(--carbon-900);
|
||||
}
|
||||
|
||||
.nav-tab {
|
||||
padding: 0.83rem 1.39rem;
|
||||
cursor: pointer;
|
||||
border-bottom: 3px solid transparent;
|
||||
font-weight: 500;
|
||||
transition: all 0.2s;
|
||||
color: var(--mulberry-300);
|
||||
background: none;
|
||||
.button {
|
||||
background-color: #3498db; /* A vibrant blue */
|
||||
color: #fff;
|
||||
padding: 0.75rem 1.5rem;
|
||||
border: none;
|
||||
font-family: inherit;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
font-size: 1rem;
|
||||
transition: background-color 0.3s ease;
|
||||
}
|
||||
|
||||
.nav-tab.active {
|
||||
border-bottom-color: var(--ocean-500);
|
||||
color: var(--ocean-300);
|
||||
background: var(--carbon-800);
|
||||
.button:hover {
|
||||
background-color: #2980b9;
|
||||
}
|
||||
|
||||
.nav-tab:hover {
|
||||
background: var(--carbon-800);
|
||||
color: var(--ocean-400);
|
||||
.button.danger {
|
||||
background-color: #e74c3c;
|
||||
}
|
||||
|
||||
.content {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
padding: 1.33rem;
|
||||
.button.danger:hover {
|
||||
background-color: #c0392b;
|
||||
}
|
||||
|
||||
.tab-content {
|
||||
display: none;
|
||||
.error {
|
||||
color: #e74c3c;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.tab-content.active {
|
||||
display: block;
|
||||
/* Grid Layouts */
|
||||
.dashboard-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(400px, 1fr));
|
||||
grid-gap: 2rem;
|
||||
}
|
||||
|
||||
/* CHORUS Card System */
|
||||
.dashboard-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(350px, 1fr));
|
||||
gap: 1.33rem;
|
||||
margin-bottom: 2rem;
|
||||
.grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
|
||||
grid-gap: 2rem;
|
||||
}
|
||||
|
||||
.card {
|
||||
background: var(--carbon-900);
|
||||
border-radius: 0;
|
||||
padding: 1.33rem;
|
||||
box-shadow: 0 0.22rem 0.89rem rgba(0,0,0,0.3);
|
||||
border: 1px solid var(--mulberry-800);
|
||||
.card.full-width {
|
||||
grid-column: 1 / -1;
|
||||
}
|
||||
|
||||
.card h3 {
|
||||
margin: 0 0 1rem 0;
|
||||
color: var(--carbon-100);
|
||||
font-size: 1rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
.table-wrapper {
|
||||
width: 100%;
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
.role-table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
font-size: 0.95rem;
|
||||
}
|
||||
|
||||
.role-table th,
|
||||
.role-table td {
|
||||
padding: 0.75rem 0.5rem;
|
||||
border-bottom: 1px solid #e0e0e0;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.role-table th {
|
||||
background-color: #f2f4f7;
|
||||
font-weight: 600;
|
||||
color: #2c3e50;
|
||||
}
|
||||
|
||||
.card h2 {
|
||||
margin: 0 0 1rem 0;
|
||||
color: var(--carbon-100);
|
||||
font-size: 1.33rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.card-icon {
|
||||
width: 1.33rem;
|
||||
height: 1.33rem;
|
||||
margin-right: 0.67rem;
|
||||
}
|
||||
|
||||
/* Metrics with CHORUS Colors */
|
||||
.metric {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin: 0.44rem 0;
|
||||
padding: 0.44rem 0;
|
||||
}
|
||||
|
||||
.metric:not(:last-child) {
|
||||
border-bottom: 1px solid var(--mulberry-900);
|
||||
}
|
||||
|
||||
.metric-label {
|
||||
color: var(--mulberry-300);
|
||||
}
|
||||
|
||||
.metric-value {
|
||||
font-weight: 600;
|
||||
color: var(--carbon-100);
|
||||
}
|
||||
|
||||
/* Task Items with CHORUS Brand Colors */
|
||||
.task-item {
|
||||
background: var(--carbon-800);
|
||||
border-radius: 0;
|
||||
padding: 0.89rem;
|
||||
margin-bottom: 0.67rem;
|
||||
border-left: 4px solid var(--mulberry-600);
|
||||
}
|
||||
|
||||
.task-item.priority-high {
|
||||
border-left-color: var(--coral-500);
|
||||
}
|
||||
|
||||
.task-item.priority-medium {
|
||||
border-left-color: var(--ocean-500);
|
||||
}
|
||||
|
||||
.task-item.priority-low {
|
||||
border-left-color: var(--eucalyptus-500);
|
||||
}
|
||||
|
||||
.task-title {
|
||||
font-weight: 600;
|
||||
color: var(--carbon-100);
|
||||
margin-bottom: 0.44rem;
|
||||
}
|
||||
|
||||
.task-meta {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
color: var(--mulberry-300);
|
||||
font-size: 0.78rem;
|
||||
}
|
||||
|
||||
/* Agent Cards */
|
||||
.agent-card {
|
||||
background: var(--carbon-800);
|
||||
border-radius: 0;
|
||||
padding: 0.89rem;
|
||||
margin-bottom: 0.67rem;
|
||||
}
|
||||
|
||||
.agent-status {
|
||||
width: 0.44rem;
|
||||
height: 0.44rem;
|
||||
border-radius: 50%;
|
||||
margin-right: 0.44rem;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.agent-status.online {
|
||||
background: var(--eucalyptus-400);
|
||||
}
|
||||
|
||||
.agent-status.offline {
|
||||
background: var(--carbon-500);
|
||||
}
|
||||
|
||||
.team-member {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0.44rem;
|
||||
background: var(--carbon-900);
|
||||
border-radius: 0;
|
||||
margin-bottom: 0.44rem;
|
||||
}
|
||||
|
||||
/* CHORUS Button System */
|
||||
.btn {
|
||||
padding: 0.44rem 0.89rem;
|
||||
border-radius: 0.375rem;
|
||||
border: none;
|
||||
font-weight: 500;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s;
|
||||
font-family: 'Inter Tight', sans-serif;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
background: var(--ocean-600);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.btn-primary:hover {
|
||||
background: var(--ocean-500);
|
||||
}
|
||||
|
||||
.btn-secondary {
|
||||
background: var(--mulberry-700);
|
||||
color: var(--mulberry-200);
|
||||
}
|
||||
|
||||
.btn-secondary:hover {
|
||||
background: var(--mulberry-600);
|
||||
}
|
||||
|
||||
/* Empty States */
|
||||
.empty-state {
|
||||
text-align: center;
|
||||
padding: 2.22rem 1.33rem;
|
||||
color: var(--mulberry-300);
|
||||
}
|
||||
|
||||
.empty-state-icon {
|
||||
font-size: 2.67rem;
|
||||
margin-bottom: 0.89rem;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* BackBeat Pulse Visualization */
|
||||
#pulse-trace {
|
||||
background: var(--carbon-800);
|
||||
border-radius: 0;
|
||||
border: 1px solid var(--mulberry-800);
|
||||
}
|
||||
|
||||
/* Additional CHORUS Styling */
|
||||
.backbeat-label {
|
||||
color: var(--mulberry-300);
|
||||
font-size: 0.67rem;
|
||||
text-align: center;
|
||||
margin-top: 0.44rem;
|
||||
}
|
||||
|
||||
/* Modal and Overlay Styling */
|
||||
.modal-overlay {
|
||||
background: rgba(0, 0, 0, 0.8) !important;
|
||||
}
|
||||
|
||||
.modal-content {
|
||||
background: var(--carbon-900) !important;
|
||||
color: var(--carbon-100) !important;
|
||||
border: 1px solid var(--mulberry-800) !important;
|
||||
}
|
||||
|
||||
.modal-content input, .modal-content select, .modal-content textarea {
|
||||
background: var(--carbon-800);
|
||||
color: var(--carbon-100);
|
||||
border: 1px solid var(--mulberry-700);
|
||||
border-radius: 0;
|
||||
padding: 0.44rem 0.67rem;
|
||||
font-family: inherit;
|
||||
}
|
||||
|
||||
.modal-content input:focus, .modal-content select:focus, .modal-content textarea:focus {
|
||||
border-color: var(--ocean-500);
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.modal-content label {
|
||||
color: var(--mulberry-200);
|
||||
display: block;
|
||||
margin-bottom: 0.33rem;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
/* Repository Cards */
|
||||
.repository-item {
|
||||
background: var(--carbon-800);
|
||||
border-radius: 0;
|
||||
padding: 0.89rem;
|
||||
margin-bottom: 0.67rem;
|
||||
border: 1px solid var(--mulberry-800);
|
||||
}
|
||||
|
||||
.repository-item h4 {
|
||||
color: var(--carbon-100);
|
||||
margin: 0 0 0.44rem 0;
|
||||
}
|
||||
|
||||
.repository-meta {
|
||||
color: var(--mulberry-300);
|
||||
font-size: 0.78rem;
|
||||
margin-bottom: 0.44rem;
|
||||
}
|
||||
|
||||
/* Success/Error States */
|
||||
.success-indicator {
|
||||
color: var(--eucalyptus-400);
|
||||
}
|
||||
|
||||
.error-indicator {
|
||||
color: var(--coral-500);
|
||||
}
|
||||
|
||||
.warning-indicator {
|
||||
color: var(--ocean-400);
|
||||
}
|
||||
|
||||
/* Tabs styling */
|
||||
.tabs {
|
||||
margin-bottom: 1.33rem;
|
||||
}
|
||||
|
||||
.tabs h4 {
|
||||
color: var(--carbon-100);
|
||||
margin-bottom: 0.67rem;
|
||||
font-size: 0.89rem;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
/* Form styling improvements */
|
||||
form {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
form > div {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.33rem;
|
||||
.role-table tr:hover td {
|
||||
background-color: #f8f9fb;
|
||||
}
|
||||
|
||||
/* Forms */
|
||||
form label {
|
||||
font-weight: 500;
|
||||
color: var(--mulberry-200);
|
||||
display: block;
|
||||
margin-bottom: 0.5rem;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
form input[type="checkbox"] {
|
||||
margin-right: 0.5rem;
|
||||
accent-color: var(--ocean-500);
|
||||
}
|
||||
form input[type="text"] {
|
||||
width: 100%;
|
||||
padding: 0.8rem;
|
||||
margin-bottom: 1rem;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 4px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
/* Loading Spinner */
|
||||
#loading-spinner {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: rgba(255, 255, 255, 0.8);
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
z-index: 9999;
|
||||
}
|
||||
|
||||
.spinner {
|
||||
border: 8px solid #f3f3f3;
|
||||
border-top: 8px solid #3498db;
|
||||
border-radius: 50%;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
animation: spin 2s linear infinite;
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
0% { transform: rotate(0deg); }
|
||||
100% { transform: rotate(360deg); }
|
||||
}
|
||||
|
||||
.hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Responsive Design */
|
||||
@media (max-width: 768px) {
|
||||
header {
|
||||
flex-direction: column;
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
nav {
|
||||
margin-top: 1rem;
|
||||
}
|
||||
|
||||
nav a {
|
||||
margin: 0 0.5rem;
|
||||
}
|
||||
|
||||
main {
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
.dashboard-grid,
|
||||
.grid {
|
||||
grid-template-columns: 1fr;
|
||||
grid-gap: 1rem;
|
||||
}
|
||||
|
||||
.card {
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user