refactor: style Intro

This commit is contained in:
Tim 2023-07-05 19:10:14 +02:00
parent 130a9dc57a
commit 0e0f27c54a
9 changed files with 321 additions and 273 deletions

15
images/background_1.svg Normal file
View file

@ -0,0 +1,15 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="968" height="565" viewBox="0 0 968 565">
<defs>
<clipPath id="clip-path">
<rect id="Rectangle_1144" data-name="Rectangle 1144" width="968" height="565" transform="translate(0 262)" fill="#fff" stroke="#707070" stroke-width="1"/>
</clipPath>
</defs>
<g id="Mask_Group_31" data-name="Mask Group 31" transform="translate(0 -262)" clip-path="url(#clip-path)">
<g id="Group_2309" data-name="Group 2309">
<path id="Path_983" data-name="Path 983" d="M410.951-49.5c337,24.76,699.788,308.381,792,500.579S897.064,762.814,577.9,762.814,0,593.971,0,385.694,73.955-74.26,410.951-49.5Z" transform="translate(-301.147 411.907)" fill="#362565" opacity="0.8"/>
<path id="Path_979" data-name="Path 979" d="M360.91-73.97c324,27.3,638,301.633,720.932,474.48S806.748,680.86,519.716,680.86,0,529.016,0,341.708,36.91-101.27,360.91-73.97Z" transform="translate(-231.91 594.67)" fill="rgba(123,91,245,0.83)" opacity="0.8"/>
<path id="Path_984" data-name="Path 984" d="M262.171-10C444.7-10,659.821,73.865,660.993,203.729S513.025,402.667,330.5,402.667,0,313.6,0,203.729,79.643-10,262.171-10Z" transform="translate(-69 681.267)" fill="#5126ed"/>
<path id="Path_980" data-name="Path 980" d="M262.171-10C444.7-10,659.821,66.535,660.993,185.049S513.025,366.6,330.5,366.6,0,285.317,0,185.049,79.643-10,262.171-10Z" transform="translate(-69 762.333)" fill="#4516fc"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

13
images/background_2.svg Normal file
View file

@ -0,0 +1,13 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="718" height="356" viewBox="0 0 718 356">
<defs>
<clipPath id="clip-path">
<rect id="Rectangle_1144" data-name="Rectangle 1144" width="718" height="356" transform="translate(602 -8)" fill="#fff" stroke="#707070" stroke-width="1"/>
</clipPath>
</defs>
<g id="Mask_Group_31" data-name="Mask Group 31" transform="translate(-602 8)" clip-path="url(#clip-path)">
<g id="Group_2308" data-name="Group 2308" transform="translate(-49.883 86.23)">
<path id="Path_982" data-name="Path 982" d="M264.138,0C470.016,0,780.486,131.36,775.97,319.553S578.654,535.889,372.776,535.889,0,418.717,0,274.178,58.26,0,264.138,0Z" transform="translate(1521.635 173.714) rotate(180)" fill="rgba(137,91,245,0.64)" opacity="0.52"/>
<path id="Path_981" data-name="Path 981" d="M177.9,0C301.753,0,447.725,59.059,448.52,150.512s-100.4,140.1-224.26,140.1S0,227.885,0,150.512,54.042,0,177.9,0Z" transform="translate(1366.094 26.124) rotate(180)" fill="#4722d2"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 207 KiB

BIN
images/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

View file

@ -20,7 +20,7 @@
--horizontal-nav-bar-size: 5.5rem;
--vertical-nav-bar-size: 6rem;
--focus-outline-size: 2px;
--color-facebook: #4267b2;
--color-facebook: #1877F1;
--color-twitter: #1DA1F2;
--color-imdb: #f5c518;
--color-placeholder: #60606080;

View file

@ -280,111 +280,116 @@ const Intro = ({ queryParams }) => {
}, [routeFocused]);
return (
<div className={styles['intro-container']}>
<div className={styles['form-container']}>
<div className={styles['background-container']} />
<div className={styles['heading-container']}>
<div className={styles['logo-container']}>
<Image className={styles['logo']} src={require('/images/stremio_symbol.png')} alt={' '} />
<Icon className={styles['name']} name={'ic_stremio'} />
<Image className={styles['logo']} src={require('/images/logo.png')} alt={' '} />
</div>
<div className={styles['title-container']}>
Freedom to Stream
</div>
<div className={styles['slogan-container']}>
All the Video Content You Enjoy in One Place
</div>
</div>
<div className={styles['content-container']}>
<div className={styles['form-container']}>
<CredentialsTextInput
ref={emailRef}
className={styles['credentials-text-input']}
type={'email'}
placeholder={'Email'}
value={state.email}
onChange={emailOnChange}
onSubmit={emailOnSubmit}
/>
<CredentialsTextInput
ref={passwordRef}
className={styles['credentials-text-input']}
type={'password'}
placeholder={'Password'}
value={state.password}
onChange={passwordOnChange}
onSubmit={passwordOnSubmit}
/>
{
state.form === SIGNUP_FORM ?
<React.Fragment>
<CredentialsTextInput
ref={confirmPasswordRef}
className={styles['credentials-text-input']}
type={'password'}
placeholder={'Confirm Password'}
value={state.confirmPassword}
onChange={confirmPasswordOnChange}
onSubmit={confirmPasswordOnSubmit}
/>
<ConsentCheckbox
ref={termsRef}
className={styles['consent-checkbox']}
label={'I have read and agree with the Stremio'}
link={'Terms and conditions'}
href={'https://www.stremio.com/tos'}
checked={state.termsAccepted}
onToggle={toggleTermsAccepted}
/>
<ConsentCheckbox
ref={privacyPolicyRef}
className={styles['consent-checkbox']}
label={'I have read and agree with the Stremio'}
link={'Privacy Policy'}
href={'https://www.stremio.com/privacy'}
checked={state.privacyPolicyAccepted}
onToggle={togglePrivacyPolicyAccepted}
/>
<ConsentCheckbox
ref={marketingRef}
className={styles['consent-checkbox']}
label={'I agree to receive marketing communications from Stremio'}
checked={state.marketingAccepted}
onToggle={toggleMarketingAccepted}
/>
</React.Fragment>
:
<div className={styles['forgot-password-link-container']}>
<Button className={styles['forgot-password-link']} onClick={openPasswordRestModal}>Forgot password?</Button>
</div>
}
{
state.error.length > 0 ?
<div ref={errorRef} className={styles['error-message']}>{state.error}</div>
:
null
}
<Button className={classnames(styles['form-button'], styles['submit-button'])} onClick={state.form === SIGNUP_FORM ? signup : loginWithEmail}>
<div className={styles['label']}>{state.form === SIGNUP_FORM ? 'Sign up' : 'Log in'}</div>
</Button>
</div>
<div className={styles['options-container']}>
<Button className={classnames(styles['form-button'], styles['facebook-button'])} onClick={loginWithFacebook}>
<Icon className={styles['icon']} name={'facebook'} />
<div className={styles['label']}>Continue with Facebook</div>
</Button>
{
state.form === SIGNUP_FORM ?
<Button className={classnames(styles['form-button'], styles['login-form-button'])} onClick={switchFormOnClick}>
<div className={styles['label']}>LOG IN</div>
</Button>
:
null
}
{
state.form === LOGIN_FORM ?
<Button className={classnames(styles['form-button'], styles['signup-form-button'])} onClick={switchFormOnClick}>
<div className={styles['label']}>SIGN UP WITH EMAIL</div>
</Button>
:
null
}
<Button className={classnames(styles['form-button'], styles['guest-login-button'])} onClick={loginAsGuest}>
<div className={styles['label']}>GUEST LOGIN</div>
</Button>
</div>
<Button className={classnames(styles['form-button'], styles['facebook-button'])} onClick={loginWithFacebook}>
<Icon className={styles['icon']} name={'facebook'} />
<div className={styles['label']}>Continue with Facebook</div>
</Button>
{
state.form === SIGNUP_FORM ?
<Button className={classnames(styles['form-button'], styles['login-form-button'])} onClick={switchFormOnClick}>
Already have an account?
{' '}
<span className={styles['login-label']}>LOG IN</span>
</Button>
:
null
}
<CredentialsTextInput
ref={emailRef}
className={styles['credentials-text-input']}
type={'email'}
placeholder={'Email'}
value={state.email}
onChange={emailOnChange}
onSubmit={emailOnSubmit}
/>
<CredentialsTextInput
ref={passwordRef}
className={styles['credentials-text-input']}
type={'password'}
placeholder={'Password'}
value={state.password}
onChange={passwordOnChange}
onSubmit={passwordOnSubmit}
/>
{
state.form === SIGNUP_FORM ?
<React.Fragment>
<CredentialsTextInput
ref={confirmPasswordRef}
className={styles['credentials-text-input']}
type={'password'}
placeholder={'Confirm Password'}
value={state.confirmPassword}
onChange={confirmPasswordOnChange}
onSubmit={confirmPasswordOnSubmit}
/>
<ConsentCheckbox
ref={termsRef}
className={styles['consent-checkbox']}
label={'I have read and agree with the Stremio'}
link={'Terms and conditions'}
href={'https://www.stremio.com/tos'}
checked={state.termsAccepted}
onToggle={toggleTermsAccepted}
/>
<ConsentCheckbox
ref={privacyPolicyRef}
className={styles['consent-checkbox']}
label={'I have read and agree with the Stremio'}
link={'Privacy Policy'}
href={'https://www.stremio.com/privacy'}
checked={state.privacyPolicyAccepted}
onToggle={togglePrivacyPolicyAccepted}
/>
<ConsentCheckbox
ref={marketingRef}
className={styles['consent-checkbox']}
label={'I agree to receive marketing communications from Stremio'}
checked={state.marketingAccepted}
onToggle={toggleMarketingAccepted}
/>
</React.Fragment>
:
<div className={styles['forgot-password-link-container']}>
<Button className={styles['forgot-password-link']} onClick={openPasswordRestModal}>Forgot password?</Button>
</div>
}
{
state.error.length > 0 ?
<div ref={errorRef} className={styles['error-message']}>{state.error}</div>
:
null
}
<Button className={classnames(styles['form-button'], styles['submit-button'])} onClick={state.form === SIGNUP_FORM ? signup : loginWithEmail}>
<div className={styles['label']}>{state.form === SIGNUP_FORM ? 'Sign up' : 'Log in'}</div>
</Button>
{
state.form === SIGNUP_FORM ?
<Button className={classnames(styles['form-button'], styles['guest-login-button'])} onClick={loginAsGuest}>
<div className={styles['label']}>GUEST LOGIN</div>
</Button>
:
null
}
{
state.form === LOGIN_FORM ?
<Button className={classnames(styles['form-button'], styles['signup-form-button'])} onClick={switchFormOnClick}>
<div className={styles['label']}>SIGN UP WITH EMAIL</div>
</Button>
:
null
}
</div>
{
passwordRestModalOpen ?

View file

@ -15,16 +15,13 @@
.credentials-text-input {
width: 100%;
padding: 1rem;
color: @color-surface-dark5;
outline: var(--focus-outline-size) solid @color-surface-light2-90;
border-radius: var(--border-radius);
outline-offset: calc(-1 * var(--focus-outline-size));
&:hover {
outline-color: @color-surface-light4-90;
}
&:focus {
outline-color: @color-background-dark5-90;
color: var(--primary-foreground-color);
background: var(--primary-overlay-color);
&:hover, &:focus {
outline: var(--focus-outline-size) solid var(--primary-overlay-color);
}
}
}
@ -39,16 +36,12 @@
.cancel-button {
background-color: transparent;
&:hover {
background-color: @color-surface-light3;
}
&:focus {
outline-color: @color-background-dark5-90;
&:hover, &:focus {
outline-color: var(--primary-foreground-color);
}
.cancel-button-label {
color: @color-surface-dark4-90;
color: var(--primary-foreground-color);
}
}
}

View file

@ -4,62 +4,92 @@
@import (reference) '~stremio/common/screen-sizes.less';
.intro-container {
position: relative;
display: flex;
flex-direction: row;
flex-direction: column;
align-items: center;
justify-content: center;
width: 100%;
height: 100%;
background:
linear-gradient(@color-background-dark3-80, @color-background-dark3-80),
url('/images/intro_background.jpg');
background-size: cover;
background-repeat: no-repeat;
background-position: center;
background-origin: border-box;
overflow-y: auto;
.form-container {
.background-container {
z-index: -1;
position: fixed;
top: -1rem;
bottom: -1rem;
left: -1rem;
right: -1rem;
background: url('/images/background_1.svg'), url('/images/background_2.svg');
background-color: var(--primary-background-color);
background-position: bottom left, top right;
background-size: 53%, 54%;
background-repeat: no-repeat;
filter: blur(6rem);
}
.heading-container {
flex: none;
width: 28rem;
margin: auto;
padding: 2rem 0;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
margin-bottom: 5rem;
.logo-container {
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
flex: none;
margin-bottom: 3rem;
.logo {
flex: none;
width: 4rem;
height: 4rem;
margin-right: 1rem;
height: 5rem;
opacity: 0.9;
}
.name {
flex: none;
width: 8rem;
height: 4rem;
color: @color-surface-dark4-90;
}
}
.title-container, .slogan-container {
color: var(--primary-foreground-color);
}
.title-container {
font-size: 3rem;
font-weight: 600;
margin-bottom: 0.5rem;
}
.slogan-container {
font-size: 1.5rem;
font-weight: 400;
text-transform: lowercase;
opacity: 0.6;
&::first-letter {
text-transform: uppercase;
}
}
}
.content-container {
flex: none;
display: flex;
flex-direction: row;
align-items: flex-start;
justify-content: center;
width: 100%;
.form-button {
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
padding: 0.5rem 1rem;
height: 4rem;
border-radius: 3.5rem;
padding: 0 1rem;
.icon {
flex: none;
width: 1rem;
height: 2rem;
width: 2rem;
margin-right: 1rem;
color: @color-surface-light5-90;
color: var(--primary-foreground-color);
}
.label {
@ -67,130 +97,92 @@
flex-shrink: 1;
flex-basis: auto;
font-size: 1.1rem;
font-weight: 500;
color: @color-surface-light5-90;
font-weight: 700;
color: var(--primary-foreground-color);
text-align: center;
}
}
.facebook-button {
min-height: 4.5rem;
margin: 1rem 0;
background: var(--color-facebook);
.label {
font-size: 1.2rem;
}
}
.login-form-button {
display: block;
margin: 1rem 0;
text-align: center;
color: @color-surface-dark2-90;
&:hover {
.login-label {
text-decoration: underline;
}
}
&:focus {
outline: none;
background-color: @color-surface-light5-20;
}
.login-label {
font-weight: 500;
color: @color-accent4-light1-90;
}
}
.credentials-text-input {
display: block;
width: 100%;
margin: 1rem 0;
padding: 1rem;
border-bottom: thin solid @color-surface-90;
color: @color-surface-light5;
&:hover {
background-color: @color-surface-light5-20;
}
&:focus {
border-bottom-color: @color-secondaryvariant2-light1-90;
&::placeholder {
color: @color-secondaryvariant2-light1-90;
}
}
&::placeholder {
color: @color-surface-dark2-90;
}
}
.forgot-password-link-container {
display: flex;
flex-direction: row;
justify-content: flex-end;
margin: 1rem 0;
text-align: right;
.forgot-password-link {
flex-grow: 0;
flex-shrink: 1;
flex-basis: auto;
padding: 0.5rem 1rem;
color: @color-surface-light3-90;
&:hover {
text-decoration: underline;
color: @color-secondaryvariant2-light1-90;
}
&:focus {
outline: none;
background-color: @color-surface-light5-20;
}
}
}
.error-message {
margin: 1rem 0;
padding: 0 1rem;
text-align: center;
color: @color-accent5-90;
}
.submit-button {
min-height: 4rem;
margin: 1rem 0;
background-color: @color-accent3;
&:hover {
background-color: @color-accent3-light1;
}
.label {
font-size: 1.2rem;
}
}
.guest-login-button, .signup-form-button {
.submit-button, .guest-login-button, .signup-form-button, .login-form-button {
margin-top: 1rem;
padding: 1rem;
outline: var(--focus-outline-size) solid var(--primary-foreground-color);
background-color: transparent;
.label {
color: var(--primary-foreground-color);
}
&:hover {
background-color: var(--primary-foreground-color);
.label {
text-decoration: underline;
color: var(--secondary-foreground-color);
}
}
}
.form-container {
flex: none;
position: relative;
width: 22rem;
margin-right: 2rem;
.credentials-text-input {
display: block;
width: 100%;
margin-bottom: 1rem;
padding: 1rem;
border-radius: var(--border-radius);
outline-offset: calc(-1 * var(--focus-outline-size));
color: var(--primary-foreground-color);
background: var(--primary-overlay-color);
&:hover, &:focus {
outline: var(--focus-outline-size) solid var(--primary-overlay-color);
}
}
&:focus {
outline: none;
background-color: @color-surface-light5-20;
.forgot-password-link-container {
display: flex;
flex-direction: row;
justify-content: flex-end;
margin: 1rem 0;
text-align: right;
.forgot-password-link {
flex-grow: 0;
flex-shrink: 1;
flex-basis: auto;
padding: 0.5rem 1rem;
color: var(--primary-foreground-color);
&:hover {
text-decoration: underline;
}
}
}
.error-message {
margin: 1rem 0;
padding: 0 1rem;
text-align: center;
color: var(--tertiary-accent-color);
}
}
.options-container {
flex: none;
position: relative;
width: 22rem;
margin-left: 2rem;
.facebook-button {
background: var(--color-facebook);
&:hover, &:focus {
outline: var(--focus-outline-size) solid var(--color-facebook);
background-color: transparent;
}
}
}
}
@ -209,7 +201,8 @@
align-items: center;
justify-content: center;
padding: 2rem;
background-color: @color-surface-light5;
border-radius: var(--border-radius);
background-color: var(--tertiary-background-color);
@keyframes flash {
0% {
@ -226,13 +219,13 @@
width: 5rem;
height: 5rem;
margin-bottom: 1rem;
color: @color-background-dark5-90;
color: var(--primary-foreground-color);
animation: 1s linear infinite alternate flash;
}
.label {
font-size: 2rem;
color: @color-background-dark5-90;
font-size: 1.5rem;
color: var(--primary-foreground-color);
animation: 1s linear infinite alternate flash;
}
}
@ -240,10 +233,39 @@
@media only screen and (max-width: @minimum) {
.intro-container {
.form-container {
flex: 0 1 auto;
width: 100%;
padding: 2rem 1.5rem;
justify-content: initial;
padding: 3rem 1.5rem;
.heading-container {
align-items: flex-start;
margin-bottom: 4rem;
.logo-container {
.logo {
height: 4rem;
}
}
.title-container {
font-size: 2.5rem;
}
.slogan-container {
font-size: 1.5rem;
}
}
.content-container {
flex-direction: column-reverse;
.form-container, .options-container {
width: 100%;
margin: 0;
}
.options-container {
margin-bottom: 4rem;
}
}
}
}

View file

@ -125,7 +125,7 @@ module.exports = (env, argv) => ({
}
},
{
test: /\.(png|jpe?g)$/,
test: /\.(png|jpe?g|svg)$/,
exclude: /node_modules/,
type: 'asset/resource',
generator: {