The Profile Layout Refresh

last updated by ewan datetime loading...

(datetime loading...)

View on WhiteWind or see the record at atproto.at

6 min read • 1,183 words


Right, so I've gone and completely redesigned how my profile component looks. Again. I know, I know—another day, another tweak to the website. But this time it actually makes sense, I promise.

What Was Wrong Before?

The old profile layout was... well, let's just say it was having an identity crisis. Everything was centred, which looked fine enough, but it felt a bit like a business card floating in the middle of a webpage. The avatar sat there like a lonely island above a sea of centred text, and the whole thing felt disconnected from the banner image above it.

Here's what the old version looked like in terms of structure:

<!-- Everything centred and floating -->
<div class="profile-content flex flex-col items-center justify-center text-center">
  <img class="rounded-full w-32 h-32 -mt-2" />
  <div class="text-center p-2">
    <!-- All the user info stacked vertically -->
  </div>
</div>

It worked, but it felt... static. Like a museum exhibit rather than a living profile.

The New Layout Philosophy

The redesign embraces a more modern, card-based approach that actually makes use of horizontal space whilst being properly responsive. I've moved from a centred, floating layout to a proper sidebar-style arrangement where the avatar overlaps the banner (because why not make use of that visual connection?) and the user information gets its own dedicated card space.

The key changes:

1. Avatar Positioning with Responsive Sizing

Instead of sitting below the banner like an awkward afterthought, the avatar now overlaps the banner with negative margins that adapt to screen size. On mobile, it uses -mt-12 with a smaller 24×24 avatar, whilst desktop gets the full -mt-16 treatment with a proper 32×32 avatar. It creates this nice visual bridge between the banner and the content below, plus it looks much more integrated.

2. Responsive Horizontal Layout

Gone is the vertical stack of doom—well, mostly. The layout now cleverly adapts: mobile devices get a sensible vertical stack (flex-col), whilst larger screens enjoy a proper horizontal arrangement (sm:flex-row). This makes much better use of screen real estate on desktop whilst keeping things readable on mobile.

3. Card-Based Information with Proper Theming

The user details now live in their own card with proper background styling (style="background: var(--card-bg)"), which gives the information more visual weight and makes it easier to scan. The card approach also provides better visual hierarchy and makes the whole thing feel more structured.

4. Adaptive Text Alignment

Text alignment now responds to screen size: centred on mobile (where it makes sense for narrow screens) and left-aligned on desktop (where it's more readable). Your eyes don't have to work as hard to follow the content, especially on wider screens.

5. Smart Content Prioritisation

Perhaps most importantly, the profile now handles different types of content intelligently. The DID (that long cryptographic identifier) is hidden on mobile devices where screen space is precious, but shows on desktop where there's room to breathe. Links are properly styled with hover states, and everything truncates gracefully when space runs out.

The Technical Bits

The new structure looks like this:

<div class="profile-content mx-2 mb-8 relative">
  <div class="flex flex-col sm:flex-row sm:items-start text-left sm:gap-6">
    <!-- Avatar with responsive sizing and positioning -->
    <img
      class="rounded-full shadow-lg hover:transform-none flex-shrink-0 relative z-10
             w-24 h-24 -mt-12 mx-auto mb-4
             sm:w-32 sm:h-32 sm:-mt-16 sm:mx-0 sm:mb-0"
    />
    
    <!-- User information card -->
    <div class="flex-1 min-w-0 p-4 rounded-[1em] overflow-hidden" 
         style="background: var(--card-bg);">
      <!-- All the lovely details with responsive alignment -->
    </div>
  </div>
</div>

A few things worth noting:

  • The responsive classes handle the mobile-first approach properly—mobile gets sensible defaults, desktop gets the enhanced experience
  • flex-shrink-0 on the avatar prevents it from getting squashed on smaller screens
  • min-w-0 on the text container prevents flex layout issues with long text (this is crucial for proper truncation)
  • overflow-hidden ensures everything stays contained within the card boundaries
  • The z-10 on the avatar makes sure it sits above everything else visually
  • Responsive margins (mx-auto mb-4 on mobile, mx-0 mb-0 on desktop) keep things properly centred where needed

Status Component Integration

The Status component deserved special attention in this redesign. It's no longer just an afterthought tacked onto the bottom—it's now properly integrated into the card layout with the same responsive text alignment approach. Where it previously forced everything to be centred (text-center), it now uses text-center sm:text-left to match the overall responsive philosophy.

But here's where it gets interesting: the Status component now handles multiple data sources intelligently. It can display:

  • Recent status updates from the uk.ewancroft.now collection
  • Recent music from Last.fm via the RecentFM API
  • A combination of both, prioritising recent status updates

The component makes smart decisions about what to show based on recency—if you've got a status update from within the last 24 hours, it'll show that. Otherwise, it falls back to recent music. And if you've got both recent status and music data, it cleverly combines them into a single, readable sentence.

There's even a subtle fade-in animation with a 2-second delay to prevent the jarring experience of content popping in immediately. Small touches like this make the whole experience feel more polished.

Error Handling and Fallbacks

One thing I'm particularly pleased with is how gracefully everything degrades. If there's no profile data, you get a helpful placeholder encouraging you to create a proper app.bsky.actor.profile record. If the Status component can't fetch data, it simply doesn't show anything rather than breaking the entire layout.

The responsive approach means that even if something goes wrong with the desktop layout, you'll still get a perfectly usable mobile experience. And vice versa.

Performance Considerations

The component now uses proper caching for profile data and implements smart fetching strategies. The safeFetch utility handles network errors gracefully, and data is cached appropriately to avoid unnecessary requests.

The Status component waits for the component to mount before fetching data, and only refetches when the profile actually changes. This prevents unnecessary API calls and keeps things snappy.

Why This Matters

Look, I'll be honest—most people probably wouldn't notice these changes unless they were looking for them. But that's kind of the point. Good design shouldn't scream at you; it should just feel right. The old layout wasn't bad, but it felt like it was trying too hard to be minimalist and ended up being a bit lifeless.

This new approach feels more natural and modern. It's the kind of layout you'd expect to see on a professional social media platform or a well-designed personal website. Plus, it scales properly across different screen sizes, handles edge cases gracefully, and provides a better experience for users regardless of how they're accessing the site.

The responsive approach means it works equally well whether someone's checking your profile on their phone during their commute or browsing on a massive desktop monitor. And the intelligent content prioritisation means the most relevant information is always front and centre.

It's these kinds of details that separate a thrown-together personal site from something that feels properly crafted. The design now feels intentional rather than accidental, and that makes all the difference.