1503 lines
56 KiB
HTML
1503 lines
56 KiB
HTML
|
|
<!--
|
||
|
|
============================================================================
|
||
|
|
CAMELEER3 — Dashboard Visual Design Mock
|
||
|
|
============================================================================
|
||
|
|
|
||
|
|
DESIGN RATIONALE
|
||
|
|
================
|
||
|
|
|
||
|
|
1. COLOR PHILOSOPHY — "Desert Dusk"
|
||
|
|
Moving away from the generic dark-navy dashboard, this design uses a
|
||
|
|
warm sandstone/parchment palette inspired by desert caravans (the camel
|
||
|
|
connection). The base is a warm off-white (#FAF8F5) with layered ivory
|
||
|
|
surfaces. The accent color is a rich amber-gold (#C6820E) that evokes
|
||
|
|
caravan lanterns. This creates a distinctive identity that no other
|
||
|
|
monitoring tool has — most are cold blue/gray.
|
||
|
|
|
||
|
|
2. TYPOGRAPHY
|
||
|
|
DM Sans for body text (geometric, modern, highly legible at small sizes).
|
||
|
|
JetBrains Mono for data values and code (excellent number alignment).
|
||
|
|
Four-level hierarchy: Page title (20px/700), Section headers (13px/600
|
||
|
|
uppercase tracking), Body (13px/400), Meta (11px/400 muted).
|
||
|
|
|
||
|
|
3. INFORMATION DENSITY
|
||
|
|
Inspired by the nJAMS three-panel layout: operators need to see many
|
||
|
|
executions at once. Rows are compact (40px) but not cramped. The stats
|
||
|
|
bar uses horizontal cards rather than tall boxes to preserve vertical
|
||
|
|
space for the table. A metrics panel below the fold provides trend data
|
||
|
|
without cluttering the primary view.
|
||
|
|
|
||
|
|
4. STATUS COLORS
|
||
|
|
Success: Warm olive-green (#3D7C47) — natural, not neon
|
||
|
|
Warning: Burnt orange (#C27516) — distinct from the amber accent
|
||
|
|
Error: Terracotta red (#C0392B) — warm red, not alarming pink
|
||
|
|
Running: Teal (#1A7F8E) — cool contrast against warm palette
|
||
|
|
|
||
|
|
5. LAYOUT
|
||
|
|
Three zones: Navigation sidebar (220px, warm dark), Main content (flex),
|
||
|
|
optional detail panel. The sidebar uses a deep warm charcoal (#2C2520)
|
||
|
|
instead of pure black — keeping the warm family. Active items get a
|
||
|
|
golden left-border accent.
|
||
|
|
|
||
|
|
6. BRAND IDENTITY
|
||
|
|
The camel silhouette in the logo area, warm desert tones, and the name
|
||
|
|
"Cameleer" (one who leads camels) create a cohesive brand. The overall
|
||
|
|
feel is "premium craft tool" rather than "enterprise dashboard."
|
||
|
|
============================================================================
|
||
|
|
-->
|
||
|
|
<!DOCTYPE html>
|
||
|
|
<html lang="en">
|
||
|
|
<head>
|
||
|
|
<meta charset="UTF-8">
|
||
|
|
<meta name="viewport" content="width=1920">
|
||
|
|
<title>Cameleer3 — Route Execution Monitor</title>
|
||
|
|
<link href="https://fonts.googleapis.com/css2?family=DM+Sans:ital,opsz,wght@0,9..40,300;0,9..40,400;0,9..40,500;0,9..40,600;0,9..40,700&family=JetBrains+Mono:wght@400;500;600&display=swap" rel="stylesheet">
|
||
|
|
<style>
|
||
|
|
/* ═══════════════════════════════════════════════════════════════════════════
|
||
|
|
RESET & FOUNDATIONS
|
||
|
|
═══════════════════════════════════════════════════════════════════════════ */
|
||
|
|
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
||
|
|
|
||
|
|
:root {
|
||
|
|
/* ── Surface palette (warm parchment) ── */
|
||
|
|
--bg-body: #F5F2ED;
|
||
|
|
--bg-surface: #FFFFFF;
|
||
|
|
--bg-raised: #FAF8F5;
|
||
|
|
--bg-inset: #F0EDE8;
|
||
|
|
--bg-hover: #F5F0EA;
|
||
|
|
|
||
|
|
/* ── Sidebar (warm charcoal) ── */
|
||
|
|
--sidebar-bg: #2C2520;
|
||
|
|
--sidebar-hover: #3A322C;
|
||
|
|
--sidebar-active: #4A3F38;
|
||
|
|
--sidebar-text: #BFB5A8;
|
||
|
|
--sidebar-muted: #7A6F63;
|
||
|
|
|
||
|
|
/* ── Text ── */
|
||
|
|
--text-primary: #1A1612;
|
||
|
|
--text-secondary: #5C5347;
|
||
|
|
--text-muted: #9C9184;
|
||
|
|
--text-faint: #C4BAB0;
|
||
|
|
|
||
|
|
/* ── Borders ── */
|
||
|
|
--border: #E4DFD8;
|
||
|
|
--border-subtle: #EDE9E3;
|
||
|
|
|
||
|
|
/* ── Brand accent (amber-gold) ── */
|
||
|
|
--amber: #C6820E;
|
||
|
|
--amber-light: #F0D9A8;
|
||
|
|
--amber-bg: #FDF6E9;
|
||
|
|
--amber-deep: #8B5A06;
|
||
|
|
|
||
|
|
/* ── Status colors ── */
|
||
|
|
--success: #3D7C47;
|
||
|
|
--success-bg: #EFF7F0;
|
||
|
|
--success-border: #C2DFC6;
|
||
|
|
--warning: #C27516;
|
||
|
|
--warning-bg: #FEF5E7;
|
||
|
|
--warning-border: #F0D9A8;
|
||
|
|
--error: #C0392B;
|
||
|
|
--error-bg: #FDF0EE;
|
||
|
|
--error-border: #F0C4BE;
|
||
|
|
--running: #1A7F8E;
|
||
|
|
--running-bg: #E8F5F7;
|
||
|
|
--running-border: #B0DDE4;
|
||
|
|
|
||
|
|
/* ── Typography ── */
|
||
|
|
--font-body: 'DM Sans', system-ui, -apple-system, sans-serif;
|
||
|
|
--font-mono: 'JetBrains Mono', 'Fira Code', monospace;
|
||
|
|
|
||
|
|
/* ── Radii ── */
|
||
|
|
--radius-sm: 5px;
|
||
|
|
--radius-md: 8px;
|
||
|
|
--radius-lg: 12px;
|
||
|
|
|
||
|
|
/* ── Shadows ── */
|
||
|
|
--shadow-sm: 0 1px 2px rgba(44, 37, 32, 0.06);
|
||
|
|
--shadow-md: 0 2px 8px rgba(44, 37, 32, 0.08);
|
||
|
|
--shadow-lg: 0 4px 16px rgba(44, 37, 32, 0.10);
|
||
|
|
--shadow-card: 0 1px 3px rgba(44, 37, 32, 0.04), 0 0 0 1px rgba(44, 37, 32, 0.04);
|
||
|
|
}
|
||
|
|
|
||
|
|
html { font-size: 14px; }
|
||
|
|
body {
|
||
|
|
font-family: var(--font-body);
|
||
|
|
background: var(--bg-body);
|
||
|
|
color: var(--text-primary);
|
||
|
|
line-height: 1.5;
|
||
|
|
min-height: 100vh;
|
||
|
|
-webkit-font-smoothing: antialiased;
|
||
|
|
}
|
||
|
|
|
||
|
|
/* ═══════════════════════════════════════════════════════════════════════════
|
||
|
|
SCROLLBAR
|
||
|
|
═══════════════════════════════════════════════════════════════════════════ */
|
||
|
|
::-webkit-scrollbar { width: 6px; height: 6px; }
|
||
|
|
::-webkit-scrollbar-track { background: transparent; }
|
||
|
|
::-webkit-scrollbar-thumb { background: var(--border); border-radius: 3px; }
|
||
|
|
::-webkit-scrollbar-thumb:hover { background: var(--text-faint); }
|
||
|
|
|
||
|
|
/* ═══════════════════════════════════════════════════════════════════════════
|
||
|
|
LAYOUT SKELETON
|
||
|
|
═══════════════════════════════════════════════════════════════════════════ */
|
||
|
|
.app {
|
||
|
|
display: flex;
|
||
|
|
height: 100vh;
|
||
|
|
overflow: hidden;
|
||
|
|
}
|
||
|
|
|
||
|
|
/* ═══════════════════════════════════════════════════════════════════════════
|
||
|
|
SIDEBAR
|
||
|
|
═══════════════════════════════════════════════════════════════════════════ */
|
||
|
|
.sidebar {
|
||
|
|
width: 220px;
|
||
|
|
flex-shrink: 0;
|
||
|
|
background: var(--sidebar-bg);
|
||
|
|
display: flex;
|
||
|
|
flex-direction: column;
|
||
|
|
overflow: hidden;
|
||
|
|
}
|
||
|
|
|
||
|
|
.sidebar-logo {
|
||
|
|
padding: 18px 20px;
|
||
|
|
display: flex;
|
||
|
|
align-items: center;
|
||
|
|
gap: 10px;
|
||
|
|
border-bottom: 1px solid rgba(255,255,255,0.06);
|
||
|
|
}
|
||
|
|
|
||
|
|
.sidebar-logo svg { flex-shrink: 0; }
|
||
|
|
|
||
|
|
.sidebar-logo .brand {
|
||
|
|
font-family: var(--font-mono);
|
||
|
|
font-weight: 600;
|
||
|
|
font-size: 15px;
|
||
|
|
color: var(--amber-light);
|
||
|
|
letter-spacing: -0.3px;
|
||
|
|
}
|
||
|
|
|
||
|
|
.sidebar-logo .version {
|
||
|
|
font-family: var(--font-mono);
|
||
|
|
font-size: 10px;
|
||
|
|
color: var(--sidebar-muted);
|
||
|
|
margin-left: 2px;
|
||
|
|
}
|
||
|
|
|
||
|
|
/* Sidebar search */
|
||
|
|
.sidebar-search {
|
||
|
|
padding: 12px 14px;
|
||
|
|
}
|
||
|
|
|
||
|
|
.sidebar-search input {
|
||
|
|
width: 100%;
|
||
|
|
background: rgba(255,255,255,0.06);
|
||
|
|
border: 1px solid rgba(255,255,255,0.08);
|
||
|
|
border-radius: var(--radius-sm);
|
||
|
|
padding: 7px 10px 7px 30px;
|
||
|
|
color: var(--sidebar-text);
|
||
|
|
font-family: var(--font-body);
|
||
|
|
font-size: 12px;
|
||
|
|
outline: none;
|
||
|
|
transition: border-color 0.15s;
|
||
|
|
}
|
||
|
|
|
||
|
|
.sidebar-search input::placeholder { color: var(--sidebar-muted); }
|
||
|
|
.sidebar-search input:focus { border-color: rgba(198, 130, 14, 0.4); }
|
||
|
|
|
||
|
|
.sidebar-search-wrap {
|
||
|
|
position: relative;
|
||
|
|
}
|
||
|
|
|
||
|
|
.sidebar-search-wrap .search-icon {
|
||
|
|
position: absolute;
|
||
|
|
left: 9px;
|
||
|
|
top: 50%;
|
||
|
|
transform: translateY(-50%);
|
||
|
|
color: var(--sidebar-muted);
|
||
|
|
font-size: 12px;
|
||
|
|
}
|
||
|
|
|
||
|
|
/* Section header */
|
||
|
|
.sidebar-section {
|
||
|
|
padding: 16px 14px 6px;
|
||
|
|
font-size: 10px;
|
||
|
|
font-weight: 600;
|
||
|
|
text-transform: uppercase;
|
||
|
|
letter-spacing: 1.2px;
|
||
|
|
color: var(--sidebar-muted);
|
||
|
|
}
|
||
|
|
|
||
|
|
/* Sidebar items */
|
||
|
|
.sidebar-items {
|
||
|
|
flex: 1;
|
||
|
|
overflow-y: auto;
|
||
|
|
padding: 0 6px;
|
||
|
|
}
|
||
|
|
|
||
|
|
.sidebar-item {
|
||
|
|
display: flex;
|
||
|
|
align-items: center;
|
||
|
|
gap: 10px;
|
||
|
|
padding: 8px 14px;
|
||
|
|
border-radius: var(--radius-sm);
|
||
|
|
color: var(--sidebar-text);
|
||
|
|
font-size: 13px;
|
||
|
|
cursor: pointer;
|
||
|
|
transition: all 0.12s;
|
||
|
|
text-decoration: none;
|
||
|
|
border-left: 3px solid transparent;
|
||
|
|
margin-bottom: 1px;
|
||
|
|
}
|
||
|
|
|
||
|
|
.sidebar-item:hover {
|
||
|
|
background: var(--sidebar-hover);
|
||
|
|
color: #E8DFD4;
|
||
|
|
}
|
||
|
|
|
||
|
|
.sidebar-item.active {
|
||
|
|
background: var(--sidebar-active);
|
||
|
|
color: var(--amber-light);
|
||
|
|
border-left-color: var(--amber);
|
||
|
|
}
|
||
|
|
|
||
|
|
.sidebar-item .health {
|
||
|
|
width: 7px;
|
||
|
|
height: 7px;
|
||
|
|
border-radius: 50%;
|
||
|
|
flex-shrink: 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
.health-live { background: #5DB866; box-shadow: 0 0 6px rgba(93, 184, 102, 0.4); }
|
||
|
|
.health-stale { background: var(--warning); }
|
||
|
|
.health-dead { background: var(--sidebar-muted); }
|
||
|
|
|
||
|
|
.sidebar-item .item-info { flex: 1; min-width: 0; }
|
||
|
|
.sidebar-item .item-name {
|
||
|
|
font-weight: 500;
|
||
|
|
white-space: nowrap;
|
||
|
|
overflow: hidden;
|
||
|
|
text-overflow: ellipsis;
|
||
|
|
}
|
||
|
|
.sidebar-item .item-meta {
|
||
|
|
font-size: 11px;
|
||
|
|
color: var(--sidebar-muted);
|
||
|
|
font-family: var(--font-mono);
|
||
|
|
}
|
||
|
|
|
||
|
|
.sidebar-item .item-count {
|
||
|
|
font-family: var(--font-mono);
|
||
|
|
font-size: 11px;
|
||
|
|
color: var(--sidebar-muted);
|
||
|
|
background: rgba(255,255,255,0.06);
|
||
|
|
padding: 1px 6px;
|
||
|
|
border-radius: 10px;
|
||
|
|
}
|
||
|
|
|
||
|
|
.sidebar-item.active .item-count {
|
||
|
|
background: rgba(198, 130, 14, 0.2);
|
||
|
|
color: var(--amber-light);
|
||
|
|
}
|
||
|
|
|
||
|
|
/* Sidebar divider */
|
||
|
|
.sidebar-divider {
|
||
|
|
height: 1px;
|
||
|
|
background: rgba(255,255,255,0.06);
|
||
|
|
margin: 8px 14px;
|
||
|
|
}
|
||
|
|
|
||
|
|
/* Sidebar bottom */
|
||
|
|
.sidebar-bottom {
|
||
|
|
border-top: 1px solid rgba(255,255,255,0.06);
|
||
|
|
padding: 8px 6px;
|
||
|
|
}
|
||
|
|
|
||
|
|
.sidebar-bottom .sidebar-item {
|
||
|
|
font-size: 12px;
|
||
|
|
color: var(--sidebar-muted);
|
||
|
|
border-left: 3px solid transparent;
|
||
|
|
}
|
||
|
|
|
||
|
|
.sidebar-bottom .sidebar-item:hover {
|
||
|
|
color: var(--sidebar-text);
|
||
|
|
}
|
||
|
|
|
||
|
|
.sidebar-bottom .sidebar-item .bottom-icon {
|
||
|
|
font-size: 14px;
|
||
|
|
width: 18px;
|
||
|
|
text-align: center;
|
||
|
|
flex-shrink: 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
/* ═══════════════════════════════════════════════════════════════════════════
|
||
|
|
MAIN CONTENT AREA
|
||
|
|
═══════════════════════════════════════════════════════════════════════════ */
|
||
|
|
.main {
|
||
|
|
flex: 1;
|
||
|
|
display: flex;
|
||
|
|
flex-direction: column;
|
||
|
|
overflow: hidden;
|
||
|
|
}
|
||
|
|
|
||
|
|
/* ── Top Bar ── */
|
||
|
|
.topbar {
|
||
|
|
display: flex;
|
||
|
|
align-items: center;
|
||
|
|
gap: 12px;
|
||
|
|
padding: 0 28px;
|
||
|
|
height: 52px;
|
||
|
|
flex-shrink: 0;
|
||
|
|
background: var(--bg-surface);
|
||
|
|
border-bottom: 1px solid var(--border);
|
||
|
|
}
|
||
|
|
|
||
|
|
.topbar-breadcrumb {
|
||
|
|
display: flex;
|
||
|
|
align-items: center;
|
||
|
|
gap: 6px;
|
||
|
|
font-size: 13px;
|
||
|
|
color: var(--text-muted);
|
||
|
|
}
|
||
|
|
|
||
|
|
.topbar-breadcrumb .crumb-active {
|
||
|
|
color: var(--text-primary);
|
||
|
|
font-weight: 600;
|
||
|
|
}
|
||
|
|
|
||
|
|
.topbar-breadcrumb .crumb-sep {
|
||
|
|
color: var(--text-faint);
|
||
|
|
font-size: 11px;
|
||
|
|
}
|
||
|
|
|
||
|
|
.topbar-right {
|
||
|
|
margin-left: auto;
|
||
|
|
display: flex;
|
||
|
|
align-items: center;
|
||
|
|
gap: 12px;
|
||
|
|
}
|
||
|
|
|
||
|
|
.topbar-env {
|
||
|
|
font-family: var(--font-mono);
|
||
|
|
font-size: 10px;
|
||
|
|
font-weight: 600;
|
||
|
|
padding: 3px 10px;
|
||
|
|
border-radius: 10px;
|
||
|
|
background: var(--success-bg);
|
||
|
|
color: var(--success);
|
||
|
|
border: 1px solid var(--success-border);
|
||
|
|
text-transform: uppercase;
|
||
|
|
letter-spacing: 0.5px;
|
||
|
|
}
|
||
|
|
|
||
|
|
.topbar-user {
|
||
|
|
display: flex;
|
||
|
|
align-items: center;
|
||
|
|
gap: 8px;
|
||
|
|
font-size: 12px;
|
||
|
|
color: var(--text-secondary);
|
||
|
|
}
|
||
|
|
|
||
|
|
.topbar-avatar {
|
||
|
|
width: 28px;
|
||
|
|
height: 28px;
|
||
|
|
border-radius: 50%;
|
||
|
|
background: var(--amber-bg);
|
||
|
|
color: var(--amber);
|
||
|
|
font-weight: 600;
|
||
|
|
font-size: 11px;
|
||
|
|
display: flex;
|
||
|
|
align-items: center;
|
||
|
|
justify-content: center;
|
||
|
|
border: 1px solid var(--amber-light);
|
||
|
|
}
|
||
|
|
|
||
|
|
.topbar-search {
|
||
|
|
display: flex;
|
||
|
|
align-items: center;
|
||
|
|
gap: 6px;
|
||
|
|
padding: 5px 12px;
|
||
|
|
border: 1px solid var(--border);
|
||
|
|
border-radius: var(--radius-sm);
|
||
|
|
background: var(--bg-raised);
|
||
|
|
color: var(--text-muted);
|
||
|
|
font-size: 12px;
|
||
|
|
cursor: pointer;
|
||
|
|
transition: border-color 0.15s;
|
||
|
|
min-width: 200px;
|
||
|
|
}
|
||
|
|
|
||
|
|
.topbar-search:hover { border-color: var(--text-faint); }
|
||
|
|
|
||
|
|
.topbar-kbd {
|
||
|
|
font-family: var(--font-mono);
|
||
|
|
font-size: 10px;
|
||
|
|
background: var(--bg-surface);
|
||
|
|
border: 1px solid var(--border);
|
||
|
|
padding: 0 4px;
|
||
|
|
border-radius: 3px;
|
||
|
|
color: var(--text-faint);
|
||
|
|
margin-left: auto;
|
||
|
|
}
|
||
|
|
|
||
|
|
/* ── Content scroll container ── */
|
||
|
|
.content {
|
||
|
|
flex: 1;
|
||
|
|
overflow-y: auto;
|
||
|
|
padding: 24px 28px 40px;
|
||
|
|
}
|
||
|
|
|
||
|
|
/* ═══════════════════════════════════════════════════════════════════════════
|
||
|
|
PAGE HEADER
|
||
|
|
═══════════════════════════════════════════════════════════════════════════ */
|
||
|
|
.page-header {
|
||
|
|
display: flex;
|
||
|
|
align-items: flex-start;
|
||
|
|
justify-content: space-between;
|
||
|
|
margin-bottom: 20px;
|
||
|
|
}
|
||
|
|
|
||
|
|
.page-header h1 {
|
||
|
|
font-size: 20px;
|
||
|
|
font-weight: 700;
|
||
|
|
letter-spacing: -0.3px;
|
||
|
|
color: var(--text-primary);
|
||
|
|
}
|
||
|
|
|
||
|
|
.page-header .subtitle {
|
||
|
|
font-size: 13px;
|
||
|
|
color: var(--text-muted);
|
||
|
|
margin-top: 2px;
|
||
|
|
}
|
||
|
|
|
||
|
|
.live-btn {
|
||
|
|
display: flex;
|
||
|
|
align-items: center;
|
||
|
|
gap: 7px;
|
||
|
|
padding: 7px 16px;
|
||
|
|
border: 1px solid var(--success-border);
|
||
|
|
border-radius: var(--radius-sm);
|
||
|
|
background: var(--success-bg);
|
||
|
|
color: var(--success);
|
||
|
|
font-family: var(--font-mono);
|
||
|
|
font-size: 12px;
|
||
|
|
font-weight: 500;
|
||
|
|
cursor: pointer;
|
||
|
|
transition: all 0.15s;
|
||
|
|
}
|
||
|
|
|
||
|
|
.live-btn:hover {
|
||
|
|
background: #E2F0E4;
|
||
|
|
}
|
||
|
|
|
||
|
|
.live-dot {
|
||
|
|
width: 7px;
|
||
|
|
height: 7px;
|
||
|
|
border-radius: 50%;
|
||
|
|
background: var(--success);
|
||
|
|
animation: pulse 2s ease-in-out infinite;
|
||
|
|
}
|
||
|
|
|
||
|
|
@keyframes pulse {
|
||
|
|
0%, 100% { box-shadow: 0 0 0 0 rgba(61, 124, 71, 0.35); }
|
||
|
|
50% { box-shadow: 0 0 0 5px rgba(61, 124, 71, 0); }
|
||
|
|
}
|
||
|
|
|
||
|
|
/* ═══════════════════════════════════════════════════════════════════════════
|
||
|
|
FILTER BAR
|
||
|
|
═══════════════════════════════════════════════════════════════════════════ */
|
||
|
|
.filter-bar {
|
||
|
|
display: flex;
|
||
|
|
align-items: center;
|
||
|
|
gap: 8px;
|
||
|
|
margin-bottom: 16px;
|
||
|
|
flex-wrap: wrap;
|
||
|
|
}
|
||
|
|
|
||
|
|
.filter-input-wrap {
|
||
|
|
position: relative;
|
||
|
|
flex: 1;
|
||
|
|
max-width: 360px;
|
||
|
|
}
|
||
|
|
|
||
|
|
.filter-input-wrap .fi-icon {
|
||
|
|
position: absolute;
|
||
|
|
left: 10px;
|
||
|
|
top: 50%;
|
||
|
|
transform: translateY(-50%);
|
||
|
|
color: var(--text-faint);
|
||
|
|
font-size: 13px;
|
||
|
|
}
|
||
|
|
|
||
|
|
.filter-input {
|
||
|
|
width: 100%;
|
||
|
|
padding: 8px 12px 8px 32px;
|
||
|
|
border: 1px solid var(--border);
|
||
|
|
border-radius: var(--radius-sm);
|
||
|
|
background: var(--bg-surface);
|
||
|
|
color: var(--text-primary);
|
||
|
|
font-family: var(--font-body);
|
||
|
|
font-size: 13px;
|
||
|
|
outline: none;
|
||
|
|
transition: border-color 0.15s;
|
||
|
|
box-shadow: var(--shadow-sm);
|
||
|
|
}
|
||
|
|
|
||
|
|
.filter-input::placeholder { color: var(--text-faint); }
|
||
|
|
.filter-input:focus { border-color: var(--amber); box-shadow: 0 0 0 3px var(--amber-bg); }
|
||
|
|
|
||
|
|
.filter-pills {
|
||
|
|
display: flex;
|
||
|
|
gap: 4px;
|
||
|
|
}
|
||
|
|
|
||
|
|
.filter-pill {
|
||
|
|
padding: 6px 14px;
|
||
|
|
border: 1px solid var(--border);
|
||
|
|
border-radius: 20px;
|
||
|
|
background: var(--bg-surface);
|
||
|
|
color: var(--text-secondary);
|
||
|
|
font-size: 12px;
|
||
|
|
font-weight: 500;
|
||
|
|
cursor: pointer;
|
||
|
|
transition: all 0.12s;
|
||
|
|
white-space: nowrap;
|
||
|
|
box-shadow: var(--shadow-sm);
|
||
|
|
}
|
||
|
|
|
||
|
|
.filter-pill:hover {
|
||
|
|
border-color: var(--text-faint);
|
||
|
|
background: var(--bg-raised);
|
||
|
|
}
|
||
|
|
|
||
|
|
.filter-pill.active {
|
||
|
|
background: var(--amber-bg);
|
||
|
|
border-color: var(--amber-light);
|
||
|
|
color: var(--amber-deep);
|
||
|
|
font-weight: 600;
|
||
|
|
}
|
||
|
|
|
||
|
|
.filter-pill .pill-count {
|
||
|
|
font-family: var(--font-mono);
|
||
|
|
font-size: 11px;
|
||
|
|
margin-left: 4px;
|
||
|
|
opacity: 0.7;
|
||
|
|
}
|
||
|
|
|
||
|
|
.filter-pill.active .pill-count { opacity: 1; }
|
||
|
|
|
||
|
|
.filter-select {
|
||
|
|
padding: 7px 28px 7px 10px;
|
||
|
|
border: 1px solid var(--border);
|
||
|
|
border-radius: var(--radius-sm);
|
||
|
|
background: var(--bg-surface);
|
||
|
|
color: var(--text-secondary);
|
||
|
|
font-family: var(--font-body);
|
||
|
|
font-size: 12px;
|
||
|
|
cursor: pointer;
|
||
|
|
outline: none;
|
||
|
|
appearance: none;
|
||
|
|
background-image: url("data:image/svg+xml,%3Csvg width='10' height='6' viewBox='0 0 10 6' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M1 1l4 4 4-4' fill='none' stroke='%239C9184' stroke-width='1.5' stroke-linecap='round'/%3E%3C/svg%3E");
|
||
|
|
background-repeat: no-repeat;
|
||
|
|
background-position: right 10px center;
|
||
|
|
box-shadow: var(--shadow-sm);
|
||
|
|
}
|
||
|
|
|
||
|
|
/* ═══════════════════════════════════════════════════════════════════════════
|
||
|
|
STATS BAR
|
||
|
|
═══════════════════════════════════════════════════════════════════════════ */
|
||
|
|
.stats-bar {
|
||
|
|
display: flex;
|
||
|
|
gap: 12px;
|
||
|
|
margin-bottom: 20px;
|
||
|
|
}
|
||
|
|
|
||
|
|
.stat-card {
|
||
|
|
flex: 1;
|
||
|
|
background: var(--bg-surface);
|
||
|
|
border: 1px solid var(--border-subtle);
|
||
|
|
border-radius: var(--radius-md);
|
||
|
|
padding: 14px 18px;
|
||
|
|
box-shadow: var(--shadow-card);
|
||
|
|
display: flex;
|
||
|
|
align-items: center;
|
||
|
|
gap: 14px;
|
||
|
|
transition: box-shadow 0.15s;
|
||
|
|
}
|
||
|
|
|
||
|
|
.stat-card:hover {
|
||
|
|
box-shadow: var(--shadow-md);
|
||
|
|
}
|
||
|
|
|
||
|
|
.stat-icon {
|
||
|
|
width: 38px;
|
||
|
|
height: 38px;
|
||
|
|
border-radius: var(--radius-md);
|
||
|
|
display: flex;
|
||
|
|
align-items: center;
|
||
|
|
justify-content: center;
|
||
|
|
font-size: 16px;
|
||
|
|
flex-shrink: 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
.stat-icon.total { background: var(--bg-inset); color: var(--text-secondary); }
|
||
|
|
.stat-icon.success { background: var(--success-bg); color: var(--success); }
|
||
|
|
.stat-icon.warning { background: var(--warning-bg); color: var(--warning); }
|
||
|
|
.stat-icon.error { background: var(--error-bg); color: var(--error); }
|
||
|
|
.stat-icon.duration { background: var(--running-bg); color: var(--running); }
|
||
|
|
|
||
|
|
.stat-info { min-width: 0; }
|
||
|
|
|
||
|
|
.stat-label {
|
||
|
|
font-size: 11px;
|
||
|
|
font-weight: 500;
|
||
|
|
text-transform: uppercase;
|
||
|
|
letter-spacing: 0.6px;
|
||
|
|
color: var(--text-muted);
|
||
|
|
margin-bottom: 1px;
|
||
|
|
}
|
||
|
|
|
||
|
|
.stat-value {
|
||
|
|
font-family: var(--font-mono);
|
||
|
|
font-size: 20px;
|
||
|
|
font-weight: 600;
|
||
|
|
color: var(--text-primary);
|
||
|
|
line-height: 1.2;
|
||
|
|
}
|
||
|
|
|
||
|
|
.stat-value.success-val { color: var(--success); }
|
||
|
|
.stat-value.warning-val { color: var(--warning); }
|
||
|
|
.stat-value.error-val { color: var(--error); }
|
||
|
|
|
||
|
|
.stat-trend {
|
||
|
|
font-family: var(--font-mono);
|
||
|
|
font-size: 11px;
|
||
|
|
color: var(--success);
|
||
|
|
margin-top: 1px;
|
||
|
|
}
|
||
|
|
|
||
|
|
.stat-trend.down { color: var(--error); }
|
||
|
|
|
||
|
|
/* ═══════════════════════════════════════════════════════════════════════════
|
||
|
|
EXECUTION TABLE
|
||
|
|
═══════════════════════════════════════════════════════════════════════════ */
|
||
|
|
.table-section {
|
||
|
|
background: var(--bg-surface);
|
||
|
|
border: 1px solid var(--border-subtle);
|
||
|
|
border-radius: var(--radius-lg);
|
||
|
|
box-shadow: var(--shadow-card);
|
||
|
|
overflow: hidden;
|
||
|
|
margin-bottom: 24px;
|
||
|
|
}
|
||
|
|
|
||
|
|
.table-header {
|
||
|
|
display: flex;
|
||
|
|
align-items: center;
|
||
|
|
justify-content: space-between;
|
||
|
|
padding: 12px 18px;
|
||
|
|
border-bottom: 1px solid var(--border-subtle);
|
||
|
|
}
|
||
|
|
|
||
|
|
.table-title {
|
||
|
|
font-size: 13px;
|
||
|
|
font-weight: 600;
|
||
|
|
color: var(--text-primary);
|
||
|
|
}
|
||
|
|
|
||
|
|
.table-meta {
|
||
|
|
font-family: var(--font-mono);
|
||
|
|
font-size: 11px;
|
||
|
|
color: var(--text-muted);
|
||
|
|
}
|
||
|
|
|
||
|
|
table {
|
||
|
|
width: 100%;
|
||
|
|
border-collapse: collapse;
|
||
|
|
}
|
||
|
|
|
||
|
|
thead {
|
||
|
|
background: var(--bg-raised);
|
||
|
|
border-bottom: 1px solid var(--border);
|
||
|
|
}
|
||
|
|
|
||
|
|
th {
|
||
|
|
padding: 10px 16px;
|
||
|
|
text-align: left;
|
||
|
|
font-size: 10px;
|
||
|
|
font-weight: 600;
|
||
|
|
text-transform: uppercase;
|
||
|
|
letter-spacing: 0.8px;
|
||
|
|
color: var(--text-muted);
|
||
|
|
white-space: nowrap;
|
||
|
|
user-select: none;
|
||
|
|
cursor: pointer;
|
||
|
|
transition: color 0.12s;
|
||
|
|
}
|
||
|
|
|
||
|
|
th:hover { color: var(--text-secondary); }
|
||
|
|
|
||
|
|
th.sorted {
|
||
|
|
color: var(--amber);
|
||
|
|
}
|
||
|
|
|
||
|
|
th .sort-arrow {
|
||
|
|
font-size: 8px;
|
||
|
|
margin-left: 3px;
|
||
|
|
opacity: 0.4;
|
||
|
|
}
|
||
|
|
|
||
|
|
th.sorted .sort-arrow { opacity: 1; }
|
||
|
|
|
||
|
|
tr {
|
||
|
|
border-bottom: 1px solid var(--border-subtle);
|
||
|
|
transition: background 0.08s;
|
||
|
|
cursor: pointer;
|
||
|
|
}
|
||
|
|
|
||
|
|
tr:last-child { border-bottom: none; }
|
||
|
|
tr:hover { background: var(--bg-hover); }
|
||
|
|
|
||
|
|
td {
|
||
|
|
padding: 10px 16px;
|
||
|
|
font-size: 13px;
|
||
|
|
vertical-align: middle;
|
||
|
|
white-space: nowrap;
|
||
|
|
}
|
||
|
|
|
||
|
|
.td-route {
|
||
|
|
font-weight: 500;
|
||
|
|
color: var(--text-primary);
|
||
|
|
}
|
||
|
|
|
||
|
|
.td-route:hover { color: var(--amber); }
|
||
|
|
|
||
|
|
.td-mono {
|
||
|
|
font-family: var(--font-mono);
|
||
|
|
font-size: 12px;
|
||
|
|
color: var(--text-secondary);
|
||
|
|
}
|
||
|
|
|
||
|
|
.td-id {
|
||
|
|
font-family: var(--font-mono);
|
||
|
|
font-size: 11px;
|
||
|
|
color: var(--text-muted);
|
||
|
|
max-width: 120px;
|
||
|
|
overflow: hidden;
|
||
|
|
text-overflow: ellipsis;
|
||
|
|
}
|
||
|
|
|
||
|
|
.td-group {
|
||
|
|
display: flex;
|
||
|
|
align-items: center;
|
||
|
|
gap: 6px;
|
||
|
|
}
|
||
|
|
|
||
|
|
.td-group-dot {
|
||
|
|
width: 6px;
|
||
|
|
height: 6px;
|
||
|
|
border-radius: 50%;
|
||
|
|
background: var(--amber);
|
||
|
|
}
|
||
|
|
|
||
|
|
/* Status badges */
|
||
|
|
.status-badge {
|
||
|
|
display: inline-flex;
|
||
|
|
align-items: center;
|
||
|
|
gap: 5px;
|
||
|
|
padding: 3px 10px;
|
||
|
|
border-radius: 12px;
|
||
|
|
font-size: 11px;
|
||
|
|
font-weight: 600;
|
||
|
|
letter-spacing: 0.2px;
|
||
|
|
}
|
||
|
|
|
||
|
|
.status-success {
|
||
|
|
background: var(--success-bg);
|
||
|
|
color: var(--success);
|
||
|
|
border: 1px solid var(--success-border);
|
||
|
|
}
|
||
|
|
|
||
|
|
.status-warning {
|
||
|
|
background: var(--warning-bg);
|
||
|
|
color: var(--warning);
|
||
|
|
border: 1px solid var(--warning-border);
|
||
|
|
}
|
||
|
|
|
||
|
|
.status-error {
|
||
|
|
background: var(--error-bg);
|
||
|
|
color: var(--error);
|
||
|
|
border: 1px solid var(--error-border);
|
||
|
|
}
|
||
|
|
|
||
|
|
.status-running {
|
||
|
|
background: var(--running-bg);
|
||
|
|
color: var(--running);
|
||
|
|
border: 1px solid var(--running-border);
|
||
|
|
}
|
||
|
|
|
||
|
|
.status-dot {
|
||
|
|
width: 5px;
|
||
|
|
height: 5px;
|
||
|
|
border-radius: 50%;
|
||
|
|
}
|
||
|
|
|
||
|
|
.status-success .status-dot { background: var(--success); }
|
||
|
|
.status-warning .status-dot { background: var(--warning); }
|
||
|
|
.status-error .status-dot { background: var(--error); }
|
||
|
|
.status-running .status-dot { background: var(--running); animation: pulse-sm 1.5s ease-in-out infinite; }
|
||
|
|
|
||
|
|
@keyframes pulse-sm {
|
||
|
|
0%, 100% { box-shadow: 0 0 0 0 rgba(26, 127, 142, 0.3); }
|
||
|
|
50% { box-shadow: 0 0 0 3px rgba(26, 127, 142, 0); }
|
||
|
|
}
|
||
|
|
|
||
|
|
/* Duration bar (visual sparkline in duration column) */
|
||
|
|
.duration-bar-wrap {
|
||
|
|
display: flex;
|
||
|
|
align-items: center;
|
||
|
|
gap: 8px;
|
||
|
|
}
|
||
|
|
|
||
|
|
.duration-bar {
|
||
|
|
width: 60px;
|
||
|
|
height: 4px;
|
||
|
|
background: var(--bg-inset);
|
||
|
|
border-radius: 2px;
|
||
|
|
overflow: hidden;
|
||
|
|
}
|
||
|
|
|
||
|
|
.duration-bar-fill {
|
||
|
|
height: 100%;
|
||
|
|
border-radius: 2px;
|
||
|
|
background: var(--running);
|
||
|
|
transition: width 0.3s ease;
|
||
|
|
}
|
||
|
|
|
||
|
|
.duration-bar-fill.fast { background: var(--success); }
|
||
|
|
.duration-bar-fill.medium { background: var(--warning); }
|
||
|
|
.duration-bar-fill.slow { background: var(--error); }
|
||
|
|
|
||
|
|
/* Pagination */
|
||
|
|
.table-footer {
|
||
|
|
display: flex;
|
||
|
|
align-items: center;
|
||
|
|
justify-content: space-between;
|
||
|
|
padding: 10px 18px;
|
||
|
|
border-top: 1px solid var(--border-subtle);
|
||
|
|
font-size: 12px;
|
||
|
|
color: var(--text-muted);
|
||
|
|
}
|
||
|
|
|
||
|
|
.pagination {
|
||
|
|
display: flex;
|
||
|
|
align-items: center;
|
||
|
|
gap: 4px;
|
||
|
|
}
|
||
|
|
|
||
|
|
.page-btn {
|
||
|
|
padding: 4px 10px;
|
||
|
|
border: 1px solid var(--border);
|
||
|
|
border-radius: var(--radius-sm);
|
||
|
|
background: var(--bg-surface);
|
||
|
|
color: var(--text-secondary);
|
||
|
|
font-size: 12px;
|
||
|
|
font-family: var(--font-mono);
|
||
|
|
cursor: pointer;
|
||
|
|
transition: all 0.12s;
|
||
|
|
}
|
||
|
|
|
||
|
|
.page-btn:hover { background: var(--bg-raised); border-color: var(--text-faint); }
|
||
|
|
.page-btn.active {
|
||
|
|
background: var(--amber-bg);
|
||
|
|
border-color: var(--amber-light);
|
||
|
|
color: var(--amber-deep);
|
||
|
|
font-weight: 600;
|
||
|
|
}
|
||
|
|
|
||
|
|
/* ═══════════════════════════════════════════════════════════════════════════
|
||
|
|
METRICS PANEL
|
||
|
|
═══════════════════════════════════════════════════════════════════════════ */
|
||
|
|
.metrics-row {
|
||
|
|
display: grid;
|
||
|
|
grid-template-columns: 1fr 1fr 1fr;
|
||
|
|
gap: 16px;
|
||
|
|
margin-bottom: 24px;
|
||
|
|
}
|
||
|
|
|
||
|
|
.metric-card {
|
||
|
|
background: var(--bg-surface);
|
||
|
|
border: 1px solid var(--border-subtle);
|
||
|
|
border-radius: var(--radius-lg);
|
||
|
|
box-shadow: var(--shadow-card);
|
||
|
|
overflow: hidden;
|
||
|
|
}
|
||
|
|
|
||
|
|
.metric-card-header {
|
||
|
|
padding: 14px 18px 0;
|
||
|
|
display: flex;
|
||
|
|
align-items: center;
|
||
|
|
justify-content: space-between;
|
||
|
|
}
|
||
|
|
|
||
|
|
.metric-card-title {
|
||
|
|
font-size: 12px;
|
||
|
|
font-weight: 600;
|
||
|
|
color: var(--text-secondary);
|
||
|
|
text-transform: uppercase;
|
||
|
|
letter-spacing: 0.5px;
|
||
|
|
}
|
||
|
|
|
||
|
|
.metric-card-value {
|
||
|
|
font-family: var(--font-mono);
|
||
|
|
font-size: 14px;
|
||
|
|
font-weight: 600;
|
||
|
|
color: var(--text-primary);
|
||
|
|
}
|
||
|
|
|
||
|
|
.metric-chart {
|
||
|
|
padding: 12px 18px 14px;
|
||
|
|
height: 100px;
|
||
|
|
position: relative;
|
||
|
|
}
|
||
|
|
|
||
|
|
/* SVG Chart styling */
|
||
|
|
.chart-line {
|
||
|
|
fill: none;
|
||
|
|
stroke-width: 2;
|
||
|
|
stroke-linecap: round;
|
||
|
|
stroke-linejoin: round;
|
||
|
|
}
|
||
|
|
|
||
|
|
.chart-area {
|
||
|
|
opacity: 0.12;
|
||
|
|
}
|
||
|
|
|
||
|
|
.chart-grid-line {
|
||
|
|
stroke: var(--border-subtle);
|
||
|
|
stroke-width: 1;
|
||
|
|
stroke-dasharray: 3 3;
|
||
|
|
}
|
||
|
|
|
||
|
|
.chart-label {
|
||
|
|
font-family: var(--font-mono);
|
||
|
|
font-size: 9px;
|
||
|
|
fill: var(--text-faint);
|
||
|
|
}
|
||
|
|
|
||
|
|
/* ═══════════════════════════════════════════════════════════════════════════
|
||
|
|
UTILITY CLASSES
|
||
|
|
═══════════════════════════════════════════════════════════════════════════ */
|
||
|
|
.mono { font-family: var(--font-mono); }
|
||
|
|
.text-muted { color: var(--text-muted); }
|
||
|
|
.text-secondary { color: var(--text-secondary); }
|
||
|
|
.flex-center { display: flex; align-items: center; }
|
||
|
|
|
||
|
|
/* Fade-in animation */
|
||
|
|
@keyframes fadeIn {
|
||
|
|
from { opacity: 0; transform: translateY(6px); }
|
||
|
|
to { opacity: 1; transform: translateY(0); }
|
||
|
|
}
|
||
|
|
|
||
|
|
.animate-in {
|
||
|
|
animation: fadeIn 0.35s ease-out both;
|
||
|
|
}
|
||
|
|
|
||
|
|
.delay-1 { animation-delay: 0.04s; }
|
||
|
|
.delay-2 { animation-delay: 0.08s; }
|
||
|
|
.delay-3 { animation-delay: 0.12s; }
|
||
|
|
.delay-4 { animation-delay: 0.16s; }
|
||
|
|
.delay-5 { animation-delay: 0.20s; }
|
||
|
|
</style>
|
||
|
|
</head>
|
||
|
|
<body>
|
||
|
|
<div class="app">
|
||
|
|
<!-- ═══════════════════════════════════════════════════════════════════
|
||
|
|
SIDEBAR
|
||
|
|
═══════════════════════════════════════════════════════════════════ -->
|
||
|
|
<aside class="sidebar">
|
||
|
|
<div class="sidebar-logo">
|
||
|
|
<svg width="24" height="26" viewBox="940 300 900 1000" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||
|
|
<path style="fill:#C6820E" d="M 1385.2768,1205.0273 c -1.7727,-1.0809 -3.4419,-2.9917 -3.7093,-4.2463 -0.2674,-1.2545 -0.6851,-23.881 -0.9282,-50.281 -0.4544,-49.3389 -1.4003,-65.7355 -5.6645,-98.1921 -10.4552,-79.57719 -28.3441,-125.96796 -62.5438,-162.19311 -9.2529,-9.80096 -19.9748,-18.38696 -33.931,-27.17162 -12.6119,-7.93853 -24.8581,-13.73088 -49.5,-23.41316 -41.7081,-16.38789 -67.8677,-32.29827 -89.0588,-54.16599 -34.7586,-35.86827 -54.3653,-83.30392 -59.0504,-142.86402 -0.8357,-10.6245 -0.92,-22.5842 -0.2891,-41 0.4899,-14.3 0.8164,-35.225 0.7255,-46.5 -0.1983,-24.59199 -2.0251,-34.76973 -8.4617,-47.14159 -6.2021,-11.92135 -10.364,-15.10789 -36.2345,-27.74305 -25.4032,-12.40694 -27.7701,-13.30168 -35.4717,-13.40961 -4.63013,-0.0649 -7.47783,0.72754 -15.6593,4.35747 -9.86218,4.37563 -10.15161,4.43672 -21,4.43267 -10.86566,-0.004 -11.08917,-0.0517 -18.30169,-3.90103 -17.43524,-9.3052 -21.50075,-23.5772 -13.55784,-47.59486 2.73631,-8.27402 10.00732,-22.43593 14.69263,-28.61719 5.4984,-7.25394 10.89014,-11.83885 20.83968,-17.72117 15.06768,-8.90827 29.60254,-11.98884 63.90372,-13.54403 l 16.5765,-0.75156 14.9235,-7.05735 c 8.2079,-3.88154 17.1735,-7.76831 19.9235,-8.63727 7.7052,-2.43474 21.059,-4.67186 27.8605,-4.66741 8.0518,0.005 22.643,2.41202 30.0139,4.95066 l 5.8744,2.02321 4.8856,-4.09041 c 10.341,-8.65797 18.6496,-12.95738 28.96,-14.98583 6.9966,-1.37649 26.3532,-0.64631 32.1116,1.21134 4.5531,1.46885 5.4951,3.7902 6.3689,15.69592 1.5167,20.66426 -5.0112,40.44987 -18.1772,55.09363 -4.3065,4.78983 -4.5016,5.25488 -3.4977,8.33516 4.5184,13.86447 5.3154,38.07517 2.1537,65.42564 -5.169,44.71349 -5.0411,70.7797 0.5404,110.15637 6.8135,48.06863 22.3335,73.51874 48.2051,79.04779 24.1748,5.16643 45.2921,-5.78181 66.8353,-34.65077 4.809,-6.4442 11.1363,-14.93006 14.0608,-18.85747 7.3865,-9.91943 25.6102,-27.11708 35.952,-33.92766 12.5235,-8.24739 26.8808,-14.74833 42.8527,-19.40354 15.4108,-4.49168 26.7091,-9.74984 36.2432,-16.86731 3.4338,-2.56341 13.3338,-12.03104 22,-21.03916 26.2356,-27.27067 44.5755,-40.32368 66.9928,-47.68062 19.1052,-6.26998 35.4927,-7.73718 50.8681,-4.55427 37.0856,7.67726 63.5507,26.77589 100.2888,72.37362 16.6011,20.60463 29.9711,32.07977 51.6071,44.29313 39.3131,22.19195 50.1228,30.50985 68.8076,52.94655 5.4963,6.6 12.9187,14.91604 16.4941,18.4801 33.6796,33.57259 54.1965,72.51092 61.6587,117.0199 2.7315,16.29242 3.3374,26.62538 3.1861,54.33713 l -0.1465,26.83714 -2.7975,2.40572 c -3.9132,3.36522 -7.2806,3.99163 -11.2591,2.09442 -6.4731,-3.08682 -6.5715,-3.57833 -6.878,-34.36929 -0.2908,-29.2175 -2.0265,-46.13705 -6.6479,-64.80512 -3.2997,-13.32891 -12.2529,-34.61943 -17.0313,-40.5 l -2.0314,-2.5 0.5698,3.5 c 5.8574,35.97875 4.2855,72.40287 -5.3946,125 -8.4016,45.65054 -4.3665,69.39588 20.7318,122 11.4175,23.93009 12.5452,27.25907 12.4212,36.6684 -0.1018,7.7227 -2.5346,19.5162 -13.1674,63.8316 -1.0558,4.4 -3.5336,14.975 -5.5063,23.5 -1.9727,8.525 -4.2259,18.2 -5.0072,21.5 -0.7812,3.3 -3.4495,15.225 -5.9296,26.5 -9.1636,41.6596 -13.4372,59.8787 -14.5204,61.9027 -2.4994,4.6702 -5.2312,5.0973 -32.6024,5.0973 H 1765.8 l -3.4,-3.4 c -2.3518,-2.3518 -3.4,-4.3226 -3.4,-6.3925 0,-1.6458 2.2347,-12.1533 4.966,-23.35 8.6906,-35.6259 11.6969,-54.778 12.6921,-80.8575 1.3475,-35.3073 -4.6406,-62.7687 -18.7825,-86.137 -7.6672,-12.66954 -11.9163,-17.84148 -29.8756,-36.36415 -22.9362,-23.65574 -34.6222,-39.72583 -47.9268,-65.90697 -5.7294,-11.27448 -13.6061,-31.99995 -15.5051,-40.79778 -0.3212,-1.48824 -1.0176,-3.84619 -1.5475,-5.2399 l -0.9634,-2.534 -11.7786,7.15145 c -38.634,23.45687 -74.5513,34.71091 -124.1895,38.91257 -14.5402,1.23075 -58.2359,0.66344 -71.9142,-0.93369 -5.4419,-0.63542 -6.4542,-0.49723 -7.25,0.98972 -0.5545,1.03621 -0.9249,60.63835 -0.9249,148.84365 0,161.6262 0.4025,151.2052 -5.9673,154.4992 -2.3865,1.2341 -7.4633,1.5162 -27.233,1.5132 -22.3926,-0 -24.5527,-0.158 -27.5229,-1.969 z M 1424,1045.6452 c 0,-87.21053 0.3878,-144.17994 1.0365,-152.24998 1.8115,-22.53829 7.2373,-44.8067 16.1142,-66.13567 20.7842,-49.93942 66.8961,-95.01414 129.8493,-126.92865 14.9469,-7.57742 29.283
|
||
|
|
</svg>
|
||
|
|
<div>
|
||
|
|
<span class="brand">cameleer</span><span class="version">v3</span>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<div class="sidebar-search">
|
||
|
|
<div class="sidebar-search-wrap">
|
||
|
|
<span class="search-icon">◊</span>
|
||
|
|
<input type="text" placeholder="Filter applications...">
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<div class="sidebar-section">Applications</div>
|
||
|
|
|
||
|
|
<div class="sidebar-items">
|
||
|
|
<div class="sidebar-item">
|
||
|
|
<span class="health health-live"></span>
|
||
|
|
<div class="item-info">
|
||
|
|
<div class="item-name">All Applications</div>
|
||
|
|
</div>
|
||
|
|
<span class="item-count">3</span>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<div style="height: 1px; background: rgba(255,255,255,0.06); margin: 4px 14px;"></div>
|
||
|
|
|
||
|
|
<div class="sidebar-item active">
|
||
|
|
<span class="health health-live"></span>
|
||
|
|
<div class="item-info">
|
||
|
|
<div class="item-name">order-service</div>
|
||
|
|
<div class="item-meta">2 instances</div>
|
||
|
|
</div>
|
||
|
|
<span class="item-count">847</span>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<div class="sidebar-item">
|
||
|
|
<span class="health health-live"></span>
|
||
|
|
<div class="item-info">
|
||
|
|
<div class="item-name">payment-gateway</div>
|
||
|
|
<div class="item-meta">1 instance</div>
|
||
|
|
</div>
|
||
|
|
<span class="item-count">312</span>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<div class="sidebar-item">
|
||
|
|
<span class="health health-stale"></span>
|
||
|
|
<div class="item-info">
|
||
|
|
<div class="item-name">notification-hub</div>
|
||
|
|
<div class="item-meta">1 instance</div>
|
||
|
|
</div>
|
||
|
|
<span class="item-count">45</span>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<div class="sidebar-section">Routes</div>
|
||
|
|
|
||
|
|
<div class="sidebar-item" style="padding-left: 24px;">
|
||
|
|
<span style="color: var(--sidebar-muted); font-size: 11px;">▸</span>
|
||
|
|
<div class="item-info">
|
||
|
|
<div class="item-name">order-processing</div>
|
||
|
|
</div>
|
||
|
|
<span class="item-count">523</span>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<div class="sidebar-item" style="padding-left: 24px;">
|
||
|
|
<span style="color: var(--sidebar-muted); font-size: 11px;">▸</span>
|
||
|
|
<div class="item-info">
|
||
|
|
<div class="item-name">order-validation</div>
|
||
|
|
</div>
|
||
|
|
<span class="item-count">215</span>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<div class="sidebar-item" style="padding-left: 24px;">
|
||
|
|
<span style="color: var(--sidebar-muted); font-size: 11px;">▸</span>
|
||
|
|
<div class="item-info">
|
||
|
|
<div class="item-name">inventory-check</div>
|
||
|
|
</div>
|
||
|
|
<span class="item-count">109</span>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<div class="sidebar-bottom">
|
||
|
|
<div class="sidebar-item">
|
||
|
|
<span class="bottom-icon">•</span>
|
||
|
|
<div class="item-info"><div class="item-name">Route Diagrams</div></div>
|
||
|
|
</div>
|
||
|
|
<div class="sidebar-item">
|
||
|
|
<span class="bottom-icon">⚙</span>
|
||
|
|
<div class="item-info"><div class="item-name">Admin</div></div>
|
||
|
|
</div>
|
||
|
|
<div class="sidebar-item">
|
||
|
|
<span class="bottom-icon">«»</span>
|
||
|
|
<div class="item-info"><div class="item-name">API Docs</div></div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</aside>
|
||
|
|
|
||
|
|
<!-- ═══════════════════════════════════════════════════════════════════
|
||
|
|
MAIN
|
||
|
|
═══════════════════════════════════════════════════════════════════ -->
|
||
|
|
<div class="main">
|
||
|
|
<!-- Top bar -->
|
||
|
|
<div class="topbar">
|
||
|
|
<div class="topbar-breadcrumb">
|
||
|
|
<span>Applications</span>
|
||
|
|
<span class="crumb-sep">/</span>
|
||
|
|
<span class="crumb-active">order-service</span>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<div class="topbar-search">
|
||
|
|
<span style="font-size: 13px; color: var(--text-faint);">🔎︎</span>
|
||
|
|
<span>Search executions...</span>
|
||
|
|
<span class="topbar-kbd">Ctrl+K</span>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<div class="topbar-right">
|
||
|
|
<span class="topbar-env">PRODUCTION</span>
|
||
|
|
<div class="topbar-user">
|
||
|
|
<span>hendrik</span>
|
||
|
|
<div class="topbar-avatar">H</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<!-- Content -->
|
||
|
|
<div class="content">
|
||
|
|
<!-- Page header -->
|
||
|
|
<div class="page-header animate-in">
|
||
|
|
<div>
|
||
|
|
<h1>Execution Explorer</h1>
|
||
|
|
<div class="subtitle">order-service — last 24 hours</div>
|
||
|
|
</div>
|
||
|
|
<button class="live-btn">
|
||
|
|
<span class="live-dot"></span>
|
||
|
|
LIVE
|
||
|
|
</button>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<!-- Filter bar -->
|
||
|
|
<div class="filter-bar animate-in delay-1">
|
||
|
|
<div class="filter-input-wrap">
|
||
|
|
<span class="fi-icon">🔎︎</span>
|
||
|
|
<input class="filter-input" type="text" placeholder="Search by route, correlation ID, body content...">
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<div class="filter-pills">
|
||
|
|
<div class="filter-pill active">All<span class="pill-count">1,204</span></div>
|
||
|
|
<div class="filter-pill">
|
||
|
|
<span style="color: var(--success);">•</span> Success<span class="pill-count">1,142</span>
|
||
|
|
</div>
|
||
|
|
<div class="filter-pill">
|
||
|
|
<span style="color: var(--warning);">•</span> Warning<span class="pill-count">38</span>
|
||
|
|
</div>
|
||
|
|
<div class="filter-pill">
|
||
|
|
<span style="color: var(--error);">•</span> Error<span class="pill-count">7</span>
|
||
|
|
</div>
|
||
|
|
<div class="filter-pill">
|
||
|
|
<span style="color: var(--running);">•</span> Running<span class="pill-count">17</span>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<select class="filter-select">
|
||
|
|
<option>Last 24 hours</option>
|
||
|
|
<option>Last 1 hour</option>
|
||
|
|
<option>Last 7 days</option>
|
||
|
|
<option>Custom range</option>
|
||
|
|
</select>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<!-- Stats bar -->
|
||
|
|
<div class="stats-bar animate-in delay-2">
|
||
|
|
<div class="stat-card">
|
||
|
|
<div class="stat-icon total">∑</div>
|
||
|
|
<div class="stat-info">
|
||
|
|
<div class="stat-label">Total</div>
|
||
|
|
<div class="stat-value">1,204</div>
|
||
|
|
<div class="stat-trend">+12% vs yesterday</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
<div class="stat-card">
|
||
|
|
<div class="stat-icon success">✓</div>
|
||
|
|
<div class="stat-info">
|
||
|
|
<div class="stat-label">Success</div>
|
||
|
|
<div class="stat-value success-val">1,142</div>
|
||
|
|
<div class="stat-trend">94.8% rate</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
<div class="stat-card">
|
||
|
|
<div class="stat-icon warning">⚠</div>
|
||
|
|
<div class="stat-info">
|
||
|
|
<div class="stat-label">Warnings</div>
|
||
|
|
<div class="stat-value warning-val">38</div>
|
||
|
|
<div class="stat-trend down">+5 vs yesterday</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
<div class="stat-card">
|
||
|
|
<div class="stat-icon error">✗</div>
|
||
|
|
<div class="stat-info">
|
||
|
|
<div class="stat-label">Errors</div>
|
||
|
|
<div class="stat-value error-val">7</div>
|
||
|
|
<div class="stat-trend">0.58% rate</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
<div class="stat-card">
|
||
|
|
<div class="stat-icon duration">⏱</div>
|
||
|
|
<div class="stat-info">
|
||
|
|
<div class="stat-label">Avg Duration</div>
|
||
|
|
<div class="stat-value">247<span style="font-size:13px; font-weight:400; color: var(--text-muted)">ms</span></div>
|
||
|
|
<div class="stat-trend">-8% vs yesterday</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<!-- Execution table -->
|
||
|
|
<div class="table-section animate-in delay-3">
|
||
|
|
<div class="table-header">
|
||
|
|
<span class="table-title">Recent Executions</span>
|
||
|
|
<span class="table-meta">Showing 1–20 of 1,204</span>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<table>
|
||
|
|
<thead>
|
||
|
|
<tr>
|
||
|
|
<th>Status</th>
|
||
|
|
<th>Route</th>
|
||
|
|
<th>Application</th>
|
||
|
|
<th class="sorted">Started <span class="sort-arrow">▼</span></th>
|
||
|
|
<th>Duration</th>
|
||
|
|
<th>Correlation ID</th>
|
||
|
|
<th>Processors</th>
|
||
|
|
</tr>
|
||
|
|
</thead>
|
||
|
|
<tbody>
|
||
|
|
<tr>
|
||
|
|
<td><span class="status-badge status-success"><span class="status-dot"></span>Success</span></td>
|
||
|
|
<td class="td-route">order-processing</td>
|
||
|
|
<td><div class="td-group"><span class="td-group-dot"></span> order-service</div></td>
|
||
|
|
<td class="td-mono">14:23:47.182</td>
|
||
|
|
<td>
|
||
|
|
<div class="duration-bar-wrap">
|
||
|
|
<span class="td-mono">124ms</span>
|
||
|
|
<div class="duration-bar"><div class="duration-bar-fill fast" style="width: 25%"></div></div>
|
||
|
|
</div>
|
||
|
|
</td>
|
||
|
|
<td class="td-id">a8f3e2d1-4b5c</td>
|
||
|
|
<td class="td-mono">12</td>
|
||
|
|
</tr>
|
||
|
|
<tr>
|
||
|
|
<td><span class="status-badge status-running"><span class="status-dot"></span>Running</span></td>
|
||
|
|
<td class="td-route">payment-flow</td>
|
||
|
|
<td><div class="td-group"><span class="td-group-dot"></span> order-service</div></td>
|
||
|
|
<td class="td-mono">14:23:45.903</td>
|
||
|
|
<td>
|
||
|
|
<div class="duration-bar-wrap">
|
||
|
|
<span class="td-mono">1.2s</span>
|
||
|
|
<div class="duration-bar"><div class="duration-bar-fill" style="width: 60%; background: var(--running);"></div></div>
|
||
|
|
</div>
|
||
|
|
</td>
|
||
|
|
<td class="td-id">b7c2a1f0-9d8e</td>
|
||
|
|
<td class="td-mono">8/15</td>
|
||
|
|
</tr>
|
||
|
|
<tr>
|
||
|
|
<td><span class="status-badge status-success"><span class="status-dot"></span>Success</span></td>
|
||
|
|
<td class="td-route">order-validation</td>
|
||
|
|
<td><div class="td-group"><span class="td-group-dot"></span> order-service</div></td>
|
||
|
|
<td class="td-mono">14:23:44.571</td>
|
||
|
|
<td>
|
||
|
|
<div class="duration-bar-wrap">
|
||
|
|
<span class="td-mono">89ms</span>
|
||
|
|
<div class="duration-bar"><div class="duration-bar-fill fast" style="width: 18%"></div></div>
|
||
|
|
</div>
|
||
|
|
</td>
|
||
|
|
<td class="td-id">c6d1b0a9-7f3e</td>
|
||
|
|
<td class="td-mono">7</td>
|
||
|
|
</tr>
|
||
|
|
<tr>
|
||
|
|
<td><span class="status-badge status-warning"><span class="status-dot"></span>Warning</span></td>
|
||
|
|
<td class="td-route">inventory-check</td>
|
||
|
|
<td><div class="td-group"><span class="td-group-dot"></span> order-service</div></td>
|
||
|
|
<td class="td-mono">14:23:42.008</td>
|
||
|
|
<td>
|
||
|
|
<div class="duration-bar-wrap">
|
||
|
|
<span class="td-mono">892ms</span>
|
||
|
|
<div class="duration-bar"><div class="duration-bar-fill medium" style="width: 55%"></div></div>
|
||
|
|
</div>
|
||
|
|
</td>
|
||
|
|
<td class="td-id">d5e0c9b8-6a2d</td>
|
||
|
|
<td class="td-mono">9</td>
|
||
|
|
</tr>
|
||
|
|
<tr>
|
||
|
|
<td><span class="status-badge status-success"><span class="status-dot"></span>Success</span></td>
|
||
|
|
<td class="td-route">order-processing</td>
|
||
|
|
<td><div class="td-group"><span class="td-group-dot"></span> order-service</div></td>
|
||
|
|
<td class="td-mono">14:23:39.245</td>
|
||
|
|
<td>
|
||
|
|
<div class="duration-bar-wrap">
|
||
|
|
<span class="td-mono">156ms</span>
|
||
|
|
<div class="duration-bar"><div class="duration-bar-fill fast" style="width: 30%"></div></div>
|
||
|
|
</div>
|
||
|
|
</td>
|
||
|
|
<td class="td-id">e4f9d8c7-5b1c</td>
|
||
|
|
<td class="td-mono">12</td>
|
||
|
|
</tr>
|
||
|
|
<tr>
|
||
|
|
<td><span class="status-badge status-error"><span class="status-dot"></span>Error</span></td>
|
||
|
|
<td class="td-route">shipment-notify</td>
|
||
|
|
<td><div class="td-group"><span class="td-group-dot"></span> order-service</div></td>
|
||
|
|
<td class="td-mono">14:23:37.891</td>
|
||
|
|
<td>
|
||
|
|
<div class="duration-bar-wrap">
|
||
|
|
<span class="td-mono">2.4s</span>
|
||
|
|
<div class="duration-bar"><div class="duration-bar-fill slow" style="width: 90%"></div></div>
|
||
|
|
</div>
|
||
|
|
</td>
|
||
|
|
<td class="td-id">f3a8b7c6-4d0e</td>
|
||
|
|
<td class="td-mono">5/11</td>
|
||
|
|
</tr>
|
||
|
|
<tr>
|
||
|
|
<td><span class="status-badge status-success"><span class="status-dot"></span>Success</span></td>
|
||
|
|
<td class="td-route">payment-flow</td>
|
||
|
|
<td><div class="td-group"><span class="td-group-dot"></span> order-service</div></td>
|
||
|
|
<td class="td-mono">14:23:35.124</td>
|
||
|
|
<td>
|
||
|
|
<div class="duration-bar-wrap">
|
||
|
|
<span class="td-mono">341ms</span>
|
||
|
|
<div class="duration-bar"><div class="duration-bar-fill fast" style="width: 40%"></div></div>
|
||
|
|
</div>
|
||
|
|
</td>
|
||
|
|
<td class="td-id">a2b7c6d5-3e9f</td>
|
||
|
|
<td class="td-mono">15</td>
|
||
|
|
</tr>
|
||
|
|
<tr>
|
||
|
|
<td><span class="status-badge status-success"><span class="status-dot"></span>Success</span></td>
|
||
|
|
<td class="td-route">order-processing</td>
|
||
|
|
<td><div class="td-group"><span class="td-group-dot"></span> order-service</div></td>
|
||
|
|
<td class="td-mono">14:23:33.567</td>
|
||
|
|
<td>
|
||
|
|
<div class="duration-bar-wrap">
|
||
|
|
<span class="td-mono">98ms</span>
|
||
|
|
<div class="duration-bar"><div class="duration-bar-fill fast" style="width: 20%"></div></div>
|
||
|
|
</div>
|
||
|
|
</td>
|
||
|
|
<td class="td-id">b1c6d5e4-2f8a</td>
|
||
|
|
<td class="td-mono">12</td>
|
||
|
|
</tr>
|
||
|
|
<tr>
|
||
|
|
<td><span class="status-badge status-running"><span class="status-dot"></span>Running</span></td>
|
||
|
|
<td class="td-route">order-processing</td>
|
||
|
|
<td><div class="td-group"><span class="td-group-dot"></span> order-service</div></td>
|
||
|
|
<td class="td-mono">14:23:31.230</td>
|
||
|
|
<td>
|
||
|
|
<div class="duration-bar-wrap">
|
||
|
|
<span class="td-mono">2.8s</span>
|
||
|
|
<div class="duration-bar"><div class="duration-bar-fill" style="width: 75%; background: var(--running);"></div></div>
|
||
|
|
</div>
|
||
|
|
</td>
|
||
|
|
<td class="td-id">c0d5e4f3-1a7b</td>
|
||
|
|
<td class="td-mono">10/12</td>
|
||
|
|
</tr>
|
||
|
|
<tr>
|
||
|
|
<td><span class="status-badge status-success"><span class="status-dot"></span>Success</span></td>
|
||
|
|
<td class="td-route">order-validation</td>
|
||
|
|
<td><div class="td-group"><span class="td-group-dot"></span> order-service</div></td>
|
||
|
|
<td class="td-mono">14:23:28.892</td>
|
||
|
|
<td>
|
||
|
|
<div class="duration-bar-wrap">
|
||
|
|
<span class="td-mono">67ms</span>
|
||
|
|
<div class="duration-bar"><div class="duration-bar-fill fast" style="width: 14%"></div></div>
|
||
|
|
</div>
|
||
|
|
</td>
|
||
|
|
<td class="td-id">d9e4f3a2-0b6c</td>
|
||
|
|
<td class="td-mono">7</td>
|
||
|
|
</tr>
|
||
|
|
</tbody>
|
||
|
|
</table>
|
||
|
|
|
||
|
|
<div class="table-footer">
|
||
|
|
<span class="mono" style="font-size: 12px;">20 rows per page</span>
|
||
|
|
<div class="pagination">
|
||
|
|
<button class="page-btn">‹</button>
|
||
|
|
<button class="page-btn active">1</button>
|
||
|
|
<button class="page-btn">2</button>
|
||
|
|
<button class="page-btn">3</button>
|
||
|
|
<button class="page-btn">...</button>
|
||
|
|
<button class="page-btn">61</button>
|
||
|
|
<button class="page-btn">›</button>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<!-- Metrics panel -->
|
||
|
|
<div class="metrics-row animate-in delay-4">
|
||
|
|
<!-- Throughput chart -->
|
||
|
|
<div class="metric-card">
|
||
|
|
<div class="metric-card-header">
|
||
|
|
<span class="metric-card-title">Throughput</span>
|
||
|
|
<span class="metric-card-value">52<span style="font-size:11px; font-weight:400; color: var(--text-muted)">/min</span></span>
|
||
|
|
</div>
|
||
|
|
<div class="metric-chart">
|
||
|
|
<svg width="100%" height="100%" viewBox="0 0 300 70" preserveAspectRatio="none">
|
||
|
|
<!-- Grid lines -->
|
||
|
|
<line x1="0" y1="17.5" x2="300" y2="17.5" class="chart-grid-line"/>
|
||
|
|
<line x1="0" y1="35" x2="300" y2="35" class="chart-grid-line"/>
|
||
|
|
<line x1="0" y1="52.5" x2="300" y2="52.5" class="chart-grid-line"/>
|
||
|
|
<!-- Area fill -->
|
||
|
|
<path d="M0,55 L20,48 40,50 60,42 80,38 100,35 120,30 140,32 160,25 180,22 200,28 220,20 240,15 260,18 280,12 300,10 L300,70 L0,70 Z"
|
||
|
|
fill="#C6820E" class="chart-area"/>
|
||
|
|
<!-- Line -->
|
||
|
|
<path d="M0,55 L20,48 40,50 60,42 80,38 100,35 120,30 140,32 160,25 180,22 200,28 220,20 240,15 260,18 280,12 300,10"
|
||
|
|
stroke="#C6820E" class="chart-line"/>
|
||
|
|
<!-- Labels -->
|
||
|
|
<text x="0" y="68" class="chart-label">12:00</text>
|
||
|
|
<text x="145" y="68" class="chart-label">13:00</text>
|
||
|
|
<text x="290" y="68" class="chart-label">14:00</text>
|
||
|
|
</svg>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<!-- Error rate chart -->
|
||
|
|
<div class="metric-card">
|
||
|
|
<div class="metric-card-header">
|
||
|
|
<span class="metric-card-title">Error Rate</span>
|
||
|
|
<span class="metric-card-value" style="color: var(--error);">0.58<span style="font-size:11px; font-weight:400; color: var(--text-muted)">%</span></span>
|
||
|
|
</div>
|
||
|
|
<div class="metric-chart">
|
||
|
|
<svg width="100%" height="100%" viewBox="0 0 300 70" preserveAspectRatio="none">
|
||
|
|
<line x1="0" y1="17.5" x2="300" y2="17.5" class="chart-grid-line"/>
|
||
|
|
<line x1="0" y1="35" x2="300" y2="35" class="chart-grid-line"/>
|
||
|
|
<line x1="0" y1="52.5" x2="300" y2="52.5" class="chart-grid-line"/>
|
||
|
|
<!-- Bar chart for errors -->
|
||
|
|
<rect x="5" y="60" width="14" height="10" rx="2" fill="var(--error-border)"/>
|
||
|
|
<rect x="25" y="55" width="14" height="15" rx="2" fill="var(--error-border)"/>
|
||
|
|
<rect x="45" y="62" width="14" height="8" rx="2" fill="var(--error-border)"/>
|
||
|
|
<rect x="65" y="58" width="14" height="12" rx="2" fill="var(--error-border)"/>
|
||
|
|
<rect x="85" y="65" width="14" height="5" rx="2" fill="var(--error-border)"/>
|
||
|
|
<rect x="105" y="63" width="14" height="7" rx="2" fill="var(--error-border)"/>
|
||
|
|
<rect x="125" y="60" width="14" height="10" rx="2" fill="var(--error-border)"/>
|
||
|
|
<rect x="145" y="45" width="14" height="25" rx="2" fill="var(--error)"/>
|
||
|
|
<rect x="165" y="55" width="14" height="15" rx="2" fill="var(--error-border)"/>
|
||
|
|
<rect x="185" y="58" width="14" height="12" rx="2" fill="var(--error-border)"/>
|
||
|
|
<rect x="205" y="63" width="14" height="7" rx="2" fill="var(--error-border)"/>
|
||
|
|
<rect x="225" y="60" width="14" height="10" rx="2" fill="var(--error-border)"/>
|
||
|
|
<rect x="245" y="55" width="14" height="15" rx="2" fill="var(--error-border)"/>
|
||
|
|
<rect x="265" y="50" width="14" height="20" rx="2" fill="var(--error)"/>
|
||
|
|
<rect x="285" y="58" width="14" height="12" rx="2" fill="var(--error-border)"/>
|
||
|
|
<text x="0" y="68" class="chart-label">12:00</text>
|
||
|
|
<text x="145" y="68" class="chart-label">13:00</text>
|
||
|
|
<text x="290" y="68" class="chart-label">14:00</text>
|
||
|
|
</svg>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<!-- Latency chart -->
|
||
|
|
<div class="metric-card">
|
||
|
|
<div class="metric-card-header">
|
||
|
|
<span class="metric-card-title">P95 Latency</span>
|
||
|
|
<span class="metric-card-value">412<span style="font-size:11px; font-weight:400; color: var(--text-muted)">ms</span></span>
|
||
|
|
</div>
|
||
|
|
<div class="metric-chart">
|
||
|
|
<svg width="100%" height="100%" viewBox="0 0 300 70" preserveAspectRatio="none">
|
||
|
|
<line x1="0" y1="17.5" x2="300" y2="17.5" class="chart-grid-line"/>
|
||
|
|
<line x1="0" y1="35" x2="300" y2="35" class="chart-grid-line"/>
|
||
|
|
<line x1="0" y1="52.5" x2="300" y2="52.5" class="chart-grid-line"/>
|
||
|
|
<!-- P95 area -->
|
||
|
|
<path d="M0,35 L20,32 40,38 60,30 80,25 100,28 120,35 140,40 160,32 180,28 200,22 220,30 240,25 260,20 280,28 300,25 L300,70 L0,70 Z"
|
||
|
|
fill="#1A7F8E" class="chart-area"/>
|
||
|
|
<!-- P50 line -->
|
||
|
|
<path d="M0,50 L20,48 40,52 60,45 80,42 100,46 120,50 140,52 160,47 180,44 200,40 220,45 240,42 260,38 280,43 300,40"
|
||
|
|
stroke="#1A7F8E" stroke-opacity="0.4" class="chart-line" stroke-dasharray="4 3"/>
|
||
|
|
<!-- P95 line -->
|
||
|
|
<path d="M0,35 L20,32 40,38 60,30 80,25 100,28 120,35 140,40 160,32 180,28 200,22 220,30 240,25 260,20 280,28 300,25"
|
||
|
|
stroke="#1A7F8E" class="chart-line"/>
|
||
|
|
<text x="0" y="68" class="chart-label">12:00</text>
|
||
|
|
<text x="145" y="68" class="chart-label">13:00</text>
|
||
|
|
<text x="290" y="68" class="chart-label">14:00</text>
|
||
|
|
</svg>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
</div><!-- /content -->
|
||
|
|
</div><!-- /main -->
|
||
|
|
</div><!-- /app -->
|
||
|
|
</body>
|
||
|
|
</html>
|