Search preview: title descenders are clipped (j, p, g cut off) #1004

Open
opened 2026-10-03 09:55:57 +00:00 by kayg · 8 comments
Owner

Found in review (2026-10-03, textthumb-652 search-files-dark-1440.png)

In the Search window's preview pane, the selected item's title ("652-image.jpg") has its descenders cut off: the bottom of j, p and g is clipped. The title box's line height or overflow clips the glyphs.

Fix

Give the preview title a line box that fits descenders (role line-height token, no fixed height with overflow hidden); keep truncation with an ellipsis on one line using text-overflow without clipping descenders (padding-block or line-height ≥ 1.25). Check every preview title kind (photo, file, note, mail) at 390/820/1440 light/dark with 3x crops; add an e2e assertion that the title's scrollHeight ≤ clientHeight.

## Found in review (2026-10-03, textthumb-652 search-files-dark-1440.png) In the Search window's preview pane, the selected item's title ("652-image.jpg") has its descenders cut off: the bottom of j, p and g is clipped. The title box's line height or overflow clips the glyphs. ## Fix Give the preview title a line box that fits descenders (role line-height token, no fixed height with overflow hidden); keep truncation with an ellipsis on one line using text-overflow without clipping descenders (padding-block or line-height ≥ 1.25). Check every preview title kind (photo, file, note, mail) at 390/820/1440 light/dark with 3x crops; add an e2e assertion that the title's scrollHeight ≤ clientHeight.
Author
Owner

Starting #1004 on branch job/pvtitle-1004, based on origin/dev at d4e7188810a89fb0e8e6b162279917f7e23989f9. I am locating the Search preview title styles and existing production-build screenshot/e2e coverage before making a focused fix.

Starting #1004 on branch `job/pvtitle-1004`, based on `origin/dev` at `d4e7188810a89fb0e8e6b162279917f7e23989f9`. I am locating the Search preview title styles and existing production-build screenshot/e2e coverage before making a focused fix.
Author
Owner

Finding: apps/web/src/lib/search/SearchPreview.svelte applies text-box: trim-both cap alphabetic to every preview h3, which removes the descender allowance below the alphabetic baseline. Its photo and file headings also render FileName with the default two-line clamp. I will scope one-line ellipsis to Search result titles and keep the existing two-line FileName rule for anchored previews and the Inspector, as DESIGN §34 currently specifies.

Finding: `apps/web/src/lib/search/SearchPreview.svelte` applies `text-box: trim-both cap alphabetic` to every preview `h3`, which removes the descender allowance below the alphabetic baseline. Its photo and file headings also render `FileName` with the default two-line clamp. I will scope one-line ellipsis to Search result titles and keep the existing two-line `FileName` rule for anchored previews and the Inspector, as DESIGN §34 currently specifies.
Author
Owner

Rechecked origin/dev d4e7188810. SearchPreview still applies text-box trim-both cap alphabetic to preview h3, and photo/file titles use the default FileName heading clamp. The proposed fix is on job/pvtitle-1004, not dev. Keep open until descender-safe one-line rendering and width and theme coverage land.

Rechecked origin/dev d4e7188810a89fb0e8e6b162279917f7e23989f9. SearchPreview still applies text-box trim-both cap alphabetic to preview h3, and photo/file titles use the default FileName heading clamp. The proposed fix is on job/pvtitle-1004, not dev. Keep open until descender-safe one-line rendering and width and theme coverage land.
Author
Owner

Build prerequisite finding: /mnt/hdd/targets/shared-server/CURRENT is absent. The first local cargo build -p calternal-server reached the embed macro and stopped because apps/web/build/ did not exist. I am producing the production SPA and will retry the local server build.

Build prerequisite finding: `/mnt/hdd/targets/shared-server/CURRENT` is absent. The first local `cargo build -p calternal-server` reached the embed macro and stopped because `apps/web/build/` did not exist. I am producing the production SPA and will retry the local server build.
Author
Owner

The production build completed and wrote apps/web/build. The first Cargo process invoked the embed macro before that directory existed and later reported that Frontend::get was unavailable. I am retrying the same local server build with the required SPA present.

The production build completed and wrote `apps/web/build`. The first Cargo process invoked the embed macro before that directory existed and later reported that `Frontend::get` was unavailable. I am retrying the same local server build with the required SPA present.
Author
Owner

E2E finding: macOS platform emulation in the full functional browser context made the existing #545 Index-indicator flow open Search at 820px without focusing its combobox; openSearch timed out after 30 seconds. I am moving platform emulation into the dedicated screenshot contexts and keeping the functional flow on the host key convention. The screenshot flow will open the real Search deep link.

E2E finding: macOS platform emulation in the full functional browser context made the existing #545 Index-indicator flow open Search at 820px without focusing its combobox; `openSearch` timed out after 30 seconds. I am moving platform emulation into the dedicated screenshot contexts and keeping the functional flow on the host key convention. The screenshot flow will open the real Search deep link.
Author
Owner

At 820 px the preview does not render: DESIGN §32 S11 and §34 remove it below 960 px. I kept that layout. Screenshot evidence at 820 px will show the selected result title and its 3x crop; the 390 px phone preview and 1440 px desktop pane will cover the preview title geometry.

At 820 px the preview does not render: DESIGN §32 S11 and §34 remove it below 960 px. I kept that layout. Screenshot evidence at 820 px will show the selected result title and its 3x crop; the 390 px phone preview and 1440 px desktop pane will cover the preview title geometry.
Author
Owner

Built

Search preview headings now keep the shared title line-height, natural height, and vertical padding. They use one-line ellipsis without alphabetic-edge trimming. Photo and file FileName titles retain their complete text and accessible name.

The Search E2E now checks real photo, text (file), note, and mail results. It asserts the result kind, visible full title text, one-line geometry, and scrollHeight <= clientHeight. It reuses the existing isolated Mail database fixture.

Files

  • apps/web/src/lib/search/SearchPreview.svelte
  • packages/ui/src/components/files/FileName.svelte
  • apps/web/e2e/search.mjs
  • docs/DESIGN.md

Commits: dcbb104a550731d1c0399cf014132a92354bd439, 9a3e0141ad5d72d24be1e7ef56d8d5db982a8d38

Head: 9a3e0141ad5d72d24be1e7ef56d8d5db982a8d38

Visual evidence

Attached 48 PNGs to this issue: 24 production screenshots and 24 device-scale 3x title crops. They cover all four result kinds, both themes, and 390/820/1440 px. Screenshot contexts expose macOS platform signals.

Gates

cargo fmt --check passed (exit 0; no output). No Rust source changed, so per-crate Clippy and Rust tests were not run. cargo build -p calternal-server passed to provide the local E2E server.

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/pvtitle-1004/apps/web
Getting Svelte diagnostics...

svelte-check found 0 errors and 0 warnings

Focused Vitest:

Test Files  2 passed (2)
     Tests  9 passed (9)

Focused production-server E2E:

search title e2e: ok
CSP REPORTS search: 0 across 3 pages

Production build:

✓ built in 41.52s
Run npm run preview to preview your production build locally.

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

Cleanup: cargo clean reported Removed 7237 files, 4.6GiB total; apps/web/build and apps/web/.svelte-kit were removed.

UX gaps closed

  • Descenders remain within photo, file, Note, and Mail preview title line boxes.
  • Long photo and file titles ellipsize on one line while preserving their full accessible name.
  • The focused checks cover pointer hover and the phone long-press preview.

UX gaps left

  • DESIGN §32 S11 removes the Search preview below 960 px. At 820 px, the production screenshot and 3x crop show the selected result title; no preview title is rendered there to crop.
  • The broader Search E2E previously timed out in the #545 Index flow at 820 px while openSearch waited for the combobox to receive focus. The focused #1004 flow passes. The merge round should rerun the broader Search flow and resolve or triage that timeout.

Decisions

  • DESIGN §32 S11 keeps the preview hidden at 820 px. I preserved that layout and captured the real selected-result title at tablet width.
  • I reused tests/adversarial/mail_screenshot_fixture.py for a real Mail Search hit. This avoids substituting the Mail navigation row for a message result.
  • I added SEARCH_E2E_TITLE_ONLY=1 to run the #1004 regression independently from the #545 focus flow.

For the merge round

Run the full Search E2E against the merged build. It must prove the #545 indexing flow focuses Search at 820 px and that the full Search suite completes:

cd apps/web
bun run build
source /mnt/hdd/targets/shared-server/CURRENT
TMPDIR="$PWD/../../target/tmp" bun e2e/search.mjs --screenshots "$PWD/../../artifacts/pvtitle-1004"
## Built Search preview headings now keep the shared title line-height, natural height, and vertical padding. They use one-line ellipsis without alphabetic-edge trimming. Photo and file `FileName` titles retain their complete text and accessible name. The Search E2E now checks real `photo`, `text` (file), `note`, and `mail` results. It asserts the result kind, visible full title text, one-line geometry, and `scrollHeight <= clientHeight`. It reuses the existing isolated Mail database fixture. ## Files - `apps/web/src/lib/search/SearchPreview.svelte` - `packages/ui/src/components/files/FileName.svelte` - `apps/web/e2e/search.mjs` - `docs/DESIGN.md` Commits: `dcbb104a550731d1c0399cf014132a92354bd439`, `9a3e0141ad5d72d24be1e7ef56d8d5db982a8d38` Head: `9a3e0141ad5d72d24be1e7ef56d8d5db982a8d38` ## Visual evidence Attached 48 PNGs to this issue: 24 production screenshots and 24 device-scale 3x title crops. They cover all four result kinds, both themes, and 390/820/1440 px. Screenshot contexts expose macOS platform signals. - [1440 px light photo crop](https://git.kayg.org/attachments/eab0766b-f839-4245-8412-922aa6fecb92) - [390 px dark Mail crop](https://git.kayg.org/attachments/551fa671-81da-497c-b6fc-c1eb3c7dafe8) - [820 px dark Note result-title crop](https://git.kayg.org/attachments/5ff3e9f8-c13f-4a78-bd1c-218793a00c53) ## Gates `cargo fmt --check` passed (exit 0; no output). No Rust source changed, so per-crate Clippy and Rust tests were not run. `cargo build -p calternal-server` passed to provide the local E2E server. `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/pvtitle-1004/apps/web Getting Svelte diagnostics... svelte-check found 0 errors and 0 warnings ``` Focused Vitest: ```text Test Files 2 passed (2) Tests 9 passed (9) ``` Focused production-server E2E: ```text search title e2e: ok CSP REPORTS search: 0 across 3 pages ``` Production build: ```text ✓ built in 41.52s Run npm run preview to preview your production build locally. > Using @sveltejs/adapter-static Wrote site to "build" ✔ done ``` Cleanup: `cargo clean` reported `Removed 7237 files, 4.6GiB total`; `apps/web/build` and `apps/web/.svelte-kit` were removed. ## UX gaps closed - Descenders remain within photo, file, Note, and Mail preview title line boxes. - Long photo and file titles ellipsize on one line while preserving their full accessible name. - The focused checks cover pointer hover and the phone long-press preview. ## UX gaps left - DESIGN §32 S11 removes the Search preview below 960 px. At 820 px, the production screenshot and 3x crop show the selected result title; no preview title is rendered there to crop. - The broader Search E2E previously timed out in the #545 Index flow at 820 px while `openSearch` waited for the combobox to receive focus. The focused #1004 flow passes. The merge round should rerun the broader Search flow and resolve or triage that timeout. ## Decisions - DESIGN §32 S11 keeps the preview hidden at 820 px. I preserved that layout and captured the real selected-result title at tablet width. - I reused `tests/adversarial/mail_screenshot_fixture.py` for a real Mail Search hit. This avoids substituting the Mail navigation row for a message result. - I added `SEARCH_E2E_TITLE_ONLY=1` to run the #1004 regression independently from the #545 focus flow. ## For the merge round Run the full Search E2E against the merged build. It must prove the #545 indexing flow focuses Search at 820 px and that the full Search suite completes: ```sh cd apps/web bun run build source /mnt/hdd/targets/shared-server/CURRENT TMPDIR="$PWD/../../target/tmp" bun e2e/search.mjs --screenshots "$PWD/../../artifacts/pvtitle-1004" ```
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#1004
No description provided.