Replace the custom themed presentation with the bare native iOS design
language across a three-tab TabView (Home / Rules / Settings):
- MainTabView hosts the enforcement lifecycle (refresh loop, rule-change
and scene-active reconcile) so it runs regardless of the selected tab
- HomeView: "Currently Blocking" + "Usage" sections (replaces AppsHomeView)
- RulesListView: rules grouped into Schedule / Time Limit / Open Limit
- SettingsView: Uninstall Protection toggle + Manage App Lists
- AppListLibraryView / ManageAppListsView: shared App List management
- AppSettings: app-group-backed settings store
Uninstall Protection: while enabled and any Hard Mode rule is actively
blocking, deny device app-removal via a dedicated ManagedSettingsStore
(RulePolicy.shouldDenyAppRemoval -> RuleEnforcer -> ShieldController).
Slim AppListPickerSheet to the picker role; drop AppsHomeView and the
custom Theme/HoldToCommitButton/RuleCardView chrome. Update spec section 6
and the unit/UI test suites accordingly.
- RuleUsage + UsageLedger: per-rule, per-day minutes/opens in app-group
defaults (monotonic minutes, incrementing opens, midnight rollover by
day-keying); MockUsageLedger for tests and seeded UI scenarios
- usage-aware status: a limit rule whose daily budget is spent on an
enabled day is active (blocking) until next midnight; Hard Mode gating
and app-list locking honor it; soft unblock pauses until midnight
- RuleEnforcer shields spent limit rules (always Block mode) while the
app runs
- new Usage section under Blocked Apps: '18m of 45m used today · 27m
left', '2 of 5 opens today · 3 opens left', 'Blocked until tomorrow'
- new 'limits' seed scenario + UI tests
Co-Authored-By: Claude <noreply@anthropic.com>