Orientation for AI coding assistants (and new contributors) working in this repo.
Read this first, then reach for README.md when you need full reference
detail (deployment recipes, integration URLs, complete design-system tables).
The official website for the 256 Foundation (256foundation.org) — a 501(c)(3)
nonprofit funding the open-source Bitcoin mining ecosystem. It's a content-driven
marketing/informational site: inform (mission, projects, ecosystem), fund (BTC/fiat +
hashrate donations), and recruit (grant applications). No database, no CMS, no auth —
all content lives in TypeScript files under data/ and MDX under content/.
- Repo:
git@github.com:256foundation/website.git(org:256foundation) - Hosting: Vercel (production deploys on push to
main; PRs get preview URLs)
npm install # install deps (Node 20 LTS+ required — uses AbortSignal.timeout)
npm run dev # dev server → http://localhost:3000
npm run build # production build (prerenders 19 routes; makes live network calls)
npm start # serve the production build
npm run lint # ESLint (next lint)
npm test # Node built-in test runner over tests/*.test.mjsThere is no separate typecheck script; npm run build runs tsc as part of the Next
build. strict mode is on (tsconfig.json). The @/* path alias maps to the repo root.
Next.js 15 (App Router, React 19, RSC-first) · TypeScript (strict) · Tailwind CSS v4 ·
next-mdx-remote + gray-matter (newsroom) · fast-xml-parser (Substack feed).
That is the entire runtime dependency set — no UI kit, CSS-in-JS, state library,
ORM, or 3D engine. Check package.json before assuming a library is available.
Tailwind v4 is configured CSS-first in app/globals.css via
@theme and @custom-variant — there is no tailwind.config.js. PostCSS config is
postcss.config.mjs.
Static-first with hourly ISR for pages that show live external data. Verified route map
(from next build):
| Route | Render | Notes |
|---|---|---|
/ |
Static + ISR (revalidate = 3600) |
fetches Substack, forum, GitHub org events |
/mission, /donate, /grants, /faq, /telehash |
Static | pure data-file content |
/newsroom |
force-static |
lists MDX posts |
/newsroom/[slug] |
SSG (generateStaticParams) |
MDX detail; force-static |
/projects |
Static + ISR (revalidate = 3600) |
grant log + live org repos/stats |
/projects/[slug] |
SSG + ISR (revalidate = 3600) |
4 slugs: ember-one, mujina, libre-board, hydrapool |
/api/hashdash |
Dynamic (force-dynamic) |
the only API route |
/robots.txt, /sitemap.xml |
Static | generated by app/robots.ts, app/sitemap.ts |
Root layout (app/layout.tsx) wraps everything with Header →
AnnouncementBanner → page → Footer, loads the three Google fonts, sets base
Metadata, and conditionally injects the Umami script (production + both Umami env vars).
app/ App Router pages (see route map above) + globals.css, robots.ts, sitemap.ts
components/
ui/ primitives (Button, Card, Badge, SectionWrapper, PCBBackground, …)
layout/ Header, Footer, MobileNav, NavDropdown, AnnouncementBanner, TelehashExtensionDetector
home/ home-page sections (Hero, DonateCards, StayUpdated, HashrateLeaderboard, ContactForm, …)
projects/ project-detail sections (PillarProjectCard, MilestoneTracker, GrantLogTable, ProjectForumSection, GitHubActivitySection, …)
newsroom/ PostCard, PostBody (MDXRemote wrapper)
shared/ TeamMemberCard, Timeline, NewsletterSignup, SubstackEmbed
telehash/ CountdownTimer, LeaderboardTable, PhotoCarousel, TeleHashEventCard
data/ ★ site content as typed TS — edit here, not in components
content/newsroom/*.mdx newsroom articles (frontmatter + markdown body)
lib/ server-side data fetchers (see below)
types/ all shared interfaces (types/index.ts)
public/ images: logos/ projects/ team/ supporters/{tier1,2,3}/ ecosystem/ newsroom/<slug>/ telehash/ og/
tests/ node --test suites
Almost all content edits happen in data/ — no component changes needed. Types for every
structure are in types/index.ts.
| File | Controls |
|---|---|
data/navigation.ts |
header nav + dropdowns (topNav) and footer links |
data/projects.ts |
the 4 pillar projects (pillarProjects): specs, milestones, team, GitHub + forum URLs |
data/grants.ts |
grant recipient log (grantLog) |
data/supporters.ts |
supporter logos by tier (supporters) |
data/team.ts |
founders + board |
data/stats.ts |
siteStats (BTC raised, blocks found, grantees) |
data/telehash.ts |
teleHashEvents, nextEventDate/nextEventDetails (countdown) |
data/faq.ts |
faqItems (categorized Q&A) |
data/donate.ts |
on-chain BITCOIN_ADDRESS + LIGHTNING_ADDRESS |
data/announcements.ts |
activeAnnouncement (banner) — null hides the banner |
Newsroom posts: add content/newsroom/<slug>.mdx with frontmatter
(title, date, author, category, excerpt, optional coverImage/ogImage).
Parsed by lib/newsroom.ts; sorted newest-first; the newest post
auto-surfaces on the home page. Article images go in public/newsroom/<slug>/.
All fetchers fail soft — on any error they return []/null/fallback so the page still
renders. GitHub/forum/Substack fetches use next: { revalidate: 3600 }.
lib/github.ts— GitHub REST: repo meta (stars/forks/issues/latest release), org repos, org stats, org events, recent commits. AddsAuthorization: Beareronly ifGITHUB_TOKENis set.lib/discourse.ts— Discourse forum (forum.256foundation.org): latest topics + per-project category topics; plusforumTopicUrl/timeAgohelpers.lib/substack.ts— parses the Substack RSS feed for post cards.lib/metadata.ts—generatePageMetadata(); every page uses it for OG/Twitter/canonical tags.app/api/hashdash/route.ts— live hashrate leaderboard: 3 parallel Prometheus queries againstpool.256foundation.org/api/v1/query, resolvesnpub…identities to Nostr names/avatars via Primal (10-min in-memory cache), 5s per-call timeout,503on upstream failure.
Contact form (components/home/ContactForm.tsx) POSTs directly to Formspree
(formspree.io/f/xkndjepy) client-side — no server route.
Defined as tokens in app/globals.css. Full tables are in the README;
the rules that matter when writing UI:
- No border radius — everything is
rounded-none(square corners). Intentional. - Purple is the only accent —
#3b1445(light) /#c084d8(dark). No orange. - Terminal green
#00FF41= live/success only — status dots, live indicators. - Depth via borders, not shadows —
#1f1f1fborders in dark mode. - Uppercase display headings — Barlow Condensed (
font-display); Space Mono (font-mono) for labels/buttons/nav/stats; Inter (font-sans) for body. - Dark mode is the primary experience, driven by
@media (prefers-color-scheme)— not a toggle. Thedark:variant is remapped to that media query via@custom-variant, so there is no.darkclass and no theme switcher. Style both modes. - Use
→(→) for directional UI, not chevrons.
All optional — the site builds and runs with none (graceful fallbacks). Only these are
actually read by code: NEXT_PUBLIC_SITE_URL, NEXT_PUBLIC_ZAPRITE_URL,
NEXT_PUBLIC_UMAMI_WEBSITE_ID, NEXT_PUBLIC_UMAMI_URL, GITHUB_TOKEN, plus Vercel's
auto VERCEL_URL. See .env.example, which also lists removed vars to
avoid (Resend, Hashdash, Typeform) so they don't creep back in.
ARCHITECTURE.mdandSPEC.mdare stale/aspirational. They describe a Three.js + GSAP 3D scroll experience and a Resend/api/contactroute that were never shipped. Both files now carry a warning banner at the top. Trust this file, the README, and the code — not those two for current implementation detail. (The orphanedHardwareProjectViewer/HashStreamCanvasplaceholder components and the emptyapp/api/contact/directory those docs referenced have since been removed.)- Discourse slug typo: Libre Board's forum category is
fibre-board(legacy), notlibre-board. SeeforumCategoryApiUrlindata/projects.ts— don't "fix" it. - TeleHash browser-extension coexistence: a Chrome extension injects a fixed 115px
topbar at a huge z-index.
components/layout/TelehashExtensionDetector.tsx+ the--ext-offsetCSS var +.site-main/header styles inglobals.csshandle this. Be careful editing fixed-position header/offset styling. - Grant cycle is currently closed — the
/grantsapply CTA andNEXT_PUBLIC_TYPEFORM_URLare intentionally removed; re-add when a cycle reopens. - Mining pool address
pool.256foundation.orgappears as hardcoded strings inapp/donate/page.tsxandapp/telehash/page.tsx(not in a data file).
README.md— full reference: deployment (Vercel / Proxmox / Coolify / Netlify / Railway), integration URLs, complete design-system tables, content-update recipes.ARCHITECTURE.md/SPEC.md— original design intent (see stale-warning banners at their tops).discourse-header-prompt.md— one-off prompt for matching the Discourse forum header to the site header; not part of the app build.