import * as React from 'react'; import { cn } from '../../shared/utils'; import { getIsotypeVariant, ISOTYPE_COLORS, ISOTYPE_PATTERNS, type IsotypePatternId, } from './patterns'; export interface IsotypeProps extends React.HTMLAttributes { /** Which registered pattern to render. */ pattern?: IsotypePatternId; /** * Deterministic seed selecting one extra cell (beyond the pattern's own * inherent blank cell) to also render as blank. Omit to render the pure * base pattern with no randomization — the correct choice for canonical * brand-mark placements (e.g. the landing page Hero). */ variantSeed?: number; /** Accessible label. Omit for purely decorative use. */ 'aria-label'?: string; } /** * A 4x4 grid brand mark — the first in a growing series of Xertica * "isotipos". Cells render flush against each other so the grid reads as a * single composed image. * * @ai-rules * 1. Colors are fixed brand hex values (see `patterns.ts`), not theme tokens — never make them theme-reactive. * 2. Never add a `gap-*` utility or per-cell border between cells — it breaks the "single image" look. * 3. Add new isotypes via `ISOTYPE_PATTERNS`/`IsotypePatternId` in `patterns.ts`; this component never needs to change. * 4. Only pass `variantSeed` for decorative/repeated placements — canonical brand-mark spots (Hero, nav) should use the pure base pattern. */ export function Isotype({ pattern = 'core', variantSeed, className, 'aria-label': ariaLabel, ...props }: IsotypeProps) { const cells = variantSeed === undefined ? ISOTYPE_PATTERNS[pattern] : getIsotypeVariant(pattern, variantSeed); return (
{cells.map((cell, index) => (
))}
); }