shadcn/ui design system — Claude Blu 2 dark theme
- Full oklch color space from tweakcn/r/themes/cmmea3qbd000004jvb99v39cd - Semantic tokens: --background, --foreground, --card, --primary, etc. - Backward compat mappings (--bg, --srf, --ln, --tx, --hi, etc.) - Dark shadows with proper opacity (--shadow-xs through --shadow-xl) - 8px scrollbar, focus rings, backdrop blurs - Cleaner card styling with subtle borders and hover lift - All existing JS functionality preserved
This commit is contained in:
+356
-75
@@ -7,78 +7,358 @@
|
|||||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;900&family=JetBrains+Mono:wght@400;500;600;700&display=swap" rel="stylesheet">
|
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;900&family=JetBrains+Mono:wght@400;500;600;700&display=swap" rel="stylesheet">
|
||||||
<script src="https://unpkg.com/lightweight-charts@4.2.3/dist/lightweight-charts.standalone.production.js"></script>
|
<script src="https://unpkg.com/lightweight-charts@4.2.3/dist/lightweight-charts.standalone.production.js"></script>
|
||||||
<style>
|
<style>
|
||||||
:root{--bg:#050508;--srf:#0b0b12;--ln:#1f1f30;--hr:#2a2a3c;--tx:#9e9eae;--hi:#e4e4f0;--gr:#22c55e;--rd:#ef4444;--bl:#3b82f6;--am:#f59e0b;--pu:#a855f7;--cy:#06b6d4;--pk:#ec4899;--ra:8px;--f:'Inter',system-ui,sans-serif;--m:'JetBrains Mono',monospace}
|
|
||||||
*{margin:0;padding:0;box-sizing:border-box}
|
/* ═══════════════════ shadcn/ui Design System — Claude Blu 2 Dark ═══════════════════ */
|
||||||
body{background:var(--bg);color:var(--hi);font-family:var(--f);min-height:100vh;-webkit-font-smoothing:antialiased}
|
:root {
|
||||||
.topbar{position:sticky;top:0;z-index:100;background:rgba(5,5,8,.95);backdrop-filter:blur(20px);border-bottom:1px solid var(--ln);padding:12px 24px;display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:12px}
|
/* shadcn semantic tokens */
|
||||||
.topbar h1{font-size:17px;font-weight:700;letter-spacing:-0.5px;display:flex;align-items:center;gap:8px}
|
--background: oklch(0.1776 0 0);
|
||||||
.topbar h1 span{font-size:10px;color:var(--tx);font-weight:400}
|
--foreground: oklch(0.7905 0.0126 259.8241);
|
||||||
.status-dot{width:8px;height:8px;border-radius:50%;flex-shrink:0;background:var(--gr);animation:pulse 2s infinite}
|
--card: oklch(0.2638 0.0024 247.9155);
|
||||||
.status-dot.off{background:var(--rd);animation:none}
|
--card-foreground: oklch(0.9755 0.0045 258.3245);
|
||||||
@keyframes pulse{0%,100%{opacity:1}50%{opacity:0.3}}
|
--popover: oklch(0.3046 0.0023 247.9001);
|
||||||
.tabs{display:flex;gap:0;padding:0 24px;border-bottom:1px solid var(--ln);position:sticky;top:52px;z-index:99;background:rgba(5,5,8,.95);backdrop-filter:blur(20px)}
|
--popover-foreground: oklch(0.9176 0.0026 228.7865);
|
||||||
.tab{padding:10px 20px;font-size:12px;font-weight:500;cursor:pointer;background:none;border:none;border-bottom:2px solid transparent;color:var(--tx);font-family:var(--f);transition:all .15s}
|
--primary: oklch(0.6576 0.1208 252.0832);
|
||||||
.tab:hover{color:var(--hi)}.tab.on{color:var(--hi);border-bottom-color:var(--bl)}
|
--primary-foreground: oklch(1 0 0);
|
||||||
.badge{font-size:8px;padding:2px 7px;border-radius:3px;font-weight:600;margin-left:6px;text-transform:uppercase;letter-spacing:.5px}
|
--secondary: oklch(0.2171 0.0025 247.9411);
|
||||||
.badge.test{background:rgba(245,158,11,.15);color:var(--am)}.badge.main{background:rgba(168,85,247,.15);color:var(--pu)}
|
--secondary-foreground: oklch(0.7559 0.0125 239.9659);
|
||||||
.main-wrap{max-width:1440px;margin:0 auto;padding:20px 24px;display:flex;gap:20px}
|
--muted: oklch(0.2171 0.0025 247.9411);
|
||||||
.panel{display:none;flex:1;min-width:0}.panel.show{display:block}
|
--muted-foreground: oklch(0.7559 0.0125 239.9659);
|
||||||
.sgrid{display:grid;grid-template-columns:repeat(auto-fill,minmax(280px,1fr));gap:10px;margin-bottom:20px}
|
--accent: oklch(0.2038 0.0067 258.3676);
|
||||||
.scard{background:var(--srf);border:1px solid var(--ln);border-radius:var(--ra);padding:16px;cursor:pointer;transition:all .2s;position:relative}
|
--accent-foreground: oklch(0.9590 0.0059 239.8204);
|
||||||
.scard:hover{border-color:var(--hr);transform:translateY(-1px);box-shadow:0 4px 20px rgba(0,0,0,.3)}
|
--destructive: oklch(0.6368 0.2078 25.3313);
|
||||||
.scard.selected{border-color:var(--bl);box-shadow:0 0 0 1px rgba(59,130,246,.3)}
|
--destructive-foreground: oklch(1 0 0);
|
||||||
.scard .sh{display:flex;justify-content:space-between;align-items:flex-start;margin-bottom:8px}
|
--border: oklch(0.3506 0.0066 248.0169);
|
||||||
.scard .sname{font-size:12px;font-weight:600;line-height:1.3;max-width:70%}
|
--input: oklch(0.4217 0.0084 248.0280);
|
||||||
.scard .salloc{font-size:9px;color:var(--tx);margin-top:2px}
|
--ring: oklch(0.6576 0.1208 252.0832);
|
||||||
.scard .stag{font-size:8px;padding:2px 7px;border-radius:3px;font-weight:500;white-space:nowrap}
|
|
||||||
.scard .stag.run{background:rgba(34,197,94,.1);color:var(--gr)}
|
/* Chart palette */
|
||||||
.scard .stag.idle{background:rgba(245,158,11,.1);color:var(--am)}
|
--chart-1: oklch(0.5098 0.1320 257.5458);
|
||||||
.scard .stag.maker{background:rgba(59,130,246,.1);color:var(--bl)}
|
--chart-2: oklch(0.7360 0.1191 266.5038);
|
||||||
.scard .stag.taker{background:rgba(239,68,68,.1);color:var(--rd)}
|
--chart-3: oklch(0.2038 0.0067 258.3676);
|
||||||
.scard .spnl{font-family:var(--m);font-size:20px;font-weight:700;margin-bottom:6px}
|
--chart-4: oklch(0.3361 0.0333 253.9085);
|
||||||
.scard .spnl.up{color:var(--gr)}.scard .spnl.dn{color:var(--rd)}
|
--chart-5: oklch(0.4893 0.1504 261.9302);
|
||||||
.scard .smeta{display:flex;gap:12px;font-size:9px;color:var(--tx);flex-wrap:wrap;margin-bottom:6px}
|
|
||||||
.scard .srisk{font-size:9px;color:var(--tx);padding:6px 8px;background:rgba(0,0,0,.2);border-radius:4px;margin-top:4px;line-height:1.6}
|
/* Semantic layer scale */
|
||||||
.scard .srisk b{color:var(--hi)}
|
--layer-0: var(--background);
|
||||||
.detail-overlay{position:fixed;top:0;left:0;right:0;bottom:0;background:rgba(0,0,0,.6);z-index:200;display:none}
|
--layer-1: color-mix(in oklch, var(--card) 50%, var(--background));
|
||||||
.detail-overlay.on{display:flex;align-items:flex-start;justify-content:center;padding-top:40px}
|
--layer-2: var(--card);
|
||||||
.detail-panel{background:var(--bg);border:1px solid var(--ln);border-radius:12px;width:95%;max-width:1100px;max-height:85vh;overflow-y:auto;box-shadow:0 20px 60px rgba(0,0,0,.5)}
|
--layer-3: var(--popover);
|
||||||
.detail-header{position:sticky;top:0;background:var(--srf);padding:16px 20px;border-bottom:1px solid var(--ln);display:flex;align-items:center;justify-content:space-between;z-index:5}
|
|
||||||
.detail-header h2{font-size:16px;font-weight:700}
|
/* Old var name mappings (backward compat) */
|
||||||
.close-btn{background:none;border:1px solid var(--ln);color:var(--hi);padding:6px 14px;border-radius:6px;cursor:pointer;font-size:12px;font-family:var(--f);transition:all .15s}
|
--bg: var(--background);
|
||||||
.close-btn:hover{background:var(--hr)}
|
--srf: var(--card);
|
||||||
.detail-body{padding:20px}
|
--ln: var(--border);
|
||||||
.detail-body .chart-wrap{width:100%;height:280px;margin-bottom:16px;border-radius:var(--ra);overflow:hidden}
|
--hr: color-mix(in oklch, var(--border) 70%, transparent);
|
||||||
.detail-stats{display:grid;grid-template-columns:repeat(6,1fr);gap:8px;margin-bottom:16px}
|
--tx: var(--muted-foreground);
|
||||||
.detail-section{margin-bottom:20px}
|
--hi: var(--foreground);
|
||||||
.detail-section h4{font-size:11px;font-weight:600;color:var(--tx);text-transform:uppercase;letter-spacing:.5px;margin-bottom:10px;padding-bottom:6px;border-bottom:1px solid var(--ln)}
|
--bl: var(--primary);
|
||||||
.trade-table{width:100%;border-collapse:collapse;font-family:var(--m)}
|
--rd: var(--destructive);
|
||||||
.trade-table th{font-size:9px;font-weight:600;color:var(--tx);text-transform:uppercase;text-align:left;padding:8px 10px;border-bottom:1px solid var(--ln)}
|
--gr: oklch(0.7057 0.1946 143.1487); /* green */
|
||||||
.trade-table td{font-size:11px;padding:7px 10px;border-bottom:1px solid rgba(255,255,255,.02);color:var(--hi)}
|
--am: oklch(0.7610 0.1858 70.0831); /* amber */
|
||||||
.trade-table td.reason{font-size:10px;color:var(--tx);max-width:250px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;font-family:var(--f)}
|
--pu: oklch(0.6197 0.1996 312.7621); /* purple */
|
||||||
.green{color:var(--gr)}.red{color:var(--rd)}
|
--cy: oklch(0.7150 0.1250 197.2349); /* cyan */
|
||||||
.desc-text{font-size:12px;color:var(--tx);line-height:1.6;padding:12px;background:var(--srf);border-radius:var(--ra);border:1px solid var(--ln);margin-bottom:16px}
|
--pk: oklch(0.6686 0.2158 0.7958); /* pink */
|
||||||
.stat{background:var(--srf);border:1px solid var(--ln);border-radius:var(--ra);padding:12px 14px}
|
|
||||||
.stat .lbl{font-size:9px;color:var(--tx);text-transform:uppercase;letter-spacing:.5px;margin-bottom:3px}
|
/* Typography */
|
||||||
.stat .val{font-family:var(--m);font-size:17px;font-weight:600}
|
--radius: 0.5rem;
|
||||||
.stat .val.up{color:var(--gr)}.stat .val.dn{color:var(--rd)}
|
--radius-sm: calc(var(--radius) - 0.125rem);
|
||||||
footer{text-align:center;padding:30px;font-size:10px;color:#2a2a35}
|
--radius-lg: calc(var(--radius) + 0.125rem);
|
||||||
footer a{color:#3f3f4a;text-decoration:none}footer a:hover{color:var(--tx)}
|
--font-sans: 'Inter', system-ui, -apple-system, sans-serif;
|
||||||
.risk-wrap{max-width:1440px;margin:0 auto 20px;padding:0 24px}
|
--font-mono: 'JetBrains Mono', ui-monospace, monospace;
|
||||||
.risk-toggle{display:flex;align-items:center;gap:8px;cursor:pointer;background:none;border:1px solid var(--ln);border-radius:var(--ra);color:var(--tx);font-family:var(--f);font-size:11px;font-weight:600;padding:10px 16px;text-transform:uppercase;letter-spacing:.5px;transition:all .15s}
|
--f: var(--font-sans);
|
||||||
.risk-toggle:hover{color:var(--hi);border-color:var(--hr)}
|
--m: var(--font-mono);
|
||||||
.risk-toggle .arrow{display:inline-block;transition:transform .2s;font-size:10px}
|
--ra: var(--radius);
|
||||||
.risk-toggle.open .arrow{transform:rotate(90deg)}
|
|
||||||
.risk-panel{display:none;background:var(--srf);border:1px solid var(--ln);border-radius:var(--ra);padding:16px;margin-top:8px}
|
/* Shadows (dark) */
|
||||||
.risk-panel.show{display:block}
|
--shadow-2xs: 0 1px 2px 0 hsl(0 0% 0% / 0.15);
|
||||||
@media(max-width:768px){
|
--shadow-xs: 0 1px 2px 0 hsl(0 0% 0% / 0.15);
|
||||||
.topbar{padding:10px 14px;flex-direction:column;align-items:flex-start}
|
--shadow-sm: 0 1px 3px 0 hsl(0 0% 0% / 0.30), 0 1px 2px -1px hsl(0 0% 0% / 0.30);
|
||||||
.tabs{padding:0 14px;top:88px;overflow-x:auto;white-space:nowrap}
|
--shadow: 0 1px 3px 0 hsl(0 0% 0% / 0.30), 0 1px 2px -1px hsl(0 0% 0% / 0.30);
|
||||||
.main-wrap{padding:12px 14px}
|
--shadow-md: 0 4px 6px -1px hsl(0 0% 0% / 0.30), 0 2px 4px -2px hsl(0 0% 0% / 0.30);
|
||||||
.sgrid{grid-template-columns:1fr 1fr}
|
--shadow-lg: 0 10px 15px -3px hsl(0 0% 0% / 0.30), 0 4px 6px -4px hsl(0 0% 0% / 0.30);
|
||||||
.detail-stats{grid-template-columns:repeat(3,1fr)}
|
--shadow-xl: 0 20px 25px -5px hsl(0 0% 0% / 0.30), 0 8px 10px -6px hsl(0 0% 0% / 0.30);
|
||||||
}
|
}
|
||||||
@media(max-width:380px){.sgrid{grid-template-columns:1fr}}
|
|
||||||
|
/* ═══════════════════ Base ═══════════════════ */
|
||||||
|
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||||||
|
body {
|
||||||
|
background: var(--background);
|
||||||
|
color: var(--foreground);
|
||||||
|
font-family: var(--font-sans);
|
||||||
|
min-height: 100vh;
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
-moz-osx-font-smoothing: grayscale;
|
||||||
|
font-feature-settings: "cv02","cv03","cv04","cv11";
|
||||||
|
}
|
||||||
|
::selection { background: color-mix(in oklch, var(--primary) 30%, transparent); }
|
||||||
|
|
||||||
|
/* ═══════════════════ Topbar ═══════════════════ */
|
||||||
|
.topbar {
|
||||||
|
position: sticky; top: 0; z-index: 100;
|
||||||
|
background: color-mix(in oklch, var(--background) 95%, transparent);
|
||||||
|
backdrop-filter: blur(24px); -webkit-backdrop-filter: blur(24px);
|
||||||
|
border-bottom: 1px solid var(--border);
|
||||||
|
padding: 12px 24px;
|
||||||
|
display: flex; align-items: center; justify-content: space-between;
|
||||||
|
flex-wrap: wrap; gap: 12px;
|
||||||
|
}
|
||||||
|
.topbar h1 {
|
||||||
|
font-size: 15px; font-weight: 700; letter-spacing: -0.02em;
|
||||||
|
display: flex; align-items: center; gap: 10px;
|
||||||
|
}
|
||||||
|
.topbar h1 span { font-size: 10px; color: var(--muted-foreground); font-weight: 500; }
|
||||||
|
.status-dot {
|
||||||
|
width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0;
|
||||||
|
background: var(--gr); animation: pulse 2s infinite;
|
||||||
|
}
|
||||||
|
.status-dot.off { background: var(--destructive); animation: none; }
|
||||||
|
@keyframes pulse { 0%,100% { opacity: 1; } 50% { opacity: 0.3; } }
|
||||||
|
|
||||||
|
/* ═══════════════════ Tabs ═══════════════════ */
|
||||||
|
.tabs {
|
||||||
|
display: flex; gap: 0; padding: 0 24px;
|
||||||
|
border-bottom: 1px solid var(--border);
|
||||||
|
position: sticky; top: 52px; z-index: 99;
|
||||||
|
background: color-mix(in oklch, var(--background) 95%, transparent);
|
||||||
|
backdrop-filter: blur(24px); -webkit-backdrop-filter: blur(24px);
|
||||||
|
}
|
||||||
|
.tab {
|
||||||
|
padding: 10px 20px; font-size: 12px; font-weight: 500; cursor: pointer;
|
||||||
|
background: none; border: none; border-bottom: 2px solid transparent;
|
||||||
|
color: var(--muted-foreground); font-family: var(--font-sans);
|
||||||
|
transition: all .15s ease;
|
||||||
|
}
|
||||||
|
.tab:hover { color: var(--foreground); }
|
||||||
|
.tab.on { color: var(--foreground); border-bottom-color: var(--primary); }
|
||||||
|
.badge {
|
||||||
|
font-size: 8px; padding: 2px 7px; border-radius: var(--radius-sm);
|
||||||
|
font-weight: 600; margin-left: 6px; text-transform: uppercase; letter-spacing: .5px;
|
||||||
|
}
|
||||||
|
.badge.test { background: color-mix(in oklch, var(--am) 15%, transparent); color: var(--am); }
|
||||||
|
.badge.main { background: color-mix(in oklch, var(--pu) 15%, transparent); color: var(--pu); }
|
||||||
|
|
||||||
|
/* ═══════════════════ Layout ═══════════════════ */
|
||||||
|
.main-wrap { max-width: 1440px; margin: 0 auto; padding: 24px 24px; }
|
||||||
|
.panel { display: none; }
|
||||||
|
.panel.show { display: block; }
|
||||||
|
|
||||||
|
/* ═══════════════════ Strategy Grid ═══════════════════ */
|
||||||
|
.sgrid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
|
||||||
|
gap: 12px; margin-bottom: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ═══════════════════ shadcn-style Card ═══════════════════ */
|
||||||
|
.scard {
|
||||||
|
background: var(--card);
|
||||||
|
border: 1px solid var(--border);
|
||||||
|
border-radius: var(--radius-lg);
|
||||||
|
padding: 18px 20px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all .2s ease;
|
||||||
|
position: relative;
|
||||||
|
box-shadow: var(--shadow-2xs);
|
||||||
|
}
|
||||||
|
.scard:hover {
|
||||||
|
border-color: var(--ring);
|
||||||
|
transform: translateY(-1px);
|
||||||
|
box-shadow: var(--shadow-md);
|
||||||
|
}
|
||||||
|
.scard.selected {
|
||||||
|
border-color: var(--primary);
|
||||||
|
box-shadow: 0 0 0 1px color-mix(in oklch, var(--primary) 40%, transparent);
|
||||||
|
}
|
||||||
|
.scard .sh {
|
||||||
|
display: flex; justify-content: space-between; align-items: flex-start;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
.scard .sname { font-size: 13px; font-weight: 600; line-height: 1.3; max-width: 70%; }
|
||||||
|
.scard .salloc { font-size: 9px; color: var(--muted-foreground); margin-top: 3px; }
|
||||||
|
.scard .stag {
|
||||||
|
font-size: 8px; padding: 3px 8px; border-radius: var(--radius-sm);
|
||||||
|
font-weight: 500; white-space: nowrap;
|
||||||
|
}
|
||||||
|
.scard .stag.run { background: color-mix(in oklch, var(--gr) 12%, transparent); color: var(--gr); }
|
||||||
|
.scard .stag.idle { background: color-mix(in oklch, var(--am) 12%, transparent); color: var(--am); }
|
||||||
|
.scard .stag.maker { background: color-mix(in oklch, var(--primary) 12%, transparent); color: var(--primary); }
|
||||||
|
.scard .stag.taker { background: color-mix(in oklch, var(--destructive) 12%, transparent); color: var(--destructive); }
|
||||||
|
.scard .spnl {
|
||||||
|
font-family: var(--font-mono); font-size: 22px; font-weight: 700;
|
||||||
|
margin-bottom: 8px; letter-spacing: -0.02em;
|
||||||
|
}
|
||||||
|
.scard .spnl.up { color: var(--gr); }
|
||||||
|
.scard .spnl.dn { color: var(--destructive); }
|
||||||
|
.scard .smeta {
|
||||||
|
display: flex; gap: 14px; font-size: 9px; color: var(--muted-foreground);
|
||||||
|
flex-wrap: wrap; margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
.scard .srisk {
|
||||||
|
font-size: 9px; color: var(--muted-foreground);
|
||||||
|
padding: 8px 10px;
|
||||||
|
background: color-mix(in oklch, var(--muted) 50%, transparent);
|
||||||
|
border-radius: var(--radius-sm);
|
||||||
|
margin-top: 6px; line-height: 1.7;
|
||||||
|
}
|
||||||
|
.scard .srisk b { color: var(--foreground); font-weight: 600; }
|
||||||
|
|
||||||
|
/* ═══════════════════ Stats (detail & rows) ═══════════════════ */
|
||||||
|
.stats-row {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
|
||||||
|
gap: 8px; margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
.stat {
|
||||||
|
background: color-mix(in oklch, var(--card) 60%, var(--background));
|
||||||
|
border: 1px solid var(--border);
|
||||||
|
border-radius: var(--radius);
|
||||||
|
padding: 14px 16px;
|
||||||
|
}
|
||||||
|
.stat .lbl {
|
||||||
|
font-size: 9px; color: var(--muted-foreground);
|
||||||
|
text-transform: uppercase; letter-spacing: 0.05em; margin-bottom: 4px;
|
||||||
|
}
|
||||||
|
.stat .val {
|
||||||
|
font-family: var(--font-mono); font-size: 17px; font-weight: 600;
|
||||||
|
}
|
||||||
|
.stat .val.up { color: var(--gr); }
|
||||||
|
.stat .val.dn { color: var(--destructive); }
|
||||||
|
|
||||||
|
/* ═══════════════════ Detail Overlay ═══════════════════ */
|
||||||
|
.detail-overlay {
|
||||||
|
position: fixed; top: 0; left: 0; right: 0; bottom: 0;
|
||||||
|
background: oklch(0 0 0 / 0.65); z-index: 200; display: none;
|
||||||
|
backdrop-filter: blur(4px); -webkit-backdrop-filter: blur(4px);
|
||||||
|
}
|
||||||
|
.detail-overlay.on {
|
||||||
|
display: flex; align-items: flex-start; justify-content: center;
|
||||||
|
padding-top: 40px;
|
||||||
|
}
|
||||||
|
.detail-panel {
|
||||||
|
background: var(--layer-0);
|
||||||
|
border: 1px solid var(--border);
|
||||||
|
border-radius: var(--radius-lg);
|
||||||
|
width: 95%; max-width: 1100px; max-height: 85vh;
|
||||||
|
overflow-y: auto;
|
||||||
|
box-shadow: var(--shadow-xl);
|
||||||
|
}
|
||||||
|
.detail-header {
|
||||||
|
position: sticky; top: 0;
|
||||||
|
background: color-mix(in oklch, var(--card) 80%, var(--background));
|
||||||
|
backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px);
|
||||||
|
padding: 16px 20px; border-bottom: 1px solid var(--border);
|
||||||
|
display: flex; align-items: center; justify-content: space-between; z-index: 5;
|
||||||
|
}
|
||||||
|
.detail-header h2 { font-size: 16px; font-weight: 700; }
|
||||||
|
.close-btn {
|
||||||
|
background: none; border: 1px solid var(--border);
|
||||||
|
color: var(--foreground); padding: 6px 14px; border-radius: var(--radius);
|
||||||
|
cursor: pointer; font-size: 12px; font-family: var(--font-sans);
|
||||||
|
transition: all .15s;
|
||||||
|
}
|
||||||
|
.close-btn:hover { background: var(--accent); color: var(--accent-foreground); }
|
||||||
|
.detail-body { padding: 20px; }
|
||||||
|
.detail-body .chart-wrap {
|
||||||
|
width: 100%; height: 280px; margin-bottom: 16px;
|
||||||
|
border-radius: var(--radius); overflow: hidden;
|
||||||
|
background: color-mix(in oklch, var(--muted) 40%, transparent);
|
||||||
|
}
|
||||||
|
.detail-stats {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
|
||||||
|
gap: 8px; margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
.detail-section { margin-bottom: 20px; }
|
||||||
|
.detail-section h4 {
|
||||||
|
font-size: 10px; font-weight: 600; color: var(--muted-foreground);
|
||||||
|
text-transform: uppercase; letter-spacing: 0.05em;
|
||||||
|
margin-bottom: 10px; padding-bottom: 6px;
|
||||||
|
border-bottom: 1px solid var(--border);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ═══════════════════ Trade Table ═══════════════════ */
|
||||||
|
.trade-table { width: 100%; border-collapse: collapse; font-family: var(--font-mono); }
|
||||||
|
.trade-table th {
|
||||||
|
font-size: 9px; font-weight: 600; color: var(--muted-foreground);
|
||||||
|
text-transform: uppercase; text-align: left;
|
||||||
|
padding: 8px 10px; border-bottom: 1px solid var(--border);
|
||||||
|
}
|
||||||
|
.trade-table td {
|
||||||
|
font-size: 11px; padding: 7px 10px;
|
||||||
|
border-bottom: 1px solid color-mix(in oklch, var(--border) 30%, transparent);
|
||||||
|
color: var(--foreground);
|
||||||
|
}
|
||||||
|
.trade-table td.reason {
|
||||||
|
font-size: 10px; color: var(--muted-foreground);
|
||||||
|
max-width: 250px; white-space: nowrap; overflow: hidden;
|
||||||
|
text-overflow: ellipsis; font-family: var(--font-sans);
|
||||||
|
}
|
||||||
|
.green { color: var(--gr); }
|
||||||
|
.red { color: var(--destructive); }
|
||||||
|
|
||||||
|
/* ═══════════════════ Description ═══════════════════ */
|
||||||
|
.desc-text {
|
||||||
|
font-size: 12px; color: var(--muted-foreground); line-height: 1.7;
|
||||||
|
padding: 14px; background: color-mix(in oklch, var(--muted) 60%, transparent);
|
||||||
|
border-radius: var(--radius); border: 1px solid var(--border);
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ═══════════════════ Collapsible Panels (Risk, Positions) ═══════════════════ */
|
||||||
|
.risk-wrap { max-width: 1440px; margin: 0 auto 20px; padding: 0 24px; }
|
||||||
|
.risk-toggle {
|
||||||
|
display: flex; align-items: center; gap: 8px; cursor: pointer;
|
||||||
|
background: none; border: 1px solid var(--border);
|
||||||
|
border-radius: var(--radius); color: var(--muted-foreground);
|
||||||
|
font-family: var(--font-sans); font-size: 11px; font-weight: 600;
|
||||||
|
padding: 10px 16px; text-transform: uppercase; letter-spacing: .5px;
|
||||||
|
transition: all .15s;
|
||||||
|
}
|
||||||
|
.risk-toggle:hover { color: var(--foreground); border-color: var(--ring); }
|
||||||
|
.risk-toggle .arrow { display: inline-block; transition: transform .2s; font-size: 10px; }
|
||||||
|
.risk-toggle.open .arrow { transform: rotate(90deg); }
|
||||||
|
.risk-panel {
|
||||||
|
display: none;
|
||||||
|
background: var(--card);
|
||||||
|
border: 1px solid var(--border);
|
||||||
|
border-radius: var(--radius);
|
||||||
|
padding: 16px; margin-top: 8px;
|
||||||
|
}
|
||||||
|
.risk-panel.show { display: block; }
|
||||||
|
|
||||||
|
/* ═══════════════════ Footer ═══════════════════ */
|
||||||
|
footer { text-align: center; padding: 30px; font-size: 10px; color: var(--muted-foreground); }
|
||||||
|
footer a { color: var(--muted-foreground); text-decoration: none; }
|
||||||
|
footer a:hover { color: var(--primary); }
|
||||||
|
|
||||||
|
/* ═══════════════════ Select / Input Overrides ═══════════════════ */
|
||||||
|
select {
|
||||||
|
background: var(--card); color: var(--foreground);
|
||||||
|
border: 1px solid var(--border);
|
||||||
|
border-radius: var(--radius-sm); padding: 4px 8px;
|
||||||
|
font-family: var(--font-sans);
|
||||||
|
}
|
||||||
|
select:focus { outline: none; border-color: var(--ring); box-shadow: 0 0 0 2px color-mix(in oklch, var(--ring) 20%, transparent); }
|
||||||
|
|
||||||
|
/* ═══════════════════ Scrollbar ═══════════════════ */
|
||||||
|
::-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(--input); }
|
||||||
|
|
||||||
|
/* ═══════════════════ Responsive ═══════════════════ */
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.topbar { padding: 10px 14px; flex-direction: column; align-items: flex-start; }
|
||||||
|
.tabs { padding: 0 14px; top: 88px; overflow-x: auto; white-space: nowrap; }
|
||||||
|
.main-wrap { padding: 14px 14px; }
|
||||||
|
.sgrid { grid-template-columns: 1fr 1fr; }
|
||||||
|
.detail-stats { grid-template-columns: 1fr 1fr 1fr; }
|
||||||
|
.stats-row { grid-template-columns: 1fr 1fr 1fr; }
|
||||||
|
}
|
||||||
|
@media (max-width: 380px) {
|
||||||
|
.sgrid { grid-template-columns: 1fr; }
|
||||||
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
@@ -86,7 +366,7 @@ footer a{color:#3f3f4a;text-decoration:none}footer a:hover{color:var(--tx)}
|
|||||||
<div style="display:flex;align-items:center;gap:10px">
|
<div style="display:flex;align-items:center;gap:10px">
|
||||||
<span class="status-dot" id="sdot"></span><div><h1>FTDT Quant Lab<span>Per-Strategy Dashboard</span></h1></div>
|
<span class="status-dot" id="sdot"></span><div><h1>FTDT Quant Lab<span>Per-Strategy Dashboard</span></h1></div>
|
||||||
</div>
|
</div>
|
||||||
<div style="font-size:10px;color:var(--tx)" id="stsub">—</div>
|
<div style="font-size:10px;color:var(--muted-foreground)" id="stsub">—</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="tabs">
|
<div class="tabs">
|
||||||
<button class="tab on" id="tl-live" onclick="switchTab('live')">Live<span class="badge test">Testnet</span></button>
|
<button class="tab on" id="tl-live" onclick="switchTab('live')">Live<span class="badge test">Testnet</span></button>
|
||||||
@@ -103,11 +383,11 @@ footer a{color:#3f3f4a;text-decoration:none}footer a:hover{color:var(--tx)}
|
|||||||
<div class="risk-wrap">
|
<div class="risk-wrap">
|
||||||
<button class="risk-toggle" onclick="togglePositions()" id="pos-btn"><span class="arrow">▶</span> Open Positions & Orders (All Strategies)</button>
|
<button class="risk-toggle" onclick="togglePositions()" id="pos-btn"><span class="arrow">▶</span> Open Positions & Orders (All Strategies)</button>
|
||||||
<div class="risk-panel" id="pos-panel">
|
<div class="risk-panel" id="pos-panel">
|
||||||
<div class="detail-stats" id="pos-positions" style="font-size:11px;color:var(--tx)">No open positions</div>
|
<div class="detail-stats" id="pos-positions" style="font-size:11px;color:var(--muted-foreground)">No open positions</div>
|
||||||
<div style="font-size:11px;color:var(--tx)" id="pos-orders">No open orders</div>
|
<div style="font-size:11px;color:var(--muted-foreground)" id="pos-orders">No open orders</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<footer><a href="https://git.ftdt.io/rams/ftdt-quant-lab" target="_blank">rams/ftdt-quant-lab</a> · 12 strategies · $100K paper · Hyperliquid</footer>
|
<footer><a href="https://git.ftdt.io/rams/ftdt-quant-lab" target="_blank">rams/ftdt-quant-lab</a> · 12 strategies · $100K paper · Hyperliquid</footer>
|
||||||
<div class="detail-overlay" id="detail-overlay" onclick="if(event.target===this)closeDetail()">
|
<div class="detail-overlay" id="detail-overlay" onclick="if(event.target===this)closeDetail()">
|
||||||
<div class="detail-panel" id="detail-panel">
|
<div class="detail-panel" id="detail-panel">
|
||||||
<div class="detail-header">
|
<div class="detail-header">
|
||||||
@@ -390,5 +670,6 @@ function togglePositions(){
|
|||||||
initDetChart();connect();loadBT();loadHistBT();
|
initDetChart();connect();loadBT();loadHistBT();
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
Reference in New Issue
Block a user