ux-fixes: lock alignment, caption band, wrapping, tap targets, VoiceOver, theme sweep (#1366)

* Fix lock glyph alignment, privacy-caption band, and empty-state wrapping

- Message-row locks: align to first text baseline instead of a hardcoded
  top padding that left the lock ~4pt below the line's visual center
- Header/caption locks: 1pt optical lift (lock.fill ink is bottom-heavy;
  geometric centering reads low); seal badge stays untouched
- DM privacy caption: sit on the themed surface like the rest of the
  bottom chrome instead of painting its own orange band
- Empty-state lines: non-breaking spaces so the closing * can't orphan
  and 'bitchat/ for help' can't break right after the slash

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Unify sheet close buttons, widen tiny tap targets, handle long nicknames

- New SheetCloseButton component: one glyph size/weight (13 semibold),
  32pt visual box, 44pt hit target; adopted by all 7 sheets (sizes had
  drifted across 12/13/14pt, two had no frame at all)
- Favorite star buttons get real tap targets (peer list + DM header)
- DM header nickname: single line with middle truncation instead of
  wrapping into the fixed-height header; peer-list names truncate tail
- Geohash people rows: leading glyph 12 -> 10 to match mesh rows
- Sidebar lock glyphs get the same optical lift as the DM header

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Make channel switching, voice notes, and header actions work under VoiceOver

- Channel rows in the location sheet are now single activatable buttons
  (label + selected trait + switch hint) with the bookmark toggle
  mirrored as a named accessibility action; bookmark buttons labeled
- Voice-note mic: press-and-hold drag gestures can't be activated by
  VoiceOver, so the default accessibility action now toggles
  start/stop-and-send; announces 'recording' state; localized labels
- Attachment button: camera (long-press) path exposed as a named
  action; labels localized instead of hardcoded English
- People-count button announces connected vs no-one-reachable (was
  color-only); verification QR button gains a spoken name (.help is
  only a hint on iOS); bitchat/ logo exposes its tap-for-app-info as a
  button (panic triple-tap stays undiscoverable on purpose)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Theme-correctness sweep: palette colors everywhere, AX-size header growth

- Fingerprint/verification sheet cards: palette-tinted boxes instead of
  fixed gray bands that ignored matrix green and occluded glass
- Voice-note card: palette background (translucent) instead of opaque
  white/black; waveform + payment chips + image placeholder follow suit
- .secondary/.primary/Color.blue swapped for palette.secondary/primary/
  accentBlue across location sheets, people sheets, message captions,
  and the header count (system gray read wrong under matrix green)
- Autocomplete/command rows: dropped the uniform gray wash that dulled
  the themed overlay panel
- 'tap to reveal' caption follows the theme font instead of hardcoding
  monospaced
- Headers use minHeight so two-line accessibility text sizes grow the
  bar instead of clipping inside it

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Fix main header expanding to fill the screen

The header bar's fixed height was load-bearing: its children fill the
bar with .frame(maxHeight: .infinity) tap targets, so switching to an
open-ended minHeight let the header expand to swallow all available
vertical space, centering the title mid-screen and crushing the
timeline into the composer. Restore the fixed height — headerHeight is
a @ScaledMetric, so it already grows with Dynamic Type. Reproduced and
verified both layouts with an offscreen render harness.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* DM header: floating glass panel instead of muddy orange wash under glass

Orange at 14% over the backdrop gradient reads as a gray-beige band,
not a privacy signature. Under liquid glass the DM header now uses the
same floating chrome panel as the main header; the private signature is
already carried by the orange lock, caption, and composer accents.
Matrix keeps its orange wash over the opaque themed surface, unchanged.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: jack <jackjackbits@users.noreply.github.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
jack
2026-07-06 14:22:38 +02:00
committed by GitHub
co-authored by jack Claude Fable 5
parent 8296630cf3
commit d285c6ad53
20 changed files with 439 additions and 121 deletions
+169 -1
View File
@@ -8572,6 +8572,42 @@
}
}
},
"content.accessibility.app_info_hint" : {
"comment" : "Accessibility hint on the bitchat/ logo explaining a tap opens app info",
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "shows app info"
}
}
}
},
"content.accessibility.attach_photo" : {
"comment" : "Accessibility label for the photo attachment button",
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "attach photo"
}
}
}
},
"content.accessibility.attach_photo_hint" : {
"comment" : "Accessibility hint explaining the attachment button opens the photo library",
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "opens the photo library; use the take photo action for the camera"
}
}
}
},
"content.accessibility.available_nostr" : {
"extractionState" : "manual",
"localizations" : {
@@ -8930,6 +8966,18 @@
}
}
},
"content.accessibility.choose_photo" : {
"comment" : "Accessibility label for the macOS photo picker button",
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "choose photo"
}
}
}
},
"content.accessibility.connected_mesh" : {
"extractionState" : "manual",
"localizations" : {
@@ -9849,6 +9897,30 @@
}
}
},
"content.accessibility.peers_connected" : {
"comment" : "Accessibility value when peers are reachable",
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "connected"
}
}
}
},
"content.accessibility.peers_none" : {
"comment" : "Accessibility value when no peers are reachable",
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "no one reachable"
}
}
}
},
"content.accessibility.people_count" : {
"extractionState" : "manual",
"localizations" : {
@@ -10770,6 +10842,42 @@
}
}
},
"content.accessibility.record_voice_hint" : {
"comment" : "Accessibility hint explaining double-tap toggles voice recording",
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "double-tap to start recording, double-tap again to send"
}
}
}
},
"content.accessibility.record_voice_note" : {
"comment" : "Accessibility label for the voice note button",
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "record voice note"
}
}
}
},
"content.accessibility.recording" : {
"comment" : "Accessibility value announced while a voice note is recording",
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "recording"
}
}
}
},
"content.accessibility.remove_favorite" : {
"extractionState" : "manual",
"localizations" : {
@@ -11486,6 +11594,18 @@
}
}
},
"content.accessibility.take_photo" : {
"comment" : "Accessibility action name for taking a photo with the camera",
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "take photo with camera"
}
}
}
},
"content.accessibility.toggle_bookmark" : {
"extractionState" : "manual",
"localizations" : {
@@ -11844,6 +11964,18 @@
}
}
},
"content.accessibility.verification" : {
"comment" : "Accessibility label for the verification QR button",
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "verify encryption"
}
}
}
},
"content.accessibility.view_fingerprint_hint" : {
"extractionState" : "manual",
"localizations" : {
@@ -17735,7 +17867,7 @@
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "tap the channel name above to switch · tap bitchat/ for help"
"value" : "tap the channel name above to switch · tap bitchat/ for help"
}
}
}
@@ -24292,6 +24424,42 @@
}
}
},
"location_channels.accessibility.add_bookmark" : {
"comment" : "Accessibility action name for bookmarking a channel",
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "bookmark channel"
}
}
}
},
"location_channels.accessibility.remove_bookmark" : {
"comment" : "Accessibility action name for removing a channel bookmark",
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "remove bookmark"
}
}
}
},
"location_channels.accessibility.switch_hint" : {
"comment" : "Accessibility hint on a channel row explaining activation switches to it",
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "switches to this channel"
}
}
}
},
"location_channels.action.open_settings" : {
"extractionState" : "manual",
"localizations" : {