.clock-wrapper
  .bg
  .knob
  .knob-lines#knob-lines
    - (0..14).each do |i|
      .knob-line
  .btn#ampm
  .btn.radio-btn#radio-btn
    %span radio
  .logo Ika
  .minutes
    .dizaines
      - (0..5).each do |i|
        .number{:id => "minutes-dizaines-#{i}"} 
          .up
            .digit #{i}
          .down
            .digit #{i}
    .unites
      - (0..9).each do |i|
        .number{:id => "minutes-unites-#{i}"} 
          .up
            .digit #{i}
          .down
            .digit #{i}
  .hours
    .dizaines
      - (0..1).each do |i|
        .number{:id => "hours-dizaines-#{i}"} 
          .up
            .digit #{i}
          .down
            .digit #{i}
    .unites
      - (0..9).each do |i|
        .number{:id => "hours-unites-#{i}"} 
          .up
            .digit #{i}
          .down
            .digit #{i}
  .seconds-wrapper
    #seconds.seconds
      - (0..59).each do |i|
        .second #{i}
View Compiled
$colors-beige: (
  100: #eeead1,
  200: #eadfb5,
  300: #c4baaf
);

$colors-green: (
  100: #10ffa6,
  200: #6fd1b5,
  300: #6ac5a9
);

$colors-purple: (
  100: #6e4875,
  200: #472c4b
);

$colors-yellow: (
  100: #fdb800
);

$colors-red: (
  100: #f85302
);

$colors-blue: (
  100: #00f1ff
);

body {
  background: map-get($colors-green, 200);
  font-family: 'ATC Duel';
  text-align: center;
}

.minutes,
.hours,
.unites,
.dizaines,
.number,
.logo,
.btn,
.seconds-wrapper,
.seconds,
.second,
.seconds-wrapper:before,
.clock-wrapper:before,
.clock-wrapper:after,
.up,
.down,
.digit,
.knob,
.knob-lines,
.hours:before,
.bg { position: absolute; }

.clock-wrapper {
  position: relative;
  z-index: 1;
  
  display: inline-block;
  margin: 33.5vmin 8.5vmin;
  width: 83vmin;
  height: 26.5vmin;
  
  &:before {
    right: 5vmin;
    bottom: -4vmin;
    left: 5vmin;
    
    display: block;
    height: 4vmin;
    
    background: map-get($colors-beige, 200);
    border-top: 1vmin solid map-get($colors-green, 300);
    
    content: '';
    
    transform: perspective(200px) rotateX(10deg);    
  }
  
  &:after {
    bottom: -4vmin;
    z-index: -1;
    
    display: block;
    width: 100%;
    height: 100%;
    
    background: map-get($colors-green, 300);
    border-radius: 1vmin;
    
    content: '';
    
    transform: perspective(100vmin) rotateX(60deg) skew(60deg);
    transform-origin: bottom right;
  }
  
  .bg {
    width: 100%;
    height: 100%;
    
    background: map-get($colors-beige, 100);
    border-radius: 1vmin;
  }
}

.seconds-wrapper {
  top: 5vmin;
  right: 16vmin;
  bottom: 5vmin;
  
  width: 8vmin;
  overflow: hidden;
  
  background: map-get($colors-purple, 200);
  border-radius: 0.5vmin;
  
  &:before {
    top: 50%;
    left: 0;
    z-index: 1;
    
    display: block;
    border: 1vmin solid transparent;
    border-right-width: 3.66vmin;
    border-left: 3.66vmin solid map-get($colors-red, 100);
    
    content: '';
    
    transform: translateY(-50%);
  }
}

.seconds {
  top: 50%;
  margin-top: 1.3vmin;
  
  transform-style: preserve-3d;
  backface-visibility: hidden;
  
  animation: secondsTick 60s infinite linear;
  animation-play-state: paused;
}


@-webkit-keyframes secondsTick {
  0% { -webkit-transform: rotateX(0deg); }
  100% { -webkit-transform: rotateX(-360deg); }
}

@-moz-keyframes secondsTick {
  0% { -moz-transform: rotateX(0deg); }
  100% { -moz-transform: rotateX(-360deg); }
}

@-ms-keyframes secondsTick {
  0% { -ms-transform: rotateX(0deg); }
  100% { -ms-transform: rotateX(-360deg); }
}

@keyframes secondsTick {
  0% { transform: rotateX(0deg); }
  100% { transform: rotateX(-360deg); }
}

.second {
  font-size: 1.5vmin;
  color: map-get($colors-yellow, 100);
  text-align: center;
  white-space: nowrap;
  line-height: 2.6vmin;
  letter-spacing: 0.05em;
  
  backface-visibility: hidden;
  
  &:before {
    display: inline-block;
    margin: -0.3vmin 1.3vmin 0 1vmin;
    width: 2.6vmin;
    height: 0.26vmin;
    
    background: currentColor;
    
    content: '';
    vertical-align: middle;
  }
  
  @for $i from 1 to 61 {
    &:nth-child(#{$i}) {
      transform: rotateX(#{$i * 6}deg) translateZ(24.737347581vmin);
    }
  }
}

.btn {
  top: 12.5vmin;
  right: 5vmin;
  
  padding: 1.3vmin 0 1.1vmin;
  width: 6.5vmin;
  
  background: currentColor;
  box-shadow:
    inset 0 0 3vmin rgba(black, 0.2),
    0 0 6vmin rgba(lighten(map-get($colors-green, 100), 20%), 0.75);
  
  color: map-get($colors-green, 100);
  line-height: 1;
  font-family: 'ATC Timberline';
  font-size: 1vmin;
  text-transform: uppercase;
  text-align: center;

  span {
    color: white;
    transition: color 0.3s;
  } 
}

.radio-btn {
  top: auto;
  bottom: 5vmin;
  
  cursor: pointer;
  box-shadow:
    inset 0 0 3vmin rgba(black, 0.2),
    0 0 6vmin rgba(lighten(map-get($colors-blue, 100), 20%), 0.75);
  
  color: map-get($colors-blue, 100);
  
  transition: box-shadow 0.3s;
  
  span { 
    color: rgba(white, 0.7); 
  }
  
  &:hover,
  &.is-active {
    box-shadow:
      inset 0 0 3vmin rgba(black, 0.3),
      0 0 6vmin rgba(lighten(map-get($colors-blue, 100), 20%), 1);
      
    span { color: white; }
  }
}

.logo {
  top: 5vmin;
  right: 5vmin;
  
  font-family: 'ATC Timberline';
  color: map-get($colors-purple, 200);
  text-transform: uppercase;
  font-size: 2.6vmin;
  line-height: 1;
}

.minutes,
.hours {
  top: 5vmin;
  bottom: 5vmin;
  width: 25vmin;
}

.minutes { right: 26vmin; }
.hours { left: 5vmin; }
.unites, .dizaines { width: calc(50% - 1vmin); }
.unites { right: 0; }
.dizaines { left: 0; }

.hours {
  &:before {
    top: 50%;
    right: -1.3vmin;
    
    display: block;
    margin-top: -2vmin;
    width: 0.8vmin;
    height: 4vmin;
    
    background: map-get($colors-purple, 100);
    
    content: '';
  }
}

.number {
  width: 100%;
  height: 16.5vmin;
  
  color: map-get($colors-yellow, 100);
  
  font-size: 12vmin;
  line-height: 16vmin;
  
  &.is-active { 
    animation: zIndexUp 0.5s forwards;
  }
  
  &.outgoing { 
    animation: zIndexDown 0.5s forwards;
  }
}

@-webkit-keyframes zIndexUp {
  0% { z-index: 1; }
  100% { z-index: 2; }
}

@-moz-keyframes zIndexUp {
  0% { z-index: 1; }
  100% { z-index: 2; }
}

@-ms-keyframes zIndexUp {
  0% { z-index: 1; }
  100% { z-index: 2; }
}

@keyframes zIndexUp {
  0% { z-index: 1; }
  100% { z-index: 2; }
}

@-webkit-keyframes zIndexDown {
  0% { z-index: 2; }
  100% { z-index: 1; }
}

@-moz-keyframes zIndexDown {
  0% { z-index: 2; }
  100% { z-index: 1; }
}

@-ms-keyframes zIndexDown {
  0% { z-index: 2; }
  100% { z-index: 1; }
}

@keyframes zIndexDown {
  0% { z-index: 2; }
  100% { z-index: 1; }
}

.up, 
.down {
  width: 100%;
  height: calc(50% - 1px);
  overflow: hidden;

  background: map-get($colors-purple, 200);
  border-radius: 0.7vmin;
  
  transform-style: preserve-3d;
  backface-visibility: hidden;
  transition: none;
  
  &:before {
    position: absolute;
    z-index: 1;
    
    display: block;
    width: 100%;
    height: 100%;
    
    content: '';
    
    transition: opactiy 0.25s;
  }
}

.up { 
  top: 0; 
  transform-origin: bottom center;
  
  &:before {
    bottom: 0;
    background: linear-gradient(to top, rgba(black, 0.5), transparent);
  }
  
  .digit { line-height: 15vmin; }
}

.down { 
  bottom: 0; 
  transform: perspective(100vmin) rotateX(180deg);
  transform-origin: top center;
  
  &:before {
    top: 0;
    background: linear-gradient(to bottom, rgba(black, 0.5), transparent);
  }
  
  .digit { 
    bottom: 0; 
    line-height: 18vmin;
  } 
}

.digit { width: 100%; }

.is-active {
  .up:before,
  .down:before { opacity: 0; }
  
  .down {
    transform: perspective(100vmin) rotateX(0deg);
    transition: transform 0.5s;
  }
}

.outgoing {
  .up {
    transform: perspective(100vmin) rotateX(-180deg);
    transition: transform 0.5s;
  }
  
  .down {
    transform: perspective(100vmin) rotateX(0deg);
    transition: transform 0.5s;
  }
}

.knob {
  top: 50%;
  right: -4vmin;
  
  width: 3vmin;
  height: 15vmin;
  
  background: map-get($colors-beige, 100);
  border-radius: 0 1vmin 1vmin 0;
  
  transform: translateY(-50%);
}

.knob-lines {
  top: 50%;
  right: -3vmin;
  
  transform-style: preserve-3d;
  backface-visibility: hidden;
  
  transform: translateY(-50%);
}

.knob-line {
  margin: 0.75vmin 0;
  width: 2.6vmin;
  height: 0.25vmin;
  
  background: map-get($colors-purple, 200);
}
View Compiled
function startTime() {
    var today=new Date();
    var h=today.getHours();
    var m=today.getMinutes();
    var ampm = h >= 12 ? 'pm' : 'am';
    h = h % 12;
    h = h ? h : 12; // the hour '0' should be '12'
    h = String(checkTime(h)).split('');
    m = String(checkTime(m)).split('');

  // let's clear the old outgoing
  var oldOutgoing = document.querySelectorAll('.outgoing');
  var i;
  for (i = 0; i < oldOutgoing.length; i++) {
      oldOutgoing[i].className = 'number';
  }
  
  // let's get minutes going
  var minutesDizainesOutgoingId = m[0] - 1 === -1 ? 5 : m[0] - 1;
  var minutesDizainesOutgoing = document.getElementById('minutes-dizaines-' + minutesDizainesOutgoingId);
  var minutesDizaines = document.getElementById('minutes-dizaines-' + m[0]);
  
  var minutesUnitesOutgoingId = m[1] - 1 === -1 ? 9 : m[1] - 1;
  var minutesUnitesOutgoing = document.getElementById('minutes-unites-' + minutesUnitesOutgoingId);
  var minutesUnites = document.getElementById('minutes-unites-' + m[1]);
  
  minutesDizaines.className = 'number is-active';
  minutesDizainesOutgoing.className = 'number outgoing';
  minutesUnites.className = 'number is-active';
  minutesUnitesOutgoing.className = 'number outgoing';
  
  // clear outgoing 
  
  // let's get hours going
  var hoursDizainesOutgoingId = h[0] - 1 === -1 ? 1 : h[0] - 1;
  var hoursDizainesOutgoing = document.getElementById('hours-dizaines-' + hoursDizainesOutgoingId);
  var hoursDizaines = document.getElementById('hours-dizaines-' + h[0]);
  
  var hoursUnitesOutgoingId = h[1] - 1 === -1 ? 9 : h[1] - 1;
  var hoursUnitesOutgoing = document.getElementById('hours-unites-' + hoursUnitesOutgoingId);
  var hoursUnites = document.getElementById('hours-unites-' + h[1]);
  
  hoursDizaines.className = 'number is-active';
  hoursDizainesOutgoing.className = 'number outgoing';
  hoursUnites.className = 'number is-active';
  hoursUnitesOutgoing.className = 'number outgoing';
  
  // am pm
  document.getElementById('ampm').innerHTML = '<span>' + ampm + '</span>';
  
  var t = setTimeout(function(){startTime()}, 500);
}

function checkTime(i) {
    if (i<10) {i = "0" + i};  // add zero in front of numbers < 10
    return i;
}

startTime();

// get the seconds rolling
var today=new Date();
var s=today.getSeconds();
var secondsElement = document.getElementById('seconds');

secondsElement.style.webkitAnimation = 'secondsTick 60s ' + -s + 's infinite linear'; 
// apparently webkiteAnimationDelay doesn't work properly, i'm probably missing something but this seems to fix it
secondsElement.style.webkitAnimationPlayState = 'running';

secondsElement.style.mozAnimationDelay = -s + 's';
secondsElement.style.mozAnimationPlayState = 'running';

secondsElement.style.msAnimationDelay = -s + 's';
secondsElement.style.msAnimationPlayState = 'running';

secondsElement.style.animationDelay = -s + 's';
secondsElement.style.animationPlayState = 'running';

// get the audio player going
var radio = document.createElement("AUDIO");
radio.setAttribute("src","http://blobfolio.com/codepenfiles/atc-flip-clock/390917_AhWilderness.mp3");
radio.setAttribute("id", "radio-player");
radio.setAttribute("loop", "true");
radioBtn = document.getElementById("radio-btn");

radioBtn.addEventListener("click", function(){
  if((' ' + radioBtn.className + ' ').indexOf(' is-active ') > -1){
    radioBtn.className = "btn radio-btn";
    radio.muted = true;
  }
  
  else {
    radioBtn.className = "btn radio-btn is-active";
    radio.play();
    radio.muted = false;
  }
});

External CSS

  1. https://s3-us-west-2.amazonaws.com/s.cdpn.io/80729/helpers.css
  2. https://s3-us-west-2.amazonaws.com/s.cdpn.io/80729/atc-fonts.css

External JavaScript

This Pen doesn't use any external JavaScript resources.