632 lines
18 KiB
Vue
632 lines
18 KiB
Vue
<template>
|
|
<div class="sidebar-wrapper">
|
|
<!-- Expanded State -->
|
|
<aside
|
|
class="sidebar-nebula"
|
|
:class="{ 'is-hidden': isCollapsed }"
|
|
>
|
|
<!-- Logo Area -->
|
|
<div class="sidebar-logo">
|
|
<div class="logo-btn" data-trackid="home_header_logo_btn_click" @click="navigateTo('/')">
|
|
<div class="brand-logo"></div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Main Navigation -->
|
|
<nav class="sidebar-menu main-menu">
|
|
<NuxtLink to="/" class="menu-item" active-class="active" title="首页广场">
|
|
<div class="icon-box">
|
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3" width="7" height="7"></rect><rect x="14" y="3" width="7" height="7"></rect><rect x="14" y="14" width="7" height="7"></rect><rect x="3" y="14" width="7" height="7"></rect></svg>
|
|
</div>
|
|
<div class="active-indicator"></div>
|
|
</NuxtLink>
|
|
|
|
<NuxtLink to="/market" class="menu-item" active-class="active" title="资讯广场">
|
|
<div class="icon-box">
|
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M4 4h15a1 1 0 0 1 1 1v13a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a1 1 0 0 1 1-1z"></path><path d="M8 8h7"></path><path d="M8 12h7"></path><path d="M8 16h4"></path></svg>
|
|
</div>
|
|
<div class="active-indicator"></div>
|
|
</NuxtLink>
|
|
|
|
<!-- <NuxtLink to="/apps" class="menu-item" active-class="active" title="AI 应用广场">
|
|
<div class="icon-box">
|
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3" width="7" height="7" rx="1.5"></rect><rect x="14" y="3" width="7" height="7" rx="1.5"></rect><rect x="3" y="14" width="7" height="7" rx="1.5"></rect><rect x="14" y="14" width="7" height="7" rx="1.5"></rect></svg>
|
|
</div>
|
|
<div class="active-indicator"></div>
|
|
</NuxtLink> -->
|
|
|
|
<NuxtLink to="/community" class="menu-item" active-class="active" title="社区">
|
|
<div class="icon-box">
|
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M7 10h6"></path><path d="M7 14h4"></path><path d="M5 20l2.5-3H17a3 3 0 0 0 3-3V7a3 3 0 0 0-3-3H7a3 3 0 0 0-3 3v7a3 3 0 0 0 3 3"></path></svg>
|
|
</div>
|
|
<div class="active-indicator"></div>
|
|
</NuxtLink>
|
|
|
|
<NuxtLink to="/docs" class="menu-item" active-class="active" title="使用教程">
|
|
<div class="icon-box">
|
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M4 19a2 2 0 0 1 2-2h5v4H6a2 2 0 0 1-2-2z"></path><path d="M20 19a2 2 0 0 0-2-2h-5v4h5a2 2 0 0 0 2-2z"></path><path d="M6 3h5v10H6a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2z"></path><path d="M18 3h-5v10h5a2 2 0 0 0 2-2V5a2 2 0 0 0-2-2z"></path></svg>
|
|
</div>
|
|
<div class="active-indicator"></div>
|
|
</NuxtLink>
|
|
</nav>
|
|
|
|
<!-- Bottom Actions -->
|
|
<nav class="sidebar-menu bottom-menu">
|
|
<NuxtLink to="/favorites" class="menu-item" active-class="active" title="我的收藏">
|
|
<div class="icon-box">
|
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M20.8 6.1a5 5 0 0 0-7.1 0L12 7.8l-1.7-1.7a5 5 0 0 0-7.1 7.1l1.7 1.7L12 21l7.1-7.1 1.7-1.7a5 5 0 0 0 0-7.1z"></path></svg>
|
|
</div>
|
|
<div class="active-indicator"></div>
|
|
</NuxtLink>
|
|
|
|
<ClientOnly>
|
|
<div class="auth-item" :key="isLoggedIn ? 'in' : 'out'">
|
|
<template v-if="isLoggedIn">
|
|
<div class="auth-actions">
|
|
<button type="button" class="avatar-btn" @click="goProfile" title="个人中心">
|
|
<div class="avatar-img">
|
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"></path><circle cx="12" cy="7" r="4"></circle></svg>
|
|
</div>
|
|
</button>
|
|
<button type="button" class="logout-btn" @click="handleLogout" title="退出登录">
|
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
|
|
<path d="M15 3h4a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2h-4"/>
|
|
<polyline points="10 17 15 12 10 7"/>
|
|
<line x1="15" y1="12" x2="3" y2="12"/>
|
|
</svg>
|
|
</button>
|
|
</div>
|
|
</template>
|
|
<template v-else>
|
|
<button type="button" class="login-btn" @click="goLogin" title="登录">
|
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M15 3h4a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2h-4"></path><polyline points="10 17 15 12 10 7"></polyline><line x1="15" y1="12" x2="3" y2="12"></line></svg>
|
|
</button>
|
|
</template>
|
|
</div>
|
|
</ClientOnly>
|
|
|
|
<!-- Collapse Button -->
|
|
<button type="button" class="collapse-btn" @click="toggleCollapse" title="收起导航">
|
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="15 18 9 12 15 6"></polyline></svg>
|
|
</button>
|
|
</nav>
|
|
</aside>
|
|
|
|
<!-- Collapsed State (Half-Dashboard Button) -->
|
|
<div
|
|
class="sidebar-collapsed-trigger"
|
|
:class="{ 'is-visible': isCollapsed }"
|
|
@click="toggleCollapse"
|
|
title="展开导航"
|
|
>
|
|
<div class="trigger-inner">
|
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3" width="7" height="7"></rect><rect x="14" y="3" width="7" height="7"></rect><rect x="14" y="14" width="7" height="7"></rect><rect x="3" y="14" width="7" height="7"></rect></svg>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { ref, computed, onMounted, onBeforeUnmount, watch } from 'vue'
|
|
import { navigateTo } from '#app'
|
|
import { useRoute } from 'vue-router'
|
|
import { useAuth } from '@/composables/useAuth'
|
|
import { useAuthToken } from '@/composables/useApi'
|
|
import { useToast } from '@/composables/useToast'
|
|
|
|
const { token } = useAuthToken()
|
|
const route = useRoute()
|
|
const isLoggedIn = computed(() => !!token.value)
|
|
const { logout } = useAuth()
|
|
const toast = useToast()
|
|
|
|
const isCollapsed = ref(true)
|
|
const userToggled = ref(false)
|
|
|
|
const toggleCollapse = () => {
|
|
isCollapsed.value = !isCollapsed.value
|
|
userToggled.value = true
|
|
}
|
|
|
|
const goLogin = () => navigateTo('/login')
|
|
const goProfile = () => navigateTo('/profile')
|
|
|
|
onMounted(() => {
|
|
checkScroll()
|
|
window.addEventListener('scroll', handleScroll)
|
|
window.addEventListener('keydown', handleKeydown)
|
|
})
|
|
|
|
onBeforeUnmount(() => {
|
|
window.removeEventListener('scroll', handleScroll)
|
|
window.removeEventListener('keydown', handleKeydown)
|
|
})
|
|
|
|
watch(
|
|
() => route.path,
|
|
() => {
|
|
userToggled.value = false
|
|
checkScroll()
|
|
},
|
|
)
|
|
|
|
function handleScroll() {
|
|
if (userToggled.value) return
|
|
checkScroll()
|
|
}
|
|
|
|
function checkScroll() {
|
|
const scrollTop = window.scrollY || document.documentElement.scrollTop
|
|
// If at top (within 50px), collapse. Otherwise, expand.
|
|
isCollapsed.value = scrollTop < 50
|
|
}
|
|
|
|
function handleKeydown(e: KeyboardEvent) {
|
|
if (e.key === 'Escape') {
|
|
isCollapsed.value = true
|
|
userToggled.value = true
|
|
}
|
|
}
|
|
|
|
async function handleLogout() {
|
|
try {
|
|
await logout()
|
|
} finally {
|
|
toast.success('已退出登录', '期待下次再见')
|
|
navigateTo('/login')
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style scoped>
|
|
/* --- Wrapper to manage layout space if needed --- */
|
|
.sidebar-wrapper {
|
|
position: fixed;
|
|
left: 0;
|
|
top: 0;
|
|
height: 100vh;
|
|
z-index: 999;
|
|
pointer-events: none; /* Let clicks pass through wrapper */
|
|
}
|
|
|
|
.sidebar-wrapper > * {
|
|
pointer-events: auto; /* Re-enable clicks on children */
|
|
}
|
|
|
|
/* --- Expanded Sidebar (Nebula Glass) --- */
|
|
.sidebar-nebula {
|
|
position: absolute;
|
|
left: 24px;
|
|
top: 134px;
|
|
bottom: 24px;
|
|
width: var(--sidebar-width-expanded, 80px);
|
|
background: rgba(255, 255, 255, 0);
|
|
backdrop-filter: blur(20px);
|
|
-webkit-backdrop-filter: blur(20px);
|
|
border-radius: var(--sidebar-radius, 40px);
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
padding: 24px 0;
|
|
|
|
/* Lighting & Shadows */
|
|
border: 1px solid var(--color-glass-border, rgba(255, 255, 255, 0.8));
|
|
box-shadow: var(--shadow-glass-floating);
|
|
|
|
transition: transform var(--duration-normal, 0.3s) var(--ease-out-back), opacity 0.2s ease;
|
|
transform-origin: left center;
|
|
}
|
|
|
|
.sidebar-nebula.is-hidden {
|
|
transform: translateX(-150%) scale(0.9);
|
|
opacity: 0;
|
|
pointer-events: none;
|
|
}
|
|
|
|
/* Optional Noise Texture */
|
|
.sidebar-nebula::before {
|
|
content: "";
|
|
position: absolute;
|
|
inset: 0;
|
|
border-radius: var(--sidebar-radius, 40px);
|
|
background: radial-gradient(circle at top left, rgba(255,255,255,0.4), transparent 70%);
|
|
pointer-events: none;
|
|
z-index: -1;
|
|
}
|
|
|
|
/* Logo Area */
|
|
.sidebar-logo {
|
|
margin-bottom: 36px;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.logo-btn {
|
|
width: 48px;
|
|
height: 48px;
|
|
border-radius: 16px;
|
|
background: rgba(255, 255, 255, 0.9);
|
|
backdrop-filter: blur(10px);
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
box-shadow: 0 4px 12px rgba(15, 23, 42, 0.06);
|
|
cursor: pointer;
|
|
transition: transform 0.2s ease, box-shadow 0.2s ease;
|
|
border: 1px solid rgba(255, 255, 255, 0.6);
|
|
}
|
|
.logo-btn:hover {
|
|
transform: scale(1.05);
|
|
box-shadow: 0 8px 18px rgba(15, 23, 42, 0.12);
|
|
}
|
|
|
|
.brand-logo {
|
|
width: 32px;
|
|
height: 32px;
|
|
background: url("../assets/logoleft.png") no-repeat center/contain;
|
|
}
|
|
|
|
/* Menu Layout */
|
|
.sidebar-menu {
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
gap: 16px;
|
|
width: 100%;
|
|
}
|
|
|
|
.main-menu {
|
|
flex: 1;
|
|
}
|
|
|
|
.bottom-menu {
|
|
margin-top: auto;
|
|
gap: 16px;
|
|
padding-top: 24px;
|
|
border-top: 1px solid rgba(255, 255, 255, 0.3);
|
|
width: 60%;
|
|
}
|
|
.bottom-menu .menu-item,
|
|
.bottom-menu .auth-item,
|
|
.collapse-btn {
|
|
width: 100%;
|
|
display: flex;
|
|
justify-content: center;
|
|
}
|
|
|
|
/* Menu Item Styles */
|
|
.menu-item {
|
|
position: relative;
|
|
width: 56px;
|
|
height: 56px;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
text-decoration: none;
|
|
color: var(--color-text-sub, #64748b);
|
|
transition: all 0.3s var(--ease-smooth);
|
|
}
|
|
|
|
.menu-item::after {
|
|
content: attr(title);
|
|
position: absolute;
|
|
left: 64px;
|
|
white-space: nowrap;
|
|
background: #0b1221;
|
|
color: #e5e7eb;
|
|
padding: 8px 12px;
|
|
border-radius: 12px;
|
|
font-size: 12px;
|
|
letter-spacing: 0.2px;
|
|
border: 1px solid rgba(255, 255, 255, 0.08);
|
|
box-shadow: 0 12px 28px rgba(15, 23, 42, 0.25);
|
|
opacity: 0;
|
|
pointer-events: none;
|
|
transform: translateY(4px);
|
|
transition: opacity 0.18s ease, transform 0.18s ease;
|
|
z-index: 10;
|
|
}
|
|
|
|
.menu-item:hover::after {
|
|
opacity: 1;
|
|
transform: translateY(0);
|
|
backdrop-filter: blur(6px);
|
|
}
|
|
|
|
/* Tooltip for auth buttons */
|
|
.avatar-btn::after,
|
|
.login-btn::after,
|
|
.logout-btn::after {
|
|
content: attr(title);
|
|
position: absolute;
|
|
left: 62px;
|
|
white-space: nowrap;
|
|
background: #0b1221;
|
|
color: #e5e7eb;
|
|
padding: 8px 12px;
|
|
border-radius: 12px;
|
|
font-size: 12px;
|
|
letter-spacing: 0.2px;
|
|
border: 1px solid rgba(255, 255, 255, 0.08);
|
|
box-shadow: 0 12px 28px rgba(15, 23, 42, 0.25);
|
|
opacity: 0;
|
|
pointer-events: none;
|
|
transform: translateY(4px);
|
|
transition: opacity 0.18s ease, transform 0.18s ease;
|
|
z-index: 10;
|
|
}
|
|
|
|
.avatar-btn:hover::after,
|
|
.login-btn:hover::after,
|
|
.logout-btn:hover::after {
|
|
opacity: 1;
|
|
transform: translateY(0);
|
|
backdrop-filter: blur(6px);
|
|
}
|
|
|
|
.icon-box {
|
|
width: 52px;
|
|
height: 52px;
|
|
border-radius: 18px;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
transition: all 0.3s ease;
|
|
position: relative;
|
|
z-index: 2;
|
|
background: transparent;
|
|
}
|
|
|
|
.icon-box svg {
|
|
width: 24px;
|
|
height: 24px;
|
|
stroke-width: 1.5px;
|
|
transition: all 0.3s ease;
|
|
}
|
|
|
|
/* Hover State */
|
|
.menu-item:hover .icon-box {
|
|
background: var(--color-glass-hover, rgba(255, 255, 255, 0.85));
|
|
border-radius: 18px;
|
|
box-shadow: 0 0 12px rgba(255, 255, 255, 0.6);
|
|
color: var(--color-text-main, #1e293b);
|
|
transform: translateY(-2px);
|
|
}
|
|
|
|
/* Active State */
|
|
.menu-item.active .icon-box {
|
|
background: linear-gradient(135deg, var(--color-primary-start), var(--color-primary-end));
|
|
border-radius: 20px;
|
|
color: var(--color-text-active, #fff);
|
|
box-shadow:
|
|
inset 0 1px 0 rgba(255, 255, 255, 0.3),
|
|
0 8px 20px -4px rgba(99, 102, 241, 0.45);
|
|
}
|
|
|
|
/* Right Side Indicator (The Beam) */
|
|
.active-indicator {
|
|
position: absolute;
|
|
right: -12px;
|
|
top: 50%;
|
|
transform: translateY(-50%) scaleY(0);
|
|
width: 3px;
|
|
height: 24px;
|
|
background: var(--color-accent-beam, #a855f7);
|
|
border-radius: 2px;
|
|
box-shadow: var(--shadow-neon-glow);
|
|
transition: transform 0.3s var(--ease-out-back), opacity 0.3s ease;
|
|
opacity: 0;
|
|
}
|
|
|
|
.menu-item.active .active-indicator {
|
|
transform: translateY(-50%) scaleY(1);
|
|
opacity: 1;
|
|
}
|
|
|
|
/* Auth / Avatar */
|
|
.auth-item {
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
gap: 10px;
|
|
}
|
|
|
|
.avatar-btn,
|
|
.login-btn,
|
|
.collapse-btn {
|
|
width: 48px;
|
|
height: 48px;
|
|
border-radius: 18px;
|
|
border: none;
|
|
background: rgba(255, 255, 255, 0.55);
|
|
cursor: pointer;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
color: var(--color-text-sub, #64748b);
|
|
transition: all 0.3s ease;
|
|
}
|
|
|
|
.avatar-btn:hover,
|
|
.login-btn:hover,
|
|
.collapse-btn:hover {
|
|
background: #ffffff;
|
|
box-shadow: 0 4px 14px rgba(15, 23, 42, 0.12);
|
|
color: var(--color-primary-end, #3b82f6);
|
|
transform: scale(1.05);
|
|
}
|
|
|
|
.avatar-img svg,
|
|
.login-btn svg,
|
|
.collapse-btn svg {
|
|
width: 22px;
|
|
height: 22px;
|
|
}
|
|
|
|
.auth-actions {
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
gap: 8px;
|
|
}
|
|
|
|
.logout-btn {
|
|
width: 48px;
|
|
height: 48px;
|
|
border-radius: 16px;
|
|
border: 1px solid rgba(229, 231, 235, 0.9);
|
|
background: #fff;
|
|
cursor: pointer;
|
|
font-size: 12px;
|
|
color: #ef4444;
|
|
transition: all 0.2s ease;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
}
|
|
|
|
.logout-btn:hover {
|
|
background: #fff7f7;
|
|
box-shadow: 0 6px 14px rgba(239, 68, 68, 0.18);
|
|
transform: translateY(-1px);
|
|
}
|
|
|
|
.logout-btn svg {
|
|
width: 22px;
|
|
height: 22px;
|
|
stroke: #ef4444;
|
|
}
|
|
|
|
/* --- Collapsed Trigger (Half-Dashboard) --- */
|
|
.sidebar-collapsed-trigger {
|
|
position: absolute;
|
|
left: 0;
|
|
top: 90%;
|
|
transform: translateY(-50%) translateX(-100%);
|
|
width: 70px;
|
|
height: 70px;
|
|
border-radius: 0 36px 36px 0; /* Half circle on right */
|
|
background: linear-gradient(145deg, #c8d8ff, #9b8cff 45%, #f5d3ff);
|
|
box-shadow: 0 14px 36px rgba(142, 123, 255, 0.35), 0 0 0 6px rgba(255, 255, 255, 0.45);
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
padding-left: 8px;
|
|
cursor: pointer;
|
|
transition: transform var(--duration-normal) var(--ease-out-back), box-shadow 0.2s ease;
|
|
z-index: 1000;
|
|
opacity: 0;
|
|
}
|
|
|
|
.sidebar-collapsed-trigger.is-visible {
|
|
transform: translateY(-50%) translateX(0);
|
|
opacity: 1;
|
|
}
|
|
|
|
.sidebar-collapsed-trigger:hover {
|
|
transform: translateY(-50%) translateX(6px) scale(1.02); /* Slight peek */
|
|
box-shadow: 0 18px 40px rgba(142, 123, 255, 0.45), 0 0 0 8px rgba(255, 255, 255, 0.52);
|
|
}
|
|
|
|
.sidebar-collapsed-trigger:active {
|
|
transform: translateY(-50%) translateX(2px) scale(0.99);
|
|
}
|
|
|
|
.trigger-inner {
|
|
width: 40px;
|
|
height: 40px;
|
|
border-radius: 14px;
|
|
background: rgba(255, 255, 255, 0.9);
|
|
display: grid;
|
|
place-items: center;
|
|
color: #0f172a;
|
|
box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.55), 0 8px 18px rgba(87, 71, 199, 0.35);
|
|
}
|
|
|
|
.trigger-inner svg {
|
|
width: 24px;
|
|
height: 24px;
|
|
}
|
|
|
|
/* ===== Mobile Bottom Nav Adaptation ===== */
|
|
@media (max-width: 640px) {
|
|
.sidebar-wrapper {
|
|
position: absolute; /* Reset fixed */
|
|
height: 100%;
|
|
width: 100%;
|
|
z-index: auto;
|
|
}
|
|
|
|
.sidebar-nebula {
|
|
position: static; /* Reset absolute */
|
|
width: 100%;
|
|
height: 100%;
|
|
border-radius: 0;
|
|
border: none;
|
|
box-shadow: none;
|
|
background: transparent;
|
|
flex-direction: row;
|
|
padding: 0 12px;
|
|
justify-content: space-around;
|
|
align-items: center;
|
|
transform: none !important; /* Disable collapse transform */
|
|
opacity: 1 !important;
|
|
}
|
|
|
|
.sidebar-nebula::before {
|
|
display: none;
|
|
}
|
|
|
|
.sidebar-logo,
|
|
.collapse-btn,
|
|
.sidebar-collapsed-trigger {
|
|
display: none !important;
|
|
}
|
|
|
|
.sidebar-menu {
|
|
flex-direction: row;
|
|
width: auto;
|
|
gap: 4px;
|
|
}
|
|
|
|
.main-menu {
|
|
flex: 1;
|
|
justify-content: space-around;
|
|
}
|
|
|
|
.bottom-menu {
|
|
margin-top: 0;
|
|
padding-top: 0;
|
|
border-top: none;
|
|
width: auto;
|
|
gap: 4px;
|
|
}
|
|
|
|
.menu-item {
|
|
width: 44px;
|
|
height: 44px;
|
|
}
|
|
|
|
.menu-item::after {
|
|
display: none; /* No tooltips on mobile */
|
|
}
|
|
|
|
.icon-box {
|
|
width: 40px;
|
|
height: 40px;
|
|
}
|
|
|
|
.auth-item {
|
|
flex-direction: row;
|
|
}
|
|
|
|
.auth-actions {
|
|
flex-direction: row;
|
|
}
|
|
|
|
.avatar-btn, .login-btn, .logout-btn {
|
|
width: 40px;
|
|
height: 40px;
|
|
}
|
|
}
|
|
</style>
|