In dark mode --c-primary switches from navy (#012851) to mint (#a1dcd8). Buttons using bg-primary+text-white showed white text on mint at 1.4:1 contrast — invisible. bg-brand-navy buttons were also invisible (navy on near-black canvas, 1.3:1). Replaced in 28 components app-wide: - bg-primary ... text-white → text-primary-fg - hover:bg-primary hover:text-white → hover:text-primary-fg - bg-brand-navy ... text-white + hover:bg-brand-navy/90 → bg-primary ... text-primary-fg + hover:bg-primary/90 Light mode is unchanged: primary-fg = white in light mode. Dark mode: primary-fg = navy (#012851) on mint bg = readable. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
82 lines
2.2 KiB
Svelte
82 lines
2.2 KiB
Svelte
<script lang="ts">
|
|
import { enhance } from '$app/forms';
|
|
import { m } from '$lib/paraglide/messages.js';
|
|
|
|
let { userInitials }: { userInitials: string | null } = $props();
|
|
|
|
let userMenuOpen = $state(false);
|
|
|
|
function clickOutside(node: HTMLElement) {
|
|
const handleClick = (event: MouseEvent) => {
|
|
if (node && !node.contains(event.target as Node) && !event.defaultPrevented) {
|
|
userMenuOpen = false;
|
|
}
|
|
};
|
|
document.addEventListener('click', handleClick, true);
|
|
return () => {
|
|
document.removeEventListener('click', handleClick, true);
|
|
};
|
|
}
|
|
</script>
|
|
|
|
<div
|
|
class="relative"
|
|
{@attach clickOutside}
|
|
onkeydown={(e) => {
|
|
if (e.key === 'Escape') userMenuOpen = false;
|
|
}}
|
|
role="none"
|
|
>
|
|
{#if userInitials}
|
|
<button
|
|
type="button"
|
|
aria-expanded={userMenuOpen}
|
|
aria-haspopup="true"
|
|
onclick={() => (userMenuOpen = !userMenuOpen)}
|
|
class="flex h-8 w-8 items-center justify-center rounded-full bg-primary font-sans text-xs font-bold text-primary-fg transition-opacity hover:opacity-80"
|
|
>
|
|
{userInitials}
|
|
</button>
|
|
{:else}
|
|
<button
|
|
type="button"
|
|
aria-label={m.nav_profile()}
|
|
aria-expanded={userMenuOpen}
|
|
aria-haspopup="true"
|
|
onclick={() => (userMenuOpen = !userMenuOpen)}
|
|
class="inline-flex items-center gap-1.5 px-3 py-2 font-sans text-xs font-bold tracking-widest text-ink-3 uppercase transition-colors hover:text-ink"
|
|
>
|
|
<img
|
|
src="/degruyter-icons/Simple/Small-16px/SVG/Action/Account-SM.svg"
|
|
alt=""
|
|
aria-hidden="true"
|
|
class="h-4 w-4 opacity-50"
|
|
/>
|
|
</button>
|
|
{/if}
|
|
|
|
{#if userMenuOpen}
|
|
<div
|
|
class="absolute top-full right-0 z-50 mt-1 min-w-[10rem] rounded-sm border border-line bg-overlay shadow-md"
|
|
>
|
|
<a
|
|
href="/profile"
|
|
onclick={() => (userMenuOpen = false)}
|
|
class="block px-4 py-2.5 font-sans text-xs font-bold tracking-widest text-ink-2 uppercase transition-colors hover:bg-muted hover:text-ink"
|
|
>
|
|
{m.nav_profile()}
|
|
</a>
|
|
<div class="border-t border-line">
|
|
<form action="/logout" method="POST" use:enhance>
|
|
<button
|
|
type="submit"
|
|
class="w-full px-4 py-2.5 text-left font-sans text-xs font-bold tracking-widest text-ink-3 uppercase transition-colors hover:bg-muted hover:text-ink"
|
|
>
|
|
{m.nav_logout()}
|
|
</button>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
{/if}
|
|
</div>
|