commit: c71aa468b5ce2aed9f9fcd0cc6c0c97166e239d3
parent: d8bc64bb09750b9e47c1ea1bb502e88a8dd676d5
Author: Eugen Rochko <eugen@zeonfederated.com>
Date: Thu, 22 Feb 2018 01:03:48 +0100
Redesign landing page (again) (#6486)
* Redesign landing page (again)
* Move login form in small version to the right column
* Display closed registrations message
* Add site setting for the hero image
* Fix test
* Increase spacing, maximum width, change call to action section
Diffstat:
38 files changed, 553 insertions(+), 306 deletions(-)
diff --git 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
@@ -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,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 447.1875 234.375" height="170" width="324"><path fill="#{hex-color($ui-base-lighter-color)}" d="M21.69 233.366c-6.45-1.268-13.347-5.63-16.704-10.564-10.705-15.734-1.513-37.724 18.632-44.57l4.8-1.632.173-17.753c.146-14.77.515-19.063 2.2-25.55 6.736-25.944 24.46-46.032 47.766-54.137 11.913-4.143 19.558-5.366 34.178-5.47l13.828-.096V71.12c0-4.755 2.853-17.457 5.238-23.327 8.588-21.137 26.735-35.957 52.153-42.593 23.248-6.07 50.153-6.415 71.863-.923 11.14 2.82 25.686 9.957 33.857 16.615 19.335 15.756 31.82 41.05 35.183 71.275.59 5.305.672 5.435 3.11 4.926 11.833-2.474 30.4-3.132 40.065-1.42 24.388 4.32 40.568 19.076 47.214 43.058 2.16 7.8 3.953 23.894 3.59 32.237l-.24 5.498 5.156 1.317c6.392 1.633 14.55 7.098 18.003 12.062 1.435 2.062 3.305 6.597 4.156 10.078 1.428 5.84 1.43 6.8.04 12.44-1.807 7.318-5.672 13.252-10.872 16.694-8.508 5.63 3.756 5.33-211.916 5.216-108.56-.056-199.22-.464-201.47-.906z"/></svg>');
- }
-
- .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,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 536.25 222.1875" height="100" width="241"><path fill="#{hex-color($ui-base-lighter-color)}" d="M42.626 221.23c-14.104-1.174-26.442-5.133-32.825-10.534-4.194-3.548-7.684-10.66-8.868-18.075-1.934-12.102.633-22.265 7.528-29.81 7.61-8.328 19.998-12.76 39.855-14.257l8.47-.638-2.08-6.223c-4.826-14.422-6.357-24.813-6.37-43.255-.012-14.923.28-18.513 2.1-25.724 2.283-9.048 8.483-23.034 13.345-30.1 14.76-21.45 43.505-38.425 70.535-41.65 30.628-3.655 64.47 12.073 89.668 41.673l5.955 6.995 2.765-4.174c1.52-2.296 5.74-6.93 9.376-10.295 18.382-17.02 43.436-20.676 73.352-10.705 12.158 4.052 21.315 9.53 29.64 17.733 12.752 12.562 18.16 25.718 18.19 44.26l.02 10.98 2.312-3.01c15.64-20.365 42.29-20.485 62.438-.28 3.644 3.653 7.558 8.593 8.697 10.976 4.895 10.24 5.932 25.688 2.486 37.046-.76 2.507-1.388 4.816-1.393 5.13-.006.316 6.845.87 15.224 1.234 53.06 2.297 76.356 12.98 81.817 37.526 3.554 15.973-3.71 28.604-19.566 34.02-4.554 1.555-17.922 1.655-234.517 1.757-126.327.06-233.497-.21-238.154-.597z"/></svg>');
- }
-
- .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,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 388.125 202.5" height="140" width="267"><path fill="#{hex-color($ui-base-lighter-color)}" d="M181.37 201.458c-17.184-1.81-36.762-8.944-49.523-18.05l-5.774-4.12-8.074 2.63c-11.468 3.738-21.382 4.962-35.815 4.422-14.79-.554-24.577-2.845-36.716-8.594-15.483-7.332-28.498-19.98-35.985-34.968C2.44 128.675-.94 108.435.9 91.356c3.362-31.234 18.197-53.698 43.63-66.074 12.803-6.23 22.384-8.55 37.655-9.122 14.433-.54 24.347.684 35.814 4.42l8.073 2.633 5.635-4.01c24.81-17.656 60.007-23.332 92.914-14.985 10.11 2.565 25.498 9.62 33.102 15.178l5.068 3.704 7.632-2.564c10.89-3.66 21.086-4.916 35.516-4.376 45.816 1.716 76.422 30.03 81.285 75.196 1.84 17.08-1.54 37.32-8.585 51.422-7.487 14.99-20.502 27.636-35.984 34.968-12.14 5.75-21.926 8.04-36.716 8.593-14.43.54-24.626-.716-35.516-4.376l-7.632-2.564-5.068 3.704c-12.844 9.387-32.714 16.488-51.545 18.42-10.607 1.09-13.916 1.08-24.81-.066z"/></svg>');
- }
- }
-
.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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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