Files
zeekay 70349b34c7 beta: a post about one topic, with that topic's page and card
The share card offers Hanzo, the products and the betas the member asked
for, the rest under More by group. A topic picks the posts Shuffle offers,
the link (/beta/for/<topic>, tagged utm_content) and the card it unfurls
to: that page carries the topic's title, line and card, a canonical naming
itself and the one noindex (lib/publish SHARES), and sends a person on to
/beta with the query kept, so ref and the campaign land as before.

lib/hanzo/topics is the list, its words the site's and BETAS's own.
generate-og draws a card per topic from it, palette-quantized with sharp:
49 cards, 2.9 MB. The cards gate reads every card's rendered words.

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

30 lines
1.7 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { phrase } from '@hanzo/i18n'
/**
* What a member may post about the beta: a line each, every one made of words
* Hanzo's own pages already say (the home page, /beta, /pricing, hanzo.bot and
* Tabs), so none of them claims what a reader cannot check. The link is the
* channel's, appended with the member's code, never part of the line.
*/
export const MESSAGES = [
{ id: 'every-model', text: phrase('Every model. One API. Your price. I’m early on Hanzo.') },
{ id: 'pick-three', text: phrase('Better, faster, cheaper. Pick three. Early access to Hanzo’s Dev, Studio, Kai, Enso and Zen is open.') },
{ id: 'build', text: phrase('Describe an app, an agent or a company, and Hanzo builds it, ships it and runs it. I’m in the beta.') },
{ id: 'dev', text: phrase('Hanzo Dev, the coding agent, is in beta. I’m on it.') },
{ id: 'tabs', text: phrase('Keep tabs on your agents. Hanzo Tabs is part of the beta.') },
{ id: 'teammates', text: phrase('AI teammates you can hand real work to: Hanzo Bot. I’m early.') },
{ id: 'one-app', text: phrase('Chat, Dev, Studio and Tabs in one app. I’m in the Hanzo beta.') },
{ id: 'board', text: phrase('I’m on the Hanzo beta board. A signup from my link moves me up.') },
] as const
/** The longest post a member may write: what X takes, less the link it counts for 23. */
export const LONGEST = 240
/** One of `count` lines other than the one shown, chosen at random; the only line when there is one. */
export function another(now: number, count: number, pick: () => number = Math.random): number {
if (count < 2) return 0
if (now < 0 || now >= count) return Math.floor(pick() * count)
const next = Math.floor(pick() * (count - 1))
return next >= now ? next + 1 : next
}