@@ -66,21 +66,28 @@ fn status_in_cloud_size(total: f32) -> f32 {
6666 total * STATUS_IN_CLOUD_RATIO
6767}
6868
69+ /// Default overhang of the overlay's BR past the circle's BR edge (toward the box's
70+ /// BR), as a fraction of `total_size`. Baked into `corner_overlay_offset` so most
71+ /// surfaces can just pass `0.0` for their `overlay_extra_overhang_ratio`.
72+ const DEFAULT_OVERLAY_OVERHANG_PAST_CIRCLE_EDGE : f32 = 0.19 ;
73+
6974/// Returns the pixel offset applied to the overlay's `BottomRight → BottomRight`
7075/// anchor.
7176/// The offset is measured from the bounding box's BR corner, so the returned value is
7277/// negative whenever the overlay sits up-and-left of the box's BR (which is the only
7378/// case we render).
7479///
75- /// `overlay_offset_from_circle_edge_ratio` is a signed fraction of `total` that
76- /// positions the overlay's BR relative to the **circle's** BR corner:
77- /// * `0.0` — overlay BR sits exactly on the circle's BR edge.
78- /// * Positive — overlay BR is pulled further into the circle (toward the center).
79- /// * Negative — overlay BR sits past the circle's BR edge, toward the box's BR.
80- /// `-(1.0 - CIRCLE_RATIO)` places it exactly on the box's BR corner, which is the
81- /// Figma-natural position where the badge appears to hang off the circle's BR.
82- fn corner_overlay_offset ( total : f32 , overlay_offset_from_circle_edge_ratio : f32 ) -> f32 {
83- -( 1.0 - CIRCLE_RATIO ) * total - overlay_offset_from_circle_edge_ratio * total
80+ /// `overlay_extra_overhang_ratio` is a signed fraction of `total` added to
81+ /// `DEFAULT_OVERLAY_OVERHANG_PAST_CIRCLE_EDGE`:
82+ /// * `0.0` — overlay BR sits `DEFAULT_OVERLAY_OVERHANG_PAST_CIRCLE_EDGE * total` past
83+ /// the circle's BR (the position most surfaces want).
84+ /// * Positive — overlay BR pushed further toward the box's BR. A value of
85+ /// `1 - CIRCLE_RATIO - DEFAULT_OVERLAY_OVERHANG_PAST_CIRCLE_EDGE` (= 0.05) lands
86+ /// exactly on the box's BR — the Figma-natural overhang.
87+ /// * Negative — overlay BR pulled inward toward the circle's center.
88+ fn corner_overlay_offset ( total : f32 , overlay_extra_overhang_ratio : f32 ) -> f32 {
89+ let total_overhang = DEFAULT_OVERLAY_OVERHANG_PAST_CIRCLE_EDGE + overlay_extra_overhang_ratio;
90+ -( ( 1.0 - CIRCLE_RATIO ) - total_overhang) * total
8491}
8592
8693/// What to render inside the circle.
@@ -109,18 +116,17 @@ pub(crate) enum IconWithStatusVariant {
109116/// sub-components (brand circle, status badge, cloud lobe) are derived proportionally,
110117/// so callers only need to pick the size they want.
111118///
112- /// `overlay_offset_from_circle_edge_ratio` is a signed fraction of `total_size` that
113- /// positions the badge / cloud overlay's BR relative to the **circle's** BR corner:
114- /// `0.0` anchors the overlay BR right on the circle's BR edge, positive values pull it
115- /// further toward the circle's center, and negative values push it past the circle's
116- /// BR toward the bounding box's BR (where the Figma-natural overhang lives).
119+ /// `overlay_extra_overhang_ratio` is a signed fraction of `total_size` added to the
120+ /// default overlay overhang past the circle's BR edge. Most surfaces pass `0.0` to
121+ /// get the default position; positive values push the overlay further toward the box's
122+ /// BR (more overhang) and negative values pull it inward toward the circle's center.
117123///
118124/// When `is_ambient` is set on an agent variant, the status badge is replaced by a
119125/// white cloud containing the status icon.
120126pub ( crate ) fn render_icon_with_status (
121127 variant : IconWithStatusVariant ,
122128 total_size : f32 ,
123- overlay_offset_from_circle_edge_ratio : f32 ,
129+ overlay_extra_overhang_ratio : f32 ,
124130 theme : & WarpTheme ,
125131 badge_ring_background : WarpThemeFill ,
126132) -> Box < dyn Element > {
@@ -163,7 +169,7 @@ pub(crate) fn render_icon_with_status(
163169 status. as_ref ( ) ,
164170 is_ambient,
165171 total_size,
166- overlay_offset_from_circle_edge_ratio ,
172+ overlay_extra_overhang_ratio ,
167173 theme,
168174 badge_ring_background,
169175 )
@@ -190,7 +196,7 @@ pub(crate) fn render_icon_with_status(
190196 status. as_ref ( ) ,
191197 is_ambient,
192198 total_size,
193- overlay_offset_from_circle_edge_ratio ,
199+ overlay_extra_overhang_ratio ,
194200 theme,
195201 badge_ring_background,
196202 )
@@ -228,7 +234,7 @@ fn attach_status_overlay(
228234 status : Option < & ConversationStatus > ,
229235 is_ambient : bool ,
230236 total_size : f32 ,
231- overlay_offset_from_circle_edge_ratio : f32 ,
237+ overlay_extra_overhang_ratio : f32 ,
232238 theme : & WarpTheme ,
233239 badge_ring_background : WarpThemeFill ,
234240) -> Box < dyn Element > {
@@ -237,15 +243,15 @@ fn attach_status_overlay(
237243 circle,
238244 status,
239245 total_size,
240- overlay_offset_from_circle_edge_ratio ,
246+ overlay_extra_overhang_ratio ,
241247 theme,
242248 )
243249 } else {
244250 render_with_optional_status_badge (
245251 circle,
246252 status,
247253 total_size,
248- overlay_offset_from_circle_edge_ratio ,
254+ overlay_extra_overhang_ratio ,
249255 theme,
250256 badge_ring_background,
251257 )
@@ -258,7 +264,7 @@ fn render_with_cloud_status_badge(
258264 circle : Box < dyn Element > ,
259265 status : Option < & ConversationStatus > ,
260266 total_size : f32 ,
261- overlay_offset_from_circle_edge_ratio : f32 ,
267+ overlay_extra_overhang_ratio : f32 ,
262268 theme : & WarpTheme ,
263269) -> Box < dyn Element > {
264270 let cloud_diameter = cloud_icon_size ( total_size) ;
@@ -299,7 +305,7 @@ fn render_with_cloud_status_badge(
299305 None => cloud,
300306 } ;
301307
302- let cloud_offset = corner_overlay_offset ( total_size, overlay_offset_from_circle_edge_ratio ) ;
308+ let cloud_offset = corner_overlay_offset ( total_size, overlay_extra_overhang_ratio ) ;
303309 let mut stack = Stack :: new ( ) . with_child (
304310 ConstrainedBox :: new ( circle)
305311 . with_width ( total_size)
@@ -326,7 +332,7 @@ fn render_with_optional_status_badge(
326332 circle : Box < dyn Element > ,
327333 status : Option < & ConversationStatus > ,
328334 total_size : f32 ,
329- overlay_offset_from_circle_edge_ratio : f32 ,
335+ overlay_extra_overhang_ratio : f32 ,
330336 theme : & WarpTheme ,
331337 badge_ring_background : WarpThemeFill ,
332338) -> Box < dyn Element > {
@@ -351,8 +357,7 @@ fn render_with_optional_status_badge(
351357 . with_corner_radius ( CornerRadius :: with_all ( Radius :: Percentage ( 50. ) ) )
352358 . finish ( ) ;
353359
354- let badge_corner_offset =
355- corner_overlay_offset ( total_size, overlay_offset_from_circle_edge_ratio) ;
360+ let badge_corner_offset = corner_overlay_offset ( total_size, overlay_extra_overhang_ratio) ;
356361 let mut stack = Stack :: new ( ) . with_child (
357362 ConstrainedBox :: new ( circle)
358363 . with_width ( total_size)
0 commit comments