feat(ui): standardize LNB sizing and active depth effect

- Adopt the official LNB desktop spec as package defaults: 240px column,
  14px menu text, 48px 1-depth rows and 42px 2/3-depth rows, with new
  item/subitem padding-block and profile min-height tokens.
- Match --hm-lnb-current-depth to the Storybook Manager selected item:
  sampled soft inset falloff (left/top/bottom) and a fade over the last
  quarter, keeping the concave corners and content join.
- Drop the size overrides from the LNB Story CSS and update the LNB, GNB
  and Dashboard docs, AI guides and the theme verification baseline.
This commit is contained in:
shkim4 committed 2026-11-09 21:34:28 +09:00
1 parent 89f265ae2f
commit e42b67c53a
9 files changed
+95 -75

No files matched your search

+1
View File
@@ -31,6 +31,7 @@
- 요청이 모드를 말하지 않으면 화면 목적(서비스 상단 메뉴 = GNB, 계층 업무 메뉴 = LNB, 운영 현황 = DASHBOARD)으로 고르고 **선택 근거를 보고**합니다. 임의로 Sidebar를 추가하지 않습니다.
- 혼합 요청(GNB + LNB 등)은 정책 충돌로 안내하고 하나를 고르게 합니다. Drawer·Hamburger 등 대체 메뉴를 추측해 만들지 않습니다.
- Breadcrumb·FilterBar·사용자 Dropdown은 Navigation 모드가 아닙니다.
- **LNB 크기의 기준은 패키지 토큰입니다.** `@hm-design/ui`의 `--hm-lnb-*`가 정의한 값(Desktop 열 240px, 메뉴 14/28/700, 1뎁스 행 48px, 2·3뎁스 행 42px, Profile 48px, 모바일 Header 56px·링크 44px)을 그대로 씁니다. Storybook 화면에서 눈으로 잰 값이나 과거 예제의 272px·18px·56px를 새로 정하지 않고, `--hm-lnb-width` 등을 소비 CSS에서 다시 정의하지 않습니다. 레이아웃 열은 `var(--hm-lnb-width)`로 읽습니다.
```tsx
// LNB ONLY 골격
+1
View File
@@ -68,6 +68,7 @@ Brown·Orange 계열 팔레트(`--hm-sem-palette-brown-*`, `--hm-sem-palette-ora
| Select Trigger 높이 | medium 34 · large 44(기본) | — |
| Control radius | 4px | `--hm-radius-control-md` → `--hm-radius-button`, `--hm-radius-input`, `--hm-radius-select`, `--hm-radius-container` |
| Card | border 1px, padding 24px, radius 4px, 그림자 없음 | `--hm-card-*` |
| LNB(Desktop) | 열 240px, 메뉴 14/28/700, 1뎁스 행 48 · 2·3뎁스 행 42, Profile 48, 콘텐츠 접점 18. 모바일 Header 56 · 링크 44 | `--hm-lnb-width`, `--hm-lnb-item-*`, `--hm-lnb-subitem-*`, `--hm-lnb-third-*`, `--hm-lnb-profile-min-height`, `--hm-lnb-join` |
| Dialog | radius 8px, padding 24px, Header 아래 16px, Footer 위 16px, 버튼 간격 8px, 그림자 `0 0 12px` 검정 20% | `--hm-dialog-*` |
## 5. 상태
+53 -13
View File
@@ -4,7 +4,7 @@
Black 10% to the same edge; an open group is a Black 8% face with a 1px green line. Spacing values are pattern-local. */
:root, [data-hm-theme] {
/* Exposed for the layout: grid column width and the surface that continues behind the content's rounded corners. */
--hm-lnb-width: 272px;
--hm-lnb-width: 240px;
--hm-lnb-join: 18px;
--hm-lnb-background: linear-gradient(90deg, var(--hm-sem-action-primary) 0%, var(--hm-sem-palette-green-light-1) 30%, var(--hm-sem-palette-green-light-2) 50%, var(--hm-sem-palette-green-light-3) 90%, var(--hm-sem-palette-green-light-2) 100%);
--hm-lnb-background-end: var(--hm-sem-palette-green-light-2);
@@ -29,10 +29,12 @@
--hm-lnb-brand-name-size: 17px;
--hm-lnb-brand-text-gap: 5px;
--hm-lnb-item-min-height: 56px;
--hm-lnb-item-min-height: 48px;
/* 1-depth row: 28px line + 2 x 10px = 48px. */
--hm-lnb-item-padding-block: 10px;
--hm-lnb-item-padding-start: 18px;
--hm-lnb-item-gap: 12px;
--hm-lnb-item-font-size: 18px;
--hm-lnb-item-font-size: 14px;
--hm-lnb-item-line-height: 28px;
--hm-lnb-item-font-weight: 700;
--hm-lnb-item-radius: 4px 0 0 4px;
@@ -46,11 +48,38 @@
--hm-lnb-current-background: var(--hm-sem-bg-content);
--hm-lnb-current-text: var(--hm-sem-action-primary);
--hm-lnb-current-radius: 8px 0 0 8px;
/* Inset depth of the current face: left edge, top, bottom; the last quarter fades so the content side stays open. */
/* Inset depth of the current face (left, top, bottom), matched to the Storybook Manager's selected item: inset box-shadows
6px 0 8px -5px Black 30%, 0 3px 5px -3px Black 20% and 0 -2px 4px -3px Black 20%, faded out over the last quarter. A background
cannot hold a box-shadow and ::before / ::after already draw the concave corners, so the blurred falloff is sampled as gradient
stops (left 10px, top 5px, bottom 4px), and the first layer repaints the face color from 75% to 100% so the depth fades toward
the content side. */
--hm-lnb-current-depth:
linear-gradient(to right, color-mix(in srgb, var(--hm-sem-palette-black) 30%, transparent), transparent 6px) 0 0 / 75% 100% no-repeat,
linear-gradient(to bottom, color-mix(in srgb, var(--hm-sem-palette-black) 20%, transparent), transparent 3px) 0 0 / 75% 100% no-repeat,
linear-gradient(to top, color-mix(in srgb, var(--hm-sem-palette-black) 20%, transparent), transparent 3px) 0 0 / 75% 100% no-repeat;
linear-gradient(to right, transparent, var(--hm-lnb-current-background)) 100% 0 / 25% 100% no-repeat,
linear-gradient(to right,
color-mix(in srgb, var(--hm-sem-palette-black) 20%, transparent) 0,
color-mix(in srgb, var(--hm-sem-palette-black) 15.7%, transparent) 1px,
color-mix(in srgb, var(--hm-sem-palette-black) 12.2%, transparent) 2px,
color-mix(in srgb, var(--hm-sem-palette-black) 9.5%, transparent) 3px,
color-mix(in srgb, var(--hm-sem-palette-black) 7.1%, transparent) 4px,
color-mix(in srgb, var(--hm-sem-palette-black) 5%, transparent) 5px,
color-mix(in srgb, var(--hm-sem-palette-black) 3.3%, transparent) 6px,
color-mix(in srgb, var(--hm-sem-palette-black) 2.2%, transparent) 7px,
color-mix(in srgb, var(--hm-sem-palette-black) 1.4%, transparent) 8px,
color-mix(in srgb, var(--hm-sem-palette-black) 0.8%, transparent) 9px,
transparent 10px),
linear-gradient(to bottom,
color-mix(in srgb, var(--hm-sem-palette-black) 12%, transparent) 0,
color-mix(in srgb, var(--hm-sem-palette-black) 8.5%, transparent) 1px,
color-mix(in srgb, var(--hm-sem-palette-black) 5%, transparent) 2px,
color-mix(in srgb, var(--hm-sem-palette-black) 2.3%, transparent) 3px,
color-mix(in srgb, var(--hm-sem-palette-black) 0.8%, transparent) 4px,
transparent 5px),
linear-gradient(to top,
color-mix(in srgb, var(--hm-sem-palette-black) 9%, transparent) 0,
color-mix(in srgb, var(--hm-sem-palette-black) 5.1%, transparent) 1px,
color-mix(in srgb, var(--hm-sem-palette-black) 2.4%, transparent) 2px,
color-mix(in srgb, var(--hm-sem-palette-black) 0.7%, transparent) 3px,
transparent 4px);
--hm-lnb-group-open-background: color-mix(in srgb, var(--hm-sem-palette-black) 8%, transparent);
--hm-lnb-group-open-line: 1px solid var(--hm-sem-palette-green-light-2);
@@ -58,14 +87,17 @@
--hm-lnb-group-current-text: var(--hm-sem-palette-yellow-accent);
--hm-lnb-group-arrow-size: 18px;
--hm-lnb-subitem-padding-start: 68px;
/* 2-depth row (links directly in a group, nested group triggers): 28px line + 2 x 7px = 42px. */
--hm-lnb-subitem-min-height: 42px;
--hm-lnb-subitem-padding-block: 7px;
/* Align the 2-depth link surface with the 1-depth group text; retain its existing text inset. */
--hm-lnb-subitem-surface-inset: calc(var(--hm-lnb-item-padding-start) + var(--hm-lnb-group-arrow-size) + var(--hm-lnb-item-gap));
--hm-lnb-group-padding-bottom: 8px;
/* 3-depth: the items of an `LNBGroup` nested in a group. Same 18px; the hierarchy is the extra 20px indent and the connector
(a vertical line at the 2-depth text start, a 12px branch to each row's middle, 8px to the text; it ends at the last row). */
--hm-lnb-third-min-height: 48px;
--hm-lnb-third-padding-block: 12px;
/* 3-depth: the items of an `LNBGroup` nested in a group. Same font size as the other depths; the hierarchy is the extra 20px indent and the connector
(a vertical line at the 2-depth text start, a 12px branch to each row's middle, 8px to the text; it ends at the last row). 42px = 24px line + 9px padding x2. */
--hm-lnb-third-min-height: 42px;
--hm-lnb-third-padding-block: 9px;
--hm-lnb-third-padding-start: 88px;
--hm-lnb-third-line-height: 24px;
--hm-lnb-third-font-weight: 500;
@@ -79,6 +111,7 @@
--hm-lnb-profile-padding-x: 30px;
--hm-lnb-profile-padding-top: 22px;
--hm-lnb-profile-gap: 12px;
--hm-lnb-profile-min-height: 48px;
--hm-lnb-profile-name-size: 16px;
--hm-lnb-profile-description-size: 12px;
}
@@ -150,7 +183,7 @@
max-width: calc(100% - 2 * (var(--hm-lnb-profile-padding-x) - 8px));
margin-top: auto;
margin-inline: calc(var(--hm-lnb-profile-padding-x) - 8px);
min-height: var(--hm-lnb-third-min-height);
min-height: var(--hm-lnb-profile-min-height);
padding: 0 8px;
border: 0;
background: transparent;
@@ -211,7 +244,7 @@
gap: var(--hm-lnb-item-gap);
width: calc(100% - 1px);
min-height: var(--hm-lnb-item-min-height);
padding: 14px calc(var(--hm-lnb-inset-end) + 12px) 14px var(--hm-lnb-item-padding-start);
padding: var(--hm-lnb-item-padding-block) calc(var(--hm-lnb-inset-end) + 12px) var(--hm-lnb-item-padding-block) var(--hm-lnb-item-padding-start);
border: 0;
border-radius: var(--hm-lnb-item-radius);
background: transparent;
@@ -329,6 +362,13 @@
[data-slot="lnb-group-content"] [data-slot="lnb-item"]:not([aria-current="page"]):hover {
border-radius: var(--hm-lnb-item-radius);
}
/* 2-depth rows (links directly in a group, nested group triggers): 42px = 28px line + 2 x 7px. */
[data-slot="lnb-group-content"] > [data-slot="lnb-item"],
[data-slot="lnb-group-content"] [data-slot="lnb-group-trigger"] {
min-height: var(--hm-lnb-subitem-min-height);
padding-top: var(--hm-lnb-subitem-padding-block);
padding-bottom: var(--hm-lnb-subitem-padding-block);
}
[data-slot="lnb-group-content"] [data-slot="lnb-item"][aria-current="page"] {
width: calc(100% + 1px);
margin-right: -1px;