Book your Squeegee Demo Call

Hey

<style> * { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif; } .wrap { padding: 20px 0 12px; } .row { display: flex; align-items: center; gap: 0; margin-bottom: 6px; } .tl { flex: 1; position: relative; height: 38px; } .appt { position: absolute; height: 38px; border-radius: 8px; border: 0.5px solid; display: flex; align-items: center; justify-content: center; font-size: 13px; font-weight: 500; transition: left 0.7s cubic-bezier(.4,0,.2,1), background 0.4s, border-color 0.4s; box-sizing: border-box; cursor: default; user-select: none; } .appt.past { background: #f5f5f3; border-color: #ccc; color: #888; } .appt.future { background: #E6F1FB; border-color: #185FA5; color: #0C447C; } .appt.moved { background: #FAEEDA; border-color: #BA7517; color: #633806; } .appt.replanned { background: #E1F5EE; border-color: #0F6E56; color: #085041; } .section-wrap { margin-bottom: 28px; } .section-title { font-size: 12px; font-weight: 500; color: #222; margin-bottom: 10px; display: flex; align-items: center; gap: 8px; } .badge { font-size: 10px; font-weight: 500; padding: 2px 7px; border-radius: 4px; border: 0.5px solid; } .badge-off { background: #f5f5f3; color: #888; border-color: #ccc; } .badge-on { background: #EAF3DE; color: #3B6D11; border-color: #639922; } .caption { font-size: 11px; color: #888; margin-bottom: 10px; min-height: 16px; } .btn-row { display: flex; gap: 8px; margin-bottom: 24px; } .pill { padding: 5px 14px; border-radius: 20px; border: 0.5px solid #ccc; font-size: 12px; cursor: pointer; background: #f5f5f3; color: #888; transition: all .2s; font-family: inherit; } .pill.active { background: #222; color: #fff; border-color: #222; } .legend { display: flex; gap: 16px; margin: 4px 0 20px 0; flex-wrap: wrap; } .leg-item { display: flex; align-items: center; gap: 5px; font-size: 11px; color: #888; } .leg-dot { width: 10px; height: 10px; border-radius: 3px; border: 0.5px solid; flex-shrink: 0; } .leg-dot.past { background: #f5f5f3; border-color: #ccc; } .leg-dot.future { background: #E6F1FB; border-color: #185FA5; } .leg-dot.moved { background: #FAEEDA; border-color: #BA7517; } .leg-dot.replanned { background: #E1F5EE; border-color: #0F6E56; } .divider { border: none; border-top: 0.5px solid #ddd; margin: 4px 0 20px; } </style> <div class="wrap"> <div class="btn-row"> <button class="pill active" id="btn-before" onclick="setState('before')">Before replan</button> <button class="pill" id="btn-after" onclick="setState('after')">After replan</button> </div> <div class="section-wrap"> <div class="section-title">Replan always update schedule <span class="badge badge-off">OFF</span></div> <div class="caption" id="cap-off">Appointments a, b, c, d sit evenly on the timeline.</div> <div class="row"><div class="tl" id="tl-off"></div></div> </div> <hr class="divider"> <div class="section-wrap"> <div class="section-title">Replan always update schedule <span class="badge badge-on">ON</span></div> <div class="caption" id="cap-on">Appointments a, b, c, d sit evenly on the timeline.</div> <div class="row"><div class="tl" id="tl-on"></div></div> </div> <div class="legend"> <div class="leg-item"><div class="leg-dot past"></div> Past / unchanged</div> <div class="leg-item"><div class="leg-dot replanned"></div> Replanned (b)</div> <div class="leg-item"><div class="leg-dot moved"></div> Shifted downstream</div> </div> </div> <script> const W = 11; const before = [ { id:'a', label:'a', left:2, type:'past' }, { id:'b', label:'b', left:24, type:'future' }, { id:'c', label:'c', left:46, type:'future' }, { id:'d', label:'d', left:68, type:'future' }, ]; const afterOff = [ { id:'a', label:'a', left:2, type:'past' }, { id:'b', label:'b', left:33, type:'replanned' }, { id:'c', label:'c', left:46, type:'future' }, { id:'d', label:'d', left:68, type:'future' }, ]; const afterOn = [ { id:'a', label:'a', left:2, type:'past' }, { id:'b', label:'b', left:33, type:'replanned' }, { id:'c', label:'c', left:55, type:'moved' }, { id:'d', label:'d', left:77, type:'moved' }, ]; function render(tlId, appts) { const tl = document.getElementById(tlId); tl.innerHTML = ''; appts.forEach(ap => { const el = document.createElement('div'); el.id = tlId + '-' + ap.id; el.className = 'appt ' + ap.type; el.style.left = ap.left + '%'; el.style.width = W + '%'; el.textContent = ap.label; tl.appendChild(el); }); } function animateTo(tlId, appts) { appts.forEach(ap => { const el = document.getElementById(tlId + '-' + ap.id); if (!el) return; el.style.left = ap.left + '%'; el.className = 'appt ' + ap.type; }); } render('tl-off', before); render('tl-on', before); function setState(s) { document.getElementById('btn-before').classList.toggle('active', s === 'before'); document.getElementById('btn-after').classList.toggle('active', s === 'after'); if (s === 'before') { animateTo('tl-off', before); animateTo('tl-on', before); document.getElementById('cap-off').textContent = 'Appointments a, b, c, d sit evenly on the timeline.'; document.getElementById('cap-on').textContent = 'Appointments a, b, c, d sit evenly on the timeline.'; } else { animateTo('tl-off', afterOff); animateTo('tl-on', afterOn); document.getElementById('cap-off').textContent = 'b is replanned and moves right — but c and d stay put. b is now crowded against c.'; document.getElementById('cap-on').textContent = 'b is replanned and moves right — and c, d shift right by the same amount, preserving spacing.'; } } </script>