diff --git a/app/images/halloween/clouds.png b/app/images/halloween/clouds.png new file mode 100644 index 000000000..29962c104 Binary files /dev/null and b/app/images/halloween/clouds.png differ diff --git a/app/images/halloween/halloween-emblem.svg b/app/images/halloween/halloween-emblem.svg new file mode 100644 index 000000000..ad23be14c --- /dev/null +++ b/app/images/halloween/halloween-emblem.svg @@ -0,0 +1,311 @@ + + + + Flying Witch during Full Moon + + + + + image/svg+xml + + Flying Witch during Full Moon + 2017-10-10 + + + Urs Roesch + + + + + + OpenClipart + + + + + remix+287475 + remix+288242 + remix+170669 + yellow + moon + yellow moon + full moon + moon + witch + cat + silhouette + bat + bats + flying bat + flying witch + black + dark + night + halloween + walpurgis night + walpurgis + + + Flying witch with cat flying during full moon. + + + gnokii + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/images/halloween/spider.svg b/app/images/halloween/spider.svg new file mode 100644 index 000000000..077b60d65 --- /dev/null +++ b/app/images/halloween/spider.svg @@ -0,0 +1,69 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/app/images/halloween/spiderweb.svg b/app/images/halloween/spiderweb.svg new file mode 100644 index 000000000..16ae81984 --- /dev/null +++ b/app/images/halloween/spiderweb.svg @@ -0,0 +1,78 @@ + + + + + Realistic spider web + + + + + + + image/svg+xml + + + + + Openclipart + + + Realistic spider web + + + + + + + + + diff --git a/app/images/halloween/starfield.png b/app/images/halloween/starfield.png new file mode 100644 index 000000000..1e7995895 Binary files /dev/null and b/app/images/halloween/starfield.png differ diff --git a/app/images/halloween/twinkle.svg b/app/images/halloween/twinkle.svg new file mode 100644 index 000000000..9869cb094 --- /dev/null +++ b/app/images/halloween/twinkle.svg @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + diff --git a/app/soapbox/containers/soapbox.js b/app/soapbox/containers/soapbox.js index b948811d3..ed4549d27 100644 --- a/app/soapbox/containers/soapbox.js +++ b/app/soapbox/containers/soapbox.js @@ -59,6 +59,7 @@ const mapStateToProps = (state) => { locale: validLocale(locale) ? locale : 'en', themeCss: generateThemeCss(soapboxConfig.get('brandColor')), themeMode: settings.get('themeMode'), + halloween: settings.get('halloween'), customCss: soapboxConfig.get('customCss'), }; }; @@ -77,6 +78,7 @@ class SoapboxMount extends React.PureComponent { themeCss: PropTypes.string, themeMode: PropTypes.string, customCss: ImmutablePropTypes.list, + halloween: PropTypes.bool, dispatch: PropTypes.func, }; @@ -122,6 +124,7 @@ class SoapboxMount extends React.PureComponent { 'no-reduce-motion': !this.props.reduceMotion, 'dyslexic': this.props.dyslexicFont, 'demetricator': this.props.demetricator, + 'halloween': this.props.halloween, }); return ( diff --git a/app/soapbox/features/preferences/index.js b/app/soapbox/features/preferences/index.js index beaab5c25..6a0727bb4 100644 --- a/app/soapbox/features/preferences/index.js +++ b/app/soapbox/features/preferences/index.js @@ -185,6 +185,11 @@ class Preferences extends ImmutablePureComponent { path={['dyslexicFont']} /> + } + hint={} + path={['halloween']} + /> } hint={} diff --git a/app/styles/application.scss b/app/styles/application.scss index fdce329ad..cb171dffd 100644 --- a/app/styles/application.scss +++ b/app/styles/application.scss @@ -76,3 +76,6 @@ @import 'components/profile_hover_card'; @import 'components/filters'; @import 'components/mfa_form'; + +// Holiday +@import 'holiday/halloween'; diff --git a/app/styles/holiday/halloween.scss b/app/styles/holiday/halloween.scss new file mode 100644 index 000000000..8f04e74c1 --- /dev/null +++ b/app/styles/holiday/halloween.scss @@ -0,0 +1,158 @@ +body.halloween { + // Set brand color to orange + --brand-color_h: 29.727272727272727; + --brand-color_s: 100%; + --brand-color_l: 43.13725490196079%; + + // Stars BG + background-color: #904700; // Color matches twinkle.svg + background-image: url('../images/halloween/starfield.png'); + background-size: cover; + background-attachment: fixed; + background-position: center; + + // Full-screen pseudo-elements to hold BG graphics + &::before, + &::after, + .app-holder::before, + .app-holder::after { + content: ''; + display: block; + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-size: cover; + background-position: center; + width: 100%; + height: 100%; + z-index: -100; + } + + // Spiderweb BG + &::before { + background-image: url('../images/halloween/spiderweb.svg'); + } + + // Twinkle effect by masking with semi-transparent animated circles + &::after { + z-index: -101; + background: transparent url("../images/halloween/twinkle.svg") repeat top center; + animation: halloween-twinkle 200s linear infinite; + } + + .app-holder { + // Black vignette + &::before { + background-image: radial-gradient( + circle, + transparent 0%, + transparent 60%, + #000 100% + ); + } + + // Floating clouds BG + &::after { + background: transparent url("../images/halloween/clouds.png") repeat top center; + animation: halloween-clouds 200s linear infinite; + } + } + + // Dangling spider + .ui .page__top::after, + .ui .page__columns::after { + content: ''; + display: block; + width: 100px; + height: 100px; + right: 20px; + background-image: url('../images/halloween/spider.svg'); + background-size: contain; + background-repeat: no-repeat; + background-position: top right; + z-index: -1; + pointer-events: none; + } + + .ui .page__columns::after { + position: fixed; + top: 50px; + } + + .ui .page__top::after { + position: absolute; + bottom: -100px; + } + + .ui .page__top + .page__columns::after { + display: none; + } + + // Witch emblem + .getting-started__footer::before { + content: ''; + display: block; + background-image: url('../images/halloween/halloween-emblem.svg'); + background-size: contain; + background-position: left; + background-repeat: no-repeat; + width: 100%; + height: 100px; + margin-bottom: 20px; + } + + // Color fixes + // Elements directly over the BG need static colors that don't change + // regardless of the theme-mode + .getting-started__footer { + color: #fff; + + a { + color: hsla(0, 0%, 100%, 0.4); + } + + p { + color: hsla(0, 0%, 100%, 0.8); + } + } + + .profile-info-panel { + color: #fff; + + &-content__name h1 { + span:first-of-type { + color: hsla(0, 0%, 100%, 0.6); + } + + small { + color: #fff; + } + } + + &-content__bio { + color: #fff; + } + + &-content__bio a, + &-content__fields a { + color: hsl( + var(--brand-color_h), + var(--brand-color_s), + calc(var(--brand-color_l) + 8%) + ); + } + } +} + +// Animations +@keyframes halloween-twinkle { + from { background-position: 0 0; } + to { background-position: -10000px 5000px; } +} + +@keyframes halloween-clouds { + from { background-position: 0 0; } + to { background-position: 10000px 0; } +}