@stn-uiux/pub-ui 0.1.57 → 0.1.59

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 (130) hide show
  1. package/dist/{chunk-L7DYM4V7.js → chunk-2FHXIAM3.js} +10 -28
  2. package/dist/{chunk-L7DYM4V7.js.map → chunk-2FHXIAM3.js.map} +1 -1
  3. package/dist/chunk-2WKT7X65.js +407 -0
  4. package/dist/chunk-2WKT7X65.js.map +1 -0
  5. package/dist/{chunk-7ASY5YJ6.js → chunk-36BAGMYT.js} +3 -3
  6. package/dist/chunk-36BAGMYT.js.map +1 -0
  7. package/dist/{chunk-THCCTVUM.js → chunk-5F63CMM7.js} +11 -1
  8. package/dist/chunk-5F63CMM7.js.map +1 -0
  9. package/dist/{chunk-Q3W7QA7N.js → chunk-75GHU6VI.js} +24 -43
  10. package/dist/chunk-75GHU6VI.js.map +1 -0
  11. package/dist/chunk-A5KLX6NX.js +1 -0
  12. package/dist/{chunk-4C7ABT2K.js → chunk-AE4CKAEK.js} +3 -3
  13. package/dist/chunk-AE4CKAEK.js.map +1 -0
  14. package/dist/{chunk-UPXSNRIJ.js → chunk-AOS3IX4T.js} +2 -2
  15. package/dist/chunk-AOS3IX4T.js.map +1 -0
  16. package/dist/{chunk-XNGYRPZI.js → chunk-CHJATVOT.js} +4 -4
  17. package/dist/{chunk-XNGYRPZI.js.map → chunk-CHJATVOT.js.map} +1 -1
  18. package/dist/{chunk-XZ3JOUX2.js → chunk-EQTZA7I2.js} +2 -14
  19. package/dist/chunk-EQTZA7I2.js.map +1 -0
  20. package/dist/{chunk-P5V6SFR7.js → chunk-H4ZJQ5YW.js} +2 -2
  21. package/dist/{chunk-GR76L7M7.js → chunk-JPILTFLI.js} +5 -5
  22. package/dist/chunk-JPILTFLI.js.map +1 -0
  23. package/dist/{chunk-WRGBYWRV.js → chunk-LKVTW54X.js} +1 -1
  24. package/dist/chunk-LKVTW54X.js.map +1 -0
  25. package/dist/{chunk-OMCBVK57.js → chunk-SKZOEF3H.js} +2 -2
  26. package/dist/chunk-SQJPE6HH.js +12 -0
  27. package/dist/chunk-SQJPE6HH.js.map +1 -0
  28. package/dist/{chunk-V7HD6SBG.js → chunk-XEG4WDUD.js} +7 -18
  29. package/dist/chunk-XEG4WDUD.js.map +1 -0
  30. package/dist/chunk-XPARWRVD.js +9 -0
  31. package/dist/chunk-XPARWRVD.js.map +1 -0
  32. package/dist/{chunk-S4YA4H2S.js → chunk-YBNEQ5LB.js} +2 -2
  33. package/dist/cli.js +15 -15
  34. package/dist/data/index.d.ts +2 -1
  35. package/dist/data/index.js +31 -27
  36. package/dist/data/stnAlertCenter.d.ts +4 -3
  37. package/dist/data/stnAlertCenter.js +1 -1
  38. package/dist/data/stnBreadcrumb.js +3 -3
  39. package/dist/data/stnDatePicker.js +2 -2
  40. package/dist/data/stnDateRangeField.d.ts +1 -1
  41. package/dist/data/stnDateRangeField.js +1 -1
  42. package/dist/data/stnDropdown.d.ts +1 -1
  43. package/dist/data/stnDropdown.js +1 -1
  44. package/dist/data/stnHeader.d.ts +2 -2
  45. package/dist/data/stnHeader.js +3 -3
  46. package/dist/data/stnLayout.d.ts +1 -1
  47. package/dist/data/stnLayout.js +1 -1
  48. package/dist/data/stnPackageVersion.d.ts +2 -2
  49. package/dist/data/stnPackageVersion.js +1 -1
  50. package/dist/data/stnPopup.d.ts +19 -41
  51. package/dist/data/stnPopup.js +1 -1
  52. package/dist/data/stnScroll.d.ts +1 -1
  53. package/dist/data/stnScroll.js +1 -1
  54. package/dist/data/stnSearchRequirement.d.ts +4 -4
  55. package/dist/data/stnSearchRequirement.js +1 -1
  56. package/dist/data/stnSideNavItem.js +3 -3
  57. package/dist/data/stnSizeSemantic.js +1 -1
  58. package/dist/data/stnStatus.d.ts +11 -0
  59. package/dist/data/stnStatus.js +7 -0
  60. package/dist/data/stnStatus.js.map +1 -0
  61. package/dist/data/stnSystemIcons.d.ts +1 -1
  62. package/dist/data/stnSystemIcons.js +2 -2
  63. package/dist/data/stnSystemIconsData.generated.js +1 -1
  64. package/dist/data/stnTree.d.ts +1 -1
  65. package/dist/data/stnTree.js +1 -1
  66. package/dist/index.d.ts +2 -1
  67. package/dist/index.js +31 -27
  68. package/package.json +1 -1
  69. package/styles/@assets/svg/system/line/eye-off.svg +5 -0
  70. package/styles/components/stn-btn.css +10 -1
  71. package/styles/components/stn-date-picker.css +13 -5
  72. package/styles/components/stn-date-range-field.css +153 -16
  73. package/styles/components/stn-dropdown.css +161 -42
  74. package/styles/components/stn-label-prefix.css +356 -0
  75. package/styles/components/stn-pagination.css +113 -5
  76. package/styles/components/stn-popup.css +78 -132
  77. package/styles/components/stn-scroll.css +51 -66
  78. package/styles/components/stn-search-requirement.css +27 -20
  79. package/styles/components/stn-segmented.css +3 -1
  80. package/styles/components/stn-status.css +853 -0
  81. package/styles/components/stn-table.css +32 -5
  82. package/styles/components/stn-text-field.css +396 -374
  83. package/styles/components/stn-toast.css +17 -0
  84. package/styles/components/stn-toggle-button.css +37 -0
  85. package/styles/layouts/stn-container.css +9 -0
  86. package/styles/layouts/stn-layer1-content.css +105 -0
  87. package/styles/patterns/stn-alert-center.css +114 -4
  88. package/styles/patterns/stn-header.css +7 -145
  89. package/styles/patterns/stn-section-side.css +64 -0
  90. package/styles/patterns/stn-tree.css +193 -2
  91. package/styles/style-pub.css +2 -1
  92. package/styles/tokens/stn-breakpoint.css +12 -0
  93. package/styles/tokens/stn-colors-semantic.css +13 -7
  94. package/styles/tokens/stn-radius-semantic.css +4 -3
  95. package/styles/tokens/stn-size-semantic.css +19 -6
  96. package/styles/tokens/stn-size.css +2 -0
  97. package/styles/tokens/stn-spacing-semantic.css +12 -0
  98. package/styles/tokens/stn-typography.css +1 -0
  99. package/dist/chunk-4C7ABT2K.js.map +0 -1
  100. package/dist/chunk-7ASY5YJ6.js.map +0 -1
  101. package/dist/chunk-GR76L7M7.js.map +0 -1
  102. package/dist/chunk-LHV26PEP.js +0 -1
  103. package/dist/chunk-Q3W7QA7N.js.map +0 -1
  104. package/dist/chunk-QT4HHVZH.js +0 -9
  105. package/dist/chunk-QT4HHVZH.js.map +0 -1
  106. package/dist/chunk-THCCTVUM.js.map +0 -1
  107. package/dist/chunk-UPXSNRIJ.js.map +0 -1
  108. package/dist/chunk-V7HD6SBG.js.map +0 -1
  109. package/dist/chunk-WRGBYWRV.js.map +0 -1
  110. package/dist/chunk-XZ3JOUX2.js.map +0 -1
  111. package/dist/chunk-ZI6EF4XD.js +0 -209
  112. package/dist/chunk-ZI6EF4XD.js.map +0 -1
  113. package/styles/@assets/svg/system/3d/print.png +0 -0
  114. package/styles/@assets/svg/system/3d/print_1.png +0 -0
  115. package/styles/@assets/svg/system/3d/server1.png +0 -0
  116. package/styles/@assets/svg/system/3d/server1_1.png +0 -0
  117. package/styles/@assets/svg/system/3d/server2.png +0 -0
  118. package/styles/@assets/svg/system/3d/server2_1.png +0 -0
  119. package/styles/@assets/svg/system/3d/signal.png +0 -0
  120. package/styles/@assets/svg/system/3d/signal_1.png +0 -0
  121. package/styles/@assets/svg/system/3d/wifi.png +0 -0
  122. package/styles/@assets/svg/system/3d/wifi_1.png +0 -0
  123. package/styles/@assets/svg/system/ai_agent.png +0 -0
  124. package/styles/@assets/svg/system/line/input.svg +0 -3
  125. package/styles/@assets/svg/system/line/radio.svg +0 -3
  126. package/styles/components/stn-severity-badge.css +0 -227
  127. /package/dist/{chunk-LHV26PEP.js.map → chunk-A5KLX6NX.js.map} +0 -0
  128. /package/dist/{chunk-P5V6SFR7.js.map → chunk-H4ZJQ5YW.js.map} +0 -0
  129. /package/dist/{chunk-OMCBVK57.js.map → chunk-SKZOEF3H.js.map} +0 -0
  130. /package/dist/{chunk-S4YA4H2S.js.map → chunk-YBNEQ5LB.js.map} +0 -0
@@ -0,0 +1,356 @@
1
+ /**
2
+ * StnLabelPrefix — 아이콘+레이블이 내장된 입력 래퍼 컴포넌트
3
+ *
4
+ * 구조:
5
+ * div.stn-label-prefix
6
+ * ├── .stn-label-prefix__label (아이콘 + 텍스트 + 구분선)
7
+ * └── .stn-label-prefix__control (children slot — StnDropdown·StnTextField·StnDateRangeField 등)
8
+ *
9
+ * Props:
10
+ * variant : outline(기본) · filled · standard · transparent
11
+ * size : sm(24px) · md(32px, 기본) · lg(40px)
12
+ * radius : none · sm · md · lg · xl (기본은 size에 따름)
13
+ * position : prefix(왼쪽, 기본) · suffix(오른쪽)
14
+ *
15
+ * ==========================================================================
16
+ * 1. Base Layout
17
+ * 2. Label Area (.stn-label-prefix__label)
18
+ * 3. Divider (.stn-label-prefix__divider)
19
+ * 4. Control Slot (.stn-label-prefix__control)
20
+ * 5. Size (sm · md · lg)
21
+ * 6. Variant (outline · filled · standard · transparent)
22
+ * 7. Focus-within State
23
+ * 8. Suffix Position
24
+ * 9. Radius Override
25
+ * 10. Width Presets
26
+ * 11. Disabled State
27
+ * ==========================================================================
28
+ */
29
+
30
+ /* ==========================================================================
31
+ 1. Base Layout
32
+ ========================================================================== */
33
+ .stn-label-prefix {
34
+ position: relative;
35
+ display: inline-flex;
36
+ align-items: stretch;
37
+ box-sizing: border-box;
38
+ max-width: 100%;
39
+ overflow: hidden;
40
+ vertical-align: middle;
41
+ transition: border-color var(--stn-motion-duration-fast, 150ms) ease;
42
+ }
43
+
44
+ /* 팝업/드롭다운이 열렸을 때 overflow를 해제하여 메뉴 목록이 잘리지 않도록 보장 */
45
+ .stn-label-prefix:has(.stn-dropdown.on),
46
+ .stn-label-prefix:has(.stn-date-picker-popup),
47
+ .stn-label-prefix:focus-within:has(.select_option) {
48
+ overflow: visible !important;
49
+ }
50
+
51
+ /* StnLabelPrefix 내부 드롭다운: 컨트롤 영역 기준으로 팝업 정렬 (방안 1) */
52
+ .stn-label-prefix > .stn-label-prefix__control > .stn-dropdown {
53
+ position: relative;
54
+ }
55
+
56
+ .stn-label-prefix .stn-dropdown > .select_option {
57
+ top: 100%;
58
+ border-top: none;
59
+ border-radius: 0 0 var(--stn-radius-input-md, 4px) var(--stn-radius-input-md, 4px);
60
+ }
61
+
62
+ .stn-label-prefix:has(.stn-dropdown.on) {
63
+ border-bottom-left-radius: 0 !important;
64
+ border-bottom-right-radius: 0 !important;
65
+ }
66
+
67
+ /* ==========================================================================
68
+ 2. Label Area
69
+ ========================================================================== */
70
+ .stn-label-prefix__label {
71
+ display: inline-flex;
72
+ align-items: center;
73
+ flex-shrink: 0;
74
+ gap: var(--stn-space-16);
75
+ padding-inline-start: var(--stn-space-16);
76
+ padding-inline-end: 0;
77
+ white-space: nowrap;
78
+ color: var(--stn-label-prefix-label-color, var(--stn-text-secondary));
79
+ background-color: transparent;
80
+ font-weight: var(--stn-font-weight-medium);
81
+ user-select: none;
82
+ }
83
+
84
+ .stn-label-prefix__checkbox {
85
+ display: inline-flex;
86
+ align-items: center;
87
+ justify-content: center;
88
+ flex-shrink: 0;
89
+ margin-inline-end: calc(-1 * var(--stn-space-8));
90
+ }
91
+
92
+ .stn-label-prefix__icon {
93
+ display: inline-flex;
94
+ align-items: center;
95
+ justify-content: center;
96
+ flex-shrink: 0;
97
+ }
98
+
99
+ .stn-label-prefix__text {
100
+ display: inline-flex;
101
+ align-items: center;
102
+ }
103
+
104
+ .stn-label-prefix__required {
105
+ color: var(--stn-feedback-error);
106
+ font-weight: var(--stn-font-weight-bold);
107
+ line-height: var(--stn-line-height-tight);
108
+ margin-inline-start: var(--stn-space-2, 2px);
109
+ }
110
+
111
+ /* ==========================================================================
112
+ 3. Divider
113
+ ========================================================================== */
114
+ .stn-label-prefix__divider {
115
+ flex-shrink: 0;
116
+ width: var(--stn-size-1, 1px);
117
+ align-self: stretch;
118
+ background-color: var(--stn-label-prefix-divider, var(--stn-input-border));
119
+ margin: var(--stn-space-8) 0;
120
+ }
121
+
122
+ /* ==========================================================================
123
+ 4. Control Slot
124
+ ========================================================================== */
125
+ .stn-label-prefix__control {
126
+ flex: 1 1 auto;
127
+ min-width: 0;
128
+ display: flex;
129
+ align-items: center;
130
+ }
131
+
132
+ /* children(Dropdown 등)이 full height를 차지하도록 */
133
+ .stn-label-prefix__control > * {
134
+ width: 100%;
135
+ }
136
+
137
+ /* ==========================================================================
138
+ 5. Size (sm · md · lg)
139
+ ========================================================================== */
140
+
141
+ /* sm — 32px */
142
+ .stn-label-prefix.sm {
143
+ height: var(--stn-dropdown-height-sm, 32px);
144
+ border-radius: var(--stn-radius-input-sm, 4px);
145
+ font-size: var(--stn-text-body-small-size);
146
+ }
147
+
148
+ .stn-label-prefix.sm > .stn-label-prefix__control {
149
+ padding: 0 var(--stn-space-8);
150
+ }
151
+
152
+ /* md — 40px (기본값) */
153
+ .stn-label-prefix.md {
154
+ height: var(--stn-dropdown-height-md, 40px);
155
+ border-radius: var(--stn-radius-input-md, 4px);
156
+ font-size: var(--stn-text-body-small-size);
157
+ }
158
+
159
+ .stn-label-prefix.md > .stn-label-prefix__control {
160
+ padding: 0 var(--stn-space-10);
161
+ }
162
+
163
+ /* lg — 56px */
164
+ .stn-label-prefix.lg {
165
+ height: var(--stn-dropdown-height-lg, 56px);
166
+ border-radius: var(--stn-radius-input-lg, 8px);
167
+ font-size: var(--stn-text-body-medium-size);
168
+ }
169
+
170
+ .stn-label-prefix.lg > .stn-label-prefix__control {
171
+ padding: 0 var(--stn-space-12);
172
+ }
173
+
174
+ /* ==========================================================================
175
+ 6. Variant (outline · filled · standard · transparent)
176
+ ========================================================================== */
177
+
178
+ /* 6-1. Outline (기본값 — 전체 테두리 박스) */
179
+ .stn-label-prefix.outline {
180
+ border: var(--stn-size-1, 1px) solid var(--stn-input-border);
181
+ background-color: var(--stn-input-bg);
182
+ }
183
+
184
+ /* 6-2. Filled (배경 채움) */
185
+ .stn-label-prefix.filled {
186
+ border: var(--stn-size-1, 1px) solid var(--stn-input-filled-border, transparent);
187
+ background-color: var(--stn-input-filled-bg, var(--stn-input-bg));
188
+ }
189
+
190
+ .stn-label-prefix.filled > .stn-label-prefix__label {
191
+ background-color: var(--stn-label-prefix-label-bg, transparent);
192
+ }
193
+
194
+ /* 6-3. Standard (하단 밑줄만) */
195
+ .stn-label-prefix.standard {
196
+ border: none;
197
+ border-bottom: var(--stn-size-1, 1px) solid var(--stn-input-border);
198
+ border-radius: var(--stn-radius-0, 0px);
199
+ background-color: transparent;
200
+ }
201
+
202
+ /* 6-4. Transparent (테두리·배경 없음 — 외부 래퍼 조합용) */
203
+ .stn-label-prefix.transparent {
204
+ border: none;
205
+ background-color: transparent;
206
+ }
207
+
208
+ /* ==========================================================================
209
+ 7. Focus-within State
210
+ ========================================================================== */
211
+ .stn-label-prefix.outline:focus-within,
212
+ .stn-label-prefix.filled:focus-within {
213
+ border-color: var(--stn-input-focus-fg, var(--stn-primary));
214
+ }
215
+
216
+ .stn-label-prefix.standard:focus-within {
217
+ border-bottom: var(--stn-input-focus);
218
+ }
219
+
220
+ /* ==========================================================================
221
+ 8. Suffix Position (label이 오른쪽에)
222
+ ========================================================================== */
223
+ .stn-label-prefix--suffix {
224
+ flex-direction: row-reverse;
225
+ }
226
+
227
+ /* suffix일 때 레이블 패딩 방향 전환 (오른쪽이 바깥쪽이므로 우측 16, 좌측 0) */
228
+ .stn-label-prefix--suffix > .stn-label-prefix__label {
229
+ padding-inline-start: 0;
230
+ padding-inline-end: var(--stn-space-16);
231
+ }
232
+
233
+ /* suffix일 때 divider를 label 내부의 가장 왼쪽(control과의 경계)에 배치 */
234
+ .stn-label-prefix--suffix .stn-label-prefix__divider {
235
+ order: -1;
236
+ }
237
+
238
+ /* ==========================================================================
239
+ 9. Radius Override
240
+ ========================================================================== */
241
+ .stn-label-prefix.radius-none {
242
+ border-radius: var(--stn-radius-0, 0px);
243
+ }
244
+
245
+ .stn-label-prefix.radius-sm {
246
+ border-radius: var(--stn-radius-input-sm, 4px);
247
+ }
248
+
249
+ .stn-label-prefix.radius-md {
250
+ border-radius: var(--stn-radius-input-md, 4px);
251
+ }
252
+
253
+ .stn-label-prefix.radius-lg {
254
+ border-radius: var(--stn-radius-input-lg, 8px);
255
+ }
256
+
257
+ .stn-label-prefix.radius-xl {
258
+ border-radius: var(--stn-radius-input-xl, 16px);
259
+ }
260
+
261
+ /* ==========================================================================
262
+ 10. Width Presets (.w80 ~ .w200 / .full)
263
+ 기본 고정 너비로 작동하며, 레이블이나 내부 컨트롤의 내용이 지정 너비보다
264
+ 길어질 경우 내용물에 맞춰 자연스럽게 늘어납니다(Hug content).
265
+ ========================================================================== */
266
+ :is(.stn-label-prefix, .stn-label-prefix-wrap).w80 { min-width: var(--stn-size-80, 80px); width: max-content; }
267
+ :is(.stn-label-prefix, .stn-label-prefix-wrap).w100 { min-width: var(--stn-size-100, 100px); width: max-content; }
268
+ :is(.stn-label-prefix, .stn-label-prefix-wrap).w120 { min-width: var(--stn-size-120, 120px); width: max-content; }
269
+ :is(.stn-label-prefix, .stn-label-prefix-wrap).w140 { min-width: var(--stn-size-140, 140px); width: max-content; }
270
+ :is(.stn-label-prefix, .stn-label-prefix-wrap).w160 { min-width: var(--stn-size-160, 160px); width: max-content; }
271
+ :is(.stn-label-prefix, .stn-label-prefix-wrap).w180 { min-width: var(--stn-size-180, 180px); width: max-content; }
272
+ :is(.stn-label-prefix, .stn-label-prefix-wrap).w200 { min-width: var(--stn-size-200, 200px); width: max-content; }
273
+ :is(.stn-label-prefix, .stn-label-prefix-wrap).full {
274
+ width: 100%;
275
+ min-width: 0;
276
+ display: flex;
277
+ }
278
+
279
+ /* ==========================================================================
280
+ 11. Disabled State
281
+ ========================================================================== */
282
+ .stn-label-prefix.is-disabled {
283
+ opacity: var(--stn-input-disabled-opacity, 0.55);
284
+ cursor: not-allowed;
285
+ pointer-events: none;
286
+ }
287
+
288
+ .stn-label-prefix.is-control-disabled .stn-label-prefix__control {
289
+ opacity: var(--stn-input-disabled-opacity, 0.45);
290
+ pointer-events: none;
291
+ }
292
+
293
+ /* ==========================================================================
294
+ 12. Feedback / Status Colors & Error State
295
+ ========================================================================== */
296
+ .stn-label-prefix.is-error,
297
+ .stn-label-prefix.error,
298
+ .stn-label-prefix[aria-invalid='true'] {
299
+ border-color: var(--stn-feedback-error);
300
+ }
301
+
302
+ .stn-label-prefix.standard.is-error,
303
+ .stn-label-prefix.standard.error,
304
+ .stn-label-prefix.standard[aria-invalid='true'] {
305
+ border-bottom-color: var(--stn-feedback-error);
306
+ }
307
+
308
+ .stn-label-prefix.outline.is-error:focus-within,
309
+ .stn-label-prefix.filled.is-error:focus-within,
310
+ .stn-label-prefix.outline.error:focus-within,
311
+ .stn-label-prefix.filled.error:focus-within {
312
+ border-color: var(--stn-feedback-error);
313
+ }
314
+
315
+ .stn-label-prefix.standard.is-error:focus-within,
316
+ .stn-label-prefix.standard.error:focus-within {
317
+ border-bottom-color: var(--stn-feedback-error);
318
+ }
319
+
320
+ .stn-label-prefix.success {
321
+ border-color: var(--stn-feedback-success);
322
+ }
323
+
324
+ .stn-label-prefix.warning {
325
+ border-color: var(--stn-feedback-warning);
326
+ }
327
+
328
+ .stn-label-prefix.info {
329
+ border-color: var(--stn-feedback-info);
330
+ }
331
+
332
+ /* ==========================================================================
333
+ 13. Helper Text & Wrapper
334
+ ========================================================================== */
335
+ .stn-label-prefix-wrap {
336
+ display: inline-flex;
337
+ flex-direction: column;
338
+ box-sizing: border-box;
339
+ vertical-align: middle;
340
+ }
341
+
342
+ .stn-label-prefix-wrap > .stn-label-prefix {
343
+ width: 100%;
344
+ }
345
+
346
+ .stn-label-prefix__helper {
347
+ margin: var(--stn-space-4) 0 0 0;
348
+ font-size: var(--stn-text-caption-size, 12px);
349
+ line-height: var(--stn-line-height-tight, 1.3);
350
+ color: var(--stn-text-muted);
351
+ }
352
+
353
+ .stn-label-prefix-wrap.is-error .stn-label-prefix__helper,
354
+ .stn-label-prefix__helper--error {
355
+ color: var(--stn-feedback-error);
356
+ }
@@ -43,7 +43,9 @@
43
43
 
44
44
  .stn-pagination__page,
45
45
  .stn-pagination__prev,
46
- .stn-pagination__next {
46
+ .stn-pagination__next,
47
+ .stn-pagination__first,
48
+ .stn-pagination__last {
47
49
  box-sizing: border-box;
48
50
  display: inline-flex;
49
51
  flex-direction: column;
@@ -55,7 +57,7 @@
55
57
  width: var(--stn-pagination-size);
56
58
  height: var(--stn-pagination-size);
57
59
  border: none;
58
- border-radius: var(--stn-pagination-radius-idle);
60
+ border-radius: var(--stn-pagination-radius-active, var(--stn-radius-circle));
59
61
  background: transparent;
60
62
  color: var(--stn-pagination-color);
61
63
  font-family: var(--stn-font-body);
@@ -68,11 +70,14 @@
68
70
  -webkit-appearance: none;
69
71
  box-shadow: none !important;
70
72
  vertical-align: middle;
73
+ transition: all 0.15s ease;
71
74
  }
72
75
 
73
76
  .stn-pagination__page:hover:not(:disabled):not(.is-active),
74
77
  .stn-pagination__prev:hover:not(:disabled),
75
- .stn-pagination__next:hover:not(:disabled) {
78
+ .stn-pagination__next:hover:not(:disabled),
79
+ .stn-pagination__first:hover:not(:disabled),
80
+ .stn-pagination__last:hover:not(:disabled) {
76
81
  background: color-mix(in srgb, var(--stn-pagination-active-bg) 70%, transparent);
77
82
  color: var(--stn-pagination-color);
78
83
  }
@@ -93,7 +98,9 @@
93
98
  }
94
99
 
95
100
  .stn-pagination__prev:disabled,
96
- .stn-pagination__next:disabled {
101
+ .stn-pagination__next:disabled,
102
+ .stn-pagination__first:disabled,
103
+ .stn-pagination__last:disabled {
97
104
  opacity: var(--stn-pagination-disabled-opacity);
98
105
  cursor: default;
99
106
  color: var(--stn-pagination-color);
@@ -101,11 +108,88 @@
101
108
  }
102
109
 
103
110
  .stn-pagination__prev:disabled:hover,
104
- .stn-pagination__next:disabled:hover {
111
+ .stn-pagination__next:disabled:hover,
112
+ .stn-pagination__first:disabled:hover,
113
+ .stn-pagination__last:disabled:hover {
105
114
  background: transparent;
106
115
  opacity: var(--stn-pagination-disabled-opacity);
107
116
  }
108
117
 
118
+ /* Size variations (STN 규격: sm · md · lg) */
119
+ .stn-pagination--sm {
120
+ --stn-pagination-size: var(--stn-size-28, 28px);
121
+ --stn-pagination-font-size: var(--stn-font-size-12, 12px);
122
+ --stn-pagination-gap: var(--stn-space-4, 4px);
123
+ --stn-pagination-arrow-gap: var(--stn-space-8, 8px);
124
+ }
125
+
126
+ .stn-pagination--md {
127
+ --stn-pagination-size: var(--stn-size-32, 32px);
128
+ --stn-pagination-font-size: var(--stn-font-size-13, 13px);
129
+ --stn-pagination-gap: var(--stn-space-8, 8px);
130
+ --stn-pagination-arrow-gap: var(--stn-space-12, 12px);
131
+ }
132
+
133
+ .stn-pagination--lg {
134
+ --stn-pagination-size: var(--stn-size-36, 36px);
135
+ --stn-pagination-font-size: var(--stn-font-size-14, 14px);
136
+ --stn-pagination-gap: var(--stn-space-8, 8px);
137
+ --stn-pagination-arrow-gap: var(--stn-space-16, 16px);
138
+ }
139
+
140
+ /* Variant: outlined (선택된 페이지만 outline 테두리 적용, 다른 번호 및 이동 버튼은 박스 없음) */
141
+ .stn-pagination--outlined .stn-pagination__page,
142
+ .stn-pagination--outlined .stn-pagination__prev,
143
+ .stn-pagination--outlined .stn-pagination__next,
144
+ .stn-pagination--outlined .stn-pagination__first,
145
+ .stn-pagination--outlined .stn-pagination__last {
146
+ border: none;
147
+ background: transparent;
148
+ }
149
+
150
+ .stn-pagination--outlined .stn-pagination__page.is-active,
151
+ .stn-pagination--outlined .stn-pagination__page[aria-current='page'] {
152
+ border: 1px solid var(--stn-pagination-active-bg, var(--stn-primary));
153
+ background: transparent;
154
+ color: var(--stn-pagination-active-bg, var(--stn-primary));
155
+ }
156
+
157
+ .stn-pagination--outlined .stn-pagination__page.is-active:hover,
158
+ .stn-pagination--outlined .stn-pagination__page[aria-current='page']:hover {
159
+ background: color-mix(in srgb, var(--stn-pagination-active-bg, var(--stn-primary)) 10%, transparent);
160
+ }
161
+
162
+ /* outlined 기본(컬러 미지정) 활성 페이지 */
163
+ .stn-pagination--outlined:not(.stn-pagination--primary):not(.stn-pagination--secondary) .stn-pagination__page.is-active,
164
+ .stn-pagination--outlined:not(.stn-pagination--primary):not(.stn-pagination--secondary) .stn-pagination__page[aria-current='page'] {
165
+ border: 1px solid var(--stn-gray-400, #94a3b8);
166
+ background: transparent;
167
+ color: var(--stn-text-primary, #ffffff);
168
+ }
169
+
170
+ [data-theme='light'] .stn-pagination--outlined:not(.stn-pagination--primary):not(.stn-pagination--secondary) .stn-pagination__page.is-active,
171
+ .light .stn-pagination--outlined:not(.stn-pagination--primary):not(.stn-pagination--secondary) .stn-pagination__page.is-active {
172
+ border-color: var(--stn-gray-500, #64748b);
173
+ color: var(--stn-gray-800, #1e293b);
174
+ }
175
+
176
+ /* Color variations */
177
+ .stn-pagination--primary {
178
+ --stn-pagination-active-bg: var(--stn-primary, var(--stn-blue-500));
179
+ --stn-pagination-active-color: var(--stn-static-white, #ffffff);
180
+ }
181
+
182
+ .stn-pagination--secondary {
183
+ --stn-pagination-active-bg: var(--stn-secondary, var(--stn-purple-500));
184
+ --stn-pagination-active-color: var(--stn-static-white, #ffffff);
185
+ }
186
+
187
+ /* Disabled state */
188
+ .stn-pagination.is-disabled {
189
+ opacity: 0.4;
190
+ pointer-events: none;
191
+ }
192
+
109
193
  .stn-pagination__icon {
110
194
  display: block;
111
195
  width: var(--stn-pagination-chevron-w);
@@ -140,3 +224,27 @@
140
224
  width: auto;
141
225
  flex: 0 0 auto;
142
226
  }
227
+
228
+ /* 모바일 좁은 화면 컴팩트 최적화
229
+ * 브레이크포인트: --stn-pagination-compact-breakpoint (480px)
230
+ * CSS @media에서 var() 사용 불가이므로 리터럴 유지; 치수는 시멘틱 토큰 참조.
231
+ */
232
+ @media (max-width: 480px) {
233
+ .stn-pagination {
234
+ gap: var(--stn-pagination-compact-gap);
235
+ }
236
+
237
+ .stn-pagination__list {
238
+ gap: var(--stn-pagination-compact-gap);
239
+ }
240
+
241
+ .stn-pagination__page,
242
+ .stn-pagination__prev,
243
+ .stn-pagination__next {
244
+ min-width: var(--stn-pagination-compact-size);
245
+ width: var(--stn-pagination-compact-size);
246
+ height: var(--stn-pagination-compact-size);
247
+ padding: var(--stn-pagination-compact-padding);
248
+ font-size: var(--stn-pagination-compact-font-size);
249
+ }
250
+ }