1/**2 * Chart color roles for the stats dashboard. Every categorical set here was3 * run through the dataviz validator against the card surface (#161a21):4 *5 * - TRIBE_COLORS mirrors web/src/render/renderer.ts (tribe identity is shared6 * with the map + feeds and MUST stay byte-identical). It sits in the CVD7 * warn band (worst adjacent ΔE 7.5), so every tribe-colored chart ships8 * secondary encoding: a persistent name legend and name-listing tooltips.9 * - BREAKDOWN / PROFESSION colors: validated PASS (worst adjacent ΔE 8.4).10 * - TIER_RAMP: ordinal blue ramp, validated PASS with `--ordinal`.11 * - PROD/CONS pair: PASS (CVD 6.5 warn band — rows are direct-labeled).12 */1314/** Per-tribe identity colors — mirror of render/renderer.ts TRIBE_COLORS. */15export const TRIBE_COLORS = [16 '#e6533c', // red17 '#3ca4e6', // blue18 '#58c15c', // green19 '#e6c93c', // yellow20 '#b06ee6', // purple21 '#e67e3c', // orange22 '#3ce6c9', // teal23 '#e63ca4', // pink24] as const;2526export const tribeColor = (id: number): string => TRIBE_COLORS[id % TRIBE_COLORS.length]!;2728/** Score-breakdown components, fixed order (matches scoreBreakdown keys). */29export const BREAKDOWN_KEYS = ['pop', 'settlements', 'techs', 'military', 'coin', 'buildings', 'age'] as const;30export const BREAKDOWN_COLORS: Record<(typeof BREAKDOWN_KEYS)[number], string> = {31 pop: '#3987e5',32 settlements: '#d95926',33 techs: '#199e70',34 military: '#c98500',35 coin: '#d55181',36 buildings: '#008300',37 age: '#9a7bd0', // prestige violet38};3940/**41 * Profession stack colors — 8 validated slots assigned to the top-842 * professions (by current global head-count) in a FIXED global order, plus a43 * neutral for the folded "other" share. Assignment is per profession name, so44 * the same profession wears the same hue in every tribe's chart.45 */46export const PROFESSION_SLOT_COLORS = [47 '#3987e5', '#d95926', '#199e70', '#c98500', '#d55181', '#008300', '#9085e9', '#e66767',48] as const;49export const OTHER_COLOR = '#5b6472'; // neutral "other"/idle — deliberately gray50export const IDLE_COLOR = '#39404c';5152/** Settlement tier ordinal ramp (camp → city), light→dark blue. */53export const TIER_RAMP = ['#9ec5f4', '#5598e7', '#256abf', '#184f95'] as const;5455/** Production vs consumption pair (chain-health charts, direct-labeled). */56export const PROD_COLOR = '#199e70';57export const CONS_COLOR = '#e66767';5859/** Chart chrome — matches the style.css token set (1-bit terminal console). */60export const CHROME = {61 surface: '#08090c', // --chart-bg (telemetry card background)62 grid: '#151920', // one step off the surface, hairline63 axis: '#2b313c', // --border64 ink: '#d6dae2', // --text65 muted: '#808a9a', // --text-dim66 accent: '#e0a458', // --accent67} as const;6869/** Pixel font stack for canvas-drawn chart text (axis labels, bar totals). */70export const PIXEL_FONT = '"VT323", "Courier New", monospace';