Skip to content

[2.x] fix: various styling fixes#4480

Merged
imorland merged 4 commits into
2.xfrom
im/styling-fixes
Mar 21, 2026
Merged

[2.x] fix: various styling fixes#4480
imorland merged 4 commits into
2.xfrom
im/styling-fixes

Conversation

@imorland

Copy link
Copy Markdown
Member

Summary

  • Mobile post padding: Remove asymmetric right padding on .Post for mobile. The base style has padding-right: 20px but padding-left: 0 (the avatar column provides left balance on desktop). On mobile with no avatar column, this caused visual asymmetry. The container already provides 15px symmetrically, so the extra post-level right padding is zeroed out.
  • Unread notification contrast: Add a primary-colour left border (box-shadow: inset 3px 0) to unread HeaderListItems for clear visual distinction in dark mode, where background contrast alone was insufficient. Also use --control-bg-shaded on hover so hovered items are distinct from the unread background.
  • Stale unread notification state: Fix PATCH /api/notifications/:id returning isRead: false after marking as read. The isRead set handler dispatched a ReadNotification command that updated the database but left the in-memory Notification model with read_at = null. The serialised response therefore returned isRead: false, causing the JS store to overwrite the optimistic local update. Calling $notification->refresh() reloads the model from the now-updated DB before serialisation.
  • Notification bubble overlapping avatar at 3+ digits: For 3+ digit unread counts, anchor the bubble to the right side of the icon button (right: 2px) so it grows leftward over the bell icon rather than rightward into the adjacent avatar. Uses a data-digits attribute on the bubble span, targeted by CSS attribute selectors at @tablet-up. Also prevents the unread count going negative on optimistic decrement, and guards the bubble against non-positive values.
  • Primary button text colour (YIQ vs luma): The previous luma-based fix ([2.x] fix: use luma-based text colour for primary buttons to ensure contrast #4451) used LESS luma() (W3C relative luminance) which disagrees with the JS isDark utility's YIQ formula for warm/mid-range colours — e.g. orange (#FF8C00) has luma ~40% (white text) but YIQ ~158 (dark text, correct). Switch to the same YIQ formula used by isDark: r×299 + g×587 + b×114, threshold 128. The original fix for dark primaries (#064635) is preserved.

Test plan

  • Mobile: Post content has equal spacing on left and right edges
  • Notifications dropdown: unread items show a left accent border; hover is visually distinct from unread background
  • Click a notification, navigate to its destination, reopen the dropdown — the clicked notification shows as read
  • With 3+ digit unread count, the bubble does not overlap the user avatar
  • Set primary colour to an orange/warm mid-range value — primary buttons should show dark text
  • Set primary colour to a dark value (e.g. #064635) — primary buttons should show white text

On mobile the avatar column is hidden, so the base Post padding
(20px right, 0 left) creates visual asymmetry. The container already
provides 15px on both sides, so zeroing the right padding here gives
symmetric spacing.
@imorland imorland requested a review from a team as a code owner March 21, 2026 21:28
@imorland imorland added this to the 2.0.0-beta.8 milestone Mar 21, 2026
@imorland imorland changed the title fix: various styling fixes [2.x] fix: various styling fixes Mar 21, 2026
- Add primary-colour left border to unread HeaderListItems for clear
  visual distinction in dark mode, where background contrast alone
  was insufficient
- Use --control-bg-shaded on hover so hovered items are visually
  distinct from the unread background
- Fix PATCH response returning isRead:false: the isRead set handler
  dispatched a ReadNotification command that updated the DB but left
  the in-memory Notification model with read_at=null; the serialised
  response therefore returned isRead:false, causing store.pushPayload
  to overwrite the local optimistic update; calling refresh() reloads
  the model from the now-updated DB before serialisation
- Add data-digits attribute to bubble span for CSS targeting
- Anchor 3+ digit bubbles to the right edge of the button so they grow leftward
- Prevent notification unread count from going negative
luma() uses W3C relative luminance (gamma-corrected) which disagrees
with the JS isDark utility's YIQ formula for warm/mid-range colours.
For example, orange (#FF8C00) has luma ~40% (below the 50% threshold,
giving white text) but YIQ ~158 (above 128, giving dark text — correct).

Switch to the same YIQ formula: r*299 + g*587 + b*114, threshold 128.
Pre-computed into a variable to avoid nested parentheses in if().

The original fix for dark primaries (#064635) is preserved — YIQ 49
is well below the threshold so white text is still used.
@imorland imorland merged commit df17ad4 into 2.x Mar 21, 2026
25 checks passed
@imorland imorland deleted the im/styling-fixes branch March 21, 2026 21:45
imorland added a commit that referenced this pull request Mar 21, 2026
imorland added a commit that referenced this pull request Mar 21, 2026
* prep for beta.8

* chore: update changelog for beta.8 (#4480, #4481)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant