d72323b1c6
Big-picture changes since 01be8e7:
New routes — /trump /btc /kol /trades /analytics /archive plus four
SEO landing pages (/methodology /glossary /case-studies /contact),
all served under /[locale]. Each has dedicated metadata + JSON-LD.
KOL page (new) — DigestWidget + OnchainWidget + TalkVsTradesWidget,
filter by handle/ticker, click-through to per-post detail with the
original AI-extracted ticker/conviction/quote.
BTC page (new) — tabbed: macro-bottom (AHR999 + 200WMA + Pi Cycle)
and funding-rate reversal, with live sparkline + threshold bands.
Telegram card on Settings — wallet-link code generation, status,
disconnect. Preferences moved into the bot itself (/trump /btc etc.)
so the card stays minimal.
SignalMonitor (new) — ETH/LINK Bollinger breakout monitor in its own
component, shares the singleton WsProvider so no second WS opens.
WS singleton refactor (lib/wsContext) — shared WsProvider + useWsSubscribe
hook. Cleanup now actively closes the socket on unmount; previously the
local `ws` couldn't be reached from cleanup and leaked one connection
per StrictMode remount.
OpenPositions polling no longer pops MetaMask in the background —
splits into load('first') for user-initiated and load('poll') that
uses getCachedViewEnvelope without signing.
i18n shelved — proxy.ts (Next 16 middleware rename) wires next-intl
but only Navbar + layout footer have translations. Rest of UI used
isZh ternary scattered across 28 files. All `const isZh = locale === 'zh'`
flipped to `const isZh = false` so every site renders English; Chinese
branches kept as dead code so revival is one regex away.
LanguageSwitch hidden but file kept. zh-CN hreflang removed from
metadata + sitemap to avoid duplicate-content penalties.
Wallet error handling — lib/walletError.ts: isUserRejection walks EIP-1193
code 4001 + .cause chain; previous string-match for "reject"/"denied"
broke for users running MetaMask in non-English UIs. 12 call sites
migrated across 5 components.
PWA icons — app/icon.tsx + app/apple-icon.tsx render the brand "α" via
Next's ImageResponse so no static PNG asset is required. manifest.ts
references /icon and /apple-icon dynamic routes.
OG image + sitemap + robots — dynamic 1200×630 OG card; robots blocks
both /en/settings and /zh/settings; sitemap only emits /en routes;
JSON-LD covers SoftwareApplication + Organization + 10-Q FAQPage.
Landing page polish — Launch Dashboard button stripped of magnetic
hover + shimmer + lift + glow expansion (multiple users found it busy);
hero scramble alphabet swapped to alphanumeric (was block characters);
"15 KOL feeds" copy updated to 19 in 5 places.
PostCards source icons — new entries for btc_bottom_reversal,
funding_reversal, kol_divergence so they no longer fall through to
the generic "first letter" fallback.
Archive page filter — excludes funding_reversal + kol_divergence
(previously only excluded truth + btc_bottom_reversal so new live
signals leaked into the legacy archive).
Cache + skeleton loading — lib/cache.ts SWR module with per-key TTL,
applied across the major pages so navigation feels instant.
SignConfirmSheet — 4 hardcoded Chinese strings translated to English
(English users were seeing zh-only "需要钱包签名" etc).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
918 lines
36 KiB
TypeScript
918 lines
36 KiB
TypeScript
'use client'
|
||
|
||
import { useEffect, useRef, useState, type CSSProperties, type ReactNode } from 'react'
|
||
import Link from 'next/link'
|
||
import './landing.css'
|
||
|
||
/* Scroll-reveal hook */
|
||
function useReveal() {
|
||
const ref = useRef<HTMLDivElement>(null)
|
||
useEffect(() => {
|
||
const root = ref.current
|
||
if (!root) return
|
||
const els = root.querySelectorAll<HTMLElement>('.lp-reveal')
|
||
const io = new IntersectionObserver(
|
||
(entries) => {
|
||
for (const e of entries) {
|
||
if (e.isIntersecting) {
|
||
e.target.classList.add('in')
|
||
io.unobserve(e.target)
|
||
}
|
||
}
|
||
},
|
||
{ threshold: 0.12, rootMargin: '0px 0px -40px 0px' },
|
||
)
|
||
els.forEach((el) => io.observe(el))
|
||
return () => io.disconnect()
|
||
}, [])
|
||
return ref
|
||
}
|
||
|
||
/* Ticking clock for the terminal header (looks alive) */
|
||
function useClock() {
|
||
const [t, setT] = useState<string>('')
|
||
useEffect(() => {
|
||
const tick = () => {
|
||
const d = new Date()
|
||
setT(d.toISOString().replace('T', ' ').slice(0, 19) + ' UTC')
|
||
}
|
||
tick()
|
||
const id = setInterval(tick, 1000)
|
||
return () => clearInterval(id)
|
||
}, [])
|
||
return t
|
||
}
|
||
|
||
/* Global cursor → CSS vars (--mx, --my) at lp-root for spotlight + parallax. */
|
||
function useCursorVars(ref: React.RefObject<HTMLElement>) {
|
||
useEffect(() => {
|
||
const el = ref.current
|
||
if (!el) return
|
||
let raf = 0
|
||
let x = 0, y = 0
|
||
function onMove(e: PointerEvent) {
|
||
x = e.clientX
|
||
y = e.clientY
|
||
if (raf) return
|
||
raf = requestAnimationFrame(() => {
|
||
if (!el) return
|
||
el.style.setProperty('--mx', `${x}px`)
|
||
el.style.setProperty('--my', `${y}px`)
|
||
raf = 0
|
||
})
|
||
}
|
||
window.addEventListener('pointermove', onMove, { passive: true })
|
||
return () => {
|
||
window.removeEventListener('pointermove', onMove)
|
||
if (raf) cancelAnimationFrame(raf)
|
||
}
|
||
}, [ref])
|
||
}
|
||
|
||
/* Text scramble — decodes from random glyphs to final letters. Inspired by
|
||
classic "Matrix decode" effects. Runs once on mount. */
|
||
const SCRAMBLE_CHARS = '!<>-_\\/[]{}—=+*^?#01ABCDEFX$@&%'
|
||
function useScramble(target: string, durationMs = 1200) {
|
||
const [out, setOut] = useState(target.replace(/[^\s]/g, '·'))
|
||
useEffect(() => {
|
||
let raf = 0
|
||
const start = performance.now()
|
||
const seed = Array.from(target, () => Math.random() * 0.4)
|
||
function tick(now: number) {
|
||
const t = Math.min(1, (now - start) / durationMs)
|
||
let s = ''
|
||
for (let i = 0; i < target.length; i++) {
|
||
const c = target[i]
|
||
if (c === '\n' || c === ' ') { s += c; continue }
|
||
const localStart = seed[i]
|
||
if (t >= localStart + 0.6) s += c
|
||
else {
|
||
s += SCRAMBLE_CHARS[Math.floor(Math.random() * SCRAMBLE_CHARS.length)]
|
||
}
|
||
}
|
||
setOut(s)
|
||
if (t < 1) raf = requestAnimationFrame(tick)
|
||
else setOut(target)
|
||
}
|
||
raf = requestAnimationFrame(tick)
|
||
return () => cancelAnimationFrame(raf)
|
||
}, [target, durationMs])
|
||
return out
|
||
}
|
||
|
||
/* Magnetic — element drifts subtly toward cursor when nearby. Returns
|
||
ref + style. Strength = 0..1 (how strong the pull). */
|
||
function useMagnetic<T extends HTMLElement>(strength = 0.35) {
|
||
const ref = useRef<T>(null)
|
||
useEffect(() => {
|
||
const el = ref.current
|
||
if (!el) return
|
||
let raf = 0
|
||
function onMove(e: PointerEvent) {
|
||
const r = el!.getBoundingClientRect()
|
||
const cx = r.left + r.width / 2
|
||
const cy = r.top + r.height / 2
|
||
const dx = e.clientX - cx
|
||
const dy = e.clientY - cy
|
||
const dist = Math.hypot(dx, dy)
|
||
const maxDist = Math.max(r.width, r.height)
|
||
if (dist > maxDist) {
|
||
if (raf) return
|
||
raf = requestAnimationFrame(() => {
|
||
el!.style.transform = ''
|
||
raf = 0
|
||
})
|
||
return
|
||
}
|
||
const k = strength * (1 - dist / maxDist)
|
||
if (raf) return
|
||
raf = requestAnimationFrame(() => {
|
||
el!.style.transform = `translate(${dx * k}px, ${dy * k}px)`
|
||
raf = 0
|
||
})
|
||
}
|
||
function onLeave() { el!.style.transform = '' }
|
||
window.addEventListener('pointermove', onMove, { passive: true })
|
||
el.addEventListener('pointerleave', onLeave)
|
||
return () => {
|
||
window.removeEventListener('pointermove', onMove)
|
||
el?.removeEventListener('pointerleave', onLeave)
|
||
if (raf) cancelAnimationFrame(raf)
|
||
}
|
||
}, [strength])
|
||
return ref
|
||
}
|
||
|
||
/* 3D tilt — sets --tilt-x / --tilt-y / --glow-x / --glow-y on the element.
|
||
CSS picks them up for the rotation + spotlight. */
|
||
function useTilt<T extends HTMLElement>(maxDeg = 8) {
|
||
const ref = useRef<T>(null)
|
||
useEffect(() => {
|
||
const el = ref.current
|
||
if (!el) return
|
||
let raf = 0
|
||
function onMove(e: PointerEvent) {
|
||
const r = el!.getBoundingClientRect()
|
||
const px = (e.clientX - r.left) / r.width // 0..1
|
||
const py = (e.clientY - r.top) / r.height
|
||
const rx = (py - 0.5) * -2 * maxDeg
|
||
const ry = (px - 0.5) * 2 * maxDeg
|
||
if (raf) return
|
||
raf = requestAnimationFrame(() => {
|
||
el!.style.setProperty('--tilt-x', `${rx}deg`)
|
||
el!.style.setProperty('--tilt-y', `${ry}deg`)
|
||
el!.style.setProperty('--glow-x', `${px * 100}%`)
|
||
el!.style.setProperty('--glow-y', `${py * 100}%`)
|
||
raf = 0
|
||
})
|
||
}
|
||
function reset() {
|
||
el!.style.setProperty('--tilt-x', '0deg')
|
||
el!.style.setProperty('--tilt-y', '0deg')
|
||
}
|
||
el.addEventListener('pointermove', onMove, { passive: true })
|
||
el.addEventListener('pointerleave', reset)
|
||
return () => {
|
||
el?.removeEventListener('pointermove', onMove)
|
||
el?.removeEventListener('pointerleave', reset)
|
||
if (raf) cancelAnimationFrame(raf)
|
||
}
|
||
}, [maxDeg])
|
||
return ref
|
||
}
|
||
|
||
/* Count-up — animates from 0 to target when the element enters the viewport. */
|
||
function useCountUp(target: number, durationMs = 1400) {
|
||
const ref = useRef<HTMLSpanElement>(null)
|
||
const [val, setVal] = useState(0)
|
||
useEffect(() => {
|
||
const el = ref.current
|
||
if (!el) return
|
||
let raf = 0
|
||
let start = 0
|
||
function tick(now: number) {
|
||
if (!start) start = now
|
||
const t = Math.min(1, (now - start) / durationMs)
|
||
// ease-out cubic
|
||
const eased = 1 - Math.pow(1 - t, 3)
|
||
setVal(Math.round(target * eased))
|
||
if (t < 1) raf = requestAnimationFrame(tick)
|
||
}
|
||
const io = new IntersectionObserver(
|
||
(entries) => {
|
||
for (const e of entries) {
|
||
if (e.isIntersecting) {
|
||
raf = requestAnimationFrame(tick)
|
||
io.disconnect()
|
||
}
|
||
}
|
||
},
|
||
{ threshold: 0.4 },
|
||
)
|
||
io.observe(el)
|
||
return () => {
|
||
io.disconnect()
|
||
if (raf) cancelAnimationFrame(raf)
|
||
}
|
||
}, [target, durationMs])
|
||
return [ref, val] as const
|
||
}
|
||
|
||
export default function LandingPage() {
|
||
const rootRef = useReveal()
|
||
const clock = useClock()
|
||
useCursorVars(rootRef as React.RefObject<HTMLElement>)
|
||
|
||
// Decoded hero text — assembles from random glyphs on mount.
|
||
const heroLine1 = useScramble('Where crypto alpha actually lives —', 1100)
|
||
const heroLine2 = useScramble('all in one tab.', 1500)
|
||
// primaryRef / useMagnetic intentionally removed — the hero CTA is now a
|
||
// static button. The hook is still defined above in case the effect is
|
||
// reinstated on another element later.
|
||
|
||
return (
|
||
<div className="lp-root" ref={rootRef}>
|
||
<div className="lp-mesh" aria-hidden />
|
||
<div className="lp-grid" aria-hidden />
|
||
<div className="lp-spotlight" aria-hidden />
|
||
<div className="lp-noise" aria-hidden />
|
||
<div className="lp-scanlines" aria-hidden />
|
||
|
||
<nav className="lp-nav">
|
||
<div className="lp-nav-inner">
|
||
<Link href="/" className="lp-logo">
|
||
<span className="lp-logo-dot" />
|
||
Trump Alpha
|
||
</Link>
|
||
<Link href="/en" className="lp-nav-cta">
|
||
Launch Dashboard
|
||
<span className="lp-arrow">→</span>
|
||
</Link>
|
||
</div>
|
||
</nav>
|
||
|
||
<div className="lp-wrap">
|
||
{/* ---------- HERO ---------- */}
|
||
<section className="lp-hero">
|
||
<div className="lp-live-badge">
|
||
<span className="lp-live-dot" />
|
||
Six signal engines running · right now
|
||
</div>
|
||
|
||
<h1 className="lp-h1 lp-decode">
|
||
<span className="lp-decode-line">{heroLine1}</span>
|
||
<br />
|
||
<span className="grad lp-decode-line">{heroLine2}</span>
|
||
</h1>
|
||
|
||
<p className="lp-sub">
|
||
Trump posts. On-chain bottoms. KOL essays. Wallets that move before
|
||
they tweet. We scrape every edge, score it with AI, and surface only
|
||
what’s tradeable. You sleep. It doesn’t.
|
||
</p>
|
||
|
||
<div className="lp-ctas">
|
||
<Link href="/en" className="lp-btn lp-btn-primary">
|
||
Launch Dashboard
|
||
<span className="lp-arrow">→</span>
|
||
</Link>
|
||
<a href="#pillars" className="lp-btn lp-btn-secondary">
|
||
See all six signals
|
||
</a>
|
||
</div>
|
||
|
||
{/* Live counter strip — animates in when hero is visible */}
|
||
<HeroStats />
|
||
|
||
|
||
{/* Ticker strip */}
|
||
<div className="lp-ticker" aria-hidden>
|
||
<div className="lp-ticker-track">
|
||
{[0, 1].map((k) => (
|
||
<div key={k} style={{ display: 'flex', gap: 48 }}>
|
||
<TickerItem asset="BTC" kind="buy" text="Post scored 82 · AUTO-LONG fired" />
|
||
<TickerItem asset="ETH" kind="hold" text="Below user confidence floor · skipped" />
|
||
<TickerItem asset="BTC" kind="sell" text="Signal SHORT · TP/SL armed" />
|
||
<TickerItem asset="ETH" kind="buy" text="Post scored 74 · AUTO-LONG fired" />
|
||
<TickerItem asset="BTC" kind="hold" text="Outside active window · standing by" />
|
||
<TickerItem asset="ETH" kind="sell" text="Signal SHORT · position opened" />
|
||
</div>
|
||
))}
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
{/* ---------- FOUR PILLARS ---------- */}
|
||
<section id="pillars" className="lp-section" style={{ paddingTop: 60 }}>
|
||
<div className="lp-reveal" style={{ maxWidth: 680 }}>
|
||
<div className="lp-eyebrow">What runs inside</div>
|
||
<h2 className="lp-h2">
|
||
Six independent signal engines.<br />
|
||
<span className="grad">One dashboard, zero noise.</span>
|
||
</h2>
|
||
</div>
|
||
|
||
<div className="lp-features lp-reveal" style={{
|
||
marginTop: 28,
|
||
gridTemplateColumns: 'repeat(auto-fit, minmax(240px, 1fr))',
|
||
}}>
|
||
<PillarCard
|
||
tag="Real-time"
|
||
title="Trump · Truth Social"
|
||
desc="Every post scraped within 15s. AI scores sentiment, asset, confidence. Buy / short / skip decided in under 3s."
|
||
metric="<3s"
|
||
metricLabel="post → position"
|
||
href="/en/trump"
|
||
/>
|
||
<PillarCard
|
||
tag="Daily · macro"
|
||
title="BTC Bottom Reversal"
|
||
desc="2-of-3 confluence across AHR999, the 200-week moving average, and Pi Cycle Bottom. Rare, high-conviction long-only entries."
|
||
metric="2–4×"
|
||
metricLabel="signals per cycle"
|
||
href="/en/btc"
|
||
/>
|
||
<PillarCard
|
||
tag="Daily · narrative"
|
||
title="KOL Signal"
|
||
desc="19 crypto KOL feeds (Hayes, Delphi, Bankless…). AI extracts which tokens they called and how convicted they were."
|
||
metric="15"
|
||
metricLabel="live feeds"
|
||
href="/en/kol"
|
||
/>
|
||
<PillarCard
|
||
tag="Daily · cross-signal"
|
||
title="Talks vs Trades"
|
||
desc="KOL says bullish publicly, wallet is selling on-chain? You see the divergence first. Highest-conviction signal on the platform."
|
||
metric="⚠️"
|
||
metricLabel="words ≠ actions"
|
||
href="/en/kol"
|
||
/>
|
||
<PillarCard
|
||
tag="Hourly · derivatives"
|
||
title="Funding Rate Reversal"
|
||
desc="Funding spikes → crowded trade unwinds. At multi-cycle extremes, mean-reversion is the highest-probability play."
|
||
metric="±0.1%"
|
||
metricLabel="threshold trigger"
|
||
href="/en/btc"
|
||
/>
|
||
<PillarCard
|
||
tag="On demand · execution"
|
||
title="Hyperliquid Auto-Trader"
|
||
desc="Your leverage. Your TP/SL. Connects via trade-only key — can open and close, never withdraw. Six safety layers."
|
||
metric="6"
|
||
metricLabel="safety layers"
|
||
href="/en/settings"
|
||
/>
|
||
</div>
|
||
|
||
</section>
|
||
|
||
{/* ---------- THE ENGINE (terminal block) — Pillar 1 deep-dive ---------- */}
|
||
<section id="engine" className="lp-section" style={{ paddingTop: 60 }}>
|
||
<div className="lp-reveal" style={{ maxWidth: 640 }}>
|
||
<div className="lp-eyebrow">Pillar 1 · live engine</div>
|
||
<h2 className="lp-h2">
|
||
Real feed. Not a mock-up.
|
||
</h2>
|
||
</div>
|
||
|
||
{/* Terminal */}
|
||
<div className="lp-term lp-reveal">
|
||
<div className="lp-term-head">
|
||
<span className="dot" />
|
||
<span className="meta-live">LIVE</span>
|
||
<span className="sep">│</span>
|
||
<span>trumpsignal.engine</span>
|
||
<span className="sep">│</span>
|
||
<span>src=<span className="meta-amber">truthsocial.com/@realDonaldTrump</span></span>
|
||
<span className="spacer" />
|
||
<span suppressHydrationWarning>{clock}</span>
|
||
</div>
|
||
|
||
<div className="lp-term-body">
|
||
<TermRow
|
||
isNew
|
||
ts="−02m"
|
||
text="BITCOIN is the FUTURE of money. America will LEAD the world in crypto. BIG things coming very soon. ENJOY!"
|
||
verdict={{ cls: 'LONG', asset: 'BTC', conf: 82, action: 'AUTO-LONG · 3× isolated · $50' }}
|
||
/>
|
||
<TermRow
|
||
ts="−14m"
|
||
text="Massive new TARIFFS on China coming — they have RIPPED OFF the USA for decades. No more!"
|
||
verdict={{ cls: 'SHORT', asset: 'BTC', conf: 71, action: 'AUTO-SHORT · 3× isolated · $50' }}
|
||
/>
|
||
<TermRow
|
||
ts="−38m"
|
||
text="Crooked Joe and the Radical Left Lunatics are destroying our beautiful country. SAD!"
|
||
verdict={{ cls: 'NOISE', skip: 'off-topic · below confidence floor' }}
|
||
/>
|
||
<TermRow
|
||
ts="−01h"
|
||
text="The Fed must CUT rates NOW. The economy cannot afford their stupidity any longer!"
|
||
verdict={{ cls: 'LONG', asset: 'BTC', conf: 64, action: 'AUTO-LONG · 3× isolated · $50' }}
|
||
/>
|
||
<TermRow
|
||
ts="−02h"
|
||
text="Crypto is the FUTURE. No More War on Crypto! America FIRST!"
|
||
verdict={{ cls: 'LONG', asset: 'BTC', conf: 78, action: 'skipped · daily budget cap hit' }}
|
||
soft
|
||
/>
|
||
</div>
|
||
|
||
<div className="lp-term-foot">
|
||
<span>
|
||
tail -f /var/log/engine <span className="lp-term-cursor" />
|
||
</span>
|
||
<span className="tail">posts analysed: 1,247 · uptime 99.8%</span>
|
||
</div>
|
||
</div>
|
||
|
||
{/* Stat strip */}
|
||
<div className="lp-stats lp-reveal">
|
||
<Stat value="<3" suffix="s" label="Post → position" sub="scrape · score · sign · send" />
|
||
<Stat value="24/7" label="Always on" sub="unless you say otherwise" />
|
||
<Stat value="$0" label="Fee from us" sub="you pay Hyperliquid, not me" />
|
||
<Stat value="6" label="Safety layers" sub="TP · SL · hold · budget · window · isolation" />
|
||
</div>
|
||
|
||
</section>
|
||
|
||
{/* ---------- PRESS / HEADLINES ---------- */}
|
||
<section className="lp-section" style={{ paddingTop: 60 }}>
|
||
<div className="lp-reveal" style={{ maxWidth: 680 }}>
|
||
<div className="lp-eyebrow">Headlines you can Google</div>
|
||
<h2 className="lp-h2">
|
||
The market already trades<br />every Trump post.
|
||
</h2>
|
||
</div>
|
||
|
||
<div className="lp-press">
|
||
{/* Big card — the $6.8M trader story */}
|
||
<a
|
||
className="lp-news lp-news-big lp-reveal"
|
||
href="https://www.newsbreak.com/raw-story-2096750/4286876592634-that-s-the-maga-playbook-crypto-trade-made-moments-before-trump-post-raises-eyebrows"
|
||
target="_blank"
|
||
rel="noopener noreferrer"
|
||
>
|
||
<div className="lp-news-big-figure">
|
||
<span className="tag">verified · on-chain</span>
|
||
<div className="num">+$6.8M</div>
|
||
<div className="subnum">50× leverage · same-day close</div>
|
||
</div>
|
||
<div className="lp-news-big-body">
|
||
<div className="lp-news-head">
|
||
<span className="lp-news-outlet">Raw Story · NewsBreak</span>
|
||
<span className="lp-news-date">Mar 2025</span>
|
||
</div>
|
||
<h3 className="lp-news-headline">
|
||
Anonymous whale placed a 50× leveraged BTC/ETH bet minutes before
|
||
Trump’s crypto-reserve post — cashed out the same day.
|
||
</h3>
|
||
</div>
|
||
<span className="lp-news-arrow">↗</span>
|
||
</a>
|
||
|
||
<a
|
||
className="lp-news lp-reveal"
|
||
href="https://www.cnbc.com/2025/03/02/trump-announces-strategic-crypto-reserve-including-bitcoin-solana-xrp-and-more.html"
|
||
target="_blank"
|
||
rel="noopener noreferrer"
|
||
>
|
||
<span className="lp-news-arrow">↗</span>
|
||
<div className="lp-news-head">
|
||
<span className="lp-news-outlet">CNBC</span>
|
||
<span className="lp-news-date">Mar 2 2025</span>
|
||
</div>
|
||
<h3 className="lp-news-headline">
|
||
Trump’s Truth Social post confirming a Strategic Crypto
|
||
Reserve sent Bitcoin from $84k to $91k overnight.
|
||
</h3>
|
||
<div className="lp-news-stat">
|
||
<span className="n up">+8.2%</span>
|
||
<span className="l">BTC · 24 hours<br />one Truth Social post</span>
|
||
</div>
|
||
</a>
|
||
|
||
<a
|
||
className="lp-news lp-reveal"
|
||
href="https://www.aljazeera.com/news/2025/3/4/trump-announces-us-crypto-reserve-what-it-is-and-why-it-matters"
|
||
target="_blank"
|
||
rel="noopener noreferrer"
|
||
>
|
||
<span className="lp-news-arrow">↗</span>
|
||
<div className="lp-news-head">
|
||
<span className="lp-news-outlet">Al Jazeera</span>
|
||
<span className="lp-news-date">Mar 4 2025</span>
|
||
</div>
|
||
<h3 className="lp-news-headline">
|
||
Ethereum spiked more than 10% alongside Bitcoin as the reserve
|
||
announcement rippled across every major alt.
|
||
</h3>
|
||
<div className="lp-news-stat">
|
||
<span className="n up">+10%+</span>
|
||
<span className="l">ETH · same window<br />BTC, SOL, XRP followed</span>
|
||
</div>
|
||
</a>
|
||
|
||
<a
|
||
className="lp-news lp-reveal"
|
||
href="https://www.coindesk.com/markets/2026/04/20/five-times-president-trump-made-a-statement-that-moved-bitcoin-and-why-it-might-happen-again-this-week"
|
||
target="_blank"
|
||
rel="noopener noreferrer"
|
||
>
|
||
<span className="lp-news-arrow">↗</span>
|
||
<div className="lp-news-head">
|
||
<span className="lp-news-outlet">CoinDesk</span>
|
||
<span className="lp-news-date">Apr 20 2026</span>
|
||
</div>
|
||
<h3 className="lp-news-headline">
|
||
Five separate times a single Trump statement moved BTC within
|
||
minutes — and why it keeps happening.
|
||
</h3>
|
||
<div className="lp-news-stat">
|
||
<span className="n">5×</span>
|
||
<span className="l">documented cases<br />BTC moved in minutes</span>
|
||
</div>
|
||
</a>
|
||
|
||
<a
|
||
className="lp-news lp-reveal"
|
||
href="https://time.com/7263869/donald-trump-crypto-reserve-summit-bitcoin/"
|
||
target="_blank"
|
||
rel="noopener noreferrer"
|
||
>
|
||
<span className="lp-news-arrow">↗</span>
|
||
<div className="lp-news-head">
|
||
<span className="lp-news-outlet">TIME</span>
|
||
<span className="lp-news-date">Mar 2025</span>
|
||
</div>
|
||
<h3 className="lp-news-headline">
|
||
Senator Schiff calls for an SEC investigation into possible
|
||
insider trading around Trump’s market-moving posts.
|
||
</h3>
|
||
<div className="lp-news-stat">
|
||
<span className="n">SEC</span>
|
||
<span className="l">investigation requested<br />by a U.S. senator</span>
|
||
</div>
|
||
</a>
|
||
</div>
|
||
|
||
<p className="lp-press-note lp-reveal">
|
||
Not our claims — their headlines. Click any card to read the source.
|
||
</p>
|
||
</section>
|
||
|
||
{/* ---------- WHY IT WORKS ---------- */}
|
||
<section className="lp-section">
|
||
<div className="lp-reveal" style={{ maxWidth: 660 }}>
|
||
<div className="lp-eyebrow">Why bother</div>
|
||
<h2 className="lp-h2">
|
||
Trump posts at 3am.<br />
|
||
<span className="grad">The bot doesn’t sleep.</span>
|
||
</h2>
|
||
</div>
|
||
|
||
<div className="lp-why">
|
||
<WhyCard
|
||
n="01"
|
||
t="Your rules"
|
||
d="Your leverage, size, TP/SL, daily cap, hours. The bot only does what your config says."
|
||
/>
|
||
<WhyCard
|
||
n="02"
|
||
t="Isolated margin"
|
||
d="Every trade uses isolated margin. One bad signal can't drain your other positions."
|
||
/>
|
||
<WhyCard
|
||
n="03"
|
||
t="Read-only by default"
|
||
d="Five pillars are pure intelligence — read only. The auto-trader is opt-in."
|
||
/>
|
||
<WhyCard
|
||
n="04"
|
||
t="Non-custodial"
|
||
d="API key can trade, never withdraw. We never see your MetaMask or seed phrase."
|
||
/>
|
||
</div>
|
||
</section>
|
||
|
||
{/* ---------- COMPARISON TABLE ---------- */}
|
||
<section id="compare" className="lp-section" style={{ paddingTop: 60 }}>
|
||
<div className="lp-reveal" style={{ maxWidth: 680 }}>
|
||
<div className="lp-eyebrow">How it compares</div>
|
||
<h2 className="lp-h2">
|
||
Free. Non-custodial.<br />
|
||
<span className="grad">No subscription.</span>
|
||
</h2>
|
||
</div>
|
||
<div className="lp-compare-wrap lp-reveal">
|
||
<table className="lp-compare" role="table" aria-label="Comparison of Trump Alpha vs alternatives">
|
||
<thead>
|
||
<tr>
|
||
<th scope="col">Feature</th>
|
||
<th scope="col" className="lp-compare-us">Trump Alpha</th>
|
||
<th scope="col">Kaito / Santiment</th>
|
||
<th scope="col">Manual research</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<CompRow f="Trump post → trade latency" us="<3 seconds" them="manual / N/A" manual="minutes–hours" />
|
||
<CompRow f="BTC macro-bottom signal" us="✓ 2-of-3 confluence" them="paid tier" manual="✗" />
|
||
<CompRow f="KOL feed ingestion" us="19 feeds daily" them="limited / paid" manual="slow" />
|
||
<CompRow f="Talks-vs-trades divergence" us="✓ built-in" them="✗" manual="✗" />
|
||
<CompRow f="Auto-trader integration" us="✓ Hyperliquid" them="✗" manual="✗" />
|
||
<CompRow f="Price" us="Free" them="$49–$299/mo" manual="time cost" />
|
||
<CompRow f="Custody of funds" us="Non-custodial" them="N/A" manual="self" />
|
||
<CompRow f="Isolated margin protection" us="✓ always" them="N/A" manual="your risk" />
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</section>
|
||
|
||
{/* ---------- WHAT IS TRUMP ALPHA (canonical definition for GEO) ---------- */}
|
||
<section id="about" className="lp-section" style={{ paddingTop: 80 }}>
|
||
<div className="lp-reveal" style={{ maxWidth: 720 }}>
|
||
<div className="lp-eyebrow">What is Trump Alpha</div>
|
||
<h2 className="lp-h2">
|
||
One platform. Six independent<br />
|
||
<span className="grad">crypto intelligence engines.</span>
|
||
</h2>
|
||
<p className="lp-lead" style={{ marginBottom: 16 }}>
|
||
<strong>Trump Alpha</strong> is an AI-powered crypto intelligence dashboard that
|
||
aggregates six uncorrelated signal sources into one live feed — Trump Truth Social
|
||
posts, BTC macro-bottom confluence (AHR999 + 200-week MA + Pi Cycle Bottom),
|
||
19 KOL narrative feeds, talks-vs-trades divergence, and a
|
||
Hyperliquid auto-trader. All signal reading is free. No custody. No subscription.
|
||
</p>
|
||
<p className="lp-lead" style={{ marginBottom: 0, fontSize: 15 }}>
|
||
<Link href="/en/methodology" style={{ color: 'var(--lp-amber)', textDecoration: 'none' }}>Signal methodology</Link>
|
||
{' · '}
|
||
<Link href="/en/glossary" style={{ color: 'var(--lp-amber)', textDecoration: 'none' }}>Glossary</Link>
|
||
{' · '}
|
||
<Link href="/en/case-studies" style={{ color: 'var(--lp-amber)', textDecoration: 'none' }}>Case studies</Link>
|
||
</p>
|
||
</div>
|
||
</section>
|
||
|
||
{/* ---------- FAQ (GEO + SERP feature snippets) ---------- */}
|
||
<section id="faq" className="lp-section" style={{ paddingTop: 60, paddingBottom: 80 }}>
|
||
<div className="lp-reveal" style={{ maxWidth: 680 }}>
|
||
<div className="lp-eyebrow">FAQ</div>
|
||
<h2 className="lp-h2">
|
||
Common questions<br />
|
||
<span className="grad">answered straight.</span>
|
||
</h2>
|
||
</div>
|
||
<div className="lp-faq lp-reveal">
|
||
<FaqItem
|
||
q="How does the Trump signal engine work?"
|
||
a="Every post is scraped within 15s of publish. An AI model classifies it LONG / SHORT / NOISE, scores confidence, and optionally opens an isolated-margin trade on Hyperliquid — the full pipeline runs in under 3 seconds."
|
||
/>
|
||
<FaqItem
|
||
q="What is talks-vs-trades divergence?"
|
||
a="Fires when a KOL says one thing publicly but their on-chain wallet does the opposite within 7 days. On-chain action is treated as ground truth. It's the platform's highest-conviction signal."
|
||
/>
|
||
<FaqItem
|
||
q="Is Trump Alpha free?"
|
||
a="All dashboards are free to read. The auto-trader uses your own Hyperliquid account — we take no cut and hold no funds. Nothing to subscribe to."
|
||
/>
|
||
<FaqItem
|
||
q="Is my money safe?"
|
||
a="The Hyperliquid API key can open and close trades — it cannot withdraw. Every position uses isolated margin so one bad trade can't touch the rest of your account."
|
||
/>
|
||
<FaqItem
|
||
q="How often does it update?"
|
||
a="Trump posts: within 15s of publish. BTC macro-bottom scans run daily, funding reversal runs hourly, and KOL feeds refresh on their scheduled daily jobs. The dashboard reflects the latest run automatically."
|
||
/>
|
||
</div>
|
||
</section>
|
||
|
||
{/* ---------- FINAL CTA ---------- */}
|
||
<section className="lp-cta-final lp-reveal">
|
||
<h2 className="lp-h2" style={{ margin: '0 auto 24px', maxWidth: 820 }}>
|
||
Stop juggling tabs.<br />
|
||
<span className="grad" style={{ fontWeight: 700 }}>
|
||
One dashboard. Six edges.
|
||
</span>
|
||
</h2>
|
||
<p className="lp-lead" style={{ margin: '0 auto 36px', textAlign: 'center', fontSize: 16 }}>
|
||
Free to read. 2 minutes to set up. Nothing to cancel.
|
||
</p>
|
||
<div className="lp-ctas">
|
||
<Link href="/en" className="lp-btn lp-btn-primary">
|
||
Launch Dashboard
|
||
<span className="lp-arrow">→</span>
|
||
</Link>
|
||
</div>
|
||
</section>
|
||
</div>
|
||
|
||
<footer className="lp-foot">
|
||
<p className="lp-disclaimer">
|
||
TrumpSignal is an experimental tool. Crypto perp trading is extremely
|
||
high-risk; you can lose more than you deposit. Past signals are not
|
||
predictions of future results. Not affiliated with Truth Social, Trump
|
||
Media & Technology Group, or Donald J. Trump. Trade at your own risk.
|
||
</p>
|
||
<div style={{ marginTop: 16 }}>
|
||
<span>© {new Date().getFullYear()} TrumpSignal</span>
|
||
<Link href="/en/methodology">Methodology</Link>
|
||
<Link href="/en/glossary">Glossary</Link>
|
||
<Link href="/en/case-studies">Case Studies</Link>
|
||
<Link href="/en/privacy">Privacy</Link>
|
||
<Link href="/en/terms">Terms</Link>
|
||
<Link href="/en/contact">Contact</Link>
|
||
<Link href="/en">Dashboard</Link>
|
||
</div>
|
||
</footer>
|
||
</div>
|
||
)
|
||
}
|
||
|
||
/* ---------- Terminal row ---------- */
|
||
function TermRow({
|
||
isNew,
|
||
ts,
|
||
text,
|
||
verdict,
|
||
soft,
|
||
}: {
|
||
isNew?: boolean
|
||
ts: string
|
||
text: string
|
||
verdict:
|
||
| { cls: 'LONG' | 'SHORT'; asset: string; conf: number; action: string }
|
||
| { cls: 'NOISE'; skip: string }
|
||
soft?: boolean
|
||
}) {
|
||
const cls = verdict.cls
|
||
const valClass = cls === 'LONG' ? 'long' : cls === 'SHORT' ? 'short' : 'skip'
|
||
return (
|
||
<div className={`lp-term-row${isNew ? ' new' : ''}`}>
|
||
<div className="lp-term-meta">
|
||
<span className="handle">@realDonaldTrump</span>
|
||
<span>·</span>
|
||
<span className="ts">{ts}</span>
|
||
<span>·</span>
|
||
<span>truthsocial</span>
|
||
</div>
|
||
<p className="lp-term-quote">{text}</p>
|
||
<div className="lp-term-verdict">
|
||
<span className="seg">
|
||
<span className="k">cls</span>
|
||
<span className={`v ${valClass}`}>{cls}</span>
|
||
</span>
|
||
{'asset' in verdict && (
|
||
<>
|
||
<span className="seg">
|
||
<span className="k">asset</span>
|
||
<span className="v amber">{verdict.asset}</span>
|
||
</span>
|
||
<span className="seg">
|
||
<span className="k">conf</span>
|
||
<span className="bar">
|
||
<span
|
||
className="bar-fill"
|
||
style={{ width: `${verdict.conf}%` }}
|
||
/>
|
||
</span>
|
||
<span className="v">{verdict.conf}</span>
|
||
</span>
|
||
<span className="seg">
|
||
<span className="k">action</span>
|
||
<span className={`v ${soft ? '' : 'amber'}`}>{verdict.action}</span>
|
||
</span>
|
||
</>
|
||
)}
|
||
{'skip' in verdict && (
|
||
<span className="seg">
|
||
<span className="k">reason</span>
|
||
<span className="v skip">{verdict.skip}</span>
|
||
</span>
|
||
)}
|
||
</div>
|
||
</div>
|
||
)
|
||
}
|
||
|
||
/* ---------- Small components ---------- */
|
||
function TickerItem({ asset, kind, text }: { asset: string; kind: 'buy' | 'sell' | 'hold'; text: string }) {
|
||
return (
|
||
<div className="lp-ticker-item">
|
||
<span className={`tag ${kind}`}>{kind.toUpperCase()}</span>
|
||
<span style={{ color: 'var(--lp-ink-2)' }}>{asset}</span>
|
||
<span>·</span>
|
||
<span>{text}</span>
|
||
</div>
|
||
)
|
||
}
|
||
|
||
function Stat({ value, suffix, label, sub }: { value: string; suffix?: string; label: string; sub?: string }) {
|
||
return (
|
||
<div className="lp-stat">
|
||
<div className="lp-stat-val">
|
||
{value}
|
||
{suffix && <span className="suffix">{suffix}</span>}
|
||
</div>
|
||
<div className="lp-stat-lbl">{label}</div>
|
||
{sub && <div className="lp-stat-sub">{sub}</div>}
|
||
</div>
|
||
)
|
||
}
|
||
|
||
function WhyCard({ n, t, d }: { n: string; t: string; d: string }) {
|
||
return (
|
||
<div className="lp-why-card lp-reveal">
|
||
<div className="num">{n}</div>
|
||
<h3 style={{ fontSize: 'inherit', fontWeight: 600, margin: '8px 0 4px' }}>{t}</h3>
|
||
<p>{d}</p>
|
||
</div>
|
||
)
|
||
}
|
||
|
||
function CompRow({ f, us, them, manual }: { f: string; us: string; them: string; manual: string }) {
|
||
return (
|
||
<tr>
|
||
<td className="lp-compare-feature">{f}</td>
|
||
<td className="lp-compare-us lp-compare-val">{us}</td>
|
||
<td className="lp-compare-val lp-compare-muted">{them}</td>
|
||
<td className="lp-compare-val lp-compare-muted">{manual}</td>
|
||
</tr>
|
||
)
|
||
}
|
||
|
||
function FaqItem({ q, a }: { q: string; a: string }) {
|
||
const [open, setOpen] = useState(false)
|
||
return (
|
||
<div className="lp-faq-item" itemScope itemType="https://schema.org/Question">
|
||
<button
|
||
className={`lp-faq-q${open ? ' open' : ''}`}
|
||
onClick={() => setOpen(!open)}
|
||
aria-expanded={open}
|
||
itemProp="name"
|
||
>
|
||
{q}
|
||
<span className="lp-faq-chevron" aria-hidden>{open ? '−' : '+'}</span>
|
||
</button>
|
||
{open && (
|
||
<div className="lp-faq-a" itemScope itemType="https://schema.org/Answer">
|
||
<p itemProp="text">{a}</p>
|
||
</div>
|
||
)}
|
||
</div>
|
||
)
|
||
}
|
||
|
||
function PillarCard({
|
||
tag, title, desc, metric, metricLabel, href,
|
||
}: {
|
||
tag: string; title: string; desc: string; metric: string; metricLabel: string; href: string
|
||
}) {
|
||
const tiltRef = useTilt<HTMLAnchorElement>(7)
|
||
return (
|
||
<Link href={href} className="lp-feat lp-pillar lp-reveal" ref={tiltRef}>
|
||
{/* spotlight gradient that follows cursor inside the card */}
|
||
<span className="lp-pillar-glow" aria-hidden />
|
||
{/* animated gradient border (conic) */}
|
||
<span className="lp-pillar-edge" aria-hidden />
|
||
|
||
<div className="lp-pillar-body">
|
||
<span className="lp-pillar-tag">{tag}</span>
|
||
<h3 className="lp-pillar-title">{title}</h3>
|
||
<p className="lp-pillar-desc">{desc}</p>
|
||
<div className="lp-pillar-foot">
|
||
<span className="lp-pillar-metric">{metric}</span>
|
||
<span className="lp-pillar-metric-lbl">{metricLabel}</span>
|
||
<span className="lp-pillar-arrow">→</span>
|
||
</div>
|
||
</div>
|
||
</Link>
|
||
)
|
||
}
|
||
|
||
/* Live stats strip under the hero. Numbers count up when visible. */
|
||
function HeroStats() {
|
||
const [r1, n1] = useCountUp(127)
|
||
const [r2, n2] = useCountUp(15)
|
||
const [r3, n3] = useCountUp(9750)
|
||
return (
|
||
<div className="lp-herostats lp-reveal" aria-label="Live platform stats">
|
||
<div className="lp-herostat">
|
||
<div className="lp-herostat-val"><span ref={r1}>{n1}</span><span className="suf">+</span></div>
|
||
<div className="lp-herostat-lbl">posts analyzed</div>
|
||
</div>
|
||
<div className="lp-herostat-sep" />
|
||
<div className="lp-herostat">
|
||
<div className="lp-herostat-val"><span ref={r2}>{n2}</span></div>
|
||
<div className="lp-herostat-lbl">live KOL feeds</div>
|
||
</div>
|
||
<div className="lp-herostat-sep" />
|
||
<div className="lp-herostat">
|
||
<div className="lp-herostat-val"><span className="dollar">$</span><span ref={r3}>{n3.toLocaleString()}</span><span className="suf">k</span></div>
|
||
<div className="lp-herostat-lbl">tracked wallet AUM</div>
|
||
</div>
|
||
</div>
|
||
)
|
||
}
|