'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(null) useEffect(() => { const root = ref.current if (!root) return const els = root.querySelectorAll('.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('') 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) { 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(strength = 0.35) { const ref = useRef(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(maxDeg = 8) { const ref = useRef(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(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) // 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 (
{/* ---------- HERO ---------- */}
Six signal engines running · right now

{heroLine1}
{heroLine2}

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.

Launch Dashboard See all six signals
{/* Live counter strip — animates in when hero is visible */} {/* Ticker strip */}
{[0, 1].map((k) => (
))}
{/* ---------- FOUR PILLARS ---------- */}
What runs inside

Six independent signal engines.
One dashboard, zero noise.

{/* ---------- THE ENGINE (terminal block) — Pillar 1 deep-dive ---------- */}
Pillar 1 · live engine

Real feed. Not a mock-up.

{/* Terminal */}
LIVE trumpsignal.engine src=truthsocial.com/@realDonaldTrump {clock}
tail -f /var/log/engine posts analysed: 1,247 · uptime 99.8%
{/* Stat strip */}
{/* ---------- PRESS / HEADLINES ---------- */}
Headlines you can Google

The market already trades
every Trump post.

{/* Big card — the $6.8M trader story */}
verified · on-chain
+$6.8M
50× leverage · same-day close
Raw Story · NewsBreak Mar 2025

Anonymous whale placed a 50× leveraged BTC/ETH bet minutes before Trump’s crypto-reserve post — cashed out the same day.

CNBC Mar 2 2025

Trump’s Truth Social post confirming a Strategic Crypto Reserve sent Bitcoin from $84k to $91k overnight.

+8.2% BTC · 24 hours
one Truth Social post
Al Jazeera Mar 4 2025

Ethereum spiked more than 10% alongside Bitcoin as the reserve announcement rippled across every major alt.

+10%+ ETH · same window
BTC, SOL, XRP followed
CoinDesk Apr 20 2026

Five separate times a single Trump statement moved BTC within minutes — and why it keeps happening.

documented cases
BTC moved in minutes
TIME Mar 2025

Senator Schiff calls for an SEC investigation into possible insider trading around Trump’s market-moving posts.

SEC investigation requested
by a U.S. senator

Not our claims — their headlines. Click any card to read the source.

{/* ---------- WHY IT WORKS ---------- */}
Why bother

Trump posts at 3am.
The bot doesn’t sleep.

{/* ---------- COMPARISON TABLE ---------- */}
How it compares

Free. Non-custodial.
No subscription.

Feature Trump Alpha Kaito / Santiment Manual research
{/* ---------- WHAT IS TRUMP ALPHA (canonical definition for GEO) ---------- */}
What is Trump Alpha

One platform. Six independent
crypto intelligence engines.

Trump Alpha 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.

Signal methodology {' · '} Glossary {' · '} Case studies

{/* ---------- FAQ (GEO + SERP feature snippets) ---------- */}
FAQ

Common questions
answered straight.

{/* ---------- FINAL CTA ---------- */}

Stop juggling tabs.
One dashboard. Six edges.

Free to read. 2 minutes to set up. Nothing to cancel.

Launch Dashboard

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.

© {new Date().getFullYear()} TrumpSignal Methodology Glossary Case Studies Privacy Terms Contact Dashboard
) } /* ---------- 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 (
@realDonaldTrump · {ts} · truthsocial

{text}

cls {cls} {'asset' in verdict && ( <> asset {verdict.asset} conf {verdict.conf} action {verdict.action} )} {'skip' in verdict && ( reason {verdict.skip} )}
) } /* ---------- Small components ---------- */ function TickerItem({ asset, kind, text }: { asset: string; kind: 'buy' | 'sell' | 'hold'; text: string }) { return (
{kind.toUpperCase()} {asset} · {text}
) } function Stat({ value, suffix, label, sub }: { value: string; suffix?: string; label: string; sub?: string }) { return (
{value} {suffix && {suffix}}
{label}
{sub &&
{sub}
}
) } function WhyCard({ n, t, d }: { n: string; t: string; d: string }) { return (
{n}

{t}

{d}

) } function CompRow({ f, us, them, manual }: { f: string; us: string; them: string; manual: string }) { return ( {f} {us} {them} {manual} ) } function FaqItem({ q, a }: { q: string; a: string }) { const [open, setOpen] = useState(false) return (
{open && (

{a}

)}
) } function PillarCard({ tag, title, desc, metric, metricLabel, href, }: { tag: string; title: string; desc: string; metric: string; metricLabel: string; href: string }) { const tiltRef = useTilt(7) return ( {/* spotlight gradient that follows cursor inside the card */} {/* animated gradient border (conic) */}
{tag}

{title}

{desc}

{metric} {metricLabel}
) } /* 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 (
{n1}+
posts analyzed
{n2}
live KOL feeds
${n3.toLocaleString()}k
tracked wallet AUM
) }