Skip to content

Commit 460079d

Browse files
whoabuddyclaude
andauthored
style(dashboard): apply AIBTC brand guidelines (#30)
- Update orange accent from #f7931a to #FF4F03 (AIBTC brand orange) - Align dark theme card backgrounds to #000/#0a0a0a - Add orange focus ring styling for accessibility - Add card-glow and card-accent hover effects with rAF-throttled mousemove - Add fadeUp entrance animations with prefers-reduced-motion support Closes #28 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 9e59dcd commit 460079d

2 files changed

Lines changed: 89 additions & 13 deletions

File tree

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@ worker-configuration.d.ts
3030
.vscode/
3131
.idea/
3232

33+
# Planning
34+
.planning/
35+
3336
# OS files
3437
.DS_Store
3538
Thumbs.db

src/endpoints/dashboard.ts

Lines changed: 86 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -169,16 +169,16 @@ function generateDashboardHTML(data: DashboardData, environment: string): string
169169
font-display: swap;
170170
}
171171
:root {
172-
--bg-primary: #09090b;
173-
--bg-card: #0f0f12;
172+
--bg-primary: #000;
173+
--bg-card: #0a0a0a;
174174
--bg-hover: #18181b;
175175
--border: rgba(255,255,255,0.06);
176176
--border-hover: rgba(255,255,255,0.1);
177177
--text-primary: #fafafa;
178178
--text-secondary: #a1a1aa;
179179
--text-muted: #71717a;
180-
--accent: #f7931a;
181-
--accent-dim: rgba(247, 147, 26, 0.12);
180+
--accent: #FF4F03;
181+
--accent-dim: rgba(255, 79, 3, 0.12);
182182
/* AIBTC brand colors - reserved for future dashboard elements */
183183
--color-blue: #7DA2FF;
184184
--color-purple: #A855F7;
@@ -258,6 +258,8 @@ function generateDashboardHTML(data: DashboardData, environment: string): string
258258
margin-bottom: 32px;
259259
}
260260
.card {
261+
position: relative;
262+
overflow: hidden;
261263
background: var(--bg-card);
262264
border: 1px solid var(--border);
263265
border-radius: 16px;
@@ -268,7 +270,28 @@ function generateDashboardHTML(data: DashboardData, environment: string): string
268270
border-color: var(--border-hover);
269271
transform: translateY(-2px);
270272
}
273+
.card-glow::after {
274+
content: '';
275+
position: absolute;
276+
top: 0; left: 0; right: 0; bottom: 0;
277+
background: radial-gradient(circle at var(--mouse-x, 50%) var(--mouse-y, 50%), var(--accent-dim) 0%, transparent 60%);
278+
opacity: 0;
279+
transition: opacity 0.4s ease;
280+
pointer-events: none;
281+
}
282+
.card-glow:hover::after { opacity: 1; }
283+
.card-accent::before {
284+
content: '';
285+
position: absolute;
286+
top: 0; left: 0; right: 0;
287+
height: 2px;
288+
background: linear-gradient(90deg, var(--accent), transparent);
289+
opacity: 0;
290+
transition: opacity 0.3s ease;
291+
}
292+
.card-accent:hover::before { opacity: 1; }
271293
.card h3 {
294+
position: relative;
272295
color: var(--text-muted);
273296
font-size: 11px;
274297
text-transform: uppercase;
@@ -277,6 +300,7 @@ function generateDashboardHTML(data: DashboardData, environment: string): string
277300
font-weight: 500;
278301
}
279302
.card .value {
303+
position: relative;
280304
font-size: 28px;
281305
font-weight: 700;
282306
color: var(--text-primary);
@@ -295,6 +319,8 @@ function generateDashboardHTML(data: DashboardData, environment: string): string
295319
scroll-margin-top: 24px;
296320
}
297321
.chart-container {
322+
position: relative;
323+
overflow: hidden;
298324
background: var(--bg-card);
299325
border: 1px solid var(--border);
300326
border-radius: 16px;
@@ -382,6 +408,7 @@ function generateDashboardHTML(data: DashboardData, environment: string): string
382408
.cat-storage { color: #3b82f6; }
383409
.cat-other { color: #71717a; }
384410
.table-container {
411+
position: relative;
385412
background: var(--bg-card);
386413
border: 1px solid var(--border);
387414
border-radius: 16px;
@@ -397,6 +424,8 @@ function generateDashboardHTML(data: DashboardData, environment: string): string
397424
gap: 12px;
398425
}
399426
.model-card {
427+
position: relative;
428+
overflow: hidden;
400429
background: #27272a;
401430
border-radius: 8px;
402431
padding: 14px;
@@ -430,6 +459,29 @@ function generateDashboardHTML(data: DashboardData, environment: string): string
430459
}
431460
.footer a { color: var(--accent); text-decoration: none; }
432461
.footer a:hover { opacity: 0.8; }
462+
a:focus-visible,
463+
th[data-sort]:focus-visible,
464+
.section-nav a:focus-visible {
465+
outline: 2px solid var(--accent);
466+
outline-offset: 3px;
467+
border-radius: 4px;
468+
}
469+
470+
@keyframes fadeUp {
471+
from { opacity: 0; transform: translateY(30px); }
472+
to { opacity: 1; transform: translateY(0); }
473+
}
474+
.animate-fadeUp {
475+
opacity: 0;
476+
animation: fadeUp 0.8s ease-out forwards;
477+
}
478+
@media (prefers-reduced-motion: reduce) {
479+
*, *::before, *::after {
480+
animation-duration: 0.01ms !important;
481+
animation-iteration-count: 1 !important;
482+
transition-duration: 0.01ms !important;
483+
}
484+
}
433485
434486
@media (max-width: 600px) {
435487
.container { padding: 16px; }
@@ -474,31 +526,31 @@ function generateDashboardHTML(data: DashboardData, environment: string): string
474526
</nav>
475527
476528
<h2 id="summary" class="section-title">Summary</h2>
477-
<div class="summary">
478-
<div class="card">
529+
<div class="summary animate-fadeUp">
530+
<div class="card card-glow card-accent">
479531
<h3>Endpoints</h3>
480532
<div class="value">${summary.totalEndpoints}</div>
481533
</div>
482-
<div class="card">
534+
<div class="card card-glow card-accent">
483535
<h3>Total Calls</h3>
484536
<div class="value">${summary.totalCalls.toLocaleString()}</div>
485537
</div>
486-
<div class="card">
538+
<div class="card card-glow card-accent">
487539
<h3>STX Earned</h3>
488540
<div class="value stx">${formatSTX(summary.earningsSTX)}</div>
489541
</div>
490-
<div class="card">
542+
<div class="card card-glow card-accent">
491543
<h3>Sats Earned</h3>
492544
<div class="value sbtc">${formatSBTC(summary.earningsSBTC)}</div>
493545
</div>
494-
<div class="card">
546+
<div class="card card-glow card-accent">
495547
<h3>USDCx Earned</h3>
496548
<div class="value usdcx">$${formatUSDCx(summary.earningsUSDCx)}</div>
497549
</div>
498550
</div>
499551
500552
<h2 id="daily" class="section-title">Daily Activity (Last 7 Days)</h2>
501-
<div class="chart-container">
553+
<div class="chart-container card-glow card-accent animate-fadeUp" style="animation-delay: 0.1s">
502554
<div class="bar-chart">
503555
${daily.map((day) => {
504556
const successHeight = Math.max((day.successfulCalls / maxDailyCalls) * 100, 2);
@@ -518,7 +570,7 @@ function generateDashboardHTML(data: DashboardData, environment: string): string
518570
</div>
519571
520572
<h2 id="endpoints" class="section-title">Endpoint Metrics</h2>
521-
<div class="table-container">
573+
<div class="table-container card-glow card-accent animate-fadeUp" style="animation-delay: 0.2s">
522574
<div class="table-scroll">
523575
<table id="endpoints-table">
524576
<thead>
@@ -561,7 +613,7 @@ function generateDashboardHTML(data: DashboardData, environment: string): string
561613
</div>
562614
563615
<h2 id="models" class="section-title">LLM Model Usage</h2>
564-
<div class="chart-container">
616+
<div class="chart-container card-glow card-accent animate-fadeUp" style="animation-delay: 0.3s">
565617
<div class="model-grid">
566618
${modelStats.length > 0 ? modelStats.map((model) => `
567619
<div class="model-card">
@@ -601,6 +653,27 @@ function generateDashboardHTML(data: DashboardData, environment: string): string
601653
602654
<script>
603655
(function() {
656+
document.querySelectorAll('.card-glow').forEach(function(card) {
657+
var isAnimating = false;
658+
var mouseX = 0;
659+
var mouseY = 0;
660+
661+
card.addEventListener('mousemove', function(e) {
662+
mouseX = e.clientX;
663+
mouseY = e.clientY;
664+
665+
if (isAnimating) return;
666+
isAnimating = true;
667+
668+
requestAnimationFrame(function() {
669+
var rect = card.getBoundingClientRect();
670+
card.style.setProperty('--mouse-x', ((mouseX - rect.left) / rect.width * 100) + '%');
671+
card.style.setProperty('--mouse-y', ((mouseY - rect.top) / rect.height * 100) + '%');
672+
isAnimating = false;
673+
});
674+
});
675+
});
676+
604677
const table = document.querySelector('#endpoints-table');
605678
if (!table) return;
606679

0 commit comments

Comments
 (0)