diff --git a/app/controllers/api/v1/accounts/follower_accounts_controller.rb b/app/controllers/api/v1/accounts/follower_accounts_controller.rb
index c4f600c54a29be0e7d49594a10fe75449cb9774f..4578cf6ca679b1ac9cc031b06db7385b2f68ed05 100644
--- a/app/controllers/api/v1/accounts/follower_accounts_controller.rb
+++ b/app/controllers/api/v1/accounts/follower_accounts_controller.rb
@@ -19,6 +19,8 @@ class Api::V1::Accounts::FollowerAccountsController < Api::BaseController
   end
 
   def load_accounts
+    return [] if @account.user_hides_network? && current_account.id != @account.id
+
     default_accounts.merge(paginated_follows).to_a
   end
 
diff --git a/app/controllers/api/v1/accounts/following_accounts_controller.rb b/app/controllers/api/v1/accounts/following_accounts_controller.rb
index 90b1f7fc51da6bc2e5ff18547662aa8f7612a07b..ce2bbda855990c939a9290a171f21d6850aa55ca 100644
--- a/app/controllers/api/v1/accounts/following_accounts_controller.rb
+++ b/app/controllers/api/v1/accounts/following_accounts_controller.rb
@@ -19,6 +19,8 @@ class Api::V1::Accounts::FollowingAccountsController < Api::BaseController
   end
 
   def load_accounts
+    return [] if @account.user_hides_network? && current_account.id != @account.id
+
     default_accounts.merge(paginated_follows).to_a
   end
 
diff --git a/app/controllers/follower_accounts_controller.rb b/app/controllers/follower_accounts_controller.rb
index ac0d4c54efe1c46f3166ad2461ee7cd96027697f..99cb3676f1e30dec6bef4508f430e3315d742d96 100644
--- a/app/controllers/follower_accounts_controller.rb
+++ b/app/controllers/follower_accounts_controller.rb
@@ -6,11 +6,15 @@ class FollowerAccountsController < ApplicationController
   def index
     respond_to do |format|
       format.html do
+        next if @account.user_hides_network?
+
         follows
         @relationships = AccountRelationshipsPresenter.new(follows.map(&:account_id), current_user.account_id) if user_signed_in?
       end
 
       format.json do
+        raise Mastodon::NotPermittedError if params[:page].present? && @account.user_hides_network?
+
         render json: collection_presenter,
                serializer: ActivityPub::CollectionSerializer,
                adapter: ActivityPub::Adapter,
diff --git a/app/controllers/following_accounts_controller.rb b/app/controllers/following_accounts_controller.rb
index 974d95c8e402397bc28a1b8bcaa4eec48a6ed8b8..03c4b10469b0ba6b3075085b67b6f199ba9fd88f 100644
--- a/app/controllers/following_accounts_controller.rb
+++ b/app/controllers/following_accounts_controller.rb
@@ -6,11 +6,15 @@ class FollowingAccountsController < ApplicationController
   def index
     respond_to do |format|
       format.html do
+        next if @account.user_hides_network?
+
         follows
         @relationships = AccountRelationshipsPresenter.new(follows.map(&:target_account_id), current_user.account_id) if user_signed_in?
       end
 
       format.json do
+        raise Mastodon::NotPermittedError if params[:page].present? && @account.user_hides_network?
+
         render json: collection_presenter,
                serializer: ActivityPub::CollectionSerializer,
                adapter: ActivityPub::Adapter,
diff --git a/app/controllers/settings/preferences_controller.rb b/app/controllers/settings/preferences_controller.rb
index 8397631388da12e2808fe17cf0aa9cc25f5acd6f..57793d776142d1b89928e9f7f5db3d8108cba5ec 100644
--- a/app/controllers/settings/preferences_controller.rb
+++ b/app/controllers/settings/preferences_controller.rb
@@ -44,6 +44,7 @@ class Settings::PreferencesController < ApplicationController
       :setting_system_font_ui,
       :setting_noindex,
       :setting_theme,
+      :setting_hide_network,
       notification_emails: %i(follow follow_request reblog favourite mention digest),
       interactions: %i(must_be_follower must_be_following)
     )
diff --git a/app/javascript/styles/mastodon/accounts.scss b/app/javascript/styles/mastodon/accounts.scss
index b063ca52dd75abdc4bd8cc73de6709e95a5b2059..93aa134cf4a09cfa0e0cc8e7cf602223bde5ff4e 100644
--- a/app/javascript/styles/mastodon/accounts.scss
+++ b/app/javascript/styles/mastodon/accounts.scss
@@ -322,6 +322,15 @@
   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;
@@ -438,8 +447,8 @@
   font-size: 14px;
   font-weight: 500;
   text-align: center;
-  padding: 60px 0;
-  padding-top: 55px;
+  padding: 130px 0;
+  padding-top: 125px;
   margin: 0 auto;
   cursor: default;
 }
diff --git a/app/javascript/styles/mastodon/footer.scss b/app/javascript/styles/mastodon/footer.scss
index ba2a06954ec21a7ed0e8449404bef109b803a0bd..dd3c1b688414678d5967a19c6887cc12d5b5b67c 100644
--- a/app/javascript/styles/mastodon/footer.scss
+++ b/app/javascript/styles/mastodon/footer.scss
@@ -4,7 +4,7 @@
   font-size: 12px;
   color: $darker-text-color;
 
-  .domain {
+  .footer__domain {
     font-weight: 500;
 
     a {
diff --git a/app/lib/user_settings_decorator.rb b/app/lib/user_settings_decorator.rb
index 9260a81bc21084a19cbe53c22b718d6eacc99f2c..a82f8974b7d34b3777daeb106da02b17d400f8ca 100644
--- a/app/lib/user_settings_decorator.rb
+++ b/app/lib/user_settings_decorator.rb
@@ -28,6 +28,7 @@ class UserSettingsDecorator
     user.settings['system_font_ui']          = system_font_ui_preference if change?('setting_system_font_ui')
     user.settings['noindex']                 = noindex_preference if change?('setting_noindex')
     user.settings['theme']                   = theme_preference if change?('setting_theme')
+    user.settings['hide_network']            = hide_network_preference if change?('setting_hide_network')
   end
 
   def merged_notification_emails
@@ -78,6 +79,10 @@ class UserSettingsDecorator
     boolean_cast_setting 'setting_noindex'
   end
 
+  def hide_network_preference
+    boolean_cast_setting 'setting_hide_network'
+  end
+
   def theme_preference
     settings['setting_theme']
   end
diff --git a/app/models/account.rb b/app/models/account.rb
index 2b3ef5cdc11bb26db1e644020e1d769cf9260968..72e850aa75f49723142885192648e3ec340819b5 100644
--- a/app/models/account.rb
+++ b/app/models/account.rb
@@ -136,6 +136,7 @@ class Account < ApplicationRecord
            :moderator?,
            :staff?,
            :locale,
+           :hides_network?,
            to: :user,
            prefix: true,
            allow_nil: true
diff --git a/app/models/user.rb b/app/models/user.rb
index 21c217e77d315095e81a2d83203a19ea0996e8d0..cfbae58ed32514729f78413734dbee73c6253578 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -86,7 +86,7 @@ class User < ApplicationRecord
   has_many :session_activations, dependent: :destroy
 
   delegate :auto_play_gif, :default_sensitive, :unfollow_modal, :boost_modal, :delete_modal,
-           :reduce_motion, :system_font_ui, :noindex, :theme, :display_sensitive_media,
+           :reduce_motion, :system_font_ui, :noindex, :theme, :display_sensitive_media, :hide_network,
            to: :settings, prefix: :setting, allow_nil: false
 
   attr_accessor :invite_code
@@ -219,6 +219,10 @@ class User < ApplicationRecord
     settings.notification_emails['digest']
   end
 
+  def hides_network?
+    @hides_network ||= settings.hide_network
+  end
+
   def token_for_app(a)
     return nil if a.nil? || a.owner != self
     Doorkeeper::AccessToken
diff --git a/app/views/accounts/_follow_grid.html.haml b/app/views/accounts/_follow_grid.html.haml
index a6d0ee8176d6a1df3aa66afe7f06b62d203e0028..fdcef84be2c57e1e6312db1eba77f593b4fe1d6e 100644
--- a/app/views/accounts/_follow_grid.html.haml
+++ b/app/views/accounts/_follow_grid.html.haml
@@ -1,5 +1,6 @@
-.accounts-grid
+.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?
diff --git a/app/views/accounts/_follow_grid_hidden.html.haml b/app/views/accounts/_follow_grid_hidden.html.haml
new file mode 100644
index 0000000000000000000000000000000000000000..e970350e639e10c3293c2c78e910fbd980a8fc30
--- /dev/null
+++ b/app/views/accounts/_follow_grid_hidden.html.haml
@@ -0,0 +1,3 @@
+.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/follower_accounts/index.html.haml b/app/views/follower_accounts/index.html.haml
index a24e4ea20fb5150ab574d27c1f7c38e16eb2b117..65af81a5b70276f01edb6e8a182f4d467c1d7c7e 100644
--- a/app/views/follower_accounts/index.html.haml
+++ b/app/views/follower_accounts/index.html.haml
@@ -7,4 +7,7 @@
 
 = render 'accounts/header', account: @account
 
-= render 'accounts/follow_grid', follows: @follows, accounts: @follows.map(&:account)
+- if @account.user_hides_network?
+  = render 'accounts/follow_grid_hidden'
+- else
+  = render 'accounts/follow_grid', follows: @follows, accounts: @follows.map(&:account)
diff --git a/app/views/following_accounts/index.html.haml b/app/views/following_accounts/index.html.haml
index 67f6cfede4def718841026ab20a1deb58e1022c7..8fd95a0b4da43ac954cc9e6c1bf9c5f85630f790 100644
--- a/app/views/following_accounts/index.html.haml
+++ b/app/views/following_accounts/index.html.haml
@@ -7,4 +7,7 @@
 
 = render 'accounts/header', account: @account
 
-= render 'accounts/follow_grid', follows: @follows, accounts: @follows.map(&:target_account)
+- if @account.user_hides_network?
+  = render 'accounts/follow_grid_hidden'
+- else
+  = render 'accounts/follow_grid', follows: @follows, accounts: @follows.map(&:target_account)
diff --git a/app/views/layouts/public.html.haml b/app/views/layouts/public.html.haml
index be96485613f1620fa3bddf95b975973e825c2361..63cc3c7a7da86c36f1521d089585e616f68272ed 100644
--- a/app/views/layouts/public.html.haml
+++ b/app/views/layouts/public.html.haml
@@ -8,9 +8,9 @@
       %span.single-user-login
         = link_to t('auth.login'), new_user_session_path
         &mdash;
-      %span.domain= link_to site_hostname, about_path
+      %span.footer__domain= link_to site_hostname, about_path
     - else
-      %span.domain= link_to site_hostname, root_path
+      %span.footer__domain= link_to site_hostname, root_path
     %span.powered-by
       != t('generic.powered_by', link: link_to('Mastodon', 'https://joinmastodon.org'))
 
diff --git a/app/views/settings/preferences/show.html.haml b/app/views/settings/preferences/show.html.haml
index fd66e13fb8ef38660d7ce167abefd27355386795..d2e8663731565f3688f8ab4613643dbf86819111 100644
--- a/app/views/settings/preferences/show.html.haml
+++ b/app/views/settings/preferences/show.html.haml
@@ -26,6 +26,9 @@
   .fields-group
     = f.input :setting_noindex, as: :boolean, wrapper: :with_label
 
+  .fields-group
+    = f.input :setting_hide_network, as: :boolean, wrapper: :with_label
+
   %h4= t 'preferences.web'
 
   .fields-group
diff --git a/config/locales/en.yml b/config/locales/en.yml
index c074fa5b041c9d017d7ca2480f67f71652693597..0257241cf10af83266f5ca1f71d02ea2676ffed8 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -40,6 +40,7 @@ en:
     following: Following
     media: Media
     moved_html: "%{name} has moved to %{new_profile_link}:"
+    network_hidden: This information is not available
     nothing_here: There is nothing here!
     people_followed_by: People whom %{name} follows
     people_who_follow: People who follow %{name}
diff --git a/config/locales/simple_form.en.yml b/config/locales/simple_form.en.yml
index 7d6907ff532bc447c9938378c03f8eaa3a3ed5dc..85597e9a7855a505164c8c42857467d49eee5626 100644
--- a/config/locales/simple_form.en.yml
+++ b/config/locales/simple_form.en.yml
@@ -15,6 +15,7 @@ en:
         note:
           one: <span class="note-counter">1</span> character left
           other: <span class="note-counter">%{count}</span> characters left
+        setting_hide_network: Who you follow and who follows you will not be shown on your profile
         setting_noindex: Affects your public profile and status pages
         setting_theme: Affects how Mastodon looks when you're logged in from any device.
       imports:
@@ -54,6 +55,7 @@ en:
         setting_default_sensitive: Always mark media as sensitive
         setting_delete_modal: Show confirmation dialog before deleting a toot
         setting_display_sensitive_media: Always show media marked as sensitive
+        setting_hide_network: Hide your network
         setting_noindex: Opt-out of search engine indexing
         setting_reduce_motion: Reduce motion in animations
         setting_system_font_ui: Use system's default font
diff --git a/config/settings.yml b/config/settings.yml
index dcf655008fc7afc7c3b55091d439a2f2ee258907..3581d10a2eb565c7439ff453dd95611378a100b6 100644
--- a/config/settings.yml
+++ b/config/settings.yml
@@ -20,6 +20,7 @@ defaults: &defaults
   timeline_preview: true
   show_staff_badge: true
   default_sensitive: false
+  hide_network: false
   unfollow_modal: false
   boost_modal: false
   delete_modal: true