about summary refs log tree commit diff
path: root/app/javascript
diff options
context:
space:
mode:
Diffstat (limited to 'app/javascript')
-rw-r--r--app/javascript/flavours/glitch/actions/notifications.js24
-rw-r--r--app/javascript/flavours/glitch/features/notifications/components/column_settings.js18
-rw-r--r--app/javascript/flavours/glitch/features/notifications/components/filter_bar.js93
-rw-r--r--app/javascript/flavours/glitch/features/notifications/containers/column_settings_container.js4
-rw-r--r--app/javascript/flavours/glitch/features/notifications/containers/filter_bar_container.js16
-rw-r--r--app/javascript/flavours/glitch/features/notifications/index.js23
-rw-r--r--app/javascript/flavours/glitch/reducers/notifications.js3
-rw-r--r--app/javascript/flavours/glitch/reducers/notifications.js.orig245
-rw-r--r--app/javascript/flavours/glitch/reducers/settings.js8
-rw-r--r--app/javascript/flavours/glitch/styles/components/accounts.scss7
-rw-r--r--app/javascript/flavours/glitch/styles/containers.scss6
-rw-r--r--app/javascript/flavours/glitch/styles/widgets.scss43
-rw-r--r--app/javascript/images/screen_federation.svg1
-rw-r--r--app/javascript/images/screen_hello.svg1
-rw-r--r--app/javascript/images/screen_interactions.svg1
-rw-r--r--app/javascript/mastodon/actions/notifications.js24
-rw-r--r--app/javascript/mastodon/actions/onboarding.js14
-rw-r--r--app/javascript/mastodon/components/column_header.js24
-rw-r--r--app/javascript/mastodon/containers/mastodon.js51
-rw-r--r--app/javascript/mastodon/features/account_gallery/index.js2
-rw-r--r--app/javascript/mastodon/features/compose/components/compose_form.js7
-rw-r--r--app/javascript/mastodon/features/compose/containers/compose_form_container.js1
-rw-r--r--app/javascript/mastodon/features/introduction/index.js196
-rw-r--r--app/javascript/mastodon/features/notifications/components/column_settings.js18
-rw-r--r--app/javascript/mastodon/features/notifications/components/filter_bar.js93
-rw-r--r--app/javascript/mastodon/features/notifications/containers/column_settings_container.js4
-rw-r--r--app/javascript/mastodon/features/notifications/containers/filter_bar_container.js16
-rw-r--r--app/javascript/mastodon/features/notifications/index.js23
-rw-r--r--app/javascript/mastodon/features/ui/components/modal_root.js2
-rw-r--r--app/javascript/mastodon/features/ui/components/onboarding_modal.js324
-rw-r--r--app/javascript/mastodon/features/ui/index.js6
-rw-r--r--app/javascript/mastodon/features/ui/util/async-components.js4
-rw-r--r--app/javascript/mastodon/locales/en.json8
-rw-r--r--app/javascript/mastodon/locales/pl.json8
-rw-r--r--app/javascript/mastodon/reducers/compose.js10
-rw-r--r--app/javascript/mastodon/reducers/notifications.js3
-rw-r--r--app/javascript/mastodon/reducers/settings.js8
-rw-r--r--app/javascript/styles/application.scss1
-rw-r--r--app/javascript/styles/mastodon/components.scss261
-rw-r--r--app/javascript/styles/mastodon/containers.scss6
-rw-r--r--app/javascript/styles/mastodon/introduction.scss153
-rw-r--r--app/javascript/styles/mastodon/widgets.scss43
42 files changed, 1152 insertions, 651 deletions
diff --git a/app/javascript/flavours/glitch/actions/notifications.js b/app/javascript/flavours/glitch/actions/notifications.js
index 0184d9c80..3cfad90a1 100644
--- a/app/javascript/flavours/glitch/actions/notifications.js
+++ b/app/javascript/flavours/glitch/actions/notifications.js
@@ -2,6 +2,7 @@ import api, { getLinks } from 'flavours/glitch/util/api';
 import IntlMessageFormat from 'intl-messageformat';
 import { fetchRelationships } from './accounts';
 import { defineMessages } from 'react-intl';
+import { List as ImmutableList } from 'immutable';
 import { unescapeHTML } from 'flavours/glitch/util/html';
 import { getFilters, regexFromFilters } from 'flavours/glitch/selectors';
 
@@ -22,6 +23,8 @@ export const NOTIFICATIONS_EXPAND_REQUEST = 'NOTIFICATIONS_EXPAND_REQUEST';
 export const NOTIFICATIONS_EXPAND_SUCCESS = 'NOTIFICATIONS_EXPAND_SUCCESS';
 export const NOTIFICATIONS_EXPAND_FAIL    = 'NOTIFICATIONS_EXPAND_FAIL';
 
+export const NOTIFICATIONS_FILTER_SET = 'NOTIFICATIONS_FILTER_SET';
+
 export const NOTIFICATIONS_CLEAR      = 'NOTIFICATIONS_CLEAR';
 export const NOTIFICATIONS_SCROLL_TOP = 'NOTIFICATIONS_SCROLL_TOP';
 
@@ -84,10 +87,16 @@ export function updateNotifications(notification, intlMessages, intlLocale) {
 const excludeTypesFromSettings = state => state.getIn(['settings', 'notifications', 'shows']).filter(enabled => !enabled).keySeq().toJS();
 
 
+const excludeTypesFromFilter = filter => {
+  const allTypes = ImmutableList(['follow', 'favourite', 'reblog', 'mention']);
+  return allTypes.filterNot(item => item === filter).toJS();
+};
+
 const noOp = () => {};
 
 export function expandNotifications({ maxId } = {}, done = noOp) {
   return (dispatch, getState) => {
+    const activeFilter = getState().getIn(['settings', 'notifications', 'quickFilter', 'active']);
     const notifications = getState().get('notifications');
     const isLoadingMore = !!maxId;
 
@@ -98,7 +107,9 @@ export function expandNotifications({ maxId } = {}, done = noOp) {
 
     const params = {
       max_id: maxId,
-      exclude_types: excludeTypesFromSettings(getState()),
+      exclude_types: activeFilter === 'all'
+        ? excludeTypesFromSettings(getState())
+        : excludeTypesFromFilter(activeFilter),
     };
 
     if (!maxId && notifications.get('items').size > 0) {
@@ -244,3 +255,14 @@ export function notificationsSetVisibility(visibility) {
     visibility: visibility,
   };
 };
+
+export function setFilter (filterType) {
+  return dispatch => {
+    dispatch({
+      type: NOTIFICATIONS_FILTER_SET,
+      path: ['notifications', 'quickFilter', 'active'],
+      value: filterType,
+    });
+    dispatch(expandNotifications());
+  };
+};
diff --git a/app/javascript/flavours/glitch/features/notifications/components/column_settings.js b/app/javascript/flavours/glitch/features/notifications/components/column_settings.js
index d9638aaf3..4e35d5b4e 100644
--- a/app/javascript/flavours/glitch/features/notifications/components/column_settings.js
+++ b/app/javascript/flavours/glitch/features/notifications/components/column_settings.js
@@ -21,9 +21,11 @@ export default class ColumnSettings extends React.PureComponent {
   render () {
     const { settings, pushSettings, onChange, onClear } = this.props;
 
-    const alertStr = <FormattedMessage id='notifications.column_settings.alert' defaultMessage='Desktop notifications' />;
-    const showStr  = <FormattedMessage id='notifications.column_settings.show' defaultMessage='Show in column' />;
-    const soundStr = <FormattedMessage id='notifications.column_settings.sound' defaultMessage='Play sound' />;
+    const filterShowStr = <FormattedMessage id='notifications.column_settings.filter_bar.show' defaultMessage='Show' />;
+    const filterAdvancedStr = <FormattedMessage id='notifications.column_settings.filter_bar.advanced' defaultMessage='Display all categories' />;
+    const alertStr  = <FormattedMessage id='notifications.column_settings.alert' defaultMessage='Desktop notifications' />;
+    const showStr   = <FormattedMessage id='notifications.column_settings.show' defaultMessage='Show in column' />;
+    const soundStr  = <FormattedMessage id='notifications.column_settings.sound' defaultMessage='Play sound' />;
 
     const showPushSettings = pushSettings.get('browserSupport') && pushSettings.get('isSubscribed');
     const pushStr = showPushSettings && <FormattedMessage id='notifications.column_settings.push' defaultMessage='Push notifications' />;
@@ -35,6 +37,16 @@ export default class ColumnSettings extends React.PureComponent {
           <ClearColumnButton onClick={onClear} />
         </div>
 
+        <div role='group' aria-labelledby='notifications-filter-bar'>
+          <span id='notifications-filter-bar' className='column-settings__section'>
+            <FormattedMessage id='notifications.column_settings.filter_bar.category' defaultMessage='Quick filter bar' />
+          </span>
+          <div className='column-settings__row'>
+            <SettingToggle id='show-filter-bar' prefix='notifications' settings={settings} settingPath={['quickFilter', 'show']} onChange={onChange} label={filterShowStr} />
+            <SettingToggle id='show-filter-bar' prefix='notifications' settings={settings} settingPath={['quickFilter', 'advanced']} onChange={onChange} label={filterAdvancedStr} />
+          </div>
+        </div>
+
         <div role='group' aria-labelledby='notifications-follow'>
           <span id='notifications-follow' className='column-settings__section'><FormattedMessage id='notifications.column_settings.follow' defaultMessage='New followers:' /></span>
 
diff --git a/app/javascript/flavours/glitch/features/notifications/components/filter_bar.js b/app/javascript/flavours/glitch/features/notifications/components/filter_bar.js
new file mode 100644
index 000000000..f95a2c9de
--- /dev/null
+++ b/app/javascript/flavours/glitch/features/notifications/components/filter_bar.js
@@ -0,0 +1,93 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
+
+const tooltips = defineMessages({
+  mentions: { id: 'notifications.filter.mentions', defaultMessage: 'Mentions' },
+  favourites: { id: 'notifications.filter.favourites', defaultMessage: 'Favourites' },
+  boosts: { id: 'notifications.filter.boosts', defaultMessage: 'Boosts' },
+  follows: { id: 'notifications.filter.follows', defaultMessage: 'Follows' },
+});
+
+export default @injectIntl
+class FilterBar extends React.PureComponent {
+
+  static propTypes = {
+    selectFilter: PropTypes.func.isRequired,
+    selectedFilter: PropTypes.string.isRequired,
+    advancedMode: PropTypes.bool.isRequired,
+    intl: PropTypes.object.isRequired,
+  };
+
+  onClick (notificationType) {
+    return () => this.props.selectFilter(notificationType);
+  }
+
+  render () {
+    const { selectedFilter, advancedMode, intl } = this.props;
+    const renderedElement = !advancedMode ? (
+      <div className='notification__filter-bar'>
+        <button
+          className={selectedFilter === 'all' ? 'active' : ''}
+          onClick={this.onClick('all')}
+        >
+          <FormattedMessage
+            id='notifications.filter.all'
+            defaultMessage='All'
+          />
+        </button>
+        <button
+          className={selectedFilter === 'mention' ? 'active' : ''}
+          onClick={this.onClick('mention')}
+        >
+          <FormattedMessage
+            id='notifications.filter.mentions'
+            defaultMessage='Mentions'
+          />
+        </button>
+      </div>
+    ) : (
+      <div className='notification__filter-bar'>
+        <button
+          className={selectedFilter === 'all' ? 'active' : ''}
+          onClick={this.onClick('all')}
+        >
+          <FormattedMessage
+            id='notifications.filter.all'
+            defaultMessage='All'
+          />
+        </button>
+        <button
+          className={selectedFilter === 'mention' ? 'active' : ''}
+          onClick={this.onClick('mention')}
+          title={intl.formatMessage(tooltips.mentions)}
+        >
+          <i className='fa fa-fw fa-at' />
+        </button>
+        <button
+          className={selectedFilter === 'favourite' ? 'active' : ''}
+          onClick={this.onClick('favourite')}
+          title={intl.formatMessage(tooltips.favourites)}
+        >
+          <i className='fa fa-fw fa-star' />
+        </button>
+        <button
+          className={selectedFilter === 'reblog' ? 'active' : ''}
+          onClick={this.onClick('reblog')}
+          title={intl.formatMessage(tooltips.boosts)}
+        >
+          <i className='fa fa-fw fa-retweet' />
+        </button>
+        <button
+          className={selectedFilter === 'follow' ? 'active' : ''}
+          onClick={this.onClick('follow')}
+          title={intl.formatMessage(tooltips.follows)}
+        >
+          <i className='fa fa-fw fa-user-plus' />
+        </button>
+      </div>
+    );
+    return renderedElement;
+  }
+
+}
diff --git a/app/javascript/flavours/glitch/features/notifications/containers/column_settings_container.js b/app/javascript/flavours/glitch/features/notifications/containers/column_settings_container.js
index 9585ea556..4b863712a 100644
--- a/app/javascript/flavours/glitch/features/notifications/containers/column_settings_container.js
+++ b/app/javascript/flavours/glitch/features/notifications/containers/column_settings_container.js
@@ -2,6 +2,7 @@ import { connect } from 'react-redux';
 import { defineMessages, injectIntl } from 'react-intl';
 import ColumnSettings from '../components/column_settings';
 import { changeSetting } from 'flavours/glitch/actions/settings';
+import { setFilter } from 'flavours/glitch/actions/notifications';
 import { clearNotifications } from 'flavours/glitch/actions/notifications';
 import { changeAlerts as changePushNotifications } from 'flavours/glitch/actions/push_notifications';
 import { openModal } from 'flavours/glitch/actions/modal';
@@ -21,6 +22,9 @@ const mapDispatchToProps = (dispatch, { intl }) => ({
   onChange (path, checked) {
     if (path[0] === 'push') {
       dispatch(changePushNotifications(path.slice(1), checked));
+    } else if (path[0] === 'quickFilter') {
+      dispatch(changeSetting(['notifications', ...path], checked));
+      dispatch(setFilter('all'));
     } else {
       dispatch(changeSetting(['notifications', ...path], checked));
     }
diff --git a/app/javascript/flavours/glitch/features/notifications/containers/filter_bar_container.js b/app/javascript/flavours/glitch/features/notifications/containers/filter_bar_container.js
new file mode 100644
index 000000000..4d495c290
--- /dev/null
+++ b/app/javascript/flavours/glitch/features/notifications/containers/filter_bar_container.js
@@ -0,0 +1,16 @@
+import { connect } from 'react-redux';
+import FilterBar from '../components/filter_bar';
+import { setFilter } from '../../../actions/notifications';
+
+const makeMapStateToProps = state => ({
+  selectedFilter: state.getIn(['settings', 'notifications', 'quickFilter', 'active']),
+  advancedMode: state.getIn(['settings', 'notifications', 'quickFilter', 'advanced']),
+});
+
+const mapDispatchToProps = (dispatch) => ({
+  selectFilter (newActiveFilter) {
+    dispatch(setFilter(newActiveFilter));
+  },
+});
+
+export default connect(makeMapStateToProps, mapDispatchToProps)(FilterBar);
diff --git a/app/javascript/flavours/glitch/features/notifications/index.js b/app/javascript/flavours/glitch/features/notifications/index.js
index 0e73f02d8..6a149927c 100644
--- a/app/javascript/flavours/glitch/features/notifications/index.js
+++ b/app/javascript/flavours/glitch/features/notifications/index.js
@@ -15,6 +15,7 @@ import { addColumn, removeColumn, moveColumn } from 'flavours/glitch/actions/col
 import NotificationContainer from './containers/notification_container';
 import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
 import ColumnSettingsContainer from './containers/column_settings_container';
+import FilterBarContainer from './containers/filter_bar_container';
 import { createSelector } from 'reselect';
 import { List as ImmutableList } from 'immutable';
 import { debounce } from 'lodash';
@@ -26,11 +27,22 @@ const messages = defineMessages({
 });
 
 const getNotifications = createSelector([
+  state => state.getIn(['settings', 'notifications', 'quickFilter', 'show']),
+  state => state.getIn(['settings', 'notifications', 'quickFilter', 'active']),
   state => ImmutableList(state.getIn(['settings', 'notifications', 'shows']).filter(item => !item).keys()),
   state => state.getIn(['notifications', 'items']),
-], (excludedTypes, notifications) => notifications.filterNot(item => item !== null && excludedTypes.includes(item.get('type'))));
+], (showFilterBar, allowedType, excludedTypes, notifications) => {
+  if (!showFilterBar || allowedType === 'all') {
+    // used if user changed the notification settings after loading the notifications from the server
+    // otherwise a list of notifications will come pre-filtered from the backend
+    // we need to turn it off for FilterBar in order not to block ourselves from seeing a specific category
+    return notifications.filterNot(item => item !== null && excludedTypes.includes(item.get('type')));
+  }
+  return notifications.filter(item => item !== null && allowedType === item.get('type'));
+});
 
 const mapStateToProps = state => ({
+  showFilterBar: state.getIn(['settings', 'notifications', 'quickFilter', 'show']),
   notifications: getNotifications(state),
   localSettings:  state.get('local_settings'),
   isLoading: state.getIn(['notifications', 'isLoading'], true),
@@ -60,6 +72,7 @@ export default class Notifications extends React.PureComponent {
   static propTypes = {
     columnId: PropTypes.string,
     notifications: ImmutablePropTypes.list.isRequired,
+    showFilterBar: PropTypes.bool.isRequired,
     dispatch: PropTypes.func.isRequired,
     shouldUpdateScroll: PropTypes.func,
     intl: PropTypes.object.isRequired,
@@ -151,12 +164,16 @@ export default class Notifications extends React.PureComponent {
   }
 
   render () {
-    const { intl, notifications, shouldUpdateScroll, isLoading, isUnread, columnId, multiColumn, hasMore } = this.props;
+    const { intl, notifications, shouldUpdateScroll, isLoading, isUnread, columnId, multiColumn, hasMore, showFilterBar } = this.props;
     const pinned = !!columnId;
     const emptyMessage = <FormattedMessage id='empty_column.notifications' defaultMessage="You don't have any notifications yet. Interact with others to start the conversation." />;
 
     let scrollableContent = null;
 
+    const filterBarContainer = showFilterBar
+      ? (<FilterBarContainer />)
+      : null;
+
     if (isLoading && this.scrollableContent) {
       scrollableContent = this.scrollableContent;
     } else if (notifications.size > 0 || hasMore) {
@@ -222,7 +239,7 @@ export default class Notifications extends React.PureComponent {
         >
           <ColumnSettingsContainer />
         </ColumnHeader>
-
+        {filterBarContainer}
         {scrollContainer}
       </Column>
     );
diff --git a/app/javascript/flavours/glitch/reducers/notifications.js b/app/javascript/flavours/glitch/reducers/notifications.js
index b65c51f32..6667966c0 100644
--- a/app/javascript/flavours/glitch/reducers/notifications.js
+++ b/app/javascript/flavours/glitch/reducers/notifications.js
@@ -6,6 +6,7 @@ import {
   NOTIFICATIONS_EXPAND_SUCCESS,
   NOTIFICATIONS_EXPAND_REQUEST,
   NOTIFICATIONS_EXPAND_FAIL,
+  NOTIFICATIONS_FILTER_SET,
   NOTIFICATIONS_CLEAR,
   NOTIFICATIONS_SCROLL_TOP,
   NOTIFICATIONS_DELETE_MARKED_REQUEST,
@@ -197,6 +198,8 @@ export default function notifications(state = initialState, action) {
   case NOTIFICATIONS_DELETE_MARKED_FAIL:
   case NOTIFICATIONS_EXPAND_FAIL:
     return state.set('isLoading', false);
+  case NOTIFICATIONS_FILTER_SET:
+    return state.set('items', ImmutableList()).set('hasMore', true);
   case NOTIFICATIONS_SCROLL_TOP:
     return updateTop(state, action.top);
   case NOTIFICATIONS_UPDATE:
diff --git a/app/javascript/flavours/glitch/reducers/notifications.js.orig b/app/javascript/flavours/glitch/reducers/notifications.js.orig
new file mode 100644
index 000000000..b65c51f32
--- /dev/null
+++ b/app/javascript/flavours/glitch/reducers/notifications.js.orig
@@ -0,0 +1,245 @@
+import {
+  NOTIFICATIONS_MOUNT,
+  NOTIFICATIONS_UNMOUNT,
+  NOTIFICATIONS_SET_VISIBILITY,
+  NOTIFICATIONS_UPDATE,
+  NOTIFICATIONS_EXPAND_SUCCESS,
+  NOTIFICATIONS_EXPAND_REQUEST,
+  NOTIFICATIONS_EXPAND_FAIL,
+  NOTIFICATIONS_CLEAR,
+  NOTIFICATIONS_SCROLL_TOP,
+  NOTIFICATIONS_DELETE_MARKED_REQUEST,
+  NOTIFICATIONS_DELETE_MARKED_SUCCESS,
+  NOTIFICATION_MARK_FOR_DELETE,
+  NOTIFICATIONS_DELETE_MARKED_FAIL,
+  NOTIFICATIONS_ENTER_CLEARING_MODE,
+  NOTIFICATIONS_MARK_ALL_FOR_DELETE,
+} from 'flavours/glitch/actions/notifications';
+import {
+  ACCOUNT_BLOCK_SUCCESS,
+  ACCOUNT_MUTE_SUCCESS,
+} from 'flavours/glitch/actions/accounts';
+import { TIMELINE_DELETE, TIMELINE_DISCONNECT } from 'flavours/glitch/actions/timelines';
+import { Map as ImmutableMap, List as ImmutableList } from 'immutable';
+import compareId from 'flavours/glitch/util/compare_id';
+
+const initialState = ImmutableMap({
+  items: ImmutableList(),
+  hasMore: true,
+  top: true,
+  mounted: 0,
+  unread: 0,
+  lastReadId: '0',
+  isLoading: false,
+  cleaningMode: false,
+  isTabVisible: true,
+  // notification removal mark of new notifs loaded whilst cleaningMode is true.
+  markNewForDelete: false,
+});
+
+const notificationToMap = (state, notification) => ImmutableMap({
+  id: notification.id,
+  type: notification.type,
+  account: notification.account.id,
+  markedForDelete: state.get('markNewForDelete'),
+  status: notification.status ? notification.status.id : null,
+});
+
+const normalizeNotification = (state, notification) => {
+  const top = !shouldCountUnreadNotifications(state);
+
+  if (top) {
+    state = state.set('lastReadId', notification.id);
+  } else {
+    state = state.update('unread', unread => unread + 1);
+  }
+
+  return state.update('items', list => {
+    if (top && list.size > 40) {
+      list = list.take(20);
+    }
+
+    return list.unshift(notificationToMap(state, notification));
+  });
+};
+
+const expandNormalizedNotifications = (state, notifications, next) => {
+  const top = !(shouldCountUnreadNotifications(state));
+  const lastReadId = state.get('lastReadId');
+  let items = ImmutableList();
+
+  notifications.forEach((n, i) => {
+    items = items.set(i, notificationToMap(state, n));
+  });
+
+  return state.withMutations(mutable => {
+    if (!items.isEmpty()) {
+      mutable.update('items', list => {
+        const lastIndex = 1 + list.findLastIndex(
+          item => item !== null && (compareId(item.get('id'), items.last().get('id')) > 0 || item.get('id') === items.last().get('id'))
+        );
+
+        const firstIndex = 1 + list.take(lastIndex).findLastIndex(
+          item => item !== null && compareId(item.get('id'), items.first().get('id')) > 0
+        );
+
+        return list.take(firstIndex).concat(items, list.skip(lastIndex));
+      });
+    }
+
+    if (top) {
+      if (!items.isEmpty()) {
+        mutable.update('lastReadId', id => compareId(id, items.first().get('id')) > 0 ? id : items.first().get('id'));
+      }
+    } else {
+      mutable.update('unread', unread => unread + items.filter(item => compareId(item.get('id'), lastReadId) > 0).size);
+    }
+
+    if (!next) {
+      mutable.set('hasMore', false);
+    }
+
+    mutable.set('isLoading', false);
+  });
+};
+
+const filterNotifications = (state, relationship) => {
+  return state.update('items', list => list.filterNot(item => item !== null && item.get('account') === relationship.id));
+};
+
+const clearUnread = (state) => {
+  state = state.set('unread', 0);
+  const lastNotification = state.get('items').find(item => item !== null);
+  return state.set('lastReadId', lastNotification ? lastNotification.get('id') : '0');
+}
+
+const updateTop = (state, top) => {
+  state = state.set('top', top);
+
+  if (!shouldCountUnreadNotifications(state)) {
+    state = clearUnread(state);
+  }
+
+  return state.set('top', top);
+};
+
+const deleteByStatus = (state, statusId) => {
+  const top = !(shouldCountUnreadNotifications(state));
+  if (!top) {
+    const lastReadId = state.get('lastReadId');
+    const deletedUnread = state.get('items').filter(item => item !== null && item.get('status') === statusId && compareId(item.get('id'), lastReadId) > 0);
+    state = state.update('unread', unread => unread - deletedUnread.size);
+  }
+  return state.update('items', list => list.filterNot(item => item !== null && item.get('status') === statusId));
+};
+
+const markForDelete = (state, notificationId, yes) => {
+  return state.update('items', list => list.map(item => {
+    if(item.get('id') === notificationId) {
+      return item.set('markedForDelete', yes);
+    } else {
+      return item;
+    }
+  }));
+};
+
+const markAllForDelete = (state, yes) => {
+  return state.update('items', list => list.map(item => {
+    if(yes !== null) {
+      return item.set('markedForDelete', yes);
+    } else {
+      return item.set('markedForDelete', !item.get('markedForDelete'));
+    }
+  }));
+};
+
+const unmarkAllForDelete = (state) => {
+  return state.update('items', list => list.map(item => item.set('markedForDelete', false)));
+};
+
+const deleteMarkedNotifs = (state) => {
+  return state.update('items', list => list.filterNot(item => item.get('markedForDelete')));
+};
+
+const updateMounted = (state) => {
+  state = state.update('mounted', count => count + 1);
+  if (!shouldCountUnreadNotifications(state)) {
+    state = clearUnread(state);
+  }
+  return state;
+};
+
+const updateVisibility = (state, visibility) => {
+  state = state.set('isTabVisible', visibility);
+  if (!shouldCountUnreadNotifications(state)) {
+    state = clearUnread(state);
+  }
+  return state;
+};
+
+const shouldCountUnreadNotifications = (state) => {
+  return !(state.get('isTabVisible') && state.get('top') && state.get('mounted') > 0);
+};
+
+export default function notifications(state = initialState, action) {
+  let st;
+
+  switch(action.type) {
+  case NOTIFICATIONS_MOUNT:
+    return updateMounted(state);
+  case NOTIFICATIONS_UNMOUNT:
+    return state.update('mounted', count => count - 1);
+  case NOTIFICATIONS_SET_VISIBILITY:
+    return updateVisibility(state, action.visibility);
+  case NOTIFICATIONS_EXPAND_REQUEST:
+  case NOTIFICATIONS_DELETE_MARKED_REQUEST:
+    return state.set('isLoading', true);
+  case NOTIFICATIONS_DELETE_MARKED_FAIL:
+  case NOTIFICATIONS_EXPAND_FAIL:
+    return state.set('isLoading', false);
+  case NOTIFICATIONS_SCROLL_TOP:
+    return updateTop(state, action.top);
+  case NOTIFICATIONS_UPDATE:
+    return normalizeNotification(state, action.notification);
+  case NOTIFICATIONS_EXPAND_SUCCESS:
+    return expandNormalizedNotifications(state, action.notifications, action.next);
+  case ACCOUNT_BLOCK_SUCCESS:
+  case ACCOUNT_MUTE_SUCCESS:
+    return filterNotifications(state, action.relationship);
+  case NOTIFICATIONS_CLEAR:
+    return state.set('items', ImmutableList()).set('hasMore', false);
+  case TIMELINE_DELETE:
+    return deleteByStatus(state, action.id);
+  case TIMELINE_DISCONNECT:
+    return action.timeline === 'home' ?
+      state.update('items', items => items.first() ? items.unshift(null) : items) :
+      state;
+
+  case NOTIFICATION_MARK_FOR_DELETE:
+    return markForDelete(state, action.id, action.yes);
+
+  case NOTIFICATIONS_DELETE_MARKED_SUCCESS:
+    return deleteMarkedNotifs(state).set('isLoading', false);
+
+  case NOTIFICATIONS_ENTER_CLEARING_MODE:
+    st = state.set('cleaningMode', action.yes);
+    if (!action.yes) {
+      return unmarkAllForDelete(st).set('markNewForDelete', false);
+    } else {
+      return st;
+    }
+
+  case NOTIFICATIONS_MARK_ALL_FOR_DELETE:
+    st = state;
+    if (action.yes === null) {
+      // Toggle - this is a bit confusing, as it toggles the all-none mode
+      //st = st.set('markNewForDelete', !st.get('markNewForDelete'));
+    } else {
+      st = st.set('markNewForDelete', action.yes);
+    }
+    return markAllForDelete(st, action.yes);
+
+  default:
+    return state;
+  }
+};
diff --git a/app/javascript/flavours/glitch/reducers/settings.js b/app/javascript/flavours/glitch/reducers/settings.js
index c04f262da..cb62f87b0 100644
--- a/app/javascript/flavours/glitch/reducers/settings.js
+++ b/app/javascript/flavours/glitch/reducers/settings.js
@@ -1,4 +1,5 @@
 import { SETTING_CHANGE, SETTING_SAVE } from 'flavours/glitch/actions/settings';
+import { NOTIFICATIONS_FILTER_SET } from 'flavours/glitch/actions/notifications';
 import { COLUMN_ADD, COLUMN_REMOVE, COLUMN_MOVE } from 'flavours/glitch/actions/columns';
 import { STORE_HYDRATE } from 'flavours/glitch/actions/store';
 import { EMOJI_USE } from 'flavours/glitch/actions/emojis';
@@ -34,6 +35,12 @@ const initialState = ImmutableMap({
       mention: true,
     }),
 
+    quickFilter: ImmutableMap({
+      active: 'all',
+      show: true,
+      advanced: false,
+    }),
+
     shows: ImmutableMap({
       follow: true,
       favourite: true,
@@ -99,6 +106,7 @@ export default function settings(state = initialState, action) {
   switch(action.type) {
   case STORE_HYDRATE:
     return hydrate(state, action.state.get('settings'));
+  case NOTIFICATIONS_FILTER_SET:
   case SETTING_CHANGE:
     return state
       .setIn(action.path, action.value)
diff --git a/app/javascript/flavours/glitch/styles/components/accounts.scss b/app/javascript/flavours/glitch/styles/components/accounts.scss
index d87cd9c43..5f465259f 100644
--- a/app/javascript/flavours/glitch/styles/components/accounts.scss
+++ b/app/javascript/flavours/glitch/styles/components/accounts.scss
@@ -445,12 +445,19 @@
   }
 }
 
+.notification__filter-bar,
 .account__section-headline {
   background: darken($ui-base-color, 4%);
   border-bottom: 1px solid lighten($ui-base-color, 8%);
   cursor: default;
   display: flex;
 
+  button {
+    background: darken($ui-base-color, 4%);
+    border: 0;
+  }
+
+  button,
   a {
     display: block;
     flex: 1 1 auto;
diff --git a/app/javascript/flavours/glitch/styles/containers.scss b/app/javascript/flavours/glitch/styles/containers.scss
index 398458e47..82d4050d7 100644
--- a/app/javascript/flavours/glitch/styles/containers.scss
+++ b/app/javascript/flavours/glitch/styles/containers.scss
@@ -296,6 +296,12 @@
         text-decoration: underline;
         color: $primary-text-color;
       }
+
+      @media screen and (max-width: $no-gap-breakpoint) {
+        &.optional {
+          display: none;
+        }
+      }
     }
 
     .nav-button {
diff --git a/app/javascript/flavours/glitch/styles/widgets.scss b/app/javascript/flavours/glitch/styles/widgets.scss
index c863e3b4f..87e633c70 100644
--- a/app/javascript/flavours/glitch/styles/widgets.scss
+++ b/app/javascript/flavours/glitch/styles/widgets.scss
@@ -229,18 +229,6 @@
   margin-bottom: 10px;
 }
 
-.moved-account-widget,
-.memoriam-widget,
-.box-widget,
-.contact-widget,
-.landing-page__information.contact-widget {
-  @media screen and (max-width: $no-gap-breakpoint) {
-    margin-bottom: 0;
-    box-shadow: none;
-    border-radius: 0;
-  }
-}
-
 .page-header {
   background: lighten($ui-base-color, 8%);
   box-shadow: 0 0 15px rgba($base-shadow-color, 0.2);
@@ -261,11 +249,20 @@
     font-size: 15px;
     color: $darker-text-color;
   }
+
+  @media screen and (max-width: $no-gap-breakpoint) {
+    margin-top: 0;
+    background: lighten($ui-base-color, 4%);
+
+    h1 {
+      font-size: 24px;
+    }
+  }
 }
 
 .directory {
   background: $ui-base-color;
-  border-radius: 0 0 4px 4px;
+  border-radius: 4px;
   box-shadow: 0 0 15px rgba($base-shadow-color, 0.2);
 
   &__tag {
@@ -407,4 +404,24 @@
       font-size: 14px;
     }
   }
+
+  @media screen and (max-width: $no-gap-breakpoint) {
+    tbody td.optional {
+      display: none;
+    }
+  }
+}
+
+.moved-account-widget,
+.memoriam-widget,
+.box-widget,
+.contact-widget,
+.landing-page__information.contact-widget,
+.directory,
+.page-header {
+  @media screen and (max-width: $no-gap-breakpoint) {
+    margin-bottom: 0;
+    box-shadow: none;
+    border-radius: 0;
+  }
 }
diff --git a/app/javascript/images/screen_federation.svg b/app/javascript/images/screen_federation.svg
new file mode 100644
index 000000000..7019a7356
--- /dev/null
+++ b/app/javascript/images/screen_federation.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" height="806.09998" width="1197.7164" viewBox="0 0 1197.7164 806.09999" id="Layer_1"><path id="path6078" d="M482.4164 557.4c-42.3-31.3-89.9-55.7-141.2-72.5-53.2-17.4-109.1-26.2-166.3-26.2-59.7 0-117.9 9.6-173.1 28.5v315.9h645.6c-21.6-95.7-80.1-182.9-165-245.7z" class="st33" fill="#fff"/><path stroke-miterlimit="10" id="path6082" d="M515.7164 589.8c-1.1 3.3-6.4 5.1-7.4 4.2l-.2-7.1.2-3.6c-86.1-74.6-203.7-120.6-333.4-120.6-61 0-119.4 10.2-173.1 28.8v313.6h641.9c-18.4-83.2-63.7-157.2-128-215.3" class="st80" fill="#587faa" stroke="#000" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" id="path6084" d="M351.5164 565.1l9.3 4.8" class="st81" fill="none" stroke="#2d3f68" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" id="path6086" d="M336.5164 558c2.2 1 4.4 2 6.5 3" class="st81" fill="none" stroke="#2d3f68" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" id="path6088" d="M321.5164 551.5c2.6 1 5.1 2.1 7.7 3.2" class="st81" fill="none" stroke="#2d3f68" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" id="path6090" d="M304.8164 545.1c3.4 1.2 6.7 2.5 10 3.7" class="st81" fill="none" stroke="#2d3f68" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/><g id="g6092" transform="translate(-1343.3836 -75.800003)"><path stroke-miterlimit="10" id="path6094" d="M1890.4 836.8c1.9 3.9 3.8 7.8 5.5 11.7" class="st81" fill="none" stroke="#2d3f68" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" id="path6100" d="M1880.9 818.7c1.5 2.7 2.9 5.4 4.4 8.1" class="st81" fill="none" stroke="#2d3f68" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" id="path6102" d="M1871.4 802.4c1.8 2.9 3.5 5.8 5.2 8.8" class="st81" fill="none" stroke="#2d3f68" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" id="path6104" d="M1860.3 785.1c2 2.9 4 5.9 5.9 8.9" class="st81" fill="none" stroke="#2d3f68" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" id="path6106" d="M1848.4 768.6c2.2 2.9 4.3 5.8 6.4 8.8" class="st81" fill="none" stroke="#2d3f68" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" id="path6108" d="M1834.4 751c2.6 3.1 5.2 6.3 7.7 9.5" class="st81" fill="none" stroke="#2d3f68" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/></g><path id="path6110" d="M156.6164 523.5c-54.6 0-106.7 10.1-154.8 28.4V805h559.5c-59.5-164.1-218.2-281.5-404.7-281.5z" class="st82" fill="#2d3f68"/><g id="g6112" transform="translate(-1343.3836 -75.800003)"><path id="path6114" d="M2065.2 128.3c1.4 69-36.9 80.4-35.7 141.1 1.2 60.6 39.9 70.5 41.3 139.5 1.4 69-36.9 80.4-35.7 141.1 1.2 60.6 39.9 70.5 41.3 139.5 1.4 69-36.9 80.4-35.7 141.1.4 20.5 5.1 35.2 11.2 48.3H2541v-803h-487.3c6.2 13.6 11 29.7 11.5 52.4z"/></g><g id="g6116" transform="translate(-1343.3836 -75.800003)"><circle stroke-miterlimit="10" id="circle6118" r="33.799999" cy="645.40002" cx="2236.6001" class="st83" fill="#ebb548" stroke="#663f09" stroke-width="3.30660009" stroke-linecap="round" stroke-linejoin="round"/><g id="g6120"><path stroke-miterlimit="10" id="path6122" d="M2243.3 641.5c-2.4-5.6-8-6.2-15.8-3.2-5.7 2.2-18.2 7.3-24.5 9.9.7 8.2 4.3 15.5 9.7 21 6.7-2.6 21.3-8.2 32-12.6 14.3-5.9 12.9-9.1 10.2-14.1-2.7-5-11.6-1-11.6-1z" class="st84" fill="#ad6a3b" stroke="#663f09" stroke-width="1.65330005"/><path stroke-miterlimit="10" id="path6124" d="M2243.4 612.3c-12.6 4.4-13.1 7.3-11.2 11.6 2.1 4.6 9.4 2.6 15.4.1 2.6-1 6.8-2.8 10.7-4.5-4.2-3.5-9.2-6.1-14.9-7.2z" class="st84" fill="#ad6a3b" stroke="#663f09" stroke-width="1.65330005"/></g><g id="g6126"><circle id="circle6128" r="3" cy="627.70001" cx="2218.8" class="st33" fill="#fff"/></g></g><g id="g6130" transform="translate(-1343.3836 -75.800003)"><circle stroke-miterlimit="10" id="circle6132" r="33.799999" cy="485.79999" cx="2402.5" class="st83" fill="#ebb548" stroke="#663f09" stroke-width="3.30660009" stroke-linecap="round" stroke-linejoin="round"/><g id="g6134"><circle id="circle6136" r="3" cy="468.20001" cx="2384.8" class="st33" fill="#fff"/></g></g><path id="path6138" d="M292.3164 506.3c-2.7 0-6.7-.4-9.8-3.5-2.9-3-4.2-7.6-4-14 .1-2.2.2-4.1.2-5.9-2.9-.4-5.8-.9-8.6-1.7-17.4-4.7-31.5-16.3-39.6-32.8-1-2.1-2-4.2-2.8-6.4-.6 0-1.2 0-1.7.1-.9 2.2-1.8 4.3-2.8 6.4-8.1 16.5-22.1 28.1-39.6 32.8-2.8.8-5.7 1.3-8.6 1.7.1 1.7.1 3.7.2 5.9.3 6.4-1 11-4 14-3.1 3.2-7.1 3.5-9.8 3.5H149.6164c-13.1 0-13.1-9.7-13.1-14.9v-14.7c-2-.9-3.9-1.9-5.7-3-1.6 2.7-4.5 5.6-9.3 6.9-4.8 1.2-8.9 1.8-12.5 1.8-4.5 0-8.3-1-11.2-2.9-3.3-2.2-5.4-5.7-6-10.1-1.5-10.5-.6-17.6 2.6-21.8 1.8-2.3 4.2-3.6 7.1-3.9l5.5-.5c-9.9-1.8-15.4-7.7-16.4-17.5-.8-8.1 6.6-16.9 11-18.6 1.1-.5 2.2-.7 3.1-.7 1.8 0 3.2.8 4.2 2.2 1 1.4 1.9 4.3-2.2 8.4-.7.9-3.3 6.5-1.8 9.9.8 1.7 2.7 2.7 5.8 3.1 1.9-7.1 5.8-12.8 11.4-16.6h-.5c-3.8 0-7-1.3-9.2-3.8-2.2-2.5-3.2-6-2.7-9.9.6-4.5.6-11.5 0-21.9-.7-13.3 4.2-23.4 13-26.3 2.2-.7 4.4-1.1 6.6-1.1 3.2 0 6.4.8 9.3 2.2l.1-.1c-1.5-3.1-1.9-6.5-1.1-9.5.7-2.6 3.4-8.9 13.8-10.1 1.4-.2 3.5-.3 6.1-.3 2.1-3.3 5.4-7.6 9.2-9.8.1-.7.1-1.2.2-1.7-1.3-3-1.4-5.7-.3-8 .7-1.6 2.4-3.7 6-4.6.7-.2 1.5-.3 2.2-.3 2.9 0 5.6 1.4 7.7 4 .4-.1.7-.1 1.1-.1h.5c2.6.2 5 1.5 6.6 3.8 2.2 3 1.3 7.1-2 10.5.3 3.1 1.5 5.7 3.5 7.7.5.5 1.2 1 1.9 1.5 4.7.7 8.8 1.6 12.5 2.5 2.8.7 5.3 1.2 7.1 1.4 1.3.2 2.8.2 4.4.2 7.5 0 17.4-1.7 22.8-6.5 2.2-1.9 3.4-4.2 3.8-6.9-2.8-2.9-3.4-6.6-1.6-9.6.6-1 2.4-4 5.8-4.6.4-.1.8-.1 1.2-.1.4 0 .8 0 1.2.1 2-2 4.2-3.1 6.5-3.1.8 0 1.6.1 2.4.4 2.5.8 4.6 2.6 5.7 4.9.9 1.9 1.1 4.1.5 6.3.3 2.4.9 7.8.1 14.5 7.9.2 15.7 2.7 23.7 7.6 1.5.9 2.8 1.8 4.1 2.7.9-.3 1.9-.6 3-.8 1.6-.3 3.2-.5 4.7-.5 7 0 16.4 3.6 21.7 20.7 1.4 4.7 2.9 8.2 4 11.1 2.7 6.6 4.8 11.9-1.1 17.1-3.9 3.4-7.7 5.2-11.5 5.2-1.3 0-2.5-.2-3.7-.6v.1c16.3 3.4 27.2 14.7 31.3 32.1 3.4-.3 5.5-1.4 6.3-3.2 1.5-3.4-1-9-1.9-10-4-4-3-6.9-2.1-8.3.9-1.4 2.4-2.2 4.2-2.2 1 0 2 .2 3.1.7 4.3 1.7 11.8 10.6 11 18.6-1 9.8-6.5 15.7-16.5 17.5l5.5.6c2.8.3 5.3 1.6 7.1 3.9 3.3 4.2 4.1 11.3 2.6 21.8-.6 4.4-2.7 7.9-6 10.1-2.9 1.9-6.6 2.9-11.1 2.9-3.6 0-7.7-.6-12.5-1.8-4.8-1.2-7.7-4.2-9.3-6.9-1.9 1.1-3.8 2.1-5.7 3v14.7c0 5.2 0 14.9-13.1 14.9h-10.8c-.5.1-.8.1-1.2.1z" class="st33" fill="#fff"/><g id="g6140" transform="translate(-1343.3836 -75.800003)"><path stroke-miterlimit="10" id="path6142" d="M1527.8 400.3s4.8-3.7 2.9-6.3c-1.9-2.6-5-2.5-6.5-.9 0 0-2.4-6.1-7.2-4.9-3.7.9-4.6 3.7-2.4 7.9 0 0-8.4 42.4 35.2 53.1l4.6-29.6c-11.7.1-26.6-3.8-26.6-19.3z" class="st85" fill="#fbc16c" stroke="#946f3a" stroke-width="2.38770008" stroke-linecap="round" stroke-linejoin="round"/><g id="g6144"><path stroke-miterlimit="10" id="path6146" d="M1695.3 523.5c-6-.6-11.9-1.2-11.9-1.2s3.6-40.6-32.8-45.4c.6-34.6-2.4-44.8-19.1-54.9-23.7-14.4-38.7-2.2-48.8-1-1.3.2-2.9.3-4.7.3l-7.6 27.9s-9.3 39.1 7.5 73.1c16.7 34 58.5 42.4 90.7 20.9 0 0 1.2 7.2 8.4 9 7.2 1.8 22.7 4.8 24.5-7.8 1.6-12.5-.2-20.3-6.2-20.9z" class="st86" fill="#876a4d" stroke="#3b3024" stroke-width="2.38770008" stroke-linecap="round" stroke-linejoin="round"/></g><path stroke-miterlimit="10" id="path6148" d="M1474.2 489.2c-.6-34.6 0-56.7 25.1-68.6 25.1-11.9 47.2-2.4 57.3-1.2 10.1 1.2 35.8-1.2 35.8-19.1 0 0-4.1-2.8-2.3-5.6 1.7-2.8 3.4-3.6 5.9-1.6 0 0 2.7-5.1 6.3-3.9 2.5.8 4.6 3.3 3.2 6.9 0 0 8.4 42.4-35.2 53.1 0 0 9.3 39.1-7.5 73.1-16.7 34-58.5 42.4-90.7 20.9 0 0-1.2 7.2-8.4 9-7.2 1.8-22.7 4.8-24.5-7.8-1.8-12.5 0-20.3 6-20.9 6-.6 11.9-1.2 11.9-1.2s-4.7-25.6 17.1-33.1z" class="st85" fill="#fbc16c" stroke="#946f3a" stroke-width="2.38770008" stroke-linecap="round" stroke-linejoin="round"/><path id="path6150" d="M1510 553.9c-13 0-25.9-4-37.2-11.6l-1.5-1-.3 1.8c0 .3-1.2 6.4-7.5 8-4.4 1.1-8 1.6-11.1 1.6-7.2 0-11.1-2.7-11.9-8.4-1.6-11 0-15.7 1.6-17.7.9-1.1 2-1.7 3.4-1.8l13.2-1.3-.2-1.3c0-.2-2.4-13.5 4.5-23.2-.7 4.7.2 9.5 2.6 13.6 2.8 4.7 8.9 10.7 22.1 12.4 4.2.5 8.4.9 12.6.8 40.6-1 51.6-8.4 53.3-27l15.7 1.5c-1.7 7.8-4.1 15.1-7.4 21.7-10 19.9-29.3 31.9-51.9 31.9z" class="st4" fill="#e09c5c"/><path id="path6152" d="M1630.6 553.9c13 0 25.9-4 37.2-11.6l1.5-1 .3 1.8c0 .3 1.2 6.4 7.5 8 4.4 1.1 8 1.6 11.1 1.6 7.2 0 11.1-2.7 11.9-8.4 1.6-11 0-15.7-1.6-17.7-.9-1.1-2-1.7-3.4-1.8l-13.2-1.3.2-1.3c0-.2 2.4-13.5-4.5-23.2.7 4.7-.2 9.5-2.6 13.6-2.8 4.7-8.9 10.7-22.1 12.4-4.2.5-8.4.9-12.6.8-40.6-1-51.6-8.4-53.3-27l-15.7 1.5c1.7 7.8 4.1 15.1 7.4 21.7 10 19.9 29.3 31.9 51.9 31.9z" fill="#6e5a3d"/><path stroke-miterlimit="10" id="path6154" d="M1484 544.4v22.7c0 6.6.6 10.7 9 10.7h10.1c3.5 0 11.9 1.2 11.3-13.1-.6-14.3-.6-19.1-.6-19.1" class="st87" fill="#e09c5c" stroke="#946f3a" stroke-width="2.38770008" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" id="path6160" d="M1460.2 515.2c-13.7.6-21-3.6-22.1-14.3-.6-6 5.4-13.1 8.4-14.3 3-1.2 3 .6.6 3s-10.7 21.5 11.9 20.3" class="st87" fill="#e09c5c" stroke="#946f3a" stroke-width="2.38770008" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" id="path6162" d="M1581.8 460.8c-.1-.8-.4-1.7.2-2.3.6-.6 1.1-.5 2-.5 5.8.1 21.1.2 24 .4 3.6.1 3.1 2.9 1.6 6-3.9 7.6-6.4 11.5-14.2 11.4-6.5-.1-12.4-6.2-13.6-15z" fill="#33281d" stroke="#3b3024" stroke-width="2.38770008" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" id="path6164" d="M1609.5 464.4c-3.9 7.6-6.4 11.5-14.2 11.4-1 0-2-.2-3-.5-.1-.9-.2-1.7-.2-2.6 0-5.6 2.2-10.7 5.8-14.5 4.5.1 8.6.1 9.9.2 3.7.1 3.3 2.9 1.7 6z" fill="#693131" stroke="#3b3024" stroke-width="2.38770008" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" id="path6166" d="M1680.4 515.2c13.7.6 21-3.6 22.1-14.3.6-6-5.4-13.1-8.4-14.3-3-1.2-3 .6-.6 3s10.7 21.5-11.9 20.3" class="st86" fill="#876a4d" stroke="#3b3024" stroke-width="2.38770008" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" id="path6168" d="M1488.2 439.4c-5.4-8.4-13.7-10.7-20.9-8.4-7.2 2.4-10.7 11.3-10.1 22.1.6 10.7.6 17.9 0 22.7-.6 4.8 1.8 9 7.8 9s7.2-4.2 7.2-4.2 1.8 2.4 5.4 2.4c3.6 0 10.1-2.4 10.7-10.1.6-7.7.6-9 .6-9" class="st85" fill="#fbc16c" stroke="#946f3a" stroke-width="2.38770008" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" id="path6170" d="M1595 506.2c-6.8 6.9-23.1 8.1-33.8 7.3-10.7-.8-8.5-7.1-8.5-16.1 0-5.5 4.3-6.5 10.8-7.3 6.5-.8 19-.4 25.2-4.8" class="st86" fill="#876a4d" stroke="#3b3024" stroke-width="2.38770008" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" id="path6172" d="M1548.5 478.8c14.9 0 23.9-1.8 29.2-2.4 5.4-.6 13.1 1.2 13.1 9.6 0 9.6-3.6 12.5-14.3 14.3-10.7 1.8-21.5 1.8-30.4 1.2" class="st85" fill="#fbc16c" stroke="#946f3a" stroke-width="2.38770008" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" id="path6174" d="M1623.7 467.4c-8.1 8.1-15.5 9-23.9 6-8.4-3-10.7-10.1-10.1-15.5.6-5.4 4.2-6 6-1.2 1.8 4.8 3 7.8 10.7 9 4.2.6 7.2-2.4 10.7-5.4 3.6-3 6-3 7.8-.6 2.1 2.8 1.2 5.3-1.2 7.7z" class="st91" fill="#fff" stroke="#7d7d65" stroke-width="2.38770008" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" id="path6176" d="M1515.1 456.1s-2.4-6-3.6-10.1c-1.2-4.2-1.8-7.2 1.8-8.4 3.6-1.2 6 1.2 7.8 5.4 1.8 4.2 3.6 10.1 3.6 10.1" class="st92" fill="none" stroke="#402f19" stroke-width="2.98460007" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" id="path6178" d="M1557 460.8c.1-.8.4-1.7-.2-2.3-.6-.6-1.1-.5-2-.5-5.8.1-21.1.2-24 .4-3.6.1-3.1 2.9-1.6 6 3.9 7.6 6.4 11.5 14.2 11.4 6.5-.1 12.5-6.2 13.6-15z" fill="#544024" stroke="#946f3a" stroke-width="2.38770008" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" id="path6180" d="M1632.1 440c-1.8-7.8 1.2-13.7 9.6-15.5 8.4-1.8 16.7 1.8 21.5 17.3 4.8 15.5 9.6 19.1 4.2 23.9-5.4 4.8-10.1 5.4-14.9 1.8 0 0-4.2 4.2-8.4.6s-4.2-7.8-4.2-7.8" class="st86" fill="#876a4d" stroke="#3b3024" stroke-width="2.38770008" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" id="path6182" d="M1605.4 452c0-6.9.7-17.9 6-18.5 5.3-.6 6.9 2.8 6.4 8.8-.5 6-1 11.9-1 11.9" class="st92" fill="none" stroke="#402f19" stroke-width="2.98460007" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" id="path6184" d="M1529.3 464.4c3.9 7.6 6.4 11.5 14.2 11.4 1 0 2-.2 3-.5.1-.9.2-1.7.2-2.6 0-5.6-2.2-10.7-5.8-14.5-4.5.1-8.6.1-9.9.2-3.7.1-3.3 2.9-1.7 6z" fill="#693131" stroke="#381916" stroke-width="2.38770008" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" id="path6186" d="M1557 460.8c.1-.8.4-1.7-.2-2.3-.6-.6-1.1-.5-2-.5-5.8.1-21.1.2-24 .4-3.6.1-3.1 2.9-1.6 6 3.9 7.6 6.4 11.5 14.2 11.4 6.5-.1 12.5-6.2 13.6-15z" fill="none" stroke="#3b3024" stroke-width="2.38770008" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" id="path6188" d="M1504.9 467.4c8.1 8.1 15.5 9 23.9 6 8.4-3 10.7-10.1 10.1-15.5-.6-5.4-4.2-6-6-1.2-1.8 4.8-3 7.8-10.7 9-4.2.6-7.2-2.4-10.7-5.4-3.6-3-6-3-7.8-.6-2.1 2.8-1.2 5.3 1.2 7.7z" class="st91" fill="#fff" stroke="#7d7d65" stroke-width="2.38770008" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" id="path6190" d="M1490 431.3c-7.1-5.2-8.4-17 5.3-18.6 2.7-.3 8-.2 8-.2s6.4-11.5 11.7-11c5.3.5 5.5 5.2 4.3 7.5 0 0 5.9.2 4.4 6.9-.6 2.8-3.6 4.2-3.6 4.2" class="st85" fill="#fbc16c" stroke="#946f3a" stroke-width="2.38770008" stroke-linecap="round" stroke-linejoin="round"/><path id="path6192" d="M1499.9 459.7l-3.7 1.4c-.9.4-2-.1-2.3-1l-.1-.3c-.4-.9.1-2 1-2.3l3.7-1.4c.9-.4 2 .1 2.3 1l.1.3c.4.9-.1 1.9-1 2.3z" class="st31" fill="#e68a4c"/><path id="path6194" d="M1630.2 459.7l3.7 1.4c.9.4 2-.1 2.3-1l.1-.3c.4-.9-.1-2-1-2.3l-3.7-1.4c-.9-.4-2 .1-2.3 1l-.1.3c-.4.9.1 1.9 1 2.3z" fill="#805945"/><path stroke-miterlimit="10" id="path6196" d="M1592.7 412.4c.3-.6.7-1.3.9-2" class="st96" fill="none" stroke="#fbd7a3" stroke-width="2.38770008" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" id="path6198" d="M1588.8 417.1c.8-.7 1-.7 1.7-1.6" class="st96" fill="none" stroke="#fbd7a3" stroke-width="2.38770008" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" id="path6200" d="M1576.3 423c2.5-.6 4.9-1.4 7-2.4" class="st96" fill="none" stroke="#fbd7a3" stroke-width="2.38770008" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" id="path6202" d="M1560.5 424.8c1.7.1 3.5 0 5.4-.2 1.3-.1 2.6-.3 3.9-.5" class="st96" fill="none" stroke="#fbd7a3" stroke-width="2.38770008" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" id="path6204" d="M1533 419.3c6.5.6 11.4 2.2 16.3 3.6" class="st96" fill="none" stroke="#fbd7a3" stroke-width="2.38770008" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" id="path6206" d="M1627.4 425.2c.7.5 1.4.9 2.1 1.5" class="st97" fill="none" stroke="#b58e67" stroke-width="2.38770008" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" id="path6208" d="M1621.5 422.2c.9.4 1.9.8 2.8 1.3" class="st97" fill="none" stroke="#b58e67" stroke-width="2.38770008" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" id="path6210" d="M1607.9 419.7c2.4.1 4.8.3 7.3.7" class="st97" fill="none" stroke="#b58e67" stroke-width="2.38770008" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" id="path6212" d="M1656.5 544.4v22.7c0 6.6-.6 10.7-9 10.7h-10.1c-3.5 0-11.9 1.2-11.3-13.1.6-14.3.6-19.1.6-19.1" fill="#6e5a3d" stroke="#3b3024" stroke-width="2.38770008" stroke-linecap="round" stroke-linejoin="round"/></g><g id="g6532" transform="translate(-1343.3836 -75.800003)"><circle stroke-miterlimit="10" id="circle6534" r="103.3" cy="500.79999" cx="1949" fill="#4a77ab" stroke="#132137" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/><circle id="circle6536" r="74.699997" cy="500.79999" cx="1949" class="st16" fill="#51a1b5"/><g id="g6538"><path stroke-miterlimit="10" id="path6540" d="M2005.2 459.7c3.8 9.9 14.9 9.6 29.9 4.9 3.4-1.1 6.5-2.1 9.3-3.1-3.4-8.3-7.9-16-13.2-23-18.9 5.2-29.4 12.3-26 21.2z" fill="#75bd8c" stroke="#132137" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" id="path6542" d="M2017 544.7c-5.9 11 .3 18.8 10.9 22.7 7.6-9 13.7-19.4 17.9-30.6-10.8-.8-24.5-.1-28.8 7.9z" class="st140" fill="#e0b779" stroke="#132137" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" id="path6544" d="M2003.9 420.2c.4-2.2.5-4.4.5-6.5-17.8-11.3-39.3-17.3-62-15.9-19 1.2-36.5 7.5-51.2 17.5-.4 12.8 2.4 21.8 13.8 25 15.7 4.4 26.4-.3 26.4-.3s2.1 12.3 23 13.1c20.9.8 20.9-14.8 20.9-14.8s25 3.3 28.6-18.1z" class="st140" fill="#e0b779" stroke="#132137" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/></g><path stroke-miterlimit="10" id="path6546" d="M2001.9 491.9c.4 8.1-3.7 14-13.6 17.7-9.8 3.8-20 4.2-32-6.9-12-11.1-38.3-23.9-61-20.5-28.8 4.3-36.6 23.5-36.6 23.5-1.9-2.2-5.5-6.1-12.9-9.8-.2 3.8-.1 7.6.1 11.4 3.6 56.9 52.7 100.1 109.7 96.5 6.3-.4 12.4-1.4 18.3-2.8-2.6-39.5-19.3-67.9-19.3-67.9 13.7 5.7 27.8 5.7 45.9-2.8 18.1-8.5 23.6-24.6 20.4-38-3.3-13.4-19.3-8.5-19-.4z" fill="#75bd8c" stroke="#1c3b28" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/><circle stroke-miterlimit="10" id="circle6548" r="9" cy="510.89999" cx="1898.9" class="st142" fill="#51a1b5" stroke="#1c3b28" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/><circle id="circle6550" r="9" cy="479.5" cx="1970.5" fill="#4a77ab"/><path stroke-miterlimit="10" id="path6552" d="M1879.4 530.7c-2.2 4.6 0 11.8 10.8 14.3s24.7-.1 30.8-6.5c6.5-6.9 8.8-13.5 3.5-17.3-5.3-3.8-11.3.4-14.3 4.7s-10.1 4.7-17.7 1.8c-7.5-2.9-10.5-2.6-13.1 3z" class="st142" fill="#51a1b5" stroke="#1c3b28" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" id="path6554" d="M1956.1 381.4c8.2-3 11.7-4.5 14.4-5.7 2.7-1.2 5-.4 6.4 2.4 1.3 2.8-.8 5.7-6 7.7-5.3 2-13 5-13 5" class="st25" fill="#fbc16c" stroke="#946f3a" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" id="path6556" d="M1950.6 411.4c.1 5.7-1.9 11.2 4.1 11.3 5.9.1 6.2-3.1 6.2-5.9 0-2.8-.1-4.7-.1-4.7" class="st26" fill="#e09c5c" stroke="#946f3a" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" id="path6558" d="M1913.2 410.2c4.9 3.8 12.6 2.5 14.2.1 1.6-2.4-.4-3.4-2.3-2.3s-7.2 1.6-9.7.2c-2.5-1.3-3.8.8-2.2 2z" class="st25" fill="#fbc16c" stroke="#946f3a" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" id="path6560" d="M1921.1 396c0 10.2 2.3 18.5 12 19s17.9-.1 23.8-.9c5.9-.8 11.1-3.5 10.9-13.7-.1-10.2-.1-25.2-.1-25.2s8.4 3 15.6-.8c7.7-4 9.7-6.7 11-8.8 1.1-1.9-1.2-7.9-6.1-4.1-4.9 3.8-10.1 6.1-15.2 3.9-5.1-2.2-7.2-5-9.9-9.3-2.5-3.9-7.7-8.1-20.6-7.7-14 .5-21.9 13-21.6 25.1.3 12.1.2 22.5.2 22.5z" class="st25" fill="#fbc16c" stroke="#946f3a" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><path id="path6562" d="M1939.7 414.1c-2.2 0-4.4-.1-6.6-.1-7.6-.3-11-5.9-11-18v-5.8c6.6-.2 11.3 3.5 11.6 8 .5 7.5 6.8 10 15.7 10h5.2c4 0 8.7 0 11.6-2.2-1.6 5.2-5.7 6.5-9.4 7-3.8.6-9.8 1.1-17.1 1.1z" class="st4" fill="#e09c5c"/><path stroke-miterlimit="10" id="path6564" d="M1929.4 357.9c-2.1-7-10.8-9.6-15.6-3.8-4.8 5.8-9.9 17.9-6.3 21.1 3.6 3.2 5.2 2.3 7.1 1.5 0 0 2.3 4.1 6.9.9 4.5-3.2 6-9.6 6-9.6" class="st25" fill="#fbc16c" stroke="#946f3a" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" id="path6566" d="M1938 378c5.7 4.2 11.2 4.4 14.7 1.8 3.4-2.5 5.6-5.2 4-6.9-1.6-1.7-3.5-.1-5.5 1.3-2 1.4-5.1 1.8-7.9.1-2.8-1.7-5-2.2-6.3-.8-1.4 1.5-.5 3.4 1 4.5z" fill="#fbe6c6" stroke="#668794" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><path id="path6568" d="M1940.7 364.8c0 3.8-.2 4.2-1.2 4.2s-1.3-.5-1.3-4.2c0-4.6.3-5.1 1.3-5.1s1.2.6 1.2 5.1z"/><path stroke-miterlimit="10" id="path6570" d="M1926 380.7c-8.2-3-8.1-3-10.7-4.2-2.6-1.2-5-.4-6.4 2.4-1.3 2.8.8 5.7 6 7.7 5.3 2 9.4 3.5 9.4 3.5" class="st25" fill="#fbc16c" stroke="#946f3a" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" id="path6572" d="M1928.4 412.5c.1 5.7-1.9 11.2 4.1 11.3 5.9.1 6.2-3.1 6.2-5.9 0-2.8-.1-4.7-.1-4.7" class="st26" fill="#e09c5c" stroke="#946f3a" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><g id="g6574"><path stroke-miterlimit="10" id="path6576" d="M1930.3 478.8l-54.2 14.5c-6.4 1.7-13-2.1-14.7-8.5l-.3-1c-1.7-6.4 2.1-13 8.5-14.7l54.2-14.5c6.4-1.7 13 2.1 14.7 8.5l.3 1c1.7 6.4-2.2 13-8.5 14.7z" class="st10" fill="#fff" stroke="#7d7d65" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" id="path6578" d="M2002.5 559.5l-32.9 8.8c-5.6 1.5-11.4-1.9-12.9-7.4-1.5-5.6 1.9-11.4 7.4-12.9l32.9-8.8c5.6-1.5 11.4 1.9 12.9 7.4 1.6 5.6-1.8 11.4-7.4 12.9z" class="st10" fill="#fff" stroke="#7d7d65" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" id="path6580" d="M2037.3 515.3l-10.8 2.9c-5.6 1.5-11.4-1.9-12.9-7.4-1.5-5.6 1.9-11.4 7.4-12.9l10.8-2.9c5.6-1.5 11.4 1.9 12.9 7.4 1.5 5.6-1.8 11.4-7.4 12.9z" class="st10" fill="#fff" stroke="#7d7d65" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/></g><path id="path6582" d="M1933.9 372.1l-2.9-.1c-1 0-1.8-.9-1.8-1.9v-.4c0-1 .9-1.8 1.9-1.8l2.9.1c1 0 1.8.9 1.8 1.9v.4c0 1.1-.9 1.9-1.9 1.8z" class="st31" fill="#e68a4c"/><path stroke-miterlimit="10" id="path6584" d="M1986.7 443.9c7.1-1.4 15.8-4.7 20.3-12" class="st36" fill="none" stroke="#51a1b5" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" id="path6586" d="M1883.3 432.1c3.7 9.5 9.5 14.2 22.5 16" class="st36" fill="none" stroke="#51a1b5" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/><circle id="circle6588" r="2.0999999" cy="424.70001" cx="2009.9" class="st16" fill="#51a1b5"/><path stroke-miterlimit="10" id="path6590" d="M1949 587.1c-27.7 0-52.4-13.1-68.2-33.4" fill="none" stroke="#66a77c" stroke-width="12" stroke-linecap="round" stroke-linejoin="round"/><g id="g6592"><path d="M1934.9 271.4v30.3h-13.5l22.6 27.6 22.6-27.6h-13.4v-30.3z" stroke-miterlimit="10" id="polygon6594" class="st80" fill="#587faa" stroke="#000" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><path d="M1939.7 275.79999v10.5" stroke-miterlimit="10" id="line6596" class="st76" fill="none" stroke="#fff" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/><path d="M1939.7 293.39999V301.5" stroke-miterlimit="10" id="line6598" class="st76" fill="none" stroke="#fff" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/></g></g><g id="g6600" transform="translate(-1343.3836 -75.800003)"><g id="g6602"><path id="path6604" d="M1784.9 522.9c0-.6-.4-1-1-1h-29.3v-16.3h29.3c.6 0 1-.4 1-1v-11.4l25.1 20.5-25.1 20.5v-11.3z" class="st143" fill="#f1614e"/><path id="path6606" d="M1785.9 495.4l22.5 18.4-22.5 18.4v-9.3c0-1.1-.9-2-2-2h-28.3v-14.3h28.3c1.1 0 2-.9 2-2v-9.2m-2-4.3v13.5h-30.3v18.3h30.3v13.5l27.6-22.6-27.6-22.7z" class="st144" fill="#9c3b2d"/></g><path d="M1757.9 509.10001h10.6" stroke-miterlimit="10" id="line6608" class="st79" fill="#f47c53" stroke="#fdbc61" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/><path d="M1775.6 509.10001h8" stroke-miterlimit="10" id="line6610" class="st79" fill="#f47c53" stroke="#fdbc61" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/></g><g id="g6612" transform="translate(-1343.3836 -75.800003)"><g id="g6614"><path id="path6616" d="M2084.4 419.8l23.3-17.7c.2-.2.3-.4.4-.7 0-.3 0-.5-.2-.7l-6.9-9 32.4 1.1-7.5 31.5-6.9-9c-.2-.3-.5-.4-.8-.4-.2 0-.4.1-.6.2l-23.3 17.7-9.9-13z" class="st143" fill="#f1614e"/><path id="path6618" d="M2103.1 392.7l29 1-6.7 28.3-5.6-7.4c-.3-.4-.8-.7-1.3-.8h-.3c-.4 0-.9.1-1.2.4l-22.5 17.1-8.7-11.4 22.5-17.1c.9-.7 1-1.9.4-2.8l-5.6-7.3m-4.2-2.1l8.2 10.7-24.1 18.3 11.1 14.6 24.1-18.3 8.2 10.7 8.3-34.7-35.8-1.3z" class="st144" fill="#9c3b2d"/></g><path d="M2089.1001 420.5l8.3999-6.29999" stroke-miterlimit="10" id="line6620" class="st79" fill="#f47c53" stroke="#fdbc61" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/><path d="M2103.2 409.89999L2109.6001 405" stroke-miterlimit="10" id="line6622" class="st79" fill="#f47c53" stroke="#fdbc61" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/></g><path stroke-miterlimit="10" id="path6624" d="M47.9164 462.8c13.3-4.1 19.9.8 23.6 7.7 8.2 15.4-1.9 21.1-28.8 31.2-27 10.1-40.4 15.2-40.4 15.2l-1.3-56.9c14.7-5.1 25.3 2.9 27 8.8-.1.1 9.5-3.9 19.9-6" fill="#587faa" stroke="#000" stroke-width="2"/><path id="path6626" d="M2.4164 474.9c2.1-.4 3.9-.6 5.4-.6 4.6 0 8.1 1.5 10 8.6l.5 2 2-.6c.1 0 10.4-3.4 22.4-7.4 2.5-.8 4.9-1.3 7.1-1.3 7.7 0 12.2 5.3 13.3 15.9-5.1 3.1-12.6 6.1-22 9.6l-37.8 14.2-.9-40.4z" class="st82" fill="#2d3f68"/><path stroke-miterlimit="10" id="path6628" d="M6.0164 564.9l12.2 25.7s7.2 5.9 11.4-3.8l-15.6-27-8 5.1z" class="st146" fill="#191b22" stroke="#000" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><g id="g6630" transform="translate(-1343.3836 -75.800003)"><path id="path6632" d="M1346.3 567.9c6.1-2.8 11.8-4.2 16.9-4.2 11.8 0 19.1 7.9 19.3 21.1 0 .3.2.6.4.8.2.1.4.2.6.2h.3s2-.6 4.8-.6c5.8 0 13.5 2.3 17 13.4 5.1 15.9-14.6 25.5-29 32.5l-.8.4c-14.1 6.9-20.2 9.4-28.7 13l-.7.3-.1-76.9z" class="st147" fill="#587faa"/><path id="path6634" d="M1363.2 562.6v2c11.4 0 18.1 7.3 18.3 20.1 0 .6.3 1.2.8 1.6.3.3.8.4 1.2.4.2 0 .4 0 .6-.1 0 0 1.9-.5 4.6-.5 5.5 0 12.7 2.2 16.1 12.7 4.9 15.1-14.4 24.4-28.5 31.3l-.8.4c-13.7 6.7-19.8 9.3-27.9 12.7l-.3-74.7c5.7-2.6 11.1-3.9 15.9-3.9v-2m0 0c-5.3 0-11.3 1.5-17.9 4.6l.3 78.9c9.6-4.1 15.5-6.5 30.7-13.9 14.6-7.1 35.8-17.1 30.3-34.1-3.9-12-12.5-14.1-18-14.1-3 0-5.1.6-5.1.6-.3-14-8.2-22-20.3-22z"/></g><path id="path6636" d="M3.9164 509.1c1.1-.1 2.2-.2 3.2-.2 12.9 0 16.5 10.9 17.2 20l.3 3.3 2.8-1.8c.1 0 6.3-4 12.9-4 7.3 0 12.3 4.8 14.9 14.4-6.1 5.5-15.1 9.9-22.4 13.5l-.7.4c-13.7 6.7-19.8 9.3-27.9 12.7l-.3-58.3z" class="st82" fill="#2d3f68"/><g id="g6638" transform="translate(-1343.3836 -75.800003)"><path id="path6640" d="M1346.2 707.5c7-2.8 13.8-4.3 19.8-4.3 13.2 0 21.1 7 21.6 19.3.4 8-9.2 14.2-9.3 14.2-.5.3-.6.9-.3 1.3.2.3.5.5.9.5.2 0 .3 0 .5-.1s16.6-8.5 28.6-14.3c4-1.9 8.2-2.9 12.1-2.9 7.4 0 13.4 3.4 16.5 9.2 4.6 8.8-2.8 14.9-3.1 15.2-.4.3-.5.8-.2 1.3.2.3.5.5.9.5.1 0 .2 0 .3-.1 0 0 3.3-1.2 7.6-1.2 5.6 0 13.3 2 18.1 11.7 8.5 16.9-4.7 24.5-12.6 29-9 5.2-38.1 23.4-39.8 24.4l-61.1 24.7-.5-128.4z" class="st147" fill="#587faa"/><path id="path6642" d="M1366 702.1v2c6 0 11.1 1.6 14.6 4.5 3.8 3.1 5.8 7.8 6.1 13.9.3 7.4-8.8 13.3-8.9 13.4-.9.6-1.2 1.8-.7 2.7.4.6 1 1 1.7 1 .3 0 .6-.1.9-.2.2-.1 16.5-8.5 28.6-14.3 3.8-1.9 7.9-2.8 11.7-2.8 7 0 12.7 3.2 15.6 8.7 4.2 8.1-2.6 13.7-2.8 13.9-.8.6-1 1.7-.5 2.5.4.6 1 1 1.7 1 .2 0 .5 0 .7-.1 0 0 3.1-1.1 7.3-1.1 7.7 0 13.5 3.7 17.2 11.1 7.4 14.8-2.4 22.1-12.2 27.7-8.9 5.1-37.4 22.9-39.7 24.4l-59.7 24.1-.4-126.3c6.6-2.6 13.1-4 18.8-4v-2.1m0 0c-6.3 0-13.5 1.6-20.9 4.7l.4 130.6 62.6-25.3s30.5-19.1 39.8-24.5c7.7-4.4 21.8-12.6 13-30.3-5-10-13-12.2-19-12.2-4.6 0-7.9 1.3-7.9 1.3s8.4-6.7 3.4-16.4c-3.3-6.3-9.8-9.8-17.3-9.8-4 0-8.3 1-12.6 3-12.2 5.9-28.6 14.3-28.6 14.3s10.2-6.5 9.8-15.1c-.6-13.8-9.9-20.3-22.7-20.3z"/></g><path id="path6644" d="M3.8164 646.2c1.5-.3 2.9-.4 4.2-.4 4.5 0 8.1 1.5 10.4 4.2 2.5 2.9 3.5 7.2 2.8 12.2l-.3 2 2 .3s3 .5 4.7 3.1c1.3 2 1.6 4.9.7 8.4l-1 4 3.7-1.6c.2-.1 16.1-7.1 25.7-11.7 2.3-1.1 5.1-2.7 7.5-3.5 4.9-1.7 10.7 1.2 12.5 3.6 2 2.7 5.8 11.9 1.2 16.6l-12.5 9.8 9.3-3.9c.1-.1 13.1-7.5 22.9-7.5 2.3 0 4.1.4 5.4 1.3 6.6 4.1 11.3 10.7 12.7 17.7-3.2 4.5-8.5 7.6-12.1 9.7-8.9 5.1-37.4 22.9-39.7 24.4l-59.7 24.1-.4-112.8z" class="st82" fill="#2d3f68"/><path d="M30.1164 786l13.1 18.6h-24.5z" stroke-miterlimit="10" id="polygon6646" class="st146" fill="#191b22" stroke="#000" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><g id="g6648" transform="translate(-1343.3836 -75.800003)"><path id="path6650" d="M1346.3 879.4l-.5-70.5c11.7-7 21.4-10.6 28.7-10.6 7.6 0 12.3 3.9 14 11.5.1.3.3.6.6.7.1 0 .2.1.4.1s.4-.1.6-.2c.1-.1 12.8-9.1 25.8-9.1 7.3 0 13.3 2.9 17.9 8.5 5.5 6.8 7.7 13.4 6.5 19.4-1.9 9.1-10.8 15.5-18 19.3-4.2 2.2-11.1 5.7-19 9.7-14.6 7.4-32.7 16.7-40.6 21.1h-16.4z" class="st147" fill="#587faa"/><path id="path6652" d="M1374.4 799.3c7.1 0 11.5 3.6 13 10.7.1.7.6 1.2 1.2 1.4.2.1.5.1.7.1.4 0 .8-.1 1.2-.4.1-.1 12.5-8.9 25.2-8.9 7 0 12.8 2.7 17.2 8.1 5.3 6.6 7.4 12.8 6.3 18.6-1.9 9.2-11.8 15.6-17.5 18.6-4.2 2.2-11 5.7-18.9 9.7-14.5 7.4-32.4 16.5-40.5 21h-15l-.5-68.9c11.3-6.6 20.6-10 27.6-10m0-2c-7.1 0-16.8 3.3-29.7 11l.5 72h17.5c11.8-6.7 47.4-24.5 59.8-31 12.4-6.5 28.3-20 11.9-40.2-5.4-6.6-12.1-8.9-18.7-8.9-13.5 0-26.4 9.3-26.4 9.3-1.5-7.3-6.2-12.2-14.9-12.2z"/></g><path id="path6654" d="M3.8164 802.6l-.4-55.6c8.8-4 15.1-5.8 19.6-5.8 4.5 0 9.8 1.5 10.9 13.2l.3 2.7 2.5-1c.8-.3 20.3-8.4 28-12.3 1.7-.9 4.9-1.8 8.5-1.8 6.1 0 16.4 2.6 18.2 20-3.8 4.6-9.2 7.9-13.1 10-4.2 2.2-11.1 5.7-19 9.7-14.5 7.4-32.4 16.5-40.5 21h-15z" class="st82" fill="#2d3f68"/><path stroke-miterlimit="10" id="path6656" d="M262.5164 805c120.1-133.6 245.9-175.3 283.3-185.2-11.4-12.4-24.7-17.1-37.5-28.3l-.2-7.2c-142.4 45.1-254 137.7-326 219 0 0-.2.6-.7 1.7h81.1z" class="st146" fill="#191b22" stroke="#000" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><g id="g6658" transform="translate(-1343.3836 -75.800003)"><path id="path6660" d="M1537.3 879.8c40.6-45 85.7-85.2 134.2-119.5 59.5-42.1 122.3-73.7 186.7-94.1 10.1 9.2 19.9 18.9 29.1 28.8-38.1 10.4-163.2 52.8-281.9 184.8h-68.1z" class="st82" fill="#2d3f68"/><path id="path6662" d="M1858 667.3c9.6 8.7 18.8 17.8 27.5 27.2-20.7 5.7-59.7 18.8-107.9 45.5-63.1 35-121.2 81.7-172.6 138.8h-65.4c40.1-44.3 84.7-83.9 132.5-117.7 59.3-41.9 121.8-73.4 185.9-93.8m.1-2.1c-140.4 44.4-250.9 135.2-323 215.6h70.8c120.1-133.6 245.9-175.3 283.3-185.2-9.7-10.6-19.9-20.7-30.6-30.4h-.5z"/></g><circle stroke-miterlimit="10" id="circle6664" r="56.5" cy="215.40001" cx="893.21649" class="st1" fill="none" stroke="#95b893" stroke-width="2"/><g id="g6666" transform="translate(-1343.3836 -75.800003)"><path id="path6668" d="M2236.6 202.6c48.8 0 88.6 39.7 88.6 88.6 0 48.9-39.7 88.6-88.6 88.6-48.9 0-88.6-39.8-88.6-88.6s39.7-88.6 88.6-88.6m0-3.3c-50.7 0-91.8 41.1-91.8 91.8 0 50.7 41.1 91.8 91.8 91.8 50.7 0 91.8-41.1 91.8-91.8 0-50.7-41.1-91.8-91.8-91.8z" class="st148" fill="#95b893"/></g><circle stroke-miterlimit="10" id="circle6670" r="46.299999" cy="410" cx="1059.1165" class="st149" fill="none" stroke="#95b893" stroke-width="3.25040007"/><g id="g6672" transform="translate(-1343.3836 -75.800003)"><path id="path6674" d="M2402.5 414.1c39.5 0 71.7 32.2 71.7 71.7s-32.2 71.7-71.7 71.7-71.7-32.2-71.7-71.7 32.1-71.7 71.7-71.7m0-3.3c-41.4 0-75 33.6-75 75s33.6 75 75 75 75-33.6 75-75-33.6-75-75-75z" class="st148" fill="#95b893"/></g><circle stroke-miterlimit="10" id="circle6676" r="51.099998" cy="569.60004" cx="893.21649" class="st149" fill="none" stroke="#95b893" stroke-width="3.25040007"/><circle stroke-miterlimit="10" id="circle6678" r="94.699997" cy="569.60004" cx="893.21649" class="st149" fill="none" stroke="#95b893" stroke-width="3.25040007"/><circle stroke-miterlimit="10" id="circle6680" r="76.099998" cy="569.60004" cx="893.21649" class="st149" fill="none" stroke="#95b893" stroke-width="3.25040007"/><circle stroke-miterlimit="10" id="circle6688" r="11.7" cy="523.5" cx="810.21649" fill="#51a1b5" stroke="#31446e" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/><circle stroke-miterlimit="10" id="circle6690" r="11.7" cy="405.90002" cx="985.0163" fill="#a7658d" stroke="#4b2254" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/><circle stroke-miterlimit="10" id="circle6692" r="8.1000004" cy="445.29999" cx="1090.6165" fill="#a8c875" stroke="#4b2254" stroke-width="2.75029993" stroke-linecap="round" stroke-linejoin="round"/><circle stroke-miterlimit="10" id="circle6694" r="11.7" cy="617.10004" cx="951.71649" class="st29" fill="#fbe6c6" stroke="#668794" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/><circle id="circle6696" r="7" cy="617.40002" cx="956.31635" class="st30" fill="#668794"/><circle stroke-miterlimit="10" id="circle6698" r="19.9" cy="280.80002" cx="829.71649" class="st29" fill="#fbe6c6" stroke="#668794" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/><circle id="circle6700" r="11.9" cy="286.10001" cx="823.91644" class="st30" fill="#668794"/><circle stroke-miterlimit="10" id="circle6702" r="14.2" cy="499.70001" cx="958.61639" fill="#a34c4c" stroke="#381916" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/><circle id="circle6704" r="2.5999999" cy="500.40002" cx="951.61639" class="st39" fill="#381916"/><circle id="circle6706" r="2.5999999" cy="492.29999" cx="954.61639" class="st39" fill="#381916"/><circle id="circle6708" r="2.5999999" cy="493.60004" cx="962.5163" class="st39" fill="#381916"/><ellipse stroke-miterlimit="10" id="ellipse6710" ry="8.2004271" rx="6.6003442" cy="1128.4603" cx="-116.2824" class="st84" transform="rotate(-73.770504)" fill="#ad6a3b" stroke="#663f09" stroke-width="1.65338624"/><ellipse stroke-miterlimit="10" id="ellipse6712" ry="4.4000001" rx="5.4000001" cy="1138.6377" cx="198.54999" class="st84" transform="rotate(-58.7950001)" fill="#ad6a3b" stroke="#663f09" stroke-width="1.65330005"/><ellipse stroke-miterlimit="10" id="ellipse6714" ry="4.8000002" rx="4.4000001" cy="717.47546" cx="892.77887" class="st84" transform="rotate(-18.4680007)" fill="#ad6a3b" stroke="#663f09" stroke-width="1.65330005"/><circle stroke-miterlimit="10" id="circle6716" r="14.2" cy="234.09999" cx="949.71649" fill="#ce8c59" stroke="#381916" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/><circle id="circle6718" r="2.5999999" cy="234.7" cx="942.71649" class="st39" fill="#381916"/><circle id="circle6720" r="2.5999999" cy="226.7" cx="945.71649" class="st39" fill="#381916"/><circle id="circle6722" r="2.5999999" cy="227.99998" cx="953.71649" class="st39" fill="#381916"/><g id="g6724" transform="translate(-1343.3836 -75.800003)"><path stroke-miterlimit="10" id="path6726" d="M1606.2 856.8c19-20 38.1-34.7 38.1-34.7" class="st153" fill="#ce8c59" stroke="#587faa" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" id="path6728" d="M1621.3 816.8c21-19.5 42.5-34.2 42.5-34.2" class="st153" fill="#ce8c59" stroke="#587faa" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" id="path6730" d="M1675.5 791.4c22.5-19 42-30.8 42-30.8" class="st153" fill="#ce8c59" stroke="#587faa" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" id="path6732" d="M1717 743.5c22-15.1 42-23.9 42-23.9" class="st153" fill="#ce8c59" stroke="#587faa" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" id="path6734" d="M1768.8 733.2c23.4-14.7 51.3-25.9 51.3-25.9" class="st153" fill="#ce8c59" stroke="#587faa" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" id="path6736" d="M1792.7 703.9c23.9-11.7 48.4-20.5 48.4-20.5" class="st153" fill="#ce8c59" stroke="#587faa" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" id="path6738" d="M1844 697.6c14.7-6.8 25.4-9.8 25.4-9.8" class="st153" fill="#ce8c59" stroke="#587faa" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" id="path6740" d="M1554.4 879.3c21-23 42-41 42-41" class="st153" fill="#ce8c59" stroke="#587faa" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/></g><g id="g6742" transform="translate(-1343.3836 -75.800003)"><g id="g6744"><path d="M2402.5 485.79999l-1.5 1.40002" stroke-miterlimit="10" id="line6746" class="st1" fill="none" stroke="#95b893" stroke-width="2"/><path d="M2398.2 489.89999L2309.7 575" stroke-miterlimit="10" id="line6748" fill="none" stroke="#95b893" stroke-width="2" stroke-dasharray="3.9,3.9"/><path d="M2308.3 576.40002l-1.5 1.39997" stroke-miterlimit="10" id="line6750" class="st1" fill="none" stroke="#95b893" stroke-width="2"/></g></g><g id="g6752" transform="translate(-1343.3836 -75.800003)"><g id="g6754"><path d="M2236.6001 550.70001v-2" stroke-miterlimit="10" id="line6756" class="st1" fill="none" stroke="#95b893" stroke-width="2"/><path d="M2236.6001 544.59998V295.20001" stroke-miterlimit="10" id="line6758" fill="none" stroke="#95b893" stroke-width="2" stroke-dasharray="4.0554,4.0554"/><path d="M2236.6 293.2v-2l1.3 1.5" stroke-miterlimit="10" id="polyline6760" class="st1" fill="none" stroke="#95b893" stroke-width="2"/><path d="M2240.3999 295.70001l111.5 130.79999" stroke-miterlimit="10" id="line6762" fill="none" stroke="#95b893" stroke-width="2" stroke-dasharray="3.9514,3.9514"/><path d="M2353.2 428l1.3 1.5" stroke-miterlimit="10" id="line6764" class="st1" fill="none" stroke="#95b893" stroke-width="2"/></g></g><g id="g6766" transform="translate(-1343.3836 -75.800003)"><circle stroke-miterlimit="10" id="circle6768" r="33.799999" cy="291.20001" cx="2236.6001" class="st83" fill="#ebb548" stroke="#663f09" stroke-width="3.30660009" stroke-linecap="round" stroke-linejoin="round"/><g id="g6770"><circle id="circle6772" r="3" cy="273.60001" cx="2218.8" class="st33" fill="#fff"/></g></g><g id="g6774" transform="translate(-1343.3836 -75.800003)"><circle stroke-miterlimit="10" id="circle6776" r="33.799999" cy="291.20001" cx="2236.6001" class="st83" fill="#ebb548" stroke="#663f09" stroke-width="3.30660009" stroke-linecap="round" stroke-linejoin="round"/><g id="g6778"><circle id="circle6780" r="3" cy="273.60001" cx="2218.8" class="st33" fill="#fff"/></g></g><circle id="circle6906" r="3.9000001" cy="445.29999" cx="1090.6165" fill="#b4dcf5"/></svg>
diff --git a/app/javascript/images/screen_hello.svg b/app/javascript/images/screen_hello.svg
new file mode 100644
index 000000000..7bcdd0afd
--- /dev/null
+++ b/app/javascript/images/screen_hello.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" height="803.09998" width="1197.8285" viewBox="0 0 1197.8284 803.09996" id="Layer_1"><path id="path6218" d="M419.21425 718.72051s1 40 2 51 3 16 20 17 41-2 50-4 16-6 14-29-4-51-4-51" class="st6" fill="#e09c5c" stroke="#946f3a" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6220" d="M504.21425 771.52051l-.1-.6c-1.5-5.7-4.5-7-8-6.3-4.8 1-6.1 7.7-6.9 16.7 0 .4-.1.8-.1 1.3l.7.3c.4-.1.9-.2 1.3-.3 5.9-1.2 10.9-3.4 13.1-11.1z" class="st2" fill="#fbc16c" stroke="#946f3a" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6222" d="M510.81425 399.72051c46-5 79-28 84-32 0 0-14-12-3-20s18 2 18 2 23.5-29.9 43.5-13.9c20 16 27.5 32.9 20.5 48.9s-52 72-147 85" class="st2" fill="#fbc16c" stroke="#946f3a" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6224" d="M239.81425 697.72051c-16 15-41 23-54 5s-4-26-7-30-21 8-13 31 54 48 97 14" class="st4" fill="#e09c5c"/><path id="path6226" d="M500.21425 361.82051s34.6 70.9 43.1 175.4c7.2 89 15 139-46 168s-142 24-180 25-78-4-88-47 .5-76.5.5-76.5 1.4-71.2-2.1-82.7-9.2-28.7-9.2-28.7-5.7 40.1-35.5 53.6c-29.8 13.6-56.1.8-53.9-36.5 0 0-25.5-42.6-37.600004-79.9-12.1-37.3 19.800004-73.9 78.300004-58.8 2-71 63.6-130.7 149.1-137.7 85.4-7.1 106.3 38.7 151.9 40.7 44 2 75-12 98-35s70-53 107-29c0 0 18-6 20 10s-7 16-12 19c0 0 7 22-7 25s-12-18-12-18-23-3-42 27-47.2 70.2-122.6 86.1c-16.1 1.4-29.5-3.9-29.5-3.9" class="st2" fill="#fbc16c" stroke="#946f3a" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6228" d="M259.81425 704.72051c0 23-4 53-5 64s3 22.4 21 23c28 1 82 5 87-12 6.3-21.6 5-58 0-70" class="st6" fill="#e09c5c" stroke="#946f3a" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6230" d="M295.01425 792.42051c.8-9.7 1.8-15.7 6.8-16.7s8.8 3.1 8.9 17.1" class="st2" fill="#fbc16c" stroke="#946f3a" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6232" d="M311.01425 792.42051c.8-9.7 1.8-15.7 6.8-16.7s8.8 3.1 8.9 17.1" class="st2" fill="#fbc16c" stroke="#946f3a" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6234" d="M326.81425 792.72051c.8-9.7 2-17 7-18s8.9 2.1 9 16" class="st2" fill="#fbc16c" stroke="#946f3a" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6236" d="M332.61425 746.52051h-15.4c-7.8 0-14.2-6.4-14.2-14.2 0-7.8 6.4-14.2 14.2-14.2h15.4c7.8 0 14.2 6.4 14.2 14.2 0 7.8-6.4 14.2-14.2 14.2z" fill="#fbc16c"/><path id="path6238" d="M127.01425 433.92051c7.3 9.1 20.6 38.2 19.8 61-.9 22.9 23.8 32.8 36.8 13 13-19.8 16.6-58.4 7.6-77.2-9-18.9-13.9-26-13.9-26s-4.9 9-17.5 10.8c-12.6 1.8-13-3.1-17.3-9.8 0 0 .6 7.4-10.6 11.5-11.2 4.2-14.8-5-14.8-5s2.7 12.7 9.9 21.7z" class="st4" fill="#e09c5c"/><path id="path6240" d="M309.31425 728.32051c-21.3 0-36.8-2.7-48.9-8.4-15.4-7.3-25-19.4-29.1-37.2-9.8-42 .4-75.1.5-75.4l.1-.3v-.3s.1-3.7.1-9.7c13.9.5 33.3 2.8 50.3 10.8 16.8 7.9 27.4 19.6 31.6 34.6 9.3 33.4 33.5 49.6 74.1 49.6 12.6 0 27-1.5 43.9-4.6 8.6-1.6 17.1-2.8 25.3-4 38.7-5.6 72.8-10.5 87.9-47.9-3.3 28.9-14.8 51.7-48.6 67.8-51.3 24.4-116.2 24.5-159.1 24.6-7.7 0-14.3 0-20.1.2-2.9.1-5.5.2-8 .2z" class="st4" fill="#e09c5c"/><path id="path6242" d="M417.81425 390.12051c1.3-8.5 2-14.7-7.8-12.6-9.8 2.1-69.8 18-80.5 20.3-10.8 2.3-8.7 12.1 1.8 18s39.7 23.2 51.7 21.6c12-1.6 22.7-3.8 27.6-19.2 4.9-15.3 7.2-28.1 7.2-28.1z" fill="#2e2314" stroke="#2b2011" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><g transform="translate(-77.185754 15.820514)" id="g6244"><path id="path6246" d="M458.6 419.7c-11.4 0-36.3-14.2-46.9-20.2l-2.2-1.3c-5.1-2.9-8.4-7.1-7.9-10.2.3-2 2.3-3.4 5.5-4.1 5.5-1.2 24-5.9 41.8-10.5l3.8-1c15.9 4.2 28.4 14.9 33.4 28.7l-.2.7c-4.5 14-13.6 16.2-25.9 17.8-.5.1-.9.1-1.4.1z" fill="#ad4949"/></g><g transform="translate(-77.185754 15.820514)" id="g6248"><path id="path6250" d="M404 397c-3.6-2.6-5.6-6.3-5-9.5.5-2.8 2.7-4.7 6.3-5.4 5.8-1.2 25.1-6.2 43.7-11 8.9-2.3 17.5-4.5 24.3-6.2l3.4 15L404 397z" class="st33" fill="#fff"/><path id="path6252" d="M471.9 367.4l2.5 11.1-70 16.4c-2.5-2.1-3.9-4.7-3.5-6.9.5-2.6 3.2-3.5 4.8-3.9 5.8-1.2 25.1-6.2 43.8-11 8.2-2.1 16-4.1 22.4-5.7m3-4.9c-20.4 5.1-61.2 15.8-70 17.7-10.3 2.2-10.6 13-1.3 19l75.6-17.8-4.3-18.9z" class="st42" fill="#7d7d65"/></g><path id="path6254" d="M215.61425 319.92051c-20.7 3.4-36.9-.3-43.7-27.4-6.8-27.1 17-58.9 51.2-71.3 34.2-12.4 68-2.3 68-2.3s9.5-22.5 12.8-35.5c3.3-13 13.3-14.1 23.6 5.2 0 0 28.8-4.1 32.3 26.8 3.6 30.9-20.7 46.4-20.7 46.4" class="st2" fill="#fbc16c" stroke="#946f3a" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6256" d="M327.61425 188.52051c4.3 10.3 2.9 22.9 2.7 27" class="st2" fill="#fbc16c" stroke="#946f3a" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><g transform="translate(-77.185754 15.820514)" id="g6258"><path id="path6260" d="M358.6 376.9c2.2 5.7 6.2 9.9 8.9 8.3 2.7-1.6 2.9-5.7.4-12.4-2.4-6.6-13.6-29.8-16.6-34.3-3-4.5-6.4-5.8-9.1-4.2-2.7 1.6-1.9 5.5-.1 9.2 1.9 3.8 16.5 33.4 16.5 33.4z"/></g><g transform="translate(-77.185754 15.820514)" id="g6262"><path id="path6264" d="M387.3 470.6c-4.3 0-8.8-.5-13.2-1.6-21.2-5.2-32.9-21.5-36.5-34-2.3-8-1.6-14.9 2-18.5 3.2-3.3 6.7-5 10.2-5 7.5 0 14.4 7.2 17.8 11.5 7.6 9.5 14.8 14.3 21.4 14.3 5.3 0 9.9-3 13.7-9 10-15.4 12.7-34.1 8.2-55.4-1.5-7.1.3-11.2 2.1-13.4 1.8-2.3 4.5-3.6 7.3-3.6 1.6 0 3 .4 4.2 1.2 18.2 11.8 20.2 52 13.6 74.4-5.6 18.8-23.9 39.1-50.8 39.1z" class="st33" fill="#fff"/><path id="path6266" d="M420.2 357.9c1.2 0 2.2.3 3.1.9 7.6 4.9 13 16 15.2 31.2 2 13.6 1 29.3-2.5 41-2.9 9.9-9.1 19.2-17.3 26-9.1 7.6-20 11.6-31.5 11.6-4.2 0-8.4-.5-12.7-1.6-20.4-5-31.6-20.7-35-32.6-2.1-7.2-1.5-13.5 1.5-16.5 2.9-2.9 5.8-4.4 8.8-4.4 6.9 0 13.7 7.5 16.3 10.7 8 10 15.7 15 22.9 15 6 0 11.2-3.3 15.4-9.9 10.3-15.9 13.1-35 8.4-56.9-1.1-4.9-.5-9.1 1.7-11.7 1.5-1.8 3.6-2.8 5.7-2.8m0-4c-6.7 0-14.1 6.4-11.3 19.4 3.6 16.6 3.6 36-7.9 53.8-3.8 5.9-8 8.1-12.1 8.1-8.2 0-16.1-8.8-19.8-13.5-3.8-4.8-11.1-12.2-19.4-12.2-3.8 0-7.7 1.5-11.7 5.6-11 11.3 2 47.6 35.5 55.8 4.7 1.2 9.3 1.7 13.7 1.7 26.7 0 46.6-19.8 52.7-40.5 7.1-24 4.6-64.4-14.4-76.7-1.5-1-3.4-1.5-5.3-1.5z" class="st42" fill="#7d7d65"/></g><path id="path6268" d="M290.11425 457.32051c6.5 1.7 19.4 2 29.8-6.6" fill="none" stroke="#7d7d65" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6270" d="M173.31425 408.82051c-3.7 5-10.1 7.9-16.3 7.2-6.2-.6-11.9-4.7-14.5-10.4-1.1 5.4-5.3 10.2-10.6 11.5-5.3 1.3-11.4-.7-14.8-5 1.6 13 12 22.7 16.5 35" fill="none" stroke="#946f3a" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6272" d="M263.31425 420.02051l-17.1 6.5c-5 1.9-10.6-.6-12.4-5.6-1.9-5 .6-10.6 5.6-12.4l17.1-6.5c5-1.9 10.6.6 12.4 5.6 1.9 4.9-.6 10.5-5.6 12.4z" fill="#e68a4c"/><path id="path6274" d="M625.31425 218.52051c7.3-2.8 14.1-4.3 19.2-3.8" class="st34" fill="none" stroke="#fbd7a3" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6276" d="M561.31425 267.62051c11.7-11.4 21.9-20.7 31.6-29.6 3.9-3.5 8.7-7.1 13.9-10.3" class="st34" fill="none" stroke="#fbd7a3" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6278" d="M471.21425 293.12051c15.7 1.4 33.6-.1 52.7-6.6" class="st34" fill="none" stroke="#fbd7a3" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6280" d="M361.61425 250.82051c19.9 3.5 36.4 12.2 56.1 23.6" class="st34" fill="none" stroke="#fbd7a3" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><g transform="translate(-77.185754 15.820514)" id="g6282"><path id="path6284" d="M311 486.9c-48 22-68 37-57 78s59 41 59 41-8 25 18 28 55-5 56-41-20-61-63-65" class="st2" fill="#fbc16c" stroke="#946f3a" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6286" d="M313 605.9c10 2 25 2 25 2" class="st2" fill="#fbc16c" stroke="#946f3a" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6288" d="M354.2 548.6l6.5 6.8c4.9 5.1 4.7 13.3-.4 18.2l-1.9 1.8c-5.1 4.9-13.3 4.7-18.2-.4l-6.5-6.8c-4.9-5.1-4.7-13.3.4-18.2l1.9-1.8c5.1-4.9 13.3-4.7 18.2.4z" fill="#fdd06e"/></g><path id="path6290" d="M396.81425 426.32051l-6.5 2.6c-4.9 1.9-10.5-.5-12.4-5.4l-.7-1.8c-1.9-4.9.5-10.5 5.4-12.4l6.5-2.6c4.9-1.9 10.5.5 12.4 5.4l.7 1.8c2 4.9-.5 10.5-5.4 12.4z" fill="#b9655a"/><path id="path6292" d="M218.51425 495.22051c1.8-14 .6-22.1.6-22.1" class="st2" fill="#fbc16c" stroke="#946f3a" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/></svg>
diff --git a/app/javascript/images/screen_interactions.svg b/app/javascript/images/screen_interactions.svg
new file mode 100644
index 000000000..41873371a
--- /dev/null
+++ b/app/javascript/images/screen_interactions.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" height="803" width="1195.8" viewBox="0 0 1195.8 802.99999" id="Layer_1"><path id="path6294" d="M132.1 466.49998c-6 5.8-11.8 5-18.2-.6-2.5-2.2-4.6.9-.6 4.9 4 4 13.5 8.3 22 .8" class="st99" fill="#e09c5c" stroke="#946f3a" stroke-width="2.28270006" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6296" d="M295.2 263.49998h-59.8c-15 0-27.3 12.3-27.3 27.3v12.9c0 6.3 2.2 12.1 5.8 16.8-6.7 13.7-21.4 16.9-21.4 16.9 18.9 2.3 24.6-3.5 30.7-9.2 3.7 1.8 7.8 2.9 12.2 2.9h59.8c15 0 27.3-12.3 27.3-27.3v-12.9c.1-15.1-12.2-27.4-27.3-27.4z" fill="#fff" stroke="#668794" stroke-width="2.28270006" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6298" d="M176.3 472.49998c-.1 11.9-2.4 21.1 7.9 21.2 10.3.1 13.2-2.5 13.1-10.1-.1-7.6-.6-21-.6-21" class="st99" fill="#e09c5c" stroke="#946f3a" stroke-width="2.28270006" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6300" d="M161.8 365.79998c-20.2 0-35.1 7.6-35.1 36v54.3c0 8 4.4 21.8 21.8 21.8h24.1c8.5 0 16.3-2.8 22.5-9.4 6.2-6.6 9.2-13.3 9.2-25.5v-46.6s20.4-.5 29.4-13.3c8.9-12.8 6.9-28.2 5.7-32.6 0 0 5.1-.5 4-4.4-1.1-3.9-7.3-3.3-10.1-1.1 0 0-1.6-1.8-7-1.7-5.4.1-3.7 6.2.7 6.7 0 0 2.4 13.8-4.6 18.7-7 4.9-21.4 6.6-29.8 2.7-8.5-3.7-11.3-5.6-30.8-5.6z" class="st101" fill="#fbc16c" stroke="#946f3a" stroke-width="2.28270006" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6302" d="M148.5 476.79998c-20.1 0-20.6-18.5-20.6-20.6v-23.1c13 .1 18.8 1.5 18.8 12.4 0 13.2 2.2 19.8 13.9 19.8H192c1.7 0 3.4-.1 5-.7-.8 1-1.7 2.1-2.7 3.2-5.6 6-12.9 9-21.6 9h-24.2z" class="st4" fill="#e09c5c"/><path id="path6304" d="M154.8 372.09998c-9.6-2.9-14.7-4.9-11.8-13.3 2.9-8.4 17-6.6 24.7-2.7 0 0 4-2.4 6.3-3.3 2.3-.9 6.6-1.3 6.7 1.7 0 0 5.4.6 4.4 4.9 0 0 6.4 3.7-8.1 10.7" class="st101" fill="#fbc16c" stroke="#946f3a" stroke-width="2.28270006" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6306" d="M138.5 381.49998c0-6.4-3.8-10.3-11.8-10.3s-14.8 7.5-13 18.7c1.8 11.2-4.3 19.9 2.8 24.9s14.4 1.9 16.7-1.9c0 0 7.6 2 7-9.9" class="st101" fill="#fbc16c" stroke="#946f3a" stroke-width="2.28270006" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6308" d="M167.3 395.79998c-5.7 0-8.8 4.4-7.5 10.2 1.3 5.7 5 10 11.4 10.2 6.4.1 12.5-2.1 14.4-11.4 1.9-9.3-1.6-9.4-4.4-9.4-2.8 0-13.9.4-13.9.4z" fill="#544024" stroke="#3b3024" stroke-width="2.28270006" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6310" d="M176.8 408.89998c0-6.7-5.4-12.2-12.2-12.2-.6 0-1.1.1-1.7.1-2.8 1.6-4.1 5-3.2 9.1 1.3 5.7 5 10 11.4 10.2 1.1 0 2.2 0 3.3-.2 1.6-2 2.4-4.4 2.4-7z" fill="#693131" stroke="#381916" stroke-width="2.28270006" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6312" d="M181.1 402.49998v-7.2c-3 0-13.8.4-13.8.4-4.5 0-7.4 2.8-7.8 6.8h21.6z" class="st104" fill="#fff" stroke="#7d7d65" stroke-width="2.28270006" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6314" d="M146.2 410.69998c6 5.8 14.3 5.8 18.1 2.6 3.8-3.2 5.8-11.4 2.7-12.2-3.1-.8-2.4 4.7-5.2 6.3-2.8 1.6-6 1.2-9-.7-2.9-1.9-5.9-3.2-7.4-1.4-1.3 2-.6 4 .8 5.4z" class="st104" fill="#fff" stroke="#7d7d65" stroke-width="2.28270006" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6316" d="M349.4 440.69998c-5.7 6.2-14 6.6-18 3.6-4-3-6.4-11-3.4-12 3-1 2.7 4.5 5.5 6s6.1.9 8.9-1.1c2.8-2 5.7-3.6 7.3-1.7 1.6 1.9 1.1 3.8-.3 5.2z" fill="none" stroke="#000" stroke-width=".57069999" stroke-miterlimit="10"/><path id="path6318" d="M134.3 415.29998l-20.5.1s-.7-3.4-3.8-2.9c-3.1.5-3.8 2.3-3.9 3.4 0 0-6.8.4-6.9 7.2-.1 6.8 4.9 9.5 12.1 9.1 7.2-.4 24.4 0 24.4 0" class="st101" fill="#fbc16c" stroke="#946f3a" stroke-width="2.28270006" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6320" d="M135.4 472.49998c-.1 11.9-2.4 21.1 7.9 21.2 10.3.1 13.2-2.5 13.1-10.1-.1-7.6-.2-10.4-.2-10.4" class="st99" fill="#e09c5c" stroke="#946f3a" stroke-width="2.28270006" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6322" d="M152.7 399.79998c-.9 0-1.6-.7-1.6-1.6v-10.9c0-.9.7-1.6 1.6-1.6.9 0 1.6.7 1.6 1.6v10.9c0 .9-.7 1.6-1.6 1.6z" fill="#402f19"/><path id="path6324" d="M524.8 296.99998c-6.9-8.5-22.1-16.7-42.9-6.4-20.8 10.3-26.2 38-14.9 56.5 11.3 18.5 14.4 22.6 14.4 22.6v46.7c0 9.8 2.8 13.3 10 13.3s11.3-2.8 11.3-9.8v-10.5h29.5v11c0 4.3 2.6 9 9.5 9s9.8-2.3 9.8-11.8v-62.6s.8-27.4-26.7-58z" class="st106" fill="#fbc16c" stroke="#946f3a" stroke-width="3.56489992" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6326" d="M491.4 427.89998c-6.2 0-8.2-2.8-8.2-11.6v-47.3l-.4-.5s-2-2.7-8.5-13.1c.1-1.4.2-2.8.1-4.1l13 17.2v22c0 5.2 1.1 11.2 9.9 11.2h52.3v15.8c0 9-2.6 10-8 10-7.2 0-7.7-5.5-7.7-7.2v-12.7H501v12.3c0 5.5-3 8-9.6 8z" class="st4" fill="#e09c5c"/><path id="rect6328" stroke="#3b3024" stroke-width="3.56489992" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" d="M510.59998 170.29993h206.2v203.5h-206.2z"/><g transform="translate(-733 -934.40002)" id="g6330"><path id="path6332" d="M1216.8 1264.5c-.8 0-1.6-.4-2-1.1l-5.3-9c-.3-.5-.4-1.2-.2-1.7.2-.6.5-1.1 1.1-1.4 1.1-.6 2.5-.3 3.2.8l5.3 9c.6 1.1.3 2.5-.8 3.2-.5.1-.9.2-1.3.2z" fill="#141a1c"/></g><path id="path6334" d="M294.8 452.99998c-7.2.9-16.7-.7-21.6-1.8-4.9-1.1-7.8 4.3-8.5 9.5-.7 5.2 11.7 14.1 32.7 8.7" class="st108" fill="#fbe6c6" stroke="#668794" stroke-width="2.28270006" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6336" d="M363 450.19998c13.1 4.1 22.2 11.7 22 20.3-.2 8.6-9.6 14.2-16.5 15.5-6.9 1.3-9.8-6.1-8.9-11.1.9-5 3.4-6.6 3.4-6.6" class="st108" fill="#fbe6c6" stroke="#668794" stroke-width="2.28270006" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6338" d="M358 465.59998c5 2.6 10.1 5.4 10.1 5.4" class="st108" fill="#fbe6c6" stroke="#668794" stroke-width="2.28270006" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6340" d="M364 411.99998c0-6.4 3.8-10.3 11.8-10.3s14.8 7.5 13 18.7c-1.8 11.2 4.3 19.9-2.8 24.9-7.1 4.9-14.4 1.9-16.7-1.9 0 0-7.6 2-7-9.9" class="st108" fill="#fbe6c6" stroke="#668794" stroke-width="2.28270006" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6342" d="M328.1 395.29998c-29.7-.3-34.4 7.9-42 14.4-7.6 6.6-17.6 18.8-36.6 19.5 0 0-2.5-3.5-5.2-1s-2.2 5.9-.3 7.2c0 0-3.7 3.7.2 7.6 3.9 3.9 7.2 0 7.2 0s14.4 1.3 25.9-4c11.4-5.4 15.1-3.3 15.1-3.3v50.4c0 15.8 7.2 22 25.9 22s36.8 1.7 44.5-6.2c7.7-7.9 6.4-19.2 5.9-29.2s0-28.1 0-43.5c0-15.4-1.4-33.6-40.6-33.9z" class="st108" fill="#fbe6c6" stroke="#668794" stroke-width="2.28270006" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6344" d="M340.3 505.59998c0 4.8-.5 6.6-.2 10.1-1.6 1.1-2.2 3-1.7 4.6.6 2 3.6 4 9.9 3.9 10.4.1 13.2-2.5 13.1-10.1-.1-3.5-.2-8.2-.3-12.2" class="st109" fill="#dcceb5" stroke="#668794" stroke-width="2.28270006" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6346" d="M334.5 506.99998c-2.6 0-5.1 0-7.9-.1-2.8 0-5.6-.1-8.4-.1-18 0-24.7-5.7-24.7-20.9 0-2.5 4.3-4.8 9-4.8 2.3 0 6.6.6 9.2 4.3 3.8 5.2 8.9 7.1 16.3 7.1 4.5 0 14.5.2 17.9-2.4 4.5-3.3 5.8-7.9 13.3-9.6 3-.7 5.6-1.2 8.6-.4.2 9.3-1.3 17.2-5.9 20.8-5.5 4.4-14.5 6.1-27.4 6.1z" fill="#dcceb5"/><path id="path6348" d="M341.9 402.79998c7-.1 10.7-4.4 10.2-8.6-.6-4.1-3.5-9.9-16.6-9.2-5.8.3-8.7 4.1-11.5 4.1-2.8-.1-8.3-8.1-13.1-7.6-4.8.5-5.1 3.9-4.3 5.5 0 0-4.3 1.3-1.9 6.9 2.4 5.6 7.3 7.5 12.1 8.1" class="st108" fill="#fbe6c6" stroke="#668794" stroke-width="2.28270006" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6350" d="M301.7 503.09998c0 4.8-.5 9.2-.2 12.7-1.6 1.1-2.2 3-1.7 4.6.6 2 3.6 4 9.9 3.9 10.4.1 13.2-2.5 13.1-10.1 0-2.9-.1-3.7-.2-7.2" class="st109" fill="#dcceb5" stroke="#668794" stroke-width="2.28270006" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6352" d="M469.1 323.09998c-3.8-5.7-8.6-7.6-16.5-3.7-7.9 3.9-8.7 14.8-4.6 21 4.2 6.3 4.8 11.2 3.8 15.8-1 4.6.5 7.1 3.7 8 3.2.9 5.2-1.1 5.2-1.1s11.2 1.1 12.4-8c1.2-9.1-.2-12.9-.2-12.9" class="st106" fill="#fbc16c" stroke="#946f3a" stroke-width="3.56489992" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6354" d="M460.7 363.09998c2-2.5 2-7.6 2-7.6" fill="none" stroke="#946f3a" stroke-width="3.56489992" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6356" d="M468.8 306.69998c-7.3-3.2-9.2-12.8-2.8-17 6.4-4.2 13.3-4.3 13.3-4.3s7.1-12.2 11.7-12.6c4.6-.4 6 2.7 5.2 5.2 0 0 5.9-1.1 6 3.8.1 5-2.6 7.8-6.4 10.6" class="st106" fill="#fbc16c" stroke="#946f3a" stroke-width="3.56489992" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6358" d="M492.8 340.79998c7.3 2.2 15.1 2.2 19.6-4.9 4.5-7.1 6.9-14.3 2.9-15.8s-5.4 2-7.2 6.5c-1.8 4.5-5.1 6-10.8 5.1-5.7-.9-7.7 0-8.1 2.7-.4 2.7.3 5.3 3.6 6.4z" fill="#fff" stroke="#4a493c" stroke-width="3.56489992" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6360" d="M633.8 211.49998c.7-8.6 12.3-17.4 29.3-11.5 17 5.9 30.2 19.1 26.7 44.7 0 0 13.1 53.9 13.6 80l-31.7 1.6 1.1-57.3c0 .1-50.3-41.3-39-57.5z" fill="#fbdeb5" stroke="#946f3a" stroke-width="3.56489992" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6362" d="M672.8 269.09998c-.4-14.1.7-22.5.7-22.5" class="st113" fill="#fbc16c" stroke="#946f3a" stroke-width="1.78240001" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6364" d="M634.7 208.59998c6.4-7.9 18.4-6.8 28.2-1.2 9.9 5.5 15.4 12 15.4 12" fill="none" stroke="#946f3a" stroke-width="1.78240001" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6366" d="M628.4 215.39998c-2.1-4.9 9.9-8.8 18.2-3.6 8.3 5.2 18.6 15.2 18.5 26.7-.1 11.5-11.2 9.1-11.2 9.1s-25.1-31.4-25.5-32.2z" class="st115" fill="#fbe6c6" stroke="#668794" stroke-width="3.56489992" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6368" d="M613 293.99998c4.3 13.7 10.6 20.3 10.6 20.3l31.8-16.4-7.9-12.1-34.5 8.2z" class="st106" fill="#fbc16c" stroke="#946f3a" stroke-width="3.56489992" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6370" d="M663.1 258.19998c0 25.5-21.2 42.3-45.8 44-28.8 2-43.4-18.5-43.4-44s20-46.1 44.6-46.1 44.6 20.6 44.6 46.1z" class="st45" fill="#fbc16c"/><path id="path6372" d="M625.4 301.09998c-2.6.6-5.3.9-8.1 1.1-28.8 2-43.4-18.5-43.4-44s20-46.1 44.6-46.1 44.6 20.7 44.6 46.1c0 7.1-1.6 13.5-4.5 19.1" class="st106" fill="#fbc16c" stroke="#946f3a" stroke-width="3.56489992" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6374" d="M587.5 247.69998c-18.4 13.4-32.3 13.5-41.8 4.6 0 0 1.6-5.8-4.2-4.8-5.8 1-7.8 7.2-5.4 10.4 0 0-2.6 4.2-.4 8.4s8 2.8 8 2.8 8.4 9.4 20.3 9.4 21.1-3.4 25.9-8.4" class="st106" fill="#fbc16c" stroke="#946f3a" stroke-width="3.56489992" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6376" d="M605.2 282.59998c-.3-2.5-1.6-4.8-3.6-6.3s-4.6-2.2-7-1.8c-.9.1-1.9.5-2.3 1.3-1.3-.4-2.6-.7-3.9-.5-1.3.2-2.6.8-3.3 2-.7 1.1-.7 2.7.2 3.7-.4 2.4.3 5 2.3 6.4.8.5 1.7.9 2.6 1.1 2.1.6 4.4.7 6.5 0 1.3-.4 2.4-1.1 3.5-1.8 1.7-1.2 3.7-2.3 5-4.1z" fill="#a34c4c" stroke="#47271c" stroke-width="1.78240001" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6378" d="M598.6 281.49998c-2.1 2.2-5.4 3.2-8.4 2.7-1.7-.3-3.5-1.3-4-3 1.8-1.4 4-2.1 6.3-2.1 2.2 0 4.3 1 6.1 2.4z" fill="#fbe6c6" stroke="#47271c" stroke-width="1.78240001" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><circle id="circle6380" r="7.1999998" cy="271.90002" cx="619.09998" fill="#a34c4c"/><path id="path6382" d="M600.6 250.59998c2.1 4.5 3.4 5.7 6.3 6.6 2.9.9 7.5-.6 9.4-3.2 0 0-2.2-3.7-7.2-4.9-5-1.1-8.5 1.5-8.5 1.5z" class="st118" fill="#fbe6c6" stroke="#946f3a" stroke-width="1.78240001" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6384" d="M586.5 247.19998s.9-4.5-8.9-7.4c-1.2 2.8-2.1 5.8-2.7 8.9 6.5 1.3 9.4.8 11.6-1.5z" class="st118" fill="#fbe6c6" stroke="#946f3a" stroke-width="1.78240001" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6386" d="M648.7 250.59998c-5 13.3-5.7 28.4-1.9 33.9 3.9 5.6 9.1 4.2 9.9 1.1 0 0 .7 5.1 6.6 5.7 5.8.6 10.3-6.8 10.2-19-.1-12.2-3.7-21-12.9-21.9-9.2-.9-11.9.2-11.9.2z" class="st106" fill="#fbc16c" stroke="#946f3a" stroke-width="3.56489992" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6388" d="M580.6 233.89998c12.3-2.5 26.9-2.1 42.9 7.1s30.1 14 39.6 14.9c-1.1-24.5-20.6-44-44.5-44-16.1.1-30.2 8.9-38 22z" fill="#51a1b5" stroke="#31446e" stroke-width="3.56489992" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6390" d="M602.6 240.79998c1.7-1 3.7-1.5 5.6-1.6" class="st113" fill="#fbc16c" stroke="#946f3a" stroke-width="1.78240001" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6392" d="M611.7 238.89998c1 0 1.9.2 2.8.5" class="st113" fill="#fbc16c" stroke="#946f3a" stroke-width="1.78240001" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6394" d="M582.4 235.49998c1.8.3 3.5 1.3 4.8 2.6" class="st113" fill="#fbc16c" stroke="#946f3a" stroke-width="1.78240001" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6396" d="M583.6 242.49998c-.3.2-.6.4-.9.7-1.5 1.7-1.4 4.3.2 5.9 1.5-.3 2.6-1 3.6-2 0 .1.5-2.2-2.9-4.6z" class="st120" fill="#4d3b21" stroke="#2b2111" stroke-width="1.78240001" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6398" d="M616.3 253.99998s-1.6-2.8-5.3-4.3c-.4.2-.9.5-1.2.9-1.6 1.8-1.4 4.5.3 6.1.2.2.5.4.7.5 2.2-.4 4.4-1.6 5.5-3.2z" class="st120" fill="#4d3b21" stroke="#2b2111" stroke-width="1.78240001" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6400" d="M689.8 244.69998c-2.3-7.7-5.4-11.6-5.4-11.6" class="st106" fill="#fbc16c" stroke="#946f3a" stroke-width="3.56489992" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6402" d="M617.3 323.09998c-3.1 9.1-5.8 21.9 2 32.1l-2.2 11.4 80.7 2.3s-1-32.5-15.5-42.8c-14.4-10.4-15.9-11.5-18.9-15-3.1-3.5-5.9-9.7-5.9-9.7l-40.2 21.7z" class="st121" fill="#876a4d" stroke="#3b3024" stroke-width="3.56489992" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6404" d="M655.1 296.49998c-18 2.9-31.5 11.9-38.2 22.5-3.8 6-3.2 10.1-3.2 10.1l47.2-28-5.8-4.6z" class="st121" fill="#876a4d" stroke="#3b3024" stroke-width="3.56489992" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6406" d="M611.7 365.49998c.5-12.8 3.5-34.8 20.8-36.8s39.3 3.1 55.7 38.2l-76.5-1.4z" class="st121" fill="#876a4d" stroke="#3b3024" stroke-width="3.56489992" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6408" d="M503.8 163.59998v218.9h218.9v-218.9H503.8zm201.9 201.9H520.8v-184.9h184.9v184.9z" fill="#594726" stroke="#45331b" stroke-width="3.56489992" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="rect6410" fill="none" stroke="#45331b" stroke-width="2.67370009" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" d="M510.59998 170.29993h206.2v206.2h-206.2z"/><path id="path6412" d="M657.5 312.19998c6.5.1 10.6 4.6 10.6 4.6" fill="none" stroke="#3b3024" stroke-width="1.78240001" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6414" d="M685.6 325.79998c-2.9-26.5-7.3-51.7-7.3-51.7" class="st113" fill="#fbc16c" stroke="#946f3a" stroke-width="1.78240001" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="line6416" class="st113" fill="#fbc16c" stroke="#946f3a" stroke-width="1.78240001" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" d="M689.30005 325.29993l-.6001-27.79993"/><circle id="circle6418" r="7.6999998" cy="298" cx="655.40002" class="st115" fill="#fbe6c6" stroke="#668794" stroke-width="3.56489992" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6420" d="M613.4 236.29998c3.3 1.2 6.6 2.8 10 4.7 16 9.2 30.1 14 39.6 14.9-.7-15.2-8.5-28.5-20.1-36.4-11.9 1.5-22.4 7.8-29.5 16.8z" fill="#31446e" stroke="#31446e" stroke-width="3.56489992" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6422" d="M501.1 346.99998c5.7 4.6 14.7 8.5 20.1 6.6 7.7-2.7 12.7-4.6 15.8 2.2 3.1 6.8-1.9 10.8-10.1 15.2-9.9 5.2-18.6.3-26.3-3.7" class="st106" fill="#fbc16c" stroke="#946f3a" stroke-width="3.56489992" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6424" d="M576.7 380.89998c0 4.9-3.9 7-8.8 7s-8.8-2.2-8.8-7 3.9-7.7 8.8-7.7 8.8 2.9 8.8 7.7z" class="st106" fill="#fbc16c" stroke="#946f3a" stroke-width="3.56489992" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6426" d="M599.5 225.49998c8.4.5 16.9 1.8 28.6 7.8" fill="none" stroke="#31446e" stroke-width="2.67370009" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="line6428" class="st127" fill="none" stroke="#fbf0d3" stroke-width="2.67370009" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" d="M604.59998 175.5h3.59997"/><path id="line6430" class="st127" fill="none" stroke="#fbf0d3" stroke-width="2.67370009" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" d="M622.30005 175.5h64"/><path id="line6432" class="st127" fill="none" stroke="#fbf0d3" stroke-width="2.67370009" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" d="M594.69995 175.5h5.6001"/><path id="line6434" class="st127" fill="none" stroke="#fbf0d3" stroke-width="2.67370009" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" d="M519.30005 175.5H585"/><g transform="translate(-733 -934.40002)" id="g6436"><path id="path6438" d="M1025.8 1218.9h-54.6c-1.9 0-3.4-1.5-3.4-3.4s1.5-3.4 3.4-3.4h54.6c1.9 0 3.4 1.5 3.4 3.4s-1.5 3.4-3.4 3.4z" class="st72" fill="#4a4439"/><path id="path6440" d="M1025.8 1235.8h-54.6c-1.9 0-3.4-1.5-3.4-3.4s1.5-3.4 3.4-3.4h54.6c1.9 0 3.4 1.5 3.4 3.4 0 1.8-1.5 3.4-3.4 3.4z" class="st72" fill="#4a4439"/><path id="path6442" d="M1025.8 1252.6h-54.6c-1.9 0-3.4-1.5-3.4-3.4s1.5-3.4 3.4-3.4h54.6c1.9 0 3.4 1.5 3.4 3.4s-1.5 3.4-3.4 3.4z" class="st72" fill="#4a4439"/></g><path id="path6444" d="M303.9 411.99998c0-6.4 3.8-10.3 11.8-10.3s14.8 7.5 13 18.7c-1.8 11.2 4.3 19.9-2.8 24.9-7.1 4.9-14.4 1.9-16.7-1.9 0 0-7.6 2-7-9.9" class="st108" fill="#fbe6c6" stroke="#668794" stroke-width="2.28270006" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="line6446" class="st128" fill="#fbe6c6" stroke="#28353b" stroke-width="7.12979984" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" d="M540.80005 202.29993h45.09997"/><path id="line6448" class="st128" fill="#fbe6c6" stroke="#28353b" stroke-width="7.12979984" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" d="M540.80005 313.40002h45.09997"/><path id="line6450" class="st128" fill="#fbe6c6" stroke="#28353b" stroke-width="7.12979984" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" d="M556.09998 330.69995h29.80004"/><path id="line6452" class="st128" fill="#fbe6c6" stroke="#28353b" stroke-width="7.12979984" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" d="M540.80005 348.40002h45.09997"/><path id="line6454" class="st128" fill="#fbe6c6" stroke="#28353b" stroke-width="7.12979984" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" d="M540.80005 218.40002h11.79993"/><path id="path6456" d="M202.3 427.59998c11.6-.6 21.6-4.6 26.7-9.3 5.8-5.3 8.9-10.5 3.7-15.1-5.1-4.5-10.1-.1-10.1-.1s-2-3.1-5-.8-.8 4.5-.8 4.5-3.6 5-14.9 5.5" class="st101" fill="#fbc16c" stroke="#946f3a" stroke-width="2.28270006" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6458" d="M147 400.59998l-3.5.6c-1 .2-2-.5-2.1-1.5-.2-1 .5-2 1.5-2.1l3.5-.6c1-.2 2 .5 2.1 1.5.2 1-.4 2-1.5 2.1z" class="st31" fill="#e68a4c"/><path id="path6460" d="M482.8 337.99998l-5.4.9c-1.6.3-3.1-.8-3.3-2.4-.3-1.6.8-3.1 2.4-3.3l5.4-.9c1.6-.3 3.1.8 3.3 2.4.3 1.6-.8 3.1-2.4 3.3z" class="st31" fill="#e68a4c"/><path id="path6462" d="M217.7 375.79998c.7-.2 1-.4 1.6-.7" class="st129" fill="none" stroke="#fbd7a3" stroke-width="2.85330009" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6464" d="M212.5 377.19998c.9-.2.4 0 1.2-.2" class="st129" fill="none" stroke="#fbd7a3" stroke-width="2.85330009" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6466" d="M200.2 377.39998c2.2.3 4.4.4 6.6.4" class="st129" fill="none" stroke="#fbd7a3" stroke-width="2.85330009" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6468" d="M186.1 373.39998c2.4 1.1 5 2 7.7 2.7" class="st129" fill="none" stroke="#fbd7a3" stroke-width="2.85330009" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6470" d="M943 464.89998c-8.7 8.4-17 7.2-26.3-.8-3.6-3.1-6.6 1.3-.8 7.1s19.4 12 31.7 1.2" class="st130" fill="#e09c5c" stroke="#946f3a" stroke-width="3.29229999" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6472" d="M1006.7 473.49998c-.2 17.1-3.5 30.4 11.5 30.6 15 .2 19.1-3.7 18.9-14.6-.2-11-.8-30.2-.8-30.2" class="st130" fill="#e09c5c" stroke="#946f3a" stroke-width="3.29229999" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6474" d="M985.8 319.59998c-29.1 0-50.6 10.9-50.6 51.9v78.4c0 11.6 6.3 31.4 31.4 31.4h34.7c12.2 0 23.5-4 32.4-13.6 8.9-9.6 13.2-19.2 13.2-36.7v-67.1s29.4-.7 42.3-19.2c12.9-18.5 9.9-40.7 8.3-47 0 0 7.4-.7 5.8-6.3-1.6-5.6-10.5-4.7-14.6-1.6 0 0-2.3-2.6-10.1-2.4-7.8.2-5.3 9 1 9.6 0 0 3.5 20-6.6 27s-30.9 9.5-43 3.9c-12.1-5.5-16.1-8.3-44.2-8.3z" class="st131" fill="#fbc16c" stroke="#946f3a" stroke-width="3.29229999" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6476" d="M983.3 370.49998c8.6 5.9 19.2 7.4 26.8.7" class="st132" fill="none" stroke="#402f19" stroke-width="4.32690001" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6478" d="M966.6 479.69998c-28.9 0-29.8-26.7-29.8-29.8v-33.3c18.8.2 27.1 2.2 27.1 17.9 0 19 3.1 28.6 20.1 28.6h45.2c2.5 0 4.9-.1 7.2-1.1-1.1 1.5-2.4 3-3.9 4.6-8.1 8.7-18.6 13-31.2 13h-34.7z" class="st4" fill="#e09c5c"/><path id="path6480" d="M975.8 328.69998c-13.8-4.1-21.2-7-17.1-19.1 4.1-12.1 24.5-9.5 35.6-3.9 0 0 5.8-3.4 9.1-4.7 3.3-1.3 9.5-1.9 9.7 2.4 0 0 7.8.8 6.4 7 0 0 9.3 5.3-11.7 15.4" class="st131" fill="#fbc16c" stroke="#946f3a" stroke-width="3.29229999" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6482" d="M952.2 342.29998c0-9.3-5.4-14.8-17-14.8s-21.4 10.8-18.7 27c2.7 16.2-6.2 28.7 4 35.9 10.2 7.2 20.8 2.7 24.1-2.7 0 0 11 2.9 10-14.3" class="st131" fill="#fbc16c" stroke="#946f3a" stroke-width="3.29229999" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6484" d="M963.3 384.39998c8.7 8.4 20.6 8.4 26.1 3.8 5.5-4.6 8.4-16.4 4-17.5-4.4-1.2-3.5 6.7-7.5 9.1-4 2.3-8.7 1.7-12.9-1-4.2-2.7-8.5-4.7-10.6-2-2.1 2.7-1.1 5.6.9 7.6z" fill="#fff" stroke="#7d7d65" stroke-width="3.29229999" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6486" d="M947.8 473.49998c-.2 17.1-3.5 30.4 11.5 30.6 15 .2 19.1-3.7 18.9-14.6-.2-11-.3-15-.3-15" class="st130" fill="#e09c5c" stroke="#946f3a" stroke-width="3.29229999" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6488" d="M965.4 369.79998l-6.7 1.1c-1 .2-2-.5-2.1-1.5l-.3-1.6c-.2-1 .5-2 1.5-2.1l6.7-1.1c1-.2 2 .5 2.1 1.5l.3 1.6c.2.9-.5 1.9-1.5 2.1z" class="st31" fill="#e68a4c"/><path id="path6490" d="M1066.5 333.99998c1-.4 1.4-.5 2.4-1" class="st134" fill="none" stroke="#fbd7a3" stroke-width="4.11530018" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6492" d="M1059 336.09998c1.2-.2.5 0 1.7-.3" class="st134" fill="none" stroke="#fbd7a3" stroke-width="4.11530018" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6494" d="M1041.1 336.39998c3.1.4 6.3.6 9.5.5" class="st134" fill="none" stroke="#fbd7a3" stroke-width="4.11530018" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6496" d="M1020.8 330.59998c3.4 1.5 7.2 2.9 11.1 3.9" class="st134" fill="none" stroke="#fbd7a3" stroke-width="4.11530018" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6498" d="M305.1 402.39998c.7-.3 1.3-.5 1.9-.8" class="st135" fill="none" stroke="#fff" stroke-width="2.28270006" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6500" d="M299.6 405.09998c.9-.5.9-.6 1.8-1.1" class="st135" fill="none" stroke="#fff" stroke-width="2.28270006" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6502" d="M291.8 410.49998c1.6-1.2 2.5-1.9 4.1-2.9" class="st135" fill="none" stroke="#fff" stroke-width="2.28270006" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6504" d="M284.1 417.79998c1.2-1.3 2.6-2.6 4-3.9" class="st135" fill="none" stroke="#fff" stroke-width="2.28270006" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6506" d="M525.2 357.69998c.9-.3 1.8-.7 2.7-1.1" class="st136" fill="none" stroke="#fbd7a3" stroke-width="4.45609999" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6508" d="M514.6 358.79998c1.5.2 2.9.3 4.5.1" class="st136" fill="none" stroke="#fbd7a3" stroke-width="4.45609999" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6510" d="M501 353.69998c2.7 1.4 5.2 2.7 7.7 3.6" class="st136" fill="none" stroke="#fbd7a3" stroke-width="4.45609999" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="line6512" class="st137" fill="none" stroke="#bf9649" stroke-width="3.56489992" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" d="M711.69995 298.90002v3"/><path id="line6514" class="st137" fill="none" stroke="#bf9649" stroke-width="3.56489992" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" d="M711.69995 290.90002V293.5"/><path id="line6516" class="st137" fill="none" stroke="#bf9649" stroke-width="3.56489992" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" d="M711.69995 243.69995v38.40003"/><g transform="translate(-733 -934.40002)" id="g6518"><path id="polygon6520" class="st33" fill="#fff" d="M1439.3 1141.2l11.7 19.2 19.7 11.1-19.3 11.8-11.1 19.6-11.8-19.2-19.6-11.1 19.3-11.8z"/></g><g transform="translate(-733 -934.40002)" id="g6522"><path id="polygon6524" class="st33" fill="#fff" d="M1426.9 1110.4l8.4-4.9 5-8.4 4.9 8.4 8.4 5-8.4 4.9-5 8.4-4.9-8.4z"/></g><path id="line6526" class="st137" fill="none" stroke="#bf9649" stroke-width="3.56489992" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" d="M515.19995 246.59998v-2.90003"/><path id="line6528" class="st137" fill="none" stroke="#bf9649" stroke-width="3.56489992" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" d="M515.19995 254.69995V252"/><path id="line6530" class="st137" fill="none" stroke="#bf9649" stroke-width="3.56489992" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" d="M515.19995 301.90002V263.5"/><g transform="translate(-733 -934.40002)" id="g6782"><path id="rect6784" fill="#587faa" d="M1193.6 1367.5h255.3v95.599998h-255.3z"/><path id="path6786" d="M1447.8 1368.5v93.6h-253.3v-93.6h253.3m2-2h-257.3v97.6h257.3v-97.6z"/></g><path id="rect6788" class="st82" transform="rotate(90)" fill="#2d3f68" d="M446.05344-714.81085h9.1000004v253.2H446.05344z"/><path id="line6790" class="st80" fill="#587faa" stroke="#000" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" d="M461.30005 446.09998h255.5"/><path id="line6792" class="st80" fill="#587faa" stroke="#000" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" d="M468.30005 463.40002v2.19996"/><path id="line6794" class="st80" fill="#587faa" stroke="#000" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" d="M468.30005 446.09998v13.09997"/><path id="line6796" class="st80" fill="#587faa" stroke="#000" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" d="M474.40002 463.40002v2.19996"/><path id="line6798" class="st80" fill="#587faa" stroke="#000" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" d="M474.40002 446.09998v13.09997"/><path id="line6800" fill="none" stroke="#fff" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" d="M464.90002 435.69995h246.79993"/><g transform="translate(-733 -934.40002)" id="g6802"><g id="g6804"><path id="path6806" d="M1453.6 1417.6c0-6.8-2.8-11.9-6.9-11.9-4.1 0-6.7 4.1-6.7 11.9v17.4c0 4.8.5 11.1 6.8 11.1s4.8-17.9 4.8-17.9" class="st158" fill="#f4a679" stroke="#668794" stroke-width="2.28270006" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6808" d="M1506.3 1417.6c0-6.8 2.8-11.9 6.9-11.9 4 0 6.7 4.1 6.7 11.9v17.4c0 4.8-.5 11.1-6.8 11.1s-4.8-17.9-4.8-17.9" class="st158" fill="#f4a679" stroke="#668794" stroke-width="2.28270006" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6810" d="M1540.4 1435.3c-2.4-2.8-6.8-3.1-9.7-.8-6.2 4.9-9.9 7.4-16.1 11v-11.1c0-.6-.1-1.1-.1-1.7.1-.9.1-1.9.1-2.9 0-18.7-15.2-30.7-33.9-30.7s-33.9 12-33.9 30.7c0 1 0 1.9.1 2.9-.1.5-.1 1.1-.1 1.7v9.7c-5.8-3.4-9.4-5.8-15.3-10.6-2.9-2.3-7.2-2-9.7.8-2.4 2.8-1.9 7.3 1.3 9.9 7.6 6 11.7 8.7 20.1 13.4 1.2.7 2.4 1 3.6 1v25.6c0 .4 0 .9.1 1.3 0 .3-.1.6-.1.9v22.6c0 3.2 2.6 5.8 5.8 5.8h7.8c3.2 0 5.8-2.6 5.8-5.8v-12.8h29.3v12.8c0 3.2 2.6 5.8 5.8 5.8h7.8c3.2 0 5.8-2.6 5.8-5.8v-22.6c0-.3 0-.6-.1-.9 0-.4.1-.9.1-1.3v-24.8c1.5.2 3-.1 4.4-.9 8.4-4.7 12.5-7.4 20.1-13.4 2.9-2.4 3.4-6.9 1-9.8z" class="st158" fill="#f4a679" stroke="#668794" stroke-width="2.28270006" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="line6812" class="st108" fill="#fbe6c6" stroke="#668794" stroke-width="2.28270006" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" d="M1461.6 1496.3h40.7"/><path id="path6814" d="M1476.3 1491.8c3.9 9.1 16.6 9.5 23.8 3.7 2.8-2.2 2.4-4.5-1.9-3.7-4.3.7-10.6 3.9-15.6-2" class="st158" fill="#f4a679" stroke="#668794" stroke-width="2.28270006" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/></g><path id="path6816" d="M1463.6 1405.7c-1.8-7.5 1.7-14.4 13.4-12.2 2.7.5 4.8 1.5 4.8 1.5s6-1 11.2-2.8c5.2-1.8 9 .5 9.9 5.4.8 4.9-1.5 8.3-8.9 9.7" class="st158" fill="#f4a679" stroke="#668794" stroke-width="2.28270006" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/></g><g transform="translate(-733 -934.40002)" id="g6818"><path id="path6820" d="M1364.2 1419.2c0-6.8-2.8-11.9-6.9-11.9-4 0-6.7 4.1-6.7 11.9v17.4c0 4.8.5 11.1 6.8 11.1s4.8-17.9 4.8-17.9" class="st159" fill="#965e8c" stroke="#5c3556" stroke-width="2.28270006" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6822" d="M1416.9 1419.2c0-6.8 2.8-11.9 6.9-11.9 4.1 0 6.7 4.1 6.7 11.9v17.4c0 4.8-.5 11.1-6.8 11.1s-4.8-17.9-4.8-17.9" class="st159" fill="#965e8c" stroke="#5c3556" stroke-width="2.28270006" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6824" d="M1426.5 1447.8l-1.3 1.6v-13.3c0-.6-.1-1.1-.1-1.7.1-.9.1-1.9.1-2.9 0-18.7-15.2-33.9-33.9-33.9s-33.9 15.2-33.9 33.9c0 1 0 1.9.1 2.9-.1.5-.1 1.1-.1 1.7v11.7c-13.2 3.2-16 17.8 0 24.1v14c0 .4 0 .9.1 1.3 0 .3-.1.6-.1.9v22.6c0 3.2 2.6 5.8 5.8 5.8h7.8c3.2 0 5.8-2.6 5.8-5.8V1498h29.3v12.8c0 3.2 2.6 5.8 5.8 5.8h7.8c3.2 0 5.8-2.6 5.8-5.8v-22.6c0-.3 0-.6-.1-.9 0-.4.1-.9.1-1.3v-13.5c.4-.1.9-.3 1.3-.5 15.8-6.3 13-21-.3-24.2z" class="st159" fill="#965e8c" stroke="#5c3556" stroke-width="2.28270006" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="line6826" fill="#fbe6c6" stroke="#5c3556" stroke-width="2.28270006" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" d="M1371.8 1498h40.7"/><g id="g6828"><path id="path6830" d="M1416.3 1413.5c.8 1.1 1.5 2.2 2.1 3.4" class="st161" fill="none" stroke="#b895a6" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6832" d="M1410.8 1407.6c.9.8 1.8 1.6 2.7 2.5" class="st161" fill="none" stroke="#b895a6" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6834" d="M1372 1407.4c5.3-4.2 12-6.7 19.2-6.7 6.4 0 12.3 2 17.3 5.3" class="st161" fill="none" stroke="#b895a6" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/></g><path id="polyline6836" class="st162" fill="none" stroke="#5c3556" stroke-width="2.28270006" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" d="M1357.3 1471.9v-10.4l3-2.1"/><path id="polyline6838" class="st162" fill="none" stroke="#5c3556" stroke-width="2.28270006" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" d="M1425.2 1472.4v-11.6l-3-2.1"/></g><path id="path6840" d="M542.7 483.19998c0-6.8-2.8-11.9-6.9-11.9-4.1 0-6.7 4.1-6.7 11.9v17.4c0 4.8.5 11.1 6.8 11.1s4.8-17.9 4.8-17.9" class="st163" fill="#fbe6c6"/><path id="path6842" d="M595.4 483.19998c0-6.8 2.8-11.9 6.9-11.9 4 0 6.7 4.1 6.7 11.9v17.4c0 4.8-.5 11.1-6.8 11.1s-4.8-17.9-4.8-17.9" class="st163" fill="#fbe6c6"/><path id="path6844" d="M629.5 500.89998c-2.4-2.8-6.8-3.1-9.7-.8-6.2 4.9-9.9 7.4-16.1 11v-11.1c0-.6-.1-1.1-.1-1.7.1-.9.1-1.9.1-2.9 0-18.7-15.2-30.7-33.9-30.7s-33.9 12-33.9 30.7c0 1 0 1.9.1 2.9-.1.5-.1 1.1-.1 1.7v9.7c-5.8-3.4-9.4-5.8-15.3-10.6-2.9-2.3-7.2-2-9.7.8-2.4 2.8-1.9 7.3 1.3 9.9 7.6 6 11.7 8.7 20.1 13.4 1.2.7 2.4 1 3.6 1v25.6c0 .4 0 .9.1 1.3 0 .3-.1.6-.1.9v22.6c0 3.2 2.6 5.8 5.8 5.8h7.8c3.2 0 5.8-2.6 5.8-5.8v-12.8h29.3v12.8c0 3.2 2.6 5.8 5.8 5.8h7.8c3.2 0 5.8-2.6 5.8-5.8v-22.6c0-.3 0-.6-.1-.9 0-.4.1-.9.1-1.3v-24.8c1.5.2 3-.1 4.4-.9 8.4-4.7 12.5-7.4 20.1-13.4 2.9-2.4 3.4-6.9 1-9.8z" class="st108" fill="#fbe6c6" stroke="#668794" stroke-width="2.28270006" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="line6846" class="st108" fill="#fbe6c6" stroke="#668794" stroke-width="2.28270006" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" d="M550.30005 561.90002H591"/><path id="path6848" d="M565.4 557.39998c3.9 9.1 16.6 9.5 23.8 3.7 2.8-2.2 2.4-4.5-1.9-3.7-4.3.7-10.6 3.9-15.6-2" class="st108" fill="#fbe6c6" stroke="#668794" stroke-width="2.28270006" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6850" d="M650.8 557.39998c3.9 9.1 16.6 9.5 23.8 3.7 2.8-2.2 2.4-4.5-1.9-3.7-4.3.8-10.6 3.9-15.6-2" class="st159" fill="#965e8c" stroke="#5c3556" stroke-width="2.28270006" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6852" d="M550.5 472.49998c-3.4-7.4 3.2-16.2 17.7-12.8 0 0 16.5-3.7 19.8-2.6 2.7 1 3.2 3.5 0 4.8 0 0 3.2 3.7-.8 5.3 0 0 1.1 4.3-3.6 5.3s-13.4 0-13.4 0" class="st108" fill="#fbe6c6" stroke="#668794" stroke-width="2.28270006" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6854" d="M580.1 466.59998c3.2-.1 7.1.6 7.1.6" class="st108" fill="#fbe6c6" stroke="#668794" stroke-width="2.28270006" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6856" d="M578.6 461.89998s4.8-1 9.3 0" class="st108" fill="#fbe6c6" stroke="#668794" stroke-width="2.28270006" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6858" d="M966.2 358.39998c3.2-4.1 7.7-4.8 10.8 0" class="st132" fill="none" stroke="#402f19" stroke-width="4.32690001" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><g transform="translate(-733 -934.40002)" id="g6860"><path id="polygon6862" class="st164" fill="#e14741" stroke="#552814" stroke-width="3.29229999" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" d="M1819.8 1370.2v-67.5l-38.8-14.3-60.6 14.4v69.2l40.2 17.1z"/><path id="polygon6864" class="st164" fill="#e14741" stroke="#552814" stroke-width="3.29229999" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" d="M1781 1288.4l-60.6 14.4 40.1 13 59.3-13.1z"/><path id="polygon6866" class="st164" fill="#e14741" stroke="#552814" stroke-width="3.29229999" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" d="M1819.8 1302.7l-59.3 13.1.1 73.3 59.2-15.1z"/></g><path id="path6868" d="M950.1 415.39998c13 12.2 29.5 18.9 48.8 15.1 7.6-1.5 9.4-19.1-3.3-19.4 0 0-1.8-6.5-6.1-5.7-4.3.8-2.4 5.7-2.4 5.7s-18.6-4.6-25.9-12.2" class="st131" fill="#fbc16c" stroke="#946f3a" stroke-width="3.29229999" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6874" d="M360.1 496.99998c6 5.8 11.8 5 18.2-.6 2.5-2.2 4.6.9.6 4.9-4 4-13.5 8.3-22 .8" class="st109" fill="#dcceb5" stroke="#668794" stroke-width="2.28270006" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6876" d="M733.9 463.19998c2.2-1.9 6.1-3.7 14.1 0 0 0 8.5-1.3 13.5-3.3" fill="none" stroke="#f7ceb2" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path transform="translate(-733 -934.40002)" id="polygon6878" class="st45" fill="#fbc16c" d="M1784.4 1350.6l-9.2-5.6 12.1-4 4.7-12.3 4.7 10.1 12.1-2.1-9.2 10.2 2.8 11-10.4-3.7-10.4 8.8z"/><circle id="circle6880" r="38.400002" cy="585.90002" cx="616.30005" class="st82" fill="#2d3f68"/><circle id="circle6882" r="38.400002" cy="582.19995" cx="996.80005" class="st82" fill="#2d3f68"/><g transform="translate(-733 -934.40002)" id="g6884"><g id="g6886"><path id="polygon6888" class="st33" fill="#fff" d="M1340.7 1520v7.9h12.5l4.5 6.1h-22.8v-14h-6.5l9.2-10.9 9.4 10.9z"/></g><g id="g6890"><path id="polygon6892" class="st33" fill="#fff" d="M1359.5 1522v-7.9H1347l-4.5-6.1h22.8v13.9l6.5.1-9.3 10.9-9.3-10.9z"/></g></g><circle id="circle6894" r="38.400002" cy="582.19995" cx="265.5" class="st82" fill="#2d3f68"/><path id="path6896" d="M283.1 579.99998c-4.8-8.9-19.9-8.5-25.1-8.1v-7.9l-13.5 13.5 13.5 13.5v-7.6c16.4 0 22.9.4 21.9 16.7 0 .2 9-9.3 3.2-20.1z" class="st33" fill="#fff"/><g transform="translate(-733 -934.40002)" id="g6898"><path id="polygon6900" class="st33" fill="#fff" d="M1738.4 1521.3l3.2 13.4-11.8-7.2-11.8 7.2 3.2-13.4-10.4-9 13.7-1.1 5.3-12.8 5.3 12.8 13.8 1.1z"/></g><path id="line6910" fill="none" stroke="#e69985" stroke-width="3.29229999" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" d="M1032 385l51-12"/></svg>
diff --git a/app/javascript/mastodon/actions/notifications.js b/app/javascript/mastodon/actions/notifications.js
index d24f39ad2..4c145febc 100644
--- a/app/javascript/mastodon/actions/notifications.js
+++ b/app/javascript/mastodon/actions/notifications.js
@@ -8,6 +8,7 @@ import {
   importFetchedStatuses,
 } from './importer';
 import { defineMessages } from 'react-intl';
+import { List as ImmutableList } from 'immutable';
 import { unescapeHTML } from '../utils/html';
 import { getFilters, regexFromFilters } from '../selectors';
 
@@ -18,6 +19,8 @@ export const NOTIFICATIONS_EXPAND_REQUEST = 'NOTIFICATIONS_EXPAND_REQUEST';
 export const NOTIFICATIONS_EXPAND_SUCCESS = 'NOTIFICATIONS_EXPAND_SUCCESS';
 export const NOTIFICATIONS_EXPAND_FAIL    = 'NOTIFICATIONS_EXPAND_FAIL';
 
+export const NOTIFICATIONS_FILTER_SET = 'NOTIFICATIONS_FILTER_SET';
+
 export const NOTIFICATIONS_CLEAR      = 'NOTIFICATIONS_CLEAR';
 export const NOTIFICATIONS_SCROLL_TOP = 'NOTIFICATIONS_SCROLL_TOP';
 
@@ -88,10 +91,16 @@ export function updateNotifications(notification, intlMessages, intlLocale) {
 
 const excludeTypesFromSettings = state => state.getIn(['settings', 'notifications', 'shows']).filter(enabled => !enabled).keySeq().toJS();
 
+const excludeTypesFromFilter = filter => {
+  const allTypes = ImmutableList(['follow', 'favourite', 'reblog', 'mention']);
+  return allTypes.filterNot(item => item === filter).toJS();
+};
+
 const noOp = () => {};
 
 export function expandNotifications({ maxId } = {}, done = noOp) {
   return (dispatch, getState) => {
+    const activeFilter = getState().getIn(['settings', 'notifications', 'quickFilter', 'active']);
     const notifications = getState().get('notifications');
     const isLoadingMore = !!maxId;
 
@@ -102,7 +111,9 @@ export function expandNotifications({ maxId } = {}, done = noOp) {
 
     const params = {
       max_id: maxId,
-      exclude_types: excludeTypesFromSettings(getState()),
+      exclude_types: activeFilter === 'all'
+        ? excludeTypesFromSettings(getState())
+        : excludeTypesFromFilter(activeFilter),
     };
 
     if (!maxId && notifications.get('items').size > 0) {
@@ -167,3 +178,14 @@ export function scrollTopNotifications(top) {
     top,
   };
 };
+
+export function setFilter (filterType) {
+  return dispatch => {
+    dispatch({
+      type: NOTIFICATIONS_FILTER_SET,
+      path: ['notifications', 'quickFilter', 'active'],
+      value: filterType,
+    });
+    dispatch(expandNotifications());
+  };
+};
diff --git a/app/javascript/mastodon/actions/onboarding.js b/app/javascript/mastodon/actions/onboarding.js
index a161c50ef..a1dd3a731 100644
--- a/app/javascript/mastodon/actions/onboarding.js
+++ b/app/javascript/mastodon/actions/onboarding.js
@@ -1,14 +1,8 @@
-import { openModal } from './modal';
 import { changeSetting, saveSettings } from './settings';
 
-export function showOnboardingOnce() {
-  return (dispatch, getState) => {
-    const alreadySeen = getState().getIn(['settings', 'onboarded']);
+export const INTRODUCTION_VERSION = 20181216044202;
 
-    if (!alreadySeen) {
-      dispatch(openModal('ONBOARDING'));
-      dispatch(changeSetting(['onboarded'], true));
-      dispatch(saveSettings());
-    }
-  };
+export const closeOnboarding = () => dispatch => {
+  dispatch(changeSetting(['introductionVersion'], INTRODUCTION_VERSION));
+  dispatch(saveSettings());
 };
diff --git a/app/javascript/mastodon/components/column_header.js b/app/javascript/mastodon/components/column_header.js
index 457508d13..f68e4155e 100644
--- a/app/javascript/mastodon/components/column_header.js
+++ b/app/javascript/mastodon/components/column_header.js
@@ -37,6 +37,14 @@ class ColumnHeader extends React.PureComponent {
     animating: false,
   };
 
+  historyBack = () => {
+    if (window.history && window.history.length === 1) {
+      this.context.router.history.push('/');
+    } else {
+      this.context.router.history.goBack();
+    }
+  }
+
   handleToggleClick = (e) => {
     e.stopPropagation();
     this.setState({ collapsed: !this.state.collapsed, animating: true });
@@ -55,16 +63,22 @@ class ColumnHeader extends React.PureComponent {
   }
 
   handleBackClick = () => {
-    if (window.history && window.history.length === 1) this.context.router.history.push('/');
-    else this.context.router.history.goBack();
+    this.historyBack();
   }
 
   handleTransitionEnd = () => {
     this.setState({ animating: false });
   }
 
+  handlePin = () => {
+    if (!this.props.pinned) {
+      this.historyBack();
+    }
+    this.props.onPin();
+  }
+
   render () {
-    const { title, icon, active, children, pinned, onPin, multiColumn, extraButton, showBackButton, intl: { formatMessage } } = this.props;
+    const { title, icon, active, children, pinned, multiColumn, extraButton, showBackButton, intl: { formatMessage } } = this.props;
     const { collapsed, animating } = this.state;
 
     const wrapperClassName = classNames('column-header__wrapper', {
@@ -95,7 +109,7 @@ class ColumnHeader extends React.PureComponent {
     }
 
     if (multiColumn && pinned) {
-      pinButton = <button key='pin-button' className='text-btn column-header__setting-btn' onClick={onPin}><i className='fa fa fa-times' /> <FormattedMessage id='column_header.unpin' defaultMessage='Unpin' /></button>;
+      pinButton = <button key='pin-button' className='text-btn column-header__setting-btn' onClick={this.handlePin}><i className='fa fa fa-times' /> <FormattedMessage id='column_header.unpin' defaultMessage='Unpin' /></button>;
 
       moveButtons = (
         <div key='move-buttons' className='column-header__setting-arrows'>
@@ -104,7 +118,7 @@ class ColumnHeader extends React.PureComponent {
         </div>
       );
     } else if (multiColumn) {
-      pinButton = <button key='pin-button' className='text-btn column-header__setting-btn' onClick={onPin}><i className='fa fa fa-plus' /> <FormattedMessage id='column_header.pin' defaultMessage='Pin' /></button>;
+      pinButton = <button key='pin-button' className='text-btn column-header__setting-btn' onClick={this.handlePin}><i className='fa fa fa-plus' /> <FormattedMessage id='column_header.pin' defaultMessage='Pin' /></button>;
     }
 
     if (!pinned && (multiColumn || showBackButton)) {
diff --git a/app/javascript/mastodon/containers/mastodon.js b/app/javascript/mastodon/containers/mastodon.js
index b2b0265aa..2912540a0 100644
--- a/app/javascript/mastodon/containers/mastodon.js
+++ b/app/javascript/mastodon/containers/mastodon.js
@@ -1,11 +1,12 @@
 import React from 'react';
-import { Provider } from 'react-redux';
+import { Provider, connect } from 'react-redux';
 import PropTypes from 'prop-types';
 import configureStore from '../store/configureStore';
-import { showOnboardingOnce } from '../actions/onboarding';
+import { INTRODUCTION_VERSION } from '../actions/onboarding';
 import { BrowserRouter, Route } from 'react-router-dom';
 import { ScrollContext } from 'react-router-scroll-4';
 import UI from '../features/ui';
+import Introduction from '../features/introduction';
 import { fetchCustomEmojis } from '../actions/custom_emojis';
 import { hydrateStore } from '../actions/store';
 import { connectUserStream } from '../actions/streaming';
@@ -18,11 +19,39 @@ addLocaleData(localeData);
 
 export const store = configureStore();
 const hydrateAction = hydrateStore(initialState);
-store.dispatch(hydrateAction);
 
-// load custom emojis
+store.dispatch(hydrateAction);
 store.dispatch(fetchCustomEmojis());
 
+const mapStateToProps = state => ({
+  showIntroduction: state.getIn(['settings', 'introductionVersion'], 0) < INTRODUCTION_VERSION,
+});
+
+@connect(mapStateToProps)
+class MastodonMount extends React.PureComponent {
+
+  static propTypes = {
+    showIntroduction: PropTypes.bool,
+  };
+
+  render () {
+    const { showIntroduction } = this.props;
+
+    if (showIntroduction) {
+      return <Introduction />;
+    }
+
+    return (
+      <BrowserRouter basename='/web'>
+        <ScrollContext>
+          <Route path='/' component={UI} />
+        </ScrollContext>
+      </BrowserRouter>
+    );
+  }
+
+}
+
 export default class Mastodon extends React.PureComponent {
 
   static propTypes = {
@@ -31,14 +60,6 @@ export default class Mastodon extends React.PureComponent {
 
   componentDidMount() {
     this.disconnect = store.dispatch(connectUserStream());
-
-    // Desktop notifications
-    // Ask after 1 minute
-    if (typeof window.Notification !== 'undefined' && Notification.permission === 'default') {
-      window.setTimeout(() => Notification.requestPermission(), 60 * 1000);
-    }
-
-    store.dispatch(showOnboardingOnce());
   }
 
   componentWillUnmount () {
@@ -54,11 +75,7 @@ export default class Mastodon extends React.PureComponent {
     return (
       <IntlProvider locale={locale} messages={messages}>
         <Provider store={store}>
-          <BrowserRouter basename='/web'>
-            <ScrollContext>
-              <Route path='/' component={UI} />
-            </ScrollContext>
-          </BrowserRouter>
+          <MastodonMount />
         </Provider>
       </IntlProvider>
     );
diff --git a/app/javascript/mastodon/features/account_gallery/index.js b/app/javascript/mastodon/features/account_gallery/index.js
index 0d66868ed..96051818b 100644
--- a/app/javascript/mastodon/features/account_gallery/index.js
+++ b/app/javascript/mastodon/features/account_gallery/index.js
@@ -103,7 +103,7 @@ class AccountGallery extends ImmutablePureComponent {
       );
     }
 
-    if (hasMore) {
+    if (hasMore && !(isLoading && medias.size === 0)) {
       loadOlder = <LoadMore visible={!isLoading} onClick={this.handleLoadOlder} />;
     }
 
diff --git a/app/javascript/mastodon/features/compose/components/compose_form.js b/app/javascript/mastodon/features/compose/components/compose_form.js
index 4b56c7fdd..d6add9b0d 100644
--- a/app/javascript/mastodon/features/compose/components/compose_form.js
+++ b/app/javascript/mastodon/features/compose/components/compose_form.js
@@ -47,6 +47,7 @@ class ComposeForm extends ImmutablePureComponent {
     caretPosition: PropTypes.number,
     preselectDate: PropTypes.instanceOf(Date),
     is_submitting: PropTypes.bool,
+    is_changing_upload: PropTypes.bool,
     is_uploading: PropTypes.bool,
     onChange: PropTypes.func.isRequired,
     onSubmit: PropTypes.func.isRequired,
@@ -82,10 +83,10 @@ class ComposeForm extends ImmutablePureComponent {
     }
 
     // Submit disabled:
-    const { is_submitting, is_uploading, anyMedia } = this.props;
+    const { is_submitting, is_changing_upload, is_uploading, anyMedia } = this.props;
     const fulltext = [this.props.spoiler_text, countableText(this.props.text)].join('');
 
-    if (is_submitting || is_uploading || length(fulltext) > maxChars || (fulltext.length !== 0 && fulltext.trim().length === 0 && !anyMedia)) {
+    if (is_submitting || is_uploading || is_changing_upload || length(fulltext) > maxChars || (fulltext.length !== 0 && fulltext.trim().length === 0 && !anyMedia)) {
       return;
     }
 
@@ -161,7 +162,7 @@ class ComposeForm extends ImmutablePureComponent {
     const { intl, onPaste, showSearch, anyMedia } = this.props;
     const disabled = this.props.is_submitting;
     const text     = [this.props.spoiler_text, countableText(this.props.text)].join('');
-    const disabledButton = disabled || this.props.is_uploading || length(text) > maxChars || (text.length !== 0 && text.trim().length === 0 && !anyMedia);
+    const disabledButton = disabled || this.props.is_uploading || this.props.is_changing_upload || length(text) > maxChars || (text.length !== 0 && text.trim().length === 0 && !anyMedia);
     let publishText = '';
 
     if (this.props.privacy === 'private' || this.props.privacy === 'direct') {
diff --git a/app/javascript/mastodon/features/compose/containers/compose_form_container.js b/app/javascript/mastodon/features/compose/containers/compose_form_container.js
index 5d7fb8852..b4a1c4b44 100644
--- a/app/javascript/mastodon/features/compose/containers/compose_form_container.js
+++ b/app/javascript/mastodon/features/compose/containers/compose_form_container.js
@@ -22,6 +22,7 @@ const mapStateToProps = state => ({
   caretPosition: state.getIn(['compose', 'caretPosition']),
   preselectDate: state.getIn(['compose', 'preselectDate']),
   is_submitting: state.getIn(['compose', 'is_submitting']),
+  is_changing_upload: state.getIn(['compose', 'is_changing_upload']),
   is_uploading: state.getIn(['compose', 'is_uploading']),
   showSearch: state.getIn(['search', 'submitted']) && !state.getIn(['search', 'hidden']),
   anyMedia: state.getIn(['compose', 'media_attachments']).size > 0,
diff --git a/app/javascript/mastodon/features/introduction/index.js b/app/javascript/mastodon/features/introduction/index.js
new file mode 100644
index 000000000..6e0617f72
--- /dev/null
+++ b/app/javascript/mastodon/features/introduction/index.js
@@ -0,0 +1,196 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import ReactSwipeableViews from 'react-swipeable-views';
+import classNames from 'classnames';
+import { connect } from 'react-redux';
+import { FormattedMessage } from 'react-intl';
+import { closeOnboarding } from '../../actions/onboarding';
+import screenHello from '../../../images/screen_hello.svg';
+import screenFederation from '../../../images/screen_federation.svg';
+import screenInteractions from '../../../images/screen_interactions.svg';
+import logoTransparent from '../../../images/logo_transparent.svg';
+
+const FrameWelcome = ({ domain, onNext }) => (
+  <div className='introduction__frame'>
+    <div className='introduction__illustration' style={{ background: `url(${logoTransparent}) no-repeat center center / auto 80%` }}>
+      <img src={screenHello} alt='' />
+    </div>
+
+    <div className='introduction__text introduction__text--centered'>
+      <h3><FormattedMessage id='introduction.welcome.headline' defaultMessage='First steps' /></h3>
+      <p><FormattedMessage id='introduction.welcome.text' defaultMessage="Welcome to the fediverse! In a few moments, you'll be able to broadcast messages and talk to your friends across a wide variety of servers. But this server, {domain}, is special—it hosts your profile, so remember its name." values={{ domain: <code>{domain}</code> }} /></p>
+    </div>
+
+    <div className='introduction__action'>
+      <button className='button' onClick={onNext}><FormattedMessage id='introduction.welcome.action' defaultMessage="Let's go!" /></button>
+    </div>
+  </div>
+);
+
+FrameWelcome.propTypes = {
+  domain: PropTypes.string.isRequired,
+  onNext: PropTypes.func.isRequired,
+};
+
+const FrameFederation = ({ onNext }) => (
+  <div className='introduction__frame'>
+    <div className='introduction__illustration'>
+      <img src={screenFederation} alt='' />
+    </div>
+
+    <div className='introduction__text introduction__text--columnized'>
+      <div>
+        <h3><FormattedMessage id='introduction.federation.home.headline' defaultMessage='Home' /></h3>
+        <p><FormattedMessage id='introduction.federation.home.text' defaultMessage='Posts from people you follow will appear in your home feed. You can follow anyone on any server!' /></p>
+      </div>
+
+      <div>
+        <h3><FormattedMessage id='introduction.federation.local.headline' defaultMessage='Local' /></h3>
+        <p><FormattedMessage id='introduction.federation.local.text' defaultMessage='Public posts from people on the same server as you will appear in the local timeline.' /></p>
+      </div>
+
+      <div>
+        <h3><FormattedMessage id='introduction.federation.federated.headline' defaultMessage='Federated' /></h3>
+        <p><FormattedMessage id='introduction.federation.federated.text' defaultMessage='Public posts from other servers of the fediverse will appear in the federated timeline.' /></p>
+      </div>
+    </div>
+
+    <div className='introduction__action'>
+      <button className='button' onClick={onNext}><FormattedMessage id='introduction.federation.action' defaultMessage='Next' /></button>
+    </div>
+  </div>
+);
+
+FrameFederation.propTypes = {
+  onNext: PropTypes.func.isRequired,
+};
+
+const FrameInteractions = ({ onNext }) => (
+  <div className='introduction__frame'>
+    <div className='introduction__illustration'>
+      <img src={screenInteractions} alt='' />
+    </div>
+
+    <div className='introduction__text introduction__text--columnized'>
+      <div>
+        <h3><FormattedMessage id='introduction.interactions.reply.headline' defaultMessage='Reply' /></h3>
+        <p><FormattedMessage id='introduction.interactions.reply.text' defaultMessage="You can reply to other people's and your own toots, which will chain them together in a conversation." /></p>
+      </div>
+
+      <div>
+        <h3><FormattedMessage id='introduction.interactions.reblog.headline' defaultMessage='Boost' /></h3>
+        <p><FormattedMessage id='introduction.interactions.reblog.text' defaultMessage="You can share other people's toots with your followers by boosting them." /></p>
+      </div>
+
+      <div>
+        <h3><FormattedMessage id='introduction.interactions.favourite.headline' defaultMessage='Favourite' /></h3>
+        <p><FormattedMessage id='introduction.interactions.favourite.text' defaultMessage='You can save a toot for later, and let the author know that you liked it, by favouriting it.' /></p>
+      </div>
+    </div>
+
+    <div className='introduction__action'>
+      <button className='button' onClick={onNext}><FormattedMessage id='introduction.interactions.action' defaultMessage='Finish tutorial!' /></button>
+    </div>
+  </div>
+);
+
+FrameInteractions.propTypes = {
+  onNext: PropTypes.func.isRequired,
+};
+
+@connect(state => ({ domain: state.getIn(['meta', 'domain']) }))
+export default class Introduction extends React.PureComponent {
+
+  static propTypes = {
+    domain: PropTypes.string.isRequired,
+    dispatch: PropTypes.func.isRequired,
+  };
+
+  state = {
+    currentIndex: 0,
+  };
+
+  componentWillMount () {
+    this.pages = [
+      <FrameWelcome domain={this.props.domain} onNext={this.handleNext} />,
+      <FrameFederation onNext={this.handleNext} />,
+      <FrameInteractions onNext={this.handleFinish} />,
+    ];
+  }
+
+  componentDidMount() {
+    window.addEventListener('keyup', this.handleKeyUp);
+  }
+
+  componentWillUnmount() {
+    window.addEventListener('keyup', this.handleKeyUp);
+  }
+
+  handleDot = (e) => {
+    const i = Number(e.currentTarget.getAttribute('data-index'));
+    e.preventDefault();
+    this.setState({ currentIndex: i });
+  }
+
+  handlePrev = () => {
+    this.setState(({ currentIndex }) => ({
+      currentIndex: Math.max(0, currentIndex - 1),
+    }));
+  }
+
+  handleNext = () => {
+    const { pages } = this;
+
+    this.setState(({ currentIndex }) => ({
+      currentIndex: Math.min(currentIndex + 1, pages.length - 1),
+    }));
+  }
+
+  handleSwipe = (index) => {
+    this.setState({ currentIndex: index });
+  }
+
+  handleFinish = () => {
+    this.props.dispatch(closeOnboarding());
+  }
+
+  handleKeyUp = ({ key }) => {
+    switch (key) {
+    case 'ArrowLeft':
+      this.handlePrev();
+      break;
+    case 'ArrowRight':
+      this.handleNext();
+      break;
+    }
+  }
+
+  render () {
+    const { currentIndex } = this.state;
+    const { pages } = this;
+
+    return (
+      <div className='introduction'>
+        <ReactSwipeableViews index={currentIndex} onChangeIndex={this.handleSwipe} className='introduction__pager'>
+          {pages.map((page, i) => (
+            <div key={i} className={classNames('introduction__frame-wrapper', { 'active': i === currentIndex })}>{page}</div>
+          ))}
+        </ReactSwipeableViews>
+
+        <div className='introduction__dots'>
+          {pages.map((_, i) => (
+            <div
+              key={`dot-${i}`}
+              role='button'
+              tabIndex='0'
+              data-index={i}
+              onClick={this.handleDot}
+              className={classNames('introduction__dot', { active: i === currentIndex })}
+            />
+          ))}
+        </div>
+      </div>
+    );
+  }
+
+}
diff --git a/app/javascript/mastodon/features/notifications/components/column_settings.js b/app/javascript/mastodon/features/notifications/components/column_settings.js
index fcdf5c6e6..a334fd63c 100644
--- a/app/javascript/mastodon/features/notifications/components/column_settings.js
+++ b/app/javascript/mastodon/features/notifications/components/column_settings.js
@@ -21,9 +21,11 @@ export default class ColumnSettings extends React.PureComponent {
   render () {
     const { settings, pushSettings, onChange, onClear } = this.props;
 
-    const alertStr = <FormattedMessage id='notifications.column_settings.alert' defaultMessage='Desktop notifications' />;
-    const showStr  = <FormattedMessage id='notifications.column_settings.show' defaultMessage='Show in column' />;
-    const soundStr = <FormattedMessage id='notifications.column_settings.sound' defaultMessage='Play sound' />;
+    const filterShowStr = <FormattedMessage id='notifications.column_settings.filter_bar.show' defaultMessage='Show' />;
+    const filterAdvancedStr = <FormattedMessage id='notifications.column_settings.filter_bar.advanced' defaultMessage='Display all categories' />;
+    const alertStr  = <FormattedMessage id='notifications.column_settings.alert' defaultMessage='Desktop notifications' />;
+    const showStr   = <FormattedMessage id='notifications.column_settings.show' defaultMessage='Show in column' />;
+    const soundStr  = <FormattedMessage id='notifications.column_settings.sound' defaultMessage='Play sound' />;
 
     const showPushSettings = pushSettings.get('browserSupport') && pushSettings.get('isSubscribed');
     const pushStr = showPushSettings && <FormattedMessage id='notifications.column_settings.push' defaultMessage='Push notifications' />;
@@ -34,6 +36,16 @@ export default class ColumnSettings extends React.PureComponent {
           <ClearColumnButton onClick={onClear} />
         </div>
 
+        <div role='group' aria-labelledby='notifications-filter-bar'>
+          <span id='notifications-filter-bar' className='column-settings__section'>
+            <FormattedMessage id='notifications.column_settings.filter_bar.category' defaultMessage='Quick filter bar' />
+          </span>
+          <div className='column-settings__row'>
+            <SettingToggle id='show-filter-bar' prefix='notifications' settings={settings} settingPath={['quickFilter', 'show']} onChange={onChange} label={filterShowStr} />
+            <SettingToggle id='show-filter-bar' prefix='notifications' settings={settings} settingPath={['quickFilter', 'advanced']} onChange={onChange} label={filterAdvancedStr} />
+          </div>
+        </div>
+
         <div role='group' aria-labelledby='notifications-follow'>
           <span id='notifications-follow' className='column-settings__section'><FormattedMessage id='notifications.column_settings.follow' defaultMessage='New followers:' /></span>
 
diff --git a/app/javascript/mastodon/features/notifications/components/filter_bar.js b/app/javascript/mastodon/features/notifications/components/filter_bar.js
new file mode 100644
index 000000000..f95a2c9de
--- /dev/null
+++ b/app/javascript/mastodon/features/notifications/components/filter_bar.js
@@ -0,0 +1,93 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
+
+const tooltips = defineMessages({
+  mentions: { id: 'notifications.filter.mentions', defaultMessage: 'Mentions' },
+  favourites: { id: 'notifications.filter.favourites', defaultMessage: 'Favourites' },
+  boosts: { id: 'notifications.filter.boosts', defaultMessage: 'Boosts' },
+  follows: { id: 'notifications.filter.follows', defaultMessage: 'Follows' },
+});
+
+export default @injectIntl
+class FilterBar extends React.PureComponent {
+
+  static propTypes = {
+    selectFilter: PropTypes.func.isRequired,
+    selectedFilter: PropTypes.string.isRequired,
+    advancedMode: PropTypes.bool.isRequired,
+    intl: PropTypes.object.isRequired,
+  };
+
+  onClick (notificationType) {
+    return () => this.props.selectFilter(notificationType);
+  }
+
+  render () {
+    const { selectedFilter, advancedMode, intl } = this.props;
+    const renderedElement = !advancedMode ? (
+      <div className='notification__filter-bar'>
+        <button
+          className={selectedFilter === 'all' ? 'active' : ''}
+          onClick={this.onClick('all')}
+        >
+          <FormattedMessage
+            id='notifications.filter.all'
+            defaultMessage='All'
+          />
+        </button>
+        <button
+          className={selectedFilter === 'mention' ? 'active' : ''}
+          onClick={this.onClick('mention')}
+        >
+          <FormattedMessage
+            id='notifications.filter.mentions'
+            defaultMessage='Mentions'
+          />
+        </button>
+      </div>
+    ) : (
+      <div className='notification__filter-bar'>
+        <button
+          className={selectedFilter === 'all' ? 'active' : ''}
+          onClick={this.onClick('all')}
+        >
+          <FormattedMessage
+            id='notifications.filter.all'
+            defaultMessage='All'
+          />
+        </button>
+        <button
+          className={selectedFilter === 'mention' ? 'active' : ''}
+          onClick={this.onClick('mention')}
+          title={intl.formatMessage(tooltips.mentions)}
+        >
+          <i className='fa fa-fw fa-at' />
+        </button>
+        <button
+          className={selectedFilter === 'favourite' ? 'active' : ''}
+          onClick={this.onClick('favourite')}
+          title={intl.formatMessage(tooltips.favourites)}
+        >
+          <i className='fa fa-fw fa-star' />
+        </button>
+        <button
+          className={selectedFilter === 'reblog' ? 'active' : ''}
+          onClick={this.onClick('reblog')}
+          title={intl.formatMessage(tooltips.boosts)}
+        >
+          <i className='fa fa-fw fa-retweet' />
+        </button>
+        <button
+          className={selectedFilter === 'follow' ? 'active' : ''}
+          onClick={this.onClick('follow')}
+          title={intl.formatMessage(tooltips.follows)}
+        >
+          <i className='fa fa-fw fa-user-plus' />
+        </button>
+      </div>
+    );
+    return renderedElement;
+  }
+
+}
diff --git a/app/javascript/mastodon/features/notifications/containers/column_settings_container.js b/app/javascript/mastodon/features/notifications/containers/column_settings_container.js
index e9cef0a7b..a67f26295 100644
--- a/app/javascript/mastodon/features/notifications/containers/column_settings_container.js
+++ b/app/javascript/mastodon/features/notifications/containers/column_settings_container.js
@@ -2,6 +2,7 @@ import { connect } from 'react-redux';
 import { defineMessages, injectIntl } from 'react-intl';
 import ColumnSettings from '../components/column_settings';
 import { changeSetting } from '../../../actions/settings';
+import { setFilter } from '../../../actions/notifications';
 import { clearNotifications } from '../../../actions/notifications';
 import { changeAlerts as changePushNotifications } from '../../../actions/push_notifications';
 import { openModal } from '../../../actions/modal';
@@ -21,6 +22,9 @@ const mapDispatchToProps = (dispatch, { intl }) => ({
   onChange (path, checked) {
     if (path[0] === 'push') {
       dispatch(changePushNotifications(path.slice(1), checked));
+    } else if (path[0] === 'quickFilter') {
+      dispatch(changeSetting(['notifications', ...path], checked));
+      dispatch(setFilter('all'));
     } else {
       dispatch(changeSetting(['notifications', ...path], checked));
     }
diff --git a/app/javascript/mastodon/features/notifications/containers/filter_bar_container.js b/app/javascript/mastodon/features/notifications/containers/filter_bar_container.js
new file mode 100644
index 000000000..4d495c290
--- /dev/null
+++ b/app/javascript/mastodon/features/notifications/containers/filter_bar_container.js
@@ -0,0 +1,16 @@
+import { connect } from 'react-redux';
+import FilterBar from '../components/filter_bar';
+import { setFilter } from '../../../actions/notifications';
+
+const makeMapStateToProps = state => ({
+  selectedFilter: state.getIn(['settings', 'notifications', 'quickFilter', 'active']),
+  advancedMode: state.getIn(['settings', 'notifications', 'quickFilter', 'advanced']),
+});
+
+const mapDispatchToProps = (dispatch) => ({
+  selectFilter (newActiveFilter) {
+    dispatch(setFilter(newActiveFilter));
+  },
+});
+
+export default connect(makeMapStateToProps, mapDispatchToProps)(FilterBar);
diff --git a/app/javascript/mastodon/features/notifications/index.js b/app/javascript/mastodon/features/notifications/index.js
index aa82dbbb9..9430b2050 100644
--- a/app/javascript/mastodon/features/notifications/index.js
+++ b/app/javascript/mastodon/features/notifications/index.js
@@ -9,6 +9,7 @@ import { addColumn, removeColumn, moveColumn } from '../../actions/columns';
 import NotificationContainer from './containers/notification_container';
 import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
 import ColumnSettingsContainer from './containers/column_settings_container';
+import FilterBarContainer from './containers/filter_bar_container';
 import { createSelector } from 'reselect';
 import { List as ImmutableList } from 'immutable';
 import { debounce } from 'lodash';
@@ -20,11 +21,22 @@ const messages = defineMessages({
 });
 
 const getNotifications = createSelector([
+  state => state.getIn(['settings', 'notifications', 'quickFilter', 'show']),
+  state => state.getIn(['settings', 'notifications', 'quickFilter', 'active']),
   state => ImmutableList(state.getIn(['settings', 'notifications', 'shows']).filter(item => !item).keys()),
   state => state.getIn(['notifications', 'items']),
-], (excludedTypes, notifications) => notifications.filterNot(item => item !== null && excludedTypes.includes(item.get('type'))));
+], (showFilterBar, allowedType, excludedTypes, notifications) => {
+  if (!showFilterBar || allowedType === 'all') {
+    // used if user changed the notification settings after loading the notifications from the server
+    // otherwise a list of notifications will come pre-filtered from the backend
+    // we need to turn it off for FilterBar in order not to block ourselves from seeing a specific category
+    return notifications.filterNot(item => item !== null && excludedTypes.includes(item.get('type')));
+  }
+  return notifications.filter(item => item !== null && allowedType === item.get('type'));
+});
 
 const mapStateToProps = state => ({
+  showFilterBar: state.getIn(['settings', 'notifications', 'quickFilter', 'show']),
   notifications: getNotifications(state),
   isLoading: state.getIn(['notifications', 'isLoading'], true),
   isUnread: state.getIn(['notifications', 'unread']) > 0,
@@ -38,6 +50,7 @@ class Notifications extends React.PureComponent {
   static propTypes = {
     columnId: PropTypes.string,
     notifications: ImmutablePropTypes.list.isRequired,
+    showFilterBar: PropTypes.bool.isRequired,
     dispatch: PropTypes.func.isRequired,
     shouldUpdateScroll: PropTypes.func,
     intl: PropTypes.object.isRequired,
@@ -117,12 +130,16 @@ class Notifications extends React.PureComponent {
   }
 
   render () {
-    const { intl, notifications, shouldUpdateScroll, isLoading, isUnread, columnId, multiColumn, hasMore } = this.props;
+    const { intl, notifications, shouldUpdateScroll, isLoading, isUnread, columnId, multiColumn, hasMore, showFilterBar } = this.props;
     const pinned = !!columnId;
     const emptyMessage = <FormattedMessage id='empty_column.notifications' defaultMessage="You don't have any notifications yet. Interact with others to start the conversation." />;
 
     let scrollableContent = null;
 
+    const filterBarContainer = showFilterBar
+      ? (<FilterBarContainer />)
+      : null;
+
     if (isLoading && this.scrollableContent) {
       scrollableContent = this.scrollableContent;
     } else if (notifications.size > 0 || hasMore) {
@@ -179,7 +196,7 @@ class Notifications extends React.PureComponent {
         >
           <ColumnSettingsContainer />
         </ColumnHeader>
-
+        {filterBarContainer}
         {scrollContainer}
       </Column>
     );
diff --git a/app/javascript/mastodon/features/ui/components/modal_root.js b/app/javascript/mastodon/features/ui/components/modal_root.js
index b3b1ea862..cc2ab6c8c 100644
--- a/app/javascript/mastodon/features/ui/components/modal_root.js
+++ b/app/javascript/mastodon/features/ui/components/modal_root.js
@@ -11,7 +11,6 @@ import BoostModal from './boost_modal';
 import ConfirmationModal from './confirmation_modal';
 import FocalPointModal from './focal_point_modal';
 import {
-  OnboardingModal,
   MuteModal,
   ReportModal,
   EmbedModal,
@@ -21,7 +20,6 @@ import {
 
 const MODAL_COMPONENTS = {
   'MEDIA': () => Promise.resolve({ default: MediaModal }),
-  'ONBOARDING': OnboardingModal,
   'VIDEO': () => Promise.resolve({ default: VideoModal }),
   'BOOST': () => Promise.resolve({ default: BoostModal }),
   'CONFIRM': () => Promise.resolve({ default: ConfirmationModal }),
diff --git a/app/javascript/mastodon/features/ui/components/onboarding_modal.js b/app/javascript/mastodon/features/ui/components/onboarding_modal.js
deleted file mode 100644
index 4a5b249c9..000000000
--- a/app/javascript/mastodon/features/ui/components/onboarding_modal.js
+++ /dev/null
@@ -1,324 +0,0 @@
-import React from 'react';
-import { connect } from 'react-redux';
-import PropTypes from 'prop-types';
-import ImmutablePropTypes from 'react-immutable-proptypes';
-import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
-import ReactSwipeableViews from 'react-swipeable-views';
-import classNames from 'classnames';
-import Permalink from '../../../components/permalink';
-import ComposeForm from '../../compose/components/compose_form';
-import Search from '../../compose/components/search';
-import NavigationBar from '../../compose/components/navigation_bar';
-import ColumnHeader from './column_header';
-import { List as ImmutableList } from 'immutable';
-import { me } from '../../../initial_state';
-
-const noop = () => { };
-
-const messages = defineMessages({
-  home_title: { id: 'column.home', defaultMessage: 'Home' },
-  notifications_title: { id: 'column.notifications', defaultMessage: 'Notifications' },
-  local_title: { id: 'column.community', defaultMessage: 'Local timeline' },
-  federated_title: { id: 'column.public', defaultMessage: 'Federated timeline' },
-});
-
-const PageOne = ({ acct, domain }) => (
-  <div className='onboarding-modal__page onboarding-modal__page-one'>
-    <div className='onboarding-modal__page-one__lead'>
-      <h1><FormattedMessage id='onboarding.page_one.welcome' defaultMessage='Welcome to Mastodon!' /></h1>
-      <p><FormattedMessage id='onboarding.page_one.federation' defaultMessage='Mastodon is a network of independent servers joining up to make one larger social network. We call these servers instances.' /></p>
-    </div>
-
-    <div className='onboarding-modal__page-one__extra'>
-      <div className='display-case'>
-        <div className='display-case__label'>
-          <FormattedMessage id='onboarding.page_one.full_handle' defaultMessage='Your full handle' />
-        </div>
-
-        <div className='display-case__case'>
-          @{acct}@{domain}
-        </div>
-      </div>
-
-      <p><FormattedMessage id='onboarding.page_one.handle_hint' defaultMessage='This is what you would tell your friends to search for.' /></p>
-    </div>
-  </div>
-);
-
-PageOne.propTypes = {
-  acct: PropTypes.string.isRequired,
-  domain: PropTypes.string.isRequired,
-};
-
-const PageTwo = ({ myAccount }) => (
-  <div className='onboarding-modal__page onboarding-modal__page-two'>
-    <div className='figure non-interactive'>
-      <div className='pseudo-drawer'>
-        <NavigationBar account={myAccount} />
-
-        <ComposeForm
-          text='Awoo! #introductions'
-          suggestions={ImmutableList()}
-          mentionedDomains={[]}
-          spoiler={false}
-          onChange={noop}
-          onSubmit={noop}
-          onPaste={noop}
-          onPickEmoji={noop}
-          onChangeSpoilerText={noop}
-          onClearSuggestions={noop}
-          onFetchSuggestions={noop}
-          onSuggestionSelected={noop}
-          showSearch
-        />
-      </div>
-    </div>
-
-    <p><FormattedMessage id='onboarding.page_two.compose' defaultMessage='Write posts from the compose column. You can upload images, change privacy settings, and add content warnings with the icons below.' /></p>
-  </div>
-);
-
-PageTwo.propTypes = {
-  myAccount: ImmutablePropTypes.map.isRequired,
-};
-
-const PageThree = ({ myAccount }) => (
-  <div className='onboarding-modal__page onboarding-modal__page-three'>
-    <div className='figure non-interactive'>
-      <Search
-        value=''
-        onChange={noop}
-        onSubmit={noop}
-        onClear={noop}
-        onShow={noop}
-      />
-
-      <div className='pseudo-drawer'>
-        <NavigationBar account={myAccount} />
-      </div>
-    </div>
-
-    <p><FormattedMessage id='onboarding.page_three.search' defaultMessage='Use the search bar to find people and look at hashtags, such as {illustration} and {introductions}. To look for a person who is not on this instance, use their full handle.' values={{ illustration: <Permalink to='/timelines/tag/illustration' href='/tags/illustration'>#illustration</Permalink>, introductions: <Permalink to='/timelines/tag/introductions' href='/tags/introductions'>#introductions</Permalink> }} /></p>
-    <p><FormattedMessage id='onboarding.page_three.profile' defaultMessage='Edit your profile to change your avatar, bio, and display name. There, you will also find other preferences.' /></p>
-  </div>
-);
-
-PageThree.propTypes = {
-  myAccount: ImmutablePropTypes.map.isRequired,
-};
-
-const PageFour = ({ domain, intl }) => (
-  <div className='onboarding-modal__page onboarding-modal__page-four'>
-    <div className='onboarding-modal__page-four__columns'>
-      <div className='row'>
-        <div>
-          <div className='figure non-interactive'><ColumnHeader icon='home' type={intl.formatMessage(messages.home_title)} /></div>
-          <p><FormattedMessage id='onboarding.page_four.home' defaultMessage='The home timeline shows posts from people you follow.' /></p>
-        </div>
-
-        <div>
-          <div className='figure non-interactive'><ColumnHeader icon='bell' type={intl.formatMessage(messages.notifications_title)} /></div>
-          <p><FormattedMessage id='onboarding.page_four.notifications' defaultMessage='The notifications column shows when someone interacts with you.' /></p>
-        </div>
-      </div>
-
-      <div className='row'>
-        <div>
-          <div className='figure non-interactive' style={{ marginBottom: 0 }}><ColumnHeader icon='users' type={intl.formatMessage(messages.local_title)} /></div>
-        </div>
-
-        <div>
-          <div className='figure non-interactive' style={{ marginBottom: 0 }}><ColumnHeader icon='globe' type={intl.formatMessage(messages.federated_title)} /></div>
-        </div>
-      </div>
-
-      <p><FormattedMessage id='onboarding.page_five.public_timelines' defaultMessage='The local timeline shows public posts from everyone on {domain}. The federated timeline shows public posts from everyone who people on {domain} follow. These are the Public Timelines, a great way to discover new people.' values={{ domain }} /></p>
-    </div>
-  </div>
-);
-
-PageFour.propTypes = {
-  domain: PropTypes.string.isRequired,
-  intl: PropTypes.object.isRequired,
-};
-
-const PageSix = ({ admin, domain }) => {
-  let adminSection = '';
-
-  if (admin) {
-    adminSection = (
-      <p>
-        <FormattedMessage id='onboarding.page_six.admin' defaultMessage="Your instance's admin is {admin}." values={{ admin: <Permalink href={admin.get('url')} to={`/accounts/${admin.get('id')}`}>@{admin.get('acct')}</Permalink> }} />
-        <br />
-        <FormattedMessage id='onboarding.page_six.read_guidelines' defaultMessage="Please read {domain}'s {guidelines}!" values={{ domain, guidelines: <a href='/about/more' target='_blank'><FormattedMessage id='onboarding.page_six.guidelines' defaultMessage='community guidelines' /></a> }} />
-      </p>
-    );
-  }
-
-  return (
-    <div className='onboarding-modal__page onboarding-modal__page-six'>
-      <h1><FormattedMessage id='onboarding.page_six.almost_done' defaultMessage='Almost done...' /></h1>
-      {adminSection}
-      <p><FormattedMessage id='onboarding.page_six.github' defaultMessage='Mastodon is free open-source software. You can report bugs, request features, or contribute to the code on {github}.' values={{ github: <a href='https://github.com/tootsuite/mastodon' target='_blank' rel='noopener'>GitHub</a> }} /></p>
-      <p><FormattedMessage id='onboarding.page_six.apps_available' defaultMessage='There are {apps} available for iOS, Android and other platforms.' values={{ apps: <a href='https://joinmastodon.org/apps' target='_blank' rel='noopener'><FormattedMessage id='onboarding.page_six.various_app' defaultMessage='mobile apps' /></a> }} /></p>
-      <p><em><FormattedMessage id='onboarding.page_six.appetoot' defaultMessage='Bon Appetoot!' /></em></p>
-    </div>
-  );
-};
-
-PageSix.propTypes = {
-  admin: ImmutablePropTypes.map,
-  domain: PropTypes.string.isRequired,
-};
-
-const mapStateToProps = state => ({
-  myAccount: state.getIn(['accounts', me]),
-  admin: state.getIn(['accounts', state.getIn(['meta', 'admin'])]),
-  domain: state.getIn(['meta', 'domain']),
-});
-
-export default @connect(mapStateToProps)
-@injectIntl
-class OnboardingModal extends React.PureComponent {
-
-  static propTypes = {
-    onClose: PropTypes.func.isRequired,
-    intl: PropTypes.object.isRequired,
-    myAccount: ImmutablePropTypes.map.isRequired,
-    domain: PropTypes.string.isRequired,
-    admin: ImmutablePropTypes.map,
-  };
-
-  state = {
-    currentIndex: 0,
-  };
-
-  componentWillMount() {
-    const { myAccount, admin, domain, intl } = this.props;
-    this.pages = [
-      <PageOne acct={myAccount.get('acct')} domain={domain} />,
-      <PageTwo myAccount={myAccount} />,
-      <PageThree myAccount={myAccount} />,
-      <PageFour domain={domain} intl={intl} />,
-      <PageSix admin={admin} domain={domain} />,
-    ];
-  };
-
-  componentDidMount() {
-    window.addEventListener('keyup', this.handleKeyUp);
-  }
-
-  componentWillUnmount() {
-    window.addEventListener('keyup', this.handleKeyUp);
-  }
-
-  handleSkip = (e) => {
-    e.preventDefault();
-    this.props.onClose();
-  }
-
-  handleDot = (e) => {
-    const i = Number(e.currentTarget.getAttribute('data-index'));
-    e.preventDefault();
-    this.setState({ currentIndex: i });
-  }
-
-  handlePrev = () => {
-    this.setState(({ currentIndex }) => ({
-      currentIndex: Math.max(0, currentIndex - 1),
-    }));
-  }
-
-  handleNext = () => {
-    const { pages } = this;
-    this.setState(({ currentIndex }) => ({
-      currentIndex: Math.min(currentIndex + 1, pages.length - 1),
-    }));
-  }
-
-  handleSwipe = (index) => {
-    this.setState({ currentIndex: index });
-  }
-
-  handleKeyUp = ({ key }) => {
-    switch (key) {
-    case 'ArrowLeft':
-      this.handlePrev();
-      break;
-    case 'ArrowRight':
-      this.handleNext();
-      break;
-    }
-  }
-
-  handleClose = () => {
-    this.props.onClose();
-  }
-
-  render () {
-    const { pages } = this;
-    const { currentIndex } = this.state;
-    const hasMore = currentIndex < pages.length - 1;
-
-    const nextOrDoneBtn = hasMore ? (
-      <button onClick={this.handleNext} className='onboarding-modal__nav onboarding-modal__next shake-bottom'>
-        <FormattedMessage id='onboarding.next' defaultMessage='Next' /> <i className='fa fa-fw fa-chevron-right' />
-      </button>
-    ) : (
-      <button onClick={this.handleClose} className='onboarding-modal__nav onboarding-modal__done shake-bottom'>
-        <FormattedMessage id='onboarding.done' defaultMessage='Done' /> <i className='fa fa-fw fa-check' />
-      </button>
-    );
-
-    return (
-      <div className='modal-root__modal onboarding-modal'>
-        <ReactSwipeableViews index={currentIndex} onChangeIndex={this.handleSwipe} className='onboarding-modal__pager'>
-          {pages.map((page, i) => {
-            const className = classNames('onboarding-modal__page__wrapper', `onboarding-modal__page__wrapper-${i}`, {
-              'onboarding-modal__page__wrapper--active': i === currentIndex,
-            });
-
-            return (
-              <div key={i} className={className}>{page}</div>
-            );
-          })}
-        </ReactSwipeableViews>
-
-        <div className='onboarding-modal__paginator'>
-          <div>
-            <button
-              onClick={this.handleSkip}
-              className='onboarding-modal__nav onboarding-modal__skip'
-            >
-              <FormattedMessage id='onboarding.skip' defaultMessage='Skip' />
-            </button>
-          </div>
-
-          <div className='onboarding-modal__dots'>
-            {pages.map((_, i) => {
-              const className = classNames('onboarding-modal__dot', {
-                active: i === currentIndex,
-              });
-
-              return (
-                <div
-                  key={`dot-${i}`}
-                  role='button'
-                  tabIndex='0'
-                  data-index={i}
-                  onClick={this.handleDot}
-                  className={className}
-                />
-              );
-            })}
-          </div>
-
-          <div>
-            {nextOrDoneBtn}
-          </div>
-        </div>
-      </div>
-    );
-  }
-
-}
diff --git a/app/javascript/mastodon/features/ui/index.js b/app/javascript/mastodon/features/ui/index.js
index 662375a76..e11235a81 100644
--- a/app/javascript/mastodon/features/ui/index.js
+++ b/app/javascript/mastodon/features/ui/index.js
@@ -294,6 +294,7 @@ class UI extends React.PureComponent {
 
   componentWillMount () {
     window.addEventListener('beforeunload', this.handleBeforeUnload, false);
+
     document.addEventListener('dragenter', this.handleDragEnter, false);
     document.addEventListener('dragover', this.handleDragOver, false);
     document.addEventListener('drop', this.handleDrop, false);
@@ -304,8 +305,13 @@ class UI extends React.PureComponent {
       navigator.serviceWorker.addEventListener('message', this.handleServiceWorkerPostMessage);
     }
 
+    if (typeof window.Notification !== 'undefined' && Notification.permission === 'default') {
+      window.setTimeout(() => Notification.requestPermission(), 120 * 1000);
+    }
+
     this.props.dispatch(expandHomeTimeline());
     this.props.dispatch(expandNotifications());
+
     setTimeout(() => this.props.dispatch(fetchFilters()), 500);
   }
 
diff --git a/app/javascript/mastodon/features/ui/util/async-components.js b/app/javascript/mastodon/features/ui/util/async-components.js
index 2a15c052f..235fd2a07 100644
--- a/app/javascript/mastodon/features/ui/util/async-components.js
+++ b/app/javascript/mastodon/features/ui/util/async-components.js
@@ -102,10 +102,6 @@ export function Mutes () {
   return import(/* webpackChunkName: "features/mutes" */'../../mutes');
 }
 
-export function OnboardingModal () {
-  return import(/* webpackChunkName: "modals/onboarding_modal" */'../components/onboarding_modal');
-}
-
 export function MuteModal () {
   return import(/* webpackChunkName: "modals/mute_modal" */'../components/mute_modal');
 }
diff --git a/app/javascript/mastodon/locales/en.json b/app/javascript/mastodon/locales/en.json
index ca5abcb05..d20ac1f88 100644
--- a/app/javascript/mastodon/locales/en.json
+++ b/app/javascript/mastodon/locales/en.json
@@ -228,6 +228,14 @@
   "notification.reblog": "{name} boosted your status",
   "notifications.clear": "Clear notifications",
   "notifications.clear_confirmation": "Are you sure you want to permanently clear all your notifications?",
+  "notifications.filter.all": "All",
+  "notifications.filter.mentions": "Mentions",
+  "notifications.filter.favourites": "Favourites",
+  "notifications.filter.boosts": "Boosts",
+  "notifications.filter.follows": "Follows",
+  "notifications.column_settings.filter_bar.category": "Quick filter bar",
+  "notifications.column_settings.filter_bar.show": "Show",
+  "notifications.column_settings.filter_bar.advanced": "Display all categories",
   "notifications.column_settings.alert": "Desktop notifications",
   "notifications.column_settings.favourite": "Favourites:",
   "notifications.column_settings.follow": "New followers:",
diff --git a/app/javascript/mastodon/locales/pl.json b/app/javascript/mastodon/locales/pl.json
index 237ffd33a..356697024 100644
--- a/app/javascript/mastodon/locales/pl.json
+++ b/app/javascript/mastodon/locales/pl.json
@@ -228,6 +228,14 @@
   "notification.reblog": "{name} podbił(a) Twój wpis",
   "notifications.clear": "Wyczyść powiadomienia",
   "notifications.clear_confirmation": "Czy na pewno chcesz bezpowrotnie usunąć wszystkie powiadomienia?",
+  "notifications.filter.all": "Wszystkie",
+  "notifications.filter.mentions": "Wspomnienia",
+  "notifications.filter.favourites": "Ulubione",
+  "notifications.filter.boosts": "Podbicia",
+  "notifications.filter.follows": "Śledzenia",
+  "notifications.column_settings.filter_bar.category": "Szybkie filtrowanie",
+  "notifications.column_settings.filter_bar.show": "Pokaż",
+  "notifications.column_settings.filter_bar.advanced": "Wyświetl wszystkie kategorie",
   "notifications.column_settings.alert": "Powiadomienia na pulpicie",
   "notifications.column_settings.favourite": "Dodanie do ulubionych:",
   "notifications.column_settings.follow": "Nowi śledzący:",
diff --git a/app/javascript/mastodon/reducers/compose.js b/app/javascript/mastodon/reducers/compose.js
index 67d55f66f..1622871b8 100644
--- a/app/javascript/mastodon/reducers/compose.js
+++ b/app/javascript/mastodon/reducers/compose.js
@@ -51,6 +51,7 @@ const initialState = ImmutableMap({
   in_reply_to: null,
   is_composing: false,
   is_submitting: false,
+  is_changing_upload: false,
   is_uploading: false,
   progress: 0,
   media_attachments: ImmutableList(),
@@ -79,6 +80,7 @@ function clearAll(state) {
     map.set('spoiler', false);
     map.set('spoiler_text', '');
     map.set('is_submitting', false);
+    map.set('is_changing_upload', false);
     map.set('in_reply_to', null);
     map.set('privacy', state.get('default_privacy'));
     map.set('sensitive', false);
@@ -248,13 +250,15 @@ export default function compose(state = initialState, action) {
       map.set('idempotencyKey', uuid());
     });
   case COMPOSE_SUBMIT_REQUEST:
-  case COMPOSE_UPLOAD_CHANGE_REQUEST:
     return state.set('is_submitting', true);
+  case COMPOSE_UPLOAD_CHANGE_REQUEST:
+    return state.set('is_changing_upload', true);
   case COMPOSE_SUBMIT_SUCCESS:
     return clearAll(state);
   case COMPOSE_SUBMIT_FAIL:
-  case COMPOSE_UPLOAD_CHANGE_FAIL:
     return state.set('is_submitting', false);
+  case COMPOSE_UPLOAD_CHANGE_FAIL:
+    return state.set('is_changing_upload', false);
   case COMPOSE_UPLOAD_REQUEST:
     return state.set('is_uploading', true);
   case COMPOSE_UPLOAD_SUCCESS:
@@ -300,7 +304,7 @@ export default function compose(state = initialState, action) {
     return insertEmoji(state, action.position, action.emoji, action.needsSpace);
   case COMPOSE_UPLOAD_CHANGE_SUCCESS:
     return state
-      .set('is_submitting', false)
+      .set('is_changing_upload', false)
       .update('media_attachments', list => list.map(item => {
         if (item.get('id') === action.media.id) {
           return fromJS(action.media);
diff --git a/app/javascript/mastodon/reducers/notifications.js b/app/javascript/mastodon/reducers/notifications.js
index d71ae00ae..19a02f5b1 100644
--- a/app/javascript/mastodon/reducers/notifications.js
+++ b/app/javascript/mastodon/reducers/notifications.js
@@ -3,6 +3,7 @@ import {
   NOTIFICATIONS_EXPAND_SUCCESS,
   NOTIFICATIONS_EXPAND_REQUEST,
   NOTIFICATIONS_EXPAND_FAIL,
+  NOTIFICATIONS_FILTER_SET,
   NOTIFICATIONS_CLEAR,
   NOTIFICATIONS_SCROLL_TOP,
 } from '../actions/notifications';
@@ -98,6 +99,8 @@ export default function notifications(state = initialState, action) {
     return state.set('isLoading', true);
   case NOTIFICATIONS_EXPAND_FAIL:
     return state.set('isLoading', false);
+  case NOTIFICATIONS_FILTER_SET:
+    return state.set('items', ImmutableList()).set('hasMore', true);
   case NOTIFICATIONS_SCROLL_TOP:
     return updateTop(state, action.top);
   case NOTIFICATIONS_UPDATE:
diff --git a/app/javascript/mastodon/reducers/settings.js b/app/javascript/mastodon/reducers/settings.js
index 12bcc2583..2e1878cf7 100644
--- a/app/javascript/mastodon/reducers/settings.js
+++ b/app/javascript/mastodon/reducers/settings.js
@@ -1,4 +1,5 @@
 import { SETTING_CHANGE, SETTING_SAVE } from '../actions/settings';
+import { NOTIFICATIONS_FILTER_SET } from '../actions/notifications';
 import { COLUMN_ADD, COLUMN_REMOVE, COLUMN_MOVE, COLUMN_PARAMS_CHANGE } from '../actions/columns';
 import { STORE_HYDRATE } from '../actions/store';
 import { EMOJI_USE } from '../actions/emojis';
@@ -32,6 +33,12 @@ const initialState = ImmutableMap({
       mention: true,
     }),
 
+    quickFilter: ImmutableMap({
+      active: 'all',
+      show: true,
+      advanced: false,
+    }),
+
     shows: ImmutableMap({
       follow: true,
       favourite: true,
@@ -112,6 +119,7 @@ export default function settings(state = initialState, action) {
   switch(action.type) {
   case STORE_HYDRATE:
     return hydrate(state, action.state.get('settings'));
+  case NOTIFICATIONS_FILTER_SET:
   case SETTING_CHANGE:
     return state
       .setIn(action.path, action.value)
diff --git a/app/javascript/styles/application.scss b/app/javascript/styles/application.scss
index 0990a4f25..4bce74187 100644
--- a/app/javascript/styles/application.scss
+++ b/app/javascript/styles/application.scss
@@ -16,6 +16,7 @@
 @import 'mastodon/stream_entries';
 @import 'mastodon/boost';
 @import 'mastodon/components';
+@import 'mastodon/introduction';
 @import 'mastodon/modal';
 @import 'mastodon/emoji_picker';
 @import 'mastodon/about';
diff --git a/app/javascript/styles/mastodon/components.scss b/app/javascript/styles/mastodon/components.scss
index 308429573..61e330a26 100644
--- a/app/javascript/styles/mastodon/components.scss
+++ b/app/javascript/styles/mastodon/components.scss
@@ -2107,6 +2107,7 @@ a.account__display-name {
   &__append {
     flex: 1 1 auto;
     position: relative;
+    min-height: 120px;
   }
 }
 
@@ -2900,7 +2901,6 @@ a.status-card.compact:hover {
     transform: translateX(-50%);
     margin: 82px 0 0 50%;
     white-space: nowrap;
-    animation: loader-label 1.15s infinite cubic-bezier(0.215, 0.610, 0.355, 1.000);
   }
 }
 
@@ -2909,11 +2909,20 @@ a.status-card.compact:hover {
   top: 50%;
   left: 50%;
   transform: translate(-50%, -50%);
-  width: 0;
-  height: 0;
+  width: 42px;
+  height: 42px;
   box-sizing: border-box;
+  background-color: transparent;
   border: 0 solid lighten($ui-base-color, 26%);
+  border-width: 6px;
   border-radius: 50%;
+}
+
+.no-reduce-motion .loading-indicator span {
+  animation: loader-label 1.15s infinite cubic-bezier(0.215, 0.610, 0.355, 1.000);
+}
+
+.no-reduce-motion .loading-indicator__figure {
   animation: loader-figure 1.15s infinite cubic-bezier(0.215, 0.610, 0.355, 1.000);
 }
 
@@ -3789,25 +3798,6 @@ a.status-card.compact:hover {
   flex-direction: column;
 }
 
-.onboarding-modal__pager {
-  height: 80vh;
-  width: 80vw;
-  max-width: 520px;
-  max-height: 470px;
-
-  .react-swipeable-view-container > div {
-    width: 100%;
-    height: 100%;
-    box-sizing: border-box;
-    display: none;
-    flex-direction: column;
-    align-items: center;
-    justify-content: center;
-    display: flex;
-    user-select: text;
-  }
-}
-
 .error-modal__body {
   height: 80vh;
   width: 80vw;
@@ -3841,22 +3831,6 @@ a.status-card.compact:hover {
   text-align: center;
 }
 
-@media screen and (max-width: 550px) {
-  .onboarding-modal {
-    width: 100%;
-    height: 100%;
-    border-radius: 0;
-  }
-
-  .onboarding-modal__pager {
-    width: 100%;
-    height: auto;
-    max-width: none;
-    max-height: none;
-    flex: 1 1 auto;
-  }
-}
-
 .onboarding-modal__paginator,
 .error-modal__footer {
   flex: 0 0 auto;
@@ -3905,124 +3879,6 @@ a.status-card.compact:hover {
   justify-content: center;
 }
 
-.onboarding-modal__dots {
-  flex: 1 1 auto;
-  display: flex;
-  align-items: center;
-  justify-content: center;
-}
-
-.onboarding-modal__dot {
-  width: 14px;
-  height: 14px;
-  border-radius: 14px;
-  background: darken($ui-secondary-color, 16%);
-  margin: 0 3px;
-  cursor: pointer;
-
-  &:hover {
-    background: darken($ui-secondary-color, 18%);
-  }
-
-  &.active {
-    cursor: default;
-    background: darken($ui-secondary-color, 24%);
-  }
-}
-
-.onboarding-modal__page__wrapper {
-  pointer-events: none;
-  padding: 25px;
-  padding-bottom: 0;
-
-  &.onboarding-modal__page__wrapper--active {
-    pointer-events: auto;
-  }
-}
-
-.onboarding-modal__page {
-  cursor: default;
-  line-height: 21px;
-
-  h1 {
-    font-size: 18px;
-    font-weight: 500;
-    color: $inverted-text-color;
-    margin-bottom: 20px;
-  }
-
-  a {
-    color: $highlight-text-color;
-
-    &:hover,
-    &:focus,
-    &:active {
-      color: lighten($highlight-text-color, 4%);
-    }
-  }
-
-  .navigation-bar a {
-    color: inherit;
-  }
-
-  p {
-    font-size: 16px;
-    color: $lighter-text-color;
-    margin-top: 10px;
-    margin-bottom: 10px;
-
-    &:last-child {
-      margin-bottom: 0;
-    }
-
-    strong {
-      font-weight: 500;
-      background: $ui-base-color;
-      color: $secondary-text-color;
-      border-radius: 4px;
-      font-size: 14px;
-      padding: 3px 6px;
-
-      @each $lang in $cjk-langs {
-        &:lang(#{$lang}) {
-          font-weight: 700;
-        }
-      }
-    }
-  }
-}
-
-.onboarding-modal__page__wrapper-0 {
-  background: url('~images/elephant_ui_greeting.svg') no-repeat left bottom / auto 250px;
-  height: 100%;
-  padding: 0;
-}
-
-.onboarding-modal__page-one {
-  &__lead {
-    padding: 65px;
-    padding-top: 45px;
-    padding-bottom: 0;
-    margin-bottom: 10px;
-
-    h1 {
-      font-size: 26px;
-      line-height: 36px;
-      margin-bottom: 8px;
-    }
-
-    p {
-      margin-bottom: 0;
-    }
-  }
-
-  &__extra {
-    padding-right: 65px;
-    padding-left: 185px;
-    text-align: center;
-  }
-}
-
 .display-case {
   text-align: center;
   font-size: 15px;
@@ -4045,92 +3901,6 @@ a.status-card.compact:hover {
   }
 }
 
-.onboarding-modal__page-two,
-.onboarding-modal__page-three,
-.onboarding-modal__page-four,
-.onboarding-modal__page-five {
-  p {
-    text-align: left;
-  }
-
-  .figure {
-    background: darken($ui-base-color, 8%);
-    color: $secondary-text-color;
-    margin-bottom: 20px;
-    border-radius: 4px;
-    padding: 10px;
-    text-align: center;
-    font-size: 14px;
-    box-shadow: 1px 2px 6px rgba($base-shadow-color, 0.3);
-
-    .onboarding-modal__image {
-      border-radius: 4px;
-      margin-bottom: 10px;
-    }
-
-    &.non-interactive {
-      pointer-events: none;
-      text-align: left;
-    }
-  }
-}
-
-.onboarding-modal__page-four__columns {
-  .row {
-    display: flex;
-    margin-bottom: 20px;
-
-    & > div {
-      flex: 1 1 0;
-      margin: 0 10px;
-
-      &:first-child {
-        margin-left: 0;
-      }
-
-      &:last-child {
-        margin-right: 0;
-      }
-
-      p {
-        text-align: center;
-      }
-    }
-
-    &:last-child {
-      margin-bottom: 0;
-    }
-  }
-
-  .column-header {
-    color: $primary-text-color;
-  }
-}
-
-@media screen and (max-width: 320px) and (max-height: 600px) {
-  .onboarding-modal__page p {
-    font-size: 14px;
-    line-height: 20px;
-  }
-
-  .onboarding-modal__page-two .figure,
-  .onboarding-modal__page-three .figure,
-  .onboarding-modal__page-four .figure,
-  .onboarding-modal__page-five .figure {
-    font-size: 12px;
-    margin-bottom: 10px;
-  }
-
-  .onboarding-modal__page-four__columns .row {
-    margin-bottom: 10px;
-  }
-
-  .onboarding-modal__page-four__columns .column-header {
-    padding: 5px;
-    font-size: 12px;
-  }
-}
-
 .onboard-sliders {
   display: inline-block;
   max-width: 30px;
@@ -5030,12 +4800,19 @@ a.status-card.compact:hover {
   }
 }
 
+.notification__filter-bar,
 .account__section-headline {
   background: darken($ui-base-color, 4%);
   border-bottom: 1px solid lighten($ui-base-color, 8%);
   cursor: default;
   display: flex;
 
+  button {
+    background: darken($ui-base-color, 4%);
+    border: 0;
+  }
+
+  button,
   a {
     display: block;
     flex: 1 1 auto;
diff --git a/app/javascript/styles/mastodon/containers.scss b/app/javascript/styles/mastodon/containers.scss
index 44fc1e538..8de53ca98 100644
--- a/app/javascript/styles/mastodon/containers.scss
+++ b/app/javascript/styles/mastodon/containers.scss
@@ -294,6 +294,12 @@
         text-decoration: underline;
         color: $primary-text-color;
       }
+
+      @media screen and (max-width: $no-gap-breakpoint) {
+        &.optional {
+          display: none;
+        }
+      }
     }
 
     .nav-button {
diff --git a/app/javascript/styles/mastodon/introduction.scss b/app/javascript/styles/mastodon/introduction.scss
new file mode 100644
index 000000000..222d8f60e
--- /dev/null
+++ b/app/javascript/styles/mastodon/introduction.scss
@@ -0,0 +1,153 @@
+.introduction {
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+  align-items: center;
+
+  @media screen and (max-width: 920px) {
+    background: darken($ui-base-color, 8%);
+    display: block !important;
+  }
+
+  &__pager {
+    background: darken($ui-base-color, 8%);
+    box-shadow: 0 0 15px rgba($base-shadow-color, 0.2);
+    overflow: hidden;
+  }
+
+  &__pager,
+  &__frame {
+    border-radius: 10px;
+    width: 50vw;
+    min-width: 920px;
+
+    @media screen and (max-width: 920px) {
+      min-width: 0;
+      width: 100%;
+      border-radius: 0;
+      box-shadow: none;
+    }
+  }
+
+  &__frame-wrapper {
+    opacity: 0;
+    transition: opacity 500ms linear;
+
+    &.active {
+      opacity: 1;
+      transition: opacity 50ms linear;
+    }
+  }
+
+  &__frame {
+    overflow: hidden;
+  }
+
+  &__illustration {
+    height: 50vh;
+
+    @media screen and (max-width: 630px) {
+      height: auto;
+    }
+
+    img {
+      object-fit: cover;
+      display: block;
+      margin: 0;
+      width: 100%;
+      height: 100%;
+    }
+  }
+
+  &__text {
+    border-top: 2px solid $ui-highlight-color;
+
+    &--columnized {
+      display: flex;
+
+      & > div {
+        flex: 1 1 33.33%;
+        text-align: center;
+        padding: 25px;
+        padding-bottom: 30px;
+      }
+
+      @media screen and (max-width: 630px) {
+        display: block;
+        padding: 15px 0;
+        padding-bottom: 20px;
+
+        & > div {
+          padding: 10px 25px;
+        }
+      }
+    }
+
+    h3 {
+      font-size: 24px;
+      line-height: 1.5;
+      font-weight: 700;
+      margin-bottom: 10px;
+    }
+
+    p {
+      font-size: 16px;
+      line-height: 24px;
+      font-weight: 400;
+      color: $darker-text-color;
+
+      code {
+        display: inline-block;
+        background: darken($ui-base-color, 8%);
+        font-size: 15px;
+        border: 1px solid lighten($ui-base-color, 8%);
+        border-radius: 2px;
+        padding: 1px 3px;
+      }
+    }
+
+    &--centered {
+      padding: 25px;
+      padding-bottom: 30px;
+      text-align: center;
+    }
+  }
+
+  &__dots {
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    padding: 25px;
+
+    @media screen and (max-width: 630px) {
+      display: none;
+    }
+  }
+
+  &__dot {
+    width: 14px;
+    height: 14px;
+    border-radius: 14px;
+    border: 1px solid $ui-highlight-color;
+    background: transparent;
+    margin: 0 3px;
+    cursor: pointer;
+
+    &:hover {
+      background: lighten($ui-base-color, 8%);
+    }
+
+    &.active {
+      cursor: default;
+      background: $ui-highlight-color;
+    }
+  }
+
+  &__action {
+    padding: 25px;
+    padding-top: 0;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+  }
+}
diff --git a/app/javascript/styles/mastodon/widgets.scss b/app/javascript/styles/mastodon/widgets.scss
index c863e3b4f..87e633c70 100644
--- a/app/javascript/styles/mastodon/widgets.scss
+++ b/app/javascript/styles/mastodon/widgets.scss
@@ -229,18 +229,6 @@
   margin-bottom: 10px;
 }
 
-.moved-account-widget,
-.memoriam-widget,
-.box-widget,
-.contact-widget,
-.landing-page__information.contact-widget {
-  @media screen and (max-width: $no-gap-breakpoint) {
-    margin-bottom: 0;
-    box-shadow: none;
-    border-radius: 0;
-  }
-}
-
 .page-header {
   background: lighten($ui-base-color, 8%);
   box-shadow: 0 0 15px rgba($base-shadow-color, 0.2);
@@ -261,11 +249,20 @@
     font-size: 15px;
     color: $darker-text-color;
   }
+
+  @media screen and (max-width: $no-gap-breakpoint) {
+    margin-top: 0;
+    background: lighten($ui-base-color, 4%);
+
+    h1 {
+      font-size: 24px;
+    }
+  }
 }
 
 .directory {
   background: $ui-base-color;
-  border-radius: 0 0 4px 4px;
+  border-radius: 4px;
   box-shadow: 0 0 15px rgba($base-shadow-color, 0.2);
 
   &__tag {
@@ -407,4 +404,24 @@
       font-size: 14px;
     }
   }
+
+  @media screen and (max-width: $no-gap-breakpoint) {
+    tbody td.optional {
+      display: none;
+    }
+  }
+}
+
+.moved-account-widget,
+.memoriam-widget,
+.box-widget,
+.contact-widget,
+.landing-page__information.contact-widget,
+.directory,
+.page-header {
+  @media screen and (max-width: $no-gap-breakpoint) {
+    margin-bottom: 0;
+    box-shadow: none;
+    border-radius: 0;
+  }
 }