about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEugen Rochko <eugen@zeonfederated.com>2018-07-28 19:25:33 +0200
committerGitHub <noreply@github.com>2018-07-28 19:25:33 +0200
commitbb71538bb503159177d46d8956bd466973c0876b (patch)
tree41e39f53b365d91f83cfe393d75ddf8a1624ded9
parente23b26178a71f90d64fe2a3e9e4468f265ecc71c (diff)
Redesign public profiles and toots (#8068)
-rw-r--r--app/controllers/concerns/account_controller_concern.rb5
-rw-r--r--app/controllers/statuses_controller.rb5
-rw-r--r--app/helpers/stream_entries_helper.rb46
-rw-r--r--app/javascript/mastodon/components/relative_timestamp.js50
-rw-r--r--app/javascript/packs/public.js45
-rw-r--r--app/javascript/styles/application.scss2
-rw-r--r--app/javascript/styles/mastodon/accounts.scss559
-rw-r--r--app/javascript/styles/mastodon/basics.scss5
-rw-r--r--app/javascript/styles/mastodon/components.scss12
-rw-r--r--app/javascript/styles/mastodon/containers.scss573
-rw-r--r--app/javascript/styles/mastodon/footer.scss157
-rw-r--r--app/javascript/styles/mastodon/landing_strip.scss111
-rw-r--r--app/javascript/styles/mastodon/stream_entries.scss390
-rw-r--r--app/javascript/styles/mastodon/variables.scss2
-rw-r--r--app/javascript/styles/mastodon/widgets.scss123
-rw-r--r--app/models/concerns/account_header.rb5
-rw-r--r--app/views/accounts/_bio.html.haml15
-rw-r--r--app/views/accounts/_follow_button.html.haml28
-rw-r--r--app/views/accounts/_follow_grid.html.haml8
-rw-r--r--app/views/accounts/_follow_grid_hidden.html.haml3
-rw-r--r--app/views/accounts/_grid_card.html.haml12
-rw-r--r--app/views/accounts/_header.html.haml82
-rw-r--r--app/views/accounts/_moved.html.haml (renamed from app/views/accounts/_moved_strip.html.haml)11
-rw-r--r--app/views/accounts/_nothing_here.html.haml1
-rw-r--r--app/views/accounts/show.html.haml69
-rw-r--r--app/views/application/_card.html.haml16
-rw-r--r--app/views/application/_sidebar.html.haml6
-rw-r--r--app/views/auth/registrations/new.html.haml2
-rw-r--r--app/views/authorize_follows/_card.html.haml23
-rw-r--r--app/views/authorize_follows/show.html.haml2
-rw-r--r--app/views/authorize_follows/success.html.haml2
-rw-r--r--app/views/follower_accounts/index.html.haml9
-rw-r--r--app/views/following_accounts/index.html.haml9
-rw-r--r--app/views/layouts/public.html.haml55
-rw-r--r--app/views/remote_follow/new.html.haml2
-rw-r--r--app/views/remote_unfollows/success.html.haml2
-rw-r--r--app/views/settings/migrations/show.html.haml2
-rw-r--r--app/views/settings/profiles/show.html.haml3
-rw-r--r--app/views/shared/_landing_strip.html.haml6
-rw-r--r--app/views/stream_entries/_content_spoiler.html.haml7
-rw-r--r--app/views/stream_entries/_detailed_status.html.haml34
-rw-r--r--app/views/stream_entries/_media.html.haml4
-rw-r--r--app/views/stream_entries/_more.html.haml2
-rw-r--r--app/views/stream_entries/_simple_status.html.haml34
-rw-r--r--app/views/stream_entries/_status.html.haml23
-rw-r--r--app/views/stream_entries/embed.html.haml2
-rw-r--r--app/views/stream_entries/show.html.haml11
-rw-r--r--config/locales/ar.yml5
-rw-r--r--config/locales/ast.yml3
-rw-r--r--config/locales/bg.yml5
-rw-r--r--config/locales/ca.yml5
-rw-r--r--config/locales/co.yml5
-rw-r--r--config/locales/da.yml3
-rw-r--r--config/locales/de.yml5
-rw-r--r--config/locales/el.yml5
-rw-r--r--config/locales/en.yml15
-rw-r--r--config/locales/eo.yml5
-rw-r--r--config/locales/es.yml5
-rw-r--r--config/locales/eu.yml5
-rw-r--r--config/locales/fa.yml5
-rw-r--r--config/locales/fi.yml5
-rw-r--r--config/locales/fr.yml5
-rw-r--r--config/locales/gl.yml5
-rw-r--r--config/locales/he.yml5
-rw-r--r--config/locales/hr.yml5
-rw-r--r--config/locales/hu.yml5
-rw-r--r--config/locales/id.yml5
-rw-r--r--config/locales/io.yml5
-rw-r--r--config/locales/it.yml5
-rw-r--r--config/locales/ja.yml5
-rw-r--r--config/locales/ko.yml5
-rw-r--r--config/locales/nl.yml5
-rw-r--r--config/locales/no.yml5
-rw-r--r--config/locales/oc.yml5
-rw-r--r--config/locales/pl.yml5
-rw-r--r--config/locales/pt-BR.yml5
-rw-r--r--config/locales/pt.yml5
-rw-r--r--config/locales/ru.yml5
-rw-r--r--config/locales/sk.yml5
-rw-r--r--config/locales/sl.yml1
-rw-r--r--config/locales/sr-Latn.yml5
-rw-r--r--config/locales/sr.yml5
-rw-r--r--config/locales/sv.yml5
-rw-r--r--config/locales/th.yml5
-rw-r--r--config/locales/tr.yml5
-rw-r--r--config/locales/uk.yml5
-rw-r--r--config/locales/zh-CN.yml5
-rw-r--r--config/locales/zh-HK.yml5
-rw-r--r--config/locales/zh-TW.yml5
-rw-r--r--lib/mastodon/version.rb6
-rw-r--r--package.json1
-rw-r--r--spec/views/stream_entries/show.html.haml_spec.rb1
-rw-r--r--yarn.lock4
93 files changed, 1382 insertions, 1417 deletions
diff --git a/app/controllers/concerns/account_controller_concern.rb b/app/controllers/concerns/account_controller_concern.rb
index 5b9981aa2..6c27ef330 100644
--- a/app/controllers/concerns/account_controller_concern.rb
+++ b/app/controllers/concerns/account_controller_concern.rb
@@ -8,6 +8,7 @@ module AccountControllerConcern
   included do
     layout 'public'
     before_action :set_account
+    before_action :set_instance_presenter
     before_action :set_link_headers
     before_action :check_account_suspension
   end
@@ -18,6 +19,10 @@ module AccountControllerConcern
     @account = Account.find_local!(params[:account_username])
   end
 
+  def set_instance_presenter
+    @instance_presenter = InstancePresenter.new
+  end
+
   def set_link_headers
     response.headers['Link'] = LinkHeader.new(
       [
diff --git a/app/controllers/statuses_controller.rb b/app/controllers/statuses_controller.rb
index b85341822..755af1deb 100644
--- a/app/controllers/statuses_controller.rb
+++ b/app/controllers/statuses_controller.rb
@@ -12,6 +12,7 @@ class StatusesController < ApplicationController
 
   before_action :set_account
   before_action :set_status
+  before_action :set_instance_presenter
   before_action :set_link_headers
   before_action :check_account_suspension
   before_action :redirect_to_original, only: [:show]
@@ -148,6 +149,10 @@ class StatusesController < ApplicationController
     raise ActiveRecord::RecordNotFound
   end
 
+  def set_instance_presenter
+    @instance_presenter = InstancePresenter.new
+  end
+
   def check_account_suspension
     gone if @account.suspended?
   end
diff --git a/app/helpers/stream_entries_helper.rb b/app/helpers/stream_entries_helper.rb
index 05cea73d7..121644263 100644
--- a/app/helpers/stream_entries_helper.rb
+++ b/app/helpers/stream_entries_helper.rb
@@ -12,6 +12,52 @@ module StreamEntriesHelper
     end
   end
 
+  def account_action_button(account)
+    if user_signed_in?
+      if account.id == current_user.account_id
+        link_to settings_profile_url, class: 'button logo-button' do
+          safe_join([render(file: Rails.root.join('app', 'javascript', 'images', 'logo.svg')), t('settings.edit_profile')])
+        end
+      elsif current_account.following?(account) || current_account.requested?(account)
+        link_to account_unfollow_path(account), class: 'button logo-button', data: { method: :post } do
+          safe_join([render(file: Rails.root.join('app', 'javascript', 'images', 'logo.svg')), t('accounts.unfollow')])
+        end
+      else
+        link_to account_follow_path(account), class: 'button logo-button', data: { method: :post } do
+          safe_join([render(file: Rails.root.join('app', 'javascript', 'images', 'logo.svg')), t('accounts.follow')])
+        end
+      end
+    else
+      link_to account_remote_follow_path(account), class: 'button logo-button modal-button', target: '_new' do
+        safe_join([render(file: Rails.root.join('app', 'javascript', 'images', 'logo.svg')), t('accounts.follow')])
+      end
+    end
+  end
+
+  def account_badge(account)
+    if account.bot?
+      content_tag(:div, content_tag(:div, t('accounts.roles.bot'), class: 'account-role bot'), class: 'roles')
+    elsif Setting.show_staff_badge && account.user_staff?
+      content_tag(:div, class: 'roles') do
+        if account.user_admin?
+          content_tag(:div, t('accounts.roles.admin'), class: 'account-role admin')
+        elsif account.user_moderator?
+          content_tag(:div, t('accounts.roles.moderator'), class: 'account-role moderator')
+        end
+      end
+    end
+  end
+
+  def link_to_more(url)
+    link_to t('statuses.show_more'), url, class: 'load-more load-gap'
+  end
+
+  def nothing_here(extra_classes = '')
+    content_tag(:div, class: "nothing-here #{extra_classes}") do
+      t('accounts.nothing_here')
+    end
+  end
+
   def account_description(account)
     prepend_str = [
       [
diff --git a/app/javascript/mastodon/components/relative_timestamp.js b/app/javascript/mastodon/components/relative_timestamp.js
index 3c8db7092..9609714a1 100644
--- a/app/javascript/mastodon/components/relative_timestamp.js
+++ b/app/javascript/mastodon/components/relative_timestamp.js
@@ -60,6 +60,32 @@ const getUnitDelay = units => {
   }
 };
 
+export const timeAgoString = (intl, date, now, year) => {
+  const delta = now - date.getTime();
+
+  let relativeTime;
+
+  if (delta < 10 * SECOND) {
+    relativeTime = intl.formatMessage(messages.just_now);
+  } else if (delta < 7 * DAY) {
+    if (delta < MINUTE) {
+      relativeTime = intl.formatMessage(messages.seconds, { number: Math.floor(delta / SECOND) });
+    } else if (delta < HOUR) {
+      relativeTime = intl.formatMessage(messages.minutes, { number: Math.floor(delta / MINUTE) });
+    } else if (delta < DAY) {
+      relativeTime = intl.formatMessage(messages.hours, { number: Math.floor(delta / HOUR) });
+    } else {
+      relativeTime = intl.formatMessage(messages.days, { number: Math.floor(delta / DAY) });
+    }
+  } else if (date.getFullYear() === year) {
+    relativeTime = intl.formatDate(date, shortDateFormatOptions);
+  } else {
+    relativeTime = intl.formatDate(date, { ...shortDateFormatOptions, year: 'numeric' });
+  }
+
+  return relativeTime;
+};
+
 @injectIntl
 export default class RelativeTimestamp extends React.Component {
 
@@ -121,28 +147,8 @@ export default class RelativeTimestamp extends React.Component {
   render () {
     const { timestamp, intl, year } = this.props;
 
-    const date  = new Date(timestamp);
-    const delta = this.state.now - date.getTime();
-
-    let relativeTime;
-
-    if (delta < 10 * SECOND) {
-      relativeTime = intl.formatMessage(messages.just_now);
-    } else if (delta < 7 * DAY) {
-      if (delta < MINUTE) {
-        relativeTime = intl.formatMessage(messages.seconds, { number: Math.floor(delta / SECOND) });
-      } else if (delta < HOUR) {
-        relativeTime = intl.formatMessage(messages.minutes, { number: Math.floor(delta / MINUTE) });
-      } else if (delta < DAY) {
-        relativeTime = intl.formatMessage(messages.hours, { number: Math.floor(delta / HOUR) });
-      } else {
-        relativeTime = intl.formatMessage(messages.days, { number: Math.floor(delta / DAY) });
-      }
-    } else if (date.getFullYear() === year) {
-      relativeTime = intl.formatDate(date, shortDateFormatOptions);
-    } else {
-      relativeTime = intl.formatDate(date, { ...shortDateFormatOptions, year: 'numeric' });
-    }
+    const date         = new Date(timestamp);
+    const relativeTime = timeAgoString(intl, date, this.state.now, year);
 
     return (
       <time dateTime={timestamp} title={intl.formatDate(date, dateFormatOptions)}>
diff --git a/app/javascript/packs/public.js b/app/javascript/packs/public.js
index 4b1e87ae3..855e56ee6 100644
--- a/app/javascript/packs/public.js
+++ b/app/javascript/packs/public.js
@@ -22,15 +22,15 @@ window.addEventListener('message', e => {
 
 function main() {
   const { length } = require('stringz');
-  const IntlRelativeFormat = require('intl-relativeformat').default;
+  const IntlMessageFormat = require('intl-messageformat').default;
+  const { timeAgoString } = require('../mastodon/components/relative_timestamp');
   const { delegate } = require('rails-ujs');
   const emojify = require('../mastodon/features/emoji/emoji').default;
   const { getLocale } = require('../mastodon/locales');
-  const { localeData } = getLocale();
+  const { messages } = getLocale();
   const React = require('react');
   const ReactDOM = require('react-dom');
-
-  localeData.forEach(IntlRelativeFormat.__addLocaleData);
+  const Rellax = require('rellax');
 
   ready(() => {
     const locale = document.documentElement.lang;
@@ -43,8 +43,6 @@ function main() {
       minute: 'numeric',
     });
 
-    const relativeFormat = new IntlRelativeFormat(locale);
-
     [].forEach.call(document.querySelectorAll('.emojify'), (content) => {
       content.innerHTML = emojify(content.innerHTML);
     });
@@ -59,12 +57,16 @@ function main() {
 
     [].forEach.call(document.querySelectorAll('time.time-ago'), (content) => {
       const datetime = new Date(content.getAttribute('datetime'));
+      const now      = new Date();
 
       content.title = dateTimeFormat.format(datetime);
-      content.textContent = relativeFormat.format(datetime);
+      content.textContent = timeAgoString({
+        formatMessage: ({ id, defaultMessage }, values) => (new IntlMessageFormat(messages[id] || defaultMessage, locale)).format(values),
+        formatDate: (date, options) => (new Intl.DateTimeFormat(locale, options)).format(date),
+      }, datetime, now, datetime.getFullYear());
     });
 
-    [].forEach.call(document.querySelectorAll('.logo-button'), (content) => {
+    [].forEach.call(document.querySelectorAll('.modal-button'), (content) => {
       content.addEventListener('click', (e) => {
         e.preventDefault();
         window.open(e.target.href, 'mastodon-intent', 'width=445,height=600,resizable=no,menubar=no,status=no,scrollbars=yes');
@@ -82,6 +84,8 @@ function main() {
         })
         .catch(error => console.error(error));
     }
+
+    new Rellax('.parallax', { speed: -1 });
   });
 
   delegate(document, '.webapp-btn', 'click', ({ target, button }) => {
@@ -106,15 +110,20 @@ function main() {
     return false;
   });
 
-  delegate(document, '.account_display_name', 'input', ({ target }) => {
+  delegate(document, '#account_display_name', 'input', ({ target }) => {
     const nameCounter = document.querySelector('.name-counter');
+    const name        = document.querySelector('.card .display-name strong');
 
     if (nameCounter) {
       nameCounter.textContent = 30 - length(target.value);
     }
+
+    if (name) {
+      name.innerHTML = emojify(target.value);
+    }
   });
 
-  delegate(document, '.account_note', 'input', ({ target }) => {
+  delegate(document, '#account_note', 'input', ({ target }) => {
     const noteCounter = document.querySelector('.note-counter');
 
     if (noteCounter) {
@@ -123,7 +132,7 @@ function main() {
   });
 
   delegate(document, '#account_avatar', 'change', ({ target }) => {
-    const avatar = document.querySelector('.card.compact .avatar img');
+    const avatar = document.querySelector('.card .avatar img');
     const [file] = target.files || [];
     const url = file ? URL.createObjectURL(file) : avatar.dataset.originalSrc;
 
@@ -131,11 +140,21 @@ function main() {
   });
 
   delegate(document, '#account_header', 'change', ({ target }) => {
-    const header = document.querySelector('.card.compact');
+    const header = document.querySelector('.card .card__img img');
     const [file] = target.files || [];
     const url = file ? URL.createObjectURL(file) : header.dataset.originalSrc;
 
-    header.style.backgroundImage = `url(${url})`;
+    header.src = url;
+  });
+
+  delegate(document, '#account_locked', 'change', ({ target }) => {
+    const lock = document.querySelector('.card .display-name i');
+
+    if (target.checked) {
+      lock.style.display = 'inline';
+    } else {
+      lock.style.display = 'none';
+    }
   });
 }
 
diff --git a/app/javascript/styles/application.scss b/app/javascript/styles/application.scss
index 7b3b10dfe..0990a4f25 100644
--- a/app/javascript/styles/application.scss
+++ b/app/javascript/styles/application.scss
@@ -10,7 +10,7 @@
 @import 'mastodon/lists';
 @import 'mastodon/footer';
 @import 'mastodon/compact_header';
-@import 'mastodon/landing_strip';
+@import 'mastodon/widgets';
 @import 'mastodon/forms';
 @import 'mastodon/accounts';
 @import 'mastodon/stream_entries';
diff --git a/app/javascript/styles/mastodon/accounts.scss b/app/javascript/styles/mastodon/accounts.scss
index b4612b063..c27bc0df3 100644
--- a/app/javascript/styles/mastodon/accounts.scss
+++ b/app/javascript/styles/mastodon/accounts.scss
@@ -1,243 +1,100 @@
 .card {
-  background-color: $base-shadow-color;
-  background-size: cover;
-  background-position: center;
-  border-radius: 4px 4px 0 0;
-  box-shadow: 0 0 15px rgba($base-shadow-color, 0.2);
-  overflow: hidden;
-  position: relative;
-  display: flex;
-
-  &::after {
-    background: rgba(darken($ui-base-color, 8%), 0.5);
+  & > a {
     display: block;
-    content: "";
-    position: absolute;
-    left: 0;
-    top: 0;
-    width: 100%;
-    height: 100%;
-    z-index: 1;
-  }
-
-  @media screen and (max-width: 740px) {
-    border-radius: 0;
-    box-shadow: none;
-  }
-
-  .card__illustration {
-    padding: 60px 0;
-    position: relative;
-    flex: 1 1 auto;
-    display: flex;
-    justify-content: center;
-    align-items: center;
-  }
-
-  .card__bio {
-    max-width: 260px;
-    flex: 1 1 auto;
-    display: flex;
-    flex-direction: column;
-    justify-content: space-between;
-    background: rgba(darken($ui-base-color, 8%), 0.8);
-    position: relative;
-    z-index: 2;
-  }
-
-  &.compact {
-    padding: 30px 0;
-    border-radius: 4px;
-
-    .avatar {
-      margin-bottom: 0;
+    text-decoration: none;
+    color: inherit;
+    box-shadow: 0 0 15px rgba($base-shadow-color, 0.2);
 
-      img {
-        object-fit: cover;
-      }
+    @media screen and (max-width: $no-gap-breakpoint) {
+      box-shadow: none;
     }
-  }
-
-  .name {
-    display: block;
-    font-size: 20px;
-    line-height: 18px * 1.5;
-    color: $primary-text-color;
-    padding: 10px 15px;
-    padding-bottom: 0;
-    font-weight: 500;
-    position: relative;
-    z-index: 2;
-    margin-bottom: 30px;
-    overflow: hidden;
-    text-overflow: ellipsis;
 
-    small {
-      display: block;
-      font-size: 14px;
-      color: $highlight-text-color;
-      font-weight: 400;
-      overflow: hidden;
-      text-overflow: ellipsis;
-
-      .fa {
-        margin-left: 3px;
+    &:hover,
+    &:active,
+    &:focus {
+      .card__bar {
+        background: lighten($ui-base-color, 8%);
       }
     }
   }
 
-  .avatar {
-    width: 120px;
-    margin: 0 auto;
+  &__img {
+    height: 130px;
     position: relative;
-    z-index: 2;
+    background: darken($ui-base-color, 12%);
+    border-radius: 4px 4px 0 0;
 
     img {
-      width: 120px;
-      height: 120px;
-      display: block;
-      border-radius: 120px;
-      box-shadow: 0 0 15px rgba($base-shadow-color, 0.2);
-    }
-  }
-
-  .roles {
-    margin-bottom: 30px;
-    padding: 0 15px;
-  }
-
-  .details-counters {
-    margin-top: 30px;
-    display: flex;
-    flex-direction: row;
-    width: 100%;
-  }
-
-  .counter {
-    width: 33.3%;
-    box-sizing: border-box;
-    flex: 0 0 auto;
-    color: $darker-text-color;
-    padding: 5px 10px 0;
-    margin-bottom: 10px;
-    border-right: 1px solid lighten($ui-base-color, 4%);
-    cursor: default;
-    text-align: center;
-    position: relative;
-
-    a {
-      display: block;
-    }
-
-    &:last-child {
-      border-right: 0;
-    }
-
-    &::after {
       display: block;
-      content: "";
-      position: absolute;
-      bottom: -10px;
-      left: 0;
       width: 100%;
-      border-bottom: 4px solid $ui-primary-color;
-      opacity: 0.5;
-      transition: all 400ms ease;
-    }
-
-    &.active {
-      &::after {
-        border-bottom: 4px solid $highlight-text-color;
-        opacity: 1;
-      }
-    }
-
-    &:hover {
-      &::after {
-        opacity: 1;
-        transition-duration: 100ms;
-      }
+      height: 100%;
+      margin: 0;
+      object-fit: cover;
+      border-radius: 4px 4px 0 0;
     }
 
-    a {
-      text-decoration: none;
-      color: inherit;
+    @media screen and (max-width: 600px) {
+      height: 200px;
     }
 
-    .counter-label {
-      font-size: 12px;
-      display: block;
-      margin-bottom: 5px;
-    }
-
-    .counter-number {
-      font-weight: 500;
-      font-size: 18px;
-      color: $primary-text-color;
-      font-family: 'mastodon-font-display', sans-serif;
+    @media screen and (max-width: $no-gap-breakpoint) {
+      display: none;
     }
   }
 
-  .bio {
-    font-size: 14px;
-    line-height: 18px;
-    padding: 0 15px;
-    color: $secondary-text-color;
-  }
-
-  @media screen and (max-width: 480px) {
-    display: block;
+  &__bar {
+    position: relative;
+    padding: 15px;
+    display: flex;
+    justify-content: flex-start;
+    align-items: center;
+    background: lighten($ui-base-color, 4%);
+    border-radius: 0 0 4px 4px;
 
-    .card__bio {
-      max-width: none;
+    @media screen and (max-width: $no-gap-breakpoint) {
+      border-radius: 0;
     }
 
-    .name,
-    .roles {
-      text-align: center;
-      margin-bottom: 15px;
-    }
+    .avatar {
+      flex: 0 0 auto;
+      width: 48px;
+      height: 48px;
+      padding-top: 2px;
 
-    .bio {
-      margin-bottom: 15px;
+      img {
+        width: 100%;
+        height: 100%;
+        display: block;
+        margin: 0;
+        border-radius: 4px;
+        background: darken($ui-base-color, 8%);
+      }
     }
-  }
-}
 
-.card,
-.account-grid-card {
-  .controls {
-    position: absolute;
-    top: 15px;
-    left: 15px;
-    z-index: 2;
-
-    .icon-button {
-      color: rgba($white, 0.8);
-      text-decoration: none;
-      font-size: 13px;
-      line-height: 13px;
-      font-weight: 500;
-
-      .fa {
-        font-weight: 400;
-        margin-right: 5px;
+    .display-name {
+      margin-left: 15px;
+      text-align: left;
+
+      strong {
+        font-size: 15px;
+        color: $primary-text-color;
+        font-weight: 500;
+        overflow: hidden;
+        text-overflow: ellipsis;
       }
 
-      &:hover,
-      &:active,
-      &:focus {
-        color: $white;
+      span {
+        display: block;
+        font-size: 14px;
+        color: $darker-text-color;
+        font-weight: 400;
+        overflow: hidden;
+        text-overflow: ellipsis;
       }
     }
   }
 }
 
-.account-grid-card .controls {
-  left: auto;
-  right: 15px;
-}
-
 .pagination {
   padding: 30px 0;
   text-align: center;
@@ -314,289 +171,23 @@
   }
 }
 
-.accounts-grid {
-  box-shadow: 0 0 15px rgba($base-shadow-color, 0.2);
-  background: darken($simple-background-color, 8%);
-  border-radius: 0 0 4px 4px;
-  padding: 20px 5px;
-  padding-bottom: 10px;
-  overflow: hidden;
-  display: flex;
-  flex-wrap: wrap;
-  z-index: 2;
-  position: relative;
-
-  &.empty img {
-    position: absolute;
-    opacity: 0.2;
-    height: 200px;
-    left: 0;
-    bottom: 0;
-    pointer-events: none;
-  }
-
-  @media screen and (max-width: 740px) {
-    border-radius: 0;
-    box-shadow: none;
-  }
-
-  .account-grid-card {
-    box-sizing: border-box;
-    width: 335px;
-    background: $simple-background-color;
-    border-radius: 4px;
-    color: $inverted-text-color;
-    margin: 0 5px 10px;
-    position: relative;
-
-    @media screen and (max-width: 740px) {
-      width: calc(100% - 10px);
-    }
-
-    .account-grid-card__header {
-      overflow: hidden;
-      height: 100px;
-      border-radius: 4px 4px 0 0;
-      background-color: lighten($inverted-text-color, 4%);
-      background-size: cover;
-      background-position: center;
-      position: relative;
-
-      &::after {
-        background: rgba(darken($ui-base-color, 8%), 0.5);
-        display: block;
-        content: "";
-        position: absolute;
-        left: 0;
-        top: 0;
-        width: 100%;
-        height: 100%;
-        z-index: 1;
-      }
-    }
-
-    .account-grid-card__avatar {
-      box-sizing: border-box;
-      padding: 15px;
-      position: absolute;
-      z-index: 2;
-      top: 100px - (40px + 2px);
-      left: -2px;
-    }
-
-    .avatar {
-      width: 80px;
-      height: 80px;
-
-      img {
-        display: block;
-        width: 80px;
-        height: 80px;
-        border-radius: 80px;
-        border: 2px solid $simple-background-color;
-        background: $simple-background-color;
-      }
-    }
-
-    .name {
-      padding: 15px;
-      padding-top: 10px;
-      padding-left: 15px + 80px + 15px;
-
-      a {
-        display: block;
-        color: $inverted-text-color;
-        text-decoration: none;
-        text-overflow: ellipsis;
-        overflow: hidden;
-        font-weight: 500;
-
-        &:hover {
-          .display_name {
-            text-decoration: underline;
-          }
-        }
-      }
-    }
-
-    .display_name {
-      font-size: 16px;
-      display: block;
-      text-overflow: ellipsis;
-      overflow: hidden;
-    }
-
-    .username {
-      color: $lighter-text-color;
-      font-size: 14px;
-      font-weight: 400;
-    }
-
-    .account__header__content {
-      padding: 10px 15px;
-      padding-top: 15px;
-      color: $lighter-text-color;
-      word-wrap: break-word;
-      overflow: hidden;
-      text-overflow: ellipsis;
-      height: 5.5em;
-      position: relative;
-
-      &::after {
-        display: block;
-        content: "";
-        width: 100%;
-        height: 100px;
-        position: absolute;
-        bottom: 0;
-        background: linear-gradient(to bottom, rgba($simple-background-color, 0.01) 0%, rgba($simple-background-color, 1) 100%);
-        left: 0;
-        border-radius: 0 0 4px 4px;
-        pointer-events: none;
-      }
-    }
-  }
-}
-
 .nothing-here {
-  width: 100%;
-  display: block;
+  background: $ui-base-color;
+  box-shadow: 0 0 15px rgba($base-shadow-color, 0.2);
   color: $light-text-color;
   font-size: 14px;
   font-weight: 500;
   text-align: center;
-  padding: 130px 0;
-  padding-top: 125px;
-  margin: 0 auto;
+  display: flex;
+  justify-content: center;
+  align-items: center;
   cursor: default;
-}
-
-.account-card {
   border-radius: 4px;
-  text-align: left;
-  box-shadow: 0 0 15px rgba($base-shadow-color, 0.2);
-  background: $simple-background-color;
-
-  &__header {
-    background: $base-shadow-color;
-    background-size: cover;
-    background-position: center center;
-    height: 90px;
-    border-radius: 4px 4px 0 0;
-  }
+  padding: 20px;
+  min-height: 30vh;
 
-  & > .detailed-status__display-name {
-    display: block;
-    overflow: hidden;
-    display: flex;
-    align-items: center;
-    padding: 10px;
-
-    &:last-child {
-      margin-bottom: 0;
-    }
-
-    & > div:first-child {
-      flex: 0 0 auto;
-      margin-right: 10px;
-      width: 48px;
-      height: 48px;
-    }
-
-    .avatar {
-      display: block;
-      border-radius: 4px;
-      margin: 0;
-    }
-
-    .display-name {
-      flex: 1 0 auto;
-      display: block;
-      max-width: 100%;
-      overflow: hidden;
-      white-space: nowrap;
-      text-overflow: ellipsis;
-      cursor: default;
-
-      & > .detailed-status__display-name {
-        margin-bottom: 0;
-      }
-
-      strong {
-        font-weight: 500;
-        color: $ui-base-color;
-
-        @each $lang in $cjk-langs {
-          &:lang(#{$lang}) {
-            font-weight: 700;
-          }
-        }
-      }
-
-      span {
-        font-size: 14px;
-        color: $light-text-color;
-      }
-    }
-
-    &:hover {
-      .display-name {
-        strong {
-          text-decoration: none;
-        }
-      }
-    }
-  }
-
-  .counter {
-    box-sizing: border-box;
-    flex: 0 0 auto;
-    color: $light-text-color;
-    padding: 0 10px;
-    cursor: default;
-    text-align: center;
-    position: relative;
-    line-height: 24px;
-
-    .counter-label {
-      font-size: 12px;
-      display: block;
-      text-transform: uppercase;
-    }
-
-    .counter-number {
-      font-weight: 500;
-      font-size: 16px;
-      color: $inverted-text-color;
-      font-family: 'mastodon-font-display', sans-serif;
-    }
-  }
-}
-
-.activity-stream-tabs {
-  background: $simple-background-color;
-  border-bottom: 1px solid $ui-secondary-color;
-  position: relative;
-  z-index: 2;
-
-  a {
-    display: inline-block;
-    padding: 15px;
-    text-decoration: none;
-    color: $highlight-text-color;
-    text-transform: uppercase;
-    font-weight: 500;
-
-    &:hover,
-    &:active,
-    &:focus {
-      color: lighten($highlight-text-color, 8%);
-    }
-
-    &.active {
-      color: $inverted-text-color;
-      cursor: default;
-    }
+  &--under-tabs {
+    border-radius: 0 0 4px 4px;
   }
 }
 
@@ -629,14 +220,14 @@
   padding: 0;
   margin: 15px -15px -15px;
   border: 0 none;
-  border-top: 1px solid lighten($ui-base-color, 4%);
-  border-bottom: 1px solid lighten($ui-base-color, 4%);
+  border-top: 1px solid lighten($ui-base-color, 12%);
+  border-bottom: 1px solid lighten($ui-base-color, 12%);
   font-size: 14px;
   line-height: 20px;
 
   dl {
     display: flex;
-    border-bottom: 1px solid lighten($ui-base-color, 4%);
+    border-bottom: 1px solid lighten($ui-base-color, 12%);
   }
 
   dt,
diff --git a/app/javascript/styles/mastodon/basics.scss b/app/javascript/styles/mastodon/basics.scss
index c52e069be..c45a50756 100644
--- a/app/javascript/styles/mastodon/basics.scss
+++ b/app/javascript/styles/mastodon/basics.scss
@@ -1,13 +1,12 @@
 body {
   font-family: 'mastodon-font-sans-serif', sans-serif;
-  background: $ui-base-color;
+  background: darken($ui-base-color, 8%);
   background-size: cover;
   background-attachment: fixed;
   font-size: 13px;
   line-height: 18px;
   font-weight: 400;
   color: $primary-text-color;
-  padding-bottom: 20px;
   text-rendering: optimizelegibility;
   font-feature-settings: "kern";
   text-size-adjust: none;
@@ -52,7 +51,7 @@ body {
   }
 
   &.embed {
-    background: transparent;
+    background: lighten($ui-base-color, 4%);
     margin: 0;
     padding-bottom: 0;
 
diff --git a/app/javascript/styles/mastodon/components.scss b/app/javascript/styles/mastodon/components.scss
index 846bda893..814739dfc 100644
--- a/app/javascript/styles/mastodon/components.scss
+++ b/app/javascript/styles/mastodon/components.scss
@@ -946,6 +946,18 @@
   background: lighten($ui-base-color, 4%);
   padding: 14px 10px;
 
+  &--flex {
+    display: flex;
+    flex-wrap: wrap;
+    justify-content: space-between;
+    align-items: flex-start;
+
+    .status__content,
+    .detailed-status__meta {
+      flex: 100%;
+    }
+  }
+
   .status__content {
     font-size: 19px;
     line-height: 24px;
diff --git a/app/javascript/styles/mastodon/containers.scss b/app/javascript/styles/mastodon/containers.scss
index ac648c868..c2ff77783 100644
--- a/app/javascript/styles/mastodon/containers.scss
+++ b/app/javascript/styles/mastodon/containers.scss
@@ -118,3 +118,576 @@
     margin-left: 8px;
   }
 }
+
+.public-layout {
+  @media screen and (max-width: $no-gap-breakpoint) {
+    padding-top: 48px;
+  }
+
+  .container {
+    max-width: 960px;
+
+    @media screen and (max-width: $no-gap-breakpoint) {
+      padding: 0;
+    }
+  }
+
+  .header {
+    background: lighten($ui-base-color, 8%);
+    box-shadow: 0 0 15px rgba($base-shadow-color, 0.2);
+    border-radius: 4px;
+    height: 48px;
+    margin: 10px 0;
+    display: flex;
+    align-items: stretch;
+    justify-content: center;
+    flex-wrap: nowrap;
+    overflow: hidden;
+
+    @media screen and (max-width: $no-gap-breakpoint) {
+      position: fixed;
+      width: 100%;
+      top: 0;
+      left: 0;
+      margin: 0;
+      border-radius: 0;
+      box-shadow: none;
+      z-index: 110;
+    }
+
+    & > div {
+      flex: 1 1 33.3%;
+      min-height: 1px;
+    }
+
+    .nav-left {
+      display: flex;
+      align-items: stretch;
+      justify-content: flex-start;
+      flex-wrap: nowrap;
+    }
+
+    .nav-center {
+      display: flex;
+      align-items: stretch;
+      justify-content: center;
+      flex-wrap: nowrap;
+    }
+
+    .nav-right {
+      display: flex;
+      align-items: stretch;
+      justify-content: flex-end;
+      flex-wrap: nowrap;
+    }
+
+    .brand {
+      display: block;
+      padding: 15px;
+
+      img {
+        display: block;
+        height: 18px;
+        width: auto;
+        position: relative;
+        bottom: -2px;
+
+        @media screen and (max-width: $no-gap-breakpoint) {
+          height: 20px;
+        }
+      }
+
+      &:hover,
+      &:focus,
+      &:active {
+        background: lighten($ui-base-color, 12%);
+      }
+    }
+
+    .nav-link {
+      display: flex;
+      align-items: center;
+      padding: 0 1rem;
+      font-size: 12px;
+      font-weight: 500;
+      text-decoration: none;
+      color: $darker-text-color;
+      white-space: nowrap;
+      text-align: center;
+
+      &:hover,
+      &:focus,
+      &:active {
+        text-decoration: underline;
+        color: $primary-text-color;
+      }
+    }
+
+    .nav-button {
+      background: lighten($ui-base-color, 16%);
+      margin: 8px;
+      margin-left: 0;
+      border-radius: 4px;
+
+      &:hover,
+      &:focus,
+      &:active {
+        text-decoration: none;
+        background: lighten($ui-base-color, 20%);
+      }
+    }
+  }
+
+  $no-columns-breakpoint: 600px;
+
+  .grid {
+    display: grid;
+    grid-gap: 10px;
+    grid-template-columns: minmax(300px, 3fr) minmax(298px, 1fr);
+    grid-auto-columns: 25%;
+    grid-auto-rows: max-content;
+
+    .column-0 {
+      grid-row: 1;
+      grid-column: 1;
+    }
+
+    .column-1 {
+      grid-row: 1;
+      grid-column: 2;
+    }
+
+    @media screen and (max-width: $no-columns-breakpoint) {
+      grid-template-columns: 100%;
+      grid-gap: 0;
+
+      .column-1 {
+        display: none;
+      }
+    }
+  }
+
+  .public-account-header {
+    overflow: hidden;
+    margin-bottom: 10px;
+    box-shadow: 0 0 15px rgba($base-shadow-color, 0.2);
+
+    &__image {
+      border-radius: 4px 4px 0 0;
+      overflow: hidden;
+      height: 300px;
+      position: relative;
+      background: darken($ui-base-color, 12%);
+
+      &::after {
+        content: "";
+        display: block;
+        position: absolute;
+        width: 100%;
+        height: 100%;
+        box-shadow: inset 0 -1px 1px 1px rgba($base-shadow-color, 0.15);
+        top: 0;
+        left: 0;
+      }
+
+      img {
+        object-fit: cover;
+        display: block;
+        width: 100%;
+        height: 100%;
+        margin: 0;
+        border-radius: 4px 4px 0 0;
+      }
+
+      @media screen and (max-width: 600px) {
+        height: 200px;
+      }
+    }
+
+    @media screen and (max-width: $no-gap-breakpoint) {
+      margin-bottom: 0;
+      box-shadow: none;
+
+      &__image::after {
+        display: none;
+      }
+
+      &__image,
+      &__image img {
+        border-radius: 0;
+      }
+    }
+
+    &__bar {
+      position: relative;
+      margin-top: -80px;
+      display: flex;
+      justify-content: flex-start;
+
+      &::before {
+        content: "";
+        display: block;
+        background: lighten($ui-base-color, 4%);
+        position: absolute;
+        bottom: 0;
+        left: 0;
+        right: 0;
+        height: 60px;
+        border-radius: 0 0 4px 4px;
+        z-index: -1;
+      }
+
+      .avatar {
+        display: block;
+        width: 120px;
+        height: 120px;
+        padding-left: 20px - 4px;
+        flex: 0 0 auto;
+
+        img {
+          display: block;
+          width: 100%;
+          height: 100%;
+          margin: 0;
+          border-radius: 50%;
+          border: 4px solid lighten($ui-base-color, 4%);
+          background: darken($ui-base-color, 8%);
+        }
+      }
+
+      @media screen and (max-width: 600px) {
+        margin-top: 0;
+        background: lighten($ui-base-color, 4%);
+        border-radius: 0 0 4px 4px;
+        padding: 5px;
+
+        &::before {
+          display: none;
+        }
+
+        .avatar {
+          width: 48px;
+          height: 48px;
+          padding: 7px 0;
+          padding-left: 10px;
+
+          img {
+            border: 0;
+            border-radius: 4px;
+          }
+
+          @media screen and (max-width: 360px) {
+            display: none;
+          }
+        }
+      }
+
+      @media screen and (max-width: $no-gap-breakpoint) {
+        border-radius: 0;
+      }
+
+      @media screen and (max-width: $no-columns-breakpoint) {
+        flex-wrap: wrap;
+      }
+    }
+
+    &__tabs {
+      flex: 1 1 auto;
+      margin-left: 20px;
+
+      &__name {
+        padding-top: 20px;
+        padding-bottom: 8px;
+
+        h1 {
+          font-size: 20px;
+          line-height: 18px * 1.5;
+          color: $primary-text-color;
+          font-weight: 500;
+          overflow: hidden;
+          white-space: nowrap;
+          text-overflow: ellipsis;
+          text-shadow: 1px 1px 1px $base-shadow-color;
+
+          small {
+            display: block;
+            font-size: 14px;
+            color: $primary-text-color;
+            font-weight: 400;
+            overflow: hidden;
+            text-overflow: ellipsis;
+          }
+        }
+      }
+
+      @media screen and (max-width: 600px) {
+        margin-left: 15px;
+        display: flex;
+        justify-content: space-between;
+        align-items: center;
+
+        &__name {
+          padding-top: 0;
+          padding-bottom: 0;
+
+          h1 {
+            font-size: 16px;
+            line-height: 24px;
+            text-shadow: none;
+
+            small {
+              color: $darker-text-color;
+            }
+          }
+        }
+      }
+
+      &__tabs {
+        display: flex;
+        justify-content: flex-start;
+        align-items: stretch;
+        height: 58px;
+
+        .details-counters {
+          display: flex;
+          flex-direction: row;
+          min-width: 300px;
+        }
+
+        @media screen and (max-width: $no-columns-breakpoint) {
+          .details-counters {
+            display: none;
+          }
+        }
+
+        .counter {
+          width: 33.3%;
+          box-sizing: border-box;
+          flex: 0 0 auto;
+          color: $darker-text-color;
+          padding: 10px;
+          border-right: 1px solid lighten($ui-base-color, 4%);
+          cursor: default;
+          text-align: center;
+          position: relative;
+
+          a {
+            display: block;
+          }
+
+          &:last-child {
+            border-right: 0;
+          }
+
+          &::after {
+            display: block;
+            content: "";
+            position: absolute;
+            bottom: 0;
+            left: 0;
+            width: 100%;
+            border-bottom: 4px solid $ui-primary-color;
+            opacity: 0.5;
+            transition: all 400ms ease;
+          }
+
+          &.active {
+            &::after {
+              border-bottom: 4px solid $highlight-text-color;
+              opacity: 1;
+            }
+          }
+
+          &:hover {
+            &::after {
+              opacity: 1;
+              transition-duration: 100ms;
+            }
+          }
+
+          a {
+            text-decoration: none;
+            color: inherit;
+          }
+
+          .counter-label {
+            font-size: 12px;
+            display: block;
+          }
+
+          .counter-number {
+            font-weight: 500;
+            font-size: 18px;
+            margin-bottom: 5px;
+            color: $primary-text-color;
+            font-family: 'mastodon-font-display', sans-serif;
+          }
+        }
+
+        .spacer {
+          flex: 1 1 auto;
+          height: 1px;
+        }
+
+        &__buttons {
+          padding: 7px 8px;
+        }
+      }
+    }
+
+    &__extra {
+      display: none;
+      margin-top: 4px;
+
+      .public-account-bio {
+        border-radius: 0;
+        box-shadow: none;
+        background: transparent;
+        margin: 0 -5px;
+
+        .account__header__fields {
+          border-top: 1px solid lighten($ui-base-color, 12%);
+        }
+
+        .roles {
+          display: none;
+        }
+      }
+
+      &__links {
+        margin-top: -15px;
+        font-size: 14px;
+        color: $darker-text-color;
+
+        a {
+          display: inline-block;
+          color: $darker-text-color;
+          text-decoration: none;
+          padding: 15px;
+
+          strong {
+            font-weight: 700;
+            color: $primary-text-color;
+          }
+        }
+      }
+
+      @media screen and (max-width: $no-columns-breakpoint) {
+        display: block;
+        flex: 100%;
+      }
+    }
+  }
+
+  .account__section-headline {
+    border-radius: 4px 4px 0 0;
+
+    @media screen and (max-width: $no-gap-breakpoint) {
+      border-radius: 0;
+    }
+  }
+
+  .detailed-status__meta {
+    margin-top: 25px;
+  }
+
+  .public-account-bio {
+    background: lighten($ui-base-color, 8%);
+    box-shadow: 0 0 15px rgba($base-shadow-color, 0.2);
+    border-radius: 4px;
+    overflow: hidden;
+    margin-bottom: 10px;
+
+    @media screen and (max-width: $no-gap-breakpoint) {
+      box-shadow: none;
+      margin-bottom: 0;
+      border-radius: 0;
+    }
+
+    .account__header__fields {
+      margin: 0;
+      border-top: 0;
+
+      a {
+        color: lighten($ui-highlight-color, 8%);
+      }
+    }
+
+    .account__header__content {
+      padding: 20px;
+      padding-bottom: 0;
+      color: $primary-text-color;
+    }
+
+    &__extra,
+    .roles {
+      padding: 20px;
+      font-size: 14px;
+      color: $darker-text-color;
+    }
+
+    .roles {
+      padding-bottom: 0;
+    }
+  }
+
+  .static-icon-button {
+    color: $action-button-color;
+    font-size: 18px;
+
+    & > span {
+      font-size: 14px;
+      font-weight: 500;
+    }
+  }
+
+  .card-grid {
+    display: flex;
+    flex-wrap: wrap;
+    min-width: 100%;
+    margin: 0 -5px;
+
+    & > div {
+      box-sizing: border-box;
+      flex: 1 0 auto;
+      width: 300px;
+      padding: 0 5px;
+      margin-bottom: 10px;
+      max-width: 33.333%;
+
+      @media screen and (max-width: 900px) {
+        max-width: 50%;
+      }
+
+      @media screen and (max-width: 600px) {
+        max-width: 100%;
+      }
+    }
+
+    @media screen and (max-width: $no-gap-breakpoint) {
+      margin: 0;
+      border-top: 1px solid lighten($ui-base-color, 8%);
+
+      & > div {
+        width: 100%;
+        padding: 0;
+        margin-bottom: 0;
+        border-bottom: 1px solid lighten($ui-base-color, 8%);
+
+        &:last-child {
+          border-bottom: 0;
+        }
+
+        .card__bar {
+          background: $ui-base-color;
+
+          &:hover,
+          &:active,
+          &:focus {
+            background: lighten($ui-base-color, 4%);
+          }
+        }
+      }
+    }
+  }
+}
diff --git a/app/javascript/styles/mastodon/footer.scss b/app/javascript/styles/mastodon/footer.scss
index 81eb1ce2d..4d75477e0 100644
--- a/app/javascript/styles/mastodon/footer.scss
+++ b/app/javascript/styles/mastodon/footer.scss
@@ -1,39 +1,140 @@
-.footer {
-  text-align: center;
-  margin-top: 30px;
-  padding-bottom: 60px;
-  font-size: 12px;
-  color: $darker-text-color;
-
-  .footer__domain {
-    font-weight: 500;
-
-    a {
-      color: inherit;
-      text-decoration: none;
+.public-layout {
+  .footer {
+    text-align: left;
+    padding-top: 20px;
+    padding-bottom: 60px;
+    font-size: 12px;
+    color: lighten($ui-base-color, 34%);
+
+    @media screen and (max-width: $no-gap-breakpoint) {
+      padding-left: 20px;
+      padding-right: 20px;
     }
-  }
 
-  .powered-by,
-  .single-user-login {
-    font-weight: 400;
+    .grid {
+      display: grid;
+      grid-gap: 10px;
+      grid-template-columns: 1fr 1fr 2fr 1fr 1fr;
+
+      .column-0 {
+        grid-column: 1;
+        grid-row: 1;
+        min-width: 0;
+      }
+
+      .column-1 {
+        grid-column: 2;
+        grid-row: 1;
+        min-width: 0;
+      }
+
+      .column-2 {
+        grid-column: 3;
+        grid-row: 1;
+        min-width: 0;
+        text-align: center;
+
+        h4 a {
+          color: lighten($ui-base-color, 34%);
+        }
+      }
+
+      .column-3 {
+        grid-column: 4;
+        grid-row: 1;
+        min-width: 0;
+      }
+
+      .column-4 {
+        grid-column: 5;
+        grid-row: 1;
+        min-width: 0;
+      }
+
+      @media screen and (max-width: 690px) {
+        grid-template-columns: 1fr 2fr 1fr;
+
+        .column-0,
+        .column-1 {
+          grid-column: 1;
+        }
+
+        .column-1 {
+          grid-row: 2;
+        }
+
+        .column-2 {
+          grid-column: 2;
+        }
 
-    a {
-      color: inherit;
-      text-decoration: underline;
-      font-weight: 500;
+        .column-3,
+        .column-4 {
+          grid-column: 3;
+        }
 
-      &:hover {
+        .column-4 {
+          grid-row: 2;
+        }
+      }
+
+      @media screen and (max-width: 600px) {
+        .column-1 {
+          display: block;
+        }
+      }
+
+      @media screen and (max-width: $no-gap-breakpoint) {
+        .column-0,
+        .column-1,
+        .column-3,
+        .column-4 {
+          display: none;
+        }
+      }
+    }
+
+    h4 {
+      text-transform: uppercase;
+      font-weight: 700;
+      margin-bottom: 8px;
+      color: $darker-text-color;
+
+      a {
+        color: inherit;
         text-decoration: none;
       }
     }
 
-    img {
-      margin: 0 4px;
-      position: relative;
-      bottom: -1px;
-      height: 18px;
-      vertical-align: top;
+    ul a {
+      text-decoration: none;
+      color: lighten($ui-base-color, 34%);
+
+      &:hover,
+      &:active,
+      &:focus {
+        text-decoration: underline;
+      }
+    }
+
+    .brand {
+      svg {
+        display: block;
+        height: 36px;
+        width: auto;
+        margin: 0 auto;
+
+        path {
+          fill: lighten($ui-base-color, 34%);
+        }
+      }
+
+      &:hover,
+      &:focus,
+      &:active {
+        svg path {
+          fill: lighten($ui-base-color, 38%);
+        }
+      }
     }
   }
 }
diff --git a/app/javascript/styles/mastodon/landing_strip.scss b/app/javascript/styles/mastodon/landing_strip.scss
deleted file mode 100644
index 86614b89b..000000000
--- a/app/javascript/styles/mastodon/landing_strip.scss
+++ /dev/null
@@ -1,111 +0,0 @@
-.landing-strip,
-.memoriam-strip {
-  background: rgba(darken($ui-base-color, 7%), 0.8);
-  color: $darker-text-color;
-  font-weight: 400;
-  padding: 14px;
-  border-radius: 4px;
-  margin-bottom: 20px;
-  display: flex;
-  align-items: center;
-
-  strong,
-  a {
-    font-weight: 500;
-
-    @each $lang in $cjk-langs {
-      &:lang(#{$lang}) {
-        font-weight: 700;
-      }
-    }
-  }
-
-  a {
-    color: inherit;
-    text-decoration: underline;
-  }
-
-  .logo {
-    width: 30px;
-    height: 30px;
-    flex: 0 0 auto;
-    margin-right: 15px;
-  }
-
-  @media screen and (max-width: 740px) {
-    margin-bottom: 0;
-  }
-}
-
-.memoriam-strip {
-  background: rgba($base-shadow-color, 0.7);
-}
-
-.moved-strip {
-  padding: 14px;
-  border-radius: 4px;
-  background: rgba(darken($ui-base-color, 7%), 0.8);
-  color: $secondary-text-color;
-  font-weight: 400;
-  margin-bottom: 20px;
-
-  strong,
-  a {
-    font-weight: 500;
-
-    @each $lang in $cjk-langs {
-      &:lang(#{$lang}) {
-        font-weight: 700;
-      }
-    }
-  }
-
-  a {
-    color: inherit;
-    text-decoration: underline;
-
-    &.mention {
-      text-decoration: none;
-
-      span {
-        text-decoration: none;
-      }
-
-      &:focus,
-      &:hover,
-      &:active {
-        text-decoration: none;
-
-        span {
-          text-decoration: underline;
-        }
-      }
-    }
-  }
-
-  &__message {
-    margin-bottom: 15px;
-
-    .fa {
-      margin-right: 5px;
-      color: $darker-text-color;
-    }
-  }
-
-  &__card {
-    .detailed-status__display-avatar {
-      position: relative;
-      cursor: pointer;
-    }
-
-    .detailed-status__display-name {
-      margin-bottom: 0;
-      text-decoration: none;
-
-      span {
-        color: $highlight-text-color;
-        font-weight: 400;
-      }
-    }
-  }
-}
diff --git a/app/javascript/styles/mastodon/stream_entries.scss b/app/javascript/styles/mastodon/stream_entries.scss
index f4d6e237f..9e2aa720c 100644
--- a/app/javascript/styles/mastodon/stream_entries.scss
+++ b/app/javascript/styles/mastodon/stream_entries.scss
@@ -1,367 +1,145 @@
 .activity-stream {
-  clear: both;
   box-shadow: 0 0 15px rgba($base-shadow-color, 0.2);
+  border-radius: 4px;
+  overflow: hidden;
+  margin-bottom: 10px;
+
+  @media screen and (max-width: $no-gap-breakpoint) {
+    margin-bottom: 0;
+    border-radius: 0;
+    box-shadow: none;
+  }
+
+  &--headless {
+    border-radius: 0;
+    margin: 0;
+    box-shadow: none;
+
+    .detailed-status,
+    .status {
+      border-radius: 0 !important;
+    }
+  }
 
   div[data-component] {
     width: 100%;
   }
 
   .entry {
-    background: $simple-background-color;
+    background: $ui-base-color;
 
-    .detailed-status.light,
-    .status.light,
-    .more.light {
-      border-bottom: 1px solid $ui-secondary-color;
+    .detailed-status,
+    .status,
+    .load-more {
       animation: none;
     }
 
     &:last-child {
-      &,
-      .detailed-status.light,
-      .status.light {
+      .detailed-status,
+      .status {
         border-bottom: 0;
         border-radius: 0 0 4px 4px;
       }
     }
 
     &:first-child {
-      &,
-      .detailed-status.light,
-      .status.light {
+      .detailed-status,
+      .status {
         border-radius: 4px 4px 0 0;
       }
 
       &:last-child {
-        &,
-        .detailed-status.light,
-        .status.light {
+        .detailed-status,
+        .status {
           border-radius: 4px;
         }
       }
     }
 
     @media screen and (max-width: 740px) {
-      &,
-      .detailed-status.light,
-      .status.light {
+      .detailed-status,
+      .status {
         border-radius: 0 !important;
       }
     }
   }
+}
 
-  &.with-header {
-    .entry {
-      &:first-child {
-        &,
-        .detailed-status.light,
-        .status.light {
-          border-radius: 0;
-        }
-
-        &:last-child {
-          &,
-          .detailed-status.light,
-          .status.light {
-            border-radius: 0 0 4px 4px;
-          }
-        }
-      }
-    }
-  }
-
-  .media-gallery__gifv__label {
-    bottom: 9px;
-  }
-
-  .status.light {
-    padding: 14px 14px 14px (48px + 14px * 2);
-    position: relative;
-    min-height: 48px;
-    cursor: default;
-
-    .status__header {
-      font-size: 15px;
-
-      .status__meta {
-        float: right;
-        font-size: 14px;
-
-        .status__relative-time {
-          color: $lighter-text-color;
-        }
-      }
-    }
-
-    .status__display-name {
-      display: block;
-      max-width: 100%;
-      padding-right: 25px;
-      color: $inverted-text-color;
-    }
-
-    .status__avatar {
-      position: absolute;
-      left: 14px;
-      top: 14px;
-      width: 48px;
-      height: 48px;
-
-      & > div {
-        width: 48px;
-        height: 48px;
-      }
-
-      img {
-        display: block;
-        border-radius: 4px;
-      }
-    }
-
-    .display-name {
-      display: block;
-      max-width: 100%;
-      overflow: hidden;
-      white-space: nowrap;
-      text-overflow: ellipsis;
-
-      strong {
-        font-weight: 500;
-        color: $inverted-text-color;
-
-        @each $lang in $cjk-langs {
-          &:lang(#{$lang}) {
-            font-weight: 700;
-          }
-        }
-      }
-
-      span {
-        font-size: 14px;
-        color: $light-text-color;
-      }
-    }
-
-    .status__content {
-      color: $inverted-text-color;
-
-      a {
-        color: $highlight-text-color;
-      }
-
-      a.status__content__spoiler-link {
-        color: $primary-text-color;
-        background: $ui-base-color;
-
-        &:hover {
-          background: lighten($ui-base-color, 8%);
-        }
-      }
-    }
-  }
-
-  .detailed-status.light {
-    padding: 14px;
-    background: $simple-background-color;
-    cursor: default;
-
-    .detailed-status__display-name {
-      display: block;
-      overflow: hidden;
-      margin-bottom: 15px;
-
-      & > div {
-        float: left;
-        margin-right: 10px;
-      }
-
-      .display-name {
-        display: block;
-        max-width: 100%;
-        overflow: hidden;
-        white-space: nowrap;
-        text-overflow: ellipsis;
-
-        strong {
-          font-weight: 500;
-          color: $inverted-text-color;
-
-          @each $lang in $cjk-langs {
-            &:lang(#{$lang}) {
-              font-weight: 700;
-            }
-          }
-        }
-
-        span {
-          font-size: 14px;
-          color: $light-text-color;
-        }
-      }
-    }
-
-    .avatar {
-      width: 48px;
-      height: 48px;
-
-      img {
-        display: block;
-        border-radius: 4px;
-      }
-    }
-
-    .status__content {
-      color: $inverted-text-color;
-
-      a {
-        color: $highlight-text-color;
-      }
-
-      a.status__content__spoiler-link {
-        color: $primary-text-color;
-        background: $ui-base-color;
-
-        &:hover {
-          background: lighten($ui-base-color, 8%);
-        }
-      }
-    }
-
-    .detailed-status__meta {
-      margin-top: 15px;
-      color: $light-text-color;
-      font-size: 14px;
-      line-height: 18px;
-
-      a {
-        color: inherit;
-      }
-
-      span > span {
-        font-weight: 500;
-        font-size: 12px;
-        margin-left: 6px;
-        display: inline-block;
-      }
-    }
-
-    .status-card {
-      border-color: lighten($ui-secondary-color, 4%);
-      color: $lighter-text-color;
-
-      &:hover {
-        background: lighten($ui-secondary-color, 4%);
-      }
-    }
-
-    .status-card__title,
-    .status-card__description {
-      color: $inverted-text-color;
-    }
-
-    .status-card__image {
-      background: $ui-secondary-color;
-    }
-  }
-
-  .media-spoiler {
-    background: $ui-base-color;
-    color: $darker-text-color;
-  }
+.button.logo-button {
+  flex: 0 auto;
+  font-size: 14px;
+  background: $ui-highlight-color;
+  color: $primary-text-color;
+  text-transform: none;
+  line-height: 36px;
+  height: auto;
+  padding: 3px 15px;
+  border: 0;
 
-  .pre-header {
-    padding: 14px 0;
-    padding-left: (48px + 14px * 2);
-    padding-bottom: 0;
-    margin-bottom: -4px;
-    color: $light-text-color;
-    font-size: 14px;
-    position: relative;
+  svg {
+    width: 20px;
+    height: auto;
+    vertical-align: middle;
+    margin-right: 5px;
 
-    .pre-header__icon {
-      position: absolute;
-      left: (48px + 14px * 2 - 30px);
+    path:first-child {
+      fill: $primary-text-color;
     }
 
-    .status__display-name.muted strong {
-      color: $light-text-color;
+    path:last-child {
+      fill: $ui-highlight-color;
     }
   }
 
-  .open-in-web-link {
-    text-decoration: none;
+  &:active,
+  &:focus,
+  &:hover {
+    background: lighten($ui-highlight-color, 10%);
 
-    &:hover {
-      text-decoration: underline;
+    svg path:last-child {
+      fill: lighten($ui-highlight-color, 10%);
     }
   }
 
-  .more {
-    color: $darker-text-color;
-    display: block;
-    padding: 14px;
-    text-align: center;
-
-    &:not(:hover) {
-      text-decoration: none;
+  @media screen and (max-width: $no-gap-breakpoint) {
+    svg {
+      display: none;
     }
   }
 }
 
-.embed {
-  .activity-stream {
-    box-shadow: none;
+.embed,
+.public-layout {
+  .detailed-status {
+    padding: 15px;
   }
-}
 
-.entry {
-  .detailed-status.light {
-    display: flex;
-    flex-wrap: wrap;
-    justify-content: space-between;
-    align-items: flex-start;
+  .status {
+    padding: 15px 15px 15px (48px + 15px * 2);
+    min-height: 48px + 2px;
 
-    .detailed-status__display-name {
-      flex: 1;
-      margin: 0 5px 15px 0;
+    &__avatar {
+      left: 15px;
+      top: 17px;
     }
 
-    .button.button-secondary.logo-button {
-      flex: 0 auto;
-      font-size: 14px;
-      background: $ui-highlight-color;
-      color: $primary-text-color;
-      border: 0;
-
-      svg {
-        width: 20px;
-        height: auto;
-        vertical-align: middle;
-        margin-right: 5px;
-
-        path:first-child {
-          fill: $primary-text-color;
-        }
-
-        path:last-child {
-          fill: $ui-highlight-color;
-        }
-      }
+    &__content {
+      padding-top: 5px;
+    }
 
-      &:active,
-      &:focus,
-      &:hover {
-        background: lighten($ui-highlight-color, 10%);
+    &__prepend {
+      margin-left: 48px + 15px * 2;
+      padding-top: 15px;
+    }
 
-        svg path:last-child {
-          fill: lighten($ui-highlight-color, 10%);
-        }
-      }
+    &__prepend-icon-wrapper {
+      left: -32px;
     }
 
-    .status__content,
-    .detailed-status__meta {
-      flex: 100%;
+    .media-gallery,
+    &__action-bar,
+    .video-player {
+      margin-top: 10px;
     }
   }
 }
diff --git a/app/javascript/styles/mastodon/variables.scss b/app/javascript/styles/mastodon/variables.scss
index 40aeb4afc..009f0a3c9 100644
--- a/app/javascript/styles/mastodon/variables.scss
+++ b/app/javascript/styles/mastodon/variables.scss
@@ -46,3 +46,5 @@ $cjk-langs: ja, ko, zh-CN, zh-HK, zh-TW;
 $media-modal-media-max-width: 100%;
 // put margins on top and bottom of image to avoid the screen covered by image.
 $media-modal-media-max-height: 80%;
+
+$no-gap-breakpoint: 415px;
diff --git a/app/javascript/styles/mastodon/widgets.scss b/app/javascript/styles/mastodon/widgets.scss
new file mode 100644
index 000000000..9324533bd
--- /dev/null
+++ b/app/javascript/styles/mastodon/widgets.scss
@@ -0,0 +1,123 @@
+.hero-widget {
+  margin-bottom: 10px;
+  box-shadow: 0 0 15px rgba($base-shadow-color, 0.2);
+
+  &__img {
+    width: 100%;
+    height: 167px;
+    position: relative;
+    overflow: hidden;
+    border-radius: 4px 4px 0 0;
+    background: $base-shadow-color;
+
+    img {
+      object-fit: cover;
+      display: block;
+      width: 100%;
+      height: 100%;
+      margin: 0;
+      border-radius: 4px 4px 0 0;
+    }
+  }
+
+  &__text {
+    background: $ui-base-color;
+    padding: 20px;
+    border-radius: 0 0 4px 4px;
+    font-size: 14px;
+    color: $darker-text-color;
+  }
+
+  @media screen and (max-width: $no-gap-breakpoint) {
+    display: none;
+  }
+}
+
+.moved-account-widget {
+  padding: 15px;
+  padding-bottom: 20px;
+  border-radius: 4px;
+  background: $ui-base-color;
+  box-shadow: 0 0 15px rgba($base-shadow-color, 0.2);
+  color: $secondary-text-color;
+  font-weight: 400;
+  margin-bottom: 10px;
+
+  strong,
+  a {
+    font-weight: 500;
+
+    @each $lang in $cjk-langs {
+      &:lang(#{$lang}) {
+        font-weight: 700;
+      }
+    }
+  }
+
+  a {
+    color: inherit;
+    text-decoration: underline;
+
+    &.mention {
+      text-decoration: none;
+
+      span {
+        text-decoration: none;
+      }
+
+      &:focus,
+      &:hover,
+      &:active {
+        text-decoration: none;
+
+        span {
+          text-decoration: underline;
+        }
+      }
+    }
+  }
+
+  &__message {
+    margin-bottom: 15px;
+
+    .fa {
+      margin-right: 5px;
+      color: $darker-text-color;
+    }
+  }
+
+  &__card {
+    .detailed-status__display-avatar {
+      position: relative;
+      cursor: pointer;
+    }
+
+    .detailed-status__display-name {
+      margin-bottom: 0;
+      text-decoration: none;
+
+      span {
+        font-weight: 400;
+      }
+    }
+  }
+}
+
+.memoriam-widget {
+  padding: 20px;
+  border-radius: 4px;
+  background: $base-shadow-color;
+  box-shadow: 0 0 15px rgba($base-shadow-color, 0.2);
+  font-size: 14px;
+  color: $darker-text-color;
+  margin-bottom: 10px;
+}
+
+.moved-account-widget,
+.memoriam-widget {
+  @media screen and (max-width: $no-gap-breakpoint) {
+    margin-bottom: 0;
+    box-shadow: none;
+    border-radius: 0;
+  }
+}
diff --git a/app/models/concerns/account_header.rb b/app/models/concerns/account_header.rb
index ef40b8126..067e166eb 100644
--- a/app/models/concerns/account_header.rb
+++ b/app/models/concerns/account_header.rb
@@ -5,11 +5,12 @@ module AccountHeader
 
   IMAGE_MIME_TYPES = ['image/jpeg', 'image/png', 'image/gif'].freeze
   LIMIT = 2.megabytes
+  MAX_PIXELS = 750_000 # 1500x500px
 
   class_methods do
     def header_styles(file)
-      styles = { original: { geometry: '700x335#', file_geometry_parser: FastGeometryParser } }
-      styles[:static] = { geometry: '700x335#', format: 'png', convert_options: '-coalesce', file_geometry_parser: FastGeometryParser } if file.content_type == 'image/gif'
+      styles = { original: { pixels: MAX_PIXELS, file_geometry_parser: FastGeometryParser } }
+      styles[:static] = { format: 'png', convert_options: '-coalesce', file_geometry_parser: FastGeometryParser } if file.content_type == 'image/gif'
       styles
     end
 
diff --git a/app/views/accounts/_bio.html.haml b/app/views/accounts/_bio.html.haml
new file mode 100644
index 000000000..c9a4d8f1b
--- /dev/null
+++ b/app/views/accounts/_bio.html.haml
@@ -0,0 +1,15 @@
+.public-account-bio
+  - unless account.fields.empty?
+    .account__header__fields
+      - account.fields.each do |field|
+        %dl
+          %dt.emojify{ title: field.name }= field.name
+          %dd.emojify{ title: field.value }= Formatter.instance.format_field(account, field.value, custom_emojify: true)
+
+  = account_badge(account)
+
+  - if account.note.present?
+    .account__header__content.emojify= Formatter.instance.simplified_format(account, custom_emojify: true)
+
+  .public-account-bio__extra
+    = t 'accounts.joined', date: l(account.created_at, format: :month)
diff --git a/app/views/accounts/_follow_button.html.haml b/app/views/accounts/_follow_button.html.haml
deleted file mode 100644
index 558ced010..000000000
--- a/app/views/accounts/_follow_button.html.haml
+++ /dev/null
@@ -1,28 +0,0 @@
-- relationships ||= nil
-
-- unless account.memorial? || account.moved?
-  - if user_signed_in?
-    - requested = relationships ? relationships.requested[account.id].present? : current_account.requested?(account)
-    - following = relationships ? relationships.following[account.id].present? : current_account.following?(account)
-
-  - if user_signed_in? && current_account.id != account.id && !requested
-    .controls
-      - if following
-        = link_to (account.local? ? account_unfollow_path(account) : remote_unfollow_path(acct: account.acct)), data: { method: :post }, class: 'icon-button' do
-          = fa_icon 'user-times'
-          = t('accounts.unfollow')
-      - else
-        = link_to (account.local? ? account_follow_path(account) : authorize_follow_path(acct: account.acct)), data: { method: :post }, class: 'icon-button' do
-          = fa_icon 'user-plus'
-          = t('accounts.follow')
-  - elsif user_signed_in? && current_account.id == account.id
-    .controls
-      = link_to settings_profile_url, class: 'icon-button' do
-        = fa_icon 'pencil'
-        = t('settings.edit_profile')
-  - elsif !user_signed_in?
-    .controls
-      .remote-follow
-        = link_to (account.local? ? account_remote_follow_path(account) : "web+mastodon://follow?uri=#{account.uri}"), class: 'icon-button' do
-          = fa_icon 'user-plus'
-          = t('accounts.remote_follow')
diff --git a/app/views/accounts/_follow_grid.html.haml b/app/views/accounts/_follow_grid.html.haml
deleted file mode 100644
index fdcef84be..000000000
--- a/app/views/accounts/_follow_grid.html.haml
+++ /dev/null
@@ -1,8 +0,0 @@
-.accounts-grid{ class: accounts.empty? ? 'empty' : '' }
-  - if accounts.empty?
-    = image_tag asset_pack_path('elephant_ui_greeting.svg'), alt: '', role: 'presentational'
-    = render partial: 'accounts/nothing_here'
-  - else
-    = render partial: 'accounts/grid_card', collection: accounts, as: :account, cached: !user_signed_in?
-
-= paginate follows
diff --git a/app/views/accounts/_follow_grid_hidden.html.haml b/app/views/accounts/_follow_grid_hidden.html.haml
deleted file mode 100644
index e970350e6..000000000
--- a/app/views/accounts/_follow_grid_hidden.html.haml
+++ /dev/null
@@ -1,3 +0,0 @@
-.accounts-grid.empty
-  = image_tag asset_pack_path('elephant_ui_greeting.svg'), alt: '', role: 'presentational'
-  %p.nothing-here= t('accounts.network_hidden')
diff --git a/app/views/accounts/_grid_card.html.haml b/app/views/accounts/_grid_card.html.haml
deleted file mode 100644
index a59ed128e..000000000
--- a/app/views/accounts/_grid_card.html.haml
+++ /dev/null
@@ -1,12 +0,0 @@
-.account-grid-card
-  .account-grid-card__header{ style: "background-image: url(#{account.header.url(:original)})" }
-    = render 'accounts/follow_button', account: account, relationships: @relationships
-  .account-grid-card__avatar
-    .avatar= image_tag account.avatar.url(:original)
-  .name
-    = link_to TagManager.instance.url_for(account) do
-      %span.display_name.emojify= display_name(account, custom_emojify: true)
-      %span.username
-        @#{account.local? ? account.local_username_and_domain : account.acct}
-        = fa_icon('lock') if account.locked?
-  .account__header__content.p-note.emojify= Formatter.instance.simplified_format(account)
diff --git a/app/views/accounts/_header.html.haml b/app/views/accounts/_header.html.haml
index 4098d6778..e343be820 100644
--- a/app/views/accounts/_header.html.haml
+++ b/app/views/accounts/_header.html.haml
@@ -1,51 +1,43 @@
-.card.h-card.p-author{ style: "background-image: url(#{account.header.url(:original)})" }
-  .card__illustration
-    = render 'accounts/follow_button', account: account
-    .avatar= image_tag account.avatar.url(:original), class: 'u-photo'
+.public-account-header
+  .public-account-header__image
+    = image_tag account.header.url, class: 'parallax'
+  .public-account-header__bar
+    = link_to short_account_url(account), class: 'avatar' do
+      = image_tag account.avatar.url
+    .public-account-header__tabs
+      .public-account-header__tabs__name
+        %h1
+          = display_name(account)
+          %small
+            = acct(account)
+            = fa_icon('lock') if account.locked?
+      .public-account-header__tabs__tabs
+        .details-counters
+          .counter{ class: active_nav_class(short_account_url(account)) }
+            = link_to short_account_url(account), class: 'u-url u-uid' do
+              %span.counter-number= number_to_human account.statuses_count, strip_insignificant_zeros: true
+              %span.counter-label= t('accounts.posts')
 
-  .card__bio
-    %h1.name
-      %span.p-name.emojify= display_name(account, custom_emojify: true)
-      %small<
-        %span>< @#{account.local_username_and_domain}
-        = fa_icon('lock') if account.locked?
+          .counter{ class: active_nav_class(account_following_index_url(account)) }
+            = link_to account_following_index_url(account) do
+              %span.counter-number= number_to_human account.following_count, strip_insignificant_zeros: true
+              %span.counter-label= t('accounts.following')
 
-    - if account.bot?
-      .roles
-        .account-role.bot
-          = t 'accounts.roles.bot'
-    - elsif Setting.show_staff_badge
-      - if account.user_admin?
-        .roles
-          .account-role.admin
-            = t 'accounts.roles.admin'
-      - elsif account.user_moderator?
-        .roles
-          .account-role.moderator
-            = t 'accounts.roles.moderator'
+          .counter{ class: active_nav_class(account_followers_url(account)) }
+            = link_to account_followers_url(account) do
+              %span.counter-number= number_to_human account.followers_count, strip_insignificant_zeros: true
+              %span.counter-label= t('accounts.followers')
+        .spacer
+        .public-account-header__tabs__tabs__buttons
+          = account_action_button(account)
 
-    .bio
-      .account__header__content.p-note.emojify= Formatter.instance.simplified_format(account, custom_emojify: true)
+    .public-account-header__extra
+      = render 'accounts/bio', account: account
 
-      - unless account.fields.empty?
-        .account__header__fields
-          - account.fields.each do |field|
-            %dl
-              %dt.emojify{ title: field.name }= field.name
-              %dd.emojify{ title: field.value }= Formatter.instance.format_field(account, field.value, custom_emojify: true)
-
-    .details-counters
-      .counter{ class: active_nav_class(short_account_url(account)) }
-        = link_to short_account_url(account), class: 'u-url u-uid' do
-          %span.counter-number= number_to_human account.statuses_count, strip_insignificant_zeros: true
-          %span.counter-label= t('accounts.posts')
-
-      .counter{ class: active_nav_class(account_following_index_url(account)) }
+      .public-account-header__extra__links
         = link_to account_following_index_url(account) do
-          %span.counter-number= number_to_human account.following_count, strip_insignificant_zeros: true
-          %span.counter-label= t('accounts.following')
-
-      .counter{ class: active_nav_class(account_followers_url(account)) }
+          %strong= number_to_human account.following_count, strip_insignificant_zeros: true
+          = t('accounts.following')
         = link_to account_followers_url(account) do
-          %span.counter-number= number_to_human account.followers_count, strip_insignificant_zeros: true
-          %span.counter-label= t('accounts.followers')
+          %strong= number_to_human account.followers_count, strip_insignificant_zeros: true
+          = t('accounts.followers')
diff --git a/app/views/accounts/_moved_strip.html.haml b/app/views/accounts/_moved.html.haml
index ae18c6dc7..f99328dbd 100644
--- a/app/views/accounts/_moved_strip.html.haml
+++ b/app/views/accounts/_moved.html.haml
@@ -1,11 +1,11 @@
 - moved_to_account = account.moved_to_account
 
-.moved-strip
-  .moved-strip__message
+.moved-account-widget
+  .moved-account-widget__message
     = fa_icon 'suitcase'
-    = t('accounts.moved_html', name: content_tag(:strong, display_name(account, custom_emojify: true), class: :emojify), new_profile_link: link_to(content_tag(:strong, safe_join(['@', content_tag(:span, moved_to_account.acct)])), TagManager.instance.url_for(moved_to_account), class: 'mention'))
+    = t('accounts.moved_html', name: content_tag(:bdi, content_tag(:strong, display_name(account, custom_emojify: true), class: :emojify)), new_profile_link: link_to(content_tag(:strong, safe_join(['@', content_tag(:span, moved_to_account.acct)])), TagManager.instance.url_for(moved_to_account), class: 'mention'))
 
-  .moved-strip__card
+  .moved-account-widget__card
     = link_to TagManager.instance.url_for(moved_to_account), class: 'detailed-status__display-name p-author h-card', target: '_blank', rel: 'noopener' do
       .detailed-status__display-avatar
         .account__avatar-overlay
@@ -13,5 +13,6 @@
           .account__avatar-overlay-overlay{ style: "background-image: url('#{account.avatar.url(:original)}')" }
 
       %span.display-name
-        %strong.emojify= display_name(moved_to_account, custom_emojify: true)
+        %bdi
+          %strong.emojify= display_name(moved_to_account, custom_emojify: true)
         %span @#{moved_to_account.acct}
diff --git a/app/views/accounts/_nothing_here.html.haml b/app/views/accounts/_nothing_here.html.haml
deleted file mode 100644
index 0c6dc1168..000000000
--- a/app/views/accounts/_nothing_here.html.haml
+++ /dev/null
@@ -1 +0,0 @@
-%p.nothing-here= t('accounts.nothing_here')
diff --git a/app/views/accounts/show.html.haml b/app/views/accounts/show.html.haml
index cfdd3a945..b30755d94 100644
--- a/app/views/accounts/show.html.haml
+++ b/app/views/accounts/show.html.haml
@@ -20,36 +20,39 @@
   = opengraph 'og:type', 'profile'
   = render 'og', account: @account, url: short_account_url(@account, only_path: false)
 
-- if @account.memorial?
-  .memoriam-strip= t('in_memoriam_html')
-- elsif @account.moved?
-  = render partial: 'moved_strip', locals: { account: @account }
-- elsif show_landing_strip?
-  = render partial: 'shared/landing_strip', locals: { account: @account }
-
-.h-feed
-  %data.p-name{ value: "#{@account.username} on #{site_hostname}" }/
-
-  = render 'header', account: @account
-
-  .activity-stream-tabs
-    = active_link_to t('accounts.posts'), short_account_url(@account)
-    = active_link_to t('accounts.posts_with_replies'), short_account_with_replies_url(@account)
-    = active_link_to t('accounts.media'), short_account_media_url(@account)
-
-  - if @statuses.empty?
-    .accounts-grid
-      = render 'nothing_here'
-  - else
-    .activity-stream.with-header
-      - if params[:page].to_i.zero?
-        = render partial: 'stream_entries/status', collection: @pinned_statuses, as: :status, locals: { pinned: true }
-
-      = render partial: 'stream_entries/status', collection: @statuses, as: :status
-
-  - if @newer_url || @older_url
-    .pagination
-      - if @older_url
-        = link_to safe_join([fa_icon('chevron-left'), t('pagination.older')], ' '), @older_url, class: 'older', rel: 'next'
-      - if @newer_url
-        = link_to safe_join([t('pagination.newer'), fa_icon('chevron-right')], ' '), @newer_url, class: 'newer', rel: 'prev'
+
+= render 'header', account: @account, with_bio: true
+
+.grid
+  .column-0
+    .h-feed
+      %data.p-name{ value: "#{@account.username} on #{site_hostname}" }/
+
+      .account__section-headline
+        = active_link_to t('accounts.posts'), short_account_url(@account)
+        = active_link_to t('accounts.posts_with_replies'), short_account_with_replies_url(@account)
+        = active_link_to t('accounts.media'), short_account_media_url(@account)
+
+      - if @statuses.empty?
+        = nothing_here 'nothing-here--under-tabs'
+      - else
+        .activity-stream
+          - if params[:page].to_i.zero?
+            = render partial: 'stream_entries/status', collection: @pinned_statuses, as: :status, locals: { pinned: true }
+
+          - if @newer_url
+            .entry= link_to_more @newer_url
+
+          = render partial: 'stream_entries/status', collection: @statuses, as: :status
+
+          - if @older_url
+            .entry= link_to_more @older_url
+
+  .column-1
+    - if @account.memorial?
+      .memoriam-widget= t('in_memoriam_html')
+    - elsif @account.moved?
+      = render 'moved', account: @account
+
+    = render 'bio', account: @account
+    = render 'application/sidebar'
diff --git a/app/views/application/_card.html.haml b/app/views/application/_card.html.haml
new file mode 100644
index 000000000..9cf8f8ff2
--- /dev/null
+++ b/app/views/application/_card.html.haml
@@ -0,0 +1,16 @@
+- account_url = local_assigns[:admin] ? admin_account_path(account.id) : TagManager.instance.url_for(account)
+
+.card.h-card
+  = link_to account_url, target: '_blank', rel: 'noopener' do
+    .card__img
+      = image_tag account.header.url, alt: ''
+    .card__bar
+      .avatar
+        = image_tag account.avatar.url, alt: '', width: 48, height: 48, class: 'u-photo'
+
+      .display-name
+        %bdi
+          %strong.emojify.p-name= display_name(account, custom_emojify: true)
+        %span
+          = acct(account)
+          = fa_icon('lock') if account.locked?
diff --git a/app/views/application/_sidebar.html.haml b/app/views/application/_sidebar.html.haml
new file mode 100644
index 000000000..3d8832bb4
--- /dev/null
+++ b/app/views/application/_sidebar.html.haml
@@ -0,0 +1,6 @@
+.hero-widget
+  .hero-widget__img
+    = image_tag @instance_presenter.hero&.file&.url || @instance_presenter.thumbnail&.file&.url || asset_pack_path('preview.jpg'), alt: @instance_presenter.site_title
+
+  .hero-widget__text
+    %p= @instance_presenter.site_description.html_safe.presence || t('about.generic_description', domain: site_hostname)
diff --git a/app/views/auth/registrations/new.html.haml b/app/views/auth/registrations/new.html.haml
index 0fac8e10d..200ed42de 100644
--- a/app/views/auth/registrations/new.html.haml
+++ b/app/views/auth/registrations/new.html.haml
@@ -10,7 +10,7 @@
   - if @invite.present? && @invite.autofollow?
     .fields-group{ style: 'margin-bottom: 30px' }
       %p.hint{ style: 'text-align: center' }= t('invites.invited_by')
-      = render 'authorize_follows/card', account: @invite.user.account
+      = render 'application/card', account: @invite.user.account
 
   = f.simple_fields_for :account do |ff|
     .input-with-append
diff --git a/app/views/authorize_follows/_card.html.haml b/app/views/authorize_follows/_card.html.haml
deleted file mode 100644
index edc03131f..000000000
--- a/app/views/authorize_follows/_card.html.haml
+++ /dev/null
@@ -1,23 +0,0 @@
-.account-card
-  .account-card__header{ style: "background-image: url(#{account.header.url(:original)})" }
-  .detailed-status__display-name
-    %div
-      = image_tag account.avatar.url(:original), alt: '', width: 48, height: 48, class: 'avatar'
-
-    %span.display-name
-      - account_url = local_assigns[:admin] ? admin_account_path(account.id) : TagManager.instance.url_for(account)
-      = link_to account_url, class: 'detailed-status__display-name p-author h-card', target: '_blank', rel: 'noopener' do
-        %strong.emojify= display_name(account, custom_emojify: true)
-        %span @#{account.acct}
-
-    .counter
-      %span.counter-number= number_to_human account.statuses_count, strip_insignificant_zeros: true
-      %span.counter-label= t('accounts.posts')
-
-    .counter
-      %span.counter-number= number_to_human account.following_count, strip_insignificant_zeros: true
-      %span.counter-label= t('accounts.following')
-
-    .counter
-      %span.counter-number= number_to_human account.followers_count, strip_insignificant_zeros: true
-      %span.counter-label= t('accounts.followers')
diff --git a/app/views/authorize_follows/show.html.haml b/app/views/authorize_follows/show.html.haml
index a1fd01dd6..90e65b34f 100644
--- a/app/views/authorize_follows/show.html.haml
+++ b/app/views/authorize_follows/show.html.haml
@@ -3,7 +3,7 @@
 
 .form-container
   .follow-prompt
-    = render 'card', account: @account
+    = render 'application/card', account: @account
 
   - if current_account.following?(@account)
     .flash-message
diff --git a/app/views/authorize_follows/success.html.haml b/app/views/authorize_follows/success.html.haml
index fa59b24b8..cf9cb50ea 100644
--- a/app/views/authorize_follows/success.html.haml
+++ b/app/views/authorize_follows/success.html.haml
@@ -8,6 +8,6 @@
     - else
       %h2= t('authorize_follow.following')
 
-    = render 'card', account: @account
+    = render 'application/card', account: @account
 
   = render 'post_follow_actions'
diff --git a/app/views/follower_accounts/index.html.haml b/app/views/follower_accounts/index.html.haml
index 65af81a5b..31dab68bf 100644
--- a/app/views/follower_accounts/index.html.haml
+++ b/app/views/follower_accounts/index.html.haml
@@ -8,6 +8,11 @@
 = render 'accounts/header', account: @account
 
 - if @account.user_hides_network?
-  = render 'accounts/follow_grid_hidden'
+  .nothing-here= t('accounts.network_hidden')
+- elsif @follows.empty?
+  = nothing_here
 - else
-  = render 'accounts/follow_grid', follows: @follows, accounts: @follows.map(&:account)
+  .card-grid
+    = render partial: 'application/card', collection: @follows.map(&:account), as: :account
+
+  = paginate @follows
diff --git a/app/views/following_accounts/index.html.haml b/app/views/following_accounts/index.html.haml
index 8fd95a0b4..8b49b529b 100644
--- a/app/views/following_accounts/index.html.haml
+++ b/app/views/following_accounts/index.html.haml
@@ -8,6 +8,11 @@
 = render 'accounts/header', account: @account
 
 - if @account.user_hides_network?
-  = render 'accounts/follow_grid_hidden'
+  .nothing-here= t('accounts.network_hidden')
+- elsif @follows.empty?
+  = nothing_here
 - else
-  = render 'accounts/follow_grid', follows: @follows, accounts: @follows.map(&:target_account)
+  .card-grid
+    = render partial: 'application/card', collection: @follows.map(&:target_account), as: :account
+
+  = paginate @follows
diff --git a/app/views/layouts/public.html.haml b/app/views/layouts/public.html.haml
index 600290297..f9d808bed 100644
--- a/app/views/layouts/public.html.haml
+++ b/app/views/layouts/public.html.haml
@@ -2,16 +2,49 @@
   = javascript_pack_tag 'public', integrity: true, crossorigin: 'anonymous'
 
 - content_for :content do
-  .container-alt= yield
-  .footer
-    - if !user_signed_in? && single_user_mode?
-      %span.single-user-login
-        = link_to t('auth.login'), new_user_session_path
-        &mdash;
-      %span.footer__domain= link_to site_hostname, about_path
-    - else
-      %span.footer__domain= link_to site_hostname, root_path
-    %span.powered-by
-      != t('generic.powered_by', link: link_to('https://joinmastodon.org') { image_tag asset_pack_path('logo_full.svg'), alt: 'Mastodon' })
+  .public-layout
+    .container
+      %nav.header
+        .nav-left
+          = link_to root_url, class: 'brand' do
+            = image_tag asset_pack_path('logo_full.svg'), alt: 'Mastodon'
+        .nav-center
+        .nav-right
+          - if user_signed_in?
+            = link_to t('settings.back'), root_url, class: 'nav-link nav-button webapp-btn'
+          - else
+            = link_to t('auth.login'), new_user_session_path, class: 'webapp-btn nav-link nav-button'
+            = link_to t('auth.register'), new_user_registration_path, class: 'webapp-btn nav-link nav-button'
+
+    .container= yield
+
+    .container
+      .footer
+        .grid
+          .column-0
+            %h4= t 'footer.resources'
+            %ul
+              %li= link_to t('about.terms'), terms_path
+              %li= link_to t('about.privacy_policy'), terms_path
+          .column-1
+            %h4= t 'footer.developers'
+            %ul
+              %li= link_to t('about.documentation'), 'https://github.com/tootsuite/documentation'
+              %li= link_to t('about.api'), 'https://github.com/tootsuite/documentation/blob/master/Using-the-API/API.md'
+          .column-2
+            %h4= link_to t('about.what_is_mastodon'), 'https://joinmastodon.org/'
+
+            = link_to root_url, class: 'brand' do
+              = render file: Rails.root.join('app', 'javascript', 'images', 'logo_transparent.svg')
+          .column-3
+            %h4= site_hostname
+            %ul
+              %li= link_to t('about.about_this'), about_more_path
+              %li= "v#{Mastodon::Version.to_s}"
+          .column-4
+            %h4= t 'footer.more'
+            %ul
+              %li= link_to t('about.source_code'), Mastodon::Version.source_url
+              %li= link_to 'joinmastodon.org', 'https://joinmastodon.org'
 
 = render template: 'layouts/application'
diff --git a/app/views/remote_follow/new.html.haml b/app/views/remote_follow/new.html.haml
index 9b22fda5f..9b679015f 100644
--- a/app/views/remote_follow/new.html.haml
+++ b/app/views/remote_follow/new.html.haml
@@ -6,7 +6,7 @@
   .follow-prompt
     %h2= t('remote_follow.prompt')
 
-    = render partial: 'authorize_follows/card', locals: { account: @account }
+    = render partial: 'application/card', locals: { account: @account }
 
   = simple_form_for @remote_follow, as: :remote_follow, url: account_remote_follow_path(@account) do |f|
     = render 'shared/error_messages', object: @remote_follow
diff --git a/app/views/remote_unfollows/success.html.haml b/app/views/remote_unfollows/success.html.haml
index aa3c838a0..b007eedc7 100644
--- a/app/views/remote_unfollows/success.html.haml
+++ b/app/views/remote_unfollows/success.html.haml
@@ -5,6 +5,6 @@
   .follow-prompt
     %h2= t('remote_unfollow.unfollowed')
 
-    = render 'card', account: @account
+    = render 'application/card', account: @account
 
   = render 'post_follow_actions'
diff --git a/app/views/settings/migrations/show.html.haml b/app/views/settings/migrations/show.html.haml
index b7c34761f..c69061d50 100644
--- a/app/views/settings/migrations/show.html.haml
+++ b/app/views/settings/migrations/show.html.haml
@@ -6,7 +6,7 @@
     %p.hint= t('migrations.currently_redirecting')
 
     .fields-group
-      = render partial: 'authorize_follows/card', locals: { account: @migration.account }
+      = render partial: 'application/card', locals: { account: @migration.account }
 
   = render 'shared/error_messages', object: @migration
 
diff --git a/app/views/settings/profiles/show.html.haml b/app/views/settings/profiles/show.html.haml
index a84f8a7da..3940eb855 100644
--- a/app/views/settings/profiles/show.html.haml
+++ b/app/views/settings/profiles/show.html.haml
@@ -8,8 +8,7 @@
     = f.input :display_name, placeholder: t('simple_form.labels.defaults.display_name'), hint: t('simple_form.hints.defaults.display_name', count: 30 - @account.display_name.size).html_safe
     = f.input :note, placeholder: t('simple_form.labels.defaults.note'), hint: t('simple_form.hints.defaults.note', count: 160 - @account.note.size).html_safe
 
-  .card.compact{ style: "background-image: url(#{@account.header.url(:original)})", data: { original_src: @account.header.url(:original) } }
-    .avatar= image_tag @account.avatar.url(:original), data: { original_src: @account.avatar.url(:original) }
+  = render 'application/card', account: @account
 
   .fields-group
     = f.input :avatar, wrapper: :with_label, input_html: { accept: AccountAvatar::IMAGE_MIME_TYPES.join(',') }, hint: t('simple_form.hints.defaults.avatar')
diff --git a/app/views/shared/_landing_strip.html.haml b/app/views/shared/_landing_strip.html.haml
deleted file mode 100644
index 9a4144723..000000000
--- a/app/views/shared/_landing_strip.html.haml
+++ /dev/null
@@ -1,6 +0,0 @@
-.landing-strip
-  = image_tag asset_pack_path('logo.svg'), class: 'logo'
-
-  %div
-    = t('landing_strip_html', name: content_tag(:span, display_name(account, custom_emojify: true), class: :emojify), link_to_root_path: link_to(content_tag(:strong, site_hostname), root_path))
-    = t('landing_strip_signup_html', sign_up_path: open_registrations? ? new_user_registration_path : 'https://joinmastodon.org/#getting-started')
diff --git a/app/views/stream_entries/_content_spoiler.html.haml b/app/views/stream_entries/_content_spoiler.html.haml
deleted file mode 100644
index 798dfce67..000000000
--- a/app/views/stream_entries/_content_spoiler.html.haml
+++ /dev/null
@@ -1,7 +0,0 @@
-.media-spoiler-wrapper{ class: sensitive == false && 'media-spoiler-wrapper__visible' }
-  .spoiler-button
-    .icon-button.overlayed
-      %i.fa.fa-fw.fa-eye
-  .media-spoiler
-    %span= t('stream_entries.sensitive_content')
-    %span= t('stream_entries.click_to_show')
diff --git a/app/views/stream_entries/_detailed_status.html.haml b/app/views/stream_entries/_detailed_status.html.haml
index 85e90a237..aa160b979 100644
--- a/app/views/stream_entries/_detailed_status.html.haml
+++ b/app/views/stream_entries/_detailed_status.html.haml
@@ -1,16 +1,15 @@
-.detailed-status.light
+.detailed-status.detailed-status--flex
   = link_to TagManager.instance.url_for(status.account), class: 'detailed-status__display-name p-author h-card', target: stream_link_target, rel: 'noopener' do
-    %div
-      .avatar
-        = image_tag status.account.avatar.url(:original), width: 48, height: 48, alt: '', class: 'u-photo'
+    .detailed-status__display-avatar
+      = image_tag status.account.avatar.url(:original), width: 48, height: 48, alt: '', class: 'account__avatar u-photo'
     %span.display-name
-      %strong.p-name.emojify= display_name(status.account, custom_emojify: true)
-      %span= acct(status.account)
+      %bdi
+        %strong.display-name__html.p-name.emojify= display_name(status.account, custom_emojify: true)
+      %span.display-name__account
+        = acct(status.account)
+        = fa_icon('lock') if status.account.locked?
 
-  - if !user_signed_in? || embedded_view?
-    = link_to account_remote_follow_path(status.account), class: 'button button-secondary logo-button', target: '_new' do
-      = render file: Rails.root.join('app', 'javascript', 'images', 'logo.svg')
-      = t('accounts.follow')
+  = account_action_button(status.account)
 
   .status__content.emojify<
     - if status.spoiler_text?
@@ -30,6 +29,7 @@
 
   .detailed-status__meta
     %data.dt-published{ value: status.created_at.to_time.iso8601 }
+
     = link_to TagManager.instance.url_for(status), class: 'detailed-status__datetime u-url u-uid', target: stream_link_target, rel: 'noopener' do
       %time.formatted{ datetime: status.created_at.iso8601, title: l(status.created_at) }= l(status.created_at)
     ·
@@ -40,20 +40,20 @@
         = link_to status.application.name, status.application.website, class: 'detailed-status__application', target: '_blank', rel: 'noopener'
       ·
     - if status.direct_visibility?
-      %span<
+      %span.detailed-status__link<
         = fa_icon('envelope')
     - elsif status.private_visibility?
-      %span<
+      %span.detailed-status__link<
         = fa_icon('lock')
     - else
-      %span<
+      %span.detailed-status__link<
         = fa_icon('retweet')
-        %span= status.reblogs_count
+        %span.detailed-status__reblogs= number_to_human status.reblogs_count, strip_insignificant_zeros: true
     ·
-    %span<
+    %span.detailed-status__link<
       = fa_icon('star')
-      %span= status.favourites_count
+      %span.detailed-status__favorites= number_to_human status.favourites_count, strip_insignificant_zeros: true
 
     - if user_signed_in?
       ·
-      = link_to t('statuses.open_in_web'), web_url("statuses/#{status.id}"), class: 'open-in-web-link', target: '_blank'
+      = link_to t('statuses.open_in_web'), web_url("statuses/#{status.id}"), class: 'detailed-status__application', target: '_blank'
diff --git a/app/views/stream_entries/_media.html.haml b/app/views/stream_entries/_media.html.haml
deleted file mode 100644
index 779f02c8d..000000000
--- a/app/views/stream_entries/_media.html.haml
+++ /dev/null
@@ -1,4 +0,0 @@
-.media-item
-  = link_to media.remote_url.blank? ? media.file.url(:original) : media.remote_url, style: media.image? ? "background-image: url(#{media.file.url(:original)})" : '', target: '_blank', rel: 'noopener', class: "u-#{media.video? || media.gifv? ? 'video' : 'photo'}" do
-    - unless media.image?
-      %video{ src: media.file.url(:original), autoplay: true, loop: true }/
diff --git a/app/views/stream_entries/_more.html.haml b/app/views/stream_entries/_more.html.haml
deleted file mode 100644
index 9b1dfe4a7..000000000
--- a/app/views/stream_entries/_more.html.haml
+++ /dev/null
@@ -1,2 +0,0 @@
-= link_to url, class: 'more light'  do
-  = t('statuses.show_more')
diff --git a/app/views/stream_entries/_simple_status.html.haml b/app/views/stream_entries/_simple_status.html.haml
index 0f27585a1..676d367ca 100644
--- a/app/views/stream_entries/_simple_status.html.haml
+++ b/app/views/stream_entries/_simple_status.html.haml
@@ -1,18 +1,19 @@
-.status.light
-  .status__header
-    .status__meta
-      = link_to TagManager.instance.url_for(status), class: 'status__relative-time u-url u-uid', target: stream_link_target, rel: 'noopener' do
-        %time.time-ago{ datetime: status.created_at.iso8601, title: l(status.created_at) }= l(status.created_at)
-      %data.dt-published{ value: status.created_at.to_time.iso8601 }
+.status
+  .status__info
+    = link_to TagManager.instance.url_for(status), class: 'status__relative-time u-url u-uid', target: stream_link_target, rel: 'noopener' do
+      %time.time-ago{ datetime: status.created_at.iso8601, title: l(status.created_at) }= l(status.created_at)
+    %data.dt-published{ value: status.created_at.to_time.iso8601 }
 
     = link_to TagManager.instance.url_for(status.account), class: 'status__display-name p-author h-card', target: stream_link_target, rel: 'noopener' do
       .status__avatar
         %div
-          = image_tag status.account.avatar(:original), width: 48, height: 48, alt: '', class: 'u-photo'
+          = image_tag status.account.avatar(:original), width: 48, height: 48, alt: '', class: 'u-photo account__avatar'
       %span.display-name
-        %strong.p-name.emojify= display_name(status.account, custom_emojify: true)
-        %span= acct(status.account)
-
+        %bdi
+          %strong.display-name__html.p-name.emojify= display_name(status.account, custom_emojify: true)
+        %span.display-name__account
+          = acct(status.account)
+          = fa_icon('lock') if status.account.locked?
   .status__content.emojify<
     - if status.spoiler_text?
       %p{ style: 'margin-bottom: 0' }<
@@ -26,3 +27,16 @@
       = react_component :video, src: video.file.url(:original), preview: video.file.url(:small), sensitive: status.sensitive? && !current_account&.user&.setting_display_sensitive_media, width: 610, height: 343, inline: true
     - else
       = react_component :media_gallery, height: 343, sensitive: status.sensitive? && !current_account&.user&.setting_display_sensitive_media, 'autoPlayGif': current_account&.user&.setting_auto_play_gif, media: status.media_attachments.map { |a| ActiveModelSerializers::SerializableResource.new(a, serializer: REST::MediaAttachmentSerializer).as_json }
+
+  .status__action-bar
+    .status__action-bar-button.static-icon-button<
+      - if status.public_visibility? || status.unlisted_visibility?
+        = fa_icon 'retweet fw'
+        %span.detailed-status__reblogs= number_to_human status.reblogs_count, strip_insignificant_zeros: true
+      - elsif status.private_visibility?
+        = fa_icon 'lock fw'
+      - else
+        = fa_icon 'envelope fw'
+    .status__action-bar-button.static-icon-button<
+      = fa_icon 'star fw'
+      %span.detailed-status__favorites= number_to_human status.favourites_count, strip_insignificant_zeros: true
diff --git a/app/views/stream_entries/_status.html.haml b/app/views/stream_entries/_status.html.haml
index b87ca2177..320c9bc4f 100644
--- a/app/views/stream_entries/_status.html.haml
+++ b/app/views/stream_entries/_status.html.haml
@@ -16,24 +16,25 @@
 - if status.reply? && include_threads
   - if @next_ancestor
     .entry{ class: entry_classes }
-      = render 'stream_entries/more', url: TagManager.instance.url_for(@next_ancestor)
+      = link_to_more TagManager.instance.url_for(@next_ancestor)
 
   = render partial: 'stream_entries/status', collection: @ancestors, as: :status, locals: { is_predecessor: true, direct_reply_id: status.in_reply_to_id }
 
 .entry{ class: entry_classes }
 
   - if status.reblog?
-    .pre-header
-      .pre-header__icon
-        = fa_icon('retweet fw')
+    .status__prepend
+      .status__prepend-icon-wrapper
+        %i.status__prepend-icon.fa.fa-fw.fa-retweet
       %span
         = link_to TagManager.instance.url_for(status.account), class: 'status__display-name muted' do
-          %strong.emojify= display_name(status.account, custom_emojify: true)
+          %bdi
+            %strong.emojify= display_name(status.account, custom_emojify: true)
         = t('stream_entries.reblogged')
   - elsif pinned
-    .pre-header
-      .pre-header__icon
-        = fa_icon('thumb-tack fw')
+    .status__prepend
+      .status__prepend-icon-wrapper
+        %i.status__prepend-icon.fa.fa-fw.fa-thumb-tack
       %span
         = t('stream_entries.pinned')
 
@@ -42,13 +43,13 @@
 - if include_threads
   - if @since_descendant_thread_id
     .entry{ class: entry_classes }
-      = render 'stream_entries/more', url: short_account_status_url(status.account.username, status, max_descendant_thread_id: @since_descendant_thread_id + 1)
+      = link_to_more short_account_status_url(status.account.username, status, max_descendant_thread_id: @since_descendant_thread_id + 1)
   - @descendant_threads.each do |thread|
     = render partial: 'stream_entries/status', collection: thread[:statuses], as: :status, locals: { is_successor: true, parent_id: status.id }
 
     - if thread[:next_status]
       .entry{ class: entry_classes }
-        = render 'stream_entries/more', url: TagManager.instance.url_for(thread[:next_status])
+        = link_to_more TagManager.instance.url_for(thread[:next_status])
   - if @next_descendant_thread
     .entry{ class: entry_classes }
-      = render 'stream_entries/more', url: short_account_status_url(status.account.username, status, since_descendant_thread_id: @max_descendant_thread_id - 1)
+      = link_to_more short_account_status_url(status.account.username, status, since_descendant_thread_id: @max_descendant_thread_id - 1)
diff --git a/app/views/stream_entries/embed.html.haml b/app/views/stream_entries/embed.html.haml
index b703c15d2..d20c1e93e 100644
--- a/app/views/stream_entries/embed.html.haml
+++ b/app/views/stream_entries/embed.html.haml
@@ -1,3 +1,3 @@
 - cache @stream_entry.activity do
-  .activity-stream.activity-stream-headless
+  .activity-stream.activity-stream--headless
     = render "stream_entries/#{@type}", @type.to_sym => @stream_entry.activity, centered: true
diff --git a/app/views/stream_entries/show.html.haml b/app/views/stream_entries/show.html.haml
index dfb83e747..9da6245dc 100644
--- a/app/views/stream_entries/show.html.haml
+++ b/app/views/stream_entries/show.html.haml
@@ -17,8 +17,9 @@
   = render 'stream_entries/og_description', activity: @stream_entry.activity
   = render 'stream_entries/og_image', activity: @stream_entry.activity, account: @account
 
-- if show_landing_strip?
-  = render partial: 'shared/landing_strip', locals: { account: @stream_entry.account }
-
-.activity-stream.activity-stream-headless.h-entry
-  = render partial: "stream_entries/#{@type}", locals: { @type.to_sym => @stream_entry.activity, include_threads: true }
+.grid
+  .column-0
+    .activity-stream.activity-stream-headless.h-entry
+      = render partial: "stream_entries/#{@type}", locals: { @type.to_sym => @stream_entry.activity, include_threads: true }
+  .column-1
+    = render 'application/sidebar'
diff --git a/config/locales/ar.yml b/config/locales/ar.yml
index 013bc7004..d40ae0f72 100644
--- a/config/locales/ar.yml
+++ b/config/locales/ar.yml
@@ -46,7 +46,6 @@ ar:
     people_who_follow: الأشخاص الذين يتبعون %{name}
     posts: منشورات
     posts_with_replies: التبويقات و الردود
-    remote_follow: إتبع عن بعد
     reserved_username: إسم المستخدم محجوز
     roles:
       admin: المدير
@@ -516,7 +515,6 @@ ar:
     unlocked_warning_title: إنّ حسابك غير مقفل
   generic:
     changes_saved_msg: تم حفظ التعديلات بنجاح !
-    powered_by: مدعوم بـ %{link}
     save_changes: حفظ التغييرات
     validation_errors:
       one: لا يزال هناك خلل ما إلى حد الآن. يُرجى إعادة النظر في الخطأ أسفله
@@ -551,8 +549,6 @@ ar:
       expires_at: تنتهي مدة صلاحيتها في
       uses: يستخدِم
     title: دعوة أشخاص
-  landing_strip_html: "<strong>%{name}</strong> هو أحد مُستخدِمي %{link_to_root_path}. بإمكانك متابعته أو التواصل معه إن كنت تملك حسابًا أيا كان على البيئة الموحَّدة فيديفرس."
-  landing_strip_signup_html: إن كنت لا تملك واحدا، يمكنك <a href="%{sign_up_path}">التسجيل مِن هنا</a>.
   lists:
     errors:
       limit: لقد بلغت الحد الأقصى للقوائم
@@ -720,7 +716,6 @@ ar:
       unlisted: غير مُدرَج
       unlisted_long: يُمكن لأيٍ كان رُؤيتَه و لكن لن يُعرَض على الخيوط العامة
   stream_entries:
-    click_to_show: إضغط للعرض
     pinned: تبويق مثبّت
     reblogged: رقى
     sensitive_content: محتوى حساس
diff --git a/config/locales/ast.yml b/config/locales/ast.yml
index 4436c2d88..3dae9cc1a 100644
--- a/config/locales/ast.yml
+++ b/config/locales/ast.yml
@@ -96,8 +96,6 @@ ast:
   followers:
     domain: Dominiu
     followers_count: Númberu de siguidores
-  generic:
-    powered_by: cola potencia de %{link}
   invites:
     expires_in:
       '1800': 30 minutos
@@ -183,7 +181,6 @@ ast:
         other: "%{count} vídeos"
     title: "%{name}: «%{quote}»"
   stream_entries:
-    click_to_show: Primi p'amosar
     sensitive_content: Conteníu sensible
   themes:
     default: Mastodon
diff --git a/config/locales/bg.yml b/config/locales/bg.yml
index cb3ed2244..f101101e2 100644
--- a/config/locales/bg.yml
+++ b/config/locales/bg.yml
@@ -22,7 +22,6 @@ bg:
     people_followed_by: Хора, които %{name} следва
     people_who_follow: Хора, които следват %{name}
     posts: Публикации
-    remote_follow: Последвай
     unfollow: Не следвай
   application_mailer:
     settings: 'Промяна на предпочитанията за e-mail: %{link}'
@@ -64,7 +63,6 @@ bg:
     storage: Съхранение на мултимедия
   generic:
     changes_saved_msg: Успешно запазване на промените!
-    powered_by: поддържано от %{link}
     save_changes: Запази промените
     validation_errors:
       one: Нещо все още не е наред! Моля, прегледай грешката по-долу
@@ -76,8 +74,6 @@ bg:
       blocking: Списък на блокираните
       following: Списък на последователите
     upload: Качване
-  landing_strip_html: "<strong>%{name}</strong> е потребител от %{link_to_root_path}. Можеш да ги следваш, или да контактуваш с тях, ако имаш акаунт където и да е из федерираната вселена на Mastodon."
-  landing_strip_signup_html: Ако нямаш акаунт, можеш да си <a href="%{sign_up_path}">създадеш ето тук</a>.
   media_attachments:
     validations:
       images_and_video: Не мога да прикача видеоклип към публикация, която вече съдържа изображения
@@ -144,7 +140,6 @@ bg:
       public: Публично
       unlisted: Публично, но не показвай в публичния канал
   stream_entries:
-    click_to_show: Покажи
     reblogged: споделено
     sensitive_content: Деликатно съдържание
   time:
diff --git a/config/locales/ca.yml b/config/locales/ca.yml
index 45430f541..ea8a5712b 100644
--- a/config/locales/ca.yml
+++ b/config/locales/ca.yml
@@ -46,7 +46,6 @@ ca:
     people_who_follow: Usuaris que segueixen %{name}
     posts: Toots
     posts_with_replies: Toots i respostes
-    remote_follow: Seguiment remot
     reserved_username: El nom d'usuari està reservat
     roles:
       admin: Administrador
@@ -504,7 +503,6 @@ ca:
     unlocked_warning_title: El teu compte no està blocat
   generic:
     changes_saved_msg: Els canvis s'han desat correctament!
-    powered_by: amb tecnologia %{link}
     save_changes: Desa els canvis
     validation_errors:
       one: Alguna cosa no va bé! Si us plau, revisa l'error
@@ -540,8 +538,6 @@ ca:
       expires_at: Caduca
       uses: Usos
     title: Convida persones
-  landing_strip_html: "<strong>%{name}</strong> és un usuari/a de %{link_to_root_path}. Pots seguir-lo/la o interactuar amb ell/a si tens un compte a qualsevol node del fediverse."
-  landing_strip_signup_html: Si no en tens, pots <a href="%{sign_up_path}">registrar-te aquí</a>.
   lists:
     errors:
       limit: Has assolit la quantitat màxima de llistes
@@ -710,7 +706,6 @@ ca:
       unlisted: No llistat
       unlisted_long: Tothom ho pot veure, però no es mostra en la història federada
   stream_entries:
-    click_to_show: Clic per mostrar
     pinned: Toot fixat
     reblogged: ha impulsat
     sensitive_content: Contingut sensible
diff --git a/config/locales/co.yml b/config/locales/co.yml
index 6608f05a9..4326dde67 100644
--- a/config/locales/co.yml
+++ b/config/locales/co.yml
@@ -46,7 +46,6 @@ co:
     people_who_follow: Seguitanu %{name}
     posts: Statuti
     posts_with_replies: Statuti è risposte
-    remote_follow: Siguità d’altrò
     reserved_username: Stu cugnome hè riservatu
     roles:
       admin: Amministratore
@@ -488,7 +487,6 @@ co:
     unlocked_warning_title: U vostru contu hè pubblicu
   generic:
     changes_saved_msg: Cambiamenti salvati!
-    powered_by: mossu da %{link}
     save_changes: Salvà e mudificazione
     validation_errors:
       one: Qualcosa ùn và bè! Verificate u prublemu quì sottu
@@ -523,8 +521,6 @@ co:
       expires_at: Spira
       uses: Utiliza
     title: Invità ghjente
-  landing_strip_html: "<strong>%{name}</strong> hè nant’à %{link_to_root_path}. Pudete seguitallu·a o cumunicà cù ellu·a cù un contu in qualche parte di u fediverse."
-  landing_strip_signup_html: Pudete ancu <a href="%{sign_up_path}">arrigistravi quì</a>.
   lists:
     errors:
       limit: Ùn pudete più creà altre liste
@@ -691,7 +687,6 @@ co:
       unlisted: Micca listatu
       unlisted_long: Tuttu u mondu pò vede, mà micca indè e linee pubbliche
   stream_entries:
-    click_to_show: Cliccà per vede
     pinned: Statutu puntarulatu
     reblogged: spartutu
     sensitive_content: Cuntenutu sensibile
diff --git a/config/locales/da.yml b/config/locales/da.yml
index 7f9cd1e1e..a66b72541 100644
--- a/config/locales/da.yml
+++ b/config/locales/da.yml
@@ -46,7 +46,6 @@ da:
     people_who_follow: Folk der følger %{name}
     posts: Dyt
     posts_with_replies: Toots og svar
-    remote_follow: Følg fra andre instanser
     reserved_username: Brugernavnet er reserveret
     roles:
       admin: Administrator
@@ -464,7 +463,6 @@ da:
     unlocked_warning_title: Din konto er ikke låst
   generic:
     changes_saved_msg: Ændringerne blev gemt!
-    powered_by: drevet af %{link}
     save_changes: Gem ændringer
   imports:
     types:
@@ -593,7 +591,6 @@ da:
       public_long: Alle kan se
       unlisted: Ikke listet
   stream_entries:
-    click_to_show: Tryk for at vise
     pinned: Fastgjort toot
     sensitive_content: Følsomt indhold
   themes:
diff --git a/config/locales/de.yml b/config/locales/de.yml
index a8a0e0f09..a7e3c6ffe 100644
--- a/config/locales/de.yml
+++ b/config/locales/de.yml
@@ -46,7 +46,6 @@ de:
     people_who_follow: Profile, die %{name} folgen
     posts: Beiträge
     posts_with_replies: Beiträge mit Antworten
-    remote_follow: Folgen
     reserved_username: Dieser Profilname ist belegt
     roles:
       admin: Admin
@@ -517,7 +516,6 @@ de:
     unlocked_warning_title: Dein Konto ist nicht gesperrt
   generic:
     changes_saved_msg: Änderungen gespeichert!
-    powered_by: angetrieben von %{link}
     save_changes: Änderungen speichern
     validation_errors:
       one: Etwas ist noch nicht ganz richtig! Bitte korrigiere den Fehler
@@ -553,8 +551,6 @@ de:
       expires_at: Läuft ab
       uses: Verwendungen
     title: Leute Einladen
-  landing_strip_html: "<strong>%{name}</strong> hat ein Profil auf %{link_to_root_path}. Du kannst folgen oder interagieren, sofern du ein Konto irgendwo im Fediversum hast."
-  landing_strip_signup_html: Wenn nicht, kannst du dich <a href="%{sign_up_path}">hier anmelden</a>.
   lists:
     errors:
       limit: Du hast die maximale Anzahl an Listen erreicht
@@ -723,7 +719,6 @@ de:
       unlisted: Nicht gelistet
       unlisted_long: Für alle sichtbar, aber nicht in öffentlichen Zeitleisten aufgelistet
   stream_entries:
-    click_to_show: Klicken, um zu zeigen
     pinned: Angehefteter Beitrag
     reblogged: teilte
     sensitive_content: Heikle Inhalte
diff --git a/config/locales/el.yml b/config/locales/el.yml
index 7fd48b7d2..905564317 100644
--- a/config/locales/el.yml
+++ b/config/locales/el.yml
@@ -46,7 +46,6 @@ el:
     people_who_follow: Χρήστες που ακολουθούν τον/την %{name}
     posts: Τουτ
     posts_with_replies: Τουτ και απαντήσεις
-    remote_follow: Απομακρυσμένη παρακολούθηση
     reserved_username: Το όνομα χρήστη είναι κατειλημμένο
     roles:
       admin: Διαχειριστής
@@ -536,7 +535,6 @@ el:
     unlocked_warning_title: Ο λογαριασμός σου δεν είναι κλειδωμένος
   generic:
     changes_saved_msg: Οι αλλαγές αποθηκεύτηκαν!
-    powered_by: παρέχεται από %{link}
     save_changes: Αποθήκευσε αλλαγές
     validation_errors:
       one: Κάτι δεν είναι εντάξει ακόμα! Για κοίταξε το παρακάτω σφάλμα
@@ -572,8 +570,6 @@ el:
       expires_at: Λήγει
       uses: Χρήσεις
     title: Προσκάλεσε άτομα
-  landing_strip_html: Ο/Η <strong>%{name}</strong> είναι χρήστης στο %{link_to_root_path}. Μπορείς να ακολουθήσεις ή να αλληλεπιδράσεις μαζί τους αν έχεις λογαριασμό οπουδήποτε στο fediverse.
-  landing_strip_signup_html: Αν όχι, μπορείς να <a href="%{sign_up_path}">γραφτείς εδώ</a>.
   lists:
     errors:
       limit: Έχεις φτάσει το μέγιστο πλήθος επιτρεπτών λιστών
@@ -741,7 +737,6 @@ el:
       unlisted: Ακαταχώριστο
       unlisted_long: Βλέπει οποιοσδήποτε, αλλά δεν καταχωρείται στις δημόσιες ροές
   stream_entries:
-    click_to_show: Κλικ για εμφάνιση
     pinned: Καρφιτσωμένο τουτ
     reblogged: προωθημένο
     sensitive_content: Ευαίσθητο περιεχόμενο
diff --git a/config/locales/en.yml b/config/locales/en.yml
index f89f89959..66f475ded 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -5,11 +5,13 @@ en:
     about_mastodon_html: Mastodon is a social network based on open web protocols and free, open-source software. It is decentralized like e-mail.
     about_this: About
     administered_by: 'Administered by:'
+    api: API
     closed_registrations: Registrations are currently closed on this instance. However! You can find a different instance to make an account on and get access to the very same network from there.
     contact: Contact
     contact_missing: Not set
     contact_unavailable: N/A
     description_headline: What is %{domain}?
+    documentation: Documentation
     domain_count_after: other instances
     domain_count_before: Connected to
     extended_description_html: |
@@ -28,9 +30,11 @@ en:
     hosted_on: Mastodon hosted on %{domain}
     learn_more: Learn more
     other_instances: Instance list
+    privacy_policy: Privacy policy
     source_code: Source code
     status_count_after: statuses
     status_count_before: Who authored
+    terms: Terms of service
     user_count_after: users
     user_count_before: Home to
     what_is_mastodon: What is Mastodon?
@@ -38,6 +42,7 @@ en:
     follow: Follow
     followers: Followers
     following: Following
+    joined: Joined %{date}
     media: Media
     moved_html: "%{name} has moved to %{new_profile_link}:"
     network_hidden: This information is not available
@@ -46,7 +51,6 @@ en:
     people_who_follow: People who follow %{name}
     posts: Toots
     posts_with_replies: Toots and replies
-    remote_follow: Remote follow
     reserved_username: The username is reserved
     roles:
       admin: Admin
@@ -534,9 +538,12 @@ en:
     true_privacy_html: Please mind that <strong>true privacy can only be achieved with end-to-end encryption</strong>.
     unlocked_warning_html: Anyone can follow you to immediately view your private statuses. %{lock_link} to be able to review and reject followers.
     unlocked_warning_title: Your account is not locked
+  footer:
+    developers: Developers
+    more: More…
+    resources: Resources
   generic:
     changes_saved_msg: Changes successfully saved!
-    powered_by: powered by %{link}
     save_changes: Save changes
     validation_errors:
       one: Something isn't quite right yet! Please review the error below
@@ -572,8 +579,6 @@ en:
       expires_at: Expires
       uses: Uses
     title: Invite people
-  landing_strip_html: "<strong>%{name}</strong> is a user on %{link_to_root_path}. You can follow them or interact with them if you have an account anywhere in the fediverse."
-  landing_strip_signup_html: If you don't, you can <a href="%{sign_up_path}">sign up here</a>.
   lists:
     errors:
       limit: You have reached the maximum amount of lists
@@ -742,7 +747,6 @@ en:
       unlisted: Unlisted
       unlisted_long: Everyone can see, but not listed on public timelines
   stream_entries:
-    click_to_show: Click to show
     pinned: Pinned toot
     reblogged: boosted
     sensitive_content: Sensitive content
@@ -836,6 +840,7 @@ en:
   time:
     formats:
       default: "%b %d, %Y, %H:%M"
+      month: "%b %Y"
   two_factor_authentication:
     code_hint: Enter the code generated by your authenticator app to confirm
     description_html: If you enable <strong>two-factor authentication</strong>, logging in will require you to be in possession of your phone, which will generate tokens for you to enter.
diff --git a/config/locales/eo.yml b/config/locales/eo.yml
index 156088af9..72010a085 100644
--- a/config/locales/eo.yml
+++ b/config/locales/eo.yml
@@ -46,7 +46,6 @@ eo:
     people_who_follow: Sekvantoj de %{name}
     posts: Mesaĝoj
     posts_with_replies: Mesaĝoj kaj respondoj
-    remote_follow: Fore sekvi
     reserved_username: La uzantnomo estas rezervita
     roles:
       admin: Administranto
@@ -517,7 +516,6 @@ eo:
     unlocked_warning_title: Via konto ne estas ŝlosita
   generic:
     changes_saved_msg: Ŝanĝoj sukcese konservitaj!
-    powered_by: povigita de %{link}
     save_changes: Konservi ŝanĝojn
     validation_errors:
       one: Io mise okazis! Bonvolu konsulti la suban erar-raporton
@@ -553,8 +551,6 @@ eo:
       expires_at: Eksvalidiĝas je
       uses: Uzoj
     title: Inviti homojn
-  landing_strip_html: "<strong>%{name}</strong> estas uzanto en %{link_to_root_path}. Vi povas sekvi tiun aŭ interagi kun tiu, se vi havas konton ie ajn en la fediverse."
-  landing_strip_signup_html: Se vi ne havas, vi povas <a href="%{sign_up_path}">registriĝi ĉi tie</a>.
   lists:
     errors:
       limit: Vi atingis la maksimuman kvanton de listoj
@@ -723,7 +719,6 @@ eo:
       unlisted: Nelistigita
       unlisted_long: Ĉiuj povas vidi, sed nelistigita en publikaj tempolinioj
   stream_entries:
-    click_to_show: Alklaki por montri
     pinned: Alpinglita
     reblogged: diskonigita
     sensitive_content: Tikla enhavo
diff --git a/config/locales/es.yml b/config/locales/es.yml
index 3e22e2643..3aae7f934 100644
--- a/config/locales/es.yml
+++ b/config/locales/es.yml
@@ -45,7 +45,6 @@ es:
     people_who_follow: Usuarios que siguen a %{name}
     posts: Toots
     posts_with_replies: Toots con respuestas
-    remote_follow: Seguir
     reserved_username: El nombre de usuario está reservado
     roles:
       admin: Administrador
@@ -486,7 +485,6 @@ es:
     unlocked_warning_title: Tu cuenta no está bloqueada
   generic:
     changes_saved_msg: "¡Cambios guardados con éxito!"
-    powered_by: gracias a %{link}
     save_changes: Guardar cambios
     validation_errors:
       one: "¡Algo no está bien! Por favor, revisa el error"
@@ -521,8 +519,6 @@ es:
       expires_at: Expira
       uses: Usos
     title: Invitar a gente
-  landing_strip_html: "<strong>%{name}</strong> es un usuario en %{link_to_root_path}. Puedes seguirlo(a) o interactuar con el o ella si tienes una cuenta en cualquier parte del fediverse."
-  landing_strip_signup_html: Si no tienes una, puedes <a href="%{sign_up_path}">registrarte aquí</a>.
   lists:
     errors:
       limit: Has alcanzado la cantidad máxima de listas
@@ -688,7 +684,6 @@ es:
       unlisted: Público, pero no mostrar en la historia federada
       unlisted_long: Todos pueden ver, pero no está listado en las líneas de tiempo públicas
   stream_entries:
-    click_to_show: Click para mostrar
     pinned: Toot fijado
     reblogged: retooteado
     sensitive_content: Contenido sensible
diff --git a/config/locales/eu.yml b/config/locales/eu.yml
index e141f27ee..c11e05908 100644
--- a/config/locales/eu.yml
+++ b/config/locales/eu.yml
@@ -46,7 +46,6 @@ eu:
     people_who_follow: "%{name} jarraitzen dutenak"
     posts: Toot-ak
     posts_with_replies: Toot eta erantzunak
-    remote_follow: Jarraitu urrunetik
     reserved_username: Erabiltzaile-izena erreserbatuta dago
     roles:
       admin: Administratzailea
@@ -488,7 +487,6 @@ eu:
     unlocked_warning_title: Zure kontua ez dago giltzapetuta
   generic:
     changes_saved_msg: Aldaketak ongi gorde dira!
-    powered_by: "(e)k %{link} darabil"
     save_changes: Gorde aldaketak
     validation_errors:
       one: Zerbait ez dabil ongi! Egiaztatu beheko errorea mesedez
@@ -524,8 +522,6 @@ eu:
       expires_at: Iraungitzea
       uses: Erabilerak
     title: Gonbidatu jendea
-  landing_strip_html: "<strong>%{name}</strong> %{link_to_root_path} instantziako erabiltzailea da. Fedibertsoko edozein tokitan kontua baduzu jarraitu dezakezu eta harremanetan jarri."
-  landing_strip_signup_html: Ez baduzu, <a href="%{sign_up_path}">hemen izena eman</a> dezakezu.
   lists:
     errors:
       limit: Gehieneko zerrenda kopurura heldu zara
@@ -693,7 +689,6 @@ eu:
       unlisted: Zerrendatu gabea
       unlisted_long: Edonork ikusi dezake, baina ez da denbora-lerro publikoetan agertzen
   stream_entries:
-    click_to_show: Klik erakusteko
     pinned: Finkatutako toot-a
     reblogged: "(r)en bultzada"
     sensitive_content: Eduki hunkigarria
diff --git a/config/locales/fa.yml b/config/locales/fa.yml
index cfd4a9838..b4dc3fd8a 100644
--- a/config/locales/fa.yml
+++ b/config/locales/fa.yml
@@ -46,7 +46,6 @@ fa:
     people_who_follow: کسانی که %{name} را پی می‌گیرند
     posts: نوشته‌ها
     posts_with_replies: نوشته‌ها و پاسخ‌ها
-    remote_follow: پیگیری غیرمستقیم
     reserved_username: این نام کاربری در دسترس نیست
     roles:
       admin: مدیر
@@ -536,7 +535,6 @@ fa:
     unlocked_warning_title: حساب شما خصوصی نیست
   generic:
     changes_saved_msg: تغییرات با موفقیت ذخیره شدند!
-    powered_by: نیرو گرفته از %{link}
     save_changes: ذخیرهٔ تغییرات
     validation_errors:
       one: یک چیزی هنوز درست نیست! لطفاً خطاهای زیر را ببینید
@@ -572,8 +570,6 @@ fa:
       expires_at: تاریخ انقضا
       uses: استفاده‌ها
     title: دعوت دیگران
-  landing_strip_html: "<strong>%{name}</strong> کاربری روی %{link_to_root_path} است. شما با داشتن حساب روی هر سروری می‌توانید نوشته‌های او را پیگیری کرده یا با او ارتباط داشته باشید."
-  landing_strip_signup_html: اگر هنوز حسابی ندارید <a href="%{sign_up_path}">این‌جا حساب باز کنید</a>.
   lists:
     errors:
       limit: از این بیشتر نمی‌شود فهرست داشت
@@ -742,7 +738,6 @@ fa:
       unlisted: فهرست‌نشده
       unlisted_long: عمومی، ولی در فهرست نوشته‌ها نمایش نمی‌یابد
   stream_entries:
-    click_to_show: برای نمایش کلیک کنید
     pinned: نوشته‌های ثابت
     reblogged: بازبوقید
     sensitive_content: محتوای حساس
diff --git a/config/locales/fi.yml b/config/locales/fi.yml
index 6c9076919..2c534f071 100644
--- a/config/locales/fi.yml
+++ b/config/locales/fi.yml
@@ -46,7 +46,6 @@ fi:
     people_who_follow: Käyttäjän %{name} seuraajat
     posts: Tuuttaukset
     posts_with_replies: Tuuttaukset ja vastaukset
-    remote_follow: Etäseuranta
     reserved_username: Käyttäjänimi on varattu
     roles:
       admin: Ylläpitäjä
@@ -484,7 +483,6 @@ fi:
     unlocked_warning_title: Tiliäsi ei ole lukittu
   generic:
     changes_saved_msg: Muutosten tallennus onnistui!
-    powered_by: voimanlähteenä %{link}
     save_changes: Tallenna muutokset
     validation_errors:
       one: Kaikki ei ole aivan oikein! Tarkasta alla oleva virhe
@@ -519,8 +517,6 @@ fi:
       expires_at: Vanhenee
       uses: Käytetty
     title: Kutsu ihmisiä
-  landing_strip_html: "<strong>%{name}</strong> on käyttäjänä palvelimella %{link_to_root_path}. Voit seurata heitä tai pitää heihin yhteyttä, jos sinulla on tili missä tahansa fediversumin kolkassa."
-  landing_strip_signup_html: Jos sinulla ei ole tiliä, voit <a href="%{sign_up_path}">rekisteröityä tätä kautta</a>.
   lists:
     errors:
       limit: Sinulla on jo suurin sallittu määrä listoja
@@ -684,7 +680,6 @@ fi:
       unlisted: Listaamaton julkinen
       unlisted_long: Kaikki voivat nähdä, mutta ei näytetä julkisilla aikajanoilla
   stream_entries:
-    click_to_show: Katso napsauttamalla
     pinned: Kiinnitetty tuuttaus
     reblogged: buustasi
     sensitive_content: Arkaluontoista sisältöä
diff --git a/config/locales/fr.yml b/config/locales/fr.yml
index 07d900cfa..bc2c7b387 100644
--- a/config/locales/fr.yml
+++ b/config/locales/fr.yml
@@ -46,7 +46,6 @@ fr:
     people_who_follow: Personnes qui suivent %{name}
     posts: Statuts
     posts_with_replies: Statuts & réponses
-    remote_follow: Suivre à distance
     reserved_username: Ce nom d’utilisateur⋅ice est réservé
     roles:
       admin: Admin
@@ -488,7 +487,6 @@ fr:
     unlocked_warning_title: Votre compte n’est pas privé
   generic:
     changes_saved_msg: Les modifications ont été enregistrées avec succès !
-    powered_by: propulsé par %{link}
     save_changes: Enregistrer les modifications
     validation_errors:
       one: Quelque chose ne va pas ! Vérifiez l’erreur ci-dessous
@@ -523,8 +521,6 @@ fr:
       expires_at: Expire
       uses: Utilise
     title: Inviter des gens
-  landing_strip_html: <strong>%{name}</strong> utilise %{link_to_root_path}. Vous pouvez læ suivre et interagir si vous possédez un compte quelque part dans le "fediverse".
-  landing_strip_signup_html: Si ce n’est pas le cas, vous pouvez <a href="%{sign_up_path}">en créer un ici</a>.
   lists:
     errors:
       limit: Vous avez atteint le nombre maximum de listes
@@ -691,7 +687,6 @@ fr:
       unlisted: Public sans être affiché sur le fil public
       unlisted_long: Tout le monde peut voir vos statuts mais ils ne seront pas sur listés sur les fils publics
   stream_entries:
-    click_to_show: Cliquer pour afficher
     pinned: Pouet épinglé
     reblogged: a partagé
     sensitive_content: Contenu sensible
diff --git a/config/locales/gl.yml b/config/locales/gl.yml
index e7943c469..a5732168b 100644
--- a/config/locales/gl.yml
+++ b/config/locales/gl.yml
@@ -46,7 +46,6 @@ gl:
     people_who_follow: Personas que seguen a %{name}
     posts: Mensaxes
     posts_with_replies: Toots e respostas
-    remote_follow: Seguimento remoto
     reserved_username: O nome de usuaria está reservado
     roles:
       admin: Admin
@@ -535,7 +534,6 @@ gl:
     unlocked_warning_title: A súa conta non está pechada
   generic:
     changes_saved_msg: Cambios gardados correctamente!!
-    powered_by: grazas a %{link}
     save_changes: Gardar cambios
     validation_errors:
       one: Algo non está ben de todo! Por favor revise abaixo o erro
@@ -571,8 +569,6 @@ gl:
       expires_at: Caduca
       uses: Usos
     title: Convidar xente
-  landing_strip_html: "<strong>%{name}</strong> é unha usuaria en %{link_to_root_path}.  Pode seguila ou interactuar con ela si ten unha conta en algún lugar do fediverso."
-  landing_strip_signup_html: Si non, pode <a href="%{sign_up_path}">rexistrarse aquí</a>.
   lists:
     errors:
       limit: Acadou o número máximo de listas
@@ -741,7 +737,6 @@ gl:
       unlisted: Non listado
       unlisted_long: Visible para calquera, pero non listado en liñas de tempo públicas
   stream_entries:
-    click_to_show: Pulse para mostrar
     pinned: Mensaxe fixada
     reblogged: promovida
     sensitive_content: Contido sensible
diff --git a/config/locales/he.yml b/config/locales/he.yml
index c127db385..b03f184ca 100644
--- a/config/locales/he.yml
+++ b/config/locales/he.yml
@@ -44,7 +44,6 @@ he:
     people_who_follow: העוקבים של %{name}
     posts: הודעות
     posts_with_replies: חצרוצים ותגובות
-    remote_follow: מעקב מרחוק
     reserved_username: שם המשתמש שמור
     roles:
       admin: מנהל
@@ -286,7 +285,6 @@ he:
     unlocked_warning_title: חשבונך אינו נעול
   generic:
     changes_saved_msg: השינויים נשמרו בהצלחה!
-    powered_by: רץ על %{link}
     save_changes: שמור שינויים
     validation_errors:
       one: משהו לא לגמרי בסדר עדיין! אנא הציצו על השגיאה מטה
@@ -299,8 +297,6 @@ he:
       following: רשימת נעקבים
       muting: רשימת השתקות
     upload: יבוא
-  landing_strip_html: "<strong>%{name}</strong> מזהה משתמש(ת) מהקהילה %{link_to_root_path}. ניתן לעקוב אחריהם או לדבר איתם בעזרת חשבון על כל שרת קהילה ברחבי הפדרציה."
-  landing_strip_signup_html: לחלופין , ניתן <a href="%{sign_up_path}">להרשם מקומית כאן</a>.
   media_attachments:
     validations:
       images_and_video: לא ניתן להוסיף וידאו לחצרוץ שכבר מכיל תמונות
@@ -372,7 +368,6 @@ he:
       unlisted: מוסתר
       unlisted_long: פומבי, אבל לא להצגה בפיד הציבורי
   stream_entries:
-    click_to_show: ללחוץ להצגה
     reblogged: הודהד
     sensitive_content: תוכן רגיש
   time:
diff --git a/config/locales/hr.yml b/config/locales/hr.yml
index 2d2eddc08..07373d19d 100644
--- a/config/locales/hr.yml
+++ b/config/locales/hr.yml
@@ -22,7 +22,6 @@ hr:
     people_followed_by: Ljudi koje %{name} slijedi
     people_who_follow: Ljudi koji slijede %{name}
     posts: Postovi
-    remote_follow: Remote follow
     unfollow: Prestani slijediti
   application_mailer:
     settings: 'Promijeni e-mail postavke: %{link}'
@@ -64,7 +63,6 @@ hr:
     storage: Pohrana media zapisa
   generic:
     changes_saved_msg: Izmjene su uspješno sačuvane!
-    powered_by: omogućuje %{link}
     save_changes: Sačuvaj izmjene
     validation_errors:
       one: Nešto ne štima! Vidi grešku ispod
@@ -77,8 +75,6 @@ hr:
       following: Lista onih koje slijedim
       muting: Lista utišanih
     upload: Upload
-  landing_strip_html: "<strong>%{name}</strong> je korisnik na %{link_to_root_path}. Možeš ih slijediti ili komunicirati s njima ako imaš račun igdje u fediversu."
-  landing_strip_signup_html: Ako nemaš, možeš se <a href="%{sign_up_path}">registrirati ovdje</a>.
   notification_mailer:
     digest:
       body: 'Ovo je kratak sažetak propuštenog %{instance} od tvog prošlog posjeta %{since}:'
@@ -141,7 +137,6 @@ hr:
       public: Javno
       unlisted: Javno, no nemoj prikazati na javnom timelineu
   stream_entries:
-    click_to_show: Klikni da bi prikazao
     reblogged: potaknut
     sensitive_content: Osjetljivi sadržaj
   time:
diff --git a/config/locales/hu.yml b/config/locales/hu.yml
index 41093aa43..af10dfd80 100644
--- a/config/locales/hu.yml
+++ b/config/locales/hu.yml
@@ -44,7 +44,6 @@ hu:
     people_who_follow: "%{name} követői"
     posts: Tülkök
     posts_with_replies: Tülkök és válaszok
-    remote_follow: Követés más hálózaton
     reserved_username: Ez egy már lefoglalt felhasználónév
     roles:
       admin: Adminisztrátor
@@ -427,7 +426,6 @@ hu:
     unlocked_warning_title: A fiókod jelenleg nem privát
   generic:
     changes_saved_msg: Változások sikeresen elmentve!
-    powered_by: működteti a %{link}
     save_changes: Változások mentése
     validation_errors:
       one: Valami nincs rendjén! Kérlek tekintsd meg a hibát alant
@@ -461,8 +459,6 @@ hu:
       expires_at: Lejárat
       uses: Használat
     title: Meghívások
-  landing_strip_html: "<strong>%{name}</strong> az alábbi instancia használója: %{link_to_root_path}. Követheted vagy kapcsolatba léphetsz vele, ha már van felhasználói fiókod a föderációban."
-  landing_strip_signup_html: Ha még nincs fiókod, <a href="%{sign_up_path}">itt regisztrálhatsz</a>.
   lists:
     errors:
       limit: Elérted a hozzáadható listák maximális számát
@@ -610,7 +606,6 @@ hu:
       unlisted: Listázatlan
       unlisted_long: Mindenki látja, de a nyilvános időfolyamokban nem jelenik meg
   stream_entries:
-    click_to_show: Megtekintéshez kattints
     pinned: Kitűzött tülk
     reblogged: reblogolt
     sensitive_content: Szenzitív tartalom
diff --git a/config/locales/id.yml b/config/locales/id.yml
index 4fb75f2b0..c391a6b4e 100644
--- a/config/locales/id.yml
+++ b/config/locales/id.yml
@@ -22,7 +22,6 @@ id:
     people_followed_by: Orang yang diikuti %{name}
     people_who_follow: Orang-orang yang mengikuti %{name}
     posts: Postingan
-    remote_follow: Mengikuti
     unfollow: Berhenti mengikuti
   admin:
     accounts:
@@ -213,7 +212,6 @@ id:
     unlocked_warning_title: Akun anda tidak dikunci
   generic:
     changes_saved_msg: Perubahan berhasil disimpan!
-    powered_by: didukung oleh %{link}
     save_changes: Simpan perubahan
     validation_errors:
       one: Ada yang tidak beres! Mohon tinjau error dibawah ini
@@ -226,8 +224,6 @@ id:
       following: Daftar diikuti
       muting: Daftar didiamkan
     upload: Unggah
-  landing_strip_html: "<strong>%{name}</strong> adalah pengguna di %{link_to_root_path}.Anda dapat mengikuti mereka atau berinteraksi dengan mereka jika anda memiliki akun di fediverse."
-  landing_strip_signup_html: Jika anda tidak punya, anda bisa <a href="%{sign_up_path}">daftar disini</a>.
   media_attachments:
     validations:
       images_and_video: Tidak bisa melampirkan video pada status yang telah memiliki gambar
@@ -298,7 +294,6 @@ id:
       public_long: Bisa dilihat semua orang
       unlisted: Bisa dilihat semua orang, tapi tidak ditampilkan di linimasa publik
   stream_entries:
-    click_to_show: Klik untuk menampilkan
     reblogged: di-boost-kan
     sensitive_content: Konten sensitif
   time:
diff --git a/config/locales/io.yml b/config/locales/io.yml
index bf15de488..71a7f2d94 100644
--- a/config/locales/io.yml
+++ b/config/locales/io.yml
@@ -22,7 +22,6 @@ io:
     people_followed_by: Sequati da %{name}
     people_who_follow: Sequanti di %{name}
     posts: Mesaji
-    remote_follow: Fore sequar
     unfollow: Dessequar
   admin:
     accounts:
@@ -192,7 +191,6 @@ io:
     storage: Konservado di kontenajo
   generic:
     changes_saved_msg: Chanji senprobleme konservita!
-    powered_by: povigita da %{link}
     save_changes: Konservar la chanji
     validation_errors:
       one: Ulo ne eventis senprobleme! Voluntez konsultar la suba eror-raporto.
@@ -205,8 +203,6 @@ io:
       following: Listo de sequati
       muting: Muting list
     upload: Kargar
-  landing_strip_html: "<strong>%{name}</strong> esas uzero en %{link_to_root_path}. Tu povas sequar lu o komunikar kun lu, se tu havas konto irgaloke en la Fediverse."
-  landing_strip_signup_html: Se tu ne havas, tu povas <a href="%{sign_up_path}">membreskar hike</a>.
   media_attachments:
     validations:
       images_and_video: Cannot attach a video to a status that already contains images
@@ -274,7 +270,6 @@ io:
       public: Publika
       unlisted: Publika, ma ne aperos en publika tempolinei
   stream_entries:
-    click_to_show: Kliktar por montrar
     reblogged: diskonocigita
     sensitive_content: Titiliva kontenajo
   time:
diff --git a/config/locales/it.yml b/config/locales/it.yml
index 0110a488e..e985d1f10 100644
--- a/config/locales/it.yml
+++ b/config/locales/it.yml
@@ -46,7 +46,6 @@ it:
     people_who_follow: Persone che seguono %{name}
     posts: Posts
     posts_with_replies: Toot e risposte
-    remote_follow: Segui da remoto
     reserved_username: Il nome utente è riservato
     roles:
       admin: Amministratore
@@ -433,7 +432,6 @@ it:
     unlocked_warning_html: Chiunque può seguirti per vedere immediatamente i tuoi status privati. %{lock_link} per poter esaminare e respingere gli utenti che vogliono seguirti.
   generic:
     changes_saved_msg: Modifiche effettuate con successo!
-    powered_by: offerto da %{link}
     save_changes: Salva modifiche
     validation_errors:
       one: Qualcosa ancora non va bene! Per favore, controlla l'errore qui sotto
@@ -467,8 +465,6 @@ it:
       expires_at: Scade
       uses: Utilizzi
     title: Invita persone
-  landing_strip_html: "<strong>%{name}</strong> è un utente su %{link_to_root_path}. Puoi seguirlo o interagire con lui se possiedi un account ovunque nel fediverse."
-  landing_strip_signup_html: Se non possiedi un account, puoi <a href="%{sign_up_path}">iscriverti qui</a>.
   lists:
     errors:
       limit: Hai raggiunto il numero massimo di liste
@@ -605,7 +601,6 @@ it:
       unlisted: Pubblico, ma non visibile sulla timeline pubblica
       unlisted_long: Tutti lo possono vedere, ma non compare nelle timeline pubbliche
   stream_entries:
-    click_to_show: Clicca per mostrare
     pinned: Toot fissato in cima
     reblogged: condiviso
     sensitive_content: Materiale sensibile
diff --git a/config/locales/ja.yml b/config/locales/ja.yml
index 0e7258b4c..9c3ab5f73 100644
--- a/config/locales/ja.yml
+++ b/config/locales/ja.yml
@@ -46,7 +46,6 @@ ja:
     people_who_follow: "%{name} さんをフォロー中のアカウント"
     posts: トゥート
     posts_with_replies: トゥートと返信
-    remote_follow: リモートフォロー
     reserved_username: このユーザー名は予約されています
     roles:
       admin: Admin
@@ -535,7 +534,6 @@ ja:
     unlocked_warning_title: このアカウントは承認制アカウントに設定されていません
   generic:
     changes_saved_msg: 正常に変更されました!
-    powered_by: powered by %{link}
     save_changes: 変更を保存
     validation_errors:
       one: エラーが発生しました! 以下のエラーを確認してください
@@ -571,8 +569,6 @@ ja:
       expires_at: 有効期限
       uses: 使用
     title: 新規ユーザーの招待
-  landing_strip_html: "<strong>%{name}</strong> さんはインスタンス %{link_to_root_path} のユーザーです。アカウントさえ持っていればフォローしたり会話したりできます。"
-  landing_strip_signup_html: もしお持ちでないなら <a href="%{sign_up_path}">こちら</a> からサインアップできます。
   lists:
     errors:
       limit: リストの上限に達しました
@@ -741,7 +737,6 @@ ja:
       unlisted: 未収載
       unlisted_long: 誰でも見ることができますが、公開タイムラインには表示されません
   stream_entries:
-    click_to_show: クリックして表示
     pinned: 固定されたトゥート
     reblogged: さんがブースト
     sensitive_content: 閲覧注意
diff --git a/config/locales/ko.yml b/config/locales/ko.yml
index 9b742d18b..f5a780f6c 100644
--- a/config/locales/ko.yml
+++ b/config/locales/ko.yml
@@ -46,7 +46,6 @@ ko:
     people_who_follow: "%{name} 님을 팔로우 중인 계정"
     posts: 툿
     posts_with_replies: 툿과 답장
-    remote_follow: 리모트 팔로우
     reserved_username: 이 아이디는 예약되어 있습니다
     roles:
       admin: 관리자
@@ -509,7 +508,6 @@ ko:
     unlocked_warning_title: 이 계정은 비공개로 설정되어 있지 않습니다
   generic:
     changes_saved_msg: 정상적으로 변경되었습니다!
-    powered_by: "%{link}에 의해 제공"
     save_changes: 변경 사항을 저장
     validation_errors:
       one: 오류가 발생했습니다. 아래 오류를 확인해 주십시오
@@ -545,8 +543,6 @@ ko:
       expires_at: 만료
       uses: 사용됨
     title: 초대
-  landing_strip_html: "<strong>%{name}</strong> 님은 %{link_to_root_path} 인스턴스의 사용자입니다. 계정을 가지고 있다면 팔로우 하거나 대화할 수 있습니다."
-  landing_strip_signup_html: 아직 계정이 없다면 <a href="%{sign_up_path}">여기서</a> 등록할 수 있습니다.
   lists:
     errors:
       limit: 리스트 최대치에 도달했습니다
@@ -715,7 +711,6 @@ ko:
       unlisted: 공개 타임라인 비공개
       unlisted_long: 누구나 볼 수 있지만, 공개 타임라인에는 표시되지 않습니다
   stream_entries:
-    click_to_show: 클릭해서 표시
     pinned: 고정된 툿
     reblogged: 님이 부스트 했습니다
     sensitive_content: 민감한 컨텐츠
diff --git a/config/locales/nl.yml b/config/locales/nl.yml
index 0c45016a7..0001891b2 100644
--- a/config/locales/nl.yml
+++ b/config/locales/nl.yml
@@ -46,7 +46,6 @@ nl:
     people_who_follow: Mensen die %{name} volgen
     posts: Toots
     posts_with_replies: Toots en reacties
-    remote_follow: Extern volgen
     reserved_username: Deze gebruikersnaam is gereserveerd
     roles:
       admin: Beheerder
@@ -536,7 +535,6 @@ nl:
     unlocked_warning_title: Jouw account is niet besloten
   generic:
     changes_saved_msg: Wijzigingen succesvol opgeslagen!
-    powered_by: wordt mogelijk gemaakt door %{link}
     save_changes: Wijzigingen opslaan
     validation_errors:
       one: Er is iets niet helemaal goed! Bekijk onderstaande fout
@@ -572,8 +570,6 @@ nl:
       expires_at: Verloopt op
       uses: Aantal keer te gebruiken
     title: Mensen uitnodigen
-  landing_strip_html: "<strong>%{name}</strong> is een gebruiker op %{link_to_root_path}. Je kunt deze volgen en ermee communiceren als je op Mastodon (of ergens anders in de fediverse) een account hebt."
-  landing_strip_signup_html: Als je dat niet hebt, kun je je <a href="%{sign_up_path}">hier registreren</a>.
   lists:
     errors:
       limit: Je hebt het maximaal aantal lijsten bereikt
@@ -742,7 +738,6 @@ nl:
       unlisted: Minder openbaar
       unlisted_long: Aan iedereen tonen, maar niet op openbare tijdlijnen
   stream_entries:
-    click_to_show: Klik om te tonen
     pinned: Vastgemaakte toot
     reblogged: boostte
     sensitive_content: Gevoelige inhoud
diff --git a/config/locales/no.yml b/config/locales/no.yml
index eb1d27a19..c17ea3e86 100644
--- a/config/locales/no.yml
+++ b/config/locales/no.yml
@@ -44,7 +44,6 @@
     people_who_follow: Folk som følger %{name}
     posts: Poster
     posts_with_replies: Tuter med svar
-    remote_follow: Følg fra andre instanser
     reserved_username: Brukernavnet er reservert
     roles:
       admin: Admin
@@ -427,7 +426,6 @@
     unlocked_warning_title: Din konto er ikke låst
   generic:
     changes_saved_msg: Vellykket lagring av endringer!
-    powered_by: drevet av %{link}
     save_changes: Lagre endringer
     validation_errors:
       one: Noe er ikke helt riktig ennå. Vennligst se etter en gang til
@@ -461,8 +459,6 @@
       expires_at: Utløper
       uses: Bruk
     title: Inviter personer
-  landing_strip_html: "<strong>%{name}</strong> er en bruker på %{link_to_root_path}. Du kan følge dem eller kommunisere med dem hvis du har en konto hvor som helst i fediverset."
-  landing_strip_signup_html: Hvis du ikke har en konto så kan du <a href="%{sign_up_path}">registrere deg her</a>.
   lists:
     errors:
       limit: Du har nådd det maksimale antall lister
@@ -610,7 +606,6 @@
       unlisted: Uoppført
       unlisted_long: Synlig for alle, men ikke på offentlige tidslinjer
   stream_entries:
-    click_to_show: Klikk for å vise
     pinned: Festet tut
     reblogged: fremhevde
     sensitive_content: Følsomt innhold
diff --git a/config/locales/oc.yml b/config/locales/oc.yml
index 7146d9220..828ecfbf5 100644
--- a/config/locales/oc.yml
+++ b/config/locales/oc.yml
@@ -46,7 +46,6 @@ oc:
     people_who_follow: Lo monde que sègon %{name}
     posts: Tuts
     posts_with_replies: Tuts e responsas
-    remote_follow: Sègre a distància
     reserved_username: Aqueste nom d’utilizaire es reservat
     roles:
       admin: Admin
@@ -593,7 +592,6 @@ oc:
     unlocked_warning_title: Vòstre compte es pas clavat
   generic:
     changes_saved_msg: Cambiaments ben realizats !
-    powered_by: propulsat per %{link}
     save_changes: Salvar los cambiaments
     validation_errors:
       one: I a quicòm que truca ! Mercés de corregir l’error çai-jos
@@ -629,8 +627,6 @@ oc:
       expires_at: Expirats
       uses: Usatges
     title: Convidar de mond
-  landing_strip_html: "<strong>%{name}</strong> utiliza %{link_to_root_path}. Podètz lo/la sègre o interagir amb el o ela s’avètz un compte ont que siasque sul fediverse."
-  landing_strip_signup_html: S’es pas lo cas, podètz <a href="%{sign_up_path}">vos marcar aquí</a>.
   lists:
     errors:
       limit: Avètz atengut lo maximum de listas
@@ -799,7 +795,6 @@ oc:
       unlisted: Pas listat
       unlisted_long: Tot lo monde pòt veire mai serà pas visible sul flux public
   stream_entries:
-    click_to_show: Clicatz per veire
     pinned: Tut penjat
     reblogged: a partejat
     sensitive_content: Contengut sensible
diff --git a/config/locales/pl.yml b/config/locales/pl.yml
index f4d6f57af..c33078496 100644
--- a/config/locales/pl.yml
+++ b/config/locales/pl.yml
@@ -46,7 +46,6 @@ pl:
     people_who_follow: Osoby, które śledzą konto %{name}
     posts: Wpisy
     posts_with_replies: Wpisy z odpowiedziami
-    remote_follow: Śledź zdalnie
     reserved_username: Ta nazwa użytkownika jest zarezerwowana
     roles:
       admin: Administrator
@@ -537,7 +536,6 @@ pl:
     unlocked_warning_title: Twoje konto nie jest zablokowane
   generic:
     changes_saved_msg: Ustawienia zapisane!
-    powered_by: uruchomione na %{link}
     save_changes: Zapisz zmiany
     validation_errors:
       few: Coś jest wciąż nie tak! Przejrzyj %{count} poniższe błędy
@@ -577,8 +575,6 @@ pl:
       expires_at: Wygaśnie po
       uses: Użycia
     title: Zaproś użytkowników
-  landing_strip_html: "<strong>%{name}</strong> ma konto na %{link_to_root_path}. Możesz je śledzić i wejść z nim w interakcję jeśli masz konto gdziekolwiek w Fediwersum."
-  landing_strip_signup_html: Jeśli jeszcze go nie masz, możesz <a href="%{sign_up_path}">stworzyć konto</a>.
   lists:
     errors:
       limit: Przekroczyłeś maksymalną liczbę utworzonych list
@@ -755,7 +751,6 @@ pl:
       unlisted: Niewypisane
       unlisted_long: Widoczne dla wszystkich, ale nie wyświetlane na publicznych osiach czasu
   stream_entries:
-    click_to_show: Naciśnij aby wyświetlić
     pinned: Przypięty wpis
     reblogged: podbił
     sensitive_content: Wrażliwa zawartość
diff --git a/config/locales/pt-BR.yml b/config/locales/pt-BR.yml
index 2bff2b469..0c1cc6a6d 100644
--- a/config/locales/pt-BR.yml
+++ b/config/locales/pt-BR.yml
@@ -46,7 +46,6 @@ pt-BR:
     people_who_follow: Pessoas que seguem %{name}
     posts: Toots
     posts_with_replies: Toots e respostas
-    remote_follow: Siga remotamente
     reserved_username: Este usuário está reservado
     roles:
       admin: Administrador
@@ -536,7 +535,6 @@ pt-BR:
     unlocked_warning_title: A sua conta não está trancada
   generic:
     changes_saved_msg: Mudanças salvas com sucesso!
-    powered_by: graças a tecnologia de %{link}
     save_changes: Salvar mudanças
     validation_errors:
       one: Algo não está certo! Por favor, reveja o erro abaixo
@@ -572,8 +570,6 @@ pt-BR:
       expires_at: Expira em
       uses: Usos
     title: Convidar pessoas
-  landing_strip_html: "<strong>%{name}</strong> é um usuário no %{link_to_root_path}. Você pode segui-lo ou interagir com ele se você tiver uma conta em qualquer lugar no fediverso."
-  landing_strip_signup_html: Se não, você pode <a href="%{sign_up_path}">se cadastrar aqui</a>.
   lists:
     errors:
       limit: Você alcançou o número máximo de listas
@@ -742,7 +738,6 @@ pt-BR:
       unlisted: Não listado
       unlisted_long: Todos podem ver, porém não será postado nas timelines públicas
   stream_entries:
-    click_to_show: Clique para mostrar
     pinned: Toot fixado
     reblogged: compartilhou
     sensitive_content: Conteúdo sensível
diff --git a/config/locales/pt.yml b/config/locales/pt.yml
index 3a6f2c993..33b6b0acb 100644
--- a/config/locales/pt.yml
+++ b/config/locales/pt.yml
@@ -44,7 +44,6 @@ pt:
     people_who_follow: Pessoas que seguem %{name}
     posts: Posts
     posts_with_replies: Posts e Respostas
-    remote_follow: Seguir remotamente
     reserved_username: Este nome de utilizadores é reservado
     roles:
       admin: Administrador
@@ -430,7 +429,6 @@ pt:
     unlocked_warning_title: A tua conta não está bloqueada
   generic:
     changes_saved_msg: Alterações guardadas!
-    powered_by: fornecido por %{link}
     save_changes: Guardar alterações
     validation_errors:
       one: Algo não está correcto. Por favor vê o erro abaixo
@@ -464,8 +462,6 @@ pt:
       expires_at: Expira
       uses: Usos
     title: Convidar pessoas
-  landing_strip_html: "<strong>%{name}</strong> é um utilizador em %{link_to_root_path}. Podes segui-lo ou interagir com ele se tiveres uma conta em qualquer lugar no fediverso."
-  landing_strip_signup_html: If you don't, you can <a href="%{sign_up_path}">sign up here</a>.
   lists:
     errors:
       limit: Número máximo de listas alcançado
@@ -612,7 +608,6 @@ pt:
       unlisted: Público, mas não mostre no timeline público
       unlisted_long: Todos podem ver, porém não será postado nas timelines públicas
   stream_entries:
-    click_to_show: Clique pra mostrar
     pinned: Toot fixado
     reblogged: boosted
     sensitive_content: Conteúdo sensível
diff --git a/config/locales/ru.yml b/config/locales/ru.yml
index 89aefc1cd..5fc511d2e 100644
--- a/config/locales/ru.yml
+++ b/config/locales/ru.yml
@@ -46,7 +46,6 @@ ru:
     people_who_follow: Подписчики %{name}
     posts: Посты
     posts_with_replies: Посты с ответами
-    remote_follow: Подписаться на удаленном узле
     reserved_username: Имя пользователя зарезервировано
     roles:
       admin: Администратор
@@ -492,7 +491,6 @@ ru:
     unlocked_warning_title: Ваш аккаунт не закрыт для подписки
   generic:
     changes_saved_msg: Изменения успешно сохранены!
-    powered_by: работает на %{link}
     save_changes: Сохранить изменения
     validation_errors:
       few: Что-то здесь не так! Пожалуйста, прочитайте о %{count} ошибках ниже
@@ -531,8 +529,6 @@ ru:
       expires_at: Истекает
       uses: Исп.
     title: Пригласить людей
-  landing_strip_html: "<strong>%{name}</strong> - пользователь на %{link_to_root_path}. Вы можете подписаться на него/нее и общаться с ним/ней, если у Вас есть аккаунт на любом узле общей сети."
-  landing_strip_signup_html: Если у Вас его нет, вы можете <a href="%{sign_up_path}">зарегистрироваться здесь</a>.
   lists:
     errors:
       limit: Вы достигли максимального числа списков
@@ -709,7 +705,6 @@ ru:
       unlisted: Скрывать из лент
       unlisted_long: Показывать всем, но не отображать в публичных лентах
   stream_entries:
-    click_to_show: Показать
     pinned: Закреплённое сообщение
     reblogged: продвинул(а)
     sensitive_content: Чувствительный контент
diff --git a/config/locales/sk.yml b/config/locales/sk.yml
index 9e2a8fd0c..0c86f5aa0 100644
--- a/config/locales/sk.yml
+++ b/config/locales/sk.yml
@@ -46,7 +46,6 @@ sk:
     people_who_follow: Ľudia sledujúci %{name}
     posts: Príspevky
     posts_with_replies: Príspevky s odpoveďami
-    remote_follow: Sleduj vzdialeného
     reserved_username: Prihlasovacie meno je rezervované
     roles:
       admin: Administrátor
@@ -526,7 +525,6 @@ sk:
     unlocked_warning_title: Tvoj účet nieje zamknutý
   generic:
     changes_saved_msg: Zmeny boli úspešne uložené!
-    powered_by: poháňané vďaka %{link}
     save_changes: Uložiť zmeny
     validation_errors:
       few: Niečo ešte stále nieje v poriadku! Prosím skontroluj všetky %{count} chyby
@@ -564,8 +562,6 @@ sk:
       expires_at: Vyprší
       uses: Používa
     title: Pozvi ľudí
-  landing_strip_html: "<strong>%{name}</strong> je užívateľ na serveri %{link_to_root_path}. Ty ich môžeš následovať a môžeš s nimi interaktovať pokiaľ máš účet kdekoľvek v rámci fediversa."
-  landing_strip_signup_html: Pokiaľ ešte nemáš, môžeš <a href="%{sign_up_path}">si tu vytvoriť účet</a>.
   lists:
     errors:
       limit: Dosiahli ste maximálny možný počet zoznamov
@@ -725,7 +721,6 @@ sk:
       unlisted: Nezaradené
       unlisted_long: Všetci môžu vidieť, ale nieje zaradené do verejnej osi
   stream_entries:
-    click_to_show: Klikni pre zobrazenie
     pinned: Pripnutý toot
     reblogged: vyzdvihnutý
     sensitive_content: Senzitívny obsah
diff --git a/config/locales/sl.yml b/config/locales/sl.yml
index 6f581f838..16ace08d3 100644
--- a/config/locales/sl.yml
+++ b/config/locales/sl.yml
@@ -42,7 +42,6 @@ sl:
     people_who_follow: Ljudje, ki sledijo %{name}
     posts: Tuti
     posts_with_replies: Tuti in odgovori
-    remote_follow: Oddaljeno sledenje
     reserved_username: Uporabniško ime je zasedeno
     roles:
       admin: Skrbnik
diff --git a/config/locales/sr-Latn.yml b/config/locales/sr-Latn.yml
index 15c6b00ac..d7dd574c7 100644
--- a/config/locales/sr-Latn.yml
+++ b/config/locales/sr-Latn.yml
@@ -44,7 +44,6 @@ sr-Latn:
     people_who_follow: Ljudi koji prate %{name}
     posts: Tutovi
     posts_with_replies: Tutovi i odgovori
-    remote_follow: Udaljena praćenja
     reserved_username: Korisničko ime je rezervisano
     roles:
       admin: Administrator
@@ -422,7 +421,6 @@ sr-Latn:
     unlocked_warning_title: Vaš nalog nije zaključan
   generic:
     changes_saved_msg: Izmene uspešno sačuvane!
-    powered_by: omogućio %{link}
     save_changes: Snimi izmene
     validation_errors:
       few: Nešto nije baš kako treba! Pregledajte %{count} greške ispod
@@ -460,8 +458,6 @@ sr-Latn:
       expires_at: Ističe
       uses: Korišćenja
     title: Pozovi ljude
-  landing_strip_html: "<strong>%{name}</strong> je korisnik na %{link_to_root_path}. Možete ga zapratiti ili komunicirati sa njim ako imte nalog bilo gde u fediversu."
-  landing_strip_signup_html: Ako nemate, možete se <a href="%{sign_up_path}">registrovati ovde</a>.
   lists:
     errors:
       limit: Dostigli ste limit broja listi
@@ -602,7 +598,6 @@ sr-Latn:
       unlisted: Neizlistano
       unlisted_long: Svako može da vidi, ali nije izlistano na javnim lajnama
   stream_entries:
-    click_to_show: Klikni da vidiš
     pinned: Prikačeni tut
     reblogged: podržano
     sensitive_content: Osetljiv sadržaj
diff --git a/config/locales/sr.yml b/config/locales/sr.yml
index 040090932..63c42f62f 100644
--- a/config/locales/sr.yml
+++ b/config/locales/sr.yml
@@ -45,7 +45,6 @@ sr:
     people_who_follow: Људи који прате %{name}
     posts: Тутови
     posts_with_replies: Тутови и одговори
-    remote_follow: Удаљена праћења
     reserved_username: Корисничко име је резервисано
     roles:
       admin: Администратор
@@ -423,7 +422,6 @@ sr:
     unlocked_warning_title: Ваш налог није закључан
   generic:
     changes_saved_msg: Измене успешно сачуване!
-    powered_by: омогућио %{link}
     save_changes: Сними измене
     validation_errors:
       few: Нешто није баш како треба! Прегледајте %{count} грешке испод
@@ -461,8 +459,6 @@ sr:
       expires_at: Истиче
       uses: Коришћења
     title: Позови људе
-  landing_strip_html: "<strong>%{name}</strong> је корисник на %{link_to_root_path}. Можете га запратити или комуницирати са њим ако имте налог било где у федиверсу."
-  landing_strip_signup_html: Ако немате, можете се <a href="%{sign_up_path}">регистровати овде</a>.
   lists:
     errors:
       limit: Достигли сте лимит броја листи
@@ -603,7 +599,6 @@ sr:
       unlisted: Неизлистано
       unlisted_long: Свако може да види, али није излистано на јавним лајнама
   stream_entries:
-    click_to_show: Кликни да видиш
     pinned: Прикачени тут
     reblogged: подржано
     sensitive_content: Осетљив садржај
diff --git a/config/locales/sv.yml b/config/locales/sv.yml
index 76b26c24f..cf1ab582f 100644
--- a/config/locales/sv.yml
+++ b/config/locales/sv.yml
@@ -46,7 +46,6 @@ sv:
     people_who_follow: Personer som följer %{name}
     posts: Toots
     posts_with_replies: Toots med svar
-    remote_follow: Avlägsen följare
     reserved_username: Användarnamnet är reserverat
     roles:
       admin: Admin
@@ -488,7 +487,6 @@ sv:
     unlocked_warning_title: Ditt konto är inte låst
   generic:
     changes_saved_msg: Ändringar sparades framgångsrikt!
-    powered_by: drivs av %{link}
     save_changes: Spara ändringar
     validation_errors:
       one: Något är inte riktigt rätt ännu! Kontrollera felet nedan
@@ -524,8 +522,6 @@ sv:
       expires_at: Utgår
       uses: Användningar
     title: Bjud in andra
-  landing_strip_html: "<strong>%{name}</strong> är en användare på %{link_to_root_path}. Du kan följa dem eller interagera med dem om du har ett konto någonstans i federationen."
-  landing_strip_signup_html: Om du inte gör det, så kan du <a href="%{sign_up_path}">registrera dig här</a>.
   lists:
     errors:
       limit: Du har nått det maximala antalet listor
@@ -693,7 +689,6 @@ sv:
       unlisted: Olistade
       unlisted_long: Alla kan se, men listas inte på offentliga tidslinjer
   stream_entries:
-    click_to_show: Klicka för att visa
     pinned: Fäst toot
     reblogged: boostad
     sensitive_content: Känsligt innehåll
diff --git a/config/locales/th.yml b/config/locales/th.yml
index 6804dbd13..182bde388 100644
--- a/config/locales/th.yml
+++ b/config/locales/th.yml
@@ -22,7 +22,6 @@ th:
     people_followed_by: ถูกติดตามโดย %{name}
     people_who_follow: คนที่ติดตาม %{name}
     posts: โพสต์
-    remote_follow: Remote follow
     unfollow: เลิกติดตาม
   admin:
     accounts:
@@ -216,7 +215,6 @@ th:
     unlocked_warning_title: แอคเค๊าท์ของคุณไม่ได้ล๊อค
   generic:
     changes_saved_msg: บันทึกการแก้ไขแล้ว!
-    powered_by: powered by %{link}
     save_changes: บันทึกการเปลี่ยนแปลง
     validation_errors:
       one: Something isn't quite right yet! Please review the error below
@@ -229,8 +227,6 @@ th:
       following: Following list
       muting: Muting list
     upload: Upload
-  landing_strip_html: "<strong>%{name}</strong> is a user on %{link_to_root_path}. You can follow them or interact with them if you have an account anywhere in the fediverse."
-  landing_strip_signup_html: If you don't, you can <a href="%{sign_up_path}">sign up here</a>.
   media_attachments:
     validations:
       images_and_video: Cannot attach a video to a status that already contains images
@@ -302,7 +298,6 @@ th:
       unlisted: Unlisted
       unlisted_long: Everyone can see, but not listed on public timelines
   stream_entries:
-    click_to_show: คลิกเพื่อแสดง
     reblogged: boosted
     sensitive_content: Sensitive content
   time:
diff --git a/config/locales/tr.yml b/config/locales/tr.yml
index 8bafbface..3609261ed 100644
--- a/config/locales/tr.yml
+++ b/config/locales/tr.yml
@@ -22,7 +22,6 @@ tr:
     people_followed_by: Kullanıcı %{name}'in takip ettikleri
     people_who_follow: Kullanıcı %{name}'i takip edenler
     posts: Gönderiler
-    remote_follow: Uzaktan takip et
     unfollow: Takibi bırak
   admin:
     accounts:
@@ -214,7 +213,6 @@ tr:
     unlocked_warning_title: Hesabınız kilitlendi
   generic:
     changes_saved_msg: Değişiklikler başarıyla kaydedildi!
-    powered_by: powered by %{link}
     save_changes: Değişiklikleri kaydet
     validation_errors:
       one: Bir şeyler ters gitti! Lütfen aşağıdaki hatayı gözden geçiriniz
@@ -227,8 +225,6 @@ tr:
       following: Takip edilenler listesi
       muting: Susturulanlar listesi
     upload: Yükle
-  landing_strip_html: "<strong>%{name}</strong>, %{link_to_root_path} sunucusundaki bir kullanıcıdır. Onu takip edebilir, veya Mastodon ağındaki bir hesabınızı kullanarak etkileşime geçebilirsiniz."
-  landing_strip_signup_html: Eğer hesabınız yoksa <a href="%{sign_up_path}">buradan kaydolabilirsiniz</a>.
   media_attachments:
     validations:
       images_and_video: Halihazırda görsel içeren bir gönderiye video ekleyemezsiniz.
@@ -300,7 +296,6 @@ tr:
       unlisted: Listelenmemiş
       unlisted_long: Herkes görebilir fakat herkese açık zaman tünellerinde listelenmez.
   stream_entries:
-    click_to_show: Görüntülemek için tıklayınız
     reblogged: boost edildi
     sensitive_content: Hassas içerik
   time:
diff --git a/config/locales/uk.yml b/config/locales/uk.yml
index 6fe46b4d9..5e75cbf72 100644
--- a/config/locales/uk.yml
+++ b/config/locales/uk.yml
@@ -22,7 +22,6 @@ uk:
     people_followed_by: Люди, на яких підписаний(-а) %{name}
     people_who_follow: Підписники %{name}
     posts: Пости
-    remote_follow: Підписатися на іншій інстанції
     unfollow: Відписатися
   admin:
     accounts:
@@ -199,7 +198,6 @@ uk:
     unlocked_warning_title: Ваш аккаунт не закритий для підписки
   generic:
     changes_saved_msg: Зміни успішно збережені!
-    powered_by: працює на %{link}
     save_changes: Зберегти зміни
     validation_errors:
       one: Щось тут не так! Будь ласка, ознайомтеся з помилкою нижче
@@ -212,8 +210,6 @@ uk:
       following: Підписки
       muting: Список глушення
     upload: Завантажити
-  landing_strip_html: "<strong>%{name}</strong> - користувач на %{link_to_root_path}. Ви можете підписатися на нього/неї та спілкуватися з ним/нею, якщо у Вас є акаунт на будь-якій інстанції загальної мережі."
-  landing_strip_signup_html: Якщо його у Вас немає, Ви можете <a href="%{sign_up_path}">зареєструватися тут</a>.
   media_attachments:
     validations:
       images_and_video: Не можна додати відео до статусу з зображеннями
@@ -289,7 +285,6 @@ uk:
       unlisted: Приховувати зі стріок
       unlisted_long: Показувати всім, але не відображати в публічних стрічках
   stream_entries:
-    click_to_show: Показати
     reblogged: передмухнув(-ла)
     sensitive_content: Непристойний контент
   time:
diff --git a/config/locales/zh-CN.yml b/config/locales/zh-CN.yml
index 1b741a7d6..6e64aff5a 100644
--- a/config/locales/zh-CN.yml
+++ b/config/locales/zh-CN.yml
@@ -46,7 +46,6 @@ zh-CN:
     people_who_follow: 关注 %{name} 的人
     posts: 嘟文
     posts_with_replies: 嘟文和回复
-    remote_follow: 跨站关注
     reserved_username: 此用户名已被保留
     roles:
       admin: 管理员
@@ -484,7 +483,6 @@ zh-CN:
     unlocked_warning_title: 你的帐户未受到保护
   generic:
     changes_saved_msg: 更改保存成功!
-    powered_by: 基于 %{link} 构建
     save_changes: 保存更改
     validation_errors:
       one: 出错啦!检查一下下面出错的地方吧
@@ -518,8 +516,6 @@ zh-CN:
       expires_at: 失效时间
       uses: 已使用次数
     title: 邀请用户
-  landing_strip_html: "<strong>%{name}</strong> 是一位来自 %{link_to_root_path} 的用户。如果你想关注他们或者与他们互动,你需要在任意一个 Mastodon 实例或与其兼容的网站上拥有一个帐户。"
-  landing_strip_signup_html: 还没有这种帐户?你可以<a href="%{sign_up_path}">在本站注册一个</a>。
   lists:
     errors:
       limit: 你所建立的列表数量已经达到上限
@@ -681,7 +677,6 @@ zh-CN:
       unlisted: 不公开
       unlisted_long: 所有人可见,但不会出现在公共时间轴上
   stream_entries:
-    click_to_show: 点击显示
     pinned: 置顶嘟文
     reblogged: 转嘟
     sensitive_content: 敏感内容
diff --git a/config/locales/zh-HK.yml b/config/locales/zh-HK.yml
index a5e997536..7ff0d7ae6 100644
--- a/config/locales/zh-HK.yml
+++ b/config/locales/zh-HK.yml
@@ -46,7 +46,6 @@ zh-HK:
     people_who_follow: 關注 %{name} 的人
     posts: 文章
     posts_with_replies: 文章和回覆
-    remote_follow: 跨站關注
     reserved_username: 此用戶名已被保留
     roles:
       admin: 管理員
@@ -488,7 +487,6 @@ zh-HK:
     unlocked_warning_title: 你的用戶目前為「公共」
   generic:
     changes_saved_msg: 已成功儲存修改。
-    powered_by: 網站由 %{link} 開發
     save_changes: 儲存修改
     validation_errors:
       one: 提交的資料有問題
@@ -524,8 +522,6 @@ zh-HK:
       expires_at: 失效時間
       uses: 已使用次數
     title: 邀請用戶
-  landing_strip_html: "<strong>%{name}</strong> 是一個在 %{link_to_root_path} 的用戶。只要你有任何 Mastodon 服務站、或者聯盟網站的用戶,便可以跨站關注此站用戶,或者與他們互動。"
-  landing_strip_signup_html: 如果你沒有這類用戶,歡迎在<a href="%{sign_up_path}">此處登記</a>。
   lists:
     errors:
       limit: 你所建立的列表數量已經達到上限
@@ -692,7 +688,6 @@ zh-HK:
       unlisted: 公開,但不在公共時間軸顯示
       unlisted_long: 所有人都能看到,但不在公共時間軸(本站時間軸、跨站時間軸)顯示
   stream_entries:
-    click_to_show: 點擊顯示
     pinned: 置頂文章
     reblogged: 轉推
     sensitive_content: 敏感內容
diff --git a/config/locales/zh-TW.yml b/config/locales/zh-TW.yml
index e2b376a3f..483cffe8e 100644
--- a/config/locales/zh-TW.yml
+++ b/config/locales/zh-TW.yml
@@ -46,7 +46,6 @@ zh-TW:
     people_who_follow: 關注 %{name} 的人
     posts: 嘟文
     posts_with_replies: 嘟文與回覆
-    remote_follow: 跨站關注
     reserved_username: 此用戶名已被保留
     roles:
       admin: 管理員
@@ -488,7 +487,6 @@ zh-TW:
     unlocked_warning_title: 你的帳戶是公開的
   generic:
     changes_saved_msg: 已成功儲存修改!
-    powered_by: 網站由 %{link} 開發
     save_changes: 儲存修改
     validation_errors:
       one: 送出的資料有問題
@@ -524,8 +522,6 @@ zh-TW:
       expires_at: 失效時間
       uses: 已使用次數
     title: 邀請使用者
-  landing_strip_html: "<strong>%{name}</strong> 是一個在 %{link_to_root_path} 的使用者。只要您有任何 Mastodon 站點、或者聯盟站點的帳戶,便可以跨站關注此站使用者,或者與他們互動。"
-  landing_strip_signup_html: 如果您沒有這些帳戶,歡迎在<a href="%{sign_up_path}">這裡註冊</a>。
   lists:
     errors:
       limit: 你所建立的列表數量已經達到上限
@@ -685,7 +681,6 @@ zh-TW:
       unlisted: 公開,但不在公共時間軸顯示
       unlisted_long: 所有人都能看到,但不會出現在公共時間軸上
   stream_entries:
-    click_to_show: 點選顯示
     pinned: 置頂嘟文
     reblogged: 轉嘟
     sensitive_content: 敏感內容
diff --git a/lib/mastodon/version.rb b/lib/mastodon/version.rb
index 04894d34d..093485111 100644
--- a/lib/mastodon/version.rb
+++ b/lib/mastodon/version.rb
@@ -32,8 +32,12 @@ module Mastodon
       [to_a.join('.'), flags].join
     end
 
+    def repository
+      'tootsuite/mastodon'
+    end
+
     def source_base_url
-      'https://github.com/tootsuite/mastodon'
+      "https://github.com/#{repository}"
     end
 
     # specify git tag or commit hash here
diff --git a/package.json b/package.json
index b0cdf562d..b4d81d603 100644
--- a/package.json
+++ b/package.json
@@ -105,6 +105,7 @@
     "redux": "^3.7.1",
     "redux-immutable": "^4.0.0",
     "redux-thunk": "^2.2.0",
+    "rellax": "^1.6.2",
     "requestidlecallback": "^0.3.0",
     "reselect": "^3.0.1",
     "rimraf": "^2.6.1",
diff --git a/spec/views/stream_entries/show.html.haml_spec.rb b/spec/views/stream_entries/show.html.haml_spec.rb
index e0681b125..34207aa6b 100644
--- a/spec/views/stream_entries/show.html.haml_spec.rb
+++ b/spec/views/stream_entries/show.html.haml_spec.rb
@@ -12,6 +12,7 @@ describe 'stream_entries/show.html.haml', without_verify_partial_doubles: true d
     allow(view).to receive(:full_asset_url).and_return('//asset.host/image.svg')
     allow(view).to receive(:local_time)
     allow(view).to receive(:local_time_ago)
+    assign(:instance_presenter, InstancePresenter.new)
   end
 
   it 'has valid author h-card and basic data for a detailed_status' do
diff --git a/yarn.lock b/yarn.lock
index 2c257ff0a..e558ea664 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -7188,6 +7188,10 @@ regjsparser@^0.1.4:
   dependencies:
     jsesc "~0.5.0"
 
+rellax@^1.6.2:
+  version "1.6.2"
+  resolved "https://registry.yarnpkg.com/rellax/-/rellax-1.6.2.tgz#b22c8715f56324fa8b396465d3dca9953b711f30"
+
 remove-trailing-separator@^1.0.1:
   version "1.1.0"
   resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef"