Avoid recreating style objects on every render in MobileBottomNav,
FloatingComposeButton, and MobileDrawer by extracting them to
module-level constants.
- Remove STICKY_HEADER_CLASS + backdrop-blur from TagFeedPage, ListDetailPage,
RelayPage, and DomainFeedPage to match the arc-based header style
- Migrate ListDetailPage tab bar to SubHeaderBar
- Migrate ThemesPage header to use shared PageHeader component
- Extract --top-bar-height and --bottom-nav-height CSS custom properties in
index.css, replacing hardcoded 2.5rem/2.75rem in all calc() expressions
- Document MobileDrawer DRAWER_BG_WIDTH constant (300px + 36px arc overhang)
- Remove unused STICKY_HEADER_CLASS import from ProfilePage
Consolidate duplicated patterns from iterative development into reusable
components:
- ArcBackground: shared SVG arc shape used by SubHeaderBar, MobileTopBar,
and MobileBottomNav (eliminates 3x duplicated SVG paths and magic numbers)
- PlanetButton: extracted FAB planet SVG with useId()-scoped gradient IDs
to prevent collisions if multiple instances ever coexist
- PageHeader: standardized back+icon+title header used across 10 pages
Net reduction of ~144 lines with no behavioral changes.
Make hasSubHeader conditional on user being logged in for Index,
KindFeedPage, BooksPage, and EventsFeedPage — these pages only render
tab sub-headers when the user is authenticated.
Change ai-chat-height to span full viewport minus only the top bar,
with padding-bottom for the bottom nav. The bg-secondary/50 background
now extends behind the bottom nav arc, eliminating the opacity seam.
- Add bg-secondary/50 to main container for full viewport chat background
- Add back arrow link matching Bookmarks/Photos pattern
- Match Bot icon color to text (foreground instead of muted)
- Match title to text-xl font-bold like other page titles
- Revert bold on <[o_o]> empty state characters
- Remove sub-header SVG arc from header, set hasSubHeader false so
logo header shows its own arc
- Change icon from Sparkles to Bot, remove background wrapper
- Remove border-t and bg-background from input area
Replace sticky backdrop-blur header with simple non-sticky title row
using the same flex items-center gap-4 px-4 mt-4 mb-1 layout as
Bookmarks, Photos, and other content pages.
Replace border-b + backdrop-blur-md with the same unified SVG arc+rect
background used by all other sub-headers. Set hasSubHeader: true so the
logo header doesn't show its own arc.
Replace backdrop-blur + border-b tab bar with SubHeaderBar component
so profile tabs get the same unified arc background as all other pages.
Set hasSubHeader: true so the logo header doesn't show its own arc.
Create SubHeaderBar component that draws the tab background and
decorative arc as one combined SVG path (rect + curve). Replace all 9
sub-header instances across Feed, Search, Notifications, Videos, Vines,
Photos, Themes, Events, and Books pages.
Also update MobileTopBar to draw its background as a unified SVG shape
(rect-only when sub-header present, rect+arc when standalone).
Eliminates the sub-pixel transparent seam between bg-background/80
containers and their separate SVG arc overlays.
Draw the arc and rectangle as one combined path instead of a separate
SVG arc over a bg-background/80 div. Single fill layer eliminates both
the sub-pixel seam during animation and the double-opacity overlap line.
Overlap the SVG arc 1px into the nav bar (bottom: calc(100% - 1px))
and add will-change-transform to promote the entire nav to a single
compositing layer. Prevents the transparent seam that appeared during
fast scroll-triggered show/hide transitions.
Replaced the pathLength/strokeDasharray trick with two literal front-arc
path segments in the mask (computed by splitting the cubic bezier at
circle intersection points). The ring visually passes in front of the
planet body at the bottom-left and top-right, and behind it through the
middle — identical to the previous Chrome rendering, now cross-browser.
Remove pathLength/strokeDasharray/strokeDashoffset from the SVG mask,
which WebKit renders inconsistently. Use a simple full-path black
stroke instead — cross-browser safe with nearly identical visual result
at FAB size.
Planet body uses accent→primary diagonal gradient, ring uses
primary→accent horizontal gradient. Replaced generic drop-shadow-lg
with a primary-colored layered drop-shadow for a glowing float effect
that adapts to the current theme.
Update all CSS utilities referencing bottom nav height (bottom-fab,
bottom-mobile-nav, pb-overscroll, ai-chat-height, livestream-height,
vine-slide-height) from 3.5rem to 2.75rem.
Update all CSS utilities that reference the top bar height (top-mobile-bar,
-mt-mobile-bar, ai-chat-height, livestream-height, vine-slide-height) from
3rem to 2.5rem. Scale logo from 28px to 24px to fit.
Affects all shared tab bars (Follows/Ditto, Posts/Accounts,
All/Mentions, Follows/Global, etc.) via the single TabButton
component. Brings total height from ~48px to ~36px for a more
compact mobile experience.
- Use identical inline sticky classes as Feed.tsx instead of STICKY_HEADER_CLASS
- Remove sidebar:py-5 from TabButtons to match Feed's default sizing
- Move search input bar outside conditional tab content, rendered
always right after tabs (like ComposeBox on Feed page)
- Use px-4 py-3 to match ComposeBox container padding
- Share single SearchInput across both tabs instead of duplicating
- Conditionally show filter/save buttons only on posts tab
- Add flex-1 min-w-0 to <main> to match Feed page layout
- Reduce search input top padding on mobile (pt-2 vs pt-5) so it
sits directly below the Posts/Accounts tabs without a gap
- Keep desktop padding unchanged with sidebar:pt-5
- Hide decorative arc SVG on mobile (only show on desktop with sidebar:block)
- Reduce top padding on search input containers from pt-5 to pt-3 on mobile
- Keep desktop layout unchanged with sidebar:pt-5
Introduces a hasSubHeader layout option. Pages with their own
tab bars set hasSubHeader: true, suppressing the arc on the
mobile top bar. Pages without tab bars (Bookmarks, Trends, etc.)
get the arc on the logo header automatically, ensuring the
bottom-most header always has the curved element.
Updates the Trends header to use the same layout pattern as
Bookmarks, Treasures, and other feed pages with a back arrow
that links to home, hidden on desktop.
Removes sticky behavior, backdrop blur, and background from the
header. Uses the same plain header style with back arrow, icon,
and title as Treasures and other feed pages.
Repositions the header prop in the Feed component to render
after the tabs and ComposeBox instead of before them. This
applies to all pages using Feed via KindFeedPage including
Treasures, Emoji Packs, Music, Podcasts, Badges, Articles,
Polls, Colors, Decks, and WebXDC.
Repositions the title/back-arrow header beneath the Follows/Global
tabs on all kind-specific feed pages, matching the layout pattern
established on the main feed and Themes pages.
Places the title/back-arrow header beneath the My Themes/Follows/
Global tabs instead of between the logo header and tabs, matching
the main feed layout pattern.
Applies the same curved arc treatment to Photos, Videos, Vines,
Events, Books, and Themes feed pages — removing the flat bottom
border and adding an SVG semi-ellipse below the Follows/Global
tabs, consistent with the main feed and notifications pages.
Wraps the -mt-mobile-bar styles in a max-width: 899px media
query so the negative margin and padding only apply when the
mobile top bar is visible. Desktop layout is unaffected.
Removes the fixed backing layer approach. Instead, pulls the
content area up behind the mobile header with a negative margin
and compensating padding. The content's bg-background/85 now
extends behind the header at all scroll positions, giving the
same double-opacity look as the tab bar without any stacking
issues.
Lowers the fixed backing layer to z-index 1 and adds z-10 to
the main content area. When at the top of the page, the backing
provides the 85% opacity behind the header. When scrolled, the
content area (z-10) occludes the backing (z-1), so only one
layer of 85% is ever behind the header — matching the tab bar.
Adds a fixed bg-background/85 div at z-index 19 that stays at
the viewport top, while the sticky header sits at z-20 on top.
This ensures the header has the same double-opacity density as
the tab bar at all scroll positions without getting darker when
content scrolls behind it.
Adds a bg-background/85 layer behind the bg-background/80 layer
in the top header, matching the double-opacity effect that the
tab bar gets from sitting over the main content area. This
ensures consistent visual density regardless of scroll position.
Replaces the separate drawer + arc background approach with a
single div spanning both areas, clipped with an SVG clipPath
that defines the rectangle + curved edge shape. The background
image flows seamlessly through the drawer and into the arc
with no seam.
Moves the arc from the generic Sheet component into MobileDrawer
so it can inherit the theme background image. Uses clip-path
ellipse on an HTML div instead of SVG fill, with the same
bg-background/70 overlay applied when a background image is set.
Increases the arc width from 20px to 36px with a deeper curve,
and changes fill from background/80 to solid background to
match the drawer's actual background color.
Removes the flat right border from the left sheet variant and
adds an SVG arc that curves outward along the right edge,
matching the curved styling used on the horizontal nav bars.