Files
zeekay 4fd349aa06 beta: the portal says less, and opting in and sharing are one press
Prose that carried no decision or fact is gone: the hero, the questions, the
gate and every step are a heading and at most a line. What scores is said once
(the leaderboard step), and every claim the cloud does not keep is out.

Step 1 is one share card (the member's link, Copy, the device's share sheet on
phones, seven channels as icons, Customize behind a text button) and a quiet
invite-by-email card. Step 3 is one searched, grouped list with one control a
row: On when `opens` says so, Get access when it does not, Requested at once
after the press. Stars and follows moved under the leaderboard as Earn more.

The 1,800-line dashboard is a shell over share, rank, betas and alpha; what
they read is one hook (standing.ts); the questions are data (program.ts).
Dead access, card, hint and referral components are deleted. Every press is
44px, every input too, and a gate walks each screen at 390px.

scripts/brands and scripts/prebuild are TypeScript now; the three marks the
share row draws ship in a JSON only /beta loads. /beta's title and card say
what the page says.

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

31 lines
1.7 KiB
TypeScript

/**
* The brand marks components/brand.tsx draws, written from simple-icons.
*
* simple-icons is ONE module holding every icon it publishes, and webpack keeps
* the exports the whole build uses in that one module. So a page that drew one
* mark from it shipped every mark any module of the build imports: measured on
* 2026-10-16, 26 icons (the marks below and @hanzo/app' network marks), 8.8 KB of
* brotli on 107 pages, 65 of them over perf.budget.json, for the GitHub glyph a
* product page draws. The paths are written here from the installed package
* on every build, so they are taken from it and never transcribed.
*/
import { writeFileSync } from 'node:fs'
import { siApple, siBluesky, siFacebook, siGithub, siGoogle, siGooglechrome, siHuggingface, siInstagram, siReddit, siX, siYcombinator } from 'simple-icons'
/** The marks every page may draw: one JSON, which every page that imports components/brand carries whole. */
const MARKS = { apple: siApple, github: siGithub, x: siX, instagram: siInstagram, facebook: siFacebook, chrome: siGooglechrome, google: siGoogle, huggingface: siHuggingface }
/** The marks the share row of /beta draws, in a JSON of their own so no other page carries them. */
const SHARE = { bluesky: siBluesky, reddit: siReddit, ycombinator: siYcombinator }
const write = (file: string, marks: Record<string, { path: string }>) => {
const paths = Object.fromEntries(Object.entries(marks).map(([name, icon]) => [name, icon.path]))
for (const [name, d] of Object.entries(paths)) {
if (!/^M[\d.\-\s]/.test(d)) throw new Error(`simple-icons gave ${name} no path`)
}
writeFileSync(new URL(`../lib/data/${file}`, import.meta.url), `${JSON.stringify(paths, null, 2)}\n`)
}
write('brands.json', MARKS)
write('share-marks.json', SHARE)