Calendar grid: thumbnails inside cards and vertical fan-out (no large standalone tiles; horizontal fan-out only in Agenda) #822

Open
opened 2026-10-02 13:17:17 +00:00 by kayg · 18 comments
Owner

Owner direction (2026-10-02)

"Horizontal fan-out is the wrong model for a vertical UI like the calendar! It only makes sense where there is more space, like the Agenda view. A vertical fan-out and thumbnails in cards rather than thumbnails by themselves make more sense here, as these large thumbnails really don't scale at higher densities."

Screenshots: in Week/Day, a stack of 18 files shows as a big rounded tile with a "18" badge, and a 2-photo pill squeezes between event cards ("Att…", "Au…", "Gym") and overlaps them.

Expected

  1. Grid (Day/Week): attachments and Activity are never standalone large tiles. They live inside the item's card as small thumbnails in a row at the bottom of the card, sized to the card (no fixed large size). Standalone Activity (photos/files with no entry at that time) is a compact card in the lane with a small thumbnail strip and a label ("12 photos", "3 files"), using the same card as events.
  2. Fan-out direction: on hover or focus, a stack fans out vertically (downwards, or upwards near the bottom edge) inside the column width, never sideways across other days. Keyboard: Enter opens the stack; arrows move through it.
  3. Density: when a card is too short for thumbnails, show only an attachment glyph and count in the card's meta line. The layout never overlaps neighbouring cards at any zoom (1-, 3-, 7-day views; 390/820/1440).
  4. Agenda keeps horizontal fan-out (it has the width), per DESIGN §38 and #413.
  5. One shared deck component with a direction parameter (vertical in the grid, horizontal in Agenda); no second implementation.

Tests

Layout checks: no overlap at three zoom levels and three widths. The thumbnail size scales with the card. e2e hover/keyboard fan-out direction. Screenshots with macOS rendering.

## Owner direction (2026-10-02) "Horizontal fan-out is the wrong model for a vertical UI like the calendar! It only makes sense where there is more space, like the Agenda view. A **vertical fan-out** and **thumbnails in cards** rather than thumbnails by themselves make more sense here, as these large thumbnails really don't scale at higher densities." Screenshots: in Week/Day, a stack of 18 files shows as a big rounded tile with a "18" badge, and a 2-photo pill squeezes between event cards ("Att…", "Au…", "Gym") and overlaps them. ## Expected 1. **Grid (Day/Week):** attachments and Activity are never standalone large tiles. They live **inside the item's card** as small thumbnails in a row at the bottom of the card, sized to the card (no fixed large size). Standalone Activity (photos/files with no entry at that time) is a compact **card** in the lane with a small thumbnail strip and a label ("12 photos", "3 files"), using the same card as events. 2. **Fan-out direction:** on hover or focus, a stack fans out **vertically** (downwards, or upwards near the bottom edge) inside the column width, never sideways across other days. Keyboard: Enter opens the stack; arrows move through it. 3. **Density:** when a card is too short for thumbnails, show only an attachment glyph and count in the card's meta line. The layout never overlaps neighbouring cards at any zoom (1-, 3-, 7-day views; 390/820/1440). 4. **Agenda keeps horizontal fan-out** (it has the width), per DESIGN §38 and #413. 5. One shared deck component with a direction parameter (vertical in the grid, horizontal in Agenda); no second implementation. ## Tests Layout checks: no overlap at three zoom levels and three widths. The thumbnail size scales with the card. e2e hover/keyboard fan-out direction. Screenshots with macOS rendering.
Author
Owner

Starting the #822 portion of agenda-decks on job/agenda-decks from job/merge-round-7a at 2f4482ded066d9c5d9c59130377907f7fd2916c9.

I read the full #822 request and the #413 discussion, including the 2026-10-02 owner note. After merging the four requested branches in order and integrating the Agenda redesign, I will implement one shared deck with horizontal Agenda fan-out and vertical Day/Week fan-out, plus layout checks for overlap, direction, and card-scaled thumbnails. No push, deploy, or merge to dev is planned.

Starting the #822 portion of agenda-decks on `job/agenda-decks` from `job/merge-round-7a` at `2f4482ded066d9c5d9c59130377907f7fd2916c9`. I read the full #822 request and the #413 discussion, including the 2026-10-02 owner note. After merging the four requested branches in order and integrating the Agenda redesign, I will implement one shared deck with horizontal Agenda fan-out and vertical Day/Week fan-out, plus layout checks for overlap, direction, and card-scaled thumbnails. No push, deploy, or merge to `dev` is planned.
Author
Owner

Owner (2026-10-02): "I added a note to remind myself that I imported calternal.js at this point in time, but it became a large thumbnail when it could literally have been a single-line card with the title. We need to think more about how to display every piece of media in a visually appealing way that scales up and down."

Design: one representation system, chosen by item kind × available size

Every attached or standalone item renders through one shared ItemChip/ItemCard family with four size classes. The grid, Agenda, previews, search, Inspector "Used in" and the Composer all choose a size class from the space they have; nothing picks "big thumbnail" by default.

Size class When Look
Micro card shorter than one text line, or a Month/Year cell kind glyph + count in the parent's meta line ("📝 2 · 📷 5")
Compact one line available single-line card: kind glyph + title (ellipsis), optional tiny trailing thumb for photos only
Regular 2–3 lines card: title + one-line snippet (text kinds) or a small thumbnail strip (visual kinds)
Large Agenda selection, hover preview, Quick Look full preview: excerpt, page-1 thumbnail, photo deck, waveform player

Per kind:

  • Note, Task, Log entry, link, mail: text-first, never an image of text. Compact = icon + title (a Task gets its checkbox, a mail gets the sender). Regular adds the first line of body text (frontmatter stripped). Large = a text excerpt card.
  • Photo, video: the thumbnail is the content. Compact = small rounded square plus a count. Regular = a strip of 2–4 thumbs inside the card. Large = a deck/carousel.
  • Voice memo: a mini waveform, the duration and a play button at every size from compact up (no thumbnail).
  • PDF, Office, other documents: a file-type glyph + the name at compact/regular; the page-1 thumbnail only at large.
  • Mixed sets: text kinds as rows, visual kinds as one strip; counts per kind in micro.

Scaling: the size class comes from measured space (container queries / ResizeObserver), so zooming the calendar or resizing the window moves items smoothly between classes. The transition uses the shared spring; reduced motion swaps instantly.

**Owner (2026-10-02):** "I added a note to remind myself that I imported calternal.js at this point in time, but it became a large thumbnail when it could literally have been a single-line card with the title. We need to think more about how to display every piece of media in a visually appealing way that scales up and down." ## Design: one representation system, chosen by item kind × available size Every attached or standalone item renders through one shared **ItemChip/ItemCard** family with four size classes. The grid, Agenda, previews, search, Inspector "Used in" and the Composer all choose a size class from the space they have; nothing picks "big thumbnail" by default. | Size class | When | Look | |---|---|---| | **Micro** | card shorter than one text line, or a Month/Year cell | kind glyph + count in the parent's meta line ("📝 2 · 📷 5") | | **Compact** | one line available | single-line card: kind glyph + title (ellipsis), optional tiny trailing thumb for photos only | | **Regular** | 2–3 lines | card: title + one-line snippet (text kinds) or a small thumbnail strip (visual kinds) | | **Large** | Agenda selection, hover preview, Quick Look | full preview: excerpt, page-1 thumbnail, photo deck, waveform player | Per kind: - **Note, Task, Log entry, link, mail:** **text-first, never an image of text.** Compact = icon + title (a Task gets its checkbox, a mail gets the sender). Regular adds the first line of body text (frontmatter stripped). Large = a text excerpt card. - **Photo, video:** the thumbnail *is* the content. Compact = small rounded square plus a count. Regular = a strip of 2–4 thumbs inside the card. Large = a deck/carousel. - **Voice memo:** a mini waveform, the duration and a play button at every size from compact up (no thumbnail). - **PDF, Office, other documents:** a file-type glyph + the name at compact/regular; the page-1 thumbnail only at large. - **Mixed sets:** text kinds as rows, visual kinds as one strip; counts per kind in micro. Scaling: the size class comes from measured space (container queries / ResizeObserver), so zooming the calendar or resizing the window moves items smoothly between classes. The transition uses the shared spring; reduced motion swaps instantly.
Author
Owner

Resumed agenda-decks on job/agenda-decks, base 2f4482ded066d9c5d9c59130377907f7fd2916c9. Read #413 comments in full and latest #822 media representation direction. Integrating the four requested branches in order. The first merge conflicts with earlier keyboard motion work; retaining #611 shared motion and current chrome while integrating Calendar cards, attachment Undo and inline audio. Representation size will use CSS container queries, avoiding per-item layout measurement.

Resumed agenda-decks on `job/agenda-decks`, base `2f4482ded066d9c5d9c59130377907f7fd2916c9`. Read #413 comments in full and latest #822 media representation direction. Integrating the four requested branches in order. The first merge conflicts with earlier keyboard motion work; retaining #611 shared motion and current chrome while integrating Calendar cards, attachment Undo and inline audio. Representation size will use CSS container queries, avoiding per-item layout measurement.
Author
Owner

Integration progress: the four requested branches are merged locally in order. Latest merge commit: a7c692fcd. No push or deployment.

Evidence: the merged Agenda and representation slice passes 46 focused tests. The older Agenda branch had lost current keyboard row/date identity, carry-in Log counts, and collapsed attachment hover behavior; these are restored. #413 explicitly changes ascending date order, Space selection, Return preview, and omission of unlinked daily Activity. Test expectations changed only for those approved behaviors.

The shared ItemCard family now renders text identities without text thumbnails, documents as glyph/name until Large, and visual items as bounded thumbnails. Grid collision lanes retain #589 packing. CSS container queries choose grid size classes; no text or icon layout measurements were added.

Decisions: Inspector Used in reuses the existing linked-notes API and stable Note links. No new endpoint or dependency is needed. Performance measurements are local because this job has no perf-VM lock; the new representation adapter has no matching baseline yet.

Integration progress: the four requested branches are merged locally in order. Latest merge commit: `a7c692fcd`. No push or deployment. Evidence: the merged Agenda and representation slice passes 46 focused tests. The older Agenda branch had lost current keyboard row/date identity, carry-in Log counts, and collapsed attachment hover behavior; these are restored. #413 explicitly changes ascending date order, Space selection, Return preview, and omission of unlinked daily Activity. Test expectations changed only for those approved behaviors. The shared ItemCard family now renders text identities without text thumbnails, documents as glyph/name until Large, and visual items as bounded thumbnails. Grid collision lanes retain #589 packing. CSS container queries choose grid size classes; no text or icon layout measurements were added. Decisions: Inspector Used in reuses the existing linked-notes API and stable Note links. No new endpoint or dependency is needed. Performance measurements are local because this job has no perf-VM lock; the new representation adapter has no matching baseline yet.
Author
Owner

Final web check: svelte-check found 0 errors and 0 warnings.

The full web test run had two failing tests and one worker startup timeout. The bounded rerun passed the contract and worker files. The remaining #611 keyboard-pulse test sets reduced motion to true and expects a pulse. The production action correctly suppresses motion under that preference. I kept the original pulse assertion, changed this normal-motion test setup to reduced motion off, and added a separate reduced-motion suppression test. This follows the owner's #611 override: keyboard and pointer animate alike; reduced-motion preferences still apply.

UX gap closed: Activity selection now opens the shared media preview for native Enter/Space as well as pointer and touch activation. The prior fine-pointer selection path did not open it.

Performance follow-up: #854 records the local Activity latency increase and host-load difference. The new representation profile has no prior baseline.

Final web check: `svelte-check found 0 errors and 0 warnings`. The full web test run had two failing tests and one worker startup timeout. The bounded rerun passed the contract and worker files. The remaining #611 keyboard-pulse test sets reduced motion to true and expects a pulse. The production action correctly suppresses motion under that preference. I kept the original pulse assertion, changed this normal-motion test setup to reduced motion off, and added a separate reduced-motion suppression test. This follows the owner's #611 override: keyboard and pointer animate alike; reduced-motion preferences still apply. UX gap closed: Activity selection now opens the shared media preview for native Enter/Space as well as pointer and touch activation. The prior fine-pointer selection path did not open it. Performance follow-up: #854 records the local Activity latency increase and host-load difference. The new representation profile has no prior baseline.
Author
Owner

The representation regression tests reproduced two failures before the fix: a pending thumbnail never retried, and a named Note after visual cards was hidden by the collapsed overflow rule. The shared ItemCard now uses the existing ActivityStack five-retry policy. A collapsed mixed deck retains up to three visual cards and three named text items, even when the text item is beyond the first page. The keyed list mounts only this bounded sample until expansion; expanded pages remain limited to 32. DESIGN §38 records that choice.

Chromium full-page capture also cleared touch emulation: a blank touch context changed from [1, false] to [0, true] for [maxTouchPoints, fine hover]. A short-lived CDP override was insufficient because detaching reset its state. The shared test capture helper now keeps one touch session per page until context close. The phone's original no-hover assertion stays in place.

The latest web check passed: svelte-check found 0 errors and 0 warnings.

The representation regression tests reproduced two failures before the fix: a pending thumbnail never retried, and a named Note after visual cards was hidden by the collapsed overflow rule. The shared ItemCard now uses the existing ActivityStack five-retry policy. A collapsed mixed deck retains up to three visual cards and three named text items, even when the text item is beyond the first page. The keyed list mounts only this bounded sample until expansion; expanded pages remain limited to 32. DESIGN §38 records that choice. Chromium full-page capture also cleared touch emulation: a blank touch context changed from `[1, false]` to `[0, true]` for `[maxTouchPoints, fine hover]`. A short-lived CDP override was insufficient because detaching reset its state. The shared test capture helper now keeps one touch session per page until context close. The phone's original no-hover assertion stays in place. The latest web check passed: `svelte-check found 0 errors and 0 warnings`.
Author
Owner

Validation update: the current web check reports svelte-check found 0 errors and 0 warnings. Photos Clippy passed; Photos tests report 46 passed; 0 failed; 2 ignored. Calendar Clippy passed; its tests are waiting on the host's shared package-cache lock. The full web VM run passed 154 files; the timezone file requires a process worker because VM workers do not apply process.env.TZ. Its process-worker rerun and the new vertical-preview keyboard test report 37 passed (37) with assertions unchanged.

The local #822 API contract round passed nine finite checks. Production-browser layout evidence is running with real uploaded media and macOS emulation. A fixture mkdir returned 503 Index is busy; retry shortly; filed #859. One bounded setup retry preserves the successful-status assertion, including rejecting a partial-write 409.

The Agenda browser found a stale renderer locator after migration to ItemCard; the locator now targets the shared thumbnail and retains its image and hover assertions. Search's Large Photo preview now uses ItemCard; Large voice preview reuses VoicePlayback, including decoder-driven duration, seek, speed and automatic pause on selection changes. Validation of that final slice is in progress.

Remaining UX gaps to report if not completed: direct Play and decoded duration in Compact Search/Activity rows and in the transient attachment hover; Used in currently has linked Notes only because that is the existing API.

Validation update: the current web check reports `svelte-check found 0 errors and 0 warnings`. Photos Clippy passed; Photos tests report `46 passed; 0 failed; 2 ignored`. Calendar Clippy passed; its tests are waiting on the host's shared package-cache lock. The full web VM run passed 154 files; the timezone file requires a process worker because VM workers do not apply process.env.TZ. Its process-worker rerun and the new vertical-preview keyboard test report `37 passed (37)` with assertions unchanged. The local #822 API contract round passed nine finite checks. Production-browser layout evidence is running with real uploaded media and macOS emulation. A fixture mkdir returned 503 `Index is busy; retry shortly`; filed #859. One bounded setup retry preserves the successful-status assertion, including rejecting a partial-write 409. The Agenda browser found a stale renderer locator after migration to ItemCard; the locator now targets the shared thumbnail and retains its image and hover assertions. Search's Large Photo preview now uses ItemCard; Large voice preview reuses VoicePlayback, including decoder-driven duration, seek, speed and automatic pause on selection changes. Validation of that final slice is in progress. Remaining UX gaps to report if not completed: direct Play and decoded duration in Compact Search/Activity rows and in the transient attachment hover; Used in currently has linked Notes only because that is the existing API.
Author
Owner

The shared host's local media test runtime rejects namespace setup before a decoder starts: outer_nproc_limit <= 4096 fails when the shared User already owns more than 4096 threads. In this job the requested bounded headroom was 4770 and then 4977. Real JPEG uploads got decoder-failed-v1 cache markers, which prevented production screenshot hover checks.

For remaining local UI evidence only, the ignored runtime copy under target/e2e-media-runtime permits an outer ceiling of 8192; the requested value stays observed account threads +512. The decoder's inner 64-process limit, capability dropping, namespaces, immutable input requirement and production wrapper remain unchanged. No repository production policy was edited. The evidence must state this local runtime qualification.

Follow-up: make the supported local runtime setup usable on the shared build host without changing production decoder limits. The job did not wait for the host to go quiet.

The shared host's local media test runtime rejects namespace setup before a decoder starts: `outer_nproc_limit <= 4096` fails when the shared User already owns more than 4096 threads. In this job the requested bounded headroom was 4770 and then 4977. Real JPEG uploads got `decoder-failed-v1` cache markers, which prevented production screenshot hover checks. For remaining local UI evidence only, the ignored runtime copy under target/e2e-media-runtime permits an outer ceiling of 8192; the requested value stays observed account threads +512. The decoder's inner 64-process limit, capability dropping, namespaces, immutable input requirement and production wrapper remain unchanged. No repository production policy was edited. The evidence must state this local runtime qualification. Follow-up: make the supported local runtime setup usable on the shared build host without changing production decoder limits. The job did not wait for the host to go quiet.
Author
Owner

Browser findings, HEAD 090f1f5669:

  • Agenda's thumbnail assertion still fails after changing the renderer locator. FileThumb retains its old class; my earlier locator diagnosis was incomplete. The real uploaded JPEG receives a decoder-failed-v1 marker. Local sealed-input probe and render both pass (exit 0, 1.359 s / 1.599 s) with the staged outer namespace headroom described in the previous comment. The server/browser discrepancy remains unresolved. No image fixture or cache was substituted.
  • The existing attachment-audio E2E reached and passed playback, pause/resume, single-player ownership, stable-ID Quick Look, elapsed time, waveform, accessible seek, keyboard seek and speed checks. It then failed its unchanged Show in Files shortcut assertion: expected Enter, actual Meta+ArrowDown. I did not change the old expectation. Later Undo, sibling navigation and responsive captures in that test therefore did not run.
  • Dense fixture upload also returned an Index-busy 503. This extends #859 from mkdir to Tus upload; successful-status expectations are unchanged.
  • Calendar Rust tests passed: 88 passed; 0 failed; 1 ignored; integration tests 1 passed and 3 passed; doc tests 0 passed. Calendar Clippy passed.

The dense-layout production run is now running against the final web build. Complete visual evidence and the remaining Rust crate gates are still outstanding within the job's final hour.

Browser findings, HEAD 090f1f5669de88afb5ea5ecf49d958421c52284f: - Agenda's thumbnail assertion still fails after changing the renderer locator. FileThumb retains its old class; my earlier locator diagnosis was incomplete. The real uploaded JPEG receives a `decoder-failed-v1` marker. Local sealed-input probe and render both pass (exit 0, 1.359 s / 1.599 s) with the staged outer namespace headroom described in the previous comment. The server/browser discrepancy remains unresolved. No image fixture or cache was substituted. - The existing attachment-audio E2E reached and passed playback, pause/resume, single-player ownership, stable-ID Quick Look, elapsed time, waveform, accessible seek, keyboard seek and speed checks. It then failed its unchanged Show in Files shortcut assertion: expected `Enter`, actual `Meta+ArrowDown`. I did not change the old expectation. Later Undo, sibling navigation and responsive captures in that test therefore did not run. - Dense fixture upload also returned an Index-busy 503. This extends #859 from mkdir to Tus upload; successful-status expectations are unchanged. - Calendar Rust tests passed: `88 passed; 0 failed; 1 ignored`; integration tests `1 passed` and `3 passed`; doc tests `0 passed`. Calendar Clippy passed. The dense-layout production run is now running against the final web build. Complete visual evidence and the remaining Rust crate gates are still outstanding within the job's final hour.
Author
Owner

Production evidence found and fixed a real collapsed-deck defect. The mixed Agenda screenshot had blank visual tiles; hover reported the .representation.thumb was not visible. Visual tiles set height: 100%, but their intermediate .card-hit and .attachment-row boxes had automatic heights. The image's percentage-height chain therefore collapsed. Mixed decks also kept the old column direction.

Commit e947951ce gives both intermediate boxes the tile's definite height, makes collapsed Agenda visuals flow horizontally, and removes old horizontal row offsets that could affect a vertical deck. All geometry remains CSS-based. No runtime text or icon measurements were added.

Validation after this fix:

svelte-check found 0 errors and 0 warnings
 Test Files  1 passed (1)
      Tests  7 passed (7)

The production build passed. The full 18-Photo mixed fixture is running again on that build. Earlier new-layout Enter failures used invalid Markdown links with spaces, so the Log had no attachments and correctly opened its editor. The fixture now uses the Journal writer's angle-bracket link syntax and asserts that attachments exist before measuring layout.

Files Clippy passed (Finished ... in 9m 12s); its tests are compiling. The job is approaching its five-hour limit. Final reports will distinguish verified behavior, failed assertions, incomplete gates and remaining UX gaps.

Production evidence found and fixed a real collapsed-deck defect. The mixed Agenda screenshot had blank visual tiles; hover reported the `.representation.thumb` was not visible. Visual tiles set `height: 100%`, but their intermediate `.card-hit` and `.attachment-row` boxes had automatic heights. The image's percentage-height chain therefore collapsed. Mixed decks also kept the old column direction. Commit e947951ce gives both intermediate boxes the tile's definite height, makes collapsed Agenda visuals flow horizontally, and removes old horizontal row offsets that could affect a vertical deck. All geometry remains CSS-based. No runtime text or icon measurements were added. Validation after this fix: ``` svelte-check found 0 errors and 0 warnings Test Files 1 passed (1) Tests 7 passed (7) ``` The production build passed. The full 18-Photo mixed fixture is running again on that build. Earlier new-layout Enter failures used invalid Markdown links with spaces, so the Log had no attachments and correctly opened its editor. The fixture now uses the Journal writer's angle-bracket link syntax and asserts that attachments exist before measuring layout. Files Clippy passed (`Finished ... in 9m 12s`); its tests are compiling. The job is approaching its five-hour limit. Final reports will distinguish verified behavior, failed assertions, incomplete gates and remaining UX gaps.
Author
Owner

Final time-box report — agenda-decks, HEAD dc68eb236c43ecf45b11f730bb78e77aaca103e1

Status: partial implementation, not ready to merge. No push or deploy. The approved branches were merged in the requested order, starting at job/merge-round-7a; origin/dev was fetched and merged once before final gates (Already up to date.).

Built: the shared ItemCard/ItemChip media family; CSS space classes; text-first Note/Task/Log/Link/Mail content; Photo/video thumbnails; voice presentation; Large-only document pages; one direction-aware AttachmentDeck used by grid and Agenda; shared content in previews, Search, Used in and Composer. The Agenda keeps one Card per day, separate time/title lines, inset selection, attachment expansion, earlier-day prepend, bounded mounting and mini-month range. Task ticks update Calendar occurrences optimistically and have Undo. Activity click/Enter opens its preview. Grid attachment Enter and vertical arrows are wired. Large Search voice preview reuses the native player. DESIGN §38 now records the approved Cards and media rules.

UX gaps closed: Task checkboxes work in Agenda; Activity primary actions work; mixed collapsed decks retain named text beyond the first visual page; glyph/count density is retained; collapsed Photo tiles now have definite heights; Agenda visuals flow horizontally and grid fan motion stays on its vertical axis; pinned grid previews focus an attachment without waiting for motion. Keyboard motion still uses shared durations and reduced motion.

UX gaps left: direct Play/decoded duration in Compact Search and Activity rows and transient hover; coordination between the new Large Search player and Calendar inline playback; Used in covers the existing linked-Notes API only; complete standard actions on collapsed Activity cards need review. Full width/theme visual evidence and the failing browser checks below remain open. This report does not call the UI complete.

Decisions: CSS container queries select space classes, with explicit caps in intrinsic rows; no runtime font/layout measurements. ItemCard supplies presentation and hosts retain controls, avoiding nested interactive elements. Collapsed mixed decks mount at most three visuals plus three text items; expanded paging remains 32. No new backlink API or eager Note-body fan-out was added. Existing text-rich Search previews remain text. Calendar time/title chrome stays in its approved host layout. Local performance numbers are labeled local; no locked VM measurement was obtained.

Browser evidence: ten fresh macOS-emulated PNGs were attached to each issue. This is partial 390px/light evidence, not the required complete 390/820/1440 × light/dark matrix. Agenda has unfocused, pointer-hover, touch-no-hover, selection, expanded attachments and mini-month range captures; Day has dense/focus captures. The final mixed run passed three Day zoom layouts and the grid deck actions before the next view's dense-Log visibility wait timed out. That view/loading or density problem is not resolved. The existing Agenda run passed the phone checks, then failed its unchanged Open Coastal trail button locator. The audio run passed playback, ownership, stable-ID Quick Look, waveform, accessible/keyboard seek and speed, then failed its unchanged Show in Files shortcut assertion (Enter expected, Meta+ArrowDown actual). Later checks in those scripts did not run. Calendar's full E2E and document-stack E2E were not completed.

The finite local media contract round passed nine small boundary checks. Index-busy 503s in mkdir and Tus setup are filed as #859. The Files timeout and later background entry not found panic are filed as #942. Expectations and the five-minute test budget were not relaxed. A local runtime copy permits bounded namespace setup above the host's >4096 account threads (ceiling 8192, requested observed count +512); production policy and the decoder's inner 64-process limit were unchanged. That qualification applies to the latest browser evidence.

Performance: new adapter average p50/p95 0.138/1.437 ms, CPU 0.148496 s, peak RSS 52,355,072 bytes; 4096-item burst p50/p95 69.570/282.636 ms, CPU 3.746471 s, RSS 71,958,528 bytes. There is no adapter baseline. Existing Activity profile average 35.22/79.68 µs vs baseline 22.56/52.88; worst 50.90/95.18 µs vs 31.03/56.61. Local load was 128.68/121.21/116.46 vs baseline 40.52/40.78/36.44. #854 tracks a locked-VM recheck. These adapter numbers do not measure browser rendering.

Gates (terminal output quoted verbatim):
cargo fmt --check exited 0 with no output. Server production-development build passed. Web production build passed after the final CSS change.

Final web check

svelte-check found 0 errors and 0 warnings

Final representation test

 Test Files  1 passed (1)
      Tests  7 passed (7)

Full web VM run

 Test Files  1 failed | 154 passed (155)
      Tests  17 failed | 1092 passed (1109)

Process-worker timezone and grid keyboard rerun

 Test Files  2 passed (2)
      Tests  37 passed (37)

The full VM command failed only its timezone file; VM workers do not apply its process.env.TZ changes. The unchanged file passed in the process-worker rerun. This is not a clean full-command exit.

calternal-plugin

    Finished `dev` profile [unoptimized + debuginfo] target(s) in 67m 53s
test result: ok. 28 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 52.20s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

calternal-plugin-photos

    Finished `dev` profile [unoptimized + debuginfo] target(s) in 46m 13s
test result: ok. 46 passed; 0 failed; 2 ignored; 0 measured; 0 filtered out; finished in 117.20s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

calternal-plugin-calendar

    Finished `dev` profile [unoptimized + debuginfo] target(s) in 42m 48s
test result: ok. 88 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out; finished in 24.69s
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.28s
test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.16s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

calternal-plugin-files

    Finished `dev` profile [unoptimized + debuginfo] target(s) in 9m 12s
test result: FAILED. 157 passed; 1 failed; 1 ignored; 0 measured; 0 filtered out; finished in 343.59s

calternal-plugin-notes

    Finished `dev` profile [unoptimized + debuginfo] target(s) in 4m 28s

Notes tests were stopped while compiling at the time limit. Money, DAV and Server Clippy/tests were not reached. The first gate queue ended with exit 143; the interrupted Files test was resumed, then failed as quoted. No successful gate claim is made for incomplete commands.

Attached evidence on #822:

Files (complete integration and feature scope):

92 changed files
apps/web/e2e/agenda-decks-822.mjs
apps/web/e2e/agenda-review-413.mjs
apps/web/e2e/calendar-attachment-audio-622.mjs
apps/web/e2e/calendar-crossday.mjs
apps/web/e2e/calendar-doc-stack.mjs
apps/web/e2e/calendar-hover-608.mjs
apps/web/e2e/calendar-perf.mjs
apps/web/e2e/calendar-preview-421.mjs
apps/web/e2e/calendar-view-switcher.mjs
apps/web/e2e/calendar.mjs
apps/web/e2e/composer.mjs
apps/web/e2e/harness.mjs
apps/web/e2e/kbd-motion-527.mjs
apps/web/e2e/layout-sweep.mjs
apps/web/e2e/motion-spring-evidence.mjs
apps/web/e2e/pill-feedback.mjs
apps/web/src/lib/a11y/inputModality.test.ts
apps/web/src/lib/actions/pillFeedback.test.ts
apps/web/src/lib/actions/pillFeedback.ts
apps/web/src/lib/calendar/ItemPreview.svelte.test.ts
apps/web/src/lib/calendar/TimeGrid.svelte.test.ts
apps/web/src/lib/calendar/agenda.svelte.test.ts
apps/web/src/lib/calendar/attachments.test.ts
apps/web/src/lib/calendar/data.test.ts
apps/web/src/lib/calendar/data.ts
apps/web/src/lib/calendar/edits.test.ts
apps/web/src/lib/calendar/edits.ts
apps/web/src/lib/calendar/grid.test.ts
apps/web/src/lib/calendar/journal.ts
apps/web/src/lib/calendar/model.test.ts
apps/web/src/lib/calendar/prefs.test.ts
apps/web/src/lib/calendar/prefs.ts
apps/web/src/lib/calendar/representation.svelte.test.ts
apps/web/src/lib/calendar/sidebarState.svelte.ts
apps/web/src/lib/components/app-sidebar.svelte
apps/web/src/lib/composer/Composer.svelte
apps/web/src/lib/files/InfoPanel.svelte
apps/web/src/lib/search/SearchPreview.svelte
apps/web/src/lib/search/SearchResultRow.svelte
apps/web/src/lib/tooltip/tooltip.test.ts
apps/web/src/lib/webmcp/tools.ts
apps/web/src/routes/calendar/[view]/[date]/+page.svelte
apps/web/src/routes/settings/calendars/CalendarsSection.svelte
bench/calendar-activity-589.mjs
bench/calendar-attachments-603.mjs
bench/calendar-hover-608.mjs
bench/calendar-inline-audio-622.mjs
bench/item-representations-822.mjs
bench/run.sh
contracts/openapi.json
crates/calternal-dav/tests/apple_replay.rs
crates/calternal-plugin/src/lib.rs
crates/calternal-server/src/system_plugin.rs
crates/plugins/calendar/src/items.rs
crates/plugins/calendar/src/view.rs
crates/plugins/files/src/thumbnails.rs
crates/plugins/money/src/lib.rs
crates/plugins/notes/src/lib.rs
crates/plugins/photos/src/lib.rs
docs/DESIGN.md
docs/perf/baseline.json
docs/perf/runs/2026-10-01-calendar-hover-608.md
packages/api-client/src/generated.ts
packages/ui/src/components/FloatingSidebar.svelte
packages/ui/src/components/ItemCard.svelte
packages/ui/src/components/OverlaySurface.svelte
packages/ui/src/components/TagPill.svelte
packages/ui/src/components/calendar/ActivityStack.svelte
packages/ui/src/components/calendar/AgendaList.svelte
packages/ui/src/components/calendar/AttachmentDeck.svelte
packages/ui/src/components/calendar/CalendarPopover.svelte
packages/ui/src/components/calendar/GridColumn.svelte
packages/ui/src/components/calendar/ItemPreview.svelte
packages/ui/src/components/calendar/MiniMonth.svelte
packages/ui/src/components/calendar/MonthGrid.svelte
packages/ui/src/components/calendar/TimeGrid.svelte
packages/ui/src/components/calendar/attachments.ts
packages/ui/src/components/calendar/inlineAudioPlayback.svelte.ts
packages/ui/src/components/calendar/layout.ts
packages/ui/src/components/calendar/model.ts
packages/ui/src/components/composer/VoicePlayback.svelte
packages/ui/src/components/composer/VoiceWaveform.svelte
packages/ui/src/components/menu/FloatingSurface.svelte
packages/ui/src/components/tooltip/place.ts
packages/ui/src/components/viewer/QuickLook.svelte
packages/ui/src/index.ts
packages/ui/src/motion.ts
packages/ui/src/time.ts
packages/ui/src/tokens.css
tests/adversarial/attack.py
tests/adversarial/calendar_event_tags.mjs
tests/adversarial/item_representations_822.mjs

Cleanup: web build and .svelte-kit/output removed. cargo clean is running; its terminal result will be appended if it finishes before the time limit. Source comments were re-read. Worktree is clean; all source changes are committed. Issues remain open.

Final time-box report — agenda-decks, HEAD `dc68eb236c43ecf45b11f730bb78e77aaca103e1` Status: partial implementation, **not ready to merge**. No push or deploy. The approved branches were merged in the requested order, starting at `job/merge-round-7a`; `origin/dev` was fetched and merged once before final gates (`Already up to date.`). Built: the shared ItemCard/ItemChip media family; CSS space classes; text-first Note/Task/Log/Link/Mail content; Photo/video thumbnails; voice presentation; Large-only document pages; one direction-aware AttachmentDeck used by grid and Agenda; shared content in previews, Search, Used in and Composer. The Agenda keeps one Card per day, separate time/title lines, inset selection, attachment expansion, earlier-day prepend, bounded mounting and mini-month range. Task ticks update Calendar occurrences optimistically and have Undo. Activity click/Enter opens its preview. Grid attachment Enter and vertical arrows are wired. Large Search voice preview reuses the native player. DESIGN §38 now records the approved Cards and media rules. UX gaps closed: Task checkboxes work in Agenda; Activity primary actions work; mixed collapsed decks retain named text beyond the first visual page; glyph/count density is retained; collapsed Photo tiles now have definite heights; Agenda visuals flow horizontally and grid fan motion stays on its vertical axis; pinned grid previews focus an attachment without waiting for motion. Keyboard motion still uses shared durations and reduced motion. UX gaps left: direct Play/decoded duration in Compact Search and Activity rows and transient hover; coordination between the new Large Search player and Calendar inline playback; Used in covers the existing linked-Notes API only; complete standard actions on collapsed Activity cards need review. Full width/theme visual evidence and the failing browser checks below remain open. This report does not call the UI complete. Decisions: CSS container queries select space classes, with explicit caps in intrinsic rows; no runtime font/layout measurements. ItemCard supplies presentation and hosts retain controls, avoiding nested interactive elements. Collapsed mixed decks mount at most three visuals plus three text items; expanded paging remains 32. No new backlink API or eager Note-body fan-out was added. Existing text-rich Search previews remain text. Calendar time/title chrome stays in its approved host layout. Local performance numbers are labeled local; no locked VM measurement was obtained. Browser evidence: ten fresh macOS-emulated PNGs were attached to each issue. This is **partial 390px/light evidence**, not the required complete 390/820/1440 × light/dark matrix. Agenda has unfocused, pointer-hover, touch-no-hover, selection, expanded attachments and mini-month range captures; Day has dense/focus captures. The final mixed run passed three Day zoom layouts and the grid deck actions before the next view's dense-Log visibility wait timed out. That view/loading or density problem is not resolved. The existing Agenda run passed the phone checks, then failed its unchanged `Open Coastal trail` button locator. The audio run passed playback, ownership, stable-ID Quick Look, waveform, accessible/keyboard seek and speed, then failed its unchanged Show in Files shortcut assertion (`Enter` expected, `Meta+ArrowDown` actual). Later checks in those scripts did not run. Calendar's full E2E and document-stack E2E were not completed. The finite local media contract round passed nine small boundary checks. Index-busy 503s in mkdir and Tus setup are filed as #859. The Files timeout and later background `entry not found` panic are filed as #942. Expectations and the five-minute test budget were not relaxed. A local runtime copy permits bounded namespace setup above the host's >4096 account threads (ceiling 8192, requested observed count +512); production policy and the decoder's inner 64-process limit were unchanged. That qualification applies to the latest browser evidence. Performance: new adapter average p50/p95 0.138/1.437 ms, CPU 0.148496 s, peak RSS 52,355,072 bytes; 4096-item burst p50/p95 69.570/282.636 ms, CPU 3.746471 s, RSS 71,958,528 bytes. There is no adapter baseline. Existing Activity profile average 35.22/79.68 µs vs baseline 22.56/52.88; worst 50.90/95.18 µs vs 31.03/56.61. Local load was 128.68/121.21/116.46 vs baseline 40.52/40.78/36.44. #854 tracks a locked-VM recheck. These adapter numbers do not measure browser rendering. Gates (terminal output quoted verbatim): `cargo fmt --check` exited 0 with no output. Server production-development build passed. Web production build passed after the final CSS change. Final web check ``` svelte-check found 0 errors and 0 warnings ``` Final representation test ``` Test Files 1 passed (1) Tests 7 passed (7) ``` Full web VM run ``` Test Files 1 failed | 154 passed (155) Tests 17 failed | 1092 passed (1109) ``` Process-worker timezone and grid keyboard rerun ``` Test Files 2 passed (2) Tests 37 passed (37) ``` The full VM command failed only its timezone file; VM workers do not apply its process.env.TZ changes. The unchanged file passed in the process-worker rerun. This is not a clean full-command exit. calternal-plugin ``` Finished `dev` profile [unoptimized + debuginfo] target(s) in 67m 53s test result: ok. 28 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 52.20s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s ``` calternal-plugin-photos ``` Finished `dev` profile [unoptimized + debuginfo] target(s) in 46m 13s test result: ok. 46 passed; 0 failed; 2 ignored; 0 measured; 0 filtered out; finished in 117.20s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s ``` calternal-plugin-calendar ``` Finished `dev` profile [unoptimized + debuginfo] target(s) in 42m 48s test result: ok. 88 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out; finished in 24.69s test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.28s test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.16s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s ``` calternal-plugin-files ``` Finished `dev` profile [unoptimized + debuginfo] target(s) in 9m 12s test result: FAILED. 157 passed; 1 failed; 1 ignored; 0 measured; 0 filtered out; finished in 343.59s ``` calternal-plugin-notes ``` Finished `dev` profile [unoptimized + debuginfo] target(s) in 4m 28s ``` Notes tests were stopped while compiling at the time limit. Money, DAV and Server Clippy/tests were not reached. The first gate queue ended with exit 143; the interrupted Files test was resumed, then failed as quoted. No successful gate claim is made for incomplete commands. Attached evidence on #822: - [agenda-413-390-light-attachment-expanded.png](https://git.kayg.org/attachments/079cf5ac-5533-4371-b4a8-836c512caaec) - [agenda-413-390-light-selected.png](https://git.kayg.org/attachments/2c704122-4330-43f1-b2f8-ffc1d2e939aa) - [agenda-413-390-light-sidebar-range.png](https://git.kayg.org/attachments/2d0b240d-3002-4c5e-b2a3-944496254c99) - [agenda-413-390-light-touch-no-hover.png](https://git.kayg.org/attachments/949de48c-90a3-427a-a9ea-ce29c0118ac6) - [agenda-413-390-light-unfocused.png](https://git.kayg.org/attachments/62fd0e3d-062f-4013-84e0-eba10cf350f1) - [agenda-390-light-hover.png](https://git.kayg.org/attachments/a7643cb0-d719-4d80-bc88-e1e3fc5fcd16) - [agenda-390-light-selected.png](https://git.kayg.org/attachments/3f55f37f-9275-4f00-8ef6-be051f9cac9f) - [agenda-390-light-unfocused.png](https://git.kayg.org/attachments/764b61d4-cee8-49c0-ad85-087a5a455a4e) - [day-390-light-dense.png](https://git.kayg.org/attachments/cdfdc5ce-75db-4208-a07e-7e67c214c34f) - [day-390-light-focus.png](https://git.kayg.org/attachments/83741d05-6709-4a15-af5d-2ee80cd2dd01) Files (complete integration and feature scope): <details><summary>92 changed files</summary> ``` apps/web/e2e/agenda-decks-822.mjs apps/web/e2e/agenda-review-413.mjs apps/web/e2e/calendar-attachment-audio-622.mjs apps/web/e2e/calendar-crossday.mjs apps/web/e2e/calendar-doc-stack.mjs apps/web/e2e/calendar-hover-608.mjs apps/web/e2e/calendar-perf.mjs apps/web/e2e/calendar-preview-421.mjs apps/web/e2e/calendar-view-switcher.mjs apps/web/e2e/calendar.mjs apps/web/e2e/composer.mjs apps/web/e2e/harness.mjs apps/web/e2e/kbd-motion-527.mjs apps/web/e2e/layout-sweep.mjs apps/web/e2e/motion-spring-evidence.mjs apps/web/e2e/pill-feedback.mjs apps/web/src/lib/a11y/inputModality.test.ts apps/web/src/lib/actions/pillFeedback.test.ts apps/web/src/lib/actions/pillFeedback.ts apps/web/src/lib/calendar/ItemPreview.svelte.test.ts apps/web/src/lib/calendar/TimeGrid.svelte.test.ts apps/web/src/lib/calendar/agenda.svelte.test.ts apps/web/src/lib/calendar/attachments.test.ts apps/web/src/lib/calendar/data.test.ts apps/web/src/lib/calendar/data.ts apps/web/src/lib/calendar/edits.test.ts apps/web/src/lib/calendar/edits.ts apps/web/src/lib/calendar/grid.test.ts apps/web/src/lib/calendar/journal.ts apps/web/src/lib/calendar/model.test.ts apps/web/src/lib/calendar/prefs.test.ts apps/web/src/lib/calendar/prefs.ts apps/web/src/lib/calendar/representation.svelte.test.ts apps/web/src/lib/calendar/sidebarState.svelte.ts apps/web/src/lib/components/app-sidebar.svelte apps/web/src/lib/composer/Composer.svelte apps/web/src/lib/files/InfoPanel.svelte apps/web/src/lib/search/SearchPreview.svelte apps/web/src/lib/search/SearchResultRow.svelte apps/web/src/lib/tooltip/tooltip.test.ts apps/web/src/lib/webmcp/tools.ts apps/web/src/routes/calendar/[view]/[date]/+page.svelte apps/web/src/routes/settings/calendars/CalendarsSection.svelte bench/calendar-activity-589.mjs bench/calendar-attachments-603.mjs bench/calendar-hover-608.mjs bench/calendar-inline-audio-622.mjs bench/item-representations-822.mjs bench/run.sh contracts/openapi.json crates/calternal-dav/tests/apple_replay.rs crates/calternal-plugin/src/lib.rs crates/calternal-server/src/system_plugin.rs crates/plugins/calendar/src/items.rs crates/plugins/calendar/src/view.rs crates/plugins/files/src/thumbnails.rs crates/plugins/money/src/lib.rs crates/plugins/notes/src/lib.rs crates/plugins/photos/src/lib.rs docs/DESIGN.md docs/perf/baseline.json docs/perf/runs/2026-10-01-calendar-hover-608.md packages/api-client/src/generated.ts packages/ui/src/components/FloatingSidebar.svelte packages/ui/src/components/ItemCard.svelte packages/ui/src/components/OverlaySurface.svelte packages/ui/src/components/TagPill.svelte packages/ui/src/components/calendar/ActivityStack.svelte packages/ui/src/components/calendar/AgendaList.svelte packages/ui/src/components/calendar/AttachmentDeck.svelte packages/ui/src/components/calendar/CalendarPopover.svelte packages/ui/src/components/calendar/GridColumn.svelte packages/ui/src/components/calendar/ItemPreview.svelte packages/ui/src/components/calendar/MiniMonth.svelte packages/ui/src/components/calendar/MonthGrid.svelte packages/ui/src/components/calendar/TimeGrid.svelte packages/ui/src/components/calendar/attachments.ts packages/ui/src/components/calendar/inlineAudioPlayback.svelte.ts packages/ui/src/components/calendar/layout.ts packages/ui/src/components/calendar/model.ts packages/ui/src/components/composer/VoicePlayback.svelte packages/ui/src/components/composer/VoiceWaveform.svelte packages/ui/src/components/menu/FloatingSurface.svelte packages/ui/src/components/tooltip/place.ts packages/ui/src/components/viewer/QuickLook.svelte packages/ui/src/index.ts packages/ui/src/motion.ts packages/ui/src/time.ts packages/ui/src/tokens.css tests/adversarial/attack.py tests/adversarial/calendar_event_tags.mjs tests/adversarial/item_representations_822.mjs ``` </details> Cleanup: web build and .svelte-kit/output removed. cargo clean is running; its terminal result will be appended if it finishes before the time limit. Source comments were re-read. Worktree is clean; all source changes are committed. Issues remain open.
Author
Owner

Cleanup finished before the time limit. cargo clean output:

     Removed 18947 files, 10.3GiB total

The web build and .svelte-kit/output directories are removed. The worktree is clean. Head remains dc68eb236c. No push, deploy, issue close or further merge was performed.

Cleanup finished before the time limit. `cargo clean` output: ``` Removed 18947 files, 10.3GiB total ``` The web build and .svelte-kit/output directories are removed. The worktree is clean. Head remains dc68eb236c43ecf45b11f730bb78e77aaca103e1. No push, deploy, issue close or further merge was performed.
Author
Owner

agenda-decks round (orchestrator review fixes), head fc147f14c on job/agenda-decks (dev merged in). Web-only; prebuilt server merge-round-7a. No push, no deploy.

Fixed from the review:

  1. One Tag chip. TagPill size="xs" is the dense Card chip in Day, Week, Agenda and previews (leaf text, full Tag in the tooltip and screen-reader text). Agenda no longer shows #work.
  2. Agenda day header shows a short month date in the User's date order (3 Oct, ISO order gives Oct 3), year only outside the current year. No numeric 02/10/26.
  3. Voice. One app-wide player (inlineAudioPlayback): Calendar rows, Activity previews, Search rows, the Search preview, Quick Look and Composer previews play one sound at a time. New VoicePlayToggle is the Compact control; VoicePlayback (Large) runs on the same keyed state, so Compact and Large always agree. Search voice rows: pointer Play button (tabindex -1 inside the listbox option) plus Play/Pause in the Cmd+K action menu; closing Search stops only a Search sound. The clock (0:12 / 1:05) shows after the first play, because rows never prefetch audio (no server duration field exists). ItemCard waveform progress fixed (it got 0–1 but expected 0–100). Voice glyph is a neutral audio-lines icon (the red pill means recording).
  4. Activity actions. Activity cards get the shared item menu (right-click, long-press, Shift+F10): Open, Quick Look, Play (single voice memo), Show in Files, Copy link (single item: its stable link; a set: the day).
  5. Used in shows Journal daily notes as Log rows that open the Calendar day; Notes keep /n/<id>. Calendar Events are not in the backlink index, so they are not listed (gap).

Found in the new screenshots and fixed: open-deck rows used Large 80px thumbnails in 44px rows (overlap) → Regular; Play button overlapped the voice name in collapsed Agenda decks; Agenda Tag chip stretched full width; Month "N more" was clipped in 104px cells → container query shows two rows plus the matching count; grid cards now show their deck when the card has 112px, not only for entries of 54+ minutes.

Gates (verbatim):

svelte-check found 0 errors and 0 warnings   (COMPLETED 2004 FILES 0 ERRORS 0 WARNINGS 0 FILES_WITH_PROBLEMS)
 Test Files  156 passed (156)
      Tests  1116 passed (1116)
PASS #822: 36 production layouts; no item overlap or escaping thumbnail; macOS screenshots in .../artifacts/agenda-decks-822
calendar attachment audio e2e: custom Quick Look playback, waveform seek, speed control, inline playback, touch taps, sibling Quick Look, URL restoration, row actions, stack labels, and 390/820/1440 light/dark screenshots passed

The earlier "17 failed" was the VM-pool timezone file; a fresh full run is clean. No Rust changed.

Evidence (macOS emulation, production build, 390/820/1440 × light/dark): artifacts/agenda-decks-822/ in the worktree — agenda-*-{unfocused,hover,selected}, day-*-{dense,focus}, week-*-dense, week-1440-*-focus, month-*-dense, and 3x crops crop3x-{day,agenda}-{thumbs,text,voice}-{light,dark}.png.

Open:

  • At 1440 Week zoom 160, three overlapping 09:00 entries leave the Dense card a ~40px lane, and its time chip shows a clipped "0". Lane packing is pre-existing; this needs a cramped-lane rule.
  • The server (calendar/src/view.rs) names image attachments Photo · HH:MM or Photo · place even when the User wrote link text ([Coastal trail](…)). Deck rows read "Photo · 11:20", and agenda-review-413.mjs fails on its Open Coastal trail locator. This needs a decision: should link text win over the generated name? Fixing it needs a Rust change and a server rebuild.
agenda-decks round (orchestrator review fixes), head `fc147f14c` on `job/agenda-decks` (dev merged in). Web-only; prebuilt server `merge-round-7a`. No push, no deploy. Fixed from the review: 1. **One Tag chip.** `TagPill size="xs"` is the dense Card chip in Day, Week, Agenda and previews (leaf text, full Tag in the tooltip and screen-reader text). Agenda no longer shows `#work`. 2. **Agenda day header** shows a short month date in the User's date order (`3 Oct`, ISO order gives `Oct 3`), year only outside the current year. No numeric `02/10/26`. 3. **Voice.** One app-wide player (`inlineAudioPlayback`): Calendar rows, Activity previews, Search rows, the Search preview, Quick Look and Composer previews play one sound at a time. New `VoicePlayToggle` is the Compact control; `VoicePlayback` (Large) runs on the same keyed state, so Compact and Large always agree. Search voice rows: pointer Play button (tabindex -1 inside the listbox option) plus Play/Pause in the Cmd+K action menu; closing Search stops only a Search sound. The clock (`0:12 / 1:05`) shows after the first play, because rows never prefetch audio (no server duration field exists). ItemCard waveform progress fixed (it got 0–1 but expected 0–100). Voice glyph is a neutral audio-lines icon (the red pill means recording). 4. **Activity actions.** Activity cards get the shared item menu (right-click, long-press, Shift+F10): Open, Quick Look, Play (single voice memo), Show in Files, Copy link (single item: its stable link; a set: the day). 5. **Used in** shows Journal daily notes as Log rows that open the Calendar day; Notes keep `/n/<id>`. Calendar Events are not in the backlink index, so they are not listed (gap). Found in the new screenshots and fixed: open-deck rows used Large 80px thumbnails in 44px rows (overlap) → Regular; Play button overlapped the voice name in collapsed Agenda decks; Agenda Tag chip stretched full width; Month "N more" was clipped in 104px cells → container query shows two rows plus the matching count; grid cards now show their deck when the card has 112px, not only for entries of 54+ minutes. Gates (verbatim): ``` svelte-check found 0 errors and 0 warnings (COMPLETED 2004 FILES 0 ERRORS 0 WARNINGS 0 FILES_WITH_PROBLEMS) Test Files 156 passed (156) Tests 1116 passed (1116) PASS #822: 36 production layouts; no item overlap or escaping thumbnail; macOS screenshots in .../artifacts/agenda-decks-822 calendar attachment audio e2e: custom Quick Look playback, waveform seek, speed control, inline playback, touch taps, sibling Quick Look, URL restoration, row actions, stack labels, and 390/820/1440 light/dark screenshots passed ``` The earlier "17 failed" was the VM-pool timezone file; a fresh full run is clean. No Rust changed. Evidence (macOS emulation, production build, 390/820/1440 × light/dark): `artifacts/agenda-decks-822/` in the worktree — `agenda-*-{unfocused,hover,selected}`, `day-*-{dense,focus}`, `week-*-dense`, `week-1440-*-focus`, `month-*-dense`, and 3x crops `crop3x-{day,agenda}-{thumbs,text,voice}-{light,dark}.png`. Open: - At 1440 Week zoom 160, three overlapping 09:00 entries leave the Dense card a ~40px lane, and its time chip shows a clipped "0". Lane packing is pre-existing; this needs a cramped-lane rule. - The server (`calendar/src/view.rs`) names image attachments `Photo · HH:MM` or `Photo · place` even when the User wrote link text (`[Coastal trail](…)`). Deck rows read "Photo · 11:20", and `agenda-review-413.mjs` fails on its `Open Coastal trail` locator. This needs a decision: should link text win over the generated name? Fixing it needs a Rust change and a server rebuild.
Author
Owner

agenda-decks follow-up, head 8babe683b (job/agenda-decks). The server was rebuilt for this branch in its own target dir (/mnt/hdd/targets/jobs/agenda-decks). No push, no deploy.

Link text (orchestrator decision). crates/plugins/calendar/src/view.rs: an image attachment keeps the User's own link text ([Coastal trail](…) → "Coastal trail"). The generated "Photo · place/time" name is used only when the link has no text or its text repeats the file name or its stem (case-insensitive). Other files keep the earlier rule. range_resolves_attachment_identities_and_thumbnails covers both cases (Beach → "Photo · 16:33", Coastal trail stays).

Voice row. The Play button is now in flow before the attachment row, so the icon never covers "Standup memo" at any width. The progress line shows only for the sound that owns the player, under its name; no full-width line. The 822 e2e asserts that Play ends before the name at 390/820/1440 × light/dark.

Deck and fan-out (owner review).

  • Collapsed: a stack of rounded cards. The first item is on top in its kind form: Photo thumbnail, document glyph and name, voice waveform chip, text as a title chip (never an image of text). Two cards peek behind it, offset and turned, and a "+N" badge sits on the stack's corner.
  • Agenda: pointer hover, keyboard focus on the deck, or a touch tap fans the cards out horizontally in their row, using the #236 spring (EASE_CSS.spring, DUR.morph, FLIP). Each card is its own target: click/Enter opens Quick Look, right-click/Shift+F10 opens the item menu (Open, Play, Copy link, Delete attachment), and voice cards keep Play. ArrowRight from the deck moves into the cards. Escape, a tap outside or leaving the deck folds the fan. Reduced motion skips the FLIP; the cards appear spread at once.
  • Day/Week: a vertical fan inside the card (on focus or hover) when the card has room. Short cards keep the stack and its count.
  • The deck hover popover and its page plumbing are removed, as is the deck's warm tooltip (it covered the next row).

Gates (verbatim):

cargo fmt --check -p calternal-plugin-calendar   (exit 0, no output)
test result: ok. 88 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out; finished in 3.69s
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 15m 07s   (cargo clippy -p calternal-plugin-calendar --all-targets -- -D warnings)
COMPLETED 2004 FILES 0 ERRORS 0 WARNINGS 0 FILES_WITH_PROBLEMS
 Test Files  156 passed (156)
      Tests  1117 passed (1117)
PASS #822: 36 production layouts; no item overlap or escaping thumbnail; macOS screenshots in .../artifacts/agenda-decks-822
PASS Agenda #413: 3 widths × 2 themes × unfocused, hover/touch, selected, expanded deck and mini-month range; screenshots in .../artifacts/agenda-413
calendar attachment audio e2e: ... 390/820/1440 light/dark screenshots passed

The calendar crate's integration and doc-test lines also passed: 1, 3 and 0 tests. Clippy ran only on the touched crate (calendar).

Test changes, all from owner decisions:

  • agenda-review-413.mjs: hover now asserts the fan and that there is no popover. It finds the card by the User's own name, "Open Coastal trail". The phone run selects through the entry line, because a tap on the deck now fans it. Opening a file goes to Quick Look on the Calendar route (#622). Before "Show earlier days" the test waits until the button is enabled; a click on the disabled button was the earlier timeout.
  • calendar-attachment-audio-622.mjs: the click point now avoids the hover action pill, because Play is in flow.

Screenshots (worktree artifacts/, macOS emulation, production build):

  • agenda-decks-822/agenda-{390,820,1440}-{light,dark}-{collapsed,fanned-pointer,fanned-keyboard,unfocused,selected}.png
  • agenda-decks-822/day-*-focus.png (vertical grid fan), day-*-dense.png, week-*-dense.png, month-*-dense.png
  • agenda-decks-822/fan-frame-{1,2,3}.png (0, 90 and 400 ms of the pointer fan)
  • agenda-decks-822/crop3x-{day,agenda}-{thumbs,text,voice}-{light,dark}.png
  • agenda-413/agenda-413-*-hover.png (fan with "Coastal trail")

Week lane packing is filed as #969 (not fixed here).

agenda-decks follow-up, head `8babe683b` (`job/agenda-decks`). The server was rebuilt for this branch in its own target dir (`/mnt/hdd/targets/jobs/agenda-decks`). No push, no deploy. **Link text (orchestrator decision).** `crates/plugins/calendar/src/view.rs`: an image attachment keeps the User's own link text (`[Coastal trail](…)` → "Coastal trail"). The generated "Photo · place/time" name is used only when the link has no text or its text repeats the file name or its stem (case-insensitive). Other files keep the earlier rule. `range_resolves_attachment_identities_and_thumbnails` covers both cases (`Beach` → "Photo · 16:33", `Coastal trail` stays). **Voice row.** The Play button is now in flow before the attachment row, so the icon never covers "Standup memo" at any width. The progress line shows only for the sound that owns the player, under its name; no full-width line. The 822 e2e asserts that Play ends before the name at 390/820/1440 × light/dark. **Deck and fan-out (owner review).** - Collapsed: a stack of rounded cards. The first item is on top in its kind form: Photo thumbnail, document glyph and name, voice waveform chip, text as a title chip (never an image of text). Two cards peek behind it, offset and turned, and a "+N" badge sits on the stack's corner. - Agenda: pointer hover, keyboard focus on the deck, or a touch tap fans the cards out horizontally in their row, using the #236 spring (`EASE_CSS.spring`, `DUR.morph`, FLIP). Each card is its own target: click/Enter opens Quick Look, right-click/Shift+F10 opens the item menu (Open, Play, Copy link, Delete attachment), and voice cards keep Play. ArrowRight from the deck moves into the cards. Escape, a tap outside or leaving the deck folds the fan. Reduced motion skips the FLIP; the cards appear spread at once. - Day/Week: a vertical fan inside the card (on focus or hover) when the card has room. Short cards keep the stack and its count. - The deck hover popover and its page plumbing are removed, as is the deck's warm tooltip (it covered the next row). Gates (verbatim): ``` cargo fmt --check -p calternal-plugin-calendar (exit 0, no output) test result: ok. 88 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out; finished in 3.69s Finished `dev` profile [unoptimized + debuginfo] target(s) in 15m 07s (cargo clippy -p calternal-plugin-calendar --all-targets -- -D warnings) COMPLETED 2004 FILES 0 ERRORS 0 WARNINGS 0 FILES_WITH_PROBLEMS Test Files 156 passed (156) Tests 1117 passed (1117) PASS #822: 36 production layouts; no item overlap or escaping thumbnail; macOS screenshots in .../artifacts/agenda-decks-822 PASS Agenda #413: 3 widths × 2 themes × unfocused, hover/touch, selected, expanded deck and mini-month range; screenshots in .../artifacts/agenda-413 calendar attachment audio e2e: ... 390/820/1440 light/dark screenshots passed ``` The calendar crate's integration and doc-test lines also passed: 1, 3 and 0 tests. Clippy ran only on the touched crate (calendar). Test changes, all from owner decisions: - `agenda-review-413.mjs`: hover now asserts the fan and that there is no popover. It finds the card by the User's own name, "Open Coastal trail". The phone run selects through the entry line, because a tap on the deck now fans it. Opening a file goes to Quick Look on the Calendar route (#622). Before "Show earlier days" the test waits until the button is enabled; a click on the disabled button was the earlier timeout. - `calendar-attachment-audio-622.mjs`: the click point now avoids the hover action pill, because Play is in flow. Screenshots (worktree `artifacts/`, macOS emulation, production build): - `agenda-decks-822/agenda-{390,820,1440}-{light,dark}-{collapsed,fanned-pointer,fanned-keyboard,unfocused,selected}.png` - `agenda-decks-822/day-*-focus.png` (vertical grid fan), `day-*-dense.png`, `week-*-dense.png`, `month-*-dense.png` - `agenda-decks-822/fan-frame-{1,2,3}.png` (0, 90 and 400 ms of the pointer fan) - `agenda-decks-822/crop3x-{day,agenda}-{thumbs,text,voice}-{light,dark}.png` - `agenda-413/agenda-413-*-hover.png` (fan with "Coastal trail") Week lane packing is filed as #969 (not fixed here).
Author
Owner

agenda-decks polish round, head 7dab53367.

  1. Deck size. Stacked and fanned cards share the Regular size (52px in Agenda; grid cards keep 32px). The two cards behind the top card peek out 10px right and 4px down, turned 5°.
  2. Count badge. "+N" sits at the stack's bottom-right corner, inside the deck. It counts the attachments that are not cards in the deck: the deck holds a bounded sample (up to three visual and three text items), and the rest open with the entry's attachment rows. It reads the same stacked and fanned (+15 in the fixture). Fanned text chips shrink with an ellipsis, so nothing covers the badge. The e2e now checks that.
  3. One focus ring. The Agenda line, day title, row tools and task check drop their own accent outlines and use only the shared #658 ring. Attachment cards draw the shared ring on the visible card, not on the row button around it.

Gates:

COMPLETED 2004 FILES 0 ERRORS 0 WARNINGS 0 FILES_WITH_PROBLEMS
 Test Files  156 passed (156)
      Tests  1117 passed (1117)
PASS #822: 24 production layouts; no item overlap or escaping thumbnail   (390 and 1440)
PASS Agenda #413: 3 widths × 2 themes × unfocused, hover/touch, selected, expanded deck and mini-month range   (run after the size and badge change, before the chip-shrink and badge-check change)

New captures: artifacts/agenda-decks-822/agenda-{390,1440}-{light,dark}-{collapsed,fanned-pointer,fanned-keyboard}.png.

agenda-decks polish round, head `7dab53367`. 1. **Deck size.** Stacked and fanned cards share the Regular size (52px in Agenda; grid cards keep 32px). The two cards behind the top card peek out 10px right and 4px down, turned 5°. 2. **Count badge.** "+N" sits at the stack's bottom-right corner, inside the deck. It counts the attachments that are not cards in the deck: the deck holds a bounded sample (up to three visual and three text items), and the rest open with the entry's attachment rows. It reads the same stacked and fanned (+15 in the fixture). Fanned text chips shrink with an ellipsis, so nothing covers the badge. The e2e now checks that. 3. **One focus ring.** The Agenda line, day title, row tools and task check drop their own accent outlines and use only the shared #658 ring. Attachment cards draw the shared ring on the visible card, not on the row button around it. Gates: ``` COMPLETED 2004 FILES 0 ERRORS 0 WARNINGS 0 FILES_WITH_PROBLEMS Test Files 156 passed (156) Tests 1117 passed (1117) PASS #822: 24 production layouts; no item overlap or escaping thumbnail (390 and 1440) PASS Agenda #413: 3 widths × 2 themes × unfocused, hover/touch, selected, expanded deck and mini-month range (run after the size and badge change, before the chip-shrink and badge-check change) ``` New captures: `artifacts/agenda-decks-822/agenda-{390,1440}-{light,dark}-{collapsed,fanned-pointer,fanned-keyboard}.png`.
Author
Owner

agenda-decks final deck polish, head a5ea4de09 (job/agenda-decks). No push, no deploy.

  1. Focus ring around the whole entry. Keyboard focus now draws the shared #658 ring on the Agenda entry (li.item), so it encloses the time, title and tag, the ⋯ button, and the attachment deck or voice row. The line itself draws no second ring. The ring is inset (outline-offset -2.5px plus the inner band), because the day's content-visibility: auto clips anything outside the row; that was the clipped left edge at 390. The entry content now sits one inset (--agenda-item-inset, 6px) inside the selected surface, so the ring clears the category dot. The selected surface still starts at the Card's padded edge, so the #413 geometry check is unchanged.
  2. Alignment. The title line and the attachment row share one marker gap (--agenda-marker-gap), and the deck lost its 2px start padding. The deck's left edge now matches the title's left edge; the e2e asserts it within 1px at every captured width and theme.
  3. Fanned count. I kept the deck metaphor: "+15" stays a corner badge on the deck and rides on the last card's bottom-right corner when fanned, as on the stack. It is no longer a separate pill. The e2e asserts the badge centre is within 18px of the last card's corner and covers no other card.

Gates:

COMPLETED 2004 FILES 0 ERRORS 0 WARNINGS 0 FILES_WITH_PROBLEMS
 Test Files  156 passed (156)
      Tests  1117 passed (1117)
PASS #822 media contract: 9 finite local checks
PASS #822: 24 production layouts; no item overlap or escaping thumbnail; macOS screenshots in /home/kayg/Developer/calternal-wt/agenda-decks/artifacts/agenda-decks-822
PASS Agenda #413: 3 widths × 2 themes × unfocused, hover/touch, selected, expanded deck and mini-month range; screenshots in /home/kayg/Developer/calternal-wt/agenda-decks/artifacts/agenda-413

The #822 run covered 390 and 1440 (CALTERNAL_DECK_WIDTHS=390,1440) to re-capture the requested set.

Re-captured (12): artifacts/agenda-decks-822/agenda-{390,1440}-{light,dark}-{collapsed,fanned-pointer,fanned-keyboard}.png.

agenda-decks final deck polish, head `a5ea4de09` (`job/agenda-decks`). No push, no deploy. 1. **Focus ring around the whole entry.** Keyboard focus now draws the shared #658 ring on the Agenda entry (`li.item`), so it encloses the time, title and tag, the ⋯ button, and the attachment deck or voice row. The line itself draws no second ring. The ring is inset (outline-offset -2.5px plus the inner band), because the day's `content-visibility: auto` clips anything outside the row; that was the clipped left edge at 390. The entry content now sits one inset (`--agenda-item-inset`, 6px) inside the selected surface, so the ring clears the category dot. The selected surface still starts at the Card's padded edge, so the #413 geometry check is unchanged. 2. **Alignment.** The title line and the attachment row share one marker gap (`--agenda-marker-gap`), and the deck lost its 2px start padding. The deck's left edge now matches the title's left edge; the e2e asserts it within 1px at every captured width and theme. 3. **Fanned count.** I kept the deck metaphor: "+15" stays a corner badge on the deck and rides on the last card's bottom-right corner when fanned, as on the stack. It is no longer a separate pill. The e2e asserts the badge centre is within 18px of the last card's corner and covers no other card. Gates: ``` COMPLETED 2004 FILES 0 ERRORS 0 WARNINGS 0 FILES_WITH_PROBLEMS Test Files 156 passed (156) Tests 1117 passed (1117) PASS #822 media contract: 9 finite local checks PASS #822: 24 production layouts; no item overlap or escaping thumbnail; macOS screenshots in /home/kayg/Developer/calternal-wt/agenda-decks/artifacts/agenda-decks-822 PASS Agenda #413: 3 widths × 2 themes × unfocused, hover/touch, selected, expanded deck and mini-month range; screenshots in /home/kayg/Developer/calternal-wt/agenda-decks/artifacts/agenda-413 ``` The #822 run covered 390 and 1440 (`CALTERNAL_DECK_WIDTHS=390,1440`) to re-capture the requested set. Re-captured (12): `artifacts/agenda-decks-822/agenda-{390,1440}-{light,dark}-{collapsed,fanned-pointer,fanned-keyboard}.png`.
Author
Owner

Resuming #413 + #822 on job/agenda-decks at a5ea4de09. The repo contract, glossary, DESIGN §§29–39 and issue #822 are read. Existing follow-up commits already provide shared leaf Tag chips, readable Agenda dates, Compact voice controls and shared audio focus. I will verify them, finish Used in and Activity action coverage, classify the 17 recorded test failures, and capture the full width/theme macOS screenshot matrix. No push or deploy.

Resuming #413 + #822 on job/agenda-decks at a5ea4de09. The repo contract, glossary, DESIGN §§29–39 and issue #822 are read. Existing follow-up commits already provide shared leaf Tag chips, readable Agenda dates, Compact voice controls and shared audio focus. I will verify them, finish Used in and Activity action coverage, classify the 17 recorded test failures, and capture the full width/theme macOS screenshot matrix. No push or deploy.
Author
Owner

Follow-up findings at e567c473e:

  • The 17 recorded web failures are all assertions in src/lib/calendar/zones.test.ts. None is a load timeout. The prior VM worker ignored process.env.TZ mutations. The unchanged file passes alone with default process workers: Test Files 1 passed (1) / Tests 21 passed (21). No expectation was changed.
  • Inspector Used in currently turns each Daily note into a whole-day link. The existing Journal read endpoint has entry IDs and attachments. The new client adapter uses them to show each matching entry title with /d/#^, resolves relative links with the existing resolver, deduplicates link/embed index rows and refreshes after live Markdown changes. Three focused tests pass.
  • Activity right-click resolves the registered preview, while keyboard actions only resolve Logs/Events/Tasks. The keyboard handler now uses the pointer handler's fallback for Enter, Space and Shift+F10.
  • Existing origin/dev and this job have separate appended DESIGN sections. The requested one-time merge retains both sections.

Decisions: Journal backlink enrichment uses the existing APIs, one request at a time, with no Home scan or new server route. Event attachment backlinks remain outside the Notes index; adding them requires a server contract change and is a remaining coverage gap.

Follow-up findings at e567c473e: - The 17 recorded web failures are all assertions in src/lib/calendar/zones.test.ts. None is a load timeout. The prior VM worker ignored process.env.TZ mutations. The unchanged file passes alone with default process workers: `Test Files 1 passed (1)` / `Tests 21 passed (21)`. No expectation was changed. - Inspector Used in currently turns each Daily note into a whole-day link. The existing Journal read endpoint has entry IDs and attachments. The new client adapter uses them to show each matching entry title with /d/<date>#^<block-id>, resolves relative links with the existing resolver, deduplicates link/embed index rows and refreshes after live Markdown changes. Three focused tests pass. - Activity right-click resolves the registered preview, while keyboard actions only resolve Logs/Events/Tasks. The keyboard handler now uses the pointer handler's fallback for Enter, Space and Shift+F10. - Existing origin/dev and this job have separate appended DESIGN sections. The requested one-time merge retains both sections. Decisions: Journal backlink enrichment uses the existing APIs, one request at a time, with no Home scan or new server route. Event attachment backlinks remain outside the Notes index; adding them requires a server contract change and is a remaining coverage gap.
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
kayg/calternal#822
No description provided.