type MinimalTheme = { dim: (s: string) => string; bold: (s: string) => string; accentSoft: (s: string) => string; }; export const defaultWaitingPhrases = [ "flibbertigibbeting", "kerfuffling", "dillydallying", "twiddling thumbs", "noodling", "bamboozling", "moseying", "hobnobbing", "pondering", "conjuring", ]; export function pickWaitingPhrase(tick: number, phrases = defaultWaitingPhrases) { const idx = Math.floor(tick / 10) % phrases.length; return phrases[idx] ?? phrases[0] ?? "waiting"; } export function shimmerText(theme: MinimalTheme, text: string, tick: number) { const width = 6; const hi = (ch: string) => theme.bold(theme.accentSoft(ch)); const pos = tick % (text.length + width); const start = Math.max(0, pos - width); const end = Math.min(text.length - 1, pos); let out = ""; for (let i = 0; i < text.length; i++) { const ch = text[i]; out += i >= start && i <= end ? hi(ch) : theme.dim(ch); } return out; } export function buildWaitingStatusMessage(params: { theme: MinimalTheme; tick: number; elapsed: string; connectionStatus: string; phrases?: string[]; }) { const phrase = pickWaitingPhrase(params.tick, params.phrases); const cute = shimmerText(params.theme, `${phrase}…`, params.tick); return `${cute} • ${params.elapsed} | ${params.connectionStatus}`; }