Merge branch 'integration/sw-home-menu' into feature/sw-home-menu
Integrate the SW home (logo) menu into SWHeader for SW general mode only. SW viewer mode code and stories are unchanged. - Resolve conflicts: keep both sw-home-menu and sw-viewer exports; renumber AI docs (catalog viewer 8->9, patterns home menu 7->8, design rules home menu 11->12) - SWHeader: start the home menu after the file name when it sits inside controls, so the file name stays visible - AI guides: mark home menu as general-mode only; forbid it in viewer mode (AI_USAGE, catalog, design rules, patterns, VIEWER.md, AI_GUIDE) - Tests: ignore wildcard identifiers in ai-docs check; update expected Storybook SW titles (SW/Tool removed, SW/Viewer added) - Add merge QA report docs/sw/sw-home-menu-merge-2026-10-19.md
This commit is contained in:
commit
3a5e29f2fa
122 files changed
+6547
-41
No files matched your search
@@ -0,0 +1,335 @@
|
||||
/* @hm-design/sw — Home menu (Figma rj6wpsfk24lOWvWiVRAANP 26:10591 "헤더/꾸러미 ver2/home on", tiles 26:11355 …).
|
||||
Scoped to .hm-sw-home-menu; reads the shared SW tokens of .hm-sw-header / .hm-sw-theme (font, text outline,
|
||||
focus). New values are Figma values (Plugin API, 2026-10-19), never global selectors. */
|
||||
|
||||
.hm-sw-home-menu {
|
||||
/* Section surface (Frame 2409–2412; Frame 2408 has slightly different stops): bottom → top + edge shade. */
|
||||
--hm-sw-home-menu-section-background:
|
||||
linear-gradient(0deg, #16120a 0%, rgba(22, 18, 10, 0) 54.458%, #16120a 100%),
|
||||
linear-gradient(0deg, #18150e 28.102%, #262015 41.084%, #332b1c 58.06%, #38301f 81.027%, #18150e 100%);
|
||||
--hm-sw-home-menu-section-border-color: #081813;
|
||||
--hm-sw-home-menu-section-inner-border-color: #20190e;
|
||||
/* Tile group g_* : fill bottom → top, 1px stroke top → bottom, drop shadow 0 2 r4 60%. */
|
||||
--hm-sw-home-menu-group-background: linear-gradient(0deg, #19160e 2%, #38301f 43.678%, #463c29 67.668%, #2f281a 100%);
|
||||
--hm-sw-home-menu-group-border: linear-gradient(180deg, #886d35 0%, #423625 8.846%, #f3dba8 26.169%, #0e0b06 83.792%, #574b30 100%);
|
||||
--hm-sw-home-menu-group-shadow: 0 2px 4px rgba(0, 0, 0, 0.6);
|
||||
/* Tile divider 1 x 44 (same gradient as the group stroke) with -1 0 r2 black shadow. */
|
||||
--hm-sw-home-menu-divider: var(--hm-sw-home-menu-group-border);
|
||||
--hm-sw-home-menu-divider-shadow: -1px 0 2px #000;
|
||||
/* Tile states: Variant2 / Variant3 stroke (INSIDE 1px, top → bottom), icon and label color. */
|
||||
--hm-sw-home-menu-item-hover-border: linear-gradient(180deg, #da6813 8.5%, #ffbb89 37.9%, #e5690d 71.9%, #ae3607 92.8%);
|
||||
--hm-sw-home-menu-item-color: var(--hm-sw-header-text-color);
|
||||
--hm-sw-home-menu-item-accent-color: #ff5c00;
|
||||
--hm-sw-home-menu-icon-color: #b6b4af;
|
||||
/* Title badge (tit_* Union, 9-slice of the Figma SVG) */
|
||||
--hm-sw-home-menu-title-color: #000;
|
||||
/* Bottom accent: 26:10591 per-section strip (top → bottom) / 662:67267 2px outline (bottom → top). */
|
||||
--hm-sw-home-menu-accent-strip: linear-gradient(180deg, #5f4b0f -6.4%, #ff5100 96.8%);
|
||||
--hm-sw-home-menu-accent-outline: linear-gradient(0deg, #ff5100 0%, #5f4b0f 76.7%);
|
||||
|
||||
/* Optional sub panel (Figma 최근파일 662:67331 / 파일출력 2뎁스 662:67471). */
|
||||
--hm-sw-recent-files-width: 354px;
|
||||
--hm-sw-recent-files-max-height: 750px;
|
||||
--hm-sw-recent-files-background: #27241d;
|
||||
--hm-sw-recent-files-border-color: #da6813;
|
||||
--hm-sw-recent-files-path-color: #d4cbbd;
|
||||
--hm-sw-recent-files-row-hover-background: var(--hm-sw-header-layer-row-hover-background);
|
||||
--hm-sw-recent-files-row-hover-color: var(--hm-sw-header-layer-row-hover-color);
|
||||
--hm-sw-recent-files-preview-width: 310px;
|
||||
--hm-sw-recent-files-preview-background: #62533d;
|
||||
|
||||
position: relative;
|
||||
isolation: isolate;
|
||||
width: max-content;
|
||||
max-width: 100%;
|
||||
}
|
||||
.hm-sw-home-menu__sections {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
max-width: 100%;
|
||||
/* 2px of the accent strip shows left, right and under the sections (menu 1305 x 77 in Figma). */
|
||||
padding: 0 2px 2px;
|
||||
/* Not in Figma (1920px only): narrower hosts scroll the menu horizontally, like the property bar. */
|
||||
overflow-x: auto;
|
||||
overflow-y: hidden;
|
||||
scrollbar-width: thin;
|
||||
}
|
||||
/* Sub panel under the menu, at its tile (position set from the DOM). */
|
||||
.hm-sw-home-menu__panel { position: absolute; z-index: 1; top: 100%; }
|
||||
|
||||
.hm-sw-home-menu__section {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex: 0 0 auto;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
height: 75px;
|
||||
/* Figma: content 5px from the top and 10px from the sides, the 1px stroke included. */
|
||||
padding: 4px 9px 0;
|
||||
border: 1px solid var(--hm-sw-home-menu-section-border-color);
|
||||
border-radius: 0 0 3px 3px;
|
||||
background: var(--hm-sw-home-menu-section-background);
|
||||
}
|
||||
/* Frame 2412 (last): 261px, 11px left. Frame 2408 keeps 340px with its group centered. */
|
||||
.hm-sw-home-menu__section:last-child { padding-left: 10px; }
|
||||
/* Inner 1px #20190E (Rectangle 6977 / border, inset 1px). */
|
||||
.hm-sw-home-menu__section::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
border: 1px solid var(--hm-sw-home-menu-section-inner-border-color);
|
||||
border-radius: 0 0 2px 2px;
|
||||
pointer-events: none;
|
||||
}
|
||||
/* 26:10591 Rectangle 6991–6995: 30px strip from y 47 behind the section, 2px visible under it. */
|
||||
.hm-sw-home-menu[data-accent="sections"] .hm-sw-home-menu__section::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
z-index: -1;
|
||||
top: 46px;
|
||||
right: -2px;
|
||||
bottom: -3px;
|
||||
left: -2px;
|
||||
border-radius: 0 0 3px 3px;
|
||||
background: var(--hm-sw-home-menu-accent-strip);
|
||||
pointer-events: none;
|
||||
}
|
||||
.hm-sw-home-menu[data-accent="sections"] .hm-sw-home-menu__section:first-child::after { left: -3px; }
|
||||
.hm-sw-home-menu[data-accent="sections"] .hm-sw-home-menu__section:last-child::after { right: -3px; }
|
||||
/* 662:67267 Rectangle 6991: 1305 x 30 from y 47, 2px INSIDE gradient stroke. */
|
||||
.hm-sw-home-menu[data-accent="outline"]::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
z-index: -1;
|
||||
top: 47px;
|
||||
right: 0;
|
||||
left: 0;
|
||||
height: 30px;
|
||||
padding: 2px;
|
||||
border-radius: 0 0 3px 3px;
|
||||
background: var(--hm-sw-home-menu-accent-outline);
|
||||
-webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
|
||||
-webkit-mask-composite: xor;
|
||||
mask: linear-gradient(#000 0 0) content-box exclude, linear-gradient(#000 0 0);
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
/* tit_* : text + 23px each side; the Figma Union SVG (132 x 27 incl. its -2 r4 shadow) is 9-sliced. */
|
||||
.hm-sw-home-menu__title {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
display: flex;
|
||||
flex: 0 0 auto;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 19px;
|
||||
margin-bottom: -1px;
|
||||
padding: 1px 23px 0;
|
||||
color: var(--hm-sw-home-menu-title-color);
|
||||
font-size: var(--hm-sw-header-label-size);
|
||||
font-weight: 400;
|
||||
line-height: 14px;
|
||||
letter-spacing: 0.02em;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.hm-sw-home-menu__title::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
z-index: -1;
|
||||
inset: -6px -4px -2px;
|
||||
border-style: solid;
|
||||
border-width: 0 30px;
|
||||
border-image: var(--hm-sw-home-menu-title-art) 0 30 fill / 0 30px / 0 stretch;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.hm-sw-home-menu__group {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex: 0 0 auto;
|
||||
height: 46px;
|
||||
border-radius: 3px;
|
||||
background: var(--hm-sw-home-menu-group-background);
|
||||
box-shadow: var(--hm-sw-home-menu-group-shadow);
|
||||
}
|
||||
/* INSIDE stroke drawn over the edge: tiles keep their full 80 x 46 like Figma. */
|
||||
.hm-sw-home-menu__group::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
padding: 1px;
|
||||
border-radius: inherit;
|
||||
background: var(--hm-sw-home-menu-group-border);
|
||||
-webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
|
||||
-webkit-mask-composite: xor;
|
||||
mask: linear-gradient(#000 0 0) content-box exclude, linear-gradient(#000 0 0);
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.hm-sw-home-menu__item {
|
||||
position: relative;
|
||||
flex: 0 0 80px;
|
||||
width: 80px;
|
||||
height: 46px;
|
||||
color: var(--hm-sw-home-menu-item-color);
|
||||
}
|
||||
.hm-sw-home-menu__item:first-child { border-radius: 3px 0 0 3px; }
|
||||
.hm-sw-home-menu__item:last-child { border-radius: 0 3px 3px 0; }
|
||||
.hm-sw-home-menu__item:only-child { border-radius: 3px; }
|
||||
/* Divider at the right edge of every tile but the last. */
|
||||
.hm-sw-home-menu__item:not(:last-child)::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
z-index: 2;
|
||||
top: 1px;
|
||||
right: -1px;
|
||||
width: 1px;
|
||||
height: 44px;
|
||||
background: var(--hm-sw-home-menu-divider);
|
||||
box-shadow: var(--hm-sw-home-menu-divider-shadow);
|
||||
pointer-events: none;
|
||||
}
|
||||
/* Variant2 / Variant3 stroke. */
|
||||
.hm-sw-home-menu__item::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
z-index: 3;
|
||||
inset: 0;
|
||||
padding: 1px;
|
||||
border-radius: inherit;
|
||||
background: var(--hm-sw-home-menu-item-hover-border);
|
||||
-webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
|
||||
-webkit-mask-composite: xor;
|
||||
mask: linear-gradient(#000 0 0) content-box exclude, linear-gradient(#000 0 0);
|
||||
opacity: 0;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
/* 18 x 18 icon slot at (31, 6); larger art is centered on it and may overflow (Figma assets carry shadows). */
|
||||
.hm-sw-home-menu__icon {
|
||||
position: absolute;
|
||||
top: 6px;
|
||||
left: 31px;
|
||||
display: grid;
|
||||
place-items: center;
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
color: var(--hm-sw-home-menu-icon-color);
|
||||
}
|
||||
.hm-sw-home-menu__icon > * { flex: none; max-width: none; }
|
||||
.hm-sw-home-menu__icon > :is(svg, img) { display: block; }
|
||||
.hm-sw-home-menu__icon--hover { visibility: hidden; }
|
||||
|
||||
.hm-sw-home-menu__label {
|
||||
position: absolute;
|
||||
top: 25px;
|
||||
left: 50%;
|
||||
max-width: 76px;
|
||||
height: 16px;
|
||||
padding: 0 var(--hm-sw-header-text-outline-room);
|
||||
overflow: hidden;
|
||||
transform: translateX(-50%);
|
||||
font-size: var(--hm-sw-header-font-size);
|
||||
font-weight: 700;
|
||||
line-height: 16px;
|
||||
letter-spacing: 0.04em;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
text-shadow: var(--hm-sw-header-text-outline);
|
||||
}
|
||||
|
||||
/* Variant2 (hover) = Variant3 (active): orange stroke, #FF5C00 icon and label, art 1px up-left. */
|
||||
.hm-sw-home-menu__item:is(:hover:not(:disabled), [data-active="true"])::after { opacity: 1; }
|
||||
.hm-sw-home-menu__item:is(:hover:not(:disabled), [data-active="true"]) {
|
||||
--hm-sw-home-menu-icon-color: var(--hm-sw-home-menu-item-accent-color);
|
||||
color: var(--hm-sw-home-menu-item-accent-color);
|
||||
}
|
||||
.hm-sw-home-menu__item:is(:hover:not(:disabled), [data-active="true"]) .hm-sw-home-menu__icon { transform: translate(-1px, -1px); }
|
||||
.hm-sw-home-menu__item:is(:hover:not(:disabled), [data-active="true"]) .hm-sw-home-menu__label { top: 24px; }
|
||||
.hm-sw-home-menu__item[data-has-hover-icon]:is(:hover:not(:disabled), [data-active="true"]) .hm-sw-home-menu__icon:not(.hm-sw-home-menu__icon--hover) { visibility: hidden; }
|
||||
.hm-sw-home-menu__item[data-has-hover-icon]:is(:hover:not(:disabled), [data-active="true"]) .hm-sw-home-menu__icon--hover { visibility: visible; }
|
||||
|
||||
/* SWRecentFiles — Figma 최근파일 662:67331 (354 x 750: rows 50px) + 2-depth preview 662:67471 (310 x 270). */
|
||||
.hm-sw-recent-files { position: relative; width: var(--hm-sw-recent-files-width); }
|
||||
/* Frame stroke: 1px #DA6813 left / right / bottom over the list edge (joins the menu's outline accent). */
|
||||
.hm-sw-recent-files::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
z-index: 2;
|
||||
inset: 0;
|
||||
border: 1px solid var(--hm-sw-recent-files-border-color);
|
||||
border-top: 0;
|
||||
border-radius: 0 0 3px 3px;
|
||||
pointer-events: none;
|
||||
}
|
||||
.hm-sw-recent-files__list {
|
||||
box-sizing: content-box; /* max-height = rows (15 x 50 = Figma 750) */
|
||||
max-height: var(--hm-sw-recent-files-max-height);
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
overscroll-behavior: contain;
|
||||
scrollbar-width: thin;
|
||||
border: 1px solid var(--hm-sw-recent-files-background);
|
||||
border-radius: 0 0 4px 4px;
|
||||
background: var(--hm-sw-recent-files-background);
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.25), inset 0 4px 8px rgba(0, 0, 0, 0.4);
|
||||
}
|
||||
.hm-sw-recent-files__row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
width: 100%;
|
||||
height: 50px;
|
||||
padding: 1px 8px;
|
||||
text-align: left;
|
||||
}
|
||||
/* Rows without a badge keep the text column at 45px (Figma px 45). */
|
||||
.hm-sw-recent-files__row:not(:has(> .hm-sw-recent-files__badge)) { padding-left: 45px; }
|
||||
.hm-sw-recent-files__badge { display: grid; flex: 0 0 29px; place-items: center; width: 29px; height: 28px; }
|
||||
.hm-sw-recent-files__badge > :is(svg, img) { display: block; max-width: none; }
|
||||
.hm-sw-recent-files__text { display: flex; flex-direction: column; gap: 2px; min-width: 0; max-width: 301px; }
|
||||
.hm-sw-recent-files__name,
|
||||
.hm-sw-recent-files__path {
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
overflow-clip-margin: var(--hm-sw-header-text-outline-room);
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
letter-spacing: 0.04em;
|
||||
}
|
||||
.hm-sw-recent-files__name { color: var(--hm-sw-header-text-color); font-size: var(--hm-sw-header-font-size); font-weight: 700; line-height: 16px; text-shadow: var(--hm-sw-header-text-outline); }
|
||||
.hm-sw-recent-files__path { color: var(--hm-sw-recent-files-path-color); font-size: var(--hm-sw-header-label-size); line-height: 14px; opacity: 0.6; text-shadow: var(--hm-sw-header-label-outline); }
|
||||
.hm-sw-recent-files__row:is(:hover, [data-hovered="true"]):not(:disabled) { background: var(--hm-sw-recent-files-row-hover-background); }
|
||||
.hm-sw-recent-files__row:is(:hover, [data-hovered="true"]):not(:disabled) .hm-sw-recent-files__name { color: var(--hm-sw-recent-files-row-hover-color); }
|
||||
.hm-sw-recent-files__empty { padding: 16px 45px; color: var(--hm-sw-recent-files-path-color); font-size: var(--hm-sw-header-label-size); opacity: 0.6; }
|
||||
/* 2-depth preview beside the row (1px gap), top aligned 1px under the row top. */
|
||||
.hm-sw-recent-files__preview {
|
||||
position: absolute;
|
||||
z-index: 3;
|
||||
left: calc(100% + 1px);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
width: var(--hm-sw-recent-files-preview-width);
|
||||
padding: 3px 0 0; /* + 1px border = Figma py 4; 270px total with the 243px body */
|
||||
border: 1px solid var(--hm-sw-recent-files-preview-background);
|
||||
border-left: 0;
|
||||
border-radius: 0 3px 4px 0;
|
||||
background: var(--hm-sw-recent-files-preview-background);
|
||||
box-shadow: inset 2px 0 2.5px rgba(0, 0, 0, 0.5);
|
||||
filter: drop-shadow(0 2px 1px rgba(0, 0, 0, 0.5));
|
||||
pointer-events: none;
|
||||
}
|
||||
.hm-sw-recent-files__preview-title {
|
||||
width: 294px;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
color: var(--hm-sw-recent-files-row-hover-color);
|
||||
font-size: var(--hm-sw-header-font-size);
|
||||
line-height: 18px;
|
||||
letter-spacing: 0.02em;
|
||||
}
|
||||
.hm-sw-recent-files__preview-body { position: relative; width: 100%; height: 243px; overflow: hidden; border-radius: 0 0 4px 0; }
|
||||
.hm-sw-recent-files__preview-body > :is(img, svg, canvas) { display: block; width: 100%; height: 100%; object-fit: cover; }
|
||||
@@ -1876,3 +1876,8 @@ div.hm-sw-header__menu-row { justify-content: space-between; gap: 8px; padding-l
|
||||
.hm-sw-header[data-leading="open"] .hm-sw-header__fields[data-configured] > .hm-sw-header__control:not([data-control="document"]) > * { flex-shrink: 0; }
|
||||
/* ...and the file name gives way only down to the default design's smallest width (96px, see the clamps above). */
|
||||
.hm-sw-header[data-leading="open"] .hm-sw-header__fields[data-configured] > .hm-sw-header__control[data-control="document"] { min-width: 96px; }
|
||||
|
||||
/* Logo (home) menu layer (SWHeader homeMenu, 2026-10-19). Top of the header, left / max-width measured from the
|
||||
object area (−2px) to the window area. Above the property bar anchor (2), under the dropdowns (30) and the
|
||||
property window (40). The logo, the file name and the window area stay visible beside it. */
|
||||
.hm-sw-header__home-menu { position: absolute; top: 0; z-index: 20; }
|
||||
Reference in new issue
Block a user