feat: the redesigned Event Clock

The new reader app replaces the old UI: Checklist with a rail (focus
pills, Next to expire, today's dailies, pinned routines), Timeline in a
new and a classic look, Routines, Archive and a Settings area, in a
Structured (default) and a Relaxed interface. It follows the approved
Round 6 B and Round 7 mockups, corrected screen by screen with the owner.

Reader data moves to a v2 store (gacha-tracker:v2:*). Existing v1 data
is migrated on first load, a recovery copy is written first, and the v1
keys are never removed, so a rollback finds them unchanged. Redeem codes
for Genshin arrive as their own feed.

Also: live's urgency ramp, editable per theme; completion and
section-complete fireworks; a returning-user tour; the design mockups,
specs, plans, reviews and handoff record.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Lucas WintherandClaude Opus 5.5 committed 2026-10-18 01:55:16 +02:00
1 parent ddd9673f86
commit 50c6e91b00
284 files changed
+45100 -1628

No files matched your search

+13 -18
View File
@@ -39,23 +39,20 @@ export function ChangelogSheet({
return () => window.removeEventListener("keydown", onKey);
}, [onClose]);
const loose = entries.filter((e) => e.note === undefined);
const months = [...new Set(loose.map((e) => e.date.slice(0, 7)))];
return (
<div className="fixed inset-0 z-50 flex items-end justify-center sm:items-center">
<button
type="button"
aria-label="Close changelog"
onClick={onClose}
className="absolute inset-0 bg-scrim backdrop-blur-sm"
/>
<div
role="dialog"
aria-modal="true"
aria-label="Changelog"
className="relative max-h-[88vh] w-full overflow-y-auto rounded-t-2xl border border-hairline bg-surface p-5 sm:max-w-lg sm:rounded-2xl"
>
<button type="button" aria-label="Close changelog" onClick={onClose} className="absolute inset-0 bg-scrim backdrop-blur-sm" />
<div role="dialog" aria-modal="true" aria-label="Changelog" className="relative max-h-[88vh] w-full overflow-y-auto rounded-t-2xl border border-hairline bg-surface p-5 sm:max-w-lg sm:rounded-2xl">
<ChangelogContent notes={notes} entries={entries} />
</div>
</div>
);
}
export function ChangelogContent({ notes, entries }: { notes: readonly Note[]; entries: readonly Entry[] }) {
const loose = entries.filter((e) => e.note === undefined);
const months = [...new Set(loose.map((e) => e.date.slice(0, 7)))];
return (<>
<h2 className="font-display text-xl font-semibold">Changelog</h2>
<p className="mt-1 text-xs leading-relaxed text-faint">
What changed, summarised from the project's history and design notes. Each links to the
@@ -122,9 +119,7 @@ export function ChangelogSheet({
))}
</section>
)}
</div>
</div>
);
</>);
}
function EntryLine({ entry }: { entry: Entry }) {