feat(horseshoe): bump top profile and bottom call horseshoe radius to 32px with 12px void gap

This commit is contained in:
heaven 2026-05-11 00:54:58 +03:00
parent 3fed5ff873
commit 4b39046c09
3 changed files with 11 additions and 10 deletions

View file

@ -3,8 +3,8 @@ import { color, toRem } from 'folds';
// Shared with the call-horseshoe surface so both ends of the chat // Shared with the call-horseshoe surface so both ends of the chat
// (top profile rail, bottom call rail) read with identical geometry. // (top profile rail, bottom call rail) read with identical geometry.
export const HORSESHOE_RADIUS_PX = 24; export const HORSESHOE_RADIUS_PX = 32;
export const HORSESHOE_GAP_PX = 8; export const HORSESHOE_GAP_PX = 12;
// Outer container — establishes the positioning context for the // Outer container — establishes the positioning context for the
// absolutely-positioned panel and the under-panel chat column. // absolutely-positioned panel and the under-panel chat column.

View file

@ -4,7 +4,7 @@
// Mobile (≤ 750): the top «horseshoe» rail. The chat header collapses // Mobile (≤ 750): the top «horseshoe» rail. The chat header collapses
// to height 0 while the rail is open so the visible gap between the // to height 0 while the rail is open so the visible gap between the
// rail's rounded bottom and the chat's rounded top is exactly the // rail's rounded bottom and the chat's rounded top is exactly the
// shared `HORSESHOE_GAP` (8px), matching the bottom call horseshoe. // shared `HORSESHOE_GAP_PX`, matching the bottom call horseshoe.
// //
// Tablet + Desktop (> 750): no top horseshoe. The wrapper is a thin // Tablet + Desktop (> 750): no top horseshoe. The wrapper is a thin
// passthrough; the profile renders as a right-side pane via // passthrough; the profile renders as a right-side pane via
@ -54,7 +54,7 @@ type DragState = {
// the chat header (1:1 DM only); slides up to close on drag-up // the chat header (1:1 DM only); slides up to close on drag-up
// anywhere on the panel. While the rail is open the chat header // anywhere on the panel. While the rail is open the chat header
// collapses to height 0 so there's no transparent ~50px void below // collapses to height 0 so there's no transparent ~50px void below
// the rail — the perceived gap matches the call horseshoe's 8px gap. // the rail — the perceived gap matches the call horseshoe's gap.
function MobileProfileHorseshoe({ header, children }: RoomViewProfilePanelProps) { function MobileProfileHorseshoe({ header, children }: RoomViewProfilePanelProps) {
const { t } = useTranslation(); const { t } = useTranslation();
const profileState = useAtomValue(userRoomProfileAtom); const profileState = useAtomValue(userRoomProfileAtom);
@ -231,8 +231,9 @@ function MobileProfileHorseshoe({ header, children }: RoomViewProfilePanelProps)
backgroundColor: expandedPx > 0 ? '#090909' : undefined, backgroundColor: expandedPx > 0 ? '#090909' : undefined,
}; };
// The «two horseshoes» visual (8px gap + 24px bottom/top radii) // The «two horseshoes» visual (HORSESHOE_GAP_PX gap +
// is gated by an emerge curve that stays at 0 for most of the // HORSESHOE_RADIUS_PX bottom/top radii) is gated by an emerge
// curve that stays at 0 for most of the
// open progress and only ramps to 1 in the last 15%. Two reasons: // open progress and only ramps to 1 in the last 15%. Two reasons:
// //
// 1) Drag-down to open — the chat header is still visible under // 1) Drag-down to open — the chat header is still visible under
@ -370,8 +371,8 @@ function MobileProfileHorseshoe({ header, children }: RoomViewProfilePanelProps)
style={{ style={{
// Collapse the chat header to 0 height while the rail is // Collapse the chat header to 0 height while the rail is
// open so the only visible chrome between the rail's // open so the only visible chrome between the rail's
// rounded bottom and the chat's rounded top is the 8px // rounded bottom and the chat's rounded top is the
// gap. CSS-grid's `1fr → 0fr` is animatable, unlike // HORSESHOE_GAP_PX gap. CSS-grid's `1fr → 0fr` is animatable, unlike
// `height: auto`, and avoids needing to measure the // `height: auto`, and avoids needing to measure the
// header's intrinsic height in JS. // header's intrinsic height in JS.
gridTemplateRows: `${1 - expandedFraction}fr`, gridTemplateRows: `${1 - expandedFraction}fr`,

View file

@ -6,8 +6,8 @@ import { toRem } from 'folds';
// call rail is mounted, so the rest of the app keeps its normal page // call rail is mounted, so the rest of the app keeps its normal page
// background. // background.
const SURFACE_GAP_COLOR = '#090909'; const SURFACE_GAP_COLOR = '#090909';
const HORSESHOE_RADIUS = toRem(24); const HORSESHOE_RADIUS = toRem(32);
const HORSESHOE_GAP = toRem(8); const HORSESHOE_GAP = toRem(12);
// Outer flex column hosting app shell + bottom call rail. // Outer flex column hosting app shell + bottom call rail.
// `min-height: 0` is required for nested scroll containers inside // `min-height: 0` is required for nested scroll containers inside