Short answer: in a browser, no — setTimeout stops when the tab is suspended, and Web Notifications on mobile can't wake a locked phone at an exact time. In Kapsula, yes: one call schedules a real system alarm that the OS delivers even if the app was swiped away or killed.
Mobile browsers throttle background tabs within seconds and kill them within minutes. Timers stop, audio stops, and the Push API requires a server and still doesn't guarantee exact delivery. That is why every "timer in a web page" eventually fails when the screen locks.
Your page runs in a sandbox inside Kapsula and talks to the shell through window.kapsula. kapsula.notify.schedule({ at, title, body }) hands the time to the operating system: on Android an exact alarm with a notification channel and sound, on iOS a scheduled local notification with sound. The page doesn't need to be running — the OS remembers.
if (window.kapsula) {
await kapsula.notify.schedule({
at: Date.now() + 25 * 60 * 1000,
title: 'Break time',
body: 'Stand up, look away from the screen'
});
}
Rules: at must be in the future, up to 16 pending alarms per project, call kapsula.notify.cancel() before rescheduling. Store the end time in kapsula.storage and render the countdown from it, so the page shows the right state after it's reopened. Full details in the bridge reference; working examples (Pomodoro, medication reminder) in the gallery.