commits
- Add width: 100% to grain-feed-layout to prevent shrinking to content
- Update skeleton to use display: block matching profile header
- Use percentage-based widths for skeleton placeholders
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Full width
- Handle row with menu icon placeholder
- Proper sizing for handle, name, stats, bio
- Remove button (conditional in real component)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
searchGalleries was calling transformTimelineResponse which caches results
under the 'timeline' key. This caused explore search results to overwrite
the actual timeline data, showing only search results when navigating to
timeline.
Created separate transformSearchResponse that caches individual gallery
records but does not update the timeline query cache.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Change notifications header sticky position from top: 48px to top: 0
- Change explore search container sticky position from top: 48px to top: 0
- Constrain explore page border between search and tabs to feed max-width
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Fixed header/bottom nav with scrollable outlet between them
- Flex layout through outlet → pages → feed-layout → pull-to-refresh
- Router saves/restores scroll position on outlet instead of window
- Pull-to-refresh fills available space for empty area triggering
- Update all pages for flex compatibility (align-self: center)
- Remove redundant 100vh/100dvh in favor of 100%
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Position comment sheet above bottom nav
- Find scroll container lazily on first touch instead of connectedCallback
- Simplify scroll container detection to just check overflow-y
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Find scrollable parent instead of using window.scrollY, which is
always 0 now that outlet is the scroll container. Prevents accidental
refresh triggers when scrolling up mid-content.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Change header from sticky to fixed positioning
- Make outlet the scroll container between header and bottom nav
- Remove redundant padding from feed-layout
- Scrollbar now starts below header for PWA feel
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Subscribe grain-profile to cache updates for reactive UI
- Only update cache if it exists (preserves galleries)
- Handle avatar URL correctly based on change type
- Add defensive check for missing galleries
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Integrate grain-avatar-crop component into edit profile page for
consistent avatar selection experience across the app.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add ability to change avatar directly from profile page when viewing
own profile. Includes custom crop component with drag-to-position,
zoom slider, pinch-to-zoom, and keyboard accessibility.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The action dialog and avatar fullscreen overlay were constrained by
the pull-to-refresh transform, preventing proper fixed positioning.
Moved both to the page level to cover the full viewport including header.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add width: 100% to grain-feed-layout to prevent shrinking to content
- Update skeleton to use display: block matching profile header
- Use percentage-based widths for skeleton placeholders
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
searchGalleries was calling transformTimelineResponse which caches results
under the 'timeline' key. This caused explore search results to overwrite
the actual timeline data, showing only search results when navigating to
timeline.
Created separate transformSearchResponse that caches individual gallery
records but does not update the timeline query cache.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Change notifications header sticky position from top: 48px to top: 0
- Change explore search container sticky position from top: 48px to top: 0
- Constrain explore page border between search and tabs to feed max-width
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Fixed header/bottom nav with scrollable outlet between them
- Flex layout through outlet → pages → feed-layout → pull-to-refresh
- Router saves/restores scroll position on outlet instead of window
- Pull-to-refresh fills available space for empty area triggering
- Update all pages for flex compatibility (align-self: center)
- Remove redundant 100vh/100dvh in favor of 100%
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Change header from sticky to fixed positioning
- Make outlet the scroll container between header and bottom nav
- Remove redundant padding from feed-layout
- Scrollbar now starts below header for PWA feel
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Subscribe grain-profile to cache updates for reactive UI
- Only update cache if it exists (preserves galleries)
- Handle avatar URL correctly based on change type
- Add defensive check for missing galleries
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add ability to change avatar directly from profile page when viewing
own profile. Includes custom crop component with drag-to-position,
zoom slider, pinch-to-zoom, and keyboard accessibility.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The action dialog and avatar fullscreen overlay were constrained by
the pull-to-refresh transform, preventing proper fixed positioning.
Moved both to the page level to cover the full viewport including header.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>