diff --git a/animated-countdown/index.html b/animated-countdown/index.html
new file mode 100644
index 0000000..6a23395
--- /dev/null
+++ b/animated-countdown/index.html
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+ Animated Countdown
+
+
+
+
+ 3
+ 2
+ 1
+ 0
+
+
Get Ready
+
+
+
+
GO
+
+
+
+
+
diff --git a/animated-countdown/script.js b/animated-countdown/script.js
new file mode 100644
index 0000000..3493444
--- /dev/null
+++ b/animated-countdown/script.js
@@ -0,0 +1,40 @@
+const nums = document.querySelectorAll('.nums span')
+const counter = document.querySelector('.counter')
+const finalMessage = document.querySelector('.final')
+const replay = document.querySelector('#replay')
+
+runAnimation()
+
+function resetDOM() {
+ counter.classList.remove('hide')
+ finalMessage.classList.remove('show')
+
+ nums.forEach((num) => {
+ num.classList.value = ''
+ })
+
+ nums[0].classList.add('in')
+}
+
+function runAnimation() {
+ nums.forEach((num, idx) => {
+ const nextToLast = nums.length - 1
+
+ num.addEventListener('animationend', (e) => {
+ if (e.animationName === 'goIn' && idx !== nextToLast) {
+ num.classList.remove('in')
+ num.classList.add('out')
+ } else if (e.animationName === 'goOut' && num.nextElementSibling) {
+ num.nextElementSibling.classList.add('in')
+ } else {
+ counter.classList.add('hide')
+ finalMessage.classList.add('show')
+ }
+ })
+ })
+}
+
+replay.addEventListener('click', () => {
+ resetDOM()
+ runAnimation()
+})
diff --git a/animated-countdown/style.css b/animated-countdown/style.css
new file mode 100644
index 0000000..04536e6
--- /dev/null
+++ b/animated-countdown/style.css
@@ -0,0 +1,126 @@
+@import url('https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&display=swap');
+
+* {
+ box-sizing: border-box;
+}
+
+body {
+ font-family: 'Roboto', sans-serif;
+ margin: 0;
+ height: 100vh;
+ overflow: hidden;
+}
+
+h4 {
+ font-size: 20px;
+ margin: 5px;
+ text-transform: uppercase;
+}
+
+.counter {
+ position: fixed;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%, -50%);
+ text-align: center;
+}
+
+.counter.hide {
+ transform: translate(-50%, -50%) scale(0);
+ animation: hide 0.2s ease-out;
+}
+
+@keyframes hide {
+ 0% {
+ transform: translate(-50%, -50%) scale(1);
+ }
+
+ 100% {
+ transform: translate(-50%, -50%) scale(0);
+ }
+}
+
+.final {
+ position: fixed;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%, -50%) scale(0);
+ text-align: center;
+}
+
+.final.show {
+ transform: translate(-50%, -50%) scale(1);
+ animation: show 0.2s ease-out;
+}
+
+@keyframes show {
+ 0% {
+ transform: translate(-50%, -50%) scale(0);
+ }
+
+ 30% {
+ transform: translate(-50%, -50%) scale(1.4);
+ }
+
+ 100% {
+ transform: translate(-50%, -50%) scale(1);
+ }
+}
+
+.nums {
+ color: #3498db;
+ font-size: 50px;
+ position: relative;
+ overflow: hidden;
+ width: 250px;
+ height: 50px;
+}
+
+.nums span {
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%, -50%) rotate(120deg);
+ transform-origin: bottom center;
+}
+
+.nums span.in {
+ transform: translate(-50%, -50%) rotate(0deg);
+ animation: goIn 0.5s ease-in-out;
+}
+
+.nums span.out {
+ animation: goOut 0.5s ease-in-out;
+}
+
+@keyframes goIn {
+ 0% {
+ transform: translate(-50%, -50%) rotate(120deg);
+ }
+
+ 30% {
+ transform: translate(-50%, -50%) rotate(-20deg);
+ }
+
+ 60% {
+ transform: translate(-50%, -50%) rotate(10deg);
+ }
+
+ 100% {
+ transform: translate(-50%, -50%) rotate(0deg);
+ }
+}
+
+@keyframes goOut {
+ 0% {
+ transform: translate(-50%, -50%) rotate(0deg);
+ }
+
+ 60% {
+ transform: translate(-50%, -50%) rotate(20deg);
+ }
+
+ 100% {
+ transform: translate(-50%, -50%) rotate(-120deg);
+ }
+}