A public Playtime tab and player-drawer playtime, and staff-only figures
(who's on, staff activity, disconnect reasons, countries, names, sessions)
for @css/generic on the staff panel and on the public site when signed in.
Hidden unless SAW_PT_DSN is set and its tables are there.
Notifications: staff turn them on per device from a new Notifications page,
pick each type (bans, gags, mutes and silences added or lifted, server down
and back up) and quiet hours. A watcher polls SimpleAdmin's tables, so in-game
penalties are sent too. Web Push with VAPID and RFC 8291 encryption in
internal/push, standard library only. Tables in sql/push.sql, created at
startup; the VAPID key is made on first start and kept in saw_settings.
Penalty notifications link to the public list searching for the player
(#bans?q=<steamid64>). The Android app delegates notifications (versionCode 3).
Caching: pages, scripts and styles are served with Cache-Control: no-cache
and an ETag, so a deploy shows up at once instead of after Cloudflare's
default 4-hour browser cache.