diff --git a/src/components/calendar/CalendarWidget.tsx b/src/components/calendar/CalendarWidget.tsx
index 97d3984..d1cb23e 100644
--- a/src/components/calendar/CalendarWidget.tsx
+++ b/src/components/calendar/CalendarWidget.tsx
@@ -2,10 +2,15 @@ import { useState, useMemo, useCallback, useEffect } from 'react';
import { format, startOfMonth, endOfMonth, startOfWeek, endOfWeek, addDays, isSameMonth, isSameDay, isToday } from 'date-fns';
import { useCalendar, CalendarEvent, formatEventTime } from '@/hooks/useCalendar';
import { VirtualKeyboard } from '@/components/keyboard';
+import { getEventColor } from './eventColors';
function EventItem({ event }: { event: CalendarEvent }) {
+ const color = getEventColor(event.summary);
return (
-
+
{formatEventTime(event)} {event.summary}
);
@@ -74,21 +79,28 @@ function EventDetails({ date, events, onAddEvent }: { date: Date; events: Calend
No events
) : (
- {events.map((event) => (
-
-
-
- {formatEventTime(event)}
-
- {event.summary}
-
- {event.location && (
-
- {event.location}
+ {events.map((event) => {
+ const color = getEventColor(event.summary);
+ return (
+
+
+
+
+ {formatEventTime(event)}
+
+ {event.summary}
- )}
-
- ))}
+ {event.location && (
+
+ {event.location}
+
+ )}
+
+ );
+ })}
)}
diff --git a/src/components/calendar/eventColors.ts b/src/components/calendar/eventColors.ts
new file mode 100644
index 0000000..f750344
--- /dev/null
+++ b/src/components/calendar/eventColors.ts
@@ -0,0 +1,32 @@
+// 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;
+
+export type EventColor = (typeof GOOGLE_EVENT_COLORS)[number];
+
+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);
+ }
+ return h >>> 0;
+}
+
+export function getEventColor(key: string): EventColor {
+ const idx = hash(key.toLowerCase().trim()) % GOOGLE_EVENT_COLORS.length;
+ return GOOGLE_EVENT_COLORS[idx];
+}
diff --git a/src/components/photoframe/PhotoFrame.tsx b/src/components/photoframe/PhotoFrame.tsx
index 589aac0..29be558 100644
--- a/src/components/photoframe/PhotoFrame.tsx
+++ b/src/components/photoframe/PhotoFrame.tsx
@@ -137,7 +137,7 @@ export function PhotoFrame({ intervalMs = 15_000, transitionMs = 1_200 }: PhotoF
key={`prev-${prevSrc}`}
src={prevSrc}
alt=""
- className="absolute inset-0 w-full h-full object-cover animate-ken-burns"
+ className="absolute inset-0 w-full h-full object-contain animate-ken-burns"
style={{ opacity: 1 }}
/>
)}
@@ -146,20 +146,18 @@ export function PhotoFrame({ intervalMs = 15_000, transitionMs = 1_200 }: PhotoF
key={`cur-${index}`}
src={currentSrc}
alt=""
- className="absolute inset-0 w-full h-full object-cover animate-ken-burns"
+ className="absolute inset-0 w-full h-full object-contain animate-ken-burns"
style={{
opacity: 0,
animation: `photo-fade-in ${transitionMs}ms ease-out forwards, ken-burns 20s ease-in-out infinite alternate`,
}}
/>
)}
- {/* Gradient + centered clock/date overlay (Skylight style) */}
-
-
-
-
{timeStr}
-
{dateStr}
-
+ {/* Lower-right clock + date overlay */}
+