<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>19-theme-clock</title>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.2.1/css/all.min.css" />
    <style>
        @import url('https://fonts.googleapis.com/css?family=Heebo:300&display=swap');

        @property --angle {
            syntax: "<number>";
            initial-value: 0;
            inherits: true;
        }

        @keyframes anim {
            from {
                --angle: 0;
            }

            to {
                --angle: 360;
            }
        }

        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        :root {
            --angle: 0;
            --accent-color: hsl(var(--angle), 100%, 50%);
            --primary-color: color-mix(in srgb, var(--accent-color), #001 85%);
            --secondary-color: color-mix(in srgb, var(--accent-color), white 85%);
            /* --primary-color: #000; */
            /* --secondary-color: #fff; */
            --main-transition: all .2s ease-in;

            accent-color: var(--accent-color);

            animation: anim 60s linear infinite;
        }

        html {
            transition: var(--main-transition);
        }

        html.dark {
            --secondary-color: color-mix(in srgb, var(--accent-color), #001 85%);
            --primary-color: color-mix(in srgb, var(--accent-color), white 85%);


            background-color: var(--secondary-color);
            color: var(--primary-color);
        }


        body {
            font-family: "Heebo", sans-serif;
            display: flex;
            align-items: center;
            justify-content: center;
            /* height: 100vh; */
            overflow: hidden;

            flex-direction: column;
            min-height: 100vh;
            background-color: var(--secondary-color);
            color: var(--primary-color);
        }

        .toggle {
            cursor: pointer;
            /* background-color: var(--primary-color); */
            /* color: var(--secondary-color); */
            border: 0;
            border-radius: 4px;
            padding: 8px 12px;
            cursor: pointer;
            /* position: absolute; */
            /* top: 100px; */

            color: var(--primary-color);
            background: transparent;
            font-size: 25px;
            transition: var(--main-transition), scale .2s ease;
        }

        .toggle:hover {
            scale: 1.2;
        }

        .toggle:focus {
            outline: none;
        }

        .container {
            display: flex;
            flex-direction: column;
            justify-content: space-between;
            align-items: center;

            transform-origin: center bottom;
            transform: rotate(0deg);

        }

        .clock {
            position: relative;
            width: 250px;
            height: 250px;
            aspect-ratio: 1;

            box-shadow: 0px 0px 50px var(--accent-color);
            border-radius: 50%;
            margin: 70px 0;

            outline: 9px solid var(--primary-color);
        }

        .needle {
            background-color: var(--primary-color);
            position: absolute;
            top: 50%;
            left: 50%;
            height: 65px;
            width: 3px;
            transform-origin: bottom center;
            transition: var(--main-transition), transform 0s;

            box-shadow: 0px 0px 10px var(--accent-color);
            border-radius: 100px;
        }

        .needle.hour {
            transform: translate(-50%, -100%) rotate(0deg);
        }

        .needle.minute {
            transform: translate(-50%, -100%) rotate(0deg);
            height: 100px;
        }

        .needle.second {
            transform: translate(-50%, -100%) rotate(0deg);
            height: 100px;
            /* background-color: #e74c3c; */

            background-color: var(--accent-color);
        }

        .center-point {
            /* background-color: #e74c3c; */
            width: 10px;
            height: 10px;
            position: absolute;
            top: 50%;
            left: 50%;
            translate: -50% -50%;
            border-radius: 50%;

            background-color: var(--primary-color);
            transition: var(--main-transition);
        }

        /* .center-point::after {
            content: "";
            background-color: var(--primary-color);
            width: 5px;
            height: 5px;
            position: absolute;
            top: 50%;
            left: 50%;
            translate: -50% -50%;
            border-radius: 50%;
        } */

        .time {
            font-size: 60px;
        }

        .date {
            /* color: #aaa; */
            /* font-size: 14px; */
            letter-spacing: .3px;
            text-transform: uppercase;

            color: var(--primary-color);
            line-height: 0;
            font-size: 30px;
            display: flex;
            align-items: center;
            justify-content: center;
        }

        .date span.circle {
            background-color: var(--accent-color);
            color: var(--secondary-color);
            border-radius: 50%;
            /* height: 18px; */
            /* width: 18px; */
            aspect-ratio: 1;
            display: inline-flex;
            align-items: center;
            justify-content: center;
            line-height: 18px;
            transition: var(--main-transition), var(--angle) 1s;
            /* font-size: 12px; */

            font-weight: 600;
            font-size: 20px;
            width: 32px;
            height: 32px;
            margin-left: 10px;
            text-align: center;
        }
    </style>
</head>

<body>
    <button class="toggle" id="toggle">
        <i class="fa-regular fa-moon"></i>
    </button>
    <div class="container">
        <div class="clock">
            <div class="needle hour"></div>
            <div class="needle minute"></div>
            <div class="needle second"></div>
            <div class="center-point"></div>
        </div>
        <div class="time">3:33</div>
        <div class="date">FRIDAY, APR <span class="circle">26</span></div>
    </div>

    <script>
        const
            container = document.querySelector(".container"),
            hourEl = document.querySelector(".hour"),
            minuteEl = document.querySelector(".minute"),
            secondEl = document.querySelector(".second"),
            timeEl = document.querySelector(".time"),
            dateEl = document.querySelector(".date"),
            toggle = document.getElementById("toggle"),
            days = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"],
            months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];

        toggle.addEventListener("click", e => {
            const html = document.querySelector("html")
            if (html.classList.contains("dark")) {
                html.classList.remove("dark")
                toggle.children[0].className = "fa-regular fa-moon"
                // e.target.innerHTML = "Dark mode"

                container.animate(
                    [
                        { transform: "rotate(0deg)" },
                        { transform: "rotate(360deg)" }
                    ],
                    {
                        duration: 400,
                        fill: "forwards",
                        easing: "ease"
                    }
                )
            } else {
                html.classList.add("dark")
                // e.target.innerHTML = "Light mode"
                toggle.children[0].className = "fa-regular fa-lightbulb"

                container.animate(
                    [
                        { transform: "rotate(360deg)" },
                        { transform: "rotate(0deg)" }
                    ],
                    {
                        duration: 400,
                        fill: "forwards",
                        easing: "ease"
                    }
                )
            }
        })

        function setTime() {
            const
                time = new Date(),
                month = time.getMonth(),
                day = time.getDay(),
                date = time.getDate(),
                hours = time.getHours(),
                hoursForClock = hours % 12,
                minutes = time.getMinutes(),
                seconds = time.getSeconds(),
                ampm = hours >= 12 ? "PM" : "AM";


            hourEl.style.transform = `translate(-50%, -100%) rotate(${scale(hoursForClock, 0, 11, 0, 360)}deg)`
            minuteEl.style.transform = `translate(-50%, -100%) rotate(${scale(minutes, 0, 59, 0, 360)}deg)`
            secondEl.style.transform = `translate(-50%, -100%) rotate(${scale(seconds, 0, 59, 0, 360)}deg)`


            // hourEl.style.transform = `translate(-50%, -100%) rotate(${((hoursForClock / 12) * 100 * 360) / 100
            //     }deg)`;

            // minuteEl.style.transform = `translate(-50%, -100%) rotate(${((minutes / 60) * 100 * 360) / 100
            //     }deg)`;

            // secondEl.style.transform = `translate(-50%, -100%) rotate(${((seconds / 60) * 100 * 360) / 100
            //     }deg)`;


            timeEl.innerHTML = `${hoursForClock < 10 ? `0${hoursForClock}` : hoursForClock}:${minutes < 10 ? `0${minutes}` : minutes} ${ampm}`;
            dateEl.innerHTML = `${days[day]}, ${months[month]} <span class="circle">${date}</span>`
        }

        const scale = (num, in_min, in_max, out_min, out_max) => {
            return (num - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
        }


        setTime()
        setInterval(setTime, 1000)
    </script>
</body>

</html>

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.