Files
HMDesign/packages/sw/src/theme/sw.css
T
shkim4 2fc1b3e108 fix(sw): 2026-10-21 SW design review and responsive header without More from 760px
User-approved design review (2026-10-21):
- SW Header: from 760px up nothing moves into More; the five menus stay with their
  titles (titles and values ellipsize), file name shrinks to 96px. Open next to the
  logo no longer blocks field shrinking above 760px (760/768 overflow fixed, also for
  configured `controls` headers). Dropdown yellow ring inside the button, black seam.
- Property Bar values as read-only red text; property popup "=" labels, read-only
  black values, per-entry hover with pointer.
- Home Menu recent files (3 rows, path + name caption, empty preview), Footer + slot
  guide off by default, Viewer file list without icons, Storybook widths 1920-760.
- Tests: old More expectations (integrated-improvement, keyboard-dismiss,
  footer-popup-viewer-refinement, storybook-cleanup-stage1) moved to the new rule;
  functional checks kept.
2026-10-21 17:29:25 +09:00

2125 lines
119 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 Header (Figma 26:8944 "header_green").
SW-only tokens. They never touch @hm-design/ui tokens or global selectors. */
/* Tokens, typography and the control reset are shared by the full header and <SWTheme>,
which scopes standalone sub-components without a consumer class.
Token defaults are declared only on the OUTERMOST SW scope (2026-10-20): a nested scope root (viewer menu,
More menu, panel, footer command line inside a header / footer / <SWTheme>) inherits the tokens instead of
resetting them, so a token set through `style` (or the consumer's own class) on the outermost scope reaches
every SW element inside it. Same specificity as before (0,1,0); the same rule is used in sw-viewer.css and
sw-footer.css. */
:is(.hm-sw-header, .hm-sw-theme):not(:where(.hm-sw-header, .hm-sw-theme) *) {
/* Size */
--hm-sw-header-height: 49px;
--hm-sw-header-bar-height: 48px;
--hm-sw-header-field-height: 38px;
--hm-sw-header-gap: 4px;
--hm-sw-header-logo-width: 32px;
--hm-sw-header-logo-height: 17px;
/* Typography: SW default is Noto Sans KR (2026-10-20 user decision; the Dotum default of the same day is withdrawn,
Figma Dotum is replaced on purpose). The package ships no font file: the app loads Noto Sans KR 400 / 500 / 700;
Malgun Gothic / Apple SD Gothic Neo cover systems without it. Web UI has its own token (same font, never shared). */
--hm-sw-header-font-family: "Noto Sans KR", "Malgun Gothic", "Apple SD Gothic Neo", sans-serif;
--hm-sw-header-font-size: 14px;
--hm-sw-header-label-size: 12px;
/* Color */
--hm-sw-header-background: #060606;
--hm-sw-header-text-color: #f6f4f2;
--hm-sw-header-title-color: #f0f7f5;
--hm-sw-header-selected-color: #ffc600;
--hm-sw-header-focus-color: #f0f7f5;
--hm-sw-header-arrow-color: #47af91;
--hm-sw-header-hover: rgba(255, 255, 255, 0.08);
/* Figma header/btn_home (26:10655) "hover" stroke: 1px, top -> bottom. */
--hm-sw-header-hover-border-gradient: linear-gradient(180deg, #a67d03 0%, #f2cc0f 16.41%, #fadd4f 37.19%, #f2cc0f 62.03%, #926e03 87.88%);
--hm-sw-header-hover-border-width: 1px;
/* Figma 662:67267 "home on" (logo menu open): header border-top / border-bottom, 2px, full width. */
--hm-sw-header-home-on-line-color: #5f4b0f;
--hm-sw-header-home-on-line-width: 2px;
/* Figma header/document_tit (26:10662) document dropdown */
--hm-sw-header-document-menu-width: 310px;
--hm-sw-header-document-menu-background: #103127;
--hm-sw-header-document-menu-border-color: #041611;
--hm-sw-header-document-menu-border-width: 1px;
--hm-sw-header-document-menu-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.25);
--hm-sw-header-document-menu-inset-shadow: inset 0 4px 8px 0 rgba(0, 0, 0, 0.4);
--hm-sw-header-document-menu-divider-color: rgba(194, 217, 210, 0.2);
--hm-sw-header-document-list-max-height: 320px;
/* Document list scrollbar (2026-10-21): the Storybook sidebar scrollbar (.storybook/manager.css, #BDDFD4 thumb at
50% / 80% on hover, 6px, round, transparent track). */
--hm-sw-header-document-scrollbar-thumb: rgba(189, 223, 212, 0.5);
--hm-sw-header-document-scrollbar-thumb-hover: rgba(189, 223, 212, 0.8);
--hm-sw-header-document-action-background: rgba(182, 208, 201, 0.2);
--hm-sw-header-document-action-color: rgba(0, 0, 0, 0.7);
/* Figma hover variants: list 26:10680, + New 26:10762, Open 26:10805 */
--hm-sw-header-document-item-hover-background: rgba(0, 0, 0, 0.4);
--hm-sw-header-document-action-hover-background: rgba(182, 208, 201, 0.3);
--hm-sw-header-document-action-hover-color: #000;
/* User addition (not in Figma): Close Document button on the current document row */
--hm-sw-header-document-close-color: rgba(240, 247, 245, 0.7);
--hm-sw-header-document-close-hover-background: rgba(182, 208, 201, 0.2);
--hm-sw-header-document-close-hover-color: #f0f7f5;
/* Figma header/menu/레이어 (26:10940) layer dropdown, rows header/dropdown/brown/row (26:10687),
icon_전구 / icon_눈꽃 / icon_자물쇠 hover (26:10810 / 26:10855 / 26:10912) */
--hm-sw-header-layer-menu-width: 234px;
--hm-sw-header-layer-menu-background: #27241d;
--hm-sw-header-layer-menu-border-color: #000;
--hm-sw-header-layer-menu-radius: 3px;
--hm-sw-header-layer-menu-shadow: 0 4px 8px 0 rgba(16, 48, 38, 0.25);
--hm-sw-header-layer-expanded-border-color: #081813;
/* Not in Figma: 8 rows (the Figma sample height); longer lists scroll inside the dropdown. */
--hm-sw-header-layer-list-max-height: 240px;
--hm-sw-header-layer-row-hover-background: #62533d;
--hm-sw-header-layer-row-hover-color: #ff5c00;
--hm-sw-header-layer-icon-hover-background: rgba(0, 0, 0, 0.25);
--hm-sw-header-layer-chip-border-color: #c9c9c9;
--hm-sw-header-layer-footer-border-color: rgba(197, 177, 158, 0.15);
--hm-sw-header-layer-detail-background: rgba(197, 177, 158, 0.15);
--hm-sw-header-layer-detail-color: #fff;
--hm-sw-header-layer-detail-text-opacity: 0.35;
--hm-sw-header-layer-detail-hover-background: rgba(197, 177, 158, 0.25);
--hm-sw-property-surface: #e4dbc9;
--hm-sw-property-content: #f1ece1;
--hm-sw-property-border: #a67d03;
--hm-sw-property-label: #000;
--hm-sw-property-table: #d2c8b4;
--hm-sw-property-inner-border: #948871;
/* Popup scrollbar (every SW popup body: SWPopup, SWViewerPanel, property window). Same as the DWG/DXF viewer
panels (thin, HM warm-neutral-mid thumb on warm-neutral-light track). */
--hm-sw-popup-scrollbar-thumb: #9a9284;
--hm-sw-popup-scrollbar-track: #e0dace;
/* Property fields (Figma 26:12170 ~ 26:12649): Hover border, editing On, dropdown On, unit colors. */
--hm-sw-property-field-hover-border-color: rgba(33, 29, 19, 0.4);
--hm-sw-property-field-editing-background: #0f0d0a;
--hm-sw-property-field-open-background: #211d13;
--hm-sw-property-field-editing-unit-color: #fff;
--hm-sw-property-field-open-unit-color: #d4cbbd;
/* Gauge (user-supplied Figma SVGs, 2026-10-19). Fill = Rectangle 6926: 6px pill, 1px black stroke,
vertical #8E0000 / #FF4242 37% / #E40000 76% / #1E0000 inside the stroke; its right end sits under
the thumb. Unfilled track = beige measured row by row from the user's reference image.
Thumb = Rectangle 6915: 14px conic + 2px 40% ring; its two drop shadows are CSS. */
--hm-sw-property-range-fill: linear-gradient(#000 0 1px, #8e0000 1px, #ff4242 2.46px, #e40000 3.99px, #1e0000 4.94px, #000 4.94px);
--hm-sw-property-range-fill-edge: #000;
--hm-sw-property-range-track: linear-gradient(#aea28b 0 1px, #c3b9a4 1px 2px, #c7bda9 2px 4px, #b7ac96 4px 5px, #ac9e84 5px);
--hm-sw-property-range-highlight: #eadec8;
/* SWSlider appearance "panel" (2026-10-20): the gauge the SW popup used so far (HM UI Slider: 6px #E0DACE
track, #266651 range, 18px white thumb with a 2px #266651 ring), the same shape as SWViewerSlider. Existing
values only (#E0DACE = popup scrollbar track, #266651 = viewer panel accent). Appearance "property" uses the
--hm-sw-property-range-* tokens above. */
--hm-sw-slider-panel-track: #e0dace;
--hm-sw-slider-panel-range: #266651;
--hm-sw-slider-panel-thumb: #fff;
/* SWSelect (2026-10-20): the panel field values of the viewer 축척 지정 select (property inner border / content). */
--hm-sw-select-border-color: var(--hm-sw-property-inner-border);
--hm-sw-select-background: var(--hm-sw-property-content);
--hm-sw-select-text: var(--hm-sw-property-label);
/* User-confirmed: document (file name) surface */
--hm-sw-header-document-background: linear-gradient(180deg, #081813 0%, #09271e 8.69%, #0b3227 25.43%, #0e3d2f 51.25%, #0b3227 80.03%, #0a2b21 89.76%, #081813 100%);
--hm-sw-header-document-border-color: #0e4c3a;
/* User-confirmed: object (editing) surface */
--hm-sw-header-object-background: linear-gradient(0deg, #144838 0%, #1a4536 6%, #1f4134 10%, #10392d 18%, #296b55 72%, #1f5a47 83%, #144838 92%, #124133 100%);
--hm-sw-header-object-border-color: #135643;
--hm-sw-header-object-radius: 6px;
/* User-confirmed: property field surface */
--hm-sw-header-property-background: linear-gradient(0deg, rgba(0, 0, 0, 0.45) 0%, rgba(0, 0, 0, 0.45) 26.41%, rgba(0, 0, 0, 0.4) 70%, rgba(0, 0, 0, 0.45) 100%);
--hm-sw-header-property-border-color: #08251c;
--hm-sw-header-property-radius: 3px;
--hm-sw-header-property-shadow: 0 1px 4px 0 rgba(9, 39, 30, 0.7);
/* Figma: window area, action pill, window-move stripes, minimize bar */
--hm-sw-header-pill-background: rgba(0, 0, 0, 0.8);
--hm-sw-header-pill-border-color: #092920;
--hm-sw-header-stripe-color: rgba(28, 106, 81, 0.32);
--hm-sw-header-window-icon-color: #adb0af;
/* Figma header/btn_최소최대화 (26:12156) hover. 종료 (26:12161) hover is its Figma asset
(close-hover.svg: #E40000 32 x 48 + white X). */
--hm-sw-header-window-button-hover-background: rgba(0, 0, 0, 0.2);
--hm-sw-header-window-icon-hover-color: #fff;
/* Figma 창이동 motion (26:10220) tooltip 26:215. */
--hm-sw-header-tooltip-background: rgba(0, 0, 0, 0.8);
--hm-sw-header-tooltip-color: #fff;
/* Figma text strokes (26:8944 and its menus, Plugin API 2026-10-16), all OUTSIDE:
14 / 16px text = black 1.3px under the text + 0.3px of its own color; 12px labels = black 1px;
"... 상세" pills = 0.4px of their own color, no black. Outline: 16 shadows on a 1.3px / 1px circle
(never clipped by the glyph like a centered -webkit-text-stroke). The 2026-10-16 additional fix removed the
own-color stroke, including the detail pills. Black text-shadow remains unchanged. */
--hm-sw-header-text-outline-color: #000;
--hm-sw-header-text-outline:
1.3px 0 0 var(--hm-sw-header-text-outline-color), 1.2px 0.5px 0 var(--hm-sw-header-text-outline-color),
0.92px 0.92px 0 var(--hm-sw-header-text-outline-color), 0.5px 1.2px 0 var(--hm-sw-header-text-outline-color),
0 1.3px 0 var(--hm-sw-header-text-outline-color), -0.5px 1.2px 0 var(--hm-sw-header-text-outline-color),
-0.92px 0.92px 0 var(--hm-sw-header-text-outline-color), -1.2px 0.5px 0 var(--hm-sw-header-text-outline-color),
-1.3px 0 0 var(--hm-sw-header-text-outline-color), -1.2px -0.5px 0 var(--hm-sw-header-text-outline-color),
-0.92px -0.92px 0 var(--hm-sw-header-text-outline-color), -0.5px -1.2px 0 var(--hm-sw-header-text-outline-color),
0 -1.3px 0 var(--hm-sw-header-text-outline-color), 0.5px -1.2px 0 var(--hm-sw-header-text-outline-color),
0.92px -0.92px 0 var(--hm-sw-header-text-outline-color), 1.2px -0.5px 0 var(--hm-sw-header-text-outline-color);
--hm-sw-header-label-outline:
1px 0 0 var(--hm-sw-header-text-outline-color), 0.92px 0.38px 0 var(--hm-sw-header-text-outline-color),
0.71px 0.71px 0 var(--hm-sw-header-text-outline-color), 0.38px 0.92px 0 var(--hm-sw-header-text-outline-color),
0 1px 0 var(--hm-sw-header-text-outline-color), -0.38px 0.92px 0 var(--hm-sw-header-text-outline-color),
-0.71px 0.71px 0 var(--hm-sw-header-text-outline-color), -0.92px 0.38px 0 var(--hm-sw-header-text-outline-color),
-1px 0 0 var(--hm-sw-header-text-outline-color), -0.92px -0.38px 0 var(--hm-sw-header-text-outline-color),
-0.71px -0.71px 0 var(--hm-sw-header-text-outline-color), -0.38px -0.92px 0 var(--hm-sw-header-text-outline-color),
0 -1px 0 var(--hm-sw-header-text-outline-color), 0.38px -0.92px 0 var(--hm-sw-header-text-outline-color),
0.71px -0.71px 0 var(--hm-sw-header-text-outline-color), 0.92px -0.38px 0 var(--hm-sw-header-text-outline-color);
/* Room for the outline outside clipped (ellipsis) text boxes. */
--hm-sw-header-text-outline-room: 2px;
/* Field dropdowns: color 26:10986, line style 26:11104 (rows 26:10702), text style 26:11181,
dimension style 26:11215. Surface, rows and ring follow the layer dropdown tokens above. */
--hm-sw-header-menu-divider-color: rgba(197, 177, 158, 0.15);
--hm-sw-header-menu-divider-strong-color: rgba(197, 177, 158, 0.25);
/* Not in Figma: 8 rows; longer lists scroll inside the dropdown (same as the layer list). */
--hm-sw-header-menu-list-max-height: 240px;
/* Not in Figma: palette + 4 user color rows; more user colors scroll inside the palette. */
--hm-sw-header-color-palette-max-height: 118px;
--hm-sw-header-color-mode-color: #d4cbbd;
--hm-sw-header-color-mode-background: rgba(98, 83, 61, 0.3);
--hm-sw-header-color-mode-on-background: #62533d;
--hm-sw-header-color-pick-background: linear-gradient(180deg, #c5b19e 0%, #5f554c 100%);
--hm-sw-header-color-chip-border-color: #c9c9c9;
--hm-sw-header-color-input-border-color: rgba(197, 177, 158, 0.2);
/* Figma input 26:11656 (Default / hover / on) and cursor 26:11664. */
--hm-sw-header-input-color: #e60403;
--hm-sw-header-input-hover-border-color: rgba(212, 203, 189, 0.25);
--hm-sw-header-input-editing-background: #0f0d0a;
--hm-sw-header-input-editing-border-color: rgba(212, 203, 189, 0.3);
}
/* Every SW scope root (nested ones too) applies the typography from the inherited tokens. */
.hm-sw-header,
.hm-sw-theme {
color: var(--hm-sw-header-text-color);
font-family: var(--hm-sw-header-font-family);
font-size: var(--hm-sw-header-font-size);
font-weight: 400;
line-height: normal;
-webkit-font-smoothing: antialiased;
}
.hm-sw-header {
container: hm-sw-header / inline-size;
position: relative;
display: block;
width: 100%;
height: var(--hm-sw-header-height);
background: var(--hm-sw-header-background);
}
/* Figma 26:10492. Header stays 49px; host content can reserve the extra 28px when open.
The strip ends after its last field (user correction 2026-10-19, overrides the fixed 1222px frame):
it shrinks to its content, so no empty brown area, and is capped by the space right of its left
edge (inline max-width); longer property lists scroll inside. */
.hm-sw-header__bar-anchor { position: absolute; top: 49px; z-index: 2; }
.hm-sw-property-bar {
--hm-sw-property-bar-background: #271f13;
--hm-sw-property-bar-border: #08251c;
width: max-content;
max-width: 100%;
height: 28px;
overflow-x: auto;
overflow-y: hidden;
scrollbar-width: thin;
border: 1px solid var(--hm-sw-property-bar-border);
border-top: 0;
border-radius: 0 0 6px 6px;
background: var(--hm-sw-property-bar-background);
box-shadow: inset 0 4px 4px rgba(0, 0, 0, .6);
}
.hm-sw-property-bar__content { display: flex; align-items: center; width: max-content; min-width: 100%; height: 27px; }
.hm-sw-property-bar__object { flex: 0 0 90px; width: 90px; text-align: center; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; color: var(--hm-sw-header-selected-color); font-weight: 700; letter-spacing: .04em; }
.hm-sw-property-bar__fields { display: flex; align-items: center; gap: 16px; padding-right: 6px; }
.hm-sw-property-bar__field { display: flex; align-items: center; gap: 6px; white-space: nowrap; }
.hm-sw-property-bar__field label { color: var(--hm-sw-header-text-color); letter-spacing: .04em; }
.hm-sw-property-bar__field .hm-sw-header__input { flex-shrink: 0; }
/* 2026-10-21 (user decision): the bar shows its values (반지름 · 지름 · 원주 · 면적 …) as plain text (an <output>, never
focused) in the input's place, font and outline. They stay red: the property window edits them. */
.hm-sw-property-bar__value { flex-shrink: 0; padding: 2px 4px 2px 6px; color: var(--hm-sw-header-input-color); font-size: var(--hm-sw-header-font-size); font-weight: 700; line-height: 16px; letter-spacing: 0.02em; white-space: nowrap; text-shadow: var(--hm-sw-header-text-outline); }
.hm-sw-property-bar__value[data-disabled="true"] { opacity: 0.4; }
.hm-sw-property-bar:focus-visible { outline: 2px solid var(--hm-sw-header-focus-color); outline-offset: -2px; }
/* Configured controls use the same components in an ordered list; no empty removed slots.
The default hierarchy and breakpoint rules below remain intact for existing callers. */
.hm-sw-header__object-area[data-configured] { padding-inline: 4px; }
.hm-sw-header__fields[data-configured] { flex: 1 1 auto; padding-left: 0; }
.hm-sw-header__control { display: flex; align-items: center; flex: 0 1 auto; min-width: 0; }
.hm-sw-header__control > * { min-width: 0; }
.hm-sw-header .hm-sw-header__control > :is(.hm-sw-header__menu, .hm-sw-header__field) { flex-shrink: 1; }
.hm-sw-header__control:is([data-control="propertyBar"], [data-control="propertyPanel"], [data-control="details"]) { flex-shrink: 0; }
.hm-sw-header__control > .hm-sw-header__toggle { padding-inline: 8px; }
.hm-sw-header__control[data-control="document"] { flex: 1 1 160px; max-width: 310px; }
.hm-sw-header__control[data-control="document"] > .hm-sw-header__document { flex: 1 1 auto; width: 100%; }
.hm-sw-header__control[data-hidden] { display: none; }
.hm-sw-header__window[data-configured] { flex-basis: 152px; width: 152px; }
.hm-sw-header__more-item[data-visible="true"] { display: flex; }
.hm-sw-header__more-item[data-visible="false"] { display: none; }
@container hm-sw-header (max-width: 1079.98px) {
.hm-sw-header__window[data-configured] { flex-basis: 88px; width: 88px; }
}
@container hm-sw-header (max-width: 639.98px) {
.hm-sw-header__window[data-configured] { flex-basis: 64px; width: 64px; }
}
:is(.hm-sw-header, .hm-sw-theme) *,
:is(.hm-sw-header, .hm-sw-theme) *::before,
:is(.hm-sw-header, .hm-sw-theme) *::after { box-sizing: border-box; }
:where(.hm-sw-header, .hm-sw-theme) button {
margin: 0;
padding: 0;
border: 0;
background: transparent;
color: inherit;
font: inherit;
letter-spacing: inherit;
text-align: inherit;
cursor: pointer;
}
:where(.hm-sw-header, .hm-sw-theme) button:disabled { cursor: default; opacity: 0.4; }
:is(.hm-sw-header, .hm-sw-theme) button:focus-visible,
:is(.hm-sw-header, .hm-sw-theme) [role="menuitem"]:focus-visible,
:is(.hm-sw-header, .hm-sw-theme) [role="menuitemcheckbox"]:focus-visible {
outline: 2px solid var(--hm-sw-header-focus-color);
outline-offset: -2px;
}
.hm-sw-header__bar {
display: flex;
align-items: stretch;
gap: 2px;
height: var(--hm-sw-header-bar-height);
min-width: 0;
overflow: visible;
}
/* Home: 80 x 48, its curved background overlaps the document well by 15px. */
.hm-sw-header__home {
position: relative;
z-index: 2;
flex: 0 0 80px;
width: 80px;
height: var(--hm-sw-header-bar-height);
margin-right: -17px;
overflow: hidden;
}
/* Figma Rectangle 6671: document surface behind the slanted home shape (0-65px only,
so the file name at x=70 stays visible through the transparent part of the 80px box). */
.hm-sw-header__home::before {
content: "";
position: absolute;
inset: 0 auto 0 0;
width: 65px;
border: 1px solid var(--hm-sw-header-document-border-color);
border-right: 0;
background: var(--hm-sw-header-document-background);
}
.hm-sw-header__home-bg,
.hm-sw-header__home-bg-hover {
position: absolute;
left: -8px;
top: -12px;
width: 92px;
height: 72px;
max-width: none;
pointer-events: none;
}
/* Logo slot: the Figma home logo frame (32 x 17 at 12, 16). The slot is common design;
the logo itself belongs to each SW program. Any logo (image or element, any ratio)
is contained inside the slot and never overflows it. */
.hm-sw-header__logo {
position: absolute;
left: 12px;
top: 16px;
display: flex;
align-items: center;
justify-content: center;
width: var(--hm-sw-header-logo-width);
height: var(--hm-sw-header-logo-height);
overflow: hidden;
pointer-events: none;
}
.hm-sw-header__logo > :is(img, svg) {
display: block;
width: 100%;
height: 100%;
object-fit: contain;
}
.hm-sw-header__logo > :not(img, svg) { max-width: 100%; max-height: 100%; }
/* Document (file name). The wrapper is the flex item (responsive width) and the anchor of the
document dropdown; the button inside is the user-confirmed square well. */
.hm-sw-header__document {
position: relative;
z-index: 1;
display: flex;
height: var(--hm-sw-header-bar-height);
}
.hm-sw-header__document-button {
display: flex;
align-items: center;
width: 100%;
min-width: 0;
height: var(--hm-sw-header-bar-height);
padding: 0 12px 0 5px;
gap: 15px;
border-radius: 0;
border-top: 1px solid var(--hm-sw-header-document-border-color);
border-right: 1px solid var(--hm-sw-header-document-border-color);
border-bottom: 1px solid var(--hm-sw-header-document-border-color);
border-left: 0;
background: var(--hm-sw-header-document-background);
box-shadow: none;
color: var(--hm-sw-header-title-color);
font-weight: 700;
letter-spacing: 0.06em;
}
.hm-sw-header__document-name {
flex: 1 1 auto;
min-width: 0;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.hm-sw-header__arrow {
flex: 0 0 7px;
width: 7px;
height: 4px;
background: var(--hm-sw-header-arrow-color);
clip-path: polygon(0 0, 100% 0, 50% 100%);
}
/* Open (Figma document_tit "hover" variant): yellow name and an up arrow. */
.hm-sw-header__document-button[aria-expanded="true"] .hm-sw-header__arrow { transform: rotate(180deg); }
/* Hover (2026-10-16 user decision): the file name gets no yellow border ring; only its text
turns #FFC600. Green border, background and arrow stay; hover never opens the dropdown. */
.hm-sw-header__document-button:hover .hm-sw-header__document-name { color: var(--hm-sw-header-selected-color); }
/* Document dropdown — Figma 26:10671 "drop". Overlays below the file name (the header keeps
49px). Figma right-aligns a 310px list (+1px border each side) to the 310px file name, so at
1920 its outer box is x 63-375; anchoring the left edge gives the same box and keeps it on
screen when the file name narrows (the file name always starts at x 65). */
.hm-sw-header__document-menu {
position: absolute;
top: 100%;
left: calc(-2 * var(--hm-sw-header-document-menu-border-width));
z-index: 30;
display: flex;
flex-direction: column;
width: calc(var(--hm-sw-header-document-menu-width) + 2 * var(--hm-sw-header-document-menu-border-width));
max-width: calc(100cqw - 71px - var(--hm-sw-header-leading-width, 0px));
border: var(--hm-sw-header-document-menu-border-width) solid var(--hm-sw-header-document-menu-border-color);
border-radius: 0 0 4px 4px;
overflow: hidden;
background: var(--hm-sw-header-document-menu-background);
box-shadow: var(--hm-sw-header-document-menu-shadow);
color: var(--hm-sw-header-title-color);
}
.hm-sw-header__document-list {
margin: 0;
padding: 0;
list-style: none;
max-height: var(--hm-sw-header-document-list-max-height);
overflow-x: hidden;
overflow-y: auto;
box-shadow: var(--hm-sw-header-document-menu-inset-shadow);
}
/* Scrollbar (2026-10-21): like the Storybook sidebar — 6px, round thumb, transparent track 3px in from top and bottom,
thumb 50% (80% on the thumb). Shown whenever the list scrolls: Chromium does not repaint a custom scrollbar on the
list's own :hover, so a hover-only thumb could stay hidden. Chromium / Safari draw it with ::-webkit-scrollbar;
Firefox, which has no such pseudo-elements, uses the SW standard thin scrollbar with the same colors. Only the
scrollbar changes: list size, rows and scrolling stay as they are. */
@supports not selector(::-webkit-scrollbar) {
.hm-sw-header__document-list { scrollbar-width: thin; scrollbar-color: var(--hm-sw-header-document-scrollbar-thumb) transparent; }
}
.hm-sw-header__document-list::-webkit-scrollbar { width: 6px; background: transparent; }
.hm-sw-header__document-list::-webkit-scrollbar-track { margin: 3px 0; background: transparent; }
.hm-sw-header__document-list::-webkit-scrollbar-thumb { border-radius: 9px; background: var(--hm-sw-header-document-scrollbar-thumb); }
.hm-sw-header__document-list::-webkit-scrollbar-thumb:hover { background: var(--hm-sw-header-document-scrollbar-thumb-hover); }
/* Row = select button + optional Close Document button (siblings). Hover and the current
document are styled on the row so the overlay stays while the pointer is on the X button. */
.hm-sw-header__document-row {
display: flex;
align-items: center;
height: 32px;
}
.hm-sw-header__document-item {
display: flex;
align-items: center;
flex: 1 1 auto;
gap: 8px;
min-width: 0;
height: 32px;
padding: 8px;
font-weight: 700;
letter-spacing: 0.04em;
text-align: left;
}
/* Figma header/document_tit/list hover: black 40% over the menu background; text and icon unchanged. */
.hm-sw-header__document-row:hover:not([data-disabled]) { background: var(--hm-sw-header-document-item-hover-background); }
/* User addition: the current document keeps its place in the list; only its name turns #FFC600
(no border, no background, icon unchanged), so selection reads differently from the black
hover overlay. */
.hm-sw-header__document-row[data-active="true"] .hm-sw-header__document-item-name { color: var(--hm-sw-header-selected-color); }
/* User addition: Close Document (X) at the right end of every row (closes that document, not the
dropdown). Hidden by default with its space reserved, so names never move; shown on row hover
and on keyboard focus (opacity, not display, so it stays reachable with Tab). */
.hm-sw-header__document-close {
display: grid;
opacity: 0;
place-items: center;
flex: 0 0 24px;
width: 24px;
height: 24px;
margin-right: 4px;
border-radius: 2px;
color: var(--hm-sw-header-document-close-color);
}
.hm-sw-header__document-row:hover .hm-sw-header__document-close,
.hm-sw-header__document-row:has(:focus-visible) .hm-sw-header__document-close { opacity: 1; }
.hm-sw-header__document-close:hover {
background: var(--hm-sw-header-document-close-hover-background);
color: var(--hm-sw-header-document-close-hover-color);
}
.hm-sw-header__document-icon {
position: relative;
display: flex;
align-items: center;
justify-content: center;
flex: 0 0 29px;
width: 29px;
height: 12px;
}
/* Figma icon_dualmonitor: 37 x 19 SVG drawn at -4 / -3 (drop shadow area) around the 29 x 12 box. */
.hm-sw-header__document-icon > img.hm-sw-header__document-icon-default {
position: absolute;
left: -4px;
top: -3px;
width: 37px;
height: 19px;
max-width: none;
}
.hm-sw-header__document-icon > :not(.hm-sw-header__document-icon-default) { max-width: 100%; max-height: 100%; }
.hm-sw-header__document-item-name {
flex: 1 1 auto;
min-width: 0;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
line-height: 16px;
}
.hm-sw-header__document-footer {
display: flex;
align-items: center;
justify-content: space-between;
height: 40px;
padding: 8px;
border-top: 1px solid var(--hm-sw-header-document-menu-divider-color);
box-shadow: var(--hm-sw-header-document-menu-inset-shadow);
}
/* A single remaining action keeps its Figma side: Open stays right, + New stays left. */
.hm-sw-header__document-footer > [data-action="open"]:only-child { margin-left: auto; }
.hm-sw-header__document-action {
height: 24px;
padding: 5px 6px;
border-radius: 2px;
background: var(--hm-sw-header-document-action-background);
color: var(--hm-sw-header-document-action-color);
font-weight: 700;
line-height: 14px;
letter-spacing: 0.02em;
white-space: nowrap;
}
/* Figma + New / Open hover: background 20% -> 30%, text black 70% -> 100%. Size, padding and
radius stay; no yellow ring (these follow their own Figma hover, not the §11.1 border rule). */
.hm-sw-header__document-action:hover:not(:disabled) {
background: var(--hm-sw-header-document-action-hover-background);
color: var(--hm-sw-header-document-action-hover-color);
}
/* Object (editing) area — user-confirmed single green surface. */
.hm-sw-header__object-area {
display: flex;
align-items: center;
flex: 1 1 0;
min-width: 0;
height: var(--hm-sw-header-bar-height);
padding: 4px 0;
border: 1px solid var(--hm-sw-header-object-border-color);
border-radius: var(--hm-sw-header-object-radius);
background: var(--hm-sw-header-object-background);
box-shadow: none;
}
/* Figma places the 90px mode cell and the 157px property block on the area's outer edge (over the 1px border). */
.hm-sw-header__mode {
flex: 0 1 90px;
min-width: 0;
margin-left: -1px;
padding: 0 8px;
overflow: hidden;
text-align: center;
white-space: nowrap;
text-overflow: ellipsis;
font-weight: 700;
letter-spacing: 0.04em;
}
.hm-sw-header__fields {
display: flex;
align-items: center;
flex: 0 1 auto;
gap: var(--hm-sw-header-gap);
min-width: 0;
}
/* Property field — user-confirmed inset surface. */
.hm-sw-header__field {
display: flex;
align-items: center;
gap: 12px;
height: var(--hm-sw-header-field-height);
min-width: 0;
padding: 0 10px 0 11px;
border: 1px solid var(--hm-sw-header-property-border-color);
border-radius: var(--hm-sw-header-property-radius);
background: var(--hm-sw-header-property-background);
box-shadow: var(--hm-sw-header-property-shadow);
}
.hm-sw-header__field--layer { flex: 0 1 auto; width: 234px; gap: 8px; padding-left: 12px; }
.hm-sw-header__field--color { flex: 0 1 auto; width: 192px; padding-left: 12px; }
.hm-sw-header__field--line-style { flex: 0 1 auto; width: 284px; justify-content: center; }
.hm-sw-header__field--text-style { flex: 0 1 auto; width: 164px; }
.hm-sw-header__field--dimension-style { flex: 0 1 auto; width: 164px; }
.hm-sw-header__field-text {
display: flex;
flex-direction: column;
min-width: 0;
}
.hm-sw-header__field-label {
height: 14px;
padding-left: 1px;
font-size: var(--hm-sw-header-label-size);
line-height: 14px;
letter-spacing: 0.02em;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
/* Value: Regular (400) 14 / 0.56px (2026-10-20 user decision, kept with Noto Sans KR). The Figma text is Dotum Regular
(the layer style name Dotum/bold/14 is an overlap + outline look); Bold values were wider and cut 0_Layer_Cludmark /
치수 Standard. The black text outline stays. Composed Controls (below) show the value Bold. */
.hm-sw-header__field-value {
height: 16px;
overflow: hidden;
font-weight: 400;
line-height: 16px;
letter-spacing: 0.04em;
white-space: nowrap;
text-overflow: ellipsis;
}
/* Composed Controls (2026-10-20 user request): the menu fields placed on their own (SWHeaderLayerMenu … outside
<SWHeader>) show the value Bold. Fields inside SWHeader keep Regular (400) above; the widths are unchanged, so a
value wider than its Figma box ends in an ellipsis + title as before. */
.hm-sw-header__field-value:not(.hm-sw-header .hm-sw-header__field-value) {
font-weight: 700;
}
.hm-sw-header__layer-icons { display: flex; flex: 0 0 auto; }
.hm-sw-header__layer-icon { position: relative; display: block; width: 20px; height: 20px; }
.hm-sw-header__layer-union { position: absolute; left: 3px; top: 1px; width: 14px; height: 18px; }
.hm-sw-header__layer-ellipse { position: absolute; left: 3px; top: 1px; width: 14px; height: 14px; }
.hm-sw-header__layer-bars { position: absolute; left: 7px; top: 13px; display: flex; flex-direction: column; }
.hm-sw-header__layer-bars > i { display: block; width: 6px; height: 1px; background: #d9d9d9; }
.hm-sw-header__layer-bars > i:nth-child(even) { background: #83898d; }
.hm-sw-header__chip {
position: relative;
flex: 0 0 60px;
width: 60px;
height: 20px;
border-radius: 2px;
background: #000;
}
.hm-sw-header__chip > span {
position: absolute;
inset: 1px;
border: 1px solid #fff;
border-radius: 1px;
}
.hm-sw-header__linetype { display: flex; flex: 0 0 auto; gap: 2px; }
.hm-sw-header__linetype > i { display: block; width: 10px; height: 4px; border: 1px solid #000; background: #fff; }
/* Grid, same tracks as the former flex row (name: content width, never under 28px; 가중치 / 스케일: 38px). Firefox gave the
flex row a max-content 6.4px under its content (cutting "Continuous" in the 284px field); grid tracks size the same in
Chromium and Firefox (2026-10-20). min-width 28px: a shrunk representative field (narrow More slot) shows an ellipsis,
never a cut glyph. */
.hm-sw-header__line-values { display: grid; grid-template-columns: minmax(28px, auto) 38px 38px; gap: 12px; min-width: 0; }
.hm-sw-header__font-name {
flex: 0 0 auto;
max-width: 48px;
overflow: hidden;
font-size: 16px;
font-weight: 700;
letter-spacing: 0.04em;
white-space: nowrap;
text-overflow: ellipsis;
}
.hm-sw-header__dimension-icon { position: relative; flex: 0 0 60px; width: 60px; height: 15px; }
.hm-sw-header__dimension-icon > img { position: absolute; inset: 0; display: block; width: 60px; height: 15px; }
.hm-sw-header__dimension-icon-hover { visibility: hidden; }
/* Group-field hover (user request): all labels/values and the font sample inherit yellow.
Swatches and layer-state graphics retain their data colors. Line borders and the dimension
SVG's black mask outline stay black; only the white foreground changes. Disabled is excluded.
While a field's own dropdown is open (data-expanded) hover adds nothing: the expanded styling
stays as is and hover returns once the list closes. Focus-visible is unaffected. */
.hm-sw-header__field:hover:not(:disabled, [data-expanded="true"]) { color: var(--hm-sw-header-selected-color); }
.hm-sw-header__field:hover:not(:disabled, [data-expanded="true"]) .hm-sw-header__linetype > i { background: var(--hm-sw-header-selected-color); }
.hm-sw-header__field:hover:not(:disabled, [data-expanded="true"]) .hm-sw-header__dimension-icon-default { visibility: hidden; }
.hm-sw-header__field:hover:not(:disabled, [data-expanded="true"]) .hm-sw-header__dimension-icon-hover { visibility: visible; }
/* Hover — Figma header/btn_home "hover": the 1px border turns into a yellow vertical gradient.
Same treatment on every bordered SW Header button except the file name and 속성Bar / 속성창
(text-only hover, see .hm-sw-header__document-button:hover and .hm-sw-header__toggle:hover),
drawn over the existing 1px border
(no size, padding, radius, background or shadow change, so nothing moves).
Selected keeps its #FFC600 text and adds the ring on hover; Focus outline stays on top;
disabled buttons get no ring. */
.hm-sw-header__home-bg-hover { opacity: 0; }
.hm-sw-header__home:hover .hm-sw-header__home-bg-hover { opacity: 1; }
:is(.hm-sw-header__field, .hm-sw-header__more-trigger, .hm-sw-header__action) { position: relative; }
:is(.hm-sw-header__field, .hm-sw-header__more-trigger, .hm-sw-header__action)::after {
--hm-sw-ring: var(--hm-sw-header-hover-border-width);
content: "";
position: absolute;
/* Bordered buttons: over the 1px border. */
inset: calc(-1 * var(--hm-sw-ring));
padding: var(--hm-sw-ring);
border-radius: inherit;
background: var(--hm-sw-header-hover-border-gradient);
-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;
}
/* Popup guide: the 1px outline is inside its SVG (rect rx 1.5 + 0.5 stroke), so the ring overlays it. */
.hm-sw-header__action--guide { border-radius: 2px; }
.hm-sw-header__action--guide::after { inset: 0; }
:is(.hm-sw-header__field, .hm-sw-header__more-trigger, .hm-sw-header__action):hover:not(:disabled, [data-expanded="true"])::after { opacity: 1; }
/* Selected: text and mono icons turn yellow; no selected background, border or shadow. */
:is(.hm-sw-header, .hm-sw-theme) [data-selected="true"] { color: var(--hm-sw-header-selected-color); }
:is(.hm-sw-header, .hm-sw-theme) [data-selected="true"] .hm-sw-header__arrow { background: var(--hm-sw-header-selected-color); }
/* Layer dropdown — Figma header/menu/레이어 26:10940 (default / hover / Variant3 = expanded), rows
header/dropdown/brown/row 26:10687. Only with `layers`; without them the field above is unchanged.
The list overlays below the field (the header keeps 49px, no field moves). Its brown surface and
orange row hover are this dropdown's own Figma colors and change no other control. */
.hm-sw-header__layer { position: relative; display: flex; flex: 0 1 auto; width: 234px; min-width: 0; }
.hm-sw-header__layer > .hm-sw-header__field--layer { width: 100%; }
/* Variant3: darker field border and square bottom corners where the list joins. */
.hm-sw-header__field--layer[data-expanded="true"] {
border-color: var(--hm-sw-header-layer-expanded-border-color);
border-radius: var(--hm-sw-header-property-radius) var(--hm-sw-header-property-radius) 0 0;
}
.hm-sw-header__layer-menu {
position: absolute;
top: 100%;
left: 0;
z-index: 30;
width: var(--hm-sw-header-layer-menu-width);
max-width: 100cqw;
}
/* Variant3 outline (236 x 320 at -1 / -1): one 1px yellow gradient ring around field + list, drawn
outside both so nothing moves. When the list is shifted to stay on screen it rings the list only. */
.hm-sw-header__layer-menu::before {
content: "";
position: absolute;
z-index: 2;
inset: calc(-1 * var(--hm-sw-header-field-height) - 1px) -1px -1px;
padding: 1px;
border-radius: calc(var(--hm-sw-header-layer-menu-radius) + 1px);
background: var(--hm-sw-header-hover-border-gradient);
-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-header__layer-menu[data-shifted="true"]::before { top: -1px; }
.hm-sw-header__layer-panel {
position: relative;
display: flex;
flex-direction: column;
overflow: hidden;
border-radius: 0 0 var(--hm-sw-header-layer-menu-radius) var(--hm-sw-header-layer-menu-radius);
background: var(--hm-sw-header-layer-menu-background);
box-shadow: var(--hm-sw-header-layer-menu-shadow);
color: var(--hm-sw-header-text-color);
}
/* Figma strokes are inside and outside layout: rows stay 234 x 30 under a 1px black overlay. */
.hm-sw-header__layer-panel::after {
content: "";
position: absolute;
z-index: 1;
inset: 0;
border: 1px solid var(--hm-sw-header-layer-menu-border-color);
border-radius: inherit;
pointer-events: none;
}
.hm-sw-header__layer-list {
margin: 0;
padding: 0;
list-style: none;
max-height: var(--hm-sw-header-layer-list-max-height);
overflow-x: hidden;
overflow-y: auto;
}
/* Row: [bulb snowflake lock] 8 [swatch 16] 8 [name]. Toggles and the selection button are siblings
(no nested buttons): a toggle never selects the row. */
.hm-sw-header__layer-row { display: flex; align-items: center; height: 30px; padding-left: 12px; }
.hm-sw-header__layer-toggles { display: flex; flex: 0 0 auto; }
.hm-sw-header__layer-toggle { position: relative; display: block; flex: 0 0 20px; width: 20px; height: 20px; border-radius: 2px; }
.hm-sw-header__layer-toggle-hover { position: absolute; inset: 0; display: block; width: 20px; height: 20px; opacity: 0; pointer-events: none; }
/* Icon hover (Variant2 / Variant4): bulb black 25% background; snowflake / lock their Figma hover
SVG (the same art over a black 25% tile). Data alone decides colored / gray; hover never toggles. */
button.hm-sw-header__layer-toggle--visibility:hover:not(:disabled) { background: var(--hm-sw-header-layer-icon-hover-background); }
button.hm-sw-header__layer-toggle:hover:not(:disabled) > .hm-sw-header__layer-toggle-hover { opacity: 1; }
/* Figma OFF Default -> OFF Hover: Smart Animate, ease-out 300ms. ON hover is instant. */
button.hm-sw-header__layer-toggle[data-on="false"] { transition: background-color 300ms ease-out; }
button.hm-sw-header__layer-toggle[data-on="false"] > .hm-sw-header__layer-toggle-hover { transition: opacity 300ms ease-out; }
@media (prefers-reduced-motion: reduce) {
button.hm-sw-header__layer-toggle[data-on="false"],
button.hm-sw-header__layer-toggle[data-on="false"] > .hm-sw-header__layer-toggle-hover { transition: none; }
}
.hm-sw-header__layer-item {
display: flex;
align-items: center;
flex: 1 1 auto;
gap: 8px;
min-width: 0;
height: 30px;
padding: 0 12px 0 8px;
text-align: left;
}
/* Figma color chip 16px: black 2px-radius tile, 1px inset swatch with a #C9C9C9 border. */
.hm-sw-header__layer-swatch { position: relative; flex: 0 0 16px; width: 16px; height: 16px; border-radius: 2px; background: #000; }
.hm-sw-header__layer-swatch > span {
position: absolute;
inset: 1px;
border: 1px solid var(--hm-sw-header-layer-chip-border-color);
border-radius: 1px;
}
.hm-sw-header__layer-name {
flex: 1 1 auto;
min-width: 0;
height: 16px;
padding-left: 1px;
overflow: hidden;
font-weight: 700;
line-height: 16px;
letter-spacing: 0.04em;
white-space: nowrap;
text-overflow: ellipsis;
}
/* Row hover (26:10695): brown background, orange name. Size and icon positions stay. */
.hm-sw-header__layer-row:is(:hover, [data-active="true"]):not([data-disabled]) { background: var(--hm-sw-header-layer-row-hover-background); }
.hm-sw-header__layer-row:is(:hover, [data-active="true"]):not([data-disabled]) .hm-sw-header__layer-name { color: var(--hm-sw-header-layer-row-hover-color); }
/* 2026-10-16 additional fix: selected layer rows use the same emphasis as hover (rule above). */
.hm-sw-header__layer-footer {
position: relative;
display: flex;
align-items: center;
justify-content: flex-end;
height: 40px;
padding: 8px 12px;
}
.hm-sw-header__layer-footer::after {
content: "";
position: absolute;
inset: 0;
border: 1px solid var(--hm-sw-header-layer-footer-border-color);
pointer-events: none;
}
/* Shared text-style detail design (26:10789 / 26:10792) for all five footer buttons.
Existing token names and the legacy layer class remain compatible. */
.hm-sw-header__menu-detail {
display: flex;
align-items: center;
gap: 4px;
height: 24px;
padding: 5px 10px;
border-radius: 24px;
background: var(--hm-sw-header-layer-detail-background);
color: var(--hm-sw-header-layer-detail-color);
font-weight: 700;
line-height: 14px;
letter-spacing: 0.02em;
white-space: nowrap;
flex: 0 0 auto;
justify-content: center;
}
.hm-sw-header__menu-detail > img,
.hm-sw-header__detail-icon { display: block; flex: 0 0 14px; width: 14px; height: 14px; }
.hm-sw-header__menu-detail > [data-detail-label] { opacity: var(--hm-sw-header-layer-detail-text-opacity); }
.hm-sw-header__detail-icon { opacity: 0.2; }
/* Explicit disabled states retain the default Figma surface. */
.hm-sw-header__menu-detail:disabled { opacity: 1; }
.hm-sw-header__menu-detail[data-detail="레이어 상세"],
.hm-sw-header__layer-detail { width: 113px; }
.hm-sw-header__menu-detail[data-detail="색상 상세"] { width: 99px; }
.hm-sw-header__menu-detail[data-detail="선스타일 상세"] { width: 128px; }
.hm-sw-header__menu-detail[data-detail="문자스타일 상세"],
.hm-sw-header__menu-detail[data-detail="치수스타일 상세"] { width: 142px; }
.hm-sw-header__menu-detail:hover:not(:disabled) {
background: var(--hm-sw-header-layer-detail-hover-background);
border-radius: 25px;
}
.hm-sw-header__menu-detail:hover:not(:disabled) > img {
content: url("../assets/layer-detail-hover.svg");
}
.hm-sw-header__menu-detail:hover:not(:disabled) > .hm-sw-header__detail-icon { opacity: 0.35; }
/* Field dropdowns (2026-10-16) — color 26:10986 / user colors 26:11036, line style 26:11104,
text style 26:11181, dimension style 26:11215. Only with their data props (`colors`, `lineTypes` /
`lineWeights`, `textStyles`, `dimensionStyles`); without them the plain fields above are unchanged.
Same contract as the layer dropdown: overlay below the field (header keeps 49px, no field moves),
brown surface, black 1px inside stroke, Variant3 field border + yellow ring around field and list.
Latest exceptions restore ByLayer / ByBlock and detail hover. Chips/pick retain their previous
independent-button policy. List rows and inputs retain their Figma hover. */
.hm-sw-header__menu { position: relative; display: flex; flex: 0 0 auto; min-width: 0; }
.hm-sw-header__menu--color { width: 192px; }
.hm-sw-header__menu--line-style { width: 284px; }
.hm-sw-header__menu--text-style,
.hm-sw-header__menu--dimension-style { width: 164px; }
.hm-sw-header__menu > .hm-sw-header__field { width: 100%; }
/* Variant3 (26:11005 / 26:11143 / 26:11200 / 26:11242): darker field border, square bottom corners,
label / value #FFC600 (selected) and the previews in their hover color. */
.hm-sw-header__menu > .hm-sw-header__field[data-expanded="true"] {
border-color: var(--hm-sw-header-layer-expanded-border-color);
border-radius: var(--hm-sw-header-property-radius) var(--hm-sw-header-property-radius) 0 0;
}
.hm-sw-header__field[data-expanded="true"] .hm-sw-header__linetype > i { background: var(--hm-sw-header-selected-color); }
.hm-sw-header__field[data-expanded="true"] .hm-sw-header__dimension-icon-default { visibility: hidden; }
.hm-sw-header__field[data-expanded="true"] .hm-sw-header__dimension-icon-hover { visibility: visible; }
.hm-sw-header__menu-panel {
position: absolute;
top: 100%;
left: 0;
z-index: 30;
display: flex;
flex-direction: column;
max-width: calc(100cqw - 2px);
border-radius: 0 0 var(--hm-sw-header-layer-menu-radius) var(--hm-sw-header-layer-menu-radius);
background: var(--hm-sw-header-layer-menu-background);
color: var(--hm-sw-header-text-color);
}
/* Figma inside stroke as an overlay: rows keep their Figma width. */
.hm-sw-header__menu-panel::after {
content: "";
position: absolute;
z-index: 1;
inset: 0;
border: 1px solid var(--hm-sw-header-layer-menu-border-color);
border-radius: inherit;
pointer-events: none;
}
/* Variant3 ring (#A67D03, 1px around field + list, e.g. 194 x 198 at -1 / -1): the layer dropdown's
gradient ring. Shifted lists (narrow headers) ring the list only. */
.hm-sw-header__menu-panel::before {
content: "";
position: absolute;
z-index: 2;
inset: calc(-1 * var(--hm-sw-header-field-height) - 1px) -1px -1px;
padding: 1px;
border-radius: calc(var(--hm-sw-header-layer-menu-radius) + 1px);
background: var(--hm-sw-header-hover-border-gradient);
-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-header__menu-panel[data-shifted="true"]::before { top: -1px; }
/* Rows: header/dropdown/brown/row (26:10702 line type, 26:10713 / 26:10748 / 26:10755 weight,
26:10718 text style, 26:10729 dimension style). Name 14 / 700, ellipsis; a click never nests. */
.hm-sw-header__menu-list {
margin: 0;
padding: 0;
list-style: none;
max-height: var(--hm-sw-header-menu-list-max-height);
overflow-x: hidden;
overflow-y: auto;
}
.hm-sw-header__menu-row { position: relative; display: flex; align-items: center; height: 30px; }
.hm-sw-header__menu-item {
display: flex;
align-items: center;
flex: 1 1 auto;
gap: 12px;
min-width: 0;
height: 30px;
padding: 0 12px;
text-align: left;
}
.hm-sw-header__menu-text { font-weight: 700; line-height: 16px; letter-spacing: 0.04em; white-space: nowrap; }
.hm-sw-header__menu-name { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.hm-sw-header__menu-value { flex: 0 0 auto; }
/* Figma 38px (Dotum); Noto Sans KR "Arial" is ~42px, so the sample keeps its width up to 56px, then ellipsizes. */
.hm-sw-header__menu-font { flex: 0 1 auto; min-width: 38px; max-width: 56px; overflow: hidden; padding-left: 1px; font-size: 16px; text-overflow: ellipsis; }
.hm-sw-header__menu-dimension { position: relative; flex: 0 0 60px; width: 60px; height: 15px; }
.hm-sw-header__menu-dimension > img { position: absolute; inset: 0; display: block; width: 60px; height: 15px; }
.hm-sw-header__menu-dimension-hover { visibility: hidden; }
/* Line type row (26:10702): 182 x 30, padding 12, gap 8, preview 70 x 2 with a 1px black outside stroke. */
.hm-sw-header__menu-row--line .hm-sw-header__menu-item { gap: 8px; }
.hm-sw-header__line-preview { display: flex; flex: 0 0 70px; gap: 4px; width: 70px; height: 2px; }
.hm-sw-header__line-preview > i {
display: block;
flex: 1 1 0;
min-width: 0;
height: 2px;
background: var(--hm-sw-header-text-color);
box-shadow: 0 0 0 1px var(--hm-sw-header-text-outline-color);
}
/* Weight / scale rows (142 x 30): name left, value or input right. */
.hm-sw-header__menu-row--weight .hm-sw-header__menu-item { justify-content: space-between; }
.hm-sw-header__menu-row--weight .hm-sw-header__menu-item:has(+ .hm-sw-header__input) { padding-right: 8px; }
.hm-sw-header__menu-row > .hm-sw-header__input { flex: 0 0 auto; margin-right: 12px; }
div.hm-sw-header__menu-row { justify-content: space-between; gap: 8px; padding-left: 12px; }
/* Row hover (Figma Variant2): #62533D, text / line / dimension sample #FF5C00. Size and positions stay. */
.hm-sw-header__menu-row:is(:hover, [data-active="true"]):not([data-disabled]) { background: var(--hm-sw-header-layer-row-hover-background); }
.hm-sw-header__menu-row:is(:hover, [data-active="true"]):not([data-disabled]) .hm-sw-header__menu-text { color: var(--hm-sw-header-layer-row-hover-color); }
.hm-sw-header__menu-row:is(:hover, [data-active="true"]):not([data-disabled]) .hm-sw-header__line-preview > i { background: var(--hm-sw-header-layer-row-hover-color); }
.hm-sw-header__menu-row:is(:hover, [data-active="true"]):not([data-disabled]) .hm-sw-header__menu-dimension-default { visibility: hidden; }
.hm-sw-header__menu-row:is(:hover, [data-active="true"]):not([data-disabled]) .hm-sw-header__menu-dimension-hover { visibility: visible; }
/* 2026-10-16 additional fix: selected style rows use the same emphasis as hover (rules above). */
/* Footer (40px, "... 상세" pill). Border / padding / alignment per Figma menu. */
.hm-sw-header__menu-footer {
display: flex;
align-items: center;
justify-content: flex-end;
flex: 0 0 40px;
height: 40px;
padding: 8px 12px;
border-top: 1px solid var(--hm-sw-header-menu-divider-color);
}
.hm-sw-header__line-column--type > .hm-sw-header__menu-footer { padding: 8px; }
.hm-sw-header__list-menu .hm-sw-header__menu-footer { padding: 8px 10px; border-top-color: var(--hm-sw-header-menu-divider-strong-color); }
.hm-sw-header__list-menu--text-style .hm-sw-header__menu-footer { justify-content: flex-start; }
/* Text / dimension style list: 164px (field width), rows 30, footer 40 (Figma body 100px for 2 rows). */
.hm-sw-header__list-menu { width: 164px; }
/* Editable input (Figma input 26:11656): Default 20px tall without surface; Hover 24px with a 1px
rgba(212,203,189,.25) border; editing (focus, 26:11661) #0F0D0A with a .3 border. The text keeps its
place in every state (the border takes 1px of the padding). Its own hover is kept on purpose: it shows
the value can be edited (not one of the independent dropdown buttons). Caret = Figma cursor 26:11664
(1px #E60403, the native caret blinks like its Default / Variant2). Width follows the value. */
.hm-sw-header__input {
flex: 0 0 auto;
width: calc(var(--hm-sw-input-chars, 1) * (1ch + 0.02em) + 12px);
height: 20px;
margin: 0;
padding: 2px 4px 2px 6px;
border: 0;
border-radius: 2px;
outline: none;
background: transparent;
color: var(--hm-sw-header-input-color);
caret-color: var(--hm-sw-header-input-color);
font: inherit;
font-size: var(--hm-sw-header-font-size);
font-weight: 700;
line-height: 16px;
letter-spacing: 0.02em;
}
@supports (field-sizing: content) {
.hm-sw-header__input { field-sizing: content; width: auto; min-width: calc(1ch + 12px); }
}
.hm-sw-header__input:hover:not(:disabled, :read-only),
.hm-sw-header__input:focus:not(:read-only) {
height: 24px;
padding: 3px 3px 3px 5px;
border: 1px solid var(--hm-sw-header-input-hover-border-color);
}
.hm-sw-header__input:focus:not(:read-only) {
border-color: var(--hm-sw-header-input-editing-border-color);
background: var(--hm-sw-header-input-editing-background);
}
/* Read-only inputs: keyboard focus still shows (no editing surface). */
.hm-sw-header__input:read-only:focus-visible { outline: 2px solid var(--hm-sw-header-focus-color); outline-offset: -2px; }
.hm-sw-header__input:disabled { opacity: 0.4; cursor: default; }
.hm-sw-header__input::selection { background: rgba(230, 4, 3, 0.35); }
/* Color dropdown (192 x 158, user colors 192 x 182): 10px top padding and gaps, centered rows. */
.hm-sw-header__color-menu {
align-items: center;
gap: 10px;
width: 192px;
padding-top: 10px;
box-shadow: 0 4px 4px 0 rgba(16, 48, 38, 0.25);
}
.hm-sw-header__color-menu > .hm-sw-header__menu-footer { align-self: stretch; }
/* ByLayer / ByBlock (26:12666 / 26:12659): 82.5 x 28 each in a black 167 x 30 tile (1px padding, radius 4).
Figma inner shadows are drawn over the text, so they are an overlay here too. */
.hm-sw-header__color-modes {
display: flex;
flex: 0 0 auto;
width: 167px;
padding: 1px;
overflow: hidden;
border-radius: 4px;
background: #000;
}
.hm-sw-header__color-mode {
--hm-sw-color-mode-shadow: inset 2px -2px 4px 0 rgba(0, 0, 0, 0.6), inset -5px 2px 4px 0 rgba(0, 0, 0, 0.6);
position: relative;
display: flex;
align-items: center;
justify-content: center;
flex: 0 0 82.5px;
height: 28px;
border-radius: 3px 0 0 3px;
background: var(--hm-sw-header-color-mode-background);
color: var(--hm-sw-header-color-mode-color);
text-align: center;
}
.hm-sw-header__color-mode--block {
--hm-sw-color-mode-shadow: inset -2px -2px 4px 0 rgba(0, 0, 0, 0.6), inset 6px 2px 4px 0 rgba(0, 0, 0, 0.6);
border-radius: 0 3px 3px 0;
}
.hm-sw-header__color-mode::after {
content: "";
position: absolute;
inset: 0;
border-radius: inherit;
box-shadow: var(--hm-sw-color-mode-shadow);
pointer-events: none;
}
/* On (26:12671 / 26:12664): #62533D and raised inner shadows. Hover changes foreground only. */
.hm-sw-header__color-mode[aria-pressed="true"] {
--hm-sw-color-mode-shadow: inset 1px 2px 2px 0 rgba(217, 207, 187, 0.25), inset -1px -2px 2px 0 rgba(0, 0, 0, 0.4);
background: var(--hm-sw-header-color-mode-on-background);
}
.hm-sw-header__color-mode:hover:not(:disabled) { color: var(--hm-sw-header-layer-row-hover-color); }
/* Palette (168 wide): 7 chips spread like Figma; user colors 2px apart, wrapping into 24px rows. */
.hm-sw-header__color-palette {
display: flex;
flex-direction: column;
flex: 0 0 auto;
gap: 2px;
width: 168px;
max-height: var(--hm-sw-header-color-palette-max-height);
overflow-x: hidden;
overflow-y: auto;
}
.hm-sw-header__color-row { display: grid; grid-template-columns: repeat(7, 22px); justify-content: space-between; row-gap: 2px; }
.hm-sw-header__color-row--user { display: flex; flex-wrap: wrap; justify-content: flex-start; gap: 2px; }
.hm-sw-header__color-option { display: block; flex: 0 0 22px; width: 22px; height: 22px; border-radius: 2px; }
/* 22px chip (26:11091): black 20px tile radius 2, 18px swatch with a 1px #C9C9C9 border radius 1. */
.hm-sw-header__color-chip { position: relative; display: block; flex: 0 0 22px; width: 22px; height: 22px; }
.hm-sw-header__color-chip::before { content: ""; position: absolute; inset: 1px; border-radius: 2px; background: #000; }
.hm-sw-header__color-chip > span { position: absolute; inset: 2px; border: 1px solid var(--hm-sw-header-color-chip-border-color); border-radius: 1px; }
.hm-sw-header__color-tools { display: flex; align-items: center; flex: 0 0 auto; gap: 8px; }
/* btn_colorize 26:11302: 24 x 24, brown gradient, black 40% border, radius 3, drop shadow, 18px icon. */
.hm-sw-header__color-pick {
display: grid;
place-items: center;
flex: 0 0 24px;
width: 24px;
height: 24px;
border: 1px solid rgba(0, 0, 0, 0.4);
border-radius: 3px;
background: var(--hm-sw-header-color-pick-background);
filter: drop-shadow(0 2px 2px rgba(0, 0, 0, 0.4));
}
.hm-sw-header__color-pick > img { display: block; width: 18px; height: 18px; }
.hm-sw-header__color-pick { position: relative; }
.hm-sw-header__color-pick > .hm-sw-header__colorize-hover { position: absolute; left: 2px; top: 2px; visibility: hidden; }
.hm-sw-header__color-pick:hover:not(:disabled) {
border-color: #da6813;
background-image: linear-gradient(rgba(0, 0, 0, .25), rgba(0, 0, 0, .25)), var(--hm-sw-header-color-pick-background);
}
.hm-sw-header__color-pick:hover:not(:disabled) > .hm-sw-header__colorize-default { visibility: hidden; }
.hm-sw-header__color-pick:hover:not(:disabled) > .hm-sw-header__colorize-hover { visibility: visible; }
.hm-sw-header__color-pick:disabled { opacity: 1; }
/* Color input (header/menu/색상/input 26:11308): 130 x 26, chip (2px padding) + value. Hover shows the
Figma rgba(197,177,158,.2) border; editing ("rgb 숫자 클릭") makes the value area black. */
.hm-sw-header__color-input {
position: relative;
display: flex;
align-items: center;
flex: 0 0 130px;
width: 130px;
height: 26px;
padding-left: 2px;
border-radius: 2px;
}
.hm-sw-header__color-input::after {
content: "";
position: absolute;
inset: 0;
border: 1px solid transparent;
border-radius: inherit;
pointer-events: none;
}
.hm-sw-header__color-input:is(:hover, :focus-within):has(.hm-sw-header__input:not(:disabled, :read-only))::after { border-color: var(--hm-sw-header-color-input-border-color); }
.hm-sw-header__color-input > .hm-sw-header__color-chip { margin-right: 2px; }
.hm-sw-header__color-input > .hm-sw-header__input,
.hm-sw-header__color-input > .hm-sw-header__input:is(:hover, :focus) {
flex: 1 1 auto;
align-self: stretch;
width: auto;
min-width: 0;
height: auto;
padding: 0 8px;
border: 0;
border-left: 1px solid transparent;
border-radius: 0 2px 2px 0;
background: transparent;
}
.hm-sw-header__color-input:hover > .hm-sw-header__input:not(:disabled, :read-only) { border-left-color: var(--hm-sw-header-color-input-border-color); }
.hm-sw-header__color-input > .hm-sw-header__input:focus {
border-left-color: var(--hm-sw-header-color-input-border-color);
background: #000;
}
/* Line style dropdown (26:11143): 468 x 192 drop_wrap centered under the field (x -92 at 1920), one
row above the field bottom (y 37). The wrap is the yellow ring; the drop inside is 466 x 190 with
the black inside stroke and three columns 182 / 142 / 142 (1px dividers inside the columns). */
.hm-sw-header__line-menu {
top: calc(100% - 1px);
padding: 1px;
border-radius: 0 0 4px 4px;
background: transparent;
box-shadow: 0 4px 8px 0 rgba(16, 48, 38, 0.25);
}
.hm-sw-header__line-menu::before { inset: 0; border-radius: inherit; }
/* Only the horizontal seam touching the field is black. Keep the other three yellow ring edges. */
.hm-sw-header__line-menu::after {
display: block;
z-index: 3;
inset: 0 auto auto var(--hm-sw-line-seam-left);
width: min(var(--hm-sw-line-seam-width), calc(100% - var(--hm-sw-line-seam-left)));
height: 1px;
border: 0;
border-radius: 0;
background: var(--hm-sw-header-layer-menu-border-color);
}
/* The field keeps its yellow ring while the list is open (Figma Rectangle 7530, 286 x 39 at -1 / -1). */
.hm-sw-header__field--line-style[data-expanded="true"]::after { opacity: 1; }
.hm-sw-header__line-drop {
position: relative;
display: flex;
align-items: stretch;
border-radius: 0 0 var(--hm-sw-header-layer-menu-radius) var(--hm-sw-header-layer-menu-radius);
background: var(--hm-sw-header-layer-menu-background);
}
.hm-sw-header__line-drop::after {
content: "";
position: absolute;
z-index: 1;
inset: 0;
border: 1px solid var(--hm-sw-header-layer-menu-border-color);
border-radius: inherit;
pointer-events: none;
}
.hm-sw-header__line-column { position: relative; display: flex; flex-direction: column; flex: 0 0 142px; width: 142px; min-width: 0; }
/* Figma 182px. Noto Sans KR is wider than Dotum ("Continuous" needs ~88px of the 80px name room), so the
column grows with its names up to 240px instead of cutting the most common line type; longer names ellipsize. */
.hm-sw-header__line-column--type { flex: 0 0 auto; width: auto; min-width: 182px; max-width: 240px; }
.hm-sw-header__line-column--type > .hm-sw-header__menu-list { flex: 1 1 auto; }
.hm-sw-header__line-column + .hm-sw-header__line-column::before {
content: "";
position: absolute;
inset: 0 auto 0 0;
width: 1px;
background: var(--hm-sw-header-menu-divider-color);
pointer-events: none;
}
/* 상세보기 / 속성Bar | 속성창 */
.hm-sw-header__properties {
display: flex;
flex-direction: column;
flex: 0 0 157px;
width: 157px;
height: 38px;
margin: 2px -1px 0 auto;
}
.hm-sw-header__properties-caption {
height: 19px;
padding-top: 3px;
font-size: var(--hm-sw-header-label-size);
line-height: 12px;
letter-spacing: 0.02em;
text-align: center;
}
.hm-sw-header__properties-row { display: flex; align-items: center; height: 19px; }
.hm-sw-header__toggle {
flex: 1 1 0;
height: 19px;
border-radius: 2px; /* focus outline shape only */
font-weight: 700;
letter-spacing: 0.04em;
text-align: center;
white-space: nowrap;
}
/* 속성Bar / 속성창 hover (2026-10-16 user decision): text only turns #FFC600; no yellow ring,
border, background or shadow. Selected keeps #FFC600; disabled toggles do not react. */
.hm-sw-header__toggle:hover:not(:disabled) { color: var(--hm-sw-header-selected-color); }
.hm-sw-header__properties-divider {
flex: 0 0 1px;
width: 1px;
height: 12px;
border-radius: 1px;
background: #000;
box-shadow: 1px 0 2px 0 rgba(255, 255, 255, 0.25);
}
/* More (overflow) menu — hidden until the compact tier. */
.hm-sw-header__more { position: relative; display: none; flex: 0 0 auto; margin-left: var(--hm-sw-header-gap); }
.hm-sw-header__more-trigger {
display: grid;
place-items: center;
width: 38px;
height: var(--hm-sw-header-field-height);
border: 1px solid var(--hm-sw-header-property-border-color);
border-radius: var(--hm-sw-header-property-radius);
background: var(--hm-sw-header-property-background);
box-shadow: var(--hm-sw-header-property-shadow);
}
.hm-sw-header__more-trigger[aria-expanded="true"] { color: var(--hm-sw-header-selected-color); }
.hm-sw-header__more-menu {
position: absolute;
top: calc(100% + 6px);
right: 0;
z-index: 30;
display: flex;
flex-direction: column;
min-width: 200px;
max-width: calc(100vw - 16px);
padding: 4px;
border: 1px solid var(--hm-sw-header-object-border-color);
border-radius: var(--hm-sw-header-property-radius);
background: #0e3d2f;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.5);
}
.hm-sw-header__more-item {
display: none;
align-items: center;
justify-content: space-between;
gap: 12px;
min-height: 32px;
padding: 0 10px;
border-radius: 2px;
white-space: nowrap;
}
.hm-sw-header__more-item:hover:not(:disabled) { background: var(--hm-sw-header-hover); }
.hm-sw-header__more-item[role="menuitemcheckbox"]::after { content: ""; width: 14px; text-align: center; }
.hm-sw-header__more-item[aria-checked="true"]::after { content: "✓"; }
.hm-sw-header__more-value { font-size: var(--hm-sw-header-label-size); opacity: 0.8; }
/* Optional title and item icons (SWViewerHeader logo menu, 2026-10-21). The title is rendered only with at least one
item and has no divider (title + items are one group); the `...` menu of SWHeader passes neither and is unchanged. */
.hm-sw-header__more-title {
display: flex;
align-items: center;
min-height: 32px;
padding: 0 10px;
font-weight: 700;
white-space: nowrap;
opacity: 0.8;
}
.hm-sw-header__more-item:has(> .hm-sw-header__more-icon) { justify-content: flex-start; }
.hm-sw-header__more-icon { display: inline-flex; align-items: center; justify-content: center; flex: 0 0 16px; width: 16px; height: 16px; }
.hm-sw-header__more-icon > svg { width: 16px; height: 16px; }
.hm-sw-header__more-item:has(> .hm-sw-header__more-icon) > .hm-sw-header__more-value { margin-left: auto; }
.hm-sw-header__more-menu[data-align="start"] { right: auto; left: 0; }
/* Window area: print / guide pill, window move, minimize, close. */
.hm-sw-header__window {
position: relative;
display: flex;
flex: 0 0 240px;
width: 240px;
height: var(--hm-sw-header-bar-height);
background: var(--hm-sw-header-document-background);
}
.hm-sw-header__window::before {
content: "";
position: absolute;
inset: 0;
border: 1px solid var(--hm-sw-header-document-border-color);
pointer-events: none;
}
.hm-sw-header__actions {
position: relative;
display: flex;
gap: 1px;
flex: 0 0 85px;
height: 42px;
margin: 3px 0 0 3px;
padding: 1px;
border: 1px solid var(--hm-sw-header-pill-border-color);
border-radius: 4px;
background: var(--hm-sw-header-pill-background);
box-shadow: inset 0 2px 2px 0 rgba(0, 0, 0, 0.25);
}
.hm-sw-header__action { position: relative; width: 40px; height: 38px; }
.hm-sw-header__action--print {
border: 1px solid var(--hm-sw-header-property-border-color);
border-radius: 2px;
background: var(--hm-sw-header-document-background);
}
.hm-sw-header__action--print > img { position: absolute; inset: 20.1% 20% 19.62%; width: 60%; height: 60.28%; }
.hm-sw-header__action--guide > img { position: absolute; inset: 0; display: block; width: 40px; height: 38px; }
/* Icon hover variants: the -hover <img> takes the default icon's place in the same box.
인쇄 / 팝업 가이드: only the #B6D0C9 fill becomes #FFC600 (print-hover.svg, popup-guide-hover.svg);
outline, shadow and the guide's gradient tile stay, and the yellow ring above still applies.
종료: Figma hover asset. Disabled buttons keep the default icon. */
.hm-sw-header__icon-hover { visibility: hidden; }
:is(.hm-sw-header__action, .hm-sw-header__window-button):hover:not(:disabled) > .hm-sw-header__icon { visibility: hidden; }
:is(.hm-sw-header__action, .hm-sw-header__window-button):hover:not(:disabled) > .hm-sw-header__icon-hover { visibility: visible; }
.hm-sw-header__motion {
position: relative;
flex: 0 0 88px;
height: var(--hm-sw-header-bar-height);
cursor: move;
background: repeating-linear-gradient(90deg, var(--hm-sw-header-stripe-color) 0 2px, transparent 2px 4px) 3px 6px / 82px 37px no-repeat;
user-select: none;
}
/* Window-move hover motion: ani_hover_move.gif path (41 x 40ms source), sped up to 1.4s.
Motion/timing follow the GIF; the 88 x 48 area, stripes, SVGs and tooltip design remain SW/Figma.
The 192px GIF height is 4x the 48px bar: sampled translations are divided by four,
without using the GIF canvas as a UI asset. Cursor rises first, text appears at 520ms,
then the group moves right/up until 1040ms and holds until the next cycle at 1640ms in the GIF.
All keyframe percentages/positions are unchanged: current text ~444ms, finish ~888ms,
hold ~512ms, repeat 1400ms (1400/1640 of the source time, user-requested speed change).
Leaving :hover resets immediately. All decoration ignores the pointer. */
.hm-sw-header__motion > * { position: absolute; pointer-events: none; }
/* Preserve the original combined Default icon. Hover splits the same art into movable layers. */
.hm-sw-header__motion-icon { left: 28px; top: 13px; width: 32px; height: 30px; }
.hm-sw-header__motion-window { left: 28px; top: 13px; width: 28px; height: 22.8574px; opacity: 0; }
.hm-sw-header__motion-window > img { display: block; width: 28px; height: 22.8574px; max-width: none; }
/* The rotated cursor starts at the combined SVG's lower-right cursor, then rises 12.5px.
Its 0.75px left drift and subsequent +28/-4.5px group travel come from GIF pixel tracks. */
.hm-sw-header__motion-cursor { left: 44.25px; top: 26.25px; width: 15.106px; height: 15.568px; opacity: 0; }
.hm-sw-header__motion-cursor > img { position: absolute; left: 50%; top: 50%; width: 13.0291px; height: 16.7588px; max-width: none; transform: translate(-50%, -50%) rotate(-40deg); }
/* Keep the Figma tooltip's 45 x 17 box/typography. Its glyph gap and travel follow the GIF.
It can overhang the move area onto window buttons, and never takes their clicks. */
.hm-sw-header__motion-tooltip {
z-index: 1;
left: 60.75px;
top: 14.5px;
display: flex;
align-items: center;
justify-content: center;
width: 45px;
height: 17px;
padding: 2px 6px;
border-radius: 2px;
background: var(--hm-sw-header-tooltip-background);
color: var(--hm-sw-header-tooltip-color);
font-family: "Inter", var(--hm-sw-header-font-family);
font-size: var(--hm-sw-header-label-size);
font-weight: 400;
line-height: normal;
white-space: nowrap;
opacity: 0;
}
.hm-sw-header__motion:hover > .hm-sw-header__motion-icon { opacity: 0; }
.hm-sw-header__motion:hover > .hm-sw-header__motion-window { opacity: 1; animation: hm-sw-window-move-window 1.4s linear infinite; }
.hm-sw-header__motion:hover > .hm-sw-header__motion-cursor { opacity: 1; animation: hm-sw-window-move-cursor 1.4s linear infinite; }
.hm-sw-header__motion:hover > .hm-sw-header__motion-tooltip { animation: hm-sw-window-move-tooltip 1.4s linear infinite; }
/* Pause while a pointer is held for dragging. No JS listener, capture or default prevention
is added: the original div/onPointerDown event remains owned by the host. */
.hm-sw-header__motion:active > :is(.hm-sw-header__motion-window, .hm-sw-header__motion-cursor, .hm-sw-header__motion-tooltip) { animation-play-state: paused; }
.hm-sw-header__motion:active > .hm-sw-header__motion-tooltip { visibility: hidden; }
/* Piecewise linear interpolation between the GIF's 40ms samples preserves its acceleration
and deceleration without adding spring overshoot absent from the reference. */
@keyframes hm-sw-window-move-window {
0% { transform: translate(0px, 0px); }
31.707317% { transform: translate(0px, 0px); }
34.146341% { transform: translate(0px, 0px); }
36.585366% { transform: translate(0.75px, -0.25px); }
39.02439% { transform: translate(3.25px, -0.5px); }
41.463415% { transform: translate(5.5px, -1px); }
43.902439% { transform: translate(9.5px, -1.5px); }
46.341463% { transform: translate(12.5px, -2px); }
48.780488% { transform: translate(15.5px, -2.5px); }
51.219512% { transform: translate(19.75px, -3.25px); }
53.658537% { transform: translate(22.5px, -3.75px); }
56.097561% { transform: translate(25.5px, -4.25px); }
58.536585% { transform: translate(27px, -4.5px); }
60.97561% { transform: translate(27.75px, -4.5px); }
63.414634% { transform: translate(28px, -4.5px); }
100% { transform: translate(28px, -4.5px); }
}
@keyframes hm-sw-window-move-cursor {
0% { transform: translate(0px, 0px); }
2.439024% { transform: translate(0px, -0.25px); }
4.878049% { transform: translate(0px, -0.5px); }
7.317073% { transform: translate(0px, -1.75px); }
9.756098% { transform: translate(0px, -2.75px); }
12.195122% { transform: translate(-0.25px, -3.75px); }
14.634146% { transform: translate(-0.25px, -5.5px); }
17.073171% { transform: translate(-0.25px, -6.75px); }
19.512195% { transform: translate(-0.5px, -8.75px); }
21.95122% { transform: translate(-0.5px, -9.75px); }
24.390244% { transform: translate(-0.5px, -10.75px); }
26.829268% { transform: translate(-0.75px, -11.75px); }
29.268293% { transform: translate(-0.75px, -12.25px); }
31.707317% { transform: translate(-0.75px, -12.5px); }
34.146341% { transform: translate(-0.5px, -12.5px); }
36.585366% { transform: translate(0.25px, -12.5px); }
39.02439% { transform: translate(2.5px, -13px); }
41.463415% { transform: translate(4.75px, -13.25px); }
43.902439% { transform: translate(8.75px, -14px); }
46.341463% { transform: translate(11.75px, -14.5px); }
48.780488% { transform: translate(14.75px, -15px); }
51.219512% { transform: translate(19.25px, -15.75px); }
53.658537% { transform: translate(21.75px, -16px); }
56.097561% { transform: translate(25px, -16.5px); }
58.536585% { transform: translate(26.5px, -16.75px); }
60.97561% { transform: translate(27.25px, -17px); }
63.414634% { transform: translate(27.25px, -17px); }
100% { transform: translate(27.25px, -17px); }
}
@keyframes hm-sw-window-move-tooltip {
0% { opacity: 0; transform: none; animation-timing-function: step-end; }
31.707317% { opacity: 1; transform: translate(0px, 0px); animation-timing-function: linear; }
34.146341% { opacity: 1; transform: translate(0.25px, 0px); }
36.585366% { opacity: 1; transform: translate(1px, -0.25px); }
39.02439% { opacity: 1; transform: translate(3.25px, -0.5px); }
41.463415% { opacity: 1; transform: translate(5.5px, -1px); }
43.902439% { opacity: 1; transform: translate(9.5px, -1.5px); }
46.341463% { opacity: 1; transform: translate(12.5px, -2px); }
48.780488% { opacity: 1; transform: translate(15.5px, -2.5px); }
51.219512% { opacity: 1; transform: translate(19.75px, -3.25px); }
53.658537% { opacity: 1; transform: translate(22.5px, -3.5px); }
56.097561% { opacity: 1; transform: translate(25.75px, -4.25px); }
58.536585% { opacity: 1; transform: translate(27.25px, -4.25px); }
60.97561% { opacity: 1; transform: translate(28px, -4.5px); }
63.414634% { opacity: 1; transform: translate(28px, -4.5px); }
100% { opacity: 1; transform: translate(28px, -4.5px); }
}
/* Reduced motion: keep the original icon and static tooltip; no movement or swapping. */
@media (prefers-reduced-motion: reduce) {
.hm-sw-header__motion:hover > :is(
.hm-sw-header__motion-icon,
.hm-sw-header__motion-window,
.hm-sw-header__motion-cursor,
.hm-sw-header__motion-tooltip
) { animation: none; }
.hm-sw-header__motion:hover > .hm-sw-header__motion-icon { opacity: 1; }
.hm-sw-header__motion:hover > :is(.hm-sw-header__motion-window, .hm-sw-header__motion-cursor) { opacity: 0; }
.hm-sw-header__motion:hover > .hm-sw-header__motion-tooltip { opacity: 1; }
}
/* Positioned so the buttons paint above the window ::before border, as in Figma
(Frame 427319960 sits above Rectangle 6669): hover fills cover the full 32 x 48. */
.hm-sw-header__window-buttons { position: relative; display: flex; flex: 0 0 64px; }
.hm-sw-header__window-button { display: grid; place-items: center; width: 32px; height: var(--hm-sw-header-bar-height); }
.hm-sw-header__window-button--minimize > span { display: block; width: 10px; height: 2px; background: var(--hm-sw-header-window-icon-color); }
.hm-sw-header__window-button--close > img { grid-area: 1 / 1; display: block; width: 32px; height: 48px; }
/* Figma hover: 최소화 black 20% + white bar; 종료 swaps to its hover asset (rule above).
No border, shadow, ring or size change. */
.hm-sw-header__window-button--minimize:hover { background: var(--hm-sw-header-window-button-hover-background); }
.hm-sw-header__window-button--minimize:hover > span { background: var(--hm-sw-header-window-icon-hover-color); }
/* Text Stroke (Figma 26:8944 + menus, restored 2026-10-16; replaces the earlier "no outline" choice).
Only text that has the stroke in Figma gets it. Font, size, weight, letter spacing, baseline and
ellipsis are unchanged; hover / selected / row hover change only the fill (outline stays black).
Not in Figma (no stroke): More menu, 창 이동 tooltip. Kept unchanged on request: + New / Open. */
:is(
.hm-sw-header__document-name, .hm-sw-header__mode, .hm-sw-header__field-value, .hm-sw-header__font-name,
.hm-sw-header__toggle, .hm-sw-header__document-item-name, .hm-sw-header__layer-name,
.hm-sw-header__menu-text, .hm-sw-header__input
) {
text-shadow: var(--hm-sw-header-text-outline);
}
:is(.hm-sw-header__field-label, .hm-sw-header__properties-caption) { text-shadow: var(--hm-sw-header-label-outline); }
/* Clipped (ellipsis) text: the outline may paint 2px outside the box instead of being cut. */
:is(
.hm-sw-header__document-name, .hm-sw-header__mode, .hm-sw-header__field-label, .hm-sw-header__field-value,
.hm-sw-header__font-name, .hm-sw-header__document-item-name, .hm-sw-header__layer-name,
.hm-sw-header__menu-name, .hm-sw-header__menu-font
) {
overflow: clip;
overflow-clip-margin: var(--hm-sw-header-text-outline-room);
}
/* Property tool window (26:11822): one data-driven overlay, no dim and no header reflow. */
.hm-sw-property {
position: relative; z-index: 40; display: flex; flex-direction: column;
width: 314px; max-width: calc(100vw - 8px); max-height: calc(100dvh - 8px);
overflow: hidden; border: 1px solid var(--hm-sw-property-border); border-radius: 4px;
background: var(--hm-sw-property-surface); color: var(--hm-sw-property-label);
font-size: 14px; font-weight: 400; line-height: 16px; letter-spacing: .02em;
box-shadow: inset 0 0 0 1px #000;
}
.hm-sw-property__titlebar { position: relative; display: flex; align-items: center; flex: 0 0 30px; height: 30px; background: var(--hm-sw-header-document-background); }
/* Figma paints btn_close first, then Union over its left side. Keep Union's diagonal and shadow
above the close background; the title and tool remain interactive on top of it. */
.hm-sw-property__title-art { position: absolute; z-index: 1; width: 308px; height: 38px; left: 0; top: -2px; transform: scaleY(-1); pointer-events: none; }
.hm-sw-property__title { position: relative; z-index: 2; flex: 1; min-width: 0; margin-left: 7px; padding-right: 4px; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; font-weight: 700; letter-spacing: .04em; color: var(--hm-sw-header-selected-color); text-shadow: var(--hm-sw-header-label-outline); }
.hm-sw-property__tool { position: absolute; z-index: 2; right: 43px; top: 1px; width: 29px; height: 27.13px; }
.hm-sw-property:not([data-selection-kind="single"]) .hm-sw-property__title { margin-right: 29px; }
.hm-sw-property__tool > img { position: absolute; top: 0; left: 0; display: block; width: 29px; height: 27.13px; }
.hm-sw-property__tool-hover { visibility: hidden; }
.hm-sw-property__tool:hover > .hm-sw-property__tool-default { visibility: hidden; }
.hm-sw-property__tool:hover > .hm-sw-property__tool-hover { visibility: visible; }
.hm-sw-property__close { position: relative; flex: 0 0 44px; width: 44px; height: 30px; }
.hm-sw-property__close > img { position: absolute; inset: 0; display: block; width: 44px; height: 30px; }
.hm-sw-property__close-hover { visibility: hidden; }
.hm-sw-property__close:hover > .hm-sw-property__close-default { visibility: hidden; }
.hm-sw-property__close:hover > .hm-sw-property__close-hover { visibility: visible; }
.hm-sw-property__body { display: flex; flex-direction: column; gap: 8px; min-height: 0; overflow-y: auto; overscroll-behavior: contain; padding: 7px 7px 7px; box-shadow: inset 0 2px 2px rgba(255,255,255,.6); }
/* Popup scrollbar: the body and any scrolling area inside it (zero-specificity so content can still override). */
.hm-sw-property__body, .hm-sw-property__body :where(*) { scrollbar-width: thin; scrollbar-color: var(--hm-sw-popup-scrollbar-thumb) var(--hm-sw-popup-scrollbar-track); }
.hm-sw-property[data-selection-kind="all"] .hm-sw-property__body { padding-bottom: 0; }
.hm-sw-property[data-selection-kind="all"] .hm-sw-property__counts { margin-top: -8px; }
.hm-sw-property__group { flex: 0 0 auto; }
.hm-sw-property__group > h3 { margin: 0 0 4px; font: inherit; font-weight: 700; color: rgba(0,0,0,.7); }
.hm-sw-property__group--rows > .hm-sw-property__group-content { border: 1px solid #585349; border-radius: 4px; padding: 2px; background: var(--hm-sw-property-content); box-shadow: 0 2px 2px rgba(255,255,255,.6), inset 0 2px 4px #e1cfab, inset 0 -2px 2px rgba(104,95,76,.8); }
.hm-sw-property__row { display: flex; align-items: center; gap: 8px; min-height: 32px; padding: 0 6px; }
.hm-sw-property__row > label { flex: 0 0 72px; min-width: 0; font-weight: 700; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.hm-sw-property__value { display: flex; align-items: center; gap: 4px; flex: 1; min-width: 0; }
.hm-sw-property__value > .hm-sw-header__input { width: auto; max-width: 100%; min-width: 0; flex: 1; text-shadow: none; letter-spacing: .02em; font-weight: 500; }
.hm-sw-property__value > .hm-sw-header__input:focus { color: var(--hm-sw-header-input-color); }
.hm-sw-property__value > select:not(.hm-sw-select) { flex: 1; min-width: 0; width: 0; height: 28px; padding: 0; appearance: none; border: 1px solid transparent; border-radius: 2px; background: transparent; color: var(--hm-sw-header-input-color); font: inherit; }
.hm-sw-property__value > select:not(.hm-sw-select):disabled { opacity: 1; appearance: none; color: var(--hm-sw-header-input-color); }
.hm-sw-property__value > select:not(.hm-sw-select):focus { background: var(--hm-sw-property-content); border-color: var(--hm-sw-property-inner-border); }
/* SWSelect: native select, panel field look; focus = the SW popup focus ring. */
.hm-sw-select { flex: 0 0 auto; height: 28px; padding: 0 8px; border: 1px solid var(--hm-sw-select-border-color); border-radius: 4px; background: var(--hm-sw-select-background); color: var(--hm-sw-select-text); font: inherit; font-size: 12px; }
.hm-sw-select:disabled { opacity: 0.4; cursor: default; }
/* 2026-10-21: in an SW popup the chosen value of an enabled select is editable, so it is red like every editable value;
a disabled select and the option list keep --hm-sw-select-text. The viewer panels keep their own text color (sw-viewer.css). */
.hm-sw-property .hm-sw-select:not(:disabled) { color: var(--hm-sw-header-input-color); }
.hm-sw-property .hm-sw-select option { color: var(--hm-sw-select-text); }
.hm-sw-property__unit { flex: 0 0 auto; font-size: 12px; white-space: nowrap; }
/* Color preview (26:12175): 70 x 16 black tile (1px padding, radius 2), 68 x 14 swatch with a white 1px border. */
.hm-sw-property__swatch-area { display: flex; align-items: center; flex: 0 0 auto; }
.hm-sw-property__swatch { display: block; flex: 0 0 70px; width: 70px; height: 16px; padding: 1px; border-radius: 2px; background: #000; }
.hm-sw-property__swatch > i { display: block; height: 14px; border: 1px solid #fff; border-radius: 1px; }
/* Property window gauge, also SWSlider appearance="property" (2026-10-20, same rules; the 86px width is the property row only). */
.hm-sw-property__value > input[type="range"]:not(.hm-sw-slider) { flex: 0 0 86px; width: 86px; }
:is(.hm-sw-property__value > input[type="range"]:not(.hm-sw-slider), .hm-sw-slider[data-appearance="property"]) { appearance: none; height: 16px; margin: 0; background: transparent; cursor: pointer; }
/* --hm-sw-range-fill (0-1) is set from the value; the red ends under the thumb centre (14px thumb).
The 3px radius rounds the fill's left cap; the first layer is its left stroke. Track and thumb are
shared values, painted once per engine: WebKit/Blink track + thumb, Gecko track + thumb (Gecko's
::-moz-range-progress is kept empty so the fill is never painted twice). */
:is(.hm-sw-property__value > input[type="range"]:not(.hm-sw-slider), .hm-sw-slider[data-appearance="property"]) {
--hm-sw-range-fill-width: calc(7px + (100% - 14px) * var(--hm-sw-range-fill, 0));
--hm-sw-range-track-paint:
linear-gradient(90deg, var(--hm-sw-property-range-fill-edge) 0 1px, transparent 1px) 0 0 / var(--hm-sw-range-fill-width) 100% no-repeat,
var(--hm-sw-property-range-fill) 0 0 / var(--hm-sw-range-fill-width) 100% no-repeat,
var(--hm-sw-property-range-track);
--hm-sw-range-thumb-paint: url("../assets/property-range-thumb.svg") center / 14px 14px no-repeat;
--hm-sw-range-thumb-shadow: 0 0 3px #1c1a16, 0 2px 2px rgba(28, 26, 22, .4);
}
:is(.hm-sw-property__value > input[type="range"]:not(.hm-sw-slider), .hm-sw-slider[data-appearance="property"])::-webkit-slider-runnable-track { height: 6px; border-radius: 3px; background: var(--hm-sw-range-track-paint); box-shadow: 0 1px 0 var(--hm-sw-property-range-highlight); }
:is(.hm-sw-property__value > input[type="range"]:not(.hm-sw-slider), .hm-sw-slider[data-appearance="property"])::-webkit-slider-thumb { appearance: none; width: 14px; height: 14px; margin-top: -4px; border: 0; border-radius: 50%; background: var(--hm-sw-range-thumb-paint); box-shadow: var(--hm-sw-range-thumb-shadow); }
:is(.hm-sw-property__value > input[type="range"]:not(.hm-sw-slider), .hm-sw-slider[data-appearance="property"])::-moz-range-track { box-sizing: border-box; height: 6px; border: 0; border-radius: 3px; background: var(--hm-sw-range-track-paint); box-shadow: 0 1px 0 var(--hm-sw-property-range-highlight); }
:is(.hm-sw-property__value > input[type="range"]:not(.hm-sw-slider), .hm-sw-slider[data-appearance="property"])::-moz-range-progress { height: 0; background: transparent; }
:is(.hm-sw-property__value > input[type="range"]:not(.hm-sw-slider), .hm-sw-slider[data-appearance="property"])::-moz-range-thumb { box-sizing: border-box; width: 14px; height: 14px; border: 0; border-radius: 50%; background: var(--hm-sw-range-thumb-paint); box-shadow: var(--hm-sw-range-thumb-shadow); }
/* SWSlider (2026-10-20): one native range, two looks. Fills the row by default (the host may set a width).
appearance="panel" is the gauge the SW popup used (also SWViewerSlider): the range is painted up to
--hm-sw-range-fill of the track. */
.hm-sw-slider { flex: 1 1 auto; width: 100%; min-width: 0; }
.hm-sw-slider:disabled { opacity: 0.4; cursor: default; }
.hm-sw-slider[data-appearance="panel"] {
--hm-sw-slider-percent: calc(var(--hm-sw-range-fill, 0) * 100%);
height: 18px;
margin: 0;
background: transparent;
appearance: none;
cursor: pointer;
}
.hm-sw-slider[data-appearance="panel"]:disabled { cursor: default; }
.hm-sw-slider[data-appearance="panel"]::-webkit-slider-runnable-track { height: 6px; border-radius: 9999px; background: linear-gradient(90deg, var(--hm-sw-slider-panel-range) var(--hm-sw-slider-percent), var(--hm-sw-slider-panel-track) var(--hm-sw-slider-percent)); }
.hm-sw-slider[data-appearance="panel"]::-moz-range-track { height: 6px; border-radius: 9999px; background: var(--hm-sw-slider-panel-track); }
.hm-sw-slider[data-appearance="panel"]::-moz-range-progress { height: 6px; border-radius: 9999px; background: var(--hm-sw-slider-panel-range); }
.hm-sw-slider[data-appearance="panel"]::-webkit-slider-thumb { width: 18px; height: 18px; margin-top: -6px; border: 2px solid var(--hm-sw-slider-panel-range); border-radius: 9999px; background: var(--hm-sw-slider-panel-thumb); appearance: none; }
.hm-sw-slider[data-appearance="panel"]::-moz-range-thumb { box-sizing: border-box; width: 18px; height: 18px; border: 2px solid var(--hm-sw-slider-panel-range); border-radius: 9999px; background: var(--hm-sw-slider-panel-thumb); }
.hm-sw-slider[data-appearance="panel"]:focus-visible { outline: 2px solid var(--hm-sw-slider-panel-range); outline-offset: 2px; }
.hm-sw-property__value > .hm-sw-header__line-preview { flex-basis: 68px; width: 68px; }
.hm-sw-property__expand { display: block; width: 100%; height: 12px; overflow: hidden; }
.hm-sw-property__expand > img { display: block; width: 296px; height: 12px; margin-left: calc((100% - 296px) / 2); }
.hm-sw-property__expand[aria-expanded="true"] > img { transform: rotate(180deg); }
.hm-sw-property__counts { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); }
.hm-sw-property__counts > span { min-height: 28px; padding: 5px 0; border-bottom: 1px solid rgba(0,0,0,.5); font-weight: 700; }
/* 2026-10-21 design review: each object type entry (원 1, 폴리선 10 …) changes its own text color on Hover, with the
SW row accent #FF5C00 (the header list row hover color). Display only: no click, selection or filter. */
.hm-sw-property__counts > span:hover { color: var(--hm-sw-header-layer-row-hover-color); }
/* 2026-10-21 user request: Popup items whose color changes on Hover show the pointer (display-only entries too: no
click is added). Inputs and read-only values keep their own cursor. */
:is(.hm-sw-property__tool, .hm-sw-property__close, .hm-sw-property__expand, .hm-sw-property__counts > span) { cursor: pointer; }
.hm-sw-property__group--circle .hm-sw-property__group-content { position: relative; min-height: 260px; }
.hm-sw-property__group--circle .hm-sw-property__editors { position: relative; min-height: 260px; padding-top: 260px; }
/* Shape slot (Figma 26:11932 / 26:12035): 208 x 208 at (39, 26) of the 260px shape group. Default content is
the Figma circle; host content is fitted inside and never moves the value labels drawn above it. */
.hm-sw-property__shape { position: absolute; left: 39px; top: 26px; display: grid; place-items: center; width: 208px; height: 208px; overflow: hidden; }
.hm-sw-property__shape > * { max-width: 100%; max-height: 100%; }
.hm-sw-property__circle { display: block; width: 208px; height: 208px; }
.hm-sw-property__group--circle .hm-sw-property__editor { position: absolute; }
.hm-sw-property__group--circle .hm-sw-property__row { padding: 0; min-height: 24px; gap: 4px; }
.hm-sw-property__group--circle .hm-sw-property__row > label { flex-basis: auto; }
/* 2026-10-21 user request: 원주 / 지름 / 반지름 / 면적 = [Input] — a text "=" after the name, outside the input. */
.hm-sw-property__editor[data-slot] .hm-sw-property__row > label::after { content: " =" / ""; }
.hm-sw-property__group--circle .hm-sw-property__value { flex: 0 1 auto; }
.hm-sw-property__group--circle .hm-sw-header__input { width: calc(var(--hm-sw-input-chars) * 1ch + 8px); flex: 0 1 auto; }
.hm-sw-property__editor[data-slot="circumference"] { left: 113px; top: 0; }
.hm-sw-property__editor[data-slot="diameter"] { left: 100px; top: 110px; }
.hm-sw-property__editor[data-slot="radius"] { left: 154px; top: 161px; background: rgba(228,219,201,.6); }
.hm-sw-property__editor[data-slot="area"] { left: 100px; top: 236px; }
.hm-sw-property__group--circle .hm-sw-property__editor:not([data-slot]) { position: relative; }
.hm-sw-property__group--position { margin-top: 8px; }
.hm-sw-property__group--position .hm-sw-property__group-content { margin: 0 4px; }
.hm-sw-property__position-head, .hm-sw-property__group--position .hm-sw-property__editors { display: grid; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); }
.hm-sw-property__position-head { background: var(--hm-sw-property-table); border-top: 1px solid rgba(0,0,0,.4); }
.hm-sw-property__position-head > span, .hm-sw-property__position-label { min-height: 24px; padding: 3px 0; text-align: center; font-weight: 700; border-bottom: 1px solid rgba(0,0,0,.4); }
.hm-sw-property__position-head > span + span, .hm-sw-property__group--position .hm-sw-property__editor { border-left: 1px solid rgba(0,0,0,.4); }
.hm-sw-property__position-label { background: var(--hm-sw-property-table); }
.hm-sw-property__group--position .hm-sw-property__row { padding: 0; gap: 0; min-height: 24px; }
.hm-sw-property__group--position label { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }
.hm-sw-property__group--position .hm-sw-header__input { padding: 0; width: 100%; height: 24px; text-align: center; }
.hm-sw-property__group--position .hm-sw-property__editor { border-bottom: 1px solid rgba(0,0,0,.4); }
.hm-sw-property__overview { position: relative; flex: 0 0 28px; height: 28px; text-align: left; overflow: hidden; }
.hm-sw-property__overview > img { position: absolute; left: -3px; top: -2px; width: 317px; height: 36.0847px; transform: scaleY(-1); }
.hm-sw-property__overview > span { position: relative; display: block; padding: 6px 7px; color: var(--hm-sw-header-selected-color); text-shadow: var(--hm-sw-header-label-outline); font-weight: 700; }
.hm-sw-property__overview:disabled { opacity: 1; }
.hm-sw-property__row[data-disabled="true"] { opacity: .4; }
.hm-sw-property button:focus-visible, .hm-sw-property input:focus-visible, .hm-sw-property select:focus-visible { outline: 2px solid var(--hm-sw-property-border); outline-offset: -2px; }
/* Property fields (2026-10-19, Figma 26:12170 ~ 26:12649). Common rows only; the circle / position groups keep
their layout. Box: 28px, radius 2, a transparent 1px border so Hover / On never move the value (8px inset as
in Default). Default: value only. Hover: rgba(33,29,19,.4) border, values / units / previews unchanged.
On (editing, numbers 26:12323 / 26:12599 / 26:12656): #0F0D0A, black text outline, unit #FFF, red caret.
On (dropdown 26:12265 / 26:12291 / 26:12404 / 26:12184): #211D13, outlined value, unit #D4CBBD.
Text and computed values (26:12583 / 26:12574) have no Figma On: only Default / Hover. */
.hm-sw-property__group--rows .hm-sw-property__value[data-field] {
position: relative;
height: 28px;
border: 1px solid transparent;
border-radius: 2px;
justify-content: space-between;
}
.hm-sw-property__group--rows .hm-sw-property__value[data-field="box"] { padding: 0 7px; }
.hm-sw-property__group--rows .hm-sw-property__value[data-field="picker"] { padding: 0; }
.hm-sw-property__group--rows .hm-sw-property__row:not([data-disabled]) > .hm-sw-property__value[data-field]:is(:hover, [data-open="true"], :not([data-readonly]):focus-within) {
border-color: var(--hm-sw-property-field-hover-border-color);
}
.hm-sw-property__group--rows .hm-sw-property__value[data-field] .hm-sw-header__input,
.hm-sw-property__group--rows .hm-sw-property__value[data-field] .hm-sw-header__input:is(:hover, :focus) {
flex: 1 1 auto;
align-self: stretch;
width: auto;
min-width: 0;
height: auto;
padding: 0;
border: 0;
border-radius: 0;
background: transparent;
font-weight: 500;
letter-spacing: 0.02em;
text-shadow: none;
}
/* The box shows the editing state; read-only values keep the keyboard focus ring. */
.hm-sw-property__group--rows .hm-sw-property__value[data-field] .hm-sw-header__input:not(:read-only):focus-visible { outline: none; }
.hm-sw-property__group--rows .hm-sw-property__value[data-on="edit"]:focus-within { background: var(--hm-sw-property-field-editing-background); }
.hm-sw-property__group--rows .hm-sw-property__value[data-on="edit"]:focus-within > .hm-sw-header__input { text-shadow: var(--hm-sw-header-text-outline); }
.hm-sw-property__group--rows .hm-sw-property__value[data-on="edit"]:focus-within > .hm-sw-property__unit { color: var(--hm-sw-property-field-editing-unit-color); }
/* 41px hug field (26:12649: 선가중치 / 투명도 value): pl 6, pr 4, the input itself is the box. */
.hm-sw-property__group--rows .hm-sw-property__value > .hm-sw-header__input.hm-sw-property__compact,
.hm-sw-property__group--rows .hm-sw-property__value > .hm-sw-header__input.hm-sw-property__compact:is(:hover, :focus) {
flex: 0 0 auto;
width: calc(var(--hm-sw-input-chars, 1) * (1ch + 0.02em) + 10px);
height: 28px;
padding: 0 3px 0 5px;
border: 1px solid transparent;
border-radius: 2px;
background: transparent;
}
@supports (field-sizing: content) {
.hm-sw-property__group--rows .hm-sw-property__value > .hm-sw-header__input.hm-sw-property__compact { width: auto; min-width: calc(1ch + 10px); }
}
.hm-sw-property__group--rows .hm-sw-property__row:not([data-disabled]) .hm-sw-header__input.hm-sw-property__compact:is(:hover, :focus:not(:read-only)) { border-color: var(--hm-sw-property-field-hover-border-color); }
.hm-sw-property__group--rows .hm-sw-property__value > .hm-sw-header__input.hm-sw-property__compact:focus:not(:read-only) {
outline: none;
background: var(--hm-sw-property-field-editing-background);
text-shadow: var(--hm-sw-header-text-outline);
}
/* Slider value box (2026-10-21, 투명도): value + annotation in one field that fills the room before the gauge; the
same Default / Hover / On (#0F0D0A, white annotation) as the number box. */
.hm-sw-property__slider-value {
position: relative;
display: flex;
align-items: center;
justify-content: space-between;
gap: 4px;
flex: 1 1 auto;
min-width: 0;
height: 28px;
padding: 0 7px;
border: 1px solid transparent;
border-radius: 2px;
}
.hm-sw-property__row:not([data-disabled]) .hm-sw-property__slider-value:is(:hover, :not([data-readonly]):focus-within) { border-color: var(--hm-sw-property-field-hover-border-color); }
.hm-sw-property__slider-value > .hm-sw-header__input,
.hm-sw-property__slider-value > .hm-sw-header__input:is(:hover, :focus) {
flex: 1 1 auto;
align-self: stretch;
width: auto;
min-width: 0;
height: auto;
padding: 0;
border: 0;
border-radius: 0;
background: transparent;
font-weight: 500;
letter-spacing: 0.02em;
text-shadow: none;
}
.hm-sw-property__slider-value > .hm-sw-header__input:not(:read-only):focus-visible { outline: none; }
.hm-sw-property__slider-value[data-on="edit"]:focus-within { background: var(--hm-sw-property-field-editing-background); }
.hm-sw-property__slider-value[data-on="edit"]:focus-within > .hm-sw-header__input { text-shadow: var(--hm-sw-header-text-outline); }
.hm-sw-property__slider-value[data-on="edit"]:focus-within > .hm-sw-property__unit { color: var(--hm-sw-property-field-editing-unit-color); }
/* Value color rule (2026-10-21): red (#E60403) marks an editable value only. A read-only, computed or disabled value
is the black label color of the light popup; a disabled row also keeps its 40%. */
:is(.hm-sw-property__value, .hm-sw-property__slider-value)[data-readonly] :is(.hm-sw-header__input, .hm-sw-property__trigger, select:not(.hm-sw-select)) { color: var(--hm-sw-property-label); }
/* Dropdown fields: layer (pl/pr 8), line style (pl 8, pr 6: value + (ByL) + pattern), color (RGB | swatch). */
.hm-sw-property__trigger {
display: flex;
align-items: center;
justify-content: space-between;
gap: 4px;
flex: 1 1 auto;
align-self: stretch;
min-width: 0;
padding: 0 7px;
color: var(--hm-sw-header-input-color);
text-align: left;
letter-spacing: 0.02em;
}
.hm-sw-property__value[data-picker="lineStyle"] > .hm-sw-property__trigger { padding-right: 5px; }
.hm-sw-property__value[data-readonly] > .hm-sw-property__trigger,
.hm-sw-property__trigger:disabled { cursor: default; opacity: 1; }
.hm-sw-property__trigger-text { display: flex; align-items: center; gap: 4px; min-width: 0; }
.hm-sw-property__text { min-width: 0; overflow: clip; overflow-clip-margin: var(--hm-sw-header-text-outline-room); white-space: nowrap; text-overflow: ellipsis; font-weight: 500; }
.hm-sw-property__trigger .hm-sw-property__unit { color: var(--hm-sw-property-label); }
/* Figma 68px (Dotum). Noto Sans KR needs more room for "Continuous (ByL)": the preview gives way first (Figma On draws it at 50px), then the name ellipsizes. */
.hm-sw-property__trigger > .hm-sw-header__line-preview { flex: 0 1 68px; width: 68px; min-width: 40px; }
.hm-sw-property__value[data-picker="lineStyle"] .hm-sw-property__trigger-text { flex-shrink: 0; max-width: calc(100% - 44px); }
.hm-sw-property__value[data-field="picker"][data-open="true"]:not([data-picker="color"]),
.hm-sw-property__value[data-picker="color"][data-open="true"] > .hm-sw-property__color-value { background: var(--hm-sw-property-field-open-background); }
.hm-sw-property__group--rows .hm-sw-property__value[data-field][data-open="true"] :is(.hm-sw-property__text, .hm-sw-header__input) { text-shadow: var(--hm-sw-header-text-outline); }
.hm-sw-property__value[data-open="true"] .hm-sw-property__trigger .hm-sw-property__unit { color: var(--hm-sw-property-field-open-unit-color); }
.hm-sw-property__color-value { display: flex; align-items: center; flex: 1 1 auto; align-self: stretch; min-width: 0; padding: 0 7px; border-right: 1px solid transparent; }
.hm-sw-property__value[data-field] > .hm-sw-property__swatch-area { align-self: stretch; padding: 0 5px; }
.hm-sw-property__value[data-field="box"] > .hm-sw-property__swatch-area { padding-right: 0; }
.hm-sw-property__value[data-picker="color"]:not([data-readonly]) > .hm-sw-property__swatch-area { cursor: pointer; }
.hm-sw-property__group--rows .hm-sw-property__row:not([data-disabled]) > .hm-sw-property__value[data-picker="color"]:is(:hover, [data-open="true"]) > .hm-sw-property__color-value {
border-right-color: var(--hm-sw-property-field-hover-border-color);
}
/* The shared header dropdown contents in a fixed overlay (escapes the scrolling body). No yellow ring:
the property Figma dropdowns have the black stroke and the brown surface only. */
.hm-sw-property__drop { position: fixed; z-index: 50; top: 0; left: 0; color: var(--hm-sw-header-text-color); text-align: left; }
.hm-sw-property__drop[data-picker="layer"] { width: var(--hm-sw-header-layer-menu-width); }
.hm-sw-property__drop.hm-sw-header__menu-panel { position: fixed; max-width: none; }
.hm-sw-property__drop.hm-sw-header__menu-panel::before { display: none; }
/* K guide 26:11698 / 26:11669: original image, fixed mask viewport and continuous pan/zoom. */
.hm-sw-k-guide { position: relative; flex: 0 0 40px; height: 38px; }
.hm-sw-k-guide__panel { z-index: 45; height: 149px; min-height: 149px; overflow: hidden; border: 1px solid var(--hm-sw-property-border); border-radius: 2px; background: #0e3c2e; animation: hm-sw-k-guide-enter 511ms ease-out; }
.hm-sw-k-guide__viewport { position: absolute; top: 6px; left: 6px; width: 192px; height: 109px; mask-size: 192px 109px; mask-repeat: no-repeat; outline: 1px solid #000; }
.hm-sw-k-guide__viewport > img { display: block; max-width: none; width: 456px; height: 256.5px; transform-origin: 0 0; transform: translate(0, 0) scale(1); transition-property: transform; transition-timing-function: ease-in-out; }
.hm-sw-k-guide__panel[data-frame="2"] .hm-sw-k-guide__viewport > img { transform: translate(0, -40.738px) scale(1); }
.hm-sw-k-guide__panel[data-frame="3"] .hm-sw-k-guide__viewport > img { transform: translate(-260px, -8.479px) scale(1, .99805); }
.hm-sw-k-guide__panel[data-frame="4"] .hm-sw-k-guide__viewport > img { transform: translate(0, 0) scale(.42105263, .42495127); }
.hm-sw-k-guide__panel > span { position: absolute; top: 123px; left: 7px; color: var(--hm-sw-header-text-color); text-shadow: var(--hm-sw-header-label-outline); font-weight: 700; line-height: 16px; letter-spacing: .04em; }
.hm-sw-k-guide[data-open="true"] .hm-sw-header__icon { visibility: hidden; }
.hm-sw-k-guide[data-open="true"] .hm-sw-header__icon-hover { visibility: visible; }
@keyframes hm-sw-k-guide-enter { from { opacity: 0; } to { opacity: 1; } }
@media (prefers-reduced-motion: reduce) {
.hm-sw-k-guide__panel { animation: none; }
.hm-sw-k-guide__viewport > img { transition: none; }
}
/* Responsive — header width (container query); the header never scrolls horizontally.
From 760px up (2026-10-21 user decision; the SW Footer story widths) nothing moves into More: the five menus 레이어 · 색상 · 선스타일 ·
문자스타일 · 치수스타일 always stay in the header with their titles, and the More button is not shown. As it narrows:
>= 1800 Figma layout. 1920 -> 1800 only the file name shrinks (310 -> 190).
< 1800 the 그리기모드 text hides, the line-type / dimension pictures hide and the color chip is 24px (fields take
their content width); the file name gives way first (down to 96px, ellipsis), then the field values
shrink with an ellipsis, each by its own width.
< 1080 window move area 88 -> 24 (window 240 -> 176); layer-state icons, the color chip and the 문자스타일
font name hide, field insets 6px.
<= 900 the 선스타일 field shows 선스타일 only (가중치 / 스케일 hide).
Below 760px (phones, e.g. 390) the former tiers are unchanged: parts move into More (선/문자/치수 스타일, 그리기모드,
속성Bar/속성창, 색상, then 인쇄/팝업 가이드 below 640), and below 520 the layer-state icons hide.
Each field keeps its button, title, value, dropdown and hover / focus box. cqw = header width.
Hiding targets the flex item of each field ([data-menu] / [data-tier] on the field button, or on the wrapper of a
field with a dropdown), so a dropdown field hides like a plain one. */
.hm-sw-header__document { flex: 0 0 clamp(190px, calc(100cqw - 1610px - var(--hm-sw-header-leading-width, 0px)), 310px); min-width: 0; }
.hm-sw-header__field--layer { flex-shrink: 1; }
.hm-sw-header__field:not(.hm-sw-header__field--layer) { flex-shrink: 0; }
@container hm-sw-header (min-width: 760px) and (max-width: 1799.98px) {
.hm-sw-header__mode { display: none; }
.hm-sw-header__fields { padding-left: 4px; }
/* Content width (no Figma box) that may shrink: the free room is taken from each value by its own width. */
.hm-sw-header__fields > :is(.hm-sw-header__layer, .hm-sw-header__menu),
.hm-sw-header__fields > .hm-sw-header__control > :is(.hm-sw-header__layer, .hm-sw-header__menu) { flex: 0 1 auto; width: auto; min-width: 0; }
.hm-sw-header__fields .hm-sw-header__field { flex: 0 1 auto; width: auto; min-width: 0; }
/* Fixed-size buttons in a configured bar (인쇄 · K) keep their box: only the fields give way. */
.hm-sw-header__fields > .hm-sw-header__control:is([data-control="print"], [data-control="popupGuide"]) { flex-shrink: 0; }
.hm-sw-header__layer > .hm-sw-header__field--layer { width: 100%; }
.hm-sw-header__field :is(.hm-sw-header__line-values, .hm-sw-header__font-name) { min-width: 0; }
/* Tighter fields: smaller insets, a 24px color chip, no line-type / dimension pictures (the value names stay). */
.hm-sw-header__fields .hm-sw-header__field { padding: 0 8px; gap: 8px; }
.hm-sw-header__fields .hm-sw-header__chip { flex-basis: 24px; width: 24px; }
.hm-sw-header__fields :is(.hm-sw-header__linetype, .hm-sw-header__dimension-icon) { display: none; }
.hm-sw-header__fields .hm-sw-header__line-values { gap: 8px; }
/* Open dropdown (2026-10-21 user request): the fields are narrower than their lists here, so the yellow ring stays
inside each button and the list gets its own ring, as a shifted list (치수스타일) already does. */
.hm-sw-header__fields :is(.hm-sw-header__layer-menu, .hm-sw-header__menu-panel:not(.hm-sw-header__line-menu))::before { top: -1px; }
.hm-sw-header__fields .hm-sw-header__field[data-expanded="true"]::after { opacity: 1; }
/* Where the list meets the button the seam is black across the button width (as the 선스타일 seam). */
.hm-sw-header__fields :is(.hm-sw-header__layer, .hm-sw-header__menu:not(.hm-sw-header__menu--line-style)):has(> .hm-sw-header__field[data-expanded="true"])::after {
content: "";
position: absolute;
z-index: 31;
top: calc(100% - 1px);
left: 0;
right: 0;
height: 2px;
background: var(--hm-sw-header-layer-menu-border-color);
pointer-events: none;
}
/* 1610 - 1301 + the tighter object area with titles, without 그리기모드 (891, measured) = 1200. */
.hm-sw-header__document { flex-basis: clamp(96px, calc(100cqw - 1200px - var(--hm-sw-header-leading-width, 0px)), 310px); }
}
@container hm-sw-header (min-width: 760px) and (max-width: 1079.98px) {
/* Values need the room (1024px, 2026-10-21 user request): the layer-state icons, the color chip and the font name
beside 문자스타일 hide, insets 6px, every value part may shrink (ellipsis). */
.hm-sw-header__fields .hm-sw-header__field { padding: 0 6px; gap: 6px; }
.hm-sw-header__fields :is(.hm-sw-header__field--layer .hm-sw-header__layer-icons, .hm-sw-header__chip, .hm-sw-header__font-name) { display: none; }
.hm-sw-header__fields .hm-sw-header__line-values { grid-template-columns: minmax(0, auto) minmax(0, 38px) minmax(0, 38px); gap: 6px; }
}
@container hm-sw-header (min-width: 760px) and (max-width: 900px) {
/* 900px and narrower (2026-10-21 user request): the 선스타일 field keeps only 선스타일 (가중치 / 스케일 hide). */
.hm-sw-header__fields .hm-sw-header__line-values { grid-template-columns: minmax(0, auto); }
.hm-sw-header__fields .hm-sw-header__line-values > :not(:first-child) { display: none; }
}
@container hm-sw-header (max-width: 1079.98px) {
.hm-sw-header__motion { flex-basis: 24px; background-size: 18px 37px; }
/* 24px move area: no room for the icon motion, so hover shows only the tooltip, right of the
area like Figma hover2 (x = area width + 1, y 11). */
.hm-sw-header__motion-icon,
.hm-sw-header__motion-window,
.hm-sw-header__motion-cursor { display: none; }
.hm-sw-header__motion-tooltip { left: calc(100% + 1px); top: 11px; }
.hm-sw-header__motion:hover > .hm-sw-header__motion-tooltip { animation: none; opacity: 1; }
.hm-sw-header__window { flex-basis: 176px; width: 176px; }
}
/* Below 760px: the former tiers (선/문자/치수 스타일 < 1800, 그리기모드 < 1180, 속성Bar/속성창 < 1080, 색상 < 900). */
@container hm-sw-header (max-width: 759.98px) {
.hm-sw-header__fields > [data-tier="aux"] { display: none; }
.hm-sw-header__more { display: block; }
.hm-sw-header__more-item[data-tier="aux"] { display: flex; }
.hm-sw-header__mode { display: none; }
.hm-sw-header__fields { padding-left: 4px; }
.hm-sw-header__properties { display: none; }
.hm-sw-header__more { margin-left: auto; margin-right: 4px; }
.hm-sw-header__more-item[data-tier="panel"] { display: flex; }
.hm-sw-header__fields > [data-menu="color"] { display: none; }
.hm-sw-header__more-item[data-tier="narrow"] { display: flex; }
.hm-sw-header__document { flex-basis: clamp(96px, calc(100cqw - 529px - var(--hm-sw-header-leading-width, 0px)), 310px); }
}
@container hm-sw-header (max-width: 639.98px) {
.hm-sw-header__actions,
.hm-sw-header__motion { display: none; }
.hm-sw-header__window { flex-basis: 64px; width: 64px; }
.hm-sw-header__more-item[data-tier="action"] { display: flex; }
.hm-sw-header__document { flex-basis: clamp(96px, calc(100cqw - 417px - var(--hm-sw-header-leading-width, 0px)), 310px); }
.hm-sw-header__document-button { padding-right: 8px; }
}
@container hm-sw-header (max-width: 519.98px) {
/* Phones: decorative layer-state icons give their width to the layer name. */
.hm-sw-header__field--layer .hm-sw-header__layer-icons { display: none; }
}
/* Representative slot (2026-10-16): a field chosen in More (SWHeader `data-promoted`) takes the
layer field's place — the first slot of the composed controls — only while that field is in More
at the current width; its dropdown opens right below it. The layer field then moves into More
(tier "slot") and choosing it gives the slot back. Order and widths at 1920 never change. The
promoted field may shrink (values ellipsize) so the object area never overflows. */
@container hm-sw-header (max-width: 1799.98px) {
.hm-sw-header__object-area[data-promoted="line-style"] .hm-sw-header__fields > [data-menu="line-style"],
.hm-sw-header__object-area[data-promoted="text-style"] .hm-sw-header__fields > [data-menu="text-style"],
.hm-sw-header__object-area[data-promoted="dimension-style"] .hm-sw-header__fields > [data-menu="dimension-style"] {
display: flex;
order: -1;
flex-shrink: 1;
min-width: 0;
}
.hm-sw-header__object-area:is([data-promoted="line-style"], [data-promoted="text-style"], [data-promoted="dimension-style"]) .hm-sw-header__fields > :is([data-menu="layer"], .hm-sw-header__layer) { display: none; }
.hm-sw-header__object-area:is([data-promoted="line-style"], [data-promoted="text-style"], [data-promoted="dimension-style"]) .hm-sw-header__more-item[data-menu="layer"] { display: flex; }
.hm-sw-header__object-area[data-promoted="line-style"] .hm-sw-header__more-item[data-menu="line-style"],
.hm-sw-header__object-area[data-promoted="text-style"] .hm-sw-header__more-item[data-menu="text-style"],
.hm-sw-header__object-area[data-promoted="dimension-style"] .hm-sw-header__more-item[data-menu="dimension-style"] { display: none; }
}
@container hm-sw-header (max-width: 899.98px) {
.hm-sw-header__object-area[data-promoted="color"] .hm-sw-header__fields > [data-menu="color"] {
display: flex;
order: -1;
flex-shrink: 1;
min-width: 0;
}
.hm-sw-header__object-area[data-promoted="color"] .hm-sw-header__fields > :is([data-menu="layer"], .hm-sw-header__layer) { display: none; }
.hm-sw-header__object-area[data-promoted="color"] .hm-sw-header__more-item[data-menu="layer"] { display: flex; }
.hm-sw-header__object-area[data-promoted="color"] .hm-sw-header__more-item[data-menu="color"] { display: none; }
}
/* Headers narrower than the 468px line style dropdown: its columns stack (scrolling vertically if the
screen is short) instead of shrinking or scrolling sideways. */
@container hm-sw-header (max-width: 479.98px) {
.hm-sw-header__line-drop {
flex-direction: column;
max-height: calc(100dvh - 64px);
overflow-y: auto;
border: 1px solid var(--hm-sw-header-layer-menu-border-color);
}
.hm-sw-header__line-drop::after { display: none; }
.hm-sw-header__line-column,
.hm-sw-header__line-column--type { flex: 0 0 auto; width: auto; }
.hm-sw-header__line-column + .hm-sw-header__line-column::before { inset: 0 0 auto; width: auto; height: 1px; }
}
/* Individual part removal (2026-10-16, SWHeader `hiddenControls`). Only applies when a part is removed;
the untouched default keeps every width above. Remaining parts keep their own Figma size and the
removed ones take no space. The logo always stays (home removed => static logo, no hover). */
.hm-sw-header__home[data-static] { cursor: default; }
.hm-sw-header__window[data-reduced] { flex: 0 0 auto; width: auto; }
.hm-sw-header__actions[data-partial],
.hm-sw-header__window-buttons[data-partial] { flex: 0 0 auto; }
.hm-sw-header__properties[data-partial] { flex: 0 0 auto; width: auto; min-width: 64px; justify-content: center; }
.hm-sw-header__properties[data-partial] .hm-sw-header__toggle { padding-inline: 8px; }
/* Script-decided default layout: each field sits in a control wrapper, so the CSS tier rules above do not
hide it; data-hidden does. Fields keep their default shrink rules; a promoted field takes the first slot. */
.hm-sw-header__fields:not([data-configured]) > .hm-sw-header__control:not([data-control="layer"]) { flex-shrink: 0; }
.hm-sw-header__fields:not([data-configured]) > .hm-sw-header__control[data-representative] { order: -1; flex-shrink: 1; }
/* When the script decides More (controls or removed parts), its visibility wins over the tier rules. */
.hm-sw-header .hm-sw-header__more .hm-sw-header__more-menu > .hm-sw-header__more-item[data-visible="true"] { display: flex; }
.hm-sw-header .hm-sw-header__more .hm-sw-header__more-menu > .hm-sw-header__more-item[data-visible="false"] { display: none; }
/* Removed window buttons shorten the tail the 창 이동 tooltip overhangs: nothing passes the header edge, and the
24px move area shows its tooltip on its left instead. */
.hm-sw-header__window[data-reduced] { overflow-x: clip; }
@container hm-sw-header (max-width: 1079.98px) {
.hm-sw-header__window[data-reduced]:not(:has(.hm-sw-header__window-buttons:not([data-partial]))) .hm-sw-header__motion-tooltip { left: auto; right: calc(100% + 1px); }
}
/* SW Tool (SWToolButton / SWToolGroup, 2026-10-19): the existing toggle, pill and file-name looks reused as
public buttons. Only placement rules live here; every color, size and state comes from the rules above. */
.hm-sw-tool__group { margin-inline: 0; }
.hm-sw-tool__item { display: contents; }
.hm-sw-tool__group .hm-sw-header__toggle { padding-inline: 8px; }
.hm-sw-tool__icon { position: absolute; inset: 20.1% 20% 19.62%; display: grid; place-items: center; pointer-events: none; }
.hm-sw-tool__icon > :is(img, svg) { display: block; max-width: 100%; max-height: 100%; }
.hm-sw-tool__label { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
/* File-name look as a button (e.g. Open next to the logo): content width, never the file-name clamp. */
.hm-sw-header__document[data-tool] { flex: 0 0 auto; }
.hm-sw-header__document[data-tool] > .hm-sw-header__document-button { width: auto; }
/* Leading area right of the logo (SWHeader documentOpenPlacement="header" / leading, 2026-10-19). It is the
flex item the logo overlaps (like the file name), so the first file-name-look button keeps the Figma junction.
Its measured width is --hm-sw-header-leading-width, subtracted from the file-name clamp above. */
.hm-sw-header__leading { position: relative; z-index: 1; display: flex; flex: 0 0 auto; gap: 2px; height: var(--hm-sw-header-bar-height); }
/* The file name after an Open button no longer sits under the logo: 12px start padding (D-1), not 5px. */
:is(.hm-sw-header__leading, .hm-sw-header__document[data-tool]) + .hm-sw-header__document > .hm-sw-header__document-button { padding-left: 12px; }
/* While the header Open is shown, the default fields keep their width: a lack of room becomes a measured
overflow that moves Open into More instead of narrowing the layer field. Custom leading content alone keeps
the existing behavior (file name first, then the layer field below 520px). Below 760px only (2026-10-21): from
760px up nothing moves into More, so the fields shrink beside Open like everywhere else. */
@container hm-sw-header (max-width: 759.98px) {
.hm-sw-header[data-leading="open"] .hm-sw-header__fields:not([data-configured]) > :is(.hm-sw-header__layer, .hm-sw-header__field--layer, .hm-sw-header__control[data-control="layer"]) { flex-shrink: 0; }
}
.hm-sw-header__more[data-forced] { display: block; }
/* Tool groups reuse the 상세보기 / print-K surfaces but are host tools: the Header breakpoints that move those
built-in parts into More never hide them (they have no More entry). */
.hm-sw-header__properties.hm-sw-tool__group { display: flex; }
.hm-sw-header__actions.hm-sw-tool__pill { display: flex; }
/* Configured layouts too: while the header Open is shown, controls other than the file name keep their width,
so a lack of room is a measured overflow that moves Open into More (the file name still gives way first).
Below 760px only (2026-10-21), as above. */
@container hm-sw-header (max-width: 759.98px) {
.hm-sw-header[data-leading="open"] .hm-sw-header__fields[data-configured] > .hm-sw-header__control:not([data-control="document"]),
.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; }
/* Measured More (SWHeader, 2026-10-19): on top of the breakpoints, parts move into More while the object area has no
room for them and return when it has. data-measuring is set for one synchronous layout read and removed before
paint: nothing in the object area shrinks, grows or takes free space through an auto margin, so the in-flow content
shows the room it really needs. A configured file name counts with the smallest default file-name width (96px).
!important: measurement only, it must win over every tier and representative-slot rule above. */
.hm-sw-header[data-measuring] :is(.hm-sw-header__object-area, .hm-sw-header__fields, .hm-sw-header__control) > * { flex-grow: 0 !important; flex-shrink: 0 !important; }
.hm-sw-header[data-measuring] .hm-sw-header__properties,
.hm-sw-header[data-measuring] .hm-sw-header__object-area[data-squeezed~="properties"] > .hm-sw-header__more { margin-left: 0 !important; }
@container hm-sw-header (max-width: 1079.98px) {
.hm-sw-header[data-measuring] .hm-sw-header__more { margin-left: 0 !important; }
}
.hm-sw-header[data-measuring] .hm-sw-header__control[data-control="document"] { flex: 0 0 96px !important; min-width: 0 !important; }
/* Measured parts take the place the breakpoints give them: without 그리기모드 the fields start 4px in (as < 1180),
without the property block More sits at the end of the object area (as < 1080). */
.hm-sw-header__object-area[data-squeezed~="drawingMode"]:not([data-configured]) > .hm-sw-header__fields { padding-left: 4px; }
.hm-sw-header__object-area[data-squeezed~="properties"] > .hm-sw-header__more { margin-left: auto; margin-right: 4px; }
/* Print / K held in More while the header grows (SWHeader data-actions-held, 2026-10-20): the window area keeps the
narrow state of the 640px tier (print / K and the move area hidden, 64px) until the object area has the room they
need. The file name keeps the clamp of the current width, so the measured room is the room they would take back. */
.hm-sw-header[data-actions-held] :is(.hm-sw-header__actions, .hm-sw-header__motion) { display: none; }
.hm-sw-header[data-actions-held] .hm-sw-header__window { flex-basis: 64px; width: 64px; }
/* 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; }
/* Home On (Figma 662:67267 btn_home + border-top / border-bottom, 2026-10-19): only while the logo menu is open.
The logo keeps the yellow hover border (the Home On asset draws the same 1px inner gradient border) and the header
gets the 2px #5F4B0F lines across its full width. Figma layer order: border-bottom under the menu (20) over the
file name / window area, border-top over the menu, the logo over both. Lines are overlays: no size or position
changes, and closing the menu removes them. SW normal mode only (SWViewerHeader has no logo menu). */
.hm-sw-header[data-home-menu-open] .hm-sw-header__home-bg-hover { opacity: 1; }
.hm-sw-header[data-home-menu-open] > .hm-sw-header__bar > .hm-sw-header__home { z-index: 22; }
.hm-sw-header[data-home-menu-open]::before,
.hm-sw-header[data-home-menu-open]::after {
content: "";
position: absolute;
left: 0;
right: 0;
height: var(--hm-sw-header-home-on-line-width);
background: var(--hm-sw-header-home-on-line-color);
pointer-events: none;
}
.hm-sw-header[data-home-menu-open]::before { top: 0; z-index: 21; }
.hm-sw-header[data-home-menu-open]::after { top: calc(var(--hm-sw-header-bar-height) - var(--hm-sw-header-home-on-line-width)); z-index: 1; }