small SPA gleam experiment to fetch and render a single bsky post
1@import "tailwindcss";
2
3:root {
4 --color-sky-50: #f0f9ff;
5 --color-sky-100: #e0f2fe;
6 --color-sky-200: #bae6fd;
7 --color-sky-300: #7dd3fc;
8 --color-sky-400: #38bdf8;
9 --color-sky-500: #0ea5e9;
10 --color-sky-600: #0284c7;
11 --color-sky-700: #0369a1;
12 --color-sky-800: #075985;
13 --color-sky-900: #0c4a6e;
14}
15
16body {
17 background-color: var(--color-sky-50);
18 -webkit-font-smoothing: antialiased;
19 -moz-osx-font-smoothing: grayscale;
20}
21
22.card {
23 background-color: white;
24 border-radius: 0.75rem;
25 box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
26 border: 1px solid #e2e8f0;
27 overflow: hidden;
28 transition: box-shadow 0.2s ease;
29}
30
31.card:hover {
32 box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
33}
34
35.btn-primary {
36 padding: 1rem 1.5rem;
37 background-color: var(--color-sky-500);
38 color: white;
39 border-radius: 0.75rem;
40 font-weight: 500;
41 transition: background-color 0.2s ease, box-shadow 0.2s ease;
42 white-space: nowrap;
43}
44
45.btn-primary:hover {
46 background-color: var(--color-sky-600);
47}
48
49.btn-primary:focus {
50 outline: none;
51 box-shadow: 0 0 0 3px rgba(14, 165, 233, 0.3);
52}
53
54.input-primary {
55 padding: 1rem 1.25rem;
56 border: 1px solid #cbd5e1;
57 border-radius: 0.75rem;
58 transition: all 0.2s ease;
59}
60
61.input-primary:focus {
62 outline: none;
63 border-color: var(--color-sky-500);
64 box-shadow: 0 0 0 3px rgba(14, 165, 233, 0.1);
65}
66
67.input-primary::placeholder {
68 color: #94a3b8;
69}
70
71.avatar {
72 width: 3.5rem;
73 height: 3.5rem;
74 border-radius: 50%;
75 object-fit: cover;
76 flex-shrink: 0;
77 box-shadow: 0 0 0 2px #e0f2fe, 0 0 0 4px white;
78}
79
80.avatar-fallback {
81 width: 3.5rem;
82 height: 3.5rem;
83 border-radius: 50%;
84 background: linear-gradient(135deg, var(--color-sky-400), var(--color-sky-600));
85 display: flex;
86 align-items: center;
87 justify-content: center;
88 color: white;
89 font-size: 1.25rem;
90 font-weight: 700;
91 flex-shrink: 0;
92 box-shadow: 0 0 0 2px #e0f2fe, 0 0 0 4px white;
93}
94
95.avatar-fallback-sm {
96 width: 3rem;
97 height: 3rem;
98 border-radius: 50%;
99 background: linear-gradient(135deg, var(--color-sky-400), var(--color-sky-600));
100 display: flex;
101 align-items: center;
102 justify-content: center;
103 color: white;
104 font-size: 1.125rem;
105 font-weight: 700;
106 flex-shrink: 0;
107 box-shadow: 0 0 0 2px #e0f2fe;
108}
109
110.loading-spinner {
111 animation: spin 1s linear infinite;
112 border-radius: 50%;
113 border: 2px solid #e2e8f0;
114 border-top-color: var(--color-sky-500);
115}
116
117@keyframes spin {
118 to {
119 transform: rotate(360deg);
120 }
121}
122
123.link-card {
124 display: block;
125 border: 1px solid #e2e8f0;
126 border-radius: 0.5rem;
127 overflow: hidden;
128 transition: all 0.2s ease;
129}
130
131.link-card:hover {
132 border-color: #bae6fd;
133 background-color: #f8fafc;
134 box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
135}
136
137.image-grid {
138 display: grid;
139 grid-template-columns: repeat(2, 1fr);
140 gap: 0.5rem;
141 border-radius: 0.5rem;
142 overflow: hidden;
143 margin-top: 1rem;
144}
145
146.image-grid img {
147 width: 100%;
148 height: auto;
149 object-fit: cover;
150 transition: transform 0.2s ease;
151}
152
153.image-grid img:hover {
154 transform: scale(1.05);
155}
156
157.label-badge {
158 display: inline-flex;
159 align-items: center;
160 padding: 0.125rem 0.625rem;
161 border-radius: 9999px;
162 font-size: 0.75rem;
163 font-weight: 500;
164 background-color: #fef3c7;
165 color: #b45309;
166 border: 1px solid #fcd34d;
167}
168
169.post-content {
170 color: #334155;
171 font-size: 1.125rem;
172 line-height: 1.75;
173 white-space: pre-wrap;
174 word-break: break-word;
175}
176
177.external-link-preview {
178 padding: 1rem;
179}
180
181.external-link-title {
182 font-weight: 600;
183 color: #0f172a;
184 font-size: 1rem;
185 margin-bottom: 0.25rem;
186}
187
188.external-link-desc {
189 font-size: 0.875rem;
190 color: #475569;
191 display: -webkit-box;
192 -webkit-line-clamp: 2;
193 -webkit-box-orient: vertical;
194 overflow: hidden;
195}
196
197@media (prefers-reduced-motion: reduce) {
198 *,
199 *::before,
200 *::after {
201 animation-duration: 0.01ms !important;
202 animation-iteration-count: 1 !important;
203 transition-duration: 0.01ms !important;
204 }
205}