The SVG viewBox has empty space at the bottom (~12% padding).
This was causing Blobbi to appear floating above the ground.
Fix:
- Changed inner container to use 'items-end' for bottom alignment
- Added negative marginBottom (-10% of size) to pull Blobbi down
- This compensates for the SVG's internal bottom padding
Shadow restored:
- Back to bottom: -4 (was 0)
- Size: 60% width, 12% height
- Blur: 2px
- Better visual separation from Blobbi
Result: Blobbi now visually sits on the ground with proper
shadow placement underneath.
Float animation fix:
- Changed from abs(sin) to (1-cos)/2 wave formula
- This creates a 0-to-1 range that regularly returns to zero (ground)
- Y offset now goes from 0 (ground contact) to -3/-4.5 (slight lift)
- Blobbi settles back to ground between float cycles
Walking animation:
- Faster cycle (~0.5s) for rhythmic bobbing
- Range: 0 to -4.5px lift
- Reduced sway (1.5px) and rotation (1.5°)
Idle animation:
- Slower cycle (~2.5s) for calm breathing
- Range: 0 to -3px lift
- Subtle sway (0.8px) and rotation (0.8°)
Shadow adjustments:
- Moved to bottom: 0 (right at ground level)
- Smaller size (55% width, 10% height) for subtler effect
- Less blur (1px) for sharper ground contact
- Stronger base opacity (0.4) that fades as Blobbi lifts
- Scale shrinks more noticeably when lifted
- Float animation now only moves Blobbi upward from ground level
- Uses abs(sin) so Y offset is always negative (up) or zero
- Base position = on the ground, animation lifts slightly above
- Shadow stays anchored to ground while Blobbi floats above it
- Shadow doesn't move with float offset
- Shadow scales/fades based on float height for depth illusion
- Reduced horizontal sway and rotation for subtler effect
- Walking: 2px sway, 2° rotation (was 3px, 3°)
- Idle: 1px sway, 1° rotation (was 1.5px, 1.5°)
- Simplify entry animation to smooth walking emergence (no stuck/squeeze)
- Add forced initial walk after entry - Blobbi walks right immediately
- Improve walking behavior - 75% walk chance, shorter idle periods
- Remove visual flip when changing direction - Blobbi always faces same way
- Add soft floating/swaying animation with different speeds for walk vs idle
- Walking: faster rhythmic bobbing (~0.8s cycle)
- Idle: slower calm breathing (~3s cycle)
- Add soft shadow underneath for depth/floating effect
- Stronger opacity (0.35), blur, and gradient for better visibility
- Shadow reacts to float height
- Keep clipping behavior for sidebar emergence on desktop
- Mobile uses simple slide-in from left edge
Entry position changes:
- Add layout config with sidebarWidth (300px) and maxContentWidth (1200px)
- Calculate main content left edge accounting for centered layout
- Entry now starts at left edge of main content area, not viewport edge
- Resting position is inside the content area with proper padding
Playful entry animation (2.2 seconds total):
- Phase 1 (0-25%): Emerge diagonally with slight forward lean and squish
- Phase 2 (25-40%): Get 'stuck' halfway with wobble effect
- Phase 3 (40-70%): Tug motions - 3 cycles of forward/back pulls, each stronger
- Phase 4 (70-100%): Break free and walk smoothly to final position
Visual effects during entry:
- Rotation (lean forward/back during tugging)
- ScaleX/ScaleY (squish/stretch for squeeze effect)
- Transform origin at center bottom for natural pivoting
The animation feels like Blobbi is squeezing out from the previous page
into the current one, getting briefly stuck, then breaking free.
- Change entry position to start behind the sidebar (padding.left/2 - size)
instead of off-screen left edge, so companion emerges from sidebar
- Add setPosition function to motion hook for syncing position
- Sync motion position to restingPosition when entry animation completes
to prevent teleport between animated and physics-controlled movement
- Entry is now continuous: emerges from sidebar -> slides to resting position
- Add canBeCompanion check to prevent eggs from being set as companion
- Show toast error if user tries to set egg as companion
- Disable companion button for eggs with helpful tooltip
- Update tooltip to show 'Hatch first to set as companion' for eggs
- Remove current_companion tag entirely when unsetting (instead of empty string)
- Filter out existing current_companion tags before adding new one
- Add Footprints icon indicator in BlobbiSelectorCard for current companion
- Include tooltip 'Current companion' on the indicator icon
- Pass currentCompanion prop through BlobbiSelectorPage and modal
- Add isCurrentCompanion and isUpdatingCompanion props to BlobbiDashboardFloatingControls
- Implement handleSetAsCompanion to toggle current_companion tag on profile
- Show green icon color when Blobbi is the current companion
- Add disabled state support to FloatingActionDef for loading states
- Pass publishEvent to BlobbiDashboard for profile updates
- Daily Missions section is now collapsible with chevron toggle
- Hatch Tasks section is collapsible when active
- Evolve Tasks section is collapsible when active
- All sections expanded by default for easy access
- Header shows progress count (e.g., 2/4) for task sections
- Header shows coins earned for Daily Missions section
- Smooth chevron rotation animation on expand/collapse
Apply the same pattern used in other Blobbi modals:
- Sticky header with bg-background
- Explicit DialogClose button in header
- Scrollable content area with flex-1 min-h-0 overflow-y-auto
- Add pr-12 to DialogHeader to account for close button, fixing right padding
- Make DialogHeader sticky with proper background for all Blobbi modals
- Structure modals as flex column with min-h-0 for proper scrolling
- Apply pattern to: BlobbiActionsModal, BlobbiActionInventoryModal,
BlobbiInventoryModal, BlobbiMissionsModal, BlobbiShopModal
- Add formatCompactNumber utility for compact coin display (1.2K, 15.4K, 1.2M)
- Fix BlobbiActionInventoryModal (medicine items) layout for mobile
- Fix BlobbiBottomBar to prevent overflow on narrow screens
- Fix BlobbiInventoryModal item cards for mobile
- Fix BlobbiMissionsModal horizontal scroll and layout issues
- Fix DailyMissionsPanel and TasksPanel for mobile
- Fix BlobbiShopModal and related dialogs for mobile
- Apply compact number formatting to all coin displays
Integrate useWikipediaSearch and useArchiveSearch into both the desktop
sidebar dropdown (ProfileSearchDropdown) and mobile bottom-nav sheet
(MobileSearchSheet). At most 1 result from each source is shown, always
positioned after Nostr profiles to preserve profile precedence. Keyboard
navigation indices updated to include the new items.
Detect Wikipedia URLs and render a custom WikipediaArticleHeader with hero
image, article title, Wikidata description, expandable extract, and a
Read on Wikipedia footer link. Also uses the Wikipedia API for accurate
page titles in the header bar and SEO metadata, and navigates back to
/wikipedia on the back button.
Pills now highlight based on which section is visible as you scroll.
Clicking a pill smooth-scrolls to that section. The 'All' pill and
filter-based empty states are removed since all sections are always shown.
Remove the inline toggle from the post composer toolbar and add
imageQuality to AppConfig instead. The setting now lives in
Settings > Network under 'Image Uploads' with a Compressed/Original
pill toggle, persisted to localStorage like other app settings.
Remove the 'X members' subtitle from the header and add a row of stacked
member avatars (up to 8) with a clickable '+X more' that switches to the
Members tab, matching the style used in quote post list cards.
Starter pack pages now have two tabs: Feed (default) shows posts from all
pack members using useStreamPosts, and Members shows the existing member
list with follow/unfollow buttons.
Adds a Compressed/Original toggle button in the ComposeBox toolbar.
When set to Original, images are uploaded as-is without resizing or
re-encoding. Defaults to Compressed.
Instead of always converting to JPEG, encode both JPEG and PNG in
parallel and keep whichever is smaller. Skip re-encoding entirely
when the image already fits within the dimension limit.
Instead of showing just the site name (e.g. 'Internet Archive'), parse the
URL path for a readable slug and title-case it. Falls back to embed site
name or hostname when the path has no meaningful slug.
ExternalContentSidebarItem now fetches the book title from OpenLibrary
via useBookInfo for ISBN entries instead of showing the generic 'Books'
label. The icon uses BookOpen instead of the Globe fallback.
ExternalContentPage (country, URL, ISBN pages) gains a 3-dots menu on
the right side of the action bar with Add/Remove from sidebar.
NoteMoreMenu gets an Add/Remove from sidebar item after 'Add to list',
so any post can be pinned to the sidebar from its options menu.
Both locations toggle between add (PanelLeft icon) and remove (Trash2
icon) based on whether the item is already in the sidebar.
Remove all non-standard NIP-58 extensions:
- Delete BadgeTierPill component and badge tier system (bronze/silver/gold/diamond)
- Delete isShopBadge, isAchievementBadge, getBadgeTier, BadgeTier type
- Delete publish-achievement-badges.sh script
- Remove kind 30009 section from NIP.md
- Clean up badge category pills from detail page and tier pills from badge rows
Badges now use pure standard NIP-58 with no custom tags.
The share dropdown on ListDetailPage now shows 'Remove from sidebar'
with a trash icon when the list is already pinned, instead of hiding
the action entirely. This lets users unpin lists without entering
sidebar edit mode.