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:
1 parent
ddd9673f86
commit
50c6e91b00
284 files changed
+45100
-1628
No files matched your search
@@ -0,0 +1,464 @@
|
||||
# Event Clock redesign: handoff to the replacement agent
|
||||
|
||||
> **Newer handoff:** the replacement implementation was also rejected. Read
|
||||
> [2026-10-17 second-rejection handoff](2026-10-17-redesign-second-rejection-handoff.md) first.
|
||||
> The owner's next-step instruction is to launch the current server, then ask them for the biggest
|
||||
> differences from the mockup before making more UI changes.
|
||||
|
||||
Date: 2026-10-16. Repository: `/home/user/gacha-event-tracker`.
|
||||
|
||||
**2026-10-17 owner amendment:** Structured is now the default. Preserve any explicitly saved
|
||||
Relaxed choice. The references and the historical rejection described below remain unchanged.
|
||||
Correction evidence is recorded in `docs/design-reviews/2026-10-17-redesign-fidelity.md`.
|
||||
|
||||
## 1. Assignment and current acceptance status
|
||||
|
||||
**Finish the already-approved redesign by faithfully translating the approved mockup markup into
|
||||
production React and wiring in real data. The current implementation was rejected by the owner.**
|
||||
|
||||
The owner approved Round 7, then explicitly chose to retain two interfaces with a Settings toggle:
|
||||
|
||||
- **Relaxed (default):** `design/mockups/round7/converged.html`.
|
||||
- **Structured:** `design/mockups/round6/b-rail.html` — specifically Round 6 **B**, not A or C.
|
||||
|
||||
The owner subsequently reported that the implementation differed substantially from Round 7 and
|
||||
asked why the previous agent had invented a design instead of using the markup and wiring data.
|
||||
The previous agent acknowledged that this is what happened: it reused old visual components and
|
||||
selected mockup CSS, built substitute pages, then verified functionality rather than fidelity.
|
||||
|
||||
**Do not repeat that approach.** Preserve the approved rendered structure, hierarchy, proportions,
|
||||
spacing, typography, control arrangements, information architecture, responsive behavior and
|
||||
interactions. Translate HTML to JSX, break it into maintainable components and connect real state.
|
||||
The existing presentation is not the reference. Matching fonts and outer panel sizes is insufficient.
|
||||
|
||||
Do not transplant the prototype's fake data, fixed clocks, demo toolbar, localStorage namespace or
|
||||
monolithic demo JavaScript into production. That restriction was previously misinterpreted as
|
||||
permission to redesign its presentation. It is not. Real-data integration should retain the markup.
|
||||
|
||||
The owner selected **Native execution** and had already approved the spec/plan before implementation.
|
||||
The task is to finish that approved design, not restart brainstorming or request permission for each
|
||||
routine correction. Resolve actual conflicts explicitly; do not make new product choices silently.
|
||||
This handoff-writing turn makes no implementation changes and does not complete the correction.
|
||||
|
||||
## 2. Read these records, in this order
|
||||
|
||||
1. `AGENTS.md` — complete repository working agreement, not just the excerpt in a chat.
|
||||
2. This document and the approved reference HTML files above, **rendered in a browser**.
|
||||
3. `docs/design-reviews/2026-10-16-redesign-round7.md` and corresponding round4/round5/round6 records.
|
||||
4. `docs/superpowers/specs/2026-10-16-ui-redesign-design.md` — approved functional/state requirements.
|
||||
5. `docs/superpowers/plans/2026-10-16-ui-redesign.md` — implementation inventory, not evidence of acceptance.
|
||||
6. `docs/PRD.md`, `PRODUCT.md`, `DESIGN.md`, `DATA-MODEL.md`, `ARCHITECTURE.md`; source work additionally
|
||||
requires `INGESTION.md` and `SOURCES.md`.
|
||||
7. `docs/design-reviews/2026-10-16-redesign-implementation.md` — prior verification, rejection audit,
|
||||
HTTP follow-up and representative **rejected implementation** screenshots.
|
||||
8. `.superpowers/sdd/2026-10-16-ui-redesign/progress.md` and `review-packet.md` — historical ledger.
|
||||
|
||||
Important record caveats:
|
||||
|
||||
- The plan's checkboxes were all marked complete before the owner rejected the result. Presentation
|
||||
and fidelity gates must be reopened; do not treat those checks as acceptance.
|
||||
- The spec's opening “written for owner review; not implemented” status is stale. Its requirements
|
||||
were approved; implementation exists but is rejected. Distinguish intent from implementation status.
|
||||
- Most product/design docs were rewritten to describe the rejected implementation. Their design
|
||||
descriptions cannot override the approved mockup or the owner's later correction. Repair this
|
||||
documentation drift as the faithful implementation lands.
|
||||
- The Round 7 review initially discussed one UI; its later owner-decision note supersedes that:
|
||||
retain **two**, Round 7 and Round 6 B.
|
||||
- `2026-10-16-110223-command-messagesuperpowersusing-superpowersc.txt` is an earlier transcript supplied
|
||||
by the owner. It predates later work; it is supplemental, not the only record of current decisions.
|
||||
|
||||
## 3. Workspace and authorization
|
||||
|
||||
Last inspected HEAD: `ee41389` (`docs: a handoff note for the next agent, and the worktree feed trap`).
|
||||
Implementation was made in place on `main`. **All redesign changes remain uncommitted.** No push,
|
||||
PR, publication or deployment was performed by this agent. The owner has separately built/used the
|
||||
app through their network, so browser data may already contain v2 state.
|
||||
|
||||
Run `git status --short` before work. There are many modified tracked files and many untracked new
|
||||
files; `git diff` alone omits most new implementation code. Preserve them. In particular, do not
|
||||
`git clean`, reset to HEAD, delete all untracked files, or discard the state work to obtain a clean
|
||||
starting point. Earlier untracked `.impeccable/`, design artifacts, transcripts and review documents
|
||||
also existed and must not be treated as disposable agent scratch.
|
||||
|
||||
The approved plan says to use the current checkout; do not create a branch/worktree, commit, push,
|
||||
or publish without a separate owner instruction. The owner's standing workflow is to carry approved
|
||||
work through execution without repeated approval stops. Keep progress communication concise and
|
||||
report genuine problems directly.
|
||||
|
||||
## 4. What went wrong, concretely
|
||||
|
||||
The previous implementation created `ReaderApp.tsx`, reused old `EventRow`, `NextUp`, `Timeline`,
|
||||
`EventDetail` and `Colophon` presentation, and added `redesign.css` plus new simplified pages.
|
||||
That produced functional features with materially different presentation and interactions.
|
||||
|
||||
Confirmed divergence examples — this is a starting inventory, not an exhaustive audit:
|
||||
|
||||
| Area | Approved reference | Rejected implementation |
|
||||
| --- | --- | --- |
|
||||
| Header | Navigation counts; intentional Settings placement; mockup header hierarchy | Generic navigation and a different live/upcoming summary |
|
||||
| Standard events | Event content, prominent separate deadline/supporting text, chevron, deliberate meter placement | Old EventRow internals decorated with CSS; different countdown hierarchy and layout |
|
||||
| Routines | Per-game bands, aligned routine/progress/cycle/pin/menu columns and appropriate library/create flows | Flattened library rows with stacked checkbox options |
|
||||
| Settings | Sidebar includes individual game entries/descriptions leading into game profiles | Generic Your games page with a game dropdown |
|
||||
| Timeline | Routine periods/progress and reset markers plotted on the same time axis as events | Event timelines followed by ordinary routine controls; textual reset strips |
|
||||
| Archive | Story panel plus interactive per-game outcome bars/filtering and the approved per-game/history bodies | Simplified statistics and per-game text totals |
|
||||
| Forms/overlays | Approved drawers, sheets, field groupings and hierarchy | Several older production forms and modal layouts reused |
|
||||
| Mobile | Mockup-specific compact rail, hierarchy and responsive adaptations | Generic stacking; screenshots showing no overflow were accepted without reference comparison |
|
||||
|
||||
The earlier independent review concentrated on storage safety and functional correctness. It found
|
||||
important real bugs, which were fixed, but it did not establish design fidelity. **1,590 passing
|
||||
tests is not evidence that this is the approved design.** Screenshots in the earlier implementation
|
||||
report document the rejected result; do not use them as visual goldens.
|
||||
|
||||
## 5. How to read the mockup correctly
|
||||
|
||||
The reference HTML is layered: it contains earlier CSS/render functions, then later overrides.
|
||||
Reading its first stylesheet or first definition of a renderer in isolation gives the wrong target.
|
||||
Render the complete file and exercise its actual controls.
|
||||
|
||||
Useful anchors in Round 7 (line numbers are approximate; search the names):
|
||||
|
||||
- Final airy system begins around line 1003: `/* A single airier world, informed by the original C planner. */`.
|
||||
- Header `tabs()` around 1336; initial `baseRoutinesScreen()` around 1392; `settingsScreen()` around 1480.
|
||||
- Later `round4Checklist()` around 1894; final timeline renderer around 1912.
|
||||
- Final `checklistScreen()` around 1976; `archiveStory()` / `renderArchive()` around 1989.
|
||||
- Final `routinesScreen()` around 2051; later render/tour/number-input adjustments around 2065.
|
||||
- Final `generalPane()` around 2073, `onboarding()` around 2085, `returningTour()` around 2087.
|
||||
|
||||
The reference has its own review toolbar, shortcuts, fixed `NOW`, synthetic histories and namespace
|
||||
`event-clock:mockup:round7:v1`. Those are tools for inspecting states, not product UI/state to ship.
|
||||
Capture all relevant states using that toolbar and the product's controls. Do the equivalent for
|
||||
Round 6 B; do not assume it is merely Round 7 with a border-radius change.
|
||||
|
||||
Some demo behavior is explicitly superseded by owner requirements: e.g. adding a server must start
|
||||
fresh choices, not copy follows/pins just because an old prototype handler does. The stale-data label
|
||||
must be **Event data may be out of date**, replacing the mockup's **Older schedules**. The two-interface
|
||||
selector is an approved addition to Appearance. Keep these necessary adaptations narrow and explicit.
|
||||
|
||||
## 6. Approved requirements to retain
|
||||
|
||||
The detailed spec remains necessary. This summary preserves the accumulated owner feedback:
|
||||
|
||||
- Two visual interfaces over shared real state/components; Relaxed default. Interface, theme,
|
||||
colour scheme and Standard/Compact row density are independent.
|
||||
- Standard rows without descriptive text are shorter, with no reserved empty description area.
|
||||
- Focus uses the existing All/game pills, counts, toggle-to-All and Next behavior, first in the
|
||||
Checklist rail as in B. It hides for one tracked game and never changes followed games.
|
||||
- Checklist, Timeline, Routines, Archive and Settings are the main navigation. Utility navigation
|
||||
must not overwrite the saved preferred main view (`soon` / `timeline`).
|
||||
- Source age belongs in the same compact updates structure as new-since-last-look notices, only
|
||||
when tracked games have stale data. Source scope is independent of temporary focus. Codes,
|
||||
event newness, release news and source age are distinct states. Keep reasons/timestamps/source
|
||||
links in detail and Data & sources; never invent a failure cause. Footer always states data age.
|
||||
- Routines are rows. Manage built-ins, custom routines, follow/unfollow, Make it mine, and independent
|
||||
Checklist/Timeline pins there. Stopping a routine preserves history. Keep daily ticks one action.
|
||||
- Dailies can have their own Checklist panel or be grouped with routines; the same setting appears
|
||||
in Routines and Appearance. Group policy: collapsed, expanded by default, or always expanded.
|
||||
Focus temporarily expands groups without rewriting the policy. Numeric controls have visible
|
||||
native steppers and step one.
|
||||
- Timeline routines belong on the time axis. Separate reset strips, when enabled, sit beside their
|
||||
game's events. Preserve the cross-game Ending soonest queue when strips are off; focus applies
|
||||
to events, routines and reset strips together.
|
||||
- Add another server explains simultaneous accounts and asks all tracking questions again. It copies
|
||||
no progress, follows or pins. Changing an existing server preserves that account's identity/history.
|
||||
Prevent duplicate active game/server setup; retired histories remain recoverable.
|
||||
- Each game's settings includes Setup, Codes and About. About names all relevant real sources,
|
||||
links them and thanks editors, including sources contributing zero events. Game colour has picker,
|
||||
hex, preview and reset, shared across that game's servers.
|
||||
- Per-server reset timing has an override and Revert to Automatic; preserve historical clock revisions.
|
||||
Display timezone defaults to Automatic, permits named IANA zones/search and revert, and affects
|
||||
display/manual date entry rather than server periods or source instants.
|
||||
- Appearance includes Slate/Warm/Plum/Custom; custom light/dark palettes, game identity and urgency
|
||||
remain legible and distinct. Preserve offline font fallback.
|
||||
- About retains the full colophon, acknowledgements, sources, studios, disclaimer and project links.
|
||||
Changelog is its own Settings page, **not a footer link or an About button**.
|
||||
- Lists must contain actual settings, not a pointless Done/ignored row linking to Archive.
|
||||
- New setup initially selects **events only**. Ask default server, appearance, timezone, games,
|
||||
tracking types and preferred main view. Types explain cycles and remain selectable even when
|
||||
nothing is available; explain the absence. Upcoming visibility belongs in “What do you want to
|
||||
track?”, initially off. Do not change existing readers to new-reader defaults.
|
||||
- Returning users get a one-time welcome/tour with Skip/Back; preserve progress and preferred view.
|
||||
- Done/Ignore saves immediately, explains movement to Archive for about 1.5 seconds, then fades/
|
||||
collapses. Undo lasts about eight seconds; Archive Restore remains available. Honor reduced motion.
|
||||
- Archive retains real metadata/logs/outcomes, defaults to per-game history, offers alternate history
|
||||
timeline and the approved story statistics/outcome bars. Exclude ignored/unresolved entries from
|
||||
completion-rate denominators; unknown ends stay unknown. Explain incomplete pre-redesign history.
|
||||
- Backups retain seven daily, four weekly and six monthly snapshots, latest per disjoint UTC bucket,
|
||||
plus recovery. Created during app use, not magically on unused days. View backup → preview →
|
||||
Restore this backup; support recovery/Undo. Keep progress merge distinct from full restore.
|
||||
- Real codes notify in-app. Viewing clears per-game newness separately from per-server redemption;
|
||||
codes and event newness do not clear one another. No sample codes/history/health as production data.
|
||||
|
||||
## 7. Existing implementation map: preserve useful machinery, replace presentation faithfully
|
||||
|
||||
Production entry is `main.tsx` → `App.tsx` (stable re-export) → `ReaderApp.tsx`.
|
||||
`ReaderContent` coordinates pages, focus, feed/state, archive transitions, settings and detail adapters.
|
||||
Only the **v2 reader store** is mounted for production writes. Older hooks still supply validators,
|
||||
types and pure helpers; **do not mount their v1 persistence effects alongside the v2 store**.
|
||||
|
||||
| Files | Existing responsibilities / cautions |
|
||||
| --- | --- |
|
||||
| `src/client/state/reader/schema.ts` | Zod v2 envelope, stable local account IDs, clocks, placements, archive/seen snapshots; passthrough unknown fields; account/clock reference validation |
|
||||
| `migration.ts`, `legacy.ts` | v1 migration, original-account mapping, retained raw bytes, startup old-tab deltas and deletion handling |
|
||||
| `store.ts`, `reducer.ts`, `lock.ts`, `useReader.ts` | Serialized read-latest writes, operation replay, field timestamps/tombstones, account/pin rebase, storage-event updates, visible save errors |
|
||||
| `accounts.ts`, `clock.ts`, `src/shared/readerClock.ts` | Account lifecycle, automatic clock metadata revisions, override/revert, active versus historical-only imported clocks |
|
||||
| `eventRows.ts`, `routines.ts` | Account-aware real selectors and custom recurrence projection; useful data sources for faithful new markup |
|
||||
| `archive.ts`, `archiveStats.ts`, `aliases.ts` | Durable snapshots/outcomes/restore/expiry, real statistics, retired/merged ID carry |
|
||||
| `backups.ts`, `restore.ts`, `export.ts`, `import.ts` | UTC retention, validated versioned envelopes, recovery/pending restore, legacy imports, progress-only merge |
|
||||
| `ids.ts`, `actions.ts` | HTTP-compatible identity generation, action timestamps/operation IDs |
|
||||
| `src/client/state/appearance.ts` | Saved palette plus readable derived tokens against surfaces; check reference fidelity when applying |
|
||||
| `src/client/state/displayTime.ts`, `CustomForms.tsx`, `useCustom.ts` | IANA display formatting, manual wall-time parsing, DST behavior and interpreted-zone context |
|
||||
| `src/shared/time.ts`, `daily.ts`, `goal.ts`, `task.ts` | Existing domain rules extended with optional injected reset timing; defaults preserve old behavior |
|
||||
| `src/client/components/redesign/` | Current replacement pages — functional starting points, **not accepted presentation** |
|
||||
| `src/client/redesign.css`, `styles.css`, `index.html` | New overrides/fonts/prepaint; existing old CSS/components still influence internals |
|
||||
| `api.ts`, `sw.js`, `useAppUpdate.ts` | Separate event/code feeds; network-first data; unchanged waiting-worker update handshake |
|
||||
|
||||
Existing UI files include AppNavigation, SettingsLayout, GameSettings, RoutinesPage, DailyPanel,
|
||||
RoutineGroup, RoutineHistory, TimelinePage, ArchivePage/ArchiveStory, BackupPage, AppearancePage,
|
||||
TimeSettings, UpdatesPanel, DataSourcesPage, FeedFooter, SetupWizard, ReturningTour, TrackingChoices,
|
||||
CodesPage and ChangelogPage. Reuse their real operations where sound; change their markup/layout to
|
||||
match the approved reference. Do not preserve a rejected arrangement just to keep a component name.
|
||||
|
||||
The prior wrapper-file substitutions are recorded in the ledger. They do not justify retaining
|
||||
presentation mismatches. Likewise, prior DOM/render tests may assert the rejected structure; update
|
||||
those intentionally while retaining meaningful state, accessibility and data-preservation coverage.
|
||||
|
||||
## 8. Data that must survive this correction
|
||||
|
||||
Browser-local accounts are game/server tracking identities, **not authentication accounts**.
|
||||
There is no server copy of user progress. UI work must preserve existing v1 and already-created v2
|
||||
state, account IDs, original event/task/daily IDs and day/period labels.
|
||||
|
||||
Active storage keys:
|
||||
|
||||
```
|
||||
gacha-tracker:v2:reader
|
||||
gacha-tracker:v2:migration-recovery
|
||||
gacha-tracker:v2:backups
|
||||
gacha-tracker:v2:restore-pending
|
||||
gacha-tracker:v2:restore-recovery
|
||||
```
|
||||
|
||||
Do not delete `gacha-tracker:v1:*`. `ReaderState` contains `accounts`, per-account `data` with progress/
|
||||
ignored/daily/amount maps, `archive`, `seenEvents`, prefs, custom games/events/tasks, `codeSeen`,
|
||||
`codeRedeemed` and `eventSeen`. Daily/amount maps are nested under clock revision. Archive/seen keys
|
||||
are `JSON.stringify([accountId,eventId])`; those are distinct from immutable domain IDs.
|
||||
|
||||
Actions carry timestamps and operation IDs. Ordinary writes use Web Locks; browsers without Web
|
||||
Locks use an IndexedDB readwrite transaction mutex. Failure is disclosed without publishing a
|
||||
successful in-memory save. Account updates capture a base and rebase changed routine/pin fields.
|
||||
|
||||
Exports: `format: "gacha-tracker-export"`, `version: 2`, `exportedAt`, `reader`, `legacy`; progress
|
||||
exports mark `scope: "progress"`. Full restore validates first and saves recovery plus a pending
|
||||
transaction before replacing live state; bootstrap resolves pending restore before mounting writers.
|
||||
Progress imports merge by game/server, preserve local prefs/active reset, retain imported clock
|
||||
history and preserve unknown extensions. Backups are outside the envelope to avoid recursive growth.
|
||||
|
||||
Important fixes already made and regression-tested — retain them:
|
||||
|
||||
- Initial event-newness seeding is batched; per-account effect writes previously created an
|
||||
O(accounts²) queue that made settings appear unresponsive.
|
||||
- Capture/reconciliation waits for finished onboarding; otherwise unchosen catalogue games enter
|
||||
new readers' seen history before they select games.
|
||||
- Deleted custom events/occurrences must not reappear from seen-event fallback. A vanished source
|
||||
event with an unpassed/unknown end remains accessible; distinguish deletion from source absence.
|
||||
- Imported clock revisions retain historical logs without changing the local active reset.
|
||||
Equality ignores import-only `historicalOnly` so repeated imports do not duplicate revisions/logs.
|
||||
- Incoming opaque root/account extensions survive subsequent exports/transfers and deduplicate.
|
||||
Imported seen markers remain distinct from redemption and are merged appropriately.
|
||||
- Retired accounts Resume by actually removing `retiredAt`; changed-field rebase must handle deletion.
|
||||
Independent tabs editing pins on the same routine must preserve both fields.
|
||||
- Reset override/revert and automatic metadata correction append revisions, never rewrite old ticks.
|
||||
History resolves the explicit original revision, not today's reset.
|
||||
- Alias carry includes amount history and archive/seen snapshots as well as progress/daily/ignore.
|
||||
- v2 preferences are read before initial paint; user choices must not be replaced by old v1 defaults.
|
||||
- Manual refresh fetches both feeds, ignores build-only timestamp movement and discloses partial
|
||||
code-feed failure. Codes page discloses stale data. Source diagnostics never invent missing causes.
|
||||
- Native numeric controls keep a local draft so async persistence does not swallow rapid typing.
|
||||
|
||||
These foundations have substantial tests, but are not an assurance that every integration is correct.
|
||||
Review real consumers while changing markup; do not label the state layer or presentation complete
|
||||
without verifying the resulting flows.
|
||||
|
||||
## 9. Critical HTTP/WireGuard regression: do not reintroduce
|
||||
|
||||
The owner uses an HTTP network address through WireGuard: **10.20.20.2**.
|
||||
They encountered on first visit:
|
||||
|
||||
> Event Clock could not open. Your saved data could not be opened safely…
|
||||
|
||||
Exact reproduction: plain HTTP hostname in Chrome → `isSecureContext === false`,
|
||||
`crypto.randomUUID` undefined, `crypto.getRandomValues` available. Startup account minting threw;
|
||||
`initializeReader` caught it and returned generic `unavailable`, misleadingly blaming saved data.
|
||||
Localhost-only checks missed it because localhost is treated as a secure context.
|
||||
|
||||
Fixed in `state/reader/ids.ts` using 128-bit `crypto.getRandomValues` tokens. Use `mintAccountId()` for
|
||||
new accounts and `mintLocalId()` for operations, reset revisions and backups. **Never reintroduce
|
||||
direct client `crypto.randomUUID()` or remint existing IDs.** There are three new regressions in
|
||||
`test/reader-http.test.ts` that failed before the fix. Existing legacy bytes were preserved.
|
||||
|
||||
Actual HTTP-origin browser checks pass: old-progress migration, new setup, editing, extra server,
|
||||
reset override/revert, backups and reload. IndexedDB locking works on this origin too. Secure-only
|
||||
features must degrade honestly (e.g. clipboard may require manual copy; a service worker is not
|
||||
available on ordinary HTTP). Do not claim HTTP offline support just because localhost SW tests pass.
|
||||
|
||||
## 10. Codes ingestion is real and already implemented
|
||||
|
||||
Do not replace it with prototype codes or repeat external fetching just to work on presentation.
|
||||
|
||||
- Source: `https://game8.co/games/Genshin-Impact/archives/304759`.
|
||||
- One descriptive-aggregator robots request and one page request returned 200 during capture.
|
||||
No header-shaping/access workaround or repeated community requests were used.
|
||||
- Pinned: `fixtures/genshin/game8-codes-2026-10-16.html`, expected JSON and capture metadata.
|
||||
- Snapshots: `snapshots/genshin-game8-codes.html`, meta, `snapshots/codes-first-seen.json`.
|
||||
- Parser/registry: `src/ingest/codes/game8.ts`, `registry.ts`, `build.ts`.
|
||||
- Offline builder: `scripts/build-codes.ts`; published file `data/codes.v1.json`.
|
||||
- `src/shared/codes.ts` validates codes/feed. Source-stated calendar expiry is `expiresOn`, not a
|
||||
fabricated `expiresAt` instant. Unstated expiry remains null. First observation survives rebuilds.
|
||||
- The captured current section has ten actual codes; the three expired programme codes are fenced
|
||||
out. Tests include a future-expiry variant that admits those programme codes appropriately.
|
||||
- `scripts/refresh-sources.ts` combines event adapters and count-only code sources under the original
|
||||
robots, six-hour floor, host spacing, conditional requests and snapshot gates. Event adapters
|
||||
still return GachaEvent arrays; codes are not fake events.
|
||||
- `package.json` build includes `build:codes`; the service worker caches the separate feed correctly.
|
||||
|
||||
Use the fixtures/snapshots offline. Existing parser/date rules and source conduct remain binding.
|
||||
No SQLite, remote sync, push service, unrelated parser changes or new runtime dependencies are needed.
|
||||
|
||||
## 11. Verification already available — and its limits
|
||||
|
||||
Latest completed verification after the HTTP fix:
|
||||
|
||||
- `bun test`: **1,590 pass, zero failures, 75 files**.
|
||||
- `bun run typecheck` and `git diff --check`: pass.
|
||||
- Full offline build before the HTTP follow-up: 209 events across 20 games, ten codes.
|
||||
- Latest JS/static rebuild after HTTP fix: shell `9752bd6bf1d2`, 119 bundled modules.
|
||||
- Earlier Docker COPY-layout suite, without docs/public: 1,586 pass, one intentional README-only
|
||||
skip, zero failures (before the three HTTP tests were added). Recheck after your changes.
|
||||
- Independent read-only reviews found/fixed several storage/integration issues; focused HTTP review
|
||||
found no important issues. These reviews did **not** establish visual fidelity.
|
||||
|
||||
Prior browser checks covered migration, default view, both interfaces/themes at 1440/390, densities,
|
||||
reduced motion, an effective 200% CSS viewport, onboarding, direct ticks, extra servers, reset history,
|
||||
code redemption, Done/Ignore/Undo, custom unknown-end events, real JSON download/upload/restore,
|
||||
backup restore/Undo, timezone search, offline reload and the actual waiting-service-worker prompt.
|
||||
These are behavioral evidence and regression starting points; the owner still rejected the UI.
|
||||
|
||||
Tests that pin state, clocks, source honesty, archive denominators, retention, quota/recovery and
|
||||
imports remain valuable. Some late render tests passed immediately because code already existed;
|
||||
not every historical checkbox is evidence of a genuine RED test run.
|
||||
|
||||
## 12. Local tools and traps
|
||||
|
||||
Commands (Bun, React 19, strict TypeScript, Tailwind, Zod; use existing dependencies):
|
||||
|
||||
```bash
|
||||
bun test
|
||||
bun run typecheck
|
||||
bun run build:css
|
||||
bun run build:js
|
||||
bun run build:static
|
||||
PORT=<fresh-port> bun run serve.ts
|
||||
bun run build # offline feed + codes + shell, no wiki fetch required
|
||||
git diff --check
|
||||
```
|
||||
|
||||
- Use `--production` exactly as the existing JS build does. `NODE_ENV=production` or a define alone
|
||||
can produce a cleanly built bundle that crashes with jsxDEV errors; real-browser loading is required.
|
||||
- **Fresh port after each rebuild:** a localhost/HTTPS service worker caches the shell cache-first.
|
||||
Do not diagnose old cached bundles as new-code behavior. Ordinary HTTP also caches JS/CSS in-browser;
|
||||
use fresh origins/cache bypass for verification and a hard refresh for the owner.
|
||||
- Stop only your own servers by exact PID/port; never `pkill -f serve.ts`.
|
||||
- To inspect the reference directly, serve a separate scratch origin with
|
||||
`PUBLIC_DIR=design/mockups PORT=<another-fresh-port> bun run serve.ts`, then open
|
||||
`/round7/converged.html` or `/round6/b-rail.html`. Keep mockup and production browser contexts
|
||||
separate. Never point prototype handlers at production storage.
|
||||
- Last known preview servers were 41880 and 41881, serving rebuilt `public/`; recheck before use.
|
||||
Earlier verification servers 41873–41879 were stopped. Do not assume temporary processes persist.
|
||||
- `public/data/` is ignored. A fresh checkout/worktree has no feed until built/copied. No worktree is
|
||||
requested here, but this trap matters if the environment is reconstructed.
|
||||
- Browser storage seed is now v2 after initialization. `gacha-tracker:v1:prefs` with `onboarded:true`
|
||||
works only before first migration. Use disposable contexts and reload after intentional seeding;
|
||||
do not let mounted effects race test setup or touch the owner's real storage.
|
||||
- Wait for rendered content, not `networkidle0`. Use `textContent`, because CSS uppercase changes
|
||||
`innerText`. Keep capture scale about 3× or less to avoid blank sticky panes.
|
||||
- Tests must not require build output or docs. `test/serve.test.ts` creates its own tree.
|
||||
- In this tool sandbox, localhost listening misleadingly reported EADDRINUSE; unrestricted runs
|
||||
passed. Tests/Chrome/server calls required the appropriate tool escalation. Do not confuse that
|
||||
restriction with an actual application failure.
|
||||
|
||||
Chrome: `/usr/bin/google-chrome-stable`. Scratch Puppeteer import used successfully:
|
||||
|
||||
```
|
||||
/tmp/claude-1000/-home-user-gacha-event-tracker/06f9b760-325c-487b-bd28-0493ad38d1b2/scratchpad/pp/node_modules/puppeteer-core/lib/esm/puppeteer/puppeteer-core.js
|
||||
```
|
||||
|
||||
Scratch Prettier: `/tmp/gacha-redesign-format/node_modules/prettier/bin/prettier.cjs`.
|
||||
No browser/format dependency was installed into the project. Discover/recreate scratch tooling if
|
||||
these paths do not survive; do not add runtime dependencies for it.
|
||||
|
||||
Temporary browser scripts (inspect their origins/selectors and adapt; these assert rejected markup):
|
||||
`/tmp/redesign-browser-journeys.mjs`, `redesign-browser-matrix.mjs`, `redesign-browser-custom.mjs`,
|
||||
`redesign-browser-update.mjs`, `redesign-browser-release-matrix.mjs`, `/tmp/check-reader-release.mjs`.
|
||||
HTTP reproduction/fix verification: `/tmp/reproduce-reader-first-visit.mjs`, `/tmp/verify-reader-http.mjs`.
|
||||
The latter launches Chrome with `--no-proxy-server` and
|
||||
`--host-resolver-rules=MAP event-clock.test 127.0.0.1` and uses `http://event-clock.test:<port>`.
|
||||
This exercises the HTTP security boundary locally; no request to the owner's WireGuard machine is
|
||||
necessary. Temporary artifacts are not the durable source of requirements or acceptance.
|
||||
|
||||
## 13. Recommended correction sequence
|
||||
|
||||
1. Inspect the complete approved Round 7 and Round 6 B in a browser. Inventory screens, controls,
|
||||
overlays and states. Capture the target before editing. Start with the real rendered markup.
|
||||
2. Reopen the plan's presentation/fidelity gates. Record a concrete component mapping from reference
|
||||
elements to JSX and existing selectors/actions. Keep already-tested domain/state machinery where
|
||||
correct. Do not create another design or hide differences behind new CSS overrides.
|
||||
3. Port the shared shell and Checklist faithfully, including exact event structure, header/counts,
|
||||
rail hierarchy, daily tick treatment, grouped routines, update rows, Standard/Compact and mobile.
|
||||
4. Port Routines/library/create/edit, per-game settings/sidebar/profiles, appearance/timezone and
|
||||
source/backup/about/changelog pages. Preserve the approved information architecture and controls.
|
||||
5. Correct Timeline as a genuine shared time-axis view, with routine periods/progress/reset markers,
|
||||
optional adjacent reset strips and the correct global queue. Preserve account-aware identities
|
||||
and event opening for multiple servers/custom occurrences.
|
||||
6. Port Archive story/outcome bars/filtering, per-game/history layouts, details and both onboarding
|
||||
flows. Connect actual empty, unavailable, stale, unknown-end and legacy-history states honestly.
|
||||
7. Verify each screen against equivalent reference states while developing, then repeat the full
|
||||
matrix and behavior/data-preservation suite. Update docs to the accepted result, not to a newly
|
||||
invented substitute. Leave integration/commit/publication for explicit owner instruction.
|
||||
|
||||
This is suggested sequencing, not permission to defer required screens. Complete the approved scope.
|
||||
If production facts require a genuine departure, identify the exact reference behavior and reason;
|
||||
do not silently substitute a different interaction.
|
||||
|
||||
## 14. Completion criteria for the next agent
|
||||
|
||||
- Side-by-side target/production comparison for both references in equivalent states, using matched
|
||||
or deliberately representative content. Explain data-dependent differences rather than dismissing
|
||||
markup/layout mismatches as real-data effects. Inspect DOM structure and computed styles where
|
||||
useful; screenshots alone do not verify hidden interactions.
|
||||
- Check Checklist, Timeline, Routines, library/create/edit, game Setup/Codes/About, every Settings
|
||||
page, Archive/history/details, new onboarding and returning tour, including empty/error states.
|
||||
- Desktop and phone, light/dark, Standard/Compact, multi-game and focused/single-game, two servers,
|
||||
long titles, missing descriptions, unknown ends, stale/fresh sources, custom colours/timezone,
|
||||
keyboard/focus, reduced motion and 200% effective viewport. No clipped controls or page overflow.
|
||||
- All existing meaningful regressions plus updated presentation tests, strict typecheck, production
|
||||
build and real-browser load pass. Tests remain offline and independent of public/docs.
|
||||
- Ordinary HTTP network-origin startup and subsequent writes remain working. Preserve all migration,
|
||||
recovery, cross-tab, reset-history, code-newness/redemption and import/export protections above.
|
||||
- A final reviewer must explicitly compare against the approved rendered mockups as well as audit
|
||||
correctness. Review “looks similar” or “no overflow” is insufficient. Do not report completion
|
||||
based on counts of passing tests while known design differences remain.
|
||||
- Update AGENTS/product/design/data/architecture/source docs and handoff/status records honestly.
|
||||
No false completed checkboxes; record material limits and no invented data. No commit/push/publish
|
||||
without authorization.
|
||||
|
||||
## 15. Prompt to give the replacement agent
|
||||
|
||||
> Read `AGENTS.md` and `docs/handoffs/2026-10-16-redesign-fidelity-handoff.md`. Finish the approved
|
||||
> redesign in the current working tree. The current implementation was rejected because it
|
||||
> substituted its own presentation for the approved markup. Faithfully translate
|
||||
> `design/mockups/round7/converged.html` (Relaxed/default) and
|
||||
> `design/mockups/round6/b-rail.html` (Structured) into React and wire real state/data. Preserve the
|
||||
> existing tested migration, storage, reset, backup, codes and HTTP/WireGuard fixes. Compare actual
|
||||
> reference and production screens/interactions throughout; do not treat the old completed plan,
|
||||
> passing tests or rejected screenshots as design acceptance. Complete all required screens and
|
||||
> validation. Leave changes uncommitted and unpublished unless I separately authorize integration.
|
||||
@@ -0,0 +1,926 @@
|
||||
# Redesign handoff: second implementation rejected
|
||||
|
||||
Date: 2026-10-17. Repository: `/home/user/gacha-event-tracker`.
|
||||
|
||||
## Start here: launch the current server, then ask the owner
|
||||
|
||||
**Explicit owner instruction for the next agent:** launch the current server, make it accessible
|
||||
on `0.0.0.0`, give the owner its browse URL, **then ask the owner for the biggest differences from
|
||||
the mockup**. Get that feedback before making more UI changes. Do not begin another broad visual
|
||||
rewrite or substitute your own audit for this conversation.
|
||||
|
||||
Suggested question after the server is reachable:
|
||||
|
||||
> The current build is running at [URL]. What are the biggest differences you see compared with
|
||||
> the approved mockup? Which screen and interface should we fix first?
|
||||
|
||||
The owner has not yet identified the specific screen, viewport or visual differences behind this
|
||||
second rejection. Do not guess that it is Checklist, Structured, a font-loading problem, or stale
|
||||
cache. An optional screen/layout question was sent, but the owner instead requested this handoff.
|
||||
|
||||
At the handoff, the current build was running at **http://10.20.20.2:41908**, listening on all
|
||||
interfaces (`*:41908`), Bun PID **2536610**. `/api/health` responded successfully. The process may
|
||||
not survive the session; check rather than assuming it is running. `serve.ts` uses `Bun.serve`'s
|
||||
all-interface default even though its log prints `localhost`. Verify the actual listener.
|
||||
|
||||
If it needs restarting, from the repository root:
|
||||
|
||||
```bash
|
||||
PORT=41908 bun run serve.ts
|
||||
```
|
||||
|
||||
If that port is occupied by the current server, reuse it; do not kill unknown processes. If the
|
||||
shell is rebuilt, use a fresh port to avoid a previous service worker serving an old shell.
|
||||
For a missing/stale build, rebuild only the shell, preserving the existing feed:
|
||||
|
||||
```bash
|
||||
bun run build:css && bun run build:js && bun run build:static
|
||||
PORT=<fresh-port> bun run serve.ts
|
||||
```
|
||||
|
||||
Use the machine's reachable network address in the URL, not `0.0.0.0` as a destination. The owner
|
||||
uses WireGuard `10.20.20.2`. Binding may require command escalation in the agent sandbox. Do not
|
||||
fetch community sources just to start the UI.
|
||||
|
||||
## Current acceptance and scope
|
||||
|
||||
The owner asked for a faithful implementation of the already-approved mockups, then explicitly
|
||||
said: **“Also make the structure layout the default.”** Structured is now the absent-preference
|
||||
and new-setup default; an explicitly saved Relaxed choice is preserved.
|
||||
|
||||
After this agent claimed the correction was complete and started the build for the owner, the owner
|
||||
said:
|
||||
|
||||
> “This is still not even close to the mockup.”
|
||||
|
||||
The owner then stopped further implementation and requested a handover specification. **The current
|
||||
implementation is rejected. The previous completion claim and visual-review verdict do not establish
|
||||
acceptance.** This handoff turn makes documentation changes only, retaining two audit screenshots
|
||||
captured by a browser inspection that had already started when the owner asked to stop.
|
||||
|
||||
The unrelated request about sorting PDF-export examples was explicitly withdrawn as a message meant
|
||||
for another agent. It is not part of this repository's task.
|
||||
|
||||
## Approved visual authority
|
||||
|
||||
1. Latest owner feedback, including the launch-and-ask instruction above.
|
||||
2. `design/mockups/round7/converged.html` — Relaxed.
|
||||
3. `design/mockups/round6/b-rail.html` — Structured, specifically B.
|
||||
4. Approved functional/state requirements in
|
||||
`docs/superpowers/specs/2026-10-16-ui-redesign-design.md`.
|
||||
|
||||
Read `AGENTS.md`, relevant product/design/domain docs, and the previous handoff
|
||||
`docs/handoffs/2026-10-16-redesign-fidelity-handoff.md`. The earlier handoff remains useful for the
|
||||
first failure, reference-file anchors and invariants. This document supersedes its current-status
|
||||
and next-action instructions. Historical statements that Relaxed is the default are superseded by
|
||||
the owner's Structured-default instruction.
|
||||
|
||||
The reference HTML files contain multiple generations of render functions and CSS overrides. The
|
||||
fully rendered final file is the reference, not the first function with a matching name. Preserve
|
||||
composition, proportions, hierarchy, typography, controls, density, responsive behavior and page
|
||||
organization when translating HTML into React. Do not treat the reference as inspiration.
|
||||
|
||||
Necessary authorized adaptations remain narrow: focus pills in both interfaces, real data and
|
||||
account-aware state, independent placements and servers, and the copy “Event data may be out of
|
||||
date.” Never ship the prototype's fixed clock, synthetic events/history, demo toolbar or demo state.
|
||||
|
||||
## What this attempt changed
|
||||
|
||||
This is an inventory, **not a list of accepted presentation decisions**:
|
||||
|
||||
- `src/client/ReaderApp.tsx`: central shared UI composition, navigation counts, release notice,
|
||||
settings routing, dedicated checklist components, archive-detail routing.
|
||||
- `components/redesign/ChecklistEvent.tsx`: new event rows and `NextDeadline`, replacing old
|
||||
`EventRow`/`NextUp` usage in the active Checklist.
|
||||
- `FocusPicker.tsx`, `DailyPanel.tsx`, `RoutineGroup.tsx`: rail and direct progress controls.
|
||||
- `RoutinesPage.tsx`, `RoutineEditor.tsx`: reset/game grouping, table columns, progress bars,
|
||||
library, independent pin controls and native custom-routine drawer.
|
||||
- `TimelinePage.tsx`: shared time grid for events and routine periods, sticky names, progress fill,
|
||||
resets, zoom and mixed deadline queue. Sticky bar labels were repaired after review.
|
||||
- `ArchivePage.tsx`, `ArchiveStory.tsx`, `ArchiveDetail.tsx`: outcome story/filter/sidebar/list/history
|
||||
and a saved-record dialog. The archive dialog reads recorded progress rather than today's live
|
||||
event state.
|
||||
- `SettingsLayout.tsx`, `GameSettings.tsx`, `AppearancePage.tsx`, `TrackingChoices.tsx`: individual
|
||||
game navigation, separate settings pages, interface/scheme controls, tracking/server/colour/reset
|
||||
groups. The final profile uses tabs to choose which server's tracking choices are edited.
|
||||
- `SetupWizard.tsx`, `EventDetail.tsx`: modified setup/detail presentation, retaining much existing
|
||||
form content.
|
||||
- `src/client/redesign.css`: large stylesheet, with initial rules plus later overrides. It is about
|
||||
2,900 lines and contains repeated selectors and superseded layout rules.
|
||||
- `state/usePrefs.ts`, `state/appearance.ts`, `index.html`: Structured default and interface grounds.
|
||||
- Tests and docs were updated. No change in this attempt intentionally reminted event/account IDs.
|
||||
|
||||
Component shorthand above resolves to `src/client/components/redesign/`, except `EventDetail.tsx`,
|
||||
which is `src/client/components/EventDetail.tsx`. `state/` shorthand resolves under `src/client/`.
|
||||
`AppNavigation.tsx` was also changed: live counts and Settings placement. The new component files
|
||||
introduced by this attempt were `ChecklistEvent.tsx`, `FocusPicker.tsx`, `RoutineEditor.tsx` and
|
||||
`ArchiveDetail.tsx`; many other untracked files were already present from the preceding agent.
|
||||
|
||||
Additional implementation details worth retaining:
|
||||
|
||||
- `prefs.routineGroup` is a new optional stored preference: absent/`reset` means By reset; `game`
|
||||
means By game. It uses the existing permissive preferences envelope, with no new storage key.
|
||||
- `appearance.ts` applies Structured Slate grounds/surfaces separately from Relaxed, while keeping
|
||||
contrast adjustment and existing custom palettes. The CSS and runtime tokens must be examined
|
||||
together: runtime variables can override apparent reference values in the stylesheet.
|
||||
- `TimelinePage` exports `routinePeriod`, also used for Routines reset countdowns. It uses resolved
|
||||
reader clocks, not guessed UTC boundaries. Custom timeline occurrences respect account event intent.
|
||||
- `placementAccounts` in `RoutinesPage` combines bulk pin changes per account. Reverting to one stale
|
||||
full-account write per row can silently undo an earlier row's placement.
|
||||
- `ArchiveDetail` displays the stored outcome/date/note/check-ins/amounts; Restore uses the existing
|
||||
reducer. Already-ended records can be reconciled back into history. It is intentionally separate
|
||||
from the live `ReaderDetail` adapter.
|
||||
- `RoutineControl` keeps a numeric draft during editing so a transient empty input is usable.
|
||||
Game colour previews use the rendered, contrast-adjusted game metadata.
|
||||
- The profile server tabs are an implementation adaptation, not a separately approved owner design.
|
||||
The reviewer accepted them within its narrow follow-up; the owner's overall rejection supersedes
|
||||
that. Revisit them if they are among the differences the owner identifies.
|
||||
|
||||
Tests changed during this attempt:
|
||||
|
||||
| File under `test/` | Change |
|
||||
| --- | --- |
|
||||
| `appearance.test.ts` | Structured default and retained explicit Relaxed distinction |
|
||||
| `prefs.test.ts` | Default/fallback expectations and saved Relaxed normalization |
|
||||
| `reader-store.test.ts`, `reader-restore.test.ts` | Test choices adjusted so writes/restores still change the now-Structured default |
|
||||
| `redesign-timeline.test.tsx` | Routine resets participate in mixed Ending soonest order |
|
||||
| `redesign-routines.test.tsx` | Bulk placement combines per account and preserves the other view's pin |
|
||||
| `game-settings.test.tsx` | Updated expected guidance for independent server progress |
|
||||
|
||||
Documentation touched by this attempt includes `AGENTS.md`, `docs/PRD.md`, `DATA-MODEL.md`,
|
||||
`DESIGN.md`, `ARCHITECTURE.md`, the approved spec/plan, the first handoff, the correction report,
|
||||
and `.superpowers/sdd/2026-10-16-ui-redesign/progress.md`. Other dirty docs and ingestion files may
|
||||
belong to the earlier agent; do not attribute all of `git diff HEAD` to this attempt. There is no
|
||||
clean per-agent commit boundary. The real changed code remains in the working tree.
|
||||
|
||||
## What went wrong
|
||||
|
||||
### 1. Translation remained approximate
|
||||
|
||||
The first rejected agent had wrapped old presentation with new CSS. This agent replaced more actual
|
||||
markup, but still recreated the reference piecemeal instead of establishing a complete translation
|
||||
of the final reference structure. It retained old form internals and filled gaps with implementation
|
||||
choices, then added CSS overrides until selected screenshots looked closer.
|
||||
|
||||
Concrete examples caught during this attempt's review were substituted Settings navigation, a
|
||||
routine Cycle column and missing live summary, invisible timeline bar text, and game colour above
|
||||
tracking with repeated tall account blocks. Those particular defects were subsequently corrected.
|
||||
**Their correction is not proof that the remaining screens or overall design are faithful.** The
|
||||
owner's latest rejection requires a fresh understanding of the gaps, starting with their feedback.
|
||||
|
||||
### 2. Comparison fixtures made the evidence narrower than the claim
|
||||
|
||||
`docs/design-reviews/fidelity-capture.mjs` freezes the clock, intercepts the event-feed request with
|
||||
mockup events, and seeds disposable routine/archive state. That can isolate visual differences, but
|
||||
it is not the app the owner browsed. For Checklist it explicitly hides `.updates-panel` and
|
||||
`.release-update` to align the first viewport. The comparison's event/account counts also differ
|
||||
from the prototype, and the custom prototype routine was not seeded.
|
||||
|
||||
A real-feed capture after the rejection shows two prominent notice bands above Running now, many
|
||||
short title-only events, and much different content density. A fixture-based image with hidden
|
||||
notices did not validate that real first impression. Do not suppress production UI in an acceptance
|
||||
capture. If fixture comparison remains useful, label it as a separate diagnostic and also capture
|
||||
the exact normal-use state the owner is judging.
|
||||
|
||||
### 3. Functional checks became a proxy for the visual task again
|
||||
|
||||
Tests, no-overflow checks, correct IDs, working locks and successful actions are necessary. They
|
||||
cannot certify fidelity. This attempt's final response led with rebuilt screens and test success
|
||||
and reported that review cleared the issues. That was too strong for the evidence and the owner's
|
||||
actual experience.
|
||||
|
||||
### 4. The independent review's scope was stretched
|
||||
|
||||
The reviewer found a finite list of material issues, then scored fixes to that list. Its final
|
||||
verdict was **“ship the reviewed corrections”**, explicitly limited to those findings, not blanket
|
||||
acceptance. Subsequent passes were instructed not to reopen a wider hunt. That process could verify
|
||||
local repairs while leaving broader divergence undiscovered. The owner rejected the result anyway.
|
||||
|
||||
Do not continue from the review's ship verdict. Treat the supplied user feedback as the next primary
|
||||
input, then review the whole affected composition against the rendered reference.
|
||||
|
||||
### 5. Documentation presented implementation as the design truth
|
||||
|
||||
`docs/DESIGN.md` and the 2026-10-17 correction report describe the implemented design confidently.
|
||||
They are records of what was built, not evidence that it is approved. Earlier failure had the same
|
||||
pattern. Keep requirements, current implementation, functional verification and owner acceptance
|
||||
separate. Do not rewrite the spec to make the implementation look compliant.
|
||||
|
||||
## Evidence and limits
|
||||
|
||||
- Historical correction report and staged comparison images:
|
||||
`docs/design-reviews/2026-10-17-redesign-fidelity.md` and its linked assets.
|
||||
These now carry a rejection warning. They document a rejected attempt, not new visual goldens.
|
||||
- Fresh real-feed audit image:
|
||||
`docs/design-reviews/assets/2026-10-17-second-rejection/current-structured-checklist.png`.
|
||||
- Fresh first-visit setup image:
|
||||
`docs/design-reviews/assets/2026-10-17-second-rejection/current-structured-setup.png`.
|
||||
|
||||
The two fresh images used Chrome at 1440×1000 on `http://10.20.20.2:41908`. The setup was a clean
|
||||
browser context. For Checklist, that disposable context was marked onboarded and limited to
|
||||
Genshin/HSR/ZZZ/Wuwa; the actual feed and notices were retained, with no request interception.
|
||||
**These are not screenshots of the owner's browser or stored preferences.** The browser reported
|
||||
Structured and loaded Barlow/Barlow Condensed. This rules out missing fonts in that test context
|
||||
only; it does not identify the owner's complaint or prove their environment matches it.
|
||||
|
||||
One observable item for later inspection: the actual audit showed a Checklist header count of 46
|
||||
and Focus All count of 60. They currently count different row sets. Do not claim this is the owner's
|
||||
main concern without asking. Likewise, correct shorter rows without descriptions are an approved
|
||||
requirement, so do not fabricate summaries merely to match fixture density.
|
||||
|
||||
## Preserve the working state and domain work
|
||||
|
||||
HEAD remained `ee41389`. The checkout is dirty on `main`; the last status had 89 modified/untracked
|
||||
entries including work that predates this agent. No commit, push, PR or deployment was made. Running
|
||||
a local preview server was explicitly authorized. Do not reset, clean untracked files, discard the
|
||||
reader implementation or create a new branch/worktree without a new reason/owner instruction.
|
||||
|
||||
Preserve, or carefully test any necessary changes to:
|
||||
|
||||
- v2 reader envelope, migration/recovery, unchanged IDs and legacy bytes;
|
||||
- account-specific progress, saved clocks and archive snapshots;
|
||||
- Web Locks plus IndexedDB serialization fallback, save failures and cross-tab synchronization;
|
||||
- backup/export/import/recovery and independent code seen/redemption state;
|
||||
- unknown-end/date-precision semantics and community-source conduct;
|
||||
- insecure HTTP identity generation using `crypto.getRandomValues`, not `crypto.randomUUID`;
|
||||
- new Structured default and explicit saved Relaxed preference;
|
||||
- useful fixes from this attempt: bulk routine placements saved together per account, row keys
|
||||
containing account+routine, and archived details using saved snapshots.
|
||||
|
||||
The most recent successful checks before handoff were 1,594 tests passing, TypeScript passing,
|
||||
production build `a28021bbe1a8`, ordinary HTTP migration/setup/server/reset/backup checks, numeric
|
||||
progress and routine creation, completion/Undo/archive Restore, and separate concurrent/offline
|
||||
browser checks. The Docker-equivalent file layout passed 1,593 tests with one intentional skip;
|
||||
no Docker image was built. This is functional evidence only, not visual acceptance.
|
||||
|
||||
## Recommended continuation after owner feedback
|
||||
|
||||
1. Write down the owner's biggest differences in their words, with the relevant interface, screen
|
||||
and viewport. Launch-and-ask comes before implementation.
|
||||
2. Render that exact approved reference state and current app state. Compare actual content,
|
||||
visible notices and first-visit/returning conditions as appropriate. Record differences in
|
||||
topology, dimensions, type hierarchy and controls, not just a list of CSS values.
|
||||
3. Repair that bounded surface by translating the final reference markup and styles into the real
|
||||
component tree. Replace rejected structure when needed; avoid another stylesheet of corrective
|
||||
overrides over structurally different elements.
|
||||
4. Keep an explicit list of necessary real-data/accessibility adaptations, with reasons. Ask the
|
||||
owner when an adaptation changes a visible product decision instead of silently choosing it.
|
||||
5. Show the normal running build to the owner at the chosen checkpoint. A fixture capture, passing
|
||||
detector or subagent approval cannot substitute for checking their reported differences.
|
||||
6. Then carry accepted treatment across the remaining screens, checking both interfaces and mobile,
|
||||
with functional regression checks proportional to the change. Correct docs only to reflect what
|
||||
has actually been established.
|
||||
|
||||
No further UI implementation was performed after the owner requested this handoff.
|
||||
|
||||
|
||||
## New-session continuity checklist
|
||||
|
||||
- Start the new session in **this same checkout**. All implementation files, reference HTML,
|
||||
screenshots, plans and handoffs are on disk, including untracked files. A fresh clone of HEAD
|
||||
will NOT contain this work; no commit/push was authorized or performed.
|
||||
- This handoff plus the linked spec, previous handoff and review records contain the material
|
||||
decisions and continuation context. They are not a verbatim chat transcript. The owner's exact
|
||||
visual objections beyond “not even close” are deliberately marked unknown because they were
|
||||
never supplied; the next session must ask, not reconstruct them from guesses.
|
||||
- The latest user instruction is to pause implementation for handoff, then have the next agent
|
||||
launch the current server and ask about the biggest differences. No new design was approved
|
||||
after either rejection. No permission to commit/publish was given.
|
||||
- `public/` and `public/data/` are ignored build artifacts. Keep the current feed when starting;
|
||||
if it is absent, use the documented offline feed build, not a network refresh. A changed port
|
||||
is a different browser origin, so it will not automatically carry the owner's saved progress.
|
||||
Do not clear or migrate the owner's browser storage merely to obtain a clean screenshot.
|
||||
- Durable reproduction entry: `docs/design-reviews/fidelity-capture.mjs`, with reference fixtures
|
||||
beside its images. Its staged-state limitations are described above. Chrome is at
|
||||
`/usr/bin/google-chrome-stable`; install/use Puppeteer in scratch, not project dependencies.
|
||||
- `/tmp/fidelity-http-final.mjs`, `/tmp/fidelity-journeys.mjs`, `/tmp/fidelity-matrix.mjs` and logs
|
||||
were scratch functional checks, not durable requirements. They may still exist, but have fixed
|
||||
ports and scratch imports; do not assume they survive or run unchanged. Standard test commands,
|
||||
checked-in test sources and the recorded browser scenarios are the durable verification contract.
|
||||
- Preview/mockup processes may survive: this run used app ports 41902–41908 and mockup41901.
|
||||
Inspect before starting/stopping; never `pkill -f serve.ts`. PID2536610 was the owner preview at
|
||||
recording time, not a permanent identity. Do not treat old port numbers or tool session IDs as
|
||||
proof of the build currently being served.
|
||||
- No UI edits were made in the handoff/continuity-check turns. The second-rejection warnings in
|
||||
the older report, plan and design documentation exist to prevent another agent mistaking their
|
||||
earlier positive wording for owner acceptance.
|
||||
|
||||
## Session 3 (2026-10-17): owner feedback on new-user setup, and the rebuild
|
||||
|
||||
The owner chose to start with new-user setup, against Round 6 (`b-rail.html`, final `onboarding()`).
|
||||
Their differences, in their words, summarised:
|
||||
|
||||
1. Screen 1: “The margin/padding, sizing and placement of buttons is off.”
|
||||
2. Screen 2: “The games are way too big, and not grouped together, not shown with colors, no
|
||||
choose all games instead. The back button does work better though.”
|
||||
3. Screen 3: no table to choose events/dailies/weeklies; instead the per-game subscription block
|
||||
was “copy pasted” for every game. “Show events that haven't started” was “a random, flowing
|
||||
button”; in the mockup it sits between dividers with a description.
|
||||
4. Screen 4: “a weird checklist-timeline switch, instead of the drawing and descriptions the
|
||||
mockup has.”
|
||||
|
||||
What changed: `SetupWizard.tsx` was rewritten as a translation of the rendered mockup markup
|
||||
(`.ob`, `.preference-grid`, `.gpick`, `.type-guide`, `.availability`, `.mtx`/`.tg` with a
|
||||
“Same for all” row and mixed state, `.upcoming-choice`, `.vcard` previews, `.ob-foot`), and the
|
||||
scattered `.setup-wizard` overrides in `redesign.css` were replaced by one block at the end of the
|
||||
file translated from the mockup's rules. Game order follows `GAMES`; colours use the app's
|
||||
contrast-adjusted `meta`.
|
||||
|
||||
Deliberate deviations, for the owner to confirm:
|
||||
|
||||
- The Interface select and the “Everything stays in this browser” line were removed from step 1:
|
||||
neither is in the mockup or the spec's setup list. New installs still get Structured, and
|
||||
Interface remains in Settings → Appearance.
|
||||
- The back link reads “Back” on every step (the mockup says “Preferences” on step 2), because the
|
||||
owner said the current back button works better.
|
||||
- The tracking table's row headers are `<th scope="row">` rather than `<td>`, for screen readers.
|
||||
|
||||
Evidence is functional and side-by-side capture only (1440 and 390, dark, fresh browser, real
|
||||
feed, no interception). **Owner acceptance of these screens is still pending.**
|
||||
|
||||
### Setup accepted as “much better”; Checklist requests (same session)
|
||||
|
||||
The owner then asked, for the Checklist: “Add the time left bar to the compact screen. Make the
|
||||
pill menu smaller. Let users sleep/dismiss the event data may be out of date for up to 7 days.”
|
||||
|
||||
- Compact rows now show the time-left meter on every row, in a fixed 120px column left of the
|
||||
time (under the time on phones). Standard rows are unchanged: the meter only accompanies a
|
||||
description.
|
||||
- Focus pills are smaller (24px high, 11.5px text, tighter gaps), kept at 30px on coarse pointers.
|
||||
- The source-age notice offers “Hide for 1 day / 3 days / 7 days”. It stores
|
||||
`prefs.staleSnooze = { until, games }` in the existing permissive prefs envelope (no new storage
|
||||
key). It returns when the time passes, when a game outside the snoozed set goes stale, or if the
|
||||
saved value is malformed or more than seven days ahead. Settings → Source status and the
|
||||
per-event detail notice are not snoozed.
|
||||
|
||||
### Checklist follow-up (same session)
|
||||
|
||||
Owner: “In compact view, there needs to be some more air, like there is in the mockup compact
|
||||
view. In standard view, the space between the bottom of the Running now [heading] and the first
|
||||
event in the list is too big. The Next to expire is too small, compared to the easier to read one
|
||||
in the mockup, and it doesn't show the next 3 ones to expire, like it does in the mockup.”
|
||||
|
||||
- Compact is now a translation of the Round 6 B ledger (`table.led`): column headings Game /
|
||||
Event / Time left / Ends in, a 3px game stripe with the short name, 15px titles, a 34%-wide
|
||||
meter and a 20px condensed time, in 51px rows. It is drawn as a CSS grid over the existing
|
||||
`<li>` rows (`LedgerColumns`, `ChecklistEvent compact`) so archive fade/confirm transitions keep
|
||||
working. Under 860px the game column hides, the game name moves above the title and the meter
|
||||
spans the row. This replaced the earlier compact `.event-entry` rules entirely.
|
||||
- Note on references: Round 6 **B** and Round 7 render but hide the rail's “then” list
|
||||
(`.rail .then{display:none}`); Round 6 **A** shows it with a 30px title and 64px countdown. The
|
||||
owner asked for the mockup's larger rail with the next three, so the rail head now follows A's
|
||||
proportions (52px under 1050px; the phone sizes and hidden list at 700px are unchanged).
|
||||
- `.list-heading` bottom padding 22px → 8px (Relaxed 18px → 8px).
|
||||
- Relaxed was not visually captured for these changes.
|
||||
- Rail routines heading (owner): title is “Routines” with “Showing only pinned” as its subtext;
|
||||
the “Focus on a game to open its routines.” hint was removed as not worth the text (groups still
|
||||
auto-open on focus).
|
||||
|
||||
### Timeline (same session)
|
||||
|
||||
Owner: the implemented Timeline resembles the mockup well, but lost the liked resemblance to the
|
||||
paimon.moe-style board on the live site; keep the new design and add a switch between the looks.
|
||||
The scroll-following bar text of the new look is liked. Dailies should not be on the timeline. Add
|
||||
a checkbox for time left vs end date. Add a divider where routines start when they have their own
|
||||
section, and rename “Separate reset strips” to “Show routines in own section”. Later: in new-user
|
||||
setup, when Timeline is chosen, show both designs and ask.
|
||||
|
||||
Owner's answers to clarifying questions: default look **New**; switch in the **Timeline controls
|
||||
bar**; classic **reproduced as production** (no added scroll-following text); routines in classic
|
||||
go in **their own section** under a divider.
|
||||
|
||||
What was built:
|
||||
|
||||
- `prefs.timelineLook` (`"new"` default | `"classic"`) and `prefs.timelineLabel` (`"left"` default
|
||||
| `"end"`), both in the permissive prefs envelope. The classic look reuses the production board
|
||||
(`components/Timeline.tsx`) with its own By game / Ending soonest, zoom and Jump to today
|
||||
controls; the new look keeps its controls. The look switch sits first in the options bar.
|
||||
- Classic gained an optional `routines` section (`ClassicRoutine`): a divider labelled Routines,
|
||||
then per-game lanes of dashed-edge bars in the board's style, clamped to the board's window and
|
||||
with names pinned like its event bars.
|
||||
- Dailies (`cadence === "day"`) never appear on either look (`onTimeline`). The Routines page shows
|
||||
a dash instead of a Timeline pin for dailies, and hides bulk “pin to Timeline” on daily-only bands.
|
||||
- “Show end dates instead of time left” switches new-look bar text to “Ends 20 Oct” and routine
|
||||
bars to “resets <date time>”. It does not change the classic look, which shows titles only.
|
||||
- New-look divider: a dashed rule with a sticky ROUTINES label before each game's routine rows
|
||||
when “Show routines in own section” is on.
|
||||
- Setup step 4: choosing Timeline reveals “Which timeline design?” with drawn New / Classic cards;
|
||||
`SetupDraft.timelineLook` is saved only when the reader starts on Timeline.
|
||||
|
||||
### Timeline follow-up: shared pill header, look in Settings, focus bar setting
|
||||
|
||||
Owner: the options (By game / Ending soonest, routines in own section, end dates) must work in the
|
||||
classic look too; the classic board's small pill toggles look better than the big options bar; the
|
||||
New/Classic switch belongs in Settings. Then: the focus bar moves under the pill header on the
|
||||
Timeline, with a Settings option to show it on the Checklist and/or Timeline.
|
||||
|
||||
- `BoardHeader` and `TogglePill` (exported from `components/Timeline.tsx`) are the one header for
|
||||
both looks: stacking pills, “Show routines in own section” and “Show end dates” toggle pills,
|
||||
small −/+ and Jump to today. The old `.timeline-options` bar and its CSS are gone.
|
||||
- Classic now honours both options: `routinesInline` (off → routines at the end of each game's
|
||||
lane; on → own section under the divider) and `label` (time left / end date shown inside the
|
||||
pinned name, after the title, shrinking before the title does; omitted on bars under 150px).
|
||||
- Settings → Appearance: “Timeline design” (New / Classic) and “Focus bar” with “Show on the
|
||||
Checklist” / “Show on the Timeline” (`prefs.focusBar = { checklist, timeline }`, absent = both).
|
||||
A view whose focus bar is hidden ignores `focusGame`, so a focus chosen elsewhere can never
|
||||
filter a page with no visible way to clear it. `TimelinePage` now receives `focus` and
|
||||
`focusBar` from `ReaderApp` instead of reading `focusGame` itself.
|
||||
- The classic board keeps its header and focus bar when it has nothing to plot, and draws the
|
||||
board when only routines exist.
|
||||
- Setup copy now points to Settings → Appearance for switching designs.
|
||||
|
||||
### Timeline polish (same session)
|
||||
|
||||
Owner: focus bar needs one row on large screens and no “Focus” text; By game / Ending soonest
|
||||
should share an outline; the two options need an off affordance (checkboxes); routine items could
|
||||
not be opened, so progress could not be tracked; the classic NOW chip was almost unreadable; open
|
||||
far enough back / zoomed out so most text shows; always prefer the title over time left / end date.
|
||||
|
||||
- Header: the stacking pair is one rounded outline with the chosen side filled; the options are
|
||||
small checkboxes (`ToggleOption`, replacing `TogglePill`).
|
||||
- Timeline focus row (`.timeline-focus`): pills and Next on one row, heading hidden; wraps on
|
||||
phones.
|
||||
- Routines open a modal dialog (`RoutineDetail` in `TimelinePage.tsx`) from both looks: game and
|
||||
server, title, reset time, and the shared `RoutineControl` for progress. It replaced the
|
||||
off-screen `.timeline-routine-detail` section.
|
||||
- Opening position (`openingLeft`, both looks; also Jump to today): back to the median running
|
||||
start, with now kept between 25% and 50% across. The default zoom (32px/day) is unchanged;
|
||||
readers who already zoomed keep their saved width.
|
||||
- Classic NOW chip: inline critical background and ground-coloured bold text (`.eyebrow` had been
|
||||
overriding the text colour with faint ink).
|
||||
- Classic labels: shown only when `labelFits` estimates room for the whole title and the label.
|
||||
- **Deferred by the owner:** an option, per routine or for all routines, to show routine dates
|
||||
only without tracking progress.
|
||||
- Footer (owner: “sometimes sticky… should not stick and take up space unless you've scrolled all
|
||||
the way down”): the footer was never sticky. The Timeline boards scrolled inside a pane capped at
|
||||
72vh, so the page bottomed out early and left the footer on screen while the board scrolled.
|
||||
Both panes (`.timeline-scroller`, classic `.scroll-pane`) are now capped at `100dvh`: with the
|
||||
board filling the window the footer is below the fold, and appears only past the board's end.
|
||||
|
||||
### NOW chip, server names, labels (same session)
|
||||
|
||||
Owner: make “now” even more readable; drop “europe” unless a game has two regions; if title and
|
||||
end date cannot both be shown in full, drop the end date rather than truncating it.
|
||||
|
||||
- Classic NOW chip: 12px bold display caps, white on a fixed `#d42a47` (≈5:1), 2px ground ring.
|
||||
- `state/reader/servers.ts`: `manyServers` / `serverSuffix`. Reading views (Checklist rows, Next to
|
||||
expire, dailies, rail routine groups, Routines table, both Timeline looks, routine dialog,
|
||||
updates, archive list/detail) name a server only when the game has more than one active account
|
||||
(archives also count retired ones). Settings views still name servers, where they are the subject.
|
||||
The “New since you last looked” row now names the game instead of the server.
|
||||
- Classic bar names are one-line wrapping rows with overflow hidden: the title truncates only when
|
||||
it alone is too long; labels (and routine progress) never shrink and simply wrap out of view
|
||||
when they do not fit whole. `labelFits` was removed.
|
||||
- Header options are now three either/or pill pairs (`PillChoice`, which also draws the stacking
|
||||
pair): By game / Ending soonest, Show time left / Show end dates, Group routines and events / Show
|
||||
routines in own section. `ToggleOption` (checkboxes) was removed.
|
||||
|
||||
### Routines view (same session)
|
||||
|
||||
Owner: Timeline accepted (“looking good now”). Routines: the Checklist/Timeline pin icons are not
|
||||
centred and look odd against the mockup; text does not sit together as in the mockup; keep the
|
||||
game colour bars; an always-open editor adds clutter — match the mockup, but show that progress
|
||||
is editable and let the reader enter their own.
|
||||
|
||||
- The table is now a translation of Round 6 B `table.rt`: quiet 11px headings with the list/bars
|
||||
icons on the pin columns, `.gcell` colour bar + short name (server only when several), 15px/500
|
||||
titles muted when met, `.pin` 34×28 icon buttons (plain when off; near-tinted outline when on),
|
||||
and a `.kebab` “⋯” summary for the existing menu.
|
||||
- `RoutineProgress.tsx` replaces `RoutineControl` in this table only: `.tick` (Done / To do, or
|
||||
“n of m days”) and `.amt` (bar + “**2** / 3 runs”, unit from the task or built-in). Amounts read
|
||||
as text; a pencil (brightens, number gets a dashed underline on hover/focus) signals they are
|
||||
editable. Click opens an inline number field + Save; Enter saves, Escape or leaving cancels.
|
||||
`RoutineControl` still serves the Checklist daily panel and the Timeline routine dialog.
|
||||
- All `.routine-table`/`.routine-pin`/`.routine-progress`/`.progress-track`/`.rtitle` rules
|
||||
(51, including phone variants) were removed rather than overridden; a single `.rt` block holds
|
||||
the replacement. On phones, hidden Routine/Progress headings keep their cells so pin headings
|
||||
stay aligned.
|
||||
- Owner follow-up: pins fade (150ms colour/background/border, skipped under reduced motion), and a
|
||||
pinned pin previews “unpin” on hover (thinner tint, dashed outline). Ticks no longer carry
|
||||
“To do / Done” text; multi-day routines keep “n of m days”, and the aria-label keeps the state.
|
||||
|
||||
### Library and create shelves (same session)
|
||||
|
||||
Owner: Routines accepted. Library and Create “lack a lot from the mockup… they are shelves in the
|
||||
mockup, where they are weird in the live”. Owner chose to add all four missing create fields now
|
||||
(Every day, Another hour, Note, Link) rather than defer the data changes.
|
||||
|
||||
- `RoutineDrawer.tsx`: one right-docked modal `<dialog>` (580px, dimmed backdrop, Escape) with two
|
||||
panes translated from Round 6 B `libraryDrawer` / `createDrawer`:
|
||||
- Library: Create-your-own card, intro, search, “New follows also show in Checklist/Timeline”,
|
||||
per-game sections (“n of m followed · k servers”, Follow all weeklies/monthlies/cycles/
|
||||
everything), rows with “Every Monday at 04:00 · 3 runs · Community wiki, checked 14 Oct 2026”
|
||||
and a Follow/Following button, or one button per server (EU/NA/Asia) when several.
|
||||
- Create/Edit: examples (mockup's five), What is it, Game, Server (select when several, note
|
||||
otherwise), Repeats (day/week/month/N days + its detail row), Resets at (game reset / another
|
||||
hour), Done when (once / several days / a number), Note, Link, Also show in (Timeline disabled
|
||||
for dailies), live Preview, Create and follow / Cancel with a “Still needed” line.
|
||||
- The library page mode and `RoutineEditor.tsx` (+ `.routine-editor` CSS) were removed. New
|
||||
routines now follow on the chosen server only, with the chosen pins; edits keep placements.
|
||||
- Data: `PeriodSchema` + `{unit:"day"}`; `TaskSchema` + optional `resetHour`, `note`, `link`
|
||||
(http/https only); `GoalStatus.scope` + "day"; a task's `resetHour` swaps only the hour on its
|
||||
row clock (same revision key). Notes show under the title in the table; links feed the menu's
|
||||
Source item. Page summary no longer counts dailies as timeline pins.
|
||||
- schema-guardian review of the routine format change: no blocker. Nothing stored is dropped or
|
||||
re-keyed; the HEAD build keeps unreadable tasks raw and carries unknown fields through edits, so
|
||||
new-format routines survive (a `day` routine is just invisible there). Fixed its two should-fix
|
||||
items: the edit form warns when a reset-hour change will move which day logged ticks count for,
|
||||
and `RoutineHistory` computes “today” and the catch-up window from a routine's own reset hour.
|
||||
Notes left as-is: legacy `Dailies.tsx`/`migration.ts` paths cannot meet `day` routines today
|
||||
(no caller for the legacy strip filter; legacy data cannot contain `day`).
|
||||
- Owner accepted the create shelf. Library Follow/Following buttons now fade (150ms, skipped under
|
||||
reduced motion), matching the Routines pins.
|
||||
|
||||
### Top bar (same session)
|
||||
|
||||
Owner: the logo and the tabs sit at different heights, so the bar feels off-centre. Measured: the
|
||||
logo's text baseline was 3px above the tab labels' (38 vs 41px; the mockup bottom-aligns boxes,
|
||||
which reads the same way with a 20px logo beside 15px tabs). Structured `.reader-ui .top` now uses
|
||||
`align-items: baseline` and `.mark` has no bottom padding, so logo, tabs and Settings share one
|
||||
baseline at the same 57px header height. Relaxed keeps `center` (its tabs are rounded pills).
|
||||
- Owner: “the logo still looks higher than the tabs”. A shared baseline still left the logo's 15px
|
||||
capitals centred 2px above the tabs' 11px capitals. `.mark` now also has `position: relative;
|
||||
top: 0.1em` (half the cap-height difference), so both sets of capitals centre at the same line
|
||||
(measured 35.5px). Reset to 0 in Relaxed and on phones, where the logo is not beside the tabs.
|
||||
|
||||
### Settings: About and Data & sources (same session)
|
||||
|
||||
Owner: dates and event-data refresh do not belong in About; move them to Data & sources, and make
|
||||
the implemented pages look more like the mockup.
|
||||
|
||||
- `AboutPage.tsx` (replaces the `Colophon` render in Settings): the Round 6 B single-column
|
||||
`.about-prose` — intro, Made by (author, GitHub, source code / report a problem / request a
|
||||
feature / support), source editors (derived from every feed source via Colophon's `siteFor`),
|
||||
Game-Time-Master, studios, idea credits, Unofficial and unaffiliated, and a “See data freshness
|
||||
and source status” button. No dates or freshness.
|
||||
- `DataSourcesPage.tsx`: intro (incl. which timezone dates use), Check for new data (shares the
|
||||
footer's handler, now `refreshFeed` in ReaderApp), “Event data last refreshed … · ago”, a stale
|
||||
warning naming the affected games, and one `.source-row` per game with each source's last
|
||||
successful check, last content change, a status sentence in the mockup's four cases
|
||||
(`sourceReason`) and Check source page. `.source-record` CSS removed.
|
||||
- Every settings title now sits on the mockup's `.ptitle` rule.
|
||||
- `Colophon.tsx` is no longer rendered by the reader app; its exported constants and `siteFor`
|
||||
are reused.
|
||||
- Owner follow-up: About's “The studios and games” lists every game again in its own (contrast-
|
||||
adjusted) colour after the studios; the “See data freshness” button was removed from About.
|
||||
|
||||
### Changelog (same session)
|
||||
|
||||
Owner: make the changelog look like the mockup, keeping the commit history, spec links and the
|
||||
New / Games & sources / Fixed kinds. `ChangelogPage.tsx` now renders its own Round 6 B
|
||||
`.changelog-page .rel` markup (the sheet still uses `ChangelogContent`): an uppercase date line
|
||||
with the note's kinds, a 26px condensed title, summary paragraphs, the covered commits as a bullet
|
||||
list each ending in a coloured kind tag and its hash link, then “Commits a…b” and “Spec: …” links;
|
||||
loose commits follow under “Other changes” by month.
|
||||
|
||||
### Reload keeps your place (same session)
|
||||
|
||||
Owner: refreshing always returned to the default view. The page was React state only
|
||||
(`useState(prefs.view)`). `state/route.ts` now maps the page, the Settings section and a game's
|
||||
settings page to the address hash (`#checklist`, `#timeline`, `#routines`, `#archive`,
|
||||
`#settings/<section>`, `#settings/games/<game>`). ReaderApp starts from a valid hash, keeps it in
|
||||
sync with `history.replaceState` (no history entry per click) once onboarded, follows manual hash
|
||||
edits, and rewrites an unknown hash to the current page. No hash still opens the default view.
|
||||
Browser-checked: Timeline, Settings → Changelog, a game page and Archive all survive a reload.
|
||||
|
||||
### Region & time (same session)
|
||||
|
||||
Owner: timezone search did not seem to work; is it needed, or should the full list just appear?
|
||||
Cause: the search box filtered the options of a closed select (no visible effect until opened)
|
||||
and matched raw IANA ids only. Decision: removed the search. `TimezoneSelect.tsx` is one native
|
||||
select — Automatic (device zone + offset) first, then every zone grouped by region (`optgroup`),
|
||||
named by city (“Buenos Aires, Argentina · GMT-3”); typing in the open list jumps to a city. Used by
|
||||
Settings and new-user setup. `TimeSettings.tsx` now follows Round 6 B: intro, Default game server
|
||||
as a segmented control, Your timezone with a “Currently displaying …” note, and Reset timing for
|
||||
your games — one row per server with its automatic/custom reset, your local time and countdown,
|
||||
and a Reset timing select (Automatic or a whole hour) that appends a clock revision like the game
|
||||
page's override (earlier progress kept). Rows resolve the clock at max(now, real time) so a just-
|
||||
saved revision shows immediately.
|
||||
|
||||
### Default view moved into Appearance (same session)
|
||||
|
||||
Owner: move Default view under Appearance and match the mockup's iconography. The separate
|
||||
“general” settings section is gone; Appearance has a Default view group with the Round 6 B drawn
|
||||
view cards (`ViewCards.tsx`, shared with new-user setup), the mockup's copy, and Replay the
|
||||
introduction. `#settings/general` and a bare `#settings` now open Appearance. The view-card CSS was
|
||||
un-scoped from `.setup-wizard` (with its border token defined on `.viewpick`).
|
||||
- Owner: Lists options move into Data & sources. The “lists” settings section is gone; Data &
|
||||
sources ends with an “In your lists” group (Show events that haven't started; Detect daily
|
||||
events from source descriptions), each with a one-line explanation. `#settings/lists` opens Data
|
||||
& sources. Appearance's menu subtitle is now “Theme, colours & default view”.
|
||||
- Owner: list options belong before the long source list. “In your lists” now sits directly under
|
||||
the refresh line and stale warning, above the per-game source rows.
|
||||
- Owner: “In your lists” goes even before the source explanation. It is now the first group
|
||||
under the title; everything about sources follows under a matching “Sources” heading.
|
||||
|
||||
### Backup (same session)
|
||||
|
||||
Owner: Backup must match the mockup much more closely. `BackupPage.tsx` keeps every action and its
|
||||
logic (back up now, export/import all, progress-only export/import, undo last restore, restore
|
||||
preview) in the Round 6 B layout: intro, a 7 days / 4 weeks / 6 months policy strip, the note,
|
||||
outlined actions (Back up now solid; file inputs hidden behind their labels, still focusable),
|
||||
then Daily / Weekly / Monthly sections (“n snapshots · span”) whose rows show the date, a summary
|
||||
of that snapshot's tracked games, followed routines and archived events, and View backup.
|
||||
`backupTier` (state/reader/backups.ts) classifies snapshots with the same windows
|
||||
`retainBackups` keeps, tested against it. Old `.backup-*`/`.file-button` CSS was replaced.
|
||||
Restore itself was not exercised in the browser (it reloads); its logic is unchanged.
|
||||
- Owner: Back up now must not overwrite the day's automatic snapshot, and manual backups must be
|
||||
deletable. New key `READER_KEYS.manualBackups` (`gacha-tracker:v2:manual-backups`), with
|
||||
`readManualBackups` / `saveManualBackup` / `deleteManualBackup`; never pruned by
|
||||
`retainBackups`, outside exports (only v1 keys are captured) and untouched by restore/undo.
|
||||
Capped at 20 copies and ~1.5MB so the shared origin quota keeps room for the reader's own save;
|
||||
entries are parsed one by one so a damaged entry does not discard the rest. The page shows a
|
||||
“Your backups” list (View backup, Delete with inline confirm) above “Automatic history”.
|
||||
schema-guardian: no blockers; its quota should-fix is the size cap above. Left as notes: the
|
||||
error screen's raw recovery download includes every `gacha-tracker:` key, so it now also carries
|
||||
manual backups (large but read-only).
|
||||
|
||||
### Your games: tracking saves on click (2026-10-18)
|
||||
|
||||
Owner: “Apply tracking choices” should not exist; choices apply when the panels are clicked. The
|
||||
button is gone; `AccountSetup` in GameSettings saves the account on each change. It now changes
|
||||
only the routines of the kind that was toggled (dailies, weeklies & monthlies, or cycles; Events
|
||||
touches no routines), so a click never resets pins the reader set on the Routines tab — the old
|
||||
Apply rewrote every kind's placements from the draft. A failed save reverts the panel. Browser-
|
||||
checked, including a Checklist unpin on Weekly Bosses surviving an Events toggle.
|
||||
- Owner: the rest of Your games should follow the mockup more closely (padding, margins, dividers,
|
||||
structure). The Setup tab is now the Round 6 B structure: `.ptitle` (game name in its hue,
|
||||
studio, Stop following game → hides the game), Codes tab “n new” badge, `.grp` sections with
|
||||
inline descriptions on a rule — What to track (`.comp` cards with status lines: Shown/Hidden,
|
||||
“n built in”, dashed “Some, fine-tuned” when partly followed — a click follows the rest — and
|
||||
dimmed “none built in” that stays selectable per the spec), “Fine-tune in Routines →”; Servers
|
||||
(`.srvrow` MAIN/ALSO with reset, local time and countdown; Remove only on extra servers); Game
|
||||
colour (swatch, hex, Reset, preview chip, contrast note); Reset timing (one `ResetTimingRow` per
|
||||
server, shared with Region & time, replacing the hour/minute editor). `TrackingChoices.tsx` and
|
||||
30 unused CSS rules were removed; its test now checks the cards. Browser-checked.
|
||||
- Owner: a game's About tab should match the mockup. It now follows Round 6 B `aboutPage`: “About
|
||||
<game>”, fact rows (Studio; each server's next reset in your time · automatic/custom override),
|
||||
then Data sources — each source linked by host with “Event / Banner / Battle pass schedule”,
|
||||
the editors' thanks, and a “Source status and freshness” button to Data & sources.
|
||||
- Owner: games under “Other games” should be greyed out like the mockup. Unfollowed rows carry
|
||||
`data-off`; the name is muted and the colour bar faded to 25% (the mockup's `.srow.off`).
|
||||
- Owner: “Manage games & order” opened a legacy-looking page that also showed the first game's
|
||||
full configuration. Then: reorder by drag and drop in the sidebar instead. Now:
|
||||
- Followed games in Settings → Your games are draggable (HTML5 drag; drop indicator), and
|
||||
Alt+↑/↓ moves a focused row. Saved as the existing `prefs.gameOrder` (followed games in the new
|
||||
order, then hidden ones), via `SettingsLayout`'s new `onReorder`. A “Sort A–Z” link replaces
|
||||
“Manage games & order” and appears only when a custom order exists.
|
||||
- A game page's title button is “Follow game” for an unfollowed game (switching its events on if
|
||||
nothing was tracked), “Stop following game” otherwise.
|
||||
- `#settings/games` without a game now shows only a games-and-order list (follow checkbox, name
|
||||
linking to the game's page, ↑/↓, Reset to A–Z), never a game's configuration. It is no longer
|
||||
linked from the sidebar.
|
||||
- Known gap: HTML5 drag does not work on touch screens; phones can reorder only via that list.
|
||||
- Owner reversed the drag-and-drop idea (weak affordance, hard to see). Removed: sidebar drag and
|
||||
Alt+↑/↓, its CSS, the sidebar “Sort A–Z”, and the games-and-order list page. Settings →
|
||||
Appearance now has a “Game order” section listing only tracked games (not hidden; events or a
|
||||
followed routine) with 40×36 ↑/↓ buttons (disabled at the ends), working for mouse, touch and
|
||||
keyboard, and “Sort A–Z” when a custom order exists. Saves `prefs.gameOrder` as tracked games
|
||||
in the new order followed by the rest in their previous order. `#settings/games` without a game
|
||||
opens Appearance. Browser-checked at 1440 (click) and 390 (tap).
|
||||
- Owner: in Appearance, “Dailies on Checklist” and “Routine groups” looked odd on their own
|
||||
background. `ChecklistDisplay` gained a `plain` variant (just the fields); Appearance now has a
|
||||
“Checklist” settings group with Event rows, Dailies on Checklist and Routine groups side by side
|
||||
(stacked on phones) and the note below. The Routines page keeps the mockup's shaded band.
|
||||
- The “Offer standard-banner pulls in the library” switch (`prefs.standardPulls`) had no control
|
||||
in the redesigned app (only the unmounted legacy `Controls.tsx`). Owner: put it in Data &
|
||||
sources with the other list options. It is now the third “In your lists” checkbox, with the
|
||||
mockup's note “Premium pulls are always offered.” Browser-checked: ticking it makes the library
|
||||
offer Genshin's “Paimon's Bargains: Acquaint Fates”.
|
||||
- Owner: the settings sidebar needs the mockup's hover. Unselected rows now take the surface
|
||||
colour and ink text on hover (the mockup's `.srow:hover`), a step lighter than the selected
|
||||
row's raised background, with a 120ms fade (skipped under reduced motion). Plain `:hover`, as in
|
||||
the mockup; headless Chrome cannot emulate `(hover: hover)`, so a guarded rule was unverifiable.
|
||||
|
||||
### Round: logo, upcoming heading, routine band names (2026-10-18)
|
||||
|
||||
- The EVENTCLOCK logo is a button once the reader is onboarded; it opens the default view
|
||||
(`changePage(prefs.view)`). Hover shows only the pointer cursor; the owner rejected an underline. During setup it stays plain text.
|
||||
- The Checklist's "Upcoming events" `h2` had no styles. It is now a second `.list-heading`, "Not started yet",
|
||||
with an "N events in G games" sub-line. That mirrors "Running now". The sub-line doesn't say "sorted by…",
|
||||
because the Doing-first sort orders upcoming rows differently. In compact, the ledger header for this
|
||||
section reads "Duration / Starts in" (`LedgerColumns upcoming`), not "Time left / Ends in".
|
||||
- Routines bands (By reset) are named Dailies, Weeklies, Monthlies and Cycles, not Today, This week and
|
||||
This month. A test covers this in `test/redesign-routines.test.tsx`. The checklist rail's `DailyPanel`
|
||||
still says "Today · …", because it describes the current period rather than naming a group.
|
||||
- Follow-up: the owner found "Not started yet" easy to miss. The section now has a 48px gap above it and a
|
||||
2px rule in the accent colour (`--color-near`). Its heading sits on a full-width raised band
|
||||
(`--color-raised`) with a "Coming up" eyebrow, and the heading is the same 28px as "Running now".
|
||||
|
||||
### Round: ticking today's dailies should feel rewarding (2026-10-18)
|
||||
|
||||
The owner found ticking a daily in the redesign "way less satisfying" than the live strip. They asked to keep
|
||||
the live fireworks. `DailyPanel` (the Checklist rail) now works like this:
|
||||
|
||||
- **Tap target:** the whole row is the button (`.daily-hit`, `aria-pressed`), as the live pill is, not a
|
||||
small checkbox at the edge. Rows that measure an amount keep their number field.
|
||||
- **Done state:** a done row washes in the game's hue (`--g`), and its box fills with the hue. A streak
|
||||
("3-day streak", from `streakOf`) shows from day 2, as live shows "3d".
|
||||
- **Tick animation:** only on a tick made in this session (`data-fresh`), so a reload doesn't replay it.
|
||||
The box pops (an overshoot scale), the check draws in, and a ring glows out from the row.
|
||||
All of it is off under reduced motion.
|
||||
- **Progress:** a pip bar in each game's colour and "N of M done" sit under the heading. The last tick
|
||||
turns them to "All done for today" and flashes the pips (`data-burst`).
|
||||
- **Fireworks:** the live `Fireworks` component, under the live rule. They fire only when a tick made now
|
||||
completes the list. A shorter list (focusing a game) or arriving already done never fires them.
|
||||
- **Tests:** `test/redesign-daily-panel.test.tsx`.
|
||||
- Follow-up: events with a check-in goal, such as "To Temper Thyself and Journey Far" at 5 days a week,
|
||||
looked unticked and had no count. The panel read only today's tick, so a week whose goal was met
|
||||
without today's tick read as not done. `DailyPanel` now counts these as live does:
|
||||
- **Done:** a row is done when it's ticked today or its goal is met (`hasGoal` and `status.met`).
|
||||
A met row that isn't ticked draws a dotted check (`data-met`), as the live chip does. Nothing is
|
||||
ticked on its behalf, so `aria-pressed` stays on today's tick.
|
||||
- **Counter:** a goal row shows its goal count (`goalCount`: "5/5 wk", "3/5", "12/20 · 6d") in place of
|
||||
the streak, one counter per row as on live. Its spoken label comes from live's `chipLabel`.
|
||||
- **Checked:** in the browser with the real Genshin event, a met goal reads done, a tick makes it
|
||||
"3/3 wk", and the tick survives a reload. Tests are in `test/redesign-daily-panel.test.tsx`.
|
||||
|
||||
### Round: pinned routines complete like dailies (2026-10-18)
|
||||
|
||||
The owner asked that routines with a target be marked complete like dailies, with fireworks, and that
|
||||
the completion can be edited or undone. The Checklist rail's pinned routines now use
|
||||
`redesign/PinnedRoutine.tsx` instead of `RoutineControl`, which still serves the Timeline routine dialog.
|
||||
|
||||
- **Look:** the same card language as the daily rows. A met routine washes in the game's colour and reads
|
||||
"Done this week · resets in 1d 3h".
|
||||
- **Check-ins** (Realm Depot, Spiral Abyss): the box ticks today. Unticking a met routine removes the
|
||||
latest tick in the current period (`lastDayInPeriod`), which may be from an earlier day.
|
||||
- **Amounts** (Weekly Bosses 3 runs, Battle Pass 10,000 EXP), when not met:
|
||||
- the box completes the routine in one click by setting the amount to the target;
|
||||
- "+1" steps the amount;
|
||||
- the count, with a small bar and a pencil, opens an editor.
|
||||
- **Amounts, auto-complete:** typing a value at or over the target completes the routine without Save,
|
||||
once typing pauses for `AUTO_COMPLETE_MS` (450ms), so "10000" isn't cut short.
|
||||
- **Undo for amounts:** unticking puts back the amount from before the completing action, when this
|
||||
session saw it. After a reload that value isn't known, so the box opens the editor instead.
|
||||
Nothing is guessed.
|
||||
- **Completion animation:** only for an action taken in the row; arriving complete never fires. It is
|
||||
staged: the bar fills from its previous value (`--from`), the row warms, the box pops at about 280ms
|
||||
and the check draws, then the live `Fireworks` sparks fire at about 300ms. Reduced motion drops all of
|
||||
it.
|
||||
- **Tests:** `test/redesign-pinned-routine.test.tsx`. The auto-complete timer and the undo paths were
|
||||
checked in the browser, not in unit tests, because the suite renders static markup only.
|
||||
|
||||
### Round: time-left bars on every standard row (2026-10-18)
|
||||
|
||||
Round 6 B hid the meter on Standard rows without a description
|
||||
(`.event-entry.no-description .meter{display:none}`, b-rail.html:837). The owner asked why
|
||||
those rows had no timing bar and chose to show it on every row, a deliberate departure from the mockup.
|
||||
`ChecklistEvent` now always renders the meter. Rows without a description keep their tighter padding and
|
||||
grow by the meter's height, about 20px.
|
||||
|
||||
### Round: the live urgency ramp (2026-10-18)
|
||||
|
||||
The owner asked for live's urgency colours: grey for a week or more, blue under a week, yellow under 3
|
||||
days, red under a day. The redesign had derived them from the theme: "under a week" was the accent, and
|
||||
"a week+" was the general muted text grey, which read nearly white. The ramp is now its own token set,
|
||||
`--color-urgency-{calm,near,soon,critical}`:
|
||||
|
||||
- **Values:** `urgencyTokens` in `state/appearance.ts` sets live's dark or light values. Each is nudged
|
||||
only to 3:1 contrast on the scheme's surfaces, the large-text bar; the default dark grey and light grey
|
||||
move slightly. A custom accent no longer changes urgency.
|
||||
- **Wiring:** `URGENCY_COLOR` (Meter.tsx) reads `var(--color-urgency-X, var(--color-X))`. The live UI never
|
||||
sets the urgency tokens, so it falls back to its own unchanged values.
|
||||
- **No CSS defaults:** none are declared in redesign.css, because that file is imported into the live
|
||||
stylesheet too.
|
||||
- **Scope:** `--color-near`, `--color-soon` and `--color-critical` keep their other jobs (accent,
|
||||
warnings, NOW chip).
|
||||
|
||||
### Round: urgency colours editable, game strips, legend, scroll on tab change (2026-10-18)
|
||||
|
||||
- **Urgency colours in Settings → Appearance.** A new group sits under Colour scheme with the four steps
|
||||
for the dark and light themes, a small bar sample per step, and "Use the default colours".
|
||||
- It works with every scheme, not only Custom.
|
||||
- Choices are stored in a new pref, `prefs.urgencyPalette`, shaped `{ dark: {calm, near, soon,
|
||||
critical}, light: {…} }` with hex values.
|
||||
- `urgencyChoice` reads it; unset or invalid steps keep live's values. `urgencyTokens` applies the
|
||||
3:1 readability nudge.
|
||||
- **Schema-guardian:** no risk. Prefs are `z.record(z.unknown())`, patches are shallow merges, and
|
||||
the pref survives export, backup and restore. One existing behaviour applies to every pref: a v2
|
||||
import merge keeps the current prefs.
|
||||
- **Game colour strip on Standard event rows.** `.event-entry::before`, 3px, in the game hue, sits in the
|
||||
list's side padding, as live's row rail does. It's faded to 55% and comes to full strength with a
|
||||
glow on hover. Compact rows already had the `.gcell` bar.
|
||||
- **Live's legend under "Running now"** (`UrgencyLegend` in ChecklistEvent.tsx): "bars = time left ·
|
||||
colour = ends in a week+ / under a week / under 3 days / under a day". It reuses live's `STEPS`, now
|
||||
exported from Legend.tsx, and `URGENCY_COLOR`, so it follows the reader's urgency colours.
|
||||
- **Bug fixed:** changing tab kept the previous page's scroll, so leaving a scrolled Settings page opened
|
||||
the Checklist part-way down and its rail looked empty. ReaderApp now scrolls to the top when `page`
|
||||
changes. It skips the first render, so a reload's restored scroll is kept.
|
||||
- Follow-up: the legend first sat inside the title block. That widened the block, so the sort and density
|
||||
buttons wrapped under it and the heading looked cluttered. The owner wants one row. The legend is now
|
||||
the last child of `.list-heading` (`flex-basis: 100%`, a 12px row gap), on its own line under the title
|
||||
and the buttons. Title and buttons share a row down to 700px. At phone width the buttons wrap as they
|
||||
always did.
|
||||
- Follow-up 2: the owner wanted the legend on the same line as "35 events in 4 games · sorted by what
|
||||
ends first". The Running now heading (`.running-heading`) is now a two-row grid:
|
||||
- **Row 1:** the title, with the sort and density buttons on the right.
|
||||
- **Row 2:** `.heading-meta` spans the full width, with the count on the left and the legend on the
|
||||
right (`space-between`).
|
||||
- **Narrower screens:** the legend wraps onto its own line under the count only when the line can't
|
||||
fit, around 1100px. Below 700px the grid is one column, with the buttons left-aligned.
|
||||
|
||||
### Round: a grand celebration for finishing a section (2026-10-18)
|
||||
|
||||
The owner asked for a bigger celebration when a whole section is done: all of today's dailies, or every
|
||||
routine in a game's group in the Checklist rail.
|
||||
|
||||
- **`Fireworks grand`:** seven bursts in two waves across the section, 14 sparks each, wider reach, 4px
|
||||
sparks, 1.4s. With `hue` the game's colour joins the sparks. Called without props, it is unchanged for
|
||||
the live strip and the single-row bursts.
|
||||
- **`useSectionCelebration(total, done)`** (redesign/useSectionCelebration.ts) is the live strip's rule,
|
||||
shared by `DailyPanel` and `RoutineGroup`. A section celebrates only when it becomes complete with more
|
||||
done than a moment ago and the same total. A shorter list or arriving already complete never fires it.
|
||||
- **Extras on a celebrating section:**
|
||||
- a sweep of light across it (`section-sweep`, in the group's colour for routines);
|
||||
- the "All done" line pops (`section-pop`): "All done for today" for dailies, and for routine groups
|
||||
the summary, which now reads "All N done" when every routine is met (set in ReaderApp), not "N of N
|
||||
completed".
|
||||
- A complete group's summary stays bold in the game's colour.
|
||||
- **Reduced motion and tests:** all motion is off under reduced motion. Tests are in
|
||||
`test/redesign-routines.test.tsx`.
|
||||
|
||||
### Round: the returning-user tour (2026-10-18)
|
||||
|
||||
The owner walked through the tour on the reachable build (Settings → Appearance → Replay the
|
||||
introduction) and asked for three things:
|
||||
|
||||
- **Back no longer takes Continue's place.** It used to appear where Continue had been, so clicking
|
||||
through could land on it. Continue is now always first, in the same spot on every step. Back follows
|
||||
it from step 2, and "Skip tour" sits apart at the far right. There's also a "2 of 6" counter.
|
||||
- **The Timeline comes right after the Checklist.**
|
||||
- **A codes step.** It opens the Codes tab of the first tracked game that has codes, or the Checklist
|
||||
when none do.
|
||||
|
||||
The order is Routines → Checklist → Timeline → Redeem codes → Archive → Settings, which now opens on
|
||||
Appearance. The welcome reads "Welcome back. A little has moved." Steps live in `TOUR_STEPS`, and
|
||||
`ReturningTour` reports `onStep(stop)` to ReaderApp, which opens the page. Tests are in
|
||||
`test/redesign-onboarding.test.tsx`.
|
||||
- Follow-up: "Replay the introduction" now starts the tour itself. It used to only bring back the welcome
|
||||
banner on the Settings page. `AppearancePage` takes `onReplayTour`, and ReaderApp sets `tourAutoStart`,
|
||||
so `ReturningTour autoStart` opens on step 1 (Routines). Finishing or skipping clears it. A returning
|
||||
reader seeing the tour for the first time still gets the welcome first. Checked twice in a row in
|
||||
the browser.
|
||||
|
||||
### Round: focus pills with live's feel (2026-10-18)
|
||||
|
||||
The owner found the redesign's focus pills harsh ("scissors on a blackboard") next to live's chips.
|
||||
They were cramped: 24px tall, 11.5px text, a 9.5px count and 5px gaps. They also snapped between states
|
||||
with no easing, and hover only tinted the background.
|
||||
|
||||
`.focus-pill` now follows live's `.hue-chip` / GameFocus `Chip`:
|
||||
- **Size:** 30px tall, 6px 12px padding, 12px text, a 10px tabular count at 70%, 6px gaps.
|
||||
- **Colour:** an unpressed border in the game's hue at 30%; pressed, it's the full hue with a 14% wash.
|
||||
- **Motion:** 130ms eased colour, border, background and shadow changes. Hover adds a 1px ring in the
|
||||
hue and, where motion is allowed, a 1px lift, and an unpressed label brightens to ink. A press
|
||||
scales to 0.96.
|
||||
- **Empty games:** a game with nothing outstanding dims to 50% (`data-empty`).
|
||||
|
||||
The same pills appear in the Timeline's focus row, where they still fit on one line.
|
||||
- Follow-up (Checklist rows): the owner found the "›" arrow too far from the time and date. It inherited
|
||||
the row's 24px column gap (22px in Relaxed, 16px under 1050px). A negative margin on `.event-entry > svg`
|
||||
now leaves 10px at every width and in both interfaces, measured in the browser.
|
||||
|
||||
### Round: closer to the screen edge, a wider rail (2026-10-18)
|
||||
|
||||
The owner found the content "weirdly far away" from the screen edge. The page was capped and centred at
|
||||
1480px (1400px in Relaxed), which left 220px empty bands each side at 1920px.
|
||||
|
||||
- **Page width:** `.reader-ui` max-width is now 1920px; Relaxed is 1840px with 20px side padding instead
|
||||
of 28px. At 2560px the page still centres, with 320px bands.
|
||||
- **Checklist edges:** the list and its heading use 24px side padding instead of 32px, matching the
|
||||
rail.
|
||||
- **The rail** (Next to expire, dailies, routines) is wider, as the owner suggested: 300→360px in
|
||||
Structured, 320→380px in Relaxed, and at medium widths 240→280px and 280→300px.
|
||||
- **Checked:** Checklist in both interfaces at 1440, 1920 and 2560px, plus Timeline, Routines, Archive
|
||||
and Settings at 1920px. Settings keeps its readable column width.
|
||||
- Follow-up: the owner meant the inset between the content and the page's outer edge, about 24px
|
||||
(32px on the update rows). It's now two tokens on `.reader-ui`: `--edge: 16px` for outer edges and
|
||||
`--gutter: 24px` for the gap where a side column meets the content, which the owner asked to keep.
|
||||
- **Full-width parts** use the edge on both sides: header, footer, Timeline and Routines headers,
|
||||
the Routines table, Archive.
|
||||
- **Side columns** use the edge outside and the gutter inside: the Checklist rail, the Settings nav,
|
||||
the Archive sidebar.
|
||||
- **The main Checklist column** mirrors that: updates, headings, list, ledger, foot.
|
||||
- **At ≤700px**, where the columns stack, everything uses the edge, and the game strip moves to
|
||||
`left: -9px` so it doesn't touch the screen edge.
|
||||
- **Checked:** measured in the browser at 1920px and 390px, with no horizontal scroll.
|
||||
- Follow-up (focus bar): the "Focus" label above the pills looked off-centre and off in weight. Cause:
|
||||
`.reader-ui h2` comes later than `.focus-heading h2` with the same specificity, so it swapped in the
|
||||
condensed display face at 13px. It also sat beside an 11px regular "Next: …" button and was centred
|
||||
by box, not text. It's now Barlow 500 12px in muted grey, like the rail's "Next to expire"
|
||||
(`.game-focus .focus-heading h2`), and `.focus-heading` aligns to the text baseline.
|
||||
|
||||
### Shipped as the initial redesign (2026-10-18)
|
||||
|
||||
The owner accepted the build: "I think this is ready to be shipped as the initial redesign." Before
|
||||
committing:
|
||||
- **Migration review:** a full schema-guardian review of the v1→v2 migration found no blockers. Its
|
||||
low-severity gaps are in TODO.md.
|
||||
- **Image check:** the suite ran as the image runs it, without docs (typecheck clean, 1642 pass,
|
||||
build OK).
|
||||
- **Docs:** `docs/DESIGN.md`'s redesign section now describes the shipped system.
|
||||
|
||||
The owner chose to commit and push, including `design/`, the redesign docs, `docs/design-reviews/` and
|
||||
`.superpowers/`. The changelog entry and note follow in their own commit, because they must name the
|
||||
redesign commit.
|
||||
Reference in new issue
Block a user