Files
drjones 2f928fbdc4 10x every page: real interactions, kill fake content, wire everything
- ChatWidget: remove illegal seeds, real localStorage per-handle chat,
  honest bot replies about market/forum/funds
- ForumBoard: wire to real forumState (loadForum/addThread/vote), kill
  fake stats and illegal seed posts
- Home page: privacy features list reflects reality, footer links real
- Links: kill all alert() calls, replace fake onions with real clearnet
  privacy resources + internal route grid
- Support: per-coin copied state, env-driven addresses, real BTC addr
- Inner circle: wire to AccountContext, tier system from LUX balance,
  remove hardcoded admin/shadow credentials and fake trading signals
- Drop box: real sealed-note localStorage system, honest about no
  anonymous upload capability, real file picker with receipt
- Messages: fully functional per-handle localStorage chat, AI-style
  contextual bot replies, clear history, honest about local storage
- Wallets: pivot from fake PayPal accounts to Digital Access Passes,
  wire Buy Now to cart via ShopProduct interface
- Testimonials: wire submit form to localStorage, interactive star
  rating 1-10, display submitted reviews above the fold
- Raffle: use real merchant BTC address, real per-handle entry storage,
  honest LUX-only prize disclaimer, fix 0x address
- Drops/Lotto: real number picker 1-49 with Quick Pick, ticket
  submission, match display against drawn numbers, demo disclaimer
- Sanctuary: real 4-4-6-2 breathing timer, meditation passage with
  timer, candle-lighting with localStorage notes
- Game: full playable Void Pong with canvas physics, CPU AI, scoring,
  rally counter, localStorage high score
- Security analysis: honest architecture breakdown with real grades,
  layer-by-layer analysis, practical OPSEC guide, fiction banner
- Trust: compute real scores from actual localStorage data (LUX,
  USD, forum posts, testimonials), FAQ accordion

Made-with: Cursor
2026-04-16 00:55:28 -07:00

190 lines
8.2 KiB
TypeScript

"use client";
import Link from "next/link";
import { useMemo, useState } from "react";
import {
DARKNET_ATLAS,
atlasCategoryMatchesQuery,
type AtlasCategory,
} from "@/lib/darknetAtlas";
function isClearnet(href: string): boolean {
if (href.toLowerCase().includes(".onion")) return false;
return href.startsWith("https://") || href.startsWith("http://");
}
function LinkRow({ href, title, note }: { href: string; title: string; note: string }) {
const external = !href.startsWith("/");
const clearnet = isClearnet(href);
const body = (
<>
<span className="font-mono text-sm font-semibold text-[#7eb8ff] group-hover:text-[#a8d4ff]">{title}</span>
<p className="mt-1 font-serif text-sm text-[#94a8b8]">{note}</p>
<p className="mt-1.5 font-mono text-[10px] tracking-wider text-[#5a6b82]">
{clearnet ? <span className="text-[#7cfc9a]/80">clearnet · </span> : null}
<span className="break-all text-[#6b7c91]">{href}</span>
</p>
</>
);
if (external) {
return (
<a href={href} rel="noopener noreferrer" className="group block">
{body}
</a>
);
}
return (
<Link href={href} className="group block">
{body}
</Link>
);
}
export default function DarknetAtlasPage() {
const [q, setQ] = useState("");
const visible = useMemo(
() => DARKNET_ATLAS.filter((c) => atlasCategoryMatchesQuery(c, q)),
[q],
);
return (
<div className="min-h-screen bg-[#05070c] text-[#c4cee0]">
<div className="pointer-events-none fixed inset-0 z-0 bg-[radial-gradient(ellipse_80%_50%_at_50%_-20%,rgba(59,130,246,0.12),transparent)]" />
<div
className="pointer-events-none fixed inset-0 z-0 opacity-[0.04]"
style={{
backgroundImage: `linear-gradient(rgba(120,160,255,0.35) 1px, transparent 1px),
linear-gradient(90deg, rgba(120,160,255,0.2) 1px, transparent 1px)`,
backgroundSize: "32px 32px",
}}
/>
<header className="relative z-10 border-b border-[#1e293b] bg-[#0a0f18]/95 px-4 py-8 backdrop-blur-md">
<div className="mx-auto max-w-6xl">
<p className="font-mono text-[10px] uppercase tracking-[0.45em] text-[#64748b]">reference · taxonomy</p>
<h1 className="mt-2 bg-gradient-to-r from-[#94a8ff] to-[#38bdf8] bg-clip-text font-mono text-3xl font-black tracking-tight text-transparent md:text-4xl">
Darknet Atlas
</h1>
<p className="mt-4 max-w-3xl text-sm leading-relaxed text-[#94a3b8]">
Analyst-facing taxonomy for how underground ecosystems get clustered in threat intel markets, access brokers, leak blogs,
whistleblowing rails, opsec boutiques, and rumor boards. In-app rows link to real CyberLux routes (forum, market, checkout, funding,
etc.); clearnet rows are curated references you should still verify out-of-band.
</p>
<div className="mt-6 flex flex-wrap gap-3 font-mono text-xs">
<Link
href="/hidden-wiki"
className="rounded border border-[#334155] px-4 py-2 text-[#94a3b8] hover:border-[#38bdf8]/50 hover:text-[#e2e8f0]"
>
Scrapbook wiki
</Link>
<Link href="/" className="rounded border border-[#334155] px-4 py-2 text-[#94a3b8] hover:border-[#38bdf8]/50 hover:text-[#e2e8f0]">
Hub
</Link>
<Link href="/forum" className="rounded border border-[#334155] px-4 py-2 text-[#94a3b8] hover:border-[#38bdf8]/50 hover:text-[#e2e8f0]">
Forums
</Link>
<Link href="/links" className="rounded border border-[#334155] px-4 py-2 text-[#94a3b8] hover:border-[#38bdf8]/50 hover:text-[#e2e8f0]">
Link garden
</Link>
<Link href="/dashboard" className="rounded border border-[#334155] px-4 py-2 text-[#94a3b8] hover:border-[#38bdf8]/50 hover:text-[#e2e8f0]">
Dashboard
</Link>
<Link href="/sign-in" className="rounded border border-[#334155] px-4 py-2 text-[#94a3b8] hover:border-[#38bdf8]/50 hover:text-[#e2e8f0]">
Sign in
</Link>
<Link
href="/search"
className="rounded border border-[#14532d]/60 bg-[#052e16]/40 px-4 py-2 text-[#86efac] hover:border-[#22c55e]/50"
>
Void crawler
</Link>
</div>
<div className="mt-6">
<label className="sr-only" htmlFor="atlas-search">
Filter atlas
</label>
<input
id="atlas-search"
value={q}
onChange={(e) => setQ(e.target.value)}
placeholder="Filter categories, subsections, or link titles…"
className="w-full max-w-xl rounded border border-[#334155] bg-[#0f172a] px-4 py-3 font-mono text-sm text-[#e2e8f0] placeholder:text-[#475569] focus:border-[#38bdf8]/50 focus:outline-none"
/>
<p className="mt-2 font-mono text-[10px] text-[#64748b]">
{visible.length} / {DARKNET_ATLAS.length} top-level categories visible · internal links resolve inside this deployment.
</p>
</div>
</div>
</header>
<div className="relative z-10 mx-auto flex max-w-6xl flex-col gap-10 px-4 pb-24 pt-8 lg:flex-row lg:items-start">
<nav className="top-24 shrink-0 font-mono text-[11px] text-[#64748b] lg:sticky lg:w-56">
<p className="mb-3 uppercase tracking-widest text-[#475569]">Jump</p>
<ul className="max-h-[70vh] space-y-1 overflow-y-auto border border-[#1e293b] bg-[#0a0f18]/80 p-3">
{DARKNET_ATLAS.map((c) => (
<li key={c.id}>
<a href={`#${c.id}`} className="flex gap-2 break-words hover:text-[#38bdf8]">
<span className="shrink-0 opacity-60">{c.icon}</span>
<span className="leading-tight">{c.title}</span>
</a>
</li>
))}
</ul>
</nav>
<div className="min-w-0 flex-1 space-y-16">
{visible.length === 0 ? (
<p className="font-mono text-sm text-[#64748b]">No sections match that filter.</p>
) : (
visible.map((cat) => <AtlasCategorySection key={cat.id} cat={cat} query={q} />)
)}
</div>
</div>
</div>
);
}
function AtlasCategorySection({ cat, query }: { cat: AtlasCategory; query: string }) {
const subs = useMemo(() => {
if (!query.trim()) return cat.subsections;
const s = query.toLowerCase();
return cat.subsections.filter(
(sub) =>
sub.name.toLowerCase().includes(s) ||
sub.blurb.toLowerCase().includes(s) ||
sub.links.some((L) => L.title.toLowerCase().includes(s) || L.note.toLowerCase().includes(s)),
);
}, [cat.subsections, query]);
if (subs.length === 0) return null;
return (
<section id={cat.id} className="scroll-mt-28">
<div className="flex flex-wrap items-start gap-4 border-b border-[#1e293b] pb-4">
<span className="font-mono text-2xl text-[#38bdf8]/80">{cat.icon}</span>
<div>
<h2 className="font-mono text-xl font-bold text-[#f1f5f9] md:text-2xl">{cat.title}</h2>
<p className="mt-2 text-sm leading-relaxed text-[#94a3b8]">{cat.overview}</p>
<p className="mt-3 border-l-2 border-[#38bdf8]/50 pl-3 text-xs leading-relaxed text-[#7dd3fc]/90">{cat.literacy}</p>
</div>
</div>
<div className="mt-8 space-y-10">
{subs.map((sub) => (
<div key={sub.name} className="rounded-lg border border-[#1e293b] bg-[#0a0f18]/60 p-5">
<h3 className="font-mono text-sm font-bold uppercase tracking-wide text-[#7dd3fc]">{sub.name}</h3>
<p className="mt-2 text-sm text-[#94a3b8]">{sub.blurb}</p>
<ul className="mt-5 divide-y divide-[#1e293b] border border-[#1e293b] bg-[#070b12]/80">
{sub.links.map((link) => (
<li key={`${sub.name}-${link.title}`} className="p-4 transition-colors hover:bg-[#0f172a]/80">
<LinkRow href={link.href} title={link.title} note={link.note} />
</li>
))}
</ul>
</div>
))}
</div>
</section>
);
}