Side Navigation
데스크톱(768 이상)의 주 메뉴 — 화면 왼쪽의 세로 띠(사이드바)에 서비스의 최상위 화면들을 묶어 둔다. 1280 이상은 펼침 240, 768 ~ 1279 는 아이콘만 56 으로 저절로 접히고, 손으로 접고 펼 수 있다. 768 미만에서는 없다 — Desk 웹은 Bottom Navigation, HR 은 ☰ 로 여는 왼쪽 Side Panel 에 같은 항목을 담는다. 다른 이동 부품(Top Navigation · Tabs)과 고르는 표는 DESIGN.md Layout 의 "이동 부품 고르기" 한 곳이다.
구조는 당근 SEED Side Navigation(Apache-2.0)을 따른다 — "서비스의 최상위 메뉴 간 이동을 돕고 앱의 전체 구조를 탐색할 수 있게 하는 컴포넌트" 로, 머리(Header) · 접기 버튼(Trigger) · 내용(Content) · 묶음(Group) · 항목(Menu Item) · 하위 항목(Menu Sub Item) · 바닥(Footer). 폭 240 · 56 · 머리 64 · 항목 44 · 아이콘 20 · 이름 14 / 19 · 500 · 모서리 10 은 SEED 값 그대로다(SEED 는 rootage 없이 레시피에 px 로 둔다). 값은 groo 토큰이고, SEED 와 다른 자리는 맨 아래 "SEED 와 다른 점" 에 적었다(2026-10-04 사용자 결정). 옛 Sidebar 스펙(shadcn — 256 · 48 · 항목 32)을 대신한다.
수치 원본은 side-navigation.yaml이다. 수치 표 자리([표: …])와 그림 자리([그림: …])는 사이트가 그 파일로 그린다 — GitHub 에서는 그 파일 · 그림 코드로 가는 링크로 보인다.
직접 골라 보기
창 폭(768 ~ 1279 · 1280 이상) · 손으로 접기 · 지금 화면 · 하위가 있는 항목 · 긴 이름 · 서비스(Desk · HR)를 고르면 스펙대로 그린 사이드바와 그 코드가 바뀐다. 접힌 사이드바에서 항목에 마우스를 올리면 이름 말풍선이, 하위가 있는 항목은 펼침 메뉴가 열린다.
import { CalendarDays, ClipboardList, LayoutGrid, TrendingUp, Wallet } from "lucide-react"
import {
SideNavigation, SideNavigationContent, SideNavigationGroup, SideNavigationHeader, SideNavigationItem, SideNavigationSubItem,
} from "@/components/ui/side-navigation"
{/* 창 폭 1440 — 1280 이상은 펼침 240. 손으로 접은 상태는 localStorage(groo:side-navigation-collapsed)에 기억 */}
<SideNavigation>
<SideNavigationHeader logo={<ServiceLogo name="그루 담다" />} />
<SideNavigationContent>
<SideNavigationGroup label="워크스페이스">
<SideNavigationItem href="/desk/home" icon={<LayoutGrid />} label="홈" current={path === "/desk/home"} />
<SideNavigationItem href="/desk/assets" icon={<Wallet />} label="자산" current={path === "/desk/assets"} />
<SideNavigationItem icon={<TrendingUp />} label="증권">
<SideNavigationSubItem href="/desk/stocks/namu" label="나무증권" current={path === "/desk/stocks/namu"} />
<SideNavigationSubItem href="/desk/stocks/toss" label="토스증권" current={path === "/desk/stocks/toss"} />
</SideNavigationItem>
<SideNavigationItem href="/desk/ledger" icon={<ClipboardList />} label="가계부" current={path === "/desk/ledger"} />
</SideNavigationGroup>
<SideNavigationGroup label="기록">
<SideNavigationItem href="/desk/calendar" icon={<CalendarDays />} label="캘린더" current={path === "/desk/calendar"} />
</SideNavigationGroup>
</SideNavigationContent>
</SideNavigation>Anatomy
| 부위 | 설명 |
|---|---|
| ⓐ Root | 사이드바 — 화면 왼쪽, 높이 전체. 흰 면 + 오른쪽 1px 선. 본문과 따로 스크롤된다. |
| ⓑ Header | 머리 — 서비스 마크 · 이름과 접기 버튼. 고정. |
| ⓒ Trigger | 접기 버튼 — 펼침 ↔ 접힘. |
| ⓓ Content | 내용 — 묶음과 항목. 넘치면 이 안에서만 스크롤하고, 머리 아래 선 · 아래 끝 흐림이 생긴다. |
| ⓔ Group | 묶음 — 이름(있을 때만)과 항목 여럿. |
| ⓕ Item | 항목 — 아이콘 + 이름. 하위가 있으면 꺾쇠. |
| ⓖ Sub Item | 하위 항목 — 아이콘 없이 이름만. |
| ⓗ Footer | 바닥 — 보조 링크(설명서 · 문의). 고정, 비면 없다. 계정은 두지 않는다(그루 이음은 예외 — 계정 줄 + 메뉴, 아래 "바닥"). |
부위
| 부위 | 설명 |
|---|---|
root | 사이드바 — 화면 왼쪽, 높이 전체. 흰 면 + 오른쪽 1px 선. 본문과 따로 스크롤된다 |
header | 머리 — 서비스 로고 · 이름 + 접기 버튼. 고정 |
logo | 서비스 마크 · 이름 — 누르지 않는다(홈은 첫 항목) |
trigger | 접기 버튼 — 펼침 ↔ 접힘. 머리 오른쪽, 접히면 가운데 |
content | 내용 — 묶음 · 항목. 넘치면 이 안에서만 스크롤 |
divider | 머리 아래 선 — 내용이 스크롤됐을 때만 |
fog | 내용 아래 끝 흐림 — 늘 켜져 있다 |
groupLabel | 묶음 이름 — 있을 때만, 누르지 않는다. 길면 줄을 바꾼다 |
groupDivider | 묶음 사이 선 — 접혔을 때만(묶음 이름 대신) |
item | 항목 — 아이콘 + 이름(+ 꺾쇠). 하위가 없으면 그 화면 링크, 있으면 펼치기만 |
itemIcon | 항목 아이콘 — lucide 선 아이콘 |
itemLabel | 항목 이름 — 짧게, 길면 줄을 바꾼다(말줄임 없음) |
chevron | 꺾쇠 — 하위가 있는 항목만. 펼치면 위로 |
subItem | 하위 항목 — 아이콘 없이 이름만, 부모 이름과 줄을 맞춘다 |
footer | 바닥 — 보조 링크(설명서 · 문의). 고정, 비면 없다. 계정은 두지 않는다(2026-10-16 Q-018-1 C) — 그루 이음은 예외로 계정 줄 + 메뉴(2026-10-23 H-A3 A) |
flyout | 펼침 메뉴 — 접혔을 때 하위가 있는 항목의 하위 목록. Menu 와 같은 표면이고 1280 미만에서도 Menu Sheet 로 바꾸지 않는다(사용자 결정 2026-10-08) |
flyoutLabel | 펼침 메뉴의 묶음 이름 — 부모 항목의 이름 |
flyoutItem | 펼침 메뉴의 줄 — 하위 항목 하나. Menu 의 줄과 같고 높이만 44 |
tooltip | 이름 말풍선 — 접혔을 때 하위가 없는 항목의 이름(Help Bubble 툴팁) |
focusRing | 키보드 포커스 링(웹) — 항목 안쪽 |
Properties
펼침 · 접힘
1280 이상은 펼침(240)이 기본이고, 768 ~ 1279 는 아이콘만(56)으로 저절로 접힌다 — 좁은 화면에서 본문을 넓게 둔다(SEED "md: 공간 효율을 위해 Collapsed 로 자동 전환"). 머리의 접기 버튼으로 어느 폭에서나 손으로 접고 펼 수 있고, 손으로 접은 상태는 기억한다(아래 "폭으로 · 손으로"). 접히면 이름 · 묶음 이름 · 꺾쇠 · 하위 항목이 보이지 않고, 묶음 사이에 1px 선이 남는다.
펼침 · 접힘
| collapsed | 너비 | logo 보이기 | trigger 오른쪽 거리 | content 간격 | groupLabel 보이기 | groupDivider 높이 | groupDivider 상하 바깥 여백 | groupDivider 좌우 바깥 여백 | groupDivider 배경 | item 너비 | item 좌우 여백 | itemLabel 보이기 | chevron 보이기 | subItem 보이기 | 설명 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
expanded (기본) | — | — | — | — | — | — | — | — | — | — | — | — | — | — | 펼침 240 — 1280 이상의 기본 |
collapsed | layout-sidebar-collapsed 56px — 접힘 56 — 아이콘만(v101 — SEED) | none — 접기 버튼만 남는다 | 8px — 56 의 가운데 | 0px — 묶음 사이는 선 | 보이지 않게(sr-only) — 보조 기술에는 묶음 이름이 남는다 | 1px | spacing-x2 8px | spacing-x2 8px — 선 폭 24 — 아이콘 칸 가운데 | color-stroke-neutral-subtle #EDEFF3 · 다크 #353B4D | 40px — 56 − 좌우 8 | spacing-x2_5 10px — 아이콘이 56 가운데(화면 끝에서 18) | 보이지 않게(sr-only) — 이름은 남는다 — 보조 기술 · 말풍선 · 펼침 메뉴 | none | none — 하위는 펼침 메뉴(flyout)로 — 마우스를 올리거나 누르면 | 접힘 56(아이콘만) — 768 ~ 1279 의 기본. 손으로 접은 상태도 |
사이드바
| 속성 | 값 | 비고 |
|---|---|---|
| 너비 | layout-sidebar 240px | 펼침 240(v101 — SEED) |
| 배경 | color-bg-layer-default #FFFFFF · 다크 #242938 | 흰 면 — 본문(bg-page 회색)과 면으로 갈린다. SEED tone=neutral 의 회색 면 대신(본문이 회색이라) |
| 테두리 | color-stroke-neutral-subtle #EDEFF3 · 다크 #353B4D | 오른쪽 안쪽 1px(inset) — SEED stroke.neutral-muted 의 불투명 짝 |
| 테두리 두께 | 1px | |
| 자리 | 화면 왼쪽 · 높이 전체(sticky) | 본문과 따로 스크롤 — 머리 · 바닥은 고정, 내용만 스크롤 |
| 전환 대상 | width | |
| 전환 시간 | motion-duration-d4 200ms | |
| 전환 곡선 | motion-ease-easing cubic-bezier(0.35, 0, 0.35, 1) |
머리 · 접기 버튼
머리는 높이 64 · 안쪽 8 이고(머리 · 접기 버튼 · 항목 최소 44 · 아이콘은 px — 글자 크기를 따르지 않는다, 03-G 1A), 왼쪽에 서비스 마크 24 + 이름(16 / 22 · 700 — "그루 담다" · "그루 이음"), 오른쪽에 접기 버튼이다. 접기 버튼은 상자 40 · 아이콘 18(fg-neutral-subtle) · 모서리 8 이고 누르는 영역은 44 다. 접히면 로고는 숨고 접기 버튼이 56 의 가운데에 선다. 로고는 누르지 않는다 — 홈은 첫 항목이다.
머리
| 속성 | 값 | 비고 |
|---|---|---|
| 최소 높이 | 64px | 접기 버튼이 들어가는 높이(SEED) |
| 여백 | spacing-x2 8px |
로고
| 속성 | 값 | 비고 |
|---|---|---|
| 크기 | 24px | 서비스 마크(브랜드 그림) |
| 간격 | spacing-x2 8px | 마크 ↔ 이름 |
| 글자 | text-t5 16px / 22px | |
| 굵기 | 700 | |
| 글자·아이콘 | color-fg-neutral #1A1F2E · 다크 #F5F6FA | |
| 왼쪽 바깥 여백 | spacing-x2 8px | 화면 끝 → 마크 16 — 항목 아이콘과 같은 줄 |
접기 버튼
| 속성 | 값 | 비고 |
|---|---|---|
| 크기 | 40px | 보이는 상자 — lucide panel-left |
| 모서리 | radius-r2 8px | |
| 아이콘 크기 | 18px | 상자 가운데 — SEED 레시피의 padding 10 은 40 · 18 과 맞지 않아(10 + 18 + 10 = 38) 두지 않는다 |
| 색 | color-fg-neutral-subtle #62697A · 다크 #A2A8B7 | 면 위 5.50 · 다크 6.09 |
| 위 거리 | 12px | 머리 64 의 가운데 |
| 오른쪽 거리 | 12px | 접히면 8 — 56 의 가운데 |
| 터치 영역 | 44 × 44 | 보이지 않는 여백 2 씩(v106) — SEED 는 40 |
| 전환 대상 | background-color | |
| 전환 시간 | motion-duration-color-transition 150ms | |
| 전환 곡선 | motion-ease-easing cubic-bezier(0.35, 0, 0.35, 1) |
묶음 · 항목
묶음 이름은 14 / 19 · 700 · fg-neutral-muted, 묶음 사이는 8 이다. 항목은 최소 44 · 좌우 8 · 모서리 10, 아이콘 20(fg-neutral-subtle) · 아이콘 ↔ 이름 12 · 이름 14 / 19 · 500(fg-neutral-muted)이다. 이름이 길면 말줄임하지 않고 줄을 바꾼다(SEED 문서 — "말줄임(...) 처리 대신 자동 줄바꿈(Word-wrap)") — 항목이 그만큼 늘어난다. 그래도 이름은 짧게 쓴다("상품 정보 관리" 대신 "상품 관리" — SEED).
항목
| 속성 | 값 | 비고 |
|---|---|---|
| 최소 높이 | 44px | 한 줄 — 이름이 줄을 바꾸면 늘어난다. AA ✓ · AAA ✓ |
| 좌우 여백 | spacing-x2 8px | 아이콘은 화면 끝에서 16(내용 8 + 8) |
| 간격 | spacing-x3 12px | 아이콘 ↔ 이름 — 이름은 항목 안 40 에서 시작한다 |
| 모서리 | radius-r2_5 10px | |
| 배경 | transparent | 누를 때 · 마우스를 올릴 때 · 지금 항목만 칠한다 |
| 커서 | pointer | |
| 전환 대상 | background-color | |
| 전환 시간 | motion-duration-color-transition 150ms | |
| 전환 곡선 | motion-ease-easing cubic-bezier(0.35, 0, 0.35, 1) |
항목 아이콘
| 속성 | 값 | 비고 |
|---|---|---|
| 크기 | 20px | |
| 색 | color-fg-neutral-subtle #62697A · 다크 #A2A8B7 | 면 위 5.50 · 다크 6.09 — SEED palette.gray-600 은 1.97:1 이라 쓰지 않는다 |
항목 이름
| 속성 | 값 | 비고 |
|---|---|---|
| 글자 | text-t4 14px / 19px | |
| 굵기 | 500 | |
| 글자·아이콘 | color-fg-neutral-muted #535866 · 다크 #B7BDCC | |
| 상하 여백 | spacing-x1_5 6px | 줄을 바꾸면 항목이 그만큼 늘어난다 — 말줄임하지 않는다(SEED 문서) |
묶음 이름
| 속성 | 값 | 비고 |
|---|---|---|
| 글자 | text-t4 14px / 19px | |
| 굵기 | 700 | |
| 글자·아이콘 | color-fg-neutral-muted #535866 · 다크 #B7BDCC | |
| 여백 | spacing-x1_5 6px | 글은 화면 끝에서 14. 길면 줄을 바꾼다(단어 단위 — v114) |
지금 항목
지금 화면의 항목은 옅은 회색 바탕(bg-neutral-weak-pressed) + 짙은 아이콘 · 이름(fg-neutral)이다. 바탕은 SEED 의 옅은 선택 바탕보다 한 단계 짙어, 다크에서도 마우스를 올린 바탕(bg-layer-default-pressed)과 갈린다(사용자 결정 2026-10-08). 굵기(500) · 크기는 바꾸지 않는다(SEED). 지금 항목에 마우스를 올리거나 눌러도 바탕은 그대로이고, 누르면 아이콘 · 이름만 줄어든다. 펼침 메뉴의 지금 화면 줄도 같은 바탕이다. 하위가 지금 화면이면 하위 항목이 지금 항목이고 부모는 저절로 펼쳐진다 — 접힌 사이드바에서는 하위가 지금인 부모가 지금 항목이다.
지금 항목
| current | item 배경 | itemIcon 색 | itemLabel 글자·아이콘 | flyoutItem 배경 | 설명 |
|---|---|---|---|---|---|
none (기본) | — | — | — | — | 다른 항목 |
current | color-bg-neutral-weak-pressed #EDEFF3 · 다크 #404757 — 옅은 회색 — SEED bg.transparent-selected(검정 4.7%)보다 한 단계 짙은 불투명 역할(사용자 결정 2026-10-08). 면 위 1.15 · 다크 1.56, 호버 바탕과 1.09 · 1.20 | color-fg-neutral #1A1F2E · 다크 #F5F6FA — 짙은 글자색 — 한 단계 짙은 바탕과 함께 지금 항목을 알린다 | color-fg-neutral #1A1F2E · 다크 #F5F6FA — 굵기는 500 그대로(SEED) — 700 은 고르지 않았다(2026-10-08) | color-bg-neutral-weak-pressed #EDEFF3 · 다크 #404757 — 펼침 메뉴의 지금 화면 줄도 같은 바탕 — 떠 있는 표면 위 1.15 · 다크 1.35, 줄 호버 바탕과 1.09 · 1.20 | 지금 화면 — 접혔을 때는 하위가 지금인 부모도 |
하위 항목
하위가 있는 항목(부모)은 누르면 하위 목록을 펼치고 접기만 한다 — 그 자체로 어떤 화면으로도 가지 않는다(SEED). 오른쪽 꺾쇠 16 이 접혀 있으면 아래, 펼치면 위를 가리킨다. 하위 항목은 아이콘 없이 이름만이고 부모 이름과 같은 자리(40)에서 시작한다. 하위가 없는 항목은 누르면 바로 그 화면으로 간다.
하위 항목
| 속성 | 값 | 비고 |
|---|---|---|
| 최소 높이 | 44px | |
| parentFrom | 하위 2개 이상 | 하위가 하나 · 없으면 부모를 만들지 않는다 — 단독 항목(꺾쇠 없이 그 화면 링크). 하위가 사용자마다 다른 항목(Desk 증권 — 연결한 증권사)도 같다(2026-10-16 Q-017-4 정리 — SEED Standalone Menu) |
| 왼쪽 여백 | 40px | 부모 이름과 같은 자리 = 8 + 아이콘 20 + 12. 아이콘 없이 이름만(t4 · 500) |
| 보이기 | 하위가 펼쳐졌을 때만 | 높이 · 투명도로 펼쳐진다(motion) |
꺾쇠
| 속성 | 값 | 비고 |
|---|---|---|
| 크기 | 16px | lucide chevron-down — 접혀 있으면 아래, 펼치면 위 |
| 색 | color-fg-neutral-subtle #62697A · 다크 #A2A8B7 | |
| 전환 대상 | rotate | |
| 전환 시간 | motion-duration-d6 300ms | 하위 펼침과 같은 300ms — Accordion 과 같다(2026-10-10 사용자 결정 3A) |
| 전환 곡선 | motion-ease-easing cubic-bezier(0.35, 0, 0.35, 1) |
스크롤 — 머리 아래 선 · 끝 흐림
머리 · 바닥은 고정이고 내용만 스크롤된다. 내용이 위 끝에서 떨어지면 머리 아래에 1px 선(stroke-neutral-subtle)이 생기고, 내용 아래 끝 24 는 늘 흐리다(gradient-fade-mask — 끝까지 내리면 흐림이 빈 여백 위에 놓인다). 이 흐림은 사이드바의 제 안개다(Scroll Fog 의 "부품이 제 안개를 가진 자리").
내용
| 속성 | 값 | 비고 |
|---|---|---|
| 위 여백 | spacing-x2 8px | |
| 좌우 여백 | spacing-x2 8px | |
| 아래 여백 | 24px | 끝 흐림 깊이와 같다 — 끝까지 내리면 흐림이 빈 여백 위에 놓인다 |
| 간격 | spacing-x2 8px | 묶음 사이 — 접히면 0(선으로 가른다) |
| 세로 넘침 | auto | |
| 스크롤 여유 | 위 8px · 아래 24px | 키보드로 옮긴 항목이 흐림 아래 멈추지 않게 |
머리 아래 선
| 속성 | 값 | 비고 |
|---|---|---|
| 높이 | 1px | |
| 배경 | color-stroke-neutral-subtle #EDEFF3 · 다크 #353B4D | 머리 아래 — 내용이 위 끝에서 떨어지면 나타난다(SEED). 안쪽 그림자로 그린다 |
| 전환 시간 | motion-duration-color-transition 150ms | |
| 전환 곡선 | motion-ease-easing cubic-bezier(0.35, 0, 0.35, 1) |
끝 흐림
| 속성 | 값 | 비고 |
|---|---|---|
| 마스크 | gradient-fade-mask | 늘 켜짐 — 내용 상자의 아래 끝. 사이드바의 제 안개다(Scroll Fog 의 box 20 이 아니라 SEED 사이드바 24) |
| 크기 | 아래 24px |
접혔을 때 — 말풍선 · 펼침 메뉴
접힌 사이드바에서 하위가 없는 항목에 마우스를 올리거나 키보드 초점이 오면 오른쪽에 이름 말풍선이 뜬다(Help Bubble 의 툴팁). 하위가 있는 항목은 오른쪽에 펼침 메뉴가 열려 하위 목록을 보인다 — 표면은 Menu 와 같고(bg-layer-floating · 모서리 20 · shadow-s3 · 폭 200), 맨 위에 부모 이름, 줄은 높이 44 다. 마우스를 올리면 200ms 뒤에 열리고 떠나면 100ms 뒤에 닫히며, 누르거나 Enter · Space 로도 연다. 지금 화면의 줄은 지금 항목과 같은 바탕이다. 1280 미만이어도 Menu Sheet 로 바꾸지 않는다 — 아래 "접힌 사이드바의 하위".
펼침 메뉴
| 속성 | 값 | 비고 |
|---|---|---|
| 너비 | 200px | Menu 와 같은 표면(menu.yaml) — 글이 길면 줄을 바꾼다 |
| 배경 | color-bg-layer-floating #FFFFFF · 다크 #2D3346 | |
| 모서리 | radius-r5 20px | |
| 그림자 | shadow-s3 | |
| 상하 여백 | spacing-x2 8px | |
| 트리거와 거리 | spacing-x2 8px | 항목 오른쪽 8 · 위 끝 맞춤(right-start). 화면 끝과도 8 — 모자라면 위로 민다 |
| 열림 지연 | 200ms | 마우스를 올리면 — 다른 펼침 메뉴가 열려 있으면 바로(SEED NavigationMenu) |
| 닫힘 지연 | 100ms | 마우스가 떠나면 — 항목에서 메뉴로 옮겨 가는 길에서는 닫히지 않는다(WCAG 1.4.13) |
| z-index | 200 | z-floating — specs/z-index.md L3 |
펼침 메뉴의 줄
| 속성 | 값 | 비고 |
|---|---|---|
| 최소 높이 | 44px | Menu 의 줄(39)보다 높다 — 접힌 사이드바는 1280 미만(터치 태블릿)에도 있다. AA ✓ · AAA ✓ |
| 좌우 여백 | spacing-x4 16px | |
| 글자 | text-t4 14px / 19px | |
| 굵기 | 400 | |
| 글자·아이콘 | color-fg-neutral #1A1F2E · 다크 #F5F6FA | |
| 바탕 들임 | spacing-x2 8px | 바탕은 좌우 8 들인 알약(Menu) |
| 모서리 | radius-r3 12px | |
| 배경 | transparent |
펼침 메뉴의 묶음 이름
| 속성 | 값 | 비고 |
|---|---|---|
| 글자 | text-t3 13px / 18px | |
| 굵기 | 400 | |
| 글자·아이콘 | color-fg-neutral-subtle #62697A · 다크 #A2A8B7 | 부모 항목의 이름 — Menu 의 묶음 이름과 같다 |
| 상하 여백 | spacing-x2 8px | |
| 좌우 여백 | spacing-x4 16px |
이름 말풍선
| 속성 | 값 | 비고 |
|---|---|---|
| 자리 | 항목 오른쪽 | Help Bubble 툴팁(help-bubble.yaml) — 항목의 이름 |
| 열림 지연 | 200ms | 마우스 — 키보드 초점이면 바로 |
| 닫힘 지연 | 100ms |
State
| 상태 | 모습 |
|---|---|
enabled | 바탕 없음(지금 항목은 옅은 회색 bg-neutral-weak-pressed) |
hovered | 웹 — bg-layer-default-pressed(지금 항목은 바탕 그대로), 축소 없음 |
pressed | 같은 바탕 + 아이콘 · 이름만 2px 거리 축소 |
focused | 웹 — 키보드 포커스에만 항목 안쪽 2px 링 |
open | 하위가 펼쳐짐 — 꺾쇠가 위로 |
disabled | 아이콘 · 이름 fg-disabled, 누르지 못한다 |
상태 — 항목
| 상태 | item 배경 | item 배율 | item 커서 | item 축소 시간 | item 축소 곡선 |
|---|---|---|---|---|---|
enabled 기본 | transparent — 누를 때 · 마우스를 올릴 때 · 지금 항목만 칠한다 | — | pointer | — | — |
hovered 웹 — 마우스를 올린 항목의 바탕(누름과 같은 색, 축소 없음) | color-bg-layer-default-pressed #F7F8FD · 다크 #353B4D — SEED bg.transparent-pressed 의 불투명 짝(흰 면 위) | — | pointer | — | — |
pressed 누름 — 항목 바탕 + 아이콘 · 이름만 2px 거리 축소 | color-bg-layer-default-pressed #F7F8FD · 다크 #353B4D | 콘텐츠 2px 거리 축소 — 아이콘 · 이름만(목록 줄 — v104), 바탕은 그대로. 모션 줄이기면 하지 않는다 | pointer | motion-duration-pressed-scale 150ms | motion-ease-pressed-scale cubic-bezier(0, 0, 0.15, 1) |
disabled 막힌 항목 — 전용 색, 누르지 못한다 | transparent — 호버 · 누름 바탕 없음 | — | not-allowed | — | — |
상태 — 지금 항목
| 상태 | item 배경 | item 배율 | item 커서 | item 축소 시간 | item 축소 곡선 |
|---|---|---|---|---|---|
enabled 기본 | color-bg-neutral-weak-pressed #EDEFF3 · 다크 #404757 — 옅은 회색 — SEED bg.transparent-selected(검정 4.7%)보다 한 단계 짙은 불투명 역할(사용자 결정 2026-10-08). 면 위 1.15 · 다크 1.56, 호버 바탕과 1.09 · 1.20 | — | pointer | — | — |
hovered 웹 — 마우스를 올린 항목의 바탕(누름과 같은 색, 축소 없음) | color-bg-neutral-weak-pressed #EDEFF3 · 다크 #404757 — 바탕 그대로 — 지금 항목보다 짙은 불투명 역할이 없다 | — | pointer | — | — |
pressed 누름 — 항목 바탕 + 아이콘 · 이름만 2px 거리 축소 | color-bg-neutral-weak-pressed #EDEFF3 · 다크 #404757 — 바탕 그대로 — 아이콘 · 이름의 2px 거리 축소만 | 콘텐츠 2px 거리 축소 — 아이콘 · 이름만(목록 줄 — v104), 바탕은 그대로. 모션 줄이기면 하지 않는다 | pointer | motion-duration-pressed-scale 150ms | motion-ease-pressed-scale cubic-bezier(0, 0, 0.15, 1) |
disabled 막힌 항목 — 전용 색, 누르지 못한다 | transparent — 호버 · 누름 바탕 없음 | — | not-allowed | — | — |
모션
| 전환 | 시간 | 곡선 | 대상 | 비고 |
|---|---|---|---|---|
펼침 ↔ 접힘 | motion-duration-d4 200ms | motion-ease-easing cubic-bezier(0.35, 0, 0.35, 1) | width, padding | 이름은 접히기 시작할 때 사라지고 다 펴진 뒤 나타난다. 모션 줄이기면 바로 바뀐다 |
하위 펼침 | motion-duration-d6 300ms | motion-ease-easing cubic-bezier(0.35, 0, 0.35, 1) | height, opacity | 꺾쇠도 같은 시간에 돈다 — 300ms, Accordion 과 같다(2026-10-10 사용자 결정 3A — 그전의 d4 200 은 스펙 초안의 값이었다). 꺾쇠는 모션 줄이기면 바로 |
하위 펼침 — 모션 줄이기 | motion-duration-d3 150ms | motion-ease-easing cubic-bezier(0.35, 0, 0.35, 1) | opacity | 높이를 움직이지 않고 하위 목록이 150ms 서서히 나타나고 사라진다(v104 · Accordion 과 같다) |
펼침 메뉴 — 열림 | motion-duration-d3 150ms | motion-ease-enter cubic-bezier(0, 0, 0.15, 1) | scale 0.95 → 1, opacity 0 → 1 | Menu 와 같다 — 항목 쪽 변을 기준점으로 |
펼침 메뉴 — 닫힘 | motion-duration-d2 100ms | motion-ease-exit cubic-bezier(0.35, 0, 1, 1) | scale → 0.95, opacity → 0 | |
머리 아래 선 | motion-duration-color-transition 150ms | motion-ease-easing cubic-bezier(0.35, 0, 0.35, 1) | box-shadow | |
누름 | motion-duration-pressed-scale 150ms | motion-ease-pressed-scale cubic-bezier(0, 0, 0.15, 1) | scale |
Guidelines
폭으로 · 손으로
| 창 폭 | 기본 | 손으로 |
|---|---|---|
| 1280 이상 | 펼침 240 | 접을 수 있다 — 접은 상태를 기억해 다음에도 접힌 채 연다 |
| 768 ~ 1279 | 접힘 56 | 펼 수 있다 — 본문이 그만큼 좁아진다. 다시 열면 접힌 채다 |
| 768 미만 | 없다 | Desk 는 하단 탭 바, HR 은 ☰ → 왼쪽 주 메뉴(Side Panel) |
기본은 창 폭으로 정하고, 창 폭이 1280 을 넘나들면 다시 정한다 — 처음 열 때도 폭을 본다(SEED 코드는 넘나들 때만 본다). 손으로 접은 것은 브라우저에 기억한다(localStorage) — 서버 쿠키가 아니다.
768 미만 — 같은 항목을 다른 그릇에
768 미만에서 사이드바는 없다. Desk 웹은 앱과 같은 Bottom Navigation 이고, HR 은 Top Navigation 의 ☰ 로 여는 왼쪽 Side Panel 에 같은 묶음 · 항목을 펼친 모양으로 담는다 — 지금 화면의 묶음이 펼쳐진 채 열리고, 항목을 누르면 이동하고 닫힌다.
접힌 사이드바의 하위 — 옆 펼침 메뉴(Menu 경계의 예외)
768 ~ 1279 의 접힌 사이드바에서 하위가 있는 항목은 누른 아이콘 옆 8 에 펼침 메뉴를 띄운다 — Menu 표면 · 폭 200 · 줄 44 · 지금 화면 줄 표시. 이 폭은 Menu 가 Menu Sheet 로 바뀌는 1280 미만이지만, 사이드바의 하위 목록은 시트로 바꾸지 않는다 — Menu 의 "1280 미만은 Menu Sheet" 규칙의 예외다(사용자 결정 2026-10-08 — Menu Sheet 는 고르지 않았다). 줄을 Menu 의 39 가 아니라 44 로 두는 것은 이 폭에 터치 태블릿이 섞여서다. 마우스는 200ms 뒤 열고 100ms 뒤 닫으며, 누르거나 키보드로도 연다(Behavior).
부모는 펼치기만, 지금 화면이면 저절로
하위가 있는 항목은 이동하지 않고 펼치기만 한다 — "증권" 을 누르면 나무증권 · 토스증권이 펼쳐질 뿐이다. 하위 하나가 지금 화면이면 부모는 사용자가 손대지 않아도 펼쳐진 채다(SEED). 부모에 따로 갈 화면이 필요하면 하위 첫 줄에 둔다("전체 보기").
하위가 사람마다 다르면 — 둘 이상일 때만 부모
하위가 사용자마다 달라지는 항목(Desk 증권 — 연결한 증권사)은 하위가 둘 이상일 때만 부모다(펼치기만, 하위 = 연결한 증권사). 하나 · 없으면 하위 없는 단독 항목이 되어 누르면 바로 그 화면으로 간다 — 꺾쇠가 없다(SEED Standalone Menu — "하위 항목이 없는 경우 … 아이템 클릭 시 즉시 해당 페이지로 이동"). 증권 화면은 연결이 하나면 그 증권사를, 없으면 연결 안내를 연다. 구독이 없으면 항목을 두지 않는다(지금 그대로 — Pro 는 증권뿐). 하위 하나짜리 나무는 만들지 않는다 — 고를 것이 없다(2026-10-16 구현 세션 질문 Q-017-4 정리). 접힌 사이드바에서는 둘 이상이면 펼침 메뉴, 하나 · 없으면 이름 말풍선이다.
위치는 사이드바가 알린다
데스크톱에서 지금 어디에 있는지는 사이드바의 지금 항목(부모는 저절로 펼침)과 본문 맨 위 제목이 알린다 — 빵부스러기(Breadcrumb)는 두지 않는다(SEED 에도 없다 — 2026-10-04 결정 9). 지금 HR 의 경로 19개는 모두 사이드바 항목이라 빵부스러기가 같은 정보를 두 번 보였다. 사이드바에 없는 하위 페이지(그루 담다 밤하늘 · 증권 종목 상세 · 자산 상세, 그루 이음 공지 상세 같은)는 데스크톱(768 이상)에서 제목 줄 위에 "‹ {부모}" 글 단추를 둔다 — Button ghost small · 앞 꺾쇠 14, 누르면 적힌 부모로 간다(라벨 = 목적지). 폰(768 미만)은 상단 바의 ← 가 들어온 화면으로 돌아간다(2026-10-23 사용자 결정 Q1-A).
묶음 · 이름
- 묶음은 성격이 다른 항목을 나눌 때만 — 묶음 이름은 짧은 명사("기록" · "관리"). 회사 이름처럼 바뀌는 말을 묶음 이름으로 두지 않는다.
- 같은 이름의 묶음과 항목을 두지 않는다(묶음 "관리자" 안의 항목 "관리자").
- 항목 이름은 화면 이름과 같게 — 사이드바 "통계 · 분석" 과 화면 제목 "통계" 처럼 갈리지 않게.
- 아이콘은 모든 항목에 두고(하위 항목은 없음), lucide 선 아이콘 20 이다.
바닥 — 보조 링크만, 비면 그리지 않는다
바닥에는 보조 링크(설명서 · 문의 — SEED Footer "'가이드북', '지원센터'와 같이 서비스의 보조적인 링크")만 둔다 — 비면 그리지 않는다. 계정(아바타 · 이름)은 바닥에 두지 않는다 — Desk 는 계정이 하나라 바꿀 일이 없고 설정 · 로그아웃은 머리의 ⚙ 가 맡는다(2026-10-16 사용자 결정 — 구현 세션 질문 Q-018-1 C). 지금 Desk 웹에는 보조 링크가 없어 바닥을 그리지 않는다. 그루 이음은 예외다 — 데스크톱 머리(⚙)가 없어 바닥에 계정 줄을 두고, 누르면 메뉴(내 정보 · 비밀번호 바꾸기 · 화면 테마 · 로그아웃)가 열린다(2026-10-23 사용자 결정 H-A3 A). 누르는 것으로 보이는 줄은 반드시 무언가를 한다.
두지 않는 것
shadcn Sidebar 에 있던 것 가운데 다음은 두지 않는다 — SEED 에 없고 groo 화면에 쓸 자리가 없다.
| shadcn | 두지 않는 까닭 |
|---|---|
⌘ / Ctrl + B 단축키 | 브라우저 · 화면 읽기 프로그램의 단축키와 겹치고, 알 길이 없다. 접기 버튼이 있다 |
쿠키로 기억(sidebar_state) | 기억은 브라우저(localStorage)에 — 지금 쿠키는 쓰기만 하고 읽지 않는다 |
floating · inset 모양 | 떠 있는 상자 · 본문 상자(HR inset — 모서리 12 · 그림자)를 걷고 흰 면 + 선 하나로 |
offcanvas(화면 밖으로 숨김) · 오른쪽 사이드바 | 접힘은 아이콘만(56) 하나, 왼쪽만. 768 미만의 서랍은 Side Panel |
| 768 미만 자동 Sheet | 768 미만은 Desk 하단 탭 바 · HR ☰ + Side Panel |
코드
레시피 recipes/shadcn/components/ui/side-navigation.tsx 를 쓴다. 아래 미리보기는 스펙 값으로 그린 모습이다.
SideNavigation— 사이드바(<nav aria-label="주 메뉴">).collapsed·defaultCollapsed·onCollapsedChange(손으로 다룰 때). 주지 않으면 창 폭(768 ~ 1279 접힘 · 1280 이상 펼침) + 손으로 접은 기억(localStorage의groo:side-navigation-collapsed)으로 정한다.SideNavigationHeader— 머리.logo(마크 + 서비스 이름). 접기 버튼(이름 "사이드바" ·aria-expanded·aria-controls)을 스스로 그린다.SideNavigationContent— 내용(스크롤 · 머리 아래 선 · 끝 흐림). 768 미만의 주 메뉴 서랍(Side Panel)에는 이것만 넣는다 —SideNavigation밖에서 쓰면 스스로<nav aria-label="주 메뉴">가 되고, 펼친 모양으로 그린다(서랍의 스크롤 · 흐림은 Side Panel 본문이 맡는다).onNavigate(항목을 눌러 이동할 때 — 서랍을 닫는다).SideNavigationGroup— 묶음.label(있을 때만).SideNavigationItem— 항목. 하위가 없으면 링크 —href·icon·label·current(aria-current="page") ·disabled. 자식으로SideNavigationSubItem을 둘 이상 주면 부모(버튼 —aria-expanded·aria-controls, 하위가current면 저절로 펼침,defaultOpen)가 된다. 하위가 하나 이하이면 부모를 만들지 않고href의 단독 링크로 그린다(href가 없으면 그 하나의href— 하위가 지금이면 지금 항목) — 하위가 사람마다 다른 항목(증권)을 그대로 넘겨도 된다. 접히면 하위가 없는 항목은 이름 말풍선, 부모는 펼침 메뉴를 스스로 그린다.SideNavigationSubItem— 하위 항목(링크).href·label·current·disabled.SideNavigationFooter— 바닥 — 보조 링크(설명서 · 문의). 비면 그리지 않는다. 계정을 넣지 않는다(그루 이음은 계정 줄 + 메뉴 — H-A3 A).
앱은 사이드바가 없다(늘 폰 틀).
Desk — 묶음 둘 · 하위가 있는 증권
import { CalendarDays, ClipboardList, LayoutGrid, Wallet, TrendingUp } from "lucide-react"
import {
SideNavigation, SideNavigationContent, SideNavigationGroup,
SideNavigationHeader, SideNavigationItem, SideNavigationSubItem,
} from "@/components/ui/side-navigation"
<SideNavigation>
<SideNavigationHeader logo={<ServiceLogo name="그루 담다" />} />
<SideNavigationContent>
<SideNavigationGroup label="워크스페이스">
<SideNavigationItem href="/desk" icon={<LayoutGrid />} label="홈" current={path === "/desk"} />
<SideNavigationItem href="/desk/assets" icon={<Wallet />} label="자산" current={path === "/desk/assets"} />
{/* 증권 — 구독이 없으면 두지 않는다. 연결한 증권사가 둘 이상이면 부모(펼치기만), 하나 · 없으면 /desk/stocks 단독 링크 */}
{subscribed && (
<SideNavigationItem href="/desk/stocks" icon={<TrendingUp />} label="증권" current={path.startsWith("/desk/stocks")}>
{brokers.map((b) => (
<SideNavigationSubItem key={b.id} href={`/desk/stocks/${b.id}`} label={b.name} current={broker === b.id} />
))}
</SideNavigationItem>
)}
<SideNavigationItem href="/desk/ledger" icon={<ClipboardList />} label="가계부" current={path === "/desk/ledger"} />
</SideNavigationGroup>
<SideNavigationGroup label="기록">
<SideNavigationItem href="/desk/calendar" icon={<CalendarDays />} label="캘린더" current={path === "/desk/calendar"} />
</SideNavigationGroup>
</SideNavigationContent>
{/* 바닥 — Desk 는 보조 링크가 없어 두지 않는다(계정은 바닥에 두지 않는다) */}
</SideNavigation>768 ~ 1279 — 접힌 사이드바
{/* 폭으로 저절로 접힌다 — 같은 코드. 손으로 정하려면 collapsed · onCollapsedChange */}
<SideNavigation>…</SideNavigation>Behavior
| 인터랙션 | 동작 |
|---|---|
| 항목 누르기 | 그 화면으로 — 초점 · 스크롤은 Top Navigation 의 "화면을 옮길 때" |
부모 누르기 · Enter · Space | 하위를 펼치고 접는다 — 이동하지 않는다. 하위가 300ms 로 펼쳐지고 꺾쇠도 같은 시간에 돈다(Accordion 과 같다) |
| 접기 버튼 | 펼침 ↔ 접힘 200ms. 1280 이상에서 접으면 기억한다 |
| 창 폭이 1280 을 넘나듦 | 기본으로 다시 — 1280 이상 펼침(접어 둔 기억이 있으면 접힘), 미만 접힘 |
| 내용 스크롤 | 머리 아래 선이 나타난다 · 아래 끝 흐림은 늘 |
| 접힌 항목에 마우스(하위 없음) | 200ms 뒤 이름 말풍선 · 떠나면 100ms 뒤 닫힘. 키보드 초점이면 바로 |
| 접힌 부모에 마우스 | 200ms 뒤 펼침 메뉴(다른 펼침 메뉴가 열려 있으면 바로) · 메뉴로 옮겨 가는 동안 닫히지 않는다 · 떠나면 100ms 뒤 닫힘 |
접힌 부모 누르기 · Enter · Space | 펼침 메뉴를 열고 닫는다 — 키보드로 열면 첫 줄로 초점, 마우스 · 터치로 열면 초점을 옮기지 않는다 |
펼침 메뉴에서 Esc · 바깥 누르기 · Tab 으로 나감 | 닫는다 — Esc 면 초점은 부모로 |
Tab | 접기 버튼 → 항목 차례(펼쳐진 하위 포함) → 바닥 |
Accessibility
| 기준 | 검증 |
|---|---|
| WCAG 1.4.3 Color contrast(글자 ≥ 4.5:1) | 이름 · 묶음 이름 fg-neutral-muted 면(bg-layer-default) 위 7.11 · 다크 7.70, 호버 바탕 위 6.70 · 5.93, 지금 항목 fg-neutral 옅은 회색 위 14.26 · 8.62 ✓. 펼침 메뉴 줄 16.41 · 11.62(지금 줄 14.26 · 8.62) · 묶음 이름 5.50 · 5.27 ✓ |
| WCAG 1.4.11 Non-text contrast(≥ 3:1) | 아이콘 fg-neutral-subtle 5.50 · 6.09(호버 바탕 위 5.18 · 4.68), 접기 버튼 같은 값 ✓(SEED gray-600 은 1.97). 키보드 포커스 링 Desk 8.38 · 6.10 · HR 8.17 · 6.07(지금 항목 위 Desk 7.28 · 3.91 · HR 7.10 · 3.90) ✓. 면 · 오른쪽 선(본문과 1.08 · 1.07)은 장식 |
| WCAG 1.4.1 Use of color | ⚠ 지금 항목은 한 단계 짙은 옅은 바탕(면 위 1.15 · 다크 1.56, 호버 바탕과 1.09 · 1.20 — 펼침 메뉴의 지금 줄도 같다)과 글자 · 아이콘의 진하기(다른 항목과 2.31 · 1.74 / 2.99 · 2.20)로 알린다. 굵기는 바꾸지 않는다. 보조 기술에는 aria-current="page". 사용자 결정 2026-10-08 — 굵기는 그대로, 낭독은 aria-current |
| WCAG 1.4.13 Content on Hover or Focus | 말풍선 · 펼침 메뉴 — 옮겨 가는 동안 닫히지 않고(hoverable), Esc 로 닫히며(dismissible), 떠날 때까지 남는다 ✓ |
| WCAG 2.1.1 Keyboard | 항목 · 부모 · 접기 버튼 · 펼침 메뉴 모두 Tab · Enter · Space · Esc ✓ |
| WCAG 2.4.1 Bypass Blocks | 본문 바로가기 링크가 사이드바를 건너뛴다(Layout 의 랜드마크) ✓ |
| WCAG 2.5.8 Target Size — Minimum(AA ≥ 24×24) | 항목 · 하위 항목 · 펼침 메뉴 줄 44, 접기 버튼 40(누르는 영역 44) ✓ |
| WCAG 2.5.5 Target Size — Enhanced(AAA ≥ 44×44) | 항목 224 × 44 · 접힘 40 × 44 ✓ · 접기 버튼 누르는 영역 44 ✓ · 펼침 메뉴 줄 44 ✓ |
| ARIA | <nav aria-label="주 메뉴">, 묶음은 목록(<ul aria-labelledby> — 묶음 이름), 항목 링크 + 지금 화면 aria-current="page", 부모 <button aria-expanded aria-controls>, 접기 버튼 이름 "사이드바" + aria-expanded · aria-controls. 접히면 이름 · 묶음 이름은 보이지 않게만 남는다(말풍선은 이름과 같은 글이라 설명으로 잇지 않는다). 펼침 메뉴는 디스클로저 — role="menu" 를 쓰지 않고, 내용은 부모로 aria-labelledby. 접힌 부모가 지금 화면의 하위를 품으면 부모(버튼)는 지금 항목 바탕만 칠하고 aria-current 를 두지 않는다 — 지금 화면은 펼침 메뉴 안의 그 링크가 aria-current="page" 로 알린다 |
Do / Don't
✅ Do
- 1280 이상 펼침 · 768 ~ 1279 접힘 — 손으로 접은 것은 기억.
- 부모는 펼치기만, 하위가 지금이면 저절로 펼침. 하위가 사람마다 다르면 둘 이상일 때만 부모.
- 긴 이름은 줄을 바꾼다 — 그래도 짧게.
- 흰 면 + 오른쪽 선 하나, 지금 항목은 한 단계 짙은 옅은 회색(
bg-neutral-weak-pressed) + 짙은 글자 — 굵기는 그대로. - 접힌 사이드바 — 하위 없는 항목은 이름 말풍선, 부모는 아이콘 옆 펼침 메뉴(1280 미만이어도).
❌ Don't
- 768 ~ 1279 에서 펼친 채 두기(본문 512 까지 좁아진다).
- 부모를 눌러 이동하면서 펼치기.
- 이름 말줄임 · 묶음 이름 대문자 변환 · 회사 이름을 묶음 이름으로.
- 떠 있는 상자 · 본문 상자(inset) · 그림자.
- 빵부스러기로 위치를 한 번 더.
- 접힌 사이드바의 하위를 Menu Sheet 로 띄우기 · 지금 항목을 굵게(700).
- 아무 일도 하지 않는 로고 버튼 · 사용자 버튼 · 바닥의 계정 줄(Desk).
- 하위 하나짜리 부모 — 하나면 단독 항목.
Specification
side-navigation.yaml 의 규칙을 하나도 빼지 않고 조건마다 그린다 — 웹이 Side Navigation 을 만들 때 이 값을 그대로 쓴다. 조건이 없는 Base 가 모든 조합에 걸리고, 뒤의 규칙이 앞의 같은 값을 덮는다. 상태는 enabled 에서 바뀌는 값만 적었다.
Base
| 부위 | 상태 | 속성 | 값 |
|---|---|---|---|
root | enabled | 너비width | $layout-sidebar펼침 240(v101 — SEED) |
| 배경background | bg-layer-default#FFFFFF다크 #242938흰 면 — 본문(bg-page 회색)과 면으로 갈린다. SEED tone=neutral 의 회색 면 대신(본문이 회색이라) | ||
| 테두리borderColor | stroke-neutral-subtle#EDEFF3다크 #353B4D오른쪽 안쪽 1px(inset) — SEED stroke.neutral-muted 의 불투명 짝 | ||
| 테두리 두께borderWidth | 1px | ||
| 전환 대상transitionProperty | width | ||
| 전환 시간transitionDuration | motion-duration-d4200ms | ||
| 전환 곡선transitionEasing | motion-ease-easingcubic-bezier(0.35, 0, 0.35, 1) | ||
| 자리position | 화면 왼쪽 · 높이 전체(sticky)본문과 따로 스크롤 — 머리 · 바닥은 고정, 내용만 스크롤 | ||
header | enabled | 최소 높이minHeight | 64px접기 버튼이 들어가는 높이(SEED) |
| 여백padding | spacing-x28px | ||
logo | enabled | 크기size | 24px서비스 마크(브랜드 그림) |
| 왼쪽 바깥 여백marginLeft | spacing-x28px화면 끝 → 마크 16 — 항목 아이콘과 같은 줄 | ||
| 간격gap | spacing-x28px마크 ↔ 이름 | ||
| 글자·아이콘foreground | fg-neutral#1A1F2E다크 #F5F6FA | ||
| 글자typography | text-t516px / 22px | ||
| 굵기fontWeight | 700 | ||
trigger | enabled | 크기size | 40px보이는 상자 — lucide panel-left |
| 아이콘 크기iconSize | 18px상자 가운데 — SEED 레시피의 padding 10 은 40 · 18 과 맞지 않아(10 + 18 + 10 = 38) 두지 않는다 | ||
| 모서리radius | radius-r28px | ||
| 색color | fg-neutral-subtle#62697A다크 #A2A8B7면 위 5.50 · 다크 6.09 | ||
| 터치 영역touchTarget | 44 × 44보이지 않는 여백 2 씩(v106) — SEED 는 40 | ||
| 전환 대상transitionProperty | background-color | ||
| 전환 시간transitionDuration | motion-duration-color-transition150ms | ||
| 전환 곡선transitionEasing | motion-ease-easingcubic-bezier(0.35, 0, 0.35, 1) | ||
| 위 거리top | 12px머리 64 의 가운데 | ||
| 오른쪽 거리right | 12px접히면 8 — 56 의 가운데 | ||
content | enabled | 좌우 여백paddingX | spacing-x28px |
| 위 여백paddingTop | spacing-x28px | ||
| 아래 여백paddingBottom | 24px끝 흐림 깊이와 같다 — 끝까지 내리면 흐림이 빈 여백 위에 놓인다 | ||
| 간격gap | spacing-x28px묶음 사이 — 접히면 0(선으로 가른다) | ||
| 세로 넘침overflowY | auto | ||
| 스크롤 여유scrollPadding | 위 8px · 아래 24px키보드로 옮긴 항목이 흐림 아래 멈추지 않게 | ||
divider | enabled | 높이height | 1px |
| 배경background | stroke-neutral-subtle#EDEFF3다크 #353B4D머리 아래 — 내용이 위 끝에서 떨어지면 나타난다(SEED). 안쪽 그림자로 그린다 | ||
| 전환 시간transitionDuration | motion-duration-color-transition150ms | ||
| 전환 곡선transitionEasing | motion-ease-easingcubic-bezier(0.35, 0, 0.35, 1) | ||
fog | enabled | 크기size | 아래 24px |
| 마스크mask | gradient-fade-masklinear-gradient(#00000000 0%, #00000003 8%, #00000005 16%, #0000000d 22%, #00000014 29%, #00000021 35%, #0000002e 41%, #00000040 47%, #00000052 53%, #00000066 59%, #0000007a 65%, #00000094 71%, #000000ab 78%, #000000c7 84%, #000000e3 92%, #000000ff 100%)늘 켜짐 — 내용 상자의 아래 끝. 사이드바의 제 안개다(Scroll Fog 의 box 20 이 아니라 SEED 사이드바 24) | ||
groupLabel | enabled | 여백padding | spacing-x1_56px글은 화면 끝에서 14. 길면 줄을 바꾼다(단어 단위 — v114) |
| 글자·아이콘foreground | fg-neutral-muted#535866다크 #B7BDCC | ||
| 글자typography | text-t414px / 19px | ||
| 굵기fontWeight | 700 | ||
item | enabled | 최소 높이minHeight | 44px한 줄 — 이름이 줄을 바꾸면 늘어난다. AA ✓ · AAA ✓ |
| 좌우 여백paddingX | spacing-x28px아이콘은 화면 끝에서 16(내용 8 + 8) | ||
| 간격gap | spacing-x312px아이콘 ↔ 이름 — 이름은 항목 안 40 에서 시작한다 | ||
| 모서리radius | radius-r2_510px | ||
| 배경background | transparent누를 때 · 마우스를 올릴 때 · 지금 항목만 칠한다 | ||
| 커서cursor | pointer | ||
| 전환 대상transitionProperty | background-color | ||
| 전환 시간transitionDuration | motion-duration-color-transition150ms | ||
| 전환 곡선transitionEasing | motion-ease-easingcubic-bezier(0.35, 0, 0.35, 1) | ||
itemIcon | enabled | 크기size | 20px |
| 색color | fg-neutral-subtle#62697A다크 #A2A8B7면 위 5.50 · 다크 6.09 — SEED palette.gray-600 은 1.97:1 이라 쓰지 않는다 | ||
itemLabel | enabled | 상하 여백paddingY | spacing-x1_56px줄을 바꾸면 항목이 그만큼 늘어난다 — 말줄임하지 않는다(SEED 문서) |
| 글자·아이콘foreground | fg-neutral-muted#535866다크 #B7BDCC | ||
| 글자typography | text-t414px / 19px | ||
| 굵기fontWeight | 500 | ||
chevron | enabled | 크기size | 16pxlucide chevron-down — 접혀 있으면 아래, 펼치면 위 |
| 색color | fg-neutral-subtle#62697A다크 #A2A8B7 | ||
| 전환 대상transitionProperty | rotate | ||
| 전환 시간transitionDuration | motion-duration-d6300ms하위 펼침과 같은 300ms — Accordion 과 같다(2026-10-10 사용자 결정 3A) | ||
| 전환 곡선transitionEasing | motion-ease-easingcubic-bezier(0.35, 0, 0.35, 1) | ||
subItem | enabled | 최소 높이minHeight | 44px |
| 왼쪽 여백paddingLeft | 40px부모 이름과 같은 자리 = 8 + 아이콘 20 + 12. 아이콘 없이 이름만(t4 · 500) | ||
| 보이기display | 하위가 펼쳐졌을 때만높이 · 투명도로 펼쳐진다(motion) | ||
| parentFromparentFrom | 하위 2개 이상하위가 하나 · 없으면 부모를 만들지 않는다 — 단독 항목(꺾쇠 없이 그 화면 링크). 하위가 사용자마다 다른 항목(Desk 증권 — 연결한 증권사)도 같다(2026-10-16 Q-017-4 정리 — SEED Standalone Menu) | ||
footer | enabled | 여백padding | spacing-x28px고정 — 비면 그리지 않는다 |
| 내용content | 보조 링크만설명서 · 문의(SEED Footer). 계정(아바타 · 이름)은 두지 않는다 — Desk 는 설정 · 로그아웃이 머리 ⚙ 에 있다(2026-10-16 사용자 결정 Q-018-1 C). 지금 Desk 웹은 보조 링크가 없어 바닥이 없다. 그루 이음은 예외 — 데스크톱 머리가 없어 바닥에 계정 줄 + 메뉴(내 정보 · 비밀번호 바꾸기 · 화면 테마 · 로그아웃)를 둔다(2026-10-23 사용자 결정 H-A3 A) | ||
flyout | enabled | 너비width | 200pxMenu 와 같은 표면(menu.yaml) — 글이 길면 줄을 바꾼다 |
| 상하 여백paddingY | spacing-x28px | ||
| 모서리radius | radius-r520px | ||
| 배경background | bg-layer-floating#FFFFFF다크 #2D3346 | ||
| 그림자shadow | shadow-s30 8px 24px -4px rgba(15, 18, 28, 0.10), 0 2px 6px -2px rgba(15, 18, 28, 0.05) · 다크 0 8px 24px -4px rgba(0, 0, 0, 0.50), 0 2px 6px -2px rgba(0, 0, 0, 0.25), inset 0 1px 0 0 rgba(255, 255, 255, 0.08) | ||
| z-indexzIndex | 200z-floating — specs/z-index.md L3 | ||
| 열림 지연openDelay | 200ms마우스를 올리면 — 다른 펼침 메뉴가 열려 있으면 바로(SEED NavigationMenu) | ||
| 닫힘 지연closeDelay | 100ms마우스가 떠나면 — 항목에서 메뉴로 옮겨 가는 길에서는 닫히지 않는다(WCAG 1.4.13) | ||
| 트리거와 거리offset | spacing-x28px항목 오른쪽 8 · 위 끝 맞춤(right-start). 화면 끝과도 8 — 모자라면 위로 민다 | ||
flyoutLabel | enabled | 상하 여백paddingY | spacing-x28px |
| 좌우 여백paddingX | spacing-x416px | ||
| 글자·아이콘foreground | fg-neutral-subtle#62697A다크 #A2A8B7부모 항목의 이름 — Menu 의 묶음 이름과 같다 | ||
| 글자typography | text-t313px / 18px | ||
| 굵기fontWeight | 400 | ||
flyoutItem | enabled | 최소 높이minHeight | 44pxMenu 의 줄(39)보다 높다 — 접힌 사이드바는 1280 미만(터치 태블릿)에도 있다. AA ✓ · AAA ✓ |
| 좌우 여백paddingX | spacing-x416px | ||
| 바탕 들임insetX | spacing-x28px바탕은 좌우 8 들인 알약(Menu) | ||
| 모서리radius | radius-r312px | ||
| 배경background | transparent | ||
| 글자·아이콘foreground | fg-neutral#1A1F2E다크 #F5F6FA | ||
| 글자typography | text-t414px / 19px | ||
| 굵기fontWeight | 400 | ||
tooltip | enabled | 열림 지연openDelay | 200ms마우스 — 키보드 초점이면 바로 |
| 닫힘 지연closeDelay | 100ms | ||
| 자리position | 항목 오른쪽Help Bubble 툴팁(help-bubble.yaml) — 항목의 이름 | ||
trigger | hovered | 배경background | bg-layer-default-pressed#F7F8FD다크 #353B4D |
item | hovered | 배경background | bg-layer-default-pressed#F7F8FD다크 #353B4DSEED bg.transparent-pressed 의 불투명 짝(흰 면 위) |
flyoutItem | hovered | 배경background | bg-layer-floating-pressed#F7F8FD다크 #353B4D떠 있는 표면 위의 누름 색(Menu) |
trigger | pressed | 배경background | bg-layer-default-pressed#F7F8FD다크 #353B4D |
| 배율scale | 2px 거리 축소기준 40 → 0.95 | ||
item | pressed | 배경background | bg-layer-default-pressed#F7F8FD다크 #353B4D |
| 배율scale | 콘텐츠 2px 거리 축소아이콘 · 이름만(목록 줄 — v104), 바탕은 그대로. 모션 줄이기면 하지 않는다 | ||
| 축소 시간scaleDuration | motion-duration-pressed-scale150ms | ||
| 축소 곡선scaleEasing | motion-ease-pressed-scalecubic-bezier(0, 0, 0.15, 1) | ||
flyoutItem | pressed | 배경background | bg-layer-floating-pressed#F7F8FD다크 #353B4D |
| 배율scale | 콘텐츠 2px 거리 축소글만(Menu) | ||
focusRing | focused | 링 두께width | 2px |
| 모서리radius | radius-r2_510px항목 모서리 10 · 접기 버튼 8 · 펼침 메뉴 줄은 알약 자리(12) | ||
| 링 색color | stroke-focus-ringDesk#0147AD다크 #7AA9F6HR#075B3C다크 #2ABE84 | ||
| 링 간격offset | -2px항목 · 접기 버튼 안쪽 — 붙은 항목에 걸리지 않는다(SEED) | ||
chevron | open | 회전rotate | 180deg위로 — 하위가 펼쳐졌다 |
subItem | open | 보이기display | 보임 |
item | disabled | 배경background | transparent호버 · 누름 바탕 없음 |
| 커서cursor | not-allowed | ||
itemIcon | disabled | 색color | fg-disabled#8A91A0다크 #838997 |
itemLabel | disabled | 글자·아이콘foreground | fg-disabled#8A91A0다크 #838997 |
current=current
| 부위 | 상태 | 속성 | 값 |
|---|---|---|---|
item | enabled | 배경background | bg-neutral-weak-pressed#EDEFF3다크 #404757옅은 회색 — SEED bg.transparent-selected(검정 4.7%)보다 한 단계 짙은 불투명 역할(사용자 결정 2026-10-08). 면 위 1.15 · 다크 1.56, 호버 바탕과 1.09 · 1.20 |
itemIcon | enabled | 색color | fg-neutral#1A1F2E다크 #F5F6FA짙은 글자색 — 한 단계 짙은 바탕과 함께 지금 항목을 알린다 |
itemLabel | enabled | 글자·아이콘foreground | fg-neutral#1A1F2E다크 #F5F6FA굵기는 500 그대로(SEED) — 700 은 고르지 않았다(2026-10-08) |
flyoutItem | enabled | 배경background | bg-neutral-weak-pressed#EDEFF3다크 #404757펼침 메뉴의 지금 화면 줄도 같은 바탕 — 떠 있는 표면 위 1.15 · 다크 1.35, 줄 호버 바탕과 1.09 · 1.20 |
item | hovered | 배경background | bg-neutral-weak-pressed#EDEFF3다크 #404757바탕 그대로 — 지금 항목보다 짙은 불투명 역할이 없다 |
flyoutItem | hovered | 배경background | bg-neutral-weak-pressed#EDEFF3다크 #404757 |
item | pressed | 배경background | bg-neutral-weak-pressed#EDEFF3다크 #404757바탕 그대로 — 아이콘 · 이름의 2px 거리 축소만 |
flyoutItem | pressed | 배경background | bg-neutral-weak-pressed#EDEFF3다크 #404757 |
collapsed=collapsed
| 부위 | 상태 | 속성 | 값 |
|---|---|---|---|
root | enabled | 너비width | $layout-sidebar-collapsed접힘 56 — 아이콘만(v101 — SEED) |
logo | enabled | 보이기display | none접기 버튼만 남는다 |
trigger | enabled | 오른쪽 거리right | 8px56 의 가운데 |
content | enabled | 간격gap | 0px묶음 사이는 선 |
groupLabel | enabled | 보이기display | 보이지 않게(sr-only)보조 기술에는 묶음 이름이 남는다 |
groupDivider | enabled | 높이height | 1px |
| 상하 바깥 여백marginY | spacing-x28px | ||
| 좌우 바깥 여백marginX | spacing-x28px선 폭 24 — 아이콘 칸 가운데 | ||
| 배경background | stroke-neutral-subtle#EDEFF3다크 #353B4D | ||
item | enabled | 너비width | 40px56 − 좌우 8 |
| 좌우 여백paddingX | spacing-x2_510px아이콘이 56 가운데(화면 끝에서 18) | ||
itemLabel | enabled | 보이기display | 보이지 않게(sr-only)이름은 남는다 — 보조 기술 · 말풍선 · 펼침 메뉴 |
chevron | enabled | 보이기display | none |
subItem | enabled | 보이기display | none하위는 펼침 메뉴(flyout)로 — 마우스를 올리거나 누르면 |
SEED 와 다른 점
- 흰 면 + 오른쪽 선 — SEED 기본
tone=neutral은 회색 면(gray-100)이다. groo 본문이 회색(bg-page)이라 사이드바를 흰 면(bg-layer-default)으로 둔다(따라오는 것).transparent톤은 두지 않는다 — SEED 의 고르는 기준은 "Neutral — 정보가 많거나 위계가 높을 때 권장 / Transparent — 미니멀한 레이아웃" 이고, groo 는 본문이 회색이라 흰 면이 맞다. 본문이 흰 서비스가 생기면 그때 다시 본다(남은 규칙 R21 — 그대로, 2026-10-22 https://claude.ai/artifact/Mag1tEv51MdQHdy1o8hY3L). - 투명한 상태 색을 불투명 역할로(v102) — 호버 · 누름
bg-layer-default-pressed, 선stroke-neutral-subtle. 지금 항목은 SEED 의 옅은 선택 바탕보다 한 단계 짙은bg-neutral-weak-pressed다(사용자 결정 2026-10-08 —bg-neutral-weak는 다크에서 호버 바탕과 같은 색 #353B4D 였다). 지금 항목은 마우스를 올리거나 눌러도 바탕이 그대로다 — SEED 는 선택 · 누름 바탕(selected-pressed)이 따로 있지만 groo 에는 그보다 짙은 불투명 역할이 없다. - 아이콘은
fg-neutral-subtle— SEED palette.gray-600 은 면 위 1.97:1 이다. - 긴 이름은 줄을 바꾼다 — SEED 문서대로다(SEED 레시피는 한 줄 말줄임).
- 처음 열 때도 폭을 본다 — SEED 코드는 창 폭이 1280 을 넘나들 때만 접고 펴서, 1000 으로 열면 펼친 채다. 768 미만의 서랍도 SEED 코드에는 없다.
- 접기 버튼은 누르는 영역 44 · 이름 "사이드바" +
aria-expanded— SEED 는 40 이고 이름만 "사이드바 열기" · "사이드바 닫기" 로 바꾼다.nav에 이름("주 메뉴")을 단다 — SEED 는 이름이 없다. - 접혔을 때 묶음 사이 1px 선 — SEED 는 묶음 이름 자리를 접어 간격만 남긴다(비교 페이지 8A 그림을 따랐다).
- 펼침 메뉴의 줄은 44 하나 — SEED 는 Menu
size="responsive"(1280 미만 medium 46 · 이상 small 39)다. groo Menu 는 small 하나뿐이고 1280 미만은 Menu Sheet 라, 사이드바의 펼침 메뉴만 Menu 표면 + 줄 44 로 두고 1280 미만에서도 시트로 바꾸지 않는다 — Menu 경계의 예외(사용자 결정 2026-10-08). - 아래 끝 흐림은
gradient-fade-mask24 — 깊이는 SEED 레시피와 같다.
Migration notes
2026-10-30 — 그루 이음 바닥 계정 줄 · 하위 페이지 돌아가기(스펙 정리)
화면 결정으로 틀리게 된 문장을 결정대로 고쳤다 — 새 규칙이 아니다.
- 그루 이음 바닥 계정 줄(2026-10-23 사용자 결정 H-A3 A) — "HR 적용 때 정한다" 로 열어 둔 자리. 그루 이음은 바닥에 계정 줄 + 메뉴(내 정보 · 비밀번호 바꾸기 · 화면 테마 · 로그아웃)를 둔다. Desk 바닥에는 그대로 계정을 두지 않는다(Q-018-1 C).
- 하위 페이지 돌아가기(2026-10-23 사용자 결정 Q1-A) — "그때 정한다" 로 열어 둔 자리. 데스크톱은 제목 줄 위 "‹ {부모}" 글 단추(ghost small · 꺾쇠 14 · 적힌 부모로), 폰은 상단 바 ←. 거절: ← 아이콘 단추(B) · 없음(C).
2026-10-22 — 이동 부품 표 링크 · transparent 톤의 까닭
머리말의 다른 이동 부품 안내를 DESIGN.md Layout 의 "이동 부품 고르기" 링크로 바꿨다(6B). "transparent 톤은 두지 않는다" 는 그대로 두고 SEED 의 고르는 기준 한 줄을 함께 적었다(남은 규칙 R21). 사용자 결정 — https://claude.ai/artifact/Mag1tEv51MdQHdy1o8hY3L. 값 변경 없음.
2026-10-21 — 단위(03-G 1A)
접기 버튼 size-10 · 항목 min-h-11 · 아이콘(rem)이 글자 200% 에서 두 배가 됐다(조사의 "px 고정" 은 틀렸다 — 아이콘 18 만 px). 레시피를 size-[40px] · min-h-[44px] · w-[40px] · 아이콘 [24px] · [20px] · 꺾쇠 [16px] 로. 비교 페이지 https://claude.ai/artifact/A3oCdxNvDwkNBPFPE36bmF.
2026-10-16 — 바닥 계정 · 증권 부모 · 홈 두 칸
사용자가 구현 질문 Q-017 · Q-018 비교 페이지에서 정했다(2026-10-16).
-
바닥 계정(Q-018-1 C) — 두지 않는다. 바닥은 보조 링크만, 비면 그리지 않는다. 설정으로 가는 항목(A) · 계정 메뉴(B) · SEED 처럼 머리에 계정(D)은 고르지 않았다.
-
증권 부모(Q-017-4 정리) — 연결한 증권사가 둘 이상일 때만 부모(펼치기만), 하나 · 없으면
/desk/stocks단독 링크(꺾쇠 없음), 구독이 없으면 숨김. -
홈 두 칸 경계(Q-017-6 A) — Desk 데스크톱 홈의 두 칸도 1280 부터다(사이드바가 펼쳐지는 폭 — DESIGN.md "문턱 — 768 · 1280"). 768 ~ 1279 는 한 칸.
-
Desk 웹 — 바닥 사용자 버튼(⇕ · 임시 브랜치의 설정으로 가는 이름 줄)을 걷는다. 증권은 부모가 이동 + 펼침(
GrooSidebar.tsx:96-101)이다 — 둘 이상이면 펼치기만 · 하위 링크로.groo.css의@media (max-width: 1100px) { .dash-grid … }를 1279 로(1280 부터 두 칸),useDeviceSize는 mobile · desktop 둘로("tablet"을 읽는 코드는 0).
2026-10-10 — 하위 펼침 300ms
펼치고 접기 · 나누기 비교 페이지 3번에서 사용자가 아코디언의 꺾쇠 · 펼침을 SEED d6 300ms ease-easing 으로 정하며 사이드바 하위 펼침도 같게 했다(3A) — 그전의 d4 200ms 는 화면 틀 라운드에서 스펙 초안이 둔 값이었고 사용자가 고른 값이 아니다. 하위 펼침 · 꺾쇠 회전이 300ms 다. 모션 줄이기면 높이 움직임 없이 150ms 서서히, 꺾쇠는 바로다(v104). 사이드바 폭이 바뀌는 펼침 ↔ 접힘은 그대로 200ms 다. 지금 Desk 웹 증권 하위는 꺾쇠 150ms · 하위 목록 움직임 0, HR 은 200ms 이고 모션 줄이기를 따르지 않는다(2026-10-09 조사 §7.1 · D9).
2026-10-08 — 펼침 메뉴는 1280 미만에서도 · 지금 항목은 한 단계 짙게
스펙을 쓰다 남은 둘을 사용자가 화면 틀 · 이동 비교 페이지 12 · 13 그림으로 정했다. 접힌 사이드바(768 ~ 1279)의 하위는 누른 아이콘 옆 펼침 메뉴(Menu 표면 · 폭 200 · 줄 44 · 지금 화면 줄 표시)이고, Menu 의 "1280 미만은 Menu Sheet" 규칙의 예외로 적는다 — Menu Sheet(12B)는 고르지 않았다. 지금 항목은 바탕만 한 단계 짙게(bg-neutral-weak-pressed — 다크에서 호버 바탕 #353B4D 와 갈린다) 하고 글자는 500 그대로다(SEED) — 굵기 700(13A · 13C)은 고르지 않았다. 색으로만 알리는 1.4.1 ⚠ 는 사용자 결정으로 남긴다(낭독은 aria-current). 펼침 메뉴의 지금 줄도 같은 규칙이다. 지금 항목을 누를 때 쓸 더 짙은 불투명 역할이 없어 바탕은 그대로 두고 축소만 한다.
2026-10-04 — SEED Side Navigation 으로 새로 둔다(옛 Sidebar 를 대신)
사용자가 화면 틀 · 이동 비교 페이지에서 정했다 — 768 ~ 1279 는 아이콘만(56)으로 저절로 접히고 1280 이상은 펼침(240), 손으로 접고 펼 수 있고 손으로 접은 상태는 기억한다(8A). 빵부스러기는 걷고 위치는 사이드바의 지금 항목(부모 자동 펼침) + 본문 제목이 알린다(9B — HR 머리가 없어진다). 그리고 "따라오는 것" — 머리 64 + 접기 버튼 40 · 18 을 머리 안으로 · 항목 44 · 아이콘 20 · 14 / 19 · 500 · 모서리 10 · 묶음 이름 14 / 19 · 700 · 지금 항목 옅은 회색 + 짙은 글자 · 부모는 펼치기만 · 하위가 지금이면 저절로 펼침 · 접힘에서 하위 = 펼침 메뉴, 단독 = 말풍선 · 긴 이름 줄바꿈 · 흰 면 + 오른쪽 선 · HR inset 걷음. 768 ~ 1279 에서 펼친 채(8B)는 고르지 않았다. 접힌 사이드바의 하위 펼침 메뉴는 이 스펙 안에서 Menu 모양으로 정의한다(Navigation Menu 는 걷었다 — navigation-menu.history/v-pre-seed-nav.*). 옛 Sidebar(shadcn — 256 · 48 · 모바일 Sheet 288 · 항목 32 · 아이콘 16 · 15 · 모서리 4 · Ctrl/⌘ + B · 쿠키 · floating · inset)는 걷었다 — 옛 스펙은 sidebar.history/v-pre-seed-nav.*.
제품은 앱 적용 단계에서 옮긴다(2026-10-04 조사 — Desk 웹 · HR 은 크로미움에 띄워 쟀다).
- Desk 웹 —
widgets/layout/ui/GrooSidebar.tsx:186-263·widgets/layout/model/nav.ts:34-61위 shadcnshared/ui/sidebar.tsx. 256 · 접힘 48 · 항목 32 · 14 / 400 · 아이콘 16 · 지금 항목 #F0F2F7 + 500. 768 · 1024 · 1100 에서도 256 으로 펼쳐져 본문이 512 까지 좁아진다(F24). 주 메뉴가nav가 아니라div+ 목록이다(sidebar.tsx:216-251, F16). "증권" 은 누르면 이동 + 펼침이다(GrooSidebar.tsx:108-112) — 펼치기만으로. 접힌 로고 버튼 이름이 "" 이고 눌러도 아무 일이 없으며, 사용자 버튼(⇕)도 동작이 없다(:193-213 · 226-256, F15). - HR 웹 —
widgets/sidebar/ui/AppSidebar.tsx:66-82·SidebarContent.tsx:81-190·SidebarFooter.tsx:72-134·shared/ui/shadcn/treeView.tsx. 288 inset(본문 상자 모서리 12 · 그림자 —widgets/layout/ui/Layout.tsx:16-31) · 접힘 66. 실제 화면인 잎 항목이div+ onClick 이라 키보드로 닿지 않고 누르면 초점이 body 로 간다(treeView.tsx:416-447, 부모는 Accordionh3—:299-355 · 457, F1). 묶음 이름 2.54 · 메뉴 글 4.23(F18), 묶음 이름이 회사 이름("SKC")이고 묶음 "관리자" 안에 항목 "관리자" 가 있다(F28). - 접힘 기억 — 두 웹 모두 쿠키
sidebar_state를 쓰기만 하고 읽지 않아 새로 고치면 펼쳐진다(웹sidebar.tsx:60-77· HRshadcn/sidebar.tsx:69-86, F14). localStorage 로. - 접힌 사이드바 — Desk 는 말풍선만(하위는 숨김), HR 은 말풍선 + 눌러 여는 하위 메뉴(
SidebarContent.tsx:134-172)다. 말풍선 · 펼침 메뉴로. - 이름이 영어 — "Toggle Sidebar"(접기 · 레일) · 모바일 시트 "Sidebar" · "Displays the mobile sidebar."(F26). "사이드바" · "주 메뉴" 로.
- 앱 적용 때 정할 자리 — 사이드바 항목 이름과 화면 제목 맞추기("통계 · 분석" · "통계"). HR 계정 메뉴는 2026-10-23 바닥 계정 줄 + 메뉴로 정했다(H-A3 A). Desk 사용자 버튼(⇕)은 2026-10-16 걷기로 정했다(위).
Select
짧은 선택지 5개 이상에서 폼에 넣을 값을 고르는 칸. 결제 수단 · 통화 · 휴가 정책 · 반복 단위처럼 한 줄 글(+ 한 줄 설명)로 충분한 선택지를 칸 아래 목록으로 연다. 달력 · 시각 · 아이콘 격자 · 검색이 필요한 긴 목록은 Input Button, 설명 · 그림이 붙는 2 ~ 6개는 Select Box다.
Side Panel
화면 옆(왼쪽 · 오른쪽)에서 미끄러져 나오는 모달 패널. 지금 쓰는 곳은 HR 폰(768 미만)의 주 메뉴 서랍 하나다 — ☰ 를 누르면 왼쪽에서 나와 Side Navigation 의 항목을 보인다. 오른쪽 패널(1280 이상의 보조 작업)은 쓰는 곳이 아직 없다. 아래에서 올라오는 모달은 Bottom Sheet, 가운데 대화상자는 Dialog 다. 이동 부품(하단 탭 바 · 사이드바 · 상단 바 · Tabs)과 고르는 표는 DESIGN.md Layout 의 "이동 부품 고르기" 한 곳이다.