Pen Settings

HTML

CSS

CSS Base

Vendor Prefixing

Add External Stylesheets/Pens

Any URLs added here will be added as <link>s in order, and before the CSS in the editor. You can use the CSS from another Pen by using its URL and the proper URL extension.

+ add another resource

JavaScript

Babel includes JSX processing.

Add External Scripts/Pens

Any URL's added here will be added as <script>s in order, and run before the JavaScript in the editor. You can use the URL of any other Pen and it will include the JavaScript from that Pen.

+ add another resource

Packages

Add Packages

Search for and use JavaScript packages from npm here. By selecting a package, an import statement will be added to the top of the JavaScript editor for this package.

Behavior

Auto Save

If active, Pens will autosave every 30 seconds after being saved once.

Auto-Updating Preview

If enabled, the preview panel updates automatically as you code. If disabled, use the "Run" button to update.

Format on Save

If enabled, your code will be formatted when you actively save your Pen. Note: your code becomes un-folded during formatting.

Editor Settings

Code Indentation

Want to change your Syntax Highlighting theme, Fonts and more?

Visit your global Editor Settings.

HTML

              
                <div class="nueclock-wrap">
  <div class="outer-ring"></div>
  <div class="inner-outer-ring"></div>
  <div class="mid-ring"></div>
  <div class="hour"><div class="shimmer"><div></div><div></div><div></div></div></div>
  <div class="outer-inner-ring"></div>
  <div class="inner-inner-ring"></div>
</div>

<div class="minihud ">
  <div class="metal-ring"></div>
  <div class="scene">
    <div class="sky"></div>
    <div id="timeContainer" ></div>
    <div class="clouds"></div>
    <div class="clouds sec"></div>
  </div>
</div>

<svg>
  <filter id="cloud1" x="-50%" y="-50%" width="200%" height="200%">
    <feTurbulence baseFrequency="0.9" numOctaves="4" seed="2"><animate attributeName="baseFrequency" dur="20s" values="0.05;0.02" keyTimes="0; 1" repeatCount="indefinite"/></feTurbulence>
    <feOffset dx="200" dy="100" /><feDisplacementMap in="SourceGraphic" scale="20" />
  </filter>
  <filter id="cloud2" x="-50%" y="-50%" width="200%" height="200%">
    <feTurbulence baseFrequency="0.9" numOctaves="3" seed="4"><animate attributeName="baseFrequency" dur="33s" values="0.05;0.02" keyTimes="0; 1" repeatCount="indefinite"/></feTurbulence>
    <feOffset dx="200" dy="100" /><feDisplacementMap in="SourceGraphic" scale="20" />
  </filter>
</svg>
              
            
!

CSS

              
                @import url('https://fonts.cdnfonts.com/css/digital-7-mono');
*{ box-sizing: border-box; -webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility; scroll-behavior: smooth;}
html, body { height: 100%; overflow: hidden;}

html {
    filter: grayscale(1) brightness(0.5) contrast(4) brightness(1.6);
}
body {
    display: flex;
    flex-direction: row;
    flex-wrap: wrap;
    justify-content: center;
    align-items: center;
    margin: 0;

    --clr-d: #c2d1e3;  /* midday */
    --clr-n: #35373a; /* midnight */
    --clr: var(--clr-d);
    --clr-dark: lch(from var(--clr) calc(l - 16) c h);

    background: var(--clr);
    background: linear-gradient(225deg, var(--clr), var(--clr-dark));

    font-size: calc(var(--_size) * 0.02);
    --_factor: min(600px, 100vh);
    --_size: min(var(--_factor), 100vw);

    --rotate-hour: 0;
    --pecentage-of-day: 0;
}
svg {
    height: 0; width: 0;
    overflow: hidden;
    max-width: 0px;
    max-height: 0;
}
.nueclock-wrap {
    width: 50em; height: 50em;
    border-radius: 50%;
    position: relative;
    --fox: calc( sin( ( var(--rotate-hour) + 135 ) * 1deg ) );
    --foy: calc( sin( ( var(--rotate-hour) + 45 )* 1deg ) );
    --sox: 1; --soy: 1;
    rotate: 90deg;
}
#timeContainer {
    font-family: 'Digital-7 Mono', sans-serif;
    font-size: 4.2em;
    font-weight: 1000;
    filter: blur(3px);
    opacity: 0.3;
    transition: opacity 0s; 
    text-align: center;
    position: absolute;
    
    color: #fff;
    top: 32%;
    transition: all 0.2s ease-in-out;
}
body:has( .hour.dragging ) #timeContainer {
    opacity: 0;
}
.scene * { pointer-events: none; }
.scene:hover #timeContainer {
    opacity: 0.6;
    filter: blur(1px);
}

.nueclock-wrap * { transition: transform 0.2s ease-out; }
.nueclock-wrap > * { position: absolute; left: 0; right: 0; top: 0; bottom: 0; margin: auto; }
.hour {
    width: 90%;
    height: 3%;
    transform-origin: 50% 50%;
    clip-path: polygon(-10% -400%, 50% -400%, 50% 400%, -10% 400%);
    transform: rotate(calc( 1deg * var(--rotate-hour)));    
    filter: grayscale(0.2) contrast(1.6);
    --sox: 0.5; --soy: 0.5;
    transition: width 0.2s ease-out;
}
.hour.hovered {
    width: 88%;
}

.hour, .hour::before {
    background: var(--clr-dark);
    box-shadow: 
    calc(0.4em * var(--soy) * var(--foy)) calc(0.4em * var(--sox) * var(--fox)) 0.2em -0.2em #000,
    calc(1em * var(--soy) * var(--foy)) calc(1em * var(--sox) * var(--fox)) 0.8em -0.2em #0005,
    inset calc(-0.4em * var(--soy) * var(--foy)) calc(-1em * var(--sox) * var(--fox)) 1em -0.6em #232323,
    inset calc(0.4em * var(--soy) * var(--foy)) calc(0.6em * var(--sox) * var(--fox)) 0.6em -0.5em #000a,
    inset calc(0.8em * var(--soy) * var(--foy)) calc(2em * var(--sox) * var(--fox)) 1em -0.6em #eee,
    inset calc(0.8em * var(--soy) * var(--foy)) calc(2em * var(--sox) * var(--fox)) 1em -0.1em #eee,
    inset calc(-0.8em * var(--soy) * var(--foy)) calc(-2em * var(--sox) * var(--fox)) 2em -0.1em #232323;
}

.hour::before {
    content: ''; display: block;
    width: 11%; 
    height: 400%;
    position: absolute;
    bottom: -150%;
    left: -2%;
    border-radius: 1.2em;
    --sox: 1;
    --soy: 1;
    cursor: grab;
}
.hour.dragging::before {
    cursor: grabbing;
}
.hour::after {
    content: ''; display: block;
    width: 1.2%; height: 200%;
    position: absolute;
    left: 8.8%; top: -50%;
    background: var(--clr-dark);
    font-size: 0.6em;
    box-shadow: 
    inset calc((2em * var(--foy)) + 1em) 0 1em -2em #000c,
    inset calc(-0.4em * var(--soy) * var(--foy)) calc(-1em * var(--sox) * var(--fox)) 1em -0.6em #232323,
    inset calc(0.4em * var(--soy) * var(--foy)) calc(0.6em * var(--sox) * var(--fox)) 0.6em -0.5em #000a,
    inset calc(0.8em * var(--soy) * var(--foy)) calc(2em * var(--sox) * var(--fox)) 1em -0.6em #eee,
    inset calc(0.8em * var(--soy) * var(--foy)) calc(2em * var(--sox) * var(--fox)) 1em -0.1em #eee,
    inset calc(-0.8em * var(--soy) * var(--foy)) calc(-2em * var(--sox) * var(--fox)) 2em -0.1em #232323;
}
.shimmer {
    position: absolute; left: 0; top: 0; z-index: 3;
    transform: translate(0, 0); transition: transform 2s ease, opacity 2s ease, scale 2s ease;
    animation: positionShimmer 1s linear infinite; animation-delay: calc((var(--rotate-hour) / 360) * -1s); animation-play-state: paused;
    opacity: 0.8;
    pointer-events: none;
}
@keyframes positionShimmer {
    0%    { opacity: 1;   transform: translate(-4.2em, -1.6em);  /* top right corner */ }
    12.5% { opacity: 1;   transform: translate(-4.8em, 0.5em);   /* top middle */ }
    25%   { opacity: 1;   transform: translate(-4.2em, 3.6em);   /* top left corner */ }
    37.5% { opacity: 1;   transform: translate(-2.2em, 3.7em);   /* left middle */ }
    50%   { opacity: 0.6; transform: translate(-0.4em, 3.3em);   /* bottom left corner */ }
    62.5% { opacity: 0.2; transform: translate(-0.2em, 0.8em);   /* bottom middle */ }
    75%   { opacity: 0.6; transform: translate(-0.4em, -1.6em);  /* bottom right corner */ }
    87.5% { opacity: 1;   transform: translate(-2.2em, -2em);    /* right middle */ }
    100%  { opacity: 1;   transform: translate(-4.2em, -1.6em);  /* back to top right corner */ }
}
.shimmer > div, .shimmer > div::before {
    --shimmer-size: 4em;
    position:absolute; left:0; right: 0; top: 0; bottom: 0; margin: auto; z-index: 100; 
    width: var(--shimmer-size); height: var(--shimmer-size);
}
.shimmer > div {
    --ani-speed: 12s; aspect-ratio: 1;
    width: calc( 2 * var(--shimmer-size));
    animation: flicker-spin var(--ani-speed) linear infinite;
}
.shimmer > div + div { animation-delay: calc( -1 * var(--ani-speed) / 3); }
.shimmer > div + div + div { animation-delay: calc( -2 * var(--ani-speed) / 3); }
.shimmer > div::before {
    content:''; display: block; width: 1em; height: 1em;
    background: #fff; filter: blur(4px);
    animation: flicker-spin calc(var(--ani-speed)/2) linear reverse infinite;
}
@keyframes flicker-spin {
    0% { border-image: radial-gradient(#fff 69%,#0000 70%) 2%/45%; rotate:0deg; }
    50% { border-image: radial-gradient(#fff 69%,#0000 70%) 0%/42%; }
    100% { border-image: radial-gradient(#fff 69%,#0000 70%) 2%/45%; rotate:360deg; }
}

.outer-ring {
    width: 63%; height: 63%; 
    border-radius: 100%;
    box-shadow: 
    -0.4em -0.4em 0.8em -0.8em #fff,
    1.4em 1.4em 1.4em 0.2em #0005,
    0.2em 0.2em 0.3em -0.1em #0005,
    inset 1.2em 1.2em 0.8em -1.2em #fff,
    inset -0.6em -0.6em 0.8em -0.2em #0005,
    inset 0em 0em 1em -0.2em #000a;
    background: #fff1;
}
.inner-outer-ring {
    width: 51%; height: 51%; 
    border-radius: 100%;
    box-shadow: 
    -0.1em -0.1em 0.2em -0.1em #000,
    inset -0.1em -0.1em 0.4em -0.1em #fff,
    inset 1em 1em 4em -1em #000;
}
.mid-ring {
    width: 46%; height: 46%; 
    border-radius: 100%;
    background: var(--clr);
    box-shadow: 
    1em 1em 1.2em -0.6em #fff5,
    -0.3em -0.3em 0.4em -0.6em #0005,
    -0.2em -0.2em 1em 0em #0004,
    inset -0.3em -0.3em 0.6em -0.2em #fff3,
    inset -1.2em -1.2em 1.2em -1.4em #fff3,
    inset 0.1em 0.1em 0.2em -0.1em #0003,
    inset 1em 1em 2em 0em #0007;
}
.mid-ring::before {
    content: ''; display: block;
    position: absolute;
    width: 100%; height: 100%;
    border-radius: 100%; 
    background: repeating-conic-gradient(
        var(--clr) 0%,
        var(--clr) calc((100%)*( 1 / 12)),
        #0001 calc((100%)*( 1 / 12)),
        #0001 calc((100%)*( 2 / 12))
    );
    mix-blend-mode: multiply;
    opacity: 0.5;
}

.outer-inner-ring {
    background: var(--clr);
    width: 36%; height: 36%;
    border-radius: 100%;
    box-shadow: 
    -1em -1em 3em -1em #fff3,
    1em 1em 3em -1em #000a,
    0.2em 0.2em 0.3em -0.1em #0001,
    0.2em 0.2em 2em -1em #000,
    inset 0.4em 0.4em 1em -0.2em #fffa,
    inset 1em 1em 1.6em -0.5em #fff2,
    inset 0em 0em 1em 0.6em #0005
    ;
}
.inner-inner-ring {
    background: var(--clr);
    width: 24%; height: 24%;
    border-radius: 100%;
    box-shadow: 
    inset 0em 0em 0.6em -0.1em #fff4,
    inset -2em -2em 2em -2em #fff2,
    inset 2em 2em 2em -2em #0002,
    -0.1em -0.1em 1em 0em #fffa,
    -1em -1em 3em 1em #fff4,
    0.1em 0.1em 1em 0em #000a,
    1em 1em 3em 1em #0004;
}

.minihud, .minhud * {
    position: absolute; left: 0; right: 0; top: 0; bottom: 0; margin: auto;
}
.minihud {
    width: 12em; height: 12em;
    border-radius: 100%;
}
.minihud{
    background: linear-gradient(-45deg, #111 0%, #444 100%);
    filter: blur(0.1px);
    box-shadow: inset 1em 1em 3em 0em #0a0a0a;
}
.minihud *:not(.metal-ring) {
    transition: opacity 3s ease-in-out;
}
.metal-ring {
    width: 100%; height: 100%;
    border-radius: 100%;
    box-shadow: 
    -0.2em -0.2em 0.3em 0em #fff7,
    0.1em 0.1em 0.3em 0em #000a,
    0em 0em 0em 0.04em #2c2c2c,
    inset 0em 0em 0.1em 0.02em #0007,
    inset 0.1em 0.1em 0.1em 0em #fffc,
    inset -0.1em -0.1em 0.1em 0em #0005,
    inset 0 0 0.1em 0.3em #777,
    inset 0.2em 0.2em 0.4em 0.2em #0005,
    inset -0.2em -0.2em 0.1em 0.1em #fffa,
    inset 0 0 0 0.4em #777;
    rotate: 90deg;
    filter: contrast(1.4) blur(0.1px);
}
.minihud .scene {
    width: 94%; height: 94%;
    border-radius: 10em;
    overflow: hidden;
}
.minihud .scene,
.minihud .scene *{
    position: absolute; margin: auto;
    top: 0; bottom: 0; left: 0; right: 0;
}

.minihud .scene .sky {
    width: 100%;
    height: 100%;
    bottom: unset;
    
    transition: --clr1 1s, --clr2 1s, --clr3 1s, --clr4 1s;
    background: linear-gradient(170deg, var(--clr1), var(--clr2), var(--clr3), var(--clr4));
    animation: daynight 1s linear infinite alternate;
    animation-play-state: paused;
    animation-delay: calc(( var(--percentage-of-day) ) * -1s);
}
@property --clr1 { syntax: '<color>'; inherits: false; initial-value: #fff; }
@property --clr2 { syntax: '<color>'; inherits: false; initial-value: #fff; }
@property --clr3 { syntax: '<color>'; inherits: false; initial-value: #fff; }
@property --clr4 { syntax: '<color>'; inherits: false; initial-value: #fff; }
@keyframes daynight {
    0%  { --clr1:#061420; --clr2:#18354e; --clr3:#41698b; --clr4:#73add0; }
    15%  { --clr1:#061420; --clr2:#18354e; --clr3:#41698b; --clr4:#73add0; }
    30%  { --clr1:#8f5a6c; --clr2:#d58078; --clr3:#fbe280; --clr4:#fdfdc6; }
    50%   { --clr1:#0180b9; --clr2:#3399c9; --clr3:#8ce2de; --clr4:#e2f9f8; }
    65%   { --clr1:#0180b9; --clr2:#3399c9; --clr3:#8ce2de; --clr4:#e2f9f8; }
    80%  { --clr1:#8f5a6c; --clr2:#d58078; --clr3:#fbe280; --clr4:#fdfdc6; }
    90%  { --clr1:#061420; --clr2:#18354e; --clr3:#41698b; --clr4:#73add0; }
    100%  { --clr1:#061420; --clr2:#18354e; --clr3:#41698b; --clr4:#73add0; }
}

.minihud .scene .clouds {
    background: #aaa;
    width: 100%;
    min-width: 150px;
    min-height: 24px;
    height: 28%;
    top: unset;
    z-index: 3;
    border: 1px solid #fff;
    padding: 2%;
    rotate: 0deg;
    scale: 2.4;
    translate: 0 40%;
    filter: url(#cloud1) blur(1.2px);
    -webkit-filter: url(#cloud1) blur(1.2px);

    animation: clouds 20s linear infinite;
}
.minihud .scene .clouds::before {
    content: ""; display: block;
    position: absolute;
    width: 100%; height: 64%;
    margin: 0; 
    top: 0px;
    left: 0px;
    right: 0px;
    bottom: 0px;
    border: 0.1em solid #fff;
    box-shadow: 0 0 3em #fff;
    filter: url(#cloud1) blur(2px);
    -webkit-filter: url(#cloud1) blur(2px);
  
    z-index: -2;
}
@keyframes clouds {
    0% { opacity: 0;}
    5% { opacity: 1;}
    95% { opacity: 1;}
    100% { opacity: 0;}
}
.minihud .scene .clouds.sec {
    height: 24%;
    filter: url(#cloud2) blur(1.2px);
    -webkit-filter: url(#cloud2) blur(1.2px);
    animation: clouds 33s linear infinite;
}
.minihud .scene .clouds.sec::before {
    filter: url(#cloud2) blur(2px);
    -webkit-filter: url(#cloud2) blur(2px);
}
              
            
!

JS

              
                document.addEventListener('DOMContentLoaded', function() {
    document.documentElement.style.transition = 'filter 3s ease-out';
    document.documentElement.style.filter = 'grayscale(0) brightness(1) contrast(1) brightness(1)';
});

function getTime() {
    const now = new Date();
    const hours = now.getHours();
    const minutes = now.getMinutes();
    const seconds = now.getSeconds();
    const hours12 = hours % 12;
    return { hours, hours12, minutes, seconds };
}

function getClockRotation() {
    const { hours, minutes } = getTime();
    const thr = hours + ( minutes / 60 ); 
    const totalRotation = 720 * thr /24;
    return totalRotation;
}

function getPercentageOfDay() {
    const pod = getClockRotation() / 720;
    return pod.toFixed(2);
}

document.body.style.setProperty('--rotate-hour', getClockRotation()+90 );
document.body.style.setProperty('--pecentage-of-day', getPercentageOfDay());
document.body.querySelector('.minihud .scene .sky').style.animationDelay = `calc(${ getPercentageOfDay()} * -1s)`;

function showCurrentTime() {
    const { hours12, minutes } = getTime();
    let disHour = hours12
    const timeContainer = document.getElementById('timeContainer');
    if (disHour == 0 ){ disHour = 12; }
    timeContainer.textContent = `${String(disHour)}:${String(minutes).padStart(2, '0')}`;
    
    updateBgColor(getPercentageOfDay());
    document.body.style.setProperty('--rotate-hour', getClockRotation() );
}
showCurrentTime();
setTimeout(function() {
    showCurrentTime();
    setInterval(showCurrentTime, 1000 * 60);
}, (60 - getTime().seconds) * 1000);

function smoothCurve(val) {
    return (1 - Math.cos(2 * Math.PI * val + Math.PI)) / 2;
}
function updateBgColor(percentage) {
    percentage = smoothCurve(percentage);
    const dayColor = getComputedStyle(document.querySelector('body')).getPropertyValue('--clr-d').trim().slice(1).match(/.{2}/g).map(hex => parseInt(hex, 16));
    const nightColor = getComputedStyle(document.querySelector('body')).getPropertyValue('--clr-n').trim().slice(1).match(/.{2}/g).map(hex => parseInt(hex, 16));
    const currentColor = dayColor.map((start, index) => {
        const end = nightColor[index];
        return Math.round(start + percentage * (end - start));
    });
    const currentColorHex = `#${currentColor.map(c => c.toString(16).padStart(2, '0')).join('')}`;
    
    document.querySelector('body').style.setProperty('--clr', currentColorHex);
}
updateBgColor(getPercentageOfDay());

document.querySelectorAll('.hour').forEach(hour => {
    let isDragging = false;
    let lastAngle = null;
    let cumulativeRotation = 0;
    let initialRotation = 0;

    hour.addEventListener('mouseenter', () => {
        hour.classList.add('hovered');
    });

    hour.addEventListener('mouseleave', () => {
        hour.classList.remove('hovered');
    });

    hour.addEventListener('mousedown', (e) => {
        isDragging = true;
        hour.classList.add('dragging');
        e.preventDefault();

        const centerX = window.innerWidth / 2;
        const centerY = window.innerHeight / 2;
        const deltaX = e.clientX - centerX;
        const deltaY = e.clientY - centerY;
        const angleInRadians = Math.atan2(deltaY, deltaX);
        let angleInDegrees = (angleInRadians * (180 / Math.PI)) + 180;

        initialRotation = parseFloat(getComputedStyle(document.body).getPropertyValue('--rotate-hour').replace('deg', ''));
        lastAngle = angleInDegrees;
        cumulativeRotation = initialRotation;
    });

    window.addEventListener('mousemove', (e) => {
        if (isDragging) {
            const centerX = window.innerWidth / 2;
            const centerY = window.innerHeight / 2;
            const deltaX = e.clientX - centerX;
            const deltaY = e.clientY - centerY;
            const angleInRadians = Math.atan2(deltaY, deltaX);
            let angleInDegrees = (angleInRadians * (180 / Math.PI)) + 180;
            if (lastAngle === null) {
                lastAngle = angleInDegrees;
            }
            let angleDifference = angleInDegrees - lastAngle;
            if (angleDifference > 180) {
                angleDifference -= 360;
            } else if (angleDifference < -180) {
                angleDifference += 360;
            }
            cumulativeRotation += angleDifference;
            if (cumulativeRotation < 0) {
                cumulativeRotation += 720;
            } else if (cumulativeRotation >= 720) {
                cumulativeRotation -= 720;
            }
            lastAngle = angleInDegrees;
            let percentage = (cumulativeRotation / 720).toFixed(3);

            document.body.style.setProperty('--rotate-hour', cumulativeRotation.toFixed(2));
            document.body.style.setProperty('--percentage-of-day', percentage);
            updateBgColor(percentage);
            document.body.querySelector('.minihud .scene .sky').style.animationDelay = `calc(${(cumulativeRotation / 720).toFixed(2)} * -1s)`;
        }
    });

    window.addEventListener('mouseup', () => {
        if (isDragging) {
            setTimeout(function (){
                isDragging = false;
            }, 100); 
            hour.classList.remove('dragging');
            const currentRotation = parseFloat(getComputedStyle(document.body).getPropertyValue('--rotate-hour').replace('deg', ''));
            const degreeIncrement = (getClockRotation()) - currentRotation;

            smoothRotateClock(degreeIncrement, 1000);
        }
    });
});

function smoothRotateClock(degreeIncrement, duration) {
    const startRotation = parseFloat(getComputedStyle(document.body).getPropertyValue('--rotate-hour').replace('deg', ''));
    const frameRate = 60;
    const totalFrames = (duration / 1000) * frameRate;
    let currentFrame = 0;
    function rotate() {
        currentFrame++;
        const progress = currentFrame / totalFrames;
        const currentRotation = startRotation + degreeIncrement * easeInOutCubic(progress);
        document.body.style.setProperty('--rotate-hour', `${currentRotation}`);
        updateBgColor(currentRotation/720);
        document.body.querySelector('.minihud .scene .sky').style.animationDelay = `calc(${currentRotation/720} * -1s)`;
        if (currentFrame < totalFrames) {
            requestAnimationFrame(rotate);
        }
    }
    rotate();
}
function easeInOutCubic(t) {
    return t < 0.5 ? 4 * t * t * t : 1 - Math.pow(-2 * t + 2, 3) / 2;
}
              
            
!
999px

Console