diff options
Diffstat (limited to 'src/components/molecules/layout')
| -rw-r--r-- | src/components/molecules/layout/branding.module.scss | 125 | ||||
| -rw-r--r-- | src/components/molecules/layout/branding.tsx | 26 | 
2 files changed, 116 insertions, 35 deletions
| diff --git a/src/components/molecules/layout/branding.module.scss b/src/components/molecules/layout/branding.module.scss index aa18002..6121fa1 100644 --- a/src/components/molecules/layout/branding.module.scss +++ b/src/components/molecules/layout/branding.module.scss @@ -1,48 +1,105 @@  @use "@styles/abstracts/functions" as fun; +@use "@styles/abstracts/mixins" as mix; + +@mixin typing-animation { +  --typing-animation: none; + +  width: fit-content; +  position: relative; +  overflow: hidden; + +  &::after { +    content: "|"; +    display: block; +    width: 100%; +    height: 100%; +    position: absolute; +    top: 0; +    right: 0; +    background: var(--color-bg); +    color: var(--color-primary-darker); +    font-weight: 400; +    text-align: left; +    visibility: hidden; +    transform: translateX(100%); +    transform-origin: right; +    animation: var(--typing-animation); + +    :global { +      animation: var(--typing-animation); +    } +  } +}  .wrapper { +  --logo-size: #{clamp(fun.convert-px(90), 12vw, fun.convert-px(100))}; +    display: grid; -  grid-template-columns: -    var(--logo-size, fun.convert-px(100)) -    minmax(0, 1fr); -  grid-template-rows: 1fr min-content; -  align-items: center; -  column-gap: var(--spacing-sm); -} +  grid-template-columns: minmax(0, 1fr); +  justify-items: center; +  width: 100%; -.logo { -  grid-row: span 2; -} +  @include mix.media("screen") { +    @include mix.dimensions("2xs") { +      grid-template-columns: +        var(--logo-size, fun.convert-px(100)) +        minmax(0, 1fr); +      grid-template-rows: 1fr min-content; +      align-items: center; +      justify-items: left; +      column-gap: var(--spacing-sm); +      width: unset; +    } +  } -.title { -  font-size: var(--font-size-2xl); -} +  .logo { +    grid-row: span 2; +    margin-bottom: var(--spacing-sm); -.baseline { -  color: var(--color-fg-light); -} +    @include mix.media("screen") { +      @include mix.dimensions("2xs") { +        margin-bottom: 0; +      } +    } +  } + +  .title { +    font-size: clamp(var(--font-size-xl), 8vw, var(--font-size-2xl)); +    text-align: center; -.link { -  background: linear-gradient( -      to top, -      var(--color-primary-light) fun.convert-px(5), -      transparent fun.convert-px(5) -    ) -    left / 0 100% no-repeat; -  text-decoration: none; -  transition: all 0.6s ease-out 0s; - -  &:hover, -  &:focus { -    background-size: 100% 100%; +    @include typing-animation;    } -  &:focus { -    color: var(--color-primary-light); +  .baseline { +    color: var(--color-fg-light); +    font-size: var(--font-size-lg); +    text-align: center; + +    @include typing-animation;    } -  &:active { -    background-size: 0 100%; -    color: var(--color-primary-dark); +  .link { +    background: linear-gradient( +        to top, +        var(--color-primary-light) fun.convert-px(5), +        transparent fun.convert-px(5) +      ) +      left / 0 100% no-repeat; +    text-decoration: none; +    transition: all 0.6s ease-out 0s; + +    &:hover, +    &:focus { +      background-size: 100% 100%; +    } + +    &:focus { +      color: var(--color-primary-light); +    } + +    &:active { +      background-size: 0 100%; +      color: var(--color-primary-dark); +    }    }  } diff --git a/src/components/molecules/layout/branding.tsx b/src/components/molecules/layout/branding.tsx index 423c54f..9a82a74 100644 --- a/src/components/molecules/layout/branding.tsx +++ b/src/components/molecules/layout/branding.tsx @@ -1,6 +1,7 @@  import Heading from '@components/atoms/headings/heading'; +import useStyles from '@utils/hooks/use-styles';  import Link from 'next/link'; -import { FC } from 'react'; +import { FC, useRef } from 'react';  import { useIntl } from 'react-intl';  import FlippingLogo, { type FlippingLogoProps } from '../images/flipping-logo';  import styles from './branding.module.scss'; @@ -37,6 +38,9 @@ const Branding: FC<BrandingProps> = ({    withLink = false,    ...props  }) => { +  const baselineRef = useRef<HTMLParagraphElement>(null); +  const logoRef = useRef<HTMLDivElement>(null); +  const titleRef = useRef<HTMLHeadingElement | HTMLParagraphElement>(null);    const intl = useIntl();    const altText = intl.formatMessage(      { @@ -55,6 +59,23 @@ const Branding: FC<BrandingProps> = ({      { website: title }    ); +  useStyles({ +    property: '--typing-animation', +    styles: 'blink 0.7s ease-in-out 0s 2, typing 4.3s linear 0s 1', +    target: titleRef, +  }); +  useStyles({ +    property: '--typing-animation', +    styles: +      'hide-text 4.25s linear 0s 1, blink 0.8s ease-in-out 4.25s 2, typing 3.8s linear 4.25s 1', +    target: baselineRef, +  }); +  useStyles({ +    property: 'animation', +    styles: 'flip-logo 9s ease-in 0s 1', +    target: logoRef, +  }); +    return (      <div className={styles.wrapper}>        <FlippingLogo @@ -62,6 +83,7 @@ const Branding: FC<BrandingProps> = ({          altText={altText}          logoTitle={logoTitle}          photo={photo} +        ref={logoRef}          {...props}        />        <Heading @@ -69,6 +91,7 @@ const Branding: FC<BrandingProps> = ({          level={1}          withMargin={false}          className={styles.title} +        ref={titleRef}        >          {withLink ? (            <Link href="/"> @@ -84,6 +107,7 @@ const Branding: FC<BrandingProps> = ({            level={4}            withMargin={false}            className={styles.baseline} +          ref={baselineRef}          >            {baseline}          </Heading> | 
