/**
 * The per-item colour palette is opt-in per diagram. A shape or container stamps a
 * `data-color-id` slot on its rendered element, and the diagram's stylesheet maps that
 * slot to a border and fill. Both halves need the same answers to the same three
 * questions — is this a colour theme, does it actually carry a palette, and which slot
 * does this item get — so they live here rather than being restated per diagram.
 *
 * Before this module the `COLOR_THEMES` list existed in five copies and the stamping
 * block was duplicated verbatim between `clusters.js` and `classBox.ts`. Two idioms for
 * the same gate had already appeared: `er/styles.ts` keys off the theme name while
 * `requirement/styles.js` keys off the array being non-empty. Anything added here is
 * added once.
 */
import type { D3Selection } from '../../types.js';
/** Themes that carry a categorical palette for per-item colouring. */
export declare const COLOR_THEMES: Set<string>;
/** How many palette slots to emit when the theme does not say. */
export declare const DEFAULT_COLOR_SLOTS = 12;
/**
 * Upper bound on slots. Every shipped palette has 12 entries, so this is generous -- it
 * exists to bound the loop, not to express a design limit. See `colorSlotCount`.
 */
export declare const MAX_COLOR_SLOTS = 64;
/**
 * A palette array is usable only if it is genuinely a non-empty array. A truthy `.length`
 * check passes for a plain string too, which would yield a per-character "palette" and
 * declarations like `stroke: r;`.
 */
export declare const hasPalette: (palette: unknown) => palette is string[];
/** Whether `theme` should render per-item colour at all. */
export declare const isColorTheme: (theme: string | undefined, palette: unknown) => boolean;
export declare const safeLook: (look: unknown) => string;
/**
 * Number of palette slots a stylesheet should emit.
 *
 * With a palette, this is exactly `palette.length` -- not the limit, not a cap. That is not
 * a policy choice: `stampColorSlot` assigns `colorIndex % palette.length`, so the ids it
 * can produce are precisely `0 .. palette.length - 1`. Emitting fewer leaves items stamped
 * with no rule to match, and emitting more is dead CSS. Deriving both from the same length
 * is what makes the two impossible to disagree, rather than something a bound has to keep
 * lined up.
 *
 * Three separate bugs came out of letting these drift apart -- a limit longer than the
 * palette, a palette longer than the limit, and then a palette longer than the cap that was
 * added to bound the limit. `paletteSlotCount` below is the single source of truth for both
 * sides, and `slotsAgree` in the spec pins that they never diverge again.
 *
 * `THEME_COLOR_LIMIT` still governs callers that emit slots *without* stamping -- timeline
 * numbers `.section-N` classes rather than palette slots -- and is bounded there, because a
 * loop runs on it directly and `Infinity` is reachable from front matter
 * (`THEME_COLOR_LIMIT: .inf` parses to it under the `JSON_SCHEMA` mermaid uses).
 */
export declare const paletteSlotCount: (palette: unknown) => number;
export declare const colorSlotCount: (themeColorLimit: unknown, palette?: unknown) => number;
/**
 * Stamp the element with its palette slot, so the diagram's `[data-color-id]` rules can
 * find it. A no-op for every theme without a palette, which is what keeps this safe to
 * call from shared rendering code used by diagrams that never opt in.
 *
 * The slot wraps at the palette length rather than indexing raw, so a palette shorter
 * than the emitted slot count cannot produce `stroke: undefined`.
 *
 * An absent `colorIndex` means "this element is not part of the cycle", so nothing is
 * stamped. It used to fall back to `colorIndex ?? 0`, which says the opposite -- an
 * unnumbered element was stamped `color-0` and painted in the first palette colour. That
 * was invisible while the only unnumbered containers were ones whose diagram emits no
 * matching rules (class namespaces, block containers), and it stops being invisible the
 * moment such a diagram gains palette rules: state's composites opt out of the cycle when
 * the author has styled them, and would otherwise all come back as `color-0`.
 */
export declare const stampColorSlot: <T extends SVGGraphicsElement>(shapeSvg: D3Selection<T>, colorIndex: number | undefined, theme: string | undefined, palette: unknown) => void;
