feat(macro-vibes): rename BTC Signal → Macro Vibes; add MacroPanel UI

Module rename across page H1, navbar tab, URL (/en/btc → /en/macro),
all metadata/JSON-LD, sitemap, llms.txt, opengraph image, and SystemControl
copy. Old /btc route fully removed.

New components/btc/MacroPanel.tsx polls /api/macro/snapshot and lays out
the 8 indicators in four sections (Valuation / Bottom trigger reference /
Market structure / Sentiment & flows / Positioning) with tone-coloured
values, current-band threshold chips, and a single CoinGlass / source
chart link per card. Composite -100..+100 needle pulses on score change.

Also fixes the pinned bottom-reversal alert on the homepage, which still
linked to the now-404 /en/btc — now routes to /en/macro.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
k
2026-05-26 01:05:18 +08:00
parent d72323b1c6
commit f34ae9eb00
33 changed files with 1810 additions and 228 deletions
+8 -6
View File
@@ -241,7 +241,7 @@ function getCopy(locale: string): GlossaryCopy {
abbr: 'Unspent Transaction Output',
category: 'Bitcoin term',
definition:
'UTXO is the fundamental accounting unit of the Bitcoin network. Trump Alphas live BTC signal no longer relies directly on UTXO-spend behavior, but the concept still matters for interpreting classic on-chain research.',
'UTXO is the fundamental accounting unit of the Bitcoin network. Trump Alphas live Macro Vibes module no longer relies directly on UTXO-spend behavior, but the concept still matters for interpreting classic on-chain research.',
},
{
term: 'Perpetual Future',
@@ -277,11 +277,12 @@ function getCopy(locale: string): GlossaryCopy {
}
}
export function generateMetadata({
params: { locale },
export async function generateMetadata({
params,
}: {
params: { locale: string }
}): Metadata {
params: Promise<{ locale: string }>
}): Promise<Metadata> {
const { locale } = await params
const copy = getCopy(locale)
return {
@@ -319,7 +320,8 @@ const CATEGORY_COLOR: Record<string, string> = {
'技术术语': '#94a3b8',
}
export default function GlossaryPage({ params: { locale } }: { params: { locale: string } }) {
export default async function GlossaryPage({ params }: { params: Promise<{ locale: string }> }) {
const { locale } = await params
const copy = getCopy(locale)
const categories = Array.from(new Set(copy.terms.map(t => t.category)))