feat: landing page redesign

This commit is contained in:
Hossein Mehrabi
2023-06-28 20:13:22 +03:30
parent be12ed12ac
commit c6eb842638
18 changed files with 219 additions and 89 deletions
@@ -50,11 +50,9 @@
}
}
@include utils.responsive('md', 'up') {
.mdx-cta-section:not(.mdx-cta-section--with-description) {
.mdx-cta-section__title {
max-width: 65%;
}
.mdx-cta-section:not(.mdx-cta-section--with-description) {
.mdx-cta-section__title {
max-width: 886px;
}
}
@@ -1,5 +1,8 @@
.mdx-hero {
position: relative;
display: flex;
flex-direction: column;
height: calc(100vh - var(--ifm-navbar-height) - 8px);
}
.mdx-hero--large {
@@ -19,6 +19,11 @@
flex-direction: row;
align-items: center;
justify-content: stretch;
z-index: 0;
& > * {
flex-basis: 50%;
}
> a,
> a > button {
@@ -1,4 +1,3 @@
import { Typography, TypographyProps } from '@acid-info/lsd-react'
import clsx from 'clsx'
import React from 'react'
import './HeroActions.scss'
@@ -7,37 +7,28 @@
z-index: -2;
font-weight: 100 !important;
text-shadow: 1px 1px 6px rgba(var(--lsd-surface-primary), 1);
opacity: 0.7;
line-height: 2.3rem !important;
max-width: 1280px;
margin-top: 18px;
}
.mdx-hero-description--small {
//margin-top: 1rem;
@include lsd.typography('h6');
max-width: 1200px;
}
.mdx-hero-description--large {
@include lsd.typography('h4');
}
.mdx-hero-description--medium {
@include lsd.typography('h3');
}
@include utils.responsive('lg', 'down') {
.mdx-hero-description {
margin-top: 12px;
@include lsd.typography('subtitle1');
}
.mdx-hero-description--large {
//font-size: 1.875rem !important;
//line-height: 2.25rem !important;
//text-transform: uppercase;
}
.mdx-hero-description--medium {
@include lsd.typography('subtitle1');
}
}
@@ -21,7 +21,7 @@ export const HeroDescription: React.FC<HeroDescriptionProps> = ({
return (
<Typography
variant={size === 'small' ? 'h5' : 'h2'}
variant={'h5'}
className={clsx(
className,
'mdx-hero-description',
@@ -1,17 +1,13 @@
@use '../../../css/utils';
.mdx-hero-info {
padding: var(--logos-hero-info-padding-bottom) 0
var(--logos-hero-info-padding-bottom) 0;
height: var(--logos-hero-info-height);
padding: 32px 0;
display: flex;
flex-direction: column;
justify-content: end;
border-bottom: 1px solid rgb(var(--lsd-surface-secondary));
margin-bottom: calc(100vh - var(--logos-hero-info-height));
transition: margin-bottom 0.05s ease-in-out;
}
@@ -19,7 +15,7 @@
}
@include utils.responsive('lg', 'down') {
:root {
//--logos-hero-info-height: 340px;
.mdx-hero-info {
padding: 24px 0;
}
}
@@ -1,15 +1,8 @@
import clsx from 'clsx'
import React, { PropsWithChildren, useEffect } from 'react'
import React, { PropsWithChildren } from 'react'
import { useHero } from '../Hero/Hero.context'
import { ScrollToBottom } from '../index'
import './HeroInfo.scss'
import { useScrollY } from '../../../lib/useScrollY'
import {
calcHeroInfoMb,
calcScrollThreshold,
isMobile,
mapFloat,
} from '../../../lib/ui.utils'
export type HeroInfoProps = PropsWithChildren<
React.HTMLAttributes<HTMLDivElement>
@@ -25,22 +18,11 @@ export const HeroInfo: React.FC<HeroInfoProps> = ({
}) => {
const ctx = useHero()
const size = sizeProp ? sizeProp : ctx ? ctx.size : 'medium'
const [mb, setMb] = React.useState(0)
const scrollY = useScrollY()
useEffect(() => {
if (isMobile()) {
setMb(calcHeroInfoMb(scrollY))
}
}, [scrollY])
return (
<>
<div
className={clsx(className, 'mdx-hero-info', `mdx-hero-info--${size}`)}
style={{
marginBottom: `calc(100vh - var(--logos-hero-info-height) - ${mb}px)`,
}}
{...(props as any)}
>
{children}
@@ -2,20 +2,15 @@
@use '../../../css/lsd';
.mdx-hero-title {
font-weight: 300 !important;
z-index: 1;
text-shadow: 0px 0px 6px rgba(var(--lsd-surface-primary), 0.5);
@include lsd.typography('h4');
font-size: 70px !important;
font-weight: 100 !important;
line-height: 100% !important;
}
.mdx-hero-title--large {
@include lsd.typography('h1');
//font-size: 5.0625rem !important;
//line-height: 5rem !important;
}
.mdx-hero-title--medium {
@include lsd.typography('h2');
}
.mdx-hero-title--uppercase {
@@ -24,17 +19,12 @@
@include utils.responsive('lg', 'down') {
.mdx-hero-title {
@include lsd.typography('h4');
text-transform: uppercase;
font-size: 28px !important;
}
.mdx-hero-title--medium {
@include lsd.typography('h4');
}
.mdx-hero-title--large {
//font-size: 1.875rem !important;
//line-height: 2.1rem !important;
font-size: 2.175rem !important;
line-height: 2.475rem !important;
}
}
@@ -0,0 +1,70 @@
@use '../../../css/utils';
.mdx-hero-video {
display: grid;
grid-template-rows: 1fr;
grid-template-columns: 1fr;
pointer-events: none;
--hero-video-scale: 58%;
--hero-video-offset-y: -10%;
--hero-video-scale-mobile: 117.8%;
--hero-video-offset-y-mobile: -10%;
& > * {
grid-row: 1 / 1;
grid-column: 1 / 1;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
transform: translateY(var(--hero-video-offset-y));
max-width: 100%;
height: 100%;
width: auto;
}
.mdx-hero-video__placeholder {
opacity: 0;
visibility: hidden;
}
img,
video {
width: 100%;
height: auto;
transform: scale(var(--hero-video-scale));
margin-left: calc((var(--hero-video-scale) - 100%) * -1);
transform-origin: top left;
}
}
.mdx-hero-video--loading {
.mdx-hero-video__video {
opacity: 0;
visibility: hidden;
}
.mdx-hero-video__placeholder {
opacity: 1;
visibility: visible;
}
}
@include utils.responsive('lg', 'down') {
.mdx-hero-video {
> * {
transform: translateY(var(--hero-video-offset-y-mobile));
}
img,
video {
width: 100%;
transform: scale(var(--hero-video-scale-mobile));
margin-left: calc((var(--hero-video-scale-mobile) - 100%) * -1);
}
}
}
@@ -0,0 +1,86 @@
import clsx from 'clsx'
import React, { PropsWithChildren, useEffect, useRef, useState } from 'react'
import { makeStyle } from '../../../lib/makeStyle'
import { settle } from '../../../lib/settle'
import { useHero } from '../Hero/Hero.context'
import './HeroVideo.scss'
export type HeroVideoStyle = {
scale?: string
offsetY?: string
}
export type HeroVideoProps = PropsWithChildren<
React.HTMLAttributes<HTMLDivElement>
> & {
placeholderSrc: string
desktop?: HeroVideoStyle
mobile?: HeroVideoStyle
}
export const HeroVideo: React.FC<HeroVideoProps> = ({
placeholderSrc,
desktop,
mobile,
className,
style = {},
children,
...props
}) => {
const ctx = useHero()
const ref = useRef<HTMLVideoElement>(null)
const [loading, setLoading] = useState(true)
const play = async () => {
const el = ref.current
if (!el) return
await settle(() => el.play())
}
const onCanPlay = async () => {
loading && setLoading(false)
await play()
}
const onEnded = async () => {
await play()
}
return (
<>
<div
className={clsx(
className,
'mdx-hero-video',
loading && 'mdx-hero-video--loading',
)}
style={makeStyle(
{ ...style },
{
'hero-video-scale': desktop?.scale ?? '58%',
'hero-video-offset-y': desktop?.offsetY ?? '-10%',
'hero-video-scale-mobile': mobile?.scale ?? '117.8%',
'hero-video-offset-y-desktop': mobile?.offsetY ?? '-10%',
},
)}
{...(props as any)}
>
<div className="mdx-hero-video__placeholder">
<img src={placeholderSrc} alt="" />
</div>
<div className="mdx-hero-video__video">
<video
muted
autoPlay
onEnded={onEnded}
onCanPlay={onCanPlay}
ref={ref}
>
{children}
</video>
</div>
</div>
</>
)
}
@@ -0,0 +1 @@
export * from './HeroVideo'
@@ -1,9 +1,10 @@
import { ArrowDownIcon, IconButton } from '@acid-info/lsd-react'
import clsx from 'clsx'
import React, { HTMLProps } from 'react'
import styles from './styles.module.scss'
import { useHydrated } from '../../../lib/useHydrated'
import { useIsMobile } from '../../../lib/useIsMobile'
import { useScrollY } from '../../../lib/useScrollY'
import { calcHeroInfoMb, isMobile } from '../../../lib/ui.utils'
import styles from './styles.module.scss'
type TProps = {}
@@ -11,7 +12,10 @@ export const ScrollToBottom = (
props: TProps & HTMLProps<HTMLButtonElement>,
): JSX.Element => {
const { children, className, ...rest } = props
const isHydrated = useHydrated()
const scrollY = useScrollY()
const isMobile = useIsMobile()
const handleScrollToBottom = () => {
const article = document.querySelector('.main-wrapper article')
const secondElement = article?.children?.[1]
@@ -22,22 +26,21 @@ export const ScrollToBottom = (
behavior: 'smooth',
})
if (isMobile()) {
window.scrollTo(0, secondElement.getBoundingClientRect().top - 200)
} else {
;(secondElement as HTMLElement)?.scrollIntoView?.({ behavior: 'smooth' })
}
return
return window.scrollTo({
left: 0,
top: secondElement.getBoundingClientRect().top - (isMobile ? 200 : 0),
behavior: 'smooth',
})
}
return (
<IconButton
onClick={handleScrollToBottom}
size="small"
size={isMobile ? 'small' : 'large'}
className={clsx(
styles.scrollToBottom,
className,
scrollY > 20 ? styles.hide : '',
(scrollY > 20 || !isHydrated) && styles.hide,
)}
{...(rest as any)}
>
@@ -13,7 +13,5 @@
transform: translateY(-10px);
}
bottom: calc(
var(--ifm-navbar-height) + var(--logos-hero-info-height) - 100vh + 16px
);
bottom: 2rem;
}
@@ -13,3 +13,4 @@ export * from './HeroTitle'
export * from './PoweredBy'
export * from './ScrollToBottom'
export * from './Showcase'
export * from './HeroVideo'
@@ -1,6 +1,13 @@
@mixin typography($variant) {
font-size: var(--lsd-#{$variant}-fontSize) !important;
line-height: var(--lsd-#{$variant}-lineHeight) !important;
font-family: var(--lsd-typography-generic-font-family) !important;
font-weight: 400 !important;
@mixin typography($variant, $important: true) {
@if $important == true {
font-size: var(--lsd-#{$variant}-fontSize) !important;
line-height: var(--lsd-#{$variant}-lineHeight) !important;
font-family: var(--lsd-typography-generic-font-family) !important;
font-weight: 400 !important;
} @else {
font-size: var(--lsd-#{$variant}-fontSize);
line-height: var(--lsd-#{$variant}-lineHeight);
font-family: var(--lsd-typography-generic-font-family);
font-weight: 400;
}
}
@@ -299,19 +299,19 @@ svg * {
}
h1 {
@include lsd.typography('h1');
@include lsd.typography('h1', false);
}
h2 {
@include lsd.typography('h2');
@include lsd.typography('h2', false);
}
h3 {
@include lsd.typography('h3');
@include lsd.typography('h3', false);
}
h4 {
@include lsd.typography('h4');
@include lsd.typography('h4', false);
}
code {
@@ -335,11 +335,6 @@ a code {
--ifm-navbar-item-padding-vertical: 8px;
--ifm-navbar-item-padding-horizontal: 12px;
--logos-navbar-height: var(--ifm-navbar-height);
--logos-hero-info-height: 420px;
--logos-hero-info-padding-top: 32px;
--logos-hero-info-padding-bottom: 32px;
}
.card,
@@ -1218,4 +1213,8 @@ code {
overflow: auto;
}
#__docusaurus {
overflow: hidden;
}
@import './blog.scss';
@@ -1,8 +1,9 @@
export const settle = async <R, E = Error>(
promise: Promise<R>,
promise: Promise<R> | (() => Promise<R>),
): Promise<[R, undefined] | [undefined, E]> => {
try {
const result: R = await promise
const result: R =
typeof promise === 'function' ? await promise() : await promise
return [result, undefined]
} catch (error) {
return [undefined, error as E]