/** * Tempo Mode engine — Phase D.3. * * Adjusts timer urgency and cascade presets based on the user's current * energy/focus level. Pure TS, no React. */ export type TempoLevel = 'deep_focus' | 'normal' | 'low_energy' | 'winding_down'; export interface TempoConfig { level: TempoLevel; label: string; description: string; urgencyOverride: string; cascadeOverride: string; notificationMute: boolean; } export const TEMPO_CONFIGS: Record = { deep_focus: { level: 'deep_focus', label: 'Deep Focus', description: 'Minimal interruptions. Only critical timers fire.', urgencyOverride: 'passive', cascadeOverride: 'minimal', notificationMute: true, }, normal: { level: 'normal', label: 'Normal', description: 'Standard timer behavior.', urgencyOverride: 'standard', cascadeOverride: 'standard', notificationMute: false, }, low_energy: { level: 'low_energy', label: 'Low Energy', description: 'Gentler reminders. Extended snooze times.', urgencyOverride: 'gentle', cascadeOverride: 'minimal', notificationMute: false, }, winding_down: { level: 'winding_down', label: 'Winding Down', description: 'Quiet mode. Non-critical timers deferred.', urgencyOverride: 'passive', cascadeOverride: 'minimal', notificationMute: true, }, }; /** * Compute effective urgency based on tempo mode. */ export function getEffectiveUrgency( timerUrgency: string, tempoLevel: TempoLevel, ): string { if (tempoLevel === 'normal') return timerUrgency; // Critical timers always fire regardless of tempo if (timerUrgency === 'critical') return 'critical'; // In deep_focus or winding_down, downgrade non-critical to passive if (tempoLevel === 'deep_focus' || tempoLevel === 'winding_down') { return timerUrgency === 'important' ? 'standard' : 'passive'; } // low_energy: make everything gentler if (tempoLevel === 'low_energy') { if (timerUrgency === 'important') return 'standard'; if (timerUrgency === 'standard') return 'gentle'; return 'passive'; } return timerUrgency; } /** * Compute effective cascade preset based on tempo mode. */ export function getEffectiveCascade( cascadePreset: string, tempoLevel: TempoLevel, ): string { if (tempoLevel === 'normal') return cascadePreset; return TEMPO_CONFIGS[tempoLevel].cascadeOverride; } /** * Check if notifications should be muted for this tempo level. */ export function shouldMuteNotifications(tempoLevel: TempoLevel): boolean { return TEMPO_CONFIGS[tempoLevel].notificationMute; }