openfree commited on
Commit
56ee7d4
·
verified ·
1 Parent(s): db25cd8

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +686 -19
index.html CHANGED
@@ -1,19 +1,686 @@
1
- <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
19
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="ko">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>AI SaaS 구축 방식 비교 분석</title>
7
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.9.1/chart.min.js"></script>
8
+ <style>
9
+ * {
10
+ margin: 0;
11
+ padding: 0;
12
+ box-sizing: border-box;
13
+ }
14
+
15
+ body {
16
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
17
+ background: linear-gradient(135deg, #0f0c29 0%, #302b63 50%, #24243e 100%);
18
+ color: #ffffff;
19
+ min-height: 100vh;
20
+ overflow-x: hidden;
21
+ }
22
+
23
+ .container {
24
+ max-width: 1400px;
25
+ margin: 0 auto;
26
+ padding: 2rem;
27
+ }
28
+
29
+ header {
30
+ text-align: center;
31
+ margin-bottom: 3rem;
32
+ animation: fadeInDown 0.8s ease-out;
33
+ }
34
+
35
+ h1 {
36
+ font-size: 3rem;
37
+ margin-bottom: 1rem;
38
+ background: linear-gradient(45deg, #00d2ff, #3a7bd5, #00d2ff);
39
+ background-size: 200% auto;
40
+ -webkit-background-clip: text;
41
+ -webkit-text-fill-color: transparent;
42
+ animation: gradient 3s ease infinite;
43
+ }
44
+
45
+ @keyframes gradient {
46
+ 0% { background-position: 0% 50%; }
47
+ 50% { background-position: 100% 50%; }
48
+ 100% { background-position: 0% 50%; }
49
+ }
50
+
51
+ .subtitle {
52
+ font-size: 1.2rem;
53
+ color: #a8a8b3;
54
+ }
55
+
56
+ .methods-grid {
57
+ display: grid;
58
+ grid-template-columns: repeat(auto-fit, minmax(350px, 1fr));
59
+ gap: 2rem;
60
+ margin-bottom: 3rem;
61
+ }
62
+
63
+ .method-card {
64
+ background: rgba(255, 255, 255, 0.05);
65
+ backdrop-filter: blur(10px);
66
+ border: 1px solid rgba(255, 255, 255, 0.1);
67
+ border-radius: 20px;
68
+ padding: 2rem;
69
+ transition: all 0.3s ease;
70
+ animation: fadeInUp 0.8s ease-out;
71
+ position: relative;
72
+ overflow: hidden;
73
+ }
74
+
75
+ .method-card::before {
76
+ content: '';
77
+ position: absolute;
78
+ top: -50%;
79
+ left: -50%;
80
+ width: 200%;
81
+ height: 200%;
82
+ background: radial-gradient(circle, rgba(58, 123, 213, 0.1) 0%, transparent 70%);
83
+ opacity: 0;
84
+ transition: opacity 0.3s ease;
85
+ }
86
+
87
+ .method-card:hover::before {
88
+ opacity: 1;
89
+ }
90
+
91
+ .method-card:hover {
92
+ transform: translateY(-10px);
93
+ box-shadow: 0 20px 40px rgba(0, 0, 0, 0.3);
94
+ border-color: rgba(58, 123, 213, 0.5);
95
+ }
96
+
97
+ .method-header {
98
+ display: flex;
99
+ align-items: center;
100
+ margin-bottom: 1.5rem;
101
+ }
102
+
103
+ .method-icon {
104
+ width: 60px;
105
+ height: 60px;
106
+ margin-right: 1rem;
107
+ display: flex;
108
+ align-items: center;
109
+ justify-content: center;
110
+ border-radius: 15px;
111
+ font-size: 2rem;
112
+ }
113
+
114
+ .outsource-icon { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); }
115
+ .inhouse-icon { background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%); }
116
+ .platform-icon { background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%); }
117
+
118
+ .method-title {
119
+ font-size: 1.5rem;
120
+ font-weight: 700;
121
+ }
122
+
123
+ .method-description {
124
+ color: #a8a8b3;
125
+ margin-bottom: 1.5rem;
126
+ line-height: 1.6;
127
+ }
128
+
129
+ .cost-breakdown {
130
+ background: rgba(0, 0, 0, 0.2);
131
+ border-radius: 10px;
132
+ padding: 1rem;
133
+ margin-bottom: 1.5rem;
134
+ }
135
+
136
+ .cost-item {
137
+ display: flex;
138
+ justify-content: space-between;
139
+ margin-bottom: 0.5rem;
140
+ padding: 0.5rem 0;
141
+ border-bottom: 1px solid rgba(255, 255, 255, 0.05);
142
+ }
143
+
144
+ .cost-item:last-child {
145
+ border-bottom: none;
146
+ }
147
+
148
+ .pros-cons {
149
+ display: grid;
150
+ grid-template-columns: 1fr 1fr;
151
+ gap: 1rem;
152
+ margin-top: 1.5rem;
153
+ }
154
+
155
+ .pros, .cons {
156
+ padding: 1rem;
157
+ border-radius: 10px;
158
+ font-size: 0.9rem;
159
+ }
160
+
161
+ .pros {
162
+ background: rgba(46, 213, 115, 0.1);
163
+ border: 1px solid rgba(46, 213, 115, 0.3);
164
+ }
165
+
166
+ .cons {
167
+ background: rgba(255, 71, 87, 0.1);
168
+ border: 1px solid rgba(255, 71, 87, 0.3);
169
+ }
170
+
171
+ .pros h4, .cons h4 {
172
+ margin-bottom: 0.5rem;
173
+ font-size: 1rem;
174
+ }
175
+
176
+ .pros ul, .cons ul {
177
+ list-style: none;
178
+ padding-left: 0;
179
+ }
180
+
181
+ .pros li::before {
182
+ content: "✓ ";
183
+ color: #2ed573;
184
+ font-weight: bold;
185
+ }
186
+
187
+ .cons li::before {
188
+ content: "✗ ";
189
+ color: #ff4757;
190
+ font-weight: bold;
191
+ }
192
+
193
+ .calculator-section {
194
+ background: rgba(255, 255, 255, 0.05);
195
+ backdrop-filter: blur(10px);
196
+ border: 1px solid rgba(255, 255, 255, 0.1);
197
+ border-radius: 20px;
198
+ padding: 2rem;
199
+ margin-bottom: 3rem;
200
+ animation: fadeInUp 1s ease-out;
201
+ }
202
+
203
+ .calculator-title {
204
+ font-size: 2rem;
205
+ margin-bottom: 2rem;
206
+ text-align: center;
207
+ }
208
+
209
+ .input-group {
210
+ display: grid;
211
+ grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
212
+ gap: 1.5rem;
213
+ margin-bottom: 2rem;
214
+ }
215
+
216
+ .input-field {
217
+ display: flex;
218
+ flex-direction: column;
219
+ }
220
+
221
+ .input-field label {
222
+ margin-bottom: 0.5rem;
223
+ color: #a8a8b3;
224
+ font-size: 0.9rem;
225
+ }
226
+
227
+ .input-field input, .input-field select {
228
+ background: rgba(255, 255, 255, 0.1);
229
+ border: 1px solid rgba(255, 255, 255, 0.2);
230
+ border-radius: 10px;
231
+ padding: 0.75rem 1rem;
232
+ color: #ffffff;
233
+ font-size: 1rem;
234
+ transition: all 0.3s ease;
235
+ }
236
+
237
+ .input-field input:focus, .input-field select:focus {
238
+ outline: none;
239
+ border-color: #3a7bd5;
240
+ background: rgba(255, 255, 255, 0.15);
241
+ }
242
+
243
+ .input-field select option {
244
+ background: #24243e;
245
+ }
246
+
247
+ .calculate-btn {
248
+ background: linear-gradient(45deg, #00d2ff, #3a7bd5);
249
+ border: none;
250
+ border-radius: 10px;
251
+ padding: 1rem 2rem;
252
+ font-size: 1.1rem;
253
+ font-weight: 600;
254
+ color: #ffffff;
255
+ cursor: pointer;
256
+ transition: all 0.3s ease;
257
+ display: block;
258
+ margin: 0 auto;
259
+ }
260
+
261
+ .calculate-btn:hover {
262
+ transform: translateY(-2px);
263
+ box-shadow: 0 10px 20px rgba(58, 123, 213, 0.3);
264
+ }
265
+
266
+ .results-section {
267
+ margin-top: 3rem;
268
+ display: none;
269
+ }
270
+
271
+ .results-grid {
272
+ display: grid;
273
+ grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
274
+ gap: 2rem;
275
+ margin-bottom: 2rem;
276
+ }
277
+
278
+ .result-card {
279
+ background: rgba(0, 0, 0, 0.3);
280
+ border-radius: 15px;
281
+ padding: 1.5rem;
282
+ text-align: center;
283
+ }
284
+
285
+ .result-value {
286
+ font-size: 2.5rem;
287
+ font-weight: 700;
288
+ margin: 1rem 0;
289
+ background: linear-gradient(45deg, #00d2ff, #3a7bd5);
290
+ -webkit-background-clip: text;
291
+ -webkit-text-fill-color: transparent;
292
+ }
293
+
294
+ .chart-container {
295
+ position: relative;
296
+ height: 400px;
297
+ background: rgba(0, 0, 0, 0.3);
298
+ border-radius: 15px;
299
+ padding: 1.5rem;
300
+ margin-top: 2rem;
301
+ }
302
+
303
+ @keyframes fadeInDown {
304
+ from {
305
+ opacity: 0;
306
+ transform: translateY(-30px);
307
+ }
308
+ to {
309
+ opacity: 1;
310
+ transform: translateY(0);
311
+ }
312
+ }
313
+
314
+ @keyframes fadeInUp {
315
+ from {
316
+ opacity: 0;
317
+ transform: translateY(30px);
318
+ }
319
+ to {
320
+ opacity: 1;
321
+ transform: translateY(0);
322
+ }
323
+ }
324
+
325
+ @media (max-width: 768px) {
326
+ h1 {
327
+ font-size: 2rem;
328
+ }
329
+
330
+ .methods-grid {
331
+ grid-template-columns: 1fr;
332
+ }
333
+
334
+ .pros-cons {
335
+ grid-template-columns: 1fr;
336
+ }
337
+ }
338
+ </style>
339
+ </head>
340
+ <body>
341
+ <div class="container">
342
+ <header>
343
+ <h1>AI SaaS 구축 방식 비교 분석</h1>
344
+ <p class="subtitle">최적의 개발 방식을 선택하기 위한 종합 가이드</p>
345
+ </header>
346
+
347
+ <div class="methods-grid">
348
+ <!-- 외주 용역 ��발 방식 -->
349
+ <div class="method-card">
350
+ <div class="method-header">
351
+ <div class="method-icon outsource-icon">🤝</div>
352
+ <h2 class="method-title">외주 용역 개발</h2>
353
+ </div>
354
+ <p class="method-description">
355
+ 전문 개발사에 프로젝트를 위탁하여 AI SaaS를 구축하는 방식
356
+ </p>
357
+ <div class="cost-breakdown">
358
+ <div class="cost-item">
359
+ <span>초기 비용</span>
360
+ <span>₩50M - ₩200M</span>
361
+ </div>
362
+ <div class="cost-item">
363
+ <span>개발 기간</span>
364
+ <span>3 - 6개월</span>
365
+ </div>
366
+ <div class="cost-item">
367
+ <span>유지보수</span>
368
+ <span>월 ₩5M - ₩15M</span>
369
+ </div>
370
+ </div>
371
+ <div class="pros-cons">
372
+ <div class="pros">
373
+ <h4>장점</h4>
374
+ <ul>
375
+ <li>빠른 개발 착수</li>
376
+ <li>전문성 활용</li>
377
+ <li>인력 관리 부담 없음</li>
378
+ </ul>
379
+ </div>
380
+ <div class="cons">
381
+ <h4>단점</h4>
382
+ <ul>
383
+ <li>높은 비용</li>
384
+ <li>커스터마이징 제한</li>
385
+ <li>의존성 문제</li>
386
+ </ul>
387
+ </div>
388
+ </div>
389
+ </div>
390
+
391
+ <!-- 자체 인력 개발 방식 -->
392
+ <div class="method-card">
393
+ <div class="method-header">
394
+ <div class="method-icon inhouse-icon">👥</div>
395
+ <h2 class="method-title">자체 인력 개발</h2>
396
+ </div>
397
+ <p class="method-description">
398
+ 내부 개발팀을 구성하여 직접 AI SaaS를 개발하는 방식
399
+ </p>
400
+ <div class="cost-breakdown">
401
+ <div class="cost-item">
402
+ <span>초기 비용</span>
403
+ <span>₩30M - ₩100M</span>
404
+ </div>
405
+ <div class="cost-item">
406
+ <span>개발 기간</span>
407
+ <span>6 - 12개월</span>
408
+ </div>
409
+ <div class="cost-item">
410
+ <span>운영 비용</span>
411
+ <span>월 ₩20M - ₩50M</span>
412
+ </div>
413
+ </div>
414
+ <div class="pros-cons">
415
+ <div class="pros">
416
+ <h4>장점</h4>
417
+ <ul>
418
+ <li>완전한 통제권</li>
419
+ <li>장기적 비용 효율</li>
420
+ <li>기술 내재화</li>
421
+ </ul>
422
+ </div>
423
+ <div class="cons">
424
+ <h4>단점</h4>
425
+ <ul>
426
+ <li>채용 어려움</li>
427
+ <li>긴 개발 기간</li>
428
+ <li>높은 운영 비용</li>
429
+ </ul>
430
+ </div>
431
+ </div>
432
+ </div>
433
+
434
+ <!-- V-Platform 방식 -->
435
+ <div class="method-card">
436
+ <div class="method-header">
437
+ <div class="method-icon platform-icon">🚀</div>
438
+ <h2 class="method-title">V-Platform</h2>
439
+ </div>
440
+ <p class="method-description">
441
+ 기존 플랫폼을 활용하여 빠르게 AI SaaS를 구축하는 방식
442
+ </p>
443
+ <div class="cost-breakdown">
444
+ <div class="cost-item">
445
+ <span>초기 비용</span>
446
+ <span>₩10M - ₩50M</span>
447
+ </div>
448
+ <div class="cost-item">
449
+ <span>개발 기간</span>
450
+ <span>1 - 3개월</span>
451
+ </div>
452
+ <div class="cost-item">
453
+ <span>구독료</span>
454
+ <span>월 ₩2M - ₩10M</span>
455
+ </div>
456
+ </div>
457
+ <div class="pros-cons">
458
+ <div class="pros">
459
+ <h4>장점</h4>
460
+ <ul>
461
+ <li>빠른 시장 진입</li>
462
+ <li>낮은 초기 비용</li>
463
+ <li>검증된 기술</li>
464
+ </ul>
465
+ </div>
466
+ <div class="cons">
467
+ <h4>단점</h4>
468
+ <ul>
469
+ <li>제한된 커스터마이징</li>
470
+ <li>플랫폼 종속성</li>
471
+ <li>차별화 어려움</li>
472
+ </ul>
473
+ </div>
474
+ </div>
475
+ </div>
476
+ </div>
477
+
478
+ <!-- 비용 계산기 섹션 -->
479
+ <div class="calculator-section">
480
+ <h2 class="calculator-title">비용 시뮬레이터</h2>
481
+ <div class="input-group">
482
+ <div class="input-field">
483
+ <label for="projectScale">프로젝트 규모</label>
484
+ <select id="projectScale">
485
+ <option value="small">소규모 (MVP)</option>
486
+ <option value="medium">중규모</option>
487
+ <option value="large">대규모</option>
488
+ </select>
489
+ </div>
490
+ <div class="input-field">
491
+ <label for="duration">운영 기간 (개월)</label>
492
+ <input type="number" id="duration" value="12" min="1" max="60">
493
+ </div>
494
+ <div class="input-field">
495
+ <label for="users">예상 사용자 수</label>
496
+ <input type="number" id="users" value="1000" min="100" max="1000000">
497
+ </div>
498
+ <div class="input-field">
499
+ <label for="features">AI 기능 복잡도</label>
500
+ <select id="features">
501
+ <option value="basic">기본 (챗봇, 번역)</option>
502
+ <option value="advanced">고급 (이미지 생성, 분석)</option>
503
+ <option value="enterprise">엔터프라이즈 (맞춤형 모델)</option>
504
+ </select>
505
+ </div>
506
+ </div>
507
+ <button class="calculate-btn" onclick="calculateCosts()">비용 계산하기</button>
508
+
509
+ <div class="results-section" id="results">
510
+ <div class="results-grid">
511
+ <div class="result-card">
512
+ <h3>외주 용역 총 비용</h3>
513
+ <div class="result-value" id="outsourceCost">₩0</div>
514
+ <p>초기 + 운영 비용</p>
515
+ </div>
516
+ <div class="result-card">
517
+ <h3>자체 인력 총 비용</h3>
518
+ <div class="result-value" id="inhouseCost">₩0</div>
519
+ <p>인건비 + 인프라</p>
520
+ </div>
521
+ <div class="result-card">
522
+ <h3>V-Platform 총 비용</h3>
523
+ <div class="result-value" id="platformCost">₩0</div>
524
+ <p>라이선스 + API</p>
525
+ </div>
526
+ </div>
527
+ <div class="chart-container">
528
+ <canvas id="costChart"></canvas>
529
+ </div>
530
+ </div>
531
+ </div>
532
+ </div>
533
+
534
+ <script>
535
+ let costChart = null;
536
+
537
+ function calculateCosts() {
538
+ const scale = document.getElementById('projectScale').value;
539
+ const duration = parseInt(document.getElementById('duration').value);
540
+ const users = parseInt(document.getElementById('users').value);
541
+ const features = document.getElementById('features').value;
542
+
543
+ // 기본 비용 설정
544
+ const baseCosts = {
545
+ outsource: {
546
+ small: { initial: 50, monthly: 5 },
547
+ medium: { initial: 100, monthly: 10 },
548
+ large: { initial: 200, monthly: 15 }
549
+ },
550
+ inhouse: {
551
+ small: { initial: 30, monthly: 20 },
552
+ medium: { initial: 60, monthly: 35 },
553
+ large: { initial: 100, monthly: 50 }
554
+ },
555
+ platform: {
556
+ small: { initial: 10, monthly: 2 },
557
+ medium: { initial: 30, monthly: 5 },
558
+ large: { initial: 50, monthly: 10 }
559
+ }
560
+ };
561
+
562
+ // 복잡도에 따른 가중치
563
+ const complexityMultiplier = {
564
+ basic: 1,
565
+ advanced: 1.5,
566
+ enterprise: 2
567
+ };
568
+
569
+ // 사용자 수에 따른 추가 비용
570
+ const userCostFactor = Math.log10(users) / 3;
571
+
572
+ // 비용 계산
573
+ const multiplier = complexityMultiplier[features] * userCostFactor;
574
+
575
+ const outsourceCost = baseCosts.outsource[scale].initial +
576
+ (baseCosts.outsource[scale].monthly * duration * multiplier);
577
+ const inhouseCost = baseCosts.inhouse[scale].initial +
578
+ (baseCosts.inhouse[scale].monthly * duration * multiplier);
579
+ const platformCost = baseCosts.platform[scale].initial +
580
+ (baseCosts.platform[scale].monthly * duration * multiplier);
581
+
582
+ // 결과 표시
583
+ document.getElementById('outsourceCost').textContent = `₩${Math.round(outsourceCost)}M`;
584
+ document.getElementById('inhouseCost').textContent = `₩${Math.round(inhouseCost)}M`;
585
+ document.getElementById('platformCost').textContent = `₩${Math.round(platformCost)}M`;
586
+ document.getElementById('results').style.display = 'block';
587
+
588
+ // 차트 그리기
589
+ drawChart(duration, baseCosts[scale], multiplier);
590
+ }
591
+
592
+ function drawChart(duration, costs, multiplier) {
593
+ const ctx = document.getElementById('costChart').getContext('2d');
594
+
595
+ if (costChart) {
596
+ costChart.destroy();
597
+ }
598
+
599
+ const months = Array.from({length: duration}, (_, i) => i + 1);
600
+
601
+ costChart = new Chart(ctx, {
602
+ type: 'line',
603
+ data: {
604
+ labels: months.map(m => `${m}개월`),
605
+ datasets: [
606
+ {
607
+ label: '외주 용역',
608
+ data: months.map(m => costs.outsource.initial + (costs.outsource.monthly * m * multiplier)),
609
+ borderColor: '#764ba2',
610
+ backgroundColor: 'rgba(118, 75, 162, 0.1)',
611
+ tension: 0.4
612
+ },
613
+ {
614
+ label: '자체 인력',
615
+ data: months.map(m => costs.inhouse.initial + (costs.inhouse.monthly * m * multiplier)),
616
+ borderColor: '#f5576c',
617
+ backgroundColor: 'rgba(245, 87, 108, 0.1)',
618
+ tension: 0.4
619
+ },
620
+ {
621
+ label: 'V-Platform',
622
+ data: months.map(m => costs.platform.initial + (costs.platform.monthly * m * multiplier)),
623
+ borderColor: '#00f2fe',
624
+ backgroundColor: 'rgba(0, 242, 254, 0.1)',
625
+ tension: 0.4
626
+ }
627
+ ]
628
+ },
629
+ options: {
630
+ responsive: true,
631
+ maintainAspectRatio: false,
632
+ plugins: {
633
+ title: {
634
+ display: true,
635
+ text: '시간에 따른 누적 비용 추이',
636
+ color: '#ffffff',
637
+ font: {
638
+ size: 16
639
+ }
640
+ },
641
+ legend: {
642
+ labels: {
643
+ color: '#ffffff'
644
+ }
645
+ }
646
+ },
647
+ scales: {
648
+ x: {
649
+ grid: {
650
+ color: 'rgba(255, 255, 255, 0.1)'
651
+ },
652
+ ticks: {
653
+ color: '#ffffff'
654
+ }
655
+ },
656
+ y: {
657
+ grid: {
658
+ color: 'rgba(255, 255, 255, 0.1)'
659
+ },
660
+ ticks: {
661
+ color: '#ffffff',
662
+ callback: function(value) {
663
+ return '₩' + value + 'M';
664
+ }
665
+ }
666
+ }
667
+ }
668
+ }
669
+ });
670
+ }
671
+
672
+ // 애니메이션 효과를 위한 Intersection Observer
673
+ const observer = new IntersectionObserver((entries) => {
674
+ entries.forEach(entry => {
675
+ if (entry.isIntersecting) {
676
+ entry.target.style.animation = 'fadeInUp 0.8s ease-out forwards';
677
+ }
678
+ });
679
+ });
680
+
681
+ document.querySelectorAll('.method-card').forEach(card => {
682
+ observer.observe(card);
683
+ });
684
+ </script>
685
+ </body>
686
+ </html>