/** Interactive Page schema v1 — caps & allowlists (spec Kimi / AttnRes). */ export const INTERACTIVE_PAGE_SCHEMA_VERSION = 1 as const export const INTERACTIVE_PAGE_CAPS = { maxSections: 8, maxBlocksPerSection: 12, maxDemosPerPage: 5, maxSimsPerPage: 3, maxOverviewCards: 4, minOverviewCards: 2, maxStatsItems: 5, minStatsItems: 2, maxJsonBytes: 128 * 1024, } as const export const SIM_CAPS = { maxParams: 4, maxComputed: 6, maxExprChars: 200, } as const export const PAGE_BLOCK_TYPES = [ 'prose', 'formula', 'callout', 'demo', 'chart', 'stats', 'table', 'image', 'sim', ] as const export const CALLOUT_KINDS = [ 'definition', 'warning', 'tip', 'note', ] as const /** * Human / locale strings — may contain hex in prose; skipped by color scan. * Must stay in sync with validate + translate strip. */ export const PAGE_HUMAN_STRING_KEYS = [ // page-level 'lang', 'kicker', 'title', 'subtitle', 'meta', 'lead', 'badge', 'body', 'footer', // blocks 'md', 'tex', 'caption', 'alt', 'value', 'label', 'columns', 'rows', // sim blocks 'symbol', 'expr', 'intro', 'xLabel', 'yLabel', // inherited from demos (speak etc. scanned via demo validator) 'speak', 'text', 'disclaimer', 'rowLabels', 'colLabels', ] as const export type PageHumanStringKey = (typeof PAGE_HUMAN_STRING_KEYS)[number] const PAGE_HUMAN_SET = new Set(PAGE_HUMAN_STRING_KEYS) export function isPageHumanStringKey(key: string): boolean { return PAGE_HUMAN_SET.has(key) }