diff --git a/app/controllers/admin/settings_controller.rb b/app/controllers/admin/settings_controller.rb
index a6214dc3f..ce3208209 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 0806171be..a95b75984 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;
- #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: 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);
+ img {
+ position: static;
+ }
- .column-header {
- color: inherit;
- font-family: inherit;
- font-size: 16px;
- line-height: inherit;
- font-weight: inherit;
- margin: 0;
- padding: 0;
+ @media screen and (max-width: $small-breakpoint) {
+ padding: 15px 0;
}
- .column {
+ @media screen and (max-width: $column-breakpoint) {
padding: 0;
- border-radius: 4px;
- overflow: hidden;
+ margin-bottom: -10px;
}
+ }
+ }
- .scrollable {
- height: 400px;
- }
+ &__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;
+ }
+
+ .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;
- p {
- font-size: inherit;
- line-height: inherit;
- font-weight: inherit;
- color: $primary-text-color;
+ &: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;
+ }
+ }
- &:last-child {
- margin-bottom: 0;
- }
+ p a {
+ color: $ui-secondary-color;
+ }
- a {
+ h1 {
+ font-weight: 500;
+ color: $primary-text-color;
+ margin-bottom: 0;
+
+ small {
+ color: $ui-primary-color;
+
+ 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%);
+ }
}
+ }
- .features-list {
- margin-top: 20px;
+ hr {
+ margin: 40px 0;
+ }
- .features-list__row {
- display: flex;
- padding: 10px 0;
- justify-content: space-between;
+ .button {
+ display: block;
+ }
- &:first-child {
- padding-top: 0;
- }
+ .subtle-hint a {
+ text-decoration: none;
- .visual {
- flex: 0 0 auto;
- display: flex;
- align-items: center;
- margin-left: 15px;
-
- .fa {
- display: block;
- color: $ui-primary-color;
- font-size: 48px;
- }
- }
+ &:hover,
+ &:focus,
+ &:active {
+ text-decoration: underline;
+ }
+ }
+ }
- .text {
- font-size: 16px;
- line-height: 30px;
- color: $ui-primary-color;
+ #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;
- h6 {
- font-size: inherit;
- line-height: inherit;
- margin-bottom: 0;
- }
- }
+ .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;
+ }
+
+ a {
+ color: $ui-secondary-color;
+ text-decoration: none;
+ }
+ }
+
+ @media screen and (max-width: $column-breakpoint) {
+ height: 90vh;
+ }
+ }
+
+ &__features {
+ .features-list {
+ margin: 40px 0 !important;
+ }
+
+ &__action {
+ text-align: center;
+ }
+ }
+
+ .features-list {
+ margin-top: 20px;
+
+ .features-list__row {
+ display: flex;
+ padding: 10px 0;
+ justify-content: space-between;
+
+ &: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 cff7078aa..0224009ee 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 af2589e23..6fa1fa38f 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 4c1124d59..e4972c962 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 000000000..9916b6bf4
--- /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 ccf4f08b9..f79c37e65 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 7a28f9738..6ca1d7129 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 9c9580eac..df072b8ae 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 b7c08479d..fd1cda8b3 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'
-
- .header
- = render 'links'
-
- .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'
-
- .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)
-
- .features
- .container
- - if Setting.timeline_preview
- #mastodon-timeline{ data: { props: Oj.dump(default_props) } }
-
- .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})"
+.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'
+
+ .hide-xs
+ = render 'forms'
+
+ .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
+
+ .landing-page__information
+ .landing-page__short-description
+ .row
+ .landing-page__logo.hide-xs
+ = image_tag asset_pack_path('logo_transparent.svg'), alt: 'Mastodon'
+
+ %h1
+ = @instance_presenter.site_title
+ %small!= t 'about.hosted_on', domain: content_tag(:span, site_hostname)
+
+ %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 ba780759c..c7d36ed47 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 73fd5642e..08d05d738 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 eadeaef3e..88b4d88bb 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 126e488d9..a685950a2 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 f03e393f5..8f17413e1 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 b9dd5bd51..071c41290 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 1ad8539de..9eb61aaac 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 c498c592c..395d226bd 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 1067496c9..e9c7273ce 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 f0fc07f7a..02d6f131c 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 40d72cbe4..5de6031fc 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 1f27dda7a..c83f4ba10 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 6e39f9800..918e85d1f 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 14a42fd76..b1c22d5f9 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 6f1371531..8bc318d7b 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 f1af8ac0e..9f2825e7f 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 1e9597a53..d198177cd 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 56554610d..80b103763 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 010b03ed2..950a70d06 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 31481ced4..0da8d957a 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 93eaf84d6..c77368e3f 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 842fd7d54..467f24ca8 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 84433a209..853988546 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 ac80e81ec..4eed44345 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 755396828..c56498765 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 79ffa9387..d20e8ba9f 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 7deb241a1..1bd2e5039 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 724643cbc..03d6fb7ab 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