about summary refs log tree commit diff
path: root/app/views
diff options
context:
space:
mode:
Diffstat (limited to 'app/views')
-rw-r--r--app/views/about/_registration.html.haml11
-rw-r--r--app/views/about/more.html.haml2
-rw-r--r--app/views/about/show.html.haml4
-rw-r--r--app/views/accounts/_bio.html.haml7
-rw-r--r--app/views/accounts/_header.html.haml7
-rw-r--r--app/views/admin/change_emails/show.html.haml11
-rw-r--r--app/views/admin/custom_emojis/new.html.haml5
-rw-r--r--app/views/admin/domain_blocks/new.html.haml13
-rw-r--r--app/views/admin/email_domain_blocks/new.html.haml3
-rw-r--r--app/views/admin/reports/_account.html.haml19
-rw-r--r--app/views/admin/reports/_report.html.haml29
-rw-r--r--app/views/admin/reports/index.html.haml52
-rw-r--r--app/views/admin/settings/edit.html.haml63
-rw-r--r--app/views/auth/confirmations/finish_signup.html.haml3
-rw-r--r--app/views/auth/confirmations/new.html.haml3
-rw-r--r--app/views/auth/passwords/edit.html.haml6
-rw-r--r--app/views/auth/passwords/new.html.haml3
-rw-r--r--app/views/auth/registrations/edit.html.haml20
-rw-r--r--app/views/auth/registrations/new.html.haml22
-rw-r--r--app/views/auth/sessions/new.html.haml12
-rw-r--r--app/views/auth/sessions/two_factor.html.haml3
-rw-r--r--app/views/filters/_fields.html.haml12
-rw-r--r--app/views/invites/_form.html.haml8
-rw-r--r--app/views/invites/index.html.haml2
-rw-r--r--app/views/layouts/modal.html.haml2
-rw-r--r--app/views/settings/applications/_fields.html.haml6
-rw-r--r--app/views/settings/exports/show.html.haml2
-rw-r--r--app/views/settings/imports/show.html.haml4
-rw-r--r--app/views/settings/preferences/show.html.haml27
-rw-r--r--app/views/settings/profiles/show.html.haml53
-rw-r--r--app/views/settings/two_factor_authentication/confirmations/new.html.haml3
-rw-r--r--app/views/settings/two_factor_authentications/show.html.haml2
32 files changed, 232 insertions, 187 deletions
diff --git a/app/views/about/_registration.html.haml b/app/views/about/_registration.html.haml
index 6ca1d7129..ee4f8fe2e 100644
--- a/app/views/about/_registration.html.haml
+++ b/app/views/about/_registration.html.haml
@@ -1,13 +1,10 @@
 = simple_form_for(new_user, url: user_registration_path) do |f|
   = f.simple_fields_for :account do |account_fields|
-    .input-with-append
-      = account_fields.input :username, autofocus: true, placeholder: t('simple_form.labels.defaults.username'), required: true, input_html: { 'aria-label' => t('simple_form.labels.defaults.username'), :autocomplete => 'off' }
-      .append
-        = "@#{site_hostname}"
+    = account_fields.input :username, wrapper: :with_label, autofocus: true, label: false, required: true, input_html: { 'aria-label' => t('simple_form.labels.defaults.username'), :autocomplete => 'off', placeholder: t('simple_form.labels.defaults.username') }, append: "@#{site_hostname}", hint: false
 
-  = f.input :email, placeholder: t('simple_form.labels.defaults.email'), required: true, input_html: { 'aria-label' => t('simple_form.labels.defaults.email'), :autocomplete => 'off' }
-  = f.input :password, placeholder: t('simple_form.labels.defaults.password'), required: true, input_html: { 'aria-label' => t('simple_form.labels.defaults.password'), :autocomplete => 'off' }
-  = f.input :password_confirmation, placeholder: t('simple_form.labels.defaults.confirm_password'), required: true, input_html: { 'aria-label' => t('simple_form.labels.defaults.confirm_password'), :autocomplete => 'off' }
+  = f.input :email, placeholder: t('simple_form.labels.defaults.email'), required: true, input_html: { 'aria-label' => t('simple_form.labels.defaults.email'), :autocomplete => 'off' }, hint: false
+  = f.input :password, placeholder: t('simple_form.labels.defaults.password'), required: true, input_html: { 'aria-label' => t('simple_form.labels.defaults.password'), :autocomplete => 'off' }, hint: false
+  = f.input :password_confirmation, placeholder: t('simple_form.labels.defaults.confirm_password'), required: true, input_html: { 'aria-label' => t('simple_form.labels.defaults.confirm_password'), :autocomplete => 'off' }, hint: false
 
   .actions
     = f.button :button, t('auth.register'), type: :submit, class: 'button button-primary'
diff --git a/app/views/about/more.html.haml b/app/views/about/more.html.haml
index 46eb17cf7..99028935f 100644
--- a/app/views/about/more.html.haml
+++ b/app/views/about/more.html.haml
@@ -24,7 +24,7 @@
             %span= t 'about.status_count_after', count: @instance_presenter.status_count
         .row__mascot
           .landing-page__mascot
-            = image_tag asset_pack_path('elephant_ui_plane.svg')
+            = image_tag asset_pack_path('elephant_ui_plane.svg'), alt: ''
 
   .column-2
     .landing-page__information.contact-widget
diff --git a/app/views/about/show.html.haml b/app/views/about/show.html.haml
index fd76a6b7d..48435fe9c 100644
--- a/app/views/about/show.html.haml
+++ b/app/views/about/show.html.haml
@@ -62,7 +62,7 @@
                   %span= t 'about.status_count_after', count: @instance_presenter.status_count
               .row__mascot
                 .landing-page__mascot
-                  = image_tag asset_pack_path('elephant_ui_plane.svg')
+                  = image_tag asset_pack_path('elephant_ui_plane.svg'), alt: ''
 
       - else
         .column-2.non-preview
@@ -94,7 +94,7 @@
                   %span= t 'about.status_count_after', count: @instance_presenter.status_count
               .row__mascot
                 .landing-page__mascot
-                  = image_tag asset_pack_path('elephant_ui_plane.svg')
+                  = image_tag asset_pack_path('elephant_ui_plane.svg'), alt: ''
 
       - if Setting.timeline_preview
         .column-3
diff --git a/app/views/accounts/_bio.html.haml b/app/views/accounts/_bio.html.haml
index 4e674beff..2ea34a048 100644
--- a/app/views/accounts/_bio.html.haml
+++ b/app/views/accounts/_bio.html.haml
@@ -4,8 +4,11 @@
       - account.fields.each do |field|
         %dl
           %dt.emojify{ title: field.name }= Formatter.instance.format_field(account, field.name, custom_emojify: true)
-          %dd.emojify{ title: field.value }= Formatter.instance.format_field(account, field.value, custom_emojify: true)
-
+          %dd{ title: field.value, class: custom_field_classes(field) }
+            - if field.verified?
+              %span.verified__mark{ title: t('accounts.link_verified_on', date: l(field.verified_at)) }
+                = fa_icon 'check'
+            = Formatter.instance.format_field(account, field.value, custom_emojify: true)
   = account_badge(account)
 
   - if account.note.present?
diff --git a/app/views/accounts/_header.html.haml b/app/views/accounts/_header.html.haml
index 95e55a1b0..3da270d27 100644
--- a/app/views/accounts/_header.html.haml
+++ b/app/views/accounts/_header.html.haml
@@ -3,7 +3,10 @@
     = 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
+      - if current_account&.user&.setting_auto_play_gif
+        = image_tag account.avatar_original_url
+      - else
+        = image_tag account.avatar_static_url
     .public-account-header__tabs
       .public-account-header__tabs__name
         %h1
@@ -13,7 +16,7 @@
             = fa_icon('lock') if account.locked?
       .public-account-header__tabs__tabs
         .details-counters
-          .counter{ class: active_nav_class(short_account_url(account)) }
+          .counter{ class: active_nav_class(short_account_url(account)) + active_nav_class(short_account_with_replies_url(account)) + active_nav_class(short_account_media_url(account)) }
             = link_to short_account_url(account), class: 'u-url u-uid', title: number_with_delimiter(account.statuses_count) do
               %span.counter-number= number_to_human account.statuses_count, strip_insignificant_zeros: true
               %span.counter-label= t('accounts.posts', count: account.statuses_count)
diff --git a/app/views/admin/change_emails/show.html.haml b/app/views/admin/change_emails/show.html.haml
index a661b1ad6..6febef9b1 100644
--- a/app/views/admin/change_emails/show.html.haml
+++ b/app/views/admin/change_emails/show.html.haml
@@ -2,6 +2,11 @@
   = t('admin.accounts.change_email.title', username: @account.acct)
 
 = simple_form_for @user, url: admin_account_change_email_path(@account.id) do |f|
-  = f.input :email, wrapper: :with_label, disabled: true, label: t('admin.accounts.change_email.current_email')
-  = f.input :unconfirmed_email, wrapper: :with_label, label: t('admin.accounts.change_email.new_email')
-  = f.button :submit, class: "button", value: t('admin.accounts.change_email.submit')
+  .fields-group
+    = f.input :email, wrapper: :with_label, disabled: true, label: t('admin.accounts.change_email.current_email')
+
+  .fields-group
+    = f.input :unconfirmed_email, wrapper: :with_label, label: t('admin.accounts.change_email.new_email')
+
+  .actions
+    = f.button :submit, class: "button", value: t('admin.accounts.change_email.submit')
diff --git a/app/views/admin/custom_emojis/new.html.haml b/app/views/admin/custom_emojis/new.html.haml
index 672afe435..e15a07cb8 100644
--- a/app/views/admin/custom_emojis/new.html.haml
+++ b/app/views/admin/custom_emojis/new.html.haml
@@ -5,8 +5,9 @@
   = render 'shared/error_messages', object: @custom_emoji
 
   .fields-group
-    = f.input :shortcode, placeholder: t('admin.custom_emojis.shortcode'), hint: t('admin.custom_emojis.shortcode_hint')
-    = f.input :image, input_html: { accept: 'image/png' }, hint: t('admin.custom_emojis.image_hint')
+    = f.input :shortcode, wrapper: :with_label, label: t('admin.custom_emojis.shortcode'), hint: t('admin.custom_emojis.shortcode_hint')
+  .fields-group
+    = f.input :image, wrapper: :with_label, input_html: { accept: 'image/png' }, hint: t('admin.custom_emojis.image_hint')
 
   .actions
     = f.button :button, t('admin.custom_emojis.upload'), type: :submit
diff --git a/app/views/admin/domain_blocks/new.html.haml b/app/views/admin/domain_blocks/new.html.haml
index 38fa90169..6e514f833 100644
--- a/app/views/admin/domain_blocks/new.html.haml
+++ b/app/views/admin/domain_blocks/new.html.haml
@@ -4,14 +4,15 @@
 = simple_form_for @domain_block, url: admin_domain_blocks_path do |f|
   = render 'shared/error_messages', object: @domain_block
 
-  %p.hint= t('.hint')
+  .fields-row
+    .fields-row__column.fields-row__column-6.fields-group
+      = f.input :domain, wrapper: :with_label, label: t('admin.domain_blocks.domain'), hint: t('.hint'), required: true
 
-  = f.input :domain, placeholder: t('admin.domain_blocks.domain')
-  = f.input :severity, collection: DomainBlock.severities.keys, wrapper: :with_label, include_blank: false, label_method: lambda { |type| t(".severity.#{type}") }
+    .fields-row__column.fields-row__column-6.fields-group
+      = f.input :severity, collection: DomainBlock.severities.keys, wrapper: :with_label, include_blank: false, label_method: lambda { |type| t(".severity.#{type}") }, hint: t('.severity.desc_html')
 
-  %p.hint= t('.severity.desc_html')
-
-  = f.input :reject_media, as: :boolean, wrapper: :with_label, label: I18n.t('admin.domain_blocks.reject_media'), hint: I18n.t('admin.domain_blocks.reject_media_hint')
+  .fields-group
+    = f.input :reject_media, as: :boolean, wrapper: :with_label, label: I18n.t('admin.domain_blocks.reject_media'), hint: I18n.t('admin.domain_blocks.reject_media_hint')
 
   .actions
     = f.button :button, t('.create'), type: :submit
diff --git a/app/views/admin/email_domain_blocks/new.html.haml b/app/views/admin/email_domain_blocks/new.html.haml
index bcae867d9..f372fa512 100644
--- a/app/views/admin/email_domain_blocks/new.html.haml
+++ b/app/views/admin/email_domain_blocks/new.html.haml
@@ -4,7 +4,8 @@
 = simple_form_for @email_domain_block, url: admin_email_domain_blocks_path do |f|
   = render 'shared/error_messages', object: @email_domain_block
 
-  = f.input :domain, placeholder: t('admin.email_domain_blocks.domain')
+  .fields-group
+    = f.input :domain, wrapper: :with_label, label: t('admin.email_domain_blocks.domain')
 
   .actions
     = f.button :button, t('.create'), type: :submit
diff --git a/app/views/admin/reports/_account.html.haml b/app/views/admin/reports/_account.html.haml
deleted file mode 100644
index 9ac161c9c..000000000
--- a/app/views/admin/reports/_account.html.haml
+++ /dev/null
@@ -1,19 +0,0 @@
-- size ||= 36
-
-.account.compact
-  .account__wrapper
-    - if account.nil?
-      .account__display-name
-        .account__avatar-wrapper
-          .account__avatar{ style: "background-image: url(#{full_asset_url('avatars/original/missing.png', skip_pipeline: true)}); width: #{size}px; height: #{size}px; background-size: #{size}px #{size}px" }
-        %span.display-name
-          %strong= t 'about.contact_missing'
-          %span.display-name__account= t 'about.contact_unavailable'
-    - else
-      = link_to TagManager.instance.url_for(account), class: 'account__display-name' do
-        .account__avatar-wrapper
-          .account__avatar{ style: "background-image: url(#{account.avatar.url}); width: #{size}px; height: #{size}px; background-size: #{size}px #{size}px" }
-        %span.display-name
-          %bdi
-            %strong.display-name__html.emojify= display_name(account, custom_emojify: true)
-          %span.display-name__account @#{account.acct}
diff --git a/app/views/admin/reports/_report.html.haml b/app/views/admin/reports/_report.html.haml
deleted file mode 100644
index 7b25c924b..000000000
--- a/app/views/admin/reports/_report.html.haml
+++ /dev/null
@@ -1,29 +0,0 @@
-%tr
-  %td.id
-    = "##{report.id}"
-  %td.target
-    = admin_account_link_to report.target_account
-  %td.reporter
-    - if report.account.local?
-      = admin_account_link_to report.account
-    - else
-      = report.account.domain
-  %td
-    %div{ title: report.comment }
-      = truncate(report.comment, length: 30, separator: ' ')
-    %div
-      - unless report.statuses.empty?
-        %span{ title: t('admin.accounts.statuses') }
-          = fa_icon('comment')
-          = report.statuses.count
-      - unless report.media_attachments.empty?
-        %span{ title: t('admin.accounts.media_attachments') }
-          = fa_icon('camera')
-          = report.media_attachments.count
-  %td
-    - if report.assigned_account.nil?
-      \-
-    - else
-      = admin_account_link_to report.assigned_account
-  %td
-    = table_link_to 'circle', t('admin.reports.view'), admin_report_path(report)
diff --git a/app/views/admin/reports/index.html.haml b/app/views/admin/reports/index.html.haml
index 44a531f2c..d73faccb0 100644
--- a/app/views/admin/reports/index.html.haml
+++ b/app/views/admin/reports/index.html.haml
@@ -8,17 +8,45 @@
       %li= filter_link_to t('admin.reports.unresolved'), resolved: nil
       %li= filter_link_to t('admin.reports.resolved'), resolved: '1'
 
-.table-wrapper
-  %table.table
-    %thead
-      %tr
-        %th= t('admin.reports.id')
-        %th= t('admin.reports.target')
-        %th= t('admin.reports.reported_by')
-        %th= t('admin.reports.report_contents')
-        %th= t('admin.reports.assigned')
-        %th
-    %tbody
-      = render @reports
+- @reports.group_by(&:target_account_id).each do |target_account_id, reports|
+  - target_account = reports.first.target_account
+  .report-card
+    .report-card__profile
+      = account_link_to target_account, '', size: 36, path: admin_account_path(target_account.id)
+      .report-card__profile__stats
+        = link_to pluralize(target_account.targeted_moderation_notes.count, t('admin.reports.account.note')), admin_account_path(target_account.id)
+        %br/
+        - if target_account.suspended?
+          %span.red= t('admin.accounts.suspended')
+        - elsif target_account.silenced?
+          %span.red= t('admin.accounts.silenced')
+        - elsif target_account.user&.disabled?
+          %span.red= t('admin.accounts.disabled')
+        - else
+          %span.neutral= t('admin.accounts.no_limits_imposed')
+    .report-card__summary
+      - reports.each do |report|
+        .report-card__summary__item
+          .report-card__summary__item__reported-by
+            - if report.account.local?
+              = admin_account_link_to report.account
+            - else
+              = report.account.domain
+          .report-card__summary__item__content
+            = link_to admin_report_path(report) do
+              .one-line= report.comment.presence || t('admin.reports.comment.none')
 
+              %span.report-card__summary__item__content__icon{ title: t('admin.accounts.statuses') }
+                = fa_icon('comment')
+                = report.statuses.count
+
+              %span.report-card__summary__item__content__icon{ title: t('admin.accounts.media_attachments') }
+                = fa_icon('camera')
+                = report.media_attachments.count
+
+          .report-card__summary__item__assigned
+            - if report.assigned_account.present?
+              = admin_account_link_to report.assigned_account
+            - else
+              \-
 = paginate @reports
diff --git a/app/views/admin/settings/edit.html.haml b/app/views/admin/settings/edit.html.haml
index abe7ecf32..b4abbf815 100644
--- a/app/views/admin/settings/edit.html.haml
+++ b/app/views/admin/settings/edit.html.haml
@@ -2,24 +2,37 @@
   = t('admin.settings.title')
 
 = simple_form_for @admin_settings, url: admin_settings_path, html: { method: :patch } do |f|
-  .actions.actions--top
-    = f.button :button, t('generic.save_changes'), type: :submit
 
   .fields-group
-    = f.input :site_title, placeholder: t('admin.settings.site_title')
-    = f.input :site_short_description, wrapper: :with_block_label, as: :text, label: t('admin.settings.site_short_description.title'), hint: t('admin.settings.site_short_description.desc_html'), input_html: { rows: 2 }
+    = f.input :site_title, wrapper: :with_label, label: t('admin.settings.site_title')
+
+  .fields-group
+    = f.input :flavour, collection: Themes.instance.flavours, label_method: lambda { |flavour| I18n.t("flavours.#{flavour}.name", default: flavour) }, wrapper: :with_label, include_blank: false
+
+  .fields-row
+    .fields-row__column.fields-row__column-6.fields-group
+      = f.input :site_contact_username, wrapper: :with_label, label: t('admin.settings.contact_information.username')
+    .fields-row__column.fields-row__column-6.fields-group
+      = f.input :site_contact_email, wrapper: :with_label, label: t('admin.settings.contact_information.email')
+
+  .fields-group
     = f.input :site_description, wrapper: :with_block_label, as: :text, label: t('admin.settings.site_description.title'), hint: t('admin.settings.site_description.desc_html'), input_html: { rows: 4 }
-    = f.input :site_contact_username, placeholder: t('admin.settings.contact_information.username')
-    = f.input :site_contact_email, placeholder: t('admin.settings.contact_information.email')
 
-  %hr/
+  .fields-group
+    = f.input :site_short_description, wrapper: :with_block_label, as: :text, label: t('admin.settings.site_short_description.title'), hint: t('admin.settings.site_short_description.desc_html'), input_html: { rows: 2 }
+
+  .fields-row
+    .fields-row__column.fields-row__column-6.fields-group
+      = f.input :thumbnail, as: :file, wrapper: :with_block_label, label: t('admin.settings.thumbnail.title'), hint: t('admin.settings.thumbnail.desc_html')
+    .fields-row__column.fields-row__column-6.fields-group
+      = f.input :hero, as: :file, wrapper: :with_block_label, label: t('admin.settings.hero.title'), hint: t('admin.settings.hero.desc_html')
+
+  %hr.spacer/
 
   .fields-group
-    = f.input :flavour, collection: Themes.instance.flavours, label_method: lambda { |flavour| I18n.t("flavours.#{flavour}.name", default: flavour) }, wrapper: :with_label, include_blank: false
-    = f.input :thumbnail, as: :file, wrapper: :with_block_label, label: t('admin.settings.thumbnail.title'), hint: t('admin.settings.thumbnail.desc_html')
-    = f.input :hero, as: :file, wrapper: :with_block_label, label: t('admin.settings.hero.title'), hint: t('admin.settings.hero.desc_html')
+    = f.input :bootstrap_timeline_accounts, wrapper: :with_block_label, label: t('admin.settings.bootstrap_timeline_accounts.title'), hint: t('admin.settings.bootstrap_timeline_accounts.desc_html')
 
-  %hr/
+  %hr.spacer/
 
   .fields-group
     = f.input :timeline_preview, as: :boolean, wrapper: :with_label, label: t('admin.settings.timeline_preview.title'), hint: t('admin.settings.timeline_preview.desc_html')
@@ -37,34 +50,24 @@
     = f.input :open_deletion, as: :boolean, wrapper: :with_label, label: t('admin.settings.registrations.deletion.title'), hint: t('admin.settings.registrations.deletion.desc_html')
 
   .fields-group
-    = f.input :closed_registrations_message, as: :text, wrapper: :with_block_label, label: t('admin.settings.registrations.closed_message.title'), hint: t('admin.settings.registrations.closed_message.desc_html'), input_html: { rows: 8 }
-
-  %hr/
-
-  .fields-group
-    = f.input :min_invite_role, wrapper: :with_label, collection: %i(disabled user moderator admin), label: t('admin.settings.registrations.min_invite_role.title'), label_method: lambda { |role| role == :disabled ? t('admin.settings.registrations.min_invite_role.disabled') : t("admin.accounts.roles.#{role}") }, as: :radio_buttons, include_blank: false, collection_wrapper_tag: 'ul', item_wrapper_tag: 'li'
-
-  %hr/
+    = f.input :activity_api_enabled, as: :boolean, wrapper: :with_label, label: t('admin.settings.activity_api_enabled.title'), hint: t('admin.settings.activity_api_enabled.desc_html')
 
   .fields-group
-    = f.input :site_extended_description, wrapper: :with_block_label, as: :text, label: t('admin.settings.site_description_extended.title'), hint: t('admin.settings.site_description_extended.desc_html'), input_html: { rows: 8 }
-    = f.input :site_terms, wrapper: :with_block_label, as: :text, label: t('admin.settings.site_terms.title'), hint: t('admin.settings.site_terms.desc_html'), input_html: { rows: 8 }
-    = f.input :custom_css, wrapper: :with_block_label, as: :text, input_html: { rows: 8 }, label: t('admin.settings.custom_css.title'), hint: t('admin.settings.custom_css.desc_html')
-  %hr/
+    = f.input :peers_api_enabled, as: :boolean, wrapper: :with_label, label: t('admin.settings.peers_api_enabled.title'), hint: t('admin.settings.peers_api_enabled.desc_html')
 
   .fields-group
-    = f.input :bootstrap_timeline_accounts, wrapper: :with_block_label, label: t('admin.settings.bootstrap_timeline_accounts.title'), hint: t('admin.settings.bootstrap_timeline_accounts.desc_html')
+    = f.input :preview_sensitive_media, as: :boolean, wrapper: :with_label, label: t('admin.settings.preview_sensitive_media.title'), hint: t('admin.settings.preview_sensitive_media.desc_html')
 
-  %hr/
+  %hr.spacer/
 
   .fields-group
-    = f.input :activity_api_enabled, as: :boolean, wrapper: :with_label, label: t('admin.settings.activity_api_enabled.title'), hint: t('admin.settings.activity_api_enabled.desc_html')
+    = f.input :min_invite_role, wrapper: :with_label, collection: %i(disabled user moderator admin), label: t('admin.settings.registrations.min_invite_role.title'), label_method: lambda { |role| role == :disabled ? t('admin.settings.registrations.min_invite_role.disabled') : t("admin.accounts.roles.#{role}") }, include_blank: false, collection_wrapper_tag: 'ul', item_wrapper_tag: 'li'
 
   .fields-group
-    = f.input :peers_api_enabled, as: :boolean, wrapper: :with_label, label: t('admin.settings.peers_api_enabled.title'), hint: t('admin.settings.peers_api_enabled.desc_html')
-
-  .fields-group
-    = f.input :preview_sensitive_media, as: :boolean, wrapper: :with_label, label: t('admin.settings.preview_sensitive_media.title'), hint: t('admin.settings.preview_sensitive_media.desc_html')
+    = f.input :closed_registrations_message, as: :text, wrapper: :with_block_label, label: t('admin.settings.registrations.closed_message.title'), hint: t('admin.settings.registrations.closed_message.desc_html'), input_html: { rows: 8 }
+    = f.input :site_extended_description, wrapper: :with_block_label, as: :text, label: t('admin.settings.site_description_extended.title'), hint: t('admin.settings.site_description_extended.desc_html'), input_html: { rows: 8 }
+    = f.input :site_terms, wrapper: :with_block_label, as: :text, label: t('admin.settings.site_terms.title'), hint: t('admin.settings.site_terms.desc_html'), input_html: { rows: 8 }
+    = f.input :custom_css, wrapper: :with_block_label, as: :text, input_html: { rows: 8 }, label: t('admin.settings.custom_css.title'), hint: t('admin.settings.custom_css.desc_html')
 
   .actions
     = f.button :button, t('generic.save_changes'), type: :submit
diff --git a/app/views/auth/confirmations/finish_signup.html.haml b/app/views/auth/confirmations/finish_signup.html.haml
index 4b5161d6b..9d09b74e1 100644
--- a/app/views/auth/confirmations/finish_signup.html.haml
+++ b/app/views/auth/confirmations/finish_signup.html.haml
@@ -8,7 +8,8 @@
         = msg
         %br
 
-  = f.input :email
+  .fields-group
+    = f.input :email, wrapper: :with_label, required: true, hint: false
 
   .actions
     = f.submit t('auth.confirm_email'), class: 'button'
diff --git a/app/views/auth/confirmations/new.html.haml b/app/views/auth/confirmations/new.html.haml
index 07ca4a7da..4a1bedaa4 100644
--- a/app/views/auth/confirmations/new.html.haml
+++ b/app/views/auth/confirmations/new.html.haml
@@ -4,7 +4,8 @@
 = simple_form_for(resource, as: resource_name, url: confirmation_path(resource_name), html: { method: :post }) do |f|
   = render 'shared/error_messages', object: resource
 
-  = f.input :email, autofocus: true, required: true, placeholder: t('simple_form.labels.defaults.email'), input_html: { 'aria-label' => t('simple_form.labels.defaults.email') }
+  .fields-group
+    = f.input :email, autofocus: true, wrapper: :with_label, label: t('simple_form.labels.defaults.email'), input_html: { 'aria-label' => t('simple_form.labels.defaults.email') }, hint: false
 
   .actions
     = f.button :button, t('auth.resend_confirmation'), type: :submit
diff --git a/app/views/auth/passwords/edit.html.haml b/app/views/auth/passwords/edit.html.haml
index 53d1769d6..383d44f00 100644
--- a/app/views/auth/passwords/edit.html.haml
+++ b/app/views/auth/passwords/edit.html.haml
@@ -7,8 +7,10 @@
   - if !use_seamless_external_login? || resource.encrypted_password.present?
     = f.input :reset_password_token, as: :hidden
 
-    = f.input :password, autofocus: true, placeholder: t('simple_form.labels.defaults.new_password'), input_html: { 'aria-label' => t('simple_form.labels.defaults.new_password'), :autocomplete => 'off' }
-    = f.input :password_confirmation, placeholder: t('simple_form.labels.defaults.confirm_new_password'), input_html: { 'aria-label' => t('simple_form.labels.defaults.confirm_new_password'), :autocomplete => 'off' }
+    .fields-group
+      = f.input :password, wrapper: :with_label, autofocus: true, label: t('simple_form.labels.defaults.new_password'), input_html: { 'aria-label' => t('simple_form.labels.defaults.new_password'), :autocomplete => 'off' }, required: true
+    .fields-group
+      = f.input :password_confirmation, wrapper: :with_label, label: t('simple_form.labels.defaults.confirm_new_password'), input_html: { 'aria-label' => t('simple_form.labels.defaults.confirm_new_password'), :autocomplete => 'off' }, required: true
 
     .actions
       = f.button :button, t('auth.set_new_password'), type: :submit
diff --git a/app/views/auth/passwords/new.html.haml b/app/views/auth/passwords/new.html.haml
index f4d22031a..bae5b24ba 100644
--- a/app/views/auth/passwords/new.html.haml
+++ b/app/views/auth/passwords/new.html.haml
@@ -4,7 +4,8 @@
 = simple_form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :post }) do |f|
   = render 'shared/error_messages', object: resource
 
-  = f.input :email, autofocus: true, required: true, placeholder: t('simple_form.labels.defaults.email'), input_html: { 'aria-label' => t('simple_form.labels.defaults.email') }
+  .fields-group
+    = f.input :email, autofocus: true, wrapper: :with_label, label: t('simple_form.labels.defaults.email'), input_html: { 'aria-label' => t('simple_form.labels.defaults.email') }, hint: false
 
   .actions
     = f.button :button, t('auth.reset_password'), type: :submit
diff --git a/app/views/auth/registrations/edit.html.haml b/app/views/auth/registrations/edit.html.haml
index 05fc7df31..7fc08a23b 100644
--- a/app/views/auth/registrations/edit.html.haml
+++ b/app/views/auth/registrations/edit.html.haml
@@ -1,24 +1,32 @@
 - content_for :page_title do
   = t('auth.security')
 
-%h4= t('auth.change_password')
 = simple_form_for(resource, as: resource_name, url: registration_path(resource_name), html: { method: :put, class: 'auth_edit' }) do |f|
   = render 'shared/error_messages', object: resource
 
   - if !use_seamless_external_login? || resource.encrypted_password.present?
-    = f.input :email, placeholder: t('simple_form.labels.defaults.email'), input_html: { 'aria-label' => t('simple_form.labels.defaults.email') }
-    = f.input :password, placeholder: t('simple_form.labels.defaults.new_password'), input_html: { 'aria-label' => t('simple_form.labels.defaults.new_password'), :autocomplete => 'off' }
-    = f.input :password_confirmation, placeholder: t('simple_form.labels.defaults.confirm_new_password'), input_html: { 'aria-label' => t('simple_form.labels.defaults.confirm_new_password'), :autocomplete => 'off' }
-    = f.input :current_password, placeholder: t('simple_form.labels.defaults.current_password'), input_html: { 'aria-label' => t('simple_form.labels.defaults.current_password'), :autocomplete => 'off' }
+    .fields-group
+      = f.input :email, wrapper: :with_label, input_html: { 'aria-label' => t('simple_form.labels.defaults.email') }, required: true, hint: false
+
+    .fields-group
+      = f.input :password, wrapper: :with_label, input_html: { 'aria-label' => t('simple_form.labels.defaults.new_password'), :autocomplete => 'off' }, hint: false
+
+    .fields-group
+      = f.input :password_confirmation, wrapper: :with_label, label: t('simple_form.labels.defaults.confirm_new_password'), input_html: { 'aria-label' => t('simple_form.labels.defaults.confirm_new_password'), :autocomplete => 'off' }
+
+    .fields-group
+      = f.input :current_password, wrapper: :with_label, input_html: { 'aria-label' => t('simple_form.labels.defaults.current_password'), :autocomplete => 'off' }, required: true
 
     .actions
       = f.button :button, t('generic.save_changes'), type: :submit
   - else
     %p.hint= t('users.seamless_external_login')
 
+%hr.spacer/
+
 = render 'sessions'
 
 - if open_deletion?
-
+  %hr.spacer/
   %h4= t('auth.delete_account')
   %p.muted-hint= t('auth.delete_account_html', path: settings_delete_path)
diff --git a/app/views/auth/registrations/new.html.haml b/app/views/auth/registrations/new.html.haml
index 200ed42de..72ce8e531 100644
--- a/app/views/auth/registrations/new.html.haml
+++ b/app/views/auth/registrations/new.html.haml
@@ -13,18 +13,22 @@
       = render 'application/card', account: @invite.user.account
 
   = f.simple_fields_for :account do |ff|
-    .input-with-append
-      = ff.input :username, autofocus: true, placeholder: t('simple_form.labels.defaults.username'), required: true, input_html: { 'aria-label' => t('simple_form.labels.defaults.username'), :autocomplete => 'off' }
-      .append
-        = "@#{site_hostname}"
-
-  = f.input :email, placeholder: t('simple_form.labels.defaults.email'), required: true, input_html: { 'aria-label' => t('simple_form.labels.defaults.email'), :autocomplete => 'off' }
-  = f.input :password, placeholder: t('simple_form.labels.defaults.password'), required: true, input_html: { 'aria-label' => t('simple_form.labels.defaults.password'), :autocomplete => 'off' }
-  = f.input :password_confirmation, placeholder: t('simple_form.labels.defaults.confirm_password'), required: true, input_html: { 'aria-label' => t('simple_form.labels.defaults.confirm_password'), :autocomplete => 'off' }
+    .fields-group
+      = ff.input :username, wrapper: :with_label, autofocus: true, label: t('simple_form.labels.defaults.username'), required: true, input_html: { 'aria-label' => t('simple_form.labels.defaults.username'), :autocomplete => 'off' }, append: "@#{site_hostname}", hint: t('simple_form.hints.defaults.username', domain: site_hostname)
+
+  .fields-group
+    = f.input :email, wrapper: :with_label, label: t('simple_form.labels.defaults.email'), required: true, input_html: { 'aria-label' => t('simple_form.labels.defaults.email'), :autocomplete => 'off' }
+
+  .fields-group
+    = f.input :password, wrapper: :with_label, label: t('simple_form.labels.defaults.password'), required: true, input_html: { 'aria-label' => t('simple_form.labels.defaults.password'), :autocomplete => 'off' }
+  .fields-group
+    = f.input :password_confirmation, wrapper: :with_label, label: t('simple_form.labels.defaults.confirm_password'), required: true, input_html: { 'aria-label' => t('simple_form.labels.defaults.confirm_password'), :autocomplete => 'off' }
+
   = f.input :invite_code, as: :hidden
 
+  %p.hint= t('auth.agreement_html', rules_path: about_more_path, terms_path: terms_path)
+
   .actions
     = f.button :button, t('auth.register'), type: :submit
 
-  %p.hint.subtle-hint=t('auth.agreement_html', rules_path: about_more_path, terms_path: terms_path)
 .form-footer= render 'auth/shared/links'
diff --git a/app/views/auth/sessions/new.html.haml b/app/views/auth/sessions/new.html.haml
index 0c9f9d5fe..ceb169408 100644
--- a/app/views/auth/sessions/new.html.haml
+++ b/app/views/auth/sessions/new.html.haml
@@ -5,11 +5,13 @@
   = render partial: 'shared/og'
 
 = simple_form_for(resource, as: resource_name, url: session_path(resource_name)) do |f|
-  - if use_seamless_external_login?
-    = f.input :email, autofocus: true, placeholder: t('simple_form.labels.defaults.username_or_email'), required: true, input_html: { 'aria-label' => t('simple_form.labels.defaults.username_or_email') }
-  - else
-    = f.input :email, autofocus: true, placeholder: t('simple_form.labels.defaults.email'), required: true, input_html: { 'aria-label' => t('simple_form.labels.defaults.email') }
-  = f.input :password, placeholder: t('simple_form.labels.defaults.password'), required: true, input_html: { 'aria-label' => t('simple_form.labels.defaults.password'), :autocomplete => 'off' }
+  .fields-group
+    - if use_seamless_external_login?
+      = f.input :email, autofocus: true, wrapper: :with_label, label: t('simple_form.labels.defaults.username_or_email'), input_html: { 'aria-label' => t('simple_form.labels.defaults.username_or_email') }, hint: false
+    - else
+      = f.input :email, autofocus: true, wrapper: :with_label, label: t('simple_form.labels.defaults.email'), input_html: { 'aria-label' => t('simple_form.labels.defaults.email') }, hint: false
+  .fields-group
+    = f.input :password, wrapper: :with_label, label: t('simple_form.labels.defaults.password'), input_html: { 'aria-label' => t('simple_form.labels.defaults.password'), :autocomplete => 'off' }, hint: false
 
   .actions
     = f.button :button, t('auth.login'), type: :submit
diff --git a/app/views/auth/sessions/two_factor.html.haml b/app/views/auth/sessions/two_factor.html.haml
index 1af3193ae..4e6bbd7a9 100644
--- a/app/views/auth/sessions/two_factor.html.haml
+++ b/app/views/auth/sessions/two_factor.html.haml
@@ -4,7 +4,8 @@
 = simple_form_for(resource, as: resource_name, url: session_path(resource_name), method: :post) do |f|
   %p.hint{ style: 'margin-bottom: 25px' }= t('simple_form.hints.sessions.otp')
 
-  = f.input :otp_attempt, type: :number, placeholder: t('simple_form.labels.defaults.otp_attempt'), input_html: { 'aria-label' => t('simple_form.labels.defaults.otp_attempt'), :autocomplete => 'off' }, required: true, autofocus: true
+  .fields-group
+    = f.input :otp_attempt, type: :number, wrapper: :with_label, label: t('simple_form.labels.defaults.otp_attempt'), input_html: { 'aria-label' => t('simple_form.labels.defaults.otp_attempt'), :autocomplete => 'off' }, autofocus: true
 
   .actions
     = f.button :button, t('auth.login'), type: :submit
diff --git a/app/views/filters/_fields.html.haml b/app/views/filters/_fields.html.haml
index a5a3f0337..fb94a07fc 100644
--- a/app/views/filters/_fields.html.haml
+++ b/app/views/filters/_fields.html.haml
@@ -1,14 +1,16 @@
-.fields-group
-  = f.input :phrase, as: :string, wrapper: :with_block_label
+.fields-row
+  .fields-row__column.fields-row__column-6.fields-group
+    = f.input :phrase, as: :string, wrapper: :with_label, hint: false
+  .fields-row__column.fields-row__column-6.fields-group
+    = f.input :expires_in, wrapper: :with_label, collection: [30.minutes, 1.hour, 6.hours, 12.hours, 1.day, 1.week].map(&:to_i), label_method: lambda { |i| I18n.t("invites.expires_in.#{i}") }, prompt: I18n.t('invites.expires_in_prompt')
 
 .fields-group
   = f.input :context, wrapper: :with_block_label, collection: CustomFilter::VALID_CONTEXTS, as: :check_boxes, collection_wrapper_tag: 'ul', item_wrapper_tag: 'li', label_method: lambda { |context| I18n.t("filters.contexts.#{context}") }, include_blank: false
 
+%hr.spacer/
+
 .fields-group
   = f.input :irreversible, wrapper: :with_label
 
 .fields-group
   = f.input :whole_word, wrapper: :with_label
-
-.fields-group
-  = f.input :expires_in, wrapper: :with_label, collection: [30.minutes, 1.hour, 6.hours, 12.hours, 1.day, 1.week].map(&:to_i), label_method: lambda { |i| I18n.t("invites.expires_in.#{i}") }, prompt: I18n.t('invites.expires_in_prompt')
diff --git a/app/views/invites/_form.html.haml b/app/views/invites/_form.html.haml
index 42a107bb2..3a2a5ef0e 100644
--- a/app/views/invites/_form.html.haml
+++ b/app/views/invites/_form.html.haml
@@ -1,9 +1,11 @@
 = simple_form_for(@invite, url: controller.is_a?(Admin::InvitesController) ? admin_invites_path : invites_path) do |f|
   = render 'shared/error_messages', object: @invite
 
-  .fields-group
-    = f.input :max_uses, wrapper: :with_label, collection: [1, 5, 10, 25, 50, 100], label_method: lambda { |num| I18n.t('invites.max_uses', count: num) }, prompt: I18n.t('invites.max_uses_prompt')
-    = f.input :expires_in, wrapper: :with_label, collection: [30.minutes, 1.hour, 6.hours, 12.hours, 1.day, 1.week].map(&:to_i), label_method: lambda { |i| I18n.t("invites.expires_in.#{i}") }, prompt: I18n.t('invites.expires_in_prompt')
+  .fields-row
+    .fields-row__column.fields-row__column-6.fields-group
+      = f.input :max_uses, wrapper: :with_label, collection: [1, 5, 10, 25, 50, 100], label_method: lambda { |num| I18n.t('invites.max_uses', count: num) }, prompt: I18n.t('invites.max_uses_prompt')
+    .fields-row__column.fields-row__column-6.fields-group
+      = f.input :expires_in, wrapper: :with_label, collection: [30.minutes, 1.hour, 6.hours, 12.hours, 1.day, 1.week].map(&:to_i), label_method: lambda { |i| I18n.t("invites.expires_in.#{i}") }, prompt: I18n.t('invites.expires_in_prompt')
 
   .fields-group
     = f.input :autofollow, wrapper: :with_label
diff --git a/app/views/invites/index.html.haml b/app/views/invites/index.html.haml
index f4c5047fa..fb827f6e6 100644
--- a/app/views/invites/index.html.haml
+++ b/app/views/invites/index.html.haml
@@ -6,7 +6,7 @@
 
   = render 'form'
 
-  %hr/
+  %hr.spacer/
 
 %table.table
   %thead
diff --git a/app/views/layouts/modal.html.haml b/app/views/layouts/modal.html.haml
index a86b4fd3f..b6e33ca91 100644
--- a/app/views/layouts/modal.html.haml
+++ b/app/views/layouts/modal.html.haml
@@ -5,7 +5,7 @@
       .name
         = t 'users.signed_in_as'
         %span.username @#{current_account.local_username_and_domain}
-      = link_to destroy_user_session_path, method: :delete, class: 'logout-link icon-button' do
+      = link_to destroy_user_session_path(continue: true), method: :delete, class: 'logout-link icon-button' do
         = fa_icon 'sign-out'
 
   .container-alt= yield
diff --git a/app/views/settings/applications/_fields.html.haml b/app/views/settings/applications/_fields.html.haml
index db90df349..6a2863b20 100644
--- a/app/views/settings/applications/_fields.html.haml
+++ b/app/views/settings/applications/_fields.html.haml
@@ -1,6 +1,8 @@
 .fields-group
-  = f.input :name, placeholder: t('activerecord.attributes.doorkeeper/application.name')
-  = f.input :website, placeholder: t('activerecord.attributes.doorkeeper/application.website')
+  = f.input :name, wrapper: :with_label, label: t('activerecord.attributes.doorkeeper/application.name')
+
+.fields-group
+  = f.input :website, wrapper: :with_label, label: t('activerecord.attributes.doorkeeper/application.website')
 
 .fields-group
   = f.input :redirect_uri, wrapper: :with_block_label, label: t('activerecord.attributes.doorkeeper/application.redirect_uri'), hint: t('doorkeeper.applications.help.redirect_uri')
diff --git a/app/views/settings/exports/show.html.haml b/app/views/settings/exports/show.html.haml
index 792dccd9e..6c030b1ab 100644
--- a/app/views/settings/exports/show.html.haml
+++ b/app/views/settings/exports/show.html.haml
@@ -9,7 +9,7 @@
         %td= number_to_human_size @export.total_storage
         %td
       %tr
-        %th= t('accounts.statuses', count: @export.total_statuses)
+        %th= t('accounts.posts', count: @export.total_statuses)
         %td= number_with_delimiter @export.total_statuses
         %td
       %tr
diff --git a/app/views/settings/imports/show.html.haml b/app/views/settings/imports/show.html.haml
index 2b43cb134..4512fc714 100644
--- a/app/views/settings/imports/show.html.haml
+++ b/app/views/settings/imports/show.html.haml
@@ -2,10 +2,8 @@
   = t('settings.import')
 
 = simple_form_for @import, url: settings_import_path do |f|
-  %p.hint= t('imports.preface')
-
   .field-group
-    = f.input :type, collection: Import.types.keys, wrapper: :with_label, include_blank: false, label_method: lambda { |type| I18n.t("imports.types.#{type}") }, as: :radio_buttons, collection_wrapper_tag: 'ul', item_wrapper_tag: 'li'
+    = f.input :type, collection: Import.types.keys, wrapper: :with_block_label, include_blank: false, label_method: lambda { |type| I18n.t("imports.types.#{type}") }, hint: t('imports.preface')
 
   .field-group
     = f.input :data, wrapper: :with_block_label, hint: t('simple_form.hints.imports.data')
diff --git a/app/views/settings/preferences/show.html.haml b/app/views/settings/preferences/show.html.haml
index 9092780c3..bb267db8a 100644
--- a/app/views/settings/preferences/show.html.haml
+++ b/app/views/settings/preferences/show.html.haml
@@ -1,29 +1,32 @@
 - content_for :page_title do
   = t('settings.preferences')
 
+%ul.quick-nav
+  %li= link_to t('preferences.languages'), '#settings_languages'
+  %li= link_to t('preferences.publishing'), '#settings_publishing'
+  %li= link_to t('preferences.other'), '#settings_other'
+  %li= link_to t('preferences.web'), '#settings_web'
+
 = simple_form_for current_user, url: settings_preferences_path, html: { method: :put } do |f|
   = render 'shared/error_messages', object: current_user
 
-  .actions.actions--top
-    = f.button :button, t('generic.save_changes'), type: :submit
-
-  %h4= t 'preferences.languages'
+  .fields-row#settings_languages
+    .fields-group.fields-row__column.fields-row__column-6
+      = f.input :locale, collection: I18n.available_locales, wrapper: :with_label, include_blank: false, label_method: lambda { |locale| human_locale(locale) }, selected: I18n.locale
+    .fields-group.fields-row__column.fields-row__column-6
+      = f.input :setting_default_language, collection: [nil] + filterable_languages.sort, wrapper: :with_label, label_method: lambda { |locale| locale.nil? ? I18n.t('statuses.language_detection') : human_locale(locale) }, required: false, include_blank: false
 
   .fields-group
-    = f.input :locale, collection: I18n.available_locales, wrapper: :with_label, include_blank: false, label_method: lambda { |locale| human_locale(locale) }, selected: I18n.locale
-
-    = f.input :setting_default_language, collection: [nil] + filterable_languages.sort, wrapper: :with_label, label_method: lambda { |locale| locale.nil? ? I18n.t('statuses.language_detection') : human_locale(locale) }, required: false, include_blank: false
-
     = f.input :chosen_languages, collection: filterable_languages.sort, wrapper: :with_block_label, include_blank: false, label_method: lambda { |locale| human_locale(locale) }, required: false, as: :check_boxes, collection_wrapper_tag: 'ul', item_wrapper_tag: 'li'
 
-  %h4= t 'preferences.publishing'
+  %hr#settings_publishing/
 
   .fields-group
-    = f.input :setting_default_privacy, collection: Status.visibilities.keys - ['direct'], wrapper: :with_label, include_blank: false, label_method: lambda { |visibility| safe_join([I18n.t("statuses.visibilities.#{visibility}"), content_tag(:span, I18n.t("statuses.visibilities.#{visibility}_long"), class: 'hint')]) }, required: false, as: :radio_buttons, collection_wrapper_tag: 'ul', item_wrapper_tag: 'li'
+    = f.input :setting_default_privacy, collection: Status.visibilities.keys - ['direct'], wrapper: :with_floating_label, include_blank: false, label_method: lambda { |visibility| safe_join([I18n.t("statuses.visibilities.#{visibility}"), content_tag(:span, I18n.t("statuses.visibilities.#{visibility}_long"), class: 'hint')]) }, required: false, as: :radio_buttons, collection_wrapper_tag: 'ul', item_wrapper_tag: 'li'
 
     = f.input :setting_default_sensitive, as: :boolean, wrapper: :with_label
 
-  %h4= t 'preferences.other'
+  %hr#settings_other/
 
   .fields-group
     = f.input :setting_noindex, as: :boolean, wrapper: :with_label
@@ -31,7 +34,7 @@
   .fields-group
     = f.input :setting_hide_network, as: :boolean, wrapper: :with_label
 
-  %h4= t 'preferences.web'
+  %hr#settings_web/
 
   .fields-group
     = f.input :setting_unfollow_modal, as: :boolean, wrapper: :with_label
diff --git a/app/views/settings/profiles/show.html.haml b/app/views/settings/profiles/show.html.haml
index 1acbb9b8a..6b61fa9c9 100644
--- a/app/views/settings/profiles/show.html.haml
+++ b/app/views/settings/profiles/show.html.haml
@@ -4,16 +4,21 @@
 = simple_form_for @account, url: settings_profile_path, html: { method: :put } do |f|
   = render 'shared/error_messages', object: @account
 
-  .fields-group
-    = 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: 500 - @account.note.size).html_safe
+  .fields-row
+    .fields-row__column.fields-group.fields-row__column-6
+      = f.input :display_name, wrapper: :with_label, hint: t('simple_form.hints.defaults.display_name', count: 30 - @account.display_name.size).html_safe
+      = f.input :note, wrapper: :with_label, hint: t('simple_form.hints.defaults.note', count: 500 - @account.note.size).html_safe
 
-  = render 'application/card', account: @account
+  .fields-row
+    .fields-row__column.fields-row__column-6
+      = 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', dimensions: '400x400', size: number_to_human_size(AccountAvatar::LIMIT))
+    .fields-row__column.fields-group.fields-row__column-6
+      = f.input :avatar, wrapper: :with_label, input_html: { accept: AccountAvatar::IMAGE_MIME_TYPES.join(',') }, hint: t('simple_form.hints.defaults.avatar', dimensions: '400x400', size: number_to_human_size(AccountAvatar::LIMIT))
+
+      = f.input :header, wrapper: :with_label, input_html: { accept: AccountHeader::IMAGE_MIME_TYPES.join(',') }, hint: t('simple_form.hints.defaults.header', dimensions: '1500x500', size: number_to_human_size(AccountHeader::LIMIT))
 
-    = f.input :header, wrapper: :with_label, input_html: { accept: AccountHeader::IMAGE_MIME_TYPES.join(',') }, hint: t('simple_form.hints.defaults.header', dimensions: '1500x500', size: number_to_human_size(AccountHeader::LIMIT))
+  %hr.spacer/
 
   .fields-group
     = f.input :locked, as: :boolean, wrapper: :with_label, hint: t('simple_form.hints.defaults.locked')
@@ -21,15 +26,27 @@
   .fields-group
     = f.input :bot, as: :boolean, wrapper: :with_label, hint: t('simple_form.hints.defaults.bot')
 
-  .fields-group
-    .input.with_block_label
-      %label= t('simple_form.labels.defaults.fields')
-      %span.hint= t('simple_form.hints.defaults.fields')
+  %hr.spacer/
+
+  .fields-row
+    .fields-row__column.fields-group.fields-row__column-6
+      .input.with_block_label
+        %label= t('simple_form.labels.defaults.fields')
+        %span.hint= t('simple_form.hints.defaults.fields')
 
-      = f.simple_fields_for :fields do |fields_f|
-        .row
-          = fields_f.input :name, placeholder: t('simple_form.labels.account.fields.name')
-          = fields_f.input :value, placeholder: t('simple_form.labels.account.fields.value')
+        = f.simple_fields_for :fields do |fields_f|
+          .row
+            = fields_f.input :name, placeholder: t('simple_form.labels.account.fields.name')
+            = fields_f.input :value, placeholder: t('simple_form.labels.account.fields.value')
+
+    .fields-row__column.fields-group.fields-row__column-6
+      %h6= t('verification.verification')
+      %p.hint= t('verification.explanation_html')
+
+      .input-copy
+        .input-copy__wrapper
+          %input{ type: :text, maxlength: '999', spellcheck: 'false', readonly: 'true', value: link_to('Mastodon', ActivityPub::TagManager.instance.url_for(@account), rel: 'me').to_str }
+        %button{ type: :button }= t('generic.copy')
 
   .actions
     = f.button :button, t('generic.save_changes'), type: :submit
@@ -38,3 +55,9 @@
 
 %h6= t('auth.migrate_account')
 %p.muted-hint= t('auth.migrate_account_html', path: settings_migration_path)
+
+- if open_deletion?
+  %hr.spacer/
+
+  %h6= t('auth.delete_account')
+  %p.muted-hint= t('auth.delete_account_html', path: settings_delete_path)
diff --git a/app/views/settings/two_factor_authentication/confirmations/new.html.haml b/app/views/settings/two_factor_authentication/confirmations/new.html.haml
index fd4a3e768..e64155299 100644
--- a/app/views/settings/two_factor_authentication/confirmations/new.html.haml
+++ b/app/views/settings/two_factor_authentication/confirmations/new.html.haml
@@ -11,7 +11,8 @@
       %p.hint= t('two_factor_authentication.manual_instructions')
       %samp.qr-alternative__code= current_user.otp_secret.scan(/.{4}/).join(' ')
 
-  = f.input :code, hint: t('two_factor_authentication.code_hint'), placeholder: t('simple_form.labels.defaults.otp_attempt'), input_html: { :autocomplete => 'off' }
+  .fields-group
+    = f.input :code, wrapper: :with_label, hint: t('two_factor_authentication.code_hint'), label: t('simple_form.labels.defaults.otp_attempt'), input_html: { :autocomplete => 'off' }, required: true
 
   .actions
     = f.button :button, t('two_factor_authentication.enable'), type: :submit
diff --git a/app/views/settings/two_factor_authentications/show.html.haml b/app/views/settings/two_factor_authentications/show.html.haml
index 67a64a046..259bcd1ef 100644
--- a/app/views/settings/two_factor_authentications/show.html.haml
+++ b/app/views/settings/two_factor_authentications/show.html.haml
@@ -10,7 +10,7 @@
   %hr/
 
   = simple_form_for @confirmation, url: settings_two_factor_authentication_path, method: :delete do |f|
-    = f.input :code, hint: t('two_factor_authentication.code_hint'), placeholder: t('simple_form.labels.defaults.otp_attempt'), input_html: { :autocomplete => 'off' }
+    = f.input :code, wrapper: :with_label, hint: t('two_factor_authentication.code_hint'), label: t('simple_form.labels.defaults.otp_attempt'), input_html: { :autocomplete => 'off' }, required: true
 
     .actions
       = f.button :button, t('two_factor_authentication.disable'), type: :submit