diff --git a/frontend/src/layouts/AppShell.vue b/frontend/src/layouts/AppShell.vue
index 9859959..5a6dd5f 100644
--- a/frontend/src/layouts/AppShell.vue
+++ b/frontend/src/layouts/AppShell.vue
@@ -35,9 +35,6 @@ const activeNav = computed<'tasks' | 'projects'>(() =>
// 현재 로그인 사용자(프로필 아바타는 UserAvatar 가 이미지/placeholder 로 표시)
const me = computed(() => authStore.user)
-// 사용자 메뉴 토글
-const menuOpen = ref(false)
-
// --- 알림(실시간 SSE) ---
const notiStore = useNotificationStore()
const {
@@ -73,7 +70,6 @@ onMounted(() => {
// 로그아웃 → 알림 스트림 해제 후 로그인 화면으로
async function onLogout() {
- menuOpen.value = false
notiStore.disconnect()
await authStore.logout()
await router.push('/login')
@@ -198,14 +194,9 @@ async function onLogout() {
>
사이드바 접기
-
-
-
-
+
+
@@ -451,7 +444,7 @@ async function onLogout() {
.shell.collapsed .nav-item span {
display: none;
}
-.shell.collapsed .side-me {
+.shell.collapsed .side-user {
justify-content: center;
padding-left: 0;
padding-right: 0;
@@ -459,6 +452,14 @@ async function onLogout() {
.shell.collapsed .side-me-text {
display: none;
}
+.shell.collapsed .logout-btn {
+ justify-content: center;
+ padding-left: 0;
+ padding-right: 0;
+}
+.shell.collapsed .logout-btn span {
+ display: none;
+}
.shell.collapsed .collapse-btn {
justify-content: center;
padding-left: 0;
@@ -470,11 +471,6 @@ async function onLogout() {
.shell.collapsed .collapse-btn svg {
transform: rotate(180deg);
}
-/* 접힘 상태에서 사용자 메뉴는 레일 오른쪽으로 펼침 */
-.shell.collapsed .side-menu {
- left: 0.5rem;
- right: auto;
-}
.brand {
display: flex;
@@ -569,25 +565,44 @@ async function onLogout() {
flex-shrink: 0;
transition: transform 0.18s ease;
}
-.side-me {
+.side-user {
display: flex;
align-items: center;
gap: 0.5625rem;
width: 100%;
padding: 0.4375rem 0.5rem;
+}
+.side-user > :first-child {
+ width: 1.875rem;
+ height: 1.875rem;
+ flex-shrink: 0;
+}
+/* 로그아웃 — 항상 노출되는 버튼 */
+.logout-btn {
+ display: flex;
+ align-items: center;
+ gap: 0.6875rem;
+ width: 100%;
+ margin-top: 0.25rem;
+ padding: 0.5rem 0.75rem;
border: none;
background: transparent;
border-radius: var(--radius);
+ color: var(--text-2);
cursor: pointer;
font-family: inherit;
- text-align: left;
+ font-size: 0.8125rem;
+ font-weight: 500;
+ line-height: 1;
+ white-space: nowrap;
}
-.side-me:hover {
- background: #f1f2f4;
+.logout-btn:hover {
+ background: var(--red-weak);
+ color: var(--red);
}
-.side-me > :first-child {
- width: 1.875rem;
- height: 1.875rem;
+.logout-btn svg {
+ width: 1.125rem;
+ height: 1.125rem;
flex-shrink: 0;
}
.side-me-text {
@@ -823,43 +838,6 @@ async function onLogout() {
z-index: 55;
}
-/* 사용자 드롭다운(사이드바 하단 → 위로 펼침) */
-.me-menu {
- position: absolute;
- z-index: 60;
- min-width: 11rem;
- background: var(--panel);
- border: 1px solid var(--border);
- border-radius: var(--radius-sm);
- box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
- overflow: hidden;
-}
-.side-menu {
- left: 0.625rem;
- right: 0.625rem;
- bottom: calc(100% - 0.25rem);
-}
-.me-action {
- width: 100%;
- text-align: left;
- padding: 0.625rem 0.875rem;
- border: none;
- background: transparent;
- font-family: inherit;
- font-size: 0.844rem;
- color: var(--text);
- cursor: pointer;
-}
-.me-action:hover {
- background: #f1f2f4;
-}
-/* 메뉴 바깥 클릭 감지용 투명 오버레이 */
-.me-overlay {
- position: fixed;
- inset: 0;
- z-index: 55;
-}
-
/* 햄버거(모바일 전용) / 드로어 배경 — 데스크톱에서는 숨김 */
.hamburger {
display: none;
@@ -896,7 +874,8 @@ async function onLogout() {
/* 접힘 축소 규칙 무효화(드로어는 항상 펼친 모양) */
.shell.collapsed .brand,
.shell.collapsed .nav-item,
- .shell.collapsed .side-me,
+ .shell.collapsed .side-user,
+ .shell.collapsed .logout-btn,
.shell.collapsed .collapse-btn {
justify-content: flex-start;
padding-left: 0.75rem;
@@ -904,7 +883,7 @@ async function onLogout() {
}
.shell.collapsed .brand-name,
.shell.collapsed .nav-item span,
- .shell.collapsed .side-me-text {
+ .shell.collapsed .logout-btn span {
display: inline;
}
.shell.collapsed .side-me-text {
@@ -913,6 +892,10 @@ async function onLogout() {
.shell.collapsed .brand {
padding-left: 1.125rem;
}
+ .shell.collapsed .side-user {
+ padding-left: 0.5rem;
+ padding-right: 0.5rem;
+ }
.sidebar-backdrop {
display: block;
position: fixed;