Pen Settings

HTML

CSS

CSS Base

Vendor Prefixing

Add External Stylesheets/Pens

Any URL's added here will be added as <link>s in order, and before the CSS in the editor. If you link to another Pen, it will include the CSS from that Pen. If the preprocessor matches, it will attempt to combine them before processing.

+ add another resource

JavaScript

Babel is required to process package imports. If you need a different preprocessor remove all packages first.

Add External Scripts/Pens

Any URL's added here will be added as <script>s in order, and run before the JavaScript in the editor. You can use the URL of any other Pen and it will include the JavaScript from that Pen.

+ add another resource

Behavior

Save Automatically?

If active, Pens will autosave every 30 seconds after being saved once.

Auto-Updating Preview

If enabled, the preview panel updates automatically as you code. If disabled, use the "Run" button to update.

Format on Save

If enabled, your code will be formatted when you actively save your Pen. Note: your code becomes un-folded during formatting.

Editor Settings

Code Indentation

Want to change your Syntax Highlighting theme, Fonts and more?

Visit your global Editor Settings.

HTML

              
                <div id="app"></div>
              
            
!

CSS

              
                *, *:before, *:after {
  box-sizing: border-box;
}

img {
  max-width: 100%;
  vertical-align: top;
}
@function rem-calc($pixelValue, $baseValue: 16) {
  @return ($pixelValue / $baseValue) * 1rem;
}
$breakpoints: (
	'xs'  : ( min-width: 40em ), // 640px
  'sm'  : ( min-width: 48em ), // 768px
  'md'  : ( min-width: 64em ), // 1024px
  'lg'  : ( min-width: 90em )	 // 1440px
);

@mixin border ($style,  $sides...){
  @if ($style != "") {
    @if ($sides == "") {
      border: $style;
    } @else {
      @each $side in $sides {
       @if ($side == 'top' or
            $side == 'right' or
            $side == 'bottom' or
            $side == 'left') {
            border-#{$side}: $style;
        }
      }
    }
  }
}

@mixin respond-to($name) {
  // If the key exists in the map
  @if map-has-key($breakpoints, $name) {
    // Prints a media query based on the value
    @media #{inspect(map-get($breakpoints, $name))} { @content; }
  }
  // If the key doesnt exist in the map
  @else {
    @warn "Unfortunately, no value could be retrieved from `#{$breakpoint}`. " + "Please make sure it is defined in `$breakpoints` map.";
  }
}
$colors: (
	blue-primary: #44c8f9,
	blue-secondary: #01aae9,
	blue-tertiary: #048fc3,
	orange-primary: #febc75,
	orange-secondary: #f59834,
	orange-tertiary: #e3831c,
	white: #f9fafc,
	light-gray-primary: #eaf0f2,
	light-gray-secondary: #e8ebf1,
	dark-gray-primary: #6a7078,
	dark-gray-secondary: #474e58,
	black: #474e58,
	mint-primary: #e8f4e7,
	mint-secondary: #d3e7d2,
	mint-tertiary: #b3cab2,
	red-primary: #f76b58,
	red-secondary: #f04730,
	red-tertiary: #d42912,
	dark-blue-primary: #303c40
);
@function color($key) {
	@if map-has-key($colors, $key) {
		@return map-get($colors, $key)
	}

	@warn "Unknown `#{key}` in $colors.";
	@return null;
}
.run-it-once {
  background-color: #020203;
}

$rio-primary: #020203;
$rio-secondary: #101012;
$rio-borders: #898c8c;
$rio-red: #B54A49;
$rio-xs: 760px;

.hero--rio {
	position: relative;
	color: color(white);
	min-height: rem-calc(520);
	text-align: center;
	@media screen and (min-width: 768px) {
		height: 75vh;
	}
	@media screen and (min-width: 1024px) {
		height: 90vh;
	}
	.button.buy-button {
		position: absolute;
		top: -150px;
		left: 50%;
    background: #A47C3F;
    color: #fff;
    border: none;
    padding: rem-calc(10) 0;
    min-width: rem-calc(195);
	 	transform: translate3d(-50%, 30px, 0);
		opacity: 0;
		transition: 600ms ease;
		z-index: 0;
		@media screen and (min-height: 580px) and (min-width: 768px) {
			top: -130px;
		}
		@media screen and (min-height: 640px) and (min-width: 768px) {
			top: -170px;
		}
		@media screen and (min-height: 768px) and (min-width: 1024px) {
			top: -220px;
		}
		@media screen and (min-height: 1000px) and (min-width: 1024px) {
			top: -230px;
		}
		@media screen and (min-height: 1200px) and (min-width: 1024px) {
			top: -270px;
		}
		&.active {
			opacity: 1;
			transform: translate3d(-50%, 0, 0);
		}
		&:hover {
			color: $rio-primary;
		}
	}
}
.rio-logo {
	position: absolute;
	margin-left: auto;
	margin-right: auto;
	top: 0;
	left: 50%;
	width: 100%;
	transform: translate3d(-50%, -100px, 0);
	transition: opacity 4000ms cubic-bezier(0.230, 1.000, 0.320, 1.000);
	transition-delay: 800ms;
	opacity: 0;
	&__inner {
		position: relative;
		height: 0;
		padding-bottom: percentage(82.7 / 560);
		img {
			position: absolute;
			top: 0;
			left: 0;
			width: 100%;
			height: 100%;
		}
	}
	@media screen and (min-height: 580px) and (min-width: 768px) {
		transform: translate3d(-50%, -120px, 0);
	}
	@media screen and (min-height: 900px) and (min-width: 768px) {
		transform: translate3d(-50%, -150px, 0);
	}
	@media screen and (min-height: 1100px) and (min-width: 768px) {
		transform: translate3d(-50%, -180px, 0);
	}
	@media screen and (min-height: 768px) and (min-width: 1024px) {
		transform: translate3d(-50%, -150px, 0);
	}
	@media screen and (min-height: 1000px) and (min-width: 1024px) {
		transform: translate3d(-50%, -180px, 0);
	}
	@media screen and (min-height: 1200px) and (min-width: 1024px) {
		transform: translate3d(-50%, -220px, 0);
	}
	@media screen and (min-height: 850px) and (min-width: 1440px) {
		transform: translate3d(-50%, -200px, 0);
	}
	@media screen and (min-height: 1100px) and (min-width: 1440px) {
		transform: translate3d(-50%, -240px, 0);
	}
}

.cardbox-container {
	position: absolute;
	bottom: -(rem-calc(100));
	left: 50%;
	width: 100%;
	max-width: rem-calc(252);
	transform: translate3d(-50%, 0, 0);
	&--intro {
		.cardbox {
			opacity: 0;
			transform: translate3d(0, 80px, 0);
			transition: transform 2000ms cubic-bezier(0.230, 1.000, 0.320, 1.000), opacity 2000ms cubic-bezier(0.230, 1.000, 0.320, 1.000);
		}
		&.loaded, {
			.cardbox {
				opacity: 1;
				transform: translate3d(0, 0, 0);
			}
			.rio-logo {
				opacity: 1;
			}
		}
	}
	@media screen and (min-height: 580px) and (min-width: 768px) {
		max-width: rem-calc(350);
		bottom: -(rem-calc(240));
	}
	@media screen and (min-height: 900px) and (min-width: 768px) {
		max-width: rem-calc(380);
		bottom: -(rem-calc(170));
	}
	@media screen and (min-height: 1100px) and (min-width: 768px) {
		max-width: rem-calc(410);
		bottom: -(rem-calc(130));
	}
	@media screen and (min-height: 768px) and (min-width: 1024px) {
		max-width: rem-calc(400);
	}
	@media screen and (min-height: 1000px) and (min-width: 1024px) {
		max-width: rem-calc(484);
		bottom: -(rem-calc(160));
	}
	@media screen and (min-height: 850px) and (min-width: 1440px) {
		max-width: rem-calc(484);
		bottom: -(rem-calc(290));
	}
	@media screen and (min-height: 1100px) and (min-width: 1440px) {
		bottom: -(rem-calc(160));
	}
}
.cardbox {
	&__item, &-ending__item {
		position: absolute;
		bottom: 0;
		left: 50%;
		transform: translate3d(-50%, 0, 0);
		will-change: transform;
		&--front {
			position: relative;
			z-index: 5;
		}
		&--lid, &--lidback {
			bottom: initial;
			top: 0;
			width: calc(100% - 12px);
			z-index: 2;
		}
		&--lidback {
			opacity: .7;
			z-index: 1;
		}
		&--card {
			bottom: initial;
			top: 10%;
			width: calc(100% - 14px);
			z-index: 4;
		}
	}
}

.two-cards {
	position: relative;
	overflow: hidden;
	//@include hero('../images/work/run-it-once/hero/two-cards.jpg');
	background-repeat: no-repeat;
	background-position: center center;
	background-size: cover;
	height: 50vh;
	min-height: rem-calc(510);
	@include respond-to(sm) { height: rem-calc(583); }
	@include respond-to(md) { height: 100vh; }
	&:before {
		content: '';
		position: absolute;
		width: 100%;
		height: 100%;
		top: 0;
		left: 0;
		background: $rio-primary;
		opacity: 1;
		transition: 600ms ease;
	}
	&.loaded:before {
		opacity: 0;
	}
}

.deck {
	overflow: hidden;
	padding: rem-calc(70) rem-calc(22) rem-calc(60);
	@include respond-to(sm) {
		padding: rem-calc(143) 0 0;
		height: rem-calc(1200);
	}
	.deck-container {
		width: 100%;
		max-width: rem-calc(1440);
		margin-left: auto;
		margin-right: auto;
		position: relative;
    &:after {
      content: '';
      display: table;
      clear: both;
    }
		.deck-container__item {

		}
	}

	&-copy {
		color: color(white);
		margin-bottom: rem-calc(25);
		transform: translateY(50px);
		opacity: 0;
		transition: opacity 1500ms cubic-bezier(0.230, 1.000, 0.320, 1.000), transform 1500ms cubic-bezier(0.230, 1.000, 0.320, 1.000);
		will-change: transform, opacity;
		padding-bottom: rem-calc(100);
		@include respond-to(sm) {
			max-width: rem-calc(410);
			margin-right: percentage(123 / 1440);
			float: right;
		}
		@include respond-to(lg) {
			max-width: rem-calc(500);
		}
		h1 {
			text-transform: uppercase;
			margin-bottom: rem-calc(25);
		}
	}

	&-cards {
		position: relative;
		margin: 0 auto 0;
		width: 100%;
		display: block;
		height: rem-calc(494);
		@media screen and (min-width: 330px) {
			max-width: rem-calc(330);
		}
		@include respond-to(sm) {
			position: absolute;
			max-width: rem-calc(1042);
			height: rem-calc(934);
			top: 0;
			right: rem-calc(115);
		}
		@include respond-to(md) {
			right: percentage(135 / 1024);
		}
		&__item {
			position: absolute;
			top: 0;
			left: 50%;
			transform: translate3d(-50%, 0, 0);
			will-change: transform;
			@include respond-to(sm) {
				left: 0;
				transform: none;
			}
			&:nth-of-type(1) {
				z-index: 6;
				max-width: percentage(327.59 / 330);
				@include respond-to(sm) {
					max-width: percentage(502 / 1042);
				}
			}
			&:nth-of-type(2) {
				top: rem-calc(97);
				max-width: percentage(326.94 / 330);
				z-index: 5;
				@include respond-to(sm) {
					max-width: percentage(501 / 1042);
					top: rem-calc(149);
				}
			}
			&:nth-of-type(3) {
				top: rem-calc(185);
				max-width: percentage(326.29 / 330);
				z-index: 4;
				@include respond-to(sm) {
					max-width: percentage(500 / 1042);
					top: rem-calc(283);
				}
			}
			&:nth-of-type(4) {
				top: rem-calc(279);
				max-width: percentage(324.33 / 330);
				z-index: 3;
				@include respond-to(sm) {
					max-width: percentage(497 / 1042);
					top: rem-calc(427);
				}
			}
			&:nth-of-type(5) {
				top: rem-calc(348);
				max-width: percentage(323.68 / 330);
				z-index: 2;
				@include respond-to(sm) {
					max-width: percentage(496 / 1042);
					top: rem-calc(533);
					left: rem-calc(60);
				}
			}
			&:nth-of-type(6) {
				display: none;
				z-index: 1;
				@include respond-to(sm) {
					display: block;
					top: rem-calc(648);
					left: rem-calc(450);
				}
			}
		}
	}
}

.cards {
	position: relative;
	background-color: $rio-secondary;
	overflow: hidden;
	&:before {
		content: '';
		position: absolute;
		top: 0;
		left: 0;
		width: 100%;
		height: 100%;
		z-index: 1;
		/* Permalink - use to edit and share this gradient: http://colorzilla.com/gradient-editor/#252529+0,000000+100&0.65+0,0+100 */
		background: -moz-linear-gradient(top,  rgba(37,37,41,0.65) 0%, rgba(0,0,0,0) 100%); /* FF3.6-15 */
		background: -webkit-linear-gradient(top,  rgba(37,37,41,0.65) 0%,rgba(0,0,0,0) 100%); /* Chrome10-25,Safari5.1-6 */
		background: linear-gradient(to bottom,  rgba(37,37,41,0.65) 0%,rgba(0,0,0,0) 100%); /* W3C, IE10+, FF16+, Chrome26+, Opera12+, Safari7+ */
		filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#a6252529', endColorstr='#00000000',GradientType=0 ); /* IE6-9 */
	}
	&-container {
		position: relative;
		z-index: 2;
		max-width: 100%;
		margin-left: auto;
		margin-right: auto;
		width: 100%;
    &:after {
      content: '';
      display: table;
      clear: both;
    }
		padding: rem-calc(45) rem-calc(20) rem-calc(90);
		@include respond-to(sm) {
			max-width: rem-calc(768);
			padding: rem-calc(184) rem-calc(20);
		}
		@include respond-to(md) {
			max-width: rem-calc(978);
			padding: rem-calc(320) rem-calc(20);
		}
		@include respond-to(lg) { padding: rem-calc(320) rem-calc(20); }
	}
	&-copy {
		max-width: rem-calc(335);
		margin-left: auto;
		margin-right: auto;
		opacity: 0;
		transform: translateY(50px);
		transition: opacity 1500ms cubic-bezier(0.230, 1.000, 0.320, 1.000), transform 1500ms cubic-bezier(0.230, 1.000, 0.320, 1.000);
		will-change: transform, opacity;
		@include respond-to(xs) {
			max-width: 80%
		}
		@include respond-to(sm) {
			max-width: rem-calc(387);
			float: left;
		}

		@include respond-to(md) {
			max-width: rem-calc(512);
		}
	}
	&-cards {
		position: relative;
		padding-top: rem-calc(100);
		max-width: rem-calc(200);
		margin-left: auto;
		margin-right: auto;
		@include respond-to(sm) {
			padding-top: 0;
			position: absolute;
			right: 5%;
			top: 50%;
			transform: translate3d(0, -50%, 0);
			max-width: rem-calc(200);
		}
		@include respond-to(md) {
			max-width: rem-calc(200);
		}
		@include respond-to(lg) {
			right: 0;
		}
		&__item {
			position: relative;
			display: block;
			margin: 0 auto 0;
			will-change: transform;

			&:nth-child(1){ z-index: 3; }
			&:nth-child(2){ z-index: 2; }
			&:nth-child(3){ z-index: 1; }
		}
	}
}

.run-it-once {
	background-color: $rio-primary;
	h1 { color: #efefef; }
	p {
		color: #efefef;
		line-height: 2.25;
		margin-bottom: 2rem;
		&:last-of-type {
			margin-bottom: 0;
		}
	}

	.button {
		display: inline-block;
		text-align: center;
		background: transparent;
		color: #B54A49;
		border: 1px solid #B54A49;
		border-radius: rem-calc(25);
		font-size: rem-calc(18);
		padding: rem-calc(5) rem-calc(20);
		margin-right: rem-calc(12);
		&:last-of-type {
			margin-right: 0;
		}

		&:hover {
			color: #fff;
		}
	}

	.case-study-gallery,
	.case-study-gallery2 {
		font-size: 0;
		.intrinsic__inner-magic {
			transition: 800ms ease;
			&:hover {
				transform: scale(1.15);
				transition: 10s ease;
			}
		}
	}

	.case-study-gallery {
		position: relative;
		&:before, &:after {
			content: '';
			position: absolute;
			width: 100%;
			height: 1px;
			left: 0;
			background-color: $rio-borders;
			z-index: 5;
		}
		&:before {
			top: 0;
		}
		&:after {
			bottom: -1px;
		}
		> div:first-of-type {
			&:before, &:after {
				content: '';
				position: absolute;
				background-color: $rio-borders;
				z-index: 5;
			}
			&:after {
				width: 100%;
				height: 1px;
				bottom: 0;
				left: 0;
			}
			@include respond-to(sm) {
				&:before {
					width: 1px;
					height: 100%;
					top: 0;
					right: 0;
				}
				&:after {
					display: none;
				}
			}
		}
		> div:last-of-type {
			> div:last-of-type {
				&:before {
					content: '';
					position: absolute;
					background-color: $rio-borders;
					z-index: 5;
					width: 100%;
					height: 1px;
					top: 0;
					left: 0;
				}
			}
		}
	}

	.case-study-gallery2 {
		@include border(1px solid $rio-borders, top);
		@include respond-to(md) {
			border: none;
		}
		> div {
			@include border(1px solid $rio-borders, bottom);
			@include respond-to(md) {
				@include border(1px solid $rio-borders, top, right, bottom);
			}
			&:last-of-type {
				@include respond-to(md) {
					border-right-color: transparent;
				}
			}
		}
	}

	.button-wrap {
		text-align: center;
		margin-bottom: rem-calc(25);

		@media screen and (min-width: $rio-xs){
			text-align: left;
		}
	}

	.case-study-gallery,
	.case-study-gallery2 {
		padding: 0;
	}
}

              
            
!

JS

              
                let helpers = {
	transformThreeD: function(e, x, xUnit, y, yUnit, z, zUnit) {
		e.style.webkitTransform = "translate3d(" + x + xUnit + ", " + y + yUnit + ", " + z + zUnit + ")";
		   e.style.MozTransform = "translate3d(" + x + xUnit + ", " + y + yUnit + ", " + z + zUnit + ")";
		     e.style.OTransform = "translate3d(" + x + xUnit + ", " + y + yUnit + ", " + z + zUnit + ")";
		  		e.style.transform = "translate3d(" + x + xUnit + ", " + y + yUnit + ", " + z + zUnit + ")";
	},
  transformRotate: function(e, value) {
    e.style.webkitTransform = 'rotate(' + value + 'deg) translateZ(0)';
    e.style.MozTransform    = 'rotate(' + value + 'deg) translateZ(0)';
    e.style.OTransform      = 'rotate(' + value + 'deg) translateZ(0)';
    e.style.transform       = 'rotate(' + value + 'deg) translateZ(0)';
  },
  position: function(base, range, relativeY, offset) {
    let returnVal = base + helpers.limit(0, 1, relativeY - offset) * range;
    return returnVal;
  },
  limit: function(min, max, value) {
    return Math.max(min, Math.min(max, value));
  },
  prefix(obj, prop, value) {
    let prefs = ['webkit', 'Moz', 'O', 'ms'];
    for (let pref in prefs) {
      if ({}.hasOwnProperty.call(prefs, pref)) {
        obj[prefs[pref] + prop] = value;
      }
    }
  }
};

let { transformThreeD, transformRotate, position, prefix } = helpers;
let { findDOMNode } = ReactDOM;

let logo = "https://s3.amazonaws.com/underbelly/playground/rio/logo.png",
    cardbox = {
      lid     : "https://s3.amazonaws.com/underbelly/playground/rio/lid-lip.png",
      lidBack : "https://s3.amazonaws.com/underbelly/playground/rio/lid-open.png",
      front   : "https://s3.amazonaws.com/underbelly/playground/rio/box-front-01.png",
      card    : "https://s3.amazonaws.com/underbelly/playground/rio/card.png"
    },
    hero = "https://s3.amazonaws.com/underbelly/playground/rio/two-cards.jpg";

const images = {
  'logo': 'https://s3.amazonaws.com/underbelly/website/work/run-it-once/hero/logo.svg',
  'hero': 'https://s3.amazonaws.com/underbelly/website/work/run-it-once/hero/hero.jpg',
  'cardbox': {
    'lid':     'https://s3.amazonaws.com/underbelly/website/work/run-it-once/hero/lid-lip.png',
    'lidBack': 'https://s3.amazonaws.com/underbelly/website/work/run-it-once/hero/lid-open.png',
    'front':   'https://s3.amazonaws.com/underbelly/website/work/run-it-once/hero/box-front-01.png',
    'card':    'https://s3.amazonaws.com/underbelly/website/work/run-it-once/hero/card.png'
  },
  'deck': {
    'one':   'https://s3.amazonaws.com/underbelly/website/work/run-it-once/deck/01.png',
    'two':   'https://s3.amazonaws.com/underbelly/website/work/run-it-once/deck/02.png',
    'three': 'https://s3.amazonaws.com/underbelly/website/work/run-it-once/deck/03.png',
    'four':  'https://s3.amazonaws.com/underbelly/website/work/run-it-once/deck/04.png',
    'five':  'https://s3.amazonaws.com/underbelly/website/work/run-it-once/deck/05.png',
    'six':   'https://s3.amazonaws.com/underbelly/website/work/run-it-once/deck/06.png'
  },
  'gallery': {
    'one':   'https://s3.amazonaws.com/underbelly/website/work/run-it-once/gallery/01-no-border.jpg',
    'two':   'https://s3.amazonaws.com/underbelly/website/work/run-it-once/gallery/02-no-border.jpg',
    'three': 'https://s3.amazonaws.com/underbelly/website/work/run-it-once/gallery/03-no-border.jpg'
  },
  'cards': {
    'one':   'https://s3.amazonaws.com/underbelly/website/work/run-it-once/cards/1.png',
    'two':   'https://s3.amazonaws.com/underbelly/website/work/run-it-once/cards/2.png',
    'three': 'https://s3.amazonaws.com/underbelly/website/work/run-it-once/cards/3.png'
  },
  'gallery2': {
    'one':   'https://s3.amazonaws.com/underbelly/website/work/run-it-once/gallery2/01-no-border.jpg',
    'two':   'https://s3.amazonaws.com/underbelly/website/work/run-it-once/gallery2/02-no-border.jpg',
    'three': 'https://s3.amazonaws.com/underbelly/website/work/run-it-once/gallery2/03-no-border.jpg'
  },
  'lifestyle': 'https://s3.amazonaws.com/underbelly/website/work/fluid/lifestyle/01.jpg',
  'seeMore': {
    'one':   'https://s3.amazonaws.com/underbelly/website/work/see-more/hive.jpg',
    'two':   'https://s3.amazonaws.com/underbelly/website/work/see-more/just-family.jpg',
    'three': 'https://s3.amazonaws.com/underbelly/website/work/see-more/nsac.jpg',
    'four':  'https://s3.amazonaws.com/underbelly/website/work/see-more/rent-tree.jpg'
  }
};
class RioHero extends React.Component {
  constructor(props) {
    super(props);

    this.onScroll = this.onScroll.bind(this);
    this.onResize = this.onResize.bind(this);
    this.update   = this.update.bind(this);
    this.onLoad   = this.onLoad.bind(this);
    this.requestTick = this.requestTick.bind(this);

    this.state = { 'loaded': false };
  }
  copmonentDidUpdate() {
    this.height = this.element.clientHeight;
  }
  componentDidMount() {
    this.lastKnownScroll = 0;
    this.ticking         = false;
    this.dimensions      = this.element.getBoundingClientRect();
    this.cardboxNodes    = document.querySelectorAll('.cardbox__item');
    this.cardboxArray    = [].slice.call(this.cardboxNodes);
    this.viewportHeight  = window.innerHeight || document.documentElement.clientHeight;

    window.addEventListener('scroll', this.onScroll, false);
    window.addEventListener('resize', this.onResize, false);
  }
  componentWillUnmount() {
    window.removeEventListener('scroll', this.onScroll, false);
    window.removeEventListener('resize', this.onResize, false);
  }
  onScroll() {
    if (this.props.parallax) {
      this.requestTick();
    }
  }
  onResize() {
    this.lastKnownScroll = window.pageYOffset;
    this.dimensions      = this.element.getBoundingClientRect();
    this.viewportHeight  = window.innerHeight || document.documentElement.clientHeight;
    this.requestTick();
  }
  requestTick() {
    if (!this.ticking) {
      this.ticking = true;
      window.requestAnimationFrame(this.update);
      this.dimensions      = this.element.getBoundingClientRect();
      this.lastKnownScroll = window.pageYOffset;
    }
  }
  onLoad() {
    this.setState({ 'loaded': true });
  }
  update() {
    let scroll        = this.lastKnownScroll;
    let cardboxBottom = this.dimensions.bottom;
    let context       = (scroll - this.viewportHeight) * -1;
    let relativeY     = scroll / this.dimensions.height;
    let movement1     = this.dimensions.height * 0.11;
    let movement2     = this.dimensions.height * -0.11;
    let movement3     = this.dimensions.height * -0.05;
    let movement4     = this.dimensions.height * 0.01;
    let movement5     = this.dimensions.height * 0.165;

    if (context >= 0 && cardboxBottom >= 0) {
      transformThreeD(this.cardboxArray[0], -50, '%', position(0, movement1, relativeY,        0), 'px', 0, 'px');
      transformThreeD(this.cardboxArray[1], -50, '%', position(0, movement1, relativeY,        0), 'px', 0, 'px');
      transformThreeD(this.cardboxArray[2], -50, '%', position(0, movement2, relativeY * 2,    0), 'px', 0, 'px');
      transformThreeD(this.cardboxArray[3], -50, '%', position(0, movement3, relativeY * 2,    0), 'px', 0, 'px');
      transformThreeD(this.cardboxArray[4], -50, '%', position(0, movement4, relativeY * 2,    0), 'px', 0, 'px');
      transformThreeD(this.cardboxArray[5], -50, '%', position(0, movement5, relativeY * 1.35, 0), 'px', 0, 'px');
    }
    this.ticking = false;
  }
  render() {
    let { logo, cardbox } = this.props;
    let loaded = this.state.loaded ? "loaded" : "";
    return (
      <div ref={(ref) => this.element = ref} className="parallax-container hero--rio">
        <div id="cardBox" className={`cardbox-container cardbox-container--intro ${loaded}`}>
          <div className="rio-logo">
            <div className="rio-logo__inner">
              <img src={logo} />
            </div>
          </div>
          <div className="cardbox">
            <img src={cardbox.lid}     className="cardbox__item cardbox__item--lid" />
            <img src={cardbox.lidBack} className="cardbox__item cardbox__item--lidback" />
            <img src={cardbox.card}    className="cardbox__item cardbox__item--card" />
            <img src={cardbox.card}    className="cardbox__item cardbox__item--card" />
            <img src={cardbox.card}    className="cardbox__item cardbox__item--card" />
            <img onLoad={this.onLoad} src={cardbox.front}   className="cardbox__item cardbox__item--front" />
          </div>
        </div>
      </div>
    );
  }
}

class TwoCards extends React.Component {
  constructor(props) {
    super(props);

    this.onLoad = this.onLoad.bind(this);

    this.state = { loaded: false }
  }
  componentDidMount() {
    let img = document.createElement('img');
    img.src = this.props.hero;
    img.onload = this.onLoad;
    this.src = img.src;
  }
  onLoad() {
    this.setState({ loaded: true });
  }
  render() {
    let { hero } = this.props;
    let loaded = this.state.loaded ? "loaded" : "";
    let style = {
      backgroundImage: `url(${this.src})`
    }
    return (
      <section style={style} className={`two-cards ${loaded}`}></section>
    )
  }
}

class Deck extends React.Component {
  constructor(props) {
    super(props);

    this.onScroll    = this.onScroll.bind(this);
    this.onResize    = this.onResize.bind(this);
    this.update      = this.update.bind(this);
    this.requestTick = this.requestTick.bind(this);
  }
  componentDidMount() {
    this.ticking        = false;
    this.element        = findDOMNode(this.refs.deck);
    this.fade           = findDOMNode(this.refs.fade);
    this.fadeDimensions = this.fade.getBoundingClientRect();
    this.dimensions     = this.element.getBoundingClientRect();
    this.deckNodes      = document.querySelectorAll('.deck-cards__item');
    this.deckArray      = [].slice.call(this.deckNodes);
    this.viewportHeight = window.innerHeight || document.documentElement.clientHeight;
    this.windowWidth    = window.innerWidth || document.documentElement.clientWidth;

    window.addEventListener('scroll', this.onScroll, false);
    window.addEventListener('resize', this.onResize, false);
  }
  componentWillUnmount() {
    window.removeEventListener('scroll', this.onScroll, false);
    window.removeEventListener('resize', this.onResize, false);
  }
  onScroll() {
    if (this.props.parallax) {
      this.requestTick();
    }
  }
  onResize() {
    this.dimensions     = this.element.getBoundingClientRect();
    this.fadeDimensions = this.fade.getBoundingClientRect();
    this.viewportHeight = window.innerHeight || document.documentElement.clientHeight;
    this.windowWidth    = window.innerWidth || document.documentElement.clientWidth;
    this.requestTick();
  }
  requestTick() {
    if (!this.ticking) {
      this.ticking = true;
      window.requestAnimationFrame(this.update);
      this.dimensions     = this.element.getBoundingClientRect();
      this.fadeDimensions = this.fade.getBoundingClientRect();
    }
  }
  update() {
    let { viewportHeight, dimensions, fadeDimensions, windowWidth } = this;
    let relativeYHelper = dimensions.height > viewportHeight ? dimensions.height : viewportHeight;
    let deckTop     = dimensions.top;
    let deckBottom  = dimensions.bottom;
    let context     = (deckTop - viewportHeight) * -1;
    let fadeContext = (fadeDimensions.top - viewportHeight) * -1;
    let relativeY   = context / (relativeYHelper * 2);
    let values      = [];

    windowWidth <= 768 ? values = [[25], [-50, -145]] : values = [[100], [0, -320]];

    if (context >= 0 && deckBottom >= 0) {
      transformThreeD(this.deckArray[0], values[1][0], '%', position(values[0][0], values[1][1], relativeY,        0), 'px', 0, 'px');
      transformThreeD(this.deckArray[1], values[1][0], '%', position(values[0][0], values[1][1], relativeY * 0.8,  0), 'px', 0, 'px');
      transformThreeD(this.deckArray[2], values[1][0], '%', position(values[0][0], values[1][1], relativeY * 0.6,  0), 'px', 0, 'px');
      transformThreeD(this.deckArray[3], values[1][0], '%', position(values[0][0], values[1][1], relativeY * 0.4,  0), 'px', 0, 'px');
      transformThreeD(this.deckArray[4], values[1][0], '%', position(values[0][0], values[1][1], relativeY * 0.2,  0), 'px', 0, 'px');
      transformThreeD(this.deckArray[5], values[1][0], '%', position(values[0][0], values[1][1], relativeY * 0.1,  0), 'px', 0, 'px');
    }

    if (fadeContext >= this.viewportHeight * 0.1) {
      this.fade.style.opacity = 1;
      this.fade.style.webkitTransform = 'translateY(0)';
      this.fade.style.MozTransform = 'translateY(0)';
      this.fade.style.transform = 'translateY(0)';
    } else {
      this.fade.style.opacity = 0;
      this.fade.style.webkitTransform = 'translateY(50px)';
      this.fade.style.MozTransform = 'translateY(50px)';
      this.fade.style.transform = 'translateY(50px)';
    }

    this.ticking = false;
  }
  render() {
    let { deck } = this.props;
    return (
      <div className="parallax-container deck" ref="deck">
        <div className="deck-container">
          <div ref="fade" className="deck-container__item deck-copy">
            <h1>Backstory</h1>
            <p>Run It Once, created by legendary poker player Phil Galfond, is a place for poker enthusiasts to gather and contribute professional-level strategy with others in the poker community. Besides the wealth of knowledge available at Run It Once, RIO’s brand is one classy act. With a clean, professional, and luxurious logo its no wonder their site is one of the best looking (and functioning) poker communities out there.</p>
            <p>At Underbelly, we’re suckers for playing card designs. That’s one of the many reasons we were stoked to partner with Phil and the Run It Once crew on designing the first official Run It Once card deck.</p>
          </div>
          <div className="deck-container__item deck-cards">
            <img src={deck.one}   className="deck-cards__item" />
            <img src={deck.two}   className="deck-cards__item" />
            <img src={deck.three} className="deck-cards__item" />
            <img src={deck.four}  className="deck-cards__item" />
            <img src={deck.five}  className="deck-cards__item" />
            <img src={deck.six}   className="deck-cards__item" />
          </div>
        </div>
      </div>
    );
  }
}

class Cards extends React.Component {
  constructor(props) {
    super(props);

    this.onScroll    = this.onScroll.bind(this);
    this.onResize    = this.onResize.bind(this);
    this.update      = this.update.bind(this);
    this.requestTick = this.requestTick.bind(this);
  }
  componentDidMount() {
    this.ticking        = false;
    this.element        = findDOMNode(this.refs.cards);
    this.dimensions     = this.element.getBoundingClientRect();
    this.cardsNodes     = document.querySelectorAll('.cards-cards__item');
    this.cardsArray     = [].slice.call(this.cardsNodes);
    this.fade           = findDOMNode(this.refs.fade);
    this.fadeDimensions = this.fade.getBoundingClientRect();
    this.viewportHeight = window.innerHeight || document.documentElement.clientHeight;
    this.windowWidth    = window.innerWidth || document.documentElement.clientWidth;

    window.addEventListener('scroll', this.onScroll, false);
    window.addEventListener('resize', this.onResize, false);
  }
  componentWillUnmount() {
    window.removeEventListener('scroll', this.onScroll, false);
    window.removeEventListener('resize', this.onResize, false);
  }
  onScroll() {
    if (this.props.parallax) {
      this.requestTick();
    }
  }
  onResize() {
    this.dimensions     = this.element.getBoundingClientRect();
    this.fadeDimensions = this.fade.getBoundingClientRect();
    this.viewportHeight = window.innerHeight || document.documentElement.clientHeight;
    this.windowWidth    = window.innerWidth || document.documentElement.clientWidth;
    if (this.props.parallax) {
      this.requestTick();
    }
  }
  requestTick() {
    if (!this.ticking) {
      this.ticking = true;
      window.requestAnimationFrame(this.update);
      this.dimensions     = this.element.getBoundingClientRect();
      this.fadeDimensions = this.fade.getBoundingClientRect();
    }
  }
  update() {
    let relativeYHelper = this.dimensions.height > this.viewportHeight ? this.dimensions.height : this.viewportHeight;
    let cardsTop    = this.dimensions.top;
    let cardsBottom = this.dimensions.bottom;
    let context     = (cardsTop - this.viewportHeight) * -1;
    let relativeY   = context / (relativeYHelper * 2);
    let fadeContext = (this.fadeDimensions.top - this.viewportHeight) * -1;

    if (context >= 0 && cardsBottom >= 0) {
      transformRotate(this.cardsArray[0], position(15,  -15, relativeY, 0));
      transformRotate(this.cardsArray[1], position(-15,  15, relativeY, 0));
      transformRotate(this.cardsArray[2], position(15,  -15, relativeY, 0));
    }

    if (fadeContext >= this.viewportHeight * 0.1) {
      this.fade.style.opacity = 1;
      this.fade.style.webkitTransform = 'translateY(0)';
      this.fade.style.MozTransform = 'translateY(0)';
      this.fade.style.transform = 'translateY(0)';
    } else {
      this.fade.style.opacity = 0;
      this.fade.style.webkitTransform = 'translateY(50px)';
      this.fade.style.MozTransform = 'translateY(50px)';
      this.fade.style.transform = 'translateY(50px)';
    }

    this.ticking = false;
  }
  render() {
    let { cards } = this.props;
    return (
      <div className="parallax-container cards" ref="cards">
        <div className="cards-container">
          <div ref="fade" className="cards-container__item cards-copy">
            <p>Matching the palatial look and feel of Run It Once’s brand was no small feat. We took multiple approaches before finally landing on a style that was sleek, geometric, and modern. Each suit was designed with a unique personality to give the deck depth and variety while still remaining true to RIO’s brand. Diamonds crafted to be rugged and adventurous, spades strong and ruthless, clubs secretive and seductive, and hearts trustworthy and approachable.</p>
            <p>The finished product is a world-class, unique deck of cards worthy of the most talented professional poker hands. However, no need to worry; you don’t have to have a bracelet under your belt to enjoy these cards. Anyone can purchase these beauties directly from RIO’s site- even if you’re one of those casual, low-stakes, hold-em folks. If you’re anything like us, you can’t pass up a hot deck of cards.</p>
          </div>
          <div className="card-container__item cards-cards">
            <img src={cards.one}   className="cards-cards__item" />
            <img src={cards.two}   className="cards-cards__item" />
            <img src={cards.three} className="cards-cards__item" />
          </div>
        </div>
      </div>
    );
  }
}

class RunItOnce extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      'parallax0': false,
      'parallax1': false,
      'parallax2': false,
      'parallax3': false
    };

    this.scrollManager = this.scrollManager.bind(this);
    this.requestTick = this.requestTick.bind(this);
    this.update = this.update.bind(this);
  }
  componentDidMount() {
    this.ticking = false;
    this.parallaxNodeList = document.querySelectorAll('.parallax-container');
    this.parallaxArray = [].slice.call(this.parallaxNodeList);
    this.dimensions0 = this.parallaxArray[0].getBoundingClientRect();
    this.dimensions1 = this.parallaxArray[1].getBoundingClientRect();
    this.dimensions2 = this.parallaxArray[2].getBoundingClientRect();
    this.viewportHeight  = window.innerHeight || document.documentElement.clientHeight;

    window.addEventListener('scroll', this.scrollManager);
    window.addEventListener('resize', this.scrollManager);
  }
  comonentWillUnmount() {
    window.removeEventListener('scroll', this.scrollManager);
    window.removeEventListener('resize', this.scrollManager);
  }
  scrollManager() {
    this.requestTick();
  }
  requestTick() {
    if (!this.ticking) {
      this.ticking = true;
      window.requestAnimationFrame(this.update);
      this.dimensions0 = this.parallaxArray[0].getBoundingClientRect();
      this.dimensions1 = this.parallaxArray[1].getBoundingClientRect();
      this.dimensions2 = this.parallaxArray[2].getBoundingClientRect();
      this.viewportHeight  = window.innerHeight || document.documentElement.clientHeight;
    }
  }
  update() {
    this.context0 = (this.dimensions0.top - this.viewportHeight) * -1;
    this.context1 = (this.dimensions1.top - this.viewportHeight) * -1;
    this.context2 = (this.dimensions2.top - this.viewportHeight) * -1;

    if (this.context0 >= 0 && this.dimensions0.bottom >= 0 && !this.state.parallax0) {
      this.setState({ 'parallax0': true });
    } else if (this.state.parallax0 && (this.dimensions0.bottom <= 0 || this.context0 <= 0)) {
      this.setState({ 'parallax0': false });
    }

    if (this.context1 >= 0 && this.dimensions1.bottom >= 0 && !this.state.parallax1) {
      this.setState({ 'parallax1': true });
    } else if (this.state.parallax1 && (this.dimensions1.bottom <= 0 || this.context1 <= 0)) {
      this.setState({ 'parallax1': false });
    }

    if (this.context2 >= 0 && this.dimensions2.bottom >= 0 && !this.state.parallax2) {
      this.setState({ 'parallax2': true });
    } else if (this.state.parallax2 && (this.dimensions2.bottom <= 0 && this.context2 <= 0)) {
      this.setState({ 'parallax2': false });
    }

    this.ticking = false;
  }
  render() {
    return (
      <div className="case-study run-it-once">
          <RioHero logo={images.logo} cardbox={images.cardbox} parallax={this.state.parallax0} />
          <TwoCards hero={images.hero} />
          <Deck deck={images.deck} parallax={this.state.parallax1} />
          <Cards cards={images.cards} parallax={this.state.parallax2} />
      </div>
    );
  }
}


ReactDOM.render(<RunItOnce images={images} helpers={helpers} />, document.getElementById("app"));

              
            
!
999px

Console