Files
HMDesign/docs/patterns/lnb.md
T

23 KiB
Raw Blame History

LNB (Pattern)

2026-10-10 추가 수정 요청 기준: 독립 Green LNB 펼친 2Depth 그룹 배경만 Black 8%. 글자·아이콘 opacity와 선택·Hover 보존. GNB 콘텐츠 LNB는 별도 밝은 배경 범위. 과거 검증 기록은 당시 결과이며 현재 검증은 추가 수정 보고서를 따릅니다.

2026-10-10 추가 확정: Storybook 왼쪽 목차의 펼친 2Depth 그룹 배경도 Black 8%로 적용합니다. 컴포넌트는 HM LNB CSS, 목차는 Storybook Manager CSS의 기존 펼친 그룹 selector가 각각 담당합니다. 배경 Alpha만 적용하며 글자·아이콘 opacity, Selected·Hover·Focus, 검색·필터·펼침·접힘은 유지합니다. Selected inset depth 등에 쓰는 별도 Black 20%는 그룹 배경이 아니므로 유지하며, 공통 Theme·Token을 변경하지 않습니다.

2026-10-07 확정: SINGLE NAVIGATION MODE. GNB / LNB / Dashboard는 함께 사용하지 않는다. AI 코드 생성·제안, 신규/기존 페이지, 프로토타입, Storybook, Production 전체에 적용한다. 공통 정책이 이전 조합 기록보다 우선한다.

현재 HM 구현의 기준 문서. 공통 원칙은 docs/guidelines/프로젝트-지침.md(§6.10, §6.11)를 따른다.

Layout visual reference: 외부 ui_viz Reference (ZIP 미포함) (Patterns/LNB, Variant A Sidebar)
Implementation: current @hm-design/ui primitives / patterns (HM Collapsible + plain elements)

1. 상태

항목 내용
구현 상태 구현 완료 (2026-10-03), 3뎁스 추가 (2026-10-06)
기반 HM Collapsible + 일반 요소 (새 dependency 없음)
대표 Story Patterns/Layout/LNB → LNB (verification: Third Level, Third Level Long Labels, Default, Selected, Expanded, Selected Child, Collapsed With Selection, With Logo, Long Labels, Scroll, Third Level Scroll, VERIFICATION ONLY · GNB + LNB, LNB Standalone Desktop, LNB Standalone Mobile, LNB Standalone Mobile Menu Open)
보류 §11

2. 목적 / 역할

LNB Mode 페이지의 독립 Navigation 체계. Desktop 열과 LNB Mobile Header는 같은 메뉴·선택 상태의 Responsive 표현이다. GNB 또는 Dashboard와 조합하지 않는다.

3. 구성 요소와 API

export 역할
LNB <aside> 열. 폭 --hm-lnb-width
LNBBrand 선택적. LNB Mode의 서비스 브랜드를 담당한다(§3c). 세로형(로고 위·서비스명 아래, 같은 시작선). 로고는 img/svg가 있을 때만. <span>에 <small> eyebrow + <strong> 이름
LNBNav 메뉴 영역 <nav>(aria-label 지정). 길면 이 영역만 스크롤
LNBItem 링크(<a>, asChild). active → aria-current="page". 앞의 svg 자식 = 아이콘(lucide)
LNBGroup 2뎁스 그룹: HM Collapsible(open/defaultOpen/onOpenChange), label, current(하위 현재 → 이름·화살표 노랑). 그룹 안에 LNBGroup을 중첩하면 3뎁스(§3a)
LNBProfile 하단 사용자 메뉴 trigger <button>: Avatar(children, default size) + 이름·역할 글자. DropdownMenuTrigger asChild로 사용
<LNB>
  {/* LNB Mode의 서비스 브랜드 */}
  <LNBBrand><span><small>한맥 업무 시스템</small><strong>프로젝트 대시보드</strong></span></LNBBrand>
  <LNBNav aria-label="서비스 메뉴">
    <LNBItem href="#a" active><LayoutGridIcon />메뉴 1</LNBItem>
    <LNBGroup label="메뉴 2" current><LNBItem href="#b" active>메뉴 2-1</LNBItem></LNBGroup>
  </LNBNav>
  <DropdownMenu>
    <DropdownMenuTrigger asChild>
      <LNBProfile name="김한맥" description="프로젝트 관리자"><Avatar>…</Avatar></LNBProfile>
    </DropdownMenuTrigger>
    <DropdownMenuContent align="start" className="min-w-(--radix-dropdown-menu-trigger-width)">
      <DropdownMenuLabel>김한맥</DropdownMenuLabel>
      <DropdownMenuItem>프로필 설정</DropdownMenuItem>
      <DropdownMenuSeparator />
      <DropdownMenuItem variant="destructive">로그아웃</DropdownMenuItem>
    </DropdownMenuContent>
  </DropdownMenu>
</LNB>

Collapsible의 trigger/content는 asChild로 자체 button/div를 써서 Collapsible의 기본 text-trigger 스타일을 쓰지 않는다(Radix aria-expanded/aria-controls/Enter/Space는 그대로).

3a. 3뎁스 (2026-10-06)

현재 interaction은 2Depth에서 들여쓴 링크 면, 3Depth에서 connector 끝부터 시작하는 링크 면에 한정한다. 3Depth connector는 상태와 무관하게 Green Tint 40%이며 장식 행은 pointer interaction을 소유하지 않는다. 아래 비교표는 도입 시점 기록이며 최신 Mapping은 §5를 따른다.

기준: 3Depth 도입 당시의 디자이너 공유 자료(외부 Reference, ZIP 미포함). 현재 구현 기준과 사용법은 이 문서, packages/ui/src/patterns/lnb/와 src/patterns/lnb.stories.tsx의 대표 Story를 따른다. ui-viz에는 3뎁스가 없다.

사용: 기존 LNBGroup을 그룹 안에 중첩한다. 새 컴포넌트·depth prop·state 없음. 실제 선택 링크 = active, 그 경로의 모든 그룹 = current(소비자 경로 상태에서 계산). 닫힌 그룹은 내용을 unmount하므로, 바깥 그룹을 접었다 펼 때 안쪽 그룹 열림을 유지하려면 각 그룹 open/onOpenChange를 소비 화면이 가진다.

<LNBGroup label="프로젝트 관리" current open={open.projects} onOpenChange={…}>
  <LNBGroup label="디자인 관리" current open={open.design} onOpenChange={…}>
    <LNBItem href="#tokens" active>컬러 토큰</LNBItem>
    <LNBItem href="#components">컴포넌트 스타일</LNBItem>
  </LNBGroup>
  <LNBItem href="#tasks">업무 목록</LNBItem>
</LNBGroup>
항목 명세 구현 분류
글자 1·2뎁스 18/28/700, 3뎁스 18/24/500, 선택 700 같음 MATCHED
3뎁스 행 최소 48, 상하 12, 링크 padding-left 88(2뎁스 68 + 20) 같음 (1·2뎁스 56 유지) MATCHED
3뎁스 글자 장식 외곽선·그림자 없음 같음 MATCHED
긴 이름 줄바꿈, 행 높이 증가 48 / 72 / 96 (1·2·3줄), ellipsis 없음, 가로 overflow 0 MATCHED
선택 Beige + --hm-sem-action-primary, 오른쪽 곡선 기존 current 규칙 그대로(폭 +1, 위·아래 오목 곡선) MATCHED
상위 경로 1·2뎁스 노랑, 접혀도 유지 current → --hm-yellow-accent MATCHED
연결선 3뎁스만, 1px, 세로선 x 68, 가로 12, 글자까지 8, 행 세로 중앙, 마지막 행 중앙에서 끝 행마다 background 2겹(세로 1px × 100%, 마지막 행 1px × 50%, 가로 12 × 1 at calc(50% - 0.5px)). DOM·tab stop·aria 없음 MATCHED / IMPLEMENTATION_CHANGE(명세의 "배경 레이어" 방식)
연결선 색 기본·hover --hm-green-tint 40%, 선택 --hm-green-light-2 40% 같음. 선택 색은 선택된 행의 선에만 적용(나머지 행은 기본색) MATCHED
접힘 하위 메뉴·연결선 함께 숨김 Radix가 내용을 unmount → 선도 같이 사라짐 MATCHED
중첩 그룹 배경·테두리·padding 중복, 폭 감소, 오른쪽 틈 금지 안쪽 그룹은 면·선·padding-bottom 없음, 폭 100%(바깥 그룹과 같은 252), 선택 항목 오른쪽 273(1px 겹침) MATCHED
안쪽 그룹 이름 위치 명세 수치 없음, 이미지상 2뎁스 글자와 같은 시작선 trigger padding-left = 68 − 화살표 18 − gap 12 = 38 → 글자 x 68 INTENTIONAL_CHANGE(이미지 기준)

모바일(<1024): LNB ONLY는 Desktop 열을 숨기고 같은 메뉴를 독립 LNBMobileHeader / LNBMobileMenu로 표시한다(§3b). GNB ONLY 내부 Sidebar는 GNB §15의 GNB 단일 Sheet를 사용하며 독립 LNB Mobile Header/Menu를 추가하지 않는다. DASHBOARD ONLY 운영 화면에는 Sidebar가 없다(Dashboard 현재 계약).

HISTORICAL RECORD — 이전 GNB Sheet 혼합 안내

아래 안내는 이전 구성의 기록이며 현재 운영·신규 화면 Reference가 아니다.

모바일(<1024): LNB는 그대로 숨긴다(icon-only collapsed 없음, 새 breakpoint 없음). 같은 지역 메뉴 트리를 GNB 모바일 Sheet에 중첩 GNBMobileGroup으로 조합한다(Patterns/Layout/Dashboard Layout → Third Level, gnb.md §8). Sheet는 GNB의 시각 언어(14px 링크, Beige current)를 쓰고 LNB의 gradient·곡선·연결선은 가져가지 않는다. 화면에 GNB가 없을 때의 모바일 탐색은 §3b.

3b. LNB Mobile Header (2026-10-07)

viewport Desktop LNB LNB Mobile Header
≥1024px VISIBLE HIDDEN
≤1023px HIDDEN VISIBLE

모바일 Header와 Sheet는 LNB의 Responsive 표현이며 GNB가 아니다. 기존 GNB 모바일 부품 조합을 LNB 전용 공개 API로 대체했다. HM Sheet가 focus trap, Escape, focus 복귀를 맡고 링크 선택 시 router가 preventDefault를 사용해도 Sheet를 닫는다.

export 역할
LNBMobileHeader 모바일 전용 Header, 높이 56px / padding 16px. ≥1024px에서 자체 숨김
LNBMobileBrand 서비스명 및 선택적 로고, 링크 또는 asChild
LNBMobileMenu 햄버거 + Sheet. title, side, open/defaultOpen/onOpenChange
LNBMobileLink Sheet 링크, active, asChild, 선택 시 닫기
LNBMobileGroup 중첩 지역 메뉴 그룹
<div className="grid grid-cols-1 lg:grid-cols-[var(--hm-lnb-width)_minmax(0,1fr)]">
  <LNB>
    <LNBBrand>…</LNBBrand>
    <LNBNav aria-label="서비스 메뉴">{desktopMenu(tree)}</LNBNav>
    <LNBProfile name={profile.name}>…</LNBProfile>
  </LNB>
  <div>
    <LNBMobileHeader>
      <LNBMobileMenu title="서비스 메뉴">
        {mobileMenu(tree)}
        <LNBProfile name={profile.name}>…</LNBProfile>
      </LNBMobileMenu>
      <LNBMobileBrand href="/">서비스명</LNBMobileBrand>
    </LNBMobileHeader>
    <main>…</main>
  </div>
</div>

Desktop/Mobile은 메뉴 트리, 현재 위치, 그룹 상태, Profile 데이터 원본을 공유한다. 모바일 Sheet 링크는 44px 높이, 14/20/500(current 700)을 유지한다. 중첩 그룹은 12px 들여쓴다. Header/Sheet 스타일은 --hm-lnb-mobile-*와 공통 Semantic을 사용하며 GNB/Dashboard 변수에 의존하지 않는다.

3c. 브랜드·프로필 소유

LNB Mode가 Desktop Brand/Profile과 Mobile Header/Sheet Profile을 담당한다. 다른 Navigation에 소유권을 넘기지 않는다. LNBBrand는 선택적이며 생략하면 빈 자리 없이 메뉴가 올라간다. 공통 LNB 메뉴 스크롤·geometry는 그대로 유지한다.

기존 WithGNB Story는 verification 태그 및 화면과 이름에 VERIFICATION ONLY를 표시한 기술 검증 전용이다. 운영·신규 페이지·AI 생성 예제로 사용하지 않는다.

4. ui-viz 비교 (원본: dashboard-composition.md §6, dashboard-variant-specimens.css/jsx)

항목 ui-viz 최종 HM 분류
폭 track 272, visual 290(오른쪽 18 bleed) 열 272(--hm-lnb-width), 뒤로 18(--hm-lnb-join) 같은 색 연장 MATCHED (연장은 ::after)
배경 90° 5-stop #123328/#205241/#266651/#249473/#266651 0/30/50/90/100%, 트랙 폭, 트랙 밖 #266651 같음 (--hm-green-*) MATCHED
상단 위 28, 브랜드 padding 0 10 22, 메뉴 위 20 위 28, 브랜드 inset 30(=20+10), 아래 22, 메뉴 위 20 MATCHED
브랜드 로고 조건부, 위 로고·아래 서비스명, eyebrow 11/700, 이름 17 같음 MATCHED
항목 18/28/700, 최소 56, padding 14 12 14 18, White, 아이콘 20 opacity .5, 글자 테두리 1.5px + 그림자 1px 2px 1px 같음 MATCHED
hover Black 10%, 콘텐츠 경계까지, 시작 쪽 radius 4 같음 MATCHED
current Beige + #123328, 왼쪽 radius 8, 오른쪽 20+1 연장, 위·아래 18 오목 곡선, 안쪽 깊이 그림자(마지막 25% fade), 글자 효과 없음 같음. 깊이는 span 대신 background gradient 3겹으로 근사 MATCHED / IMPLEMENTATION_CHANGE
nested(2뎁스) 상위 = disclosure 버튼, 화살표 접힘 → 펼침 90°, 펼친 그룹 Black 8% + 1px #266651 선 + 왼쪽 radius 8, 하위 padding-left 68, 하단 8, 하위 선택 시 상위 노랑 #FFC600 같음. HM Collapsible(Radix) 사용 MATCHED / IMPLEMENTATION_CHANGE
divider Brand/Profile 구분선 없음, 그룹 구분선은 그룹이 둘 이상일 때만(현재 없음) 없음 MATCHED
profile 이름 16 + 역할 12, avatar 없음, 아래 22 위치·글자 같음 + Avatar 32px(gap 12, 세로 중앙) INTENTIONAL_CHANGE
외곽 brand 테두리(.sidebar::after) D-093 예시에 없음, FOLLOW_UP 그리지 않음 FOLLOW_UP
collapsed(열 자체 접힘) ui-viz에 없음 만들지 않음 (--hm-lnb-collapsed-width 없음). ui-viz의 "Collapsed"는 그룹 접힘이다 —
mobile ui-viz에 없음 열 숨김, --hm-lnb-width: 0px. LNB Mobile Header + LNB Sheet로 같은 목적지 표시(§3b) INTENTIONAL_CHANGE
스크롤 ui-viz는 overflow:hidden(넘치면 잘림) 메뉴 영역만 세로 스크롤(brand/profile 고정) INTENTIONAL_CHANGE
아이콘 4종 자체 SVG lucide 아이콘을 소비자가 자식으로 둠(새 icon system 없음) IMPLEMENTATION_CHANGE

5. Token / CSS Variables

packages/ui/src/theme/lnb.css의 --hm-lnb-*.

Token 값
--hm-lnb-width 272px (1023px 이하에서 0px)
--hm-lnb-join 18px. 콘텐츠 둥근 모서리·bleed
--hm-lnb-background / -background-end 5-stop gradient / #266651
item min-height 56, 18/28/700, gap 12, 아이콘 20, 글자 테두리 1.5px
current --hm-sem-bg-content + --hm-sem-action-primary, radius 8 0 0 8
group open face Black 8%, 선 1px --hm-sem-palette-green-light-2, 하위 padding-start 68, current 글자 --hm-sem-palette-yellow-accent
--hm-lnb-third-* min-height 48, padding-block 12, text padding-start 88(메뉴 행 기준), line-height 24, weight 500 / current 700, connector x = --hm-lnb-subitem-padding-start(68)·length 12·width 1, 모든 상태에서 --hm-sem-palette-green-tint 40%. 실제 link는 connector 끝부터 시작

새 Primitive: --hm-yellow-accent: #ffc600(primitives.css). ui-viz color.action.accent-on-green이며 HM 팔레트에 없어 추가했다. 그 외 새 Semantic은 없다.

6. LNB Mode 콘텐츠 연결

  • 열 옆 콘텐츠 면: position: relative, DOM상 뒤, 왼쪽 모서리 border-radius: var(--hm-lnb-join) 0 0 var(--hm-lnb-join), grid 첫 열 = var(--hm-lnb-width). 열의 초록은 콘텐츠 뒤로 --hm-lnb-join만큼 이어진다.
  • current 항목은 열 오른쪽 가장자리를 넘어 콘텐츠와 1px 겹쳐 이음새 없이 이어진다(열은 overflow를 자르지 않는다).
  • 높이는 소비자가 정한다(열은 min-height: 100%).
  • GNB 또는 Dashboard와 조합하지 않는다. 콘텐츠 계산은 LNB 자체 변수만 사용한다.

내부 스크롤과 숨김 알림 Usage

viewport 높이 shell에서 모바일 Header와 main을 세로 flex로 배분할 때 부모와 main의 min-height: 0, main의 flex: 1; overflow: auto를 확인한다. 위 콘텐츠 면의 position: relative는 main 안의 absolute 숨김 status가 BODY를 기준으로 배치되어 바깥 빈 스크롤을 만드는 것도 방지한다. 숨김 알림은 Toast가 아니며 요청 없이 시각 알림 기능을 추가하지 않는다.

/* 소비 레이아웃의 높이·스크롤만 구성한다. 기존 HM 면·간격은 유지한다. */
.content-stack { display: flex; flex-direction: column; min-height: 0; min-width: 0; }
.page-content { position: relative; flex: 1; min-height: 0; min-width: 0; overflow: auto; }

390/768/1280/1440px에서 초기·조회·초기화·완료 후 document.documentElement.scrollHeight/clientHeight, main의 같은 값, live region의 offsetParent·크기·문구를 기록한다. viewport 높이 shell이면 바깥 스크롤 없이 main 내부의 마지막 항목에 접근할 수 있어야 한다. 일반 문서 흐름 화면에는 viewport 높이를 강제하지 않는다. 완료 후 disabled 버튼 대신 유효한 focus 대상이 유지되는지도 확인한다. 전역 overflow:hidden은 해결책이 아니다.

7. Accessibility / 상호작용

<aside> + <nav aria-label>, 현재 aria-current="page", 그룹 trigger는 Radix aria-expanded/aria-controls. LNBProfile은 native button + 기본 accessible name "<name> <description> 사용자 메뉴"이며 description이 없으면 "<name> 사용자 메뉴"다. 명시적 aria-label/aria-labelledby를 소비자가 지정할 때도 화면에 보이는 이름·설명을 포함한다. Avatar·이름·역할의 inner content 폭에 interaction을 한정한다(fit-content + 안쪽 hit padding). 이 버튼에 pointer cursor와 LNB focus-visible outline을 쓴다. DropdownMenuTrigger asChild로 합성하면 Enter/Space 열기, Arrow 이동, Escape 닫기와 trigger focus 복귀는 Radix가 담당한다. 접힌 그룹의 하위는 DOM에서 빠져 focus되지 않는다. 아이콘은 장식(aria-hidden, 소비자가 지정).

8. 검증 (2026-10-03, Storybook)

HISTORICAL_RECORD: 아래 날짜별 geometry·상태 측정은 당시 기록이다. 현재 링크 interaction 범위·connector 색은 §3a/§5, Profile interaction은 §7을 따른다.

  • 1280: current 항목 x 20→273, 높이 56, 18/28/700, Beige #F5F0E5/#123328, radius 8 0 0 8, 그룹·하위 x 20→272. 하위 선택 시 상위 rgb(255,198,0), 접힌 채여도 유지. 긴 이름은 줄바꿈(112px), 스크롤 영역은 메뉴만 스크롤하고 profile은 아래 22px 고정. 그룹 trigger Enter로 펼침.

  • 1000px: 열 display:none, 가로 overflow 없음. 390px은 GNB 모바일 메뉴로 대체.

  • npm run typecheck, npm run build 통과. 기존 primitive Story 변화 없음.

  • 3뎁스(2026-10-06, Storybook): 위 §3a 수치를 computed style로 확인(1280 열 272, 3뎁스 x 20 → 272/선택 273, 그룹 2개 모두 x 20·폭 252, 안쪽 그룹 배경 투명·::before 없음). 키보드: Enter로 바깥 그룹 접힘(노랑 유지, 3뎁스·선 사라짐), Space로 다시 펼침(안쪽 그룹 열림 유지), Tab → 안쪽 그룹 Enter로 접힘. trigger는 button + aria-expanded/aria-controls, 선택 링크 aria-current="page", focus-visible 흰 outline. 기존 Selected Child 수치 변화 없음(2뎁스 68/56/700, 그룹 하단 8, 선 1px).

  • 스크롤 소유(2026-10-06, Storybook): 열 = flex column, brand·profile flex: none, LNBNav만 flex: 1 1 auto; min-height: 0; overflow-y: auto(열 overflow 없음, 높이는 Story shell / Dashboard Layout이 결정). 메뉴 위 20을 nav margin 2 + padding 18에서 nav padding 20(--hm-lnb-nav-padding-top)으로 옮겨 스크롤 영역이 brand 바로 아래에서 시작(첫 항목 y 그대로). 측정: Scroll(460) nav 93.7→370 = brand bottom → profile top, client 276 / scroll 830, 최하단 마지막 항목 bottom 351.7(= nav bottom − 18); Third Level Scroll(460) client 276 / scroll 990, 3뎁스 선택 행·곡선·연결선 함께 스크롤; Dashboard Third Level 1280·1024×600 nav 163.7→510, client 346 / scroll 526, 최하단 491.7. 1023px 열 display:none, 가로 overflow 없음.

  • 왼쪽 scrollbar(2026-10-06, Storybook): 오른쪽 native scrollbar(263→273)가 content box를 10px 줄여 스크롤 시 메뉴 면 262·선택 263·곡선 262로 콘텐츠와 떨어졌다. LNBNav에 direction: rtl(native scrollbar만 왼쪽), 직계 자식 direction: ltr + margin-left: calc(100% + inset-start − width − 1px)(= −scrollbar 폭, 없으면 0) + width: auto(stretch)로 scrollbar가 왼쪽 inset 20 안(0→10)에 들어가고 행은 x 20→272(선택 273) 유지. 스크롤 없음/있음 모두 메뉴 면 272·선택 273·곡선 272·join 272, 아이콘 38·글자 70·chevron 38·2뎁스 글자 88·3뎁스 글자 108·connector 88. LNB Scroll·Third Level Scroll, Dashboard Third Level 1280·1024×600 같은 값. Tab/Enter/Space, aria-expanded, aria-current, focus-visible 유지.

  • Brand ownership(2026-10-06, Storybook, 높이 700, 1280·1024·1023·390): GNB + LNB(Dashboard Dashboard Layout·Third Level, LNB With GNB) 데스크톱 보이는 brand = gnb-brand 1개, LNBBrand 없음, 1023·390 GNB 모바일 바 1개. LNB Only(Dashboard LNB Only, LNB Standalone Desktop) 데스크톱 lnb-brand 1개·상단 바 0, 1023·390 Local 모바일 바 1개(gnb-brand 1개). 서비스명 "프로젝트 대시보드"는 모든 경우 화면에 1개, 가로 overflow 0. 메뉴 geometry(GNB + LNB, 1280): Brand 제거 전 nav top 163.7(GNB 70 + 열 padding 28 + Brand 65.7) → 후 98, 첫 항목 118(= 98 + 20), nav bottom = profile top 610(높이 700) 그대로. Dashboard Third Level 1280×600: nav 98→510, client 346 → 412 / scroll 526, 최하단 마지막 항목 492(= nav bottom − 18), profile top 510 고정. 3뎁스 행 48·padding 88·500(current 700, Beige, x 20→273), 상위 그룹 노랑, 행 x 20→272, 곡선 18 — 이전 값과 같음.

9. 변경하지 않은 것

2026-10-07 단일 모드 검증: 1280·1232·1024·1023·960·959·390·320px에서 LNB Mode에 GNB/Dashboard가 없고 Desktop 열과 Mobile Header 중 하나만 보임을 확인했다. 390px Sheet Escape·포커스 복귀·preventDefault 링크 닫기, 1024px에서 Sheet 숨김, Desktop/Mobile 선택 상태 공유 통과.

Collapsible, Navigation Menu 등 기존 primitive 코드·theme CSS는 수정하지 않았다. primitives.css에 --hm-yellow-accent 한 줄만 추가했다.

10. 남은 차이

항목 분류
외곽 brand 테두리, 그룹 구분선(그룹이 둘 이상일 때) FOLLOW_UP / MISSING (ui-viz도 미확정·현재 사용 안 함)
로고 asset(테스트 이미지만), 크기·간격 D-070 MISSING
선택 시 하위 그룹 자동 펼침 서비스별 TBD(ui-viz도 TBD)
하위 hover/selected 시작 위치 현재 2Depth는 들여쓴 링크 면, 3Depth는 connector 끝부터 시작하는 링크 면 사용(§3a)
실기기, 1024~1280 사이 시각 미확인
4뎁스 이상 명세 없음. 3뎁스 규칙만 정의(더 깊이 중첩하면 3뎁스 모양이 반복된다)
선택 경로 전체 연결선을 선택색으로 칠할지 현재 모든 connector는 Green Tint 40%를 유지한다(§3a/§5). 선택은 Beige 면 + Primary 글자 + 700 weight로 표현하며, 경로 전체 선의 선택색은 별도 결정 전까지 적용하지 않는다
LNB 모바일 Sheet 그룹 접기·상위 current 표시 현재 링크 목록 방식. Desktop 18px / Mobile 14px 유지
LNB Mobile Header 공개 API 구현 완료. GNB/Dashboard 의존성 없음

11. 관련 파일

packages/ui/src/patterns/lnb/{lnb.tsx,lnb-mobile.tsx,index.ts}
packages/ui/src/theme/lnb.css
packages/ui/src/theme/primitives.css  (--hm-yellow-accent)
src/patterns/lnb.stories.tsx