diff --git a/frontend/src/styles/tokens.css b/frontend/src/styles/tokens.css index d97151f..015cb07 100644 --- a/frontend/src/styles/tokens.css +++ b/frontend/src/styles/tokens.css @@ -20,6 +20,9 @@ --cyan-dim: #00b8cc; /* 暗青(hover/次要激活) */ --cyan-soft: rgba(0, 229, 255, 0.14); /* 青色填充底 */ + /* —— 次强调:紫(alpha158)—— */ + --purple-dim: #b48cff; /* alpha158 类别色 */ + /* —— 数据高亮:琥珀 —— */ --amber: #ffb000; /* 数据高亮/警告 */ --warn: #ffb000; /* 语义别名 */ diff --git a/frontend/src/views/factor/Leaderboard.vue b/frontend/src/views/factor/Leaderboard.vue index ea0a4b0..6793424 100644 --- a/frontend/src/views/factor/Leaderboard.vue +++ b/frontend/src/views/factor/Leaderboard.vue @@ -269,14 +269,14 @@ onMounted(async () => { } .btn.primary { - color: #04141a; + color: var(--text); background: var(--brand); border-color: var(--brand); box-shadow: var(--glow-cyan); } .btn.primary:hover { - background: #33ecff; + background: var(--cyan-dim); } .stats { @@ -572,7 +572,7 @@ td .fexpr { } .cat-alpha158 { - color: #b48cff; + color: var(--purple-dim); background: rgba(180, 140, 255, 0.1); border-color: rgba(180, 140, 255, 0.3); } diff --git a/frontend/src/views/factor/LeaderboardDetail.vue b/frontend/src/views/factor/LeaderboardDetail.vue index 2719fab..fe94898 100644 --- a/frontend/src/views/factor/LeaderboardDetail.vue +++ b/frontend/src/views/factor/LeaderboardDetail.vue @@ -1,28 +1,313 @@ @@ -47,6 +332,15 @@ function goBack() { text-underline-offset: 3px; } +.error-state { + padding: 60px; + text-align: center; + color: var(--text-3); + background: var(--bg-card); + border: 1px solid var(--border); + border-radius: var(--r-lg); +} + .page-head { display: flex; align-items: flex-end; @@ -71,12 +365,282 @@ function goBack() { letter-spacing: 0.02em; } -.placeholder { - padding: 60px; - text-align: center; - color: var(--text-3); +.fcard { background: var(--bg-card); border: 1px solid var(--border); border-radius: var(--r-lg); + padding: 16px 18px; + margin-bottom: var(--sp-3); +} + +.fcard .hd { + display: flex; + align-items: center; + gap: 10px; + margin-bottom: 10px; + flex-wrap: wrap; +} + +.fcard .name { + font-family: var(--mono); + font-size: 17px; + font-weight: 700; + color: var(--brand); + letter-spacing: 0.03em; +} + +.expr { + font-family: var(--mono); + font-size: 11.5px; + line-height: 1.7; + background: var(--panel); + border: 1px solid var(--border-2); + border-left: 2px solid var(--cyan-dim); + border-radius: var(--r-sm); + padding: 11px 14px; + color: var(--text-2); + overflow-x: auto; + white-space: pre; + position: relative; +} + +.expr:not(.expanded) { + max-height: 80px; + overflow: hidden; + mask-image: linear-gradient(to bottom, black 60%, transparent 100%); + -webkit-mask-image: linear-gradient(to bottom, black 60%, transparent 100%); +} + +.expr.expanded { + mask-image: none; + -webkit-mask-image: none; +} + +.expr-toggle { + position: absolute; + bottom: 8px; + right: 12px; + font-size: 10px; + color: var(--brand); + background: rgba(0, 229, 255, 0.1); + border: 1px solid rgba(0, 229, 255, 0.3); + border-radius: var(--r-sm); + padding: 2px 8px; + cursor: pointer; + transition: all 0.15s var(--ease); +} + +.expr-toggle:hover { + background: rgba(0, 229, 255, 0.2); +} + +.metric-strip { + display: grid; + grid-template-columns: repeat(6, 1fr); + gap: 1px; + background: var(--border); + border: 1px solid var(--border); + border-radius: var(--r-lg); + overflow: hidden; + margin-bottom: var(--sp-3); +} + +@media (max-width: 1100px) { + .metric-strip { + grid-template-columns: repeat(3, 1fr); + } +} + +.metric { + background: var(--bg-card); + padding: 11px 13px; +} + +.metric .k { + color: var(--text-3); + font-family: var(--mono); + font-size: 9.5px; + letter-spacing: 0.12em; + text-transform: uppercase; +} + +.metric .v { + font-family: var(--mono); + font-variant-numeric: tabular-nums; + font-size: 18px; + font-weight: 600; + margin-top: 2px; +} + +.metric .d { + font-size: 10px; + margin-top: 2px; + color: var(--text-3); + font-family: var(--mono); +} + +.period-switch { + display: flex; + border: 1px solid var(--border); + border-radius: var(--r-sm); + overflow: hidden; + margin-bottom: var(--sp-3); +} + +.period-switch button { + font-family: var(--mono); + font-size: 11px; + padding: 4px 12px; + color: var(--text-2); + background: transparent; + border: none; + cursor: pointer; +} + +.period-switch button.on { + background: rgba(0, 229, 255, 0.12); + color: var(--brand); +} + +.charts { + display: grid; + grid-template-columns: 3fr 2fr; + gap: var(--sp-3); + margin-bottom: var(--sp-3); +} + +@media (max-width: 1100px) { + .charts { + grid-template-columns: 1fr; + } +} + +.chart-card { + background: var(--bg-card); + border: 1px solid var(--border); + border-radius: var(--r-lg); + padding: 14px 16px; +} + +.chart-card h3 { + font-size: 12.5px; + font-weight: 600; + letter-spacing: 0.04em; + margin-bottom: 4px; +} + +.chart-card .cs { + color: var(--text-3); + font-family: var(--mono); + font-size: 10.5px; + margin-bottom: 10px; +} + +.chart-box { + width: 100%; + height: 215px; +} + +.actions { + display: flex; + gap: 10px; +} + +.btn { + font-size: 12.5px; + font-weight: 600; + border-radius: var(--r-md); + padding: 7px 16px; + border: 1px solid var(--border); + color: var(--text-2); + background: var(--bg-card); + transition: all 0.15s var(--ease); + cursor: pointer; +} + +.btn:hover { + color: var(--text); + border-color: var(--text-3); +} + +.btn.primary { + color: var(--text); + background: var(--brand); + border-color: var(--brand); + box-shadow: var(--glow-cyan); +} + +.btn.primary:hover { + background: var(--cyan-dim); +} + +.cat-chip { + display: inline-block; + padding: 1px 8px; + border-radius: var(--r-sm); + font-family: var(--mono); + font-size: 10.5px; + font-weight: 600; + line-height: 17px; + letter-spacing: 0.3px; + border: 1px solid transparent; +} + +.cat-alpha101 { + color: var(--brand); + background: rgba(0, 229, 255, 0.1); + border-color: rgba(0, 229, 255, 0.3); +} + +.cat-alpha158 { + color: var(--purple-dim); + background: rgba(180, 140, 255, 0.1); + border-color: rgba(180, 140, 255, 0.3); +} + +.cat-builtin { + color: var(--amber); + background: rgba(255, 176, 0, 0.1); + border-color: rgba(255, 176, 0, 0.3); +} + +.st { + display: inline-flex; + align-items: center; + gap: 5px; + font-family: var(--mono); + font-size: 10.5px; + letter-spacing: 0.08em; +} + +.st-ok .lamp { + background: var(--lamp-ok); + box-shadow: 0 0 6px rgba(46, 230, 138, 0.7); +} + +.st-watch .lamp { + background: var(--lamp-warn); + box-shadow: 0 0 6px rgba(255, 176, 0, 0.7); +} + +.st-eliminated .lamp { + background: var(--lamp-idle); + box-shadow: none; +} + +.lamp { + width: 7px; + height: 7px; + border-radius: 50%; + display: inline-block; + flex-shrink: 0; +} + +.pos { + color: var(--up); +} + +.neg { + color: var(--down); }