Files
HMDesign/packages/sw/src/theme/sw-footer.css
T

654 lines
37 KiB
CSS
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* @hm-design/sw — SW Footer (Figma "레이아웃 분리" 26:10097 bottom bar, components 26:9459 … 26:10097, read
through the Figma Plugin API 2026-10-20). Footer-only tokens. Text keeps the SW typography of sw.css
(Noto Sans KR instead of Figma Dotum — the 2026-10-20 Dotum default is withdrawn, black OUTSIDE outline as 16 text-shadows, own-color 0.3 / 0.4px strokes removed
like the 2026-10-16 header fix). Never touches global selectors, SWHeader or SWPopup classes.
Declared on the outermost SW scope only, like sw.css: the command line inside the bar inherits the tokens. */
:is(.hm-sw-header, .hm-sw-theme):not(:where(.hm-sw-header, .hm-sw-theme) *) {
/* Bar (26:10098 background, 72px high, #060606) */
--hm-sw-footer-height: 72px;
--hm-sw-footer-background: #060606;
--hm-sw-footer-text: #f6f4f2;
--hm-sw-footer-muted: #d4cbbd;
--hm-sw-footer-accent: #ff5c00;
--hm-sw-footer-red: #e60403;
--hm-sw-footer-disabled-opacity: 0.4;
/* Side buttons 74 × 71 (26:10189 보조기능 / 26:10192 명령어 전체보기): side-bg.svg + 8px 60% black drop shadow
towards the bar content. */
--hm-sw-footer-side-width: 74px;
--hm-sw-footer-side-shadow: 0 0 8px rgba(0, 0, 0, 0.6);
--hm-sw-footer-side-shadow-offset: 5px;
/* Auxiliary toggles 104 × 33 (26:10104, 3 × 2, gap 2px) */
--hm-sw-footer-aux-width: 104px;
--hm-sw-footer-aux-height: 33px;
--hm-sw-footer-aux-gap: 2px;
--hm-sw-footer-aux-background: linear-gradient(0deg, #262218 8%, #4a3c2b 34%, #594c31 55%, #312a1b 90%);
/* Selected face (not in Figma: sampled from the reference program screen, user decision 2026-11-09; stops approximate). */
--hm-sw-footer-aux-pressed-background: linear-gradient(0deg, #594931 0%, #3b3021 23%, #1b170f 58%, #0d0b07 100%);
--hm-sw-footer-aux-radius: 3px;
--hm-sw-footer-aux-font-size: 13px;
/* 1px borders (Plugin API, btn_객체스냅 26:9248 … btn_선가중치 26:9412): Default = brown gradient, Variant2 / Variant3
(selected) = the footer orange ring gradient. Hover is not drawn on these sets: it reuses the SW header Figma
hover ring (yellow gradient, 1px), user decision 2026-10-20. */
--hm-sw-footer-aux-border: linear-gradient(180deg, #886d35 0%, #423625 8.85%, #f3dba8 26.17%, #0e0b06 83.79%, #574b30 100%);
--hm-sw-footer-aux-hover-border: var(--hm-sw-header-hover-border-gradient);
/* Figma gra-border-orange (one value): the selected border of the auxiliary toggles, the Model tab surface and the
hover surface of the Layout tabs and their + (2026-10-20), the hover ring of the side buttons. */
--hm-sw-footer-gra-border-orange: linear-gradient(180deg, #da6813 8.52%, #ffbb89 37.93%, #e5690d 71.85%, #ae3607 92.77%);
--hm-sw-footer-aux-pressed-border: var(--hm-sw-footer-gra-border-orange);
/* Icon fill (Default #F1EDE5, selected = --hm-sw-footer-accent #FF5C00); the black 90% outline never changes. */
--hm-sw-footer-aux-icon-color: #f1ede5;
/* Command group (26:10111 groop명령어): 68 × 47 slots over a 24px category row, 71px high */
--hm-sw-footer-slot-width: 68px;
--hm-sw-footer-slot-height: 47px;
--hm-sw-footer-group-background: linear-gradient(0deg, #2f281a 0%, #312a1b 5%, #332b1c 36%, #463c29 58%, #38301f 79%, #19160e 98%);
/* Not in Figma (user decision 2026-10-27): the group and ▲ panel 1px border use the button border gradient of
명령어 전체보기 (side-bg.svg) and the auxiliary toggles instead of the solid #886D35 (= its top stop). */
--hm-sw-footer-group-border: var(--hm-sw-footer-aux-border);
--hm-sw-footer-group-radius: 4px;
/* bg_vacant 26:10113: the darker surface after the last command (empty slots and the rest of the bar). */
--hm-sw-footer-vacant-background: linear-gradient(0deg, #18150e 28%, #262015 41%, #332b1c 58%, #38301f 81%, #18150e 100%);
--hm-sw-footer-divider: linear-gradient(0deg, #20190e 0.27%, #8a7a5b 45.15%, #f3dba8 70.08%, #423625 100%);
--hm-sw-footer-divider-shadow: -1px 0 1px #000;
/* Category row (menu_bg 26:10127): the active tab is a pocket opened into the slots above */
--hm-sw-footer-menu-height: 24px;
--hm-sw-footer-menu-top: #574b30;
--hm-sw-footer-menu-bottom: #282216;
--hm-sw-footer-menu-edge-top: #685a3b;
--hm-sw-footer-menu-pocket-edge: #675a3b;
--hm-sw-footer-menu-divider: #000;
--hm-sw-footer-menu-tab-min-width: 43px;
/* Empty-slot guide (26:9242 Variant2 / guide_바로가기 등록 26:9096): 208 × 149, 4px above the slot */
--hm-sw-footer-guide-width: 208px;
--hm-sw-footer-guide-height: 149px;
--hm-sw-footer-guide-background: #0e3c2e;
--hm-sw-footer-guide-border-color: #da6813;
--hm-sw-footer-guide-caption: #b6d0c9;
/* Layout tabs (26:9942 탭 상태변화, layout01 / layout02 / layout03 / model / btn_add_layout) */
--hm-sw-footer-tab-height: 22px;
--hm-sw-footer-tab-font-size: 12px;
--hm-sw-footer-tab-text: #161410;
--hm-sw-footer-tab-background: #c3b79e;
--hm-sw-footer-tab-hover-overlay: rgba(0, 0, 0, 0.2);
--hm-sw-footer-tab-on-background: linear-gradient(0deg, #7c6c4c 0.48%, #7c6c4c 85.07%, #a6946f 100%);
--hm-sw-footer-tab-editing-background: #0f0d0a;
--hm-sw-footer-tab-border-color: rgba(0, 0, 0, 0.05);
--hm-sw-footer-tab-hover-border-color: #da6813;
--hm-sw-footer-tab-inset-shadow: inset 0 -3px 4px rgba(56, 48, 31, 0.25);
/* 12px tab text: rgba(0, 0, 0, .7) 1.3px OUTSIDE stroke under the hover / on / editing text. */
--hm-sw-footer-tab-outline-color: rgba(0, 0, 0, 0.7);
/* Command line (26:10048 / 26:10056): 566px, 71px collapsed, 270px expanded */
--hm-sw-footer-command-width: 566px;
--hm-sw-footer-command-height: 71px;
--hm-sw-footer-command-expanded-height: 270px;
--hm-sw-footer-command-background: linear-gradient(180deg, #635537 0%, #262218 5%, #281f16 10%, #282216 100%);
--hm-sw-footer-command-expanded-background: #282216;
--hm-sw-footer-command-input-background: #16130d;
--hm-sw-footer-command-input-shadow: 0 -1px 2px rgba(255, 255, 255, 0.25), inset 0 1px 4px #000;
--hm-sw-footer-command-font-size: 12px;
--hm-sw-footer-command-line-height: 14px;
/* Not in Figma (reference screens 2026-10-20): the command line inside the bar keeps at least this width. */
--hm-sw-footer-command-min-width: 280px;
/* Not in Figma: with the command line inside the bar, the slot area takes this share of the free width (bar minus
the auxiliary area and 명령어 전체보기), the command line the rest. 0.57 reproduces both reference screens
(1920 → 12 slots / command line 629px, 952 → 4 commands + ▲). Bar width only, never the command count. */
--hm-sw-footer-slot-share: 0.57;
/* Not in Figma: below this bar width the auxiliary toggles show their icon only (reference screen 2026-10-20). */
--hm-sw-footer-aux-compact-width: 45px;
}
.hm-sw-footer-sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
/* ---------- Bar ---------- */
.hm-sw-footer {
container: hm-sw-footer / inline-size;
position: relative;
display: flex;
align-items: stretch;
width: 100%;
min-width: 0;
height: var(--hm-sw-footer-height);
background: var(--hm-sw-footer-background);
color: var(--hm-sw-footer-text);
}
/* Layout tabs sit on top of the bar, right aligned (26:10190 at 1823, 986 in the 1920 frame). */
.hm-sw-footer__tabs { position: absolute; right: 0; bottom: 100%; z-index: 1; display: flex; }
.hm-sw-footer__aux-area { flex: 0 0 auto; display: flex; gap: 2px; margin-right: 4px; }
/* 26:10111 starts 1px below the bar top and ends at the bar bottom. */
.hm-sw-footer__group {
position: relative;
flex: 1 1 auto;
min-width: 0;
display: flex;
margin-top: 1px;
border: 1px solid transparent;
border-right: 0;
border-radius: var(--hm-sw-footer-group-radius) 0 0 0;
background: var(--hm-sw-footer-group-background) padding-box, var(--hm-sw-footer-group-border) border-box;
}
/* The vacant surface covers the slot row only (2026-10-20): it used to run under the category row, where the open
pocket of the current tab showed it, so a pocket crossing the last command's edge (e.g. 수정 with one command) was
split into the group surface and the vacant surface. Every pocket now shows the same group surface. */
.hm-sw-footer__vacant { position: absolute; top: 1px; right: 0; height: calc(var(--hm-sw-footer-slot-height) - 1px); background: var(--hm-sw-footer-vacant-background); pointer-events: none; }
.hm-sw-footer__scroll {
position: relative;
flex: 0 1 auto;
min-width: 0;
margin: -1px 0 -1px -1px;
}
.hm-sw-footer__panel { position: relative; display: flex; flex-direction: column; width: max-content; }
.hm-sw-footer__slots { display: flex; height: var(--hm-sw-footer-slot-height); }
.hm-sw-footer__group > .hm-sw-footer-side { margin-top: -1px; }
/* The rest of the bar is bg_vacant too (26:10113 runs to the frame edge and covers the bottom border). */
.hm-sw-footer__trailing { flex: 1 1 auto; min-width: 0; display: flex; align-items: center; justify-content: flex-end; margin-bottom: -1px; background: var(--hm-sw-footer-vacant-background); }
/* Command line in the bar (reference screen 2026-10-20): free width between the auxiliary grid and the slots,
bottom aligned so an expanded line grows upwards. The slots keep their own width before 명령어 전체보기. */
.hm-sw-footer__command { position: relative; z-index: 2; flex: 1 1 0; min-width: var(--hm-sw-footer-command-min-width); margin: 1px 4px 0 0; }
.hm-sw-footer__command > .hm-sw-footer-command { position: absolute; left: 0; right: 0; bottom: 0; width: auto; max-width: none; }
.hm-sw-footer[data-command] .hm-sw-footer__group { flex: 0 1 auto; }
.hm-sw-footer[data-command] .hm-sw-footer__trailing { flex: 0 0 auto; }
/* Status text above the bar, left (cursor coordinates in the reference screen). */
.hm-sw-footer__status { position: absolute; left: 0; bottom: 100%; z-index: 1; padding: 0 0 3px 2px; font-size: 12px; line-height: 14px; color: var(--hm-sw-footer-text); white-space: nowrap; text-shadow: var(--hm-sw-header-label-outline); }
/* Bar-level guide: 4px above the empty slot (which starts 2px below the bar top). */
.hm-sw-footer > .hm-sw-footer__guide { bottom: calc(100% + 2px); }
/* ---------- Side buttons (보조기능 / 명령어 전체보기) ---------- */
.hm-sw-footer-side {
position: relative;
z-index: 1;
flex: 0 0 var(--hm-sw-footer-side-width);
display: flex;
flex-direction: column;
align-items: center;
gap: 2px;
width: var(--hm-sw-footer-side-width);
height: 71px;
padding-top: 18px;
background: url("../components/sw-footer/assets/side-bg.svg") 0 0 / 74px 71px no-repeat;
filter: drop-shadow(var(--hm-sw-footer-side-shadow-offset) 0 8px rgba(0, 0, 0, 0.6));
color: var(--hm-sw-footer-text);
font-size: 14px;
letter-spacing: 0.04em;
line-height: 16px;
text-align: center;
white-space: nowrap;
}
.hm-sw-footer-side[data-side="end"] { filter: drop-shadow(calc(-1 * var(--hm-sw-footer-side-shadow-offset)) 0 8px rgba(0, 0, 0, 0.6)); }
/* Title (보조기능 / 명령어) Bold in every state (2026-10-20 user request); the 전체보기 subtitle keeps its weight. */
.hm-sw-footer-side__title { font-weight: 700; text-shadow: var(--hm-sw-header-text-outline); }
.hm-sw-footer-side__subtitle { text-shadow: var(--hm-sw-header-label-outline); }
/* Not in Figma: hover / selected reuse the footer rules: the whole button lights up, both text lines in the accent
(#FF5C00) and the orange ring of a selected auxiliary toggle over the frame (2026-10-20; was the title only). Size,
face and shadow are unchanged; disabled keeps the default look. */
.hm-sw-footer-side::after {
content: "";
position: absolute;
inset: 0;
border: 1px solid transparent;
background: var(--hm-sw-footer-gra-border-orange) border-box;
-webkit-mask: linear-gradient(#000 0 0) padding-box, linear-gradient(#000 0 0);
-webkit-mask-composite: xor;
mask: linear-gradient(#000 0 0) padding-box exclude, linear-gradient(#000 0 0);
opacity: 0;
pointer-events: none;
}
.hm-sw-footer-side:is(:hover:not(:disabled), [aria-pressed="true"], [aria-expanded="true"])::after { opacity: 1; }
.hm-sw-footer-side:is(:hover:not(:disabled), [aria-pressed="true"], [aria-expanded="true"]) :is(.hm-sw-footer-side__title, .hm-sw-footer-side__subtitle) { color: var(--hm-sw-footer-accent); }
/* ---------- Auxiliary toggles (객체스냅 …) ---------- */
.hm-sw-footer-aux {
display: grid;
grid-template-columns: repeat(var(--hm-sw-footer-aux-columns, 3), var(--hm-sw-footer-aux-width));
grid-auto-rows: var(--hm-sw-footer-aux-height);
align-content: center;
gap: var(--hm-sw-footer-aux-gap);
}
.hm-sw-footer-aux__button {
position: relative;
width: var(--hm-sw-footer-aux-width);
height: var(--hm-sw-footer-aux-height);
/* Gradient border: the face on the padding box, the border gradient on the border box (size and radius unchanged). */
border: 1px solid transparent;
border-radius: var(--hm-sw-footer-aux-radius);
background: var(--hm-sw-footer-aux-background) padding-box, var(--hm-sw-footer-aux-border) border-box;
color: var(--hm-sw-footer-text);
font-size: var(--hm-sw-footer-aux-font-size);
letter-spacing: 0.04em;
}
/* Icon box: Figma icons sit at 12px, 8–10px (14–16px boxes); a 17px box at 10, 7 inside the 1px border centers them. */
.hm-sw-footer-aux__icon { position: absolute; left: 10px; top: 7px; display: grid; place-items: center; width: 17px; height: 17px; color: var(--hm-sw-footer-aux-icon-color); }
.hm-sw-footer-aux__icon :is(img, svg) { display: block; flex: none; }
.hm-sw-footer-aux__label {
position: absolute;
left: 35px;
right: 10px;
top: 7px;
overflow: hidden;
line-height: 17px;
text-align: center;
text-overflow: ellipsis;
white-space: nowrap;
text-shadow: var(--hm-sw-header-text-outline);
}
/* Hover (not selected): yellow ring only; icon and text keep their Default colors. */
.hm-sw-footer-aux__button:hover:not(:disabled):not([aria-pressed="true"]) {
background: var(--hm-sw-footer-aux-background) padding-box, var(--hm-sw-footer-aux-hover-border) border-box;
}
/* Selected (Figma Variant2 / Variant3): orange border, icon and text together; it stays while hovered and after
the pointer leaves. Icons follow through currentColor (swFooterAuxIcons, or any currentColor icon). */
.hm-sw-footer-aux__button[aria-pressed="true"] {
background: var(--hm-sw-footer-aux-pressed-background) padding-box, var(--hm-sw-footer-aux-pressed-border) border-box;
}
.hm-sw-footer-aux__button[aria-pressed="true"] :is(.hm-sw-footer-aux__icon, .hm-sw-footer-aux__label) { color: var(--hm-sw-footer-accent); }
/* ---------- Command slots (Line, PLine … / 빈 칸) ---------- */
.hm-sw-footer-slot {
position: relative;
flex: 0 0 var(--hm-sw-footer-slot-width);
width: var(--hm-sw-footer-slot-width);
height: var(--hm-sw-footer-slot-height);
}
/* 1px divider between slots (Rectangle 7461 …: x = 68n, 5 → 42). */
.hm-sw-footer-slot + .hm-sw-footer-slot::before {
content: "";
position: absolute;
z-index: 1;
left: 0;
top: 5px;
width: 1px;
height: 37px;
background: var(--hm-sw-footer-divider);
box-shadow: var(--hm-sw-footer-divider-shadow);
pointer-events: none;
}
.hm-sw-footer-tool {
position: absolute;
inset: 0;
color: var(--hm-sw-footer-text);
font-size: 14px;
letter-spacing: 0.04em;
}
.hm-sw-footer-tool__label {
position: absolute;
left: 2px;
right: 2px;
top: 6px;
overflow: hidden;
line-height: 16px;
text-align: center;
/* A command longer than the slot (POLYGON, WIPEOUT …) ends in … inside the same 64px; the full name stays the
accessible name and shows as the tooltip (SWFooterToolButton). Slot, font and centering are unchanged. */
text-overflow: ellipsis;
white-space: nowrap;
text-shadow: var(--hm-sw-header-text-outline);
}
.hm-sw-footer-tool__icon { position: absolute; left: 50%; top: 26px; display: grid; place-items: center; width: 18px; height: 18px; transform: translateX(-50%); }
.hm-sw-footer-tool__icon :is(img, svg) { display: block; flex: none; }
.hm-sw-footer-tool__icon--active { display: none; }
/* Variant2 (hover) and Variant3 (selected) are the same in Figma: #FF5C00 text and the orange icon. */
.hm-sw-footer-tool:is(:hover:not(:disabled), [aria-pressed="true"]) { color: var(--hm-sw-footer-accent); }
.hm-sw-footer-tool[data-active-icon]:is(:hover:not(:disabled), [aria-pressed="true"]) .hm-sw-footer-tool__icon--default { display: none; }
.hm-sw-footer-tool[data-active-icon]:is(:hover:not(:disabled), [aria-pressed="true"]) .hm-sw-footer-tool__icon--active { display: grid; }
.hm-sw-footer-tool:disabled { opacity: var(--hm-sw-footer-disabled-opacity); }
/* Last slot when the commands do not fit (reference screens 2026-10-20): ico_arrow 26:10023 ▲ opens the panel of
the other commands above the slots, ▼ while open. */
.hm-sw-footer-more { position: absolute; inset: 0; }
.hm-sw-footer-more__icon { position: absolute; top: 4px; right: 4px; width: 18px; height: 18px; border-radius: 2px; background: #000 url("../components/sw-footer/assets/arrow-up.svg") 1px 1px / 16px 16px no-repeat; }
.hm-sw-footer-more:is(:hover, [data-active]) .hm-sw-footer-more__icon { background-image: url("../components/sw-footer/assets/arrow-up-hover.svg"); }
.hm-sw-footer-more[aria-expanded="true"] .hm-sw-footer-more__icon { background-image: url("../components/sw-footer/assets/arrow-down.svg"); }
.hm-sw-footer-more[aria-expanded="true"]:is(:hover, [data-active]) .hm-sw-footer-more__icon { background-image: url("../components/sw-footer/assets/arrow-down-hover.svg"); }
.hm-sw-footer__more-panel {
position: absolute;
z-index: 4;
right: 0;
bottom: 100%;
display: flex;
flex-wrap: wrap;
/* Rows fill from the left in data order; a short last row stays on the left (the panel itself is right aligned). */
justify-content: flex-start;
border: 1px solid transparent;
border-bottom: 0;
border-radius: var(--hm-sw-footer-group-radius) var(--hm-sw-footer-group-radius) 0 0;
background: var(--hm-sw-footer-group-background) padding-box, var(--hm-sw-footer-group-border) border-box;
}
/* Empty slot (btn_add_menu 26:9971): 68 × 46 one pixel below the slot top; hover adds the orange dashed ring. */
.hm-sw-footer-add {
position: absolute;
left: 0;
top: 1px;
width: var(--hm-sw-footer-slot-width);
height: 46px;
background: url("../components/sw-footer/assets/slot-add.svg") 0 0 / 68px 46px no-repeat;
}
.hm-sw-footer-add:is(:hover:not(:disabled), [aria-expanded="true"]) { background-image: url("../components/sw-footer/assets/slot-add-hover.svg"); }
.hm-sw-footer-add:disabled { opacity: var(--hm-sw-footer-disabled-opacity); }
/* Without onSlotAdd the + wells are drawn but inert (no ring, no guide). */
.hm-sw-footer-add[data-inert] { pointer-events: none; }
.hm-sw-footer-slot:has(.hm-sw-footer-add:hover:not(:disabled))::before { visibility: hidden; }
/* Guide (가이드 영상 보기): centered over the slot, 4px above it. */
.hm-sw-footer-guide {
position: absolute;
z-index: 3;
left: 50%;
bottom: calc(100% + 3px);
width: var(--hm-sw-footer-guide-width);
height: var(--hm-sw-footer-guide-height);
overflow: hidden;
transform: translateX(-50%);
border: 1px solid var(--hm-sw-footer-guide-border-color);
border-radius: 2px;
background: var(--hm-sw-footer-guide-background);
pointer-events: none;
}
.hm-sw-footer-guide[data-standalone] { position: relative; left: auto; bottom: auto; transform: none; }
.hm-sw-footer-guide__media { position: absolute; left: 5px; top: 5px; width: 194px; height: 111px; overflow: hidden; border: 1px solid #000; background: #000; }
.hm-sw-footer-guide__media > :is(img, video) { display: block; width: 100%; height: 100%; object-fit: cover; }
.hm-sw-footer-guide__title { position: absolute; left: 5px; top: 123px; font-size: 14px; letter-spacing: 0.04em; line-height: 16px; color: var(--hm-sw-footer-text); text-shadow: var(--hm-sw-header-text-outline); white-space: nowrap; }
.hm-sw-footer-guide__caption { position: absolute; right: 6px; top: 124px; font-size: 12px; letter-spacing: 0.02em; line-height: 14px; color: var(--hm-sw-footer-guide-caption); text-shadow: var(--hm-sw-header-label-outline); white-space: nowrap; }
/* Narrow bar (reference screen 2026-10-20): icon-only toggles, 45 × 33. The label stays as the accessible name. */
@container hm-sw-footer (max-width: 1279px) {
.hm-sw-footer-aux { --hm-sw-footer-aux-width: var(--hm-sw-footer-aux-compact-width); }
.hm-sw-footer-aux__icon { left: 13px; }
.hm-sw-footer-aux__label { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
}
/* ---------- Category row (도형 수정 편집 …) ---------- */
.hm-sw-footer-menu { position: relative; display: flex; align-items: flex-start; height: var(--hm-sw-footer-menu-height); }
/* Tabs that do not fit scroll inside the viewport with ◀ ▶ (reference screens 2026-10-20). */
.hm-sw-footer-menu__viewport { position: relative; flex: 0 1 auto; min-width: 0; display: flex; align-items: flex-start; height: 100%; padding-left: 7px; overflow: hidden; scrollbar-width: none; }
.hm-sw-footer-menu__viewport::-webkit-scrollbar { display: none; }
.hm-sw-footer-menu__step { position: relative; flex: 0 0 13px; display: grid; place-items: center; width: 13px; height: 16px; margin-top: 4px; color: var(--hm-sw-footer-text); }
.hm-sw-footer-menu__step svg { display: block; filter: drop-shadow(0 0 1px #000); }
.hm-sw-footer-menu__step:hover:not(:disabled) { color: var(--hm-sw-footer-accent); }
.hm-sw-footer-menu__step:disabled { opacity: var(--hm-sw-footer-disabled-opacity); }
.hm-sw-footer-menu__step + .hm-sw-footer-menu__step { margin-right: 4px; }
.hm-sw-footer-menu__tabs { display: contents; }
.hm-sw-footer-menu__surface { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; overflow: visible; }
.hm-sw-footer-menu__tab {
position: relative;
flex: 0 0 auto;
min-width: var(--hm-sw-footer-menu-tab-min-width);
height: 16px;
margin-top: 4px;
padding: 0 8px;
color: var(--hm-sw-footer-muted);
font-size: 14px;
/* Bold in Default / Hover / current (2026-10-20 user request); only the color changes between the states. */
font-weight: 700;
/* Figma 1.4px (10%) on 레이어 … 구조/배근 (0.56px on the first four): with it the Noto widths meet the Figma
boxes (45 / 61 / 43 / 84px). */
letter-spacing: 0.1em;
line-height: 16px;
text-align: center;
white-space: nowrap;
text-shadow: var(--hm-sw-header-text-outline);
}
/* Variant2 (hover) and Variant3 (current) are #FF5C00 in Figma. */
.hm-sw-footer-menu__tab:is(:hover:not(:disabled), [aria-selected="true"]) { color: var(--hm-sw-footer-accent); }
/* 1px × 10px black divider (Rectangle 7480 …) between tabs; the current tab has its 7px pocket edges instead. */
.hm-sw-footer-menu__divider { position: relative; flex: 0 0 1px; width: 1px; height: 10px; margin-top: 7px; background: var(--hm-sw-footer-menu-divider); }
/* 2026-10-22: selecting a tab never moves text or tabs. The row keeps every 1px divider slot (hidden beside the
current tab) and the current tab gets no margins: its 7px pocket edges are drawn over the neighbours' 8px padding.
The last tab always keeps 6px on its right so its pocket edge (6px + the 1px slot) stays clear of + / ◀ ▶. */
.hm-sw-footer-menu__divider[data-pocket] { visibility: hidden; }
.hm-sw-footer-menu__tab:last-of-type { margin-right: 6px; }
.hm-sw-footer-menu__add { position: relative; flex: 0 0 28px; width: 28px; height: 12px; margin-top: 6px; background: url("../components/sw-footer/assets/menu-add.svg") 0 0 / 28px 12px no-repeat; }
/* Not in Figma: only Default of btn_add (26:9451) exists. Hover (2026-10-20, user request): the + in the footer accent
(#FF5C00, same black outline), like the category tabs next to it. */
.hm-sw-footer-menu__add:hover:not(:disabled) { background-image: url("../components/sw-footer/assets/menu-add-hover.svg"); }
/* ---------- Layout tabs ---------- */
.hm-sw-footer-tabs { display: flex; align-items: flex-end; gap: 1px; height: var(--hm-sw-footer-tab-height); font-size: var(--hm-sw-footer-tab-font-size); letter-spacing: 0.02em; }
.hm-sw-footer-tabs__list { display: contents; }
.hm-sw-footer-tabs__add { flex: 0 0 24px; width: 24px; height: 22px; background: url("../components/sw-footer/assets/tab-add.svg") 0 0 / 24px 22px no-repeat; }
/* Hover (2026-10-20, user request): the Model / Layout orange surface in the button shape, the + keeps its outline. */
.hm-sw-footer-tabs__add { position: relative; }
.hm-sw-footer-tabs__add:hover:not(:disabled)::before {
content: "";
position: absolute;
inset: 0;
background: url("../components/sw-footer/assets/menu-add.svg") 50% 50% / 28px 12px no-repeat, var(--hm-sw-footer-gra-border-orange);
-webkit-mask: url("../components/sw-footer/assets/tab-add.svg") 0 0 / 24px 22px no-repeat;
mask: url("../components/sw-footer/assets/tab-add.svg") 0 0 / 24px 22px no-repeat;
}
.hm-sw-footer-tab { position: relative; flex: 0 0 auto; display: flex; height: 22px; color: var(--hm-sw-footer-tab-text); }
.hm-sw-footer-tab__select {
position: relative;
z-index: 1;
display: flex;
align-items: center;
height: 22px;
min-width: 69px;
padding: 0 4px 0 8px;
/* -5% (2026-10-22 user-set, was the row's 2%): the Bold labels fit the fixed 57px slanted label box. */
letter-spacing: -0.05em;
white-space: nowrap;
line-height: 14px;
}
/* Model / Layout labels are Bold in every state (2026-10-22 user request); the name-edit input keeps 400. */
.hm-sw-footer-tab__label { display: block; font-weight: 700; }
.hm-sw-footer-tab__input {
width: 57px;
height: 16px;
margin: 0;
padding: 0;
border: 0;
outline: none;
background: transparent;
color: inherit;
font: inherit;
letter-spacing: inherit;
}
.hm-sw-footer-tab__remove { position: relative; z-index: 1; flex: 0 0 auto; height: 22px; opacity: 0; }
.hm-sw-footer-tab__remove:focus-visible { opacity: 1; }
/* Rounded tab (layout02 / layout03): 1px border, 4px top radius, -3px inset shadow. */
/* The Figma border is an inside stroke drawn over the content (it does not widen the 85px tab): ::after. */
.hm-sw-footer-tab[data-shape="rounded"] {
overflow: hidden;
border-radius: 4px 4px 0 0;
background: var(--hm-sw-footer-tab-background);
}
.hm-sw-footer-tab[data-shape="rounded"]::after {
content: "";
position: absolute;
z-index: 2;
inset: 0;
border: 1px solid var(--hm-sw-footer-tab-border-color);
border-radius: inherit;
box-shadow: var(--hm-sw-footer-tab-inset-shadow);
pointer-events: none;
}
.hm-sw-footer-tab[data-shape="rounded"] .hm-sw-footer-tab__label { max-width: 12em; overflow: hidden; text-overflow: ellipsis; }
.hm-sw-footer-tab[data-shape="rounded"] .hm-sw-footer-tab__remove { width: 16px; background: url("../components/sw-footer/assets/tab-delete.svg") 0 0 / 16px 22px no-repeat; }
.hm-sw-footer-tab[data-shape="rounded"] .hm-sw-footer-tab__remove:hover { background-image: url("../components/sw-footer/assets/tab-delete-hover.svg"); }
.hm-sw-footer-tab[data-shape="rounded"][data-state="on"] { background: var(--hm-sw-footer-tab-on-background); }
.hm-sw-footer-tab[data-shape="rounded"][data-state="editing"] { background: var(--hm-sw-footer-tab-editing-background); }
.hm-sw-footer-tab[data-shape="rounded"]:is(:hover, [data-state="editing"])::after { border-color: var(--hm-sw-footer-tab-hover-border-color); }
/* Hover, not selected (2026-10-20, user request): the Model orange surface; text as on Model (below). */
.hm-sw-footer-tab[data-shape="rounded"][data-state="off"]:hover { background: var(--hm-sw-footer-gra-border-orange); }
/* Slanted tab (layout01, next to Model): 97 × 22 mirrored bg asset + the 28px red close piece.
9-slice (2026-10-22): 97px / 57px label stay the minimum and the tab grows with a longer label. Each state asset is
drawn as a border-image: the 21px slant and the 4px corner keep their size, only the flat middle stretches (the
asset gradients are vertical, so stretching changes nothing else). Border-image works in every target browser;
mask-border (Firefox: none) is not used. */
.hm-sw-footer-tab[data-shape="slant"] { min-width: 97px; }
.hm-sw-footer-tab[data-shape="slant"] .hm-sw-footer-tab__label { min-width: 57px; max-width: 12em; overflow: hidden; text-overflow: ellipsis; }
.hm-sw-footer-tab[data-shape="slant"]::before,
.hm-sw-footer-tab[data-shape="slant"]::after {
content: "";
position: absolute;
inset: 0;
box-sizing: border-box;
transform: scaleX(-1);
border: solid transparent;
border-width: 0 4px 0 21px;
border-image: url("../components/sw-footer/assets/tab-slant.svg") 0 4 0 21 fill / 0 4px 0 21px stretch;
pointer-events: none;
}
.hm-sw-footer-tab[data-shape="slant"]::after { z-index: 2; border-image-source: none; }
.hm-sw-footer-tab[data-shape="slant"] .hm-sw-footer-tab__remove { width: 28px; background: url("../components/sw-footer/assets/tab-close.svg") 0 0 / 28px 22px no-repeat; }
.hm-sw-footer-tab[data-shape="slant"] .hm-sw-footer-tab__remove:hover { background-image: url("../components/sw-footer/assets/tab-close-hover.svg"); }
.hm-sw-footer-tab[data-shape="slant"][data-state="on"]::before { border-image-source: url("../components/sw-footer/assets/tab-slant-on.svg"); }
.hm-sw-footer-tab[data-shape="slant"][data-state="editing"]::before { border-image-source: url("../components/sw-footer/assets/tab-slant-editing.svg"); }
/* Hover, not selected (2026-10-20, user request): the Model orange surface in the slanted shape. The shape mask is the
union of the asset at both ends (slant end, corner end) and a plain middle, so it follows any width without
mask-border. */
.hm-sw-footer-tab[data-shape="slant"][data-state="off"]:hover::before {
border-image-source: none;
/* Longhands: a var() shorthand followed by background-origin does not survive CSSOM re-serialization. */
background-image: var(--hm-sw-footer-gra-border-orange);
background-origin: border-box;
-webkit-mask:
url("../components/sw-footer/assets/tab-slant.svg") 0 0 / 97px 22px no-repeat,
url("../components/sw-footer/assets/tab-slant.svg") 100% 0 / 97px 22px no-repeat,
linear-gradient(#000 0 0) 21px 0 / calc(100% - 25px) 22px no-repeat;
mask:
url("../components/sw-footer/assets/tab-slant.svg") 0 0 / 97px 22px no-repeat,
url("../components/sw-footer/assets/tab-slant.svg") 100% 0 / 97px 22px no-repeat,
linear-gradient(#000 0 0) 21px 0 / calc(100% - 25px) 22px no-repeat;
-webkit-mask-origin: border-box;
mask-origin: border-box;
-webkit-mask-clip: border-box;
mask-clip: border-box;
}
.hm-sw-footer-tab[data-shape="slant"][data-state="off"]:hover::after { border-image-source: url("../components/sw-footer/assets/tab-slant-ring.svg"); }
/* layout01 Variant6 (editing + hover): the fill without its own ring and the orange ring on top. */
.hm-sw-footer-tab[data-shape="slant"][data-state="editing"]:hover::before { border-image-source: url("../components/sw-footer/assets/tab-slant-editing-fill.svg"); }
.hm-sw-footer-tab[data-shape="slant"][data-state="editing"]:hover::after { border-image-source: url("../components/sw-footer/assets/tab-slant-ring.svg"); }
.hm-sw-footer-tab[data-shape="slant"] + .hm-sw-footer-tab--model { margin-left: -9px; }
/* Text per state (Figma layout01 / layout02 variants). */
/* Selected / editing Layout tabs (light text on brown / black) keep the 70% outline. Hover of a tab that is not
selected and the Model tab draw their text exactly as the Default (2026-10-20): only the surface changes. */
.hm-sw-footer-tab:not(.hm-sw-footer-tab--model):is([data-state="on"], [data-state="editing"]) .hm-sw-footer-tab__select {
text-shadow:
1.3px 0 0 var(--hm-sw-footer-tab-outline-color), 0.92px 0.92px 0 var(--hm-sw-footer-tab-outline-color),
0 1.3px 0 var(--hm-sw-footer-tab-outline-color), -0.92px 0.92px 0 var(--hm-sw-footer-tab-outline-color),
-1.3px 0 0 var(--hm-sw-footer-tab-outline-color), -0.92px -0.92px 0 var(--hm-sw-footer-tab-outline-color),
0 -1.3px 0 var(--hm-sw-footer-tab-outline-color), 0.92px -0.92px 0 var(--hm-sw-footer-tab-outline-color);
}
.hm-sw-footer-tab[data-state="on"] { color: var(--hm-sw-footer-text); }
.hm-sw-footer-tab[data-state="editing"] { color: var(--hm-sw-footer-red); }
.hm-sw-footer-tab[data-shape="rounded"][data-state="on"]:hover,
.hm-sw-footer-tab[data-shape="slant"][data-state="on"]:hover { color: var(--hm-sw-footer-accent); }
/* On the orange surface (Model selected or hovered, Layout hovered, 2026-10-20 user decision): the Default tab text,
black #161410 without outline, in the inherited tab size and weight (no size or weight of its own), so hover never
changes the text, its size or its place. */
.hm-sw-footer-tab:is([data-shape="rounded"], [data-shape="slant"])[data-state="off"]:hover,
.hm-sw-footer-tab--model:is([data-state="on"], :hover) { color: var(--hm-sw-footer-tab-text); }
/* layout01 "on hover" draws the default beige surface under the orange text. */
.hm-sw-footer-tab[data-shape="slant"][data-state="on"]:hover::before { border-image-source: url("../components/sw-footer/assets/tab-slant.svg"); }
/* The × appears on hover (all shapes) and in no other state (Figma opacity 0). */
.hm-sw-footer-tab:hover .hm-sw-footer-tab__remove { opacity: 1; }
.hm-sw-footer-tab .hm-sw-footer-tab__remove:disabled { opacity: 0; cursor: default; }
/* Model (26:9914): 73 × 22 asset, label 22px from the left. 9-slice (2026-10-22, see the slanted tab): 73px stays the
minimum; the 21px slant and the 1px right edge keep their size, the flat middle stretches with a longer label. */
.hm-sw-footer-tab--model { min-width: 73px; }
.hm-sw-footer-tab--model::before {
content: "";
position: absolute;
inset: 0;
box-sizing: border-box;
border: solid transparent;
border-width: 0 1px 0 21px;
border-image: url("../components/sw-footer/assets/tab-model.svg") 0 1 0 21 fill / 0 1px 0 21px stretch;
pointer-events: none;
}
/* Selected and hovered (2026-10-20, user request; was the brown model On 26:9925): the gra-border-orange surface in the
Model shape (union mask: the asset at the slant end + a plain rest, square right end). */
.hm-sw-footer-tab--model:is([data-state="on"], :hover)::before {
border-image-source: none;
background-image: var(--hm-sw-footer-gra-border-orange);
background-origin: border-box;
-webkit-mask:
url("../components/sw-footer/assets/tab-model.svg") 0 0 / 73px 22px no-repeat,
linear-gradient(#000 0 0) 21px 0 / calc(100% - 21px) 22px no-repeat;
mask:
url("../components/sw-footer/assets/tab-model.svg") 0 0 / 73px 22px no-repeat,
linear-gradient(#000 0 0) 21px 0 / calc(100% - 21px) 22px no-repeat;
-webkit-mask-origin: border-box;
mask-origin: border-box;
-webkit-mask-clip: border-box;
mask-clip: border-box;
}
.hm-sw-footer-tab--model .hm-sw-footer-tab__select { flex: 1 0 auto; min-width: 0; padding: 0 16px 0 22px; }
.hm-sw-footer-tab--model .hm-sw-footer-tab__label { max-width: 12em; overflow: hidden; text-overflow: ellipsis; }
/* ---------- Command line ---------- */
.hm-sw-footer-command {
position: relative;
display: flex;
flex-direction: column;
width: var(--hm-sw-footer-command-width);
max-width: 100%;
height: var(--hm-sw-footer-command-height);
overflow: hidden;
border-radius: 4px 4px 0 0;
background: var(--hm-sw-footer-command-background) 0 0 / 100% var(--hm-sw-footer-command-height) no-repeat, var(--hm-sw-footer-command-expanded-background);
color: var(--hm-sw-footer-text);
font-size: var(--hm-sw-footer-command-font-size);
letter-spacing: 0.1em;
line-height: var(--hm-sw-footer-command-line-height);
}
.hm-sw-footer-command[data-expanded] { height: var(--hm-sw-footer-command-expanded-height); }
.hm-sw-footer-command__history {
flex: 1 1 auto;
min-height: 0;
margin: 0;
padding: 4px 30px 2px 8px;
overflow-y: auto;
list-style: none;
scrollbar-width: thin;
scrollbar-color: #574b30 transparent;
text-shadow: var(--hm-sw-header-label-outline);
}
.hm-sw-footer-command__history > li { white-space: pre; }
.hm-sw-footer-command:not([data-expanded]) .hm-sw-footer-command__history { overflow: hidden; }
.hm-sw-footer-command__history > li { overflow: hidden; text-overflow: ellipsis; }
.hm-sw-footer-command__toggle { position: absolute; top: 4px; right: 4px; width: 18px; height: 18px; border-radius: 2px; background: #000 url("../components/sw-footer/assets/arrow-up.svg") 1px 1px / 16px 16px no-repeat; }
.hm-sw-footer-command__toggle:hover { background-image: url("../components/sw-footer/assets/arrow-up-hover.svg"); }
.hm-sw-footer-command__toggle[aria-expanded="true"] { background-image: url("../components/sw-footer/assets/arrow-down.svg"); }
.hm-sw-footer-command__toggle[aria-expanded="true"]:hover { background-image: url("../components/sw-footer/assets/arrow-down-hover.svg"); }
.hm-sw-footer-command__prompt {
flex: 0 0 23px;
display: flex;
align-items: center;
gap: 5px;
height: 23px;
margin: 0 4px;
padding: 0 6px;
background: var(--hm-sw-footer-command-input-background);
box-shadow: var(--hm-sw-footer-command-input-shadow);
}
.hm-sw-footer-command__label { flex: 0 0 auto; text-shadow: var(--hm-sw-header-label-outline); }
.hm-sw-footer-command__input {
flex: 1 1 auto;
min-width: 0;
height: 16px;
margin: 0;
padding: 0;
border: 0;
outline: none;
background: transparent;
color: inherit;
font: inherit;
letter-spacing: inherit;
text-shadow: var(--hm-sw-header-label-outline);
caret-color: var(--hm-sw-footer-text);
}
.hm-sw-footer-command__prompt:has(.hm-sw-footer-command__input:focus-visible) { outline: 1px solid var(--hm-sw-header-focus-color); outline-offset: -1px; }