mixin paw(className)
  .clock__paw(class=`clock__paw--${className}`)
    - let p = 0
    while p < 5
      .clock__pad
      - p++
.clock
  .clock__face
    .clock__mouth
      .clock__tongue
    .clock__whiskers
      - let w = 0
      while w < 4
        .clock__whisker
        - w++
  .clock__eyes
    .clock__eye.clock__eye--left
      .clock__pupil
    .clock__eye.clock__eye--right
      .clock__pupil
  .clock__nose
  .clock__body
    - let d = 0
    while (d < 12)
      .clock__dot(style=`--index: ${d};`)
      - d++
    .clock__hand.clock__hand--minutes
    .clock__hand.clock__hand--hours
  +paw('top-left')
  +paw('top-right')
  +paw('bottom-left')
  +paw('bottom-right')
  .clock__tail
  .clock__bowtie
View Compiled
*
*:after
*:before
  box-sizing border-box

:root
  --hue 320
  --white hsl(0, 0%, 95%)
  --black hsl(0, 0%, 25%)
  --aspect-ratio calc(300 / 800)
  // 75vmin === 800px then 75 / 800 === 1px in our drawing
  --unit calc((80 / 800) * 1vmin)
  // --unit 1px
  --width calc(300 * var(--unit))
  --height calc(800 * var(--unit))
svg
  // width calc(var(--width) * 1px)
  width 30vmin
  height 80vmin
  position fixed
  top 50%
  // display none


  &:nth-of-type(1)
    left 50%
    transform translate(-50%, -50%)
    opacity 0.15


  &:nth-of-type(2)
    right 0
    height 800px
    width 300px
    transform translate(0, -50%)

body
  min-height 100vh
  background var(--black)
  display flex
  align-items center
  justify-content center
  transform-origin top center

.clock
  height calc(var(--height))
  width calc(var(--width))
  position relative

  &__eye
    --size 134
    height calc(var(--size) * var(--unit))
    width calc(var(--size) * var(--unit))
    background var(--white)
    position absolute
    top calc(17 * var(--unit))
    border-radius 50%
    border calc(6 * var(--unit)) solid var(--black)
    left 50%

    // Eyebrows
    &:after
      content ''
      height 110%
      width 110%
      border calc(4 * var(--unit)) solid var(--white)
      border-radius 50%
      position absolute
      top 50%
      left 50%
      $clip = polygon(50% 50%, 94% 0, 6% 0)
      -webkit-clip-path $clip
      clip-path $clip

    &--left
      transform translate(-100%, 0%)
      &:after
        transform translate(-50%, -60%)

    &--right
      transform translate(0%, 0%)
      &:after
        transform translate(-50%, -60%)
  &__body
    --size 200
    background var(--white)
    height calc(var(--size) * var(--unit))
    width calc(var(--size) * var(--unit))
    position absolute
    top 46%
    left 50%
    transform translate(-50%, -50%)
    border-radius 50%

    &:after
      --size calc(25 * var(--unit))
      content ''
      position absolute
      top 50%
      left 50%
      border-radius 50%
      background var(--black)
      height var(--size)
      width var(--size)
      transform translate(-50%, -50%)

  &__dot
    --size 10
    --radius 90
    height calc(var(--size) * var(--unit))
    width calc(var(--size) * var(--unit))
    background var(--black)
    border-radius 50%
    top 50%
    left 50%
    position absolute
    transform translate(-50%, -50%) rotate(calc(((360/12) * var(--index)) * 1deg)) translate(0, calc(var(--radius) * var(--unit)))

  &__paw
    --height 70
    --width 80
    position absolute
    height calc(var(--height) * var(--unit))
    width calc(var(--width) * var(--unit))

    &--top-left
      top calc(238 * var(--unit))
      left 0

    &--bottom-left
      top calc(448 * var(--unit))
      left 0

    &--top-right
      top calc(238 * var(--unit))
      right 0

    &--bottom-right
      top calc(448 * var(--unit))
      right 0

  &__pad
    --size calc(20 * var(--unit))
    height var(--size)
    width var(--size)
    background var(--white)
    position absolute
    border-radius 50%

    &:nth-of-type(1)
      left 0%
      top 20%

    &:nth-of-type(2)
      left 24%
      top 0%

    &:nth-of-type(3)
      left 52%
      top 0%

    &:nth-of-type(4)
      right 0%
      top 20%

    &:nth-of-type(5)
      --size calc(50 * var(--unit))
      bottom 0%
      left 50%
      transform translate(-50%, 0)
  &__face
    background var(--white)
    position absolute
    top calc(136 * var(--unit))
    left calc(20 * var(--unit))
    height calc(90 * var(--unit))
    width calc(260 * var(--unit))
    border-radius 0 0 50% 50% / 0 0 100% 100%
  &__nose
    background var(--black)
    position absolute
    height calc(45 * var(--unit))
    width calc(70 * var(--unit))
    top calc(115 * var(--unit))
    border-radius 50%
    left 50%
    transform translate(-50%, 0)

  &__mouth
    position absolute
    height calc(60 * var(--unit))
    width calc(110 * var(--unit))
    background var(--black)
    border-radius 50%
    bottom calc(5 * var(--unit))
    left 50%
    transform translate(-50%, 0)

    &:before
    &:after
      content ''
      position absolute
      top 0
      height 50%
      width 55%
      background var(--white)

    &:before
      right 49%
      border-radius 0 0 40% 35%
    &:after
      left 49%
      border-radius 0 0 35% 40%

  &__tongue
    width 100%
    height 100%
    overflow hidden
    border-radius 50%
    position relative

    &:before
      content ''
      position absolute
      bottom 0
      height 40%
      width 50%
      background hsl(0, 90%, 55%)
      border-radius 50%
      left 50%
      transform translate(-45%, 50%)

  &__whiskers
    height 100%
    width 100%
    position relative

  &__whisker
    background var(--black)
    height calc(5 * var(--unit))
    width calc(70 * var(--unit))
    position absolute
    left 50%
    top 50%

    &:nth-of-type(1)
      transform-origin right
      transform translate(-160%, -550%) rotate(-5deg)
    &:nth-of-type(2)
      transform-origin right
      width calc(56 * var(--unit))
      transform translate(-160%, -350%) rotate(-15deg)
    &:nth-of-type(3)
      transform-origin left
      transform translate(60%, -550%) rotate(5deg)
    &:nth-of-type(4)
      transform-origin left
      width calc(56 * var(--unit))
      transform translate(60%, -350%) rotate(15deg)

  &__tail
    --swing 38
    width calc(140 * var(--unit))
    height calc(280 * var(--unit))
    position absolute
    bottom 0
    left 50%
    transform translate(-50%, 0)
    transform-origin top center
    animation swing 1s infinite alternate ease-in-out

    &:after
      content ''
      background var(--white)
      position absolute
      height calc(70 * var(--unit))
      width calc(50 * var(--unit))
      bottom 0
      left 50%
      transform-origin bottom left
      transform translate(-18%, 0) rotate(-30deg)
      border-radius 0 0 50% 50% / 0 0 50% 50%
      $clip = polygon(0 0, 100% 25%, 100% 100%, 0 100%)
      -webkit-clip-path $clip
      clip-path $clip

    @keyframes swing
      from
        transform translate(-50%, 0) rotate(calc(var(--swing) * -1deg))
      to
        transform translate(-50%, 0) rotate(calc(var(--swing) * 1deg))

  // Pupils
  &__pupil
    position absolute
    top 50%
    left 50%
    height 92%
    width 15%
    transform translate(-50%, -50%)
    animation shift 1s infinite alternate ease-in-out

    &:before
      content ''
      height 100%
      width 100%
      background var(--black)
      border-radius 50%
      position absolute
      top 50%
      left 50%
      transform translate(-50%, -50%)
      animation scale 0.5s infinite ease-in-out alternate

    @keyframes scale
      0%
        transform translate(-50%, -50%) scale(0.6)
      100%
        transform translate(-50%, -50%) scale(1)

    @keyframes shift
      0%
        transform translate(-50%, -50%) translate(-250%, 0)
      100%
        transform translate(-50%, -50%) translate(250%, 0)
  &__bowtie
    --size calc(20 * var(--unit))
    border-radius 50%
    position absolute
    background 'hsl(%s, 60%, 60%)' % var(--hue)
    left 50%
    top calc(236 * var(--unit))
    transform translate(-50%, 0)
    height var(--size)
    width var(--size)

    &:after
    &:before
      content ''
      position absolute
      height 160%
      width 160%
      background 'hsl(%s, 60%, 60%)' % var(--hue)
      top 50%
      transform translate(0, -50%) rotate(calc(var(--rotate, 0) * 1deg))
      $clip = polygon(0 0, 100% 50%, 0 100%)
      -webkit-clip-path $clip
      clip-path $clip

    &:after
      --rotate 180
      left 15%
    &:before
      right 15%

  &__hand
    position absolute
    width calc(5 * var(--unit))
    background var(--black)
    border-radius calc(2 * var(--unit)) calc(2 * var(--unit)) 0 0
    top 50%
    left 50%
    transform-origin bottom center

    &:before
      content ''
      position absolute
      bottom 0
      left 50%
      transform translate(-50%, 0)
      width calc(12 * var(--unit))
      height 80%
      background var(--black)
      $clip = polygon(50% 0, 100% 20%, 75% 100%, 25% 100%, 0 20%)
      -webkit-clip-path $clip
      clip-path $clip

    &--minutes
      --seconds 3600
      height 40%
      transform translate(-50%, -100%) rotate(0deg)
      animation time calc(var(--seconds) * 1s) calc(var(--minutes-delay, 0) * -1s) infinite linear
    &--hours
      --seconds 43200
      height 35%
      transform translate(-50%, -100%) rotate(270deg)
      animation time calc(var(--seconds) * 1s) calc(var(--hours-delay) * -1s) infinite linear

    @keyframes time
      0%
        transform translate(-50%, -100%) rotate(0deg)
      100%
        transform translate(-50%, -100%) rotate(360deg)
View Compiled
const CLOCK = document.querySelector('.clock')
const DATE = new Date()
const MINUTES = DATE.getMinutes()
const HOURS = DATE.getHours() % 12

CLOCK.style.setProperty('--hue', Math.random() * 360)
CLOCK.style.setProperty('--minutes-delay', (3600 / 60) * MINUTES)
CLOCK.style.setProperty(
  '--hours-delay',
  (43200 / 12) * HOURS + (43200 / 12 / 60) * MINUTES
)
View Compiled

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.