Page state
These watchers are on by default with createPal(), except page errors. Each accepts false to turn it off.
Fast scrolling → dizzy
Section titled “Fast scrolling → dizzy”Triggered when the average scroll speed over the last 300 ms passes the threshold (px per ms). It works for the page and for any scrollable container, and needs at least two movements, so jumping to an anchor doesn’t count.
createPal({ scroll: { threshold: 2 } }); // 600px in 300msOffline → sad
Section titled “Offline → sad”Sad while navigator.onLine is false, then a cheer when the connection comes back. Emits connection events with { online, offlineMs? }.
createPal({ network: false });Dark mode → sleepy
Section titled “Dark mode → sleepy”Dark mode is detected from common theme markers on <html> or <body>: data-theme, data-color-scheme, data-bs-theme, data-mode, .dark/.light classes, and an inline color-scheme. It falls back to prefers-color-scheme. Changes are picked up live.
createPal({ darkMode: { detect: () => document.body.classList.contains('night') } });The detector is exported as isDarkMode(document, window) if you need it elsewhere.
Idle → dozing
Section titled “Idle → dozing”After 30 seconds without pointer, keyboard, wheel, touch or scroll activity, it dozes off. The next activity, or returning to the tab, wakes it.
createPal({ idle: { timeout: 60_000 } });Password fields → shy
Section titled “Password fields → shy”It covers its eyes while a password field has focus. If the page offers “show password” (switching the input to type="text"), it peeks. A wrong-password wince still shows over it.
createPal({ password: false });Copying → wink
Section titled “Copying → wink”A wink when the user copies text with the keyboard or the context menu. Clipboard API calls from scripts don’t fire the copy event.
Coming back → cheer
Section titled “Coming back → cheer”When the tab becomes visible again after being hidden for at least 30 seconds.
createPal({ welcomeBack: { after: 120_000 } });Page errors → wince (opt-in)
Section titled “Page errors → wince (opt-in)”Uncaught errors and unhandled promise rejections. Useful in development, off by default:
createPal({ errors: import.meta.env.DEV });This only affects the mascot. To record errors, use the analytics plugin’s opt-in js_error event: see privacy.
The pal in the corner is pagepal itself.