Files
design-system/ui-mocks/mock-v2-dark.html

1708 lines
76 KiB
HTML
Raw Normal View History

<!--
============================================================================
CAMELEER3 v2 — Operations Dashboard (Dark Theme)
============================================================================
DESIGN NOTES — SYNTHESIS RATIONALE
===================================
What was taken from each expert:
FROM DESIGN EXPERT:
- Amber-gold accent (#D4940F) as the primary brand color, maintaining the
"Desert Dusk" identity even in dark mode. The camel silhouette SVG logo.
- Typography system: DM Sans + JetBrains Mono, four-level hierarchy.
- Card-based layouts with subtle borders and layered surfaces.
- Duration bar sparklines for quick visual comparison.
- Warm sidebar tone (not pure black, but warm obsidian).
FROM USABILITY EXPERT:
- Full information hierarchy: health strip -> filter bar -> results -> detail.
- Master-detail pattern with slide-in panel (45% width on row select).
- Status pills with live counts, time preset chips, removable filter tags.
- Relative timestamps ("2m ago") with absolute fallback.
- Keyboard shortcut hints bar.
- Failed/running row border accents for scan-ability.
- Processor Gantt timeline in detail panel.
- Tab-based progressive disclosure in detail (Overview/Processors/Exchange/Error).
FROM OPERATOR EXPERT:
- Business IDs (Order ID, Customer, Source) as first-class table columns.
- Inline error previews directly below failed rows — no click needed.
- SLA threshold indicators on metric charts and duration cells.
- Agent health panel (integrated into sidebar).
- Trend arrows on all metric cards (directional context).
- Top error pattern grouping with occurrence counts.
- Shift-aware labeling ("since 06:00", overnight vs. today split).
KEY DESIGN DECISIONS:
1. Dark palette uses refined obsidian (#0B0F18) not generic navy. Surfaces
layer from #0B0F18 -> #111827 -> #1A2332 -> #212D3F for depth.
2. Status colors are tuned for dark contrast: emerald (#10B981), amber
(#F0B429), rose (#F43F5E), sky blue (#3B82F6) with subtle glow effects.
3. The warm amber accent (#D4940F) provides brand continuity with the light
theme — both mocks are clearly the same product.
4. Glow effects on status indicators (box-shadow with colored alpha) give
the dark theme a polished, premium feel without being garish.
5. Chart palettes use semi-transparent fills that work on dark backgrounds,
with SLA threshold lines clearly visible.
WHAT MAKES THIS BETTER THAN EACH INDIVIDUAL:
- Design expert had the warm brand but was light-only. This proves the amber
brand works equally well on dark backgrounds.
- Usability expert had a dark theme but with generic navy colors and no
business context. This uses refined obsidian + business data.
- Operator expert had excellent data but a flat single-page layout with no
sidebar or detail panel. This adds proper navigation + drill-down.
- The synthesis creates a cohesive dark monitoring experience: professional
enough for a NOC wall display, detailed enough for incident response.
============================================================================
-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=1920">
<title>Cameleer3 — Operations Dashboard (Dark)</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 (obsidian layers) */
--bg-deep: #0B0F18;
--bg-base: #0E1220;
--bg-surface: #141B2A;
--bg-raised: #1A2332;
--bg-hover: #212D3F;
/* Sidebar (warm obsidian) */
--sidebar-bg: #0E1118;
--sidebar-hover: #171D28;
--sidebar-active: #1D2636;
--sidebar-text: #94A3B8;
--sidebar-muted: #475569;
/* Text */
--text-primary: #E8ECF4;
--text-secondary: #94A3B8;
--text-muted: #5A6B83;
--text-faint: #3A4A5E;
/* Borders */
--border: #1E2D3D;
--border-subtle: #172030;
/* Brand accent (amber-gold) */
--amber: #D4940F;
--amber-light: #F0C060;
--amber-bg: rgba(212, 148, 15, 0.12);
--amber-deep: #A67200;
--amber-glow: rgba(212, 148, 15, 0.15);
/* Status colors (dark-optimized, brighter for contrast) */
--success: #10B981;
--success-bg: rgba(16, 185, 129, 0.10);
--success-border: rgba(16, 185, 129, 0.25);
--success-glow: rgba(16, 185, 129, 0.15);
--warning: #F0B429;
--warning-bg: rgba(240, 180, 41, 0.10);
--warning-border: rgba(240, 180, 41, 0.25);
--error: #F43F5E;
--error-bg: rgba(244, 63, 94, 0.08);
--error-border: rgba(244, 63, 94, 0.20);
--error-glow: rgba(244, 63, 94, 0.12);
--running: #3B82F6;
--running-bg: rgba(59, 130, 246, 0.10);
--running-border: rgba(59, 130, 246, 0.25);
--cyan: #22D3EE;
--cyan-bg: rgba(34, 211, 238, 0.10);
/* Typography */
--font-body: 'DM Sans', system-ui, -apple-system, sans-serif;
--font-mono: 'JetBrains Mono', 'Fira Code', monospace;
/* Spacing & Radii */
--radius-sm: 6px;
--radius-md: 8px;
--radius-lg: 12px;
/* Shadows (dark-optimized: deeper, colored) */
--shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.3);
--shadow-md: 0 2px 8px rgba(0, 0, 0, 0.35);
--shadow-lg: 0 4px 16px rgba(0, 0, 0, 0.4);
--shadow-card: 0 1px 3px rgba(0, 0, 0, 0.2), 0 0 0 1px var(--border-subtle);
}
html { font-size: 14px; }
body {
font-family: var(--font-body);
background: var(--bg-deep);
color: var(--text-primary);
line-height: 1.5;
min-height: 100vh;
-webkit-font-smoothing: antialiased;
}
/* Subtle gradient background */
body::before {
content: '';
position: fixed;
inset: 0;
background:
radial-gradient(ellipse 900px 450px at 15% 10%, rgba(212, 148, 15, 0.03), transparent),
radial-gradient(ellipse 700px 700px at 85% 85%, rgba(34, 211, 238, 0.015), transparent);
pointer-events: none;
z-index: 0;
}
::-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-muted); }
/* ==========================================================================
ANIMATIONS
========================================================================== */
@keyframes fadeIn {
from { opacity: 0; transform: translateY(6px); }
to { opacity: 1; transform: translateY(0); }
}
@keyframes pulse {
0%, 100% { box-shadow: 0 0 0 0 rgba(16, 185, 129, 0.4); }
50% { box-shadow: 0 0 0 5px rgba(16, 185, 129, 0); }
}
@keyframes errorPulse {
0%, 100% { box-shadow: 0 0 0 0 rgba(244, 63, 94, 0.2); }
50% { box-shadow: 0 0 0 4px rgba(244, 63, 94, 0); }
}
@keyframes slideIn {
from { opacity: 0; transform: translateX(20px); }
to { opacity: 1; transform: translateX(0); }
}
@keyframes glowPulse {
0%, 100% { opacity: 0.6; }
50% { opacity: 1; }
}
.animate-in { animation: fadeIn 0.3s 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; }
/* ==========================================================================
LAYOUT: 3-column
========================================================================== */
.app {
display: flex;
height: 100vh;
overflow: hidden;
position: relative;
z-index: 1;
}
/* ==========================================================================
SIDEBAR (warm obsidian)
========================================================================== */
.sidebar {
width: 220px;
flex-shrink: 0;
background: var(--sidebar-bg);
border-right: 1px solid var(--border-subtle);
display: flex;
flex-direction: column;
overflow: hidden;
}
.sidebar-logo {
padding: 16px 18px;
display: flex;
align-items: center;
gap: 10px;
border-bottom: 1px solid var(--border-subtle);
}
.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 { padding: 10px 12px; }
.sidebar-search input {
width: 100%;
background: var(--bg-raised);
border: 1px solid var(--border);
border-radius: var(--radius-sm);
padding: 6px 10px 6px 28px;
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: var(--amber); }
.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;
}
.sidebar-section {
padding: 14px 12px 5px;
font-size: 10px;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 1.2px;
color: var(--sidebar-muted);
}
.sidebar-items {
flex: 1;
overflow-y: auto;
padding: 0 6px;
}
.sidebar-item {
display: flex;
align-items: center;
gap: 10px;
padding: 7px 12px;
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: var(--text-primary); }
.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: var(--success); box-shadow: 0 0 6px var(--success-glow); }
.health-stale { background: var(--warning); box-shadow: 0 0 6px rgba(240, 180, 41, 0.3); }
.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: var(--bg-raised);
padding: 1px 6px;
border-radius: 10px;
}
.sidebar-item.active .item-count { background: var(--amber-bg); color: var(--amber-light); }
.sidebar-divider {
height: 1px;
background: var(--border-subtle);
margin: 6px 12px;
}
/* Agent health in sidebar */
.sidebar-agents-header {
padding: 14px 12px 6px;
font-size: 10px;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 1.2px;
color: var(--sidebar-muted);
display: flex;
align-items: center;
justify-content: space-between;
}
.sidebar-agent-badge {
font-family: var(--font-mono);
font-size: 10px;
padding: 1px 6px;
border-radius: 10px;
background: var(--success-bg);
color: var(--success);
border: 1px solid var(--success-border);
}
.agent-item {
display: flex;
align-items: center;
gap: 8px;
padding: 6px 12px;
margin: 0 6px 2px;
border-radius: var(--radius-sm);
font-size: 11px;
color: var(--sidebar-text);
transition: background 0.1s;
}
.agent-item:hover { background: var(--sidebar-hover); }
.agent-dot {
width: 6px;
height: 6px;
border-radius: 50%;
flex-shrink: 0;
}
.agent-info { flex: 1; min-width: 0; }
.agent-name { font-family: var(--font-mono); font-size: 11px; font-weight: 500; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; color: var(--text-secondary); }
.agent-detail { font-size: 10px; color: var(--sidebar-muted); }
.agent-stats-col {
text-align: right;
font-family: var(--font-mono);
font-size: 10px;
color: var(--sidebar-muted);
}
.agent-tps { color: var(--sidebar-text); }
.sidebar-bottom {
border-top: 1px solid var(--border-subtle);
padding: 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); }
/* ==========================================================================
MAIN CONTENT AREA
========================================================================== */
.main {
flex: 1;
display: flex;
flex-direction: column;
overflow: hidden;
min-width: 0;
}
/* Top bar */
.topbar {
display: flex;
align-items: center;
gap: 12px;
padding: 0 24px;
height: 48px;
flex-shrink: 0;
background: rgba(14, 18, 32, 0.85);
backdrop-filter: blur(16px);
border-bottom: 1px solid var(--border-subtle);
}
.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-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: 280px;
}
.topbar-search:hover { border-color: var(--text-muted); }
.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-muted);
margin-left: auto;
}
.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-shift {
font-family: var(--font-mono);
font-size: 10px;
padding: 3px 10px;
border-radius: 10px;
background: var(--cyan-bg);
color: var(--cyan);
border: 1px solid rgba(34, 211, 238, 0.2);
}
.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 rgba(212, 148, 15, 0.3);
}
/* Content scroll container */
.content-wrap {
flex: 1;
display: flex;
overflow: hidden;
}
.content {
flex: 1;
overflow-y: auto;
padding: 20px 24px 40px;
min-width: 0;
}
/* ==========================================================================
HEALTH STATUS BAR
========================================================================== */
.health-strip {
display: grid;
grid-template-columns: repeat(5, 1fr);
gap: 10px;
margin-bottom: 16px;
}
.stat-card {
background: var(--bg-surface);
border: 1px solid var(--border-subtle);
border-radius: var(--radius-md);
padding: 12px 16px;
position: relative;
overflow: hidden;
transition: border-color 0.2s;
cursor: pointer;
}
.stat-card:hover { border-color: var(--border); }
.stat-card::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
height: 2px;
}
.stat-card.card-amber::before { background: linear-gradient(90deg, var(--amber), transparent); }
.stat-card.card-green::before { background: linear-gradient(90deg, var(--success), transparent); }
.stat-card.card-error::before { background: linear-gradient(90deg, var(--error), transparent); }
.stat-card.card-teal::before { background: linear-gradient(90deg, var(--cyan), transparent); }
.stat-card.card-warn::before { background: linear-gradient(90deg, var(--warning), transparent); }
.stat-card.has-errors { animation: errorPulse 2.5s ease-in-out infinite; }
.stat-label {
font-size: 10px;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.6px;
color: var(--text-muted);
margin-bottom: 3px;
}
.stat-value-row {
display: flex;
align-items: baseline;
gap: 6px;
}
.stat-value {
font-family: var(--font-mono);
font-size: 20px;
font-weight: 600;
line-height: 1.2;
color: var(--text-primary);
}
.stat-value.val-amber { color: var(--amber); }
.stat-value.val-green { color: var(--success); }
.stat-value.val-error { color: var(--error); }
.stat-value.val-teal { color: var(--cyan); }
.stat-value.val-warn { color: var(--warning); }
.stat-unit { font-size: 12px; color: var(--text-muted); }
.stat-trend {
font-family: var(--font-mono);
font-size: 11px;
display: inline-flex;
align-items: center;
gap: 2px;
margin-left: auto;
}
.trend-up-good { color: var(--success); }
.trend-up-bad { color: var(--error); }
.trend-down-good { color: var(--success); }
.trend-down-bad { color: var(--error); }
.trend-flat { color: var(--text-muted); }
.stat-detail { font-size: 11px; color: var(--text-muted); margin-top: 2px; }
.stat-detail strong { color: var(--text-secondary); }
/* ==========================================================================
FILTER BAR
========================================================================== */
.filter-section {
background: var(--bg-surface);
border: 1px solid var(--border-subtle);
border-radius: var(--radius-lg);
padding: 12px 16px;
margin-bottom: 16px;
}
.filter-row {
display: flex;
gap: 8px;
align-items: center;
flex-wrap: wrap;
}
.filter-group {
display: flex;
align-items: center;
gap: 5px;
}
.filter-label {
font-size: 10px;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.5px;
color: var(--text-muted);
white-space: nowrap;
margin-right: 2px;
}
.filter-sep {
width: 1px;
height: 22px;
background: var(--border);
margin: 0 6px;
}
.filter-pill {
display: inline-flex;
align-items: center;
gap: 4px;
padding: 4px 12px;
border: 1px solid var(--border);
border-radius: 20px;
background: transparent;
color: var(--text-secondary);
font-size: 12px;
font-weight: 500;
cursor: pointer;
transition: all 0.12s;
white-space: nowrap;
}
.filter-pill:hover { border-color: var(--text-muted); background: var(--bg-raised); }
.filter-pill.active {
background: var(--amber-bg);
border-color: rgba(212, 148, 15, 0.35);
color: var(--amber-light);
font-weight: 600;
}
.pill-dot { width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
.pill-count { font-family: var(--font-mono); font-size: 10px; opacity: 0.7; }
.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-muted);
font-size: 13px;
}
.filter-input {
width: 100%;
padding: 6px 12px 6px 30px;
border: 1px solid var(--border);
border-radius: var(--radius-sm);
background: var(--bg-raised);
color: var(--text-primary);
font-family: var(--font-body);
font-size: 12px;
outline: none;
transition: border-color 0.15s;
}
.filter-input::placeholder { color: var(--text-muted); }
.filter-input:focus { border-color: var(--amber); box-shadow: 0 0 0 3px var(--amber-bg); }
.active-filters {
display: flex;
gap: 6px;
flex-wrap: wrap;
align-items: center;
margin-top: 8px;
}
.filter-tag {
display: inline-flex;
align-items: center;
gap: 6px;
padding: 3px 10px;
background: var(--amber-bg);
border: 1px solid rgba(212, 148, 15, 0.25);
border-radius: 20px;
font-size: 11px;
color: var(--amber-light);
font-family: var(--font-mono);
}
.filter-tag-remove { cursor: pointer; opacity: 0.5; font-size: 13px; line-height: 1; background: none; border: none; color: inherit; }
.filter-tag-remove:hover { opacity: 1; }
.clear-all { font-size: 11px; color: var(--text-muted); cursor: pointer; padding: 3px 6px; background: none; border: none; }
.clear-all:hover { color: var(--error); }
/* ==========================================================================
EXECUTION TABLE
========================================================================== */
.table-section {
background: var(--bg-surface);
border: 1px solid var(--border-subtle);
border-radius: var(--radius-lg);
overflow: hidden;
margin-bottom: 20px;
}
.table-header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 10px 16px;
border-bottom: 1px solid var(--border-subtle);
}
.table-title { font-size: 13px; font-weight: 600; color: var(--text-primary); }
.table-right { display: flex; align-items: center; gap: 12px; }
.table-meta { font-family: var(--font-mono); font-size: 11px; color: var(--text-muted); }
.live-btn {
display: flex;
align-items: center;
gap: 6px;
padding: 5px 12px;
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: 11px;
font-weight: 500;
cursor: pointer;
transition: all 0.15s;
}
.live-btn:hover { background: rgba(16, 185, 129, 0.15); }
.live-dot {
width: 6px;
height: 6px;
border-radius: 50%;
background: var(--success);
animation: pulse 2s ease-in-out infinite;
}
.table-scroll { overflow-x: auto; }
table { width: 100%; border-collapse: collapse; }
thead {
background: var(--bg-raised);
border-bottom: 1px solid var(--border);
}
th {
padding: 9px 14px;
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); }
.sort-arrow { font-size: 8px; margin-left: 3px; opacity: 0.4; }
th.sorted .sort-arrow { opacity: 1; }
tbody tr {
border-bottom: 1px solid var(--border-subtle);
border-left: 3px solid transparent;
transition: background 0.08s;
cursor: pointer;
}
tbody tr:last-child { border-bottom: none; }
tbody tr:hover { background: var(--bg-hover); }
tbody tr.selected { background: var(--amber-bg); }
tbody tr.row-error { border-left-color: var(--error); }
tbody tr.row-warning { border-left-color: var(--warning); }
tbody tr.row-running { border-left-color: var(--running); }
td {
padding: 9px 14px;
font-size: 13px;
vertical-align: top;
white-space: nowrap;
}
/* Status badge with glow */
.status-badge {
display: inline-flex;
align-items: center;
gap: 5px;
padding: 2px 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%; background: currentColor; }
/* Glow on status indicators */
.status-success .status-dot { box-shadow: 0 0 4px var(--success-glow); }
.status-error .status-dot { box-shadow: 0 0 4px var(--error-glow); }
.route-name { font-weight: 500; color: var(--text-primary); }
.route-name:hover { color: var(--amber); }
.route-group { font-size: 11px; color: var(--text-muted); }
.biz-id { font-family: var(--font-mono); font-weight: 500; color: var(--cyan); font-size: 12px; }
.biz-id-secondary { font-family: var(--font-mono); font-size: 11px; color: var(--text-muted); }
.time-relative { color: var(--text-secondary); font-size: 13px; }
.time-absolute { font-family: var(--font-mono); font-size: 10px; color: var(--text-muted); display: block; }
.duration { font-family: var(--font-mono); font-size: 12px; }
.dur-fast { color: var(--success); }
.dur-normal { color: var(--text-primary); }
.dur-slow { color: var(--warning); }
.dur-breach { color: var(--error); font-weight: 600; }
.sla-tag {
display: inline-flex;
align-items: center;
gap: 2px;
color: var(--error);
font-size: 10px;
font-family: var(--font-mono);
font-weight: 600;
margin-left: 4px;
animation: glowPulse 2s ease-in-out infinite;
}
.agent-badge {
display: inline-flex;
align-items: center;
gap: 4px;
font-family: var(--font-mono);
font-size: 11px;
color: var(--text-muted);
}
.agent-badge-dot { width: 5px; height: 5px; border-radius: 50%; }
/* Error preview row */
.error-preview-row td {
padding: 0 14px 8px 20px !important;
border-bottom: 1px solid var(--border-subtle);
}
.error-preview {
display: flex;
align-items: flex-start;
gap: 8px;
padding: 8px 12px;
background: rgba(244, 63, 94, 0.05);
border: 1px solid var(--error-border);
border-left: 3px solid var(--error);
border-radius: var(--radius-sm);
font-family: var(--font-mono);
font-size: 11px;
color: var(--error);
line-height: 1.6;
}
.error-preview-icon { flex-shrink: 0; margin-top: 1px; }
.error-preview-text { white-space: normal; word-break: break-word; }
.error-expand-hint { color: var(--text-muted); font-size: 10px; margin-top: 4px; font-family: var(--font-body); }
/* Pagination */
.table-footer {
display: flex;
align-items: center;
justify-content: space-between;
padding: 8px 16px;
border-top: 1px solid var(--border-subtle);
font-size: 12px;
color: var(--text-muted);
background: var(--bg-raised);
}
.pagination { display: flex; align-items: center; gap: 4px; }
.page-btn {
padding: 4px 10px;
border: 1px solid var(--border);
border-radius: var(--radius-sm);
background: transparent;
color: var(--text-secondary);
font-size: 12px;
font-family: var(--font-mono);
cursor: pointer;
transition: all 0.12s;
}
.page-btn:hover { background: var(--bg-hover); border-color: var(--text-muted); }
.page-btn.active { background: var(--amber-bg); border-color: rgba(212, 148, 15, 0.35); color: var(--amber-light); font-weight: 600; }
/* ==========================================================================
METRICS ROW
========================================================================== */
.metrics-row {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
gap: 14px;
margin-bottom: 20px;
}
.metric-card {
background: var(--bg-surface);
border: 1px solid var(--border-subtle);
border-radius: var(--radius-lg);
overflow: hidden;
}
.metric-card-header {
padding: 12px 16px 0;
display: flex;
align-items: center;
justify-content: space-between;
}
.metric-card-title { font-size: 11px; font-weight: 600; color: var(--text-muted); 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: 10px 16px 12px; height: 90px; position: relative; }
.chart-line { fill: none; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.chart-area { opacity: 0.15; }
.chart-grid-line { stroke: var(--border-subtle); stroke-width: 0.5; }
.chart-label { font-family: var(--font-mono); font-size: 9px; fill: var(--text-muted); }
.sla-line { stroke: var(--error); stroke-width: 1; stroke-dasharray: 4 3; opacity: 0.6; }
.sla-label-text { fill: var(--error); font-size: 8px; font-family: var(--font-mono); opacity: 0.7; }
/* ==========================================================================
DETAIL PANEL
========================================================================== */
.detail-panel {
width: 0;
overflow: hidden;
transition: width 0.25s ease, opacity 0.2s ease;
opacity: 0;
border-left: 1px solid transparent;
display: flex;
flex-direction: column;
background: var(--bg-surface);
flex-shrink: 0;
}
.detail-panel.open {
width: 400px;
opacity: 1;
border-left-color: var(--border);
animation: slideIn 0.25s ease-out both;
}
.detail-header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 12px 16px;
border-bottom: 1px solid var(--border-subtle);
flex-shrink: 0;
}
.detail-breadcrumb { font-size: 11px; color: var(--text-muted); display: flex; align-items: center; gap: 5px; }
.detail-breadcrumb .bc-sep { color: var(--text-faint); font-size: 9px; }
.detail-breadcrumb .bc-current { color: var(--amber); font-weight: 500; }
.detail-close {
width: 26px;
height: 26px;
display: flex;
align-items: center;
justify-content: center;
background: none;
border: 1px solid var(--border);
border-radius: var(--radius-sm);
color: var(--text-muted);
cursor: pointer;
font-size: 13px;
transition: all 0.15s;
}
.detail-close:hover { color: var(--text-primary); border-color: var(--text-muted); }
.detail-tabs { display: flex; border-bottom: 1px solid var(--border-subtle); flex-shrink: 0; }
.detail-tab {
padding: 9px 16px;
font-size: 12px;
font-weight: 500;
color: var(--text-muted);
cursor: pointer;
border-bottom: 2px solid transparent;
transition: all 0.15s;
background: none;
border-top: none; border-left: none; border-right: none;
font-family: var(--font-body);
}
.detail-tab:hover { color: var(--text-secondary); }
.detail-tab.active { color: var(--amber); border-bottom-color: var(--amber); }
.detail-body {
flex: 1;
overflow-y: auto;
padding: 16px;
background: var(--bg-deep);
}
.detail-section { margin-bottom: 18px; }
.detail-section-title {
font-size: 10px;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.8px;
color: var(--text-muted);
margin-bottom: 8px;
}
.detail-grid {
display: grid;
grid-template-columns: 100px 1fr;
gap: 6px 10px;
font-size: 12px;
}
.detail-key { color: var(--text-muted); font-size: 11px; }
.detail-val { color: var(--text-primary); font-family: var(--font-mono); font-size: 11px; word-break: break-all; }
.detail-val.error-text { color: var(--error); }
.detail-val.link { color: var(--amber); cursor: pointer; }
/* Processor timeline */
.processor-timeline { display: flex; flex-direction: column; gap: 5px; }
.proc-row { display: flex; align-items: center; gap: 8px; font-size: 11px; }
.proc-name {
width: 100px;
text-align: right;
color: var(--text-secondary);
font-family: var(--font-mono);
font-size: 10px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
flex-shrink: 0;
}
.proc-bar-bg {
flex: 1;
height: 16px;
background: var(--bg-raised);
border-radius: 3px;
position: relative;
overflow: hidden;
}
.proc-bar-fill {
position: absolute;
top: 0;
height: 100%;
border-radius: 3px;
display: flex;
align-items: center;
justify-content: flex-end;
padding-right: 5px;
font-family: var(--font-mono);
font-size: 8px;
color: rgba(255,255,255,0.8);
min-width: 20px;
}
.proc-ok { background: rgba(16, 185, 129, 0.45); }
.proc-slow { background: rgba(240, 180, 41, 0.45); }
.proc-fail { background: rgba(244, 63, 94, 0.45); }
.proc-dur { width: 42px; font-family: var(--font-mono); font-size: 10px; color: var(--text-muted); flex-shrink: 0; }
/* Error block */
.error-block {
background: rgba(244, 63, 94, 0.05);
border: 1px solid var(--error-border);
border-left: 3px solid var(--error);
border-radius: var(--radius-sm);
padding: 12px 14px;
}
.error-class { font-family: var(--font-mono); font-size: 11px; color: var(--error); font-weight: 600; margin-bottom: 4px; }
.error-message-detail { font-family: var(--font-mono); font-size: 10px; color: var(--text-secondary); line-height: 1.6; }
.error-expand { margin-top: 6px; font-size: 10px; color: var(--text-muted); cursor: pointer; background: none; border: none; font-family: var(--font-mono); }
.error-expand:hover { color: var(--amber); }
/* Detail actions */
.detail-actions {
display: flex;
gap: 6px;
padding: 10px 16px;
border-top: 1px solid var(--border-subtle);
flex-shrink: 0;
}
.action-btn { padding: 6px 14px; border-radius: var(--radius-sm); font-size: 11px; font-weight: 500; cursor: pointer; transition: all 0.15s; font-family: var(--font-body); }
.action-btn.primary { background: var(--amber); color: var(--bg-deep); border: none; }
.action-btn.primary:hover { background: var(--amber-light); }
.action-btn.secondary { background: none; border: 1px solid var(--border); color: var(--text-secondary); }
.action-btn.secondary:hover { border-color: var(--text-muted); color: var(--text-primary); }
/* ==========================================================================
KEYBOARD SHORTCUTS BAR
========================================================================== */
.shortcuts-bar {
position: fixed;
bottom: 12px;
right: 12px;
display: flex;
gap: 10px;
z-index: 50;
animation: fadeIn 0.5s ease-out 0.5s both;
}
.shortcut-hint {
display: flex;
align-items: center;
gap: 5px;
font-size: 10px;
color: var(--text-muted);
background: var(--bg-surface);
border: 1px solid var(--border-subtle);
border-radius: var(--radius-sm);
padding: 4px 8px;
}
.shortcut-hint kbd {
font-family: var(--font-mono);
font-size: 9px;
background: var(--bg-raised);
border: 1px solid var(--border);
border-radius: 3px;
padding: 0 4px;
color: var(--text-secondary);
}
.mono { font-family: var(--font-mono); }
</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:#D4940F" 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">&#9671;</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">4</span>
</div>
<div class="sidebar-divider"></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 agents</div></div>
<span class="item-count">1,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">2 agents</div></div>
<span class="item-count">923</span>
</div>
<div class="sidebar-item">
<span class="health health-live"></span>
<div class="item-info"><div class="item-name">shipment-tracker</div><div class="item-meta">2 agents</div></div>
<span class="item-count">471</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 agent</div></div>
<span class="item-count">128</span>
</div>
<div class="sidebar-divider"></div>
<div class="sidebar-section">Routes</div>
<div class="sidebar-item" style="padding-left: 22px;">
<span style="color: var(--sidebar-muted); font-size: 10px;">&#9656;</span>
<div class="item-info"><div class="item-name">order-intake</div></div>
<span class="item-count">892</span>
</div>
<div class="sidebar-item" style="padding-left: 22px;">
<span style="color: var(--sidebar-muted); font-size: 10px;">&#9656;</span>
<div class="item-info"><div class="item-name">order-enrichment</div></div>
<span class="item-count">541</span>
</div>
<div class="sidebar-item" style="padding-left: 22px;">
<span style="color: var(--sidebar-muted); font-size: 10px;">&#9656;</span>
<div class="item-info"><div class="item-name">payment-process</div></div>
<span class="item-count">414</span>
</div>
</div>
<!-- Agent health -->
<div class="sidebar-agents-header">
<span>Agents</span>
<span class="sidebar-agent-badge">4/4 live</span>
</div>
<div style="padding: 0 0 6px; overflow-y: auto; max-height: 180px;">
<div class="agent-item">
<span class="agent-dot health-live"></span>
<div class="agent-info"><div class="agent-name">prod-1</div><div class="agent-detail">order-service v3.2.1</div></div>
<div class="agent-stats-col"><div class="agent-tps">14.2/s</div><div>12s ago</div></div>
</div>
<div class="agent-item">
<span class="agent-dot health-live"></span>
<div class="agent-info"><div class="agent-name">prod-2</div><div class="agent-detail">payment-svc v3.2.1</div></div>
<div class="agent-stats-col"><div class="agent-tps">11.8/s</div><div style="color: var(--error);">3 err/h</div></div>
</div>
<div class="agent-item">
<span class="agent-dot health-live"></span>
<div class="agent-info"><div class="agent-name">prod-3</div><div class="agent-detail">shipment-svc v3.2.0</div></div>
<div class="agent-stats-col"><div class="agent-tps">12.1/s</div><div>5s ago</div></div>
</div>
<div class="agent-item">
<span class="agent-dot health-live"></span>
<div class="agent-info"><div class="agent-name">prod-4</div><div class="agent-detail">shipment-svc v3.2.0</div></div>
<div class="agent-stats-col"><div class="agent-tps">9.1/s</div><div>3s ago</div></div>
</div>
</div>
<div class="sidebar-bottom">
<div class="sidebar-item"><span style="font-size: 13px; width: 18px; text-align: center;">&#9881;</span><div class="item-info"><div class="item-name">Admin</div></div></div>
<div class="sidebar-item"><span style="font-size: 13px; width: 18px; text-align: center;">&#9776;</span><div class="item-info"><div class="item-name">API Docs</div></div></div>
</div>
</aside>
<!-- MAIN CONTENT -->
<div class="main">
<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: 12px; color: var(--text-muted);">&#128270;</span>
<span>Search by Order ID, route, error...</span>
<span class="topbar-kbd">Ctrl+K</span>
</div>
<div class="topbar-right">
<span class="topbar-env">PRODUCTION</span>
<span class="topbar-shift">Shift: Day (06:00-18:00)</span>
<div class="topbar-user">
<span>hendrik</span>
<div class="topbar-avatar">H</div>
</div>
</div>
</div>
<div class="content-wrap">
<div class="content">
<!-- Health strip -->
<div class="health-strip animate-in">
<div class="stat-card card-amber">
<div class="stat-label">Executions (shift)</div>
<div class="stat-value-row"><span class="stat-value">3,241</span><span class="stat-trend trend-up-good">+12%</span></div>
<div class="stat-detail"><strong>97.1%</strong> success since 06:00</div>
</div>
<div class="stat-card card-green">
<div class="stat-label">Success Rate</div>
<div class="stat-value-row"><span class="stat-value val-green">97.1%</span><span class="stat-trend trend-down-bad">-0.4%</span></div>
<div class="stat-detail">3,147 ok / 56 warn / 38 error</div>
</div>
<div class="stat-card card-error has-errors">
<div class="stat-label">Errors (shift)</div>
<div class="stat-value-row"><span class="stat-value val-error">38</span><span class="stat-trend trend-up-bad">+5</span></div>
<div class="stat-detail"><strong>23</strong> overnight &middot; <strong>15</strong> since 06:00</div>
</div>
<div class="stat-card card-teal">
<div class="stat-label">Throughput</div>
<div class="stat-value-row"><span class="stat-value">47.2</span><span class="stat-unit">msg/s</span><span class="stat-trend trend-flat">&#8596;</span></div>
<div class="stat-detail">Capacity: 120 msg/s &middot; <strong>39%</strong></div>
</div>
<div class="stat-card card-warn">
<div class="stat-label">Latency p99</div>
<div class="stat-value-row"><span class="stat-value val-warn">287</span><span class="stat-unit">ms</span><span class="stat-trend trend-up-bad">+23ms</span></div>
<div class="stat-detail">SLA: &lt;300ms &middot; <strong style="color: var(--warning);">CLOSE</strong></div>
</div>
</div>
<!-- Filter bar -->
<div class="filter-section animate-in delay-1">
<div class="filter-row">
<div class="filter-input-wrap">
<span class="fi-icon">&#128270;</span>
<input class="filter-input" type="text" placeholder="Search by Order ID, correlation ID, error message...">
</div>
<div class="filter-sep"></div>
<div class="filter-group">
<span class="filter-label">Status</span>
<span class="filter-pill active">All <span class="pill-count">3,241</span></span>
<span class="filter-pill"><span class="pill-dot" style="background: var(--success);"></span> OK <span class="pill-count">3,147</span></span>
<span class="filter-pill"><span class="pill-dot" style="background: var(--warning);"></span> Warn <span class="pill-count">56</span></span>
<span class="filter-pill"><span class="pill-dot" style="background: var(--error);"></span> Error <span class="pill-count">38</span></span>
<span class="filter-pill"><span class="pill-dot" style="background: var(--running);"></span> Running <span class="pill-count">9</span></span>
</div>
<div class="filter-sep"></div>
<div class="filter-group">
<span class="filter-label">Time</span>
<span class="filter-pill">15m</span>
<span class="filter-pill">1h</span>
<span class="filter-pill active">Shift</span>
<span class="filter-pill">24h</span>
<span class="filter-pill">7d</span>
</div>
</div>
<div class="active-filters">
<span class="filter-tag">time: since 06:00 (shift) <button class="filter-tag-remove">&times;</button></span>
<span class="filter-tag">app: order-service <button class="filter-tag-remove">&times;</button></span>
<span class="filter-tag">sort: newest first <button class="filter-tag-remove">&times;</button></span>
<button class="clear-all">Clear all</button>
</div>
</div>
<!-- Execution table -->
<div class="table-section animate-in delay-2">
<div class="table-header">
<span class="table-title">Recent Executions</span>
<div class="table-right">
<span class="table-meta">Showing 1-20 of 3,241</span>
<button class="live-btn"><span class="live-dot"></span> LIVE</button>
</div>
</div>
<div class="table-scroll">
<table>
<thead>
<tr>
<th style="width: 85px">Status</th>
<th>Route</th>
<th>Order ID</th>
<th>Customer</th>
<th class="sorted">Started <span class="sort-arrow">&#9660;</span></th>
<th>Duration</th>
<th>Agent</th>
</tr>
</thead>
<tbody>
<tr class="row-success">
<td><span class="status-badge status-success"><span class="status-dot"></span>OK</span></td>
<td><div class="route-name">order-intake</div><div class="route-group">order-flow</div></td>
<td><div class="biz-id">OP-92184</div><div class="biz-id-secondary">SAP-DE</div></td>
<td><span class="biz-id-secondary">CUST-44210</span></td>
<td><span class="time-relative">2 min ago</span><span class="time-absolute">09:12:04</span></td>
<td><span class="duration dur-fast">87ms</span></td>
<td><span class="agent-badge"><span class="agent-badge-dot health-live"></span>prod-1</span></td>
</tr>
<tr class="row-success">
<td><span class="status-badge status-success"><span class="status-dot"></span>OK</span></td>
<td><div class="route-name">payment-validate</div><div class="route-group">payment-flow</div></td>
<td><div class="biz-id">OP-92183</div><div class="biz-id-secondary">WEB-EU</div></td>
<td><span class="biz-id-secondary">CUST-18773</span></td>
<td><span class="time-relative">3 min ago</span><span class="time-absolute">09:11:22</span></td>
<td><span class="duration dur-normal">164ms</span></td>
<td><span class="agent-badge"><span class="agent-badge-dot health-live"></span>prod-2</span></td>
</tr>
<tr class="row-running">
<td><span class="status-badge status-running"><span class="status-dot" style="animation: pulse 1.5s ease-in-out infinite;"></span>RUN</span></td>
<td><div class="route-name">order-enrichment</div><div class="route-group">order-flow</div></td>
<td><div class="biz-id">OP-92185</div><div class="biz-id-secondary">EDI-US</div></td>
<td><span class="biz-id-secondary">CUST-67501</span></td>
<td><span class="time-relative">30s ago</span><span class="time-absolute">09:13:44</span></td>
<td><span class="duration" style="color: var(--running);">~30s</span></td>
<td><span class="agent-badge"><span class="agent-badge-dot health-live"></span>prod-1</span></td>
</tr>
<tr class="row-warning">
<td><span class="status-badge status-warning"><span class="status-dot"></span>WARN</span></td>
<td><div class="route-name">shipment-dispatch</div><div class="route-group">shipment-flow</div></td>
<td><div class="biz-id">OP-92180</div><div class="biz-id-secondary">SAP-DE</div></td>
<td><span class="biz-id-secondary">CUST-55019</span></td>
<td><span class="time-relative">5 min ago</span><span class="time-absolute">09:09:47</span></td>
<td><span class="duration dur-slow">248ms</span> <span class="sla-tag">SLA</span></td>
<td><span class="agent-badge"><span class="agent-badge-dot health-live"></span>prod-3</span></td>
</tr>
<!-- ERROR with inline preview -->
<tr class="row-error selected">
<td><span class="status-badge status-error"><span class="status-dot"></span>ERR</span></td>
<td><div class="route-name">payment-process</div><div class="route-group">payment-flow</div></td>
<td><div class="biz-id">OP-88421</div><div class="biz-id-secondary">WEB-EU</div></td>
<td><span class="biz-id-secondary">CUST-31094</span></td>
<td><span class="time-relative">8 min ago</span><span class="time-absolute">09:06:11</span></td>
<td><span class="duration dur-breach">412ms</span></td>
<td><span class="agent-badge"><span class="agent-badge-dot health-live"></span>prod-2</span></td>
</tr>
<tr class="error-preview-row">
<td colspan="7">
<div class="error-preview">
<span class="error-preview-icon">&#9888;</span>
<div>
<div class="error-preview-text">org.apache.camel.CamelExecutionException: Payment gateway timeout after 5000ms &mdash; POST https://pay.provider.com/v2/charge returned HTTP 504. Retry exhausted (3/3).</div>
<div class="error-expand-hint">Click to view full stack trace and exchange snapshot</div>
</div>
</div>
</td>
</tr>
<!-- ERROR 2 -->
<tr class="row-error">
<td><span class="status-badge status-error"><span class="status-dot"></span>ERR</span></td>
<td><div class="route-name">order-enrichment</div><div class="route-group">order-flow</div></td>
<td><div class="biz-id">OP-88419</div><div class="biz-id-secondary">EDI-US</div></td>
<td><span class="biz-id-secondary">CUST-72841</span></td>
<td><span class="time-relative">12 min ago</span><span class="time-absolute">09:02:38</span></td>
<td><span class="duration dur-breach">1,247ms</span></td>
<td><span class="agent-badge"><span class="agent-badge-dot health-live"></span>prod-1</span></td>
</tr>
<tr class="error-preview-row">
<td colspan="7">
<div class="error-preview">
<span class="error-preview-icon">&#9888;</span>
<div>
<div class="error-preview-text">java.sql.SQLTransientConnectionException: HikariPool-1 - Connection not available, request timed out after 1000ms. (pool: 10, active: 10, idle: 0, waiting: 3)</div>
<div class="error-expand-hint">Click to view full stack trace and exchange snapshot</div>
</div>
</div>
</td>
</tr>
<tr class="row-success"><td><span class="status-badge status-success"><span class="status-dot"></span>OK</span></td><td><div class="route-name">order-intake</div><div class="route-group">order-flow</div></td><td><div class="biz-id">OP-92179</div><div class="biz-id-secondary">WEB-EU</div></td><td><span class="biz-id-secondary">CUST-90123</span></td><td><span class="time-relative">14 min ago</span><span class="time-absolute">09:00:15</span></td><td><span class="duration dur-fast">62ms</span></td><td><span class="agent-badge"><span class="agent-badge-dot health-live"></span>prod-3</span></td></tr>
<tr class="row-success"><td><span class="status-badge status-success"><span class="status-dot"></span>OK</span></td><td><div class="route-name">payment-validate</div><div class="route-group">payment-flow</div></td><td><div class="biz-id">OP-92178</div><div class="biz-id-secondary">SAP-DE</div></td><td><span class="biz-id-secondary">CUST-44210</span></td><td><span class="time-relative">16 min ago</span><span class="time-absolute">08:58:33</span></td><td><span class="duration dur-normal">131ms</span></td><td><span class="agent-badge"><span class="agent-badge-dot health-live"></span>prod-1</span></td></tr>
<tr class="row-success"><td><span class="status-badge status-success"><span class="status-dot"></span>OK</span></td><td><div class="route-name">shipment-track</div><div class="route-group">shipment-flow</div></td><td><div class="biz-id">OP-92175</div><div class="biz-id-secondary">EDI-US</div></td><td><span class="biz-id-secondary">CUST-67892</span></td><td><span class="time-relative">21 min ago</span><span class="time-absolute">08:53:07</span></td><td><span class="duration dur-fast">94ms</span></td><td><span class="agent-badge"><span class="agent-badge-dot health-live"></span>prod-4</span></td></tr>
<tr class="row-success"><td><span class="status-badge status-success"><span class="status-dot"></span>OK</span></td><td><div class="route-name">order-intake</div><div class="route-group">order-flow</div></td><td><div class="biz-id">OP-92174</div><div class="biz-id-secondary">WEB-EU</div></td><td><span class="biz-id-secondary">CUST-15293</span></td><td><span class="time-relative">24 min ago</span><span class="time-absolute">08:50:41</span></td><td><span class="duration dur-fast">73ms</span></td><td><span class="agent-badge"><span class="agent-badge-dot health-live"></span>prod-1</span></td></tr>
<tr class="row-success"><td><span class="status-badge status-success"><span class="status-dot"></span>OK</span></td><td><div class="route-name">payment-process</div><div class="route-group">payment-flow</div></td><td><div class="biz-id">OP-92173</div><div class="biz-id-secondary">SAP-DE</div></td><td><span class="biz-id-secondary">CUST-88104</span></td><td><span class="time-relative">28 min ago</span><span class="time-absolute">08:46:19</span></td><td><span class="duration dur-normal">198ms</span></td><td><span class="agent-badge"><span class="agent-badge-dot health-live"></span>prod-2</span></td></tr>
<tr class="row-warning"><td><span class="status-badge status-warning"><span class="status-dot"></span>WARN</span></td><td><div class="route-name">order-enrichment</div><div class="route-group">order-flow</div></td><td><div class="biz-id">OP-92170</div><div class="biz-id-secondary">EDI-US</div></td><td><span class="biz-id-secondary">CUST-50321</span></td><td><span class="time-relative">35 min ago</span><span class="time-absolute">08:39:52</span></td><td><span class="duration dur-slow">267ms</span> <span class="sla-tag">SLA</span></td><td><span class="agent-badge"><span class="agent-badge-dot health-live"></span>prod-1</span></td></tr>
<tr class="row-success"><td><span class="status-badge status-success"><span class="status-dot"></span>OK</span></td><td><div class="route-name">shipment-dispatch</div><div class="route-group">shipment-flow</div></td><td><div class="biz-id">OP-92168</div><div class="biz-id-secondary">WEB-EU</div></td><td><span class="biz-id-secondary">CUST-29104</span></td><td><span class="time-relative">42 min ago</span><span class="time-absolute">08:32:28</span></td><td><span class="duration dur-fast">55ms</span></td><td><span class="agent-badge"><span class="agent-badge-dot health-live"></span>prod-3</span></td></tr>
<tr class="row-success"><td><span class="status-badge status-success"><span class="status-dot"></span>OK</span></td><td><div class="route-name">order-intake</div><div class="route-group">order-flow</div></td><td><div class="biz-id">OP-92165</div><div class="biz-id-secondary">SAP-DE</div></td><td><span class="biz-id-secondary">CUST-77618</span></td><td><span class="time-relative">51 min ago</span><span class="time-absolute">08:23:14</span></td><td><span class="duration dur-fast">81ms</span></td><td><span class="agent-badge"><span class="agent-badge-dot health-live"></span>prod-4</span></td></tr>
<tr class="row-error"><td><span class="status-badge status-error"><span class="status-dot"></span>ERR</span></td><td><div class="route-name">payment-process</div><div class="route-group">payment-flow</div></td><td><div class="biz-id">OP-91844</div><div class="biz-id-secondary">WEB-EU</div></td><td><span class="biz-id-secondary">CUST-10082</span></td><td><span class="time-relative">5 hours ago</span><span class="time-absolute">04:12:55</span></td><td><span class="duration dur-breach">timeout</span></td><td><span class="agent-badge"><span class="agent-badge-dot health-live"></span>prod-2</span></td></tr>
<tr class="row-success"><td><span class="status-badge status-success"><span class="status-dot"></span>OK</span></td><td><div class="route-name">order-intake</div><div class="route-group">order-flow</div></td><td><div class="biz-id">OP-91840</div><div class="biz-id-secondary">EDI-US</div></td><td><span class="biz-id-secondary">CUST-38291</span></td><td><span class="time-relative">5 hours ago</span><span class="time-absolute">04:10:22</span></td><td><span class="duration dur-fast">78ms</span></td><td><span class="agent-badge"><span class="agent-badge-dot health-live"></span>prod-1</span></td></tr>
</tbody>
</table>
</div>
<div class="table-footer">
<span class="mono" style="font-size: 11px;">20 rows per page</span>
<div class="pagination">
<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">162</button>
</div>
</div>
</div>
<!-- Metrics panel -->
<div class="metrics-row animate-in delay-3">
<div class="metric-card">
<div class="metric-card-header">
<span class="metric-card-title">Throughput (1h)</span>
<span class="metric-card-value">47.2<span style="font-size:11px; font-weight:400; color: var(--text-muted)"> msg/s</span></span>
</div>
<div class="metric-chart">
<svg width="100%" height="100%" viewBox="0 0 300 65" preserveAspectRatio="none">
<line x1="0" y1="16" x2="300" y2="16" class="chart-grid-line"/>
<line x1="0" y1="32" x2="300" y2="32" class="chart-grid-line"/>
<line x1="0" y1="48" x2="300" y2="48" class="chart-grid-line"/>
<path d="M0,50 L25,47 50,43 75,45 100,40 125,37 150,39 175,35 200,33 225,35 250,37 275,34 300,33 L300,65 L0,65 Z" fill="#22D3EE" class="chart-area"/>
<path d="M0,50 L25,47 50,43 75,45 100,40 125,37 150,39 175,35 200,33 225,35 250,37 275,34 300,33" stroke="#22D3EE" class="chart-line"/>
<text x="0" y="63" class="chart-label">08:15</text>
<text x="145" y="63" class="chart-label">08:45</text>
<text x="282" y="63" class="chart-label">09:14</text>
</svg>
</div>
</div>
<div class="metric-card">
<div class="metric-card-header">
<span class="metric-card-title">Latency p99 (1h)</span>
<span class="metric-card-value" style="color: var(--warning);">287<span style="font-size:11px; font-weight:400; color: var(--text-muted)">ms</span> <span style="font-size:12px; color: var(--error);">&#8599;</span></span>
</div>
<div class="metric-chart">
<svg width="100%" height="100%" viewBox="0 0 300 65" preserveAspectRatio="none">
<line x1="0" y1="16" x2="300" y2="16" class="chart-grid-line"/>
<line x1="0" y1="32" x2="300" y2="32" class="chart-grid-line"/>
<line x1="0" y1="48" x2="300" y2="48" class="chart-grid-line"/>
<line x1="0" y1="10" x2="300" y2="10" class="sla-line"/>
<text x="4" y="8" class="sla-label-text">SLA 300ms</text>
<rect x="0" y="0" width="300" height="10" fill="rgba(244, 63, 94, 0.04)"/>
<path d="M0,42 L25,40 50,37 75,35 100,33 125,30 150,27 175,23 200,20 225,18 250,16 275,14 300,13 L300,65 L0,65 Z" fill="#F0B429" class="chart-area"/>
<path d="M0,42 L25,40 50,37 75,35 100,33 125,30 150,27 175,23 200,20 225,18 250,16 275,14 300,13" stroke="#F0B429" class="chart-line"/>
<path d="M0,52 L25,53 50,52 75,50 100,52 125,51 150,50 175,52 200,50 225,49 250,50 275,48 300,47" stroke="#22D3EE" stroke-width="1" opacity="0.4" fill="none" stroke-dasharray="4 3"/>
<text x="0" y="63" class="chart-label">08:15</text>
<text x="145" y="63" class="chart-label">08:45</text>
<text x="282" y="63" class="chart-label">09:14</text>
</svg>
</div>
</div>
<div class="metric-card">
<div class="metric-card-header">
<span class="metric-card-title">Error Rate (1h)</span>
<span class="metric-card-value" style="color: var(--error);">2.9<span style="font-size:11px; font-weight:400; color: var(--text-muted)">%</span> <span style="font-size:12px;">&#8599;</span></span>
</div>
<div class="metric-chart">
<svg width="100%" height="100%" viewBox="0 0 300 65" preserveAspectRatio="none">
<line x1="0" y1="16" x2="300" y2="16" class="chart-grid-line"/>
<line x1="0" y1="32" x2="300" y2="32" class="chart-grid-line"/>
<line x1="0" y1="48" x2="300" y2="48" class="chart-grid-line"/>
<line x1="0" y1="16" x2="300" y2="16" class="sla-line"/>
<text x="4" y="14" class="sla-label-text">SLA 5%</text>
<rect x="2" y="54" width="18" height="11" rx="2" fill="rgba(244, 63, 94, 0.25)"/>
<rect x="24" y="56" width="18" height="9" rx="2" fill="rgba(244, 63, 94, 0.25)"/>
<rect x="46" y="58" width="18" height="7" rx="2" fill="rgba(244, 63, 94, 0.25)"/>
<rect x="68" y="55" width="18" height="10" rx="2" fill="rgba(244, 63, 94, 0.25)"/>
<rect x="90" y="52" width="18" height="13" rx="2" fill="rgba(244, 63, 94, 0.3)"/>
<rect x="112" y="56" width="18" height="9" rx="2" fill="rgba(244, 63, 94, 0.25)"/>
<rect x="134" y="59" width="18" height="6" rx="2" fill="rgba(244, 63, 94, 0.25)"/>
<rect x="156" y="50" width="18" height="15" rx="2" fill="rgba(244, 63, 94, 0.35)"/>
<rect x="178" y="45" width="18" height="20" rx="2" fill="rgba(244, 63, 94, 0.5)"/>
<rect x="200" y="42" width="18" height="23" rx="2" fill="rgba(244, 63, 94, 0.55)"/>
<rect x="222" y="38" width="18" height="27" rx="2" fill="rgba(244, 63, 94, 0.6)"/>
<rect x="244" y="36" width="18" height="29" rx="2" fill="rgba(244, 63, 94, 0.65)"/>
<rect x="266" y="34" width="18" height="31" rx="2" fill="rgba(244, 63, 94, 0.75)"/>
<text x="0" y="63" class="chart-label">08:15</text>
<text x="145" y="63" class="chart-label">08:45</text>
<text x="282" y="63" class="chart-label">09:14</text>
</svg>
</div>
</div>
</div>
</div><!-- /content -->
<!-- DETAIL PANEL -->
<div class="detail-panel open">
<div class="detail-header">
<div class="detail-breadcrumb">
<span>order-service</span>
<span class="bc-sep">&#9656;</span>
<span>payment-process</span>
<span class="bc-sep">&#9656;</span>
<span class="bc-current">OP-88421</span>
</div>
<button class="detail-close" title="Close (Esc)">&times;</button>
</div>
<div class="detail-tabs">
<button class="detail-tab active">Overview</button>
<button class="detail-tab">Processors</button>
<button class="detail-tab">Exchange</button>
<button class="detail-tab">Error</button>
</div>
<div class="detail-body">
<div class="detail-section">
<div class="detail-section-title">Execution Details</div>
<div class="detail-grid">
<span class="detail-key">Status</span>
<span class="detail-val"><span class="status-badge status-error" style="font-size:10px"><span class="status-dot"></span>FAILED</span></span>
<span class="detail-key">Order ID</span>
<span class="detail-val" style="color: var(--cyan);">OP-88421</span>
<span class="detail-key">Customer</span>
<span class="detail-val">CUST-31094</span>
<span class="detail-key">Source</span>
<span class="detail-val">WEB-EU</span>
<span class="detail-key">Correlation ID</span>
<span class="detail-val">c7e2a1f0-9b3d-4e1a-8f2c-5d6e7f8a9b0c</span>
<span class="detail-key">Application</span>
<span class="detail-val">order-service</span>
<span class="detail-key">Route</span>
<span class="detail-val link">payment-process</span>
<span class="detail-key">Agent</span>
<span class="detail-val">prod-2</span>
<span class="detail-key">Started</span>
<span class="detail-val">2026-03-17T09:06:11.341Z</span>
<span class="detail-key">Duration</span>
<span class="detail-val error-text">412ms</span>
<span class="detail-key">Processors</span>
<span class="detail-val">7 (5 ok, 1 failed, 1 skipped)</span>
</div>
</div>
<div class="detail-section">
<div class="detail-section-title">Processor Timeline</div>
<div class="processor-timeline">
<div class="proc-row"><span class="proc-name">unmarshal</span><div class="proc-bar-bg"><div class="proc-bar-fill proc-ok" style="left:0;width:8%">12ms</div></div><span class="proc-dur">12ms</span></div>
<div class="proc-row"><span class="proc-name">validate</span><div class="proc-bar-bg"><div class="proc-bar-fill proc-ok" style="left:8%;width:5%">8ms</div></div><span class="proc-dur">8ms</span></div>
<div class="proc-row"><span class="proc-name">enrich(inventory)</span><div class="proc-bar-bg"><div class="proc-bar-fill proc-slow" style="left:13%;width:20%">85ms</div></div><span class="proc-dur">85ms</span></div>
<div class="proc-row"><span class="proc-name">transform</span><div class="proc-bar-bg"><div class="proc-bar-fill proc-ok" style="left:33%;width:3%">5ms</div></div><span class="proc-dur">5ms</span></div>
<div class="proc-row"><span class="proc-name">to(payment-api)</span><div class="proc-bar-bg"><div class="proc-bar-fill proc-fail" style="left:36%;width:58%">280ms</div></div><span class="proc-dur">280ms</span></div>
<div class="proc-row"><span class="proc-name">log</span><div class="proc-bar-bg"><div class="proc-bar-fill proc-ok" style="left:94%;width:2%">2ms</div></div><span class="proc-dur">2ms</span></div>
<div class="proc-row"><span class="proc-name" style="color: var(--text-faint);">marshal</span><div class="proc-bar-bg" style="opacity:0.3"></div><span class="proc-dur" style="color: var(--text-faint);">skip</span></div>
</div>
</div>
<div class="detail-section">
<div class="detail-section-title">Error</div>
<div class="error-block">
<div class="error-class">org.apache.camel.http.base.HttpOperationFailedException</div>
<div class="error-message-detail">
HTTP operation failed invoking https://pay.provider.com/v2/charge<br>
with statusCode: 504 Gateway Timeout<br>
Retry exhausted (3/3 attempts)<br>
&nbsp;&nbsp;at processor: to(payment-api) [step 5/7]
</div>
<button class="error-expand">&#9656; Show full stack trace</button>
</div>
</div>
</div>
<div class="detail-actions">
<button class="action-btn primary">View Route Diagram</button>
<button class="action-btn secondary">Copy ID</button>
<button class="action-btn secondary">Re-process</button>
</div>
</div>
</div>
</div>
</div>
<div class="shortcuts-bar">
<div class="shortcut-hint"><kbd>Ctrl</kbd>+<kbd>K</kbd> Search</div>
<div class="shortcut-hint"><kbd>&#8593;</kbd><kbd>&#8595;</kbd> Navigate</div>
<div class="shortcut-hint"><kbd>Enter</kbd> Detail</div>
<div class="shortcut-hint"><kbd>Esc</kbd> Close</div>
<div class="shortcut-hint"><kbd>?</kbd> Shortcuts</div>
</div>
</body>
</html>