Standardizes mobile navigation headers: Android uses Home’s shared
Flutter blur; iOS uses native soft edges, with graduated material
retained during large-title collapse and the iOS 26 fallback preserved.
Preserves Home’s upward title motion with a soft boundary and keeps the
avatar crop title visible.
Validation: 4,112 Flutter tests and 111 native tests passed after
merging main. Rendered partial-scroll regression verified on the iOS 27
simulator; removing either review fix fails its regression assertion.
The earlier preview was installed on a physical iPhone with the existing
profile.
---------
Signed-off-by: kenny lopez <klopez4212@gmail.com>
Co-authored-by: Terp <5856f6900e8e0a4e0ea1f4f8d2ee33e4753d2119bc122f94ecafc660b46c0511@buzz.block.builderlab.xyz>
On mobile, the Create agent form previewed emoji and image avatars as
circles. Once the agent was created, its avatar showed as a rounded
square, and other surfaces used yet other radii. None of them matched
the agent squircle desktop uses.
This PR makes `lib/shared/widgets/avatar_shape.dart` the single source
of avatar silhouettes. Agents get desktop's squircle (traced from
buzz-app's `avatar-squircle.svg`), and people keep circles.
`avatarShape(isAgent:)`, `avatarPath()` and `AvatarClip` are the only
ways to get either shape, and the squircle border class is private.
Every agent avatar surface now goes through that bottleneck:
- Create agent form and avatar picker previews (previously circles for
emoji and photo avatars, and unclipped for catalog characters;
`PresetAgentAvatar` now owns the clip)
- The avatar picker's camera cutout (`ImageAvatarCapture` with `isAgent:
true`); profile editing keeps the circle
- Agents grid card portrait (previously a 22pt rounded rect)
- `AvatarImage` (message authors, DM rows, member lists), the profile
sheet, `SmallAvatar`, and the native avatar PNG used by iOS Add members
(previously 30% rounded rects)
- Huddle speaking halo, preparing placeholder, and spotlight frame
- The iOS Add members fallback tile (Swift), shown while an avatar
loads, now draws the same squircle instead of a 30% rounded rect
To catch future drift, `avatar_shape_test.dart` adds a source guard. It
fails when code under `lib/` picks an avatar shape inline from agent
identity (for example `isAgent ? BoxShape.rectangle` or `if (!isAgent)
return ClipOval`), hand-rolls the old 30%/60% agent radius, or uses a
person shape (`ClipOval`, `CircleAvatar`, `BoxShape.circle`) under
`lib/features/agents/`. Against main it flags 8 of the 10 old sites. It
is best effort: the native PNG's inline ternary and the card's RRect
didn't match those patterns and are fixed directly here.
The Create agent form also gets 8pt above **Choose avatar**, so the
button and everything below it move down from the preview, as Kenny
requested.
### Before / after
Captured on the iPhone SE (iOS 27) with a release build against a hosted
Builderlab community, using a throwaway agent with an emoji avatar. In
each pair, before (main) is on the left and after is on the right.
**Create agent form** (also shows the 8pt spacing)

**Avatar picker**

**Agents card**

**Agent profile sheet**

**Message author avatar** (`AvatarImage`)

**DM list row** (`AvatarImage`)

**Add members** (native iOS list, `nativeAvatarImage`)

Not captured on device: `SmallAvatar` (thread reply and search avatars)
and the Huddle halo, placeholder, and spotlight, which need a live agent
thread or huddle. Widget tests cover these.
### Validation
- Device: the before/after captures above. They predate the catalog
preview clip
([355ebca](355ebca27e)),
which only trims the transparent character art at the squircle corners.
The test agent was deleted afterwards.
- Added tests: `avatar_shape_test.dart` pins the squircle geometry to
desktop's mask and runs the source guard. The avatar picker journey now
checks that the catalog preview, emoji preview, and camera cutout use
the agent shape. Existing `AvatarImage` and channel-detail
Huddle/thread-avatar assertions were updated to the new shapes.
- Full mobile format, analyze, and test suite pass locally. The iOS
release build compiles with the Swift change.
- The device build predates a merge of main that brought in
[#8773](https://github.com/block/buzz/pull/8773). That merge touched the
card, create page, and profile sheet without changing any avatar shapes.
Human pre-readiness app testing is not applicable under Tom's standing
exception for Buzz mobile changes. An independent agent review ran, and
its optional findings were addressed in 00b1ec6.
buzz-review-completed
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Signed-off-by: Tom Brow <tomb@squareup.com>
Co-authored-by: Tom Brow <tomb@squareup.com>
Co-authored-by: studio <dc2fc481343672df31a689840c09299972e704dac592e0da6f18486646a7ee3e@buzz.block.builderlab.xyz>
Co-authored-by: studio <dc2fc481343672df31a689840c09299972e704dac592e0da6f18486646a7ee3e@localhost>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
## Summary
Use native iOS sheets for channel editing and Add Members, with profile
avatars, matching search, and destructive removal dialogs. Canvas
content becomes a tappable preview with Add/Remove actions.
Fix the Settings availability menu and clipped copy confirmation. Align
channel action messages with chat styling and keep agent identities
distinguishable across selection, attribution, and profile surfaces.
### Related issue
No duplicate found in the existing mobile Settings/channel issues and
PRs.
### Testing
- Flutter analysis, formatting, file-size checks, focused collision
regressions, and the full mobile test suite passed.
- Production UIKit picker simulator check passed: distinct
visible/accessibility labels, avatar updates, selected rows, and pubkey
callbacks. Wired into Mobile Swift CI.
- Original UI was built and tested on the physical iPhone with author
confirmation; profile/community data preserved.
- Review fixes await renewed author device confirmation before restoring
`buzz-review-completed` and ready-for-review status.
---------
Signed-off-by: kenny lopez <klopez4212@gmail.com>