feat(登录页): 重新设计登录页面
- 采用居中卡片布局设计 - 左侧展示品牌区域和认证动画 - 右侧提供登录表单 - 使用灰白色背景提升视觉体验 - 添加响应式设计支持移动端 - 优化表单交互和动画效果
This commit is contained in:
parent
c781657003
commit
6d96c5b947
@ -5,6 +5,7 @@ import {
|
|||||||
Link,
|
Link,
|
||||||
Button,
|
Button,
|
||||||
Space,
|
Space,
|
||||||
|
Message,
|
||||||
} from '@arco-design/web-react';
|
} from '@arco-design/web-react';
|
||||||
import { FormInstance } from '@arco-design/web-react/es/Form';
|
import { FormInstance } from '@arco-design/web-react/es/Form';
|
||||||
import { IconLock, IconUser } from '@arco-design/web-react/icon';
|
import { IconLock, IconUser } from '@arco-design/web-react/icon';
|
||||||
@ -75,11 +76,12 @@ export default function LoginForm() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles['login-form-wrapper']}>
|
<div className={styles['login-form-wrapper']}>
|
||||||
<div className={styles['login-form-title']}>{t['login.form.title']}</div>
|
<div className={styles['login-form-title']}>账号登录</div>
|
||||||
<div className={styles['login-form-sub-title']}>
|
|
||||||
{t['login.form.title']}
|
{errorMessage && (
|
||||||
</div>
|
|
||||||
<div className={styles['login-form-error-msg']}>{errorMessage}</div>
|
<div className={styles['login-form-error-msg']}>{errorMessage}</div>
|
||||||
|
)}
|
||||||
|
|
||||||
<Form
|
<Form
|
||||||
className={styles['login-form']}
|
className={styles['login-form']}
|
||||||
layout="vertical"
|
layout="vertical"
|
||||||
@ -91,39 +93,40 @@ export default function LoginForm() {
|
|||||||
rules={[{ required: true, message: t['login.form.userName.errMsg'] }]}
|
rules={[{ required: true, message: t['login.form.userName.errMsg'] }]}
|
||||||
>
|
>
|
||||||
<Input
|
<Input
|
||||||
prefix={<IconUser />}
|
|
||||||
placeholder={t['login.form.userName.placeholder']}
|
placeholder={t['login.form.userName.placeholder']}
|
||||||
onPressEnter={onSubmitClick}
|
onPressEnter={onSubmitClick}
|
||||||
|
size="large"
|
||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|
||||||
<Form.Item
|
<Form.Item
|
||||||
field="password"
|
field="password"
|
||||||
rules={[{ required: true, message: t['login.form.password.errMsg'] }]}
|
rules={[{ required: true, message: t['login.form.password.errMsg'] }]}
|
||||||
>
|
>
|
||||||
<Input.Password
|
<Input.Password
|
||||||
prefix={<IconLock />}
|
|
||||||
placeholder={t['login.form.password.placeholder']}
|
placeholder={t['login.form.password.placeholder']}
|
||||||
onPressEnter={onSubmitClick}
|
onPressEnter={onSubmitClick}
|
||||||
|
size="large"
|
||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Space size={16} direction="vertical">
|
|
||||||
<div className={styles['login-form-password-actions']}>
|
<div className={styles['login-form-actions']}>
|
||||||
<Checkbox checked={rememberPassword} onChange={setRememberPassword}>
|
<Checkbox checked={rememberPassword} onChange={setRememberPassword}>
|
||||||
{t['login.form.rememberPassword']}
|
{t['login.form.rememberPassword']}
|
||||||
</Checkbox>
|
</Checkbox>
|
||||||
<Link>{t['login.form.forgetPassword']}</Link>
|
<Link>{t['login.form.forgetPassword']}</Link>
|
||||||
</div>
|
</div>
|
||||||
<Button type="primary" long onClick={onSubmitClick} loading={loading}>
|
|
||||||
|
<Button
|
||||||
|
type="primary"
|
||||||
|
long
|
||||||
|
size="large"
|
||||||
|
onClick={onSubmitClick}
|
||||||
|
loading={loading}
|
||||||
|
className={styles['login-btn']}
|
||||||
|
>
|
||||||
{t['login.form.login']}
|
{t['login.form.login']}
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
|
||||||
type="text"
|
|
||||||
long
|
|
||||||
className={styles['login-form-register-btn']}
|
|
||||||
>
|
|
||||||
{t['login.form.register']}
|
|
||||||
</Button>
|
|
||||||
</Space>
|
|
||||||
</Form>
|
</Form>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -1,8 +1,5 @@
|
|||||||
import React, { useEffect } from 'react';
|
import React, { useEffect } from 'react';
|
||||||
import Footer from '@/components/Footer';
|
|
||||||
import Logo from '@/assets/logo.svg';
|
|
||||||
import LoginForm from './form';
|
import LoginForm from './form';
|
||||||
import LoginBanner from './banner';
|
|
||||||
import styles from './style/index.module.less';
|
import styles from './style/index.module.less';
|
||||||
|
|
||||||
function Login() {
|
function Login() {
|
||||||
@ -12,26 +9,53 @@ function Login() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.container}>
|
<div className={styles.container}>
|
||||||
<div className={styles.logo}>
|
<div className={styles['login-card-wrapper']}>
|
||||||
<Logo />
|
{/* 左侧插画区域 */}
|
||||||
<div className={styles['logo-text']}>Arco Design Pro</div>
|
|
||||||
</div>
|
|
||||||
<div className={styles.banner}>
|
<div className={styles.banner}>
|
||||||
<div className={styles['banner-inner']}>
|
<div className={styles['banner-inner']}>
|
||||||
<LoginBanner />
|
{/* Logo */}
|
||||||
|
<div className={styles.logo}>
|
||||||
|
<span className={styles['logo-text']}>Coder Admin</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* 插画区域 */}
|
||||||
|
<div className={styles['illustration-wrapper']}>
|
||||||
|
<div className={styles.illustration}>
|
||||||
|
{/* 认证卡片 */}
|
||||||
|
<div className={styles['auth-card']}>
|
||||||
|
<div className={styles['auth-card-header']}>
|
||||||
|
<div className={styles['scan-line']}></div>
|
||||||
|
</div>
|
||||||
|
<div className={styles['auth-card-avatar']}>
|
||||||
|
<div className={styles['avatar-circle']}></div>
|
||||||
|
</div>
|
||||||
|
<div className={styles['auth-card-info']}>
|
||||||
|
<div className={styles['info-line']}></div>
|
||||||
|
<div className={styles['info-line-short']}></div>
|
||||||
|
</div>
|
||||||
|
<div className={styles['check-icon']}>✓</div>
|
||||||
|
</div>
|
||||||
|
{/* 人物剪影 */}
|
||||||
|
<div className={styles['person-silhouette']}></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* 右侧登录表单区域 */}
|
||||||
<div className={styles.content}>
|
<div className={styles.content}>
|
||||||
<div className={styles['content-inner']}>
|
<div className={styles['content-wrapper']}>
|
||||||
<LoginForm />
|
<LoginForm />
|
||||||
</div>
|
|
||||||
<div className={styles.footer}>
|
<div className={styles.footer}>
|
||||||
<Footer />
|
Copyright © 2024 Coder Admin. All Rights Reserved.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Login.displayName = 'LoginPage';
|
Login.displayName = 'LoginPage';
|
||||||
|
|
||||||
export default Login;
|
export default Login;
|
||||||
|
|||||||
@ -1,120 +1,504 @@
|
|||||||
|
// 登录页面容器
|
||||||
.container {
|
.container {
|
||||||
display: flex;
|
display: flex;
|
||||||
height: 100vh;
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
.banner {
|
|
||||||
width: 550px;
|
|
||||||
background: linear-gradient(163.85deg, #1d2129 0%, #00308f 100%);
|
|
||||||
}
|
|
||||||
|
|
||||||
.content {
|
|
||||||
flex: 1;
|
|
||||||
position: relative;
|
|
||||||
padding-bottom: 40px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.footer {
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
position: absolute;
|
min-height: 100vh;
|
||||||
bottom: 0;
|
background: #f0f2f5;
|
||||||
right: 0;
|
padding: 40px 20px;
|
||||||
}
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.logo {
|
// 登录卡片包装器
|
||||||
position: fixed;
|
.login-card-wrapper {
|
||||||
top: 24px;
|
display: flex;
|
||||||
left: 22px;
|
background: #fff;
|
||||||
display: inline-flex;
|
border-radius: 16px;
|
||||||
align-items: center;
|
box-shadow: 0 20px 60px rgba(0, 0, 0, 30%);
|
||||||
|
overflow: hidden;
|
||||||
|
max-width: 1000px;
|
||||||
|
width: 100%;
|
||||||
|
position: relative;
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
|
animation: fade-in-up 0.6s ease-out;
|
||||||
&-text {
|
|
||||||
margin-left: 4px;
|
|
||||||
margin-right: 4px;
|
|
||||||
font-size: 20px;
|
|
||||||
color: var(--color-fill-1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 左侧插画区域
|
||||||
.banner {
|
.banner {
|
||||||
|
flex: 0 0 500px;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
background: linear-gradient(135deg, #6b8aff 0%, #5470ff 100%);
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
padding: 60px 40px;
|
||||||
|
}
|
||||||
|
|
||||||
&-inner {
|
.banner-inner {
|
||||||
height: 100%;
|
width: 100%;
|
||||||
flex: 1;
|
position: relative;
|
||||||
|
z-index: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Logo 区域
|
||||||
|
.logo {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
margin-bottom: 40px;
|
||||||
|
|
||||||
|
.logo-text {
|
||||||
|
font-size: 24px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #fff;
|
||||||
|
letter-spacing: 1px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.content {
|
// 插画区域
|
||||||
|
.illustration-wrapper {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
min-height: 400px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.carousel {
|
.illustration {
|
||||||
height: 100%;
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
&-item {
|
max-width: 400px;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
align-items: center;
|
||||||
height: 100%;
|
gap: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 认证卡片
|
||||||
|
.auth-card {
|
||||||
|
width: 200px;
|
||||||
|
height: 260px;
|
||||||
|
background: rgba(255, 255, 255, 95%);
|
||||||
|
border-radius: 16px;
|
||||||
|
padding: 20px;
|
||||||
|
box-shadow: 0 20px 60px rgba(0, 0, 0, 15%);
|
||||||
|
position: relative;
|
||||||
|
animation: float 3s ease-in-out infinite;
|
||||||
|
|
||||||
|
&-header {
|
||||||
|
position: relative;
|
||||||
|
height: 60px;
|
||||||
|
border-radius: 8px;
|
||||||
|
background: linear-gradient(135deg, #e8eeff 0%, #f5f7ff 100%);
|
||||||
|
overflow: hidden;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
|
||||||
|
.scan-line {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
height: 2px;
|
||||||
|
background: linear-gradient(90deg, transparent, #5470ff, transparent);
|
||||||
|
animation: scan 2s linear infinite;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&-title {
|
&-avatar {
|
||||||
font-weight: 500;
|
display: flex;
|
||||||
font-size: 20px;
|
justify-content: center;
|
||||||
line-height: 28px;
|
margin-bottom: 16px;
|
||||||
color: var(--color-fill-1);
|
|
||||||
|
.avatar-circle {
|
||||||
|
width: 80px;
|
||||||
|
height: 80px;
|
||||||
|
border-radius: 50%;
|
||||||
|
background: linear-gradient(135deg, #6b8aff 0%, #5470ff 100%);
|
||||||
|
border: 4px solid rgba(84, 112, 255, 20%);
|
||||||
|
box-shadow: 0 4px 12px rgba(84, 112, 255, 30%);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&-sub-title {
|
&-info {
|
||||||
margin-top: 8px;
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 8px;
|
||||||
|
|
||||||
|
.info-line {
|
||||||
|
height: 12px;
|
||||||
|
background: #e8eeff;
|
||||||
|
border-radius: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-line-short {
|
||||||
|
height: 12px;
|
||||||
|
width: 60%;
|
||||||
|
background: #e8eeff;
|
||||||
|
border-radius: 6px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.check-icon {
|
||||||
|
position: absolute;
|
||||||
|
top: -12px;
|
||||||
|
right: -12px;
|
||||||
|
width: 40px;
|
||||||
|
height: 40px;
|
||||||
|
border-radius: 50%;
|
||||||
|
background: linear-gradient(135deg, #52c41a 0%, #389e0d 100%);
|
||||||
|
color: #fff;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
font-size: 24px;
|
||||||
|
font-weight: bold;
|
||||||
|
box-shadow: 0 4px 12px rgba(82, 196, 26, 40%);
|
||||||
|
animation: check-pulse 2s ease-in-out infinite;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 人物剪影
|
||||||
|
.person-silhouette {
|
||||||
|
width: 120px;
|
||||||
|
height: 140px;
|
||||||
|
background: rgba(255, 255, 255, 30%);
|
||||||
|
border-radius: 60px 60px 80px 80px;
|
||||||
|
position: relative;
|
||||||
|
animation: float 3s ease-in-out infinite reverse;
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: 20px;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
width: 50px;
|
||||||
|
height: 50px;
|
||||||
|
border-radius: 50%;
|
||||||
|
background: rgba(255, 255, 255, 50%);
|
||||||
|
}
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
width: 60px;
|
||||||
|
height: 8px;
|
||||||
|
border-radius: 50%;
|
||||||
|
background: rgba(0, 0, 0, 10%);
|
||||||
|
filter: blur(4px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 右侧表单区域
|
||||||
|
.content {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 60px 50px;
|
||||||
|
background: #fff;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-wrapper {
|
||||||
|
width: 100%;
|
||||||
|
max-width: 400px;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 登录表单
|
||||||
|
.login-form-wrapper {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-form-title {
|
||||||
|
font-size: 24px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #1d2129;
|
||||||
|
margin-bottom: 32px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-form-error-msg {
|
||||||
|
padding: 12px 16px;
|
||||||
|
background: #ffece8;
|
||||||
|
border: 1px solid #ffccc7;
|
||||||
|
border-radius: 8px;
|
||||||
|
color: #f53f3f;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
line-height: 22px;
|
margin-bottom: 20px;
|
||||||
color: var(--color-text-3);
|
animation: shake 0.5s ease;
|
||||||
}
|
|
||||||
|
|
||||||
&-image {
|
|
||||||
margin-top: 30px;
|
|
||||||
width: 320px;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.login-form {
|
.login-form {
|
||||||
&-wrapper {
|
:global {
|
||||||
width: 320px;
|
.arco-form-item {
|
||||||
|
margin-bottom: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
&-title {
|
.arco-input-wrapper,
|
||||||
font-size: 24px;
|
.arco-input-password {
|
||||||
font-weight: 500;
|
border-radius: 8px;
|
||||||
color: var(--color-text-1);
|
height: 44px;
|
||||||
line-height: 32px;
|
transition: all 0.3s ease;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
border-color: #5470ff;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&-sub-title {
|
.arco-input-wrapper.arco-input-focus,
|
||||||
font-size: 16px;
|
.arco-input-password.arco-input-focus {
|
||||||
line-height: 24px;
|
border-color: #5470ff;
|
||||||
color: var(--color-text-3);
|
box-shadow: 0 0 0 2px rgba(84, 112, 255, 10%);
|
||||||
}
|
}
|
||||||
|
|
||||||
&-error-msg {
|
.arco-input {
|
||||||
height: 32px;
|
height: 44px;
|
||||||
line-height: 32px;
|
font-size: 14px;
|
||||||
color: rgb(var(--red-6));
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
&-password-actions {
|
}
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
.login-form-actions {
|
||||||
}
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
&-register-btn {
|
align-items: center;
|
||||||
color: var(--color-text-3) !important;
|
margin-bottom: 24px;
|
||||||
|
|
||||||
|
:global {
|
||||||
|
.arco-checkbox-text {
|
||||||
|
color: #4e5969;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.arco-link {
|
||||||
|
color: #5470ff;
|
||||||
|
font-size: 14px;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: #6b8aff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-btn {
|
||||||
|
height: 44px;
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 500;
|
||||||
|
background: linear-gradient(135deg, #5470ff 0%, #6b8aff 100%);
|
||||||
|
border: none;
|
||||||
|
border-radius: 8px;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
transform: translateY(-2px);
|
||||||
|
box-shadow: 0 6px 16px rgba(84, 112, 255, 40%);
|
||||||
|
background: linear-gradient(135deg, #6b8aff 0%, #7d9aff 100%);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:active {
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:global(.arco-btn-primary):not(:global(.arco-btn-disabled)) {
|
||||||
|
background: linear-gradient(135deg, #5470ff 0%, #6b8aff 100%);
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: linear-gradient(135deg, #6b8aff 0%, #7d9aff 100%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 底部版权
|
||||||
|
.footer {
|
||||||
|
margin-top: 40px;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 12px;
|
||||||
|
color: #86909c;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 动画定义
|
||||||
|
@keyframes float {
|
||||||
|
0%,
|
||||||
|
100% {
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
50% {
|
||||||
|
transform: translateY(-20px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes scan {
|
||||||
|
0% {
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
transform: translateY(60px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes check-pulse {
|
||||||
|
0%,
|
||||||
|
100% {
|
||||||
|
transform: scale(1);
|
||||||
|
box-shadow: 0 4px 12px rgba(82, 196, 26, 40%);
|
||||||
|
}
|
||||||
|
|
||||||
|
50% {
|
||||||
|
transform: scale(1.1);
|
||||||
|
box-shadow: 0 4px 20px rgba(82, 196, 26, 60%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes rotate {
|
||||||
|
from {
|
||||||
|
transform: rotate(0deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
to {
|
||||||
|
transform: rotate(360deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes fade-in-up {
|
||||||
|
from {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateY(30px);
|
||||||
|
}
|
||||||
|
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes shake {
|
||||||
|
0%,
|
||||||
|
100% {
|
||||||
|
transform: translateX(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
10%,
|
||||||
|
30%,
|
||||||
|
50%,
|
||||||
|
70%,
|
||||||
|
90% {
|
||||||
|
transform: translateX(-5px);
|
||||||
|
}
|
||||||
|
|
||||||
|
20%,
|
||||||
|
40%,
|
||||||
|
60%,
|
||||||
|
80% {
|
||||||
|
transform: translateX(5px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 响应式设计
|
||||||
|
@media (max-width: 1024px) {
|
||||||
|
.login-card-wrapper {
|
||||||
|
flex-direction: column;
|
||||||
|
max-width: 500px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.banner {
|
||||||
|
flex: 0 0 auto;
|
||||||
|
padding: 40px 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.illustration-wrapper {
|
||||||
|
min-height: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.auth-card {
|
||||||
|
width: 150px;
|
||||||
|
height: 200px;
|
||||||
|
padding: 15px;
|
||||||
|
|
||||||
|
&-header {
|
||||||
|
height: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-avatar {
|
||||||
|
margin-bottom: 12px;
|
||||||
|
|
||||||
|
.avatar-circle {
|
||||||
|
width: 60px;
|
||||||
|
height: 60px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.check-icon {
|
||||||
|
width: 32px;
|
||||||
|
height: 32px;
|
||||||
|
font-size: 18px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.person-silhouette {
|
||||||
|
width: 80px;
|
||||||
|
height: 100px;
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
width: 35px;
|
||||||
|
height: 35px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
padding: 40px 30px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.container {
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-card-wrapper {
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.banner {
|
||||||
|
padding: 30px 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo {
|
||||||
|
margin-bottom: 30px;
|
||||||
|
|
||||||
|
.logo-text {
|
||||||
|
font-size: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.illustration-wrapper {
|
||||||
|
min-height: 250px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.auth-card {
|
||||||
|
width: 120px;
|
||||||
|
height: 160px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.person-silhouette {
|
||||||
|
width: 60px;
|
||||||
|
height: 80px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
padding: 30px 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-form-title {
|
||||||
|
font-size: 20px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user