Project Viability Calculator
You can't have it all ;)
This is a simple representation of project management, where only 2 out of 3 can be applied.
You can have it fast
and cheap
, but then it's not going to be good
.
You can have it fast
and good
, but it's not going to be cheap.
You can have it cheap
and good
, but it's going to take forever.
Project Viability Calculator
Fast
Cheap
Good
<div style="font-family:'Segoe UI',sans-serif;background:linear-gradient(to bottom right,#0f2027,#203a43,#2c5364);color:#fff;padding:30px;border-radius:20px;width:100%;max-width:420px;margin:auto;box-shadow:0 0 30px rgba(0,0,0,0.5);">
<h1 style="text-align:center;margin-bottom:40px;font-size:24px;letter-spacing:1px;color:#ffffffcc;">Project Viability Calculator</h1>
<div style="margin-bottom:35px;">
<div style="font-size:16px;margin-bottom:10px;letter-spacing:1px;text-transform:uppercase;color:#ffffffbb;">Fast</div>
<input type="range" min="0" max="100" value="66" id="fast" style="width:100%;-webkit-appearance:none;height:14px;border-radius:10px;background:linear-gradient(to right,#ff0044,#00ff88);outline:none;cursor:pointer;">
</div>
<div style="margin-bottom:35px;">
<div style="font-size:16px;margin-bottom:10px;letter-spacing:1px;text-transform:uppercase;color:#ffffffbb;">Cheap</div>
<input type="range" min="0" max="100" value="66" id="cheap" style="width:100%;-webkit-appearance:none;height:14px;border-radius:10px;background:linear-gradient(to right,#ff0044,#00ff88);outline:none;cursor:pointer;">
</div>
<div style="margin-bottom:10px;">
<div style="font-size:16px;margin-bottom:10px;letter-spacing:1px;text-transform:uppercase;color:#ffffffbb;">Good</div>
<input type="range" min="0" max="100" value="66" id="good" style="width:100%;-webkit-appearance:none;height:14px;border-radius:10px;background:linear-gradient(to right,#ff0044,#00ff88);outline:none;cursor:pointer;">
</div>
</div>
<script>
(function(){
const sliders = {
fast: document.getElementById('fast'),
cheap: document.getElementById('cheap'),
good: document.getElementById('good')
};
let maxTotal = 200;
let active = false;
function updateValues(changed) {
if (active) return;
active = true;
let values = {
fast: parseInt(sliders.fast.value),
cheap: parseInt(sliders.cheap.value),
good: parseInt(sliders.good.value)
};
let total = values.fast + values.cheap + values.good;
if (total > maxTotal) {
const overflow = total - maxTotal;
let others = Object.keys(values).filter(k => k !== changed);
let remaining = values[others[0]] + values[others[1]];
if (remaining > 0) {
let reduce1 = Math.min(values[others[0]], overflow * (values[others[0]] / remaining));
let reduce2 = overflow - reduce1;
values[others[0]] -= Math.round(reduce1);
values[others[1]] -= Math.round(reduce2);
sliders[others[0]].value = values[others[0]];
sliders[others[1]].value = values[others[1]];
}
}
active = false;
}
Object.keys(sliders).forEach(key => {
sliders[key].addEventListener('input', () => updateValues(key));
});
})();
</script>
Copy & paste into HTML widget in your CMS