[Glitch] Redesign landing page

Port 65fffeac3f to glitch-soc
main
Eugen Rochko 6 years ago committed by Thibaut Girka
parent 02062aab55
commit bbb9ff0e84

@ -1,6 +1,7 @@
# frozen_string_literal: true # frozen_string_literal: true
class PublicTimelinesController < ApplicationController class PublicTimelinesController < ApplicationController
before_action :set_pack
layout 'public' layout 'public'
before_action :check_enabled before_action :check_enabled
@ -31,4 +32,8 @@ class PublicTimelinesController < ApplicationController
def set_instance_presenter def set_instance_presenter
@instance_presenter = InstancePresenter.new @instance_presenter = InstancePresenter.new
end end
def set_pack
use_pack 'about'
end
end end

@ -7,7 +7,6 @@ import { hydrateStore } from 'flavours/glitch/actions/store';
import { IntlProvider, addLocaleData } from 'react-intl'; import { IntlProvider, addLocaleData } from 'react-intl';
import { getLocale } from 'mastodon/locales'; import { getLocale } from 'mastodon/locales';
import PublicTimeline from 'flavours/glitch/features/standalone/public_timeline'; import PublicTimeline from 'flavours/glitch/features/standalone/public_timeline';
import CommunityTimeline from 'flavours/glitch/features/standalone/community_timeline';
import HashtagTimeline from 'flavours/glitch/features/standalone/hashtag_timeline'; import HashtagTimeline from 'flavours/glitch/features/standalone/hashtag_timeline';
import ModalContainer from 'flavours/glitch/features/ui/containers/modal_container'; import ModalContainer from 'flavours/glitch/features/ui/containers/modal_container';
import initialState from 'flavours/glitch/util/initial_state'; import initialState from 'flavours/glitch/util/initial_state';
@ -26,24 +25,22 @@ export default class TimelineContainer extends React.PureComponent {
static propTypes = { static propTypes = {
locale: PropTypes.string.isRequired, locale: PropTypes.string.isRequired,
hashtag: PropTypes.string, hashtag: PropTypes.string,
showPublicTimeline: PropTypes.bool.isRequired, local: PropTypes.bool,
}; };
static defaultProps = { static defaultProps = {
showPublicTimeline: initialState.settings.known_fediverse, local: !initialState.settings.known_fediverse,
}; };
render () { render () {
const { locale, hashtag, showPublicTimeline } = this.props; const { locale, hashtag, local } = this.props;
let timeline; let timeline;
if (hashtag) { if (hashtag) {
timeline = <HashtagTimeline hashtag={hashtag} />; timeline = <HashtagTimeline hashtag={hashtag} />;
} else if (showPublicTimeline) {
timeline = <PublicTimeline />;
} else { } else {
timeline = <CommunityTimeline />; timeline = <PublicTimeline local={local} />;
} }
return ( return (
@ -51,6 +48,7 @@ export default class TimelineContainer extends React.PureComponent {
<Provider store={store}> <Provider store={store}>
<Fragment> <Fragment>
{timeline} {timeline}
{ReactDOM.createPortal( {ReactDOM.createPortal(
<ModalContainer />, <ModalContainer />,
document.getElementById('modal-container'), document.getElementById('modal-container'),

@ -1,71 +0,0 @@
import React from 'react';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';
import StatusListContainer from 'flavours/glitch/features/ui/containers/status_list_container';
import { expandCommunityTimeline } from 'flavours/glitch/actions/timelines';
import Column from 'flavours/glitch/components/column';
import ColumnHeader from 'flavours/glitch/components/column_header';
import { defineMessages, injectIntl } from 'react-intl';
import { connectCommunityStream } from 'flavours/glitch/actions/streaming';
const messages = defineMessages({
title: { id: 'standalone.public_title', defaultMessage: 'A look inside...' },
});
@connect()
@injectIntl
export default class CommunityTimeline extends React.PureComponent {
static propTypes = {
dispatch: PropTypes.func.isRequired,
intl: PropTypes.object.isRequired,
};
handleHeaderClick = () => {
this.column.scrollTop();
}
setRef = c => {
this.column = c;
}
componentDidMount () {
const { dispatch } = this.props;
dispatch(expandCommunityTimeline());
this.disconnect = dispatch(connectCommunityStream());
}
componentWillUnmount () {
if (this.disconnect) {
this.disconnect();
this.disconnect = null;
}
}
handleLoadMore = maxId => {
this.props.dispatch(expandCommunityTimeline({ maxId }));
}
render () {
const { intl } = this.props;
return (
<Column ref={this.setRef} label={intl.formatMessage(messages.title)}>
<ColumnHeader
icon='users'
title={intl.formatMessage(messages.title)}
onClick={this.handleHeaderClick}
/>
<StatusListContainer
timelineId='community'
onLoadMore={this.handleLoadMore}
scrollKey='standalone_public_timeline'
trackScroll={false}
/>
</Column>
);
}
}

@ -1,42 +1,59 @@
import React from 'react'; import React from 'react';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import StatusListContainer from 'flavours/glitch/features/ui/containers/status_list_container'; import ImmutablePropTypes from 'react-immutable-proptypes';
import { expandPublicTimeline } from 'flavours/glitch/actions/timelines'; import { expandPublicTimeline, expandCommunityTimeline } from 'flavours/glitch/actions/timelines';
import Column from 'flavours/glitch/components/column'; import { connectPublicStream, connectCommunityStream } from 'flavours/glitch/actions/streaming';
import ColumnHeader from 'flavours/glitch/components/column_header'; import Masonry from 'react-masonry-infinite';
import { defineMessages, injectIntl } from 'react-intl'; import { List as ImmutableList, Map as ImmutableMap } from 'immutable';
import { connectPublicStream } from 'flavours/glitch/actions/streaming'; import DetailedStatusContainer from 'flavours/glitch/features/status/containers/detailed_status_container';
import { debounce } from 'lodash';
import LoadingIndicator from 'flavours/glitch/components/loading_indicator';
const messages = defineMessages({ const mapStateToProps = (state, { local }) => {
title: { id: 'standalone.public_title', defaultMessage: 'A look inside...' }, const timeline = state.getIn(['timelines', local ? 'community' : 'public'], ImmutableMap());
});
@connect() return {
@injectIntl statusIds: timeline.get('items', ImmutableList()),
export default class PublicTimeline extends React.PureComponent { isLoading: timeline.get('isLoading', false),
hasMore: timeline.get('hasMore', false),
};
};
export default @connect(mapStateToProps)
class PublicTimeline extends React.PureComponent {
static propTypes = { static propTypes = {
dispatch: PropTypes.func.isRequired, dispatch: PropTypes.func.isRequired,
intl: PropTypes.object.isRequired, statusIds: ImmutablePropTypes.list.isRequired,
isLoading: PropTypes.bool.isRequired,
hasMore: PropTypes.bool.isRequired,
local: PropTypes.bool,
}; };
handleHeaderClick = () => { componentDidMount () {
this.column.scrollTop(); this._connect();
} }
setRef = c => { componentDidUpdate (prevProps) {
this.column = c; if (prevProps.local !== this.props.local) {
this._disconnect();
this._connect();
}
} }
componentDidMount () { componentWillUnmount () {
const { dispatch } = this.props; this._disconnect();
}
dispatch(expandPublicTimeline()); _connect () {
this.disconnect = dispatch(connectPublicStream()); const { dispatch, local } = this.props;
dispatch(local ? expandCommunityTimeline() : expandPublicTimeline());
this.disconnect = dispatch(local ? connectCommunityStream() : connectPublicStream());
} }
componentWillUnmount () { _disconnect () {
if (this.disconnect) { if (this.disconnect) {
this.disconnect(); this.disconnect();
this.disconnect = null; this.disconnect = null;
@ -44,27 +61,48 @@ export default class PublicTimeline extends React.PureComponent {
} }
handleLoadMore = maxId => { handleLoadMore = maxId => {
this.props.dispatch(expandPublicTimeline({ maxId })); const { dispatch, local } = this.props;
dispatch(local ? expandCommunityTimeline({ maxId }) : expandPublicTimeline({ maxId }));
} }
setRef = c => {
this.masonry = c;
}
handleHeightChange = debounce(() => {
if (!this.masonry) {
return;
}
this.masonry.forcePack();
}, 50)
render () { render () {
const { intl } = this.props; const { statusIds, hasMore, isLoading } = this.props;
return ( const sizes = [
<Column ref={this.setRef} label={intl.formatMessage(messages.title)}> { columns: 1, gutter: 0 },
<ColumnHeader { mq: '415px', columns: 1, gutter: 10 },
icon='globe' { mq: '640px', columns: 2, gutter: 10 },
title={intl.formatMessage(messages.title)} { mq: '960px', columns: 3, gutter: 10 },
onClick={this.handleHeaderClick} { mq: '1255px', columns: 3, gutter: 10 },
/> ];
<StatusListContainer const loader = (isLoading && statusIds.isEmpty()) ? <LoadingIndicator key={0} /> : undefined;
timelineId='public'
onLoadMore={this.handleLoadMore} return (
scrollKey='standalone_public_timeline' <Masonry ref={this.setRef} className='statuses-grid' hasMore={hasMore} loadMore={this.handleLoadMore} sizes={sizes} loader={loader}>
trackScroll={false} {statusIds.map(statusId => (
<div className='statuses-grid__item' key={statusId}>
<DetailedStatusContainer
id={statusId}
compact
measureHeight
onHeightChange={this.handleHeightChange}
/> />
</Column> </div>
)).toArray()}
</Masonry>
); );
} }

@ -23,7 +23,7 @@ export default class DetailedStatus extends ImmutablePureComponent {
}; };
static propTypes = { static propTypes = {
status: ImmutablePropTypes.map.isRequired, status: ImmutablePropTypes.map,
settings: ImmutablePropTypes.map.isRequired, settings: ImmutablePropTypes.map.isRequired,
onOpenMedia: PropTypes.func.isRequired, onOpenMedia: PropTypes.func.isRequired,
onOpenVideo: PropTypes.func.isRequired, onOpenVideo: PropTypes.func.isRequired,

@ -193,6 +193,7 @@ $small-breakpoint: 960px;
} }
strong { strong {
font-family: $font-display, sans-serif;
font-weight: 500; font-weight: 500;
font-size: 32px; font-size: 32px;
line-height: 48px; line-height: 48px;
@ -282,168 +283,6 @@ $small-breakpoint: 960px;
} }
.landing-page { .landing-page {
.grid {
display: grid;
grid-gap: 10px;
grid-template-columns: 1fr 2fr;
grid-auto-columns: 25%;
grid-auto-rows: max-content;
.column-0 {
display: none;
}
.column-1 {
grid-column: 1;
grid-row: 1;
}
.column-2 {
grid-column: 2;
grid-row: 1;
}
.column-3 {
grid-column: 3;
grid-row: 1 / 3;
}
.column-4 {
grid-column: 1 / 3;
grid-row: 2;
}
}
@media screen and (max-width: $small-breakpoint) {
.grid {
grid-template-columns: 40% 60%;
.column-0 {
display: none;
}
.column-1 {
grid-column: 1;
grid-row: 1;
&.non-preview .landing-page__forms {
height: 100%;
}
}
.column-2 {
grid-column: 2;
grid-row: 1 / 3;
&.non-preview {
grid-column: 2;
grid-row: 1;
}
}
.column-3 {
grid-column: 1;
grid-row: 2 / 4;
}
.column-4 {
grid-column: 2;
grid-row: 3;
&.non-preview {
grid-column: 1 / 3;
grid-row: 2;
}
}
}
}
@media screen and (max-width: $column-breakpoint) {
.grid {
grid-template-columns: 100%;
.column-0 {
display: block;
grid-column: 1;
grid-row: 1;
}
.column-1 {
grid-column: 1;
grid-row: 3;
.brand {
display: none;
}
}
.column-2 {
grid-column: 1;
grid-row: 2;
.landing-page__logo,
.landing-page__call-to-action {
display: none;
}
&.non-preview {
grid-column: 1;
grid-row: 2;
}
}
.column-3 {
grid-column: 1;
grid-row: 5;
}
.column-4 {
grid-column: 1;
grid-row: 4;
&.non-preview {
grid-column: 1;
grid-row: 4;
}
}
}
}
.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: $darker-text-color;
text-transform: uppercase;
position: relative;
z-index: 1;
padding: 0 8px;
cursor: default;
}
}
p, p,
li { li {
font-family: $font-sans-serif, sans-serif; font-family: $font-sans-serif, sans-serif;
@ -460,28 +299,6 @@ $small-breakpoint: 960px;
} }
} }
.closed-registrations-message {
margin-top: 20px;
&,
p {
text-align: center;
font-size: 12px;
line-height: 18px;
color: $darker-text-color;
margin-bottom: 0;
a {
color: $highlight-text-color;
text-decoration: underline;
}
}
p:last-child {
margin-bottom: 0;
}
}
em { em {
display: inline; display: inline;
margin: 0; margin: 0;
@ -595,187 +412,6 @@ $small-breakpoint: 960px;
} }
} }
.container-alt {
width: 100%;
box-sizing: border-box;
max-width: 800px;
margin: 0 auto;
word-wrap: break-word;
}
.header-wrapper {
padding-top: 15px;
background: $ui-base-color;
background: linear-gradient(150deg, lighten($ui-base-color, 8%), $ui-base-color);
position: relative;
&.compact {
background: $ui-base-color;
padding-bottom: 15px;
.hero .heading {
padding-bottom: 20px;
font-family: $font-sans-serif, sans-serif;
font-size: 16px;
font-weight: 400;
font-size: 16px;
line-height: 30px;
color: $darker-text-color;
a {
color: $highlight-text-color;
text-decoration: underline;
}
}
}
}
.brand {
a {
padding-left: 0;
padding-right: 0;
color: $white;
}
img {
height: 32px;
position: relative;
top: 4px;
left: -10px;
}
}
.header {
line-height: 30px;
overflow: hidden;
.container-alt {
display: flex;
justify-content: space-between;
}
.links {
position: relative;
z-index: 4;
a {
display: flex;
justify-content: center;
align-items: center;
color: $darker-text-color;
text-decoration: none;
padding: 12px 16px;
line-height: 32px;
font-family: $font-display, sans-serif;
font-weight: 500;
font-size: 14px;
&:hover {
color: $secondary-text-color;
}
}
ul {
list-style: none;
margin: 0;
li {
display: inline-block;
vertical-align: bottom;
margin: 0;
&:first-child a {
padding-left: 0;
}
&:last-child a {
padding-right: 0;
}
}
}
}
.hero {
margin-top: 50px;
align-items: center;
position: relative;
.heading {
position: relative;
z-index: 4;
padding-bottom: 150px;
}
.simple_form,
.closed-registrations-message {
background: darken($ui-base-color, 4%);
width: 280px;
padding: 15px 20px;
border-radius: 4px 4px 0 0;
line-height: initial;
position: relative;
z-index: 4;
.actions {
margin-bottom: 0;
button,
.button,
.block-button {
margin-bottom: 0;
}
}
}
.closed-registrations-message {
min-height: 330px;
display: flex;
flex-direction: column;
justify-content: space-between;
}
}
}
.about-short {
background: darken($ui-base-color, 4%);
padding: 50px 0 30px;
font-family: $font-sans-serif, sans-serif;
font-size: 16px;
font-weight: 400;
font-size: 16px;
line-height: 30px;
color: $darker-text-color;
a {
color: $highlight-text-color;
text-decoration: underline;
}
}
&.alternative {
padding: 10px 0;
.brand {
text-align: center;
padding: 30px 0;
margin-bottom: 10px;
img {
position: static;
padding: 10px 0;
}
@media screen and (max-width: $small-breakpoint) {
padding: 15px 0;
}
@media screen and (max-width: $column-breakpoint) {
padding: 0;
margin-bottom: -10px;
}
}
}
&__information, &__information,
&__forms { &__forms {
padding: 20px; padding: 20px;
@ -970,353 +606,253 @@ $small-breakpoint: 960px;
} }
} }
&__forms { @media screen and (max-width: 840px) {
height: 100%; .information-board {
.container-alt {
@media screen and (max-width: $small-breakpoint) { padding-right: 20px;
height: auto;
} }
@media screen and (max-width: $column-breakpoint) { .panel {
background: transparent; position: static;
box-shadow: none; margin-top: 20px;
padding: 0 20px; width: 100%;
margin-top: 30px; border-radius: 4px;
margin-bottom: 40px;
.separator-or { .panel-header {
span { text-align: center;
background: darken($ui-base-color, 8%);
}
} }
} }
hr {
margin: 40px 0;
} }
.button {
display: block;
} }
.subtle-hint a { @media screen and (max-width: 675px) {
text-decoration: none; .header-wrapper {
padding-top: 0;
&:hover, &.compact {
&:focus, padding-bottom: 0;
&:active {
text-decoration: underline;
}
}
} }
#mastodon-timeline { &.compact .hero .heading {
display: flex; text-align: initial;
-webkit-overflow-scrolling: touch;
-ms-overflow-style: -ms-autohiding-scrollbar;
font-family: $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;
height: 100%;
.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 { .header .container-alt,
height: 400px; .features .container-alt {
display: block;
} }
p {
font-size: inherit;
line-height: inherit;
font-weight: inherit;
color: $primary-text-color;
margin-bottom: 20px;
&:last-child {
margin-bottom: 0;
} }
a { .cta {
color: $secondary-text-color; margin: 20px;
text-decoration: none;
}
} }
}
.attachment-list__list { .landing {
margin-left: 0; margin-bottom: 100px;
list-style: none;
li { @media screen and (max-width: 738px) {
font-size: inherit;
line-height: inherit;
font-weight: inherit;
margin-bottom: 0; margin-bottom: 0;
}
a { &__brand {
color: $dark-text-color; display: flex;
text-decoration: none; justify-content: center;
align-items: center;
padding: 100px;
&:hover { img {
text-decoration: underline; height: 52px;
}
}
}
} }
@media screen and (max-width: $column-breakpoint) { @media screen and (max-width: $no-gap-breakpoint) {
display: none; padding: 0;
margin-bottom: 30px;
} }
} }
&__features { .directory {
& > p { margin-top: 30px;
padding-right: 60px; background: transparent;
box-shadow: none;
border-radius: 0;
} }
.features-list { .hero-widget {
margin: 40px 0;
margin-top: 30px; margin-top: 30px;
} margin-bottom: 0;
&__action { h4 {
text-align: center; padding: 10px;
} text-transform: uppercase;
font-weight: 700;
font-size: 13px;
color: $darker-text-color;
} }
.features-list { &__text {
.features-list__row { border-radius: 0;
display: flex; padding-bottom: 0;
padding: 10px 0; }
justify-content: space-between;
.visual { &__footer {
flex: 0 0 auto; background: $ui-base-color;
padding: 10px;
border-radius: 0 0 4px 4px;
display: flex; display: flex;
align-items: center;
margin-left: 15px;
.fa { &__column {
display: block; flex: 1 1 50%;
color: $darker-text-color;
font-size: 48px;
} }
} }
.text { .account {
font-size: 16px; padding: 10px 0;
line-height: 30px; border-bottom: 0;
color: $darker-text-color;
h6 { .account__display-name {
font-size: inherit; display: flex;
line-height: inherit; align-items: center;
margin-bottom: 0;
}
}
} }
@media screen and (min-width: $small-breakpoint) { .account__avatar {
display: grid; width: 44px;
grid-gap: 30px; height: 44px;
grid-template-columns: 1fr 1fr; background-size: 44px 44px;
grid-auto-columns: 50%;
grid-auto-rows: max-content;
} }
} }
.footer-links { &__counter {
padding-bottom: 50px; padding: 10px;
text-align: right;
color: $dark-text-color;
p {
font-size: 14px;
}
a { strong {
color: inherit; font-family: $font-display, sans-serif;
text-decoration: underline; font-size: 15px;
} font-weight: 700;
display: block;
} }
&__footer { span {
margin-top: 10px;
text-align: center;
color: $dark-text-color;
p {
font-size: 14px; font-size: 14px;
color: $darker-text-color;
a {
color: inherit;
text-decoration: underline;
} }
} }
} }
@media screen and (max-width: 840px) { .simple_form .user_agreement .label_input > label {
.container-alt { font-weight: 400;
padding: 0 20px; color: $darker-text-color;
} }
.information-board { .simple_form p.lead {
.container-alt { color: $darker-text-color;
padding-right: 20px; font-size: 15px;
line-height: 20px;
font-weight: 400;
margin-bottom: 25px;
} }
.panel { &__grid {
position: static; max-width: 960px;
margin-top: 20px; margin: 0 auto;
width: 100%; display: grid;
border-radius: 4px; grid-template-columns: minmax(0, 50%) minmax(0, 50%);
grid-gap: 30px;
.panel-header {
text-align: center;
}
}
}
}
@media screen and (max-width: 675px) { @media screen and (max-width: 738px) {
.header-wrapper { grid-template-columns: minmax(0, 100%);
padding-top: 0; grid-gap: 10px;
&.compact { &__column-login {
padding-bottom: 0; grid-row: 1;
} display: flex;
flex-direction: column;
&.compact .hero .heading { .box-widget {
text-align: initial; order: 2;
} flex: 0 0 auto;
} }
.header .container-alt, .hero-widget {
.features .container-alt { margin-top: 0;
display: block; margin-bottom: 10px;
order: 1;
flex: 0 0 auto;
} }
.header {
.links {
padding-top: 15px;
background: darken($ui-base-color, 4%);
a {
padding: 12px 8px;
} }
.nav { &__column-registration {
display: flex; grid-row: 2;
flex-flow: row wrap;
justify-content: space-around;
} }
.brand img { .directory {
left: 0; margin-top: 10px;
top: 0;
} }
} }
.hero { @media screen and (max-width: $no-gap-breakpoint) {
margin-top: 30px; grid-gap: 0;
padding: 0;
.heading { .hero-widget {
padding: 30px 20px; display: block;
text-align: center; margin-bottom: 0;
} box-shadow: none;
.simple_form, &__img,
.closed-registrations-message { &__img img,
background: darken($ui-base-color, 8%); &__footer {
width: 100%;
border-radius: 0; border-radius: 0;
box-sizing: border-box;
}
}
} }
} }
.cta { .hero-widget,
margin: 20px; .box-widget,
.directory__tag {
border-bottom: 1px solid lighten($ui-base-color, 8%);
} }
&.tag-page { .directory {
@media screen and (max-width: $column-breakpoint) { margin-top: 0;
padding: 0;
.container { &__tag {
padding: 0; margin-bottom: 0;
}
#mastodon-timeline { & > a,
display: flex; & > div {
height: 100vh;
border-radius: 0; border-radius: 0;
} box-shadow: none;
}
.grid {
@media screen and (min-width: $small-breakpoint) {
grid-template-columns: 33% 67%;
} }
.column-2 { &:last-child {
grid-column: 2; border-bottom: 0;
grid-row: 1;
}
} }
.brand {
text-align: unset;
padding: 0;
img {
height: 48px;
width: auto;
} }
} }
.cta {
margin: 0;
.button {
margin-right: 4px;
} }
} }
}
@media screen and (max-width: $column-breakpoint) { .brand {
.grid { position: relative;
grid-gap: 0; text-decoration: none;
}
.column-1 { .brand__tagline {
grid-column: 1; display: block;
grid-row: 1; position: absolute;
} bottom: -10px;
left: 50px;
width: 300px;
color: $ui-primary-color;
text-decoration: none;
font-size: 14px;
.column-2 { @media screen and (max-width: $no-gap-breakpoint) {
display: none; position: static;
} width: auto;
} margin-top: 20px;
} color: $dark-text-color;
} }
} }

@ -68,6 +68,17 @@ code {
top: 2px; top: 2px;
left: 0; left: 0;
} }
label a {
color: $highlight-text-color;
text-decoration: underline;
&:hover,
&:active,
&:focus {
text-decoration: none;
}
}
} }
} }
@ -305,7 +316,7 @@ code {
box-shadow: none; box-shadow: none;
} }
&:focus:invalid { &:focus:invalid:not(:placeholder-shown) {
border-color: lighten($error-red, 12%); border-color: lighten($error-red, 12%);
} }
@ -346,6 +357,10 @@ code {
} }
} }
.input.disabled {
opacity: 0.5;
}
.actions { .actions {
margin-top: 30px; margin-top: 30px;
display: flex; display: flex;
@ -392,6 +407,10 @@ code {
background-color: darken($ui-highlight-color, 5%); background-color: darken($ui-highlight-color, 5%);
} }
&:disabled:hover {
background-color: $ui-primary-color;
}
&.negative { &.negative {
background: $error-value-color; background: $error-value-color;

@ -295,6 +295,11 @@
cursor: default; cursor: default;
} }
&.disabled > div {
opacity: 0.5;
cursor: default;
}
h4 { h4 {
flex: 1 1 auto; flex: 1 1 auto;
font-size: 18px; font-size: 18px;

@ -4,7 +4,6 @@
- content_for :header_tags do - content_for :header_tags do
%meta{ name: 'robots', content: 'noindex' }/ %meta{ name: 'robots', content: 'noindex' }/
%script#initial-state{ type: 'application/json' }!= json_escape(@initial_state_json) %script#initial-state{ type: 'application/json' }!= json_escape(@initial_state_json)
= javascript_pack_tag 'about', integrity: true, crossorigin: 'anonymous'
.page-header .page-header
%h1= t('about.see_whats_happening') %h1= t('about.see_whats_happening')

Loading…
Cancel
Save