Problem
Snooze is currently unlimited. Users can (and do) snooze every break indefinitely, training themselves to dismiss every break and defeating the app's purpose. The Eye Health Analyzer already detects snooze patterns but takes no action on them.
Proposal
Add progressive friction to repeated snoozes within a session:
- First snooze — free, works as today (single Esc or button)
- Second consecutive snooze — requires a 3-second press-and-hold on the Snooze button (Esc still works but with a visible countdown)
- Third consecutive snooze in a row — snooze is disabled until the user completes one full break
The counter resets after every completed break.
UX Details
- Show a subtle indicator on the break overlay: "Snooze 1 of 2 remaining"
- When snooze is locked out, the button is grayed with a tooltip: "Complete a break to unlock snooze"
- Skip (double-Esc) remains available as an escape hatch — the goal is friction, not a prison
- Add a setting to disable progressive friction for users who hate it (default: ON)
Why This Matters
Snooze abuse is the #1 retention risk. Users who never complete breaks see no health improvement, see no streak progress, and eventually uninstall. This is the single highest-leverage change for the core metric: breaks actually taken.
Technical Notes
- State lives in
AppState (consecutive snooze counter, resets on break completion)
BreakOverlayView needs conditional UI for hold-to-snooze and lockout states
TimerEngine needs to check snooze eligibility before allowing snooze transition
Problem
Snooze is currently unlimited. Users can (and do) snooze every break indefinitely, training themselves to dismiss every break and defeating the app's purpose. The Eye Health Analyzer already detects snooze patterns but takes no action on them.
Proposal
Add progressive friction to repeated snoozes within a session:
The counter resets after every completed break.
UX Details
Why This Matters
Snooze abuse is the #1 retention risk. Users who never complete breaks see no health improvement, see no streak progress, and eventually uninstall. This is the single highest-leverage change for the core metric: breaks actually taken.
Technical Notes
AppState(consecutive snooze counter, resets on break completion)BreakOverlayViewneeds conditional UI for hold-to-snooze and lockout statesTimerEngineneeds to check snooze eligibility before allowing snooze transition