/** * Pure, DOM-free registry of every tool's STATIC presentational classes. * * Both the editor's block tools and the view's emitters read from here, which * is what makes view↔read-only visual parity structurally impossible to drift * (enforced by `test/unit/view/golden-harness.test.ts`, guarantee 4). * * Two hard constraints on every module in this directory: * * 1. PURE — no DOM, no `twMerge` at call time. Export `readonly string[]`; the * consumer merges. `src/view/*` may only import from `src/shared/*` (its * purity contract, enforced by * `test/unit/architecture/view-entry-law.test.ts`), and importing anything * that touches `globalThis.window` at module load would break Node rendering. * 2. ENUMERABLE — every class a module can emit must be reachable from * {@link ALL_STATIC_CLASSES}, because `scripts/generate-view-css.mjs` * generates the stylesheet from it and the view-stylesheet law asserts that * each one has a matching rule. For data-dependent tools that means * enumerating every variant, not just the default. * * Edit-only classes (placeholders, focus rings, hover affordances, resize * grips, `group/*` markers) do NOT belong here — they stay at the tool's call * site. * * NAMING IS LOAD-BEARING. `test/unit/styles/tailwind-class-emits-law.test.ts` * only harvests class strings from identifiers matching * `(?:^|_)(?:CLASS|CLASSES|STYLES)$`. Every export holding class strings in this * directory MUST end in `_CLASS` or `_CLASSES`, or its classes silently fall out * of that law's coverage and a dead Tailwind token can ship unnoticed. Moving * classes here from a tool already caught one such near-miss. */ import { CALLOUT_CHILDREN_CLASSES, CALLOUT_WRAPPER_CLASSES } from './callout'; import { CODE_AREA_CLASSES, CODE_WRAPPER_CLASSES } from './code'; import { DIVIDER_RULE_CLASSES, DIVIDER_WRAPPER_CLASSES } from './divider'; import { HEADER_LEVEL_CLASSES, headerClasses } from './header'; import { LIST_CHECKBOX_CLASSES, LIST_CHECKLIST_ROW_CLASSES, LIST_CONTENT_CLASSES, LIST_ITEM_CLASSES, LIST_ITEM_ROW_CLASSES, } from './list'; import { PARAGRAPH_CLASSES } from './paragraph'; import { quoteClasses } from './quote'; import { SPACER_WRAPPER_CLASSES } from './spacer'; import { TOGGLE_CHILDREN_CLASSES, TOGGLE_CONTENT_CLASSES, TOGGLE_HEADER_ROW_CLASSES, TOGGLE_WRAPPER_CLASSES, } from './toggle'; /** Static classes for tools whose set does not vary with block data. */ const STATIC_BY_TOOL: Record = { paragraph: PARAGRAPH_CLASSES, code: CODE_WRAPPER_CLASSES, callout: CALLOUT_WRAPPER_CLASSES, toggle: TOGGLE_WRAPPER_CLASSES, divider: DIVIDER_WRAPPER_CLASSES, spacer: SPACER_WRAPPER_CLASSES, /** * Each list ITEM is its own block, so these land on the `
  • ` — never on the * grouping `