cssAudio - Activefile-genericCSS - ActiveGeneric - ActiveHTML - ActiveImage - ActiveJS - ActiveSVG - ActiveText - Activefile-genericVideo - ActiveLovehtmlicon-new-collectionicon-personicon-teamlog-outoctocatpop-outspinnerstartv

Pen Settings

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

You're using npm packages, so we've auto-selected Babel for you here, which we require to process imports and make it all work. If you need to use a different JavaScript preprocessor, remove the packages in the npm tab.

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

Use npm Packages

We can make npm packages available for you to use in your JavaScript. We use webpack to prepare them and make them available to import. We'll also process your JavaScript with Babel.

⚠️ This feature can only be used by logged in users.

Code Indentation

     

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.

            
              <div class="intro">
  <h1 class="intro-title">Stranger Things</h1>

  <p class="intro-text intro-text--can">
    The following demo is performance intensive, and will play audio. If you
    experience any issues, try sizing down your browser and refreshing.
    <br/>
    <button class="intro-text-play" data-play>&#9654;</button>
  </p>

  <p class="intro-text intro-text--shouldnt">
    Unfortunately this demo uses many features only found in the latest
    version of Google Chrome. You can still run this, but it may not look
    as intended. Please try running it in Chrome for the best experience.
    <br/>
    <a class="intro-text-button" href="https://www.google.com/chrome/browser/">
      Download Chrome
    </a>
    <button class="intro-text-button" data-play>
      Play Anyway
    </button>
  </p>

  <p class="intro-text intro-text--cant">
    Unfortunately your browser doesn't support this demo. Please download
    Google Chrome, and try running it again.
    <br/>
    <a class="intro-text-button" href="https://www.google.com/chrome/browser/">
      Download Chrome
    </a>
  </p>

  <noscript>
    The following demo requires javascript to run. Please enable it and
    refresh the browser.
  </noscript>
</div>

<div class="viewport">
  <div class="scene">
    <div class="title title--full">
      <div class="title-word">
        <span class="title-word-letter" data-letter="S1">
          <span class="title-word-letter-large">S</span>
          <div class="titlebar titlebar--left"></div>
        </span>
        <span class="title-word-letter" data-letter="T1">T</span>
        <span class="title-word-letter" data-letter="R1">R</span>
        <span class="title-word-letter" data-letter="A">A</span>
        <span class="title-word-letter" data-letter="N1">N</span>
        <span class="title-word-letter" data-letter="G1">G</span>
        <span class="title-word-letter" data-letter="E">E</span>
        <span class="title-word-letter" data-letter="R2">
          <span class="title-word-letter-large">R</span>
          <div class="titlebar titlebar--right"></div>
        </span>
        <div class="titlebar titlebar--top"></div>
      </div>

      <div></div>

      <div class="title-word title-word--second">
        <span class="title-word-letter" data-letter="T2">T</span>
        <span class="title-word-letter" data-letter="H">H</span>
        <span class="title-word-letter" data-letter="I">I</span>
        <span class="title-word-letter" data-letter="N2">N</span>
        <span class="title-word-letter" data-letter="G2">G</span>
        <span class="title-word-letter" data-letter="S2">S</span>
      </div>
    </div>

    <div class="title title--scene title--scene0"></div>
    <div class="title title--scene title--scene1">
      <div class="title-word">
        <div class="title-word-letter" data-letter="A">A</div>
      </div>
    </div>
    <div class="title title--scene title--scene2">
      <div class="title-word">
        <div class="title-word-letter" data-letter="N">N</div>
      </div>
    </div>
    <div class="title title--scene title--scene3">
      <div class="title-word">
        <div class="title-word-letter" data-letter="R">R</div>
        <div class="title-word-letter" data-letter="I">I</div>
      </div>
    </div>
    <div class="title title--scene title--scene4">
      <div class="title-word">
        <div class="title-word-letter" data-letter="S">S</div>
        <div class="title-word-letter" data-letter="G">G</div>
      </div>
    </div>
    <div class="title title--scene title--scene5">
      <div class="title-word">
        <div class="title-word-letter" data-letter="R">R</div>
        <div class="title-word-letter" data-letter="S">S</div>
      </div>
    </div>
    <div class="title title--scene title--scene6">
      <div class="title-word">
        <div class="title-word-letter" data-letter="I">I</div>
        <div class="title-word-letter" data-letter="A">A</div>
        <div class="title-word-letter" data-letter="T">T</div>
        <div class="title-word-letter" data-letter="H">H</div>
        <div class="title-word-letter" data-letter="N">N</div>
        <div class="title-word-letter" data-letter="G">G</div>
      </div>
    </div>
  </div>

  <div class="credits">
    <div class="credits-group">
      <div class="credits-group-credit">
        A Netflix Original Series
      </div>
    </div>

    <div class="credits-group">
      <div class="credits-group-credit" data-text="Winona Ryder">
        Winona Ryder
      </div>
    </div>

    <div class="credits-group">
      <div class="credits-group-credit">
        David Harbour
      </div>
    </div>

    <div class="credits-group">
      <div class="credits-group-credit" data-text="Finn Wolfhard">
        Finn Wolfhard
      </div>
      <div class="credits-group-credit" data-text="Millie Bobby Brown">
        Millie Bobby Brown
      </div>
    </div>

    <div class="credits-group">
      <div class="credits-group-credit" data-text="Gaten Matarazzo">
        Gaten Matarazzo
      </div>
      <div class="credits-group-credit" data-text="Caleb McLaughlin">
        Caleb M<span>c</span>Laughlin
      </div>
    </div>

    <div class="credits-group">
      <div class="credits-group-credit" data-text="Natalia Dyer">
        Natalia Dyer
      </div>
      <div class="credits-group-credit" data-text="Charlie Heaton">
        Charlie Heaton
      </div>
    </div>

    <div class="credits-group">
      <div class="credits-group-credit" data-text="Cara Buono">
        Cara Buono
      </div>
    </div>

    <div class="credits-group">
      <div class="credits-group-sub" data-text="And">
        And
      </div>
      <div class="credits-group-credit" data-text="Matthew Modine">
        Matthew Modine
      </div>
    </div>

    <div class="credits-group">
      <div class="credits-group-sub" data-text="Co-Executive Producer">
        Co-Executive Producer
      </div>
      <div class="credits-group-credit" data-text="Iain Paterson">
        Iain Paterson
      </div>
    </div>

    <div class="credits-group">
      <div class="credits-group-sub" data-text="Executive Producer">
        Executive Producer
      </div>
      <div class="credits-group-credit" data-text="Karl Gajdusek">
        Karl Gajdusek
      </div>
    </div>

    <div class="credits-group">
      <div class="credits-group-sub" data-text="Executive Producers">
        Executive Producers
      </div>
      <div class="credits-group-credit" data-text="Cindy Holland">
        Cindy Holland
      </div>
      <div class="credits-group-credit" data-text="Brian Wright">
        Brian Wright
      </div>
      <div class="credits-group-credit" data-text="Matt Thunell">
        Matt Thunell
      </div>
    </div>

    <div class="credits-group">
      <div class="credits-group-sub" data-text="Executive Producers">
        Executive Producers
      </div>
      <div class="credits-group-credit" data-text="Shawn Levy">
        Shawn Levy
      </div>
      <div class="credits-group-credit" data-text="Dan Cohen">
        Dan Cohen
      </div>
    </div>

    <div class="credits-group">
      <div class="credits-group-sub" data-text="Executive Producers">
        Executive Producers
      </div>
      <div class="credits-group-credit" data-text="The Duffer Brothers">
        The Duffer Brothers
      </div>
    </div>

    <div class="credits-final">
      <div class="credits-group-sub" data-text="Created By">
        Created By
      </div>
      <div class="credits-group-credit" data-text="Will O'Beirne">
        Will O'Beirne
      </div>

      <a
        href="https://wbobeirne.github.io" target="_blank"
        class="credits-final-link credits-final-link--website"
      ></a>
      <a
        href="https://twitter.com/wbobeirne" target="_blank"
        class="credits-final-link credits-final-link--twitter"
      ></a>
      <a
        href="https://github.com/wbobeirne" target="_blank"
        class="credits-final-link credits-final-link--github"
      ></a>
      <a
        href="https://codepen.io/wbobeirne" target="_blank"
        class="credits-final-link credits-final-link--codepen"
      ></a>
    </div>
  </div>
</div>

<div class="vignette"></div>
<div class="grain"></div>
<div class="letterbox">
  <div class="letterbox-cover letterbox-cover--top"></div>
  <div class="letterbox-cover letterbox-cover--left"></div>
  <div class="letterbox-cover letterbox-cover--right"></div>
  <div class="letterbox-cover letterbox-cover--bottom"></div>
</div>
            
          
!
            
              // Variables
$desired-ratio-y: 9;
$desired-ratio-x: 16;
$desired-ratio: #{$desired-ratio-x} / #{$desired-ratio-y};
$desired-ratio-multiplier: $desired-ratio-y / $desired-ratio-x;

$color-bg: #000;
$color-title: #C11B1F;
$color-credits: #A8A6A7;
$color-credits-top: #B2B0B1;
$color-credits-bottom: $color-credits;

$font-title: 'BenguiatITCW01-BoldCn';
$font-credits: "Avant Garde", Avantgarde, "Century Gothic", CenturyGothic, AppleGothic, sans-serif;

$title-fsize: 28vmin;
$title-fsize-large: 34vmin;
$title-spacing: -1.3vmin;
$title-stroke: 0.4vmin;
$title-shadow: 2vmin;

$titlebar-height: 1vmin;
$titlebar-border: 0.4vmin;
$titlebar-shadow-outer: 1.2vmin;
$titlebar-shadow-inner: 0.5vmin;
$titlebar-radius: 0.1vmin;

$credits-fsize: 6vmin;
$credits-fsize-small: 4.6vmin;
$credits-margin: 0vmin;
$credits-speed: 3000ms;
$credits-link-size: 12vmin;
$credits-link-margin: 5vmin;
$credits-shadow-offset: 0.3vmin;
$credits-shadow-blur: 0.15vmin;

/// Remove the unit of a length
@function strip-unit($number) {
  @if type-of($number) == 'number' and not unitless($number) {
    @return $number / ($number * 0 + 1);
  }

  @return $number;
}

// Ensure that things resize properly, even without the correct aspect ratio
@mixin v-rule($rule, $vmin-val) {
  $vw-val: '';

  // Convert multiple args into the proper values, i.e. 10px 20px 5px
  @if type-of($vmin-val) == 'list' {
    @each $val in $vmin-val {
      // 0 and 'auto' or 'none' don't like being mathed
      @if type-of($val) == 'string' or type-of($val) == 'color' or unitless($val) {
        $w-val: #{$vw-val} #{$val};
      }
      @else {
        $vw-val: #{$vw-val} #{strip-unit($val * $desired-ratio-multiplier)}vw;
      }
    }
  }
  // Convert a regular single value, i.e. 100vmin
  @else {
    $vw-val: #{strip-unit($vmin-val * $desired-ratio-multiplier)}vw;
  }

  #{$rule}: $vmin-val;
  @media screen and (max-aspect-ratio: $desired-ratio) {
    #{$rule}: $vw-val;
  }
}

// Simply center something
@mixin centerize() {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translateX(-50%) translateY(-50%);
}

// Font
@font-face {
  font-family: $font-title;
  src: url('https://s3-us-west-2.amazonaws.com/s.cdpn.io/161676/BenguiatProITC-BoldCond.eot') format('embedded-opentype'),
       url('https://s3-us-west-2.amazonaws.com/s.cdpn.io/161676/BenguiatProITC-BoldCond.woff') format('woff'),
       url('https://s3-us-west-2.amazonaws.com/s.cdpn.io/161676/BenguiatProITC-BoldCond.ttf') format('truetype');
  font-style: normal;
  font-weight: bold;
}

// Styles
body {
  background: $color-bg;
  text-align: center;
  line-height: 1;
  margin: 0;
  -webkit-font-smoothing: subpixel-antialiased;
  overflow: hidden;
  box-sizing: border-box;

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

.intro {
  padding: 0 20px;
  width: 100%;
  max-width: 440px;
  @include centerize;
  transition: opacity 600ms ease, visibility 0ms linear 800ms;

  &--hide {
    opacity: 0;
    visibility: hidden;
  }

  &-title {
    font-family: $font-title;
    color: $color-title;
    font-size: 34px;
    margin-bottom: 15px;
  }

  &-text {
    text-align: center;
    color: $color-credits;
    font-size: 16px;
    line-height: 22px;
    font-family: $font-credits;
    display: none;

    &--show {
      display: block;
    }

    &-button {
      display: inline-block;
      vertical-align: top;
      cursor: pointer;
      padding: 0;
      margin: 20px 5px 0;
      width: 160px;
      height: 42px;
      line-height: 42px;
      border: none;
      text-decoration: none;
      font-size: 16px;
      border-radius: 4px;
      font-family: $font-credits;
      background: $color-title;
      color: #FFF;

      &:hover {
        background: darken($color-title, 10%);
      }
    }

    &-play {
      display: block;
      cursor: pointer;
      width: 120px;
      height: 120px;
      margin: 30px auto 0;
      border: 4px solid #FFF;
      font-size: 40px;
      text-indent: 10px;
      color: #FFF;
      background: rgba(#555, 0.2);
      opacity: 0.3;
      border-radius: 100%;
      transition: color 100ms ease, opacity 100ms ease;
      transform: translateZ(0);

      &:hover,
      &:focus,
      &:active {
        opacity: 1;
        color: $color-title;
        outline: 0;
      }
    }
  }
}

.viewport {
  height: 100vh;
  width: 100vw;
  user-select: none;
  display: none;

  &--show {
    display: block;
  }
}

.title {
  @include centerize;
  transform: translateX(-50%) translateY(-45%);
  width: 100%;
  font-size: 0;
  font-family: $font-title;
  color: $color-bg;
  letter-spacing: $title-spacing;
  font-weight: bold;
  display: none;

  -webkit-text-stroke-color: $color-title;
  @include v-rule(-webkit-text-stroke-width, $title-stroke);
  @include v-rule(text-shadow, 0 0 $title-shadow rgba($color-title, 0.5));

  .no-textstroke & {
    text-shadow: 3px  0 $title-shadow $color-title,
                -3px  0 $title-shadow $color-title,
                 0 -3px $title-shadow $color-title,
                 0  3px $title-shadow $color-title;
  }

  &--show {
    display: block;
  }

  &-word {
    position: relative;
    display: inline-block;

    &--second {
      transform: translateY(-38%);
    }

    &-letter {
      display: inline-block;
      position: relative;
      vertical-align: top;
      @include v-rule(font-size, $title-fsize);

      &-large {
        display: inline-block;
        transform: translateY(-2.8%);
        @include v-rule(font-size, $title-fsize-large);
      }
    }
  }
}
.titlebar {
  position: absolute;
  border-style: solid;
  border-color: $color-title;
  @include v-rule(height, $titlebar-height);
  @include v-rule(border-width, $titlebar-border);
  @include v-rule(border-radius, $titlebar-radius);
  box-shadow: 0 0 $titlebar-shadow-outer rgba($color-title, 0.8),
              0 0 $titlebar-shadow-inner rgba($color-title, 0.8) inset;

  &--top {
    bottom: 100%;
    width: 100%;
  }

  &--left,
  &--right {
    top: 90%;
  }

  &--left {
    left: 0;
    right: -12%;
  }
  &--right {
    left: -15%;
    right: 0;
  }
}


.credits {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  font-family: $font-credits;
  font-weight: bold;
  @include v-rule(font-size, $credits-fsize);


  $wiggle: 0.015vmin;
  @keyframes credits-wiggle {
    0%  { transform: translateX(-50%) translateY(-50%) translateX(0)        translateY(0);        }
    20% { transform: translateX(-50%) translateY(-50%) translateX(0)        translateY(-$wiggle); }
    40% { transform: translateX(-50%) translateY(-50%) translateX($wiggle)  translateY(-$wiggle); }
    60% { transform: translateX(-50%) translateY(-50%) translateX(0)        translateY($wiggle);  }
    80% { transform: translateX(-50%) translateY(-50%) translateX(-$wiggle) translateY(0);        }
    100%{ transform: translateX(-50%) translateY(-50%) translateX(-$wiggle) translateY($wiggle);  }
  }
  @keyframes credits-flash {
    0%, 30%   { opacity: 1;    }
    40%       { opacity: 0.97; }
    42%, 85%  { opacity: 1;    }
    92%       { opacity: 0.94; }
    94%, 100% { opacity: 1;    }
  }
  &-group,
  &-final {
    @include centerize;
    width: 90%;
    opacity: 0;
    transition: opacity $credits-speed * 0.1 ease;

    &--show {
      opacity: 1;
      transition-delay: $credits-speed * 0.1;
      animation: credits-wiggle 200ms infinite $credits-speed * 0.1,
                 credits-flash 2200ms infinite $credits-speed * 0.1;
    }
  }

  &-group {
    &-credit,
    &-sub {
      position: relative;
      @include v-rule(margin-bottom, $credits-margin);
      color: $color-credits;
      background: linear-gradient($color-credits-top, $color-credits-bottom);
      -webkit-background-clip: text;
      -webkit-text-fill-color: transparent;

      .no-textstroke & {
        background: none;
        // Just in case
        -webkit-background-clip: border-box;
        -webkit-text-fill-color: currentcolor;
      }

      // Background clip text fill makes shadows not work, so put them in
      // an :after element
      &:after {
        content: attr(data-text);
        position: absolute;
        z-index: -1;
        width: 100%;
        top: 0;
        left: 0;
        background: none;
        text-shadow: $credits-shadow-offset
                     $credits-shadow-offset
                     $credits-shadow-blur #000;
      }
    }

    &-credit {
      font-weight: 800;
      text-transform: uppercase;

      > span {
        @include v-rule(font-size, $credits-fsize * 0.8);
      }
    }

    &-sub {
      @include v-rule(font-size, $credits-fsize-small);
    }
  }

  &-final {
    @include centerize;

    &-link {
      display: inline-block;
      @include v-rule(width, $credits-link-size);
      @include v-rule(height, $credits-link-size);
      @include v-rule(margin, $credits-link-margin);
      background-size: 100% 100%;

      &:hover {
        opacity: 0.8;
      }

      &--website {
        background-image: url("https://s3-us-west-2.amazonaws.com/s.cdpn.io/161676/website.svg");
      }

      &--github {
        background-image: url("https://s3-us-west-2.amazonaws.com/s.cdpn.io/161676/github.svg");
      }

      &--twitter {
        background-image: url("https://s3-us-west-2.amazonaws.com/s.cdpn.io/161676/twitter.svg");
      }

      &--codepen {
        background-image: url("https://s3-us-west-2.amazonaws.com/s.cdpn.io/161676/codepen.svg");
      }
    }
  }
}

.grain {
  @keyframes grain-wiggle {
    0%  { transform: translateX(8%)   translateY(-5%);  }
    10% { transform: translateX(0%)   translateY(0%);   }
    20% { transform: translateX(10%)  translateY(-15%); }
    30% { transform: translateX(-10%) translateY(0%);   }
    40% { transform: translateX(25%)  translateY(15%);  }
    50% { transform: translateX(10%)  translateY(-10%); }
    60% { transform: translateX(-5%)  translateY(5%);   }
    70% { transform: translateX(15%)  translateY(0%);   }
    80% { transform: translateX(-20%) translateY(-10%); }
    90% { transform: translateX(20%)  translateY(15%);  }
    100%{ transform: translateX(4%)   translateY(7%);   }
  }

  position: fixed;
  top: -50vh;
  left: -50vw;
  height: 200vh;
  width: 200vw;
  background: url("https://s3-us-west-2.amazonaws.com/s.cdpn.io/161676/grain.png");
  animation: grain-wiggle 5s steps(10) infinite;
  pointer-events: none;
}

.letterbox {
  @include centerize;
  position: fixed;
  height: 100vh;
  width: 100vh / $desired-ratio-multiplier;
  pointer-events: none;
  display: none;

  &--show {
    display: block;
  }

  @media screen and (max-aspect-ratio: $desired-ratio) {
    height: 100vw * $desired-ratio-multiplier;
    width: 100vw;
  }

  &-cover {
    // Arbitrarily large
    position: absolute;
    width: 5000px;
    height: 5000px;
    background: #000;

    &--top,
    &--bottom {
      left: 50%;
      transform: translateX(-50%);
    }

    &--left,
    &--right {
      top: 50%;
      transform: translateY(-50%);
    }

    &--top {
      bottom: 100%;
    }

    &--left {
      right: 100%;
    }

    &--right {
      left: 100%;
    }

    &--bottom {
      top: 100%;
    }
  }
}


// Title Animations
@mixin letter($letter: null, $scale: null) {
  $selector: "data-letter";
  @if $letter != null {
    $selector: '#{$selector}="#{$letter}"';
  }

  .title-word-letter[#{$selector}] {
    @if $scale != null {
      @include v-rule(font-size, $title-fsize * $scale);

      .textstroke & {
        @include v-rule(text-shadow, 0 0 $title-shadow * $scale rgba($color-title, 0.5));
        @include v-rule(-webkit-text-stroke-width, $title-stroke * $scale);
      }
    }

    @content;
  }

  @if $letter == null and $scale != null {
    .title-word-letter[#{$selector}] .title-word-letter-large {
      @include v-rule(font-size, $title-fsize-large * $scale);
    }
  }
}

@mixin scaled-bar($scale) {
  @include v-rule(height, $titlebar-height * $scale);
  @include v-rule(border-width, $titlebar-border * $scale);
  @include v-rule(border-radius, $titlebar-radius * $scale);
  box-shadow: 0 0 $titlebar-shadow-outer * $scale rgba($color-title, 0.8),
              0 0 $titlebar-shadow-inner * $scale rgba($color-title, 0.8) inset;
}

.title {
  &--scene {
    .title-word {
      @include centerize;
    }
  }

  &--scene1 {
    @keyframes scene1 {
      0%   { transform: translateX(-43.85%) translateY(-40%) scale(2.2);   }
      100% { transform: translateX(-43.85%) translateY(-40%) scale(1); }
    }

    @include letter("A", 60) {
      @include centerize;
      animation: scene1 7000ms ease-out forwards;
      transform-origin: 43.85% 40%;
    }
  }

  &--scene2 {
    @keyframes scene2-word {
      0%   { transform: translateX(-68%) translateY(-41%); }
      100% { transform: translateX(-68%) translateY(-38%); }
    }
    @keyframes scene2-letter {
      0%   { transform: scale(1); }
      100% { transform: scale(0.92); }
    }

    .title-word {
      animation: scene2-word 3000ms linear forwards;
    }

    @include letter("N", 20) {
      animation: scene2-letter 3000ms linear forwards;
      transform-origin: 68.4% 40%;
    }
  }

  &--scene3 {
    @keyframes scene3-r {
      0%   { transform: translateX(-78%) translateY(-30%) scale(0.95);   }
      100% { transform: translateX(-81%) translateY(-30%) scale(0.84); }
    }
    @keyframes scene3-i {
      0%   { transform: translateX(15%) translateY(-50%);  }
      100% { transform: translateX(35%) translateY(-50%); }
    }

    @include letter("R", 23) {
      @include centerize;
      animation: scene3-r 3000ms linear forwards;
      transform-origin: 75% 27%;
    }
    @include letter("I", 23) {
      @include centerize;
      animation: scene3-i 3000ms linear forwards;
    }
  }

  &--scene4 {
    @keyframes scene4-word {
      0%   { transform: translateX(-50%) translateY(-50%) scale(1); }
      100% { transform: translateX(-50%) translateY(-50%) scale(0.9); }
    }
    @keyframes scene4-s {
      0%   { transform: translateX(-53%) translateY(-11%); }
      100% { transform: translateX(-65%) translateY(-11%); }
    }
    @keyframes scene4-g {
      0%   { transform: translateX(-42%) translateY(-90%); }
      100% { transform: translateX(-34%) translateY(-90%); }
    }

    .title-word {
      animation: scene4-word 3000ms linear forwards;
    }

    @include letter("S", 18) {
      @include centerize;
      animation: scene4-s 3000ms linear forwards;
    }
    @include letter("G", 18) {
      @include centerize;
      animation: scene4-g 3000ms linear forwards;
    }
  }

  &--scene5 {
    @keyframes scene5-r {
      0%   { transform: translateX(-118%) translateY(-30%); }
      100% { transform: translateX(-112%) translateY(-34%); }
    }
    @keyframes scene5-s { 
      0%   { transform: translateX(-19%) translateY(-28.5%); }
      100% { transform: translateX(-22%) translateY(-32%);   }
    }

    @include letter("R", 14) {
      @include centerize;
      animation: scene5-r 3000ms linear forwards;
    }
    @include letter("S", 14) {
      @include centerize;
      animation: scene5-s 3000ms linear forwards;
    }
  }

  &--scene6 {
    @keyframes scene6-fade-out {
      0%, 40%   { opacity: 1; }
      85%, 100% { opacity: 0; }
    }
    @keyframes scene6-i {
      0%        { transform: translateX(-105%) translateY(-91%); };
      85%, 100% { transform: translateX(-135%) translateY(-85%); };
    }
    @keyframes scene6-a {
      0%        { transform: translateX(14%) translateY(-91%); };
      85%, 100% { transform: translateX(34%) translateY(-85%); };
    }
    @keyframes scene6-t {
      0%        { transform: translateX(-134%) translateY(-7%); };
      85%, 100% { transform: translateX(-111%) translateY(-1%); };
    }
    @keyframes scene6-h {
      0%        { transform: translateX(24%) translateY(-7%); };
      85%, 100% { transform: translateX(15%) translateY(-1%); };
    }

    @keyframes scene6-fade-in {
      0%, 40%   { opacity: 0; }
      85%, 100% { opacity: 1; }
    }
    @keyframes scene6-n {
      0%, 40% { transform: translateX(-170%) translateY(-50%); }
      100%    { transform: translateX(-147%) translateY(-50%); }
    }
    @keyframes scene6-g {
      0%, 40% { transform: translateX(82%) translateY(-50%); }
      100%    { transform: translateX(49%) translateY(-50%);  }
    }

    @include letter("I", 8) {
      @include centerize;
      animation: scene6-i        6000ms linear forwards,
                 scene6-fade-out 6000ms linear forwards;
    }
    @include letter("A", 8) {
      @include centerize;
      animation: scene6-a        6000ms linear forwards,
                 scene6-fade-out 6000ms linear forwards;
    }
    @include letter("T", 8) {
      @include centerize;
      animation: scene6-t        6000ms linear forwards,
                 scene6-fade-out 6000ms linear forwards;
    }
    @include letter("H", 8) {
      @include centerize;
      animation: scene6-h        6000ms linear forwards,
                 scene6-fade-out 6000ms linear forwards;
    }

    @include letter("N", 3) {
      @include centerize;
      animation: scene6-n       6000ms linear forwards,
                 scene6-fade-in 6000ms linear forwards;
    }
    @include letter("G", 3) {
      @include centerize;
      animation: scene6-g       6000ms linear forwards,
                 scene6-fade-in 6000ms linear forwards;
    }
  }

  &--full {
    @keyframes full-title {
      0% {
        opacity: 1;
        transform: translateX(-50%) translateY(-41%) scale(0.8);
      }
      90% { opacity: 1; }
      100% {
        opacity: 0;
        transform: translateX(-50%) translateY(-45%) scale(0.06);
      }
    }

    // First word
    @keyframes full-s1 {
      0%, 50%   { transform: translateX(-200%); }
      76%, 100% { transform: translateX(0%);    }
    }
    @keyframes full-t1 {
      0%, 40%   { transform: translateY(-120%); }
      75%, 100% { transform: translateY(0%);    }
    }
    @keyframes full-r1 {
      0%, 25%   { transform: translateX(-55%); }
      72%, 100% { transform: translateX(0%);   }
    }
    @keyframes full-a {
      0%        { transform: translateX(-15%); }
      40%, 100% { transform: translateX(0%);   }
    }
    @keyframes full-n1 {
      0%        { transform: translateX(15%); }
      40%, 100% { transform: translateX(0%);  }
    }
    @keyframes full-g1 {
      0%        { transform: translateX(30%); }
      55%, 100% { transform: translateX(0%);  }
    }
    @keyframes full-e {
      0%, 50%   { transform: translateY(-120%); }
      75%, 100% { transform: translateY(0%);    }
    }
    @keyframes full-r2 {
      0%, 45%   { transform: translateX(200%); }
      71%, 100% { transform: translateX(0%);    }
    }

    // Second word
    @keyframes full-t2 {
      0%, 30%   { transform: translateX(-80%); }
      60%, 100% { transform: translateX(0%);   }
    }
    @keyframes full-h {
      0%, 36%   { transform: translateY(200%); }
      76%, 100% { transform: translateY(0%);   }
    }
    @keyframes full-i {
      0%, 25%   { transform: translateX(-70%); }
      75%, 100% { transform: translateX(0%);   }
    }
    @keyframes full-n2 {
      0%, 10%   { transform: translateY(70%); }
      40%, 100% { transform: translateY(0%);   }
    }
    @keyframes full-g2 {
      0%        { transform: translateX(30%); }
      45%, 100% { transform: translateX(0%);  }
    }
    @keyframes full-s2 {
      0%, 40%   { transform: translateY(200%); }
      80%, 100% { transform: translateY(0%);   }
    }

    // Bars
    @keyframes full-bar-top {
      0%, 67%   { transform: scaleX(0); }
      72%, 100% { transform: scaleX(1); }
    }
    @keyframes full-bar-side {
      0%, 70%   { transform: scaleX(0); }
      75%, 100% { transform: scaleX(1); }
    }

    width: 1000vw;
    animation: full-title 20s cubic-bezier(0.15, 0.7, 0.26, 0.88) forwards;
    transform-origin: 50% 45%;

    @include letter(null, 10);
    @include letter("S1") {
      animation: full-s1 20s ease forwards;
    }
    @include letter("T1") {
      animation: full-t1 20s ease forwards;
    }
    @include letter("R1") {
      animation: full-r1 20s ease forwards;
    }
    @include letter("A") {
      animation: full-a 20s ease forwards;
    }
    @include letter("N1") {
      letter-spacing: -15vmin;
      animation: full-n1 20s ease forwards;
    }
    @include letter("G1") {
      animation: full-g1 20s ease forwards;
    }
    @include letter("E") {
      animation: full-e 20s ease forwards;
    }
    @include letter("R2") {
      animation: full-r2 20s ease forwards;
    }

    @include letter("T2") {
      animation: full-t2 20s ease forwards;
    }
    @include letter("H") {
      animation: full-h 20s ease forwards;
    }
    @include letter("I") {
      animation: full-i 20s ease forwards;
    }
    @include letter("N2") {
      letter-spacing: -15vmin;
      animation: full-n2 20s ease forwards;
    }
    @include letter("G2") {
      animation: full-g2 20s ease forwards;
    }
    @include letter("S2") {
      animation: full-s2 20s ease forwards;
    }

    .titlebar {
      @include scaled-bar(10);

      &--top {
        animation: full-bar-top 20s ease forwards;
      }

      &--left,
      &--right {
        animation: full-bar-side 20s ease forwards;
      }

      &--left {
        transform-origin: right;
      }

      &--right {
        transform-origin: left;
      }
    }
  }
}

            
          
!
            
              // Real quick add another modernizr check foooor...
Modernizr.addTest('textstroke', function() {
  var h1 = document.createElement('h1');
  if (!('webkitTextStroke' in h1.style) && !('textStroke' in h1.style)) {
    return false;
  }
  else {
    return true;
  }
});

document.addEventListener("DOMContentLoaded", () => {
  let bind = false;
  let text = null;

  // Must-haves
  if (!Modernizr.audio || !Modernizr.cssanimations || !Modernizr.textshadow) {
    text = document.getElementsByClassName("intro-text--cant")[0];
  }
  // Should-haves
  else if (!Modernizr.textstroke) {
    bind = true;
    text = document.getElementsByClassName("intro-text--shouldnt")[0];
  }
  // All good!
  else {
    bind = true;
    text = document.getElementsByClassName("intro-text--can")[0];
  }

  text.className += " intro-text--show";

  if (bind) {
    const btns = document.querySelectorAll("[data-play]");
    for (let i = 0; i < btns.length; i++) {
      btns[i].addEventListener("click", () => {
        start();
      });
    }
  }
});

// Fade out intro, start music and animation
let started = false;
function start() {
  if (started) {
    return;
  }
  started = true;

  const intro = document.getElementsByClassName("intro")[0];
  
  const music = new Audio("https://s3-us-west-2.amazonaws.com/s.cdpn.io/161676/music.mp3");

  intro.className += " intro--hide";

  music.addEventListener("canplay", () => {
    setTimeout(() => {
      startAnimation();
      setTimeout(() => {
        music.play();
      }, 200);
    }, 1500);
  });
}

// Kick off the animation
function startAnimation() {
  // In milliseconds, how long each one is
  const creditsMs = 3000;
  const scenesMs = [
    creditsMs,
    creditsMs * 2,
    creditsMs,
    creditsMs,
    creditsMs,
    creditsMs,
    creditsMs * 2,
    19500,
  ];

  // Elements
  const viewport = document.getElementsByClassName("viewport")[0];
  const letterbox = document.getElementsByClassName("letterbox")[0];
  const scenes = document.getElementsByClassName("title--scene");
  const fullTitle = document.getElementsByClassName("title--full")[0];
  const credits = document.getElementsByClassName("credits-group");
  const finalCredit = document.getElementsByClassName("credits-final")[0];

  viewport.className += " viewport--show";
  letterbox.className += " letterbox--show";

  // Set up credits to show every interval
  let activeCredits = null;
  for (let i = 0; i < credits.length; i++) {
    setTimeout(() => {
      if (credits[i - 1]) {
        credits[i - 1].className = "credits-group";
      }
      credits[i].className = "credits-group credits-group--show";
    }, i * creditsMs);

    if (!credits[i + 1]) {
      setTimeout(() => {
        credits[i].className="credits-group";
      }, i * creditsMs + creditsMs);
    }
  }

  // Set up scenes to show after each interval
  let offset = 0;
  for (let i = 0; i < scenes.length; i++) {
    setTimeout(() => {
      if (scenes[i - 1]) {
        scenes[i - 1].className = scenes[i - 1]
          .className.replace("title--show", "");
      }
      scenes[i].className += " title--show";
    }, offset);

    offset += scenesMs[i];

    if (!scenes[i + 1]) {
      // Show the last scene
      setTimeout(() => {
        scenes[i].className = scenes[i].className.replace("title--show", "");
        fullTitle.className += " title--show";
      }, offset);

      // Show the final credits
      setTimeout(() => {
        finalCredit.className += " credits-group--show";
      }, offset + scenesMs[i + 1] + 1500);
    }
  }
}

            
          
!
999px
🕑 One or more of the npm packages you are using needs to be built. You're the first person to ever need it! We're building it right now and your preview will start updating again when it's ready.
Loading ..................

Console