mirror of
https://github.com/hanzo-apps/longform-essays.git
synced 2026-10-30 19:12:21 +00:00
Vite + React 19 + @hanzo/gui + @hanzo/iam + @hanzo/base, forked from hanzo-starter. Three views (year-grouped index, distraction-free reading column with drop-cap, markdown editor with publish toggle) over an org-scoped essays collection in Hanzo Base. Warm-paper editorial design.
3.1 KiB
3.1 KiB
longform-essays — agent notes
A minimalist personal essay blog on the canonical Hanzo stack: Vite + React 19 +
@hanzo/gui (UI) + @hanzo/iam (auth) + @hanzo/base (data). Forked from
hanzo-apps/hanzo-starter; the provider stack, vite.config.ts, auth, and
deploy contract are the starter's and stay identical. Keep it REAL — every
surface must build and run, no fabricated UI.
What this app is
- Three views, no router:
contents(year-grouped index) →reader(distraction-free column) →editor(title/subtitle/markdown + publish toggle).src/views/home.tsxis a small state machine that swaps between them. - Data is the
essayscollection (seeschema.sql+src/lib/essays.ts).collections+essay_collectionsare provisioned for series grouping. - Design is warm-paper editorial: cream sheet, book serif, one narrow reading
measure (~66ch), drop-cap opening, footnote-gray metadata. Palette is one place
(
src/lib/theme.ts).
Gotchas (do not regress)
@hanzo/guiunder Vite needs three things invite.config.ts(unchanged from the starter): (1) aliasreact-native→react-native-web, (2)defineprocess.env.TAMAGUI_TARGET/NODE_ENV/__DEV__, (3)dedupereact/react-dom/react-native-web. No@hanzogui/vite-plugin.@hanzo/guiprops are Tamagui LONGHAND:alignItems/justifyContent/backgroundColor/padding/alignSelf/borderRadius/textAlign— NOT theitems/justify/bg/p/self/rounded/textshorthands. Shorthands pass at runtime but FAILtsc.ButtonusesonPress;Input/TextAreausevalue/onChangeText.- Serif + drop-cap live in
index.html, not props.fontFamilyas a raw string is not a valid gui prop (it wants a font token), and::first-letterhas no style-prop equivalent — so the book serif (#root, #root *) and the drop-cap (.lf-drop) are one small id-scoped CSS block. Everything else (colour, spacing, size, weight, leading) is Tamagui longhand props. This is the app's typography, not a second UI kit. - Colours are raw hex from
src/lib/theme.tsoncolor/backgroundColor/borderColor(Tamagui accepts arbitrary colour strings). One place for the palette. - Auth reads
VITE_IAM_CLIENT_ID(fallbackhanzo-app) insrc/env.ts. - PKCE storage is
localStorageso the verifier/state survive the hanzo.id round-trip. schema.sqlis the data contract (provisionBaseFromDDL). Keep it in lockstep withsrc/lib/essays.ts.
Deploy contract (Hanzo Cloud)
- Static SPA:
npm run build→dist/, served at<slug>.hanzo.app. No server. - On publish,
schema.sql→ Base collections (org-scoped, IAM-native,@request.auth.org_id = org). Runtime read/write is browser →VITE_HANZO_BASE_URLwith the IAM token. - IAM redirect registration is the one external requirement: the client
(
VITE_IAM_CLIENT_ID) must allow this origin's/auth/callback.
Build
CI (.github/workflows/ci.yml) runs npm ci && npm run typecheck && npm run build — build-verification only, NEVER a container image (Hanzo Cloud owns
deploys; do not build images locally).