feat: production-harden app and finalize merge-ready UX/theme baseline

- complete tokenized theme preset system and admin style guide visibility
- refine dashboard layout/scroll behavior and shared async/request UI states
- add user nav-visibility settings across API, migration, and frontend stores
- harden security headers/CSP handling and related test coverage
- enforce CI repository hygiene + frontend contract/theme/build quality gates
- update docs/env references and make migration smoke test head-aware
This commit is contained in:
Justin Visser 2026-02-19 15:43:20 +01:00
parent ab1d29b203
commit ae2ca8f149
66 changed files with 5655 additions and 853 deletions

View file

@ -0,0 +1,89 @@
# Theme Inventory (Phase 0)
This file captures the semantic color system baseline for the theme refactor.
## Token Domains
- `scale`:
- `brand` (`50..950`)
- `info` (`50..950`)
- `success` (`50..950`)
- `warning` (`50..950`)
- `danger` (`50..950`)
- `surface`:
- `app`
- `nav`
- `nav_active`
- `card`
- `card_muted`
- `table`
- `table_header`
- `input`
- `overlay`
- `text`:
- `primary`
- `secondary`
- `muted`
- `inverse`
- `link`
- `border`:
- `default`
- `strong`
- `subtle`
- `interactive`
- `focus`:
- `ring`
- `ring_offset`
- `action` variants (`primary`, `secondary`, `ghost`, `danger`):
- `bg`
- `border`
- `text`
- `hover_bg`
- `hover_border`
- `hover_text`
- `state` variants (`info`, `success`, `warning`, `danger`):
- `bg`
- `border`
- `text`
## Theme Sources
Theme presets are dynamically loaded from `frontend/src/theme/presets/*.{json,js}`.
Current preset files:
- `frontend/src/theme/presets/parchment.js`
- `frontend/src/theme/presets/lilac.js`
- `frontend/src/theme/presets/dune.js`
- `frontend/src/theme/presets/oatmeal.js`
- `frontend/src/theme/presets/scholarly.json`
- `frontend/src/theme/presets/graphite.json`
- `frontend/src/theme/presets/tide.json`
Each preset contains both `light` and `dark` mode token definitions.
## Adoption Status (Phase 0-3 complete baseline)
Tokenized foundation components:
- `AppButton`
- `AppCard`
- `AppCheckbox`
- `AppEmptyState`
- `AppHelpHint`
- `AppInput`
- `AppSelect`
- `AppTable`
- `AppModal`
- `AppHeader`
- `AppNav`
- `AppAlert`
- `AppBadge`
- `RunStatusBadge`
- `QueueHealthBadge`
Hardening in place:
- Frontend token policy check script: `frontend/scripts/check_theme_tokens.mjs`
- CI enforcement step in `frontend-quality` workflow
- Theme preset integrity tests in `frontend/src/theme/presets.test.ts`

View file

@ -0,0 +1,69 @@
import { describe, expect, it } from "vitest";
import {
COLOR_SCALE_STEPS,
THEME_ACTION_KEYS,
THEME_ACTION_VARIANTS,
THEME_BORDER_KEYS,
THEME_COLOR_TYPES,
THEME_FOCUS_KEYS,
THEME_PRESETS,
THEME_STATE_KEYS,
THEME_STATE_VARIANTS,
THEME_SURFACE_KEYS,
THEME_TEXT_KEYS,
THEME_MODES,
themeCssVariables,
} from "@/theme/presets";
const RGB_TRIPLET_PATTERN = /^\d{1,3} \d{1,3} \d{1,3}$/;
describe("theme presets", () => {
it("exposes unique preset identifiers", () => {
const ids = THEME_PRESETS.map((preset) => preset.id);
expect(ids.length).toBeGreaterThan(0);
expect(new Set(ids).size).toBe(ids.length);
});
it("builds complete CSS variable maps for each preset and mode", () => {
const expectedCount =
THEME_COLOR_TYPES.length * COLOR_SCALE_STEPS.length +
THEME_SURFACE_KEYS.length +
THEME_TEXT_KEYS.length +
THEME_BORDER_KEYS.length +
THEME_FOCUS_KEYS.length +
THEME_ACTION_VARIANTS.length * THEME_ACTION_KEYS.length +
THEME_STATE_VARIANTS.length * THEME_STATE_KEYS.length;
for (const preset of THEME_PRESETS) {
for (const mode of THEME_MODES) {
const cssVars = themeCssVariables(preset.id, mode);
expect(Object.keys(cssVars)).toHaveLength(expectedCount);
expect(cssVars["--theme-surface-app"]).toBeDefined();
expect(cssVars["--theme-text-primary"]).toBeDefined();
expect(cssVars["--theme-border-default"]).toBeDefined();
expect(cssVars["--theme-focus-ring"]).toBeDefined();
expect(cssVars["--theme-action-primary-bg"]).toBeDefined();
expect(cssVars["--theme-state-warning-text"]).toBeDefined();
}
}
});
it("converts all theme variables to RGB triplets", () => {
for (const preset of THEME_PRESETS) {
for (const mode of THEME_MODES) {
const cssVars = themeCssVariables(preset.id, mode);
for (const value of Object.values(cssVars)) {
expect(value).toMatch(RGB_TRIPLET_PATTERN);
const [red, green, blue] = value.split(" ").map(Number);
expect(red).toBeGreaterThanOrEqual(0);
expect(red).toBeLessThanOrEqual(255);
expect(green).toBeGreaterThanOrEqual(0);
expect(green).toBeLessThanOrEqual(255);
expect(blue).toBeGreaterThanOrEqual(0);
expect(blue).toBeLessThanOrEqual(255);
}
}
}
});
});

View file

@ -0,0 +1,274 @@
export const COLOR_SCALE_STEPS = ["50", "100", "200", "300", "400", "500", "600", "700", "800", "900", "950"] as const;
export const THEME_MODES = ["light", "dark"] as const;
export const THEME_COLOR_TYPES = ["brand", "info", "success", "warning", "danger"] as const;
export const THEME_SURFACE_KEYS = [
"app",
"nav",
"nav_active",
"card",
"card_muted",
"table",
"table_header",
"input",
"overlay",
] as const;
export const THEME_TEXT_KEYS = ["primary", "secondary", "muted", "inverse", "link"] as const;
export const THEME_BORDER_KEYS = ["default", "strong", "subtle", "interactive"] as const;
export const THEME_FOCUS_KEYS = ["ring", "ring_offset"] as const;
export const THEME_ACTION_VARIANTS = ["primary", "secondary", "ghost", "danger"] as const;
export const THEME_ACTION_KEYS = ["bg", "border", "text", "hover_bg", "hover_border", "hover_text"] as const;
export const THEME_STATE_VARIANTS = ["info", "success", "warning", "danger"] as const;
export const THEME_STATE_KEYS = ["bg", "border", "text"] as const;
export type ColorScaleStep = (typeof COLOR_SCALE_STEPS)[number];
export type ThemeMode = (typeof THEME_MODES)[number];
export type ThemeColorType = (typeof THEME_COLOR_TYPES)[number];
export type ThemeSurfaceKey = (typeof THEME_SURFACE_KEYS)[number];
export type ThemeTextKey = (typeof THEME_TEXT_KEYS)[number];
export type ThemeBorderKey = (typeof THEME_BORDER_KEYS)[number];
export type ThemeFocusKey = (typeof THEME_FOCUS_KEYS)[number];
export type ThemeActionVariant = (typeof THEME_ACTION_VARIANTS)[number];
export type ThemeActionKey = (typeof THEME_ACTION_KEYS)[number];
export type ThemeStateVariant = (typeof THEME_STATE_VARIANTS)[number];
export type ThemeStateKey = (typeof THEME_STATE_KEYS)[number];
export type ThemePresetId = string;
export type ThemeColorScale = Record<ColorScaleStep, string>;
export type ThemeScaleTokenMap = Record<ThemeColorType, ThemeColorScale>;
export type ThemeSurfaceTokens = Record<ThemeSurfaceKey, string>;
export type ThemeTextTokens = Record<ThemeTextKey, string>;
export type ThemeBorderTokens = Record<ThemeBorderKey, string>;
export type ThemeFocusTokens = Record<ThemeFocusKey, string>;
export type ThemeActionTokens = Record<ThemeActionKey, string>;
export type ThemeActionTokenMap = Record<ThemeActionVariant, ThemeActionTokens>;
export type ThemeStateTokens = Record<ThemeStateKey, string>;
export type ThemeStateTokenMap = Record<ThemeStateVariant, ThemeStateTokens>;
export interface ThemePresetOption {
id: ThemePresetId;
label: string;
description: string;
}
export interface ThemeModeDefinition {
scale: ThemeScaleTokenMap;
surface: ThemeSurfaceTokens;
text: ThemeTextTokens;
border: ThemeBorderTokens;
focus: ThemeFocusTokens;
action: ThemeActionTokenMap;
state: ThemeStateTokenMap;
}
export interface ThemePresetDefinition extends ThemePresetOption {
modes: Record<ThemeMode, ThemeModeDefinition>;
}
const HEX_COLOR_PATTERN = /^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/;
const presetModules = import.meta.glob<{ default?: unknown }>(
"./presets/*.{json,js}",
{ eager: true },
);
function asObject(value: unknown, path: string): Record<string, unknown> {
if (!value || typeof value !== "object" || Array.isArray(value)) {
throw new Error(`Invalid theme schema at ${path}: expected object.`);
}
return value as Record<string, unknown>;
}
function asString(value: unknown, path: string): string {
if (typeof value !== "string" || value.trim().length === 0) {
throw new Error(`Invalid theme schema at ${path}: expected non-empty string.`);
}
return value;
}
function asHexColor(value: unknown, path: string): string {
const color = asString(value, path).trim();
if (!HEX_COLOR_PATTERN.test(color)) {
throw new Error(`Invalid theme color at ${path}: expected #RGB or #RRGGBB.`);
}
return color;
}
function readRecordByKeys<K extends readonly string[]>(
source: unknown,
keys: K,
path: string,
): Record<K[number], string> {
const record = asObject(source, path);
const result = {} as Record<K[number], string>;
for (const key of keys as readonly K[number][]) {
result[key] = asHexColor(record[key], `${path}.${key}`);
}
return result;
}
function readScaleTokens(source: unknown, path: string): ThemeScaleTokenMap {
const record = asObject(source, path);
return {
brand: readRecordByKeys(record.brand, COLOR_SCALE_STEPS, `${path}.brand`),
info: readRecordByKeys(record.info, COLOR_SCALE_STEPS, `${path}.info`),
success: readRecordByKeys(record.success, COLOR_SCALE_STEPS, `${path}.success`),
warning: readRecordByKeys(record.warning, COLOR_SCALE_STEPS, `${path}.warning`),
danger: readRecordByKeys(record.danger, COLOR_SCALE_STEPS, `${path}.danger`),
};
}
function readActionTokens(source: unknown, path: string): ThemeActionTokenMap {
const record = asObject(source, path);
return {
primary: readRecordByKeys(record.primary, THEME_ACTION_KEYS, `${path}.primary`),
secondary: readRecordByKeys(record.secondary, THEME_ACTION_KEYS, `${path}.secondary`),
ghost: readRecordByKeys(record.ghost, THEME_ACTION_KEYS, `${path}.ghost`),
danger: readRecordByKeys(record.danger, THEME_ACTION_KEYS, `${path}.danger`),
};
}
function readStateTokens(source: unknown, path: string): ThemeStateTokenMap {
const record = asObject(source, path);
return {
info: readRecordByKeys(record.info, THEME_STATE_KEYS, `${path}.info`),
success: readRecordByKeys(record.success, THEME_STATE_KEYS, `${path}.success`),
warning: readRecordByKeys(record.warning, THEME_STATE_KEYS, `${path}.warning`),
danger: readRecordByKeys(record.danger, THEME_STATE_KEYS, `${path}.danger`),
};
}
function readModeTokens(source: unknown, path: string): ThemeModeDefinition {
const record = asObject(source, path);
return {
scale: readScaleTokens(record.scale, `${path}.scale`),
surface: readRecordByKeys(record.surface, THEME_SURFACE_KEYS, `${path}.surface`),
text: readRecordByKeys(record.text, THEME_TEXT_KEYS, `${path}.text`),
border: readRecordByKeys(record.border, THEME_BORDER_KEYS, `${path}.border`),
focus: readRecordByKeys(record.focus, THEME_FOCUS_KEYS, `${path}.focus`),
action: readActionTokens(record.action, `${path}.action`),
state: readStateTokens(record.state, `${path}.state`),
};
}
function validateThemePreset(source: unknown, sourcePath: string): ThemePresetDefinition {
const record = asObject(source, sourcePath);
const id = asString(record.id, `${sourcePath}.id`);
return {
id,
label: asString(record.label, `${sourcePath}.label`),
description: asString(record.description, `${sourcePath}.description`),
modes: {
light: readModeTokens(asObject(record.modes, `${sourcePath}.modes`).light, `${sourcePath}.modes.light`),
dark: readModeTokens(asObject(record.modes, `${sourcePath}.modes`).dark, `${sourcePath}.modes.dark`),
},
};
}
const loadedPresetSources = Object.entries(presetModules)
.sort(([left], [right]) => left.localeCompare(right))
.map(([sourcePath, moduleValue]) => ({
sourcePath,
source:
moduleValue && typeof moduleValue === "object" && "default" in moduleValue
? moduleValue.default
: moduleValue,
}));
export const THEME_PRESETS: ThemePresetDefinition[] = loadedPresetSources.map(
({ source, sourcePath }) => validateThemePreset(source, sourcePath),
);
const presetById = new Map<ThemePresetId, ThemePresetDefinition>();
for (const preset of THEME_PRESETS) {
if (presetById.has(preset.id)) {
throw new Error(`Duplicate theme preset id detected: ${preset.id}`);
}
presetById.set(preset.id, preset);
}
export const DEFAULT_THEME_PRESET: ThemePresetId = presetById.has("parchment")
? "parchment"
: (THEME_PRESETS[0]?.id ?? "parchment");
export const THEME_PRESET_OPTIONS: ThemePresetOption[] = THEME_PRESETS.map((preset) => ({
id: preset.id,
label: preset.label,
description: preset.description,
}));
function normalizeHex(hex: string): string {
const normalized = hex.trim().replace(/^#/, "");
if (normalized.length === 3) {
return normalized
.split("")
.map((char) => `${char}${char}`)
.join("");
}
return normalized;
}
function hexToRgbTriplet(hex: string): string {
const normalized = normalizeHex(hex);
const red = parseInt(normalized.slice(0, 2), 16);
const green = parseInt(normalized.slice(2, 4), 16);
const blue = parseInt(normalized.slice(4, 6), 16);
return `${red} ${green} ${blue}`;
}
export function isThemePresetId(value: string): boolean {
return presetById.has(value);
}
export function getThemePreset(presetId: ThemePresetId): ThemePresetDefinition {
return presetById.get(presetId) ?? presetById.get(DEFAULT_THEME_PRESET) ?? THEME_PRESETS[0];
}
export function themeCssVariables(presetId: ThemePresetId, mode: ThemeMode): Record<string, string> {
const preset = getThemePreset(presetId);
const selected = preset.modes[mode];
const entries: Array<[string, string]> = [];
for (const role of THEME_COLOR_TYPES) {
for (const step of COLOR_SCALE_STEPS) {
entries.push([`--color-${role}-${step}`, hexToRgbTriplet(selected.scale[role][step])]);
}
}
for (const key of THEME_SURFACE_KEYS) {
entries.push([`--theme-surface-${key.replace(/_/g, "-")}`, hexToRgbTriplet(selected.surface[key])]);
}
for (const key of THEME_TEXT_KEYS) {
entries.push([`--theme-text-${key.replace(/_/g, "-")}`, hexToRgbTriplet(selected.text[key])]);
}
for (const key of THEME_BORDER_KEYS) {
entries.push([`--theme-border-${key.replace(/_/g, "-")}`, hexToRgbTriplet(selected.border[key])]);
}
for (const key of THEME_FOCUS_KEYS) {
entries.push([`--theme-focus-${key.replace(/_/g, "-")}`, hexToRgbTriplet(selected.focus[key])]);
}
for (const variant of THEME_ACTION_VARIANTS) {
for (const key of THEME_ACTION_KEYS) {
entries.push([
`--theme-action-${variant}-${key.replace(/_/g, "-")}`,
hexToRgbTriplet(selected.action[variant][key]),
]);
}
}
for (const variant of THEME_STATE_VARIANTS) {
for (const key of THEME_STATE_KEYS) {
entries.push([
`--theme-state-${variant}-${key.replace(/_/g, "-")}`,
hexToRgbTriplet(selected.state[variant][key]),
]);
}
}
return Object.fromEntries(entries);
}

View file

@ -0,0 +1,314 @@
export default {
"id": "dune",
"label": "Dune",
"description": "Sandy beige environments featuring soft mauve highlights.",
"modes": {
"light": {
"scale": {
"brand": {
"50": "#f7f5f6",
"100": "#ece7e9",
"200": "#d7cccd",
"300": "#baabb2",
"400": "#9e8893",
"500": "#856b77",
"600": "#6c5460",
"700": "#58424d",
"800": "#4a3841",
"900": "#3d3036",
"950": "#21181d"
},
"info": {
"50": "#f4f5f8",
"100": "#e5e8ef",
"200": "#cdd4e1",
"300": "#a9b6cb",
"400": "#8496b1",
"500": "#697a98",
"600": "#53617e",
"700": "#455067",
"800": "#3a4356",
"900": "#323948",
"950": "#21252f"
},
"success": {
"50": "#f3f7f4",
"100": "#e1ebe4",
"200": "#c4d8c9",
"300": "#9dbfa6",
"400": "#75a383",
"500": "#588567",
"600": "#446950",
"700": "#385441",
"800": "#2f4436",
"900": "#27382d",
"950": "#131f18"
},
"warning": {
"50": "#fdf7f3",
"100": "#faebe2",
"200": "#f3d2be",
"300": "#eab192",
"400": "#de8f68",
"500": "#cc784f",
"600": "#b05e3b",
"700": "#924a2f",
"800": "#783e29",
"900": "#633524",
"950": "#351a0f"
},
"danger": {
"50": "#fcf5f6",
"100": "#f8e6e9",
"200": "#efcbd1",
"300": "#e2a6b1",
"400": "#d07d8d",
"500": "#b85d6e",
"600": "#9b4556",
"700": "#823746",
"800": "#6c303c",
"900": "#5a2a33",
"950": "#31141a"
}
},
"surface": {
"app": "#efece5",
"nav": "#f7f5f0",
"nav_active": "#d7cccd",
"card": "#f7f5f0",
"card_muted": "#e6e3dd",
"table": "#f7f5f0",
"table_header": "#efece5",
"input": "#ffffff",
"overlay": "#3d3a3b"
},
"text": {
"primary": "#3d3a3b",
"secondary": "#757072",
"muted": "#9c9699",
"inverse": "#f7f5f0",
"link": "#6c5460"
},
"border": {
"default": "#e6e3dd",
"strong": "#d1cdc6",
"subtle": "#f2f0eb",
"interactive": "#baabb2"
},
"focus": {
"ring": "#9e8893",
"ring_offset": "#efece5"
},
"action": {
"primary": {
"bg": "#9e8893",
"border": "#9e8893",
"text": "#f7f5f0",
"hover_bg": "#856b77",
"hover_border": "#856b77",
"hover_text": "#ffffff"
},
"secondary": {
"bg": "#e6e3dd",
"border": "#d1cdc6",
"text": "#3d3a3b",
"hover_bg": "#d8d5ce",
"hover_border": "#bcbbb5",
"hover_text": "#1f1d1e"
},
"ghost": {
"bg": "#efece5",
"border": "#e6e3dd",
"text": "#6c5460",
"hover_bg": "#e6e3dd",
"hover_border": "#d1cdc6",
"hover_text": "#3d3a3b"
},
"danger": {
"bg": "#f8e6e9",
"border": "#efcbd1",
"text": "#823746",
"hover_bg": "#efcbd1",
"hover_border": "#e2a6b1",
"hover_text": "#9b4556"
}
},
"state": {
"info": {
"bg": "#e5e8ef",
"border": "#cdd4e1",
"text": "#455067"
},
"success": {
"bg": "#e1ebe4",
"border": "#c4d8c9",
"text": "#385441"
},
"warning": {
"bg": "#faebe2",
"border": "#f3d2be",
"text": "#924a2f"
},
"danger": {
"bg": "#f8e6e9",
"border": "#efcbd1",
"text": "#823746"
}
}
},
"dark": {
"scale": {
"brand": {
"50": "#f7f5f6",
"100": "#ece7e9",
"200": "#d7cccd",
"300": "#baabb2",
"400": "#9e8893",
"500": "#856b77",
"600": "#6c5460",
"700": "#58424d",
"800": "#4a3841",
"900": "#3d3036",
"950": "#21181d"
},
"info": {
"50": "#f4f5f8",
"100": "#e5e8ef",
"200": "#cdd4e1",
"300": "#a9b6cb",
"400": "#8496b1",
"500": "#697a98",
"600": "#53617e",
"700": "#455067",
"800": "#3a4356",
"900": "#323948",
"950": "#21252f"
},
"success": {
"50": "#f3f7f4",
"100": "#e1ebe4",
"200": "#c4d8c9",
"300": "#9dbfa6",
"400": "#75a383",
"500": "#588567",
"600": "#446950",
"700": "#385441",
"800": "#2f4436",
"900": "#27382d",
"950": "#131f18"
},
"warning": {
"50": "#fdf7f3",
"100": "#faebe2",
"200": "#f3d2be",
"300": "#eab192",
"400": "#de8f68",
"500": "#cc784f",
"600": "#b05e3b",
"700": "#924a2f",
"800": "#783e29",
"900": "#633524",
"950": "#351a0f"
},
"danger": {
"50": "#fcf5f6",
"100": "#f8e6e9",
"200": "#efcbd1",
"300": "#e2a6b1",
"400": "#d07d8d",
"500": "#b85d6e",
"600": "#9b4556",
"700": "#823746",
"800": "#6c303c",
"900": "#5a2a33",
"950": "#31141a"
}
},
"surface": {
"app": "#3d3a3b",
"nav": "#4a4748",
"nav_active": "#6c5460",
"card": "#4a4748",
"card_muted": "#575354",
"table": "#4a4748",
"table_header": "#575354",
"input": "#312e2f",
"overlay": "#1f1d1e"
},
"text": {
"primary": "#e6e3e4",
"secondary": "#b8b4b6",
"muted": "#918e8f",
"inverse": "#3d3a3b",
"link": "#baabb2"
},
"border": {
"default": "#575354",
"strong": "#696466",
"subtle": "#474345",
"interactive": "#9e8893"
},
"focus": {
"ring": "#9e8893",
"ring_offset": "#3d3a3b"
},
"action": {
"primary": {
"bg": "#9e8893",
"border": "#9e8893",
"text": "#1f1d1e",
"hover_bg": "#baabb2",
"hover_border": "#baabb2",
"hover_text": "#1f1d1e"
},
"secondary": {
"bg": "#575354",
"border": "#696466",
"text": "#e6e3e4",
"hover_bg": "#696466",
"hover_border": "#7a7577",
"hover_text": "#ffffff"
},
"ghost": {
"bg": "#3d3a3b",
"border": "#575354",
"text": "#b8b4b6",
"hover_bg": "#575354",
"hover_border": "#696466",
"hover_text": "#ffffff"
},
"danger": {
"bg": "#5a2a33",
"border": "#6c303c",
"text": "#efcbd1",
"hover_bg": "#6c303c",
"hover_border": "#823746",
"hover_text": "#f8e6e9"
}
},
"state": {
"info": {
"bg": "#323948",
"border": "#455067",
"text": "#cdd4e1"
},
"success": {
"bg": "#27382d",
"border": "#385441",
"text": "#c4d8c9"
},
"warning": {
"bg": "#633524",
"border": "#924a2f",
"text": "#f3d2be"
},
"danger": {
"bg": "#5a2a33",
"border": "#823746",
"text": "#efcbd1"
}
}
}
}
}
;

View file

@ -0,0 +1,313 @@
{
"id": "graphite",
"label": "Graphite",
"description": "Neutral slate base with crisp indigo accents.",
"modes": {
"light": {
"scale": {
"brand": {
"50": "#f8fafc",
"100": "#f1f5f9",
"200": "#e2e8f0",
"300": "#cbd5e1",
"400": "#94a3b8",
"500": "#64748b",
"600": "#475569",
"700": "#334155",
"800": "#1e293b",
"900": "#0f172a",
"950": "#020617"
},
"info": {
"50": "#eef2ff",
"100": "#e0e7ff",
"200": "#c7d2fe",
"300": "#a5b4fc",
"400": "#818cf8",
"500": "#6366f1",
"600": "#4f46e5",
"700": "#4338ca",
"800": "#3730a3",
"900": "#312e81",
"950": "#1e1b4b"
},
"success": {
"50": "#ecfdf5",
"100": "#d1fae5",
"200": "#a7f3d0",
"300": "#6ee7b7",
"400": "#34d399",
"500": "#10b981",
"600": "#059669",
"700": "#047857",
"800": "#065f46",
"900": "#064e3b",
"950": "#022c22"
},
"warning": {
"50": "#fffbeb",
"100": "#fef3c7",
"200": "#fde68a",
"300": "#fcd34d",
"400": "#fbbf24",
"500": "#f59e0b",
"600": "#d97706",
"700": "#b45309",
"800": "#92400e",
"900": "#78350f",
"950": "#451a03"
},
"danger": {
"50": "#fff1f2",
"100": "#ffe4e6",
"200": "#fecdd3",
"300": "#fda4af",
"400": "#fb7185",
"500": "#f43f5e",
"600": "#e11d48",
"700": "#be123c",
"800": "#9f1239",
"900": "#881337",
"950": "#4c0519"
}
},
"surface": {
"app": "#f5f7fb",
"nav": "#ffffff",
"nav_active": "#334155",
"card": "#ffffff",
"card_muted": "#f1f5f9",
"table": "#ffffff",
"table_header": "#f8fafc",
"input": "#ffffff",
"overlay": "#0f172a"
},
"text": {
"primary": "#111827",
"secondary": "#374151",
"muted": "#6b7280",
"inverse": "#f9fafb",
"link": "#334155"
},
"border": {
"default": "#dbe2ea",
"strong": "#cbd5e1",
"subtle": "#eef2f7",
"interactive": "#94a3b8"
},
"focus": {
"ring": "#6366f1",
"ring_offset": "#f5f7fb"
},
"action": {
"primary": {
"bg": "#334155",
"border": "#334155",
"text": "#f9fafb",
"hover_bg": "#1e293b",
"hover_border": "#1e293b",
"hover_text": "#ffffff"
},
"secondary": {
"bg": "#f3f4f6",
"border": "#d1d5db",
"text": "#1f2937",
"hover_bg": "#e5e7eb",
"hover_border": "#cbd5e1",
"hover_text": "#111827"
},
"ghost": {
"bg": "#f8fafc",
"border": "#cbd5e1",
"text": "#334155",
"hover_bg": "#f1f5f9",
"hover_border": "#94a3b8",
"hover_text": "#1f2937"
},
"danger": {
"bg": "#ffe4e6",
"border": "#fecdd3",
"text": "#be123c",
"hover_bg": "#fecdd3",
"hover_border": "#fda4af",
"hover_text": "#9f1239"
}
},
"state": {
"info": {
"bg": "#eef2ff",
"border": "#c7d2fe",
"text": "#3730a3"
},
"success": {
"bg": "#ecfdf5",
"border": "#a7f3d0",
"text": "#047857"
},
"warning": {
"bg": "#fffbeb",
"border": "#fde68a",
"text": "#92400e"
},
"danger": {
"bg": "#fff1f2",
"border": "#fecdd3",
"text": "#be123c"
}
}
},
"dark": {
"scale": {
"brand": {
"50": "#f8fafc",
"100": "#f1f5f9",
"200": "#e2e8f0",
"300": "#cbd5e1",
"400": "#94a3b8",
"500": "#64748b",
"600": "#475569",
"700": "#334155",
"800": "#1e293b",
"900": "#0f172a",
"950": "#020617"
},
"info": {
"50": "#eef2ff",
"100": "#e0e7ff",
"200": "#c7d2fe",
"300": "#a5b4fc",
"400": "#818cf8",
"500": "#6366f1",
"600": "#4f46e5",
"700": "#4338ca",
"800": "#3730a3",
"900": "#312e81",
"950": "#1e1b4b"
},
"success": {
"50": "#ecfdf5",
"100": "#d1fae5",
"200": "#a7f3d0",
"300": "#6ee7b7",
"400": "#34d399",
"500": "#10b981",
"600": "#059669",
"700": "#047857",
"800": "#065f46",
"900": "#064e3b",
"950": "#022c22"
},
"warning": {
"50": "#fffbeb",
"100": "#fef3c7",
"200": "#fde68a",
"300": "#fcd34d",
"400": "#fbbf24",
"500": "#f59e0b",
"600": "#d97706",
"700": "#b45309",
"800": "#92400e",
"900": "#78350f",
"950": "#451a03"
},
"danger": {
"50": "#fff1f2",
"100": "#ffe4e6",
"200": "#fecdd3",
"300": "#fda4af",
"400": "#fb7185",
"500": "#f43f5e",
"600": "#e11d48",
"700": "#be123c",
"800": "#9f1239",
"900": "#881337",
"950": "#4c0519"
}
},
"surface": {
"app": "#0b1120",
"nav": "#111827",
"nav_active": "#64748b",
"card": "#111827",
"card_muted": "#1f2937",
"table": "#111827",
"table_header": "#1f2937",
"input": "#0f172a",
"overlay": "#020617"
},
"text": {
"primary": "#e5e7eb",
"secondary": "#cbd5e1",
"muted": "#94a3b8",
"inverse": "#0b1120",
"link": "#a5b4fc"
},
"border": {
"default": "#334155",
"strong": "#475569",
"subtle": "#1f2937",
"interactive": "#64748b"
},
"focus": {
"ring": "#818cf8",
"ring_offset": "#0b1120"
},
"action": {
"primary": {
"bg": "#64748b",
"border": "#64748b",
"text": "#020617",
"hover_bg": "#94a3b8",
"hover_border": "#94a3b8",
"hover_text": "#020617"
},
"secondary": {
"bg": "#1f2937",
"border": "#475569",
"text": "#e5e7eb",
"hover_bg": "#334155",
"hover_border": "#64748b",
"hover_text": "#f8fafc"
},
"ghost": {
"bg": "#0f172a",
"border": "#334155",
"text": "#cbd5e1",
"hover_bg": "#1f2937",
"hover_border": "#475569",
"hover_text": "#f8fafc"
},
"danger": {
"bg": "#4c0519",
"border": "#881337",
"text": "#fecdd3",
"hover_bg": "#9f1239",
"hover_border": "#be123c",
"hover_text": "#fff1f2"
}
},
"state": {
"info": {
"bg": "#1e1b4b",
"border": "#4338ca",
"text": "#c7d2fe"
},
"success": {
"bg": "#022c22",
"border": "#047857",
"text": "#a7f3d0"
},
"warning": {
"bg": "#451a03",
"border": "#b45309",
"text": "#fde68a"
},
"danger": {
"bg": "#4c0519",
"border": "#be123c",
"text": "#fecdd3"
}
}
}
}
}

View file

@ -0,0 +1,313 @@
export default {
"id": "lilac",
"label": "Lilac",
"description": "Soft pastel lilac foundation with gentle purple interactions.",
"modes": {
"light": {
"scale": {
"brand": {
"50": "#faf8fb",
"100": "#f3ecf5",
"200": "#e5d5ea",
"300": "#d1b4db",
"400": "#b98dc8",
"500": "#9e63b0",
"600": "#844a95",
"700": "#6d397a",
"800": "#5a3164",
"900": "#4a2a51",
"950": "#2d1332"
},
"info": {
"50": "#f2f6fa",
"100": "#e1ebf4",
"200": "#c9dceb",
"300": "#a5c4df",
"400": "#7da8cc",
"500": "#5e8ab3",
"600": "#4a6e94",
"700": "#3c5978",
"800": "#334a63",
"900": "#2b3e51",
"950": "#1a2736"
},
"success": {
"50": "#f2f8f4",
"100": "#e0efe5",
"200": "#c3dfcb",
"300": "#9cc8a8",
"400": "#74ad84",
"500": "#558e66",
"600": "#41704e",
"700": "#355a40",
"800": "#2d4935",
"900": "#253d2d",
"950": "#132218"
},
"warning": {
"50": "#fdf8f4",
"100": "#faeee5",
"200": "#f3daca",
"300": "#e8bea5",
"400": "#d99f7c",
"500": "#c68058",
"600": "#ab623e",
"700": "#8d4e32",
"800": "#73412b",
"900": "#5e3624",
"950": "#331b10"
},
"danger": {
"50": "#fdf5f6",
"100": "#f9e7ea",
"200": "#f1d1d7",
"300": "#e4b0bc",
"400": "#d3889a",
"500": "#be6379",
"600": "#a1485d",
"700": "#85384b",
"800": "#6f3140",
"900": "#5d2b37",
"950": "#33141c"
}
},
"surface": {
"app": "#f7f5f9",
"nav": "#ffffff",
"nav_active": "#e5d5ea",
"card": "#ffffff",
"card_muted": "#f3ecf5",
"table": "#ffffff",
"table_header": "#f7f5f9",
"input": "#ffffff",
"overlay": "#2d1332"
},
"text": {
"primary": "#2d1332",
"secondary": "#5a3164",
"muted": "#844a95",
"inverse": "#ffffff",
"link": "#844a95"
},
"border": {
"default": "#e5d5ea",
"strong": "#d1b4db",
"subtle": "#f3ecf5",
"interactive": "#b98dc8"
},
"focus": {
"ring": "#9e63b0",
"ring_offset": "#f7f5f9"
},
"action": {
"primary": {
"bg": "#9e63b0",
"border": "#9e63b0",
"text": "#ffffff",
"hover_bg": "#844a95",
"hover_border": "#844a95",
"hover_text": "#ffffff"
},
"secondary": {
"bg": "#f3ecf5",
"border": "#d1b4db",
"text": "#2d1332",
"hover_bg": "#e5d5ea",
"hover_border": "#b98dc8",
"hover_text": "#1a0a1d"
},
"ghost": {
"bg": "#f7f5f9",
"border": "#e5d5ea",
"text": "#844a95",
"hover_bg": "#f3ecf5",
"hover_border": "#d1b4db",
"hover_text": "#2d1332"
},
"danger": {
"bg": "#f9e7ea",
"border": "#f1d1d7",
"text": "#85384b",
"hover_bg": "#f1d1d7",
"hover_border": "#e4b0bc",
"hover_text": "#a1485d"
}
},
"state": {
"info": {
"bg": "#e1ebf4",
"border": "#c9dceb",
"text": "#3c5978"
},
"success": {
"bg": "#e0efe5",
"border": "#c3dfcb",
"text": "#355a40"
},
"warning": {
"bg": "#faeee5",
"border": "#f3daca",
"text": "#8d4e32"
},
"danger": {
"bg": "#f9e7ea",
"border": "#f1d1d7",
"text": "#85384b"
}
}
},
"dark": {
"scale": {
"brand": {
"50": "#faf8fb",
"100": "#f3ecf5",
"200": "#e5d5ea",
"300": "#d1b4db",
"400": "#b98dc8",
"500": "#9e63b0",
"600": "#844a95",
"700": "#6d397a",
"800": "#5a3164",
"900": "#4a2a51",
"950": "#2d1332"
},
"info": {
"50": "#f2f6fa",
"100": "#e1ebf4",
"200": "#c9dceb",
"300": "#a5c4df",
"400": "#7da8cc",
"500": "#5e8ab3",
"600": "#4a6e94",
"700": "#3c5978",
"800": "#334a63",
"900": "#2b3e51",
"950": "#1a2736"
},
"success": {
"50": "#f2f8f4",
"100": "#e0efe5",
"200": "#c3dfcb",
"300": "#9cc8a8",
"400": "#74ad84",
"500": "#558e66",
"600": "#41704e",
"700": "#355a40",
"800": "#2d4935",
"900": "#253d2d",
"950": "#132218"
},
"warning": {
"50": "#fdf8f4",
"100": "#faeee5",
"200": "#f3daca",
"300": "#e8bea5",
"400": "#d99f7c",
"500": "#c68058",
"600": "#ab623e",
"700": "#8d4e32",
"800": "#73412b",
"900": "#5e3624",
"950": "#331b10"
},
"danger": {
"50": "#fdf5f6",
"100": "#f9e7ea",
"200": "#f1d1d7",
"300": "#e4b0bc",
"400": "#d3889a",
"500": "#be6379",
"600": "#a1485d",
"700": "#85384b",
"800": "#6f3140",
"900": "#5d2b37",
"950": "#33141c"
}
},
"surface": {
"app": "#27242a",
"nav": "#312d35",
"nav_active": "#6d397a",
"card": "#312d35",
"card_muted": "#3d3842",
"table": "#312d35",
"table_header": "#3d3842",
"input": "#1e1b21",
"overlay": "#141116"
},
"text": {
"primary": "#e8e4e9",
"secondary": "#b6aebd",
"muted": "#8e8496",
"inverse": "#27242a",
"link": "#d1b4db"
},
"border": {
"default": "#4a4450",
"strong": "#5f5766",
"subtle": "#3d3842",
"interactive": "#9e63b0"
},
"focus": {
"ring": "#b98dc8",
"ring_offset": "#27242a"
},
"action": {
"primary": {
"bg": "#9e63b0",
"border": "#9e63b0",
"text": "#141116",
"hover_bg": "#b98dc8",
"hover_border": "#b98dc8",
"hover_text": "#141116"
},
"secondary": {
"bg": "#4a4450",
"border": "#5f5766",
"text": "#e8e4e9",
"hover_bg": "#5f5766",
"hover_border": "#6d397a",
"hover_text": "#ffffff"
},
"ghost": {
"bg": "#27242a",
"border": "#4a4450",
"text": "#b6aebd",
"hover_bg": "#4a4450",
"hover_border": "#5f5766",
"hover_text": "#ffffff"
},
"danger": {
"bg": "#5d2b37",
"border": "#6f3140",
"text": "#f1d1d7",
"hover_bg": "#6f3140",
"hover_border": "#85384b",
"hover_text": "#f9e7ea"
}
},
"state": {
"info": {
"bg": "#2b3e51",
"border": "#3c5978",
"text": "#c9dceb"
},
"success": {
"bg": "#253d2d",
"border": "#355a40",
"text": "#c3dfcb"
},
"warning": {
"bg": "#5e3624",
"border": "#8d4e32",
"text": "#f3daca"
},
"danger": {
"bg": "#5d2b37",
"border": "#85384b",
"text": "#f1d1d7"
}
}
}
}
}

View file

@ -0,0 +1,314 @@
export default {
"id": "oatmeal",
"label": "Oatmeal",
"description": "Warm beige foundation with muted sage green interactions.",
"modes": {
"light": {
"scale": {
"brand": {
"50": "#f4f7f5",
"100": "#e5ece7",
"200": "#ccd9cf",
"300": "#a8bdae",
"400": "#8ba390",
"500": "#6c8471",
"600": "#546958",
"700": "#435446",
"800": "#364338",
"900": "#2d372f",
"950": "#161d18"
},
"info": {
"50": "#f0f5f6",
"100": "#d9e6e8",
"200": "#b6ced4",
"300": "#8aadb6",
"400": "#648d99",
"500": "#4a717e",
"600": "#3e5c68",
"700": "#344b55",
"800": "#2d3f47",
"900": "#27353d",
"950": "#151f25"
},
"success": {
"50": "#f2f7f3",
"100": "#e0efe3",
"200": "#c3dfc9",
"300": "#9bc4a6",
"400": "#75a383",
"500": "#568465",
"600": "#42694f",
"700": "#365340",
"800": "#2d4234",
"900": "#25372b",
"950": "#121e16"
},
"warning": {
"50": "#fcf9f2",
"100": "#f6efe0",
"200": "#ecdeb8",
"300": "#dfc68a",
"400": "#cfa85e",
"500": "#c79f67",
"600": "#ac7f42",
"700": "#8f6336",
"800": "#755030",
"900": "#60422a",
"950": "#352213"
},
"danger": {
"50": "#fdf4f4",
"100": "#fae5e5",
"200": "#f3cccc",
"300": "#e8a8a8",
"400": "#da7b7b",
"500": "#c47575",
"600": "#a64d4d",
"700": "#8b3f3f",
"800": "#753737",
"900": "#623232",
"950": "#361818"
}
},
"surface": {
"app": "#f5f2eb",
"nav": "#fcfaf5",
"nav_active": "#e5e1d8",
"card": "#fcfaf5",
"card_muted": "#ece9e1",
"table": "#fcfaf5",
"table_header": "#f5f2eb",
"input": "#ffffff",
"overlay": "#3d3b38"
},
"text": {
"primary": "#3d3b38",
"secondary": "#716d68",
"muted": "#96918a",
"inverse": "#fcfaf5",
"link": "#546958"
},
"border": {
"default": "#e5e1d8",
"strong": "#cecabf",
"subtle": "#f0ede6",
"interactive": "#a8bdae"
},
"focus": {
"ring": "#8ba390",
"ring_offset": "#f5f2eb"
},
"action": {
"primary": {
"bg": "#8ba390",
"border": "#8ba390",
"text": "#fcfaf5",
"hover_bg": "#6c8471",
"hover_border": "#6c8471",
"hover_text": "#ffffff"
},
"secondary": {
"bg": "#ece9e1",
"border": "#cecabf",
"text": "#3d3b38",
"hover_bg": "#e5e1d8",
"hover_border": "#b8b3a8",
"hover_text": "#1a1918"
},
"ghost": {
"bg": "#f5f2eb",
"border": "#e5e1d8",
"text": "#546958",
"hover_bg": "#ece9e1",
"hover_border": "#cecabf",
"hover_text": "#3d3b38"
},
"danger": {
"bg": "#fae5e5",
"border": "#f3cccc",
"text": "#8b3f3f",
"hover_bg": "#f3cccc",
"hover_border": "#e8a8a8",
"hover_text": "#a64d4d"
}
},
"state": {
"info": {
"bg": "#d9e6e8",
"border": "#b6ced4",
"text": "#344b55"
},
"success": {
"bg": "#e0efe3",
"border": "#c3dfc9",
"text": "#365340"
},
"warning": {
"bg": "#f6efe0",
"border": "#ecdeb8",
"text": "#8f6336"
},
"danger": {
"bg": "#fae5e5",
"border": "#f3cccc",
"text": "#8b3f3f"
}
}
},
"dark": {
"scale": {
"brand": {
"50": "#f4f7f5",
"100": "#e5ece7",
"200": "#ccd9cf",
"300": "#a8bdae",
"400": "#8ba390",
"500": "#6c8471",
"600": "#546958",
"700": "#435446",
"800": "#364338",
"900": "#2d372f",
"950": "#161d18"
},
"info": {
"50": "#f0f5f6",
"100": "#d9e6e8",
"200": "#b6ced4",
"300": "#8aadb6",
"400": "#648d99",
"500": "#4a717e",
"600": "#3e5c68",
"700": "#344b55",
"800": "#2d3f47",
"900": "#27353d",
"950": "#151f25"
},
"success": {
"50": "#f2f7f3",
"100": "#e0efe3",
"200": "#c3dfc9",
"300": "#9bc4a6",
"400": "#75a383",
"500": "#568465",
"600": "#42694f",
"700": "#365340",
"800": "#2d4234",
"900": "#25372b",
"950": "#121e16"
},
"warning": {
"50": "#fcf9f2",
"100": "#f6efe0",
"200": "#ecdeb8",
"300": "#dfc68a",
"400": "#cfa85e",
"500": "#c79f67",
"600": "#ac7f42",
"700": "#8f6336",
"800": "#755030",
"900": "#60422a",
"950": "#352213"
},
"danger": {
"50": "#fdf4f4",
"100": "#fae5e5",
"200": "#f3cccc",
"300": "#e8a8a8",
"400": "#da7b7b",
"500": "#c47575",
"600": "#a64d4d",
"700": "#8b3f3f",
"800": "#753737",
"900": "#623232",
"950": "#361818"
}
},
"surface": {
"app": "#3a3937",
"nav": "#454442",
"nav_active": "#546958",
"card": "#454442",
"card_muted": "#504e4c",
"table": "#454442",
"table_header": "#504e4c",
"input": "#2e2d2b",
"overlay": "#1a1918"
},
"text": {
"primary": "#e8e6e1",
"secondary": "#bebcb8",
"muted": "#969490",
"inverse": "#3a3937",
"link": "#a8bdae"
},
"border": {
"default": "#504e4c",
"strong": "#62605d",
"subtle": "#403f3d",
"interactive": "#8ba390"
},
"focus": {
"ring": "#8ba390",
"ring_offset": "#3a3937"
},
"action": {
"primary": {
"bg": "#8ba390",
"border": "#8ba390",
"text": "#1a1918",
"hover_bg": "#a8bdae",
"hover_border": "#a8bdae",
"hover_text": "#1a1918"
},
"secondary": {
"bg": "#504e4c",
"border": "#62605d",
"text": "#e8e6e1",
"hover_bg": "#62605d",
"hover_border": "#73716e",
"hover_text": "#ffffff"
},
"ghost": {
"bg": "#3a3937",
"border": "#504e4c",
"text": "#bebcb8",
"hover_bg": "#504e4c",
"hover_border": "#62605d",
"hover_text": "#ffffff"
},
"danger": {
"bg": "#623232",
"border": "#753737",
"text": "#f3cccc",
"hover_bg": "#753737",
"hover_border": "#8b3f3f",
"hover_text": "#fae5e5"
}
},
"state": {
"info": {
"bg": "#27353d",
"border": "#344b55",
"text": "#b6ced4"
},
"success": {
"bg": "#25372b",
"border": "#365340",
"text": "#c3dfc9"
},
"warning": {
"bg": "#60422a",
"border": "#8f6336",
"text": "#ecdeb8"
},
"danger": {
"bg": "#623232",
"border": "#8b3f3f",
"text": "#f3cccc"
}
}
}
}
}
;

View file

@ -0,0 +1,313 @@
export default {
"id": "parchment",
"label": "Parchment",
"description": "Dusty beige canvas paired with slate blue accents.",
"modes": {
"light": {
"scale": {
"brand": {
"50": "#f5f7f9",
"100": "#eaf0f4",
"200": "#d5e0e9",
"300": "#b3c9d7",
"400": "#8daabc",
"500": "#7d93a4",
"600": "#5c7487",
"700": "#495e6f",
"800": "#3f4d5b",
"900": "#36414e",
"950": "#232b35"
},
"info": {
"50": "#f2f6fa",
"100": "#e0ebf4",
"200": "#c8dceb",
"300": "#a1c4de",
"400": "#73a5cc",
"500": "#538ab8",
"600": "#406d96",
"700": "#34577a",
"800": "#2d4965",
"900": "#273e55",
"950": "#192838"
},
"success": {
"50": "#f1f8f5",
"100": "#def0e6",
"200": "#bee0ce",
"300": "#93c7b0",
"400": "#6a9982",
"500": "#4c8a6d",
"600": "#386b53",
"700": "#2e5543",
"800": "#274537",
"900": "#21392e",
"950": "#112019"
},
"warning": {
"50": "#fdf8f1",
"100": "#f9eedc",
"200": "#f3dbbc",
"300": "#ebc191",
"400": "#e0a163",
"500": "#d1a569",
"600": "#b37435",
"700": "#945c2d",
"800": "#784b29",
"900": "#613e24",
"950": "#36200f"
},
"danger": {
"50": "#fcf5f5",
"100": "#f9e8e8",
"200": "#f1d1d1",
"300": "#e5b1b1",
"400": "#d48888",
"500": "#c26b6b",
"600": "#a64f4f",
"700": "#8a4141",
"800": "#733838",
"900": "#603232",
"950": "#331818"
}
},
"surface": {
"app": "#f2eee9",
"nav": "#faf8f5",
"nav_active": "#d5e0e9",
"card": "#faf8f5",
"card_muted": "#eae5df",
"table": "#faf8f5",
"table_header": "#f2eee9",
"input": "#ffffff",
"overlay": "#333638"
},
"text": {
"primary": "#333638",
"secondary": "#6b737c",
"muted": "#929ba5",
"inverse": "#faf8f5",
"link": "#5c7487"
},
"border": {
"default": "#eae5df",
"strong": "#d4cec6",
"subtle": "#f6f3ef",
"interactive": "#b3c9d7"
},
"focus": {
"ring": "#7d93a4",
"ring_offset": "#f2eee9"
},
"action": {
"primary": {
"bg": "#7d93a4",
"border": "#7d93a4",
"text": "#faf8f5",
"hover_bg": "#5c7487",
"hover_border": "#5c7487",
"hover_text": "#ffffff"
},
"secondary": {
"bg": "#eae5df",
"border": "#d4cec6",
"text": "#333638",
"hover_bg": "#dcd6cd",
"hover_border": "#c2bba0",
"hover_text": "#1a1b1d"
},
"ghost": {
"bg": "#f2eee9",
"border": "#eae5df",
"text": "#5c7487",
"hover_bg": "#eae5df",
"hover_border": "#d4cec6",
"hover_text": "#333638"
},
"danger": {
"bg": "#f9e8e8",
"border": "#f1d1d1",
"text": "#8a4141",
"hover_bg": "#f1d1d1",
"hover_border": "#e5b1b1",
"hover_text": "#a64f4f"
}
},
"state": {
"info": {
"bg": "#e0ebf4",
"border": "#c8dceb",
"text": "#34577a"
},
"success": {
"bg": "#def0e6",
"border": "#bee0ce",
"text": "#2e5543"
},
"warning": {
"bg": "#f9eedc",
"border": "#f3dbbc",
"text": "#945c2d"
},
"danger": {
"bg": "#f9e8e8",
"border": "#f1d1d1",
"text": "#8a4141"
}
}
},
"dark": {
"scale": {
"brand": {
"50": "#f5f7f9",
"100": "#eaf0f4",
"200": "#d5e0e9",
"300": "#b3c9d7",
"400": "#8daabc",
"500": "#7d93a4",
"600": "#5c7487",
"700": "#495e6f",
"800": "#3f4d5b",
"900": "#36414e",
"950": "#232b35"
},
"info": {
"50": "#f2f6fa",
"100": "#e0ebf4",
"200": "#c8dceb",
"300": "#a1c4de",
"400": "#73a5cc",
"500": "#538ab8",
"600": "#406d96",
"700": "#34577a",
"800": "#2d4965",
"900": "#273e55",
"950": "#192838"
},
"success": {
"50": "#f1f8f5",
"100": "#def0e6",
"200": "#bee0ce",
"300": "#93c7b0",
"400": "#6a9982",
"500": "#4c8a6d",
"600": "#386b53",
"700": "#2e5543",
"800": "#274537",
"900": "#21392e",
"950": "#112019"
},
"warning": {
"50": "#fdf8f1",
"100": "#f9eedc",
"200": "#f3dbbc",
"300": "#ebc191",
"400": "#e0a163",
"500": "#d1a569",
"600": "#b37435",
"700": "#945c2d",
"800": "#784b29",
"900": "#613e24",
"950": "#36200f"
},
"danger": {
"50": "#fcf5f5",
"100": "#f9e8e8",
"200": "#f1d1d1",
"300": "#e5b1b1",
"400": "#d48888",
"500": "#c26b6b",
"600": "#a64f4f",
"700": "#8a4141",
"800": "#733838",
"900": "#603232",
"950": "#331818"
}
},
"surface": {
"app": "#35373a",
"nav": "#424549",
"nav_active": "#5c7487",
"card": "#424549",
"card_muted": "#4d5156",
"table": "#424549",
"table_header": "#4d5156",
"input": "#2a2c2e",
"overlay": "#1a1b1d"
},
"text": {
"primary": "#e3e5e8",
"secondary": "#aeb5bc",
"muted": "#889098",
"inverse": "#35373a",
"link": "#b3c9d7"
},
"border": {
"default": "#4d5156",
"strong": "#5d6268",
"subtle": "#3e4145",
"interactive": "#7d93a4"
},
"focus": {
"ring": "#7d93a4",
"ring_offset": "#35373a"
},
"action": {
"primary": {
"bg": "#7d93a4",
"border": "#7d93a4",
"text": "#1a1b1d",
"hover_bg": "#b3c9d7",
"hover_border": "#b3c9d7",
"hover_text": "#1a1b1d"
},
"secondary": {
"bg": "#4d5156",
"border": "#5d6268",
"text": "#e3e5e8",
"hover_bg": "#5d6268",
"hover_border": "#70767c",
"hover_text": "#ffffff"
},
"ghost": {
"bg": "#35373a",
"border": "#4d5156",
"text": "#aeb5bc",
"hover_bg": "#4d5156",
"hover_border": "#5d6268",
"hover_text": "#ffffff"
},
"danger": {
"bg": "#603232",
"border": "#733838",
"text": "#f1d1d1",
"hover_bg": "#733838",
"hover_border": "#8a4141",
"hover_text": "#f9e8e8"
}
},
"state": {
"info": {
"bg": "#273e55",
"border": "#34577a",
"text": "#c8dceb"
},
"success": {
"bg": "#21392e",
"border": "#2e5543",
"text": "#bee0ce"
},
"warning": {
"bg": "#613e24",
"border": "#945c2d",
"text": "#f3dbbc"
},
"danger": {
"bg": "#603232",
"border": "#8a4141",
"text": "#f1d1d1"
}
}
}
}
};

View file

@ -0,0 +1,313 @@
{
"id": "scholarly",
"label": "Scholarly",
"description": "Calm, academic blues with restrained contrast.",
"modes": {
"light": {
"scale": {
"brand": {
"50": "#f3f6fb",
"100": "#e7edf7",
"200": "#cedcee",
"300": "#afc6df",
"400": "#8eaac8",
"500": "#6f8fac",
"600": "#5a7490",
"700": "#495f77",
"800": "#3f5063",
"900": "#374554",
"950": "#242d38"
},
"info": {
"50": "#f0f9ff",
"100": "#e0f2fe",
"200": "#bae6fd",
"300": "#7dd3fc",
"400": "#38bdf8",
"500": "#0ea5e9",
"600": "#0284c7",
"700": "#0369a1",
"800": "#075985",
"900": "#0c4a6e",
"950": "#082f49"
},
"success": {
"50": "#ecfdf5",
"100": "#d1fae5",
"200": "#a7f3d0",
"300": "#6ee7b7",
"400": "#34d399",
"500": "#10b981",
"600": "#059669",
"700": "#047857",
"800": "#065f46",
"900": "#064e3b",
"950": "#022c22"
},
"warning": {
"50": "#fffbeb",
"100": "#fef3c7",
"200": "#fde68a",
"300": "#fcd34d",
"400": "#fbbf24",
"500": "#f59e0b",
"600": "#d97706",
"700": "#b45309",
"800": "#92400e",
"900": "#78350f",
"950": "#451a03"
},
"danger": {
"50": "#fff1f2",
"100": "#ffe4e6",
"200": "#fecdd3",
"300": "#fda4af",
"400": "#fb7185",
"500": "#f43f5e",
"600": "#e11d48",
"700": "#be123c",
"800": "#9f1239",
"900": "#881337",
"950": "#4c0519"
}
},
"surface": {
"app": "#f3f6fb",
"nav": "#ffffff",
"nav_active": "#495f77",
"card": "#ffffff",
"card_muted": "#e7edf7",
"table": "#ffffff",
"table_header": "#f3f6fb",
"input": "#ffffff",
"overlay": "#0f172a"
},
"text": {
"primary": "#1f2937",
"secondary": "#475569",
"muted": "#64748b",
"inverse": "#f8fafc",
"link": "#495f77"
},
"border": {
"default": "#cedcee",
"strong": "#afc6df",
"subtle": "#e7edf7",
"interactive": "#8eaac8"
},
"focus": {
"ring": "#6f8fac",
"ring_offset": "#f3f6fb"
},
"action": {
"primary": {
"bg": "#5a7490",
"border": "#5a7490",
"text": "#f8fafc",
"hover_bg": "#495f77",
"hover_border": "#495f77",
"hover_text": "#ffffff"
},
"secondary": {
"bg": "#eef2f7",
"border": "#cedcee",
"text": "#334155",
"hover_bg": "#e2e8f0",
"hover_border": "#afc6df",
"hover_text": "#1f2937"
},
"ghost": {
"bg": "#f3f6fb",
"border": "#cedcee",
"text": "#495f77",
"hover_bg": "#e7edf7",
"hover_border": "#afc6df",
"hover_text": "#374554"
},
"danger": {
"bg": "#ffe4e6",
"border": "#fecdd3",
"text": "#be123c",
"hover_bg": "#fecdd3",
"hover_border": "#fda4af",
"hover_text": "#9f1239"
}
},
"state": {
"info": {
"bg": "#f0f9ff",
"border": "#bae6fd",
"text": "#075985"
},
"success": {
"bg": "#ecfdf5",
"border": "#a7f3d0",
"text": "#047857"
},
"warning": {
"bg": "#fffbeb",
"border": "#fde68a",
"text": "#92400e"
},
"danger": {
"bg": "#fff1f2",
"border": "#fecdd3",
"text": "#be123c"
}
}
},
"dark": {
"scale": {
"brand": {
"50": "#f3f6fb",
"100": "#e7edf7",
"200": "#cedcee",
"300": "#afc6df",
"400": "#8eaac8",
"500": "#6f8fac",
"600": "#5a7490",
"700": "#495f77",
"800": "#3f5063",
"900": "#374554",
"950": "#242d38"
},
"info": {
"50": "#f0f9ff",
"100": "#e0f2fe",
"200": "#bae6fd",
"300": "#7dd3fc",
"400": "#38bdf8",
"500": "#0ea5e9",
"600": "#0284c7",
"700": "#0369a1",
"800": "#075985",
"900": "#0c4a6e",
"950": "#082f49"
},
"success": {
"50": "#ecfdf5",
"100": "#d1fae5",
"200": "#a7f3d0",
"300": "#6ee7b7",
"400": "#34d399",
"500": "#10b981",
"600": "#059669",
"700": "#047857",
"800": "#065f46",
"900": "#064e3b",
"950": "#022c22"
},
"warning": {
"50": "#fffbeb",
"100": "#fef3c7",
"200": "#fde68a",
"300": "#fcd34d",
"400": "#fbbf24",
"500": "#f59e0b",
"600": "#d97706",
"700": "#b45309",
"800": "#92400e",
"900": "#78350f",
"950": "#451a03"
},
"danger": {
"50": "#fff1f2",
"100": "#ffe4e6",
"200": "#fecdd3",
"300": "#fda4af",
"400": "#fb7185",
"500": "#f43f5e",
"600": "#e11d48",
"700": "#be123c",
"800": "#9f1239",
"900": "#881337",
"950": "#4c0519"
}
},
"surface": {
"app": "#0b1220",
"nav": "#111827",
"nav_active": "#8eaac8",
"card": "#111827",
"card_muted": "#1f2937",
"table": "#111827",
"table_header": "#1f2937",
"input": "#0f172a",
"overlay": "#020617"
},
"text": {
"primary": "#e5e7eb",
"secondary": "#cbd5e1",
"muted": "#94a3b8",
"inverse": "#0b1220",
"link": "#afc6df"
},
"border": {
"default": "#334155",
"strong": "#475569",
"subtle": "#1f2937",
"interactive": "#64748b"
},
"focus": {
"ring": "#8eaac8",
"ring_offset": "#0b1220"
},
"action": {
"primary": {
"bg": "#8eaac8",
"border": "#8eaac8",
"text": "#0b1220",
"hover_bg": "#afc6df",
"hover_border": "#afc6df",
"hover_text": "#020617"
},
"secondary": {
"bg": "#1f2937",
"border": "#475569",
"text": "#e5e7eb",
"hover_bg": "#334155",
"hover_border": "#64748b",
"hover_text": "#f8fafc"
},
"ghost": {
"bg": "#0f172a",
"border": "#334155",
"text": "#cbd5e1",
"hover_bg": "#1f2937",
"hover_border": "#475569",
"hover_text": "#f8fafc"
},
"danger": {
"bg": "#4c0519",
"border": "#881337",
"text": "#fecdd3",
"hover_bg": "#9f1239",
"hover_border": "#be123c",
"hover_text": "#fff1f2"
}
},
"state": {
"info": {
"bg": "#082f49",
"border": "#0369a1",
"text": "#bae6fd"
},
"success": {
"bg": "#022c22",
"border": "#047857",
"text": "#a7f3d0"
},
"warning": {
"bg": "#451a03",
"border": "#b45309",
"text": "#fde68a"
},
"danger": {
"bg": "#4c0519",
"border": "#be123c",
"text": "#fecdd3"
}
}
}
}
}

View file

@ -0,0 +1,313 @@
{
"id": "tide",
"label": "Tide",
"description": "Ocean-inspired palette with teal emphasis.",
"modes": {
"light": {
"scale": {
"brand": {
"50": "#f0fdfa",
"100": "#ccfbf1",
"200": "#99f6e4",
"300": "#5eead4",
"400": "#2dd4bf",
"500": "#14b8a6",
"600": "#0d9488",
"700": "#0f766e",
"800": "#115e59",
"900": "#134e4a",
"950": "#042f2e"
},
"info": {
"50": "#f0f9ff",
"100": "#e0f2fe",
"200": "#bae6fd",
"300": "#7dd3fc",
"400": "#38bdf8",
"500": "#0ea5e9",
"600": "#0284c7",
"700": "#0369a1",
"800": "#075985",
"900": "#0c4a6e",
"950": "#082f49"
},
"success": {
"50": "#ecfdf5",
"100": "#d1fae5",
"200": "#a7f3d0",
"300": "#6ee7b7",
"400": "#34d399",
"500": "#10b981",
"600": "#059669",
"700": "#047857",
"800": "#065f46",
"900": "#064e3b",
"950": "#022c22"
},
"warning": {
"50": "#fffbeb",
"100": "#fef3c7",
"200": "#fde68a",
"300": "#fcd34d",
"400": "#fbbf24",
"500": "#f59e0b",
"600": "#d97706",
"700": "#b45309",
"800": "#92400e",
"900": "#78350f",
"950": "#451a03"
},
"danger": {
"50": "#fff1f2",
"100": "#ffe4e6",
"200": "#fecdd3",
"300": "#fda4af",
"400": "#fb7185",
"500": "#f43f5e",
"600": "#e11d48",
"700": "#be123c",
"800": "#9f1239",
"900": "#881337",
"950": "#4c0519"
}
},
"surface": {
"app": "#f0fdfa",
"nav": "#ffffff",
"nav_active": "#0f766e",
"card": "#ffffff",
"card_muted": "#ccfbf1",
"table": "#ffffff",
"table_header": "#f0fdfa",
"input": "#ffffff",
"overlay": "#0f172a"
},
"text": {
"primary": "#134e4a",
"secondary": "#0f766e",
"muted": "#115e59",
"inverse": "#f8fafc",
"link": "#0d9488"
},
"border": {
"default": "#99f6e4",
"strong": "#5eead4",
"subtle": "#ccfbf1",
"interactive": "#2dd4bf"
},
"focus": {
"ring": "#14b8a6",
"ring_offset": "#f0fdfa"
},
"action": {
"primary": {
"bg": "#0d9488",
"border": "#0d9488",
"text": "#f8fafc",
"hover_bg": "#0f766e",
"hover_border": "#0f766e",
"hover_text": "#ffffff"
},
"secondary": {
"bg": "#ecfeff",
"border": "#99f6e4",
"text": "#115e59",
"hover_bg": "#ccfbf1",
"hover_border": "#5eead4",
"hover_text": "#134e4a"
},
"ghost": {
"bg": "#f0fdfa",
"border": "#99f6e4",
"text": "#0f766e",
"hover_bg": "#ccfbf1",
"hover_border": "#5eead4",
"hover_text": "#115e59"
},
"danger": {
"bg": "#ffe4e6",
"border": "#fecdd3",
"text": "#be123c",
"hover_bg": "#fecdd3",
"hover_border": "#fda4af",
"hover_text": "#9f1239"
}
},
"state": {
"info": {
"bg": "#f0f9ff",
"border": "#bae6fd",
"text": "#075985"
},
"success": {
"bg": "#ecfdf5",
"border": "#a7f3d0",
"text": "#047857"
},
"warning": {
"bg": "#fffbeb",
"border": "#fde68a",
"text": "#92400e"
},
"danger": {
"bg": "#fff1f2",
"border": "#fecdd3",
"text": "#be123c"
}
}
},
"dark": {
"scale": {
"brand": {
"50": "#f0fdfa",
"100": "#ccfbf1",
"200": "#99f6e4",
"300": "#5eead4",
"400": "#2dd4bf",
"500": "#14b8a6",
"600": "#0d9488",
"700": "#0f766e",
"800": "#115e59",
"900": "#134e4a",
"950": "#042f2e"
},
"info": {
"50": "#f0f9ff",
"100": "#e0f2fe",
"200": "#bae6fd",
"300": "#7dd3fc",
"400": "#38bdf8",
"500": "#0ea5e9",
"600": "#0284c7",
"700": "#0369a1",
"800": "#075985",
"900": "#0c4a6e",
"950": "#082f49"
},
"success": {
"50": "#ecfdf5",
"100": "#d1fae5",
"200": "#a7f3d0",
"300": "#6ee7b7",
"400": "#34d399",
"500": "#10b981",
"600": "#059669",
"700": "#047857",
"800": "#065f46",
"900": "#064e3b",
"950": "#022c22"
},
"warning": {
"50": "#fffbeb",
"100": "#fef3c7",
"200": "#fde68a",
"300": "#fcd34d",
"400": "#fbbf24",
"500": "#f59e0b",
"600": "#d97706",
"700": "#b45309",
"800": "#92400e",
"900": "#78350f",
"950": "#451a03"
},
"danger": {
"50": "#fff1f2",
"100": "#ffe4e6",
"200": "#fecdd3",
"300": "#fda4af",
"400": "#fb7185",
"500": "#f43f5e",
"600": "#e11d48",
"700": "#be123c",
"800": "#9f1239",
"900": "#881337",
"950": "#4c0519"
}
},
"surface": {
"app": "#041f1f",
"nav": "#042f2e",
"nav_active": "#5eead4",
"card": "#042f2e",
"card_muted": "#134e4a",
"table": "#042f2e",
"table_header": "#134e4a",
"input": "#063a38",
"overlay": "#020617"
},
"text": {
"primary": "#e6fffb",
"secondary": "#c9fff3",
"muted": "#99f6e4",
"inverse": "#041f1f",
"link": "#5eead4"
},
"border": {
"default": "#115e59",
"strong": "#0f766e",
"subtle": "#134e4a",
"interactive": "#2dd4bf"
},
"focus": {
"ring": "#2dd4bf",
"ring_offset": "#041f1f"
},
"action": {
"primary": {
"bg": "#2dd4bf",
"border": "#2dd4bf",
"text": "#042f2e",
"hover_bg": "#5eead4",
"hover_border": "#5eead4",
"hover_text": "#042f2e"
},
"secondary": {
"bg": "#0f766e",
"border": "#14b8a6",
"text": "#e6fffb",
"hover_bg": "#0d9488",
"hover_border": "#2dd4bf",
"hover_text": "#ffffff"
},
"ghost": {
"bg": "#042f2e",
"border": "#0f766e",
"text": "#c9fff3",
"hover_bg": "#115e59",
"hover_border": "#14b8a6",
"hover_text": "#ffffff"
},
"danger": {
"bg": "#4c0519",
"border": "#881337",
"text": "#fecdd3",
"hover_bg": "#9f1239",
"hover_border": "#be123c",
"hover_text": "#fff1f2"
}
},
"state": {
"info": {
"bg": "#082f49",
"border": "#0369a1",
"text": "#bae6fd"
},
"success": {
"bg": "#022c22",
"border": "#047857",
"text": "#a7f3d0"
},
"warning": {
"bg": "#451a03",
"border": "#b45309",
"text": "#fde68a"
},
"danger": {
"bg": "#4c0519",
"border": "#be123c",
"text": "#fecdd3"
}
}
}
}
}