feat(header): pill nav bar, brand shortening, status pulse, header gradient

This commit is contained in:
2026-04-08 11:11:35 -04:00
parent 4bc7f9eaac
commit f953a36b86
+51 -29
View File
@@ -68,17 +68,19 @@ router.afterEach(() => {
<!-- Left: brand --> <!-- Left: brand -->
<router-link to="/" class="nav-brand"> <router-link to="/" class="nav-brand">
<AppLogo :size="34" /> <AppLogo :size="34" />
Fabled Assistant <span class="brand-text">Fabled</span>
</router-link> </router-link>
<!-- Center: primary navigation (desktop) --> <!-- Center: primary navigation (desktop) -->
<div class="nav-center"> <div class="nav-center">
<router-link to="/" class="nav-link" :class="{ 'router-link-active': isKnowledgeActive }">Knowledge</router-link> <div class="nav-pill-bar">
<router-link to="/chat" :class="['nav-link', { 'router-link-active': isChatActive }]">Chat</router-link> <router-link to="/" class="nav-link" :class="{ 'router-link-active': isKnowledgeActive }">Knowledge</router-link>
<router-link to="/briefing" class="nav-link">Briefing</router-link> <router-link to="/chat" :class="['nav-link', { 'router-link-active': isChatActive }]">Chat</router-link>
<router-link to="/calendar" class="nav-link">Calendar</router-link> <router-link to="/briefing" class="nav-link">Briefing</router-link>
<router-link to="/news" class="nav-link">News</router-link> <router-link to="/calendar" class="nav-link">Calendar</router-link>
<router-link to="/projects" class="nav-link">Projects</router-link> <router-link to="/news" class="nav-link">News</router-link>
<router-link to="/projects" class="nav-link">Projects</router-link>
</div>
</div> </div>
<!-- Right: status + utilities + gear + user --> <!-- Right: status + utilities + gear + user -->
@@ -150,40 +152,51 @@ router.afterEach(() => {
<style scoped> <style scoped>
.app-header { .app-header {
background: var(--color-bg-secondary); background: linear-gradient(180deg, var(--color-surface), var(--color-bg));
border-bottom: 1px solid rgba(124, 58, 237, 0.08);
position: relative; position: relative;
} }
.nav { .nav {
padding: 0.75rem 1.5rem; padding: 0.6rem 1.5rem;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: space-between; justify-content: space-between;
position: relative; position: relative;
} }
/* Left */ /* Left — brand */
.nav-brand { .nav-brand {
display: flex; display: flex;
align-items: center; align-items: center;
gap: 0.4rem; gap: 0.45rem;
font-family: 'Fraunces', Georgia, serif;
font-optical-sizing: auto;
font-weight: 600;
font-size: 1.15rem;
letter-spacing: -0.01em;
color: var(--color-primary);
text-decoration: none; text-decoration: none;
flex-shrink: 0; flex-shrink: 0;
} }
.brand-text {
font-family: 'Fraunces', Georgia, serif;
font-style: italic;
font-optical-sizing: auto;
font-weight: 600;
font-size: 1rem;
letter-spacing: -0.01em;
color: #c4b0f0;
}
/* Center — absolutely positioned so it's truly centered regardless of side widths */ /* Center — pill bar */
.nav-center { .nav-center {
position: absolute; position: absolute;
left: 50%; left: 50%;
transform: translateX(-50%); transform: translateX(-50%);
display: flex; display: flex;
align-items: center; align-items: center;
gap: 0.1rem; }
.nav-pill-bar {
display: flex;
align-items: center;
gap: 2px;
background: rgba(124, 58, 237, 0.06);
border-radius: 10px;
padding: 3px;
} }
/* Right */ /* Right */
@@ -195,22 +208,22 @@ router.afterEach(() => {
} }
.nav-link { .nav-link {
color: var(--color-text-secondary); color: var(--color-text-muted);
text-decoration: none; text-decoration: none;
font-size: 0.9rem; font-size: 0.82rem;
padding: 0.3rem 0.6rem; padding: 0.3rem 0.75rem;
border-radius: var(--radius-sm); border-radius: 8px;
transition: background 0.15s, color 0.15s; transition: background 0.15s, color 0.15s;
} }
.nav-link:hover { .nav-link:hover {
color: var(--color-primary); color: var(--color-text-secondary);
background: color-mix(in srgb, var(--color-primary) 8%, transparent); background: rgba(124, 58, 237, 0.08);
} }
.nav-link.router-link-active { .nav-link.router-link-active {
color: var(--color-primary); color: #c4b5fd;
font-weight: 600; font-weight: 600;
box-shadow: inset 0 -2px 0 var(--color-primary); background: rgba(124, 58, 237, 0.2);
border-radius: 0; box-shadow: 0 0 12px rgba(124, 58, 237, 0.2);
} }
/* Status indicator */ /* Status indicator */
@@ -232,7 +245,7 @@ router.afterEach(() => {
font-weight: 500; font-weight: 500;
color: var(--color-text-muted); color: var(--color-text-muted);
} }
.status-green .status-dot { background: var(--color-success, #2ecc71); } .status-green .status-dot { background: var(--color-success, #2ecc71); animation: status-pulse 2.5s ease-in-out infinite; }
.status-yellow .status-dot { background: var(--color-warning, #f59e0b); animation: pulse-dot 2s infinite; } .status-yellow .status-dot { background: var(--color-warning, #f59e0b); animation: pulse-dot 2s infinite; }
.status-orange .status-dot { background: #f97316; } .status-orange .status-dot { background: #f97316; }
.status-red .status-dot { background: var(--color-danger, #e74c3c); } .status-red .status-dot { background: var(--color-danger, #e74c3c); }
@@ -241,6 +254,10 @@ router.afterEach(() => {
0%, 100% { opacity: 1; } 0%, 100% { opacity: 1; }
50% { opacity: 0.3; } 50% { opacity: 0.3; }
} }
@keyframes status-pulse {
0%, 100% { box-shadow: 0 0 4px rgba(74, 222, 128, 0.4); }
50% { box-shadow: 0 0 10px rgba(74, 222, 128, 0.6); }
}
/* Icon buttons (?, theme, gear) */ /* Icon buttons (?, theme, gear) */
.btn-icon { .btn-icon {
@@ -367,6 +384,11 @@ router.afterEach(() => {
min-height: 44px; min-height: 44px;
display: flex; display: flex;
align-items: center; align-items: center;
border-radius: 8px;
}
.mobile-menu .nav-link.router-link-active {
background: rgba(124, 58, 237, 0.15);
box-shadow: none;
} }
.mobile-user .btn-logout { .mobile-user .btn-logout {
min-height: 36px; min-height: 36px;