From ff5d768d91dca93c73244f3319684d46bef1a5ac Mon Sep 17 00:00:00 2001 From: Tsahi Matsliah Date: Thu, 28 May 2026 12:22:09 +0300 Subject: [PATCH 1/2] fix(header): keep profile-completion dot visible inside the stats pill The stats pill uses overflow-hidden so the hover backgrounds round cleanly at the pill's rounded-12 corners. That same clip was hiding the bottom half of the yellow profile-completion indicator, which ProfilePictureWithIndicator positions half outside the avatar via translate. Render ProfilePicture directly inside the combined profile Button, and lift the indicator dot out to a sibling of the pill anchored to a relative outer wrapper. Positioned at right-[31px] -bottom-1, the dot lands at the same visual spot as the avatar's bottom-left corner without being affected by the pill's overflow clip. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../src/components/profile/ProfileButton.tsx | 149 ++++++++++-------- 1 file changed, 79 insertions(+), 70 deletions(-) diff --git a/packages/shared/src/components/profile/ProfileButton.tsx b/packages/shared/src/components/profile/ProfileButton.tsx index f51da8086f..15292a0aec 100644 --- a/packages/shared/src/components/profile/ProfileButton.tsx +++ b/packages/shared/src/components/profile/ProfileButton.tsx @@ -3,8 +3,8 @@ import React, { useCallback, useEffect, useRef, useState } from 'react'; import classNames from 'classnames'; import dynamic from 'next/dynamic'; import { useAuthContext } from '../../contexts/AuthContext'; -import { ProfilePictureWithIndicator } from './ProfilePictureWithIndicator'; -import { ProfileImageSize } from '../ProfilePicture'; +import { ProfileImageSize, ProfilePicture } from '../ProfilePicture'; +import { useProfileCompletionIndicator } from '../../hooks/profile/useProfileCompletionIndicator'; import { CoreIcon, ReputationIcon, SettingsIcon } from '../icons'; import { Button, ButtonSize, ButtonVariant } from '../buttons/Button'; import { IconSize } from '../Icon'; @@ -37,6 +37,7 @@ export default function ProfileButton({ }: ProfileButtonProps): ReactElement { const { isOpen, onUpdate, wrapHandler } = useInteractivePopup(); const { user, isAuthReady } = useAuthContext(); + const { showIndicator } = useProfileCompletionIndicator(); const { streak, isLoading, isStreaksEnabled } = useReadingStreak(); const hasCoresAccess = useHasAccessToCores(); const [animatedCores, setAnimatedCores] = useState(null); @@ -208,77 +209,85 @@ export default function ProfileButton({ icon={} /> ) : ( -
- {isStreaksEnabled && streak && ( - - )} - {hasCoresAccess && ( - - Wallet -
- {preciseBalance} Cores - - } - > -
+
+ {isStreaksEnabled && streak && ( + + )} + {hasCoresAccess && ( + + Wallet +
+ {preciseBalance} Cores + + } > - - - -
+
+ + + +
+ + )} + + +
+ {showIndicator && ( +
)} - - -
)} {isOpen && onUpdate(false)} />} From dfa47f883fdbd2a742f555e817d946c8b72a9ffa Mon Sep 17 00:00:00 2001 From: Tsahi Matsliah Date: Thu, 28 May 2026 12:26:04 +0300 Subject: [PATCH 2/2] fix(header): move streak timezone warning to a corner badge MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In compact mode the streak's WarningIcon was rendered as a flex sibling of the streak icon inside a width-constrained IconWrapper, so it overflowed the wrapper and appeared on top of the streak number. Wrap the streak icon in a relative slot in compact mode and render the WarningIcon as an absolute size-4 badge anchored at the streak icon's bottom-left corner — mirroring how the profile-completion dot sits on the avatar. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../components/streak/ReadingStreakButton.tsx | 36 ++++++++++++------- 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/packages/shared/src/components/streak/ReadingStreakButton.tsx b/packages/shared/src/components/streak/ReadingStreakButton.tsx index 30dfe8976b..dda43c5790 100644 --- a/packages/shared/src/components/streak/ReadingStreakButton.tsx +++ b/packages/shared/src/components/streak/ReadingStreakButton.tsx @@ -122,18 +122,30 @@ export function ReadingStreakButton({ type="button" iconPosition={iconPosition} icon={ - - - {!isTimezoneOk && ( - - )} - + compact ? ( +
+ + + + {!isTimezoneOk && ( + + )} +
+ ) : ( + + + {!isTimezoneOk && ( + + )} + + ) } variant={ compact || isLaptop || isMobile