mixin flaps()
  .package__flap.package__flap--top
  .package__flap.package__flap--bottom
      
mixin side()
  .package__side(class=`package__side--${attributes.class || 'side'}`)
    +flaps()
    if block
      block

.scene
  .package__wrapper
    .package
      +side()(class="main")
        +side()(class="tabbed")
        +side()(class="extra")
          +side()(class="flipped")
View Compiled
:root
  --bg hsl(180, 20%, 92%) 
  --face-1 hsl(28, 41%, 57%)
  --face-2 hsl(29, 58%, 66%)
  --face-3 hsl(30, 69%, 70%)
  --face-4 hsl(31, 82%, 74%)
  --face-5 hsl(30, 72%, 70%)
  --face-6 hsl(21, 75%, 28%)
  --flap-one hsl(32, 76%, 70%)
  --flap-two hsl(32, 76%, 74%)
  --flap-three hsl(32, 72%, 72%)
  --flap-four hsl(32, 78%, 76%)
  --flap-five hsl(32, 78%, 72%)

*
*:after
*:before
  box-sizing border-box
  transform-style preserve-3d
  
body
  background var(--bg)
  min-height 100vh
  display grid
  place-items center
  perspective 100vmin
  overflow hidden
  
.scene
  transform rotateX(calc(var(--rotate-x, -24) * 1deg)) rotateY(calc(var(--rotate-y, -32) * 1deg)) rotateX(90deg)
    
.package
  height calc(var(--height, 20) * 1vmin)
  width calc(var(--width, 20) * 1vmin)
  transform-origin 50% 0 

  &__flap
    width 99.5%
    height 49.5%
    background var(--flap-bg, var(--face-4))
    position absolute
    left 50%
    transform translate(-50%, 0)

    &--top
      transform-origin 50% 100%
      bottom 100%

    &--bottom
      top 100%
      transform-origin 50% 0%


  &__side
    height calc(var(--height, 20) * 1vmin)
    position absolute
    top 0

    &--extra
    &--tabbed
      & > .package__flap--bottom
        top 99%
      & > .package__flap--top
        bottom 99%

    &--main
      background var(--face-5)
      left 50%
      top 50%
      transform translate(-50%, -50%) translate3d(0, 0, 0)
      width calc(var(--width, 20) * 1vmin)


      & > .package__flap
        height calc(var(--depth, 20) * 0.495vmin)

    &--tabbed
      left 100%
      background var(--face-2)
      width calc(var(--depth, 20) * 1vmin)
      transform-origin 0% 50%
      transform rotateY(calc(var(--packaged, 0) * -90deg))

      & > .package__flap
        height calc(var(--width, 20) * 0.495vmin)
        --flap-bg var(--face-3)

      &:after
        content ''
        position absolute
        left 99.5%
        height 100%
        width 10%
        background var(--face-3)
        $clip = polygon(0 0%, 100% 20%, 100% 80%, 0 100%)
        clip-path $clip
        -webkit-clip-path $clip
        transform-origin 0% 50%
        transform rotateY(calc(var(--packaged, 0) * -90deg))

    &--extra
      right 100%
      background var(--face-2)
      width calc(var(--depth, 20) * 1vmin)
      transform-origin 100% 50%
      transform rotateY(calc(var(--packaged, 0) * 90deg))

      & > .package__flap
        height calc(var(--width, 20) * 0.495vmin)
        --flap-bg var(--face-3)

    &--flipped
      background var(--face-3)
      right 100%
      width calc(var(--width, 20) * 1vmin)
      transform-origin 100% 50%

      & > .package__flap
        height calc(var(--depth, 20) * 0.495vmin)
        --flap-bg var(--face-4) 
          
    &--extra > .package__flap.package__flap--top
      --flap-bg var(--flap-one)
    &--extra > .package__flap.package__flap--bottom
      --flap-bg var(--flap-two)
    &--tabbed > .package__flap.package__flap--bottom
      --flap-bg var(--flap-three)
    &--flipped > .package__flap.package__flap--bottom
      --flap-bg var(--flap-four)
    &--main > .package__flap.package__flap--top
      --flap-bg var(--flap-five)
View Compiled
import { GUI } from 'https://cdn.skypack.dev/dat.gui'

const CONFIG = {
  'rotate-x': -24,
  'rotate-y': -32,
  'packaged': false,
}

const UPDATE = () => Object.keys(CONFIG).forEach(key => document.documentElement.style.setProperty(`--${key}`, typeof CONFIG[key] === 'boolean' ? CONFIG[key] ? 1 : 0 : CONFIG[key]))

const CTRL = new GUI()

CTRL.add(CONFIG, 'rotate-x', -90, 90, 1).onChange(UPDATE).name('Rotate X')
CTRL.add(CONFIG, 'rotate-y', -90, 90, 1).onChange(UPDATE).name('Rotate Y')
CTRL.add(CONFIG, 'packaged').onChange(UPDATE).name('Package?')

UPDATE()
View Compiled
Run Pen

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.