mixin cuboid()
  .cuboid(class!=attributes.class)
    if block
      block
    - let s = 0
    while s < 6
      .cuboid__side
      - s++
.rotater(data-multiplier="-2" style=`--index: 0;`)
.rotater(data-multiplier="-1" style=`--index: 1;`)
.rotater(data-multiplier="0" style=`--index: 2;`)
.rotater(data-multiplier="1" style=`--index: 3;`)
.rotater(data-multiplier="2" style=`--index: 4;`)
.scene
  form.stopwatch
    input#start(type='checkbox')
    input#pause(type='checkbox')
    .stopwatch__chords
      .stopwatch__chord
        +cuboid()
      .stopwatch__chord
        +cuboid()
    .stopwatch__back
    .stopwatch__content
      img.stopwatch__logo(src="https://assets.codepen.io/605876/Bear+%E2%80%93+2021+.png" alt="new bear logo")
      .stopwatch__face
        .digit.m.m--tens 0
        .digit.m.m--singles 0
        span :
        .digit.second.s.s--tens 0
        .digit.second.s.s--singles 0
        span .
        .digit.digit--small.ms.ms--tens 0
        .digit.digit--small.ms.ms--singles 0
    .stopwatch__glass
    .cuboid.stopwatch__body
      .cuboid__side
        .stopwatch__body-angle
          +cuboid.stopwatch__frame
          button.stopwatch__control.stopwatch__reset(type='reset')
            .button__placeholder
              +cuboid.button__container
                +cuboid.button
        .stopwatch__body-angle
          +cuboid.stopwatch__frame
        .stopwatch__body-angle
          +cuboid.stopwatch__frame
          label.stopwatch__control.stopwatch__pause(for="pause")
            .button__placeholder
              +cuboid.button__container
                +cuboid.button
          label.stopwatch__control.stopwatch__start(for="start")
            .button__placeholder
              +cuboid.button__container
                +cuboid.button
      .cuboid__side
        .stopwatch__body-angle
          +cuboid.stopwatch__frame
        .stopwatch__body-angle
          +cuboid.stopwatch__frame
        .stopwatch__body-angle
          +cuboid.stopwatch__frame
      .cuboid__side
        .stopwatch__body-angle
          +cuboid.stopwatch__frame
        .stopwatch__body-angle
          +cuboid.stopwatch__frame
        .stopwatch__body-angle
          +cuboid.stopwatch__frame
      .cuboid__side
        .stopwatch__body-angle
          +cuboid.stopwatch__frame
        .stopwatch__body-angle
          +cuboid.stopwatch__frame
        .stopwatch__body-angle
          +cuboid.stopwatch__frame
      .cuboid__side
      .cuboid__side
View Compiled
@import url('https://fonts.googleapis.com/css2?family=Orbitron:wght@500&display=swap')

.cuboid
  width 100%
  height 100%
  position relative
  // 1 is the top and go t, r, b, l, f, b

  &__side
    filter brightness(var(--b, 1))
    position absolute

  &__side:nth-of-type(1)
    --b 1.1
    height calc(var(--depth, 20) * 1vmin)
    width 100%
    top 0
    transform translate(0, -50%) rotateX(90deg)

  &__side:nth-of-type(2)
    --b 0.9
    height 100%
    width calc(var(--depth, 20) * 1vmin)
    top 50%
    right 0
    transform translate(50%, -50%) rotateY(90deg)

  &__side:nth-of-type(3)
    --b 0.5
    width 100%
    height calc(var(--depth, 20) * 1vmin)
    bottom 0
    transform translate(0%, 50%) rotateX(90deg)

  &__side:nth-of-type(4)
    --b 1
    height 100%
    width calc(var(--depth, 20) * 1vmin)
    left 0
    top 50%
    transform translate(-50%, -50%) rotateY(90deg)

  &__side:nth-of-type(5)
    --b 0.8
    height 100%
    width 100%
    transform translate3d(0, 0, calc(var(--depth, 20) * 0.5vmin))
    top 0
    left 0

  &__side:nth-of-type(6)
    --b 1.2
    height 100%
    width 100%
    transform translate3d(0, 0, calc(var(--depth, 20) * -0.5vmin)) rotateY(180deg)
    top 0
    left 0

:root
  --stopwatch-size 40
  --stopwatch-depth 10
  --stopwatch-frame-depth 4
  --body-clip polygon(25% 0, 75% 0, 100% 25%, 100% 75%, 75% 100%, 25% 100%, 0 75%, 0 25%)
  --state paused
  --bg hsl(280, 50%, 90%)
  --digit hsl(90, 50%, 90%)
  --face hsl(90, 50%, 5%)
  --content hsl(0, 0%, 40%)
  --glare hsla(0, 0%, 100%, 0.2)
  --stopwatch-frame hsl(210, 20%, 50%)
  --glass hsla(210, 100%, 90%, 0.15)
  --chord-one hsl(0, 10%, 50%)
  --chord-two hsl(0, 10%, 30%)
  --start hsl(90, 90%, 50%)
  --reset hsl(10, 90%, 50%)

*
*:after
*:before
  box-sizing border-box
  transform-style preserve-3d

// Trick to stop/start the stopwatch
// If neither are checked the animation-name is "none"
// And that resets the counters to their initial value
#start:checked ~ .stopwatch__content
#pause:checked ~ .stopwatch__content
  .ms--tens
    --name ms-tens
  .ms--singles
    --name ms-singles
  .s--tens
    --name s-tens
  .s--singles
    --name s-singles
  .m--tens
    --name m-tens
  .m--singles
    --name m-singles

// What handles the playback. When "Start" is checked,
// the play state is running. Then we can use "Pause" to
// toggle the play start of the animations.
#start:checked ~ .stopwatch__content
  --state running
#pause:checked ~ .stopwatch__content
  --state paused
// Trick to hide the start button
#start:checked
  & ~ .stopwatch__body .stopwatch__start
    z-index -1
    display none
  & ~ .stopwatch__body .stopwatch__pause
    display block

.stopwatch__start:active ~ .stopwatch__stop-start
.stopwatch__pause:active ~ .stopwatch__stop-start
  --y 25
.stopwatch__reset:active ~ .stopwatch__restart
  --y 15

// The properties for animating each digit
// We should be able to declare these all as a chain
// But the syntax listed at: https://web.dev/at-property/#multiple-declarations
// doesn't work for me.
@property --ms-tens
  initial-value 0
  inherits false
  syntax '<integer>'

@property --ms-singles
  initial-value 0
  inherits false
  syntax '<integer>'

@property --s-tens
  initial-value 0
  inherits false
  syntax '<integer>'

@property --s-singles
  initial-value 0
  inherits false
  syntax '<integer>'

@property --m-tens
  initial-value 0
  inherits false
  syntax '<integer>'

@property --m-singles
  initial-value 0
  inherits false
  syntax '<integer>'

body
  min-height 100vh
  display grid
  place-items center
  background var(--bg)
  overflow hidden
  font-family 'Orbitron', sans-serif

[type='checkbox']
  position fixed
  width 1px
  height 1px
  padding 0
  margin -1px
  overflow hidden
  clip rect(0, 0, 0, 0)
  white-space nowrap
  border-width 0

.scene
  --rotate-y 0
  --rotate-x 0
  transform translate(-50%, -50%)
  position fixed
  top 50%
  left 50%
  transition transform 0.1s
  transform translate3d(-50%, -50%, 100vmin) rotateX(-24deg) rotateY(-24deg) rotateX(calc(var(--rotate-x, 0) * 1deg)) rotateY(calc(var(--rotate-y, 0) * 1deg))

.stopwatch
  --depth var(--stopwatch-depth)
  height calc(var(--stopwatch-size, 50) * 1vmin)
  margin 0
  width calc(var(--stopwatch-size, 50) * 1vmin)

  &__chords
    height 100vmax
    width 26%
    position absolute
    top 100%
    left 50%
    transform translate(-50%, 0)

  &__chord
    height 100%
    width 10%
    position absolute
    top 0

    .cuboid
      --depth 1
      .cuboid__side
        background repeating-linear-gradient(calc(var(--deg, 45) * 1deg), var(--chord-one) 0 1%, var(--chord-two) 1% 2%)

        &:nth-of-type(even)
          --deg -45
          --b 0.5

    &:nth-of-type(1)
      left 0
    &:nth-of-type(2)
      right 0

  &__logo
    height 20%
    position absolute
    top 80%
    left 50%
    transform translate(-50%, -50%)
    filter saturate(0)
    opacity 0.5

  &__glass
    background var(--glass)
    height 100%
    width 100%
    clip-path var(--body-clip)
    -webkit-clip-path var(--body-clip)
    position absolute
    transform translate3d(0, 0, calc(var(--stopwatch-depth) * 0.3vmin)) scale(0.85)

    &:after
      content ''
      position absolute
      height 300%
      width 300%
      transition transform 0.1s
      background linear-gradient(transparent 0 35%, var(--glare) 36% 42%, transparent 43% 45%, var(--glare) 46% 48%, transparent 49%)
      transform translate(-50%, -50%) translateX(calc(var(--shift, 0) * 1%)) rotate(-60deg)
      top 50%
      left 50%

  &__content
    background var(--content)
    height 100%
    width 100%
    clip-path var(--body-clip)
    -webkit-clip-path var(--body-clip)
    position absolute
    transform scale(0.85)

  &__face
    color var(--digit, white)
    display flex
    font-size 6vmin
    position absolute
    top 50%
    left 50%
    transform translate(-50%, -50%)
    padding 1.75vmin
    border-radius 1vmin
    background var(--face, black)

  .stopwatch__body > .cuboid__side
    &:nth-of-type(5)
    &:nth-of-type(6)
      display none

  &__back
    height 100%
    width 100%
    background var(--stopwatch-frame)
    position absolute
    transform translate3d(0, 0, calc(var(--stopwatch-depth) * -0.5vmin)) scale(1)
    -webkit-clip-path var(--body-clip)
    clip-path var(--body-clip)

.rotater
  z-index -1
  position fixed
  height 100vh
  width 20vw
  left calc(var(--index) * 20%)

[data-multiplier="-2"]:hover ~ .scene
  --shift 20
  --rotate-y calc(-2 * var(--scene-rotation, 10))
[data-multiplier="-1"]:hover ~ .scene
  --shift 10
  --rotate-y calc(-1 * var(--scene-rotation, 10))
[data-multiplier="0"]:hover ~ .scene
  --shift 0
  --rotate-y calc(0 * var(--scene-rotation, 10))
[data-multiplier="1"]:hover ~ .scene
  --shift -10
  --rotate-y calc(1 * var(--scene-rotation, 10))
[data-multiplier="2"]:hover ~ .scene
  --shift -20
  --rotate-y calc(2 * var(--scene-rotation, 10))

// Theming
.stopwatch__body .cuboid__side
  // Need to override "filter" in some places as it applies overflow hidden
  filter none
  display flex
  flex-direction var(--flow, column)

  &:nth-of-type(odd)
    --flow row

  // Front faces
  &:nth-of-type(even) .stopwatch__frame .cuboid__side:nth-of-type(4)
  &:nth-of-type(odd) .stopwatch__frame .cuboid__side:nth-of-type(3)
    --b 0.55

  // Rear faces for back panel
  &:nth-of-type(even) .stopwatch__frame .cuboid__side:nth-of-type(2)
  &:nth-of-type(odd) .stopwatch__frame .cuboid__side:nth-of-type(1)
    --b 1

  // Internal pieces that aren't seen
  &:nth-of-type(even) .stopwatch__frame .cuboid__side:nth-of-type(1)
  &:nth-of-type(even) .stopwatch__frame .cuboid__side:nth-of-type(3)
  &:nth-of-type(odd) .stopwatch__frame .cuboid__side:nth-of-type(2)
  &:nth-of-type(odd) .stopwatch__frame .cuboid__side:nth-of-type(4)
    --b 0.5

// Drill down into the individual outer and inner faces
// Outer Faces
// Top face
.stopwatch__body .cuboid__side:nth-of-type(1) .stopwatch__body-angle:nth-of-type(2) .stopwatch__frame .cuboid__side:nth-of-type(5)
  --b 1.2

// Top left
.stopwatch__body .cuboid__side:nth-of-type(1) .stopwatch__body-angle:nth-of-type(1) .stopwatch__frame .cuboid__side:nth-of-type(5)
.stopwatch__body .cuboid__side:nth-of-type(4) .stopwatch__body-angle:nth-of-type(1) .stopwatch__frame .cuboid__side:nth-of-type(6)
  --b 1.1

// Left
.stopwatch__body .cuboid__side:nth-of-type(4) .stopwatch__body-angle:nth-of-type(2) .stopwatch__frame .cuboid__side:nth-of-type(6)
  --b 1

//Bottom left
.stopwatch__body .cuboid__side:nth-of-type(3) .stopwatch__body-angle:nth-of-type(1) .stopwatch__frame .cuboid__side:nth-of-type(6)
.stopwatch__body .cuboid__side:nth-of-type(4) .stopwatch__body-angle:nth-of-type(3) .stopwatch__frame .cuboid__side:nth-of-type(6)
  --b 0.9

//Bottom
.stopwatch__body .cuboid__side:nth-of-type(3) .stopwatch__body-angle:nth-of-type(2) .stopwatch__frame .cuboid__side:nth-of-type(6)
  --b 0.8

//Bottom right
.stopwatch__body .cuboid__side:nth-of-type(3) .stopwatch__body-angle:nth-of-type(3) .stopwatch__frame .cuboid__side:nth-of-type(6)
.stopwatch__body .cuboid__side:nth-of-type(2) .stopwatch__body-angle:nth-of-type(3) .stopwatch__frame .cuboid__side:nth-of-type(5)
  --b 0.7

//Right
.stopwatch__body .cuboid__side:nth-of-type(2) .stopwatch__body-angle:nth-of-type(2) .stopwatch__frame .cuboid__side:nth-of-type(5)
  --b 0.7

//Top right
.stopwatch__body .cuboid__side:nth-of-type(1) .stopwatch__body-angle:nth-of-type(3) .stopwatch__frame .cuboid__side:nth-of-type(5)
.stopwatch__body .cuboid__side:nth-of-type(2) .stopwatch__body-angle:nth-of-type(1) .stopwatch__frame .cuboid__side:nth-of-type(5)
  --b 1

// Internal Faces
// Top face
.stopwatch__body .cuboid__side:nth-of-type(1) .stopwatch__body-angle:nth-of-type(2) .stopwatch__frame .cuboid__side:nth-of-type(6)
  --b 0.6

// Top left
.stopwatch__body .cuboid__side:nth-of-type(1) .stopwatch__body-angle:nth-of-type(1) .stopwatch__frame .cuboid__side:nth-of-type(6)
.stopwatch__body .cuboid__side:nth-of-type(4) .stopwatch__body-angle:nth-of-type(1) .stopwatch__frame .cuboid__side:nth-of-type(5)
  --b 0.5

// Left
.stopwatch__body .cuboid__side:nth-of-type(4) .stopwatch__body-angle:nth-of-type(2) .stopwatch__frame .cuboid__side:nth-of-type(5)
  --b 0.4

//Bottom left
.stopwatch__body .cuboid__side:nth-of-type(3) .stopwatch__body-angle:nth-of-type(1) .stopwatch__frame .cuboid__side:nth-of-type(5)
.stopwatch__body .cuboid__side:nth-of-type(4) .stopwatch__body-angle:nth-of-type(3) .stopwatch__frame .cuboid__side:nth-of-type(5)
  --b 0.5

//Bottom
.stopwatch__body .cuboid__side:nth-of-type(3) .stopwatch__body-angle:nth-of-type(2) .stopwatch__frame .cuboid__side:nth-of-type(5)
  --b 0.8

//Bottom right
.stopwatch__body .cuboid__side:nth-of-type(3) .stopwatch__body-angle:nth-of-type(3) .stopwatch__frame .cuboid__side:nth-of-type(5)
.stopwatch__body .cuboid__side:nth-of-type(2) .stopwatch__body-angle:nth-of-type(3) .stopwatch__frame .cuboid__side:nth-of-type(6)
  --b 0.9

//Right
.stopwatch__body .cuboid__side:nth-of-type(2) .stopwatch__body-angle:nth-of-type(2) .stopwatch__frame .cuboid__side:nth-of-type(6)
  --b 1

//Top right
.stopwatch__body .cuboid__side:nth-of-type(1) .stopwatch__body-angle:nth-of-type(3) .stopwatch__frame .cuboid__side:nth-of-type(6)
.stopwatch__body .cuboid__side:nth-of-type(2) .stopwatch__body-angle:nth-of-type(1) .stopwatch__frame .cuboid__side:nth-of-type(6)
  --b 0.8





.stopwatch__body > .cuboid__side
  pointer-events none

button
  appearance none
  border 0
  background none

label
label > *
button
button > *
  cursor pointer
  pointer-events all

.stopwatch__body-angle
  flex 1
  position relative

  &:nth-of-type(1)
  &:nth-of-type(3)
    flex 0.5


.stopwatch__body-angle
  transform-origin var(--transform-origin, 50% 50%)
  transform var(--rotate, rotate(0deg)) translate3d(0, 0, calc((var(--stopwatch-frame-depth) * var(--coefficient, -0.5)) * 1vmin))

.stopwatch__body .cuboid__side

  &:nth-of-type(1) .stopwatch__body-angle
    &:nth-of-type(1)
      --transform-origin 100% 50%
      --rotate rotateY(-45deg)

    &:nth-of-type(3)
      --transform-origin 0% 50%
      --rotate rotateY(45deg)

  &:nth-of-type(2) .stopwatch__body-angle
    &:nth-of-type(1)
      --transform-origin 50% 100%
      --rotate rotateX(45deg)

    &:nth-of-type(3)
      --transform-origin 50% 0%
      --rotate rotateX(-45deg)

  &:nth-of-type(3) .stopwatch__body-angle
    &:nth-of-type(1)
      --transform-origin 100% 50%
      --rotate rotateY(45deg)
      --coefficient 0.5

    &:nth-of-type(2)
      --coefficient 0.5

    &:nth-of-type(3)
      --transform-origin 0% 50%
      --coefficient 0.5
      --rotate rotateY(-45deg)

  &:nth-of-type(4) .stopwatch__body-angle
    &:nth-of-type(1)
      --transform-origin 50% 100%
      --rotate rotateX(-45deg)
      --coefficient 0.5

    &:nth-of-type(2)
      --coefficient 0.5

    &:nth-of-type(3)
      --transform-origin 50% 0%
      --rotate rotateX(45deg)
      --coefficient 0.5

.stopwatch__frame
  --depth var(--stopwatch-frame-depth)

  .cuboid__side
    background var(--stopwatch-frame)
    filter brightness(var(--b))

.stopwatch__control
  position absolute
  height 100%
  width calc(var(--width, 140) * 1%)
  top 50%
  left 50%
  transform translate3d(calc(var(--offset-x, -32) * 1%), -50%, calc(var(--stopwatch-frame-depth) * 0.5vmin))

.stopwatch__reset
  --offset-x -64

.stopwatch__pause
  display none

.cuboid__side > [type='reset']
  height 100%
  width 100%
  position absolute


.stopwatch__pause
.stopwatch__start
  --control-bg var(--start)
.stopwatch__reset
  --control-bg var(--reset)

.button
  --depth calc(var(--stopwatch-frame-depth) * 1)
  transform translate3d(-50%, -50%, var(--elevation))
  height 75%
  width 65%
  top 50%
  left 50%
  transition transform 0.1s

  .cuboid__side
    background var(--control-bg, red)
    filter brightness(var(--b))

  &__placeholder
    width 100%
    height 100%

  &__container
    --depth calc(var(--stopwatch-frame-depth) * 1.4)
    --elevation calc(var(--stopwatch-frame-depth) * -0.2vmin)

    transform translate3d(0, 0, calc(var(--depth) * 0.5vmin))

    &:hover
      --elevation calc(var(--stopwatch-frame-depth) * -0.35vmin)

    &:active
      --elevation calc(var(--stopwatch-frame-depth) * -0.85vmin)

    .cuboid__side
      filter brightness(var(--b))

// Stopwatch functionality
.digit
  position relative
  color transparent
  counter-reset var(--counter-name) var(--counter-variable)
  animation var(--name, none) var(--duration, 1s) infinite steps(var(--steps)) var(--state)

  &:after
    content counter(var(--counter-name))
    font-variant tabular-nums
    color var(--digit, white)
    position absolute
    bottom 0
    right 0

.ms
  font-size 4vmin
  transform translate(0, -6%)

  &--tens
    --duration 1s
    --steps 10
    --counter-name ms-tens
    --counter-variable var(--ms-tens)

  &--singles
    --duration 0.1s
    --steps 10
    --counter-name ms-singles
    --counter-variable var(--ms-singles)

.s
  &--tens
    --duration 60s
    --steps 6
    --counter-name s-tens
    --counter-variable var(--s-tens)

  &--singles
    --duration 10s
    --steps 10
    --counter-name s-singles
    --counter-variable var(--s-singles)

.m
  &--tens
    --duration 3600s
    --steps 6
    --counter-name m-tens
    --counter-variable var(--m-tens)

  &--singles
    --duration 600s
    --steps 10
    --counter-name m-singles
    --counter-variable var(--m-singles)

// The different animations requires for each digit
@keyframes ms-tens
  to
    --ms-tens 10

@keyframes ms-singles
  to
    --ms-singles 10

@keyframes s-tens
  to
    --s-tens 6

@keyframes s-singles
  to
    --s-singles 10

@keyframes m-tens
  to
    --m-tens 6

@keyframes m-singles
  to
    --m-singles 10
View Compiled

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.