The hands' drop-shadow outline sat on their own compositor layers, so the GPU
recomputed it every frame a bubble moved. It is now on an inner box, painted
once into the hand's layer. The bubbles rise beside the watch, never behind it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The remote's hauppauge.rem names the Guide button KEY_GUIDE, not lircd's
KEY_EPG, so the remote never toggled the clock.
The overlay is now hidden by opacity rather than display: none, so it is
already laid out and painted when Pos1 or Guide shows it. The drop-shadow
filter on the whole watch is gone (it re-rendered and re-blurred the dial on
every second-hand tick), the hands sit on their own layers, and the bubbles
and countdown cards only exist while the clock is on screen.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Each fix to the home-screen app's layout on iOS broke something else, and they
all traced back to black-translucent: it runs the page under the clock, so any
top-anchored control without its own inset sat behind it (the play view's back
button), and since iOS 26 it sizes the app one status bar short with a strip at
the bottom that CSS cannot paint (WebKit 301108). The status bar is opaque now
("black"), the page starts below it, and lib/fullHeight.ts - the JS workaround
for the short viewport - is gone with the CSS that depended on it.
viewport-fit=cover stays, so everything against a screen edge now adds that
edge's inset from shared --safe-* variables: the corner back button, the
remote-assign button, the assign toast, the tool buttons and the tab rail did
not before. The rules are written down under "Layout on phones" in the README.
On a phone held sideways the mini player and the tabs share one row instead of
taking half the screen.
Home-screen installs read the status-bar tag once: remove and re-add the app.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Einfg on the kiosk keyboard, or Guide (KEY_EPG) on the IR remote, shows a big
analog watch over whatever page is open, built from the Delphin Uhr mockup
without its swimming dolphin. The overlay stays mounted and is only hidden, so it
appears at once. Beside the watch, only while they run:
- The bus: on school days, a silent countdown to `general.clock.bus_time` (07:25)
that starts `bus_lead_minutes` (60) before. School days skip weekends and the
school and public holidays of `general.clock.subdivision` (DE-BY), fetched daily
from openholidaysapi.org and cached under the library cache. A badge on the
clock says whether there is school today, and why not.
- The dolphin timer, set in parent mode (5/10/15/30 minutes, or until a time).
It lives in the backend, so a parent's phone can start it for the kiosk. When it
runs out the kiosk opens the clock at 00:00 and a soft bell chimes on the
device; it clears after a minute, or at the next key, tap or remote press.
Parent mode is now a way in rather than a page: `?parentMode=1` adds a 🔧 button
next to the ⌨ one, or an "Eltern" tab in the phone's dock, so the URL can stay
bookmarked. The timer comes first there, the device settings below it.
Unmapped IR buttons are logged at debug level, to find out what irserver calls a
new one.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>