Files rows: text/Markdown files show a white circle (text-card thumbnail cropped to a circle) instead of a file-kind icon #652

Open
opened 2026-10-02 00:28:14 +00:00 by kayg · 9 comments
Owner

Seen in the #576 review screenshots (Files list, 1440, both themes): small text files (.txt, .md, a tiny PDF) show a white circle as their row icon. At 3× it is the text-card thumbnail (mostly white, tiny text) cropped into a circle. It reads as a broken/empty icon and does not match the folder glyph next to it.

Expected (opinionated default): in list rows, use the file-kind glyph (same set and tint as the folder icon) for text, Markdown and documents whose thumbnail carries no visual information at row size; show a real thumbnail only for media (images, video, PDFs with a rendered first page) and in grid view, and never crop a document thumbnail into a circle — use the shared rounded-rect thumbnail shape. Check Files, Recent, Shared, Trash and search results. Zoom in on icon/text alignment.

Seen in the #576 review screenshots (Files list, 1440, both themes): small text files (`.txt`, `.md`, a tiny PDF) show a **white circle** as their row icon. At 3× it is the text-card thumbnail (mostly white, tiny text) cropped into a circle. It reads as a broken/empty icon and does not match the folder glyph next to it. Expected (opinionated default): in list rows, use the file-kind glyph (same set and tint as the folder icon) for text, Markdown and documents whose thumbnail carries no visual information at row size; show a real thumbnail only for media (images, video, PDFs with a rendered first page) and in grid view, and never crop a document thumbnail into a circle — use the shared rounded-rect thumbnail shape. Check Files, Recent, Shared, Trash and search results. Zoom in on icon/text alignment.
Author
Owner

Starting #652 on job/textthumb-652. Branch base SHA: 687ff703136e71e89f8dfba139e93cd0788b25c1. Initial finding from the issue and code search: the file row renderers use thumbnails as row icons in Files and Recent, and several collection surfaces share that rendering path; I’m tracing the shared component before editing.

Starting #652 on `job/textthumb-652`. Branch base SHA: `687ff703136e71e89f8dfba139e93cd0788b25c1`. Initial finding from the issue and code search: the file row renderers use thumbnails as row icons in Files and Recent, and several collection surfaces share that rendering path; I’m tracing the shared component before editing.
Author
Owner

Cause confirmed in packages/ui/src/components/files/FileCollection.svelte: the list branch passed every item.thumb into a 16–22 px box, including text-card renders. The wrapper used --radius-surface (12 px), which clamps to a circular crop at the 16 px desktop size. Grid tiles already use a larger rounded surface. Search result rows used a generic Lucide file icon instead of the shared extension-aware FileIcon.

Cause confirmed in `packages/ui/src/components/files/FileCollection.svelte`: the list branch passed every `item.thumb` into a 16–22 px box, including text-card renders. The wrapper used `--radius-surface` (12 px), which clamps to a circular crop at the 16 px desktop size. Grid tiles already use a larger rounded surface. Search result rows used a generic Lucide file icon instead of the shared extension-aware `FileIcon`.
Author
Owner

#652 report

Implemented compact-row kind glyphs for files whose text-card thumbnails carry no useful detail at row size. Files, Recent, and Trash share the FileCollection decision; Search uses the shared extension-aware FileIcon. Image, video, and PDF thumbnails remain in list rows. Grid tiles still receive full thumbnails. Small list thumbnails use the rounded inset radius so they do not become circles.

Files

  • packages/ui/src/components/files/FileCollection.svelte
  • packages/ui/src/components/files/FileIcon.svelte
  • packages/ui/src/components/files/rowThumbnail.ts
  • packages/ui/src/index.ts
  • apps/web/src/lib/files/FileCollection.svelte.test.ts
  • apps/web/src/lib/search/SearchResultRow.svelte and SearchResultRow.svelte.test.ts
  • apps/web/e2e/files.mjs, apps/web/e2e/search.mjs, apps/web/e2e/harness.mjs
  • bench/files-row-thumbnail-652.mjs
  • docs/perf/baseline.json

Commits

  • 38ea605b9 Use kind glyphs for text thumbnail rows
  • f622143f2 Emulate macOS in file screenshot evidence
  • 33d452807 Profile row thumbnail kind selection
  • f390aa2a8 Record text thumbnail hot-path measurements
  • 352c08dc3 Assert real Files text rows use kind glyphs

Base was fast-forwarded from origin/dev at c4a61e8cf090170f35b1bed3350d9de20c83ecd5 before final gates. Head SHA: 352c08dc3f957e5d80a9440d17bffac63627d56c.

UX gaps closed

  • Text-card thumbnails now resolve to accent-tinted, shared kind glyphs in compact Files, Recent, and Trash rows. The real-server screenshot harness asserts the glyph and rejects a thumbnail slot for those rows.
  • Search file and text hits use the same extension-aware glyph set.
  • Image, video, PDF, and grid thumbnail paths stay available with rounded-rectangle crops.

UX gaps left

  • The requested Files, Recent, Shared, Trash, and Search screenshots were not generated or attached. The web production build succeeded, but the matching local calternal-server build remained blocked in shared Cargo compilation past the 2-hour limit. The screenshot harness now emulates macOS and is ready to run when that binary is available. No mock or standalone-page screenshots were used.
  • The Shared view therefore has no visual review evidence from this run. No real-Mac VM was used.

Decisions not covered by DESIGN

  • Keep image, video, and PDF previews in compact rows because those renderer kinds show visible image detail at row size; use kind glyphs for all other kinds, including text-card documents.
  • Use --radius-inset for compact list previews to preserve a rounded rectangle at 16–22 px. Grid keeps its existing surface radius.
  • Search has no thumbnail slot, so file and text results use fileGlyphKind and the shared FileIcon directly.

Performance

The files-row-thumbnail-652 profile has no feature-specific baseline (baseline: null). Local result, recorded beside that baseline in docs/perf/baseline.json; the shared host was heavily loaded, so latency is noisy (load average 79.52, 71.23, 62.27 before and after):

  • 24 visible rows, 2,000 runs: p50 0.001 ms, p95 0.010 ms; CPU 10.773 ms total; RSS 26,226,688 B before, 32,042,624 B sampled peak, 32,542,720 B after.
  • 50k rows, 20 runs: p50 0.776 ms, p95 8.842 ms; CPU 22.154 ms; RSS 32,542,720 B before, 32,542,720 B sampled peak, 35,004,416 B after.
  • 50k-row burst, 8 runs: p50 0.820 ms, p95 4.297 ms; CPU 5.742 ms; RSS 35,004,416 B before, 35,004,416 B sampled peak, 36,052,992 B after.

Web gates (output excerpts verbatim)

bun run check:

User browser caches use userStorage; only documented device/public-link exceptions remain.
Text sizes and UI shape values use shared role tokens.
UI transitions and animation options use shared motion tokens or documented exceptions.
Loading svelte-check in workspace: /home/kayg/Developer/calternal-wt/textthumb-652/apps/web
Getting Svelte diagnostics...

svelte-check found 0 errors and 0 warnings

bun run test:

 Test Files  153 passed (153)
      Tests  1058 passed (1058)
   Start at  15:20:19
   Duration  103.37s (transform 57%, environment 20%, import 11%, tests 8%, setup 3%)

bun run build:

  Wrote site to "build"
  ✔ done

node --check apps/web/e2e/files.mjs passed. No Rust source changed, so Rust clippy/test gates were not run. cargo clean output:

     Removed 4769 files, 2.1GiB total

No push, deploy, or merge was done. The issue remains open.

## #652 report Implemented compact-row kind glyphs for files whose text-card thumbnails carry no useful detail at row size. Files, Recent, and Trash share the `FileCollection` decision; Search uses the shared extension-aware `FileIcon`. Image, video, and PDF thumbnails remain in list rows. Grid tiles still receive full thumbnails. Small list thumbnails use the rounded inset radius so they do not become circles. ### Files - `packages/ui/src/components/files/FileCollection.svelte` - `packages/ui/src/components/files/FileIcon.svelte` - `packages/ui/src/components/files/rowThumbnail.ts` - `packages/ui/src/index.ts` - `apps/web/src/lib/files/FileCollection.svelte.test.ts` - `apps/web/src/lib/search/SearchResultRow.svelte` and `SearchResultRow.svelte.test.ts` - `apps/web/e2e/files.mjs`, `apps/web/e2e/search.mjs`, `apps/web/e2e/harness.mjs` - `bench/files-row-thumbnail-652.mjs` - `docs/perf/baseline.json` ### Commits - `38ea605b9` Use kind glyphs for text thumbnail rows - `f622143f2` Emulate macOS in file screenshot evidence - `33d452807` Profile row thumbnail kind selection - `f390aa2a8` Record text thumbnail hot-path measurements - `352c08dc3` Assert real Files text rows use kind glyphs Base was fast-forwarded from `origin/dev` at `c4a61e8cf090170f35b1bed3350d9de20c83ecd5` before final gates. Head SHA: `352c08dc3f957e5d80a9440d17bffac63627d56c`. ### UX gaps closed - Text-card thumbnails now resolve to accent-tinted, shared kind glyphs in compact Files, Recent, and Trash rows. The real-server screenshot harness asserts the glyph and rejects a thumbnail slot for those rows. - Search file and text hits use the same extension-aware glyph set. - Image, video, PDF, and grid thumbnail paths stay available with rounded-rectangle crops. ### UX gaps left - The requested Files, Recent, Shared, Trash, and Search screenshots were not generated or attached. The web production build succeeded, but the matching local `calternal-server` build remained blocked in shared Cargo compilation past the 2-hour limit. The screenshot harness now emulates macOS and is ready to run when that binary is available. No mock or standalone-page screenshots were used. - The Shared view therefore has no visual review evidence from this run. No real-Mac VM was used. ### Decisions not covered by DESIGN - Keep image, video, and PDF previews in compact rows because those renderer kinds show visible image detail at row size; use kind glyphs for all other kinds, including text-card documents. - Use `--radius-inset` for compact list previews to preserve a rounded rectangle at 16–22 px. Grid keeps its existing surface radius. - Search has no thumbnail slot, so file and text results use `fileGlyphKind` and the shared FileIcon directly. ### Performance The `files-row-thumbnail-652` profile has no feature-specific baseline (`baseline: null`). Local result, recorded beside that baseline in `docs/perf/baseline.json`; the shared host was heavily loaded, so latency is noisy (load average 79.52, 71.23, 62.27 before and after): - 24 visible rows, 2,000 runs: p50 0.001 ms, p95 0.010 ms; CPU 10.773 ms total; RSS 26,226,688 B before, 32,042,624 B sampled peak, 32,542,720 B after. - 50k rows, 20 runs: p50 0.776 ms, p95 8.842 ms; CPU 22.154 ms; RSS 32,542,720 B before, 32,542,720 B sampled peak, 35,004,416 B after. - 50k-row burst, 8 runs: p50 0.820 ms, p95 4.297 ms; CPU 5.742 ms; RSS 35,004,416 B before, 35,004,416 B sampled peak, 36,052,992 B after. ### Web gates (output excerpts verbatim) `bun run check`: ```text User browser caches use userStorage; only documented device/public-link exceptions remain. Text sizes and UI shape values use shared role tokens. UI transitions and animation options use shared motion tokens or documented exceptions. Loading svelte-check in workspace: /home/kayg/Developer/calternal-wt/textthumb-652/apps/web Getting Svelte diagnostics... svelte-check found 0 errors and 0 warnings ``` `bun run test`: ```text Test Files 153 passed (153) Tests 1058 passed (1058) Start at 15:20:19 Duration 103.37s (transform 57%, environment 20%, import 11%, tests 8%, setup 3%) ``` `bun run build`: ```text Wrote site to "build" ✔ done ``` `node --check apps/web/e2e/files.mjs` passed. No Rust source changed, so Rust clippy/test gates were not run. `cargo clean` output: ```text Removed 4769 files, 2.1GiB total ``` No push, deploy, or merge was done. The issue remains open.
Author
Owner

Starting screenshot-only Round 2 on job/textthumb-652. Original head: 352c08dc3f957e5d80a9440d17bffac63627d56c. Merged origin/dev once; current head is recorded in the final report. The shared-server CURRENT file is absent; building the production web app and server once. Evidence will cover Files list/grid and Search at 390/820/1440, Light/Dark, macOS emulation, with 3× row crops. No product code changes unless evidence shows a defect.

Starting screenshot-only Round 2 on `job/textthumb-652`. Original head: `352c08dc3f957e5d80a9440d17bffac63627d56c`. Merged `origin/dev` once; current head is recorded in the final report. The shared-server CURRENT file is absent; building the production web app and server once. Evidence will cover Files list/grid and Search at 390/820/1440, Light/Dark, macOS emulation, with 3× row crops. No product code changes unless evidence shows a defect.
Author
Owner

Screenshot setup finding: the current local media wrapper successfully probes and renders the PDF (probe exit 0; 180×80 first page; thumbnail exit 0, 1682 bytes). FFprobe initially exited 127 with libblas.so.3: cannot open shared object file. The host library links cross /etc/alternatives, which the bounded renderer does not mount. Staged resolved libblas and liblapack copies under ignored target/e2e-media-runtime/lib; the same wrapped video probe now exits 0 with 320×180 dimensions. No product files changed. Evidence uses the merge-round server binary from c4a61e8cf090170f35b1bed3350d9de20c83ecd5; its Rust sources and lockfile match this branch, and the production SPA comes from this worktree.

Screenshot setup finding: the current local media wrapper successfully probes and renders the PDF (probe exit 0; 180×80 first page; thumbnail exit 0, 1682 bytes). FFprobe initially exited 127 with `libblas.so.3: cannot open shared object file`. The host library links cross `/etc/alternatives`, which the bounded renderer does not mount. Staged resolved libblas and liblapack copies under ignored `target/e2e-media-runtime/lib`; the same wrapped video probe now exits 0 with 320×180 dimensions. No product files changed. Evidence uses the merge-round server binary from `c4a61e8cf090170f35b1bed3350d9de20c83ecd5`; its Rust sources and lockfile match this branch, and the production SPA comes from this worktree.
Author
Owner

Screenshot defect found in Search at 820 px Light: PDF, video and audio file results have generic file glyphs. SearchResultRow calls the shared fileGlyphKind(title) without MIME; that helper classified media only by MIME. Added suffix fallbacks to the existing shared classifier and four Search row regression cases. No existing test expectations changed. The 390 px 3× crops also show icons centred on the combined title/metadata stack instead of the first title cap height; IconLabel records that broader audit as #253, and this screenshot-only round leaves its geometry for that review.

Screenshot defect found in Search at 820 px Light: PDF, video and audio file results have generic file glyphs. `SearchResultRow` calls the shared `fileGlyphKind(title)` without MIME; that helper classified media only by MIME. Added suffix fallbacks to the existing shared classifier and four Search row regression cases. No existing test expectations changed. The 390 px 3× crops also show icons centred on the combined title/metadata stack instead of the first title cap height; `IconLabel` records that broader audit as #253, and this screenshot-only round leaves its geometry for that review.
Author
Owner

Round 2 is complete. Captured the production Files list, Files grid and Search at 390/820/1440 in Light and Dark with macOS emulation. The phone pass uses touch input. The set has 22 full views, 84 individual 3× row crops and six crop sheets. All eight Files kinds are present. Image, video and PDF rows use completed real renderer output. The final capture run has no browser errors.

The screenshots exposed one additional defect: Search showed generic media glyphs when MIME was absent. Extended the existing shared classifier with media suffix fallbacks and added four focused Search regressions. No existing test expectations changed.

Files changed in this round

  • packages/ui/src/components/files/FileIcon.svelte
  • apps/web/src/lib/search/SearchResultRow.svelte.test.ts
  • Ignored evidence: artifacts/textthumb-652/ (no screenshots or videos committed).

Commits

  • a75458e2c: merge origin/dev once, including the busy-host wrapper fix.
  • 83c7ff450: resolve Search media glyphs from filename suffixes.

Head SHA: 83c7ff450c1930582274fba96a8511d8bbfa35da.

Evidence

Theme / width Files list Files grid Search 3× crops
Light / 390 List Grid Search Crop sheet
Light / 820 List Grid Search Crop sheet
Light / 1440 List Grid Search Crop sheet
Dark / 390 List Grid Search Crop sheet
Dark / 820 List Grid Search Crop sheet
Dark / 1440 List Grid Search Crop sheet

Phone continuation captures: files-list light, files-grid light, files-list dark, files-grid dark.

Download all 84 individual crops, the manifest, runner, provenance and gate logs. The attached archive SHA-256 matches the local archive. All 29 uploads succeeded.

UX gaps closed

  • Search uses PDF, image, video and audio kind glyphs when its hit has no MIME.
  • The Round 1 evidence gap is closed for the requested Files list/grid and Search surfaces at all six width/theme pairs.

UX gaps left / known gaps

  • The phone Files glyph centres on the combined title/metadata block. Search glyphs on rows with snippets centre on both lines. The first title cap height is above that centre. The 3× crops expose this existing geometry for review. The shared IconLabel comment assigns the wider cap-height audit to #253; no geometry expectations were changed here.
  • This round did not retake Recent, Shared or Trash. It covers the specific Round 2 brief.
  • macOS is emulated in Chromium. Real Mac interop belongs to the merge round.

Decisions

  • Keep the suffix fallback in the existing shared classifier. Search hits omit MIME, so the shared function must also classify media names.
  • Reuse the merge-round server binary from c4a61e8cf090170f35b1bed3350d9de20c83ecd5. git diff --name-only job/merge-round-6 HEAD -- crates plugins Cargo.toml Cargo.lock is empty. Serve the current production SPA through routeCurrentBuild. The official shared-server CURRENT file was absent; the duplicate cold server compile was stopped after this equivalent binary was found.
  • Stage resolved BLAS/LAPACK libraries in the ignored local media runtime. The host's alternatives links are outside the wrapper; the staged libraries let the actual FFprobe run. No product code changed for this setup.
  • Keep all review artifacts ignored. No new dependency or design-doc decision was needed.

Gate output, verbatim

cargo fmt --check: exit 0, no output. No Rust source changed, so Rust clippy/test gates do not apply.

bun run check:

$ node scripts/check-user-storage.mjs && node scripts/check-type-tokens.mjs && node scripts/check-motion-tokens.mjs && svelte-kit sync && svelte-check --tsconfig ./tsconfig.json
User browser caches use userStorage; only documented device/public-link exceptions remain.
Text sizes and UI shape values use shared role tokens.
UI transitions and animation options use shared motion tokens or documented exceptions.
Loading svelte-check in workspace: /home/kayg/Developer/calternal-wt/textthumb-652/apps/web
Getting Svelte diagnostics...

svelte-check found 0 errors and 0 warnings

bunx vitest run src/lib/files/FileCollection.svelte.test.ts src/lib/search/SearchResultRow.svelte.test.ts --maxWorkers=2:

 Test Files  2 passed (2)
      Tests  17 passed (17)
   Start at  20:28:41
   Duration  21.44s (transform 64%, environment 26%, tests 4%, import 4%, setup 3%)

bun run build:

  Wrote site to "build"
  ✔ done

Screenshot runner:

PASS light-390 Files list/grid and 6 Search file rows
PASS light-820 Files list/grid and 6 Search file rows
PASS light-1440 Files list/grid and 6 Search file rows
PASS dark-390 Files list/grid and 6 Search file rows
PASS dark-820 Files list/grid and 6 Search file rows
PASS dark-1440 Files list/grid and 6 Search file rows
TEXTTHUMB SCREENSHOTS PASSED

cargo clean:

     Removed 982 files, 503.1MiB total

Web build and .svelte-kit/output were deleted. The temporary local media runtime and this run's fixture Homes were deleted. The worktree is clean. Doc comments of both changed source files were read again.

For the merge round

  • cd apps/web && bun run test: run the combined branch's full web suite once.
  • cd apps/web && bun e2e/files.mjs: prove the real Files, Recent and Trash interactions and glyph assertions.
  • cd apps/web && bun e2e/search.mjs: prove the full Search interactions and real file-hit glyph assertions.
  • Run the combined branch's full e2e, adversarial matrices and Mac interop under the current verification policy. No performance measurement was run; #652 is not a performance issue.

No push or deploy. No merge into dev or main. The issue remains open for the orchestrator's visual review.

Round 2 is complete. Captured the production Files list, Files grid and Search at 390/820/1440 in Light and Dark with macOS emulation. The phone pass uses touch input. The set has 22 full views, 84 individual 3× row crops and six crop sheets. All eight Files kinds are present. Image, video and PDF rows use completed real renderer output. The final capture run has no browser errors. The screenshots exposed one additional defect: Search showed generic media glyphs when MIME was absent. Extended the existing shared classifier with media suffix fallbacks and added four focused Search regressions. No existing test expectations changed. **Files changed in this round** - `packages/ui/src/components/files/FileIcon.svelte` - `apps/web/src/lib/search/SearchResultRow.svelte.test.ts` - Ignored evidence: `artifacts/textthumb-652/` (no screenshots or videos committed). **Commits** - `a75458e2c`: merge `origin/dev` once, including the busy-host wrapper fix. - `83c7ff450`: resolve Search media glyphs from filename suffixes. Head SHA: `83c7ff450c1930582274fba96a8511d8bbfa35da`. **Evidence** | Theme / width | Files list | Files grid | Search | 3× crops | |---|---|---|---|---| | Light / 390 | [List](https://git.kayg.org/attachments/660cfd62-c219-4119-a11f-0fc19ccbb3cb) | [Grid](https://git.kayg.org/attachments/264f8823-51e3-4fd1-8508-c3b21f26ad19) | [Search](https://git.kayg.org/attachments/5f3a35dc-a1d6-40d8-8c01-94936439c18e) | [Crop sheet](https://git.kayg.org/attachments/eea7891a-a8ea-4541-a300-eb2b202d2cc0) | | Light / 820 | [List](https://git.kayg.org/attachments/4cc4e22d-00b1-4829-8b91-d605ee742071) | [Grid](https://git.kayg.org/attachments/1a8d261c-2bb8-44fe-90fd-059ce496cc19) | [Search](https://git.kayg.org/attachments/e9e984c4-ae07-4750-b8d9-901853cff472) | [Crop sheet](https://git.kayg.org/attachments/85699b3f-ca63-4b5e-abe4-2e49ef341e16) | | Light / 1440 | [List](https://git.kayg.org/attachments/8babb201-9318-4ab5-8053-54786eecb6b5) | [Grid](https://git.kayg.org/attachments/d2ea29b6-8d5d-4358-911e-ad1eaa172fef) | [Search](https://git.kayg.org/attachments/b756dd49-6d43-41a8-96cf-792d28e6eaab) | [Crop sheet](https://git.kayg.org/attachments/f36af74d-dce1-439a-a0d4-46c7881702d3) | | Dark / 390 | [List](https://git.kayg.org/attachments/db02f3b2-3723-459a-85fa-226bed8a911e) | [Grid](https://git.kayg.org/attachments/80f5f829-6fe4-43fa-9906-543e369fa8d6) | [Search](https://git.kayg.org/attachments/f4788407-0c81-4736-b498-3267b0ae5873) | [Crop sheet](https://git.kayg.org/attachments/7b674919-3863-4b5b-8454-3a586aaf6892) | | Dark / 820 | [List](https://git.kayg.org/attachments/f094cb96-55c4-4c6c-9ac5-6ccab0fcae2c) | [Grid](https://git.kayg.org/attachments/e48654b5-88f2-45de-8e31-e2610ef2c2f5) | [Search](https://git.kayg.org/attachments/3dbc0e2c-8fb6-4893-9e31-330285f1b898) | [Crop sheet](https://git.kayg.org/attachments/1f59ff30-b21c-456b-a1bf-df329acc8bcf) | | Dark / 1440 | [List](https://git.kayg.org/attachments/4fcbb5f9-b820-4b5d-9814-66ab94d89fd1) | [Grid](https://git.kayg.org/attachments/979979e7-ccaa-4ca2-8d10-f9de942910df) | [Search](https://git.kayg.org/attachments/81f59f9a-aba1-439a-8462-ff71a51f17ea) | [Crop sheet](https://git.kayg.org/attachments/93564f9d-efb1-40b4-b0d1-045db81402ac) | Phone continuation captures: [files-list light](https://git.kayg.org/attachments/de770ce5-0452-4cd5-8d63-d9a5908ca26f), [files-grid light](https://git.kayg.org/attachments/1a51f7e8-a734-483e-a1dd-214723a2d365), [files-list dark](https://git.kayg.org/attachments/71345826-0578-4f2b-9a07-e33e5587e363), [files-grid dark](https://git.kayg.org/attachments/c6d96317-ed15-4b4e-a87e-5b6dfcfe99d4). [Download all 84 individual crops, the manifest, runner, provenance and gate logs](https://git.kayg.org/attachments/011d4f32-a6f3-43e1-a7ef-4d53c37c6a66). The attached archive SHA-256 matches the local archive. All 29 uploads succeeded. **UX gaps closed** - Search uses PDF, image, video and audio kind glyphs when its hit has no MIME. - The Round 1 evidence gap is closed for the requested Files list/grid and Search surfaces at all six width/theme pairs. **UX gaps left / known gaps** - The phone Files glyph centres on the combined title/metadata block. Search glyphs on rows with snippets centre on both lines. The first title cap height is above that centre. The 3× crops expose this existing geometry for review. The shared `IconLabel` comment assigns the wider cap-height audit to #253; no geometry expectations were changed here. - This round did not retake Recent, Shared or Trash. It covers the specific Round 2 brief. - macOS is emulated in Chromium. Real Mac interop belongs to the merge round. **Decisions** - Keep the suffix fallback in the existing shared classifier. Search hits omit MIME, so the shared function must also classify media names. - Reuse the merge-round server binary from `c4a61e8cf090170f35b1bed3350d9de20c83ecd5`. `git diff --name-only job/merge-round-6 HEAD -- crates plugins Cargo.toml Cargo.lock` is empty. Serve the current production SPA through `routeCurrentBuild`. The official shared-server CURRENT file was absent; the duplicate cold server compile was stopped after this equivalent binary was found. - Stage resolved BLAS/LAPACK libraries in the ignored local media runtime. The host's alternatives links are outside the wrapper; the staged libraries let the actual FFprobe run. No product code changed for this setup. - Keep all review artifacts ignored. No new dependency or design-doc decision was needed. **Gate output, verbatim** `cargo fmt --check`: exit 0, no output. No Rust source changed, so Rust clippy/test gates do not apply. `bun run check`: ```text $ node scripts/check-user-storage.mjs && node scripts/check-type-tokens.mjs && node scripts/check-motion-tokens.mjs && svelte-kit sync && svelte-check --tsconfig ./tsconfig.json User browser caches use userStorage; only documented device/public-link exceptions remain. Text sizes and UI shape values use shared role tokens. UI transitions and animation options use shared motion tokens or documented exceptions. Loading svelte-check in workspace: /home/kayg/Developer/calternal-wt/textthumb-652/apps/web Getting Svelte diagnostics... svelte-check found 0 errors and 0 warnings ``` `bunx vitest run src/lib/files/FileCollection.svelte.test.ts src/lib/search/SearchResultRow.svelte.test.ts --maxWorkers=2`: ```text Test Files 2 passed (2) Tests 17 passed (17) Start at 20:28:41 Duration 21.44s (transform 64%, environment 26%, tests 4%, import 4%, setup 3%) ``` `bun run build`: ```text Wrote site to "build" ✔ done ``` Screenshot runner: ```text PASS light-390 Files list/grid and 6 Search file rows PASS light-820 Files list/grid and 6 Search file rows PASS light-1440 Files list/grid and 6 Search file rows PASS dark-390 Files list/grid and 6 Search file rows PASS dark-820 Files list/grid and 6 Search file rows PASS dark-1440 Files list/grid and 6 Search file rows TEXTTHUMB SCREENSHOTS PASSED ``` `cargo clean`: ```text Removed 982 files, 503.1MiB total ``` Web `build` and `.svelte-kit/output` were deleted. The temporary local media runtime and this run's fixture Homes were deleted. The worktree is clean. Doc comments of both changed source files were read again. **For the merge round** - `cd apps/web && bun run test`: run the combined branch's full web suite once. - `cd apps/web && bun e2e/files.mjs`: prove the real Files, Recent and Trash interactions and glyph assertions. - `cd apps/web && bun e2e/search.mjs`: prove the full Search interactions and real file-hit glyph assertions. - Run the combined branch's full e2e, adversarial matrices and Mac interop under the current verification policy. No performance measurement was run; #652 is not a performance issue. No push or deploy. No merge into `dev` or `main`. The issue remains open for the orchestrator's visual review.
Author
Owner

Starting the #652 send-back on branch job/textthumb-652 at 83c7ff450c1930582274fba96a8511d8bbfa35da. The branch base is c4faf184df726a9375ae0c13bdfb6018ac2cf57e. I am checking the shared row-thumbnail picker and Search row typography/tints, then I will update the focused tests and production screenshot set.

Starting the #652 send-back on branch `job/textthumb-652` at `83c7ff450c1930582274fba96a8511d8bbfa35da`. The branch base is `c4faf184df726a9375ae0c13bdfb6018ac2cf57e`. I am checking the shared row-thumbnail picker and Search row typography/tints, then I will update the focused tests and production screenshot set.
Author
Owner

#652 send-back complete

Final head: 9b812f9fd242ed59edf454930fc224ea44a9362c (job/textthumb-652). No push or deploy.

What changed

  • Compact Files and Recent rows now show a PDF glyph when the source is under 4 KiB or its size is unknown. Larger PDFs keep their thumbnail. The shared picker also uses glyphs for text-card kinds and keeps image/video thumbnails. Grid tiles still use full thumbnails.
  • Search file, text and folder result titles use one regular weight (450); matches remain visible through the existing highlight.
  • File-kind glyphs in Search and Files inherit one root --file-glyph-accent theme token. Search glass text can keep its contrast color without darkening the glyph.
  • Real-server regression assertions cover the tiny PDF, Search title weight and shared tint. The existing #652 row-thumbnail benchmark/profile remains in bench/files-row-thumbnail-652.mjs and docs/perf/baseline.json.

Files

  • packages/ui/src/components/files/FileCollection.svelte
  • packages/ui/src/components/files/FileIcon.svelte
  • packages/ui/src/components/files/rowThumbnail.ts
  • packages/ui/src/tokens.css
  • packages/ui/src/index.ts
  • apps/web/src/lib/files/FilesBrowser.svelte
  • apps/web/src/lib/files/RecentView.svelte
  • apps/web/src/lib/files/TrashView.svelte
  • apps/web/src/lib/files/FileCollection.svelte.test.ts
  • apps/web/src/lib/search/SearchResultRow.svelte
  • apps/web/src/lib/search/SearchResultRow.svelte.test.ts
  • apps/web/e2e/files.mjs
  • apps/web/e2e/search.mjs
  • apps/web/e2e/harness.mjs
  • bench/files-row-thumbnail-652.mjs
  • docs/perf/baseline.json
  • docs/DESIGN.md came from the required origin/dev merge (2254e6e2e).

UX gaps closed

  • Tiny PDF rows now have a visible document glyph instead of a blank white thumbnail.
  • Search title weights are consistent across file kinds, with the match highlight as the emphasis.
  • Search and Files row glyph tints now match.
  • Production screenshots cover Files list, Files grid and Search at 390, 820 and 1440 px in Light and Dark, with macOS platform emulation. The 390 px run uses touch emulation.

Evidence: screenshot and crop archive. It contains 84 individual 3× row crops and six crop sheets. The 22 full screenshots are also attached separately. Example: Files list, Light, 390 px.

The screenshot build was captured at 93dac00cd8cacc9d4dd766f08d585d73c7ca36db. Final commit 9b812f9fd only fixes comments and indentation after the visual capture; it does not change runtime behavior or emitted UI.

UX gaps left

  • Two-line Search rows with snippets center the icon against the title-and-snippet stack, so the title cap centre sits above the icon centre. I noted this on #253 with a link to the 390 px crop sheet.
  • This run used Chromium with macOS emulation. Real Mac interop remains for the merge round.

Decisions not covered by DESIGN

  • Use a 4 KiB source-size floor for compact PDF thumbnails. Unknown or smaller files use the glyph. This keeps row rendering cheap and fixes tiny pages that have no useful image detail at row size.
  • Resolve the shared file-glyph tint from the root theme accent. Glass surfaces locally darken --accent for readable text, but that local contrast treatment should not change file-kind glyphs.

Gate output, verbatim

cargo fmt --check: exit 0; stdout and stderr were empty. No Rust source changed, so per-crate clippy/test gates do not apply.

cd apps/web && bun run check:

$ node scripts/check-user-storage.mjs && node scripts/check-type-tokens.mjs && node scripts/check-motion-tokens.mjs && svelte-kit sync && svelte-check --tsconfig ./tsconfig.json
User browser caches use userStorage; only documented device/public-link exceptions remain.
Text sizes and UI shape values use shared role tokens.
UI transitions and animation options use shared motion tokens or documented exceptions.
Loading svelte-check in workspace: /home/kayg/Developer/calternal-wt/textthumb-652/apps/web
Getting Svelte diagnostics...

svelte-check found 0 errors and 0 warnings

bunx vitest run src/lib/files/FileCollection.svelte.test.ts src/lib/search/SearchResultRow.svelte.test.ts --maxWorkers=2:

 RUN  v5.0.1 /home/kayg/Developer/calternal-wt/textthumb-652/apps/web

 Test Files  2 passed (2)
      Tests  20 passed (20)
   Start at  11:48:19
   Duration  11.93s (transform 74%, tests 10%, environment 7%, import 6%, setup 3%)

  Transform  |component| transforming modules took 16.32s · 74% of tracked time, re-done on every run
             persist transforms across runs with fsModuleCache: true
             learn more: https://vitest.dev/guide/improving-performance#caching-between-reruns

bun run build succeeded:

✓ built in 54.98s

Run npm run preview to preview your production build locally.

> Using @sveltejs/adapter-static
  Wrote site to "build"
  ✔ done

Production screenshot runner:

PASS light-390 Files list/grid and 6 Search file rows
PASS light-820 Files list/grid and 6 Search file rows
PASS light-1440 Files list/grid and 6 Search file rows
PASS dark-390 Files list/grid and 6 Search file rows
PASS dark-820 Files list/grid and 6 Search file rows
PASS dark-1440 Files list/grid and 6 Search file rows
TEXTTHUMB SCREENSHOTS PASSED

cargo clean:

     Removed 7237 files, 4.6GiB total

Web build output and the temporary local media runtime were removed. The worktree is clean. I re-read the doc comments in the touched source files before finishing.

For the merge round

  • cd apps/web && bun run test — run the combined branch's full web suite.
  • cd apps/web && bun run test:e2e:files — prove Files, Recent and Trash interactions, including the tiny-PDF glyph assertion.
  • cd apps/web && bun run test:e2e:search — prove real Search file results and keyboard/pointer flows.
  • tests/adversarial/run.sh — run the full real-server hostile-input, authorization and concurrency probes once on the combined branch.
  • Run the combined branch's full e2e suite, deployed-build/o2 checks and real Mac interop per the merge-round policy.

No new performance measurement was run in this visual send-back round; the existing #652 profile and local result remain recorded in the performance baseline.

## #652 send-back complete Final head: `9b812f9fd242ed59edf454930fc224ea44a9362c` (`job/textthumb-652`). No push or deploy. ### What changed - Compact Files and Recent rows now show a PDF glyph when the source is under 4 KiB or its size is unknown. Larger PDFs keep their thumbnail. The shared picker also uses glyphs for text-card kinds and keeps image/video thumbnails. Grid tiles still use full thumbnails. - Search file, text and folder result titles use one regular weight (`450`); matches remain visible through the existing highlight. - File-kind glyphs in Search and Files inherit one root `--file-glyph-accent` theme token. Search glass text can keep its contrast color without darkening the glyph. - Real-server regression assertions cover the tiny PDF, Search title weight and shared tint. The existing #652 row-thumbnail benchmark/profile remains in `bench/files-row-thumbnail-652.mjs` and `docs/perf/baseline.json`. ### Files - `packages/ui/src/components/files/FileCollection.svelte` - `packages/ui/src/components/files/FileIcon.svelte` - `packages/ui/src/components/files/rowThumbnail.ts` - `packages/ui/src/tokens.css` - `packages/ui/src/index.ts` - `apps/web/src/lib/files/FilesBrowser.svelte` - `apps/web/src/lib/files/RecentView.svelte` - `apps/web/src/lib/files/TrashView.svelte` - `apps/web/src/lib/files/FileCollection.svelte.test.ts` - `apps/web/src/lib/search/SearchResultRow.svelte` - `apps/web/src/lib/search/SearchResultRow.svelte.test.ts` - `apps/web/e2e/files.mjs` - `apps/web/e2e/search.mjs` - `apps/web/e2e/harness.mjs` - `bench/files-row-thumbnail-652.mjs` - `docs/perf/baseline.json` - `docs/DESIGN.md` came from the required `origin/dev` merge (`2254e6e2e`). ### UX gaps closed - Tiny PDF rows now have a visible document glyph instead of a blank white thumbnail. - Search title weights are consistent across file kinds, with the match highlight as the emphasis. - Search and Files row glyph tints now match. - Production screenshots cover Files list, Files grid and Search at 390, 820 and 1440 px in Light and Dark, with macOS platform emulation. The 390 px run uses touch emulation. Evidence: [screenshot and crop archive](https://git.kayg.org/attachments/ffcf2c88-63b7-4363-95a6-0844d2cf4178). It contains 84 individual 3× row crops and six crop sheets. The 22 full screenshots are also attached separately. Example: [Files list, Light, 390 px](https://git.kayg.org/attachments/b11c3de8-32e1-428b-9a9a-ca1712467495). The screenshot build was captured at `93dac00cd8cacc9d4dd766f08d585d73c7ca36db`. Final commit `9b812f9fd` only fixes comments and indentation after the visual capture; it does not change runtime behavior or emitted UI. ### UX gaps left - Two-line Search rows with snippets center the icon against the title-and-snippet stack, so the title cap centre sits above the icon centre. I noted this on #253 with a link to the 390 px crop sheet. - This run used Chromium with macOS emulation. Real Mac interop remains for the merge round. ### Decisions not covered by DESIGN - Use a 4 KiB source-size floor for compact PDF thumbnails. Unknown or smaller files use the glyph. This keeps row rendering cheap and fixes tiny pages that have no useful image detail at row size. - Resolve the shared file-glyph tint from the root theme accent. Glass surfaces locally darken `--accent` for readable text, but that local contrast treatment should not change file-kind glyphs. ### Gate output, verbatim `cargo fmt --check`: exit 0; stdout and stderr were empty. No Rust source changed, so per-crate clippy/test gates do not apply. `cd apps/web && bun run check`: ```text $ node scripts/check-user-storage.mjs && node scripts/check-type-tokens.mjs && node scripts/check-motion-tokens.mjs && svelte-kit sync && svelte-check --tsconfig ./tsconfig.json User browser caches use userStorage; only documented device/public-link exceptions remain. Text sizes and UI shape values use shared role tokens. UI transitions and animation options use shared motion tokens or documented exceptions. Loading svelte-check in workspace: /home/kayg/Developer/calternal-wt/textthumb-652/apps/web Getting Svelte diagnostics... svelte-check found 0 errors and 0 warnings ``` `bunx vitest run src/lib/files/FileCollection.svelte.test.ts src/lib/search/SearchResultRow.svelte.test.ts --maxWorkers=2`: ```text RUN v5.0.1 /home/kayg/Developer/calternal-wt/textthumb-652/apps/web Test Files 2 passed (2) Tests 20 passed (20) Start at 11:48:19 Duration 11.93s (transform 74%, tests 10%, environment 7%, import 6%, setup 3%) Transform |component| transforming modules took 16.32s · 74% of tracked time, re-done on every run persist transforms across runs with fsModuleCache: true learn more: https://vitest.dev/guide/improving-performance#caching-between-reruns ``` `bun run build` succeeded: ```text ✓ built in 54.98s Run npm run preview to preview your production build locally. > Using @sveltejs/adapter-static Wrote site to "build" ✔ done ``` Production screenshot runner: ```text PASS light-390 Files list/grid and 6 Search file rows PASS light-820 Files list/grid and 6 Search file rows PASS light-1440 Files list/grid and 6 Search file rows PASS dark-390 Files list/grid and 6 Search file rows PASS dark-820 Files list/grid and 6 Search file rows PASS dark-1440 Files list/grid and 6 Search file rows TEXTTHUMB SCREENSHOTS PASSED ``` `cargo clean`: ```text Removed 7237 files, 4.6GiB total ``` Web build output and the temporary local media runtime were removed. The worktree is clean. I re-read the doc comments in the touched source files before finishing. ### For the merge round - `cd apps/web && bun run test` — run the combined branch's full web suite. - `cd apps/web && bun run test:e2e:files` — prove Files, Recent and Trash interactions, including the tiny-PDF glyph assertion. - `cd apps/web && bun run test:e2e:search` — prove real Search file results and keyboard/pointer flows. - `tests/adversarial/run.sh` — run the full real-server hostile-input, authorization and concurrency probes once on the combined branch. - Run the combined branch's full e2e suite, deployed-build/o2 checks and real Mac interop per the merge-round policy. No new performance measurement was run in this visual send-back round; the existing #652 profile and local result remain recorded in the performance baseline.
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#652
No description provided.