add reusable .popup-notification component

Hunter
Sunday, November 16th, 2025 at 10:12 PM

script.js+23 
style.css+35-1

script.js
   4  const grid = document.getElementById('grid');
   5  const page = document.querySelector('.page');
   6  
   7 +let popupElement = null;
   8 +let popupTimeout = null;
   9 +
  10  // Calculate cell size dynamically based on actual grid dimensions
  11  function getCellSize() {
  12  	const gridRect = grid.getBoundingClientRect();

1067  	// Clear the input so the same files can be selected again
1068  	fileInput.value = '';
1069  });
1070 +
1071 +function showPopup(message, displayDuration = 1250) {
1072 +	if (!popupElement) {
1073 +		popupElement = document.createElement('div');
1074 +		popupElement.className = 'popup-notification';
1075 +		document.body.appendChild(popupElement);
1076 +	}
1077 +
1078 +	if (popupTimeout) clearTimeout(popupTimeout);
1079 +
1080 +	popupElement.textContent = message;
1081 +	popupElement.classList.remove('fade-out');
1082 +	popupElement.classList.add('show');
1083 +
1084 +	popupTimeout = setTimeout(() => {
1085 +		popupElement.classList.remove('show');
1086 +		popupElement.classList.add('fade-out');
1087 +	}, displayDuration);
1088 +}
style.css
 61  
 62  	/* Set text color for all themes */
 63  	color: var(--white);
 64 +
 65 +	/* Set font */
 66 +	font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
 67  }
 68  
 69  /* Theme definitions */

561  	border-radius: 100px;
562  	padding: 14px 28px;
563  	font-size: 16px;
    -	font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
564  	font-weight: 600;
565  	cursor: pointer;
566  	box-shadow: 0 4px 12px rgba(0,0,0,0.2);

588  		opacity: 1;
589  	}
590  }
591 +
592 +.popup-notification {
593 +	position: fixed;
594 +	bottom: 2rem;
595 +	left: 50%;
596 +	transform: translateX(-50%);
597 +	background-color: var(--accent);
598 +	color: var(--page);
599 +	border: 2px solid var(--page);
600 +	padding: 0.7rem 0.9rem;
601 +	border-radius: 50rem;
602 +	font-size: 1.2rem;
603 +	text-align: center;
604 +	white-space: nowrap;
605 +	user-select: none;
606 +	width: fit-content;
607 +	height: fit-content;
608 +	opacity: 0;
609 +	pointer-events: none;
610 +	z-index: 10000;
611 +}
612 +
613 +.popup-notification.show {
614 +	opacity: 1;
615 +	transition: none;
616 +}
617 +
618 +.popup-notification.fade-out {
619 +	opacity: 0;
620 +	filter: blur(4px);
621 +	transition: opacity 1.5s ease-out, filter 1.5s ease-out;
622 +}