Skip to content

fix(client): align every control in the page-header filter bar - #344

Merged
centralcmd merged 2 commits into
mainfrom
claude/adoring-mendel-xsktok
Oct 22, 2026
Merged

centralcmd merged 2 commits into
mainfrom
claude/adoring-mendel-xsktok

Conversation

@centralcmd

@centralcmd centralcmd commented Oct 22, 2026 •

Copy link
Copy Markdown
Owner

Summary

The page-header filter bars were misaligned on all 17 pages that have one. Measured in a browser:

Control Before (top offset / height) After
Search field 4 px / 40 px (MudBlazor dense margin) 0 / 40
Multiselect 3 px / 42 px (centred by .odc-popmenu's global align-self) 0 / 40
Sort select 0 px / 40 px 0 / 40
Page-size select 4 px / 40 px 0 / 40
Photos toolbar buttons — / 38 px — / 40

Changes (CSS only):

  • .odc-ms-trigger: changed from 42 px to var(--control-h) (DS token, 40 px).
  • .pl-toolbtn: changed from 38 px to var(--control-h).
  • PageHeader.razor.css: inside .ph-filter-bar, .odc-popmenu children are pinned to align-self: flex-start (beating the zero-specificity global center), and the search field's vertical margin is set to 0.

Type of Change

  • Bug fix

Testing Steps

  1. Open /contacts, /photos, /journal, /transactions and open the Search region.
  2. Every control in each row should share the same top and bottom edge.
  3. dotnet test Odyssey.Client.Tests: 3729 passed, 0 failed.

Related Issues

None.

🤖 Generated with Claude Code

https://claude.ai/code/session_014EFrKrHPVW1Y7e1xyUKDRF

Copy link
Copy Markdown
Owner Author

✅ PR was reviewed by Security Agent. No security-relevant changes detected: Approved.


Generated by Claude Code

Copy link
Copy Markdown
Owner Author

✅ PR was reviewed by Accessibility Agent and no issues were found: Approved.

Scope: CSS-only (PageHeader.razor.css, odyssey-components.css). Checks made: focus-visible outline on .odc-ms-trigger is untouched; no DOM order change (align-self is visual only, so tab/reading order is unaffected, 2.4.3 / 1.3.2); target size improves or holds (38px to 40px, 42px to 40px, all above the 24px minimum of 2.5.8; the dense --control-h of 32px defined in app.css is also above it); flex-wrap is retained so reflow at 320px / 400% zoom (1.4.10) is unchanged; no colour, contrast or motion changes.


Generated by Claude Code

Copy link
Copy Markdown
Owner Author

✅ PR was reviewed by Senior Tester Agent and no issues were found.


Generated by Claude Code

Copy link
Copy Markdown
Owner Author

✅ PR was reviewed by Senior Architect Agent and no issues were found: Approved.

Scope: CSS-only (PageHeader.razor.css, odyssey-components.css); no API, DTO, schema, migration or auth surface touched. Verified against the live tree: --control-h is 40px in app.css (the 32px compact override applies only under [data-density='compact'], which nothing in the client sets), the replaced 42px/38px literals now use that token (removing a client-side copy of a design value), and the new .ph-filter-bar > * / > .mud-input-control rules out-specify the zero-specificity :where(.odc-popmenu) { align-self: center } and MudBlazor's dense margin.

Non-blocking note: if data-density="compact" is ever applied, the multiselect trigger and .pl-toolbtn would drop to 32px while MudBlazor fields stay dense 40px; this is already how the other --control-h consumers behave, so not a regression.


Generated by Claude Code

Copy link
Copy Markdown
Owner Author

Senior Frontend Agent review: no blocking issues, 2 nits.

Verified against the tree (PR head 362a5f8):

  • --control-h is 40px at app.css:144 and drops to --control-h-dense (32px) under [data-density='compact'] (app.css:283). Tokenising .odc-ms-trigger and .pl-toolbtn is correct: both now track density like the sibling controls (.odc-dpr, .odc-rpp-trigger, .odc-stepper, the select triggers at ~1443-1530), where the hardcoded 42px/38px could not.
  • The root cause is real. :where(.odc-popmenu) { align-self: center } (odyssey-components.css:809) has zero specificity, so .ph-root ::deep .ph-filter-bar > * overrides it cleanly. The scoped ::deep placement stays in the one owner of the bar contract (#371).
  • .odc-ms-trigger keeps var(--control-border), so ControlContrastTests.A_named_control_boundary_uses_the_control_border is unaffected. The trigger is otherwise only restyled via .quiet and .ods-modal-body, neither of which touches height.
  • CSS only, with no markup or scoped-CSS relocation. No design-system literals are reintroduced, no a11y baseline is touched (focus ring and reduced-motion rules are unchanged), and nothing here affects layout shift or render cost.

Nits (non-blocking):

  1. PageHeader.razor.css:134: .ph-filter-bar > * { align-self: flex-start } duplicates the container's align-items: flex-start. It is needed only to beat the popmenu's align-self: center. Say so in the rule's comment, or target > .odc-popmenu explicitly. As written, a future child that deliberately wants align-self: stretch will be silently overridden.
  2. odyssey-components.css ~838-846: the rewritten "Height is the DS --control-h..." comment sits above the unrelated .odc-field .odc-ms block, not directly above .odc-ms-trigger where it applies. This was already the case before the PR. Moving the comment down beside the rule would help the next reader.

Optional: the alignment contract (every direct child of .ph-filter-bar shares one top and one height) has no regression guard. A small source-lint in Odyssey.Client.Tests, like the existing CSS lints, asserting the .ph-filter-bar > * rule exists and that .odc-ms-trigger and .pl-toolbtn use var(--control-h), would stop the 42px/38px literals from coming back.

I did not run the app, so the before/after measurements in the PR body are taken as reported.

✅ "PR was reviewed by Senior Frontend Agent and no blocking issues were found: Approved (nits above)."


Generated by Claude Code

centralcmd pushed a commit that referenced this pull request Oct 22, 2026
…menu

Review nits on PR #344: target .odc-popmenu, the only child whose
zero-specificity align-self: center needs beating, instead of every
child, and move the height comment onto .odc-ms-trigger.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014EFrKrHPVW1Y7e1xyUKDRF
@centralcmd centralcmd self-assigned this Oct 22, 2026
@centralcmd
centralcmd marked this pull request as ready for review October 22, 2026 20:10
Measured on all 17 pages with a filter bar: the search field sat 4px
down (MudBlazor dense margin), multiselect triggers were 42px and
centred by OdsPopupMenu's global align-self, and the sort select alone
was top-aligned, so one row showed tops at 0/3/4px and heights of
38/40/42px.

All filter-bar controls now use the DS --control-h (40px), the search
field's vertical margin is zeroed inside the bar, and every child is
pinned to flex-start. The photos toolbar buttons move from 38px to
--control-h as well.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014EFrKrHPVW1Y7e1xyUKDRF
…menu

Review nits on PR #344: target .odc-popmenu, the only child whose
zero-specificity align-self: center needs beating, instead of every
child, and move the height comment onto .odc-ms-trigger.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014EFrKrHPVW1Y7e1xyUKDRF
@centralcmd
centralcmd force-pushed the claude/adoring-mendel-xsktok branch from 52b320a to 2b285f4 Compare October 22, 2026 20:24
@centralcmd
centralcmd merged commit 86ca53a into main Oct 22, 2026
8 checks passed
@centralcmd
centralcmd deleted the claude/adoring-mendel-xsktok branch October 22, 2026 20:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants