dipping-charts 0.1.0

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 (137) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +216 -0
  3. package/dist/__tests__/FullFeaturedChart.test.d.ts +2 -0
  4. package/dist/__tests__/FullFeaturedChart.test.d.ts.map +1 -0
  5. package/dist/__tests__/indicators-accuracy.test.d.ts +2 -0
  6. package/dist/__tests__/indicators-accuracy.test.d.ts.map +1 -0
  7. package/dist/__tests__/indicators.test.d.ts +2 -0
  8. package/dist/__tests__/indicators.test.d.ts.map +1 -0
  9. package/dist/__tests__/setup.d.ts +1 -0
  10. package/dist/__tests__/setup.d.ts.map +1 -0
  11. package/dist/__tests__/validateCandle.test.d.ts +2 -0
  12. package/dist/__tests__/validateCandle.test.d.ts.map +1 -0
  13. package/dist/chart/index.d.ts +2 -0
  14. package/dist/chart/index.js +5 -0
  15. package/dist/chart/index.js.map +1 -0
  16. package/dist/components/TradingChart.d.ts +24 -0
  17. package/dist/components/TradingChart.d.ts.map +1 -0
  18. package/dist/components/TradingChart.js +100 -0
  19. package/dist/components/TradingChart.js.map +1 -0
  20. package/dist/components/index.d.ts +3 -0
  21. package/dist/components/index.d.ts.map +1 -0
  22. package/dist/dipping-charts.css +1 -0
  23. package/dist/index.d.ts +5 -0
  24. package/dist/index.d.ts.map +1 -0
  25. package/dist/index.js +28 -0
  26. package/dist/index.js.map +1 -0
  27. package/dist/indicators/atr.d.ts +15 -0
  28. package/dist/indicators/atr.d.ts.map +1 -0
  29. package/dist/indicators/atr.js +30 -0
  30. package/dist/indicators/atr.js.map +1 -0
  31. package/dist/indicators/bollingerBands.d.ts +11 -0
  32. package/dist/indicators/bollingerBands.d.ts.map +1 -0
  33. package/dist/indicators/bollingerBands.js +39 -0
  34. package/dist/indicators/bollingerBands.js.map +1 -0
  35. package/dist/indicators/currencyStrength.d.ts +43 -0
  36. package/dist/indicators/currencyStrength.d.ts.map +1 -0
  37. package/dist/indicators/currencyStrength.js +53 -0
  38. package/dist/indicators/currencyStrength.js.map +1 -0
  39. package/dist/indicators/ema.d.ts +11 -0
  40. package/dist/indicators/ema.d.ts.map +1 -0
  41. package/dist/indicators/ema.js +24 -0
  42. package/dist/indicators/ema.js.map +1 -0
  43. package/dist/indicators/index.d.ts +19 -0
  44. package/dist/indicators/index.d.ts.map +1 -0
  45. package/dist/indicators/index.js +23 -0
  46. package/dist/indicators/index.js.map +1 -0
  47. package/dist/indicators/macd.d.ts +11 -0
  48. package/dist/indicators/macd.d.ts.map +1 -0
  49. package/dist/indicators/macd.js +52 -0
  50. package/dist/indicators/macd.js.map +1 -0
  51. package/dist/indicators/rsi.d.ts +11 -0
  52. package/dist/indicators/rsi.d.ts.map +1 -0
  53. package/dist/indicators/rsi.js +29 -0
  54. package/dist/indicators/rsi.js.map +1 -0
  55. package/dist/indicators/sma.d.ts +13 -0
  56. package/dist/indicators/sma.d.ts.map +1 -0
  57. package/dist/indicators/sma.js +22 -0
  58. package/dist/indicators/sma.js.map +1 -0
  59. package/dist/indicators/stochastic.d.ts +15 -0
  60. package/dist/indicators/stochastic.d.ts.map +1 -0
  61. package/dist/indicators/stochastic.js +34 -0
  62. package/dist/indicators/stochastic.js.map +1 -0
  63. package/dist/indicators/types.d.ts +102 -0
  64. package/dist/indicators/types.d.ts.map +1 -0
  65. package/dist/indicators/vwap.d.ts +14 -0
  66. package/dist/indicators/vwap.d.ts.map +1 -0
  67. package/dist/indicators/vwap.js +17 -0
  68. package/dist/indicators/vwap.js.map +1 -0
  69. package/dist/indicators/williamsR.d.ts +17 -0
  70. package/dist/indicators/williamsR.d.ts.map +1 -0
  71. package/dist/indicators/williamsR.js +19 -0
  72. package/dist/indicators/williamsR.js.map +1 -0
  73. package/dist/react/FullFeaturedChart.d.ts +3 -0
  74. package/dist/react/FullFeaturedChart.d.ts.map +1 -0
  75. package/dist/react/FullFeaturedChart.js +640 -0
  76. package/dist/react/FullFeaturedChart.js.map +1 -0
  77. package/dist/react/components/IndicatorSettings.d.ts +20 -0
  78. package/dist/react/components/IndicatorSettings.d.ts.map +1 -0
  79. package/dist/react/components/IndicatorSettings.js +748 -0
  80. package/dist/react/components/IndicatorSettings.js.map +1 -0
  81. package/dist/react/hooks/useChart.d.ts +15 -0
  82. package/dist/react/hooks/useChart.d.ts.map +1 -0
  83. package/dist/react/hooks/useChart.js +155 -0
  84. package/dist/react/hooks/useChart.js.map +1 -0
  85. package/dist/react/hooks/useIndicators.d.ts +10 -0
  86. package/dist/react/hooks/useIndicators.d.ts.map +1 -0
  87. package/dist/react/hooks/useIndicators.js +264 -0
  88. package/dist/react/hooks/useIndicators.js.map +1 -0
  89. package/dist/react/hooks/useLineTools.d.ts +26 -0
  90. package/dist/react/hooks/useLineTools.d.ts.map +1 -0
  91. package/dist/react/hooks/useLineTools.js +189 -0
  92. package/dist/react/hooks/useLineTools.js.map +1 -0
  93. package/dist/react/hooks/useShiftSnap.d.ts +12 -0
  94. package/dist/react/hooks/useShiftSnap.d.ts.map +1 -0
  95. package/dist/react/hooks/useShiftSnap.js +54 -0
  96. package/dist/react/hooks/useShiftSnap.js.map +1 -0
  97. package/dist/react/index.d.ts +14 -0
  98. package/dist/react/index.d.ts.map +1 -0
  99. package/dist/react/index.js +18 -0
  100. package/dist/react/index.js.map +1 -0
  101. package/dist/react/loadLightweightCharts.d.ts +18 -0
  102. package/dist/react/loadLightweightCharts.d.ts.map +1 -0
  103. package/dist/react/loadLightweightCharts.js +32 -0
  104. package/dist/react/loadLightweightCharts.js.map +1 -0
  105. package/dist/react/locale.d.ts +79 -0
  106. package/dist/react/locale.d.ts.map +1 -0
  107. package/dist/react/locale.js +158 -0
  108. package/dist/react/locale.js.map +1 -0
  109. package/dist/react/types.d.ts +130 -0
  110. package/dist/react/types.d.ts.map +1 -0
  111. package/dist/types/index.d.ts +24 -0
  112. package/dist/types/index.d.ts.map +1 -0
  113. package/dist/utils/getToolId.d.ts +9 -0
  114. package/dist/utils/getToolId.d.ts.map +1 -0
  115. package/dist/utils/getToolId.js +12 -0
  116. package/dist/utils/getToolId.js.map +1 -0
  117. package/dist/utils/mockData.d.ts +10 -0
  118. package/dist/utils/mockData.d.ts.map +1 -0
  119. package/dist/utils/mockData.js +61 -0
  120. package/dist/utils/mockData.js.map +1 -0
  121. package/dist/utils/snapCrosshair.d.ts +25 -0
  122. package/dist/utils/snapCrosshair.d.ts.map +1 -0
  123. package/dist/utils/validateCandle.d.ts +30 -0
  124. package/dist/utils/validateCandle.d.ts.map +1 -0
  125. package/dist/utils/validateCandle.js +21 -0
  126. package/dist/utils/validateCandle.js.map +1 -0
  127. package/examples/css/base.css +209 -0
  128. package/examples/css/chart.css +282 -0
  129. package/examples/css/indicators.css +255 -0
  130. package/examples/index.html +163 -0
  131. package/examples/js/chart.js +370 -0
  132. package/examples/js/indicators.js +27 -0
  133. package/examples/js/main.js +6 -0
  134. package/examples/js/ui.js +1641 -0
  135. package/lib/lightweight-charts.standalone.production.js +7 -0
  136. package/package.json +106 -0
  137. package/src/react/FullFeaturedChart.css +1007 -0
@@ -0,0 +1,209 @@
1
+ @import url('https://cdn.jsdelivr.net/gh/toss/tossface/dist/tossface.css');
2
+
3
+ .tossface {
4
+ font-family: Tossface;
5
+ }
6
+ * {
7
+ margin: 0;
8
+ padding: 0;
9
+ box-sizing: border-box;
10
+ }
11
+
12
+ body {
13
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
14
+ background: #f5f5f5;
15
+ padding: 20px;
16
+ }
17
+
18
+ .container {
19
+ max-width: 1400px;
20
+ margin: 0 auto;
21
+ background: white;
22
+ border-radius: 8px;
23
+ box-shadow: 0 2px 8px rgba(0,0,0,0.1);
24
+ overflow: hidden;
25
+ }
26
+
27
+ .header {
28
+ padding: 8px 12px;
29
+ border-bottom: 1px solid #e0e0e0;
30
+ background: white;
31
+ display: flex;
32
+ align-items: center;
33
+ justify-content: space-between;
34
+ }
35
+
36
+ .header-left {
37
+ display: flex;
38
+ align-items: center;
39
+ gap: 8px;
40
+ }
41
+
42
+ .header-right {
43
+ display: flex;
44
+ align-items: center;
45
+ gap: 6px;
46
+ }
47
+
48
+ .timeframe-group {
49
+ display: flex;
50
+ gap: 2px;
51
+ background: #f5f5f5;
52
+ padding: 3px;
53
+ border-radius: 6px;
54
+ }
55
+
56
+ .btn-timeframe {
57
+ padding: 4px 10px;
58
+ border: none;
59
+ background: transparent;
60
+ border-radius: 4px;
61
+ cursor: pointer;
62
+ font-size: 13px;
63
+ font-weight: 500;
64
+ color: #666;
65
+ transition: all 0.15s;
66
+ }
67
+
68
+ .btn-timeframe:hover {
69
+ background: #e8e8e8;
70
+ color: #333;
71
+ }
72
+
73
+ .btn-timeframe.active {
74
+ background: white;
75
+ color: #333;
76
+ box-shadow: 0 1px 2px rgba(0,0,0,0.1);
77
+ }
78
+
79
+ .btn-icon {
80
+ width: 32px;
81
+ height: 32px;
82
+ border: none;
83
+ background: transparent;
84
+ border-radius: 4px;
85
+ cursor: pointer;
86
+ display: flex;
87
+ align-items: center;
88
+ justify-content: center;
89
+ color: #666;
90
+ font-size: 16px;
91
+ transition: all 0.15s;
92
+ }
93
+
94
+ .btn-icon:hover {
95
+ background: #f5f5f5;
96
+ color: #333;
97
+ }
98
+
99
+ .btn-icon.active {
100
+ background: #e8f2ff;
101
+ color: #2563eb;
102
+ }
103
+
104
+ .separator {
105
+ width: 1px;
106
+ height: 20px;
107
+ background: #e0e0e0;
108
+ margin: 0 4px;
109
+ }
110
+
111
+ .btn-text {
112
+ padding: 6px 12px;
113
+ border: none;
114
+ background: transparent;
115
+ border-radius: 4px;
116
+ cursor: pointer;
117
+ font-size: 14px;
118
+ font-weight: 500;
119
+ color: #666;
120
+ transition: all 0.15s;
121
+ display: flex;
122
+ align-items: center;
123
+ gap: 4px;
124
+ }
125
+
126
+ .btn-text:hover {
127
+ background: #f5f5f5;
128
+ color: #333;
129
+ }
130
+
131
+ .btn-text.active {
132
+ background: #e8f2ff;
133
+ color: #2563eb;
134
+ }
135
+
136
+ .btn-delete {
137
+ padding: 6px 12px;
138
+ border: none;
139
+ background: #fee;
140
+ border-radius: 4px;
141
+ cursor: pointer;
142
+ font-size: 14px;
143
+ font-weight: 500;
144
+ color: #dc2626;
145
+ transition: all 0.15s;
146
+ }
147
+
148
+ .btn-delete:hover {
149
+ background: #fdd;
150
+ }
151
+
152
+ /* 드롭다운 메뉴 */
153
+ .dropdown {
154
+ position: relative;
155
+ }
156
+
157
+ .dropdown-menu {
158
+ position: absolute;
159
+ top: calc(100% + 4px);
160
+ right: 0;
161
+ background: white;
162
+ border: 1px solid #e0e0e0;
163
+ border-radius: 12px;
164
+ box-shadow: 0 4px 12px rgba(0,0,0,0.15);
165
+ min-width: 200px;
166
+ padding: 8px;
167
+ display: none;
168
+ z-index: 1000;
169
+ }
170
+
171
+ .dropdown-menu.show {
172
+ display: block;
173
+ }
174
+
175
+ #indicatorMenu.show {
176
+ display: flex;
177
+ }
178
+
179
+ .dropdown-item {
180
+ width: 100%;
181
+ padding: 8px 12px;
182
+ border: none;
183
+ background: transparent;
184
+ border-radius: 4px;
185
+ cursor: pointer;
186
+ display: flex;
187
+ align-items: center;
188
+ gap: 8px;
189
+ font-size: 13px;
190
+ color: #333;
191
+ transition: all 0.15s;
192
+ text-align: left;
193
+ }
194
+
195
+ .dropdown-item:hover {
196
+ background: #f5f5f5;
197
+ }
198
+
199
+ .dropdown-item.active {
200
+ background: #e8f2ff;
201
+ color: #2563eb;
202
+ }
203
+
204
+ .item-icon {
205
+ font-size: 16px;
206
+ width: 20px;
207
+ text-align: center;
208
+ }
209
+
@@ -0,0 +1,282 @@
1
+ .modal-overlay {
2
+ position: fixed;
3
+ top: 0;
4
+ left: 0;
5
+ right: 0;
6
+ bottom: 0;
7
+ background: rgba(0, 0, 0, 0.5);
8
+ display: none;
9
+ align-items: center;
10
+ justify-content: center;
11
+ z-index: 10000;
12
+ }
13
+
14
+ .modal-overlay.show {
15
+ display: flex;
16
+ }
17
+
18
+ .modal-content {
19
+ background: white;
20
+ border-radius: 8px;
21
+ padding: 20px;
22
+ min-width: 300px;
23
+ box-shadow: 0 8px 24px rgba(0,0,0,0.2);
24
+ }
25
+
26
+ .modal-title {
27
+ font-size: 16px;
28
+ font-weight: 600;
29
+ margin-bottom: 12px;
30
+ color: #333;
31
+ }
32
+
33
+ .modal-input {
34
+ width: 100%;
35
+ padding: 8px 12px;
36
+ border: 1px solid #ddd;
37
+ border-radius: 6px;
38
+ font-size: 14px;
39
+ margin-bottom: 16px;
40
+ box-sizing: border-box;
41
+ }
42
+
43
+ .modal-input:focus {
44
+ outline: none;
45
+ border-color: #2563eb;
46
+ }
47
+
48
+ .modal-buttons {
49
+ display: flex;
50
+ gap: 8px;
51
+ justify-content: flex-end;
52
+ }
53
+
54
+ .modal-btn {
55
+ padding: 8px 16px;
56
+ border: none;
57
+ border-radius: 6px;
58
+ font-size: 13px;
59
+ font-weight: 500;
60
+ cursor: pointer;
61
+ transition: all 0.15s;
62
+ }
63
+
64
+ .modal-btn-cancel {
65
+ background: #f5f5f5;
66
+ color: #666;
67
+ }
68
+
69
+ .modal-btn-cancel:hover {
70
+ background: #e8e8e8;
71
+ }
72
+
73
+ .modal-btn-confirm {
74
+ background: #2563eb;
75
+ color: white;
76
+ }
77
+
78
+ .modal-btn-confirm:hover {
79
+ background: #1d4ed8;
80
+ }
81
+
82
+ #chart {
83
+ width: 100%;
84
+ height: 600px;
85
+ position: relative;
86
+ }
87
+
88
+ .info {
89
+ padding: 20px;
90
+ border-top: 1px solid #e5e5e5;
91
+ background: #fafafa;
92
+ }
93
+
94
+ .info h3 {
95
+ font-size: 16px;
96
+ margin-bottom: 10px;
97
+ color: #666;
98
+ }
99
+
100
+ .info ul {
101
+ list-style: none;
102
+ padding-left: 0;
103
+ }
104
+
105
+ .info li {
106
+ padding: 4px 0;
107
+ color: #666;
108
+ font-size: 14px;
109
+ }
110
+
111
+ /* Context Menu Styles - Toolbar Style (Light Mode) */
112
+ .context-menu {
113
+ position: absolute;
114
+ background: rgba(255, 255, 255, 0.95);
115
+ backdrop-filter: blur(10px);
116
+ border: 1px solid rgba(0, 0, 0, 0.1);
117
+ border-radius: 8px;
118
+ box-shadow: 0 4px 20px rgba(0,0,0,0.15);
119
+ padding: 6px;
120
+ z-index: 10000;
121
+ display: none;
122
+ gap: 4px;
123
+ flex-direction: row;
124
+ align-items: center;
125
+ cursor: move;
126
+ user-select: none;
127
+ }
128
+
129
+ .context-menu.show {
130
+ display: flex;
131
+ }
132
+
133
+ .context-menu.dragging {
134
+ cursor: grabbing;
135
+ }
136
+
137
+ .context-menu-btn {
138
+ width: 36px;
139
+ height: 36px;
140
+ border: none;
141
+ background: transparent;
142
+ color: #333;
143
+ cursor: pointer;
144
+ border-radius: 6px;
145
+ display: flex;
146
+ align-items: center;
147
+ justify-content: center;
148
+ font-size: 18px;
149
+ transition: all 0.2s;
150
+ position: relative;
151
+ }
152
+
153
+ .context-menu-btn:hover {
154
+ background: rgba(0, 0, 0, 0.05);
155
+ }
156
+
157
+ .context-menu-btn.active {
158
+ background: rgba(59, 130, 246, 0.15);
159
+ color: #2563eb;
160
+ }
161
+
162
+ .context-menu-btn.danger:hover {
163
+ background: rgba(239, 68, 68, 0.1);
164
+ color: #dc2626;
165
+ }
166
+
167
+ .context-menu-separator {
168
+ width: 1px;
169
+ height: 24px;
170
+ background: rgba(0, 0, 0, 0.1);
171
+ margin: 0 4px;
172
+ }
173
+
174
+ /* 선 두께 표시 */
175
+ .width-display {
176
+ min-width: 32px;
177
+ height: 36px;
178
+ display: flex;
179
+ align-items: center;
180
+ justify-content: center;
181
+ font-size: 16px;
182
+ font-weight: bold;
183
+ color: #333;
184
+ background: rgba(0, 0, 0, 0.05);
185
+ border-radius: 6px;
186
+ padding: 0 8px;
187
+ user-select: none;
188
+ }
189
+
190
+ /* 색상 드롭다운 */
191
+ .color-picker-dropdown {
192
+ position: relative;
193
+ }
194
+
195
+ .color-current-btn {
196
+ width: 36px;
197
+ height: 36px;
198
+ border: none;
199
+ background: transparent;
200
+ cursor: pointer;
201
+ border-radius: 6px;
202
+ display: flex;
203
+ align-items: center;
204
+ justify-content: center;
205
+ transition: all 0.2s;
206
+ position: relative;
207
+ padding: 0;
208
+ }
209
+
210
+ .color-current-btn:hover {
211
+ background: rgba(0, 0, 0, 0.05);
212
+ }
213
+
214
+ .color-current-display {
215
+ width: 24px;
216
+ height: 24px;
217
+ border-radius: 4px;
218
+ border: 2px solid rgba(0, 0, 0, 0.2);
219
+ }
220
+
221
+ .color-palette {
222
+ position: absolute;
223
+ top: 100%;
224
+ left: 50%;
225
+ transform: translateX(-50%);
226
+ margin-top: 4px;
227
+ background: rgba(255, 255, 255, 0.95);
228
+ backdrop-filter: blur(10px);
229
+ border: 1px solid rgba(0, 0, 0, 0.1);
230
+ border-radius: 8px;
231
+ padding: 8px;
232
+ display: none;
233
+ gap: 6px;
234
+ flex-wrap: wrap;
235
+ width: 120px;
236
+ box-shadow: 0 4px 12px rgba(0,0,0,0.15);
237
+ z-index: 10002;
238
+ }
239
+
240
+ .color-palette.show {
241
+ display: flex;
242
+ }
243
+
244
+ .color-option {
245
+ width: 28px;
246
+ height: 28px;
247
+ border: 2px solid transparent;
248
+ border-radius: 6px;
249
+ cursor: pointer;
250
+ transition: all 0.2s;
251
+ padding: 0;
252
+ }
253
+
254
+ .color-option:hover {
255
+ transform: scale(1.1);
256
+ box-shadow: 0 2px 8px rgba(0,0,0,0.2);
257
+ }
258
+
259
+ /* Tooltip */
260
+ .context-menu-btn::after,
261
+ .color-current-btn::after {
262
+ content: attr(data-tooltip);
263
+ position: absolute;
264
+ bottom: -32px;
265
+ left: 50%;
266
+ transform: translateX(-50%);
267
+ background: rgba(0, 0, 0, 0.85);
268
+ color: white;
269
+ padding: 4px 8px;
270
+ border-radius: 4px;
271
+ font-size: 11px;
272
+ white-space: nowrap;
273
+ opacity: 0;
274
+ pointer-events: none;
275
+ transition: opacity 0.2s;
276
+ z-index: 10001;
277
+ }
278
+
279
+ .context-menu-btn:hover::after,
280
+ .color-current-btn:hover::after {
281
+ opacity: 1;
282
+ }
@@ -0,0 +1,255 @@
1
+ /* 보조지표 드롭다운 (넓은 버전) */
2
+ #indicatorMenu {
3
+ width: 600px;
4
+ padding: 0;
5
+ max-height: 500px;
6
+ }
7
+
8
+ .indicator-menu-layout {
9
+ display: flex;
10
+ width: 100%;
11
+ height: 100%;
12
+ }
13
+
14
+ .indicator-list-side {
15
+ width: 180px;
16
+ background: #f8f9fa;
17
+ border-right: 1px solid #e0e0e0;
18
+ overflow-y: auto;
19
+ max-height: 500px;
20
+ border-radius: 12px;
21
+ }
22
+
23
+ .indicator-category {
24
+ padding: 12px 16px 8px;
25
+ font-size: 11px;
26
+ font-weight: 600;
27
+ color: #999;
28
+ }
29
+
30
+ .indicator-item {
31
+ display: flex;
32
+ align-items: center;
33
+ justify-content: space-between;
34
+ padding: 10px 16px;
35
+ cursor: pointer;
36
+ font-size: 13px;
37
+ color: #333;
38
+ transition: all 0.15s;
39
+ }
40
+
41
+ .indicator-item:hover {
42
+ background: rgba(0,0,0,0.03);
43
+ }
44
+
45
+ .indicator-item.selected {
46
+ background: white;
47
+ color: #2563eb;
48
+ border-left: 3px solid #2563eb;
49
+ }
50
+
51
+ .indicator-checkbox {
52
+ width: 20px;
53
+ height: 20px;
54
+ border: 2px solid #d0d0d0;
55
+ border-radius: 50%;
56
+ display: flex;
57
+ align-items: center;
58
+ justify-content: center;
59
+ transition: all 0.15s;
60
+ cursor: pointer;
61
+ padding: 4px; /* 클릭 영역 확대 */
62
+ }
63
+
64
+ .indicator-checkbox:hover {
65
+ border-color: #2563eb;
66
+ background: #f0f5ff;
67
+ }
68
+
69
+ .indicator-item.checked .indicator-checkbox {
70
+ background: #2563eb;
71
+ border-color: #2563eb;
72
+ }
73
+
74
+ .indicator-item.checked .indicator-checkbox::after {
75
+ content: '✓';
76
+ color: white;
77
+ font-size: 12px;
78
+ font-weight: bold;
79
+ }
80
+
81
+ .indicator-settings-side {
82
+ flex: 1;
83
+ padding: 16px;
84
+ overflow-y: auto;
85
+ max-height: 500px;
86
+ }
87
+
88
+ .indicator-settings-title {
89
+ font-size: 14px;
90
+ font-weight: 600;
91
+ margin-bottom: 4px;
92
+ }
93
+
94
+ .indicator-settings-desc {
95
+ font-size: 12px;
96
+ color: #666;
97
+ margin-bottom: 16px;
98
+ }
99
+
100
+ .indicator-period-row {
101
+ display: flex;
102
+ align-items: center;
103
+ gap: 8px;
104
+ margin-bottom: 12px;
105
+ }
106
+
107
+ .period-label-col {
108
+ min-width: 60px;
109
+ font-size: 13px;
110
+ color: #666;
111
+ }
112
+
113
+ .period-color-picker {
114
+ width: 60px;
115
+ height: 36px;
116
+ border: 2px solid #e0e0e0;
117
+ border-radius: 6px;
118
+ cursor: pointer;
119
+ transition: all 0.15s;
120
+ }
121
+
122
+ .period-color-picker:hover {
123
+ border-color: #999;
124
+ }
125
+
126
+ .color-palette-popup {
127
+ position: fixed;
128
+ background: white;
129
+ border: 1px solid #e0e0e0;
130
+ border-radius: 8px;
131
+ padding: 12px 20px 12px 12px;
132
+ box-shadow: 0 4px 12px rgba(0,0,0,0.15);
133
+ display: none;
134
+ z-index: 10000;
135
+ width: 280px;
136
+ }
137
+
138
+ .color-palette-popup.show {
139
+ display: block;
140
+ }
141
+
142
+ .color-palette-title {
143
+ font-size: 12px;
144
+ font-weight: 600;
145
+ color: #333;
146
+ margin-bottom: 8px;
147
+ }
148
+
149
+ .color-palette-grid {
150
+ display: grid;
151
+ grid-template-columns: repeat(8, 1fr);
152
+ gap: 4px;
153
+ }
154
+
155
+ .color-palette-item {
156
+ width: 28px;
157
+ height: 28px;
158
+ border-radius: 50%;
159
+ cursor: pointer;
160
+ border: 2px solid transparent;
161
+ transition: all 0.15s;
162
+ }
163
+
164
+ .color-palette-item:hover {
165
+ transform: scale(1.1);
166
+ border-color: #333;
167
+ }
168
+
169
+ .color-palette-item.selected {
170
+ border-color: #2563eb;
171
+ box-shadow: 0 0 0 2px rgba(37, 99, 235, 0.2);
172
+ }
173
+
174
+ .period-thickness-display {
175
+ width: 60px;
176
+ height: 36px;
177
+ border: 1px solid #e0e0e0;
178
+ border-radius: 6px;
179
+ display: flex;
180
+ align-items: center;
181
+ justify-content: center;
182
+ font-size: 13px;
183
+ background: white;
184
+ cursor: pointer;
185
+ }
186
+
187
+ .period-source-dropdown {
188
+ width: 90px;
189
+ height: 36px;
190
+ padding: 0 8px;
191
+ border: 1px solid #e0e0e0;
192
+ border-radius: 6px;
193
+ font-size: 13px;
194
+ background: white;
195
+ cursor: pointer;
196
+ }
197
+
198
+ .period-value-field {
199
+ width: 80px;
200
+ height: 36px;
201
+ padding: 0 8px;
202
+ border: 1px solid #e0e0e0;
203
+ border-radius: 6px;
204
+ font-size: 13px;
205
+ text-align: center;
206
+ }
207
+
208
+ .period-delete-btn {
209
+ width: 32px;
210
+ height: 32px;
211
+ border: none;
212
+ background: transparent;
213
+ border-radius: 6px;
214
+ cursor: pointer;
215
+ font-size: 18px;
216
+ color: #999;
217
+ transition: all 0.15s;
218
+ }
219
+
220
+ .period-delete-btn:hover {
221
+ background: rgba(239, 68, 68, 0.1);
222
+ color: #dc2626;
223
+ }
224
+
225
+ .add-period-button {
226
+ width: 100%;
227
+ padding: 10px;
228
+ border: 2px dashed #e0e0e0;
229
+ background: transparent;
230
+ border-radius: 6px;
231
+ cursor: pointer;
232
+ font-size: 13px;
233
+ color: #666;
234
+ display: flex;
235
+ align-items: center;
236
+ justify-content: center;
237
+ gap: 6px;
238
+ transition: all 0.15s;
239
+ margin-top: 8px;
240
+ }
241
+
242
+ .add-period-button:hover {
243
+ border-color: #2563eb;
244
+ color: #2563eb;
245
+ }
246
+
247
+ .indicator-empty-state {
248
+ text-align: center;
249
+ padding: 40px 20px;
250
+ color: #999;
251
+ font-size: 13px;
252
+ }
253
+
254
+
255
+ /* 커스텀 텍스트 입력 모달 */