diff --git a/src/app.css b/src/app.css index 0f19908..e426277 100644 --- a/src/app.css +++ b/src/app.css @@ -20,6 +20,14 @@ --logo-wash-2: #96d6c6; --logo-text: #56555a; --map-icon-filter: none; + --cat-0: #2a78d6; + --cat-1: #eb6834; + --cat-2: #1baf7a; + --cat-3: #eda100; + --cat-4: #e87ba4; + --cat-5: #008300; + --cat-6: #4a3aa7; + --cat-7: #e34948; } /* dark tokens apply when the OS prefers dark (unless the user forced light), @@ -46,6 +54,14 @@ --logo-wash-2: #1e6355; --logo-text: #eef2f0; --map-icon-filter: invert(1) brightness(1.1); + --cat-0: #3987e5; + --cat-1: #d95926; + --cat-2: #199e70; + --cat-3: #c98500; + --cat-4: #d55181; + --cat-5: #008300; + --cat-6: #9085e9; + --cat-7: #e66767; } } :root[data-theme='dark'] { @@ -69,6 +85,14 @@ --logo-wash-2: #1e6355; --logo-text: #eef2f0; --map-icon-filter: invert(1) brightness(1.1); + --cat-0: #3987e5; + --cat-1: #d95926; + --cat-2: #199e70; + --cat-3: #c98500; + --cat-4: #d55181; + --cat-5: #008300; + --cat-6: #9085e9; + --cat-7: #e66767; } * { diff --git a/src/lib/activity-colors.ts b/src/lib/activity-colors.ts new file mode 100644 index 0000000..8eea9f5 --- /dev/null +++ b/src/lib/activity-colors.ts @@ -0,0 +1,53 @@ +// Categorical palette slots (validated for light and dark surfaces). +// Activity types map to fixed slots so a type keeps its color everywhere. + +export const CAT_SLOTS = [ + { light: '#2a78d6', dark: '#3987e5' }, // blue + { light: '#eb6834', dark: '#d95926' }, // orange + { light: '#1baf7a', dark: '#199e70' }, // aqua + { light: '#eda100', dark: '#c98500' }, // yellow + { light: '#e87ba4', dark: '#d55181' }, // magenta + { light: '#008300', dark: '#008300' }, // green + { light: '#4a3aa7', dark: '#9085e9' }, // violet + { light: '#e34948', dark: '#e66767' } // red +]; + +const TYPE_SLOT: Record = { + hiking: 0, + hike: 0, + walk: 0, + walking: 0, + run: 1, + running: 1, + 'trail run': 1, + ride: 2, + cycling: 2, + bike: 2, + biking: 2, + 'virtual ride': 2, + 'mountain bike': 2, + climb: 3, + climbing: 3, + 'via ferrata': 3, + alpinism: 3, + ski: 6, + 'backcountry ski': 6, + 'nordic ski': 6, + snowboard: 6, + snowshoe: 6 +}; + +function hash(s: string): number { + let h = 0; + for (let i = 0; i < s.length; i++) h = (h * 31 + s.charCodeAt(i)) | 0; + return Math.abs(h); +} + +export function typeSlot(type: string): number { + const t = type.toLowerCase().trim(); + return TYPE_SLOT[t] ?? hash(t) % CAT_SLOTS.length; +} + +export function typeColor(type: string): { light: string; dark: string } { + return CAT_SLOTS[typeSlot(type)]; +} diff --git a/src/lib/components/ActivityItem.svelte b/src/lib/components/ActivityItem.svelte index 9c55b8c..50ea7a7 100644 --- a/src/lib/components/ActivityItem.svelte +++ b/src/lib/components/ActivityItem.svelte @@ -1,5 +1,6 @@