diff --git a/package.json b/package.json
index 02c227df8ccd35562e7cb2750212ee0f683bcbb2..2d4bcf9b71c571c0bc8dca8a2677c7a64fec3798 100644
--- a/package.json
+++ b/package.json
@@ -91,7 +91,7 @@
     "scratch-audio": "0.1.0-prerelease.1523977528",
     "scratch-blocks": "0.1.0-prerelease.1524774938",
     "scratch-l10n": "2.0.20180108132626",
-    "scratch-paint": "0.2.0-prerelease.20180426161647",
+    "scratch-paint": "0.2.0-prerelease.20180426204040",
     "scratch-render": "0.1.0-prerelease.20180427143155",
     "scratch-svg-renderer": "0.1.0-prerelease.20180423193917",
     "scratch-storage": "0.4.0",
diff --git a/src/components/cards/card.css b/src/components/cards/card.css
new file mode 100644
index 0000000000000000000000000000000000000000..84b6e6bf784773577d29e29954b663d19f74ab5a
--- /dev/null
+++ b/src/components/cards/card.css
@@ -0,0 +1,236 @@
+@import "../../css/units.css";
+@import "../../css/colors.css";
+
+.card-container {
+    position:absolute;
+    z-index: 100;
+}
+
+.left-card, .right-card {
+    height: 90%;
+    position: absolute;
+    top: 5%;
+    background: $ui-white;
+    border: 1px solid $ui-tertiary;
+    width: 10px;
+    z-index: 99;
+    opacity: 0.9;
+    overflow: hidden;
+}
+
+.left-card {
+    left: -10px;
+    border-right: 0;
+    border-top-left-radius: 0.75rem;
+    border-bottom-left-radius: 0.75rem;
+}
+
+.right-card {
+    right: -10px;
+    border-left: 0;
+    border-top-right-radius: 0.75rem;
+    border-bottom-right-radius: 0.75rem;
+}
+
+.left-card::after, .right-card::after {
+    content: "";
+    position: absolute;
+    top: 0;
+    left: 0;
+    height: 1.8rem;
+    width: 100%;
+    background: $motion-primary;
+}
+
+.left-button, .right-button {
+    position: absolute;
+    top: 50%;
+    margin-top: -15px;
+    z-index: 101;
+    user-select: none;
+    cursor: pointer;
+    background: $motion-primary;
+    box-shadow: 0 0 0 4px $motion-transparent;
+    height: 40px;
+    width: 40px;
+    border-radius: 100%;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+}
+
+.left-button {
+    left: -27px;
+}
+
+.right-button {
+    right: -27px;
+}
+
+.card {
+    border: 1px solid $ui-tertiary;
+    border-radius: 0.75rem;
+    display: flex;
+    flex-direction: column;
+    cursor: move;
+    z-index: 101;
+    overflow: hidden;
+    box-shadow: 0px 5px 25px 5px $ui-black-transparent;
+    align-items: center;
+}
+
+.header-buttons {
+    width: 100%;
+    display: flex;
+    flex-direction: row;
+    justify-content: space-between;
+    align-items: center;
+    background: $motion-primary;
+    border-bottom: 1px solid $motion-tertiary;
+    padding: 0.5rem;
+    font-size: 0.625rem;
+}
+
+.remove-button, .all-button {
+    cursor: pointer;
+    color: white;
+    display: flex;
+    flex-direction: row;
+    justify-content: center;
+    align-items: center;
+}
+
+.step-title {
+    font-size: 0.9rem;
+    margin: 0.9rem;
+    text-align: center;
+    font-weight: bold;
+    color: $text-primary;
+}
+
+.step-body {
+    background: $ui-white;
+    display: flex;
+    flex-direction: column;
+    justify-content: center;
+    align-items: center;
+    position: relative;
+    text-align: center;
+}
+
+.step-video {
+    height: 337px;
+}
+
+.step-image {
+    max-width: 450px;
+    background: #F9F9F9;
+    border: 1px solid #ddd;
+    border-radius: 0.5rem;
+    overflow: hidden;
+    margin: 0 0.5rem 0.5rem;
+}
+
+.decks {
+    display: flex;
+    flex-direction: row;
+    justify-content: space-around;
+    padding: 0 0.5rem 0.5rem;
+}
+
+.deck {
+    display: flex;
+    flex-direction: column;
+    margin: 0 8px 8px;
+    cursor: pointer;
+    border: 1px solid $ui-black-transparent;
+    border-radius: 0.25rem;
+    overflow: hidden;
+}
+
+.deck-image {
+    width: 130px;
+    height: 100px;
+    object-fit: cover;
+}
+
+.deck-name {
+    color: $motion-primary;
+    font-weight: bold;
+    font-size: 0.85rem;
+    margin: 14px 0px;
+    text-align: center;
+    font-family: "Helvetica Neue";
+    font-weight: bold;
+    text-align: center;
+}
+
+.help-icon, .close-icon {
+    height: 0.75rem;
+}
+
+.help-icon {
+    margin-right: 0.25rem;
+}
+
+.close-icon {
+    margin-left: 0.25rem;
+    transform: rotate(45deg);
+}
+
+.see-all {
+    display: flex;
+    flex-direction: row;
+    justify-content: center;
+    width: 100%;
+    padding: 0.5rem;
+}
+
+.see-all-button {
+    cursor: pointer;
+    padding: 0.5rem 1rem;
+    background-color: $motion-primary;
+    color: white;
+    font-weight: bold;
+    border-radius: 0.25rem;
+    display: flex;
+    align-items: center;
+    color: $ui-white;
+    font-family: "Helvetica Neue";
+    font-size: 12px;
+    font-weight: bold;
+    line-height: 15px;
+    text-align: center;
+}
+
+.see-all-button img {
+    margin-left: 0.5rem;
+}
+
+.video-cover {
+    width: 100%;
+    height: 100%;
+    position: absolute;
+    top: 0;
+    left: 0;
+}
+
+.steps-list {
+    display: flex;
+    flex-direction: row;
+    justify-content: center;
+    align-items: center;
+}
+
+.active-step-pip, .inactiveStepPip {
+    width: 0.5rem;
+    height: 0.5rem;
+    margin: 0 0.25rem;
+    border-radius: 100%;
+    background: transparent;
+    border: 2px solid $ui-white-transparent;
+}
+
+.active-step-pip {
+    background: white;
+}
diff --git a/src/components/cards/cards.jsx b/src/components/cards/cards.jsx
new file mode 100644
index 0000000000000000000000000000000000000000..ab01f8ecdf1f54a193abb692a38c0f00061e80b3
--- /dev/null
+++ b/src/components/cards/cards.jsx
@@ -0,0 +1,284 @@
+import PropTypes from 'prop-types';
+import React, {Fragment} from 'react';
+import {FormattedMessage} from 'react-intl';
+import Draggable from 'react-draggable';
+
+import styles from './card.css';
+
+import nextIcon from './icon--next.svg';
+import prevIcon from './icon--prev.svg';
+
+import helpIcon from './icon--help.svg';
+import closeIcon from '../close-button/icon--close.svg';
+
+const CardHeader = ({onCloseCards, onShowAll, totalSteps, step}) => (
+    <div className={styles.headerButtons}>
+        <div
+            className={styles.allButton}
+            onClick={onShowAll}
+        >
+            <img
+                className={styles.helpIcon}
+                src={helpIcon}
+            />
+            <FormattedMessage
+                defaultMessage="All How-Tos"
+                description="Title for button to return to how-to library"
+                id="gui.cards.all-how-tos"
+            />
+        </div>
+        {totalSteps > 1 ? (
+            <div className={styles.stepsList}>
+                {Array(totalSteps).fill(0)
+                    .map((_, i) => (
+                        <div
+                            className={i === step ? styles.activeStepPip : styles.inactiveStepPip}
+                            key={`pip-step-${i}`}
+                        />
+                    ))}
+            </div>
+        ) : null}
+        <div
+            className={styles.removeButton}
+            onClick={onCloseCards}
+        >
+            <FormattedMessage
+                defaultMessage="Remove"
+                description="Title for button to close how-to card"
+                id="gui.cards.remove"
+            />
+            <img
+                className={styles.closeIcon}
+                src={closeIcon}
+            />
+        </div>
+    </div>
+);
+
+// Video step needs to know if the card is being dragged to cover the video
+// so that the mouseup is not swallowed by the iframe.
+const VideoStep = ({video, dragging}) => (
+    <div className={styles.stepVideo}>
+        {dragging ? (
+            <div className={styles.videoCover} />
+        ) : null}
+        <iframe
+            allowFullScreen
+            allow="autoplay; encrypted-media"
+            frameBorder="0"
+            height="337"
+            src={`${video}?rel=0&amp;showinfo=0`}
+            width="600"
+        />
+    </div>
+);
+
+VideoStep.propTypes = {
+    dragging: PropTypes.bool.isRequired,
+    video: PropTypes.string.isRequired
+};
+
+const ImageStep = ({title, image}) => (
+    <Fragment>
+        <div className={styles.stepTitle}>
+            {title}
+        </div>
+        <div className={styles.stepImageContainer}>
+            <img
+                className={styles.stepImage}
+                draggable={false}
+                src={image}
+            />
+        </div>
+    </Fragment>
+);
+
+ImageStep.propTypes = {
+    image: PropTypes.string.isRequired,
+    title: PropTypes.node.isRequired
+};
+
+const NextPrevButtons = ({onNextStep, onPrevStep}) => (
+    <Fragment>
+        {onNextStep ? (
+            <div>
+                <div className={styles.rightCard} />
+                <div
+                    className={styles.rightButton}
+                    onClick={onNextStep}
+                >
+                    <img
+                        draggable={false}
+                        src={nextIcon}
+                    />
+                </div>
+            </div>
+        ) : null}
+        {onPrevStep ? (
+            <div>
+                <div className={styles.leftCard} />
+                <div
+                    className={styles.leftButton}
+                    onClick={onPrevStep}
+                >
+                    <img
+                        draggable={false}
+                        src={prevIcon}
+                    />
+                </div>
+            </div>
+        ) : null}
+    </Fragment>
+);
+
+NextPrevButtons.propTypes = {
+    onNextStep: PropTypes.func,
+    onPrevStep: PropTypes.func
+};
+CardHeader.propTypes = {
+    onCloseCards: PropTypes.func.isRequired,
+    onShowAll: PropTypes.func.isRequired,
+    step: PropTypes.number,
+    totalSteps: PropTypes.number
+};
+
+const PreviewsStep = ({deckIds, content, onActivateDeckFactory, onShowAll}) => (
+    <Fragment>
+        <div className={styles.stepTitle}>
+            <FormattedMessage
+                defaultMessage="More things to try!"
+                description="Title card with more things to try"
+                id="gui.cards.more-things-to-try"
+            />
+        </div>
+        <div className={styles.decks}>
+            {deckIds.map(id => (
+                <div
+                    className={styles.deck}
+                    key={`deck-preview-${id}`}
+                    onClick={onActivateDeckFactory(id)}
+                >
+                    <img
+                        className={styles.deckImage}
+                        draggable={false}
+                        src={content[id].img}
+                    />
+                    <div className={styles.deckName}>{content[id].name}</div>
+                </div>
+            ))}
+        </div>
+        <div className={styles.seeAll}>
+            <div
+                className={styles.seeAllButton}
+                onClick={onShowAll}
+            >
+                <FormattedMessage
+                    defaultMessage="See more"
+                    description="Title for button to see more in how-to library"
+                    id="gui.cards.see-more"
+                />
+            </div>
+        </div>
+    </Fragment>
+);
+
+PreviewsStep.propTypes = {
+    content: PropTypes.shape({
+        id: PropTypes.shape({
+            name: PropTypes.node.isRequired,
+            img: PropTypes.string.isRequired,
+            steps: PropTypes.arrayOf(PropTypes.shape({
+                title: PropTypes.node,
+                image: PropTypes.string,
+                video: PropTypes.string,
+                deckIds: PropTypes.arrayOf(PropTypes.string)
+            }))
+        })
+    }).isRequired,
+    deckIds: PropTypes.arrayOf(PropTypes.string).isRequired,
+    onActivateDeckFactory: PropTypes.func.isRequired,
+    onShowAll: PropTypes.func.isRequired
+};
+
+const Cards = props => {
+    if (props.activeDeckId === null) return;
+
+    const steps = props.content[props.activeDeckId].steps;
+
+    return (
+        <Draggable
+            bounds="parent"
+            position={{x: props.x, y: props.y}}
+            onDrag={props.onDrag}
+            onStart={props.onStartDrag}
+            onStop={props.onEndDrag}
+        >
+            <div className={styles.cardContainer}>
+                <div className={styles.card}>
+                    <CardHeader
+                        step={props.step}
+                        totalSteps={steps.length}
+                        onCloseCards={props.onCloseCards}
+                        onShowAll={props.onShowAll}
+                    />
+                    <div className={styles.stepBody}>
+                        {steps[props.step].deckIds ? (
+                            <PreviewsStep
+                                content={props.content}
+                                deckIds={steps[props.step].deckIds}
+                                onActivateDeckFactory={props.onActivateDeckFactory}
+                                onShowAll={props.onShowAll}
+                            />
+                        ) : (
+                            steps[props.step].video ? (
+                                <VideoStep
+                                    dragging={props.dragging}
+                                    video={steps[props.step].video}
+                                />
+                            ) : (
+                                <ImageStep
+                                    image={steps[props.step].image}
+                                    title={steps[props.step].title}
+                                />
+                            )
+                        )}
+                    </div>
+                    <NextPrevButtons
+                        onNextStep={props.step < steps.length - 1 ? props.onNextStep : null}
+                        onPrevStep={props.step > 0 ? props.onPrevStep : null}
+                    />
+                </div>
+            </div>
+        </Draggable>
+    );
+};
+
+Cards.propTypes = {
+    activeDeckId: PropTypes.string.isRequired,
+    content: PropTypes.shape({
+        id: PropTypes.shape({
+            name: PropTypes.node.isRequired,
+            img: PropTypes.string.isRequired,
+            steps: PropTypes.arrayOf(PropTypes.shape({
+                title: PropTypes.node,
+                image: PropTypes.string,
+                video: PropTypes.string,
+                deckIds: PropTypes.arrayOf(PropTypes.string)
+            }))
+        })
+    }),
+    dragging: PropTypes.bool.isRequired,
+    onActivateDeckFactory: PropTypes.func.isRequired,
+    onCloseCards: PropTypes.func.isRequired,
+    onDrag: PropTypes.func,
+    onEndDrag: PropTypes.func,
+    onNextStep: PropTypes.func.isRequired,
+    onPrevStep: PropTypes.func.isRequired,
+    onShowAll: PropTypes.func,
+    onStartDrag: PropTypes.func,
+    step: PropTypes.number.isRequired,
+    x: PropTypes.number,
+    y: PropTypes.number
+};
+
+export default Cards;
diff --git a/src/components/cards/icon--help.svg b/src/components/cards/icon--help.svg
new file mode 100644
index 0000000000000000000000000000000000000000..436d052874bd47c11a55909be61d0fb83777c000
Binary files /dev/null and b/src/components/cards/icon--help.svg differ
diff --git a/src/components/cards/icon--next.svg b/src/components/cards/icon--next.svg
new file mode 100644
index 0000000000000000000000000000000000000000..0c991f7c6e4cb2e6ce3b85a13e2a84eff50f03f2
Binary files /dev/null and b/src/components/cards/icon--next.svg differ
diff --git a/src/components/cards/icon--prev.svg b/src/components/cards/icon--prev.svg
new file mode 100644
index 0000000000000000000000000000000000000000..82d4e886e115c47e1bec804e5c4dac60f7ae1171
Binary files /dev/null and b/src/components/cards/icon--prev.svg differ
diff --git a/src/components/gui/gui.jsx b/src/components/gui/gui.jsx
index 572d01bab1ffd3989d2e0a21275779ab9c7112f0..640e07fdd6d0af5b8d5fb20b14ffb490dda93313 100644
--- a/src/components/gui/gui.jsx
+++ b/src/components/gui/gui.jsx
@@ -17,8 +17,11 @@ import Stage from '../../containers/stage.jsx';
 import Loader from '../loader/loader.jsx';
 import Box from '../box/box.jsx';
 import MenuBar from '../menu-bar/menu-bar.jsx';
+
 import PreviewModal from '../../containers/preview-modal.jsx';
 import WebGlModal from '../../containers/webgl-modal.jsx';
+import TipsLibrary from '../../containers/tips-library.jsx';
+import Cards from '../../containers/cards.jsx';
 
 import layout from '../../lib/layout-constants.js';
 import styles from './gui.css';
@@ -44,6 +47,7 @@ const GUIComponent = props => {
         activeTabIndex,
         basePath,
         blocksTabVisible,
+        cardsVisible,
         children,
         costumesTabVisible,
         intl,
@@ -54,6 +58,7 @@ const GUIComponent = props => {
         onActivateTab,
         previewInfoVisible,
         soundsTabVisible,
+        tipsLibraryVisible,
         vm,
         ...componentProps
     } = props;
@@ -77,7 +82,6 @@ const GUIComponent = props => {
     if (isRendererSupported === null) {
         isRendererSupported = Renderer.isSupported();
     }
-
     return (
         <Box
             className={styles.pageWrapper}
@@ -92,6 +96,12 @@ const GUIComponent = props => {
             {isRendererSupported ? null : (
                 <WebGlModal />
             )}
+            {tipsLibraryVisible ? (
+                <TipsLibrary />
+            ) : null}
+            {cardsVisible ? (
+                <Cards />
+            ) : null}
             <MenuBar />
             <Box className={styles.bodyWrapper}>
                 <Box className={styles.flexWrapper}>
@@ -212,6 +222,7 @@ GUIComponent.propTypes = {
     activeTabIndex: PropTypes.number,
     basePath: PropTypes.string,
     blocksTabVisible: PropTypes.bool,
+    cardsVisible: PropTypes.bool,
     children: PropTypes.node,
     costumesTabVisible: PropTypes.bool,
     intl: intlShape.isRequired,
@@ -223,6 +234,7 @@ GUIComponent.propTypes = {
     onTabSelect: PropTypes.func,
     previewInfoVisible: PropTypes.bool,
     soundsTabVisible: PropTypes.bool,
+    tipsLibraryVisible: PropTypes.bool,
     vm: PropTypes.instanceOf(VM).isRequired
 };
 GUIComponent.defaultProps = {
diff --git a/src/components/library-item/library-item.css b/src/components/library-item/library-item.css
index f8874e0c4eea50664004c0f843191e2a75ee4da9..7b91cc96acf857c8957877fa73ab431f239385b9 100644
--- a/src/components/library-item/library-item.css
+++ b/src/components/library-item/library-item.css
@@ -71,7 +71,7 @@
 .featured-item {
     flex-basis: 300px;
     max-width: 300px;
-    height: 320px;
+    height: auto;
     overflow: hidden;
     padding: 0;
 }
@@ -87,11 +87,12 @@
 .featured-text {
     font-weight: bold;
     padding: 10px;
-    height: 140px;
+    /* height: 140px; */
     width: 300px;
 }
 
 .featured-description {
+    display: block;
     font-weight: normal;
     line-height: 2;
 }
diff --git a/src/components/library-item/library-item.jsx b/src/components/library-item/library-item.jsx
index 407cd6471b41435f7bdece4b0206bd5799cb3b64..8977d3f931d2069b805a8347ef887f69d78953e5 100644
--- a/src/components/library-item/library-item.jsx
+++ b/src/components/library-item/library-item.jsx
@@ -111,7 +111,10 @@ LibraryItem.propTypes = {
     featured: PropTypes.bool,
     iconURL: PropTypes.string.isRequired,
     id: PropTypes.number.isRequired,
-    name: PropTypes.string.isRequired,
+    name: PropTypes.oneOfType([
+        PropTypes.string,
+        PropTypes.node
+    ]).isRequired,
     onBlur: PropTypes.func,
     onFocus: PropTypes.func,
     onMouseEnter: PropTypes.func.isRequired,
diff --git a/src/components/library/library.jsx b/src/components/library/library.jsx
index e9996d4f2ea4716f35c650e713605aa803a5ff31..55303854055695efdc8371989815b1b87423ac3f 100644
--- a/src/components/library/library.jsx
+++ b/src/components/library/library.jsx
@@ -166,7 +166,10 @@ LibraryComponent.propTypes = {
         PropTypes.shape({
             // @todo remove md5/rawURL prop from library, refactor to use storage
             md5: PropTypes.string,
-            name: PropTypes.string.isRequired,
+            name: PropTypes.oneOfType([
+                PropTypes.string,
+                PropTypes.node
+            ]).isRequired,
             rawURL: PropTypes.string
         })
         /* eslint-enable react/no-unused-prop-types, lines-around-comment */
diff --git a/src/components/menu-bar/icon--help.svg b/src/components/menu-bar/icon--help.svg
new file mode 100644
index 0000000000000000000000000000000000000000..6974a7f45f8c740074060a3414eadc02cefd0084
Binary files /dev/null and b/src/components/menu-bar/icon--help.svg differ
diff --git a/src/components/menu-bar/menu-bar.css b/src/components/menu-bar/menu-bar.css
index 1a26960a4581daece08d44e088419878e0644723..b46d08356a83c2c7c374f22831acd940dad318af 100644
--- a/src/components/menu-bar/menu-bar.css
+++ b/src/components/menu-bar/menu-bar.css
@@ -132,6 +132,12 @@
     height: 1rem;
 }
 
+.help-icon {
+    height: 2rem;
+    width: 3rem;
+    margin-top: 0.5rem;
+}
+
 .account-nav-menu, .mystuff-button {
     padding: 0 .25rem;
     display: flex;
diff --git a/src/components/menu-bar/menu-bar.jsx b/src/components/menu-bar/menu-bar.jsx
index f647b24df534aa6e96ee65917dc59b5b056a0cb7..16f7cfaf6e3be73ec2c67c3ecd565041c006b2e5 100644
--- a/src/components/menu-bar/menu-bar.jsx
+++ b/src/components/menu-bar/menu-bar.jsx
@@ -14,6 +14,7 @@ import Menu from '../../containers/menu.jsx';
 import {MenuItem, MenuSection} from '../menu/menu.jsx';
 import ProjectSaver from '../../containers/project-saver.jsx';
 
+import {openTipsLibrary} from '../../reducers/modals';
 import {
     openFileMenu,
     closeFileMenu,
@@ -31,6 +32,8 @@ import communityIcon from './icon--see-community.svg';
 import dropdownCaret from '../language-selector/dropdown-caret.svg';
 import scratchLogo from './scratch-logo.svg';
 
+import helpIcon from './icon--help.svg';
+
 const MenuBarItemTooltip = ({
     children,
     className,
@@ -220,6 +223,15 @@ const MenuBar = props => (
             </div>
         </div>
         <div className={styles.accountInfoWrapper}>
+            <div
+                className={classNames(styles.menuBarItem, styles.hoverable)}
+                onClick={props.onOpenTipLibrary}
+            >
+                <img
+                    className={styles.helpIcon}
+                    src={helpIcon}
+                />
+            </div>
             <MenuBarItemTooltip id="mystuff">
                 <div
                     className={classNames(
@@ -265,6 +277,7 @@ MenuBar.propTypes = {
     fileMenuOpen: PropTypes.bool,
     onClickEdit: PropTypes.func,
     onClickFile: PropTypes.func,
+    onOpenTipLibrary: PropTypes.func,
     onRequestCloseEdit: PropTypes.func,
     onRequestCloseFile: PropTypes.func
 };
@@ -275,6 +288,7 @@ const mapStateToProps = state => ({
 });
 
 const mapDispatchToProps = dispatch => ({
+    onOpenTipLibrary: () => dispatch(openTipsLibrary()),
     onClickFile: () => dispatch(openFileMenu()),
     onRequestCloseFile: () => dispatch(closeFileMenu()),
     onClickEdit: () => dispatch(openEditMenu()),
diff --git a/src/containers/cards.jsx b/src/containers/cards.jsx
new file mode 100644
index 0000000000000000000000000000000000000000..3d08932f775894aa809014deb85b2cbaca78a93c
--- /dev/null
+++ b/src/containers/cards.jsx
@@ -0,0 +1,46 @@
+import {connect} from 'react-redux';
+
+import {
+    activateDeck,
+    closeCards,
+    nextStep,
+    prevStep,
+    dragCard,
+    startDrag,
+    endDrag
+} from '../reducers/cards';
+
+import {
+    openTipsLibrary
+} from '../reducers/modals';
+
+import CardsComponent from '../components/cards/cards.jsx';
+
+const mapStateToProps = state => ({
+    visible: state.cards.visible,
+    content: state.cards.content,
+    activeDeckId: state.cards.activeDeckId,
+    step: state.cards.step,
+    x: state.cards.x,
+    y: state.cards.y,
+    dragging: state.cards.dragging
+});
+
+const mapDispatchToProps = dispatch => ({
+    onActivateDeckFactory: id => () => dispatch(activateDeck(id)),
+    onShowAll: () => {
+        dispatch(openTipsLibrary());
+        dispatch(closeCards());
+    },
+    onCloseCards: () => dispatch(closeCards()),
+    onNextStep: () => dispatch(nextStep()),
+    onPrevStep: () => dispatch(prevStep()),
+    onDrag: (e_, data) => dispatch(dragCard(data.x, data.y)),
+    onStartDrag: () => dispatch(startDrag()),
+    onEndDrag: () => dispatch(endDrag())
+});
+
+export default connect(
+    mapStateToProps,
+    mapDispatchToProps
+)(CardsComponent);
diff --git a/src/containers/gui.jsx b/src/containers/gui.jsx
index cd2a5a95f76648e57b592e84f10a6e7ba16ca560..a47467c0c338a164ee1a38de1ce0ee7a99c3f24d 100644
--- a/src/containers/gui.jsx
+++ b/src/containers/gui.jsx
@@ -97,10 +97,12 @@ GUI.defaultProps = GUIComponent.defaultProps;
 const mapStateToProps = state => ({
     activeTabIndex: state.editorTab.activeTabIndex,
     blocksTabVisible: state.editorTab.activeTabIndex === BLOCKS_TAB_INDEX,
+    cardsVisible: state.cards.visible,
     costumesTabVisible: state.editorTab.activeTabIndex === COSTUMES_TAB_INDEX,
     loadingStateVisible: state.modals.loadingProject,
     previewInfoVisible: state.modals.previewInfo,
-    soundsTabVisible: state.editorTab.activeTabIndex === SOUNDS_TAB_INDEX
+    soundsTabVisible: state.editorTab.activeTabIndex === SOUNDS_TAB_INDEX,
+    tipsLibraryVisible: state.modals.tipsLibrary
 });
 
 const mapDispatchToProps = dispatch => ({
diff --git a/src/containers/tips-library.jsx b/src/containers/tips-library.jsx
new file mode 100644
index 0000000000000000000000000000000000000000..7d45f37a6c967aa2ff669464bc41042aee768da7
--- /dev/null
+++ b/src/containers/tips-library.jsx
@@ -0,0 +1,75 @@
+import bindAll from 'lodash.bindall';
+import PropTypes from 'prop-types';
+import React from 'react';
+
+import decksLibraryContent from '../lib/libraries/decks/index.jsx';
+
+import analytics from '../lib/analytics';
+import LibraryComponent from '../components/library/library.jsx';
+
+import {connect} from 'react-redux';
+
+import {
+    closeTipsLibrary
+} from '../reducers/modals';
+
+import {
+    activateDeck
+} from '../reducers/cards';
+
+class TipsLibrary extends React.PureComponent {
+    constructor (props) {
+        super(props);
+        bindAll(this, [
+            'handleItemSelect'
+        ]);
+    }
+    handleItemSelect (item) {
+        this.props.onActivateDeck(item.id);
+        analytics.event({
+            category: 'library',
+            action: 'Select How-to',
+            label: item.id
+        });
+    }
+    render () {
+        const decksLibraryThumbnailData = Object.keys(decksLibraryContent).map(id => ({
+            rawURL: decksLibraryContent[id].img,
+            id: id,
+            name: decksLibraryContent[id].name,
+            featured: true
+        }));
+
+        if (!this.props.visible) return null;
+        return (
+            <LibraryComponent
+                data={decksLibraryThumbnailData}
+                filterable={false}
+                title="How-Tos"
+                visible={this.props.visible}
+                onItemSelected={this.handleItemSelect}
+                onRequestClose={this.props.onRequestClose}
+            />
+        );
+    }
+}
+
+TipsLibrary.propTypes = {
+    onActivateDeck: PropTypes.func.isRequired,
+    onRequestClose: PropTypes.func,
+    visible: PropTypes.bool
+};
+
+const mapStateToProps = state => ({
+    visible: state.modals.tipsLibrary
+});
+
+const mapDispatchToProps = dispatch => ({
+    onActivateDeck: id => dispatch(activateDeck(id)),
+    onRequestClose: () => dispatch(closeTipsLibrary())
+});
+
+export default connect(
+    mapStateToProps,
+    mapDispatchToProps
+)(TipsLibrary);
diff --git a/src/lib/libraries/decks/clicker/add-sound.gif b/src/lib/libraries/decks/clicker/add-sound.gif
new file mode 100644
index 0000000000000000000000000000000000000000..16408bed591f8359bbe2139a9d6fffd7a56a6fa5
Binary files /dev/null and b/src/lib/libraries/decks/clicker/add-sound.gif differ
diff --git a/src/lib/libraries/decks/clicker/add-whenclicked.gif b/src/lib/libraries/decks/clicker/add-whenclicked.gif
new file mode 100644
index 0000000000000000000000000000000000000000..a03b3d14e4b34f6bf1ba52ce8112b6a85019b7b0
Binary files /dev/null and b/src/lib/libraries/decks/clicker/add-whenclicked.gif differ
diff --git a/src/lib/libraries/decks/clicker/click-events.gif b/src/lib/libraries/decks/clicker/click-events.gif
new file mode 100644
index 0000000000000000000000000000000000000000..b387b01e31ba78e9b34d5dd8b4d2c46b407de35d
Binary files /dev/null and b/src/lib/libraries/decks/clicker/click-events.gif differ
diff --git a/src/lib/libraries/decks/clicker/click-goto.gif b/src/lib/libraries/decks/clicker/click-goto.gif
new file mode 100644
index 0000000000000000000000000000000000000000..7be32f5c4f4d955f39538a1e254023fd1aece7c4
Binary files /dev/null and b/src/lib/libraries/decks/clicker/click-goto.gif differ
diff --git a/src/lib/libraries/decks/clicker/click-sprite.gif b/src/lib/libraries/decks/clicker/click-sprite.gif
new file mode 100644
index 0000000000000000000000000000000000000000..955a39c9c78f74d961b9b5feb6825473856c247c
Binary files /dev/null and b/src/lib/libraries/decks/clicker/click-sprite.gif differ
diff --git a/src/lib/libraries/decks/clicker/drag-goto.gif b/src/lib/libraries/decks/clicker/drag-goto.gif
new file mode 100644
index 0000000000000000000000000000000000000000..1e24802e939d0e53ff81b42f93f2c84b56b76d2a
Binary files /dev/null and b/src/lib/libraries/decks/clicker/drag-goto.gif differ
diff --git a/src/lib/libraries/decks/clicker/library-clicker.gif b/src/lib/libraries/decks/clicker/library-clicker.gif
new file mode 100644
index 0000000000000000000000000000000000000000..bc0e2d1934fb1dc91433982237e8088a04ce2f98
Binary files /dev/null and b/src/lib/libraries/decks/clicker/library-clicker.gif differ
diff --git a/src/lib/libraries/decks/clicker/thumb-clicker.gif b/src/lib/libraries/decks/clicker/thumb-clicker.gif
new file mode 100644
index 0000000000000000000000000000000000000000..ca46a4b7bce9e67cf86472bff54feacb33c06841
Binary files /dev/null and b/src/lib/libraries/decks/clicker/thumb-clicker.gif differ
diff --git a/src/lib/libraries/decks/index.jsx b/src/lib/libraries/decks/index.jsx
new file mode 100644
index 0000000000000000000000000000000000000000..d831c5f7380829bb2427bd8a0eda5b0c534befb9
--- /dev/null
+++ b/src/lib/libraries/decks/index.jsx
@@ -0,0 +1,411 @@
+import React from 'react';
+import {FormattedMessage} from 'react-intl';
+
+// Spin around
+import librarySpin from './spin/library-spin.gif';
+import stepDragTurn from './spin/drag-turn.gif';
+import stepClickTurn from './spin/click-turn.gif';
+import stepClickControl from './spin/click-control.gif';
+import stepDragForever from './spin/drag-forever.gif';
+import stepClickForever from './spin/click-forever.gif';
+import stepChangeColor from './spin/change-color.gif';
+
+// Say hello
+import librarySay from './say/library-say.gif';
+import stepAddSprite from './say/add-sprite.gif';
+import stepClickLooks from './say/click-looks.gif';
+import stepDragSay from './say/drag-say.gif';
+import stepClickSay from './say/click-say.gif';
+import stepAnotherSay from './say/another-say.gif';
+import stepEditSay from './say/edit-say.gif';
+import stepClickStack from './say/click-stack.gif';
+
+// Clicker
+import libraryClicker from './clicker/library-clicker.gif';
+import stepDragGoTo from './clicker/drag-goto.gif';
+import stepClickGoTo from './clicker/click-goto.gif';
+import stepClickEvents from './clicker/click-events.gif';
+import stepAddWhenClicked from './clicker/add-whenclicked.gif';
+import stepClickSprite from './clicker/click-sprite.gif';
+import stepAddSound from './clicker/add-sound.gif';
+
+// Videos
+import glideAroundThumb from './videos/glide-around.jpg';
+import changeSizeThumb from './videos/change-size.jpg';
+import switchCostumeThumb from './videos/switch-costume.jpg';
+import hideAndShowThumb from './videos/hide-and-show.jpg';
+import addBackdropThumb from './videos/add-backdrop.jpg';
+import addEffectsThumb from './videos/add-effects.jpg';
+import moveArrowKeysThumb from './videos/move-arrow-keys.jpg';
+import spinThumb from './videos/spin.jpg';
+
+export default {
+    'spin-around': {
+        name: (
+            <FormattedMessage
+                defaultMessage="Spin around"
+                description="Name for the 'Spin around' how-to"
+                id="gui.howtos.spin-around.name"
+            />
+        ),
+        img: librarySpin,
+        steps: [
+            {
+                title: (
+                    <FormattedMessage
+                        defaultMessage="Drag out a “turn” block"
+                        description="Step name for 'Drag out a “turn” block' step"
+                        id="gui.howtos.spin.step_dragTurn"
+                    />
+                ),
+                image: stepDragTurn
+            }, {
+                title: (
+                    <FormattedMessage
+                        defaultMessage="Click the block to run it"
+                        description="Step name for 'Click the block to run it' step"
+                        id="gui.howtos.spin.step_clickTurn"
+                    />
+                ),
+                image: stepClickTurn
+            }, {
+                title: (
+                    <FormattedMessage
+                        defaultMessage="Click the “Control” category"
+                        description="Step name for 'Click the “Control” category' step"
+                        id="gui.howtos.spin.step_clickControl"
+                    />
+                ),
+                image: stepClickControl
+            }, {
+                title: (
+                    <FormattedMessage
+                        defaultMessage="Drag out a “forever” block"
+                        description="Step name for 'Drag out a “forever” block' step"
+                        id="gui.howtos.spin.step_dragForever"
+                    />
+                ),
+                image: stepDragForever
+            }, {
+                title: (
+                    <FormattedMessage
+                        defaultMessage="Click the stack to run it"
+                        description="Step name for 'Click the stack to run it' step"
+                        id="gui.howtos.spin.step_clickForever"
+                    />
+                ),
+                image: stepClickForever
+            }, {
+                title: (
+                    <FormattedMessage
+                        defaultMessage="Add a “change color effect” block"
+                        description="Step name for 'Add a “change color effect” block' step"
+                        id="gui.howtos.spin.step_changeColor"
+                    />
+                ),
+                image: stepChangeColor
+            }, {
+                deckIds: [
+                    'add-a-backdrop',
+                    'switch-costume',
+                    'change-size'
+                ]
+            }
+        ]
+    },
+    'say-hello': {
+        name: (
+            <FormattedMessage
+                defaultMessage="Say hello"
+                description="Name for the 'Say hello' how-to"
+                id="gui.howtos.say-hello.name"
+            />
+        ),
+        img: librarySay,
+        steps: [
+            {
+                title: (
+                    <FormattedMessage
+                        defaultMessage="Add a new sprite"
+                        description="Step name for 'Add a new sprite' step"
+                        id="gui.howtos.say-hello.step_addSprite"
+                    />
+                ),
+                image: stepAddSprite
+            }, {
+                title: (
+                    <FormattedMessage
+                        defaultMessage="Click the “Looks” category"
+                        description="Step name for 'Click the “Looks” category' step"
+                        id="gui.howtos.say-hello.step_clickLooks"
+                    />
+                ),
+                image: stepClickLooks
+            }, {
+                title: (
+                    <FormattedMessage
+                        defaultMessage="Drag out a “say” block"
+                        description="Step name for 'Drag out a “say” block' step"
+                        id="gui.howtos.say-hello.step_dragSay"
+                    />
+                ),
+                image: stepDragSay
+            }, {
+                title: (
+                    <FormattedMessage
+                        defaultMessage="Click the block to run it"
+                        description="Step name for 'Click the block to run it' step"
+                        id="gui.howtos.say-hello.step_clickSay"
+                    />
+                ),
+                image: stepClickSay
+            }, {
+                title: (
+                    <FormattedMessage
+                        defaultMessage="Drag out another “say” block"
+                        description="Step name for 'Drag out another “say” block' step"
+                        id="gui.howtos.say-hello.step_anotherSay"
+                    />
+                ),
+                image: stepAnotherSay
+            }, {
+                title: (
+                    <FormattedMessage
+                        defaultMessage="Say something else"
+                        description="Step name for 'Say something else' step"
+                        id="gui.howtos.say-hello.step_editSay"
+                    />
+                ),
+                image: stepEditSay
+            }, {
+                title: (
+                    <FormattedMessage
+                        defaultMessage="Click the stack to run it"
+                        description="Step name for 'Click the stack to run it' step"
+                        id="gui.howtos.say-hello.step_clickStack"
+                    />
+                ),
+                image: stepClickStack
+            }, {
+                deckIds: [
+                    'add-a-backdrop',
+                    'switch-costume',
+                    'change-size'
+                ]
+            }
+        ]
+    },
+    'run-away': {
+        name: (
+            <FormattedMessage
+                defaultMessage="Run away"
+                description="Name for the 'Run away' how-to"
+                id="gui.howtos.run-away.name"
+            />
+        ),
+        img: libraryClicker,
+        steps: [
+            {
+                title: (
+                    <FormattedMessage
+                        defaultMessage="Drag out a “go to random position” block"
+                        description="Step name for 'Drag out a “go to random position” block' step"
+                        id="gui.howtos.run-away.step_dragGoTo"
+                    />
+                ),
+                image: stepDragGoTo
+            }, {
+                title: (
+                    <FormattedMessage
+                        defaultMessage="Click the block to run it"
+                        description="Step name for 'Click the block to run it' step"
+                        id="gui.howtos.run-away.step_clickGoTo"
+                    />
+                ),
+                image: stepClickGoTo
+            }, {
+                title: (
+                    <FormattedMessage
+                        defaultMessage="Click the “Events” category"
+                        description="Step 3 title"
+                        id="gui.howtos.run-away.step3"
+                    />
+                ),
+                image: stepClickEvents
+            }, {
+                title: (
+                    <FormattedMessage
+                        defaultMessage="Add a “when this sprite clicked” block"
+                        description="Step name for 'Add a “when this sprite clicked” block' step"
+                        id="gui.howtos.run-away.step_addWhenClicked"
+                    />
+                ),
+                image: stepAddWhenClicked
+            }, {
+                title: (
+                    <FormattedMessage
+                        defaultMessage="Click the sprite to run it"
+                        description="Step name for 'Click the sprite to run it' step"
+                        id="gui.howtos.run-away.step_clickSprite"
+                    />
+                ),
+                image: stepClickSprite
+            }, {
+                title: (
+                    <FormattedMessage
+                        defaultMessage="Add a “start sound” block"
+                        description="Step name for 'Add a “start sound” block' step"
+                        id="gui.howtos.run-away.step_addSound"
+                    />
+                ),
+                image: stepAddSound
+            }, {
+                deckIds: [
+                    'add-a-backdrop',
+                    'switch-costume',
+                    'change-size'
+                ]
+            }
+        ]
+    },
+    'glide-around': {
+        name: (
+            <FormattedMessage
+                defaultMessage="Glide around"
+                description="Name for the 'Glide around' how-to"
+                id="gui.howtos.glide-around.name"
+            />
+        ),
+        img: glideAroundThumb,
+        steps: [{
+            video: 'https://www.youtube.com/embed/WUcmsMEIbGg'
+        }, {
+            deckIds: [
+                'add-a-backdrop',
+                'switch-costume',
+                'change-size'
+            ]
+        }]
+    },
+    'change-size': {
+        name: (
+            <FormattedMessage
+                defaultMessage="Change size"
+                description="Name for the 'Change size' how-to"
+                id="gui.howtos.change-size.name"
+            />
+        ),
+        img: changeSizeThumb,
+        steps: [{
+            video: 'https://www.youtube.com/embed/NiK9KcghZ9s'
+        }, {
+            deckIds: [
+                'add-a-backdrop',
+                'switch-costume',
+                'change-size'
+            ]
+        }]
+    },
+    'switch-costume': {
+        name: (
+            <FormattedMessage
+                defaultMessage="Switch costume"
+                description="Name for the 'Switch costume' how-to"
+                id="gui.howtos.switch-costume.name"
+            />
+        ),
+        img: switchCostumeThumb,
+        steps: [{
+            video: 'https://www.youtube.com/embed/AUBoFxQDPWA'
+        }, {
+            deckIds: [
+                'add-a-backdrop',
+                'switch-costume',
+                'change-size'
+            ]
+        }]
+    },
+    'hide-and-show': {
+        name: (
+            <FormattedMessage
+                defaultMessage="Hide & Show"
+                description="Name for the 'Hide & Show' how-to"
+                id="gui.howtos.hide-and-show.name"
+            />
+        ),
+        img: hideAndShowThumb,
+        steps: [{
+            video: 'https://www.youtube.com/embed/jpvqnlfsDTU'
+        }, {
+            deckIds: [
+                'add-a-backdrop',
+                'switch-costume',
+                'change-size'
+            ]
+        }]
+    },
+    'add-a-backdrop': {
+        name: (
+            <FormattedMessage
+                defaultMessage="Add a backdrop"
+                description="Name for the 'Add a backdrop' how-to"
+                id="gui.howtos.add-a-backdrop.name"
+            />
+        ),
+        img: addBackdropThumb,
+        steps: [{
+            video: 'https://www.youtube.com/embed/WpV05Q7AbPU'
+        }, {
+            deckIds: [
+                'add-a-backdrop',
+                'switch-costume',
+                'change-size'
+            ]
+        }]
+    },
+    'add-effects': {
+        name: (
+            <FormattedMessage
+                defaultMessage="Add effects"
+                description="Name for the 'Add effects' how-to"
+                id="gui.howtos.add-effects.name"
+            />
+        ),
+        img: addEffectsThumb,
+        steps: [{
+            video: 'https://www.youtube.com/embed/ORuohhkx15g'
+        }, {
+            deckIds: [
+                'add-a-backdrop',
+                'switch-costume',
+                'change-size'
+            ]
+        }]
+    },
+    'move-around-with-arrow-keys': {
+        name: 'Move Using Arrow Keys',
+        img: moveArrowKeysThumb,
+        steps: [{
+            video: 'https://www.youtube.com/embed/7DUA_Yl0B_M'
+        }, {
+            deckIds: [
+                'add-a-backdrop',
+                'switch-costume',
+                'change-size'
+            ]
+        }]
+    },
+    'spin-video': {
+        name: 'Spin!',
+        img: spinThumb,
+        steps: [{
+            video: 'https://www.youtube.com/embed/rHP3aojB_6w'
+        }, {
+            deckIds: [
+                'add-a-backdrop',
+                'switch-costume',
+                'change-size'
+            ]
+        }]
+    }
+};
diff --git a/src/lib/libraries/decks/intro/add-glide.gif b/src/lib/libraries/decks/intro/add-glide.gif
new file mode 100644
index 0000000000000000000000000000000000000000..9341cd30fe510f61c47d98a1f4c1276731307164
Binary files /dev/null and b/src/lib/libraries/decks/intro/add-glide.gif differ
diff --git a/src/lib/libraries/decks/intro/add-say.gif b/src/lib/libraries/decks/intro/add-say.gif
new file mode 100644
index 0000000000000000000000000000000000000000..55e370e68fde62ff368a0bb463b799a72a93986d
Binary files /dev/null and b/src/lib/libraries/decks/intro/add-say.gif differ
diff --git a/src/lib/libraries/decks/intro/drag-glide.gif b/src/lib/libraries/decks/intro/drag-glide.gif
new file mode 100644
index 0000000000000000000000000000000000000000..939ada9fd076552e433cb2f4092c23dc3ca0d476
Binary files /dev/null and b/src/lib/libraries/decks/intro/drag-glide.gif differ
diff --git a/src/lib/libraries/decks/intro/drag-say.gif b/src/lib/libraries/decks/intro/drag-say.gif
new file mode 100644
index 0000000000000000000000000000000000000000..e6546012f746c2b8189d21790271cfd47bd12871
Binary files /dev/null and b/src/lib/libraries/decks/intro/drag-say.gif differ
diff --git a/src/lib/libraries/decks/intro/hat-stack.gif b/src/lib/libraries/decks/intro/hat-stack.gif
new file mode 100644
index 0000000000000000000000000000000000000000..6e4dc77b0cd8914f176a132dfd52a25ead0d8378
Binary files /dev/null and b/src/lib/libraries/decks/intro/hat-stack.gif differ
diff --git a/src/lib/libraries/decks/intro/when-clicked.gif b/src/lib/libraries/decks/intro/when-clicked.gif
new file mode 100644
index 0000000000000000000000000000000000000000..ab390154f4d16f5a9577074c7e185f9ed7fcc664
Binary files /dev/null and b/src/lib/libraries/decks/intro/when-clicked.gif differ
diff --git a/src/lib/libraries/decks/say/add-sprite.gif b/src/lib/libraries/decks/say/add-sprite.gif
new file mode 100644
index 0000000000000000000000000000000000000000..efcb8a3d556946a2b19f40dfbe33f084997d0da9
Binary files /dev/null and b/src/lib/libraries/decks/say/add-sprite.gif differ
diff --git a/src/lib/libraries/decks/say/another-say.gif b/src/lib/libraries/decks/say/another-say.gif
new file mode 100644
index 0000000000000000000000000000000000000000..842f93b343273c0f9c8a032be03094d1644567a0
Binary files /dev/null and b/src/lib/libraries/decks/say/another-say.gif differ
diff --git a/src/lib/libraries/decks/say/click-looks.gif b/src/lib/libraries/decks/say/click-looks.gif
new file mode 100644
index 0000000000000000000000000000000000000000..a2bf3165319db11b9cba798808b38c3f82b031a1
Binary files /dev/null and b/src/lib/libraries/decks/say/click-looks.gif differ
diff --git a/src/lib/libraries/decks/say/click-say.gif b/src/lib/libraries/decks/say/click-say.gif
new file mode 100644
index 0000000000000000000000000000000000000000..8ed7b817a91fcd98893f0c0e58e8e9dacf8a9a34
Binary files /dev/null and b/src/lib/libraries/decks/say/click-say.gif differ
diff --git a/src/lib/libraries/decks/say/click-stack.gif b/src/lib/libraries/decks/say/click-stack.gif
new file mode 100644
index 0000000000000000000000000000000000000000..bb427e586c84b783bae8b1fd99114d8f1fe376c8
Binary files /dev/null and b/src/lib/libraries/decks/say/click-stack.gif differ
diff --git a/src/lib/libraries/decks/say/drag-say.gif b/src/lib/libraries/decks/say/drag-say.gif
new file mode 100644
index 0000000000000000000000000000000000000000..5597bc9792a145e2cf242ec5380f36a273958caa
Binary files /dev/null and b/src/lib/libraries/decks/say/drag-say.gif differ
diff --git a/src/lib/libraries/decks/say/edit-say.gif b/src/lib/libraries/decks/say/edit-say.gif
new file mode 100644
index 0000000000000000000000000000000000000000..03076cda1d2dc0731e37d788d3341144635999cc
Binary files /dev/null and b/src/lib/libraries/decks/say/edit-say.gif differ
diff --git a/src/lib/libraries/decks/say/library-say.gif b/src/lib/libraries/decks/say/library-say.gif
new file mode 100644
index 0000000000000000000000000000000000000000..45e6ebbafb8a72108377d890493055c1a8cf6ac6
Binary files /dev/null and b/src/lib/libraries/decks/say/library-say.gif differ
diff --git a/src/lib/libraries/decks/say/thumb-say.gif b/src/lib/libraries/decks/say/thumb-say.gif
new file mode 100644
index 0000000000000000000000000000000000000000..279017d1d2a20b9ef6a1abdf93488043ae082855
Binary files /dev/null and b/src/lib/libraries/decks/say/thumb-say.gif differ
diff --git a/src/lib/libraries/decks/spin/change-color.gif b/src/lib/libraries/decks/spin/change-color.gif
new file mode 100644
index 0000000000000000000000000000000000000000..dca51dad4e1c4b8de89436c025ce38d0f03c45c4
Binary files /dev/null and b/src/lib/libraries/decks/spin/change-color.gif differ
diff --git a/src/lib/libraries/decks/spin/click-control.gif b/src/lib/libraries/decks/spin/click-control.gif
new file mode 100644
index 0000000000000000000000000000000000000000..24128a0edd07854a4415e0c467d273558b70afa5
Binary files /dev/null and b/src/lib/libraries/decks/spin/click-control.gif differ
diff --git a/src/lib/libraries/decks/spin/click-forever.gif b/src/lib/libraries/decks/spin/click-forever.gif
new file mode 100644
index 0000000000000000000000000000000000000000..f9d465bc093cb70428ad09e1db37ba2b78057977
Binary files /dev/null and b/src/lib/libraries/decks/spin/click-forever.gif differ
diff --git a/src/lib/libraries/decks/spin/click-turn.gif b/src/lib/libraries/decks/spin/click-turn.gif
new file mode 100644
index 0000000000000000000000000000000000000000..af887244849f335a7b29b0abbcac2b96f2db0ef9
Binary files /dev/null and b/src/lib/libraries/decks/spin/click-turn.gif differ
diff --git a/src/lib/libraries/decks/spin/drag-forever.gif b/src/lib/libraries/decks/spin/drag-forever.gif
new file mode 100644
index 0000000000000000000000000000000000000000..a51d6b4385d2d4d45d6bc15aca2913f0c4f9b6bc
Binary files /dev/null and b/src/lib/libraries/decks/spin/drag-forever.gif differ
diff --git a/src/lib/libraries/decks/spin/drag-turn.gif b/src/lib/libraries/decks/spin/drag-turn.gif
new file mode 100644
index 0000000000000000000000000000000000000000..8df663eaf9316622017ee86a8d100750e97670f4
Binary files /dev/null and b/src/lib/libraries/decks/spin/drag-turn.gif differ
diff --git a/src/lib/libraries/decks/spin/library-spin.gif b/src/lib/libraries/decks/spin/library-spin.gif
new file mode 100644
index 0000000000000000000000000000000000000000..12e60ecf79b543f77a9840fa687a903d69c3db32
Binary files /dev/null and b/src/lib/libraries/decks/spin/library-spin.gif differ
diff --git a/src/lib/libraries/decks/spin/thumb-spin.gif b/src/lib/libraries/decks/spin/thumb-spin.gif
new file mode 100644
index 0000000000000000000000000000000000000000..e151455be735a0a8a65af10a2c85691ff66790f1
Binary files /dev/null and b/src/lib/libraries/decks/spin/thumb-spin.gif differ
diff --git a/src/lib/libraries/decks/story/add-say--zoomed.gif b/src/lib/libraries/decks/story/add-say--zoomed.gif
new file mode 100644
index 0000000000000000000000000000000000000000..2e8470164efa68433d84746e7c5592c1feaa5732
Binary files /dev/null and b/src/lib/libraries/decks/story/add-say--zoomed.gif differ
diff --git a/src/lib/libraries/decks/story/add-say.gif b/src/lib/libraries/decks/story/add-say.gif
new file mode 100644
index 0000000000000000000000000000000000000000..bdf5b7aa697a68936d92a1b8c246effc3512fde0
Binary files /dev/null and b/src/lib/libraries/decks/story/add-say.gif differ
diff --git a/src/lib/libraries/decks/story/add-sprite--zoomed.gif b/src/lib/libraries/decks/story/add-sprite--zoomed.gif
new file mode 100644
index 0000000000000000000000000000000000000000..38d846634fc47e30320d69fe5c20f6d85259270b
Binary files /dev/null and b/src/lib/libraries/decks/story/add-sprite--zoomed.gif differ
diff --git a/src/lib/libraries/decks/story/add-sprite.gif b/src/lib/libraries/decks/story/add-sprite.gif
new file mode 100644
index 0000000000000000000000000000000000000000..ab2735208c992b29e265ab66bdedce13b49c0636
Binary files /dev/null and b/src/lib/libraries/decks/story/add-sprite.gif differ
diff --git a/src/lib/libraries/decks/story/add-wait--zoomed.gif b/src/lib/libraries/decks/story/add-wait--zoomed.gif
new file mode 100644
index 0000000000000000000000000000000000000000..b6c1a3562823d3522bbc7ade77cb2f227ed74f95
Binary files /dev/null and b/src/lib/libraries/decks/story/add-wait--zoomed.gif differ
diff --git a/src/lib/libraries/decks/story/add-wait.gif b/src/lib/libraries/decks/story/add-wait.gif
new file mode 100644
index 0000000000000000000000000000000000000000..ba5701c251d01e5fd94a5503c45e4a263ba3a452
Binary files /dev/null and b/src/lib/libraries/decks/story/add-wait.gif differ
diff --git a/src/lib/libraries/decks/story/another-say--zoomed.gif b/src/lib/libraries/decks/story/another-say--zoomed.gif
new file mode 100644
index 0000000000000000000000000000000000000000..2cd8124409994fcc29de581e840393cdabcff9f2
Binary files /dev/null and b/src/lib/libraries/decks/story/another-say--zoomed.gif differ
diff --git a/src/lib/libraries/decks/story/another-say.gif b/src/lib/libraries/decks/story/another-say.gif
new file mode 100644
index 0000000000000000000000000000000000000000..7a5e09b6c857d5e83ecf6f7829968031a804a79d
Binary files /dev/null and b/src/lib/libraries/decks/story/another-say.gif differ
diff --git a/src/lib/libraries/decks/story/both-say.gif b/src/lib/libraries/decks/story/both-say.gif
new file mode 100644
index 0000000000000000000000000000000000000000..5cce6ad3c8c459303ea84e631709ae0a712b06cc
Binary files /dev/null and b/src/lib/libraries/decks/story/both-say.gif differ
diff --git a/src/lib/libraries/decks/story/click-say.gif b/src/lib/libraries/decks/story/click-say.gif
new file mode 100644
index 0000000000000000000000000000000000000000..02fa02b0f558f906d5b1f58f98809ed808a14660
Binary files /dev/null and b/src/lib/libraries/decks/story/click-say.gif differ
diff --git a/src/lib/libraries/decks/story/dialog.gif b/src/lib/libraries/decks/story/dialog.gif
new file mode 100644
index 0000000000000000000000000000000000000000..b89ab96a4b95fc11322083060b234595f6032566
Binary files /dev/null and b/src/lib/libraries/decks/story/dialog.gif differ
diff --git a/src/lib/libraries/decks/story/green-flag--zoomed.gif b/src/lib/libraries/decks/story/green-flag--zoomed.gif
new file mode 100644
index 0000000000000000000000000000000000000000..18b1ec2b846f8d50d801a63cd239992b1ed07637
Binary files /dev/null and b/src/lib/libraries/decks/story/green-flag--zoomed.gif differ
diff --git a/src/lib/libraries/decks/story/green-flag.gif b/src/lib/libraries/decks/story/green-flag.gif
new file mode 100644
index 0000000000000000000000000000000000000000..aea1e74266188c541a476a1d8b34629249eb945e
Binary files /dev/null and b/src/lib/libraries/decks/story/green-flag.gif differ
diff --git a/src/lib/libraries/decks/story/sprite-library.gif b/src/lib/libraries/decks/story/sprite-library.gif
new file mode 100644
index 0000000000000000000000000000000000000000..51a6738dc351fe2eea0ebae1cbe135370e39befc
Binary files /dev/null and b/src/lib/libraries/decks/story/sprite-library.gif differ
diff --git a/src/lib/libraries/decks/story/story--library.gif b/src/lib/libraries/decks/story/story--library.gif
new file mode 100644
index 0000000000000000000000000000000000000000..f29bbdf2de57f35f453c1ded63491f561475e116
Binary files /dev/null and b/src/lib/libraries/decks/story/story--library.gif differ
diff --git a/src/lib/libraries/decks/videos/add-backdrop.jpg b/src/lib/libraries/decks/videos/add-backdrop.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..a40fed4aba638941d2baa77e7f29a8299f6e5b35
Binary files /dev/null and b/src/lib/libraries/decks/videos/add-backdrop.jpg differ
diff --git a/src/lib/libraries/decks/videos/add-effects.jpg b/src/lib/libraries/decks/videos/add-effects.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..a6e1a135529beb9a8dc8f583d27a8896f01326ce
Binary files /dev/null and b/src/lib/libraries/decks/videos/add-effects.jpg differ
diff --git a/src/lib/libraries/decks/videos/change-size.jpg b/src/lib/libraries/decks/videos/change-size.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..93958ad158f73f1b7cb754d75e9866f108a6794e
Binary files /dev/null and b/src/lib/libraries/decks/videos/change-size.jpg differ
diff --git a/src/lib/libraries/decks/videos/glide-around.jpg b/src/lib/libraries/decks/videos/glide-around.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..f14d947a2383cca810145ad256871d13b7d5019d
Binary files /dev/null and b/src/lib/libraries/decks/videos/glide-around.jpg differ
diff --git a/src/lib/libraries/decks/videos/hide-and-show.jpg b/src/lib/libraries/decks/videos/hide-and-show.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..6b095b4ea94080b34adb83805e9ea2612a21fe9b
Binary files /dev/null and b/src/lib/libraries/decks/videos/hide-and-show.jpg differ
diff --git a/src/lib/libraries/decks/videos/move-arrow-keys.jpg b/src/lib/libraries/decks/videos/move-arrow-keys.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..2e42e189a48a26646db9a8f96d32a1e0c3ccf47b
Binary files /dev/null and b/src/lib/libraries/decks/videos/move-arrow-keys.jpg differ
diff --git a/src/lib/libraries/decks/videos/spin.jpg b/src/lib/libraries/decks/videos/spin.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..5bbef48845f955eb23d0399bf61f79eec30ef99e
Binary files /dev/null and b/src/lib/libraries/decks/videos/spin.jpg differ
diff --git a/src/lib/libraries/decks/videos/switch-costume.jpg b/src/lib/libraries/decks/videos/switch-costume.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..bfbfa87d5484b68ad9981cb56e891c2e1d5161bf
Binary files /dev/null and b/src/lib/libraries/decks/videos/switch-costume.jpg differ
diff --git a/src/lib/libraries/decks/zoom/click-turn--zoomed.gif b/src/lib/libraries/decks/zoom/click-turn--zoomed.gif
new file mode 100644
index 0000000000000000000000000000000000000000..68cbbd8274fa79ee06e4a521e23d95da730b3250
Binary files /dev/null and b/src/lib/libraries/decks/zoom/click-turn--zoomed.gif differ
diff --git a/src/lib/libraries/decks/zoom/click-turn.gif b/src/lib/libraries/decks/zoom/click-turn.gif
new file mode 100644
index 0000000000000000000000000000000000000000..8e10e3db9594795418d20f9679c2db1ed8456cb1
Binary files /dev/null and b/src/lib/libraries/decks/zoom/click-turn.gif differ
diff --git a/src/lib/libraries/decks/zoom/color--zoomed.gif b/src/lib/libraries/decks/zoom/color--zoomed.gif
new file mode 100644
index 0000000000000000000000000000000000000000..30734631014550d87ae78fd45f05675f6e0f5437
Binary files /dev/null and b/src/lib/libraries/decks/zoom/color--zoomed.gif differ
diff --git a/src/lib/libraries/decks/zoom/color.gif b/src/lib/libraries/decks/zoom/color.gif
new file mode 100644
index 0000000000000000000000000000000000000000..5639976b4c28bc5043b88144afef465be6df2253
Binary files /dev/null and b/src/lib/libraries/decks/zoom/color.gif differ
diff --git a/src/lib/libraries/decks/zoom/drag-turn--zoomed.gif b/src/lib/libraries/decks/zoom/drag-turn--zoomed.gif
new file mode 100644
index 0000000000000000000000000000000000000000..af50185eeb4597a0c6967a1f24c006154297c8d7
Binary files /dev/null and b/src/lib/libraries/decks/zoom/drag-turn--zoomed.gif differ
diff --git a/src/lib/libraries/decks/zoom/drag-turn.gif b/src/lib/libraries/decks/zoom/drag-turn.gif
new file mode 100644
index 0000000000000000000000000000000000000000..58d09eff4cd0758fad1201025a6f885d70b456ac
Binary files /dev/null and b/src/lib/libraries/decks/zoom/drag-turn.gif differ
diff --git a/src/lib/libraries/decks/zoom/edge.gif b/src/lib/libraries/decks/zoom/edge.gif
new file mode 100644
index 0000000000000000000000000000000000000000..5069d83a9ab59d78274fef20703ca5128653e900
Binary files /dev/null and b/src/lib/libraries/decks/zoom/edge.gif differ
diff --git a/src/lib/libraries/decks/zoom/forever--zoomed.gif b/src/lib/libraries/decks/zoom/forever--zoomed.gif
new file mode 100644
index 0000000000000000000000000000000000000000..30d94b36f1688bfbd7cf897ba12ee729c7ec6a35
Binary files /dev/null and b/src/lib/libraries/decks/zoom/forever--zoomed.gif differ
diff --git a/src/lib/libraries/decks/zoom/forever.gif b/src/lib/libraries/decks/zoom/forever.gif
new file mode 100644
index 0000000000000000000000000000000000000000..013f925a1c484daab40abd0f3ad7ac677edfc63a
Binary files /dev/null and b/src/lib/libraries/decks/zoom/forever.gif differ
diff --git a/src/lib/libraries/decks/zoom/green-flag.gif b/src/lib/libraries/decks/zoom/green-flag.gif
new file mode 100644
index 0000000000000000000000000000000000000000..dadceba6f918a79475701432645251da76859345
Binary files /dev/null and b/src/lib/libraries/decks/zoom/green-flag.gif differ
diff --git a/src/lib/libraries/decks/zoom/loudness.gif b/src/lib/libraries/decks/zoom/loudness.gif
new file mode 100644
index 0000000000000000000000000000000000000000..11fb68ca8948df097aae30dd9c48dfb47594bc2a
Binary files /dev/null and b/src/lib/libraries/decks/zoom/loudness.gif differ
diff --git a/src/lib/libraries/decks/zoom/move--zoomed.gif b/src/lib/libraries/decks/zoom/move--zoomed.gif
new file mode 100644
index 0000000000000000000000000000000000000000..b3e36a5d9d803ec543d02e5bcc37efc0c2819439
Binary files /dev/null and b/src/lib/libraries/decks/zoom/move--zoomed.gif differ
diff --git a/src/lib/libraries/decks/zoom/move.gif b/src/lib/libraries/decks/zoom/move.gif
new file mode 100644
index 0000000000000000000000000000000000000000..97b1efe86449626e79495ee48a0cb4ac9edc60cc
Binary files /dev/null and b/src/lib/libraries/decks/zoom/move.gif differ
diff --git a/src/lib/libraries/decks/zoom/stop.gif b/src/lib/libraries/decks/zoom/stop.gif
new file mode 100644
index 0000000000000000000000000000000000000000..cbc2b39a7a90ee21da81cce7f58f07f93acc8fbc
Binary files /dev/null and b/src/lib/libraries/decks/zoom/stop.gif differ
diff --git a/src/lib/libraries/decks/zoom/zoom-around--library.gif b/src/lib/libraries/decks/zoom/zoom-around--library.gif
new file mode 100644
index 0000000000000000000000000000000000000000..a7d87c6cd92c56cbfe6155131d58f7573c764b54
Binary files /dev/null and b/src/lib/libraries/decks/zoom/zoom-around--library.gif differ
diff --git a/src/lib/libraries/decks/zoom/zoom-thumb.gif b/src/lib/libraries/decks/zoom/zoom-thumb.gif
new file mode 100644
index 0000000000000000000000000000000000000000..df8410a9912e5ad5d5fc65eeb9a7db82e9ec9abe
Binary files /dev/null and b/src/lib/libraries/decks/zoom/zoom-thumb.gif differ
diff --git a/src/reducers/cards.js b/src/reducers/cards.js
new file mode 100644
index 0000000000000000000000000000000000000000..334225639ca579c80c3ab62ee6d267d10b81ef97
--- /dev/null
+++ b/src/reducers/cards.js
@@ -0,0 +1,118 @@
+import decks from '../lib/libraries/decks/index.jsx';
+
+const CLOSE_CARDS = 'scratch-gui/cards/CLOSE_CARDS';
+const VIEW_CARDS = 'scratch-gui/cards/VIEW_CARDS';
+const ACTIVATE_DECK = 'scratch-gui/cards/ACTIVATE_DECK';
+const NEXT_STEP = 'scratch-gui/cards/NEXT_STEP';
+const PREV_STEP = 'scratch-gui/cards/PREV_STEP';
+const DRAG_CARD = 'scratch-gui/cards/DRAG_CARD';
+const START_DRAG = 'scratch-gui/cards/START_DRAG';
+const END_DRAG = 'scratch-gui/cards/END_DRAG';
+
+const initialState = {
+    visible: false,
+    content: decks,
+    activeDeckId: null,
+    step: 0,
+    x: 292,
+    y: 365,
+    dragging: false
+};
+
+const reducer = function (state, action) {
+    if (typeof state === 'undefined') state = initialState;
+    switch (action.type) {
+    case CLOSE_CARDS:
+        return Object.assign({}, state, {
+            visible: false
+        });
+    case VIEW_CARDS:
+        return Object.assign({}, state, {
+            visible: true
+        });
+    case ACTIVATE_DECK:
+        return Object.assign({}, state, {
+            activeDeckId: action.activeDeckId,
+            step: 0,
+            visible: true
+        });
+    case NEXT_STEP:
+        if (state.activeDeckId !== null) {
+            return Object.assign({}, state, {
+                step: state.step + 1
+            });
+        }
+        return state;
+    case PREV_STEP:
+        if (state.activeDeckId !== null) {
+            if (state.step > 0) {
+                return Object.assign({}, state, {
+                    step: state.step - 1
+                });
+            }
+        }
+        return state;
+    case DRAG_CARD:
+        return Object.assign({}, state, {
+            x: action.x,
+            y: action.y
+        });
+    case START_DRAG:
+        return Object.assign({}, state, {
+            dragging: true
+        });
+    case END_DRAG:
+        return Object.assign({}, state, {
+            dragging: false
+        });
+    default:
+        return state;
+    }
+};
+
+const activateDeck = function (activeDeckId) {
+    return {
+        type: ACTIVATE_DECK,
+        activeDeckId
+    };
+};
+
+const viewCards = function () {
+    return {type: VIEW_CARDS};
+};
+
+const closeCards = function () {
+    return {type: CLOSE_CARDS};
+};
+
+const nextStep = function () {
+    return {type: NEXT_STEP};
+};
+
+const prevStep = function () {
+    return {type: PREV_STEP};
+};
+
+const dragCard = function (x, y) {
+    return {type: DRAG_CARD, x, y};
+};
+
+const startDrag = function () {
+    return {type: START_DRAG};
+};
+
+const endDrag = function () {
+    return {type: END_DRAG};
+};
+
+export {
+    reducer as default,
+    activateDeck,
+    viewCards,
+    closeCards,
+    nextStep,
+    prevStep,
+    dragCard,
+    startDrag,
+    endDrag
+};
diff --git a/src/reducers/gui.js b/src/reducers/gui.js
index 64d84634297fb03efefbc5dbc31592d2cdcf65b5..15218e100f83425f791e1f67a2607f7a3ec2253c 100644
--- a/src/reducers/gui.js
+++ b/src/reducers/gui.js
@@ -1,4 +1,5 @@
 import {combineReducers} from 'redux';
+import cardsReducer from './cards';
 import colorPickerReducer from './color-picker';
 import customProceduresReducer from './custom-procedures';
 import blockDragReducer from './block-drag';
@@ -17,6 +18,7 @@ import {ScratchPaintReducer} from 'scratch-paint';
 
 export default combineReducers({
     blockDrag: blockDragReducer,
+    cards: cardsReducer,
     colorPicker: colorPickerReducer,
     customProcedures: customProceduresReducer,
     editorTab: editorTabReducer,
diff --git a/src/reducers/modals.js b/src/reducers/modals.js
index ce2e91b3365be8b25a136a636ebcb4996de37cd2..6bb28c81bff32909830ad88c17085fef9c299d04 100644
--- a/src/reducers/modals.js
+++ b/src/reducers/modals.js
@@ -12,6 +12,8 @@ const MODAL_SOUND_LIBRARY = 'soundLibrary';
 const MODAL_SPRITE_LIBRARY = 'spriteLibrary';
 const MODAL_SOUND_RECORDER = 'soundRecorder';
 
+const MODAL_TIPS_LIBRARY = 'tipsLibrary';
+
 
 const initialState = {
     [MODAL_BACKDROP_LIBRARY]: false,
@@ -21,7 +23,8 @@ const initialState = {
     [MODAL_PREVIEW_INFO]: true,
     [MODAL_SOUND_LIBRARY]: false,
     [MODAL_SPRITE_LIBRARY]: false,
-    [MODAL_SOUND_RECORDER]: false
+    [MODAL_SOUND_RECORDER]: false,
+    [MODAL_TIPS_LIBRARY]: false
 };
 
 const reducer = function (state, action) {
@@ -83,6 +86,10 @@ const openSoundRecorder = function () {
     analytics.pageview('/modals/microphone');
     return openModal(MODAL_SOUND_RECORDER);
 };
+const openTipsLibrary = function () {
+    analytics.pageview('/modals/tips');
+    return openModal(MODAL_TIPS_LIBRARY);
+};
 const closeBackdropLibrary = function () {
     return closeModal(MODAL_BACKDROP_LIBRARY);
 };
@@ -107,6 +114,9 @@ const closeSoundLibrary = function () {
 const closeSoundRecorder = function () {
     return closeModal(MODAL_SOUND_RECORDER);
 };
+const closeTipsLibrary = function () {
+    return closeModal(MODAL_TIPS_LIBRARY);
+};
 export {
     reducer as default,
     openBackdropLibrary,
@@ -117,6 +127,7 @@ export {
     openSoundLibrary,
     openSpriteLibrary,
     openSoundRecorder,
+    openTipsLibrary,
     closeBackdropLibrary,
     closeCostumeLibrary,
     closeExtensionLibrary,
@@ -124,5 +135,6 @@ export {
     closePreviewInfo,
     closeSpriteLibrary,
     closeSoundLibrary,
-    closeSoundRecorder
+    closeSoundRecorder,
+    closeTipsLibrary
 };
diff --git a/webpack.config.js b/webpack.config.js
index 393e9dbb44ffe9b25971ad3d7195dd319ad6e977..e100c600669b0d91f80b49a4457a13dace5ca1e5 100644
--- a/webpack.config.js
+++ b/webpack.config.js
@@ -90,7 +90,7 @@ module.exports = [
         module: {
             rules: base.module.rules.concat([
                 {
-                    test: /\.(svg|png|wav)$/,
+                    test: /\.(svg|png|wav|gif|jpg)$/,
                     loader: 'file-loader',
                     options: {
                         outputPath: 'static/assets/'
@@ -168,7 +168,8 @@ module.exports = [
             module: {
                 rules: base.module.rules.concat([
                     {
-                        test: /\.(svg|png|wav)$/,
+                      
+                        test: /\.(svg|png|wav|gif|jpg)$/,
                         loader: 'file-loader',
                         options: {
                             outputPath: 'static/assets/',