From a5fe3583133b965bc9b8a0098c6f473171180d8b Mon Sep 17 00:00:00 2001 From: Jared Vititoe Date: Sun, 14 Jun 2026 14:49:42 -0400 Subject: [PATCH] fix: rewrite decoration grid to contain images within cells MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The INSET overflow approach (position:absolute images extending beyond 52×52 buttons) was fundamentally broken: absolutely positioned children don't contribute to flex row height, so rowGap controlled button-to-button spacing but image pixels still painted into the gap, causing visual overlap regardless of how large rowGap was set. New approach: 72×72 circle cells, overflow:hidden, image fills the cell via inset:0 with objectFit:contain. Gap of 16px is actual clear space between cell edges — no math needed. Also bumped maxHeight 420→480. Co-Authored-By: Claude Sonnet 4.6 --- .../settings/account/ProfileDecoration.tsx | 52 +++++++------------ 1 file changed, 18 insertions(+), 34 deletions(-) diff --git a/src/app/features/settings/account/ProfileDecoration.tsx b/src/app/features/settings/account/ProfileDecoration.tsx index cf6e3f14f..ab8e7fb87 100644 --- a/src/app/features/settings/account/ProfileDecoration.tsx +++ b/src/app/features/settings/account/ProfileDecoration.tsx @@ -12,7 +12,7 @@ import { import { invalidateDecorationCache } from '../../../hooks/useAvatarDecoration'; const PROFILE_FIELD = 'io.lotus.avatar_decoration'; -const INSET = 8; +const CELL_SIZE = 72; function DecorationPreviewCell({ slug, @@ -34,29 +34,19 @@ function DecorationPreviewCell({ onClick={() => onSelect(slug)} style={{ position: 'relative', - width: 52, - height: 52, + width: CELL_SIZE, + height: CELL_SIZE, flexShrink: 0, border: `2px solid ${selected ? 'var(--accent-cyan)' : 'transparent'}`, - borderRadius: '0.75rem', + borderRadius: '50%', background: 'var(--bg-surface-variant)', cursor: 'pointer', padding: 0, boxShadow: selected ? '0 0 0 1px var(--accent-cyan)' : 'none', - overflow: 'visible', + overflow: 'hidden', outline: 'none', }} > - {/* Avatar placeholder tint */} -
{name} {selected && ( @@ -163,10 +152,9 @@ export function ProfileDecoration() { alt="Selected decoration preview" style={{ position: 'absolute', - top: -INSET, - left: -INSET, - width: `calc(100% + ${INSET * 2}px)`, - height: `calc(100% + ${INSET * 2}px)`, + inset: 0, + width: '100%', + height: '100%', objectFit: 'contain', pointerEvents: 'none', }} @@ -236,7 +224,7 @@ export function ProfileDecoration() { direction="Column" gap="300" style={{ - maxHeight: 420, + maxHeight: 480, overflowY: 'auto', paddingRight: 4, }} @@ -250,12 +238,8 @@ export function ProfileDecoration() { style={{ display: 'flex', flexWrap: 'wrap', - columnGap: 28, - rowGap: 52, - paddingBottom: INSET, - paddingLeft: INSET, - paddingRight: INSET, - paddingTop: INSET, + gap: 16, + padding: 4, }} > {category.decorations.map((d) => (