@stn-uiux/pub-ui 0.1.85 → 0.1.87

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. package/dist/{chunk-BYGKJSDN.js → chunk-6HRKKRTT.js} +18 -3
  2. package/dist/chunk-6HRKKRTT.js.map +1 -0
  3. package/dist/{chunk-YN774RCQ.js → chunk-6TQ4O7BK.js} +2 -2
  4. package/dist/chunk-7OZGRHFD.js +15 -0
  5. package/dist/chunk-7OZGRHFD.js.map +1 -0
  6. package/dist/{chunk-W7K3FSAX.js → chunk-F5WWHWEU.js} +9 -1
  7. package/dist/chunk-F5WWHWEU.js.map +1 -0
  8. package/dist/chunk-I2Y7E4TU.js +15 -0
  9. package/dist/chunk-I2Y7E4TU.js.map +1 -0
  10. package/dist/chunk-PXTPAYC3.js +1 -0
  11. package/dist/{chunk-SOEBXG3T.js → chunk-U66BCO23.js} +2 -2
  12. package/dist/chunk-ZGYPJEU3.js +9 -0
  13. package/dist/chunk-ZGYPJEU3.js.map +1 -0
  14. package/dist/cli.js +7 -7
  15. package/dist/data/index.d.ts +3 -1
  16. package/dist/data/index.js +61 -47
  17. package/dist/data/stnColorPalette.js +2 -2
  18. package/dist/data/stnFeedbackColors.d.ts +7 -0
  19. package/dist/data/stnFeedbackColors.js +1 -1
  20. package/dist/data/stnList.d.ts +19 -0
  21. package/dist/data/stnList.js +9 -0
  22. package/dist/data/stnList.js.map +1 -0
  23. package/dist/data/stnMenu.d.ts +22 -0
  24. package/dist/data/stnMenu.js +9 -0
  25. package/dist/data/stnMenu.js.map +1 -0
  26. package/dist/data/stnPackageVersion.d.ts +2 -2
  27. package/dist/data/stnPackageVersion.js +1 -1
  28. package/dist/data/stnSplitView.d.ts +3 -1
  29. package/dist/data/stnSplitView.js +3 -1
  30. package/dist/data/stnToast.js +2 -2
  31. package/dist/index.d.ts +3 -1
  32. package/dist/index.js +61 -47
  33. package/package.json +1 -1
  34. package/styles/components/stn-badge.css +17 -0
  35. package/styles/components/stn-breadcrumb.css +9 -0
  36. package/styles/components/stn-card.css +32 -0
  37. package/styles/components/stn-drawer.css +7 -0
  38. package/styles/components/stn-list.css +430 -0
  39. package/styles/components/stn-menu.css +467 -0
  40. package/styles/components/stn-popup.css +32 -0
  41. package/styles/components/stn-topology.css +93 -1
  42. package/styles/foundations/stn-typography.css +1 -0
  43. package/styles/layouts/stn-container.css +49 -5
  44. package/styles/layouts/stn-layer1-content.css +4 -1
  45. package/styles/patterns/stn-floating-toolbar.css +39 -0
  46. package/styles/patterns/stn-split-view.css +68 -0
  47. package/styles/style-pub.css +2 -0
  48. package/styles/tokens/stn-colors-semantic.css +36 -4
  49. package/styles/tokens/stn-size-semantic.css +22 -4
  50. package/styles/tokens/stn-size.css +1 -0
  51. package/dist/chunk-5QPBSOJ6.js +0 -9
  52. package/dist/chunk-5QPBSOJ6.js.map +0 -1
  53. package/dist/chunk-BYGKJSDN.js.map +0 -1
  54. package/dist/chunk-ERZPIKPF.js +0 -1
  55. package/dist/chunk-W7K3FSAX.js.map +0 -1
  56. /package/dist/{chunk-YN774RCQ.js.map → chunk-6TQ4O7BK.js.map} +0 -0
  57. /package/dist/{chunk-ERZPIKPF.js.map → chunk-PXTPAYC3.js.map} +0 -0
  58. /package/dist/{chunk-SOEBXG3T.js.map → chunk-U66BCO23.js.map} +0 -0
@@ -0,0 +1,467 @@
1
+ /**
2
+ * ==========================================================================
3
+ * STN Design System — StnMenu CSS
4
+ *
5
+ * 4대 표준 규격(Size, Width, Semantic Tokens) 엄격 준수
6
+ * ==========================================================================
7
+ */
8
+
9
+ /* ==========================================================================
10
+ 1. CSS Custom Properties (Menu Semantic Tokens)
11
+ ========================================================================== */
12
+ :root {
13
+ --stn-menu-bg: var(--stn-dropdown-menu-bg, var(--stn-elevation-surface-0));
14
+ --stn-menu-border: var(--stn-dropdown-menu-border, var(--stn-border-subtle));
15
+ --stn-menu-shadow: var(--stn-dropdown-menu-shadow, var(--stn-shadow-md));
16
+ --stn-menu-radius: var(--stn-radius-8, 8px);
17
+
18
+ /* 호버 상태: 드롭다운 옵션 hover 스타일과 100% 동일하게 일원화 */
19
+ --stn-menu-item-hover: var(--stn-dropdown-menu-hover-bg);
20
+ --stn-menu-item-hover-fg: var(--stn-text-primary);
21
+
22
+ /* 클릭/누름(Active) 상태: 드롭다운 옵션 active 스타일과 일치 */
23
+ --stn-menu-item-active: var(--stn-dropdown-menu-hover-bg);
24
+
25
+ /* 선택(Selected) 상태: 드롭다운 옵션 selected 스타일과 일치 */
26
+ --stn-menu-item-selected: var(--stn-dropdown-menu-selected-bg);
27
+ --stn-menu-item-selected-hover: var(--stn-dropdown-menu-hover-bg);
28
+ --stn-menu-item-selected-active: var(--stn-dropdown-menu-hover-bg);
29
+ --stn-menu-item-selected-fg: var(--stn-primary);
30
+
31
+ /* 위험/파괴적(Destructive) 상태 */
32
+ --stn-menu-item-destructive-fg: var(--stn-grade-critical);
33
+ --stn-menu-item-destructive-hover: color-mix(in srgb, var(--stn-grade-critical) 12%, var(--stn-dropdown-menu-hover-bg));
34
+ --stn-menu-item-destructive-active: color-mix(in srgb, var(--stn-grade-critical) 20%, var(--stn-dropdown-menu-hover-bg));
35
+ }
36
+
37
+ /* ==========================================================================
38
+ 2. StnMenu Root & Paper Box (드롭다운 .select_option과 100% 일치)
39
+ ========================================================================== */
40
+ .stn-menu-paper {
41
+ box-sizing: border-box;
42
+ background: var(--stn-menu-bg);
43
+ border: var(--stn-size-1, 1px) solid var(--stn-menu-border);
44
+ border-radius: var(--stn-menu-radius, var(--stn-radius-8, 8px));
45
+ box-shadow: var(--stn-menu-shadow);
46
+ color: var(--stn-text-primary);
47
+ outline: none;
48
+ overflow-x: hidden;
49
+ overflow-y: auto;
50
+ width: max-content;
51
+ min-width: var(--stn-menu-min-width, var(--stn-size-140, 140px));
52
+ max-width: calc(100vw - var(--stn-space-32, 32px));
53
+ z-index: var(--stn-menu-z, var(--stn-elevation-z-popover, 250));
54
+ padding: var(--stn-space-4, 4px); /* StnDropdown .select_option과 100% 동일한 상하좌우 4px 패딩 */
55
+ transition: transform 0.15s cubic-bezier(0.4, 0, 0.2, 1), opacity 0.15s ease;
56
+ }
57
+
58
+ /* Elevation Shadow Levels */
59
+ .stn-menu-paper--elev-0 { box-shadow: none; }
60
+ .stn-menu-paper--elev-1 { box-shadow: var(--stn-shadow-sm); }
61
+ .stn-menu-paper--elev-2 { box-shadow: var(--stn-shadow-md); }
62
+ .stn-menu-paper--elev-3 { box-shadow: var(--stn-shadow-lg); }
63
+
64
+ /* ==========================================================================
65
+ 3. StnMenuList (메뉴 아이템 리스트 컨테이너)
66
+ ========================================================================== */
67
+ .stn-menu-list {
68
+ box-sizing: border-box;
69
+ margin: 0;
70
+ padding: 0;
71
+ list-style: none;
72
+ outline: none;
73
+ display: flex;
74
+ flex-direction: column;
75
+ gap: var(--stn-space-2, 2px);
76
+ width: 100%;
77
+ }
78
+
79
+ .stn-menu-list > li {
80
+ list-style: none;
81
+ margin: 0;
82
+ padding: 0;
83
+ }
84
+
85
+ /* ==========================================================================
86
+ 4. 5대 표준 Size 규격 (xs · sm · md · lg · xl)
87
+ ========================================================================== */
88
+ .stn-menu--xs,
89
+ .stn-menu-list--xs,
90
+ .stn-menu-item--xs {
91
+ --stn-menu-item-height: var(--stn-menu-item-height-xs, var(--stn-size-24, 24px));
92
+ --stn-menu-item-padding-y: var(--stn-space-2, 2px);
93
+ --stn-menu-item-padding-x: var(--stn-space-6, 6px);
94
+ --stn-menu-item-font-size: var(--stn-font-size-caption, 11px);
95
+ --stn-menu-item-icon-size: var(--stn-size-14, 14px);
96
+ --stn-menu-item-gap: var(--stn-space-4, 4px);
97
+ }
98
+
99
+ .stn-menu--sm,
100
+ .stn-menu-list--sm,
101
+ .stn-menu-item--sm,
102
+ .stn-menu-list--dense,
103
+ .stn-menu-item--dense {
104
+ --stn-menu-item-height: var(--stn-menu-item-height-sm, var(--stn-size-28, 28px));
105
+ --stn-menu-item-padding-y: var(--stn-space-4, 4px);
106
+ --stn-menu-item-padding-x: var(--stn-space-6, 6px);
107
+ --stn-menu-item-font-size: var(--stn-font-size-caption, 12px);
108
+ --stn-menu-item-icon-size: var(--stn-size-16, 16px);
109
+ --stn-menu-item-gap: var(--stn-space-4, 4px);
110
+ }
111
+
112
+ /* StnDropdown .select_option > li 와 100% 동일한 md 기본 규격 (SSOT) */
113
+ .stn-menu--md,
114
+ .stn-menu-list--md,
115
+ .stn-menu-item--md {
116
+ --stn-menu-item-height: var(--stn-menu-item-height-md, var(--stn-size-32, 32px));
117
+ --stn-menu-item-padding-y: var(--stn-space-6, 6px);
118
+ --stn-menu-item-padding-x: var(--stn-space-8, 8px);
119
+ --stn-menu-item-font-size: var(--stn-text-body-small-size, 13px);
120
+ --stn-menu-item-icon-size: var(--stn-size-16, 16px);
121
+ --stn-menu-item-gap: var(--stn-space-6, 6px);
122
+ }
123
+
124
+ .stn-menu--lg,
125
+ .stn-menu-list--lg,
126
+ .stn-menu-item--lg {
127
+ --stn-menu-item-height: var(--stn-menu-item-height-lg, var(--stn-size-38, 38px));
128
+ --stn-menu-item-padding-y: var(--stn-space-8, 8px);
129
+ --stn-menu-item-padding-x: var(--stn-space-10, 10px);
130
+ --stn-menu-item-font-size: var(--stn-font-size-body-2, 14px);
131
+ --stn-menu-item-icon-size: var(--stn-size-18, 18px);
132
+ --stn-menu-item-gap: var(--stn-space-8, 8px);
133
+ }
134
+
135
+ .stn-menu--xl,
136
+ .stn-menu-list--xl,
137
+ .stn-menu-item--xl {
138
+ --stn-menu-item-height: var(--stn-menu-item-height-xl, var(--stn-size-44, 44px));
139
+ --stn-menu-item-padding-y: var(--stn-space-10, 10px);
140
+ --stn-menu-item-padding-x: var(--stn-space-12, 12px);
141
+ --stn-menu-item-font-size: var(--stn-font-size-body-1, 16px);
142
+ --stn-menu-item-icon-size: var(--stn-size-20, 20px);
143
+ --stn-menu-item-gap: var(--stn-space-10, 10px);
144
+ }
145
+
146
+ /* ==========================================================================
147
+ 5. 패딩 규격 프리셋 (Padding Presets)
148
+ ========================================================================== */
149
+ .stn-menu-list--pad-none,
150
+ .stn-menu-item--pad-none,
151
+ .stn-menu-list--pad-none .stn-menu-item {
152
+ --stn-menu-item-padding-y: 0;
153
+ --stn-menu-item-padding-x: 0;
154
+ }
155
+
156
+ .stn-menu-list--pad-xs,
157
+ .stn-menu-item--pad-xs,
158
+ .stn-menu-list--pad-xs .stn-menu-item {
159
+ --stn-menu-item-padding-y: var(--stn-space-2, 2px);
160
+ --stn-menu-item-padding-x: var(--stn-space-6, 6px);
161
+ }
162
+
163
+ .stn-menu-list--pad-sm,
164
+ .stn-menu-item--pad-sm,
165
+ .stn-menu-list--pad-sm .stn-menu-item {
166
+ --stn-menu-item-padding-y: var(--stn-space-4, 4px);
167
+ --stn-menu-item-padding-x: var(--stn-space-6, 6px);
168
+ }
169
+
170
+ .stn-menu-list--pad-md,
171
+ .stn-menu-item--pad-md,
172
+ .stn-menu-list--pad-md .stn-menu-item {
173
+ --stn-menu-item-padding-y: var(--stn-space-6, 6px);
174
+ --stn-menu-item-padding-x: var(--stn-space-8, 8px);
175
+ }
176
+
177
+ .stn-menu-list--pad-lg,
178
+ .stn-menu-item--pad-lg,
179
+ .stn-menu-list--pad-lg .stn-menu-item {
180
+ --stn-menu-item-padding-y: var(--stn-space-8, 8px);
181
+ --stn-menu-item-padding-x: var(--stn-space-10, 10px);
182
+ }
183
+
184
+ .stn-menu-list--pad-xl,
185
+ .stn-menu-item--pad-xl,
186
+ .stn-menu-list--pad-xl .stn-menu-item {
187
+ --stn-menu-item-padding-y: var(--stn-space-10, 10px);
188
+ --stn-menu-item-padding-x: var(--stn-space-12, 12px);
189
+ }
190
+
191
+ /* ==========================================================================
192
+ 6. 4대 표준 너비 규격 (Width Presets — STN 4대 표준 규격: .w80 ~ .w200, .full)
193
+ ========================================================================== */
194
+ .stn-menu.w80 { width: var(--stn-size-80); min-width: var(--stn-size-80); }
195
+ .stn-menu.w100 { width: var(--stn-size-100); min-width: var(--stn-size-100); }
196
+ .stn-menu.w120 { width: var(--stn-size-120); min-width: var(--stn-size-120); }
197
+ .stn-menu.w140 { width: var(--stn-size-140); min-width: var(--stn-size-140); }
198
+ .stn-menu.w160 { width: var(--stn-size-160); min-width: var(--stn-size-160); }
199
+ .stn-menu.w180 { width: var(--stn-size-180); min-width: var(--stn-size-180); }
200
+ .stn-menu.w200 { width: var(--stn-size-200); min-width: var(--stn-size-200); }
201
+ .stn-menu.full { width: 100%; max-width: 100%; }
202
+
203
+ /* 페이퍼 내부 리스트는 페이퍼 안쪽 패딩 영역(100%)을 채우도록 하여 우측 짤림 방지 */
204
+ .stn-menu-paper .stn-menu-list {
205
+ width: 100%;
206
+ min-width: 0;
207
+ max-width: 100%;
208
+ }
209
+
210
+ /* ==========================================================================
211
+ 7. StnMenuItem (개별 메뉴 버튼 행) — StnDropdown li와 100% 동일 규격
212
+ ========================================================================== */
213
+ .stn-menu-item {
214
+ box-sizing: border-box;
215
+ display: flex;
216
+ align-items: center;
217
+ position: relative;
218
+ width: 100%;
219
+ margin: 0;
220
+ border-radius: var(--stn-radius-4, 4px);
221
+ min-height: var(--stn-menu-item-height, 32px);
222
+ padding: var(--stn-menu-item-padding-y, var(--stn-space-6, 6px)) var(--stn-menu-item-padding-x, var(--stn-space-8, 8px));
223
+ gap: var(--stn-menu-item-gap, var(--stn-space-6, 6px));
224
+ background: transparent;
225
+ border: none;
226
+ color: var(--stn-text-primary);
227
+ font-size: var(--stn-menu-item-font-size, var(--stn-text-body-small-size, 13px));
228
+ line-height: var(--stn-line-height-tight, 1.4);
229
+ font-weight: var(--stn-font-weight-medium, 500);
230
+ text-align: left;
231
+ text-decoration: none;
232
+ cursor: pointer;
233
+ user-select: none;
234
+ outline: none;
235
+ transition: background-color var(--stn-motion-duration-fast, 150ms) ease,
236
+ color var(--stn-motion-duration-fast, 150ms) ease;
237
+ -webkit-appearance: none;
238
+ }
239
+
240
+ /* 호버 상태 (Hover) — 드롭다운 li:hover와 100% 동일한 hover 스타일 */
241
+ .stn-menu-item:hover:not(.is-disabled),
242
+ .stn-menu-item.is-active:not(.is-disabled) {
243
+ background-color: var(--stn-dropdown-menu-hover-bg);
244
+ color: var(--stn-text-primary);
245
+ }
246
+
247
+ .stn-menu-item:hover:not(.is-disabled) .stn-menu-item-icon:not(:has(.stn-menu-radio)):not(:has(.stn-menu-checkbox)) {
248
+ color: var(--stn-text-primary);
249
+ }
250
+
251
+ /* 클릭/누름 상태 (Active / Clicked) */
252
+ .stn-menu-item:active:not(.is-disabled) {
253
+ background-color: var(--stn-dropdown-menu-hover-bg);
254
+ }
255
+
256
+ /* 포커스 링 (Focus Visible — 키보드 탐색) */
257
+ .stn-menu-item:focus-visible {
258
+ background-color: var(--stn-dropdown-menu-hover-bg);
259
+ outline: var(--stn-focus-ring-width, 2px) solid var(--stn-focus-ring);
260
+ outline-offset: calc(var(--stn-focus-ring-width, 2px) * -1);
261
+ }
262
+
263
+ /* 선택(Selected) 상태 — 드롭다운 li.selected와 100% 동일한 스타일 */
264
+ .stn-menu-item.is-selected {
265
+ background-color: var(--stn-dropdown-menu-selected-bg);
266
+ color: var(--stn-primary);
267
+ font-weight: var(--stn-font-weight-medium, 500);
268
+ }
269
+
270
+ .stn-menu-item.is-selected .stn-menu-item-icon {
271
+ color: var(--stn-primary);
272
+ }
273
+
274
+ /* 선택 항목 호버 */
275
+ .stn-menu-item.is-selected:hover:not(.is-disabled) {
276
+ background-color: var(--stn-dropdown-menu-hover-bg);
277
+ color: var(--stn-primary);
278
+ }
279
+
280
+ /* 선택 항목 클릭 (Active) */
281
+ .stn-menu-item.is-selected:active:not(.is-disabled) {
282
+ background-color: var(--stn-dropdown-menu-hover-bg);
283
+ }
284
+
285
+ /* 비활성화(Disabled) 상태 */
286
+ .stn-menu-item.is-disabled,
287
+ .stn-menu-item[disabled] {
288
+ opacity: 0.45;
289
+ cursor: not-allowed;
290
+ pointer-events: none;
291
+ }
292
+
293
+ /* 위험/삭제 액션(Destructive) 상태 */
294
+ .stn-menu-item.is-destructive {
295
+ color: var(--stn-menu-item-destructive-fg);
296
+ }
297
+
298
+ .stn-menu-item.is-destructive .stn-menu-item-icon {
299
+ color: var(--stn-menu-item-destructive-fg);
300
+ }
301
+
302
+ .stn-menu-item.is-destructive:hover:not(.is-disabled) {
303
+ background-color: var(--stn-menu-item-destructive-hover);
304
+ color: var(--stn-menu-item-destructive-fg);
305
+ }
306
+
307
+ .stn-menu-item.is-destructive:active:not(.is-disabled) {
308
+ background-color: var(--stn-menu-item-destructive-active);
309
+ transform: scale(0.985);
310
+ }
311
+
312
+ /* 패딩 규격이 none 일 때는 여백 없이 edge-to-edge 채움 */
313
+ .stn-menu-list--pad-none .stn-menu-item,
314
+ .stn-menu-item--pad-none {
315
+ width: 100%;
316
+ margin: 0;
317
+ border-radius: 0;
318
+ }
319
+
320
+ /* ==========================================================================
321
+ 8. StnMenuItemIcon (좌측 시각 슬롯)
322
+ ========================================================================== */
323
+ .stn-menu-item-icon {
324
+ display: inline-flex;
325
+ align-items: center;
326
+ justify-content: center;
327
+ flex-shrink: 0;
328
+ width: var(--stn-menu-item-icon-size, var(--stn-size-18, 18px));
329
+ height: var(--stn-menu-item-icon-size, var(--stn-size-18, 18px));
330
+ min-width: var(--stn-menu-item-icon-size, var(--stn-size-18, 18px));
331
+ color: var(--stn-text-secondary);
332
+ transition: color 0.15s ease;
333
+ }
334
+
335
+ .stn-menu-item-icon .stn-icon,
336
+ .stn-menu-item-icon svg {
337
+ width: var(--stn-menu-item-icon-size, var(--stn-size-18, 18px));
338
+ height: var(--stn-menu-item-icon-size, var(--stn-size-18, 18px));
339
+ }
340
+
341
+ /* ==========================================================================
342
+ 9. StnMenuItemText (본문 텍스트 슬롯)
343
+ ========================================================================== */
344
+ .stn-menu-item-text {
345
+ flex: 1;
346
+ min-width: 0;
347
+ display: flex;
348
+ flex-direction: column;
349
+ justify-content: center;
350
+ text-align: left;
351
+ overflow: hidden;
352
+ text-overflow: ellipsis;
353
+ white-space: nowrap;
354
+ }
355
+
356
+ .stn-menu-item-text__primary {
357
+ display: block;
358
+ font-size: var(--stn-menu-item-font-size, var(--stn-font-size-body-2));
359
+ font-weight: inherit;
360
+ color: inherit;
361
+ line-height: 1.4;
362
+ overflow: hidden;
363
+ text-overflow: ellipsis;
364
+ white-space: nowrap;
365
+ }
366
+
367
+ .stn-menu-item-text__secondary {
368
+ display: block;
369
+ font-size: calc(var(--stn-menu-item-font-size, var(--stn-font-size-body-2)) - 2px);
370
+ color: var(--stn-text-tertiary);
371
+ line-height: 1.35;
372
+ margin-top: var(--stn-space-2, 2px);
373
+ overflow: hidden;
374
+ text-overflow: ellipsis;
375
+ white-space: nowrap;
376
+ }
377
+
378
+ /* 말줄임표 해제 (noWrap=false) */
379
+ .stn-menu-item-text--wrap,
380
+ .stn-menu-item-text--wrap .stn-menu-item-text__primary,
381
+ .stn-menu-item-text--wrap .stn-menu-item-text__secondary {
382
+ white-space: normal;
383
+ }
384
+
385
+ /* 단독 HTML 클래스 지원 (.stn-menu-item-text--nowrap) */
386
+ .stn-menu-item-text--nowrap {
387
+ white-space: nowrap;
388
+ overflow: hidden;
389
+ text-overflow: ellipsis;
390
+ }
391
+
392
+ /* 아이콘 없는 항목 정렬 정합성 (Inset Indentation) */
393
+ .stn-menu-item-text--inset {
394
+ padding-left: calc(var(--stn-menu-item-icon-size, var(--stn-size-16, 16px)) + var(--stn-menu-item-gap, var(--stn-space-6, 6px)));
395
+ }
396
+
397
+ /* ==========================================================================
398
+ 10. StnMenuShortcut (우측 단축키 힌트)
399
+ ========================================================================== */
400
+ .stn-menu-item-shortcut {
401
+ display: inline-flex;
402
+ align-items: center;
403
+ margin-left: auto;
404
+ flex-shrink: 0;
405
+ font-size: var(--stn-font-size-caption);
406
+ color: var(--stn-text-tertiary);
407
+ font-family: inherit;
408
+ letter-spacing: 0.04em;
409
+ padding-left: var(--stn-space-16);
410
+ user-select: none;
411
+ }
412
+
413
+ /* ==========================================================================
414
+ 11. StnMenuDivider (공식 StnDivider as="li" SSOT — 메뉴 팝오버 풀블리드 배치)
415
+ ========================================================================== */
416
+ .stn-menu-divider {
417
+ display: block;
418
+ height: 0;
419
+ width: calc(100% + (var(--stn-space-4, 4px) * 2));
420
+ margin: var(--stn-space-4, 4px) calc(-1 * var(--stn-space-4, 4px));
421
+ border-top: var(--stn-size-1, 1px) solid var(--stn-dropdown-menu-border, var(--stn-border-subtle));
422
+ border-bottom: none;
423
+ border-left: none;
424
+ border-right: none;
425
+ list-style: none;
426
+ }
427
+
428
+ /* ==========================================================================
429
+ 12. StnMenuSubheader (그룹 카테고리 헤더)
430
+ ========================================================================== */
431
+ .stn-menu-subheader {
432
+ box-sizing: border-box;
433
+ display: flex;
434
+ align-items: center;
435
+ padding: var(--stn-space-6, 6px) var(--stn-space-8, 8px) var(--stn-space-2, 2px);
436
+ font-size: var(--stn-font-size-caption, 11px);
437
+ font-weight: var(--stn-font-weight-semibold, 600);
438
+ color: var(--stn-text-tertiary);
439
+ line-height: 1.3;
440
+ letter-spacing: 0.02em;
441
+ user-select: none;
442
+ list-style: none;
443
+ }
444
+
445
+ /* ==========================================================================
446
+ 13. StnMenuRadio & StnMenuCheckbox (선택 인디케이터)
447
+ ========================================================================== */
448
+ .stn-menu-radio,
449
+ .stn-menu-checkbox {
450
+ display: inline-flex;
451
+ align-items: center;
452
+ justify-content: center;
453
+ flex-shrink: 0;
454
+ line-height: 1;
455
+ }
456
+
457
+ .stn-menu-checkbox.is-checked {
458
+ color: var(--stn-primary);
459
+ }
460
+
461
+ .stn-menu-radio svg circle:first-child {
462
+ transition: stroke 0.15s ease;
463
+ }
464
+
465
+ .stn-menu-radio svg circle:last-child {
466
+ transition: transform 0.15s ease, opacity 0.15s ease;
467
+ }
@@ -270,6 +270,10 @@
270
270
  background-color: var(--stn-pop-surface);
271
271
  }
272
272
 
273
+ .stn-pop__actions--left {
274
+ justify-content: flex-start;
275
+ }
276
+
273
277
  .stn-pop__actions--right {
274
278
  justify-content: flex-end;
275
279
  }
@@ -282,6 +286,13 @@
282
286
  justify-content: space-between;
283
287
  }
284
288
 
289
+ /* Actions Group — between 정렬 등에서 버튼들을 시멘틱 간격으로 묶는 표준 래퍼 */
290
+ .stn-pop__actions-group {
291
+ display: flex;
292
+ align-items: center;
293
+ gap: var(--stn-pop-actions-gap);
294
+ }
295
+
285
296
  /* —— Master-Detail Split Layout (.stn-pop-split) —— */
286
297
  .stn-pop-split {
287
298
  display: flex;
@@ -313,3 +324,24 @@
313
324
  overflow-y: auto;
314
325
  box-sizing: border-box;
315
326
  }
327
+
328
+ /* 1. 반반 분할 (50:50 대칭 비교형 — .half, .equal) */
329
+ :is(.stn-pop-split.half, .stn-pop-split--half, .stn-pop-split.equal, .stn-pop-split--equal) > .stn-pop-split__aside {
330
+ flex: 1 1 0;
331
+ width: 50%;
332
+ min-width: 0;
333
+ max-width: none;
334
+ }
335
+
336
+ /* 2. 역방향 분할 (7:3 좌측 넓음 1fr · 우측 좁음 280px 속성창 — .reverse) */
337
+ :is(.stn-pop-split.reverse, .stn-pop-split--reverse) {
338
+ flex-direction: row-reverse;
339
+ }
340
+
341
+ :is(.stn-pop-split.reverse, .stn-pop-split--reverse) > .stn-pop-split__aside,
342
+ .stn-pop-split > .stn-pop-split__main + .stn-pop-split__aside {
343
+ border-right: none;
344
+ border-left: var(--stn-pop-border-width) solid var(--stn-pop-divider);
345
+ padding-right: 0;
346
+ padding-left: var(--stn-pop-split-aside-padding-right);
347
+ }
@@ -5,6 +5,36 @@
5
5
  * STN 표준 시멘틱 토큰 기반 스타일링
6
6
  */
7
7
 
8
+ /* ==========================================================================
9
+ Topology Labels & Tooltips (STN 시멘틱 토큰 기반 회선/노드 라벨 표준 규격)
10
+ ========================================================================== */
11
+ .stn-topology-link__label text {
12
+ fill: var(--stn-topology-link-label-fg, var(--stn-text-secondary));
13
+ stroke: var(--stn-topology-link-label-halo, var(--stn-elevation-surface-0));
14
+ stroke-width: 2.4px;
15
+ paint-order: stroke;
16
+ stroke-linejoin: round;
17
+ font-weight: 600;
18
+ letter-spacing: -0.2px;
19
+ }
20
+
21
+ .stn-topology-node__bottom-label--plain text {
22
+ fill: var(--stn-topology-node-label-fg, var(--stn-text-primary));
23
+ stroke: var(--stn-topology-node-label-halo, var(--stn-elevation-surface-0));
24
+ stroke-width: 2.4px;
25
+ paint-order: stroke;
26
+ stroke-linejoin: round;
27
+ font-weight: 700;
28
+ letter-spacing: -0.2px;
29
+ }
30
+
31
+ .stn-topology-node__label-badge.neutral.subtle {
32
+ background-color: var(--stn-elevation-surface-0);
33
+ border: none;
34
+ color: var(--stn-text-primary);
35
+ font-weight: var(--stn-font-weight-regular, 400);
36
+ }
37
+
8
38
  .stn-topology-ring,
9
39
  .stn-topology-graph {
10
40
  box-sizing: border-box;
@@ -86,7 +116,7 @@
86
116
  color: var(--stn-static-white);
87
117
  }
88
118
 
89
- /* 4대 표준 크기 규격 (xs · sm · md · lg) */
119
+ /* 5대 표준 크기 규격 (xs · sm · md · lg · xl) */
90
120
  .stn-topology-node-mark.xs .stn-topology-node__circle {
91
121
  width: var(--stn-topology-node-size-xs);
92
122
  height: var(--stn-topology-node-size-xs);
@@ -103,6 +133,10 @@
103
133
  width: var(--stn-topology-node-size-lg);
104
134
  height: var(--stn-topology-node-size-lg);
105
135
  }
136
+ .stn-topology-node-mark.xl .stn-topology-node__circle {
137
+ width: var(--stn-topology-node-size-xl);
138
+ height: var(--stn-topology-node-size-xl);
139
+ }
106
140
 
107
141
  /* Shapes: circle · square · diamond (3대 표준 도형) */
108
142
  .stn-topology-node-mark.shape-circle .stn-topology-node__circle {
@@ -134,6 +168,58 @@
134
168
  transform: rotate(45deg) scale(0.92);
135
169
  }
136
170
 
171
+ /* ==========================================================================
172
+ Current Node Highlight (현재 선택 노드 — 다크: 흰색 반투명, 라이트: gray 반투명)
173
+ ========================================================================== */
174
+
175
+ /* 2D 마크용 현재 노드 스타일 */
176
+ :is(.stn-topology-node-mark.is-current, .stn-topology-node-mark.current) .stn-topology-node__circle {
177
+ outline: none;
178
+ box-shadow:
179
+ 0 0 0 3px var(--stn-topology-node-selected-gap, var(--stn-elevation-surface-0)),
180
+ 0 0 0 5.5px var(--stn-topology-node-current-ring),
181
+ 0 0 16px var(--stn-topology-node-current-glow);
182
+ transform: scale(1.06);
183
+ }
184
+
185
+ :is(.stn-topology-node-mark.shape-diamond.is-current, .stn-topology-node-mark.shape-diamond.current) .stn-topology-node__circle {
186
+ transform: rotate(45deg) scale(0.92);
187
+ }
188
+
189
+ /* 3D SVG 노드용 선택/현재 하이라이트 배경 플레이트 (border 대신 background 채움 — 다크: 흰색, 라이트: 검은색) */
190
+ .stn-topology-node__current-ring {
191
+ pointer-events: none;
192
+ transition: opacity 0.2s ease, transform 0.2s ease;
193
+ }
194
+ .stn-topology-node__current-ring :is(circle, rect, polygon) {
195
+ fill: var(--stn-topology-node-current-bg);
196
+ stroke: none;
197
+ }
198
+
199
+ /* ==========================================================================
200
+ Topology Start/End Node Badge Tokens (시작 & 종료 노드 뱃지 — Primary Blue SSOT)
201
+ ========================================================================== */
202
+ .stn-topology-node__badge rect {
203
+ fill: var(--stn-topology-badge-bg, var(--stn-primary));
204
+ transition: fill 0.2s ease, stroke 0.2s ease;
205
+ }
206
+ .stn-topology-node__badge text {
207
+ fill: var(--stn-topology-badge-text, var(--stn-static-white));
208
+ transition: fill 0.2s ease;
209
+ }
210
+
211
+ /* STN 토폴로지 노드 벡터 외곽선 stroke-width 표준 시멘틱 토큰 강제 규격 */
212
+ .stn-topology-node > g > rect,
213
+ .stn-topology-node > g > circle:not([class*='stn-topology-pulse-ring']),
214
+ .stn-topology-node > g > polygon,
215
+ .stn-topology-node > g > path,
216
+ .stn-topology-node > circle:not([class*='stn-topology-pulse-ring']),
217
+ .stn-topology-node > rect,
218
+ .stn-topology-node > polygon,
219
+ .stn-topology-node > path {
220
+ stroke-width: var(--stn-topology-node-stroke, 1.2px);
221
+ }
222
+
137
223
  /* Severity / Status Themes on Circle (통일된 단일 룰) */
138
224
  .stn-topology-node-mark.normal .stn-topology-node__circle {
139
225
  background: var(--stn-opacity-white-5);
@@ -383,4 +469,10 @@
383
469
  animation: stnTopologyPulseRing 2s infinite ease-out 0.8s;
384
470
  }
385
471
 
472
+ /* Node Tooltip in SVG Overlay */
473
+ .stn-topology-node-tooltip {
474
+ transition: opacity 0.15s ease;
475
+ pointer-events: none;
476
+ }
477
+
386
478
 
@@ -148,6 +148,7 @@
148
148
  .stn-text-color-success { color: var(--stn-feedback-success); }
149
149
  .stn-text-color-error { color: var(--stn-feedback-error); }
150
150
  .stn-text-color-info { color: var(--stn-feedback-info); }
151
+ .stn-text-color-discovery { color: var(--stn-feedback-discovery); }
151
152
  .stn-text-color-critical { color: var(--stn-grade-critical); }
152
153
  .stn-text-color-major { color: var(--stn-grade-major); }
153
154
  .stn-text-color-minor { color: var(--stn-grade-minor); }