diff --git a/.travis.yml b/.travis.yml
index 5805f6b68392113a5296715eaa5ffb7b402a054f..ba21af32461a84353b42c378e6583c44036f9c95 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -29,15 +29,6 @@ before_deploy:
     export BEFORE_DEPLOY_RAN=true
   fi
 deploy:
-- provider: script
-  on:
-    all_branches: true
-  skip_cleanup: true
-  script: npm run deploy -- -x -e $TRAVIS_BRANCH -r https://${GH_TOKEN}@github.com/${TRAVIS_REPO_SLUG}.git
-- provider: script
-  on:
-    all_branches: true
-  script: npm run prune -- https://${GH_TOKEN}@github.com/${TRAVIS_REPO_SLUG}.git
 - provider: npm
   on:
     branch:
@@ -59,5 +50,14 @@ deploy:
   acl: public_read
   skip_cleanup: true
   local_dir: build
+- provider: script
+  on:
+    all_branches: true
+  skip_cleanup: true
+  script: npm run deploy -- -x -e $TRAVIS_BRANCH -r https://${GH_TOKEN}@github.com/${TRAVIS_REPO_SLUG}.git
+- provider: script
+  on:
+    all_branches: true
+  script: npm run prune -- https://${GH_TOKEN}@github.com/${TRAVIS_REPO_SLUG}.git
 after_deploy:
 - 'curl -X POST -H "Fastly-Key: $FASTLY_TOKEN" -H "Accept: application/json" https://api.fastly.com/service/$FASTLY_SERVICE_ID/purge_all'
diff --git a/package.json b/package.json
index 1cf1ce989618cd8fbc19c06aff68b30b717ce046..c18f84fc9460616e1efdc99097092ee9fd005a3c 100644
--- a/package.json
+++ b/package.json
@@ -70,7 +70,6 @@
     "lodash.pick": "4.4.0",
     "minilog": "3.1.0",
     "mkdirp": "^0.5.1",
-    "postcss-import": "^11.0.0",
     "postcss-import": "^12.0.0",
     "postcss-loader": "^3.0.0",
     "postcss-simple-vars": "^4.0.0",
@@ -97,13 +96,13 @@
     "redux-throttle": "0.1.1",
     "rimraf": "^2.6.1",
     "scratch-audio": "0.1.0-prerelease.20180625202813",
-    "scratch-blocks": "0.1.0-prerelease.1533910749",
-    "scratch-l10n": "3.0.20180810134928",
-    "scratch-paint": "0.2.0-prerelease.20180809185222",
+    "scratch-blocks": "0.1.0-prerelease.1534513944",
+    "scratch-l10n": "3.0.20180817135616",
+    "scratch-paint": "0.2.0-prerelease.20180816205442",
     "scratch-render": "0.1.0-prerelease.20180811013828",
     "scratch-storage": "0.5.1",
-    "scratch-svg-renderer": "0.2.0-prerelease.20180712223402",
-    "scratch-vm": "0.2.0-prerelease.20180809193416",
+    "scratch-svg-renderer": "0.2.0-prerelease.20180817005452",
+    "scratch-vm": "0.2.0-prerelease.20180817143311",
     "selenium-webdriver": "3.6.0",
     "startaudiocontext": "1.2.1",
     "style-loader": "^0.22.1",
diff --git a/src/components/browser-modal/browser-modal.css b/src/components/browser-modal/browser-modal.css
index aa8840c4cc822574ff565273a858d52ced169227..a7f86ac4efe52677a2ef8bbf440c162a6f61f426 100644
--- a/src/components/browser-modal/browser-modal.css
+++ b/src/components/browser-modal/browser-modal.css
@@ -34,6 +34,10 @@
     background-size: cover;
 }
 
+[dir="rtl"] .illustration {
+    transform: scaleX(-1);
+}
+
 .body {
     background: $ui-white;
     padding: 1.5rem 2.25rem;
diff --git a/src/components/browser-modal/browser-modal.jsx b/src/components/browser-modal/browser-modal.jsx
index 457105727df41413ee3767d0d02cada6cdcaf1c3..0a271ea7a7838ba2a3500e02503c5bf8b41e24f7 100644
--- a/src/components/browser-modal/browser-modal.jsx
+++ b/src/components/browser-modal/browser-modal.jsx
@@ -22,62 +22,65 @@ const BrowserModal = ({intl, ...props}) => (
         overlayClassName={styles.modalOverlay}
         onRequestClose={props.onBack}
     >
-        <Box className={styles.illustration} />
+        <div dir={props.isRtl ? 'rtl' : 'ltr'} >
+            <Box className={styles.illustration} />
 
-        <Box className={styles.body}>
-            <h2>
-                <FormattedMessage {...messages.label} />
-            </h2>
-            <p>
-                { /* eslint-disable max-len */ }
-                <FormattedMessage
-                    defaultMessage="We're very sorry, but Scratch 3.0 does not support Internet Explorer, Vivaldi, Opera or Silk. We recommend trying a newer browser such as Google Chrome, Mozilla Firefox, or Microsoft Edge."
-                    description="Unsupported browser description"
-                    id="gui.unsupportedBrowser.description"
-                />
-                { /* eslint-enable max-len */ }
-            </p>
-
-            <Box className={styles.buttonRow}>
-                <button
-                    className={styles.backButton}
-                    onClick={props.onBack}
-                >
+            <Box className={styles.body}>
+                <h2>
+                    <FormattedMessage {...messages.label} />
+                </h2>
+                <p>
+                    { /* eslint-disable max-len */ }
                     <FormattedMessage
-                        defaultMessage="Back"
-                        description="Button to go back in unsupported browser modal"
-                        id="gui.unsupportedBrowser.back"
+                        defaultMessage="We're very sorry, but Scratch 3.0 does not support Internet Explorer, Vivaldi, Opera or Silk. We recommend trying a newer browser such as Google Chrome, Mozilla Firefox, or Microsoft Edge."
+                        description="Unsupported browser description"
+                        id="gui.unsupportedBrowser.description"
                     />
-                </button>
+                    { /* eslint-enable max-len */ }
+                </p>
+
+                <Box className={styles.buttonRow}>
+                    <button
+                        className={styles.backButton}
+                        onClick={props.onBack}
+                    >
+                        <FormattedMessage
+                            defaultMessage="Back"
+                            description="Button to go back in unsupported browser modal"
+                            id="gui.unsupportedBrowser.back"
+                        />
+                    </button>
 
+                </Box>
+                <div className={styles.faqLinkText}>
+                    <FormattedMessage
+                        defaultMessage="To learn more, go to the {previewFaqLink}."
+                        description="Invitation to try 3.0 preview"
+                        id="gui.unsupportedBrowser.previewfaq"
+                        values={{
+                            previewFaqLink: (
+                                <a
+                                    className={styles.faqLink}
+                                    href="//scratch.mit.edu/3faq"
+                                >
+                                    <FormattedMessage
+                                        defaultMessage="FAQ"
+                                        description="link to Scratch 3.0 FAQ page"
+                                        id="gui.unsupportedBrowser.previewfaqlinktext"
+                                    />
+                                </a>
+                            )
+                        }}
+                    />
+                </div>
             </Box>
-            <div className={styles.faqLinkText}>
-                <FormattedMessage
-                    defaultMessage="To learn more, go to the {previewFaqLink}."
-                    description="Invitation to try 3.0 preview"
-                    id="gui.unsupportedBrowser.previewfaq"
-                    values={{
-                        previewFaqLink: (
-                            <a
-                                className={styles.faqLink}
-                                href="//scratch.mit.edu/3faq"
-                            >
-                                <FormattedMessage
-                                    defaultMessage="FAQ"
-                                    description="link to Scratch 3.0 FAQ page"
-                                    id="gui.unsupportedBrowser.previewfaqlinktext"
-                                />
-                            </a>
-                        )
-                    }}
-                />
-            </div>
-        </Box>
+        </div>
     </ReactModal>
 );
 
 BrowserModal.propTypes = {
     intl: intlShape.isRequired,
+    isRtl: PropTypes.bool,
     onBack: PropTypes.func.isRequired
 };
 
diff --git a/src/components/cards/card.css b/src/components/cards/card.css
index c16d9b26ec332cdd57c3dd70bf754749df703eda..439c8191f9d7a0fab002fbabb6f6240d91c4da27 100644
--- a/src/components/cards/card.css
+++ b/src/components/cards/card.css
@@ -187,15 +187,26 @@
     height: 1rem;
 }
 
-.help-icon {
+[dir="ltr"] .help-icon {
     margin-right: 0.25rem;
 }
 
-.close-icon {
+[dir="rtl"] .help-icon {
     margin-left: 0.25rem;
+}
+
+.close-icon {
     transform: rotate(45deg);
 }
 
+[dir="ltr"] .close-icon {
+    margin-left: 0.25rem;
+}
+
+[dir="rtl"] .close-icon {
+    margin-right: 0.25rem;
+}
+
 .see-all {
     display: flex;
     flex-direction: row;
@@ -220,10 +231,14 @@
     text-align: center;
 }
 
-.see-all-button img {
+[dir="ltr"] .see-all-button img {
     margin-left: 0.5rem;
 }
 
+[dir="rtl"] .see-all-button img {
+    margin-right: 0.5rem;
+}
+
 .video-cover {
     width: 100%;
     height: 100%;
diff --git a/src/components/cards/cards.jsx b/src/components/cards/cards.jsx
index 8e2c40ac3640b0d8cf9087f662f5e1cfab1a468d..c389f2923028022dbff2d758350ce5096bb397d7 100644
--- a/src/components/cards/cards.jsx
+++ b/src/components/cards/cards.jsx
@@ -5,8 +5,8 @@ import Draggable from 'react-draggable';
 
 import styles from './card.css';
 
-import nextIcon from './icon--next.svg';
-import prevIcon from './icon--prev.svg';
+import rightArrow from './icon--next.svg';
+import leftArrow from './icon--prev.svg';
 
 import helpIcon from '../../lib/assets/icon--tutorials.svg';
 import closeIcon from '../close-button/icon--close.svg';
@@ -98,32 +98,32 @@ ImageStep.propTypes = {
     title: PropTypes.node.isRequired
 };
 
-const NextPrevButtons = ({onNextStep, onPrevStep}) => (
+const NextPrevButtons = ({isRtl, onNextStep, onPrevStep}) => (
     <Fragment>
         {onNextStep ? (
             <div>
-                <div className={styles.rightCard} />
+                <div className={isRtl ? styles.leftCard : styles.rightCard} />
                 <div
-                    className={styles.rightButton}
+                    className={isRtl ? styles.leftButton : styles.rightButton}
                     onClick={onNextStep}
                 >
                     <img
                         draggable={false}
-                        src={nextIcon}
+                        src={isRtl ? leftArrow : rightArrow}
                     />
                 </div>
             </div>
         ) : null}
         {onPrevStep ? (
             <div>
-                <div className={styles.leftCard} />
+                <div className={isRtl ? styles.rightCard : styles.leftCard} />
                 <div
-                    className={styles.leftButton}
+                    className={isRtl ? styles.rightButton : styles.leftButton}
                     onClick={onPrevStep}
                 >
                     <img
                         draggable={false}
-                        src={prevIcon}
+                        src={isRtl ? rightArrow : leftArrow}
                     />
                 </div>
             </div>
@@ -132,6 +132,7 @@ const NextPrevButtons = ({onNextStep, onPrevStep}) => (
 );
 
 NextPrevButtons.propTypes = {
+    isRtl: PropTypes.bool,
     onNextStep: PropTypes.func,
     onPrevStep: PropTypes.func
 };
@@ -201,51 +202,76 @@ PreviewsStep.propTypes = {
 };
 
 const Cards = props => {
-    if (props.activeDeckId === null) return;
+    const {
+        activeDeckId,
+        content,
+        dragging,
+        isRtl,
+        onActivateDeckFactory,
+        onCloseCards,
+        onDrag,
+        onStartDrag,
+        onEndDrag,
+        onShowAll,
+        onNextStep,
+        onPrevStep,
+        step,
+        ...posProps
+    } = props;
+    let {x, y} = posProps;
 
-    const steps = props.content[props.activeDeckId].steps;
+    if (activeDeckId === null) return;
+
+    if (x === 0 && y === 0) {
+        // initialize positions
+        x = isRtl ? -292 : 292;
+        y = 365;
+    }
+
+    const steps = content[activeDeckId].steps;
 
     return (
         <Draggable
             bounds="parent"
-            position={{x: props.x, y: props.y}}
-            onDrag={props.onDrag}
-            onStart={props.onStartDrag}
-            onStop={props.onEndDrag}
+            position={{x: x, y: y}}
+            onDrag={onDrag}
+            onStart={onStartDrag}
+            onStop={onEndDrag}
         >
             <div className={styles.cardContainer}>
                 <div className={styles.card}>
                     <CardHeader
-                        step={props.step}
+                        step={step}
                         totalSteps={steps.length}
-                        onCloseCards={props.onCloseCards}
-                        onShowAll={props.onShowAll}
+                        onCloseCards={onCloseCards}
+                        onShowAll={onShowAll}
                     />
                     <div className={styles.stepBody}>
-                        {steps[props.step].deckIds ? (
+                        {steps[step].deckIds ? (
                             <PreviewsStep
-                                content={props.content}
-                                deckIds={steps[props.step].deckIds}
-                                onActivateDeckFactory={props.onActivateDeckFactory}
-                                onShowAll={props.onShowAll}
+                                content={content}
+                                deckIds={steps[step].deckIds}
+                                onActivateDeckFactory={onActivateDeckFactory}
+                                onShowAll={onShowAll}
                             />
                         ) : (
-                            steps[props.step].video ? (
+                            steps[step].video ? (
                                 <VideoStep
-                                    dragging={props.dragging}
-                                    video={steps[props.step].video}
+                                    dragging={dragging}
+                                    video={steps[step].video}
                                 />
                             ) : (
                                 <ImageStep
-                                    image={steps[props.step].image}
-                                    title={steps[props.step].title}
+                                    image={steps[step].image}
+                                    title={steps[step].title}
                                 />
                             )
                         )}
                     </div>
                     <NextPrevButtons
-                        onNextStep={props.step < steps.length - 1 ? props.onNextStep : null}
-                        onPrevStep={props.step > 0 ? props.onPrevStep : null}
+                        isRtl={isRtl}
+                        onNextStep={step < steps.length - 1 ? onNextStep : null}
+                        onPrevStep={step > 0 ? onPrevStep : null}
                     />
                 </div>
             </div>
@@ -268,6 +294,7 @@ Cards.propTypes = {
         })
     }),
     dragging: PropTypes.bool.isRequired,
+    isRtl: PropTypes.bool,
     onActivateDeckFactory: PropTypes.func.isRequired,
     onCloseCards: PropTypes.func.isRequired,
     onDrag: PropTypes.func,
diff --git a/src/components/coming-soon/coming-soon.css b/src/components/coming-soon/coming-soon.css
index 091d2dd344c4bba864447041cd0c08b5ee07f5d6..900173e420dd9b042964c924b75e38f94898e8de 100644
--- a/src/components/coming-soon/coming-soon.css
+++ b/src/components/coming-soon/coming-soon.css
@@ -62,8 +62,15 @@
 }
 
 .coming-soon-image {
-    margin-left: .125rem;
     width: 1.25rem;
     height: 1.25rem;
     vertical-align: middle;
 }
+
+[dir="ltr"] .coming-soon-image {
+    margin-left: .125rem;
+}
+
+[dir="rtl"] .coming-soon-image {
+    margin-right: .125rem;
+}
diff --git a/src/components/gui/gui.css b/src/components/gui/gui.css
index 1924bd8c4080c2ce3208de1c2fb211492a0fbd79..46cf41d2b79baf011980c08bef45b07eac1e9611 100644
--- a/src/components/gui/gui.css
+++ b/src/components/gui/gui.css
@@ -186,6 +186,9 @@
     */
     display: flex;
     flex-direction: column;
+    /* pad entire wrapper to the left and right; allow children to fill width */
+    padding-left: $space;
+    padding-right: $space;
 }
 
 .stage-and-target-wrapper.large {
@@ -209,9 +212,6 @@
     flex-basis: 0;
 
     padding-top: $space;
-    padding-left: $space;
-    padding-right: $space;
-
     min-height: 0; /* this makes it work in Firefox */
 
     /*
diff --git a/src/components/gui/gui.jsx b/src/components/gui/gui.jsx
index c7859c5aa54aec12c417b36cc28cd1aaf668e78e..96fea86537fb95b886a43268dac70d77334d2e2f 100644
--- a/src/components/gui/gui.jsx
+++ b/src/components/gui/gui.jsx
@@ -125,7 +125,7 @@ const GUIComponent = props => {
                     <ImportModal />
                 ) : null}
                 {isRendererSupported ? null : (
-                    <WebGlModal />
+                    <WebGlModal isRtl={isRtl} />
                 )}
                 {tipsLibraryVisible ? (
                     <TipsLibrary />
diff --git a/src/components/import-modal/import-modal.css b/src/components/import-modal/import-modal.css
index b265efae02fc5ed6c7348a4422d9b84e9e474fa0..7da215c015b83017e9be1c1ad95c57bf7cf8f37a 100644
--- a/src/components/import-modal/import-modal.css
+++ b/src/components/import-modal/import-modal.css
@@ -82,6 +82,10 @@ $sides: 20rem;
     justify-content: flex-start;
 }
 
+[dir="rtl"] .header-item-close img {
+    transform: scaleX(-1);
+}
+
 .body {
     background: $ui-white;
     padding: 1.5rem 2.25rem;
diff --git a/src/components/import-modal/import-modal.jsx b/src/components/import-modal/import-modal.jsx
index 0fa3aac864978b182c294cc4ce0de911ef652e65..1028d5ddc20f0490a19bfecbf82526869a5a2d27 100644
--- a/src/components/import-modal/import-modal.jsx
+++ b/src/components/import-modal/import-modal.jsx
@@ -42,106 +42,112 @@ const ImportModal = ({intl, ...props}) => (
         overlayClassName={styles.modalOverlay}
         onRequestClose={props.onCancel}
     >
-        <Box>
-            <div className={styles.header}>
-                <div
-                    className={classNames(
-                        styles.headerItem,
-                        styles.headerItemClose
-                    )}
-                >
-                    <CloseButton
-                        buttonType="back"
-                        size={CloseButton.SIZE_LARGE}
-                        onClick={props.onGoBack}
-                    />
-                </div>
-                <div
-                    className={classNames(
-                        styles.headerItem,
-                        styles.headerItemTitle
-                    )}
-                >
-                    <h2>
-                        {intl.formatMessage({...messages.title})}
-                    </h2>
-                </div>
-                <div className={classNames(styles.headerItem, styles.headerItemFilter)}>
-                    {null}
+        <div dir={props.isRtl ? 'rtl' : 'ltr'} >
+            <Box>
+                <div className={styles.header}>
+                    <div
+                        className={classNames(
+                            styles.headerItem,
+                            styles.headerItemClose
+                        )}
+                    >
+                        <CloseButton
+                            buttonType="back"
+                            size={CloseButton.SIZE_LARGE}
+                            onClick={props.onGoBack}
+                        />
+                    </div>
+                    <div
+                        className={classNames(
+                            styles.headerItem,
+                            styles.headerItemTitle
+                        )}
+                    >
+                        <h2>
+                            {intl.formatMessage({...messages.title})}
+                        </h2>
+                    </div>
+                    <div className={classNames(styles.headerItem, styles.headerItemFilter)}>
+                        {null}
+                    </div>
                 </div>
-            </div>
-        </Box>
+            </Box>
 
-        <Box className={styles.body}>
-            <p>
-                {intl.formatMessage({...messages.formDescription})}
-            </p>
-            <Box
-                className={classNames(styles.inputRow,
-                    (props.hasValidationError ? styles.badInputContainer : styles.okInputContainer))
-                }
-            >
-                <input
-                    autoFocus
-                    placeholder={props.placeholder}
-                    value={props.inputValue}
-                    onChange={props.onChange}
-                    onKeyPress={props.onKeyPress}
-                />
-                <button
-                    className={styles.okButton}
-                    title="viewproject"
-                    onClick={props.onViewProject}
+            <Box className={styles.body}>
+                <p>
+                    {intl.formatMessage({...messages.formDescription})}
+                </p>
+                <Box
+                    className={classNames(styles.inputRow,
+                        (props.hasValidationError ? styles.badInputContainer : styles.okInputContainer))
+                    }
                 >
-                    <FormattedMessage
-                        defaultMessage="View"
-                        description="Label for button to load a scratch 2.0 project"
-                        id="gui.importModal.viewproject"
+                    <input
+                        autoFocus
+                        placeholder={props.placeholder}
+                        value={props.inputValue}
+                        onChange={props.onChange}
+                        onKeyPress={props.onKeyPress}
                     />
-                </button>
-            </Box>
-            {props.hasValidationError ?
-                <Box className={styles.errorRow}>
-                    <p>
+                    <button
+                        className={styles.okButton}
+                        title={intl.formatMessage({
+                            defaultMessage: 'View Project',
+                            description: 'Tooltip for View button',
+                            id: 'gui.importModal.viewprojecttooltip'
+                        })}
+                        onClick={props.onViewProject}
+                    >
                         <FormattedMessage
-                            {...messages[`${props.errorMessage}`]}
+                            defaultMessage="View"
+                            description="Label for button to load a scratch 2.0 project"
+                            id="gui.importModal.viewproject"
                         />
-                    </p>
-                </Box> : null
-            }
-            <Box className={styles.buttonRow}>
-                <button
-                    onClick={props.onGoBack}
-                >
+                    </button>
+                </Box>
+                {props.hasValidationError ?
+                    <Box className={styles.errorRow}>
+                        <p>
+                            <FormattedMessage
+                                {...messages[`${props.errorMessage}`]}
+                            />
+                        </p>
+                    </Box> : null
+                }
+                <Box className={styles.buttonRow}>
+                    <button
+                        onClick={props.onGoBack}
+                    >
+                        <FormattedMessage
+                            defaultMessage="Go Back"
+                            description="Label for button to back out of importing a project"
+                            id="gui.importInfo.goback"
+                        />
+                    </button>
+                </Box>
+                <Box className={styles.faqLinkText}>
                     <FormattedMessage
-                        defaultMessage="Go Back"
-                        description="Label for button to back out of importing a project"
-                        id="gui.importInfo.goback"
+                        defaultMessage="To learn more, go to the {previewFaqLink}."
+                        description="Invitation to try 3.0 preview"
+                        id="gui.importInfo.previewfaq"
+                        values={{
+                            previewFaqLink: (
+                                <a
+                                    className={styles.faqLink}
+                                    href="//scratch.mit.edu/3faq"
+                                >
+                                    <FormattedMessage
+                                        defaultMessage="FAQ"
+                                        description="link to Scratch 3.0 FAQ page"
+                                        id="gui.importInfo.previewfaqlinktext"
+                                    />
+                                </a>
+                            )
+                        }}
                     />
-                </button>
-            </Box>
-            <Box className={styles.faqLinkText}>
-                <FormattedMessage
-                    defaultMessage="To learn more, go to the {previewFaqLink}."
-                    description="Invitation to try 3.0 preview"
-                    id="gui.importInfo.previewfaq"
-                    values={{
-                        previewFaqLink: (
-                            <a
-                                className={styles.faqLink}
-                                href="//scratch.mit.edu/3faq"
-                            >
-                                <FormattedMessage
-                                    defaultMessage="FAQ"
-                                    description="link to Scratch 3.0 FAQ page"
-                                    id="gui.importInfo.previewfaqlinktext"
-                                />
-                            </a>
-                        )
-                    }}
-                />
+                </Box>
             </Box>
-        </Box>
+        </div>
     </ReactModal>
 );
 
diff --git a/src/components/menu-bar/menu-bar.css b/src/components/menu-bar/menu-bar.css
index 635b18012b2a5e88bc5e7f56372da3d102a2eec0..c1ae3f9fa2144059547841170b555535081062f8 100644
--- a/src/components/menu-bar/menu-bar.css
+++ b/src/components/menu-bar/menu-bar.css
@@ -66,6 +66,7 @@
     align-self: center;
     position: relative;
     align-items: center;
+    white-space: nowrap;
     height: $menu-bar-height;
 }
 
@@ -168,11 +169,18 @@
 }
 
 .dropdown-caret-icon {
-    margin-left: .5rem;
     width: 0.5rem;
     height: 0.5rem;
 }
 
+[dir="ltr"] .dropdown-caret-icon {
+    margin-left: .5rem;
+}
+
+[dir="rtl"] .dropdown-caret-icon {
+    margin-right: .5rem;
+}
+
 .disabled {
     opacity: 0.5;
 }
diff --git a/src/components/menu-bar/menu-bar.jsx b/src/components/menu-bar/menu-bar.jsx
index 28530131fb3e25ae7f01d5d1d6d06fbf76c13ab2..11562411086b5cb47d97300f424d6494a1fd7000 100644
--- a/src/components/menu-bar/menu-bar.jsx
+++ b/src/components/menu-bar/menu-bar.jsx
@@ -91,10 +91,11 @@ MenuBarItemTooltip.propTypes = {
     place: PropTypes.oneOf(['top', 'bottom', 'left', 'right'])
 };
 
-const MenuItemTooltip = ({id, children, className}) => (
+const MenuItemTooltip = ({id, isRtl, children, className}) => (
     <ComingSoonTooltip
         className={classNames(styles.comingSoon, className)}
-        place="right"
+        isRtl={isRtl}
+        place={isRtl ? 'left' : 'right'}
         tooltipClassName={styles.comingSoonTooltip}
         tooltipId={id}
     >
@@ -105,7 +106,8 @@ const MenuItemTooltip = ({id, children, className}) => (
 MenuItemTooltip.propTypes = {
     children: PropTypes.node,
     className: PropTypes.string,
-    id: PropTypes.string
+    id: PropTypes.string,
+    isRtl: PropTypes.bool
 };
 
 const MenuBarMenu = ({
@@ -143,9 +145,9 @@ class MenuBar extends React.Component {
             this.props.onClickLanguage(e);
         }
     }
-    handleRestoreOption (restoreFun /* eslint-disable-line no-unused-vars */) {
+    handleRestoreOption (restoreFun) {
         return () => {
-            // restoreFun(); TODO re-enable this when validation issues are fixed
+            restoreFun();
             this.props.onRequestCloseEdit();
         };
     }
@@ -189,6 +191,7 @@ class MenuBar extends React.Component {
                                 </div>
                                 <MenuBarMenu
                                     open={this.props.languageMenuOpen}
+                                    place={this.props.isRtl ? 'left' : 'right'}
                                     onRequestClose={this.props.onRequestCloseLanguage}
                                 >
                                     <LanguageSelector />
@@ -211,9 +214,13 @@ class MenuBar extends React.Component {
                             </div>
                             <MenuBarMenu
                                 open={this.props.fileMenuOpen}
+                                place={this.props.isRtl ? 'left' : 'right'}
                                 onRequestClose={this.props.onRequestCloseFile}
                             >
-                                <MenuItemTooltip id="new">
+                                <MenuItemTooltip
+                                    id="new"
+                                    isRtl={this.props.isRtl}
+                                >
                                     <MenuItem>
                                         <FormattedMessage
                                             defaultMessage="New"
@@ -223,7 +230,10 @@ class MenuBar extends React.Component {
                                     </MenuItem>
                                 </MenuItemTooltip>
                                 <MenuSection>
-                                    <MenuItemTooltip id="save">
+                                    <MenuItemTooltip
+                                        id="save"
+                                        isRtl={this.props.isRtl}
+                                    >
                                         <MenuItem>
                                             <FormattedMessage
                                                 defaultMessage="Save now"
@@ -232,7 +242,10 @@ class MenuBar extends React.Component {
                                             />
                                         </MenuItem>
                                     </MenuItemTooltip>
-                                    <MenuItemTooltip id="copy">
+                                    <MenuItemTooltip
+                                        id="copy"
+                                        isRtl={this.props.isRtl}
+                                    >
                                         <MenuItem>
                                             <FormattedMessage
                                                 defaultMessage="Save as a copy"
@@ -285,29 +298,28 @@ class MenuBar extends React.Component {
                             </div>
                             <MenuBarMenu
                                 open={this.props.editMenuOpen}
+                                place={this.props.isRtl ? 'left' : 'right'}
                                 onRequestClose={this.props.onRequestCloseEdit}
                             >
-                                <MenuItemTooltip id="restore">
-                                    <DeletionRestorer>{(handleRestore, {restorable /* eslint-disable-line no-unused-vars, max-len */, deletedItem}) => (
-                                        <MenuItem
-                                            className={classNames(styles.disabled)}
-                                            onClick={this.handleRestoreOption(handleRestore)}
-                                        >
-                                            {deletedItem === 'Sprite' ?
-                                                <FormattedMessage
-                                                    defaultMessage="Restore Sprite"
-                                                    description="Menu bar item for restoring the last deleted sprite."
-                                                    id="gui.menuBar.restoreSprite"
-                                                /> :
-                                                <FormattedMessage
-                                                    defaultMessage="Restore"
-                                                    description="Menu bar item for restoring the last deleted item in its disabled state." /* eslint-disable-line max-len */
-                                                    id="gui.menuBar.restore"
-                                                />
-                                            }
-                                        </MenuItem>
-                                    )}</DeletionRestorer>
-                                </MenuItemTooltip>
+                                <DeletionRestorer>{(handleRestore, {restorable, deletedItem}) => (
+                                    <MenuItem
+                                        className={classNames({[styles.disabled]: !restorable})}
+                                        onClick={this.handleRestoreOption(handleRestore)}
+                                    >
+                                        {deletedItem === 'Sprite' ?
+                                            <FormattedMessage
+                                                defaultMessage="Restore Sprite"
+                                                description="Menu bar item for restoring the last deleted sprite."
+                                                id="gui.menuBar.restoreSprite"
+                                            /> :
+                                            <FormattedMessage
+                                                defaultMessage="Restore"
+                                                description="Menu bar item for restoring the last deleted item in its disabled state." /* eslint-disable-line max-len */
+                                                id="gui.menuBar.restore"
+                                            />
+                                        }
+                                    </MenuItem>
+                                )}</DeletionRestorer>
                                 <MenuSection>
                                     <TurboMode>{(toggleTurboMode, {turboMode}) => (
                                         <MenuItem onClick={toggleTurboMode}>
@@ -429,7 +441,7 @@ class MenuBar extends React.Component {
                     </MenuBarItemTooltip>
                     <MenuBarItemTooltip
                         id="account-nav"
-                        place="left"
+                        place={this.props.isRtl ? 'right' : 'left'}
                     >
                         <div
                             className={classNames(
@@ -462,6 +474,7 @@ MenuBar.propTypes = {
     enableCommunity: PropTypes.bool,
     fileMenuOpen: PropTypes.bool,
     intl: intlShape,
+    isRtl: PropTypes.bool,
     languageMenuOpen: PropTypes.bool,
     onClickEdit: PropTypes.func,
     onClickFile: PropTypes.func,
@@ -476,6 +489,7 @@ MenuBar.propTypes = {
 const mapStateToProps = state => ({
     fileMenuOpen: fileMenuOpen(state),
     editMenuOpen: editMenuOpen(state),
+    isRtl: state.locales.isRtl,
     languageMenuOpen: languageMenuOpen(state)
 });
 
diff --git a/src/components/preview-modal/preview-modal.css b/src/components/preview-modal/preview-modal.css
index d6cf6dc4568fd5178ea0849bbd92551838d14bf9..6e17cb6ea0817f2baebc957608831e7ecd8ced7e 100644
--- a/src/components/preview-modal/preview-modal.css
+++ b/src/components/preview-modal/preview-modal.css
@@ -74,17 +74,28 @@
     color: white;
 }
 
-.button-row button + button {
+[dir="ltr"] .button-row button + button {
     margin-left: 0.5rem;
 }
 
+[dir="rtl"] .button-row button + button {
+    margin-right: 0.5rem;
+}
+
 .cat-icon {
-    margin-left: .125rem;
     width: 1.5rem;
     height: 1.5rem;
     vertical-align: middle;
 }
 
+[dir="ltr"] .cat-icon {
+    margin-left: .125rem;
+}
+
+[dir="rtl"] .cat-icon {
+    margin-right: .125rem;
+}
+
 .faq-link-text {
     margin: 2rem 0 .5rem 0;
     font-size: .875rem;
diff --git a/src/components/preview-modal/preview-modal.jsx b/src/components/preview-modal/preview-modal.jsx
index b9c803b767782939b86193725d4ff6dd09b919d1..2c946bb422b78db3f5131f3409ab68254163e296 100644
--- a/src/components/preview-modal/preview-modal.jsx
+++ b/src/components/preview-modal/preview-modal.jsx
@@ -28,93 +28,111 @@ const PreviewModal = ({intl, ...props}) => (
         overlayClassName={styles.modalOverlay}
         onRequestClose={props.onTryIt}
     >
-        <Box className={styles.illustration} />
+        <div dir={props.isRtl ? 'rtl' : 'ltr'} >
+            <Box className={styles.illustration} />
 
-        <Box className={styles.body}>
-            <h2>
-                <FormattedMessage
-                    defaultMessage="Welcome to the Scratch 3.0 Beta"
-                    description="Header for Beta Info Modal"
-                    id="gui.previewInfo.betawelcome"
-                />
-            </h2>
-            <p>
-                <FormattedMessage
-                    defaultMessage="We're working on the next generation of Scratch. We're excited for you to try it!"
-                    description="Invitation to try 3.0 Beta"
-                    id="gui.previewInfo.invitation"
-                />
-            </p>
-
-            <Box className={styles.buttonRow}>
-                <button
-                    className={styles.noButton}
-                    onClick={props.onCancel}
-                >
+            <Box className={styles.body}>
+                <h2>
+                    <FormattedMessage
+                        defaultMessage="Welcome to the Scratch 3.0 Beta"
+                        description="Header for Beta Info Modal"
+                        id="gui.previewInfo.betawelcome"
+                    />
+                </h2>
+                <p>
+                    { /* eslint-disable max-len */ }
                     <FormattedMessage
-                        defaultMessage="Not Now"
-                        description="Label for button to back out of trying Scratch 3.0 Beta"
-                        id="gui.previewInfo.notnow"
+                        defaultMessage="We're working on the next generation of Scratch. We're excited for you to try it!"
+                        description="Invitation to try 3.0 Beta"
+                        id="gui.previewInfo.invitation"
                     />
-                </button>
-                <button
-                    className={styles.okButton}
-                    title="tryit"
-                    onClick={props.onTryIt}
-                >
+                    { /* eslint-enable max-len */ }
+                </p>
+
+                <Box className={styles.buttonRow}>
+                    <button
+                        className={styles.noButton}
+                        title={intl.formatMessage({
+                            defaultMessage: 'Not Now',
+                            description: 'Tooltip for Not Now button',
+                            id: 'gui.previewModal.notnowtooltip'
+                        })}
+                        onClick={props.onCancel}
+                    >
+                        <FormattedMessage
+                            defaultMessage="Not Now"
+                            description="Label for button to back out of trying Scratch 3.0 Beta"
+                            id="gui.previewInfo.notnow"
+                        />
+                    </button>
+                    <button
+                        className={styles.okButton}
+                        title={intl.formatMessage({
+                            defaultMessage: 'Try It',
+                            description: 'Tooltip for Try It button',
+                            id: 'gui.previewModal.tryittooltip'
+                        })}
+                        onClick={props.onTryIt}
+                    >
+                        <FormattedMessage
+                            defaultMessage="Try It! {caticon}"
+                            description="Label for button to try Scratch 3.0 Beta"
+                            id="gui.previewModal.tryit"
+                            values={{
+                                caticon: (
+                                    <img
+                                        className={styles.catIcon}
+                                        src={catIcon}
+                                    />
+                                )
+                            }}
+                        />
+                    </button>
+                    <button
+                        className={styles.viewProjectButton}
+                        title={intl.formatMessage({
+                            defaultMessage: 'View 2.0 Project',
+                            description: 'Tooltip for View 2.0 Project button',
+                            id: 'gui.previewModal.viewprojecttooltip'
+                        })}
+                        onClick={props.onViewProject}
+                    >
+                        <FormattedMessage
+                            defaultMessage="View 2.0 Project"
+                            description="Label for button to import a 2.0 project"
+                            id="gui.previewModal.viewproject"
+                        />
+                    </button>
+                </Box>
+                <Box className={styles.faqLinkText}>
                     <FormattedMessage
-                        defaultMessage="Try It! {caticon}"
-                        description="Label for button to try Scratch 3.0 Beta"
-                        id="gui.previewModal.tryit"
+                        defaultMessage="To learn more, go to the {previewFaqLink}."
+                        description="Invitation to try 3.0 Beta"
+                        id="gui.previewInfo.previewfaq"
                         values={{
-                            caticon: (
-                                <img
-                                    className={styles.catIcon}
-                                    src={catIcon}
-                                />
+                            previewFaqLink: (
+                                <a
+                                    className={styles.faqLink}
+                                    href="//scratch.mit.edu/3faq"
+                                >
+                                    <FormattedMessage
+                                        defaultMessage="FAQ"
+                                        description="link to Scratch 3.0 FAQ page"
+                                        id="gui.previewInfo.previewfaqlinktext"
+                                    />
+                                </a>
                             )
                         }}
                     />
-                </button>
-                <button
-                    className={styles.viewProjectButton}
-                    title="viewproject"
-                    onClick={props.onViewProject}
-                >
-                    <FormattedMessage
-                        defaultMessage="View 2.0 Project"
-                        description="Label for button to import a 2.0 project"
-                        id="gui.previewModal.viewproject"
-                    />
-                </button>
-            </Box>
-            <Box className={styles.faqLinkText}>
-                <FormattedMessage
-                    defaultMessage="To learn more, go to the {previewFaqLink}."
-                    description="Invitation to try 3.0 Beta"
-                    id="gui.previewInfo.previewfaq"
-                    values={{
-                        previewFaqLink: (
-                            <a
-                                className={styles.faqLink}
-                                href="//scratch.mit.edu/3faq"
-                            >
-                                <FormattedMessage
-                                    defaultMessage="FAQ"
-                                    description="link to Scratch 3.0 FAQ page"
-                                    id="gui.previewInfo.previewfaqlinktext"
-                                />
-                            </a>
-                        )
-                    }}
-                />
+                </Box>
             </Box>
-        </Box>
+        </div>
     </ReactModal>
 );
 
 PreviewModal.propTypes = {
     intl: intlShape.isRequired,
+    isRtl: PropTypes.bool,
     onCancel: PropTypes.func.isRequired,
     onTryIt: PropTypes.func.isRequired,
     onViewProject: PropTypes.func.isRequired
diff --git a/src/components/stage-header/stage-header.css b/src/components/stage-header/stage-header.css
index 397c679da34811e8170a422d6f24dc336a619db4..dd2dc2c65ca642338358d681f572a1b04796fd14 100644
--- a/src/components/stage-header/stage-header.css
+++ b/src/components/stage-header/stage-header.css
@@ -22,7 +22,8 @@
     flex-shrink: 0;
     align-items: center;
     height: $stage-menu-height;
-    padding: $space;
+    padding-top: $space;
+    padding-bottom: $space;
 }
 
 .stage-size-row {
diff --git a/src/components/stage-wrapper/stage-wrapper.css b/src/components/stage-wrapper/stage-wrapper.css
index 29ca66aa2923ec3c3b3076a524e4216cfde71832..9f6ab5c6149ecc6c398ce1a0594d7696dd964cf2 100644
--- a/src/components/stage-wrapper/stage-wrapper.css
+++ b/src/components/stage-wrapper/stage-wrapper.css
@@ -6,9 +6,6 @@
 }
 
 .stage-canvas-wrapper {
-    padding-left: $space;
-    padding-right: $space;
-
     /* Hides negative space between edge of rounded corners + container, when selected */
     user-select: none;
 }
diff --git a/src/components/stage/stage.css b/src/components/stage/stage.css
index 003947533cafe82ff22178ce1aaa35d1e3a2e88c..7ce4d55d9f6a953541564e6e12b51fc1fed9be78 100644
--- a/src/components/stage/stage.css
+++ b/src/components/stage/stage.css
@@ -11,7 +11,7 @@
 
     /* Attach border radius directly to canvas to prevent needing overflow:hidden; */
     border-radius: $space;
-    border: 1px solid $ui-black-transparent;
+    border: $stage-standard-border-width solid $ui-black-transparent;
 
     /* @todo: This is for overriding the value being set somewhere. Where is it being set? */
     background-color: transparent;
@@ -51,15 +51,17 @@
     bottom: 0;
     z-index: $z-index-stage-wrapper-overlay;
     background-color: $ui-white;
+    /* spacing between stage and control bar (on the top), or between
+    stage and window edges (on left/right/bottom) */
+    padding: $stage-full-screen-stage-padding;
 }
 
+/* wraps only main content of overlay player, not monitors */
 .stage-overlay-content {
     outline: none;
     margin: auto;
-    border: 3px solid rgb(126, 133, 151);
+    border: $stage-full-screen-border-width solid rgb(126, 133, 151);
     padding: 0;
-    margin-top: 3px;
-    margin-bottom: 3px;
     border-radius: $space;
 
     overflow: hidden;
@@ -76,6 +78,21 @@
     position: absolute;
 }
 
+/* adjust monitors when stage is standard size:
+shift them down and right to compensate for the stage's border */
+.stage-wrapper .monitor-wrapper {
+    top: $stage-standard-border-width;
+    left: $stage-standard-border-width;
+}
+
+/* adjust monitors when stage is full screen:
+.stage-wrapper-overlay uses position: fixed instead of relative, so we need
+to adjust for the border using a different method */
+.stage-wrapper-overlay .monitor-wrapper {
+    padding-top: calc($stage-full-screen-stage-padding + $stage-full-screen-border-width);
+    padding-bottom: calc($stage-full-screen-stage-padding + $stage-full-screen-border-width);
+}
+
 .monitor-wrapper, .color-picker-wrapper, .queston-wrapper {
     position: absolute;
     top: 0;
diff --git a/src/components/webgl-modal/webgl-modal.css b/src/components/webgl-modal/webgl-modal.css
index f1b6ff6efee57e7a40a5ad1a1ebc3325e8167dcd..10eed71f1d4667f7ea166508cd3b3a7cbbf8502c 100644
--- a/src/components/webgl-modal/webgl-modal.css
+++ b/src/components/webgl-modal/webgl-modal.css
@@ -34,6 +34,10 @@
     background-size: cover;
 }
 
+[dir="rtl"] .illustration {
+    transform: scaleX(-1);
+}
+
 .body {
     background: $ui-white;
     padding: 1.5rem 2.25rem;
diff --git a/src/components/webgl-modal/webgl-modal.jsx b/src/components/webgl-modal/webgl-modal.jsx
index f0c3c6c27529eb3ac8ab782131898698634459b7..faf5ac55171925ca5ba40b2869272f59f52858e2 100644
--- a/src/components/webgl-modal/webgl-modal.jsx
+++ b/src/components/webgl-modal/webgl-modal.jsx
@@ -22,76 +22,79 @@ const WebGlModal = ({intl, ...props}) => (
         overlayClassName={styles.modalOverlay}
         onRequestClose={props.onBack}
     >
-        <Box className={styles.illustration} />
+        <div dir={props.isRtl ? 'rtl' : 'ltr'}>
+            <Box className={styles.illustration} />
 
-        <Box className={styles.body}>
-            <h2>
-                <FormattedMessage {...messages.label} />
-            </h2>
-            <p>
-                { /* eslint-disable max-len */ }
-                <FormattedMessage
-                    defaultMessage="Unfortunately it looks like your browser or computer {webGlLink}. This technology is needed for Scratch 3.0 to run."
-                    description="WebGL missing message"
-                    id="gui.webglModal.description"
-                    values={{
-                        webGlLink: (
-                            <a
-                                className={styles.faqLink}
-                                href="https://en.wikipedia.org/wiki/WebGL#Support"
-                            >
-                                <FormattedMessage
-                                    defaultMessage="does not support WebGL"
-                                    description="link part of your browser does not support WebGL message"
-                                    id="gui.webglModal.webgllink"
-                                />
-                            </a>
-                        )
-                    }}
-                />
-                { /* eslint-enable max-len */ }
-            </p>
-
-            <Box className={styles.buttonRow}>
-                <button
-                    className={styles.backButton}
-                    onClick={props.onBack}
-                >
+            <Box className={styles.body}>
+                <h2>
+                    <FormattedMessage {...messages.label} />
+                </h2>
+                <p>
+                    { /* eslint-disable max-len */ }
                     <FormattedMessage
-                        defaultMessage="Back"
-                        description="Label for button go back when browser is unsupported"
-                        id="gui.webglModal.back"
+                        defaultMessage="Unfortunately it looks like your browser or computer {webGlLink}. This technology is needed for Scratch 3.0 to run."
+                        description="WebGL missing message"
+                        id="gui.webglModal.description"
+                        values={{
+                            webGlLink: (
+                                <a
+                                    className={styles.faqLink}
+                                    href="https://en.wikipedia.org/wiki/WebGL#Support"
+                                >
+                                    <FormattedMessage
+                                        defaultMessage="does not support WebGL"
+                                        description="link part of your browser does not support WebGL message"
+                                        id="gui.webglModal.webgllink"
+                                    />
+                                </a>
+                            )
+                        }}
                     />
-                </button>
+                    { /* eslint-enable max-len */ }
+                </p>
+
+                <Box className={styles.buttonRow}>
+                    <button
+                        className={styles.backButton}
+                        onClick={props.onBack}
+                    >
+                        <FormattedMessage
+                            defaultMessage="Back"
+                            description="Label for button go back when browser is unsupported"
+                            id="gui.webglModal.back"
+                        />
+                    </button>
 
+                </Box>
+                <div className={styles.faqLinkText}>
+                    <FormattedMessage
+                        defaultMessage="To learn more, go to the {previewFaqLink}."
+                        description="Scratch 3.0 FAQ description"
+                        id="gui.webglModal.previewfaq"
+                        values={{
+                            previewFaqLink: (
+                                <a
+                                    className={styles.faqLink}
+                                    href="//scratch.mit.edu/3faq"
+                                >
+                                    <FormattedMessage
+                                        defaultMessage="FAQ"
+                                        description="link to Scratch 3.0 FAQ page"
+                                        id="gui.webglModal.previewfaqlinktext"
+                                    />
+                                </a>
+                            )
+                        }}
+                    />
+                </div>
             </Box>
-            <div className={styles.faqLinkText}>
-                <FormattedMessage
-                    defaultMessage="To learn more, go to the {previewFaqLink}."
-                    description="Scratch 3.0 FAQ description"
-                    id="gui.webglModal.previewfaq"
-                    values={{
-                        previewFaqLink: (
-                            <a
-                                className={styles.faqLink}
-                                href="//scratch.mit.edu/3faq"
-                            >
-                                <FormattedMessage
-                                    defaultMessage="FAQ"
-                                    description="link to Scratch 3.0 FAQ page"
-                                    id="gui.webglModal.previewfaqlinktext"
-                                />
-                            </a>
-                        )
-                    }}
-                />
-            </div>
-        </Box>
+        </div>
     </ReactModal>
 );
 
 WebGlModal.propTypes = {
     intl: intlShape.isRequired,
+    isRtl: PropTypes.bool,
     onBack: PropTypes.func.isRequired
 };
 
diff --git a/src/containers/backpack.jsx b/src/containers/backpack.jsx
index e7303c145fb969ff5e226f68ff51b768f3b2da5b..e90fe1dff10b4d767596e7509b7ac1cb4d5106cb 100644
--- a/src/containers/backpack.jsx
+++ b/src/containers/backpack.jsx
@@ -27,6 +27,7 @@ class Backpack extends React.Component {
             'handleDrop',
             'handleToggle',
             'handleDelete',
+            'getBackpackAssetURL',
             'refreshContents'
         ]);
         this.state = {
@@ -44,11 +45,14 @@ class Backpack extends React.Component {
         if (props.host && !storage._hasAddedBackpackSource) {
             storage.addWebSource(
                 [storage.AssetType.ImageVector, storage.AssetType.ImageBitmap, storage.AssetType.Sound],
-                asset => `${props.host}/${asset.assetId}.${asset.dataFormat}`
+                this.getBackpackAssetURL
             );
             storage._hasAddedBackpackSource = true;
         }
     }
+    getBackpackAssetURL (asset) {
+        return `${this.props.host}/${asset.assetId}.${asset.dataFormat}`;
+    }
     handleToggle () {
         const newState = !this.state.expanded;
         this.setState({expanded: newState, offset: 0});
@@ -132,8 +136,8 @@ const getTokenAndUsername = state => {
     // Look for the session state provided by scratch-www
     if (state.session && state.session.session) {
         return {
-            token: state.session.session.token,
-            username: state.session.session.username
+            token: state.session.session.user.token,
+            username: state.session.session.user.username
         };
     }
     // Otherwise try to pull testing params out of the URL, or return nulls
diff --git a/src/containers/cards.jsx b/src/containers/cards.jsx
index 5dc081f7b96f883cdbe07cd05ec1d23ce6c2f76c..2e4b92e5af01252ec88d1ae1c47dbb7a3c219663 100644
--- a/src/containers/cards.jsx
+++ b/src/containers/cards.jsx
@@ -23,6 +23,7 @@ const mapStateToProps = state => ({
     step: state.scratchGui.cards.step,
     x: state.scratchGui.cards.x,
     y: state.scratchGui.cards.y,
+    isRtl: state.locales.isRtl,
     dragging: state.scratchGui.cards.dragging
 });
 
diff --git a/src/containers/error-boundary.jsx b/src/containers/error-boundary.jsx
index 52e522d5aaea290d3775515d18400023e4f15f13..fbb15f3b998d1deb80cb309146c1dfa48d88a593 100644
--- a/src/containers/error-boundary.jsx
+++ b/src/containers/error-boundary.jsx
@@ -1,5 +1,6 @@
 import React from 'react';
 import PropTypes from 'prop-types';
+import {connect} from 'react-redux';
 import bowser from 'bowser';
 import BrowserModalComponent from '../components/browser-modal/browser-modal.jsx';
 import CrashMessageComponent from '../components/crash-message/crash-message.jsx';
@@ -57,7 +58,10 @@ class ErrorBoundary extends React.Component {
             if (supportedBrowser()) {
                 return <CrashMessageComponent onReload={this.handleReload} />;
             }
-            return <BrowserModalComponent onBack={this.handleBack} />;
+            return (<BrowserModalComponent
+                isRtl={this.props.isRtl}
+                onBack={this.handleBack}
+            />);
         }
         return this.props.children;
     }
@@ -65,7 +69,15 @@ class ErrorBoundary extends React.Component {
 
 ErrorBoundary.propTypes = {
     action: PropTypes.string.isRequired, // Used for defining tracking action
-    children: PropTypes.node
+    children: PropTypes.node,
+    isRtl: PropTypes.bool
 };
 
-export default ErrorBoundary;
+const mapStateToProps = state => ({
+    isRtl: state.locales.isRtl
+});
+
+// no-op function to prevent dispatch prop being passed to component
+const mapDispatchToProps = () => {};
+
+export default connect(mapStateToProps, mapDispatchToProps)(ErrorBoundary);
diff --git a/src/containers/gui.jsx b/src/containers/gui.jsx
index ffa099496fc5c3d10587fdb66f3f547e6622f127..cdcb87c8985b31498c8e5eee61c54067225901fe 100644
--- a/src/containers/gui.jsx
+++ b/src/containers/gui.jsx
@@ -72,10 +72,12 @@ class GUI extends React.Component {
                 `Failed to load project from server [id=${window.location.hash}]: ${this.state.errorMessage}`);
         }
         const {
+            assetHost, // eslint-disable-line no-unused-vars
             children,
             fetchingProject,
             loadingStateVisible,
             projectData, // eslint-disable-line no-unused-vars
+            projectHost, // eslint-disable-line no-unused-vars
             vm,
             ...componentProps
         } = this.props;
@@ -92,7 +94,7 @@ class GUI extends React.Component {
 }
 
 GUI.propTypes = {
-    ...GUIComponent.propTypes,
+    children: PropTypes.node,
     fetchingProject: PropTypes.bool,
     importInfoVisible: PropTypes.bool,
     loadingStateVisible: PropTypes.bool,
@@ -102,8 +104,6 @@ GUI.propTypes = {
     vm: PropTypes.instanceOf(VM)
 };
 
-GUI.defaultProps = GUIComponent.defaultProps;
-
 const mapStateToProps = state => ({
     activeTabIndex: state.scratchGui.editorTab.activeTabIndex,
     backdropLibraryVisible: state.scratchGui.modals.backdropLibrary,
diff --git a/src/containers/import-modal.jsx b/src/containers/import-modal.jsx
index 0731098f1563c2fda54258c807babc0872ee4638..1c75929cf560a17b6d81c1e59457c7ce99371dc5 100644
--- a/src/containers/import-modal.jsx
+++ b/src/containers/import-modal.jsx
@@ -73,6 +73,7 @@ class ImportModal extends React.Component {
                 errorMessage={this.state.errorMessage}
                 hasValidationError={this.state.hasValidationError}
                 inputValue={this.state.inputValue}
+                isRtl={this.props.isRtl}
                 placeholder="scratch.mit.edu/projects/123456789"
                 onCancel={this.handleCancel}
                 onChange={this.handleChange}
@@ -85,12 +86,15 @@ class ImportModal extends React.Component {
 }
 
 ImportModal.propTypes = {
+    isRtl: PropTypes.bool,
     onBack: PropTypes.func.isRequired,
     onCancel: PropTypes.func.isRequired,
     onViewProject: PropTypes.func
 };
 
-const mapStateToProps = () => ({});
+const mapStateToProps = state => ({
+    isRtl: state.locales.isRtl
+});
 
 const mapDispatchToProps = dispatch => ({
     onBack: () => {
diff --git a/src/containers/preview-modal.jsx b/src/containers/preview-modal.jsx
index a53f398ee70d19b33504e7267fff104fa291986f..7145cfa6acbb3170a85a4bc1c9d44673731fc64e 100644
--- a/src/containers/preview-modal.jsx
+++ b/src/containers/preview-modal.jsx
@@ -39,12 +39,12 @@ class PreviewModal extends React.Component {
 
         // otherwise, show the intro modal
         return (<PreviewModalComponent
+            isRtl={this.props.isRtl}
             previewing={this.state.previewing}
             onCancel={this.handleCancel}
             onTryIt={this.handleTryIt}
             onViewProject={this.handleViewProject}
         />);
-        
     }
     handleTryIt () {
         this.setState({previewing: true});
@@ -62,6 +62,7 @@ class PreviewModal extends React.Component {
         return (supportedBrowser() ?
             this.introIfShown() :
             <BrowserModalComponent
+                isRtl={this.props.isRtl}
                 onBack={this.handleCancel}
             />
         );
@@ -70,11 +71,14 @@ class PreviewModal extends React.Component {
 
 PreviewModal.propTypes = {
     hideIntro: PropTypes.bool,
+    isRtl: PropTypes.bool,
     onTryIt: PropTypes.func,
     onViewProject: PropTypes.func
 };
 
-const mapStateToProps = () => ({});
+const mapStateToProps = state => ({
+    isRtl: state.locales.isRtl
+});
 
 const mapDispatchToProps = dispatch => ({
     onTryIt: () => {
diff --git a/src/containers/sprite-selector-item.jsx b/src/containers/sprite-selector-item.jsx
index 785f9d08f49359bc6a6c60f89262b5a177d58f36..a0197ad6dd9ecfc09e61c5a783878395eef7e509 100644
--- a/src/containers/sprite-selector-item.jsx
+++ b/src/containers/sprite-selector-item.jsx
@@ -2,6 +2,7 @@ import bindAll from 'lodash.bindall';
 import PropTypes from 'prop-types';
 import React from 'react';
 import {connect} from 'react-redux';
+import {defineMessages, injectIntl, intlShape} from 'react-intl';
 
 import {setHoveredSprite} from '../reducers/hovered-target';
 import {updateAssetDrag} from '../reducers/asset-drag';
@@ -11,6 +12,14 @@ import SpriteSelectorItemComponent from '../components/sprite-selector-item/spri
 
 const dragThreshold = 3; // Same as the block drag threshold
 
+const messages = defineMessages({
+    deleteSpriteConfirmation: {
+        defaultMessage: 'Are you sure you want to delete this?',
+        description: 'Confirmation for deleting sprites',
+        id: 'gui.spriteSelectorItem.deleteSpriteConfirmation'
+    }
+});
+
 class SpriteSelectorItem extends React.Component {
     constructor (props) {
         super(props);
@@ -75,9 +84,8 @@ class SpriteSelectorItem extends React.Component {
     }
     handleDelete (e) {
         e.stopPropagation(); // To prevent from bubbling back to handleClick
-        // @todo add i18n here
         // eslint-disable-next-line no-alert
-        if (window.confirm('Are you sure you want to delete this?')) {
+        if (window.confirm(this.props.intl.formatMessage(messages.deleteSpriteConfirmation))) {
             this.props.onDeleteButtonClick(this.props.id);
         }
     }
@@ -136,6 +144,7 @@ SpriteSelectorItem.propTypes = {
     dragType: PropTypes.string,
     id: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
     index: PropTypes.number,
+    intl: intlShape.isRequired,
     name: PropTypes.string,
     onClick: PropTypes.func,
     onDeleteButtonClick: PropTypes.func,
@@ -159,7 +168,8 @@ const mapDispatchToProps = dispatch => ({
     onDrag: data => dispatch(updateAssetDrag(data))
 });
 
+
 export default connect(
     mapStateToProps,
     mapDispatchToProps
-)(SpriteSelectorItem);
+)(injectIntl(SpriteSelectorItem));
diff --git a/src/containers/webgl-modal.jsx b/src/containers/webgl-modal.jsx
index 02e43bf01db100c611003e517d015e9f45c6291c..d6633f30394ae74a6c2845547d165b4c9df116ee 100644
--- a/src/containers/webgl-modal.jsx
+++ b/src/containers/webgl-modal.jsx
@@ -1,4 +1,5 @@
 import React from 'react';
+import PropTypes from 'prop-types';
 
 import WebGlModalComponent from '../components/webgl-modal/webgl-modal.jsx';
 
@@ -9,10 +10,15 @@ class WebGlModal extends React.Component {
     render () {
         return (
             <WebGlModalComponent
+                isRtl={this.props.isRtl}
                 onBack={this.handleCancel}
             />
         );
     }
 }
 
+WebGlModal.propTypes = {
+    isRtl: PropTypes.bool
+};
+
 export default WebGlModal;
diff --git a/src/css/units.css b/src/css/units.css
index ef34280983f2c54b1fa67c9ecf50e00b141396dc..59d9a2e7cdd244f7bb3beaf8482adce58a6a3380 100644
--- a/src/css/units.css
+++ b/src/css/units.css
@@ -1,3 +1,6 @@
+/* make sure to keep these in sync with other constants,
+e.g. STAGE_DIMENSION_DEFAULTS in lib/screen-utils.js */
+
 $space: 0.5rem;
 
 $sprites-per-row: 5;
@@ -9,6 +12,10 @@ $stage-menu-height: 2.75rem;
 $library-header-height: 3.125rem;
 $library-filter-bar-height: 2.5rem;
 
+$stage-standard-border-width: 0.0625rem;
+$stage-full-screen-border-width: 0.1875rem;
+$stage-full-screen-stage-padding: 0.1875rem;
+
 $form-radius: calc($space / 2);
 
 /* layout contants from `layout-constants.js` */
diff --git a/src/lib/backpack-api.js b/src/lib/backpack-api.js
index f0c51f14040ced7823c226521dd792b4cf639f65..9453f197709fee3e1b06dbcb2c98d90f50ab1e49 100644
--- a/src/lib/backpack-api.js
+++ b/src/lib/backpack-api.js
@@ -12,7 +12,7 @@ const getBackpackContents = ({
 }) => new Promise((resolve, reject) => {
     xhr({
         method: 'GET',
-        uri: `${host}${username}?limit=${limit}&offset=${offset}`,
+        uri: `${host}/${username}?limit=${limit}&offset=${offset}`,
         headers: {'x-token': token},
         json: true
     }, (error, response) => {
@@ -43,7 +43,7 @@ const saveBackpackObject = ({
 }) => new Promise((resolve, reject) => {
     xhr({
         method: 'POST',
-        uri: `${host}${username}`,
+        uri: `${host}/${username}`,
         headers: {'x-token': token},
         json: {type, mime, name, body, thumbnail}
     }, (error, response) => {
@@ -62,7 +62,7 @@ const deleteBackpackObject = ({
 }) => new Promise((resolve, reject) => {
     xhr({
         method: 'DELETE',
-        uri: `${host}${username}/${id}`,
+        uri: `${host}/${username}/${id}`,
         headers: {'x-token': token}
     }, (error, response) => {
         if (error || response.statusCode !== 200) {
diff --git a/src/lib/project-loader-hoc.jsx b/src/lib/project-loader-hoc.jsx
index cb8501af42ab532cb153a6a68efbbec185adf682..22a1aa5d1ce4c9666b6b87acde4084285053b62c 100644
--- a/src/lib/project-loader-hoc.jsx
+++ b/src/lib/project-loader-hoc.jsx
@@ -19,6 +19,9 @@ const ProjectLoaderHOC = function (WrappedComponent) {
                 projectData: null,
                 fetchingProject: false
             };
+            storage.setProjectHost(props.projectHost);
+            storage.setAssetHost(props.assetHost);
+
         }
         componentDidMount () {
             if (this.props.projectId || this.props.projectId === 0) {
@@ -26,6 +29,12 @@ const ProjectLoaderHOC = function (WrappedComponent) {
             }
         }
         componentWillUpdate (nextProps) {
+            if (this.props.projectHost !== nextProps.projectHost) {
+                storage.setProjectHost(nextProps.projectHost);
+            }
+            if (this.props.assetHost !== nextProps.assetHost) {
+                storage.setAssetHost(nextProps.assetHost);
+            }
             if (this.props.projectId !== nextProps.projectId) {
                 this.setState({fetchingProject: true}, () => {
                     this.updateProject(nextProps.projectId);
@@ -67,9 +76,13 @@ const ProjectLoaderHOC = function (WrappedComponent) {
         }
     }
     ProjectLoaderComponent.propTypes = {
+        assetHost: PropTypes.string,
+        projectHost: PropTypes.string,
         projectId: PropTypes.oneOfType([PropTypes.string, PropTypes.number])
     };
     ProjectLoaderComponent.defaultProps = {
+        assetHost: 'https://assets.scratch.mit.edu',
+        projectHost: 'https://projects.scratch.mit.edu',
         projectId: 0
     };
 
diff --git a/src/lib/screen-utils.js b/src/lib/screen-utils.js
index e233993e26155a8f493363c7a6424422d2e1e054..afef90d84c845119d881c11eef4e27c4f3a0b2ae 100644
--- a/src/lib/screen-utils.js
+++ b/src/lib/screen-utils.js
@@ -10,8 +10,13 @@ import layout, {STAGE_DISPLAY_SCALES, STAGE_SIZE_MODES, STAGE_DISPLAY_SIZES} fro
  */
 
 const STAGE_DIMENSION_DEFAULTS = {
-    spacingBorderAdjustment: 9,
-    menuHeightAdjustment: 40
+    // referencing css/units.css,
+    // spacingBorderAdjustment = 2 * $full-screen-top-bottom-margin +
+    //   2 * $full-screen-border-width
+    fullScreenSpacingBorderAdjustment: 12,
+    // referencing css/units.css,
+    // menuHeightAdjustment = $stage-menu-height
+    menuHeightAdjustment: 44
 };
 
 /**
@@ -48,7 +53,7 @@ const getStageDimensions = (stageSize, isFullScreen) => {
     if (isFullScreen) {
         stageDimensions.height = window.innerHeight -
             STAGE_DIMENSION_DEFAULTS.menuHeightAdjustment -
-            STAGE_DIMENSION_DEFAULTS.spacingBorderAdjustment;
+            STAGE_DIMENSION_DEFAULTS.fullScreenSpacingBorderAdjustment;
 
         stageDimensions.width = stageDimensions.height + (stageDimensions.height / 3);
 
diff --git a/src/lib/storage.js b/src/lib/storage.js
index be7bcef1e6df21e80093f7e713554bcf38364547..9c49d81703f96aa67e6509013d91df0f0231e911 100644
--- a/src/lib/storage.js
+++ b/src/lib/storage.js
@@ -2,9 +2,6 @@ import ScratchStorage from 'scratch-storage';
 
 import defaultProjectAssets from './default-project';
 
-const PROJECT_SERVER = 'https://projects.scratch.mit.edu';
-const ASSET_SERVER = 'https://cdn.assets.scratch.mit.edu';
-
 /**
  * Wrapper for ScratchStorage which adds default web sources.
  * @todo make this more configurable
@@ -12,29 +9,36 @@ const ASSET_SERVER = 'https://cdn.assets.scratch.mit.edu';
 class Storage extends ScratchStorage {
     constructor () {
         super();
+        defaultProjectAssets.forEach(asset => this.cache(
+            this.AssetType[asset.assetType],
+            this.DataFormat[asset.dataFormat],
+            asset.data,
+            asset.id
+        ));
         this.addWebSource(
             [this.AssetType.Project],
-            projectAsset => {
-                const [projectId, revision] = projectAsset.assetId.split('.');
-                return revision ?
-                    `${PROJECT_SERVER}/internalapi/project/${projectId}/get/${revision}` :
-                    `${PROJECT_SERVER}/internalapi/project/${projectId}/get/`;
-            }
+            this.getProjectURL.bind(this)
         );
         this.addWebSource(
             [this.AssetType.ImageVector, this.AssetType.ImageBitmap, this.AssetType.Sound],
-            asset => `${ASSET_SERVER}/internalapi/asset/${asset.assetId}.${asset.dataFormat}/get/`
+            this.getAssetURL.bind(this)
         );
         this.addWebSource(
             [this.AssetType.Sound],
             asset => `static/extension-assets/scratch3_music/${asset.assetId}.${asset.dataFormat}`
         );
-        defaultProjectAssets.forEach(asset => this.cache(
-            this.AssetType[asset.assetType],
-            this.DataFormat[asset.dataFormat],
-            asset.data,
-            asset.id
-        ));
+    }
+    setProjectHost (projectHost) {
+        this.projectHost = projectHost;
+    }
+    getProjectURL (projectAsset) {
+        return `${this.projectHost}/internalapi/project/${projectAsset.assetId}/get/`;
+    }
+    setAssetHost (assetHost) {
+        this.assetHost = assetHost;
+    }
+    getAssetURL (asset) {
+        return `${this.assetHost}/internalapi/asset/${asset.assetId}.${asset.dataFormat}/get/`;
     }
 }
 
diff --git a/src/reducers/cards.js b/src/reducers/cards.js
index ba1c50d8e28af9d3e7a3c234417ccdc09e0b3f07..37319cbea06d82c0e2ac65e97d7a211eb5e18db9 100644
--- a/src/reducers/cards.js
+++ b/src/reducers/cards.js
@@ -16,8 +16,8 @@ const initialState = {
     content: decks,
     activeDeckId: null,
     step: 0,
-    x: 292,
-    y: 365,
+    x: 0,
+    y: 0,
     dragging: false
 };
 
diff --git a/test/integration/backpack.test.js b/test/integration/backpack.test.js
index 9694e67ba2cc4b3aca21d96a2c0145285ec0405b..cfc78613ccdb6ab4fa71d029842b7df26543b03c 100644
--- a/test/integration/backpack.test.js
+++ b/test/integration/backpack.test.js
@@ -24,7 +24,7 @@ describe('Working with the how-to library', () => {
 
     test('Backpack is "Coming Soon" without backpack host param', async () => {
         await loadUri(uri);
-        await clickXpath('//button[@title="tryit"]');
+        await clickXpath('//button[@title="Try It"]');
         // Check that the backpack header is visible and wrapped in a coming soon tooltip
         await clickText('Backpack', '*[@data-for="backpack-tooltip"]');
         const logs = await getLogs();
@@ -33,7 +33,7 @@ describe('Working with the how-to library', () => {
 
     test('Backpack can be expanded with backpack host param', async () => {
         await loadUri(`${uri}?backpack_host=some-value`);
-        await clickXpath('//button[@title="tryit"]');
+        await clickXpath('//button[@title="Try It"]');
 
         // Try activating the backpack from the costumes tab to make sure it isn't pushed off
         await clickText('Costumes');
diff --git a/test/integration/blocks.test.js b/test/integration/blocks.test.js
index e7fcf0b827f94f5f8baedb3237a4a4728e6eaa20..83b72620bcc04dad457f157071a54016f74381aa 100644
--- a/test/integration/blocks.test.js
+++ b/test/integration/blocks.test.js
@@ -29,7 +29,7 @@ describe('Working with the blocks', () => {
 
     test('Blocks report when clicked in the toolbox', async () => {
         await loadUri(uri);
-        await clickXpath('//button[@title="tryit"]');
+        await clickXpath('//button[@title="Try It"]');
         await clickText('Code');
         await clickText('Operators', scope.blocksTab);
         await new Promise(resolve => setTimeout(resolve, 1000)); // Wait for scroll animation
@@ -41,7 +41,7 @@ describe('Working with the blocks', () => {
 
     test('Switching sprites updates the block menus', async () => {
         await loadUri(uri);
-        await clickXpath('//button[@title="tryit"]');
+        await clickXpath('//button[@title="Try It"]');
         await clickText('Sound', scope.blocksTab);
         await new Promise(resolve => setTimeout(resolve, 1000)); // Wait for scroll animation
         // "Meow" sound block should be visible
@@ -58,7 +58,7 @@ describe('Working with the blocks', () => {
 
     test('Creating variables', async () => {
         await loadUri(uri);
-        await clickXpath('//button[@title="tryit"]');
+        await clickXpath('//button[@title="Try It"]');
         await clickText('Code');
         await clickText('Variables', scope.blocksTab);
         await new Promise(resolve => setTimeout(resolve, 1000)); // Wait for scroll animation
@@ -92,7 +92,7 @@ describe('Working with the blocks', () => {
 
     test('Creating a list', async () => {
         await loadUri(uri);
-        await clickXpath('//button[@title="tryit"]');
+        await clickXpath('//button[@title="Try It"]');
         await clickText('Code');
         await clickText('Variables', scope.blocksTab);
         await new Promise(resolve => setTimeout(resolve, 1000)); // Wait for scroll animation
@@ -127,7 +127,7 @@ describe('Working with the blocks', () => {
 
     test('Custom procedures', async () => {
         await loadUri(uri);
-        await clickXpath('//button[@title="tryit"]');
+        await clickXpath('//button[@title="Try It"]');
         await clickText('My Blocks');
         await new Promise(resolve => setTimeout(resolve, 1000)); // Wait for scroll animation
         await clickText('Make a Block');
@@ -146,7 +146,7 @@ describe('Working with the blocks', () => {
 
     test('Adding an extension', async () => {
         await loadUri(uri);
-        await clickXpath('//button[@title="tryit"]');
+        await clickXpath('//button[@title="Try It"]');
         await clickXpath('//button[@title="Add Extension"]');
 
         await clickText('Pen');
diff --git a/test/integration/costumes.test.js b/test/integration/costumes.test.js
index 23790842d8d84dc8928a05fbdeda5db361de1bc0..7aa3b969fc2e152cd461c1c649f392e5fc00dfc9 100644
--- a/test/integration/costumes.test.js
+++ b/test/integration/costumes.test.js
@@ -27,7 +27,7 @@ describe('Working with costumes', () => {
 
     test('Adding a costume through the library', async () => {
         await loadUri(uri);
-        await clickXpath('//button[@title="tryit"]');
+        await clickXpath('//button[@title="Try It"]');
         await clickText('Costumes');
         await clickXpath('//button[@aria-label="Choose a Costume"]');
         const el = await findByXpath("//input[@placeholder='Search']");
@@ -40,7 +40,7 @@ describe('Working with costumes', () => {
 
     test('Adding a costume by surprise button', async () => {
         await loadUri(uri);
-        await clickXpath('//button[@title="tryit"]');
+        await clickXpath('//button[@title="Try It"]');
         await clickText('Costumes');
         const el = await findByXpath('//button[@aria-label="Choose a Costume"]');
         await driver.actions().mouseMove(el)
@@ -53,7 +53,7 @@ describe('Working with costumes', () => {
 
     test('Adding a costume by paint button', async () => {
         await loadUri(uri);
-        await clickXpath('//button[@title="tryit"]');
+        await clickXpath('//button[@title="Try It"]');
         await clickText('Costumes');
         const el = await findByXpath('//button[@aria-label="Choose a Costume"]');
         await driver.actions().mouseMove(el)
@@ -66,7 +66,7 @@ describe('Working with costumes', () => {
 
     test('Duplicating a costume', async () => {
         await loadUri(uri);
-        await clickXpath('//button[@title="tryit"]');
+        await clickXpath('//button[@title="Try It"]');
         await clickText('Costumes');
 
         await rightClickText('costume1', scope.costumesTab);
@@ -82,7 +82,7 @@ describe('Working with costumes', () => {
 
     test('Adding a backdrop', async () => {
         await loadUri(uri);
-        await clickXpath('//button[@title="tryit"]');
+        await clickXpath('//button[@title="Try It"]');
         await clickXpath('//button[@aria-label="Choose a Backdrop"]');
         const el = await findByXpath("//input[@placeholder='Search']");
         await el.sendKeys('blue');
@@ -93,7 +93,7 @@ describe('Working with costumes', () => {
 
     test('Converting bitmap/vector in paint editor', async () => {
         await loadUri(uri);
-        await clickXpath('//button[@title="tryit"]');
+        await clickXpath('//button[@title="Try It"]');
         await clickText('Costumes');
 
         // Convert the first costume to bitmap.
@@ -117,7 +117,7 @@ describe('Working with costumes', () => {
 
     test('Undo/redo in the paint editor', async () => {
         await loadUri(uri);
-        await clickXpath('//button[@title="tryit"]');
+        await clickXpath('//button[@title="Try It"]');
         await clickText('Costumes');
         await clickText('costume1', scope.costumesTab);
         await clickText('Convert to Bitmap', scope.costumesTab);
diff --git a/test/integration/how-tos.test.js b/test/integration/how-tos.test.js
index 5b9b76e4b74cb0163066010a3bd91da03a8992b3..dcdccb4994706fec851695f136e4e51c3f0567eb 100644
--- a/test/integration/how-tos.test.js
+++ b/test/integration/how-tos.test.js
@@ -25,7 +25,7 @@ describe('Working with the how-to library', () => {
 
     test('Choosing a how-to', async () => {
         await loadUri(uri);
-        await clickXpath('//button[@title="tryit"]');
+        await clickXpath('//button[@title="Try It"]');
         await clickText('Costumes');
         await clickXpath('//*[@aria-label="Tutorials"]');
         await clickText('Getting Started'); // Modal should close
diff --git a/test/integration/localization.test.js b/test/integration/localization.test.js
index 101d3ce8613bd27e89b4e69ddfdfdbe483cfae6f..abd8ee4676db49ad620e6aae480aff6cefbea363 100644
--- a/test/integration/localization.test.js
+++ b/test/integration/localization.test.js
@@ -24,7 +24,7 @@ describe('Localization', () => {
 
     test('Localization', async () => {
         await loadUri(uri);
-        await clickXpath('//button[@title="tryit"]');
+        await clickXpath('//button[@title="Try It"]');
         await clickXpath('//*[@aria-label="language selector"]');
         await clickText('English');
         await clickText('Deutsch');
diff --git a/test/integration/project-loading.test.js b/test/integration/project-loading.test.js
index cb0477ec9317a9fbb2fc0ca91c3e564b1b525ad2..62199cdcbb0cf2885b969f00a082d9c54b4245b2 100644
--- a/test/integration/project-loading.test.js
+++ b/test/integration/project-loading.test.js
@@ -38,7 +38,7 @@ describe('Loading scratch gui', () => {
             const el = await findByXpath("//input[@placeholder='scratch.mit.edu/projects/123456789']");
             const projectId = '96708228';
             await el.sendKeys(`scratch.mit.edu/projects/${projectId}`);
-            await clickXpath('//button[@title="viewproject"]');
+            await clickXpath('//button[@title="View Project"]');
             await new Promise(resolve => setTimeout(resolve, 2000));
             await clickXpath('//img[@title="Go"]');
             await new Promise(resolve => setTimeout(resolve, 2000));
@@ -52,11 +52,11 @@ describe('Loading scratch gui', () => {
             await clickText('View 2.0 Project');
             let el = await findByXpath("//input[@placeholder='scratch.mit.edu/projects/123456789']");
             await el.sendKeys('thisisnotaurl');
-            await clickXpath('//button[@title="viewproject"]');
+            await clickXpath('//button[@title="View Project"]');
             el = await findByXpath("//input[@placeholder='scratch.mit.edu/projects/123456789']");
             await el.clear();
             await el.sendKeys('scratch.mit.edu/projects/96708228');
-            await clickXpath('//button[@title="viewproject"]');
+            await clickXpath('//button[@title="View Project"]');
             await new Promise(resolve => setTimeout(resolve, 2000));
             await clickXpath('//img[@title="Go"]');
             await new Promise(resolve => setTimeout(resolve, 2000));
@@ -71,7 +71,7 @@ describe('Loading scratch gui', () => {
 
             const projectId = '96708228';
             await loadUri(`${uri}#${projectId}`);
-            await clickXpath('//button[@title="tryit"]');
+            await clickXpath('//button[@title="Try It"]');
             await new Promise(resolve => setTimeout(resolve, 2000));
             await clickXpath('//img[@title="Go"]');
             await new Promise(resolve => setTimeout(resolve, 2000));
@@ -93,7 +93,7 @@ describe('Loading scratch gui', () => {
                 .setSize(1920, 1080);
             const projectId = '96708228';
             await loadUri(`${uri}#${projectId}`);
-            await clickXpath('//button[@title="tryit"]');
+            await clickXpath('//button[@title="Try It"]');
             await new Promise(resolve => setTimeout(resolve, 2000));
             await clickXpath('//img[@title="Full Screen Control"]');
             await clickXpath('//img[@title="Go"]');
diff --git a/test/integration/sounds.test.js b/test/integration/sounds.test.js
index aa3790f9508c251438bec724f2f3f813fecaa440..7c306a5eee2c9c05c2d16d1c9ed8a1a489f5370c 100644
--- a/test/integration/sounds.test.js
+++ b/test/integration/sounds.test.js
@@ -27,7 +27,7 @@ describe('Working with sounds', () => {
 
     test('Adding a sound through the library', async () => {
         await loadUri(uri);
-        await clickXpath('//button[@title="tryit"]');
+        await clickXpath('//button[@title="Try It"]');
         await clickText('Sounds');
 
         // Delete the sound
@@ -65,7 +65,7 @@ describe('Working with sounds', () => {
 
     test('Adding a sound by surprise button', async () => {
         await loadUri(uri);
-        await clickXpath('//button[@title="tryit"]');
+        await clickXpath('//button[@title="Try It"]');
         await clickText('Sounds');
         const el = await findByXpath('//button[@aria-label="Choose a Sound"]');
         await driver.actions().mouseMove(el)
@@ -78,7 +78,7 @@ describe('Working with sounds', () => {
 
     test('Duplicating a sound', async () => {
         await loadUri(uri);
-        await clickXpath('//button[@title="tryit"]');
+        await clickXpath('//button[@title="Try It"]');
         await clickText('Sounds');
 
         await rightClickText('Meow', scope.soundsTab);
@@ -95,7 +95,7 @@ describe('Working with sounds', () => {
     // Regression test for gui issue #1320
     test('Switching sprites with different numbers of sounds', async () => {
         await loadUri(uri);
-        await clickXpath('//button[@title="tryit"]');
+        await clickXpath('//button[@title="Try It"]');
 
         // Add a sound so this sprite has 2 sounds.
         await clickText('Sounds');
diff --git a/test/integration/sprites.test.js b/test/integration/sprites.test.js
index 816d06a1ebf246eeb7aa67729412c64bd99c3694..41f2eec3ab4220e83fc08f8936c35328367f3da4 100644
--- a/test/integration/sprites.test.js
+++ b/test/integration/sprites.test.js
@@ -28,7 +28,7 @@ describe('Working with sprites', () => {
 
     test('Adding a sprite through the library', async () => {
         await loadUri(uri);
-        await clickXpath('//button[@title="tryit"]');
+        await clickXpath('//button[@title="Try It"]');
         await clickText('Costumes');
         await clickXpath('//button[@aria-label="Choose a Sprite"]');
         await clickText('Apple', scope.modal); // Closes modal
@@ -39,7 +39,7 @@ describe('Working with sprites', () => {
 
     test('Adding a sprite by surprise button', async () => {
         await loadUri(uri);
-        await clickXpath('//button[@title="tryit"]');
+        await clickXpath('//button[@title="Try It"]');
         const el = await findByXpath('//button[@aria-label="Choose a Sprite"]');
         await driver.actions().mouseMove(el)
             .perform();
@@ -51,7 +51,7 @@ describe('Working with sprites', () => {
 
     test('Deleting only sprite does not crash', async () => {
         await loadUri(uri);
-        await clickXpath('//button[@title="tryit"]');
+        await clickXpath('//button[@title="Try It"]');
         await new Promise(resolve => setTimeout(resolve, 1000)); // Wait for scroll animation
         await rightClickText('Sprite1', scope.spriteTile);
         await clickText('delete', scope.spriteTile);