diff --git a/frontend/src/App.css b/frontend/src/App.css
index 9d9188e..f3d8c96 100644
--- a/frontend/src/App.css
+++ b/frontend/src/App.css
@@ -187,6 +187,7 @@ html.theme-blue {
padding: 0 12px;
gap: 4px;
z-index: 200;
+ position: relative;
}
/* 로고 */
@@ -227,6 +228,85 @@ html.theme-blue {
flex: 1;
min-width: 0;
}
+.tmb-nav--groups {
+ flex: 0 1 auto;
+ min-width: 0;
+}
+.tmb-nav-group {
+ position: relative;
+ flex-shrink: 0;
+}
+.tmb-nav-group-btn {
+ padding-right: 8px;
+}
+.tmb-nav-group-btn--open {
+ background: var(--bg4);
+ color: var(--text);
+}
+.tmb-nav-chevron {
+ display: inline-flex;
+ align-items: center;
+ opacity: 0.65;
+ margin-left: 1px;
+ transition: transform 0.15s ease;
+}
+.tmb-nav-chevron--open {
+ transform: rotate(180deg);
+}
+.tmb-nav-dropdown {
+ position: absolute;
+ top: calc(100% + 6px);
+ left: 0;
+ min-width: 168px;
+ padding: 4px;
+ background: var(--bg2);
+ border: 1px solid var(--border);
+ border-radius: 8px;
+ box-shadow: 0 8px 24px rgba(0, 0, 0, 0.28);
+ z-index: 400;
+}
+.tmb-nav-dropdown-item {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ width: 100%;
+ min-height: 36px;
+ padding: 0 10px;
+ border: none;
+ border-radius: 6px;
+ background: none;
+ color: var(--text2);
+ font-size: 13px;
+ font-weight: 500;
+ text-align: left;
+ cursor: pointer;
+ transition: background 0.12s, color 0.12s;
+}
+.tmb-nav-dropdown-item:hover {
+ background: var(--bg4);
+ color: var(--text);
+}
+.tmb-nav-dropdown-item--active {
+ background: rgba(var(--accent-rgb, 122, 162, 247), 0.12);
+ color: var(--accent);
+}
+.app.dark .tmb-nav-dropdown-item--active { background: rgba(122, 162, 247, 0.13); }
+.app.blue .tmb-nav-dropdown-item--active { background: rgba(94, 181, 255, 0.13); }
+.app.light .tmb-nav-dropdown-item--active { background: rgba(25, 118, 210, 0.10); }
+.tmb-nav-dropdown-icon {
+ display: flex;
+ align-items: center;
+ flex-shrink: 0;
+ opacity: 0.85;
+}
+.tmb-nav-dropdown-label {
+ flex: 1;
+ white-space: nowrap;
+}
+.tmb-notify-badge--dropdown {
+ position: static;
+ margin-left: auto;
+}
.tmb-nav-btn {
position: relative; /* 알림 뱃지 absolute 기준점 */
display: inline-flex;
@@ -269,6 +349,7 @@ html.theme-blue {
align-items: center;
gap: 0;
flex-shrink: 0;
+ margin-left: auto;
}
/* 테마 버튼 */
@@ -12878,20 +12959,24 @@ html.theme-light .tam-disclaimer { color: #90a4ae; }
}
.app--mobile .top-menubar::-webkit-scrollbar { display: none; }
.app--mobile .tmb-logo-text { display: none; }
-.app--mobile .tmb-nav {
+.app--mobile .tmb-nav--groups {
flex: 1;
min-width: 0;
overflow-x: auto;
-webkit-overflow-scrolling: touch;
scrollbar-width: none;
}
-.app--mobile .tmb-nav::-webkit-scrollbar { display: none; }
-.app--mobile .tmb-nav-btn {
- flex-shrink: 0;
- padding: 6px 10px;
+.app--mobile .tmb-nav-group-btn .tmb-nav-label {
+ display: inline;
font-size: 11px;
}
-.app--mobile .tmb-nav-label { display: none; }
+.app--mobile .tmb-nav-dropdown {
+ min-width: 152px;
+}
+.app--mobile .tmb-nav-dropdown-item {
+ min-height: 40px;
+ font-size: 12px;
+}
.app--mobile .tmb-theme-label,
.app--mobile .tmb-login-btn span { display: none; }
.app--mobile .tmb-right { flex-shrink: 0; }
diff --git a/frontend/src/components/TopMenuBar.tsx b/frontend/src/components/TopMenuBar.tsx
index c4b528a..9116de6 100644
--- a/frontend/src/components/TopMenuBar.tsx
+++ b/frontend/src/components/TopMenuBar.tsx
@@ -2,15 +2,16 @@
* 최상단 글로벌 메뉴바
*
* 레이아웃:
- * [로고] | [대시보드] [실시간차트] [전략편집기] … | [테마토글] [로그인]
+ * [로고] | [그룹메뉴 ▾] … | [테마토글] [로그인]
*/
-import React, { memo, useCallback, useEffect, useState } from 'react';
+import React, { memo, useEffect, useState } from 'react';
import type { Theme } from '../types';
import type { AuthSession } from '../utils/auth';
import type { TradeAlertPopupLayout, TradeAlertPopupPosition } from '../utils/tradeAlertPopupLayout';
import { canAccessMenu } from '../utils/permissions';
import { isDesktop } from '../utils/platform';
import DesktopUpdateModal from './DesktopUpdateModal';
+import TopMenuBarNavGroups from './TopMenuBarNavGroups';
export type MenuPage = 'dashboard' | 'chart' | 'paper' | 'virtual' | 'trend-search' | 'verification-board' | 'strategy' | 'strategy-editor' | 'strategy-evaluation' | 'backtest' | 'analysis-report' | 'notifications' | 'settings' | 'widget-dashboard';
@@ -244,6 +245,34 @@ const MENU_ITEMS: { page: MenuPage; label: string; icon: React.ReactNode }[] = [
{ page: 'verification-board', label: '검증게시판', icon: