my website at ewancroft.uk
6
fork

Configure Feed

Select the types of activity you want to include in your feed.

feat(layout): optimise mobile CSS for BlueskyPostCard

+35 -35
+35 -35
src/lib/components/layout/main/card/BlueskyPostCard.svelte
··· 118 118 {#snippet postContent(postData: BlueskyPost, depth: number = 0, isReplyParent: boolean = false)} 119 119 <div> 120 120 <!-- Author Info --> 121 - <div class="flex gap-{isReplyParent ? '2' : '3'} relative"> 121 + <div class="flex gap-{isReplyParent ? '2' : '3 sm:gap-3'} relative"> 122 122 {#if isReplyParent} 123 123 <a 124 124 href={getProfileUrl(postData.author.handle)} ··· 130 130 <img 131 131 src={postData.author.avatar} 132 132 alt={postData.author.displayName || postData.author.handle} 133 - class="h-10 w-10 rounded-full object-cover" 133 + class="h-8 w-8 sm:h-10 sm:w-10 rounded-full object-cover" 134 134 loading="lazy" 135 135 /> 136 136 {:else} 137 137 <div 138 - class="flex h-10 w-10 items-center justify-center rounded-full bg-primary-200 dark:bg-primary-800" 138 + class="flex h-8 w-8 sm:h-10 sm:w-10 items-center justify-center rounded-full bg-primary-200 dark:bg-primary-800" 139 139 > 140 - <span class="text-base font-semibold text-primary-700 dark:text-primary-300"> 140 + <span class="text-sm sm:text-base font-semibold text-primary-700 dark:text-primary-300"> 141 141 {(postData.author.displayName || postData.author.handle).charAt(0).toUpperCase()} 142 142 </span> 143 143 </div> ··· 154 154 <img 155 155 src={postData.author.avatar} 156 156 alt={postData.author.displayName || postData.author.handle} 157 - class="h-12 w-12 rounded-full object-cover" 157 + class="h-10 w-10 sm:h-12 sm:w-12 rounded-full object-cover" 158 158 loading="lazy" 159 159 /> 160 160 {:else} 161 161 <div 162 - class="flex h-12 w-12 items-center justify-center rounded-full bg-primary-200 dark:bg-primary-800" 162 + class="flex h-10 w-10 sm:h-12 sm:w-12 items-center justify-center rounded-full bg-primary-200 dark:bg-primary-800" 163 163 > 164 - <span class="text-lg font-semibold text-primary-700 dark:text-primary-300"> 164 + <span class="text-base sm:text-lg font-semibold text-primary-700 dark:text-primary-300"> 165 165 {(postData.author.displayName || postData.author.handle).charAt(0).toUpperCase()} 166 166 </span> 167 167 </div> ··· 294 294 295 295 <!-- Engagement Stats (only for non-reply-parent posts) --> 296 296 {#if !isReplyParent} 297 - <div class="flex items-center gap-6 text-sm pt-1"> 297 + <div class="flex flex-wrap items-center gap-3 sm:gap-6 text-xs sm:text-sm pt-1"> 298 298 {#if postData.replyCount !== undefined} 299 - <div class="flex items-center gap-1.5 text-ink-600 dark:text-ink-400"> 300 - <MessageCircle class="h-4 w-4" aria-hidden="true" /> 299 + <div class="flex items-center gap-1 sm:gap-1.5 text-ink-600 dark:text-ink-400"> 300 + <MessageCircle class="h-3.5 w-3.5 sm:h-4 sm:w-4" aria-hidden="true" /> 301 301 <span class="font-medium">{formatCompactNumber(postData.replyCount, locale)}</span> 302 302 </div> 303 303 {/if} 304 304 305 305 {#if postData.repostCount !== undefined} 306 - <div class="flex items-center gap-1.5 text-ink-600 dark:text-ink-400"> 307 - <Repeat2 class="h-4 w-4" aria-hidden="true" /> 306 + <div class="flex items-center gap-1 sm:gap-1.5 text-ink-600 dark:text-ink-400"> 307 + <Repeat2 class="h-3.5 w-3.5 sm:h-4 sm:w-4" aria-hidden="true" /> 308 308 <span class="font-medium">{formatCompactNumber(postData.repostCount, locale)}</span> 309 309 </div> 310 310 {/if} 311 311 312 312 {#if postData.likeCount !== undefined} 313 - <div class="flex items-center gap-1.5 text-ink-600 dark:text-ink-400"> 314 - <Heart class="h-4 w-4" aria-hidden="true" /> 313 + <div class="flex items-center gap-1 sm:gap-1.5 text-ink-600 dark:text-ink-400"> 314 + <Heart class="h-3.5 w-3.5 sm:h-4 sm:w-4" aria-hidden="true" /> 315 315 <span class="font-medium">{formatCompactNumber(postData.likeCount, locale)}</span> 316 316 </div> 317 317 {/if} ··· 366 366 {:else if error} 367 367 <Card error={true} errorMessage={error} /> 368 368 {:else if post} 369 - <article class="rounded-xl bg-canvas-100 p-6 shadow-lg transition-all duration-300 hover:shadow-xl dark:bg-canvas-900"> 369 + <article class="rounded-xl bg-canvas-100 p-4 sm:p-6 shadow-lg transition-all duration-300 hover:shadow-xl dark:bg-canvas-900"> 370 370 <!-- Header --> 371 - <div class="mb-4 flex items-center justify-between"> 372 - <div class="flex items-center gap-2"> 373 - <span class="text-xs font-semibold tracking-wide text-ink-700 uppercase dark:text-ink-300"> 371 + <div class="mb-3 sm:mb-4 flex items-start sm:items-center justify-between gap-2"> 372 + <div class="flex flex-col sm:flex-row sm:items-center gap-1 sm:gap-2 min-w-0"> 373 + <span class="text-xs font-semibold tracking-wide text-ink-700 uppercase dark:text-ink-300 whitespace-nowrap"> 374 374 Latest Bluesky Post 375 375 </span> 376 376 {#if post.isRepost && post.repostAuthor} 377 - <span class="text-xs text-ink-600 dark:text-ink-400">·</span> 377 + <span class="hidden sm:inline text-xs text-ink-600 dark:text-ink-400">·</span> 378 378 <div class="flex items-center gap-1.5 text-xs text-ink-600 dark:text-ink-400"> 379 - <Repeat2 class="h-3 w-3" aria-hidden="true" /> 379 + <Repeat2 class="h-3 w-3 shrink-0" aria-hidden="true" /> 380 380 <a 381 381 href={getProfileUrl(post.repostAuthor.handle)} 382 382 target="_blank" 383 383 rel="noopener noreferrer" 384 - class="font-medium text-primary-600 transition-colors hover:text-primary-700 dark:text-primary-400 dark:hover:text-primary-300" 384 + class="font-medium text-primary-600 transition-colors hover:text-primary-700 dark:text-primary-400 dark:hover:text-primary-300 truncate" 385 385 > 386 386 {post.repostAuthor.displayName || post.repostAuthor.handle} 387 387 </a> 388 - <span>reposted</span> 388 + <span class="whitespace-nowrap">reposted</span> 389 389 </div> 390 390 {:else if post.replyParent} 391 - <span class="text-xs text-ink-600 dark:text-ink-400">·</span> 391 + <span class="hidden sm:inline text-xs text-ink-600 dark:text-ink-400">·</span> 392 392 <div class="flex items-center gap-1.5 text-xs text-ink-600 dark:text-ink-400"> 393 - <MessageCircle class="h-3 w-3" aria-hidden="true" /> 394 - <span>Replying to</span> 393 + <MessageCircle class="h-3 w-3 shrink-0" aria-hidden="true" /> 394 + <span class="whitespace-nowrap">Replying to</span> 395 395 <a 396 396 href={getProfileUrl(post.replyParent.author.handle)} 397 397 target="_blank" 398 398 rel="noopener noreferrer" 399 - class="font-medium text-primary-600 transition-colors hover:text-primary-700 dark:text-primary-400 dark:hover:text-primary-300" 399 + class="font-medium text-primary-600 transition-colors hover:text-primary-700 dark:text-primary-400 dark:hover:text-primary-300 truncate" 400 400 > 401 401 @{post.replyParent.author.handle} 402 402 </a> ··· 407 407 href={getPostUrl(post.uri)} 408 408 target="_blank" 409 409 rel="noopener noreferrer" 410 - class="text-ink-600 transition-colors hover:text-primary-600 dark:text-ink-400 dark:hover:text-primary-400" 410 + class="text-ink-600 transition-colors hover:text-primary-600 dark:text-ink-400 dark:hover:text-primary-400 shrink-0" 411 411 aria-label="View post on Bluesky" 412 412 > 413 413 <ExternalLink class="h-4 w-4" aria-hidden="true" /> ··· 416 416 417 417 <!-- Reply Context --> 418 418 {#if post.replyParent} 419 - <div class="mb-4 rounded-xl border border-canvas-300 bg-canvas-200 p-3 dark:border-canvas-700 dark:bg-canvas-800"> 419 + <div class="mb-3 sm:mb-4 rounded-xl border border-canvas-300 bg-canvas-200 p-2.5 sm:p-3 dark:border-canvas-700 dark:bg-canvas-800"> 420 420 {@render postContent(post.replyParent, 0, true)} 421 421 </div> 422 422 {/if} ··· 438 438 <!-- Lightbox Modal --> 439 439 {#if lightboxImage} 440 440 <div 441 - class="fixed inset-0 z-50 flex items-center justify-center bg-black/90 p-4" 441 + class="fixed inset-0 z-50 flex items-center justify-center bg-black/90 p-2 sm:p-4" 442 442 onclick={closeLightbox} 443 443 onkeydown={(e) => e.key === 'Escape' && closeLightbox()} 444 444 role="button" ··· 448 448 <button 449 449 type="button" 450 450 onclick={closeLightbox} 451 - class="absolute top-4 right-4 rounded-full bg-black/50 p-2 text-white transition-colors hover:bg-black/70 focus:ring-2 focus:ring-white focus:outline-none" 451 + class="absolute top-2 right-2 sm:top-4 sm:right-4 rounded-full bg-black/50 p-2 text-white transition-colors hover:bg-black/70 focus:ring-2 focus:ring-white focus:outline-none z-10" 452 452 aria-label="Close" 453 453 > 454 - <X class="h-6 w-6" /> 454 + <X class="h-5 w-5 sm:h-6 sm:w-6" /> 455 455 </button> 456 - <div class="relative flex max-h-[90vh] w-full max-w-[90vw] flex-col items-center"> 456 + <div class="relative flex max-h-[90vh] w-full max-w-[95vw] sm:max-w-[90vw] flex-col items-center"> 457 457 <img 458 458 src={lightboxImage.url} 459 459 alt={lightboxImage.alt} 460 460 title={lightboxImage.alt} 461 - class="max-h-[80vh] w-full object-contain" 461 + class="max-h-[75vh] sm:max-h-[80vh] w-full object-contain" 462 462 loading="lazy" 463 463 /> 464 464 {#if lightboxImage.alt && lightboxImage.alt !== `Post attachment ${lightboxImage.url.split('/').pop()}`} 465 - <div class="mt-4 w-full max-w-full overflow-y-auto rounded-lg bg-black/70 px-4 py-2 text-center text-sm text-white" style="max-height: calc(10vh - 2rem);"> 465 + <div class="mt-2 sm:mt-4 w-full max-w-full overflow-y-auto rounded-lg bg-black/70 px-3 py-2 sm:px-4 text-center text-xs sm:text-sm text-white" style="max-height: calc(15vh - 1rem); sm:max-height: calc(10vh - 2rem);"> 466 466 {lightboxImage.alt} 467 467 </div> 468 468 {/if} 469 469 </div> 470 470 </div> 471 - {/if} 471 + {/if}