@stn-uiux/pub-ui 0.1.86 → 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 (37) hide show
  1. package/dist/chunk-7OZGRHFD.js +15 -0
  2. package/dist/chunk-7OZGRHFD.js.map +1 -0
  3. package/dist/chunk-I2Y7E4TU.js +15 -0
  4. package/dist/chunk-I2Y7E4TU.js.map +1 -0
  5. package/dist/chunk-PXTPAYC3.js +1 -0
  6. package/dist/chunk-ZGYPJEU3.js +9 -0
  7. package/dist/chunk-ZGYPJEU3.js.map +1 -0
  8. package/dist/cli.js +5 -5
  9. package/dist/data/index.d.ts +2 -0
  10. package/dist/data/index.js +55 -43
  11. package/dist/data/stnList.d.ts +19 -0
  12. package/dist/data/stnList.js +9 -0
  13. package/dist/data/stnList.js.map +1 -0
  14. package/dist/data/stnMenu.d.ts +22 -0
  15. package/dist/data/stnMenu.js +9 -0
  16. package/dist/data/stnMenu.js.map +1 -0
  17. package/dist/data/stnPackageVersion.d.ts +2 -2
  18. package/dist/data/stnPackageVersion.js +1 -1
  19. package/dist/index.d.ts +2 -0
  20. package/dist/index.js +55 -43
  21. package/package.json +1 -1
  22. package/styles/components/stn-badge.css +0 -14
  23. package/styles/components/stn-drawer.css +7 -1
  24. package/styles/components/stn-list.css +430 -0
  25. package/styles/components/stn-menu.css +467 -0
  26. package/styles/components/stn-topology.css +47 -51
  27. package/styles/layouts/stn-container.css +49 -5
  28. package/styles/layouts/stn-layer1-content.css +4 -1
  29. package/styles/patterns/stn-floating-toolbar.css +39 -0
  30. package/styles/style-pub.css +2 -0
  31. package/styles/tokens/stn-colors-semantic.css +26 -2
  32. package/styles/tokens/stn-size-semantic.css +22 -10
  33. package/styles/tokens/stn-size.css +1 -0
  34. package/dist/chunk-2PIUQUBN.js +0 -9
  35. package/dist/chunk-2PIUQUBN.js.map +0 -1
  36. package/dist/chunk-ERZPIKPF.js +0 -1
  37. /package/dist/{chunk-ERZPIKPF.js.map → chunk-PXTPAYC3.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
+ }
@@ -6,34 +6,33 @@
6
6
  */
7
7
 
8
8
  /* ==========================================================================
9
- Topology Tokens (현재 노드 하이라이트 링 & 시작/종료 노드 뱃지 토큰)
10
- - STN 4대 표준 규격: 원시 Hex/RGB 절대 금지, 순수 --stn-* 시멘틱 토큰으로만 구성
11
- - 다크 모드(기본): 흰색 반투명 테두리 링, 흰색 뱃지 배경, 검은색 뱃지 텍스트
12
- - 라이트 모드: Gray 반투명 테두리 링, 검은색 뱃지 배경, 흰색 뱃지 텍스트
9
+ Topology Labels & Tooltips (STN 시멘틱 토큰 기반 회선/노드 라벨 표준 규격)
13
10
  ========================================================================== */
14
- :root,
15
- [data-mode='dark'],
16
- [data-theme='dark'] {
17
- --stn-topology-node-current-bg: color-mix(in srgb, var(--stn-static-white) 22%, transparent);
18
- --stn-topology-node-current-ring: color-mix(in srgb, var(--stn-static-white) 40%, transparent);
19
- --stn-topology-node-current-ambient: color-mix(in srgb, var(--stn-static-white) 15%, transparent);
20
- --stn-topology-node-current-glow: color-mix(in srgb, var(--stn-static-white) 20%, transparent);
21
- --stn-topology-node-point: var(--stn-primary);
22
- --stn-topology-badge-bg: var(--stn-static-white);
23
- --stn-topology-badge-text: var(--stn-gray-900);
24
- --stn-topology-badge-border: color-mix(in srgb, var(--stn-gray-900) 20%, transparent);
25
- }
26
-
27
- [data-mode='light'],
28
- [data-theme='light'] {
29
- --stn-topology-node-current-bg: color-mix(in srgb, var(--stn-gray-900) 15%, transparent);
30
- --stn-topology-node-current-ring: color-mix(in srgb, var(--stn-gray-900) 30%, transparent);
31
- --stn-topology-node-current-ambient: color-mix(in srgb, var(--stn-gray-900) 12%, transparent);
32
- --stn-topology-node-current-glow: color-mix(in srgb, var(--stn-gray-700) 15%, transparent);
33
- --stn-topology-node-point: var(--stn-primary);
34
- --stn-topology-badge-bg: var(--stn-gray-900);
35
- --stn-topology-badge-text: var(--stn-static-white);
36
- --stn-topology-badge-border: color-mix(in srgb, var(--stn-static-white) 20%, transparent);
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);
37
36
  }
38
37
 
39
38
  .stn-topology-ring,
@@ -172,16 +171,6 @@
172
171
  /* ==========================================================================
173
172
  Current Node Highlight (현재 선택 노드 — 다크: 흰색 반투명, 라이트: gray 반투명)
174
173
  ========================================================================== */
175
- :root {
176
- --stn-topology-node-current-ring: color-mix(in srgb, var(--stn-neutral-90, #1f242f) 28%, transparent);
177
- --stn-topology-node-current-glow: color-mix(in srgb, var(--stn-neutral-90, #1f242f) 12%, transparent);
178
- }
179
-
180
- [data-theme="dark"],
181
- .theme-dark {
182
- --stn-topology-node-current-ring: color-mix(in srgb, var(--stn-static-white, #ffffff) 45%, transparent);
183
- --stn-topology-node-current-glow: color-mix(in srgb, var(--stn-static-white, #ffffff) 20%, transparent);
184
- }
185
174
 
186
175
  /* 2D 마크용 현재 노드 스타일 */
187
176
  :is(.stn-topology-node-mark.is-current, .stn-topology-node-mark.current) .stn-topology-node__circle {
@@ -208,28 +197,29 @@
208
197
  }
209
198
 
210
199
  /* ==========================================================================
211
- Topology Start/End Node Badge Tokens (시작 & 종료 노드 뱃지 — 다크: 흰색, 라이트: 검은색)
200
+ Topology Start/End Node Badge Tokens (시작 & 종료 노드 뱃지 — Primary Blue SSOT)
212
201
  ========================================================================== */
213
- :root {
214
- --stn-topology-badge-bg: var(--stn-neutral-90, #1f242f);
215
- --stn-topology-badge-text: var(--stn-static-white, #ffffff);
216
- --stn-topology-badge-border: var(--stn-elevation-surface-0);
217
- }
218
-
219
- [data-theme="dark"],
220
- .theme-dark {
221
- --stn-topology-badge-bg: var(--stn-static-white, #ffffff);
222
- --stn-topology-badge-text: var(--stn-neutral-90, #1f242f);
223
- --stn-topology-badge-border: var(--stn-elevation-surface-0);
224
- }
225
-
226
202
  .stn-topology-node__badge rect {
203
+ fill: var(--stn-topology-badge-bg, var(--stn-primary));
227
204
  transition: fill 0.2s ease, stroke 0.2s ease;
228
205
  }
229
206
  .stn-topology-node__badge text {
207
+ fill: var(--stn-topology-badge-text, var(--stn-static-white));
230
208
  transition: fill 0.2s ease;
231
209
  }
232
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
+
233
223
  /* Severity / Status Themes on Circle (통일된 단일 룰) */
234
224
  .stn-topology-node-mark.normal .stn-topology-node__circle {
235
225
  background: var(--stn-opacity-white-5);
@@ -479,4 +469,10 @@
479
469
  animation: stnTopologyPulseRing 2s infinite ease-out 0.8s;
480
470
  }
481
471
 
472
+ /* Node Tooltip in SVG Overlay */
473
+ .stn-topology-node-tooltip {
474
+ transition: opacity 0.15s ease;
475
+ pointer-events: none;
476
+ }
477
+
482
478
 
@@ -42,11 +42,55 @@
42
42
  }
43
43
  }
44
44
 
45
- /* 컨테이너 자신의 좌우 패딩만 끈다.
46
- !important를 쓰지 않아, .stn-layer-1__body > .stn-container 의 16px은 그대로 남는다. */
47
- .stn-container--disable-gutters {
48
- padding-left: var(--stn-container-gutter-none);
49
- padding-right: var(--stn-container-gutter-none);
45
+ /* ==========================================================================
46
+ Padding 0 Modifiers (상·하·좌·우 개별 및 전체 패딩 0 제거 유틸리티)
47
+ - !important 없이 CSS 변수 및 특정성 체이닝으로 부모 레이어 여백도 자연스럽게 무력화
48
+ ========================================================================== */
49
+ .stn-container--disable-gutters,
50
+ .stn-container.stn-container--disable-gutters,
51
+ .stn-layer-1__body > .stn-container.stn-container--disable-gutters {
52
+ --stn-container-padding-left: var(--stn-container-gutter-none, 0px);
53
+ --stn-container-padding-right: var(--stn-container-gutter-none, 0px);
54
+ padding-left: var(--stn-container-gutter-none, 0px);
55
+ padding-right: var(--stn-container-gutter-none, 0px);
56
+ }
57
+
58
+ .stn-container--disable-padding-top,
59
+ .stn-container.stn-container--disable-padding-top,
60
+ .stn-layer-1__body > .stn-container.stn-container--disable-padding-top {
61
+ --stn-container-padding-top: var(--stn-space-0, 0px);
62
+ padding-top: var(--stn-space-0, 0px);
63
+ }
64
+
65
+ .stn-container--disable-padding-bottom,
66
+ .stn-container.stn-container--disable-padding-bottom,
67
+ .stn-layer-1__body > .stn-container.stn-container--disable-padding-bottom {
68
+ --stn-container-padding-bottom: var(--stn-space-0, 0px);
69
+ padding-bottom: var(--stn-space-0, 0px);
70
+ }
71
+
72
+ .stn-container--disable-padding-left,
73
+ .stn-container.stn-container--disable-padding-left,
74
+ .stn-layer-1__body > .stn-container.stn-container--disable-padding-left {
75
+ --stn-container-padding-left: var(--stn-container-gutter-none, 0px);
76
+ padding-left: var(--stn-container-gutter-none, 0px);
77
+ }
78
+
79
+ .stn-container--disable-padding-right,
80
+ .stn-container.stn-container--disable-padding-right,
81
+ .stn-layer-1__body > .stn-container.stn-container--disable-padding-right {
82
+ --stn-container-padding-right: var(--stn-container-gutter-none, 0px);
83
+ padding-right: var(--stn-container-gutter-none, 0px);
84
+ }
85
+
86
+ .stn-container--disable-padding,
87
+ .stn-container.stn-container--disable-padding,
88
+ .stn-layer-1__body > .stn-container.stn-container--disable-padding {
89
+ --stn-container-padding-top: var(--stn-space-0, 0px);
90
+ --stn-container-padding-bottom: var(--stn-space-0, 0px);
91
+ --stn-container-padding-left: var(--stn-space-0, 0px);
92
+ --stn-container-padding-right: var(--stn-space-0, 0px);
93
+ padding: var(--stn-space-0, 0px);
50
94
  }
51
95
 
52
96
  /* Fluid max-width. width 100%라서 캡에 닿기 전까지 화면과 같이 늘어난다.
@@ -177,7 +177,10 @@
177
177
  display: flex;
178
178
  flex-direction: column;
179
179
  box-sizing: border-box;
180
- padding: var(--stn-space-16);
180
+ padding-top: var(--stn-container-padding-top, var(--stn-space-16));
181
+ padding-bottom: var(--stn-container-padding-bottom, var(--stn-space-16));
182
+ padding-left: var(--stn-container-padding-left, var(--stn-space-16));
183
+ padding-right: var(--stn-container-padding-right, var(--stn-space-16));
181
184
  overflow: hidden;
182
185
  }
183
186