1import type { ReactNode } from "react";2import Link from "@docusaurus/Link";3import useDocusaurusContext from "@docusaurus/useDocusaurusContext";4import Layout from "@theme/Layout";5import NodePlayground from "../components/NodePlayground";6import TicketAnatomy from "../components/TicketAnatomy";7import SliceMerge from "../components/SliceMerge";89import "../css/landing.css";10import "../css/node-landing.css";1112// The /node landing: lofi-node's front door. Shares the brand tokens with the13// root landing but none of its furniture. The page is three interactive14// rigs: a node you operate, a ticket you open, and a store two apps share.15// lofi-node is an END USER capability (owning where their data syncs), not a16// way to host a lofi app; the copy keeps that audience.1718export default function NodeHome(): ReactNode {19 const { siteConfig } = useDocusaurusContext();20 const version = siteConfig.customFields?.lofiNodeVersion as string;2122 return (23 <Layout24 title="lofi-node"25 description="lofi apps let their users choose where data syncs. lofi-node makes that choice real. One daemon a user runs, with an embedded Jazz sync server, iroh node-to-node transport, and a ticket-based access gate."26 >27 <main className="landing landing--node">28 {/* ===================== HERO: MARK + THE PLAYABLE NODE ===================== */}29 <div className="wrap">30 <header className="node-hero">31 <div className="node-hero-top">32 <h1 className="nmark" aria-label="lofi-node">33 <span className="lo">lo</span>34 <span className="fi">fi</span>35 <span className="dash">-</span>36 <span className="node">node</span>37 </h1>38 <div className="node-hero-side">39 <p className="eyebrow">40 <span>user-owned sync</span>41 <span className="pill">v{version} · alpha · MIT</span>42 </p>43 <div className="cta-row">44 <Link45 className="btn btn--primary"46 to="/node/docs/self-host-a-sync-node"47 >48 Host your first node49 </Link>50 <Link className="btn" to="/node/docs">docs</Link>51 <Link52 className="btn"53 href="https://github.com/FelineStateMachine/lofi-node"54 >55 source56 </Link>57 </div>58 </div>59 </div>60 <NodePlayground />61 </header>62 </div>6364 {/* ===================== TICKET ANATOMY ===================== */}65 <div className="wrap">66 <section className="band band--rule">67 <div className="band-head">68 <p className="eyebrow">A singular entry</p>69 <h2>Open the ticket.</h2>70 <p className="lede band-lede">71 No accounts, no OAuth, no server-side user table. A{" "}72 <code className="inline-mono">lofisync1.</code>{" "}73 string carries the store's identity and a bearer secret riding74 the URL path, which is why the app needs zero changes to sync75 somewhere new. Click a field.76 </p>77 </div>78 <TicketAnatomy />79 <p className="dim intro-note">80 The normative spec lives with the node and renders here from the81 pinned source:{" "}82 <Link to="/node/docs/app-ticket">the app-ticket contract</Link>.83 <br />84 Both repos test against the same conformance fixtures, so the85 string above can't drift quietly.86 </p>87 </section>88 </div>8990 {/* ===================== SHARED STORE ===================== */}91 <div className="wrap">92 <section className="band band--rule">93 <div className="band-head">94 <p className="eyebrow">many apps, one store, no folklore</p>95 <h2>Apps are tenants. The store is yours.</h2>96 <p className="lede band-lede">97 A user's node can hold several lofi apps' data at once. Each app98 may provision only the tables under its own namespaces;99 everything else, a neighbor's tables{" "}100 <em>and its access rules</em>, rides through byte-for-byte. Run101 the story below; every step of it is a real, conformance-tested102 flow.103 </p>104 </div>105 <SliceMerge />106 <p className="dim intro-note">107 The full model:{" "}108 <Link to="/node/docs/sliceable-apps-and-shared-stores">109 sliceable apps and shared stores110 </Link>{" "}111 and the hands-on version,{" "}112 <Link to="/node/docs/provision-a-store">113 provision a store114 </Link>.115 </p>116 </section>117 </div>118119 {/* ===================== HONESTY + PATHS ===================== */}120 <div className="wrap">121 <section className="band band--rule">122 <div className="two-up">123 <div>124 <div className="band-head band-head--tight">125 <h2>Still curious?</h2>126 </div>127 <ul className="limits">128 <li>129 <b>The data plane is Jazz 2 alpha, pinned exactly.</b>{" "}130 A node must run the same alpha as the apps it serves; bumps131 are coordinated.132 </li>133 <li>134 <b>Windows runs LAN-only.</b>{" "}135 A documented native-build gap; the store works, pairing136 reports itself unavailable instead of degrading silently.137 </li>138 <li>139 <b>Tickets are bearer credentials.</b>{" "}140 Plain http is for trusted LANs; beyond one, front the gate141 with TLS.142 </li>143 <li>144 <b>Storage is SQLite or memory</b>, the engine's honest145 surface today. Replicate the file for off-site durability.146 </li>147 </ul>148 </div>149 <div>150 <div className="band-head band-head--tight">151 <h2>Keep going.</h2>152 </div>153 <ul className="node-paths">154 <li>155 <b>156 <Link to="/node/docs/self-host-a-sync-node">157 Self-host a node158 </Link>159 </b>: compile, init, ticket, enroll.160 </li>161 <li>162 <b>163 <Link to="/node/docs/pair-two-homes">Pair two homes</Link>164 </b>: hole-punched, no static IPs.165 </li>166 <li>167 <b>168 <Link to="/node/docs/provision-a-store">169 Provision a store170 </Link>171 </b>: the merge, end to end.172 </li>173 <li>174 <b>175 <Link to="/node/docs/tickets-explained">176 Tickets explained177 </Link>178 </b>: scopes, revocation, posture.179 </li>180 <li>181 <b>182 <Link to="/node/docs/cli">CLI</Link> ·{" "}183 <Link to="/node/docs/configuration">Configuration</Link> ·184 {" "}185 <Link to="/node/docs/http-surface">HTTP</Link>186 </b>: the reference shelf.187 </li>188 <li>189 <b>190 <Link to="/node/api">API reference</Link>191 </b>: <code className="inline-mono">createSyncNode</code>192 {" "}193 and friends, generated from source.194 </li>195 <li>196 <b>197 <Link to="/node/llms.txt" target="_blank">198 /node/llms.txt199 </Link>200 </b>: the node corpus for agents, separate from the201 framework's.202 </li>203 </ul>204 </div>205 </div>206 </section>207 </div>208 </main>209 </Layout>210 );211}