Each release ships with its receipt: what changed, why, and the exact lines that landed.
Added a /code route that renders the full source of every key file with line numbers and a copy button. Nothing hidden — every line of the temple in the open.
1import rootRaw from "../routes/__root.tsx?raw";2import indexRaw from "../routes/index.tsx?raw";3import explorerRaw from "../routes/explorer.tsx?raw";4// ... ?raw imports inline the source at build time5 6const FILES = [7 { path: "src/routes/__root.tsx", code: rootRaw },8 { path: "src/routes/index.tsx", code: indexRaw },9 { path: "src/routes/explorer.tsx", code: explorerRaw },10 // ...11];useState initializer ran Math.random() during SSR and again on the client, producing different block data and breaking hydration. Moved seeding into useEffect so the server renders an empty stream and the client fills it after mount.
1function ExplorerPage() {2 const [blocks, setBlocks] = useState<Block[]>([]);3 const [mounted, setMounted] = useState(false);4 5 useEffect(() => {6 setBlocks(7 Array.from({ length: 14 }, (_, i) => ({8 ...makeBlock(SEED_HEIGHT - i),9 age: `${i * 6 + 4}s ago`,10 })),11 );12 setMounted(true);13 }, []);14}Live block stream with search, tag filters (DREAM / ORACLE / CORE / DEPLOY / DOCS / CHORE), a stats grid, and a streaming ping. New block every 4s.
1const SEED_HEIGHT = 429_256;2 3function makeBlock(height: number): Block {4 const pick = MSGS[Math.floor(Math.random() * MSGS.length)];5 return {6 height,7 hash: "0x" + rhex(40),8 tag: pick.tag,9 msg: pick.msg,10 cycle: 1204 + Math.floor(height / 1000),11 age: "just now",12 txs: Math.floor(Math.random() * 32) + 1,13 };14}Added IntersectionObserver-driven reveal animations, an animated aurora backdrop, gold shimmer text, and lift hover on cards. Respects prefers-reduced-motion.
1export function Reveal({ children, delay = 0, className = "" }: RevealProps) {2 const ref = useRef<HTMLElement | null>(null);3 const [visible, setVisible] = useState(false);4 5 useEffect(() => {6 const io = new IntersectionObserver(7 (entries) => {8 for (const e of entries) {9 if (e.isIntersecting) { setVisible(true); io.disconnect(); break; }10 }11 },12 { threshold: 0.12, rootMargin: "0px 0px -60px 0px" },13 );14 if (ref.current) io.observe(ref.current);15 return () => io.disconnect();16 }, []);17}Added the official CA strip to the hero with a one-click copy.
1const CA = "HH5Gu1eF2FJKyPufm28omEQfs22MXQsyXWZZvDe6pump";2 3<button onClick={() => navigator.clipboard.writeText(CA)}>4 CA · {CA.slice(0, 6)}…{CA.slice(-6)}5</button>Stripped GitHub references from nav, footer, and docs. HYPNOS ships from on-chain governance, not pull requests.
1- <a href="https://github.com/hypnos">GitHub</a>2+ // removed — source ships via /code and on-chain commitsNew gold-statue favicon and refreshed og:image / twitter:image for shareable previews.
1links: [2 { rel: "stylesheet", href: appCss },3 { rel: "icon", type: "image/png", href: "/favicon.png" },4],Landing page, terminal panel, pantheon of deities, talk + docs routes, dark/gold mythic identity.
1export const Route = createFileRoute("/")({2 component: HomePage,3});