my website at ewancroft.uk

fix: update footer layout and integrate DecimalClock component

ewancroft.uk 572ff577 72457019

verified
Changed files
+62 -51
src
lib
components
+50 -39
src/lib/components/layout/Footer.svelte
··· 1 1 <script lang="ts"> 2 2 import type { ProfileData, SiteInfoData } from '$lib/services/atproto'; 3 + import DecimalClock from './DecimalClock.svelte'; 3 4 4 5 export let profile: ProfileData | null = null; 5 6 export let siteInfo: SiteInfoData | null = null; ··· 37 38 <footer 38 39 class="mt-auto w-full border-t border-canvas-200 bg-canvas-50 py-6 dark:border-canvas-800 dark:bg-canvas-950" 39 40 > 40 - <div 41 - class="container mx-auto space-y-2 px-4 text-center text-sm font-medium text-ink-800 dark:text-ink-100" 42 - > 43 - <!-- Line 1: Copyright & Profile --> 44 - <div class="flex flex-col items-center justify-center gap-1 sm:flex-row sm:gap-2"> 45 - <span>&copy; <span>{copyrightText}</span></span> 46 - {#if loading} 47 - <span role="status" aria-live="polite">Loading profile…</span> 48 - {:else if profile} 49 - <a 50 - href="https://bsky.app/profile/{profile.did}" 51 - class="underline hover:text-primary-500 focus-visible:text-primary-500 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary-600 dark:hover:text-primary-400 dark:focus-visible:text-primary-400" 52 - target="_blank" 53 - rel="noopener noreferrer" 54 - aria-label="Visit {profile.handle}'s Bluesky profile">@{profile.handle}</a 55 - > 56 - {:else if error} 57 - <span role="alert">Profile unavailable</span> 58 - {/if} 59 - </div> 41 + <div class="container mx-auto px-4"> 42 + <div class="flex items-center justify-between"> 43 + <!-- Left: Copyright & Info (centered on mobile) --> 44 + <div 45 + class="flex flex-1 flex-col items-center justify-center gap-2 text-center text-sm font-medium text-ink-800 md:items-start md:text-left dark:text-ink-100" 46 + > 47 + <!-- Line 1: Copyright & Profile --> 48 + <div class="flex flex-col items-center gap-1 sm:flex-row sm:gap-2 md:items-start"> 49 + <span>&copy; <span>{copyrightText}</span></span> 50 + {#if loading} 51 + <span role="status" aria-live="polite">Loading profile…</span> 52 + {:else if profile} 53 + <a 54 + href="https://bsky.app/profile/{profile.did}" 55 + class="underline hover:text-primary-500 focus-visible:text-primary-500 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary-600 dark:hover:text-primary-400 dark:focus-visible:text-primary-400" 56 + target="_blank" 57 + rel="noopener noreferrer" 58 + aria-label="Visit {profile.handle}'s Bluesky profile">@{profile.handle}</a 59 + > 60 + {:else if error} 61 + <span role="alert">Profile unavailable</span> 62 + {/if} 63 + </div> 64 + 65 + <!-- Line 2: Powered by & Code --> 66 + <div class="flex flex-col flex-wrap items-center gap-1 sm:flex-row sm:gap-2 md:items-start"> 67 + <span 68 + >Powered by <a 69 + href="https://atproto.com/guides/glossary#at-protocol" 70 + class="underline hover:text-primary-500 focus-visible:text-primary-500 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary-600 dark:hover:text-primary-400 dark:focus-visible:text-primary-400" 71 + target="_blank" 72 + rel="noopener noreferrer">atproto</a 73 + ></span 74 + > 75 + <a 76 + href="https://github.com/ewanc26/website" 77 + target="_blank" 78 + rel="noopener noreferrer" 79 + class="underline hover:text-primary-500 focus-visible:text-primary-500 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary-600 dark:hover:text-primary-400 dark:focus-visible:text-primary-400" 80 + aria-label="View source code on GitHub">code</a 81 + > 82 + <!-- Line 3: Version number --> 83 + <span aria-label="Version 10.3.0">v10.3.0</span> 84 + </div> 85 + </div> 60 86 61 - <!-- Line 2: Powered by & Code --> 62 - <div class="flex flex-col flex-wrap items-center justify-center gap-1 sm:flex-row sm:gap-2"> 63 - <span 64 - >Powered by <a 65 - href="https://atproto.com/guides/glossary#at-protocol" 66 - class="underline hover:text-primary-500 focus-visible:text-primary-500 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary-600 dark:hover:text-primary-400 dark:focus-visible:text-primary-400" 67 - target="_blank" 68 - rel="noopener noreferrer">atproto</a 69 - ></span 70 - > 71 - <a 72 - href="https://github.com/ewanc26/website" 73 - target="_blank" 74 - rel="noopener noreferrer" 75 - class="underline hover:text-primary-500 focus-visible:text-primary-500 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary-600 dark:hover:text-primary-400 dark:focus-visible:text-primary-400" 76 - aria-label="View source code on GitHub">code</a 77 - > 78 - <!-- Line 3: Version number because why not show it? --> 79 - <span aria-label="Version 10.3.0">v10.3.0</span> 87 + <!-- Right: Decimal Clock (hidden on mobile) --> 88 + <div class="hidden md:block"> 89 + <DecimalClock /> 90 + </div> 80 91 </div> 81 92 </div> 82 93 </footer>
+12 -12
src/lib/components/layout/Header.svelte
··· 5 5 import * as LucideIcons from '@lucide/svelte'; 6 6 import ThemeToggle from './ThemeToggle.svelte'; 7 7 import WolfToggle from './WolfToggle.svelte'; 8 - import DecimalClock from './DecimalClock.svelte'; 9 8 import { navItems } from '$lib/data/navItems'; 10 9 import { fetchProfile, type ProfileData } from '$lib/services/atproto'; 11 10 import { defaultSiteMeta, createSiteMeta, type SiteMetadata } from '$lib/helper/siteMeta'; ··· 85 84 <!-- Logo/Avatar with hover title --> 86 85 <a 87 86 href="/" 88 - class="group relative flex min-w-0 shrink items-center gap-2" 87 + class="group relative flex min-w-0 shrink items-center" 89 88 onclick={closeMobileMenu} 90 89 aria-label="Home - {siteMeta.title}" 91 90 > ··· 113 112 ></div> 114 113 {/if} 115 114 116 - <!-- Site title revealed on hover --> 117 - <span 118 - class="absolute top-1/2 left-full ml-2 -translate-y-1/2 truncate text-lg font-bold text-ink-900 opacity-0 transition-all duration-300 group-hover:opacity-100 sm:ml-3 dark:text-ink-50" 119 - aria-hidden="true" 120 - > 121 - {siteMeta.title} 122 - </span> 123 115 </div> 116 + <!-- Site title revealed on hover --> 117 + <span 118 + class="ml-2 truncate text-lg font-bold text-ink-900 opacity-0 transition-all duration-300 group-hover:opacity-100 sm:ml-3 dark:text-ink-50" 119 + aria-hidden="true" 120 + > 121 + {siteMeta.title} 122 + </span> 124 123 </a> 125 124 126 - <!-- Desktop Navigation --> 125 + <!-- Right side: Navigation + Toggles --> 127 126 <div class="hidden items-center gap-4 md:flex"> 128 127 <ul class="flex items-center gap-6" role="list"> 129 128 {#each navItems as item} ··· 152 151 </li> 153 152 {/each} 154 153 </ul> 155 - <DecimalClock /> 154 + 155 + <!-- Desktop Toggles --> 156 156 <div class="flex items-center gap-2"> 157 157 <WolfToggle /> 158 158 <ThemeToggle /> 159 159 </div> 160 160 </div> 161 161 162 - <!-- Mobile Menu Button --> 162 + <!-- Mobile Menu Button + Toggles --> 163 163 <div class="flex items-center gap-2 md:hidden"> 164 164 <WolfToggle /> 165 165 <ThemeToggle />