diff --git a/web/src/components/MarketOpportunities.tsx b/web/src/components/MarketOpportunities.tsx index 5ea3f0a..dc7d62b 100644 --- a/web/src/components/MarketOpportunities.tsx +++ b/web/src/components/MarketOpportunities.tsx @@ -1,5 +1,6 @@ import type { BotState } from '../hooks/useWebSocket'; import { Activity, BrainCircuit } from 'lucide-react'; +import { Badge, EmptyState, Panel, PanelDescription, PanelHeader, PanelTitle } from './ui/Primitives'; interface MarketOpportunitiesProps { botState: BotState; @@ -12,27 +13,37 @@ export const TopVolatile = ({ botState }: MarketOpportunitiesProps) => { .slice(0, 5); return ( -
-
- -
-

Top movers

-

24h change by absolute move.

+ + +
+ + + +
+ Top movers + 24h change by absolute move. +
-
-
+ +
{topSymbols .map(symbol => ( -
- {symbol} - = 0 ? 'up' : 'down'}`}> - {botState.symbols[symbol].change24h >= 0 ? '+' : ''}{botState.symbols[symbol].change24h?.toFixed(2)}% - -
- ))} - {symbols.length === 0 &&
Waiting for live market ticks...
} +
+ {symbol} + = 0 ? 'success' : 'danger'} size="sm"> + {botState.symbols[symbol].change24h >= 0 ? '+' : ''}{botState.symbols[symbol].change24h?.toFixed(2)}% + +
+ ))} + {symbols.length === 0 && ( + + )}
-
+ ); }; @@ -44,28 +55,36 @@ export const AISetups = ({ botState }: MarketOpportunitiesProps) => { .slice(0, 5); return ( -
-
- -
-

AI setups

-

Highest-confidence symbols from strategy rules.

+ + +
+ + + +
+ AI setups + Highest-confidence symbols from strategy rules. +
-
-
+ +
{aiSymbols .map(symbol => ( -
- {symbol} - - {botState.symbols[symbol].rules['AIAnalysisRule']?.metadata?.confidence}% Conf - -
- ))} +
+ {symbol} + + {botState.symbols[symbol].rules['AIAnalysisRule']?.metadata?.confidence}% Conf + +
+ ))} {aiSymbols.length === 0 && ( -
No AI confidence signals yet.
+ )}
-
+ ); }; diff --git a/web/src/index.css b/web/src/index.css index 361f6a1..b49a878 100644 --- a/web/src/index.css +++ b/web/src/index.css @@ -1,8 +1,8 @@ @import '@bytelyst/design-tokens/generated/tokens.css'; +@import 'tailwindcss'; -@tailwind base; -@tailwind components; -@tailwind utilities; +@source './**/*.{ts,tsx}'; +@source '../../../learning_ai_common_plat/packages/ui/src/**/*.{ts,tsx}'; :root { font-family: 'Inter', system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif; @@ -2287,119 +2287,6 @@ body { min-width: 0; } -.opportunity-card-sidebar { - display: grid; - gap: 18px; - min-width: 0; - border: 1px solid var(--border); - border-radius: 18px; - background: var(--card); - padding: 20px; - box-shadow: 0 18px 50px rgba(15, 23, 42, 0.07); -} - -.opportunity-card-header { - display: flex; - align-items: flex-start; - gap: 12px; - min-width: 0; -} - -.opportunity-card-icon { - display: grid; - width: 34px; - height: 34px; - flex: 0 0 auto; - place-items: center; - border: 1px solid color-mix(in oklab, var(--accent) 24%, var(--border)); - border-radius: 12px; - background: var(--accent-soft); - color: var(--accent); -} - -.opportunity-card-sidebar h3 { - margin: 0; - color: var(--foreground); - font-size: 16px; - font-weight: 820; - letter-spacing: 0; -} - -.opportunity-card-sidebar p { - margin: 4px 0 0; - color: var(--muted-foreground); - font-size: 13px; - line-height: 1.5; -} - -.opp-list { - display: grid; - gap: 8px; -} - -.opp-item { - display: grid; - grid-template-columns: minmax(0, 1fr) auto; - align-items: center; - gap: 12px; - min-height: 42px; - border: 1px solid var(--border); - border-radius: 12px; - background: color-mix(in oklab, var(--muted) 48%, var(--card)); - padding: 8px 12px; -} - -.opp-symbol { - min-width: 0; - overflow: hidden; - color: var(--foreground); - font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace; - font-size: 13px; - font-weight: 800; - text-overflow: ellipsis; - white-space: nowrap; -} - -.opp-value { - display: inline-flex; - align-items: center; - min-height: 24px; - border-radius: 999px; - padding: 0 9px; - font-size: 11px; - font-weight: 800; - white-space: nowrap; -} - -.opp-value.up { - background: var(--bl-success-muted); - color: var(--bl-success); -} - -.opp-value.down { - background: var(--bl-danger-muted); - color: var(--bl-danger); -} - -.opp-value.ai { - background: var(--bl-info-muted); - color: var(--bl-info); -} - -.opp-empty { - display: grid; - min-height: 120px; - place-items: center; - border: 1px dashed var(--border); - border-radius: 14px; - background: color-mix(in oklab, var(--muted) 42%, transparent); - color: var(--muted-foreground); - padding: 18px; - text-align: center; - font-size: 13px; - line-height: 1.5; -} - .screener-filter-card { overflow: hidden; }