.ctc-undo { position: relative; display: flex; flex-direction: column; gap: 12px; min-height: 70px; }
.ctc-undo-list { display: flex; flex-wrap: wrap; gap: 8px; }
.ctc-undo-chip { display: inline-flex; align-items: center; gap: 6px; padding: 6px 8px 6px 12px; background: #1f1f2e; color: #f0eeff; border: 1px solid rgba(255,255,255,0.08); border-radius: 999px; font: 600 12px/1 system-ui, sans-serif; transition: opacity 0.25s, transform 0.25s; }
.ctc-undo-chip.is-removing { opacity: 0; transform: scale(0.7); pointer-events: none; }
.ctc-undo-chip button { width: 18px; height: 18px; background: transparent; border: 0; padding: 0; color: #b8b6d4; cursor: pointer; font-size: 16px; line-height: 1; border-radius: 50%; }
.ctc-undo-chip button:hover { background: rgba(255,255,255,0.1); color: #fff; }
.ctc-undo-toast { display: inline-flex; align-items: center; gap: 12px; padding: 8px 12px; background: #15151d; border: 1px solid rgba(46,204,138,0.4); border-radius: 8px; font: 500 12px/1.2 system-ui, sans-serif; color: #c4b5fd; align-self: flex-start; animation: ctc-undo-in 0.2s ease; }
.ctc-undo-toast[hidden] { display: none; }
.ctc-undo-btn { background: transparent; border: 0; color: #2ecc8a; font: inherit; font-weight: 700; cursor: pointer; padding: 0; }
.ctc-undo-btn:hover { text-decoration: underline; } <div class="ctc-undo">
<div class="ctc-undo-list">
<span class="ctc-undo-chip" data-ctc-undo>Frontend<button type="button" aria-label="Remove Frontend">×</button></span>
<span class="ctc-undo-chip" data-ctc-undo>Backend<button type="button" aria-label="Remove Backend">×</button></span>
<span class="ctc-undo-chip" data-ctc-undo>DevOps<button type="button" aria-label="Remove DevOps">×</button></span>
</div>
<div class="ctc-undo-toast" role="status" aria-live="polite" hidden>
<span class="ctc-undo-msg"></span>
<button type="button" class="ctc-undo-btn">Undo</button>
</div>
</div> (function () {
document.querySelectorAll('.ctc-undo').forEach(function (root) {
var toast = root.querySelector('.ctc-undo-toast');
var msg = root.querySelector('.ctc-undo-msg');
var btn = root.querySelector('.ctc-undo-btn');
var pendingChip = null;
var timer = null;
function commit() {
if (pendingChip && pendingChip.parentNode) pendingChip.parentNode.removeChild(pendingChip);
pendingChip = null;
toast.setAttribute('hidden','');
timer = null;
}
btn.addEventListener('click', function () {
if (!pendingChip) return;
pendingChip.classList.remove('is-removing');
clearTimeout(timer); timer = null;
pendingChip = null;
toast.setAttribute('hidden','');
});
root.querySelectorAll('[data-ctc-undo] button').forEach(function (x) {
x.addEventListener('click', function () {
if (timer) commit();
var chip = x.closest('[data-ctc-undo]');
chip.classList.add('is-removing');
pendingChip = chip;
msg.textContent = 'Removed "' + chip.firstChild.textContent.trim() + '"';
toast.removeAttribute('hidden');
timer = setTimeout(commit, 4000);
});
});
});
})(); Live preview Edit any tab — preview updates live Ready