Initial commit: HMDesignSystem baseline
This commit is contained in:
commit
b6a0a61103
486 files changed
+68432
No files matched your search
@@ -0,0 +1,573 @@
|
||||
/* GNB pattern (layout visual reference: D:\컴포넌트\ui-viz Patterns/GNB, implementation: current @hm-design/ui primitives).
|
||||
The bar is the ui-viz green top header: 70px, vertical brand gradient, brand left, menu centered on the whole bar, text-only profile
|
||||
right, Beige "current" item joined to the content by two concave corners, White 2-depth panel. The Navigation Menu, Dropdown Menu,
|
||||
Sheet, Button and Avatar keep their own markup, Radix behavior and tokens; here they are only re-colored INSIDE the GNB scope
|
||||
(`[data-slot="gnb"] …`), so their own Stories do not change. Spacing values are pattern-local (no global spacing scale exists).
|
||||
Navigation must use `<NavigationMenu viewport={false}>` so each panel opens under its own trigger at the trigger's width. */
|
||||
:root, [data-hm-theme] {
|
||||
/* Exposed for GNB Mode content layouts: the bar height and the content join below it. Mobile uses a shorter bar. */
|
||||
--hm-gnb-height: 70px;
|
||||
--hm-gnb-join: 12px;
|
||||
/* Same stops as the shared Semantic action surface gradient family (tone 1-4); painted over bar + join as one gradient. */
|
||||
--hm-gnb-background: linear-gradient(180deg, var(--hm-sem-action-surface-stop-0) 0%, var(--hm-sem-action-surface-stop-30) 30%, var(--hm-sem-action-surface-stop-65) 65%, var(--hm-sem-action-surface-stop-100) 100%);
|
||||
--hm-gnb-padding-x: 28px;
|
||||
--hm-gnb-column-gap: 24px;
|
||||
/* Below the z-50 of Popover / Dropdown / Sheet / Dialog (portaled). Applies when `sticky`. */
|
||||
--hm-gnb-z-index: 40;
|
||||
|
||||
--hm-gnb-text: var(--hm-sem-on-action-primary);
|
||||
--hm-gnb-text-secondary: var(--hm-sem-palette-green-tint);
|
||||
--hm-gnb-text-stroke-color: color-mix(in srgb, var(--hm-sem-palette-black) 30%, transparent);
|
||||
--hm-gnb-text-stroke-width: 1px;
|
||||
--hm-gnb-hover-background: color-mix(in srgb, var(--hm-sem-palette-black) 10%, transparent);
|
||||
--hm-gnb-focus-outline: 2px solid var(--hm-sem-on-action-primary);
|
||||
|
||||
--hm-gnb-brand-gap: 12px;
|
||||
--hm-gnb-brand-padding-end: 28px;
|
||||
--hm-gnb-brand-eyebrow-size: 11px;
|
||||
--hm-gnb-brand-eyebrow-spacing: 0.12em;
|
||||
--hm-gnb-brand-name-size: 16px;
|
||||
--hm-gnb-brand-text-gap: 5px;
|
||||
--hm-gnb-logo-max-height: 100%;
|
||||
|
||||
/* Primary menu: 4px above the item, item face 66px = bar 70; first/last item keeps room for the current join curves. */
|
||||
--hm-gnb-menu-inset-top: 4px;
|
||||
--hm-gnb-menu-join: 12px;
|
||||
--hm-gnb-menu-min-width: 112px;
|
||||
--hm-gnb-menu-padding-x: 16px;
|
||||
--hm-gnb-menu-gap: 12px;
|
||||
--hm-gnb-menu-radius: 4px 4px 0 0;
|
||||
--hm-gnb-menu-font-size: 16px;
|
||||
--hm-gnb-menu-font-weight: 700;
|
||||
--hm-gnb-current-background: var(--hm-sem-bg-content);
|
||||
--hm-gnb-current-text: var(--hm-sem-action-primary);
|
||||
--hm-gnb-open-background: var(--hm-sem-bg-surface);
|
||||
--hm-gnb-open-text: var(--hm-sem-action-primary);
|
||||
|
||||
/* 2-depth panel: parent width, White, items centered. Radius and shadow are review values in ui-viz. */
|
||||
--hm-gnb-panel-background: var(--hm-sem-bg-surface);
|
||||
--hm-gnb-panel-radius: 0 0 8px 8px;
|
||||
--hm-gnb-panel-shadow: 0 6px 16px color-mix(in srgb, var(--hm-sem-palette-black) 10%, transparent);
|
||||
--hm-gnb-panel-item-min-height: 56px;
|
||||
--hm-gnb-panel-item-padding: 16px;
|
||||
--hm-gnb-panel-item-font-size: 16px;
|
||||
--hm-gnb-panel-item-line-height: 24px;
|
||||
--hm-gnb-panel-item-text: var(--hm-sem-fg-primary);
|
||||
--hm-gnb-panel-item-hover-background: var(--hm-sem-bg-content);
|
||||
--hm-gnb-panel-item-hover-text: var(--hm-sem-action-primary);
|
||||
|
||||
/* Profile (Avatar default size + name and role; the text is hidden on the mobile bar, the Avatar stays). */
|
||||
--hm-gnb-user-gap: 3px;
|
||||
--hm-gnb-user-radius: var(--hm-radius-control-md);
|
||||
--hm-gnb-user-name-size: 16px;
|
||||
--hm-gnb-user-description-size: 12px;
|
||||
--hm-gnb-user-text-max-width: 220px;
|
||||
|
||||
/* Mobile menu content (inside the HM Sheet, white face). */
|
||||
--hm-gnb-mobile-link-height: 44px;
|
||||
--hm-gnb-mobile-link-padding-x: 12px;
|
||||
--hm-gnb-mobile-link-radius: var(--hm-radius-control-md);
|
||||
--hm-gnb-mobile-link-font-size: 14px;
|
||||
--hm-gnb-mobile-link-line-height: 20px;
|
||||
--hm-gnb-mobile-link-font-weight: 500;
|
||||
--hm-gnb-mobile-link-text: var(--hm-sem-fg-primary);
|
||||
--hm-gnb-mobile-link-hover-background: var(--accent);
|
||||
--hm-gnb-mobile-link-hover-text: var(--accent-foreground);
|
||||
--hm-gnb-mobile-link-current-background: var(--hm-sem-bg-content);
|
||||
--hm-gnb-mobile-link-current-text: var(--hm-sem-action-primary);
|
||||
--hm-gnb-mobile-link-current-font-weight: 700;
|
||||
--hm-gnb-mobile-group-label-color: var(--hm-sem-fg-secondary);
|
||||
--hm-gnb-mobile-group-gap: 16px;
|
||||
--hm-gnb-mobile-nested-gap: 8px;
|
||||
--hm-gnb-mobile-nested-indent: var(--hm-gnb-mobile-link-padding-x);
|
||||
--hm-gnb-mobile-focus-ring: 0 0 0 3px color-mix(in srgb, var(--ring) 50%, transparent);
|
||||
}
|
||||
|
||||
/* ── Bar ─────────────────────────────────────────────────────────────────────────────────────── */
|
||||
[data-slot="gnb"] {
|
||||
position: relative;
|
||||
box-sizing: border-box;
|
||||
display: grid;
|
||||
grid-template-columns: minmax(0, 1fr) minmax(0, auto) minmax(0, 1fr);
|
||||
column-gap: var(--hm-gnb-column-gap);
|
||||
align-items: start;
|
||||
width: 100%;
|
||||
height: var(--hm-gnb-height);
|
||||
padding: 0 var(--hm-gnb-padding-x);
|
||||
background: var(--hm-gnb-background) left top / 100% calc(var(--hm-gnb-height) + var(--hm-gnb-join)) no-repeat;
|
||||
color: var(--hm-gnb-text);
|
||||
font-size: 16px;
|
||||
}
|
||||
/* Continue the gradient only outside the content's rounded top corners. A full strip would cover the content when the sticky
|
||||
header creates a higher stacking context. Static and sticky share this geometry (Dashboard Layout contract). */
|
||||
[data-slot="gnb"]::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 100%;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: var(--hm-gnb-join);
|
||||
background: var(--hm-gnb-background) 0 calc(-1 * var(--hm-gnb-height)) / 100% calc(var(--hm-gnb-height) + var(--hm-gnb-join)) no-repeat;
|
||||
mask:
|
||||
radial-gradient(circle at bottom right, transparent var(--hm-gnb-join), #000 var(--hm-gnb-join)) left top / var(--hm-gnb-join) 100% no-repeat,
|
||||
radial-gradient(circle at bottom left, transparent var(--hm-gnb-join), #000 var(--hm-gnb-join)) right top / var(--hm-gnb-join) 100% no-repeat;
|
||||
pointer-events: none;
|
||||
}
|
||||
[data-slot="gnb"][data-sticky] {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: var(--hm-gnb-z-index);
|
||||
}
|
||||
|
||||
/* ── Brand: horizontal; logo (img / svg) only when supplied, then the name. Eyebrow + name are optional. ───────── */
|
||||
[data-slot="gnb-brand"] {
|
||||
grid-column: 1;
|
||||
justify-self: start;
|
||||
box-sizing: border-box;
|
||||
min-width: 0;
|
||||
max-width: 100%;
|
||||
height: calc(var(--hm-gnb-height) - 2px);
|
||||
padding-right: var(--hm-gnb-brand-padding-end);
|
||||
gap: var(--hm-gnb-brand-gap);
|
||||
color: var(--hm-gnb-text);
|
||||
text-decoration: none;
|
||||
outline: none;
|
||||
}
|
||||
[data-slot="gnb-brand"]:focus-visible {
|
||||
outline: var(--hm-gnb-focus-outline);
|
||||
outline-offset: -2px;
|
||||
}
|
||||
[data-slot="gnb-brand"] > :is(img, svg) {
|
||||
flex: 0 1 auto;
|
||||
min-width: 0;
|
||||
width: auto;
|
||||
height: auto;
|
||||
max-width: 100%;
|
||||
max-height: var(--hm-gnb-logo-max-height);
|
||||
}
|
||||
[data-slot="gnb-brand"] > span {
|
||||
display: grid;
|
||||
gap: var(--hm-gnb-brand-text-gap);
|
||||
flex: 0 1 auto;
|
||||
min-width: 0;
|
||||
-webkit-text-stroke: var(--hm-gnb-text-stroke-width) var(--hm-gnb-text-stroke-color);
|
||||
paint-order: stroke fill;
|
||||
}
|
||||
[data-slot="gnb-brand"] :is(small, strong) {
|
||||
min-width: 0;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
[data-slot="gnb-brand"] small {
|
||||
color: var(--hm-gnb-text-secondary);
|
||||
font-size: var(--hm-gnb-brand-eyebrow-size);
|
||||
font-weight: 700;
|
||||
letter-spacing: var(--hm-gnb-brand-eyebrow-spacing);
|
||||
line-height: 1.2;
|
||||
}
|
||||
[data-slot="gnb-brand"] strong {
|
||||
font-size: var(--hm-gnb-brand-name-size);
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
/* ── Primary navigation: centered on the whole bar by the equal side columns ────────────────────────────────── */
|
||||
[data-slot="gnb"] [data-slot="gnb-nav"] {
|
||||
grid-column: 2;
|
||||
align-items: flex-start;
|
||||
min-width: 0;
|
||||
height: var(--hm-gnb-height);
|
||||
/* `clip` (unlike `hidden`) leaves the vertical axis visible so the open panel below the bar is not cut; too-long labels are cut here. */
|
||||
overflow-x: clip;
|
||||
}
|
||||
[data-slot="gnb"] [data-slot="gnb-nav"] [data-slot="navigation-menu"] {
|
||||
flex: 0 1 auto;
|
||||
align-items: flex-start;
|
||||
height: 100%;
|
||||
justify-content: center;
|
||||
}
|
||||
[data-slot="gnb"] [data-slot="gnb-nav"] [data-slot="navigation-menu-list"] {
|
||||
align-items: flex-start;
|
||||
justify-content: center;
|
||||
gap: 0;
|
||||
height: 100%;
|
||||
padding-inline: var(--hm-gnb-menu-join);
|
||||
}
|
||||
[data-slot="gnb"] [data-slot="gnb-nav"] [data-slot="navigation-menu-item"] {
|
||||
height: 100%;
|
||||
}
|
||||
[data-slot="gnb"] [data-slot="gnb-nav"] :is([data-slot="navigation-menu-trigger"], [data-slot="navigation-menu-link"]) {
|
||||
position: relative;
|
||||
justify-content: center;
|
||||
gap: var(--hm-gnb-menu-gap);
|
||||
min-width: var(--hm-gnb-menu-min-width);
|
||||
height: calc(var(--hm-gnb-height) - var(--hm-gnb-menu-inset-top));
|
||||
margin-top: var(--hm-gnb-menu-inset-top);
|
||||
padding: 0 var(--hm-gnb-menu-padding-x);
|
||||
border-radius: var(--hm-gnb-menu-radius);
|
||||
background: transparent;
|
||||
color: var(--hm-gnb-text);
|
||||
font-size: var(--hm-gnb-menu-font-size);
|
||||
font-weight: var(--hm-gnb-menu-font-weight);
|
||||
white-space: nowrap;
|
||||
box-shadow: none;
|
||||
}
|
||||
/* Arrow optical correction: (12px SVG box - 7px painted width) / 4 = 1.25px.
|
||||
Keep the total padding, intrinsic trigger width, gap and icon margin unchanged. */
|
||||
[data-slot="gnb"] [data-slot="gnb-nav"] [data-slot="navigation-menu-trigger"]:has(> [data-slot="navigation-menu-trigger-icon"]) {
|
||||
padding-left: calc(var(--hm-gnb-menu-padding-x) + 1.25px);
|
||||
padding-right: calc(var(--hm-gnb-menu-padding-x) - 1.25px);
|
||||
}
|
||||
/* Hover / focus (not the current item, not an open parent): Black 10% over the green. */
|
||||
[data-slot="gnb"] [data-slot="gnb-nav"] :is([data-slot="navigation-menu-trigger"], [data-slot="navigation-menu-link"]):is(:hover, :focus-visible):not([data-active], [aria-current="page"], [data-state="open"]) {
|
||||
background: var(--hm-gnb-hover-background);
|
||||
color: var(--hm-gnb-text);
|
||||
}
|
||||
[data-slot="gnb"] [data-slot="gnb-nav"] :is([data-slot="navigation-menu-trigger"], [data-slot="navigation-menu-link"]):focus-visible {
|
||||
outline: var(--hm-gnb-focus-outline);
|
||||
outline-offset: -2px;
|
||||
}
|
||||
/* Current location: Beige face joined to the content below by two concave corners. Hover does not repaint it. Radix `active` on a
|
||||
Link (`data-active`, `aria-current="page"`); a Trigger carries `aria-current="page"` from the consumer. */
|
||||
[data-slot="gnb"] [data-slot="gnb-nav"] :is([data-slot="navigation-menu-trigger"], [data-slot="navigation-menu-link"]):is([data-active], [aria-current="page"]) {
|
||||
z-index: 1;
|
||||
background: var(--hm-gnb-current-background);
|
||||
color: var(--hm-gnb-current-text);
|
||||
}
|
||||
[data-slot="gnb"] [data-slot="gnb-nav"] :is([data-slot="navigation-menu-trigger"], [data-slot="navigation-menu-link"]):is([data-active], [aria-current="page"]):focus-visible {
|
||||
outline-color: var(--hm-gnb-current-text);
|
||||
}
|
||||
[data-slot="gnb"] [data-slot="gnb-nav"] :is([data-slot="navigation-menu-trigger"], [data-slot="navigation-menu-link"]):is([data-active], [aria-current="page"])::before,
|
||||
[data-slot="gnb"] [data-slot="gnb-nav"] :is([data-slot="navigation-menu-trigger"], [data-slot="navigation-menu-link"]):is([data-active], [aria-current="page"])::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
width: var(--hm-gnb-menu-join);
|
||||
height: var(--hm-gnb-menu-join);
|
||||
pointer-events: none;
|
||||
}
|
||||
[data-slot="gnb"] [data-slot="gnb-nav"] :is([data-slot="navigation-menu-trigger"], [data-slot="navigation-menu-link"]):is([data-active], [aria-current="page"])::before {
|
||||
right: 100%;
|
||||
background: radial-gradient(circle at top left, transparent calc(var(--hm-gnb-menu-join) - 0.5px), var(--hm-gnb-current-background) var(--hm-gnb-menu-join));
|
||||
}
|
||||
[data-slot="gnb"] [data-slot="gnb-nav"] :is([data-slot="navigation-menu-trigger"], [data-slot="navigation-menu-link"]):is([data-active], [aria-current="page"])::after {
|
||||
left: 100%;
|
||||
background: radial-gradient(circle at top right, transparent calc(var(--hm-gnb-menu-join) - 0.5px), var(--hm-gnb-current-background) var(--hm-gnb-menu-join));
|
||||
}
|
||||
/* Open parent: reuse the current concave joins with the panel's surface.
|
||||
alignPanels supplies each side independently after viewport clamping. */
|
||||
[data-slot="gnb"] [data-slot="gnb-nav"] [data-slot="navigation-menu-trigger"][data-state="open"] {
|
||||
z-index: 3;
|
||||
background: var(--hm-gnb-open-background);
|
||||
color: var(--hm-gnb-open-text);
|
||||
}
|
||||
[data-slot="gnb"] [data-slot="gnb-nav"] [data-slot="navigation-menu-trigger"][data-state="open"]::before,
|
||||
[data-slot="gnb"] [data-slot="gnb-nav"] [data-slot="navigation-menu-trigger"][data-state="open"]::after {
|
||||
content: "";
|
||||
display: block;
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
height: var(--hm-gnb-menu-join);
|
||||
pointer-events: none;
|
||||
}
|
||||
[data-slot="gnb"] [data-slot="gnb-nav"] [data-slot="navigation-menu-trigger"][data-state="open"]::before {
|
||||
right: 100%;
|
||||
width: min(var(--hm-gnb-panel-left-extension, 0px), var(--hm-gnb-menu-join));
|
||||
background: radial-gradient(circle at top left, transparent calc(var(--hm-gnb-menu-join) - 0.5px), var(--hm-gnb-panel-background) var(--hm-gnb-menu-join)) right bottom / var(--hm-gnb-menu-join) var(--hm-gnb-menu-join) no-repeat;
|
||||
}
|
||||
[data-slot="gnb"] [data-slot="gnb-nav"] [data-slot="navigation-menu-trigger"][data-state="open"]::after {
|
||||
left: 100%;
|
||||
width: min(var(--hm-gnb-panel-right-extension, 0px), var(--hm-gnb-menu-join));
|
||||
background: radial-gradient(circle at top right, transparent calc(var(--hm-gnb-menu-join) - 0.5px), var(--hm-gnb-panel-background) var(--hm-gnb-menu-join)) left bottom / var(--hm-gnb-menu-join) var(--hm-gnb-menu-join) no-repeat;
|
||||
}
|
||||
[data-slot="gnb"] [data-slot="gnb-nav"] [data-slot="navigation-menu-trigger"][data-state="open"]:focus-visible {
|
||||
outline-color: var(--hm-gnb-open-text);
|
||||
}
|
||||
|
||||
/* ── 2-depth panel (viewport={false}): under its own trigger, same width, White, centered items ─────────────── */
|
||||
[data-slot="gnb"] [data-slot="gnb-nav"] [data-slot="navigation-menu-content"] {
|
||||
position: absolute;
|
||||
z-index: 2;
|
||||
top: 100%;
|
||||
left: 0;
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
min-width: 0;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
border-radius: var(--hm-gnb-panel-radius);
|
||||
background: var(--hm-gnb-panel-background);
|
||||
color: var(--hm-gnb-panel-item-text);
|
||||
box-shadow: var(--hm-gnb-panel-shadow);
|
||||
}
|
||||
[data-slot="gnb"] [data-slot="gnb-nav"] [data-slot="navigation-menu-content"] > ul {
|
||||
display: grid;
|
||||
width: auto;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
gap: 0;
|
||||
list-style: none;
|
||||
}
|
||||
[data-slot="gnb"] [data-slot="gnb-nav"] [data-slot="navigation-menu-content"] [data-slot="navigation-menu-link"] {
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
height: auto;
|
||||
min-height: var(--hm-gnb-panel-item-min-height);
|
||||
margin: 0;
|
||||
padding: var(--hm-gnb-panel-item-padding);
|
||||
border-radius: 0;
|
||||
background: transparent;
|
||||
color: var(--hm-gnb-panel-item-text);
|
||||
font-size: var(--hm-gnb-panel-item-font-size);
|
||||
line-height: var(--hm-gnb-panel-item-line-height);
|
||||
font-weight: 700;
|
||||
text-align: center;
|
||||
white-space: normal;
|
||||
word-break: keep-all;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
[data-slot="gnb"] [data-slot="gnb-nav"] [data-slot="navigation-menu-content"] [data-slot="navigation-menu-link"]:is(:hover, :focus-visible, [data-active]) {
|
||||
background: var(--hm-gnb-panel-item-hover-background);
|
||||
color: var(--hm-gnb-panel-item-hover-text);
|
||||
outline: none;
|
||||
}
|
||||
[data-slot="gnb"] [data-slot="gnb-nav"] [data-slot="navigation-menu-content"] [data-slot="navigation-menu-link"]:focus-visible {
|
||||
outline: 2px solid var(--hm-gnb-panel-item-hover-text);
|
||||
outline-offset: -2px;
|
||||
}
|
||||
|
||||
/* ── Utilities and profile ──────────────────────────────────────────────────────────────────────────────── */
|
||||
[data-slot="gnb-utilities"] {
|
||||
grid-column: 3;
|
||||
justify-self: end;
|
||||
min-width: 0;
|
||||
height: calc(var(--hm-gnb-height) - 2px);
|
||||
gap: 4px;
|
||||
}
|
||||
/* Optional icon actions (search, notification...) are HM ghost Buttons; on the green bar they are white with the Black 10% hover. */
|
||||
[data-slot="gnb-utilities"] [data-slot="button"][data-variant="ghost"] {
|
||||
color: var(--hm-gnb-text);
|
||||
}
|
||||
[data-slot="gnb-utilities"] [data-slot="button"][data-variant="ghost"]:is(:hover, [aria-expanded="true"]) {
|
||||
background: var(--hm-gnb-hover-background);
|
||||
color: var(--hm-gnb-text);
|
||||
}
|
||||
[data-slot="gnb-utilities"] [data-slot="button"][data-variant="ghost"]:focus-visible {
|
||||
border-color: transparent;
|
||||
outline: var(--hm-gnb-focus-outline);
|
||||
outline-offset: -2px;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
[data-slot="gnb-user"] {
|
||||
box-sizing: border-box;
|
||||
min-width: 0;
|
||||
max-width: 100%;
|
||||
padding: 0 8px;
|
||||
gap: 10px;
|
||||
border: 0;
|
||||
border-radius: var(--hm-gnb-user-radius);
|
||||
background: transparent;
|
||||
color: var(--hm-gnb-text);
|
||||
text-align: left;
|
||||
cursor: pointer;
|
||||
outline: none;
|
||||
}
|
||||
[data-slot="gnb-user"]:is(:hover, [data-state="open"]) {
|
||||
background: var(--hm-gnb-hover-background);
|
||||
}
|
||||
[data-slot="gnb-user"]:focus-visible {
|
||||
outline: var(--hm-gnb-focus-outline);
|
||||
outline-offset: -2px;
|
||||
}
|
||||
[data-slot="gnb-user-text"] {
|
||||
display: grid;
|
||||
gap: var(--hm-gnb-user-gap);
|
||||
min-width: 0;
|
||||
max-width: var(--hm-gnb-user-text-max-width);
|
||||
padding-block: 4px;
|
||||
}
|
||||
[data-slot="gnb-user-name"],
|
||||
[data-slot="gnb-user-description"] {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
-webkit-text-stroke: var(--hm-gnb-text-stroke-width) var(--hm-gnb-text-stroke-color);
|
||||
paint-order: stroke fill;
|
||||
}
|
||||
[data-slot="gnb-user-name"] {
|
||||
font-size: var(--hm-gnb-user-name-size);
|
||||
font-weight: 700;
|
||||
}
|
||||
[data-slot="gnb-user-description"] {
|
||||
color: var(--hm-gnb-text-secondary);
|
||||
font-size: var(--hm-gnb-user-description-size);
|
||||
}
|
||||
|
||||
/* ── Mobile menu content (inside the HM Sheet): destinations as a plain link list ─────────────────────────── */
|
||||
[data-slot="gnb-mobile-nav"] {
|
||||
display: grid;
|
||||
gap: var(--hm-gnb-mobile-group-gap);
|
||||
padding-bottom: 16px;
|
||||
}
|
||||
[data-slot="gnb-mobile-group-label"] {
|
||||
margin: 0;
|
||||
padding: 0 var(--hm-gnb-mobile-link-padding-x) 4px;
|
||||
color: var(--hm-gnb-mobile-group-label-color);
|
||||
font-size: 12px;
|
||||
line-height: 18px;
|
||||
font-weight: 500;
|
||||
}
|
||||
/* A group inside a group (a deeper local level, e.g. the LNB 3-depth): one link padding further in, with room above its title. */
|
||||
[data-slot="gnb-mobile-group"] [data-slot="gnb-mobile-group"] {
|
||||
margin-top: var(--hm-gnb-mobile-nested-gap);
|
||||
padding-left: var(--hm-gnb-mobile-nested-indent);
|
||||
}
|
||||
[data-slot="gnb-mobile-link"] {
|
||||
box-sizing: border-box;
|
||||
min-height: var(--hm-gnb-mobile-link-height);
|
||||
padding: 0 var(--hm-gnb-mobile-link-padding-x);
|
||||
border-radius: var(--hm-gnb-mobile-link-radius);
|
||||
color: var(--hm-gnb-mobile-link-text);
|
||||
font-size: var(--hm-gnb-mobile-link-font-size);
|
||||
line-height: var(--hm-gnb-mobile-link-line-height);
|
||||
font-weight: var(--hm-gnb-mobile-link-font-weight);
|
||||
text-decoration: none;
|
||||
overflow-wrap: anywhere;
|
||||
outline: none;
|
||||
}
|
||||
[data-slot="gnb-mobile-link"]:is(:hover, :focus-visible) {
|
||||
background: var(--hm-gnb-mobile-link-hover-background);
|
||||
color: var(--hm-gnb-mobile-link-hover-text);
|
||||
}
|
||||
[data-slot="gnb-mobile-link"]:focus-visible {
|
||||
box-shadow: var(--hm-gnb-mobile-focus-ring);
|
||||
}
|
||||
[data-slot="gnb-mobile-link"][aria-current="page"] {
|
||||
background: var(--hm-gnb-mobile-link-current-background);
|
||||
color: var(--hm-gnb-mobile-link-current-text);
|
||||
font-weight: var(--hm-gnb-mobile-link-current-font-weight);
|
||||
}
|
||||
|
||||
/* Desktop panels grow to their longest label. The GNB region measures only the
|
||||
viewport-edge correction; extreme labels scroll within the bounded panel. */
|
||||
@media (min-width: 1024px) {
|
||||
[data-slot="gnb"] [data-slot="gnb-nav"] {
|
||||
overflow-x: visible;
|
||||
}
|
||||
[data-slot="gnb"] [data-slot="gnb-nav"] [data-slot="navigation-menu-content"] {
|
||||
left: var(--hm-gnb-panel-offset-x, 0px);
|
||||
width: max-content;
|
||||
min-width: 100%;
|
||||
max-width: calc(100vw - 2 * var(--hm-gnb-padding-x));
|
||||
overflow-x: auto;
|
||||
}
|
||||
[data-slot="gnb"] [data-slot="gnb-nav"] [data-slot="navigation-menu-content"] > ul {
|
||||
min-width: max-content;
|
||||
}
|
||||
[data-slot="gnb"] [data-slot="gnb-nav"] [data-slot="navigation-menu-content"] [data-slot="navigation-menu-link"] {
|
||||
white-space: nowrap;
|
||||
overflow-wrap: normal;
|
||||
}
|
||||
/* The concave current-page joins belong to 1Depth only, not panel rows. */
|
||||
[data-slot="gnb"] [data-slot="gnb-nav"] [data-slot="navigation-menu-content"] [data-slot="navigation-menu-link"]::before,
|
||||
[data-slot="gnb"] [data-slot="gnb-nav"] [data-slot="navigation-menu-content"] [data-slot="navigation-menu-link"]::after {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
/* ── Mobile bar: below 1024px (Tailwind `lg`). Menu → hamburger + Sheet; profile → Avatar only. Keep this block last. ──────── */
|
||||
@media (max-width: 1023px) {
|
||||
:root, [data-hm-theme] {
|
||||
--hm-gnb-height: 56px;
|
||||
--hm-gnb-padding-x: 16px;
|
||||
}
|
||||
[data-slot="gnb"] {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
[data-slot="gnb"] [data-slot="gnb-nav"] {
|
||||
display: none;
|
||||
}
|
||||
[data-slot="gnb-brand"] {
|
||||
flex: 0 1 auto;
|
||||
height: auto;
|
||||
padding-right: 0;
|
||||
}
|
||||
[data-slot="gnb-brand"] small {
|
||||
display: none;
|
||||
}
|
||||
[data-slot="gnb-utilities"] {
|
||||
flex: none;
|
||||
height: auto;
|
||||
margin-left: auto;
|
||||
}
|
||||
[data-slot="gnb-user"] {
|
||||
padding: 0 4px;
|
||||
}
|
||||
[data-slot="gnb-user-text"] {
|
||||
display: none;
|
||||
}
|
||||
/* The hamburger is a ghost Button: white on the green bar. */
|
||||
[data-slot="gnb"] > [data-slot="button"][data-variant="ghost"] {
|
||||
color: var(--hm-gnb-text);
|
||||
}
|
||||
[data-slot="gnb"] > [data-slot="button"][data-variant="ghost"]:is(:hover, [aria-expanded="true"]) {
|
||||
background: var(--hm-gnb-hover-background);
|
||||
color: var(--hm-gnb-text);
|
||||
}
|
||||
[data-slot="gnb"] > [data-slot="button"][data-variant="ghost"]:focus-visible {
|
||||
border-color: transparent;
|
||||
outline: var(--hm-gnb-focus-outline);
|
||||
outline-offset: -2px;
|
||||
box-shadow: none;
|
||||
}
|
||||
}
|
||||
|
||||
/* Opt-in GNB ONLY composition. Reuse LNB's DOM, tokens and responsive menu unchanged.
|
||||
These layout hooks ship with @hm-design/ui/theme.css; no Story-only stylesheet is required.
|
||||
The consumer provides the frame height and content padding. */
|
||||
[data-hm-gnb-layout="sidebar"] {
|
||||
display: grid;
|
||||
grid-template-rows: auto minmax(0, 1fr);
|
||||
min-width: 0;
|
||||
min-height: 0;
|
||||
}
|
||||
[data-hm-gnb-layout="sidebar"] > [data-slot="gnb"] {
|
||||
z-index: var(--hm-gnb-z-index);
|
||||
}
|
||||
[data-hm-gnb-layout="sidebar"] > [data-hm-gnb-body] {
|
||||
position: relative;
|
||||
display: grid;
|
||||
grid-template-columns: var(--hm-lnb-width) minmax(0, 1fr);
|
||||
min-width: 0;
|
||||
min-height: 0;
|
||||
background: var(--hm-sem-palette-green-light-2);
|
||||
border-radius: var(--hm-gnb-join) var(--hm-gnb-join) 0 0;
|
||||
}
|
||||
[data-hm-gnb-layout="sidebar"] > [data-hm-gnb-body] > [data-slot="lnb"][data-hm-gnb-sidebar] {
|
||||
--hm-lnb-background: var(--hm-sem-palette-green-light-2);
|
||||
}
|
||||
[data-hm-gnb-layout="sidebar"] > [data-hm-gnb-body] > [data-hm-gnb-main] {
|
||||
position: relative;
|
||||
grid-column: 2;
|
||||
min-width: 0;
|
||||
min-height: 0;
|
||||
overflow: auto;
|
||||
background: var(--hm-sem-bg-content);
|
||||
border-radius: var(--hm-lnb-join) var(--hm-gnb-join) 0 var(--hm-lnb-join);
|
||||
}
|
||||
@media (max-width: 1023px) {
|
||||
[data-hm-gnb-layout="sidebar"] > [data-hm-gnb-body] {
|
||||
grid-template-columns: minmax(0, 1fr);
|
||||
}
|
||||
[data-hm-gnb-layout="sidebar"] > [data-hm-gnb-body] > [data-hm-gnb-main] {
|
||||
grid-column: 1;
|
||||
border-radius: var(--hm-gnb-join) var(--hm-gnb-join) 0 0;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user