Spaces:
Running
Running
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Cost Calculator - Does It Cost?</title> | |
| <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> | |
| <style> | |
| :root { | |
| --primary-color: #6366f1; | |
| --primary-dark: #4f46e5; | |
| --secondary-color: #ec4899; | |
| --background-color: #0f172a; | |
| --surface-color: #1e293b; | |
| --text-primary: #f1f5f9; | |
| --text-secondary: #94a3b8; | |
| --accent-color: #10b981; | |
| --warning-color: #f59e0b; | |
| --error-color: #ef4444; | |
| --gradient-1: linear-gradient(135deg, #667eea 0%, #764ba2 100%); | |
| --gradient-2: linear-gradient(135deg, #f093fb 0%, #f5576c 100%); | |
| --gradient-3: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%); | |
| } | |
| * { | |
| margin: 0; | |
| padding: 0; | |
| box-sizing: border-box; | |
| } | |
| body { | |
| font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; | |
| background-color: var(--background-color); | |
| color: var(--text-primary); | |
| line-height: 1.6; | |
| min-height: 100vh; | |
| overflow-x: hidden; | |
| } | |
| .container { | |
| max-width: 1200px; | |
| margin: 0 auto; | |
| padding: 0 20px; | |
| } | |
| /* Header Styles */ | |
| header { | |
| background: rgba(30, 41, 59, 0.8); | |
| backdrop-filter: blur(10px); | |
| border-bottom: 1px solid rgba(148, 163, 184, 0.1); | |
| position: sticky; | |
| top: 0; | |
| z-index: 100; | |
| padding: 1rem 0; | |
| } | |
| .header-content { | |
| display: flex; | |
| justify-content: space-between; | |
| align-items: center; | |
| } | |
| .logo { | |
| font-size: 1.5rem; | |
| font-weight: 700; | |
| background: var(--gradient-1); | |
| -webkit-background-clip: text; | |
| -webkit-text-fill-color: transparent; | |
| background-clip: text; | |
| } | |
| .anycoder-link { | |
| color: var(--accent-color); | |
| text-decoration: none; | |
| font-weight: 500; | |
| transition: all 0.3s ease; | |
| display: flex; | |
| align-items: center; | |
| gap: 0.5rem; | |
| } | |
| .anycoder-link:hover { | |
| transform: translateY(-2px); | |
| color: #34d399; | |
| } | |
| /* Hero Section */ | |
| .hero { | |
| padding: 4rem 0; | |
| text-align: center; | |
| position: relative; | |
| overflow: hidden; | |
| } | |
| .hero::before { | |
| content: ''; | |
| position: absolute; | |
| top: 0; | |
| left: 0; | |
| right: 0; | |
| bottom: 0; | |
| background: radial-gradient(circle at 20% 50%, rgba(99, 102, 241, 0.15) 0%, transparent 50%), | |
| radial-gradient(circle at 80% 80%, rgba(236, 72, 153, 0.1) 0%, transparent 50%); | |
| z-index: -1; | |
| } | |
| .hero h1 { | |
| font-size: clamp(2.5rem, 5vw, 4rem); | |
| margin-bottom: 1rem; | |
| background: var(--gradient-1); | |
| -webkit-background-clip: text; | |
| -webkit-text-fill-color: transparent; | |
| background-clip: text; | |
| line-height: 1.2; | |
| } | |
| .hero p { | |
| font-size: 1.2rem; | |
| color: var(--text-secondary); | |
| max-width: 600px; | |
| margin: 0 auto; | |
| } | |
| /* Main Content */ | |
| .main-content { | |
| padding: 4rem 0; | |
| } | |
| .calculator-section { | |
| background: var(--surface-color); | |
| border-radius: 20px; | |
| padding: 2.5rem; | |
| margin-bottom: 3rem; | |
| box-shadow: 0 20px 40px rgba(0, 0, 0, 0.3); | |
| position: relative; | |
| overflow: hidden; | |
| } | |
| .calculator-section::before { | |
| content: ''; | |
| position: absolute; | |
| top: 0; | |
| left: 0; | |
| width: 100%; | |
| height: 4px; | |
| background: var(--gradient-1); | |
| } | |
| .section-title { | |
| font-size: 2rem; | |
| margin-bottom: 2rem; | |
| display: flex; | |
| align-items: center; | |
| gap: 1rem; | |
| } | |
| .section-title i { | |
| color: var(--primary-color); | |
| } | |
| .calculator-grid { | |
| display: grid; | |
| grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); | |
| gap: 2rem; | |
| margin-bottom: 2rem; | |
| } | |
| .input-group { | |
| margin-bottom: 1.5rem; | |
| } | |
| .input-group label { | |
| display: block; | |
| margin-bottom: 0.5rem; | |
| font-weight: 500; | |
| color: var(--text-primary); | |
| } | |
| .input-group input, | |
| .input-group select { | |
| width: 100%; | |
| padding: 0.8rem 1rem; | |
| background: var(--background-color); | |
| border: 1px solid rgba(148, 163, 184, 0.2); | |
| border-radius: 10px; | |
| color: var(--text-primary); | |
| font-size: 1rem; | |
| transition: all 0.3s ease; | |
| } | |
| .input-group input:focus, | |
| .input-group select:focus { | |
| outline: none; | |
| border-color: var(--primary-color); | |
| box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.1); | |
| } | |
| .input-group .input-hint { | |
| font-size: 0.85rem; | |
| color: var(--text-secondary); | |
| margin-top: 0.3rem; | |
| } | |
| .calculate-btn { | |
| background: var(--gradient-1); | |
| color: white; | |
| border: none; | |
| padding: 1rem 2rem; | |
| border-radius: 10px; | |
| font-size: 1.1rem; | |
| font-weight: 600; | |
| cursor: pointer; | |
| transition: all 0.3s ease; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| gap: 0.5rem; | |
| margin-top: 1rem; | |
| } | |
| .calculate-btn:hover { | |
| transform: translateY(-2px); | |
| box-shadow: 0 10px 20px rgba(99, 102, 241, 0.3); | |
| } | |
| .calculate-btn:active { | |
| transform: translateY(0); | |
| } | |
| /* Results Section */ | |
| .results-section { | |
| background: var(--surface-color); | |
| border-radius: 20px; | |
| padding: 2.5rem; | |
| box-shadow: 0 20px 40px rgba(0, 0, 0, 0.3); | |
| display: none; | |
| } | |
| .results-section.active { | |
| display: block; | |
| animation: fadeIn 0.5s ease; | |
| } | |
| @keyframes fadeIn { | |
| from { opacity: 0; transform: translateY(20px); } | |
| to { opacity: 1; transform: translateY(0); } | |
| } | |
| .result-card { | |
| background: var(--background-color); | |
| border-radius: 15px; | |
| padding: 1.5rem; | |
| margin-bottom: 1.5rem; | |
| border: 1px solid rgba(148, 163, 184, 0.1); | |
| transition: all 0.3s ease; | |
| } | |
| .result-card:hover { | |
| transform: translateY(-5px); | |
| box-shadow: 0 10px 20px rgba(0, 0, 0, 0.2); | |
| } | |
| .result-title { | |
| font-size: 1.2rem; | |
| margin-bottom: 1rem; | |
| display: flex; | |
| align-items: center; | |
| gap: 0.5rem; | |
| } | |
| .result-value { | |
| font-size: 2.5rem; | |
| font-weight: 700; | |
| background: var(--gradient-1); | |
| -webkit-background-clip: text; | |
| -webkit-text-fill-color: transparent; | |
| background-clip: text; | |
| } | |
| .result-breakdown { | |
| margin-top: 1rem; | |
| padding-top: 1rem; | |
| border-top: 1px solid rgba(148, 163, 184, 0.1); | |
| } | |
| .breakdown-item { | |
| display: flex; | |
| justify-content: space-between; | |
| margin-bottom: 0.5rem; | |
| } | |
| .breakdown-label { | |
| color: var(--text-secondary); | |
| } | |
| .breakdown-value { | |
| color: var(--text-primary); | |
| font-weight: 500; | |
| } | |
| /* Comparison Section */ | |
| .comparison-section { | |
| display: grid; | |
| grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); | |
| gap: 1.5rem; | |
| margin-top: 2rem; | |
| } | |
| .comparison-card { | |
| background: var(--background-color); | |
| border-radius: 15px; | |
| padding: 1.5rem; | |
| border: 1px solid rgba(148, 163, 184, 0.1); | |
| text-align: center; | |
| transition: all 0.3s ease; | |
| } | |
| .comparison-card:hover { | |
| transform: translateY(-5px); | |
| box-shadow: 0 10px 20px rgba(0, 0, 0, 0.2); | |
| } | |
| .comparison-card.best { | |
| border: 2px solid var(--accent-color); | |
| background: linear-gradient(135deg, rgba(16, 185, 129, 0.1) 0%, rgba(16, 185, 129, 0.05) 100%); | |
| } | |
| .comparison-card h3 { | |
| margin-bottom: 1rem; | |
| color: var(--primary-color); | |
| } | |
| .comparison-card .price { | |
| font-size: 1.8rem; | |
| font-weight: 700; | |
| margin-bottom: 1rem; | |
| } | |
| .comparison-card .features { | |
| text-align: left; | |
| margin-bottom: 1rem; | |
| } | |
| .feature-item { | |
| display: flex; | |
| align-items: center; | |
| gap: 0.5rem; | |
| margin-bottom: 0.5rem; | |
| color: var(--text-secondary); | |
| } | |
| .feature-item i { | |
| font-size: 0.8rem; | |
| } | |
| .feature-item.active { | |
| color: var(--accent-color); | |
| } | |
| /* Stats Section */ | |
| .stats-section { | |
| display: grid; | |
| grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); | |
| gap: 1.5rem; | |
| margin-top: 3rem; | |
| } | |
| .stat-card { | |
| background: var(--background-color); | |
| border-radius: 15px; | |
| padding: 1.5rem; | |
| text-align: center; | |
| border: 1px solid rgba(148, 163, 184, 0.1); | |
| } | |
| .stat-value { | |
| font-size: 2rem; | |
| font-weight: 700; | |
| color: var(--primary-color); | |
| margin-bottom: 0.5rem; | |
| } | |
| .stat-label { | |
| color: var(--text-secondary); | |
| font-size: 0.9rem; | |
| } | |
| /* Floating Action Button */ | |
| .fab { | |
| position: fixed; | |
| bottom: 2rem; | |
| right: 2rem; | |
| width: 60px; | |
| height: 60px; | |
| background: var(--gradient-1); | |
| border-radius: 50%; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| color: white; | |
| font-size: 1.5rem; | |
| cursor: pointer; | |
| box-shadow: 0 10px 20px rgba(99, 102, 241, 0.3); | |
| transition: all 0.3s ease; | |
| z-index: 1000; | |
| } | |
| .fab:hover { | |
| transform: scale(1.1); | |
| box-shadow: 0 15px 30px rgba(99, 102, 241, 0.4); | |
| } | |
| /* Responsive Design */ | |
| @media (max-width: 768px) { | |
| .hero h1 { | |
| font-size: 2.5rem; | |
| } | |
| .calculator-grid { | |
| grid-template-columns: 1fr; | |
| } | |
| .comparison-section { | |
| grid-template-columns: 1fr; | |
| } | |
| .stats-section { | |
| grid-template-columns: repeat(2, 1fr); | |
| } | |
| } | |
| /* Animations */ | |
| @keyframes pulse { | |
| 0% { transform: scale(1); } | |
| 50% { transform: scale(1.05); } | |
| 100% { transform: scale(1); } | |
| } | |
| .pulse { | |
| animation: pulse 2s infinite; | |
| } | |
| /* Loading Spinner */ | |
| .spinner { | |
| width: 40px; | |
| height: 40px; | |
| border: 4px solid rgba(255, 255, 255, 0.1); | |
| border-top: 4px solid var(--primary-color); | |
| border-radius: 50%; | |
| animation: spin 1s linear infinite; | |
| margin: 2rem auto; | |
| } | |
| @keyframes spin { | |
| 0% { transform: rotate(0deg); } | |
| 100% { transform: rotate(360deg); } | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <header> | |
| <div class="container header-content"> | |
| <div class="logo">Cost Calculator</div> | |
| <a href="https://huggingface.co/spaces/akhaliq/anycoder" class="anycoder-link" target="_blank"> | |
| <i class="fas fa-code"></i> | |
| Built with anycoder | |
| </a> | |
| </div> | |
| </header> | |
| <section class="hero"> | |
| <div class="container"> | |
| <h1>Does It Cost?</h1> | |
| <p>Calculate and compare costs for various services and products. Get instant insights and make informed decisions.</p> | |
| </div> | |
| </section> | |
| <main class="main-content"> | |
| <div class="container"> | |
| <section class="calculator-section"> | |
| <h2 class="section-title"> | |
| <i class="fas fa-calculator"></i> | |
| Cost Calculator | |
| </h2> | |
| <div class="calculator-grid"> | |
| <div> | |
| <div class="input-group"> | |
| <label for="service-type">Service Type</label> | |
| <select id="service-type"> | |
| <option value="cloud">Cloud Hosting</option> | |
| <option value="software">Software Subscription</option> | |
| <option value="hardware">Hardware Purchase</option> | |
| <option value="consulting">Consulting Services</option> | |
| <option value="marketing">Marketing Services</option> | |
| </select> | |
| </div> | |
| <div class="input-group"> | |
| <label for="quantity">Quantity/Units</label> | |
| <input type="number" id="quantity" placeholder="Enter quantity" value="1" min="1"> | |
| <div class="input-hint">Number of units or months</div> | |
| </div> | |
| <div class="input-group"> | |
| <label for="price-per-unit">Price per Unit ($)</label> | |
| <input type="number" id="price-per-unit" placeholder="Enter price" value="100" min="0" step="0.01"> | |
| <div class="input-hint">Cost per unit or per month</div> | |
| </div> | |
| <div class="input-group"> | |
| <label for="discount">Discount (%)</label> | |
| <input type="number" id="discount" placeholder="Enter discount" value="0" min="0" max="100"> | |
| <div class="input-hint">Percentage discount on the total</div> | |
| </div> | |
| </div> | |
| <div> | |
| <div class="input-group"> | |
| <label for="tax-rate">Tax Rate (%)</label> | |
| <input type="number" id="tax-rate" placeholder="Enter tax rate" value="10" min="0" max="100"> | |
| <div class="input-hint">Applicable tax percentage</div> | |
| </div> | |
| <div class="input-group"> | |
| <label for="setup-fee">Setup Fee ($)</label> | |
| <input type="number" id="setup-fee" placeholder="Enter setup fee" value="0" min="0" step="0.01"> | |
| <div class="input-hint">One-time setup cost</div> | |
| </div> | |
| <div class="input-group"> | |
| <label for="maintenance">Monthly Maintenance ($)</label> | |
| <input type="number" id="maintenance" placeholder="Enter maintenance cost" value="0" min="0" step="0.01"> | |
| <div class="input-hint">Recurring monthly maintenance</div> | |
| </div> | |
| <button class="calculate-btn" id="calculate-btn"> | |
| <i class="fas fa-calculator"></i> | |
| Calculate Cost | |
| </button> | |
| </div> | |
| </div> | |
| </section> | |
| <section class="results-section" id="results-section"> | |
| <h2 class="section-title"> | |
| <i class="fas fa-chart-pie"></i> | |
| Cost Analysis Results | |
| </h2> | |
| <div class="result-card"> | |
| <div class="result-title"> | |
| <i class="fas fa-dollar-sign"></i> | |
| Total Cost | |
| </div> | |
| <div class="result-value" id="total-cost">$0.00</div> | |
| <div class="result-breakdown"> | |
| <div class="breakdown-item"> | |
| <span class="breakdown-label">Base Cost:</span> | |
| <span class="breakdown-value" id="base-cost">$0.00</span> | |
| </div> | |
| <div class="breakdown-item"> | |
| <span class="breakdown-label">Discount:</span> | |
| <span class="breakdown-value" id="discount-amount">-$0.00</span> | |
| </div> | |
| <div class="breakdown-item"> | |
| <span class="breakdown-label">Tax:</span> | |
| <span class="breakdown-value" id="tax-amount">+$0.00</span> | |
| </div> | |
| <div class="breakdown-item"> | |
| <span class="breakdown-label">Setup Fee:</span> | |
| <span class="breakdown-value" id="setup-fee-result">+$0.00</span> | |
| </div> | |
| <div class="breakdown-item"> | |
| <span class="breakdown-label">Maintenance:</span> | |
| <span class="breakdown-value" id="maintenance-result">+$0.00</span> | |
| </div> | |
| </div> | |
| </div> | |
| <h3 class="section-title" style="margin-top: 2rem;"> | |
| <i class="fas fa-balance-scale"></i> | |
| Cost Comparison | |
| </h3> | |
| <div class="comparison-section" id="comparison-section"> | |
| <!-- Comparison cards will be inserted here --> | |
| </div> | |
| <div class="stats-section"> | |
| <div class="stat-card"> | |
| <div class="stat-value" id="savings-percent">0%</div> | |
| <div class="stat-label">Potential Savings</div> | |
| </div> | |
| <div class="stat-card"> | |
| <div class="stat-value" id="cost-per-unit">$0</div> | |
| <div class="stat-label">Cost per Unit</div> | |
| </div> | |
| <div class="stat-card"> | |
| <div class="stat-value" id="total-units">0</div> | |
| <div class="stat-label">Total Units</div> | |
| </div> | |
| <div class="stat-card"> | |
| <div class="stat-value" id="effective-rate">$0</div> | |
| <div class="stat-label">Effective Rate</div> | |
| </div> | |
| </div> | |
| </section> | |
| </div> | |
| </main> | |
| <div class="fab" id="reset-btn"> | |
| <i class="fas fa-redo"></i> | |
| </div> | |
| <script> | |
| document.addEventListener('DOMContentLoaded', function() { | |
| const calculateBtn = document.getElementById('calculate-btn'); | |
| const resetBtn = document.getElementById('reset-btn'); | |
| const resultsSection = document.getElementById('results-section'); | |
| const serviceType = document.getElementById('service-type'); | |
| const quantity = document.getElementById('quantity'); | |
| const pricePerUnit = document.getElementById('price-per-unit'); | |
| const discount = document.getElementById('discount'); | |
| const taxRate = document.getElementById('tax-rate'); | |
| const setupFee = document.getElementById('setup-fee'); | |
| const maintenance = document.getElementById('maintenance'); | |
| // Service type presets | |
| const servicePresets = { | |
| cloud: { name: 'Cloud Hosting', basePrice: 50, setupFee: 0, maintenance: 10 }, | |
| software: { name: 'Software Subscription', basePrice: 29, setupFee: 0, maintenance: 0 }, | |
| hardware: { name: 'Hardware Purchase', basePrice: 500, setupFee: 50, maintenance: 20 }, | |
| consulting: { name: 'Consulting Services', basePrice: 150, setupFee: 100, maintenance: 0 }, | |
| marketing: { name: 'Marketing Services', basePrice: 1000, setupFee: 200, maintenance: 100 } | |
| }; | |
| // Calculate cost function | |
| function calculateCost() { | |
| const qty = parseFloat(quantity.value) || 0; | |
| const price = parseFloat(pricePerUnit.value) || 0; | |
| const disc = parseFloat(discount.value) || 0; | |
| const tax = parseFloat(taxRate.value) || 0; | |
| const setup = parseFloat(setupFee.value) || 0; | |
| const maint = parseFloat(maintenance.value) || 0; | |
| // Calculate base cost | |
| const baseCost = qty * price; | |
| // Calculate discount | |
| const discountAmount = (baseCost * disc) / 100; | |
| // Calculate subtotal after discount | |
| const subtotal = baseCost - discountAmount; | |
| // Calculate tax | |
| const taxAmount = (subtotal * tax) / 100; | |
| // Calculate total cost | |
| const totalCost = subtotal + taxAmount + setup + (maint * qty); | |
| // Update results | |
| document.getElementById('total-cost').textContent = `$${totalCost.toFixed(2)}`; | |
| document.getElementById('base-cost').textContent = `$${baseCost.toFixed(2)}`; | |
| document.getElementById('discount-amount').textContent = `-$${discountAmount.toFixed(2)}`; | |
| document.getElementById('tax-amount').textContent = `+$${taxAmount.toFixed(2)}`; | |
| document.getElementById('setup-fee-result').textContent = `+$${setup.toFixed(2)}`; | |
| document.getElementById('maintenance-result').textContent = `+$${(maint * qty).toFixed(2)}`; | |
| // Update stats | |
| document.getElementById('savings-percent').textContent = `${disc}%`; | |
| document.getElementById('cost-per-unit').textContent = `$${(totalCost / qty).toFixed(2)}`; | |
| document.getElementById('total-units').textContent = qty; | |
| document.getElementById('effective-rate').textContent = `$${((totalCost - setup) / qty).toFixed(2)}`; | |
| // Generate comparison | |
| generateComparison(totalCost, qty, price, disc, tax, setup, maint); | |
| // Show results section | |
| resultsSection.classList.add('active'); | |
| } | |
| // Generate comparison cards | |
| function generateComparison(totalCost, qty, price, disc, tax, setup, maint) { | |
| const comparisonSection = document.getElementById('comparison-section'); | |
| comparisonSection.innerHTML = ''; | |
| // Generate alternative scenarios | |
| const scenarios = [ | |
| { | |
| name: 'No Discount', | |
| price: price, | |
| discount: 0, | |
| setup: setup, | |
| maintenance: maint, | |
| color: 'primary' | |
| }, | |
| { | |
| name: 'Higher Quantity', | |
| price: price * 0.9, // 10% discount for bulk | |
| discount: 10, | |
| setup: setup * 0.8, // 20% discount on setup | |
| maintenance: maint * 0.9, | |
| color: 'accent' | |
| }, | |
| { | |
| name: 'Premium Option', | |
| price: price * 1.5, | |
| discount: disc, | |
| setup: setup * 1.2, | |
| maintenance: maint * 1.5, | |
| color: 'warning' | |
| } | |
| ]; | |
| scenarios.forEach((scenario, index) => { | |
| const baseCost = qty * scenario.price; | |
| const discountAmount = (baseCost * scenario.discount) / 100; | |
| const subtotal = baseCost - discountAmount; | |
| const taxAmount = (subtotal * tax) / 100; | |
| const total = subtotal + taxAmount + scenario.setup + (scenario.maintenance * qty); | |
| const card = document.createElement('div'); | |
| card.className = `comparison-card ${index === 0 ? 'best' : ''}`; | |
| card.innerHTML = ` | |
| <h3>${scenario.name}</h3> | |
| <div class="price">$${total.toFixed(2)}</div> | |
| <div class="features"> | |
| <div class="feature-item ${index === 0 ? 'active' : ''}"> | |
| <i class="fas fa-check"></i> | |
| <span>Base: $${(qty * scenario.price).toFixed(2)}</span> | |
| </div> | |
| <div class="feature-item ${index === 0 ? 'active' : ''}"> | |
| <i class="fas fa-check"></i> | |
| <span>Discount: ${scenario.discount}%</span> | |
| </div> | |
| <div class="feature-item ${index === 0 ? 'active' : ''}"> | |
| <i class="fas fa-check"></i> | |
| <span>Setup: $${scenario.setup.toFixed(2)}</span> | |
| </div> | |
| <div class="feature-item ${index === 0 ? 'active' : ''}"> | |
| <i class="fas fa-check"></i> | |
| <span>Maintenance: $${(scenario.maintenance * qty).toFixed(2)}</span> | |
| </div> | |
| </div> | |
| `; | |
| comparisonSection.appendChild(card); | |
| }); | |
| } | |
| // Event listeners | |
| calculateBtn.addEventListener('click', calculateCost); | |
| resetBtn.addEventListener('click', function() { | |
| // Reset form | |
| quantity.value = 1; | |
| pricePerUnit.value = 100; | |
| discount.value = 0; | |
| taxRate.value = 10; | |
| setupFee.value = 0; | |
| maintenance.value = 0; | |
| // Hide results | |
| resultsSection.classList.remove('active'); | |
| // Scroll to top | |
| window.scrollTo({ top: 0, behavior: 'smooth' }); | |
| }); | |
| // Auto-calculate on input change | |
| const inputs = [quantity, pricePerUnit, discount, taxRate, setupFee, maintenance]; | |
| inputs.forEach(input => { | |
| input.addEventListener('input', function() { | |
| if (this.value < 0) this.value = 0; | |
| if (this.value > 100 && this.id === 'discount') this.value = 100; | |
| if (this.id === 'tax-rate' && this.value > 100) this.value = 100; | |
| }); | |
| }); | |
| // Service type change handler | |
| serviceType.addEventListener('change', function() { | |
| const preset = servicePresets[this.value]; | |
| if (preset) { | |
| pricePerUnit.value = preset.basePrice; | |
| setupFee.value = preset.setupFee; | |
| maintenance.value = preset.maintenance; | |
| } | |
| }); | |
| // Add keyboard shortcut for calculation | |
| document.addEventListener('keydown', function(e) { | |
| if (e.key === 'Enter' && (e.target.tagName === 'INPUT' || e.target.tagName === 'SELECT')) { | |
| calculateCost(); | |
| } | |
| }); | |
| }); | |
| </script> | |
| </body> | |
| </html> |