ui: tighten dashboard copy and fix layout issues

This commit is contained in:
k
2026-06-14 21:58:56 +08:00
parent 4c3c8c6f87
commit 8534d90589
19 changed files with 1036 additions and 345 deletions
+53 -26
View File
@@ -128,11 +128,14 @@ function MetricCard({
activeIndex,
chartHref,
chartLabel = 'CoinGlass',
hero = false,
}: {
rank: number
label: string
value: string
tone?: Tone
/** What the indicator IS, one sentence. Do NOT enumerate threshold bands
* here — the chips below each card already list them. */
hint: string
summary: string
thresholds: Array<{ label: string; tone?: Tone }>
@@ -143,31 +146,54 @@ function MetricCard({
* the dual "Data source + Chart" pattern confused users about which to click. */
chartHref: string
chartLabel?: string
/** Horizontal headline layout for a single full-width card (Valuation).
* The stacked layout stretched across the panel left a dead middle. */
hero?: boolean
}) {
const head = (
<div className="macro-metric-head">
<div className="macro-metric-title">
<span className="macro-rank">{String(rank).padStart(2, '0')}</span>
<span>{label}</span>
<InfoTip text={hint} placement="top" width={280} />
</div>
<div className="macro-metric-value">{value}</div>
</div>
)
const chips = (
<div className="macro-thresholds">
{thresholds.map((item, i) => (
<ThresholdChip key={item.label} tone={item.tone} active={i === activeIndex}>
{item.label}
</ThresholdChip>
))}
</div>
)
const action = (
<div className="macro-actions">
<SourceButton href={chartHref}>{chartLabel}</SourceButton>
</div>
)
if (hero) {
return (
<article className={`macro-metric-card tone-${tone} hero`}>
{head}
<div className="macro-hero-body">
<div className="macro-summary">{summary}</div>
{chips}
</div>
{action}
</article>
)
}
return (
<article className={`macro-metric-card tone-${tone}`}>
<div className="macro-metric-head">
<div className="macro-metric-title">
<span className="macro-rank">{String(rank).padStart(2, '0')}</span>
<span>{label}</span>
<InfoTip text={hint} placement="top" width={280} />
</div>
<div className="macro-metric-value">{value}</div>
</div>
{head}
<div className="macro-summary">{summary}</div>
<div className="macro-thresholds">
{thresholds.map((item, i) => (
<ThresholdChip key={item.label} tone={item.tone} active={i === activeIndex}>
{item.label}
</ThresholdChip>
))}
</div>
<div className="macro-actions">
<SourceButton href={chartHref}>{chartLabel}</SourceButton>
</div>
{chips}
{action}
</article>
)
}
@@ -402,11 +428,12 @@ export default function MacroPanel() {
<Section title="Valuation">
<div className="macro-grid one">
<MetricCard
hero
rank={1}
label="AHR999"
value={ind.ahr999?.toFixed(4) ?? '—'}
tone={toneAhr(ind.ahr999)}
hint="BTC valuation index: price vs 200-day geometric mean × price vs fitted long-run growth curve. < 0.45 = buy/accumulation zone, 0.450.75 = fair value leaning cheap, 0.751.2 = neutral / no edge, > 1.2 = expensive."
hint="BTC valuation index: price vs 200-day geometric mean × price vs fitted long-run growth curve. Lower = cheaper."
summary={ahrSay}
activeIndex={ahrActive}
thresholds={[
@@ -457,7 +484,7 @@ export default function MacroPanel() {
label="Altcoin Season"
value={ind.altcoin_season_index == null ? '—' : ind.altcoin_season_index.toFixed(0) + ' / 100'}
tone={toneAltseason(ind.altcoin_season_index)}
hint="% of top-50 alts that beat BTC over the last 90 days (blockchaincenter.net formula). < 25 = Bitcoin season, 2560 = mixed, 6075 = alt strength building, ≥ 75 = altseason."
hint="% of top-50 alts that beat BTC over the last 90 days (blockchaincenter.net formula). Higher = broader alt strength."
summary={altSay}
activeIndex={altActive}
thresholds={[
@@ -474,7 +501,7 @@ export default function MacroPanel() {
label="BTC Dominance"
value={fmtPct(ind.btc_dominance_pct)}
tone={toneBtcDominance(ind.btc_dominance_pct)}
hint="BTC's share of total crypto market cap. < 45% = alt rotation, 4555% = balanced, 5565% = BTC-led / defensive, > 65% = flight to safety."
hint="BTC's share of total crypto market cap. High dominance = defensive, capital hiding in BTC; low = alt rotation."
summary={domSay}
activeIndex={domActive}
thresholds={[
@@ -491,7 +518,7 @@ export default function MacroPanel() {
label="ETH / BTC"
value={ind.eth_btc_ratio == null ? '—' : ind.eth_btc_ratio.toFixed(5)}
tone={toneEthBtc(ind.eth_btc_ratio)}
hint="Relative strength of ETH vs BTC. < 0.025 = defensive / BTC-led, 0.0250.04 = range, > 0.04 = ETH and alts gaining leadership."
hint="Relative strength of ETH vs BTC — a proxy for broader crypto risk appetite."
summary={ebrSay}
activeIndex={ebrActive}
thresholds={[
@@ -547,7 +574,7 @@ export default function MacroPanel() {
label="ETF Net Flow (1d)"
value={fmtSignedUsd(ind.etf_flow_net_usd_1d)}
tone={toneEtfFlow(ind.etf_flow_net_usd_1d)}
hint="Yesterday's total net flow into/out of US spot BTC ETFs. > +$200M = strong bid, $50M to +$50M = noise, < $200M = heavy outflow."
hint="Yesterday's total net flow into/out of US spot BTC ETFs — a direct read on institutional demand."
summary={etfSay}
activeIndex={etfActive}
thresholds={[