Commit 33e00ce5 authored by minseok.park's avatar minseok.park

update ui - main

parent 71ed96cd
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<link rel="icon" type="image/png" href="./src/assets/images/favicon.ico" /> <link rel="icon" type="image/png" href="./src/assets/images/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>SW Lab</title> <title>SWLab</title>
</head> </head>
<body> <body>
<div id="root"></div> <div id="root"></div>
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
"dependencies": { "dependencies": {
"@react-three/drei": "^9.105.4", "@react-three/drei": "^9.105.4",
"@react-three/fiber": "^8.16.2", "@react-three/fiber": "^8.16.2",
"clsx": "^2.1.1",
"react": "^18.2.0", "react": "^18.2.0",
"react-dom": "^18.2.0", "react-dom": "^18.2.0",
"react-icons": "^5.1.0", "react-icons": "^5.1.0",
...@@ -1696,6 +1697,14 @@ ...@@ -1696,6 +1697,14 @@
"node": ">= 6" "node": ">= 6"
} }
}, },
"node_modules/clsx": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz",
"integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==",
"engines": {
"node": ">=6"
}
},
"node_modules/color-convert": { "node_modules/color-convert": {
"version": "2.0.1", "version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
"dependencies": { "dependencies": {
"@react-three/drei": "^9.105.4", "@react-three/drei": "^9.105.4",
"@react-three/fiber": "^8.16.2", "@react-three/fiber": "^8.16.2",
"clsx": "^2.1.1",
"react": "^18.2.0", "react": "^18.2.0",
"react-dom": "^18.2.0", "react-dom": "^18.2.0",
"react-icons": "^5.1.0", "react-icons": "^5.1.0",
......
// @ts-nocheck // @ts-nocheck
import './styles/index.scss'
import Banner from './components/Banner' import Banner from './components/Banner'
import Header from './components/Header' import Header from './components/Header'
import Section from './components/Section' import Section from './components/Section'
import Card from './components/Card' import Card from './components/Card'
import './styles/index.scss'
function App () { function App () {
return ( return (
<> <>
<Header /> <Header />
<Banner /> <Banner />
<Section> <Section gap='3rem'>
<Card title='title1' subTitle='subTitle1' desc='desc1' /> <Card
<Card title='title1' subTitle='subTitle1' desc='desc1' /> title='BXM'
<Card title='title1' subTitle='subTitle1' desc='desc1' /> subTitle='Business eXcellence Framework'
mainDesc='고성능 Java 애플리케이션 개발 및 운영 프레임워크'
subDesc={[
'고성능 아키텍처',
'안정적 시스템',
'개발 생산성과 품질 향상',
'확장성',
'클라우드 지원',
]}/>
<Card
title='BXI'
subTitle='Business eXcellence Integrator'
mainDesc='대내외 인터페이스 통합 솔루션'
subDesc={[
'BXI-FEP: 대외시스템 연계',
'BXI-EAI: 대내시스템 연계',
'BXI-MCI: 단말 연계',
]}/>
<Card
title='BXCloud'
subTitle='Business eXcellence Cloud'
mainDesc='구조화된 Cloud Native Platform과 Framework'
subDesc={[
'Kubernetes 기반 Container Orchestration',
'통합 관리 도구',
'구조화된 시스템 컴포넌트',
'분산 트랜젝션 처리',
'클라우드 네이티브 Java 프레임워크',
]}/>
</Section> </Section>
</> </>
) )
......
// @ts-nocheck
import { useState, useRef } from 'react'
import { Canvas, useFrame } from '@react-three/fiber'
import { Points, PointMaterial } from '@react-three/drei'
import * as random from 'maath/random/dist/maath-random.esm'
const Galaxy = (props) => {
const ref = useRef()
const [sphere] = useState(() => random.inSphere(new Float32Array(5000), { radius: 1.5 }))
useFrame((state, delta) => {
ref.current.rotation.x -= delta / 10
ref.current.rotation.y -= delta / 15
})
return (
<group rotation={[0, 0, Math.PI / 4]}>
<Points ref={ref} positions={sphere} stride={3} frustumCulled={false} {...props}>
{/* <PointMaterial transparent color="#ffa0e0" size={0.005} sizeAttenuation={true} depthWrite={false} /> */}
<PointMaterial transparent color='#0072CE' size={0.005} sizeAttenuation={true} depthWrite={false} />
</Points>
</group>
)
}
export default function Backdrop (props) {
const { style } = props
return (
<Canvas style={style} camera={{ position: [0, 0, 1] }}>
<Galaxy />
</Canvas>
)
}
// @ts-nocheck // @ts-nocheck
import { useState, useRef } from 'react'
import { Canvas, useFrame } from '@react-three/fiber'
import { Points, PointMaterial } from '@react-three/drei'
import * as random from 'maath/random/dist/maath-random.esm'
import styled from 'styled-components'
import { SiGithub } from 'react-icons/si' import { SiGithub } from 'react-icons/si'
import styled from 'styled-components'
import Button from './Button' import Button from './Button'
import Backdrop from './Backdrop'
const Galaxy = (props) => { const backdropStyle = {
const ref = useRef() borderBottomLeftRadius: '50% 25%',
const [sphere] = useState(() => random.inSphere(new Float32Array(5000), { radius: 1.5 })) borderBottomRightRadius: '50% 25%',
useFrame((state, delta) => {
ref.current.rotation.x -= delta / 10
ref.current.rotation.y -= delta / 15
})
return (
<group rotation={[0, 0, Math.PI / 4]}>
<Points ref={ref} positions={sphere} stride={3} frustumCulled={false} {...props}>
{/* <PointMaterial transparent color="#ffa0e0" size={0.005} sizeAttenuation={true} depthWrite={false} /> */}
<PointMaterial transparent color='#0072CE' size={0.005} sizeAttenuation={true} depthWrite={false} />
</Points>
</group>
)
} }
export default function Banner () { export default function Banner () {
return ( return (
<Wrapper> <Wrapper>
<Canvas camera={{ position: [0, 0, 1] }}> <Backdrop style={backdropStyle} />
<Galaxy />
</Canvas>
<Overlay> <Overlay>
<BannerTitle type='main' fontSize='5em'>Bankware Global</BannerTitle> <BannerTitle type='main' fontSize='5em'>Bankware Global</BannerTitle>
<BannerTitle type='sub' fontSize='3.5em'>Software Lab.</BannerTitle> <BannerTitle type='sub' fontSize='3.5em'>Software Lab.</BannerTitle>
...@@ -47,14 +29,16 @@ export default function Banner () { ...@@ -47,14 +29,16 @@ export default function Banner () {
const Wrapper = styled.div` const Wrapper = styled.div`
position: relative; position: relative;
width: 100%; width: 100%;
height: 510px; height: 610px;
background-color: #12071f; background-color: #12071f;
border-bottom-left-radius: 50% 25%;
border-bottom-right-radius: 50% 25%;
` `
const Overlay = styled.div` const Overlay = styled.div`
position: absolute; position: absolute;
top: 50%; top: 60%;
left: 50%; left: 50%;
transform: translate3d(-50%,-50%,0); transform: translate3d(-50%, -50%, 0);
text-align: center; text-align: center;
` `
const BannerTitle = styled.h1` const BannerTitle = styled.h1`
......
// @ts-nocheck // @ts-nocheck
import styled from 'styled-components' import styled from 'styled-components'
import Backdrop from './Backdrop'
import Button from './Button'
export default function Card (props) { export default function Card (props) {
const { title, subTitle, desc } = props const { title, subTitle, mainDesc, subDesc } = props
return <Wrapper> return <Scene>
<div>{title}</div> <FlipCard>
<div>{subTitle}</div> <CardFace className='front'>
<div>{desc}</div> <Title size='50px' fontWeight={700} align='left'>{title}</Title>
</Wrapper> <Title size='18px' fontWeight={500} align='left'>{subTitle}</Title>
<div style={{ width: '100%', border: '1px solid #0072ce', marginTop: '10px' }}></div>
<div style={{ height: '110px' }}></div>
<Title size='25px' fontWeight={700} color='#12071F' align='center'>{mainDesc}</Title>
</CardFace>
<CardFace className='back'>
<Backdrop />
<Overlay>
<div style={{ flexGrow: '1' }}>
{
subDesc && subDesc.map((desc, idx) => <Title key={idx} className='mb_10' size='14px' fontWeight={700} align='center'>
{desc}
</Title>)
}
</div>
<Button text='Learn more'/>
</Overlay>
</CardFace>
</FlipCard>
</Scene>
} }
const Wrapper = styled.div` const Scene = styled.div`
width: 300px; position: 'relative';
height: 500px; width: 400px;
border: 1px solid red; height: 460px;
border-radius: 10px; margin: 40px 0;
perspective: 1200px;
`
const FlipCard = styled.article`
width: 100%;
height: 100%;
transition: transform 1s;
transform-style: preserve-3d;
cursor: pointer;
position: relative;
${Scene}:hover & {
transform: scale(1.1) rotateY(180deg);
}
`
const CardFace = styled.article`
position: absolute;
width: 100%;
height: 100%;
padding: 1.5rem;
color: white;
text-align: center;
-webkit-backface-visibility: hidden;
backface-visibility: hidden;
border: 1px solid hsla(0, 0%, 9%, .04);
border-radius: 16px;
box-shadow: 0 2px 8px -2px hsla(0, 0%, 9%, .08), 0 8px 12px -2px hsla(0, 0%, 9%, .16);
&.front {
background-color: #fff; background-color: #fff;
color: #0072ce;
}
&.back {
background-color: #12071f;
color: white;
transform: rotateY(180deg);
}
`
const Title = styled.h1`
font-size: ${props => props.size};
font-weight: ${props => props.fontWeight};
text-align: ${props => props.align};
color: ${props => props.color};
`
const Overlay = styled.div`
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
justify-content: center;
padding: 3rem;
` `
// @ts-nocheck // @ts-nocheck
import { useState, useEffect } from 'react'
import clsx from 'clsx'
import styled from 'styled-components' import styled from 'styled-components'
import logoImg from '../assets/images/logo.png' import logoImg from '../assets/images/logo.png'
import colorLogoImg from '../assets/images/logo_color.png'
import Nav from './Nav' import Nav from './Nav'
export default function Header () { export default function Header () {
const [scrollY, setScrollY] = useState(0)
const handleScroll = () => {
const offset = window.scrollY
setScrollY(offset)
}
useEffect(() => {
window.addEventListener('scroll', handleScroll)
return () => {
window.removeEventListener('scroll', handleScroll)
}
}, [])
return ( return (
<Wrapper> <Wrapper className={clsx({ active: scrollY > 10 })}>
<LogoWrap> <LogoWrap>
<Logo image={logoImg} /> <Logo className={clsx({ active: scrollY > 10 })} image={ scrollY > 10 ? colorLogoImg : logoImg} />
<LogoTitpeWrap> <LogoTitpeWrap>
<LogoTitle type='main'>SW Lab</LogoTitle> <LogoTitle type='main'>SWLab</LogoTitle>
<LogoTitle type='sub'>Bankware Global</LogoTitle> <LogoTitle type='sub'>Bankware Global</LogoTitle>
</LogoTitpeWrap> </LogoTitpeWrap>
</LogoWrap> </LogoWrap>
...@@ -23,8 +42,7 @@ const Wrapper = styled.div` ...@@ -23,8 +42,7 @@ const Wrapper = styled.div`
align-items: center; align-items: center;
height: 8.125rem; height: 8.125rem;
max-height: 8.125rem; max-height: 8.125rem;
padding: 1.875rem 0; padding: 1.875rem 5rem;
margin: 0 5rem;
background-color: rgba(0, 0, 0, 0); background-color: rgba(0, 0, 0, 0);
position: fixed; position: fixed;
top: 0; top: 0;
...@@ -32,15 +50,29 @@ const Wrapper = styled.div` ...@@ -32,15 +50,29 @@ const Wrapper = styled.div`
left: 0; left: 0;
z-index: 100; z-index: 100;
color: #fff; color: #fff;
&.active {
background-color: #fff;
box-shadow: 0 6px 9px 0 rgba(0, 0, 0, .16);
color: #0072CE;
padding: .5rem 5rem;
max-height: 5.5rem;
transition: background-color 1s, box-shadow .2s, max-height .8s;
}
` `
const Logo = styled.div` const Logo = styled.div`
margin-top: 4px; margin-top: 10px;
margin-right: 4px; margin-right: 6px;
width: 35px; width: 35px;
height: 40px; height: 44px;
background-image: url(${props => props.image}); background-image: url(${props => props.image});
background-size: contain; background-size: contain;
background-repeat: no-repeat; background-repeat: no-repeat;
&.active {
width: 52px;
height: 52px;
}
` `
const LogoWrap = styled.div` const LogoWrap = styled.div`
display: flex; display: flex;
...@@ -48,13 +80,14 @@ const LogoWrap = styled.div` ...@@ -48,13 +80,14 @@ const LogoWrap = styled.div`
flex-grow: 1; flex-grow: 1;
width: 300px; width: 300px;
height: 60px; height: 60px;
margin-top: -8px;
` `
const LogoTitpeWrap = styled.div` const LogoTitpeWrap = styled.div`
display: flex; display: flex;
flex-direction: column; flex-direction: column;
` `
const LogoTitle = styled.span` const LogoTitle = styled.span`
font-size: ${(props) => (props.type === 'main' ? '30px' : '14px')}; font-size: ${(props) => (props.type === 'main' ? '33px' : '14px')};
font-weight: ${(props) => (props.type === 'main' ? 600 : 400)}; font-weight: ${(props) => (props.type === 'main' ? 600 : 400)};
margin-top: ${(props) => (props.type !== 'main' && '-4px')} margin-top: ${(props) => (props.type !== 'main' && '-4px')}
` `
...@@ -27,7 +27,7 @@ const MenuItem = styled.li` ...@@ -27,7 +27,7 @@ const MenuItem = styled.li`
font-size: 20px; font-size: 20px;
&:hover { &:hover {
p { p {
background: linear-gradient(270deg, rgba(255,255,255,1) 0%, rgba(0,212,255,1) 50%, rgba(0,114,206,1) 100%); background: linear-gradient(270deg, #89CFF0 0%, rgba(0,212,255,1) 50%, rgba(0,114,206,1) 100%);
-webkit-background-clip: text; -webkit-background-clip: text;
background-clip: text; background-clip: text;
-webkit-text-fill-color: transparent; -webkit-text-fill-color: transparent;
......
...@@ -2,13 +2,18 @@ ...@@ -2,13 +2,18 @@
import styled from 'styled-components' import styled from 'styled-components'
export default function Section (props) { export default function Section (props) {
return <Wrapper> const { gap } = props
return <Wrapper gap={gap}>
{props.children} {props.children}
</Wrapper> </Wrapper>
} }
const Wrapper = styled.div` const Wrapper = styled.div`
display: flex; display: flex;
flex-direction: ${props => props.flexDirection};
justify-content: center; justify-content: center;
align-items: center;
gap: ${props => props.gap};
padding: 80px 0; padding: 80px 0;
` `
...@@ -7,36 +7,36 @@ ...@@ -7,36 +7,36 @@
font-family: $noto-sans-kr; font-family: $noto-sans-kr;
font-style: normal; font-style: normal;
font-weight: 100; font-weight: 100;
src:url(../fonts/noto/NotoSansKR-Thin.otf) format('opentype'); src:url(../assets/fonts/noto/NotoSansKR-Thin.otf) format('opentype');
} }
@font-face { @font-face {
font-family: $noto-sans-kr; font-family: $noto-sans-kr;
font-style: normal; font-style: normal;
font-weight: 300; font-weight: 300;
src:url(../fonts/noto/NotoSansKR-Light.otf) format('opentype'); src:url(../assets/fonts/noto/NotoSansKR-Light.otf) format('opentype');
} }
@font-face { @font-face {
font-family: $noto-sans-kr; font-family: $noto-sans-kr;
font-style: normal; font-style: normal;
font-weight: 400; font-weight: 400;
src:url(../fonts/noto/NotoSansKR-Regular.otf) format('opentype'); src:url(../assets/fonts/noto/NotoSansKR-Regular.otf) format('opentype');
} }
@font-face { @font-face {
font-family: $noto-sans-kr; font-family: $noto-sans-kr;
font-style: normal; font-style: normal;
font-weight: 500; font-weight: 500;
src:url(../fonts/noto/NotoSansKR-Medium.otf) format('opentype'); src:url(../assets/fonts/noto/NotoSansKR-Medium.otf) format('opentype');
} }
@font-face { @font-face {
font-family: $noto-sans-kr; font-family: $noto-sans-kr;
font-style: normal; font-style: normal;
font-weight: 700; font-weight: 700;
src:url(../fonts/noto/NotoSansKR-Bold.otf) format('opentype'); src:url(../assets/fonts/noto/NotoSansKR-Bold.otf) format('opentype');
} }
@font-face { @font-face {
font-family: $noto-sans-kr; font-family: $noto-sans-kr;
font-style: normal; font-style: normal;
font-weight: 900; font-weight: 900;
src:url(../fonts/noto/NotoSansKR-Black.otf) format('opentype'); src:url(../assets/fonts/noto/NotoSansKR-Black.otf) format('opentype');
} }
\ No newline at end of file
...@@ -31,6 +31,7 @@ ul { ...@@ -31,6 +31,7 @@ ul {
body { body {
font-weight: 400; font-weight: 400;
font-size: 13px !important; font-size: 13px !important;
font-family: Noto Sans KR, sans-serif, Arial;
} }
a { a {
...@@ -51,3 +52,388 @@ input::-ms-reveal, ...@@ -51,3 +52,388 @@ input::-ms-reveal,
input::-ms-clear { input::-ms-clear {
display: none; display: none;
} }
::-webkit-scrollbar {
background-color: transparent;
width: 10px;
height: 8px;
}
/* background of the scrollbar except button or resizer */
::-webkit-scrollbar-track {
background-color: transparent;
}
/* scrollbar itself */
::-webkit-scrollbar-thumb {
background: rgba(121, 121, 121, 0.4);
border-radius: 8px;
}
/* set button(top and bottom of the scrollbar) */
::-webkit-scrollbar-button {
display: none;
}
::-webkit-scrollbar-corner {
background: rgba(0,0,0,0);
}
.mt_0 {
margin-top: 0 !important;
}
.mb_0 {
margin-bottom: 0 !important;
}
.mr_0 {
margin-right: 0 !important;
}
.ml_0 {
margin-left: 0 !important;
}
.ml_1 {
margin-left: 1 !important;
}
.pt_0 {
padding-top: 0 !important;
}
.pb_0 {
padding-bottom: 0 !important;
}
.pr_0 {
padding-right: 0 !important;
}
.pr_4 {
padding-right: 4px !important;
}
.pr_10 {
padding-right: 10px !important;
}
.pl_0 {
padding-left: 0 !important;
}
.pl_6 {
padding-left: 6px !important;
}
.pl_10 {
padding-left: 10px !important;
}
.pl_12 {
padding-left: 12px !important;
}
.pl_30 {
padding-left: 30px !important;
}
.mt_2 {
margin-top: 2px !important;
}
.mt_3 {
margin-top: 3px !important;
}
.ml_1 {
margin-left: 1px !important;
}
.ml_2 {
margin-left: 2px !important;
}
.ml_3 {
margin-left: 3px !important;
}
.ml_3 {
margin-left: 3px !important;
}
.ml_5 {
margin-left: 5px !important;
}
.ml_6 {
margin-left: 6px !important;
}
.mb_3 {
margin-bottom: 3px !important;
}
.mb_5 {
margin-bottom: 5px !important;
}
.mb_6 {
margin-bottom: 6px !important;
}
.mb_10 {
margin-bottom: 10px !important;
}
.mr_3 {
margin-right: 3px !important;
}
.mr_4 {
margin-right: 4px !important;
}
.mr_5 {
margin-right: 5px !important;
}
.mr_6 {
margin-right: 6px !important;
}
.mr_10 {
margin-right: 10px !important;
}
.mr_15 {
margin-right: 15px !important;
}
.ml_10 {
margin-left: 10px !important;
}
.ml_15 {
margin-left: 15px !important;
}
.mr_20 {
margin-right: 20px !important;
}
.mb_20 {
margin-bottom: 20px !important;
}
.mt_5 {
margin-top: 5px !important;
}
.mt_10 {
margin-top: 10px !important;
}
.mt_20 {
margin-top: 20px !important;
}
.mt_m1 {
margin-top: -1px !important;
}
.mt_m15 {
margin-top: -15px !important;
}
.mt_m20 {
margin-top: -20px !important;
}
.mt_m22 {
margin-top: -22px !important;
}
.mt_m200 {
margin-top: -200px !important;
}
.mt_p175 {
margin-top: 175px !important;
}
.pt_10 {
padding-top: 10px !important;
}
.pt_20 {
padding-top: 20px !important;
}
.pt_40 {
padding-top: 40px !important;
}
.pb_15 {
padding-bottom: 15px !important;
}
.p_20_30 {
padding: 20px 30px !important;
}
.p_20 {
padding: 20px !important;
}
.p_10 {
padding: 10px !important;
}
.p_2 {
padding: 2px !important;
}
.f_l {
float: left !important;
}
.f_r {
float: right !important;
}
.w_300_px {
width: 300px !important;
}
.w_100 {
width: 100% !important;
}
.w_96 {
width: 96% !important;
}
.w_80 {
width: 80% !important;
}
.w_77 {
width: 77% !important;
}
.w_75 {
width: 75% !important;
}
.w_70 {
width: 70% !important;
}
.w_66 {
width: 66.7% !important;
}
.w_50 {
width: 50% !important;
}
.w_37_5 {
width: 37.5% !important;
}
.w_33 {
width: 33.3% !important;
}
.w_30 {
width: 30% !important;
}
.w_25 {
width: 25% !important;
}
.w_22 {
width: 22% !important;
}
.w_20 {
width: 20% !important;
}
.w_10 {
width: 10% !important;
}
.h_30 {
height: 30px !important;
}
.l_h_24 {
line-height: 24px !important;
}
.ico_50 {
display: inline-block;
line-height: 50px;
vertical-align: top;
width: 50px;
height: 50px;
}
.ico_40 {
display: inline-block;
line-height: 40px;
vertical-align: top;
width: 40px;
height: 40px;
}
.ico_30 {
display: inline-block;
line-height: 30px;
vertical-align: top;
width: 30px;
height: 30px;
}
.ico_25 {
display: inline-block;
line-height: 25px;
vertical-align: top;
width: 25px;
height: 25px;
}
.ico_20 {
display: inline-block;
line-height: 20px;
vertical-align: top;
width: 20px;
height: 20px;
}
.ico_20_15 {
line-height: 20px;
vertical-align: top;
display: inline-block;
width: 20px;
height: 15px;
}
.ico_18 {
line-height: 18px;
vertical-align: top;
display: inline-block;
width: 18px;
height: 18px;
}
.cs_p {
cursor: pointer !important;
}
.cs_d {
cursor: default !important;
}
.bg_w {
background-color: #fff !important;
}
.d_n {
display: none !important;
}
.d_h {
visibility: hidden;
}
.d_b {
display: block !important;
}
.d_f {
display: flex !important;
}
.d_ib {
display: inline-block !important;
}
.bs {
box-shadow: rgb(145 158 171 / 24%) 0px 0px 4px 0px,
rgb(145 158 171 / 24%) 0px 4px 12px -4px !important;
}
.br {
border-radius: 6px !important;
}
.br_t {
border-top-left-radius: 6px !important;
border-top-right-radius: 6px !important;
}
.br_b {
border-bottom-left-radius: 6px !important;
border-bottom-right-radius: 6px !important;
}
.of_y {
overflow-y: auto;
}
.fs_12 {
font-size: 12px !important;
}
.fs_18 {
font-size: 18px !important;
}
.ws_pw {
white-space: pre-wrap;
}
.v_t {
vertical-align: top;
}
.ac {
display: flex;
align-items: center;
justify-content: center;
}
.ac_v {
display: flex;
align-items: center;
}
import { defineConfig } from 'vite' import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react-swc' import react from '@vitejs/plugin-react-swc'
import sass from 'sass'
// https://vitejs.dev/config/ // https://vitejs.dev/config/
export default defineConfig({ export default defineConfig({
plugins: [react()], plugins: [react()],
css: {
preprocessorOptions: {
scss: {
implementation: sass,
},
},
},
}) })
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment