Ghost CMS · · 2 min read

Playing with embeds...

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

Read next