├── .gitignore ├── README.md ├── components └── GlowingButton │ ├── Browser.tsx │ ├── Credits.tsx │ ├── Intro.tsx │ └── Stars.tsx ├── lib ├── createSVGMask.ts └── useElementSize.ts ├── next.config.js ├── package.json ├── pages ├── Loader.tsx ├── Normal.tsx ├── Special.tsx ├── _app.tsx ├── _document.tsx └── index.tsx ├── public ├── favicon.ico ├── grid.svg ├── lights.png ├── nusu_pp.png ├── oguz_pp.png └── stars.svg ├── styles └── globals.css ├── tsconfig.json └── yarn.lock /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # next.js 12 | /.next/ 13 | /out/ 14 | 15 | # production 16 | /build 17 | 18 | # misc 19 | .DS_Store 20 | *.pem 21 | 22 | # debug 23 | npm-debug.log* 24 | yarn-debug.log* 25 | yarn-error.log* 26 | .pnpm-debug.log* 27 | 28 | # local env files 29 | .env*.local 30 | 31 | # vercel 32 | .vercel 33 | 34 | # typescript 35 | *.tsbuildinfo 36 | next-env.d.ts 37 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Glowing Button 2 | 3 | A glowing transparent button experiment by [@nusualabuga](https://twitter.com/nusualabuga) and [@oguzyagizkara](https://twitter.com/oguzyagizkara) 4 | 5 | ## Preview: 6 | 7 | https://user-images.githubusercontent.com/1702215/214709198-54e73373-ed00-4556-a752-ab04ebceadfd.mp4 8 | 9 | 10 | ## Demo: 11 | https://react-glowing-button.vercel.app/ 12 | -------------------------------------------------------------------------------- /components/GlowingButton/Browser.tsx: -------------------------------------------------------------------------------- 1 | import styled, { css } from "styled-components" 2 | import { motion } from "framer-motion" 3 | import { useEffect, useRef, useState } from "react" 4 | 5 | 6 | const Wrapper = styled.div<{m?: string}>` 7 | position: relative; 8 | ${p => p.m && `margin: ${p.m};`} 9 | &:before { 10 | content: ""; 11 | width: 665px; 12 | height: 470px; 13 | background: url(/grid.svg); 14 | background-size: cover; 15 | position: absolute; 16 | top: calc(50% - 235px); 17 | right: calc(50% - 332px); 18 | } 19 | ` 20 | 21 | const BrowserPanel = styled.div` 22 | width: 400px; 23 | height: 200px; 24 | background: radial-gradient(63.94% 63.94% at 50% 0%, rgba(255, 255, 255, 0.12) 0%, rgba(255, 255, 255, 0) 100%), rgba(255, 255, 255, 0.01); 25 | backdrop-filter: blur(6px); 26 | border-radius: 10px; 27 | position: relative; 28 | 29 | &:before { 30 | content: ""; 31 | width: calc(100% + 2px); 32 | height: calc(100% + 2px); 33 | background: linear-gradient(180deg, rgba(255, 255, 255, 0.12) 0%, rgba(255, 255, 255, 0) 74.04%), 34 | linear-gradient(0deg, rgba(255, 255, 255, 0.04), rgba(255, 255, 255, 0.04)); 35 | position: absolute; 36 | top: -1px; 37 | left: -1px; 38 | mask: url("data:image/svg+xml,%3Csvg width='402' height='202' viewBox='0 0 402 202' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Crect x='0.5' y='0.5' width='401' height='201' rx='9.5' stroke='black'/%3E%3C/svg%3E%0A"); 39 | mask-mode: alpha; 40 | pointer-events: none; 41 | } 42 | 43 | &:after { 44 | content: ""; 45 | background-image: url("data:image/svg+xml,%3Csvg width='52' height='12' viewBox='0 0 52 12' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Ccircle cx='6' cy='6' r='6' fill='%23020308' fill-opacity='0.12'/%3E%3Ccircle cx='6' cy='6' r='5.5' stroke='white' stroke-opacity='0.1'/%3E%3Ccircle cx='26' cy='6' r='6' fill='%23020308' fill-opacity='0.12'/%3E%3Ccircle cx='26' cy='6' r='5.5' stroke='white' stroke-opacity='0.1'/%3E%3Ccircle cx='46' cy='6' r='6' fill='%23020308' fill-opacity='0.12'/%3E%3Ccircle cx='46' cy='6' r='5.5' stroke='white' stroke-opacity='0.1'/%3E%3C/svg%3E%0A"); 46 | position: absolute; 47 | top: 12px; 48 | left: 12px; 49 | width: 52px; 50 | height: 12px; 51 | } 52 | ` 53 | 54 | const NavigatorLeftBG = styled.div<{width?: number}>` 55 | background: rgba(0, 0, 0, 0.16); 56 | border-bottom-right-radius: 6px; 57 | min-width: 84px; 58 | width: ${p => p.width}px; 59 | height: 36px; 60 | position: absolute; 61 | top: 0; 62 | left: 0; 63 | pointer-events: none; 64 | 65 | transition: 300ms all; 66 | 67 | &:before { 68 | content: ""; 69 | position: absolute; 70 | inset: 0; 71 | border-top-left-radius: 6px; 72 | border-bottom-right-radius: 6px; 73 | padding: 1px; 74 | transition: 300ms all; 75 | background: radial-gradient(100% 148.61% at 90% 148.61%, rgba(255, 255, 255, 0.24) 0%, rgba(255, 255, 255, 0) 100%); 76 | -webkit-mask: 77 | linear-gradient(#fff 0 0) content-box, 78 | linear-gradient(#fff 0 0); 79 | -webkit-mask-composite: xor; 80 | mask-composite: exclude; 81 | } 82 | ` 83 | 84 | const NavigatorRightBG = styled(NavigatorLeftBG)` 85 | height: 36px; 86 | border-bottom-right-radius: 0; 87 | min-width: 56px; 88 | left: unset; 89 | right: 0; 90 | 91 | &:before { 92 | border-top-left-radius: 0; 93 | border-bottom-left-radius: 6px; 94 | background: radial-gradient(100% 148.61% at 0% 148.61%, rgba(255, 255, 255, 0.24) 0%, rgba(255, 255, 255, 0) 100%); 95 | } 96 | ` 97 | 98 | const Navigation = styled.div` 99 | display: flex; 100 | align-items: center; 101 | ` 102 | 103 | const Tabs = styled.div` 104 | display: flex; 105 | align-items: center; 106 | margin-left: 84px; 107 | height: 36px; 108 | 109 | ` 110 | 111 | const Item = styled.div<{active?: boolean}>` 112 | min-width: 80px; 113 | font-family: 'Inter'; 114 | font-style: normal; 115 | font-weight: 400; 116 | font-size: 14px; 117 | line-height: 24px; 118 | text-align: center; 119 | 120 | background: ${ p => p.active ? 'linear-gradient(180deg, rgba(255, 255, 255, 0.3) 8.85%, #FFFFFF 100%);' : 'linear-gradient(180deg, rgba(255, 255, 255, 0.15) 8.85%, rgba(255, 255, 255, 0.5) 100%)'}; 121 | -webkit-background-clip: text; 122 | -webkit-text-fill-color: transparent; 123 | background-clip: text; 124 | text-fill-color: transparent; 125 | cursor: pointer; 126 | position: relative; 127 | border-top-left-radius: 6px; 128 | border-top-right-radius: 6px; 129 | 130 | &:before { 131 | content: ''; 132 | width: 100%; 133 | height: 30px; 134 | position: absolute; 135 | border-top-left-radius: 6px; 136 | border-top-right-radius: 6px; 137 | top: -7px; 138 | left: 0; 139 | overflow: hidden; 140 | /* background: radial-gradient(39% 100% at 38% 0%,rgba(255,255,255,0.32) 0%,rgba(255,255,255,0) 100%), radial-gradient(100% 100% at 30.75% 0%,rgba(255,255,255,0.12) 0%,rgba(255,255,255,0) 100%); */ 141 | background: radial-gradient(39% 100% at 48% -20%,rgba(255,255,255,0.32) 0%,rgba(255,255,255,0) 100%),radial-gradient(100% 100% at 30.75% 0%,rgba(255,255,255,0.12) 60%,rgba(255,255,255,0) 100%); 142 | transition: 300ms all; 143 | opacity: ${p => p.active ? .5 : 0}; 144 | transition-delay: ${p => p.active ? '220ms' : '0'}; 145 | } 146 | ` 147 | 148 | const Content = styled.div` 149 | display: flex; 150 | align-items: center; 151 | justify-content: center; 152 | height: 165px; 153 | ` 154 | 155 | interface Props { 156 | children: React.ReactNode 157 | m?: string 158 | onActiveTabChange: (val: number) => void 159 | } 160 | 161 | export default function Browser(props: Props) { 162 | const TabsRef = useRef(null) 163 | 164 | const [left, setLeft] = useState(0); 165 | const [right, setRight] = useState(0); 166 | const refs = useRef([]); 167 | const [activeTab, setActiveTab] = useState(1); 168 | 169 | useEffect(() => { 170 | if (refs.current.length > 0) { 171 | const activeRef = refs.current[activeTab - 1]; 172 | setLeft(activeRef.offsetLeft); 173 | // @ts-ignore 174 | setRight(activeRef.parentNode.parentNode.offsetWidth - (activeRef.offsetLeft + activeRef.offsetWidth)); 175 | 176 | props.onActiveTabChange(activeTab) 177 | } 178 | }, [activeTab]); 179 | 180 | 181 | return ( 182 | 183 | 184 | 185 | 186 | 187 | el && refs.current.push(el)} active={activeTab === 1} onClick={() => setActiveTab(1)}>Normal 188 | el && refs.current.push(el)} active={activeTab === 2} onClick={() => setActiveTab(2)}>Loader 189 | el && refs.current.push(el)} active={activeTab === 3} onClick={() => setActiveTab(3)}>Special 190 | 191 | 192 | 193 | 194 | {props.children} 195 | 196 | 197 | 198 | ) 199 | } -------------------------------------------------------------------------------- /components/GlowingButton/Credits.tsx: -------------------------------------------------------------------------------- 1 | import styled from "styled-components" 2 | 3 | const Wrapper = styled.div` 4 | display: flex; 5 | gap: 40px; 6 | justify-content: center; 7 | align-items: center; 8 | margin-top: 132px; 9 | ` 10 | 11 | const MiddleLine = styled.div` 12 | width: 1px; 13 | height: 48px; 14 | background-image: url("data:image/svg+xml,%3Csvg width='1' height='48' viewBox='0 0 1 48' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cline x1='0.5' y1='2.18557e-08' x2='0.499998' y2='48' stroke='url(%23paint0_radial_1_187)' stroke-opacity='0.1'/%3E%3Cdefs%3E%3CradialGradient id='paint0_radial_1_187' cx='0' cy='0' r='1' gradientUnits='userSpaceOnUse' gradientTransform='translate(-3.4969e-07 24) rotate(90) scale(24 16)'%3E%3Cstop offset='0.235042' stop-color='white'/%3E%3Cstop offset='1' stop-color='white' stop-opacity='0'/%3E%3C/radialGradient%3E%3C/defs%3E%3C/svg%3E%0A"); 15 | ` 16 | 17 | const Item = styled.a` 18 | padding: 12px 16px; 19 | border-radius: 10px; 20 | width: 210px; 21 | height: 72px; 22 | display: flex; 23 | gap: 16px; 24 | align-items: center; 25 | position: relative; 26 | background: radial-gradient(46.41% 74.04% at 50% 0%, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0) 100%); 27 | transition: 1s all; 28 | 29 | &:before { 30 | content: ""; 31 | width: calc(100% + 2px); 32 | height: calc(100% + 2px); 33 | border-radius: 10px; 34 | background: radial-gradient(46.41% 74.04% at 50% 0%, rgba(255, 255, 255, 0.12) 0%, rgba(255, 255, 255, 0) 100%); 35 | position: absolute; 36 | top: -1px; 37 | left: -1px; 38 | mask: url("data:image/svg+xml,%3Csvg width='210' height='72' viewBox='0 0 210 72' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Crect x='0.5' y='0.5' width='209' height='72' rx='9.5' stroke='black'/%3E%3C/svg%3E%0A"); 39 | mask-repeat: no-repeat; 40 | mask-mode: alpha; 41 | pointer-events: none; 42 | } 43 | 44 | &:hover { 45 | background: radial-gradient(46.41% 74.04% at 50% 0%, rgba(255, 255, 255, 0.12) 0%, rgba(255, 255, 255, 0) 100%); 46 | 47 | :before { 48 | background: radial-gradient(46.41% 74.04% at 50% 0%, rgba(255, 255, 255, 0.12) 0%, rgba(255, 255, 255, 0) 100%), 49 | radial-gradient(50% 100% at 50% 0%, rgba(255, 255, 255, 0.12) 0%, rgba(255, 255, 255, 0) 100%), 50 | linear-gradient(0deg, rgba(255, 255, 255, 0.06), rgba(255, 255, 255, 0.06)), 51 | linear-gradient(0deg, rgba(255, 255, 255, 0.01), rgba(255, 255, 255, 0.01)); 52 | } 53 | } 54 | 55 | 56 | p { 57 | &:first-child { 58 | font-family: 'Inter'; 59 | font-style: normal; 60 | font-weight: 400; 61 | font-size: 14px; 62 | line-height: 24px; 63 | letter-spacing: -0.02em; 64 | background: linear-gradient(180deg, rgba(255, 255, 255, 0.72) 8.85%, #FFFFFF 100%); 65 | -webkit-background-clip: text; 66 | -webkit-text-fill-color: transparent; 67 | background-clip: text; 68 | text-fill-color: transparent; 69 | } 70 | &:last-child { 71 | font-family: 'Inter'; 72 | font-style: normal; 73 | font-weight: 400; 74 | font-size: 14px; 75 | line-height: 24px; 76 | letter-spacing: -0.02em; 77 | color: rgba(255, 255, 255, 0.5); 78 | } 79 | } 80 | ` 81 | 82 | export default function Credits() { 83 | 84 | return ( 85 | 86 | 87 | 88 |
89 |

Design

90 |

@oguzyagizkara

91 |
92 |
93 | 94 | 95 | 96 |
97 |

Code

98 |

@nusualabuga

99 |
100 |
101 |
102 | ) 103 | } -------------------------------------------------------------------------------- /components/GlowingButton/Intro.tsx: -------------------------------------------------------------------------------- 1 | import styled from "styled-components" 2 | 3 | const H1 = styled.h1` 4 | font-family: "Inter"; 5 | font-weight: 400; 6 | font-size: 40px; 7 | line-height: 48px; 8 | /* identical to box height, or 120% */ 9 | 10 | text-align: center; 11 | 12 | background: radial-gradient(123.44% 123.44% at 56.63% 100%, #ECECEE 6.77%, rgba(255, 255, 255, 0.45) 100%); 13 | -webkit-background-clip: text; 14 | -webkit-text-fill-color: transparent; 15 | background-clip: text; 16 | text-fill-color: transparent; 17 | 18 | ` 19 | 20 | const P = styled.p` 21 | font-family: 'Inter V', 'Inter'; 22 | font-style: normal; 23 | font-weight: 400; 24 | font-size: 20px; 25 | line-height: 32px; 26 | /* identical to box height, or 160% */ 27 | 28 | text-align: center; 29 | letter-spacing: -0.01em; 30 | 31 | background: radial-gradient(123.44% 123.44% at 56.63% 100%, rgba(236, 236, 238, 0.5) 6.77%, rgba(255, 255, 255, 0.225) 100%); 32 | -webkit-background-clip: text; 33 | -webkit-text-fill-color: transparent; 34 | background-clip: text; 35 | text-fill-color: transparent; 36 | ` 37 | 38 | const Wrapper = styled.div` 39 | display: flex; 40 | flex-direction: column; 41 | gap: 8px; 42 | ` 43 | 44 | export default function Intro() { 45 | return ( 46 | 47 |

Glowing Button.

48 |

A magical button, interact with it.

49 |
50 | ) 51 | } -------------------------------------------------------------------------------- /components/GlowingButton/Stars.tsx: -------------------------------------------------------------------------------- 1 | import styled from "styled-components" 2 | import { motion } from 'framer-motion' 3 | 4 | const Wrapper = styled.div` 5 | position: absolute; 6 | width: 100vw; 7 | height: 100vh; 8 | top: 0; 9 | mask: url('/stars.svg'); 10 | overflow: hidden; 11 | pointer-events: none; 12 | ` 13 | 14 | const Gradient = styled.div` 15 | width: 40vw; 16 | height: 40vw; 17 | background: radial-gradient(50% 50% at 50% 50%, #000000 24.68%, #FFFFFF 41.49%, #000000 50%, #000000 72.92%, #FFFFFF 89.06%, #000000 96.88%); 18 | border-radius: 999px; 19 | position: absolute; 20 | left: calc(50% - 20vw); 21 | top: 5vw; 22 | ` 23 | 24 | export default function Stars() { 25 | return ( 26 | 27 | 31 | 32 | ) 33 | } -------------------------------------------------------------------------------- /lib/createSVGMask.ts: -------------------------------------------------------------------------------- 1 | export default function createSVGMask(width:number, height: number) { 2 | let svg = ` 3 | 4 | `; 5 | 6 | return "data:image/svg+xml," + encodeURIComponent(svg); 7 | } -------------------------------------------------------------------------------- /lib/useElementSize.ts: -------------------------------------------------------------------------------- 1 | import { useCallback, useState } from 'react' 2 | 3 | import { useEventListener, useIsomorphicLayoutEffect } from 'usehooks-ts' 4 | 5 | interface Size { 6 | width: number 7 | height: number 8 | } 9 | 10 | function useElementSize(): [ 11 | (node: HTMLButtonElement | null) => void, 12 | Size, 13 | ] { 14 | // Mutable values like 'ref.current' aren't valid dependencies 15 | // because mutating them doesn't re-render the component. 16 | // Instead, we use a state as a ref to be reactive. 17 | const [ref, setRef] = useState(null) 18 | const [size, setSize] = useState({ 19 | width: 0, 20 | height: 0, 21 | }) 22 | 23 | // Prevent too many rendering using useCallback 24 | const handleSize = useCallback(() => { 25 | setSize({ 26 | width: ref?.offsetWidth || 0, 27 | height: ref?.offsetHeight || 0, 28 | }) 29 | // eslint-disable-next-line react-hooks/exhaustive-deps 30 | }, [ref?.offsetHeight, ref?.offsetWidth]) 31 | 32 | useEventListener('resize', handleSize) 33 | 34 | useIsomorphicLayoutEffect(() => { 35 | handleSize() 36 | // eslint-disable-next-line react-hooks/exhaustive-deps 37 | }, [ref?.offsetHeight, ref?.offsetWidth]) 38 | 39 | return [setRef, size] 40 | } 41 | 42 | export default useElementSize -------------------------------------------------------------------------------- /next.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('next').NextConfig} */ 2 | const nextConfig = { 3 | reactStrictMode: true, 4 | compiler: { 5 | styledComponents: true, 6 | }, 7 | typescript: { 8 | ignoreBuildErrors: true, 9 | }, 10 | } 11 | 12 | module.exports = nextConfig 13 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "glowing-button", 3 | "version": "1.0.0", 4 | "scripts": { 5 | "dev": "next dev", 6 | "build": "next build", 7 | "start": "next start", 8 | "lint": "next lint" 9 | }, 10 | "dependencies": { 11 | "@next/font": "13.1.1", 12 | "@types/node": "18.11.18", 13 | "@types/react": "17.0.2", 14 | "@types/react-dom": "17.0.2", 15 | "@types/styled-components": "^5.1.26", 16 | "framer-motion": "6.5.1", 17 | "next": "12.2.5", 18 | "react": "17.0.2", 19 | "react-dom": "17.0.2", 20 | "styled-components": "5.3.5", 21 | "typescript": "4.9.4", 22 | "usehooks-ts": "^2.9.1" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /pages/Loader.tsx: -------------------------------------------------------------------------------- 1 | import { animate, motion, useAnimationControls, useMotionValue } from "framer-motion"; 2 | import createSVGMask from "lib/createSVGMask"; 3 | import useElementSize from "lib/useElementSize"; 4 | import { useEffect, useRef, useState } from "react"; 5 | import styled, { keyframes } from "styled-components"; 6 | 7 | 8 | const buttonHover = keyframes` 9 | to { 10 | --radialWidth: 120%; 11 | --radialLength: 85%; 12 | } 13 | ` 14 | 15 | const buttonHoverOut = keyframes` 16 | from { 17 | --radialWidth: 120%; 18 | --radialLength: 85%; 19 | } 20 | to { 21 | --radialWidth: 40%; 22 | --radialLength: 10%; 23 | } 24 | ` 25 | 26 | const Button = styled.button<{noBorder?: boolean}>` 27 | @property --border-angle { 28 | syntax: ""; 29 | initial-value: 0turn; 30 | inherits: false; 31 | } 32 | 33 | @property --position { 34 | syntax: ""; 35 | initial-value: 20%; 36 | inherits: false; 37 | } 38 | 39 | @property --radialWidth { 40 | syntax: ""; 41 | initial-value: 60%; 42 | inherits: false; 43 | } 44 | 45 | @property --radialLength { 46 | syntax: ""; 47 | initial-value: 10%; 48 | inherits: false; 49 | } 50 | 51 | --radialWidth: 40%; 52 | --radialLength: 10%; 53 | 54 | position: relative; 55 | font-family: "Inter"; 56 | box-sizing: border-box; 57 | font-size: 14px; 58 | line-height: 24px; 59 | width: 40px; 60 | min-height: 40px; 61 | padding: 8px 16px; 62 | border: none; 63 | stroke: 0; 64 | -webkit-appearance: none; 65 | /* make this black if you want to rotating conic gradient */ 66 | background-color: transparent; 67 | border-radius: 999px; 68 | cursor: pointer; 69 | /* opacity: .5; */ 70 | ${ p => !p.noBorder && ` 71 | &:before { 72 | content: ""; 73 | width: calc(100% + 2px); 74 | height: calc(100% + 2px); 75 | position: absolute; 76 | top: -2px; 77 | left: -2px; 78 | border-radius: 999px; 79 | border: 1px solid rgba(255, 255, 255, 0.1); 80 | } 81 | `} 82 | 83 | &:after { 84 | content: ""; 85 | width: calc(100% + 4px); 86 | height: calc(100% + 4px); 87 | position: absolute; 88 | left: -2px; 89 | top: -2px; 90 | opacity: 0; 91 | background: radial-gradient(var(--radialLength) var(--radialWidth) at 50% 120%, rgba(255, 255, 255, 0.24) 0%, rgba(255, 255, 255, 0) 100%); 92 | 93 | transition: 1s all; 94 | border-radius: 999px; 95 | animation: .4s ${buttonHoverOut} forwards; 96 | } 97 | 98 | &:hover { 99 | &:after { 100 | content: ""; 101 | opacity: .7; 102 | animation: .4s ${buttonHover} forwards; 103 | } 104 | } 105 | 106 | span { 107 | background: linear-gradient(180deg, rgba(255, 255, 255, 0.3) 8.85%, #FFFFFF 100%); 108 | -webkit-background-clip: text; 109 | -webkit-text-fill-color: transparent; 110 | background-clip: text; 111 | text-fill-color: transparent; 112 | } 113 | ` 114 | 115 | const ButtonWrapper = styled.div` 116 | position: relative; 117 | overflow: hidden; 118 | border-radius: 999px; 119 | padding: 2px 2px; 120 | ` 121 | 122 | const Border = styled.div<{size: number, buttonWidth: number, buttonHeight: number}>` 123 | --border-size: 15px; 124 | --border-angle: 0turn; 125 | pointer-events: none; 126 | background-image: 127 | conic-gradient( 128 | from var(--border-angle) at 50% 50%, 129 | rgba(255, 255, 255, 0.5) 0deg, rgba(255, 255, 255, 0) 60deg, rgba(255, 255, 255, 0) 310deg, rgba(255, 255, 255, 0.5) 360deg); 130 | background-size: calc(100% - (var(--border-size) * 2)) 131 | calc(100% - (var(--border-size) * 2)), 132 | cover; 133 | 134 | position: absolute; 135 | bottom: calc(50% - ${p => p.size / 2}px); 136 | left: calc(50% - ${p => p.size / 2}px); 137 | 138 | /* it should be square */ 139 | width: ${p => p.size}px; 140 | height: ${p => p.size}px; 141 | 142 | background-position: center; 143 | background-repeat: no-repeat; 144 | 145 | mask: url(${p => createSVGMask(p.buttonWidth + 4, p.buttonHeight + 4)}); 146 | mask-size: ${p => p.buttonWidth + 4}px ${p => p.buttonHeight + 4}px; 147 | mask-position: center; 148 | mask-repeat: no-repeat; 149 | mask-mode: alpha; 150 | ` 151 | 152 | const Glow = styled(Border)` 153 | filter: blur(8px); 154 | opacity: .15; 155 | z-index: 5; 156 | mask: none; 157 | ` 158 | 159 | const Stars = styled(Border)` 160 | mask: url("data:image/svg+xml,%3Csvg width='28' height='24' viewBox='0 0 28 24' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M14.0534 15.732C13.8444 15.283 14.2848 14.8489 14.7326 15.051C14.8296 15.0959 14.9043 15.1707 14.949 15.268C15.1506 15.717 14.7177 16.1511 14.2698 15.949C14.1728 15.9041 14.0982 15.8293 14.0534 15.732Z' fill='black'/%3E%3Cpath d='M18.8001 13.5093C19.0016 13.0603 18.5687 12.6263 18.1209 12.8283C18.0239 12.8732 17.9492 12.9481 17.9045 13.0453C17.6955 13.4944 18.1358 13.9284 18.5837 13.7264C18.6807 13.6815 18.7553 13.6066 18.8001 13.5093Z' fill='black'/%3E%3Cpath d='M0.949043 2.732C1.15057 2.28297 0.717663 1.84891 0.269836 2.05097C0.172806 2.09587 0.098162 2.17071 0.0533793 2.268C-0.155607 2.71703 0.284759 3.15109 0.732587 2.94903C0.829616 2.90413 0.90426 2.82929 0.949043 2.732Z' fill='black'/%3E%3Cpath d='M26.9489 7.732C27.151 7.28297 26.7169 6.84891 26.2679 7.05097C26.1706 7.09587 26.0958 7.17071 26.0508 7.268C25.8488 7.71703 26.2828 8.15109 26.7319 7.94903C26.8292 7.90413 26.904 7.82929 26.9489 7.732Z' fill='black'/%3E%3Cpath d='M13.0534 5.732C12.8444 5.28297 13.2848 4.84891 13.7326 5.05097C13.8296 5.09587 13.9043 5.17071 13.949 5.268C14.1506 5.71703 13.7177 6.15109 13.2698 5.94903C13.1728 5.90413 13.0982 5.82929 13.0534 5.732Z' fill='black'/%3E%3Cpath d='M10.0534 17.732C9.84439 17.283 10.2848 16.8489 10.7326 17.051C10.8296 17.0959 10.9043 17.1707 10.949 17.268C11.1506 17.717 10.7177 18.1511 10.2698 17.949C10.1728 17.9041 10.0982 17.8293 10.0534 17.732Z' fill='black'/%3E%3Cpath d='M15.0534 21.732C14.8444 21.283 15.2848 20.8489 15.7326 21.051C15.8296 21.0959 15.9043 21.1707 15.949 21.268C16.1506 21.717 15.7177 22.1511 15.2698 21.949C15.1728 21.9041 15.0982 21.8293 15.0534 21.732Z' fill='black'/%3E%3C/svg%3E%0A"); 161 | mask-size: auto; 162 | mask-repeat: repeat; 163 | ` 164 | 165 | interface Props { 166 | children?: React.ReactNode 167 | noBorder?: boolean 168 | noStar?: boolean 169 | } 170 | 171 | export default function GradientButton(props: Props) { 172 | const controls = useAnimationControls() 173 | const turn = useMotionValue('0turn') 174 | const [buttonRef, { width, height }] = useElementSize() 175 | 176 | useEffect(() => { 177 | animate(turn, '1turn', { 178 | repeat: Infinity, 179 | duration: 6, 180 | ease: "linear", 181 | }) 182 | 183 | return controls.stop 184 | }, []) 185 | 186 | 187 | function generateSquareMask() { 188 | const dimensions = width + 50 // safe distance 189 | 190 | return dimensions 191 | } 192 | 193 | const target = useRef(null) 194 | 195 | return( 196 |
197 | 198 | 206 | 214 | {!props.noStar && 215 | 223 | } 224 | 225 | 226 |
227 | ) 228 | } -------------------------------------------------------------------------------- /pages/Normal.tsx: -------------------------------------------------------------------------------- 1 | import { motion } from "framer-motion"; 2 | import createSVGMask from "lib/createSVGMask"; 3 | import useElementSize from "lib/useElementSize"; 4 | import styled, { keyframes } from "styled-components"; 5 | 6 | const buttonHover = keyframes` 7 | to { 8 | --radialWidth: 120%; 9 | --radialLength: 85%; 10 | } 11 | ` 12 | 13 | const buttonHoverOut = keyframes` 14 | from { 15 | --radialWidth: 120%; 16 | --radialLength: 85%; 17 | } 18 | to { 19 | --radialWidth: 40%; 20 | --radialLength: 10%; 21 | } 22 | ` 23 | 24 | const Button = styled.button` 25 | --radialWidth: 40%; 26 | --radialLength: 10%; 27 | 28 | position: relative; 29 | font-family: "Inter"; 30 | box-sizing: border-box; 31 | font-size: 14px; 32 | line-height: 24px; 33 | padding: 8px 16px; 34 | border: none; 35 | stroke: 0; 36 | -webkit-appearance: none; 37 | /* make this black if you want to rotating conic gradient */ 38 | background-color: transparent; 39 | border-radius: 999px; 40 | cursor: pointer; 41 | /* opacity: .5; */ 42 | &:before { 43 | content: ""; 44 | width: calc(100% + 2px); 45 | height: calc(100% + 2px); 46 | position: absolute; 47 | top: -2px; 48 | left: -2px; 49 | border-radius: 999px; 50 | border: 1px solid rgba(255, 255, 255, 0.1); 51 | } 52 | 53 | &:after { 54 | content: ""; 55 | width: calc(100% + 4px); 56 | height: calc(100% + 4px); 57 | position: absolute; 58 | left: -2px; 59 | top: -2px; 60 | opacity: 0; 61 | background: radial-gradient(var(--radialLength) var(--radialWidth) at 50% 120%, rgba(255, 255, 255, 0.24) 0%, rgba(255, 255, 255, 0) 100%); 62 | 63 | transition: 1s all; 64 | border-radius: 999px; 65 | animation: .4s ${buttonHoverOut} forwards; 66 | } 67 | 68 | &:hover { 69 | &:after { 70 | content: ""; 71 | opacity: .7; 72 | animation: .4s ${buttonHover} forwards; 73 | } 74 | } 75 | 76 | span { 77 | background: linear-gradient(180deg, rgba(255, 255, 255, 0.3) 8.85%, #FFFFFF 100%); 78 | -webkit-background-clip: text; 79 | -webkit-text-fill-color: transparent; 80 | background-clip: text; 81 | text-fill-color: transparent; 82 | } 83 | ` 84 | 85 | const ButtonWrapper = styled.div` 86 | position: relative; 87 | overflow: hidden; 88 | border-radius: 999px; 89 | padding: 2px 2px; 90 | display: inline-block; 91 | 92 | @property --border-angle { 93 | syntax: ""; 94 | initial-value: 0turn; 95 | inherits: false; 96 | } 97 | 98 | @property --position { 99 | syntax: ""; 100 | initial-value: 20%; 101 | inherits: false; 102 | } 103 | 104 | @property --radialWidth { 105 | syntax: ""; 106 | initial-value: 60%; 107 | inherits: false; 108 | } 109 | 110 | @property --radialLength { 111 | syntax: ""; 112 | initial-value: 10%; 113 | inherits: false; 114 | } 115 | ` 116 | 117 | const Border = styled.div<{size: number, buttonWidth: number, buttonHeight: number}>` 118 | --border-size: 15px; 119 | --border-angle: 0turn; 120 | pointer-events: none; 121 | background-image: 122 | conic-gradient( 123 | from var(--border-angle) at 50% 50%, 124 | rgba(255, 255, 255, 0.5) 0deg, rgba(255, 255, 255, 0) 60deg, rgba(255, 255, 255, 0) 310deg, rgba(255, 255, 255, 0.5) 360deg); 125 | background-size: calc(100% - (var(--border-size) * 2)) 126 | calc(100% - (var(--border-size) * 2)), 127 | cover; 128 | position: absolute; 129 | bottom: calc(50% - ${p => p.size / 2}px); 130 | left: calc(50% - ${p => p.size / 2}px); 131 | /* it should be square */ 132 | width: ${p => p.size}px; 133 | height: ${p => p.size}px; 134 | background-position: center center; 135 | background-repeat: no-repeat; 136 | 137 | mask: url(${p => createSVGMask(p.buttonWidth + 4, p.buttonHeight + 4)}); 138 | mask-size: ${p => p.buttonWidth + 4}px ${p => p.buttonHeight + 4}px; 139 | mask-position: center center; 140 | mask-repeat: no-repeat; 141 | mask-mode: alpha; 142 | ` 143 | 144 | const Glow = styled(Border)` 145 | filter: blur(8px); 146 | opacity: .15; 147 | z-index: 5; 148 | mask: none; 149 | ` 150 | 151 | const Stars = styled(Border)` 152 | mask: url("data:image/svg+xml,%3Csvg width='28' height='24' viewBox='0 0 28 24' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M14.0534 15.732C13.8444 15.283 14.2848 14.8489 14.7326 15.051C14.8296 15.0959 14.9043 15.1707 14.949 15.268C15.1506 15.717 14.7177 16.1511 14.2698 15.949C14.1728 15.9041 14.0982 15.8293 14.0534 15.732Z' fill='black'/%3E%3Cpath d='M18.8001 13.5093C19.0016 13.0603 18.5687 12.6263 18.1209 12.8283C18.0239 12.8732 17.9492 12.9481 17.9045 13.0453C17.6955 13.4944 18.1358 13.9284 18.5837 13.7264C18.6807 13.6815 18.7553 13.6066 18.8001 13.5093Z' fill='black'/%3E%3Cpath d='M0.949043 2.732C1.15057 2.28297 0.717663 1.84891 0.269836 2.05097C0.172806 2.09587 0.098162 2.17071 0.0533793 2.268C-0.155607 2.71703 0.284759 3.15109 0.732587 2.94903C0.829616 2.90413 0.90426 2.82929 0.949043 2.732Z' fill='black'/%3E%3Cpath d='M26.9489 7.732C27.151 7.28297 26.7169 6.84891 26.2679 7.05097C26.1706 7.09587 26.0958 7.17071 26.0508 7.268C25.8488 7.71703 26.2828 8.15109 26.7319 7.94903C26.8292 7.90413 26.904 7.82929 26.9489 7.732Z' fill='black'/%3E%3Cpath d='M13.0534 5.732C12.8444 5.28297 13.2848 4.84891 13.7326 5.05097C13.8296 5.09587 13.9043 5.17071 13.949 5.268C14.1506 5.71703 13.7177 6.15109 13.2698 5.94903C13.1728 5.90413 13.0982 5.82929 13.0534 5.732Z' fill='black'/%3E%3Cpath d='M10.0534 17.732C9.84439 17.283 10.2848 16.8489 10.7326 17.051C10.8296 17.0959 10.9043 17.1707 10.949 17.268C11.1506 17.717 10.7177 18.1511 10.2698 17.949C10.1728 17.9041 10.0982 17.8293 10.0534 17.732Z' fill='black'/%3E%3Cpath d='M15.0534 21.732C14.8444 21.283 15.2848 20.8489 15.7326 21.051C15.8296 21.0959 15.9043 21.1707 15.949 21.268C16.1506 21.717 15.7177 22.1511 15.2698 21.949C15.1728 21.9041 15.0982 21.8293 15.0534 21.732Z' fill='black'/%3E%3C/svg%3E%0A"); 153 | mask-size: auto; 154 | mask-repeat: repeat; 155 | ` 156 | 157 | interface Props { 158 | noStar?: boolean 159 | children?: React.ReactNode 160 | } 161 | 162 | export default function NormalButton(props: Props) { 163 | const [buttonRef, { width, height }] = useElementSize() 164 | 165 | function generateSquareMask() { 166 | const dimensions = width + 50 // safe distance 167 | 168 | return dimensions 169 | } 170 | 171 | return( 172 |
173 | 174 | 182 | 190 | {!props.noStar && 191 | 199 | } 200 | 205 | 206 |
207 | ) 208 | } -------------------------------------------------------------------------------- /pages/Special.tsx: -------------------------------------------------------------------------------- 1 | import { animate, motion, useAnimationControls, useMotionValue } from "framer-motion"; 2 | import createSVGMask from "lib/createSVGMask"; 3 | import useElementSize from "lib/useElementSize"; 4 | import { useEffect, useRef, useState } from "react"; 5 | import styled, { keyframes } from "styled-components"; 6 | 7 | const buttonHover = keyframes` 8 | to { 9 | --radialWidth: 120%; 10 | --radialLength: 85%; 11 | } 12 | ` 13 | 14 | const buttonHoverOut = keyframes` 15 | from { 16 | --radialWidth: 120%; 17 | --radialLength: 85%; 18 | } 19 | to { 20 | --radialWidth: 40%; 21 | --radialLength: 10%; 22 | } 23 | ` 24 | 25 | const ButtonWrapper = styled.div` 26 | position: relative; 27 | overflow: hidden; 28 | border-radius: 999px; 29 | padding: 2px 2px; 30 | 31 | @property --border-angle { 32 | syntax: ""; 33 | initial-value: 0turn; 34 | inherits: false; 35 | } 36 | 37 | @property --position { 38 | syntax: ""; 39 | initial-value: 20%; 40 | inherits: false; 41 | } 42 | 43 | @property --radialWidth { 44 | syntax: ""; 45 | initial-value: 60%; 46 | inherits: false; 47 | } 48 | 49 | @property --radialLength { 50 | syntax: ""; 51 | initial-value: 10%; 52 | inherits: false; 53 | } 54 | ` 55 | 56 | const Button = styled.button` 57 | --radialWidth: 40%; 58 | --radialLength: 10%; 59 | 60 | position: relative; 61 | font-family: "Inter"; 62 | box-sizing: border-box; 63 | font-size: 14px; 64 | line-height: 24px; 65 | padding: 8px 16px; 66 | border: none; 67 | stroke: 0; 68 | -webkit-appearance: none; 69 | /* make this black if you want to rotating conic gradient */ 70 | background-color: transparent; 71 | border-radius: 999px; 72 | cursor: pointer; 73 | /* opacity: .5; */ 74 | &:before { 75 | content: ""; 76 | width: calc(100% + 2px); 77 | height: calc(100% + 2px); 78 | position: absolute; 79 | top: -2px; 80 | left: -2px; 81 | border-radius: 999px; 82 | border: 1px solid rgba(255, 255, 255, 0.1); 83 | } 84 | 85 | &:after { 86 | content: ""; 87 | width: calc(100% + 4px); 88 | height: calc(100% + 4px); 89 | position: absolute; 90 | left: -2px; 91 | top: -2px; 92 | opacity: 0; 93 | background: radial-gradient(var(--radialLength) var(--radialWidth) at 50% 120%, rgba(255, 255, 255, 0.24) 0%, rgba(255, 255, 255, 0) 100%); 94 | 95 | transition: 1s all; 96 | border-radius: 999px; 97 | animation: .4s ${buttonHoverOut} forwards; 98 | } 99 | 100 | &:hover { 101 | &:after { 102 | content: ""; 103 | opacity: .7; 104 | animation: .4s ${buttonHover} forwards; 105 | } 106 | } 107 | 108 | span { 109 | background: linear-gradient(180deg, rgba(255, 255, 255, 0.3) 8.85%, #FFFFFF 100%); 110 | -webkit-background-clip: text; 111 | -webkit-text-fill-color: transparent; 112 | background-clip: text; 113 | text-fill-color: transparent; 114 | } 115 | ` 116 | 117 | const Border = styled.div<{size: number, buttonWidth: number, buttonHeight: number}>` 118 | --border-size: 15px; 119 | --border-angle: 0turn; 120 | pointer-events: none; 121 | background-image: 122 | conic-gradient( 123 | from var(--border-angle) at 50% 50%, 124 | rgba(255, 255, 255, 0.5) 0deg, rgba(255, 255, 255, 0) 60deg, rgba(255, 255, 255, 0) 310deg, rgba(255, 255, 255, 0.5) 360deg); 125 | background-size: calc(100% - (var(--border-size) * 2)) 126 | calc(100% - (var(--border-size) * 2)), 127 | cover; 128 | position: absolute; 129 | bottom: calc(50% - ${p => p.size / 2}px); 130 | left: calc(50% - ${p => p.size / 2}px); 131 | /* it should be square */ 132 | width: ${p => p.size}px; 133 | height: ${p => p.size}px; 134 | background-position: center center; 135 | background-repeat: no-repeat; 136 | 137 | mask: url(${p => createSVGMask(p.buttonWidth + 4, p.buttonHeight + 4)}); 138 | mask-size: ${p => p.buttonWidth + 4}px ${p => p.buttonHeight + 4}px; 139 | mask-position: center center; 140 | mask-repeat: no-repeat; 141 | mask-mode: alpha; 142 | ` 143 | 144 | const Glow = styled(Border)` 145 | filter: blur(8px); 146 | opacity: .15; 147 | z-index: 5; 148 | mask: none; 149 | ` 150 | 151 | const Stars = styled(Border)` 152 | mask: url("data:image/svg+xml,%3Csvg width='28' height='24' viewBox='0 0 28 24' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M14.0534 15.732C13.8444 15.283 14.2848 14.8489 14.7326 15.051C14.8296 15.0959 14.9043 15.1707 14.949 15.268C15.1506 15.717 14.7177 16.1511 14.2698 15.949C14.1728 15.9041 14.0982 15.8293 14.0534 15.732Z' fill='black'/%3E%3Cpath d='M18.8001 13.5093C19.0016 13.0603 18.5687 12.6263 18.1209 12.8283C18.0239 12.8732 17.9492 12.9481 17.9045 13.0453C17.6955 13.4944 18.1358 13.9284 18.5837 13.7264C18.6807 13.6815 18.7553 13.6066 18.8001 13.5093Z' fill='black'/%3E%3Cpath d='M0.949043 2.732C1.15057 2.28297 0.717663 1.84891 0.269836 2.05097C0.172806 2.09587 0.098162 2.17071 0.0533793 2.268C-0.155607 2.71703 0.284759 3.15109 0.732587 2.94903C0.829616 2.90413 0.90426 2.82929 0.949043 2.732Z' fill='black'/%3E%3Cpath d='M26.9489 7.732C27.151 7.28297 26.7169 6.84891 26.2679 7.05097C26.1706 7.09587 26.0958 7.17071 26.0508 7.268C25.8488 7.71703 26.2828 8.15109 26.7319 7.94903C26.8292 7.90413 26.904 7.82929 26.9489 7.732Z' fill='black'/%3E%3Cpath d='M13.0534 5.732C12.8444 5.28297 13.2848 4.84891 13.7326 5.05097C13.8296 5.09587 13.9043 5.17071 13.949 5.268C14.1506 5.71703 13.7177 6.15109 13.2698 5.94903C13.1728 5.90413 13.0982 5.82929 13.0534 5.732Z' fill='black'/%3E%3Cpath d='M10.0534 17.732C9.84439 17.283 10.2848 16.8489 10.7326 17.051C10.8296 17.0959 10.9043 17.1707 10.949 17.268C11.1506 17.717 10.7177 18.1511 10.2698 17.949C10.1728 17.9041 10.0982 17.8293 10.0534 17.732Z' fill='black'/%3E%3Cpath d='M15.0534 21.732C14.8444 21.283 15.2848 20.8489 15.7326 21.051C15.8296 21.0959 15.9043 21.1707 15.949 21.268C16.1506 21.717 15.7177 22.1511 15.2698 21.949C15.1728 21.9041 15.0982 21.8293 15.0534 21.732Z' fill='black'/%3E%3C/svg%3E%0A"); 153 | mask-size: auto; 154 | mask-repeat: repeat; 155 | ` 156 | 157 | interface Props { 158 | noStar?: boolean 159 | } 160 | 161 | export default function GradientButton(props: Props) { 162 | const controls = useAnimationControls() 163 | const turn = useMotionValue('0turn') 164 | const [ duration, setDuration ] = useState(6) 165 | const [buttonRef, { width, height }] = useElementSize() 166 | 167 | useEffect(() => { 168 | const remaining = Number(turn.get().split('turn')[0]) 169 | // THIS WILL ONLY WORK WITH LINEAR EASINGS 170 | const calculated = duration * (1 - remaining) 171 | // if the turn has been completed start with 0 172 | const currentTurn = turn.get() === '1turn'? '0turn': turn.get() 173 | 174 | controls.stop() 175 | animate(turn, [currentTurn, '1turn'], { 176 | duration: calculated || duration, 177 | ease: "linear", 178 | onComplete() { 179 | prepareNextAnimation() 180 | }, 181 | }) 182 | return controls.stop 183 | }, [duration]) 184 | 185 | function prepareNextAnimation(){ 186 | animate(turn, ['0turn', '1turn'], { 187 | duration: duration, 188 | ease: "linear", 189 | repeat: Infinity 190 | }) 191 | } 192 | 193 | const target = useRef(null) 194 | 195 | function calculateSpeed(x:number, y:number, maxSpeed = 6, minSpeed = 0.6) { 196 | // Pythagorean 197 | const distance = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2)); 198 | const speed = maxSpeed - ((distance / (window.innerWidth / 3)) * (maxSpeed - minSpeed)); 199 | return Math.max(Math.min(speed, maxSpeed), minSpeed); 200 | } 201 | 202 | function generateSquareMask() { 203 | const dimensions = width + 50 // safe distance 204 | 205 | return dimensions 206 | } 207 | 208 | useEffect(() => { 209 | const handleMouseMove = (event: any) => { 210 | if(target.current){ 211 | const rect = target.current.getBoundingClientRect() 212 | 213 | const relativeX = event.clientX - rect.x 214 | const relativeY = event.clientY - rect.y 215 | 216 | setDuration(calculateSpeed(relativeX, relativeY)) 217 | } 218 | }; 219 | 220 | window.addEventListener('mousemove', handleMouseMove); 221 | 222 | return () => { 223 | window.removeEventListener( 224 | 'mousemove', 225 | handleMouseMove 226 | ); 227 | }; 228 | }, [target]); 229 | 230 | return( 231 |
232 | 233 | 241 | 249 | { !props.noStar && 250 | 258 | } 259 | 264 | 265 |
266 | ) 267 | } -------------------------------------------------------------------------------- /pages/_app.tsx: -------------------------------------------------------------------------------- 1 | import '../styles/globals.css' 2 | import type { AppProps } from 'next/app' 3 | 4 | export default function App({ Component, pageProps }: AppProps) { 5 | return 6 | } 7 | -------------------------------------------------------------------------------- /pages/_document.tsx: -------------------------------------------------------------------------------- 1 | import Document, { DocumentContext, Html, Head, Main, NextScript } from 'next/document' 2 | import { ServerStyleSheet } from 'styled-components' 3 | 4 | export default class MyDocument extends Document { 5 | render () { 6 | return ( 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | ) 17 | } 18 | 19 | static async getInitialProps(ctx: DocumentContext) { 20 | const sheet = new ServerStyleSheet() 21 | const originalRenderPage = ctx.renderPage 22 | 23 | try { 24 | ctx.renderPage = () => 25 | originalRenderPage({ 26 | enhanceApp: (App) => (props) => 27 | sheet.collectStyles(), 28 | }) 29 | 30 | const initialProps = await Document.getInitialProps(ctx) 31 | return { 32 | ...initialProps, 33 | styles: ( 34 | <> 35 | {initialProps.styles} 36 | {sheet.getStyleElement()} 37 | 38 | ), 39 | } 40 | } finally { 41 | sheet.seal() 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /pages/index.tsx: -------------------------------------------------------------------------------- 1 | import styled from "styled-components" 2 | import { AnimatePresence, motion, useAnimationControls } from "framer-motion" 3 | import Stars from "@/c/GlowingButton/Stars" 4 | import Intro from "@/c/GlowingButton/Intro" 5 | import Browser from "@/c/GlowingButton/Browser" 6 | import { useEffect, useState } from "react" 7 | import NormalButton from "./Normal" 8 | import Loader from "./Loader" 9 | import Special from "./Special" 10 | import Credits from "@/c/GlowingButton/Credits" 11 | 12 | const BACKGROUNDS = [ 13 | "#020308", 14 | "#010609", 15 | "#0B020D", 16 | "#090401", 17 | "#010902" 18 | ] 19 | 20 | const Container = styled.div<{bg: string}>` 21 | width: 100vw; 22 | height: 100vh; 23 | background: radial-gradient(63.94% 63.94% at 50% 0%, rgba(255, 255, 255, 0.12) 0%, rgba(255, 255, 255, 0) 100%), ${p => p.bg}; 24 | transition: 1s all; 25 | 26 | display: flex; 27 | flex-direction: column; 28 | align-items: center; 29 | justify-content: center; 30 | ` 31 | 32 | const Content = styled.div` 33 | display: flex; 34 | gap: 32px; 35 | ` 36 | 37 | const Notice = styled.div` 38 | width: 330px; 39 | height: 40px; 40 | padding: 6px 16px; 41 | background: radial-gradient(63.94% 63.94% at 50% 0%, rgba(255, 255, 255, 0.12) 0%, rgba(255, 255, 255, 0) 100%), rgba(255, 255, 255, 0.01); 42 | backdrop-filter: blur(6px); 43 | border-radius: 6px; 44 | position: absolute; 45 | font-family: "Inter"; 46 | bottom: 40px; 47 | font-size: 14px; 48 | text-align: center; 49 | line-height: 24px; 50 | 51 | span { 52 | background: linear-gradient(180deg, rgba(255, 255, 255, 0.3) 8.85%, #FFFFFF 100%); 53 | -webkit-background-clip: text; 54 | -webkit-text-fill-color: transparent; 55 | background-clip: text; 56 | text-fill-color: transparent; 57 | } 58 | 59 | 60 | &:before { 61 | content: ""; 62 | width: calc(100% + 2px); 63 | height: calc(100% + 2px); 64 | border-radius: 6px; 65 | background: linear-gradient(180deg, rgba(255, 255, 255, 0.12) 0%, rgba(255, 255, 255, 0) 74.04%), 66 | linear-gradient(0deg, rgba(255, 255, 255, 0.04), rgba(255, 255, 255, 0.04)); 67 | position: absolute; 68 | top: -1px; 69 | left: -1px; 70 | mask: url("data:image/svg+xml,%3Csvg width='330' height='42' viewBox='0 0 330 42' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Crect x='0.5' y='0.5' width='329' height='42' rx='9.5' stroke='black'/%3E%3C/svg%3E%0A"); 71 | mask-repeat: no-repeat; 72 | mask-mode: alpha; 73 | pointer-events: none; 74 | } 75 | ` 76 | 77 | enum ActiveTab { 78 | 'Normal' = 1, 79 | 'Loader' = 2, 80 | 'Special' = 3 81 | } 82 | 83 | const variants = { 84 | hidden: { opacity: 0, y: 15 }, 85 | open: { 86 | opacity: 1, 87 | y: 0, 88 | transition: { 89 | duration: .5, 90 | staggerChildren: 0.1 91 | } 92 | }, 93 | out: { 94 | opacity: 0, 95 | y: 15, 96 | transition: { 97 | duration: .2, 98 | staggerChildren: 0.1, 99 | when: "afterChildren" 100 | }, 101 | } 102 | } 103 | 104 | export default function GlowingButton() { 105 | const [ activeTab, setActiveTab ] = useState(ActiveTab.Normal) 106 | const [ bg, setBg ] = useState(0) 107 | const [ _, setShow ] = useState(false) 108 | 109 | // this is only here to re-trigger mask rendering after font load. 110 | useEffect(() => { 111 | setTimeout(() => { 112 | setShow(true) 113 | }, 200) 114 | }, []) 115 | 116 | setTimeout(() => { 117 | const newBg = bg < BACKGROUNDS.length -1 ? bg + 1 : 0 118 | 119 | setBg(newBg) 120 | }, 10000) 121 | 122 | return ( 123 | 124 | 125 | 126 | 127 | setActiveTab(activeIndex)}> 128 | 129 | 130 | {activeTab === 1 && 131 | 139 | 140 | 141 | 142 | } 143 | 144 | {activeTab === 2 && 145 | 153 | 154 | 155 | 156 | } 157 | 158 | {activeTab === 3 && 159 | 167 | 168 | 169 | } 170 | 171 | 172 | 173 | 174 | 175 | 176 | 190 | Move away your cursor to see the magic ✨ 191 | 192 | 193 | ) 194 | } -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nusu/react-glowing-button/ff908fca8f7c8fb5015833aba665338b7fcae96d/public/favicon.ico -------------------------------------------------------------------------------- /public/grid.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /public/lights.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nusu/react-glowing-button/ff908fca8f7c8fb5015833aba665338b7fcae96d/public/lights.png -------------------------------------------------------------------------------- /public/nusu_pp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nusu/react-glowing-button/ff908fca8f7c8fb5015833aba665338b7fcae96d/public/nusu_pp.png -------------------------------------------------------------------------------- /public/oguz_pp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nusu/react-glowing-button/ff908fca8f7c8fb5015833aba665338b7fcae96d/public/oguz_pp.png -------------------------------------------------------------------------------- /public/stars.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | -------------------------------------------------------------------------------- /styles/globals.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --max-width: 1100px; 3 | --border-radius: 12px; 4 | --font-mono: ui-monospace, Menlo, Monaco, 'Cascadia Mono', 'Segoe UI Mono', 5 | 'Roboto Mono', 'Oxygen Mono', 'Ubuntu Monospace', 'Source Code Pro', 6 | 'Fira Mono', 'Droid Sans Mono', 'Courier New', monospace; 7 | 8 | --foreground-rgb: 0, 0, 0; 9 | --background-start-rgb: 214, 219, 220; 10 | --background-end-rgb: 255, 255, 255; 11 | 12 | --primary-glow: conic-gradient( 13 | from 180deg at 50% 50%, 14 | #16abff33 0deg, 15 | #0885ff33 55deg, 16 | #54d6ff33 120deg, 17 | #0071ff33 160deg, 18 | transparent 360deg 19 | ); 20 | --secondary-glow: radial-gradient( 21 | rgba(255, 255, 255, 1), 22 | rgba(255, 255, 255, 0) 23 | ); 24 | 25 | --tile-start-rgb: 239, 245, 249; 26 | --tile-end-rgb: 228, 232, 233; 27 | --tile-border: conic-gradient( 28 | #00000080, 29 | #00000040, 30 | #00000030, 31 | #00000020, 32 | #00000010, 33 | #00000010, 34 | #00000080 35 | ); 36 | 37 | --callout-rgb: 238, 240, 241; 38 | --callout-border-rgb: 172, 175, 176; 39 | --card-rgb: 180, 185, 188; 40 | --card-border-rgb: 131, 134, 135; 41 | } 42 | 43 | @media (prefers-color-scheme: dark) { 44 | :root { 45 | --foreground-rgb: 255, 255, 255; 46 | --background-start-rgb: 0, 0, 0; 47 | --background-end-rgb: 0, 0, 0; 48 | 49 | --primary-glow: radial-gradient(rgba(1, 65, 255, 0.4), rgba(1, 65, 255, 0)); 50 | --secondary-glow: linear-gradient( 51 | to bottom right, 52 | rgba(1, 65, 255, 0), 53 | rgba(1, 65, 255, 0), 54 | rgba(1, 65, 255, 0.3) 55 | ); 56 | 57 | --tile-start-rgb: 2, 13, 46; 58 | --tile-end-rgb: 2, 5, 19; 59 | --tile-border: conic-gradient( 60 | #ffffff80, 61 | #ffffff40, 62 | #ffffff30, 63 | #ffffff20, 64 | #ffffff10, 65 | #ffffff10, 66 | #ffffff80 67 | ); 68 | 69 | --callout-rgb: 20, 20, 20; 70 | --callout-border-rgb: 108, 108, 108; 71 | --card-rgb: 100, 100, 100; 72 | --card-border-rgb: 200, 200, 200; 73 | } 74 | } 75 | 76 | * { 77 | box-sizing: border-box; 78 | padding: 0; 79 | margin: 0; 80 | } 81 | 82 | html, 83 | body { 84 | max-width: 100vw; 85 | overflow-x: hidden; 86 | } 87 | 88 | body { 89 | text-rendering: optimizelegibility; 90 | -webkit-font-smoothing: antialiased; 91 | color: rgb(var(--foreground-rgb)); 92 | background: linear-gradient( 93 | to bottom, 94 | transparent, 95 | rgb(var(--background-end-rgb)) 96 | ) 97 | rgb(var(--background-start-rgb)); 98 | } 99 | 100 | a { 101 | color: inherit; 102 | text-decoration: none; 103 | } 104 | 105 | @media (prefers-color-scheme: dark) { 106 | html { 107 | color-scheme: dark; 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "baseUrl": ".", 4 | "paths": { 5 | "@/c/*": ["components/*"], 6 | }, 7 | "target": "esnext", 8 | "module": "esnext", 9 | "jsx": "preserve", 10 | "lib": [ 11 | "dom", 12 | "es2017" 13 | ], 14 | "moduleResolution": "node", 15 | "allowJs": true, 16 | "noEmit": true, 17 | "strict": true, 18 | "allowSyntheticDefaultImports": true, 19 | "skipLibCheck": true, 20 | "noUnusedLocals": true, 21 | "noUnusedParameters": true, 22 | "removeComments": false, 23 | "preserveConstEnums": true, 24 | "sourceMap": true, 25 | "esModuleInterop": true, 26 | "forceConsistentCasingInFileNames": true, 27 | "resolveJsonModule": true, 28 | "isolatedModules": true, 29 | "incremental": true 30 | }, 31 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"], 32 | "exclude": ["node_modules"] 33 | } 34 | -------------------------------------------------------------------------------- /yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | "@babel/code-frame@^7.18.6": 6 | version "7.18.6" 7 | resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.18.6.tgz#3b25d38c89600baa2dcc219edfa88a74eb2c427a" 8 | integrity sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q== 9 | dependencies: 10 | "@babel/highlight" "^7.18.6" 11 | 12 | "@babel/generator@^7.20.7": 13 | version "7.20.7" 14 | resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.20.7.tgz#f8ef57c8242665c5929fe2e8d82ba75460187b4a" 15 | integrity sha512-7wqMOJq8doJMZmP4ApXTzLxSr7+oO2jroJURrVEp6XShrQUObV8Tq/D0NCcoYg2uHqUrjzO0zwBjoYzelxK+sw== 16 | dependencies: 17 | "@babel/types" "^7.20.7" 18 | "@jridgewell/gen-mapping" "^0.3.2" 19 | jsesc "^2.5.1" 20 | 21 | "@babel/helper-annotate-as-pure@^7.16.0": 22 | version "7.18.6" 23 | resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.18.6.tgz#eaa49f6f80d5a33f9a5dd2276e6d6e451be0a6bb" 24 | integrity sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA== 25 | dependencies: 26 | "@babel/types" "^7.18.6" 27 | 28 | "@babel/helper-environment-visitor@^7.18.9": 29 | version "7.18.9" 30 | resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz#0c0cee9b35d2ca190478756865bb3528422f51be" 31 | integrity sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg== 32 | 33 | "@babel/helper-function-name@^7.19.0": 34 | version "7.19.0" 35 | resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz#941574ed5390682e872e52d3f38ce9d1bef4648c" 36 | integrity sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w== 37 | dependencies: 38 | "@babel/template" "^7.18.10" 39 | "@babel/types" "^7.19.0" 40 | 41 | "@babel/helper-hoist-variables@^7.18.6": 42 | version "7.18.6" 43 | resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz#d4d2c8fb4baeaa5c68b99cc8245c56554f926678" 44 | integrity sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q== 45 | dependencies: 46 | "@babel/types" "^7.18.6" 47 | 48 | "@babel/helper-module-imports@^7.0.0", "@babel/helper-module-imports@^7.16.0": 49 | version "7.18.6" 50 | resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz#1e3ebdbbd08aad1437b428c50204db13c5a3ca6e" 51 | integrity sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA== 52 | dependencies: 53 | "@babel/types" "^7.18.6" 54 | 55 | "@babel/helper-split-export-declaration@^7.18.6": 56 | version "7.18.6" 57 | resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz#7367949bc75b20c6d5a5d4a97bba2824ae8ef075" 58 | integrity sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA== 59 | dependencies: 60 | "@babel/types" "^7.18.6" 61 | 62 | "@babel/helper-string-parser@^7.19.4": 63 | version "7.19.4" 64 | resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz#38d3acb654b4701a9b77fb0615a96f775c3a9e63" 65 | integrity sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw== 66 | 67 | "@babel/helper-validator-identifier@^7.18.6", "@babel/helper-validator-identifier@^7.19.1": 68 | version "7.19.1" 69 | resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz#7eea834cf32901ffdc1a7ee555e2f9c27e249ca2" 70 | integrity sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w== 71 | 72 | "@babel/highlight@^7.18.6": 73 | version "7.18.6" 74 | resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.18.6.tgz#81158601e93e2563795adcbfbdf5d64be3f2ecdf" 75 | integrity sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g== 76 | dependencies: 77 | "@babel/helper-validator-identifier" "^7.18.6" 78 | chalk "^2.0.0" 79 | js-tokens "^4.0.0" 80 | 81 | "@babel/parser@^7.20.7": 82 | version "7.20.7" 83 | resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.20.7.tgz#66fe23b3c8569220817d5feb8b9dcdc95bb4f71b" 84 | integrity sha512-T3Z9oHybU+0vZlY9CiDSJQTD5ZapcW18ZctFMi0MOAl/4BjFF4ul7NVSARLdbGO5vDqy9eQiGTV0LtKfvCYvcg== 85 | 86 | "@babel/template@^7.18.10": 87 | version "7.20.7" 88 | resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.20.7.tgz#a15090c2839a83b02aa996c0b4994005841fd5a8" 89 | integrity sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw== 90 | dependencies: 91 | "@babel/code-frame" "^7.18.6" 92 | "@babel/parser" "^7.20.7" 93 | "@babel/types" "^7.20.7" 94 | 95 | "@babel/traverse@^7.4.5": 96 | version "7.20.10" 97 | resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.20.10.tgz#2bf98239597fcec12f842756f186a9dde6d09230" 98 | integrity sha512-oSf1juCgymrSez8NI4A2sr4+uB/mFd9MXplYGPEBnfAuWmmyeVcHa6xLPiaRBcXkcb/28bgxmQLTVwFKE1yfsg== 99 | dependencies: 100 | "@babel/code-frame" "^7.18.6" 101 | "@babel/generator" "^7.20.7" 102 | "@babel/helper-environment-visitor" "^7.18.9" 103 | "@babel/helper-function-name" "^7.19.0" 104 | "@babel/helper-hoist-variables" "^7.18.6" 105 | "@babel/helper-split-export-declaration" "^7.18.6" 106 | "@babel/parser" "^7.20.7" 107 | "@babel/types" "^7.20.7" 108 | debug "^4.1.0" 109 | globals "^11.1.0" 110 | 111 | "@babel/types@^7.18.6", "@babel/types@^7.19.0", "@babel/types@^7.20.7": 112 | version "7.20.7" 113 | resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.20.7.tgz#54ec75e252318423fc07fb644dc6a58a64c09b7f" 114 | integrity sha512-69OnhBxSSgK0OzTJai4kyPDiKTIe3j+ctaHdIGVbRahTLAT7L3R9oeXHC2aVSuGYt3cVnoAMDmOCgJ2yaiLMvg== 115 | dependencies: 116 | "@babel/helper-string-parser" "^7.19.4" 117 | "@babel/helper-validator-identifier" "^7.19.1" 118 | to-fast-properties "^2.0.0" 119 | 120 | "@emotion/is-prop-valid@^0.8.2": 121 | version "0.8.8" 122 | resolved "https://registry.yarnpkg.com/@emotion/is-prop-valid/-/is-prop-valid-0.8.8.tgz#db28b1c4368a259b60a97311d6a952d4fd01ac1a" 123 | integrity sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA== 124 | dependencies: 125 | "@emotion/memoize" "0.7.4" 126 | 127 | "@emotion/is-prop-valid@^1.1.0": 128 | version "1.2.0" 129 | resolved "https://registry.yarnpkg.com/@emotion/is-prop-valid/-/is-prop-valid-1.2.0.tgz#7f2d35c97891669f7e276eb71c83376a5dc44c83" 130 | integrity sha512-3aDpDprjM0AwaxGE09bOPkNxHpBd+kA6jty3RnaEXdweX1DF1U3VQpPYb0g1IStAuK7SVQ1cy+bNBBKp4W3Fjg== 131 | dependencies: 132 | "@emotion/memoize" "^0.8.0" 133 | 134 | "@emotion/memoize@0.7.4": 135 | version "0.7.4" 136 | resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.7.4.tgz#19bf0f5af19149111c40d98bb0cf82119f5d9eeb" 137 | integrity sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw== 138 | 139 | "@emotion/memoize@^0.8.0": 140 | version "0.8.0" 141 | resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.8.0.tgz#f580f9beb67176fa57aae70b08ed510e1b18980f" 142 | integrity sha512-G/YwXTkv7Den9mXDO7AhLWkE3q+I92B+VqAE+dYG4NGPaHZGvt3G8Q0p9vmE+sq7rTGphUbAvmQ9YpbfMQGGlA== 143 | 144 | "@emotion/stylis@^0.8.4": 145 | version "0.8.5" 146 | resolved "https://registry.yarnpkg.com/@emotion/stylis/-/stylis-0.8.5.tgz#deacb389bd6ee77d1e7fcaccce9e16c5c7e78e04" 147 | integrity sha512-h6KtPihKFn3T9fuIrwvXXUOwlx3rfUvfZIcP5a6rh8Y7zjE3O06hT5Ss4S/YI1AYhuZ1kjaE/5EaOOI2NqSylQ== 148 | 149 | "@emotion/unitless@^0.7.4": 150 | version "0.7.5" 151 | resolved "https://registry.yarnpkg.com/@emotion/unitless/-/unitless-0.7.5.tgz#77211291c1900a700b8a78cfafda3160d76949ed" 152 | integrity sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg== 153 | 154 | "@jridgewell/gen-mapping@^0.3.2": 155 | version "0.3.2" 156 | resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz#c1aedc61e853f2bb9f5dfe6d4442d3b565b253b9" 157 | integrity sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A== 158 | dependencies: 159 | "@jridgewell/set-array" "^1.0.1" 160 | "@jridgewell/sourcemap-codec" "^1.4.10" 161 | "@jridgewell/trace-mapping" "^0.3.9" 162 | 163 | "@jridgewell/resolve-uri@3.1.0": 164 | version "3.1.0" 165 | resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz#2203b118c157721addfe69d47b70465463066d78" 166 | integrity sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w== 167 | 168 | "@jridgewell/set-array@^1.0.1": 169 | version "1.1.2" 170 | resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.2.tgz#7c6cf998d6d20b914c0a55a91ae928ff25965e72" 171 | integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw== 172 | 173 | "@jridgewell/sourcemap-codec@1.4.14", "@jridgewell/sourcemap-codec@^1.4.10": 174 | version "1.4.14" 175 | resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz#add4c98d341472a289190b424efbdb096991bb24" 176 | integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw== 177 | 178 | "@jridgewell/trace-mapping@^0.3.9": 179 | version "0.3.17" 180 | resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz#793041277af9073b0951a7fe0f0d8c4c98c36985" 181 | integrity sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g== 182 | dependencies: 183 | "@jridgewell/resolve-uri" "3.1.0" 184 | "@jridgewell/sourcemap-codec" "1.4.14" 185 | 186 | "@motionone/animation@^10.12.0": 187 | version "10.15.1" 188 | resolved "https://registry.yarnpkg.com/@motionone/animation/-/animation-10.15.1.tgz#4a85596c31cbc5100ae8eb8b34c459fb0ccf6807" 189 | integrity sha512-mZcJxLjHor+bhcPuIFErMDNyrdb2vJur8lSfMCsuCB4UyV8ILZLvK+t+pg56erv8ud9xQGK/1OGPt10agPrCyQ== 190 | dependencies: 191 | "@motionone/easing" "^10.15.1" 192 | "@motionone/types" "^10.15.1" 193 | "@motionone/utils" "^10.15.1" 194 | tslib "^2.3.1" 195 | 196 | "@motionone/dom@10.12.0": 197 | version "10.12.0" 198 | resolved "https://registry.yarnpkg.com/@motionone/dom/-/dom-10.12.0.tgz#ae30827fd53219efca4e1150a5ff2165c28351ed" 199 | integrity sha512-UdPTtLMAktHiqV0atOczNYyDd/d8Cf5fFsd1tua03PqTwwCe/6lwhLSQ8a7TbnQ5SN0gm44N1slBfj+ORIhrqw== 200 | dependencies: 201 | "@motionone/animation" "^10.12.0" 202 | "@motionone/generators" "^10.12.0" 203 | "@motionone/types" "^10.12.0" 204 | "@motionone/utils" "^10.12.0" 205 | hey-listen "^1.0.8" 206 | tslib "^2.3.1" 207 | 208 | "@motionone/easing@^10.15.1": 209 | version "10.15.1" 210 | resolved "https://registry.yarnpkg.com/@motionone/easing/-/easing-10.15.1.tgz#95cf3adaef34da6deebb83940d8143ede3deb693" 211 | integrity sha512-6hIHBSV+ZVehf9dcKZLT7p5PEKHGhDwky2k8RKkmOvUoYP3S+dXsKupyZpqx5apjd9f+php4vXk4LuS+ADsrWw== 212 | dependencies: 213 | "@motionone/utils" "^10.15.1" 214 | tslib "^2.3.1" 215 | 216 | "@motionone/generators@^10.12.0": 217 | version "10.15.1" 218 | resolved "https://registry.yarnpkg.com/@motionone/generators/-/generators-10.15.1.tgz#dc6abb11139d1bafe758a41c134d4c753a9b871c" 219 | integrity sha512-67HLsvHJbw6cIbLA/o+gsm7h+6D4Sn7AUrB/GPxvujse1cGZ38F5H7DzoH7PhX+sjvtDnt2IhFYF2Zp1QTMKWQ== 220 | dependencies: 221 | "@motionone/types" "^10.15.1" 222 | "@motionone/utils" "^10.15.1" 223 | tslib "^2.3.1" 224 | 225 | "@motionone/types@^10.12.0", "@motionone/types@^10.15.1": 226 | version "10.15.1" 227 | resolved "https://registry.yarnpkg.com/@motionone/types/-/types-10.15.1.tgz#89441b54285012795cbba8612cbaa0fa420db3eb" 228 | integrity sha512-iIUd/EgUsRZGrvW0jqdst8st7zKTzS9EsKkP+6c6n4MPZoQHwiHuVtTQLD6Kp0bsBLhNzKIBlHXponn/SDT4hA== 229 | 230 | "@motionone/utils@^10.12.0", "@motionone/utils@^10.15.1": 231 | version "10.15.1" 232 | resolved "https://registry.yarnpkg.com/@motionone/utils/-/utils-10.15.1.tgz#6b5f51bde75be88b5411e084310299050368a438" 233 | integrity sha512-p0YncgU+iklvYr/Dq4NobTRdAPv9PveRDUXabPEeOjBLSO/1FNB2phNTZxOxpi1/GZwYpAoECEa0Wam+nsmhSw== 234 | dependencies: 235 | "@motionone/types" "^10.15.1" 236 | hey-listen "^1.0.8" 237 | tslib "^2.3.1" 238 | 239 | "@next/env@12.2.5": 240 | version "12.2.5" 241 | resolved "https://registry.yarnpkg.com/@next/env/-/env-12.2.5.tgz#d908c57b35262b94db3e431e869b72ac3e1ad3e3" 242 | integrity sha512-vLPLV3cpPGjUPT3PjgRj7e3nio9t6USkuew3JE/jMeon/9Mvp1WyR18v3iwnCuX7eUAm1HmAbJHHLAbcu/EJcw== 243 | 244 | "@next/font@13.1.1": 245 | version "13.1.1" 246 | resolved "https://registry.yarnpkg.com/@next/font/-/font-13.1.1.tgz#a0cb38bf8a181560f195d82f13f9f92fd0b0dd20" 247 | integrity sha512-amygRorS05hYK1/XQRZo5qBl7l2fpHnezeKU/cNveWU5QJg+sg8gMGkUXHtvesNKpiKIJshBRH1TzvO+2sKpvQ== 248 | 249 | "@next/swc-android-arm-eabi@12.2.5": 250 | version "12.2.5" 251 | resolved "https://registry.yarnpkg.com/@next/swc-android-arm-eabi/-/swc-android-arm-eabi-12.2.5.tgz#903a5479ab4c2705d9c08d080907475f7bacf94d" 252 | integrity sha512-cPWClKxGhgn2dLWnspW+7psl3MoLQUcNqJqOHk2BhNcou9ARDtC0IjQkKe5qcn9qg7I7U83Gp1yh2aesZfZJMA== 253 | 254 | "@next/swc-android-arm64@12.2.5": 255 | version "12.2.5" 256 | resolved "https://registry.yarnpkg.com/@next/swc-android-arm64/-/swc-android-arm64-12.2.5.tgz#2f9a98ec4166c7860510963b31bda1f57a77c792" 257 | integrity sha512-vMj0efliXmC5b7p+wfcQCX0AfU8IypjkzT64GiKJD9PgiA3IILNiGJr1fw2lyUDHkjeWx/5HMlMEpLnTsQslwg== 258 | 259 | "@next/swc-darwin-arm64@12.2.5": 260 | version "12.2.5" 261 | resolved "https://registry.yarnpkg.com/@next/swc-darwin-arm64/-/swc-darwin-arm64-12.2.5.tgz#31b1c3c659d54be546120c488a1e1bad21c24a1d" 262 | integrity sha512-VOPWbO5EFr6snla/WcxUKtvzGVShfs302TEMOtzYyWni6f9zuOetijJvVh9CCTzInnXAZMtHyNhefijA4HMYLg== 263 | 264 | "@next/swc-darwin-x64@12.2.5": 265 | version "12.2.5" 266 | resolved "https://registry.yarnpkg.com/@next/swc-darwin-x64/-/swc-darwin-x64-12.2.5.tgz#2e44dd82b2b7fef88238d1bc4d3bead5884cedfd" 267 | integrity sha512-5o8bTCgAmtYOgauO/Xd27vW52G2/m3i5PX7MUYePquxXAnX73AAtqA3WgPXBRitEB60plSKZgOTkcpqrsh546A== 268 | 269 | "@next/swc-freebsd-x64@12.2.5": 270 | version "12.2.5" 271 | resolved "https://registry.yarnpkg.com/@next/swc-freebsd-x64/-/swc-freebsd-x64-12.2.5.tgz#e24e75d8c2581bfebc75e4f08f6ddbd116ce9dbd" 272 | integrity sha512-yYUbyup1JnznMtEBRkK4LT56N0lfK5qNTzr6/DEyDw5TbFVwnuy2hhLBzwCBkScFVjpFdfiC6SQAX3FrAZzuuw== 273 | 274 | "@next/swc-linux-arm-gnueabihf@12.2.5": 275 | version "12.2.5" 276 | resolved "https://registry.yarnpkg.com/@next/swc-linux-arm-gnueabihf/-/swc-linux-arm-gnueabihf-12.2.5.tgz#46d8c514d834d2b5f67086013f0bd5e3081e10b9" 277 | integrity sha512-2ZE2/G921Acks7UopJZVMgKLdm4vN4U0yuzvAMJ6KBavPzqESA2yHJlm85TV/K9gIjKhSk5BVtauIUntFRP8cg== 278 | 279 | "@next/swc-linux-arm64-gnu@12.2.5": 280 | version "12.2.5" 281 | resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-12.2.5.tgz#91f725ac217d3a1f4f9f53b553615ba582fd3d9f" 282 | integrity sha512-/I6+PWVlz2wkTdWqhlSYYJ1pWWgUVva6SgX353oqTh8njNQp1SdFQuWDqk8LnM6ulheVfSsgkDzxrDaAQZnzjQ== 283 | 284 | "@next/swc-linux-arm64-musl@12.2.5": 285 | version "12.2.5" 286 | resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-12.2.5.tgz#e627e8c867920995810250303cd9b8e963598383" 287 | integrity sha512-LPQRelfX6asXyVr59p5sTpx5l+0yh2Vjp/R8Wi4X9pnqcayqT4CUJLiHqCvZuLin3IsFdisJL0rKHMoaZLRfmg== 288 | 289 | "@next/swc-linux-x64-gnu@12.2.5": 290 | version "12.2.5" 291 | resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-12.2.5.tgz#83a5e224fbc4d119ef2e0f29d0d79c40cc43887e" 292 | integrity sha512-0szyAo8jMCClkjNK0hknjhmAngUppoRekW6OAezbEYwHXN/VNtsXbfzgYOqjKWxEx3OoAzrT3jLwAF0HdX2MEw== 293 | 294 | "@next/swc-linux-x64-musl@12.2.5": 295 | version "12.2.5" 296 | resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-12.2.5.tgz#be700d48471baac1ec2e9539396625584a317e95" 297 | integrity sha512-zg/Y6oBar1yVnW6Il1I/08/2ukWtOG6s3acdJdEyIdsCzyQi4RLxbbhkD/EGQyhqBvd3QrC6ZXQEXighQUAZ0g== 298 | 299 | "@next/swc-win32-arm64-msvc@12.2.5": 300 | version "12.2.5" 301 | resolved "https://registry.yarnpkg.com/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-12.2.5.tgz#a93e958133ad3310373fda33a79aa10af2a0aa97" 302 | integrity sha512-3/90DRNSqeeSRMMEhj4gHHQlLhhKg5SCCoYfE3kBjGpE63EfnblYUqsszGGZ9ekpKL/R4/SGB40iCQr8tR5Jiw== 303 | 304 | "@next/swc-win32-ia32-msvc@12.2.5": 305 | version "12.2.5" 306 | resolved "https://registry.yarnpkg.com/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-12.2.5.tgz#4f5f7ba0a98ff89a883625d4af0125baed8b2e19" 307 | integrity sha512-hGLc0ZRAwnaPL4ulwpp4D2RxmkHQLuI8CFOEEHdzZpS63/hMVzv81g8jzYA0UXbb9pus/iTc3VRbVbAM03SRrw== 308 | 309 | "@next/swc-win32-x64-msvc@12.2.5": 310 | version "12.2.5" 311 | resolved "https://registry.yarnpkg.com/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-12.2.5.tgz#20fed129b04a0d3f632c6d0de135345bb623b1e4" 312 | integrity sha512-7h5/ahY7NeaO2xygqVrSG/Y8Vs4cdjxIjowTZ5W6CKoTKn7tmnuxlUc2h74x06FKmbhAd9agOjr/AOKyxYYm9Q== 313 | 314 | "@swc/helpers@0.4.3": 315 | version "0.4.3" 316 | resolved "https://registry.yarnpkg.com/@swc/helpers/-/helpers-0.4.3.tgz#16593dfc248c53b699d4b5026040f88ddb497012" 317 | integrity sha512-6JrF+fdUK2zbGpJIlN7G3v966PQjyx/dPt1T9km2wj+EUBqgrxCk3uX4Kct16MIm9gGxfKRcfax2hVf5jvlTzA== 318 | dependencies: 319 | tslib "^2.4.0" 320 | 321 | "@types/hoist-non-react-statics@*": 322 | version "3.3.1" 323 | resolved "https://registry.yarnpkg.com/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz#1124aafe5118cb591977aeb1ceaaed1070eb039f" 324 | integrity sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA== 325 | dependencies: 326 | "@types/react" "*" 327 | hoist-non-react-statics "^3.3.0" 328 | 329 | "@types/node@18.11.18": 330 | version "18.11.18" 331 | resolved "https://registry.yarnpkg.com/@types/node/-/node-18.11.18.tgz#8dfb97f0da23c2293e554c5a50d61ef134d7697f" 332 | integrity sha512-DHQpWGjyQKSHj3ebjFI/wRKcqQcdR+MoFBygntYOZytCqNfkd2ZC4ARDJ2DQqhjH5p85Nnd3jhUJIXrszFX/JA== 333 | 334 | "@types/prop-types@*": 335 | version "15.7.5" 336 | resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.5.tgz#5f19d2b85a98e9558036f6a3cacc8819420f05cf" 337 | integrity sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w== 338 | 339 | "@types/react-dom@17.0.2": 340 | version "17.0.2" 341 | resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-17.0.2.tgz#35654cf6c49ae162d5bc90843d5437dc38008d43" 342 | integrity sha512-Icd9KEgdnFfJs39KyRyr0jQ7EKhq8U6CcHRMGAS45fp5qgUvxL3ujUCfWFttUK2UErqZNj97t9gsVPNAqcwoCg== 343 | dependencies: 344 | "@types/react" "*" 345 | 346 | "@types/react@*": 347 | version "18.0.26" 348 | resolved "https://registry.yarnpkg.com/@types/react/-/react-18.0.26.tgz#8ad59fc01fef8eaf5c74f4ea392621749f0b7917" 349 | integrity sha512-hCR3PJQsAIXyxhTNSiDFY//LhnMZWpNNr5etoCqx/iUfGc5gXWtQR2Phl908jVR6uPXacojQWTg4qRpkxTuGug== 350 | dependencies: 351 | "@types/prop-types" "*" 352 | "@types/scheduler" "*" 353 | csstype "^3.0.2" 354 | 355 | "@types/react@17.0.2": 356 | version "17.0.2" 357 | resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.2.tgz#3de24c4efef902dd9795a49c75f760cbe4f7a5a8" 358 | integrity sha512-Xt40xQsrkdvjn1EyWe1Bc0dJLcil/9x2vAuW7ya+PuQip4UYUaXyhzWmAbwRsdMgwOFHpfp7/FFZebDU6Y8VHA== 359 | dependencies: 360 | "@types/prop-types" "*" 361 | csstype "^3.0.2" 362 | 363 | "@types/scheduler@*": 364 | version "0.16.2" 365 | resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.2.tgz#1a62f89525723dde24ba1b01b092bf5df8ad4d39" 366 | integrity sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew== 367 | 368 | "@types/styled-components@^5.1.26": 369 | version "5.1.26" 370 | resolved "https://registry.yarnpkg.com/@types/styled-components/-/styled-components-5.1.26.tgz#5627e6812ee96d755028a98dae61d28e57c233af" 371 | integrity sha512-KuKJ9Z6xb93uJiIyxo/+ksS7yLjS1KzG6iv5i78dhVg/X3u5t1H7juRWqVmodIdz6wGVaIApo1u01kmFRdJHVw== 372 | dependencies: 373 | "@types/hoist-non-react-statics" "*" 374 | "@types/react" "*" 375 | csstype "^3.0.2" 376 | 377 | ansi-styles@^3.2.1: 378 | version "3.2.1" 379 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" 380 | integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== 381 | dependencies: 382 | color-convert "^1.9.0" 383 | 384 | "babel-plugin-styled-components@>= 1.12.0": 385 | version "2.0.7" 386 | resolved "https://registry.yarnpkg.com/babel-plugin-styled-components/-/babel-plugin-styled-components-2.0.7.tgz#c81ef34b713f9da2b7d3f5550df0d1e19e798086" 387 | integrity sha512-i7YhvPgVqRKfoQ66toiZ06jPNA3p6ierpfUuEWxNF+fV27Uv5gxBkf8KZLHUCc1nFA9j6+80pYoIpqCeyW3/bA== 388 | dependencies: 389 | "@babel/helper-annotate-as-pure" "^7.16.0" 390 | "@babel/helper-module-imports" "^7.16.0" 391 | babel-plugin-syntax-jsx "^6.18.0" 392 | lodash "^4.17.11" 393 | picomatch "^2.3.0" 394 | 395 | babel-plugin-syntax-jsx@^6.18.0: 396 | version "6.18.0" 397 | resolved "https://registry.yarnpkg.com/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz#0af32a9a6e13ca7a3fd5069e62d7b0f58d0d8946" 398 | integrity sha512-qrPaCSo9c8RHNRHIotaufGbuOBN8rtdC4QrrFFc43vyWCCz7Kl7GL1PGaXtMGQZUXrkCjNEgxDfmAuAabr/rlw== 399 | 400 | camelize@^1.0.0: 401 | version "1.0.1" 402 | resolved "https://registry.yarnpkg.com/camelize/-/camelize-1.0.1.tgz#89b7e16884056331a35d6b5ad064332c91daa6c3" 403 | integrity sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ== 404 | 405 | caniuse-lite@^1.0.30001332: 406 | version "1.0.30001441" 407 | resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001441.tgz#987437b266260b640a23cd18fbddb509d7f69f3e" 408 | integrity sha512-OyxRR4Vof59I3yGWXws6i908EtGbMzVUi3ganaZQHmydk1iwDhRnvaPG2WaR0KcqrDFKrxVZHULT396LEPhXfg== 409 | 410 | chalk@^2.0.0: 411 | version "2.4.2" 412 | resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" 413 | integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== 414 | dependencies: 415 | ansi-styles "^3.2.1" 416 | escape-string-regexp "^1.0.5" 417 | supports-color "^5.3.0" 418 | 419 | color-convert@^1.9.0: 420 | version "1.9.3" 421 | resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" 422 | integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== 423 | dependencies: 424 | color-name "1.1.3" 425 | 426 | color-name@1.1.3: 427 | version "1.1.3" 428 | resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" 429 | integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== 430 | 431 | css-color-keywords@^1.0.0: 432 | version "1.0.0" 433 | resolved "https://registry.yarnpkg.com/css-color-keywords/-/css-color-keywords-1.0.0.tgz#fea2616dc676b2962686b3af8dbdbe180b244e05" 434 | integrity sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg== 435 | 436 | css-to-react-native@^3.0.0: 437 | version "3.0.0" 438 | resolved "https://registry.yarnpkg.com/css-to-react-native/-/css-to-react-native-3.0.0.tgz#62dbe678072a824a689bcfee011fc96e02a7d756" 439 | integrity sha512-Ro1yETZA813eoyUp2GDBhG2j+YggidUmzO1/v9eYBKR2EHVEniE2MI/NqpTQ954BMpTPZFsGNPm46qFB9dpaPQ== 440 | dependencies: 441 | camelize "^1.0.0" 442 | css-color-keywords "^1.0.0" 443 | postcss-value-parser "^4.0.2" 444 | 445 | csstype@^3.0.2: 446 | version "3.1.1" 447 | resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.1.tgz#841b532c45c758ee546a11d5bd7b7b473c8c30b9" 448 | integrity sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw== 449 | 450 | debug@^4.1.0: 451 | version "4.3.4" 452 | resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" 453 | integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== 454 | dependencies: 455 | ms "2.1.2" 456 | 457 | escape-string-regexp@^1.0.5: 458 | version "1.0.5" 459 | resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" 460 | integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== 461 | 462 | framer-motion@6.5.1: 463 | version "6.5.1" 464 | resolved "https://registry.yarnpkg.com/framer-motion/-/framer-motion-6.5.1.tgz#802448a16a6eb764124bf36d8cbdfa6dd6b931a7" 465 | integrity sha512-o1BGqqposwi7cgDrtg0dNONhkmPsUFDaLcKXigzuTFC5x58mE8iyTazxSudFzmT6MEyJKfjjU8ItoMe3W+3fiw== 466 | dependencies: 467 | "@motionone/dom" "10.12.0" 468 | framesync "6.0.1" 469 | hey-listen "^1.0.8" 470 | popmotion "11.0.3" 471 | style-value-types "5.0.0" 472 | tslib "^2.1.0" 473 | optionalDependencies: 474 | "@emotion/is-prop-valid" "^0.8.2" 475 | 476 | framesync@6.0.1: 477 | version "6.0.1" 478 | resolved "https://registry.yarnpkg.com/framesync/-/framesync-6.0.1.tgz#5e32fc01f1c42b39c654c35b16440e07a25d6f20" 479 | integrity sha512-fUY88kXvGiIItgNC7wcTOl0SNRCVXMKSWW2Yzfmn7EKNc+MpCzcz9DhdHcdjbrtN3c6R4H5dTY2jiCpPdysEjA== 480 | dependencies: 481 | tslib "^2.1.0" 482 | 483 | globals@^11.1.0: 484 | version "11.12.0" 485 | resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" 486 | integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== 487 | 488 | has-flag@^3.0.0: 489 | version "3.0.0" 490 | resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" 491 | integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw== 492 | 493 | hey-listen@^1.0.8: 494 | version "1.0.8" 495 | resolved "https://registry.yarnpkg.com/hey-listen/-/hey-listen-1.0.8.tgz#8e59561ff724908de1aa924ed6ecc84a56a9aa68" 496 | integrity sha512-COpmrF2NOg4TBWUJ5UVyaCU2A88wEMkUPK4hNqyCkqHbxT92BbvfjoSozkAIIm6XhicGlJHhFdullInrdhwU8Q== 497 | 498 | hoist-non-react-statics@^3.0.0, hoist-non-react-statics@^3.3.0: 499 | version "3.3.2" 500 | resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45" 501 | integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw== 502 | dependencies: 503 | react-is "^16.7.0" 504 | 505 | "js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: 506 | version "4.0.0" 507 | resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" 508 | integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== 509 | 510 | jsesc@^2.5.1: 511 | version "2.5.2" 512 | resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" 513 | integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== 514 | 515 | lodash@^4.17.11: 516 | version "4.17.21" 517 | resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" 518 | integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== 519 | 520 | loose-envify@^1.1.0: 521 | version "1.4.0" 522 | resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" 523 | integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== 524 | dependencies: 525 | js-tokens "^3.0.0 || ^4.0.0" 526 | 527 | ms@2.1.2: 528 | version "2.1.2" 529 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" 530 | integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== 531 | 532 | nanoid@^3.3.4: 533 | version "3.3.4" 534 | resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.4.tgz#730b67e3cd09e2deacf03c027c81c9d9dbc5e8ab" 535 | integrity sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw== 536 | 537 | next@12.2.5: 538 | version "12.2.5" 539 | resolved "https://registry.yarnpkg.com/next/-/next-12.2.5.tgz#14fb5975e8841fad09553b8ef41fe1393602b717" 540 | integrity sha512-tBdjqX5XC/oFs/6gxrZhjmiq90YWizUYU6qOWAfat7zJwrwapJ+BYgX2PmiacunXMaRpeVT4vz5MSPSLgNkrpA== 541 | dependencies: 542 | "@next/env" "12.2.5" 543 | "@swc/helpers" "0.4.3" 544 | caniuse-lite "^1.0.30001332" 545 | postcss "8.4.14" 546 | styled-jsx "5.0.4" 547 | use-sync-external-store "1.2.0" 548 | optionalDependencies: 549 | "@next/swc-android-arm-eabi" "12.2.5" 550 | "@next/swc-android-arm64" "12.2.5" 551 | "@next/swc-darwin-arm64" "12.2.5" 552 | "@next/swc-darwin-x64" "12.2.5" 553 | "@next/swc-freebsd-x64" "12.2.5" 554 | "@next/swc-linux-arm-gnueabihf" "12.2.5" 555 | "@next/swc-linux-arm64-gnu" "12.2.5" 556 | "@next/swc-linux-arm64-musl" "12.2.5" 557 | "@next/swc-linux-x64-gnu" "12.2.5" 558 | "@next/swc-linux-x64-musl" "12.2.5" 559 | "@next/swc-win32-arm64-msvc" "12.2.5" 560 | "@next/swc-win32-ia32-msvc" "12.2.5" 561 | "@next/swc-win32-x64-msvc" "12.2.5" 562 | 563 | object-assign@^4.1.1: 564 | version "4.1.1" 565 | resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" 566 | integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== 567 | 568 | picocolors@^1.0.0: 569 | version "1.0.0" 570 | resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" 571 | integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== 572 | 573 | picomatch@^2.3.0: 574 | version "2.3.1" 575 | resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" 576 | integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== 577 | 578 | popmotion@11.0.3: 579 | version "11.0.3" 580 | resolved "https://registry.yarnpkg.com/popmotion/-/popmotion-11.0.3.tgz#565c5f6590bbcddab7a33a074bb2ba97e24b0cc9" 581 | integrity sha512-Y55FLdj3UxkR7Vl3s7Qr4e9m0onSnP8W7d/xQLsoJM40vs6UKHFdygs6SWryasTZYqugMjm3BepCF4CWXDiHgA== 582 | dependencies: 583 | framesync "6.0.1" 584 | hey-listen "^1.0.8" 585 | style-value-types "5.0.0" 586 | tslib "^2.1.0" 587 | 588 | postcss-value-parser@^4.0.2: 589 | version "4.2.0" 590 | resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz#723c09920836ba6d3e5af019f92bc0971c02e514" 591 | integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ== 592 | 593 | postcss@8.4.14: 594 | version "8.4.14" 595 | resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.14.tgz#ee9274d5622b4858c1007a74d76e42e56fd21caf" 596 | integrity sha512-E398TUmfAYFPBSdzgeieK2Y1+1cpdxJx8yXbK/m57nRhKSmk1GB2tO4lbLBtlkfPQTDKfe4Xqv1ASWPpayPEig== 597 | dependencies: 598 | nanoid "^3.3.4" 599 | picocolors "^1.0.0" 600 | source-map-js "^1.0.2" 601 | 602 | react-dom@17.0.2: 603 | version "17.0.2" 604 | resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-17.0.2.tgz#ecffb6845e3ad8dbfcdc498f0d0a939736502c23" 605 | integrity sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA== 606 | dependencies: 607 | loose-envify "^1.1.0" 608 | object-assign "^4.1.1" 609 | scheduler "^0.20.2" 610 | 611 | react-is@^16.7.0: 612 | version "16.13.1" 613 | resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" 614 | integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== 615 | 616 | react@17.0.2: 617 | version "17.0.2" 618 | resolved "https://registry.yarnpkg.com/react/-/react-17.0.2.tgz#d0b5cc516d29eb3eee383f75b62864cfb6800037" 619 | integrity sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA== 620 | dependencies: 621 | loose-envify "^1.1.0" 622 | object-assign "^4.1.1" 623 | 624 | scheduler@^0.20.2: 625 | version "0.20.2" 626 | resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.20.2.tgz#4baee39436e34aa93b4874bddcbf0fe8b8b50e91" 627 | integrity sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ== 628 | dependencies: 629 | loose-envify "^1.1.0" 630 | object-assign "^4.1.1" 631 | 632 | shallowequal@^1.1.0: 633 | version "1.1.0" 634 | resolved "https://registry.yarnpkg.com/shallowequal/-/shallowequal-1.1.0.tgz#188d521de95b9087404fd4dcb68b13df0ae4e7f8" 635 | integrity sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ== 636 | 637 | source-map-js@^1.0.2: 638 | version "1.0.2" 639 | resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c" 640 | integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw== 641 | 642 | style-value-types@5.0.0: 643 | version "5.0.0" 644 | resolved "https://registry.yarnpkg.com/style-value-types/-/style-value-types-5.0.0.tgz#76c35f0e579843d523187989da866729411fc8ad" 645 | integrity sha512-08yq36Ikn4kx4YU6RD7jWEv27v4V+PUsOGa4n/as8Et3CuODMJQ00ENeAVXAeydX4Z2j1XHZF1K2sX4mGl18fA== 646 | dependencies: 647 | hey-listen "^1.0.8" 648 | tslib "^2.1.0" 649 | 650 | styled-components@5.3.5: 651 | version "5.3.5" 652 | resolved "https://registry.yarnpkg.com/styled-components/-/styled-components-5.3.5.tgz#a750a398d01f1ca73af16a241dec3da6deae5ec4" 653 | integrity sha512-ndETJ9RKaaL6q41B69WudeqLzOpY1A/ET/glXkNZ2T7dPjPqpPCXXQjDFYZWwNnE5co0wX+gTCqx9mfxTmSIPg== 654 | dependencies: 655 | "@babel/helper-module-imports" "^7.0.0" 656 | "@babel/traverse" "^7.4.5" 657 | "@emotion/is-prop-valid" "^1.1.0" 658 | "@emotion/stylis" "^0.8.4" 659 | "@emotion/unitless" "^0.7.4" 660 | babel-plugin-styled-components ">= 1.12.0" 661 | css-to-react-native "^3.0.0" 662 | hoist-non-react-statics "^3.0.0" 663 | shallowequal "^1.1.0" 664 | supports-color "^5.5.0" 665 | 666 | styled-jsx@5.0.4: 667 | version "5.0.4" 668 | resolved "https://registry.yarnpkg.com/styled-jsx/-/styled-jsx-5.0.4.tgz#5b1bd0b9ab44caae3dd1361295559706e044aa53" 669 | integrity sha512-sDFWLbg4zR+UkNzfk5lPilyIgtpddfxXEULxhujorr5jtePTUqiPDc5BC0v1NRqTr/WaFBGQQUoYToGlF4B2KQ== 670 | 671 | supports-color@^5.3.0, supports-color@^5.5.0: 672 | version "5.5.0" 673 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" 674 | integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== 675 | dependencies: 676 | has-flag "^3.0.0" 677 | 678 | to-fast-properties@^2.0.0: 679 | version "2.0.0" 680 | resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" 681 | integrity sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog== 682 | 683 | tslib@^2.1.0, tslib@^2.3.1, tslib@^2.4.0: 684 | version "2.4.1" 685 | resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.1.tgz#0d0bfbaac2880b91e22df0768e55be9753a5b17e" 686 | integrity sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA== 687 | 688 | typescript@4.9.4: 689 | version "4.9.4" 690 | resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.4.tgz#a2a3d2756c079abda241d75f149df9d561091e78" 691 | integrity sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg== 692 | 693 | use-sync-external-store@1.2.0: 694 | version "1.2.0" 695 | resolved "https://registry.yarnpkg.com/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz#7dbefd6ef3fe4e767a0cf5d7287aacfb5846928a" 696 | integrity sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA== 697 | 698 | usehooks-ts@^2.9.1: 699 | version "2.9.1" 700 | resolved "https://registry.yarnpkg.com/usehooks-ts/-/usehooks-ts-2.9.1.tgz#953d3284851ffd097432379e271ce046a8180b37" 701 | integrity sha512-2FAuSIGHlY+apM9FVlj8/oNhd+1y+Uwv5QNkMQz1oSfdHk4PXo1qoCw9I5M7j0vpH8CSWFJwXbVPeYDjLCx9PA== 702 | --------------------------------------------------------------------------------