{title}
-{copy}
-diff --git a/web/src/main.tsx b/web/src/main.tsx index 94c2ea5..6448e4b 100644 --- a/web/src/main.tsx +++ b/web/src/main.tsx @@ -4,6 +4,7 @@ import { Agentation } from 'agentation' import './index.css' import './App.css' import './layout-fixes.css' +import './styles/landing-views.css' import App from './App.tsx' import { AuthProvider } from './components/AuthContext'; import { ProductAccessibilityGate } from './components/ProductAccessibilityGate'; diff --git a/web/src/styles/landing-views.css b/web/src/styles/landing-views.css new file mode 100644 index 0000000..ffcb605 --- /dev/null +++ b/web/src/styles/landing-views.css @@ -0,0 +1,91 @@ +/* --------------------------------------------------------------------------- + landing-views.css — extracted patterns from OverviewTab, HomeView, MyStrategiesTab + (UI audit #8, Pattern B). Keeps token-driven structural styles in CSS so they + can have @media queries and so consumers can override via class composition. + One-off styles remain inline (already var(--bl-*) driven). +--------------------------------------------------------------------------- */ + +/* Card / panel container — used across overview metric cards, strategy + profile cards, and home preview panels. */ +.lv-card { + background: var(--card); + border-radius: 12px; + border: 1px solid var(--border); + padding: 16px; +} + +/* Larger structural card — overview "tile" / strategy profile shell. */ +.lv-card-lg { + background: var(--bl-surface-overlay); + border: 1px solid var(--bl-border-subtle); + padding: 16px; + border-radius: 20px; + display: flex; + flex-direction: column; +} + +/* Highlight chip / icon tag — small square holder for an icon + accent. */ +.lv-icon-tag { + width: 38px; + height: 38px; + border-radius: 10px; + background: var(--bl-surface-highlight); + border: 1px solid var(--bl-border-subtle); + display: flex; + align-items: center; + justify-content: center; +} + +/* Soft 24-radius surface — used by strategy profile sections, education panels. */ +.lv-surface { + background: var(--bl-surface-highlight); + border: 1px solid var(--bl-border-subtle); + border-radius: 24px; + padding: 16px; +} + +/* Eyebrow / section label — small, bold, uppercase, letter-spaced. */ +.lv-eyebrow { + font-size: 11px; + font-weight: 900; + color: var(--bl-text-quiet); + text-transform: uppercase; + letter-spacing: 2px; +} + +/* Section title — bold token-foreground at fixed metric size. */ +.lv-section-title { + font-size: 13px; + font-weight: 700; + color: var(--foreground); + margin-bottom: 10px; +} + +/* Section subtitle — muted, fixed metric size. */ +.lv-section-sub { + font-size: 12px; + color: var(--muted-foreground); +} + +/* Empty-state text — italic, centered, padded, tertiary color. */ +.lv-empty-text { + text-align: center; + padding: 16px; + color: var(--bl-text-tertiary); + font-size: 12px; + font-style: italic; +} + +/* Top-bordered divider with breathing room — used for footer-like rows + inside cards (totals, last-updated stamps). */ +.lv-divider-row { + margin-top: 12px; + padding-top: 10px; + border-top: 1px solid var(--border); +} + +/* Tiny meta value — used for fine-print metrics next to the eyebrow. */ +.lv-meta-faint { + font-size: 0.65rem; + color: var(--bl-text-faint); +} diff --git a/web/src/tabs/MyStrategiesTab.tsx b/web/src/tabs/MyStrategiesTab.tsx index f604126..e1f6502 100644 --- a/web/src/tabs/MyStrategiesTab.tsx +++ b/web/src/tabs/MyStrategiesTab.tsx @@ -3,24 +3,24 @@ import { useAuth } from '../components/AuthContext'; import { getStrategyExplanation } from '../lib/StrategyExplanationService'; import { getUserTier } from '../lib/TierPolicy'; import { - Play, - Pause, - Trash2, - Activity, - TrendingUp, - Plus, - Shield, - Zap, - Scale, - Settings, - ChevronDown, - ChevronUp, - Lightbulb, - Cpu, - Fingerprint, - Target, - DollarSign, - Lock + Play, + Pause, + Trash2, + Activity, + TrendingUp, + Plus, + Shield, + Zap, + Scale, + Settings, + ChevronDown, + ChevronUp, + Lightbulb, + Cpu, + Fingerprint, + Target, + DollarSign, + Lock } from 'lucide-react'; import { StrategyWizard } from '../components/StrategyWizard'; import { BacktestRunnerPanel } from '../backtest/components/BacktestRunnerPanel'; @@ -30,459 +30,459 @@ import { Button, IconButton } from '../components/ui/Primitives'; import { CardButton } from '@bytelyst/ui'; function getStrategyKindLabel(config: any) { - if (config?.type === 'visual') return 'Visual Builder'; - if (config?.type === 'code') return 'Code Strategy'; - return 'V4.0 Core'; + if (config?.type === 'visual') return 'Visual Builder'; + if (config?.type === 'code') return 'Code Strategy'; + return 'V4.0 Core'; } const ActiveStrategyCard: React.FC<{ - profile: any; - botState: any; - tier: string; - onToggle: (p: any) => void; - onEdit: (p: any) => void; - onBacktest?: (p: any) => void; - onDelete: (id: string) => void; - isExpanded: boolean; - onToggleExpand: (id: string) => void; + profile: any; + botState: any; + tier: string; + onToggle: (p: any) => void; + onEdit: (p: any) => void; + onBacktest?: (p: any) => void; + onDelete: (id: string) => void; + isExpanded: boolean; + onToggleExpand: (id: string) => void; }> = ({ profile, botState, tier, onToggle, onEdit, onBacktest, onDelete, isExpanded, onToggleExpand }) => { - const config = profile.strategy_config; - const isAggressive = config?.execution?.minRulePassRatio < 0.9; - const isSafe = config?.execution?.minRulePassRatio >= 1.0; - const strategyKindLabel = getStrategyKindLabel(config); + const config = profile.strategy_config; + const isAggressive = config?.execution?.minRulePassRatio < 0.9; + const isSafe = config?.execution?.minRulePassRatio >= 1.0; + const strategyKindLabel = getStrategyKindLabel(config); - const explanation = getStrategyExplanation(profile, botState); + const explanation = getStrategyExplanation(profile, botState); - return ( -
- {explanation.reason} -
- {isExpanded && explanation.recommendation && ( -{explanation.recommendation}
-+ {explanation.reason} +
+ {isExpanded && explanation.recommendation && ( +{explanation.recommendation}
+- Monitor active profiles, review recent signals, and create new automated trading workflows. -
-+ Monitor active profiles, review recent signals, and create new automated trading workflows. +
+Create your first strategy to start monitoring markets and testing automated execution.
- -Create your first strategy to start monitoring markets and testing automated execution.
+ +Global view of market conditions and bot status.
-| Capital Scope | -Allocated | -Used | -Remaining | -Utilization | -Win Rate ({winRateWindowConfig.label}) | -Realized P&L | -State | -
|---|---|---|---|---|---|---|---|
| {row.name} | -{formatUsd(row.allocated)} | -{formatUsd(row.used)} | -
- {formatUsd(row.remaining)}
- {overAllocated && (
-
- raw +{formatUsd(row.overAllocatedAmount)}
-
- )}
- |
- - {row.utilizationPct.toFixed(1)}% - | -= 50 ? overviewSuccessText : overviewWarningText }}> - {row.winRate.toFixed(1)}% - - ({row.tradeCount}) - - | -= 0 ? overviewSuccessText : overviewDangerText }}> - {formatUsd(row.netPnl)} - | -
-
-
-
- {row.runtimeState}
-
-
- {row.runtimeDetail}
-
- |
-
| Account (Fallback) | -{formatUsd(allocatedCapital)} | -{formatUsd(capitalUsed)} | - 1e-8 ? overviewDangerText : overviewSuccessText }}>
- {formatUsd(remainingCapital)}
- {overAllocatedCapital > 1e-8 && (
-
- raw +{formatUsd(overAllocatedCapital)}
-
- )}
- |
- - {allocatedCapital > 0 ? ((capitalUsed / allocatedCapital) * 100).toFixed(1) : '0.0'}% - | -- | -= 0 ? overviewSuccessText : overviewDangerText }}>{formatUsd(displayRealizedPnl)} | -- No signal - | -
| Time | -Symbol | -Side | -Qty | -Reason | -Sub-tag | -Profile | -
|---|---|---|---|---|---|---|
| {new Date(fail.timestamp).toLocaleString()} | -{fail.symbol} | -{fail.side} | -{fail.qty} | -- {fail.reason} - | -- {compactTag(fail.subTag)} - | -{fail.profileId || 'Unknown'} | -
Global view of market conditions and bot status.
+| Capital Scope | +Allocated | +Used | +Remaining | +Utilization | +Win Rate ({winRateWindowConfig.label}) | +Realized P&L | +State | +
|---|---|---|---|---|---|---|---|
| {row.name} | +{formatUsd(row.allocated)} | +{formatUsd(row.used)} | +
+ {formatUsd(row.remaining)}
+ {overAllocated && (
+
+ raw +{formatUsd(row.overAllocatedAmount)}
+
+ )}
+ |
+ + {row.utilizationPct.toFixed(1)}% + | += 50 ? overviewSuccessText : overviewWarningText }}> + {row.winRate.toFixed(1)}% + + ({row.tradeCount}) + + | += 0 ? overviewSuccessText : overviewDangerText }}> + {formatUsd(row.netPnl)} + | +
+
+
+
+ {row.runtimeState}
+
+
+ {row.runtimeDetail}
+
+ |
+
| Account (Fallback) | +{formatUsd(allocatedCapital)} | +{formatUsd(capitalUsed)} | + 1e-8 ? overviewDangerText : overviewSuccessText }}>
+ {formatUsd(remainingCapital)}
+ {overAllocatedCapital > 1e-8 && (
+
+ raw +{formatUsd(overAllocatedCapital)}
+
+ )}
+ |
+ + {allocatedCapital > 0 ? ((capitalUsed / allocatedCapital) * 100).toFixed(1) : '0.0'}% + | +- | += 0 ? overviewSuccessText : overviewDangerText }}>{formatUsd(displayRealizedPnl)} | ++ No signal + | +
| Time | +Symbol | +Side | +Qty | +Reason | +Sub-tag | +Profile | +
|---|---|---|---|---|---|---|
| {new Date(fail.timestamp).toLocaleString()} | +{fail.symbol} | +{fail.side} | +{fail.qty} | ++ {fail.reason} + | ++ {compactTag(fail.subTag)} + | +{fail.profileId || 'Unknown'} | +
- Search or pick a configured asset to open charts, fundamentals, news, alerts, and execution context in one focused workspace. -
-+ Search or pick a configured asset to open charts, fundamentals, news, alerts, and execution context in one focused workspace. +
+{copy}
-{copy}
+