Swap calendar coloring to per-person keyword match; teal UI accent

- Events now color by name match in the summary: Becca=teal, Chris=green,
  Arabella=pink. Anything without a match gets a neutral slate. Replaces
  the hash-to-Google-palette logic.
- Main accent swapped from blue to pastel teal (#14b8a6) so the UI feels
  cohesive with the event palette.
This commit is contained in:
root
2026-04-15 08:06:09 -05:00
parent 7b36551c32
commit 9315374944
2 changed files with 28 additions and 32 deletions

View File

@@ -1,32 +1,28 @@
// Google Calendar's 11 event colors, values lifted from the web client
// color picker. Colors are assigned deterministically by hashing the event
// summary so each recurring event always renders in the same color.
const GOOGLE_EVENT_COLORS = [
{ name: 'Tomato', bg: '#d50000', text: '#ffffff' },
{ name: 'Flamingo', bg: '#e67c73', text: '#ffffff' },
{ name: 'Tangerine', bg: '#f4511e', text: '#ffffff' },
{ name: 'Banana', bg: '#f6bf26', text: '#202124' },
{ name: 'Sage', bg: '#33b679', text: '#ffffff' },
{ name: 'Basil', bg: '#0b8043', text: '#ffffff' },
{ name: 'Peacock', bg: '#039be5', text: '#ffffff' },
{ name: 'Blueberry', bg: '#3f51b5', text: '#ffffff' },
{ name: 'Lavender', bg: '#7986cb', text: '#ffffff' },
{ name: 'Grape', bg: '#8e24aa', text: '#ffffff' },
{ name: 'Graphite', bg: '#616161', text: '#ffffff' },
] as const;
// Per-person event colors. Any event whose summary contains one of the
// configured names (case-insensitive) renders in that person's color.
// Events that don't match a name fall back to a neutral slate color.
export interface PersonColor {
name: string;
bg: string;
text: string;
}
export type EventColor = (typeof GOOGLE_EVENT_COLORS)[number];
export const PEOPLE: PersonColor[] = [
{ name: 'Becca', bg: '#14b8a6', text: '#ffffff' }, // teal-500
{ name: 'Chris', bg: '#22c55e', text: '#ffffff' }, // green-500
{ name: 'Arabella', bg: '#ec4899', text: '#ffffff' }, // pink-500
];
function hash(str: string): number {
let h = 2166136261;
for (let i = 0; i < str.length; i++) {
h ^= str.charCodeAt(i);
h = Math.imul(h, 16777619);
const FALLBACK: PersonColor = {
name: 'default',
bg: '#94a3b8', // slate-400 - muted pastel neutral
text: '#ffffff',
};
export function getEventColor(summary: string): PersonColor {
const lowered = summary.toLowerCase();
for (const p of PEOPLE) {
if (lowered.includes(p.name.toLowerCase())) return p;
}
return h >>> 0;
}
export function getEventColor(key: string): EventColor {
const idx = hash(key.toLowerCase().trim()) % GOOGLE_EVENT_COLORS.length;
return GOOGLE_EVENT_COLORS[idx];
return FALLBACK;
}