Files
trumpsignal-frontend/app/page.tsx
T
k d72323b1c6 Production polish: i18n shelved, PWA icons, SEO/GEO cleanup, UX fixes
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>
2026-05-25 00:53:27 +08:00

918 lines
36 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
'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&rsquo;s tradeable. You sleep. It doesn&rsquo;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="24×"
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&rsquo;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&nbsp;2025</span>
</div>
<h3 className="lp-news-headline">
Trump&rsquo;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&nbsp;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&nbsp;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&rsquo;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&rsquo;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="minuteshours" />
<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 &amp; 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>
)
}