JSFiddle - React, Tailwind, and code Playground
by SvennMats
HTML
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700&display=swap" rel="stylesheet">
<div class="calculator-card">
<h2>💰 Hvor mye kan du spare?</h2>
<p class="subtitle">Se effekten av å bytte til Svenn Kalkulasjon</p>
<div class="input-section">
<div class="input-group">
<div class="label-row">
<label>Tid brukt per tilbud i dag (min)</label>
<span id="val-time" class="highlight-value">60 min</span>
</div>
<input type="range" id="input-time" min="10" max="240" step="5" value="60">
</div>
<div class="input-group">
<div class="label-row">
<label>Antall tilbud i uken (snitt)</label>
<span id="val-amount" class="highlight-value">5 stk</span>
</div>
<input type="range" id="input-amount" min="1" max="50" step="1" value="5">
</div>
<div class="input-group">
<div class="label-row">
<label>Din timespris (kr)</label>
<span id="val-rate" class="highlight-value">850 kr</span>
</div>
<input type="range" id="input-rate" min="300" max="3000" step="50" value="850">
</div>
</div>
<hr>
<div class="result-section">
<div class="result-row">
<span>Timer spart pr mnd:</span>
<span id="res-hours" class="res-value">0 t</span>
</div>
<div class="result-row">
<span>Verdi av spart tid:</span>
<span id="res-gross" class="res-value">0 kr</span>
</div>
<div class="result-row cost-row">
<span>Kostnad Svenn:</span>
<span class="res-value">-1 599 kr</span>
</div>
<div class="total-box">
<span class="total-label">Din månedlige gevinst:</span>
<span id="res-net" class="total-value">0 kr</span>
</div>
<p class="disclaimer">Beregningen baserer seg på at du bruker 10% av tiden du bruker i dag, samt 4,3 uker pr mnd.</p>
</div>
</div>
CSS
:root {
--svenn-dark: #241D2D; /* Din spesifiserte mørkeblå */
--svenn-orange: #F96529; /* Din spesifiserte oransje */
--text-grey: #64748b;
}
body {
font-family: 'Inter', sans-serif;
background-color: transparent;
padding: 15px;
margin: 0;
}
.calculator-card {
background: #ffffff;
max-width: 480px;
margin: 0 auto;
padding: 30px;
border-radius: 16px;
box-shadow: 0 10px 40px rgba(36, 29, 45, 0.12);
border: 1px solid #edf2f7;
}
h2 {
margin: 0 0 10px 0;
font-size: 1.6rem;
text-align: center;
color: var(--svenn-dark);
font-weight: 700;
letter-spacing: -0.02em;
}
.subtitle {
text-align: center;
color: var(--text-grey);
margin-bottom: 30px;
font-size: 0.95rem;
}
.input-group {
margin-bottom: 25px;
}
.label-row {
display: flex;
justify-content: space-between;
margin-bottom: 12px;
font-weight: 600;
font-size: 0.9rem;
color: var(--svenn-dark);
}
.highlight-value {
color: var(--svenn-orange);
font-weight: 700;
font-size: 1.1rem;
}
/* Custom Slider Styling */
input[type=range] {
width: 100%;
-webkit-appearance: none;
background: transparent;
}
input[type=range]::-webkit-slider-thumb {
-webkit-appearance: none;
height: 24px;
width: 24px;
border-radius: 50%;
background: #ffffff;
border: 3px solid var(--svenn-orange);
cursor: pointer;
margin-top: -10px;
box-shadow: 0 4px 10px rgba(249, 101, 41, 0.2);
transition: all 0.2s ease;
}
input[type=range]::-webkit-slider-runnable-track {
width: 100%;
height: 6px;
background: #e2e8f0;
border-radius: 10px;
}
hr {
border: 0;
border-top: 2px solid #f1f5f9;
margin: 30px 0;
}
.result-row {
display: flex;
justify-content: space-between;
margin-bottom: 12px;
font-size: 1rem;
color: var(--svenn-dark);
}
.res-value {
font-weight: 600;
}
.cost-row {
color: #ef4444;
opacity: 0.9;
}
.total-box {
...
JavaScript
const WEEKS_PER_MONTH = 4.33;
const COST_SVENN = 1599;
const inputs = {
time: document.getElementById('input-time'),
amount: document.getElementById('input-amount'),
rate: document.getElementById('input-rate')
};
const displays = {
time: document.getElementById('val-time'),
amount: document.getElementById('val-amount'),
rate: document.getElementById('val-rate')
};
const results = {
hours: document.getElementById('res-hours'),
gross: document.getElementById('res-gross'),
net: document.getElementById('res-net')
};
const formatCurrency = (num) => {
return new Intl.NumberFormat('no-NO', {
style: 'currency',
currency: 'NOK',
maximumFractionDigits: 0
}).format(num);
};
function calculate() {
const t = parseInt(inputs.time.value);
const a = parseInt(inputs.amount.value);
const r = parseInt(inputs.rate.value);
displays.time.textContent = `${t} min`;
displays.amount.textContent = `${a} stk`;
displays.rate.textContent = `${r} kr`;
const oldTotal = t * a;
const newTotal = oldTotal * 0.10;
const savedHours = ((oldTotal - newTotal) * WEEKS_PER_MONTH) / 60;
const gross = savedHours * r;
const net = gross - COST_SVENN;
results.hours.textContent = `${Math.round(savedHours)} timer`;
results.gross.textContent = formatCurrency(gross);
results.net.textContent = formatCurrency(net);
}
Object.values(inputs).forEach(i => i.addEventListener('input', calculate));
calculate();