this repo has no description
1---
2import type { BskyProfile } from '../lib/types';
3import { escapeHtml, formatCount } from '../lib/render';
4import { HANDLE } from '../lib/atproto';
5
6interface Props {
7 profile: BskyProfile;
8}
9
10const { profile } = Astro.props;
11---
12
13{profile.banner ? (
14 <div class="banner"><img src={profile.banner} alt="Banner" /></div>
15) : (
16 <div class="banner" style="height:200px;background:var(--red);"></div>
17)}
18
19<div class="profile-header">
20 <div class="profile-top">
21 <div class="avatar-wrap">
22 <img src={profile.avatar || ''} alt={profile.displayName || HANDLE} />
23 </div>
24 <div class="profile-info">
25 <h1 class="display-name">{profile.displayName || HANDLE}</h1>
26 <p class="handle">
27 <a href={`https://bsky.app/profile/${HANDLE}`} target="_blank" rel="noopener">@{profile.handle}</a>
28 </p>
29 </div>
30 </div>
31 {profile.description && <p class="bio">{profile.description}</p>}
32 <div class="stats">
33 <span class="stat"><strong>{formatCount(profile.postsCount || 0)}</strong> POSTS</span>
34 <span class="stat"><strong>{formatCount(profile.followingCount || profile.followsCount || 0)}</strong> FOLLOWING</span>
35 <span class="stat"><strong>{formatCount(profile.followersCount || 0)}</strong> FOLLOWERS</span>
36 </div>
37</div>
38
39<style>
40 .profile-header {
41 max-width: 720px;
42 margin: 0 auto;
43 padding: 0;
44 border-bottom: 6px solid var(--black);
45 }
46 .profile-top {
47 display: flex;
48 align-items: center;
49 gap: 24px;
50 padding: 24px;
51 border-bottom: 3px solid var(--black);
52 }
53 .avatar-wrap {
54 width: 100px; height: 100px;
55 flex-shrink: 0;
56 overflow: hidden;
57 border: 4px solid var(--black);
58 background: var(--blue);
59 }
60 .avatar-wrap img { width: 100%; height: 100%; object-fit: cover; }
61 .display-name {
62 font-size: 3rem;
63 font-weight: 900;
64 text-transform: uppercase;
65 letter-spacing: -0.02em;
66 line-height: 0.95;
67 color: var(--text);
68 margin-bottom: 4px;
69 }
70 .handle {
71 font-size: 0.85rem;
72 font-weight: 700;
73 text-transform: uppercase;
74 letter-spacing: 0.06em;
75 }
76 .handle a { color: var(--blue); }
77 .bio {
78 font-size: 1rem;
79 color: var(--text-light);
80 padding: 16px 24px;
81 border-bottom: 3px solid var(--black);
82 white-space: pre-line;
83 line-height: 1.6;
84 }
85 .stats {
86 display: flex;
87 gap: 16px;
88 padding: 12px 24px;
89 }
90 .stat {
91 font-size: 0.75rem;
92 font-weight: 700;
93 text-transform: uppercase;
94 letter-spacing: 0.06em;
95 color: var(--text-muted);
96 }
97 .stat strong {
98 font-weight: 900;
99 color: var(--text);
100 margin-right: 3px;
101 }
102
103 @media (max-width: 600px) {
104 .profile-top { flex-direction: column; align-items: flex-start; gap: 16px; }
105 .avatar-wrap { width: 80px; height: 80px; }
106 .display-name { font-size: 2rem; }
107 .stats { flex-wrap: wrap; }
108 .stat { padding: 10px 16px; }
109 }
110</style>