feat(project): 아사나식 프로젝트/서브프로젝트 트리 사이드바

좌측 사이드바를 직속 서브 평면 목록 → 전체 프로젝트 재귀 트리로 교체.
- 접기/펼치기 캐럿(localStorage 로 펼침 상태 저장, 활성 프로젝트 상위 자동 펼침)
- 프로젝트 색상 아이콘, 들여쓰기(depth), 활성 프로젝트 강조
- hover 시 서브추가(+)/삭제(×) 액션(관리자·멤버, 서버 권한 검증)
- 상단 '새 프로젝트'(관리자). Material Symbols 아이콘(self-host) 사용.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-25 13:09:17 +09:00
parent 57b4b37468
commit 64dd7445bc
5 changed files with 149 additions and 41 deletions
+24 -5
View File
@@ -60,13 +60,32 @@
.pj-side-block { margin-bottom: 22px; }
.pj-side-head { display: flex; align-items: center; justify-content: space-between; font-size: 12px; font-weight: 700; color: #6b7280; text-transform: uppercase; letter-spacing: .04em; margin-bottom: 8px; }
.pj-sub-list, .pj-member-list { list-style: none; margin: 0; padding: 0; }
.pj-sub-list li, .pj-member-list li { display: flex; align-items: center; gap: 8px; padding: 5px 4px; border-radius: 7px; }
.pj-sub-list li:hover, .pj-member-list li:hover { background: #f6f7f8; }
.pj-sub-list a { display: flex; align-items: center; gap: 8px; text-decoration: none; color: inherit; font-size: 13.5px; flex: 1; }
.pj-sub-dot { width: 8px; height: 8px; border-radius: 50%; }
.pj-member-list { list-style: none; margin: 0; padding: 0; }
.pj-member-list li { display: flex; align-items: center; gap: 8px; padding: 5px 4px; border-radius: 7px; }
.pj-member-list li:hover { background: #f6f7f8; }
.pj-member-name { font-size: 13px; flex: 1; }
/* ── 아사나식 프로젝트 트리 ── */
.pj-tree { list-style: none; margin: 0; padding: 0; }
.pj-tree .pj-tree { padding-left: 0; } /* 들여쓰기는 row 패딩으로 처리 */
.pj-tree-row { display: flex; align-items: center; gap: 2px; border-radius: 7px; padding-right: 2px;
padding-left: calc(var(--pj-indent, 0) * 16px); position: relative; }
.pj-tree-row:hover { background: #f1f2f4; }
.pj-tree-row.is-active { background: #ececf8; }
.pj-tree-row.is-active .pj-tree-name { font-weight: 700; color: #1e1f21; }
.pj-tree-caret { border: none; background: transparent; cursor: pointer; width: 20px; height: 26px;
display: inline-flex; align-items: center; justify-content: center; color: #6b7280; padding: 0; }
.pj-tree-caret .material-symbols-outlined { font-size: 18px; transition: transform .12s; }
.pj-tree-caret.is-open .material-symbols-outlined { transform: rotate(90deg); }
.pj-tree-caret-spacer { width: 20px; flex: 0 0 auto; }
.pj-tree-link { display: flex; align-items: center; gap: 7px; flex: 1; min-width: 0;
text-decoration: none; color: inherit; padding: 5px 2px; }
.pj-tree-icon { font-size: 18px; flex: 0 0 auto; }
.pj-tree-name { font-size: 13.5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pj-tree-acts { display: none; gap: 0; flex: 0 0 auto; }
.pj-tree-row:hover .pj-tree-acts { display: inline-flex; }
.pj-tree-acts .pj-icon-btn { width: 22px; height: 22px; font-size: 14px; }
/* 구글 머티리얼 심볼 아이콘(담당자) */
.material-symbols-outlined { font-variation-settings: 'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 24; line-height: 1; vertical-align: middle; }
.pj-gicon { font-size: 24px; color: #5f6368; flex: 0 0 auto; }