diff --git a/src/assets/icons/mail.svg b/src/assets/icons/mail.svg
new file mode 100644
index 00000000..ca34cb55
--- /dev/null
+++ b/src/assets/icons/mail.svg
@@ -0,0 +1,3 @@
+
diff --git a/src/lib/components/Navigation.svelte b/src/lib/components/Navigation.svelte
index 62191fb0..e2042c51 100644
--- a/src/lib/components/Navigation.svelte
+++ b/src/lib/components/Navigation.svelte
@@ -17,7 +17,6 @@
import UserSettingsModal from './UserSettingsModal.svelte'
import InvitationsModal from './crew/InvitationsModal.svelte'
import { authStore } from '$lib/stores/auth.store'
- import { crewStore } from '$lib/stores/crew.store.svelte'
// Props from layout data
const {
@@ -145,6 +144,15 @@
// Database back button hover state
let databaseBackHovered = $state(false)
+ // Query for the user's crew (to determine if phantom claims should be fetched)
+ const myCrewQuery = createQuery(() => ({
+ ...crewQueries.myCrew(),
+ enabled: isAuth
+ }))
+
+ // Derived: whether the user is in a crew (from query, not store)
+ const isInCrew = $derived(myCrewQuery.data != null)
+
// Query for pending invitations (only when authenticated)
const pendingInvitationsQuery = createQuery(() => ({
...crewQueries.pendingInvitations(),
@@ -154,7 +162,7 @@
// Query for pending phantom claims (only when authenticated and in a crew)
const pendingPhantomClaimsQuery = createQuery(() => ({
...crewQueries.pendingPhantomClaims(),
- enabled: isAuth && crewStore.isInCrew
+ enabled: isAuth && isInCrew
}))
// Derived counts
@@ -264,23 +272,16 @@
aria-label="Your account"
class="profile-link"
>
-
- {#if avatarSrc}
-
- {/if}
- {#if totalNotificationCount > 0}
-
-
-
- {/if}
-
+ {#if avatarSrc}
+
+ {/if}
{username}
@@ -298,8 +299,14 @@
-
-
+
+ {#if totalNotificationCount > 0}
+
+ {:else}
+
+ {/if}
@@ -317,11 +324,13 @@
{/if}
- {#if isAuth && totalNotificationCount > 0}
+ {#if isAuth}
{/if}
@@ -556,25 +565,12 @@
align-items: center;
gap: spacing.$unit-half;
- .avatar-container {
- position: relative;
- display: flex;
- align-items: center;
- justify-content: center;
- }
-
.user-avatar {
width: 24px;
height: 24px;
border-radius: 50%;
object-fit: cover;
}
-
- .avatar-badge {
- position: absolute;
- top: -2px;
- right: -4px;
- }
}
// Dropdown button with badge (for Invitations)
@@ -630,6 +626,70 @@
}
}
+ // Notification pulse animation for the more trigger
+ @keyframes notification-pulse {
+ 0%,
+ 100% {
+ opacity: 1;
+ }
+ 50% {
+ opacity: 0.6;
+ }
+ }
+
+ :global(.nav-more-trigger.has-notification) {
+ animation: notification-pulse 2s ease-in-out infinite;
+ // Default pulse color (no element selected)
+ background-color: var(--button-primary-bg);
+ color: white;
+ // Compensate for larger mail icon (18px vs 14px ellipsis)
+ padding: spacing.$unit calc(spacing.$unit + 3px);
+
+ &:hover {
+ animation: none;
+ background-color: var(--button-primary-bg-hover);
+ }
+ }
+
+ // Element-specific notification colors
+ :global(.nav-more-trigger.has-notification.wind) {
+ background-color: var(--wind-button-bg);
+ &:hover {
+ background-color: var(--wind-button-bg-hover);
+ }
+ }
+ :global(.nav-more-trigger.has-notification.fire) {
+ background-color: var(--fire-button-bg);
+ &:hover {
+ background-color: var(--fire-button-bg-hover);
+ }
+ }
+ :global(.nav-more-trigger.has-notification.water) {
+ background-color: var(--water-button-bg);
+ &:hover {
+ background-color: var(--water-button-bg-hover);
+ }
+ }
+ :global(.nav-more-trigger.has-notification.earth) {
+ background-color: var(--earth-button-bg);
+ &:hover {
+ background-color: var(--earth-button-bg-hover);
+ }
+ }
+ :global(.nav-more-trigger.has-notification.light) {
+ background-color: var(--light-button-bg);
+ color: black;
+ &:hover {
+ background-color: var(--light-button-bg-hover);
+ }
+ }
+ :global(.nav-more-trigger.has-notification.dark) {
+ background-color: var(--dark-button-bg);
+ &:hover {
+ background-color: var(--dark-button-bg-hover);
+ }
+ }
+
// Style the new team button as a prominent circular button
// Remove redundant styles that the Button component already handles
:global(.new-team-button) {