Search: footer band and top blur are back (regression of the floating action Pills decision) #1360

Closed
opened 2026-10-07 14:03:38 +00:00 by kayg · 16 comments
Owner

Owner report 2026-10-07 on production 0419170fe (dark theme, desktop): "the search bottom bar is back and the top bar is some random blur".

Owner decision (2026-10-02, reaffirmed; #499): the action hints (Open / See all / Actions) are SEPARATE small floating glass Pills at the bottom right of the results column, floating OVER the results with the shared ProgressiveBlur behind them. NO bottom band, no joined footer bar, no divider lines, and no divider or band under the search field.

Regression: #1123/#1137 (commit 5bbcc7860, 2026-10-05) moved the Pills into a footer row that is a flex sibling after the result scroller (.sw-action-pills), which paints a visible band with a top edge under the results; it also added a top-edge progressive blur under the group heading, so the sticky "RECENT" heading shows as a lighter band and the first row under it is a heavy blur smear.

Also seen: a document preview in the right pane rendered as an opaque white block with black text in dark theme, cut at the bottom with no padding (preview of a text/PDF-like file). Previews must follow the theme or sit in a framed, padded page with rounded corners, never a raw white slab touching the pane edges.

Owner report 2026-10-07 on production 0419170fe (dark theme, desktop): "the search bottom bar is back and the top bar is some random blur". Owner decision (2026-10-02, reaffirmed; #499): the action hints (Open / See all / Actions) are SEPARATE small floating glass Pills at the bottom right of the results column, floating OVER the results with the shared ProgressiveBlur behind them. NO bottom band, no joined footer bar, no divider lines, and no divider or band under the search field. Regression: #1123/#1137 (commit 5bbcc7860, 2026-10-05) moved the Pills into a footer row that is a flex sibling after the result scroller (`.sw-action-pills`), which paints a visible band with a top edge under the results; it also added a top-edge progressive blur under the group heading, so the sticky "RECENT" heading shows as a lighter band and the first row under it is a heavy blur smear. Also seen: a document preview in the right pane rendered as an opaque white block with black text in dark theme, cut at the bottom with no padding (preview of a text/PDF-like file). Previews must follow the theme or sit in a framed, padded page with rounded corners, never a raw white slab touching the pane edges.
Author
Owner

Starting #1360 on job/searchbar-1360, based at ed12462cee1edea9e60f4817fba6373d831010bb (job/merge32). I will restore the #499 floating Pills and top-edge behavior, fix the dark document preview, add the requested regression coverage, and capture the required production screenshots.

Starting #1360 on `job/searchbar-1360`, based at `ed12462cee1edea9e60f4817fba6373d831010bb` (job/merge32). I will restore the #499 floating Pills and top-edge behavior, fix the dark document preview, add the requested regression coverage, and capture the required production screenshots.
Author
Owner

Finding from the branch: search-dialog.svelte renders .sw-action-pills as a sibling after .results-scroll-area, and measureCompactPalette() adds its height to the results column. SearchGroupHeading.svelte adds a top ProgressiveBlur; calternal-app.css reveals that blur and a surface when sticky. This matches the reported footer and heading regression. I am changing the controls to overlay the results and keeping group headings non-sticky.

Finding from the branch: `search-dialog.svelte` renders `.sw-action-pills` as a sibling after `.results-scroll-area`, and `measureCompactPalette()` adds its height to the results column. `SearchGroupHeading.svelte` adds a top `ProgressiveBlur`; `calternal-app.css` reveals that blur and a surface when sticky. This matches the reported footer and heading regression. I am changing the controls to overlay the results and keeping group headings non-sticky.
Author
Owner

Progress on #1360: the restored Search layout now anchors its separate action Pills over the results column and reserves one control height plus one standard gap in both scroll padding and content padding. SearchGroupHeading now stays in normal flow without a top blur or fill. I am replacing the former footer/sticky expectations in the real-server Playwright checks and adding the requested 1440/820/390 light/dark captures; long-list rows are created through the test server API and are not shipped UI data.

Progress on #1360: the restored Search layout now anchors its separate action Pills over the results column and reserves one control height plus one standard gap in both scroll padding and content padding. SearchGroupHeading now stays in normal flow without a top blur or fill. I am replacing the former footer/sticky expectations in the real-server Playwright checks and adding the requested 1440/820/390 light/dark captures; long-list rows are created through the test server API and are not shipped UI data.
Author
Owner

Verification finding: bun run check reported scripts/perf-lint --check as INVALID because the exact layout.observer-purpose record for search-dialog.svelte no longer matches after removing the footer observer target. The token audit also rejected the new literal border-radius: 0 in the plain-text preview. I will replace that literal with the shared --radius-none token and refresh only the moved exact exception; the rule and ratchet remain unchanged.

Verification finding: `bun run check` reported `scripts/perf-lint --check` as INVALID because the exact `layout.observer-purpose` record for `search-dialog.svelte` no longer matches after removing the footer observer target. The token audit also rejected the new literal `border-radius: 0` in the plain-text preview. I will replace that literal with the shared `--radius-none` token and refresh only the moved exact exception; the rule and ratchet remain unchanged.
Author
Owner

Perf-check found that removing .sw-action-pills from the Search ResizeObserver changed the exact #1058 adoption checkpoint. I restored the existing single-group observer and its exact pin; footer sizing remains removed from the palette height calculation. This avoids changing the owner-approved adoption ledger. The focused SearchPreview Vitest file passes: 1 file, 2 tests. I will rerun ordered final gates after the required origin/dev merge.

Perf-check found that removing `.sw-action-pills` from the Search ResizeObserver changed the exact #1058 adoption checkpoint. I restored the existing single-group observer and its exact pin; footer sizing remains removed from the palette height calculation. This avoids changing the owner-approved adoption ledger. The focused SearchPreview Vitest file passes: 1 file, 2 tests. I will rerun ordered final gates after the required origin/dev merge.
Author
Owner

Merged origin/dev once and resolved its conflicts with both sides retained. The Files test now uses the shared abort/join helper while keeping the 1,000-write, four-scan #668 fixture and timeout assertions. The adversarial harness keeps the incoming #1202 cases plus the existing #1223 probes; the feature flag route uses the canonical feature_flag_id field with the same Instance-scoped Admin authority checks. scripts/perf-lint --adopt-7c refreshed exact source hashes; result: perf-lint: PASS; 0 violations; 22543 scoped exceptions. Merge commit: e52f93d18. Files crate clippy/test and the required web gates are still running.

Merged origin/dev once and resolved its conflicts with both sides retained. The Files test now uses the shared abort/join helper while keeping the 1,000-write, four-scan #668 fixture and timeout assertions. The adversarial harness keeps the incoming #1202 cases plus the existing #1223 probes; the feature flag route uses the canonical `feature_flag_id` field with the same Instance-scoped Admin authority checks. `scripts/perf-lint --adopt-7c` refreshed exact source hashes; result: `perf-lint: PASS; 0 violations; 22543 scoped exceptions`. Merge commit: e52f93d18. Files crate clippy/test and the required web gates are still running.
Author
Owner

The production Search review found the action overlay was wider than the results column at 1440 px: the overlay measured about 418 px against a 332 px column, so it extended about 86 px to the left. The selected-row and full-width-paint assertions passed before this bounds assertion failed. I changed fine-pointer content mode to arrange the three shared Pills in two rows and made scroll padding reserve both rows. I am rebuilding and rerunning the focused production review now.

The production Search review found the action overlay was wider than the results column at 1440 px: the overlay measured about 418 px against a 332 px column, so it extended about 86 px to the left. The selected-row and full-width-paint assertions passed before this bounds assertion failed. I changed fine-pointer content mode to arrange the three shared Pills in two rows and made scroll padding reserve both rows. I am rebuilding and rerunning the focused production review now.
Author
Owner

The keyboard-last production check found a fractional edge case after the two-row layout passed its bounds checks: the selected last row ended at y=787 while the first Pill began at y=786.9. The scroller padding matched the measured row heights and gaps, but scrollIntoView rounded the row edge upward by 0.1 px. I added a 1 px rounding guard to both padding values; the focused real-server review will verify it.

The keyboard-last production check found a fractional edge case after the two-row layout passed its bounds checks: the selected last row ended at y=787 while the first Pill began at y=786.9. The scroller padding matched the measured row heights and gaps, but scrollIntoView rounded the row edge upward by 0.1 px. I added a 1 px rounding guard to both padding values; the focused real-server review will verify it.
Author
Owner

Completed — #1360

Restored the #499 Search layout in commit 16f980ebf, then fixed narrow-column Pill wrapping and fractional scroll clearance in 9b683d7f102402f7409344cccaa71769afe9e789.

  • Three independent shared frosted Pill controls float over the lower-right results list. The shared ProgressiveBlur is limited to the Pill area. No footer, full-width band, divider, or top heading blur remains.
  • Fine-pointer content mode uses a two-column Pill grid so all three controls fit within the results column. Touch keeps one row of 44px icon Pills. Scroll padding and content padding reserve the matching one or two rows plus a standard gap and a 1px rounding guard.
  • Group headings stay in normal flow. Document/PDF and Markdown previews use the shared Card; plain text uses the themed pane surface. Other preview types are unchanged.
  • Visible controls reuse Pill, Kbd, ProgressiveBlur, and Card from packages/ui.

UX gaps closed

The first real-server geometry run found a 418px Pill group spilling 86px beyond a 332px results column. The two-column layout keeps every Pill inside the column. Keyboard navigation to the final result then exposed a 0.1px overlap after scrollIntoView; the shared reserve now includes a 1px rounding guard. The tests also verify no wide background spans the results below its scroller and no active row intersects any Pill.

The production Playwright run captured the long list mid-scroll and the final keyboard-selected row at 1440, 820 and 390 px, in light and dark themes, with macOS platform signals. It also captured native 4x Pill and heading crops and a dark Markdown document preview. There are 17 PNGs in artifacts/searchbar-1360/; no screenshot is committed.

Files changed by this job

  • apps/web/src/lib/components/search-dialog.svelte
  • apps/web/src/lib/search/SearchGroupHeading.svelte
  • apps/web/src/lib/search/SearchPreview.svelte
  • apps/web/src/lib/search/SearchPreview.svelte.test.ts
  • apps/web/src/calternal-app.css
  • apps/web/e2e/search.mjs
  • contracts/perf/adoption-1058.json
  • contracts/perf/exceptions.json

Gate output

cd apps/web && bun run build — PASS:

Compressed 914 static variants; saved 21485244 bytes.

cd apps/web && bun run check — PASS:

PASS production dependency licences: 759 locked package releases across apps/web, apps/docs and packages
perf-lint: PASS; 0 violations; 22543 scoped exceptions
svelte-check found 0 errors and 4 warnings in 2 files

The four warnings are existing selector warnings in Mail and Money. The full web test suite passed after the origin/dev merge and before the final CSS/geometry refinement:

 Test Files  291 passed (291)
      Tests  2083 passed (2083)
   Start at  19:13:19
   Duration  1017.65s (environment 27%, transform 27%, import 21%, tests 18%, setup 7%)

After the final component changes, the focused preview test passed:

 Test Files  1 passed (1)
      Tests  2 passed (2)
   Start at  20:46:31
   Duration  13.24s (transform 77%, environment 8%, import 7%, tests 5%, setup 3%)

Production E2E output:

PASS #1360 production screenshots: long list mid-scroll and last row at 1440px/820px/390px in light/dark; dark Markdown preview and native 4x crops captured
CSP REPORTS search: 0 across 3 pages

Rust gates after merge:

cargo fmt --check: PASS (exit 0, no output)
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 36m 00s

The second line is cargo clippy -p calternal-plugin-files --all-targets -- -D warnings (PASS). cargo test -p calternal-plugin-files hit two timeouts under host load (load averages 79.73/77.18/71.19); 263 tests passed:

test result: FAILED. 263 passed; 2 failed; 4 ignored; 0 measured; 0 filtered out; finished in 457.92s
error: test failed, to rerun pass `-p calternal-plugin-files --lib`

The timed-out tests were concurrent_uploads_keep_their_intents_until_patch_finishes (10-second PATCH join timeout) and internal_temp_paths_never_enter_index_during_atomic_write_reconcile_storm (five-minute stress deadline). No test expectations were changed.

Performance

Expected work is the existing result rows plus three shared action controls; there is no new request or search operation. The screenshot fixture has 28 result rows. Fine-pointer content mode lays out two Pill rows; touch uses one icon row.

The existing local bench/search-group-rows.mjs profile measured the grouping hot path. The search-100k palette baseline in docs/perf/baseline.json is p50 100.5ms / p95 218.4ms. Local grouping profile:

  • 20 rows, 2,000 runs: p50 0.001ms / p95 0.009ms; 17.389ms total CPU; RSS 29,360,128 → 43,192,320 bytes.
  • 200 rows, 2,000 runs: p50 0.006ms / p95 0.013ms; 37.507ms total CPU; RSS 44,744,704 → 52,019,200 bytes.
  • 200-row burst, 1,000 runs: p50 0.004ms / p95 0.008ms; 8.797ms total CPU; RSS 52,019,200 → 53,854,208 bytes.

Decisions and remaining gaps

The design specifies three floating Pills but does not specify wrapping at narrow desktop/tablet widths. The two-column fine-pointer layout, single-row touch layout, and 1px rounding guard are the smallest changes that keep every control within the column and the active row clear of them.

No product UX gaps remain from this change. I could not attach the PNGs to this issue: the local fj CLI can post comments, but its stored credential was not accepted by Forgejo's multipart attachment API. Screenshots remain available in the worktree at artifacts/searchbar-1360/.

For the merge round, run cd apps/web && bun run test -- --maxWorkers=2 on the combined branch to recheck the full suite after the final CSS change, and cargo test -p calternal-plugin-files -- --test-threads=4 to distinguish the two load-sensitive timeouts from regressions.

## Completed — #1360 Restored the #499 Search layout in commit `16f980ebf`, then fixed narrow-column Pill wrapping and fractional scroll clearance in `9b683d7f102402f7409344cccaa71769afe9e789`. - Three independent shared frosted `Pill` controls float over the lower-right results list. The shared `ProgressiveBlur` is limited to the Pill area. No footer, full-width band, divider, or top heading blur remains. - Fine-pointer content mode uses a two-column Pill grid so all three controls fit within the results column. Touch keeps one row of 44px icon Pills. Scroll padding and content padding reserve the matching one or two rows plus a standard gap and a 1px rounding guard. - Group headings stay in normal flow. Document/PDF and Markdown previews use the shared `Card`; plain text uses the themed pane surface. Other preview types are unchanged. - Visible controls reuse `Pill`, `Kbd`, `ProgressiveBlur`, and `Card` from `packages/ui`. ### UX gaps closed The first real-server geometry run found a 418px Pill group spilling 86px beyond a 332px results column. The two-column layout keeps every Pill inside the column. Keyboard navigation to the final result then exposed a 0.1px overlap after `scrollIntoView`; the shared reserve now includes a 1px rounding guard. The tests also verify no wide background spans the results below its scroller and no active row intersects any Pill. The production Playwright run captured the long list mid-scroll and the final keyboard-selected row at 1440, 820 and 390 px, in light and dark themes, with macOS platform signals. It also captured native 4x Pill and heading crops and a dark Markdown document preview. There are 17 PNGs in `artifacts/searchbar-1360/`; no screenshot is committed. ### Files changed by this job - `apps/web/src/lib/components/search-dialog.svelte` - `apps/web/src/lib/search/SearchGroupHeading.svelte` - `apps/web/src/lib/search/SearchPreview.svelte` - `apps/web/src/lib/search/SearchPreview.svelte.test.ts` - `apps/web/src/calternal-app.css` - `apps/web/e2e/search.mjs` - `contracts/perf/adoption-1058.json` - `contracts/perf/exceptions.json` ### Gate output `cd apps/web && bun run build` — PASS: ```text Compressed 914 static variants; saved 21485244 bytes. ``` `cd apps/web && bun run check` — PASS: ```text PASS production dependency licences: 759 locked package releases across apps/web, apps/docs and packages perf-lint: PASS; 0 violations; 22543 scoped exceptions svelte-check found 0 errors and 4 warnings in 2 files ``` The four warnings are existing selector warnings in Mail and Money. The full web test suite passed after the `origin/dev` merge and before the final CSS/geometry refinement: ```text Test Files 291 passed (291) Tests 2083 passed (2083) Start at 19:13:19 Duration 1017.65s (environment 27%, transform 27%, import 21%, tests 18%, setup 7%) ``` After the final component changes, the focused preview test passed: ```text Test Files 1 passed (1) Tests 2 passed (2) Start at 20:46:31 Duration 13.24s (transform 77%, environment 8%, import 7%, tests 5%, setup 3%) ``` Production E2E output: ```text PASS #1360 production screenshots: long list mid-scroll and last row at 1440px/820px/390px in light/dark; dark Markdown preview and native 4x crops captured CSP REPORTS search: 0 across 3 pages ``` Rust gates after merge: ```text cargo fmt --check: PASS (exit 0, no output) Finished `dev` profile [unoptimized + debuginfo] target(s) in 36m 00s ``` The second line is `cargo clippy -p calternal-plugin-files --all-targets -- -D warnings` (PASS). `cargo test -p calternal-plugin-files` hit two timeouts under host load (load averages 79.73/77.18/71.19); 263 tests passed: ```text test result: FAILED. 263 passed; 2 failed; 4 ignored; 0 measured; 0 filtered out; finished in 457.92s error: test failed, to rerun pass `-p calternal-plugin-files --lib` ``` The timed-out tests were `concurrent_uploads_keep_their_intents_until_patch_finishes` (10-second PATCH join timeout) and `internal_temp_paths_never_enter_index_during_atomic_write_reconcile_storm` (five-minute stress deadline). No test expectations were changed. ### Performance Expected work is the existing result rows plus three shared action controls; there is no new request or search operation. The screenshot fixture has 28 result rows. Fine-pointer content mode lays out two Pill rows; touch uses one icon row. The existing local `bench/search-group-rows.mjs` profile measured the grouping hot path. The `search-100k` palette baseline in `docs/perf/baseline.json` is p50 100.5ms / p95 218.4ms. Local grouping profile: - 20 rows, 2,000 runs: p50 0.001ms / p95 0.009ms; 17.389ms total CPU; RSS 29,360,128 → 43,192,320 bytes. - 200 rows, 2,000 runs: p50 0.006ms / p95 0.013ms; 37.507ms total CPU; RSS 44,744,704 → 52,019,200 bytes. - 200-row burst, 1,000 runs: p50 0.004ms / p95 0.008ms; 8.797ms total CPU; RSS 52,019,200 → 53,854,208 bytes. ### Decisions and remaining gaps The design specifies three floating Pills but does not specify wrapping at narrow desktop/tablet widths. The two-column fine-pointer layout, single-row touch layout, and 1px rounding guard are the smallest changes that keep every control within the column and the active row clear of them. No product UX gaps remain from this change. I could not attach the PNGs to this issue: the local `fj` CLI can post comments, but its stored credential was not accepted by Forgejo's multipart attachment API. Screenshots remain available in the worktree at `artifacts/searchbar-1360/`. For the merge round, run `cd apps/web && bun run test -- --maxWorkers=2` on the combined branch to recheck the full suite after the final CSS change, and `cargo test -p calternal-plugin-files -- --test-threads=4` to distinguish the two load-sensitive timeouts from regressions.
Author
Owner

Continuing #1360 in job/searchbar-1360.

Base: 0419170fe456b58614befcb12d9c9d255118f1c0
Starting HEAD: 9b683d7f102402f7409344cccaa71769afe9e789

I am fixing the shared ProgressiveBlur edge/fade and keeping the three action Pills in one right-aligned row when they fit. I will preserve the scroller's bottom space and attach the requested clean captures.

Continuing #1360 in `job/searchbar-1360`. Base: `0419170fe456b58614befcb12d9c9d255118f1c0` Starting HEAD: `9b683d7f102402f7409344cccaa71769afe9e789` I am fixing the shared ProgressiveBlur edge/fade and keeping the three action Pills in one right-aligned row when they fit. I will preserve the scroller's bottom space and attach the requested clean captures.
Author
Owner

Finding from the rejected captures: .results-bottom-blur is a child of .sw-action-pills, so the blur uses the action wrapper's box and exposes its left/top edges over rows (visible in search-1360-mid-1440-noir.png). The wrapper also uses a two-column grid, which leaves the third desktop action on a second row at 1440 px. I am changing the shared blur placement and the row layout while retaining the scroll inset.

Finding from the rejected captures: `.results-bottom-blur` is a child of `.sw-action-pills`, so the blur uses the action wrapper's box and exposes its left/top edges over rows (visible in `search-1360-mid-1440-noir.png`). The wrapper also uses a two-column grid, which leaves the third desktop action on a second row at 1440 px. I am changing the shared blur placement and the row layout while retaining the scroll inset.
Author
Owner

The production e2e reached the document preview check after capturing both themes at all three widths. Its preview query matched the Note title but the returned hit had no snippet (status=200, 2 results). I changed the probe to scrollport, which occurs only in the seeded Note body; the check still requires a snippet and now distinguishes content indexing from title matching.

The production e2e reached the document preview check after capturing both themes at all three widths. Its `preview` query matched the Note title but the returned hit had no snippet (`status=200`, 2 results). I changed the probe to `scrollport`, which occurs only in the seeded Note body; the check still requires a snippet and now distinguishes content indexing from title matching.
Author
Owner

The body-only scrollport probe with semantic=true returned 29 results and a snippet in one production run, then 0 results in the next run. I am pinning this fixture check to semantic=false so it verifies the deterministic keyword body index and snippet; the screenshot path still exercises the UI's normal hybrid search.

The body-only `scrollport` probe with `semantic=true` returned 29 results and a snippet in one production run, then 0 results in the next run. I am pinning this fixture check to `semantic=false` so it verifies the deterministic keyword body index and snippet; the screenshot path still exercises the UI's normal hybrid search.
Author
Owner

The final production e2e retry passed the keyword-only body snippet check (status=200, one Note hit with a snippet). In the UI preview step, Playwright found the Searchbar 1360 preview row and then saw it detach during hover while hybrid results were still updating. I am using the existing fillSearchAndWait helper before hovering so the preview capture acts on the completed Search response.

The final production e2e retry passed the keyword-only body snippet check (`status=200`, one Note hit with a snippet). In the UI preview step, Playwright found the `Searchbar 1360 preview` row and then saw it detach during hover while hybrid results were still updating. I am using the existing `fillSearchAndWait` helper before hovering so the preview capture acts on the completed Search response.
Author
Owner

#1360 complete

Branch: job/searchbar-1360
Head SHA: 06a5d6786a

Built

  • Moved the shared ProgressiveBlur to a full-width sibling behind the floating action Pills. Its top edge fades across the results column, with no Pill-sized side edge.
  • Kept Open, Show fewer and Actions as three separate shared Pills. They stay on one right-aligned row when their combined width fits and wrap right-aligned when it does not.
  • Kept the last result clear of the Pills. The existing results observer updates the scroll reserve from the rendered row count; it measures one control and the group, not each result.
  • Added clean-capture checks that dismiss only the expected stale-build notice through Escape and reject any remaining visible toast.

UX gaps closed

  • Covered pointer and shortcut focus with real results on screen; both captures have no Search input ring.
  • Captured mid-scroll and last-row states at 1440, 820 and 390 px in mono light and noir dark, with macOS platform emulation.
  • Added 4x captures of both Pill areas and the existing dark Markdown preview.

UX gaps left: none found in this #1360 slice.

Files

  • apps/web/src/lib/components/search-dialog.svelte
  • apps/web/e2e/search.mjs
  • contracts/perf/adoption-1058.json
  • contracts/perf/exceptions.json

Gates

bun run check

perf-lint: PASS; 0 violations; 22543 scoped exceptions
svelte-check found 0 errors and 4 warnings in 2 files

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

Test Files 2 passed (2)
Tests 12 passed (12)
Start at 22:16:17
Duration 19.62s (transform 80%, environment 9%, import 7%, setup 3%, tests 1%)

Transform |component| transforming modules took 30.82s · 80% 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

#1360 production e2e

Search preview API probe {"status":200,"count":1,"matches":[{"kind":"note","snippet":true}]}
PASS #1360 production screenshots: long list mid-scroll and last row at 1440px/820px/390px in light/dark; dark Markdown preview and native 4x crops captured
CSP REPORTS search: 0 across 3 pages

cargo clean: Removed 1 file, 356B total. No Rust code changed, so Rust gates were not run. apps/web/build and apps/web/.svelte-kit/output were removed after verification.

Decisions not specified in DESIGN.md

  • Used the shared ProgressiveBlur bottom edge over the full results column. It uses the allowed top-only fade fallback so no side edge can show at the Pills.
  • Used the existing bounded ResizeObserver to keep the scroll reserve in sync with responsive flex wrapping. The added work is constant per observer notification and does not scan result rows.
  • The fixture proves body indexing with the keyword-only scrollport query (semantic=false), which is present only in the Note body. The screenshot path still exercises normal hybrid Search.

Review captures

Focus states:

Mid-scroll:

Last row:

4x Pill-area crops: mono https://git.kayg.org/attachments/6a18017d-2d90-4f24-98ec-552cf688c9ac · noir https://git.kayg.org/attachments/0450692c-5d00-479e-af0b-be7b77524e4c

Dark Markdown preview, 1440: https://git.kayg.org/attachments/a575414b-53bd-4a97-bff3-0255a2cdcd9b

Known gaps: the full web test suite and unrelated full e2e suite remain for the merge round under the verification policy. The visual artifact review remains with the orchestrator.

## #1360 complete Branch: job/searchbar-1360 Head SHA: 06a5d6786a45629e53752c21706043482b7bdef0 ### Built - Moved the shared ProgressiveBlur to a full-width sibling behind the floating action Pills. Its top edge fades across the results column, with no Pill-sized side edge. - Kept Open, Show fewer and Actions as three separate shared Pills. They stay on one right-aligned row when their combined width fits and wrap right-aligned when it does not. - Kept the last result clear of the Pills. The existing results observer updates the scroll reserve from the rendered row count; it measures one control and the group, not each result. - Added clean-capture checks that dismiss only the expected stale-build notice through Escape and reject any remaining visible toast. ### UX gaps closed - Covered pointer and shortcut focus with real results on screen; both captures have no Search input ring. - Captured mid-scroll and last-row states at 1440, 820 and 390 px in mono light and noir dark, with macOS platform emulation. - Added 4x captures of both Pill areas and the existing dark Markdown preview. UX gaps left: none found in this #1360 slice. ### Files - apps/web/src/lib/components/search-dialog.svelte - apps/web/e2e/search.mjs - contracts/perf/adoption-1058.json - contracts/perf/exceptions.json ### Gates bun run check > perf-lint: PASS; 0 violations; 22543 scoped exceptions > svelte-check found 0 errors and 4 warnings in 2 files bunx vitest run src/lib/search/SearchField.svelte.test.ts src/lib/search/SearchResultRow.svelte.test.ts --maxWorkers=2 > Test Files 2 passed (2) > Tests 12 passed (12) > Start at 22:16:17 > Duration 19.62s (transform 80%, environment 9%, import 7%, setup 3%, tests 1%) > Transform |component| transforming modules took 30.82s · 80% 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 #1360 production e2e > Search preview API probe {"status":200,"count":1,"matches":[{"kind":"note","snippet":true}]} > PASS #1360 production screenshots: long list mid-scroll and last row at 1440px/820px/390px in light/dark; dark Markdown preview and native 4x crops captured > CSP REPORTS search: 0 across 3 pages cargo clean: Removed 1 file, 356B total. No Rust code changed, so Rust gates were not run. apps/web/build and apps/web/.svelte-kit/output were removed after verification. ### Decisions not specified in DESIGN.md - Used the shared ProgressiveBlur bottom edge over the full results column. It uses the allowed top-only fade fallback so no side edge can show at the Pills. - Used the existing bounded ResizeObserver to keep the scroll reserve in sync with responsive flex wrapping. The added work is constant per observer notification and does not scan result rows. - The fixture proves body indexing with the keyword-only scrollport query (semantic=false), which is present only in the Note body. The screenshot path still exercises normal hybrid Search. ### Review captures Focus states: - Shortcut open, 1440 mono: https://git.kayg.org/attachments/cc6fd1e6-667a-4d93-b64d-007526c8a840 - Pointer click, 1440 mono: https://git.kayg.org/attachments/80122a6f-6e7d-46f7-b896-c545adedad69 Mid-scroll: - 1440: mono https://git.kayg.org/attachments/9e8a0186-ca37-419c-8979-8c81845af8a2 · noir https://git.kayg.org/attachments/e81c6184-7fea-40f1-a92a-3f21154960a9 - 820: mono https://git.kayg.org/attachments/db38a00b-5383-47b4-be82-8986bab85b27 · noir https://git.kayg.org/attachments/bbcedb3c-a2e0-4ae1-bdc3-9f8e731e3b41 - 390: mono https://git.kayg.org/attachments/445a6fb0-e72a-481d-9673-693d482a149b · noir https://git.kayg.org/attachments/65056235-0ed4-4f81-9437-0c5c338d55e4 Last row: - 1440: mono https://git.kayg.org/attachments/76a95a02-fb16-446a-8d79-69ecc5250eb2 · noir https://git.kayg.org/attachments/53ff3512-08cc-47ce-8617-922c740d4270 - 820: mono https://git.kayg.org/attachments/f73a4a6a-2fe1-49a0-b3b7-87e0923d3cf4 · noir https://git.kayg.org/attachments/61000be3-4f1f-4a2d-b85c-03c3d177ba86 - 390: mono https://git.kayg.org/attachments/bc8702f9-97a9-47e1-9270-b6826c40bc74 · noir https://git.kayg.org/attachments/3ee48aa0-c2d4-4bda-b4c1-1e680c294bca 4x Pill-area crops: mono https://git.kayg.org/attachments/6a18017d-2d90-4f24-98ec-552cf688c9ac · noir https://git.kayg.org/attachments/0450692c-5d00-479e-af0b-be7b77524e4c Dark Markdown preview, 1440: https://git.kayg.org/attachments/a575414b-53bd-4a97-bff3-0255a2cdcd9b Known gaps: the full web test suite and unrelated full e2e suite remain for the merge round under the verification policy. The visual artifact review remains with the orchestrator.
Author
Owner

Deployed to calternal.cloud in merge round 34 (d395b6e25), 2026-10-08 05:03 IST. Backup: /srv/calternal/backup-pre-m34-20261008-0132. Production healthy after 36 s; served build matches.

Deployed to calternal.cloud in merge round 34 (d395b6e25), 2026-10-08 05:03 IST. Backup: /srv/calternal/backup-pre-m34-20261008-0132. Production healthy after 36 s; served build matches.
kayg closed this issue 2026-10-07 23:54:44 +00:00
Commenting is not possible because the repository is archived.
No labels
No milestone
No project
No assignees
1 participant
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-v0#1360
No description provided.