Files
hanzo.ai/app/_web.tsx
zeekay ca39f476a7 beta: the portal sits on the pane, and every claim is one the server keeps
In the app the portal painted the site's page glow, an opaque slab, over
the pane's own fill, inset by the pane's padding. It takes `framed` now:
no glow, no window height, the pane's fill and scroll.

The dashboard counted points the server does not award (local actions,
+25 for asking for Alpha) and promised rewards nothing pays (48 spots, a
free week, 10% tokens back, +1 per $1, "Linked:" on every account). The
score is the server's `score` once it answers one; until then verified
points plus the referrals it counts. The copy states what scores:
+1 per signup, +20 per referral that pays, +1 per 100K tokens, +10 per
star, +1 per follow.

Claude-Session: https://claude.ai/code/session_017vrVus6PPBgP5YRzKV1iqW
2026-10-26 01:13:24 -07:00

50 lines
2.4 KiB
TypeScript

'use client'
// The web app, for a signed-in reader: @hanzo/app' `App`, the column, Chat,
// Dev and Studio in one window, mounted under this site's router with the path
// it reads (@hanzo/app lib/host `talk`, `app`, `studio`, `place`). `/` and
// `/chat` are Chat on a new conversation, `/chat/<id>` one of the reader's, a
// path under `/dev` is Dev and one under `/studio` Studio. Every page draws this
// one app (app/page.tsx at `/`, app/(app)/chat/_door.tsx at `/chat`,
// app/dev/_door.tsx at `/dev`, app/studio/_door.tsx at `/studio`, and by the
// edge every path under each), so moving between the modes is a history entry
// and never a load.
//
// THE ORGANIZATION COMES FIRST, and `App` mounts its gate itself
// (@hanzo/app `Orgs`): a reader with none makes one and a reader with several
// picks one. No plan stands in front of the app, whatever the organization's:
// what it may spend is the API's to meter, per plan, on every call, and the
// per-seat Team plan is hanzo.team's to ask for. A stranger is sent to sign in
// (destination.ts `enter`) and drawn nothing.
//
// Its own module because `_apex.tsx` loads it only for a signed-in reader: the
// app is some 200 KB of gzipped script, and a stranger reading the landing
// downloads none of it (e2e/gates/weight.spec.ts holds the landing's budget).
import dynamic from 'next/dynamic'
import { usePathname } from 'next/navigation'
import { App as Rooms } from '@hanzo/app/App'
import { RoomsHost } from '@/components/app'
/** The beta portal (components/beta/portal.tsx), fetched when Betas opens. It is
* the pane of the app's Betas mode however the reader got there — /beta, the
* rail, or a link inside the app — never @hanzo/app's plain list. */
const Portal = dynamic(() => import('@/components/beta/portal').then((m) => m.Portal), { ssr: false })
export default function App() {
const path = usePathname()
const isDesktop = typeof window !== 'undefined' && Boolean((window as unknown as { __TAURI__?: unknown; __TAURI_INTERNALS__?: unknown }).__TAURI__ || (window as unknown as { __TAURI__?: unknown; __TAURI_INTERNALS__?: unknown }).__TAURI_INTERNALS__)
const bar = isDesktop
? {
inset: typeof navigator !== 'undefined' && /Mac/.test(navigator.userAgent) ? 78 : 0,
drag: { 'data-tauri-drag-region': 'deep' },
}
: undefined
return (
<RoomsHost path={path}>
<Rooms bar={bar} betas={<Portal framed />} />
</RoomsHost>
)
}