/// Creates a hinge effect by rotating the element.
/// @param {Keyword} $state [in] - State to transition to.
/// @param {Keyword} $from [left] - Edge of the element to rotate from. Can be `top`, `right`, `bottom`, or `left`.
/// @param {Keyword} $axis [edge] - Axis of the element to rotate on. Can be `edge` or `center`.
/// @param {Number} $perspective [2000px] - Perceived distance between the viewer and the element. A higher number will make the rotation effect more pronounced.
/// @param {Keyword} $turn-origin [from-back] - Side of the element to start the rotation from. Can be `from-back` or `from-front`.
@function hinge (
  $state: in,
  $from: left,
  $axis: edge,
  $perspective: 2000px,
  $turn-origin: from-back
) {
  // Rotation directions when hinging from back vs. front
  $rotation-amount: 90deg;
  $rotations-back: (
    top: rotateX($rotation-amount * -1),
    right: rotateY($rotation-amount * -1),
    bottom: rotateX($rotation-amount),
    left: rotateY($rotation-amount),
  );
  $rotations-from: (
    top: rotateX($rotation-amount),
    right: rotateY($rotation-amount),
    bottom: rotateX($rotation-amount * -1),
    left: rotateY($rotation-amount * -1),
  );

  // Rotation origin
  $rotation: '';
  @if $turn-origin == from-front {
    $rotation: map-get($rotations-from, $from);
  } @else if $turn-origin == from-back {
    $rotation: map-get($rotations-back, $from);
  } @else {
    @warn '$turn-origin must be either "from-back" or "from-front"';
  }

  // Start and end state
  $start: '';
  $end: '';
  @if $state == in {
    $start: perspective($perspective) $rotation;
    $end: perspective($perspective) rotate(0deg);
  } @else {
    $start: perspective($perspective) rotate(0deg);
    $end: perspective($perspective) $rotation;
  }

  // Turn axis
  $origin: '';
  @if $axis == edge {
    $origin: $from;
  } @else {
    $origin: center;
  }

  $keyframes: (
    name: 'hinge-#{$state}-#{$from}-#{$axis}-#{$turn-origin}',
    0: (transform: $start, transform-origin: $origin),
    100: (transform: $end),
  );

  @return $keyframes;
}
