@keyframes gentlePop 0% transform: scale(1); 50% transform: scale(0.94); 100% transform: scale(1);
// show temporary toast message function showToast(message, duration = 1800) const existingToast = document.querySelector('.toast-msg'); if(existingToast) existingToast.remove(); const toast = document.createElement('div'); toast.className = 'toast-msg'; toast.textContent = message; document.body.appendChild(toast); setTimeout(() => if(toast.parentNode) toast.remove(); , duration); small icons on desktop
// save icons positions to localStorage function persistPositions() const positions = iconsState.map(icon => ( id: icon.id, x: icon.x, y: icon.y )); localStorage.setItem('desktopIconsLayout', JSON.stringify(positions)); @keyframes gentlePop 0% transform: scale(1)
.context-menu-item padding: 8px 18px; cursor: pointer; transition: background 0.08s linear; display: flex; align-items: center; gap: 10px; 50% transform: scale(0.94)
// clamp all icon positions to visible area (on window resize) function clampIconPositions() const containerRect = desktopEl.getBoundingClientRect(); let changed = false; iconsState.forEach(icon => const maxX = Math.max(20, containerRect.width - 95); const maxY = Math.max(20, containerRect.height - 85); if (icon.x > maxX) icon.x = maxX; changed = true; if (icon.y > maxY) icon.y = maxY; changed = true; if (icon.x < 5) icon.x = 5; changed = true; if (icon.y < 5) icon.y = 5; changed = true; ); if (changed) persistPositions(); renderAllIcons(); // re-render with updated coords else // still re-render to keep consistent? we call after resize anyway renderAllIcons();