AI-Calcurator / index.html
openfree's picture
Update index.html
1eaa353 verified
raw
history blame
77 kB
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>AI SAAS Build Calculator</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.9.1/chart.min.js"></script>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
background: linear-gradient(135deg, #0f0c29 0%, #302b63 50%, #24243e 100%);
color: #ffffff;
min-height: 100vh;
overflow-x: hidden;
}
.container {
max-width: 1400px;
margin: 0 auto;
padding: 2rem;
}
header {
text-align: center;
margin-bottom: 3rem;
animation: fadeInDown 0.8s ease-out;
}
h1 {
font-size: 3rem;
margin-bottom: 1rem;
background: linear-gradient(45deg, #00d2ff, #3a7bd5, #00d2ff);
background-size: 200% auto;
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
animation: gradient 3s ease infinite;
}
@keyframes gradient {
0% { background-position: 0% 50%; }
50% { background-position: 100% 50%; }
100% { background-position: 0% 50%; }
}
.subtitle {
font-size: 1.2rem;
color: #a8a8b3;
}
.tabs {
display: flex;
justify-content: center;
margin-bottom: 3rem;
background: rgba(255, 255, 255, 0.05);
backdrop-filter: blur(10px);
border-radius: 15px;
padding: 0.5rem;
gap: 0.5rem;
}
.tab {
padding: 1rem 2rem;
background: transparent;
border: none;
color: #a8a8b3;
cursor: pointer;
border-radius: 10px;
transition: all 0.3s ease;
font-size: 1.1rem;
font-weight: 500;
}
.tab.active {
background: linear-gradient(45deg, #00d2ff, #3a7bd5);
color: #ffffff;
transform: scale(1.05);
}
.tab:hover:not(.active) {
background: rgba(255, 255, 255, 0.1);
color: #ffffff;
}
.tab-content {
display: none;
}
.tab-content.active {
display: block;
animation: fadeIn 0.5s ease;
}
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
.methods-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(350px, 1fr));
gap: 2rem;
margin-bottom: 3rem;
}
.method-card {
background: rgba(255, 255, 255, 0.05);
backdrop-filter: blur(10px);
border: 1px solid rgba(255, 255, 255, 0.1);
border-radius: 20px;
padding: 2rem;
transition: all 0.3s ease;
animation: fadeInUp 0.8s ease-out;
position: relative;
overflow: hidden;
}
.method-card::before {
content: '';
position: absolute;
top: -50%;
left: -50%;
width: 200%;
height: 200%;
background: radial-gradient(circle, rgba(58, 123, 213, 0.1) 0%, transparent 70%);
opacity: 0;
transition: opacity 0.3s ease;
}
.method-card:hover::before {
opacity: 1;
}
.method-card:hover {
transform: translateY(-10px);
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.3);
border-color: rgba(58, 123, 213, 0.5);
}
.method-header {
display: flex;
align-items: center;
margin-bottom: 1.5rem;
}
.method-icon {
width: 60px;
height: 60px;
margin-right: 1rem;
display: flex;
align-items: center;
justify-content: center;
border-radius: 15px;
font-size: 2rem;
}
.outsource-icon { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); }
.inhouse-icon { background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%); }
.platform-icon { background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%); }
.method-title {
font-size: 1.5rem;
font-weight: 700;
}
.method-description {
color: #a8a8b3;
margin-bottom: 1.5rem;
line-height: 1.6;
}
.cost-breakdown {
background: rgba(0, 0, 0, 0.2);
border-radius: 10px;
padding: 1rem;
margin-bottom: 1.5rem;
}
.cost-item {
display: flex;
justify-content: space-between;
margin-bottom: 0.5rem;
padding: 0.5rem 0;
border-bottom: 1px solid rgba(255, 255, 255, 0.05);
}
.cost-item:last-child {
border-bottom: none;
}
.pros-cons {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 1rem;
margin-top: 1.5rem;
}
.pros, .cons {
padding: 1rem;
border-radius: 10px;
font-size: 0.9rem;
}
.pros {
background: rgba(46, 213, 115, 0.1);
border: 1px solid rgba(46, 213, 115, 0.3);
}
.cons {
background: rgba(255, 71, 87, 0.1);
border: 1px solid rgba(255, 71, 87, 0.3);
}
.pros h4, .cons h4 {
margin-bottom: 0.5rem;
font-size: 1rem;
}
.pros ul, .cons ul {
list-style: none;
padding-left: 0;
}
.pros li::before {
content: "โœ“ ";
color: #2ed573;
font-weight: bold;
}
.cons li::before {
content: "โœ— ";
color: #ff4757;
font-weight: bold;
}
.calculator-section {
background: rgba(255, 255, 255, 0.05);
backdrop-filter: blur(10px);
border: 1px solid rgba(255, 255, 255, 0.1);
border-radius: 20px;
padding: 2rem;
margin-bottom: 3rem;
animation: fadeInUp 1s ease-out;
}
.calculator-title {
font-size: 2rem;
margin-bottom: 2rem;
text-align: center;
}
.input-group {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 1.5rem;
margin-bottom: 2rem;
}
.input-field {
display: flex;
flex-direction: column;
}
.input-field label {
margin-bottom: 0.5rem;
color: #a8a8b3;
font-size: 0.9rem;
}
.input-field input, .input-field select {
background: rgba(255, 255, 255, 0.1);
border: 1px solid rgba(255, 255, 255, 0.2);
border-radius: 10px;
padding: 0.75rem 1rem;
color: #ffffff;
font-size: 1rem;
transition: all 0.3s ease;
}
.input-field input:focus, .input-field select:focus {
outline: none;
border-color: #3a7bd5;
background: rgba(255, 255, 255, 0.15);
}
.input-field select option {
background: #24243e;
}
.calculate-btn {
background: linear-gradient(45deg, #00d2ff, #3a7bd5);
border: none;
border-radius: 10px;
padding: 1rem 2rem;
font-size: 1.1rem;
font-weight: 600;
color: #ffffff;
cursor: pointer;
transition: all 0.3s ease;
display: block;
margin: 0 auto;
}
.calculate-btn:hover {
transform: translateY(-2px);
box-shadow: 0 10px 20px rgba(58, 123, 213, 0.3);
}
.results-section {
margin-top: 3rem;
display: none;
}
.results-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 2rem;
margin-bottom: 2rem;
}
.result-card {
background: rgba(0, 0, 0, 0.3);
border-radius: 15px;
padding: 1.5rem;
text-align: center;
}
.result-value {
font-size: 2.5rem;
font-weight: 700;
margin: 1rem 0;
background: linear-gradient(45deg, #00d2ff, #3a7bd5);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
.chart-container {
position: relative;
height: 400px;
background: rgba(0, 0, 0, 0.3);
border-radius: 15px;
padding: 1.5rem;
margin-top: 2rem;
}
/* ๋งž์ถค ์„ค๊ณ„ ์Šคํƒ€์ผ */
.custom-design-container {
background: rgba(255, 255, 255, 0.05);
backdrop-filter: blur(10px);
border: 1px solid rgba(255, 255, 255, 0.1);
border-radius: 20px;
padding: 2rem;
}
.component-section {
margin-bottom: 2.5rem;
}
.component-title {
font-size: 1.3rem;
margin-bottom: 1rem;
display: flex;
align-items: center;
gap: 0.5rem;
}
.component-icon {
width: 30px;
height: 30px;
background: linear-gradient(45deg, #00d2ff, #3a7bd5);
border-radius: 8px;
display: flex;
align-items: center;
justify-content: center;
font-size: 1.2rem;
}
.component-options {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
gap: 1rem;
}
.option-card {
background: rgba(255, 255, 255, 0.05);
border: 2px solid rgba(255, 255, 255, 0.2);
border-radius: 10px;
padding: 1rem;
cursor: pointer;
transition: all 0.3s ease;
position: relative;
overflow: hidden;
}
.option-card.selected {
background: rgba(58, 123, 213, 0.3);
border-color: #3a7bd5;
transform: scale(1.05);
box-shadow: 0 5px 20px rgba(58, 123, 213, 0.3);
}
.option-card.selected::after {
content: 'โœ“';
position: absolute;
top: 0.5rem;
right: 0.5rem;
background: #3a7bd5;
color: white;
width: 25px;
height: 25px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-weight: bold;
}
.option-card:hover {
border-color: #00d2ff;
background: rgba(255, 255, 255, 0.1);
transform: translateY(-2px);
}
.option-name {
font-weight: 600;
margin-bottom: 0.5rem;
}
.option-details {
display: flex;
justify-content: space-between;
font-size: 0.9rem;
color: #a8a8b3;
}
.custom-result {
background: rgba(0, 0, 0, 0.3);
border-radius: 15px;
padding: 2rem;
margin-top: 2rem;
display: none;
}
.result-header {
text-align: center;
margin-bottom: 2rem;
}
.result-header h3 {
font-size: 1.8rem;
margin-bottom: 0.5rem;
color: #00d2ff;
}
.period-tabs {
display: flex;
justify-content: center;
gap: 1rem;
margin-bottom: 2rem;
}
.period-tab {
padding: 0.5rem 1.5rem;
background: rgba(255, 255, 255, 0.1);
border: 1px solid rgba(255, 255, 255, 0.2);
border-radius: 20px;
cursor: pointer;
transition: all 0.3s ease;
}
.period-tab.active {
background: linear-gradient(45deg, #00d2ff, #3a7bd5);
border-color: transparent;
}
.custom-summary {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 2rem;
margin-bottom: 2rem;
}
.summary-item {
text-align: center;
}
.summary-label {
color: #a8a8b3;
margin-bottom: 0.5rem;
}
.summary-value {
font-size: 2rem;
font-weight: 700;
background: linear-gradient(45deg, #00d2ff, #3a7bd5);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
.selected-components {
background: rgba(255, 255, 255, 0.05);
border-radius: 10px;
padding: 1.5rem;
margin-bottom: 1.5rem;
}
.selected-components h4 {
margin-bottom: 1rem;
font-size: 1.2rem;
}
.component-list {
display: grid;
gap: 0.5rem;
}
.component-list-item {
display: flex;
justify-content: space-between;
padding: 0.75rem;
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
background: rgba(255, 255, 255, 0.02);
border-radius: 5px;
}
.component-list-item:last-child {
border-bottom: none;
}
.monthly-breakdown {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
gap: 1rem;
margin-top: 1rem;
}
.monthly-item {
background: rgba(255, 255, 255, 0.05);
padding: 1rem;
border-radius: 10px;
text-align: center;
}
.monthly-label {
font-size: 0.9rem;
color: #a8a8b3;
margin-bottom: 0.5rem;
}
.monthly-value {
font-size: 1.2rem;
font-weight: 600;
color: #00d2ff;
}
.build-method-comparison {
margin-top: 2rem;
}
.comparison-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 1.5rem;
}
.comparison-card {
background: rgba(118, 75, 162, 0.1);
border: 1px solid rgba(118, 75, 162, 0.3);
padding: 1.5rem;
border-radius: 10px;
}
.comparison-card h5 {
color: #764ba2;
margin-bottom: 1rem;
}
.comparison-item {
display: flex;
justify-content: space-between;
margin-bottom: 0.5rem;
}
.periodDisplay {
color: #00d2ff;
}
@keyframes fadeInDown {
from {
opacity: 0;
transform: translateY(-30px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
@keyframes fadeInUp {
from {
opacity: 0;
transform: translateY(30px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
@media (max-width: 768px) {
h1 {
font-size: 2rem;
}
.methods-grid {
grid-template-columns: 1fr;
}
.pros-cons {
grid-template-columns: 1fr;
}
.tabs {
flex-direction: column;
}
.tab {
width: 100%;
}
}
</style>
</head>
<body>
<div class="container">
<header>
<h1>AI SAAS Build Calculator</h1>
<p class="subtitle">์ตœ์ ์˜ AI ์„œ๋น„์Šค ๊ตฌ์ถ• ๋ฐฉ์‹์„ ์ฐพ์•„๋“œ๋ฆฝ๋‹ˆ๋‹ค</p>
</header>
<div class="tabs">
<button class="tab active" onclick="switchTab('custom')">AI SaaS ๋งž์ถค ์„ค๊ณ„ ๊ณ„์‚ฐ๊ธฐ</button>
</div>
<!-- AI SaaS ๋งž์ถค ์„ค๊ณ„ ํƒญ -->
<div id="custom" class="tab-content active">
<div class="custom-design-container">
<h2 class="calculator-title">๋‚˜๋งŒ์˜ AI SaaS ๋งž์ถค ์„ค๊ณ„</h2>
<!-- ํƒ€๊นƒ ์„œ๋น„์Šค ์œ ํ˜• -->
<div class="component-section">
<div class="component-title">
<div class="component-icon">๐ŸŽฏ</div>
<span>ํƒ€๊นƒ ์„œ๋น„์Šค ์œ ํ˜• (ํ•„์ˆ˜, ๋ณต์ˆ˜ ์„ ํƒ ๊ฐ€๋Šฅ)</span>
</div>
<!-- AI ์ด๋ฏธ์ง€ ๊ด€๋ จ -->
<h4 style="color: #00d2ff; margin: 1.5rem 0 1rem 0;">๐Ÿ–ผ๏ธ AI ์ด๋ฏธ์ง€ ๊ด€๋ จ</h4>
<div class="component-options" style="margin-bottom: 2rem;">
<div class="option-card" data-category="service" data-id="image-gen" data-cost="5" data-time="1" data-resource="0.7">
<div class="option-name">AI ์ด๋ฏธ์ง€ ์ƒ์„ฑ</div>
<div class="option-details">
<span>$5K</span>
<span>1๊ฐœ์›”</span>
</div>
</div>
<div class="option-card" data-category="service" data-id="book-cover" data-cost="7" data-time="1" data-resource="0.7">
<div class="option-name">์ฑ… ํ‘œ์ง€ AI ์ƒ์„ฑ</div>
<div class="option-details">
<span>$7K</span>
<span>1๊ฐœ์›”</span>
</div>
</div>
<div class="option-card" data-category="service" data-id="bg-removal" data-cost="7" data-time="1" data-resource="0.7">
<div class="option-name">๋ฐฐ๊ฒฝ ์ œ๊ฑฐ ๋ฐ ์ƒ์„ฑ</div>
<div class="option-details">
<span>$7K</span>
<span>1๊ฐœ์›”</span>
</div>
</div>
<div class="option-card" data-category="service" data-id="image-enhance" data-cost="7" data-time="1" data-resource="1.4">
<div class="option-name">AI ์ด๋ฏธ์ง€ ํŽธ์ง‘/ํ–ฅ์ƒ</div>
<div class="option-details">
<span>$7K</span>
<span>1๊ฐœ์›”</span>
</div>
</div>
<div class="option-card" data-category="service" data-id="image-upscale" data-cost="7" data-time="1" data-resource="1.4">
<div class="option-name">์ด๋ฏธ์ง€ ์—…์Šค์ผ€์ผ๋ง</div>
<div class="option-details">
<span>$7K</span>
<span>1๊ฐœ์›”</span>
</div>
</div>
<div class="option-card" data-category="service" data-id="image-custom" data-cost="50" data-time="1" data-resource="20">
<div class="option-name">์ด๋ฏธ์ง€ ์—”ํ„ฐํ”„๋ผ์ด์ฆˆ ์ปค์Šคํ…€</div>
<div class="option-details">
<span>$50K</span>
<span>1๊ฐœ์›”</span>
</div>
</div>
</div>
<!-- AI ๋น„๋””์˜ค ๊ด€๋ จ -->
<h4 style="color: #00d2ff; margin: 1.5rem 0 1rem 0;">๐ŸŽฅ AI ๋น„๋””์˜ค ๊ด€๋ จ</h4>
<div class="component-options" style="margin-bottom: 2rem;">
<div class="option-card" data-category="service" data-id="video-gen" data-cost="20" data-time="1" data-resource="10">
<div class="option-name">AI ๋น„๋””์˜ค ์ƒ์„ฑ</div>
<div class="option-details">
<span>$20K</span>
<span>1๊ฐœ์›”</span>
</div>
</div>
<div class="option-card" data-category="service" data-id="video-edit" data-cost="20" data-time="1" data-resource="10">
<div class="option-name">AI ๋น„๋””์˜ค ํŽธ์ง‘</div>
<div class="option-details">
<span>$20K</span>
<span>1๊ฐœ์›”</span>
</div>
</div>
<div class="option-card" data-category="service" data-id="avatar-video" data-cost="20" data-time="1" data-resource="10">
<div class="option-name">AI ์•„๋ฐ”ํƒ€ ๋น„๋””์˜ค</div>
<div class="option-details">
<span>$20K</span>
<span>1๊ฐœ์›”</span>
</div>
</div>
<div class="option-card" data-category="service" data-id="auto-subtitle" data-cost="7" data-time="1" data-resource="0.7">
<div class="option-name">์ž๋™ ์ž๋ง‰ ์ƒ์„ฑ</div>
<div class="option-details">
<span>$7K</span>
<span>1๊ฐœ์›”</span>
</div>
</div>
<div class="option-card" data-category="service" data-id="shortform" data-cost="20" data-time="1" data-resource="100">
<div class="option-name">AI ์ˆํผ ๋น„๋””์˜ค</div>
<div class="option-details">
<span>$20K</span>
<span>1๊ฐœ์›”</span>
</div>
</div>
<div class="option-card" data-category="service" data-id="video-custom" data-cost="50" data-time="1" data-resource="20">
<div class="option-name">๋น„๋””์˜ค ์—”ํ„ฐํ”„๋ผ์ด์ฆˆ ์ปค์Šคํ…€</div>
<div class="option-details">
<span>$50K</span>
<span>1๊ฐœ์›”</span>
</div>
</div>
</div>
<!-- AI ์˜ค๋””์˜ค ๊ด€๋ จ -->
<h4 style="color: #00d2ff; margin: 1.5rem 0 1rem 0;">๐ŸŽต AI ์˜ค๋””์˜ค ๊ด€๋ จ</h4>
<div class="component-options" style="margin-bottom: 2rem;">
<div class="option-card" data-category="service" data-id="sound-gen" data-cost="5" data-time="1" data-resource="0.7">
<div class="option-name">AI ์Œํ–ฅ ์ƒ์„ฑ</div>
<div class="option-details">
<span>$5K</span>
<span>1๊ฐœ์›”</span>
</div>
</div>
<div class="option-card" data-category="service" data-id="music-gen" data-cost="5" data-time="1" data-resource="1.4">
<div class="option-name">AI ์Œ์•… ์ƒ์„ฑ</div>
<div class="option-details">
<span>$5K</span>
<span>1๊ฐœ์›”</span>
</div>
</div>
<div class="option-card" data-category="service" data-id="song-gen" data-cost="5" data-time="1" data-resource="1.5">
<div class="option-name">AI ๋…ธ๋ž˜ ์ƒ์„ฑ (์Œ์•…+๊ฐ€์‚ฌ+๋ณด์ปฌ)</div>
<div class="option-details">
<span>$5K</span>
<span>1๊ฐœ์›”</span>
</div>
</div>
<div class="option-card" data-category="service" data-id="music-video" data-cost="5" data-time="1" data-resource="12">
<div class="option-name">AI ๋ฎค์ง๋น„๋””์˜ค ์ƒ์„ฑ</div>
<div class="option-details">
<span>$5K</span>
<span>1๊ฐœ์›”</span>
</div>
</div>
<div class="option-card" data-category="service" data-id="ai-singer" data-cost="30" data-time="1" data-resource="20">
<div class="option-name">AI ๊ฐ€์ˆ˜ ์ƒ์„ฑ (ํ’€ํŒจํ‚ค์ง€)</div>
<div class="option-details">
<span>$30K</span>
<span>1๊ฐœ์›”</span>
</div>
</div>
<div class="option-card" data-category="service" data-id="voice-clone" data-cost="5" data-time="1" data-resource="2.5">
<div class="option-name">์Œ์„ฑ ๋ณต์ œ/ํ•ฉ์„ฑ</div>
<div class="option-details">
<span>$5K</span>
<span>1๊ฐœ์›”</span>
</div>
</div>
<div class="option-card" data-category="service" data-id="tts" data-cost="5" data-time="1" data-resource="1.4">
<div class="option-name">ํ…์ŠคํŠธ TO ์Œ์„ฑ ๋ณ€ํ™˜</div>
<div class="option-details">
<span>$5K</span>
<span>1๊ฐœ์›”</span>
</div>
</div>
<div class="option-card" data-category="service" data-id="stt" data-cost="5" data-time="1" data-resource="3">
<div class="option-name">์Œ์„ฑ TO ํ…์ŠคํŠธ ๋ณ€ํ™˜</div>
<div class="option-details">
<span>$5K</span>
<span>1๊ฐœ์›”</span>
</div>
</div>
<div class="option-card" data-category="service" data-id="podcast" data-cost="5" data-time="1" data-resource="3">
<div class="option-name">AI ํŒŸ์บ์ŠคํŠธ ์ œ์ž‘</div>
<div class="option-details">
<span>$5K</span>
<span>1๊ฐœ์›”</span>
</div>
</div>
<div class="option-card" data-category="service" data-id="audio-custom" data-cost="50" data-time="1" data-resource="20">
<div class="option-name">์˜ค๋””์˜ค ์—”ํ„ฐํ”„๋ผ์ด์ฆˆ ์ปค์Šคํ…€</div>
<div class="option-details">
<span>$50K</span>
<span>1๊ฐœ์›”</span>
</div>
</div>
</div>
<!-- AI ํ…์ŠคํŠธ ๊ด€๋ จ -->
<h4 style="color: #00d2ff; margin: 1.5rem 0 1rem 0;">๐Ÿ’ฌ AI ํ…์ŠคํŠธ ๊ด€๋ จ</h4>
<div class="component-options" style="margin-bottom: 2rem;">
<div class="option-card" data-category="service" data-id="chatbot-text" data-cost="5" data-time="1" data-resource="0.7">
<div class="option-name">AI ์ฑ—๋ด‡ (ํ…์ŠคํŠธ)</div>
<div class="option-details">
<span>$5K</span>
<span>1๊ฐœ์›”</span>
</div>
</div>
<div class="option-card" data-category="service" data-id="chatbot-rag" data-cost="5" data-time="1" data-resource="1.4">
<div class="option-name">AI ์ฑ—๋ด‡ (ํ…์ŠคํŠธ+RAG)</div>
<div class="option-details">
<span>$5K</span>
<span>1๊ฐœ์›”</span>
</div>
</div>
<div class="option-card" data-category="service" data-id="chatbot-voice" data-cost="5" data-time="1" data-resource="1.5">
<div class="option-name">AI ์ฑ—๋ด‡ (ํ…์ŠคํŠธ+์Œ์„ฑ)</div>
<div class="option-details">
<span>$5K</span>
<span>1๊ฐœ์›”</span>
</div>
</div>
<div class="option-card" data-category="service" data-id="chatbot-full" data-cost="5" data-time="1" data-resource="3">
<div class="option-name">AI ์ฑ—๋ด‡ (ํ…์ŠคํŠธ+์Œ์„ฑ+RAG)</div>
<div class="option-details">
<span>$5K</span>
<span>1๊ฐœ์›”</span>
</div>
</div>
<div class="option-card" data-category="service" data-id="translation" data-cost="5" data-time="1" data-resource="0.7">
<div class="option-name">AI ๋ฒˆ์—ญ ์„œ๋น„์Šค</div>
<div class="option-details">
<span>$5K</span>
<span>1๊ฐœ์›”</span>
</div>
</div>
<div class="option-card" data-category="service" data-id="email-writing" data-cost="5" data-time="1" data-resource="0.7">
<div class="option-name">AI ์ด๋ฉ”์ผ/๋ฌธ์„œ ์ž‘์„ฑ</div>
<div class="option-details">
<span>$5K</span>
<span>1๊ฐœ์›”</span>
</div>
</div>
<div class="option-card" data-category="service" data-id="code-assistant" data-cost="5" data-time="1" data-resource="0.7">
<div class="option-name">AI ์ฝ”๋“œ ์–ด์‹œ์Šคํ„ดํŠธ</div>
<div class="option-details">
<span>$5K</span>
<span>1๊ฐœ์›”</span>
</div>
</div>
<div class="option-card" data-category="service" data-id="text-custom" data-cost="50" data-time="1" data-resource="20">
<div class="option-name">ํ…์ŠคํŠธ ์—”ํ„ฐํ”„๋ผ์ด์ฆˆ ์ปค์Šคํ…€</div>
<div class="option-details">
<span>$50K</span>
<span>1๊ฐœ์›”</span>
</div>
</div>
</div>
<!-- AI ๋ถ„์„ ๋„๊ตฌ -->
<h4 style="color: #00d2ff; margin: 1.5rem 0 1rem 0;">๐Ÿ“Š AI ๋ถ„์„ ๋„๊ตฌ</h4>
<div class="component-options" style="margin-bottom: 2rem;">
<div class="option-card" data-category="service" data-id="data-analysis" data-cost="5" data-time="1" data-resource="0.7">
<div class="option-name">AI ๋ฐ์ดํ„ฐ ๋ถ„์„</div>
<div class="option-details">
<span>$5K</span>
<span>1๊ฐœ์›”</span>
</div>
</div>
<div class="option-card" data-category="service" data-id="ocr" data-cost="5" data-time="1" data-resource="2">
<div class="option-name">AI OCR ์„œ๋น„์Šค</div>
<div class="option-details">
<span>$5K</span>
<span>1๊ฐœ์›”</span>
</div>
</div>
<div class="option-card" data-category="service" data-id="computer-vision" data-cost="5" data-time="1" data-resource="1.4">
<div class="option-name">์ปดํ“จํ„ฐ ๋น„์ „</div>
<div class="option-details">
<span>$5K</span>
<span>1๊ฐœ์›”</span>
</div>
</div>
<div class="option-card" data-category="service" data-id="sentiment-analysis" data-cost="5" data-time="1" data-resource="0.7">
<div class="option-name">๊ฐ์ • ๋ถ„์„ AI</div>
<div class="option-details">
<span>$5K</span>
<span>1๊ฐœ์›”</span>
</div>
</div>
<div class="option-card" data-category="service" data-id="analysis-custom" data-cost="50" data-time="1" data-resource="20">
<div class="option-name">๋ถ„์„ ์—”ํ„ฐํ”„๋ผ์ด์ฆˆ ์ปค์Šคํ…€</div>
<div class="option-details">
<span>$50K</span>
<span>1๊ฐœ์›”</span>
</div>
</div>
</div>
<!-- AI ์ฝ˜ํ…์ธ  ์ƒ์„ฑ -->
<h4 style="color: #00d2ff; margin: 1.5rem 0 1rem 0;">๐Ÿ“ AI ์ฝ˜ํ…์ธ  ์ƒ์„ฑ</h4>
<div class="component-options" style="margin-bottom: 2rem;">
<div class="option-card" data-category="service" data-id="novel" data-cost="20" data-time="1" data-resource="20">
<div class="option-name">AI ์†Œ์„ค ์ƒ์„ฑ</div>
<div class="option-details">
<span>$20K</span>
<span>1๊ฐœ์›”</span>
</div>
</div>
<div class="option-card" data-category="service" data-id="webnovel" data-cost="20" data-time="1" data-resource="20">
<div class="option-name">AI ์›น์†Œ์„ค ์ƒ์„ฑ</div>
<div class="option-details">
<span>$20K</span>
<span>1๊ฐœ์›”</span>
</div>
</div>
<div class="option-card" data-category="service" data-id="webtoon" data-cost="20" data-time="1" data-resource="20">
<div class="option-name">AI ์›นํˆฐ ์ƒ์„ฑ</div>
<div class="option-details">
<span>$20K</span>
<span>1๊ฐœ์›”</span>
</div>
</div>
<div class="option-card" data-category="service" data-id="ai-book" data-cost="20" data-time="1" data-resource="2">
<div class="option-name">AI BOOK ์ œ์ž‘</div>
<div class="option-details">
<span>$20K</span>
<span>1๊ฐœ์›”</span>
</div>
</div>
<div class="option-card" data-category="service" data-id="ecommerce" data-cost="20" data-time="1" data-resource="20">
<div class="option-name">์ด์ปค๋จธ์Šค AI (์ƒํ’ˆ์„ค๋ช…)</div>
<div class="option-details">
<span>$20K</span>
<span>1๊ฐœ์›”</span>
</div>
</div>
</div>
<!-- AI ์ „๋ฌธ ์„œ๋น„์Šค -->
<h4 style="color: #00d2ff; margin: 1.5rem 0 1rem 0;">โš•๏ธ AI ์ „๋ฌธ ์„œ๋น„์Šค</h4>
<div class="component-options" style="margin-bottom: 2rem;">
<div class="option-card" data-category="service" data-id="medical" data-cost="20" data-time="1" data-resource="5">
<div class="option-name">AI ์˜๋ฃŒ ์–ด์‹œ์Šคํ„ดํŠธ</div>
<div class="option-details">
<span>$20K</span>
<span>1๊ฐœ์›”</span>
</div>
</div>
<div class="option-card" data-category="service" data-id="legal" data-cost="20" data-time="1" data-resource="5">
<div class="option-name">AI ๋ฒ•๋ฅ  ์–ด์‹œ์Šคํ„ดํŠธ</div>
<div class="option-details">
<span>$20K</span>
<span>1๊ฐœ์›”</span>
</div>
</div>
<div class="option-card" data-category="service" data-id="education" data-cost="20" data-time="1" data-resource="5">
<div class="option-name">AI ๊ต์œก/ํŠœํ„ฐ๋ง</div>
<div class="option-details">
<span>$20K</span>
<span>1๊ฐœ์›”</span>
</div>
</div>
</div>
<!-- AI ์‹œ๋ฎฌ๋ ˆ์ด์…˜ -->
<h4 style="color: #00d2ff; margin: 1.5rem 0 1rem 0;">๐ŸŽญ AI ์‹œ๋ฎฌ๋ ˆ์ด์…˜</h4>
<div class="component-options" style="margin-bottom: 2rem;">
<div class="option-card" data-category="service" data-id="hairstyle" data-cost="20" data-time="1" data-resource="1.2">
<div class="option-name">ํ—ค์–ด์Šคํƒ€์ผ AI ์‹œ๋ฎฌ๋ ˆ์ด์…˜</div>
<div class="option-details">
<span>$20K</span>
<span>1๊ฐœ์›”</span>
</div>
</div>
<div class="option-card" data-category="service" data-id="fashion" data-cost="7" data-time="1" data-resource="0.7">
<div class="option-name">ํŒจ์…˜ ๊ฐ€์ƒ ํ”ผํŒ… AI</div>
<div class="option-details">
<span>$7K</span>
<span>1๊ฐœ์›”</span>
</div>
</div>
<div class="option-card" data-category="service" data-id="3d-model" data-cost="20" data-time="1" data-resource="2">
<div class="option-name">AI 3D ๋ชจ๋ธ ์ƒ์„ฑ</div>
<div class="option-details">
<span>$20K</span>
<span>1๊ฐœ์›”</span>
</div>
</div>
<div class="option-card" data-category="service" data-id="nsfw" data-cost="20" data-time="1" data-resource="0.7">
<div class="option-name">NSFW ์ด๋ฏธ์ง€ ์ƒ์„ฑ</div>
<div class="option-details">
<span>$20K</span>
<span>1๊ฐœ์›”</span>
</div>
</div>
</div>
<!-- ์ปค์Šคํ…€ ๋ชจ๋ธ -->
<h4 style="color: #00d2ff; margin: 1.5rem 0 1rem 0;">๐Ÿ”ง ์ปค์Šคํ…€ ๋ชจ๋ธ</h4>
<div class="component-options" style="margin-bottom: 2rem;">
<div class="option-card" data-category="service" data-id="llm-finetune" data-cost="200" data-time="1" data-resource="20">
<div class="option-name">๋ชจ๋ธ: LLM(ํŒŒ์ธํŠœ๋‹)</div>
<div class="option-details">
<span>$200K</span>
<span>1๊ฐœ์›”</span>
</div>
</div>
<div class="option-card" data-category="service" data-id="image-lora" data-cost="50" data-time="1" data-resource="20">
<div class="option-name">๋ชจ๋ธ: ์ด๋ฏธ์ง€ ์ƒ์„ฑ(LoRA)</div>
<div class="option-details">
<span>$50K</span>
<span>1๊ฐœ์›”</span>
</div>
</div>
<div class="option-card" data-category="service" data-id="gen-lora" data-cost="50" data-time="1" data-resource="20">
<div class="option-name">๋ชจ๋ธ: ์ƒ์„ฑ(LoRA)</div>
<div class="option-details">
<span>$50K</span>
<span>1๊ฐœ์›”</span>
</div>
</div>
<div class="option-card" data-category="service" data-id="vision-model" data-cost="50" data-time="1" data-resource="20">
<div class="option-name">๋ชจ๋ธ: ๋น„์ „์ธ์‹</div>
<div class="option-details">
<span>$50K</span>
<span>1๊ฐœ์›”</span>
</div>
</div>
<div class="option-card" data-category="service" data-id="custom-model" data-cost="50" data-time="1" data-resource="20">
<div class="option-name">๋งž์ถค ์ฃผ๋ฌธํ˜• ๋ชจ๋ธ</div>
<div class="option-details">
<span>$50K</span>
<span>1๊ฐœ์›”</span>
</div>
</div>
</div>
</div>
<!-- DB ๊ด€๋ฆฌ -->
<div class="component-section">
<div class="component-title">
<div class="component-icon">๐Ÿ’พ</div>
<span>DB ๊ด€๋ฆฌ</span>
</div>
<div class="component-options">
<div class="option-card" data-category="db" data-id="basic-db" data-cost="3" data-time="0.5">
<div class="option-name">๊ธฐ๋ณธ DB</div>
<div class="option-details">
<span>$3K</span>
<span>0.5๊ฐœ์›”</span>
</div>
</div>
<div class="option-card" data-category="db" data-id="advanced-db" data-cost="8" data-time="1">
<div class="option-name">๊ณ ๊ธ‰ DB + ๋ฐฑ์—…</div>
<div class="option-details">
<span>$8K</span>
<span>1๊ฐœ์›”</span>
</div>
</div>
<div class="option-card" data-category="db" data-id="enterprise-db" data-cost="12" data-time="1.5">
<div class="option-name">์—”ํ„ฐํ”„๋ผ์ด์ฆˆ DB</div>
<div class="option-details">
<span>$12K</span>
<span>1.5๊ฐœ์›”</span>
</div>
</div>
</div>
</div>
<!-- ํšŒ์›๊ฐ€์ž… ๋ฐ ๋กœ๊ทธ์ธ -->
<div class="component-section">
<div class="component-title">
<div class="component-icon">๐Ÿ”</div>
<span>ํšŒ์›๊ฐ€์ž… ๋ฐ ๋กœ๊ทธ์ธ</span>
</div>
<div class="component-options">
<div class="option-card" data-category="auth" data-id="gmail-only" data-cost="2" data-time="0.3">
<div class="option-name">Gmail ์—ฐ๋™</div>
<div class="option-details">
<span>$2K</span>
<span>0.3๊ฐœ์›”</span>
</div>
</div>
<div class="option-card" data-category="auth" data-id="multi-auth" data-cost="4" data-time="0.5">
<div class="option-name">๋‹ค์ค‘ ์†Œ์…œ ๋กœ๊ทธ์ธ</div>
<div class="option-details">
<span>$4K</span>
<span>0.5๊ฐœ์›”</span>
</div>
</div>
<div class="option-card" data-category="auth" data-id="custom-auth" data-cost="6" data-time="1">
<div class="option-name">์ปค์Šคํ…€ ์ธ์ฆ ์‹œ์Šคํ…œ</div>
<div class="option-details">
<span>$6K</span>
<span>1๊ฐœ์›”</span>
</div>
</div>
</div>
</div>
<!-- ํฌ๋ ˆ๋”ง ๊ด€๋ฆฌ -->
<div class="component-section">
<div class="component-title">
<div class="component-icon">๐Ÿ’ฐ</div>
<span>ํฌ๋ ˆ๋”ง ๊ด€๋ฆฌ</span>
</div>
<div class="component-options">
<div class="option-card" data-category="credit" data-id="basic-credit" data-cost="3" data-time="0.5">
<div class="option-name">๊ธฐ๋ณธ ํฌ๋ ˆ๋”ง ์‹œ์Šคํ…œ</div>
<div class="option-details">
<span>$3K</span>
<span>0.5๊ฐœ์›”</span>
</div>
</div>
<div class="option-card" data-category="credit" data-id="advanced-credit" data-cost="6" data-time="1">
<div class="option-name">๊ณ ๊ธ‰ ํฌ๋ ˆ๋”ง + ๊ตฌ๋…</div>
<div class="option-details">
<span>$6K</span>
<span>1๊ฐœ์›”</span>
</div>
</div>
</div>
</div>
<!-- ํŽ˜์ด๋จผํŠธ ์ง€์› -->
<div class="component-section">
<div class="component-title">
<div class="component-icon">๐Ÿ’ณ</div>
<span>ํŽ˜์ด๋จผํŠธ ์ง€์›</span>
</div>
<div class="component-options">
<div class="option-card" data-category="payment" data-id="basic-payment" data-cost="4" data-time="0.5">
<div class="option-name">๊ธฐ๋ณธ ๊ฒฐ์ œ (์นด๋“œ)</div>
<div class="option-details">
<span>$4K</span>
<span>0.5๊ฐœ์›”</span>
</div>
</div>
<div class="option-card" data-category="payment" data-id="multi-payment" data-cost="8" data-time="1">
<div class="option-name">๋‹ค์ค‘ ๊ฒฐ์ œ ์ˆ˜๋‹จ</div>
<div class="option-details">
<span>$8K</span>
<span>1๊ฐœ์›”</span>
</div>
</div>
<div class="option-card" data-category="payment" data-id="global-payment" data-cost="10" data-time="1.5">
<div class="option-name">๊ธ€๋กœ๋ฒŒ ๊ฒฐ์ œ ์‹œ์Šคํ…œ</div>
<div class="option-details">
<span>$10K</span>
<span>1.5๊ฐœ์›”</span>
</div>
</div>
</div>
</div>
<!-- ๋งˆ์ผ€ํŒ… ์ง€์› -->
<div class="component-section">
<div class="component-title">
<div class="component-icon">๐Ÿ“ข</div>
<span>๋งˆ์ผ€ํŒ… ์ง€์›</span>
</div>
<div class="component-options">
<div class="option-card" data-category="marketing" data-id="basic-marketing" data-cost="5" data-time="1">
<div class="option-name">๊ธฐ๋ณธ ๋งˆ์ผ€ํŒ… ๋„๊ตฌ</div>
<div class="option-details">
<span>$5K</span>
<span>1๊ฐœ์›”</span>
</div>
</div>
<div class="option-card" data-category="marketing" data-id="advanced-marketing" data-cost="10" data-time="1.5">
<div class="option-name">๊ณ ๊ธ‰ ๋งˆ์ผ€ํŒ… ์ž๋™ํ™”</div>
<div class="option-details">
<span>$10K</span>
<span>1.5๊ฐœ์›”</span>
</div>
</div>
</div>
</div>
<!-- ๊ฐœ๋ฐœ ๋ฐ ๊ธฐ์ˆ  ์ธ๋ ฅ ์ง€์› -->
<div class="component-section">
<div class="component-title">
<div class="component-icon">๐Ÿ‘จโ€๐Ÿ’ป</div>
<span>๊ฐœ๋ฐœ ๋ฐ ๊ธฐ์ˆ  ์ธ๋ ฅ ์ง€์›</span>
</div>
<div class="component-options">
<div class="option-card" data-category="support" data-id="basic-support" data-cost="3" data-time="0">
<div class="option-name">๊ธฐ๋ณธ ๊ธฐ์ˆ  ์ง€์›</div>
<div class="option-details">
<span>์›” $3K</span>
<span>์ฆ‰์‹œ</span>
</div>
</div>
<div class="option-card" data-category="support" data-id="dedicated-support" data-cost="8" data-time="0">
<div class="option-name">์ „๋‹ด ๊ฐœ๋ฐœ์ž ์ง€์›</div>
<div class="option-details">
<span>์›” $8K</span>
<span>์ฆ‰์‹œ</span>
</div>
</div>
</div>
</div>
<!-- ์›๊ฒฉ ๋ชจ๋‹ˆํ„ฐ๋ง ์ง€์› -->
<div class="component-section">
<div class="component-title">
<div class="component-icon">๐Ÿ“Š</div>
<span>์›๊ฒฉ ๋ชจ๋‹ˆํ„ฐ๋ง ์ง€์›</span>
</div>
<div class="component-options">
<div class="option-card" data-category="monitoring" data-id="basic-monitor" data-cost="2" data-time="0.3">
<div class="option-name">๊ธฐ๋ณธ ๋ชจ๋‹ˆํ„ฐ๋ง</div>
<div class="option-details">
<span>$2K</span>
<span>0.3๊ฐœ์›”</span>
</div>
</div>
<div class="option-card" data-category="monitoring" data-id="advanced-monitor" data-cost="4" data-time="0.5">
<div class="option-name">๊ณ ๊ธ‰ ๋ถ„์„ + ์•Œ๋ฆผ</div>
<div class="option-details">
<span>$4K</span>
<span>0.5๊ฐœ์›”</span>
</div>
</div>
</div>
</div>
<!-- ์ถ”๊ฐ€ ๊ตฌ์„ฑ ์š”์†Œ -->
<div class="component-section">
<div class="component-title">
<div class="component-icon">๐Ÿ”ง</div>
<span>์ถ”๊ฐ€ ๊ธฐ๋Šฅ (๋ณต์ˆ˜ ์„ ํƒ ๊ฐ€๋Šฅ)</span>
</div>
<div class="component-options">
<div class="option-card" data-category="additional" data-id="admin-panel" data-cost="5" data-time="0.5">
<div class="option-name">๊ด€๋ฆฌ์ž ๋Œ€์‹œ๋ณด๋“œ</div>
<div class="option-details">
<span>$5K</span>
<span>0.5๊ฐœ์›”</span>
</div>
</div>
<div class="option-card" data-category="additional" data-id="api-system" data-cost="8" data-time="1">
<div class="option-name">API ์‹œ์Šคํ…œ</div>
<div class="option-details">
<span>$8K</span>
<span>1๊ฐœ์›”</span>
</div>
</div>
<div class="option-card" data-category="additional" data-id="analytics" data-cost="6" data-time="0.5">
<div class="option-name">๋ถ„์„ ๋„๊ตฌ</div>
<div class="option-details">
<span>$6K</span>
<span>0.5๊ฐœ์›”</span>
</div>
</div>
<div class="option-card" data-category="additional" data-id="multi-language" data-cost="4" data-time="0.5">
<div class="option-name">๋‹ค๊ตญ์–ด ์ง€์›</div>
<div class="option-details">
<span>$4K</span>
<span>0.5๊ฐœ์›”</span>
</div>
</div>
</div>
</div>
<button class="calculate-btn" onclick="calculateCustomCost()">๋งž์ถค ๊ฒฌ์  ๊ณ„์‚ฐํ•˜๊ธฐ</button>
<div class="custom-result" id="customResult">
<div class="result-header">
<h3>๋งž์ถค AI SaaS ๊ฒฌ์ ์„œ</h3>
<p>์„ ํƒํ•˜์‹  ๊ตฌ์„ฑ์œผ๋กœ ์‚ฐ์ถœ๋œ ์ƒ์„ธ ๊ฒฌ์ ์ž…๋‹ˆ๋‹ค</p>
</div>
<div class="custom-summary">
<div class="summary-item">
<div class="summary-label">์ดˆ๊ธฐ ๊ฐœ๋ฐœ ๋น„์šฉ</div>
<div class="summary-value" id="initialCost">$0K</div>
</div>
<div class="summary-item">
<div class="summary-label">์˜ˆ์ƒ ๊ฐœ๋ฐœ ๊ธฐ๊ฐ„</div>
<div class="summary-value" id="devTime">0๊ฐœ์›”</div>
</div>
<div class="summary-item">
<div class="summary-label">์ด ๋น„์šฉ (<span id="periodText">3</span>๊ฐœ์›”)</div>
<div class="summary-value" id="totalCost">$0K</div>
</div>
</div>
<div class="selected-components">
<h4>์„ ํƒํ•œ ๊ตฌ์„ฑ ์š”์†Œ ์ƒ์„ธ</h4>
<div class="component-list" id="componentList"></div>
</div>
<div class="monthly-breakdown">
<div class="monthly-item">
<div class="monthly-label">์›” ์„œ๋ฒ„ ๋น„์šฉ</div>
<div class="monthly-value" id="serverCost">$0K</div>
</div>
<div class="monthly-item">
<div class="monthly-label">์›” ๋ฆฌ์†Œ์Šค ๋น„์šฉ (GPU/API)</div>
<div class="monthly-value" id="resourceCost">$0K</div>
</div>
<div class="monthly-item">
<div class="monthly-label">์›” ์œ ์ง€๋ณด์ˆ˜</div>
<div class="monthly-value" id="maintenanceCost">$0K</div>
</div>
<div class="monthly-item">
<div class="monthly-label">์›” ์ด ์šด์˜๋น„</div>
<div class="monthly-value" id="totalMonthlyCost">$0K</div>
</div>
</div>
<!-- ๊ตฌ์ถ• ๋ฐฉ์‹๋ณ„ ๋น„๊ต -->
<div class="build-method-comparison" style="margin-top: 2rem;">
<h4 style="margin-bottom: 1.5rem; color: #00d2ff;">๊ตฌ์ถ• ๋ฐฉ์‹๋ณ„ ๋น„๊ต</h4>
<div class="comparison-grid" style="display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); gap: 1.5rem;">
<div class="comparison-card" style="background: rgba(118, 75, 162, 0.1); border: 1px solid rgba(118, 75, 162, 0.3); padding: 1.5rem; border-radius: 10px;">
<h5 style="color: #764ba2; margin-bottom: 1rem;">์™ธ์ฃผ ์šฉ์—ญ ๊ฐœ๋ฐœ</h5>
<div class="comparison-item" style="display: flex; justify-content: space-between; margin-bottom: 0.5rem;">
<span>์ดˆ๊ธฐ ๋น„์šฉ</span>
<span id="outsourceInitial">$0K</span>
</div>
<div class="comparison-item" style="display: flex; justify-content: space-between; margin-bottom: 0.5rem;">
<span>์›” ์šด์˜ ๋น„์šฉ</span>
<span id="outsourceMonthly">$0K</span>
</div>
<div class="comparison-item" style="display: flex; justify-content: space-between; margin-bottom: 0.5rem;">
<span><span class="periodDisplay">3</span>๊ฐœ์›” ์ด ๋น„์šฉ</span>
<span id="outsourceTotal">$0K</span>
</div>
</div>
<div class="comparison-card" style="background: rgba(245, 87, 108, 0.1); border: 1px solid rgba(245, 87, 108, 0.3); padding: 1.5rem; border-radius: 10px;">
<h5 style="color: #f5576c; margin-bottom: 1rem;">์ž์ฒด ์ธ๋ ฅ ๊ฐœ๋ฐœ</h5>
<div class="comparison-item" style="display: flex; justify-content: space-between; margin-bottom: 0.5rem;">
<span>์ดˆ๊ธฐ ๋น„์šฉ</span>
<span id="inhouseInitial">$0K</span>
</div>
<div class="comparison-item" style="display: flex; justify-content: space-between; margin-bottom: 0.5rem;">
<span>์›” ์šด์˜ ๋น„์šฉ</span>
<span id="inhouseMonthly">$0K</span>
</div>
<div class="comparison-item" style="display: flex; justify-content: space-between; margin-bottom: 0.5rem;">
<span><span class="periodDisplay">3</span>๊ฐœ์›” ์ด ๋น„์šฉ</span>
<span id="inhouseTotal">$0K</span>
</div>
</div>
<div class="comparison-card" style="background: rgba(79, 172, 254, 0.1); border: 1px solid rgba(79, 172, 254, 0.3); padding: 1.5rem; border-radius: 10px;">
<h5 style="color: #4facfe; margin-bottom: 1rem;">ํ”Œ๋žซํผ ๋Œ€์—ฌ</h5>
<div class="comparison-item" style="display: flex; justify-content: space-between; margin-bottom: 0.5rem;">
<span>์ดˆ๊ธฐ ๋น„์šฉ</span>
<span id="platformInitial">$0K</span>
</div>
<div class="comparison-item" style="display: flex; justify-content: space-between; margin-bottom: 0.5rem;">
<span>์›” ์šด์˜ ๋น„์šฉ</span>
<span id="platformMonthly">$0K</span>
</div>
<div class="comparison-item" style="display: flex; justify-content: space-between; margin-bottom: 0.5rem;">
<span><span class="periodDisplay">3</span>๊ฐœ์›” ์ด ๋น„์šฉ</span>
<span id="platformTotal">$0K</span>
</div>
</div>
```html
</div>
</div>
<!-- ๊ธฐ๊ฐ„๋ณ„ ๋น„์šฉ ์ฐจํŠธ -->
<div class="chart-container">
<canvas id="customChart"></canvas>
</div>
</div>
</div>
</div>
</div>
<script>
// ์ „์—ญ ๋ณ€์ˆ˜
let selectedComponents = {
service: [],
db: null,
auth: null,
credit: null,
payment: null,
marketing: null,
support: null,
monitoring: null,
additional: []
};
let customChart = null;
let currentPeriod = 3;
// ์˜ต์…˜ ์นด๋“œ ํด๋ฆญ ์ด๋ฒคํŠธ
document.querySelectorAll('.option-card').forEach(card => {
card.addEventListener('click', function() {
const category = this.dataset.category;
const id = this.dataset.id;
if (category === 'service' || category === 'additional') {
// ๋ณต์ˆ˜ ์„ ํƒ ๊ฐ€๋Šฅ
this.classList.toggle('selected');
if (this.classList.contains('selected')) {
if (!selectedComponents[category].includes(id)) {
selectedComponents[category].push(id);
}
} else {
const index = selectedComponents[category].indexOf(id);
if (index > -1) {
selectedComponents[category].splice(index, 1);
}
}
} else {
// ๋‹จ์ผ ์„ ํƒ
document.querySelectorAll(`[data-category="${category}"]`).forEach(c => {
c.classList.remove('selected');
});
this.classList.add('selected');
selectedComponents[category] = id;
}
});
});
// ํƒญ ์ „ํ™˜ ํ•จ์ˆ˜
function switchTab(tabId) {
document.querySelectorAll('.tab').forEach(tab => {
tab.classList.remove('active');
});
document.querySelectorAll('.tab-content').forEach(content => {
content.classList.remove('active');
});
event.target.classList.add('active');
document.getElementById(tabId).classList.add('active');
}
// ์ปค์Šคํ…€ ๋น„์šฉ ๊ณ„์‚ฐ ํ•จ์ˆ˜
function calculateCustomCost() {
let totalInitialCost = 0;
let totalResourceCost = 0;
let maxTime = 0;
let componentDetails = [];
// ์„œ๋น„์Šค ๋น„์šฉ ๊ณ„์‚ฐ
selectedComponents.service.forEach(serviceId => {
const card = document.querySelector(`[data-id="${serviceId}"]`);
const cost = parseFloat(card.dataset.cost);
const time = parseFloat(card.dataset.time);
const resource = parseFloat(card.dataset.resource) || 0;
const name = card.querySelector('.option-name').textContent;
totalInitialCost += cost;
totalResourceCost += resource;
maxTime = Math.max(maxTime, time);
componentDetails.push({
name: name,
cost: cost,
type: 'service'
});
});
// ๊ธฐํƒ€ ๊ตฌ์„ฑ ์š”์†Œ ๋น„์šฉ ๊ณ„์‚ฐ
['db', 'auth', 'credit', 'payment', 'marketing', 'monitoring'].forEach(category => {
if (selectedComponents[category]) {
const card = document.querySelector(`[data-category="${category}"][data-id="${selectedComponents[category]}"]`);
const cost = parseFloat(card.dataset.cost);
const time = parseFloat(card.dataset.time);
const name = card.querySelector('.option-name').textContent;
totalInitialCost += cost;
maxTime = Math.max(maxTime, time);
componentDetails.push({
name: name,
cost: cost,
type: category
});
}
});
// ์ง€์› ์„œ๋น„์Šค (์›”๊ฐ„ ๋น„์šฉ)
let monthlySupport = 0;
if (selectedComponents.support) {
const card = document.querySelector(`[data-category="support"][data-id="${selectedComponents.support]}"]`);
monthlySupport = parseFloat(card.dataset.cost);
const name = card.querySelector('.option-name').textContent;
componentDetails.push({
name: name,
cost: monthlySupport,
type: 'monthly'
});
}
// ์ถ”๊ฐ€ ๊ธฐ๋Šฅ ๋น„์šฉ ๊ณ„์‚ฐ
selectedComponents.additional.forEach(additionalId => {
const card = document.querySelector(`[data-category="additional"][data-id="${additionalId}"]`);
const cost = parseFloat(card.dataset.cost);
const time = parseFloat(card.dataset.time);
const name = card.querySelector('.option-name').textContent;
totalInitialCost += cost;
maxTime = Math.max(maxTime, time);
componentDetails.push({
name: name,
cost: cost,
type: 'additional'
});
});
// ์›”๊ฐ„ ์šด์˜ ๋น„์šฉ ๊ณ„์‚ฐ
const serverCost = totalInitialCost > 100 ? 5 : totalInitialCost > 50 ? 3 : totalInitialCost > 20 ? 2 : 1;
const resourceCost = totalResourceCost;
const maintenanceCost = totalInitialCost * 0.05; // ์ดˆ๊ธฐ ๋น„์šฉ์˜ 5%
const totalMonthlyCost = serverCost + resourceCost + maintenanceCost + monthlySupport;
// ๊ฒฐ๊ณผ ํ‘œ์‹œ
document.getElementById('initialCost').textContent = `$${totalInitialCost}K`;
document.getElementById('devTime').textContent = `${maxTime}๊ฐœ์›”`;
document.getElementById('serverCost').textContent = `$${serverCost}K`;
document.getElementById('resourceCost').textContent = `$${resourceCost.toFixed(1)}K`;
document.getElementById('maintenanceCost').textContent = `$${maintenanceCost.toFixed(1)}K`;
document.getElementById('totalMonthlyCost').textContent = `$${totalMonthlyCost.toFixed(1)}K`;
// ์ด ๋น„์šฉ ๊ณ„์‚ฐ (๊ธฐ๊ฐ„๋ณ„)
updateTotalCost(totalInitialCost, totalMonthlyCost);
// ์„ ํƒํ•œ ๊ตฌ์„ฑ ์š”์†Œ ๋ชฉ๋ก ํ‘œ์‹œ
displayComponentList(componentDetails);
// ๊ตฌ์ถ• ๋ฐฉ์‹๋ณ„ ๋น„๊ต
compareBuilderMethods(totalInitialCost, totalMonthlyCost, maxTime);
// ์ฐจํŠธ ์—…๋ฐ์ดํŠธ
updateCustomChart(totalInitialCost, totalMonthlyCost);
// ๊ฒฐ๊ณผ ์„น์…˜ ํ‘œ์‹œ
document.getElementById('customResult').style.display = 'block';
}
// ์ด ๋น„์šฉ ์—…๋ฐ์ดํŠธ
function updateTotalCost(initialCost, monthlyCost) {
const totalCost = initialCost + (monthlyCost * currentPeriod);
document.getElementById('totalCost').textContent = `$${totalCost.toFixed(1)}K`;
}
// ๊ตฌ์„ฑ ์š”์†Œ ๋ชฉ๋ก ํ‘œ์‹œ
function displayComponentList(components) {
const listContainer = document.getElementById('componentList');
listContainer.innerHTML = '';
components.forEach(component => {
const item = document.createElement('div');
item.className = 'component-list-item';
let costDisplay = component.type === 'monthly'
? `์›” $${component.cost}K`
: `$${component.cost}K`;
item.innerHTML = `
<span>${component.name}</span>
<span style="color: #00d2ff;">${costDisplay}</span>
`;
listContainer.appendChild(item);
});
}
// ๊ตฌ์ถ• ๋ฐฉ์‹๋ณ„ ๋น„๊ต
function compareBuilderMethods(initialCost, monthlyCost, devTime) {
// ์™ธ์ฃผ ์šฉ์—ญ ๊ฐœ๋ฐœ
const outsourceInitial = initialCost;
const outsourceMonthly = monthlyCost;
const outsourceTotal = outsourceInitial + (outsourceMonthly * currentPeriod);
// ์ž์ฒด ์ธ๋ ฅ ๊ฐœ๋ฐœ
const developerSalary = 10; // ์›” $10K
const teamSize = Math.ceil(initialCost / 50); // $50K๋‹น 1๋ช…
const inhouseDevTime = Math.max(devTime * 1.5, 3); // ์ตœ์†Œ 3๊ฐœ์›”
const inhouseInitial = developerSalary * teamSize * inhouseDevTime;
const inhouseMonthly = monthlyCost + (developerSalary * Math.ceil(teamSize / 2)); // ์œ ์ง€๋ณด์ˆ˜ ์ธ๋ ฅ
const inhouseTotal = inhouseInitial + (inhouseMonthly * currentPeriod);
// ํ”Œ๋žซํผ ๋Œ€์—ฌ
const platformInitial = 1; // ์„ค์ • ๋น„์šฉ
const platformMonthly = monthlyCost * 2 + 5; // ํ”Œ๋žซํผ ์ˆ˜์ˆ˜๋ฃŒ ํฌํ•จ
const platformTotal = platformInitial + (platformMonthly * currentPeriod);
// ๊ฒฐ๊ณผ ํ‘œ์‹œ
document.getElementById('outsourceInitial').textContent = `$${outsourceInitial}K`;
document.getElementById('outsourceMonthly').textContent = `$${outsourceMonthly.toFixed(1)}K`;
document.getElementById('outsourceTotal').textContent = `$${outsourceTotal.toFixed(1)}K`;
document.getElementById('inhouseInitial').textContent = `$${inhouseInitial}K`;
document.getElementById('inhouseMonthly').textContent = `$${inhouseMonthly.toFixed(1)}K`;
document.getElementById('inhouseTotal').textContent = `$${inhouseTotal.toFixed(1)}K`;
document.getElementById('platformInitial').textContent = `$${platformInitial}K`;
document.getElementById('platformMonthly').textContent = `$${platformMonthly.toFixed(1)}K`;
document.getElementById('platformTotal').textContent = `$${platformTotal.toFixed(1)}K`;
}
// ์ฐจํŠธ ์—…๋ฐ์ดํŠธ
function updateCustomChart(initialCost, monthlyCost) {
const ctx = document.getElementById('customChart').getContext('2d');
if (customChart) {
customChart.destroy();
}
const months = Array.from({length: 12}, (_, i) => `${i + 1}๊ฐœ์›”`);
const outsourceData = months.map((_, i) => initialCost + (monthlyCost * (i + 1)));
const inhouseData = months.map((_, i) => {
const teamSize = Math.ceil(initialCost / 50);
const inhouseInitial = 10 * teamSize * 3;
const inhouseMonthly = monthlyCost + (10 * Math.ceil(teamSize / 2));
return inhouseInitial + (inhouseMonthly * (i + 1));
});
const platformData = months.map((_, i) => 1 + ((monthlyCost * 2 + 5) * (i + 1)));
customChart = new Chart(ctx, {
type: 'line',
data: {
labels: months,
datasets: [{
label: '์™ธ์ฃผ ์šฉ์—ญ ๊ฐœ๋ฐœ',
data: outsourceData,
borderColor: '#764ba2',
backgroundColor: 'rgba(118, 75, 162, 0.1)',
tension: 0.4
}, {
label: '์ž์ฒด ์ธ๋ ฅ ๊ฐœ๋ฐœ',
data: inhouseData,
borderColor: '#f5576c',
backgroundColor: 'rgba(245, 87, 108, 0.1)',
tension: 0.4
}, {
label: 'ํ”Œ๋žซํผ ๋Œ€์—ฌ',
data: platformData,
borderColor: '#4facfe',
backgroundColor: 'rgba(79, 172, 254, 0.1)',
tension: 0.4
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: {
labels: {
color: '#ffffff'
}
},
tooltip: {
callbacks: {
label: function(context) {
return context.dataset.label + ': $' + context.parsed.y.toFixed(1) + 'K';
}
}
}
},
scales: {
x: {
grid: {
color: 'rgba(255, 255, 255, 0.1)'
},
ticks: {
color: '#a8a8b3'
}
},
y: {
grid: {
color: 'rgba(255, 255, 255, 0.1)'
},
ticks: {
color: '#a8a8b3',
callback: function(value) {
return '$' + value + 'K';
}
}
}
}
}
});
}
</script>
</body>
</html>