- The INBUXA palette on warm surfaces, softer cards, buttons and inputs, and self-hosted Inter and Space Grotesk. - Each section's icon sits on a colored tile, colored by what the section is about. - The sidebar gets a guide line for sub-pages and a labeled Management / Settings / Account switch, and folds to a rail of tiles (remembered). - Every page has a header with its section's tile. - Fields and pages with no label of their own are spelled out in words (defaultCertificateId becomes Default certificate ID). - The dashboard greets you, and its stat cards wear colored tiles. - Unavailable live numbers are a calm note, not an error. - The cat appears in empty lists and while loading. - Chart colors work again: they were hex values wrapped in hsl().
73 lines
1.8 KiB
TypeScript
73 lines
1.8 KiB
TypeScript
/*
|
|
* SPDX-FileCopyrightText: 2026 Coffey Labs
|
|
*
|
|
* SPDX-License-Identifier: AGPL-3.0-only
|
|
*/
|
|
|
|
export type Tone = 'teal' | 'orange' | 'sky' | 'violet' | 'rose' | 'amber' | 'emerald' | 'indigo' | 'slate';
|
|
|
|
/**
|
|
* Colors by meaning, for the icons the server's layout names:
|
|
* - teal: mail itself;
|
|
* - rose: security;
|
|
* - amber: storage and data;
|
|
* - sky: network and connectivity;
|
|
* - violet: people and identity;
|
|
* - indigo: monitoring and reports;
|
|
* - emerald: automation and tasks;
|
|
* - orange: look and feel;
|
|
* - slate: the rest.
|
|
*/
|
|
const TONES: Record<string, Tone> = {
|
|
'layout-dashboard': 'teal',
|
|
mail: 'teal',
|
|
inbox: 'teal',
|
|
send: 'teal',
|
|
'mail-minus': 'teal',
|
|
plane: 'teal',
|
|
route: 'sky',
|
|
globe: 'sky',
|
|
cable: 'sky',
|
|
zap: 'sky',
|
|
monitor: 'sky',
|
|
'shield-check': 'rose',
|
|
'shield-alert': 'rose',
|
|
lock: 'rose',
|
|
fingerprint: 'rose',
|
|
'key-round': 'rose',
|
|
'key-square': 'rose',
|
|
filter: 'rose',
|
|
database: 'amber',
|
|
archive: 'amber',
|
|
boxes: 'amber',
|
|
folder: 'amber',
|
|
search: 'amber',
|
|
'search-code': 'amber',
|
|
users: 'violet',
|
|
'circle-user': 'violet',
|
|
contact: 'violet',
|
|
calendar: 'violet',
|
|
activity: 'indigo',
|
|
'chart-line': 'indigo',
|
|
'file-text': 'indigo',
|
|
'list-checks': 'emerald',
|
|
clock: 'emerald',
|
|
brain: 'emerald',
|
|
'file-code': 'emerald',
|
|
palette: 'orange',
|
|
'app-window': 'orange',
|
|
settings: 'slate',
|
|
'sliders-horizontal': 'slate',
|
|
};
|
|
|
|
const FALLBACK: Tone[] = ['teal', 'sky', 'violet', 'amber', 'emerald', 'indigo', 'orange', 'rose'];
|
|
|
|
/** The tone for an icon name: by meaning where known, otherwise a stable pick from its name. */
|
|
export function toneFor(name: string): Tone {
|
|
const known = TONES[name];
|
|
if (known) return known;
|
|
let h = 0;
|
|
for (const c of name) h = (h * 31 + c.charCodeAt(0)) >>> 0;
|
|
return FALLBACK[h % FALLBACK.length];
|
|
}
|