Five timezone-correctness fixes across the medication / compliance surfaces:
- getUserTodayBounds now derives both bounds through the DST-safe
startOfLocalDayInTz, so the today window is 23h on spring-forward and
25h on fall-back instead of a hardcoded 24h sampled at now. A 23:30
local dose no longer drops off the med cards, dashboard, PWA badge and
reminder idempotency near midnight on a transition day.
- dailyComplianceRatesFromLedger takes the user's zone and buckets each
per-day rate with userDayKey, so a non-Berlin user's evening dose is
filed on the local day it was due rather than the next Berlin day.
- classifyIntakeTiming interprets the window HH:mm in an optional zone;
the achievements perfect-day check passes the user's zone and reads the
scheduled minute-of-day in-zone, so a dose far from UTC is graded
against local wall time.
- The /insights greeting resolves the hour in the user's stored zone via
the new hourInTz helper, matching the dashboard hero.
- The doctor-report and schedule-anchored compliance queries load
schedules through SCHEDULE_COMPLIANCE_SELECT instead of a broad
include, so a future engine column reaches both surfaces.