diff --git a/app/controllers/admin/settings_controller.rb b/app/controllers/admin/settings_controller.rb
index a6214dc3fc..ce32082099 100644
--- a/app/controllers/admin/settings_controller.rb
+++ b/app/controllers/admin/settings_controller.rb
@@ -16,6 +16,7 @@ module Admin
show_staff_badge
bootstrap_timeline_accounts
thumbnail
+ hero
min_invite_role
activity_api_enabled
peers_api_enabled
@@ -34,6 +35,7 @@ module Admin
UPLOAD_SETTINGS = %w(
thumbnail
+ hero
).freeze
def edit
diff --git a/app/javascript/styles/mastodon/about.scss b/app/javascript/styles/mastodon/about.scss
index 0806171be1..a95b759840 100644
--- a/app/javascript/styles/mastodon/about.scss
+++ b/app/javascript/styles/mastodon/about.scss
@@ -1,3 +1,130 @@
+$maximum-width: 1235px;
+$fluid-breakpoint: $maximum-width + 20px;
+$column-breakpoint: 700px;
+$small-breakpoint: 960px;
+
+.container {
+ box-sizing: border-box;
+ max-width: $maximum-width;
+ margin: 0 auto;
+ position: relative;
+
+ @media screen and (max-width: $fluid-breakpoint) {
+ width: 100%;
+ padding: 0 10px;
+ }
+}
+
+.show-xs,
+.show-sm {
+ display: none;
+}
+
+.show-m {
+ display: block;
+}
+
+@media screen and (max-width: $small-breakpoint) {
+ .hide-sm {
+ display: none !important;
+ }
+
+ .show-sm {
+ display: block !important;
+ }
+}
+
+@media screen and (max-width: $column-breakpoint) {
+ .hide-xs {
+ display: none !important;
+ }
+
+ .show-xs {
+ display: block !important;
+ }
+}
+
+.row {
+ display: flex;
+ flex-wrap: wrap;
+ margin: 0 -5px;
+
+ @for $i from 1 through 15 {
+ .column-#{$i} {
+ box-sizing: border-box;
+ min-height: 1px;
+ flex: 0 0 percentage($i / 15);
+ max-width: percentage($i / 15);
+ padding: 0 5px;
+
+ @media screen and (max-width: $small-breakpoint) {
+ &-sm {
+ box-sizing: border-box;
+ min-height: 1px;
+ flex: 0 0 percentage($i / 15);
+ max-width: percentage($i / 15);
+ padding: 0 5px;
+
+ @media screen and (max-width: $column-breakpoint) {
+ max-width: 100%;
+ flex: 0 0 100%;
+ margin-bottom: 10px;
+
+ &:last-child {
+ margin-bottom: 0;
+ }
+ }
+ }
+ }
+
+ @media screen and (max-width: $column-breakpoint) {
+ max-width: 100%;
+ flex: 0 0 100%;
+ margin-bottom: 10px;
+
+ &:last-child {
+ margin-bottom: 0;
+ }
+ }
+ }
+ }
+}
+
+.column-flex {
+ display: flex;
+ flex-direction: column;
+}
+
+.separator-or {
+ position: relative;
+ margin: 40px 0;
+ text-align: center;
+
+ &::before {
+ content: "";
+ display: block;
+ width: 100%;
+ height: 0;
+ border-bottom: 1px solid rgba($ui-base-lighter-color, .6);
+ position: absolute;
+ top: 50%;
+ left: 0;
+ }
+
+ span {
+ display: inline-block;
+ background: $ui-base-color;
+ font-size: 12px;
+ font-weight: 500;
+ color: $ui-primary-color;
+ text-transform: uppercase;
+ position: relative;
+ z-index: 1;
+ padding: 0 8px;
+ cursor: default;
+ }
+}
+
.landing-page {
p,
li {
@@ -116,10 +243,14 @@
}
hr {
- border-color: rgba($ui-base-lighter-color, .6);
+ width: 100%;
+ height: 0;
+ border: 0;
+ border-bottom: 1px solid rgba($ui-base-lighter-color, .6);
+ margin: 20px 0;
}
- .container {
+ .container-alt {
width: 100%;
box-sizing: border-box;
max-width: 800px;
@@ -152,24 +283,20 @@
}
}
}
+ }
- .mascot-container {
- max-width: 800px;
- margin: 0 auto;
- position: absolute;
- top: 0;
- left: 0;
- right: 0;
- height: 100%;
+ .brand {
+ a {
+ padding-left: 0;
+ padding-right: 0;
+ color: $white;
}
- .mascot {
- position: absolute;
- bottom: -14px;
- width: auto;
- height: auto;
- left: 60px;
- z-index: 3;
+ img {
+ height: 32px;
+ position: relative;
+ top: 4px;
+ left: -10px;
}
}
@@ -177,7 +304,7 @@
line-height: 30px;
overflow: hidden;
- .container {
+ .container-alt {
display: flex;
justify-content: space-between;
}
@@ -203,21 +330,6 @@
}
}
- .brand {
- a {
- padding-left: 0;
- padding-right: 0;
- color: $white;
- }
-
- img {
- height: 32px;
- position: relative;
- top: 4px;
- left: -10px;
- }
- }
-
ul {
list-style: none;
margin: 0;
@@ -243,53 +355,6 @@
align-items: center;
position: relative;
- .floats {
- position: absolute;
- width: 100%;
- height: 100%;
- top: 0;
- left: 0;
-
- div {
- position: absolute;
- transition: all 0.1s linear;
- animation-name: floating;
- animation-iteration-count: infinite;
- animation-direction: alternate;
- animation-timing-function: ease-in-out;
- z-index: 2;
- }
-
- .float-1 {
- width: 324px;
- height: 170px;
- right: -120px;
- bottom: 0;
- animation-duration: 3s;
- background-image: url('data:image/svg+xml;utf8,');
- }
-
- .float-2 {
- width: 241px;
- height: 100px;
- right: 210px;
- bottom: 0;
- animation-duration: 3.5s;
- animation-delay: 0.2s;
- background-image: url('data:image/svg+xml;utf8,');
- }
-
- .float-3 {
- width: 267px;
- height: 140px;
- right: 110px;
- top: -30px;
- animation-duration: 4s;
- animation-delay: 0.5s;
- background-image: url('data:image/svg+xml;utf8,');
- }
- }
-
.heading {
position: relative;
z-index: 4;
@@ -346,18 +411,18 @@
background: darken($ui-base-color, 4%);
padding: 20px 0;
- .container {
+ .container-alt {
position: relative;
padding-right: 280px + 15px;
}
- .information-board-sections {
+ &__sections {
display: flex;
justify-content: space-between;
flex-wrap: wrap;
}
- .section {
+ &__section {
flex: 1 0 0;
font-family: 'mastodon-font-sans-serif', sans-serif;
font-size: 16px;
@@ -382,6 +447,10 @@
font-size: 32px;
line-height: 48px;
}
+
+ @media screen and (max-width: $column-breakpoint) {
+ text-align: center;
+ }
}
.panel {
@@ -460,111 +529,282 @@
}
}
- .features {
- padding: 50px 0;
+ &.alternative {
+ padding: 10px 0;
- .container {
- display: flex;
+ .brand {
+ text-align: center;
+ padding: 30px 0;
+ margin-bottom: 10px;
+
+ img {
+ position: static;
+ }
+
+ @media screen and (max-width: $small-breakpoint) {
+ padding: 15px 0;
+ }
+
+ @media screen and (max-width: $column-breakpoint) {
+ padding: 0;
+ margin-bottom: -10px;
+ }
+ }
+ }
+
+ &__information,
+ &__forms {
+ padding: 20px;
+ }
+
+ &__call-to-action {
+ margin-bottom: 10px;
+ background: darken($ui-base-color, 4%);
+ border-radius: 4px;
+ padding: 25px 40px;
+ overflow: hidden;
+
+ .row {
+ align-items: center;
}
- #mastodon-timeline {
- display: flex;
- -webkit-overflow-scrolling: touch;
- -ms-overflow-style: -ms-autohiding-scrollbar;
- font-family: 'mastodon-font-sans-serif', sans-serif;
- font-size: 13px;
- line-height: 18px;
- font-weight: 400;
+ .information-board__section {
+ padding: 0;
+ }
+ }
+
+ &__logo {
+ margin-right: 20px;
+
+ img {
+ height: 50px;
+ width: auto;
+ mix-blend-mode: lighten;
+ }
+ }
+
+ &__information {
+ padding: 45px 40px;
+ margin-bottom: 10px;
+
+ &:last-child {
+ margin-bottom: 0;
+ }
+
+ @media screen and (max-width: $column-breakpoint) {
+ padding: 25px 20px;
+ }
+ }
+
+ &__information,
+ &__forms,
+ #mastodon-timeline {
+ box-sizing: border-box;
+ background: $ui-base-color;
+ border-radius: 4px;
+ box-shadow: 0 0 6px rgba($black, 0.1);
+ }
+
+ &__mascot {
+ height: 104px;
+ position: relative;
+ left: -40px;
+ bottom: 25px;
+
+ img {
+ height: 190px;
+ width: auto;
+ }
+ }
+
+ &__short-description {
+ .row {
+ align-items: center;
+ margin-bottom: 40px;
+ }
+
+ @media screen and (max-width: $column-breakpoint) {
+ .row {
+ margin-bottom: 20px;
+ }
+ }
+
+ p a {
+ color: $ui-secondary-color;
+ }
+
+ h1 {
+ font-weight: 500;
color: $primary-text-color;
- width: 330px;
- margin-right: 30px;
- flex: 0 0 auto;
- background: $ui-base-color;
- overflow: hidden;
- border-radius: 4px;
- box-shadow: 0 0 6px rgba($black, 0.1);
+ margin-bottom: 0;
- .column-header {
- color: inherit;
- font-family: inherit;
- font-size: 16px;
- line-height: inherit;
- font-weight: inherit;
- margin: 0;
- padding: 0;
- }
+ small {
+ color: $ui-primary-color;
- .column {
- padding: 0;
- border-radius: 4px;
- overflow: hidden;
- }
-
- .scrollable {
- height: 400px;
- }
-
- p {
- font-size: inherit;
- line-height: inherit;
- font-weight: inherit;
- color: $primary-text-color;
- margin-bottom: 20px;
-
- &:last-child {
- margin-bottom: 0;
- }
-
- a {
+ span {
color: $ui-secondary-color;
- text-decoration: none;
}
}
}
- .about-mastodon {
- max-width: 675px;
+ p:last-child {
+ margin-bottom: 0;
+ }
+ }
- p {
- margin-bottom: 20px;
+ &__hero {
+ margin-bottom: 10px;
+
+ img {
+ display: block;
+ margin: 0;
+ max-width: 100%;
+ height: auto;
+ border-radius: 4px;
+ }
+ }
+
+ &__forms {
+ height: 100%;
+
+ @media screen and (max-width: $small-breakpoint) {
+ margin-bottom: 10px;
+ height: auto;
+ }
+
+ @media screen and (max-width: $column-breakpoint) {
+ background: transparent;
+ box-shadow: none;
+ padding: 0 20px;
+ margin-top: 30px;
+ margin-bottom: 40px;
+
+ .separator-or {
+ span {
+ background: darken($ui-base-color, 8%);
+ }
+ }
+ }
+
+ hr {
+ margin: 40px 0;
+ }
+
+ .button {
+ display: block;
+ }
+
+ .subtle-hint a {
+ text-decoration: none;
+
+ &:hover,
+ &:focus,
+ &:active {
+ text-decoration: underline;
+ }
+ }
+ }
+
+ #mastodon-timeline {
+ display: flex;
+ -webkit-overflow-scrolling: touch;
+ -ms-overflow-style: -ms-autohiding-scrollbar;
+ font-family: 'mastodon-font-sans-serif', sans-serif;
+ font-size: 13px;
+ line-height: 18px;
+ font-weight: 400;
+ color: $primary-text-color;
+ width: 100%;
+ flex: 1 1 auto;
+ overflow: hidden;
+
+ .column-header {
+ color: inherit;
+ font-family: inherit;
+ font-size: 16px;
+ line-height: inherit;
+ font-weight: inherit;
+ margin: 0;
+ padding: 0;
+ }
+
+ .column {
+ padding: 0;
+ border-radius: 4px;
+ overflow: hidden;
+ width: 100%;
+ }
+
+ .scrollable {
+ height: 400px;
+ }
+
+ p {
+ font-size: inherit;
+ line-height: inherit;
+ font-weight: inherit;
+ color: $primary-text-color;
+ margin-bottom: 20px;
+
+ &:last-child {
+ margin-bottom: 0;
}
- .features-list {
- margin-top: 20px;
+ a {
+ color: $ui-secondary-color;
+ text-decoration: none;
+ }
+ }
- .features-list__row {
- display: flex;
- padding: 10px 0;
- justify-content: space-between;
+ @media screen and (max-width: $column-breakpoint) {
+ height: 90vh;
+ }
+ }
- &:first-child {
- padding-top: 0;
- }
+ &__features {
+ .features-list {
+ margin: 40px 0 !important;
+ }
- .visual {
- flex: 0 0 auto;
- display: flex;
- align-items: center;
- margin-left: 15px;
+ &__action {
+ text-align: center;
+ }
+ }
- .fa {
- display: block;
- color: $ui-primary-color;
- font-size: 48px;
- }
- }
+ .features-list {
+ margin-top: 20px;
- .text {
- font-size: 16px;
- line-height: 30px;
- color: $ui-primary-color;
+ .features-list__row {
+ display: flex;
+ padding: 10px 0;
+ justify-content: space-between;
- h6 {
- font-size: inherit;
- line-height: inherit;
- margin-bottom: 0;
- }
- }
+ &:first-child {
+ padding-top: 0;
+ }
+
+ .visual {
+ flex: 0 0 auto;
+ display: flex;
+ align-items: center;
+ margin-left: 15px;
+
+ .fa {
+ display: block;
+ color: $ui-primary-color;
+ font-size: 48px;
+ }
+ }
+
+ .text {
+ font-size: 16px;
+ line-height: 30px;
+ color: $ui-primary-color;
+
+ h6 {
+ font-size: inherit;
+ line-height: inherit;
+ margin-bottom: 0;
}
}
}
@@ -600,21 +840,31 @@
}
}
+ &__footer {
+ margin-top: 10px;
+ text-align: center;
+ color: $ui-base-lighter-color;
+
+ p {
+ font-size: 14px;
+
+ a {
+ color: inherit;
+ text-decoration: underline;
+ }
+ }
+ }
+
@media screen and (max-width: 840px) {
- .container {
+ .container-alt {
padding: 0 20px;
}
.information-board {
-
- .container {
+ .container-alt {
padding-right: 20px;
}
- .section {
- text-align: center;
- }
-
.panel {
position: static;
margin-top: 20px;
@@ -626,16 +876,6 @@
}
}
}
-
- .header-wrapper .mascot {
- left: 20px;
- }
- }
-
- @media screen and (max-width: 689px) {
- .header-wrapper .mascot {
- display: none;
- }
}
@media screen and (max-width: 675px) {
@@ -651,13 +891,12 @@
}
}
- .header .container,
- .features .container {
+ .header .container-alt,
+ .features .container-alt {
display: block;
}
.header {
-
.links {
padding-top: 15px;
background: darken($ui-base-color, 4%);
@@ -682,10 +921,6 @@
margin-top: 30px;
padding: 0;
- .floats {
- display: none;
- }
-
.heading {
padding: 30px 20px;
text-align: center;
@@ -700,16 +935,6 @@
}
}
}
-
- .features #mastodon-timeline {
- height: 70vh;
- width: 100%;
- margin-bottom: 50px;
-
- .column {
- width: 100%;
- }
- }
}
.cta {
@@ -720,7 +945,7 @@
.features {
padding: 30px 0;
- .container {
+ .container-alt {
max-width: 820px;
#mastodon-timeline {
@@ -772,7 +997,7 @@
.features {
padding: 10px 0;
- .container {
+ .container-alt {
display: flex;
flex-direction: column;
@@ -808,17 +1033,3 @@
}
}
}
-
-@keyframes floating {
- from {
- transform: translate(0, 0);
- }
-
- 65% {
- transform: translate(0, 4px);
- }
-
- to {
- transform: translate(0, -0);
- }
-}
diff --git a/app/javascript/styles/mastodon/components.scss b/app/javascript/styles/mastodon/components.scss
index cff7078aab..0224009ee1 100644
--- a/app/javascript/styles/mastodon/components.scss
+++ b/app/javascript/styles/mastodon/components.scss
@@ -40,14 +40,20 @@
cursor: default;
}
- &.button-alternative {
+ &.button-primary,
+ &.button-alternative,
+ &.button-secondary,
+ &.button-alternative-2 {
font-size: 16px;
line-height: 36px;
height: auto;
- color: $ui-base-color;
- background: $ui-primary-color;
text-transform: none;
padding: 4px 16px;
+ }
+
+ &.button-alternative {
+ color: $ui-base-color;
+ background: $ui-primary-color;
&:active,
&:focus,
@@ -56,15 +62,20 @@
}
}
+ &.button-alternative-2 {
+ background: $ui-base-lighter-color;
+
+ &:active,
+ &:focus,
+ &:hover {
+ background-color: lighten($ui-base-lighter-color, 4%);
+ }
+ }
+
&.button-secondary {
- font-size: 16px;
- line-height: 36px;
- height: auto;
color: $ui-primary-color;
- text-transform: none;
background: transparent;
padding: 3px 15px;
- border-radius: 4px;
border: 1px solid $ui-primary-color;
&:active,
diff --git a/app/javascript/styles/mastodon/containers.scss b/app/javascript/styles/mastodon/containers.scss
index af2589e23c..6fa1fa38f5 100644
--- a/app/javascript/styles/mastodon/containers.scss
+++ b/app/javascript/styles/mastodon/containers.scss
@@ -1,4 +1,4 @@
-.container {
+.container-alt {
width: 700px;
margin: 0 auto;
margin-top: 40px;
diff --git a/app/presenters/instance_presenter.rb b/app/presenters/instance_presenter.rb
index 4c1124d599..e4972c9623 100644
--- a/app/presenters/instance_presenter.rb
+++ b/app/presenters/instance_presenter.rb
@@ -39,4 +39,8 @@ class InstancePresenter
def thumbnail
@thumbnail ||= Rails.cache.fetch('site_uploads/thumbnail') { SiteUpload.find_by(var: 'thumbnail') }
end
+
+ def hero
+ @hero ||= Rails.cache.fetch('site_uploads/hero') { SiteUpload.find_by(var: 'hero') }
+ end
end
diff --git a/app/views/about/_forms.html.haml b/app/views/about/_forms.html.haml
new file mode 100644
index 0000000000..9916b6bf4c
--- /dev/null
+++ b/app/views/about/_forms.html.haml
@@ -0,0 +1,14 @@
+- if @instance_presenter.open_registrations
+ = render 'registration'
+- else
+ - if @instance_presenter.closed_registrations_message.blank?
+ %p= t('about.closed_registrations')
+ - else
+ = @instance_presenter.closed_registrations_message.html_safe
+
+ = link_to t('auth.register'), 'https://joinmastodon.org', class: 'button button-primary'
+
+.separator-or
+ %span= t('auth.or')
+
+= link_to t('auth.login'), new_user_session_path, class: 'button button-alternative-2 webapp-btn'
diff --git a/app/views/about/_links.html.haml b/app/views/about/_links.html.haml
index ccf4f08b95..f79c37e658 100644
--- a/app/views/about/_links.html.haml
+++ b/app/views/about/_links.html.haml
@@ -1,4 +1,4 @@
-.container.links
+.container-alt.links
.brand
= link_to root_url do
= image_tag asset_pack_path('logo_full.svg'), alt: 'Mastodon'
diff --git a/app/views/about/_registration.html.haml b/app/views/about/_registration.html.haml
index 7a28f97388..6ca1d71290 100644
--- a/app/views/about/_registration.html.haml
+++ b/app/views/about/_registration.html.haml
@@ -10,6 +10,6 @@
= 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' }
.actions
- = f.button :button, t('auth.register'), type: :submit, class: 'button button-alternative'
+ = f.button :button, t('auth.register'), type: :submit, class: 'button button-primary'
%p.hint.subtle-hint=t('auth.agreement_html', rules_path: about_more_path, terms_path: terms_path)
diff --git a/app/views/about/more.html.haml b/app/views/about/more.html.haml
index 9c9580eac2..df072b8aec 100644
--- a/app/views/about/more.html.haml
+++ b/app/views/about/more.html.haml
@@ -10,34 +10,34 @@
.header
= render 'links'
- .container.hero
+ .container-alt.hero
.heading
%h3= t('about.description_headline', domain: site_hostname)
%p= @instance_presenter.site_description.html_safe.presence || t('about.generic_description', domain: site_hostname)
.information-board
- .container
- .information-board-sections
- .section
+ .container-alt
+ .information-board__sections
+ .information-board__section
%span= t 'about.user_count_before'
%strong= number_with_delimiter @instance_presenter.user_count
%span= t 'about.user_count_after'
- .section
+ .information-board__section
%span= t 'about.status_count_before'
%strong= number_with_delimiter @instance_presenter.status_count
%span= t 'about.status_count_after'
- .section
+ .information-board__section
%span= t 'about.domain_count_before'
%strong= number_with_delimiter @instance_presenter.domain_count
%span= t 'about.domain_count_after'
= render 'contact', contact: @instance_presenter
.extended-description
- .container
+ .container-alt
= @instance_presenter.site_extended_description.html_safe.presence || t('about.extended_description_html')
.footer-links
- .container
+ .container-alt
%p
= link_to t('about.source_code'), @instance_presenter.source_url
= " (#{@instance_presenter.version_number})"
diff --git a/app/views/about/show.html.haml b/app/views/about/show.html.haml
index b7c08479da..fd1cda8b39 100644
--- a/app/views/about/show.html.haml
+++ b/app/views/about/show.html.haml
@@ -6,51 +6,74 @@
= javascript_pack_tag 'about', integrity: true, crossorigin: 'anonymous'
= render partial: 'shared/og'
-.landing-page
- .header-wrapper
- .mascot-container
- = image_tag asset_pack_path('elephant-fren.png'), alt: '', role: 'presentation', class: 'mascot'
+.landing-page.alternative
+ .container
+ .row
+ .column-4.hide-sm.show-xs.show-m
+ .landing-page__forms
+ .brand
+ = link_to root_url do
+ = image_tag asset_pack_path('logo_full.svg'), alt: 'Mastodon'
- .header
- = render 'links'
+ .hide-xs
+ = render 'forms'
- .container.hero
- .floats
- %div{ role: 'presentation', class: 'float-1' }
- %div{ role: 'presentation', class: 'float-2' }
- %div{ role: 'presentation', class: 'float-3' }
- .heading
- %h1
- = @instance_presenter.site_title
- %small= t 'about.hosted_on', domain: site_hostname
- - if @instance_presenter.open_registrations
- = render 'registration'
- - else
- .closed-registrations-message
- %div
- - if @instance_presenter.closed_registrations_message.blank?
- %p= t('about.closed_registrations')
- - else
- = @instance_presenter.closed_registrations_message.html_safe
- = link_to t('about.find_another_instance'), 'https://joinmastodon.org/', class: 'button button-alternative button--block'
+ .column-7.column-9-sm
+ .landing-page__hero
+ = image_tag @instance_presenter.hero&.file&.url || @instance_presenter.thumbnail&.file&.url || asset_pack_path('preview.jpg'), alt: @instance_presenter.site_title
- .about-short
- .container
- %h3= t('about.description_headline', domain: site_hostname)
- %p= @instance_presenter.site_description.html_safe.presence || t('about.generic_description', domain: site_hostname)
+ .landing-page__information
+ .landing-page__short-description
+ .row
+ .landing-page__logo.hide-xs
+ = image_tag asset_pack_path('logo_transparent.svg'), alt: 'Mastodon'
- .features
- .container
- - if Setting.timeline_preview
- #mastodon-timeline{ data: { props: Oj.dump(default_props) } }
+ %h1
+ = @instance_presenter.site_title
+ %small!= t 'about.hosted_on', domain: content_tag(:span, site_hostname)
- .about-mastodon
- %h3= t 'about.what_is_mastodon'
- %p= t 'about.about_mastodon_html'
- = link_to t('about.learn_more'), 'https://joinmastodon.org/', class: 'button button-secondary'
- = render 'features'
- .footer-links
- .container
- %p
- = link_to t('about.source_code'), @instance_presenter.source_url
- = " (#{@instance_presenter.version_number})"
+ %p= @instance_presenter.site_description.html_safe.presence || t('about.generic_description', domain: site_hostname)
+
+ .show-xs
+ .landing-page__forms
+ = render 'forms'
+ .landing-page__call-to-action.hide-xs
+ .row
+ .column-5
+ .landing-page__mascot
+ = image_tag asset_pack_path('elephant_ui_plane.svg')
+ .column-5
+ .information-board__section
+ %span= t 'about.user_count_before'
+ %strong= number_with_delimiter @instance_presenter.user_count
+ %span= t 'about.user_count_after'
+ .column-5
+ .information-board__section
+ %span= t 'about.status_count_before'
+ %strong= number_with_delimiter @instance_presenter.status_count
+ %span= t 'about.status_count_after'
+ .landing-page__information
+ .landing-page__features
+ %h3= t 'about.what_is_mastodon'
+ %p= t 'about.about_mastodon_html'
+
+ = render 'features'
+
+ .landing-page__features__action
+ = link_to t('about.learn_more'), 'https://joinmastodon.org/', class: 'button button-alternative'
+
+ .landing-page__footer
+ %p
+ = link_to t('about.source_code'), @instance_presenter.source_url
+ = " (#{@instance_presenter.version_number})"
+
+ .column-4.column-6-sm.column-flex
+ .show-sm.hide-xs
+ .landing-page__forms
+ .brand
+ = link_to root_url do
+ = image_tag asset_pack_path('logo_full.svg'), alt: 'Mastodon'
+
+ = render 'forms'
+ - if Setting.timeline_preview
+ #mastodon-timeline{ data: { props: Oj.dump(default_props) } }
diff --git a/app/views/about/terms.html.haml b/app/views/about/terms.html.haml
index ba780759ce..c7d36ed47a 100644
--- a/app/views/about/terms.html.haml
+++ b/app/views/about/terms.html.haml
@@ -7,5 +7,5 @@
= render 'links'
.extended-description
- .container
+ .container-alt
= @instance_presenter.site_terms.html_safe.presence || t('terms.body_html')
diff --git a/app/views/admin/settings/edit.html.haml b/app/views/admin/settings/edit.html.haml
index 73fd5642ee..08d05d7385 100644
--- a/app/views/admin/settings/edit.html.haml
+++ b/app/views/admin/settings/edit.html.haml
@@ -12,6 +12,7 @@
.fields-group
= 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')
%hr/
diff --git a/config/locales/ar.yml b/config/locales/ar.yml
index eadeaef3ea..88b4d88bb2 100644
--- a/config/locales/ar.yml
+++ b/config/locales/ar.yml
@@ -14,7 +14,6 @@ ar:
humane_approach_title: أسلوب يعيد الإعتبار للإنسان
not_a_product_title: إنك إنسان و لست سلعة
real_conversation_title: مبني لتحقيق تواصل حقيقي
- find_another_instance: إبحث عن مثيل خادوم آخر
generic_description: "%{domain} هو سيرفر من بين سيرفرات الشبكة"
hosted_on: ماستدون مُستضاف على %{domain}
learn_more: تعلم المزيد
diff --git a/config/locales/ca.yml b/config/locales/ca.yml
index 126e488d92..a685950a2d 100644
--- a/config/locales/ca.yml
+++ b/config/locales/ca.yml
@@ -23,7 +23,6 @@ ca:
real_conversation_title: Construït per a converses reals
within_reach_body: Diverses aplicacions per a iOS, Android i altres plataformes gràcies a un ecosistema API amable amb el desenvolupador, et permet mantenir-te al dia amb els amics en qualsevol lloc..
within_reach_title: Sempre a l'abast
- find_another_instance: Troba altres instàncies
generic_description: "%{domain} és un servidor a la xarxa"
hosted_on: Mastodon allotjat a %{domain}
learn_more: Més informació
diff --git a/config/locales/de.yml b/config/locales/de.yml
index f03e393f52..8f17413e10 100644
--- a/config/locales/de.yml
+++ b/config/locales/de.yml
@@ -23,7 +23,6 @@ de:
real_conversation_title: Für das echte Gespräch gemacht
within_reach_body: Verschiedene Apps für iOS, Android und andere Plattformen erlauben dir dank unserem blühenden API-Ökosystem, dich von überall auf dem Laufenden zu halten.
within_reach_title: Immer für dich da
- find_another_instance: Eine andere Instanz finden
generic_description: "%{domain} ist ein Server im Netzwerk"
hosted_on: Mastodon, beherbergt auf %{domain}
learn_more: Mehr erfahren
diff --git a/config/locales/en.yml b/config/locales/en.yml
index b9dd5bd51f..071c412909 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -23,7 +23,6 @@ en:
real_conversation_title: Built for real conversation
within_reach_body: Multiple apps for iOS, Android, and other platforms thanks to a developer-friendly API ecosystem allow you to keep up with your friends anywhere.
within_reach_title: Always within reach
- find_another_instance: Find another instance
generic_description: "%{domain} is one server in the network"
hosted_on: Mastodon hosted on %{domain}
learn_more: Learn more
@@ -274,6 +273,9 @@ en:
contact_information:
email: Business e-mail
username: Contact username
+ hero:
+ desc_html: Displayed on the frontpage. At least 600x100px recommended. When not set, falls back to instance thumbnail
+ title: Hero image
peers_api_enabled:
desc_html: Domain names this instance has encountered in the fediverse
title: Publish list of discovered instances
diff --git a/config/locales/es.yml b/config/locales/es.yml
index 1ad8539de2..9eb61aaac5 100644
--- a/config/locales/es.yml
+++ b/config/locales/es.yml
@@ -23,7 +23,6 @@ es:
real_conversation_title: Hecho para verdaderas conversaciones
within_reach_body: Aplicaciones múltiples para iOS, Android, y otras plataformas gracias a un ecosistema de APIs amigable al desarrollador para permitirte estar con tus amigos donde sea.
within_reach_title: Siempre al alcance
- find_another_instance: Busca otra instancia
generic_description: "%{domain} es un servidor en la red"
hosted_on: Mastodon hosteado en %{domain}
learn_more: Aprende más
diff --git a/config/locales/fa.yml b/config/locales/fa.yml
index c498c592c0..395d226bd2 100644
--- a/config/locales/fa.yml
+++ b/config/locales/fa.yml
@@ -23,7 +23,6 @@ fa:
real_conversation_title: برای گفتگوهای واقعی
within_reach_body: اپهای متنوع برای iOS، اندروید، و سیستمهای دیگر به خاطر وجود یک اکوسیستم API دوستانه برای برنامهنویسان. از همه جا با دوستان خود ارتباط داشته باشید.
within_reach_title: همیشه در دسترس
- find_another_instance: یافتن سرورهای دیگر
generic_description: "%{domain} یک سرور روی شبکه است"
hosted_on: ماستدون، میزبانیشده روی %{domain}
learn_more: بیشتر بدانید
diff --git a/config/locales/fi.yml b/config/locales/fi.yml
index 1067496c90..e9c7273ce6 100644
--- a/config/locales/fi.yml
+++ b/config/locales/fi.yml
@@ -21,7 +21,6 @@ fi:
real_conversation_title: Rakennettu oikealle keskustelulle
within_reach_body: Kehittäjäystävällisen rajapintaekosysteemin ansiosta useita appeja Androidille, iOS:lle ja muille alustoille, jotka mahdollistavat yhteydenpidon ystäviesi kanssa missä vain.
within_reach_title: Aina lähellä
- find_another_instance: Löydä toinen instanssi
learn_more: Lisätietoja
other_instances: Muut palvelimet
source_code: Lähdekoodi
diff --git a/config/locales/fr.yml b/config/locales/fr.yml
index f0fc07f7a1..02d6f131c3 100644
--- a/config/locales/fr.yml
+++ b/config/locales/fr.yml
@@ -23,7 +23,6 @@ fr:
real_conversation_title: Construit pour de vraies conversations
within_reach_body: Grâce à l’existence d’un environnement API accueillant pour les développeur·se·s, de multiples applications pour iOS, Android et d’autres plateformes vous permettent de rester en contact avec vos ami·e·s où que vous soyez.
within_reach_title: Toujours à portée de main
- find_another_instance: Trouver une autre instance
generic_description: "%{domain} est seulement un serveur du réseau"
hosted_on: Instance Mastodon hébergée par %{domain}
learn_more: En savoir plus
diff --git a/config/locales/gl.yml b/config/locales/gl.yml
index 40d72cbe4e..5de6031fca 100644
--- a/config/locales/gl.yml
+++ b/config/locales/gl.yml
@@ -23,7 +23,6 @@ gl:
real_conversation_title: Construído para conversacións reais
within_reach_body: Existen múltiples aplicativos para iOS, Android e outras plataformas grazas a un entorno API amigable para o desenvolvedor que lle permite estar ao tanto cos seus amigos en calquer lugar.
within_reach_title: Sempre en contacto
- find_another_instance: Atope outra instancia
generic_description: "%{domain} é un servidor na rede"
hosted_on: Mastodon aloxado en %{domain}
learn_more: Coñeza máis
diff --git a/config/locales/he.yml b/config/locales/he.yml
index 1f27dda7a5..c83f4ba10e 100644
--- a/config/locales/he.yml
+++ b/config/locales/he.yml
@@ -23,7 +23,6 @@ he:
real_conversation_title: בנוי לשיחות אמתיות
within_reach_body: שלל אפליקציות עבור iOS, אנדרואיד ופלטפורמות אחרות שיאפשרו לך לשמור על קשר עם חברים בכל מקום, תודות למערכת מנשקי תוכנה ידידותיים למפתחים.
within_reach_title: תמיד במרחק נגיעה
- find_another_instance: לאיתור שרת אחר
generic_description: "%{domain} הוא שרת אחד בתוך הרשת"
hosted_on: מסטודון שיושב בכתובת %{domain}
learn_more: מידע נוסף
diff --git a/config/locales/hu.yml b/config/locales/hu.yml
index 6e39f98003..918e85d1f5 100644
--- a/config/locales/hu.yml
+++ b/config/locales/hu.yml
@@ -23,7 +23,6 @@ hu:
real_conversation_title: Valódi beszélgetésekre tervezve
within_reach_body: A fejlesztőbarát API-nak köszönhetően számos iOS, Android és egyéb platformra írt alkalmazás teszi lehetővé, hogy bármikor, bárhonnan részt vehess a társalgásban.
within_reach_title: Mindig elérhetőnek lenni
- find_another_instance: További instanciák keresése
generic_description: "%{domain} csak egy a számtalan szerver közül a föderációban"
hosted_on: "%{domain} Mastodon instancia"
learn_more: Tudj meg többet
diff --git a/config/locales/ja.yml b/config/locales/ja.yml
index 14a42fd76d..b1c22d5f92 100644
--- a/config/locales/ja.yml
+++ b/config/locales/ja.yml
@@ -23,7 +23,6 @@ ja:
real_conversation_title: 本当のコミュニケーションのために
within_reach_body: デベロッパーフレンドリーな API により実現された、iOS や Android、その他様々なプラットフォームのためのアプリでどこでも友人とやりとりできます。
within_reach_title: いつでも身近に
- find_another_instance: 他のインスタンスを探す
generic_description: "%{domain} は、Mastodon インスタンスの一つです"
hosted_on: Mastodon hosted on %{domain}
learn_more: もっと詳しく
diff --git a/config/locales/ko.yml b/config/locales/ko.yml
index 6f13715311..8bc318d7bc 100644
--- a/config/locales/ko.yml
+++ b/config/locales/ko.yml
@@ -23,7 +23,6 @@ ko:
real_conversation_title: 진정한 커뮤니케이션을 위하여
within_reach_body: 개발자 친화적인 API에 의해서 실현된 iOS나 Android, 그 외의 여러 Platform들 덕분에 어디서든 친구들과 자유롭게 메세지를 주고 받을 수 있습니다.
within_reach_title: 언제나 유저의 곁에서
- find_another_instance: 다른 인스턴스 찾기
generic_description: "%{domain} 은 Mastodon의 인스턴스 입니다."
hosted_on: "%{domain}에서 호스팅 되는 마스토돈"
learn_more: 자세히
diff --git a/config/locales/nl.yml b/config/locales/nl.yml
index f1af8ac0ea..9f2825e7fa 100644
--- a/config/locales/nl.yml
+++ b/config/locales/nl.yml
@@ -23,7 +23,6 @@ nl:
real_conversation_title: Voor echte gesprekken gemaakt
within_reach_body: Meerdere apps voor iOS, Android en andere platformen, met dank aan het ontwikkelaarsvriendelijke API-systeem, zorgen ervoor dat je overal op de hoogte blijft.
within_reach_title: Altijd binnen bereik
- find_another_instance: Vind een andere server
generic_description: "%{domain} is een server in het Mastodonnetwerk"
hosted_on: Mastodon op %{domain}
learn_more: Meer leren
diff --git a/config/locales/no.yml b/config/locales/no.yml
index 1e9597a536..d198177cd1 100644
--- a/config/locales/no.yml
+++ b/config/locales/no.yml
@@ -23,7 +23,6 @@
real_conversation_title: Laget for ekte samtaler
within_reach_body: Takket være et utviklingsvennlig API-økosystem vil flere apper for iOS, Android og andre plattformer la deg holde kontakten med dine venner hvor som helst.
within_reach_title: Alltid innen rekkevidde
- find_another_instance: Finn en annen instans
generic_description: "%{domain} er en tjener i nettverket"
hosted_on: Mastodon driftet på %{domain}
learn_more: Lær mer
diff --git a/config/locales/oc.yml b/config/locales/oc.yml
index 56554610d6..80b1037630 100644
--- a/config/locales/oc.yml
+++ b/config/locales/oc.yml
@@ -23,7 +23,6 @@ oc:
real_conversation_title: Fach per de conversacions vertadièras
within_reach_body: Multiplas aplicacion per iOS, Android, e autras plataformas mercés a un entorn API de bon utilizar, vos permet de gardar lo contacte pertot.
within_reach_title: Totjorn al costat
- find_another_instance: Trobar mai instàncias
generic_description: "%{domain} es un dels servidors del malhum"
hosted_on: Mastodon albergat sus %{domain}
learn_more: Ne saber mai
diff --git a/config/locales/pl.yml b/config/locales/pl.yml
index 010b03ed29..950a70d066 100644
--- a/config/locales/pl.yml
+++ b/config/locales/pl.yml
@@ -23,7 +23,6 @@ pl:
real_conversation_title: Zaprojektowany do prawdziwych rozmów
within_reach_body: Wiele aplikacji dla Androida, iOS i innych platform dzięki przyjaznemu programistom API sprawia, że możesz utrzymywać kontakt ze znajomymi praktycznie wszędzie.
within_reach_title: Zawsze w Twoim zasięgu
- find_another_instance: Znajdź inną instancję
generic_description: "%{domain} jest jednym z serwerów sieci"
hosted_on: Mastodon uruchomiony na %{domain}
learn_more: Dowiedz się więcej
diff --git a/config/locales/pt-BR.yml b/config/locales/pt-BR.yml
index 31481ced46..0da8d957a6 100644
--- a/config/locales/pt-BR.yml
+++ b/config/locales/pt-BR.yml
@@ -23,7 +23,6 @@ pt-BR:
real_conversation_title: Feito para conversas reais
within_reach_body: Vários apps para iOS, Android e outras plataformas graças a um ecossistema de API amigável para desenvolvedores permitem que você possa se manter atualizado sobre seus amigos de qualquer lugar.
within_reach_title: Sempre ao seu alcance
- find_another_instance: Encontre outra instância
generic_description: "%{domain} é um servidor na rede"
hosted_on: Mastodon hospedado em %{domain}
learn_more: Saiba mais
diff --git a/config/locales/pt.yml b/config/locales/pt.yml
index 93eaf84d6d..c77368e3f8 100644
--- a/config/locales/pt.yml
+++ b/config/locales/pt.yml
@@ -23,7 +23,6 @@ pt:
real_conversation_title: Feito para conversas reais
within_reach_body: Várias aplicações para iOS, Android e outras plataformas graças a um ecossistema de API amigável para desenvolvedores, permitem-te que te mantenhas em contacto com os teus amigos em qualquer lugar.
within_reach_title: Sempre ao teu alcance
- find_another_instance: Encontra outra instância
generic_description: "%{domain} é um servidor na rede"
hosted_on: Mastodon em %{domain}
learn_more: Saber mais
diff --git a/config/locales/ru.yml b/config/locales/ru.yml
index 842fd7d544..467f24ca8d 100644
--- a/config/locales/ru.yml
+++ b/config/locales/ru.yml
@@ -23,7 +23,6 @@ ru:
real_conversation_title: Создан для настоящего общения
within_reach_body: Различные приложения для iOS, Android и других платформ, написанные благодаря дружественной к разработчикам экосистеме API, позволят Вам держать связь с Вашими друзьями где угодно.
within_reach_title: Всегда под рукой
- find_another_instance: Найти другой узел
generic_description: "%{domain} - один из серверов сети"
hosted_on: Mastodon размещен на %{domain}
learn_more: Узнать больше
diff --git a/config/locales/sk.yml b/config/locales/sk.yml
index 84433a209e..8539885462 100644
--- a/config/locales/sk.yml
+++ b/config/locales/sk.yml
@@ -23,7 +23,6 @@ sk:
real_conversation_title: Vytvorený pre reálnu konverzáciu
within_reach_body: Viacero aplikácií pre iOS, Android a iné platformy, ktoré vďaka jednoduchému API ekosystému vám dovoľujú byť online so svojimi priateľmi kdekoľvek.
within_reach_title: Stále v dosahu
- find_another_instance: Nájdi inú inštanciu
generic_description: "%{domain} je jeden server v sieti"
hosted_on: Mastodon hostovaný na %{domain}
learn_more: Dozvedieť sa viac
diff --git a/config/locales/sr-Latn.yml b/config/locales/sr-Latn.yml
index ac80e81ec7..4eed44345b 100644
--- a/config/locales/sr-Latn.yml
+++ b/config/locales/sr-Latn.yml
@@ -23,7 +23,6 @@ sr-Latn:
real_conversation_title: Pravljen za pravi razgovor
within_reach_body: Više aplikacija za iOS, Android, kao i druge platforme zahvaljujući ekosistemu dobrih API-ja će Vam omogućiti da ostanete u kontaktu sa prijateljima svuda.
within_reach_title: Uvek u kontaktu
- find_another_instance: Nađite drugu instancu
generic_description: "%{domain} je server na mreži"
hosted_on: Mastodont hostovan na %{domain}
learn_more: Saznajte više
diff --git a/config/locales/sr.yml b/config/locales/sr.yml
index 7553968288..c564987656 100644
--- a/config/locales/sr.yml
+++ b/config/locales/sr.yml
@@ -23,7 +23,6 @@ sr:
real_conversation_title: Прављен за прави разговор
within_reach_body: Више апликација за iOS, Андроид, као и друге платформе захваљујући екосистему добрих API-ја ће Вам омогућити да останете у контакту са пријатељима свуда.
within_reach_title: Увек у контакту
- find_another_instance: Нађите другу инстанцу
generic_description: "%{domain} је сервер на мрежи"
hosted_on: Мастодонт хостован на %{domain}
learn_more: Сазнајте више
diff --git a/config/locales/sv.yml b/config/locales/sv.yml
index 79ffa93878..d20e8ba9fd 100644
--- a/config/locales/sv.yml
+++ b/config/locales/sv.yml
@@ -23,7 +23,6 @@ sv:
real_conversation_title: Byggd för riktiga konversationer
within_reach_body: Flera appar för iOS, Android och andra plattformar tack vare ett utvecklingsvänligt API-ekosystem gör att du kan hålla kontakten med dina vänner var som helst.
within_reach_title: Alltid inom räckhåll
- find_another_instance: Hitta en annan instans
generic_description: "%{domain} är en server i nätverket"
hosted_on: Mastodon värd på %{domain}
learn_more: Lär dig mer
diff --git a/config/locales/zh-CN.yml b/config/locales/zh-CN.yml
index 7deb241a15..1bd2e5039a 100644
--- a/config/locales/zh-CN.yml
+++ b/config/locales/zh-CN.yml
@@ -23,7 +23,6 @@ zh-CN:
real_conversation_title: 为真正的交流而生
within_reach_body: 通过一个面向开发者友好的 API 生态系统,Mastodon 让你可以随时随地通过众多 iOS、Android 以及其他平台的应用与朋友们保持联系。
within_reach_title: 始终触手可及
- find_another_instance: 寻找另一个实例
generic_description: "%{domain} 是这个庞大网络中的一台服务器"
hosted_on: 一个在 %{domain} 上运行的 Mastodon 实例
learn_more: 详细了解
diff --git a/spec/views/about/show.html.haml_spec.rb b/spec/views/about/show.html.haml_spec.rb
index 724643cbcd..03d6fb7ab4 100644
--- a/spec/views/about/show.html.haml_spec.rb
+++ b/spec/views/about/show.html.haml_spec.rb
@@ -16,6 +16,9 @@ describe 'about/show.html.haml', without_verify_partial_doubles: true do
source_url: 'https://github.com/tootsuite/mastodon',
open_registrations: false,
thumbnail: nil,
+ hero: nil,
+ user_count: 0,
+ status_count: 0,
closed_registrations_message: 'yes')
assign(:instance_presenter, instance_presenter)
render