214b64945d
Live trading optimizations (cumulative: $2,807 net, 81.8% WR, Sharpe 3.97): - #28B: Smart breakeven locks profit at entry + 0.5x ATR instead of fixed $2 - #31B: H1 Price vs EMA20 filter — BUY only when H1 bullish, SELL only when bearish Backtests #26-#32 (7 scripts testing sell improvement, regime-aware entry, confluence scoring, dynamic RR, multi-TF H1, and ML exit optimizer). Winners: #28B (+$229), #31B (+$343). Failed: #26, #27, #29, #30, #32. Also includes: web dashboard redesign, Docker setup, startup scripts. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
7.9 KiB
7.9 KiB
XAUBot AI Dashboard - Styling Guide
Overview
The dashboard uses shadcn/ui components with Tailwind CSS and a custom dark theme inspired by nof1.ai and SURGE-AI-Trading.
Color System
Theme Colors
// Background & Surface
background: #0a0a0f (HSL: 222 47% 6%)
surface: #121218 (HSL: 222 25% 7%)
surface-light: #1a1a24 (HSL: 222 20% 10%)
surface-hover: #22222e (HSL: 222 18% 14%)
// Primary & Accent
primary: #6366f1 (Indigo)
primary-dark: #4f46e5
accent: #8b5cf6 (Purple)
// Semantic Colors
success: #22c55e (Green)
warning: #f59e0b (Orange)
danger: #ef4444 (Red)
info: #3b82f6 (Blue)
// Each semantic color has a background variant with 12.5% opacity
success-bg: #22c55e20
warning-bg: #f59e0b20
danger-bg: #ef444420
info-bg: #3b82f620
Border & Text
border: #2a2a3a
border-light: #3a3a4a
foreground: #ffffff
muted-foreground: #a1a1aa
Component Styling
Cards
// Glass effect card (recommended for dashboard)
<Card className="glass">
<CardHeader>...</CardHeader>
<CardContent>...</CardContent>
</Card>
// Custom card utilities
.glass → bg-surface/80 + backdrop-blur
.card-custom → bg-surface + rounded-xl + border
.card-hover → card-custom + hover effect
Badges
// Available badge variants
<Badge variant="default">Primary</Badge>
<Badge variant="success">Success</Badge>
<Badge variant="warning">Warning</Badge>
<Badge variant="danger">Danger</Badge>
<Badge variant="info">Info</Badge>
<Badge variant="outline">Outline</Badge>
Buttons
// Utility classes for buttons
className="btn-primary" → Primary button
className="btn-success" → Success button
className="btn-danger" → Danger button
className="btn-outline" → Outline button
Utility Classes
Text & Numbers
.font-number → font-mono + tabular-nums (for prices, numbers)
.text-gradient → gradient from primary to accent
.price-up → text-success
.price-down → text-danger
.price-neutral → text-muted-foreground
Animations
.animate-pulse-slow → 3s pulse
.animate-fade-in → fade in effect
.animate-slide-up → slide up effect
.animate-shimmer → shimmer loading effect
.skeleton → loading skeleton with shimmer
Live Indicators
// Adds a pulsing dot indicator
<div className="pulse-live">LIVE</div>
Utility Functions
Formatting
import {
formatUSD, // → $1,234.56
formatGoldPrice, // → 2345.67
formatPercent, // → +2.45%
formatCompact, // → 1.2M, 3.4K
formatTime, // → 14:23:45
formatDate, // → Jan 17, 2026
formatDateTime, // → Jan 17, 2026 14:23:45
formatDateTimeWIB // → 17 Jan 2026 14:23:45 WIB
} from '@/lib/utils';
Color Helpers
import {
getValueColor, // → Returns color class based on +/-
getValueBgColor, // → Returns bg color class based on +/-
getSignalColor, // → Returns color for BUY/SELL/HOLD
getSignalBadgeColor, // → Returns badge variant for signals
getConfidenceColor, // → Returns color based on confidence %
getConfidenceLevel // → Returns "Very High", "High", etc.
} from '@/lib/utils';
Other Utilities
import {
cn, // Merge Tailwind classes
calcProgress, // Calculate progress % (capped at 100)
debounce, // Debounce function
generateId, // Generate unique ID
sleep // Async sleep
} from '@/lib/utils';
Usage Examples
Price Display
import { formatGoldPrice, getValueColor } from '@/lib/utils';
<span className={cn(
"text-3xl font-bold font-number",
getValueColor(priceChange)
)}>
${formatGoldPrice(price)}
</span>
Signal Badge
import { getSignalBadgeColor } from '@/lib/utils';
<Badge variant={getSignalBadgeColor(signal)}>
{signal}
</Badge>
Confidence Display
import { getConfidenceColor, getConfidenceLevel } from '@/lib/utils';
const confidencePercent = confidence * 100;
<span className={cn(
"font-semibold",
getConfidenceColor(confidencePercent)
)}>
{confidencePercent.toFixed(0)}% - {getConfidenceLevel(confidencePercent)}
</span>
Profit/Loss Display
import { formatUSD, getValueColor } from '@/lib/utils';
<span className={cn(
"font-bold font-number",
getValueColor(profit)
)}>
{profit >= 0 ? '+' : ''}{formatUSD(profit)}
</span>
Typography
Fonts
- Sans: Inter, system-ui, sans-serif
- Mono: JetBrains Mono, Fira Code, monospace
Font Classes
<span className="font-sans">Regular text</span>
<span className="font-mono">Code or numbers</span>
<span className="font-number">Numbers (tabular-nums)</span>
Responsive Design
The dashboard is optimized for desktop but responsive:
<div className="hidden sm:flex">Desktop only</div>
<div className="sm:hidden">Mobile only</div>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3">
Responsive grid
</div>
Adding New shadcn/ui Components
- Check available components:
npx shadcn@latest view @shadcn
- Add a component:
npx shadcn@latest add button
npx shadcn@latest add tooltip
npx shadcn@latest add dialog
- Components will be added to
src/components/ui/
Best Practices
- Always use utility functions for formatting numbers, dates, and colors
- Use the
cn()helper to merge Tailwind classes - Apply
font-numberto all numeric displays for consistent monospace formatting - Use semantic colors (success, warning, danger, info) instead of raw colors
- Apply
glasseffect to cards for depth and consistency - Use uppercase + tracking-wider for card titles:
className="uppercase tracking-wider" - Add proper spacing with
space-y-*orgap-*utilities - Keep contrast in mind - use
text-muted-foregroundfor secondary text
Example Card Component
"use client";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Badge } from "@/components/ui/badge";
import { TrendingUp } from "lucide-react";
import { cn, formatUSD, getValueColor } from "@/lib/utils";
interface ExampleCardProps {
title: string;
value: number;
change: number;
status: "active" | "inactive";
}
export function ExampleCard({ title, value, change, status }: ExampleCardProps) {
return (
<Card className="glass">
<CardHeader className="pb-2">
<CardTitle className="text-sm font-medium text-muted-foreground flex items-center gap-2 uppercase tracking-wider">
<TrendingUp className="h-4 w-4" />
{title}
</CardTitle>
</CardHeader>
<CardContent className="space-y-3">
<div className="text-2xl font-bold font-number">
{formatUSD(value)}
</div>
<div className="flex items-center justify-between">
<span className={cn(
"text-sm font-medium font-number",
getValueColor(change)
)}>
{change >= 0 ? '+' : ''}{change.toFixed(2)}%
</span>
<Badge variant={status === 'active' ? 'success' : 'danger'}>
{status}
</Badge>
</div>
</CardContent>
</Card>
);
}
Migration Checklist
When updating existing components to the new styling:
- Replace hardcoded colors with theme colors (text-green-500 → text-success)
- Add
glassclass to cards - Use utility formatting functions instead of manual formatting
- Apply
font-numberto numeric displays - Use uppercase + tracking-wider for titles
- Replace manual color logic with utility functions (getValueColor, etc.)
- Update Badge variants to semantic ones (success, warning, danger, info)
- Add proper spacing with space-y or gap utilities
- Ensure proper use of
cn()for class merging
Resources
- shadcn/ui docs: https://ui.shadcn.com
- Tailwind CSS docs: https://tailwindcss.com
- Lucide Icons: https://lucide.dev
Last updated: Feb 6, 2026