/** * 套餐总览 (usage-mix) — the cross-platform quota board, 2×2. * * ┌ 套餐总览 ──────────────╭───╮┐ * │ 92M │86%││ 标题 → 今日用量 20px → 右上角占用环形 * │ 重置 2h13m ╰───╯│ 灰字 = 最紧窗口的回血倒计时 * │ ─────────────────────────────│ 发丝分隔线 * │ 今日 92M │ 今日永远第一行(灰) * │ Command Code 86.0% │ 每个平台取自己最紧的窗口 * │ OpenCode Go 42.0% │ * └──────────────────────────────┘ * * TODAY FIRST (the owner's convention): the card leads with what the machine * actually SPENT, and `today` is the FIRST body row and never moves. The head * carries a DIFFERENT reading rather than repeating it — the headline figure is * today's tokens, the grey caption under it is when the tightest plan refills, * and the RING in the top-right corner is that plan's occupancy (the「缓存命中」 * head-donut shape the owner pointed at, with the urgency ramp INVERTED: there a * high number is good (green), here a high number means a plan about to block). * * WHY ONE WINDOW PER ROW: OpenCode Go carries three windows and Command Code two * to three; a seven-column chart on a 150px tile is not a glance. Each ROW is a * POOL (the platform name, or `Command Code Ⅱ` for its second key pool), * reduced to the window closest to its cap — the binding one, which is what * "would I be blocked" asks. The per-window cards (usage-rolling/weekly/monthly, * cc-window-*) keep the full window-by-window breakdown. * * ── SIZE: 2×2 ONLY (owner's call, 2026-09-28) ───────────────────────────────── * The 2×4 was dropped. On the shared geometry (card-geometry.ts — pad 12, so a * 150px card's content box is 126px tall) its extra WIDTH could only buy a longer * reset line and one more pool row, never a chart: the available `bars` chart is * a FIXED 69px block (charts/bars.tsx: 56 + 4 + 9) and `barsV` is 77px, so * neither shares a 126px box with a head and three rows of data. A wide variant * would have been the same card with more chrome — so there is one size, one * shape, and the vertical rhythm below is tuned to it. * * HEIGHT AUDIT (why the rows stop at three): title 16 + headAfter 4+25 + caption * 2+12 + 3 rows (3·16 − 4 = 44) + the breakdown's 6px padding-top and 1px * hairline = 120 of the 126px content box. The head's RING (a 52px donut) raises * the head BLOCK to ~80px, so a fourth row would sit past the floor; MAX_ROWS = 3 * (今日 + two pools) and the ranking below decides WHICH pools get those rows. * * NOTHING IS FABRICATED: a platform that is not configured at all is not drawn * (its row would be a permanent `—`), while a pool payload that answered with a * key whose slice did not keeps that key's row and prints `—` muted. Only when * nothing at all is configured does the card return null. Each row group can be * switched off in the component config — the explicit way to retire a plan (e.g. * an OpenCode subscription no longer renewed) without losing the card. * * ── TONE ───────────────────────────────────────────────────────────────────── * The widget owns the direction (the renderer never guesses): quota occupancy — * HIGH IS BAD. <75% success, ≥75% warn, ≥95% danger, no reading muted, for both * the rows and the ring. The 今日 row is deliberately `muted` always: tokens * spent are information, not danger. * * All reads are the sync projections the collector already folds; the math * (normalisation, the per-pool reduction, the countdown) lives here, pure. * `Date.now()` is read for the countdown and the local day key (display only). */ import type { WidgetRenderOut, WidgetStats } from '../../client/lib/contract/types'; declare function usageMixRender(stats: WidgetStats): WidgetRenderOut | null; /** * Preview: a live-shaped pair of plans, BOTH with key pools, so the market * preview shows the whole board — two OpenCode pools, two Command Code pools * (`Command Code` and `Command Code Ⅱ`), the muted 今日 row, the ring and the * countdown. The ranking is exercised by the example itself: the row cap hides * the least loaded pool, and the round-robin keeps both platforms on the tile. * Every value is deterministic; only the countdown moves with the clock. */ declare function previewStats(): Partial; declare const _default: { id: string; name: () => string; desc: () => string; builtin: true; group: string; sizes: "2x2"[]; render: typeof usageMixRender; configSchema: { key: string; label: () => string; type: "toggle"; default: true; }[]; example: { stats: typeof previewStats; }; }; export default _default;