@use 'sprucecss/scss/spruce' as *;
.profile-card {
background-color: color('surface');
border: config('border-width-base', $display) solid color('border');
border-radius: radius('lg');
overflow: hidden;
text-align: center;
&__cover {
background-image: linear-gradient(135deg, #{color('primary')}, #{color('secondary')});
block-size: 6rem;
}
&__avatar {
block-size: 6rem;
border: 4px solid color('surface');
border-radius: 50%;
inline-size: 6rem;
margin-block-start: -3rem;
margin-inline: auto;
object-fit: cover;
position: relative;
}
&__body {
padding: spacer('s') spacer-clamp('m', 'l') spacer-clamp('m', 'l');
@include layout-stack('xs');
}
&__name {
font-size: font-size('h4');
}
&__role {
color: color('muted');
font-size: config('font-size-sm', $typography);
}
&__stats {
border-block: config('border-width-base', $display) solid color('border');
display: grid;
grid-template-columns: repeat(3, 1fr);
margin-block-start: spacer('m') !important;
padding-block: spacer('s');
div {
display: flex;
flex-direction: column-reverse;
}
dt {
color: color('muted');
font-size: config('font-size-sm', $typography);
font-weight: 400;
}
dd {
color: color('heading');
font-size: font-size('h4');
font-weight: 700;
margin: 0;
}
}
&__actions {
display: flex;
gap: spacer('xs');
justify-content: center;
padding-block-start: spacer('xs');
}
}
<article class="profile-card">
<div class="profile-card__cover" aria-hidden="true"></div>
<img class="profile-card__avatar" src="https://images.unsplash.com/photo-1438761681033-6461ffad8d80?auto=format&fit=crop&w=192&h=192&q=70" alt="" width="96" height="96">
<div class="profile-card__body">
<h3 class="profile-card__name">Ava Martinez</h3>
<p class="profile-card__role">Product Designer · Lisbon</p>
<p class="profile-card__bio">Designing calm interfaces for busy people. Writing about design systems and accessible color.</p>
<dl class="profile-card__stats">
<div><dt>Posts</dt><dd>142</dd></div>
<div><dt>Followers</dt><dd>8.4k</dd></div>
<div><dt>Following</dt><dd>312</dd></div>
</dl>
<div class="profile-card__actions">
<button class="btn btn--primary btn--sm" type="button" aria-pressed="false" data-follow-button>Follow</button>
<a class="btn btn--outline-primary btn--sm" href="#">Message</a>
</div>
</div>
</article>
(() => {
document.querySelectorAll('[data-follow-button]').forEach((button) => {
button.addEventListener('click', () => {
const isFollowing = button.getAttribute('aria-pressed') === 'true';
button.setAttribute('aria-pressed', String(!isFollowing));
button.textContent = isFollowing ? 'Follow' : 'Following';
button.classList.toggle('btn--primary', isFollowing);
button.classList.toggle('btn--soft-primary', !isFollowing);
});
});
})();